diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index af5b1e2e..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,63 +0,0 @@ -version: 2.1 -orbs: # adds orbs to your configuration - jira: circleci/jira@1.0.5 # invokes the Jira orb, making its commands accessible -jobs: - build: - working_directory: ~/Cider - docker: - - image: circleci/node:16 - steps: - - checkout - - run: - name: Update Package Managers - command: sudo npm update -g npm yarn - - restore_cache: - name: Restore Yarn Package Cache - keys: - - yarn-packages-{{ checksum "yarn.lock" }} - - run: - name: Install Dependencies - command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn - - save_cache: - name: Save Yarn Package Cache - key: yarn-packages-{{ checksum "yarn.lock" }} - paths: - - ~/.cache/yarn - - run: - name: Install Playwright - command: yarn playwright install --with-deps - - run: - name: Install system build dependencies - command: | - sudo apt-get update -y - sudo apt-get install -y dpkg fakeroot wine64 - sudo dpkg --add-architecture i386 - sudo apt-get update -y - sudo apt-get install -y wine32 - - store_test_results: - path: test-results - - run: - name: Generate Builds (Linux) - command: yarn dist -l -p never - post-steps: - - jira/notify - - run: - name: Generate Builds (Windows) - command: yarn dist -w --x64 -p never - post-steps: - - jira/notify - - run: - name: Move Build Files - command: | - mkdir ~/Cider/dist/artifacts/ - mv ~/Cider/dist/*.exe ~/Cider/dist/artifacts - mv ~/Cider/dist/*.deb ~/Cider/dist/artifacts - mv ~/Cider/dist/*.AppImage ~/Cider/dist/artifacts - mv ~/Cider/dist/*.snap ~/Cider/dist/artifacts - mv ~/Cider/dist/*.yml ~/Cider/dist/artifacts - - store_artifacts: - path: ~/Cider/dist/artifacts - post-steps: - - jira/notify - - diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..1014ba78 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 92509691..f274bacc 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,4 @@ github: ciderapp ko_fi: cryptofyre open_collective: ciderapp +custom: "https://opencollective.com/ciderapp/donate/10/month/Support%20Development?redirect=https://cidercollective.dev/thanks" diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index dc1856ec..a54d19c2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,20 +1,74 @@ name: Bug Report description: If you encounter an issue whilst using our app, please use this template to help improve the app. title: "[Bug]: " -labels: ["bug", "triage"] +labels: ["bug", "needs-triage"] assignees: [] body: - type: markdown attributes: value: | Thanks for taking the time to fill out this bug report! + - type: checkboxes + attributes: + label: Preflight Checklist + description: Please ensure you've completed all of the following. + options: + - label: I have read the [Support Disclaimer](https://docs.cider.sh/support/disclaimer) for this project. + required: true + - label: I agree to follow the [Code of Conduct](https://github.com/ciderapp/Cider/blob/main/CODE_OF_CONDUCT.md) that this project adheres to. + required: true + - label: I have searched the [issue tracker](https://www.github.com/ciderapp/Cider/issues) for a bug report that matches the one I want to file, without success. + required: true + - label: I have read the [troublshooting FAQs](https://cider.gitbook.io/welcome-to-gitbook/support/faqs#why-is-my-discordrpc-status-not-appearing) and none solved my issue. + required: true + - type: input + attributes: + label: Cider Version + description: | + What version of Cider are you using? + + Note: Please only report issues for [currently supported versions of Cider](hhttps://cider.gitbook.io/welcome-to-gitbook/support/version-information). You can find your version on the About Page. + placeholder: 1.6.0 + validations: + required: true + - type: dropdown + attributes: + label: What operating system are you using? + options: + - Windows + - macOS + - Ubuntu + - Other Linux + - Other (specify below) + validations: + required: true + - type: input + attributes: + label: Operating System Version + description: What operating system version are you using? On Windows, click Start button > Settings > System > About. On macOS, click the Apple Menu > About This Mac. On Linux, use lsb_release or uname -a. + placeholder: "e.g. Windows 10 version 1909, macOS Catalina 10.15.7, or Ubuntu 20.04" + validations: + required: true + - type: dropdown + id: download + attributes: + label: Where did you download Cider from? + options: + - Microsoft Store + - GitHub + - Winget + - Winget (Nightly) + - Chocolatey + - Flathub + - AUR + validations: + required: true - type: textarea id: description attributes: label: Describe the Bug - description: A clear and concise description of the bug you encountered. Also tell us, what did you expect to happen? + description: A clear and concise description of the bug you encountered. Tell us what did you expect to happen? placeholder: Tell us what you see! - value: "A bug happened!" validations: required: true - type: textarea @@ -22,23 +76,7 @@ body: attributes: label: Steps to Reproduce description: How did you produce this bug, tell us how you did it so we can do it ourselves. - placeholder: Tell us how you did it - value: "1. Clicked on..." - validations: - required: true - - type: textarea - id: environment - attributes: - label: Environment Information - description: | - Examples: - - **OS**: Ubuntu 20.04 - - **App Version**: 1.0.0 - - **Commit ID**: c9d43be - value: | - - OS: - - App Version: - - Commit ID: + placeholder: 1. Clicked on... validations: required: true - type: textarea @@ -48,11 +86,3 @@ body: Links? References? Anything that will give us more context about the issue you are encountering! Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. - - type: checkboxes - id: terms - attributes: - label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/ciderapp/Cider/blob/main/CODE_OF_CONDUCT.md) - options: - - label: I agree to follow this project's Code of Conduct - required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 4c8bcbbb..5009beff 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,10 +1,16 @@ -blank_issues_enabled: true +blank_issues_enabled: false contact_links: + - name: Support Disclaimer + url: https://docs.cider.sh/support/disclaimer + about: Please read this before creating any issue. + - name: Feature Request + url: https://github.com/ciderapp/Cider/discussions/new?category=feature-request + about: Have a feature you would like to have in the app? Make a request. - name: Discord Support url: https://discord.com/invite/AppleMusic about: For quick support, make a ticket or ask for community support here. - - name: GitHub Troublshooting - url: https://github.com/ciderapp/Cider/wiki/Troubleshooting + - name: Cider Documentation + url: https://docs.cider.sh/support/faqs about: In most cases, these troubleshooting tips can resolve basic issues. Try them out before opening an issue. - name: GitHub Issues url: https://github.com/ciderapp/Cider/issues diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml deleted file mode 100644 index d4624c96..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: Feature Request -description: Suggest an idea to improve Cider. -title: "[Enhancement]: " -labels: ["enhancement", "triage"] -assignees: [] -body: - - type: markdown - attributes: - value: | - Thanks for taking the time to fill out this report! - - type: textarea - id: description - attributes: - label: The feature you would like - description: A clear and concise description of what you would like to be added to the application. State if your request if related to an issue. - placeholder: A great addition to this project would be... - validations: - required: true - - type: textarea - id: other - attributes: - label: Alternatives and Other Information - description: If you have any alternative solutions to implement your request or other information that could help. - placeholder: Anything that can help us? - validations: - required: false - - type: checkboxes - id: terms - attributes: - label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/ciderapp/Cider/blob/main/CODE_OF_CONDUCT.md) - options: - - label: I agree to follow this project's Code of Conduct - required: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..f71d469b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "monthly" diff --git a/.github/workflows/auto-project.yml b/.github/workflows/auto-project.yml new file mode 100644 index 00000000..742d82e1 --- /dev/null +++ b/.github/workflows/auto-project.yml @@ -0,0 +1,18 @@ +name: Add bugs to bugs project + +on: + issues: + types: + - opened + +jobs: + add-to-project: + name: Add issue to project + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@main + with: + project-url: https://github.com/orgs/ciderapp/projects/5 + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} + labeled: bug, needs-triage + label-operator: OR diff --git a/.github/workflows/cider-chores.yml b/.github/workflows/cider-chores.yml new file mode 100644 index 00000000..757d14fb --- /dev/null +++ b/.github/workflows/cider-chores.yml @@ -0,0 +1,67 @@ +name: Cider Chores + +on: + push: + branches: + - main + +jobs: + compile-and-post: + runs-on: ubuntu-latest + + container: + image: electronuserland/builder:wine + + + steps: + - name: Checkout 🛎 + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + + - name: Install Dependencies đŸ“Ļ + run: yarn install + + - name: Build 🏗 + run: yarn dist:all + + - name: Upload Release 🚀 + uses: softprops/action-gh-release@v2.0.5 + with: + files: | + ./dist/*.exe + ./dist/*.deb + ./dist/*.AppImage + ./dist/*.rpm + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + prettier: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [18] + + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + # Make sure the actual branch is checked out when running on pull requests + ref: ${{ github.head_ref }} + + - name: Prettify code + run: npm run format:write + + - name: Commit Prettier Code + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: "chore: Prettified Code\n [ci skip]" + commit_user_name: "cider-chore[bot]" + commit_user_email: "cider-chore[bot]@users.noreply.github.com" diff --git a/.github/workflows/dev-chores.yml b/.github/workflows/dev-chores.yml new file mode 100644 index 00000000..04feb41f --- /dev/null +++ b/.github/workflows/dev-chores.yml @@ -0,0 +1,33 @@ +name: Developer Chores + +on: [pull_request] + +jobs: + linter-check: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest] + node: [18] + + steps: + - name: Checkout 🛎 + uses: actions/checkout@v3 + + - name: Setup node env 🏗 + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + check-latest: true + + - name: Install dependencies 👨đŸģ‍đŸ’ģ + run: npm run bootstrap + + - name: Run linter 👀 + run: npm run format:write + + - name: Comment Suggestions đŸ—’ī¸ + uses: getsentry/action-git-diff-suggestions@main + with: + message: Prettier Suggestion diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml new file mode 100644 index 00000000..66d920d9 --- /dev/null +++ b/.github/workflows/stale-issues.yml @@ -0,0 +1,22 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '30 1 * * *' + +permissions: + issues: write + pull-requests: write + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v4 + with: + stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.' + days-before-stale: 30 + days-before-close: 7 + stale-issue-label: "stale" + stale-pr-label: "stale" + exempt-all-assignees: true + exempt-issue-labels: 'more-info,work-in-progress,accessibility-feature,help-wanted,persist/priority' diff --git a/.github/workflows/support-notice.yml b/.github/workflows/support-notice.yml new file mode 100644 index 00000000..5b743c15 --- /dev/null +++ b/.github/workflows/support-notice.yml @@ -0,0 +1,18 @@ +name: Support Notice + +on: + issues: + types: [opened] + +jobs: + post-notice: + runs-on: ubuntu-latest + + steps: + - uses: derekprior/add-autoresponse@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + respondableId: ${{ github.event.issue.node_id }} + response: "Cider 1.x is no longer actively maintained. We highly suggest moving to the newer version versions of the app available at https://cider.sh through official storefronts ex. Itch.io, or the Microsoft Store." + author: ${{ github.event.issue.user.login }} diff --git a/.gitignore b/.gitignore index 475cb6f3..5dcb31cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ # Building dist build +.flatpak* +yarn-cache +src/renderer/style.css +.pnpm-store # Misc .idea @@ -135,7 +139,6 @@ dist .vscode-test # yarn v2 -yarn.lock .pnp.* .yarn/* .yarn/cache @@ -316,3 +319,14 @@ src/renderer/workbox-962786f2.js.map keys.sh package-lock.json +resources/b64.txt + + +savedconfig/cider-config.json +savedconfig/config.json +savedconfig/session.json +savedconfig/window-state.json +src/main/base/sample.json + +# yeet circleci ci for now +.circleci/ diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..ee8c4d17 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +node-linker=hoisted +public-hoist-pattern=* +shamefully-hoist=true diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..86d4688d --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20.2.0 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..261acc66 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +src/renderer/*hls*.js +build/* +dist/* +src/renderer/lib/* +*.min.* +.pnpm-store diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..b93c35c2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,13 @@ +{ + "printWidth": 600, + "singleAttributePerLine": true, + "bracketSameLine": true, + "overrides": [ + { + "files": "src/renderer/main/**/*.js", + "options": { + "singleAttributePerLine": false + } + } + ] +} diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 00000000..91b1101f --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,5 @@ +compressionLevel: mixed + +enableGlobalCache: false + +nodeLinker: node-modules diff --git a/Assets/AppChromeBtn.afdesign b/Assets/AppChromeBtn.afdesign new file mode 100644 index 00000000..00fc374b Binary files /dev/null and b/Assets/AppChromeBtn.afdesign differ diff --git a/Assets/Cider Icons/svg/cider-backward.svg b/Assets/Cider Icons/svg/cider-backward.svg new file mode 100644 index 00000000..e5801e05 --- /dev/null +++ b/Assets/Cider Icons/svg/cider-backward.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Assets/Cider Icons/svg/cider-forward.svg b/Assets/Cider Icons/svg/cider-forward.svg new file mode 100644 index 00000000..41154a4c --- /dev/null +++ b/Assets/Cider Icons/svg/cider-forward.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Assets/Cider Icons/svg/cider-pause.svg b/Assets/Cider Icons/svg/cider-pause.svg new file mode 100644 index 00000000..bcc4cf53 --- /dev/null +++ b/Assets/Cider Icons/svg/cider-pause.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Assets/Cider Icons/svg/cider-play.svg b/Assets/Cider Icons/svg/cider-play.svg new file mode 100644 index 00000000..4246456a --- /dev/null +++ b/Assets/Cider Icons/svg/cider-play.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Assets/Install On Cider/install on cider.afdesign b/Assets/Install On Cider/install on cider.afdesign new file mode 100644 index 00000000..5a621a62 Binary files /dev/null and b/Assets/Install On Cider/install on cider.afdesign differ diff --git a/Assets/Install On Cider/install on cider.svg b/Assets/Install On Cider/install on cider.svg new file mode 100644 index 00000000..7bf4d965 --- /dev/null +++ b/Assets/Install On Cider/install on cider.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/MissingArtwork.afdesign b/Assets/MissingArtwork.afdesign new file mode 100644 index 00000000..6346990e Binary files /dev/null and b/Assets/MissingArtwork.afdesign differ diff --git a/Assets/MissingArtwork.svg b/Assets/MissingArtwork.svg new file mode 100644 index 00000000..cca3ca5b --- /dev/null +++ b/Assets/MissingArtwork.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Assets/Release.svg b/Assets/Release.svg index f27dc45d..3c9999cd 100644 --- a/Assets/Release.svg +++ b/Assets/Release.svg @@ -1,6 +1,9 @@ - - - + + + + + + diff --git a/README.md b/README.md index 911736d6..73bc1260 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,56 @@ +## ⚠ Cider Classic has approached its End-of-Life status. +This application is now no longer being actively maintained. +No support will be given on Windows. + +Thanks for your continued support. + +[Get Cider 2 today.](https://cider.sh/download) + +Banner +Banner +--- +

- Banner

- GitHub Releases + Banner +
+ A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance & visuals in mind. 🚀 +

GitHub Stars GitHub Forks - GitHub Downloads +
- Buy Me A Coffee + Buy Me A Coffee Open Collective + GitHub Sponsor
+ QQįž¤ Discord Twitter Reddit

- CircleCI Status + Azure Pipelines Status

#### Links -* [Wiki](https://github.com/ciderapp/Cider/wiki) -* [Request Feature](https://github.com/ciderapp/Cider/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=%5BEnhancement%5D) + +* [Documentation](https://docs.cider.sh) +* [Request Feature](https://github.com/ciderapp/Cider/discussions/new?category=feature-request) * [Report Bug](https://github.com/ciderapp/Cider/issues/new?assignees=&labels=bug&template=bug_report.md&title=%5BBUG%5D+) -* [**View The Releases**](https://github.com/ciderapp/Cider/releases/latest) +* [**View The Releases**](https://github.com/ciderapp/cider-releases/releases/latest) ### Install Sources -[![Get it from Github](https://img.shields.io/badge/Get_It_From_GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/ciderapp/cider/releases/latest) +[![Get it from Github](https://img.shields.io/badge/Get_It_From_GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/ciderapp/cider-releases/releases/latest) -[![Get it from the Microsoft Store](https://img.shields.io/badge/Get_It_From_The_Microsoft_Store-100000?style=for-the-badge&logo=microsoft)](https://www.microsoft.com/store/apps/9P21XJ9D9G66) +[![Get it from Windows Package Manager](https://custom-icon-badges.herokuapp.com/badge/Get_It_via_Winget_-100000?style=for-the-badge&logo=winstall)](https://winstall.app/apps/CiderCollective.Cider) +[![Get it from Windows Package Manager](https://custom-icon-badges.herokuapp.com/badge/Get_It_via_Winget_(Nightly)_-100000?style=for-the-badge&logo=winstall)](https://winstall.app/apps/CiderCollective.Cider.Nightly) -[![Get it from Windows Package Manager](https://custom-icon-badges.herokuapp.com/badge/Get_It_via_Winget-100000?style=for-the-badge&logo=winstall)](https://winstall.app/apps/CiderCollective.Cider.Nightly) +[![Get it from Chocolatey Package Manager](https://custom-icon-badges.herokuapp.com/badge/Get_It_via_Chocolatey_-100000?style=for-the-badge&logo=chocolatey)](https://community.chocolatey.org/packages/cider) + + + +[![Get it from Flathub](https://img.shields.io/badge/Get_It_From_Flathub-100000?style=for-the-badge&logo=flathub)](https://flathub.org/apps/details/sh.cider.Cider) [![Get it from the AUR](https://img.shields.io/badge/Get_It_From_The_AUR-100000?style=for-the-badge&logo=archlinux)](https://aur.archlinux.org/packages/cider) -### Compiling and Configuration -For more information surrounding configuration, compiling and other developer documentation, see the [compilation docs](https://cider.sh/compile.html). +### Insights Snapshot +[![CircleCI](https://dl.circleci.com/insights-snapshot/gh/ciderapp/Cider/main/build_and_release/badge.svg?window=30d)](https://app.circleci.com/insights/github/ciderapp/Cider/workflows/build_and_release/overview?branch=main&reporting-window=last-30-days&insights-snapshot=true) ### Credits ![Contributors](https://contrib.rocks/image?repo=ciderapp/Cider) @@ -54,4 +78,3 @@ for any legal concerns contact me at JetBrains MacStadium

- diff --git a/appx/Square150x150Logo.PNG b/appx/Square150x150Logo.PNG index 7ec9fb93..673996b9 100644 Binary files a/appx/Square150x150Logo.PNG and b/appx/Square150x150Logo.PNG differ diff --git a/appx/Square44x44Logo.PNG b/appx/Square44x44Logo.PNG index 7374d271..342f6441 100644 Binary files a/appx/Square44x44Logo.PNG and b/appx/Square44x44Logo.PNG differ diff --git a/appx/Square44x44Logo.targetsize-44_altform-unplated.PNG b/appx/Square44x44Logo.targetsize-44_altform-unplated.PNG new file mode 100644 index 00000000..342f6441 Binary files /dev/null and b/appx/Square44x44Logo.targetsize-44_altform-unplated.PNG differ diff --git a/appx/StoreLogo.PNG b/appx/StoreLogo.PNG index c9ff7a22..5fdd980e 100644 Binary files a/appx/StoreLogo.PNG and b/appx/StoreLogo.PNG differ diff --git a/docs/plugins/example/examplePlugin.ts b/docs/plugins/example/examplePlugin.ts new file mode 100644 index 00000000..ccbe5609 --- /dev/null +++ b/docs/plugins/example/examplePlugin.ts @@ -0,0 +1,62 @@ +let i = 1, + k = 1; +class ExamplePlugin { + /** + * Private variables for interaction in plugins + */ + private _win: any; + private _app: any; + private _store: any; + + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "examplePlugin"; + public description: string = "Example plugin"; + public version: string = "1.0.0"; + public author: string = "Example author"; + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(app: any, store: any) { + this._app = app; + this._store = store; + console.debug(`[Plugin][${this.name}] Loading Complete.`); + } + + /** + * Runs on app ready + */ + onReady(win: any): void { + this._win = win; + console.debug(`[Plugin][${this.name}] Ready.`); + } + + /** + * Runs on app stop + */ + onBeforeQuit(): void { + console.debug(`[Plugin][${this.name}] Stopped.`); + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + onPlaybackStateDidChange(attributes: object): void { + console.log("onPlaybackStateDidChange has been called " + i + " times"); + i++; + } + + /** + * Runs on song change + * @param attributes Music Attributes + */ + onNowPlayingItemDidChange(attributes: object): void { + console.log("onNowPlayingDidChange has been called " + k + " times"); + k++; + } +} + +module.exports = ExamplePlugin; diff --git a/docs/plugins/sendSongToTitlebar.ts b/docs/plugins/sendSongToTitlebar.ts new file mode 100644 index 00000000..6ef2c3a6 --- /dev/null +++ b/docs/plugins/sendSongToTitlebar.ts @@ -0,0 +1,39 @@ +class sendSongToTitlebar { + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "sendSongToTitlebar"; + public description: string = "Sets the app's titlebar to the Song title"; + public version: string = "0.0.1"; + public author: string = "Cider Collective (credit to 8times9 via #147)"; + /** + * Runs on plugin load (Currently run on application start) + */ + private _win: any; + private _app: any; + constructor() {} + /** + * Runs on app ready + */ + onReady(win: any): void { + this._win = win; + } + /** + * Runs on app stop + */ + onBeforeQuit(): void {} + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + onPlaybackStateDidChange(attributes: any): void { + this._win.setTitle(`${attributes != null && attributes.name != null && attributes.name.length > 0 ? attributes.name + " - " : ""}Cider`); + } + /** + * Runs on song change + * @param attributes Music Attributes + */ + onNowPlayingItemDidChange(attributes: object): void {} +} + +module.exports = sendSongToTitlebar; diff --git a/flatpak/cider-wrapper b/flatpak/cider-wrapper new file mode 100644 index 00000000..d1d954f7 --- /dev/null +++ b/flatpak/cider-wrapper @@ -0,0 +1,7 @@ +#!/bin/sh + +for i in {0..9}; do + test -S $XDG_RUNTIME_DIR/discord-ipc-$i || ln -sf {app/com.discordapp.Discord,$XDG_RUNTIME_DIR}/discord-ipc-$i; +done + +cider "$@" \ No newline at end of file diff --git a/flatpak/flathub.json b/flatpak/flathub.json new file mode 100644 index 00000000..621375db --- /dev/null +++ b/flatpak/flathub.json @@ -0,0 +1,4 @@ +{ + "only-arches": ["x86_64"], + "publish-delay-hours": 2 +} diff --git a/flatpak/flatpak-node-generator.py b/flatpak/flatpak-node-generator.py deleted file mode 100644 index 2a7c1f21..00000000 --- a/flatpak/flatpak-node-generator.py +++ /dev/null @@ -1,1839 +0,0 @@ -#!/usr/bin/env python3 - -# pyright: strict - -__license__ = 'MIT' - -from typing import * # pyright: reportWildcardImportFromLibrary=false -# Explictly import these. -from typing import cast, IO - -from pathlib import Path -from distutils.version import StrictVersion - -import argparse -import asyncio -import base64 -import binascii -import collections -import contextlib -import hashlib -import json -import os -import re -import shlex -import shutil -import sys -import tempfile -import textwrap -import types -import urllib.parse -import urllib.request - -DEFAULT_PART_SIZE = 4096 - -GIT_SCHEMES: Dict[str, Dict[str, str]] = { - 'github': { - 'scheme': 'https', - 'netloc': 'github.com' - }, - 'gitlab': { - 'scheme': 'https', - 'netloc': 'gitlab.com' - }, - 'bitbucket': { - 'scheme': 'https', - 'netloc': 'bitbucket.com' - }, - 'git': {}, - 'git+http': { - 'scheme': 'http' - }, - 'git+https': { - 'scheme': 'https' - }, -} - -GIT_URL_PATTERNS = [ - re.compile(r'^git:'), - re.compile(r'^git\+.+:'), - re.compile(r'^ssh:'), - re.compile(r'^https?:.+\.git$'), - re.compile(r'^https?:.+\.git#.+'), -] - -GIT_URL_HOSTS = ['github.com', 'gitlab.com', 'bitbucket.com', 'bitbucket.org'] - -NPM_MIRROR = 'https://unpkg.com/' - - -class Cache: - instance: 'Cache' - - @classmethod - def get_working_instance_if(cls, condition: bool) -> 'Cache': - return cls.instance if condition else NullCache() - - class BucketReader: - def read_parts(self, size: int = DEFAULT_PART_SIZE) -> Iterator[bytes]: - raise NotImplementedError - - def read_all(self) -> bytes: - raise NotImplementedError - - def close(self) -> None: - raise NotImplementedError - - def __enter__(self) -> 'Cache.BucketReader': - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - traceback: Optional[types.TracebackType]) -> None: - self.close() - - class BucketWriter: - def write(self, data: bytes) -> None: - raise NotImplementedError - - def cancel(self) -> None: - raise NotImplementedError - - def seal(self) -> None: - raise NotImplementedError - - def __enter__(self) -> 'Cache.BucketWriter': - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - traceback: Optional[types.TracebackType]) -> None: - if traceback is None: - self.seal() - else: - self.cancel() - - class BucketRef: - def __init__(self, key: str) -> None: - self.key = key - - def open_read(self) -> Optional['Cache.BucketReader']: - raise NotImplementedError - - def open_write(self) -> 'Cache.BucketWriter': - raise NotImplementedError - - def get(self, key: str) -> BucketRef: - raise NotImplementedError - - -class NullCache(Cache): - class NullBucketWriter(Cache.BucketWriter): - def write(self, data: bytes) -> None: - pass - - def cancel(self) -> None: - pass - - def seal(self) -> None: - pass - - class NullBucketRef(Cache.BucketRef): - def __init__(self, key: str) -> None: - super().__init__(key) - - def open_read(self) -> Optional[Cache.BucketReader]: - return None - - def open_write(self) -> Cache.BucketWriter: - return NullCache.NullBucketWriter() - - def get(self, key: str) -> Cache.BucketRef: - return NullCache.NullBucketRef(key) - - -class FilesystemBasedCache(Cache): - _SUBDIR = 'flatpak-node-generator' - _KEY_CHAR_ESCAPE_RE = re.compile(r'[^A-Za-z0-9._\-]') - - @staticmethod - def _escape_key(key: str) -> str: - return FilesystemBasedCache._KEY_CHAR_ESCAPE_RE.sub( - lambda m: f'_{ord(m.group()):02X}', key) - - class FilesystemBucketReader(Cache.BucketReader): - def __init__(self, file: IO[bytes]) -> None: - self.file = file - - def close(self) -> None: - self.file.close() - - def read_parts(self, size: int = DEFAULT_PART_SIZE) -> Iterator[bytes]: - while True: - data = self.file.read(size) - if not data: - break - - yield data - - def read_all(self) -> bytes: - return self.file.read() - - class FilesystemBucketWriter(Cache.BucketWriter): - def __init__(self, file: IO[bytes], temp: Path, target: Path) -> None: - self.file = file - self.temp = temp - self.target = target - - def write(self, data: bytes) -> None: - self.file.write(data) - - def cancel(self) -> None: - self.file.close() - self.temp.unlink() - - def seal(self) -> None: - self.file.close() - self.temp.rename(self.target) - - class FilesystemBucketRef(Cache.BucketRef): - def __init__(self, key: str, cache_root: Path) -> None: - super().__init__(key) - self._cache_root = cache_root - - self._cache_path = self._cache_root / FilesystemBasedCache._escape_key(key) - - def open_read(self) -> Optional[Cache.BucketReader]: - try: - fp = self._cache_path.open('rb') - except FileNotFoundError: - return None - else: - return FilesystemBasedCache.FilesystemBucketReader(fp) - - def open_write(self) -> Cache.BucketWriter: - target = self._cache_path - if not target.parent.exists(): - target.parent.mkdir(exist_ok=True, parents=True) - - fd, temp = tempfile.mkstemp(dir=self._cache_root, prefix='__temp__') - return FilesystemBasedCache.FilesystemBucketWriter(os.fdopen(fd, 'wb'), - Path(temp), target) - - @property - def _cache_root(self) -> Path: - xdg_cache_home = os.environ.get('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) - return Path(xdg_cache_home) / self._SUBDIR - - def get(self, key: str) -> Cache.BucketRef: - return FilesystemBasedCache.FilesystemBucketRef(key, self._cache_root) - - -Cache.instance = NullCache() - - -class Requests: - instance: 'Requests' - - DEFAULT_RETRIES = 5 - retries: ClassVar[int] = DEFAULT_RETRIES - - @property - def is_async(self) -> bool: - raise NotImplementedError - - def __get_cache_bucket(self, cachable: bool, url: str) -> Cache.BucketRef: - return Cache.get_working_instance_if(cachable).get(f'requests:{url}') - - async def _read_parts(self, - url: str, - size: int = DEFAULT_PART_SIZE) -> AsyncIterator[bytes]: - raise NotImplementedError - yield b'' # Silence mypy. - - async def _read_all(self, url: str) -> bytes: - raise NotImplementedError - - async def read_parts(self, - url: str, - *, - cachable: bool, - size: int = DEFAULT_PART_SIZE) -> AsyncIterator[bytes]: - bucket = self.__get_cache_bucket(cachable, url) - - bucket_reader = bucket.open_read() - if bucket_reader is not None: - for part in bucket_reader.read_parts(size): - yield part - - return - - for i in range(1, Requests.retries + 1): - try: - with bucket.open_write() as bucket_writer: - async for part in self._read_parts(url, size): - bucket_writer.write(part) - yield part - - return - except Exception: - if i == Requests.retries: - raise - - async def read_all(self, url: str, *, cachable: bool = False) -> bytes: - bucket = self.__get_cache_bucket(cachable, url) - - bucket_reader = bucket.open_read() - if bucket_reader is not None: - return bucket_reader.read_all() - - for i in range(1, Requests.retries + 1): - try: - with bucket.open_write() as bucket_writer: - data = await self._read_all(url) - bucket_writer.write(data) - return data - except Exception: - if i == Requests.retries: - raise - - assert False - - -class UrllibRequests(Requests): - @property - def is_async(self) -> bool: - return False - - async def _read_parts(self, - url: str, - size: int = DEFAULT_PART_SIZE) -> AsyncIterator[bytes]: - with urllib.request.urlopen(url) as response: - while True: - data = response.read(size) - if not data: - return - - yield data - - async def _read_all(self, url: str) -> bytes: - with urllib.request.urlopen(url) as response: - return cast(bytes, response.read()) - - -class StubRequests(Requests): - @property - def is_async(self) -> bool: - return True - - async def _read_parts(self, - url: str, - size: int = DEFAULT_PART_SIZE) -> AsyncIterator[bytes]: - yield b'' - - async def _read_all(self, url: str) -> bytes: - return b'' - - -Requests.instance = UrllibRequests() - -try: - import aiohttp - - class AsyncRequests(Requests): - @property - def is_async(self) -> bool: - return True - - @contextlib.asynccontextmanager - async def _open_stream(self, url: str) -> AsyncIterator[aiohttp.StreamReader]: - async with aiohttp.ClientSession() as session: - async with session.get(url) as response: - yield response.content - - async def _read_parts(self, - url: str, - size: int = DEFAULT_PART_SIZE) -> AsyncIterator[bytes]: - async with self._open_stream(url) as stream: - while True: - data = await stream.read(size) - if not data: - return - - yield data - - async def _read_all(self, url: str) -> bytes: - async with self._open_stream(url) as stream: - return await stream.read() - - Requests.instance = AsyncRequests() - -except ImportError: - pass - - -class CachedRequests(Requests): - pass - - -class Integrity(NamedTuple): - algorithm: str - digest: str - - @staticmethod - def parse(value: str) -> 'Integrity': - algorithm, encoded_digest = value.split('-', 1) - assert algorithm.startswith('sha'), algorithm - digest = binascii.hexlify(base64.b64decode(encoded_digest)).decode() - - return Integrity(algorithm, digest) - - @staticmethod - def from_sha1(sha1: str) -> 'Integrity': - assert len(sha1) == 40, f'Invalid length of sha1: {sha1}' - return Integrity('sha1', sha1) - - @staticmethod - def generate(data: Union[str, bytes], *, algorithm: str = 'sha256') -> 'Integrity': - builder = IntegrityBuilder(algorithm) - builder.update(data) - return builder.build() - - @staticmethod - def from_json_object(data: Any) -> 'Integrity': - return Integrity(algorithm=data['algorithm'], digest=data['digest']) - - def to_json_object(self) -> Any: - return {'algorithm': self.algorithm, 'digest': self.digest} - - def to_base64(self) -> str: - return base64.b64encode(binascii.unhexlify(self.digest)).decode() - - -class IntegrityBuilder: - def __init__(self, algorithm: str = 'sha256') -> None: - self.algorithm = algorithm - self._hasher = hashlib.new(algorithm) - - def update(self, data: Union[str, bytes]) -> None: - data_bytes: bytes - if isinstance(data, str): - data_bytes = data.encode() - else: - data_bytes = data - self._hasher.update(data_bytes) - - def build(self) -> Integrity: - return Integrity(algorithm=self.algorithm, digest=self._hasher.hexdigest()) - - -class RemoteUrlMetadata(NamedTuple): - integrity: Integrity - size: int - - @staticmethod - def __get_cache_bucket(cachable: bool, kind: str, url: str) -> Cache.BucketRef: - return Cache.get_working_instance_if(cachable).get( - f'remote-url-metadata:{kind}:{url}') - - @staticmethod - def from_json_object(data: Any) -> 'RemoteUrlMetadata': - return RemoteUrlMetadata(integrity=Integrity.from_json_object(data['integrity']), - size=data['size']) - - @classmethod - async def get(cls, - url: str, - *, - cachable: bool, - integrity_algorithm: str = 'sha256') -> 'RemoteUrlMetadata': - bucket = cls.__get_cache_bucket(cachable, 'full', url) - - bucket_reader = bucket.open_read() - if bucket_reader is not None: - data = json.loads(bucket_reader.read_all()) - return RemoteUrlMetadata.from_json_object(data) - - builder = IntegrityBuilder(integrity_algorithm) - size = 0 - - async for part in Requests.instance.read_parts(url, cachable=False): - builder.update(part) - size += len(part) - - metadata = RemoteUrlMetadata(integrity=builder.build(), size=size) - - with bucket.open_write() as bucket_writer: - bucket_writer.write(json.dumps(metadata.to_json_object()).encode('ascii')) - - return metadata - - @classmethod - async def get_size(cls, url: str, *, cachable: bool) -> int: - bucket = cls.__get_cache_bucket(cachable, 'size', url) - - bucket_reader = bucket.open_read() - if bucket_reader is not None: - return int(bucket_reader.read_all()) - - size = 0 - async for part in Requests.instance.read_parts(url, cachable=False): - size += len(part) - - with bucket.open_write() as bucket_writer: - bucket_writer.write(str(size).encode('ascii')) - - return size - - def to_json_object(self) -> Any: - return {'integrity': self.integrity.to_json_object(), 'size': self.size} - - -class ResolvedSource(NamedTuple): - resolved: str - integrity: Optional[Integrity] - - async def retrieve_integrity(self) -> Integrity: - if self.integrity is not None: - return self.integrity - else: - url = self.resolved - assert url is not None, 'registry source has no resolved URL' - metadata = await RemoteUrlMetadata.get(url, cachable=True) - return metadata.integrity - - -class UnresolvedRegistrySource: - pass - - -class GitSource(NamedTuple): - original: str - url: str - commit: str - from_: Optional[str] - - -PackageSource = Union[ResolvedSource, UnresolvedRegistrySource, GitSource] - - -class Package(NamedTuple): - name: str - version: str - source: PackageSource - lockfile: Path - - -class ManifestGenerator(contextlib.AbstractContextManager): - MAX_GITHUB_SIZE = 49 * 1000 * 1000 - JSON_INDENT = 4 - - def __init__(self) -> None: - # Store the dicts as a set of tuples, then rebuild the dict when returning it. - # That way, we ensure uniqueness. - self._sources: Set[Tuple[Tuple[str, Any], ...]] = set() - self._commands: List[str] = [] - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - tb: Optional[types.TracebackType]) -> None: - self._finalize() - - @property - def data_root(self) -> Path: - return Path('flatpak-node') - - @property - def tmp_root(self) -> Path: - return self.data_root / 'tmp' - - @property - def source_count(self) -> int: - return len(self._sources) - - def ordered_sources(self) -> Iterator[Dict[Any, Any]]: - return map(dict, sorted(self._sources)) # type: ignore - - def split_sources(self) -> Iterator[List[Dict[Any, Any]]]: - BASE_CURRENT_SIZE = len('[\n]') - current_size = BASE_CURRENT_SIZE - current: List[Dict[Any, Any]] = [] - - for source in self.ordered_sources(): - # Generate one source by itself, then check the length without the closing and - # opening brackets. - source_json = json.dumps([source], indent=ManifestGenerator.JSON_INDENT) - source_json_len = len('\n'.join(source_json.splitlines()[1:-1])) - if current_size + source_json_len >= ManifestGenerator.MAX_GITHUB_SIZE: - yield current - current = [] - current_size = BASE_CURRENT_SIZE - current.append(source) - current_size += source_json_len - - if current: - yield current - - def _add_source(self, source: Dict[str, Any]) -> None: - self._sources.add(tuple(source.items())) - - def _add_source_with_destination(self, - source: Dict[str, Any], - destination: Optional[Path], - *, - is_dir: bool, - only_arches: Optional[List[str]] = None) -> None: - if destination is not None: - if is_dir: - source['dest'] = str(destination) - else: - source['dest-filename'] = destination.name - if len(destination.parts) > 1: - source['dest'] = str(destination.parent) - - if only_arches: - source['only-arches'] = tuple(only_arches) - - self._add_source(source) - - def add_url_source(self, - url: str, - integrity: Integrity, - destination: Optional[Path] = None, - *, - only_arches: Optional[List[str]] = None) -> None: - source: Dict[str, Any] = { - 'type': 'file', - 'url': url, - integrity.algorithm: integrity.digest - } - self._add_source_with_destination(source, - destination, - is_dir=False, - only_arches=only_arches) - - def add_archive_source(self, - url: str, - integrity: Integrity, - destination: Optional[Path] = None, - only_arches: Optional[List[str]] = None, - strip_components: int = 1) -> None: - source: Dict[str, Any] = { - 'type': 'archive', - 'url': url, - 'strip-components': strip_components, - integrity.algorithm: integrity.digest - } - self._add_source_with_destination(source, - destination, - is_dir=True, - only_arches=only_arches) - - def add_data_source(self, data: Union[str, bytes], destination: Path) -> None: - if isinstance(data, bytes): - source = { - 'type': 'inline', - 'contents': base64.b64encode(data).decode('ascii'), - 'base64': True, - } - else: - assert isinstance(data, str) - source = { - 'type': 'inline', - 'contents': data, - } - self._add_source_with_destination(source, destination, is_dir=False) - - def add_git_source(self, - url: str, - commit: str, - destination: Optional[Path] = None) -> None: - source = {'type': 'git', 'url': url, 'commit': commit} - self._add_source_with_destination(source, destination, is_dir=True) - - def add_script_source(self, commands: List[str], destination: Path) -> None: - source = {'type': 'script', 'commands': tuple(commands)} - self._add_source_with_destination(source, destination, is_dir=False) - - def add_shell_source(self, - commands: List[str], - destination: Optional[Path] = None, - only_arches: Optional[List[str]] = None) -> None: - """This might be slow for multiple instances. Use `add_command()` instead.""" - source = {'type': 'shell', 'commands': tuple(commands)} - self._add_source_with_destination(source, - destination=destination, - only_arches=only_arches, - is_dir=True) - - def add_command(self, command: str) -> None: - self._commands.append(command) - - def _finalize(self) -> None: - if self._commands: - self._add_source({'type': 'shell', 'commands': tuple(self._commands)}) - - -class LockfileProvider: - def parse_git_source(self, version: str, from_: Optional[str] = None) -> GitSource: - # https://github.com/microsoft/pyright/issues/1589 - # pyright: reportPrivateUsage=false - - original_url = urllib.parse.urlparse(version) - assert original_url.scheme and original_url.path and original_url.fragment - - replacements = GIT_SCHEMES.get(original_url.scheme, {}) - new_url = original_url._replace(fragment='', **replacements) - # Replace e.g. git:github.com/owner/repo with git://github.com/owner/repo - if not new_url.netloc: - path = new_url.path.split('/') - new_url = new_url._replace(netloc=path[0], path='/'.join(path[1:])) - - return GitSource(original=original_url.geturl(), - url=new_url.geturl(), - commit=original_url.fragment, - from_=from_) - - def process_lockfile(self, lockfile: Path) -> Iterator[Package]: - raise NotImplementedError() - - -class ModuleProvider(contextlib.AbstractContextManager): - async def generate_package(self, package: Package) -> None: - raise NotImplementedError() - - -class ElectronBinaryManager: - class Arch(NamedTuple): - electron: str - flatpak: str - - class Binary(NamedTuple): - filename: str - url: str - integrity: Integrity - - arch: Optional['ElectronBinaryManager.Arch'] = None - - ELECTRON_ARCHES_TO_FLATPAK = { - 'ia32': 'i386', - 'x64': 'x86_64', - 'armv7l': 'arm', - 'arm64': 'aarch64', - } - - INTEGRITY_BASE_FILENAME = 'SHASUMS256.txt' - - def __init__(self, version: str, base_url: str, integrities: Dict[str, - Integrity]) -> None: - self.version = version - self.base_url = base_url - self.integrities = integrities - - def child_url(self, child: str) -> str: - return f'{self.base_url}/{child}' - - def find_binaries(self, binary: str) -> Iterator['ElectronBinaryManager.Binary']: - for electron_arch, flatpak_arch in self.ELECTRON_ARCHES_TO_FLATPAK.items(): - binary_filename = f'{binary}-v{self.version}-linux-{electron_arch}.zip' - binary_url = self.child_url(binary_filename) - - arch = ElectronBinaryManager.Arch(electron=electron_arch, - flatpak=flatpak_arch) - yield ElectronBinaryManager.Binary( - filename=binary_filename, - url=binary_url, - integrity=self.integrities[binary_filename], - arch=arch) - - @property - def integrity_file(self) -> 'ElectronBinaryManager.Binary': - return ElectronBinaryManager.Binary( - filename=f'SHASUMS256.txt-{self.version}', - url=self.child_url(self.INTEGRITY_BASE_FILENAME), - integrity=self.integrities[self.INTEGRITY_BASE_FILENAME]) - - @staticmethod - async def for_version(version: str) -> 'ElectronBinaryManager': - base_url = f'https://github.com/electron/electron/releases/download/v{version}' - integrity_url = f'{base_url}/{ElectronBinaryManager.INTEGRITY_BASE_FILENAME}' - integrity_data = (await Requests.instance.read_all(integrity_url, - cachable=True)).decode() - - integrities: Dict[str, Integrity] = {} - for line in integrity_data.splitlines(): - digest, star_filename = line.split() - filename = star_filename.strip('*') - integrities[filename] = Integrity(algorithm='sha256', digest=digest) - - integrities[ElectronBinaryManager.INTEGRITY_BASE_FILENAME] = ( - Integrity.generate(integrity_data)) - - return ElectronBinaryManager(version=version, - base_url=base_url, - integrities=integrities) - - -class SpecialSourceProvider: - class Options(NamedTuple): - node_chromedriver_from_electron: str - electron_ffmpeg: str - electron_node_headers: bool - nwjs_version: str - nwjs_node_headers: bool - nwjs_ffmpeg: bool - xdg_layout: bool - - def __init__(self, gen: ManifestGenerator, options: Options): - self.gen = gen - self.node_chromedriver_from_electron = options.node_chromedriver_from_electron - self.electron_ffmpeg = options.electron_ffmpeg - self.electron_node_headers = options.electron_node_headers - self.nwjs_version = options.nwjs_version - self.nwjs_node_headers = options.nwjs_node_headers - self.nwjs_ffmpeg = options.nwjs_ffmpeg - self.xdg_layout = options.xdg_layout - - @property - def electron_cache_dir(self) -> Path: - if self.xdg_layout: - return self.gen.data_root / 'cache' / 'electron' - return self.gen.data_root / 'electron-cache' - - def _add_electron_cache_downloads(self, - manager: ElectronBinaryManager, - binary_name: str, - *, - add_integrities: bool = True) -> None: - electron_cache_dir = self.electron_cache_dir - - for binary in manager.find_binaries(binary_name): - assert binary.arch is not None - self.gen.add_url_source(binary.url, - binary.integrity, - electron_cache_dir / binary.filename, - only_arches=[binary.arch.flatpak]) - #Symlinks for @electron/get, which stores electron zips in a subdir - if self.xdg_layout: - sanitized_url = ''.join(c for c in binary.url if c not in '/:') - - #And for @electron/get >= 1.12.4 its sha256 hash of url dirname - url = urllib.parse.urlparse(binary.url) - url_dir = urllib.parse.urlunparse( - url._replace(path=os.path.dirname(url.path))) - url_hash = hashlib.sha256(url_dir.encode()).hexdigest() - - self.gen.add_shell_source([ - f'mkdir -p "{sanitized_url}"', - f'ln -s "../{binary.filename}" "{sanitized_url}/{binary.filename}"', - f'mkdir -p "{url_hash}"', - f'ln -s "../{binary.filename}" "{url_hash}/{binary.filename}"' - ], - destination=electron_cache_dir, - only_arches=[binary.arch.flatpak]) - - if add_integrities: - integrity_file = manager.integrity_file - self.gen.add_url_source(integrity_file.url, integrity_file.integrity, - electron_cache_dir / integrity_file.filename) - - async def _handle_electron(self, package: Package) -> None: - manager = await ElectronBinaryManager.for_version(package.version) - self._add_electron_cache_downloads(manager, 'electron') - - if self.electron_ffmpeg is not None: - if self.electron_ffmpeg == 'archive': - self._add_electron_cache_downloads(manager, - 'ffmpeg', - add_integrities=False) - elif self.electron_ffmpeg == 'lib': - for binary in manager.find_binaries('ffmpeg'): - assert binary.arch is not None - self.gen.add_archive_source(binary.url, - binary.integrity, - destination=self.gen.data_root, - only_arches=[binary.arch.flatpak]) - else: - assert False, self.electron_ffmpeg - - def _handle_gulp_atom_electron(self, package: Package) -> None: - # Versions after 1.22.0 use @electron/get and don't need this - if StrictVersion(package.version) <= StrictVersion('1.22.0'): - cache_path = self.gen.data_root / 'tmp' / 'gulp-electron-cache' / 'atom' / 'electron' - self.gen.add_command(f'mkdir -p "{cache_path.parent}"') - self.gen.add_command(f'ln -sfTr "{self.electron_cache_dir}" "{cache_path}"') - - async def _handle_electron_headers(self, package: Package) -> None: - if self.xdg_layout: - node_gyp_headers_dir = self.gen.data_root / 'cache' / 'node-gyp' / package.version - else: - node_gyp_headers_dir = self.gen.data_root / 'node-gyp' / 'electron-current' - url = f'https://www.electronjs.org/headers/v{package.version}/node-v{package.version}-headers.tar.gz' - metadata = await RemoteUrlMetadata.get(url, cachable=True) - self.gen.add_archive_source(url, - metadata.integrity, - destination=node_gyp_headers_dir) - if self.xdg_layout: - install_version_data = "9" - self.gen.add_data_source(install_version_data, - destination=node_gyp_headers_dir / 'installVersion') - - async def _get_chromedriver_binary_version(self, package: Package) -> str: - # Note: node-chromedriver seems to not have tagged all releases on GitHub, so - # just use unpkg instead. - url = urllib.parse.urljoin(NPM_MIRROR, f'chromedriver@{package.version}/lib/chromedriver') - js = await Requests.instance.read_all(url, cachable=True) - # XXX: a tad ugly - match = re.search(r"exports\.version = '([^']+)'", js.decode()) - assert match is not None, f'Failed to get ChromeDriver binary version from {url}' - return match.group(1) - - async def _handle_electron_chromedriver(self, package: Package) -> None: - manager = await ElectronBinaryManager.for_version(package.version) - self._add_electron_cache_downloads(manager, 'chromedriver') - - async def _handle_node_chromedriver(self, package: Package) -> None: - version = await self._get_chromedriver_binary_version(package) - destination = self.gen.data_root / 'chromedriver' - - if self.node_chromedriver_from_electron is not None: - manager = await ElectronBinaryManager.for_version( - self.node_chromedriver_from_electron) - - for binary in manager.find_binaries('chromedriver'): - assert binary.arch is not None - self.gen.add_archive_source(binary.url, - binary.integrity, - destination=destination, - only_arches=[binary.arch.flatpak]) - else: - url = (f'https://chromedriver.storage.googleapis.com/{version}/' - 'chromedriver_linux64.zip') - metadata = await RemoteUrlMetadata.get(url, cachable=True) - - self.gen.add_archive_source(url, - metadata.integrity, - destination=destination, - only_arches=['x86_64']) - - async def _add_nwjs_cache_downloads(self, version: str, flavor: str = 'normal'): - assert not version.startswith('v') - nwjs_mirror = 'https://dl.nwjs.io' - ffmpeg_dl_base = 'https://github.com/iteufel/nwjs-ffmpeg-prebuilt/releases/download' - - if self.nwjs_node_headers: - headers_dl_url = f'{nwjs_mirror}/v{version}/nw-headers-v{version}.tar.gz' - headers_dest = self.gen.data_root / 'node-gyp' / 'nwjs-current' - headers_metadata = await RemoteUrlMetadata.get(headers_dl_url, cachable=True) - self.gen.add_archive_source(headers_dl_url, - headers_metadata.integrity, - destination=headers_dest) - - if flavor == 'normal': - filename_base = 'nwjs' - else: - filename_base = f'nwjs-{flavor}' - - destdir = self.gen.data_root / 'nwjs-cache' - nwjs_arch_map = [ - ('x86_64', 'linux-x64', 'linux64'), - ('i386', 'linux-ia32', 'linux32'), - ] - for flatpak_arch, nwjs_arch, platform in nwjs_arch_map: - filename = f'{filename_base}-v{version}-{nwjs_arch}.tar.gz' - dl_url = f'{nwjs_mirror}/v{version}/{filename}' - metadata = await RemoteUrlMetadata.get(dl_url, cachable=True) - dest = destdir / f'{version}-{flavor}' / platform - - self.gen.add_archive_source(dl_url, - metadata.integrity, - destination=dest, - only_arches=[flatpak_arch]) - - if self.nwjs_ffmpeg: - ffmpeg_dl_url = f'{ffmpeg_dl_base}/{version}/{version}-{nwjs_arch}.zip' - ffmpeg_metadata = await RemoteUrlMetadata.get(ffmpeg_dl_url, cachable=True) - self.gen.add_archive_source(ffmpeg_dl_url, - ffmpeg_metadata.integrity, - destination=dest, - strip_components=0, - only_arches=[flatpak_arch]) - - async def _handle_nw_builder(self, package: Package) -> None: - if self.nwjs_version: - version = self.nwjs_version - else: - versions_json = json.loads(await Requests.instance.read_all( - 'https://nwjs.io/versions.json', cachable=False)) - version = versions_json['latest'].lstrip('v') - await self._add_nwjs_cache_downloads(version) - self.gen.add_data_source(version, destination=self.gen.data_root / 'nwjs-version') - - async def _handle_dugite_native(self, package: Package) -> None: - dl_json_url = urllib.parse.urljoin( - NPM_MIRROR, f'{package.name}@{package.version}/script/embedded-git.json') - dl_json = json.loads(await Requests.instance.read_all(dl_json_url, cachable=True)) - dugite_arch_map = { - 'x86_64': 'linux-x64', - } - destdir = self.gen.data_root / 'tmp' - for arch, dugite_arch in dugite_arch_map.items(): - url = dl_json[dugite_arch]['url'] - filename = dl_json[dugite_arch]['name'] - integrity = Integrity(algorithm='sha256', - digest=dl_json[dugite_arch]['checksum']) - - self.gen.add_url_source(url, - integrity, - destination=destdir / filename, - only_arches=[arch]) - - async def _handle_ripgrep_prebuilt(self, package: Package) -> None: - async def get_ripgrep_tag(version: str) -> str: - url = f'https://github.com/microsoft/vscode-ripgrep/raw/v{version}/lib/postinstall.js' - tag_re = re.compile(r"VERSION\s+=\s+'(v[\d.-]+)';") - resp = await Requests.instance.read_all(url, cachable=True) - match = tag_re.search(resp.decode()) - assert match is not None - return match.group(1) - - tag = await get_ripgrep_tag(package.version) - ripgrep_arch_map = { - 'x86_64': 'x86_64-unknown-linux-musl', - 'i386': 'i686-unknown-linux-musl', - 'arm': 'arm-unknown-linux-gnueabihf', - 'aarch64': 'aarch64-unknown-linux-gnu' - } - destdir = self.gen.data_root / 'tmp' / f'vscode-ripgrep-cache-{package.version}' - for arch, ripgrep_arch in ripgrep_arch_map.items(): - filename = f'ripgrep-{tag}-{ripgrep_arch}.tar.gz' - url = f'https://github.com/microsoft/ripgrep-prebuilt/releases/download/{tag}/{filename}' - metadata = await RemoteUrlMetadata.get(url, cachable=True) - self.gen.add_url_source(url, - metadata.integrity, - destination=destdir / filename, - only_arches=[arch]) - - async def _handle_playwright(self, package: Package) -> None: - base_url = f'https://github.com/microsoft/playwright/raw/v{package.version}/' - if StrictVersion(package.version) >= StrictVersion('1.16.0'): - browsers_json_url = base_url + 'packages/playwright-core/browsers.json' - else: - browsers_json_url = base_url + 'browsers.json' - browsers_json = json.loads(await Requests.instance.read_all(browsers_json_url, - cachable=True)) - for browser in browsers_json['browsers']: - if not browser.get('installByDefault', True): - continue - name = browser['name'] - revision = int(browser['revision']) - - if name == 'chromium': - if revision < 792639: - url_tp = 'https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/%d/%s' - dl_file = 'chrome-linux.zip' - else: - url_tp = 'https://playwright.azureedge.net/builds/chromium/%d/%s' - dl_file = 'chromium-linux.zip' - elif name == 'firefox': - url_tp = 'https://playwright.azureedge.net/builds/firefox/%d/%s' - if revision < 1140: - dl_file = 'firefox-linux.zip' - else: - dl_file = 'firefox-ubuntu-18.04.zip' - elif name == 'webkit': - url_tp = 'https://playwright.azureedge.net/builds/webkit/%d/%s' - if revision < 1317: - dl_file = 'minibrowser-gtk-wpe.zip' - else: - dl_file = 'webkit-ubuntu-20.04.zip' - elif name == 'ffmpeg': - url_tp = 'https://playwright.azureedge.net/builds/ffmpeg/%d/%s' - dl_file = 'ffmpeg-linux.zip' - else: - raise ValueError(f'Unknown playwright browser {name}') - - dl_url = url_tp % (revision, dl_file) - metadata = await RemoteUrlMetadata.get(dl_url, cachable=True) - destdir = self.gen.data_root / 'cache' / 'ms-playwright' / f'{name}-{revision}' - self.gen.add_archive_source(dl_url, - metadata.integrity, - destination=destdir, - strip_components=0) - # Arbitrary string here; flatpak-builder segfaults on empty data: url - self.gen.add_data_source("flatpak-node-cache", - destination=destdir / 'INSTALLATION_COMPLETE') - - async def _handle_esbuild(self, package: Package) -> None: - pkg_names = { - 'x86_64': 'esbuild-linux-64', - 'i386': 'esbuild-linux-32', - 'arm': 'esbuild-linux-arm', - 'aarch64': 'esbuild-linux-arm64' - } - - for flatpak_arch, pkg_name in pkg_names.items(): - dl_url = f'https://registry.npmjs.org/{pkg_name}/-/{pkg_name}-{package.version}.tgz' - metadata = await RemoteUrlMetadata.get(dl_url, cachable=True) - - cache_dst = self.gen.data_root / 'cache' / 'esbuild' - archive_dst = cache_dst / '.package' / f'{pkg_name}@{package.version}' - bin_src = archive_dst / 'bin' / 'esbuild' - bin_dst = cache_dst / 'bin' / f'{pkg_name}@{package.version}' - - self.gen.add_archive_source(dl_url, - metadata.integrity, - destination=archive_dst, - only_arches=[flatpak_arch], - strip_components=1) - - cmd = [ - f'mkdir -p "{bin_dst.parent.relative_to(cache_dst)}"', - f'cp "{bin_src.relative_to(cache_dst)}" "{bin_dst.relative_to(cache_dst)}"', - f'ln -sf "{bin_dst.name}" "bin/esbuild-current"' - ] - self.gen.add_shell_source(cmd, - only_arches=[flatpak_arch], - destination=cache_dst) - - def _handle_electron_builder(self, package: Package) -> None: - destination = self.gen.data_root / 'electron-builder-arch-args.sh' - - script: List[str] = [] - script.append('case "$FLATPAK_ARCH" in') - - for electron_arch, flatpak_arch in ( - ElectronBinaryManager.ELECTRON_ARCHES_TO_FLATPAK.items()): - script.append(f'"{flatpak_arch}")') - script.append(f' export ELECTRON_BUILDER_ARCH_ARGS="--{electron_arch}"') - script.append(' ;;') - - script.append('esac') - - self.gen.add_script_source(script, destination) - - async def generate_special_sources(self, package: Package) -> None: - if isinstance(Requests.instance, StubRequests): - # This is going to crash and burn. - return - - if package.name == 'electron': - await self._handle_electron(package) - if self.electron_node_headers or self.xdg_layout: - await self._handle_electron_headers(package) - elif package.name == 'electron-chromedriver': - await self._handle_electron_chromedriver(package) - elif package.name == 'chromedriver': - await self._handle_node_chromedriver(package) - elif package.name == 'electron-builder': - self._handle_electron_builder(package) - elif package.name == 'gulp-atom-electron': - self._handle_gulp_atom_electron(package) - elif package.name == 'nw-builder': - await self._handle_nw_builder(package) - elif package.name in {'dugite', '@shiftkey/dugite'}: - await self._handle_dugite_native(package) - elif package.name == 'vscode-ripgrep': - await self._handle_ripgrep_prebuilt(package) - elif package.name == 'playwright': - await self._handle_playwright(package) - elif package.name == 'esbuild': - await self._handle_esbuild(package) - - -class NpmLockfileProvider(LockfileProvider): - class Options(NamedTuple): - no_devel: bool - - def __init__(self, options: Options): - self.no_devel = options.no_devel - - def process_dependencies( - self, lockfile: Path, - dependencies: Dict[str, Dict[Any, Any]]) -> Iterator[Package]: - for name, info in dependencies.items(): - if info.get('dev') and self.no_devel: - continue - elif info.get('bundled'): - continue - - version: str = info['version'] - - source: PackageSource - if info.get('from'): - git_source = self.parse_git_source(version, info['from']) - source = git_source - else: - # NOTE: npm ignores the resolved field and just uses the provided - # registry instead. We follow the same behavior here. - source = UnresolvedRegistrySource() - - yield Package(name=name, version=version, source=source, lockfile=lockfile) - - if 'dependencies' in info: - yield from self.process_dependencies(lockfile, info['dependencies']) - - def process_lockfile(self, lockfile: Path) -> Iterator[Package]: - with open(lockfile) as fp: - data = json.load(fp) - - assert data['lockfileVersion'] <= 2, data['lockfileVersion'] - - yield from self.process_dependencies(lockfile, data.get('dependencies', {})) - - -class NpmModuleProvider(ModuleProvider): - class Options(NamedTuple): - registry: str - no_autopatch: bool - no_trim_index: bool - - class RegistryPackageIndex(NamedTuple): - url: str - data: Dict[Any, Any] - used_versions: Set[str] - - def __init__(self, gen: ManifestGenerator, special: SpecialSourceProvider, - lockfile_root: Path, options: Options) -> None: - self.gen = gen - self.special_source_provider = special - self.lockfile_root = lockfile_root - self.registry = options.registry - self.no_autopatch = options.no_autopatch - self.no_trim_index = options.no_trim_index - self.npm_cache_dir = self.gen.data_root / 'npm-cache' - self.cacache_dir = self.npm_cache_dir / '_cacache' - # Awaitable so multiple tasks can be waiting on the same package info. - self.registry_packages: Dict[ - str, asyncio.Future[NpmModuleProvider.RegistryPackageIndex]] = {} - self.index_entries: Dict[Path, str] = {} - self.all_lockfiles: Set[Path] = set() - # Mapping of lockfiles to a dict of the Git source target paths and GitSource objects. - self.git_sources: DefaultDict[Path, Dict[ - Path, GitSource]] = collections.defaultdict(lambda: {}) - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - tb: Optional[types.TracebackType]) -> None: - self._finalize() - - def get_cacache_integrity_path(self, integrity: Integrity) -> Path: - digest = integrity.digest - return Path(digest[0:2]) / digest[2:4] / digest[4:] - - def get_cacache_index_path(self, integrity: Integrity) -> Path: - return self.cacache_dir / Path('index-v5') / self.get_cacache_integrity_path( - integrity) - - def get_cacache_content_path(self, integrity: Integrity) -> Path: - return (self.cacache_dir / Path('content-v2') / integrity.algorithm / - self.get_cacache_integrity_path(integrity)) - - def add_index_entry(self, url: str, metadata: RemoteUrlMetadata) -> None: - key = f'make-fetch-happen:request-cache:{url}' - index_json = json.dumps({ - 'key': - key, - 'integrity': - f'{metadata.integrity.algorithm}-{metadata.integrity.to_base64()}', - 'time': - 0, - 'size': - metadata.size, - 'metadata': { - 'url': url, - 'reqHeaders': {}, - 'resHeaders': {}, - }, - }) - - content_integrity = Integrity.generate(index_json, algorithm='sha1') - index = '\t'.join((content_integrity.digest, index_json)) - - key_integrity = Integrity.generate(key) - index_path = self.get_cacache_index_path(key_integrity) - self.index_entries[index_path] = index - - async def resolve_source(self, package: Package) -> ResolvedSource: - # These results are going to be the same each time. - if package.name not in self.registry_packages: - cache_future = asyncio.get_event_loop().create_future() - self.registry_packages[package.name] = cache_future - - data_url = f'{self.registry}/{package.name.replace("/", "%2f")}' - # NOTE: Not cachable, because this is an API call. - raw_data = await Requests.instance.read_all(data_url, cachable=False) - data = json.loads(raw_data) - - assert 'versions' in data, f'{data_url} returned an invalid package index' - cache_future.set_result( - NpmModuleProvider.RegistryPackageIndex(url=data_url, - data=data, - used_versions=set())) - - if not self.no_trim_index: - for key in list(data): - if key != 'versions': - del data[key] - - index = await self.registry_packages[package.name] - - versions = index.data['versions'] - assert package.version in versions, \ - f'{package.name} versions available are {", ".join(versions)}, not {package.version}' - - dist = versions[package.version]['dist'] - assert 'tarball' in dist, f'{package.name}@{package.version} has no tarball in dist' - - index.used_versions.add(package.version) - - integrity: Integrity - if 'integrity' in dist: - integrity = Integrity.parse(dist['integrity']) - elif 'shasum' in dist: - integrity = Integrity.from_sha1(dist['shasum']) - else: - assert False, f'{package.name}@{package.version} has no integrity in dist' - - return ResolvedSource(resolved=dist['tarball'], integrity=integrity) - - async def generate_package(self, package: Package) -> None: - self.all_lockfiles.add(package.lockfile) - source = package.source - - assert not isinstance(source, ResolvedSource) - - if isinstance(source, UnresolvedRegistrySource): - source = await self.resolve_source(package) - assert source.resolved is not None - assert source.integrity is not None - - integrity = await source.retrieve_integrity() - size = await RemoteUrlMetadata.get_size(source.resolved, cachable=True) - metadata = RemoteUrlMetadata(integrity=integrity, size=size) - content_path = self.get_cacache_content_path(integrity) - self.gen.add_url_source(source.resolved, integrity, content_path) - self.add_index_entry(source.resolved, metadata) - - await self.special_source_provider.generate_special_sources(package) - - # pyright: reportUnnecessaryIsInstance=false - elif isinstance(source, GitSource): - # Get a unique name to use for the Git repository folder. - name = f'{package.name}-{source.commit}' - path = self.gen.data_root / 'git-packages' / name - self.git_sources[package.lockfile][path] = source - self.gen.add_git_source(source.url, source.commit, path) - - def relative_lockfile_dir(self, lockfile: Path) -> Path: - return lockfile.parent.relative_to(self.lockfile_root) - - def _finalize(self) -> None: - for _, async_index in self.registry_packages.items(): - index = async_index.result() - - if not self.no_trim_index: - for version in list(index.data['versions'].keys()): - if version not in index.used_versions: - del index.data['versions'][version] - - raw_data = json.dumps(index.data).encode() - - metadata = RemoteUrlMetadata(integrity=Integrity.generate(raw_data), - size=len(raw_data)) - content_path = self.get_cacache_content_path(metadata.integrity) - self.gen.add_data_source(raw_data, content_path) - self.add_index_entry(index.url, metadata) - - patch_commands: DefaultDict[Path, List[str]] = collections.defaultdict(lambda: []) - - if self.git_sources: - # Generate jq scripts to patch the package*.json files. - scripts = { - 'package.json': - r''' - walk( - if type == "object" - then - to_entries | map( - if (.value | type == "string") and $data[.value] - then .value = "git+file:\($buildroot)/\($data[.value])" - else . - end - ) | from_entries - else . - end - ) - ''', - 'package-lock.json': - r''' - walk( - if type == "object" and (.version | type == "string") and $data[.version] - then - .version = "git+file:\($buildroot)/\($data[.version])" - else . - end - ) - ''', - } - - for lockfile, sources in self.git_sources.items(): - prefix = self.relative_lockfile_dir(lockfile) - data: Dict[str, Dict[str, str]] = { - 'package.json': {}, - 'package-lock.json': {}, - } - - for path, source in sources.items(): - original_version = f'{source.original}' - new_version = f'{path}#{source.commit}' - assert source.from_ is not None - data['package.json'][source.from_] = new_version - data['package-lock.json'][original_version] = new_version - - for filename, script in scripts.items(): - target = Path('$FLATPAK_BUILDER_BUILDDIR') / prefix / filename - script = textwrap.dedent(script.lstrip('\n')).strip().replace( - '\n', '') - json_data = json.dumps(data[filename]) - patch_commands[lockfile].append( - 'jq' - ' --arg buildroot "$FLATPAK_BUILDER_BUILDDIR"' - f' --argjson data {shlex.quote(json_data)}' - f' {shlex.quote(script)} {target}' - f' > {target}.new') - patch_commands[lockfile].append(f'mv {target}{{.new,}}') - - patch_all_commands: List[str] = [] - for lockfile in self.all_lockfiles: - patch_dest = self.gen.data_root / 'patch' / self.relative_lockfile_dir( - lockfile) - # Don't use with_extension to avoid problems if the package has a . in its name. - patch_dest = patch_dest.with_name(patch_dest.name + '.sh') - - self.gen.add_script_source(patch_commands[lockfile], patch_dest) - patch_all_commands.append(f'$FLATPAK_BUILDER_BUILDDIR/{patch_dest}') - - patch_all_dest = self.gen.data_root / 'patch-all.sh' - self.gen.add_script_source(patch_all_commands, patch_all_dest) - - if not self.no_autopatch: - # FLATPAK_BUILDER_BUILDDIR isn't defined yet for script sources. - self.gen.add_command(f'FLATPAK_BUILDER_BUILDDIR=$PWD {patch_all_dest}') - - if self.index_entries: - for path, entry in self.index_entries.items(): - self.gen.add_data_source(entry, path) - - -class YarnLockfileProvider(LockfileProvider): - @staticmethod - def is_git_version(version: str) -> bool: - for pattern in GIT_URL_PATTERNS: - if pattern.match(version): - return True - url = urllib.parse.urlparse(version) - if url.netloc in GIT_URL_HOSTS: - return len([p for p in url.path.split("/") if p]) == 2 - return False - - def unquote(self, string: str) -> str: - if string.startswith('"'): - assert string.endswith('"') - return string[1:-1] - else: - return string - - def parse_package_section(self, lockfile: Path, section: List[str]) -> Package: - assert section - name_line = section[0] - assert name_line.endswith(':'), name_line - name_line = name_line[:-1] - - name = self.unquote(name_line.split(',', 1)[0]) - name, _ = name.rsplit('@', 1) - - version: Optional[str] = None - resolved: Optional[str] = None - integrity: Optional[Integrity] = None - - section_indent = 0 - - line = None - for line in section[1:]: - indent = 0 - while line[indent].isspace(): - indent += 1 - - assert indent, line - if not section_indent: - section_indent = indent - elif indent > section_indent: - # Inside some nested section. - continue - - line = line.strip() - if line.startswith('version'): - version = self.unquote(line.split(' ', 1)[1]) - elif line.startswith('resolved'): - resolved = self.unquote(line.split(' ', 1)[1]) - elif line.startswith('integrity'): - _, values_str = line.split(' ', 1) - values = self.unquote(values_str).split(' ') - integrity = Integrity.parse(values[0]) - - assert version and resolved, line - - source: PackageSource - if self.is_git_version(resolved): - source = self.parse_git_source(version=resolved) - else: - source = ResolvedSource(resolved=resolved, integrity=integrity) - - return Package(name=name, version=version, source=source, lockfile=lockfile) - - def process_lockfile(self, lockfile: Path) -> Iterator[Package]: - section: List[str] = [] - - with open(lockfile) as fp: - for line in map(str.rstrip, fp): - if not line.strip() or line.strip().startswith('#'): - continue - - if not line[0].isspace(): - if section: - yield self.parse_package_section(lockfile, section) - section = [] - - section.append(line) - - if section: - yield self.parse_package_section(lockfile, section) - - -class YarnModuleProvider(ModuleProvider): - # From https://github.com/yarnpkg/yarn/blob/v1.22.4/src/fetchers/tarball-fetcher.js - _PACKAGE_TARBALL_URL_RE = re.compile( - r'(?:(@[^/]+)(?:/|%2f))?[^/]+/(?:-|_attachments)/(?:@[^/]+/)?([^/]+)$') - - def __init__(self, gen: ManifestGenerator, special: SpecialSourceProvider) -> None: - self.gen = gen - self.special_source_provider = special - self.mirror_dir = self.gen.data_root / 'yarn-mirror' - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - tb: Optional[types.TracebackType]) -> None: - pass - - async def generate_package(self, package: Package) -> None: - source = package.source - - if isinstance(source, ResolvedSource): - integrity = await source.retrieve_integrity() - url_parts = urllib.parse.urlparse(source.resolved) - match = self._PACKAGE_TARBALL_URL_RE.search(url_parts.path) - if match is not None: - scope, filename = match.groups() - if scope: - filename = f'{scope}-{filename}' - else: - filename = os.path.basename(url_parts.path) - - self.gen.add_url_source(source.resolved, integrity, - self.mirror_dir / filename) - - elif isinstance(source, GitSource): - repo_name = urllib.parse.urlparse(source.url).path.split('/')[-1] - name = f'{repo_name}-{source.commit}' - repo_dir = self.gen.tmp_root / name - target_tar = os.path.relpath(self.mirror_dir / name, repo_dir) - - self.gen.add_git_source(source.url, source.commit, repo_dir) - self.gen.add_command( - f'cd {repo_dir}; git archive --format tar -o {target_tar} HEAD') - - await self.special_source_provider.generate_special_sources(package) - - -class ProviderFactory: - def create_lockfile_provider(self) -> LockfileProvider: - raise NotImplementedError() - - def create_module_provider(self, gen: ManifestGenerator, - special: SpecialSourceProvider) -> ModuleProvider: - raise NotImplementedError() - - -class NpmProviderFactory(ProviderFactory): - class Options(NamedTuple): - lockfile: NpmLockfileProvider.Options - module: NpmModuleProvider.Options - - def __init__(self, lockfile_root: Path, options: Options) -> None: - self.lockfile_root = lockfile_root - self.options = options - - def create_lockfile_provider(self) -> NpmLockfileProvider: - return NpmLockfileProvider(self.options.lockfile) - - def create_module_provider(self, gen: ManifestGenerator, - special: SpecialSourceProvider) -> NpmModuleProvider: - return NpmModuleProvider(gen, special, self.lockfile_root, self.options.module) - - -class YarnProviderFactory(ProviderFactory): - def __init__(self) -> None: - pass - - def create_lockfile_provider(self) -> YarnLockfileProvider: - return YarnLockfileProvider() - - def create_module_provider(self, gen: ManifestGenerator, - special: SpecialSourceProvider) -> YarnModuleProvider: - return YarnModuleProvider(gen, special) - - -class GeneratorProgress(contextlib.AbstractContextManager): - def __init__(self, packages: Collection[Package], - module_provider: ModuleProvider) -> None: - self.finished = 0 - self.packages = packages - self.module_provider = module_provider - self.previous_package: Optional[Package] = None - self.current_package: Optional[Package] = None - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - tb: Optional[types.TracebackType]) -> None: - print() - - def _format_package(self, package: Package, max_width: int) -> str: - result = f'{package.name} @ {package.version}' - - if len(result) > max_width: - result = result[:max_width - 3] + '...' - - return result - - def _update(self) -> None: - columns, _ = shutil.get_terminal_size() - - sys.stdout.write('\r' + ' ' * columns) - - prefix_string = f'\rGenerating packages [{self.finished}/{len(self.packages)}] ' - sys.stdout.write(prefix_string) - max_package_width = columns - len(prefix_string) - - if self.current_package is not None: - sys.stdout.write(self._format_package(self.current_package, - max_package_width)) - - sys.stdout.flush() - - def _update_with_package(self, package: Package) -> None: - self.previous_package, self.current_package = self.current_package, package - self._update() - - async def _generate(self, package: Package) -> None: - self._update_with_package(package) - await self.module_provider.generate_package(package) - self.finished += 1 - self._update_with_package(package) - - async def run(self) -> None: - self._update() - await asyncio.wait( - [asyncio.create_task(self._generate(pkg)) for pkg in self.packages]) - - -def scan_for_lockfiles(base: Path, patterns: List[str]) -> Iterator[Path]: - for root, _, files in os.walk(base.parent): - if base.name in files: - lockfile = Path(root) / base.name - if not patterns or any(map(lockfile.match, patterns)): - yield lockfile - - -async def main() -> None: - parser = argparse.ArgumentParser(description='Flatpak Node generator') - parser.add_argument('type', choices=['npm', 'yarn']) - parser.add_argument('lockfile', - help='The lockfile path (package-lock.json or yarn.lock)') - parser.add_argument('-o', - '--output', - help='The output sources file', - default='generated-sources.json') - parser.add_argument( - '-r', - '--recursive', - action='store_true', - help='Recursively process all files under the lockfile directory with ' - 'the lockfile basename') - parser.add_argument( - '-R', - '--recursive-pattern', - action='append', - help='Given -r, restrict files to those matching the given pattern.') - parser.add_argument('--registry', - help='The registry to use (npm only)', - default='https://registry.npmjs.org') - parser.add_argument('--no-trim-index', - action='store_true', - help="Don't trim npm package metadata (npm only)") - parser.add_argument('--no-devel', - action='store_true', - help="Don't include devel dependencies (npm only)") - parser.add_argument('--no-aiohttp', - action='store_true', - help="Don't use aiohttp, and silence any warnings related to it") - parser.add_argument('--no-requests-cache', - action='store_true', - help='Disable the requests cache') - parser.add_argument('--retries', - type=int, - help='Number of retries of failed requests', - default=Requests.DEFAULT_RETRIES) - parser.add_argument('-P', - '--no-autopatch', - action='store_true', - help="Don't automatically patch Git sources from package*.json") - parser.add_argument('-s', - '--split', - action='store_true', - help='Split the sources file to fit onto GitHub.') - parser.add_argument('--node-chromedriver-from-electron', - help='Use the ChromeDriver version associated with the given ' - 'Electron version for node-chromedriver') - # Deprecated alternative to --node-chromedriver-from-electron - parser.add_argument('--electron-chromedriver', help=argparse.SUPPRESS) - parser.add_argument('--electron-ffmpeg', - choices=['archive', 'lib'], - help='Download prebuilt ffmpeg for matching electron version') - parser.add_argument('--electron-node-headers', - action='store_true', - help='Download the electron node headers') - parser.add_argument('--nwjs-version', - help='Specify NW.js version (will use latest otherwise)') - parser.add_argument('--nwjs-node-headers', - action='store_true', - help='Download the NW.js node headers') - parser.add_argument('--nwjs-ffmpeg', action='store_true', - help='Download prebuilt ffmpeg for current NW.js version') - parser.add_argument('--xdg-layout', - action='store_true', - help='Use XDG layout for caches') - # Internal option, useful for testing. - parser.add_argument('--stub-requests', action='store_true', help=argparse.SUPPRESS) - - args = parser.parse_args() - - Requests.retries = args.retries - - if args.type == 'yarn' and (args.no_devel or args.no_autopatch): - sys.exit('--no-devel and --no-autopatch do not apply to Yarn.') - - if args.electron_chromedriver: - print('WARNING: --electron-chromedriver is deprecated', file=sys.stderr) - print(' (Use --node-chromedriver-from-electron instead.)', file=sys.stderr) - - if args.stub_requests: - Requests.instance = StubRequests() - elif args.no_aiohttp: - if Requests.instance.is_async: - Requests.instance = UrllibRequests() - elif not Requests.instance.is_async: - print('WARNING: aiohttp is not found, performance will suffer.', file=sys.stderr) - print(' (Pass --no-aiohttp to silence this warning.)', file=sys.stderr) - - if not args.no_requests_cache: - Cache.instance = FilesystemBasedCache() - - lockfiles: List[Path] - if args.recursive or args.recursive_pattern: - lockfiles = list(scan_for_lockfiles(Path(args.lockfile), args.recursive_pattern)) - if not lockfiles: - sys.exit('No lockfiles found.') - print(f'Found {len(lockfiles)} lockfiles.') - else: - lockfiles = [Path(args.lockfile)] - - lockfile_root = Path(args.lockfile).parent - - provider_factory: ProviderFactory - if args.type == 'npm': - npm_options = NpmProviderFactory.Options( - NpmLockfileProvider.Options(no_devel=args.no_devel), - NpmModuleProvider.Options(registry=args.registry, - no_autopatch=args.no_autopatch, - no_trim_index=args.no_trim_index)) - provider_factory = NpmProviderFactory(lockfile_root, npm_options) - elif args.type == 'yarn': - provider_factory = YarnProviderFactory() - else: - assert False, args.type - - print('Reading packages from lockfiles...') - packages: Set[Package] = set() - - for lockfile in lockfiles: - lockfile_provider = provider_factory.create_lockfile_provider() - packages.update(lockfile_provider.process_lockfile(lockfile)) - - print(f'{len(packages)} packages read.') - - gen = ManifestGenerator() - with gen: - options = SpecialSourceProvider.Options( - node_chromedriver_from_electron=args.node_chromedriver_from_electron - or args.electron_chromedriver, - nwjs_version=args.nwjs_version, - nwjs_node_headers=args.nwjs_node_headers, - nwjs_ffmpeg=args.nwjs_ffmpeg, - xdg_layout=args.xdg_layout, - electron_ffmpeg=args.electron_ffmpeg, - electron_node_headers=args.electron_node_headers) - special = SpecialSourceProvider(gen, options) - - with provider_factory.create_module_provider(gen, special) as module_provider: - with GeneratorProgress(packages, module_provider) as progress: - await progress.run() - - if args.xdg_layout: - script_name = "setup_sdk_node_headers.sh" - node_gyp_dir = gen.data_root / "cache" / "node-gyp" - gen.add_script_source([ - 'version=$(node --version | sed "s/^v//")', - 'nodedir=$(dirname "$(dirname "$(which node)")")', - f'mkdir -p "{node_gyp_dir}/$version"', - f'ln -s "$nodedir/include" "{node_gyp_dir}/$version/include"', - f'echo 9 > "{node_gyp_dir}/$version/installVersion"', - ], - destination=gen.data_root / script_name) - gen.add_command(f"bash {gen.data_root / script_name}") - - if args.split: - i = 0 - for i, part in enumerate(gen.split_sources()): - output = Path(args.output) - output = output.with_suffix(f'.{i}{output.suffix}') - with open(output, 'w') as fp: - json.dump(part, fp, indent=ManifestGenerator.JSON_INDENT) - - print(f'Wrote {gen.source_count} to {i + 1} file(s).') - else: - with open(args.output, 'w') as fp: - json.dump(list(gen.ordered_sources()), - fp, - indent=ManifestGenerator.JSON_INDENT) - - if fp.tell() >= ManifestGenerator.MAX_GITHUB_SIZE: - print('WARNING: generated-sources.json is too large for GitHub.', - file=sys.stderr) - print(' (Pass -s to enable splitting.)') - - print(f'Wrote {gen.source_count} source(s).') - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/flatpak/generated-sources.json b/flatpak/generated-sources.json deleted file mode 100644 index a629990e..00000000 --- a/flatpak/generated-sources.json +++ /dev/null @@ -1,7600 +0,0 @@ -[ - { - "type": "file", - "url": "https://codeload.github.com/bitfocus/node-dns-js/tar.gz/e5f0c3da63653398005bf36f66ad0b77770dcad6", - "sha256": "bf7bfb00f51ea158aa1f6a76814fbc5f6123bc089c7861caca96202a3c679389", - "dest-filename": "e5f0c3da63653398005bf36f66ad0b77770dcad6", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://codeload.github.com/bitfocus/node-mdns-js/tar.gz/1af6b83ce91e5538012f977e1dcadbda5dc0d3b5", - "sha256": "0f4ffd7064e01fff4455f14413d20f6c6a3e1119aa9a4de40d268bbf914a785c", - "dest-filename": "1af6b83ce91e5538012f977e1dcadbda5dc0d3b5", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://codeload.github.com/devsnek/node-register-scheme/tar.gz/e7cc9a63a1f512565da44cb57316d9fb10750e17", - "sha256": "ab95956c7df0d1252400d97a9b62c7c2e807f41c38629471dc0f41723aa7ff17", - "dest-filename": "e7cc9a63a1f512565da44cb57316d9fb10750e17", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://github.com/electron/electron/releases/download/v17.0.0-beta.8/SHASUMS256.txt", - "sha256": "3272f07d071093b3fae5ba6f11fd7b1889edc77fb5a5876ad9bb40b95ea4feda", - "dest-filename": "SHASUMS256.txt-17.0.0-beta.8", - "dest": "flatpak-node/electron-cache" - }, - { - "type": "file", - "url": "https://github.com/electron/electron/releases/download/v17.0.0-beta.8/electron-v17.0.0-beta.8-linux-arm64.zip", - "sha256": "fd116b98d965f435b1ac6696308297fd995e91c040c24f02081b1eb3705eb114", - "dest-filename": "electron-v17.0.0-beta.8-linux-arm64.zip", - "dest": "flatpak-node/electron-cache", - "only-arches": [ - "aarch64" - ] - }, - { - "type": "file", - "url": "https://github.com/electron/electron/releases/download/v17.0.0-beta.8/electron-v17.0.0-beta.8-linux-armv7l.zip", - "sha256": "f6d7bc963b27930a4f9c367a9dfea26214bb309bad9cc6e7594adbcb90ac5cc6", - "dest-filename": "electron-v17.0.0-beta.8-linux-armv7l.zip", - "dest": "flatpak-node/electron-cache", - "only-arches": [ - "arm" - ] - }, - { - "type": "file", - "url": "https://github.com/electron/electron/releases/download/v17.0.0-beta.8/electron-v17.0.0-beta.8-linux-ia32.zip", - "sha256": "96e99d642835a98332f320e8ffb94180632c5c37023acaed26c775b2c5712035", - "dest-filename": "electron-v17.0.0-beta.8-linux-ia32.zip", - "dest": "flatpak-node/electron-cache", - "only-arches": [ - "i386" - ] - }, - { - "type": "file", - "url": "https://github.com/electron/electron/releases/download/v17.0.0-beta.8/electron-v17.0.0-beta.8-linux-x64.zip", - "sha256": "d346cdb4b333caa6078b4c2196d45e9a3a631cf46fef109ce78e423089e82e85", - "dest-filename": "electron-v17.0.0-beta.8-linux-x64.zip", - "dest": "flatpak-node/electron-cache", - "only-arches": [ - "x86_64" - ] - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.1.1.tgz#9274ec7460652f9c632c59addf24efb1684ef876", - "sha512": "b003f82e575e58dcf494dce64e2adddee59f1435964de83a57f32c9b2c8b47d5f589dc0a056220b7f66f8a7a9095d266dcb79c284b357a691baae3ba3c288b55", - "dest-filename": "7zip-bin-5.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30", - "sha1": "9cafb171af82329490353b4816f03347aa150a30", - "dest-filename": "7zip-0.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789", - "sha512": "8805ea527f0821e05335def6c6c16581a5c790c04cb7acb81c9a75b4868ae3ae4258b4ff7c6d5aa81ef292bf798071e69417466c579659fc81e0d249d2799e22", - "dest-filename": "@babel-code-frame-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60", - "sha512": "9bb3a45f421d28b28fa41949b45e7ad5825a979cbf8f22397cd7d66cfc61d83fe76f3cc6238a91cab0fcc4eda3076e2eee5fb92366b8dec7021b622b7e30b9d1", - "dest-filename": "@babel-compat-data-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/core/-/core-7.16.12.tgz#5edc53c1b71e54881315923ae2aedea2522bb784", - "sha512": "74ae4fb46d6e88dda2924fbee4ecd262c8ad64a9f2e303820f49eb3b84ea9d6e015414d0d8d192dcd82296f4ff4c4cb14d24fb2cdc9657f4f8b570e80f77ce82", - "dest-filename": "@babel-core-7.16.12.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe", - "sha512": "d688d9c04f7e94e5f371675698ee936d4cc37ea2c3dfd0a612137cfb6717f57903a39c96d4ea607de8df962cac4760162e931a99388e880a7f9adae86b29a1a7", - "dest-filename": "@babel-generator-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862", - "sha512": "b3ab76c3f20f4154c0113d478ada28c11197a285fc98282db8fe75f79c03fd024f57ac188e9ba308617b26e30e0d55f664024e7f5193e834fd307119bcb3854b", - "dest-filename": "@babel-helper-annotate-as-pure-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b", - "sha512": "0ba15d6d16b1623c15bbf81e296e19790d10df501fb6045c7529d9e7f8ec1fa0730896edbd7be1a5f91b9138584aebad640ee7097a4f47a003f73775769acc90", - "dest-filename": "@babel-helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b", - "sha512": "986a23070216730183eab7ea8115d59556263c0bfb78ea487a6506ddd1a70dd098e0f69eef444e8a3dd799fac7e856b58756a20f29698256d9ca4b5fcf2a3f84", - "dest-filename": "@babel-helper-compilation-targets-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c", - "sha512": "c0379e8f4a6edd637f7df4f130d08f5b950288e6aff0870b471488ca9ffdf88176c4950cf61fce6238342092c768be85f2853c92a333f67735bebc9784cb205e", - "dest-filename": "@babel-helper-create-class-features-plugin-7.16.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48", - "sha512": "7e4e40eb299fa7e3b9fa9db20a45c0bb92b28fabf4c61d1105e35c024614303bef000a31bd22979fe25bdfbb7fc961624150c52b510ba544c3f3f68b8423eefa", - "dest-filename": "@babel-helper-create-regexp-features-plugin-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665", - "sha512": "27d8463292509ad5a68f8e81de404798bdfc5212468585fb7aa91cabeda0b2cb7262ddf8d4798f796b298a15f8df2551034992fbc18693619c91cedb63f1c298", - "dest-filename": "@babel-helper-define-polyfill-provider-0.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7", - "sha512": "48b2dbd00027e8f9147807ca24208e97d7b5479de94251807dce32e17b8c4597ea78c60b13474cd4b321a9b180946418d257f0e7fa21a185807bd575ca26d16a", - "dest-filename": "@babel-helper-environment-visitor-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a", - "sha512": "2b251e9e158c0bc56bc739063f4262ce3a38fd9c7ed67359860a1cb3e80bcf267207c48789d868abd28affc02da386a7870b22bdf9012dfb64cbb82fcdb64cb5", - "dest-filename": "@babel-helper-explode-assignable-expression-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f", - "sha512": "41f0df127214cb20524771edaed1840ae67a0c0c82918169ec61e5ef9bc5b539e7ea98ca78ad13d4307994b905bc179af0c75a894001c77a2c6e02f2227a1e8c", - "dest-filename": "@babel-helper-function-name-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419", - "sha512": "7e573e44b48e057ccdcd585c2eeeae8de1d4ac3ead00d00e539a23ad1c7f6acfad6f37fcfacb540a3efe21f451a006c466a8ff6a15c432c8e13a181e66cae74f", - "dest-filename": "@babel-helper-get-function-arity-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246", - "sha512": "9b4e1dff43a9df81f9bfba5b670ea948a3fbc1e03a96c32f7e220031e22f918fd1e3142d05230512282ef504d9daa07ff65db6becc6d33c6be43c0b30f6e797e", - "dest-filename": "@babel-helper-hoist-variables-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0", - "sha512": "56d27feb9b58894ffa01b3130f0ca85c63ca1e04ec7d16ab8af9be61b079b80cca532b8f8e065280015e1bcec50a281ceca347bb63de821d57213de55e3bf3dd", - "dest-filename": "@babel-helper-member-expression-to-functions-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.35.tgz#308e350e731752cdb4d0f058df1d704925c64e0a", - "sha512": "bda0b52b22194aec966f72e3dbbedf5f4a718afc87c2e0d4e3166ca1faa06006e40f136278c836bee8733f902033078c63b7c24143138be0603ea4cb8e4c5716", - "dest-filename": "@babel-helper-module-imports-7.0.0-beta.35.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437", - "sha512": "2d5b52e93aa324715cfa761e213468e952d7bdeef4c66abbc0f8564ea0c9bac2448069a4000096c0c89336bbdfa10a3a844845c00222c4d92f0748cf5c32fc5a", - "dest-filename": "@babel-helper-module-imports-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41", - "sha512": "81aaad2c3c4910509e41b629f5a2c079f8e190a76329c761e8307b8e7888194dcfcf9d960263f6ebcccad1580fcfd85436431261e1fdefa2b6fd8eb23da7699e", - "dest-filename": "@babel-helper-module-transforms-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2", - "sha512": "12d801860eeb77f25c9e96455e9072d337b56117dd9bb067057e2e28c05dde2c5add1180134d3625907ae85272347ee0d05dfc534e695e60393fc70187bcfed7", - "dest-filename": "@babel-helper-optimise-call-expression-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5", - "sha512": "420dcd93b671a6032bb28c7a1eb798d5934a741abb2bbdad0d296203a7429797f4d3b8d1e277bc883e54cee3670891f6c417f60441151abfbf38be86769ed1c4", - "dest-filename": "@babel-helper-plugin-utils-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3", - "sha512": "7e6d201fb1656fc1f9d4ba891f2dc7277c27135faab5847603df4ad3a6a1c2b6b02dd385b021168d93ab62b89c5c91e83d2b9d34ac6b30150f1083f188822f07", - "dest-filename": "@babel-helper-remap-async-to-generator-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1", - "sha512": "cbdbec5a295335a567561eb18897c0073b0da600cf29ebfd1e7020cfa19bd69e945307fd35ea5d96c57b5571827ed24cfa3a83e5fec9204b9b7292e3663e5d07", - "dest-filename": "@babel-helper-replace-supers-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7", - "sha512": "648cc7572a1e2ccbd730dfefa24fdae0b591cbc1b6bf6d3998d3f45ceb9ff5744bc97e7fbbd0a756e954b438144da99ade54fe6dffd4aae72e663aa21ae4d2d6", - "dest-filename": "@babel-helper-simple-access-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09", - "sha512": "fa2975813cb4a07c14b01419c89bee91b078bcf31d71806b1476b451ce008b32f16eae813980b9d51bf8b56a1c5fd04b0432d9e2473aa9416943a1d180bfb7cf", - "dest-filename": "@babel-helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b", - "sha512": "c5b5a8cbf3c5a314966b3213a13f5289ffa325396b31c9dd22c68e2af4c0eaeed0128ee2964459a637b0d7cfd6ddcee79bc7d77540d7874d955d36d9d2918337", - "dest-filename": "@babel-helper-split-export-declaration-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad", - "sha512": "86c12715e99e896e03d3c039814019c4b0535e9677f4ff9af83183b07c35cb1ab243f8f31449f17f9b93106a7eddbcc06cd3b1535a5a4e0612e04094fc881f0f", - "dest-filename": "@babel-helper-validator-identifier-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23", - "sha512": "4d1b5e9ceb91515a3da084063c2e46f4380ae3be3771dc6fb4ec34c1e40da595da4b5e920818b930d8d917cbdb6b71135118d9a536d59fb56f71fd9e030168cd", - "dest-filename": "@babel-helper-validator-option-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200", - "sha512": "f11a724552005b545c0c319303e1a93c0c15db6c1709f28ea0cf5b7ade932e4188153911412907d67310e587ade0ca685ded59c073d5b4d6ac736c34b9932a9f", - "dest-filename": "@babel-helper-wrap-function-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc", - "sha512": "f590e8aad7d8ec0b843adddcc5c85f8a2e82ec60f2c8c05f7e4b51e41da3bd6bfcbb6f9e7f0be99d5297316ccd7a1ab2ebcb4a8007d2c1f770fe55a9b614b66f", - "dest-filename": "@babel-helpers-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88", - "sha512": "e459d340b48bb30123e88920570e4abac35450563d646a9efd34459cffc12981d881f87bb5cf82ee6c22cbde7fc8d3fb0e1f71e7cd15bfcafbbbb65f4c117177", - "dest-filename": "@babel-highlight-7.16.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6", - "sha512": "55f695d79a68f11899b2cae43f07b2bdb19549ee31db2f9a722142827d27d3f489311db6730a1f455d66b6725061c481d70513680fd7d4b9c0ddeb3ae8c08ee4", - "dest-filename": "@babel-parser-7.16.12.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050", - "sha512": "6a7bff0ce6e5ef06a21849c2db83bdcea2f4a52b88f619638a1aa20ee1470bc77bfdb8ebff844b18f5ae73cad839f7ff40fcdb10f4a4cc6f30186f5a0ee84746", - "dest-filename": "@babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9", - "sha512": "762f2f50745d7fee1a27b96d5e16836cfa2ccdd921e7d010b49339b282ecb87a5025d15064e038b868f4576bbf099f1b27fbbc50b0cbe72aba14efdb0979ca1f", - "dest-filename": "@babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8", - "sha512": "ef560722f32e8aea9625091e6d626d7614137dde10e2617beaad885f7eee64f906f7ea25071b17fab1f5be4845b68e1478967d74f636b3e983be10e6d6ed8119", - "dest-filename": "@babel-plugin-proposal-async-generator-functions-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0", - "sha512": "2286d4d1799edf57b08d839285222a77f64633faff72e3b3db3d0c0db36b845e455be655822d1fda5c9ea23f4a14f0ce02ab18c662d666d7b558ec25bd8f5ac3", - "dest-filename": "@babel-plugin-proposal-class-properties-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz#712357570b612106ef5426d13dc433ce0f200c2a", - "sha512": "760a8926b719a06ff80a4328a7384f2631b1b087bd03c4659102e72ff561871f0003d66e691c064a5b1c4a1e3685acdced64abc9afc82bb9937a81740cff6d13", - "dest-filename": "@babel-plugin-proposal-class-static-block-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2", - "sha512": "23c496f47a37ffc0d149d983747de039177252e6279359b870cc5401dbb9a32e27dce7cdf1f943107f9deb4886edd51f8b42a46304afa1a947cf3751ce95874e", - "dest-filename": "@babel-plugin-proposal-dynamic-import-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163", - "sha512": "67176da835cb44604beb8a1c65cb3ba2fb7bd4bde3842d51192c91f7deacbeb0a2dcf62a1cd91bdd2c0f242b3c448cc3f3ab3e58fa6dd92ef7f841c218ef8d50", - "dest-filename": "@babel-plugin-proposal-export-namespace-from-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8", - "sha512": "94d677104820b0663bf096af81b1ec2bdbb93f7a50696ee4e1ac658052d890c77b501b2235a8422134a12e3350b1c84fca3b4ee9d003acbdb8ef9ec876106bb1", - "dest-filename": "@babel-plugin-proposal-json-strings-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea", - "sha512": "2b75f3c99246402af4d3e12d62dac38e6c17ee8ecf2cae94f5b8b59c2c24422a1115552fe9d268c5b423b5656d3fe6c23f2f366ce341286f0d3f2438fa2eb28e", - "dest-filename": "@babel-plugin-proposal-logical-assignment-operators-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99", - "sha512": "6943ab614dc456d8dfeb68d0ac28fade9619ee4eaf9ecda1fc342f1cf5869ac25163359767afc0b1f829891cba5e2b880c00e12733f643d33048c29ab8143e51", - "dest-filename": "@babel-plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9", - "sha512": "bd080f3249ce2208ae56a6e8913a325db918fce9a68c0cebff49614886c6fca9a7cd73c6c16fc076174aa62f8ee17fd59168968e790a3818aa26b4da0bdf152b", - "dest-filename": "@babel-plugin-proposal-numeric-separator-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8", - "sha512": "dced18e3e770f781c0f3aa9283d2077f23e4b6047bab782935501e88a41dfbc8c1285694e4d412d586ad828e3063e50536e2e3bf17129b372c1eaae1813c8150", - "dest-filename": "@babel-plugin-proposal-object-rest-spread-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf", - "sha512": "78c387fcbe0ebd6499004d559076ebd6f7242c6d5651c1c62522eaa90c25d86694a86e908dd76face69350c3588afefb1f920a3cc67d53d3fb11a1f0bc04a17c", - "dest-filename": "@babel-plugin-proposal-optional-catch-binding-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a", - "sha512": "782df1cbe66b51c06d3fbc7eb2aeb643f1d877aef8a4f4dbffbed764c6f9c1b0cf19621d51b4abe0082bd39dbecda50f49bfa01919e3c577ca16fc7988c27e0c", - "dest-filename": "@babel-plugin-proposal-optional-chaining-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50", - "sha512": "17fdae0243e55c3afcf811e966fa35f70de12c52a07be93be57529ac4ea36aa2b18c691261c2bee1cf9bba9e4f756ffb5bf4698f0aa5ec54d51035be7d1010b3", - "dest-filename": "@babel-plugin-proposal-private-methods-7.16.11.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce", - "sha512": "acc4248dc3856e6fae7deddb4d92f239fb0e50ec72bcb5d92424c046126bfbc50c4a8666a937b52b506090572b5b7eeb01c856839ef223af4e471896bd420db9", - "dest-filename": "@babel-plugin-proposal-private-property-in-object-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2", - "sha512": "4112b4608ff8d152e13551888d13400109041f0b3472cc12745163a45cadf78dd8989214d5d6bdb96eb722ee8d155e82c53656e5e4c30abc1952cb415a0a7f46", - "dest-filename": "@babel-plugin-proposal-unicode-property-regex-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d", - "sha512": "b727266719067d96b184c45b5e53d7b95169756957a62af65b800c85226044ace4fde0e52173a16f62c75a82e90c5ed3107ca5579ccd872917e8a0201c999337", - "dest-filename": "@babel-plugin-syntax-async-generators-7.8.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10", - "sha512": "7e6e227632a56b461a85436014d2c2074ab249db283e264fde2404deb932d26054b4c676df20c9f5225d83a7574d20e7ba5395aa21771e0afd9db5ef5d341960", - "dest-filename": "@babel-plugin-syntax-class-properties-7.12.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406", - "sha512": "6fe6323e6afa95dc8d9cceaca9878c584f9b809709a4eeb24b8403ef29b1807df81813cd0ccfd31c187c8ae9f2bca219ced8b02c7e02259d11c5393d7a68298f", - "dest-filename": "@babel-plugin-syntax-class-static-block-7.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3", - "sha512": "e607466c5a27f8fb33633aacf374b71399a98bbff2ffc33d782f743114d97ddb903985bbea283a48e48f35ee35206e4ba0fdc51819f6374463543490892f7891", - "dest-filename": "@babel-plugin-syntax-dynamic-import-7.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a", - "sha512": "3177f995a5e8e9cd486c46de8039b318fc06353b07666132e901b39eee528765025afb9ecb06f679ef82084e3342266cb7153d04ca103bd8bacd41526342a3d1", - "dest-filename": "@babel-plugin-syntax-export-namespace-from-7.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a", - "sha512": "958ea4746a561ef8e87b6be4e16ac06a912e051ebd10cc5997e46819186b14635854af2638f016f157db4ff660ac56d794336289ac509c0b6054267a8efdf410", - "dest-filename": "@babel-plugin-syntax-json-strings-7.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699", - "sha512": "77cc1a4a19691438a743932dbc653dc4300ecca1f8efe145a277b2d9b68522832bf79da128e2e9d4747b56cce866f3ac57fe3e451b33358ec3d7b6dad2d7b48a", - "dest-filename": "@babel-plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9", - "sha512": "6927dfe333c8235bb6403ef2f85f280eccf5f5ec3820610983d4955be6eac29c2d7c595e8900cc77303f47e525583cdf9c7142c7195e153d0f308ad1dfa5cb35", - "dest-filename": "@babel-plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97", - "sha512": "f47e9875f91c2bfb8e9d8fcaeff680db1a73680824427dfbcb35943112bb39a3cea8ea464b5fa7d07e61c53f40530f44b128cf5bc495c8c270611b56b375f7ba", - "dest-filename": "@babel-plugin-syntax-numeric-separator-7.10.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871", - "sha512": "5e8a8c8a31996fdcb7cb65ec90df8fd70506895c16679266a03470c79fb71a612994dc95336b360e0f082c5426f2b58ce3ca2b1b2e58a48e4197c535cbbc9d94", - "dest-filename": "@babel-plugin-syntax-object-rest-spread-7.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1", - "sha512": "e953c3d0f7359694eac3468aa1e45332207e916840a13db83c0fa4b16481ac5b65e52211569665c0ddcd34f4237a103613ff75155dd18cb5a855382559c495dd", - "dest-filename": "@babel-plugin-syntax-optional-catch-binding-7.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a", - "sha512": "2a82bd12b1f53019423f15745403645d6dbf770e2f95b183ac5833f1b994b0119890545c6d1c0c87a70826e6dd3eb931470b8676d0a4d2fff03d329b42006392", - "dest-filename": "@babel-plugin-syntax-optional-chaining-7.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad", - "sha512": "d30567a7d77127bd995090d5dbb65f6d28fa8872e8cad6199a1deb15cc4d9efb0917792d9332c364fcbf980d7b1c6b1a413dff0d0b16617d5fd50196902a1552", - "dest-filename": "@babel-plugin-syntax-private-property-in-object-7.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c", - "sha512": "871fbeba92efe54d6b8187f07b5c41414851994e35344be952fae9f2392b48276f1929cce7fa9d44cb72949e8f1b938590168791b4c02939dddff63211244717", - "dest-filename": "@babel-plugin-syntax-top-level-await-7.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154", - "sha512": "f5f7e414531bbf34efbfeedd4e9ffaeb1bd9016012b8f0f94e5f4b2b767dbe13a600da3a8fde2b8a4fb960c06de02c0754c58b5a932cae221cdb3b1add65b7c5", - "dest-filename": "@babel-plugin-transform-arrow-functions-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808", - "sha512": "32d9949932501c29f2255ad270dccd9687d027774b16ea1b627de6c0e4ca1e748232d6cdb2abc5ef51909897c58ddad74ac000ee2cac166616c386d7676d213a", - "dest-filename": "@babel-plugin-transform-async-to-generator-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620", - "sha512": "254bb3973985e3467d717cb2b5c6d911929c920ad0cc285b409c3fe4fb841d87aacc2b2f79b0f1d0ad235a720855c9a60ce01572d0a09d8b34a4c72b623db326", - "dest-filename": "@babel-plugin-transform-block-scoped-functions-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87", - "sha512": "39b65ebf69f1540600e1b872bac10b768f616f71fe039e9bc47dc564c6c42266458840d85475d0489d6140a1650e796df06f5b06b099e59a5445952b5781b9a9", - "dest-filename": "@babel-plugin-transform-block-scoping-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00", - "sha512": "598ee8837f1214019845eeb806b8ca7fc3ab13aba5107b6be63118699330a31f4a79b82a3e2ebb66acfc2b9dc42a4d5f1442609bdeabdf6ae4299dea0369c259", - "dest-filename": "@babel-plugin-transform-classes-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470", - "sha512": "80def61bd6dc99e9d520b8fffecbf5ccb35a3f261c3b3521a36948241321fe26a427dca00a8fe1105f5ca466fad5208c103c5b6f2068550c6bb7e6d62aee4a1b", - "dest-filename": "@babel-plugin-transform-computed-properties-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23", - "sha512": "56a0308531c19eee710550c2bebbea25bb4b51afbea996960b4160af69aaa24065ba5640446c88bd90e8a9b3e53da288990f5d280702cdbbfeba5fffbaabbbd0", - "dest-filename": "@babel-plugin-transform-destructuring-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241", - "sha512": "2f2b6d69aa364a3645e8f7f8be4d5d54abfc632a4ca689806f2816fa65397183f74b97164df0898c6f3157a08577318595f58af352232fdbe2893be96fa1bb81", - "dest-filename": "@babel-plugin-transform-dotall-regex-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9", - "sha512": "d370efa5b45fbd6217c8ad3fe90891d4a31359e4fa39c43bb5b863ad7c854b4da48ee5ff9aee41be78794834961f1c9ac22b7683969684ac08f3a104ec65274f", - "dest-filename": "@babel-plugin-transform-duplicate-keys-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b", - "sha512": "f1460b4a5c8b8118b142f9581f72767a45c51c314b42eb5dcbb15f140326dc23d9eaaf701c2c27532897a5009ede05559d09477399ecba2115ce2b5e44d4d710", - "dest-filename": "@babel-plugin-transform-exponentiation-operator-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c", - "sha512": "fd0666f56f763eda70eec8c8f4dc7599b72c5b3df7fa5f24b8c2109c3c204011b9b377c07d0be446343b36a5e1b4d70a3a73e47480a6507c826965b4e870acaa", - "dest-filename": "@babel-plugin-transform-for-of-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf", - "sha512": "494fc2ebc615c13471a968f9920b1b28835a9066a0d0a4e0abd7f6899117752b6801b3b32c7101458cc89a603ac85a3c61984955f96f5e620750eec65879b1c4", - "dest-filename": "@babel-plugin-transform-function-name-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1", - "sha512": "ead1fc453a53588d2cdac57abaaddefc2f703e8e0f4eaa99a6ce2e17493343dff13cb150b62a729ef993d60fdd39f109fb4110b0786443fcf244877c2766fccd", - "dest-filename": "@babel-plugin-transform-literals-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384", - "sha512": "981aee44c6e4b4a4306f1689a1fdf62d3f4a2f2d9fde01fedbb6b95d2b97a3a87b477bea96d9743e067cd02f1930ac3df017fc6eab7a044562decbce8763f333", - "dest-filename": "@babel-plugin-transform-member-expression-literals-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186", - "sha512": "29a684b6004bec5298c2327fb5e1fade802613794fdf837792c873f269b854c030ed4dcfc63570c149b110592c6e0b0d51a3b7c0877d4760154184841916b6fa", - "dest-filename": "@babel-plugin-transform-modules-amd-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe", - "sha512": "a1f94a3efb0b4f6fae290a297ac26ddc0a626884b61d6fa1cc715cc1136dc831a2780782fdd207657f1bb894362765f5af118fcb87917148a39b7a9c48f8d870", - "dest-filename": "@babel-plugin-transform-modules-commonjs-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7", - "sha512": "0ee2b913793e4109a73aa051f5492eb01cb2e56656191c5fcd5e76f6cf673eb6b5184ee8966c5fa8ed851e86c439848f2233c14ebe29eba603723427b7c7019b", - "dest-filename": "@babel-plugin-transform-modules-systemjs-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618", - "sha512": "10c87bba896c0bc3b8c61b9d17617ac1e75b4879b51c76740ba689ecaebbcdc0cd89d33355cc56746afe86d5bd9f6d64966f9b3a7f91c78081b009ed65ddeb11", - "dest-filename": "@babel-plugin-transform-modules-umd-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252", - "sha512": "8f7270fa7e4fbe99a1451fa6ae0221d38a6e48034293f4ff500de6dcfd4c8c992194af74ebe0291e10c8a8140374e80bfebd54629cf818d7254d7c7266b6064b", - "dest-filename": "@babel-plugin-transform-named-capturing-groups-regex-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244", - "sha512": "c622c3cd634c7caa063a973ab7753e7ad084db24679f748cd3d057a963c864e0692f682f56b05650a9ec271d0afc00e2e45e580b97fc00f15f5abcf6e537651a", - "dest-filename": "@babel-plugin-transform-new-target-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94", - "sha512": "d782757de890556686bd1c63d968f232e5d2da3b0192007731d48de47b82d86e6746ca5ae512bd08e72cf363f0cb906e19c8dbf9f61a523f7899870e8fbac2bf", - "dest-filename": "@babel-plugin-transform-object-super-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f", - "sha512": "013dccb9f43bcd9121536870380d756b10671315b42ecceee112ffb40954241b8da116a4fb07a1416f21e8a71739c823638d9f1ed0f1b30b8c84c8c512ebff6b", - "dest-filename": "@babel-plugin-transform-parameters-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55", - "sha512": "cf8146afd34c19da0897546a6af0aa186f99b988df67f8640887ae1fa0e8eed5e64a6d25b35d67615489a8511439225b0da6f9c02ea5444ff0e988d572be87ab", - "dest-filename": "@babel-plugin-transform-property-literals-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb", - "sha512": "985ee33a01980a44896a027a5c2ba349083eeb10b533beffd372b6a01995256a0518d52d9d524ee161ca264ddd9cf0bc1c2723e310503f51209bc0d68773dbdd", - "dest-filename": "@babel-plugin-transform-regenerator-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586", - "sha512": "290cf30e767d8564018f08b9969639bfdb219a6e88546d14f69075f33bccbb68b81fdd31a53e209aac0f62c9fcace6e269d61ed8cd209a0b2238817903fdabb6", - "dest-filename": "@babel-plugin-transform-reserved-words-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a", - "sha512": "85a876f85127a11a004dd21bd3920e5dffb81b35d84eaef94d58489f53dec2285ba72acd594b7625bb9d2903844d6c3a4292def80214a49e4c54b61341b79e52", - "dest-filename": "@babel-plugin-transform-shorthand-properties-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44", - "sha512": "fa98c9a6002781be772f489a039814ff530b5c921f5dc61ea4b8170777ac5517f87ea9a3f1fd9cc4cdff14a687b199acd3c84540990571c116b88a66e36f535e", - "dest-filename": "@babel-plugin-transform-spread-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660", - "sha512": "3496b405dffced05793596734ee646e413c98cb61a75e499f5f3baa0e5282f8890c7ef4412ec3f78433dd92aec4f5f587368e0075bb586c8ea0ed1f4d9cdc3af", - "dest-filename": "@babel-plugin-transform-sticky-regex-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab", - "sha512": "5706e40c351e7a79488e67cd7835ff574696ad01f642257226dc32995412cc8b450d3a717f2261dc455a4224b4ac837f0aa6cb1abd157069aec324dd66d748b0", - "dest-filename": "@babel-plugin-transform-template-literals-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e", - "sha512": "a76ace8b108a449ce983d241e208e71b88235a459af3d6686149e5f6c9c9d5c5887131ff86fc59a9f3be5a31ba4fc0d106972d1289798f0d4ee6b03c8240a891", - "dest-filename": "@babel-plugin-transform-typeof-symbol-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3", - "sha512": "4c05792066a1233df267dfc77efdf94d5db1126fa46810da6500a7d92fe11bdfc26740e4b7126ff5e29f3dcef2602bce611e091b1d61f02fa37123af81a688fd", - "dest-filename": "@babel-plugin-transform-unicode-escapes-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2", - "sha512": "a02e6d6182b0e7a1ceef929954b43e47f365dc7ae8f647fc886d215e86873fbb630320a9bea06248d7babc6ad99e2d59e8c820994382e80ed53fb0159b0db6e5", - "dest-filename": "@babel-plugin-transform-unicode-regex-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982", - "sha512": "a9c9961bc47b656e960513d92bfff2f84dc2962d79d41db45b546fee59f6eefb8f69753ff132a6b3a8c576226d17b5034f172b6fb99977cf2d01e2bd2e3753f2", - "dest-filename": "@babel-preset-env-7.16.11.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9", - "sha512": "039eed87a6111bba11ddcabfcadfd8f3832f1a01347891b617524b84abb21be8c5c4482b77f1c03096ad885b663a266eaf3fb40e4aef6e17822da5797f625f8c", - "dest-filename": "@babel-preset-modules-0.1.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa", - "sha512": "f44f45268c2a02ccadc8e63a2c6fb52aeb9e72444bf9a416fa62af5d15e7b851b2440c9ea493e6128f6f80c7d7500e8ef6edc878476ff4c024a6915c690c2881", - "dest-filename": "@babel-runtime-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155", - "sha512": "23c8ffc7c90752b6d84535315ebacc6df09aee3c6413bb59adedfdc77923afd86f23cd9c2b515fa8bca0a2d71637991d3c659c2dd58c1e94816afb1ee6d5b0df", - "dest-filename": "@babel-template-7.16.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f", - "sha512": "cb3b9a617a1124118c94186c309a145bb1b552649bfde5ebfc91d833f32c38981abc989b2f00128a35bba1705dc37350e93d1b5bb4f2e4ffd56ab3acf5c1e6ab", - "dest-filename": "@babel-traverse-7.16.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.35.tgz#cf933a9a9a38484ca724b335b88d83726d5ab960", - "sha512": "cbd5d3d750a8cc70e08d67137719a14a3d77ac9557a5ae595f08e33a24de76368cd1b6b922da9d4b4daddf51213e5ec7b4e5b1b1991808250dad27eb3a2b00eb", - "dest-filename": "@babel-types-7.0.0-beta.35.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1", - "sha512": "b263760d0739b3833b7e7b728c6b7220f6d126feb05b8ad4ffde1f99827b3ca42e6640b4a863075c96e0eac346b75d89995af893961aa6d23f5ed88b2419e622", - "dest-filename": "@babel-types-7.16.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz#3ece22c5838402419a6e0425f85742b961d9b6c6", - "sha512": "d1ca783ec590ffd6afa9354c0ad67e1a2ae2908037ea292f8ed1f0794e3f8fcc8bb6039b234f8950f858152720c25b5ebde181d6bb770a6f1484dd385dac838a", - "dest-filename": "@develar-schema-utils-2.6.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@electron/get/-/get-1.13.1.tgz#42a0aa62fd1189638bd966e23effaebb16108368", - "sha512": "539be45c367d0f05ed90faa5078e6d7d89e760137c3de3e9d73fd70c2ba99d2a5daf14fcfd3842bfd582c0f2dff68aa2486653907e9dc768c350fba85e98e470", - "dest-filename": "@electron-get-1.13.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.5.tgz#b812340e4ef21da2b3ee77b2b4d35c9b86defe37", - "sha512": "cd7f4eebe8ebd8d33201d4a4c04525ca5b62238fc404bbb62ecfd50f7a5441d8b770061e61f7509d3d80249dfc1c4e10c4b71c6d4d772d2a5c730d485a59326a", - "dest-filename": "@electron-universal-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d", - "sha512": "45304658be45590720f68ac3382729e0bbc8b4dcd43dcc8453d6f069e257d2b275210c73b9c0b8f18d3fb102e9fe0eadf7d21080094621a7ac252fa04e7eed55", - "dest-filename": "@malept-cross-spawn-promise-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz#e8a32c30a95d20c2b1bb635cc580981a06389858", - "sha512": "f503ad35f7dc385fdcd6c78c0839e37246f747d587706df8b64cbe147a4d28a096d3073fb1c60bc0cb4efa9b721947cc5b4fdbfe7e2a46200b95a14773d3a3ed", - "dest-filename": "@malept-flatpak-bundler-0.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@nornagon/put/-/put-0.0.8.tgz#9d497ec46c9364acc3f8b59aa3cf8ee4134ae337", - "sha512": "ba0bd7263c05e6576d5296bb0fde64aee349e35c8540310ac85e425b84e02899e1f96ff39a50735d778a4f2a88830305ae478f37626a381a9c174334a0eba7a3", - "dest-filename": "@nornagon-put-0.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.7.1.tgz#e01144a08984a486ecc91d7922cc457e9c9bd6b7", - "sha512": "4793d8c784d3be27dc53bf745e42ba2551b06af29a5f0c9c0d4d0c680c1f73855fec12e6e4a08d242b03c92bb544f01aa7fd35ecc5587f9e29e9d5af2a246f88", - "dest-filename": "@sentry-browser-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/core/-/core-6.7.1.tgz#c3aaa6415d06bec65ac446b13b84f073805633e3", - "sha512": "540bfc391ffb20d9f625f88b72ea29e217c37320bb99f2fd7dd3e775012195a7239b0f2046b8178d1eeaca19c24e0cc52e41c8ed5e5b71d23303cdd344f610a4", - "dest-filename": "@sentry-core-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/electron/-/electron-2.5.4.tgz#337b2f7e228e805a3e4eb3611c7b12c6cf87c618", - "sha512": "b4208af8fe7cd5399d8ec0e91c1433eea61c95dcc675493515de853f13f2d49286cde638b9ffee48b2b347cd0bcece644e911914ec22307480f328f0169e6aa0", - "dest-filename": "@sentry-electron-2.5.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.7.1.tgz#d46d24deec67f0731a808ca16796e6765b371bc1", - "sha512": "7950935afbdca7ac5ad00e4618d1cc4045ac96628f962b04e6b1a6b15fe48ef494bf7cd2ac8d1e2037dbe758a47670a20631e92b634158ff15cbc71938425e82", - "dest-filename": "@sentry-hub-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.7.1.tgz#babf85ee2f167e9dcf150d750d7a0b250c98449c", - "sha512": "1c30cf1274110fa842d2a68776aa8a0d2b5c744d4a864161d110ad24d3020e7d33a5abfc0e3f40b5e17bd31ea42d296588027f245c22e80990acbcfe1713dec7", - "dest-filename": "@sentry-minimal-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/node/-/node-6.7.1.tgz#b09e2eca8e187168feba7bd865a23935bf0f5cc0", - "sha512": "aed668d4ef113afe25670ba58d0cf7885656f3da174a5817086d95aa4c50c91b293d6bbcf5a6d13a9c4b8d8cec5b043c7639eeaf55e316fe7590e2c35134ba43", - "dest-filename": "@sentry-node-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.7.1.tgz#b11f0c17a6c5dc14ef44733e5436afb686683268", - "sha512": "c324b79d6365e66cda0b5a99d80229d618d79df3bd1044633082630a286cd8b581cf5af779fc6b1f1247b3cc1794d5afad3dca2e1abfeefbc5e42754f36b8f79", - "dest-filename": "@sentry-tracing-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/types/-/types-6.7.1.tgz#c8263e1886df5e815570c4668eb40a1cfaa1c88b", - "sha512": "f403bb1caa22a7630130d40911debe00ab638f6faaf597b8a28594744bdd3954ade5dae0ec11a92b6db5fe9f4910ec89019c043c45dd70c77754020c88e6f830", - "dest-filename": "@sentry-types-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.7.1.tgz#909184ad580f0f6375e1e4d4a6ffd33dfe64a4d1", - "sha512": "4eada8b5d6d694702472d0fe1164d82a4131e812f5427dd9fe29a43b4ebf3efce95af561256439a87033cf95e7c30a8d1f2574dca573601eb39ead4179af47b8", - "dest-filename": "@sentry-utils-6.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea", - "sha512": "f4d113f75d0335a20f9e06272cb3de83e3a0ceab22f6e3389926e8539cbaa7c4b90f3313544b0966b6b08be0680cd51505ad83849a9061416f3037e0534eb62d", - "dest-filename": "@sindresorhus-is-0.14.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.4.0.tgz#e277e5bdbdf7cb1e20d320f02f5e2ed113cd3185", - "sha512": "429a4f33ff25dcc6b0be1e2b9fd08d118214f5bc695d409131a5fdc94a6f064d6730abac2caa5f5c60c4284c4a68f84bcdc9f79738a5ee947aae7275d4781e45", - "dest-filename": "@sindresorhus-is-4.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421", - "sha512": "5c80765dbcc74cdea27888df20c57d86555c7cf536eacdaf69f61641c6475971cec62691658103284c1d975dbd672839d3e7e8615da30a0b6ba9203aa8db8d48", - "dest-filename": "@szmarczak-http-timer-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807", - "sha512": "e0101f7f29183a03bee67cc1598c04dd6f74b0180b26850f45659c2fcc25ca233c201f22a49cf750c27d29741dd512905e92a9f13bad9fcd0766d5acbb6bbbeb", - "dest-filename": "@szmarczak-http-timer-4.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276", - "sha512": "3af8c5fb3e752f7a2fd0ec8053476ecec62ebced353c7ef1e2de83271fa0b9a8604e704792125d1bbb2841e4d214b58ddde7e71f289b67867c97612e5b024ddc", - "dest-filename": "@tokenizer-token-0.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0", - "sha512": "00b6289deea99ba426c19a0081ec8d92c71c4fd438016650e8fbdfc11dfb193eabe855943e0baaeac52634648c5765abefad68428071c0619ae83479a350c2f6", - "dest-filename": "@types-body-parser-1.19.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9", - "sha512": "077c55a3e76528cea79ca4dc9a6e59b58fce2fc6ce00e7763a579ef4cd737edeb9a31e743b38c41d6f75b03894f63e9cbd6f048e0d7f4247f8c5dda4ba002950", - "dest-filename": "@types-cacheable-request-6.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1", - "sha512": "71d798cafe0a5a8120a412124f15afa98b15cb8e380cea9e8621777ccde77b5d00989eb6452c8d9149f13095c7416450417d9e47de26e72d486720f006357d15", - "dest-filename": "@types-connect-3.4.35.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82", - "sha512": "f40a27533c938d75e110e6b40e7aa9cd98ba54796a28cb3081af445e3a579e7ab1c0bb5dbcf3ed94ef1ebeb2390fd4ba6ac151090eaffb0a6250a6f0faf2aaca", - "dest-filename": "@types-debug-4.1.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/discord-rpc/-/discord-rpc-4.0.0.tgz#29080812b9092996046af1a21138fb488d180f87", - "sha512": "6b91e228e701901e3783f94de9f058c3c17219ce947bd098b9cc711f15e510b5e96f50b109ad8d036a462b651bf3ca62e2e639f8741e4856d8b47e8326d57743", - "dest-filename": "@types-discord-rpc-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224", - "sha512": "3c1de5772adc9c089c4f7e5358fb3921cc0a0fc4b7df71cc69ad9556fe3ec1dbde6c99235ae5bfc444a807c23045ca20f0761561a99bd60fd1df542fe41c74de", - "dest-filename": "@types-eslint-scope-3.7.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304", - "sha512": "184e38f83344cb1c61d8a73aae8fd59088fef666b4a4ed1bc2ff7eb874b206b8a460e1ebf3361c74fbe704ea756b0f2cf828d1bee4b1ec2c96a91acd150e7d98", - "dest-filename": "@types-eslint-8.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83", - "sha512": "0ba379b36645b6e6518f9e24dbfcf24613438c9c3071588033735b9bcce30696ea01d674d26af4085c6f48a78ef18fded3759514ba5031d1d855f51de9207e1f", - "dest-filename": "@types-estree-0.0.50.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8", - "sha512": "3f5049004016dc4d8325496482ae2d38bdd1c8cba7a165ea6d20b2816a396485938d480dd589da5d65b855697fa1cf2fb3f5e86226c418128fd2e6721780078a", - "dest-filename": "@types-express-serve-static-core-4.17.28.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034", - "sha512": "e9b4994cf6932000b19f8f25e74491f9ac60aea9baa97148c6b74029a1ba3da264dfecee52bdf98419604fbbce98972e9be38468804bb4757faa5a0400521378", - "dest-filename": "@types-express-4.17.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45", - "sha512": "9c49f007efb5bb99550ccd94238735fb947e15868a7da0334b83a87287229a3566de7430dd3bb31f950db2872b71305b8677ab6e5c878f8038f6a5db22265da4", - "dest-filename": "@types-fs-extra-9.0.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb", - "sha512": "654c5bcca97421f2482d34bab7b8a9e5f41033f2774c962e6c39b79cc6e0b9b34d612eb6797794a682d40bcffb7c93621581d3ac63d09fb86ca435332075f750", - "dest-filename": "@types-glob-7.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57", - "sha512": "87895332030972d2726c3a7c090af14d48a262679d8a11d69239c5ffc3f1b1ebb64ba3657dccbc9306e843cc9e8e1e39eab3f6c96a04566d6c4bf155b1f338f3", - "dest-filename": "@types-html-minifier-terser-5.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812", - "sha512": "499b3b7a46cff02374b71546db15511fa1202a6126df504ec40d3bbe415a113cd9cf5c61f9c6edf01708d2c969ca6bf0871e5d9459d01b6ad394f5509fe8913d", - "dest-filename": "@types-http-cache-semantics-4.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d", - "sha512": "a9c517b9e9ad12ef84e7065224737151778266101f5ca438d43f9db97f9560f75eef1c84559722fbfa172892f5ded9d1b3d951da9af87e8779f464fafd7d7fc9", - "dest-filename": "@types-json-schema-7.0.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.3.tgz#1c9aae32872ec1f20dcdaee89a9f3ba88f465e41", - "sha512": "157089832c8dde2bd5811a2697887de06fe9de463ebbf07ce8b6be429b5ca89696b415ad99ce93b6435f4b8d27f5b22fc8bb5e1e1ef35ceb606e86ce44a3db0e", - "dest-filename": "@types-keyv-3.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a", - "sha512": "6004f1571811a8d1fa9c7108b2f83a93606873524723d65b1f9896145bff31391c873ddbd627860dae53d1af51ce735d2342a155b75b59237e2965ab4194714f", - "dest-filename": "@types-mime-1.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40", - "sha512": "2a5cfde3d874d86cf6b9908c1b00d44834b56019537430e06d61e2fbcd65dbdb5000b52dbf3e2b0188b9ba85611392da828aba0dea805256eb1ef5bf9970e075", - "dest-filename": "@types-minimatch-3.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197", - "sha512": "8a25202b357d02e684919aa438b0c8be54222fa96db9977db46716de0c299d7f096ee8ae8459441a69855c45e4379d02beaeceb3cf08636bf47640ea5d859580", - "dest-filename": "@types-ms-0.7.31.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/node/-/node-14.18.9.tgz#0e5944eefe2b287391279a19b407aa98bd14436d", - "sha512": "8f5d574ae46e0257edeaf2c3117e11be1a82d0ac4dc71e9023231735bd2f1c748d3d74cf7a2cb76a580449698e388cc4b6210bd2a8a8c0f5377b05bd84755aed", - "dest-filename": "@types-node-14.18.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/node/-/node-17.0.13.tgz#5ed7ed7c662948335fcad6c412bb42d99ea754e3", - "sha512": "63ce8c0310127b6e613739436ecbe25e5f234076f4443bcab78738d19250d43a27d0000bd124cb652b3837eea02c43b9e6979dcbbaf670bc12f990f13e6ff607", - "dest-filename": "@types-node-17.0.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01", - "sha512": "50baaf64d18cbf4cd116faa7f3fe0b48fb6798de0c7e194f36d2424e92ae208c46546676ad85b3157aef101a21f42572a9213b0fa605449d61c9d2c723a91b5b", - "dest-filename": "@types-plist-3.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb", - "sha512": "1466b517ad854f4f6a72bb9e040eaa613ac93d50f36a1f5afb8f77fa8d8f097b1eb161c89f6ec6f7c4ec48cb3758f35b648123e3e5497fab1a485a6f0fedd9b3", - "dest-filename": "@types-qs-6.9.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc", - "sha512": "10486c2ec0fa52c0ccd7216102fcb40a3afa5709a9316a850426fdc34ef056e805ef0f677da8f12ee5669e04c8a604bab2f0a79ba55ac3e3198680c22a739fb3", - "dest-filename": "@types-range-parser-1.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29", - "sha512": "f396360638ae7c5cda30896f243bd34c1f05c65db17cba381e0987cd5073d3cc38c0378f0938d8c3ae8f76ba253b4933962df26a6fd80a046e7f2a350dd4154c", - "dest-filename": "@types-responselike-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc", - "sha512": "2ff4cca725117c191ffa8ff9dba65bea477fb5c8543f78810c43e3aa36fe536300261551c71ae6af67f0a5ed3c13b42c57b60b729ab4b54690f4ef71f7b648c5", - "dest-filename": "@types-semver-7.3.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9", - "sha512": "9c2907188e30ed980074d92b12ed1bbfee31355fd70ea5be0f27649de6cc390c24a431b1f06f874e58fb47b00123c8bc9cac55c34c2d28f8b50fe94f3a487861", - "dest-filename": "@types-serve-static-1.13.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9", - "sha512": "2b92beca697c2d3a3d6d6248feb1027c83eb1a0c5da5e35b8fe779de5c0de108d6d4c0b09648549acfa0b5dce2813794c81af4f7ebbc070388637317bc775cb0", - "dest-filename": "@types-source-list-map-0.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310", - "sha512": "8a98b1b95ae1d8e74d99abafb53e75a3777ccf5da9e8bb455bd8a7ed4efd75eaff9307a38dd35c8500b950c9f9bbf2b136833b5471ceb3f97c292f2e1f184e0d", - "dest-filename": "@types-tapable-1.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.1.tgz#5e889e9e81e94245c75b6450600e1c5ea2878aea", - "sha512": "3b732644093a66e00a6bd087820d0faf4fa550eaa830ba5cf404b847c6a7a366aebec83b204f2cc85dd787f34faf6e935a497161caa810415dccb2ecd5f57d3d", - "dest-filename": "@types-uglify-js-3.13.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.5.tgz#2a1413aded46e67a1fe2386800e291123ed75eb1", - "sha512": "f548cc0872b918f81046835ba9d2c802f032d04227ba2a9b5b43c132d54fe81e41d8740996fa091ccf8aa1d3d93048ce6b956449cfb92c7ef1cbe714cd07661f", - "dest-filename": "@types-verror-1.10.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.3.tgz#b776327a73e561b71e7881d0cd6d34a1424db86a", - "sha512": "f60b4e3cf91fc8da04a82420c78a892a4b8d9bfc7447684a47b7dd97bcef4c9c879c88acb84fcb7ef5ceb1858bd28deaababa206729934d3738b7974cbf5fec7", - "dest-filename": "@types-webpack-env-1.16.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.0.tgz#16d759ba096c289034b26553d2df1bf45248d38b", - "sha512": "16ded81f794455143a96cf24e057f5a01e2337aa32fd7994ead40848a7617e1fb5991faf899169852e962f422bb433b3bde7e6260e5ad2ced9428457c2a4c416", - "dest-filename": "@types-webpack-sources-3.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.32.tgz#a7bab03b72904070162b2f169415492209e94212", - "sha512": "71bfb48a88a5ffba33e7fffbb59512c1bad200dfcd587ad0ca5cf9716f06d1d593705fe0fbf75274c94a559b29058b8c00dd7e5a7c07ae4c6246b2dcc1dd077a", - "dest-filename": "@types-webpack-4.41.32.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21", - "sha512": "34e9f978872058b3a8eaa5bc01cb8b67b1bc3f2717bb4c53c71912e90d7c55617180f5123b0574a418f66bfe2f88d655bb6e62ed1201ec6b6d7640085145ce3a", - "dest-filename": "@types-ws-8.2.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129", - "sha512": "eed1489a080d78d05532c9f4bcbae99f51f5b8fad405d9c044f4e96688ad637ed9add2511337fb235ead32b94ade17a7df8f60af535887c0a66506bb0931ba03", - "dest-filename": "@types-yargs-parser-20.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.8.tgz#d23a3476fd3da8a0ea44b5494ca7fa677b9dad4c", - "sha512": "c03794c225267a6f45ceccb2b04c11ba468474335cc1b44ebd0f5019129a2c8eadf8896d3736e7e3f8b86ac981d746aebd91900b3490eadd0649ccc44e19545f", - "dest-filename": "@types-yargs-17.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a", - "sha512": "f2e00b6392d3bd2b87825a03554bd63f7a486ae20b9bef3fd290cca24b83608a0db0e912c1de408870534842632930dc66be73f14a60396664c411788897eda0", - "dest-filename": "@types-yauzl-2.9.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7", - "sha512": "ba4061d78a852e3c5340d4d7a1c77292c37941d336f12d42c47b76addb241722fec4557b56b7a6b812d56e609e3e3f9445a957044371ffd2e6ee59e18a1b424b", - "dest-filename": "@webassemblyjs-ast-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f", - "sha512": "88645fc9ce41abe36736e5fc6f987006b463cdfd2872b24f23a1961687411739859f2beb43cdd21ca8668a5094ffc26febb8b818964132113396dc7370d6a0b5", - "dest-filename": "@webassemblyjs-floating-point-hex-parser-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16", - "sha512": "465852f020425df45447f730a36868f5b9217925c6d3e370a285dc7373c020b00b7f640b745ca3eca1ac2916d573de61667867111a27e245bf0f7499a69e9372", - "dest-filename": "@webassemblyjs-helper-api-error-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5", - "sha512": "8308a417ae5a0cd79e5daf09c576b604093e4448d2ca1acd0bd670753d1ff2373875041e0d0ec6e26d1fd9008b3c988c4d33bac1f0e64668ffa56d0fb14bc870", - "dest-filename": "@webassemblyjs-helper-buffer-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae", - "sha512": "bc391bc6207ccdf9cf74d2bd45a8dc7b2e42d30f9026e804825374a1ffa498ef25ee50dbefb02794a61017b69aad9b82aeffa5d14bea2feebc8120ebde4f4b3d", - "dest-filename": "@webassemblyjs-helper-numbers-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1", - "sha512": "3efa68386889c17793ad27ffa9fb9d261c25bc34311607a56ccaadab9d965a25c2e97820d484447678263cdddbb384683bcdcf9cbfe716bc6e7178f5f815fad9", - "dest-filename": "@webassemblyjs-helper-wasm-bytecode-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a", - "sha512": "d743fd368dbdad85f58fb1771153d7dc9bc63d03da7be0289ae4933e217d78141e0a11c8ea2aa3308c11f4998e257c299e7fe85460e4ec8e4896c92e33053fa6", - "dest-filename": "@webassemblyjs-helper-wasm-section-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614", - "sha512": "849f3b4083ed00c29b16ae821939196098af1306436d052061ddea29269d4cd3a1558ee9fa07cfe92af494b4554da1b5263163fabdd8721a2a458c4d1f733419", - "dest-filename": "@webassemblyjs-ieee754-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5", - "sha512": "049d8fd21359d2ef938756195c9a735ba9a2c2a41419c2074f51bfb1fef680b543f4367901d613a8f35b1d987a2b53395662af157c064966400f3faa056c5e47", - "dest-filename": "@webassemblyjs-leb128-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff", - "sha512": "f64a9cc4011d3218b04241e990d8a8ad9ceaa46ae8750436206ac71f10b2f8ece7834a1fc8c034953aa22e456cd6ecd345e8d7fbf3b410e4fb2b1a953ee5e8b1", - "dest-filename": "@webassemblyjs-utf8-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6", - "sha512": "83e46cba9502d5a4c77d1f020e09ec551559149a9d9051e9b0731f26e590cd6537b6f9cb0b4ed4a872027cffb85f22f6b67af56a6be5d52769d3a4e760299590", - "dest-filename": "@webassemblyjs-wasm-edit-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76", - "sha512": "17b42a297c30365326b2e963ebe3bbaf89a6b4094259f3bfd077603b14a49597d0703bb44e92e20f5991b7fcc5db9064e7d1488c4b86008ca7e5e8b8c8c7cb84", - "dest-filename": "@webassemblyjs-wasm-gen-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2", - "sha512": "56a9e436a9d9954e4407ae29a7597b85d9b7866430ed582a6b4285fca08d3bdb08a48e8593a6eb0c4897fa208e62bbccb81583c2cd0d9133b16046fce574071f", - "dest-filename": "@webassemblyjs-wasm-opt-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199", - "sha512": "aeb06e8f0f9d26edf681807bfcbba9e9485d90fc7d4bd4a7a1b6734552fb55c047f41b7d6c204b12e5ff61738eb41b0e678350ad1ca42a17df4561ef8a042f38", - "dest-filename": "@webassemblyjs-wasm-parser-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0", - "sha512": "2106e851633878acd65be37f8e28f6b116ad28c87df5011e968dc46f6ab4a9792f3d1212023f10c6d9b0e62b70a8af934e406e508138e40c583d3a2a3ed2f982", - "dest-filename": "@webassemblyjs-wast-printer-1.11.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790", - "sha512": "0d7f272a0a9c1b0b1cd1e252a98b799703f80c7e459479e6b96581472ed7d0d71a191d19b6ec9e11280cc1361512dc66b0d198faa8ade10613fcc2184ce4cf78", - "dest-filename": "@xtuc-ieee754-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d", - "sha512": "36e1ea058d4f07f0fcc54eacfed84180e02200fec73980d0df6f8115920b27c8af9149001d09d67e7e9684befd3b08f5aa6527a0dfd83e192d748a2e722a6401", - "dest-filename": "@xtuc-long-4.2.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/abstract-socket/-/abstract-socket-2.1.1.tgz#243a7e6e6ff65bb9eab16a22fa90699b91e528f7", - "sha512": "619262cecbd2d5a06e6b919dd35c287b8ceec9804681231ea83381ebf0a1c1d4c8f74e0a3fa406b49b305e5e2172a5b16f3f3a85005efbe1d6574845d5a194b4", - "dest-filename": "abstract-socket-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd", - "sha512": "225f3442cd968d89492013733642ba298aa554c4db64b5e01f1da84f4a54fdf8d11f2129f8f11f10f634477582c001953ad6aec61d613b136021fe5bbfb750a4", - "dest-filename": "accepts-1.3.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9", - "sha512": "9bb559de3c33e1e2ba03856db7c130d7f98d6cfdb8bb41617727c0edf4af9c947a2cc75f3989e6b88aeb24082b61f609d7417fa2d6874edaedaed98774c37313", - "dest-filename": "acorn-import-assertions-1.8.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf", - "sha512": "57f2c6af500fcbe3d723029e6c45ab9193f0a1ea05fb0d6388e0549aec6e89421a387b686fc41cf414eb628ed5b88e5f47cb6ab32f9bb80d96168a11e6896abd", - "dest-filename": "acorn-8.7.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77", - "sha512": "45937035c945efe312ffc6c383bd1a9a0df6772799199c620ee42667128b025423af78c6c8bc7ee0a924e7c50eec3d90760148402a2fb92b991129dee911ba5d", - "dest-filename": "agent-base-6.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a", - "sha512": "e08ed3774d6ab96fd1a6871f35ac85745564d6a4aea21d04ec9adb449d7a9c7d351e128543cf0836af5277e9ddef6cea4724a5afd0660c0f3194427abc932b60", - "dest-filename": "aggregate-error-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d", - "sha512": "0c245f3bfe2743ef3da7f44ae378bc133778d44a9d18853895dee7185f0e435e2873fc1ee6b127b4b0946bbfa3ae7de79fcdc1a2c7f0640d306f8a689f6a3c89", - "dest-filename": "ajv-errors-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520", - "sha512": "5b1d0ac79da1c44ec2d7c8643048206251227ea599b58691828b89a2bf9631d3e743210ad77be0116c9536ea7b4a879ea0b32caf891fe61e9d396d75235e4c50", - "dest-filename": "ajv-formats-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d", - "sha512": "e69e964cdd03753195424e958dc123bb5f4881a1ee75a95c7da6c3ef284319e03a6dc42798bf82a6f78b26aff786f7f07756a87fa2f7f3a3ae824c7a45fc8c21", - "dest-filename": "ajv-keywords-3.5.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4", - "sha512": "8f77d52e0bd3a39dbb6a7c98c893864d825b1bebe79d062f1349b99a691cd532be9f1029a6408b3082f4699e1d6e55423681928619be933138654ca4068320e2", - "dest-filename": "ajv-6.12.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18", - "sha512": "a8e289c8d8ff87e396c7bb390de3cbe99bb529e33d8cf661c01aacfbb0f33fa6c63afab354249fd31b9e62656e682fe843f56d4b6ccb30b1dd4056e491af970d", - "dest-filename": "ajv-8.9.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59", - "sha512": "20e7f0c0117989ccce8e9fd6798e18c728ea005310a19b9f750583775f52104c5b54b357aafa73489fcced96b8fec08f990d3e191aaea00edb19c20d7317b0eb", - "dest-filename": "ansi-align-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf", - "sha512": "84751719a81e7e3376891ac80fadf172422fa2d3973a88e140a5883d467898d519f672d95beec530da04d653a412135662cc7fef2b0622e2580a230003d167ac", - "dest-filename": "ansi-colors-3.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41", - "sha512": "d403c7032af7f8f09a9b0370ddb5c23e9e0714b38d66dff2207d2c669d3fe3af4a58d4c4cbea8de634371955fa0cc675517022df8c95c2d4de686fc7a41baecf", - "dest-filename": "ansi-html-community-0.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df", - "sha1": "c3b33ab5ee360d86e0e628f0468ae7ef27d654df", - "dest-filename": "ansi-regex-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997", - "sha512": "d5aa5e3df5ccd54392ab0d28f48885028bd5cfd3394b50e0fb84eb0f07cc7b043aa7fae632e79beed5998d0d6bc782e8cb502b060828a86a5faaa748e2ba2776", - "dest-filename": "ansi-regex-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304", - "sha512": "aae2505e54d25062f62c7f52517a3c570b18e2ca1a9e1828e8b3529bce04d4b05c13cb373b4c29762473c91f73fd9649325316bf7eea38e6fda5d26531410a15", - "dest-filename": "ansi-regex-5.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d", - "sha512": "553d1923a91945d4e1f18c89c3748c6d89bfbbe36a7ec03112958ed0f7fdb2af3f7bde16c713a93cac7d151d459720ad3950cd390fbc9ed96a17189173eaf9a8", - "dest-filename": "ansi-styles-3.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937", - "sha512": "cdb07dac22404f5adb8e25436f686a2851cd60bc60b64f0d511c59dc86700f717a36dc5b5d94029e74a2d4b931f880e885d3e5169db6db05402c885e64941212", - "dest-filename": "ansi-styles-4.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb", - "sha512": "e6d78eb105800571c70453fdcb7b244b93f777f59f597a6fdc5529cbe2e8accacd61a4fda48e282cc417ee3cd0d8a9253691a9587cdd0974c34f66375c695907", - "dest-filename": "anymatch-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716", - "sha512": "3f8dde3df38022ea6482e1d4c9cadce2a27d933f198ae3948a36844f05fb4c7b7463f18d2bbbf469af2b63cd7ac568d9eeb25d0395dd31ca5515328cabe46f5a", - "dest-filename": "anymatch-3.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.7.1.tgz#cb0825c5e12efc85b196ac3ed9c89f076c61040e", - "sha512": "aa5f77bc452ae96b2cb465c3f9204b488430e9236785b0c4334b30ce0ba0cad3312e9deb4f6e0083f8dc0bcd191f188f45375ec359e2b91ecfdff142ac3a888f", - "dest-filename": "app-builder-bin-3.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.14.5.tgz#a61a50b132b858e98fdc70b6b88994ae99b4f96d", - "sha512": "93757028fe24a6c9d4697a14926d6ce336921cf1c83059cde243cc53dc9768a984d4b7c71ea05a11a8796d7793017e55fc10b8d7015d83c085e6f3a3be0cbc46", - "dest-filename": "app-builder-lib-22.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a", - "sha512": "63d27a6635eda1887c4675d508c394fedb439a4d5a063ba7abdbced2d6b9c7ce560d08907d417db083c121375b8a2215701a34dc78b78ccc62801b6c75d95747", - "dest-filename": "aproba-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911", - "sha512": "a39468cbab4d1b848bfc53a408037a4738e26a4652db944b605adc32db49a9b75df015ab9c0f9f1b3e7b88de4f6f4ea9bc11af979810d01e3c74996c957be84e", - "dest-filename": "argparse-1.0.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38", - "sha512": "f3ef56a9e6db173a57f4e47e59ae8edbd6ac22881e44ccdc1ad00835da4c1c7c80835d1fd3969215505b704a867ff3d7c35123019faadbf6c4060dc3beeacadd", - "dest-filename": "argparse-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520", - "sha1": "d6461074febfec71e7e15235761a329a5dc7c520", - "dest-filename": "arr-diff-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1", - "sha512": "2f784a57947fa79a3cd51eced362069f0a439a4a7a13df365e1b5bbb049edcee2a3ad30c32da1d89c0120350a7cb653e6825dc3699a5fa6e1d3ecbec2778dab6", - "dest-filename": "arr-flatten-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4", - "sha1": "e39b09aea9def866a8f206e288af63919bae39c4", - "dest-filename": "arr-union-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2", - "sha1": "9a5f699051b1e7073328f2a008968b64ea2955d2", - "dest-filename": "array-flatten-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099", - "sha512": "84d7f370e57c5b835db9a96da8114fc953bee780d226e64663da93e2946ba01e92f5ede28a2768d884880b987d476b0f27c1f71470888849ecbf594f5cedcab5", - "dest-filename": "array-flatten-2.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39", - "sha1": "9a34410e4f4e3da23dea375be5be70f24778ec39", - "dest-filename": "array-union-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6", - "sha1": "af6ac877a25cc7f74e058894753858dfdb24fdb6", - "dest-filename": "array-uniq-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428", - "sha1": "a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428", - "dest-filename": "array-unique-0.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/asar/-/asar-3.1.0.tgz#70b0509449fe3daccc63beb4d3c7d2e24d3c6473", - "sha512": "bf2c4fc4fe5aadc02a37817f79b1ddfc78709c0899b7086096f76673b051d9fd32c1b54d4cea527b284b0db197b44ff2e7c86fd680bbe5368d217bad9ec399b1", - "dest-filename": "asar-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525", - "sha1": "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525", - "dest-filename": "assert-plus-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367", - "sha1": "59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367", - "dest-filename": "assign-symbols-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31", - "sha512": "67bb4cc35cad4d7b798ea31c38ff8e42d794d55b8d2bd634daeb89b4a4354afebd8d740a2a0e5c89b2f0189a30f32cd93fe780735f0498b18f6a5d1ba77eabbd", - "dest-filename": "astral-regex-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf", - "sha512": "cff5a143914fc922ddbd1101c88daf6624d6c029c5d26a0c27584af584300d31ca87a23bfee49c90c7ada1119be540593c2d73d23970fa7fd70a08de1fbcb501", - "dest-filename": "async-each-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3", - "sha512": "356d9c5fc9b543b28f03b6b933650b41e676c11e6a2393c06f0e4bd1438cc5d8a8564f4f319d21d539b264490f62b0af6230e51480aeb0ebb576510a00079707", - "dest-filename": "async-exit-hook-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd", - "sha512": "72c3a558601c44525a23a9be17658a76730aaf81e1761155064d07fd06c914c0abfae3b6930a21c1740fc70ffd382c69d39af9821541152ca2a22c71de07e435", - "dest-filename": "async-limiter-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d", - "sha1": "aea74d5e61c1f899613bf64bda66d4c78f2fd17d", - "dest-filename": "async-0.9.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff", - "sha512": "cdf96f96cd750c2cbe7505b34d6d9dcee8a5bfc6795ffa637e664e59b6ba4cd2150e6fb650368999748e5e56ac1ca7cd06cf28a37334693e747c31167ca6635e", - "dest-filename": "async-2.6.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79", - "sha1": "c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79", - "dest-filename": "asynckit-0.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2", - "sha512": "faafedec492fd440d8da5e8675ae8b2e25f5e2b53d4d5db459ade87de426c0f1596ce328f435eb2db3a315a69c9645ca5a27486a8a7000e6d00eac16b46523aa", - "dest-filename": "at-least-node-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9", - "sha512": "5a6eae92868e1898bfef7a7f725d86bcb8d323924cd64fced788ac0fbdd830bf12b6b1ffeff9511609a0f272026600f76d966f8f0086c6d30e0f7c16340bbc72", - "dest-filename": "atob-2.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/atomically/-/atomically-1.7.0.tgz#c07a0458432ea6dbc9a3506fffa424b48bccaafe", - "sha512": "5dccfd974cfbcbdc90f6b7436b1966688e2e2477ff4fc83d84e13325cb04a97d928c28f8276d2e2bbfa57640c731ba490caefac05ef110883173fbd296c7f0e7", - "dest-filename": "atomically-1.7.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450", - "sha1": "d08885be6b9bbf9439fe087c76287245f0a81450", - "dest-filename": "author-regex-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d", - "sha512": "9f865eb5af0d0b7400b2eca28b3bb41a4991710e9c96457d58552751fd625cffff21e48a6d68e87d6dd41f2655c25381e32d37f5840a79f6b0c939fae19c1bbb", - "dest-filename": "babel-loader-8.2.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/babel-plugin-component/-/babel-plugin-component-1.1.1.tgz#9b023a23ff5c9aae0fd56c5a18b9cab8c4d45eea", - "sha512": "594c3cf3b9097f6187f34360fd931cb4a679d7589a98736a3e177db8aa35e32ce2b2f57b5add4472422b6fca2afee0b3dc1dcfa405bb5df97b0244cb0d84fa6a", - "dest-filename": "babel-plugin-component-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3", - "sha512": "8d9548facf5983722a03f91d8b48ba5030b26d423769204b9e096161b4928ca955ef217517fe4b5aff0c6a4426bd8a676c90d2e9f7012f62b31d2c4d08cb5649", - "dest-filename": "babel-plugin-dynamic-import-node-2.3.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5", - "sha512": "bfbfd3e8441c35f54b7dc3765fc2ee95bec38e9ae27b22d624aff33961f90d461c0207b1f6c3f7876e50f832ec5fd4e5a177b7cb53bc976ab626ff6af14541f7", - "dest-filename": "babel-plugin-polyfill-corejs2-0.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz#d66183bf10976ea677f4149a7fcc4d8df43d4060", - "sha512": "4e286a11ee2c41c6ff41c3c9bf17bde3ff5166e2d0b85d7e4e8e16a90711bdcfb727780b08f20f8032b318b1bace640b7c7de79f6e61791b833644b6291e08f0", - "dest-filename": "babel-plugin-polyfill-corejs3-0.5.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990", - "sha512": "636074eadbe01d8b75c74cb3d7b8c690679e32be4578a52ef80489f8dea7079950f036a97e0e368b4395adff0f346277cca2f8036dec9cc8b5211c2baaa343ec", - "dest-filename": "babel-plugin-polyfill-regenerator-0.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee", - "sha512": "de849e50ed13315ebb84dd4099b5ec2b8c9aa94eed8e21e56f144364ea47d0a5bdf82797e1b440697d009f1b74b71d8cae94695b041a3f02252121098585393f", - "dest-filename": "balanced-match-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f", - "sha512": "e53e8fe313e0a69d180c5bd25b0119e0da04dda3384014170f39956eb6829058fccc733e99b6bc4b2a81e436d95b247b9981e8e98ec1750a373280389b44de42", - "dest-filename": "base-0.11.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a", - "sha512": "00aa5a6251e7f2de1255b3870b2f9be7e28a82f478bebb03f2f6efadb890269b3b7ca0d3923903af2ea38b4ad42630b49336cd78f2f0cf1abc8b2a68e35a9e58", - "dest-filename": "base64-js-1.5.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16", - "sha1": "dc34314f4e679318093fc760272525f94bf25c16", - "dest-filename": "batch-0.6.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328", - "sha512": "bf22f63b2989c666ab3bc83132bd2684286c3bd406c21ca77eebb8f8c1d3016e9ccdfabd86e98207bacaa548c377d6148833d4e26ce9caea454af382940c1b99", - "dest-filename": "big.js-5.2.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65", - "sha512": "527ecc2040dd502e603697060d5f7ba29d58c24ef8f0ca477054c7a18b3aaa78f56778fb239dd51b79f06612b3a016666dd44d9dbe9645d165c25eed483b991b", - "dest-filename": "binary-extensions-1.13.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df", - "sha512": "a76abfb7f9a1bee3a3fd478b955eb9eba183fe0ba8c25af4847c42948d16f66ecc59890bd45d212e8fb401ec6cf4748f0ad4754974344c3dcc30aad765a8db89", - "dest-filename": "bindings-1.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.9.tgz#a64a0e4365658b9ab5fe875eb9dfb694189bb41c", - "sha512": "ec1d51b71f368639d20f83c62c08d559e607ded1c07155260a187ce5ade596d2909ba16b7ac5e1f44ad0a3aa00bfa0aac6db5ccc2dff90483c498e4d96e3ee53", - "dest-filename": "bluebird-lst-1.0.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f", - "sha512": "5e9363e860d0cdd7d6fabd969e7ef189201ded33378f39311970464ed58ab925efd71515f9acf1026f2375664dd3a413424fb63765c1f6344392f6e6426711b6", - "dest-filename": "bluebird-3.7.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4", - "sha512": "f258df422e5e064f0425f10232b82a34658f118e6358ffb5233933906745144c05419672699db552a75a1e4b6088c947d312c7a8816d13fbb639813974eb5588", - "dest-filename": "body-parser-1.19.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5", - "sha1": "8e890a183d8ee9a2393b3844c691a42bcf7bc9f5", - "dest-filename": "bonjour-3.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e", - "sha1": "68dff5fbe60c51eb37725ea9e3ed310dcc1e776e", - "dest-filename": "boolbase-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/boolean/-/boolean-3.1.4.tgz#f51a2fb5838a99e06f9b6ec1edb674de67026435", - "sha512": "de1c74930537bb31ba45e437a6768540f4a4b69070e911cddff8af0ca12e53c8355d27da7e8c32bc39da763bf5c69f0866a86d4ae931970bfd6c5e85857f26d3", - "dest-filename": "boolean-3.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50", - "sha512": "f6062040a5f1fb59cff263fb0b3172694011860ec3de7d5d17f16712b5a6bbd97a26f1a9354376efc8746926fe423a22292586fa2677b87adcaa4d2aad8f5141", - "dest-filename": "boxen-5.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd", - "sha512": "882b8f1c3160ac75fb1f6bc423fe71a73d3bcd21c1d344e9ba0aa1998b5598c3bae75f260ae44ca0e60595d101974835f3bb9fa3375a1e058a71815beb5a8688", - "dest-filename": "brace-expansion-1.1.11.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729", - "sha512": "68d75b9e3f4ff0f8dd5d4e326da58b2b6205de373f1280d86c2ec06b35bab68dd346c7d7c6c702f545ce07988388442b93221b5a9d922d075ae3e4006bb9dcdf", - "dest-filename": "braces-2.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3", - "sha512": "bb6b5b6c6e4f74a45352872d3b73410fc150e4774f8756573c7ce9d6bc1a6b98d373e455f7ff9195688020a9a344f405fb16c633d2a4963e5b65015adacff7f0", - "dest-filename": "browserslist-4.19.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0", - "sha512": "4c433688c20441d276ca33c9a1222c95d9e5795680935a16dc305553293238bb04b0598473d927f921453f3fa0979e0a40dc650e7030097a2c392f4e931db102", - "dest-filename": "buffer-alloc-unsafe-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec", - "sha512": "085b074208ed5b550285d5e06f2246b679be3bfb8b41e65db5b0e8f267d48185c21d2335c20ad5c579ba6d2cab52e12b11bfb8b185460b3012051a2def3caba3", - "dest-filename": "buffer-alloc-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242", - "sha1": "0d333e3f00eac50aa1454abd30ef8c2a5d9a7242", - "dest-filename": "buffer-crc32-0.2.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe", - "sha1": "59616b498304d556abd466966b22eeda3eca5fbe", - "dest-filename": "buffer-equal-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c", - "sha1": "f8f78b76789888ef39f205cd637f68e702122b2c", - "dest-filename": "buffer-fill-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5", - "sha512": "13e5d0091c126da6a20a1b6fea4e83c2073e6f1f81b3abee2891c7979928c7f05a29b8625f3a903b02b870edb6c84946a763829a3c15853dc79b18323c69c97d", - "dest-filename": "buffer-from-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c", - "sha512": "e3face120f3a8e2bed3d378e5144fad6324ed586b54eb47f3a4a824990f2abce16261dcbbae8a984160937e7e6e71b9f224e17005704c2d7bff16cc2f087ffd6", - "dest-filename": "buffer-indexof-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0", - "sha512": "10773220f050e0148696f8c1d7a9392a0009dbb088b0763fd8906609145ea38f32f6b43731a533597dca56505ae14eccc97d361dd563d0aec2dd6681de3bbb15", - "dest-filename": "buffer-5.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.9.1.tgz#25f066b3fbc20b3e6236a9b956b1ebb0e33ff66a", - "sha512": "73c6bc277c0ae812152d6ee5b3eed344af6282ca536f35a652ac456e02b49b8d06826e9e7d46f1b565421888dcf9db5c872af9a8030050bea210645d4bfeafc2", - "dest-filename": "builder-util-runtime-8.9.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/builder-util/-/builder-util-22.14.5.tgz#42a18608d2a566c0846e91266464776c8bfb0cc9", - "sha512": "cea2070c5270980ee357b482f5a23edf7316c13da65a88a31fe3a5f489ed340c2eb915e84beed7789c2784b0573a17030735d3e240f31e7464e0929e6b280460", - "dest-filename": "builder-util-22.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048", - "sha1": "d32815404d689699f85a4ea4fa8755dd13a96048", - "dest-filename": "bytes-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a", - "sha512": "7567b89d63bfaee10e63b1e4509e6016dd4308557dccf46826bf29574fc04907ab98e663b6af233233a9ac2d0a775d062cdfa5ef16943efc732455adc46bbc16", - "dest-filename": "bytes-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c", - "sha512": "e59bc0c5dd391c30d4fb2f4156f72a62ed8b2d798f9d0d215bada1df6838c414e02ff329a51e3fd383477e3ff270cdb2ea59939dbc3a1d58bed5e3743ec6daeb", - "dest-filename": "cacache-13.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2", - "sha512": "00a71d4e71525804dde7f1823d1c6bd82870209f3909ecab1328d11e52b1439e9de1724c1b29b4b8088a9f4c5b2ce18e977fb24693938b8f38755084739014cd", - "dest-filename": "cache-base-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005", - "sha512": "dbf90db1c3e1a5cc6b3a280c6736e2585eddcfc8a585bfe72075371326625d65e97aafdabbca89f1585d7ed324b72de7ec68fa1c819a9501bca2204d07700980", - "dest-filename": "cacheable-lookup-5.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912", - "sha512": "3a3ddc0063c2a8e657ed1cfae149f2d8660064d962412a9f6de3eb800435c0a022858982527ada06d26d29c191e31cfbc05f8ba090beb2c159befe41805f4882", - "dest-filename": "cacheable-request-6.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27", - "sha512": "a68b96f3f16688f41bb86a645d0f4100fbff328e710c600d812357cd3cc9f03aca1ae5ceb2c338c084118df6a735187762ee5c7d83ef728aea6e183628826d7b", - "dest-filename": "cacheable-request-7.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c", - "sha512": "ecef856c28a1ac1e5619b1587ac72dc264ca69eeab3a22339b3d6272b79627ed1a03b2c97eeaa112ca364fd9dca5c16dccc42dcd77f64061ae7962464d8b2aac", - "dest-filename": "call-bind-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a", - "sha512": "83119606b4d3d49b8cc7a47ea393d35cc9949e19d5ccb43d48dbad0f862a2ad23a6a9f3deedded28409895aea0096124a655e794dc9b124660f46106c4a14283", - "dest-filename": "camel-case-4.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320", - "sha512": "2f6f124c1d7bd27c164badd48ed944384ddd95d400a5a257664388d6e3057f37f7ad1b8f7a01da1deb3279ef98c50f96e92bd10d057a52b74e751891d79df026", - "dest-filename": "camelcase-5.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a", - "sha512": "1a6cba161625098eee3849595126f1a365020c7f28c0493df7a8246eba6c806b6b24b33727b8c6c65f4873b430c23e22bce13901665644c79c0dd17b86a1a314", - "dest-filename": "camelcase-6.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001303.tgz#9b168e4f43ccfc372b86f4bc5a551d9b909c95c9", - "sha512": "fcca9cd681129dd50db3324fd24c7451a414f6412ff6736d27b2a7f00740d263671fc791d5c8f4906f8d6cdb82d56abf6f6d5e03ca6b84a440ddb6e48ce35e81", - "dest-filename": "caniuse-lite-1.0.30001303.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424", - "sha512": "32d8be7fd96924d730178b5657cfcead34ed1758198be7fc16a97201da2eada95c156150585dbe3600874a18e409bf881412eaf5bb99c04d71724414e29792b9", - "dest-filename": "chalk-2.4.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01", - "sha512": "a0a9db845c91217a54b9ecfc881326c846b89db8f820e432ba173fc32f6463bfd654f73020ef5503aebc3eef1190eefed06efa48b44e7b2c3d0a9434eb58b898", - "dest-filename": "chalk-4.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917", - "sha512": "6666546b37cecdfd0dbdeeddba208a0f6dcf1520ace093e863271c8d4145dda42441a76a0617f3863930047da634e1bd71307085a98cdfb108b08919c379d182", - "dest-filename": "chokidar-2.1.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b", - "sha512": "8c9d1bab36b296626d567360cd37923acf033dabe96d8804aff6f460bf3fd863b7c4912122716684a3149c42508d9ba62bb297185854cbcf4faec25695a90156", - "dest-filename": "chownr-1.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac", - "sha512": "a772942f2420e12ecd2078b17706c65fe9c51e4a01880e18426c96b636fc5e7812295d76e27266472b2001eba36d455bd79be1f91bc551f08fa94eeb5e4fa166", - "dest-filename": "chrome-trace-event-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205", - "sha1": "04a106672c18b085ab774d983dfa3ea138f22205", - "dest-filename": "chromium-pickle-js-0.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46", - "sha512": "e6d2bb12dad9d0df8e2c532d86da8e8f87c8d8979bf3c0b808064fbb6e4b0d55205c9d00dc9b383cc1aaae7d095355b4321d7f67cc19cd83f1a94ad77816e809", - "dest-filename": "ci-info-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2", - "sha512": "ae24ffdef239629547ebfaa89a50e7268c3a4c179ed8f04a484a71dcedf61063d86d618846c2251919acdd29bbe30604d49328f119ced381dbd76fafd49e480b", - "dest-filename": "ci-info-3.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463", - "sha512": "a8e84f6bf163eece9363c1fc7ac1aee5036930c431cfbf61faeaf3acd60dea69fef419f194319fe5067e5de083b314a33eab12479e973993899a97aeae72cc7a", - "dest-filename": "class-utils-0.3.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178", - "sha512": "1095034fb9c35450ef690800a361bf3c9bf19a9d68fdcea25cb6ecc2c05b5055e2d4dafe02303670a99f6ca0cc8ccbf311eef98373fa2646830c02a4f7a03ce4", - "dest-filename": "clean-css-4.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b", - "sha512": "e1d882f4769313e29100c5a10e1ac63840a0599c687af31ce5396439b32a352b1553ad8f6335d9fd23138f3c8600517562eb20c46712593117061a7408fc10d4", - "dest-filename": "clean-stack-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f", - "sha512": "cb872831cca581209d5629e388306e47c3c20b66cb8f2193c0498f6fd34747f41a354e8450e5dc4d8fece958c6303e8435211a790607098d063464b98df3303f", - "dest-filename": "cli-boxes-2.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7", - "sha512": "9fc7ce8b1c030fa6ff39b8a7cd3ae9d59285cdb82f299beecff4ef7a39cb9f56907c2eabe765c4c7ce459ae0bedc723e24cedca0145752f36a114d8f1d5ac7a6", - "dest-filename": "cli-truncate-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5", - "sha512": "3d87864849a61cceb3be879fdb0f133f396b9cda572234e2a582bbf3462cc2620ff6f8f199de98d9adc20762acebf014f0d1e366e817be8f30de858cdaa9f05c", - "dest-filename": "cliui-5.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1", - "sha512": "b7ac1b82da025ef033b2ded0817c4962a3edd2eb047db81075fb443db2cbfdcbefe873c4e5582fa82b80203474360539d9db3aac5c2aae06a434bac712309bad", - "dest-filename": "cliui-6.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f", - "sha512": "39c444ebc70eb15317a7562fa2797f7f39103b28cb4aeffc6e13c37d0b747b4fc46f6f374ca3f6d05b3632aa0fb2bf52c00e7de6b44203e40ccd873d9c13fe25", - "dest-filename": "cliui-7.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b", - "sha1": "d1dc973920314df67fbeb94223b4ee350239e96b", - "dest-filename": "clone-response-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0", - "sha1": "4bc0373c164bc3291b4d368c829cf1a80a59dca0", - "dest-filename": "collection-visit-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8", - "sha512": "41f014b5dfaf15d02d150702f020b262dd5f616c52a8088ad9c483eb30c1f0dddca6c10102f471a7dcce1a0e86fd21c7258013f3cfdacff22e0c600bb0d55b1a", - "dest-filename": "color-convert-1.9.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3", - "sha512": "4511023ec8fb8aeff16f9a0a61cb051d2a6914d9ec8ffe763954d129be333f9a275f0545df3566993a0d70e7c60be0910e97cafd4e7ce1f320dfc64709a12529", - "dest-filename": "color-convert-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25", - "sha1": "a7d0558bd89c42f795dd42328f740831ca53bc25", - "dest-filename": "color-name-1.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2", - "sha512": "74ecbedc0b96ddadb035b64722e319a537208c6b8b53fb812ffb9b71917d3976c3a3c7dfe0ef32569e417f479f4bcb84a18a39ab8171edd63d3a04065e002c40", - "dest-filename": "color-name-1.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b", - "sha1": "0433f44d809680fdeb60ed260f1b0c262e82a40b", - "dest-filename": "colors-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f", - "sha512": "1503783117ee25e1dfedc05b04c2455e12920eafb690002b06599106f72f144e410751d9297b5214048385d973f73398c3187c943767be630e7bffb971da0476", - "dest-filename": "combined-stream-1.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33", - "sha512": "1a956498cf2f176bd05248f62ef6660f7e49c5e24e2c2c09f5c524ba0ca4da7ba16efdfe989be92d862dfb4f9448cc44fa88fe7b2fe52449e1670ef9c7f38c71", - "dest-filename": "commander-2.20.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4", - "sha1": "9c99094176e12240cb22d6c5146098400fe0f7d4", - "dest-filename": "commander-2.9.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068", - "sha512": "34e2a6f31864cc08f3171f01dafe4e0074febb9a5141cd9409ad95abd8d82ffdf5a36c22f66c4103b2c816cdec5795520b8f73ea91217db3142ef4a12a3dba58", - "dest-filename": "commander-4.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae", - "sha512": "3f40b2b0d0d0eebb55c3840842d9be311c55ebabca152be5b10bc6617656477a855348e530a1d9659830f1efbc0d26a1e140ca32a9e49d10d0cfec6e41743f66", - "dest-filename": "commander-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b", - "sha1": "ddd800da0c66127393cca5950ea968a3aaf1253b", - "dest-filename": "commondir-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080", - "sha1": "0162ec2d9351f5ddd59a9202cba935366a725080", - "dest-filename": "compare-version-0.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0", - "sha512": "45ddec7ba401fac3b54f0a998ec710aeeae910f21f3b4ff26274a29fa43fac3de63aeb47bd4ac202126e6f7afdd2e35bf9211206e134418a01f7461d7dab6c46", - "dest-filename": "component-emitter-1.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba", - "sha512": "005debecfe5d5b12fc331c884d132539140d68e036224005693af893b054ba68cfb51a460d36699743dbd5708ee89783081769d76e8282cf6c331a928e063246", - "dest-filename": "compressible-2.0.18.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f", - "sha512": "8da4880f33fda59552e197d0f93cefb625a17691611364431f3f10264a57f522292eaf3c56e785e63270eadfba09441c02803ab7ec7cf4c2eb580aa97c313c89", - "dest-filename": "compression-1.7.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b", - "sha1": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", - "dest-filename": "concat-map-0.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34", - "sha512": "dbb1c18212718e266d224dd872f9ffe246c993fd6e66e2457ee3c49ece8b684be9bc6d5fd214de6bc96296ba2eca8f6655cd8659d70467c38ba0699200396b0b", - "dest-filename": "concat-stream-1.6.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/conf/-/conf-10.1.1.tgz#ff08046d5aeeee0eaff55d57f5b4319193c3dfda", - "sha512": "cf6722bf0abf93c4cc62d727dd254fd0f7aca38a2d2169c7b5c4ee1e1434cc364374fe0d4f1a8473ca307e4cf8cc1b1d318767fcb15c13e6616c27aa921b6add", - "dest-filename": "conf-10.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4", - "sha512": "aa3f9ff003c04571eb33486b6aa5d86f6fdb395495e0fbc9425359fc3563d10ae634cdaad9eba2ce47ae55c910e7b27e5b49911fa1ef8be939d0ce09ba5d9545", - "dest-filename": "config-chain-1.1.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96", - "sha512": "68c2a9ae093962104dc87db9863f301addbe0f9d92c350d1448cea0702e9d986bd985998f0a3efbedbe69daf12c5547d24c678933303ebc376daf95a46991e14", - "dest-filename": "configstore-5.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc", - "sha512": "7b9e01f7dabf394a07eb8cd86117f71c13f9cf6e06dfc8790f7a97bb6dc9191a228295f94ace2bf599c393783467cb900b6c7694f689f9495605cd5958159d2e", - "dest-filename": "connect-history-api-fallback-1.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe", - "sha512": "16f7994cdb86c34e1cc6502259bce2eb34c02ff9617a16966d3b6096e261e3f13de43a8cc139a16b7299375680580f1c148847ccc654bcb7af930e51aa4fad49", - "dest-filename": "content-disposition-0.5.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b", - "sha512": "8483f71043ecf2d07d013d4bf8d52ab70380a6ce269366686fcf4c5973078c75a0f668a517f8f8a2c9e740b5c108114193fb6f206fed51cf663942623c184f5c", - "dest-filename": "content-type-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369", - "sha512": "f8e41d8cfe3dcd5888ffa8bb9c826903cac0978b15fc974f7d4f6766cdd5a8ec062208b3202bee376aeee9f31dfb89652f4b5aaf5f146095df67f4d6b668548c", - "dest-filename": "convert-source-map-1.8.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c", - "sha1": "e303a882b342cc3ee8ca513a79999734dab3ae2c", - "dest-filename": "cookie-signature-1.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1", - "sha512": "670ac5906271511dc42285ed3bec9513af446fb2a58b16da78059f05007dbd5b0d9ffa3e630ebd8015924832bcdb985035d37ec05f3310b7f7745365fe4c6450", - "dest-filename": "cookie-0.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0", - "sha512": "7f676899df5fb150c5b5a15c6da459b985f0b5d9a7cea6c00d2c21496631601fd0f33b1d51414c5d54705c60cc5a66c4cc09f591d46bb48d53fca4c538be17d8", - "dest-filename": "copy-concurrently-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d", - "sha1": "676f6eb3c39997c2ee1ac3a924fd6124748f578d", - "dest-filename": "copy-descriptor-0.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6", - "sha512": "73c339874224359f88f76421229b928a33b1180723de5829b167640aa9944d937089dba3178af7a62eb1d4308df9572ce6a4d2d9759631f592b82ab2ba95fc83", - "dest-filename": "core-js-compat-3.20.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7", - "sha1": "b5fd54220aa2bc5ab57aab7140c940754503c1a7", - "dest-filename": "core-util-is-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85", - "sha512": "65006f8b50dca49e060ea6a78ee719d878f7c043b9a590d2f3d0566e472bbddc64b09a2bc140c365a997f65745929f5ac369660432e090e6c40380d6349f4561", - "dest-filename": "core-util-is-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6", - "sha512": "897de67e0713308ab764a2c8b151406efefe31cd7493169b00641bf07be3035a374f53c8629adb6a443ae5ddc8fb61c61edea748a90cf4f62382824ed8a70505", - "dest-filename": "crc-3.8.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/crocket/-/crocket-0.9.11.tgz#288fca11ef0d3dd239b62c488265f30c8edfb0c5", - "sha1": "288fca11ef0d3dd239b62c488265f30c8edfb0c5", - "dest-filename": "crocket-0.9.11.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cross-spawn-windows-exe/-/cross-spawn-windows-exe-1.2.0.tgz#46253b0f497676e766faf4a7061004618b5ac5ec", - "sha512": "9a42ed2497186c30b1106ec9b3a7949d43677568f2519c09dc7edb12b9a6b4e614fd96fdf43c949296a6b88644d1bddb86627267b0fdd2e4ba7fe086c514633b", - "dest-filename": "cross-spawn-windows-exe-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4", - "sha512": "79354bac14adedf8db0f2833f34e69327b2d22cd954c1364466d2ac5977e33b0395c377155158ee4cc460576618d8e1ca8b60b76dac6a917fc9813e6cf04a959", - "dest-filename": "cross-spawn-6.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6", - "sha512": "8910cf24a50f544343edd1cf3bcae46ce9cfa720f281c0c5b568e9796342832f163f6ad77315cbf13b2445e425e8eac1d86efe509ada82cd6ad7916e75cec6eb", - "dest-filename": "cross-spawn-7.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f", - "sha1": "5183bc47a09559befcf98cc4657964999359372f", - "dest-filename": "cross-unzip-0.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5", - "sha512": "bf5a65203df2f6bfe53e1be2275c2b5e92dec94206019d921cd61311aa66efff00f672cfa32bd5a7744afc43c5aa7e641339f25a061936c46d6182166ee1bc28", - "dest-filename": "crypto-random-string-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/css-hot-loader/-/css-hot-loader-1.4.4.tgz#ae784932cd8b7d092f7f15702af08b3ec9436052", - "sha512": "27fa971f3fabec5393f76a8c2097f1524d0b0bd7de71035956bd0cb3043814ea4a2f2382063a1f54c7dce91dbaf1b87fe64b644d286bc1e32bd305aa7ab0bdda", - "dest-filename": "css-hot-loader-1.4.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645", - "sha512": "339952ba4a168b521ff1d8500140af8f81fcbd4b77bce9f06d0047f437539bfb38626d81ff774f32d6197899aaed0dd2dcf6be23de03719ee973d6cfd7871621", - "dest-filename": "css-loader-3.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd", - "sha512": "fda52c94a873913342414076a935fce255667e26bd3728cfdd6a431ad8ff5b18700735816145770e0529bab1d399ef144cf70f9400f50c9f9bd2737fb79d330d", - "dest-filename": "css-select-4.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe", - "sha512": "6ab48c456208158d2157ca48c593047e6308e3b5a3dd1fda5a96430f159808f12238cbfab5f3ab9e90ed8310583c4403e15d18ffde7cfb54dd0b78964c57143f", - "dest-filename": "css-what-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee", - "sha512": "fd36ff25c8cad75d67352706a1be4c36db27b4d3356823540e2a41fd39306458720ebac4e3b48ec7fd7cc05d9b6e381cdd9cc248a5b54f99ede446c5a00cff56", - "dest-filename": "cssesc-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dbus-next/-/dbus-next-0.9.2.tgz#d69a24ea5b54d90ab6bd543c7b81bcb965a99f93", - "sha512": "b7342affec2b4d9db253e5393e879773deca001857dafe790bf4f47e29c7ded48a62e23c1ff4aaa69205ca6041ad41dc2b5dcbbc4198def763de290f3de9cbe6", - "dest-filename": "dbus-next-0.9.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/debounce-fn/-/debounce-fn-4.0.0.tgz#ed76d206d8a50e60de0dd66d494d82835ffe61c7", - "sha512": "f296024222fd5dd720d143d20f777ed0a3253a3a7e28653910fc1875d83343b0c04ec8387ee5038d0b6c60b9968e7936a1b9cd1e0577bc4d98e237a348e25505", - "dest-filename": "debounce-fn-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f", - "sha512": "6c2ec496b7496899cf6c03fed44a2d62fa99b1bdde725e708ba05f8ba0494d470da30a7a72fb298348d7ce74532838e6fc4ec076014155e00f54c35c286b0730", - "dest-filename": "debug-2.6.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a", - "sha512": "0858f3618022e1385f890be2ceb1507af4d35c7b670aa59f7bbc75021804b1c4f3e996cb6dfa0b44b3ee81343206d87a7fc644455512c961c50ffed6bb8b755d", - "dest-filename": "debug-3.2.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664", - "sha512": "ff3c70e7ebe1d537effb8427edae67b1b70928f692bc20e1a239fa14497dbeea702b6542483b44884b6aafc0c5b7360539dcfadcb064c5e73b0d8b9cda3a27e9", - "dest-filename": "debug-4.3.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290", - "sha1": "f6534d15148269b20352e7bee26f501f9a191290", - "dest-filename": "decamelize-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545", - "sha1": "eb3913333458775cb84cd1a1fae062106bb87545", - "dest-filename": "decode-uri-component-0.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3", - "sha1": "80a4dd323748384bfa248083622aedec982adff3", - "dest-filename": "decompress-response-3.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc", - "sha512": "696df9c9933a05bff8a099599dc307d8b0a866d2574d1c444b5eef137868462a305369161da24a1644810e70d1f9c9bd27ef5085799113221fbf4a638bd7a309", - "dest-filename": "decompress-response-6.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a", - "sha512": "c9df5ce40762a95711f898dcc1441bf4392125cf2780daf431a844046bc3889c3ca6e59a6f6c99961fa791ab0e9d93fe1064c03faad1a76273261259cef345f2", - "dest-filename": "deep-equal-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac", - "sha512": "2ce1f120e68f61d1e5251b4241f0c8559b5fc3fb9f33cfab563eb8f51207cdc9bfbc6c1045716de8e3ea2055ac9b65c432b34812d591eb8b18d4b10a0f6bc038", - "dest-filename": "deep-extend-0.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b", - "sha512": "87ab0cad507554c595ad6d7799273a89afc3c18630e4c37af9ec4dbb539a25e15a73969202fc0cee56743557d3001b929107a5af8879a1e6e0dca0755cf76380", - "dest-filename": "default-gateway-4.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591", - "sha512": "d0849d368bac1ef653d84885959799007054bd2c662acc150847fc856eca5a01b86bc31512eff755beae598a33923ca5c82c5ed090488910758d5e394bbd1655", - "dest-filename": "defer-to-connect-1.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587", - "sha512": "e2dbedb5ea571b555a606ad189b93913025dd6de2e76e9d239531d2d200bea621dd62c78dfca0fc0f64c00b638d450a28ee90ed4bd2dc0d706b1dcd2edd1e00e", - "dest-filename": "defer-to-connect-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1", - "sha512": "dcca9f60a8f694bcdd3127fc648644fd5f99bb2f81803e9fd7ae1ef0adb0edd827a4a02b0437ab198a4ce3a21861c8e791d3cd3233e4f40e95141f3edd22a55d", - "dest-filename": "define-properties-1.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116", - "sha1": "c35b1ef918ec3c990f9a5bc57be04aacec5c8116", - "dest-filename": "define-property-0.2.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6", - "sha1": "769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6", - "dest-filename": "define-property-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d", - "sha512": "8f02b6515e1c9cfa5b706efe55101129364f516a30c1703c6f31f934feae774a1e031c983ee1995000bb84cba0a42773e01792665d8397d93ae821c9ff8e9961", - "dest-filename": "define-property-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4", - "sha512": "4301ae114a2e3f6915c107a702c3a87f916ff0af6ddc3f026bc3717172ab2291078d35cae49da75cb74ff802c8d5c82ff308fb2aec01853c0190e65224a3395d", - "dest-filename": "del-4.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619", - "sha1": "df3ae199acadfb7d440aaae0b29e2272b24ec619", - "dest-filename": "delayed-stream-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9", - "sha1": "9bcd52e14c097763e749b274c4346ed2e560b5a9", - "dest-filename": "depd-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80", - "sha1": "978857442c44749e4206613e37946205826abd80", - "dest-filename": "destroy-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7", - "sha1": "f0d66d03672a825cb1b73bdb3fe62310c8e552b7", - "dest-filename": "detect-file-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1", - "sha512": "4f4348b90a674ef14301336e1cde6ba0fc12046f37ac5b2e3be3175c7f7fdcdd5e15b9f8c1c3e3b6dbe330b10f589d11194620404edc1a04b7b4dc5ba8218cee", - "dest-filename": "detect-node-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.2.tgz#2e48c0d3b825462afe75ab4ad5e829c8ece36257", - "sha512": "415e8f31a1d308d98a49e3fa4285e1553c3db2773d543f0cba54d3d0177df4f69ca78492d5c8dcad83e004f9a26ea295b4c2497ea0ba5ef39780f30410f1ff7e", - "dest-filename": "dijkstrajs-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631", - "sha512": "97d866bbcc7fae3542f59db3986ce484e128c19bd6ee9998c2ce42587bad83cbb5260bec296331ed0fd43837aee1d8cb6781605b96deb30e72bcc427047cee08", - "dest-filename": "dir-compare-2.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/discord-rpc/-/discord-rpc-4.0.1.tgz#a89aa04a048aa83ad4f347d53fa0162501eae0d8", - "sha512": "1cebc7a5bab9493459263408073c282a74348c7a656c45855a53c3c175ca9bf6c82e1e27ce3720ee636a965d1463b46c8c5a1a5c0edefe861bff896fa5d6b6cc", - "dest-filename": "discord-rpc-4.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.14.5.tgz#137c0b55e639badcc0b119eb060e6fa4ed61d948", - "sha512": "d46bc5190137df66ef3da99c330643a96a9f59f253cb20cb3ac1cc7068b4cecf8987b24e9faff3b8190724858776c8f64096e1ccb572776fd9aadb4e2afec8f3", - "dest-filename": "dmg-builder-22.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dmg-license/-/dmg-license-1.0.10.tgz#89f52afae25d827fce8d818c13aff30af1c16bcc", - "sha512": "49579eca239e8a75792423c75cc74a3a02b56156da93fe3ef162f6ac19dfa9162903915a7856909d059bdb9c7adbc6a6d70ef409b8a9183bfd4b9d5b8a987adc", - "dest-filename": "dmg-license-1.0.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d", - "sha1": "b39e7f1da6eb0a75ba9c17324b34753c47e0654d", - "dest-filename": "dns-equal-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f", - "sha512": "050e85e2fc9c2d706f76b259e92de065ec2deab72b92cf4a06033dbeb856fa49c646a73cb84753edfb82c25a1cee79f2e71368309d7b1c61f447fe9fa68f0408", - "dest-filename": "dns-packet-1.3.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6", - "sha1": "b91d806f5d27188e4ab3e7d107d881a1cc4642b6", - "dest-filename": "dns-txt-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768", - "sha512": "81ddf2a483df38cafd8798c82aaf04dec1ce4c28de8ab9e5d162b965d4b5016d0e76dd1bd4f696687749e10938925bfe601f5a2414bb9844978c5a0340fbba0c", - "dest-filename": "dom-converter-0.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91", - "sha512": "e5ce78064e43c38a80c4d388d691448b33d28d5b31e7e6e924a98bda43e7f0984152adaad3db5309ade68e28ee9f635f2bbf0d328b8360d30190eacf6624be8a", - "dest-filename": "dom-serializer-1.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57", - "sha512": "0ed04ca3cda9bf5745b54987cabe3c6de8aeabbf764b1a21afef079bdce8c649583df6ba9f46770728e3d8857b6e6af6232a82967a844217e01c9279405d11e4", - "dest-filename": "domelementtype-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a", - "sha512": "2750b9ac800d51bb982be16e14bf7ceb9d2b8a1ca750e13344bc56fbdd1b29945607a0355f54dff361b1475a8058bc9f34f46f8ea7e2a77439b5d6259806bd94", - "dest-filename": "domhandler-3.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626", - "sha512": "7c2d1a5cd417a8a4854ebdb00cd64386c1188c2898b035a5dc3d35930b76e619b56083f20c61efbe2debc3e3cba87025fe6ef531a885edde73bc1af4a79501da", - "dest-filename": "domhandler-4.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135", - "sha512": "c3de828e87e9ef63392088698e0a1b06299811fa0f8f1d55c740525fd3f7d1605d656d9620a5344f505dd24cf678d67d8a48ca8076c4c8ac7c041e87d4bde1dc", - "dest-filename": "domutils-2.8.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751", - "sha512": "2afe672a587ac91addac6bf1789d9ee72d9e454a64528b085b8036012dfccf04b3dbbceeeee7c3c103e2e4986cdd702518d7ad9776e69c6850b0cb642899e3df", - "dest-filename": "dot-case-3.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88", - "sha512": "40cf2adf30dee7c86a52a8eb6903a6cd9d4b207f525902539442821f8909da842f2d993b45b417bed0ccd9712addfc2457d082bef1f82c0d0057ea2016c04cd9", - "dest-filename": "dot-prop-5.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083", - "sha512": "b44ef3b58cd71c87b2bdcecdfa1477a22ec521b7ff3488d53fd86602ddf2317ceb434ef6fdfa6318bc761b13711b1525e55ef7304a98ce2a0e32856118c27970", - "dest-filename": "dot-prop-6.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0", - "sha512": "617425d4349ae3f3d0c917e0aefe9aa0d8e16aca7fa78aacf458c9e2ae1c424fbc9b8afa938652884cb2b4a1bc7fc5bd822f16b10b4839b36629dfad33335398", - "dest-filename": "dotenv-expand-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b", - "sha512": "22b3dd5d0b24d816f3bc204604e4e69921f94a8766a9936de04440643996e024feb4bf15b6f8a7ab2c2e00d685bb86ce316922d7a9ea7f47b8a02d1021a0ebfe", - "dest-filename": "dotenv-8.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05", - "sha512": "23d3afbeb1e9e2920046fe3ec7d8ae7b0ad6c9c5fa09c66da00bb55ebccfc5ce54ca03095c9658981b329e4bbc224ac9c20ca91390c63630cf98f4610c2a6d52", - "dest-filename": "dotenv-9.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6", - "sha512": "8ed0fa606dfbd190888bff464da24a431593643d38e7ee11e214e4ff1d54ca8a9a77227dc7d0a04a2d519550d017c536b312cb4a716409a32286a9631c85a032", - "dest-filename": "duplexer-0.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2", - "sha1": "ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2", - "dest-filename": "duplexer3-0.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d", - "sha1": "590c61156b0ae2f4f0255732a158b266bc56b21d", - "dest-filename": "ee-first-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a", - "sha512": "f65b7d66c7b884fb9c3e4a0fec51c31742d00251b217d255a670a514b147dda4926f19b2a2a20d469a7ff7078f5894d497828e43044bef6230dc89c73c39281b", - "dest-filename": "ejs-3.1.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.14.5.tgz#3a25547bd4fe3728d4704da80956a794c5c31496", - "sha512": "37bde149b5c5cfa333e59ea1e82e65cba081f9d50dea4d4bb820c98c8f15178edb317bff404d0713e2a46f418f2aa4ea33b1ec93fc88617fa41c27d2911e451a", - "dest-filename": "electron-builder-22.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-2.2.4.tgz#261a50337e37121d338b966f07922eb4939a8763", - "sha512": "6f991c33786652a9fae3e4547078e3afc64ca474b6589e583b4a671bdf8ffd14ddc78ea87ff26b123b9c8875aec7aa44f8e9faca75a11c9179de3fc40c93743c", - "dest-filename": "electron-devtools-installer-2.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-fetch/-/electron-fetch-1.7.4.tgz#af975ab92a14798bfaa025f88dcd2e54a7b0b769", - "sha512": "f9f04b5c4cb8089590e5bcfc77269e486d610fa249d799016728f77a1db8a4856b77784b338ec7fee99f7eb7507d2e866747da945d20f494fd7f746ce8055487", - "dest-filename": "electron-fetch-1.7.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-log/-/electron-log-4.4.5.tgz#5fcfd0c2dc5fbda915ee0a9d802705dc57930786", - "sha512": "09f6b608a9f00619547c897faabd86179482a9fa00f723c1a9327aff03ecf8f127dfa336f8467746919268e858435059a6894bd425b27aede0306f1ea4b97736", - "dest-filename": "electron-log-4.4.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-1.1.1.tgz#3ed274b36158c1beb1dbef14e7faf5927e028629", - "sha512": "92e7ec9ea87ce824d7f3d018346dcd08fa1ba2a9e4bbffb7d91c5e276fbb03845b9b86db3b1d0d73b5d3cb7fe002505fa63f713c0c477e164b38781f8ba70957", - "dest-filename": "electron-notarize-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz#fc258c5e896859904bbe3d01da06902c04b51c3a", - "sha512": "89ca112c7cc5cffab1cc387f3783e2db3e32547bab96c080610bec0921bb7c279d2785095c14ba3e8432187ef521f72a2aea5c29e2bb1d7fcd9327c6fafeaf95", - "dest-filename": "electron-osx-sign-0.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-packager/-/electron-packager-15.4.0.tgz#07ea036b70cde2062d4c8dce4d907d793b303998", - "sha512": "26bacb7013f5e4a1ab3e3d1c67f00b28699a438809927de6a1c7f41376d129d47793129661c0d1a42bdd864b180d7c3faf723ab4c11c67b5f3c80a56157755a7", - "dest-filename": "electron-packager-15.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.14.5.tgz#34bcdce671f0e651330db20040d6919c77c94bd6", - "sha512": "87e34035175a0343ea185d7918abe8aec7963f38753d76bfcf1e08dfbfff3c8a245bc78a228bfc932db77e85126f9e591565071a9c5026ec7bcb63427c1b507a", - "dest-filename": "electron-publish-22.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-store/-/electron-store-8.0.1.tgz#9b598c1d2edeffebee9d8c1cd957ad368c528925", - "sha512": "6722ef372c22a92a5bc02fe9a7cf4efc0c9c55663f5092249adcb317605dd0d9bfacb99c15cd0d4c6b8b760ebe2c4f264bcaac88ae493287b83e7ade70b1c7e7", - "dest-filename": "electron-store-8.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.57.tgz#2b2766df76ac8dbc0a1d41249bc5684a31849892", - "sha512": "14d0be3f92b59faa45f8cd3320afa0142a17709861cc35622f70d1206cb616fe4fa21b92112d491d1ed3f86970c52c65cf1e3261bb2ecc266f1f17014910883b", - "dest-filename": "electron-to-chromium-1.4.57.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.6.1.tgz#80ca805c4f51b2e682aac29d18fed75d6a533d32", - "sha512": "62c535987a972eb5d798132cc61c72db83eb6da07cae7a590cf9856b680e913624fc2875dfe4747e3b114a93d8beab6c915558d2ec7c7eef879d491592a73ba2", - "dest-filename": "electron-updater-4.6.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-webpack-js/-/electron-webpack-js-2.4.1.tgz#5389cc22f34c71f6416d5ba1e043f9b0fd6130af", - "sha512": "34f6dc2389e7b9c9642c42a6c1123cb2e8b618d7b7ecd2a6d2909047a29903b612577290747e08ef03a0219d8091e0a9c9e507ac148c19063e56a84f0fb3ad30", - "dest-filename": "electron-webpack-js-2.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-webpack/-/electron-webpack-2.8.2.tgz#5a0357ce8f7d147e5f559294a08bb072d1092b0a", - "sha512": "ad1ee1c683a56487097fa474f26565ff84c1b4563e1d6eacbf8676f1374c5844ef70ce1904805d18d1b297117480dc01f20913828f149240db5c65f8f0ae15a3", - "dest-filename": "electron-webpack-2.8.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/electron-window-state/-/electron-window-state-5.0.3.tgz#4f36d09e3f953d87aff103bf010f460056050aa8", - "sha512": "d66353c027e4a255e5de431fe74c96def1369598f4cbdd8ffc7616141adbfafd92fe90a46b999dc0dddc6a02a6e39f00ecd8e7752c228f29d781c2d646876c56", - "dest-filename": "electron-window-state-5.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156", - "sha512": "0b004b444210ecbbd8141d16c91bf086ae4de6a3e173a3cc8c3e9b620805948e58c83825fb4bf1ab95476cc385a8b83b85f5b39aef13e59d50a1f8664c8848b4", - "dest-filename": "emoji-regex-7.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37", - "sha512": "3128d8cdc58d380d1ec001e9cf4331a5816fc20eb28f2d4d1b7c6d7a8ab3eb8e150a8fd13e09ebd7f186b7e89cde2253cd0f04bb74dd335e126b09d5526184e8", - "dest-filename": "emoji-regex-8.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78", - "sha512": "fe4c8cd7c11f8a7c1765b9e8f45c9419e161f3b282f074500501a295d1d96c4b91c9614e9afd54d74a3d041a7c5d564354d36e40ac88188bb96580005c9d15d9", - "dest-filename": "emojis-list-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda", - "sha512": "b9c027b8112150ae1ba07d878d5606e50da64323e8aefbf4bbfa1c4bece1770d12f00947618f8638584fd468a8e73e227293f68af152be1b458d08bcf93f69a7", - "dest-filename": "encode-utf8-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59", - "sha1": "ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59", - "dest-filename": "encodeurl-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9", - "sha512": "11305aba8c354f7e58fd664c922a3d8e2334679c631c7989e179a364eab597f757cf796bdac467f3b9c9cb6d11ba9a928751769b71c73d2a7c4a120f409ac9dc", - "dest-filename": "encoding-0.1.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0", - "sha512": "faec358a720754f428695b87cd1c97776d6270cf9c9ede02cc3e6b5be342d708ce5124ceb3e4deec53afec084deef4bdc7fa08ca12cfe4f4751fea614001eee5", - "dest-filename": "end-of-stream-1.4.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec", - "sha512": "36ff66dfa4bfbf1a6c23e1dce3f64646cd27f665ea496186ab8f73c5bfdc25f3c040c6d4b6db4902534f4b8010cda05dc3fa4ab24c396cc6de913fd8ed6fd696", - "dest-filename": "enhanced-resolve-4.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0", - "sha512": "10601b1af1fb8fb5edda773413b0fdf4b6b53a212cf0b9f28a6911830131a5431270de8efb7c7db485acecf2d0655371e180fed34b241d73d78b5c901e902664", - "dest-filename": "enhanced-resolve-5.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55", - "sha512": "a7dda27f9373eb5f48d30f9a909acb647d0c5f43dbe435f7f573b0413b5749d41039a607d374b5b88429e2684e66d017af1ab85623baed84e22c1a36eb7f28f4", - "dest-filename": "entities-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2", - "sha512": "fa1d6590b2a164c4d88e8835544a49346ecd64959cb9cd830e4feab2a49345108e5e22e3790d5dd7fb9dad41a1a8cc5480097028d67471fdaea9a9f918bb92d8", - "dest-filename": "env-paths-2.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f", - "sha512": "749ea806be5243555277daa493b0724606ffd521f82598c21d25bf9abeb7fd07173bdccb571bc9e8ecb5de78a8d37af1a529d50c38c5a2bef94a355e6563d6fc", - "dest-filename": "errno-0.1.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf", - "sha512": "edd147366a9e15212dd9906c0ab8a8aca9e7dd9da98fe7ddf64988e90a16c38fff0cbfa270405f73453ba890a2b2aad3b0a4e3c387cd172da95bd3aa4ad0fce2", - "dest-filename": "error-ex-1.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3", - "sha512": "daf27ab6303f51fa8b9b630fb3b8f15726cba01f22d6dd4977d4779084a5776d2c2313dc4db2ee82040e531796780bc852476ebff09f323ba1e169a25ebdaff7", - "dest-filename": "es-abstract-1.19.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19", - "sha512": "d47436336b0fb71c27bcebd3d590a51f24038a081d3635115a9636c1ee9a30a0908945714e656cd9460f2c8ac3f38b12fa431d5307c14b295b24fc0d9c1ae71d", - "dest-filename": "es-module-lexer-0.9.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a", - "sha512": "4023a5960649b5a528f6689805c2c285351a1cd8c91773d8b35562743ec0c22123d6463129e41372d2c07b300e1f964a447d20d8880f9fa2b0078213f22469bc", - "dest-filename": "es-to-primitive-1.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d", - "sha512": "526ffe17132bf422125a1d1b8b966fd22383fb8705879a8b7a4b35aa1028a4a540270dddae029b2b24a2929ef01a10cbd073de6a36b43f950b66bc4b92789456", - "dest-filename": "es6-error-4.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40", - "sha512": "9347abda05242dff0ed332898808669139c9953bc8346bfbca00cd3db788b17fd3263189647ba1f41d94c5bb1a1249a5128f4c7e1ad2ce68489614652361979f", - "dest-filename": "escalade-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675", - "sha512": "f3fb8885b1b5d82b23cb62445bb0fda476eb79a55a4bf3a9377c9c9f2bc49537703399fa198e96e9ed883de99fbc665e50ca99f40ff71aa2193202a7061030fd", - "dest-filename": "escape-goat-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988", - "sha1": "0258eae4d3d0c0974de1c169188ef0051d1d1988", - "dest-filename": "escape-html-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4", - "sha1": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4", - "dest-filename": "escape-string-regexp-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34", - "sha512": "4eda5c349dd7033c771aaf2c591cc96956a346cd2e57103660091d6f58e6d9890fcf81ba7a05050320379f9bed10865e7cf93959ae145db2ae4b97ca90959d80", - "dest-filename": "escape-string-regexp-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c", - "sha512": "d8dc706c5fe16742a97a960dd1c35ba3e14de97a0aec6687950860c7f848665e956b46c5e3945038ec212c8cbc9500dbb8289a7522c20671f608562aba2b796f", - "dest-filename": "eslint-scope-5.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71", - "sha512": "786b85170ed4a5d6be838a7e407be75b44724d7fd255e2410ccfe00ad30044ed1c2ee4f61dc10a9d33ef86357a6867aaac207fb1b368a742acce6d23b1a594e0", - "dest-filename": "esprima-4.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921", - "sha512": "2a67ca2f76fa1be457bcff0dd6faf74ead642ffa021609f63585c4b6a3fcfcbde929aa540381bc70555aa05dd2537db7083e17ca947f7df8a81e692d8bafd36a", - "dest-filename": "esrecurse-4.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d", - "sha512": "dfd9e729f7d6cfcc4dd4153fd9cefd9fd9c1f470f3a349e2614ab1eb1caa527ca8027432c96a4e4dd6447a209c87c041bb9d79b78c29f599a055f5619fd101a7", - "dest-filename": "estraverse-4.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123", - "sha512": "30c74046e54443388d4de243f0380caa6870475d41450fdc04ffa92ed61d4939dfdcc20ef1f15e8883446d7dfa65d3657d4ffb03d7f7814c38f41de842cbf004", - "dest-filename": "estraverse-5.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64", - "sha512": "915b1ca97938382a7af126747648042958baffc8a3df4d0a0564c9ab7d8ffdd61e5934b02b8d56c93c5a94dd5e46603967d514fcb5fd0fb1564a657d480631ea", - "dest-filename": "esutils-2.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887", - "sha1": "41ae2eeb65efa62268aebfea83ac7d79299b0887", - "dest-filename": "etag-1.8.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571", - "sha1": "4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571", - "dest-filename": "event-stream-3.3.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f", - "sha512": "f20b870590b02a716161d1ebdb2b2e45612b4f08683765fc5c42d196b470a667de6368e3b94378b5a40cb142ca515a352b80ef665fb4a607f2a32b07c6f9af13", - "dest-filename": "eventemitter3-4.0.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400", - "sha512": "990c3ed9f9106c02f343b574318d08a9d9d734e793b4fe2bd2537dcfb0006b009782a79aedb0e28b6d0062b201ac577f1f1d0cd8e733e92d75d4268591471bd1", - "dest-filename": "events-3.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf", - "sha512": "5522634f9a0236b16f092ea2823ccf02de61073436a8f04521b274df32c8f521349b1c19a4cc3a05f26b6c51e6d5ad78d406af30407c24798185601deba3df0a", - "dest-filename": "eventsource-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8", - "sha512": "69d6f1732595e3aaa21f2bd2a79d132add39b41e2d2b71dc985eff9f17c07619e8c7cdec7930dbc276aa28ee2c5d1cbbae81c0205a893ff470fc0b846d7eb52c", - "dest-filename": "execa-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622", - "sha1": "b77735e315ce30f6b6eff0f83b04151a22449622", - "dest-filename": "expand-brackets-2.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502", - "sha1": "97e801aa052df02454de46b02bf621642cdc8502", - "dest-filename": "expand-tilde-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3", - "sha512": "a31971271710958c2a3d6295249b6f422c07828b07fcbacb48f03e1f8531a72bd24ba8c2e5a1fee4ca0714cf8a0018133add003ee7b8c3ae876bc8c2528f501a", - "dest-filename": "express-4.17.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f", - "sha1": "51af7d614ad9a9f610ea1bafbb989d6b1c56890f", - "dest-filename": "extend-shallow-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8", - "sha1": "26a71aaf073b39fb2127172746131c2704028db8", - "dest-filename": "extend-shallow-3.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543", - "sha512": "3666fa4179042ecb81af6e02252922968e941c781b7a42b95226607c4e941c3dc46f6ed80baa03f9b85c4feb49e9c97c766b20750c675a572bcbc92c04804ba7", - "dest-filename": "extglob-2.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927", - "sha512": "c688791b55bf3c1d3fdbb95780c4322213f90d263f2e1a02b0ec9981bfba88c991b42c15068e79b8a68ca0462b0c2290856bea122a7964f28073a7853727ff30", - "dest-filename": "extract-zip-1.7.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a", - "sha512": "183854f67b70b8ac865dd6415204c87bebd79d68f47e9a5412d3032f4fa275de52b5af131a91ecb27fdebac03d9ab3ebf6a343ca6e92c406198cdbc29fff5106", - "dest-filename": "extract-zip-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07", - "sha512": "5ab937e5ef327422838ff02b0a5a3556b3d598df33a61e55e00b47c08b8786f317b0a7fbdd44f704e0fe6b30485bedf0389e058441fbcf2689085bc286362f30", - "dest-filename": "extsprintf-1.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525", - "sha512": "7f7a90f68432f63d808417bf1fd542f75c0b98a042094fe00ce9ca340606e61b303bb04b2a3d3d1dce4760dcfd70623efb19690c22200da8ad56cd3701347ce1", - "dest-filename": "fast-deep-equal-3.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633", - "sha512": "96177fc05f8b93df076684c2b6556b687b5f8795d88a32236a55dc93bb1a52db9a9d20f22ccc671e149710326a1f10fb9ac47c0f4b829aa964c23095f31bf01f", - "dest-filename": "fast-json-stable-stringify-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884", - "sha512": "5be28973676620b94fa650ff1f82bd97d2dc00701f3ed3fa058f38b952d743a12f733f4b720df7636cf52156e54fac5d639e0f5d854712ffb45a9abc228eb390", - "dest-filename": "fast-safe-stringify-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da", - "sha512": "0b36c297095702e891400954c9fa8f82f3e834a4dc9133c67f0655e1974085570fda587d294c498366f91a413b5db8ca4376099d0f73e83f67b4b02507eb4ff2", - "dest-filename": "faye-websocket-0.11.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e", - "sha1": "25c7c89cb1f9077f8891bbe61d8f390eae256f1e", - "dest-filename": "fd-slicer-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e", - "sha512": "d1bb6723f1fc7f6a5abc630df30e349a548a39f4cad925499817c1795223de4370d2cc30833c91ab47794c954ec287459adbe93de58f37f30271fb961741336f", - "dest-filename": "figgy-pudding-3.5.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d", - "sha512": "aa8de096ac936bad58b60e2eef71ae96d8c71a3751ca2837b46ea53edc97fe338426f1e27fdb81d3f3822362a27fa72d17771a4135b61b98329b6d6802c238a7", - "dest-filename": "file-loader-6.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/file-type/-/file-type-16.5.3.tgz#474b7e88c74724046abb505e9b8ed4db30c4fc06", - "sha512": "b95b25ee21611d2398e1b10e34b9532b8ee2007b4db051d63f9604e3125f678ae75fb4b5437c1c7b4f5782a482ec4ff187c35cbff6ded65368ca9ae5507ff1e8", - "dest-filename": "file-type-16.5.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd", - "sha512": "d19b7eb372fb55fd5b8b0599dbd6804625582f1ee23069c4525f71df77db07f8f78d1f35bbf3b62dba8af819b508348d0ca56d27f623c18ed351de5291e2d02f", - "dest-filename": "file-uri-to-path-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b", - "sha512": "cfb3b4212f0f95cdfdad30aaea2ea21f1938dddb983a7f2e14989649ec08ab4070c3544dc9b5474828da866702f3b66a026e0e4ef173973786bb75c0cc6d5cb5", - "dest-filename": "filelist-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229", - "sha1": "abf73dfab735d045440abfea2d91f389ebbfa229", - "dest-filename": "filename-reserved-regex-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106", - "sha512": "85c14ac941b9ef2586033bb508cb7f74fcd866ebfe8c02544fce5b2fc9ab5ef35eea15a3eb210711ce0475c82203a677a22d7ff705c97593d7176759360c203a", - "dest-filename": "filenamify-4.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7", - "sha1": "d544811d428f98eb06a63dc402d2403c328c38f7", - "dest-filename": "fill-range-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d", - "sha512": "68059c5b9eeec5536b419a855e3213a56dec2144261c61b7a926fd9946a1f4c80c0b835e5a134e94d8d7118ab71e3440bcbe9aad4be2646189b0183acf4cec58", - "dest-filename": "finalhandler-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b", - "sha512": "c17655e5e985123aeb89d220103d753a850a2f18988c072aa2dfcd25d0243a1949faf1b3c213807dc1b9397d633fe4b43dc8c49fc6dd309bfe8368f04373a78a", - "dest-filename": "find-cache-dir-3.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7", - "sha1": "45d1b7e506c717ddd482775a2b77920a3c0c57a7", - "dest-filename": "find-up-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73", - "sha512": "d720fa4662c8d5705fc6e82f391c25724e9fef9b582fe891d23ab0b0eacec4c672198a94b83849d25e005dd3b5897fc54ecf5c040304935816484c759126f296", - "dest-filename": "find-up-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19", - "sha512": "3e93b001d43f6255d0daf8fc6b787c222a43b98462df071e550406616c4d20d71cab8d009f0ec196c11708c6edd59b7e38b03a16af6cb88a48583d0eb2721297", - "dest-filename": "find-up-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1", - "sha512": "61b7df6ab85c89c1213ab9b80adaf074a05d0aecf9efa44b761243b087ef36dc54ba17517add6a65cb0c8ea6de3ed02c78a7409c3c8cfc8c976eeecf44f44b62", - "dest-filename": "findup-sync-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/flora-colossus/-/flora-colossus-1.0.1.tgz#aba198425a8185341e64f9d2a6a96fd9a3cbdb93", - "sha512": "77ef676bbb7d1721fc8012683434a2dbc984e0d8105461afc50e1a1ed1517ad8f28794978eebacf95e4465ac4598575755e9923abc7496c80497f64c8e739624", - "dest-filename": "flora-colossus-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685", - "sha512": "fa16f1a0b6c531b44a0f0a215fc1a44dab5a1aa3ba25bee31b0a40970832d9b233db95ed466eca13324cefa4755a2353e52c19917e18ef94b0068964a6613b89", - "dest-filename": "follow-redirects-1.14.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80", - "sha1": "81068d295a8142ec0ac726c6e2200c30fb6d5e80", - "dest-filename": "for-in-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452", - "sha512": "1131249521a2e6dd10319ba25e803f43abdc9f170b40fe6f76e812a6e0328ba4951a2d9c94f3e9fb180486e31a1c2fb31a09f7d4a776df95b7e5fec7ca491ac3", - "dest-filename": "form-data-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811", - "sha512": "6ee446d1fa41b511d24c238049eea10f6e7cb44b9b16844b6f864d03a3713151cdc3680e7301e8f70c9a6e5ccccce039cfdc40f4bd4a36393f36de8c4fd698a3", - "dest-filename": "forwarded-0.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19", - "sha1": "4290fad27f13e89be7f33799c6bc5a0abfff0d19", - "dest-filename": "fragment-cache-0.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7", - "sha1": "3d8cadd90d976569fa835ab1f8e4b23a105605a7", - "dest-filename": "fresh-0.5.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe", - "sha1": "83c60afc58b9c56997007ed1a768b3ab303a44fe", - "dest-filename": "from-0.1.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1", - "sha512": "0b9a306f5e2ef5e2708b328675c85c0d441e16d9521c7b61064f296d7f557353c566b2e899bb9d8c39cd9ecf3c698b250b217a218e52530dd1a33eb14a170421", - "dest-filename": "fs-extra-10.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94", - "sha512": "abaadb743775a369809d0ade3bb6000c8c5ffd6871e001c18917fa77efdc553f21e38b2cfa51e0c5fd457a672a0e742df57ddcb7831c1ebf893069584ac2bb0a", - "dest-filename": "fs-extra-4.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9", - "sha512": "6090da0896449c199c6f0d777ef74033d03034e2703b3ac4e29a8ca81ab99c5884a9752a1f094ae01fb7a54c3a24dbdf48fb57d39c451ed632ff59e2d357860b", - "dest-filename": "fs-extra-7.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0", - "sha512": "ca1950800ea69ce25428eb11505b2025d402be42a1733f2d9591b91c141f45e619cb8e8ec0b718f9989ad26b5d1ec3a8f72fe13fe0b130dd1353d431a0eb46e2", - "dest-filename": "fs-extra-8.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d", - "sha512": "85c8376667a94b7d3fec1485a91be8a370ce310bbb223ab13b99c20edfb333d5d68dbdf75a0ef388d4fe42fa9bb9cdfe816a733b4d89b9b5729361b866fa3539", - "dest-filename": "fs-extra-9.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb", - "sha512": "57f26038b1424be47a55cab4b250ae69e58474d0b7a2e0e524c348b1a707d95b402e2bbd995e0b3eb1dce5c0e5f24e5ac3a27c8f08165a9893a39458866233be", - "dest-filename": "fs-minipass-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9", - "sha1": "b47df53493ef911df75731e70a9ded0189db40c9", - "dest-filename": "fs-write-stream-atomic-1.0.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f", - "sha1": "1504ad2523158caa40db4a2787cb01411994ea4f", - "dest-filename": "fs.realpath-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38", - "sha512": "a166f567a9a41c8b242f3109fd7597d2cae4a644d0eef6a8a4c424c9a108a2ad1f9ad155c4eb616fc702c5e4fea77ca74dd924fd16706e01b86eb47905e5840b", - "dest-filename": "fsevents-1.2.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d", - "sha512": "c88a2f033317e3db05f18979f1f482589e6cbd22ee6a26cfc5740914b98139b4ee0abd0c7f52a23e8a4633d3621638980426df69ad8587a6eb790e803554c8d0", - "dest-filename": "function-bind-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/galactus/-/galactus-0.2.1.tgz#cbed2d20a40c1f5679a35908e2b9415733e78db9", - "sha1": "cbed2d20a40c1f5679a35908e2b9415733e78db9", - "dest-filename": "galactus-0.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0", - "sha512": "de137b35ab2462f3032d0639e609d6dcd43e99eb0401ea53aa583e5446e3ef3cea10c055361cdc19861ea85a3f4e5633e9e42215ca751dcb0264efa71a04bcce", - "dest-filename": "gensync-1.0.0-beta.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e", - "sha512": "0f214fdc133fdd81d340e0942ffc343991d1d25a4a786af1a2d70759ca8d11d9e5b6a1705d57e110143de1e228df801f429a34ac6922e1cc8889fb58d3a87616", - "dest-filename": "get-caller-file-2.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6", - "sha512": "91666b9d5338d900a2100d888356c6f338e820c3a0c56c1808478d77063a4effdc392786a5ca17e295c77ca53134a56802b9eb12bd9ef6cae7031c4622b692f5", - "dest-filename": "get-intrinsic-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-package-info/-/get-package-info-1.0.0.tgz#6432796563e28113cd9474dbbd00052985a4999c", - "sha1": "6432796563e28113cd9474dbbd00052985a4999c", - "dest-filename": "get-package-info-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193", - "sha512": "83f4356934833b11697215c2e22f195afc40d659cfab1fc91ea729230d3f2d7f53f31fc605b8ba62794de6785a2881644fca05b2c7142a00c96317f07d2e90b1", - "dest-filename": "get-port-5.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5", - "sha512": "18c6ade04279d7ad64232d877af2e5af896e363060be68f8d7729a400ee3b7857c078443b1fa4793b590f4656a7d8cb2c7c392fcbeba2a8c7eac944d9252caef", - "dest-filename": "get-stream-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3", - "sha512": "9c117e175ac06550aefe9eeb8f3800f986f895f617ae997b6ba56626b53cc05f48d422af3ff4303cd6479ce9706d3918e9dbed148cc5312c905db2e84d03d1a4", - "dest-filename": "get-stream-5.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6", - "sha512": "d8499d1f562f210899a65b4236092e8949f2ba4cf133f47a343257df529edc11b536ae5bd12d8f857e7d50a8bdbd9a4f0d055daa7fb521c680c27cd34f9bc28f", - "dest-filename": "get-symbol-description-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28", - "sha1": "dc15ca1c672387ca76bd37ac0a395ba2042a2c28", - "dest-filename": "get-value-2.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae", - "sha1": "9e6af6299d8d3bd2bd40430832bd113df906c5ae", - "dest-filename": "glob-parent-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e", - "sha512": "9645f51c95f0c8c729af0ff961465cdacec3ae90221c1db5fd5f84d6b1d4ad5368924bc1e9ba8ccd3d157d5ebff3a64d69bb75935e18388693ee70ef397dc88b", - "dest-filename": "glob-to-regexp-0.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023", - "sha512": "9662dfea0b72acfabcb538d29ab3bde3005e41b151dc76cb1dbbb20faf70bb2424226a76856a8c181e3b397eb914190f7df3bae3520ff6359ad73e22bea1b6e9", - "dest-filename": "glob-7.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6", - "sha512": "3d3e9745e27e0f4ec9bc6a3140c913eaa8e2fe354d7d7fe1dfae171d9396791cf2eb8b1216bfb1279397ecb2376f830f43374be07f18f0cd31ccfa6c54cc00f1", - "dest-filename": "global-agent-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686", - "sha512": "bfc868d834b94620a37ed8f59c3f4d9a77da3b34ddb9ded146755df6414d3a3a996c84a5c790d0f8ead3932c20774748b7ba050af29eb59487a0770fdec0dd88", - "dest-filename": "global-dirs-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea", - "sha512": "b0ace91247f5d46a4e16ec346738f39ade01e146708ce706ef9ecf3efadf87170b15bab4c29b20a4eab1a71b71162086e03b46f7733a5d155b176a0675ebfb6e", - "dest-filename": "global-modules-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780", - "sha512": "3466df989069f71f08c722527753fea2d60af2fa27a0969cb4ea20ad57c5448004635ba48a5f1148a0f3d98a3bc21d688a1979d65febe96e1ea6478a247a8bf0", - "dest-filename": "global-modules-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe", - "sha1": "dbf743c6c14992593c655568cb66ed32c0122ebe", - "dest-filename": "global-prefix-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97", - "sha512": "6b00a89c9495087546343eb1ded98c68a710bf05cb8637649a89b2d96f86a1aba2f183e06205c965ec218377d60be0e57eaa90b9683c030aa31930f69c03d55a", - "dest-filename": "global-prefix-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f", - "sha512": "e2cf83c9c896055d1e2b5e3cc2a5f17265406c554faad737b04b5413f19341fb94f34af248b70c8549872921c8eff2c38fcab4803608d6522145107b89e440aa", - "dest-filename": "global-tunnel-ng-2.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e", - "sha512": "58e069fc410652222c252a7bc1cbffcba30efa557d5289dc5aac6e15f9bc781c3358d8327c177a1b3f8878a43d8c29b28681fdf60d793374fe41a5471638b354", - "dest-filename": "globals-11.12.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b", - "sha512": "6509d214ed656bc3fb6ae20e4040a79b4b12ba831e692ab4104757301145d9024ee2e35cc1bca14a01b732bb9635b153a822e6c55c063a5ecb67d9004af1dd79", - "dest-filename": "globalthis-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c", - "sha1": "f5a6d70e8395e21c858fb0489d64df02424d506c", - "dest-filename": "globby-6.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770", - "sha512": "ee0b50e4a88f87546d192f7f25bbf5a1f0e9045baae368327c489bf9e8da44126e8ffded405791e7e830e7b7b88a9694f1cfeb0a3bd7e9f910cf69720e51803a", - "dest-filename": "got-11.8.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85", - "sha512": "47b796a6d5ee198c708a3b34795fafde8ebe5c7d48a952bc74938479c41f4e6927730f4057875cc3f0e1c62f0c765a8fb61c71a59ca2ccccf283c453984b06f9", - "dest-filename": "got-9.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96", - "sha512": "36d371a947178295b688cadfa927d1ef71a5b77f4af812f05ac3ecf78c91eb7bf8e53d166de8fb79198be5c59fc0482a5e79a3429df36894ec85d456fea0b665", - "dest-filename": "graceful-fs-4.2.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725", - "sha1": "4cafad76bc62f02fa039b2f94e9a3dd3a391a725", - "dest-filename": "graceful-readlink-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e", - "sha512": "f509f8c81c5e971a21d8ec3ada73fe29afe4327397462f015e745a5307b32cd86a7a59cde3dc4acf817f74f3fc3982f12f1aba243b596f68bd5f39d441b34f4e", - "dest-filename": "handle-thing-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113", - "sha512": "2d2052d8b8db3414dfeb6f3b2446c4cef2607ed905e6a164982a3d8434690332a150e949fa1c7c75de144acd344a0b14370738eb5ec9f648b962d10294cd9f7c", - "dest-filename": "has-bigints-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd", - "sha1": "b5d454dc2199ae225699f3467e5a07f3b955bafd", - "dest-filename": "has-flag-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b", - "sha512": "1329094ff4352a34d672da698080207d23b4b4a56e6548e180caf5ee4a93ba6325e807efdc421295e53ba99533a170c54c01d30c2e0d3a81bf67153712f94c3d", - "dest-filename": "has-flag-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423", - "sha512": "7215daefdacbfd40b62a55f5ee3a37bd11b3d1acda584c79b46a99839a4edcd532109541d7b74caee425cc208e7d4bc496084a726e75f78f81091be2d91bff1b", - "dest-filename": "has-symbols-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25", - "sha512": "9058dc48d867946575932a0693b3972926b01f924e6ff2f351ce70f41d3684e4ced1d7c54636c740abe0d5de9c7f71db7949ad53d55b6d5deacd9d937a1f7b59", - "dest-filename": "has-tostringtag-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f", - "sha1": "7b1f58bada62ca827ec0a2078025654845995e1f", - "dest-filename": "has-value-0.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177", - "sha1": "18b281da585b1c5c51def24c930ed29a0be6b177", - "dest-filename": "has-value-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771", - "sha1": "6d61de95d91dfca9b9a02089ad384bff8f62b771", - "dest-filename": "has-values-0.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f", - "sha1": "95b0b63fec2146619a6fe57fe75628d5a39efe4f", - "dest-filename": "has-values-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77", - "sha512": "52a051aa2e23bbb4fe4ea18d76a00ed0f692546b0318950142f93d79458d191635085183cd884b5a833b25011e9a796f55cbff60499cdb0356f010b6e049d4b3", - "dest-filename": "has-yarn-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796", - "sha512": "7f676f3b4554e8e7a3ed1916246ade8636f33008c5a79fd528fa79b53a56215e091c764ad7f0716c546d7ffb220364964ded3d71a0e656d618cd61086c14b8cf", - "dest-filename": "has-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f", - "sha512": "17fd439d418fa29391662d278be0afac28074391721001d12d2029b9858c9ab6d2c28376327ffb93e1a5dfc8099d1ef2c83664e962d7c221a877524e58d0ca1b", - "dest-filename": "he-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/hexy/-/hexy-0.2.11.tgz#9939c25cb6f86a91302f22b8a8a72573518e25b4", - "sha512": "722aba845b121bf069b760e6ad926dbfee7ace93dd9eaf8d4388a3105aef78a374646d66865fcb753d4d419f6c7bab72d5f002708e1de2f62a0bdbfc118a47d8", - "dest-filename": "hexy-0.2.11.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8", - "sha512": "7929a6584e5b6532b6368bb8834008df367daecc29ec644aa0a5d2d412d492f3ef88eaace184cdd5d8d022aad7cbd939804b5d2cfcbce898d1c2c34cf6d9c370", - "dest-filename": "homedir-polyfill-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9", - "sha512": "9b120301bf4bb26e83a0e27bc47fb9f97e32d4b53fe078b9d0bf42e6c22cc0adc9cd42d2e1bc24d45be374182f611e1bcd3e2db944220b5e451367f91db2ef63", - "dest-filename": "hosted-git-info-2.8.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224", - "sha512": "9320ae10e5a326a66e0db447ccbf15f77373421c0807bd681564b2cd5a3e28f648fa99d03cfc6e71d92b399be42d19eb7f9511b1033e209d3d0f0dbd71100b20", - "dest-filename": "hosted-git-info-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2", - "sha1": "87774c0949e513f42e84575b3c45681fade2a0b2", - "dest-filename": "hpack.js-2.1.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc", - "sha512": "f27c6370171df30a2f6de2b1ee1df04e38b87bafab85a56e3cda4cab05a09c787e37d4e8aac0ace97ced59104f43e52dceca0c01d299b5410da15cd4fc432d64", - "dest-filename": "html-entities-1.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/html-loader/-/html-loader-1.3.2.tgz#5a72ebba420d337083497c9aba7866c9e1aee340", - "sha512": "0c4914c12774b228cae4f1779115aca588b9e973fb6d3364ca0e58592cc17636920e6bc2b9f7a9e5ce15a5bdcf05fea550bd183ed2f005fcbd7cbd2de6104018", - "dest-filename": "html-loader-1.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054", - "sha512": "64faf930d39baa757f4fd6a4b213ca6d58323aa2e6cbe071a3b8ee2827d37e78cd9e24c031dcb8873db5610aa8a1f301243da475111aa8f3dd4e1a11efc4e0c6", - "dest-filename": "html-minifier-terser-5.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12", - "sha512": "ab9a187738ca5083d05633a8b2382f08740ebfd12db7d098607960bc97971b4a90bdd4a88e706ae2f01d401c27d7ec86bde0301c2a1efeb311f3aa335f7f9cd8", - "dest-filename": "html-webpack-plugin-4.5.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78", - "sha512": "e330ead5ad73844e2042ca3f7392cfd4eb6b8584e7717352a6f258b56241b570044cf94c7e2dc814d8c6b906d82ee558e1947440ca9156fa383ddcbd28bc8ff1", - "dest-filename": "htmlparser2-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7", - "sha512": "832c8f93aae0a272c51031a879181035a114bdd27892d4e699487f876b7bb3e33ca0fa483f180d00259afba112479ee45ecb70a8f882badd15f0d469730814ec", - "dest-filename": "htmlparser2-6.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390", - "sha512": "71aacf92571487b44e5912bb0afdbb44fb5d858854b1e95afee7b9fe32b38de815bd70ea33620b13d4360469fd259261d60f3b729e7ab2efc58104b37164bc71", - "dest-filename": "http-cache-semantics-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87", - "sha1": "fa7168944ab9a519d337cb0bec7284dc3e723d87", - "dest-filename": "http-deceiver-1.2.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d", - "sha1": "8b55680bb4be283a0b5bf4ea2e38580be1d9320d", - "dest-filename": "http-errors-1.6.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c", - "sha512": "2a993d4a6ecd988f911e19e3e8e2160c8d5de9f228140b45b7d44b693311960ffcc38f63b804adb2b060a740e9e0e7717556d121e2a1b4252fa22fd1b8084ee2", - "dest-filename": "http-errors-1.8.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5", - "sha512": "c7e2551243b63e833caaaa5b3db38bddca873f07ab7a9ecec332bb032fac3108cacda282a96be3a179b9b6a30ff6d5d65939d3cc08c885783e27df5762e3e13c", - "dest-filename": "http-parser-js-0.5.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a", - "sha512": "c876138163103bc56fc0d4b6d9e2cb968024bee9e0b0a74a4cb3bc00995fb5820a35f26bdc62b7ccad1909fcc30c6501b6d74673cc45cb59828adbcd290b42dd", - "dest-filename": "http-proxy-middleware-0.19.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549", - "sha512": "ee6cffef6d406e72702156e7692bf50b3dc09b464b4ff501c240bdd95971857bff93f04141f3367d712540d0b6ec1546af4bb0529a6560f40cf4b9da04c47935", - "dest-filename": "http-proxy-1.18.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d", - "sha512": "57edb7b0332bd765a7cfb893703789af73ba008c659ef4ff6e66800003ff5dd6b7e42f74a7de7df69d05d5e1d1fcdd4a20b592a1654088e3058c105769748cc6", - "dest-filename": "http2-wrapper-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2", - "sha512": "124626e4170a50689dbb1cd2b77129a64a3e3e2356344a5ae324a4f6f4c2eb00ec4095bdac749af94846349a11629edbcfa1edd5e69121ae90689a8ee6b0856c", - "dest-filename": "https-proxy-agent-5.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz#31065e6ab2c9272154c8b0821151e2c88f1b002a", - "sha512": "4f5d2abe4c34cf3e309e6e7ad253848343e8bd5a945ee3858611c0922c70f3fb32732ed326deeffd1ae410a1109c0c36be23d226eea202412bc67cd1d20f0fa5", - "dest-filename": "iconv-corefoundation-1.1.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b", - "sha512": "bf73179d901cbe7cb091350466898801cb657bb4575de79d391df5c3097b565ca85cee108bd6abbd27a73505a77b54dc4708422f51f02c8db56c4a9da63f3fac", - "dest-filename": "iconv-lite-0.4.24.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501", - "sha512": "e1f0a4efdc2c84c773329dab1f4eaa5ab244e22a25a8b842507f8e8ae22053ef91074fbde0d9432fcd5ab4eec65f9e6e50ab9ea34b711cdb6f13223a0fb59d33", - "dest-filename": "iconv-lite-0.6.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467", - "sha512": "e1a16aef0bd6c8c1ca831b07f1042d1a9bdb01209ff9e337c0f44b23a47e3200274c267a49362c46fb6d2ef4562b435f89fe69885dfde12b771de2436a58c63c", - "dest-filename": "icss-utils-4.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352", - "sha512": "75ccaa843bd7d42e3a95765c56a0a92be16d31141574830debf0dfe63b36ce8b94b2a1bb23ab05c62b480beeca60adbd29d5ce2c776ef732f8b059e85509ea68", - "dest-filename": "ieee754-1.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501", - "sha1": "c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501", - "dest-filename": "iferr-0.1.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43", - "sha1": "05698e3d45c88e8d7e9d92cb0584e77f096f3e43", - "dest-filename": "import-lazy-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d", - "sha512": "6fab34e26dcefacdc21926ea0c8c8fe11e9a03001e62556af7e59459ea7a8876bc11345ff727a2d54e3c0b93267c9995f4088b61804a3ccabf5befd646942609", - "dest-filename": "import-local-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea", - "sha1": "9218b9b2b928a238b13dc4fb6b6d576f231453ea", - "dest-filename": "imurmurhash-0.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251", - "sha512": "11d0c366ee00d8ec882bb2ebff6cc6fb0e6399bba4d435419c4c11110bc1ceca412640846d16bc1b153596085871a1890a745689b8c35e5abbefd5f5ff2e71c2", - "dest-filename": "indent-string-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467", - "sha512": "202963f97cfde3e77b8ab1f9a91c9f2689ce75f4f3b836a27c4e993d67f1d0dd3efc04d909bb933eada9ac5979dbabab91077dd16c942888750df050da1333f4", - "dest-filename": "infer-owner-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9", - "sha1": "49bd6331d7d02d0c09bc910a1075ba8165b56df9", - "dest-filename": "inflight-1.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de", - "sha1": "633c2c83e3da42a502f52466022480f4208261de", - "dest-filename": "inherits-2.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c", - "sha512": "93fbc6697e3f6256b75b3c8c0af4d039761e207bea38ab67a8176ecd31e9ce9419cc0b2428c859d8af849c189233dcc64a820578ca572b16b8758799210a9ec1", - "dest-filename": "inherits-2.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c", - "sha512": "255ff2ba0576bb35b988c4528990320ed41dfa7c6d5278de2edd1a70d770f7c90a2ebbee455c81f34b6c444384ef2bc65606a5859e913570a61079142812b17b", - "dest-filename": "ini-1.3.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5", - "sha512": "ecf9c5e283770af645db7003840e7045a60442927cab281291bb535d605e5d65e61154572bed484dc8875b01e1b23bf54e65b432069c22fea1122e695f935074", - "dest-filename": "ini-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907", - "sha512": "4b5cc1a350facdcb32b82e8f326639fb9e583082d0f5abfc968b4cc78e3b06ae92020a3fb032bacbab942a6b98856ede69c9c88457ec3e608d61d0f3b279c30a", - "dest-filename": "internal-ip-4.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c", - "sha512": "3b40c1d490bfb0fc9997b708a3bf27e5d47b7944b0c2960f8974614f337165500c52e07cbe59d11722f176b553a24b3a5cf2d59c57dbcda55de562e386083ebc", - "dest-filename": "internal-slot-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e", - "sha512": "6a013841f0762e4a7db880a7ec102aa2c730e1264ff644c4da1c62148de304f99725f76a89a8536d4b8a1ac3283761ada8bf40c61622a00715be0b1bd47bd16c", - "dest-filename": "interpret-1.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9", - "sha1": "fa78bf5d2e6913c911ce9f819ee5146bb6d844e9", - "dest-filename": "ip-regex-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a", - "sha1": "bdded70114290828c0a039e72ef25f5aaec4354a", - "dest-filename": "ip-1.1.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3", - "sha512": "d0a23feb4ef1a31493a07ec68cdd457d26cba14d3e6ed4e2723b1049642587f859ca437c2a998c7fbb98c0f5b747e6a467a47fc35f199574870585e26143cede", - "dest-filename": "ipaddr.js-1.9.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698", - "sha512": "a2998d217eee1674bde8db4f9a1590810c7afcd60582c51760c96571fcf058a50cc1fa3c924bb54ef13a86435c1fe435b6ce5c315aec63b8f46f15d00dc8aef5", - "dest-filename": "is-absolute-url-3.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6", - "sha1": "a9e12cb3ae8d876727eeef3843f8a0897b5c98d6", - "dest-filename": "is-accessor-descriptor-0.1.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656", - "sha512": "9b98671d391c56c3dfab1dc02a5cadb483dbec9f97ca41ef24fd81f5b6438e584b22812ae17a0aeb8560edba199555982ba2d463de1d60f104ecb87466464a71", - "dest-filename": "is-accessor-descriptor-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b", - "sha512": "f10ec40118f31272a9b7f3c20fb7b5720512d1ae97f2ee6d75288ca978688ce76857d4ec32c88efbd54b0b9bc098ef0deff1a65e7ef28d1f2a9c0e9b5401337c", - "dest-filename": "is-arguments-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d", - "sha1": "77c99840527aa8ecb1a8ba697b80645a7a926a9d", - "dest-filename": "is-arrayish-0.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3", - "sha512": "cc1f42aee31a9a3ca6f358b6259dd4327e783ca1ac433b097a8eb1bcddc7249e0202c40d07a891bada764e8efb39f08dba8c6ca6c221cda3e83b5cf20848453a", - "dest-filename": "is-bigint-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898", - "sha1": "75f16642b480f187a711c814161fd3a4a7655898", - "dest-filename": "is-binary-path-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719", - "sha512": "80361a2872669e3e1a5b1ca3e981f25d5a5d41ac2d54b1d4e5c6fe7b3b4f19ccdfe9c8ee4ddc2f7b964811f817a87e1ee7b027d43d4029ff02677918ad046a60", - "dest-filename": "is-boolean-object-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be", - "sha512": "35c7402f0a579139b966fbdb93ba303944af56f04a0e028fe7f7b07d71339e64057ece194666a739e2814e34558e46b7405a0de9727ef45dd44aa7c7a93694e7", - "dest-filename": "is-buffer-1.1.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945", - "sha512": "9ecbb0b7165f317ebb3abca5f4b090faea670b4674060a709eda52f3d9b51ff4cb174ccd7f37cb315ffd59affa319b23d1a72912300ed0a175c53e9974b97de7", - "dest-filename": "is-callable-1.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c", - "sha512": "61f253eeb929401d2ea5db1d1cb196aef84125f71fccd35ac180cd232417273d0856219fef93bc1013ca49dbf0dab17e2c60ac5f8159f2d72bddbd7d2dc66ae3", - "dest-filename": "is-ci-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867", - "sha512": "658bc282b79fc2aa10eb24f26146d0bbae07b084d9dcd7ca5f597368461d9130dc7cacf3088ff0b6145160a91d8c72855603625ca00a9bae59a35a64d9ab3f41", - "dest-filename": "is-ci-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211", - "sha512": "49d34252cdbce21af8d2115314fea5d087d9fd14ab317177aa0a111dddffefdba7513beb14efc9a17c241a6fb927f39edc4fdbe46b271b7df4b94360469bb53c", - "dest-filename": "is-core-module-2.8.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56", - "sha1": "0b5ee648388e2c860282e793f1856fec3f301b56", - "dest-filename": "is-data-descriptor-0.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7", - "sha512": "8db457cb5166b40a028d0915988558c2ebaa0c551b68e7838e679dd6d3863ebb0c86d240e2b0fdb64800d05d6a2778111515dc1d856475e68fe74439ac4fe32d", - "dest-filename": "is-data-descriptor-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f", - "sha512": "f5841a4b1b00892c1cbd2df7301937c130959d62be1e117c5594768d1c5e84cd7a41c54e747a8f9f854f1e644ae254abdfc9fd26b8aeac89cb70ff74c6c60d7d", - "dest-filename": "is-date-object-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca", - "sha512": "6af0d8af4481dc3c0ef73b0ca2fd20282112158a829c4e21abfe33dd375496e904cb9b7d0b4611abb1cbaec379d8d01ca9729a7a97820f49fe0746ab9d51b71e", - "dest-filename": "is-descriptor-0.1.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec", - "sha512": "d9e8ace56a90195ee97a8a03c8b98d10f52ba6cf7e4975f973da4bdf1101fb87bd1e71ae0daee607b907c47c3809ba92f64d53da1387de688bf27f16b62615b6", - "dest-filename": "is-descriptor-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa", - "sha512": "17e8b604ab05ac7eba89a505734c280fcb0bcbc81eb64c13c2d3818efb39e82c780a024378a41ea9fcfcc0062249bf093a9ad68471f9a7becf6e6602bef52e5d", - "dest-filename": "is-docker-2.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89", - "sha1": "62b110e289a471418e3ec36a617d472e301dfc89", - "dest-filename": "is-extendable-0.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4", - "sha512": "6ab9d73314f5861a0aa3d9352d976694dc897430dfcb6bf47d78c5966a24e3e8bcba5ffa5a56d581ef5b84cef83a934f40f306513a03b73f8a5dad4f9de27138", - "dest-filename": "is-extendable-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2", - "sha1": "a88c02535791f02ed37c76a1b9ea9773c833f8c2", - "dest-filename": "is-extglob-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f", - "sha1": "a3b30a5c4f199183167aaab93beefae3ddfb654f", - "dest-filename": "is-fullwidth-code-point-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d", - "sha512": "cf29a6e7ebbeb02b125b20fda8d69e8d5dc316f84229c94a762cd868952e1c0f3744b8dbee74ae1a775d0871afd2193e298ec130096c59e2b851e83a115e9742", - "dest-filename": "is-fullwidth-code-point-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a", - "sha1": "7ba5ae24217804ac70707b96922567486cc3e84a", - "dest-filename": "is-glob-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084", - "sha512": "c5e9526b21c7dfa66013b6568658bba56df884d6cd97c3a3bf92959a4243e2105d0f7b61f137e4f6f61ab0b33e99758e6611648197f184b4a7af046be1e9524a", - "dest-filename": "is-glob-4.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520", - "sha512": "8b01aa3b7276d5a692902ee35a71cffdd89f6b3c12ed215e22ac6feb012d2d4f18e4a9731538f2a9c4884f477cb38f9d0e12b2b6c93d3c96760644b9799c1045", - "dest-filename": "is-installed-globally-0.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150", - "sha512": "76a26f6ab2dac17b056cd0de256ef3033f08b49f5c776f18b9fbae1738741bca4d1e324c9d8d3c0efeec617dae17952940ec2278078e13111801659fbbb65950", - "dest-filename": "is-negative-zero-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8", - "sha512": "596feb40b39acd4abe493fdb080541a7fda83044562ec47b3ab2b2b74e7674d0e4e031dc0c4d3fed04972139668be541715d770df21bcac1b7b59266e517dd04", - "dest-filename": "is-npm-5.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0", - "sha512": "6c454eaa245cbe8df33b5f86da554ccbe8249049bd621edc0cc46eb0a2aee5924a3d46122702024ca66b34a1c0d846d23f44eed3ee81fde9ac60d1d9ca7e8af2", - "dest-filename": "is-number-object-1.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195", - "sha1": "24fd6201a4782cf50561c810276afc7d12d71195", - "dest-filename": "is-number-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982", - "sha512": "76ba831b771b733c7110946839770e8ed769d49fe5ca9d66367d316b39d1b3cfa6b8186041cae76eca68c795f97cec341e73276df0f3be710c12da83109128f3", - "dest-filename": "is-obj-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb", - "sha512": "c3de366d372287c7dd24f266407173912efa3443fc2b3cef9b0f76717b1acdbf229edc0ba8f89b3cf7577f800d74a577ad832eb90606216b6fcfd262941dcd15", - "dest-filename": "is-path-cwd-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb", - "sha512": "acda1c5c7822a4efabbe73fa764df3236d11a4eb6b00cfe4cdb076e7c530e415abdd3a578bceb5cb38e8d7a0e7e21528c74ee2c3903278c2c75acba3923cef45", - "dest-filename": "is-path-in-cwd-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2", - "sha512": "c22ca14f37c35acbf0016e77381585e73baf68e1a567a3f063101b3d50e1a66fa0334f712901a306affcb98375d9a0ef3319c09eadddc53ca84a844d9a0e5816", - "dest-filename": "is-path-inside-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283", - "sha512": "15de200016fec9c18098aa2ef1e31fb42ba94a2af9951c6a7f8683fef774703daa7381cbd3b3a309eb8732bf11a380a831a782283074fc40813955a34f052f3d", - "dest-filename": "is-path-inside-3.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e", - "sha1": "71a50c8429dfca773c92a390a4a03b39fcd51d3e", - "dest-filename": "is-plain-obj-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677", - "sha512": "8793e98179168ad737f0104c61ac1360c5891c564956706ab85139ef11698c1f29245885ea067e6d4f96c88ff2a9788547999d2ec81835a3def2e6a8e94bfd3a", - "dest-filename": "is-plain-object-2.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958", - "sha512": "92f45dc43b31663873517d3b6672f27734b54d4fd32654d41c763860b2fcededfba14038f437e42ea832f958c5a1ca30cb6f5c2af7128aefa422fef6f234d356", - "dest-filename": "is-regex-1.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6", - "sha512": "214d0d9b2927619374ac285c2a144ed57f0b633e48b23fc5b2a87c3493927fe37f842393c32dbd177d8893b6be42ccc4eb721dbe6c1d4cf0dde9c679a60e1cc0", - "dest-filename": "is-shared-array-buffer-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44", - "sha1": "12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44", - "dest-filename": "is-stream-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd", - "sha512": "b44d945f38af8deea87cf5bb976ddc8c338c6b4f606fbc6502a1ba8c6e5e8fab8f577d939563f734a3e282d68678736ef5fa2171c458bc889931f38e9ce614b6", - "dest-filename": "is-string-1.0.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c", - "sha512": "0bf08f06a2969ef75cc6a200471c8e878bf551410e087a600dad16620a4a0c532ccdcacf71f7e0e6e8704a03c22c3d965b19aaea2b22b33f3bb734f4d6db8686", - "dest-filename": "is-symbol-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a", - "sha1": "e479c80858df0c1b11ddda6940f96011fcda4a9a", - "dest-filename": "is-typedarray-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2", - "sha512": "a9cb6cb8b666210d3ebd248c7e856fc857b6f86484be7999d9ecd3ba9d5206c7bdfadc0209e89a97a1048b735cd8a15c7fafaacf61413e78d7b24f3184a49a3d", - "dest-filename": "is-weakref-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d", - "sha512": "7972b55089ead9b3e68f25fa7b754723330ba1b73827de22e005a7f87a6adce5392a4ad10bde8e01c4773d127fa46bba9bc4d19c11cff5d917415b13fc239520", - "dest-filename": "is-windows-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d", - "sha1": "1f16e4aa22b04d1336b66188a66af3c600c3a66d", - "dest-filename": "is-wsl-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271", - "sha512": "7cacc0adad2b18951407018180d90766e4e865c9fe4ed5c7a5e0a09a430930c631d6c40361a092ca32414826b69c7d431a6eecde7d68067a21a154c168decbc3", - "dest-filename": "is-wsl-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232", - "sha512": "56349e6ff9479a4a3277caf23d520abce0a7e03d64a0ca98fafab28e351f737c722ad3f87583b1338e2c66b9ea412cd276cdf1c8ead44cb4c2f4b5425602e783", - "dest-filename": "is-yarn-global-0.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11", - "sha1": "bb935d48582cba168c06834957a54a3e07124f11", - "dest-filename": "isarray-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80", - "sha512": "f1c2412f9b53776392d1d3388f3d3bc107798347420aa2215313c81ad65f6b92fa85696f5793074c84f2fc3040b05f8e7b62d2d57de4ac1521370686516a56c7", - "dest-filename": "isbinaryfile-3.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf", - "sha512": "e7787a5c59e2abbed8756faca6846b79b8749a7993c513d395cb8802b3b9ee598c76ae2e04a14a69e4e39dbf76a185ab4a7fcb54bf8b4fe1daa76b45423f15fb", - "dest-filename": "isbinaryfile-4.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10", - "sha1": "e8fbf374dc556ff8947a10dcb0572d633f2cfa10", - "dest-filename": "isexe-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89", - "sha1": "f065561096a3f1da2ef46272f815c840d87e0c89", - "dest-filename": "isobject-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df", - "sha1": "4e431e92b11a9731636aa1f9c8d1ccbcfdab78df", - "dest-filename": "isobject-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b", - "sha512": "78ba4acab7c6de6cef184d83bbc5683db792911af2d3ddfeb723637586816c94bdbf5ee49c899818d5d009457480bc50b45f369b713c8916ffc1d49064ba2aec", - "dest-filename": "jake-10.8.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1", - "sha512": "fddb12994908cb910119fbff2238ea985c6b34052904445f1acd681d13b20fbcb18c6ff0fadd063890d7f0ed64df6c9299defe6b92219c9536a9015c2789f5bf", - "dest-filename": "jest-worker-25.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e", - "sha512": "80758917fe978b90931b9402bd13abe86726a48a8d6290c9c9cf00d61fc3c97a87d6d0fa4a74423347775399ac577d43d8b07f53e13433e5b8a32bca578e2837", - "dest-filename": "jest-worker-27.4.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499", - "sha512": "45d2547e5704ddc5332a232a420b02bb4e853eef5474824ed1b7986cf84737893a6a9809b627dca02b53f5b7313a9601b690f690233a49bce0e026aeb16fcf29", - "dest-filename": "js-tokens-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537", - "sha512": "a24307ece5d727b62b37d3a4dff497ae7bb8897f723a4fb6e67a97e22992da7a6ebd36039a8fd0119a2ac199186880e4de356f04e4ce20480485a2ceca7052f6", - "dest-filename": "js-yaml-3.14.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602", - "sha512": "c29c59b3d368c596891122462194f20c4698a65d0529203e141f5a262c9e98a84cc24c5083ade1e13d4a2605061e94ea3c33517269982ee82b46326506d5af44", - "dest-filename": "js-yaml-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jsbi/-/jsbi-2.0.5.tgz#82589011da87dc59b4b549d94dcef51a9155f6fe", - "sha512": "4f33bfeb61f179bdba40c6f8206948ff95fe40bafd52aa7514f930a76f8a388096f90faf4ae163eb573ca644fac009ece1670ae7a5fb0a64878497831963aac5", - "dest-filename": "jsbi-2.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d", - "sha1": "e7dee66e35d6fc16f710fe91d5cf69f70f08911d", - "dest-filename": "jsesc-0.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4", - "sha512": "398bbb5c4ce39024370b93ecdd0219b107cda6aa09c99640f7dc1df5a59dd39342b42e6958e91284ada690be875d047afc2cb695b35d3e5641a6e4075c4eb780", - "dest-filename": "jsesc-2.5.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898", - "sha1": "5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898", - "dest-filename": "json-buffer-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13", - "sha512": "e1b57905f4769aa7d04c99be579b4f3dd7fe669ba1888bd3b8007983c91cad7399a534ff430c15456072c17d68cebea512e3dd6c7c70689966f46ea6236b1f49", - "dest-filename": "json-buffer-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9", - "sha512": "9abab264a7d7e4484bee1bea715e961b5c988e78deb980f30e185c00052babc3e8f3934140124ff990d44fbe6a650f7c22452806a76413192e90e53b4ecdb0af", - "dest-filename": "json-parse-better-errors-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660", - "sha512": "c5b6c21f9742614e53f0b704861ba1ec727cf075ee5b7aac237634cce64529f6441dca5688753f271ce4eb6f41aec69bfe63221d0b62f7030ffbce3944f7b756", - "dest-filename": "json-schema-traverse-0.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2", - "sha512": "34cf3f3fd9f75e35e12199f594b86415a0024ce5114178d6855e0103f4673aff31be0aadaa9017f483b89914314b1d51968e2dab37aa6f4b0e96bb9a3b2dddba", - "dest-filename": "json-schema-traverse-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.3.tgz#23ff481b8b4eebcd2ca123b4fa0409e66469a2d9", - "sha512": "ec313c9a91befdf570f9d4e98dbc67c78ed368c9c37ce2358f07edf60d55c9b96d64276ec9140f24fbdcfb3cca63d58f1f184f59ccf216e61ae88f0cc38894e4", - "dest-filename": "json-schema-typed-7.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb", - "sha1": "1296a2d58fd45f19a0f6ce01d65701e2c735b6eb", - "dest-filename": "json-stringify-safe-5.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81", - "sha512": "73bffc99b52c2a28006cb903e41d35d012b80fd2d99bb035a4d22d904c2251946920deba7b1bbf7bb6105b2b06ba7f9344a689a7c3217a633e5647d6bf8d9a08", - "dest-filename": "json3-3.3.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe", - "sha512": "68a4b85908cf7a7471890b02f7730d7e3c7e9db1783c0758ce677fd49223f07633a9f6eef3a6de4ee3605c3ccf9275a4d27d2e0119727b0668e2cfbe112dfa3b", - "dest-filename": "json5-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3", - "sha512": "7fef1c95dbbb5ffcbb44026eacc10999da0a5c607f5f9e74c3636bded4db7b32fa470104fe231c9beb599d77a866d2ae3aae9fb7cf82ab3124ac8831d5f3e840", - "dest-filename": "json5-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jsonc/-/jsonc-2.0.0.tgz#9e2a25100d164a9bb864c57517563717fa882551", - "sha512": "076f356cb093d9344c41af80414418e4019ca9239704e29a6063f8c03ce803ff90b3051f37cb0e0de92d6cf12cf416aaecb18aba7e6341b345a73c06b9560a87", - "dest-filename": "jsonc-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb", - "sha1": "8771aae0799b64076b76640fca058f9c10e33ecb", - "dest-filename": "jsonfile-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae", - "sha512": "e5d8277563ab8984a6e5c9d86893616a52cd0ca3aa170c8307faebd44f59b067221af28fb3c476c5818269cb9fdf3e8ad58283cf5f367ddf9f637727de932a5d", - "dest-filename": "jsonfile-6.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1", - "sha512": "a41c5c0772c573c41581d820bd95b27b2b3e867acd5a0e0e719214ff55f9f64e6341d2c1942b1819141acf6df84aaa112d30a0307d347d8d314491fe17d3044d", - "dest-filename": "junk-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9", - "sha512": "f72909ff8e9237ff4a3ccfec89c87343b3af5f218360a19368394a306080960d942bc291cb88dbd1df2c15cfb44edd186274e1abc5f645980283be113f181c54", - "dest-filename": "keyv-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/keyv/-/keyv-4.0.5.tgz#bb12b467aba372fab2a44d4420c00d3c4ebd484c", - "sha512": "e77d699062ea57704c834783aaa2452344759a42b5366e7120fda633a91e3f93fc59f16d0a483620ec29953526946a1380883dc90619fe4762861cfcf571f7bc", - "dest-filename": "keyv-4.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892", - "sha512": "2f3aad2ca954c22ac453297f9e2722ad598d88fbd8b3b9799fcc0e3cfedfc8956950f92f0a75bfbee8971a9ca51949673c39c1ef7d75ac047302ddcc86cc298e", - "dest-filename": "killable-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64", - "sha1": "31ea21a734bab9bbb0f32466d893aea51e4a3c64", - "dest-filename": "kind-of-3.2.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57", - "sha1": "20813df3d712928b207378691a45066fae72dd57", - "dest-filename": "kind-of-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d", - "sha512": "346104ae71fa176bd4b970e1f8e95b70a5bbff039c7dd447699ed55ada82ced7c7ae2ffef982a63f9d4e7567863eea8239b6ba924d8e4dee5dd365664c1f343f", - "dest-filename": "kind-of-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd", - "sha512": "75c4b5ba5fbdb66783f794fec76f3f7a12e077d98435adcbb2f0d3b739b7bf20443bb44fa6dbc00feb78e165576948d305172ba45785942f160abb94478e7a87", - "dest-filename": "kind-of-6.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lastfm/-/lastfm-0.8.4.tgz#4dddf08297a6fa23f84d4827052a0d282fe99688", - "sha1": "4dddf08297a6fa23f84d4827052a0d282fe99688", - "dest-filename": "lastfm-0.8.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lastfmapi/-/lastfmapi-0.1.1.tgz#ce336dcf7cc81820c22dc40247c97b31133486fa", - "sha1": "ce336dcf7cc81820c22dc40247c97b31133486fa", - "dest-filename": "lastfmapi-0.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face", - "sha512": "c1e4feaf491391141d09d60236d90cc165d04cc12cc0aac50649b872440e315861aa120c235513da1323fb58a28088604999b98139ab45704da06520693635c4", - "dest-filename": "latest-version-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d", - "sha512": "d3f06718209fc943240697838168a16a720017d2666611c1814844ab3bdff9a7613462e83fa4da888e6817ca326f7238e4ff8f727aea8a149fd353349741b9f9", - "dest-filename": "lazy-val-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8", - "sha1": "7947e42149af80d696cbf797bcaabcfe1fe29ca8", - "dest-filename": "load-json-file-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384", - "sha512": "f76fa1bafc4cbd894ccccb748883ae91cc18045a64609769976c6c67b2eb95ac8eec4f123aff8925410ad7b07f74920700e2cc7e1d9d659fd8d7c5a0986b5837", - "dest-filename": "loader-runner-4.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613", - "sha512": "a87d1648c06d9ffa07bb08f2fcdb9c1206f1e5d6f1c67c6ea7db383d55c95031d905063eb3435603dac97f9dd1067419c5f721edeb94ba2ee1a6800fbc02d974", - "dest-filename": "loader-utils-1.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129", - "sha512": "4cce7b55e1e9b6fe7af5dfc62a1e9301877329b9700cd8ae98e7641677a38c3d17c131fcecaf74c373bb022251a9d4285f282f8b55504c94cb1a1265ed6a80ec", - "dest-filename": "loader-utils-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e", - "sha1": "2b568b265eec944c6d9c0de9c3dbbbca0354cd8e", - "dest-filename": "locate-path-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e", - "sha512": "ec03bbe3cc169c884da80b9ab72d995879101d148d7cf548b0f21fc043963b6d8099aa15ad66af94e70c4799f34cb358be9dfa5f6db4fe669a46cade7351bae4", - "dest-filename": "locate-path-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0", - "sha512": "b7b870f6923e5afbb03495f0939cd51e9ca122ace0daa4e592524e7f4995c4649b7b7169d9589e65c76e3588da2c3a32ea9f6e1a94041961bced6a4c2a536af2", - "dest-filename": "locate-path-5.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af", - "sha1": "82d79bff30a67c4005ffd5e2515300ad9ca4d7af", - "dest-filename": "lodash.debounce-4.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347", - "sha1": "64762c48618082518ac3df4ccf5d5886dae20347", - "dest-filename": "lodash.escaperegexp-4.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99", - "sha1": "2d177f652fa31e939b4438d5341499dfa3825e99", - "dest-filename": "lodash.get-4.4.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0", - "sha1": "415c4478f2bcc30120c22ce10ed3226f7d3e18e0", - "dest-filename": "lodash.isequal-4.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c", - "sha512": "bf690311ee7b95e713ba568322e3533f2dd1cb880b189e99d4edef13592b81764daec43e2c54c61d5c558dc5cfb35ecb85b65519e74026ff17675b6f8f916f4a", - "dest-filename": "lodash-4.17.21.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114", - "sha512": "1ba03f9c92d18163aebb074db80ea4a28bdf115d58a6aa801b8a5152515acf78e3d90359f0ce2f06a9d503e1c14e653f00c354b653ac3264a917a3723a3ced6c", - "dest-filename": "loglevel-1.8.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28", - "sha512": "5ec3fe2a14227f86e35f591bb928b248914d01e84dc602dbea13d1189f50b14afc6a31e4b9719dac79855135145e10f0557d91e5b63824d644c1b52232157e30", - "dest-filename": "long-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf", - "sha512": "972bb13c6aff59f86b95e9b608bfd472751cd7372a280226043cee918ed8e45ff242235d928ebe7d12debe5c351e03324b0edfeb5d54218e34f04b71452a0add", - "dest-filename": "loose-envify-1.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28", - "sha512": "edf9b797734017d59f37a5b724e99fe5daf0a55a97efc26da0627703a5b46ba66795d338d70d9f5790f8f74a6c2854e931db3c4c9b1efde1cb145b0d1c78c782", - "dest-filename": "lower-case-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f", - "sha512": "1b62e3eb5b570e754514e8bc55976cf92a108ed402ddd82890a7431b69939b5b71e26e743541c1399481c10407cb2d15d760342531b889c7d9407fb13f287c54", - "dest-filename": "lowercase-keys-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479", - "sha512": "b6a357ad2efca0c384ef734cc4ae0430b42c428c167fc8caa281fd83bc4f6af453ef4e91e9b91027a0d8d937bb42e91a66cba5c5adf4c10edb934a66e1788798", - "dest-filename": "lowercase-keys-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920", - "sha512": "2a9340450037230bfe8d3034bad51555bae1f8996baf516fd1ee7a186cc014e5cdedd93f16f89a0d6f0b1e62b9d8395c1f858fda7ea023cbcdd5a7ac045828f7", - "dest-filename": "lru-cache-5.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94", - "sha512": "268e9d274e029928eece7c09492de951e5a677f1f47df4e59175e0c198be7aad540a6a90c0287e78bb183980b063df758b615a878875044302c78a938466ec88", - "dest-filename": "lru-cache-6.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd", - "sha1": "b5c8351b9464cbd750335a79650a0ec0e56118dd", - "dest-filename": "lru_map-0.3.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f", - "sha512": "83715e3f6d0b3708402dbffa0b3e837781769e0cded23cfbb5bceb0f6c0057ea3d15e3477b8acbfb22b699dd09fdf8927f5b1ad400e15ea8b9fa857038cfde1b", - "dest-filename": "make-dir-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf", - "sha1": "c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf", - "dest-filename": "map-cache-0.2.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194", - "sha1": "e56aa94c4c8055a16404a0674b78f215f7c8e194", - "dest-filename": "map-stream-0.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f", - "sha1": "ecdca8f13144e660f1b5bd41f12f3479d98dfb8f", - "dest-filename": "map-visit-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca", - "sha512": "3a478368067f6d00b1785028ccce793ca70a534c8930f1a27cbc15e108238adbbee4ca007d240de25b0b25e5d9d5bf30d31fbf12675ae8c6605d2d63bec6a99e", - "dest-filename": "matcher-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748", - "sha1": "8710d7af0aa626f8fffa1ce00168545263255748", - "dest-filename": "media-typer-0.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561", - "sha512": "6a2b27ac33f818d7b4e9470a1675796df30d3c1530e23b0b19a5b059f9c7defd361a706e5d7d8c0959f945bad6a348f7a5ccd48a561b96aedf43b370dade572b", - "dest-filename": "media-typer-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552", - "sha1": "3a9a20b8462523e447cfbc7e8bb80ed667bfc552", - "dest-filename": "memory-fs-0.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c", - "sha512": "8c0d2b754e4aa10302d1eea9a68351b69a7abe316aebe358eebf21cb09c2ed5fb55e3fccb47c0621b07541a2bf76e9f28d6b5e2739a4a5dee8a1e5a0d744fb18", - "dest-filename": "memory-fs-0.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61", - "sha1": "b00aaa556dd8b44568150ec9d1b953f3f90cbb61", - "dest-filename": "merge-descriptors-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60", - "sha512": "69bbffa8e72e3df9375113df0f39995352ca9aec3c913fb49c81ef2ab2a016bc227e897f76859c740e19aac590f0436b14a91debb31fa68fcba2f6c852c6eddf", - "dest-filename": "merge-stream-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee", - "sha1": "5529a4d67654134edcc5266656835b0f851afcee", - "dest-filename": "methods-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23", - "sha512": "3168a4825f67f4cdf0f9ba6c6371def0bfb0f5e17ddf7f31465f0800ee6f8838b3c12cf3885132533a36c6bae5a01eb80036d37fcb80f2f46aaadb434ce99c72", - "dest-filename": "micromatch-3.1.10.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c", - "sha512": "e72f00e7a8e0ed7550c7699bbf596ee3d351e1da24467859613b4bf8a19f69adbbbaae294935e4c10905265e29911332345cff12d6034a48a2107c7717b50dea", - "dest-filename": "mime-db-1.51.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24", - "sha512": "e9c3faf765b0188b3d5d774e3b8fbe37eeea8eabf4aeac7156f2775473e1fd273d99565c40ff991a190a893bd631046bdad6c79093ff627ed8d27a5bdd906ce0", - "dest-filename": "mime-types-2.1.34.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1", - "sha512": "c74567f2ca48fb0b89d4ee92ee09db69083c3f187834d1dbeca4883661162a23c4e1128ea65be28e7f8d92662699180febc99cef48f611b793151b2bb306907a", - "dest-filename": "mime-1.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367", - "sha512": "5123e431e113df5ace3226abb013481d928b1a0bca73f2eb8e87c09c194eb6d7f96a346faa2440f10b1e9db728a1cb4ae9de93b3a6aa657040f976e42ad86242", - "dest-filename": "mime-2.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b", - "sha512": "3aa6ce939a0441e019f165d6c9d96ef47263cfd59574422f6a63027179aea946234e49c7fecaac5af850def830285451d47a63bcd04a437ee76c9818cc6a8672", - "dest-filename": "mimic-fn-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74", - "sha512": "62c6e2f6e616f611727eb4e1743110bb290de04cba06ec0f0f6929239112fe71530e7ffdf32c5834b64972050028f4ff99cacb2ca686cc947d615c49ac874049", - "dest-filename": "mimic-fn-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b", - "sha512": "8f911cb67907eda99f57fab91e09a86a5d60d901c5251ada3ad9b1d09a48aa4c6106123f9494a5d67329438e6155aaf03444cea161229a7759e102b4447c6ec5", - "dest-filename": "mimic-response-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9", - "sha512": "cf4c9623ee050ebaf0792f199ade048f91dd266932d79f8bd9ee96827dfe88ae5f5b36fa4f77e1345ab6f8c79345bd3ae1ce96af837fc2fd03cd04e33731cd19", - "dest-filename": "mimic-response-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e", - "sha512": "969dc6798ef281c80099521c44f05584891ff14b3b1598c0f882e96a5e38a8b752bb5d709a3290dddf64d7995f0fba4ee1eb2ef5e508016eea898201a69bf8d0", - "dest-filename": "mini-css-extract-plugin-0.9.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7", - "sha512": "52d25c003e3211a1ad8cf7b35ae3bdc02e27c149d51fff3f226df210740fe1bebb717943fd0afd85d213094d710db4845e0d9728d68ff23b11795eef41dd34fc", - "dest-filename": "minimalistic-assert-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083", - "sha512": "c891d5404872a8f2d44e0b7d07cdcf5eee96debc7832fbc7bd252f4e8a20a70a060ce510fb20eb4741d1a2dfb23827423bbbb8857de959fb7a91604172a87450", - "dest-filename": "minimatch-3.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602", - "sha512": "14cf6735462b4410042d9413df179943b7e630e060ea758d989293720b0979a2ecb4ffd43835691acaf93a15e185783a7feaad27cba267e3d4c640d67202172f", - "dest-filename": "minimist-1.2.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617", - "sha512": "e93ea51f41fc386f642139bf266ead768a086e8806f5ed2d2e0a58ea6a615d29bf03dbbc36ad6bc811be42ca62b9bf4b8d69413ec3d2ded590fc1a2dab815dc4", - "dest-filename": "minipass-collect-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373", - "sha512": "266412618a4f52a5f92729f5997691c0e75ad6e43c1cfe4a013fe80d22c2cedd41611850534fe10edb01d6e7d97c4133319f5a0159ac070f3e156b085e50a55b", - "dest-filename": "minipass-flush-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c", - "sha512": "c6e22aedc20eb74f513d1275f60762e1bf9188dbc31587b9247fa080dbc1a86aa941772bbb73dc466399b8704a58ad53c5ff7e710f8731537877acf8e8b64fec", - "dest-filename": "minipass-pipeline-1.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee", - "sha512": "aedcb9929c3dff3f125fd766c5b94503a79d22d526c0980c7980d946bc25215376ee2f20cac19bce7270520830d95fc556a1520dd5b2d38d193d2f35d43600a9", - "dest-filename": "minipass-3.1.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566", - "sha512": "591a039fffe65c1889d47e34aea6b7bc7d2da1e3f04ac19be398889d6953c926be52ee24ded6144b16b6bf52aa0222edbe5ad2cda131a92d60b64f7a03dcef10", - "dest-filename": "mixin-deep-1.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def", - "sha512": "34a98094449fea3306ca6d7ef91d116bbc2f855fb0156eb715a48e14fc116a1bde6b480c51c19485578083fd010b4c22bfd8a1e4d60f0755a7d54108d7f2fec5", - "dest-filename": "mkdirp-0.5.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92", - "sha1": "be2c005fda32e0b29af1f05d7c4b33214c701f92", - "dest-filename": "move-concurrently-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/mpris-service/-/mpris-service-2.1.2.tgz#ed6db2574f48e1fc356413fd3fc8e857d93d2e7b", - "sha512": "002e967a90a7156c0e304f4e5a994767ca6cfc107e83d42b12950a0afef05fcd9f0cfcd1de73ebca938598bfc59b4265a0402ee904d649f0cb2dcea633f8e29f", - "dest-filename": "mpris-service-2.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8", - "sha1": "5608aeadfc00be6c2901df5f9861788de0d597c8", - "dest-filename": "ms-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009", - "sha512": "b0690fc7e56332d980e8c5f6ee80381411442c50996784b85ea7863970afebcb53fa36f7be4fd1c9a2963f43d32b25ad98b48cd1bf9a7544c4bdbb353c4687db", - "dest-filename": "ms-2.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2", - "sha512": "e85973b9b4cb646dc9d9afcd542025784863ceae68c601f268253dc985ef70bb2fa1568726afece715c8ebf5d73fab73ed1f7100eb479d23bfb57b45dd645394", - "dest-filename": "ms-2.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901", - "sha1": "899f11d9686e5e05cb91b35d5f0e63b773cfc901", - "dest-filename": "multicast-dns-service-types-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229", - "sha512": "8e2e89e5e9db3321911c802400ebb759d57c9e082abe228210ab5770ea9fa61659b50ae61cac9c7f29c9d95ede54f500e0d849e95ed67f84e619b4f0284f41ea", - "dest-filename": "multicast-dns-6.2.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/music-metadata/-/music-metadata-7.11.7.tgz#95051a6a62a94390985a20c49e2207f5b1cfd898", - "sha512": "31ad7f79e8664452ce4c2ad4aff0ae380de86fb21b2bd7821039467ada8a02d6868f8c2f32c405bb6605c0ae90c863e225d3dd6c44953b19cf83cb91bf7cd97a", - "dest-filename": "music-metadata-7.11.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/musickit-typescript/-/musickit-typescript-1.2.4.tgz#d055117e2c897c4ebc570f0d969ad31649744837", - "sha512": "dfeff6d0f8b6cce5401df5057fadf52d4d8dc1a0bfa841c1064b0cf9843343f7df7f8b4830f5f9589e967bf5979b04c790090720e122b495b87113e7bd502af8", - "dest-filename": "musickit-typescript-1.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee", - "sha512": "f19b6f12703673969809961dd5cbe076753a72ac22c51a1883bd313cb594c2ce4e4536bf967c3ebb86a68b1452fc0739539990560a7da679525276cd58569665", - "dest-filename": "nan-2.15.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119", - "sha512": "7e9a1ed93d116c7c014c150e7ed01f04f683122d3ab9f6946a2d2613a627d6469c7374a74c4adf6ff87e5fde155f323ae2b2851d82265d2bddc061829b03aa08", - "dest-filename": "nanomatch-1.2.13.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb", - "sha512": "8595dcecad9ef8f81e23578305eff5d00adde1e91b7ebaea1bc129fbc2667f82480f66cd83b36f08f39937e91f179ef8a45408ee6ba6d8052a0e27682aa7133b", - "dest-filename": "negotiator-0.6.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f", - "sha512": "61ddd4112e665824aa47ea8d4fddd2dd4a18524a8067d94b83c6bb83dae29ac5a66062bc7154e8038fec17746bb21772577b0018c5d5526a4c60ec3e74ba4ebb", - "dest-filename": "neo-async-2.6.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366", - "sha512": "d67878e5d79e6f9a25358ede5fcd8190f3bb492c51e524982623d3ad3745515630025f0228c03937d3e34d89078918e2b15731710d475dd2e1c76ab1c49ccb35", - "dest-filename": "nice-try-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d", - "sha512": "7e000dde318087e468c541991d348e2c922a51cdb09a8070191e2d6e93402a69a8bc5a16ab439d4646f456495d45e3b66b68814ff384ba51bd5d251cd74af7ce", - "dest-filename": "no-case-3.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d", - "sha512": "89b3cade203ebda6357848c44a442433405b0aa14e6993225d14ed741d2eedbe1d8ed63a267b23bcf7541d5320eb142ddc1f1fa534d61c8f40f800e333d7ebce", - "dest-filename": "node-addon-api-1.7.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad", - "sha512": "66330f1447d5c798fecb6c85df92b3c79b05ee40f3c6e0e3eb3887e0515b3a9f3bcca0d9371f321312486f4e4e185e0d96df481c520c064465e3555dbdc35d6d", - "dest-filename": "node-fetch-2.6.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3", - "sha512": "3cf9aef1e11e1bdb1a114bc8f7b7e6e0e6315d507a6c5bf2353ca250e062721069146f00d4b8f0ddb63adbee683a30c430746777463b1d0fb1eeecf13b30ba24", - "dest-filename": "node-forge-0.10.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/node-loader/-/node-loader-0.6.0.tgz#c797ef51095ed5859902b157f6384f6361e05ae8", - "sha1": "c797ef51095ed5859902b157f6384f6361e05ae8", - "dest-filename": "node-loader-0.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5", - "sha512": "0aacb337acfb43a68c785fe4b5c3154f38401c21297fc48e6abc29ce97fca4d058da4e7fa0cdf850795d530a7c54a23bbb172dd87c5245d26305a65e112cdcc4", - "dest-filename": "node-releases-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8", - "sha512": "ff908c3774f44785d38f80dc19a7b1a3eae8652752156ff400e39344eae3c73086d70ad65c4b066d129ebe39482fe643138b19949af9103e185b4caa9a42be78", - "dest-filename": "normalize-package-data-2.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9", - "sha1": "1ab28b556e198363a8c1a6f7e6fa20137fe6aed9", - "dest-filename": "normalize-path-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65", - "sha512": "e9e66ce4bb375ad0a2b075a9f52d86532f1daa4a468b80554b3dc66aa884e9ecee6f4e75d844b3b57530501e82e8829b4246363e76ff983e166288c24707302c", - "dest-filename": "normalize-path-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c", - "sha1": "2cc0d66b31ea23036458436e3620d85954c66c3c", - "dest-filename": "normalize-url-1.9.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a", - "sha512": "f546421511d074dadf4e91a0f3ed4834883ddc1eb3134697315164c35585c2f3b84a5672c14e9a2e0e4e7f4029fcf81c6d2c382cdc6f3165cc7ae8303025f400", - "dest-filename": "normalize-url-4.5.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a", - "sha512": "0e52fe5f03b2dcdc4043cc6e0b4a243e02b8ea2b953402b4d5837b46e79806aa85786b018d5f5798203301d82dfbaebb6c297990f87d12a28a0f09da3c6d48ec", - "dest-filename": "normalize-url-6.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9", - "sha512": "6227386d91c93adf510856d13f71a0a6a85270e6381c7dd5d8ff32063e82798ab5d7c42bf812d7a93d89be9274d26af22c44a980ec5fe57945bf86635f12d273", - "dest-filename": "npm-conf-1.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f", - "sha1": "35a9232dfa35d7067b4cb2ddf2357b1871536c5f", - "dest-filename": "npm-run-path-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2", - "sha512": "8add6f13de7317a7534fd941b186f1bea8744a8cb848fa307218f45011a3fd5e9c4cf9d75ed40e3d46e167a0a61b3003feb5b6d8b40ae84f7aa5c7495e4e00e3", - "dest-filename": "nth-check-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863", - "sha1": "2109adc7965887cfc05cbbd442cac8bfbb360863", - "dest-filename": "object-assign-4.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c", - "sha1": "7e7d858b781bd7c991a41ba975ed3812754e998c", - "dest-filename": "object-copy-0.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0", - "sha512": "1e8db3f346d522f265a07f98cd19a965541ef3bfaa01298150a6435a0c7d72ef8a0eb5f66431ffded332fa05db6444d51acd8cf1877139b3a1ed702d8a6f58d2", - "dest-filename": "object-inspect-1.12.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac", - "sha512": "ddcc83b321e0b668bb23b0df4922362c3a7a48ada5c2fb5b834a744757b446f4ea17971e1b1f8ad9d7d28e6d5b283315085103010bf2fa8f1ce9aed5ba339d77", - "dest-filename": "object-is-1.1.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e", - "sha512": "36e00449439432b9485ce7c72b30fa6e93eeded62ddf1be335d44843e15e4f494d6f82bc591ef409a0f186e360b92d971be1a39323303b3b0de5992d2267e12c", - "dest-filename": "object-keys-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb", - "sha1": "f79c4493af0c5377b59fe39d395e41042dd045bb", - "dest-filename": "object-visit-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940", - "sha512": "8b14f62f94c75ec029ca250f60a996fb6107a575dee488b733e7f87be6891401daa396a61515ba27438ee9cfcb53c05ee3bbad0b1d862fcf61c4607a5d298ab9", - "dest-filename": "object.assign-4.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e", - "sha512": "55d0e80b0bc923841d0ba9dd8e9a859a82f7ffe1f17df1416dc2732a2e61c0b2eaab1de675b79d4697d90dd2b44ab3926ae8fc5f81b306f9c3665e2f4cdedd3b", - "dest-filename": "object.getownpropertydescriptors-2.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747", - "sha1": "87a10ac4c1694bd2e1cbf53591a66141fb5dd747", - "dest-filename": "object.pick-1.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e", - "sha512": "3d7d70bb402601d3ea38bd665a1aa694e77c90e219430199c3aae1eee6f2f5f4dce6585a39614b5f723a47586b17d937cd4638d1eea282c2c69035caf762c936", - "dest-filename": "obuf-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947", - "sha1": "20f1336481b083cd75337992a16971aa2d906947", - "dest-filename": "on-finished-2.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f", - "sha512": "a59004f8524ba32213cad76a2b4539b3e148a6337424fdcecc58bfbbc471f84579fd6f894d61971bcc45cdebc4ec08c17c3a87bfff2f2fca90b088479ea464ac", - "dest-filename": "on-headers-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1", - "sha1": "583b1aa775961d4b113ac17d9c50baef9dd76bd1", - "dest-filename": "once-1.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e", - "sha512": "91ba5a4921894d674063928f55e30e2974ab3edafc0bc0bbc287496dcb1de758d19e60fe199bbc63456853a0e6e59e2f5abd0883fd4d2ae59129fee3e5a6984a", - "dest-filename": "onetime-5.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc", - "sha512": "3ea1e98200bd6cb57455e59c74a864a7163edc94f37ad2d2a930962ffcffb4521b23a1bc2428e89dd5e4953d498a77332f3d9789beb6b12a744ff80a4f82a4b0", - "dest-filename": "opn-5.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f", - "sha512": "87205597a8aaa94389f05a917be97f812f07fa42988eb12775de4f9b531f06db04280d37f0792475b025ffbd840171b2a270ff3c5b2f9951be12f708a6588c06", - "dest-filename": "original-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc", - "sha512": "b3bdd7c4e678ce9b7579d658673be1a856babaf41cd6fc146b42b405db4866040c0098fd21b79b1fe26480a65cf61f81d393ca1cb3939786a31b506636b55997", - "dest-filename": "p-cancelable-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf", - "sha512": "0593abde74501ce9ed5234eb1fcf8b879e2c98a1e81f2babf167b557c0d2315ae5e40da66a538ec2e2519ca4438d29e4a1e061e1ab7a0701276f923b265df5c2", - "dest-filename": "p-cancelable-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae", - "sha1": "3fbcfb15b899a44123b34b6dcc18b724336a2cae", - "dest-filename": "p-finally-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8", - "sha512": "bef717b0b009f43af9ad038f93bb68650649029065d8ae09e9d00d4ac12e87a408e3525872c4bfaa14c66bd12b2145202b758d428258bf2971be3aa68aa100f5", - "dest-filename": "p-limit-1.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1", - "sha512": "ffff3c985592271f25c42cf07400014c92f6332581d76f9e218ecc0cbd92a8b98091e294f6ac51bd6b92c938e6dc5526a4110cb857dc90022a11a546503c5beb", - "dest-filename": "p-limit-2.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43", - "sha1": "20a0103b222a70c8fd39cc2e580680f3dde5ec43", - "dest-filename": "p-locate-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4", - "sha512": "c7ed76c3f4e8fb81857e0261044a620dc2e8cd12467a063e122effcf4b522e4326c4664dc9b54c49f5a3f5a267f19e4573b74150d24e39580fbf61fb230ba549", - "dest-filename": "p-locate-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07", - "sha512": "47bf5967fd30031286bb7a18325cfc8f2fe46e1b0dad2ed2299ecfc441c1809e7e1769ad156d9f2b670eb4187570762442c6f3155ec8f84a1129ee98b74a0aec", - "dest-filename": "p-locate-4.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175", - "sha512": "cb76fc2a977c380378e388717c16c57e3d4563f463b5377cb73630854a8d617c747d7c76897e2668fe10afaaa120a6d05c8d36c132c075ae1f6146c36a04d417", - "dest-filename": "p-map-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d", - "sha512": "777a9755317fb3e5be09d279036f70cb05769fc0904186a1960cf66c5880fb87953496c726874f67efe05f03c68746cea80fa3f12fbaf9c926bcb18f935429c5", - "dest-filename": "p-map-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328", - "sha512": "5c4e86e3e6134e44f66b45166f692365ef313707fc6c86e7aa973f212fe274e055872bdeb3498ae4e2607a8723c7bab9a6f5ffea6db7c6ecd53d84f5b8633bdf", - "dest-filename": "p-retry-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3", - "sha1": "cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3", - "dest-filename": "p-try-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6", - "sha512": "4789cf0154c053407d0f7e7f1a4dee25fffb5d86d0732a2148a76f03121148d821165e1eef5855a069c1350cfd716697c4ed88d742930bede331dbefa0ac3a75", - "dest-filename": "p-try-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0", - "sha512": "9376dd9b69f6e6d932c5c8d22b3079c7c91f57194c760b1b3ebd069197301ec2e96dae9c063a82b752a570284a12fc4721c4c1d4554cbb0a228d9dbac5ec7931", - "dest-filename": "package-json-6.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5", - "sha512": "457963ef3098a2445ea96a4e3c7f68622bd4ccb619e6f00f21f1260933558a8b02efc17c1741fdcbb4fb806d8cdfdca682eb7117981c144b326504a987d069dc", - "dest-filename": "param-case-3.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f", - "sha1": "d3460bf1ddd0dfaeed42da754242e65fb684a81f", - "dest-filename": "parse-author-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9", - "sha1": "f480f40434ef80741f8469099f8dea18f55a4dc9", - "dest-filename": "parse-json-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0", - "sha1": "be35f5425be1f7f6c747184f98a788cb99477ee0", - "dest-filename": "parse-json-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6", - "sha1": "6d5b934a456993b23d37f40a382d6f1666a8e5c6", - "dest-filename": "parse-passwd-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4", - "sha512": "0a2c9e3b1153fc96723799b4cfd3df5f0e1208127a4b2833d43a65d30aa39610c418604fd469ec51510bd29eb78681b57dc8f77c7ca75e2f4d60ee2758e2fea9", - "dest-filename": "parseurl-1.3.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb", - "sha512": "b969464f76129caf71dc140968e75c670ae757a84fa5df23147d7fb9ca622d13e1ff6cc2549292d7d1381af607bda09c0029f77e85d9d1c2c1f56af1d4a19ee6", - "dest-filename": "pascal-case-3.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14", - "sha1": "b363e55e8006ca6fe21784d2db22bd15d7917f14", - "dest-filename": "pascalcase-0.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0", - "sha1": "cc33d24d525e099a5388c0336c6e32b9160609e0", - "dest-filename": "path-dirname-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515", - "sha1": "ce0ebeaa5f78cb18925ea7d810d7b59b010fd515", - "dest-filename": "path-exists-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3", - "sha512": "6a4f50cb943b8d86f65b071ecb9169be0d8aa0073f64884b48b392066466ca03ec1b091556dd1f65ad2aaed333fa6ead2530077d943c167981e0c1b82d6cbbff", - "dest-filename": "path-exists-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f", - "sha1": "174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f", - "dest-filename": "path-is-absolute-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53", - "sha1": "365417dede44430d1c11af61027facf074bdfc53", - "dest-filename": "path-is-inside-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40", - "sha1": "411cadb574c5a140d3a4b1910d40d80cc9f40b40", - "dest-filename": "path-key-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375", - "sha512": "a2399e374a9dfb2d23b3312da18e3caf43deab97703049089423aee90e5fe3595f92cc17b8ab58ae18284e92e7c887079b6e1486ac7ee53aa6d889d2c0b844e9", - "dest-filename": "path-key-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735", - "sha512": "2c32733d510410f47ecb8f33f7703411dd325dbf29001c865a8fe4e5861d620a58dbfd84b0eb24b09aeaee5387c6bcab54e9f57a31baa00a7c6a1bce2100fcb3", - "dest-filename": "path-parse-1.0.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c", - "sha1": "df604178005f522f15eb4490e7247a1bfaa67f8c", - "dest-filename": "path-to-regexp-0.1.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73", - "sha1": "f012ccb8415b7096fc2daa1054c3d72389594c73", - "dest-filename": "path-type-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445", - "sha1": "fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445", - "dest-filename": "pause-stream-0.0.11.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.2.tgz#a5cb847e347d3eccdc37642c82d2b4155c1ab8af", - "sha512": "f5f31acface8c70f72a4ed4a672e510c9812ba912dbb443e83f3aaaac5475f7aca191f2a7a144b633b050116786d5bddbdf9272a25efb836e43273b583a711a5", - "dest-filename": "peek-readable-4.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50", - "sha1": "7a57eb550a6783f9115331fcf4663d5c8e007a50", - "dest-filename": "pend-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f", - "sha512": "70c943a9a2c4a9f49a5bc67b379270fa5c885bcebd1334fbdff179961b58f5c2c6a15c525f39df81f5cc3b46792b4a344364e44d7abed0a16c76749ede30d588", - "dest-filename": "picocolors-0.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c", - "sha512": "d5fca0ae84cb947bbaeb38b6e95a130eff324609b415c71e72cb2da3e321b19d03fc3196dac9bc13c0235bb354e5555346de46c5b799e6a06e26bf87c8b6248d", - "dest-filename": "picocolors-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42", - "sha512": "254ded7874cd8e6136542185cee63c117cc20d5c04a81d9af1fb08bf0692b4784058911e55dd68d500fcd0253af997445d748b6d2b2e2f0263902056a9141454", - "dest-filename": "picomatch-2.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c", - "sha1": "ed141a6ac043a849ea588498e7dca8b15330e90c", - "dest-filename": "pify-2.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176", - "sha1": "e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176", - "dest-filename": "pify-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231", - "sha512": "b81f3490115bfed7ddebc6d595e1bd4f9186b063e326b2c05294793d922b8419c86914d0463a9d252b082a438fe8e00815b8fb18eadcb9d739a4d8d9fa0795da", - "dest-filename": "pify-4.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa", - "sha1": "2135d6dfa7a358c069ac9b178776288228450ffa", - "dest-filename": "pinkie-promise-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870", - "sha1": "72556b80cfa0d48a974e80e77248e80ed4f7f870", - "dest-filename": "pinkie-2.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3", - "sha512": "fc4e7b018928790db9aa4c4c8f93c1395805f0a8aefe1edc612df4679f91ed66a208205f2eae7c648fdd49e68429bf565495799ffd37430acddc8796205965bf", - "dest-filename": "pkg-dir-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3", - "sha512": "1d10f36da2a30be00e5955f1014ff1e7808e19e22ff5e6fee82903490a0d4ede17c96a0826fb8fb178b3c6efc5af6dc489e91bb59c2687521c206fe5fdad7419", - "dest-filename": "pkg-dir-4.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5", - "sha512": "9c3cb04e1164d62e0140ae2dc0f43a4c0e114fc6c363deb27ae0950562f778f0110a210a0d14ab3466c5220509a4ba7e5de211eb9bfcadaed6b89385501b6430", - "dest-filename": "pkg-up-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/plist/-/plist-3.0.4.tgz#a62df837e3aed2bb3b735899d510c4f186019cbe", - "sha512": "92caebf32f7e9d73b1401da8b1536aae0bd7fd740f397694e0140c2a362af0fbda635535f26a3e7ca8014b0ccafa5b92ca29ceb8f69ef79ea5495701c3194032", - "dest-filename": "plist-3.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb", - "sha512": "e34416e586a504d7d0a39c916268b0ed8cfa4ca295af787af7bd01d9813eddf429b1672b6e3d4fcc9831789d7d0d142384c6ca3c8b8c63cac569773c9a8a2557", - "dest-filename": "pngjs-5.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778", - "sha512": "49efb68ac6a721c12a7f65cc1e3c942ac91ccf16cf1fb7509e53235d7ebe7726dacb21ef01ffd30a0c8c465cdffc1e900e100414e19eb34a73468ddbcb801b30", - "dest-filename": "portfinder-1.0.28.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab", - "sha1": "01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab", - "dest-filename": "posix-character-classes-0.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e", - "sha512": "2da60b0cd4b8486f10e56016a882607473c9ac30ebfcbbfbef9acc04551b8234f3ea3df8954ce70021dc7515aba0fbd700d3f6563ef234ae7bbe9f5e16accb59", - "dest-filename": "postcss-modules-extract-imports-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0", - "sha512": "7b7c43abe2e8b6219eb329a946528d81a2743c2ce85087691f4763e3b89602e8bf9324e08770a202bd6a3f9e2ea1d989865ea9f6b37a06835c7440d5271f510f", - "dest-filename": "postcss-modules-local-by-default-3.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee", - "sha512": "632120b13311a4d77e1e6c82ec7fe6877cbe31e1567afcbb5757af5612567b098c6e30c721b65b3972020b6cbe9b5c48d5455f213d47316fced381f1caef685d", - "dest-filename": "postcss-modules-scope-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10", - "sha512": "d7ffc4e63081ad9f439915fecc2b6642d45257a3d5e36231ec1ce3f466f025c79dbae7fb22a3fc3207935ee4431ce5a3da6d15cd90f9faba05583b94f1142372", - "dest-filename": "postcss-modules-values-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f", - "sha512": "50edd282764e553c2ee24c8b476d94435c59874f3a472359a696fb94b00a0452bc6b7dadb46e62f3b63f3f7fb66d14a364dc89d41ee17c5368dbbded29ef58c5", - "dest-filename": "postcss-selector-parser-6.0.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514", - "sha512": "d4d342b3abaeadf9156de5c6e12f09153f6dd7d9b8e480a789ff3358b779a0f499e74427c0c7caf87de3bf8d3c7788f0ffb06db6fe5ac52e48887a0b69534779", - "dest-filename": "postcss-value-parser-4.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309", - "sha512": "ca2a1aca335b1e7eb3d7f072c326f6638b37caf0c079718ecb1a83f8b9d53a29eae8c76677ef925b6c14355cdabf2c87c5debe0f1cd6188ba8b20e8fd518fcb8", - "dest-filename": "postcss-7.0.39.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc", - "sha1": "d4f4562b0ce3696e41ac52d0e002e57a635dc6dc", - "dest-filename": "prepend-http-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897", - "sha1": "e92434bfa5ea8c19f41cdfd401d741a3c819d897", - "dest-filename": "prepend-http-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6", - "sha512": "118e680f39ac5f9c2fbb29c0072ae66343f485ca7e4299c029b26783603630f8d52970b1ac3494933821549e1918f22ff890b8817f1f3d45ac702d11b63b161b", - "dest-filename": "pretty-error-2.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2", - "sha512": "de8b943a9421b60adb39ad7b27bfaec4e4e92136166863fbfc0868477f80fbfd5ef6c92bcde9468bf757cc4632bdbc6e6c417a5a7db2a6c7132a22891459f56a", - "dest-filename": "process-nextick-args-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8", - "sha512": "ecf887b4b965e4b767288330d74d08fbcc495d1e605b6430598913ea226f6b46d78ad64a6bf5ccad26dd9a0debd979da89dcfd42e99dd153da32b66517d57db0", - "dest-filename": "progress-2.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3", - "sha1": "98472870bf228132fcbdd868129bad12c3c029e3", - "dest-filename": "promise-inflight-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849", - "sha1": "212d5bfe1318306a420f6402b8e26ff39647a849", - "dest-filename": "proto-list-1.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025", - "sha512": "96542c30b4940d43d3e388ddad4fcedfbaa59e27e2b433fe670ae699972848ac8b2afb59c69c95d27dbf6c3fcde2d040019fe024475953b28cadaa0ad7e5d802", - "dest-filename": "proxy-addr-2.0.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476", - "sha1": "d3fc114ba06995a45ec6893f484ceb1d78f5f476", - "dest-filename": "prr-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64", - "sha512": "2f0672fa9dd216cd4fcad77f8d872de30a6fe3d1e2602a9df5195ce5955d93457ef18cefea34790659374d198f2f57edebd4f13f420c64627e58f154d81161c3", - "dest-filename": "pump-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d", - "sha1": "9653a036fb7c1ee42342f2325cceefea3926c48d", - "dest-filename": "punycode-1.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec", - "sha512": "5d1b118dd7fe8f99a5fb2ffa18a1cf65bac5ffca766206b424fb5da93218d977b9a2124f0fdb1a0c924b3efa7df8d481a6b56f7af7576726e78f672ff0e11dd0", - "dest-filename": "punycode-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62", - "sha512": "9758cd02ca4805216a6d3fb2fb9168b288cda55a45f789e523ec03529a8ff5e9f03937c7c7d7f4821e6707deaf97eeb24e9b09b32a5e36bc1fccfacab87078d4", - "dest-filename": "pupa-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/qap/-/qap-3.3.1.tgz#11f9e8fa8890fe7cb99210c0f44d0613b7372cac", - "sha1": "11f9e8fa8890fe7cb99210c0f44d0613b7372cac", - "dest-filename": "qap-3.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819", - "sha512": "117b73459982f981a61a50c56d72b142231937008b10ee8100d2971b8882b5220cd32a9cfe96a9a52c774482abe2bd2e87926c05c90e5de2ab077233ee6750a5", - "dest-filename": "qrcode-terminal-0.12.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.0.tgz#95abb8a91fdafd86f8190f2836abbfc500c72d1b", - "sha512": "f4c811a6055cfbffb8edd16f41e0fa536b3467dd84b0acdc1e882dba6e1007e50d774db958e2521ef9ff86393dc66ce3ed2b63f790b2500b37d66ae3c65884b1", - "dest-filename": "qrcode-1.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee", - "sha512": "4c8464e1aa982cda0951b77e836944773e642d622e4cc45a8005f197bf10d118958c03ae80799e28d19d777730a3f92da5ff5a2fd7a909f16a58310acac5252d", - "dest-filename": "qs-6.9.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb", - "sha1": "bbb693b9ca915c232515b228b1a02b609043dbeb", - "dest-filename": "query-string-4.3.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620", - "sha1": "b209849203bb25df820da756e747005878521620", - "dest-filename": "querystring-0.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6", - "sha512": "148aa08f6114bd36bb479d2ed2b1acc937edce3626bff6b784edf8e5b64daea69b36a8ed8220cc826a389a452377e9f3539a05ddd0a52aa1483d42b26d4caaa1", - "dest-filename": "querystringify-2.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932", - "sha512": "5aec802d18d63c31adb7fc3326269d3b901763ef2167cd215697ba3328af82b691116ef9d57dd26e146f1b778b28e60dfbc544bea2dc7f7c1d9ede386784b848", - "dest-filename": "quick-lru-5.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a", - "sha512": "bd897788e5fee022945aec468bd5248627ba7eca97a92f4513665a89ce2d3450f637641069738c15bb8a2b84260c70b424ee81d59a78d49d0ba53d2847af1a99", - "dest-filename": "randombytes-2.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031", - "sha512": "1eb82cc7ea2baa8ca09e68456ca68713a736f7a27e1d30105e8c4417a80dba944e9a6189468cb37c6ddc700bdea8206bc2bff6cb143905577f1939796a03b04a", - "dest-filename": "range-parser-1.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32", - "sha512": "44f30015424fd7d5887adffdf67821e88bfc7f301baae9b82e2ec00fa0ed19a5b6469301ff5d710e86a53e224c4dbbba2378646cc564013bd9aea6fd104a9e79", - "dest-filename": "raw-body-2.4.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed", - "sha512": "cb76c682a2a3dd005dc4b6cb9289a5a2192fb00f207408944254812670617e7f813f18386dceb677c4dc056d79c1abc37e07b10a071c72485c66fcb0c9060f3b", - "dest-filename": "rc-1.2.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/rcedit/-/rcedit-3.0.1.tgz#ae21b43e49c075f4d84df1929832a12c302f3c90", - "sha512": "5ccd09bf8d3fcb885502a8ff30eef4a3f216b38b8eb1a4a8a3698bca4de49450d6f924ad2e70adcee42efb53814c830694cf02bda2bd7ed9580a9e8327e70cb3", - "dest-filename": "rcedit-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23", - "sha512": "b3887de8ab4b0d4425b04361327d5aafcb766c46beabf600b63f293cf7488cf0c604321536cac3f5a5cd5aab2951ee80cca0881b40b51d964ba8b57baa938118", - "dest-filename": "react-dom-17.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037", - "sha512": "82784fb7be62fddabfcf7ffaabfd1ab0fefc0f4bb9f760f92f5a5deccf0ff9d724e85bbf8c978bea25552b6ddfa6d494663f158dffbeef05c0f1435c94641c6c", - "dest-filename": "react-17.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/read-config-file/-/read-config-file-4.0.1.tgz#ece5f6b1a5e6a46d0d93fdd0339f2f60ab892776", - "sha512": "e5c6840f7ba8d8801930f71b87ff61c7f3b6f6cdb8df444bc6d9c50ddcf1a47fdea44a5ac0ead09c6047b9ea2d21752b18f3c881d35037e4bf088a765a68927f", - "dest-filename": "read-config-file-4.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.2.0.tgz#71536072330bcd62ba814f91458b12add9fc7ade", - "sha512": "831ecf82be48e7a26d633f96baa11b4078ffc56a3ee55c2e6b68e16f55703385a27793ea6266788b4d190746041887e4541b02bfd52b8e0caa0a241f4bf3a8b2", - "dest-filename": "read-config-file-6.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be", - "sha1": "6b72a8048984e0c41e79510fd5e9fa99b3b549be", - "dest-filename": "read-pkg-up-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8", - "sha1": "8ef1c0623c6a6db0dc6713c4bfac46332b2368f8", - "dest-filename": "read-pkg-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57", - "sha512": "11b868f0ae2321b1c0c67bb18bba38d8ead9805fd94cd72c663ea744ac949a484b16af021c8b69fdfcba85066e6663ff9f7c99f550546e9e33cff997f219983f", - "dest-filename": "readable-stream-2.3.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198", - "sha512": "055887cbb2ca793cf8a0d9e470b27e95548beafa6215e5fafddde8487f33096ed4c4fda89dc864faf4c6075e37c6e1631d2ddd7938242a85d7ca65eaca688874", - "dest-filename": "readable-stream-3.6.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb", - "sha512": "78f78ae9c73511c28b121245b7f01e6cc08b2fe1a048a86eca0ad9fc62da29960479c22020409fe14694b9a072886b73724c11e1a8a7f55cd487de53d5ec581b", - "dest-filename": "readable-web-to-node-stream-3.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525", - "sha512": "d4953ff2af95805672c70ac9f925483ac87e2b2c161a976cdcd4ea8a488aa43319592726018c8a220aa43be011bcd5897d7797475cf1cfb687178bb80b21fabd", - "dest-filename": "readdirp-2.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326", - "sha512": "dc4d7651e3523df8eb8308e447cd66e49ec0c3f4f9e53bbb9d4c995506022843acfb6764c4463e0e93ed6733b862bbae88f6fb36460b55cc890b8fb309b939a4", - "dest-filename": "regenerate-unicode-properties-9.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a", - "sha512": "ceb71e47f5e119853f77fa29af610a3bb6911d47a2048f2a8ed7c7a800d3c1977a4b37f2d7a95aea4a83d0c214b39cf9871e8068a6be3e2c693eb476f3df88d0", - "dest-filename": "regenerate-1.4.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52", - "sha512": "a77553f9c38483116c45103d5f896423513e936fc2b672ad53881cc7268252b7a294bfefa88e82759df0c55531dd439483e82750e41071123b066488eb9e8c60", - "dest-filename": "regenerator-runtime-0.13.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4", - "sha512": "78e7fabe46b920ed79d497ecc3634ef56a465f9f16eb05a679f2b7235cc41abd25383d2ef2bc0f68da902f5691c546b12de28edc0acd87755883529b683f8517", - "dest-filename": "regenerator-transform-0.14.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c", - "sha512": "27a4838d4803c508f936eb273ad745c43c0dffe1d6ca447c1842f072d27b99daa1732cb5c44738491147517bf14e9ebad586952808df44b67d702a92ead9f7d8", - "dest-filename": "regex-not-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307", - "sha512": "a4c47b84155450623b3cc037ee6da87c87500aca265676acf899f950f1801d0fbf2e5c0a9bf6932c91dd6ac98747395f799c0788039a452a36adb0439b79cd51", - "dest-filename": "regexp.prototype.flags-1.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0", - "sha512": "d45e9b62ca188b3ea2b3ea33ef4356babd95961f4a5adb30b91bb324e7de614adf3d7da8f27ef802751568e1836d4a9518ef5f347bb8f3fa6324ee2c355c2c3a", - "dest-filename": "regexpu-core-4.8.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250", - "sha512": "ea09126f853a696241e1217666f2dbefac8206372fb9f5c1aafbc4c751db98a3e4badb308d6d71355458d3e75a96321845ba2037b3b47ad61295b89a110c8ccb", - "dest-filename": "registry-auth-token-4.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009", - "sha512": "f1a7185d74c8d00910bfa4403a3137bce6885d9913f70a382ce15b04a6101049e730d0692aa754ac8e92e0d4f428f228fd656f279b44fd7e4b17f4d051fd1e93", - "dest-filename": "registry-url-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733", - "sha512": "385153dcc7eb1fdd31216f0e392c94ae4e901c3e44f49393786a1d8897814b727a230960cc930d13fd5b664956cf9a1383ef5d08cc847ad725bc255738fa0ddc", - "dest-filename": "regjsgen-0.5.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968", - "sha512": "038a5c68e46a98d3035705235a84f3ba1c0c1a93fe3729297ea02c1202351521ff1330bb96b3794cc77e90df180a8bd7fa3329bbc79aa978173c26b483c15035", - "dest-filename": "regjsparser-0.7.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9", - "sha1": "54dbf377e51440aca90a4cd274600d3ff2d888a9", - "dest-filename": "relateurl-0.2.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef", - "sha1": "c24bce2a283adad5bc3f58e0d48249b92379d8ef", - "dest-filename": "remove-trailing-separator-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609", - "sha512": "a02705cb168cacab0a713639f6a9c202d9835522df3dbaefe80ded55b3dd14c32bbf98da2b5d15ea6e3470ab283cd840a8deab9875bdb2cc16e28debb92af051", - "dest-filename": "renderkid-2.0.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9", - "sha512": "2c588d7d1712bbb28addebccc983ae0b3bf72f5d135bbc82d46dbff92b4c8caf18e95a9dd8c1bbaff423c38821b6e08e8c5be59e6b3f88c98baa9bd6fc44bf59", - "dest-filename": "repeat-element-1.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637", - "sha1": "8dcae470e1c88abc2d600fff4a776286da75e637", - "dest-filename": "repeat-string-1.6.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42", - "sha1": "8c64ad5fd30dab1c976e2344ffe7f792a6a6df42", - "dest-filename": "require-directory-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909", - "sha512": "5dfd2759ee91b1ece214cbbe029f5b8a251b9a996ae92f7fa7eef0ed85cffc904786b5030d48706bebc0372b9bbaa7d9593bde53ffc36151ac0c6ed128bfef13", - "dest-filename": "require-from-string-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b", - "sha512": "34a37990c0f294aba577160b4947eb6e8e53bb387885dfb613c34f3d7d36999b67d55b911104e861efd9765272f89dee0a97da886174e5eec1f16d225db4079a", - "dest-filename": "require-main-filename-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff", - "sha1": "925d2601d39ac485e091cf0da5c6e694dc3dcaff", - "dest-filename": "requires-port-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9", - "sha512": "d1ad45e25ef7fd915939a9099d0dc5be4276fa0493416cffaf6284e4e7436344f13e6e61e0692a91659f338ed3ec7b1b9ceb5c255105e1ea42572eaeed0dcafa", - "dest-filename": "resolve-alpn-1.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a", - "sha1": "00a9f7387556e27038eae232caa372a6a59b665a", - "dest-filename": "resolve-cwd-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43", - "sha1": "79a40644c362be82f26effe739c9bb5382046f43", - "dest-filename": "resolve-dir-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748", - "sha1": "b22c7af7d9d6881bc8b6e653335eebcb0a188748", - "dest-filename": "resolve-from-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a", - "sha1": "2c637fe77c893afd2a663fe21aa9080068e2052a", - "dest-filename": "resolve-url-0.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198", - "sha512": "1e1b6bc349cb792ac543ba613e9e0e39c5632cf21e327465af999c9d5b8c7bb33fede067f7c0378661512e8168dc32d9922bd26308515094f23f2580939e962f", - "dest-filename": "resolve-1.22.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7", - "sha1": "918720ef3b631c5642be068f15ade5a46f4ba1e7", - "dest-filename": "responselike-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723", - "sha512": "c47e3cbb715307d56c670ed1fafbe068a78b2b34fa8cea206d08447bf8dec309d98333dc9f25ae8b602fe89a6861917ff75bae782fa5aa15aa794470e7faa10b", - "dest-filename": "responselike-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc", - "sha512": "4d3958a5af8e2febcc30d1b6e314a5406109dc1fd1cc47d494b72dedbe46ff2b5abfec0fae9942a55305bb0cd76e479c26b6fa218a358856f44bdbf7efbe789a", - "dest-filename": "ret-0.1.15.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b", - "sha1": "1b42a6266a21f07421d1b0b54b7dc167b01c013b", - "dest-filename": "retry-0.12.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec", - "sha512": "b968db68a20add3d4e495a6dcd7ecd97a3ef437a801ad284b5546346e6b38df2f7071e5e238d3d5594aa80d0fee143679b32d574f8fd16a14934fa81645bdee3", - "dest-filename": "rimraf-2.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a", - "sha512": "25990931990018514f3f662a5d95cf6cc94c060b31cc4f082ece253085ffda8d0bf54070f4efd8de8eb0170fe2f582daa5c5095b0a9b8b791dc483dd0bad9320", - "dest-filename": "rimraf-3.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd", - "sha512": "08784f87e50d1c3d864d735884f58b9d4f0e347748fb90c8fb811820039a883eb7ac7798959bf287c3fe8a7e7df7d4d348581462e294023cd123899d87fa7ed8", - "dest-filename": "roarr-2.15.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47", - "sha1": "e848396f057d223f24386924618e25694161ec47", - "dest-filename": "run-queue-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/run-script-os/-/run-script-os-1.1.6.tgz#8b0177fb1b54c99a670f95c7fdc54f18b9c72347", - "sha512": "aa5e8fd8bce10534c37f32adb3e428e07f785542a9c4a0c5cfa431c7069464dd26c2f8bb2f7969388ec1a8f0aaee58038775cb974769797c1f715222b65ad8af", - "dest-filename": "run-script-os-1.1.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d", - "sha512": "19dd94641243917958ec66c9c5fb04f3f9ef2a45045351b7f1cd6c88de903fa6bd3d3f4c98707c1a7a6c71298c252a05f0b388aedf2e77fc0fb688f2b381bafa", - "dest-filename": "safe-buffer-5.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", - "sha512": "ae9dd2a34eca71d9a629b1af81a37141226bedb1954959394bd12ad45fa9a5b468ef4f9879a0f1930e4377c34f37e183e9b8e7626d95b8fb825e6a6e62f9825d", - "dest-filename": "safe-buffer-5.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e", - "sha1": "40a3669f3b077d1e943d44629e157dd48023bf2e", - "dest-filename": "safe-regex-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a", - "sha512": "619a372bcd920fb462ca2d04d4440fa232f3ee4a5ea6749023d2323db1c78355d75debdbe5d248eeda72376003c467106c71bbbdcc911e4d1c6f0a9c42b894b6", - "dest-filename": "safer-buffer-2.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378", - "sha512": "cbfe7631ccbb6b0de0466ec8adc183171fdb0a4e00851876788f65b8739033cea766cab0891924ab619e9075c1043f9298f89d73c8b63eab58665fa9589f0e7a", - "dest-filename": "sanitize-filename-1.6.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9", - "sha512": "36a543bfd4e900d523166d0df2e3391b12f7e9480a8bdfdab59c3ec7b6059d0f1c9301462ab978c57e325adadecb75099b99cfd6451b9d880ba29a963524615b", - "dest-filename": "sax-1.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91", - "sha512": "d9e59f1a002aa96146aad74c99c2f9cc230ad54f0a957bfc4901468252f7084b5dd1a0d50d681e17f6280a6be59f9e66e734a4dc9ff6d214da48179239bb100d", - "dest-filename": "scheduler-0.20.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770", - "sha512": "8b6ecc89ce0aa2f33f9671accbcc214421e173b5627096a30234eb620d752bdcdf6579d822de24e45fa4664c239eb84accb89cfc72d4e23d759a3b33d86ffbe6", - "dest-filename": "schema-utils-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7", - "sha512": "48788db4c394196050270cc84a25582aef361a257841819e3e9de8765635b6e28eee03eda61013e51fe9cb47c0eb1b5b80b2ff46fb4966753d6fcb34175ab45e", - "dest-filename": "schema-utils-2.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281", - "sha512": "6393d0c52e084e50be11a84bb97698f3a4d77d1ec3739970dbde1a9573aaf3a2401c28a100865faaff273425af68426f682e75b8df616cb19e57470505d1fe17", - "dest-filename": "schema-utils-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca", - "sha1": "625d8658f865af43ec962bfc376a37359a4994ca", - "dest-filename": "select-hose-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574", - "sha512": "9648da880c9efb00590c206cbb90468b45e22d1c5e525b06a1de593fddb8091484a06b99030fdfef2f512aedbcaf04df88756175abe1074a87d08355e8fd6510", - "dest-filename": "selfsigned-1.10.14.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc", - "sha1": "0dee216a1c941ab37e9efb1788f6afc5ff5537fc", - "dest-filename": "semver-compare-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b", - "sha512": "197d08c7f089707c81f1ce329291c6200bcbc8ec0ea1bb4cffc77e4d090077cd7f6c48e03c7adf6dae355697acafb8d7fedf1487e477117f5e012e5b7be8d062", - "dest-filename": "semver-diff-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7", - "sha512": "b1ab9a0dffcf65d560acb4cd60746da576b589188a71a79b88a435049769425587da50af7b141d5f9e6c9cf1722bb433a6e76a6c2234a9715f39ab0777234319", - "dest-filename": "semver-5.7.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d", - "sha512": "6f7f5305a4d27d5eb206b6a953cf69e5f29e904da6fcdc270e870e56bb90152d7fbde320773b8f72738cdf833a0b0c56f231ff97111ae6b0680de530bb91c74f", - "dest-filename": "semver-6.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e", - "sha512": "f8607acd503d2d687ace8bd840b00b1f0bf9adbd8f1c69498b795f8aa207c51d2ebb00a079f70e25ce7dbfd7efd70f066d2b70c6ebaaa808c8f4d30038e82ad4", - "dest-filename": "semver-7.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7", - "sha512": "3e878625887c1cae014cefdaf537fa646def7a8fc0ed956c62b480e89f27cbd9dbdc1d55ae992e37ecfd384e707c4e69e87e0b721619b1e8224206c90fde1915", - "dest-filename": "semver-7.3.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820", - "sha512": "509601eb0152244dc6d349c48af479ae05a9f1cdb15ef27738f58f866bad794d082a3f2729b1b70eb8e23a62f0a671c6616015c00ebdce64e6fbe606d079b0c3", - "dest-filename": "send-0.17.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18", - "sha512": "f08f138d6e4a30e2ac6504efa318ee4886bb7e80303d618eb6cfbaa3bb208f3e35fea303f55407103c62e8f06f2b6974317526a99c8da542be4f6b5069a125bf", - "dest-filename": "serialize-error-7.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa", - "sha512": "19a340e78dfcd2e15e7d68213830561068ac2d9163d349d2e400aceb21daf672ea94ba552cef0284319e2918d99d5e0d8789f4422ee7858643ffd7c23f312a93", - "dest-filename": "serialize-javascript-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8", - "sha512": "42bdd3a2cbe0b85b7c78f5aab2f45facac905c8896fa719b629cbc5cadb83501c4f3771ac56b7e988ca64d3d7d0c615b35634b7c4c2cae44a637ae2555607d6a", - "dest-filename": "serialize-javascript-6.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239", - "sha1": "d3768d69b1e7d82e5ce050fff5b453bea12a9239", - "dest-filename": "serve-index-1.9.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa", - "sha512": "f9330d03d005c54106b82d33da67afa204a79fd31729be1f6bb9e079130969a1aff2f4f09c81242a2f901af3eddf71d29dff29452f9618cd046ccb4224b28c05", - "dest-filename": "serve-static-1.14.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7", - "sha1": "045f9782d011ae9a6803ddd382b24392b3d890f7", - "dest-filename": "set-blocking-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b", - "sha512": "2711dcd7078237af30458d1f842a17a722b9e66fd73c769f3a62b85160fb9b6088d7818c705ca9b78c3fd3e355e5ffd931bcb617a4b6c3003b7e0ca787d8164b", - "dest-filename": "set-value-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656", - "sha512": "06f13f4f0a595f8157131c4ec59c9119042feb9d4c4b09962991aabe63dc4488c3a96b9bebb9132ae20cc78ddc659ad2fdc041cf005c3435a8171b765c4148a5", - "dest-filename": "setprototypeof-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424", - "sha512": "1392c35fb5aba7ce4a8a5e5b859bf8ea3f2339e6e82aae4932660cde05467461fcc45a4f59750cb0dae53830ab928c4c11e362fd7648c2e46f6385cdc18309a7", - "dest-filename": "setprototypeof-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea", - "sha1": "44aac65b695b03398968c39f363fee5deafdf1ea", - "dest-filename": "shebang-command-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea", - "sha512": "907c6bdb366962d766acdd6a0e3aeb5ff675ad1d641bc0f1fa09292b51b87979af5ecc26704d614d6056614ce5ada630d7fc99a7a62e0d8efb62dbdb3747660c", - "dest-filename": "shebang-command-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3", - "sha1": "da42f49740c0b42db2ca9728571cb190c98efea3", - "dest-filename": "shebang-regex-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172", - "sha512": "efef9d161b5cc77df9dee05aabc0c347836ec417ad0730bb6503a19934089c711de9b4ab5dd884cb30af1b4ed9e3851874b4a1594c97b7933fca1cfc7a471bd4", - "dest-filename": "shebang-regex-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf", - "sha512": "ab95cfcada85108287906762308ad8d749af2d1be7421e36ffe1a8065156ddbd8b5cb136c71269645766f78c1ed016a85774702721aa839c12edea714efd19bf", - "dest-filename": "side-channel-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af", - "sha512": "b03978a8c1698a3706c36d94e70eb72a60f771925f06e16554d6d530a8deda47a828c2fb5f653359b7385eb9846c3c20d0d5c9737cafe3fa31edbf8959be7b91", - "dest-filename": "signal-exit-3.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787", - "sha512": "a52cafedb4930bb8a0f437206f0f40b913546f993957aa03b9d8d9a0c052af5deaa4b046eed07ece00a40118eaef121481dcf93f541ef2efab486768b8e388c9", - "dest-filename": "slice-ansi-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae", - "sha512": "f7884ad0787cacfa90976c577371ec681a0e5ca576d0c4e83e4717bf06c84962c4b3eeb8b01ab9905827da42431dbd4faf2f72acfd1dc6b088f5145c8bb4572a", - "dest-filename": "smart-buffer-4.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b", - "sha512": "3b6ee5e3168c62dfd1490e53477be9582001e4a6ff73321ca9414e33f0b87d870b9db6547353e48d300c8e87f6a4159a493c0e51deaa5077051951a3eda2309f", - "dest-filename": "snapdragon-node-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2", - "sha512": "99b2a431d40ab235f80402f86d16138f6d5e74e7fc70ded71dd6142447be667f7d85511870cbca3dcb7522a35eefe0193e2ae7f01083390047419927aa62a565", - "dest-filename": "snapdragon-util-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d", - "sha512": "16dc8e9d637fc021d355738cc2f4afdba77e928e6f5a52030face8509ecb5bcbe1f99042f107658ef7913fe72b36bb41c22a04516cbfe1d32d6c18c0e22a0d96", - "dest-filename": "snapdragon-0.8.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.2.tgz#4bc48c2da9ce4769f19dc723396b50f5c12330a3", - "sha512": "6734713c1212404ed1a73947e2d2893106c733da5a6c796e9345816b1010fb09bf52279e055068bb4a78c159d240637d426a40672810d1c0c8ca95aea8e16615", - "dest-filename": "sockjs-client-1.5.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce", - "sha512": "18980b4d9eef61bfc9b4f492675d21b0e608bc462c8db354fb33dd20771469654d5043e2bf3c64bb7d7ceb9b124ae7740dad16e2511e38f966c3ddf32d0721b9", - "dest-filename": "sockjs-0.3.24.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad", - "sha1": "441b6d4d346798f1b4e49e8920adfba0e543f9ad", - "dest-filename": "sort-keys-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34", - "sha512": "aa743b81533118dc6c88be2512e2707bf4e8f149caedf02799b184107f11a4ba2eb8a6de126d2585b415148acd4ae07e1bbb55ac0955b198044d3e679637fe23", - "dest-filename": "source-list-map-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a", - "sha512": "1edcfe467b175a4e7e3f6b25c79261dd0ebabe1423d429659b4cef9da63df3e345c7e0efd8217f7f93bfb7cc7e29a35dadd200b2bb8dce887f2a989a95ba809f", - "dest-filename": "source-map-resolve-0.5.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f", - "sha512": "b811d4dcbddccec232617297f3c7ddac6a2fc5d482a13183459e92617b524712d95331e0e4fffae87b7aba85251eef4466877e8a75e12a8dea420c17513ff2d7", - "dest-filename": "source-map-support-0.5.21.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56", - "sha512": "70f8853932d42af245220e1229549ccb88a53cf5baac580c81fb9924f3680ee32cde70b51db314c9c068270efbc45229eb3d5425024e7f1e82f46307f340e24f", - "dest-filename": "source-map-url-0.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc", - "sha1": "8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc", - "dest-filename": "source-map-0.5.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263", - "sha512": "52381aa6e99695b3219018334fb624739617513e3a17488abbc4865ead1b7303f9773fe1d0f963e9e9c9aa3cf565bab697959aa989eb55bc16396332177178ee", - "dest-filename": "source-map-0.6.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383", - "sha512": "0a40a3ea088ddd2fa7f6aad88814d7e60cacb6510d9d15b98d978d2c7a5ee9ab9ef92ac7706e55630ba3856f6ce1d637d66106b31043ac747aa08ebd7d35ec69", - "dest-filename": "source-map-0.7.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9", - "sha512": "70e61c516c210ae1c25e2e3d4611510b22442b788f8f5662cfd0e9562577b5b64ec170f8f50cc837732938b24dc61daac2ada524965a28c570f6a362e234c2d3", - "dest-filename": "spdx-correct-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d", - "sha512": "fed4eb60e0bb3cf2359d4020c77e21529a97bb2246f834c72539c850b1b8ac3ca08b8c6efed7e09aad5ed5c211c11cf0660a3834bc928beae270b919930e22e4", - "dest-filename": "spdx-exceptions-2.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679", - "sha512": "71ba87ba7b105a724d13a2a155232c31e1f91ff2fd129ca66f3a93437b8bc0d08b675438f35a166a87ea1fb9cee95d3bc655f063a3e141d43621e756c7f64ae1", - "dest-filename": "spdx-expression-parse-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95", - "sha512": "0ad97606b1623345f7300358823dc29328318519abf668bac617a36dd3bdeb49c5e840c90294d8a67d014270ca96734150b2a208dd67df0f440641caf195a0fa", - "dest-filename": "spdx-license-ids-3.0.11.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31", - "sha512": "86c2d5144e528c0e930a2b167895c52a788618ea4180c2e67ab7ced9a0b2094e6cee727fae901ea6a98589fbff1826d26ee7847802499e6490dab282fe0f0573", - "dest-filename": "spdy-transport-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b", - "sha512": "af8ea065065057e2a5f6822dbe5d49659a89286afea04901d3c03a07392247be7ddffec86edba77171ddd98a18793b06e35e7b66cb0cbbd298bd41cb723703a0", - "dest-filename": "spdy-4.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2", - "sha512": "3733558490d8a7071e5558a2f3f1eee8329f0f61be36b407952fd5fea82fefadc462e755c0470c40dc5dda587ed15ad40725cdfe826497982b3a1616bd05188b", - "dest-filename": "split-string-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f", - "sha1": "cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f", - "dest-filename": "split-0.3.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c", - "sha1": "04e6926f662895354f3dd015203633b857297e2c", - "dest-filename": "sprintf-js-1.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673", - "sha512": "544d123951070a4ed073cba5916c379ed0335eea9fed2da5bf041a0cb46751e20468a35027357a07098b2a13aa4fad5a1a17d432b5de68193ea03182cef85cba", - "dest-filename": "sprintf-js-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ssri/-/ssri-7.1.1.tgz#33e44f896a967158e3c63468e47ec46613b95b5f", - "sha512": "c3e75a0b35cdf3d3ec7932fdf4c900f9fc4911c537c1f684fda8748b49673a5a46d4260b276663cc4af2ebc60129f2ece097e84d286b4c4b0990066e359fecb7", - "dest-filename": "ssri-7.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/stat-mode/-/stat-mode-1.0.0.tgz#68b55cb61ea639ff57136f36b216a291800d1465", - "sha512": "8c7f4486d2888ee5d9d9c5b19974bc64ff345f20b789ab10c4c0d5f23ce1349a5f0dbed56d02d55b85afb31cfd419bf357e1b862849f05454a0cecb12f38bfb2", - "dest-filename": "stat-mode-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6", - "sha1": "60809c39cbff55337226fd5e0b520f341f1fb5c6", - "dest-filename": "static-extend-0.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c", - "sha1": "161c7dac177659fd9811f43771fa99381478628c", - "dest-filename": "statuses-1.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14", - "sha1": "4d5e433c185261dde623ca3f44c586bcf5c4ad14", - "dest-filename": "stream-combiner-0.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713", - "sha1": "279b225df1d582b1f54e65addd4352e18faa0713", - "dest-filename": "strict-uri-encode-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961", - "sha512": "bda7dcbfa2a3559292833d3aa0cfc7e860c1ac0b73f2f76141a9068c522f36b1c0eb2dc7085d422272f2f902eaf1d4c93d0d5bf8a0d4a8315cb647515b8e1ed7", - "dest-filename": "string-width-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010", - "sha512": "c0ac90450a63274b08a7ad84ad265d1ac8cc256b1aa79a1136284786ee86ec954effd8c807a5327af2feb57b8eaab9e0f23fdcc4a4d6c96530bd24eb8a2673fe", - "dest-filename": "string-width-4.2.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80", - "sha512": "cbdc428f0d4fdb703093c12f4e97322f6348af58fbc09dfd7fe93a96f46748ccfe9b3f421b3f4d60f7a50e4e3690ecfafaa97cc637caf28633cb78c03f9414e4", - "dest-filename": "string.prototype.trimend-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed", - "sha512": "8e1e9ef7ce0e05fbf14b9d2d758da74599e80b9fe62c528e44441fc3cb79cb2b64a14b0944dc6f23f137f6abb5b03d0eb56237382d1780a4a6716c338b062e67", - "dest-filename": "string.prototype.trimstart-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8", - "sha512": "9ff4a19ef0e2e851db6d57ef8aba3e5a88e2173bfeb3c30f30705ccd578f7d4a4324bc282d3d21b759786300426e2f29240bde104767907c8fc933ff9b345fc2", - "dest-filename": "string_decoder-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e", - "sha512": "864457f14d568c915df0bb03276c90ff0596c5aa2912c0015355df90cf00fa3d3ef392401a9a6dd7a72bd56860e8a21b6f8a2453a32a97a04e8febaea7fc0a78", - "dest-filename": "string_decoder-1.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf", - "sha1": "6a385fb8853d952d5ff05d0e8aaf94278dc63dcf", - "dest-filename": "strip-ansi-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae", - "sha512": "0ee46cd6029b06ab0c288665adf7f096e83c30791c9e98ece553e62f53c087e980df45340d3a2d7c3674776514b17a4f98f98c309e96efbdcc680dc9fa56e258", - "dest-filename": "strip-ansi-5.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9", - "sha512": "637f153d21dcaa416b0a916743dbee4979aabaebf9a1738aa46793e9a1abaf7a3719cf409556ba2417d448e0a76f1186645fbfd28a08ecaacfb944b3b54754e4", - "dest-filename": "strip-ansi-6.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3", - "sha1": "2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3", - "dest-filename": "strip-bom-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878", - "sha512": "df1bab16fe6d1208a2df7662f09b69e79c042082d1f5e877e05016d343d97fe2674ac4e657f8a87b04a0425f7b247be08e8446c0f4a1b169be21daf1077e5dd3", - "dest-filename": "strip-bom-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf", - "sha1": "bb43ff5598a6eb05d89b59fcd129c983313606bf", - "dest-filename": "strip-eof-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a", - "sha1": "3c531942e908c2697c0ec344858c286c7ca0a60a", - "dest-filename": "strip-json-comments-2.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006", - "sha512": "e9f3dcf91e22870a8fe8dfda22fd9fd60307f25395b56407a2a0b8c8aea8483555a1cba602c7c2aa39179ea89832198cc12fe61072e9ed57a196ddea97a9448a", - "dest-filename": "strip-json-comments-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631", - "sha512": "939e72c4a1f06979e9606b0ece0e1597cfad0eb5b29710c4a649c68e14e2641f1d151539ad3a3d080cdec9c8afc55decfb39532b0aece96c4cc51f799f6ea4c2", - "dest-filename": "strip-outer-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.4.tgz#302aea64c0fa25d12a0385069ba66253fdc38a81", - "sha512": "18ef0870517d1a6143bea76e22ca540700b309bab37a0c95288b12ca670c82264a7827eb37d4a8c2d5288bcf9be7d5993008c8cd566273f16df7bfa9ca747723", - "dest-filename": "strtok3-6.2.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e", - "sha512": "57b4c2391928f2bb3dac8aa44ab94c7e4a80eb70dfa060412662b590a1827128be0566f872acf4491b27a7897aad4e62c0e11dd3fd9e3efebc495db6557a27e1", - "dest-filename": "style-loader-1.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42", - "sha512": "32f8d7ce4cff04e7f2543906d2814eb41c475f6bb780a6cc1c817f7576e566c803dc158e14b987a2f229658ec1ca425d02372a442062d5660135d102f7223bbe", - "dest-filename": "sumchecker-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f", - "sha512": "423563c1d5c8b78d3c308880a825f8a142ac814d84a801b3b363e9926e1a4186e39be644584716e127c5353af8b8c35999ad1ecb87f99602eb901d1a5f440ca3", - "dest-filename": "supports-color-5.5.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3", - "sha512": "a9ed637e6d4c83b36afcd4a1e97136e203d744e115b161f10b52c8c7ffd73650fd8b0ed86501a364d8d837bc466841ba88a740f04b4d156e91d208e7557a7ec1", - "dest-filename": "supports-color-6.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da", - "sha512": "aa9080bd197db2db8e1ef78ab27ec79dc251befe74d6a21a70acd094effe2f0c5cf7ed2adb02f2bf80dfbedf34fc33e7da9a8e06c25d0e2a205c647df8ebf047", - "dest-filename": "supports-color-7.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c", - "sha512": "3295043763a876d533c6f29097bd9c505ed14391221ec1af4ac546d226bd73945b5862f6088e02ec4a4f4bc513048a659e5cd988db95e7ac3e16e371cb7b72d9", - "dest-filename": "supports-color-8.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09", - "sha512": "a2dd169d74bd7e076480871e3dee911cd935580f3e9ae3dae9c4a3791dd5f0adbbabd041d6b4c4dd1d69ec7bf4cf567201cf2ce95beff0323259febcd4c02dd3", - "dest-filename": "supports-preserve-symlinks-flag-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2", - "sha512": "e162bf6d86668fcc4bafe1d408e0c7185d59173b187df6ac2d480488c058e1f82d96d74ee81e1626d9526cf6834cba584dc195c0cdaa2e715320211c371b3790", - "dest-filename": "tapable-1.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0", - "sha512": "18dcd0bd04ce20fe91c937c4d90c5bf19565366c349fcf2fa75b33c1646298fd369a74ecc775ad9f9a9176a63dc365ddb8535482f3b084d9d0b23c02a7e92a69", - "dest-filename": "tapable-2.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/temp-file/-/temp-file-3.4.0.tgz#766ea28911c683996c248ef1a20eea04d51652c7", - "sha512": "0b9b63942fc70ad5543a2dca595a24778bc755588e9868ed2f0221e0cbb33e8fe73184d5fe9d6eaeddd19cccf62165c374a106247de4e7e28fc6da91b14606b6", - "dest-filename": "temp-file-3.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz#894764a19b0743f2f704e7c2a848c5283a696724", - "sha512": "fdf2b0dd1fa15b21df631ec1bfaa0faa69381c641cad62ed5775fa820bcfbb03cd1d29f3bd5579d73e8e69a08ebace182e3bad6063b3de91296e17ba529dacd7", - "dest-filename": "terser-webpack-plugin-2.3.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f", - "sha512": "2cf222b22dce978721c0068f3fcb68509dcbe2a08cd46d306a8ecbdea36fe7b0eb7b3c63ebe544cb24a93f0e01d4748ed8483f84363f30d1795e2842028aa7b1", - "dest-filename": "terser-webpack-plugin-5.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17", - "sha512": "1003e2a5335e5ac6ffdf02cf7aea75b553da5df21a53af3132755d3da7c82f54d5d393a101202b63221f16f9ef24236b4763483af0d534d4c545af917b6316cb", - "dest-filename": "terser-4.8.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc", - "sha512": "00c985f7d0cc7c40e24497f17d8e638f9c0d1ff6d83b4f5c9e24aa85fa32c5cf2c168608824272f3a1b4e14a195395639699e9955bb42ba4f1e84f5be7e0e51c", - "dest-filename": "terser-5.10.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5", - "sha1": "0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5", - "dest-filename": "through-2.3.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d", - "sha512": "78763b9c17ed813841a8ec8719537e97c805d01b9c3f4f5f328d283bf2dbd30d4e17cd1d26ffa50d5a571bad16310be47310243726cab2b10813766d28698fac", - "dest-filename": "thunky-1.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7", - "sha512": "47033b3283e88cfc6c381627c9dda1cb46f1b48955ae284db3da63e5252f63c673d6c41c406dad1b5852afc3c3c5f80407c44d28386a6c896ba086ab48d0cdb1", - "dest-filename": "tmp-promise-3.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14", - "sha512": "efa49486d7ea4762239fec6595c2393f5a326a79c73470720fcd16d6ae38ee05379a9f46f4f4a919d5a68d43874433e21d869c224eba5bbb9b0d3b8f177044b5", - "dest-filename": "tmp-0.2.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e", - "sha1": "dc5e698cbd079265bc73e0377681a4e4e83f616e", - "dest-filename": "to-fast-properties-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af", - "sha1": "297588b7b0e7e0ac08e04e672f85c1f4999e17af", - "dest-filename": "to-object-path-0.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771", - "sha512": "22adb95c1b7acc3e67a4f8652d55c614ddff832476fea38370a34dc9331de2f6e6dfd1d468e8803383ccab478c542fd3931cfe66376c739e60f72cb3f98ab4d1", - "dest-filename": "to-readable-stream-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38", - "sha1": "7c80c17b9dfebe599e27367e0d4dd5590141db38", - "dest-filename": "to-regex-range-2.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce", - "sha512": "156b6578d02d67f2a2daab6a7a3d825d339ac8e1fd6c70d017e438f15a56c835e36d8c40e18cfc883077d735ce05494e1c72a27436ea195ad352f40c3e604607", - "dest-filename": "to-regex-3.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35", - "sha512": "a39b123ca12483f0c840d987e37574fee7ab2eba7355e764521f2d18dbda797a5fa6ec2329e9e54a8c7fd8efc14e5654b447be246eece58844cfad3c3e500744", - "dest-filename": "toidentifier-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/token-types/-/token-types-4.1.1.tgz#ef9e8c8e2e0ded9f1b3f8dbaa46a3228b113ba1a", - "sha512": "843f90cae500c88daca73b08d01ee07ff8c9da0811e118e4028dfb8f74adb9e3e1029254c1c5838e71c33857485984b0351dbc1f5e21a709b8108f95d5379dd7", - "dest-filename": "token-types-4.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a", - "sha1": "8184fd347dac9cdc185992f3a6622e14b9d9ab6a", - "dest-filename": "tr46-0.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21", - "sha1": "e3646a2ea4e891312bf7eace6cfb05380bc01c21", - "dest-filename": "trim-repeated-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b", - "sha1": "405923909592d56f78a5818434b0b78489ca5f2b", - "dest-filename": "truncate-utf8-bytes-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00", - "sha512": "5e78b7e4d2b38e032bc1ebf2b074c202bb4b0e93efc9ef3357fd04e04c989f8dcfeffeeabd0c0f87d0469077b06ccba5567b5b8a099c4fbadd5f704da3dc1126", - "dest-filename": "tslib-1.14.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01", - "sha512": "efb11bc8f3e9333f8544546e00595632d9a051619ef54386d99db936a0b08888d184e7f988a1aecd27b93f6c3595aabe164472e29f8f0ae5642521a4cd310a57", - "dest-filename": "tslib-2.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c", - "sha512": "d61fcb9eaf726a3298d8f11b05a74f5e3dd5c6c0c3bbce383a7680a39d9456623322fc30b413c8b8dbe48eecc19535a97c9c946c6ddecf42920626d0923e288e", - "dest-filename": "tunnel-0.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934", - "sha512": "df847b1d39c6d172097014a7e5784377b9cd14f45c5d8459ac10763b68dd2aa60e0e5752cc102acec5a865862f76e932ef7b68612fc44aac4fbe40dffc5d1732", - "dest-filename": "type-fest-0.13.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4", - "sha512": "35ef9e138af4fe25a7a40c43f39db3dc0f8dd01b7944dfff36327045dd95147126af2c317f9bec66587847a962c65e81fb0cfff1dfa669348090dd452242372d", - "dest-filename": "type-fest-0.20.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1", - "sha512": "c864b36bbe31934506f24fa92e1e687a8622aef2225a8e6dd3fa37cc71c03b6b510e265cc563fb7f2c0d95786a6fafebeac5afc22f91b3240c5a154b7b8055b8", - "dest-filename": "type-fest-1.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131", - "sha512": "4e444aafdb144f1107f0c75fb8248fed58b3272cd134c8e3d89d9da3626bdcaca6e7df0955d124b2eccf4029e514f5b8932f50fa203e99af411a6d3a5d0072f2", - "dest-filename": "type-is-1.6.18.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080", - "sha512": "cddbbc5cc3440dea4a291f9760e5c054fb56ba2d25cb436da2152c730f9499a1e20164fc86b575aebfff1fa57ed03bc9dce435f52f7bf4cd2568b7d7f2b9bcd9", - "dest-filename": "typedarray-to-buffer-3.1.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777", - "sha1": "867ac74e3864187b1d3d47d996a78ec5c8830777", - "dest-filename": "typedarray-0.0.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3", - "sha512": "4c24c8ba5ef42f259ee882564fc41261e039e1641ef048d0154e30639d856ac8f950ac7cf0b35828280110770e30eac5175aca19b0fcbffc5c356554abd4b298", - "dest-filename": "typescript-4.5.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471", - "sha512": "b5953fdcda8addd0398291352adca2254ac40749719c690c147a6d27baba7b0759f2cd7642b383c0d6e12094ad98991dd500d76b535103c685d80d7393f629cb", - "dest-filename": "unbox-primitive-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/underscore/-/underscore-1.13.2.tgz#276cea1e8b9722a8dbed0100a407dda572125881", - "sha512": "7a4635361473ab4074f20e1b1ae5f8c1dda3671e469cacfa98a4aa14be27a8195fc8c1a21b5d200c58434cc11f6260cbe89cb4154219a7bc22441fb404fec9da", - "dest-filename": "underscore-1.13.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc", - "sha512": "c98e4fa4395f548539fb2fc1482c402510484b565cd9d0c6dd48eafac47453e26351ebd6d8986870e17eb2844e60349a01eccecce2aecb28b1843ea60649d299", - "dest-filename": "unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3", - "sha512": "e646990ab6e9e6699bcf9ba50640e46d8d12b0f3a32aa552df95692fdba530f7d29742745ec9bef44be986ff42a08645c2b7bb689a1af78018eac78c28654de5", - "dest-filename": "unicode-match-property-ecmascript-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714", - "sha512": "ed886473461efade0f358cce18a79d0e15db60805ed57110610c4e3f285c5cd309d1608006aaa3e9c93275dea95916531d5e06b823ca74101488c73ad2db0a57", - "dest-filename": "unicode-match-property-value-ecmascript-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8", - "sha512": "e597eecbdabf0c5af8b5f3bb64f7955dbd5a3e879049d78530ba58b8579b7a10c085bb9ebcbb39cb149998814dd6d3f917d5a5e08a49ad8a2383ce7fce0c991d", - "dest-filename": "unicode-property-aliases-ecmascript-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847", - "sha512": "b497d79b131e5989dccc256ced7004bc857b89ea6900b7727a958c90793072246966b686ff1c13facd8937cfa9af5fbc8c245ff34145cefafe32941e7a81785e", - "dest-filename": "union-value-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230", - "sha512": "566a748c8a76967df95135eeaf2be3ce48c6751c9ff5bda54d7b9261488f9b345c977143b58a80c0e9d3264027803f525a19e82730db4cac1a3ab67e493b7135", - "dest-filename": "unique-filename-1.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c", - "sha512": "ce85abf4e6dac402c3dc338f7e33d2ab1b787e766259b9711c881e5aa5bcc7b52a0f312d1c440bce38b672e258405094e8a9a826290e600665ad31c779b8f1db", - "dest-filename": "unique-slug-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d", - "sha512": "b8d69e8ab10fbe96564a0cf0b0f1ad536cd5493ae7ffc2f9abf21ec59987d1e1fa480ef70a6000e54e06c0e453c50019b3de530172cda9e2e83cf34ee6065f5a", - "dest-filename": "unique-string-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66", - "sha512": "ac125e2390970259b2d6957eeb5ed607d27add4e9771acc71c5d9fd9d6c98b1e17ce9505d114b765b8f414620e080bdae4ffddfc604e61a002435c3ed1acd492", - "dest-filename": "universalify-0.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717", - "sha512": "84066c2aaed8cb5d59bb50c4d0ecd68f0ee79cb6662596130d96721051d9754855f05907e4c09fa14d5731ac57a2fa725b99eae6c70faaad190cff59ca5d38a1", - "dest-filename": "universalify-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec", - "sha1": "b2bf4ee8514aae6165b4817829d21b2ef49904ec", - "dest-filename": "unpipe-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559", - "sha1": "8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559", - "dest-filename": "unset-value-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894", - "sha512": "699c06a5a9853bad60dce95f4fb390087aa11a75b8de2787f5665e3fb43137f1bf8d2e237ea524671a2bcaf26054f11cae5e4d2ff8201ec4a62cc1ee1fae0b86", - "dest-filename": "upath-1.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9", - "sha512": "22d9c80876de321f46a94cb7d6114fac3d6472e677ae9c4365b7f82940dabd7c12d1b5b99bb48b6c3429197dd462bd3bd9c6eb17984552cdebe6d52c3f08df1f", - "dest-filename": "update-notifier-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e", - "sha512": "eeb294cb2df7435c9cf7ca50d430262edc17d74f45ed321f5a55b561da3c5a5d628b549e1e279e8741c77cf78bd9f3172bacf4b3c79c2acf5fac2b8b26f9dd06", - "dest-filename": "uri-js-4.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72", - "sha1": "da937f7a62e21fec1fd18d49b35c2935067a6c72", - "dest-filename": "urix-0.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2", - "sha512": "dc14d5f35dbe0151c738940ef0ee4c916819e5aa2c3fb1a744e270bf32d2f615838f4d2567a674c0d6a4e36dcba7d3c164dd3937e264fcde528bc8d10251b258", - "dest-filename": "url-loader-4.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c", - "sha1": "16b5cafc07dbe3676c1b1999177823d6503acb0c", - "dest-filename": "url-parse-lax-3.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.4.tgz#e4f645a7e2a0852cc8a66b14b292a3e9a11a97fd", - "sha512": "213780072596a2abad14295cfe54599c5a6581780466bdd627a5e780c33f37d0cc226e0af335cf099d4976ed2b111c0ef38c35582e709257b6b9bc1303835306", - "dest-filename": "url-parse-1.5.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1", - "sha1": "3838e97cfc60521eb73c525a8e55bfdd9e2e28f1", - "dest-filename": "url-0.11.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f", - "sha512": "73011255794edeeae5f585a5156fd303d72c842121b6eec8289fe9e6ca09fe01a98fbbdbbc5ac063f7888a843a0f0db72a3661620888a3c1ceb359d0dafaffa1", - "dest-filename": "use-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61", - "sha1": "f45f150c4c66eee968186505ab93fcbb8ad6bf61", - "dest-filename": "utf8-byte-length-1.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf", - "sha1": "450d4dc9fa70de732762fbd2d4a28981419a0ccf", - "dest-filename": "util-deprecate-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030", - "sha512": "8beeaa03630f86fa0a2eec6724da57006860ec7a6140e494ab62ca3190f49b5e448ac91752432f29d17852e8b459878250679afa8d9cc3f66ec1e86d7ecacd90", - "dest-filename": "util.promisify-1.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c", - "sha1": "8a16a05d445657a3aea5eecc5b12a4fa5379772c", - "dest-filename": "utila-0.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713", - "sha1": "9f95710f50a267947b2ccc124741c1028427e713", - "dest-filename": "utils-merge-1.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee", - "sha512": "1e3483470ea0644e4932081cb4705c8d56a4d3cf8a1158522220f31674fd4bd69e826a7ce52fdb45e0554dbe104c5691369b49f64b9868d8676cd10e91b29bfc", - "dest-filename": "uuid-3.4.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2", - "sha512": "f8d62cd9078c5b2f865853849bdc679fa1c20e9d25ed0043ee697cccb52627ef77439345d0da1c12b9f09139175453625f7fdfa42e9a7d2f0385bfe0cfb47b7a", - "dest-filename": "uuid-8.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee", - "sha512": "97c9421262dc2d8661e276ee9cd66f40225ce69bfbf910b06bcabf2dd531f2eee5b16bcf0ca9a9a1d24024dc24021242fff745638f0ab881268ed778455883ac", - "dest-filename": "v8-compile-cache-2.3.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a", - "sha512": "0e92a6d948bfc4deff1d0282b69671a11581859f59d24aadca01bc5c280d43c6650e7c6e4265a18f9eba8fc7cde02bb7fc999b86c0e8edf70026ae2cf61dbb13", - "dest-filename": "validate-npm-package-license-3.0.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc", - "sha1": "2299f02c6ded30d4a5961b0b9f74524a18f634fc", - "dest-filename": "vary-1.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb", - "sha512": "bdeb9f726c6b8b87b75d2ad3d31c1f511ee482e2246b105ea2c0e0d34c835a1938f7077091252bbefb26ee773be5ed4f532bc87998fa9d2f15411633dbf4b85e", - "dest-filename": "verror-1.10.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/vue-devtools/-/vue-devtools-5.1.4.tgz#265a7458ade2affb291739176964256b597fa302", - "sha512": "1010045ef0075229ec3f3a12884969b34260b4b5d49c95ca2096cfea77ddcff47add574a04c7c9df8feb162a7ee224fb88c6d54b9940e16e8dd63ab81e3e0b0a", - "dest-filename": "vue-devtools-5.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25", - "sha512": "c74b7426ec9d228f2a08d72d743ae7d4ecc7fea0f3936fab742382dd8cee999e367e232a990ed3df142eaf291832161f1da3c74e9e19c40c7635f528d4ae9068", - "dest-filename": "watchpack-2.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df", - "sha512": "3bce103a7af489cb1b1462d2d0eddb23916cc31cd1afcfe01f05a40e5405b248523ebc905efad33318f118fe3e8966286ae2e806f7c3a64ace6ae67ed226690c", - "dest-filename": "wbuf-1.7.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871", - "sha1": "24534275e2a7bc6be7bc86611cc16ae0a5654871", - "dest-filename": "webidl-conversions-3.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a", - "sha512": "3555816b3f64f37f591ffb229eeaccf87703bc93935f04a3629d64bbee5729e382d37cfcbf9422b672bfc7e940c465c5ca175aca821ffc63a9bfce73dffc4f6a", - "dest-filename": "webpack-cli-3.3.12.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5", - "sha512": "7637a573fcc68b3f67663fd4ecf4c18b6562a2b1895c45a8ff796d90f6c3cb1097861117916d1c7bdf5f6a56a89384cf8fe02cc4b897251d0404e6f4ce1f5f29", - "dest-filename": "webpack-dev-middleware-3.7.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz#8c86b9d2812bf135d3c9bce6f07b718e30f7c3d3", - "sha512": "df1df5ae36c441628c37369c519444eb05ef505b86a47eefaf494811b6293001bd04ec62d3ddbc414d4106cc0e00fde48371f53b88624beb2ae18c809fa00d9c", - "dest-filename": "webpack-dev-server-3.11.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f", - "sha512": "717f06daf47ff395181b9f45824a0c6a6c075089124a55776c1311b1bc555d5524da3e8d95e08a8d0fd613d79883d598e30db93bdc3cc0a3f8af335916651c52", - "dest-filename": "webpack-log-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d", - "sha512": "4d4135506a135f609de368f792b198a8e6d96ce0fec45eeedbc581eed7d4a2b772b528db5932232bff15d1a9a405f4d8378fe907f1880e525967ae7b0461b5f6", - "dest-filename": "webpack-merge-4.2.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933", - "sha512": "9604d2dd786fd6508e2a8ed20394e3297323a52338b018cd579faad9ba9eb1b48fb391631a653a8e3b414a45fd6f8a96f3bbc322c0889543ce1216d9acc76379", - "dest-filename": "webpack-sources-1.4.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde", - "sha512": "fc3c8c10eac380b28a206d1f9afb73fb87545ffdc6868cf0826ea23e9f0a461be7f9e41ff7e43b196c5534c937fae08f59f757602e04c4605c9085dd1447c7d7", - "dest-filename": "webpack-sources-3.2.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/webpack/-/webpack-5.65.0.tgz#ed2891d9145ba1f0d318e4ea4f89c3fa18e6f9be", - "sha512": "439a2bda8e842acefea0a989a3b2daa9968c3a50d642c7bd4e6e65d5601f53fba32c63793dbd12a8679590dff86e93e612a10fe519d5862aac3ad5ad515c0647", - "dest-filename": "webpack-5.65.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760", - "sha512": "6f5eca783210563bdbd2cb2e4831767185d28368b3b65889e01f5676cb81e89f79daa08f2a69d5ab80f25b99a8b489971c30b57014ffd547b3ac956c2b0e738e", - "dest-filename": "websocket-driver-0.7.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42", - "sha512": "3aa79d3c818e7ec0e5a37d5437061b08531268ef66f46ff47da2078f9fdd6450cc16a3d3731e94c2ac8ecb708e11a10e83ff55b0622976a9fad96e4a868292a6", - "dest-filename": "websocket-extensions-0.1.4.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d", - "sha1": "966454e8765462e37644d3626f6742ce8b70965d", - "dest-filename": "whatwg-url-5.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6", - "sha512": "6f065dbf400a2e9a65158d8a6515fa4efcae37ba238ebee5c2483a9a5d2ba08cbd61eb92afb252dfbdaa94d5b5f14418ce060af7388671ead6a993a6127f5536", - "dest-filename": "which-boxed-primitive-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a", - "sha1": "d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a", - "dest-filename": "which-module-2.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a", - "sha512": "1f125d616ab53132106c9de7c3472ab2c1e84cd536ebb2a5ac3b866755989710d2b54b4a52139a266875d76fd36661f1c547ee26a3d748e9bbb43c9ab3439221", - "dest-filename": "which-1.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1", - "sha512": "04b2374e5d535b73ef97bd25df2ab763ae22f9ac29c17aac181616924a8cb676d782b303fb28fbae15b492e103c7325a6171a3116e6881aa4a34c10a34c8e26c", - "dest-filename": "which-2.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca", - "sha512": "36c9a85da96c5950cc1aea71679474f246bd7e56638e22ef1d501660e2ad88a33cba3b595abf5c45f7da93eb92138f3e39bf0e6da957a70c9e522c830fa40582", - "dest-filename": "widest-line-3.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09", - "sha512": "402d7f88dff6fd13d52798d82bc046b6d8f9cfcdcb9922a6bdbbeb5cf3422d94846f7d8a2950c90e5fcc3add8dd35a94d87fc593311af4f2ada3506a0e3b5ded", - "dest-filename": "wrap-ansi-5.1.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53", - "sha512": "afa94f7011b1657948732984bbb227c43321756d0a0f1a4b82814b720b9ab3109a27f48e219c0835ab4af4a63fb5ff99ae5cb038a5345038f70135d405fc495c", - "dest-filename": "wrap-ansi-6.2.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43", - "sha512": "6151888f691a98b493c70e8db198e80717d2c2c9f4c9c75eb26738a7e436d5ce733ee675a65f8d7f155dc4fb5d1ef98d54e43a5d2606e0052dcadfc58bb0f5e9", - "dest-filename": "wrap-ansi-7.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f", - "sha1": "b5243d8f3ec1aa35f1364605bc0d1036e30ab69f", - "dest-filename": "wrappy-1.0.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8", - "sha512": "02f1dcc99e499d27eade2a12ca3ac1907f725b89bb03293cffd332fc30fda2729ebbff787f0acca1c7a63b64002450259e70cdf990d2f998c0479b9ad7f3d5fd", - "dest-filename": "write-file-atomic-3.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e", - "sha512": "ce6865b68491f2ed5c9c3b03e374d7e7d9b3a0c66c2caa94c1ec9804022f4e7811dec85cd16e9a399ca5666abfee1ab25713dd8bee547764089db960c84ef67f", - "dest-filename": "ws-6.2.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b", - "sha512": "e862e00aaa36732d80dab8c2345971412e999631bf72865f65772595d23c141ff51b7082237e9977cc72d87ac55400a2f2d7e4e57ae02d0124f8fd139f3f5470", - "dest-filename": "ws-7.5.6.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b", - "sha512": "29b938371caaeff656aabfed6ab23dc88b7ffa234d14e8c15c45a04dbe3275a34704d1a0bdfd901db4bd7dd7ec9dd7e316517011de0097e9b0f37624683d7464", - "dest-filename": "ws-8.4.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13", - "sha512": "3d23611090de8d9615ee1e7406884bd3d12bf5568879faf62cc01fdce126a429233a2df8798c906005d44e3110b5925329c17413650a4e1fa8b032ec80d8a6f5", - "dest-filename": "xdg-basedir-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66", - "sha512": "c923e2323334fa92c37ed1e05d8e01cb4bacc08dd23ca2c3c3f8b75176e73bc33fa76f33a9ec425283e6405ad80feff5073846252b368b511158a240b622ebba", - "dest-filename": "xml2js-0.4.23.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3", - "sha512": "7c396c23f905131ee02ef6de71cd3fa212c6e747ee810a7caf21f3313b96f6f49ad462745d858a9e1b14c7ba227b71bdf3eaf9e9a4d0214078921b78d91dc9bc", - "dest-filename": "xmlbuilder-11.0.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5", - "sha512": "c8ca8606ab57c9e3757b74c662f80d803559de3f385b873090e5d0b30821a25e803e065669f7fd9676ef37b3076093a25ecbc63d7b634d8244882f49db0bfd12", - "dest-filename": "xmlbuilder-15.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d", - "sha1": "132ee63d2ec5565c557e20f4c22df9aca686b10d", - "dest-filename": "xmlbuilder-9.0.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf", - "sha1": "8dd8bf45fc3f7f55f0e054b878f43a62614dafdf", - "dest-filename": "xpipe-1.0.5.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf", - "sha512": "24a86a4cec12aea340d4d639952ced2751ab06252874b326219b8b88368c449fa2b4577e001544f170633af2162fead2a8d0c2ef82c24859a56ff538519e2125", - "dest-filename": "y18n-4.0.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55", - "sha512": "d297c5cde81e0d62472480264cb44fd83c078dd179b3b8e8f6dbb3b5d43102120d09dbd2fb79c620da8f774d00a61a8947fd0b8403544baffeed209bf7c60e7c", - "dest-filename": "y18n-5.0.8.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd", - "sha512": "6b850641a58f1f9f663975189c01b67b09dc412e22e05e374efdc9a0033eb365430264bd36c2bc1a90cc2eb0873e4b054fb8772ba4cea14367da96fb4685f1e2", - "dest-filename": "yallist-3.1.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72", - "sha512": "df074689d672ab93c1d3ce172c44b94e9392440df08d7025216321ba6da445cbffe354a7d9e990d1dc9c416e2e6572de8f02af83a12cbdb76554bf8560472dec", - "dest-filename": "yallist-4.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38", - "sha512": "de56ec3517ff8fe03842e4997c3440ec74527d6af33b4623a9325de648c0ab7ed97a9d421206989ab1fd4371b03e207d707c9dd58d54c208068491a8c62a5bce", - "dest-filename": "yargs-parser-13.1.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0", - "sha512": "a39d23d09793a32ff82ba39971a4265ba9725d72a1abb72c4445dc0f0936a2614f244c1434e56d24abe60ebf442357c025953265c445ee4c460569915ee76b09", - "dest-filename": "yargs-parser-18.1.3.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee", - "sha512": "cb5d67184953215f824f766ff6ded52a5f90de14d0a13f5ad50cdece1865e91a76d6027f2154d6ed9df2f4459786e5010b64a19dff835f46a7b5e72903048ff3", - "dest-filename": "yargs-parser-20.2.9.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55", - "sha512": "cfd900a5850e0b0a1e67bf2b7d161859d894fe234bea6c3062592465f268c8c475c69b3e344057e57ed7991a719191e15c9ebe132d342302b1041496f45223c8", - "dest-filename": "yargs-parser-21.0.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd", - "sha512": "017dd9c3988faee37989eeb119120382a913f9986746564c2cc1c0b3cb60ee746bbb2d8d6fe8b9a3d6f082102882d334f2ad5da6bd8b5684bc2924cc62959753", - "dest-filename": "yargs-13.3.2.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8", - "sha512": "69e3dbc4399c616fbe3daa81b09f8761417009dbf82d5bdd9e1072efc139ecf228afcfce56f84cac00c51440e1f031c3151bff3bd8b794f86c10d8ceed05f4f8", - "dest-filename": "yargs-15.4.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9", - "sha512": "59400d41e5608cb6cdb04986936d1ffa794780eab3445a6219655a06b60660818034822ede55a3a328b47cd94598992f7e1099e815c835eeff5b63b66d5e2268", - "dest-filename": "yargs-17.3.1.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9", - "sha1": "c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9", - "dest-filename": "yauzl-2.10.0.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "file", - "url": "https://registry.yarnpkg.com/youtube-search-without-api-key/-/youtube-search-without-api-key-1.0.7.tgz#39b348d6416318731430a9316da7900c3744bf4f", - "sha512": "3e3c1e8c5e98029643a93168e3aff8aba210973b54b50b0fffcca07076326a43c7aa28c82a7dfafb251054f4c2f76ffe219b6ac99061a5328fd5b1bab9928ffd", - "dest-filename": "youtube-search-without-api-key-1.0.7.tgz", - "dest": "flatpak-node/yarn-mirror" - }, - { - "type": "git", - "url": "https://github.com/castlabs/electron-releases.git", - "commit": "a3484109f0f0710a65f255e7c8e235aea1f06b24", - "dest": "flatpak-node/tmp/electron-releases.git-a3484109f0f0710a65f255e7c8e235aea1f06b24" - }, - { - "type": "script", - "commands": [ - "case \"$FLATPAK_ARCH\" in", - "\"i386\")", - " export ELECTRON_BUILDER_ARCH_ARGS=\"--ia32\"", - " ;;", - "\"x86_64\")", - " export ELECTRON_BUILDER_ARCH_ARGS=\"--x64\"", - " ;;", - "\"arm\")", - " export ELECTRON_BUILDER_ARCH_ARGS=\"--armv7l\"", - " ;;", - "\"aarch64\")", - " export ELECTRON_BUILDER_ARCH_ARGS=\"--arm64\"", - " ;;", - "esac" - ], - "dest-filename": "electron-builder-arch-args.sh", - "dest": "flatpak-node" - }, - { - "type": "shell", - "commands": [ - "cd flatpak-node/tmp/electron-releases.git-a3484109f0f0710a65f255e7c8e235aea1f06b24; git archive --format tar -o ../../yarn-mirror/electron-releases.git-a3484109f0f0710a65f255e7c8e235aea1f06b24 HEAD" - ] - } -] \ No newline at end of file diff --git a/flatpak/org.cidercollective.cider.yml b/flatpak/org.cidercollective.cider.yml index 65a83a73..3a604b64 100644 --- a/flatpak/org.cidercollective.cider.yml +++ b/flatpak/org.cidercollective.cider.yml @@ -1,84 +1,67 @@ app-id: org.cidercollective.cider -branch: main runtime: org.freedesktop.Platform runtime-version: '21.08' sdk: org.freedesktop.Sdk -# Use the Electron 2 BaseApp, which adds several common libraries we'll need. base: org.electronjs.Electron2.BaseApp base-version: '21.08' -# Add the Node 10 SDK extension. -sdk-extensions: - - org.freedesktop.Sdk.Extension.node14 -# Electron doesn't use a traditional locale format so separate-locales is useless. -separate-locales: false command: cider +rename-desktop-file: cider.desktop +rename-icon: cider finish-args: - # These two lines add Xorg access for graphics. - - '--share=ipc' - - '--socket=x11' - # Sound access. - - '--socket=pulseaudio' - # Network access. - - '--share=network' - # If you need to access the filesystem, also add: - # - '--filesystem=home' + - --device=dri + - --filesystem=xdg-music + - --own-name=org.mpris.MediaPlayer2.Cider + - --share=ipc + - --share=network + - --socket=pulseaudio + # needs electron v11 (chromium v87) or newer with ozone enabled + # https://github.com/electron/electron/issues/10915 + # - --socket=wayland + - --socket=x11 + - --system-talk-name=org.freedesktop.UPower + - --talk-name=com.canonical.AppMenu.Registrar + - --talk-name=com.canonical.dbusmenu + - --talk-name=org.freedesktop.Notifications + - --talk-name=org.kde.StatusNotifierWatcher modules: - # With electron-webpack and electron-builder we don't install Node to /app/node, - # because electron-builder will bundle everything for us in one piece. - # Instead we jump straight to the quick start module. - - # However, since this quick start uses yarn, we do have to install that. - - name: yarn - buildsystem: simple - build-commands: - - 'cp -a * /app' - # Only used for building, so clean it up afterwards. - cleanup: - - '*' - sources: - - type: archive - url: https://github.com/yarnpkg/yarn/releases/download/v1.22.17/yarn-v1.22.17.tar.gz - sha256: 267982c61119a055ba2b23d9cf90b02d3d16c202c03cb0c3a53b9633eae37249 - - name: cider buildsystem: simple - build-options: - # Add the node bin directory & yarn directory. - append-path: '/usr/lib/sdk/node14/bin:/app/yarn/bin' - env: - # Set the Electron cache directory. - # (The directory format is: /run/build/MODULE_NAME/flatpak-node/electron-cache) - ELECTRON_CACHE: '/run/build/cider/flatpak-node/electron-cache' - # Sets the directory where Node is located so way npm won't download the headers. - npm_config_nodedir: '/usr/lib/sdk/node14' build-commands: - # Have Yarn use the offline mirror. - - 'HOME=$PWD yarn config --offline set yarn-offline-mirror $FLATPAK_BUILDER_BUILDDIR/flatpak-node/yarn-mirror' - # Download the packages. - - 'yarn install --offline' - # If you were using npm with electron-webpack/electron-builder, then the above two commands - # would look more like the npm commands in the vanilla-quick-start manifest, just without - # the --prefix. - - # Run electron-builder, passing the architecture arguments to it. - # Note that the -- is important; without that, the argument will be passed to - # yarn instead of electron-builder. - - '. flatpak-node/electron-builder-arch-args.sh; yarn run --offline electron-builder build --linux dir -- $ELECTRON_BUILDER_ARCH_ARGS' - # Copy the resulting, unpacked directory to /app. - # (A glob is used because the directory name may contain the current arch.) - - 'cp -r dist/linux*unpacked /app/cider' - # If you passed --electron-non-patented-ffmpeg, you could install it like this: - # - 'install -Dm 755 flatpak-node/libffmpeg.so -t /app/electron-webpack-quick-start' - # Install the wrapper script to start it. - - 'install -Dm 755 cider.sh /app/bin/cider' + - install -dm755 ${FLATPAK_DEST}/cider + - | + bsdtar -Oxf cider.deb 'data.tar*' | + bsdtar -xf - \ + -C ${FLATPAK_DEST}/cider \ + --strip-components=3 \ + ./opt/Cider + - | + bsdtar -Oxf cider.deb 'data.tar*' | + bsdtar -xf - \ + -C ${FLATPAK_DEST} \ + --strip-components=2 \ + --exclude=./usr/share/doc \ + ./usr/share + - desktop-file-edit --set-key=Exec --set-value=cider ${FLATPAK_DEST}/share/applications/cider.desktop + - install -Dm755 stub_sandbox ${FLATPAK_DEST}/cider/chrome-sandbox + - install -Dm755 cider -t ${FLATPAK_DEST}/bin/ sources: - - type: git - url: https://github.com/ciderapp/cider - branch: main - # Add the flatpak-node-generator generated sources. - - generated-sources.json - # Our runner script. + - type: file + dest-filename: cider.deb + url: https://1308-429851205-gh.circle-artifacts.com/0/~/Cider/dist/artifacts/cider_1.3.1308_amd64.deb + sha256: 342abde96bac9668e7238860ba435171edd72077ed9f4b385a3546c4d8f96995 + x-checker-data: + type: html + url: https://circleci.com/api/v1.1/project/gh/ciderapp/Cider/latest/artifacts?branch=main&filter=successful + pattern: (https://.*circle-artifacts.com/.+/cider_([\d\.]+)_amd64.deb) - type: script - dest-filename: cider.sh + dest-filename: cider commands: - - '/app/cider/cider' + # share chromium singleton between multiple session, needed for flatpak<1.11.1 + - export TMPDIR=$XDG_RUNTIME_DIR/app/$FLATPAK_ID + - exec zypak-wrapper /app/cider/cider "$@" + - type: script + dest-filename: stub_sandbox + commands: + - | + echo Stub sandbox ignoring command: $@ + exit 1 diff --git a/flatpak/sh.cider.Cider.metainfo.xml b/flatpak/sh.cider.Cider.metainfo.xml new file mode 100644 index 00000000..9a674783 --- /dev/null +++ b/flatpak/sh.cider.Cider.metainfo.xml @@ -0,0 +1,38 @@ + + + + sh.cider.Cider + + Cider + An open source and community oriented Apple Music client + + CC0-1.0 + AGPL-1.0-or-later + Cider Collective + + https://cider.sh/?utm_source=flathub%26utm_medium=link%26utm_campaign=product-page + https://github.com/ciderapp/Cider/issues + https://ko-fi.com/cryptofyre + + +

+ Project Cider. A new look into listening and enjoying Apple Music in style and performance with Features such as Discord and Last.fm integration, spatial audio support, equalizers, and remote controllable using companion app +

+
+ + cider.desktop + + + + https://github.com/ciderapp/cider.sh/blob/main/assets/img/frontpage-scn.png?raw=true + + + + + + + + + + +
diff --git a/flatpak/sh.cider.Cider.yml b/flatpak/sh.cider.Cider.yml new file mode 100644 index 00000000..252e2ea7 --- /dev/null +++ b/flatpak/sh.cider.Cider.yml @@ -0,0 +1,75 @@ +app-id: sh.cider.Cider +runtime: org.freedesktop.Platform +runtime-version: '21.08' +sdk: org.freedesktop.Sdk +base: org.electronjs.Electron2.BaseApp +base-version: '21.08' +command: cider-wrapper +rename-desktop-file: cider.desktop +rename-icon: cider +finish-args: + - --device=dri + - --filesystem=xdg-music + - --filesystem=xdg-run/app/com.discordapp.Discord:create + - --own-name=org.mpris.MediaPlayer2.cider + - --share=ipc + - --share=network + - --socket=pulseaudio + # needs electron v11 (chromium v87) or newer with ozone enabled + # https://github.com/electron/electron/issues/10915 + #- --socket=wayland + - --socket=x11 + - --system-talk-name=org.freedesktop.UPower + - --talk-name=com.canonical.AppMenu.Registrar + - --talk-name=com.canonical.dbusmenu + - --talk-name=org.freedesktop.Notifications + - --talk-name=org.kde.StatusNotifierWatcher +modules: + - name: cider + buildsystem: simple + build-commands: + - install -dm755 ${FLATPAK_DEST}/cider + - | + bsdtar -Oxf cider.deb 'data.tar*' | + bsdtar -xf - \ + -C ${FLATPAK_DEST}/cider \ + --strip-components=3 \ + ./opt/Cider + - | + bsdtar -Oxf cider.deb 'data.tar*' | + bsdtar -xf - \ + -C ${FLATPAK_DEST} \ + --strip-components=2 \ + --exclude=./usr/share/doc \ + ./usr/share + - install -Dm755 cider-wrapper /app/bin/cider-wrapper + - desktop-file-edit --set-key=Exec --set-value=cider-wrapper ${FLATPAK_DEST}/share/applications/cider.desktop + - install -Dm755 stub_sandbox ${FLATPAK_DEST}/cider/chrome-sandbox + - install -Dm755 cider -t ${FLATPAK_DEST}/bin/ + - install -Dm644 -t /app/share/metainfo ${FLATPAK_ID}.metainfo.xml + sources: + - type: file + dest-filename: cider.deb + url: https://github.com/ciderapp/cider-releases/releases/download/v1.3.0.1555/cider_1.3.0-alpha.1555_amd64.deb + sha256: 8a582ca2758d556cc2d5fad73e05ed3e2f27076e13bf377d1d83d9494aaef9c2 + x-checker-data: + type: json + url: https://api.github.com/repos/ciderapp/cider-releases/releases/latest + version-query: .tag_name + url-query: .assets[] | select(.name | match("(amd64.deb)")) | .browser_download_url + - type: script + dest-filename: cider + commands: + # share chromium singleton between multiple session, needed for flatpak<1.11.1 + - export TMPDIR=$XDG_RUNTIME_DIR/app/$FLATPAK_ID + - exec zypak-wrapper /app/cider/cider "$@" + - type: script + dest-filename: stub_sandbox + commands: + - | + echo Stub sandbox ignoring command: $@ + exit 1 + - type: file + path: cider-wrapper + - type: file + path: sh.cider.Cider.metainfo.xml diff --git a/msft-test.json b/msft-test.json new file mode 100644 index 00000000..5a2ac1e5 --- /dev/null +++ b/msft-test.json @@ -0,0 +1,45 @@ +{ + "electronVersion": "16.2.8", + "electronDownload": { + "version": "16.2.8+wvcus", + "mirror": "https://github.com/castlabs/electron-releases/releases/download/v" + }, + "appId": "cider", + "protocols": [ + { + "name": "Cider", + "schemes": ["ame", "cider", "itms", "itmss", "musics", "music"] + } + ], + "extends": null, + "files": ["**/*", "./src/**/*", "./resources/icons/icon.*"], + "linux": { + "target": ["AppImage", "deb", "snap", "rpm"], + "synopsis": "A new look into listening and enjoying music in style and performance. ", + "category": "AudioVideo", + "icon": "cider", + "executableName": "cider" + }, + "appx": { + "applicationId": "CiderAlpha", + "publisher": "CN=CiderCollective, OID.2.25.311729368913984317654407730594956997722=1", + "displayName": "Cider", + "identityName": "CiderCollective.CiderAlpha", + "backgroundColor": "transparent", + "setBuildNumber": true + }, + "win": { + "target": ["appx"], + "icon": "resources/icons/icon.ico" + }, + "directories": { + "buildResources": ".", + "output": "dist" + }, + "mac": { + "icon": "./resources/icons/icon.icns", + "category": "public.app-category.music", + "entitlements": "resources/entitlements.mac.plist", + "darkModeSupport": true + } +} diff --git a/package.json b/package.json index 7b288392..7c7e947d 100644 --- a/package.json +++ b/package.json @@ -2,75 +2,96 @@ "name": "cider", "applicationId": "Cider", "productName": "Cider", - "version": "1.1.0", - "description": "A new look into listening and enjoying music in style and performance.", + "version": "1.6.3", + "description": "A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance in mind.", "license": "AGPL-3.0", + "exports": "./build/index.js", "main": "./build/index.js", "author": "Cider Collective (https://cider.sh)", - "repository": "https://github.com/ciderapp/Cider.git", + "repository": "github:ciderapp/Cider", + "type": "module", "bugs": { "url": "https://github.com/ciderapp/Cider/issues?q=is%3Aopen+is%3Aissue+label%3Abug" }, "homepage": "https://cider.sh/", "buildResources": "resources", "scripts": { - "build": "tsc", - "watch": "tsc --watch", - "test": "yarn build && playwright test", - "start": "run-script-os", - "start:win32": "yarn build && set ELECTRON_ENABLE_LOGGING=true && electron ./build/index.js --enable-accelerated-mjpeg-decode --enable-accelerated-video --disable-gpu-driver-bug-workarounds --ignore-gpu-blacklist --enable-native-gpu-memory-buffers", - "start:linux": "yarn build && ELECTRON_ENABLE_LOGGING=true && electron ./build/index.js --enable-accelerated-mjpeg-decode --enable-accelerated-video --disable-gpu-driver-bug-workarounds --ignore-gpu-blacklist --enable-native-gpu-memory-buffers", - "start:darwin": "yarn build && ELECTRON_ENABLE_LOGGING=true && electron ./build/index.js --enable-accelerated-mjpeg-decode --enable-accelerated-video --disable-gpu-driver-bug-workarounds --ignore-gpu-blacklist --enable-native-gpu-memory-buffers", - "pack": "electron-builder --dir", - "dist": "yarn build && electron-builder", - "dist:all": "yarn build && electron-builder -mwl", - "msft": "yarn build && electron-builder -c msft-package.json", - "postinstall": "electron-builder install-app-deps" + "bootstrap": "npx -y check-engine && yarn", + "build": "tsc && lessc ./src/renderer/style.less ./src/renderer/style.css", + "start": "npm run build && electron ./build/index.js", + "dist": "npm run build && electron-builder --publish=never", + "dist:win": "npm run build && electron-builder --win --publish=never", + "dist:linux": "npm run build && electron-builder --linux --publish=never", + "dist:all": "npm run build && electron-builder -wl --publish=never", + "dist:universalNotWorking": "npm run build && electron-builder --mac --universal --publish:never", + "winget": "npm run build && electron-builder --win -c winget.json", + "msft": "npm run build && electron-builder -c msft-package.json", + "mstest": "npm run build && electron-builder -c msft-test.json", + "steamdeck": "npm run build && electron-builder --linux -c steam-deck.json", + "format:check": "npx prettier --check \"src/**/*.{js,json,ts,less}\"", + "format:write": "npx prettier --write \"src/**/*.{js,json,ts,less}\"" }, "dependencies": { - "@sentry/electron": "^2.5.4", - "discord-rpc": "^4.0.1", - "ejs": "^3.1.6", - "electron-fetch": "^1.7.4", - "electron-log": "^4.4.4", - "electron-notarize": "^1.1.1", - "electron-packager": "^15.4.0", - "electron-store": "^8.0.1", - "electron-updater": "^4.6.1", + "@achingbrain/ssdp": "^4.0.6", + "@crowdin/ota-client": "^1.1.1", + "@sentry/electron": "^4.24.0", + "@sentry/integrations": "7.114.0", + "adm-zip": "^0.5.12", + "airtunes2": "ciderapp/node_airtunes2", + "castv2-client": "ciderapp/node-castv2-client", + "chokidar": "^3.6.0", + "discord-auto-rpc": "^1.0.17", + "ejs": "^3.1.10", + "electron-log": "^5.1.4", + "electron-notarize": "^1.2.2", + "electron-store": "^9.0.0", + "electron-updater": "6.2.1", "electron-window-state": "^5.0.3", - "express": "^4.17.2", - "get-port": "^5.1.1", - "jsonc": "^2.0.0", + "express": "^4.19.2", + "get-port": "7.1.0", + "jimp": "^0.22.12", "lastfmapi": "^0.1.1", - "mdns-js": "git+https://github.com/bitfocus/node-mdns-js.git", - "mpris-service": "^2.1.2", - "music-metadata": "^7.11.4", - "node-gyp": "^8.4.1", - "qrcode": "^1.5.0", - "qrcode-terminal": "^0.12.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "run-script-os": "^1.1.6", + "mdns-js": "ciderapp/node-mdns-js", + "mpris-service": "ciderapp/mpris-service", + "music-metadata": "7.14.0", + "node-fetch": "^3.3.2", + "node-ssdp": "^4.0.1", + "node-ssdp-js": "^0.9.6", + "qrcode": "^1.5.3", + "request": "^2.88.2", + "simple-ssdp": "^1.0.2", "source-map-support": "^0.5.21", - "typescript": "^4.5.5", - "v8-compile-cache": "^2.3.0", - "ws": "^8.4.2", - "xml2js": "^0.4.23", - "youtube-search-without-api-key": "^1.0.7" + "ssdp-js": "^1.0.1", + "ts-md5": "1.3.1", + "upnp-mediarenderer-client": "vapormusic/node-upnp-mediarenderer-client", + "v8-compile-cache": "^2.4.0", + "wallpaper": "7.2.1", + "ws": "^8.17.0", + "xml2js": "^0.6.2", + "youtube-search-without-api-key": "^2.0.1" }, "devDependencies": { - "@playwright/test": "^1.18.1", - "@types/discord-rpc": "^4.0.0", - "@types/express": "^4.17.13", - "@types/qrcode-terminal": "^0.12.0", - "@types/ws": "^8.2.2", - "electron": "git+https://github.com/castlabs/electron-releases.git", - "electron-builder": "^22.14.5", + "@types/adm-zip": "^0.5.5", + "@types/discord-rpc": "4.0.8", + "@types/express": "^4.17.21", + "@types/musickit": "ciderapp/musickit-types", + "@types/node": "^20.12.12", + "@types/node-ssdp": "^4.0.4", + "@types/qrcode-terminal": "^0.12.2", + "@types/request": "^2.48.12", + "@types/upnp-mediarenderer-client": "^1.4.3", + "@types/ws": "^8.5.10", + "@types/xml2js": "^0.4.14", + "electron": "github:castlabs/electron-releases#v30.0.4+wvcus", + "electron-builder": "^24.13.3", + "electron-builder-notarize-pkg": "^1.2.0", "electron-webpack": "^2.8.2", - "musickit-typescript": "^1.2.4", - "playwright": "^1.18.1", + "less": "^4.2.0", + "node-gyp": "^10.1.0", + "prettier": "3.2.5", + "typescript": "^5.4.5", "vue-devtools": "^5.1.4", - "webpack": "~5.65.0" + "webpack": "~5.91.0" }, "fileAssociations": [ { @@ -95,14 +116,14 @@ } ], "build": { - "electronVersion": "16.0.7", + "electronVersion": "30.0.6", "electronDownload": { - "version": "16.0.7+wvcus", + "version": "30.0.6+wvcus", "mirror": "https://github.com/castlabs/electron-releases/releases/download/v" }, "appId": "cider", - "afterPack": "./resources/afterPack.js", - "afterSign": "./resources/notarize.js", + "afterPack": "./resources/afterPack.cjs", + "afterSign": "./resources/notarize.cjs", "protocols": [ { "name": "Cider", @@ -119,14 +140,14 @@ "extends": null, "files": [ "./build/**/*", - "./resources/icons/icon.*", - "./src/**/*" + "./src/**/*", + "./resources/icons/**/*" ], "linux": { "target": [ "AppImage", "deb", - "snap" + "rpm" ], "synopsis": "A new look into listening and enjoying music in style and performance. ", "category": "AudioVideo", @@ -146,7 +167,39 @@ "perMachine": false, "allowToChangeInstallationDirectory": true, "license": "LICENSE", - "deleteAppDataOnUninstall": true + "deleteAppDataOnUninstall": true, + "artifactName": "${productName}-Setup-${version}.${ext}" + }, + "pkg": { + "installLocation": "/Applications", + "background": { + "file": "./resources/bg.png", + "alignment": "bottomleft" + }, + "allowAnywhere": true, + "allowCurrentUserHome": true, + "allowRootDirectory": true, + "license": "./LICENSE", + "isVersionChecked": false, + "isRelocatable": false, + "overwriteAction": "upgrade" + }, + "snap": { + "slots": [ + { + "mpris": { + "interface": "mpris" + } + } + ] + }, + "dmg": { + "background": "./resources/bg.tiff", + "icon": "resources/icons/icon.ico" + }, + "mas": { + "entitlements": "./resources/entitlements.mac.plist", + "entitlementsInherit": "./resources/entitlements.mac.plist" }, "win": { "target": [ @@ -168,8 +221,18 @@ "darkModeSupport": true, "target": [ "dmg" - ] - }, - "artifactName": "${productName}.${ext}" + ], + "extendInfo": { + "NSUserNotificationAlertStyle": "alert" + } + } + }, + "electronWebpack": { + "devtool": "source-map" + }, + "engines": { + "node": ">= 18", + "npm": ">= 6.13.4", + "yarn": ">= 1.21.1" } } diff --git a/resources/afterPack.cjs b/resources/afterPack.cjs new file mode 100644 index 00000000..6c5efde1 --- /dev/null +++ b/resources/afterPack.cjs @@ -0,0 +1,35 @@ +exports.default = function (context) { + const { execSync } = require("child_process"); + const fs = require("fs"); + + if (process.platform !== "darwin") return; + + if (fs.existsSync("dist/mac-universal--x64/Cider.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/Electron Framework.sig")) + fs.unlinkSync("dist/mac-universal--x64/Cider.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/Electron Framework.sig"); + if (fs.existsSync("dist/mac-universal--arm64/Cider.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/Electron Framework.sig")) + fs.unlinkSync("dist/mac-universal--arm64/Cider.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/Electron Framework.sig"); + console.log('Castlabs-evs update start') + execSync('python3 -m pip install --upgrade castlabs-evs') + console.log('Castlabs-evs update complete') + + // xcode 13 + if ( + fs.existsSync("dist/mac-universal--x64") && + fs.existsSync("dist/mac-universal--arm64") && + fs.existsSync("dist/mac-universal--x64/Cider.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/MainMenu.nib/keyedobjects-101300.nib") + ) + execSync( + "cp 'dist/mac-universal--x64/Cider.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/MainMenu.nib/keyedobjects-101300.nib' 'dist/mac-universal--arm64/Cider.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/MainMenu.nib/keyedobjects-101300.nib'", + { stdio: "inherit" } + ); + + console.log('VMP signing start') + if (fs.existsSync('dist/mac-universal')) + execSync('python3 -m castlabs_evs.vmp -n sign-pkg dist/mac-universal',{stdio: 'inherit'}) + if (fs.existsSync('dist/mac')) + execSync('python3 -m castlabs_evs.vmp -n sign-pkg dist/mac',{stdio: 'inherit'}) + if (fs.existsSync('dist/mac-arm64')) + execSync('python3 -m castlabs_evs.vmp -n sign-pkg dist/mac-arm64 -z',{stdio: 'inherit'}) + + console.log('VMP signing complete') +}; diff --git a/resources/afterPack.js b/resources/afterPack.js deleted file mode 100644 index 6c677c49..00000000 --- a/resources/afterPack.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.default = function(context) { - const { execSync } = require('child_process') - - if (process.platform !== 'darwin') - return - - console.log('Castlabs-evs update start') - execSync('python3 -m pip install --upgrade castlabs-evs') - console.log('Castlabs-evs update complete') - - - - console.log('VMP signing start') - - execSync('python3 -m castlabs_evs.vmp -n sign-pkg dist/mac',{stdio: 'inherit'}) - - console.log('VMP signing complete') -} \ No newline at end of file diff --git a/resources/bg.tiff b/resources/bg.tiff new file mode 100644 index 00000000..d21b3863 Binary files /dev/null and b/resources/bg.tiff differ diff --git a/resources/icons/icon-old.icns b/resources/icons/icon-old.icns new file mode 100644 index 00000000..4276a463 Binary files /dev/null and b/resources/icons/icon-old.icns differ diff --git a/resources/icons/icon.icns b/resources/icons/icon.icns index 2325c333..562f3ad7 100644 Binary files a/resources/icons/icon.icns and b/resources/icons/icon.icns differ diff --git a/resources/icons/icon.svg b/resources/icons/icon.svg new file mode 100644 index 00000000..6f5cad41 --- /dev/null +++ b/resources/icons/icon.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/media/dark/next-inactive.png b/resources/icons/media/dark/next-inactive.png deleted file mode 100644 index 6e8f950b..00000000 Binary files a/resources/icons/media/dark/next-inactive.png and /dev/null differ diff --git a/resources/icons/media/dark/next.png b/resources/icons/media/dark/next.png deleted file mode 100644 index f56fefd4..00000000 Binary files a/resources/icons/media/dark/next.png and /dev/null differ diff --git a/resources/icons/media/dark/pause-inactive.png b/resources/icons/media/dark/pause-inactive.png deleted file mode 100644 index 8bf5bb72..00000000 Binary files a/resources/icons/media/dark/pause-inactive.png and /dev/null differ diff --git a/resources/icons/media/dark/pause.png b/resources/icons/media/dark/pause.png deleted file mode 100644 index a71ca9a9..00000000 Binary files a/resources/icons/media/dark/pause.png and /dev/null differ diff --git a/resources/icons/media/dark/play-inactive.png b/resources/icons/media/dark/play-inactive.png deleted file mode 100644 index aa4ee6a9..00000000 Binary files a/resources/icons/media/dark/play-inactive.png and /dev/null differ diff --git a/resources/icons/media/dark/play.png b/resources/icons/media/dark/play.png deleted file mode 100644 index af1d3bd5..00000000 Binary files a/resources/icons/media/dark/play.png and /dev/null differ diff --git a/resources/icons/media/dark/previous-inactive.png b/resources/icons/media/dark/previous-inactive.png deleted file mode 100644 index 4a76213f..00000000 Binary files a/resources/icons/media/dark/previous-inactive.png and /dev/null differ diff --git a/resources/icons/media/dark/previous.png b/resources/icons/media/dark/previous.png deleted file mode 100644 index 52b66d8f..00000000 Binary files a/resources/icons/media/dark/previous.png and /dev/null differ diff --git a/resources/icons/media/light/next-inactive.png b/resources/icons/media/light/next-inactive.png deleted file mode 100644 index 2ff1bf16..00000000 Binary files a/resources/icons/media/light/next-inactive.png and /dev/null differ diff --git a/resources/icons/media/light/next.png b/resources/icons/media/light/next.png deleted file mode 100644 index bf203ba0..00000000 Binary files a/resources/icons/media/light/next.png and /dev/null differ diff --git a/resources/icons/media/light/pause-inactive.png b/resources/icons/media/light/pause-inactive.png deleted file mode 100644 index ccd75d91..00000000 Binary files a/resources/icons/media/light/pause-inactive.png and /dev/null differ diff --git a/resources/icons/media/light/pause.png b/resources/icons/media/light/pause.png deleted file mode 100644 index 94b21e41..00000000 Binary files a/resources/icons/media/light/pause.png and /dev/null differ diff --git a/resources/icons/media/light/play-inactive.png b/resources/icons/media/light/play-inactive.png deleted file mode 100644 index fadd6e2b..00000000 Binary files a/resources/icons/media/light/play-inactive.png and /dev/null differ diff --git a/resources/icons/media/light/play.png b/resources/icons/media/light/play.png deleted file mode 100644 index a0776aba..00000000 Binary files a/resources/icons/media/light/play.png and /dev/null differ diff --git a/resources/icons/media/light/previous-inactive.png b/resources/icons/media/light/previous-inactive.png deleted file mode 100644 index f8f69f2e..00000000 Binary files a/resources/icons/media/light/previous-inactive.png and /dev/null differ diff --git a/resources/icons/media/light/previous.png b/resources/icons/media/light/previous.png deleted file mode 100644 index 1b089dae..00000000 Binary files a/resources/icons/media/light/previous.png and /dev/null differ diff --git a/resources/icons/thumbar/dark_next.png b/resources/icons/thumbar/dark_next.png new file mode 100644 index 00000000..6ec98abb Binary files /dev/null and b/resources/icons/thumbar/dark_next.png differ diff --git a/resources/icons/thumbar/dark_pause.png b/resources/icons/thumbar/dark_pause.png new file mode 100644 index 00000000..8df81694 Binary files /dev/null and b/resources/icons/thumbar/dark_pause.png differ diff --git a/resources/icons/thumbar/dark_play.png b/resources/icons/thumbar/dark_play.png new file mode 100644 index 00000000..3cb0bfa5 Binary files /dev/null and b/resources/icons/thumbar/dark_play.png differ diff --git a/resources/icons/thumbar/dark_previous.png b/resources/icons/thumbar/dark_previous.png new file mode 100644 index 00000000..c7dbd401 Binary files /dev/null and b/resources/icons/thumbar/dark_previous.png differ diff --git a/resources/icons/thumbar/light_next.png b/resources/icons/thumbar/light_next.png new file mode 100644 index 00000000..cb2261f0 Binary files /dev/null and b/resources/icons/thumbar/light_next.png differ diff --git a/resources/icons/thumbar/light_pause.png b/resources/icons/thumbar/light_pause.png new file mode 100644 index 00000000..f528b33d Binary files /dev/null and b/resources/icons/thumbar/light_pause.png differ diff --git a/resources/icons/thumbar/light_play.png b/resources/icons/thumbar/light_play.png new file mode 100644 index 00000000..128df4d3 Binary files /dev/null and b/resources/icons/thumbar/light_play.png differ diff --git a/resources/icons/thumbar/light_previous.png b/resources/icons/thumbar/light_previous.png new file mode 100644 index 00000000..6068befe Binary files /dev/null and b/resources/icons/thumbar/light_previous.png differ diff --git a/resources/lfmApiCredentials.json b/resources/lfmApiCredentials.json deleted file mode 100644 index 689c02aa..00000000 --- a/resources/lfmApiCredentials.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "key": "f9986d12aab5a0fe66193c559435ede3", - "secret": "acba3c29bd5973efa38cc2f0b63cc625" -} diff --git a/resources/license.json b/resources/license.json new file mode 100644 index 00000000..9c852155 --- /dev/null +++ b/resources/license.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://github.com/argv-minus-one/dmg-license/raw/master/schema.json", + "body": [ + { + "file": "license.txt", + "lang": ["en-US"] + } + ] +} diff --git a/resources/license.txt b/resources/license.txt new file mode 100644 index 00000000..0ad25db4 --- /dev/null +++ b/resources/license.txt @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/resources/macPackager.cjs b/resources/macPackager.cjs new file mode 100644 index 00000000..d564634b --- /dev/null +++ b/resources/macPackager.cjs @@ -0,0 +1,408 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const bluebird_lst_1 = require("bluebird-lst"); +const builder_util_1 = require("builder-util"); +const electron_osx_sign_1 = require("electron-osx-sign"); +const promises_1 = require("fs/promises"); +const lazy_val_1 = require("lazy-val"); +const path = require("path"); +const fs_1 = require("builder-util/out/fs"); +const promise_1 = require("builder-util/out/promise"); +const appInfo_1 = require("./appInfo"); +const macCodeSign_1 = require("./codeSign/macCodeSign"); +const core_1 = require("./core"); +const platformPackager_1 = require("./platformPackager"); +const ArchiveTarget_1 = require("./targets/ArchiveTarget"); +const pkg_1 = require("./targets/pkg"); +const targetFactory_1 = require("./targets/targetFactory"); +const macosVersion_1 = require("./util/macosVersion"); +const pathManager_1 = require("./util/pathManager"); +const fs = require("fs/promises"); +class MacPackager extends platformPackager_1.PlatformPackager { + constructor(info) { + super(info, core_1.Platform.MAC); + this.codeSigningInfo = new lazy_val_1.Lazy(() => { + const cscLink = this.getCscLink(); + if (cscLink == null || process.platform !== "darwin") { + return Promise.resolve({ + keychainFile: process.env.CSC_KEYCHAIN || null, + }); + } + return macCodeSign_1 + .createKeychain({ + tmpDir: this.info.tempDirManager, + cscLink, + cscKeyPassword: this.getCscPassword(), + cscILink: platformPackager_1.chooseNotNull(this.platformSpecificBuildOptions.cscInstallerLink, process.env.CSC_INSTALLER_LINK), + cscIKeyPassword: platformPackager_1.chooseNotNull(this.platformSpecificBuildOptions.cscInstallerKeyPassword, process.env.CSC_INSTALLER_KEY_PASSWORD), + currentDir: this.projectDir, + }) + .then((result) => { + const keychainFile = result.keychainFile; + if (keychainFile != null) { + this.info.disposeOnBuildFinish(() => macCodeSign_1.removeKeychain(keychainFile)); + } + return result; + }); + }); + this._iconPath = new lazy_val_1.Lazy(() => this.getOrConvertIcon("icns")); + } + get defaultTarget() { + return this.info.framework.macOsDefaultTargets; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + prepareAppInfo(appInfo) { + return new appInfo_1.AppInfo(this.info, this.platformSpecificBuildOptions.bundleVersion, this.platformSpecificBuildOptions); + } + async getIconPath() { + return this._iconPath.value; + } + createTargets(targets, mapper) { + for (const name of targets) { + switch (name) { + case core_1.DIR_TARGET: + break; + case "dmg": { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { DmgTarget } = require("dmg-builder"); + mapper(name, (outDir) => new DmgTarget(this, outDir)); + break; + } + case "zip": + // https://github.com/electron-userland/electron-builder/issues/2313 + mapper(name, (outDir) => new ArchiveTarget_1.ArchiveTarget(name, outDir, this, true)); + break; + case "pkg": + mapper(name, (outDir) => new pkg_1.PkgTarget(this, outDir)); + break; + default: + mapper(name, (outDir) => (name === "mas" || name === "mas-dev" ? new targetFactory_1.NoOpTarget(name) : targetFactory_1.createCommonTarget(name, outDir, this))); + break; + } + } + } + async doPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets) { + switch (arch) { + default: { + return super.doPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets); + } + case builder_util_1.Arch.universal: { + const x64Arch = builder_util_1.Arch.x64; + const x64AppOutDir = appOutDir + "--" + builder_util_1.Arch[x64Arch]; + await super.doPack(outDir, x64AppOutDir, platformName, x64Arch, platformSpecificBuildOptions, targets, false, true); + const arm64Arch = builder_util_1.Arch.arm64; + const arm64AppOutPath = appOutDir + "--" + builder_util_1.Arch[arm64Arch]; + await super.doPack(outDir, arm64AppOutPath, platformName, arm64Arch, platformSpecificBuildOptions, targets, false, true); + const framework = this.info.framework; + builder_util_1.log.info( + { + platform: platformName, + arch: builder_util_1.Arch[arch], + [`${framework.name}`]: framework.version, + appOutDir: builder_util_1.log.filePath(appOutDir), + }, + `packaging` + ); + const appFile = `${this.appInfo.productFilename}.app`; + const { makeUniversalApp } = require("@electron/universal"); + await makeUniversalApp({ + x64AppPath: path.join(x64AppOutDir, appFile), + arm64AppPath: path.join(arm64AppOutPath, appFile), + outAppPath: path.join(appOutDir, appFile), + force: true, + }); + await fs.rm(x64AppOutDir, { recursive: true, force: true }); + await fs.rm(arm64AppOutPath, { recursive: true, force: true }); + const packContext = { + appOutDir, + outDir, + arch, + targets, + packager: this, + electronPlatformName: platformName, + }; + await this.info.afterPack(packContext); + if (framework.afterPack != null) { + await framework.afterPack(packContext); + } + await this.doSignAfterPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets); + break; + } + } + } + async pack(outDir, arch, targets, taskManager) { + let nonMasPromise = null; + const hasMas = targets.length !== 0 && targets.some((it) => it.name === "mas" || it.name === "mas-dev"); + const prepackaged = this.packagerOptions.prepackaged; + if (!hasMas || targets.length > 1) { + const appPath = prepackaged == null ? path.join(this.computeAppOutDir(outDir, arch), `${this.appInfo.productFilename}.app`) : prepackaged; + nonMasPromise = (prepackaged ? Promise.resolve() : this.doPack(outDir, path.dirname(appPath), this.platform.nodeName, arch, this.platformSpecificBuildOptions, targets)).then(() => + this.packageInDistributableFormat(appPath, arch, targets, taskManager) + ); + } + for (const target of targets) { + const targetName = target.name; + if (!(targetName === "mas" || targetName === "mas-dev")) { + continue; + } + const masBuildOptions = builder_util_1.deepAssign({}, this.platformSpecificBuildOptions, this.config.mas); + if (targetName === "mas-dev") { + builder_util_1.deepAssign(masBuildOptions, this.config.masDev, { + type: "development", + }); + } + const targetOutDir = path.join(outDir, `${targetName}${builder_util_1.getArchSuffix(arch)}`); + if (prepackaged == null) { + await this.doPack(outDir, targetOutDir, "mas", arch, masBuildOptions, [target]); + await this.sign(path.join(targetOutDir, `${this.appInfo.productFilename}.app`), targetOutDir, masBuildOptions, arch); + } else { + await this.sign(prepackaged, targetOutDir, masBuildOptions, arch); + } + } + if (nonMasPromise != null) { + await nonMasPromise; + } + } + async sign(appPath, outDir, masOptions, arch) { + if (!macCodeSign_1.isSignAllowed()) { + return; + } + const isMas = masOptions != null; + const options = masOptions == null ? this.platformSpecificBuildOptions : masOptions; + const qualifier = options.identity; + if (!isMas && qualifier === null) { + if (this.forceCodeSigning) { + throw new builder_util_1.InvalidConfigurationError("identity explicitly is set to null, but forceCodeSigning is set to true"); + } + builder_util_1.log.info({ reason: "identity explicitly is set to null" }, "skipped macOS code signing"); + return; + } + const keychainFile = (await this.codeSigningInfo.value).keychainFile; + const explicitType = options.type; + const type = explicitType || "distribution"; + const isDevelopment = type === "development"; + const certificateTypes = getCertificateTypes(isMas, isDevelopment); + let identity = null; + for (const certificateType of certificateTypes) { + identity = await macCodeSign_1.findIdentity(certificateType, qualifier, keychainFile); + if (identity != null) { + break; + } + } + if (identity == null) { + if (!isMas && !isDevelopment && explicitType !== "distribution") { + identity = await macCodeSign_1.findIdentity("Mac Developer", qualifier, keychainFile); + if (identity != null) { + builder_util_1.log.warn("Mac Developer is used to sign app — it is only for development and testing, not for production"); + } + } + if (identity == null) { + await macCodeSign_1.reportError(isMas, certificateTypes, qualifier, keychainFile, this.forceCodeSigning); + return; + } + } + if (!macosVersion_1.isMacOsHighSierra()) { + throw new builder_util_1.InvalidConfigurationError("macOS High Sierra 10.13.6 is required to sign"); + } + let filter = options.signIgnore; + if (Array.isArray(filter)) { + if (filter.length == 0) { + filter = null; + } + } else if (filter != null) { + filter = filter.length === 0 ? null : [filter]; + } + const filterRe = filter == null ? null : filter.map((it) => new RegExp(it)); + let binaries = options.binaries || undefined; + if (binaries) { + // Accept absolute paths for external binaries, else resolve relative paths from the artifact's app Contents path. + const userDefinedBinaries = await Promise.all( + binaries.map(async (destination) => { + if (await fs_1.statOrNull(destination)) { + return destination; + } + return path.resolve(appPath, destination); + }) + ); + // Insert at front to prioritize signing. We still sort by depth next + binaries = userDefinedBinaries.concat(binaries); + builder_util_1.log.info("Signing addtional user-defined binaries: " + JSON.stringify(userDefinedBinaries, null, 1)); + } + const signOptions = { + "identity-validation": false, + // https://github.com/electron-userland/electron-builder/issues/1699 + // kext are signed by the chipset manufacturers. You need a special certificate (only available on request) from Apple to be able to sign kext. + ignore: (file) => { + if (filterRe != null) { + for (const regExp of filterRe) { + if (regExp.test(file)) { + return true; + } + } + } + return ( + file.endsWith(".kext") || + file.startsWith("/Contents/PlugIns", appPath.length) || + file.includes("/node_modules/puppeteer/.local-chromium") || + file.includes("/node_modules/playwright-firefox/.local-browsers") || + file.includes("/node_modules/playwright/.local-browsers") + ); + /* Those are browser automating modules, browser (chromium, nightly) cannot be signed + https://github.com/electron-userland/electron-builder/issues/2010 + https://github.com/electron-userland/electron-builder/issues/5383 + */ + }, + identity: identity, + type, + platform: isMas ? "mas" : "darwin", + version: this.config.electronVersion, + app: appPath, + keychain: keychainFile || undefined, + binaries, + timestamp: isMas ? (masOptions === null || masOptions === void 0 ? void 0 : masOptions.timestamp) : options.timestamp, + requirements: isMas || this.platformSpecificBuildOptions.requirements == null ? undefined : await this.getResource(this.platformSpecificBuildOptions.requirements), + // https://github.com/electron-userland/electron-osx-sign/issues/196 + // will fail on 10.14.5+ because a signed but unnotarized app is also rejected. + "gatekeeper-assess": options.gatekeeperAssess === true, + // https://github.com/electron-userland/electron-builder/issues/1480 + "strict-verify": options.strictVerify, + hardenedRuntime: isMas ? masOptions && masOptions.hardenedRuntime === true : options.hardenedRuntime !== false, + }; + await this.adjustSignOptions(signOptions, masOptions); + builder_util_1.log.info( + { + file: builder_util_1.log.filePath(appPath), + identityName: identity.name, + identityHash: identity.hash, + provisioningProfile: signOptions["provisioning-profile"] || "none", + }, + "signing" + ); + await this.doSign(signOptions); + // https://github.com/electron-userland/electron-builder/issues/1196#issuecomment-312310209 + if (masOptions != null && !isDevelopment) { + const certType = isDevelopment ? "Mac Developer" : "3rd Party Mac Developer Installer"; + const masInstallerIdentity = await macCodeSign_1.findIdentity(certType, masOptions.identity, keychainFile); + if (masInstallerIdentity == null) { + throw new builder_util_1.InvalidConfigurationError(`Cannot find valid "${certType}" identity to sign MAS installer, please see https://electron.build/code-signing`); + } + // mas uploaded to AppStore, so, use "-" instead of space for name + const artifactName = this.expandArtifactNamePattern(masOptions, "pkg", arch); + const artifactPath = path.join(outDir, artifactName); + await this.doFlat(appPath, artifactPath, masInstallerIdentity, keychainFile); + await this.dispatchArtifactCreated(artifactPath, null, builder_util_1.Arch.x64, this.computeSafeArtifactName(artifactName, "pkg", arch, true, this.platformSpecificBuildOptions.defaultArch)); + } + } + async adjustSignOptions(signOptions, masOptions) { + const resourceList = await this.resourceList; + const customSignOptions = masOptions || this.platformSpecificBuildOptions; + const entitlementsSuffix = masOptions == null ? "mac" : "mas"; + let entitlements = customSignOptions.entitlements; + if (entitlements == null) { + const p = `entitlements.${entitlementsSuffix}.plist`; + if (resourceList.includes(p)) { + entitlements = path.join(this.info.buildResourcesDir, p); + } else { + entitlements = pathManager_1.getTemplatePath("entitlements.mac.plist"); + } + } + signOptions.entitlements = entitlements; + let entitlementsInherit = customSignOptions.entitlementsInherit; + if (entitlementsInherit == null) { + const p = `entitlements.${entitlementsSuffix}.inherit.plist`; + if (resourceList.includes(p)) { + entitlementsInherit = path.join(this.info.buildResourcesDir, p); + } else { + entitlementsInherit = pathManager_1.getTemplatePath("entitlements.mac.plist"); + } + } + signOptions["entitlements-inherit"] = entitlementsInherit; + if (customSignOptions.provisioningProfile != null) { + signOptions["provisioning-profile"] = customSignOptions.provisioningProfile; + } + signOptions["entitlements-loginhelper"] = customSignOptions.entitlementsLoginHelper; + } + //noinspection JSMethodCanBeStatic + async doSign(opts) { + return electron_osx_sign_1.signAsync(opts); + } + //noinspection JSMethodCanBeStatic + async doFlat(appPath, outFile, identity, keychain) { + // productbuild doesn't created directory for out file + await promises_1.mkdir(path.dirname(outFile), { recursive: true }); + const args = pkg_1.prepareProductBuildArgs(identity, keychain); + args.push("--component", appPath, "/Applications"); + args.push(outFile); + return await builder_util_1.exec("productbuild", args); + } + getElectronSrcDir(dist) { + return path.resolve(this.projectDir, dist, this.info.framework.distMacOsAppName); + } + getElectronDestinationDir(appOutDir) { + return path.join(appOutDir, this.info.framework.distMacOsAppName); + } + // todo fileAssociations + async applyCommonInfo(appPlist, contentsPath) { + const appInfo = this.appInfo; + const appFilename = appInfo.productFilename; + // https://github.com/electron-userland/electron-builder/issues/1278 + appPlist.CFBundleExecutable = appFilename.endsWith(" Helper") ? appFilename.substring(0, appFilename.length - " Helper".length) : appFilename; + const icon = await this.getIconPath(); + if (icon != null) { + const oldIcon = appPlist.CFBundleIconFile; + const resourcesPath = path.join(contentsPath, "Resources"); + if (oldIcon != null) { + await fs_1.unlinkIfExists(path.join(resourcesPath, oldIcon)); + } + const iconFileName = "icon.icns"; + appPlist.CFBundleIconFile = iconFileName; + await fs_1.copyFile(icon, path.join(resourcesPath, iconFileName)); + } + appPlist.CFBundleName = appInfo.productName; + appPlist.CFBundleDisplayName = appInfo.productName; + const minimumSystemVersion = this.platformSpecificBuildOptions.minimumSystemVersion; + if (minimumSystemVersion != null) { + appPlist.LSMinimumSystemVersion = minimumSystemVersion; + } + appPlist.CFBundleIdentifier = appInfo.macBundleIdentifier; + appPlist.CFBundleShortVersionString = this.platformSpecificBuildOptions.bundleShortVersion || appInfo.version; + appPlist.CFBundleVersion = appInfo.buildVersion; + builder_util_1.use(this.platformSpecificBuildOptions.category || this.config.category, (it) => (appPlist.LSApplicationCategoryType = it)); + appPlist.NSHumanReadableCopyright = appInfo.copyright; + if (this.platformSpecificBuildOptions.darkModeSupport) { + appPlist.NSRequiresAquaSystemAppearance = false; + } + const extendInfo = this.platformSpecificBuildOptions.extendInfo; + if (extendInfo != null) { + Object.assign(appPlist, extendInfo); + } + } + async signApp(packContext, isAsar) { + const appFileName = `${this.appInfo.productFilename}.app`; + await bluebird_lst_1.default.map(promises_1.readdir(packContext.appOutDir), (file) => { + if (file === appFileName) { + return this.sign(path.join(packContext.appOutDir, file), null, null, null); + } + return null; + }); + if (!isAsar) { + return; + } + const outResourcesDir = path.join(packContext.appOutDir, "resources", "app.asar.unpacked"); + await bluebird_lst_1.default.map(promise_1.orIfFileNotExist(promises_1.readdir(outResourcesDir), []), (file) => { + if (file.endsWith(".app")) { + return this.sign(path.join(outResourcesDir, file), null, null, null); + } else { + return null; + } + }); + } +} +exports.default = MacPackager; +function getCertificateTypes(isMas, isDevelopment) { + if (isDevelopment) { + return isMas ? ["Mac Developer", "Apple Development"] : ["Developer ID Application"]; + } + return isMas ? ["Apple Distribution"] : ["Developer ID Application"]; +} +//# sourceMappingURL=macPackager.js.map diff --git a/resources/notarize.cjs b/resources/notarize.cjs new file mode 100644 index 00000000..2b9b580e --- /dev/null +++ b/resources/notarize.cjs @@ -0,0 +1,18 @@ +require("dotenv").config(); +const { notarize } = require("electron-notarize"); + +exports.default = async function notarizing(context) { + const { electronPlatformName, appOutDir } = context; + if (electronPlatformName !== "darwin") { + return; + } + + const appName = context.packager.appInfo.productFilename; + + return await notarize({ + appBundleId: "com.ciderapp.cider", + appPath: `${appOutDir}/${appName}.app`, + appleId: process.env.APPLEID, + appleIdPassword: process.env.APPLEIDPASS, + }); +}; diff --git a/resources/notarize.js b/resources/notarize.js deleted file mode 100644 index 9e98e18c..00000000 --- a/resources/notarize.js +++ /dev/null @@ -1,20 +0,0 @@ - - -require('dotenv').config(); - const { notarize } = require('electron-notarize'); - -exports.default = async function notarizing(context) { - const { electronPlatformName, appOutDir } = context; - if (electronPlatformName !== 'darwin') { - return; - } - - const appName = context.packager.appInfo.productFilename; - - return await notarize({ - appBundleId: 'com.ciderapp.cider', - appPath: `${appOutDir}/${appName}.app`, - appleId: process.env.APPLEID, - appleIdPassword: process.env.APPLEIDPASS, - }); -}; \ No newline at end of file diff --git a/resources/verror-types b/resources/verror-types new file mode 100644 index 00000000..07cfb21d --- /dev/null +++ b/resources/verror-types @@ -0,0 +1,77 @@ +// Type definitions for verror 1.10 +// Project: https://github.com/davepacheco/node-verror +// Definitions by: Sven Reglitzki , Maxime Toumi-M +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/* + * VError([cause], fmt[, arg...]): Like JavaScript's built-in Error class, but + * supports a "cause" argument (another error) and a printf-style message. The + * cause argument can be null or omitted entirely. + * + * Examples: + * + * CODE MESSAGE + * new VError('something bad happened') "something bad happened" + * new VError('missing file: "%s"', file) "missing file: "/etc/passwd" + * with file = '/etc/passwd' + * new VError(err, 'open failed') "open failed: file not found" + * with err.message = 'file not found' + */ +declare class VError extends Error { + static VError: typeof VError; + + static cause(err: Error): Error | null; + static info(err: Error): VError.Info; + static fullStack(err: Error): string; + static findCauseByName(err: Error, name: string): Error | null; + static hasCauseWithName(err: Error, name: string): boolean; + static errorFromList(errors: T[]): null | T | VError.MultiError; + static errorForEach(err: Error, func: (err: Error) => void): void; + + //@ts-ignore + cause(): Error | undefined; + constructor(options: VError.Options | Error, message: string, ...params: any[]); + constructor(message?: string, ...params: any[]); +} + +declare namespace VError { + interface Info { + [key: string]: any; + } + + interface Options { + cause?: Error | null | undefined; + name?: string | undefined; + strict?: boolean | undefined; + constructorOpt?(...args: any[]): void; + info?: Info | undefined; + } + + /* + * SError is like VError, but stricter about types. You cannot pass "null" or + * "undefined" as string arguments to the formatter. Since SError is only a + * different function, not really a different class, we don't set + * SError.prototype.name. + */ + class SError extends VError {} + + /* + * Represents a collection of errors for the purpose of consumers that generally + * only deal with one error. Callers can extract the individual errors + * contained in this object, but may also just treat it as a normal single + * error, in which case a summary message will be printed. + */ + class MultiError extends VError { + constructor(errors: Error[]); + errors(): Error[]; + } + + /* + * Like JavaScript's built-in Error class, but supports a "cause" argument which + * is wrapped, not "folded in" as with VError. Accepts a printf-style message. + * The cause argument can be null. + */ + class WError extends VError {} +} + +export = VError; \ No newline at end of file diff --git a/resources/version.sh b/resources/version.sh new file mode 100644 index 00000000..b8f74f7a --- /dev/null +++ b/resources/version.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Setup the variables needed +if [[ $GH_REQUEST_TOKEN != "" ]]; then + STABLE_SHA=$(curl -H "Authorization: token ${GH_REQUEST_TOKEN}" -s https://api.github.com/repos/ciderapp/Cider/branches/stable | grep '"sha"' | head -1 | cut -d '"' -f 4) +elif [[ $GITHUB_TOKEN != "" ]]; then + STABLE_SHA=$(curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/ciderapp/Cider/branches/stable | grep '"sha"' | head -1 | cut -d '"' -f 4) +else + STABLE_SHA=$(curl -s https://api.github.com/repos/ciderapp/Cider/branches/stable | grep '"sha"' | head -1 | cut -d '"' -f 4) +fi + +SHA_DATE=$(git show -s --format=%ci $STABLE_SHA) +VERSION_POSTFIX=$(git rev-list $STABLE_SHA..HEAD --count --since="$SHA_DATE") +CURRENT_VERSION=$(node -p -e "require('./package.json').version" | cut -d '-' -f 1) + +# Set the version number for commits on main branch +if [[ ($CIRCLE_BRANCH == "main" || $GITHUB_REF_NAME == "main") && $VERSION_POSTFIX -gt 0 ]]; then + NEW_VERSION_NUMBERED="$CURRENT_VERSION-beta.$(printf "%03d\n" $VERSION_POSTFIX)" + NEW_VERSION="${CURRENT_VERSION}-beta.${VERSION_POSTFIX}" + + # Update the version in package.json + if [[ $NO_WRITE_VER == "" && $(node -p -e "require('./package.json').version" | cut -d '.' -f 4) != $VERSION_POSTFIX ]]; then + if [[ $RUNNER_OS == "macOS" ]]; then + sed -i "" -e "s/$CURRENT_VERSION/$NEW_VERSION/" package.json + else + sed -i "0,/$CURRENT_VERSION/s//$NEW_VERSION/" package.json + fi + fi +else + NEW_VERSION_NUMBERED=$CURRENT_VERSION + NEW_VERSION=$CURRENT_VERSION +fi + +echo $NEW_VERSION + + +# Add the version to the environment for CI usage +if [[ $GITHUB_REF_NAME != "" ]] && [[ "$GITHUB_ENV" ]]; then + echo "APP_VERSION=$NEW_VERSION" >>$GITHUB_ENV + echo "RELEASE_VERSION=$NEW_VERSION_NUMBERED" >>$GITHUB_ENV +elif [[ $CIRCLE_BRANCH != "" ]] && [[ "$BASH_ENV" ]]; then + echo "export APP_VERSION=$NEW_VERSION" >>$BASH_ENV + echo "export RELEASE_VERSION=$NEW_VERSION_NUMBERED" >>$BASH_ENV +fi diff --git a/src/__tests__/base.test.ts b/src/__tests__/base.test.ts deleted file mode 100644 index 90725579..00000000 --- a/src/__tests__/base.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { _electron as electron } from "playwright"; -import { test, expect } from "@playwright/test"; -import { resolve } from "path"; -import * as fs from "fs"; - -test("Launch electron app", async () => { - - const paths = { - "mainBuild": resolve(__dirname, "../../build/"), - "main": resolve(__dirname, "../main"), - "root": resolve(__dirname, "../../"), - "cwd": __dirname, - "processcwd": process.cwd() - } - - console.log(paths) - - console.log(fs.readdirSync(paths.main)) - - const electronApp = await electron.launch({ args: ['build/index.js'], cwd: paths.root }); - - const appPath = await electronApp.evaluate(async ({ app }) => { - // This runs in the main Electron process, parameter here is always - // the result of the require('electron') in the main app script. - return app.getAppPath(); - }); - console.log(`cwd: ${appPath}`); - - - - const windowState: { isVisible: boolean, isDevToolsOpened: boolean, isCrashed: boolean } = await electronApp.evaluate(async ({ BrowserWindow, app }) => { - const win = BrowserWindow.getAllWindows()[0]; - - console.log(win) - - const getState = (win: Electron.BrowserWindow) => ({ - isVisible: win.isVisible(), - isDevToolsOpened: win.webContents.isDevToolsOpened(), - isCrashed: win.webContents.isCrashed() - }) - - return new Promise((resolve) => { - if (win && win.isVisible()) { - resolve(getState(win)) - } else if (win) { - win.once("ready-to-show", () => setTimeout(() => resolve(getState(win)))); - } else { - app.once("browser-window-created", (_e: Event, window: Electron.BrowserWindow) => setTimeout(() => resolve(getState(window)))); - } - }) - - }) - - console.log(windowState) - - expect(windowState.isVisible).toBeTruthy(); - expect(windowState.isDevToolsOpened).toBeFalsy(); - expect(windowState.isCrashed).toBeFalsy(); - - await electronApp.close(); -}); diff --git a/src/ciderkit/public.js b/src/ciderkit/public.js new file mode 100644 index 00000000..b48b5362 --- /dev/null +++ b/src/ciderkit/public.js @@ -0,0 +1,26 @@ +const CiderKit = { + v1: { + musickit: { + async mkv3(route, body, options) { + let opts = { + method: "POST", + cache: "no-cache", + credentials: "same-origin", + headers: { + "Content-Type": "application/json", + }, + redirect: "follow", + referrerPolicy: "no-referrer", + body: {}, + }; + opts.body = JSON.stringify({ + route: route, + body: body, + options: options, + }); + let response = await fetch("./api/musickit/v3", opts); + return response.json(); + }, + }, + }, +}; diff --git a/src/i18n/README.md b/src/i18n/README.md deleted file mode 100644 index cdbba71d..00000000 --- a/src/i18n/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Cider i18n - -Some notes about Cider's i18n support. - -- Localization files are stored in jsonc format aka "JSON with Comments" -- The default language is English. -- The default language is used for messages that are not translated. -- Try when possible to keep the messages the similar in length to the English ones. -- Most of the strings in the content area are provided and translated by Apple themselves, and do not need to be translated. -- The language Apple Music uses are dependent on the storefront region. - - -## Localization Notices - -Several changes have been made to configuration options and will be listed below with the relevant locales that have -been modified, the ones not mentioned in the list need modifying. - -* `settings.option.experimental.closeButtonBehaviour`: Changed to `close_button_hide` - Should be "Close Button Should Hide the Application". `.quit`, `.minimizeTaskbar` and `.minimizeTray` have been removed. Translations done for en_US. -* `action.update`: Added for `en_US`. \ No newline at end of file diff --git a/src/i18n/de_DE.jsonc b/src/i18n/de_DE.jsonc deleted file mode 100644 index fa62c1a2..00000000 --- a/src/i18n/de_DE.jsonc +++ /dev/null @@ -1,312 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "Deutsch", // name of language in native language - "i18n.languageNameEnglish": "German", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@motz0815 @n0chteil", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${d}.${m}.${y}", - - // Dialogs - "dialog.cancel": "Abbrechen", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "Aktualisiere Songs...", - "notification.updatingLibraryAlbums": "Aktualisiere Alben...", - "notification.updatingLibraryArtists": "Aktualisiere KÃŧnstler...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Mehr erfahren", - "term.accountSettings": "Account-Einstellungen", - "term.logout": "Abmelden", - "term.login": "Anmelden", - "term.about": "Über", - "term.privateSession": "Private Sitzung", - "term.queue": "Warteschlange", - "term.search": "Suche", - "term.library": "Mediathek", - "term.listenNow": "Jetzt HÃļren", - "term.browse": "Durchsuchen", - "term.radio": "Radio", - "term.recentlyAdded": "Zuletzt hinzugefÃŧgt", - "term.songs": "Songs", - "term.albums": "Alben", - "term.artists": "KÃŧnstler", - "term.podcasts": "Podcasts", - "term.playlists": "Playlists", - "term.playlist": "Playlist", - "term.newPlaylist": "Neue Playlist", - "term.newPlaylistFolder": "Neuer Playlist-Ordner", - "term.createNewPlaylist": "Neue Playlist erstellen", - "term.createNewPlaylistFolder": "Neuen Playlist-Ordner erstellen", - "term.deletePlaylist": "Bist du sicher, dass du diese Playlist lÃļschen willst?", - "term.play": "Wiedergabe", - "term.pause": "Pause", - "term.previous": "ZurÃŧck", - "term.next": "Weiter", - "term.shuffle": "Zufällig", - "term.repeat": "Wiederholen", - "term.volume": "Lautstärke", - "term.mute": "Stummschalten", - "term.unmute": "Stummschaltung aufheben", - "term.share": "Teilen", - "term.settings": "Einstellungen", - "term.seeAll": "Alle Sehen", - "term.sortBy": "Sortieren nach", - "term.sortBy.album": "Album", - "term.sortBy.artist": "KÃŧnstler", - "term.sortBy.name": "Name", - "term.sortBy.genre": "Genre", - "term.sortBy.releaseDate": "VerÃļffentlichungsdatum", - "term.sortBy.duration": "Länge", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Aufsteigend", - "term.sortOrder.descending": "Absteigend", - "term.viewAs": "Ansehen als", - "term.viewAs.coverArt": "Cover-Bild", - "term.viewAs.list": "Liste", - "term.size": "GrÃļße", - "term.size.normal": "Normal", - "term.size.compact": "Kompakt", - "term.enable": "Aktivieren", - "term.disable": "Deaktivieren", - "term.enabled": "Aktiv", - "term.disabled": "Nicht aktiv", - "term.connect": "Verbinden", - "term.connecting": "Verbindet", - "term.disconnect": "Trennen", - "term.authed": "Autorisiert", - "term.confirm": "Bestätigen?", - "term.more": "Mehr", - "term.less": "Weniger", - "term.showMore": "Mehr anzeigen", - "term.showLess": "Weniger anzeigen", - "term.topSongs": "Top Songs", - "term.latestReleases": "Letzte VerÃļffentlichungen", - "term.time.added": "HinzugefÃŧgt", - "term.time.released": "VerÃļffentlicht", - "term.time.updated": "Aktualisiert", - "term.time.hours": "Stunden", - "term.time.hour": "Stunde", - "term.time.minutes": "Minuten", - "term.time.minute": "Minute", - "term.time.seconds": "Sekunden", - "term.time.second": "Sekunde", - "term.fullscreenView": "Vollbildansicht", - "term.defaultView": "Normale Ansicht", - "term.audioSettings": "Audio-Einstellungen", - "term.spacializedAudioSetting": "Räumliches Audio", - "term.clearAll": "Alle lÃļschen", - "term.recentStations": "Letzte Sender", - "term.language": "Sprache", - "term.funLanguages": "Spaß", - "term.noLyrics": "Lädt... / Lyrik nicht gefunden./ Instrumental.", - "term.copyright": "Copyright", - "term.rightsReserved": "Alle Rechte vorbehalten.", - "term.sponsor": "UnterstÃŧtze dieses Projekt", - "term.ciderTeam": "Cider Team", - "term.developer": "Entwickler", - "term.socialTeam": "Social Team", - "term.socials": "Soziale Medien", - "term.contributors": "Mithelfer", - "term.equalizer": "Equalizer", - "term.reset": "ZurÃŧcksetzen", - "term.tracks": "Lieder", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Videos", - "term.menu": "MenÃŧ", - "term.check": "Nach Updates suchen", - "term.aboutArtist": "Über {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Cider aktualisieren", - - // Home - "home.title": "Home", - "home.recentlyPlayed": "Zuletzt gespielt", - "home.recentlyAdded": "Zuletzt hinzugefÃŧgt", - "home.artistsFeed": "Dein KÃŧnstler-Feed", - "home.artistsFeed.noArtist": "Folge zuerst einigen KÃŧnstlern, dann wirst du hier die neusten Lieder sehen.", - "home.madeForYou": "FÃŧr dich gemacht", - "home.friendsListeningTo": "Freunde hÃļren", - "home.followedArtists": "Gefolgte KÃŧnstler", - // Errors - "error.appleMusicSubRequired": "Apple Music benÃļtigt ein Abonnement.", - "error.connectionError": "Es gab ein Problem beim Verbinden mit Apple Music.", - "error.noResults": "Keine Ergebnisse.", - "error.noResults.description": "Versuche einen anderen Suchbegriff.", - - //Podcasts - "podcast.followOnCider": "Folge auf Cider", - "podcast.followedOnCider": "Gefolgt auf Cider", - "podcast.subscribeOnItunes": "Folge auf iTunes", - "podcast.subscribedOnItunes": "Gefolgt auf iTunes", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "Episoden", - "podcast.playEpisode": "Spiele Episode", - "podcast.website": "Podcast Webseite", - - // Actions - "action.addToLibrary": "Zur Mediathek hinzufÃŧgen", - "action.addToLibrary.success": "Zur Mediathek hinzugefÃŧgt", - "action.addToLibrary.error": "Fehler beim HinzufÃŧgen zur Mediathek", - "action.removeFromLibrary": "Aus Mediathek entfernen", - "action.removeFromLibrary.success": "Aus Mediathek entfernt", - "action.addToQueue": "Zur Warteschlange hinzufÃŧgen", - "action.addToQueue.success": "Zur Warteschlange hinzugefÃŧgt", - "action.addToQueue.error": "Fehler beim HinzufÃŧgen zur Warteschlange", - "action.removeFromQueue": "Aus Warteschlange entfernen", - "action.removeFromQueue.success": "Aus Warteschlange entfernt", - "action.removeFromQueue.error": "Fehler beim Entfernen aus der Warteschlange", - "action.createPlaylist": "Neue Playlist erstellen", - "action.addToPlaylist": "Zur Playlist hinzufÃŧgen", - "action.removeFromPlaylist": "Aus Playlist entfernen", - "action.addToFavorites": "Zu Favoriten hinzufÃŧgen", - "action.follow": "Folgen", - "action.follow.success": "Gefolgt", - "action.follow.error": "Fehler beim Folgen", - "action.unfollow": "Entfolgen", - "action.unfollow.success": "Entfolgt", - "action.unfollow.error": "Fehler beim Entfolgen", - "action.playNext": "Spiele als Nächstes", - "action.playLater": "Spiele später", - "action.startRadio": "Starte Radio", - "action.goToArtist": "Gehe zu KÃŧnstler", - "action.goToAlbum": "Gehe zu Album", - "action.moveToTop": "Gehe zum Anfang", - "action.share": "Teilen", - "action.rename": "Umbenennen", - "action.love": "Lieben", - "action.unlove": "Entlieben", - "action.dislike": "Dislike", - "action.undoDislike": "Dislike entfernen", - "action.showWebRemoteQR": "Zeige Web-Remote QR-Code", - "action.playTracksNext": "Spiele ${app.selectedMediaItems.length} Lieder als Nächstes", - "action.playTracksLater": "Spiele ${app.selectedMediaItems.length} Lieder später", - "action.removeTracks": "Entferne ${self.selectedItems.length} Lieder aus der Warteschlange", - "action.import": "Importieren", - "action.export": "Exportieren", - "action.showAlbum": "Ganzes Album anzeigen", - "action.tray.minimize": "Zu Tray minimieren", - "action.tray.quit": "Beenden", - "action.tray.show": "{appName} anzeigen", - "action.update": "Update", - - // Settings - General - "settings.header.general": "Allgemein", - "settings.header.general.description": "Passe die allgemeinen Einstellungen fÃŧr Cider an.", - "settings.option.general.language": "Sprache", - - // Language optgroups - "settings.option.general.language.main": "Sprachen", - "settings.option.general.language.fun": "Lustige Sprachen", - "settings.option.general.language.unsorted": "Unsortiert", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Passe die Audio-Einstellungen fÃŧr Cider an.", - "settings.option.audio.quality": "Audioqualität", // Dropdown - "settings.header.audio.quality.high": "Hoch", - "settings.header.audio.quality.low": "Niedrig", - "settings.header.audio.quality.auto": "Auto", - "settings.option.audio.seamlessTransition": "Nahtloser AudioÃŧbergang", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Akiviere erweiterte Funktionalität", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Das Aktivieren der erweiterten Funktionalität ermÃļglicht spezielle Features wie Audio-Normalisierung, Equalizer und Visualizer, jedoch kÃļnnte dies auf einigen Systemen zu Aussetzern in der Musik fÃŧhren.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio-Normalisierung", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalisiert die Lautstärke aller Lieder, um die HÃļrerfahrung einheitlicher zu machen.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Räumliches Audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Macht die Musik räumlicher (3D-Effekt) (Beachte: Dies ist kein Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visuell", - "settings.header.visual.description": "Passe die visuellen Einstellungen fÃŧr Cider an.", - "settings.option.visual.windowBackgroundStyle": "Fensterhintergrund-Stil", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Keiner", - "settings.header.visual.windowBackgroundStyle.artwork": "Coverbild", - "settings.header.visual.windowBackgroundStyle.image": "Bild", - "settings.option.visual.animatedArtwork": "Animiertes Coverbild", // Dropdown - "settings.header.visual.animatedArtwork.always": "Immer", - "settings.header.visual.animatedArtwork.limited": "Beschränkt auf Seiten und Spezialeinträge", - "settings.header.visual.animatedArtwork.disable": "Überall deaktivieren", - "settings.option.visual.animatedArtworkQuality": "Qualität des Animierten Coverbilds", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Niedrig", - "settings.header.visual.animatedArtworkQuality.medium": "Mittel", - "settings.header.visual.animatedArtworkQuality.high": "Hoch", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Sehr hoch", - "settings.header.visual.animatedArtworkQuality.extreme": "Extrem", - "settings.option.visual.animatedWindowBackground": "Animierter Fensterhintergrund", // Toggle - "settings.option.visual.hardwareAcceleration": "Hardware-Beschleunigung", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "Erfordert Neustart der Anwendung", - "settings.header.visual.hardwareAcceleration.default": "Normal", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "PersÃļnliche Daten anzeigen", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "Liedtext", - "settings.header.lyrics.description": "Passe die Liedtext-Einstellungen fÃŧr Cider an.", - "settings.option.lyrics.enableMusixmatch": "Aktiviere Musixmatch-Liedtexte", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Aktiviere Karaoke-Modus (nur mit Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Bevorzugte Sprache fÃŧr Musixmatch-Übersetzung", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Aktiviere YouTube-Liedtexte fÃŧr Musikvideos", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Konnektivität", - "settings.header.connectivity.description": "Passe die Konnektivitäts-Einstellungen fÃŧr Cider an.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Wiedergabe-Benachrichtigungen", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "'Cider' anzeigen", - "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music' anzeigen", - "settings.option.connectivity.discordRPC.clearOnPause": "Leere Discord Rich Presence wenn pausiert", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble Delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Aktiviere LastFM Jetzt spielend", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Entferne KÃŧnstler-Featuring von Liedtitel (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtere gelooptes Lied (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "Experimentell", - "settings.header.experimental.description": "Passe die experimentellen Einstellungen fÃŧr Cider an.", - "settings.option.experimental.compactUI": "Kompaktes UI", // Toggle - "settings.option.experimental.close_button_hide": "Schließ-Taste soll die App verbergen", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "Die Audio-Spatialisierung ist deaktiviert. Um sie zu verwenden, musst du diese zuerst aktivieren.", - "spatial.spatialProperties": "Räumliche Einstellungen", - "spatial.width": "Breite", - "spatial.height": "HÃļhe", - "spatial.depth": "Tiefe", - "spatial.gain": "Gain", - "spatial.roomMaterials": "Raummaterialien", - "spatial.roomDimensions": "Raumabmessungen", - "spatial.roomPositions": "Raumpositionen", - "spatial.setDimensions": "Setze Abmessungen", - "spatial.setPositions": "Setze Positionen", - "spatial.up": "Oben", - "spatial.front": "Vorne", - "spatial.left": "Links", - "spatial.right": "Rechts", - "spatial.back": "Hinten", - "spatial.down": "Unten", - "spatial.listener": "HÃļrer*in", - "spatial.audioSource": "Audioquelle", - - // Settings - Unfinished - "settings.header.unfinished": "Unvollendet", - - // Web Remote - "remote.web.title": "Cider Remote", - "remote.web.description": "Scanne den QR-Code um dein Handy mit dieser Cider-Instanz zu verbinden", - - // About - "about.thanks": "Vielen lieben Dank an das Cider Collective Team und an alle Mithelfer." -} diff --git a/src/i18n/el_GR.jsonc b/src/i18n/el_GR.jsonc deleted file mode 100644 index ca100520..00000000 --- a/src/i18n/el_GR.jsonc +++ /dev/null @@ -1,299 +0,0 @@ -{ - - // i18n Info - "i18n.languageName": "ΕÎģÎģΡÎŊΚÎēÎŦ", - "i18n.languageNameEnglish": "Greek", - "i18n.category": "main", - "i18n.authors": "@down-bad", - - // App info - "app.name": "Cider", - - "date.format": "${d} ${m}, ${y}", - - // Dialogs - "dialog.cancel": "ΑÎēĪĪĪ‰ĪƒÎˇ", - "dialog.ok": "ΟΚ", - - // Notification - "notification.updatingLibrarySongs": "ΕÎŊΡÎŧÎ­ĪĪ‰ĪƒÎˇ βΚβÎģΚÎŋθΎÎēÎˇĪ‚ Ī„ĪÎąÎŗÎŋĪ…Î´ÎšĪŽÎŊ...", - "notification.updatingLibraryAlbums": "ΕÎŊΡÎŧÎ­ĪĪ‰ĪƒÎˇ βΚβÎģΚÎŋθΎÎēÎˇĪ‚ ÎŦÎģÎŧĪ€ÎŋĪ…Îŧ...", - "notification.updatingLibraryArtists": "ΕÎŊΡÎŧÎ­ĪĪ‰ĪƒÎˇ βΚβÎģΚÎŋθΎÎēÎˇĪ‚ ÎēÎąÎģÎģÎšĪ„Îĩ·ÎŊĪŽÎŊ...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "ΜÎŦθÎĩĪ„Îĩ Ī€ÎĩĪÎšĪƒĪƒĪŒĪ„ÎĩĪÎą", - "term.accountSettings": "ÎĄĪ…Î¸ÎŧÎ¯ĪƒÎĩÎšĪ‚ ÎģÎŋÎŗÎąĪÎšÎąĪƒÎŧÎŋĪ", - "term.logout": "Î‘Ī€ÎŋĪƒĪÎŊδÎĩĪƒÎˇ", - "term.login": "ÎŖĪÎŊδÎĩĪƒÎˇ", - "term.about": "ÎŖĪ‡ÎĩĪ„ÎšÎēÎŦ ÎŧÎĩ", - "term.privateSession": "Î™Î´ÎšĪ‰Ī„ÎšÎēÎŽ Ī€ÎĩĪÎ¯ÎŋδÎŋĪ‚ ÎģÎĩÎšĪ„ÎŋĪ…ĪÎŗÎ¯ÎąĪ‚", - "term.queue": "ÎŸĪ…ĪÎŦ", - "term.search": "Î•ĪĪÎĩĪƒÎˇ", - "term.library": "ΒιβÎģΚÎŋθΎÎēΡ", - "term.listenNow": "ΑÎēĪĪŒÎąĪƒÎˇ", - "term.browse": "ΠÎĩĪÎšÎŽÎŗÎˇĪƒÎˇ", - "term.radio": "ÎĄÎŦδΚÎŋ", - "term.recentlyAdded": "Î ĪĪŒĪƒĪ†ÎąĪ„ÎĩĪ‚ ΀΁ÎŋĪƒÎ¸ÎŽÎēÎĩĪ‚", - "term.songs": "Î¤ĪÎąÎŗÎŋĪÎ´ÎšÎą", - "term.albums": "ΆÎģÎŧĪ€ÎŋĪ…Îŧ", - "term.artists": "ΚαÎģÎģÎšĪ„Î­Ī‡ÎŊÎĩĪ‚", - "term.podcasts": "Podcast", - "term.playlists": "Î›Î¯ĪƒĪ„ÎĩĪ‚ ÎąÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽĪ‚", - "term.playlist": "Î›Î¯ĪƒĪ„Îą ÎąÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽĪ‚", - "term.play": "ΑÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽ", - "term.pause": "Î ÎąĪĪƒÎˇ", - "term.previous": "Î ĪÎŋÎˇÎŗÎŋĪÎŧÎĩÎŊÎŋ", - "term.next": "Î•Ī€ĪŒÎŧÎĩÎŊÎŋ", - "term.shuffle": "Î¤Ī…Ī‡ÎąÎ¯Îą ΃ÎĩÎšĪÎŦ", - "term.repeat": "Î•Ī€ÎąÎŊÎŦÎģÎˇĪˆÎˇ", - "term.volume": "ΈÎŊĪ„ÎąĪƒÎˇ", - "term.mute": "ÎŖÎ¯ÎŗÎąĪƒÎˇ", - "term.unmute": "ÎšÎąĪ„ÎŦĪÎŗÎˇĪƒÎˇ ĪƒÎ¯ÎŗÎąĪƒÎˇĪ‚", - "term.share": "ΚÎŋΚÎŊÎŽ Î§ĪÎŽĪƒÎˇ", - "term.settings": "ÎĄĪ…Î¸ÎŧÎ¯ĪƒÎĩÎšĪ‚", - "term.seeAll": "Î ĪÎŋβÎŋÎģÎŽ ΌÎģΉÎŊ", - "term.sortBy": "ΤιΞΚÎŊΌÎŧÎˇĪƒÎˇ ÎēÎąĪ„ÎŦ", - "term.sortBy.album": "ΆÎģÎŧĪ€ÎŋĪ…Îŧ", - "term.sortBy.artist": "ΚαÎģÎģÎšĪ„Î­Ī‡ÎŊΡ", - "term.sortBy.name": "ΌÎŊÎŋÎŧÎą", - "term.sortBy.genre": "ΕίδÎŋĪ‚", - "term.sortBy.releaseDate": "ΗÎŧÎĩ΁ÎŋÎŧΡÎŊÎ¯Îą ÎēĪ…ÎēÎģÎŋΆÎŋĪÎ¯ÎąĪ‚", - "term.sortBy.duration": "ΔιÎŦ΁ÎēÎĩΚι", - "term.sortOrder": "Α-Ί", - "term.sortOrder.ascending": "Î‘ĪÎžÎŋĪ…ĪƒÎą", - "term.sortOrder.descending": "ÎĻθίÎŊÎŋĪ…ĪƒÎą", - "term.viewAs": "Î ĪÎŋβÎŋÎģÎŽ Ή΂", - "term.viewAs.coverArt": "Î•ÎžĪŽĪ†Ī…ÎģÎģÎŋ", - "term.viewAs.list": "Î›Î¯ĪƒĪ„Îą", - "term.size": "ÎœÎ­ÎŗÎĩθÎŋĪ‚", - "term.size.normal": "ΚαÎŊÎŋÎŊΚÎēΌ", - "term.size.compact": "ÎŖĪ…ÎŧĪ€ÎąÎŗÎŽ", - "term.enable": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ", - "term.disable": "Î‘Ī€ÎĩÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ", - "term.enabled": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋΚΡÎŧέÎŊÎŋ", - "term.disabled": "Î‘Ī€ÎĩÎŊÎĩĪÎŗÎŋĪ€ÎŋΚΡÎŧέÎŊÎŋ", - "term.connect": "ÎŖĪÎŊδÎĩĪƒÎˇ", - "term.connecting": "ΓίÎŊÎĩĪ„ÎąÎš ĪƒĪÎŊδÎĩĪƒÎˇ", - "term.disconnect": "Î‘Ī€ÎŋĪƒĪÎŊδÎĩĪƒÎˇ", - "term.authed": "Î•Ī€ÎšÎē΅΁ΉÎŧέÎŊÎŋ", - "term.confirm": "ÎŖÎ¯ÎŗÎŋĪ…ĪÎą;", - "term.more": "ΠÎĩĪÎšĪƒĪƒĪŒĪ„ÎĩĪÎą", - "term.less": "Î›ÎšÎŗĪŒĪ„ÎĩĪÎą", - "term.showMore": "ΕÎŧΆÎŦÎŊÎšĪƒÎˇ Ī€ÎĩĪÎšĪƒĪƒĪŒĪ„Îĩ΁ΉÎŊ", - "term.showLess": "ΕÎŧΆÎŦÎŊÎšĪƒÎˇ ÎģÎšÎŗĪŒĪ„Îĩ΁ΉÎŊ", - "term.topSongs" : "ΚÎŋĪĪ…Ī†ÎąÎ¯Îą Ī„ĪÎąÎŗÎŋĪÎ´ÎšÎą", - "term.latestReleases": "ΤÎĩÎģÎĩĪ…Ī„ÎąÎ¯ÎĩĪ‚ ÎēĪ…ÎēÎģÎŋΆÎŋĪÎ¯ÎĩĪ‚", - "term.time.added": "Î ĪÎŋĪƒĪ„Î­Î¸ÎˇÎēÎĩ", - "term.time.released": "ÎšĪ…ÎēÎģÎŋĪ†ĪŒĪÎˇĪƒÎĩ", - "term.time.updated": "ΕÎŊΡÎŧÎĩĪĪŽÎ¸ÎˇÎēÎĩ", - "term.time.hours": "ĪŽĪÎĩĪ‚", - "term.time.hour": "ĪŽĪÎą", - "term.time.minutes": "ÎģÎĩ΀΄ÎŦ", - "term.time.minute": "ÎģÎĩĪ€Ī„ĪŒ", - "term.time.seconds": "δÎĩĪ…Ī„Îĩ΁ΌÎģÎĩĪ€Ī„Îą", - "term.time.second": "δÎĩĪ…Ī„Îĩ΁ΌÎģÎĩ΀΄Îŋ", - "term.fullscreenView": "ΠÎģÎŽĪÎˇĪ‚ ÎŋÎ¸ĪŒÎŊΡ", - "term.defaultView": "ΚαÎŊÎŋÎŊΚÎēÎŽ ÎŋÎ¸ĪŒÎŊΡ", - "term.spacializedAudioSetting": "Î§Ī‰ĪÎšÎēÎŽ ĪĪÎ¸ÎŧÎšĪƒÎˇ ÎŽĪ‡ÎŋĪ…", - "term.clearAll": "ΕÎēÎēιθÎŦĪÎšĪƒÎˇ ΌÎģΉÎŊ", - "term.recentStations": "Î ĪĪŒĪƒĪ†ÎąĪ„ÎŋΚ ĪƒĪ„ÎąÎ¸ÎŧÎŋί", - "term.language": "ΓÎģĪŽĪƒĪƒÎą", - "term.funLanguages": "Για Ī€ÎģÎŦÎēÎą", - "term.noLyrics": "ÎĻĪŒĪĪ„Ī‰ĪƒÎˇ... / ΔÎĩÎŊ Î˛ĪÎ­Î¸ÎˇÎēÎąÎŊ ĪƒĪ„Î¯Ī‡ÎŋΚ. / ÎŸĪĪ‡ÎˇĪƒĪ„ÎšÎēΌ.", - "term.copyright": "Copyright", - "term.rightsReserved": "ΌÎģÎą Ī„Îą δΚÎēÎąÎšĪŽÎŧÎąĪ„Îą Î´ÎšÎąĪ„ÎˇĪÎŋĪÎŊĪ„ÎąÎš.", - "term.sponsor": "ΧÎŋĪÎŽÎŗÎˇĪƒÎĩ ÎąĪ…Ī„ĪŒ Ī„Îŋ Î­ĪÎŗÎŋ", - "term.ciderTeam": "ΟÎŧÎŦδι Cider", - "term.developer": "Î ĪÎŋÎŗĪÎąÎŧÎŧÎąĪ„ÎšĪƒĪ„ÎŽĪ‚", - "term.socialTeam": "ΚÎŋΚÎŊΉÎŊΚÎēÎŽ ΟÎŧÎŦδι", - "term.contributors": "ÎŖĪ…ÎŊÎĩÎšĪƒĪ†Î­ĪÎŋÎŊĪ„ÎĩĪ‚", - "term.equalizer": "Î™ĪƒÎŋĪƒĪ„ÎąÎ¸ÎŧÎšĪƒĪ„ÎŽĪ‚", - "term.reset": "Î•Ī€ÎąÎŊÎąĪ†Îŋ΁ÎŦ", - "term.tracks": "Ī„ĪÎąÎŗÎŋĪÎ´ÎšÎą", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "ΒίÎŊĪ„ÎĩÎŋ", - "term.menu": "ΜÎĩÎŊÎŋĪ", - "action.showAlbum": "ΕÎŧΆÎŦÎŊÎšĪƒÎˇ ÎŋÎģΌÎēÎģÎˇĪÎŋĪ… ÎŦÎģÎŧĪ€ÎŋĪ…Îŧ", - - // Home - "home.title": "Î‘ĪĪ‡ÎšÎēÎŽ", - "home.recentlyPlayed": "ÎˆĪ€ÎąÎšÎžÎąÎŊ Ī€ĪĪŒĪƒĪ†ÎąĪ„Îą", - "home.recentlyAdded": "Î ĪĪŒĪƒĪ†ÎąĪ„ÎĩĪ‚ ΀΁ÎŋĪƒÎ¸ÎŽÎēÎĩĪ‚", - "home.artistsFeed": "ÎĄÎŋÎŽ ΄ΉÎŊ ÎēÎąÎģÎģÎšĪ„Îĩ·ÎŊĪŽÎŊ ΃ÎŋĪ…", - "home.artistsFeed.noArtist": "ΑÎēÎŋÎģÎŋĪÎ¸ÎˇĪƒÎĩ ÎŧÎĩĪÎšÎēÎŋĪĪ‚ ÎēÎąÎģÎģÎšĪ„Î­Ī‡ÎŊÎĩĪ‚ Ī€ĪĪŽĪ„Îą ÎēιΚ ÎŋΚ Ī„ÎĩÎģÎĩĪ…Ī„ÎąÎ¯ÎĩĪ‚ ÎēĪ…ÎēÎģÎŋΆÎŋĪÎ¯ÎĩĪ‚ Ī„ÎŋĪ…Ī‚ θι ÎĩÎŧĪ†ÎąÎŊίÎļÎŋÎŊĪ„ÎąÎš ÎĩÎ´ĪŽ", - "home.madeForYou": "ΔηÎŧΚÎŋĪ…ĪÎŗÎŽÎ¸ÎˇÎēÎĩ ÎŗÎšÎą Îĩ΃ÎŦĪ‚", - "home.friendsListeningTo": "Οι Ī†Î¯ÎģÎŋΚ ΃ÎŋĪ… ÎąÎēÎŋĪÎŊ", - "home.followedArtists": "ΚαÎģÎģÎšĪ„Î­Ī‡ÎŊÎĩĪ‚ Ī€ÎŋĪ… ÎąÎēÎŋÎģÎŋĪ…Î¸ÎĩÎ¯Ī„Îĩ", - // Errors - "error.appleMusicSubRequired": "ΤÎŋ Apple Music ÎąĪ€ÎąÎšĪ„Îĩί ÎŧΚι ĪƒĪ…ÎŊÎ´ĪÎŋÎŧÎŽ.", - "error.connectionError": "ΔÎĩÎŊ ÎĩίÎŊιΚ Î´Ī…ÎŊÎąĪ„ÎŽ Ρ ĪƒĪÎŊδÎĩĪƒÎˇ ÎŧÎĩ Ī„Îŋ Apple Music.", - "error.noResults": "ΚαÎŊέÎŊÎą ÎąĪ€ÎŋĪ„Î­ÎģÎĩ΃ÎŧÎą.", - "error.noResults.description": "ΔÎŋÎēΚÎŧÎŦĪƒĪ„Îĩ ÎŧΚι ÎŊέι ÎąÎŊÎąÎļÎŽĪ„ÎˇĪƒÎˇ.", - - //Podcasts - "podcast.followOnCider": "ΑÎēÎŋÎģÎŋĪÎ¸ÎˇĪƒÎˇ ĪƒĪ„Îŋ Cider", - "podcast.followedOnCider": "ΑÎēÎŋÎģÎŋĪ…Î¸ÎĩÎ¯Ī„Îĩ ĪƒĪ„Îŋ Cider", - "podcast.subscribeOnItunes": "ÎŖĪ…ÎŊÎ´ĪÎŋÎŧÎŽ ĪƒĪ„Îŋ iTunes", - "podcast.subscribedOnItunes": "ÎŖĪ…ÎŊÎ´ĪÎŋÎŧÎˇĪ„ÎŽĪ‚ ĪƒĪ„Îŋ iTunes", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "Î•Ī€ÎĩÎšĪƒĪŒÎ´ÎšÎą", - "podcast.playEpisode": "ΑÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽ ÎĩĪ€ÎĩÎšĪƒÎŋδίÎŋĪ…", - "podcast.website": "Î™ĪƒĪ„ĪŒĪ„ÎŋĪ€ÎŋĪ‚ Podcast", - - // Actions - "action.addToLibrary": "Î ĪÎŋĪƒÎ¸ÎŽÎēΡ ĪƒĪ„Îˇ βΚβÎģΚÎŋθΎÎēΡ", - "action.addToLibrary.success": "Î ĪÎŋĪƒĪ„Î­Î¸ÎˇÎēÎĩ ĪƒĪ„Îˇ βΚβÎģΚÎŋθΎÎēΡ", - "action.addToLibrary.error": "ÎŖĪ†ÎŦÎģÎŧÎą Î ĪÎŋĪƒÎ¸ÎŽÎēÎˇĪ‚ ĪƒĪ„Îˇ βΚβÎģΚÎŋθΎÎēÎˇĪ‚", - "action.removeFromLibrary": "Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇ ÎąĪ€ĪŒ Ī„Îˇ βΚβÎģΚÎŋθΎÎēΡ", - "action.removeFromLibrary.success": "Î‘Ī†ÎąÎšĪÎ­Î¸ÎˇÎēÎĩ ÎąĪ€ĪŒ Ī„Îˇ βΚβÎģΚÎŋθΎÎēΡ", - "action.addToQueue": "Î ĪÎŋĪƒÎ¸ÎŽÎēΡ ĪƒĪ„ÎˇÎŊ Îŋ΅΁ÎŦ", - "action.addToQueue.success": "Î ĪÎŋĪƒĪ„Î­Î¸ÎˇÎēÎĩ ĪƒĪ„ÎˇÎŊ Îŋ΅΁ÎŦ", - "action.addToQueue.error": "Î ĪÎŋĪƒĪ„Î­Î¸ÎˇÎēÎĩ ĪƒĪ„ÎˇÎŊ Îŋ΅΁ÎŦ", - "action.removeFromQueue": "Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇ ÎąĪ€ĪŒ Ī„ÎˇÎŊ Îŋ΅΁ÎŦ", - "action.removeFromQueue.success": "Î‘Ī†ÎąÎšĪÎ­Î¸ÎˇÎēÎĩ ÎąĪ€ĪŒ Ī„ÎˇÎŊ Îŋ΅΁ÎŦ", - "action.removeFromQueue.error": "ÎŖĪ†ÎŦÎģÎŧÎą Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇĪ‚ ÎąĪ€ĪŒ Ī„ÎˇÎŊ Îŋ΅΁ÎŦ", - "action.addToPlaylist": "Î ĪÎŋĪƒÎ¸ÎŽÎēΡ ΃Îĩ ÎģÎ¯ĪƒĪ„Îą", - "action.removeFromPlaylist": "Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇ ÎąĪ€ĪŒ ÎģÎ¯ĪƒĪ„Îą", - "action.addToFavorites": "Î ĪÎŋĪƒÎ¸ÎŽÎēΡ ĪƒĪ„Îą ÎąÎŗÎąĪ€ÎˇÎŧέÎŊÎą", - "action.follow": "ΑÎēÎŋÎģÎŋĪÎ¸ÎˇĪƒÎˇ", - "action.follow.success": "ΑÎēÎŋÎģÎŋĪ…Î¸ÎŽÎ¸ÎˇÎēÎĩ", - "action.follow.error": "ÎŖĪ†ÎŦÎģÎŧÎą ÎąÎēÎŋÎģÎŋĪÎ¸ÎˇĪƒÎˇĪ‚", - "action.unfollow": "ΔιαÎēÎŋĪ€ÎŽ ÎąÎēÎŋÎģÎŋĪÎ¸ÎˇĪƒÎˇĪ‚", - "action.unfollow.success": "ÎˆÎŗÎšÎŊÎĩ δΚιÎēÎŋĪ€ÎŽ ÎąÎēÎŋÎģÎŋĪÎ¸ÎˇĪƒÎˇĪ‚", - "action.unfollow.error": "ÎŖĪ†ÎŦÎģÎŧÎą δΚιÎēÎŋĪ€ÎŽĪ‚ ÎąÎēÎŋÎģÎŋĪÎ¸ÎˇĪƒÎˇĪ‚ ", - "action.playNext": "ΑÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽ Ή΂ ÎĩĪ€ĪŒÎŧÎĩÎŊÎŋĪ…", - "action.playLater": "ΑÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽ ÎąĪÎŗĪŒĪ„ÎĩĪÎą", - "action.startRadio": "ΈÎŊÎąĪÎžÎˇ ĪÎąÎ´ÎšÎŋĪ†ĪŽÎŊÎŋĪ…", - "action.goToArtist": "ΜÎĩĪ„ÎŦÎ˛ÎąĪƒÎˇ ΃Îĩ ÎēÎąÎģÎģÎšĪ„Î­Ī‡ÎŊΡ", - "action.goToAlbum": "ΜÎĩĪ„ÎŦÎ˛ÎąĪƒÎˇ ΃Îĩ ÎŦÎģÎŧĪ€ÎŋĪ…Îŧ", - "action.moveToTop": "ΜÎĩĪ„ÎąÎēίÎŊÎˇĪƒÎˇ ĪƒĪ„Îˇ ÎēÎŋĪĪ…Ī†ÎŽ", - "action.share": "ΚÎŋΚÎŊÎŽ Ī‡ĪÎŽĪƒÎˇ", - "action.rename": "ΜÎĩĪ„ÎŋÎŊÎŋÎŧÎąĪƒÎ¯Îą", - "action.love": "ΜÎŋĪ… ÎąĪÎ­ĪƒÎĩΚ Ī€ÎŋÎģĪ", - "action.unlove": "ΑÎŊÎąÎ¯ĪÎĩĪƒÎˇ \"ΜÎŋĪ… ÎąĪÎ­ĪƒÎĩΚ\"", - "action.dislike": "ΔÎĩÎŊ ÎŧÎŋĪ… ÎąĪÎ­ĪƒÎĩΚ", - "action.undoDislike": "ΑÎŊÎąÎ¯ĪÎĩĪƒÎˇ \"ΔÎĩÎŊ ÎŧÎŋĪ… ÎąĪÎ­ĪƒÎĩΚ\"", - "action.showWebRemoteQR": "ΕÎŧΆÎŦÎŊÎšĪƒÎˇ Web Remote QR", - "action.playTracksNext": "ΑÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽ ${app.selectedMediaItems.length} Ī„ĪÎąÎŗÎŋĪ…Î´ÎšĪŽÎŊ Ή΂ ÎĩĪ€ĪŒÎŧÎĩÎŊΉÎŊ", - "action.playTracksLater": "ΑÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽ ${app.selectedMediaItems.length} Ī„ĪÎąÎŗÎŋĪ…Î´ÎšĪŽÎŊ ÎąĪÎŗĪŒĪ„ÎĩĪÎą", - "action.removeTracks": "Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇ ${self.selectedItems.length} Ī„ĪÎąÎŗÎŋĪ…Î´ÎšĪŽÎŊ ÎąĪ€ĪŒ Ī„ÎˇÎŊ Îŋ΅΁ÎŦ", - "action.import": "Î•ÎšĪƒÎąÎŗĪ‰ÎŗÎŽ", - "action.export": "Î•ÎžÎąÎŗĪ‰ÎŗÎŽ", - - // Settings - General - "settings.header.general": "ΓÎĩÎŊΚÎēÎŦ", - "settings.header.general.description": "Î ĪÎŋĪƒÎąĪÎŧÎŋÎŗÎŽ ÎŗÎĩÎŊΚÎēĪŽÎŊ ĪĪ…Î¸ÎŧÎ¯ĪƒÎĩΉÎŊ ÎŗÎšÎą Ī„Îŋ Cider.", - "settings.option.general.language": "ΓÎģĪŽĪƒĪƒÎą", - - // Language optgroups - "settings.option.general.language.main": "ΓÎģĪŽĪƒĪƒÎĩĪ‚", - "settings.option.general.language.fun": "ΓÎģĪŽĪƒĪƒÎĩĪ‚ ÎŗÎšÎą Ī€ÎģÎŦÎēÎą", - "settings.option.general.language.unsorted": "Î‘Ī„ÎąÎžÎšÎŊΌÎŧÎˇĪ„ÎĩĪ‚", - - // Settings - Audio - "settings.header.audio": "Î‰Ī‡ÎŋĪ‚", - "settings.header.audio.description": "Î ĪÎŋĪƒÎąĪÎŧÎŋÎŗÎŽ ĪĪ…Î¸ÎŧÎ¯ĪƒÎĩΉÎŊ ÎŽĪ‡ÎŋĪ… ÎŗÎšÎą Ī„Îŋ Cider.", - "settings.option.audio.quality": "ΠÎŋÎšĪŒĪ„ÎˇĪ„Îą Î‰Ī‡ÎŋĪ…", // Dropdown - "settings.header.audio.quality.high": "ÎĨĪˆÎˇÎģÎŽ", - "settings.header.audio.quality.low": "ΧιÎŧΡÎģÎŽ", - "settings.header.audio.quality.auto": "Î‘Ī…Ī„ĪŒÎŧÎąĪ„Îˇ", - "settings.option.audio.seamlessTransition": "ΑδιÎŦÎēÎŋĪ€Îˇ ΜÎĩĪ„ÎŦÎ˛ÎąĪƒÎˇ Î‰Ī‡ÎŋĪ…", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ Î ĪÎŋÎˇÎŗÎŧέÎŊÎˇĪ‚ ΛÎĩÎšĪ„ÎŋĪ…ĪÎŗÎšÎēĪŒĪ„ÎˇĪ„ÎąĪ‚", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎšĪŽÎŊĪ„ÎąĪ‚ Ī„Îˇ ÎģÎĩÎšĪ„ÎŋĪ…ĪÎŗÎšÎēĪŒĪ„ÎˇĪ„Îą AudioContext θι ÎĩĪ€ÎšĪ„ĪÎ­ĪˆÎĩΚ ΃Îĩ ÎĩĪ€ÎĩÎēĪ„ÎąÎŧέÎŊÎĩĪ‚ Î´Ī…ÎŊÎąĪ„ĪŒĪ„ÎˇĪ„ÎĩĪ‚ ÎŽĪ‡ÎŋĪ… ĪŒĪ€Ī‰Ī‚ ΚαÎŊÎŋÎŊΚÎēÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ΈÎŊĪ„ÎąĪƒÎˇĪ‚ Î‰Ī‡ÎŋĪ…, Î™ĪƒÎŋĪƒĪ„ÎąÎ¸ÎŧÎšĪƒĪ„Î­Ī‚ ÎēιΚ ÎŸĪ€Ī„ÎšÎēÎŋĪ€ÎŋÎšÎˇĪ„Î­Ī‚, Ī‰ĪƒĪ„ĪŒĪƒÎŋ ΃Îĩ ÎēÎŦĪ€ÎŋΚι ĪƒĪ…ĪƒĪ„ÎŽÎŧÎąĪ„Îą ÎŧĪ€Îŋ΁Îĩί ÎŊÎą ΀΁ÎŋÎēÎąÎģÎ­ĪƒÎĩΚ Ī„ĪÎąĪÎģÎšĪƒÎŧÎą ÎŽĪ‡ÎŋĪ….", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "ΚαÎŊÎŋÎŊΚÎēÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ΈÎŊĪ„ÎąĪƒÎˇĪ‚ Î‰Ī‡ÎŋĪ…", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "ΚαÎŊÎŋÎŊΚÎēÎŋĪ€ÎŋΚÎĩί Ī„ÎˇÎŊ έÎŊĪ„ÎąĪƒÎˇ ÎŗÎšÎą ÎŧÎĩÎŧÎŋÎŊΉÎŧέÎŊÎą ÎēÎŋÎŧÎŧÎŦĪ„ÎšÎą ÎŗÎšÎą ÎŧΚι Ī€ÎšÎŋ ÎŋÎŧÎŋÎšĪŒÎŧÎŋĪĪ†Îˇ ÎĩÎŧĪ€ÎĩÎšĪÎ¯Îą ÎąÎēĪĪŒÎąĪƒÎˇĪ‚.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Î§Ī‰ĪÎšÎēÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ Î‰Ī‡ÎŋĪ…", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "ΠΚÎŋ Ī„ĪÎšĪƒÎ´ÎšÎŦĪƒĪ„ÎąĪ„ÎŋĪ‚ ÎēιΚ Ī‡Ī‰ĪÎšÎēÎŋĪ€ÎŋΚΡÎŧέÎŊÎŋĪ‚ ÎŽĪ‡ÎŋĪ‚ (ĪƒÎˇÎŧÎĩÎ¯Ī‰ĪƒÎˇ: Î‘Ī…Ī„ĪŒ δÎĩÎŊ ÎĩίÎŊιΚ Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "ÎŸĪ€Ī„ÎšÎēÎŦ", - "settings.header.visual.description": "Î ĪÎŋĪƒÎąĪÎŧÎŋÎŗÎŽ ÎŋĪ€Ī„ÎšÎēĪŽÎŊ ĪĪ…Î¸ÎŧÎ¯ĪƒÎĩΉÎŊ ÎŗÎšÎą Ī„Îŋ Cider.", - "settings.option.visual.windowBackgroundStyle": "ÎŖĪ„Ī…Îģ ÎĻΌÎŊĪ„ÎŋĪ… Î ÎąĪÎąÎ¸ĪĪÎŋĪ…", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "ΚαÎŊέÎŊÎą", - "settings.header.visual.windowBackgroundStyle.artwork": "Î•ÎžĪŽĪ†Ī…ÎģÎģÎŋ", - "settings.header.visual.windowBackgroundStyle.image": "ΕιÎēΌÎŊÎą", - "settings.option.visual.animatedArtwork": "ΚιÎŊÎŋĪÎŧÎĩÎŊÎŋ Î•ÎžĪŽĪ†Ī…ÎģÎģÎŋ", // Dropdown - "settings.header.visual.animatedArtwork.always": "ΠÎŦÎŊĪ„Îą", - "settings.header.visual.animatedArtwork.limited": "ΠÎĩĪÎšÎŋĪÎšĪƒÎŧĪŒĪ‚ ΃Îĩ ΃ÎĩÎģίδÎĩĪ‚ ÎēιΚ ÎĩΚδΚÎēÎ­Ī‚ ÎēÎąĪ„ÎąĪ‡Ī‰ĪÎŽĪƒÎĩÎšĪ‚", - "settings.header.visual.animatedArtwork.disable": "Î‘Ī€ÎĩÎŊÎĩĪÎŗÎŋĪ€ÎŋΚΡÎŧέÎŊÎŋ Ī€ÎąÎŊĪ„ÎŋĪ", - "settings.option.visual.animatedArtworkQuality": "ΠÎŋÎšĪŒĪ„ÎˇĪ„Îą ΚιÎŊÎŋĪÎŧÎĩÎŊÎŋĪ… Î•ÎžĪ‰Ī†ĪÎģÎģÎŋĪ…", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "ΧιÎŧΡÎģÎŽ", - "settings.header.visual.animatedArtworkQuality.medium": "ÎœÎ­Ī„ĪÎšÎą", - "settings.header.visual.animatedArtworkQuality.high": "ÎĨĪˆÎˇÎģÎŽ", - "settings.header.visual.animatedArtworkQuality.veryHigh": "ΠÎŋÎģĪ ÎĨĪˆÎˇÎģÎŽ", - "settings.header.visual.animatedArtworkQuality.extreme": "ΑÎēĪÎąÎ¯Îą", - "settings.option.visual.animatedWindowBackground": "ΚιÎŊÎŋĪÎŧÎĩÎŊÎŋ ÎĻΌÎŊĪ„Îŋ Î ÎąĪÎąÎ¸ĪĪÎŋĪ…", // Toggle - "settings.option.visual.hardwareAcceleration": "Î•Ī€ÎšĪ„ÎŦ·΅ÎŊĪƒÎˇ ÎĨÎģΚÎēÎŋĪ", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "Î‘Ī€ÎąÎšĪ„Îĩί ÎĩĪ€ÎąÎŊÎĩÎēÎēίÎŊÎˇĪƒÎˇ", - "settings.header.visual.hardwareAcceleration.default": "Î ĪÎŋÎĩĪ€ÎšÎģÎŋÎŗÎŽ", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "ΕÎŧΆÎŦÎŊÎšĪƒÎˇ ΀΁ÎŋĪƒĪ‰Ī€ÎšÎēĪŽÎŊ ĪƒĪ„ÎŋÎšĪ‡ÎĩÎ¯Ī‰ÎŊ", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "ÎŖĪ„Î¯Ī‡ÎŋΚ", - "settings.header.lyrics.description": "Î ĪÎŋĪƒÎąĪÎŧÎŋÎŗÎŽ ĪĪ…Î¸ÎŧÎ¯ĪƒÎĩΉÎŊ ĪƒĪ„Î¯Ī‡Ī‰ÎŊ ÎŗÎšÎą Ī„Îŋ Cider.", - "settings.option.lyrics.enableMusixmatch": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ÎŖĪ„Î¯Ī‡Ī‰ÎŊ Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ΛÎĩÎšĪ„ÎŋĪ…ĪÎŗÎ¯ÎąĪ‚ ÎšÎąĪÎąĪŒÎēÎĩ (Musixmatch ÎŧΌÎŊÎŋ)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Î ĪÎŋĪ„ÎšÎŧĪŽÎŧÎĩÎŊΡ ΓÎģĪŽĪƒĪƒÎą ΜÎĩĪ„ÎŦĪ†ĪÎąĪƒÎˇĪ‚ Musixmatch", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ÎŖĪ„Î¯Ī‡Ī‰ÎŊ Youtube ÎŗÎšÎą ΜÎŋĪ…ĪƒÎšÎēÎŦ ΒίÎŊĪ„ÎĩÎŋ", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "ÎŖĪÎŊδÎĩĪƒÎˇ", - "settings.header.connectivity.description": "Î ĪÎŋĪƒÎąĪÎŧÎŋÎŗÎŽ ĪĪ…Î¸ÎŧÎ¯ĪƒÎĩΉÎŊ ĪƒĪÎŊδÎĩĪƒÎˇĪ‚ ÎŗÎšÎą Ī„Îŋ Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "ΕιδÎŋĪ€ÎŋÎšÎŽĪƒÎĩÎšĪ‚ ΑÎŊÎąĪ€ÎąĪÎąÎŗĪ‰ÎŗÎŽĪ‚", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "ΕÎŧΆÎŦÎŊÎšĪƒÎˇ Ή΂ 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "ΕÎŧΆÎŦÎŊÎšĪƒÎˇ Ή΂ 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "ΕÎēÎēιθÎŦĪÎšĪƒÎˇ Ī„ÎŋĪ… Discord Rich Presence ĪƒĪ„ÎˇÎŊ Î ÎąĪĪƒÎˇ", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "ÎšÎąÎ¸Ī…ĪƒĪ„Î­ĪÎˇĪƒÎˇ LastFM Scrobble (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ LastFM \"Now Playing\"", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇ ÎēÎąÎģÎģÎšĪ„Îĩ·ÎŊĪŽÎŊ feature ÎąĪ€ĪŒ Ī„ÎŋÎŊ Ī„Î¯Ī„ÎģÎŋ Ī„ÎŋĪ… Ī„ĪÎąÎŗÎŋĪ…Î´ÎšÎŋĪ (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "ÎĻΚÎģ΄΁ÎŦĪÎšĪƒÎŧÎą ÎĩĪ€ÎąÎŊÎĩΚÎģΡÎŧÎŧέÎŊÎŋĪ… Ī„ĪÎąÎŗÎŋĪ…Î´ÎšÎŋĪ (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "ΠÎĩÎšĪÎąÎŧÎąĪ„ÎšÎēÎ­Ī‚", - "settings.header.experimental.description": "Î ĪÎŋĪƒÎąĪÎŧÎŋÎŗÎŽ Ī€ÎĩÎšĪÎąÎŧÎąĪ„ÎšÎēĪŽÎŊ ĪĪ…Î¸ÎŧÎ¯ĪƒÎĩΉÎŊ ÎŗÎšÎą Ī„Îŋ Cider.", - "settings.option.experimental.compactUI": "ÎŖĪ…ÎŧĪ€ÎąÎŗÎŽĪ‚ ΔιÎĩĪ€ÎąĪ†ÎŽ", // Toggle - "settings.option.experimental.closeButtonBehaviour": "ÎŖĪ…ÎŧĪ€ÎĩĪÎšĪ†Îŋ΁ÎŦ ΚÎŋĪ…ÎŧĪ€ÎšÎŋĪ Î•ÎžĪŒÎ´ÎŋĪ…", - "settings.option.experimental.closeButtonBehaviour.quit": "ΈΞÎŋδÎŋĪ‚ Ī„ÎŋĪ… Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "ΕÎģÎąĪ‡ÎšĪƒĪ„ÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ĪƒĪ„Îˇ ÎŗĪÎąÎŧÎŧÎŽ ÎĩĪÎŗÎąĪƒÎšĪŽÎŊ", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "ΕÎģÎąĪ‡ÎšĪƒĪ„ÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ĪƒĪ„Îˇ ÎŗĪ‰ÎŊÎ¯Îą ÎŗĪÎąÎŧÎŧÎŽĪ‚ ÎĩĪÎŗÎąĪƒÎšĪŽÎŊ", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.spatialProperties" : "Î§Ī‰ĪÎšÎēÎ­Ī‚ Î™Î´ÎšĪŒĪ„ÎˇĪ„ÎĩĪ‚", - "spatial.width" : "ΠÎģÎŦĪ„ÎŋĪ‚", - "spatial.height" : "ÎŽĪˆÎŋĪ‚", - "spatial.depth" : "ΒÎŦθÎŋĪ‚", - "spatial.gain" : "Î‘Ī€ÎŋÎģιβΎ", - "spatial.roomMaterials" : "ÎĨÎģΚÎēÎŦ Î”Ī‰ÎŧÎąĪ„Î¯ÎŋĪ…", - "spatial.roomDimensions" : "Î”ÎšÎąĪƒĪ„ÎŦ΃ÎĩÎšĪ‚ Î”Ī‰ÎŧÎąĪ„Î¯ÎŋĪ…", - "spatial.roomPositions" : "Î˜Î­ĪƒÎĩÎšĪ‚ Î”Ī‰ÎŧÎąĪ„Î¯ÎŋĪ…", - "spatial.setDimensions" : "ÎŸĪÎšĪƒÎŧĪŒĪ‚ Î”ÎšÎąĪƒĪ„ÎŦ΃ÎĩΉÎŊ", - "spatial.setPositions" : "ÎŸĪÎšĪƒÎŧĪŒĪ‚ Î˜Î­ĪƒÎĩΉÎŊ", - "spatial.up" : "ΠÎŦÎŊΉ", - "spatial.front" : "Î ĪĪŒĪƒÎŋĪˆÎˇ", - "spatial.left" : "Î‘ĪÎšĪƒĪ„Îĩ΁ÎŦ", - "spatial.right" : "ΔÎĩΞΚÎŦ", - "spatial.back" : "Î Î¯ĪƒĪ‰ ÎŒĪˆÎˇ", - "spatial.down" : "ΚÎŦ΄Ή", - "spatial.listener" : "ΑÎē΁ÎŋÎąĪ„ÎŽĪ‚", - "spatial.audioSource" : "Î ÎˇÎŗÎŽ Î‰Ī‡ÎŋĪ…", - - // Settings - Unfinished - "settings.header.unfinished": "ΗÎŧÎšĪ„ÎĩÎģÎŽĪ‚", - - // Web Remote - "remote.web.title": "Cider Remote", - "remote.web.description": "ÎŖÎąĪĪŽĪƒĪ„Îĩ Ī„ÎŋÎŊ ÎēĪ‰Î´ÎšÎēΌ QR ÎŗÎšÎą ĪƒĪÎļÎĩĪ…ÎžÎˇ Ī„ÎŋĪ… Cider ÎŧÎĩ Ī„Îŋ ÎēΚÎŊÎˇĪ„ĪŒ ĪƒÎąĪ‚", - - //About - "about.thanks": "ΜÎĩÎŗÎŦÎģÎą ÎĩĪ…Ī‡ÎąĪÎšĪƒĪ„ĪŽ ĪƒĪ„ÎˇÎŊ ΟÎŧÎŦδι Cider Collective ÎēιΚ ΃Îĩ ΌÎģÎŋĪ…Ī‚ Ī„ÎŋĪ…Ī‚ ĪƒĪ…ÎŊÎĩÎšĪƒĪ†Î­ĪÎŋÎŊĪ„Î­Ī‚ ÎŧÎąĪ‚." -} \ No newline at end of file diff --git a/src/i18n/en_GB.jsonc b/src/i18n/en_GB.jsonc deleted file mode 100644 index bf6030b1..00000000 --- a/src/i18n/en_GB.jsonc +++ /dev/null @@ -1,16 +0,0 @@ -{ - // i18n Info - "i18n.languageName": "English (UK)", // name of language in native language - "i18n.languageNameEnglish": "English (UK)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "Core, inalone", // Authors, if you contribute to this file feel free to add your name seperated with a space - "date.format": "${d} ${m}, ${y}", - // translations - "term.equalizer": "Equaliser", - "settings.option.audio.enableAdvancedFunctionality.description": "Enabling AudioContext functionality will allow for extended audio features like Audio Normalisation , Equalisers and Visualisers, however on some systems this may cause stuttering in audio tracks.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio Normalisation", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalises peak volume for individual tracks to create a more uniform listening experience.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Audio Spatialisation", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spatialise audio and make audio more 3-dimensional (note: This is not Dolby Atmos)", - "spatial.notTurnedOn": "Audio Spatialisation is disabled. To use, please enable it first." -} diff --git a/src/i18n/en_HODOR.jsonc b/src/i18n/en_HODOR.jsonc deleted file mode 100644 index e925e968..00000000 --- a/src/i18n/en_HODOR.jsonc +++ /dev/null @@ -1,312 +0,0 @@ -{ // HODOR - - // i18n Info - "i18n.languageName": "HODOR", // name of language in native language - "i18n.languageNameEnglish": "HODOR", // name of language in English - "i18n.category": "fun", // main = real language, fun = fun community languages - "i18n.authors": "HODOR", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "HODER", - - "date.format": "${m} ${d}, ${y}", - - // Dialogs - "dialog.cancel": "NO HODOR", - "dialog.ok": "YES HODOR", - - // Notification - "notification.updatingLibrarySongs": "UPDATING HODOR HODORS...", - "notification.updatingLibraryAlbums": "UPDATING HODOR HODORBUMS...", - "notification.updatingLibraryArtists": "UPDATING HODOR HODORTISTS...", - // Terms - "term.appleInc": "HODOR Inc.", - "term.appleMusic": "HODOR MUSIC", - "term.applePodcasts": "HODOR PODCASTS", - "term.itunes": "iHODOR", - "term.github": "HODORHUB", - "term.discord": "HODORSCORD", - "term.learnMore": "LEARN HODOR", - "term.accountSettings": "HODOR SETTINGS", - "term.logout": "HODOR OUT", - "term.login": "HODOR IN", - "term.about": "WHAT'S HODOR", - "term.privateSession": "HODOR SESSION", - "term.queue": "HODORUEUE", - "term.search": "HODORCH", - "term.library": "HODORRARY", - "term.listenNow": "HODOR NOW", - "term.browse": "HODOROWSE", - "term.radio": "HODORADIO", - "term.recentlyAdded": "RECENTLY HODOR", - "term.songs": "HODORS", - "term.albums": "HODORBUMS", - "term.artists": "HODORTISTS", - "term.podcasts": "HODORCASTS", - "term.playlists": "HODORLISTS", - "term.playlist": "HODORLIST", - "term.newPlaylist": "NEW HODOR", - "term.newPlaylistFolder": "NEW HODOR FOLDER", - "term.createNewPlaylist": "CREATE NEW HODOR", - "term.createNewPlaylistFolder": "CREATE NEW HODOR FOLDER", - "term.deletePlaylist": "ARE YOU HODOR YOU HODOR TO HODOR THIS HODOR?", - "term.play": "HODOR", - "term.pause": "PAHODOR", - "term.previous": "PREHODOR", - "term.next": "NEXHODOR", - "term.shuffle": "HODORFFLE", - "term.repeat": "REPHODOR", - "term.volume": "HODORVOL", - "term.mute": "HODORMUT", - "term.unmute": "HODORUNMUT", - "term.share": "SHARE HODOR", - "term.settings": " SET HODOR", - "term.seeAll": "SEE HODOR", - "term.sortBy": "SORT HODOR", - "term.sortBy.album": "HODORBUM", - "term.sortBy.artist": "HODORTIST", - "term.sortBy.name": "HODOR", - "term.sortBy.genre": "HODOR TYPE", - "term.sortBy.releaseDate": "HODOR DATE", - "term.sortBy.duration": "HODOR DURATION", - "term.sortOrder": "HODAR-HODZR", - "term.sortOrder.ascending": "ASCENDING HODOR", - "term.sortOrder.descending": "DESCENDING HODOR", - "term.viewAs": "VIEW HODOR", - "term.viewAs.coverArt": "COVER HODOR", - "term.viewAs.list": "HODORIST", - "term.size": "HODOR SIZE", - "term.size.normal": "HODOR!!", - "term.size.compact": "hodor.", - "term.enable": "HODOR IT", - "term.disable": "NO HODOR", - "term.enabled": "HODORED", - "term.disabled": "NOT HODORED", - "term.connect": "CONNECT HODOR", - "term.connecting": "HODOR WAIT", - "term.disconnect": "NO HODOR", - "term.authed": "HODORED", - "term.confirm": "U HODOR?", - "term.more": "HODOR", - "term.less": "hodor", - "term.showMore": "MORE HODOR", - "term.showLess": "LESS HODOR", - "term.topSongs" : "TOP HODORS", - "term.latestReleases": "LATEST HODORS", - "term.time.added": "HODOR ADDED", - "term.time.released": "HODOR RELEASED", - "term.time.updated": "HODOR UPDATED", - "term.fullscreenView": "FULL HODOR", - "term.defaultView": "NO HODOR", - "term.audioSettings": "HODOR HEARS", - "term.clearAll": "CLEAR HODORS", - "term.recentStations": "RECENT HODORTATIONS", - "term.language": "HODOR SPEAKS", - "term.noLyrics": "HODORING... / HODOR NOT HODOR./ HODOR.", - "term.copyright": "HODORIGHT", - "term.rightsReserved": "ALL HODORS RESERVED.", - "term.sponsor": "HODOR THIS HODOR", - "term.ciderTeam": "HODOR TEAM", - "term.developer": "CODER HODOR", - "term.socialTeam": "SOCIAL HODOR", - "term.socials": "HODORS", - "term.contributors": "OTHER HODORS", - "term.equalizer": "HODORIZER", - "term.reset": "HODOR IT", - "term.tracks": "HODORS", - "term.time.hours": "HODOR", - "term.time.hour": "HODOR", - "term.time.minutes": "HODOR", - "term.time.minute": "HODOR", - "term.time.seconds": "HODOR", - "term.time.second": "HODOR", - "term.funLanguages": "HODOR SPEAKS", - "term.videos": "HODOR WATCHING", - "term.menu": "HODOR MENU", - - // Home - "home.title": "HODOR", - "home.recentlyPlayed": "RECENTLY HODOR", - "home.recentlyAdded": "NEW HODOR", - "home.artistsFeed": "HODOR FEED", - "home.artistsFeed.noArtist": "FOLLOW SOME HODOR FIRST AND THEIR NEW HODOR WILL BE HODOR", - "home.madeForYou": "HODOR FOR YOU", - "home.friendsListeningTo": "FRIENDS HODOR HODOR", - "home.followedArtists": "FOLLOWED HODOR", - // Errors - "error.appleMusicSubRequired": "HODOR MUSIC REQUIRES A HODOR.", - "error.connectionError": "CANNOT HODOR TO HODOR.", - "error.noResults": "NO HODOR.", - "error.noResults.description": "TRY NEW HODOR.", - - //Podcasts - "podcast.followOnCider": "FOLLOW ON HODOR", - "podcast.followedOnCider": "FOLLOWING ON HODOR", - "podcast.subscribeOnItunes": "SUBSCRIBE ON iHODOR", - "podcast.subscribedOnItunes": "SUBSCRIBED ON İHODOR", - "podcast.itunesStore": "HODOR STORE", - "podcast.episodes": "HODORS", - "podcast.playEpisode": "PLAY HODOR", - "podcast.website": "HODORCAST PAGE", - - // Actions - "action.addToLibrary": "ADD HODOR", - "action.addToLibrary.success": "YES HODOR", - "action.addToLibrary.error": "NO HODOR", - "action.removeFromLibrary": "DELETE HODOR", - "action.removeFromLibrary.success": "HODOR OK", - "action.addToQueue": "ADD HODORUEUE", - "action.addToQueue.success": "YES HODOR", - "action.addToQueue.error": "NO HODOR", - "action.removeFromQueue": "DELETE HODOR FROM HODORUEUE", - "action.removeFromQueue.success": "YES HODOR", - "action.removeFromQueue.error": "NO HODOR", - "action.createPlaylist": "CREATE HODOR", - "action.addToPlaylist": "ADD HODOR", - "action.removeFromPlaylist": "DELETE HODOR", - "action.addToFavorites": "LOVE HODOR", - "action.follow": "HODOR", - "action.follow.success": "YES HODOR", - "action.follow.error": "NO HODOR", - "action.unfollow": "UNHODOR", - "action.unfollow.success": "YES HODOR", - "action.unfollow.error": "NO HODOR", - "action.playNext": "NEXT HODOR", - "action.playLater": "LATER HODOR", - "action.startRadio": "HODORADIO", - "action.goToArtist": " GO TO HODOR", - "action.goToAlbum": "GO TO HODORBUM", - "action.moveToTop": "MOVE HODOR TO TOP", - "action.share": "HODOR IT", - "action.rename": "REHODOR", - "action.love": "LOVE HODOR", - "action.unlove": "UNLOVE HODOR", - "action.dislike": "NO LIKE HODOR", - "action.undoDislike": "NO NO LIKE HODOR", - "action.showWebRemoteQR": "REMOTE HODOR", - "action.playTracksNext": "HODOR ${app.selectedMediaItems.length} HODOR NEXT", - "action.playTracksLater": "HODOR ${app.selectedMediaItems.length} HODOR LATER", - "action.removeTracks": "HODOR ${self.selectedItems.length} HODOR FROM HODORUEUE", - "action.import": "HODOR IN", - "action.export": "HODOR OUT", - "action.showAlbum": "SHOW HODOR HODOR", - // Waiting on Core for moving plugin to app.ts - "action.tray.minimize": "HODOR TO TRAY", - "action.tray.quit": "HODOR", - "action.tray.show": "SEE", - - // Settings - General (Reserved) - "settings.header.general": "HODORAL", - "settings.header.general.description": "HODOR HODORAL HODOR FOR HODOR.", - "settings.option.general.language": "HODOR SPEAKS", - - // Language optgroups - "settings.option.general.language.main": "REAL HODORS", - "settings.option.general.language.fun": "HODOR HODORS", - "settings.option.general.language.unsorted": "NO HODORS", - - // Settings - Audio - "settings.header.audio": "HODOR HEARS", - "settings.header.audio.description": "ADJUST HODOR EARS FOR HODOR HODOR.", - "settings.option.audio.quality": "HODOR QUALITY", // Dropdown - "settings.header.audio.quality.high": "HODOR!!.", - "settings.header.audio.quality.low": "hodor.", - "settings.header.audio.quality.auto": "HODORMATIC", - "settings.option.audio.seamlessTransition": "SEAMLESS HODOR", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "ADVANCED HODOR", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "ENABLING HODOR FUNCTIONALITY WILL HODOR FOR EXTENDED HODOR FEATURES LIKE HODOR NORMALIZATION , HODORIZERS AND HODORS, BUT ON SOME HODOR SYSTEMS THIS HODOR CAUSE HODOR IN HODOR.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "HODOR NORMALIZATION", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "NORMALIZES HODOR VOLUME FOR INDIVIDUAL HODORS TO HODOR A MORE HODOR LISTENING HODOR.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "HODOR SPATIALIZATION", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "SPATIALIZE HODOR AND MAKE HODOR MORE 3-HODOR (HODOR: THIS IS NOT HODOR ATMOS)", - // Settings - Visual - "settings.header.visual": "HODOR SEES", - "settings.header.visual.description": "ADJUST HODOR EYES FOR HODOR.", - "settings.option.visual.windowBackgroundStyle": "BACK HODOR STYLE", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "NO HODOR", - "settings.header.visual.windowBackgroundStyle.artwork": "HODORWORK", - "settings.header.visual.windowBackgroundStyle.image": "HODOR", - "settings.option.visual.animatedArtwork": "MOVING HODORWORK", // Dropdown - "settings.header.visual.animatedArtwork.always": "YES HODOR", - "settings.header.visual.animatedArtwork.limited": "SOME HODOR", - "settings.header.visual.animatedArtwork.disable": "NO HODOR", - "settings.option.visual.animatedArtworkQuality": "MOVING HODOR QUALITY", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "hodor..", - "settings.header.visual.animatedArtworkQuality.medium": "HODOR.", - "settings.header.visual.animatedArtworkQuality.high": "HODOR!", - "settings.header.visual.animatedArtworkQuality.veryHigh": "HODOR HODOR!", - "settings.header.visual.animatedArtworkQuality.extreme": "HODOOOOOOOR!!", - "settings.option.visual.animatedWindowBackground": "ANIMATED HODOR BACK", // Toggle - "settings.option.visual.hardwareAcceleration": "HODOR ACCELERATION", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "NEED RE HODOR", - "settings.header.visual.hardwareAcceleration.default": "HODOR.", - "settings.header.visual.hardwareAcceleration.webGPU": "WEB HODOR!!", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "SHOW HODOR NAME?", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "HODOR READS", - "settings.header.lyrics.description": "ADJUST THE HODOR TEXT FOR HODOR.", - "settings.option.lyrics.enableMusixmatch": "MUSIXMATCH HODOR", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "HO-DOR SING MODE (MUSIXMATCH HODOR)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "TRANSLATE HODOR TEXT", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "HODOR YOUTUBE HODOR TEXT FOR HODOR VIDEOS", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "HODORTIVITY", - "settings.header.connectivity.description": "ADJUST THE HODORTIVITY FOR HODOR.", - "settings.option.connectivity.discordRPC": "DISCORD HODOR", // Dropdown - "settings.option.connectivity.playbackNotifications": "NOTIFICATION FOR HODOR", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "SEE HODOR AS 'CIDER'", - "settings.header.connectivity.discordRPC.appleMusic": "SEE HODOR AS 'HODOR MUSIC'", - "settings.option.connectivity.discordRPC.clearOnPause": "HODOR DISCORD ON PAUSE", // Toggle - "settings.option.connectivity.lastfmScrobble": "HODOR.FM SCROBBLING", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "HODOR.FM HODOR DELAY (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "YES HODOR.FM NOW HODORING", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "DELETE HODORING HODORTIST FROM HODOR TITLE (HODOR.FM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "FILTER MULTI HODOEDR HODOR (HODOR.FM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "EXPERIMENTAL HODOR", - "settings.header.experimental.description": "ADJUST THE EXPERIMENTAL HODOR FOR HODOR.", - "settings.option.experimental.compactUI": "smol hodor", // Toggle - "settings.option.experimental.closeButtonBehaviour": "CLOSE HODOR BUTTON", - "settings.option.experimental.closeButtonBehaviour.quit": "END HODOR", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "MINIMIZE HODOR TO HODORBAR", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "MINIMIZE HODOR TO HODORAY", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "HODOR SPATIALIZATION IS HODOR. TO HODOR, PLEASE HODOR IT HODOR.", - "spatial.spatialProperties" : "SPATIAL HODOR", - "spatial.width" : "HODOR WIDTH", - "spatial.height" : "HODOR HEIGHT", - "spatial.depth" : "HODOR DEPTH", - "spatial.gain" : "HODOR POWER", - "spatial.roomMaterials" : "ROOM HODORS", - "spatial.roomDimensions" : "ROOM HODOR SIZE", - "spatial.roomPositions" : "ROOM HODOR POSITION", - "spatial.setDimensions" : "HODOR SIZE", - "spatial.setPositions" : "SET HODOR POSITION", - "spatial.up" : "UP HODOR", - "spatial.front" : "FRONT HODOR", - "spatial.left" : "LEFT HODOR", - "spatial.right" : "RIGHT HODOR", - "spatial.back" : "BACK HODOR", - "spatial.down" : "DOWN HODOR", - "spatial.listener" : "HODOR EARS", - "spatial.audioSource" : "HODOR PLAYS", - - // Settings - Unfinished - "settings.header.unfinished": "NOT HODOR YET", - - // Web Remote - "remote.web.title": "HODOR REMOTE", - "remote.web.description": "HODOR THE HODOR TO HODOR YOUR HODOR UP WITH THIS HODOR INSTANCE", - - //About - "about.thanks": "HODOR THANKS TO THE HODOR TEAM AND ALL OF OUR HODORS." - -} \ No newline at end of file diff --git a/src/i18n/en_PISS.jsonc b/src/i18n/en_PISS.jsonc deleted file mode 100644 index ddd831a0..00000000 --- a/src/i18n/en_PISS.jsonc +++ /dev/null @@ -1,312 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "piss", // name of language in native language - "i18n.languageNameEnglish": "English (piss)", // name of language in English - "i18n.category": "fun", // main = real language, fun = fun community languages - "i18n.authors": "@SoNothingMC", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "piss", - - "date.format": "${y}-${m}-${d}", // ISO 8601 for the win! - - // Dialogs - "dialog.cancel": "no piss", - "dialog.ok": "yes piss", - - // Notification - "notification.updatingLibrarySongs": "pisssing all over your songs", - "notification.updatingLibraryAlbums": "pissing all over your albums", - "notification.updatingLibraryArtists": "pissing all over your idols", - // Terms - "term.appleInc": "piss Inc.", - "term.appleMusic": "piss music", - "term.applePodcasts": "piss podcasts", - "term.itunes": "iPiss", - "term.github": "PissHub", - "term.discord": "Pisscord", - "term.learnMore": "piss more", - "term.accountSettings": "piss music settings", - "term.logout": "piss out", - "term.login": "piss in", - "term.about": "piss info", - "term.privateSession": "piss in private", - "term.queue": "to be pissed", - "term.search": "find piss", - "term.library": "obtained piss", - "term.listenNow": "piss now", - "term.browse": "find piss", - "term.radio": "piss everywhere", - "term.recentlyAdded": "recently obtained piss", - "term.songs": "piss list", // not to be confused with pisslist (playlist) - "term.albums": "piss collection", - "term.artists": "pissers", - "term.podcasts": "pisscasts", - "term.playlists": "pisslists", - "term.playlist": "pisslist", - "term.newPlaylist": "new pisslist", - "term.newPlaylistFolder": "new pisslist folder", - "term.createNewPlaylist": "create new pisslist", - "term.createNewPlaylistFolder": "create new pisslist folder", - "term.deletePlaylist": "obliterate pisslist?", - "term.play": "piss", - "term.pause": "hold your piss", - "term.previous": "piss", - "term.next": "piss", - "term.shuffle": "piss randomly", - "term.repeat": "piss at the same place", - "term.volume": "piss loudness", - "term.mute": "piss without sound", - "term.unmute": "piss with sound", - "term.share": "piss on your friends", - "term.settings": "pissettings", - "term.seeAll": "all of the piss", - "term.sortBy": "piss by", - "term.sortBy.album": "piss collection", - "term.sortBy.artist": "pissers", - "term.sortBy.name": "piss name", - "term.sortBy.genre": "way to piss", - "term.sortBy.releaseDate": "pissed date", - "term.sortBy.duration": "piss duration", - "term.sortOrder": "piss-PISS", - "term.sortOrder.ascending": "pissing upwards", - "term.sortOrder.descending": "pissing downwards", - "term.viewAs": "piss as", - "term.viewAs.coverArt": "piss art", - "term.viewAs.list": "piss list", // not to be confused with pisslist (playlist) - "term.size": "piss size", - "term.size.normal": "normal piss", - "term.size.compact": "compact piss", - "term.enable": "piss!", - "term.disable": "pissâ€Ļ", - "term.enabled": "pissed!", - "term.disabled": "pissedâ€Ļ", - "term.connect": "piss", - "term.connecting": "pissing", - "term.disconnect": "unpiss", - "term.authed": "pissed", - "term.confirm": "pissâ€Ļ?", - "term.more": "piss more", - "term.less": "piss less", - "term.showMore": "more piss", - "term.showLess": "less piss", - "term.topSongs" : "top piss", - "term.latestReleases": "latest piss collection", - "term.time.added": "pissed", - "term.time.released": "pissed", - "term.time.updated": "pissed", - "term.time.hours": "hours", - "term.time.hour": "hour", - "term.time.minutes": "minutes", - "term.time.minute": "minute", - "term.time.seconds": "seconds", - "term.time.second": "second", - "term.fullscreenView": "fullpiss view", - "term.defaultView": "normal piss view", - "term.audioSettings": "cool piss tricks", - "term.clearAll": "flush the toilet", - "term.recentStations": "recent pisses", - "term.language": "piss around the world", - "term.funLanguages": "piss languages", - "term.noLyrics": "pissâ€Ļ", - "term.copyright": "copypiss", - "term.rightsReserved": "all piss reserved.", - "term.sponsor": "piss on Cider", - "term.ciderTeam": "meet the pisseneers", - "term.developer": "pisseneer", - "term.socialTeam": "social pisser", - "term.socials": "our piss", - "term.contributors": "more pisseneers", - "term.equalizer": "advanced piss configuration", - "term.reset": "repiss", - "term.tracks": "pisses", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "piss videos đŸ˜ŗ", - "term.menu": "piss menu", - "term.check": "piss!", - - // Home - "home.title": "piss central", - "home.recentlyPlayed": "recently pissed on", - "home.recentlyAdded": "recently obtained piss", - "home.artistsFeed": "your piss feed", - "home.artistsFeed.noArtist": "follow some pissers, their new piss will be here.", - "home.madeForYou": "pissed for you", - "home.friendsListeningTo": "friends pissing to", - "home.followedArtists": "followed pissers", - // Errors - "error.appleMusicSubRequired": "piss music requires, like y'know, an actual piss music subscription to actually use.", - "error.connectionError": "oh, piss.", - "error.noResults": "no piss found", - "error.noResults.description": "try pissing somewhere else (or press Enter/Return to search)", - - //Podcasts - "podcast.followOnCider": "piss on Cider", - "podcast.followedOnCider": "pissed on Cider", - "podcast.subscribeOnItunes": "piss on iPiss", - "podcast.subscribedOnItunes": "pissed On iPiss", - "podcast.itunesStore": "iPiss store", - "podcast.episodes": "pisses", - "podcast.playEpisode": "play piss", - "podcast.website": "pisscast site", - - // Actions - "action.addToLibrary": "obtain piss", - "action.addToLibrary.success": "piss obtained", - "action.addToLibrary.error": "error obtaining piss", - "action.removeFromLibrary": "unobtain piss", - "action.removeFromLibrary.success": "piss unobtained", - "action.addToQueue": "add to toilet", - "action.addToQueue.success": "added to toilet", - "action.addToQueue.error": "error adding to toilet", - "action.removeFromQueue": "flsuh from the toilet", - "action.removeFromQueue.success": "flushed from the toilet", - "action.removeFromQueue.error": "error flushing from toilet", - "action.createPlaylist": "create new pisslist", - "action.addToPlaylist": "add to pisslist", - "action.removeFromPlaylist": "flush from pisslist", - "action.addToFavorites": "add to favourite piss", - "action.follow": "follow pisser", - "action.follow.success": "pisser followed", - "action.follow.error": "error following pisser", - "action.unfollow": "unfollow pisser", - "action.unfollow.success": "pisser unfollowed", - "action.unfollow.error": "error unfollowing pisser", - "action.playNext": "piss next", - "action.playLater": "piss later", - "action.startRadio": "start pissing everywhere", - "action.goToArtist": "go to pisser", - "action.goToAlbum": "go to piss collection", - "action.moveToTop": "piss to top", - "action.share": "piss on your friends", - "action.rename": "rename piss", - "action.love": "love piss", - "action.unlove": "unlove piss", - "action.dislike": "dislike piss", - "action.undoDislike": "undislike piss", - "action.showWebRemoteQR": "piss remote", - "action.playTracksNext": "piss ${app.selectedMediaItems.length} pisses next", - "action.playTracksLater": "piss ${app.selectedMediaItems.length} pisses later", - "action.removeTracks": "flush ${self.selectedItems.length} pisses from toilet", - "action.import": "impiss", - "action.export": "expiss", - "action.showAlbum": "show complete piss collection", - // Waiting on Core for moving plugin to app.ts - "action.tray.minimize": "piss off to tray", - "action.tray.quit": "piss off", - "action.tray.show": "piss back", - - // Settings - General - "settings.header.general": "general", - "settings.header.general.description": "the dumping place for settings when there are no other places to put them into", - "settings.option.general.language": "piss around the world", - - // Language optgroups - "settings.option.general.language.main": "actaul human languages", - "settings.option.general.language.fun": "piss languages", - "settings.option.general.language.unsorted": "???? who put this here", - - // Settings - Audio - "settings.header.audio": "piss sounds", - "settings.header.audio.description": "change how your piss sounds", - "settings.option.audio.quality": "piss quality", // Dropdown - "settings.header.audio.quality.high": "nice piss", - "settings.header.audio.quality.low": "piss with blood", - "settings.header.audio.quality.auto": "automatic piss", - "settings.option.audio.seamlessTransition": "seamless piss-to-piss transition", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "cool piss tricks", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "enabling the AudioContext thingy allows you to do cool stuffs, however on some systems your song may stutter", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "piss normaliztion", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "protect your eardrums from overly loud/slient pisses", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "3D piss", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "this aint the dolby atmos you are looking for but its still pretty crazy so check it out", - // Settings - Visual - "settings.header.visual": "piss appearance", - "settings.header.visual.description": "change how your piss looks", - "settings.option.visual.windowBackgroundStyle": "background piss", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "no piss", - "settings.header.visual.windowBackgroundStyle.artwork": "piss art", - "settings.header.visual.windowBackgroundStyle.image": "piss image", - "settings.option.visual.animatedArtwork": "moving piss art", // Dropdown - "settings.header.visual.animatedArtwork.always": "yes piss", - "settings.header.visual.animatedArtwork.limited": "only piss pages and special pisses", - "settings.header.visual.animatedArtwork.disable": "no piss", - "settings.option.visual.animatedArtworkQuality": "moving piss art quality", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "piss with blood", - "settings.header.visual.animatedArtworkQuality.medium": "okay piss", - "settings.header.visual.animatedArtworkQuality.high": "nice piss", - "settings.header.visual.animatedArtworkQuality.veryHigh": "good piss", - "settings.header.visual.animatedArtworkQuality.extreme": "literally 4k piss", - "settings.option.visual.animatedWindowBackground": "moving background piss", // Toggle - "settings.option.visual.hardwareAcceleration": "make Cider piss faster", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "you need to relaunch Cider", - "settings.header.visual.hardwareAcceleration.default": "default piss", - "settings.header.visual.hardwareAcceleration.webGPU": "WebPISS", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "show yourself to the pissiverse", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "piss lyrics", - "settings.header.lyrics.description": "change how your piss speaks to you", - "settings.option.lyrics.enableMusixmatch": "Musixpiss piss lyrics", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "pissraoke mode (Musixpiss only)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "language for Musixpiss translations", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "PissTube subtitles for piss videos", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "pisser-to-pisser connections", - "settings.header.connectivity.description": "change how Cider piss on other people, including you", - "settings.option.connectivity.discordRPC": "Pisscord rich pissence", // Dropdown - "settings.option.connectivity.playbackNotifications": "toilet notifications", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "piss as 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "piss as 'piss music'", - "settings.option.connectivity.discordRPC.clearOnPause": "flush Pisscord rich pissence when holding your piss", // Toggle - "settings.option.connectivity.lastfmScrobble": "Piss.fm scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Piss.fm scrobble delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "push now playing data to Piss.fm", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "remove featured pissers from piss names (Piss.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "filter same piss (Piss.fm)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "piss lab", - "settings.header.experimental.description": "mitochondria is the powerhouse of the cell", - "settings.option.experimental.compactUI": "compact piss", // Toggle - "settings.option.experimental.closeButtonBehaviour": "piss off button behaviour", - "settings.option.experimental.closeButtonBehaviour.quit": "ask cider to piss off", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "piss off to the taskbar", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "piss off to the tray", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "3D piss is not on. turn it on lol", - "spatial.spatialProperties": "3D properties", - "spatial.width": "longness", - "spatial.height": "thiccness", - "spatial.depth": "longness, the other way", - "spatial.gain": "eardrum explosion level", - "spatial.roomMaterials": "toilet materials", - "spatial.roomDimensions": "toilet size", - "spatial.roomPositions": "toilet positions", - "spatial.setDimensions": "set size", - "spatial.setPositions": "set positions", - "spatial.up": "the piss on the ceiling", - "spatial.front": "the piss in front", - "spatial.left": "the piss on the left", - "spatial.right": "the piss on the right", - "spatial.back": "the piss at the back", - "spatial.down": "the piss on the floor", - "spatial.listener": "you", - "spatial.audioSource": "piss source", - - // Settings - Unfinished - "settings.header.unfinished": "DLC piss", - - // Web Remote - "remote.web.title": "piss remote", - "remote.web.description": "piss on your phone camera to connect to Cider.", - - // About - "about.thanks": "thanks to the Cider Collective team and all the pisseneers putting this together" -} diff --git a/src/i18n/en_SGA.jsonc b/src/i18n/en_SGA.jsonc deleted file mode 100644 index ab6a1138..00000000 --- a/src/i18n/en_SGA.jsonc +++ /dev/null @@ -1,301 +0,0 @@ -{ - - // i18n Info - "i18n.languageName": "┤ᖋ|:á–‹á”Žá’Ŗâ•Žá”Ž ᖋ|:i!â‘á–‹á•Šá’ˇá’Ŗ", // name of language in native language - "i18n.languageNameEnglish": "Galactic Alphabet", // name of language in English - "i18n.category": "fun", // main = real language, fun = fun community languages - "i18n.authors": "@kyw504100", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "ᔮ╎↸ᒷ∷", - - "date.format": "${m} ${d}, ${y}", - - // Dialogs - "dialog.cancel": "ᔮᖋãƒĒᔮᒷ|:", - "dialog.ok": "ᒍ·Į€Âˇ", - - // Notification - "notification.updatingLibrarySongs": "⚍i!â†¸á–‹á’Ŗâ•ŽãƒĒ┤ |:╎ᕊ∷ᖋ∷āĨĨ ĪŸá’ãƒĒâ”¤ĪŸ...", - "notification.updatingLibraryAlbums": "⚍i!â†¸á–‹á’Ŗâ•ŽãƒĒ┤ |:╎ᕊ∷ᖋ∷āĨĨ ᖋ|:á•Šâšá’˛ĪŸ...", - "notification.updatingLibraryArtists": "⚍i!â†¸á–‹á’Ŗâ•ŽãƒĒ┤ |:╎ᕊ∷ᖋ∷āĨĨ á–‹âˆˇá’Ŗâ•ŽĪŸá’ŖĪŸ...", - // Terms - "term.appleInc": "ᖋi!i!|:ᒷ ╎ãƒĒᔮ.", - "term.appleMusic": "ᖋi!i!|:ᒷ á’˛âšĪŸâ•Žá”Ž", - "term.applePodcasts": "ᖋi!i!|:ᒷ i!á’â†¸á”Žá–‹ĪŸá’ŖĪŸ", - "term.itunes": "â•Žá’ŖâšãƒĒá’ˇĪŸ", - "term.github": "â”¤â•Žá’Ŗâ‘âšá•Š", - "term.discord": "â†¸â•ŽĪŸá”Žá’âˆˇâ†¸", - "term.learnMore": "|:ᒷᖋ∷ãƒĒ ᒲᒍ∷ᒷ", - "term.accountSettings": "ᖋᔮᔮᒍ⚍ãƒĒá’Ŗ ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ", - "term.logout": "|:á’â”¤á’âšá’Ŗ", - "term.login": "|:ᒍ┤╎ãƒĒ", - "term.about": "á–‹á•Šá’âšá’Ŗ", - "term.privateSession": "I!âˆˇâ•ŽâŠá–‹á’Ŗá’ˇ ĪŸá’ˇĪŸĪŸâ•Žá’ãƒĒ", - "term.queue": "ᑑ⚍ᒷ⚍ᒷ", - "term.search": "ĪŸá’ˇá–‹âˆˇá”Žâ‘", - "term.library": "|:╎ᕊ∷ᖋ∷āĨĨ", - "term.listenNow": "|:â•ŽĪŸá’Ŗá’ˇãƒĒ", - "term.browse": "ãƒĒᒍ∴", - "term.radio": "∷ᖋ↸╎ᒍ", - "term.recentlyAdded": "∷ᒷᔮᒷãƒĒá’Ŗ|:āĨĨ ᖋ↸↸ᒷ↸", - "term.songs": "ĪŸá’ãƒĒâ”¤ĪŸ", - "term.albums": "ᖋ|:á•Šâšá’˛ĪŸ", - "term.artists": "á–‹âˆˇá’Ŗâ•ŽĪŸá’ŖĪŸ", - "term.podcasts": "I!á’â†¸á”Žá–‹ĪŸá’ŖĪŸ", - "term.playlists": "i!|:ᖋāĨĨ|:â•ŽĪŸá’ŖĪŸ", - "term.playlist": "i!|:ᖋāĨĨ|:â•ŽĪŸá’Ŗ", - "term.play": "i!|:ᖋāĨĨ", - "term.pause": "I!á–‹âšĪŸá’ˇ", - "term.previous": "I!âˆˇá’ˇâŠâ•Žá’âšĪŸ", - "term.next": "ãƒĒᒷ/á’Ŗ", - "term.shuffle": "ĪŸâ‘âšâŽ“âŽ“|:ᒷ", - "term.repeat": "∷ᒷi!á’ˇá–‹á’Ŗ", - "term.volume": "⍊ᒍ|:⚍ᒲᒷ", - "term.mute": "á’˛âšá’Ŗá’ˇ", - "term.unmute": "⚍ãƒĒá’˛âšá’Ŗá’ˇ", - "term.share": "ĪŸâ‘á–‹âˆˇá’ˇ", - "term.settings": "ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ", - "term.seeAll": "ĪŸá’ˇá’ˇ ᖋ|:|:", - "term.sortBy": "ĪŸá’âˆˇá’Ŗ ᕊāĨĨ", - "term.sortBy.album": "ᖋ|:ᕊ⚍ᒲ", - "term.sortBy.artist": "á–‹âˆˇá’Ŗâ•ŽĪŸá’Ŗ", - "term.sortBy.name": "ãƒĒᖋᒲᒷ", - "term.sortBy.genre": "┤ᒷãƒĒ∷ᒷ", - "term.sortBy.releaseDate": "∷ᒷ|:á’ˇá–‹ĪŸá’ˇ â†¸á–‹á’Ŗá’ˇ", - "term.sortBy.duration": "â†¸âšâˆˇá–‹á’Ŗâ•Žá’ãƒĒ", - "term.sortOrder": "ᖋ-∊", - "term.sortOrder.ascending": "á–‹ĪŸá”Žá’ˇãƒĒ↸╎ãƒĒ┤", - "term.sortOrder.descending": "â†¸á’ˇĪŸá”Žá’ˇãƒĒ↸╎ãƒĒ┤", - "term.viewAs": "⍊╎ᒷ∴ á–‹ĪŸ", - "term.viewAs.coverArt": "ᔮᒍ⍊ᒷ∷ á–‹âˆˇá’Ŗ", - "term.viewAs.list": "|:â•ŽĪŸá’Ŗ", - "term.size": "ĪŸâ•ŽâˆŠá’ˇ", - "term.size.normal": "ãƒĒᒍ∷ᒲᖋ|:", - "term.size.compact": "ᔮᒍᒲi!á–‹á”Žá’Ŗ", - "term.enable": "ᒷãƒĒᖋᕊ|:ᒷ", - "term.disable": "â†¸â•ŽĪŸá–‹á•Š|:ᒷ", - "term.enabled": "ᒷãƒĒᖋᕊ|:ᒷ↸", - "term.disabled": "â†¸â•ŽĪŸá–‹á•Š|:ᒷ↸", - "term.connect": "ᔮᒍãƒĒãƒĒá’ˇá”Žá’Ŗ", - "term.connecting": "ᔮᒍãƒĒãƒĒá’ˇá”Žá’Ŗâ•ŽãƒĒ┤", - "term.disconnect": "â†¸â•ŽĪŸá”Žá’ãƒĒãƒĒá’ˇá”Žá’Ŗ", - "term.authed": "á–‹âšá’Ŗâ‘á’ˇâ†¸", - "term.confirm": "ᔮᒍãƒĒ⎓╎∷ᒲ ?", - "term.more": "ᒲᒍ∷ᒷ", - "term.less": "|:á’ˇĪŸĪŸ", - "term.showMore": "ĪŸâ‘á’âˆ´ ᒲᒍ∷ᒷ", - "term.showLess": "ĪŸâ‘á’âˆ´ |:á’ˇĪŸĪŸ", - "term.topSongs" : "á’Ŗá’i! ĪŸá’ãƒĒâ”¤ĪŸ", - "term.latestReleases": "|:á–‹á’Ŗá’ˇĪŸá’Ŗ ∷ᒷ|:á’ˇá–‹ĪŸá’ˇĪŸ", - "term.time.added": "ᖋ↸↸ᒷ↸", - "term.time.released": "∷ᒷ|:á’ˇá–‹ĪŸá’ˇâ†¸", - "term.time.updated": "⚍i!â†¸á–‹á’Ŗá’ˇâ†¸", - "term.time.hours": "â‘á’âšâˆˇĪŸ", - "term.time.hour": "⍑ᒍ⚍∷", - "term.time.minutes": "ᒲ╎ãƒĒâšá’Ŗá’ˇĪŸ", - "term.time.minute": "ᒲ╎ãƒĒâšá’Ŗá’ˇ", - "term.time.seconds": "ĪŸá’ˇá”Žá’ãƒĒâ†¸ĪŸ", - "term.time.second": "ĪŸá’ˇá”Žá’ãƒĒ↸", - "term.fullscreenView": "⎓⚍|:|:ĪŸá”Žâˆˇá’ˇá’ˇãƒĒ ⍊╎ᒷ∴", - "term.defaultView": "↸ᒷ⎓ᖋ⚍|:á’Ŗ ⍊╎ᒷ∴", - "term.audioSettings": "ᖋ⚍↸╎ᒍ ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ", - "term.clearAll": "ᔮ|:ᒷᖋ∷ ᖋ|:|:", - "term.recentStations": "∷ᒷᔮᒷãƒĒá’Ŗ ĪŸá’Ŗá–‹á’Ŗâ•Žá’ãƒĒΟ", - "term.language": "|:ᖋãƒĒ┤⚍ᖋ┤ᒷ", - "term.funLanguages": "⎓⚍ãƒĒ", - "term.noLyrics": "|:ᒍᖋ↸╎ãƒĒ┤... / |:āĨĨâˆˇâ•Žá”ŽĪŸ ãƒĒá’á’Ŗ ⎓ᒍ⚍ãƒĒ↸./ ╎ãƒĒĪŸá’Ŗâˆˇâšá’˛á’ˇãƒĒá’Ŗá–‹|:.", - "term.copyright": "ᔮᒍi!āĨĨâˆˇâ•Žâ”¤â‘á’Ŗ", - "term.rightsReserved": "ᖋ|:|: âˆˇâ•Žâ”¤â‘á’ŖĪŸ âˆˇá’ˇĪŸá’ˇâˆˇâŠá’ˇâ†¸.", - "term.sponsor": "Οi!ᒍãƒĒĪŸá’âˆˇ á’Ŗâ‘â•ŽĪŸ i!âˆˇá’â‹Žá’ˇá”Žá’Ŗ", - "term.ciderTeam": "ᔮ╎↸ᒷ∷ á’Ŗá’ˇá–‹á’˛", - "term.developer": "↸ᒷ⍊ᒷ|:ᒍi!ᒷ∷", - "term.socialTeam": "ĪŸá’á”Žâ•Žá–‹|: á’Ŗá’ˇá–‹á’˛", - "term.socials": "ĪŸá’á”Žâ•Žá–‹|:Ο", - "term.contributors": "ᔮᒍãƒĒá’Ŗâˆˇâ•Žá•Šâšá’Ŗá’âˆˇĪŸ", - "term.equalizer": "ᒷᑑ⚍ᖋ|:╎∩ᒷ∷", - "term.reset": "âˆˇá’ˇĪŸá’ˇá’Ŗ", - "term.tracks": "á’Ŗâˆˇá–‹á”ŽÂˇĮ€ÂˇĪŸ", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "⍊╎↸ᒷᒍ", - "term.menu": "ᒲᒷ⚍ãƒĒ", - "term.showAlbum": "ĪŸâ‘á’âˆ´ ᔮᒍᒲi!|:á’ˇá’Ŗá’ˇ ᖋ|:ᕊ⚍ᒲ", - - // Home - "home.title": "⍑ᒍᒲᒷ", - "home.recentlyPlayed": "∷ᒷᔮᒷãƒĒá’Ŗ|:āĨĨ i!|:ᖋāĨĨᒷ↸", - "home.recentlyAdded": "∷ᒷᔮᒷãƒĒá’Ŗ|:āĨĨ ᖋ↸↸ᒷ↸", - "home.artistsFeed": "āĨĨᒍ⚍∷ á–‹âˆˇá’Ŗâ•ŽĪŸá’ŖĪŸ ⎓ᒷᒷ↸", - "home.artistsFeed.noArtist": "⎓ᒍ|:|:ᒍ∴ ĪŸá’á’˛á’ˇ á–‹âˆˇá’Ŗâ•ŽĪŸá’ŖĪŸ âŽ“â•ŽâˆˇĪŸá’Ŗ ᖋãƒĒ↸ á’Ŗâ‘á’ˇâ•Žâˆˇ |:á–‹á’Ŗá’ˇĪŸá’Ŗ ∷ᒷ|:á’ˇá–‹ĪŸá’ˇĪŸ ∴╎|:|: ᕊᒷ ⍑ᒷ∷ᒷ", - "home.madeForYou": "ᒲᖋ↸ᒷ ⎓ᒍ∷ āĨĨᒍ⚍", - "home.friendsListeningTo": "⎓∷╎ᒷãƒĒâ†¸ĪŸ |:â•ŽĪŸá’Ŗá’ˇãƒĒ╎ãƒĒ┤ á’Ŗá’", - "home.followedArtists": "⎓ᒍ|:|:ᒍ∴ᒷ↸ á–‹âˆˇá’Ŗâ•ŽĪŸá’ŖĪŸ", - // Errors - "error.appleMusicSubRequired": "ᖋi!i!|:ᒷ á’˛âšĪŸâ•Žá”Ž âˆˇá’ˇá‘‘âšâ•Žâˆˇá’ˇĪŸ ᖋ ĪŸâšá•ŠĪŸá”Žâˆˇâ•Ži!á’Ŗâ•Žá’ãƒĒ.", - "error.connectionError": "á’Ŗâ‘á’ˇâˆˇá’ˇ âˆ´á–‹ĪŸ ᖋ i!∷ᒍᕊ|:ᒷᒲ ᔮᒍãƒĒãƒĒá’ˇá”Žá’Ŗâ•ŽãƒĒ┤ á’Ŗá’ ᖋi!i!|:ᒷ á’˛âšĪŸâ•Žá”Ž.", - "error.noResults": "ãƒĒᒍ âˆˇá’ˇĪŸâš|:á’ŖĪŸ.", - "error.noResults.description": "á’ŖâˆˇāĨĨ ᖋ ãƒĒᒷ∴ ĪŸá’ˇá–‹âˆˇá”Žâ‘.", - - //Podcasts - "podcast.followOnCider": "⎓ᒍ|:|:ᒍ∴ ᒍãƒĒ ᔮ╎↸ᒷ∷", - "podcast.followedOnCider": "⎓ᒍ|:|:ᒍ∴╎ãƒĒ┤ ᒍãƒĒ ᔮ╎↸ᒷ∷", - "podcast.subscribeOnItunes": "ĪŸâšá•ŠĪŸá”Žâˆˇâ•Žá•Šá’ˇ ᒍãƒĒ â•Žá’ŖâšãƒĒá’ˇĪŸ", - "podcast.subscribedOnItunes": "ĪŸâšá•ŠĪŸá”Žâˆˇâ•Žá•Šá’ˇâ†¸ ᒍãƒĒ â•Žá’ŖâšãƒĒá’ˇĪŸ", - "podcast.itunesStore": "â•Žá’ŖâšãƒĒá’ˇĪŸ ĪŸá’Ŗá’âˆˇá’ˇ", - "podcast.episodes": "ᒷi!â•ŽĪŸá’â†¸á’ˇĪŸ", - "podcast.playEpisode": "i!|:ᖋāĨĨ ᒷi!â•ŽĪŸá’â†¸á’ˇ", - "podcast.website": "I!á’â†¸á”Žá–‹ĪŸá’Ŗ âˆ´á’ˇá•ŠĪŸâ•Žá’Ŗá’ˇ", - - // Actions - "action.addToLibrary": "ᖋ↸↸ á’Ŗá’ |:╎ᕊ∷ᖋ∷āĨĨ", - "action.addToLibrary.success": "ᖋ↸↸ᒷ↸ á’Ŗá’ |:╎ᕊ∷ᖋ∷āĨĨ", - "action.addToLibrary.error": "ᒷ∷∷ᒍ∷ ᖋ↸↸╎ãƒĒ┤ á’Ŗá’ |:╎ᕊ∷ᖋ∷āĨĨ", - "action.removeFromLibrary": "∷ᒷᒲᒍ⍊ᒷ ⎓∷ᒍᒲ |:╎ᕊ∷ᖋ∷āĨĨ", - "action.removeFromLibrary.success": "∷ᒷᒲᒍ⍊ᒷ↸ ⎓∷ᒍᒲ |:╎ᕊ∷ᖋ∷āĨĨ", - "action.addToQueue": "ᖋ↸↸ á’Ŗá’ ᑑ⚍ᒷ⚍ᒷ", - "action.addToQueue.success": "ᖋ↸↸ᒷ↸ á’Ŗá’ ᑑ⚍ᒷ⚍ᒷ", - "action.addToQueue.error": "ᒷ∷∷ᒍ∷ ᖋ↸↸╎ãƒĒ┤ á’Ŗá’ ᑑ⚍ᒷ⚍ᒷ", - "action.removeFromQueue": "∷ᒷᒲᒍ⍊ᒷ ⎓∷ᒍᒲ ᑑ⚍ᒷ⚍ᒷ", - "action.removeFromQueue.success": "∷ᒷᒲᒍ⍊ᒷ↸ ⎓∷ᒍᒲ ᑑ⚍ᒷ⚍ᒷ", - "action.removeFromQueue.error": "ᒷ∷∷ᒍ∷ ∷ᒷᒲᒍ⍊╎ãƒĒ┤ ⎓∷ᒍᒲ ᑑ⚍ᒷ⚍ᒷ", - "action.createPlaylist": "á”Žâˆˇá’ˇá–‹á’Ŗá’ˇ i!|:ᖋāĨĨ|:â•ŽĪŸá’Ŗ", - "action.addToPlaylist": "ᖋ↸↸ á’Ŗá’ i!|:ᖋāĨĨ|:â•ŽĪŸá’Ŗ", - "action.removeFromPlaylist": "∷ᒷᒲᒍ⍊ᒷ ⎓∷ᒍᒲ i!|:ᖋāĨĨ|:â•ŽĪŸá’Ŗ", - "action.addToFavorites": "ᖋ↸↸ á’Ŗá’ âŽ“á–‹âŠá’âˆˇâ•Žá’Ŗá’ˇĪŸ", - "action.follow": "⎓ᒍ|:|:ᒍ∴", - "action.follow.success": "⎓ᒍ|:|:ᒍ∴ᒷ↸", - "action.follow.error": "ᒷ∷∷ᒍ∷ ⎓ᒍ|:|:ᒍ∴╎ãƒĒ┤", - "action.unfollow": "⚍ãƒĒ⎓ᒍ|:|:ᒍ∴", - "action.unfollow.success": "⚍ãƒĒ⎓ᒍ|:|:ᒍ∴ᒷ↸", - "action.unfollow.error": "ᒷ∷∷ᒍ∷ ⚍ãƒĒ⎓ᒍ|:|:ᒍ∴╎ãƒĒ┤", - "action.playNext": "i!|:ᖋāĨĨ ãƒĒᒷ/á’Ŗ", - "action.playLater": "i!|:ᖋāĨĨ |:á–‹á’Ŗá’ˇâˆˇ", - "action.startRadio": "ĪŸá’Ŗá–‹âˆˇá’Ŗ ∷ᖋ↸╎ᒍ", - "action.goToArtist": "┤ᒍ á’Ŗá’ á–‹âˆˇá’Ŗâ•ŽĪŸá’Ŗ", - "action.goToAlbum": "┤ᒍ á’Ŗá’ ᖋ|:ᕊ⚍ᒲ", - "action.moveToTop": "ᒲᒍ⍊ᒷ á’Ŗá’ á’Ŗá’i!", - "action.share": "ĪŸâ‘á–‹âˆˇá’ˇ", - "action.rename": "∷ᒷãƒĒᖋᒲᒷ", - "action.love": "|:ᒍ⍊ᒷ", - "action.unlove": "⚍ãƒĒ|:ᒍ⍊ᒷ", - "action.dislike": "â†¸â•ŽĪŸ|:╎·Į€Âˇá’ˇ", - "action.undoDislike": "⚍ãƒĒ↸ᒍ â†¸â•ŽĪŸ|:╎·Į€Âˇá’ˇ", - "action.showWebRemoteQR": "∴ᒷᕊ âˆˇá’ˇá’˛á’á’Ŗá’ˇ", - "action.playTracksNext": "i!|:ᖋāĨĨ ${app.selectedMediaItems.length} á’Ŗâˆˇá–‹á”ŽÂˇĮ€ÂˇĪŸ ãƒĒᒷ/á’Ŗ", - "action.playTracksLater": "i!|:ᖋāĨĨ ${app.selectedMediaItems.length} á’Ŗâˆˇá–‹á”ŽÂˇĮ€ÂˇĪŸ |:á–‹á’Ŗá’ˇâˆˇ", - "action.removeTracks": "∷ᒷᒲᒍ⍊ᒷ ${self.selectedItems.length} á’Ŗâˆˇá–‹á”ŽÂˇĮ€ÂˇĪŸ ⎓∷ᒍᒲ ᑑ⚍ᒷ⚍ᒷ", - "action.import": "╎ᒲi!á’âˆˇá’Ŗ", - "action.export": "ᒷ/i!á’âˆˇá’Ŗ", - - // Settings - General - "settings.header.general": "┤ᒷãƒĒᒷ∷ᖋ|:", - "settings.header.general.description": "á–‹â†¸â‹ŽâšĪŸá’Ŗ á’Ŗâ‘á’ˇ ┤ᒷãƒĒᒷ∷ᖋ|: ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", - "settings.option.general.language": "|:ᖋãƒĒ┤⚍ᖋ┤ᒷ", - - // Language optgroups - "settings.option.general.language.main": "|:ᖋãƒĒâ”¤âšá–‹â”¤á’ˇĪŸ", - "settings.option.general.language.fun": "⎓⚍ãƒĒ |:ᖋãƒĒâ”¤âšá–‹â”¤á’ˇĪŸ", - "settings.option.general.language.unsorted": "⚍ãƒĒĪŸá’âˆˇá’Ŗá’ˇâ†¸", - - // Settings - Audio - "settings.header.audio": "ᖋ⚍↸╎ᒍ", - "settings.header.audio.description": "á–‹â†¸â‹ŽâšĪŸá’Ŗ á’Ŗâ‘á’ˇ ᖋ⚍↸╎ᒍ ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", - "settings.option.audio.quality": "ᖋ⚍↸╎ᒍ ᑑ⚍ᖋ|:â•Žá’ŖāĨĨ", // Dropdown - "settings.header.audio.quality.high": "⍑╎┤⍑", - "settings.header.audio.quality.low": "|:ᒍ∴", - "settings.header.audio.quality.auto": "á–‹âšá’Ŗá’", - "settings.option.audio.seamlessTransition": "ĪŸá’ˇá–‹á’˛|:á’ˇĪŸĪŸ ᖋ⚍↸╎ᒍ á’Ŗâˆˇá–‹ãƒĒĪŸâ•Žá’Ŗâ•Žá’ãƒĒ", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "ᒷãƒĒᖋᕊ|:ᒷ ᖋ↸⍊ᖋãƒĒᔮᒷ↸ ⎓⚍ãƒĒá”Žá’Ŗâ•Žá’ãƒĒᖋ|:â•Žá’ŖāĨĨ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "ᒷãƒĒᖋᕊ|:╎ãƒĒ┤ ᖋ⚍↸╎ᒍᔮᒍãƒĒá’Ŗá’ˇ/á’Ŗ ⎓⚍ãƒĒá”Žá’Ŗâ•Žá’ãƒĒᖋ|:â•Žá’ŖāĨĨ ∴╎|:|: ᖋ|:|:ᒍ∴ ⎓ᒍ∷ ᒷ/á’Ŗá’ˇãƒĒ↸ᒷ↸ ᖋ⚍↸╎ᒍ âŽ“á’ˇá–‹á’Ŗâšâˆˇá’ˇĪŸ |:╎·Į€Âˇá’ˇ ᖋ⚍↸╎ᒍ ãƒĒᒍ∷ᒲᖋ|:â•ŽâˆŠá–‹á’Ŗâ•Žá’ãƒĒ , ᒷᑑ⚍ᖋ|:â•ŽâˆŠá’ˇâˆˇĪŸ ᖋãƒĒ↸ âŠâ•ŽĪŸâšá–‹|:â•ŽâˆŠá’ˇâˆˇĪŸ, ⍑ᒍ∴ᒷ⍊ᒷ∷ ᒍãƒĒ ĪŸá’á’˛á’ˇ ΟāĨĨĪŸá’Ŗá’ˇá’˛ĪŸ á’Ŗâ‘â•ŽĪŸ ᒲᖋāĨĨ á”Žá–‹âšĪŸá’ˇ ĪŸá’Ŗâšá’Ŗá’Ŗá’ˇâˆˇâ•ŽãƒĒ┤ ╎ãƒĒ ᖋ⚍↸╎ᒍ á’Ŗâˆˇá–‹á”ŽÂˇĮ€ÂˇĪŸ.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "ᖋ⚍↸╎ᒍ ãƒĒᒍ∷ᒲᖋ|:â•ŽâˆŠá–‹á’Ŗâ•Žá’ãƒĒ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "ãƒĒᒍ∷ᒲᖋ|:â•ŽâˆŠá’ˇĪŸ i!ᒷᖋ·Į€Âˇ ⍊ᒍ|:⚍ᒲᒷ ⎓ᒍ∷ ╎ãƒĒ↸╎⍊╎↸⚍ᖋ|: á’Ŗâˆˇá–‹á”ŽÂˇĮ€ÂˇĪŸ á’Ŗá’ á”Žâˆˇá’ˇá–‹á’Ŗá’ˇ ᖋ ᒲᒍ∷ᒷ ⚍ãƒĒ╎⎓ᒍ∷ᒲ |:â•ŽĪŸá’Ŗá’ˇãƒĒ╎ãƒĒ┤ ᒷ/i!ᒷ∷╎ᒷãƒĒᔮᒷ.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "ᖋ⚍↸╎ᒍ Οi!á–‹á’Ŗâ•Žá–‹|:â•ŽâˆŠá–‹á’Ŗâ•Žá’ãƒĒ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Οi!á–‹á’Ŗâ•Žá–‹|:╎∩ᒷ ᖋ⚍↸╎ᒍ ᖋãƒĒ↸ ᒲᖋ·Į€Âˇá’ˇ ᖋ⚍↸╎ᒍ ᒲᒍ∷ᒷ 3-↸╎ᒲᒷãƒĒĪŸâ•Žá’ãƒĒᖋ|: (ãƒĒá’á’Ŗá’ˇ: á’Ŗâ‘â•ŽĪŸ â•ŽĪŸ ãƒĒá’á’Ŗ ↸ᒍ|:ᕊāĨĨ á–‹á’Ŗá’˛á’ĪŸ)", - // Settings - Visual - "settings.header.visual": "âŠâ•ŽĪŸâšá–‹|:", - "settings.header.visual.description": "á–‹â†¸â‹ŽâšĪŸá’Ŗ á’Ŗâ‘á’ˇ âŠâ•ŽĪŸâšá–‹| ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", - "settings.option.visual.windowBackgroundStyle": "∴╎ãƒĒ↸ᒍ∴ ᕊᖋᔮ·Į€Âˇâ”¤âˆˇá’âšãƒĒ↸ ĪŸá’ŖāĨĨ|:ᒷ", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "ãƒĒᒍãƒĒᒷ", - "settings.header.visual.windowBackgroundStyle.artwork": "á–‹âˆˇá’Ŗâˆ´á’âˆˇÂˇĮ€Âˇ", - "settings.header.visual.windowBackgroundStyle.image": "╎ᒲᖋ┤ᒷ", - "settings.option.visual.animatedArtwork": "ᖋãƒĒâ•Žá’˛á–‹á’Ŗá’ˇâ†¸ á–‹âˆˇá’Ŗâˆ´á’âˆˇÂˇĮ€Âˇ", // Dropdown - "settings.header.visual.animatedArtwork.always": "ᖋ|:∴ᖋāĨĨΟ", - "settings.header.visual.animatedArtwork.limited": "|:â•Žá’˛â•Žá’Ŗá’ˇâ†¸ á’Ŗá’ i!á–‹â”¤á’ˇĪŸ ᖋãƒĒ↸ Οi!ᒷᔮ╎ᖋ|: ᒷãƒĒá’Ŗâˆˇâ•Žá’ˇĪŸ", - "settings.header.visual.animatedArtwork.disable": "â†¸â•ŽĪŸá–‹á•Š|:ᒷ ᒷ⍊ᒷ∷āĨĨ∴⍑ᒷ∷ᒷ", - "settings.option.visual.animatedArtworkQuality": "ᖋãƒĒâ•Žá’˛á–‹á’Ŗá’ˇâ†¸ á–‹âˆˇá’Ŗâˆ´á’âˆˇÂˇĮ€Âˇ ᑑ⚍ᖋ|:â•Žá’ŖāĨĨ", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "|:ᒍ∴", - "settings.header.visual.animatedArtworkQuality.medium": "ᒲᒷ↸╎⚍ᒲ", - "settings.header.visual.animatedArtworkQuality.high": "⍑╎┤⍑", - "settings.header.visual.animatedArtworkQuality.veryHigh": "⍊ᒷ∷āĨĨ ⍑╎┤⍑", - "settings.header.visual.animatedArtworkQuality.extreme": "ᒷ/á’Ŗâˆˇá’ˇá’˛á’ˇ", - "settings.option.visual.animatedWindowBackground": "ᖋãƒĒâ•Žá’˛á–‹á’Ŗá’ˇâ†¸ ∴╎ãƒĒ↸ᒍ∴ ᕊᖋᔮ·Į€Âˇâ”¤âˆˇá’âšãƒĒ↸", // Toggle - "settings.option.visual.hardwareAcceleration": "⍑ᖋ∷↸∴ᖋ∷ᒷ ᖋᔮᔮᒷ|:á’ˇâˆˇá–‹á’Ŗâ•Žá’ãƒĒ", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "âˆˇá’ˇá‘‘âšâ•Žâˆˇá’ˇĪŸ ∷ᒷ|:ᖋ⚍ãƒĒᔮ⍑", - "settings.header.visual.hardwareAcceleration.default": "↸ᒷ⎓ᖋ⚍|:á’Ŗ", - "settings.header.visual.hardwareAcceleration.webGPU": "∴ᒷᕊ┤i!⚍", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "ĪŸâ‘á’âˆ´ i!á’ˇâˆˇĪŸá’ãƒĒᖋ|: ╎ãƒĒ⎓ᒍ", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "|:āĨĨâˆˇâ•Žá”ŽĪŸ", - "settings.header.lyrics.description": "á–‹â†¸â‹ŽâšĪŸá’Ŗ á’Ŗâ‘á’ˇ |:āĨĨâˆˇâ•Žá”ŽĪŸ ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", - "settings.option.lyrics.enableMusixmatch": "ᒷãƒĒᖋᕊ|:ᒷ á’˛âšĪŸâ•ŽĖ‡/á’˛á–‹á’Ŗá”Žâ‘ |:āĨĨâˆˇâ•Žá”ŽĪŸ", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "ᒷãƒĒᖋᕊ|:ᒷ ¡Į€Âˇá–‹âˆˇá–‹á’ÂˇĮ€Âˇá’ˇ ᒲᒍ↸ᒷ (á’˛âšĪŸâ•ŽĖ‡/á’˛á–‹á’Ŗá”Žâ‘ ᒍãƒĒ|:āĨĨ)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "á’˛âšĪŸâ•ŽĖ‡/á’˛á–‹á’Ŗá”Žâ‘ á’Ŗâˆˇá–‹ãƒĒΟ|:á–‹á’Ŗâ•Žá’ãƒĒ i!∷ᒷ⎓ᒷ∷∷ᒷ↸ |:ᖋãƒĒ┤⚍ᖋ┤ᒷ", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "ᒷãƒĒᖋᕊ|:ᒷ āĨĨá’âšá’Ŗâšá•Šá’ˇ |:āĨĨâˆˇâ•Žá”ŽĪŸ ⎓ᒍ∷ á’˛âšĪŸâ•Žá”Ž âŠâ•Žâ†¸á’ˇá’ĪŸ", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "ᔮᒍãƒĒãƒĒá’ˇá”Žá’Ŗâ•ŽâŠâ•Žá’ŖāĨĨ", - "settings.header.connectivity.description": "á–‹â†¸â‹ŽâšĪŸá’Ŗ á’Ŗâ‘á’ˇ ᔮᒍãƒĒãƒĒá’ˇá”Žá’Ŗâ•ŽâŠâ•Žá’ŖāĨĨ ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", - "settings.option.connectivity.discordRPC": "â†¸â•ŽĪŸá”Žá’âˆˇâ†¸ ∷╎ᔮ⍑ i!âˆˇá’ˇĪŸá’ˇãƒĒᔮᒷ", // Dropdown - "settings.option.connectivity.playbackNotifications": "i!|:ᖋāĨĨᕊᖋᔮ·Į€Âˇ ãƒĒá’á’Ŗâ•ŽâŽ“â•Žá”Žá–‹á’Ŗâ•Žá’ãƒĒΟ", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "â†¸â•ŽĪŸi!|:ᖋāĨĨ á–‹ĪŸ 'ᔮ╎↸ᒷ∷'", - "settings.header.connectivity.discordRPC.appleMusic": "â†¸â•ŽĪŸi!|:ᖋāĨĨ á–‹ĪŸ 'ᖋi!i!|:ᒷ á’˛âšĪŸâ•Žá”Ž'", - "settings.option.connectivity.discordRPC.clearOnPause": "ᔮ|:ᒷᖋ∷ â†¸â•ŽĪŸá”Žá’âˆˇâ†¸ ∷╎ᔮ⍑ i!âˆˇá’ˇĪŸá’ˇãƒĒᔮᒷ ᒍãƒĒ i!á–‹âšĪŸá’ˇ", // Toggle - "settings.option.connectivity.lastfmScrobble": "|:á–‹ĪŸá’ŖâŽ“á’˛ ĪŸá”Žâˆˇá’á•Šá•Š|:╎ãƒĒ┤", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "|:á–‹ĪŸá’ŖâŽ“á’˛ ĪŸá”Žâˆˇá’á•Šá•Š|:ᒷ ↸ᒷ|:ᖋāĨĨ (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "ᒷãƒĒᖋᕊ|:ᒷ |:á–‹ĪŸá’ŖâŽ“á’˛ ãƒĒᒍ∴ i!|:ᖋāĨĨ╎ãƒĒ┤", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "∷ᒷᒲᒍ⍊ᒷ âŽ“á’ˇá–‹á’Ŗâšâˆˇâ•ŽãƒĒ┤ á–‹âˆˇá’Ŗâ•ŽĪŸá’ŖĪŸ ⎓∷ᒍᒲ ĪŸá’ãƒĒ┤ á’Ŗâ•Žá’Ŗ|:ᒷ (|:á–‹ĪŸá’ŖâŽ“á’˛)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "⎓╎|:á’Ŗá’ˇâˆˇ |:ᒍᒍi!ᒷ↸ á’Ŗâˆˇá–‹á”ŽÂˇĮ€Âˇ (|:á–‹ĪŸá’ŖâŽ“á’˛)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "ᒷ/i!ᒷ∷╎ᒲᒷãƒĒá’Ŗá–‹|:", - "settings.header.experimental.description": "á–‹â†¸â‹ŽâšĪŸá’Ŗ á’Ŗâ‘á’ˇ ᒷ/i!ᒷ∷╎ᒲᒷãƒĒá’Ŗá–‹|: ĪŸá’ˇá’Ŗá’Ŗâ•ŽãƒĒâ”¤ĪŸ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", - "settings.option.experimental.compactUI": "ᔮᒍᒲi!á–‹á”Žá’Ŗ ⚍╎", // Toggle - "settings.option.experimental.closeButtonBehaviour": "ᔮ|:á’ĪŸá’ˇ á•Šâšá’Ŗá’Ŗá’ãƒĒ ᕊᒷ⍑ᖋ⍊╎ᒍ⚍∷", - "settings.option.experimental.closeButtonBehaviour.quit": "á‘‘âšâ•Žá’Ŗ ᔮ╎↸ᒷ∷", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "ᒲ╎ãƒĒ╎ᒲ╎∩ᒷ á’Ŗá’ á’Ŗá–‹ĪŸÂˇĮ€Âˇá•Šá–‹âˆˇ", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "ᒲ╎ãƒĒ╎ᒲ╎∩ᒷ á’Ŗá’ ΟāĨĨĪŸá’Ŗá’ˇá’˛ á’Ŗâˆˇá–‹āĨĨ", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.spatialProperties" : "Οi!á–‹á’Ŗâ•Žá–‹|: i!∷ᒍi!á’ˇâˆˇá’Ŗâ•Žá’ˇĪŸ", - "spatial.width" : "âˆ´â•Žâ†¸á’Ŗâ‘", - "spatial.height" : "â‘á’ˇâ•Žâ”¤â‘á’Ŗ", - "spatial.depth" : "↸ᒷi!á’Ŗâ‘", - "spatial.gain" : "┤ᖋ╎ãƒĒ", - "spatial.roomMaterials" : "∷ᒍᒍᒲ á’˛á–‹á’Ŗá’ˇâˆˇâ•Žá–‹|:Ο", - "spatial.roomDimensions" : "∷ᒍᒍᒲ ↸╎ᒲᒷãƒĒĪŸâ•Žá’ãƒĒΟ", - "spatial.roomPositions" : "∷ᒍᒍᒲ i!á’ĪŸâ•Žá’Ŗâ•Žá’ãƒĒΟ", - "spatial.setDimensions" : "ĪŸá’ˇá’Ŗ ↸╎ᒲᒷãƒĒĪŸâ•Žá’ãƒĒΟ", - "spatial.setPositions" : "ĪŸá’ˇá’Ŗ i!á’ĪŸâ•Žá’Ŗâ•Žá’ãƒĒΟ", - "spatial.up" : "⚍i!", - "spatial.front" : "⎓∷ᒍãƒĒá’Ŗ", - "spatial.left" : "|:á’ˇâŽ“á’Ŗ", - "spatial.right" : "âˆˇâ•Žâ”¤â‘á’Ŗ", - "spatial.back" : "ᕊᖋᔮ·Į€Âˇ", - "spatial.down" : "↸ᒍ∴ãƒĒ", - "spatial.listener" : "|:â•ŽĪŸá’Ŗá’ˇãƒĒᒷ∷", - "spatial.audioSource" : "ᖋ⚍↸╎ᒍ ĪŸá’âšâˆˇá”Žá’ˇ", - - // Settings - Unfinished - "settings.header.unfinished": "⚍ãƒĒ⎓╎ãƒĒâ•ŽĪŸâ‘á’ˇâ†¸", - - // Web Remote - "remote.web.title": "ᔮ╎↸ᒷ∷ âˆˇá’ˇá’˛á’á’Ŗá’ˇ", - "remote.web.description": "ĪŸá”Žá–‹ãƒĒ á’Ŗâ‘á’ˇ ᑑ∷ ᔮᒍ↸ᒷ á’Ŗá’ i!ᖋ╎∷ āĨĨᒍ⚍∷ i!⍑ᒍãƒĒᒷ ⚍i! âˆ´â•Žá’Ŗâ‘ á’Ŗâ‘â•ŽĪŸ ᔮ╎↸ᒷ∷ ╎ãƒĒĪŸá’Ŗá–‹ãƒĒᔮᒷ", - - // About - "about.thanks": "ᒲᖋ⋮ᒍ∷ á’Ŗâ‘á–‹ãƒĒ¡Į€ÂˇĪŸ á’Ŗá’ á’Ŗâ‘á’ˇ ᔮ╎↸ᒷ∷ ᔮᒍ|:|:á’ˇá”Žá’Ŗâ•ŽâŠá’ˇ á’Ŗá’ˇá–‹á’˛ ᖋãƒĒ↸ ᖋ|:|: ᒍ⎓ ᒍ⚍∷ ᔮᒍãƒĒá’Ŗâˆˇâ•Žá•Šâšá’Ŗá’âˆˇĪŸ." -} \ No newline at end of file diff --git a/src/i18n/en_US.jsonc b/src/i18n/en_US.jsonc deleted file mode 100644 index 0436c4e7..00000000 --- a/src/i18n/en_US.jsonc +++ /dev/null @@ -1,311 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "English (US)", // name of language in native language - "i18n.languageNameEnglish": "English (US)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${m} ${d}, ${y}", - - // Dialogs - "dialog.cancel": "Cancel", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "Updating library songs...", - "notification.updatingLibraryAlbums": "Updating library albums...", - "notification.updatingLibraryArtists": "Updating library artists...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Learn more", - "term.accountSettings": "Account Settings", - "term.logout": "Logout", - "term.login": "Login", - "term.about": "About", - "term.privateSession": "Private Session", - "term.queue": "Queue", - "term.search": "Search", - "term.library": "Library", - "term.listenNow": "Listen Now", - "term.browse": "Browse", - "term.radio": "Radio", - "term.recentlyAdded": "Recently Added", - "term.songs": "Songs", - "term.albums": "Albums", - "term.artists": "Artists", - "term.podcasts": "Podcasts", - "term.playlists": "Playlists", - "term.playlist": "Playlist", - "term.newPlaylist": "New Playlist", - "term.newPlaylistFolder": "New Playlist Folder", - "term.createNewPlaylist": "Create New Playlist", - "term.createNewPlaylistFolder": "Create New Playlist Folder", - "term.deletePlaylist": "Are you sure you want to delete this playlist?", - "term.play": "Play", - "term.pause": "Pause", - "term.previous": "Previous", - "term.next": "Next", - "term.shuffle": "Shuffle", - "term.repeat": "Repeat", - "term.volume": "Volume", - "term.mute": "Mute", - "term.unmute": "Unmute", - "term.share": "Share", - "term.settings": "Settings", - "term.seeAll": "See All", - "term.sortBy": "Sort By", - "term.sortBy.album": "Album", - "term.sortBy.artist": "Artist", - "term.sortBy.name": "Name", - "term.sortBy.genre": "Genre", - "term.sortBy.releaseDate": "Release Date", - "term.sortBy.duration": "Duration", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Ascending", - "term.sortOrder.descending": "Descending", - "term.viewAs": "View As", - "term.viewAs.coverArt": "Cover Art", - "term.viewAs.list": "List", - "term.size": "Size", - "term.size.normal": "Normal", - "term.size.compact": "Compact", - "term.enable": "Enable", - "term.disable": "Disable", - "term.enabled": "Enabled", - "term.disabled": "Disabled", - "term.connect": "Connect", - "term.connecting": "Connecting", - "term.disconnect": "Disconnect", - "term.authed": "Authed", - "term.confirm": "Confirm ?", - "term.more": "More", - "term.less": "Less", - "term.showMore": "Show more", - "term.showLess": "Show less", - "term.topSongs" : "Top Songs", - "term.latestReleases": "Latest Releases", - "term.time.added": "Added", - "term.time.released": "Released", - "term.time.updated": "Updated", - "term.time.hours": "hours", - "term.time.hour": "hour", - "term.time.minutes": "minutes", - "term.time.minute": "minute", - "term.time.seconds": "seconds", - "term.time.second": "second", - "term.fullscreenView": "Fullscreen View", - "term.defaultView": "Default View", - "term.audioSettings": "Audio Settings", - "term.clearAll": "Clear All", - "term.recentStations": "Recent Stations", - "term.language": "Language", - "term.funLanguages": "Fun", - "term.noLyrics": "Loading... / Lyrics not found./ Instrumental.", - "term.copyright": "Copyright", - "term.rightsReserved": "All Rights Reserved.", - "term.sponsor": "Sponsor this project", - "term.ciderTeam": "Cider Team", - "term.developer": "Developer", - "term.socialTeam": "Social Team", - "term.socials": "Socials", - "term.contributors": "Contributors", - "term.equalizer": "Equalizer", - "term.reset": "Reset", - "term.tracks": "tracks", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Videos", - "term.menu": "Menu", - "term.check": "Check", - "term.aboutArtist": "About {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Update Cider", - - // Home - "home.title": "Home", - "home.recentlyPlayed": "Recently Played", - "home.recentlyAdded": "Recently Added", - "home.artistsFeed": "Your Artists Feed", - "home.artistsFeed.noArtist": "Follow some artists first and their latest releases will be here", - "home.madeForYou": "Made For You", - "home.friendsListeningTo": "Friends Listening To", - "home.followedArtists": "Followed Artists", - // Errors - "error.appleMusicSubRequired": "Apple Music requires a subscription.", - "error.connectionError": "There was a problem connecting to Apple Music.", - "error.noResults": "No Results.", - "error.noResults.description": "Try a new search.", - - //Podcasts - "podcast.followOnCider": "Follow On Cider", - "podcast.followedOnCider": "Following On Cider", - "podcast.subscribeOnItunes": "Subscribe On iTunes", - "podcast.subscribedOnItunes": "Subscribed On iTunes", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "Episodes", - "podcast.playEpisode": "Play Episode", - "podcast.website": "Podcast Website", - - // Actions - "action.addToLibrary": "Add to Library", - "action.addToLibrary.success": "Added to Library", - "action.addToLibrary.error": "Error Adding to Library", - "action.removeFromLibrary": "Remove from Library", - "action.removeFromLibrary.success": "Removed from Library", - "action.addToQueue": "Add to Queue", - "action.addToQueue.success": "Added to Queue", - "action.addToQueue.error": "Error Adding to Queue", - "action.removeFromQueue": "Remove from Queue", - "action.removeFromQueue.success": "Removed from Queue", - "action.removeFromQueue.error": "Error Removing from Queue", - "action.createPlaylist": "Create a New Playlist", - "action.addToPlaylist": "Add to Playlist", - "action.removeFromPlaylist": "Remove from Playlist", - "action.addToFavorites": "Add to Favorites", - "action.follow": "Follow", - "action.follow.success": "Followed", - "action.follow.error": "Error Following", - "action.unfollow": "Unfollow", - "action.unfollow.success": "Unfollowed", - "action.unfollow.error": "Error Unfollowing", - "action.playNext": "Play Next", - "action.playLater": "Play Later", - "action.startRadio": "Start Radio", - "action.goToArtist": "Go to Artist", - "action.goToAlbum": "Go to Album", - "action.moveToTop": "Move to top", - "action.share": "Share", - "action.rename": "Rename", - "action.love": "Love", - "action.unlove": "Unlove", - "action.dislike": "Dislike", - "action.undoDislike": "Undo dislike", - "action.showWebRemoteQR": "Web Remote", - "action.playTracksNext": "Play ${app.selectedMediaItems.length} tracks next", - "action.playTracksLater": "Play ${app.selectedMediaItems.length} tracks later", - "action.removeTracks": "Remove ${self.selectedItems.length} tracks from queue", - "action.import": "Import", - "action.export": "Export", - "action.showAlbum": "Show Complete Album", - "action.tray.minimize": "Minimize to Tray", - "action.tray.quit": "Quit", - "action.tray.show": "Show", - "action.update": "Update", - - // Settings - General - "settings.header.general": "General", - "settings.header.general.description": "Adjust the general settings for Cider.", - "settings.option.general.language": "Language", - - // Language optgroups - "settings.option.general.language.main": "Languages", - "settings.option.general.language.fun": "Fun Languages", - "settings.option.general.language.unsorted": "Unsorted", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Adjust the audio settings for Cider.", - "settings.option.audio.quality": "Audio Quality", // Dropdown - "settings.header.audio.quality.high": "High", - "settings.header.audio.quality.low": "Low", - "settings.header.audio.quality.auto": "Auto", - "settings.option.audio.seamlessTransition": "Seamless Audio Transition", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Enable Advanced Functionality", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Enabling AudioContext functionality will allow for extended audio features like Audio Normalization , Equalizers and Visualizers, however on some systems this may cause stuttering in audio tracks.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio Normalization", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizes peak volume for individual tracks to create a more uniform listening experience.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Audio Spatialization", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spatialize audio and make audio more 3-dimensional (note: This is not Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visual", - "settings.header.visual.description": "Adjust the visual settings for Cider.", - "settings.option.visual.windowBackgroundStyle": "Window Background Style", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "None", - "settings.header.visual.windowBackgroundStyle.artwork": "Artwork", - "settings.header.visual.windowBackgroundStyle.image": "Image", - "settings.option.visual.animatedArtwork": "Animated Artwork", // Dropdown - "settings.header.visual.animatedArtwork.always": "Always", - "settings.header.visual.animatedArtwork.limited": "Limited to pages and special entries", - "settings.header.visual.animatedArtwork.disable": "Disable everywhere", - "settings.option.visual.animatedArtworkQuality": "Animated Artwork Quality", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Low", - "settings.header.visual.animatedArtworkQuality.medium": "Medium", - "settings.header.visual.animatedArtworkQuality.high": "High", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Very High", - "settings.header.visual.animatedArtworkQuality.extreme": "Extreme", - "settings.option.visual.animatedWindowBackground": "Animated Window Background", // Toggle - "settings.option.visual.hardwareAcceleration": "Hardware Acceleration", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "Requires relaunch", - "settings.header.visual.hardwareAcceleration.default": "Default", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Show Personal Info", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "Lyrics", - "settings.header.lyrics.description": "Adjust the lyrics settings for Cider.", - "settings.option.lyrics.enableMusixmatch": "Enable Musixmatch Lyrics", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Enable Karaoke Mode (Musixmatch only)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch Translation Preferred Language", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Enable Youtube Lyrics for Music Videos", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Connectivity", - "settings.header.connectivity.description": "Adjust the connectivity settings for Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Playback Notifications", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Display as 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Display as 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Clear Discord Rich Presence on Pause", // Toggle - "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble Delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Enable Last.fm Now Playing", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (Last.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.fm)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "Experimental", - "settings.header.experimental.description": "Adjust the experimental settings for Cider.", - "settings.option.experimental.compactUI": "Compact UI", // Toggle - "settings.option.experimental.close_button_hide": "Close Button Should Hide the Application", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "Audio Spatialization is disabled. To use, please enable it first.", - "spatial.spatialProperties": "Spatial Properties", - "spatial.width": "Width", - "spatial.height": "Height", - "spatial.depth": "Depth", - "spatial.gain": "Gain", - "spatial.roomMaterials": "Room Materials", - "spatial.roomDimensions": "Room Dimensions", - "spatial.roomPositions": "Room Positions", - "spatial.setDimensions": "Set Dimensions", - "spatial.setPositions": "Set Positions", - "spatial.up": "Up", - "spatial.front": "Front", - "spatial.left": "Left", - "spatial.right": "Right", - "spatial.back": "Back", - "spatial.down": "Down", - "spatial.listener": "Listener", - "spatial.audioSource": "Audio Source", - - // Settings - Unfinished - "settings.header.unfinished": "Unfinished", - - // Web Remote - "remote.web.title": "Cider Remote", - "remote.web.description": "Scan the QR code to pair your phone up with this Cider instance", - - // About - "about.thanks": "Major thanks to the Cider Collective Team and all of our contributors." -} diff --git a/src/i18n/es_ES.jsonc b/src/i18n/es_ES.jsonc deleted file mode 100644 index 6ad1ee9d..00000000 --- a/src/i18n/es_ES.jsonc +++ /dev/null @@ -1,312 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "EspaÃąol (ES)", // name of language in native language - "i18n.languageNameEnglish": "Spanish (Spain)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@j.fl220", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${d} ${m}, ${y}", - - // Dialogs - "dialog.cancel": "Cancelar", - "dialog.ok": "Aceptar", - - // Notification - "notification.updatingLibrarySongs": "Actualizando canciones de la biblioteca...", - "notification.updatingLibraryAlbums": "Actualizando ÃĄlbumes de la biblioteca...", - "notification.updatingLibraryArtists": "Actualizando biblioteca de artistas...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Leer mÃĄs", - "term.accountSettings": "Ajustes de la cuenta", - "term.logout": "Cerrar sesiÃŗn", - "term.login": "Iniciar sesiÃŗn", - "term.about": "MÃĄs informaciÃŗn", - "term.privateSession": "SesiÃŗn privada", - "term.queue": "En cola", - "term.search": "Buscar", - "term.library": "Biblioteca", - "term.listenNow": "Escuchar", - "term.browse": "Explorar", - "term.radio": "Radio", - "term.recentlyAdded": "AÃąadido recientemente", - "term.songs": "Canciones", - "term.albums": "Álbumes", - "term.artists": "Artistas", - "term.podcasts": "Podcasts", - "term.playlists": "Playlists", - "term.playlist": "Playlist", - "term.newPlaylist": "Nueva playlist", - "term.newPlaylistFolder": "Nueva carpeta de playlists", - "term.createNewPlaylist": "Crear nueva playlists", - "term.createNewPlaylistFolder": "Crear nueva carpeta de playlists", - "term.deletePlaylist": "ÂŋEstÃĄ seguro que desea eliminar esta playlist?", - "term.play": "Reproducir", - "term.pause": "Pausar", - "term.previous": "Anterior", - "term.next": "Siguiente", - "term.shuffle": "Aleatorio", - "term.repeat": "Repetir", - "term.volume": "Volumen", - "term.mute": "Silenciar", - "term.unmute": "Desilenciar", - "term.share": "Compartir", - "term.settings": "Ajustes", - "term.seeAll": "Ver todo", - "term.sortBy": "Ordenar por", - "term.sortBy.album": "Álbum", - "term.sortBy.artist": "Artista", - "term.sortBy.name": "Nombre", - "term.sortBy.genre": "GÊnero", - "term.sortBy.releaseDate": "Fecha de lanzamiento", - "term.sortBy.duration": "DuraciÃŗn", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Ascendiente", - "term.sortOrder.descending": "Descendiente", - "term.viewAs": "Ver como", - "term.viewAs.coverArt": "CarÃĄtula", - "term.viewAs.list": "Lista", - "term.size": "TamaÃąo", - "term.size.normal": "Normal", - "term.size.compact": "Compacto", - "term.enable": "Habilitar", - "term.disable": "Deshabilitar", - "term.enabled": "Activado", - "term.disabled": "Desactivado", - "term.connect": "Conectar", - "term.connecting": "Conectando", - "term.disconnect": "Desconectado", - "term.authed": "Autentificado", - "term.confirm": "ÂŋConfirmar?", - "term.more": "MÃĄs", - "term.less": "Menos", - "term.showMore": "Mostrar mÃĄs", - "term.showLess": "Mostrar menos", - "term.topSongs" : "Top canciones", - "term.latestReleases": "Últimos lanzamientos", - "term.time.added": "AÃąadido", - "term.time.released": "Lanzado", - "term.time.updated": "Actualizado", - "term.time.hours": "horas", - "term.time.hour": "hora", - "term.time.minutes": "minutos", - "term.time.minute": "minuto", - "term.time.seconds": "segundos", - "term.time.second": "segundo", - "term.fullscreenView": "Pantalla completa", - "term.defaultView": "Vista por defecto", - "term.audioSettings": "Ajustes de audio", - "term.clearAll": "Borrar todo", - "term.recentStations": "Radios recientes", - "term.language": "Idioma", - "term.funLanguages": "Divertido", - "term.noLyrics": "Cargando... / Letra no encontrada./ Instrumental.", - "term.copyright": "Copyright", - "term.rightsReserved": "Todos los derechos reservados.", - "term.sponsor": "Apoya este proyecto", - "term.ciderTeam": "Equipo Cider", - "term.developer": "Desarrollador", - "term.socialTeam": "Equipo RRSS", - "term.socials": "Redes sociales", - "term.contributors": "Contribuidores", - "term.equalizer": "Equalizador", - "term.reset": "Resetear", - "term.tracks": "canciones", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Vídeos", - "term.menu": "MenÃē", - "term.check": "Comprobar", - "term.aboutArtist": "MÃĄs sobre {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Actualizar Cider", - - // Home - "home.title": "Inicio", - "home.recentlyPlayed": "Reproducciones recientes", - "home.recentlyAdded": "AÃąadido recientemente", - "home.artistsFeed": "Historial de tus artistas", - "home.artistsFeed.noArtist": "Sigue primero a algunos artistas y sus Ãēltimos lanzamientos aparecerÃĄn aquí", - "home.madeForYou": "Hecho para ti", - "home.friendsListeningTo": "Tus amigos estÃĄn escuchando", - "home.followedArtists": "Artistas que sigues", - // Errors - "error.appleMusicSubRequired": "Apple Music necesita una suscripciÃŗn.", - "error.connectionError": "Ha habido un problema al conectar con Apple Music.", - "error.noResults": "Sin resultados", - "error.noResults.description": "Intenta otra bÃēsqueda.", - - //Podcasts - "podcast.followOnCider": "Seguir en Cider", - "podcast.followedOnCider": "Siguiendo en Cider", - "podcast.subscribeOnItunes": "Suscribirse en iTunes", - "podcast.subscribedOnItunes": "Suscrito en iTunes", - "podcast.itunesStore": "Tienda de iTunes", - "podcast.episodes": "Episodios", - "podcast.playEpisode": "Iniciar Episodio", - "podcast.website": "Pagina del podcast", - - // Actions - "action.addToLibrary": "AÃąadir a la biblioteca", - "action.addToLibrary.success": "AÃąadido a la biblioteca", - "action.addToLibrary.error": "Error al aÃąadir a la biblioteca", - "action.removeFromLibrary": "Eliminar de la biblioteca", - "action.removeFromLibrary.success": "Eliminado de la biblioteca", - "action.addToQueue": "AÃąadir a la cola", - "action.addToQueue.success": "AÃąadido a la cola", - "action.addToQueue.error": "Error al aÃąadirlo a la cola", - "action.removeFromQueue": "Elimiar de la cola", - "action.removeFromQueue.success": "Eliminado de la cola", - "action.removeFromQueue.error": "Error al eliminarlo de la cola", - "action.createPlaylist": "Crear nueva playlist", - "action.addToPlaylist": "AÃąadir a la playlist", - "action.removeFromPlaylist": "Eliminar de la playlist", - "action.addToFavorites": "AÃąadir a favoritos", - "action.follow": "Seguir", - "action.follow.success": "Siguiendo", - "action.follow.error": "Error al seguir", - "action.unfollow": "Dejar de seguir", - "action.unfollow.success": "Has dejado de seguirle", - "action.unfollow.error": "Error al dejar de seguir", - "action.playNext": "Reproducir a continuaciÃŗn", - "action.playLater": "Reproducir al final", - "action.startRadio": "Crear emisora", - "action.goToArtist": "Ir al artista", - "action.goToAlbum": "Mostrar ÃĄlbum", - "action.moveToTop": "Mover a arriba", - "action.share": "Compartir", - "action.rename": "Renombrar", - "action.love": "Me gusta", - "action.unlove": "Eliminar me gusta", - "action.dislike": "Sugerir menos este estilo", - "action.undoDislike": "Sugerir este estilo", - "action.showWebRemoteQR": "ConexiÃŗn remota", - "action.playTracksNext": "Reproducir ${app.selectedMediaItems.length} siguiente canciÃŗn", - "action.playTracksLater": "Reproducir ${app.selectedMediaItems.length} como Ãēltima canciÃŗn", - "action.removeTracks": "Eliminar ${self.selectedItems.length} canciones de la cola", - "action.import": "Importar", - "action.export": "Exportar", - "action.showAlbum": "Mostrar ÃĄlbum completo", - "action.tray.minimize": "Mover a la bandeja", - "action.tray.quit": "Salir", - "action.tray.show": "Abrir", - "action.update": "Actualizar", - - // Settings - General - "settings.header.general": "General", - "settings.header.general.description": "Ajustes generales de Cider.", - "settings.option.general.language": "Idioma", - - // Language optgroups - "settings.option.general.language.main": "Idiomas", - "settings.option.general.language.fun": "Idiomas divertidos", - "settings.option.general.language.unsorted": "Sin clasificar", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Ajustes del audio de Cider.", - "settings.option.audio.quality": "Calidad de audio", // Dropdown - "settings.header.audio.quality.high": "Alto", - "settings.header.audio.quality.low": "Bajo", - "settings.header.audio.quality.auto": "Auto", - "settings.option.audio.seamlessTransition": "TransiciÃŗn de audio perfecta", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Activar funciones avanzadas", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Habilitar la funcionalidad de AudioContext permitirÃĄ funciones de audio extendidas como NormalizaciÃŗn de audio, Ecualizadores y Visualizadores; sin embargo, en algunos sistemas esto puede causar interrupciones en las canciones.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizar volumen", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliza los picos altos de canciones para hacer la experiencia de escucha mejor.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "EspacializaciÃŗn del audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Espacializa mÃĄs el audio y conviÊrtelo mÃĄs 3-dimensional (nota: Esto no es Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visual", - "settings.header.visual.description": "Ajustes visuales para Cider.", - "settings.option.visual.windowBackgroundStyle": "Estilo del fondo de la ventana", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Nada", - "settings.header.visual.windowBackgroundStyle.artwork": "CarÃĄtula", - "settings.header.visual.windowBackgroundStyle.image": "Imagen", - "settings.option.visual.animatedArtwork": "CarÃĄtula animada", // Dropdown - "settings.header.visual.animatedArtwork.always": "Habilitar siempre", - "settings.header.visual.animatedArtwork.limited": "Limitado a algunas pÃĄginas", - "settings.header.visual.animatedArtwork.disable": "Deshabilitar en todas partes", - "settings.option.visual.animatedArtworkQuality": "Calidad de la carÃĄtula animada", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Bajo", - "settings.header.visual.animatedArtworkQuality.medium": "Medio", - "settings.header.visual.animatedArtworkQuality.high": "Alto", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Muy alto", - "settings.header.visual.animatedArtworkQuality.extreme": "Extrema", - "settings.option.visual.animatedWindowBackground": "Fondo de la ventana animado", // Toggle - "settings.option.visual.hardwareAcceleration": "AceleraciÃŗn del hardware", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "La app requiere reinicio", - "settings.header.visual.hardwareAcceleration.default": "Por defecto", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Mostrar informaciÃŗn personal", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "Letras", - "settings.header.lyrics.description": "Ajuste las letras para Cider", - "settings.option.lyrics.enableMusixmatch": "Habilitar las letras de Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Habilita el modo Karaoke (solo con Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Idioma de traducciÃŗn por defecto en Musixmatch", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Habilitar las letras de Youtube para los videos con mÃēsica", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Conectividad", - "settings.header.connectivity.description": "Ajusta la conectividad para Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Notificaciones de reproducciÃŗn", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Mostrar como 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Mostrar como 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Quitar Discord Rich Presence en pausa", // Toggle - "settings.option.connectivity.lastfmScrobble": "Scrobbling Last.fm", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Delay del Scrobbling en Last.fm (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Habilitar 'Escuchando ahora' en Last.fm", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Eliminar artistas destacados del título de la canciÃŗn (Last.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrar pista en bucle (Last.fm)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "En pruebas", - "settings.header.experimental.description": "Ajustes en pruebas para Cider.", - "settings.option.experimental.compactUI": "Interfaz de usuario compacto", // Toggle - "settings.option.experimental.close_button_hide": "El botÃŗn de cerrar minimizarÃĄ la aplicaciÃŗn en la bandeja", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "La espacializaciÃŗn del audio esta desactivada. Para usarlo primero actívelo.", - "spatial.spatialProperties": "Propiedades espaciales", - "spatial.width": "Ancho", - "spatial.height": "Altura", - "spatial.depth": "Profundidad", - "spatial.gain": "Ganancia", - "spatial.roomMaterials": "Material de la habitaciÃŗn", - "spatial.roomDimensions": "DimensiÃŗn de la habitaciÃŗn", - "spatial.roomPositions": "Posiciones de la habitaciÃŗn", - "spatial.setDimensions": "Establecer dimensiones", - "spatial.setPositions": "Establecer posiciones", - "spatial.up": "Arriba", - "spatial.front": "Delante", - "spatial.left": "Izquierda", - "spatial.right": "Derecha", - "spatial.back": "AtrÃĄs", - "spatial.down": "Abajo", - "spatial.listener": "Oyente", - "spatial.audioSource": "Salida del audio", - - // Settings - Unfinished - "settings.header.unfinished": "Sin acabar", - "settings.header.unfinished.description": "Ajustes siendo testeados, no estÃĄn acabados.", - - // Web Remote - "remote.web.title": "Cider Remoto", - "remote.web.description": "Escanee el cÃŗdigo QR para emparejar su telÊfono con su cliente de Cider", - - // About - "about.thanks": "Muchísimas gracias al equipo de Cider Collective y tambiÊn a todos nuestros contribuidores." - } diff --git a/src/i18n/fr_CA.jsonc b/src/i18n/fr_CA.jsonc deleted file mode 100644 index 132cf845..00000000 --- a/src/i18n/fr_CA.jsonc +++ /dev/null @@ -1,299 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "Français (CA)", // name of language in native language - "i18n.languageNameEnglish": "French (CA)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "brock#7527", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${m} ${d}, ${y}", - - // Dialogs - "dialog.cancel": "Annuler", - "dialog.ok": "D'accord", - - // Notification - "notification.updatingLibrarySongs": "RafraÃŽchir des chansons...", - "notification.updatingLibraryAlbums": "RafraÃŽchir des albums...", - "notification.updatingLibraryArtists": "RafraÃŽchir des artistes...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Savoir plus", - "term.accountSettings": "RÊglages du compte", - "term.logout": "Se dÊconnecter", - "term.login": "Se connecter", - "term.about": "À propos", - "term.privateSession": "Session en privÊe", - "term.queue": "Suivants", - "term.search": "Rechercher", - "term.library": "Bibliothèque", - "term.listenNow": "À Êcouter", - "term.browse": "Parcourir", - "term.radio": "Radio", - "term.recentlyAdded": "AjoutÊ rÊcemment", - "term.songs": "Chansons", - "term.albums": "Albums", - "term.artists": "Artistes", - "term.podcasts": "Podcasts", - "term.playlists": "Listes de lecture", - "term.playlist": "Liste de lecture", - "term.play": "Écouter", - "term.pause": "Pause", - "term.previous": "Retour", - "term.next": "Suivant", - "term.shuffle": "Lecture alÊatoire", - "term.repeat": "RÊpÊter", - "term.volume": "Volume", - "term.mute": "Assourde", - "term.unmute": "RÊactiver", - "term.share": "Partager", - "term.settings": "RÊglages", - "term.seeAll": "Voix tous", - "term.sortBy": "Sorter par", - "term.sortBy.album": "Album", - "term.sortBy.artist": "Artiste", - "term.sortBy.name": "Nom", - "term.sortBy.genre": "Genre", - "term.sortBy.releaseDate": "Date de sortie", - "term.sortBy.duration": "Duration", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Ascender", - "term.sortOrder.descending": "Descender", - "term.viewAs": "Voix comme", - "term.viewAs.coverArt": "Art de couverture", - "term.viewAs.list": "Liste", - "term.size": "Grandeur", - "term.size.normal": "Normal", - "term.size.compact": "Compacte", - "term.enable": "Activer", - "term.disable": "DÊsactiver", - "term.enabled": "ActivÊe", - "term.disabled": "DÊsactivÊe", - "term.connect": "Connecter", - "term.connecting": "De liaison", - "term.disconnect": "DÊconnecter", - "term.authed": "Authed", - "term.confirm": "Confirmer ?", - "term.more": "De plus", - "term.less": "De moins", - "term.showMore": "Voir plus", - "term.showLess": "Voir moins", - "term.topSongs" : "Meilleures chansons", - "term.latestReleases": "Nouvelles sorties", - "term.time.added": "AjoutÊ", - "term.time.released": "PubliÊ", - "term.time.updated": "Mis à jour", - "term.time.hours": "heures", - "term.time.hour": "heur", - "term.time.minutes": "minutes", - "term.time.minute": "minute", - "term.time.seconds": "secondes", - "term.time.second": "seconde", - "term.fullscreenView": "Vue plein Êcran", - "term.defaultView": "Vue par dÊfaut", - "term.spacializedAudioSetting": "RÊglage audio spacialisÊ", - "term.clearAll": "Tout effacer", - "term.recentStations": "Stations rÊcentes", - "term.language": "Langue", - "term.funLanguages": "Amusement", - "term.noLyrics": "Loading... / Paroles pas trouvÊ./ Instrumental.", - "term.copyright": "Droits d'auteur", - "term.rightsReserved": "Tous les droits sont rÊservÊs.", - "term.sponsor": "Parrainez ce projet", - "term.ciderTeam": "Team Cider", - "term.developer": "DÊveloppeur", - "term.socialTeam": "Équipe sociale", - "term.contributors": "Contributeurs", - "term.equalizer": "Égaliseur", - "term.reset": "RÊinitialiser", - "term.tracks": "chansons", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "VidÊos", - "term.menu": "Menu", - "action.showAlbum": "Afficher l'album complet", - - // Home - "home.title": "Maison", - "home.recentlyPlayed": "JouÊ rÊcemment", - "home.recentlyAdded": "AjoutÊ rÊcemment", - "home.artistsFeed": "Votre flux d'artistes", - "home.artistsFeed.noArtist": "Suivez certains artistes en premier et leurs dernières sorties seront ici", - "home.madeForYou": "CreÊr pour toi", - "home.friendsListeningTo": "Amis Êcoutant", - "home.followedArtists": "Artistes suivis", - // Errors - "error.appleMusicSubRequired": "Apple Music nÊcessite un abonnement.", - "error.connectionError": "Un problème est survenu lors de la connexion à Apple Music.", - "error.noResults": "Pas de resultats.", - "error.noResults.description": "Essayez une nouvelle recherche.", - - //Podcasts - "podcast.followOnCider": "Suivez sur Cider", - "podcast.followedOnCider": "Suivi sur Cider", - "podcast.subscribeOnItunes": "S'abonner sur iTunes", - "podcast.subscribedOnItunes": "AbonnÊ sur iTunes", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "Épisodes", - "podcast.playEpisode": "Lire l'Êpisode", - "podcast.website": "Site web du Podcast", - - // Actions - "action.addToLibrary": "Ajouter à biblio", - "action.addToLibrary.success": "AjoutÊ à biblio", - "action.addToLibrary.error": "Erreur lors de l'ajout à biblio", - "action.removeFromLibrary": "Enlever du biblio", - "action.removeFromLibrary.success": "EnlevÊ du biblio", - "action.addToQueue": "Ajouter à suivants", - "action.addToQueue.success": "AjoutÊ à suivants", - "action.addToQueue.error": "Erreur lors de l'ajout à suivants", - "action.removeFromQueue": "Enlever du suivants", - "action.removeFromQueue.success": "EnlevÊ du suivants", - "action.removeFromQueue.error": "Erreur lors d'enleve du suivants", - "action.addToPlaylist": "Ajoute à liste de lecture", - "action.removeFromPlaylist": "Enleve de liste de lecture", - "action.addToFavorites": "Ajoute à Favorites", - "action.follow": "Suivre", - "action.follow.success": "Suivi", - "action.follow.error": "Erreur a suivre", - "action.unfollow": "Arreter a suivi", - "action.unfollow.success": "Arreter a suivre", - "action.unfollow.error": "Erreur de arreter à suivre", - "action.playNext": "Jouer en prochaine", - "action.playLater": "Jouer plus tard", - "action.startRadio": "Commencer la radio", - "action.goToArtist": "Aller à l'artiste", - "action.goToAlbum": "Aller à l'album", - "action.moveToTop": "DÊplacer vers le haut", - "action.share": "Partager", - "action.rename": "Renommer", - "action.love": "J'adore", - "action.unlove": "Je n'adore plus", - "action.dislike": "Moins de suggestions similaires", - "action.undoDislike": "Annuler le choix Moins de suggestions de ce type", - "action.showWebRemoteQR": "Demontrer la Web Remote QR", - "action.playTracksNext": "Joue ${app.selectedMediaItems.length} chansons en prochain", - "action.playTracksLater": "Joue ${app.selectedMediaItems.length} chansons plus tard", - "action.removeTracks": "Remove ${self.selectedItems.length} tracks from queue", - "action.import": "Importer", - "action.export": "Exporter", - - // Settings - General - "settings.header.general": "RÊglages gÊnÊraux", - "settings.header.general.description": "RÊglez les rÊglages gÊnÊraux de Cider.", - "settings.option.general.language": "Langue", - - // Language optgroups - "settings.option.general.language.main": "Langue", - "settings.option.general.language.fun": "Langues amusantes", - "settings.option.general.language.unsorted": "Non triÊ", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "RÊglez les rÊglages audio de Cider.", - "settings.option.audio.quality": "QualitÊ audio", // Dropdown - "settings.header.audio.quality.high": "Haut", - "settings.header.audio.quality.low": "Bas", - "settings.header.audio.quality.auto": "Auto", - "settings.option.audio.seamlessTransition": "Transition audio fluide", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Activer la fonctionnalitÊ avancÊe", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "L'activation de la fonctionnalitÊ AudioContext permettra des fonctionnalitÊs audio Êtendues telles que la normalisation audio, les Êgaliseurs et les visualiseurs, mais sur certains systèmes, cela peut provoquer des saccades dans les chansons audio.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalisation audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalise le volume maximal des pistes individuelles pour crÊer une expÊrience d'Êcoute plus uniforme.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Audio Spatialization", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spatialisez l'audio et rendez l'audio plus tridimensionnel (remarque: il ne s'agit pas de Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visuel", - "settings.header.visual.description": "Ajustez les rÊglages visuels de Cider.", - "settings.option.visual.windowBackgroundStyle": "Style d'arrière-plan de la window", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Rien", - "settings.header.visual.windowBackgroundStyle.artwork": "Ouvrages d'art", - "settings.header.visual.windowBackgroundStyle.image": "Image", - "settings.option.visual.animatedArtwork": "Oeuvre animÊe", // Dropdown - "settings.header.visual.animatedArtwork.always": "Toujours", - "settings.header.visual.animatedArtwork.limited": "LimitÊ aux pages et aux entrÊes spÊciales", - "settings.header.visual.animatedArtwork.disable": "DÊsactiver partout", - "settings.option.visual.animatedArtworkQuality": "QualitÊ des illustrations animÊes", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Bas", - "settings.header.visual.animatedArtworkQuality.medium": "Moyen", - "settings.header.visual.animatedArtworkQuality.high": "Haut", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Très haut", - "settings.header.visual.animatedArtworkQuality.extreme": "ExtrÃĒme", - "settings.option.visual.animatedWindowBackground": "Fond de window animÊ", // Toggle - "settings.option.visual.hardwareAcceleration": "AccÊlÊration matÊrielle", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "NÊcessite une relance", - "settings.header.visual.hardwareAcceleration.default": "DÊfaut", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Afficher les informations personnelles", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "Paroles", - "settings.header.lyrics.description": "Ajustez les rÊglages des paroles de Cider.", - "settings.option.lyrics.enableMusixmatch": "Activer les paroles de Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Activer le mode karaokÊ (Musixmatch uniquement)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Traduction Musixmatch langue prÊfÊrÊe", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Activer les paroles Youtube pour les clips vidÊo", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "ConnectivitÊ", - "settings.header.connectivity.description": "Ajustez les rÊglages de connectivitÊ pour Cider.", - "settings.option.connectivity.discordRPC": "Discord Riche PrÊsence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Notifications de lecture", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Afficher comme 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Afficher comme 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Effacer la Discord Riche PrÊsence en pause", // Toggle - "settings.option.connectivity.lastfmScrobble": "Scrobbling LastFM", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "DÊlai de scrobble LastFM (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Activer LastFM en jouer maitenant", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Supprimer les artistes en vedette du titre de la chanson (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrer la chanson en boucle (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "ExpÊrimental", - "settings.header.experimental.description": "Ajustez les rÊglages expÊrimentaux pour Cider.", - "settings.option.experimental.compactUI": "UI Compact", // Toggle - "settings.option.experimental.closeButtonBehaviour": "Comportement du bouton de fermeture", - "settings.option.experimental.closeButtonBehaviour.quit": "Quitter Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "RÊduire à la barre des tÃĸches", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "RÊduire dans le bac", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.spatialProperties" : "PropriÊtÊs spatiales", - "spatial.width" : "Largeur", - "spatial.height" : "Hauteur", - "spatial.depth" : "Profondeur", - "spatial.gain" : "Gagner", - "spatial.roomMaterials" : "MatÊriaux de la chambre", - "spatial.roomDimensions" : "Dimensions de la chambre", - "spatial.roomPositions" : "Positions de la chambre", - "spatial.setDimensions" : "DÊfinir les cotes", - "spatial.setPositions" : "DÊfinir les positions", - "spatial.up" : "Haut", - "spatial.front" : "Avant", - "spatial.left" : "Gauche", - "spatial.right" : "Droite", - "spatial.back" : "Arrière", - "spatial.down" : "Bas", - "spatial.listener" : "Auditeur", - "spatial.audioSource" : "Source audio", - - // Settings - Unfinished - "settings.header.unfinished": "InachevÊe", - - // Web Remote - "remote.web.title": "Cider Remote", - "remote.web.description": "Scannez le code QR pour coupler votre tÊlÊphone avec cette instance Cider", - - // About - "about.thanks": "Un grand merci à l'Êquipe de Cider Collective et à tous nos contributeurs." -} \ No newline at end of file diff --git a/src/i18n/fr_FR.jsonc b/src/i18n/fr_FR.jsonc deleted file mode 100644 index 83ecc9e2..00000000 --- a/src/i18n/fr_FR.jsonc +++ /dev/null @@ -1,300 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "Français", // name of language in native language - "i18n.languageNameEnglish": "French", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@ErwanGit", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${d} ${m} ${y}", - - // Dialogs - "dialog.cancel": "Annuler", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "Mise à jour des chansons de la bibliothèque...", - "notification.updatingLibraryAlbums": "Mise à jour des albums de la bibliothèque...", - "notification.updatingLibraryArtists": "Mise à jour des artistes de la bibliothèque...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "En savoir plus", - "term.accountSettings": "Paramètres du compte", - "term.logout": "DÊconnexion", - "term.login": "Connexion", - "term.about": "À propos", - "term.privateSession": "Session privÊe", - "term.queue": "File d'attente", - "term.search": "Recherche", - "term.library": "Bibliothèque", - "term.listenNow": "Écoutez maintenant", - "term.browse": "Explorer", - "term.radio": "Radio", - "term.recentlyAdded": "AjoutÊ rÊcemment", - "term.songs": "Musiques", - "term.albums": "Albums", - "term.artists": "Artistes", - "term.podcasts": "Podcasts", - "term.playlists": "Playlists", - "term.playlist": "Playlist", - "term.play": "Lecture", - "term.pause": "Pause", - "term.previous": "PrÊcÊdent", - "term.next": "Suivant", - "term.shuffle": "AlÊatoire", - "term.repeat": "RÊpÊter", - "term.volume": "Volume", - "term.mute": "Rendre muet", - "term.unmute": "Ne plus rendre muet", - "term.share": "Partager", - "term.settings": "Paramètres", - "term.seeAll": "Voir tout", - "term.sortBy": "Trier par", - "term.sortBy.album": "Album", - "term.sortBy.artist": "Artiste", - "term.sortBy.name": "Nom", - "term.sortBy.genre": "Genre", - "term.sortBy.releaseDate": "Date de sortie", - "term.sortBy.duration": "DurÊe", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Ascendant", - "term.sortOrder.descending": "Descendant", - "term.viewAs": "Voir comme", - "term.viewAs.coverArt": "Pochette d'album", - "term.viewAs.list": "Liste", - "term.size": "Taille", - "term.size.normal": "Normal", - "term.size.compact": "Compacte", - "term.enable": "Activer", - "term.disable": "DÊsactiver", - "term.enabled": "ActivÊ", - "term.disabled": "DÊsactivÊ", - "term.connect": "Connecter", - "term.connecting": "Connexion", - "term.disconnect": "DÊconnexion", - "term.authed": "AuthentifiÊ", - "term.confirm": "Confirmer ?", - "term.more": "Plus", - "term.less": "Moins", - "term.showMore": "Afficher plus", - "term.showLess": "Afficher moins", - "term.topSongs" : "Meilleurs titres", - "term.latestReleases": "Dernières sorties", - "term.time.added": "AjoutÊ", - "term.time.released": "PubliÊ", - "term.time.updated": "Mis à jour", - "term.time.hours": "heures", - "term.time.hour": "heure", - "term.time.minutes": "minutes", - "term.time.minute": "minute", - "term.time.seconds": "secondes", - "term.time.second": "seconde", - "term.fullscreenView": "Vue plein Êcran", - "term.defaultView": "Vue par dÊfaut", - "term.spacializedAudioSetting": "Paramètres audio spatialisÊs", - "term.clearAll": "Tout effacer", - "term.recentStations": "Stations rÊcentes", - "term.language": "Langue", - "term.funLanguages": "Amusant", - "term.noLyrics": "Chargement... / Paroles non trouvÊ./ Instrumental.", - "term.copyright": "Copyright", - "term.rightsReserved": "Tous droits rÊservÊs.", - "term.sponsor": "Soutenez ce projet", - "term.ciderTeam": "Équipe Cider", - "term.developer": "DÊveloppeur", - "term.socialTeam": "Équipe de communication", - "term.contributors": "Contributeurs", - "term.equalizer": "Égaliseur", - "term.reset": "RÊinitialiser", - "term.tracks": "musiques", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "VidÊos", - "term.menu": "Menu", - "action.showAlbum": "Afficher l'album complet", - - // Home - "home.title": "Accueil", - "home.recentlyPlayed": "JouÊ rÊcemment", - "home.recentlyAdded": "RÊcemment ajoutÊ", - "home.artistsFeed": "Votre file d'artistes", - "home.artistsFeed.noArtist": "Suivez d'abord certains artistes et leurs dernières sorties seront ici", - "home.madeForYou": "Fait pour vous", - "home.friendsListeningTo": "Vos amis Êcoutent", - "home.followedArtists": "Artistes suivis", - // Errors - "error.appleMusicSubRequired": "Apple Music nÊcessite un abonnement.", - "error.connectionError": "Il y a eu un problème de connexion à Apple Music.", - "error.noResults": "Aucun rÊsultat.", - "error.noResults.description": "Essayez une nouvelle recherche.", - - //Podcasts - "podcast.followOnCider": "Suivre sur Cider", - "podcast.followedOnCider": "Suivi sur Cider", - "podcast.subscribeOnItunes": "Suivre sur iTunes", - "podcast.subscribedOnItunes": "Suivi sur iTunes", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "Épisodes", - "podcast.playEpisode": "Lire l'Êpisode", - "podcast.website": "Site du podcast", - - // Actions - "action.addToLibrary": "Ajouter à la bibliothèque", - "action.addToLibrary.success": "AjoutÊ à la bibliothèque", - "action.addToLibrary.error": "Erreur lors de l'ajout à la bibliothèque", - "action.removeFromLibrary": "Retirer de la bibliothèque", - "action.removeFromLibrary.success": "RetirÊ de la bibliothèque", - "action.addToQueue": "Ajouter à la file d'attente", - "action.addToQueue.success": "AjoutÊ à la file d'attente", - "action.addToQueue.error": "Erreur lors de l'ajout à la file d'attente", - "action.removeFromQueue": "Retirer de la file d'attente", - "action.removeFromQueue.success": "RetirÊ de la file d'attente", - "action.removeFromQueue.error": "Erreur lors du retrait de la file d'attente", - "action.addToPlaylist": "Ajouter à une playlist", - "action.removeFromPlaylist": "Retirer de la playlist", - "action.addToFavorites": "Ajouter aux favoris", - "action.follow": "Suivre", - "action.follow.success": "Suivi", - "action.follow.error": "Erreur lors de l'abonnement", - "action.unfollow": "Se dÊsabonner", - "action.unfollow.success": "DÊsabonnÊ", - "action.unfollow.error": "Erreur lors du dÊsabonnement", - "action.playNext": "Jouer après", - "action.playLater": "Jouer plus tard", - "action.startRadio": "Lancer la radio", - "action.goToArtist": "Aller à l'artiste", - "action.goToAlbum": "Aller à l'album", - "action.moveToTop": "Haut de page", - "action.share": "Partager", - "action.rename": "Renommer", - "action.love": "Aimer", - "action.unlove": "Ne plus aimer", - "action.dislike": "Je n'aime pas", - "action.undoDislike": "Je n'aime plus", - "action.showWebRemoteQR": "Afficher le QR Code de la tÊlÊcommande à distance", - "action.playTracksNext": "Jouer ${app.selectedMediaItems.length} musiques après", - "action.playTracksLater": "Jouer ${app.selectedMediaItems.length} musiques plus tard", - "action.removeTracks": "Retirer ${self.selectedItems.length} musiques de la file d'attente", - "action.import": "Importer", - "action.export": "Exporter", - - // Settings - General - "settings.header.general": "GÊnÊral", - "settings.header.general.description": "Ajuster les paramètres gÊnÊraux de Cider.", - "settings.option.general.language": "Langue", - - // Language optgroups - "settings.option.general.language.main": "Langues", - "settings.option.general.language.fun": "Langues amusantes", - "settings.option.general.language.unsorted": "Non triÊ", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Ajuster les paramètres audio de Cider.", - "settings.option.audio.quality": "QualitÊ Audio", // Dropdown - "settings.header.audio.quality.high": "ÉlevÊe", - "settings.header.audio.quality.low": "Faible", - "settings.header.audio.quality.auto": "Automatique", - "settings.option.audio.seamlessTransition": "Fondu audio transparent", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Activer les fonctions avancÊes", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "L'activation de la fonctionnalitÊ AudioContext permet d'utiliser des fonctions audio Êtendues telles que la normalisation du son, les Êgaliseurs et les visualiseurs. Toutefois, sur certains systèmes, cela peut provoquer des bÊgaiements dans les pistes audio.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalisation du son", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalise le volume maximal des pistes individuelles pour crÊer une expÊrience d'Êcoute plus uniforme.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spatialisation audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spatialiser l'audio et rendre l'audio plus tridimensionnel (note: Ce n'est pas Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visuel", - "settings.header.visual.description": "Ajuster les paramètres visuels de Cider.", - "settings.option.visual.windowBackgroundStyle": "Style d'arrière-plan de la fenÃĒtre", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Aucun", - "settings.header.visual.windowBackgroundStyle.artwork": "Pochette d'album", - "settings.header.visual.windowBackgroundStyle.image": "Image", - "settings.option.visual.animatedArtwork": "Pochette d'album animÊe", // Dropdown - "settings.header.visual.animatedArtwork.always": "Toujours", - "settings.header.visual.animatedArtwork.limited": "LimitÊ aux pages et aux entrÊes spÊciales", - "settings.header.visual.animatedArtwork.disable": "DÊsactiver partout", - "settings.option.visual.animatedArtworkQuality": "QualitÊ de la pochette d'album animÊe", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Faible", - "settings.header.visual.animatedArtworkQuality.medium": "Moyen", - "settings.header.visual.animatedArtworkQuality.high": "ÉlevÊe", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Très ÊlevÊe", - "settings.header.visual.animatedArtworkQuality.extreme": "ExtrÃĒme", - "settings.option.visual.animatedWindowBackground": "Arrière-plan de fenÃĒtre animÊ", // Toggle - "settings.option.visual.hardwareAcceleration": "AccÊlÊration matÊrielle", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "NÊcessite un relancement", - "settings.header.visual.hardwareAcceleration.default": "DÊfaut", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Afficher vos informations personnelles", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "Paroles", - "settings.header.lyrics.description": "Ajuster les paramètres des paroles pour Cider.", - "settings.option.lyrics.enableMusixmatch": "Activer les paroles Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Activer le mode karaokÊ (Musixmatch seulement)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Langue prÊfÊrÊe pour les traductions Musixmatch", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Activer les paroles YouTube pour les vidÊos de musique", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "ConnectivitÊ", - "settings.header.connectivity.description": "Ajuster les paramètres de connectivitÊ de Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Notifications de lecture", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Afficher comme 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Afficher comme 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "DÊsactiver le Discord Rich Presence quand la musique est en pause", // Toggle - "settings.option.connectivity.lastfmScrobble": "Scrobble LastFM", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "DÊlai de Scrobble LastFM (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Activer la lecture en cours sur LastFM", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Supprimer les artistes en vedette du titre de la chanson (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrer les titres en boucle (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "ExpÊrimental", - "settings.header.experimental.description": "Ajuster les paramètres expÊrimentaux de Cider.", - "settings.option.experimental.compactUI": "Interface utilisateur compacte", // Toggle - "settings.option.experimental.closeButtonBehaviour": "Comportement du bouton de fermeture", - "settings.option.experimental.closeButtonBehaviour.quit": "Quitter Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "RÊduire dans la barre des tÃĸches", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "RÊduire dans la barre d'outils", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.spatialProperties": "PropriÊtÊs spatiales", - "spatial.width": "Largeur", - "spatial.height": "Hauteur", - "spatial.depth": "Profondeur", - "spatial.gain": "Gain", - "spatial.roomMaterials": "MatÊriaux de la pièce", - "spatial.roomDimensions": "Dimensions de la pièce", - "spatial.roomPositions": "Positions de la pièce", - "spatial.setDimensions": "DÊfinir les dimensions", - "spatial.setPositions": "DÊfinir les positions", - "spatial.up": "Haut", - "spatial.front": "Avant", - "spatial.left": "Gauche", - "spatial.right": "Droite", - "spatial.back": "Retour", - "spatial.down": "Bas", - "spatial.listener": "Auditeur", - "spatial.audioSource": "Source Audio", - - // Settings - Unfinished - "settings.header.unfinished": "InachevÊe", - - // Web Remote - "remote.web.title": "Cider Remote", - "remote.web.description": "Scanner le QR code pour associer votre tÊlÊphone avec cette instance Cider", - - // About - "about.thanks": "Un grand merci à l'Êquipe de la Cider Collective et à tous nos contributeurs." - } - \ No newline at end of file diff --git a/src/i18n/hu_HU.jsonc b/src/i18n/hu_HU.jsonc deleted file mode 100644 index 1fc03018..00000000 --- a/src/i18n/hu_HU.jsonc +++ /dev/null @@ -1,311 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "Magyar", // name of language in native language - "i18n.languageNameEnglish": "Hungarian", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@Greenoliv @Rias @BenjaminStonawski", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${m} ${d}, ${y}", - - // Dialogs - "dialog.cancel": "MÊgsem", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "ZenekÃļnyvtÃĄr frissítÊse...", - "notification.updatingLibraryAlbums": "Albumok frissítÊse...", - "notification.updatingLibraryArtists": "ElőadÃŗk frissítÊse...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Tudj meg tÃļbbet", - "term.accountSettings": "FiÃŗkbeÃĄllítÃĄsok", - "term.logout": "KijelentkezÊs", - "term.login": "BejelentkezÊs", - "term.about": "NÊvjegy", - "term.privateSession": "PrivÃĄt hallgatÃĄs", - "term.queue": "VÃĄrÃŗlista", - "term.search": "KeresÊs", - "term.library": "KÃļnyvtÃĄr", - "term.listenNow": "HallgatÃĄs most", - "term.browse": "BÃļngÊszÊs", - "term.radio": "RÃĄdiÃŗ", - "term.recentlyAdded": "NemrÊg hozzÃĄadott", - "term.songs": "Dalok", - "term.albums": "Albumok", - "term.artists": "ElőadÃŗk", - "term.podcasts": "Podcastok", - "term.playlists": "LejÃĄtszÃĄsi listÃĄk", - "term.playlist": "LejÃĄtszÃĄsi lista", - "term.newPlaylist": "Új lejÃĄtszÃĄsi lista", - "term.newPlaylistFolder": "Új lejÃĄtszÃĄsi lista mappa", - "term.createNewPlaylist": "Új lejÃĄtszÃĄsi lista lÊtrehozÃĄsa", - "term.createNewPlaylistFolder": "Új lejÃĄtszÃĄsi lista mappa lÊtrehozÃĄsa", - "term.deletePlaylist": "Biztosan szeretnÊ tÃļrÃļlni a lejÃĄtszÃĄsi listÃĄt?", - "term.play": "LejÃĄtszÃĄs", - "term.pause": "MegÃĄllítÃĄs", - "term.previous": "Előző", - "term.next": "KÃļvetkező", - "term.shuffle": "KeverÊs", - "term.repeat": "IsmÊtlÊs", - "term.volume": "Hangerő", - "term.mute": "NÊmítÃĄs", - "term.unmute": "NÊmítÃĄs feloldÃĄsa", - "term.share": "MegosztÃĄs", - "term.settings": "BeÃĄllítÃĄsok", - "term.seeAll": "Összes", - "term.sortBy": "RendezÊs", - "term.sortBy.album": "Album", - "term.sortBy.artist": "ElőadÃŗ", - "term.sortBy.name": "NÊv", - "term.sortBy.genre": "MÅąfaj", - "term.sortBy.releaseDate": "KiadÃĄs dÃĄtuma", - "term.sortBy.duration": "Időtartam", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "NÃļvekvő", - "term.sortOrder.descending": "CsÃļkkenő", - "term.viewAs": "MegjelenítÊs", - "term.viewAs.coverArt": "BorítÃŗ", - "term.viewAs.list": "Lista", - "term.size": "MÊret", - "term.size.normal": "NormÃĄl", - "term.size.compact": "Kompakt", - "term.enable": "Be", - "term.disable": "Ki", - "term.enabled": "Be", - "term.disabled": "Ki", - "term.connect": "CsatlakoztatÃĄs", - "term.connecting": "CsatlakozÃĄs", - "term.disconnect": "LecsatlakozatÃĄs", - "term.authed": "Hitelesítve", - "term.confirm": "JÃŗvÃĄhagyja?", - "term.more": "TÃļbb", - "term.less": "Kevesebb", - "term.showMore": "Mutass tÃļbbet", - "term.showLess": "Mutass kevesebbet", - "term.topSongs" : "A legjobb dalok", - "term.latestReleases": "Új megjelenÊsek", - "term.time.added": "HozzÃĄadva", - "term.time.released": "Kiadva:", - "term.time.updated": "Frissítve", - "term.time.hours": "Ãŗra", - "term.time.hour": "Ãŗra", - "term.time.minutes": "perc", - "term.time.minute": "perc", - "term.time.seconds": "mÃĄsodperc", - "term.time.second": "mÃĄsodperc", - "term.fullscreenView": "Teljes kÊpernyős mÃŗd", - "term.defaultView": "AlapÊrtelmezett nÊzet", - "term.spacializedAudioSetting": "TÊrbeli hangzÃĄs", - "term.clearAll": "Összes tÃļrlÊse", - "term.recentStations": "NemrÊg jÃĄtszott", - "term.language": "Nyelv", - "term.funLanguages": "MÃŗkÃĄs", - "term.noLyrics": "DalszÃļveg nem talÃĄlhatÃŗ", - "term.copyright": "Szerzői jog", - "term.rightsReserved": "Minden jog fenntartva.", - "term.sponsor": "TÃĄmogasd a projektet", - "term.ciderTeam": "A Cider csapata", - "term.developer": "Fejlesztő", - "term.socialTeam": "SzociÃĄlis csapat", - "term.socials": "SzociÃĄlis", - "term.contributors": "KÃļzremÅąkÃļdők", - "term.equalizer": "HangszínszabÃĄlyzÃŗ", - "term.reset": "VisszaÃĄllítÃĄs", - "term.tracks": "zeneszÃĄm", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "VideÃŗk", - "term.menu": "MenÃŧ", - "term.check": "EllenőrzÊs", - "term.aboutArtist": "TovÃĄbbi informÃĄciÃŗ {{artistName}} előadÃŗrÃŗl", // e.g. 'About Doja Cat' - "term.updateCider": "Cider frissítÊse", - - // Home - "home.title": "Kezdőlap", - "home.recentlyPlayed": "NemrÊg jÃĄtszott", - "home.recentlyAdded": "NemrÊg hozzÃĄadott", - "home.artistsFeed": "Az előadÃŗid feedje", - "home.artistsFeed.noArtist": "KÃļvess nÊhÃĄny előadÃŗt, hogy a legÃējabb zenÊi itt megjelenhessenek.", - "home.madeForYou": "SzemÊlyre szabva", - "home.friendsListeningTo": "A barÃĄtaid Êpp ezt hallgatjÃĄk", - "home.followedArtists": "KÃļvetett előadÃŗk", - // Errors - "error.appleMusicSubRequired": "Apple Music előfizetÊs szÃŧksÊges.", - "error.connectionError": "Hiba tÃļrtÊnt az Apple Music-hoz valÃŗ csatlakozÃĄs kÃļzben.", - "error.noResults": "Nincs talÃĄlat", - "error.noResults.description": "PrÃŗbÃĄlkozzon Ãēj keresÊssel", - - //Podcasts - "podcast.followOnCider": "KÃļvetÊs a Cideren", - "podcast.followedOnCider": "KÃļvetve a Cideren", - "podcast.subscribeOnItunes": "FeliratkozÃĄs az iTunes-ban", - "podcast.subscribedOnItunes": "Feliratkozva az iTunes-ban", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "EpizÃŗdok", - "podcast.playEpisode": "EpizÃŗd lejÃĄtszÃĄsa", - "podcast.website": "Podcast weboldala", - - // Actions - "action.addToLibrary": "HozzÃĄadÃĄs a kÃļnyvtÃĄrhoz", - "action.addToLibrary.success": "HozzÃĄadva a kÃļnyvtÃĄrhoz", - "action.addToLibrary.error": "Hiba a hozzÃĄadÃĄskor.", - "action.removeFromLibrary": "TÃļrlÊs a KÃļnytÃĄrbÃŗl", - "action.removeFromLibrary.success": "TÃļrÃļlve a kÃļnyvtÃĄrbÃŗl", - "action.addToQueue": "HozzÃĄadÃĄs a vÃĄrÃŗlistÃĄhoz", - "action.addToQueue.success": "HozzÃĄadva a vÃĄrÃŗlistÃĄhoz", - "action.addToQueue.error": "Sikertelen hozzÃĄadÃĄs a vÃĄrÃŗlistÃĄhoz", - "action.removeFromQueue": "TÃļrlÊs a vÃĄrÃŗlistÃĄrÃŗl", - "action.removeFromQueue.success": "TÃļrÃļlve a vÃĄrÃŗlistÃĄrÃŗl", - "action.removeFromQueue.error": "Sikertelen tÃļrlÊs a vÃĄrÃŗlistÃĄrÃŗl", - "action.createPlaylist": "Új lejÃĄtszÃĄsi lista lÊtrehozÃĄsa", - "action.addToPlaylist": "LejÃĄtszÃĄsi listÃĄhoz adÃĄs", - "action.removeFromPlaylist": "TÃļrlÊs a lejÃĄtszÃĄsi listÃĄrÃŗl", - "action.addToFavorites": "HozzÃĄadÃĄs a kedvencekhez", - "action.follow": "KÃļvetÊs", - "action.follow.success": "KÃļvetve", - "action.follow.error": "Sikertelen kÃļvetÊs", - "action.unfollow": "KÃļvetÊs visszavonÃĄsa", - "action.unfollow.success": "KÃļvetÊs visszavonva", - "action.unfollow.error": "Sikertelen visszavonÃĄs", - "action.playNext": "LejÃĄtszÃĄs kÃļvetkezőkÊnt", - "action.playLater": "LejÃĄtszÃĄs utolsÃŗkÊnt", - "action.startRadio": "ÁllomÃĄs lÊtrehozÃĄsa", - "action.goToArtist": "ElőadÃŗ megjelenítÊse", - "action.goToAlbum": "Album megjelenítÊse", - "action.moveToTop": "MozgatÃĄs legfelÃŧlre", - "action.share": "MegosztÃĄs", - "action.rename": "ÁtnevezÊs", - "action.love": "Kedvelem", - "action.unlove": "KedvelÊs visszavonÃĄsa", - "action.dislike": "Nem kedvelem", - "action.undoDislike": "Nem kedvelÊs visszavonÃĄsa", - "action.showWebRemoteQR": "TÃĄvirÃĄnyítÃŗ QR kÃŗd megjelenítÊse", - "action.playTracksNext": "${app.selectedMediaItems.length} zenÊk lejÃĄtszÃĄsa kÃļvetkezőnek", - "action.playTracksLater": "${app.selectedMediaItems.length} zenÊk lejÃĄtszÃĄsa kÊsőbb", - "action.removeTracks": "${self.selectedItems.length} zenÊk eltÃĄvolítÃĄsa a vÃĄrÃŗlistÃĄrÃŗl", - "action.import": "ImportÃĄlÃĄs", - "action.export": "ExportÃĄlÃĄs", - "action.showAlbum": "Teljes album megjelenítÊse", - // Waiting on Core for moving plugin to app.ts - "action.tray.minimize": "KicsinyítÊs a tÃĄlcÃĄra", - "action.tray.quit": "KilÊpÊs", - "action.tray.show": "A kÃļvetkező megjelenítÊse:", - - // Settings - General - "settings.header.general": "ÁltalÃĄnos", - "settings.header.general.description": "A Cider ÃĄltalÃĄnos beÃĄllítÃĄsainak mÃŗdosítÃĄsa", - "settings.option.general.language": "Nyelv", - - // Language optgroups - "settings.option.general.language.main": "Nyelvek", - "settings.option.general.language.fun": "MÃŗkÃĄs nyelvek", - "settings.option.general.language.unsorted": "Nem besorolhatÃŗ", - - // Settings - Audio - "settings.header.audio": "Hang", - "settings.header.audio.description": "A Cider hangbeÃĄllítÃĄsainak mÃŗdosítÃĄsa", - "settings.option.audio.quality": "HangminősÊg", // Dropdown - "settings.header.audio.quality.high": "Magas", - "settings.header.audio.quality.low": "Alacsony", - "settings.header.audio.quality.auto": "Automatikus", - "settings.option.audio.seamlessTransition": "SzÃŧnetmentes lejÃĄtszÃĄs", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "HaladÃŗ funkcionalitÃĄs engedÊlyezÊse", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Az AudioContext funkciÃŗ engedÊlyezÊse lehetővÊ teszi a fejlettebb hangfunkciÃŗkat, pÊldÃĄul a normalizÃĄsÃĄst, a hangszínszabÃĄlyzÃŗt Ês a vizualizÃĄciÃŗ funkciÃŗkat, azonban egyes szÃĄmítÃŗgÊpeken ez akadozÃĄst okozhat a hangsÃĄvokban.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "NormalizÃĄlÃĄs", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "NormalizÃĄlja az egyes zeneszÃĄmok hangosabb rÊszeit, hogy egysÊgesebb hallgatÃĄsi ÊlmÊnyt hozzon lÊtre.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "TÊrbeli hangzÃĄs", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "TÊrbeli hangzÃĄs Ês a hang hÃĄromdimenziÃŗsabbÃĄ tÊtele (Ez nem Ãļsszekeverendő a Dolby Atmos-szal!)", - // Settings - Visual - "settings.header.visual": "VizuÃĄlis", - "settings.header.visual.description": "A Cider vizuÃĄlis beÃĄllítÃĄsainak mÃŗdosítÃĄsa.", - "settings.option.visual.windowBackgroundStyle": "Ablak hÃĄttÊr stílusa", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Egyik sem", - "settings.header.visual.windowBackgroundStyle.artwork": "BorítÃŗ", - "settings.header.visual.windowBackgroundStyle.image": "KÊp", - "settings.option.visual.animatedArtwork": "AnimÃĄlt borítÃŗ", // Dropdown - "settings.header.visual.animatedArtwork.always": "Mindig", - "settings.header.visual.animatedArtwork.limited": "Oldalakra Ês speciÃĄlis bejegyzÊsekre korlÃĄtozva", - "settings.header.visual.animatedArtwork.disable": "KikapcsolÃĄs mindenhol", - "settings.option.visual.animatedArtworkQuality": "AnimÃĄlt borítÃŗ minősÊge", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Alacsony", - "settings.header.visual.animatedArtworkQuality.medium": "KÃļzepes", - "settings.header.visual.animatedArtworkQuality.high": "Magas", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Nagyon magas", - "settings.header.visual.animatedArtworkQuality.extreme": "ExtrÊm", - "settings.option.visual.animatedWindowBackground": "AnimÃĄlt ablakhÃĄttÊr", // Toggle - "settings.option.visual.hardwareAcceleration": "Hardveres gyorsítÃĄs", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "ÚjraindítÃĄs szÃŧksÊges", - "settings.header.visual.hardwareAcceleration.default": "Alap", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "SzemÊlyes adatok mutatÃĄsa", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "DalszÃļveg", - "settings.header.lyrics.description": "A Cider dalszÃļveg beÃĄllítÃĄsainak mÃŗdosítÃĄsa.", - "settings.option.lyrics.enableMusixmatch": "MusixMatch dalszÃļvegek engedÊlyezÊse", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Karaoke mÃŗd bekapcsolÃĄsa (Csak MusixMatch esetÊn)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "MusixMatch fordítÃĄs nyelve", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "YouTube dalszÃļvegek engedÊlyezÊse a zenei videÃŗknÃĄl", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "CsatlakozhatÃŗsÃĄgok", - "settings.header.connectivity.description": "A Cider csatlakozÃĄs beÃĄllítÃĄsainak mÃŗdosítÃĄsa.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "ÉrtesítÊs Ãēj dal lejÃĄtszÃĄsakor", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "MegjelenítÊs 'Cider'-kÊnt", - "settings.header.connectivity.discordRPC.appleMusic": "MegjelenítÊs 'Apple Music'-kÊnt", - "settings.option.connectivity.discordRPC.clearOnPause": "Discord Rich Presence tÃļrlÊse megÃĄllítÃĄsnÃĄl", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble KÊsleltetÊs (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "LastFM Now Playing engedÊlyezÊse", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "A kÃļzremÅąkÃļdő előadÃŗk eltÃĄvolítÃĄsa a dal címÊből (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Loopolt zeneszÃĄm szÅąrÊse (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "KísÊrleti", - "settings.header.experimental.description": "A Cider kísÊrleti beÃĄllítÃĄsainak mÃŗdosítÃĄsa.", - "settings.option.experimental.compactUI": "Kompakt UI", // Toggle - "settings.option.experimental.close_button_hide": "A bezÃĄrÃĄs gomb rejtse el az alkalmazÃĄst", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "A tÊrbeli hangzÃĄs ki van kapcsolva, hasznÃĄlatÃĄhoz kapcsolja be.", - "spatial.spatialProperties": "TÊrbeli hangzÃĄs", - "spatial.width": "SzÊlessÊg", - "spatial.height": "MagassÃĄg", - "spatial.depth": "HosszÃēsÃĄg", - "spatial.gain": "Gain", - "spatial.roomMaterials": "Szoba felÊpítÊse", - "spatial.roomDimensions": "Szoba mÊretei", - "spatial.roomPositions": "Szoba pozíciÃŗi", - "spatial.setDimensions": "MÊretek beÃĄllítÃĄsa", - "spatial.setPositions": "PozíciÃŗk beÃĄllítÃĄsa", - "spatial.up": "Fent", - "spatial.front": "Elől", - "spatial.left": "Balra", - "spatial.right": "Jobbra", - "spatial.back": "HÃĄtul", - "spatial.down": "Lent", - "spatial.listener": "HallgatÃŗ", - "spatial.audioSource": "HangforrÃĄs", - - // Settings - Unfinished - "settings.header.unfinished": "Befejezetlen", - - // Web Remote - "remote.web.title": "Cider Remote", - "remote.web.description": "Olvasd be ezt a QR-kÃŗdot a telefonoddal, hogy vezÊrelhesd a lejÃĄtszÃŗt.", - - // About - "about.thanks": "KÃļszÃļnet a Cider Collective csapatÃĄnak Ês minden kÃļzremÅąkÃļdőnek." -} diff --git a/src/i18n/it_IT.jsonc b/src/i18n/it_IT.jsonc deleted file mode 100644 index 5c3589f0..00000000 --- a/src/i18n/it_IT.jsonc +++ /dev/null @@ -1,312 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "Italiano", // name of language in native language - "i18n.languageNameEnglish": "Italian", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "ConnectedR", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${d} ${m}, ${y}", - - // Dialogs - "dialog.cancel": "Annulla", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "Aggiornamento raccolta brani...", - "notification.updatingLibraryAlbums": "Aggornamento raccolta album...", - "notification.updatingLibraryArtists": "Aggiornamento raccolta artisti...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Impara di piÚ", - "term.accountSettings": "Impostazioni Account", - "term.logout": "Disconnetti", - "term.login": "Accedi", - "term.about": "Informazioni", - "term.privateSession": "Sessione Privata", - "term.queue": "Coda", - "term.search": "Cerca", - "term.library": "Raccolta", - "term.listenNow": "Ascolta ora", - "term.browse": "Sfoglia", - "term.radio": "Radio", - "term.recentlyAdded": "Aggiunto di recente", - "term.songs": "Brani", - "term.albums": "Album", - "term.artists": "Artisti", - "term.podcasts": "Podcast", - "term.playlists": "Playlist", - "term.playlist": "Playlist", - "term.newPlaylist": "Nuova Playlist", - "term.newPlaylistFolder": "Nuova Cartella Playlist", - "term.createNewPlaylist": "Crea Nuova Playlist", - "term.createNewPlaylistFolder": "Crea Nuova Cartella Playlist", - "term.deletePlaylist": "Sei sicuro che vuoi eliminare questa playlist?", - "term.play": "Riproduci", - "term.pause": "Pausa", - "term.previous": "Precedente", - "term.next": "Avanti", - "term.shuffle": "Shuffle", - "term.repeat": "Ripeti", - "term.volume": "Volume", - "term.mute": "Muta", - "term.unmute": "Riattiva", - "term.share": "Condividi", - "term.settings": "Impostazioni", - "term.seeAll": "Vedi tutto", - "term.sortBy": "Ordina per", - "term.sortBy.album": "Album", - "term.sortBy.artist": "Artista", - "term.sortBy.name": "Nome", - "term.sortBy.genre": "Genere", - "term.sortBy.releaseDate": "Data di rilascio", - "term.sortBy.duration": "Durata", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Crescente", - "term.sortOrder.descending": "Decrescente", - "term.viewAs": "Visualizza come", - "term.viewAs.coverArt": "Copertina", - "term.viewAs.list": "Lista", - "term.size": "Dimensione", - "term.size.normal": "Normale", - "term.size.compact": "Compatto", - "term.enable": "Attive", - "term.disable": "Disattiva", - "term.enabled": "Attivo", - "term.disabled": "Disattivo", - "term.connect": "Connetti", - "term.connecting": "Connessione", - "term.disconnect": "Disconnetti", - "term.authed": "Connesso", - "term.confirm": "Conferma?", - "term.more": "Altro", - "term.less": "Meno", - "term.showMore": "Mostra altro", - "term.showLess": "Mostra menu", - "term.topSongs" : "Brani top", - "term.latestReleases": "Uscite Recenti", - "term.time.added": "Aggiunto", - "term.time.released": "Rilasciato", - "term.time.updated": "Aggiornato", - "term.time.hours": "ore", - "term.time.hour": "ora", - "term.time.minutes": "minuti", - "term.time.minute": "minuto", - "term.time.seconds": "secondi", - "term.time.second": "secondo", - "term.fullscreenView": "Vista schermo pieno", - "term.defaultView": "Vista normale", - "term.audioSettings": "Impostazioni Audio", - "term.clearAll": "Rimuovi Tutto", - "term.recentStations": "Stazioni recenti", - "term.language": "Lingua", - "term.funLanguages": "Scherzo", - "term.noLyrics": "Caricamento... / Testo non trovato. / Strumentale.", - "term.copyright": "Copyright", - "term.rightsReserved": "Tutti i diritti riservati.", - "term.sponsor": "Sponsorizza questo progetto", - "term.ciderTeam": "Team di Cider", - "term.developer": "Sviluppatore", - "term.socialTeam": "Team Sociale", - "term.socials": "Social", - "term.contributors": "Contribuenti", - "term.equalizer": "Equalizzatore", - "term.reset": "Reset", - "term.tracks": "brani", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Video", - "term.menu": "Menu", - "term.check": "Controllo", - - // Home - "home.title": "Casa", - "home.recentlyPlayed": "Ascoltato di recente", - "home.recentlyAdded": "Aggiunto di recente", - "home.artistsFeed": "Feed di Artisti", - "home.artistsFeed.noArtist": "Segui alcuni artisti e le loro uscite recenti appariranno qui", - "home.madeForYou": "Per Te", - "home.friendsListeningTo": "Ascoltato da Amici", - "home.followedArtists": "Artisti Seguiti", - // Errors - "error.appleMusicSubRequired": "Apple Music ha bisogno di un abbonamento.", - "error.connectionError": "C'è stato un problema nella connessione a Apple Music.", - "error.noResults": "Nessun risultato.", - "error.noResults.description": "Prova un'altra ricerca.", - - //Podcasts - "podcast.followOnCider": "Segui in Cider", - "podcast.followedOnCider": "Seguiti in Cider", - "podcast.subscribeOnItunes": "Iscriviti in iTunes", - "podcast.subscribedOnItunes": "Iscritto in iTunes", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "Episodi", - "podcast.playEpisode": "Ascolta Episodio", - "podcast.website": "Sito Podcast", - - // Actions - "action.addToLibrary": "Aggiungi a Raccolta", - "action.addToLibrary.success": "Aggiunto a Raccolta", - "action.addToLibrary.error": "Errore ad Aggiungere a Raccolta", - "action.removeFromLibrary": "Rimuovi da Raccolta", - "action.removeFromLibrary.success": "Rimosso da Raccolta", - "action.addToQueue": "Aggiungi a Coda", - "action.addToQueue.success": "Aggiunto a Coda", - "action.addToQueue.error": "Errore ad Aggiungere a Coda", - "action.removeFromQueue": "Rimuovi da Coda", - "action.removeFromQueue.success": "Rimosso da Coda", - "action.removeFromQueue.error": "Errore a Rimuovere da Coda", - "action.createPlaylist": "Crea Nuova Playlist", - "action.addToPlaylist": "Aggiungi a Playlist", - "action.removeFromPlaylist": "Rimuovi da Playlist", - "action.addToFavorites": "Aggiungi a Preferiti", - "action.follow": "Segui", - "action.follow.success": "Seguito", - "action.follow.error": "Errore a Seguire", - "action.unfollow": "Non Seguire", - "action.unfollow.success": "Rimosso dai Seguiti", - "action.unfollow.error": "Errore a Rimuovere dai Seguiti", - "action.playNext": "Riproduci Dopo", - "action.playLater": "Riprodici in Fine", - "action.startRadio": "Inizia Radio", - "action.goToArtist": "Vai all'Artista", - "action.goToAlbum": "Vai all'Album", - "action.moveToTop": "Torna in Alto", - "action.share": "Condividi", - "action.rename": "Rinomina", - "action.love": "Mi Piace", - "action.unlove": "Rimuovi Mi Piace", - "action.dislike": "Non Mi Piace", - "action.undoDislike": "Rimuovi Non Mi Piace", - "action.showWebRemoteQR": "Telecomando Web", - "action.playTracksNext": "Riproduci ${app.selectedMediaItems.length} brani Dopo", - "action.playTracksLater": "Riproduci ${app.selectedMediaItems.length} brani in fine", - "action.removeTracks": "Riproduci ${self.selectedItems.length} brani dalla coda", - "action.import": "Importa", - "action.export": "Esporta", - "action.showAlbum": "Mostra Album Intero", - // Waiting on Core for moving plugin to app.ts - "action.tray.minimize": "Minimizza nel tray", - "action.tray.quit": "Chiudi", - "action.tray.show": "Mostra", - - // Settings - General - "settings.header.general": "Generale", - "settings.header.general.description": "Cambia le impostazioni generali di Cider.", - "settings.option.general.language": "Lingua", - - // Language optgroups - "settings.option.general.language.main": "Lingue", - "settings.option.general.language.fun": "Lingue da Scherzo", - "settings.option.general.language.unsorted": "Non ordinato", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Cambia le impostazioni di audio di Cider.", - "settings.option.audio.quality": "Qualità di audio", // Dropdown - "settings.header.audio.quality.high": "Alta", - "settings.header.audio.quality.low": "Bassa", - "settings.header.audio.quality.auto": "Automatica", - "settings.option.audio.seamlessTransition": "Transizioni Audio Immediate", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Attiva funzionalità avanzata", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Attiva AudioContext per funzionalià audio avanzata Normalizzazione Audio, Equalizzatori and Visualizzatori, perÃ˛ su alcuni sistemi potrebbero causare lag nei brani.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizzazione Audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizza il volume massimo nei brani per un'esperienza d'ascolto piÚ uniforme.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spazializzazione Audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spazializza l'audio per dare un effetto piÚ tridimensionale (nota: questo non è Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visuale", - "settings.header.visual.description": "Cambia le impostazioni visuali per Cider.", - "settings.option.visual.windowBackgroundStyle": "Stile Sfondo Finestra", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Nessuno", - "settings.header.visual.windowBackgroundStyle.artwork": "Copertina", - "settings.header.visual.windowBackgroundStyle.image": "Immagine", - "settings.option.visual.animatedArtwork": "Copertina Animata", // Dropdown - "settings.header.visual.animatedArtwork.always": "Sempre", - "settings.header.visual.animatedArtwork.limited": "Limita ad alcune pagine", - "settings.header.visual.animatedArtwork.disable": "Disattiva dappertutto", - "settings.option.visual.animatedArtworkQuality": "Qualità Copertina Animata", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Bassa", - "settings.header.visual.animatedArtworkQuality.medium": "Media", - "settings.header.visual.animatedArtworkQuality.high": "Alta", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Molto Alta", - "settings.header.visual.animatedArtworkQuality.extreme": "Estrema", - "settings.option.visual.animatedWindowBackground": "Sfondo Finestra Animato", // Toggle - "settings.option.visual.hardwareAcceleration": "Accelerazione Hardware", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "Richiede riavvio del'app", - "settings.header.visual.hardwareAcceleration.default": "Normale", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Mostra Informazione Personale", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "Testi", - "settings.header.lyrics.description": "Aggiusta le impostazioni dei testi per Cider.", - "settings.option.lyrics.enableMusixmatch": "Attiva Testi Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Attiva Modalità Karaoke (solo Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Lingua di Traduzione MusixMatch Preferita", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Attiva Testi da YouTube Per i Video ", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Connectività", - "settings.header.connectivity.description": "Cambia le impostazioni di connettività per Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Notifiche di Riproduzione", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Mostra come 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Mostra come 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Pausare Disattiva la Rich Presence", // Toggle - "settings.option.connectivity.lastfmScrobble": "Scrobbling LastFM", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Ritardo di Scrobbling LastFM (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Attiva Now Playing in LastFM", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Rimouvi Artisti Extra dal Titolo del Brano (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtra Brani Ripetuti (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "Sperimentale", - "settings.header.experimental.description": "Cambia impostazioni sperimentali per Cider.", - "settings.option.experimental.compactUI": "Interfaccia Compatta", // Toggle - "settings.option.experimental.closeButtonBehaviour": "Comportamento Tasto Chiudi", - "settings.option.experimental.closeButtonBehaviour.quit": "Chiudi Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "Minimizza", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "Minimizza Nel Tray", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "Spazializzazione Audio è disattivata. Attivala prima.", - "spatial.spatialProperties" : "Proprietà Spaziali", - "spatial.width" : "Larghezza", - "spatial.height" : "Altezza", - "spatial.depth" : "Profondità", - "spatial.gain" : "Guadagno", - "spatial.roomMaterials" : "Materiali Stanza", - "spatial.roomDimensions" : "Dimensioni Stanza", - "spatial.roomPositions" : "Posizioni Stanza", - "spatial.setDimensions" : "Imposta Dimensioni", - "spatial.setPositions" : "Imposta Posizioni", - "spatial.up" : "Sopra", - "spatial.front" : "In fronte", - "spatial.left" : "Sinistra", - "spatial.right" : "Destra", - "spatial.back" : "Dietro", - "spatial.down" : "Sotto", - "spatial.listener" : "Utente", - "spatial.audioSource" : "Fonte Audio", - - // Settings - Unfinished - "settings.header.unfinished": "Incompleto", - - // Web Remote - "remote.web.title": "Telecomando Cider", - "remote.web.description": "Leggi il codice QR per connettere il tuo telefono con questa istanza di Cider", - - // About - "about.thanks": "Grazie mille alla Team di Cider Collective e tutti i nostri contribuenti." -} \ No newline at end of file diff --git a/src/i18n/ja_JP.jsonc b/src/i18n/ja_JP.jsonc deleted file mode 100644 index 8c178de1..00000000 --- a/src/i18n/ja_JP.jsonc +++ /dev/null @@ -1,293 +0,0 @@ -{ - // App info - "app.name": "Cider", - - "date.format": "${y}åš´${m}月${d}æ—Ĩ", - - // i18n Info - "i18n.languageName": "æ—ĨæœŦčĒž", // name of language in native language - "i18n.languageNameEnglish": "Japanese", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // Dialogs - "dialog.cancel": "ã‚­ãƒŖãƒŗã‚ģãƒĢ", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "ナイブナãƒĒぎ更新中...", - "notification.updatingLibraryAlbums": "ナイブナãƒĒぎ更新中...", - "notification.updatingLibraryArtists": "ナイブナãƒĒぎ更新中...", - - // Terms - "term.appleMusic": "Apple Music", // Follows brand term - "term.applePodcasts": "Apple Podcasts", // Follows brand term - "term.itunes": "iTunes", // Follows brand term - "term.github": "GitHub", // Follows brand term - "term.discord": "Discord", // Follows brand term - "term.learnMore": "čŠŗã—ã„æƒ…å ą", - "term.accountSettings": "ã‚ĸã‚Ģã‚Ļãƒŗãƒˆč¨­åŽš", - "term.logout": "ã‚ĩã‚¤ãƒŗã‚ĸã‚Ļト", - "term.login": "ã‚ĩã‚¤ãƒŗã‚¤ãƒŗ", - "term.about": "CiderãĢついãĻ", - "term.privateSession": "プナイベãƒŧトã‚ģãƒƒã‚ˇãƒ§ãƒŗ", - "term.queue": "æŦĄã¯ã“ãĄã‚‰", - "term.search": "検į´ĸ", - "term.library": "ナイブナãƒĒ", - "term.listenNow": "äģŠã™ãč´ã", - "term.browse": "čĻ‹ã¤ã‘ã‚‹", - "term.radio": "ナジã‚Ē", - "term.recentlyAdded": "最čŋ‘čŋŊåŠ ã—ãŸé …į›Ž", - "term.songs": "æ›˛", - "term.albums": "ã‚ĸãƒĢバム", - "term.artists": "ã‚ĸãƒŧãƒ†ã‚Ŗã‚šãƒˆ", - "term.podcasts": "Podcast", - "term.playlists": "プãƒŦイãƒĒ゚ト", - "term.playlist": "プãƒŦイãƒĒ゚ト", - "term.play": "å†į”Ÿ", - "term.pause": "停æ­ĸ", - "term.previous": "æˆģる", - "term.next": "æŦĄã¸", - "term.shuffle": "ã‚ˇãƒŖãƒƒãƒ•ãƒĢ", - "term.repeat": "ãƒĒピãƒŧト", - "term.volume": "éŸŗé‡", - "term.mute": "ミãƒĨãƒŧト", - "term.unmute": "ミãƒĨãƒŧãƒˆč§Ŗé™¤", - "term.share": "å…ąæœ‰", - "term.settings": "č¨­åŽš", - "term.seeAll": "すずãĻčĻ‹ã‚‹", - "term.sortBy": "ä¸Ļずæ›ŋえ", - "term.sortBy.album": "ã‚ĸãƒĢバム", - "term.sortBy.artist": "ã‚ĸãƒŧãƒ†ã‚Ŗã‚šãƒˆ", - "term.sortBy.name": "æ›˛å", - "term.sortBy.genre": "ã‚¸ãƒŖãƒŗãƒĢ", - "term.sortBy.releaseDate": "配äŋĄé–‹å§‹æ—Ĩ", - "term.sortBy.duration": "時間", - "term.sortOrder": "ä¸Ļずæ›ŋえ", - "term.sortOrder.ascending": "昇順", - "term.sortOrder.descending": "降順", - "term.viewAs": "襨į¤ē", - "term.viewAs.coverArt": "ã‚Ģバãƒŧã‚ĸãƒŧト", - "term.viewAs.list": "ãƒĒ゚ト", - "term.size": "ã‚ĩイã‚ē", - "term.size.normal": "晎通", - "term.size.compact": "ã‚ŗãƒŗãƒ‘ã‚¯ãƒˆ", - "term.enable": "ON", - "term.disable": "OFF", - "term.enabled": "ON", - "term.disabled": "OFF", - "term.connect": "æŽĨįļš", - "term.connecting": "æŽĨįļšä¸­", - "term.disconnect": "切断", - "term.authed": "čĒč¨ŧ済ãŋ", - "term.confirm": "よろしいでしょうかīŧŸ", - "term.more": "ã‚‚ãŖã¨", - "term.less": "減らす", - "term.showMore": "ã‚‚ãŖã¨čĻ‹ã‚‹", - "term.showLess": "襨į¤ē数を少ãĒくする", - "term.topSongs" : "トップã‚Ŋãƒŗã‚°", - "term.latestReleases": "ニãƒĨãƒŧãƒĒãƒĒãƒŧ゚", - "term.time.added": "čŋŊ加æ—Ĩ", - "term.time.released": "配äŋĄé–‹å§‹æ—Ĩ", - "term.time.updated": "最įĩ‚æ›´æ–°æ—Ĩ", - "term.time.hours": "時間", - "term.time.hour": "時間", - "term.time.minutes": "分", - "term.time.minute": "分", - "term.time.seconds": "į§’", - "term.time.second": "į§’", - "term.fullscreenView": "全į”ģéĸ襨į¤ē", - "term.defaultView": "ã‚Ļã‚Ŗãƒŗãƒ‰ã‚Ļ襨į¤ē", - "term.audioSettings": "ã‚Ēãƒŧãƒ‡ã‚Ŗã‚Ēč¨­åŽš", - "term.spacializedAudioSetting": "ã‚Ēãƒŧãƒ‡ã‚Ŗã‚ĒįŠēé–“åŒ–č¨­åŽš", - "term.clearAll": "æļˆåŽģ", - "term.recentStations": "最čŋ‘ãŽå†į”Ÿ", - "term.language": "言čĒž", - "term.noLyrics": "ロãƒŧãƒ‡ã‚Ŗãƒŗã‚°ã€‚ã€‚ / æ­ŒčŠžãŒčĻ‹ã¤ã‹ã‚‰ãĒい / 器æĨŊæ›˛.", - "term.copyright": "著äŊœæ¨Š", - "term.rightsReserved": "All Rights Reserved.", // Translation does not exist in Japanese - "term.sponsor": "ã‚šãƒãƒŗã‚ĩãƒŧãĢãĒりぞしょう", - "term.ciderTeam": "Cider チãƒŧム", - "term.developer": "開į™ē者", - "term.socialTeam": "ã‚Ŋãƒŧã‚ˇãƒŖãƒĢ チãƒŧム", - "term.contributors": "č˛ĸįŒŽč€…", - "term.equalizer": "ã‚¤ã‚ŗãƒŠã‚¤ã‚ļãƒŧ", - "term.reset": "ãƒĒã‚ģット", - "term.tracks": "æ›˛", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "ビデã‚Ē", - "term.menu": "ãƒĄãƒ‹ãƒĨãƒŧ", - "term.check": "įĸēčĒ", - "term.aboutArtist": "{{artistName}}ãĢついãĻ", // e.g. 'About Doja Cat' - "term.updateCider": "Cider 更新", - - // Home - "home.title": "ホãƒŧム", - "home.recentlyPlayed": "最čŋ‘ãŽå†į”Ÿ", - "home.recentlyAdded": "最čŋ‘čŋŊåŠ ã—ãŸé …į›Ž", - "home.artistsFeed": "ã‚ĸãƒŧãƒ†ã‚Ŗã‚šãƒˆãŽãƒ•ã‚Ŗãƒŧド", - "home.artistsFeed.noArtist": "č‡Ē分ぎåĨŊきãĒã‚ĸãƒŧãƒ†ã‚Ŗã‚šãƒˆã‚’ãƒ•ã‚Šãƒ­ãƒŧしぞしょうãƒģ", - "home.madeForYou": "あãĒたãĢおすすめ", - "home.friendsListeningTo": "å‹é”ãŒč´ã„ãĻいる", - "home.followedArtists": "フりロãƒŧしãĻいるã‚ĸãƒŧãƒ†ã‚Ŗã‚šãƒˆ", - // Errors - "error.appleMusicSubRequired": "Apple Musicぎã‚ĩブ゚クãƒĒãƒ—ã‚ˇãƒ§ãƒŗãŒåŋ…čĻã§ã™ã€‚", - "error.connectionError": "Apple MusicãĢæŽĨįļšã§ããžã›ã‚“。", - "error.noResults": "čĻ‹ã¤ã‹ã‚Šãžã›ã‚“ã§ã—ãŸ", - "error.noResults.description": "もう一åēĻおčŠĻしください。", - - //Podcasts - "podcast.followOnCider": "Ciderでフりロãƒŧ", - "podcast.followedOnCider": "フりロãƒŧ中", - "podcast.subscribeOnItunes": "iTunesでčŗŧčĒ­", - "podcast.subscribedOnItunes": "čŗŧčǭ䏭", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "į•Ēįĩ„", - "podcast.playEpisode": "å†į”Ÿ", - "podcast.website": "Podcast ã‚Ļェブ", - - // Actions - "action.addToLibrary": "ナイブナãƒĒãĢčŋŊ加", - "action.addToLibrary.success": "ナイブナãƒĒãĢčŋŊ加されぞした", - "action.addToLibrary.error": "ナイブナãƒĒへぎčŋŊ加ãĢå¤ąæ•—ã—ãžã—ãŸ", - "action.removeFromLibrary": "ナイブナãƒĒから削除", - "action.removeFromLibrary.success": "ナイブナãƒĒから削除されぞした", - "action.addToQueue": "「æŦĄã¯ã“ãĄã‚‰ã€ãĢé …į›Žã‚’čŋŊ加", - "action.addToQueue.success": "「æŦĄã¯ã“ãĄã‚‰ã€ãĢé …į›Žã‚’čŋŊ加されぞした", - "action.addToQueue.error": "操äŊœã‚’åތäē†ã§ããžã›ã‚“でした", - "action.addToPlaylist": "プãƒŦイãƒĒ゚トãĢčŋŊ加", - "action.removeFromPlaylist": "プãƒŦイãƒĒ゚トから削除", - "action.addToFavorites": "ナブãĢčŋŊ加", - "action.removeFromQueue": "「æŦĄã¯ã“ãĄã‚‰ã€ã‹ã‚‰é …į›Žã‚’å‰Šé™¤", - "action.removeFromQueue.success": "「æŦĄã¯ã“ãĄã‚‰ã€ã‹ã‚‰é …į›Žã‚’å‰Šé™¤ã•ã‚Œãžã—ãŸ", - "action.removeFromQueue.error": "操äŊœã‚’åތäē†ã§ããžã›ã‚“でした", - "action.follow": "フりロãƒŧ", - "action.follow.success": "フりロãƒŧ中", - "action.follow.error": "操äŊœã‚’åތäē†ã§ããžã›ã‚“でした", - "action.unfollow": "フりロãƒŧ觪除", - "action.unfollow.success": "フりロãƒŧをやめぞした", - "action.unfollow.error": "操äŊœã‚’åތäē†ã§ããžã›ã‚“でした", - "action.playNext": "æŦĄãĢå†į”Ÿ", - "action.playLater": "最垌ãĢå†į”Ÿ", - "action.startRadio": "゚テãƒŧã‚ˇãƒ§ãƒŗã‚’äŊœæˆ", - "action.goToArtist": "ã‚ĸãƒŧãƒ†ã‚Ŗã‚šãƒˆã¸į§ģ動", - "action.goToAlbum": "ã‚ĸãƒĢバムへį§ģ動", - "action.moveToTop": "上ãĢæˆģる", - "action.share": "æ›˛ã‚’å…ąæœ‰", - "action.rename": "名前ぎ変更", - "action.love": "ナブ", - "action.unlove": "ãƒŠãƒ–ã‚’č§Ŗé™¤", - "action.dislike": "これãĢäŧŧたもぎをすすめãĒい", - "action.undoDislike": "「これとäŧŧãŸæ›˛ãŽãŠã™ã™ã‚ã‚’æ¸›ã‚‰ã™ã€ã‚’å–ã‚Šæļˆã™", - "action.showWebRemoteQR": "WEBãƒĒãƒĸã‚ŗãƒŗQRã‚ŗãƒŧãƒ‰ã‚’čĄ¨į¤ē", - "action.playTracksNext": "${app.selectedMediaItems.length}æ›˛ãŒæŦĄãĢå†į”Ÿ", - "action.playTracksLater": "${app.selectedMediaItems.length}æ›˛ãŒæœ€åžŒãĢå†į”Ÿ", - "action.removeTracks": "${self.selectedItems.length}æ›˛ãŒã€ŒæŦĄã¯ã“ãĄã‚‰ã€ã‹ã‚‰å‰Šé™¤", - "action.import": "ã‚¤ãƒŗãƒãƒŧト", - "action.export": "エク゚ポãƒŧト", - "action.showAlbum": "すずãĻčĻ‹ã‚‹", - "action.tray.minimize": "最小化", - "action.tray.quit": "įĩ‚äē†", - "action.tray.show": "襨į¤ē", - "action.update": "ã‚ĸップデãƒŧト", - - // Settings - Audio - "settings.header.audio": "ã‚Ēãƒŧãƒ‡ã‚Ŗã‚Ē", - "settings.header.audio.description": "Ciderぎã‚Ēãƒŧãƒ‡ã‚Ŗã‚Ēč¨­åŽš", - "settings.option.audio.quality": "韺čŗĒ", // Dropdown - "settings.header.audio.quality.high": "éĢ˜å“čŗĒ", - "settings.header.audio.quality.low": "éĢ˜åŠšįŽ‡", - "settings.header.audio.quality.auto": "č‡Ē動", - "settings.option.audio.seamlessTransition": "æ›˛é–“ãĒã—ã§å†į”Ÿ", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "å…ˆé€˛įš„ãĒ抟čƒŊ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "AudioContext 抟čƒŊを有劚ãĢすると、ã‚Ēãƒŧãƒ‡ã‚Ŗã‚Ēノãƒŧマナイã‚ē、įŠē間ã‚Ēãƒŧãƒ‡ã‚Ŗã‚Ēã€ã‚¤ã‚ŗãƒŠã‚¤ã‚ļãƒŧãĒおぎ抟čƒŊをäŊŋį”¨ã§ããžã™ãŒã€éŸŗãŒé€”åˆ‡ã‚Œã‚‹ã‹ã‚‚ã—ã‚Œãžã›ã‚“ã€‚", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "ã‚Ēãƒŧãƒ‡ã‚Ŗã‚Ēノãƒŧマナイã‚ē", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "さぞざぞãĒæ›˛ãŽéŸŗé‡ã‚’å‡ä¸€ãĢã—ã€ã‚ˆã‚Šæ•´ãŖãŸéŸŗã‚’æĨŊしめるようãĢする抟čƒŊです。", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "ã‚Ēãƒŧãƒ‡ã‚Ŗã‚ĒįŠē間化", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "ã‚Ēãƒŧãƒ‡ã‚Ŗã‚ĒをįŠē間ãĢåˆ†æ•Ŗã•ã›ã‚‹æŠŸčƒŊです。 (ドãƒĢビãƒŧã‚ĸトãƒĸ゚ではありぞせん)", - // Settings - Visual - "settings.header.visual": "ビジãƒĨã‚ĸãƒĢ", - "settings.header.visual.description": "CiderぎビジãƒĨã‚ĸãƒĢč¨­åŽš", - "settings.option.visual.windowBackgroundStyle": "ã‚ĸプãƒĒã‚Ļã‚¤ãƒŗãƒ‰ã‚ĻãŽčƒŒæ™¯ã‚šã‚ŋイãƒĢ", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "ãĒし", - "settings.header.visual.windowBackgroundStyle.artwork": "ã‚ĸãƒŧトワãƒŧク", - "settings.option.visual.animatedArtwork": "ã‚ĸãƒ‹ãƒĄãƒŧã‚ˇãƒ§ãƒŗã‚ĸãƒŧトワãƒŧク", // Dropdown - "settings.header.visual.animatedArtwork.always": "常ãĢ襨į¤ē", - "settings.header.visual.animatedArtwork.limited": "ã‚ĸãƒŧãƒ†ã‚Ŗã‚šãƒˆãƒšãƒŧジぎãŋ襨į¤ē", - "settings.header.visual.animatedArtwork.disable": "ã‚Ēフ", - "settings.option.visual.animatedArtworkQuality": "ã‚ĸãƒ‹ãƒĄãƒŧã‚ˇãƒ§ãƒŗã‚ĸãƒŧトワãƒŧクぎ品čŗĒ", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "äŊŽ", - "settings.header.visual.animatedArtworkQuality.medium": "中", - "settings.header.visual.animatedArtworkQuality.high": "é̘", - "settings.header.visual.animatedArtworkQuality.veryHigh": "čļ…é̘", - "settings.header.visual.animatedArtworkQuality.extreme": "最é̘", - "settings.option.visual.animatedWindowBackground": "ã‚ĸプãƒĒã‚Ļã‚Ŗãƒŗãƒ‰ã‚ĻãŽčƒŒæ™¯ã‚’ã‚ĸãƒ‹ãƒĄãƒŧã‚ˇãƒ§ãƒŗåŒ–", // Toggle - "settings.option.visual.hardwareAcceleration": "ハãƒŧドã‚Ļェã‚ĸ ã‚ĸクã‚ģナãƒŦãƒŧã‚ˇãƒ§ãƒŗ", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "ã‚ĸプãƒĒを再čĩˇå‹•するåŋ…čĻãŒã‚ã‚Šãžã™", - "settings.header.visual.hardwareAcceleration.default": "æ—ĸ厚", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "ãƒ—ãƒ­ãƒ•ã‚ŖãƒŧãƒĢã‚’čĄ¨į¤ē", // Toggle - // Settings - General (Reserved) - "settings.header.general": "一čˆŦ", - "settings.header.general.description": "Ciderぎ一čˆŦč¨­åŽš", - - // Settings - Lyrics - "settings.header.lyrics": "æ­ŒčŠž", - "settings.header.lyrics.description": "æ­ŒčŠžãŽčĄ¨į¤ēč¨­åŽš", - "settings.option.lyrics.enableMusixmatch": "Musixmatchã§æ­ŒčŠžã‚’čĄ¨į¤ēする", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "ã‚Ģナã‚Ēã‚ąãƒĸãƒŧドを有劚ãĢする (Musixmatchぎãŋ)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "æ­ŒčŠžãŽå„Ēå…ˆč¨€čĒž", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "YouTubeãŽæ­ŒčŠžã‚’ãƒŸãƒĨãƒŧジックビデã‚ĒãĢäŊŋį”¨ã™ã‚‹", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "ã‚ĸプãƒĒã¨é€Ŗæē", - "settings.header.connectivity.description": "CiderãŽé€Ŗæēč¨­åŽš", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "'Cider' ã‚’čĄ¨į¤ēする", - "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music' ã‚’čĄ¨į¤ēする", - "settings.option.connectivity.discordRPC.clearOnPause": "一時停æ­ĸ時ãĢDiscord Rich PresenceをクãƒĒã‚ĸする", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble Delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Enable LastFM Now Playing", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "čŠĻé¨“įš„ãĒ抟čƒŊ", - "settings.header.experimental.description": "開į™ēä¸­ãŽåŽŸé¨“įš„ãĒ抟čƒŊは不厌全で不厉厚である可čƒŊ性がありぞす", - "settings.option.experimental.compactUI": "ã‚ŗãƒŗãƒ‘ã‚¯ãƒˆã‚¤ãƒŗã‚ŋãƒŧフェãƒŧ゚", // Toggle - "settings.option.experimental.close_button_hide": "「閉じる」ボã‚ŋãƒŗã§ã‚ĸプãƒĒを隠しぞす", // Dropdown - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.spatialProperties" : "įŠēé–“åŒ–ãŽãƒ—ãƒ­ãƒ‘ãƒ†ã‚Ŗ", - "spatial.width" : "åš…", - "spatial.height" : "éĢ˜ã•", - "spatial.depth" : "åĨĨ行", - "spatial.gain" : "ã‚˛ã‚¤ãƒŗ", - "spatial.roomMaterials" : "éƒ¨åą‹ãŽãƒžãƒ†ãƒĒã‚ĸãƒĢ", - "spatial.roomDimensions" : "éƒ¨åą‹ãŽå¤§ãã•", - "spatial.roomPositions" : "éƒ¨åą‹ãŽäŊįŊŽ", - "spatial.setDimensions" : "å¤§ãã•ã‚’č¨­åŽš", - "spatial.setPositions" : "äŊįŊŽã‚’設åޚ", - "spatial.up" : "上", - "spatial.front" : "前", - "spatial.left" : "åˇĻ", - "spatial.right" : "åŗ", - "spatial.back" : "垌", - "spatial.down" : "下", - "spatial.listener" : "ãƒĒ゚ナãƒŧ", - "spatial.audioSource" : "韺æē", - - // Settings - Unfinished - "settings.header.unfinished": "æœĒ厌成", - - // Web Remote - "remote.web.title": "Cider ãƒĒãƒĸãƒŧト", - "remote.web.description": "QRã‚ŗãƒŧドをäŊŋį”¨ã—ãĻ、Ciderと゚マãƒŧãƒˆãƒ•ã‚Šãƒŗã‚’ãƒšã‚ĸãƒĒãƒŗã‚°ã™ã‚‹", - - //About - "about.thanks": "Cider Collective とご協力いただいたč˛ĸįŒŽč€…æ§˜ãĢ感čŦį”ŗã—上げぞす。" - -} diff --git a/src/i18n/ko_KR.jsonc b/src/i18n/ko_KR.jsonc deleted file mode 100644 index 76d94149..00000000 --- a/src/i18n/ko_KR.jsonc +++ /dev/null @@ -1,311 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "한ęĩ­ė–´", // name of language in native language - "i18n.languageNameEnglish": "Korean", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@sj8923", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${y}년 ${m}ė›” ${d}ėŧ", - - // Dialogs - "dialog.cancel": "ėˇ¨ė†Œ", - "dialog.ok": "í™•ė¸", - - // Notification - "notification.updatingLibrarySongs": "ëŧė´ë¸ŒëŸŦëĻŦ ęŗĄ ė—…ë°ė´íŠ¸ 뤑...", - "notification.updatingLibraryAlbums": "ëŧė´ë¸ŒëŸŦëĻŦ ė•¨ë˛” ė—…ë°ė´íŠ¸ 뤑...", - "notification.updatingLibraryArtists": "ëŧė´ë¸ŒëŸŦëĻŦ ė•„í‹°ėŠ¤íŠ¸ ė—…ë°ė´íŠ¸ 뤑...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "ë”ëŗ´ę¸°", - "term.accountSettings": "ęŗ„ė • 네렕", - "term.logout": "ëĄœęˇ¸ė•„ė›ƒ", - "term.login": "ëĄœęˇ¸ė¸", - "term.about": "ė •ëŗ´", - "term.privateSession": "ę°œė¸ ė„¸ė…˜", - "term.queue": "ëŒ€ę¸°ė—´", - "term.search": "ę˛€ėƒ‰", - "term.library": "ëŧė´ë¸ŒëŸŦëĻŦ", - "term.listenNow": "ė§€ę¸ˆ ë“Ŗę¸°", - "term.browse": "둘ëŸŦëŗ´ę¸°", - "term.radio": "ëŧë””ė˜¤", - "term.recentlyAdded": "ėĩœęˇŧ ėļ”ę°€ëœ 항ëĒŠ", - "term.songs": "노래", - "term.albums": "ė•¨ë˛”", - "term.artists": "ė•„í‹°ėŠ¤íŠ¸", - "term.podcasts": "팟ėēėŠ¤íŠ¸", - "term.playlists": "í”Œë ˆė´ëĻŦėŠ¤íŠ¸", - "term.playlist": "í”Œë ˆė´ëĻŦėŠ¤íŠ¸", - "term.newPlaylist": "냈 í”Œë ˆė´ëĻŦėŠ¤íŠ¸", - "term.newPlaylistFolder": "냈 í”Œë ˆė´ëĻŦėŠ¤íŠ¸ 폴더", - "term.createNewPlaylist": "냈 í”Œë ˆė´ëĻŦėŠ¤íŠ¸ 만들기", - "term.createNewPlaylistFolder": "냈 í”Œë ˆė´ëĻŦėŠ¤íŠ¸ 폴더 만들기", - "term.deletePlaylist": "ė •ë§ í”Œë ˆė´ëĻŦėŠ¤íŠ¸ëĨŧ ė‚­ė œí•˜ė‹œę˛ ėŠĩ니까?", - "term.play": "ėžŦėƒ", - "term.pause": "ė •ė§€", - "term.previous": "ė´ė „", - "term.next": "ë‹¤ėŒ", - "term.shuffle": "ė…”í”Œ", - "term.repeat": "반ëŗĩėžŦėƒ", - "term.volume": "ëŗŧëĨ¨", - "term.mute": "ėŒė†Œęą°", - "term.unmute": "ėŒė†Œęą° í•´ė œ", - "term.share": "ęŗĩ뜠", - "term.settings": "네렕", - "term.seeAll": "ëĒ¨ë‘ ëŗ´ę¸°", - "term.sortBy": "ė •ë Ŧë°Šė‹", - "term.sortBy.album": "ė•¨ë˛”", - "term.sortBy.artist": "ė•„í‹°ėŠ¤íŠ¸", - "term.sortBy.name": "ė´ëĻ„", - "term.sortBy.genre": "ėžĨëĨ´", - "term.sortBy.releaseDate": "ėļœė‹œėŧ", - "term.sortBy.duration": "ėžŦėƒė‹œę°„", - "term.sortOrder": "ã„ą-ㅎ", - "term.sortOrder.ascending": "똤ëĻ„ė°¨ėˆœ", - "term.sortOrder.descending": "내ëĻŧ밍눜", - "term.viewAs": "í‘œė‹œë°Šė‹", - "term.viewAs.coverArt": "ėģ¤ë˛„ė•„íŠ¸", - "term.viewAs.list": "ëĻŦėŠ¤íŠ¸", - "term.size": "íŦ기", - "term.size.normal": "ėŧ반", - "term.size.compact": "ėģ´íŒŠíЏ", - "term.enable": "í™œė„ąí™”", - "term.disable": "ëš„í™œė„ąí™”", - "term.enabled": "í™œė„ąí™”", - "term.disabled": "ëš„í™œė„ąí™”", - "term.connect": "뗰枰", - "term.connecting": "뗰枰 뤑", - "term.disconnect": "뗰枰 끊김", - "term.authed": "ė¸ėĻë¨", - "term.confirm": "í™•ė¸í•˜ė‹œę˛ ėŠĩ니까 ?", - "term.more": "더", - "term.less": "렁枌", - "term.showMore": "더 ëŗ´ę¸°", - "term.showLess": "렁枌 ëŗ´ę¸°", - "term.topSongs" : "ė¸ę¸°ęŗĄ", - "term.latestReleases": "ėĩœė‹ ęŗĄ", - "term.time.added": "ėļ”ę°€", - "term.time.released": "발매ėŧ", - "term.time.updated": "ė—…ë°ė´íŠ¸ėŧ", - "term.time.hours": "ė‹œę°„", - "term.time.hour": "ė‹œę°„", - "term.time.minutes": "ëļ„", - "term.time.minute": "ëļ„", - "term.time.seconds": "봈", - "term.time.second": "봈", - "term.fullscreenView": "ė „ė˛´í™”ëŠ´", - "term.defaultView": "ę¸°ëŗ¸í™”ëŠ´", - "term.audioSettings": "ė˜¤ë””ė˜¤ 네렕", - "term.clearAll": "ëš„ėš°ę¸°", - "term.recentStations": "ėĩœęˇŧ ėŠ¤í…Œė´ė…˜", - "term.language": "떏떴", - "term.funLanguages": "ėžŦë¯¸ėžˆëŠ”", - "term.noLyrics": "ëļˆëŸŦė˜¤ëŠ” 뤑... / 가ė‚ŦëĨŧ ė°žė„ 눘 ė—†ėŠĩ니다/ ė—°ėŖŧęŗĄ", - "term.copyright": "Copyright", // Used in Korea w/o translation - "term.rightsReserved": "All Rights Reserved.", - "term.sponsor": "ė´ í”„ëĄœė íŠ¸ëĨŧ í›„ė›í•˜ė„¸ėš”", - "term.ciderTeam": "Cider 팀", - "term.developer": "ę°œë°œėž", - "term.socialTeam": "ė†Œė…œ 팀", - "term.socials": "ė†Œė…œ", - "term.contributors": "기ė—Ŧėž", - "term.equalizer": "ė´í€„ëŧė´ė €", - "term.reset": "ė´ˆę¸°í™”", - "term.tracks": "트랙", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "ëš„ë””ė˜¤", - "term.menu": "메뉴", - "term.check": "í™•ė¸", - "term.aboutArtist": "{{artistName}}뗐 대해", // e.g. 'About Doja Cat' - "term.updateCider": "Cider ė—…ë°ė´íŠ¸", - - // Home - "home.title": "홈", - "home.recentlyPlayed": "ėĩœęˇŧ ėžŦėƒëœ 항ëĒŠ", - "home.recentlyAdded": "ėĩœęˇŧ ėļ”ę°€ëœ 항ëĒŠ", - "home.artistsFeed": "내 ė•„í‹°ėŠ¤íŠ¸ í”ŧ드", - "home.artistsFeed.noArtist": "ė•„í‹°ėŠ¤íŠ¸ëĨŧ íŒ”ëĄœėš°í•˜ëŠ´ ėĩœęˇŧ ë°œë§¤ęŗĄė´ í‘œė‹œëŠë‹ˆë‹¤", - "home.madeForYou": "ë‚˜ë§Œė„ ėœ„í•œ ėļ”ė˛œ", - "home.friendsListeningTo": "ėšœęĩŦë“¤ė´ ë“ŖëŠ”", - "home.followedArtists": "íŒ”ëĄœėš°í•œ ė•„í‹°ėŠ¤íŠ¸", - // Errors - "error.appleMusicSubRequired": "ė• í”ŒëŽ¤ė§ ęĩŦë…ė´ í•„ėš”í•Šë‹ˆë‹¤.", - "error.connectionError": "ė• í”ŒëŽ¤ė§ 뗰枰뗐 ëŦ¸ė œę°€ ë°œėƒí–ˆėŠĩ니다.", - "error.noResults": "결ęŗŧ ė—†ėŒ.", - "error.noResults.description": "ėƒˆëĄœ ę˛€ėƒ‰í•´ėŖŧė„¸ėš”.", - - //Podcasts - "podcast.followOnCider": "Cider íŒ”ëĄœėš°", - "podcast.followedOnCider": "Cider íŒ”ëĄœėš°ë¨", - "podcast.subscribeOnItunes": "iTunes ęĩŦ독하기", - "podcast.subscribedOnItunes": "iTunes ęĩŦ독 뤑", - "podcast.itunesStore": "iTunes ėŠ¤í† ė–´", - "podcast.episodes": "뗐í”ŧė†Œë“œ", - "podcast.playEpisode": "뗐í”ŧė†Œë“œ ėžŦėƒ", - "podcast.website": "팟ėēėŠ¤íŠ¸ ė›šė‚Ŧė´íŠ¸", - - // Actions - "action.addToLibrary": "ëŗ´ę´€í•¨ė— ėļ”ę°€", - "action.addToLibrary.success": "ëŗ´ę´€í•¨ė— ėļ”가됨", - "action.addToLibrary.error": "ëŗ´ę´€í•¨ė— ėļ”ę°€ ė‹¤íŒ¨", - "action.removeFromLibrary": "ëŗ´ę´€í•¨ė—ė„œ ė‚­ė œ", - "action.removeFromLibrary.success": "ëŗ´ę´€í•¨ė—ė„œ ė‚­ė œë¨", - "action.addToQueue": "ëŒ€ę¸°ė—´ė— ėļ”ę°€", - "action.addToQueue.success": "ëŒ€ę¸°ė—´ė— ėļ”가됨", - "action.addToQueue.error": "ëŒ€ę¸°ė—´ė— ėļ”ę°€ ė‹¤íŒ¨", - "action.removeFromQueue": "ëŒ€ę¸°ė—´ė—ė„œ ė‚­ė œ", - "action.removeFromQueue.success": "ëŒ€ę¸°ė—´ė—ė„œ ė‚­ė œë¨", - "action.removeFromQueue.error": "ëŒ€ę¸°ė—´ė—ė„œ ė‚­ė œ ė‹¤íŒ¨", - "action.createPlaylist": "냈 í”Œë ˆė´ëĻŦėŠ¤íŠ¸", - "action.addToPlaylist": "í”Œë ˆė´ëĻŦėŠ¤íŠ¸ė— ėļ”ę°€...", - "action.removeFromPlaylist": "í”Œë ˆė´ëĻŦėŠ¤íŠ¸ė—ė„œ ė‚­ė œ", - "action.addToFavorites": "ė„ í˜¸í•­ëĒŠė— ėļ”ę°€", - "action.follow": "íŒ”ëĄœėš°", - "action.follow.success": "íŒ”ëĄœėš°ë¨", - "action.follow.error": "íŒ”ëĄœėš° ė‹¤íŒ¨", - "action.unfollow": "ė–¸íŒ”ëĄœėš°", - "action.unfollow.success": "ė–¸íŒ”ëĄœėš°ë¨", - "action.unfollow.error": "ė–¸íŒ”ëĄœėš° ė‹¤íŒ¨", - "action.playNext": "바로 ë‹¤ėŒė— ėžŦėƒ", - "action.playLater": "맨 ë‚˜ė¤‘ė— ėžŦėƒ", - "action.startRadio": "ėŠ¤í…Œė´ė…˜ ėƒė„ą", - "action.goToArtist": "ė•„í‹°ėŠ¤íŠ¸ ëŗ´ę¸°", - "action.goToAlbum": "ė•¨ë˛” ëŗ´ę¸°", - "action.moveToTop": "맨 ėœ„ëĄœ ė´ë™", - "action.share": "ęŗĩėœ í•˜ę¸°", - "action.rename": "ė´ëĻ„ íŽ¸ė§‘í•˜ę¸°", - "action.love": "ėĸ‹ė•„ėš”", - "action.unlove": "ėĸ‹ė•„ėš” ėˇ¨ė†Œ", - "action.dislike": "ëš„ėŠˇí•œ 항ëĒŠė˜ ė œė•ˆ ė¤„ė´ę¸°", - "action.undoDislike": "ëš„ėŠˇí•œ 항ëĒŠė˜ ė œė•ˆ ė¤„ė´ę¸° ė‹¤í–‰ ėˇ¨ė†Œ", - "action.showWebRemoteQR": "ė›š ëĻŦëĒ¨íŠ¸", - "action.playTracksNext": "${app.selectedMediaItems.length} 바로 ë‹¤ėŒė— ėžŦėƒ", - "action.playTracksLater": "${app.selectedMediaItems.length} 맨 ë‚˜ė¤‘ė— ėžŦėƒ", - "action.removeTracks": "${self.selectedItems.length} ëŒ€ę¸°ė—´ė—ė„œ ė‚­ė œ", - "action.import": "ę°€ė ¸ė˜¤ę¸°", - "action.export": "ë‚´ëŗ´ë‚´ę¸°", - "action.showAlbum": "렄랴 ė•¨ë˛” ëŗ´ę¸°", - "action.tray.minimize": "íŠ¸ë ˆė´ëĄœ ėĩœė†Œí™”", - "action.tray.quit": "ėĸ…ëŖŒ", - "action.tray.show": "", // None is Better in Korean - "action.update": "ė—…ë°ė´íŠ¸", - - // Settings - General - "settings.header.general": "ėŧ반 네렕", - "settings.header.general.description": "CiderëĨŧ ėœ„í•œ ėŧ반 ė„¤ė •ė„ ėĄ°ė ˆí•Šë‹ˆë‹¤.", - "settings.option.general.language": "떏떴", - - // Language optgroups - "settings.option.general.language.main": "떏떴", - "settings.option.general.language.fun": "ė‹¤í—˜ė ė¸ 떏떴", - "settings.option.general.language.unsorted": "ė •ëĻŦë˜ė§€ė•ŠėŒ", - - // Settings - Audio - "settings.header.audio": "ė˜¤ë””ė˜¤", - "settings.header.audio.description": "CiderëĨŧ ėœ„í•œ ė˜¤ë””ė˜¤ ė„¤ė •ė„ ėĄ°ė ˆí•˜ė„¸ėš”.", - "settings.option.audio.quality": "ė˜¤ë””ė˜¤ í’ˆė§ˆ", // Dropdown - "settings.header.audio.quality.high": "ë†’ėŒ", - "settings.header.audio.quality.low": "ë‚ŽėŒ", - "settings.header.audio.quality.auto": "ėžë™", - "settings.option.audio.seamlessTransition": "간격 ė—†ëŠ” ėžŦėƒ", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "ė‹¤í—˜ė ė¸ 기ëŠĨ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "노멀ëŧė´ėĻˆė™€ ė´í€„ëŧė´ė €ė™€ ę°™ė€ 확ėžĨ기ëŠĨė„ ė‚ŦėšŠí•  눘 ėžˆė§€ë§Œ ėŧëļ€ ė‹œėŠ¤í…œė—ė„œ 끊김 í˜„ėƒė´ ë°œėƒí•  눘 ėžˆėŠĩ니다.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "ė‚Ŧėš´ë“œ ėžë™ ėĄ°ė ˆ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "각각 íŠ¸ëž™ė˜ ëŗŧëĨ¨ė„ ėžë™ ėĄ°ė ˆí•Šë‹ˆë‹¤.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "ęŗĩ간 ėŒí–Ĩ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "ė†ŒëĻŦëĨŧ ęŗĩ간 ėŒí–Ĩėœŧ로 ë§Œë“¤ęŗ  3d효ęŗŧëĨŧ ė¤ë‹ˆë‹¤. (ėŖŧė˜: 돌비 ė• íŠ¸ëĒ¨ėŠ¤ę°€ ė•„ë‹˜)", - // Settings - Visual - "settings.header.visual": "ė‹œę° 효ęŗŧ", - "settings.header.visual.description": "CiderëĨŧ ėœ„í•œ ė‹œę° 효ęŗŧ ė„¤ė •ė„ ėĄ°ė ˆí•˜ė„¸ėš”.", - "settings.option.visual.windowBackgroundStyle": "ė°Ŋ ë°°ę˛Ŋ 네렕", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "ė—†ėŒ", - "settings.header.visual.windowBackgroundStyle.artwork": "ė•„íŠ¸ė›ŒíŦ", - "settings.header.visual.windowBackgroundStyle.image": "ė´ë¯¸ė§€", - "settings.option.visual.animatedArtwork": "ė›€ė§ė´ëŠ” ė•„íŠ¸ė›ŒíŦ", // Dropdown - "settings.header.visual.animatedArtwork.always": "í™œė„ąí™”", - "settings.header.visual.animatedArtwork.limited": "íŠšė • íŽ˜ė´ė§€ė— í•œė •", - "settings.header.visual.animatedArtwork.disable": "ëš„í™œė„ąí™”", - "settings.option.visual.animatedArtworkQuality": "ė›€ė§ė´ëŠ” ė•„íŠ¸ė›ŒíŦ í’ˆė§ˆ", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "ë‚ŽėŒ", - "settings.header.visual.animatedArtworkQuality.medium": "뤑氄", - "settings.header.visual.animatedArtworkQuality.high": "ë†’ėŒ", - "settings.header.visual.animatedArtworkQuality.veryHigh": "ë§¤ėš° ë†’ėŒ", - "settings.header.visual.animatedArtworkQuality.extreme": "ėĩœęŗ ", - "settings.option.visual.animatedWindowBackground": "ė›€ė§ė´ëŠ” ė°Ŋ ë°°ę˛Ŋ", // Toggle - "settings.option.visual.hardwareAcceleration": "í•˜ë“œė›¨ė–´ ę°€ė†", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "ėžŦė‹¤í–‰ í•„ėš”", - "settings.header.visual.hardwareAcceleration.default": "ę¸°ëŗ¸", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "ID í‘œė‹œ", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "가ė‚Ŧ", - "settings.header.lyrics.description": "CiderëĨŧ ėœ„í•œ 가ė‚Ŧ ė„¤ė •ė„ ėĄ°ė ˆí•˜ė„¸ėš”.", - "settings.option.lyrics.enableMusixmatch": "Musixmatch 가ė‚Ŧ", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "노래방 ëĒ¨ë“œ (Musixmatch만)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch ė„ í˜¸ ë˛ˆė—­ 떏떴", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "ëŽ¤ė§ëš„ë””ė˜¤ ėžŦėƒ ė‹œ ėœ íŠœë¸Œė—ė„œ 가ė‚Ŧ ę°€ė ¸ė˜¤ę¸°", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "뗰枰", - "settings.header.connectivity.description": "CiderëĨŧ ėœ„í•œ 뗰枰 ė„¤ė •ė„ ėĄ°ė ˆí•˜ė„¸ėš”.", - "settings.option.connectivity.discordRPC": "Discord ėƒíƒœ í‘œė‹œ", // Dropdown - "settings.option.connectivity.playbackNotifications": "ėžŦėƒ ėƒíƒœ í‘œė‹œ", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "'Cider'로 í‘œė‹œ", - "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music'ėœŧ로 í‘œė‹œ", - "settings.option.connectivity.discordRPC.clearOnPause": "ėŧė‹œ ė •ė§€ ėƒíƒœė—ė„œ Discord ėƒíƒœ í‘œė‹œ 끄기", // Toggle - "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble 맀뗰 (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Last.fm Now Playing í™œė„ą", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "ęŗĄ ė´ëĻ„ė—ė„œ í”ŧėŗë§ ė•„í‹°ėŠ¤íŠ¸ ëšŧ기 (Last.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "반ëŗĩ ėžŦėƒ 트랙 ė œęą° (Last.fm)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "ė‹¤í—˜ 기ëŠĨ", - "settings.header.experimental.description": "CiderëĨŧ ėœ„í•œ ė‹¤í—˜ 기ëŠĨė„ ėĄ°ė ˆí•˜ė„¸ėš”.", - "settings.option.experimental.compactUI": "ėģ´íŒŠíЏ UI", // Toggle - "settings.option.experimental.close_button_hide": "ë‹Ģ기 버íŠŧėœŧ로 프로그램 눍揰揰", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "ë¨ŧė € ęŗĩ간 ėŒí–Ĩ ė„¤ė •ė„ í™œė„ąí™”í•´ėŖŧė„¸ėš”.", - "spatial.spatialProperties": "ęŗĩ간 ė†ė„ą", - "spatial.width": "너비", - "spatial.height": "ë†’ė´", - "spatial.depth": "ęšŠė´", - "spatial.gain": "ę˛Œė¸", - "spatial.roomMaterials": "ë°Š ėžŦ마", - "spatial.roomDimensions": "ë°Š 밍뛐", - "spatial.roomPositions": "ë°Š ėœ„ėš˜", - "spatial.setDimensions": "밍뛐 네렕", - "spatial.setPositions": "ėœ„ėš˜ 네렕", - "spatial.up": "ėœ„", - "spatial.front": "ė•ž", - "spatial.left": "ė™ŧėĒŊ", - "spatial.right": "똤ëĨ¸ėĒŊ", - "spatial.back": "뒤", - "spatial.down": "ė•„ëž˜", - "spatial.listener": "ė˛­ėˇ¨ėž", - "spatial.audioSource": "ė˜¤ë””ė˜¤ ėļœė˛˜", - - // Settings - Unfinished - "settings.header.unfinished": "ë¯¸ė™„ė„ą", - - // Web Remote - "remote.web.title": "Cider ëĻŦëĒ¨íŠ¸", - "remote.web.description": "Cider ė¸ėŠ¤í„´ėŠ¤ė™€ 휴대 ė „í™”ëĨŧ ė—°ę˛°í•˜ë ¤ëŠ´ QR ėŊ”드ëĨŧ 늤ėē”í•´ėŖŧė„¸ėš”", - - // About - "about.thanks": "Cider ėģŦ렉티브 팀ęŗŧ 뚰ëĻŦė˜ ëĒ¨ë“  기ė—Ŧėžë“¤ęģ˜ ëŒ€ë‹¨ížˆ 감ė‚ŦëĨŧ 표합니다." -} diff --git a/src/i18n/pt_BR.jsonc b/src/i18n/pt_BR.jsonc deleted file mode 100644 index dad04de4..00000000 --- a/src/i18n/pt_BR.jsonc +++ /dev/null @@ -1,244 +0,0 @@ -{ // Base File - // App info - "app.name": "Cider", - - "date.format": "${d} ${m}, ${y}", - - // i18n Info - "i18n.languageName": "PortuguÃĒs ( brasileiro )", // name of language in native language - "i18n.languageNameEnglish": "Portuguese (Brazil)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // Dialogs - "dialog.cancel": "Cancelar", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "Atualizando mÃēsicas na biblioteca...", - "notification.updatingLibraryAlbums": "Atualizando albuns na biblioteca...", - "notification.updatingLibraryArtists": "Atualizando artistas na biblioteca...", - "notification.connectionError": "Houve um problema a se conectar no Apple Music", - - // Terms - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Saiba Mais", - "term.accountSettings": "DefiniçÃĩes da Conta", - "term.logout": "Sair", - "term.login": "Entrar", - "term.about": "Sobre", - "term.privateSession": "SessÃŖo Privada", - "term.queue": "Fila", - "term.search": "Procurar", - "term.library": "Biblioteca", - "term.listenNow": "Ouça Agora", - "term.browse": "Explorar", - "term.radio": "Radio", - "term.recentlyAdded": "Adicionado Recentemente", - "term.songs": "MÃēsicas", - "term.albums": "Albuns", - "term.artists": "Artistas", - "term.podcasts": "Podcasts", - "term.playlists": "Listas de ReproduÃ§ÃŖo", - "term.playlist": "Lista de ReproduÃ§ÃŖo", - "term.play": "Tocar", - "term.pause": "Pausar", - "term.previous": "Anterior", - "term.next": "PrÃŗximo", - "term.shuffle": "AleatÃŗrio", - "term.repeat": "Repetir", - "term.volume": "Volume", - "term.mute": "Mudo", - "term.unmute": "Tirar o Mudo", - "term.share": "Partilhar", - "term.settings": "DefiniçÃĩes", - "term.seeAll": "Ver Tudo", - "term.sortBy": "Organizar Por", - "term.sortBy.album": "Album", - "term.sortBy.artist": "Artista", - "term.sortBy.name": "Nome", - "term.sortBy.genre": "Genero", - "term.sortBy.releaseDate": "Data de Lançamento", - "term.sortBy.duration": "DuraÃ§ÃŖo", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Ascendente", - "term.sortOrder.descending": "Descendente", - "term.viewAs": "Ver Como", - "term.viewAs.coverArt": "Capa", - "term.viewAs.list": "Lista", - "term.size": "Tamanho", - "term.size.normal": "Normal", - "term.size.compact": "Compacto", - "term.enable": "Ativar", - "term.disable": "Desativar", - "term.enabled": "Ativado", - "term.disabled": "Desativado", - "term.connect": "Conectar", - "term.disconnect": "Desconectar", - "term.connecting": "Conectando", - "term.confirm": "Confirmar ?", - "term.more": "Mais", - "term.less": "Menos", - "term.showMore": "Mostrar Mais", - "term.showLess": "Mostrar Menos", - "term.topSongs" : "Top de MÃēsicas", - "term.latestReleases": "Ultimos Lançamentos", - "term.time.added": "Adicionado", - "term.time.released": "Lançado", - "term.time.updated": "Atualizado", - "term.fullscreenView": "VisualizaÃ§ÃŖo em Tela Cheia", - "term.defaultView": "VisualizaÃ§ÃŖo Normal", - "term.spacializedAudioSetting": "DefiniçÃĩes de Audio Espacial", - "term.clearAll": "Limpar Tudo", - "term.language": "Idioma", - "term.recentStations": "EstaçÃĩes Recentes", - - // Home - "home.title": "Inicio", - "home.recentlyPlayed": "Tocado Recentemente", - "home.recentlyAdded": "Adicionado Recentemente", - "home.artistsFeed": "Novidades dos seus Artistas", - "home.madeForYou": "Feito para VocÃĒ", - "home.friendsListeningTo": "Amigos Ouvindo", - "home.followedArtists": "Artistas Seguidos", - // Errors - "error.appleMusicSubRequired": "NecessÃĄrio uma assinatura Apple Music.", - - // Actions - "action.addToLibrary": "Adicionar à Biblioteca", - "action.addToLibrary.success": "Adicionado à Biblioteca", - "action.addToLibrary.error": "Erro ao Adicionar na Biblioteca", - "action.removeFromLibrary": "Remover da Biblioteca", - "action.removeFromLibrary.success": "Removido da Biblioteca", - "action.addToQueue": "Adicionar à Fila", - "action.addToQueue.success": "Adicionado à Fila", - "action.addToQueue.error": "Erro ao Adicionar à Fila", - "action.removeFromQueue": "Remover da Fila", - "action.removeFromQueue.success": "Removido da Fila", - "action.removeFromQueue.error": "Erro ao Remover da Fila", - "action.addToPlaylist": "Adicionar à Lista de ReproduÃ§ÃŖo", - "action.removeFromPlaylist": "Remover da Lista de ReproduÃ§ÃŖo", - "action.addToFavorites": "Adicionar aos Favoritos", - "action.follow": "Seguir", - "action.follow.success": "A Seguir", - "action.follow.error": "Erro ao Seguir", - "action.unfollow": "Deixar de Seguir", - "action.unfollow.success": "Deixou de Seguir", - "action.unfollow.error": "Erro ao Deixar de Seguir", - "action.playNext": "Tocar Proximo", - "action.playLater": "Tocar por Ultimo", - "action.startRadio": "Começar Radio", - "action.goToArtist": "Ir para o Artista", - "action.goToAlbum": "Ir para o Album", - "action.moveToTop": "Mover para cima", - "action.share": "Partilhar", - "action.rename": "Mudar o Nome", - "action.love": "Gostar", - "action.unlove": "Deixar de Gostar", - "action.dislike": "NÃŖo Gostar", - "action.undoDislike": "Deixar de NÃŖo Gostar", - "action.showWebRemoteQR": "Mostrar o QR para PÃĄgina Remota", - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Ajustar as definiçÃĩes de audio no Cider.", - "settings.option.audio.quality": "Qualidade do Audio", // Dropdown - "settings.header.audio.quality.high": "Alta", - "settings.header.audio.quality.low": "Baixa", - "settings.header.audio.quality.auto": "Automatico", - "settings.option.audio.seamlessTransition": "TransiÃ§ÃŖo de Áudio Perfeita", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Ativar Funcionabilidades Avançadas", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Habilitar a funcionalidade AudioContext permitirÃĄ recursos de ÃĄudio estendidos, como NormalizaÃ§ÃŖo de Áudio , Equalizadores e Visualizadores. No entanto, em alguns sistemas, isso pode causar travamentos nas faixas de ÃĄudio.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "NormalizaÃ§ÃŖo de Audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliza o volume alto para faixas individuais para criar uma experiÃĒncia de audiÃ§ÃŖo mais uniforme.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Audio Espacial", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Espacialize o ÃĄudio e torne o ÃĄudio mais tridimensional (nota: isto nÃŖo Ê Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visual", - "settings.header.visual.description": "Ajustar as DefiniçÃĩes de Visual do Cider.", - "settings.option.visual.windowBackgroundStyle": "Estilo do Fundo da Janela", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Nenhum", - "settings.header.visual.windowBackgroundStyle.artwork": "Capa", - "settings.option.visual.animatedArtwork": "Capa Animada", // Dropdown - "settings.header.visual.animatedArtwork.always": "Sempre", - "settings.header.visual.animatedArtwork.limited": "Limitado a pÃĄginas e entradas especiais", - "settings.header.visual.animatedArtwork.disable": "Desativar em Tudo", - "settings.option.visual.animatedArtworkQuality": "Qualidade da Capa Animada", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Baixa", - "settings.header.visual.animatedArtworkQuality.medium": "Media", - "settings.header.visual.animatedArtworkQuality.high": "Alta", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Muito Alta", - "settings.header.visual.animatedArtworkQuality.extreme": "Extrema", - "settings.option.visual.animatedWindowBackground": "Fundo de Janela Animado", // Toggle - "settings.option.visual.hardwareAcceleration": "AcelaraÃ§ÃŖo no Hardware", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "NecessÃĄrio reiniciar a aplicaÃ§ÃŖo", - "settings.header.visual.hardwareAcceleration.default": "Normal", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - - - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Mostrar Informaçoes Pessoais", // Toggle - // Settings - General (Reserved) - "settings.header.general": "Principal", - "settings.header.general.description": "Ajustar as definiçoes principais no Cider.", - - // Settings - Lyrics - "settings.header.lyrics": "Letras", - "settings.header.lyrics.description": "Ajustar as definiçÃĩes das letras no Cider.", - "settings.option.lyrics.enableMusixmatch": "Ativar Letras do Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Ativar Modo Karaoke (sÃŗ para Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Idioma Preferido para TraduÃ§ÃŖo Musixmatch", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Ativar letras do Youtube para videos musicais", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Conectividade", - "settings.header.connectivity.description": "Ajustar as definiçÃĩes de conectividade no Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Mostrar como 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Mostrar como 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Apagar Discord Rich Presence quando estiver pausado", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Atraso dos Scrobbles do LastFM (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Ativar LastFM Now Playing", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remover artistas de colaboraÃ§ÃŖo do nome da mÃēsica (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "Experimental", - "settings.header.experimental.description": "Ajustar as definiçÃĩes experimental no Cider.", - "settings.option.experimental.compactUI": "UI Compacto", // Toggle - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.spatialProperties" : "Propriedades do Espacial", - "spatial.width" : "Largura", - "spatial.height" : "Altura", - "spatial.depth" : "Profundidade", - "spatial.roomMaterials" : "Materiais da Sala", - "spatial.roomDimensions" : "DimensÃĩes da Sala", - "spatial.roomPositions" : "PosiçÃĩes da Sala", - "spatial.setDimensions" : "Definir DimensÃĩes", - "spatial.setPositions" : "Definir PosiçÃĩes", - "spatial.up" : "Acima", - "spatial.front" : "Frente", - "spatial.left" : "Esquerda", - "spatial.right" : "Direita", - "spatial.back" : "AtrÃĄs", - "spatial.down" : "Abaixo", - "spatial.listener" : "Ouvinte", - "spatial.audioSource" : "Fonte de Audio", - - - - - // Settings - Unfinished - "settings.header.unfinished": "Inacabado", - - // Web Remote - "remote.web.title": "Cider Remoto", - "remote.web.description": "Digitalize o cÃŗdigo QR para emparelhar seu telefone com esta instÃĸncia Cider" -} \ No newline at end of file diff --git a/src/i18n/ro_RO.jsonc b/src/i18n/ro_RO.jsonc deleted file mode 100644 index 181257dd..00000000 --- a/src/i18n/ro_RO.jsonc +++ /dev/null @@ -1,311 +0,0 @@ -{ - - // i18n Info - "i18n.languageName": "RomÃĸnă", // name of language in native language - "i18n.languageNameEnglish": "Romanian", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@SubZeroNexii georgechrc", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${d} ${m}, ${y}", - - // Dialogs - "dialog.cancel": "Anulare", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "Actualizare bibliotecă muzică...", - "notification.updatingLibraryAlbums": "Actualizare bibliotecă albume...", - "notification.updatingLibraryArtists": "Actualizare bibliotecă artiști...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Află mai multe", - "term.accountSettings": "Setări cont", - "term.logout": "Deconectare", - "term.login": "Autentificare", - "term.about": "Despre", - "term.privateSession": "Sesiune Privată", - "term.queue": "ÃŽn Coadă", - "term.search": "Căutare", - "term.library": "Bibliotecă", - "term.listenNow": "Ascultă acum", - "term.browse": "Navigați", - "term.radio": "Radio", - "term.recentlyAdded": "Recent Adăugate", - "term.songs": "Muzică", - "term.albums": "Albume", - "term.artists": "Artiști", - "term.podcasts": "Podcast-uri", - "term.playlists": "Playlist-uri", - "term.playlist": "Playlist", - "term.newPlaylist": "Playlist Nou", - "term.newPlaylistFolder": "Dosar Playlist Nou", - "term.createNewPlaylist": "Creează un Playlist Nou", - "term.createNewPlaylistFolder": "Creează un Dosar Playlist Nou", - "term.deletePlaylist": "Sunteți siguri că vreți să ștergeți acest Playlist?", - "term.play": "Redă", - "term.pause": "Pauză", - "term.previous": "Înapoi", - "term.next": "Înainte", - "term.shuffle": "Aleator", - "term.repeat": "Repetă", - "term.volume": "Volum", - "term.mute": "Fară sunet", - "term.unmute": "Activare sunet", - "term.share": "Partajează", - "term.settings": "Setări", - "term.seeAll": "Vedeți tot", - "term.sortBy": "Sortare după", - "term.sortBy.album": "Album", - "term.sortBy.artist": "Artist", - "term.sortBy.name": "Nume", - "term.sortBy.genre": "Gen", - "term.sortBy.releaseDate": "Data Lansării", - "term.sortBy.duration": "Durată", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Ascendent", - "term.sortOrder.descending": "Descendent", - "term.viewAs": "Vizualizare ca", - "term.viewAs.coverArt": "Artă Copertă", - "term.viewAs.list": "Listă", - "term.size": "Mărime", - "term.size.normal": "Normal", - "term.size.compact": "Compact", - "term.enable": "Activare", - "term.disable": "Dezactivare", - "term.enabled": "Activat", - "term.disabled": "Dezactivat", - "term.connect": "Conectare", - "term.connecting": "Se conectează", - "term.disconnect": "Deconectare", - "term.authed": "Autentificat", - "term.confirm": "Confirmați ?", - "term.more": "Mai mult", - "term.less": "Mai puțin", - "term.showMore": "Arată mai mult", - "term.showLess": "Arată mai puțin", - "term.topSongs" : "Top Muzică", - "term.latestReleases": "Ultimele Lansări", - "term.time.added": "Adăugate", - "term.time.released": "Lansate", - "term.time.updated": "Actualizate", - "term.time.hours": "ore", - "term.time.hour": "oră", - "term.time.minutes": "minute", - "term.time.minute": "minut", - "term.time.seconds": "secunde", - "term.time.second": "secundă", - "term.fullscreenView": "Vizualizare Ecran Complet", - "term.defaultView": "Vizualizare Standard", - "term.audioSettings": "Setări Audio", - "term.clearAll": "Ștergere toate", - "term.recentStations": "Stații Recente", - "term.language": "Limbă", - "term.funLanguages": "Amuzament", - "term.noLyrics": "Incărcare... / Versurile nu au fost găsite./ Instrumental.", - "term.copyright": "Copyright", - "term.rightsReserved": "Toate drepturile rezervate.", - "term.sponsor": "Sponsorizați acest proiect", - "term.ciderTeam": "Echipa Cider", - "term.developer": "Dezvoltatori", - "term.socialTeam": "Echipa de relații publice", - "term.socials": "Rețele Sociale", - "term.contributors": "Contribuitori", - "term.equalizer": "Egalizator", - "term.reset": "Reset", - "term.tracks": "melodii", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Videoclipuri", - "term.menu": "Meniu", - "term.check": "Verificare", - "term.aboutArtist": "Despre {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Actualizare Cider", - - // Home - "home.title": "Acasă", - "home.recentlyPlayed": "Asculate Recent", - "home.recentlyAdded": "Adăugate Recent", - "home.artistsFeed": "Fluxul Artiștilor tăi", - "home.artistsFeed.noArtist": "Urmărește prima oară cațiva artiști și ultimele lor lansări vor apărea aici", - "home.madeForYou": "Pentru tine", - "home.friendsListeningTo": "Prietenii tăi ascultă", - "home.followedArtists": "Artiști Urmăriți", - // Errors - "error.appleMusicSubRequired": "Apple Music necesită un abonament.", - "error.connectionError": "A apărut o problemă ÃŽn conectarea la Apple Music.", - "error.noResults": "Nici un rezultat.", - "error.noResults.description": "ÃŽncearcă o nouă căutare.", - - //Podcasts - "podcast.followOnCider": "Urmărește pe Cider", - "podcast.followedOnCider": "Urmărit pe Cider", - "podcast.subscribeOnItunes": "Abonează-te pe iTunes", - "podcast.subscribedOnItunes": "Abonat pe iTunes", - "podcast.itunesStore": "Magazin iTunes", - "podcast.episodes": "Episoade", - "podcast.playEpisode": "Începe Episodul", - "podcast.website": "Pagină Podcast", - - // Actions - "action.addToLibrary": "Adaugă ÃŽn Librărie", - "action.addToLibrary.success": "Adăugat ÃŽn Librărie", - "action.addToLibrary.error": "Eroare la adăugarea ÃŽn Librărie", - "action.removeFromLibrary": "Ștergere din Librărie", - "action.removeFromLibrary.success": "Șters din Librărie", - "action.addToQueue": "Adăugare la Coadă", - "action.addToQueue.success": "Adăugat la Coadă", - "action.addToQueue.error": "Eroare adăugare la Coadă", - "action.removeFromQueue": "Ștergere din Coadă", - "action.removeFromQueue.success": "Șters din Coadă", - "action.removeFromQueue.error": "Eroare Ștergere din Coadă", - "action.createPlaylist": "Creează un nou Playlist", - "action.addToPlaylist": "Adaugă la Playlist", - "action.removeFromPlaylist": "Ștergere din Playlist", - "action.addToFavorites": "Adaugă la Favorite", - "action.follow": "Urmărește", - "action.follow.success": "Urmărit", - "action.follow.error": "Eroare Urmărire", - "action.unfollow": "Nu mai urmăriți", - "action.unfollow.success": "Urmărire ÃŽncetată", - "action.unfollow.error": "Eroare ÃŽncetare Urmărire", - "action.playNext": "Ascultă ÃŽn Continuare", - "action.playLater": "Ascultă Mai TÃĸrziu", - "action.startRadio": "Pornește Radio", - "action.goToArtist": "Du-te la Artist", - "action.goToAlbum": "Du-te la Album", - "action.moveToTop": "Mută ÃŽn vÃĸrf", - "action.share": "Partajează", - "action.rename": "Redenumire", - "action.love": "Apreciază", - "action.unlove": "Elimină Apreciere", - "action.dislike": "Dislike", - "action.undoDislike": "Elimină dislike", - "action.showWebRemoteQR": "Telecomandă Web", - "action.playTracksNext": "Redă ${app.selectedMediaItems.length} de melodii ÃŽn continuare", - "action.playTracksLater": "Redă ${app.selectedMediaItems.length} de melodii mai tÃĸrziu", - "action.removeTracks": "Șterge ${self.selectedItems.length} de melodii din Coadă", - "action.import": "Import", - "action.export": "Export", - "action.showAlbum": "Arată Albumul Complet", - "action.tray.minimize": "Minimizează ÃŽn Tray", - "action.tray.quit": "Ieșire", - "action.tray.show": "Arată", - "action.update": "Actualizează", - - // Settings - General - "settings.header.general": "General", - "settings.header.general.description": "Ajustează setările generale pentru Cider.", - "settings.option.general.language": "Limbă", - - // Language optgroups - "settings.option.general.language.main": "Limbi", - "settings.option.general.language.fun": "Amuzant", - "settings.option.general.language.unsorted": "Nesortate", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Ajustează setările audio pentru Cider.", - "settings.option.audio.quality": "Calitate Audio", // Dropdown - "settings.header.audio.quality.high": "Ridicată", - "settings.header.audio.quality.low": "Redusă", - "settings.header.audio.quality.auto": "Auto", - "settings.option.audio.seamlessTransition": "Tranziție Audio NeÃŽntreruptă", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Activează Funcționalitate Avansată", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Pornirea funcționalității AudioContext va permite folosirea funcțiilor audio avansate precum Normalizare Volum , Egalizator și Vizualizator, dar pe unele sisteme poate cauza probleme precum ÃŽntreruperi ÃŽn redare.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizare Volum", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizează volumul maxim al melodiilor pentru a genera o experiență audio optimă.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spațializare Audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spațializează sunetul și face sunetul 3-dimensional (notă: Nu este Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Vizual", - "settings.header.visual.description": "Ajustează setările vizuale pentru Cider.", - "settings.option.visual.windowBackgroundStyle": "Stil Fundal Fereastră", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Niciunul", - "settings.header.visual.windowBackgroundStyle.artwork": "Copertă Melodie", - "settings.header.visual.windowBackgroundStyle.image": "Imagine", - "settings.option.visual.animatedArtwork": "Copertă Animată", // Dropdown - "settings.header.visual.animatedArtwork.always": "Întotdeauna", - "settings.header.visual.animatedArtwork.limited": "Limitat la pagini și Albume speciale", - "settings.header.visual.animatedArtwork.disable": "Dezactivează peste tot", - "settings.option.visual.animatedArtworkQuality": "Calitate Copertă Animată", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Redusă", - "settings.header.visual.animatedArtworkQuality.medium": "Medie", - "settings.header.visual.animatedArtworkQuality.high": "Ridicată", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Foarte Ridicată", - "settings.header.visual.animatedArtworkQuality.extreme": "Extremă", - "settings.option.visual.animatedWindowBackground": "Fundal Fereastră Animat", // Toggle - "settings.option.visual.hardwareAcceleration": "Accelerare Hardware", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "Necesită Repornire", - "settings.header.visual.hardwareAcceleration.default": "Implitcit", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Arată informații personale", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "Versuri", - "settings.header.lyrics.description": "Ajustează setările versurilor pentru Cider.", - "settings.option.lyrics.enableMusixmatch": "Activează Versuri Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Activează Mod Karaoke (numai Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Limbă Preferată Traducere Musixmatch", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Activează Versuri Youtube pentru Videoclipuri Muzică", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Conectivitate", - "settings.header.connectivity.description": "Ajustează setările de conectivitate pentru Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Notificări Redare", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Afișează ca 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Afișează ca 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Curăță Discord Rich Presence la Pauză", // Toggle - "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble Delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Activează Last.fm Now Playing", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Ștergeți artiștii invitat din titlul melodiei (Last.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrează melodii repetate (Last.fm)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "Experimental", - "settings.header.experimental.description": "Ajustează setările experimentale pentru Cider.", - "settings.option.experimental.compactUI": "UI Compact", // Toggle - "settings.option.experimental.close_button_hide": "Butonul de ÃŽnchidere ar trebui să ascundă aplicația", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "Spațializarea Audio este dezactivată. Pentru a folosi opțiunea aceasta, activați-o mai ÃŽntÃĸi.", - "spatial.spatialProperties": "Proprietăți Spațiale", - "spatial.width": "Lățime", - "spatial.height": "Înălțime", - "spatial.depth": "AdÃĸncime", - "spatial.gain": "Gain", - "spatial.roomMaterials": "Materiale Cameră", - "spatial.roomDimensions": "Dimensiuni Cameră", - "spatial.roomPositions": "Poziții Cameră", - "spatial.setDimensions": "Setează Dimensiunile", - "spatial.setPositions": "Setează Pozițiile", - "spatial.up": "Sus", - "spatial.front": "În Față", - "spatial.left": "StÃĸnga", - "spatial.right": "Dreapta", - "spatial.back": "În Spate", - "spatial.down": "Jos", - "spatial.listener": "Ascultător", - "spatial.audioSource": "Sursă Audio", - - // Settings - Unfinished - "settings.header.unfinished": "Neterminat", - - // Web Remote - "remote.web.title": "Telecomandă Cider", - "remote.web.description": "Scanează codul QR pentru a ÃŽmperechea telefonul tău cu această instanță Cider", - - // About - "about.thanks": "Multe Mulțumiri Echipei Colectiv Cider și a tuturor contribuitorilor." -} diff --git a/src/i18n/sv_SE.jsonc b/src/i18n/sv_SE.jsonc deleted file mode 100644 index 22953aee..00000000 --- a/src/i18n/sv_SE.jsonc +++ /dev/null @@ -1,311 +0,0 @@ -{ // Base File - - // i18n Info - "i18n.languageName": "Svenska (SE)", // name of language in native language - "i18n.languageNameEnglish": "Swedish (SE)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@thisismemeboi", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${d} ${m}, ${y}", - - // Dialogs - "dialog.cancel": "Avbryt", - "dialog.ok": "OK", - - // Notification - "notification.updatingLibrarySongs": "Uppdaterar lÃĨtar i biblioteket...", - "notification.updatingLibraryAlbums": "Uppdaterar album i biblioteket...", - "notification.updatingLibraryArtists": "Uppdaterar artister i biblioteket...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Visa mer", - "term.accountSettings": "Kontoinställningar", - "term.logout": "Logga ut", - "term.login": "Logga in", - "term.about": "Om", - "term.privateSession": "Privat läge", - "term.queue": "KÃļ", - "term.search": "SÃļk", - "term.library": "Bibliotek", - "term.listenNow": "Lyssna nu", - "term.browse": "Bläddra", - "term.radio": "Radio", - "term.recentlyAdded": "Senast tillagda", - "term.songs": "LÃĨtar", - "term.albums": "Album", - "term.artists": "Artister", - "term.podcasts": "Podcasts", - "term.playlists": "Spellistor", - "term.playlist": "Spellista", - "term.newPlaylist": "Ny spellista", - "term.newPlaylistFolder": "Ny spellistemapp", - "term.createNewPlaylist": "Skapa ny spellista", - "term.createNewPlaylistFolder": "Skapa ny spellistemapp", - "term.deletePlaylist": "Är du säker att du vill ta bort den här spellistan?", - "term.play": "Spela", - "term.pause": "Pausa", - "term.previous": "FÃļregÃĨende", - "term.next": "Nästa", - "term.shuffle": "Blanda", - "term.repeat": "Upprepa", - "term.volume": "Volym", - "term.mute": "Tysta", - "term.unmute": "Sluta tysta", - "term.share": "Dela", - "term.settings": "Inställningar", - "term.seeAll": "Se allt", - "term.sortBy": "Sortera efter", - "term.sortBy.album": "Album", - "term.sortBy.artist": "Artist", - "term.sortBy.name": "Namn", - "term.sortBy.genre": "Genre", - "term.sortBy.releaseDate": "Releasedatum", - "term.sortBy.duration": "Längd", - "term.sortOrder": "Ordna efter", - "term.sortOrder.ascending": "Stigande", - "term.sortOrder.descending": "Fallande", - "term.viewAs": "Visa som", - "term.viewAs.coverArt": "Omslagsbild", - "term.viewAs.list": "Lista", - "term.size": "Storlek", - "term.size.normal": "Standard", - "term.size.compact": "Liten", - "term.enable": "Aktivera", - "term.disable": "Inaktivera", - "term.enabled": "PÃĨ", - "term.disabled": "Av", - "term.connect": "Anslut", - "term.connecting": "Ansluter", - "term.disconnect": "Koppla frÃĨn", - "term.authed": "Godkänd", - "term.confirm": "Klicka igen fÃļr att bekräfta", - "term.more": "Mer", - "term.less": "Mindre", - "term.showMore": "Visa mer", - "term.showLess": "Visa mindre", - "term.topSongs" : "TopplÃĨtar", - "term.latestReleases": "Senaste releaserna", - "term.time.added": "Tillagd", - "term.time.released": "Tillagd den", - "term.time.updated": "Uppdaterad", - "term.time.hours": "timmar", - "term.time.hour": "timme", - "term.time.minutes": "minuter", - "term.time.minute": "minut", - "term.time.seconds": "sekunder", - "term.time.second": "sekund", - "term.fullscreenView": "Helskärmsvy", - "term.defaultView": "Standardvy", - "term.audioSettings": "Ljudinställningar", - "term.clearAll": "Rensa allt", - "term.recentStations": "Senaste stationerna", - "term.language": "SprÃĨk (Language)", - "term.funLanguages": "Roliga", - "term.noLyrics": "Laddar... / Inga lÃĨttexter hittades./ Instrumental.", - "term.copyright": "Copyright", - "term.rightsReserved": "Alla rättigheter behÃĨlls.", - "term.sponsor": "Hjälp det här projektet", - "term.ciderTeam": "Cider teamet", - "term.developer": "Utvecklare", - "term.socialTeam": "Sociala teamet", - "term.socials": "Sociala medier", - "term.contributors": "Bidrag", - "term.equalizer": "EQ", - "term.reset": "Återställ", - "term.tracks": "lÃĨtar", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Videor", - "term.menu": "Meny", - "term.check": "SÃļk efter uppdateringar", - "term.aboutArtist": "Om {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Uppdatera Cider", - - // Home - "home.title": "Hem", - "home.recentlyPlayed": "Senast spelade", - "home.recentlyAdded": "Senast tillagda", - "home.artistsFeed": "Ditt artistflÃļde", - "home.artistsFeed.noArtist": "När du fÃļljer artister visas deras senaste releaser här.", - "home.madeForYou": "Skapat fÃļr dig", - "home.friendsListeningTo": "Vänner lyssnar pÃĨ", - "home.followedArtists": "FÃļljda artister", - // Errors - "error.appleMusicSubRequired": "Apple Music kräver en prenumeration.", - "error.connectionError": "OjdÃĨ. Det gick inte att ansluta till Apple Music.", - "error.noResults": "Inga träffar.", - "error.noResults.description": "Prova en ny sÃļkning.", - - //Podcasts - "podcast.followOnCider": "FÃļlj pÃĨ Cider", - "podcast.followedOnCider": "FÃļljer pÃĨ Cider", - "podcast.subscribeOnItunes": "FÃļlj pÃĨ iTunes", - "podcast.subscribedOnItunes": "FÃļljer pÃĨ iTunes", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "Avsnitt", - "podcast.playEpisode": "Spela avsnitt", - "podcast.website": "Öppna webbsida", - - // Actions - "action.addToLibrary": "Lägg till i bibliotek", - "action.addToLibrary.success": "Tillagd i biblioteket", - "action.addToLibrary.error": "Kunde inte lägga till i biblioteket", - "action.removeFromLibrary": "Radera frÃĨn biblioteket", - "action.removeFromLibrary.success": "Borttagen frÃĨn biblioteket", - "action.addToQueue": "Lägg till i kÃļ", - "action.addToQueue.success": "Tillagd i kÃļn", - "action.addToQueue.error": "Kunde inte lägga till i kÃļn", - "action.removeFromQueue": "Radera frÃĨn kÃļn", - "action.removeFromQueue.success": "Borttagen frÃĨn kÃļn", - "action.removeFromQueue.error": "Kunde inte lägga radera frÃĨn kÃļn", - "action.createPlaylist": "Skapa ny spellista", - "action.addToPlaylist": "Lägg till i en spellista", - "action.removeFromPlaylist": "Ta bort frÃĨn spellista", - "action.addToFavorites": "Lägg till i favoriter", - "action.follow": "FÃļlj", - "action.follow.success": "FÃļljd", - "action.follow.error": "Kunde inte fÃļlja", - "action.unfollow": "AvfÃļlj", - "action.unfollow.success": "AvfÃļljd", - "action.unfollow.error": "Kunde inte avfÃļlja", - "action.playNext": "Spela härnäst", - "action.playLater": "Spela upp sist", - "action.startRadio": "Skapa station", - "action.goToArtist": "Visa artist", - "action.goToAlbum": "Visa album", - "action.moveToTop": "Flytta hÃļgst upp", - "action.share": "Dela", - "action.rename": "Byt namn", - "action.love": "Älska", - "action.unlove": "Sluta älska", - "action.dislike": "Ogilla", - "action.undoDislike": "Sluta ogilla", - "action.showWebRemoteQR": "Cider fjärrkotroll", - "action.playTracksNext": "Spela ${app.selectedMediaItems.length} lÃĨtar härnäst", - "action.playTracksLater": "Spela ${app.selectedMediaItems.length} lÃĨtar sist", - "action.removeTracks": "Radera ${self.selectedItems.length} lÃĨtar frÃĨn kÃļn", - "action.import": "Importera", - "action.export": "Exportera", - "action.showAlbum": "Visa komplett album", - "action.tray.minimize": "DÃļlj Cider", - "action.tray.quit": "Avsluta", - "action.tray.show": "Visa Cider", - "action.update": "Uppdatera", - - // Settings - General - "settings.header.general": "Allmänt", - "settings.header.general.description": "Ändra Ciders allmänna inställningar.", - "settings.option.general.language": "SprÃĨk", - - // Language optgroups - "settings.option.general.language.main": "SprÃĨk", - "settings.option.general.language.fun": "Roliga sprÃĨk", - "settings.option.general.language.unsorted": "Osorterade", - - // Settings - Audio - "settings.header.audio": "Ljud", - "settings.header.audio.description": "Ändra Ciders ljudinställningar.", - "settings.option.audio.quality": "Ljudkvalitet", // Dropdown - "settings.header.audio.quality.high": "HÃļg", - "settings.header.audio.quality.low": "LÃĨg", - "settings.header.audio.quality.auto": "Automatisk", - "settings.option.audio.seamlessTransition": "SÃļmlÃļsa ljudÃļvergÃĨngar", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Aktivera avancerade ljudfunktioner", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Om du aktiverar avancerade ljudfunktioner kommer funktioner som ljudnormalisering, EQ och virtualisering aktiveras, men pÃĨ nÃĨgra system kan detta orsaka ljudproblem.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Ljudnormalisering", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliserar hÃļga ljudnivÃĨer fÃļr att fÃļrbättra ljudkvaliteten.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spiralljud", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "GÃļr ljudet mer 3D (Ej Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visuellt", - "settings.header.visual.description": "Ändra Ciders visuella inställningar.", - "settings.option.visual.windowBackgroundStyle": "Stil fÃļr bakgrunden", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Ingen", - "settings.header.visual.windowBackgroundStyle.artwork": "FrÃĨn omslagsbilden", - "settings.header.visual.windowBackgroundStyle.image": "Bild", - "settings.option.visual.animatedArtwork": "Animerad omslagsbild", // Dropdown - "settings.header.visual.animatedArtwork.always": "Alltid", - "settings.header.visual.animatedArtwork.limited": "Endast pÃĨ sidor där det behÃļvs", - "settings.header.visual.animatedArtwork.disable": "Aldrig", - "settings.option.visual.animatedArtworkQuality": "Kvalitet fÃļr animerad omslagsbild", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "LÃĨg", - "settings.header.visual.animatedArtworkQuality.medium": "Standard", - "settings.header.visual.animatedArtworkQuality.high": "HÃļg", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Väldigt hÃļg", - "settings.header.visual.animatedArtworkQuality.extreme": "Okomprimerat", - "settings.option.visual.animatedWindowBackground": "Animerad fÃļnsterbakgrund", // Toggle - "settings.option.visual.hardwareAcceleration": "HÃĨrdvaruacceleration", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "kräver omstart", - "settings.header.visual.hardwareAcceleration.default": "Standard", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Visa personlig information", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "LÃĨttext", - "settings.header.lyrics.description": "Ändra Ciders lÃĨttextsinställningar.", - "settings.option.lyrics.enableMusixmatch": "Använd Musixmatch istället fÃļr Apple Lyrics", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Aktivera karaokeläge (Endast Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "SprÃĨk fÃļr lÃĨttextsÃļversättning (Endast Musixmatch)", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Använd YouTube Lyrcis fÃļr videor", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Anslutning", - "settings.header.connectivity.description": "Ändra Ciders anslutningsinställningar.", - "settings.option.connectivity.discordRPC": "Discord integration (discordRPC)", // Dropdown - "settings.option.connectivity.playbackNotifications": "Uppspelningsnotiser", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "PÃĨ, visa som 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "PÃĨ, visa som 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Rensa Discord notiser frÃĨn Cider när du pausar", // Toggle - "settings.option.connectivity.lastfmScrobble": "Last.fm integration", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Last.fm fÃļrdrÃļjning i %", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Visa vad som spelas nu i Last.fm", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Visa inte extraartister i Last.fm", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrera bort loopade lÃĨtar i Last.fm", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "Experimentellt", - "settings.header.experimental.description": "Ändra Ciders experimentella inställningar.", - "settings.option.experimental.compactUI": "Kompakt gränssnitt", // Toggle - "settings.option.experimental.close_button_hide": "Stängknappen gÃļmmer Cider istället", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "Spiralljud är av. Akrtivera det fÃļrst.", - "spatial.spatialProperties": "Spiralljudsintällningar", - "spatial.width": "Bredd", - "spatial.height": "HÃļjd", - "spatial.depth": "Djup", - "spatial.gain": "Volym", - "spatial.roomMaterials": "Material av rum", - "spatial.roomDimensions": "MÃĨtt av rum", - "spatial.roomPositions": "Plats av rum", - "spatial.setDimensions": "Välj mÃĨtt", - "spatial.setPositions": "Välj platser", - "spatial.up": "Upp", - "spatial.front": "Fram", - "spatial.left": "Väsnter", - "spatial.right": "HÃļger", - "spatial.back": "BakÃĨt", - "spatial.down": "Ner", - "spatial.listener": "Lyssnare", - "spatial.audioSource": "Ljudkälla", - - // Settings - Unfinished - "settings.header.unfinished": "Ej tillgängligt", - - // Web Remote - "remote.web.title": "Cider fjärrkontroll", - "remote.web.description": "Skanna QR koden fÃļr att ansluta din telefon till Cider.", - - // About - "about.thanks": "Stort tack till Ciders Collective Team och alla som har bidragit!" -} diff --git a/src/i18n/tr_TR.jsonc b/src/i18n/tr_TR.jsonc deleted file mode 100644 index ead8ddfd..00000000 --- a/src/i18n/tr_TR.jsonc +++ /dev/null @@ -1,314 +0,0 @@ -{ - // i18n Info - "i18n.languageName": "TÃŧrkçe", // name of language in native language - "i18n.languageNameEnglish": "Turkish", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@gms10ur", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${d} ${m}, ${y}", - - // Dialogs - "dialog.cancel": "İptal", - "dialog.ok": "Tamam", - - // Notification - "notification.updatingLibrarySongs": "Arşiv'deki şarkÄąlar alÄąnÄąyor...", - "notification.updatingLibraryAlbums": "Arşiv'deki albÃŧmler alÄąnÄąyor...", - "notification.updatingLibraryArtists": "Arşiv'deki sanatÃ§Äąlar alÄąnÄąyor...", - - // Terms - "term.appleInc": "Apple", - "term.appleMusic": "Apple MÃŧzik", - "term.applePodcasts": "Apple Podcastler", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Daha fazla bilgi edin", - "term.accountSettings": "Hesap AyarlarÄą", - "term.logout": "Ã‡ÄąkÄąÅŸ Yap", - "term.login": "Giriş yap", - "term.about": "HakkÄąnda", - "term.privateSession": "Özel Oturum", - "term.queue": "Çalma SÄąrasÄą", - "term.search": "Arama", - "term.library": "Arşiv", - "term.listenNow": "Şimdi Dinle", - "term.browse": "GÃļz At", - "term.radio": "Radyo", - "term.recentlyAdded": "Son Eklenenler", - "term.songs": "ŞarkÄąlar", - "term.albums": "AlbÃŧmler", - "term.artists": "SanatÃ§Äąlar", - "term.podcasts": "Podcastler", - "term.playlists": "Listeler", - "term.playlist": "Liste", - "term.createNewPlaylist": "Yeni Liste Oluştur", - "term.createNewPlaylistFolder": "Yeni KlasÃļr Oluştur", - "term.newPlaylist": "Yeni Liste", - "term.newPlaylistFolder": "Yeni KlasÃļr", - "term.deletePlaylist": "Bu listeyi silmek istediğinize emin misiniz?", - "term.play": "Oynat", - "term.pause": "Duraklat", - "term.previous": "Önceki", - "term.next": "Sonraki", - "term.shuffle": "KarÄąÅŸtÄąr", - "term.repeat": "Tekrarla", - "term.volume": "Ses", - "term.mute": "Sustur", - "term.unmute": "Sesi Aç", - "term.share": "Paylaş", - "term.settings": "Ayarlar", - "term.seeAll": "TÃŧmÃŧnÃŧ GÃļr", - "term.sortBy": "SÄąrala", - "term.sortBy.album": "AlbÃŧm", - "term.sortBy.artist": "SanatÃ§Äą", - "term.sortBy.name": "ŞarkÄą İsmi", - "term.sortBy.genre": "TÃŧr", - "term.sortBy.releaseDate": "YayÄąnlanma Tarihi", - "term.sortBy.duration": "SÃŧre", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Çoğalan", - "term.sortOrder.descending": "Azalan", - "term.viewAs": "ŞÃļyle GÃļster", - "term.viewAs.coverArt": "AlbÃŧm Kapağı", - "term.viewAs.list": "Liste", - "term.size": "Boyut", - "term.size.normal": "Normal", - "term.size.compact": "Daha SÄąkÄą", - "term.enable": "Aç", - "term.disable": "Kapa", - "term.enabled": "AÃ§Äąk", - "term.disabled": "KapalÄą", - "term.connect": "Bağlan", - "term.connecting": "BağlanÄąyor", - "term.disconnect": "BağlantÄąyÄą Kes", - "term.authed": "BağlantÄą sağlandÄą", - "term.confirm": "Onayla?", - "term.more": "Daha Fazla", - "term.less": "Daha Az", - "term.showMore": "Daha Fazla GÃļster", - "term.showLess": "Daha Az GÃļster", - "term.topSongs" : "PopÃŧler Parçalar", - "term.latestReleases": "Yeni Ã‡Äąkan", - "term.time.added": "Şu tarihte eklendi: ", - "term.time.released": "Şu tarihte yayÄąnalndÄą: ", - "term.time.updated": "Şu tarihte gÃŧncellendi: ", - "term.fullscreenView": "Tam Ekrana Geç", - "term.defaultView": "Normal GÃļrÃŧnÃŧme DÃļn", - "term.spacializedAudioSetting": "Uzamsal Ses AyarlarÄą", - "term.audioSettings": "Ses AyarlarÄą", - "term.clearAll": "TÃŧmÃŧnÃŧ Temizle", - "term.recentStations": "Son İstasyonlar", - "term.language": "Dil", - "term.funLanguages": "Mizahi Diller", - "term.noLyrics": "YÃŧkleniyor... / ŞarkÄą SÃļzÃŧ BulunamadÄą./ Enstrumantal.", - "term.copyright": "Copyright", - "term.rightsReserved": "TÃŧm HaklasÄą SaklÄądÄąr.", - "term.sponsor": "Bu Projeye Destek Olun", - "term.ciderTeam": "Cider Ekibi", - "term.developer": "Geliştirici", - "term.socialTeam": "Sosyal Ekip", - "term.socials": "Cider Topluluğu", - "term.contributors": "KatkÄąda Bulunanlar", - "term.equalizer": "Ekolayzer", - "term.reset": "SÄąfÄąrla", - "term.tracks": "adet şarkÄą", // Assume x amount of tracks. e.g. 50 tracks - "term.time.hours": "saat", - "term.time.hour": "saat", - "term.time.minutes": "dakika", - "term.time.minute": "dakika", - "term.time.seconds": "saniye", - "term.time.second": "saniye", - "term.videos": "Video Klipler", - "term.menu": "MenÃŧ", - - // Home - "home.title": "Ana Sayfa", - "home.recentlyPlayed": "Son OynatÄąlanlar", - "home.recentlyAdded": "Son Eklenenler", - "home.artistsFeed": "Son Ã‡Äąkanlar", - "home.artistsFeed.noArtist": "Birkaç sanatÃ§Äą takip ettiğinizde, sanatÃ§ÄąlarÄąnÄązÄąn son Ã§Äąkan yayÄąnlarÄą burada gÃļzÃŧkÃŧr.", - "home.madeForYou": "Sadece Size Özel", - "home.friendsListeningTo": "ArkadaşlarÄąnÄązÄąn Dinledikleri", - "home.followedArtists": "Takip Edilen SanatÃ§Äąlar", - - // Errors - "error.appleMusicSubRequired": "Apple MÃŧzik, aktif bir abonelik gerektirir.", - "error.connectionError": "Apple MÃŧzik ile bağlantÄą kurulamadÄą.", - "error.noResults": "Hiç sonuç yok", - "error.noResults.description": "Tekrar deneyin.", - - //Podcasts - "podcast.followOnCider": "Cider'de Takip Et", - "podcast.followedOnCider": "Cider'de Takip Ediliyor", - "podcast.subscribeOnItunes": "itunes'de Abone Ol", - "podcast.subscribedOnItunes": "iTunes'de Abone Olundu", - "podcast.itunesStore": "iTunes MağazasÄą", - "podcast.episodes": "BÃļlÃŧmler", - "podcast.playEpisode": "BÃļlÃŧmÃŧ Oynat", - "podcast.website": "Web SayfasÄą", - - // Actions - "action.addToLibrary": "Arşiv'e Ekle", - "action.addToLibrary.success": "Arşiv'e Eklendi", - "action.addToLibrary.error": "Arşiv'e Eklenemedi", - "action.removeFromLibrary": "Arşiv'den Sil", - "action.removeFromLibrary.success": "Arşiv'den Silindi", - "action.createPlaylist": "Yeni Liste Oluştur", - "action.addToPlaylist": "Liste'ye Ekle", - "action.removeFromPlaylist": "Liste'den Sil", - "action.addToFavorites": "Favorilere Ekle", - "action.moveToTop": "En Başa TaÅŸÄą", - "action.rename": "Yeniden AdlandÄąr", - "action.addToQueue": "SÄąraya Ekle", - "action.addToQueue.success": "SÄąraya Eklendi", - "action.addToQueue.error": "SÄąraya Eklenemedi", - "action.removeFromQueue": "SÄąradan KaldÄąr", - "action.removeFromQueue.success": "SÄąradan KaldÄąrÄąldÄą", - "action.removeFromQueue.error": "SÄąradan KaldÄąrÄąlamadÄą", - "action.follow": "Takip Et", - "action.follow.success": "Takip Ediliyor", - "action.follow.error": "Takip Edilemedi", - "action.unfollow": "Takibi BÄąrak", - "action.unfollow.success": "Takipten Ã‡ÄąkÄąldÄą", - "action.unfollow.error": "Takipten Ã‡ÄąkÄąlamadÄą", - "action.playNext": "SÄąradaki Yap", - "action.playLater": "En Son Çal", - "action.startRadio": "İstasyon Yarat", - "action.goToArtist": "SanatÃ§Äąya Git", - "action.goToAlbum": "AlbÃŧme Git", - "action.share": "Paylaş", - "action.love": "Beğen", - "action.unlove": "Beğeniyi KaldÄąr", - "action.dislike": "Bunun Gibileri Daha Az Öner", - "action.undoDislike": "Bunun Gibileri Daha Az Önermeyi Geri Al", - "action.showWebRemoteQR": "Uzaktan Kumanda Bağla", - "action.playTracksNext": "${app.selectedMediaItems.length} adet şarkÄąyÄą sÄąraya ekle", - "action.playTracksLater": "${app.selectedMediaItems.length} adet şarkÄąyÄą sÄąranÄąn en sonuna ekle", - "action.removeTracks": "SÄąradan ${self.selectedItems.length} adet şarkÄąyÄą kaldÄąr", - "action.import": "Import", - "action.export": "Export", - "action.showAlbum": "TÃŧm AlbÃŧmÃŧ GÃļster", - "action.tray.minimize": "GÃļrev Çubuğuna KÃŧçÃŧlt", - "action.tray.quit": "'den Ã‡Äąk", - "action.tray.show": "'i GÃļster", - - // Settings - General - "settings.header.general": "Genel Ayarlar", - "settings.header.general.description": "Genel ayarlarÄą buradan dÃŧzenleyin.", - "settings.option.general.language": "Dil Seçeneği", - - // Language optgroups - "settings.option.general.language.main": "Gerçek Diller", - "settings.option.general.language.fun": "Mizahi Diller", - "settings.option.general.language.unsorted": "HenÃŧz TamamlanmamÄąÅŸ Diller", - - // Settings - Audio - "settings.header.audio": "Çalma / Oynatma", - "settings.header.audio.description": "Cider'in sizin için en iyi dinleme deneyimini sağlayabilmesi için ses ayarlarÄąnÄązÄą yapÄąn.", - "settings.option.audio.quality": "Ses Kalitesi", // Dropdown - "settings.header.audio.quality.high": "YÃŧksek Kalite", - "settings.header.audio.quality.low": "YÃŧksek Verimlilik", - "settings.header.audio.quality.auto": "Otomatik", - "settings.option.audio.seamlessTransition": "Kesintisiz Ses Geçişi", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Gelişmiş Ses Deneyimi", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Gelişmiş ses deneyiminin etkinleştirilmesi, Ses Normalleştirme, Ekolayzer ve GÃļrselleştirici gibi genişletilmiş ses Ãļzelliklerine izin verir, ancak bu durum bazÄą sistemlerde seste bozulmalara neden olabilir.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Ses Normalleştirme", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Ses normalleştirme alçak ve yÃŧksek sesli şarkÄąlarÄą dengeler ve daha dÃŧzgÃŧn bir dinleme deneyimi sağlar.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Uzamsal Ses", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Sesi uzamsallaştÄąrÄąn ve sesi daha 3 boyutlu hale getirin (not: Bu Dolby Atmos değildir)", - - // Settings - Visual - "settings.header.visual": "GÃļrÃŧnÃŧm", - "settings.header.visual.description": "Cider'in nasÄąl gÃļzÃŧkmesini istediğinizi ayarlayÄąn", - "settings.option.visual.windowBackgroundStyle": "Uygulama Arka Plan Stili", // Toggle - "settings.header.visual.windowBackgroundStyle.image": "GÃļrsel", - "settings.header.visual.windowBackgroundStyle.none": "KaranlÄąk", - "settings.header.visual.windowBackgroundStyle.artwork": "AlbÃŧm Kapağı", - "settings.option.visual.animatedArtwork": "Hareketli AlbÃŧm KapaklarÄą", // Dropdown - "settings.header.visual.animatedArtwork.always": "Her Zaman AÃ§Äąk", - "settings.header.visual.animatedArtwork.limited": "BazÄą Sayfalara ve Özel BÃļlgelerle SÄąnÄąrlÄą", - "settings.header.visual.animatedArtwork.disable": "Her Zaman KapalÄą", - "settings.option.visual.animatedArtworkQuality": "Hareketli AlbÃŧm Kapağı Kalitesi", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "DÃŧşÃŧk", - "settings.header.visual.animatedArtworkQuality.medium": "Orta", - "settings.header.visual.animatedArtworkQuality.high": "YÃŧksek", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Daha YÃŧksek", - "settings.header.visual.animatedArtworkQuality.extreme": "Ekstrem", - "settings.option.visual.animatedWindowBackground": "Hareketli Uygulama Arka PlanÄą", // Toggle - "settings.option.visual.hardwareAcceleration": "DonanÄąm HÄązlandÄąrmasÄą", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "Etki etmesi için uygulamayÄą yeniden başlatmak gerekir.", - "settings.header.visual.hardwareAcceleration.default": "VarsayÄąlan", - "settings.header.visual.hardwareAcceleration.webGPU": "Gelişmiş", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "KullanÄącÄą AdÄąmÄą GÃļster", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "ŞarkÄą SÃļzleri", - "settings.header.lyrics.description": "Cider'in şarkÄą sÃļzlerini nasÄąl gÃļrÃŧntÃŧlemesini istediğini buradan ayarlayÄąn.", - "settings.option.lyrics.enableMusixmatch": "Musixmatch Kullan", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Karaoke Modunu Etkinleştir (Sadece Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch için Otomatik Çeviri Dili", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "MÃŧzik VideolarÄą için ŞarkÄą SÃļzÃŧnÃŧ YouTube'dan Al", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "Diğer Servisler", - "settings.header.connectivity.description": "Cider'i diğer servislere bağlayarak deneyiminizi zenginleştirin.", - "settings.option.connectivity.discordRPC": "Ne Dinlediğimi Discord'da GÃļster", // Dropdown - "settings.option.connectivity.playbackNotifications": "OynatÄąlan değiştiğinde bildirim gÃļster", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "'Cider' Olarak", - "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music' Olarak", - "settings.option.connectivity.discordRPC.clearOnPause": "DuraklatÄąldığında Discord'da GÃļsterme", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM BağlantÄąsÄą", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobblalma YÃŧzdesi (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Şimdi çalan şarkÄąyÄą LastFM'de gÃļster", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "AlbÃŧm sanatÃ§ÄąsÄąnÄą Scrobbledan kaldÄąr(LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Tekrar edilen şarkÄąyÄą filtrele (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "Deneysel", - "settings.header.experimental.description": "Cider'deki deneysel Ãļzelliklere erişim sağlayÄąn. (Not: BazÄą Ãļzellikler dÃŧzgÃŧn çalÄąÅŸmayabilir.)", - "settings.option.experimental.compactUI": "Kompakt ArayÃŧz", // Toggle - "settings.option.experimental.closeButtonBehaviour": "Kapat dÃŧğmesi davranÄąÅŸÄą", - "settings.option.experimental.closeButtonBehaviour.quit": "Cider'den Ã§Äąk", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "Simge durumuna kÃŧçÃŧlt", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "GÃļrev çubuğuna kÃŧçÃŧlt", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "Uzamsal ses devre dÄąÅŸÄą. Kullanabilmek için lÃŧtfen Ãļnce etkinleştirin.", - "spatial.spatialProperties" : "Uzamsal Özellikler", - "spatial.width" : "Genişlik", - "spatial.height" : "YÃŧkseklik", - "spatial.depth" : "Derinlik", - "spatial.roomMaterials" : "Oda Materyalleri", - "spatial.roomDimensions" : "Oda ÖlçÃŧleri", - "spatial.roomPositions" : "Oda Pozisyonu", - "spatial.setDimensions" : "ÖlçÃŧleri Ayarla", - "spatial.setPositions" : "Pozisyonu Ayarla", - "spatial.up" : "Üst", - "spatial.front" : "Ön", - "spatial.left" : "Sol", - "spatial.right" : "Sağ", - "spatial.back" : "Arka", - "spatial.down" : "Aşağı", - "spatial.listener" : "Dinleyici", - "spatial.audioSource" : "Ses Kaynağı", - "spatial.gain" : "Kazanç", - - // Settings - Unfinished - "settings.header.unfinished": "Geliştirme AşamasÄąnda", - - // Web Remote - "remote.web.title": "Cider'e Bağlan", - "remote.web.description": "Telefonunuzu Bu Cider Oturumuyla Eşleştirmek için QR Kodunu TarayÄąn", - - //About - "about.thanks": "Cider Collective Ekibine ve tÃŧm katkÄąda bulunanlara çok teşekkÃŧr ederiz." - -} \ No newline at end of file diff --git a/src/i18n/zh_CN.jsonc b/src/i18n/zh_CN.jsonc deleted file mode 100644 index 1adbf1ae..00000000 --- a/src/i18n/zh_CN.jsonc +++ /dev/null @@ -1,306 +0,0 @@ -{ - // App info - "app.name": "Cider", - - "date.format": "${y}åš´${m}月${d}æ—Ĩ", - - // i18n Info - "i18n.languageName": "įŽ€äŊ“中文īŧˆä¸­å›Ŋīŧ‰", // name of language in native language - "i18n.languageNameEnglish": "Simp. Chinese (China)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@maikirakiwi @BillKerman", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // Dialogs - "dialog.cancel": "取æļˆ", - "dialog.ok": "įĄŽåŽš", - - // Notification - "notification.updatingLibrarySongs": "æ­Ŗåœ¨æ›´æ–°čĩ„æ–™åē“įš„æ­Œæ›˛äŋĄæ¯...", - "notification.updatingLibraryAlbums": "æ­Ŗåœ¨æ›´æ–°čĩ„æ–™åē“įš„ä¸“čž‘äŋĄæ¯...", - "notification.updatingLibraryArtists": "æ­Ŗåœ¨æ›´æ–°čĩ„æ–™åē“įš„č‰ēäēēäŋĄæ¯...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", // Follows brand term - "term.applePodcasts": "Apple Podcasts", // Follows brand term - "term.itunes": "iTunes", // Follows brand term - "term.github": "GitHub", // Follows brand term - "term.discord": "Discord", // Follows brand term - "term.learnMore": "更多äŋĄæ¯", - "term.accountSettings": "č´ĻæˆˇčŽžįŊŽ", - "term.logout": "į™ģå‡ē", - "term.login": "į™ģåŊ•", - "term.about": "å…ŗäēŽ", - "term.privateSession": "ᧁäēē聆åŦ", - "term.queue": "垅播清单", - "term.search": "搜į´ĸ", - "term.library": "čĩ„æ–™åē“", - "term.listenNow": "įŽ°åœ¨å°ąåŦ", - "term.browse": "æĩč§ˆ", - "term.radio": "åšŋ播", - "term.recentlyAdded": "最čŋ‘æˇģ加", - "term.songs": "æ­Œæ›˛", - "term.albums": "专辑", - "term.artists": "č‰ēäēē", - "term.podcasts": "播åŽĸ", - "term.playlists": "æ’­æ”žåˆ—čĄ¨", - "term.playlist": "æ’­æ”žåˆ—čĄ¨", - "term.newPlaylist": "æ–°æ’­æ”žåˆ—čĄ¨", - "term.newPlaylistFolder": "æ–°æ’­æ”žåˆ—čĄ¨æ–‡äģļ多", - "term.createNewPlaylist": "新åģēæ’­æ”žåˆ—襨", - "term.createNewPlaylistFolder": "新åģēæ’­æ”žåˆ—čĄ¨æ–‡äģļ多", - "term.deletePlaylist": "æ‚¨įĄŽåŽščĻåˆ é™¤č¯Ĩæ’­æ”žåˆ—čĄ¨å—?", - "term.play": "播攞", - "term.pause": "暂停", - "term.previous": "上一éĻ–", - "term.next": "下一éĻ–", - "term.shuffle": "随æœē播攞", - "term.repeat": "重复播攞", - "term.volume": "éŸŗé‡", - "term.mute": "é™éŸŗ", - "term.unmute": "č§Ŗé™¤é™éŸŗ", - "term.share": "分äēĢ", - "term.settings": "莞įŊŽ", - "term.seeAll": "æŸĨįœ‹å…¨éƒ¨", - "term.sortBy": "排åē", - "term.sortBy.album": "专辑", - "term.sortBy.artist": "č‰ēäēē", - "term.sortBy.name": "歌名", - "term.sortBy.genre": "įąģ型", - "term.sortBy.releaseDate": "å‘čĄŒæ—Ĩ期", - "term.sortBy.duration": "æ—ļé•ŋ", - "term.sortOrder": "字母排åē", - "term.sortOrder.ascending": "升åē", - "term.sortOrder.descending": "倒åē", - "term.viewAs": "昞į¤ēæ¨Ąåŧ", - "term.viewAs.coverArt": "ä¸“čž‘å°éĸ", - "term.viewAs.list": "åˆ—čĄ¨", - "term.size": "大小", - "term.size.normal": "æ­Ŗå¸¸", - "term.size.compact": "ᴧ凑", - "term.enable": "吝ᔍ", - "term.disable": "įρᔍ", - "term.enabled": "厞吝ᔍ", - "term.disabled": "厞įρᔍ", - "term.connect": "čŋžæŽĨ", - "term.connecting": "čŋžæŽĨ中", - "term.disconnect": "断åŧ€", - "term.authed": "åˇ˛čŽ¤č¯", - "term.confirm": "įĄŽčŽ¤īŧŸ", - "term.more": "更多", - "term.less": "čžƒå°‘", - "term.showMore": "昞į¤ē更多", - "term.showLess": "昞į¤ē更少", - "term.topSongs" : "įƒ­é—¨æ­Œæ›˛", - "term.latestReleases": "æœ€æ–°å‘čĄŒ", - "term.time.added": "æˇģ加äēŽ", - "term.time.released": "å‘čĄŒäēŽ", - "term.time.updated": "更新äēŽ", - "term.time.hours": "小æ—ļ", - "term.time.hour": "小æ—ļ", - "term.time.minutes": "分钟", - "term.time.minute": "分钟", - "term.time.seconds": "į§’", - "term.time.second": "į§’", - "term.fullscreenView": "å…¨åą", - "term.defaultView": "éģ˜čޤ", - "term.audioSettings": "韺éĸ‘莞įŊŽ", - "term.spacializedAudioSetting": "韺éĸ‘įŠēé—´åŒ–čŽžįŊŽ", - "term.clearAll": "清įŠē", - "term.recentStations": "最čŋ‘æ’­æ”žįš„éĸ‘道", - "term.language": "蝭荀", - "term.funLanguages": "æļ搞", - "term.noLyrics": "加čŊŊ中... / 搜į´ĸ无į쓿žœ / įē¯éŸŗäš", - "term.copyright": "į‰ˆæƒæ‰€æœ‰", - "term.rightsReserved": "äŋį•™æ‰€æœ‰æƒåˆŠã€‚", - "term.sponsor": "čĩžåŠŠ", - "term.ciderTeam": "Cider å›ĸ队", - "term.developer": "åŧ€å‘者", - "term.socialTeam": "åĒ’äŊ“å›ĸ队", - "term.contributors": "č´ĄįŒŽč€…", - "term.equalizer": "å‡čĄĄå™¨", - "term.reset": "重įŊŽ", - "term.tracks": "éĻ–æ­Œæ›˛", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "视éĸ‘", - "term.menu": "čœå•", - "term.check": "æŖ€æŸĨ", - "term.aboutArtist": "å…ŗäēŽ{{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "更新 Cider", - - // Home - "home.title": "ä¸ģéĄĩ", - "home.recentlyPlayed": "最čŋ‘播攞", - "home.recentlyAdded": "最čŋ‘æˇģ加", - "home.artistsFeed": "č‰ēäēēæŽ¨č", - "home.artistsFeed.noArtist": "å…ŗæŗ¨æ‚¨å–œįˆąįš„č‰ēäēē后äžŋ可æŸĨįœ‹äģ–äģŦįš„æœ€æ–°å‘čĄŒæ­Œæ›˛ã€‚", - "home.madeForYou": "ä¸“åąžæŽ¨č", - "home.friendsListeningTo": "æœ‹å‹æ­Ŗåœ¨åŦ", - "home.followedArtists": "å…ŗæŗ¨įš„č‰ēäēē", - - // Errors - "error.appleMusicSubRequired": "需čρčŽĸ阅 Apple Music äģĨäŊŋᔍ Cider", - "error.connectionError": "æ— æŗ•čŋžæŽĨ到 Apple Music。", - "error.noResults": "æ˛Ąæœ‰į쓿žœã€‚", - "error.noResults.description": "å°č¯•æ›´æ”šæœį´ĸæĄäģļ。", - - //Podcasts - "podcast.followOnCider": "在 Cider ä¸­å…ŗæŗ¨", - "podcast.followedOnCider": "åˇ˛å…ŗæŗ¨", - "podcast.subscribeOnItunes": "在 iTunes 上čŽĸ阅", - "podcast.subscribedOnItunes": "厞čŽĸ阅", - "podcast.itunesStore": "iTunes Store", // Follow brand term - "podcast.episodes": "单集", - "podcast.playEpisode": "播攞单集", - "podcast.website": "Podcast įŊ‘įĢ™", - - - // Actions - "action.addToLibrary": "加å…Ĩčĩ„æ–™åē“", - "action.addToLibrary.success": "成功加å…Ĩčĩ„æ–™åē“", - "action.addToLibrary.error": "加å…Ĩčĩ„æ–™åē“įš„čŋ‡į¨‹å‘į”Ÿäē†é”™č¯¯", - "action.removeFromLibrary": "äģŽčĩ„æ–™åē“中į§ģ除", - "action.removeFromLibrary.success": "厞äģŽčĩ„æ–™åē“中į§ģ除", - "action.addToQueue": "加å…Ĩ垅播清单", - "action.addToQueue.success": "成功加å…Ĩ垅播清单", - "action.addToQueue.error": "加å…Ĩåž…æ’­æ¸…å•įš„čŋ‡į¨‹å‘į”Ÿäē†é”™č¯¯", - "action.removeFromQueue": "äģŽåž…播清单中į§ģ除", - "action.removeFromQueue.success": "厞äģŽåž…播清单中į§ģ除", - "action.removeFromQueue.error": "äģŽåž…播清单中į§ģé™¤įš„čŋ‡į¨‹å‘į”Ÿäē†é”™č¯¯", - "action.createPlaylist": "新åģēæ’­æ”žåˆ—襨", - "action.addToPlaylist": "加å…Ĩæ’­æ”žåˆ—čĄ¨", - "action.removeFromPlaylist": "äģŽæ’­æ”žåˆ—襨中į§ģ除", - "action.addToFavorites": "åŠ č‡ŗæ”ļ藏", - "action.follow": "å…ŗæŗ¨", - "action.follow.success": "åˇ˛å…ŗæŗ¨", - "action.follow.error": "å°č¯•å…ŗæŗ¨įš„čŋ‡į¨‹å‘į”Ÿäē†é”™č¯¯", - "action.unfollow": "取æļˆå…ŗæŗ¨", - "action.unfollow.success": "åˇ˛å–æļˆå…ŗæŗ¨", - "action.unfollow.error": "å°č¯•å–æļˆå…ŗæŗ¨įš„čŋ‡į¨‹å‘į”Ÿäē†é”™č¯¯", - "action.playNext": "插播", - "action.playLater": "最后播攞", - "action.startRadio": "åŧ€å§‹į”ĩ台", - "action.goToArtist": "前垀č‰ēäēē", - "action.goToAlbum": "å‰åž€ä¸“čž‘", - "action.moveToTop": "į§ģ到éĄļ部", - "action.share": "分äēĢæ­Œæ›˛", - "action.rename": "重å‘Ŋ名", - "action.love": "喜æŦĸ", - "action.unlove": "踊", - "action.dislike": "减少此įąģåģē莎", - "action.undoDislike": "撤销减少此įąģåģē莎", - "action.showWebRemoteQR": "昞į¤ēčŋœį¨‹æŽ§åˆļįš„äēŒįģ´į ", - "action.playTracksNext": "插播 ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.playTracksLater": "最后播攞 ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.removeTracks": "äģŽåž…播清单中į§ģ除 ${self.selectedItems.length} éĻ–æ­Œæ›˛", - "action.import": "å¯ŧå…Ĩ", - "action.export": "å¯ŧå‡ē", - "action.showAlbum": "昞į¤ē专辑", - "action.tray.minimize": "最小化", - "action.tray.quit": "退å‡ē", - "action.tray.show": "昞į¤ē", - "action.update": "更新", - - - // Settings - Audio - "settings.header.audio": "韺éĸ‘", - "settings.header.audio.description": "č°ƒæ•´ Cider įš„éŸŗéĸ‘莞įŊŽ", - "settings.option.audio.quality": "韺贍", // Dropdown - "settings.header.audio.quality.high": "é̘韺贍", - "settings.header.audio.quality.low": "éĢ˜æ•ˆįŽ‡", - "settings.header.audio.quality.auto": "č‡Ē动", - "settings.option.audio.seamlessTransition": "无įŧæ’­æ”ž", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "čŋ›é˜ļ功čƒŊ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "吝ᔍ AudioContext å°†č§Ŗé”äž‹åĻ‚éŸŗé‡æ ‡å‡†åŒ–å’ŒéŸŗéĸ‘įŠēé—´åŒ–įš„åŠŸčƒŊīŧŒäŊ†å¯čƒŊäŧšåœ¨å°éƒ¨åˆ†čŽžå¤‡ä¸Šå‡ēįŽ°éŸŗéĸ‘ä¸Šįš„åĄéĄŋ。", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "éŸŗé‡æ ‡å‡†åŒ–", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "äŊŋ所感įŸĨåˆ°įš„éŸŗéĸ‘响åēĻįģŸä¸€", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "韺éĸ‘įŠē间化", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "äŊŋ所感įŸĨåˆ°įš„éŸŗéĸ‘更有įĢ‹äŊ“感 (æŗ¨: čŋ™ä¸æ˜¯æœæ¯”å…¨æ™¯åŖ°)", - // Settings - Visual - "settings.header.visual": "外观", - "settings.header.visual.description": "č°ƒæ•´ Cider įš„å¤–č§‚", - "settings.option.visual.windowBackgroundStyle": "įĒ—åŖčƒŒæ™¯æ ˇåŧ", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "无", - "settings.header.visual.windowBackgroundStyle.artwork": "ä¸“čž‘å°éĸ", - "settings.header.visual.windowBackgroundStyle.image": "回像", - "settings.option.visual.animatedArtwork": "åŠ¨æ€ä¸“čž‘å°éĸ", // Dropdown - "settings.header.visual.animatedArtwork.always": "æ€ģ是昞į¤ē", - "settings.header.visual.animatedArtwork.limited": "åĒ在č‰ēäēēéĄĩéĸå’Œä¸“čž‘å°éĸ昞į¤ē", - "settings.header.visual.animatedArtwork.disable": "å…ŗé—­", - "settings.option.visual.animatedArtworkQuality": "åŠ¨æ€ä¸“čž‘å°éĸį”ģč´¨", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "äŊŽ", - "settings.header.visual.animatedArtworkQuality.medium": "中", - "settings.header.visual.animatedArtworkQuality.high": "é̘", - "settings.header.visual.animatedArtworkQuality.veryHigh": "非常é̘", - "settings.header.visual.animatedArtworkQuality.extreme": "极é̘", - "settings.option.visual.animatedWindowBackground": "动态įĒ—åŖčƒŒæ™¯", // Toggle - "settings.option.visual.hardwareAcceleration": "įĄŦäģļ加速", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "需čĻé‡å¯ Cider 才äŧšį”Ÿæ•ˆ", - "settings.header.visual.hardwareAcceleration.default": "éģ˜čޤ", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "昞į¤ēä¸Ēäēēčĩ„æ–™", // Toggle - // Settings - General (Reserved) - "settings.header.general": "é€šį”¨", - "settings.header.general.description": "č°ƒæ•´ Cider įš„é€šį”¨čŽžįŊŽ", - - // Settings - Lyrics - "settings.header.lyrics": "æ­Œč¯", - "settings.header.lyrics.description": "č°ƒæ•´ Cider įš„æ­Œč¯čŽžįŊŽ", - "settings.option.lyrics.enableMusixmatch": "吝ᔍ Musixmatch æ­Œč¯", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "å¯į”¨åĄæ‹‰ OK æ¨Ąåŧīŧˆäģ… Musixmatchīŧ‰", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch æ­Œč¯č¯­č¨€ååĨŊ", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "播攞 MV æ—ļäŊŋᔍ YouTube æ­Œč¯", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "外部čŋžæŽĨ", - "settings.header.connectivity.description": "č°ƒæ•´Cider与外部åē”į”¨įš„äē¤äē’莞įŊŽ", - "settings.option.connectivity.discordRPC": "Discord 动态", // Dropdown - "settings.option.connectivity.playbackNotifications": "播攞通įŸĨ", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "昞į¤ēæ­Ŗåœ¨ 'Cider' 上聆åŦ", - "settings.header.connectivity.discordRPC.appleMusic": "昞į¤ēæ­Ŗåœ¨ 'Apple Music' 上聆åŦ", - "settings.option.connectivity.discordRPC.clearOnPause": "暂停æ—ļ清除 Discord 动态", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 莰åŊ•", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble åģļčŋŸ (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "吝ᔍ LastFM æ­Ŗåœ¨æ’­æ”ž", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "äģŽæ­Œåé‡ŒåŽģ除合äŊœč€… (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "不记åŊ•å•æ›˛åžĒįŽ¯ (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "厞éĒŒæ€§åŠŸčƒŊ", - "settings.header.experimental.description": "č°ƒæ•´Ciderįš„åŽžéĒŒæ€§åŠŸčƒŊ", - "settings.option.experimental.compactUI": "į´§å‡‘åž‹ UI", // Toggle - "settings.option.experimental.close_button_hide": "į‚šå‡ģå…ŗé—­æŒ‰é’Žæ—ļäģ…éšč—įĒ—åŖ", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "韺éĸ‘įŠē间化功čƒŊčĸĢįρᔍīŧŒäŊŋį”¨å‰č¯ˇå…ˆå¯į”¨ã€‚", - "spatial.spatialProperties" : "įŠēé—´åąžæ€§", - "spatial.width" : "åŽŊåēĻ", - "spatial.height" : "é̘åēĻ", - "spatial.depth" : "æˇąåēĻ", - "spatial.gain": "åĸžį›Š", - "spatial.roomMaterials" : "įŠēé—´æč´¨", - "spatial.roomDimensions" : "įŠē间å°ē寸", - "spatial.roomPositions" : "įŠē间äŊįŊŽ", - "spatial.setDimensions" : "莞įŊŽå°ē寸", - "spatial.setPositions" : "莞įŊŽäŊįŊŽ", - "spatial.up" : "上", - "spatial.front" : "前", - "spatial.left" : "åˇĻ", - "spatial.right" : "åŗ", - "spatial.back" : "后", - "spatial.down" : "下", - "spatial.listener" : "您", - "spatial.audioSource" : "韺æē", - - // Settings - Unfinished - "settings.header.unfinished": "æœĒ厌成", - - // Web Remote - "remote.web.title": "Cider čŋœį¨‹æŽ§åˆļ", - "remote.web.description": "æ‰Ģ描äģĨä¸‹įš„äēŒįģ´į äģĨ控åˆļ Cider", - - //About - "about.thanks": "郑重感č°ĸ Cider Collective äģĨ及ä¸ēčŋ™ä¸ĒéĄšį›Žæäž›æ”¯æŒįš„č´ĄįŒŽč€…ã€‚" -} diff --git a/src/i18n/zh_HK.jsonc b/src/i18n/zh_HK.jsonc deleted file mode 100644 index f15099cf..00000000 --- a/src/i18n/zh_HK.jsonc +++ /dev/null @@ -1,307 +0,0 @@ -{ - - // i18n Info - "i18n.languageName": "įšéĢ”ä¸­æ–‡īŧˆéĻ™æ¸¯īŧ‰", // name of language in native language - "i18n.languageNameEnglish": "Trad. Chinese (Hong Kong)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@kyw504100 @maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${y}åš´${m}月${d}æ—Ĩ", - - // Dialogs - "dialog.cancel": "取æļˆ", - "dialog.ok": "įĸēčĒ", - - // Notification - "notification.updatingLibrarySongs": "æ­Ŗåœ¨æ›´æ–°čŗ‡æ–™åēĢįš„æ­Œæ›˛...", - "notification.updatingLibraryAlbums": "æ­Ŗåœ¨æ›´æ–°čŗ‡æ–™åēĢįš„å°ˆčŧ¯...", - "notification.updatingLibraryArtists": "æ­Ŗåœ¨æ›´æ–°čŗ‡æ–™åēĢįš„č—äēē...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", // Follows brand term - "term.applePodcasts": "Apple Podcasts", // Follows brand term - "term.itunes": "iTunes", // Follows brand term - "term.github": "GitHub", // Follows brand term - "term.discord": "Discord", // Follows brand term - "term.learnMore": "äē†č§Ŗæ›´å¤š", - "term.accountSettings": "å¸ŗč™Ÿč¨­åŽš", - "term.logout": "į™ģå‡ē", - "term.login": "į™ģå…Ĩ", - "term.about": "關æ–ŧ", - "term.privateSession": "ᧁäē翍Ąåŧ", - "term.queue": "垅播清喎", - "term.search": "搜尋", - "term.library": "čŗ‡æ–™åēĢ", - "term.listenNow": "įĢ‹åŗč†čŊ", - "term.browse": "į€čĻŊ", - "term.radio": "åģŖæ’­", - "term.recentlyAdded": "最čŋ‘加å…Ĩ", - "term.songs": "æ­Œæ›˛", - "term.albums": "專čŧ¯", - "term.artists": "藝äēē", - "term.podcasts": "Podcasts", - "term.playlists": "æ’­æ”žåˆ—čĄ¨", - "term.playlist": "æ’­æ”žåˆ—čĄ¨", - "term.newPlaylist": "æ–°æ’­æ”žåˆ—čĄ¨", - "term.newPlaylistFolder": "æ–°æ’­æ”žåˆ—čĄ¨čŗ‡æ–™å¤ž", - "term.createNewPlaylist": "新åģēæ’­æ”žåˆ—襨", - "term.createNewPlaylistFolder": "新åģēæ’­æ”žåˆ—čĄ¨čŗ‡æ–™å¤ž", - "term.deletePlaylist": "æ‚¨įĄŽåŽščĻåˆ é™¤č¯Ĩæ’­æ”žåˆ—čĄ¨å—?", - "term.play": "播攞", - "term.pause": "æšĢ停", - "term.previous": "上一éĻ–", - "term.next": "下一éĻ–", - "term.shuffle": "隨抟播攞", - "term.repeat": "é‡č¤‡æ’­æ”ž", - "term.volume": "éŸŗé‡", - "term.mute": "éœéŸŗ", - "term.unmute": "取æļˆéœéŸŗ", - "term.share": "分äēĢ", - "term.settings": "č¨­åŽš", - "term.seeAll": "éĄ¯į¤ē全部", - "term.sortBy": "排åē", - "term.sortBy.album": "專čŧ¯", - "term.sortBy.artist": "藝äēē", - "term.sortBy.name": "歌名", - "term.sortBy.genre": "éŸŗæ¨‚éĸ¨æ ŧ", - "term.sortBy.releaseDate": "į™ŧ行æ—Ĩ期", - "term.sortBy.duration": "æ™‚é•ˇ", - "term.sortOrder": "字母排åē", - "term.sortOrder.ascending": "順åē", - "term.sortOrder.descending": "倒åē", - "term.viewAs": "éĄ¯į¤ēæ¨Ąåŧ", - "term.viewAs.coverArt": "專čŧ¯å°éĸ", - "term.viewAs.list": "åˆ—čĄ¨", - "term.size": "大小", - "term.size.normal": "æ­Ŗå¸¸", - "term.size.compact": "įˇŠå‡‘", - "term.enable": "å•Ÿį”¨", - "term.disable": "åœį”¨", - "term.enabled": "åˇ˛å•Ÿį”¨", - "term.disabled": "åˇ˛åœį”¨", - "term.connect": "逪įĩ", - "term.connecting": "逪įĩä¸­", - "term.disconnect": "取æļˆé€Ŗįĩ", - "term.authed": "åˇ˛æŽˆæŦŠ", - "term.confirm": "įĸēčĒ?", - "term.more": "更多", - "term.less": "čŧƒå°‘", - "term.showMore": "éĄ¯į¤ē更多", - "term.showLess": "éĄ¯į¤ēčŧƒå°‘", - "term.topSongs" : "į†ąé–€æ­Œæ›˛", - "term.latestReleases": "最新į™ŧ行", - "term.time.added": "加å…Ĩæ–ŧ", - "term.time.released": "į™ŧ行æ–ŧ", - "term.time.updated": "更新æ–ŧ", - "term.time.hours": "小時", - "term.time.hour": "小時", - "term.time.minutes": "分鐘", - "term.time.minute": "分鐘", - "term.time.seconds": "į§’", - "term.time.second": "į§’", - "term.fullscreenView": "全čžĸåš•æĒĸčĻ–", - "term.defaultView": "一čˆŦæĒĸčĻ–", - "term.audioSettings": "éŸŗč¨Šč¨­åŽš", - "term.clearAll": "清įŠē", - "term.recentStations": "最čŋ‘æ’­æ”žįš„é ģ道", - "term.language": "čĒžč¨€", - "term.funLanguages": "æƒĄæž", - "term.noLyrics": "加čŧ‰ä¸­... / æ‰žä¸åˆ°æ­ŒčŠžã€‚/ į´”éŸŗæ¨‚ã€‚", - "term.copyright": "Copyright", - "term.rightsReserved": "äŋį•™ä¸€åˆ‡æŦŠåˆŠã€‚", - "term.sponsor": "č´ŠåŠŠé€™å€‹é …į›Ž", - "term.ciderTeam": "Cider 團隊", - "term.developer": "開į™ŧ者", - "term.socialTeam": "į¤žäē¤åœ˜éšŠ", - "term.socials": "į¤žįž¤", - "term.contributors": "č˛ĸįģ者", - "term.equalizer": "å‡čĄĄå™¨", - "term.reset": "重設", - "term.tracks": "éĻ–æ­Œæ›˛", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "åŊąį‰‡", - "term.menu": "選項", - "term.showAlbum": "éĄ¯į¤ēåŽŒæ•´įš„å°ˆčŧ¯", - - // Home - "home.title": "ä¸ģ頁", - "home.recentlyPlayed": "最čŋ‘播攞", - "home.recentlyAdded": "最čŋ‘加å…Ĩ", - "home.artistsFeed": "藝äēē動態", - "home.artistsFeed.noArtist": "čŋŊ蹤一äē›č—äēēäž†į˛åž—äģ–å€‘įš„æœ€æ–°æ­Œæ›˛čŗ‡č¨Šã€‚", - "home.madeForYou": "į‚ē您推č–Ļ", - "home.friendsListeningTo": "æœ‹å‹æ­Ŗåœ¨č†čŊ", - "home.followedArtists": "čŋŊčš¤įš„č—äēē", - // Errors - "error.appleMusicSubRequired": "需čĻč¨‚é–ąApple MusicäģĨäŊŋᔍCider", - "error.connectionError": "į„Ąæŗ•é€ŖæŽĨ到 Apple Music。", - "error.noResults": "æ˛’æœ‰įĩæžœ", - "error.noResults.description": "čĢ‹å˜—čŠĻæ–°įš„æœå°‹å…§åŽšã€‚", - - //Podcasts - "podcast.followOnCider": "在Cider上čŋŊ蚤", - "podcast.followedOnCider": "厞圍Cider上čŋŊ蚤", - "podcast.subscribeOnItunes": "在iTunes上訂閱", - "podcast.subscribedOnItunes": "厞圍iTunes上訂閱", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "喎集", - "podcast.playEpisode": "播攞喎集", - "podcast.website": "Podcast įļ˛é ", - - // Actions - "action.addToLibrary": "加å…Ĩčŗ‡æ–™åēĢ", - "action.addToLibrary.success": "成功加å…Ĩčŗ‡æ–™åēĢ", - "action.addToLibrary.error": "加å…Ĩčŗ‡æ–™åēĢįš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.removeFromLibrary": "åžžčŗ‡æ–™åēĢåˆĒ除", - "action.removeFromLibrary.success": "åˇ˛åžžčŗ‡æ–™åēĢåˆĒ除", - "action.addToQueue": "加å…Ĩ垅播清喎", - "action.addToQueue.success": "成功加å…Ĩ垅播清喎", - "action.addToQueue.error": "加å…Ĩåž…æ’­æ¸…å–Žįš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.removeFromQueue": "垞垅播清喎åˆĒ除", - "action.removeFromQueue.success": "åˇ˛åžžåž…æ’­æ¸…å–ŽåˆĒ除", - "action.removeFromQueue.error": "垞垅播清喎åˆĒé™¤įš„éŽį¨‹ä¸­į™ŧį”ŸéŒ¯čǤ", - "action.createPlaylist": "新åĸžæ’­æ”žæ¸…å–Ž", - "action.addToPlaylist": "åŠ č‡ŗæ’­æ”žåˆ—čĄ¨", - "action.removeFromPlaylist": "åžžæ’­æ”žåˆ—čĄ¨åˆĒ除", - "action.addToFavorites": "åŠ č‡ŗæ”ļ藏", - "action.follow": "čŋŊ蚤", - "action.follow.success": "čŋŊ蚤中", - "action.follow.error": "čŋŊčš¤įš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.unfollow": "取æļˆčŋŊ蚤", - "action.unfollow.success": "åˇ˛å–æļˆčŋŊ蚤", - "action.unfollow.error": "取æļˆčŋŊčš¤įš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.playNext": "插播", - "action.playLater": "į¨åžŒæ’­æ”ž", - "action.startRadio": "åģēįĢ‹é›ģ台", - "action.goToArtist": "å‰åž€č—äēē", - "action.goToAlbum": "前垀專čŧ¯", - "action.moveToTop": "į§ģ動到頂部", - "action.share": "分äēĢæ­Œæ›˛", - "action.rename": "重新å‘Ŋ名", - "action.love": "喜愛", - "action.unlove": "取æļˆå–œæ„›", - "action.dislike": "æ¸›å°‘æ­¤éĄžåģēč­°", - "action.undoDislike": "é‚„åŽŸæ¸›å°‘æ­¤éĄžåģēč­°", - "action.showWebRemoteQR": "é™čˇæŽ§åˆļ", - "action.playTracksNext": "插播 ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.playTracksLater": "į¨åžŒæ’­æ”ž ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.removeTracks": "垞垅播清喎åˆĒ除 ${self.selectedItems.length} éĻ–æ­Œæ›˛", - "action.import": "匯å…Ĩ", - "action.export": "匯å‡ē", - - // Settings - General - "settings.header.general": "一čˆŦ", - "settings.header.general.description": "čĒŋ整Ciderįš„ä¸€čˆŦč¨­åŽš", - "settings.option.general.language": "čĒžč¨€", - - // Language optgroups - "settings.option.general.language.main": "čĒžč¨€", - "settings.option.general.language.fun": "æƒĄæžčĒžč¨€", - "settings.option.general.language.unsorted": "æœĒåˆ†éĄž", - - // Settings - Audio - "settings.header.audio": "韺荊", - "settings.header.audio.description": "čĒŋ整Ciderįš„éŸŗč¨Šč¨­åŽš", - "settings.option.audio.quality": "韺荊韺čŗĒ", // Dropdown - "settings.header.audio.quality.high": "é̘ᴠčŗĒ", - "settings.header.audio.quality.low": "éĢ˜æ•ˆįŽ‡", - "settings.header.audio.quality.auto": "č‡Ē動", - "settings.option.audio.seamlessTransition": "į„Ąį¸Ģ播攞", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "é€˛éšŽåŠŸčƒŊ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "å•Ÿį”¨ AudioContext å°‡č§ŖéŽ–éĄžäŧŧéŸŗé‡åšŗčĄĄå’Œå‡čĄĄå™¨įš„é€˛éšŽåŠŸčƒŊ。äŊ†æ˜¯æœƒåœ¨ä¸€äē›é›ģč…Ļé€ æˆéŸŗæ¨‚åĄé “ã€‚", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "éŸŗé‡åšŗčĄĄ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "å°‡åšŗčĄĄčŧ•柔和éŸŋäēŽįš„æ­Œæ›˛īŧŒåģēįĢ‹æ›´įĩąä¸€įš„聆čŊéĢ”éŠ—ã€‚", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "įŠēé–“éŸŗč¨Š", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "å°‡éŸŗč¨Šé€˛čĄŒįŠēé–“åŒ–č™•į†äž†čŖŊ造一個更įĢ‹éĢ”įš„č†čŊéĢ”éŠ—īŧˆæŗ¨īŧšæ­¤åŠŸčƒŊä¸æ˜¯åŽ˜æ–šįš„æœæ¯”å…¨æ™¯č˛īŧ‰", - // Settings - Visual - "settings.header.visual": "外觀", - "settings.header.visual.description": "čĒŋ整Ciderįš„å¤–č§€", - "settings.option.visual.windowBackgroundStyle": "įĒ—åŖčƒŒæ™¯æ¨Ŗåŧ", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "įŠēį™Ŋ", - "settings.header.visual.windowBackgroundStyle.artwork": "專čŧ¯å°éĸ", - "settings.header.visual.windowBackgroundStyle.image": "åœ–į‰‡", - "settings.option.visual.animatedArtwork": "動態專čŧ¯å°éĸ", // Dropdown - "settings.header.visual.animatedArtwork.always": "į¸Ŋæ˜¯éĄ¯į¤ē", - "settings.header.visual.animatedArtwork.limited": "åĒåœ¨č—äēē頁éĸ和專čŧ¯å°éĸéĄ¯į¤ē", - "settings.header.visual.animatedArtwork.disable": "關閉", - "settings.option.visual.animatedArtworkQuality": "動態專čŧ¯å°éĸ品čŗĒ", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "äŊŽ", - "settings.header.visual.animatedArtworkQuality.medium": "中", - "settings.header.visual.animatedArtworkQuality.high": "é̘", - "settings.header.visual.animatedArtworkQuality.veryHigh": "非常é̘", - "settings.header.visual.animatedArtworkQuality.extreme": "æĨĩé̘", - "settings.option.visual.animatedWindowBackground": "動態įĒ—åŖčƒŒæ™¯", // Toggle - "settings.option.visual.hardwareAcceleration": "įĄŦéĢ”åŠ é€Ÿ", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "需čĻé‡å•“ Cider 才čƒŊį”Ÿæ•ˆ", - "settings.header.visual.hardwareAcceleration.default": "預設", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "éĄ¯į¤ē個äēēæĒ”æĄˆ", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "æ­ŒčŠž", - "settings.header.lyrics.description": "čĒŋ整Ciderįš„æ­ŒčŠžč¨­åŽš", - "settings.option.lyrics.enableMusixmatch": "å•Ÿį”¨ Musixmatch æ­ŒčŠž", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "å•Ÿį”¨åĄæ‹‰OKæ¨Ąåŧīŧˆåƒ…限Musixmatchīŧ‰", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch æ­ŒčŠžčĒžč¨€ååĨŊ", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "播攞 MV 時äŊŋᔍ YouTube æ­ŒčŠž", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "å¤–éƒ¨é€Ŗįĩ", - "settings.header.connectivity.description": "čĒŋ整Ciderčˆ‡å¤–éƒ¨įš„é€Ŗįĩ", - "settings.option.connectivity.discordRPC": "Discord į‹€æ…‹", // Dropdown - "settings.option.connectivity.playbackNotifications": "播攞通įŸĨ", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "éĄ¯į¤ēį‚ē'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "éĄ¯į¤ēį‚ē'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "æšĢ停時清除 Discord į‹€æ…‹", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble åģļ遲 (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "å•Ÿį”¨ LastFM æ­Ŗåœ¨æ’­æ”ž", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "垞歌名中į§ģ除åŽĸ串藝äēē (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "ä¸č¨˜éŒ„å–Žæ›˛åžĒį’° (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "å¯Ļ銗性功čƒŊ", - "settings.header.experimental.description": "čĒŋ整Ciderįš„å¯Ļ銗性功čƒŊ", - "settings.option.experimental.compactUI": "įˇŠå‡‘åž‹ UI", // Toggle - "settings.option.experimental.closeButtonBehaviour": "é—œé–‰æŒ‰éˆ•čĄŒį‚ē", - "settings.option.experimental.closeButtonBehaviour.quit": "įĩæŸ Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "į¸Žå°č‡ŗåˇĨäŊœåˆ—", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "į¸Žå°č‡ŗįŗģįĩ࿉˜į›¤", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "įŠēé–“éŸŗč¨ŠåŠŸčƒŊčĸĢįρᔍīŧŒäŊŋį”¨å‰čĢ‹å…ˆå•“į”¨ã€‚", - "spatial.spatialProperties" : "įŠēé–“éŸŗč¨ŠåąŦ性", - "spatial.width" : "闊åēĻ", - "spatial.height" : "é̘åēĻ", - "spatial.depth" : "æˇąåēĻ", - "spatial.gain" : "åĸžį›Š", - "spatial.roomMaterials" : "įŠē間材čŗĒ", - "spatial.roomDimensions" : "įŠē間大小", - "spatial.roomPositions" : "įŠē間äŊįŊŽ", - "spatial.setDimensions" : "å¤§å°č¨­åŽš", - "spatial.setPositions" : "äŊįŊŽč¨­åޚ", - "spatial.up" : "上斚", - "spatial.front" : "前斚", - "spatial.left" : "åˇĻæ–š", - "spatial.right" : "åŗæ–š", - "spatial.back" : "垌斚", - "spatial.down" : "下斚", - "spatial.listener" : "č§€įœž", - "spatial.audioSource" : "韺æē", - - // Settings - Unfinished - "settings.header.unfinished": "æœĒ厌成", - - // Web Remote - "remote.web.title": "é™čˇæŽ§åˆļ Cider", - "remote.web.description": "掃描äģĨä¸‹įš„äēŒįļ­įĸŧäģĨ控åˆļ Cider", - - //About - "about.thanks": "感čŦ Cider Collective äģĨ及所有č˛ĸįģč€…æ‰€äŊœå‡ēįš„č˛ĸįģ。" -} \ No newline at end of file diff --git a/src/i18n/zh_TW.jsonc b/src/i18n/zh_TW.jsonc deleted file mode 100644 index 2a608063..00000000 --- a/src/i18n/zh_TW.jsonc +++ /dev/null @@ -1,342 +0,0 @@ -{ - - // i18n Info - "i18n.languageName": "įšéĢ”ä¸­æ–‡īŧˆå°įŖīŧ‰", // name of language in native language - "i18n.languageNameEnglish": "Trad. Chinese (Taiwan)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@maikirakiwi @jay900604 @kyw504100", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${y}åš´${m}月${d}æ—Ĩ", - - // Dialogs - "dialog.cancel": "取æļˆ", - "dialog.ok": "įĸē厚", - - // Notification - "notification.updatingLibrarySongs": "æ­Ŗåœ¨æ›´æ–°čŗ‡æ–™åēĢįš„æ­Œæ›˛...", - "notification.updatingLibraryAlbums": "æ­Ŗåœ¨æ›´æ–°čŗ‡æ–™åēĢįš„å°ˆčŧ¯...", - "notification.updatingLibraryArtists": "æ­Ŗåœ¨æ›´æ–°čŗ‡æ–™åēĢįš„č—äēē...", - - // Terms - "term.appleMusic": "Apple Music", // Follows brand term - "term.applePodcasts": "Apple Podcasts", // Follows brand term - "term.itunes": "iTunes", // Follows brand term - "term.github": "GitHub", // Follows brand term - "term.discord": "Discord", // Follows brand term - "term.learnMore": "更多内厚", - "term.accountSettings": "叺æˆļč¨­åŽš", - "term.logout": "į™ģå‡ē", - "term.login": "į™ģå…Ĩ", - "term.about": "關æ–ŧ", - "term.privateSession": "ᧁäēēæ™‚æŽĩ", - "term.queue": "垅播清喎", - "term.search": "搜尋", - "term.library": "čŗ‡æ–™åēĢ", - "term.listenNow": "įĢ‹åŗč†čŊ", - "term.browse": "į€čĻŊ", - "term.radio": "åģŖæ’­", - "term.recentlyAdded": "最čŋ‘加å…Ĩ", - "term.songs": "æ­Œæ›˛", - "term.albums": "專čŧ¯", - "term.artists": "藝äēē", - "term.podcasts": "Podcasts", - "term.playlists": "æ’­æ”žåˆ—čĄ¨", - "term.playlist": "æ’­æ”žåˆ—čĄ¨", - "term.newPlaylist": "æ–°æ’­æ”žåˆ—čĄ¨", - "term.newPlaylistFolder": "æ–°æ’­æ”žåˆ—čĄ¨čŗ‡æ–™å¤ž", - "term.createNewPlaylist": "新åĸžæ’­æ”žåˆ—襨", - "term.createNewPlaylistFolder": "新åĸžæ’­æ”žåˆ—čĄ¨čŗ‡æ–™å¤ž", - "term.deletePlaylist": "æ‚¨įĄŽåŽščĻåˆ é™¤č¯Ĩæ’­æ”žåˆ—čĄ¨å—?", - "term.play": "播攞", - "term.pause": "æšĢ停", - "term.previous": "上一éĻ–", - "term.next": "下一éĻ–", - "term.shuffle": "隨抟播攞", - "term.repeat": "é‡č¤‡æ’­æ”ž", - "term.volume": "éŸŗé‡", - "term.mute": "éœéŸŗ", - "term.unmute": "取æļˆéœéŸŗ", - "term.share": "分äēĢ", - "term.share.success": "厞複čŖŊ臺å‰Ēč˛ŧį°ŋ", - "term.settings": "č¨­åŽš", - "term.seeAll": "éĄ¯į¤ē全部", - "term.sortBy": "排åē", - "term.sortBy.album": "專čŧ¯", - "term.sortBy.artist": "藝äēē", - "term.sortBy.name": "歌名", - "term.sortBy.genre": "éŸŗæ¨‚éĸ¨æ ŧ", - "term.sortBy.releaseDate": "į™ŧ行æ—Ĩ期", - "term.sortBy.duration": "æ™‚é•ˇ", - "term.sortOrder": "字母排åē", - "term.sortOrder.ascending": "升åē", - "term.sortOrder.descending": "降åē", - "term.viewAs": "éĄ¯į¤ēæ¨Ąåŧ", - "term.viewAs.coverArt": "專čŧ¯å°éĸ", - "term.viewAs.list": "åˆ—čĄ¨", - "term.size": "大小", - "term.size.normal": "æ­Ŗå¸¸", - "term.size.compact": "įˇŠå¯†", - "term.enable": "å•Ÿį”¨", - "term.disable": "åœį”¨", - "term.enabled": "åˇ˛å•Ÿį”¨", - "term.disabled": "åˇ˛åœį”¨", - "term.connect": "逪æŽĨ", - "term.connecting": "逪æŽĨ中", - "term.disconnect": "æ–ˇé–‹", - "term.authed": "åˇ˛æŽˆæŦŠ", - "term.confirm": "įĸē厚īŧŸ", - "term.more": "更多", - "term.less": "更少", - "term.showMore": "éĄ¯į¤ē更多", - "term.showLess": "éĄ¯į¤ē更少", - "term.topSongs": "į†ąé–€æ­Œæ›˛", - "term.latestReleases": "最新į™ŧ行", - "term.time.added": "加å…Ĩæ–ŧ", - "term.time.released": "į™ŧ行æ–ŧ", - "term.time.updated": "更攚æ–ŧ", - "term.time.hours": "小時", - "term.time.hour": "小時", - "term.time.minutes": "分鐘", - "term.time.minute": "分鐘", - "term.time.seconds": "į§’", - "term.time.second": "į§’", - "term.fullscreenView": "全čžĸåš•éĄ¯į¤ē", - "term.defaultView": "é č¨­éĄ¯į¤ē", - "term.audioSettings": "éŸŗč¨Šč¨­åŽš", - "term.spacializedAudioSetting": "įŠēé–“éŸŗč¨Šč¨­åŽš", - "term.clearAll": "清įŠē", - "term.recentStations": "最čŋ‘æ”ļčŊįš„åģŖæ’­", - "term.language": "čĒžč¨€", - "term.noLyrics": "æ­Ŗåœ¨čŧ‰å…Ĩ。。/ į„Ąæ­ŒčŠžįĩæžœ / į´”éŸŗæ¨‚", - "term.copyright": "į‰ˆæŦŠč˛æ˜Ž", - "term.rightsReserved": "äŋį•™æ‰€æœ‰æŦŠåˆŠã€‚", - "term.sponsor": "č´ŠåŠŠæˆ‘å€‘", - "term.socials": "į¤žįž¤åšŗå°", - "term.ciderTeam": "Cider 團隊", - "term.developer": "開į™ŧ者", - "term.socialTeam": "å…Ŧ關團隊", - "term.contributors": "č˛ĸįģ者", - "term.equalizer": "į­‰åŒ–å™¨", - "term.reset": "重設", - "term.tracks": "éĻ–æ­Œæ›˛", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "åŊąį‰‡", - "term.menu": "選喎", - "term.check": "æĒĸæŸĨ", - "term.aboutArtist": "關æ–ŧ{{artistName}}", // e.g. 'About Doja Cat' - - // Home - "home.title": "éϖ頁", - "home.recentlyPlayed": "最čŋ‘播攞", - "home.recentlyAdded": "最čŋ‘加å…Ĩ", - "home.artistsFeed": "藝äēēčŋŊ蚤", - "home.artistsFeed.noArtist": "čŋŊ蹤一äē›č—äēēäž†į˛åž—äģ–å€‘įš„æœ€æ–°æ­Œæ›˛ã€‚", - "home.madeForYou": "į‚ē您推č–Ļ", - "home.friendsListeningTo": "æœ‹å‹æ­Ŗåœ¨č†čŊ", - "home.followedArtists": "čŋŊčš¤įš„č—äēē", - - // Errors - "error.appleMusicSubRequired": "需čĻč¨‚é–ą Apple Music äģĨäŊŋᔍ Cider", - "error.connectionError": "į„Ąæŗ•é€ŖæŽĨ到 Apple Music。", - "error.noResults": "æ˛’æœ‰įĩæžœ", - "error.noResults.description": "嘗čŠĻæ–°įš„æœå°‹é …į›Žã€‚", - - // Podcasts - "podcast.followOnCider": "在 Cider 上čŋŊ蚤", - "podcast.followedOnCider": "厞čŋŊ蚤", - "podcast.subscribeOnItunes": "在 iTunes 上訂閱", - "podcast.subscribedOnItunes": "åˇ˛č¨‚é–ą", - "podcast.itunesStore": "iTunes Store", // Follows brand term - "podcast.episodes": "喎集", - "podcast.playEpisode": "播攞喎集", - "podcast.website": "Podcast įļ˛įĢ™", - - // Actions - "action.addToLibrary": "加å…Ĩčŗ‡æ–™åēĢ", - "action.addToLibrary.success": "成功加å…Ĩčŗ‡æ–™åēĢ", - "action.addToLibrary.error": "加å…Ĩčŗ‡æ–™åēĢįš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.removeFromLibrary": "åžžčŗ‡æ–™åēĢåˆĒ除", - "action.removeFromLibrary.success": "åˇ˛åžžčŗ‡æ–™åēĢåˆĒ除", - "action.addToQueue": "加å…Ĩ垅播清喎", - "action.addToQueue.success": "成功加å…Ĩ垅播清喎", - "action.addToQueue.error": "加å…Ĩåž…æ’­æ¸…å–Žįš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.removeFromQueue": "垞垅播清喎åˆĒ除", - "action.removeFromQueue.success": "åˇ˛åžžåž…æ’­æ¸…å–ŽåˆĒ除", - "action.removeFromQueue.error": "垞垅播清喎åˆĒé™¤įš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.createPlaylist": "新åĸžæ’­æ”žåˆ—襨", - "action.addToPlaylist": "加å…Ĩæ’­æ”žåˆ—čĄ¨", - "action.removeFromPlaylist": "åžžæ’­æ”žåˆ—čĄ¨åˆĒ除", - "action.addToFavorites": "加å…Ĩæˆ‘įš„æœ€æ„›", - "action.follow": "čŋŊ蚤", - "action.follow.success": "čŋŊ蚤中", - "action.follow.error": "čŋŊčš¤įš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.unfollow": "取æļˆčŋŊ蚤", - "action.unfollow.success": "åˇ˛å–æļˆčŋŊ蚤", - "action.unfollow.error": "取æļˆčŋŊčš¤įš„éŽį¨‹į™ŧį”ŸéŒ¯čǤ", - "action.playNext": "插播", - "action.playLater": "最垌播攞", - "action.startRadio": "åģēįĢ‹é›ģ台", - "action.goToArtist": "å‰åž€č—äēē", - "action.goToAlbum": "前垀專čŧ¯", - "action.moveToTop": "į§ģ臺頂į̝", - "action.share": "分äēĢæ­Œæ›˛", - "action.rename": "重新å‘Ŋ名", - "action.love": "喜愛", - "action.unlove": "取æļˆå–œæ„›", - "action.dislike": "æ¸›å°‘æ­¤éĄžåģēč­°", - "action.undoDislike": "é‚„åŽŸæ¸›å°æ­¤éĄžåģēč­°", - "action.showWebRemoteQR": "éĄ¯į¤ēé į¨‹æ“æŽ§čĄŒå‹•æĸįĸŧ", - "action.playTracksNext": "插播 ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.playTracksLater": "最垌播攞 ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.removeTracks": "垞垅播清喎åˆĒ除 ${self.selectedItems.length} éĻ–æ­Œæ›˛", - "action.import": "匯å…Ĩ", - "action.export": "匯å‡ē", - "action.showAlbum": "éĄ¯į¤ē專čŧ¯", - "action.tray.minimize": "最小化", - "action.tray.quit": "關閉", - "action.tray.show": "éĄ¯į¤ē", - "action.update": "更新", - "action.copy": "複čŖŊ", - "action.newpreset": "新åĸžé č¨­", // Equalizer Preset - "action.deletepreset": "åˆĒ除預設", // Equalizer Preset - - // Settings - General - "settings.header.general": "一čˆŦ", - "settings.header.general.description": "čĒŋ整 Cider įš„ä¸€čˆŦč¨­åŽš", - - // Language optgroups - "settings.option.general.language.main": "čĒžč¨€", - "settings.option.general.language.fun": "į‰šæŽŠčĒžč¨€", - "settings.option.general.language.unsorted": "æœĒåˆ†éĄž", - - // Update Cider - "settings.option.general.updateCider": "更新 Cider", // Button - "settings.option.general.updateCider.branch": "Cider 更新通道", // Dropdown - "settings.option.general.updateCider.branch.description": "選擇您čρæŽĨæ”ļ Cider čģŸéĢ”æ›´æ–°įš„é€šé“", - "settings.option.general.updateCider.branch.main": "įŠŠåŽšį‰ˆ(åģēč­°)", - "settings.option.general.updateCider.branch.develop": "開į™ŧ者æ¸ŦčŠĻį‰ˆ(ä¸įŠŠåŽš)", - - // Settings - Audio - "settings.header.audio": "韺荊", - "settings.header.audio.description": "čĒŋ整 Cider įš„éŸŗč¨Šč¨­åŽš", - "settings.option.audio.quality": "éŸŗč¨Šå“čŗĒ", // Dropdown - "settings.header.audio.quality.hireslossless": "éĢ˜å“čŗĒį„ĄæåŖ“į¸Ž", - "settings.header.audio.quality.hireslossless.description": "īŧˆéĢ˜é” 24-bit/192 kHzīŧ‰", - "settings.header.audio.quality.lossless": "į„ĄæåŖ“į¸Ž", - "settings.header.audio.quality.lossless.description": "īŧˆéĢ˜é” 24-bit/48 kHzīŧ‰", - "settings.header.audio.quality.enhanced": "數äŊåĸžåŧˇ", - "settings.header.audio.quality.high": "éĢ˜å“čŗĒ", - "settings.header.audio.quality.standard": "éĢ˜æ•ˆįŽ‡", - "settings.header.audio.quality.auto": "č‡Ē動", - "settings.option.audio.seamlessTransition": "į„Ąé–“æ–ˇæ’­æ”ž", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "é€˛éšŽéŸŗč¨ŠåŠŸčƒŊ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "å•Ÿį”¨ AudioContext å°‡é–‹å•ŸéĄžäŧŧéŸŗč¨ŠåšŗčĄĄå’Œį­‰åŒ–å™¨įš„é€˛éšŽč¨­åŽšã€‚äŊ†é€™ä¸Ļ不一厚遊合每部é›ģč…ĻīŧŒå¯čƒŊ會į™ŧį”ŸéŸŗæ¨‚åĄé “ã€‚", - "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 數äŊåĸžåŧˇéŸŗč¨Šč™•ᐆâ„ĸī¸", // Toggle - "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "將æŦēé¨™æ‚¨įš„å¤§č…ĻčŽ“æ‚¨æ„Ÿå—åˆ°čŋ‘äŧŧäŋįœŸåŖ“į¸Žįš„éŸŗčŗĒ。| į”ą Maikiwi 設計", - "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "數äŊåĸžåŧˇéŸŗč¨Šč™•ᐆ荭åޚ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "å°‡æ›´æ”šéŸŗč¨Šč™•į†įš„æŋ€é€˛/振åĨŽį¨‹åēĻīŧˆåĸžåŧˇé¸é …有可čƒŊ會åŧ•čĩˇé›œč¨Šīŧ‰", - "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "標æē–", - "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "åĸžåŧˇ", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "éŸŗč¨ŠåšŗčĄĄ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "å°‡åšŗčĄĄčŧ•柔和éŸŋäēŽįš„æ­Œæ›˛īŧŒåģēįĢ‹æ›´įĩąä¸€čˆ’éŠįš„č†čŊéĢ”éŠ—ã€‚", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "įŠēé–“éŸŗč¨Š", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "å°‡éŸŗč¨Šé€˛čĄŒįŠēé–“åŒ–č™•į†äž†čŖŊ造一個更įĢ‹éĢ”įš„č†čŊéĢ”éŠ—īŧˆč¨ģīŧšæ­¤åŠŸčƒŊä¸æ˜¯åŽ˜æ–šįš„æœæ¯”å…¨æ™¯č˛īŧ‰", - - // Settings - Visual - "settings.header.visual": "外觀", - "settings.header.visual.description": "čĒŋ整 Cider įš„å¤–č§€", - "settings.option.visual.windowBackgroundStyle": "čĻ–įĒ—čƒŒæ™¯æ¨Ŗåŧ", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "įŠēį™Ŋ", - "settings.header.visual.windowBackgroundStyle.artwork": "專čŧ¯å°éĸ", - "settings.header.visual.windowBackgroundStyle.image": "åœ–į‰‡", - "settings.option.visual.animatedArtwork": "動態專čŧ¯å°éĸ", // Dropdown - "settings.header.visual.animatedArtwork.always": "į¸Ŋæ˜¯éĄ¯į¤ē", - "settings.header.visual.animatedArtwork.limited": "åĒåœ¨č—äēē頁éĸ和專čŧ¯å°éĸéĄ¯į¤ē", - "settings.header.visual.animatedArtwork.disable": "關閉", - "settings.option.visual.animatedArtworkQuality": "動態專čŧ¯å°éĸ品čŗĒ", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "äŊŽ", - "settings.header.visual.animatedArtworkQuality.medium": "中", - "settings.header.visual.animatedArtworkQuality.high": "é̘", - "settings.header.visual.animatedArtworkQuality.veryHigh": "非常é̘", - "settings.header.visual.animatedArtworkQuality.extreme": "æĨĩé̘", - "settings.option.visual.animatedWindowBackground": "動態čĻ–įĒ—čƒŒæ™¯", // Toggle - "settings.option.visual.hardwareAcceleration": "įĄŦéĢ”åŠ é€Ÿ", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "需čĻé‡æ–°å•Ÿå‹• Cider 才會åĨ—ᔍ", - "settings.header.visual.hardwareAcceleration.default": "預設", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - "settings.header.visual.theme": "ä¸ģ題", - - // Settings - Visual - Theme name - "settings.option.visual.theme.default": "Cider", - "settings.option.visual.theme.dark": "暗é쑿¨Ąåŧ", - - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "éĄ¯į¤ē個äēēæĒ”æĄˆ", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "æ­ŒčŠž", - "settings.header.lyrics.description": "čĒŋ整 Cider įš„æ­ŒčŠžč¨­åŽš", - "settings.option.lyrics.enableMusixmatch": "å•Ÿį”¨ Musixmatch æ­ŒčŠž", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "å•Ÿį”¨Kæ­Œæ¨Ąåŧīŧˆåƒ…限Musixmatchīŧ‰", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch æ­ŒčŠžčĒžč¨€ååĨŊ", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "播攞 MV 時äŊŋᔍ YouTube æ­ŒčŠž", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "å¤–éƒ¨é€ŖæŽĨ", - "settings.header.connectivity.description": "čĒŋ整 Cider čˆ‡å¤–éƒ¨įš„é€ŖæŽĨ", - "settings.option.connectivity.discordRPC": "Discord 動態", // Dropdown - "settings.option.connectivity.playbackNotifications": "æ­Œæ›˛æ’­æ”žé€šįŸĨ", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "éĄ¯į¤ēæ­Ŗåœ¨įŽŠ 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "éĄ¯į¤ēæ­Ŗåœ¨įŽŠ 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "æšĢ停時清除 Discord 動態", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble åģļ遲 (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "å•Ÿį”¨ LastFM į›Žå‰č†čŊ", // Toggle - "settings.option.connectivity.lastfmScrobble.removeFeatured": "垞歌名中į§ģ除åŽĸ串藝äēē (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "ä¸č¨˜éŒ„å–Žæ›˛åžĒį’° (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "å¯Ļ銗性功čƒŊ", - "settings.header.experimental.description": "čĒŋ整 Cider įš„å¯Ļ銗性功čƒŊ", - "settings.option.experimental.compactUI": "äŊŋį”¨įˇŠå¯†įš„äģ‹éĸ設計", // Toggle - "settings.option.experimental.closeButtonBehaviour": "關閉按鈕操äŊœ", // Dropdown - "settings.option.experimental.close_button_hide": "關閉按鈕將 Cider éšąč—č‡ŗįŗģįĩąåˆ—", - "settings.option.experimental.copy_log": "複čŖŊåŸˇčĄŒį´€éŒ„æĒ”臺å‰Ēč˛ŧį°ŋ", - "settings.option.experimental.inline_playlists": "å°‡æ’­æ”žåˆ—čĄ¨åšį‚ēčĄŒå†…å…ƒį´ éĄ¯į¤ē", - - // Refer to term.disabled & term.enabled - // Spatialization Menu - "spatial.notTurnedOn": "įŠēé–“éŸŗč¨Šį›Žå‰æ˜¯é—œé–‰į‹€æ…‹īŧŒčĢ‹å…ˆå•Ÿį”¨å†äŊŋį”¨ã€‚", - "spatial.spatialProperties" : "įŠēé–“éŸŗč¨ŠåąŦæ€§č¨­åŽš", - "spatial.width" : "å¯ŦåēĻ", - "spatial.height" : "é̘åēĻ", - "spatial.depth" : "æˇąåēĻ", - "spatial.gain" : "åĸžį›Š", - "spatial.roomMaterials" : "įŠē間材čŗĒ", - "spatial.roomDimensions" : "įŠē間å°ē寸", - "spatial.roomPositions" : "įŠē間äŊįŊŽ", - "spatial.setDimensions" : "č¨­åŽšå°ē寸", - "spatial.setPositions" : "åĨ—ᔍ荭åޚ", - "spatial.up" : "上", - "spatial.front" : "前", - "spatial.left" : "åˇĻ", - "spatial.right" : "åŗ", - "spatial.back" : "垌", - "spatial.down" : "下", - "spatial.listener" : "čŊ衆", - "spatial.audioSource" : "éŸŗč¨Šäž†æē", - - // Settings - Unfinished - "settings.header.unfinished": "æœĒ開į™ŧåŽŒæˆįš„åŠŸčƒŊ", - - // Web Remote - "remote.web.title": "Cider 遠įĢ¯æ“æŽ§", - "remote.web.description": "掃描äģĨä¸‹įš„čĄŒå‹•æĸįĸŧäģĨ操控 Cider", - - //About - "about.thanks": "č‘—é‡æ„ŸčŦ Cider Collective įš„æˆå“ĄäģĨ及所有į‚ēé …į›Žäģ˜å‡ēįš„č˛ĸįģč€…ã€‚" -} diff --git a/src/i18n/zh_yue.jsonc b/src/i18n/zh_yue.jsonc deleted file mode 100644 index 41abc873..00000000 --- a/src/i18n/zh_yue.jsonc +++ /dev/null @@ -1,301 +0,0 @@ -{ - - // i18n Info - "i18n.languageName": "åģŖæąčŠąīŧˆéĻ™æ¸¯īšš", // name of language in native language - "i18n.languageNameEnglish": "Cantonese (Hong Kong)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@tszngaiyip @strikesnc", // Authors, if you contribute to this file feel free to add your name seperated with a space - - // App info - "app.name": "Cider", - - "date.format": "${y}åš´${m}月${d}æ—Ĩ", - - // Dialogs - "dialog.cancel": "取æļˆ", - "dialog.ok": "įĸēčĒ", - - // Notification - "notification.updatingLibrarySongs": "æ›´æ–°įˇŠčŗ‡æ–™åēĢå˜…æ­Œæ›˛...", - "notification.updatingLibraryAlbums": "æ›´æ–°įˇŠčŗ‡æ–™åēĢ嘅專čŧ¯...", - "notification.updatingLibraryArtists": "æ›´æ–°įˇŠčŗ‡æ–™åēĢå˜…č—äēē...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "æƒŗįŸĨ更多", - "term.accountSettings": "å¸ŗč™Ÿč¨­åŽš", - "term.logout": "į™ģå‡ē", - "term.login": "į™ģå…Ĩ", - "term.about": "關æ–ŧ", - "term.privateSession": "į„Ąį—•æ¨Ąåŧ", - "term.queue": "垅播清喎", - "term.search": "æĩ野", - "term.library": "čŗ‡æ–™åēĢ", - "term.listenNow": "åŗåˆģčŊ", - "term.browse": "į€čĻŊ", - "term.radio": "é›ģ台", - "term.recentlyAdded": "最čŋ‘加å…Ĩ", - "term.songs": "æ­Œæ›˛", - "term.albums": "專čŧ¯", - "term.artists": "藝äēē", - "term.podcasts": "Podcasts", - "term.playlists": "播攞清喎", - "term.playlist": "播攞清喎", - "term.play": "播攞", - "term.pause": "æšĢ停", - "term.previous": "前一éĻ–", - "term.next": "下一éĻ–", - "term.shuffle": "隨抟播攞", - "term.repeat": "é‡č¤‡æ’­æ”ž", - "term.volume": "éŸŗé‡", - "term.mute": "éœéŸŗ", - "term.unmute": "取æļˆéœéŸŗ", - "term.share": "分äēĢ", - "term.settings": "č¨­åŽš", - "term.seeAll": "į‡å“‚å…¨éƒ¨", - "term.sortBy": "排åē", - "term.sortBy.album": "專čŧ¯", - "term.sortBy.artist": "藝äēē", - "term.sortBy.name": "歌名", - "term.sortBy.genre": "éŸŗæ¨‚éĸ¨æ ŧ", - "term.sortBy.releaseDate": "嚞時å‡ē", - "term.sortBy.duration": "åšžé•ˇ", - "term.sortOrder": "éģžæŽ’", - "term.sortOrder.ascending": "順åē", - "term.sortOrder.descending": "倒åē", - "term.viewAs": "æƒŗéģžæ¨ŖéĄ¯į¤ē", - "term.viewAs.coverArt": "專čŧ¯å°éĸ", - "term.viewAs.list": "åˆ—čĄ¨", - "term.size": "大ᴰ", - "term.size.normal": "æ­Ŗå¸¸", - "term.size.compact": "čŋĢ啞", - "term.enable": "開", - "term.disable": "ᆄ", - "term.enabled": "開åˇĻ", - "term.disabled": "ᆄåˇĻ", - "term.connect": "逪įĩ", - "term.connecting": "é€ŖįˇŠ", - "term.disconnect": "取æļˆé€Ŗįĩ", - "term.authed": "授æŦŠå’—", - "term.confirm": "įĸēčĒīŧŸ", - "term.more": "å¤šå•˛", - "term.less": "少啞", - "term.showMore": "éĄ¯į¤ēå¤šå•˛", - "term.showLess": "éĄ¯į¤ē少啞", - "term.topSongs" : "į†ąé–€æ­Œæ›˛", - "term.latestReleases": "最新å‡ē嘅", - "term.time.added": "加å…Ĩæ–ŧ", - "term.time.released": "į™ŧ行æ–ŧ", - "term.time.updated": "更新æ–ŧ", - "term.time.hours": "į˛’é˜", - "term.time.hour": "į˛’é˜", - "term.time.minutes": "分鐘", - "term.time.minute": "分鐘", - "term.time.seconds": "į§’", - "term.time.second": "į§’", - "term.fullscreenView": "ᔍ免čžĸåš•į‡", - "term.defaultView": "åšŗæ™‚å’į‡", - "term.audioSettings": "éŸŗč¨Šč¨­åŽš", - "term.clearAll": "清除", - "term.recentStations": "å‘ĸ排čŊįˇŠå˜…", - "term.language": "čĒžč¨€", - "term.funLanguages": "æƒĄæž", - "term.noLyrics": "æĩᎊ... / æĩå””åˆ°æ­ŒčŠžã€‚ / į´”éŸŗæ¨‚éģŽã€‚", - "term.copyright": "į‰ˆæŦŠ", - "term.rightsReserved": "äŋį•™ä¸€åˆ‡æŦŠåˆŠ", - "term.sponsor": "čǞ金äŋžå‘ĸ個Project", - "term.ciderTeam": "Cider 團隊", - "term.developer": "開į™ŧ者", - "term.socialTeam": "PR", - "term.socials": "æˆ‘å“‹å˜…į¤žįž¤", - "term.contributors": "合äŊœäēē", - "term.equalizer": "å‡čĄĄå™¨ (EQ)", - "term.reset": "重設", - "term.tracks": "éĻ–æ­Œ", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "åŊąį‰‡", - "term.menu": "選項", - "term.showAlbum": "éĄ¯į¤ē厌整嘅專čŧ¯", - - // Home - "home.title": "ä¸ģ頁", - "home.recentlyPlayed": "å‘ĸ排播åˇĻ", - "home.recentlyAdded": "å‘ĸ排加嘅", - "home.artistsFeed": "藝äēē動態", - "home.artistsFeed.noArtist": "Follow ä¸€å•˛č—äēēåšŸį˛åž—äŊĸå“‹å˜…æœ€æ–°æ­Œæ›˛čŗ‡č¨Šã€‚ ", - "home.madeForYou": "į‚ēäŊ č€Œæ•´", - "home.friendsListeningTo": "äŊ å•˛FriendčŊᎊ", - "home.followedArtists": "FollowåˇĻå˜…č—äēē", - // Errors - "error.appleMusicSubRequired": "需čĻč¨‚é–ąApple Music先可äģĨᔍCider。", - "error.connectionError": "逪æŽĨ唔到Apple Music。", - "error.noResults": "冇įĩæžœã€‚", - "error.noResults.description": "重新æĩ過å•Ļ。", - - //Podcasts - "podcast.followOnCider": "å–ēCider上Follow", - "podcast.followedOnCider": "å–ēCider上FollowåˇĻ", - "podcast.subscribeOnItunes": "å–ēiTunes上訂閱", - "podcast.subscribedOnItunes": "å–ēiTunes上訂閱åˇĻ", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "喎集", - "podcast.playEpisode": "播å‘ĸ集", - "podcast.website": "Podcast įļ˛é ", - - // Actions - "action.addToLibrary": "加å…Ĩčŗ‡æ–™åēĢ", - "action.addToLibrary.success": "加å…Ĩå’—čŗ‡æ–™åēĢ", - "action.addToLibrary.error": "加å…Ĩå””åˆ°čŗ‡æ–™åēĢ", - "action.removeFromLibrary": "å–ēčŗ‡æ–™åēĢ到åˆĒ除", - "action.removeFromLibrary.success": "厞įļ“å–ēčŗ‡æ–™åēĢ到åˆĒ除咗", - "action.addToQueue": "加å…Ĩ垅播清喎", - "action.addToQueue.success": "加å…Ĩ咗垅播清喎", - "action.addToQueue.error": "加å…Ĩ唔到垅播清喎", - "action.removeFromQueue": "å–ē垅播清喎åˆĒ除", - "action.removeFromQueue.success": "厞įļ“å–ē垅播清喎到åˆĒ除咗", - "action.removeFromQueue.error": "å–ē垅播清喎到åˆĒ除唔到", - "action.createPlaylist": "åģēįĢ‹æ–°å˜…æ’­æ”žæ¸…å–Ž", - "action.addToPlaylist": "加å…Ĩ播攞清喎", - "action.removeFromPlaylist": "å–ē播攞清喎到åˆĒ除", - "action.addToFavorites": "åŠ č‡ŗæ”ļ藏", - "action.follow": "Follow", - "action.follow.success": "Followᎊ", - "action.follow.error": "Follow唔到", - "action.unfollow": "Unfollow", - "action.unfollow.success": "Unfollow咗", - "action.unfollow.error": "Unfollow唔到", - "action.playNext": "下éĻ–åŗåˆģ播", - "action.playLater": "é™Ŗé–“å…ˆå†æ’­", - "action.startRadio": "åģēįĢ‹é›ģ台", - "action.goToArtist": "å‰åž€č—äēē", - "action.goToAlbum": "前垀專čŧ¯", - "action.moveToTop": "čŋ”最頂", - "action.share": "分äēĢæ­Œæ›˛", - "action.rename": "重新å‘Ŋ名", - "action.love": "鐘意", - "action.unlove": "唔鐘意", - "action.dislike": "å””æƒŗå†į‡åˆ°", - "action.undoDislike": "é‚„åŽŸå””æƒŗå†į‡åˆ°", - "action.showWebRemoteQR": "é™čˇæŽ§åˆļ", - "action.playTracksNext": "插播 ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.playTracksLater": "é™Ŗé–“æ’­æ”ž ${app.selectedMediaItems.length} éĻ–æ­Œæ›˛", - "action.removeTracks": "å–ē垅播清喎到åˆĒ除 ${self.selectedItems.length} éĻ–æ­Œæ›˛", - "action.import": "匯å…Ĩ", - "action.export": "匯å‡ē", - - // Settings - General - "settings.header.general": "一čˆŦ", - "settings.header.general.description": "čĒŋ整Cider嘅一čˆŦč¨­åŽš", - "settings.option.general.language": "čĒžč¨€", - - // Language optgroups - "settings.option.general.language.main": "čĒžč¨€", - "settings.option.general.language.fun": "æƒĄæžčĒžč¨€", - "settings.option.general.language.unsorted": "æœĒåˆ†éĄž", - - // Settings - Audio - "settings.header.audio": "韺荊", - "settings.header.audio.description": "čĒŋ整Ciderå˜…éŸŗč¨Šč¨­åŽš", - "settings.option.audio.quality": "韺čŗĒ", // Dropdown - "settings.header.audio.quality.high": "čŗĒį´ å„Ē先", - "settings.header.audio.quality.low": "æĩæšĸåēĻå„Ē先", - "settings.header.audio.quality.auto": "č‡Ē動", - "settings.option.audio.seamlessTransition": "į„Ąį¸Ģ播攞", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "é€˛éšŽåŠŸčƒŊ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "å•Ÿį”¨AudioContextīŧŒč§ŖéŽ–éĄžäŧŧéŸŗé‡åšŗčĄĄå’Œå‡čĄĄå™¨å˜…é€˛éšŽåŠŸčƒŊīŧŒäŊ†äŋ‚會å–ē部分é›ģč…Ļé€ æˆéŸŗæ¨‚Lag抟。", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "éŸŗé‡åšŗčĄĄ", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "åšŗčĄĄčŧ•柔同éŸŋäēŽå˜…æ­Œæ›˛īŧŒäģ¤äŊ æœ‰įĩąä¸€å˜…聆čŊéĢ”éŠ—ã€‚", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "įŠēé–“éŸŗč¨Š", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "įŠēé–“åŒ–éŸŗč¨ŠīŧŒčŖŊ造一個更įĢ‹éĢ”å˜…č†čŊéĢ”éŠ—īŧˆæŗ¨æ„īŧšå‘ĸ個功čƒŊ唔äŋ‚åŽ˜æ–šå˜…æœæ¯”å…¨æ™¯č˛īŧ‰", - // Settings - Visual - "settings.header.visual": "外觀", - "settings.header.visual.description": "čĒŋ整Ciderå˜…å¤–č§€", - "settings.option.visual.windowBackgroundStyle": "čĻ–įĒ—čƒŒæ™¯æ¨Ŗåŧ", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "įŠēį™Ŋ", - "settings.header.visual.windowBackgroundStyle.artwork": "專čŧ¯å°éĸ", - "settings.header.visual.windowBackgroundStyle.image": "åœ–į‰‡", - "settings.option.visual.animatedArtwork": "動態專čŧ¯å°éĸ", // Dropdown - "settings.header.visual.animatedArtwork.always": "į¸Ŋæ˜¯éĄ¯į¤ē", - "settings.header.visual.animatedArtwork.limited": "æˇ¨äŋ‚å–ē藝äēē頁éĸ同專čŧ¯å°éĸéĄ¯į¤ē", - "settings.header.visual.animatedArtwork.disable": "ᆄåˇĻäŊĸ", - "settings.option.visual.animatedArtworkQuality": "動態專čŧ¯å°éĸ品čŗĒ", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "äŊŽ", - "settings.header.visual.animatedArtworkQuality.medium": "中", - "settings.header.visual.animatedArtworkQuality.high": "é̘", - "settings.header.visual.animatedArtworkQuality.veryHigh": "非常é̘", - "settings.header.visual.animatedArtworkQuality.extreme": "æĨĩé̘", - "settings.option.visual.animatedWindowBackground": "動態čĻ–įĒ—čƒŒæ™¯", // Toggle - "settings.option.visual.hardwareAcceleration": "įĄŦéĢ”åŠ é€Ÿ", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "需čĻé‡é–‹Ciderå…ˆæœƒį”Ÿæ•ˆ", - "settings.header.visual.hardwareAcceleration.default": "預設", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "éĄ¯į¤ē個äēēæĒ”æĄˆ", // Toggle - - // Settings - Lyrics - "settings.header.lyrics": "æ­ŒčŠž", - "settings.header.lyrics.description": "čĒŋ整Ciderå˜…æ­ŒčŠžč¨­åŽš", - "settings.option.lyrics.enableMusixmatch": "å•Ÿį”¨ Musixmatch æ­ŒčŠž", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "é–‹å•Ÿå”ąKæ¨Ąåŧīŧˆåƒ…限Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch æ­ŒčŠžčĒžč¨€ååĨŊ", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "播攞MVå˜…æ™‚å€™į”¨YouTubeå­—åš•", // Toggle - - // Settings - Connectivity - "settings.header.connectivity": "å¤–éƒ¨é€Ŗįĩ", - "settings.header.connectivity.description": "čĒŋ整CideråŒå¤–éƒ¨å˜…é€Ŗįĩ", - "settings.option.connectivity.discordRPC": "Discord į‹€æ…‹", // Dropdown - "settings.option.connectivity.playbackNotifications": "å–ē播歌嘅時候通įŸĨäŊ ", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "éĄ¯į¤ēį‚ē'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "éĄ¯į¤ēį‚ē'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "æšĢ停時清除 Discord į‹€æ…‹", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble åģļ遲 (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "å•Ÿį”¨ LastFM æ­Ŗåœ¨æ’­æ”ž", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "垞歌名中į§ģ除藝äēēæŽ¨č–Ļ (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (LastFM)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "å¯Ļ銗性功čƒŊ", - "settings.header.experimental.description": "čĒŋ整Cider嘅å¯Ļ銗性功čƒŊ", - "settings.option.experimental.compactUI": "é€ŧ啞æ—ĸ UI", // Toggle - "settings.option.experimental.closeButtonBehaviour": "é—œé–‰æŒ‰éˆ•čĄŒį‚ē", - "settings.option.experimental.closeButtonBehaviour.quit": "ᆄåˇĻCideräŊĸ", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "æ”ļ埋Ciderå–ēåˇĨäŊœåˆ—", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "æ”ļ埋Ciderå–ēįŗģįĩ࿉˜į›¤", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.spatialProperties" : "įŠēé–“éŸŗč¨ŠåąŦ性", - "spatial.width" : "åšžé—Š", - "spatial.height" : "åšžé̘", - "spatial.depth" : "åšžæˇą", - "spatial.gain" : "åĸžį›Š", - "spatial.roomMaterials" : "įŠē間材čŗĒ", - "spatial.roomDimensions" : "įŠē間大小", - "spatial.roomPositions" : "įŠē間äŊįŊŽ", - "spatial.setDimensions" : "å¤§å°č¨­åŽš", - "spatial.setPositions" : "äŊįŊŽč¨­åޚ", - "spatial.up" : "上éĸ", - "spatial.front" : "前éĸ", - "spatial.left" : "åˇĻ邊", - "spatial.right" : "åŗé‚Š", - "spatial.back" : "垌éĸ", - "spatial.down" : "下éĸ", - "spatial.listener" : "č§€įœž", - "spatial.audioSource" : "韺æē", - - // Settings - Unfinished - "settings.header.unfinished": "æœĒ搞掂", - - // Web Remote - "remote.web.title": "é™čˇæŽ§åˆļ Cider", - "remote.web.description": "Scan å‘ĸ個 QR Code åŽģ控åˆļ Cider", - - // About - "about.thanks": "多čŦ Cider Collective 同埋所有合äŊœäēēäŊœå‡ē嘅č˛ĸįģ。" -} diff --git a/src/main/base/app.ts b/src/main/base/app.ts index b6415152..27b5c903 100644 --- a/src/main/base/app.ts +++ b/src/main/base/app.ts @@ -1,287 +1,447 @@ -import {app, Menu, nativeImage, Tray} from 'electron'; -import * as path from 'path'; -import {utils} from './utils' +import { Menu, Tray, app, clipboard, ipcMain, nativeImage, shell } from "electron"; +import log from "electron-log"; +import { readFileSync } from "node:fs"; +import { dirname, join, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import os from "os"; +import { utils } from "../base/utils.js"; +/** + * @file Creates App instance + * @author CiderCollective + */ + +/** @namespace */ export class AppEvents { - private protocols: string[] = [ - "ame", - "cider", - "itms", - "itmss", - "musics", - "music" - ] - private plugin: any = undefined; - private tray: any = undefined; - private i18n: any = undefined; + private protocols: string[] = ["ame", "cider", "itms", "itmss", "musics", "music"]; + private plugin: any = undefined; + private tray: any = undefined; + private i18n: any = undefined; - constructor() { - this.start(); + /** @constructor */ + constructor() { + this.start(); + } + + /** + * Handles all actions that occur for the app on start (Mainly commandline arguments) + * @returns {void} + */ + private start(): void { + AppEvents.initLogging(); + console.info("[AppEvents] App started"); + + /********************************************************************************************************************** + * Startup arguments handling + **********************************************************************************************************************/ + if (app.commandLine.hasSwitch("version") || app.commandLine.hasSwitch("v")) { + console.log(app.getVersion()); + app.exit(); } - /** - * Handles all actions that occur for the app on start (Mainly commandline arguments) - * @returns {void} - */ - private start(): void { - console.info('[AppEvents] App started'); - - /********************************************************************************************************************** - * Startup arguments handling - **********************************************************************************************************************/ - if (app.commandLine.hasSwitch('version') || app.commandLine.hasSwitch('v')) { - console.log(app.getVersion()) - app.exit() - } - - // Verbose Check - if (app.commandLine.hasSwitch('verbose')) { - console.log("[Cider] User has launched the application with --verbose"); - } - - // Log File Location - if (app.commandLine.hasSwitch('log') || app.commandLine.hasSwitch('l')) { - console.log(path.join(app.getPath('userData'), 'logs')) - app.exit() - } - - // Expose GC - app.commandLine.appendSwitch('js-flags', '--expose_gc') - - if (process.platform === "win32") { - app.setAppUserModelId(app.getName()) // For notification name - } - - /*********************************************************************************************************************** - * Commandline arguments - **********************************************************************************************************************/ - switch (utils.getStoreValue('visual.hw_acceleration') as string) { - default: - case "default": - app.commandLine.appendSwitch('enable-accelerated-mjpeg-decode') - app.commandLine.appendSwitch('enable-accelerated-video') - app.commandLine.appendSwitch('disable-gpu-driver-bug-workarounds') - app.commandLine.appendSwitch('ignore-gpu-blacklist') - app.commandLine.appendSwitch('enable-native-gpu-memory-buffers') - app.commandLine.appendSwitch('enable-accelerated-video-decode'); - app.commandLine.appendSwitch('enable-gpu-rasterization'); - app.commandLine.appendSwitch('enable-native-gpu-memory-buffers'); - app.commandLine.appendSwitch('enable-oop-rasterization'); - break; - - case "webgpu": - console.info("WebGPU is enabled."); - app.commandLine.appendSwitch('enable-unsafe-webgpu') - break; - - case "disabled": - console.info("Hardware acceleration is disabled."); - app.commandLine.appendSwitch('disable-gpu') - break; - } - - if (process.platform === "linux") { - app.commandLine.appendSwitch('disable-features', 'MediaSessionService'); - } - - /*********************************************************************************************************************** - * Protocols - **********************************************************************************************************************/ - if (process.defaultApp) { - if (process.argv.length >= 2) { - this.protocols.forEach((protocol: string) => { - app.setAsDefaultProtocolClient(protocol, process.execPath, [path.resolve(process.argv[1])]) - }) - } - } else { - this.protocols.forEach((protocol: string) => { - app.setAsDefaultProtocolClient(protocol) - }) - } - - + // Verbose Check + if (app.commandLine.hasSwitch("verbose")) { + console.log("[Cider] User has launched the application with --verbose"); } - public quit() { - console.log('[AppEvents] App quit'); + // Log File Location + if (app.commandLine.hasSwitch("log") || app.commandLine.hasSwitch("l")) { + console.log(join(app.getPath("userData"), "logs")); + app.exit(); } - public ready(plug: any) { - this.plugin = plug - console.log('[AppEvents] App ready'); - } + // Try limiting JS memory to 350MB. + app.commandLine.appendSwitch("js-flags", "--max-old-space-size=350"); - public bwCreated() { - app.on('open-url', (event, url) => { - event.preventDefault() - if (this.protocols.some((protocol: string) => url.includes(protocol))) { - this.LinkHandler(url) - console.log(url) - } - }) + // Expose GC + app.commandLine.appendSwitch("js-flags", "--expose_gc"); - this.InstanceHandler() - this.InitTray() + if (process.platform === "win32") { + app.setAppUserModelId(app.getName()); // For notification name } /*********************************************************************************************************************** - * Private methods + * Commandline arguments **********************************************************************************************************************/ + switch (utils.getStoreValue("visual.hw_acceleration") as string) { + default: + case "default": + app.commandLine.appendSwitch("enable-accelerated-mjpeg-decode"); + app.commandLine.appendSwitch("enable-accelerated-video"); + app.commandLine.appendSwitch("disable-gpu-driver-bug-workarounds"); + app.commandLine.appendSwitch("ignore-gpu-blacklist"); + app.commandLine.appendSwitch("enable-native-gpu-memory-buffers"); + app.commandLine.appendSwitch("enable-accelerated-video-decode"); + app.commandLine.appendSwitch("enable-gpu-rasterization"); + app.commandLine.appendSwitch("enable-native-gpu-memory-buffers"); + app.commandLine.appendSwitch("enable-oop-rasterization"); + break; - /** - * Handles links (URI) and protocols for the application - * @param arg - */ - private LinkHandler(arg: string) { - if (!arg) return; - - // LastFM Auth URL - if (arg.includes('auth')) { - let authURI = arg.split('/auth/')[1] - if (authURI.startsWith('lastfm')) { // If we wanted more auth options - const authKey = authURI.split('lastfm?token=')[1]; - utils.setStoreValue('lastfm.enabled', true); - utils.setStoreValue('lastfm.auth_token', authKey); - utils.getWindow().webContents.send('LastfmAuthenticated', authKey); - this.plugin.callPlugin('lastfm', 'authenticate', authKey); - } + case "webgpu": + console.info("[AppEvents] WebGPU is enabled."); + app.commandLine.appendSwitch("enable-unsafe-webgpu"); + if (process.platform === "linux") { + app.commandLine.appendSwitch("enable-features", "Vulkan"); } - // Play - else if (arg.includes('/play/')) { //Steer away from protocol:// specific conditionals - const playParam = arg.split('/play/')[1] + break; - const mediaType = { - "s/": "song", - "a/": "album", - "p/": "playlist" - } - - for (const [key, value] of Object.entries(mediaType)) { - if (playParam.includes(key)) { - const id = playParam.split(key)[1] - utils.getWindow().webContents.send('play', value, id) - console.debug(`[LinkHandler] Attempting to load ${value} by id: ${id}`) - } - } - - } else if (arg.includes('music.apple.com')) { // URL (used with itms/itmss/music/musics uris) - console.log(arg) - let url = arg.split('//')[1] - console.warn(`[LinkHandler] Attempting to load url: ${url}`); - utils.getWindow().webContents.send('play', 'url', url) - } + case "disabled": + console.info("[AppEvents] Hardware acceleration is disabled."); + app.commandLine.appendSwitch("disable-gpu"); + app.disableHardwareAcceleration(); + break; } - /** - * Handles the creation of a new instance of the app - */ - private InstanceHandler() { - - // Detects of an existing instance is running (So if the lock has been achieved, no existing instance has been found) - const gotTheLock = app.requestSingleInstanceLock() - - if (!gotTheLock) { // Runs on the new instance if another instance has been found - console.log('[Cider] Another instance has been found, quitting.') - app.quit() - } else { // Runs on the first instance if no other instance has been found - app.on('second-instance', (_event, startArgs) => { - console.log("[InstanceHandler] (second-instance) Instance started with " + startArgs.toString()) - - startArgs.forEach(arg => { - console.log(arg) - if (arg.includes("cider://")) { - console.debug('[InstanceHandler] (second-instance) Link detected with ' + arg) - this.LinkHandler(arg) - } else if (arg.includes("--force-quit")) { - console.warn('[InstanceHandler] (second-instance) Force Quit found. Quitting App.'); - app.quit() - } else if (utils.getWindow()) { - if (utils.getWindow().isMinimized()) utils.getWindow().restore() - utils.getWindow().focus() - } - }) - }) - } + if (process.platform === "linux") { + app.commandLine.appendSwitch("disable-features", "MediaSessionService"); + if (os.version().includes("SteamOS")) { + app.commandLine.appendSwitch("enable-features", "UseOzonePlatform"); + app.commandLine.appendSwitch("ozone-platform", "x11"); + } } - /** - * Initializes the applications tray - */ - private InitTray() { - const icons = { - "win32": nativeImage.createFromPath(path.join(__dirname, `../../resources/icons/icon.ico`)).resize({ - width: 32, - height: 32 - }), - "linux": nativeImage.createFromPath(path.join(__dirname, `../../resources/icons/icon.png`)).resize({ - width: 32, - height: 32 - }), - "darwin": nativeImage.createFromPath(path.join(__dirname, `../../resources/icons/icon.png`)).resize({ - width: 20, - height: 20 - }), - } + /*********************************************************************************************************************** + * Protocols + **********************************************************************************************************************/ + /** */ + if (process.defaultApp) { + if (process.argv.length >= 2) { + this.protocols.forEach((protocol: string) => { + app.setAsDefaultProtocolClient(protocol, process.execPath, [resolve(process.argv[1])]); + }); + } + } else { + this.protocols.forEach((protocol: string) => { + app.setAsDefaultProtocolClient(protocol); + }); + } + } - this.tray = new Tray(process.platform === 'win32' ? icons.win32 : (process.platform === 'darwin' ? icons.darwin : icons.linux)) - this.tray.setToolTip(app.getName()) - this.setTray(false) + public quit() { + console.log("[AppEvents] App quit"); + } - this.tray.on('double-click', () => { - if (utils.getWindow()) { - if (utils.getWindow().isVisible()) { - utils.getWindow().focus() - } else { - utils.getWindow().show() - } - } - }) + public ready(plug: any) { + this.plugin = plug; + console.log("[AppEvents] App ready"); - utils.getWindow().on('show', () => { - this.setTray(true) - }) + AppEvents.setLoginSettings(); + } - utils.getWindow().on('restore', () => { - this.setTray(true) - }) + public bwCreated() { + app.on("open-url", (event, url) => { + event.preventDefault(); + if (this.protocols.some((protocol: string) => url.includes(protocol))) { + this.LinkHandler(url); + console.log(url); + } + }); - utils.getWindow().on('hide', () => { - this.setTray(false) - }) - - utils.getWindow().on('minimize', () => { - this.setTray(false) - }) + if (process.platform === "darwin") { + app.setUserActivity( + "8R23J2835D.com.ciderapp.webremote.play", + { + title: "Web Remote", + description: "Connect to your Web Remote", + }, + "https://webremote.cider.sh", + ); } - /** - * Sets the tray context menu to a given state - * @param visible - BrowserWindow Visibility - */ - private setTray(visible: boolean = utils.getWindow().isVisible()) { - this.i18n = utils.getLocale(utils.getStoreValue('general.language')) + this.InstanceHandler(); + if (process.platform !== "darwin") { + this.InitTray(); + } + } - const menu = Menu.buildFromTemplate([ + /*********************************************************************************************************************** + * Private methods + **********************************************************************************************************************/ + + /** + * Handles links (URI) and protocols for the application + * @param arg + */ + private LinkHandler(arg: string) { + if (!arg) return; + + // LastFM Auth URL + if (arg.includes("auth")) { + const authURI = arg.split("/auth/")[1]; + if (authURI.startsWith("lastfm")) { + // If we wanted more auth options + console.log("token: ", authURI.split("lastfm?token=")[1]); + utils + .getWindow() + .webContents.executeJavaScript(`ipcRenderer.send('lastfm:auth', ${JSON.stringify(authURI.split("lastfm?token=")[1])})`) + .catch(console.error); + } + } else if (arg.includes("playpause")) { + //language=JS + utils.getWindow().webContents.executeJavaScript("MusicKitInterop.playPause()"); + } else if (arg.includes("nextitem")) { + //language=JS + utils.getWindow().webContents.executeJavaScript("app.mk.skipToNextItem()"); + } + // Play + else if (arg.includes("/play/")) { + //Steer away from protocol:// specific conditionals + const playParam = arg.split("/play/")[1]; + + const mediaType = { + "s/": "song", + "a/": "album", + "p/": "playlist", + }; + + for (const [key, value] of Object.entries(mediaType)) { + if (playParam.includes(key)) { + const id = playParam.split(key)[1]; + utils.getWindow().webContents.send("play", value, id); + console.debug(`[LinkHandler] Attempting to load ${value} by id: ${id}`); + } + } + } else if (arg.includes("music.apple.com")) { + // URL (used with itms/itmss/music/musics uris) + console.log(arg); + let url = arg.split("//")[1]; + console.warn(`[LinkHandler] Attempting to load url: ${url}`); + utils.getWindow().webContents.send("play", "url", url); + } else if (arg.includes("/debug/appdata")) { + shell.openPath(app.getPath("userData")); + } else if (arg.includes("/debug/logs")) { + shell.openPath(app.getPath("logs")); + } else if (arg.includes("/discord")) { + shell.openExternal("https://discord.gg/applemusic"); + } else if (arg.includes("/github")) { + shell.openExternal("https://github.com/ciderapp/cider"); + } else if (arg.includes("/donate")) { + shell.openExternal("https://opencollective.com/ciderapp"); + } else if (arg.includes("/beep")) { + shell.beep(); + } else { + utils.getWindow().webContents.executeJavaScript(`app.appRoute(${JSON.stringify(arg.split("//")[1])})`); + } + } + + /** + * Handles the creation of a new instance of the app + */ + private InstanceHandler() { + // Detects of an existing instance is running (So if the lock has been achieved, no existing instance has been found) + const gotTheLock = app.requestSingleInstanceLock(); + + if (!gotTheLock) { + // Runs on the new instance if another instance has been found + console.log("[Cider] Another instance has been found, quitting."); + app.quit(); + } else { + // Runs on the first instance if no other instance has been found + app.on("second-instance", (_event, startArgs) => { + console.log("[InstanceHandler] (second-instance) Instance started with " + startArgs.toString()); + + startArgs.forEach((arg) => { + console.log(arg); + if (arg.includes("cider://") || arg.includes("itms://") || arg.includes("itmss://") || arg.includes("music://") || arg.includes("musics://")) { + console.debug("[InstanceHandler] (second-instance) Link detected with " + arg); + this.LinkHandler(arg); + } else if (arg.includes("--force-quit")) { + console.warn("[InstanceHandler] (second-instance) Force Quit found. Quitting App."); + app.quit(); + } else if (utils.getWindow()) { + if (utils.getWindow().isMinimized()) utils.getWindow().restore(); + utils.getWindow().show(); + utils.getWindow().focus(); + } + }); + }); + } + } + + /** + * Initializes the applications tray + */ + private InitTray() { + const icons = { + win32: nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.ico`)).resize({ + width: 32, + height: 32, + }), + linux: nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.png`)).resize({ + width: 32, + height: 32, + }), + darwin: nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.png`)).resize({ + width: 20, + height: 20, + }), + }; + this.tray = new Tray(process.platform === "win32" ? icons.win32 : process.platform === "darwin" ? icons.darwin : icons.linux); + this.tray.setToolTip(app.getName()); + this.setTray(false); + + this.tray.on("double-click", () => { // supports windows and mac only + if (utils.getWindow()) { + if (utils.getWindow().isVisible()) { + utils.getWindow().focus(); + } else { + utils.getWindow().show(); + } + } + }); + + this.tray.on("click", () => { + if (utils.getWindow() && process.platform === "linux") { // use single click to open when double doesn't work + if (utils.getWindow().isVisible()) { + utils.getWindow().focus(); + } else { + utils.getWindow().show(); + } + } + }); + + utils.getWindow().on("show", () => { + this.setTray(true); + }); + + utils.getWindow().on("restore", () => { + this.setTray(true); + }); + + utils.getWindow().on("hide", () => { + this.setTray(false); + }); + + utils.getWindow().on("minimize", () => { + this.setTray(false); + }); + } + + /** + * Sets the tray context menu to a given state + * @param visible - BrowserWindow Visibility + */ + private setTray(visible: boolean = utils.getWindow().isVisible()) { + this.i18n = utils.getLocale(utils.getStoreValue("general.language")); + + const ciderIcon = nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.png`)).resize({ + width: 24, + height: 24, + }); + + const menu = Menu.buildFromTemplate([ + { + label: app.getName(), + enabled: false, + icon: ciderIcon, + }, + + { type: "separator" }, + + /* For now only idea i dont know if posible to implement + + this could be implemented in a plugin if you would like track info, it would be impractical to put listeners in this file. -Core { - label: (visible ? this.i18n['action.tray.minimize'] : this.i18n['action.tray.show'].includes("{appName}") ? `${this.i18n['action.tray.show'].replace("{appName}", app.getName())}` : `${this.i18n['action.tray.show']} ${app.getName()}`), - click: () => { - if (utils.getWindow()) { - if (visible) { - utils.getWindow().hide() - } else { - utils.getWindow().show() - } - } - } + label: this.i18n['action.tray.listento'], + enabled: false, }, + { - label: this.i18n['action.tray.quit'], - click: () => { - app.quit() - } + visible: visible, + label: 'track info', + enabled: false, + }, + + {type: 'separator'}, + */ + + { + visible: !visible, + label: this.i18n["term.playpause"], + click: () => { + utils.getWindow().webContents.executeJavaScript("MusicKitInterop.playPause()"); + }, + }, + + { + visible: !visible, + label: this.i18n["term.next"], + click: () => { + utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`); + }, + }, + + { + visible: !visible, + label: this.i18n["term.previous"], + click: () => { + utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`); + }, + }, + + { type: "separator", visible: !visible }, + + { + label: visible ? this.i18n["action.tray.minimize"] : `${this.i18n["action.tray.show"]}`, + click: () => { + if (utils.getWindow()) { + if (visible) { + utils.getWindow().hide(); + } else { + utils.getWindow().show(); } - ]) - this.tray.setContextMenu(menu) + } + }, + }, + { + label: this.i18n["term.quit"], + click: () => { + app.quit(); + }, + }, + ]); + this.tray.setContextMenu(menu); + } + + /** + * Initializes logging in the application + * @private + */ + private static initLogging() { + log.transports.console.format = "[{h}:{i}:{s}.{ms}] [{level}] {text}"; + Object.assign(console, log.functions); + console.debug = function (...args: any[]) { + if (!app.isPackaged) { + log.debug(...args); + } + }; + + ipcMain.on("fetch-log", (_event) => { + const data = readFileSync(log.transports.file.getFile().path, { + encoding: "utf8", + flag: "r", + }); + clipboard.writeText(data); + }); + } + + /** + * Set login settings + * @private + */ + private static setLoginSettings() { + if (utils.getStoreValue("general.onStartup.enabled")) { + app.setLoginItemSettings({ + openAtLogin: true, + path: app.getPath("exe"), + args: [`${utils.getStoreValue("general.onStartup.hidden") ? "--hidden" : ""}`], + }); + } else { + app.setLoginItemSettings({ + openAtLogin: false, + path: app.getPath("exe"), + }); } + } } diff --git a/src/main/base/browserwindow.ts b/src/main/base/browserwindow.ts index d7729c16..8d29ec54 100644 --- a/src/main/base/browserwindow.ts +++ b/src/main/base/browserwindow.ts @@ -1,597 +1,1687 @@ -import * as path from "path"; -import {app, BrowserWindow as bw, ipcMain, shell} from "electron"; -import * as windowStateKeeper from "electron-window-state"; -import * as express from "express"; -import * as getPort from "get-port"; -import * as yt from "youtube-search-without-api-key"; -import * as fs from "fs"; -import {Stream} from "stream"; -import * as qrcode from "qrcode-terminal"; -import * as os from "os"; -import * as mm from 'music-metadata'; -import fetch from 'electron-fetch' -import {wsapi} from "./wsapi"; -import {jsonc} from "jsonc"; -import {NsisUpdater} from "electron-updater"; -import {utils} from './utils' +import AdmZip from "adm-zip"; +import { watch } from "chokidar"; +import { ShareMenu, app, BrowserWindow as bw, dialog, ipcMain, nativeTheme, screen, shell } from "electron"; +import windowStateKeeper from "electron-window-state"; +import express from "express"; +import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "fs"; +import getPort from "get-port"; +import { LocalFiles } from "../providers/local/index.js"; +import mm from "music-metadata"; +import fetch from "node-fetch"; +import os, { networkInterfaces } from "os"; +import { join } from "path"; +import { Stream } from "stream"; +import { getWallpaper } from "wallpaper"; +import { search } from "youtube-search-without-api-key"; +import { Plugins } from "./plugins.js"; +import { utils } from "./utils.js"; +import { wsapi } from "./wsapi.js"; +/** + * @file Creates the BrowserWindow + * @author CiderCollective + */ + +/** @namespace */ export class BrowserWindow { - public static win: any | undefined = null; - private devMode: boolean = !app.isPackaged; + public static win: any | undefined = null; + private devMode: boolean = !app.isPackaged; + public static express: any | undefined = null; - private paths: any = { - srcPath: path.join(__dirname, "../../src"), - resourcePath: path.join(__dirname, "../../resources"), - ciderCache: path.resolve(app.getPath("userData"), "CiderCache"), - themes: path.resolve(app.getPath("userData"), "Themes"), - plugins: path.resolve(app.getPath("userData"), "Plugins"), - }; - private audioStream: any = new Stream.PassThrough(); - private clientPort: number = 0; - private remotePort: number = 6942; - private EnvironmentVariables: object = { - env: { - platform: process.platform, - dev: app.isPackaged, + private audioStream: any = new Stream.PassThrough(); + private headerSent: any = false; + private chromecastIP: any = []; + private clientPort: number = 0; + private remotePort: number = 6942; + private EnvironmentVariables: object = { + env: { + platform: process.platform, + dev: app.isPackaged, + osRelease: os.release(), + updatable: !process.windowsStore || !process.mas, + useV3: utils.getStoreValue("advanced.experiments").includes("ampv3"), + components: [ + "pages/podcasts", + "pages/apple-account-settings", + "pages/library-songs", + "pages/library-albums", + "pages/library-artists", + "pages/library-recentlyadded", + "pages/browse", + "pages/groupings", + "pages/charts", + //"pages/installed-themes", + "pages/listen_now", + "pages/radio", + "pages/home", + "pages/artist-feed", + "pages/cider-playlist", + "pages/playlist-inline", + "pages/recordLabel", + "pages/cider-multiroom", + "pages/collection-list", + "pages/apple-curator", + "pages/artist", + "pages/search", + "pages/about", + "pages/library-videos", + "pages/remote-pair", + //"pages/themes-github", + //"pages/plugins-github", + "pages/replay", + "pages/audiolabs", + "pages/zoo", + "pages/plugin-renderer", + "pages/oobe", + "pages/cider-profile", + "components/c2-upgrade", + "components/app-content", + "components/sidebar", + "components/mediaitem-artwork", + "components/artwork-material", + "components/menu-panel", + "components/sidebar-playlist", + "components/audio-settings", + "components/plugin-menu", + "components/audio-controls", + "components/audio-playbackrate", + "components/qrcode-modal", + "components/moreinfo-modal", + "components/equalizer", + "components/add-to-playlist", + "components/queue", + "components/smarthints", + "components/mediaitem-scroller-horizontal", + "components/mediaitem-scroller-horizontal-large", + "components/mediaitem-scroller-horizontal-sp", + "components/mediaitem-scroller-horizontal-mvview", + "components/mediaitem-list-item", + "components/mediaitem-hrect", + "components/mediaitem-square", + "components/mediaitem-mvview", + // "components/libraryartist-item", + "components/listennow-child", + "components/mediaitem-mvview-sp", + "components/animatedartwork-view", + "components/listitem-horizontal", + "components/lyrics-view", + "components/fullscreen", + "components/miniplayer", + "components/castmenu", + "components/pathmenu", + "components/airplay-modal", + "components/artist-chip", + "components/hello-world", + "components/inline-collection-list", + "components/settings-window", + "components/pagination", + "components/settings-keybinds", + "components/settings-themes", + "components/settings-themes-github", + "components/settings-plugins-github", + ], + appRoutes: [ + { + page: "lzedit", + component: ``, + condition: "$root.page == 'lzedit'", }, - }; - private options: any = { - icon: path.join( - this.paths.resourcePath, - `icons/icon.` + (process.platform === "win32" ? "ico" : "png") - ), - width: 1024, - height: 600, - x: undefined, - y: undefined, - minWidth: 900, - minHeight: 390, - frame: false, - title: "Cider", - vibrancy: "dark", - transparent: process.platform === "darwin", - hasShadow: false, - show: false, - backgroundColor: "#1E1E1E", - webPreferences: { - nodeIntegration: true, - sandbox: true, - allowRunningInsecureContent: true, - contextIsolation: false, - webviewTag: true, - plugins: true, - nodeIntegrationInWorker: false, - webSecurity: false, - preload: path.join(this.paths.srcPath, "./preload/cider-preload.js"), + { + page: "library-recentlyadded", + component: ``, + condition: "$root.page == 'library-recentlyadded'", }, - }; + { + page: "plugin-renderer", + component: ``, + condition: "$root.page == 'plugin-renderer'", + }, + { + page: "zoo", + component: "", + condition: "$root.page == 'zoo'", + }, + { + page: "podcasts", + component: ``, + condition: `$root.page == 'podcasts'`, + }, + { + page: "library-videos", + component: ``, + condition: `$root.page == 'library-videos'`, + }, + { + page: "apple-account-settings", + component: ``, + condition: `$root.page == 'apple-account-settings'`, + }, + { + page: "about", + component: ``, + condition: `$root.page == 'about'`, + }, + { + page: "cider-artist", + component: ``, + condition: `$root.page == 'artist-page' && $root.artistPage.data.attributes`, + }, + { + page: "collection-list", + component: ``, + condition: `$root.page == 'collection-list'`, + }, + { + page: "home", + component: ``, + condition: `$root.page == 'home'`, + }, + { + page: "artist-feed", + component: ``, + condition: `$root.page == 'artist-feed'`, + }, + { + page: "playlist-inline", + component: ``, + condition: `$root.modals.showPlaylist`, + }, + { + page: "playlist_", + component: ``, + condition: `$root.page.includes('playlist_')`, + }, + { + page: "album_", + component: ``, + condition: `$root.page.includes('album_')`, + }, + { + page: "recordLabel_", + component: ``, + condition: `$root.page.includes('recordLabel_')`, + }, + { + page: "social-profiles_", + component: ``, + condition: `$root.page.includes('social-profiles_')`, + }, + { + page: "multiroom", + component: ``, + condition: `$root.page.includes('multiroom')`, + }, + { + page: "curator_", + component: ``, + condition: `$root.page.includes('curator_')`, + }, + { + page: "browsepage", + component: ``, + condition: `$root.page == 'browse'`, + onEnter: ``, + }, + { + page: "groupings", + component: ``, + condition: `$root.page == 'groupings'`, + onEnter: ``, + }, + { + page: "charts", + component: ``, + condition: `$root.page == 'charts'`, + onEnter: ``, + }, + { + page: "listen_now", + component: ``, + condition: `$root.page == 'listen_now'`, + onEnter: ``, + }, + { + page: "radio", + component: ``, + condition: `$root.page == 'radio'`, + onEnter: ``, + }, + { + page: "settings", + component: ``, + condition: `$root.page == 'settings'`, + }, + { + page: "installed-themes", + component: ``, + condition: `$root.page == 'installed-themes'`, + }, + { + page: "search", + component: ``, + condition: `$root.page == 'search'`, + }, + { + page: "library-songs", + component: ``, + condition: `$root.page == 'library-songs'`, + onEnter: ``, + }, + { + page: "library-albums", + component: ``, + condition: `$root.page == 'library-albums'`, + onEnter: ``, + }, + { + page: "library-artists", + component: ``, + condition: `$root.page == 'library-artists'`, + onEnter: ``, + }, + { + page: "appleCurator", + component: ``, + condition: `$root.page.includes('appleCurator')`, + }, + { + page: "themes-github", + component: ``, + condition: `$root.page == 'themes-github'`, + }, + { + page: "plugins-github", + component: ``, + condition: `$root.page == 'plugins-github'`, + }, + { + page: "remote-pair", + component: ``, + condition: `$root.page == 'remote-pair'`, + }, + { + page: "audiolabs", + component: ``, + condition: `$root.page == 'audiolabs'`, + }, + { + page: "replay", + component: ``, + condition: `$root.page == 'replay'`, + }, + { + page: "keydinds", + component: ``, + condition: `$root.page == 'keybinds-settings'`, + }, + ], + }, + }; + private options: any = { + icon: join(utils.getPath("resourcePath"), `icons/icon.` + (process.platform === "win32" ? "ico" : "png")), + width: 1024, + height: 600, + x: undefined, + y: undefined, + minWidth: 900, + minHeight: 390, + frame: false, + title: "Cider", + show: false, + // backgroundColor: "#1E1E1E", + titleBarStyle: "hidden", + trafficLightPosition: { x: 15, y: 20 }, + webPreferences: { + experimentalFeatures: true, + nodeIntegration: true, + sandbox: true, + allowRunningInsecureContent: true, + contextIsolation: false, + webviewTag: true, + plugins: true, + nodeIntegrationInWorker: true, + webSecurity: false, + preload: join(utils.getPath("srcPath"), "./preload/cider-preload.js"), + }, + }; - /** - * Creates the browser window - */ - async createWindow(): Promise { - this.clientPort = await getPort({port: 9000}); - this.verifyFiles(); + public static watcher: any; - // Load the previous state with fallback to defaults - const windowState = windowStateKeeper({ - defaultWidth: 1024, - defaultHeight: 600, - }); - this.options.width = windowState.width; - this.options.height = windowState.height; + StartWatcher(path: string) { + BrowserWindow.watcher = watch(path, { + ignored: /[\/\\]\./, + persistent: true, + }); - // Start the webserver for the browser window to load - - this.startWebServer(); - - BrowserWindow.win = new bw(this.options); - const ws = new wsapi(BrowserWindow.win) - ws.InitWebSockets() - // and load the renderer. - this.startSession(); - this.startHandlers(); - - // Register listeners on Window to track size and position of the Window. - windowState.manage(BrowserWindow.win); - - return BrowserWindow.win + function onWatcherReady() { + console.info("From here can you check for real changes, the initial scan has been completed."); } - /** - * Verifies the files for the renderer to use (Cache, library info, etc.) - */ - private verifyFiles(): void { - const expectedDirectories = ["CiderCache"]; - const expectedFiles = [ - "library-songs.json", - "library-artists.json", - "library-albums.json", - "library-playlists.json", - "library-recentlyAdded.json", - ]; - for (let i = 0; i < expectedDirectories.length; i++) { - if ( - !fs.existsSync( - path.join(app.getPath("userData"), expectedDirectories[i]) - ) - ) { - fs.mkdirSync( - path.join(app.getPath("userData"), expectedDirectories[i]) - ); - } - } - for (let i = 0; i < expectedFiles.length; i++) { - const file = path.join(this.paths.ciderCache, expectedFiles[i]); - if (!fs.existsSync(file)) { - fs.writeFileSync(file, JSON.stringify([])); - } - } - } + // Declare the listeners of the watcher + BrowserWindow.watcher + .on("add", function (path: string) { + // console.log('File', path, 'has been added'); + }) + .on("addDir", function (path: string) { + // console.log('Directory', path, 'has been added'); + }) + .on("change", function (path: string) { + console.log("File", path, "has been changed"); + BrowserWindow.win.webContents.send("theme-update", ""); + }) + .on("unlink", function (path: string) { + // console.log('File', path, 'has been removed'); + }) + .on("unlinkDir", function (path: string) { + // console.log('Directory', path, 'has been removed'); + }) + .on("error", function (error: string) { + // console.log('Error happened', error); + }) + .on("ready", onWatcherReady) + .on("raw", function (event: any, path: any, details: any) { + // This event should be triggered everytime something happens. + // console.log('Raw event info:', event, path, details); + }); + } - /** - * Starts the webserver for the renderer process. - */ - private startWebServer(): void { - const app = express(); + async StopWatcher() { + await BrowserWindow.watcher.close(); + } - app.use(express.static(path.join(this.paths.srcPath, "./renderer/"))); - app.set("views", path.join(this.paths.srcPath, "./renderer/views")); - app.set("view engine", "ejs"); - let firstRequest = true; - app.use((req, res, next) => { - if (!req || !req.headers || !req.headers.host || !req.headers["user-agent"]) { - console.error('Req not defined') - return - } - if (req.url.includes("audio.webm") || (req.headers.host.includes("localhost") && (this.devMode || req.headers["user-agent"].includes("Electron")))) { - next(); - } else { - res.redirect("https://discord.gg/applemusic"); - } - }); + /** + * Creates the browser window + * @generator + * @function createWindow + * @yields {object} Electron browser window + */ + async createWindow(): Promise { + const envPort = process.env?.CIDER_PORT || "9000"; + this.clientPort = await getPort({ port: parseInt(envPort, 10) || 9000 }); + BrowserWindow.verifyFiles(); + this.StartWatcher(utils.getPath("themes")); - app.get("/", (_req, res) => { - res.render("main", this.EnvironmentVariables); - }); + // Load the previous state with fallback to defaults + const windowState = windowStateKeeper({ + defaultWidth: 1024, + defaultHeight: 600, + fullScreen: false, + }); + this.options.width = windowState.width; + this.options.height = windowState.height; + this.options.x = windowState.x; + this.options.y = windowState.y; - app.get("/audio.webm", (req, res) => { - try { - req.socket.setTimeout(Number.MAX_SAFE_INTEGER); - // CiderBase.requests.push({req: req, res: res}); - // var pos = CiderBase.requests.length - 1; - // req.on("close", () => { - // console.info("CLOSED", CiderBase.requests.length); - // requests.splice(pos, 1); - // console.info("CLOSED", CiderBase.requests.length); - // }); - this.audioStream.on("data", (data: any) => { - try { - res.write(data); - } catch (ex) { - console.log(ex); - } - }); - } catch (ex) { - console.log(ex); - } - }); - //app.use(express.static()) - - app.listen(this.clientPort, () => { - console.log(`Cider client port: ${this.clientPort}`); - }); - - /* - * Remote Client (I had no idea how to add it to our existing express server, so I just made another one) -@quacksire - * TODO: Broadcast the remote so that /web-remote/ can connect - * https://github.com/ciderapp/Apple-Music-Electron/blob/818ed18940ff600d76eb59d22016723a75885cd5/resources/functions/handler.js#L1173 - */ - const remote = express(); - remote.use(express.static(path.join(this.paths.srcPath, "./web-remote/"))) - remote.set("views", path.join(this.paths.srcPath, "./web-remote/views")); - remote.set("view engine", "ejs"); - getPort({port: 6942}).then((port) => { - this.remotePort = port; - // Start Remote Discovery - this.broadcastRemote() - remote.listen(this.remotePort, () => { - console.log(`Cider remote port: ${this.remotePort}`); - if (firstRequest) { - console.log("---- Ignore Me ;) ---"); - qrcode.generate(`http://${os.hostname}:${this.remotePort}`); - console.log("---- Ignore Me ;) ---"); - /* - * - * USING https://www.npmjs.com/package/qrcode-terminal for terminal - * WE SHOULD USE https://www.npmjs.com/package/qrcode for the remote (or others) for showing to user via an in-app dialog - * -@quacksire - */ - } - firstRequest = false; - }) - remote.get("/", (_req, res) => { - res.render("index", this.EnvironmentVariables); - }); - }) - } - - /** - * Starts the session for the renderer process. - */ - private startSession(): void { - // intercept "https://js-cdn.music.apple.com/hls.js/2.141.1/hls.js/hls.js" and redirect to local file "./apple-hls.js" instead - BrowserWindow.win.webContents.session.webRequest.onBeforeRequest( - { - urls: ["https://*/*.js"], - }, - ( - details: { url: string | string[] }, - callback: (arg0: { redirectURL?: string; cancel?: boolean }) => void - ) => { - if (details.url.includes("hls.js")) { - callback({ - redirectURL: `http://localhost:${this.clientPort}/apple-hls.js`, - }); - } else { - callback({ - cancel: false, - }); - } - } - ); - - BrowserWindow.win.webContents.session.webRequest.onBeforeSendHeaders( - async ( - details: { url: string; requestHeaders: { [x: string]: string } }, - callback: (arg0: { requestHeaders: any }) => void - ) => { - if (details.url === "https://buy.itunes.apple.com/account/web/info") { - details.requestHeaders["sec-fetch-site"] = "same-site"; - details.requestHeaders["DNT"] = "1"; - let itspod = await BrowserWindow.win.webContents.executeJavaScript( - `window.localStorage.getItem("music.ampwebplay.itspod")` - ); - if (itspod != null) - details.requestHeaders["Cookie"] = `itspod=${itspod}`; - } - callback({requestHeaders: details.requestHeaders}); - } - ); - - let location = `http://localhost:${this.clientPort}/`; - - if (app.isPackaged) { - BrowserWindow.win.loadURL(location); + switch (process.platform) { + default: + break; + case "win32": + if (!(utils.getStoreValue("visual.transparent") ?? false)) { + this.options.backgroundColor = "#1E1E1E"; } else { - BrowserWindow.win.loadURL(location, { - userAgent: "Cider Development Environment", - }); + this.options.transparent = true; } + this.options.autoHideMenuBar = true; + if (utils.getStoreValue("visual.nativeTitleBar")) { + this.options.titleBarStyle = "visible"; + this.options.frame = true; + } + break; + case "linux": + this.options.autoHideMenuBar = true; + if (!(utils.getStoreValue("visual.transparent") ?? false)) { + this.options.backgroundColor = "#1E1E1E"; + } else { + this.options.transparent = true; + } + if (utils.getStoreValue("visual.nativeTitleBar")) { + this.options.titleBarStyle = "visible"; + this.options.frame = true; + } + break; + case "darwin": + this.options.transparent = true; + this.options.vibrancy = "dark"; + this.options.hasShadow = true; + break; } - /** - * Initializes the window handlers + nativeTheme.themeSource = utils.getStoreValue("visual.overrideDisplayTheme"); + + // Start the webserver for the browser window to load + // LocalFiles.DB.init() + this.startWebServer(); + + BrowserWindow.win = new bw(this.options); + // cant be built in CI + // if (process.platform === "win32" && (utils.getStoreValue('visual.transparent') ?? false)) { + // var electronVibrancy = require('electron-vibrancy-updated'); + // electronVibrancy.SetVibrancy(BrowserWindow.win, 0); + + // } + const ws = new wsapi(BrowserWindow.win); + ws.InitWebSockets(); + // and load the renderer. + this.startSession(); + this.startHandlers(); + + // Register listeners on Window to track size and position of the Window. + windowState.manage(BrowserWindow.win); + + return BrowserWindow.win; + } + + /** + * Verifies the files for the renderer to use (Cache, library info, etc.) + */ + private static verifyFiles(): void { + const expectedDirectories = ["CiderCache"]; + const expectedFiles = ["library-songs.json", "library-artists.json", "library-albums.json", "library-playlists.json", "library-recentlyAdded.json"]; + for (let i = 0; i < expectedDirectories.length; i++) { + if (!existsSync(join(app.getPath("userData"), expectedDirectories[i]))) { + mkdirSync(join(app.getPath("userData"), expectedDirectories[i])); + } + } + for (let i = 0; i < expectedFiles.length; i++) { + const file = join(join(app.getPath("userData"), "CiderCache"), expectedFiles[i]); + if (!existsSync(file)) { + writeFileSync(file, JSON.stringify([])); + } + } + } + + /** + * Starts the webserver for the renderer process. + */ + private startWebServer(): void { + const app = express(); + BrowserWindow.express = app; + app.use(express.static(join(utils.getPath("srcPath"), "./renderer/"))); + app.set("views", join(utils.getPath("srcPath"), "./renderer/views")); + app.set("view engine", "ejs"); + let firstRequest = true; + app.use((req, res, next) => { + if (!req || !req.headers || !req.headers.host || !req.headers["user-agent"]) { + console.error("Req not defined"); + return; + } + if (req.url.includes("api") || req.url.includes("audio.wav") || (req.headers.host.includes("localhost") && (this.devMode || req.headers["user-agent"].includes("Electron"))) || req.url.includes("/connect")) { + next(); + } else { + res.redirect("https://discord.gg/applemusic"); + } + }); + + app.get("/", (_req, res) => { + res.render("main", this.EnvironmentVariables); + }); + + app.get("/audio/cideraudio.js", (_req, res) => { + if (existsSync(join(utils.getPath("externals"), "/audio.js"))) { + if (utils.getStoreValue("audio.maikiwiAudio.cloud") == true) { + res.sendFile(join(utils.getPath("externals"), "/cloud/audio.js")); + } else { + res.sendFile(join(utils.getPath("externals"), "/audio.js")); + } + } else { + res.sendFile(join(utils.getPath("srcPath"), "./renderer/audio/audio.js")); + } + }); + + app.get("/cideraudio/impulses/:file", (req, res) => { + const impulseExternals = join(utils.getPath("externals"), "/impulses/"); + const impulseFile = join(impulseExternals, req.params.file); + if (existsSync(impulseFile)) { + res.sendFile(impulseFile); + } else { + res.sendFile(join(utils.getPath("srcPath"), "./renderer/audio/impulses/" + req.params.file)); + } + }); + + app.get("/api/playback/:action", (req, res) => { + const action = req.params.action; + switch (action) { + case "playpause": + BrowserWindow.win.webContents.executeJavaScript("wsapi.togglePlayPause()"); + res.send("Play/Pause toggle"); + break; + case "play": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().play()"); + res.send("Playing"); + break; + case "pause": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().pause()"); + res.send("Paused"); + break; + case "stop": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().stop()"); + res.send("Stopped"); + break; + case "next": + BrowserWindow.win.webContents.executeJavaScript("if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);}"); + res.send("Next"); + break; + case "previous": + BrowserWindow.win.webContents.executeJavaScript("if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex);}"); + res.send("Previous"); + break; + default: { + res.send("Invalid action"); + } + } + }); + + app.get("/themes/:theme", (req, res) => { + const theme = req.params.theme; + const themePath = join(utils.getPath("srcPath"), "./renderer/themes/", theme); + const userThemePath = join(utils.getPath("themes"), theme); + if (existsSync(userThemePath)) { + res.sendFile(userThemePath); + } else if (existsSync(themePath)) { + res.sendFile(themePath); + } else { + res.send(`// Theme not found - ${userThemePath}`); + } + }); + + app.get("/themes/:theme/*", (req: { params: { theme: string; 0: string } }, res) => { + const theme = req.params.theme; + const file = req.params[0]; + const themePath = join(utils.getPath("srcPath"), "./renderer/themes/", theme); + const userThemePath = join(utils.getPath("themes"), theme); + if (existsSync(userThemePath)) { + res.sendFile(join(userThemePath, file)); + } else if (existsSync(themePath)) { + res.sendFile(join(themePath, file)); + } else { + res.send(`// File not found - ${userThemePath}`); + } + }); + + app.get("/plugins/:plugin/*", (req: { params: { plugin: string; 0: string } }, res) => { + let plugin = req.params.plugin; + if (Plugins.getPluginFromMap(plugin)) { + plugin = Plugins.getPluginFromMap(plugin); + } + const file = req.params[0]; + const pluginPath = join(utils.getPath("plugins"), plugin); + console.log(pluginPath); + if (existsSync(pluginPath)) { + res.sendFile(join(pluginPath, file)); + } else { + res.send(`// Plugin not found - ${pluginPath}`); + } + }); + + app.get("/audio.wav", (req, res) => { + try { + const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress; + if (!this.chromecastIP.includes(ip)) { + this.headerSent = false; + this.audioStream._readableState.buffer.clear(); + this.audioStream._readableState.length = 0; + this.chromecastIP.push(ip); + } + req.socket.setTimeout(Number.MAX_SAFE_INTEGER); + // CiderBase.requests.push({req: req, res: res}); + // var pos = CiderBase.requests.length - 1; + req.on("close", () => { + console.log("disconnected"); + this.headerSent = false; + this.chromecastIP = this.chromecastIP.filter((item: any) => item !== ip); + }); + + this.audioStream.on("data", (data: any) => { + try { + res.write(data); + } catch (ex) { + console.log(ex); + } + }); + } catch (ex) { + console.log(ex); + } + }); + //region Connect Integration + app.get("/connect/set-cc-user/:data", (req, res) => { + //utils.getStoreValue('connectUser', JSON.parse()) // [Connect] Save user in store + utils.getWindow().webContents.send("setStoreValue", "connectUser", JSON.parse(req.params.data)); + res.redirect(`https://connect.cidercollective.dev/linked.html`); + }); + + LocalFiles.setupHandlers(); + + // [Connect] Set auth URL in store for `shell.openExternal` + utils.setStoreValue("cc_authURL", `https://connect.cidercollective.dev/callback/discord?app=cider&appPort=${this.clientPort}`); + console.log(`[Connect] Auth URL: ${utils.getStoreValue("cc_authURL")}`); + //endregion + + app.listen(this.clientPort, () => { + console.log(`Cider client port: ${this.clientPort}`); + }); + + /* + * Remote Client -@quacksire + * https://github.com/ciderapp/Apple-Music-Electron/blob/818189ed40ff600d76eb59d22016723a75885cd5/resources/functions/handler.js#L1173 */ - private startHandlers(): void { - /********************************************************************************************************************** - * ipcMain Events - ****************************************************************************************************************** */ - ipcMain.on("cider-platform", (event) => { - event.returnValue = process.platform; - }); + const remote = express(); + remote.use(express.static(join(utils.getPath("srcPath"), "./web-remote/"))); + remote.set("views", join(utils.getPath("srcPath"), "./web-remote/views")); + remote.set("view engine", "ejs"); + getPort({ port: 6942 }).then((port: number) => { + this.remotePort = port; + // Start Remote Discovery + this.broadcastRemote(); + remote.listen(this.remotePort, () => { + console.log(`Cider remote port: ${this.remotePort}`); + firstRequest = false; + }); + remote.get("/", (_req, res) => { + res.render("index", this.EnvironmentVariables); + }); + }); + } - ipcMain.on("get-i18n", (event, key) => { - event.returnValue = utils.getLocale(key); - }); + /** + * Starts the session for the renderer process. + */ + private startSession(): void { + // intercept "https://js-cdn.music.apple.com/hls.js/2.141.1/hls.js/hls.js" and redirect to local file "./apple-hls.js" instead + BrowserWindow.win.webContents.session.webRequest.onBeforeRequest( + { + urls: ["https://*/*"], + }, + (details: { url: string | string[] }, callback: (arg0: { redirectURL?: string; cancel?: boolean }) => void) => { + if (details.url.includes("hls.js")) { + callback({ + redirectURL: `http://localhost:${this.clientPort}/apple-hls.js`, + }); + } else if (details.url.includes("ciderlocal") && !details.url.includes("https://apic-desktop.musixmatch.com")) { + let text = details.url.toString().includes("ids=") ? decodeURIComponent(details.url.toString()).split("?ids=")[1] : decodeURIComponent(details.url.toString().substring(details.url.toString().lastIndexOf("/") + 1)); + //console.log('localurl',text) + callback({ + redirectURL: `http://localhost:${this.clientPort}/ciderlocal/${Buffer.from(text).toString("base64url")}`, + }); + } else { + callback({ + cancel: false, + }); + } + }, + ); - ipcMain.on("get-i18n-listing", event => { - let i18nFiles = fs.readdirSync(path.join(__dirname, "../../src/i18n")).filter(file => file.endsWith(".jsonc")); - // read all the files and parse them - let i18nListing = [] - for (let i = 0; i < i18nFiles.length; i++) { - const i18n: { [index: string]: Object } = jsonc.parse(fs.readFileSync(path.join(__dirname, `../../src/i18n/${i18nFiles[i]}`), "utf8")); - i18nListing.push({ - "code": i18nFiles[i].replace(".jsonc", ""), - "nameNative": i18n["i18n.languageName"] ?? i18nFiles[i].replace(".jsonc", ""), - "nameEnglish": i18n["i18n.languageNameEnglish"] ?? i18nFiles[i].replace(".jsonc", ""), - "category": i18n["i18n.category"] ?? "", - "authors": i18n["i18n.authors"] ?? "" - }) - } - event.returnValue = i18nListing; - }) + BrowserWindow.win.webContents.session.webRequest.onBeforeSendHeaders(async (details: { url: string; requestHeaders: { [x: string]: string } }, callback: (arg0: { requestHeaders: any }) => void) => { + if (details.url === "https://buy.itunes.apple.com/account/web/info") { + details.requestHeaders["sec-fetch-site"] = "same-site"; + details.requestHeaders["DNT"] = "1"; + let itspod = await BrowserWindow.win.webContents.executeJavaScript(`window.localStorage.getItem("music.ampwebplay.itspod")`); + if (itspod != null) details.requestHeaders["Cookie"] = `itspod=${itspod}`; + } + if (details.url.includes("apple.com")) { + details.requestHeaders["DNT"] = "1"; + details.requestHeaders["authority"] = "amp-api.music.apple.com"; + details.requestHeaders["origin"] = "https://beta.music.apple.com"; + details.requestHeaders["referer"] = "https://beta.music.apple.com"; + details.requestHeaders["sec-fetch-dest"] = "empty"; + details.requestHeaders["sec-fetch-mode"] = "cors"; + details.requestHeaders["sec-fetch-site"] = "same-site"; + } + if (details.url.startsWith("https://music.163.com")) { + details.requestHeaders["Referer"] = "https://music.163.com/"; + details.requestHeaders["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Cider/1.0.0 Chrome/96.0.4664.45 Electron/16.0.0 Safari/537.36"; + } + if (details.url.includes("https://qq.com")) { + (details.requestHeaders["Accept"] = "*/*"), (details.requestHeaders["Accept-Encoding"] = "gzip, deflate, br"), (details.requestHeaders["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"), (details.requestHeaders["Referer"] = "https://y.qq.com/"), (details.requestHeaders["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X; zh-CN) AppleWebKit/537.51.1 ("); + ("KHTML, like Gecko) Mobile/17D50 UCBrowser/12.8.2.1268 Mobile AliApp(TUnionSDK/0.1.20.3) "); + } + if (details.url.includes("https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg")) { + (details.requestHeaders["Accept"] = "*/*"), (details.requestHeaders["Accept-Encoding"] = "gzip, deflate, br"), (details.requestHeaders["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"), (details.requestHeaders["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X; zh-CN) AppleWebKit/537.51.1 ("); + ("KHTML, like Gecko) Mobile/17D50 UCBrowser/12.8.2.1268 Mobile AliApp(TUnionSDK/0.1.20.3) "); + details.requestHeaders["Referer"] = "https://y.qq.com/portal/player.html"; + } + callback({ requestHeaders: details.requestHeaders }); + }); - ipcMain.on("get-gpu-mode", (event) => { - event.returnValue = process.platform; - }); + let location = `http://localhost:${this.clientPort}/`; - ipcMain.on("is-dev", (event) => { - event.returnValue = this.devMode; - }); + if (app.isPackaged) { + BrowserWindow.win.loadURL(location); + } else { + BrowserWindow.win.loadURL(location, { + userAgent: "Cider Development Environment", + }); + } + } - ipcMain.on("put-library-songs", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-songs.json"), - JSON.stringify(arg) - ); - }); + /** + * Initializes the window handlers + */ + private startHandlers(): void { + /********************************************************************************************************************** + * ipcMain Events + ****************************************************************************************************************** */ - ipcMain.on("put-library-artists", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-artists.json"), - JSON.stringify(arg) - ); - }); + ipcMain.handle("mkv3", async (event, args) => { + const options = { + route: "", + token: "", + mediaToken: "", + GETBody: {}, + }; + Object.assign(options, args); - ipcMain.on("put-library-albums", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-albums.json"), - JSON.stringify(arg) - ); - }); + let res = await fetch( + `https://amp-api.music.apple.com/${options.route}?${new URLSearchParams({ + ...options.GETBody, + }).toString()}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + authorization: `Bearer ${options.token}`, + path: options.route, + authority: "amp-api.music.apple.com", + "media-user-token": options.mediaToken, + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Cider/1.4.2 Chrome/100.0.4896.75 Electron/18.0.3 Safari/537.36", + }, + }, + ); + let json = await res.json(); + return json; + }); - ipcMain.on("put-library-playlists", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-playlists.json"), - JSON.stringify(arg) - ); - }); + ipcMain.on("get-wallpaper", async (event, args) => { + const wpPath: string = await getWallpaper(); + const Jimp = (await import("jimp")).default; + const img = await Jimp.read(wpPath); + const blurAmount = args.blurAmount ?? 256; + if (blurAmount) { + img.blur(blurAmount); + } + const screens = await screen.getAllDisplays(); + const width = screens.reduce((a, b) => a + b.size.width, 0); + const height = screens.reduce((a, b) => a + b.size.height, 0); - ipcMain.on("put-library-recentlyAdded", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-recentlyAdded.json"), - JSON.stringify(arg) - ); - }); + img.cover(width, height, Jimp.HORIZONTAL_ALIGN_LEFT | Jimp.VERTICAL_ALIGN_MIDDLE); + const result = await img.getBase64Async(Jimp.MIME_PNG); - ipcMain.on("get-library-songs", (event) => { - let librarySongs = fs.readFileSync( - path.join(this.paths.ciderCache, "library-songs.json"), - "utf8" - ); - event.returnValue = JSON.parse(librarySongs); - }); + event.returnValue = { + path: wpPath, + data: result, + res: { + width: width, + height: height, + }, + }; + }); - ipcMain.on("get-library-artists", (event) => { - let libraryArtists = fs.readFileSync( - path.join(this.paths.ciderCache, "library-artists.json"), - "utf8" - ); - event.returnValue = JSON.parse(libraryArtists); - }); - - ipcMain.on("get-library-albums", (event) => { - let libraryAlbums = fs.readFileSync( - path.join(this.paths.ciderCache, "library-albums.json"), - "utf8" - ); - event.returnValue = JSON.parse(libraryAlbums); - }); - - ipcMain.on("get-library-playlists", (event) => { - let libraryPlaylists = fs.readFileSync( - path.join(this.paths.ciderCache, "library-playlists.json"), - "utf8" - ); - event.returnValue = JSON.parse(libraryPlaylists); - }); - - ipcMain.on("get-library-recentlyAdded", (event) => { - let libraryRecentlyAdded = fs.readFileSync( - path.join(this.paths.ciderCache, "library-recentlyAdded.json"), - "utf8" - ); - event.returnValue = JSON.parse(libraryRecentlyAdded); - }); - - ipcMain.handle("getYTLyrics", async (_event, track, artist) => { - const u = track + " " + artist + " official video"; - return await yt.search(u); - }); - - ipcMain.on("close", () => { - BrowserWindow.win.close(); - }); - - ipcMain.on("maximize", () => { - // listen for maximize event - if (BrowserWindow.win.isMaximized()) { - BrowserWindow.win.unmaximize(); - } else { - BrowserWindow.win.maximize(); - } - }); - ipcMain.on("unmaximize", () => { - // listen for maximize event - BrowserWindow.win.unmaximize(); - }); - - ipcMain.on("minimize", () => { - // listen for minimize event - BrowserWindow.win.minimize(); - }); - - // Set scale - ipcMain.on("setScreenScale", (_event, scale) => { - BrowserWindow.win.webContents.setZoomFactor(parseFloat(scale)); - }); - - ipcMain.on("windowmin", (_event, width, height) => { - BrowserWindow.win.setMinimumSize(width, height); - }) - - ipcMain.on("windowontop", (_event, ontop) => { - BrowserWindow.win.setAlwaysOnTop(ontop); - }); - - // Set scale - ipcMain.on("windowresize", (_event, width, height, lock = false) => { - BrowserWindow.win.setContentSize(width, height); - BrowserWindow.win.setResizable(!lock); - }); - - //Fullscreen - ipcMain.on('setFullScreen', (_event, flag) => { - BrowserWindow.win.setFullScreen(flag) - }) - //Fullscreen - ipcMain.on('detachDT', (_event, _) => { - BrowserWindow.win.webContents.openDevTools({mode: 'detach'}); - }) - - - ipcMain.on('play', (_event, type, id) => { - BrowserWindow.win.webContents.executeJavaScript(` - MusicKit.getInstance().setQueue({ ${type}: '${id}'}).then(function(queue) { - MusicKit.getInstance().play(); - }); - `) - }) - - //QR Code - ipcMain.handle('showQR', async (event, _) => { - let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`; - shell.openExternal(`https://cider.sh/pair-remote?url=${Buffer.from(encodeURI(url)).toString('base64')}`).catch(console.error); - }) - - // Get previews for normalization - ipcMain.on("getPreviewURL", (_event, url) => { - - fetch(url) - .then(res => res.buffer()) - .then(async (buffer) => { - const metadata = await mm.parseBuffer(buffer, 'audio/x-m4a'); - let SoundCheckTag = metadata.native.iTunes[1].value - console.log('sc', SoundCheckTag) - BrowserWindow.win.webContents.send('SoundCheckTag', SoundCheckTag) - }).catch(err => { - console.log(err) + ipcMain.handle("uninstall-theme", async (event, path) => { + await this.StopWatcher(); + const themesDir = utils.getPath("themes"); + // validate the path is in the themes directory + try { + if (path.startsWith(themesDir)) { + // get last dir in path, can be either / or \ and may have a trailing slash + const themeName = path.split(/[\\\/]/).pop(); + if (themeName == "Themes" || themeName == "themes") { + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + status: 3, }); + return; + } + // if path is directory, delete it + if (lstatSync(path).isDirectory()) { + await rmdirSync(path, { recursive: true }); + } else { + // if path is file, delete it + await unlinkSync(path); + } + // return the path + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + status: 0, + }); + } else { + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + status: 1, + }); + } + } catch (e: any) { + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + message: e.message, + status: 2, }); + } - ipcMain.on('check-for-update', async (_event, url) => { - const options: any = { - provider: 'generic', - url: 'https://43-429851205-gh.circle-artifacts.com/0/%7E/Cider/dist/artifacts' //Base URL + this.StartWatcher(utils.getPath("themes")); + }); + + ipcMain.handle("reinstall-widevine-cdm", () => { + // remove WidevineCDM from appdata folder + const widevineCdmPath = join(app.getPath("userData"), "./WidevineCdm"); + if (existsSync(widevineCdmPath)) { + rmSync(widevineCdmPath, { recursive: true, force: true }); + } + // reinstall WidevineCDM + app.relaunch(); + app.exit(); + }); + + ipcMain.handle("get-github-plugin", async (event, url) => { + await this.StopWatcher(); + const returnVal = { + success: true, + theme: null, + message: "", + }; + try { + if (!existsSync(utils.getPath("plugins"))) { + mkdirSync(utils.getPath("plugins")); + } + if (url.endsWith("/")) url = url.slice(0, -1); + let response = await utils.fetch(`${url}/archive/refs/heads/main.zip`); + let repo = url.split("/").slice(-2).join("/"); + let apiRepo = await utils.fetch(`https://api.github.com/repos/${repo}`).then((res) => res.json()) as { id: number}; + console.debug(`REPO ID: ${apiRepo.id}`); + // extract the files from the first folder in the zip response + let zip = new AdmZip(await response.buffer()); + let entry = zip.getEntries()[0]; + if (!existsSync(join(utils.getPath("plugins"), "gh_" + apiRepo.id))) { + mkdirSync(join(utils.getPath("plugins"), "gh_" + apiRepo.id)); + } + console.log(join(utils.getPath("plugins"), "gh_" + apiRepo.id)); + zip.extractEntryTo(entry, join(utils.getPath("plugins"), "gh_" + apiRepo.id), false, true); + let commit = await utils.fetch(`https://api.github.com/repos/${repo}/commits`).then((res) => res.json()) as { sha: string }[]; + console.debug(`COMMIT SHA: ${commit[0].sha}`); + let theme = JSON.parse(readFileSync(join(utils.getPath("plugins"), "gh_" + apiRepo.id, "package.json"), "utf8")); + theme.id = apiRepo.id; + theme.commit = commit[0].sha; + writeFileSync(join(utils.getPath("plugins"), "gh_" + apiRepo.id, "package.json"), JSON.stringify(theme, null, 4), "utf8"); + } catch (e) { + returnVal.success = false; + } + BrowserWindow.win.webContents.send("plugin-installed", returnVal); + this.StartWatcher(utils.getPath("themes")); + }); + + ipcMain.handle("get-github-theme", async (event, url) => { + await this.StopWatcher(); + const returnVal = { + success: true, + theme: null, + message: "", + }; + try { + if (!existsSync(utils.getPath("themes"))) { + mkdirSync(utils.getPath("themes")); + } + if (url.endsWith("/")) url = url.slice(0, -1); + let response = await utils.fetch(`${url}/archive/refs/heads/main.zip`); + let repo = url.split("/").slice(-2).join("/"); + let apiRepo = await utils + .fetch(`https://api.github.com/repos/${repo}`, { + headers: { + "User-Agent": utils.getWindow().webContents.getUserAgent(), + }, + }) + .then((res) => res.json()) as { id: number} + console.error(apiRepo); + console.debug(`REPO ID: ${apiRepo.id}`); + // extract the files from the first folder in the zip response + let zip = new AdmZip(await response.buffer()); + if (!existsSync(join(utils.getPath("themes"), "gh_" + apiRepo.id))) { + mkdirSync(join(utils.getPath("themes"), "gh_" + apiRepo.id)); + } + console.log(join(utils.getPath("themes"), "gh_" + apiRepo.id)); + zip.getEntries().forEach((entry) => { + if (entry.entryName.endsWith("/")) return; + let subFolder = entry.entryName.split("/").slice(1, -1).join("/"); + zip.extractEntryTo(entry, join(utils.getPath("themes"), "gh_" + apiRepo.id, "/", subFolder), false, true); + }); + let commit = await utils.fetch(`https://api.github.com/repos/${repo}/commits`).then((res) => res.json()) as { sha: string }[]; + console.debug(`COMMIT SHA: ${commit[0].sha}`); + let theme = JSON.parse(readFileSync(join(utils.getPath("themes"), "gh_" + apiRepo.id, "theme.json"), "utf8")); + theme.id = apiRepo.id; + theme.commit = commit[0].sha; + writeFileSync(join(utils.getPath("themes"), "gh_" + apiRepo.id, "theme.json"), JSON.stringify(theme, null, 4), "utf8"); + } catch (e) { + console.error(e); + returnVal.success = false; + } + BrowserWindow.win.webContents.send("theme-installed", returnVal); + this.StartWatcher(utils.getPath("themes")); + BrowserWindow.win.webContents.send("theme-update", ""); + }); + + ipcMain.on("get-themes", (event, _key) => { + if (existsSync(utils.getPath("themes"))) { + let files = readdirSync(utils.getPath("themes")); + let themes = []; + for (let file of files) { + if (file.endsWith(".less")) { + themes.push(file); + } else if (statSync(join(utils.getPath("themes"), file)).isDirectory()) { + let subFiles = readdirSync(join(utils.getPath("themes"), file)); + for (let subFile of subFiles) { + if (subFile.endsWith("index.less")) { + themes.push(join(file, subFile)); + } } - const autoUpdater = new NsisUpdater(options) //Windows Only (for now) -q - await autoUpdater.checkForUpdatesAndNotify() - }) - - /* ********************************************************************************************* - * Window Events - * **********************************************************************************************/ - if (process.platform === "win32") { - let WND_STATE = { - MINIMIZED: 0, - NORMAL: 1, - MAXIMIZED: 2, - FULL_SCREEN: 3, - }; - let wndState = WND_STATE.NORMAL; - - BrowserWindow.win.on("resize", (_: any) => { - const isMaximized = BrowserWindow.win.isMaximized(); - const isMinimized = BrowserWindow.win.isMinimized(); - const isFullScreen = BrowserWindow.win.isFullScreen(); - const state = wndState; - if (isMinimized && state !== WND_STATE.MINIMIZED) { - wndState = WND_STATE.MINIMIZED; - } else if (isFullScreen && state !== WND_STATE.FULL_SCREEN) { - wndState = WND_STATE.FULL_SCREEN; - } else if (isMaximized && state !== WND_STATE.MAXIMIZED) { - wndState = WND_STATE.MAXIMIZED; - BrowserWindow.win.webContents.executeJavaScript(`app.chrome.maximized = true`); - } else if (state !== WND_STATE.NORMAL) { - wndState = WND_STATE.NORMAL; - BrowserWindow.win.webContents.executeJavaScript( - `app.chrome.maximized = false` - ); - } + } + } + let themeObjects = []; + for (let theme of themes) { + let themePath = join(utils.getPath("themes"), theme); + let themeName = theme; + let themeDescription = ""; + if (theme.includes("/")) { + themeName = theme.split("/")[1]; + themeDescription = theme.split("/")[0]; + } + if (themePath.endsWith("index.less")) { + themePath = themePath.slice(0, -10); + } + if (existsSync(join(themePath, "theme.json"))) { + try { + let themeJson = JSON.parse(readFileSync(join(themePath, "theme.json"), "utf8")); + themeObjects.push({ + name: themeJson.name || themeName, + description: themeJson.description || themeDescription, + path: themePath, + file: theme, + github_repo: themeJson.github_repo || "", + commit: themeJson.commit || "", + pack: themeJson.pack || false, + }); + } catch (e) { + console.error(e); + } + } else { + themeObjects.push({ + name: themeName, + description: themeDescription, + path: themePath, + file: theme, + github_repo: "", + commit: "", + pack: false, }); + } + } + event.returnValue = themeObjects; + } else { + event.returnValue = []; + } + }); + + ipcMain.handle("open-path", async (event, path) => { + switch (path) { + default: + case "plugins": + if (existsSync(utils.getPath("plugins"))) { + shell.openPath(utils.getPath("plugins")); + } else { + mkdirSync(utils.getPath("plugins")); + shell.openPath(utils.getPath("plugins")); + } + break; + case "userdata": + shell.openPath(app.getPath("userData")); + break; + case "themes": + if (existsSync(utils.getPath("themes"))) { + shell.openPath(utils.getPath("themes")); + } else { + mkdirSync(utils.getPath("themes")); + shell.openPath(utils.getPath("themes")); + } + break; + } + }); + + ipcMain.on("get-i18n", (event, key) => { + event.returnValue = utils.getLocale(key); + }); + + ipcMain.on("get-i18n-listing", (event) => { + const translations = utils.i18n; + const i18nListing: any = []; + + for (const lang in translations) { + i18nListing.push({ + code: lang, + nameNative: translations[lang][0].content["i18n.languageName"] ?? lang, + nameEnglish: translations[lang][0].content["i18n.languageNameEnglish"] ?? lang, + category: translations[lang][0].content["i18n.category"] ?? "", + authors: translations[lang][0].content["i18n.authors"] ?? "", + }); + } + + event.returnValue = i18nListing; + }); + + ipcMain.on("get-gpu-mode", (event) => { + event.returnValue = process.platform; + }); + + ipcMain.on("get-port", (event) => { + event.returnValue = this.clientPort; + }); + + ipcMain.on("is-dev", (event) => { + event.returnValue = this.devMode; + }); + + ipcMain.handle("put-cache", (_event, arg) => { + writeFileSync(join(join(app.getPath("userData"), "CiderCache"), `${arg.file}.json`), arg.data); + }); + + ipcMain.on("get-cache", (event, arg) => { + let read = ""; + if (existsSync(join(join(app.getPath("userData"), "CiderCache"), `${arg}.json`))) { + read = readFileSync(join(join(app.getPath("userData"), "CiderCache"), `${arg}.json`), "utf8"); + } + event.returnValue = read; + }); + + ipcMain.handle("getYTLyrics", async (_event, track, artist) => { + const u = track + " " + artist + " official video"; + return await search(u); + }); + + ipcMain.on("close", (_event) => { + BrowserWindow.win.close(); + }); + + ipcMain.on("maximize", (_event) => { + // listen for maximize event + if (BrowserWindow.win.isMaximized()) { + BrowserWindow.win.unmaximize(); + } else { + BrowserWindow.win.maximize(); + } + }); + ipcMain.on("unmaximize", () => { + // listen for maximize event + BrowserWindow.win.unmaximize(); + }); + + ipcMain.on("minimize", () => { + // listen for minimize event + BrowserWindow.win.minimize(); + }); + + // Set scale + ipcMain.on("setScreenScale", (_event, scale) => { + BrowserWindow.win.webContents.setZoomFactor(parseFloat(scale)); + }); + + ipcMain.on("windowmin", (_event, width, height) => { + BrowserWindow.win.setMinimumSize(width, height); + }); + + ipcMain.on("windowontop", (_event, ontop) => { + BrowserWindow.win.setAlwaysOnTop(ontop); + }); + + // Set scale + ipcMain.on("windowresize", (_event, width, height, lock = false) => { + BrowserWindow.win.setContentSize(width, height); + BrowserWindow.win.setResizable(!lock); + }); + + // Move window + ipcMain.on("windowmove", (_event, x, y) => { + BrowserWindow.win.setBounds({ x, y }); + }); + + // Override light, dark + ipcMain.on("changeDisplayTheme", (event, theme) => { + nativeTheme.themeSource = theme; + }); + + //Fullscreen + ipcMain.on("setFullScreen", (_event, flag) => { + BrowserWindow.win.setFullScreen(flag); + }); + + //Fullscreen + ipcMain.on("getFullScreen", (event, flag) => { + event.returnValue = BrowserWindow.win.isFullScreen(); + }); + + //Fullscreen + ipcMain.on("detachDT", (_event, _) => { + BrowserWindow.win.webContents.openDevTools({ mode: "detach" }); + }); + + ipcMain.handle("relaunchApp", (_event, _) => { + const opt: Electron.RelaunchOptions = {}; + opt.args = process.argv.slice(1).concat(["--relaunch"]); + opt.execPath = process.execPath; + if (app.isPackaged && process.env.PORTABLE_EXECUTABLE_FILE != undefined) { + opt.execPath = process.env.PORTABLE_EXECUTABLE_FILE; + } else if (app.isPackaged && process.env.APPIMAGE != undefined) { + opt.execPath = process.env.APPIMAGE; + opt.args.unshift("--appimage-extract-and-run"); + } else if (app.isPackaged && process.env.CHROME_DESKTOP != undefined && process.env.PLATFORM == "Linux") { + opt.execPath = "cider"; + } + app.relaunch(opt); + app.quit(); + }); + + ipcMain.handle("quit-app", (_event, _) => { + app.quit(); + }); + + ipcMain.on("play", (_event, type, id) => { + BrowserWindow.win.webContents.executeJavaScript(` + MusicKit.getInstance().setQueue({ ${type}: '${id}', parameters : {l : app.mklang}}).then(function(queue) { + MusicKit.getInstance().play(); + }); + `); + }); + + // ipcMain.handle("scanLibrary", async (event, folders) => { + // // const oldmetadatalist = await LocalFiles.sendOldLibrary(); + // // BrowserWindow.win.webContents.send("getUpdatedLocalList", oldmetadatalist); + // const metadatalist = await LocalFiles.scanLibrary(); + // BrowserWindow.win.webContents.send("getUpdatedLocalList", metadatalist); + // LocalFiles.localSongs = metadatalist; + // // LocalFiles.cleanUpDB(); + // }); + + LocalFiles.eventEmitter.on("newtracks", (data) => { + BrowserWindow.win.webContents.send("getUpdatedLocalList", data); + }); + + ipcMain.on("writeWAV", (event, leftpcm, rightpcm, bufferlength) => { + function interleave16(leftChannel: any, rightChannel: any) { + var length = leftChannel.length + rightChannel.length; + var result = new Int16Array(length); + + var inputIndex = 0; + + for (var index = 0; index < length; ) { + result[index++] = leftChannel[inputIndex]; + result[index++] = rightChannel[inputIndex]; + inputIndex++; + } + return result; + } + + //https://github.com/HSU-ANT/jsdafx + + function quantization(audiobufferleft: any, audiobufferright: any) { + let h = Float32Array.from([1]); + let nsState = new Array(0); + let ditherstate = new Float32Array(0); + let qt = Math.pow(2, 1 - 16); + + //noise shifting order 3 + h = Float32Array.from([1.623, -0.982, 0.109]); + for (let i = 0; i < nsState.length; i++) { + nsState[i] = new Float32Array(h.length); } - let isQuiting = false - - BrowserWindow.win.on("close", (event: Event) => { - if ((utils.getStoreValue('general.close_button_hide') || process.platform === "darwin") && !isQuiting) { - event.preventDefault(); - BrowserWindow.win.hide(); - } else { - BrowserWindow.win.destroy(); + function setChannelCount(nc: any) { + if (ditherstate.length !== nc) { + ditherstate = new Float32Array(nc); + } + if (nsState.length !== nc) { + nsState = new Array(nc); + for (let i = 0; i < nsState.length; i++) { + nsState[i] = new Float32Array(h.length); } - }) - - app.on('before-quit', () => { - isQuiting = true - }); - - app.on('window-all-closed', () => { - app.quit() - }) - - BrowserWindow.win.on("closed", () => { - BrowserWindow.win = null; - }); - - // Set window Handler - BrowserWindow.win.webContents.setWindowOpenHandler((x: any) => { - if (x.url.includes("apple") || x.url.includes("localhost")) { - return {action: "allow"}; - } - shell.openExternal(x.url).catch(console.error); - return {action: "deny"}; - }); - } - - private static getIP(): string { - let ip: string = ''; - let alias = 0; - const ifaces: any = os.networkInterfaces(); - for (let dev in ifaces) { - ifaces[dev].forEach((details: any) => { - if (details.family === 'IPv4') { - if (!/(loopback|vmware|internal|hamachi|vboxnet|virtualbox)/gi.test(dev + (alias ? ':' + alias : ''))) { - if (details.address.substring(0, 8) === '192.168.' || - details.address.substring(0, 7) === '172.16.' || - details.address.substring(0, 3) === '10.' - ) { - ip = details.address; - ++alias; - } - } - } - }); + } } - return ip; + + function hpDither(channel: any) { + const rnd = Math.random() - 0.5; + const d = rnd - ditherstate[channel]; + ditherstate[channel] = rnd; + return d; + } + + setChannelCount(2); + const inputs = [audiobufferleft, audiobufferright]; + const outputs = [audiobufferleft, audiobufferright]; + + for (let channel = 0; channel < inputs.length; channel++) { + const inputData = inputs[channel]; + const outputData = outputs[channel]; + for (let sample = 0; sample < bufferlength; sample++) { + let input = inputData[sample]; + // console.log('a2',inputData.length); + for (let i = 0; i < h.length; i++) { + input -= h[i] * nsState[channel][i]; + } + // console.log('a3',input); + let d_rand = 0.0; + // ditherstate = new Float32Array(h.length); + // d_rand = hpDither(channel); + const tmpOutput = qt * Math.round(input / qt + d_rand); + for (let i = h.length - 1; i >= 0; i--) { + nsState[channel][i] = nsState[channel][i - 1]; + } + nsState[channel][0] = tmpOutput - input; + outputData[sample] = tmpOutput; + } + } + return outputs; + } + + function convert(n: any) { + var v = n < 0 ? n * 32768 : n * 32767; // convert in range [-32768, 32767] + return Math.max(-32768, Math.min(32768, v)); // clamp + } + + function bitratechange(e: any) { + var t = e.length; + let sampleRate = 96.0; + let outputSampleRate = 48.0; + var s = 0, + o = sampleRate / outputSampleRate, + u = Math.ceil((t * outputSampleRate) / sampleRate), + a = new Int16Array(u); + for (let i = 0; i < u; i++) { + a[i] = e[Math.floor(s)]; + s += o; + } + + return a; + } + + let newaudio = quantization(leftpcm, rightpcm); + //let newaudio = [leftpcm, rightpcm]; + // console.log(newaudio.length); + + let pcmData = Buffer.from(new Int8Array(interleave16(bitratechange(Int16Array.from(newaudio[0], (x) => convert(x))), bitratechange(Int16Array.from(newaudio[1], (x) => convert(x)))).buffer)); + + if (!this.headerSent) { + console.log("new header"); + const header = Buffer.alloc(44); + header.write("RIFF", 0); + header.writeUInt32LE(2147483600, 4); + header.write("WAVE", 8); + header.write("fmt ", 12); + header.writeUInt8(16, 16); + header.writeUInt8(1, 20); + header.writeUInt8(2, 22); + header.writeUInt32LE(48000, 24); + header.writeUInt32LE(16, 28); + header.writeUInt8(4, 32); + header.writeUInt8(16, 34); + header.write("data", 36); + header.writeUInt32LE(2147483600 + 44 - 8, 40); + this.audioStream.write(Buffer.concat([header, pcmData])); + this.headerSent = true; + } else { + this.audioStream.write(pcmData); + } + }); + + //QR Code + ipcMain.handle("showQR", async (_event, _) => { + //macOS + let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`; + BrowserWindow.win.webContents.send("send-remote-pair-url", `https://cider.sh/remote/pair?url=${Buffer.from(encodeURI(url)).toString("base64")}`.toString()); + }); + + ipcMain.on("get-remote-pair-url", (_event, _) => { + // Linux and Windows + let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`; + //if (app.isPackaged) { + BrowserWindow.win.webContents.send("send-remote-pair-url", `https://cider.sh/remote/pair?url=${Buffer.from(encodeURI(url)).toString("base64")}`.toString()); + //} else { + // BrowserWindow.win.webContents.send('send-remote-pair-url', (`http://127.0.0.1:5500/pair-remote.html?url=${Buffer.from(encodeURI(url)).toString('base64')}`).toString()); + //} + }); + + if (process.platform === "darwin") { + //macOS + app.setUserActivity( + "com.CiderCollective.remote.pair", + { + ip: `${BrowserWindow.getIP()}`, + }, + `http://${BrowserWindow.getIP()}:${this.remotePort}`, + ); + } + // Get previews for normalization + ipcMain.on("getPreviewURL", (_event, url) => { + + fetch(url) + .then((res) => res.buffer()) + .then(async (buffer) => { + const metadata = await mm.parseBuffer(buffer, "audio/x-m4a"); + let SoundCheckTag = metadata.native.iTunes[1].value; + console.debug("sc", SoundCheckTag); + BrowserWindow.win.webContents.send("SoundCheckTag", SoundCheckTag); + }) + .catch((err) => { + console.log(err); + }); + }); + + ipcMain.on("share-menu", async (_event, url) => { + if (process.platform !== "darwin") return; + //https://www.electronjs.org/docs/latest/api/share-menu + console.log("[Share Sheet - App.ts]", url); + const options = { + title: "Share", + urls: [url], + }; + const shareMenu = new ShareMenu(options); + shareMenu.popup(); + }); + + ipcMain.on("get-version", (_event) => { + if (app.isPackaged) { + _event.returnValue = app.getVersion(); + } else { + _event.returnValue = `Experimental running on Electron ${app.getVersion()}`; + } + }); + + ipcMain.on("open-appdata", (_event) => { + shell.openPath(app.getPath("userData")); + }); + + ipcMain.handle("folderSelector", async (_event) => { + let u = await dialog.showOpenDialog({ + properties: ["openDirectory", "multiSelections"], + }); + return u.filePaths; + }); + + //#region Cider Connect + ipcMain.on("cc-auth", (_event) => { + shell.openExternal(String(utils.getStoreValue("cc_authURL"))); + }); + + ipcMain.on("auth-window", (_event) => { + AuthWindow(BrowserWindow.win); + }); + + function AuthWindow(win: bw) { + // create a BrowserWindow + const authWindow = new bw({ + width: 500, + height: 600, + show: false, + titleBarOverlay: { + color: "#1d1d1f", + symbolColor: "#ffffff", + }, + titleBarStyle: "hidden", + darkTheme: true, + resizable: false, + webPreferences: { + contextIsolation: false, + nodeIntegration: true, + sandbox: true, + allowRunningInsecureContent: true, + webSecurity: false, + preload: join(utils.getPath("srcPath"), "./preload/cider-preload.js"), + nodeIntegrationInWorker: false, + experimentalFeatures: true, + }, + }); + // authWindow.webContents.openDevTools(); + // remove all local storage data + authWindow.webContents.session.clearStorageData(); + + // set user agent + authWindow.webContents.setUserAgent(`Mozilla/5.0 (Macintosh; Intel Mac OS X 13_3_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15`); + + // show the window + authWindow.loadURL("https://beta.music.apple.com/"); + const cookieKeys = ["itspod", "pltvcid", "pldfltcid", "itua", "media-user-token", "acn1", "dslang"]; + + ipcMain.on("auth-window-ready", async (_event) => { + authWindow.show(); + }); + + ipcMain.on("auth-completed", async (_event) => { + const cookies = await getCookies(); + console.log("cookies", cookies); + win.webContents.send("recv-cookies", cookies); + authWindow.close(); + }); + + const overlayStyling = ` + .hehehe { + position: fixed; + top:0; + left:0; + width: 100px; + height: 100px; + background: #1d1d1f; + z-index: 99999; + } + .titlebar { + height: 30px; + position: fixed; + top:0; + left:0; + right:0; + -webkit-app-region: drag; + z-index: 99999; + }`; + + // on content loaded + authWindow.webContents.on("did-finish-load", () => { + authWindow.webContents.executeJavaScript(` + let tOut = setInterval(async ()=>{ + try { + if(typeof MusicKit === 'undefined') return; + MusicKit.getInstance().addEventListener(MusicKit.Events.authorizationStatusDidChange, ()=>{ + if(MusicKit.getInstance().isAuthorized) { + ipcRenderer.send('auth-completed') + } + }) + clearInterval(tOut) + }catch(e) {} + }, 500) + let tOut2 = setInterval(()=>{ + try { + const el = document.querySelector('.signin') + if(el) { + el.click() + ipcRenderer.send('auth-window-ready') + clearInterval(tOut2) + } + }catch(e) {} + }, 500) + let styling = \`${overlayStyling}\`; + (()=>{ + const titleBarEl = document.createElement('div') + const overlayEl = document.createElement('div') + titleBarEl.classList.add('titlebar') + overlayEl.classList.add('hehehe') + const styleTag = document.createElement('style') + styleTag.innerHTML = styling + document.head.appendChild(styleTag) + document.body.appendChild(overlayEl) + document.body.appendChild(titleBarEl) + })() + `); + }); + + async function getCookies(): Promise<{ [key: string]: string }> { + return new Promise((res, rej) => { + authWindow.webContents.session.cookies + .get({}) + .then((cookies) => { + // for each cookie + const toRenderer: { + [key: string]: string; + } = {}; + for (let i = 0; i < cookieKeys.length; i++) { + const key = cookieKeys[i]; + // find the cookie + const cookie = cookies.find((cookie) => cookie.name === key); + // if cookie exists + if (cookie) { + toRenderer[`music.ampwebplay.${cookie.name}`] = cookie.value; + } + } + res(toRenderer); + }) + .catch((error) => { + console.log(error); + rej(); + }); + }); + } } - /** - * Broadcast the remote to the IP - * @private - */ - private async broadcastRemote() { - const myString = `http://${BrowserWindow.getIP()}:${this.remotePort}`; - const mdns = require('mdns-js'); - const encoded = new Buffer(myString).toString('base64'); - const x = mdns.tcp('cider-remote'); - const txt_record = { - "Ver": "131077", - 'DvSv': '3689', - 'DbId': 'D41D8CD98F00B205', - 'DvTy': 'Cider', - 'OSsi': '0x212F0', - 'txtvers': '1', - "CtlN": "Cider", - "iV": "196623" - }; - let server2 = mdns.createAdvertisement(x, `${await getPort({port: 3839})}`, { - name: encoded, - txt: txt_record - }); - server2.start(); - console.log('remote broadcasted') + ipcMain.on("cc-logout", (_event) => { + //Make sure to update the default store + utils.setStoreValue("connectUser", { + auth: null, + sync: { + themes: false, + plugins: false, + settings: false, + }, + }); + utils.getWindow().reload(); + }); + + ipcMain.on("cc-push", (_event) => { + utils.pushStoreToConnect(); + }); + /* ********************************************************************************************* + * Window Events + * **********************************************************************************************/ + let WND_STATE = { + MINIMIZED: 0, + NORMAL: 1, + MAXIMIZED: 2, + FULL_SCREEN: 3, + }; + let wndState = WND_STATE.NORMAL; + const win = BrowserWindow.win; + let isQuitting = false; + + win.on("resize", (_: any) => { + const isMaximized = win.isMaximized(); + const isMinimized = win.isMinimized(); + const isFullScreen = win.isFullScreen(); + const state = wndState; + if (isMinimized && state !== WND_STATE.MINIMIZED) { + wndState = WND_STATE.MINIMIZED; + win.webContents.send("window-state-changed", "minimized"); + } else if (isFullScreen && state !== WND_STATE.FULL_SCREEN) { + wndState = WND_STATE.FULL_SCREEN; + win.webContents.send("window-state-changed", "fullscreen"); + } else if (isMaximized && state !== WND_STATE.MAXIMIZED) { + wndState = WND_STATE.MAXIMIZED; + win.webContents.send("window-state-changed", "maximized"); + win.webContents.executeJavaScript(`app.chrome.maximized = true`); + } else if (state !== WND_STATE.NORMAL) { + wndState = WND_STATE.NORMAL; + win.webContents.send("window-state-changed", "normal"); + win.webContents.executeJavaScript(`app.chrome.maximized = false`); + } + }); + + win.on("close", async (e: any) => { + if ((process.platform === "darwin" || utils.getStoreValue("general.close_button_hide")) && !isQuitting) { + e.preventDefault(); + win.hide(); + } else { + await win.webContents.executeJavaScript(` + window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem)); + window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime)); + window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue._unplayedQueueItems)); + ipcRenderer.send('stopGCast',''); + MusicKit.getInstance().stop(); + `); + } + }); + + app.on("before-quit", () => { + isQuitting = true; + }); + + app.on("activate", function () { + win.show(); + }); + + // Quit when all windows are closed. + app.on("window-all-closed", () => { + if (process.platform !== "darwin") { + app.quit(); + } + }); + + // Set window Handler + BrowserWindow.win.webContents.setWindowOpenHandler((x: any) => { + if (x.url.includes("apple.com") || x.url.includes("localhost")) { + return { action: "allow" }; + } + shell.openExternal(x.url).catch(console.error); + return { action: "deny" }; + }); + } + + /** + * Gets ip + * @private + */ + private static getIP(): string { + let ip: string = ""; + let ip2: any = []; + let alias = 0; + const ifaces: any = networkInterfaces(); + for (let dev in ifaces) { + ifaces[dev].forEach((details: any) => { + if (details.family === "IPv4" && !details.internal) { + if (!/(loopback|vmware|internal|hamachi|vboxnet|virtualbox)/gi.test(dev + (alias ? ":" + alias : ""))) { + if (details.address.substring(0, 8) === "192.168." || details.address.substring(0, 7) === "172.16." || details.address.substring(0, 3) === "10.") { + if (!ip.startsWith("192.168.") || (String(ip2).startsWith("192.168.") && !ip.startsWith("192.168.") && String(ip2).startsWith("172.16.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.")) || (String(ip2).startsWith("10.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.") && !ip.startsWith("10."))) { + ip = details.address; + } + ++alias; + } + } + } + }); } + return ip; + } + + /** + * Broadcast the remote to the IP + * @private + */ + private async broadcastRemote() { + const myString = `http://${BrowserWindow.getIP()}:${this.remotePort}`; + const mdns = (await import("mdns-js")).default; + const encoded = Buffer.from(myString).toString("base64"); + const x = mdns.tcp("cider-remote"); + const txt_record = { + Ver: "131077", + DvSv: "3689", + DbId: "D41D8CD98F00B205", + DvTy: "Cider", + OSsi: "0x212F0", + txtvers: "1", + CtlN: "Cider", + iV: "196623", + }; + let server2 = mdns.createAdvertisement(x, `${await getPort({ port: 3839 })}`, { + name: encoded, + txt: txt_record, + }); + server2.start(); + console.log("remote broadcasted"); + } } - diff --git a/src/main/base/castcontroller.ts b/src/main/base/castcontroller.ts new file mode 100644 index 00000000..fac5bb65 --- /dev/null +++ b/src/main/base/castcontroller.ts @@ -0,0 +1,32 @@ +// @ts-nocheck +import castv2Cli from "castv2-client"; +const RequestResponseController = castv2Cli.RequestResponseController; + + + +export class CiderCastController extends RequestResponseController { + constructor(client: string, sourceId: string, destinationId: string) { + super(client, sourceId, destinationId, "urn:x-cast:com.ciderapp.customdata"); + this.once("close", onclose); + var self = this; + function onclose() { + self.stop(); + } + } + + sendIp(ip: string) { + // TODO: Implement Callback + let data = { + ip: ip, + }; + this.request(data); + } + + kill() { + // TODO: Implement Callback + let data = { + action: "stop", + }; + this.request(data); + } +} diff --git a/src/main/base/castreceiver.ts b/src/main/base/castreceiver.ts new file mode 100644 index 00000000..4bc55ca0 --- /dev/null +++ b/src/main/base/castreceiver.ts @@ -0,0 +1,80 @@ +// @ts-nocheck +import castv2Cli from "castv2-client"; +import { CiderCastController } from "./castcontroller.js"; + +const Application = castv2Cli.Application; +const MediaController = castv2Cli.MediaController; + +export class CiderReceiver extends Application { + // FE96A351 + // 27E1334F + public APP_ID = "FE96A351"; + + constructor(_client: unknown, _session: unknown) { + super(); + super.apply(this, arguments); + + this.media = this.createController(MediaController); + this.mediaReceiver = this.createController(CiderCastController); + + this.media.on("status", onstatus); + + var self = this; + + function onstatus(status: string) { + self.emit("status", status); + } + } + + getStatus(callback: unknown) { + this.media.getStatus.apply(this.media, arguments); + } + + load(media: unknown, options: unknown, callback: unknown) { + this.media.load.apply(this.media, arguments); + } + + play(callback: unknown) { + this.media.play.apply(this.media, arguments); + } + + pause(callback: unknown) { + this.media.pause.apply(this.media, arguments); + } + + stop(callback: unknown) { + this.media.stop.apply(this.media, arguments); + } + + seek(currentTime: unknown, callback: unknown) { + this.media.seek.apply(this.media, arguments); + } + + queueLoad(items: unknown, options: unknown, callback: unknown) { + this.media.queueLoad.apply(this.media, arguments); + } + + queueInsert(items: unknown, options: unknown, callback: unknown) { + this.media.queueInsert.apply(this.media, arguments); + } + + queueRemove(itemIds: unknown, options: unknown, callback: unknown) { + this.media.queueRemove.apply(this.media, arguments); + } + + queueReorder(itemIds: unknown, options: unknown, callback: unknown) { + this.media.queueReorder.apply(this.media, arguments); + } + + queueUpdate(items: unknown, callback: unknown) { + this.media.queueUpdate.apply(this.media, arguments); + } + + sendIp(opts: unknown) { + this.mediaReceiver.sendIp.apply(this.mediaReceiver, arguments); + } + + kill(opts: unknown) { + this.mediaReceiver.kill.apply(this.mediaReceiver, arguments); + } +} diff --git a/src/main/base/plugins.ts b/src/main/base/plugins.ts index 4ffb1042..a8b8aaad 100644 --- a/src/main/base/plugins.ts +++ b/src/main/base/plugins.ts @@ -1,64 +1,122 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as electron from 'electron' -import {utils} from './utils'; +import {app} from "electron"; +import { existsSync, lstatSync, readdirSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { utils } from "./utils.js"; +// +// Hello, this is our loader for the various plugins that the Cider Development Team built for our +// numerous plugins internally and ones made by the community +// +// To learn how to make your own, visit https://github.com/ciderapp/Cider/wiki/Plugins +// +/** + * @class + * Plugin Loading + * @author booploops#7139 + * @see {@link https://github.com/ciderapp/Cider/wiki/Plugins|Documentation} + */ export class Plugins { - private basePluginsPath = path.join(__dirname, '../plugins'); - private userPluginsPath = path.join(electron.app.getPath('userData'), 'plugins'); - private readonly pluginsList: any = {}; + private static PluginMap: any = {}; + private basePluginsPath = join(dirname(fileURLToPath(import.meta.url)), "../plugins"); + private userPluginsPath = join(app.getPath("userData"), "Plugins"); + private readonly pluginsList: any = {}; - constructor() { - this.pluginsList = this.getPlugins(); + constructor() { + this.pluginsList = this.getPlugins(); + } + + public static getPluginFromMap(plugin: string): any { + if (Plugins.PluginMap[plugin]) { + return Plugins.PluginMap[plugin]; + } else { + return plugin; + } + } + + public getPlugins(): any { + let plugins: any = {}; + + if (existsSync(this.basePluginsPath)) { + readdirSync(this.basePluginsPath).forEach(async (file) => { + if (file.endsWith(".ts") || file.endsWith(".js")) { + const plugin = (await import(join(this.basePluginsPath, file))).default; + if (plugins[file] || plugin.name in plugins) { + console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`); + } else { + plugins[file] = new plugin(utils); + } + } + }); } - public getPlugins(): any { - let plugins: any = {}; - - - if (fs.existsSync(this.basePluginsPath)) { - fs.readdirSync(this.basePluginsPath).forEach(file => { - if (file.endsWith('.ts') || file.endsWith('.js')) { - const plugin = require(path.join(this.basePluginsPath, file)).default; - if (plugins[file] || plugin.name in plugins) { - console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`); - } else { - plugins[file] = new plugin(electron.app, utils.getStore()); - } - } - }); - } - - - if (fs.existsSync(this.userPluginsPath)) { - fs.readdirSync(this.userPluginsPath).forEach(file => { - if (file.endsWith('.ts') || file.endsWith('.js')) { - const plugin = require(path.join(this.userPluginsPath, file)).default; - file = file.replace('.ts', '').replace('.js', ''); - if (plugins[file] || plugin in plugins) { - console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`); - } else { - plugins[file] = new plugin(electron.app, utils.getStore()); - } - } - }); - } - console.log('[PluginHandler] Loaded plugins:', Object.keys(plugins)); - return plugins; - } - - public callPlugins(event: string, ...args: any[]) { - for (const plugin in this.pluginsList) { - if (this.pluginsList[plugin][event]) { - this.pluginsList[plugin][event](...args); + if (existsSync(this.userPluginsPath)) { + readdirSync(this.userPluginsPath).forEach(async (file) => { + // Plugins V1 + if (file.endsWith(".ts") || file.endsWith(".js")) { + if (!app.isPackaged) { + const plugin = (await import(join(this.userPluginsPath, file))).default; + file = file.replace(".ts", "").replace(".js", ""); + if (plugins[file] || plugin in plugins) { + console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`); + } else { + plugins[file] = new plugin(utils); } + } else { + const plugin = await import(join(this.userPluginsPath, file)); + file = file.replace(".ts", "").replace(".js", ""); + if (plugins[file] || plugin in plugins) { + console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`); + } else { + plugins[file] = new plugin(utils); + } + } } - } - - public callPlugin(plugin: string, event: string, ...args: any[]) { - if (this.pluginsList[plugin][event]) { - this.pluginsList[plugin][event](...args); + // Plugins V2 + else if (lstatSync(join(this.userPluginsPath, file)).isDirectory()) { + const pluginPath = join(this.userPluginsPath, file); + if (existsSync(join(pluginPath, "package.json"))) { + const pluginPackage = await import(join(pluginPath, "package.json")); + const plugin = await import(join(pluginPath, pluginPackage.main)); + if (plugins[plugin.name] || plugin.name in plugins) { + console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`); + } else { + Plugins.PluginMap[pluginPackage.name] = file; + const pluginEnv = { + app: app, + store: utils.getStore(), + utils: utils, + win: utils.getWindow(), + dir: pluginPath, + dirName: file, + express: utils.getExpress(), + }; + plugins[plugin.name] = new plugin(pluginEnv); + } + } } + }); } + console.log("[PluginHandler] Loaded plugins:", Object.keys(plugins)); + return plugins; + } + public callPlugins(event: string, ...args: any[]) { + for (const plugin in this.pluginsList) { + if (this.pluginsList[plugin][event]) { + try { + this.pluginsList[plugin][event](...args); + } catch (e) { + console.error(`[${plugin}] An error was encountered: ${e}`); + console.error(e); + } + } + } + } + + public callPlugin(plugin: string, event: string, ...args: any[]) { + if (this.pluginsList[plugin][event]) { + this.pluginsList[plugin][event](...args); + } + } } diff --git a/src/main/base/store.ts b/src/main/base/store.ts index 54ca5ba9..917f1dc4 100644 --- a/src/main/base/store.ts +++ b/src/main/base/store.ts @@ -1,162 +1,333 @@ -import * as ElectronStore from 'electron-store'; -import * as electron from "electron"; +import ElectronStore from "electron-store"; +import { app, ipcMain } from "electron"; +import fetch from "node-fetch"; export class Store { - static cfg: ElectronStore; + static cfg: ElectronStore; - private defaults: any = { - "general": { - "close_button_hide": true, - "open_on_startup": false, - "discord_rpc": 1, // 0 = disabled, 1 = enabled as Cider, 2 = enabled as Apple Music - "discord_rpc_clear_on_pause": true, - "language": "en_US", // electron.app.getLocale().replace('-', '_') this can be used in future - "playbackNotifications": true + private defaults = { + main: { + PLATFORM: process.platform, + UPDATABLE: app.isPackaged && (!process.mas || !process.windowsStore || !process.env.FLATPAK_ID), + }, + general: { + close_button_hide: false, + language: "en_US", + playbackNotifications: true, + resumeOnStartupBehavior: "local", + privateEnabled: false, + themeUpdateNotification: true, + sidebarItems: { + recentlyAdded: true, + songs: true, + albums: true, + artists: true, + videos: true, + podcasts: true, + }, + sidebarCollapsed: { + cider: false, + applemusic: false, + library: false, + amplaylists: false, + playlists: false, + localLibrary: false, + }, + onStartup: { + enabled: false, + hidden: false, + }, + resumeTabs: { + tab: "home", + dynamicData: "", + }, + keybindings: { + search: ["CommandOrControl", "F"], + listnow: ["CommandOrControl", "L"], + browse: ["CommandOrControl", "B"], + recentAdd: ["CommandOrControl", "G"], + songs: ["CommandOrControl", "J"], + albums: ["CommandOrControl", process.platform == "darwin" ? "Option" : process.platform == "linux" ? "Shift" : "Alt", "A"], + artists: ["CommandOrControl", "D"], + togglePrivateSession: ["CommandOrControl", "P"], + webRemote: ["CommandOrControl", process.platform == "darwin" ? "Option" : process.platform == "linux" ? "Shift" : "Alt", "W"], + audioSettings: ["CommandOrControl", process.platform == "darwin" ? "Option" : process.platform == "linux" ? "Shift" : "Alt", "A"], + pluginMenu: ["CommandOrControl", process.platform == "darwin" ? "Option" : process.platform == "linux" ? "Shift" : "Alt", "P"], + castToDevices: ["CommandOrControl", process.platform == "darwin" ? "Option" : process.platform == "linux" ? "Shift" : "Alt", "C"], + settings: [ + "CommandOrControl", // Who the hell uses a different key for this? Fucking Option? + ",", + ], + zoomn: ["Control", "numadd"], + zoomt: ["Control", "numsub"], + zoomrst: ["Control", "num0"], + openDeveloperTools: ["CommandOrControl", "Shift", "I"], + }, + showLovedTracksInline: true, + }, + connectivity: { + discord_rpc: { + enabled: true, + client: "Cider", + activity: { + state_format: "by {artist}", + details_format: "{title}", + hide_timestamp: false, + buttons: { + enabled: true, + first: "listenOnCider", + second: "viewOnAppleMusic", + options: ["listenOnCider", "viewOnAppleMusic", "viewOnOtherMusicServices"], + }, }, - "home": { - "followedArtists": [], - "favoriteItems": [] + clear_on_pause: true, + }, + lastfm: { + enabled: false, + scrobble_after: 50, + filter_loop: false, + filter_types: {}, + remove_featured: true, + secrets: { + username: "", + key: "", }, - "libraryPrefs": { - "songs": { - "sort": "name", - "sortOrder": "asc", - "size": "normal" - } + }, + }, + home: { + followedArtists: [], + favoriteItems: [], + }, + libraryPrefs: { + songs: { + scroll: "paged", + sort: "name", + sortOrder: "asc", + size: "normal", + }, + albums: { + scroll: "paged", + sort: "name", + sortOrder: "asc", + viewAs: "covers", + }, + playlists: { + scroll: "infinite", + }, + localPaths: [], + pageSize: 250, + }, + audio: { + volume: 1, + volumeStep: 0.01, + maxVolume: 1, + lastVolume: 1, + muted: false, + playbackRate: 1, + quality: "HIGH", + seamless_audio: true, + normalization: true, + dBSPL: false, + dBSPLcalibration: 90, + maikiwiAudio: { + ciderPPE: true, + ciderPPE_value: "MAIKIWI", + staticOptimizer: { + state: false, + lock: false, }, - "audio": { - "volume": 1, - "lastVolume": 1, - "muted": false, - "quality": "256", - "seamless_audio": true, - "normalization": false, - "spatial": false, - "maxVolume": 1, - "volumePrecision": 0.1, - "volumeRoundMax": 0.9, - "volumeRoundMin": 0.1, - "spatial_properties": { - "presets": [], - "gain": 0.8, - "listener_position": [0, 0, 0], - "audio_position": [0, 0, 0], - "room_dimensions": { - "width": 32, - "height": 12, - "depth": 32 - }, - "room_materials": { - "left": 'metal', - "right": 'metal', - "front": 'brick-bare', - "back": 'brick-bare', - "down": 'acoustic-ceiling-tiles', - "up": 'acoustic-ceiling-tiles', - } - }, - "equalizer": { - 'preset': "default", - 'frequencies': [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000], - 'gain': [0,0,0,0,0,0,0,0,0,0], - 'Q' : [1,1,1,1,1,1,1,1,1,1], - 'preamp' : 0, - 'mix' : 1, - 'vibrantBass' : 0, - 'presets': [], - 'userGenerated': false - }, - "vibrantBass": { // Hard coded into the app. Don't include any of this config into exporting presets in store.ts - 'multiplier': 0, - 'frequencies': [17.182, 42.169, 53.763, 112.69, 119.65, 264.59, 336.57, 400.65, 505.48, 612.7, 838.7, 1155.3, 1175.6, 3406.8, 5158.6, 5968.1, 6999.9, 7468.6, 8862.9, 9666, 10109], - 'Q': [2.5, 0.388, 5, 5, 2.5, 7.071, 14.14, 10, 7.071, 14.14, 8.409, 0.372, 7.071, 10, 16.82, 7.071, 28.28, 20, 8.409, 40, 40], - 'gain': [-0.34, 2.49, 0.23, -0.49, 0.23, -0.12, 0.32, -0.29, 0.33, 0.19, -0.18, -1.27, -0.11, 0.25, -0.18, -0.53, 0.34, 1.32, 1.78, 0.41, -0.28] - } + opportunisticCorrection_state: "OFF", + atmosphereRealizer1: false, + atmosphereRealizer1_value: "NATURAL_STANDARD", + atmosphereRealizer2: false, + atmosphereRealizer2_value: "NATURAL_STANDARD", + spatial: false, + spatialProfile: "BPLK", + vibrantBass: { + // Hard coded into the app. Don't include any of this config into exporting presets in store.ts + frequencies: [17.182, 42.169, 53.763, 112.69, 119.65, 264.59, 336.57, 400.65, 505.48, 612.7, 838.7, 1155.3, 1175.6, 3406.8, 5158.6, 5968.1, 6999.9, 7468.6, 8862.9, 9666, 10109], + Q: [2.5, 0.388, 5, 5, 2.5, 7.071, 14.14, 10, 7.071, 14.14, 8.409, 0.372, 7.071, 10, 16.82, 7.071, 28.28, 20, 8.409, 40, 40], + gain: [-0.34, 2.49, 0.23, -0.49, 0.23, -0.12, 0.32, -0.29, 0.33, 0.19, -0.18, -1.27, -0.11, 0.25, -0.18, -0.53, 0.34, 1.32, 1.78, 0.41, -0.28], }, - "visual": { - "theme": "", - "scrollbars": 0, // 0 = show on hover, 2 = always hide, 3 = always show - "refresh_rate": 0, - "window_background_style": "artwork", // "none", "artwork", "color" - "animated_artwork": "limited", // 0 = always, 1 = limited, 2 = never - "animated_artwork_qualityLevel": 1, - "bg_artwork_rotation": false, - "hw_acceleration": "default", // default, webgpu, disabled - "showuserinfo": true, - "miniplayer_top_toggle": true + cloud: false, + }, + spatial: false, + spatial_properties: { + presets: [], + gain: 0.8, + listener_position: [0, 0, 0], + audio_position: [0, 0, 0], + room_dimensions: { + width: 32, + height: 12, + depth: 32, }, - "lyrics": { - "enable_mxm": false, - "mxm_karaoke": false, - "mxm_language": "en", - "enable_yt": false, + room_materials: { + left: "metal", + right: "metal", + front: "brick-bare", + back: "brick-bare", + down: "acoustic-ceiling-tiles", + up: "acoustic-ceiling-tiles", }, - "lastfm": { - "enabled": false, - "scrobble_after": 30, - "auth_token": "", - "enabledRemoveFeaturingArtists": true, - "filterLoop": true, - "NowPlaying": "true" - }, - "advanced": { - "AudioContext": false, - "experiments": [] - } + }, + equalizer: { + preset: "default", + frequencies: [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000], + gain: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + Q: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + mix: 1, + vibrantBass: 0, + presets: [], + userGenerated: false, + }, + }, + visual: { + theme: "", + styles: [], + scrollbars: 0, // 0 = show on hover, 2 = always hide, 3 = always show + refresh_rate: 0, + window_background_style: "none", // "none", "artwork", "color" + animated_artwork: "limited", // 0 = always, 1 = limited, 2 = never + animated_artwork_qualityLevel: 1, + bg_artwork_rotation: false, + hw_acceleration: "default", // default, webgpu, disabled + showuserinfo: true, + transparent: false, + miniplayer_top_toggle: true, + directives: { + windowLayout: "twopanel", + }, + windowControlPosition: 0, // 0 default right + nativeTitleBar: false, + windowColor: "#000000", + customAccentColor: false, + accentColor: "#fc3c44", + purplePodcastPlaybackBar: false, + maxElementScale: -1, // -1 default, anything else is a custom scale + overrideDisplayTheme: "system", // system , dark, light + artworkDisplayLayout: "default", + }, + lyrics: { + enable_mxm: true, + mxm_karaoke: false, + mxm_language: "disabled", + enable_qq: false, + enable_yt: false, + }, + advanced: { + AudioContext: true, + experiments: [], + playlistTrackMapping: true, + ffmpegLocation: "", + disableLogging: true, + }, + connectUser: { + auth: null, + sync: { + themes: false, + plugins: false, + settings: false, + }, + }, + musickit: { + "stored-attributes": { + autoplayEnabled: "", + }, + }, + }; + private migrations = {}; + + + constructor() { + Store.cfg = new ElectronStore({ + name: "cider-config", + defaults: this.defaults, + migrations: this.migrations, + clearInvalidConfig: false, //disabled for now + }); + + Store.cfg.set(this.mergeStore(this.defaults, Store.cfg.store)); + this.ipcHandler(); + } + + static pushToCloud(): void { + if (Store.cfg.get("connectUser.auth") === null) return; + var syncData = Object(); + if (Store.cfg.get("connectUser.sync.themes")) { + syncData.push({ + themes: Store.cfg.store.themes, + }); } - private migrations: any = {} - - constructor() { - Store.cfg = new ElectronStore({ - name: 'cider-config', - defaults: this.defaults, - migrations: this.migrations, - }); - - Store.cfg.set(this.mergeStore(this.defaults, Store.cfg.store)) - this.ipcHandler(); + if (Store.cfg.get("connectUser.sync.plugins")) { + syncData.push({ + plugins: Store.cfg.store.plugins, + }); } - /** - * Merge Configurations - * @param target The target configuration - * @param source The source configuration - */ - private mergeStore = (target: { [x: string]: any; }, source: { [x: string]: any; }) => { - // Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties - for (const key of Object.keys(source)) { - if (key.includes('migrations')) { - continue; - } - if (source[key] instanceof Array) { - continue - } - if (source[key] instanceof Object) Object.assign(source[key], this.mergeStore(target[key], source[key])) - } - // Join `target` and modified `source` - Object.assign(target || {}, source) - return target + if (Store.cfg.get("connectUser.sync.settings")) { + syncData.push({ + general: Store.cfg.get("general"), + home: Store.cfg.get("home"), + libraryPrefs: Store.cfg.get("libraryPrefs"), + advanced: Store.cfg.get("advanced"), + }); } + let postBody = { + id: Store.cfg.get("connectUser.id"), + app: app.getName(), + version: app.isPackaged ? app.getVersion() : "dev", + syncData: syncData, + }; - /** - * IPC Handler - */ - private ipcHandler(): void { - electron.ipcMain.handle('getStoreValue', (event, key, defaultValue) => { - return (defaultValue ? Store.cfg.get(key, true) : Store.cfg.get(key)); - }); + fetch("https://connect.cidercollective.dev/api/v1/setttings/set", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(postBody), + }); + } - electron.ipcMain.handle('setStoreValue', (event, key, value) => { - Store.cfg.set(key, value); - }); - - electron.ipcMain.on('getStore', (event) => { - event.returnValue = Store.cfg.store - }) - - electron.ipcMain.on('setStore', (event, store) => { - Store.cfg.store = store - }) + /** + * Merge Configurations + * @param target The target configuration + * @param source The source configuration + */ + private mergeStore = (target: { [x: string]: any }, source: { [x: string]: any }) => { + // Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties + for (const key of Object.keys(source)) { + if (key.includes("migrations")) { + continue; + } + if (source[key] instanceof Array) { + continue; + } + if (source[key] instanceof Object) Object.assign(source[key], this.mergeStore(target[key], source[key])); } + // Join `target` and modified `source` + Object.assign(target || {}, source); + return target; + }; + /** + * IPC Handler + */ + private ipcHandler(): void { + ipcMain.handle("getStoreValue", (_event, key, defaultValue) => { + return defaultValue ? Store.cfg.get(key, true) : Store.cfg.get(key); + }); + + ipcMain.handle("setStoreValue", (_event, key, value) => { + Store.cfg.set(key, value); + }); + + ipcMain.on("getStore", (event) => { + event.returnValue = Store.cfg.store; + }); + + ipcMain.on("setStore", (_event, store) => { + Store.cfg.store = store; + }); + } } diff --git a/src/main/base/utils.ts b/src/main/base/utils.ts index 89301c0f..4fa1bfc9 100644 --- a/src/main/base/utils.ts +++ b/src/main/base/utils.ts @@ -1,61 +1,192 @@ -import * as fs from "fs"; -import * as path from "path"; -import {jsonc} from "jsonc"; -import {Store} from "./store"; -import {BrowserWindow as bw} from "./browserwindow"; +import { BrowserWindow, app, ipcMain } from "electron"; +import ElectronStore from "electron-store"; +import fetch from "node-fetch"; +import { readFileSync } from "node:fs"; +import { join, resolve,dirname } from "node:path"; +import { BrowserWindow as bw } from "./browserwindow.js"; +import { Store } from "./store.js"; +import { fileURLToPath } from "node:url"; export class utils { + static hash = "fda9a6528649ea90dee35390wog" + static i18n: any = {}; - /** - * Fetches the i18n locale for the given language. - * @param language {string} The language to fetch the locale for. - * @param key {string} The key to search for. - * @returns {string | Object} The locale value. - */ - static getLocale(language: string, key?: string): string | object { - let i18n: { [index: string]: Object } = jsonc.parse(fs.readFileSync(path.join(__dirname, "../../src/i18n/en_US.jsonc"), "utf8")); + /** + * Playback Functions + */ + static playback = { + pause: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.pause()"); + }, + play: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.play()"); + }, + playPause: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.playPause()"); + }, + next: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.next()"); + }, + previous: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.previous()"); + }, + seek: (seconds: number) => { + bw.win.webContents.executeJavaScript(`MusicKit.getInstance().seekToTime(${seconds})`); + }, + }; + /** + * Paths for the application to use + */ + static paths: any = { + srcPath: join(dirname(fileURLToPath(import.meta.url)), "../../src"), + rendererPath: join(dirname(fileURLToPath(import.meta.url)), "../../src/renderer"), + mainPath: join(dirname(fileURLToPath(import.meta.url)), "../../src/main"), + resourcePath: join(dirname(fileURLToPath(import.meta.url)), "../../resources"), + ciderCache: resolve(app.getPath("userData"), "CiderCache"), + themes: resolve(app.getPath("userData"), "Themes"), + plugins: resolve(app.getPath("userData"), "Plugins"), + externals: resolve(app.getPath("userData"), "externals"), + }; - if (language !== "en_US" && fs.existsSync(path.join(__dirname, `../../src/i18n/${language}.jsonc`))) { - i18n = Object.assign(i18n, jsonc.parse(fs.readFileSync(path.join(__dirname, `../../src/i18n/${language}.jsonc`), "utf8"))); - } + /** + * Get the path + * @returns {string} + * @param name + */ + static getPath(name: string): string { + return this.paths[name]; + } - if (key) { - return i18n[key] - } else { - return i18n - } + /** + * Get the app + * @returns {Electron.App} + */ + static getApp(): Electron.App { + return app; + } + + /** + * Get the IPCMain + */ + static getIPCMain(): Electron.IpcMain { + return ipcMain; + } + + /* + * Get the Express instance + * @returns {any} + */ + static getExpress(): any { + return bw.express; + } + + /** + * MitM the electron fetch for a function that proxies github. + * Written in TS so Maikiwi doesn't fuck up + */ + static async fetch(url: string, opts: object = {}) { + Object.assign(opts, { + headers: { + "User-Agent": utils.getWindow().webContents.getUserAgent(), + }, + }); + if (this.getStoreValue("advanced.experiments").includes("cider_mirror") === true) { + if (url.includes("api.github.com/")) { + return await fetch(url.replace("api.github.com/", "mirror.api.cider.sh/v2/api/"), opts); + } else if (url.includes("raw.githubusercontent.com/")) { + return await fetch(url.replace("raw.githubusercontent.com/", "mirror.api.cider.sh/v2/raw/"), opts); + } else { + return await fetch(url, opts); + } + } else { + return await fetch(url, opts); + } + } + + static async initializeTranslations() { + const otaClient = (await import('@crowdin/ota-client')).default.default; + const crowdin = new otaClient(this.hash) + + this.i18n = await crowdin.getTranslations(); + } + + /** + * Fetches the i18n locale for the given language. + * @param language {string} The language to fetch the locale for. + * @param key {string} The key to search for. + * @returns {string | Object} The locale value. + */ + static getLocale(language: string, key?: string): string | object { + let i18n: any = {}; + if (!this.i18n[language]) { + i18n = this.i18n["en"][0].content; + } else { + i18n = this.i18n[language ?? "en"][0].content; } - /** - * Gets a store value - * @param key - * @returns store value - */ - static getStoreValue(key: string): any { - return Store.cfg.get(key) + if (key) { + return i18n[key]; + } else { + return i18n; } + } - /** - * Sets a store - * @returns store - */ - static getStore(): Object { - return Store.cfg.store - } + /** + * Gets a store value + * @param key + * @returns store value + */ + static getStoreValue(key: string): any { + return Store.cfg.get(key); + } - /** - * Sets a store value - * @param key - * @param value - */ - static setStoreValue(key: string, value: any): void { - Store.cfg.set(key, value) - } + /** + * Sets a store + * @returns store + */ + static getStore(): Object { + return Store.cfg.store; + } - /** - * Gets the browser window - */ - static getWindow(): Electron.BrowserWindow { - return bw.win + /** + * Get the store instance + * @returns {Store} + */ + static getStoreInstance(): ElectronStore { + return Store.cfg; + } + + /** + * Sets a store value + * @param key + * @param value + */ + static setStoreValue(key: string, value: any): void { + Store.cfg.set(key, value); + } + + /** + * Pushes Store to Connect + * @return Function + */ + static pushStoreToConnect(): Function { + return Store.pushToCloud; + } + + /** + * Gets the browser window + */ + static getWindow(): Electron.BrowserWindow { + if (bw.win) { + return bw.win; + } else { + return BrowserWindow.getAllWindows()[0]; } -} \ No newline at end of file + } + + static loadPluginFrontend(path: string): void {} + + static loadJSFrontend(path: string): void { + bw.win.webContents.executeJavaScript(readFileSync(path, "utf8")); + } +} diff --git a/src/main/base/vcomponents.json b/src/main/base/vcomponents.json new file mode 100644 index 00000000..2c694941 --- /dev/null +++ b/src/main/base/vcomponents.json @@ -0,0 +1,68 @@ +[ + "pages/podcasts", + "pages/apple-account-settings", + "pages/library-songs", + "pages/library-albums", + "pages/library-artists", + "pages/browse", + "pages/groupings", + "pages/installed-themes", + "pages/listen_now", + "pages/radio", + "pages/home", + "pages/artist-feed", + "pages/cider-playlist", + "pages/playlist-inline", + "pages/recordLabel", + "pages/cider-multiroom", + "pages/collection-list", + "pages/apple-curator", + "pages/artist", + "pages/search", + "pages/about", + "pages/library-videos", + "pages/remote-pair", + "pages/themes-github", + "pages/plugins-github", + "pages/replay", + "pages/audiolabs", + "pages/zoo", + "pages/plugin-renderer", + "pages/keybinds", + "pages/oobe", + "components/mediaitem-artwork", + "components/artwork-material", + "components/menu-panel", + "components/sidebar-playlist", + "components/audio-settings", + "components/plugin-menu", + "components/audio-controls", + "components/audio-playbackrate", + "components/qrcode-modal", + "components/moreinfo-modal", + "components/equalizer", + "components/add-to-playlist", + "components/smarthints", + "components/queue", + "components/mediaitem-scroller-horizontal", + "components/mediaitem-scroller-horizontal-large", + "components/mediaitem-scroller-horizontal-sp", + "components/mediaitem-scroller-horizontal-mvview", + "components/mediaitem-list-item", + "components/mediaitem-hrect", + "components/mediaitem-square", + "components/mediaitem-mvview", + "components/listennow-child", + "components/mediaitem-mvview-sp", + "components/animatedartwork-view", + "components/listitem-horizontal", + "components/lyrics-view", + "components/fullscreen", + "components/miniplayer", + "components/castmenu", + "components/pathmenu", + "components/airplay-modal", + "components/artist-chip", + "components/hello-world", + "components/inline-collection-list" +] diff --git a/src/main/base/vrouting.json b/src/main/base/vrouting.json new file mode 100644 index 00000000..fabe8d03 --- /dev/null +++ b/src/main/base/vrouting.json @@ -0,0 +1,185 @@ +[ + { + "page": "plugin-renderer", + "component": "", + "condition": "page == 'plugin-renderer'" + }, + { + "page": "zoo", + "component": "", + "condition": "page == 'zoo'" + }, + { + "page": "podcasts", + "component": "", + "condition": "page == 'podcasts'" + }, + { + "page": "library-videos", + "component": "", + "condition": "page == 'library-videos'" + }, + { + "page": "apple-account-settings", + "component": "", + "condition": "page == 'apple-account-settings'" + }, + { + "page": "about", + "component": "", + "condition": "page == 'about'" + }, + { + "page": "cider-artist", + "component": "", + "condition": "page == 'artist-page' && artistPage.data.attributes" + }, + { + "page": "collection-list", + "component": "", + "condition": "page == 'collection-list'" + }, + { + "page": "home", + "component": "", + "condition": "page == 'home'" + }, + { + "page": "artist-feed", + "component": "", + "condition": "page == 'artist-feed'" + }, + { + "page": "playlist-inline", + "component": "", + "condition": "modals.showPlaylist" + }, + { + "page": "playlist_", + "component": "", + "condition": "page.includes('playlist_')" + }, + { + "page": "oobe", + "component": "", + "condition": "page == 'oobe'" + }, + { + "page": "album_", + "component": "", + "condition": "page.includes('album_')" + }, + { + "page": "social-profiles_", + "component": "", + "condition": "$root.page.includes('social-profiles_')" + }, + { + "page": "recordLabel_", + "component": "", + "condition": "page.includes('recordLabel_')" + }, + { + "page": "multiroom", + "component": "", + "condition": "page.includes('multiroom')" + }, + { + "page": "curator_", + "component": "", + "condition": "page.includes('curator_')" + }, + { + "page": "browsepage", + "component": "", + "condition": "page == 'browse'", + "onEnter": "" + }, + { + "page": "groupings", + "component": "", + "condition": "page == 'groupings'", + "onEnter": "" + }, + { + "page": "charts", + "component": "", + "condition": "page == 'charts'", + "onEnter": "" + }, + { + "page": "listen_now", + "component": "", + "condition": "page == 'listen_now'", + "onEnter": "" + }, + { + "page": "radio", + "component": "", + "condition": "page == 'radio'", + "onEnter": "" + }, + { + "page": "settings", + "component": "", + "condition": "page == 'settings'" + }, + { + "page": "installed-themes", + "component": "", + "condition": "page == 'installed-themes'" + }, + { + "page": "search", + "component": "", + "condition": "page == 'search'" + }, + { + "page": "library-songs", + "component": "", + "condition": "page == 'library-songs'", + "onEnter": "" + }, + { + "page": "library-albums", + "component": "", + "condition": "page == 'library-albums'", + "onEnter": "" + }, + { + "page": "library-artists", + "component": "", + "condition": "page == 'library-artists'", + "onEnter": "" + }, + { + "page": "appleCurator", + "component": "", + "condition": "page.includes('appleCurator')" + }, + { + "page": "themes-github", + "component": "", + "condition": "page == 'themes-github'" + }, + { + "page": "plugins-github", + "component": "", + "condition": "page == 'plugins-github'" + }, + { + "page": "remote-pair", + "component": "", + "condition": "page == 'remote-pair'" + }, + { + "page": "audiolabs", + "component": "", + "condition": "page == 'audiolabs'" + }, + { + "page": "replay", + "component": "", + "condition": "page == 'replay'" + } +] diff --git a/src/main/base/wsapi.ts b/src/main/base/wsapi.ts index bb82ec49..60dccc36 100644 --- a/src/main/base/wsapi.ts +++ b/src/main/base/wsapi.ts @@ -1,293 +1,425 @@ -import * as ws from "ws"; -import * as http from "http"; -import * as https from "https"; -import * as url from "url"; -import * as fs from "fs"; -import * as path from "path"; -import * as electron from "electron"; -const WebSocket = ws; -const WebSocketServer = ws.Server; +import WebSocket, { WebSocketServer } from 'ws'; +import electron from "electron"; interface standardResponse { - status?: Number, - message?: String, - data?: any, - type?: string, + status?: Number; + message?: String; + data?: any; + type?: string; } - export class wsapi { - static clients: any; - port: any = 26369 - wss: any = null - clients: any = [] - private _win : any; - constructor(win : any) { - this._win = win; - } - - - createId() { - // create random guid - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0, - v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - } - public async InitWebSockets () { - electron.ipcMain.on('wsapi-updatePlaybackState', (event :any, arg :any) => { - this.updatePlaybackState(arg); - }) + static clients: any; + port: any = 26369; + wss: any = null; + clients: any = []; + private _win: any; - electron.ipcMain.on('wsapi-returnQueue', (event :any, arg :any) => { - this.returnQueue(JSON.parse(arg)); - }); + constructor(win: any) { + this._win = win; + } - electron.ipcMain.on('wsapi-returnSearch', (event :any, arg :any) => { - console.log("SEARCH") - this.returnSearch(JSON.parse(arg)); - }); + createId() { + // create random guid + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { + var r = (Math.random() * 16) | 0, + v = c == "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); + } - electron.ipcMain.on('wsapi-returnSearchLibrary', (event :any, arg :any) => { - this.returnSearchLibrary(JSON.parse(arg)); - }); + public async InitWebSockets() { + electron.ipcMain.on("wsapi-updatePlaybackState", (_event: any, arg: any) => { + this.updatePlaybackState(arg); + }); - electron.ipcMain.on('wsapi-returnDynamic', (event :any, arg :any, type :any) => { - this.returnDynamic(JSON.parse(arg), type); - }); + electron.ipcMain.on("wsapi-returnQueue", (_event: any, arg: any) => { + this.returnQueue(JSON.parse(arg)); + }); - electron.ipcMain.on('wsapi-returnMusicKitApi', (event :any, arg :any, method :any) => { - this.returnMusicKitApi(JSON.parse(arg), method); - }); + electron.ipcMain.on("wsapi-returnSearch", (_event: any, arg: any) => { + console.log("SEARCH"); + this.returnSearch(JSON.parse(arg)); + }); - electron.ipcMain.on('wsapi-returnLyrics', (event :any, arg :any) => { - this.returnLyrics(JSON.parse(arg)); - }); - this.wss = new WebSocketServer({ - port: this.port, - perMessageDeflate: { - zlibDeflateOptions: { - // See zlib defaults. - chunkSize: 1024, - memLevel: 7, - level: 3 - }, - zlibInflateOptions: { - chunkSize: 10 * 1024 - }, - // Other options settable: - clientNoContextTakeover: true, // Defaults to negotiated value. - serverNoContextTakeover: true, // Defaults to negotiated value. - serverMaxWindowBits: 10, // Defaults to negotiated value. - // Below options specified as default values. - concurrencyLimit: 10, // Limits zlib concurrency for perf. - threshold: 1024 // Size (in bytes) below which messages - // should not be compressed if context takeover is disabled. + electron.ipcMain.on("wsapi-returnSearchLibrary", (_event: any, arg: any) => { + this.returnSearchLibrary(JSON.parse(arg)); + }); + + electron.ipcMain.on("wsapi-returnDynamic", (_event: any, arg: any, type: any) => { + this.returnDynamic(JSON.parse(arg), type); + }); + + electron.ipcMain.on("wsapi-returnMusicKitApi", (_event: any, arg: any, method: any) => { + this.returnMusicKitApi(JSON.parse(arg), method); + }); + + electron.ipcMain.on("wsapi-returnLyrics", (_event: any, arg: any) => { + this.returnLyrics(JSON.parse(arg)); + }); + electron.ipcMain.on("wsapi-returnvolumeMax", (_event: any, arg: any) => { + this.returnmaxVolume(JSON.parse(arg)); + }); + electron.ipcMain.on("wsapi-libraryStatus", (_event: any, inLibrary: boolean, rating: number) => { + this.returnLibraryStatus(inLibrary, rating); + }); + electron.ipcMain.on("wsapi-rate", (_event: any, kind: string, id: string, rating: number) => { + this.returnRatingStatus(kind, id, rating); + }); + electron.ipcMain.on("wsapi-change-library", (_event: any, kind: string, id: string, shouldAdd: boolean) => { + this.returnLibraryChange(kind, id, shouldAdd); + }); + this.wss = new WebSocketServer({ + port: this.port, + perMessageDeflate: { + zlibDeflateOptions: { + // See zlib defaults. + chunkSize: 1024, + memLevel: 7, + level: 3, + }, + zlibInflateOptions: { + chunkSize: 10 * 1024, + }, + // Other options settable: + clientNoContextTakeover: true, // Defaults to negotiated value. + serverNoContextTakeover: true, // Defaults to negotiated value. + serverMaxWindowBits: 10, // Defaults to negotiated value. + // Below options specified as default values. + concurrencyLimit: 10, // Limits zlib concurrency for perf. + threshold: 1024, // Size (in bytes) below which messages + // should not be compressed if context takeover is disabled. + }, + }); + console.log(`WebSocketServer started on port: ${this.port}`); + + const defaultResponse: standardResponse = { + status: 0, + data: {}, + message: "OK", + type: "generic", + }; + + this.wss.on("connection", (ws: any) => { + ws.id = this.createId(); + console.log(`Client ${ws.id} connected`); + this.clients.push(ws); + ws.on("message", function incoming(_message: any) {}); + // ws on message + ws.on("message", (message: any) => { + let data = JSON.parse(message); + let response: standardResponse = { + status: 0, + data: {}, + message: "OK", + type: "generic", + }; + if (data.action) { + data.action.toLowerCase(); + } + switch (data.action) { + default: + response.message = "Action not found"; + break; + case "identify": + response.message = "Thanks for identifying!"; + response.data = { + id: ws.id, + }; + ws.identity = { + name: data.name, + author: data.author, + description: data.description, + version: data.version, + }; + break; + case "play-next": + this._win.webContents.executeJavaScript(`wsapi.playNext(\`${data.type}\`,\`${data.id}\`)`); + response.message = "Play Next"; + break; + case "play-later": + this._win.webContents.executeJavaScript(`wsapi.playLater(\`${data.type}\`,\`${data.id}\`)`); + response.message = "Play Later"; + break; + case "quick-play": + this._win.webContents.executeJavaScript(`wsapi.quickPlay(\`${data.term}\`)`); + response.message = "Quick Play"; + break; + case "get-lyrics": + this._win.webContents.executeJavaScript(`wsapi.getLyrics()`); + break; + case "shuffle": + this._win.webContents.executeJavaScript(`wsapi.toggleShuffle()`); + break; + case "set-shuffle": + if (data.shuffle == true) { + this._win.webContents.executeJavaScript(`MusicKit.getInstance().shuffleMode = 1`); + } else { + this._win.webContents.executeJavaScript(`MusicKit.getInstance().shuffleMode = 0`); } - }) - console.log(`WebSocketServer started on port: ${this.port}`); + break; + case "repeat": + this._win.webContents.executeJavaScript(`wsapi.toggleRepeat()`); + break; + case "set-repeat": + if (data.repeat === 0 || data.repeat === 1 || data.repeat === 2) { + this._win.webContents.executeJavaScript(`MusicKit.getInstance().repeatMode = ${data.repeat}`); + response.message = "Repeat " + data.repeat; + } else { + this._win.webContents.executeJavaScript(`wsapi.toggleRepeat()`); + response.message = "Invalid Repeat, toggling"; + } + break; + case "seek": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().seekToTime(${parseFloat(data.time)})`); + response.message = "Seek"; + break; + case "pause": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().pause()`); + response.message = "Paused"; + break; + case "playpause": + this._win.webContents.executeJavaScript(`MusicKitInterop.playPause()`); + response.message = "Play/Pause"; + break; + case "play": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().play()`); + response.message = "Playing"; + break; + case "stop": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().stop()`); + response.message = "Stopped"; + break; + case "volumeMax": + this._win.webContents.executeJavaScript(`wsapi.getmaxVolume()`); + response.message = "maxVolume"; + break; + case "volume": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().volume = ${parseFloat(data.volume)}`); + response.message = "Volume"; + break; + case "mute": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().mute()`); + response.message = "Muted"; + break; + case "unmute": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().unmute()`); + response.message = "Unmuted"; + break; + case "next": + this._win.webContents.executeJavaScript(`MusicKitInterop.next()`); + response.message = "Next"; + break; + case "previous": + this._win.webContents.executeJavaScript(`MusicKitInterop.previous()`); + response.message = "Previous"; + break; + case "musickit-api": + this._win.webContents.executeJavaScript(`wsapi.musickitApi(\`${data.method}\`, \`${data.id}\`, ${JSON.stringify(data.params)} , ${data.library})`); + break; + case "musickit-library-api": + break; + case "set-autoplay": + this._win.webContents.executeJavaScript(`wsapi.setAutoplay(${data.autoplay})`); + break; + case "queue-move": + this._win.webContents.executeJavaScript(`wsapi.moveQueueItem(${data.from},${data.to})`); + break; + case "get-queue": + this._win.webContents.executeJavaScript(`wsapi.getQueue()`); + break; + case "search": + if (!data.limit) { + data.limit = 10; + } + this._win.webContents.executeJavaScript(`wsapi.search(\`${data.term}\`, \`${data.limit}\`)`); + break; + case "library-search": + if (!data.limit) { + data.limit = 10; + } + this._win.webContents.executeJavaScript(`wsapi.searchLibrary(\`${data.term}\`, \`${data.limit}\`)`); + break; + case "show-window": + this._win.show(); + break; + case "hide-window": + this._win.hide(); + break; + case "play-mediaitem": + this._win.webContents.executeJavaScript(`wsapi.playTrackById("${data.id}", \`${data.kind}\`)`); + response.message = "Playing track"; + break; + case "get-status": + response.data = { + isAuthorized: true, + }; + response.message = "Status"; + break; + case "get-currentmediaitem": + this._win.webContents.executeJavaScript(`wsapi.getPlaybackState()`); + break; + case "library-status": + this._win.webContents.executeJavaScript(`wsapi.getLibraryStatus("${data.type}", "${data.id}")`); + break; + case "rating": + this._win.webContents.executeJavaScript(`wsapi.rate("${data.type}", "${data.id}", ${data.rating})`); + break; + case "change-library": + this._win.webContents.executeJavaScript(`wsapi.changeLibrary("${data.type}", "${data.id}", ${data.add})`); + break; + case "quit": + electron.app.quit(); + break; + } + ws.send(JSON.stringify(response)); + }); - const defaultResponse :standardResponse = {status :0, data:{}, message:"OK", type:"generic"}; + ws.on("close", () => { + // remove client from list + this.clients.splice(wsapi.clients.indexOf(ws), 1); + console.log(`Client ${ws.id} disconnected`); + }); + ws.send(JSON.stringify(defaultResponse)); + }); + } + sendToClient(_id: any) { + // replace the clients.forEach with a filter to find the client that requested + } - this.wss.on('connection', (ws : any) => { - ws.id = this.createId(); - console.log(`Client ${ws.id} connected`) - this.clients.push(ws); - ws.on('message', function incoming(message : any) { + updatePlaybackState(attr: any) { + const response: standardResponse = { + status: 0, + data: attr, + message: "OK", + type: "playbackStateUpdate", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } - }); - // ws on message - ws.on('message', (message : any) => { - let data = JSON.parse(message); - let response :standardResponse = {status :0, data:{}, message:"OK", type:"generic"}; - if (data.action) { - data.action.toLowerCase(); - } - switch (data.action) { - default: - response.message = "Action not found"; - break; - case "identify": - response.message = "Thanks for identifying!" - response.data = { - id: ws.id - } - ws.identity = { - name: data.name, - author: data.author, - description: data.description, - version: data.version - } - break; - case "play-next": - this._win.webContents.executeJavaScript(`wsapi.playNext(\`${data.type}\`,\`${data.id}\`)`); - response.message = "Play Next"; - break; - case "play-later": - this._win.webContents.executeJavaScript(`wsapi.playLater(\`${data.type}\`,\`${data.id}\`)`); - response.message = "Play Later"; - break; - case "quick-play": - this._win.webContents.executeJavaScript(`wsapi.quickPlay(\`${data.term}\`)`); - response.message = "Quick Play"; - break; - case "get-lyrics": - this._win.webContents.executeJavaScript(`wsapi.getLyrics()`); - break; - case "shuffle": - this._win.webContents.executeJavaScript(`wsapi.toggleShuffle()`); - break; - case "set-shuffle": - if(data.shuffle == true) { - this._win.webContents.executeJavaScript(`MusicKit.getInstance().shuffleMode = 1`); - }else{ - this._win.webContents.executeJavaScript(`MusicKit.getInstance().shuffleMode = 0`); - } - break; - case "repeat": - this._win.webContents.executeJavaScript(`wsapi.toggleRepeat()`); - break; - case "seek": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().seekToTime(${parseFloat(data.time)})`); - response.message = "Seek"; - break; - case "pause": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().pause()`); - response.message = "Paused"; - break; - case "play": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().play()`); - response.message = "Playing"; - break; - case "stop": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().stop()`); - response.message = "Stopped"; - break; - case "volume": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().volume = ${parseFloat(data.volume)}`); - response.message = "Volume"; - break; - case "mute": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().mute()`); - response.message = "Muted"; - break; - case "unmute": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().unmute()`); - response.message = "Unmuted"; - break; - case "next": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().skipToNextItem()`); - response.message = "Next"; - break; - case "previous": - this._win.webContents.executeJavaScript(`MusicKit.getInstance().skipToPreviousItem()`); - response.message = "Previous"; - break; - case "musickit-api": - this._win.webContents.executeJavaScript(`wsapi.musickitApi(\`${data.method}\`, \`${data.id}\`, ${JSON.stringify(data.params)} , ${data.library})`); - break; - case "musickit-library-api": - break; - case "set-autoplay": - this._win.webContents.executeJavaScript(`wsapi.setAutoplay(${data.autoplay})`); - break; - case "queue-move": - this._win.webContents.executeJavaScript(`wsapi.moveQueueItem(${data.from},${data.to})`); - break; - case "get-queue": - this._win.webContents.executeJavaScript(`wsapi.getQueue()`); - break; - case "search": - if (!data.limit) { - data.limit = 10; - } - this._win.webContents.executeJavaScript(`wsapi.search(\`${data.term}\`, \`${data.limit}\`)`); - break; - case "library-search": - if (!data.limit) { - data.limit = 10; - } - this._win.webContents.executeJavaScript(`wsapi.searchLibrary(\`${data.term}\`, \`${data.limit}\`)`); - break; - case "show-window": - this._win.show() - break; - case "hide-window": - this._win.hide() - break; - case "play-mediaitem": - this._win.webContents.executeJavaScript(`wsapi.playTrackById("${data.id}", \`${data.kind}\`)`); - response.message = "Playing track"; - break; - case "get-status": - response.data = { - isAuthorized: true - }; - response.message = "Status"; - break; - case "get-currentmediaitem": - this._win.webContents.executeJavaScript(`wsapi.getPlaybackState()`); - break; - case "quit": - electron.app.quit(); - break; - } - ws.send(JSON.stringify(response)); - }); + returnMusicKitApi(results: any, method: any) { + const response: standardResponse = { + status: 0, + data: results, + message: "OK", + type: `musickitapi.${method}`, + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } - ws.on('close', () => { - // remove client from list - this.clients.splice(wsapi.clients.indexOf(ws), 1); - console.log(`Client ${ws.id} disconnected`); - }); - ws.send(JSON.stringify(defaultResponse)); - }); - } - sendToClient(id : any) { - // replace the clients.forEach with a filter to find the client that requested - } - updatePlaybackState(attr : any) { - const response : standardResponse = {status: 0, data: attr, message: "OK", type:"playbackStateUpdate"}; - this.clients.forEach(function each(client: any) { - client.send(JSON.stringify(response)); - }); - } - returnMusicKitApi(results :any, method :any) { - const response : standardResponse = {status :0, data: results, message:"OK", type:`musickitapi.${method}`}; - this.clients.forEach(function each(client :any) { - client.send(JSON.stringify(response)); - }); - } - returnDynamic(results :any, type :any) { - const response : standardResponse = {status :0, data: results, message: "OK", type: type}; - this.clients.forEach(function each(client :any) { - client.send(JSON.stringify(response)); - }); - } - returnLyrics(results :any) { - const response : standardResponse = {status :0, data: results, message: "OK", type: "lyrics"}; - this.clients.forEach(function each(client :any) { - client.send(JSON.stringify(response)); - }); - } - returnSearch(results :any) { - const response : standardResponse = {status :0, data: results, message: "OK", type: "searchResults"}; - this.clients.forEach(function each(client :any) { - client.send(JSON.stringify(response)); - }); - } - returnSearchLibrary(results :any) { - const response: standardResponse = {status :0, data :results, message:"OK", type:"searchResultsLibrary"}; - this.clients.forEach(function each(client :any) { - client.send(JSON.stringify(response)); - }); - } - returnQueue(queue :any) { - const response : standardResponse = {status :0,data :queue, message:"OK", type:"queue"}; - this.clients.forEach(function each(client :any) { - client.send(JSON.stringify(response)); - }); - } -} \ No newline at end of file + returnDynamic(results: any, type: any) { + const response: standardResponse = { + status: 0, + data: results, + message: "OK", + type: type, + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnLyrics(results: any) { + const response: standardResponse = { + status: 0, + data: results, + message: "OK", + type: "lyrics", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnSearch(results: any) { + const response: standardResponse = { + status: 0, + data: results, + message: "OK", + type: "searchResults", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnSearchLibrary(results: any) { + const response: standardResponse = { + status: 0, + data: results, + message: "OK", + type: "searchResultsLibrary", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnQueue(queue: any) { + const response: standardResponse = { + status: 0, + data: queue, + message: "OK", + type: "queue", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnmaxVolume(vol: any) { + const response: standardResponse = { + status: 0, + data: vol, + message: "OK", + type: "maxVolume", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnLibraryStatus(inLibrary: boolean, rating: number) { + const response: standardResponse = { + status: 0, + data: { + inLibrary, + rating, + }, + message: "OK", + type: "libraryStatus", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnRatingStatus(kind: string, id: string, rating: number) { + const response: standardResponse = { + status: 0, + data: { kind, id, rating }, + message: "OK", + type: "rate", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } + + returnLibraryChange(kind: string, id: string, shouldAdd: boolean) { + const response: standardResponse = { + status: 0, + data: { kind, id, add: shouldAdd }, + message: "OK", + type: "change-library", + }; + this.clients.forEach(function each(client: any) { + client.send(JSON.stringify(response)); + }); + } +} diff --git a/src/main/index.ts b/src/main/index.ts index 2db1f6a9..e4dc0897 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,19 +1,33 @@ -require('v8-compile-cache'); +// @ts-ignore +await import("v8-compile-cache"); -import {app, components, ipcMain} from 'electron'; -import {join} from 'path'; -app.setPath('userData', join(app.getPath('appData'), 'Cider')); +import { app, components, ipcMain } from "electron"; +import { join } from "path"; +import { Store } from "./base/store.js"; +import { AppEvents } from "./base/app.js"; +import { Plugins } from "./base/plugins.js"; +import { BrowserWindow } from "./base/browserwindow.js"; +import { init as Sentry } from "@sentry/electron"; +import { RewriteFrames } from "@sentry/integrations"; +import { utils } from "./base/utils.js"; +const appName = 'sh.cider.classic'; + +if (!app.isPackaged) { + app.setPath('userData', join(app.getPath('appData'), `${appName}.dev`)); +} else { + app.setPath('userData', join(app.getPath('appData'), appName)); +} // Analytics for debugging fun yeah. -import {init as Sentry} from '@sentry/electron'; -import {Store} from "./base/store"; -import {AppEvents} from "./base/app"; -import {Plugins} from "./base/plugins"; -import {utils} from "./base/utils"; -import {BrowserWindow} from "./base/browserwindow"; - -Sentry({dsn: "https://68c422bfaaf44dea880b86aad5a820d2@o954055.ingest.sentry.io/6112214"}); +Sentry({ + dsn: "https://68c422bfaaf44dea880b86aad5a820d2@o954055.ingest.sentry.io/6112214", + integrations: [ + new RewriteFrames({ + root: process.cwd(), + }), + ], +}); new Store(); const Cider = new AppEvents(); @@ -22,66 +36,61 @@ const CiderPlug = new Plugins(); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * App Event Handlers * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +app.on("ready", async () => { + await utils.initializeTranslations(); + Cider.ready(CiderPlug); -app.on('ready', () => { - Cider.ready(CiderPlug); + console.log("[Cider] Application is Ready. Creating Window."); + if (!app.isPackaged) { + console.info("[Cider] Running in development mode."); + // @ts-ignore + (await import("vue-devtools")).default.install(); + } + console.log("aa"); + components.whenReady().then(async () => { + const bw = new BrowserWindow(); + console.log("[Cider] Creating Window."); + const win = await bw.createWindow(); - console.log('[Cider] Application is Ready. Creating Window.') - if (!app.isPackaged) { - console.info('[Cider] Running in development mode.') - require('vue-devtools').install() - } - - components.whenReady().then(async () => { - const bw = new BrowserWindow() - const win = await bw.createWindow() - - win.on("ready-to-show", () => { - Cider.bwCreated(); - CiderPlug.callPlugins('onReady', win); - win.show(); - }); + app.getGPUInfo("complete").then((gpuInfo) => { + console.log(gpuInfo); }); + console.log("[Cider][Widevine] Status:", components.status()); + Cider.bwCreated(); + win.on("ready-to-show", () => { + console.debug("[Cider] Window is Ready."); + CiderPlug.callPlugins("onReady", win); + if (!app.commandLine.hasSwitch("hidden")) { + win.show(); + } + }); + }); }); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Renderer Event Handlers * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - -ipcMain.on('playbackStateDidChange', (event, attributes) => { - CiderPlug.callPlugins('onPlaybackStateDidChange', attributes); +let rendererInitialized = false; +ipcMain.handle("renderer-ready", (event) => { + if (rendererInitialized) return; + CiderPlug.callPlugins("onRendererReady", event); + rendererInitialized = true; }); -ipcMain.on('nowPlayingItemDidChange', (event, attributes) => { - CiderPlug.callPlugins('onNowPlayingItemDidChange', attributes); +ipcMain.on("playbackStateDidChange", (_event, attributes) => { + CiderPlug.callPlugins("onPlaybackStateDidChange", attributes); }); -app.on('before-quit', () => { - CiderPlug.callPlugins('onBeforeQuit'); - console.warn(`${app.getName()} exited.`); +ipcMain.on("nowPlayingItemDidChange", (_event, attributes) => { + CiderPlug.callPlugins("onNowPlayingItemDidChange", attributes); }); -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Widevine Event Handlers - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +ipcMain.on("playbackTimeDidChange", (_event, attributes) => { + CiderPlug.callPlugins("playbackTimeDidChange", attributes); +}); -// @ts-ignore -app.on('widevine-ready', (version, lastVersion) => { - if (null !== lastVersion) { - console.log('[Cider][Widevine] Widevine ' + version + ', upgraded from ' + lastVersion + ', is ready to be used!') - } else { - console.log('[Cider][Widevine] Widevine ' + version + ' is ready to be used!') - } -}) - -// @ts-ignore -app.on('widevine-update-pending', (currentVersion, pendingVersion) => { - console.log('[Cider][Widevine] Widevine ' + currentVersion + ' is ready to be upgraded to ' + pendingVersion + '!') -}) - -// @ts-ignore -app.on('widevine-error', (error) => { - console.log('[Cider][Widevine] Widevine installation encountered an error: ' + error) - app.exit() -}) +app.on("before-quit", () => { + CiderPlug.callPlugins("onBeforeQuit"); + console.warn(`${app.getName()} exited.`); +}); diff --git a/src/main/plugins/Extras/examplePlugin.ts b/src/main/plugins/Extras/examplePlugin.ts deleted file mode 100644 index 98b6af4c..00000000 --- a/src/main/plugins/Extras/examplePlugin.ts +++ /dev/null @@ -1,60 +0,0 @@ -let i = 1, k = 1; -export default class ExamplePlugin { - /** - * Private variables for interaction in plugins - */ - private _win: any; - private _app: any; - private _store: any; - - /** - * Base Plugin Details (Eventually implemented into a GUI in settings) - */ - public name: string = 'examplePlugin'; - public description: string = 'Example plugin'; - public version: string = '1.0.0'; - public author: string = 'Example author'; - - /** - * Runs on plugin load (Currently run on application start) - */ - constructor(app: any, store: any) { - this._app = app; - this._store = store; - console.debug(`[Plugin][${this.name}] Loading Complete.`); - } - - /** - * Runs on app ready - */ - onReady(win: any): void { - this._win = win; - console.debug(`[Plugin][${this.name}] Ready.`); - } - - /** - * Runs on app stop - */ - onBeforeQuit(): void { - console.debug(`[Plugin][${this.name}] Stopped.`); - } - - /** - * Runs on playback State Change - * @param attributes Music Attributes (attributes.state = current state) - */ - onPlaybackStateDidChange(attributes: object): void { - console.log('onPlaybackStateDidChange has been called ' + i + ' times'); - i++ - } - - /** - * Runs on song change - * @param attributes Music Attributes - */ - onNowPlayingItemDidChange(attributes: object): void { - console.log('onNowPlayingDidChange has been called ' + k + ' times'); - k++ - } - -} diff --git a/src/main/plugins/Extras/sendSongToTitlebar.ts b/src/main/plugins/Extras/sendSongToTitlebar.ts deleted file mode 100644 index 8b39e47d..00000000 --- a/src/main/plugins/Extras/sendSongToTitlebar.ts +++ /dev/null @@ -1,37 +0,0 @@ -export default class sendSongToTitlebar { - /** - * Base Plugin Details (Eventually implemented into a GUI in settings) - */ - public name: string = 'sendSongToTitlebar'; - public description: string = 'Sets the app\'s titlebar to the Song title'; - public version: string = '0.0.1'; - public author: string = 'Cider Collective (credit to 8times9 via #147)'; - /** - * Runs on plugin load (Currently run on application start) - */ - private _win: any; - private _app: any; - constructor() {} - /** - * Runs on app ready - */ - onReady(win: any): void { - this._win = win; - } - /** - * Runs on app stop - */ - onBeforeQuit(): void {} - /** - * Runs on playback State Change - * @param attributes Music Attributes (attributes.state = current state) - */ - onPlaybackStateDidChange(attributes: any): void { - this._win.setTitle(`${(attributes != null && attributes.name != null && attributes.name.length > 0) ? (attributes.name + " - ") : ''}Cider`) - } - /** - * Runs on song change - * @param attributes Music Attributes - */ - onNowPlayingItemDidChange(attributes: object): void {} -} \ No newline at end of file diff --git a/src/main/plugins/chromecast.ts b/src/main/plugins/chromecast.ts new file mode 100644 index 00000000..f62e344a --- /dev/null +++ b/src/main/plugins/chromecast.ts @@ -0,0 +1,354 @@ +import electron from "electron"; +import os from "os"; +import {CiderReceiver} from "../base/castreceiver.js"; +import MediaRendererClient from "upnp-mediarenderer-client"; +import request from "request"; +import castv2 from "castv2-client"; +import mdnsjs from "mdns-js"; + +export default class ChromecastPlugin { + /** + * Private variables for interaction in plugins + */ + private _win: any; + private _app: any; + private _lastfm: any; + private _store: any; + private _timer: any; + private audioClient = castv2.Client; + private mdns = mdnsjs; + + private devices: any = []; + private castDevices: any = []; + + // private GCRunning = false; + // private GCBuffer: any; + // private expectedConnections = 0; + // private currentConnections = 0; + private activeConnections: any = []; + // private requests = []; + // private GCstream = new Stream.PassThrough(), + private connectedHosts: any = {}; + private connectedPlayer: any; + private ciderPort: any = 9000; + private scanCount: any = 0; + // private server = false; + // private bufcount = 0; + // private bufcount2 = 0; + // private headerSent = false; + + private async searchForGCDevices() { + try { + let browser = this.mdns.createBrowser(this.mdns.tcp("googlecast")); + browser.on("ready", browser.discover); + + browser.on("update", (service: any) => { + if (service.addresses && service.fullname && service.fullname.includes("_googlecast._tcp")) { + let a = service.txt.filter((u: any) => String(u).startsWith("fn=")); + let name = (a[0] ?? "").substring(3) != "" ? (a[0] ?? "").substring(3) : service.fullname.substring(0, service.fullname.indexOf("._googlecast")); + this.ondeviceup(service.addresses[0], name + " (" + (service.type[0]?.description ?? "") + ")", "", "googlecast"); + } + }); + const Client = (await import("node-ssdp")).Client; + // also do a SSDP/UPnP search + let ssdpBrowser = new Client(); + ssdpBrowser.on("response", (headers: any, statusCode: any, rinfo: any) => { + var location = getLocation(headers); + if (location != null) { + this.getServiceDescription(location, rinfo.address); + } + }); + + function getLocation(headers: any) { + let location = null; + if (headers["LOCATION"] != null) { + location = headers["LOCATION"]; + } else if (headers["Location"] != null) { + location = headers["Location"]; + } + return location; + } + + ssdpBrowser.search("urn:dial-multiscreen-org:device:dial:1"); + + // actual upnp devices + let ssdpBrowser2 = new Client(); + ssdpBrowser2.on("response", (headers: any, statusCode: any, rinfo: any) => { + var location = getLocation(headers); + if (location != null) { + this.getServiceDescription(location, rinfo.address); + } + }); + ssdpBrowser2.search("urn:schemas-upnp-org:device:MediaRenderer:1"); + } catch (e) { + console.log("Search GC err", e); + } + } + + private getServiceDescription(url: any, address: any) { + request.get(url, (error: any, response: any, body: any) => { + if (!error && response.statusCode === 200) { + this.parseServiceDescription(body, address, url); + } + }); + } + + private ondeviceup(host: any, name: any, location: any, type: any) { + if (this.castDevices.findIndex((item: any) => item.host === host && item.name === name && item.location === location && item.type === type) === -1) { + this.castDevices.push({ + name: name, + host: host, + location: location, + type: type, + }); + if (this.devices.indexOf(host) === -1) { + this.devices.push(host); + } + if (name) { + this._win.webContents.executeJavaScript(`console.log('deviceFound','ip: ${host} name:${name}')`).catch((err: any) => console.error(err)); + console.log("deviceFound", host, name); + } + } else { + this._win.webContents.executeJavaScript(`console.log('deviceFound (added)','ip: ${host} name:${name}')`).catch((err: any) => console.error(err)); + console.log("deviceFound (added)", host, name); + } + } + + private async parseServiceDescription(body: any, address: any, url: any) { + const parseString = (await import("xml2js")).parseString; + parseString(body, (err: any, result: any) => { + if (!err && result && result.root && result.root.device) { + const device = result.root.device[0]; + console.log("device", device); + let devicetype = "googlecast"; + console.log(); + if (device.deviceType && device.deviceType.toString() === "urn:schemas-upnp-org:device:MediaRenderer:1") { + devicetype = "upnp"; + } + this.ondeviceup(address, device.friendlyName.toString(), url, devicetype); + } + }); + } + + private loadMedia(client: any, song: any, artist: any, album: any, albumart: any, cb?: any) { + // const u = 'http://' + this.getIp() + ':' + server.address().port + '/'; + // const DefaultMediaReceiver : any = require('castv2-client').DefaultMediaReceiver; + client.launch(CiderReceiver, (err: any, player: any) => { + if (err) { + console.log(err); + return; + } + let media = { + // Here you can plug an URL to any mp4, webm, mp3 or jpg file with the proper contentType. + contentId: "http://" + this.getIp() + ":" + this.ciderPort + "/audio.wav", + contentType: "audio/wav", + streamType: "LIVE", // or LIVE + + // Title and cover displayed while buffering + metadata: { + type: 0, + metadataType: 3, + title: song ?? "", + albumName: album ?? "", + artist: artist ?? "", + images: [{ url: albumart ?? "" }], + }, + }; + + player.on("status", (status: any) => { + console.log("status broadcast playerState=%s", status); + }); + + console.log('app "%s" launched, loading media %s ...', player, media); + + player.load( + media, + { + autoplay: true, + }, + (err: any, status: any) => { + console.log("media loaded playerState=%s", status); + }, + ); + + client.getStatus((x: any, status: any) => { + if (status && status.volume) { + client.volume = status.volume.level; + client.muted = status.volume.muted; + client.stepInterval = status.volume.stepInterval; + } + }); + + // send websocket ip + + player.sendIp("ws://" + this.getIp() + ":26369"); + electron.ipcMain.on("stopGCast", (_event) => { + player.kill(); + }); + electron.app.on("before-quit", (_event) => { + player.kill(); + }); + }); + } + + private getIp() { + let ip: string = ""; + let ip2: any = []; + let alias = 0; + const ifaces: any = os.networkInterfaces(); + for (let dev in ifaces) { + ifaces[dev].forEach((details: any) => { + if (details.family === "IPv4" && !details.internal) { + if (!/(loopback|vmware|internal|hamachi|vboxnet|virtualbox)/gi.test(dev + (alias ? ":" + alias : ""))) { + if (details.address.substring(0, 8) === "192.168." || details.address.substring(0, 7) === "172.16." || details.address.substring(0, 3) === "10.") { + if (!ip.startsWith("192.168.") || (ip2.startsWith("192.168.") && !ip.startsWith("192.168.") && ip2.startsWith("172.16.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.")) || (ip2.startsWith("10.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.") && !ip.startsWith("10."))) { + ip = details.address; + } + ++alias; + } + } + } + }); + } + return ip; + } + + private stream(device: any, song: any, artist: any, album: any, albumart: any) { + let castMode = "googlecast"; + let UPNPDesc = ""; + castMode = device.type; + UPNPDesc = device.location; + + let client; + if (castMode === "googlecast") { + let client = new this.audioClient(); + client.volume = 100; + client.stepInterval = 0.5; + client.muted = false; + + client.connect(device.host, () => { + // console.log('connected, launching app ...', 'http://' + this.getIp() + ':' + server.address().port + '/'); + if (!this.connectedHosts[device.host]) { + this.connectedHosts[device.host] = client; + this.activeConnections.push(client); + } + this.loadMedia(client, song, artist, album, albumart); + }); + + client.on("close", () => { + console.info("Client Closed"); + for (let i = this.activeConnections.length - 1; i >= 0; i--) { + if (this.activeConnections[i] === client) { + this.activeConnections.splice(i, 1); + return; + } + } + }); + + client.on("error", (err: any) => { + console.log("Error: %s", err.message); + client.close(); + delete this.connectedHosts[device.host]; + }); + } else { + // upnp devices + try { + let client = new MediaRendererClient(UPNPDesc); + const options = { + autoplay: true, + contentType: "audio/x-wav", + dlnaFeatures: "DLNA.ORG_PN=-;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000", + metadata: { + title: "Cider", + creator: "Streaming ...", + type: "audio", // can be 'video', 'audio' or 'image' + // url: 'http://' + getIp() + ':' + server.address().port + '/', + // protocolInfo: 'DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000; + }, + }; + client.load("http://" + this.getIp() + ":" + this.ciderPort + "/audio.wav", options, function (err: any, _result: any) { + if (err) throw err; + console.log("playing ..."); + }); + if (!this.connectedHosts[device.host]) { + this.connectedHosts[device.host] = client; + this.activeConnections.push(client); + } + } catch (e) {} + } + } + + private async setupGCServer() { + return ""; + } + + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "Chromecast"; + public description: string = "LastFM plugin for Cider"; + public version: string = "0.0.1"; + public author: string = "vapormusic / Cider Collective"; + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(utils: { getApp: () => any; getStore: () => any }) { + this._app = utils.getApp(); + this._store = utils.getStore(); + } + + /** + * Runs on app ready + */ + onReady(win: any): void { + this._win = win; + electron.ipcMain.on("getKnownCastDevices", (event) => { + event.returnValue = this.castDevices; + }); + + electron.ipcMain.on("performGCCast", (event, device, song, artist, album, albumart) => { + // this.setupGCServer().then( () => { + this._win.webContents.setAudioMuted(true); + console.log(device); + this.stream(device, song, artist, album, albumart); + // }) + }); + + electron.ipcMain.on("getChromeCastDevices", (_event, _data) => { + if (this.scanCount++ == 2) { + this.scanCount = 0; + this.castDevices = []; + } + this.searchForGCDevices(); + }); + + electron.ipcMain.on("stopGCast", (_event) => { + this._win.webContents.setAudioMuted(false); + this.activeConnections.forEach((client: any) => { + try { + client.stop(); + } catch (e) {} + }); + this.activeConnections = []; + this.connectedHosts = {}; + }); + } + + /** + * Runs on app stop + */ + onBeforeQuit(): void {} + + /** + * Runs on song change + * @param attributes Music Attributes + */ + onNowPlayingItemDidChange(attributes: any): void {} + + onRendererReady(): void { + this._win.webContents.executeJavaScript(`ipcRenderer.sendSync('get-port')`).then((result: any) => { + this.ciderPort = result; + }); + } +} diff --git a/src/main/plugins/discordrpc.ts b/src/main/plugins/discordrpc.ts index 3265320f..7210ad4e 100644 --- a/src/main/plugins/discordrpc.ts +++ b/src/main/plugins/discordrpc.ts @@ -1,195 +1,307 @@ -import * as RPC from 'discord-rpc' +import { AutoClient } from "discord-auto-rpc"; +import { ipcMain } from "electron"; +import fetch from "node-fetch"; -export default class DiscordRichPresence { +export default class DiscordRPC { + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "Discord Rich Presence"; + public description: string = "Discord RPC plugin for Cider"; + public version: string = "1.1.0"; + public author: string = "vapormusic/Core/cryptofyre (Cider Collective)"; - /** - * Private variables for interaction in plugins - */ - private static _store: any; - private static _connection: boolean = false; + /** + * Private variables for interaction in plugins + */ + private _utils: any; + private _attributes: any; + private ready: boolean = false; - /** - * Base Plugin Details (Eventually implemented into a GUI in settings) - */ - public name: string = 'Discord Rich Presence'; - public description: string = 'Discord RPC plugin for Cider'; - public version: string = '1.0.0'; - public author: string = 'vapormusic/Core (Cider Collective)'; + /** + * Plugin Initialization + */ + private _client: any = null; + private _activityCache: any = { + details: "", + state: "", + largeImageKey: "", + largeImageText: "", + smallImageKey: "", + smallImageText: "", + instance: false, + }; - /** - * Plugin Initialization - */ - private _client: any = null; - private _activity: RPC.Presence = { - details: '', - state: '', - largeImageKey: '', - largeImageText: '', - smallImageKey: '', - smallImageText: '', - instance: false - }; - private _activityCache: RPC.Presence = { - details: '', - state: '', - largeImageKey: '', - largeImageText: '', - smallImageKey: '', - smallImageText: '', - instance: false - }; + /******************************************************************************************* + * Public Methods + * ****************************************************************************************/ - /******************************************************************************************* - * Private Methods - * ****************************************************************************************/ + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(utils: any) { + this._utils = utils; + console.debug(`[Plugin][${this.name}] Loading Complete.`); + } - /** - * Connect to Discord - * @param clientId - * @private - */ - private connect(clientId: any) { - if (DiscordRichPresence._store.general.discord_rpc == 0) { - return - } + /** + * Runs on app ready + */ + onReady(_win: any): void { + this.connect(); + console.debug(`[Plugin][${this.name}] Ready.`); + } - // Apparently needed for ask to join, join, spectate etc. - RPC.register(clientId) + /** + * Set up ipc listeners for the plugin + */ + onRendererReady() { + const self = this; + ipcMain.on("discordrpc:updateImage", async (_event, artworkUrl) => { + if (this._utils.getStoreValue("general.privateEnabled")) return; - // Create the client - this._client = new RPC.Client({transport: "ipc"}); - - // Runs on Ready - this._client.on('ready', () => { - console.info(`[DiscordRPC][connect] Successfully Connected to Discord. Authed for user: ${this._client.user.id}.`); - }) - - // Handles Errors - this._client.on('error', (err: any) => { - console.error(`[DiscordRichPresence] ${err}`); - this.disconnect() + fetch("https://api.cider.sh/v1/images", { + method: "POST", + headers: { + "User-Agent": this._utils.getWindow().webContents.getUserAgent(), + url: artworkUrl, + }, + }) + .then(async (res) => { + const json = await res.json() as { imageUrl: string }; + self._activityCache.largeImageKey = "https://images.weserv.nl/?url=" + json.imageUrl + "&w=1024&h=1024&output=jpg"; + self._client.setActivity(self._activityCache); }); + }); + ipcMain.on("discordrpc:reload", (_event, configUpdate = null) => { + console.log(`[DiscordRPC][reload] Reloading DiscordRPC.`); - // Login to Discord - this._client.login({clientId}) - .then(() => { - DiscordRichPresence._connection = true; + if (this._client) { + this._client.destroy(); + } + + if (!this._utils.getStoreValue("connectivity.discord_rpc.enabled")) return; + this._client + .endlessLogin({ + clientId: this._utils.getStoreValue("connectivity.discord_rpc.client") === "Cider" ? "911790844204437504" : "886578863147192350", }) - .catch((e: any) => console.error(`[DiscordRichPresence][connect] ${e}`)); + .then(() => { + console.log(`[DiscordRPC][reload] DiscordRPC Reloaded.`); + this.ready = true; + if (configUpdate == null) this._utils.getWindow().webContents.send("rpcReloaded", this._client.user); + if (this._activityCache && this._activityCache.details && this._activityCache.state) { + console.info(`[DiscordRPC][reload] Restoring activity cache.`); + this._client.setActivity(this._activityCache); + } + }) + .catch((e: any) => console.error(`[DiscordRPC][reload] ${e}`)); + // this.connect(true) + }); + ipcMain.on("onPrivacyModeChange", (_event, enabled) => { + if (enabled && this._client) { + this._client.clearActivity(); + } else if (!enabled && this._activityCache && this._activityCache.details && this._activityCache.state) { + this._client.setActivity(this._activityCache); + } + }); + } + + /** + * Runs on app stop + */ + onBeforeQuit(): void { + console.debug(`[Plugin][${this.name}] Stopped.`); + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + onPlaybackStateDidChange(attributes: object): void { + this._attributes = attributes; + this.setActivity(attributes); + } + + /** + * Runs on song change + * @param attributes Music Attributes + */ + playbackTimeDidChange(attributes: object): void { + this._attributes = attributes; + this.setActivity(attributes); + } + + /******************************************************************************************* + * Private Methods + * ****************************************************************************************/ + + /** + * Connect to Discord RPC + * @private + */ + private connect() { + if (!this._utils.getStoreValue("connectivity.discord_rpc.enabled")) { + return; + } + + // Create the client + this._client = new AutoClient({ transport: "ipc" }); + + // Runs on Ready + this._client.once("ready", () => { + console.info(`[DiscordRPC][connect] Successfully Connected to Discord. Authed for user: ${this._client.user.id}.`); + + if (this._activityCache && this._activityCache.details && this._activityCache.state && !this._utils.getStoreValue("general.privateEnabled")) { + console.info(`[DiscordRPC][connect] Restoring activity cache.`); + this._client.setActivity(this._activityCache); + } + }); + + // Login to Discord + this._client + .endlessLogin({ + clientId: this._utils.getStoreValue("connectivity.discord_rpc.client") === "Cider" ? "911790844204437504" : "886578863147192350", + }) + .then(() => { + this.ready = true; + }) + .catch((e: any) => console.error(`[DiscordRPC][connect] ${e}`)); + } + + /** + * Sets the activity + * @param attributes Music Attributes + */ + private setActivity(attributes: any) { + if (!this._client || !attributes) { + return; + } + + // Check if show buttons is (true) or (false) + let activity: Object = { + details: this._utils.getStoreValue("connectivity.discord_rpc.activity.details_format"), + state: this._utils.getStoreValue("connectivity.discord_rpc.activity.state_format"), + largeImageKey: attributes?.artwork?.url?.replace("{w}", "1024").replace("{h}", "1024"), + largeImageText: attributes.albumName, + instance: false, // Whether the activity is in a game session + }; + + // Filter the activity + activity = this.filterActivity(activity, attributes); + + if (!this.ready) { + this._activityCache = activity; + return; + } + + if (!activity) { + return; + } + + if (!attributes.status && this._utils.getStoreValue("connectivity.discord_rpc.clear_on_pause")) { + this._client.clearActivity(); + } else if (activity && this._activityCache !== activity) { + if (this._utils.getStoreValue("general.privateEnabled")) return; + this._client.setActivity(activity); + } + this._activityCache = activity; + } + + /** + * Filter the Discord activity object + */ + private filterActivity(activity: any, attributes: any): Object { + // Handling Activity Buttons + if (this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.enabled") && this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first") != "disabled") { + const activityUrls: { [key: string]: any } = { + listenOnCider: "cider", + viewOnAppleMusic: "appleMusic", + viewOnOtherMusicServices: "songLink", + }; + + const firstActivity = this._utils.getLocale(this._utils.getStoreValue("general.language"), `settings.option.connectivity.discordRPC.buttons.${this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first")}`); + const secondActivity = this._utils.getLocale(this._utils.getStoreValue("general.language"), `settings.option.connectivity.discordRPC.buttons.${this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.second")}`); + + if (this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.second") != "disabled") { + activity.buttons = [ + { label: firstActivity, url: attributes.url[activityUrls[this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first")]] }, + { label: secondActivity, url: attributes.url[activityUrls[this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.second")]] }, + ]; + } else { + activity.buttons = [{ label: firstActivity, url: attributes.url[activityUrls[this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first")]] }]; + } + } + + // Add the timestamp if its playing and people want them + if (!this._utils.getStoreValue("connectivity.discord_rpc.hide_timestamp") && attributes.status && new Date(attributes.endTime).getTime() > 0 && isFinite(attributes.endTime) && isFinite(attributes.startTime)) { + activity.startTimestamp = Date.now() - (attributes?.durationInMillis - attributes?.remainingTime); + activity.endTimestamp = attributes.endTime; + } + + // If the user wants to keep the activity when paused + if (!this._utils.getStoreValue("connectivity.discord_rpc.clear_on_pause")) { + activity.smallImageKey = attributes.status ? "play" : "pause"; + activity.smallImageText = attributes.status ? "Playing" : "Paused"; } /** - * Disconnects from Discord RPC + * Works with: + * {artist} + * {composer} + * {title} + * {album} + * {trackNumber} */ - private disconnect() { - if (!this._client) return; + const rpcVars: any = { + artist: attributes.artistName, + composer: attributes.composerName, + title: attributes.name, + album: attributes.albumName, + trackNumber: attributes.trackNumber, + }; - this._client.destroy().then(() => { - DiscordRichPresence._connection = false; - console.log('[DiscordRPC][disconnect] Disconnected from discord.') - }).catch((e: any) => console.error(`[DiscordRPC][disconnect] ${e}`)); + // Replace the variables + Object.keys(rpcVars).forEach((key) => { + if (activity.details.includes(`{${key}}`)) { + activity.details = activity.details.replace(`{${key}}`, rpcVars[key]); + } + if (activity.state.includes(`{${key}}`)) { + activity.state = activity.state.replace(`{${key}}`, rpcVars[key]); + } + }); + + // Checks if the details is greater than 128 because some songs can be that long + if (activity.details && activity.details.length >= 128) { + activity.details = activity.details.substring(0, 125) + "..."; } - /** - * Sets the activity of the client - * @param {object} attributes - */ - private updateActivity(attributes: any) { - if (!this._client) return; - - if (!DiscordRichPresence._connection) { - this._client.clearActivity().catch((e: any) => console.error(`[DiscordRichPresence][clearActivity] ${e}`)); - return; - } - - this._activity = { - details: attributes.name, - state: `${attributes.artistName ? `by ${attributes.artistName}` : ''}`, - startTimestamp: ((new Date(attributes.endTime).getTime() < 0) ? null : attributes.startTime), - endTimestamp: ((new Date(attributes.endTime).getTime() < 0) ? null : attributes.endTime), - largeImageKey: (attributes.artwork.url.replace('{w}', '1024').replace('{h}', '1024')) ?? 'cider', - largeImageText: attributes.albumName, - instance: false, // Whether the activity is in a game session - - buttons: [ - {label: "Listen on Cider", url: attributes.url.cider}, - {label: "View on Apple Music", url: attributes.url.appleMusic}, - ] - }; - - - // Checks if the name is greater than 128 because some songs can be that long - if (this._activity.details && this._activity.details.length > 128) { - this._activity.details = this._activity.details.substring(0, 125) + '...' - } - - // Check if its pausing (false) or playing (true) - if (!attributes.status) { - if (DiscordRichPresence._store.general.discord_rpc_clear_on_pause) { - this._client.clearActivity() - .catch((e: any) => console.error(`[DiscordRichPresence][clearActivity] ${e}`)); - } else { - this._activity.smallImageKey = 'pause'; - this._activity.smallImageText = 'Paused'; - delete this._activity.endTimestamp; - delete this._activity.startTimestamp; - this._client.setActivity(this._activity) - .catch((e: any) => console.error(`[DiscordRichPresence][setActivity] ${e}`)); - } - - } else if (this._activity && this._activityCache !== this._activity && this._activity.details) { - if (!DiscordRichPresence._store.general.discord_rpc_clear_on_pause) { - this._activity.smallImageKey = 'play'; - this._activity.smallImageText = 'Playing'; - } - - this._client.setActivity(this._activity) - .catch((e: any) => console.error(`[DiscordRichPresence][updateActivity] ${e}`)); - this._activityCache = this._activity; - } - + // Checks if the state is greater than 128 because some songs can be that long + if (activity.state && activity.state.length >= 128) { + activity.state = activity.state.substring(0, 125) + "..."; } - /******************************************************************************************* - * Public Methods - * ****************************************************************************************/ - - /** - * Runs on plugin load (Currently run on application start) - */ - constructor(_app: any, store: any) { - DiscordRichPresence._store = store - console.debug(`[Plugin][${this.name}] Loading Complete.`); + // Checks if the state is greater than 128 because some songs can be that long + if (activity.largeImageText && activity.largeImageText.length >= 128) { + activity.largeImageText = activity.largeImageText.substring(0, 125) + "..."; } - /** - * Runs on app ready - */ - onReady(_win: any): void { - this.connect((DiscordRichPresence._store.general.discord_rpc == 1) ? '911790844204437504' : '886578863147192350'); - console.debug(`[Plugin][${this.name}] Ready.`); + // Check large image + if (activity.largeImageKey == null || activity.largeImageKey === "" || activity.largeImageKey.length > 256) { + activity.largeImageKey = "cider"; } - /** - * Runs on app stop - */ - onBeforeQuit(): void { - console.debug(`[Plugin][${this.name}] Stopped.`); + // not sure + if (!attributes.artistName) { + delete activity.state; } - /** - * Runs on playback State Change - * @param attributes Music Attributes (attributes.state = current state) - */ - onPlaybackStateDidChange(attributes: object): void { - this.updateActivity(attributes) + if (!activity.largeImageText || activity.largeImageText.length < 2) { + delete activity.largeImageText; } - /** - * Runs on song change - * @param attributes Music Attributes - */ - onNowPlayingItemDidChange(attributes: object): void { - this.updateActivity(attributes) + if (activity.status === "" || activity.details === "") { + return false; } + return activity; + } } diff --git a/src/main/plugins/lastfm.ts b/src/main/plugins/lastfm.ts index 51ddcc34..5210ac2a 100644 --- a/src/main/plugins/lastfm.ts +++ b/src/main/plugins/lastfm.ts @@ -1,253 +1,236 @@ -import * as electron from 'electron'; -import * as fs from 'fs'; -import {resolve} from 'path'; +// @ts-ignore +import LastfmAPI from "lastfmapi"; -export default class LastFMPlugin { - private sessionPath = resolve(electron.app.getPath('userData'), 'session.json'); - private apiCredentials = { - key: "f9986d12aab5a0fe66193c559435ede3", - secret: "acba3c29bd5973efa38cc2f0b63cc625" +export default class lastfm { + /** + * Base Plugin Information + */ + public name: string = "LastFM Plugin"; + public version: string = "2.0.0"; + public author: string = "Core (Cider Collective)"; + + private _apiCredentials = { + key: "f9986d12aab5a0fe66193c559435ede3", + secret: "acba3c29bd5973efa38cc2f0b63cc625", + }; + /** + * Plugin Initialization + */ + private _lfm: any = null; + private _authenticated: boolean = false; + private _utils: any = null; + private _scrobbleCache: any = {}; + private _nowPlayingCache: any = {}; + + /** + * Public Methods + */ + + constructor(utils: any) { + this._utils = utils; + } + + onReady(_win: Electron.BrowserWindow): void { + this.initializeLastFM("", this._apiCredentials); + } + + onRendererReady(): void { + // Register the ipcMain handlers + this._utils.getIPCMain().handle("lastfm:url", (event: any) => { + console.debug(`[${lastfm.name}:url] Called.`); + return this._lfm.getAuthenticationUrl({ cb: "cider://auth/lastfm" }); + }); + + this._utils.getIPCMain().on("lastfm:auth", (event: any, token: string) => { + console.debug(`[${lastfm.name}:auth] Token: `, token); + this.authenticateLastFM(token); + }); + + this._utils.getIPCMain().on("lastfm:disconnect", (_event: any) => { + this._lfm.setSessionCredentials(null, null); + this._authenticated = false; + console.debug(`[${lastfm.name}:disconnect] Disconnected`); + }); + + this._utils.getIPCMain().on("lastfm:nowPlayingChange", (event: any, attributes: any) => { + if (this._utils.getStoreValue("connectivity.lastfm.filter_loop") || this._utils.getStoreValue("general.privateEnabled") || attributes.kind === "radioStation") return; + this.updateNowPlayingTrack(attributes); + }); + + this._utils.getIPCMain().on("lastfm:FilteredNowPlayingItemDidChange", (event: any, attributes: any) => { + if (this._utils.getStoreValue("general.privateEnabled") || attributes.kind === "radioStation") return; + this.updateNowPlayingTrack(attributes); + }); + + this._utils.getIPCMain().on("lastfm:scrobbleTrack", (event: any, attributes: any) => { + if (this._utils.getStoreValue("general.privateEnabled") || attributes.kind === "radioStation") return; + this.scrobbleTrack(attributes); + }); + } + + /** + * Initialize LastFM + * @param token + * @param api + * @private + */ + private initializeLastFM(token: string, api: { key: string; secret: string }): void { + console.debug(`[${lastfm.name}:initialize] Initializing LastFM`); + this._lfm = new LastfmAPI({ + api_key: api.key, + secret: api.secret, + }); + + if (this._utils.getStoreValue("connectivity.lastfm.secrets.username") && this._utils.getStoreValue("connectivity.lastfm.secrets.key")) { + this._lfm.setSessionCredentials(this._utils.getStoreValue("connectivity.lastfm.secrets.username"), this._utils.getStoreValue("connectivity.lastfm.secrets.key")); + this._authenticated = true; + } else { + this.authenticateLastFM(token); } - /** - * Private variables for interaction in plugins - */ - private _win: any; - private _app: any; - private _lastfm: any; - private _store: any; + } - private authenticateFromFile() { - let sessionData = require(this.sessionPath) - console.log("[LastFM][authenticateFromFile] Logging in with Session Info.") - this._lastfm.setSessionCredentials(sessionData.username, sessionData.key) - console.log("[LastFM][authenticateFromFile] Logged in.", sessionData.username, sessionData.key) - } + /** + * Authenticate the user with the given token + * @param token + * @private + */ + private authenticateLastFM(token: string): void { + if (!token) return; + this._lfm.authenticate(token, (err: any, session: any) => { + if (err) { + console.error(`[${lastfm.name}:authenticate] Error: ${typeof err === "string" ? err : err.message}`); + this._utils.getWindow().webContents.executeJavaScript(`app.notyf.error("${err.message}");`); + return; + } + this._utils.getWindow().webContents.send("lastfm:authenticated", session); + this._authenticated = true; + console.debug(`[${lastfm.name}:authenticate] Authenticated as ${session.username}`); + }); + } - authenticate() { - try { - if (this._store.lastfm.auth_token) { - this._store.lastfm.enabled = true; - } + /** + * Verifies the track information with lastfm + * @param attributes + * @param callback + * @private + */ + private verifyTrack(attributes: any, callback: Function): void { + if (!attributes) return attributes; - if (!this._store.lastfm.enabled || !this._store.lastfm.auth_token) { - this._store.lastfm.enabled = false; - return - } - /// dont move this require to top , app wont load - const LastfmAPI = require('lastfmapi'); - const lfmAPI = new LastfmAPI({ - 'api_key': this.apiCredentials.key, - 'secret': this.apiCredentials.secret - }); - - this._lastfm = Object.assign(lfmAPI, {cachedAttributes: false, cachedNowPlayingAttributes: false}); - - fs.stat(this.sessionPath, (err: any) => { - if (err) { - console.error("[LastFM][Session] Session file couldn't be opened or doesn't exist,", err) - console.log("[LastFM][Auth] Beginning authentication from configuration") - console.log("[LastFM][tk]", this._store.lastfm.auth_token) - this._lastfm.authenticate(this._store.lastfm.auth_token, (err: any, session: any) => { - if (err) { - throw err; - } - console.log("[LastFM] Successfully obtained LastFM session info,", session); // {"name": "LASTFM_USERNAME", "key": "THE_USER_SESSION_KEY"} - console.log("[LastFM] Saving session info to disk.") - let tempData = JSON.stringify(session) - fs.writeFile(this.sessionPath, tempData, (err: any) => { - if (err) - console.log("[LastFM][fs]", err) - else { - console.log("[LastFM][fs] File was written successfully.") - this.authenticateFromFile() - new electron.Notification({ - title: electron.app.getName(), - body: "Successfully logged into LastFM using Authentication Key." - }).show() - } - }) - }); - } else { - this.authenticateFromFile() - } - }) - } catch (err) { - console.log(err) + if (!attributes.lfmAlbum) { + this._lfm.album.getInfo( + { + artist: attributes.primaryArtist, + album: attributes.albumName.replace(/ - Single| - EP/g, ""), + }, + (err: any, data: any) => { + if (err) { + console.error(`[${lastfm.name}] [album.getInfo] Error: ${typeof err === "string" ? err : err.message}`); + attributes.lfmAlbum = { + name: attributes.albumName.replace(/ - Single| - EP/g, ""), + artist: attributes.primaryArtist, + }; + callback(attributes); + } + if (data) { + attributes.lfmAlbum = data; + callback(attributes); + } + }, + ); + } else { + this._lfm.track.getCorrection(attributes.primaryArtist, attributes.name, (err: any, data: any) => { + if (err) { + console.error(`[${lastfm.name}] [track.getCorrection] Error: ${typeof err === "string" ? err : err.message}`); + attributes.lfmTrack = { + name: attributes.name, + artist: { + name: attributes.primaryArtist, + }, + }; + callback(attributes); } + if (data) { + attributes.lfmTrack = data.correction.track; + callback(attributes); + } + }); + } + } + + /** + * Scrobbles the track to lastfm + * @param attributes + * @private + */ + private scrobbleTrack(attributes: any): void { + if (!attributes?.lfmTrack || !attributes?.lfmAlbum) { + this.verifyTrack(attributes, (a: any) => { + this.scrobbleTrack(a); + }); + return; } - private async scrobbleSong(attributes: any) { - await new Promise(resolve => setTimeout(resolve, Math.round(attributes.durationInMillis * (this._store.lastfm.scrobble_after / 100)))); - const currentAttributes = attributes; + if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.kind] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._scrobbleCache.track === attributes.lfmTrack.name)) return; - if (!this._lastfm || this._lastfm.cachedAttributes === attributes) { - return - } + // Scrobble + const scrobble = { + artist: attributes.lfmTrack.artist.name, + track: attributes.lfmTrack.name, + album: attributes.lfmAlbum.name, + albumArtist: attributes.lfmAlbum.artist, + timestamp: new Date().getTime() / 1000, + trackNumber: attributes.trackNumber, + duration: attributes.durationInMillis / 1000, + }; - if (this._lastfm.cachedAttributes) { - if (this._lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return; - } + // Easy Debugging + console.debug(`[${lastfm.name}:scrobble] Scrobbling ${scrobble.artist} - ${scrobble.track}`); - if (currentAttributes.status && currentAttributes === attributes) { - if (fs.existsSync(this.sessionPath)) { - // Scrobble playing song. - if (attributes.status === true) { - this._lastfm.track.scrobble({ - 'artist': this.filterArtistName(attributes.artistName), - 'track': attributes.name, - 'album': attributes.albumName, - 'albumArtist': this.filterArtistName(attributes.artistName), - 'timestamp': new Date().getTime() / 1000 - }, function (err: any, scrobbled: any) { - if (err) { - return console.error('[LastFM] An error occurred while scrobbling', err); - } + // Scrobble the track + this._lfm.track.scrobble(scrobble, (err: any, _res: any) => { + if (err) { + console.error(`[${lastfm.name}:scrobble] Scrobble failed: ${err.message}`); + } else { + console.debug(`[${lastfm.name}:scrobble] Track scrobbled: ${scrobble.artist} - ${scrobble.track}`); + this._scrobbleCache = scrobble; + } + }); + } - console.log('[LastFM] Successfully scrobbled: ', scrobbled); - }); - this._lastfm.cachedAttributes = attributes - } - } else { - this.authenticate(); - } - } else { - return console.log('[LastFM] Did not add ', attributes.name, '—', this.filterArtistName(attributes.artistName), 'because now playing a other song.'); - } + /** + * Updates the now playing track + * @param attributes + * @private + */ + private updateNowPlayingTrack(attributes: any): void { + if (!attributes?.lfmTrack || !attributes?.lfmAlbum) { + this.verifyTrack(attributes, (a: any) => { + this.updateNowPlayingTrack(a); + }); + return; } - private filterArtistName(artist: any) { - if (!this._store.lastfm.enabledRemoveFeaturingArtists) return artist; + if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.kind] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._nowPlayingCache.track === attributes.lfmTrack.name)) return; + console.log(this._utils.getStoreValue("connectivity.lastfm.filter_types")); - artist = artist.split(' '); - if (artist.includes('&')) { - artist.length = artist.indexOf('&'); - } - if (artist.includes('and')) { - artist.length = artist.indexOf('and'); - } - artist = artist.join(' '); - if (artist.includes(',')) { - artist = artist.split(',') - artist = artist[0] - } - return artist.charAt(0).toUpperCase() + artist.slice(1); - } + const nowPlaying = { + artist: attributes.lfmTrack.artist.name, + track: attributes.lfmTrack.name, + album: attributes.lfmAlbum.name, + trackNumber: attributes.trackNumber, + duration: attributes.durationInMillis / 1000, + albumArtist: attributes.lfmAlbum.artist, + }; - private updateNowPlayingSong(attributes: any) { - if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._store.lastfm.NowPlaying) { - return - } - - if (this._lastfm.cachedNowPlayingAttributes) { - if (this._lastfm.cachedNowPlayingAttributes.playParams.id === attributes.playParams.id) return; - } - - if (fs.existsSync(this.sessionPath)) { - // update Now Playing - if (attributes.status === true) { - this._lastfm.track.updateNowPlaying({ - 'artist': this.filterArtistName(attributes.artistName), - 'track': attributes.name, - 'album': attributes.albumName, - 'albumArtist': this.filterArtistName(attributes.artistName) - }, function (err: any, nowPlaying: any) { - if (err) { - return console.error('[LastFM] An error occurred while updating nowPlayingSong', err); - } - - console.log('[LastFM] Successfully updated nowPlayingSong', nowPlaying); - }); - this._lastfm.cachedNowPlayingAttributes = attributes - } - - } else { - this.authenticate() - } - } - - /** - * Base Plugin Details (Eventually implemented into a GUI in settings) - */ - public name: string = 'LastFMPlugin'; - public description: string = 'LastFM plugin for Cider'; - public version: string = '0.0.1'; - public author: string = 'vapormusic / Cider Collective'; - - /** - * Runs on plugin load (Currently run on application start) - */ - constructor(app: any, store: any) { - this._app = app; - this._store = store - electron.app.on('second-instance', (_e: any, argv: any) => { - // Checks if first instance is authorized and if second instance has protocol args - argv.forEach((value: any) => { - if (value.includes('auth')) { - console.log('[LastFMPlugin ok]') - let authURI = String(argv).split('/auth/')[1]; - if (authURI.startsWith('lastfm')) { // If we wanted more auth options - const authKey = authURI.split('lastfm?token=')[1]; - this._store.lastfm.enabled = true; - this._store.lastfm.auth_token = authKey; - console.log(authKey); - this._win.webContents.send('LastfmAuthenticated', authKey); - this.authenticate(); - } - } - }) - }) - electron.app.on('open-url', (event: any, arg: any) => { - console.log('[LastFMPlugin] yes') - event.preventDefault(); - if (arg.includes('auth')) { - let authURI = String(arg).split('/auth/')[1]; - if (authURI.startsWith('lastfm')) { // If we wanted more auth options - const authKey = authURI.split('lastfm?token=')[1]; - this._store.lastfm.enabled = true; - this._store.lastfm.auth_token = authKey; - this._win.webContents.send('LastfmAuthenticated', authKey); - console.log(authKey); - this.authenticate(); - } - } - }) - } - - /** - * Runs on app ready - */ - onReady(win: any): void { - this._win = win; - this.authenticate(); - } - - /** - * Runs on app stop - */ - onBeforeQuit(): void { - console.log('Example plugin stopped'); - } - - /** - * Runs on playback State Change - * @param attributes Music Attributes (attributes.state = current state) - */ - onPlaybackStateDidChange(attributes: object): void { - this.scrobbleSong(attributes) - this.updateNowPlayingSong(attributes) - } - - /** - * Runs on song change - * @param attributes Music Attributes - */ - onNowPlayingItemDidChange(attributes: object): void { - if (!this._store.lastfm.filterLoop){ - this._lastfm.cachedNowPlayingAttributes = false; - this._lastfm.cachedAttributes = false} - this.scrobbleSong(attributes) - this.updateNowPlayingSong(attributes) - } - -} \ No newline at end of file + this._lfm.track.updateNowPlaying(nowPlaying, (err: any, res: any) => { + if (err) { + console.error(`[${lastfm.name}:updateNowPlaying] Now Playing Update failed: ${err.message}`); + } else { + console.debug(`[${lastfm.name}:updateNowPlaying] Now Playing Updated: ${nowPlaying.artist} - ${nowPlaying.track}`); + this._nowPlayingCache = nowPlaying; + } + }); + } +} diff --git a/src/main/plugins/menubar.ts b/src/main/plugins/menubar.ts new file mode 100644 index 00000000..13d16a1c --- /dev/null +++ b/src/main/plugins/menubar.ts @@ -0,0 +1,327 @@ +import { app, Menu, shell } from "electron"; +import { utils } from "../base/utils.js"; + +export default class Thumbar { + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "Menubar Plugin"; + public description: string = "Creates the menubar"; + public version: string = "1.0.0"; + public author: string = "Core"; + public contributors: string[] = ["Core", "Qwack", "Monochromish"]; + + /** + * Menubar Assets + * @private + */ + + private isNotMac: boolean = process.platform !== "darwin"; + private isMac: boolean = process.platform === "darwin"; + private _menuTemplate: any = []; + + /******************************************************************************************* + * Public Methods + * ****************************************************************************************/ + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(_utils: utils) { + console.debug(`[Plugin][${this.name}] Loading Complete.`); + } + + /** + * Runs on app ready + */ + onReady(_win: Electron.BrowserWindow): void { + this._menuTemplate = [ + { + label: app.getName(), + submenu: [ + { + label: `${utils.getLocale(utils.getStoreValue("general.language"), "term.about")} ${app.getName()}`, + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('about')`), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.toggleprivate"), + accelerator: utils.getStoreValue("general.keybindings.togglePrivateSession").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.settings"), + accelerator: utils.getStoreValue("general.keybindings.settings").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.openSettingsPage()`), + }, + ...(this.isMac ? [{ type: "separator" }, { role: "services" }, { type: "separator" }, { role: "hide" }, { role: "hideOthers" }, { role: "unhide" }, { type: "separator" }, { role: "quit" }] : []), + ...(this.isNotMac + ? [ + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.quit"), + accelerator: "Control+Q", + click: () => app.quit(), + }, + ] + : []), + ], + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.view"), + submenu: [ + ...(this.isMac ? [{ role: "reload" }, { role: "forceReload" }, { role: "toggleDevTools" }, { type: "separator" }, { role: "resetZoom" }, { role: "zoomIn" }, { role: "zoomOut" }, { type: "separator" }, { role: "togglefullscreen" }, { type: "separator" }] : []), + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.search"), + accelerator: utils.getStoreValue("general.keybindings.search").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript("app.focusSearch()"), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.listenNow"), + accelerator: utils.getStoreValue("general.keybindings.listnow").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('listen_now')`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.browse"), + accelerator: utils.getStoreValue("general.keybindings.browse").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('browse')`), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.recentlyAdded"), + accelerator: utils.getStoreValue("general.keybindings.recentAdd").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-recentlyadded')`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.songs"), + accelerator: utils.getStoreValue("general.keybindings.songs").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-songs')`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.albums"), + accelerator: utils.getStoreValue("general.keybindings.albums").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-albums')`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.artists"), + accelerator: utils.getStoreValue("general.keybindings.artists").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-artists')`), + }, + ], + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.window"), + submenu: [ + { + role: "minimize", + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.minimize"), + }, + { type: "separator" }, + ...(this.isMac + ? [ + { + label: "Show", + click: () => utils.getWindow().show(), + }, + { role: "zoom" }, + { type: "separator" }, + { role: "front" }, + { role: "close" }, + { + label: "Edit", + submenu: [{ role: "undo" }, { role: "redo" }, { type: "separator" }, { role: "cut" }, { role: "copy" }, { role: "paste" }], + }, + { type: "separator" }, + ] + : []), + ...(this.isNotMac + ? [ + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.zoom"), + submenu: [ + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomin"), + role: "zoomIn", + accelerator: utils.getStoreValue("general.keybindings.zoomn").join("+"), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomout"), + role: "zoomOut", + accelerator: utils.getStoreValue("general.keybindings.zoomt").join("+"), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomreset"), + role: "resetZoom", + accelerator: utils.getStoreValue("general.keybindings.zoomrst").join("+"), + }, + ], + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.fullscreen"), + accelerator: "Control+Enter", + role: "togglefullscreen", + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "action.close"), + accelerator: "Control+W", + role: "close", + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.reload"), + accelerator: "Control+R", + role: "reload", + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.forcereload"), + accelerator: "Control+Shift+R", + role: "forceReload", + }, + ] + : []), + ], + }, + + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.controls"), + submenu: [ + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.playpause"), + accelerator: "Space", + click: () => utils.getWindow().webContents.executeJavaScript(`app.SpacePause()`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.next"), + accelerator: "CommandOrControl+Right", + click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.previous"), + accelerator: "CommandOrControl+Left", + click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.volumeup"), + accelerator: "CommandOrControl+Up", + click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeUp()`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.volumedown"), + accelerator: "CommandOrControl+Down", + click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeDown()`), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.cast2"), + accelerator: utils.getStoreValue("general.keybindings.castToDevices").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.castMenu = true`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.webremote"), + accelerator: utils.getStoreValue("general.keybindings.webRemote").join("+"), + sublabel: "Opens in external window", + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('remote-pair')`), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.audioSettings"), + accelerator: utils.getStoreValue("general.keybindings.audioSettings").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.audioSettings = true`), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.plugins"), + accelerator: utils.getStoreValue("general.keybindings.pluginMenu").join("+"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.pluginMenu = true`), + }, + ], + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.account"), + submenu: [ + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.accountSettings"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('apple-account-settings')`), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.signout"), + click: () => utils.getWindow().webContents.executeJavaScript(`app.unauthorize()`), + }, + ], + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.support"), + role: "help", + submenu: [ + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.discord"), + click: () => shell.openExternal("https://discord.gg/AppleMusic").catch(console.error), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "term.github"), + click: () => shell.openExternal("https://github.com/ciderapp/Cider/wiki/Troubleshooting").catch(console.error), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.report"), + submenu: [ + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.bug"), + click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=bug%2Ctriage&template=bug_report.yaml&title=%5BBug%5D%3A+").catch(console.error), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.feature"), + click: () => shell.openExternal("https://github.com/ciderapp/Cider/discussions/new?category=feature-request").catch(console.error), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.trans"), + click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=%F0%9F%8C%90+Translations&template=translation.yaml&title=%5BTranslation%5D%3A+").catch(console.error), + }, + ], + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.license"), + click: () => shell.openExternal("https://github.com/ciderapp/Cider/blob/main/LICENSE").catch(console.error), + }, + { type: "separator" }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.toggledevtools"), + accelerator: utils.getStoreValue("general.keybindings.openDeveloperTools").join("+"), + click: () => utils.getWindow().webContents.openDevTools(), + }, + { + label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.conf"), + click: () => utils.getStoreInstance().openInEditor(), + }, + ], + }, + ]; + + const menu = Menu.buildFromTemplate(this._menuTemplate); + Menu.setApplicationMenu(menu); + } + + /** + * Runs on app stop + */ + onBeforeQuit(): void { + console.debug(`[Plugin][${this.name}] Stopped.`); + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + onPlaybackStateDidChange(attributes: object): void {} + + /** + * Runs on song change + * @param attributes Music Attributes + */ + onNowPlayingItemDidChange(attributes: object): void {} +} diff --git a/src/main/plugins/mpris.ts b/src/main/plugins/mpris.ts index 869cbceb..f8b8f67f 100644 --- a/src/main/plugins/mpris.ts +++ b/src/main/plugins/mpris.ts @@ -1,196 +1,185 @@ -// @ts-ignore -import * as Player from 'mpris-service'; +import Player from 'mpris-service'; -export default class MPRIS { - /** - * Private variables for interaction in plugins - */ - private _win: any; - private _app: any; +export default class mpris { + /** + * Private variables for interaction in plugins + */ + private static utils: any; + /** + * MPRIS Service + */ + private static player: Player; + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "MPRIS Service"; + public description: string = "Handles MPRIS service calls for Linux systems."; + public version: string = "1.0.0"; + public author: string = "Core"; - /** - * Base Plugin Details (Eventually implemented into a GUI in settings) - */ - public name: string = 'MPRIS Service'; - public description: string = 'Handles MPRIS service calls for Linux systems.'; - public version: string = '1.0.0'; - public author: string = 'Core'; + /******************************************************************************************* + * Private Methods + * ****************************************************************************************/ - /** - * MPRIS Service - */ - private mpris: any; - private mprisEvents: Object = { - "playpause": "pausePlay", - "play": "pausePlay", - "pause": "pausePlay", - "next": "nextTrack", - "previous": "previousTrack", + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(utils: any) { + mpris.utils = utils; + console.debug(`[Plugin][${mpris.name}] Loading Complete.`); + } + + /** + * Blocks non-linux systems from running this plugin + * @private + * @decorator + */ + private static linuxOnly(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) { + if (process.platform !== "linux") { + descriptor.value = function () { + return; + }; } + } - /******************************************************************************************* - * Private Methods - * ****************************************************************************************/ + /** + * Connects to MPRIS Service + */ + private static connect() { + const player = new Player({ + name: "cider", + identity: "Cider", + supportedInterfaces: ["player"], + }); - /** - * Runs a media event - * @param type - pausePlay, nextTrack, PreviousTrack - * @private - */ - private runMediaEvent(type: string) { - if (this._win) { - this._win.webContents.executeJavaScript(`MusicKitInterop.${type}()`).catch(console.error) - } + console.debug(`[${mpris.name}:connect] Successfully connected.`); + + const renderer = mpris.utils.getWindow().webContents; + const loopType: { [key: string]: number } = { + none: 0, + track: 1, + playlist: 2, + }; + + player.on("next", () => mpris.utils.playback.next()); + player.on("previous", () => mpris.utils.playback.previous()); + player.on("playpause", () => mpris.utils.playback.playPause()); + player.on("play", () => mpris.utils.playback.play()); + player.on("pause", () => mpris.utils.playback.pause()); + player.on("quit", () => mpris.utils.getApp().exit()); + player.on("position", (args: { position: any }) => mpris.utils.playback.seek(args.position / 1000 / 1000)); + player.on("loopStatus", (status: string) => renderer.executeJavaScript(`app.mk.repeatMode = ${loopType[status.toLowerCase()]}`)); + player.on("shuffle", () => renderer.executeJavaScript("app.mk.shuffleMode = (app.mk.shuffleMode === 0) ? 1 : 0")); + player.on("volume", (volume: string) => { + renderer.executeJavaScript(`app.mk.volume = ${parseFloat(volume)}`); + }); + player.on("raise", () => { + mpris.utils.getWindow().show(); + mpris.utils.getWindow().focus(); + }); + + mpris.utils.getIPCMain().on("mpris:playbackTimeDidChange", (event: any, time: number) => { + player.getPosition = () => time; + }); + + mpris.utils.getIPCMain().on("repeatModeDidChange", (_e: any, mode: number) => { + switch (mode) { + case 0: + player.loopStatus = Player.LOOP_STATUS_NONE; + break; + case 1: + player.loopStatus = Player.LOOP_STATUS_TRACK; + break; + case 2: + player.loopStatus = Player.LOOP_STATUS_PLAYLIST; + break; + } + }); + + mpris.utils.getIPCMain().on("mpris:volumeChange", (_e: any, volume: number) => { + player.volume = volume; + }); + + mpris.utils.getIPCMain().on("shuffleModeDidChange", (_e: any, mode: number) => { + player.shuffle = mode === 1; + }); + + mpris.player = player; + } + + /** + * Update M.P.R.I.S Player Attributes + */ + private static updateMetaData(attributes: any) { + mpris.player.metadata = { + "mpris:trackid": mpris.player.objectPath(`track/${attributes.playParams.id.replace(/[^a-zA-Z 0-9]+/g, "")}`), + "mpris:length": attributes.durationInMillis * 1000, // In microseconds + "mpris:artUrl": attributes.artwork.url.replace("/{w}x{h}bb", "/512x512bb").replace("/2000x2000bb", "/35x35bb"), + "xesam:title": `${attributes.name}`, + "xesam:album": `${attributes.albumName}`, + "xesam:artist": [`${attributes.artistName}`], + "xesam:genre": attributes.genreNames, + }; + } + + /******************************************************************************************* + * Public Methods + * ****************************************************************************************/ + + /** + * Clear state + * @private + */ + private static clearState() { + if (!mpris.player) { + return; } + mpris.player.metadata = { + "mpris:trackid": "/org/mpris/MediaPlayer2/TrackList/NoTrack", + }; + mpris.player.playbackStatus = Player.PLAYBACK_STATUS_STOPPED; + } - /** - * Blocks non-linux systems from running this plugin - * @private - * @decorator - */ - private static linuxOnly(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) { - if (process.platform !== 'linux') { - descriptor.value = function () { - return - } - } - } + /** + * Runs on app ready + */ + @mpris.linuxOnly + onReady(_: any): void { + console.debug(`[${mpris.name}:onReady] Ready.`); + } + /** + * Renderer ready + */ + @mpris.linuxOnly + onRendererReady(): void { + mpris.connect(); + } - /** - * Connects to MPRIS Service - */ - @MPRIS.linuxOnly - private connect() { - this.mpris = Player({ - name: 'Cider', - identity: 'Cider', - supportedUriSchemes: [], - supportedMimeTypes: [], - supportedInterfaces: ['player'] - }); - this.mpris = Object.assign(this.mpris, { - canQuit: true, - canControl: true, - canPause: true, - canPlay: true, - canGoNext: true, - active: true - }) + /** + * Runs on app stop + */ + @mpris.linuxOnly + onBeforeQuit(): void { + console.debug(`[Plugin][${mpris.name}] Stopped.`); + mpris.clearState(); + } + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + @mpris.linuxOnly + onPlaybackStateDidChange(attributes: any): void { + mpris.player.playbackStatus = attributes?.status ? Player.PLAYBACK_STATUS_PLAYING : Player.PLAYBACK_STATUS_PAUSED; + } - const pos_atr = {durationInMillis: 0}; - this.mpris.getPosition = function () { - const durationInMicro = pos_atr.durationInMillis * 1000; - const percentage = parseFloat("0") || 0; - return durationInMicro * percentage; - } - - for (const [key, value] of Object.entries(this.mprisEvents)) { - this.mpris.on(key, () => { - this.runMediaEvent(value) - }); - } - } - - /** - * Update MPRIS Player Attributes - */ - @MPRIS.linuxOnly - private updatePlayer(attributes: any) { - - const MetaData = { - 'mpris:trackid': this.mpris.objectPath(`track/${attributes.playParams.id.replace(/[.]+/g, "")}`), - 'mpris:length': attributes.durationInMillis * 1000, // In microseconds - 'mpris:artUrl': (attributes.artwork.url.replace('/{w}x{h}bb', '/512x512bb')).replace('/2000x2000bb', '/35x35bb'), - 'xesam:title': `${attributes.name}`, - 'xesam:album': `${attributes.albumName}`, - 'xesam:artist': [`${attributes.artistName}`,], - 'xesam:genre': attributes.genreNames - } - - if (this.mpris.metadata["mpris:trackid"] === MetaData["mpris:trackid"]) { - return - } - - this.mpris.metadata = MetaData - - } - - /** - * Update MPRIS Player State - * @private - * @param attributes - */ - @MPRIS.linuxOnly - private updatePlayerState(attributes: any) { - - let status = 'Stopped'; - if (attributes.status) { - status = 'Playing'; - } else if (attributes.status === false) { - status = 'Paused'; - } - - if (this.mpris.playbackStatus === status) { - return - } - this.mpris.playbackStatus = status; - } - - /** - * Clear state - * @private - */ - private clearState() { - this.mpris.metadata = {'mpris:trackid': '/org/mpris/MediaPlayer2/TrackList/NoTrack'} - this.mpris.playbackStatus = 'Stopped'; - } - - - /******************************************************************************************* - * Public Methods - * ****************************************************************************************/ - - /** - * Runs on plugin load (Currently run on application start) - */ - constructor(app: any, _store: any) { - this._app = app; - console.debug(`[Plugin][${this.name}] Loading Complete.`); - } - - /** - * Runs on app ready - */ - onReady(win: any): void { - this._win = win; - console.debug(`[Plugin][${this.name}] Ready.`); - this.connect() - } - - /** - * Runs on app stop - */ - onBeforeQuit(): void { - console.debug(`[Plugin][${this.name}] Stopped.`); - this.clearState() - } - - /** - * Runs on playback State Change - * @param attributes Music Attributes (attributes.state = current state) - */ - onPlaybackStateDidChange(attributes: object): void { - this.updatePlayerState(attributes) - } - - /** - * Runs on song change - * @param attributes Music Attributes - */ - onNowPlayingItemDidChange(attributes: object): void { - this.updatePlayer(attributes); - } - + /** + * Runs on song change + * @param attributes Music Attributes + */ + @mpris.linuxOnly + playbackTimeDidChange(attributes: object): void { + mpris.updateMetaData(attributes); + } } diff --git a/src/main/plugins/playbackNotifications.ts b/src/main/plugins/playbackNotifications.ts new file mode 100644 index 00000000..870b7180 --- /dev/null +++ b/src/main/plugins/playbackNotifications.ts @@ -0,0 +1,118 @@ +import fetch from "node-fetch"; +import { app, nativeImage, Notification } from "electron"; +import NativeImage = Electron.NativeImage; +import { createWriteStream } from "fs"; +import { join } from "path"; + +export default class playbackNotifications { + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "Playback Notifications"; + public description: string = "Creates notifications on playback."; + public version: string = "1.0.0"; + public author: string = "Core"; + public contributors: string[] = ["Core", "Monochromish"]; + + private _utils: any; + private _notification: Notification | undefined; + private _artworkImage: { [key: string]: NativeImage } = {}; + private _artworkNums: string[] = []; + + /** + * Creates playback notification + * @param a: Music Attributes + */ + createNotification(a: any): void { + if (this._notification) { + this._notification.close(); + } + + this._notification = new Notification({ + title: a.name, + body: `${a.artistName} — ${a.albumName}`, + silent: true, + icon: this._artworkImage[a.artwork.url], + urgency: "low", + actions: [ + { + type: "button", + text: `${this._utils.getLocale(this._utils.getStoreValue("general.language"), "term.skip")}`, + }, + ], + toastXml: ` + + `, + }); + + this._notification.on("click", (_: any) => { + this._utils.getWindow().show(); + this._utils.getWindow().focus(); + }); + + this._notification.on("close", (_: any) => { + this._notification = undefined; + }); + + this._notification.on("action", (event: any, action: any) => { + this._utils.playback.next(); + }); + + this._notification.show(); + } + + /******************************************************************************************* + * Public Methods + * ****************************************************************************************/ + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(utils: any) { + this._utils = utils; + console.debug(`[Plugin][${this.name}] Loading Complete.`); + + utils.getIPCMain().on("playbackNotifications:create", (event: any, a: any) => { + a.artwork.url = a.artwork.url.replace("/{w}x{h}bb", "/512x512bb").replace("/2000x2000bb", "/35x35bb"); + + if (this._artworkNums.length > 20) { + delete this._artworkImage[this._artworkNums[0]]; + this._artworkNums.shift(); + } + + if (this._artworkImage[a.artwork.url]) { + this.createNotification(a); + } else { + if (process.platform === "win32") { + fetch(a.artwork.url).then((res) => { + console.log(join(app.getPath("temp"), `${a.songId}-${a.artwork.url.split("/").pop()}`)); + const dest = createWriteStream(join(app.getPath("temp"), `${a.songId}-${a.artwork.url.split("/").pop()}`)); + // @ts-ignore + let stream = res.body.pipe(dest); + stream.on("finish", () => { + this.createNotification(a); + }); + }); + } else { + fetch(a.artwork.url).then(async (blob) => { + this._artworkImage[a.artwork.url] = nativeImage.createFromBuffer(Buffer.from(await blob.arrayBuffer())); + this._artworkNums[this._artworkNums.length] = a.artwork.url; + this.createNotification(a); + }); + } + } + }); + } +} diff --git a/src/main/plugins/raop.ts b/src/main/plugins/raop.ts new file mode 100644 index 00000000..3fa097f7 --- /dev/null +++ b/src/main/plugins/raop.ts @@ -0,0 +1,511 @@ +import electron from "electron"; +import fetch from "node-fetch"; +import { Stream } from "stream"; +import { Worker } from "worker_threads"; +import mdnsjs from "mdns-js"; + +export default class RAOP { + /** + * Private variables for interaction in plugins + */ + private _utils: any; + private _win: any; + private _app: any; + private _store: any; + private _cacheAttr: any; + private u: any; + private ipairplay: any = ""; + private portairplay: any = ""; + + private airtunes: any; + // private device: any; + private mdns = mdnsjs; + private ok: any = 1; + private devices: any = []; + private castDevices: any = []; + private i: any = false; + private audioStream: any = new Stream.PassThrough(); + private ffmpeg: any = null; + private worker: any = null; + + private processNode = ` + const { + Worker, isMainThread, parentPort, workerData + } = require('node:worker_threads'); + function getAudioConv (buffers) { + + function interleave16(leftChannel, rightChannel) { + var length = leftChannel.length + rightChannel.length; + var result = new Int16Array(length); + + var inputIndex = 0; + + for (var index = 0; index < length;) { + result[index++] = leftChannel[inputIndex]; + result[index++] = rightChannel[inputIndex]; + inputIndex++; + } + return result; + } + + + + function convert(n) { + var v = n < 0 ? n * 32768 : n * 32767; // convert in range [-32768, 32767] + return Math.max(-32768, Math.min(32768, v)); // clamp + } + + function bitratechange(e) { + var t = e.length; + let sampleRate = 96.0; + let outputSampleRate = 44.1; + var s = 0, + o = sampleRate / outputSampleRate, + u = Math.ceil(t * outputSampleRate / sampleRate), + a = new Int16Array(u); + for (let i = 0; i < u; i++) { + a[i] = e[Math.floor(s)]; + s += o; + } + + return a; + } + + let newaudio = buffers; + + let pcmData = new Int8Array(interleave16(bitratechange(Int16Array.from(newaudio[0], x => convert(x))), bitratechange(Int16Array.from(newaudio[1], x => convert(x)))).buffer); + return pcmData; + } + parentPort.on("message", data => { + parentPort.postMessage({buffer: data.buffer, outbuffer: getAudioConv(data.buffer)}); + }); + +`; + + private ondeviceup(name: any, host: any, port: any, addresses: any, text: any, airplay2: any = null) { + // console.log(this.castDevices.findIndex((item: any) => {return (item.name == host.replace(".local","") && item.port == port )})) + + let d = ""; + let audiook = true; + try { + d = text.filter((u: any) => String(u).startsWith("features=")); + if (d.length == 0) d = text.filter((u: any) => String(u).startsWith("ft=")); + let features_set = d.length > 0 ? d[0].substring(d[0].indexOf("=") + 1).split(",") : []; + let features = [...(features_set.length > 0 ? parseInt(features_set[0]).toString(2).split("") : []), ...(features_set.length > 1 ? parseInt(features_set[1]).toString(2).split("") : [])]; + if (features.length > 0) { + audiook = features[features.length - 1 - 9] == "1"; + } + } catch (_) {} + if (audiook) { + let shown_name = name; + try { + let model = text.filter((u: any) => String(u).startsWith("model=")); + let manufacturer = text.filter((u: any) => String(u).startsWith("manufacturer=")); + let name1 = text.filter((u: any) => String(u).startsWith("name=")); + if (name1.length > 0) { + shown_name = name1[0].split("=")[1]; + } else if (manufacturer.length > 0) { + shown_name = (manufacturer.length > 0 ? manufacturer[0].substring(13) : "") + " " + (model.length > 0 ? model[0].substring(6) : ""); + shown_name = shown_name.trim().length > 1 ? shown_name : (host ?? "Unknown").replace(".local", ""); + } + } catch (e) {} + let host_name = addresses != null && typeof addresses == "object" && addresses.length > 0 ? addresses[0] : typeof addresses == "string" ? addresses : ""; + + if ( + this.castDevices.findIndex((item: any) => { + return item != null && item.name == shown_name && item.host == host_name && item.host != "Unknown"; + }) == -1 + ) { + this.castDevices.push({ + name: shown_name, + host: host_name, + port: port, + addresses: addresses, + txt: text, + airplay2: airplay2, + }); + // if (this.devices.indexOf(host_name) === -1) { + // this.devices.push(host_name); + // } + if (shown_name) { + this._win.webContents.executeJavaScript(`console.log('deviceFound','ip: ${host_name} name:${shown_name}')`).catch((err: any) => console.error(err)); + console.log("deviceFound", host_name, shown_name); + } + } else { + this._win.webContents.executeJavaScript(`console.log('deviceFound (added)','ip: ${host_name} name:${shown_name}')`).catch((err: any) => console.error(err)); + console.log("deviceFound (added)", host_name, shown_name); + } + } + } + + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "RAOP"; + public description: string = "RAOP Plugin"; + public version: string = "0.0.1"; + public author: string = "vapormusic / Cider Collective"; + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(utils: { getStore: () => any; getApp: () => any }) { + this._utils = utils; + console.debug(`[Plugin][${this.name}] Loading Complete.`); + this._app = utils.getApp(); + } + + /** + * Runs on app ready + */ + async onReady(win: any): Promise { + this.u = (await import("airtunes2")).default; + this._win = win; + + electron.ipcMain.on("getKnownAirplayDevices", (event) => { + event.returnValue = this.castDevices; + }); + + electron.ipcMain.on("getAirplayDevice", (event, data) => { + this.castDevices = []; + console.debug("scan for airplay devices"); + + const browser = this.mdns.createBrowser(this.mdns.tcp("raop")); + browser.on("ready", browser.discover); + + browser.on("update", (service: any) => { + if (service.addresses && service.fullname && service.fullname.includes("_raop._tcp")) { + // console.log(service.txt) + this._win.webContents.executeJavaScript(`console.log( + "${service.name} ${service.host}:${service.port} ${service.addresses} ${service.fullname}" + )`); + let itemname = service.fullname.substring(service.fullname.indexOf("@") + 1, service.fullname.indexOf("._raop._tcp")); + this.ondeviceup(itemname, service.host, service.port, service.addresses, service.txt); + } + }); + + const browser2 = this.mdns.createBrowser(this.mdns.tcp("airplay")); + browser2.on("ready", browser2.discover); + + browser2.on("update", (service: any) => { + if (service.addresses && service.fullname && service.fullname.includes("_airplay._tcp")) { + // console.log(service.txt) + this._win.webContents.executeJavaScript(`console.log( + "${service.name} ${service.host}:${service.port} ${service.addresses}" + )`); + let itemname = service.fullname.substring(service.fullname.indexOf("@") + 1, service.fullname.indexOf("._airplay._tcp")); + this.ondeviceup(itemname, service.host, service.port, service.addresses, service.txt, true); + } + }); + + // const browser2 = this.mdns.createBrowser(this.mdns.tcp('airplay')); + // browser2.on('ready', browser2.discover); + + // browser2.on('update', (service: any) => { + // if (service.addresses && service.fullname && (service.fullname.includes('_raop._tcp') || service.fullname.includes('_airplay._tcp'))) { + // // console.log(service.txt) + // this._win.webContents.executeJavaScript(`console.log( + // "${service.name} ${service.host}:${service.port} ${service.addresses}" + // )`); + // this.ondeviceup(service.name, service.host, service.port, service.addresses, service.txt); + // } + // }); + }); + + electron.ipcMain.on("performAirplayPCM", (event, ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv, silent) => { + if (ipv4 != this.ipairplay || ipport != this.portairplay) { + if (this.airtunes == null) { + this.airtunes = new this.u(); + } + this.ipairplay = ipv4; + this.portairplay = ipport; + let identifier = ipv4 + ":" + ipport + "ap"; + let idx = this.devices.findIndex((a: any) => { + return a.id == identifier; + }); + if (idx != -1) { + delete this.devices[idx]; + this.devices = this.devices.filter((n: any) => n); // remove old controller + } + this.devices.push({ + id: identifier, + ip: ipv4, + port: ipport, + state: 0, + controller: this.airtunes.add(ipv4, { + port: ipport, + volume: airplay2dv ? 30 : 50, + password: sepassword, + txt: txt, + airplay2: airplay2dv, + debug: false, + forceAlac: false, + }), + }); + + idx = this.devices.findIndex((a: any) => { + return a.id == identifier; + }); + + // console.log('lol', this.devices) + this.devices[idx].controller.on("status", (status: any) => { + console.log("device status", status); + if (status == "ready") { + this._win.webContents.setAudioMuted(true); + this._win.webContents.executeJavaScript(`CiderAudio.sendAudio()`).catch((err: any) => console.error(err)); + } + if (status == "need_password") { + this._win.webContents.executeJavaScript(`app.setAirPlayCodeUI('${this.devices[idx].id}')`); + } + if (status == "pair_success") { + this._win.webContents.executeJavaScript(`app.sendAirPlaySuccess(${silent},'${this.devices[idx].id}')`); + } + if (status == "pair_failed") { + this._win.webContents.executeJavaScript(`app.sendAirPlayFailed()`); + this.disconnectAirplay(this.devices[idx].id); + } + if (status == "stopped") { + // this.airtunes.stopAll(() => { + // console.log("end"); + // }); + if (this.devices[idx]?.state != null && this.devices[idx].state != -1) this._win.webContents.executeJavaScript(`app.airplayDisconnect(true, ${JSON.stringify([ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv])})`).catch((err: any) => console.error(err)); + // this.airtunes = null; + // this.device = null; + // this.ipairplay = ""; + // this.portairplay = ""; + // this.ok = 1; + } else { + setTimeout(() => { + if (this.ok == 1) { + console.log(this.devices[idx].controller.key, title ?? "", artist ?? "", album ?? ""); + this.airtunes.setTrackInfo(this.devices[idx].controller.key, title ?? "", artist ?? "", album ?? ""); + this.uploadImageAirplay(artworkURL); + console.log("done", status); + this.ok == 2; + } + }, 1000); + } + }); + } + }); + + electron.ipcMain.on("setAirPlayPasscode", (event, passcode, identifier) => { + if (this.devices.length > 0) { + let idx = this.devices.findIndex((a: any) => { + return a.id == identifier; + }); + if (idx != -1) { + this.devices[idx].controller.setPasscode(passcode); + } + } + }); + + electron.ipcMain.on("setAirPlayVolume", (event, volume, identifier) => { + if (this.devices.length > 0) { + let idx = this.devices.findIndex((a: any) => { + return a.id == identifier; + }); + if (idx != -1) { + this.devices[idx].controller.setVolume(volume); + } + } + }); + + electron.ipcMain.on("writeWAV", (event, leftbuffer, rightbuffer) => { + if (this.airtunes != null) { + if (this.worker == null) { + try { + // const toDataUrl = (js: any) => new URL(`data:text/javascript,${encodeURIComponent(js)}`); + // let blob = new Blob([this.processNode], { type: 'application/javascript' }); + //Create new worker + this.worker = new Worker(this.processNode, { eval: true }); + + //Listen for a message from worker + this.worker.on("message", (result: any) => { + // fs.writeFile(join(electron.app.getPath('userData'), 'buffer.raw'), Buffer.from(Int8Array.from(result.outbuffer)),{flag: 'a+'}, function (err) { + // if (err) throw err; + // console.log('It\'s saved!'); + // }); + this.airtunes.circularBuffer.write(Buffer.from(Int8Array.from(result.outbuffer))); + }); + + this.worker.on("error", (error: any) => { + console.log("worker err", error); + }); + this.worker.postMessage({ buffer: [leftbuffer, rightbuffer] }); + } catch (e) { + console.log(e); + } + + // this.ffmpeg != null ? this.ffmpeg.kill() : null; + // this.ffmpeg = spawn(this._utils.getStoreValue("advanced.ffmpegLocation"), [ + // '-f', 's16le', // PCM 16bits, little-endian + // '-ar', '48000', + // '-ac', "2", + // '-err_detect','ignore_err', + // '-i', "http://localhost:9000/audio.wav", + // '-acodec', 'pcm_s16le', + // '-f', 's16le', // PCM 16bits, little-endian + // '-ar', '44100', // Sampling rate + // '-ac', "2", // Stereo + // 'pipe:1' // Output on stdout + // ]); + + // // pipe data to AirTunes + // this.ffmpeg.stdout.pipe(this.airtunes); + // this.i = true; + } else { + this.worker.postMessage({ buffer: [leftbuffer, rightbuffer] }); + } + } + }); + + electron.ipcMain.on("disconnectAirplay", (event, identifier = "") => { + console.log("iden", identifier); + this.disconnectAirplay(identifier); + }); + + electron.ipcMain.on("updateAirplayInfo", (event, title, artist, album, artworkURL) => { + if (this.airtunes && this.devices.length > 0) { + for (let i in this.devices) { + console.log(this.devices[i].controller.key, title, artist, album); + this.airtunes.setTrackInfo(this.devices[i].controller.key, title, artist, album); + } + this.uploadImageAirplay(artworkURL); + } + }); + + electron.ipcMain.on("discordrpc:updateImage", (_event, imageurl) => { + this.uploadImageAirplay(imageurl); + }); + } + private disconnectAirplay(identifier: any = "") { + console.log("awdas"); + this._win.webContents + .executeJavaScript(`app.airplayDisconnect(false, [], '${identifier}')`) + .then(() => { + if (identifier == "") { + if (this.airtunes) { + for (let i in this.devices) { + this.devices[i].state = -1; + } + this.airtunes.stopAll(() => { + console.log("endAll"); + this.airtunes = null; + this.devices = []; + this.airtunes = null; + + this.ipairplay = ""; + this.portairplay = ""; + this.ok = 1; + this.i = false; + }); + } else { + this.devices = []; + } + } else { + let idx = this.devices.findIndex((a: any) => { + return a.id == identifier; + }); + if (idx != -1) { + this.devices[idx].state = -1; + this.devices[idx].controller.stop(() => { + console.log(this.devices[idx].id, "stopped"); + }); + + delete this.devices[idx]; + this.devices = this.devices.filter((n: any) => n); + } + } + if (this.devices.length == 0) { + console.log("cleanup airtunes"); + this._win.webContents.setAudioMuted(false); + this.airtunes = null; + + this.ipairplay = ""; + this.portairplay = ""; + this.ok = 1; + this.i = false; + this.devices = []; + } + }) + .catch((err: any) => console.error("lsdsd", err)); + } + private uploadImageAirplay = (url: any) => { + try { + if (url != null && url != "") { + //console.log(join(this._app.getPath('userData'), 'temp.png'), url); + fetch(url) + .then((res) => res.buffer()) + .then((buffer) => { + if (this.airtunes && this.devices.length > 0) { + for (let i in this.devices) { + this.airtunes.setArtwork(this.devices[i].controller.key, buffer, "image/png"); + } + } + }) + .catch((err) => { + console.log(err); + }); + } + } catch (e) { + console.log(e); + } + }; + + /** + * Runs on app stop + */ + onBeforeQuit(): void {} + + /** + * Runs on song change + * @param attributes Music Attributes + */ + onNowPlayingItemDidChange(attributes: any): void { + if (this.airtunes && this.devices.length > 0) { + let title = attributes?.name ?? ""; + let artist = attributes?.artistName ?? ""; + let album = attributes?.albumName ?? ""; + for (let i in this.devices) { + console.log(this.devices[i].controller.key, title, artist, album); + this.airtunes.setTrackInfo(this.devices[i].controller.key, title, artist, album); + } + let artworkURL = attributes?.artwork?.url ?? null; + + if (artworkURL != null) { + this.uploadImageAirplay(artworkURL.replace("{w}", "1024").replace("{h}", "1024")); + } + } + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + onPlaybackStateDidChange(attributes: any): void { + if (this.airtunes && this.devices.length > 0) { + let title = attributes?.name ?? ""; + let artist = attributes?.artistName ?? ""; + let album = attributes?.albumName ?? ""; + for (let i in this.devices) { + console.log(this.devices[i].controller.key, title, artist, album); + this.airtunes.setTrackInfo(this.devices[i].controller.key, title, artist, album); + } + let artworkURL = attributes?.artwork?.url ?? null; + + if (artworkURL != null) { + this.uploadImageAirplay(artworkURL.replace("{w}", "1024").replace("{h}", "1024")); + } + } + } + + playbackTimeDidChange(attributes: any): void { + // console.log(attributes) + if (this.airtunes && this.devices.length > 0 && attributes?.currentPlaybackTime != null && attributes?.durationInMillis != null) { + for (let i in this.devices) { + this.airtunes.setProgress(this.devices[i].controller.key, Math.round(attributes.currentPlaybackTime), Math.floor(attributes.durationInMillis / 1000)); + } + } + } +} diff --git a/src/main/plugins/thumbar.ts b/src/main/plugins/thumbar.ts new file mode 100644 index 00000000..9257af60 --- /dev/null +++ b/src/main/plugins/thumbar.ts @@ -0,0 +1,134 @@ +import { nativeImage, nativeTheme } from "electron"; +import { utils } from "../base/utils.js"; +import { join } from "path"; + +export default class Thumbar { + /** + * Private variables for interaction in plugins + */ + private _win: any; + private _app: any; + + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "Thumbnail Toolbar Plugin"; + public description: string = "Creates and managed the thumbnail toolbar buttons and their events"; + public version: string = "1.0.0"; + public author: string = "Core"; + + /** + * Thumbnail Toolbar Assets + */ + private icons: { [key: string]: Electron.NativeImage } = { + pause: nativeImage.createFromPath(join(utils.getPath("resourcePath"), "icons/thumbar", `${nativeTheme.shouldUseDarkColors ? "light" : "dark"}_pause.png`)), + play: nativeImage.createFromPath(join(utils.getPath("resourcePath"), "icons/thumbar", `${nativeTheme.shouldUseDarkColors ? "light" : "dark"}_play.png`)), + next: nativeImage.createFromPath(join(utils.getPath("resourcePath"), "icons/thumbar", `${nativeTheme.shouldUseDarkColors ? "light" : "dark"}_next.png`)), + previous: nativeImage.createFromPath(join(utils.getPath("resourcePath"), "icons/thumbar", `${nativeTheme.shouldUseDarkColors ? "light" : "dark"}_previous.png`)), + }; + + /******************************************************************************************* + * Private Methods + * ****************************************************************************************/ + + /** + * Blocks non-windows systems from running this plugin + * @private + * @decorator + */ + private static windowsOnly(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) { + if (process.platform !== "win32") { + descriptor.value = function () { + return; + }; + } + } + + /** + * Update the thumbnail toolbar + */ + private updateButtons(attributes: any) { + console.log(attributes); + + if (!attributes) { + return; + } + + const buttons = [ + { + tooltip: "Previous", + icon: this.icons.previous, + click() { + utils.playback.previous(); + }, + }, + { + tooltip: attributes.status ? "Pause" : "Play", + icon: attributes.status ? this.icons.pause : this.icons.play, + click() { + utils.playback.playPause(); + }, + }, + { + tooltip: "Next", + icon: this.icons.next, + click() { + utils.playback.next(); + }, + }, + ]; + + if (!attributes.playParams || attributes.playParams.id === "no-id-found") { + this._win.setThumbarButtons([]); + } else { + this._win.setThumbarButtons(buttons); + } + } + + /******************************************************************************************* + * Public Methods + * ****************************************************************************************/ + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(a: { getApp: () => any }) { + this._app = utils.getApp(); + console.debug(`[Plugin][${this.name}] Loading Complete.`); + } + + /** + * Runs on app ready + */ + @Thumbar.windowsOnly + onReady(win: Electron.BrowserWindow): void { + this._win = win; + console.debug(`[Plugin][${this.name}] Ready.`); + } + + /** + * Runs on app stop + */ + @Thumbar.windowsOnly + onBeforeQuit(): void { + console.debug(`[Plugin][${this.name}] Stopped.`); + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + @Thumbar.windowsOnly + onPlaybackStateDidChange(attributes: object): void { + this.updateButtons(attributes); + } + + /** + * Runs on song change + * @param attributes Music Attributes + */ + @Thumbar.windowsOnly + onNowPlayingItemDidChange(attributes: object): void { + this.updateButtons(attributes); + } +} diff --git a/src/main/plugins/webNowPlaying.ts b/src/main/plugins/webNowPlaying.ts new file mode 100644 index 00000000..58d66d01 --- /dev/null +++ b/src/main/plugins/webNowPlaying.ts @@ -0,0 +1,244 @@ +import WebSocket from "ws"; + +/** + * 0-pad a number. + * @param {Number} number + * @param {Number} length + * @returns String + */ +const pad = (number: number, length: number) => String(number).padStart(length, "0"); + +/** + * Convert seconds to a time string acceptable to Rainmeter + * https://github.com/tjhrulz/WebNowPlaying-BrowserExtension/blob/master/WebNowPlaying.js#L50-L59 + * @param {Number} timeInSeconds + * @returns String + */ +const convertTimeToString = (timeInSeconds: number) => { + const timeInMinutes = Math.floor(timeInSeconds / 60); + if (timeInMinutes < 60) { + return timeInMinutes + ":" + pad(Math.floor(timeInSeconds % 60), 2); + } + return Math.floor(timeInMinutes / 60) + ":" + pad(Math.floor(timeInMinutes % 60), 2) + ":" + pad(Math.floor(timeInSeconds % 60), 2); +}; + +export default class WebNowPlaying { + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = "WebNowPlaying"; + public description: string = "Song info and playback control for the Rainmeter WebNowPlaying plugin."; + public version: string = "1.0.1"; + public author: string = "Zennn "; + + private _win: any; + private ws?: WebSocket; + private wsapiConn?: WebSocket; + private playerName: string = "Cider"; + + constructor() { + console.debug(`[Plugin][${this.name}] Loading Complete.`); + } + + /** + * Blocks non-windows systems from running this plugin + * @private + * @decorator + */ + private static windowsOnly(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) { + if (process.platform !== "win32") { + descriptor.value = () => void 0; + } + } + + private sendSongInfo(attributes: any) { + if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return; + + const fields = ["STATE", "TITLE", "ARTIST", "ALBUM", "COVER", "DURATION", "POSITION", "VOLUME", "REPEAT", "SHUFFLE"]; + fields.forEach((field) => { + try { + let value: any = ""; + switch (field) { + case "STATE": + value = attributes.status ? 1 : 2; + break; + case "TITLE": + value = attributes.name; + break; + case "ARTIST": + value = attributes.artistName; + break; + case "ALBUM": + value = attributes.albumName; + break; + case "COVER": + value = attributes.artwork.url.replace("{w}", attributes.artwork.width).replace("{h}", attributes.artwork.height); + break; + case "DURATION": + value = convertTimeToString(attributes.durationInMillis / 1000); + break; + case "POSITION": + value = convertTimeToString((attributes.durationInMillis - attributes.remainingTime) / 1000); + break; + case "VOLUME": + value = attributes.volume * 100; + break; + case "REPEAT": + value = attributes.repeatMode; + break; + case "SHUFFLE": + value = attributes.shuffleMode; + break; + } + this.ws?.send(`${field}:${value}`); + } catch (error) { + if (this.ws?.readyState === WebSocket.OPEN) { + this.ws.send(`Error:Error updating ${field} for ${this.playerName}`); + this.ws.send(`ErrorD:${error}`); + } + } + }); + } + + private fireEvent(evt: WebSocket.MessageEvent) { + if (!evt.data) return; + const data = evt.data; + + let value: string = ""; + if (data.split(/ (.+)/).length > 1) { + value = data.split(/ (.+)/)[1]; + } + const eventName = data.split(" ")[0].toLowerCase(); + + try { + switch (eventName) { + case "playpause": + this._win.webContents.executeJavaScript("MusicKitInterop.playPause()").catch(console.error); + break; + case "next": + this._win.webContents.executeJavaScript("MusicKitInterop.next()").catch(console.error); + break; + case "previous": + this._win.webContents.executeJavaScript("MusicKitInterop.previous()").catch(console.error); + break; + case "setposition": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().seekToTime(${parseFloat(value)})`); + break; + case "setvolume": + this._win.webContents.executeJavaScript(`MusicKit.getInstance().volume = ${parseFloat(value) / 100}`); + break; + case "repeat": + this._win.webContents.executeJavaScript("wsapi.toggleRepeat()").catch(console.error); + break; + case "shuffle": + this._win.webContents.executeJavaScript("wsapi.toggleShuffle()").catch(console.error); + break; + case "togglethumbsup": + // not implemented + break; + case "togglethumbsdown": + // not implemented + break; + case "rating": + // not implemented + break; + } + } catch (error) { + console.debug(error); + if (this.ws?.readyState === WebSocket.OPEN) { + this.ws.send(`Error:Error sending event to ${this.playerName}`); + this.ws.send(`ErrorD:${error}`); + } + } + } + + /** + * Runs on app ready + */ + @WebNowPlaying.windowsOnly + public onReady(win: any) { + this._win = win; + + // Connect to Rainmeter plugin and retry on disconnect. + const init = () => { + try { + this.ws = new WebSocket("ws://127.0.0.1:8974/"); + let retry: NodeJS.Timeout; + this.ws.onopen = () => { + console.info("[WebNowPlaying] Connected to Rainmeter"); + this.ws?.send(`PLAYER:${this.playerName}`); + }; + + this.ws.onclose = () => { + clearTimeout(retry); + retry = setTimeout(init, 2000); + }; + + this.ws.onerror = () => { + clearTimeout(retry); + this.ws?.close(); + }; + + this.ws.onmessage = this.fireEvent?.bind(this); + } catch (error) { + console.error(error); + } + }; + + init(); + + // Connect to wsapi. Only used to update progress. + try { + this.wsapiConn = new WebSocket("ws://127.0.0.1:26369/"); + + this.wsapiConn.onopen = () => { + console.info("[WebNowPlaying] Connected to wsapi"); + }; + + this.wsapiConn.onmessage = (evt: WebSocket.MessageEvent) => { + const response = JSON.parse(evt.data); + if (response.type === "playbackStateUpdate") { + this.sendSongInfo(response.data); + } + }; + } catch (error) { + console.error(error); + } + + console.debug(`[Plugin][${this.name}] Ready.`); + } + + /** + * Runs on app stop + */ + @WebNowPlaying.windowsOnly + public onBeforeQuit() { + if (this.ws) { + this.ws.send("STATE:0"); + this.ws.onclose = () => void 0; // disable onclose handler first to stop it from retrying + this.ws.close(); + } + if (this.wsapiConn) { + this.wsapiConn.close(); + } + console.debug(`[Plugin][${this.name}] Stopped.`); + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + @WebNowPlaying.windowsOnly + public onPlaybackStateDidChange(attributes: any) { + this.sendSongInfo(attributes); + } + + /** + * Runs on song change + * @param attributes Music Attributes + */ + @WebNowPlaying.windowsOnly + public onNowPlayingItemDidChange(attributes: any) { + this.sendSongInfo(attributes); + } +} diff --git a/src/main/providers/local/index.ts b/src/main/providers/local/index.ts new file mode 100644 index 00000000..c3ec6dea --- /dev/null +++ b/src/main/providers/local/index.ts @@ -0,0 +1,197 @@ +// import { ProviderDB } from "./db"; +import { EventEmitter } from "events"; +import mm from "music-metadata"; +import { resolve } from "node:path"; +import { Md5 } from "ts-md5"; +import { utils } from "../../base/utils.js"; +import { readdirSync } from "node:fs"; + +export class LocalFiles { + static localSongs: any = []; + static localSongsArts: any = []; + // public static DB = ProviderDB.db; + static eventEmitter = new EventEmitter(); + + static getDataType(item_id: String | any) { + if ((item_id ?? "").startsWith("ciderlocalart")) return "artwork"; + else if ((item_id ?? "").startsWith("ciderlocal")) return "track"; + } + + // static async sendOldLibrary() { + // ProviderDB.init(); + // let rows = (await ProviderDB.db.allDocs({ include_docs: true, attachments: true })).rows.map((item: any) => { + // return item.doc; + // }); + // let tracks = rows.filter((item: any) => { + // return this.getDataType(item._id) == "track"; + // }); + // let arts = rows.filter((item: any) => { + // return this.getDataType(item._id) == "artwork"; + // }); + // this.localSongs = tracks; + // this.localSongsArts = arts; + // return tracks; + // } + + static async scanLibrary() { + // ProviderDB.init(); + let folders = utils.getStoreValue("libraryPrefs.localPaths"); + if (folders == null || folders.length == null || folders.length == 0) folders = []; + let files: any[] = []; + for (var folder of folders) { + // get files from the Music folder + files = files.concat(await LocalFiles.getFiles(folder)); + } + + let supporttedformats = ["mp3", "aac", "webm", "flac", "m4a", "ogg", "wav", "opus"]; + let audiofiles = files.filter((f) => supporttedformats.includes(f.substring(f.lastIndexOf(".") + 1))); + let metadatalist = []; + let metadatalistart = []; + let numid = 0; + for (var audio of audiofiles) { + try { + const metadata = await mm.parseFile(audio); + let lochash = Md5.hashStr(audio) ?? numid; + if (metadata != null) { + let form = { + id: "ciderlocal" + lochash, + _id: "ciderlocal" + lochash, + type: "podcast-episodes", + href: audio, + attributes: { + artwork: { + width: 3000, + height: 3000, + url: "/ciderlocalart/" + "ciderlocal" + lochash, + }, + topics: [], + url: "", + subscribable: true, + mediaKind: "audio", + genreNames: [""], + // "playParams": { + // "id": "ciderlocal" + numid, + // "kind": "podcast", + // "isLibrary": true, + // "reporting": false }, + trackNumber: metadata.common.track?.no ?? 0, + discNumber: metadata.common.disk?.no ?? 0, + name: metadata.common.title ?? audio.substring(audio.lastIndexOf("\\") + 1), + albumName: metadata.common.album, + artistName: metadata.common.artist, + copyright: metadata.common.copyright ?? "", + assetUrl: "file:///" + audio, + contentAdvisory: "", + releaseDateTime: `${metadata?.common?.year ?? "2022"}-05-13T00:23:00Z`, + durationInMillis: Math.floor((metadata.format.duration ?? 0) * 1000), + bitrate: Math.floor((metadata.format?.bitrate ?? 0) / 1000), + offers: [ + { + kind: "get", + type: "STDQ", + }, + ], + contentRating: "clean", + }, + flavor: Math.floor((metadata.format?.bitrate ?? 0) / 1000), + localFilesMetadata: { + lossless: metadata.format?.lossless, + container: metadata.format?.container, + bitDepth: metadata.format?.bitsPerSample ?? 0, + sampleRate: metadata.format?.sampleRate ?? 0, + }, + }; + let art = { + id: "ciderlocal" + lochash, + _id: "ciderlocalart" + lochash, + url: metadata.common.picture != undefined ? metadata.common.picture[0].data.toString("base64") : "", + }; + metadatalistart.push(art); + numid += 1; + // ProviderDB.db.putIfNotExists(form); + // ProviderDB.db.putIfNotExists(art); + metadatalist.push(form); + + if (this.localSongs.length === 0 && numid % 10 === 0) { + // send updated chunks only if there is no previous database + this.eventEmitter.emit("newtracks", metadatalist); + } + } + } catch (e) { + console.error("localfiles error:", e); + } + } + // console.log('metadatalist', metadatalist); + this.localSongs = metadatalist; + this.localSongsArts = metadatalistart; + return metadatalist; + } + + static async getFiles(dir: string): Promise { + const dirents = readdirSync(dir, { withFileTypes: true }); + const files = await Promise.all( + dirents.map((dirent: any) => { + const res = resolve(dir, dirent.name); + return dirent.isDirectory() ? this.getFiles(res) : res; + }), + ); + return Array.prototype.concat(...files); + } + + // static async cleanUpDB() { + // let folders = utils.getStoreValue("libraryPrefs.localPaths"); + // let rows = (await ProviderDB.db.allDocs({ include_docs: true, attachments: true })).rows.map((item: any) => { + // return item.doc; + // }); + // let tracks = rows.filter((item: any) => { + // return ( + // this.getDataType(item._id) == "track" && + // !folders.some((i: String) => { + // return item["attributes"]["assetUrl"].startsWith("file:///" + i); + // }) + // ); + // }); + // let hashs = tracks.map((i: any) => { + // return i._id; + // }); + // for (let hash of hashs) { + // try { + // ProviderDB.db.get(hash).then(function (doc: any) { + // return ProviderDB.db.remove(doc); + // }); + // } catch (e) {} + // try { + // ProviderDB.db.get(hash.replace("ciderlocal", "ciderlocalart")).then(function (doc: any) { + // return ProviderDB.db.remove(doc); + // }); + // } catch (e) {} + // } + // } + + static setupHandlers() { + const app = utils.getExpress(); + console.log("Setting up handlers for local files"); + app.get("/ciderlocal/:songs", (req: any, res: any) => { + const audio = atob(req.params.songs.replace(/_/g, "/").replace(/-/g, "+")); + // console.log('auss', LocalFiles.localSongs) + let data = { + data: LocalFiles.localSongs.filter((f: any) => audio.split(",").includes(f.id)), + }; + res.send(data); + }); + + app.get("/ciderlocalart/:songs", (req: any, res: any) => { + const audio = req.params.songs; + // metadata.common.picture[0].data.toString('base64') + + res.setHeader("Cache-Control", "public, max-age=31536000"); + res.setHeader("Expires", new Date(Date.now() + 31536000000).toUTCString()); + res.setHeader("Content-Type", "image/jpeg"); + + let data = LocalFiles.localSongsArts.filter((f: any) => f.id == audio); + res.status(200).send(Buffer.from(data[0]?.url, "base64")); + }); + + return app; + } +} diff --git a/src/main/thumbaricons/backwardPng.png b/src/main/thumbaricons/backwardPng.png deleted file mode 100644 index 4c99640c..00000000 Binary files a/src/main/thumbaricons/backwardPng.png and /dev/null differ diff --git a/src/main/thumbaricons/forwardPng.png b/src/main/thumbaricons/forwardPng.png deleted file mode 100644 index 3de644f9..00000000 Binary files a/src/main/thumbaricons/forwardPng.png and /dev/null differ diff --git a/src/main/thumbaricons/pausePng.png b/src/main/thumbaricons/pausePng.png deleted file mode 100644 index 428b380a..00000000 Binary files a/src/main/thumbaricons/pausePng.png and /dev/null differ diff --git a/src/main/thumbaricons/playPng.png b/src/main/thumbaricons/playPng.png deleted file mode 100644 index 8ece27c0..00000000 Binary files a/src/main/thumbaricons/playPng.png and /dev/null differ diff --git a/src/preload/cider-preload.js b/src/preload/cider-preload.js index 0f55e657..1933ae5c 100644 --- a/src/preload/cider-preload.js +++ b/src/preload/cider-preload.js @@ -1,113 +1,352 @@ -global.ipcRenderer = require('electron').ipcRenderer; -console.log('Loaded Preload') +global.ipcRenderer = require("electron").ipcRenderer; +console.info("Loaded Preload"); -let cache = {playParams: {id: 0}, status: null, remainingTime: 0}, - playbackCache = {status: null, time: Date.now()}; +let cache = { playParams: { id: 0 }, status: null, remainingTime: 0 }, + playbackCache = { status: null, time: Date.now() }; const MusicKitInterop = { - init: function () { - MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => { - if (MusicKitInterop.filterTrack(MusicKitInterop.getAttributes(), true, false)) { - global.ipcRenderer.send('playbackStateDidChange', MusicKitInterop.getAttributes()) - ipcRenderer.send('wsapi-updatePlaybackState', MusicKitInterop.getAttributes()); - // if (typeof _plugins != "undefined") { - // _plugins.execute("OnPlaybackStateChanged", {Attributes: MusicKitInterop.getAttributes()}) - // } - } - }); + init: function () { + /* MusicKit.Events.playbackStateDidChange */ + MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => { + const attributes = MusicKitInterop.getAttributes(); + if (!attributes) return; + MusicKitInterop.updateMediaState(attributes); + if (MusicKitInterop.filterTrack(attributes, true, false)) { + global.ipcRenderer.send("playbackStateDidChange", attributes); + global.ipcRenderer.send("wsapi-updatePlaybackState", attributes); + } + }); - /** wsapi */ - MusicKit.getInstance().addEventListener(MusicKit.Events.playbackProgressDidChange, () => { - ipcRenderer.send('wsapi-updatePlaybackState', MusicKitInterop.getAttributes()); - }); - /** wsapi */ + /* MusicKit.Events.playbackProgressDidChange */ + MusicKit.getInstance().addEventListener(MusicKit.Events.playbackProgressDidChange, async () => { + const attributes = MusicKitInterop.getAttributes(); + if (!attributes) return; + // wsapi call + ipcRenderer.send("wsapi-updatePlaybackState", attributes); + // lastfm call + if (app.mk.currentPlaybackProgress === app.cfg.connectivity.lastfm.scrobble_after / 100) { + attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchSongRelationships() : attributes.artistName; + ipcRenderer.send("lastfm:scrobbleTrack", attributes); + } + }); - MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, () => { - if (MusicKitInterop.filterTrack(MusicKitInterop.getAttributes(), false, true) || !app.cfg.lastfm.filterLoop) { - global.ipcRenderer.send('nowPlayingItemDidChange', MusicKitInterop.getAttributes()); - } - }); + /* MusicKit.Events.playbackTimeDidChange */ + MusicKit.getInstance().addEventListener(MusicKit.Events.playbackTimeDidChange, () => { + ipcRenderer.send("mpris:playbackTimeDidChange", MusicKit.getInstance()?.currentPlaybackTime * 1000 * 1000 ?? 0); + const attributes = MusicKitInterop.getAttributes(); + if (!attributes) return; + ipcRenderer.send("playbackTimeDidChange", attributes); + MusicKitInterop.updatePositionState(attributes); + }); - MusicKit.getInstance().addEventListener(MusicKit.Events.authorizationStatusDidChange, () => { - global.ipcRenderer.send('authorizationStatusDidChange', MusicKit.getInstance().authorizationStatus) - }) + /* MusicKit.Events.nowPlayingItemDidChange */ + MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, async () => { + if (window?.localStorage) { + window.localStorage.setItem("currentTrack", JSON.stringify(MusicKit.getInstance().nowPlayingItem)); + window.localStorage.setItem("currentTime", JSON.stringify(MusicKit.getInstance().currentPlaybackTime)); + window.localStorage.setItem("currentQueue", JSON.stringify(MusicKit.getInstance().queue?._unplayedQueueItems)); + } - MusicKit.getInstance().addEventListener(MusicKit.Events.mediaPlaybackError, (e) => { - console.warn(`[mediaPlaybackError] ${e}`); - }) - }, + const attributes = MusicKitInterop.getAttributes(); + if (!attributes) return; + attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchSongRelationships() : attributes.artistName; - getAttributes: function () { - const mk = MusicKit.getInstance() - const nowPlayingItem = mk.nowPlayingItem; - const isPlayingExport = mk.isPlaying; - const remainingTimeExport = mk.currentPlaybackTimeRemaining; - const attributes = (nowPlayingItem != null ? nowPlayingItem.attributes : {}); + MusicKitInterop.updateMediaSession(attributes); + global.ipcRenderer.send("nowPlayingItemDidChange", attributes); - attributes.status = isPlayingExport ?? false; - attributes.name = attributes?.name ?? 'No Title Found'; - attributes.artwork = attributes?.artwork ?? {url: ''}; - attributes.artwork.url = (attributes?.artwork?.url ?? '').replace(`{f}`, "png"); - attributes.playParams = attributes?.playParams ?? {id: 'no-id-found'}; - attributes.playParams.id = attributes?.playParams?.id ?? 'no-id-found'; - attributes.url = { - cider: "cider://play/s/" + nowPlayingItem?._songId ?? 'no-id-found', - appleMusic: "https://music.apple.com/"+ mk.storefrontId +"/song/" + nowPlayingItem?._songId ?? 'no-id-found' - } - if (attributes.playParams.id === 'no-id-found') { - attributes.playParams.id = nowPlayingItem?.id ?? 'no-id-found'; - } - attributes.albumName = attributes?.albumName ?? ''; - attributes.artistName = attributes?.artistName ?? ''; - attributes.genreNames = attributes?.genreNames ?? []; - attributes.remainingTime = remainingTimeExport - ? remainingTimeExport * 1000 - : 0; - attributes.durationInMillis = attributes?.durationInMillis ?? 0; - attributes.startTime = Date.now(); - attributes.endTime = Math.round( - attributes?.playParams?.id === cache.playParams.id - ? Date.now() + attributes?.remainingTime - : attributes?.startTime + attributes?.durationInMillis - ); - return attributes; - }, + if (MusicKitInterop.filterTrack(attributes, false, true)) { + global.ipcRenderer.send("lastfm:FilteredNowPlayingItemDidChange", attributes); + } else if (attributes.name !== "no-title-found" && attributes.playParams.id !== "no-id-found") { + global.ipcRenderer.send("lastfm:nowPlayingChange", attributes); + } - filterTrack: function (a, playbackCheck, mediaCheck) { - if (a.title === "No Title Found" || a.playParams.id === "no-id-found") { - return; - } else if (mediaCheck && a.playParams.id === cache.playParams.id) { - return; - } else if (playbackCheck && a.status === playbackCache.status) { - return; - } else if (playbackCheck && !a.status && a.remainingTime === playbackCache.time) { /* Pretty much have to do this to prevent multiple runs when a song starts playing */ - return; - } - cache = a; - if (playbackCheck) playbackCache = {status: a.status, time: a.remainingTime}; - return true; - }, + if (app.cfg.general.playbackNotifications && !document.hasFocus() && attributes.artistName && attributes.artwork && attributes.name) { + global.ipcRenderer.send("playbackNotifications:create", attributes); + } - pausePlay: function () { - if (MusicKit.getInstance().isPlaying) { - MusicKit.getInstance().pause(); - } else if (MusicKit.getInstance().nowPlayingItem != null) { - MusicKit.getInstance().play().then(r => console.log(`[MusicKitInterop] Playing ${r}`)); - } - }, + if (MusicKit.getInstance().nowPlayingItem) { + await this.sleep(750); + MusicKit.getInstance().playbackRate = app.cfg.audio.playbackRate; + } + console.debug("[cider:preload] nowPlayingItemDidChange"); + }); - nextTrack: function () { - MusicKit.getInstance().skipToNextItem().then(r => console.log(`[MusicKitInterop] Skipping to Next ${r}`)); - }, + /* MusicKit.Events.authorizationStatusDidChange */ + MusicKit.getInstance().addEventListener(MusicKit.Events.authorizationStatusDidChange, () => { + global.ipcRenderer.send("authorizationStatusDidChange", MusicKit.getInstance().authorizationStatus); + }); - previousTrack: function () { - MusicKit.getInstance().skipToPreviousItem().then(r => console.log(`[MusicKitInterop] Skipping to Previous ${r}`)); - } + /* MusicKit.Events.mediaPlaybackError */ + MusicKit.getInstance().addEventListener(MusicKit.Events.mediaPlaybackError, (e) => { + console.warn(`[cider:preload] mediaPlaybackError] ${e}`); + }); -} + /* MusicKit.Events.shuffleModeDidChange */ + MusicKit.getInstance().addEventListener(MusicKit.Events.shuffleModeDidChange, () => { + global.ipcRenderer.send("shuffleModeDidChange", MusicKit.getInstance().shuffleMode); + }); + /* MusicKit.Events.repeatModeDidChange */ + MusicKit.getInstance().addEventListener(MusicKit.Events.repeatModeDidChange, () => { + global.ipcRenderer.send("repeatModeDidChange", MusicKit.getInstance().repeatMode); + }); + }, -process.once('loaded', () => { - console.log("Setting ipcRenderer") - global.MusicKitInterop = MusicKitInterop; + sleep(ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + }, + + async fetchSongRelationships({ id = this.getAttributes().songId, relationship = "primaryName" } = {}) { + if (!id) return null; + const res = await MusicKit.getInstance().api.v3.music("/v1/catalog/" + MusicKit.getInstance().storefrontId + `/songs/${id}`, { + include: { + songs: ["artists"], + }, + }); + + if (!res || !res.data) { + console.warn("[cider:preload] fetchSongRelationships: no response"); + if (id === this.getAttributes().songId) { + return this.getAttributes().artistName; + } + } + if (!res.data.data.length) { + console.error(`[cider:preload] fetchSongRelationships: Unable to locate song with id of ${id}`); + if (id === this.getAttributes().songId) { + return this.getAttributes().artistName; + } + } + + const songData = res.data.data[0]; + const artistData = songData.relationships.artists.data; + const albumData = songData.relationships.albums.data; + const primaryArtist = artistData[0]; + + switch (relationship) { + default: + case "primaryName": + if (artistData.length < 1) { + console.error(`[cider:preload] fetchSongRelationships: Unable to find artists related to the song with id of ${id}`); + return app.mk.nowPlayingItem.attributes.artistName; + } + return primaryArtist.attributes.name; + + case "primaryArtist": + return primaryArtist; + + case "album": + return albumData[0]; + } + }, + + getAttributes: function () { + const mk = MusicKit.getInstance(); + const nowPlayingItem = mk.nowPlayingItem; + const isPlayingExport = mk.isPlaying; + const remainingTimeExport = mk.currentPlaybackTimeRemaining; + const currentPlaybackProgress = mk.currentPlaybackProgress; + const attributes = nowPlayingItem != null ? nowPlayingItem.attributes : {}; + + attributes.songId = attributes.songId ?? attributes.playParams?.catalogId ?? attributes.playParams?.id; + attributes.kind = nowPlayingItem?.type ?? attributes?.type ?? attributes.playParams?.kind ?? ""; + attributes.status = nowPlayingItem == null ? null : !!isPlayingExport; + attributes.name = attributes?.name ?? "no-title-found"; + attributes.artwork = attributes?.artwork ?? { url: "" }; + attributes.artwork.url = (attributes?.artwork?.url ?? "").replace(`{f}`, "png"); + attributes.playParams = attributes?.playParams ?? { id: "no-id-found" }; + attributes.playParams.id = attributes?.playParams?.id ?? "no-id-found"; + attributes.url = { + cider: `https://cider.sh/link?play/s/${nowPlayingItem?._songId ?? nowPlayingItem?.songId ?? "no-id-found"}`, + appleMusic: attributes.websiteUrl ? attributes.websiteUrl : `https://music.apple.com/${mk.storefrontId}/song/${nowPlayingItem?._songId ?? nowPlayingItem?.songId ?? "no-id-found"}`, + songLink: "https://song.link/i/" + attributes.songId, + }; + if (attributes.playParams.id === "no-id-found") { + attributes.playParams.id = nowPlayingItem?.id ?? "no-id-found"; + } + attributes.albumName = attributes?.albumName ?? ""; + attributes.artistName = attributes?.artistName ?? ""; + attributes.genreNames = attributes?.genreNames ?? []; + attributes.remainingTime = remainingTimeExport ? remainingTimeExport * 1000 : 0; + attributes.durationInMillis = attributes?.durationInMillis ?? 0; + attributes.currentPlaybackTime = mk?.currentPlaybackTime ?? 0; + attributes.currentPlaybackProgress = currentPlaybackProgress ?? 0; + attributes.startTime = Date.now(); + attributes.endTime = Math.round(attributes?.playParams?.id === cache.playParams.id ? Date.now() + attributes?.remainingTime : attributes?.startTime + attributes?.durationInMillis); + + if (attributes.name === "no-title-found") { + return; + } + return attributes; + }, + + filterTrack: function (a, playbackCheck, mediaCheck) { + if (a.name === "no-title-found" || a.playParams.id === "no-id-found") { + return; + } else if (mediaCheck && a.playParams.id === cache.playParams.id) { + return; + } else if (playbackCheck && a.status === playbackCache.status) { + return; + } else if (playbackCheck && !a.status && a.remainingTime === playbackCache.time) { + /* Pretty much have to do this to prevent multiple runs when a song starts playing */ + return; + } + cache = a; + if (playbackCheck) playbackCache = { status: a.status, time: a.remainingTime }; + return true; + }, + + play: () => { + MusicKit.getInstance().play().catch(console.error); + }, + + pause: () => { + MusicKit.getInstance().pause(); + }, + + playPause: () => { + if (MusicKit.getInstance().isPlaying) { + MusicKit.getInstance().pause(); + } else if (MusicKit.getInstance().nowPlayingItem != null) { + MusicKit.getInstance().play().catch(console.error); + } + }, + + next: () => { + if (app) { + app.skipToNextItem(); + } else { + MusicKit.getInstance() + .skipToNextItem() + .then((r) => console.debug(`[cider:preload] [next] Skipping to Next ${r}`)); + } + }, + + previous: () => { + if (app) { + app.skipToPreviousItem(); + } else { + MusicKit.getInstance() + .skipToPreviousItem() + .then((r) => console.debug(`[cider:preload] [previous] Skipping to Previous ${r}`)); + } + }, + + initMediaSession: () => { + if ("mediaSession" in navigator) { + console.debug("[cider:preload] [initMediaSession] Media Session API supported"); + navigator.mediaSession.setActionHandler("play", () => { + MusicKitInterop.play(); + }); + navigator.mediaSession.setActionHandler("pause", () => { + MusicKitInterop.pause(); + }); + navigator.mediaSession.setActionHandler("stop", () => { + MusicKit.getInstance().stop(); + }); + navigator.mediaSession.setActionHandler("seekbackward", (details) => { + if (details.seekOffset) { + MusicKit.getInstance().seekToTime(Math.max(MusicKit.getInstance().currentPlaybackTime - details.seekOffset, 0)); + } else { + MusicKit.getInstance().seekBackward(); + } + }); + navigator.mediaSession.setActionHandler("seekforward", (details) => { + if (details.seekOffset) { + MusicKit.getInstance().seekToTime(Math.max(MusicKit.getInstance().currentPlaybackTime + details.seekOffset, 0)); + } else { + MusicKit.getInstance().seekForward(); + } + }); + navigator.mediaSession.setActionHandler("seekto", ({ seekTime, fastSeek }) => { + MusicKit.getInstance().seekToTime(seekTime); + }); + navigator.mediaSession.setActionHandler("previoustrack", () => { + MusicKitInterop.previous(); + }); + navigator.mediaSession.setActionHandler("nexttrack", () => { + MusicKitInterop.next(); + }); + } else { + console.debug("[cider:preload] [initMediaSession] Media Session API not supported"); + } + }, + + updateMediaSession: (a) => { + if ("mediaSession" in navigator) { + navigator.mediaSession.metadata = new MediaMetadata({ + title: a.name, + artist: a.artistName, + album: a.albumName, + artwork: [ + { + src: a.artwork.url.replace("/{w}x{h}bb", "/96x96bb").replace("/2000x2000bb", "/35x35bb"), + sizes: "96x96", + type: "image/jpeg", + }, + { + src: a.artwork.url.replace("/{w}x{h}bb", "/128x128bb").replace("/2000x2000bb", "/35x35bb"), + sizes: "128x128", + type: "image/jpeg", + }, + { + src: a.artwork.url.replace("/{w}x{h}bb", "/192x192bb").replace("/2000x2000bb", "/35x35bb"), + sizes: "192x192", + type: "image/jpeg", + }, + { + src: a.artwork.url.replace("/{w}x{h}bb", "/256x256bb").replace("/2000x2000bb", "/35x35bb"), + sizes: "256x256", + type: "image/jpeg", + }, + { + src: a.artwork.url.replace("/{w}x{h}bb", "/384x384bb").replace("/2000x2000bb", "/35x35bb"), + sizes: "384x384", + type: "image/jpeg", + }, + { + src: a.artwork.url.replace("/{w}x{h}bb", "/512x512bb").replace("/2000x2000bb", "/35x35bb"), + sizes: "512x512", + type: "image/jpeg", + }, + ], + }); + } + }, + + updateMediaState: (a) => { + if ("mediaSession" in navigator) { + console.debug("[cider:preload] [updateMediaState] Updating Media State to " + a.status); + switch (a.status) { + default: + case null: + navigator.mediaSession.playbackState = "none"; + break; + + case false: + navigator.mediaSession.playbackState = "paused"; + break; + + case true: + navigator.mediaSession.playbackState = "playing"; + break; + } + } + }, + + updatePositionState: (a) => { + if ("mediaSession" in navigator && a.currentPlaybackTime <= a.durationInMillis / 1000 && a.currentPlaybackTime >= 0) { + navigator.mediaSession.setPositionState({ + duration: a.durationInMillis / 1000, + playbackRate: app?.cfg?.audio?.playbackRate ?? 1, + position: a.currentPlaybackTime, + }); + } + }, +}; + +process.once("loaded", () => { + console.debug("[cider:preload] IPC Listeners Created!"); + global.MusicKitInterop = MusicKitInterop; }); diff --git a/src/renderer/.jsbeautifyrc b/src/renderer/.jsbeautifyrc deleted file mode 100644 index bde13199..00000000 --- a/src/renderer/.jsbeautifyrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "js": { - "beautify.ignore": "src/renderer/index.js" - } -} \ No newline at end of file diff --git a/src/renderer/AppHeader.svg b/src/renderer/AppHeader.svg deleted file mode 100644 index d6a7b723..00000000 --- a/src/renderer/AppHeader.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/renderer/ameframework.css b/src/renderer/ameframework.css deleted file mode 100644 index 38c56508..00000000 --- a/src/renderer/ameframework.css +++ /dev/null @@ -1,1002 +0,0 @@ -:root { - --appleEase: cubic-bezier(.42, 0, .58, 1); - --appleTransition: .2s var(--appleEase); -} - -/* Simple CSS framework for Apple Music Electron */ - -.md-labeltext { - font-size: 14px; - text-transform: uppercase; - opacity: 0.75; - font-weight: 500; -} - -.md-option-container { - /* border-radius: 10px; */ - overflow: hidden; -} - -.md-option-line { - display: flex; - width: 100%; - padding: 14px; - background: var(--opaquePageBGColor); - font-size: 0.85em; -} - -.md-option-segment.md-option-segment_auto { - width: auto; - white-space: nowrap; -} - -.md-option-container .md-option-line:not(:last-child) { - border-bottom: 1px solid rgb(0 0 0 / 15%); -} - -input[type="range"].md-slider { - -webkit-appearance: none; - height: 7px; - background: rgba(255, 255, 255, 0.6); - border-radius: 5px; - background-size: 70% 100%; - background-repeat: no-repeat; -} - -input[type="range"].md-slider::-webkit-slider-thumb { - -webkit-appearance: none; - height: 20px; - width: 20px; - border-radius: 50%; - background: rgb(255 255 255); - cursor: ew-resize; - box-shadow: 0 0 2px 0 #555; -} - -input[type=range].md-slider::-webkit-slider-runnable-track { - -webkit-appearance: none; - box-shadow: none; - border: none; - background: transparent; -} - -.md-option-header { - padding: 10px; - border-bottom: 1px solid rgb(200 200 200 / 25%); - font-weight: 500; - font-size: 0.9em; - background: rgb(255 255 255 / 10%); -} - -.md-option-segment { - width: 100%; - display: flex; - justify-content: center; - flex-direction: column; -} - -.md-h1 { - font-size: 3em; - text-align: center; -} - -.md-header { - padding: 16px; -} - -.md-header-title { - padding: 18px; - font-weight: 600; - font-size: 16px; - height: 55px; - background: var(--opaquePageBGColor); - border-bottom: 1px solid rgb(0 0 0 / 15%); -} - -.md-footer { - padding: 16px; - text-align: center; -} - - - - -.md-transparent { - background: transparent; -} - -.md-container { - display: flex; - flex-direction: column; - height: 100%; - position: absolute; - top: 0px; - left: 0px; - width: 100%; - padding: 32px; -} - -.md-container_panel { - padding: 0px; -} - -.md-body { - height: 100%; - padding: 16px; - font-size: 1.25em; -} - -@media (prefers-color-scheme: light) { - .md-btn { - box-shadow: rgb(0 0 0 / 10%) 0px 0px 1px, rgb(0 0 0 / 20%) 0px 1px 1px; - border: 1px solid rgb(0 0 0 / 15%); - } - - .md-close-btn { - background-color: #000; - } -} - -/* Vue transitions */ -.fade_simple-enter-active, .fade_simple-leave-active { - transition: all .5s; -} - -.fade_simple-enter, .fade_simple-leave-to { - opacity: 0; -} - -.fade-enter-active, .fade-leave-active { - transition: all .5s; -} - -.fade-enter, .fade-leave-to { - opacity: 0; - transform: scale(0.95); -} - -/* CSS Grids */ - -.container, -.container-fluid, -.container-xxl, -.container-xl, -.container-lg, -.container-md, -.container-sm { - width: 100%; - padding-right: var(--bs-gutter-x, 0.75rem); - padding-left: var(--bs-gutter-x, 0.75rem); - margin-right: auto; - margin-left: auto; -} - -.row { - --bs-gutter-x: 1.5rem; - --bs-gutter-y: 0; - display: flex; - flex-wrap: wrap; - /*margin-top: calc(-1 * var(--bs-gutter-y));*/ - /*margin-right: calc(-0.5 * var(--bs-gutter-x));*/ - /*margin-left: calc(-0.5 * var(--bs-gutter-x));*/ -} - -.row > * { - box-sizing: border-box; - flex-shrink: 0; - width: 100%; - max-width: 100%; - padding-right: calc(var(--bs-gutter-x) * 0.5); - padding-left: calc(var(--bs-gutter-x) * 0.5); - margin-top: var(--bs-gutter-y); -} - -.col { - flex: 1 0 0%; -} - -.row-cols-auto > * { - flex: 0 0 auto; - width: auto; -} - -.row-cols-1 > * { - flex: 0 0 auto; - width: 100%; -} - -.row-cols-2 > * { - flex: 0 0 auto; - width: 50%; -} - -.row-cols-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; -} - -.row-cols-4 > * { - flex: 0 0 auto; - width: 25%; -} - -.row-cols-5 > * { - flex: 0 0 auto; - width: 20%; -} - -.row-cols-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; -} - -.col-auto { - flex: 0 0 auto; - width: auto; -} - -.col-1 { - flex: 0 0 auto; - width: 8.33333333%; -} - -.col-2 { - flex: 0 0 auto; - width: 16.66666667%; -} - -.col-3 { - flex: 0 0 auto; - width: 25%; -} - -.col-4 { - flex: 0 0 auto; - width: 33.33333333%; -} - -.col-5 { - flex: 0 0 auto; - width: 41.66666667%; -} - -.col-6 { - flex: 0 0 auto; - width: 50%; -} - -.col-7 { - flex: 0 0 auto; - width: 58.33333333%; -} - -.col-8 { - flex: 0 0 auto; - width: 66.66666667%; -} - -.col-9 { - flex: 0 0 auto; - width: 75%; -} - -.col-10 { - flex: 0 0 auto; - width: 83.33333333%; -} - -.col-11 { - flex: 0 0 auto; - width: 91.66666667%; -} - -.col-12 { - flex: 0 0 auto; - width: 100%; -} - -.offset-1 { - margin-left: 8.33333333%; -} - -.offset-2 { - margin-left: 16.66666667%; -} - -.offset-3 { - margin-left: 25%; -} - -.offset-4 { - margin-left: 33.33333333%; -} - -.offset-5 { - margin-left: 41.66666667%; -} - -.offset-6 { - margin-left: 50%; -} - -.offset-7 { - margin-left: 58.33333333%; -} - -.offset-8 { - margin-left: 66.66666667%; -} - -.offset-9 { - margin-left: 75%; -} - -.offset-10 { - margin-left: 83.33333333%; -} - -.offset-11 { - margin-left: 91.66666667%; -} - -.g-0, -.gx-0 { - --bs-gutter-x: 0; -} - -.g-0, -.gy-0 { - --bs-gutter-y: 0; -} - -.g-1, -.gx-1 { - --bs-gutter-x: 0.25rem; -} - -.g-1, -.gy-1 { - --bs-gutter-y: 0.25rem; -} - -.g-2, -.gx-2 { - --bs-gutter-x: 0.5rem; -} - -.g-2, -.gy-2 { - --bs-gutter-y: 0.5rem; -} - -.g-3, -.gx-3 { - --bs-gutter-x: 1rem; -} - -.g-3, -.gy-3 { - --bs-gutter-y: 1rem; -} - -.g-4, -.gx-4 { - --bs-gutter-x: 1.5rem; -} - -.g-4, -.gy-4 { - --bs-gutter-y: 1.5rem; -} - -.g-5, -.gx-5 { - --bs-gutter-x: 3rem; -} - -.g-5, -.gy-5 { - --bs-gutter-y: 3rem; -} - -.d-inline { - display: inline !important; -} - -.d-inline-block { - display: inline-block !important; -} - -.d-block { - display: block !important; -} - -.d-grid { - display: grid !important; -} - -.d-table { - display: table !important; -} - -.d-table-row { - display: table-row !important; -} - -.d-table-cell { - display: table-cell !important; -} - -.d-flex { - display: flex !important; -} - -.d-inline-flex { - display: inline-flex !important; -} - -.d-none { - display: none !important; -} - -.flex-fill { - flex: 1 1 auto !important; -} - -.flex-row { - flex-direction: row !important; -} - -.flex-column { - flex-direction: column !important; -} - -.flex-row-reverse { - flex-direction: row-reverse !important; -} - -.flex-column-reverse { - flex-direction: column-reverse !important; -} - -.flex-grow-0 { - flex-grow: 0 !important; -} - -.flex-grow-1 { - flex-grow: 1 !important; -} - -.flex-shrink-0 { - flex-shrink: 0 !important; -} - -.flex-shrink-1 { - flex-shrink: 1 !important; -} - -.flex-wrap { - flex-wrap: wrap !important; -} - -.flex-nowrap { - flex-wrap: nowrap !important; -} - -.flex-wrap-reverse { - flex-wrap: wrap-reverse !important; -} - -.justify-content-start { - justify-content: flex-start !important; -} - -.justify-content-end { - justify-content: flex-end !important; -} - -.justify-content-center { - justify-content: center !important; -} - -.justify-content-between { - justify-content: space-between !important; -} - -.justify-content-around { - justify-content: space-around !important; -} - -.justify-content-evenly { - justify-content: space-evenly !important; -} - -.align-items-start { - align-items: flex-start !important; -} - -.align-items-end { - align-items: flex-end !important; -} - -.align-items-center { - align-items: center !important; -} - -.align-items-baseline { - align-items: baseline !important; -} - -.align-items-stretch { - align-items: stretch !important; -} - -.align-content-start { - align-content: flex-start !important; -} - -.align-content-end { - align-content: flex-end !important; -} - -.align-content-center { - align-content: center !important; -} - -.align-content-between { - align-content: space-between !important; -} - -.align-content-around { - align-content: space-around !important; -} - -.align-content-stretch { - align-content: stretch !important; -} - -.align-self-auto { - align-self: auto !important; -} - -.align-self-start { - align-self: flex-start !important; -} - -.align-self-end { - align-self: flex-end !important; -} - -.align-self-center { - align-self: center !important; -} - -.align-self-baseline { - align-self: baseline !important; -} - -.align-self-stretch { - align-self: stretch !important; -} - -.order-first { - order: -1 !important; -} - -.order-0 { - order: 0 !important; -} - -.order-1 { - order: 1 !important; -} - -.order-2 { - order: 2 !important; -} - -.order-3 { - order: 3 !important; -} - -.order-4 { - order: 4 !important; -} - -.order-5 { - order: 5 !important; -} - -.order-last { - order: 6 !important; -} - -.m-0 { - margin: 0 !important; -} - -.m-1 { - margin: 0.25rem !important; -} - -.m-2 { - margin: 0.5rem !important; -} - -.m-3 { - margin: 1rem !important; -} - -.m-4 { - margin: 1.5rem !important; -} - -.m-5 { - margin: 3rem !important; -} - -.m-auto { - margin: auto !important; -} - -.mx-0 { - margin-right: 0 !important; - margin-left: 0 !important; -} - -.mx-1 { - margin-right: 0.25rem !important; - margin-left: 0.25rem !important; -} - -.mx-2 { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; -} - -.mx-3 { - margin-right: 1rem !important; - margin-left: 1rem !important; -} - -.mx-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; -} - -.mx-5 { - margin-right: 3rem !important; - margin-left: 3rem !important; -} - -.mx-auto { - margin-right: auto !important; - margin-left: auto !important; -} - -.my-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -.my-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; -} - -.my-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; -} - -.my-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; -} - -.my-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; -} - -.my-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; -} - -.my-auto { - margin-top: auto !important; - margin-bottom: auto !important; -} - -.mt-0 { - margin-top: 0 !important; -} - -.mt-1 { - margin-top: 0.25rem !important; -} - -.mt-2 { - margin-top: 0.5rem !important; -} - -.mt-3 { - margin-top: 1rem !important; -} - -.mt-4 { - margin-top: 1.5rem !important; -} - -.mt-5 { - margin-top: 3rem !important; -} - -.mt-auto { - margin-top: auto !important; -} - -.me-0 { - margin-right: 0 !important; -} - -.me-1 { - margin-right: 0.25rem !important; -} - -.me-2 { - margin-right: 0.5rem !important; -} - -.me-3 { - margin-right: 1rem !important; -} - -.me-4 { - margin-right: 1.5rem !important; -} - -.me-5 { - margin-right: 3rem !important; -} - -.me-auto { - margin-right: auto !important; -} - -.mb-0 { - margin-bottom: 0 !important; -} - -.mb-1 { - margin-bottom: 0.25rem !important; -} - -.mb-2 { - margin-bottom: 0.5rem !important; -} - -.mb-3 { - margin-bottom: 1rem !important; -} - -.mb-4 { - margin-bottom: 1.5rem !important; -} - -.mb-5 { - margin-bottom: 3rem !important; -} - -.mb-auto { - margin-bottom: auto !important; -} - -.ms-0 { - margin-left: 0 !important; -} - -.ms-1 { - margin-left: 0.25rem !important; -} - -.ms-2 { - margin-left: 0.5rem !important; -} - -.ms-3 { - margin-left: 1rem !important; -} - -.ms-4 { - margin-left: 1.5rem !important; -} - -.ms-5 { - margin-left: 3rem !important; -} - -.ms-auto { - margin-left: auto !important; -} - -.p-0 { - padding: 0 !important; -} - -.p-1 { - padding: 0.25rem !important; -} - -.p-2 { - padding: 0.5rem !important; -} - -.p-3 { - padding: 1rem !important; -} - -.p-4 { - padding: 1.5rem !important; -} - -.p-5 { - padding: 3rem !important; -} - -.px-0 { - padding-right: 0 !important; - padding-left: 0 !important; -} - -.px-1 { - padding-right: 0.25rem !important; - padding-left: 0.25rem !important; -} - -.px-2 { - padding-right: 0.5rem !important; - padding-left: 0.5rem !important; -} - -.px-3 { - padding-right: 1rem !important; - padding-left: 1rem !important; -} - -.px-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; -} - -.px-5 { - padding-right: 3rem !important; - padding-left: 3rem !important; -} - -.py-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; -} - -.py-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; -} - -.py-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; -} - -.py-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; -} - -.py-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; -} - -.py-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; -} - -.pt-0 { - padding-top: 0 !important; -} - -.pt-1 { - padding-top: 0.25rem !important; -} - -.pt-2 { - padding-top: 0.5rem !important; -} - -.pt-3 { - padding-top: 1rem !important; -} - -.pt-4 { - padding-top: 1.5rem !important; -} - -.pt-5 { - padding-top: 3rem !important; -} - -.pe-0 { - padding-right: 0 !important; -} - -.pe-1 { - padding-right: 0.25rem !important; -} - -.pe-2 { - padding-right: 0.5rem !important; -} - -.pe-3 { - padding-right: 1rem !important; -} - -.pe-4 { - padding-right: 1.5rem !important; -} - -.pe-5 { - padding-right: 3rem !important; -} - -.pb-0 { - padding-bottom: 0 !important; -} - -.pb-1 { - padding-bottom: 0.25rem !important; -} - -.pb-2 { - padding-bottom: 0.5rem !important; -} - -.pb-3 { - padding-bottom: 1rem !important; -} - -.pb-4 { - padding-bottom: 1.5rem !important; -} - -.pb-5 { - padding-bottom: 3rem !important; -} - -.ps-0 { - padding-left: 0 !important; -} - -.ps-1 { - padding-left: 0.25rem !important; -} - -.ps-2 { - padding-left: 0.5rem !important; -} - -.ps-3 { - padding-left: 1rem !important; -} - -.ps-4 { - padding-left: 1.5rem !important; -} - -.ps-5 { - padding-left: 3rem !important; -} \ No newline at end of file diff --git a/src/renderer/apple-hls-old.js b/src/renderer/apple-hls-old.js new file mode 100644 index 00000000..fbbc38fc --- /dev/null +++ b/src/renderer/apple-hls-old.js @@ -0,0 +1,25453 @@ +/*! For license information please see hls.js.LICENSE.txt */ ! function Xy(Yy) { + const Jy = this; + var e, t; + e = this, t = function() { + "use strict"; + var P, e = e => e && e.Math === Math && e, + l = e("object" == typeof globalThis && globalThis) || e("object" == typeof window && window) || e("object" == typeof Jy && Jy) || e("object" == typeof global && global) || Function("return this")(); + class d { + constructor() { + this.keySize = null, this.ksRows = null, this.keySchedule = null, this.invKeySchedule = null, this.rcon = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54], this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)], this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)], this.sBox = new Uint32Array(256), this.invSBox = new Uint32Array(256), this.key = new Uint32Array(0), this.initTable() + } + uint8ArrayToUint32Array_(e) { + const t = new DataView(e), + i = Math.floor(t.byteLength / 4), + r = new Uint32Array(i); + for (let e = 0; e < i; e++) r[e] = t.getUint32(4 * e); + return r + } + initTable() { + const e = this["sBox"], + t = this["invSBox"], + i = this["subMix"], + r = i[0], + n = i[1], + s = i[2], + a = i[3], + o = this["invSubMix"], + l = o[0], + d = o[1], + u = o[2], + c = o[3], + h = new Uint32Array(256); + let p = 0, + f = 0, + m = 0; + for (m = 0; m < 256; m++) h[m] = m < 128 ? m << 1 : m << 1 ^ 283; + for (m = 0; m < 256; m++) { + var g = (g = f ^ f << 1 ^ f << 2 ^ f << 3 ^ f << 4) >>> 8 ^ 255 & g ^ 99; + e[p] = g, t[g] = p; + const o = h[p], + m = h[o], + v = h[m]; + var y = 257 * h[g] ^ 16843008 * g; + r[p] = y << 24 | y >>> 8, n[p] = y << 16 | y >>> 16, s[p] = y << 8 | y >>> 24, a[p] = y, y = 16843009 * v ^ 65537 * m ^ 257 * o ^ 16843008 * p, l[g] = y << 24 | y >>> 8, d[g] = y << 16 | y >>> 16, u[g] = y << 8 | y >>> 24, c[g] = y, p ? (p = o ^ h[h[h[v ^ o]]], f ^= h[h[f]]) : p = f = 1 + } + } + expandKey(e) { + var n = this.uint8ArrayToUint32Array_(e); + let t = !0, + i = 0; + for (; i < n.length && t;) t = n[i] === this.key[i], i++; + if (!t) { + this.key = n; + var s = this.keySize = n.length; + if (4 !== s && 6 !== s && 8 !== s) throw new Error("Invalid aes key size=" + s); + var a = this.ksRows = 4 * (s + 6 + 1); + let e, t; + const o = this.keySchedule = new Uint32Array(a), + l = this.invKeySchedule = new Uint32Array(a), + d = this.sBox, + u = this["rcon"], + c = this["invSubMix"], + h = c[0], + p = c[1], + f = c[2], + m = c[3]; + let i, r; + for (e = 0; e < a; e++) e < s ? i = o[e] = n[e] : (r = i, e % s == 0 ? (r = r << 8 | r >>> 24, r = d[r >>> 24] << 24 | d[r >>> 16 & 255] << 16 | d[r >>> 8 & 255] << 8 | d[255 & r], r ^= u[e / s | 0] << 24) : 6 < s && e % s == 4 && (r = d[r >>> 24] << 24 | d[r >>> 16 & 255] << 16 | d[r >>> 8 & 255] << 8 | d[255 & r]), o[e] = i = (o[e - s] ^ r) >>> 0); + for (t = 0; t < a; t++) e = a - t, r = 3 & t ? o[e] : o[e - 4], l[t] = t < 4 || e <= 4 ? r : h[d[r >>> 24]] ^ p[d[r >>> 16 & 255]] ^ f[d[r >>> 8 & 255]] ^ m[d[255 & r]], l[t] = l[t] >>> 0 + } + } + networkToHostOrderSwap(e) { + return e << 24 | (65280 & e) << 8 | (16711680 & e) >> 8 | e >>> 24 + } + decrypt(e, t, i) { + var r = this.keySize + 6, + n = this["invKeySchedule"], + s = this.invSBox, + a = this["invSubMix"], + o = a[0], + l = a[1], + d = a[2], + u = a[3], + i = this.uint8ArrayToUint32Array_(i); + let c = i[0], + h = i[1], + p = i[2], + f = i[3]; + const m = new Int32Array(e), + g = new Int32Array(m.length); + let y, v, S, b, T, E, I, w, A, O, k, C, D, M; + const x = this.networkToHostOrderSwap; + for (; t < m.length;) { + for (A = x(m[t]), O = x(m[t + 1]), k = x(m[t + 2]), C = x(m[t + 3]), T = A ^ n[0], E = C ^ n[1], I = k ^ n[2], w = O ^ n[3], D = 4, M = 1; M < r; M++) y = o[T >>> 24] ^ l[E >> 16 & 255] ^ d[I >> 8 & 255] ^ u[255 & w] ^ n[D], v = o[E >>> 24] ^ l[I >> 16 & 255] ^ d[w >> 8 & 255] ^ u[255 & T] ^ n[D + 1], S = o[I >>> 24] ^ l[w >> 16 & 255] ^ d[T >> 8 & 255] ^ u[255 & E] ^ n[D + 2], b = o[w >>> 24] ^ l[T >> 16 & 255] ^ d[E >> 8 & 255] ^ u[255 & I] ^ n[D + 3], T = y, E = v, I = S, w = b, D += 4; + y = s[T >>> 24] << 24 ^ s[E >> 16 & 255] << 16 ^ s[I >> 8 & 255] << 8 ^ s[255 & w] ^ n[D], v = s[E >>> 24] << 24 ^ s[I >> 16 & 255] << 16 ^ s[w >> 8 & 255] << 8 ^ s[255 & T] ^ n[D + 1], S = s[I >>> 24] << 24 ^ s[w >> 16 & 255] << 16 ^ s[T >> 8 & 255] << 8 ^ s[255 & E] ^ n[D + 2], b = s[w >>> 24] << 24 ^ s[T >> 16 & 255] << 16 ^ s[E >> 8 & 255] << 8 ^ s[255 & I] ^ n[D + 3], D += 3, g[t] = x(y ^ c), g[t + 1] = x(b ^ h), g[t + 2] = x(S ^ p), g[t + 3] = x(v ^ f), c = A, h = O, p = k, f = C, t += 4 + } + return g.buffer + } + destroy() { + this.key = void 0, this.keySize = void 0, this.ksRows = void 0, this.sBox = void 0, this.invSBox = void 0, this.subMix = void 0, this.invSubMix = void 0, this.keySchedule = void 0, this.invKeySchedule = void 0, this.rcon = void 0 + } + } + class i { + constructor(e, t) { + this.rpc = e, this.logger = t, this.decrypt = (r, n, s, a, o) => t => { + const i = l.crypto; + if (null != o && o.useJSCrypto || null == i || !i.subtle) { + const s = new d; + var e; + s.expandKey(r); + const i = s.decrypt(a, 0, n); + e = o.plainTextLength ? i.slice(0, o.plainTextLength) : function(e) { + var t = new Uint8Array(e), + i = t[e.byteLength - 1], + r = e.byteLength - 1; + let n = 0; + if (1 <= i && i <= 16) + for (let e = r; e > r - i && t[e] === i; e--) n++; + return e = n === i ? e.slice(0, r - i + 1) : e + }(i), t(e, void 0, [e]) + } else i.subtle.importKey("raw", r, s, !1, ["decrypt"]).then(e => i.subtle.decrypt({ + name: s, + iv: n + }, e, a)).then(e => { + t(e, void 0, [e]) + }).catch(e => t(void 0, e)) + }, e.register("decrypt", this.decrypt) + } + }(vr = P = P || {}).MEDIA_ATTACHING = "hlsMediaAttaching", vr.MEDIA_ATTACHED = "hlsMediaAttached", vr.MEDIA_DETACHING = "hlsMediaDetaching", vr.MEDIA_DETACHED = "hlsMediaDetached", vr.BUFFER_CREATED = "hlsBufferCreated", vr.BUFFER_APPENDING = "hlsBufferAppending", vr.BUFFER_APPENDED = "hlsBufferAppended", vr.BUFFER_FLUSHED = "hlsBufferFlushed", vr.MANIFEST_LOADING = "hlsManifestLoading", vr.MANIFEST_LOADED = "hlsManifestLoaded", vr.MANIFEST_PARSED = "hlsManifestParsed", vr.LEVEL_SWITCHING = "hlsLevelSwitching", vr.LEVEL_SWITCHED = "hlsLevelSwitched", vr.LEVEL_LOADING = "hlsLevelLoading", vr.LEVEL_LOADED = "hlsLevelLoaded", vr.LEVEL_UPDATED = "hlsLevelUpdated", vr.LEVELS_CHANGED = "hlsLevelsChanged", vr.AUDIO_TRACKS_UPDATED = "hlsAudioTracksUpdated", vr.AUDIO_TRACK_SWITCH = "hlsAudioTrackSwitch", vr.AUDIO_TRACK_SWITCHED = "hlsAudioTrackSwitched", vr.AUDIO_TRACK_LOADED = "hlsAudioTrackLoaded", vr.SUBTITLE_TRACKS_UPDATED = "hlsSubtitleTracksUpdated", vr.SUBTITLE_TRACKS_CREATED = "hlsSubtitleTracksCreated", vr.SUBTITLE_TRACK_SWITCH = "hlsSubtitleTrackSwitch", vr.INLINE_STYLES_PARSED = "hlsInlineStylesParsed", vr.SESSION_DATA_COMPLETE = "hlsSessionDataComplete", vr.FRAG_LOADING = "hlsFragLoading", vr.FRAG_LOADED = "hlsFragLoaded", vr.FRAG_BUFFERED = "hlsFragBuffered", vr.FRAG_CHANGED = "hlsFragChanged", vr.INTERNAL_ERROR = "hlsInternalError", vr.ERROR = "hlsError", vr.DESTROYING = "hlsDestroying", vr.KEY_REQUEST_STARTED = "hlsKeyRequestStarted", vr.LICENSE_CHALLENGE_CREATED = "hlsLicenseChallengeCreated", vr.LICENSE_RELEASED = "hlsLicenseReleased", vr.KEY_LOADED = "hlsKeyLoaded", vr.UNRESOLVED_URI_LOADING = "hlsUnresolvedUriLoading", vr.DESIRED_RATE_CHANGED = "hlsDesiredRateChanged", vr.PLAYER_STATE_CHANGE = "hlsPlayerStateChange", vr.SEEKING = "hlsSeeking", vr.SEEKED = "hlsSeeked", vr.STALLED = "hlsStalled", vr.RESUME_FROM_STALL = "hlsResumeFromStall", vr.READY_FOR_NEXT_ITEM = "hlsReadyForNextItem", vr.ITEM_TRANSITIONED = "hlsItemTransitioned", vr.ITEM_EVICTED = "hlsItemEvicted", vr.DATERANGE_UPDATED = "hlsDaterangeUpdated"; + var v, x = P; + (dl = v = v || {}).FRAG_PARSING_INIT_SEGMENT = "hlsFragParsingInitSegment", dl.FRAG_PARSING_DATA = "hlsFragParsingData", dl.FRAG_PARSED = "hlsFragParsed", dl.INIT_PTS_FOUND = "hlsInitPtsFound"; + class p extends Error { + constructor(e, t, i, r, n) { + super(r), this.type = e, this.details = t, this.fatal = i, this.reason = r, this.response = n, this.handled = !1 + } + } + class R extends p { + constructor(e, t, i, r, n) { + super(e, t, i, r, n), this.response = n + } + } + const $ = { + PlaylistNotReceived: { + code: -12884, + text: "Playlist not received" + }, + CryptResponseReceivedSlowly: { + code: -16833, + text: "Crypt key received slowly" + }, + LivePlaylistUpdateError: { + code: -12888, + text: "Live playlist not updated" + }, + NoResponseFromMediaRequest: { + code: -12889, + text: "No response for fragment" + }, + IncompatibleAsset: { + code: -12927, + text: "IncompatibleAsset" + }, + CorruptStream: { + code: -16041, + text: "Corrupt fragment" + }, + InternalError: { + code: -12645, + text: "InternalException" + }, + CantSwitchInTime: { + code: -12644, + text: "CantSwitchInTime" + }, + VideoDecoderBadDataErr: { + code: -12909, + text: "Buffer error" + }, + InsufficientDataAvailable: { + code: -12928, + text: "Incomplete data" + }, + AllocationFailed: { + code: -12862, + text: "AllocationFailed" + }, + PlaylistErrorMissingEXTM3U: { + code: -12269, + text: "Response doesnt have #EXTM3U tag" + }, + PlaylistErrorInvalidEntry: { + code: -12264, + text: "Invalid entry" + }, + PlaylistErrorBadTargetDuration: { + code: -12271, + text: "Invalid targetduration" + }, + NoValidAlternates: { + code: -12925, + text: "No valid alternates" + }, + FormatError: { + code: -12642, + text: "Incorrect playlist format" + }, + UnsupportedKeySystemError: { + code: -6e4, + text: "Unsupported Key System" + }, + EmptyLoadSourceError: { + code: -60001, + text: "Empty loadSource url" + }, + UndefinedItemIdError: { + code: -60002, + text: "Undefined itemId" + }, + ManifestParseError: { + code: -60003, + text: "Manifest parse error" + }, + DemuxWorkerError: { + code: -60004, + text: "Demux worker error" + }, + DecryptWorkerError: { + code: -60005, + text: "Decrypt worker error" + }, + OutOfRangeSeekError: { + code: -60006, + text: "Seeked out of playable range" + }, + ExceptionInKeyLoadError: { + code: -60007, + text: "Exception in Key load" + }, + FragmentAbortError: { + code: -60008, + text: "Fragment abort error" + }, + ManifestTimeoutError: { + code: -60009, + text: "Manifest Timeout Error" + }, + PlaylistTimeoutError: { + code: -60010, + text: "Playlist Timeout Error" + }, + FragmentTimeoutError: { + code: -60011, + text: "Fragment Timeout Error" + }, + IncompleteSessionData: { + code: -60012, + text: "Session data not complete after loading all items" + }, + SessionDataLoadTimeout: { + code: -60013, + text: "Session data load timeout" + }, + FailedDemuxerSanityCheck: { + code: -60014, + text: "Failed demuxer sanity check" + }, + InvalidADTSSamplingIndex: { + code: -60015, + text: "Invalid ADTS sampling index" + }, + DemuxerNotFound: { + code: -60016, + text: "No demux matching with content found" + }, + InvalidAC3Magic: { + code: -60029, + text: "Invalid ac-3 magic" + }, + InvalidInitTimestamp: { + code: -60017, + text: "Invalid initPTS or initDTS" + }, + NoAVSamplesFound: { + code: -60018, + text: "no audio/video samples found" + }, + NoTSSyncByteFound: { + code: -60019, + text: "TS packet did not start with 0x47" + }, + PESDidNotStartWithADTS: { + code: -60020, + text: "AAC PES did not start with ADTS header" + }, + NoADTSHeaderInPES: { + code: -60021, + text: "No ADTS header found in AAC PES" + }, + InvalidDolbyAudioMagic: { + code: -60022, + text: "Invalid dolby audio magic" + }, + FailedToAllocateVideoMdat: { + code: -60023, + text: "Fail allocating video mdat" + }, + FailedToAllocateAudioMdat: { + code: -60024, + text: "Fail allocating audio mdat" + }, + InsufficientEC3Data: { + code: -60025, + text: "Error parsing ec-3, not enough data" + }, + InvalidEC3Magic: { + code: -60026, + text: "Invalid ec-3 magic" + }, + ReservedStreamType: { + code: -60027, + text: "Reserved stream type" + }, + InsufficientAC3Data: { + code: -60028, + text: "error parsing ac-3, not enough data" + }, + InvalidAC3SamplingRateCode: { + code: -60030, + text: "Invalid ac-3 samplingRateCode" + }, + PlaylistErrorInvalidEXTXDEFINE: { + code: -61e3, + text: "Encountered undefined/not imported EXT-X-DEFINE property" + }, + PlaylistErrorMissingImportReference: { + code: -61001, + text: "IMPORT references variable not in master playlist and/or NAME" + }, + PlaylistErrorInvalidSERVERURI: { + code: -61002, + text: "Encountered undefined/invalid SERVER-URI attribute for EXT-X-CONTENT-STEERING tag" + }, + PlaylistErrorInvalidPATHWAYID: { + code: -61003, + text: "Encountered invalid PATHWAY-ID attribute for EXT-X-CONTENT-STEERING tag" + }, + PlaylistErrorInvalidSCORE: { + code: -61004, + text: "Encountered negative/non-number SCORE property" + }, + KeySystemFailedToUpdateSession: { + code: -62e3, + text: "KeySystem: Promise Rejected while updating session" + }, + KeySystemFailedToGenerateLicenseRenewal: { + code: -62001, + text: "KeySystem: Failed to generate license renewal" + }, + KeySystemFailedToGenerateLicenseRequest: { + code: -62002, + text: "KeySystem: Failed to generate license request" + }, + KeySystemAbort: { + code: -62003, + text: "KeySystem: Aborted" + }, + KeySystemUnexpectedStateTransition: { + code: -62004, + text: "KeySystem: Unexpected state transition" + }, + KeySystemUnexpectedState: { + code: -62005, + text: "KeySystem: Unexpected state" + }, + KeySystemCDMUnknownError: { + code: -62006, + text: "KeySystem: Unknown error from CDM" + }, + KeySystemRequestTimedOut: { + code: -62007, + text: "Key request timed out" + }, + KeySystemUnexpectedMETHOD: { + code: -62008, + text: "Unexpected METHOD attribute" + }, + KeySystemUnmatchedString: { + code: -62009, + text: "KeySystem: string does not match" + }, + KeySystemInternalError: { + code: -62010, + text: "KeySystem: internal-error" + }, + KeySystemOutputRestricted: { + code: -62011, + text: "KeySystem: output-restricted" + }, + KeySystemSetupError: { + code: -62012, + text: "KeySystem: setup error" + }, + KeySystemFailedToInitialize: { + code: -62013, + text: "KeySystem: could not initialize" + }, + KeySystemFailedToCreateSession: { + code: -62014, + text: "KeySystem: could not create session" + }, + KeySystemUndefinedNavigator: { + code: -62015, + text: "KeySystem: navigator undefined" + }, + KeySystemNoKeySystemsToTry: { + code: -62016, + text: "KeySystem: no key systems to try" + }, + KeySystemNoConstructor: { + code: -62017, + text: "KeySystem: No constructor" + }, + KeySystemNoKeySystemAccess: { + code: -62018, + text: "KeySystem: No KeySystemAccess" + }, + KeySystemCertificateLoadError: { + code: -62019, + text: "KeySystem: Certificate Load Error" + } + }, + o = "networkError", + L = "mediaError", + s = "otherError", + _ = "manifestParsingError", + f = "manifestIncompatibleCodecsError", + N = "levelLoadError", + n = "bufferAppendError", + r = "internalException"; + class V extends p { + constructor(e, t, i) { + super(s, r, e, t, i) + } + } + class D extends p { + constructor(e, t, i) { + super(L, "fragParsingError", e, t, i) + } + } + class F extends p { + constructor(e, t, i, r) { + super("muxError", "remuxAllocError", e, t, i), this.bytes = r + } + } + + function S(e) { + return e.baseTime / e.timescale + } + + function B(e, t) { + return { + baseTime: Math.floor(e * t), + timescale: t + } + } + + function g(e, t) { + return S(e) < S(t) ? e : t + } + + function y(e, t) { + return S(e) > S(t) ? e : t + } + + function b(e, t) { + return S(e) - S(t) + } + var t = void 0 !== l.Buffer ? require("events").EventEmitter : class { + constructor() { + this.eventMap = {} + } + _on(e, t, i = !1) { + return null == this.eventMap[e] && (this.eventMap[e] = []), i ? this.eventMap[e].splice(0, 0, t) : this.eventMap[e].push(t), this + } + _off(e, t) { + return null != this.eventMap[e] && (this.eventMap[e] = this.eventMap[e].filter(e => e.listener !== t.listener), 0 === this.eventMap[e].length && delete this.eventMap[e]), this + } + on(e, t) { + return this._on(e, { + listener: t, + once: !1 + }) + } + off(e, t) { + return this._off(e, { + listener: t + }) + } + addListener(e, t) { + return this.on(e, t) + } + once(e, t) { + return this._on(e, { + listener: t, + once: !0 + }) + } + removeListener(e, t) { + return this.off(e, t) + } + removeAllListeners(e) { + return delete this.eventMap[e], this + } + setMaxListeners(e) { + return this + } + getMaxListeners() { + return 1 / 0 + } + listeners(e) { + return null == this.eventMap[e] ? [] : this.eventMap[e].map(e => e.listener) + } + rawListeners(e) { + return this.listeners(e) + } + emit(e, ...t) { + if (null == this.eventMap[e]) return !1; + let i = !1; + for (const r of this.eventMap[e]) { + try { + r.listener.apply(this, t) + } catch (e) {} + i = !0 + } + return i + } + listenerCount(e) { + return null == this.eventMap[e] ? 0 : this.eventMap[e].length + } + prependListener(e, t) { + return this._on(e, { + listener: t, + once: !1 + }, !0) + } + prependOnceListener(e, t) { + return this._on(e, { + listener: t, + once: !0 + }, !0) + } + eventNames() { + return Object.keys(this.eventMap) + } + }; + class a extends t { + trigger(e, t) { + this.emit(e, t) + } + } + + function E(e, t, i, r, n) { + let s, a, o, l; + const d = navigator.userAgent.toLowerCase(), + u = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350]; + s = 1 + ((192 & t[i + 2]) >>> 6); + var c = (60 & t[i + 2]) >>> 2; + if (!(u.length - 1 < c)) return o = (1 & t[i + 2]) << 2, o |= (192 & t[i + 3]) >>> 6, /firefox/i.test(d) ? 6 <= c ? (s = 5, l = new Array(4), a = c - 3) : (s = 2, l = new Array(2)) : -1 !== d.indexOf("android") ? (s = 2, l = new Array(2)) : (s = 5, l = new Array(4), a = r && (-1 !== r.indexOf("mp4a.40.29") || -1 !== r.indexOf("mp4a.40.5")) || !r && 6 <= c ? c - 3 : ((r && -1 !== r.indexOf("mp4a.40.2") || !r && 1 == o) && (s = 2, l = new Array(2)), c)), l[0] = s << 3, l[0] |= (14 & c) >> 1, l[1] |= (1 & c) << 7, l[1] |= o << 3, 5 === s && (l[1] |= (14 & a) >> 1, l[2] = (1 & a) << 7, l[2] |= 8, l[3] = 0), { + esdsConfig: l, + samplerate: u[c], + channelCount: o, + segmentCodec: "aac", + codec: "mp4a.40." + s + }; { + const t = new D(!0, `invalid ADTS sampling index:${c}`, $.InvalidADTSSamplingIndex); + e.trigger(x.INTERNAL_ERROR, t) + } + } + class u { + constructor(e, t, i, r, n) { + this.observer = e, this.remuxer = t, this.config = i, this.typeSupported = r, this.logger = n + } + static probe(e, t) { + throw new Error("Method not implemented") + } + resetTimeStamp(e) {} + resetInitSegment(e, t, i, r) {} + destroy() {} + } + class c extends u { + constructor(e, t, i, r, n) { + super(e, t, i, r, n), this.observer = e, this.remuxer = t, this.config = i, this.typeSupported = r, this.logger = n, this.esRemuxer = t + } + } + class h { + constructor(e, t, i) { + this.observer = e, this.config = t, this.logger = i + } + resetInitSegment() {} + resetTimeStamp(e) {} + destroy() {} + } + let m, I; + var w = { + strToUtf8array: e => (m = m || new TextEncoder, m.encode(e)), + utf8arrayToStr: e => (I = I || new TextDecoder("utf-8"), I.decode(e)) + }, + A = { + strToUtf8array(e) { + e = l.Buffer.from(e, "utf-8"); + return new Uint8Array(e.buffer, e.byteOffset, e.byteLength) + }, + utf8arrayToStr: e => l.Buffer.from(e).toString("utf-8") + }; + let O = { + strToUtf8array(e) { + const t = unescape(encodeURIComponent(e)), + i = new Uint8Array(t.length); + for (let e = 0; e < t.length; e++) i[e] = t.charCodeAt(e); + return i + }, + utf8arrayToStr: e => String.fromCharCode.apply(null, Array.from(e)) + }; + "undefined" != typeof TextEncoder && "undefined" != typeof TextDecoder ? O = w : "function" == typeof(null === (fl = l.Buffer) || void 0 === fl ? void 0 : fl.from) && (O = A); + const k = { + name: "ID3" + }; + class C { + constructor(e, t) { + this.logger = t, this._hasTimeStamp = !1, this._audioType = null, this._length = 0, this._frames = []; + let i, r, n, s, a = 0; + for (;;) + if (n = C.readUTF(e, a, 3), a += 3, "ID3" === n) { + this._minor = e[a++], this._revision = e[a++]; + const t = e[a++]; + if (128 & t && (this._unsynchronized = !0, this.logger.error(k, "id3 tag is unsynchronized")), 64 & t && (this._hasExtendedHeader = !0, this.logger.warn(k, "id3 tag has extended header")), i = C.readSynchSafeUint32(e.subarray(a, a + 4)), a += 4, r = a + i, this._hasExtendedHeader) { + const t = C.readSynchSafeUint32(e.subarray(a, a + 4)); + this.logger.warn(k, `id3 tag has ${t}-byte extended header. usually 6 or 10 bytes`), a += t + } + 2 < this.minor ? this._parseID3Frames(e, a, r) : this.logger.error(k, "[id3] doesn't support older than v2.3 tags"), a = r + } else { + if ("3DI" !== n) return a -= 3, void((s = a) && (this.hasTimeStamp || this.logger.warn(k, "ID3 tag found, but no timestamp"), this._length = s, this._payload = e.slice(0, s))); + a += 7 + } + } + static isHeader(e, t) { + return 73 === e[t] && 68 === e[t + 1] && 51 === e[t + 2] && e[t + 3] < 255 && e[t + 4] < 255 && e[t + 6] < 128 && e[t + 7] < 128 && e[t + 8] < 128 && e[t + 9] < 128 + } + static readSynchSafeUint32(e) { + return 2097152 * (127 & e[0]) + 16384 * (127 & e[1]) + 128 * (127 & e[2]) + (127 & e[3]) + } + static readUTF(e, t, i) { + let r = "", + n = t; + for (var s = t + i; r += String.fromCharCode(e[n++]), n < s;); + return r + } + isID3Frame(e, t) { + return e[t + 4] < 128 && e[t + 5] < 128 && e[t + 6] < 128 && e[t + 7] < 128 + } + decodeID3Frame(e) { + return "TXXX" === e.type ? this.decodeTxxxFrame(e) : "WXXX" === e.type ? this.decodeWxxxFrame(e) : "PRIV" === e.type ? this.decodePrivFrame(e) : "T" === e.type[0] ? this.decodeTextFrame(e) : { + key: e.type, + data: e.data + } + } + decodeTxxxFrame(e) { + if (!(e.size < 2) && 3 === e.data[0]) { + var t = 1, + i = this.id3utf8ArrayToStr(e.data.subarray(1)); + return t += i.length + 1, { + key: "TXXX", + description: i, + data: this.id3utf8ArrayToStr(e.data.subarray(t)) + } + } + } + decodeWxxxFrame(e) { + if (!(e.size < 2) && 3 === e.data[0]) { + var t = 1, + i = this.id3utf8ArrayToStr(e.data.subarray(1)); + return t += i.length + 1, { + key: "WXXX", + description: i, + data: O.utf8arrayToStr(e.data.subarray(t)) + } + } + } + decodeTextFrame(e) { + if (!(e.size < 2) && 3 === e.data[0]) { + var t = e.data.subarray(1); + return { + key: e.type, + data: this.id3utf8ArrayToStr(t) + } + } + } + decodePrivFrame(e) { + if (!(e.size < 2)) { + var t = this.id3utf8ArrayToStr(e.data); + return { + key: "PRIV", + info: t, + data: e.data.slice(t.length + 1) + } + } + } + _extractID3Frame(e, t, i, r, n) { + var s = r + i; + let a; + return s <= n ? a = { + type: t, + data: e.slice(r, s) + } : this.logger.error(k, `id3 frame ${t} size ${i} exceeded ${n}`), a + } + _parseID3Frames(e, t, i) { + let r, n, s, a; + for (; t + 8 <= i;) { + if (!this.isID3Frame(e, t)) return void this.logger.error(k, `[id3] illegal id3 frame @ offset ${t}. skip this id3 tag`); + if (r = C.readUTF(e, t, 4), t += 4, "" === r) return; + if (0 === (n = C.readSynchSafeUint32(e.subarray(t, t + 4)))) return; + t += 4, e[t++], e[t++], s = t; + var o = this._extractID3Frame(e, r, n, s, i); + if (o) { + const e = this.decodeID3Frame(o); + this._frames.push(e) + } + if ("PRIV" === r) + if (53 === n && "com.apple.streaming.transportStreamTimestamp" === C.readUTF(e, t, 44)) { + t += 44, t += 4; + const i = 1 & e[t++]; + this._hasTimeStamp = !0, a = ((e[t++] << 23) + (e[t++] << 15) + (e[t++] << 7) + e[t++]) / 45, i && (a += 47721858.84), a = Math.round(a), this._timeStamp = a + } else 45 <= n && "com.apple.streaming.audioDescription" === C.readUTF(e, t, 36) ? (t += 37, this._audioType = C.readUTF(e, t, 4), t += 4, t += n - 41) : t += n; + else t += n + } + } + id3utf8ArrayToStr(e) { + let t, i, r = "", + n = 0; + const s = e.length; + for (; n < s;) { + const s = e[n++]; + switch (s >> 4) { + case 0: + return r; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + r += String.fromCharCode(s); + break; + case 12: + case 13: + t = e[n++], r += String.fromCharCode((31 & s) << 6 | 63 & t); + break; + case 14: + t = e[n++], i = e[n++], r += String.fromCharCode((15 & s) << 12 | (63 & t) << 6 | (63 & i) << 0) + } + } + } + get hasTimeStamp() { + return this._hasTimeStamp + } + get timeStamp() { + return this._timeStamp + } + get audioType() { + return this._audioType + } + get length() { + return this._length + } + get payload() { + return this._payload + } + get frames() { + return this._frames + } + get minor() { + return this._minor + } + get revision() { + return this._revision + } + } + var M = C; + const U = { + name: "AACDemuxer" + }; + class K extends c { + resetInitSegment(e, t) { + this.audioConfig = void 0, this.audioTrack = void 0, this.duration = t + } + static probe(e, t) { + let i, r; + for (i = new M(e, t).length, r = Math.min(e.length - 1, i + 100); i < r; i++) + if (255 === e[i] && 240 == (246 & e[i + 1])) return !0; + return !1 + } + append(e, t, i, r, n) { + var s = new M(e, this.logger), + a = s.hasTimeStamp ? 90 * s.timeStamp : 9e4 * t; + let o, l, d, u, c, h, p, f, m, g; + for (s.length && (g = s.payload, s.frames.length && (m = s.frames), f = { + id3Samples: [{ + pts: a, + dts: a, + data: g, + frames: m + }], + inputTimescale: 9e4 + }), d = s.length, h = e.length; d < h - 1 && (255 !== e[d] || 240 != (246 & e[d + 1])); d++); + if (!this.audioConfig && (this.audioConfig = E(this.observer, e, d, void 0, this.logger), !this.audioConfig)) throw "failed to parse adts config"; + if (!this.audioTrack) { + const e = { + id: 258, + inputTimescale: 9e4, + timescale: NaN, + duration: this.duration, + encrypted: !1, + keyTagInfo: n + }, + t = { + len: 0, + sequenceNumber: 0, + esSamples: [] + }; + this.audioTrack = { + info: e, + parsingData: t, + type: "audio", + config: this.audioConfig + } + } + "zaac" !== s.audioType && "zach" !== s.audioType && "zacp" !== s.audioType || (this.audioTrack.info.encrypted = !0), l = 0; + for (var y = 9216e4 / this.audioConfig.samplerate; d + 5 < h && (u = 1 & e[d + 1] ? 7 : 9, o = (3 & e[d + 3]) << 11 | e[d + 4] << 3 | (224 & e[d + 5]) >>> 5, o -= u, 0 < o && d + u + o <= h);) + for (c = a + l * y, p = { + unit: e.subarray(d + u, d + u + o), + pts: c, + dts: c, + keyTagInfo: n + }, this.audioTrack.parsingData.esSamples.push(p), this.audioTrack.parsingData.len += o, d += o + u, l++; d < h - 1; d++) { + if (M.isHeader(e, d)) { + const t = new M(e.subarray(d), this.logger); + if (0 < t.length) { + d += t.length; + const e = t.hasTimeStamp ? 90 * t.timeStamp : a; + f.id3Samples.push({ + pts: e, + dts: e, + data: t.payload, + frames: t.frames + }) + } else this.logger.error(U, `[id3] invalid length ${h}`) + } + if (255 === e[d] && 240 == (246 & e[d + 1])) break + } + this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, f, void 0, t, i, r, n) + } + } + class q { + bsReadAndUpdate(e, t, i) { + e = this.readBits(e, t, i); + return this.updateOffset(t, i), e + } + bsWriteAndUpdate(e, t, i, r) { + r = this.writeBits(e, t, i, r); + return this.updateOffset(t, i), r + } + bsSkip(e, t) { + this.updateOffset(e, t) + } + readBits(i, r, n) { + if (i && r) { + let t = r.byteOffset; + const s = r["usedBits"]; + if (!(8 <= s || 32 < s + n)) { + let e; + const a = new Uint32Array(1), + o = new Uint32Array(1), + l = new Uint8Array(1); + if (!(8 <= s || 32 < n)) { + if (s) { + const r = 8 - s, + a = n < r ? r - n : 0; + o[0] = 4278190080 >>> 32 - r, e = (i[t] & o[0]) >>> a, t += 1, n -= r + } + for (; 0 < n;) { + l[0] = i[t]; + const r = Math.min(n, 8), + s = 8 - r; + o[0] = 4278190080 >>> 24 + s << s, a[0] = (l[0] & o[0]) >> s, e = e ? e << r | a[0] : a[0], t += 1, n -= r + } + return e + } + } + } + } + writeBits(t, i, r, n) { + if (t && i) { + let e = i.byteOffset; + var i = i["usedBits"]; + if (!(8 <= i || 32 < i + r)) { + const s = new Uint32Array(1), + a = new Uint32Array(1), + o = new Uint32Array(1), + l = new Uint8Array(1); + for (s[0] = n, i && (a[0] = s[0] << 32 - r, o[0] = 4278190080, l[0] = (a[0] & o[0]) >>> 24 + i, t[e] &= ~(o[0] >>> 24 + i), t[e] |= l[0], e += 1, r -= 8 - i); 0 < r;) { + a[0] = s[0] << 32 - r, o[0] = 4278190080, l[0] = (a[0] & o[0]) >>> 24; + const d = r < 0 ? 8 - r : 0; + t[e] &= ~(o[0] >>> 24 >>> d << d), t[e] |= l[0], r -= 8, e += 1 + } + return 0 + } + } + } + updateOffset(e, t) { + var i, r; + !e || !t || 32 < e.usedBits + t || (i = e.usedBits % 8, r = Math.floor((i + t) / 8), t = (i + t) % 8, e.byteOffset += r, e.usedBits = t) + } + } + + function H(e, t) { + return 1536 / e.samplerate * t + } + + function j(e, t, i, r) { + let n; + if (i + 8 > t.length) return n = new D(!0, "error parsing ac-3, not enough data", $.InsufficientAC3Data), void e.trigger(x.INTERNAL_ERROR, n); + if (11 !== t[i] || 119 !== t[i + 1]) return n = new D(!0, "invalid ac-3 magic", $.InvalidAC3Magic), void e.trigger(x.INTERNAL_ERROR, n); + var s = t[i + 4] >> 6; + if (3 <= s) return n = new D(!0, `invalid ac-3 samplingRateCode:${s}`, $.InvalidAC3SamplingRateCode), void e.trigger(x.INTERNAL_ERROR, n); + var a = 63 & t[i + 4], + o = t[i + 6] >> 5; + let l = 0; + 2 == o ? l += 2 : (1 & o && 1 != o && (l += 2), 4 & o && (l += 2)); + var d = (t[i + 6] << 8 | t[i + 7]) >> 12 - l & 1, + u = [2, 1, 2, 3, 3, 4, 4, 5][o] + d, + e = t[i + 5] >> 3, + i = 7 & t[i + 5]; + return { + samplerate: W[s], + channelCount: u, + segmentCodec: "ac3", + codec: "ac-3", + extraData: s << 22 | e << 17 | i << 14 | o << 11 | d << 10 | a >> 1 << 5 + } + } + + function Q(e, t, i) { + let r; + if (i + 8 > t.length) return r = new D(!0, "error parsing ac-3, not enough data", $.InsufficientAC3Data), void e.trigger(x.INTERNAL_ERROR, r); + if (11 !== t[i] || 119 !== t[i + 1]) return r = new D(!0, "invalid ac-3 magic", $.InvalidAC3Magic), void e.trigger(x.INTERNAL_ERROR, r); + var n = t[i + 4] >> 6; + return 3 <= n ? (r = new D(!0, `invalid ac-3 samplingRateCode:${n}`, $.InvalidAC3SamplingRateCode), void e.trigger(x.INTERNAL_ERROR, r)) : (i = 63 & t[i + 4], 2 * G[3 * i + n]) + } + const W = [48e3, 44100, 32e3], + G = [64, 69, 96, 64, 70, 96, 80, 87, 120, 80, 88, 120, 96, 104, 144, 96, 105, 144, 112, 121, 168, 112, 122, 168, 128, 139, 192, 128, 140, 192, 160, 174, 240, 160, 175, 240, 192, 208, 288, 192, 209, 288, 224, 243, 336, 224, 244, 336, 256, 278, 384, 256, 279, 384, 320, 348, 480, 320, 349, 480, 384, 417, 576, 384, 418, 576, 448, 487, 672, 448, 488, 672, 512, 557, 768, 512, 558, 768, 640, 696, 960, 640, 697, 960, 768, 835, 1152, 768, 836, 1152, 896, 975, 1344, 896, 976, 1344, 1024, 1114, 1536, 1024, 1115, 1536, 1152, 1253, 1728, 1152, 1254, 1728, 1280, 1393, 1920, 1280, 1394, 1920]; + class z extends c { + resetInitSegment(e, t) { + this.audioConfig = void 0, this.audioTrack = void 0, this.duration = t + } + static probe(e, t) { + var i = new M(e, t), + t = i.length; + return !!(i.hasTimeStamp && 11 === e[t] && 119 === e[t + 1] && (new q).bsReadAndUpdate(e, { + byteOffset: t + 5, + usedBits: 0 + }, 5) < 16) + } + append(e, t, i, r, n) { + var s = new M(e, this.logger), + a = 90 * s.timeStamp, + o = e.byteLength; + let l = 0, + d = s.length; + if (this.audioConfig || (this.audioConfig = j(this.observer, e, d, this.logger)), !this.audioConfig) throw "failed to parse ac3 config"; + if (!this.audioTrack) { + const e = { + id: 258, + inputTimescale: 9e4, + timescale: NaN, + duration: this.duration, + encrypted: !1, + keyTagInfo: n + }, + t = { + len: 0, + sequenceNumber: 0, + esSamples: [] + }; + this.audioTrack = { + info: e, + parsingData: t, + type: "audio", + config: this.audioConfig + } + } + var u = H(this.audioConfig, this.audioTrack.info.inputTimescale); + for ("zac3" === s.audioType && (this.audioTrack.info.encrypted = !0); d < o;) { + if (M.isHeader(e, d) && (d += new M(e.subarray(d), this.logger).length), 11 !== e[d] || 119 !== e[d + 1]) { + const e = new D(!0, "invalid ac-3 magic", $.InvalidAC3Magic); + return void this.observer.trigger(x.INTERNAL_ERROR, e) + } + const t = Q(this.observer, e, d), + i = a + l * u, + r = { + unit: e.subarray(d, d + t), + pts: i, + dts: i, + keyTagInfo: n + }; + this.audioTrack.parsingData.esSamples.push(r), this.audioTrack.parsingData.len += t, d += t, l++ + } + this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, { + id3Samples: [{ + pts: a, + dts: a, + data: s.payload, + frames: s.frames + }], + inputTimescale: this.audioTrack.info.inputTimescale + }, void 0, t, i, r, n) + } + } + var X = function(t, i, r, n) { + const s = new q; + let a, o = !1, + l = 0; + for (; r < i.length;) { + if (r + 8 > i.length) return a = new D(!0, "error parsing ec-3, not enough data", $.InsufficientEC3Data), void t.trigger(x.INTERNAL_ERROR, a); + let e = 0; + if (M.isHeader(i, r) && (e = new M(i.subarray(r), n).length || 0, r += e), 11 !== i[r] || 119 !== i[r + 1]) return a = new D(!0, "invalid ec-3 magic", $.InvalidEC3Magic), void t.trigger(x.INTERNAL_ERROR, a); + var d = { + byteOffset: r + 2, + usedBits: 0 + }, + u = s.bsReadAndUpdate(i, d, 2), + c = s.bsReadAndUpdate(i, d, 3); + if (0 === u || 2 === u) + if (!0 === o) { + if (0 === c) break + } else o = !0; + else if (1 !== u) return a = new D(!0, "reserved stream type", $.ReservedStreamType), void t.trigger(x.INTERNAL_ERROR, a); + d = 2 * (s.bsReadAndUpdate(i, d, 11) + 1); + r += d, l += d + (e || 0) + } + return l + }, + Y = function(t, i, r, n) { + const s = { + frmsiz: 0, + fscod: 0, + numblkscod: 0, + acmod: 0, + lfeon: 0, + bsid: 0, + strmtyp: 0, + substreamid: 0, + chanmape: 0, + chanmap: 0, + mixdef: 0, + mixdeflen: 0, + bsmod: 0 + }, + a = { + fscod: 0, + acmod: 0, + lfeon: 0, + bsid: 0, + bsmod: 0, + chan_loc: 0, + data_rate: 0, + num_ind_sub: 0, + num_dep_sub: [], + complexity_index_type_a: 0 + }, + o = new q; + let l, d = !1, + u = 0; + for (; r < i.length;) { + if (r + 8 > i.length) return l = new D(!0, "error parsing ec-3, not enough data", $.InsufficientEC3Data), void t.trigger(x.INTERNAL_ERROR, l); + let e = 0; + if (M.isHeader(i, r) && (e = new M(i.subarray(r), n).length || 0, r += e), 11 !== i[r] || 119 !== i[r + 1]) return l = new D(!0, "invalid ec-3 magic", $.InvalidEC3Magic), void t.trigger(x.INTERNAL_ERROR, l); + const h = { + byteOffset: r + 2, + usedBits: 0 + }; + if (s.strmtyp = o.bsReadAndUpdate(i, h, 2), s.substreamid = o.bsReadAndUpdate(i, h, 3), 0 === s.strmtyp || 2 === s.strmtyp) { + if (!0 === d) { + if (0 === s.substreamid) break + } else d = !0; + a.num_ind_sub++, a.num_dep_sub.push(0) + } else { + if (1 !== s.strmtyp) return l = new D(!0, "reserved stream type", $.ReservedStreamType), void t.trigger(x.INTERNAL_ERROR, l); + a.num_dep_sub[a.num_ind_sub - 1]++ + } + if (s.frmsiz = o.bsReadAndUpdate(i, h, 11), s.fscod = o.bsReadAndUpdate(i, h, 2), 3 === s.fscod ? (o.bsSkip(h, 2), s.numblkscod = 3) : s.numblkscod = o.bsReadAndUpdate(i, h, 2), s.acmod = o.bsReadAndUpdate(i, h, 3), s.lfeon = o.bsReadAndUpdate(i, h, 1), s.bsid = o.bsReadAndUpdate(i, h, 5), o.bsSkip(h, 5), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8), 0 === s.acmod && (o.bsSkip(h, 5), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8)), 1 === s.strmtyp && (s.chanmape = o.bsReadAndUpdate(i, h, 1), s.chanmape && (s.chanmap = o.bsReadAndUpdate(i, h, 16))), o.bsReadAndUpdate(i, h, 1) && (2 < s.acmod && o.bsSkip(h, 2), 1 & s.acmod && 2 < s.acmod && o.bsSkip(h, 6), 4 & s.acmod && o.bsSkip(h, 6), s.lfeon && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 5), 0 === s.strmtyp)) { + if (o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 6), 0 === s.acmod && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 6), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 6), s.mixdef = o.bsReadAndUpdate(i, h, 2), 1 === s.mixdef) o.bsSkip(h, 5); + else if (2 === s.mixdef) o.bsSkip(h, 12); + else if (3 === s.mixdef) { + s.mixdeflen = o.bsReadAndUpdate(i, h, 5), o.bsReadAndUpdate(i, h, 1) && (o.bsSkip(h, 5), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && (o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4))), o.bsReadAndUpdate(i, h, 1) && (o.bsSkip(h, 5), o.bsReadAndUpdate(i, h, 1) && (o.bsSkip(h, 7), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8))); + const t = s.mixdeflen + 2 + (h.usedBits ? 1 : 0); + h.byteOffset += t + } + if (s.acmod < 2 && (o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 14), 0 === s.acmod && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 14)), o.bsReadAndUpdate(i, h, 1)) + if (0 === s.numblkscod) o.bsSkip(h, 5); + else + for (let e = 0; e < s.numblkscod; e++) o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 5) + } + if (s.bsmod = 0, o.bsReadAndUpdate(i, h, 1) && (s.bsmod = o.bsReadAndUpdate(i, h, 3), o.bsSkip(h, 2), 2 === s.acmod && o.bsSkip(h, 4), 6 <= s.acmod && o.bsSkip(h, 2), o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8), 0 === s.acmod && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8), s.fscod < 3 && o.bsSkip(h, 1)), 0 === s.strmtyp && 3 !== s.numblkscod && o.bsSkip(h, 1), 2 !== s.strmtyp || (3 === s.numblkscod ? 1 : o.bsReadAndUpdate(i, h, 1)) && o.bsReadAndUpdate(i, h, 6), o.bsReadAndUpdate(i, h, 1)) { + const t = o.bsReadAndUpdate(i, h, 6); + if (0 === s.strmtyp && 0 === s.substreamid && 1 === t) { + const t = o.bsReadAndUpdate(i, h, 7), + r = o.bsReadAndUpdate(i, h, 1), + n = o.bsReadAndUpdate(i, h, 8); + 0 === t && 1 === r && 1 <= n && n <= 16 && (a.complexity_index_type_a = n) + } + } + if (s.chanmape) a.chan_loc |= s.chanmap; + else { + const t = [40960, 16384, 40960, 57344, 41472, 57856, 47104, 63488]; + a.chan_loc |= t[s.acmod] + } + 0 === s.strmtyp && (a.fscod = s.fscod, a.bsid = s.bsid, a.bsmod = s.bsmod, a.acmod = s.acmod, a.lfeon = s.lfeon), a.chan_loc |= s.lfeon ? 1 : 0; + const p = 2 * (s.frmsiz + 1); + r += p, u += p + (e || 0) + } + let c = 0; + for (let e = 0; e < 16; e++) a.chan_loc & 1 << e && c++; + a.lfeon && c++; + let h = 10 + 3 * a.num_ind_sub; + const p = [48e3, 44100, 32e3][a.fscod]; + a.data_rate = p / 1536 * u * 8, h = 10 + 3 * a.num_ind_sub; + for (let e = 0; e < a.num_ind_sub; e++) 0 < a.num_dep_sub[e] && h++; + 0 < a.complexity_index_type_a && (h += 2); + var f = new Uint8Array(h), + m = { + byteOffset: 0, + usedBits: 0 + }; + o.bsWriteAndUpdate(f, m, 32, h), o.bsWriteAndUpdate(f, m, 32, 1684366131), o.bsWriteAndUpdate(f, m, 13, a.data_rate), o.bsWriteAndUpdate(f, m, 3, a.num_ind_sub); + for (let e = 0; e < a.num_ind_sub; e++) o.bsWriteAndUpdate(f, m, 2, a.fscod), o.bsWriteAndUpdate(f, m, 5, a.bsid), o.bsWriteAndUpdate(f, m, 1, 0), o.bsWriteAndUpdate(f, m, 1, 0 === e ? 0 : 1), o.bsWriteAndUpdate(f, m, 3, a.bsmod), o.bsWriteAndUpdate(f, m, 3, a.acmod), o.bsWriteAndUpdate(f, m, 1, a.lfeon), o.bsWriteAndUpdate(f, m, 3, 0), o.bsWriteAndUpdate(f, m, 4, a.num_dep_sub[e]), 0 < a.num_dep_sub[e] ? o.bsWriteAndUpdate(f, m, 9, a.chan_loc) : o.bsWriteAndUpdate(f, m, 1, 0); + return 0 < a.complexity_index_type_a && (o.bsWriteAndUpdate(f, m, 7, 0), o.bsWriteAndUpdate(f, m, 1, 1), o.bsWriteAndUpdate(f, m, 8, a.complexity_index_type_a)), { + samplerate: p, + channelCount: c, + segmentCodec: "ec3", + codec: "ec-3", + extraDataBytes: f + } + }; + class J extends c { + resetInitSegment(e, t) { + this.audioConfig = void 0, this.audioTrack = void 0, this.duration = t + } + static probe(e, t) { + var i = new M(e, t), + t = i.length; + return !(!i.hasTimeStamp || 11 !== e[t] || 119 !== e[t + 1] || 16 !== (new q).bsReadAndUpdate(e, { + byteOffset: t + 5, + usedBits: 0 + }, 5)) + } + append(e, t, i, r, n) { + var s = new M(e, this.logger), + a = 90 * s.timeStamp, + o = e.length; + let l = 0, + d = s.length; + if (this.audioConfig || (this.audioConfig = Y(this.observer, e, d, this.logger)), !this.audioConfig) throw "failed to parse ec-3 config"; + if (!this.audioTrack) { + const e = { + id: 258, + inputTimescale: 9e4, + timescale: NaN, + duration: this.duration, + encrypted: !1, + keyTagInfo: n + }, + t = { + len: 0, + sequenceNumber: 0, + esSamples: [] + }; + this.audioTrack = { + info: e, + parsingData: t, + type: "audio", + config: this.audioConfig + } + } + var u = H(this.audioConfig, this.audioTrack.info.inputTimescale); + for ("zec3" === s.audioType && (this.audioTrack.info.encrypted = !0); d < o;) { + const t = X(this.observer, e, d, this.logger), + i = a + l * u, + r = { + unit: e.subarray(d, d + t), + pts: i, + dts: i, + keyTagInfo: n + }; + this.audioTrack.parsingData.esSamples.push(r), this.audioTrack.parsingData.len += t, d += t, l++ + } + this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, { + id3Samples: [{ + pts: a, + dts: a, + data: s.payload, + frames: s.frames + }], + inputTimescale: this.audioTrack.info.inputTimescale + }, void 0, t, i, r, n) + } + } + const Z = { + BitratesMap: [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160], + SamplingRateMap: [44100, 48e3, 32e3, 22050, 24e3, 16e3, 11025, 12e3, 8e3], + SamplesCoefficients: [ + [0, 72, 144, 12], + [0, 0, 0, 0], + [0, 72, 144, 12], + [0, 144, 144, 12] + ], + BytesInSlot: [0, 1, 1, 4], + onFrame: function(e, t, i, r, n, s, a) { + r = a + s * (10368e4 / r); + e.esSamples.push({ + unit: t, + pts: r, + dts: r + }), e.len += t.length + }, + onNoise: function(e, t) { + t.warn("mpeg audio has noise: " + e.length + " bytes") + }, + parseFrames: function(e, t, i, r, n, s, a) { + if (r < i + 2) return -1; + if (255 === t[i] || 224 == (224 & t[i + 1])) { + if (r < i + 24) return -1; + const a = t[i + 1] >> 3 & 3, + c = t[i + 1] >> 1 & 3, + h = t[i + 2] >> 4 & 15, + p = t[i + 2] >> 2 & 3, + f = !!(2 & t[i + 2]); + if (1 != a && 0 != h && 15 != h && 3 != p) { + var o = 1e3 * [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160][14 * (3 == a ? 3 - c : 3 == c ? 3 : 4) + h - 1], + l = [44100, 48e3, 32e3, 22050, 24e3, 16e3, 11025, 12e3, 8e3][3 * (3 == a ? 0 : 2 == a ? 1 : 2) + p], + d = f ? 1 : 0, + u = t[i + 3] >> 6 == 3 ? 1 : 2, + d = 3 == c ? (3 == a ? 12 : 6) * o / l + d << 2 : (3 == a ? 144 : 72) * o / l + d | 0; + return r < i + d ? -1 : (Z.onFrame(e, t.subarray(i, i + d), o, l, u, n, s), d) + } + } + let c = i + 2; + for (; c < r;) { + if (255 === t[c - 1] && 224 == (224 & t[c])) return Z.onNoise(t.subarray(i, c - 1), a), c - i - 1; + c++ + } + return -1 + }, + parse: function(e, t, i, r, n) { + var s = t.length; + let a, o = 0; + for (; i < s && 0 < (a = Z.parseFrames(e, t, i, s, o++, r, n));) i += a + }, + getAudioConfig: function(e, t) { + var i = e[t + 1] >> 3 & 3, + r = e[t + 1] >> 1 & 3, + n = e[t + 2] >> 4 & 15, + s = e[t + 2] >> 2 & 3, + a = e[t + 2] >> 1 & 1; + if (1 != i && 0 != n && 15 != n && 3 != s) { + var o = 3 == i ? 3 - r : 3 == r ? 3 : 4, + o = 1e3 * Z.BitratesMap[14 * o + n - 1], + n = 3 == i ? 0 : 2 == i ? 1 : 2, + s = Z.SamplingRateMap[3 * n + s], + t = e[t + 3] >> 6 == 3 ? 1 : 2, + i = Z.SamplesCoefficients[i][r], + r = Z.BytesInSlot[r]; + return { + segmentCodec: "mp3", + codec: "mp3", + samplerate: s, + channelCount: t, + frameLength: parseInt(i * o / s + a, 10) * r + } + } + }, + isHeaderPattern: function(e, t) { + return 255 === e[t] && 224 == (224 & e[t + 1]) && 0 != (6 & e[t + 1]) + }, + probe: function(t, i) { + if (i + 1 < t.length && Z.isHeaderPattern(t, i)) { + var r = Z.getAudioConfig(t, i); + let e = 4; + r && r.frameLength && (e = r.frameLength); + i = i + e; + if (i === t.length || i + 1 < t.length && Z.isHeaderPattern(t, i)) return !0 + } + return !1 + } + }; + var ee = Z; + const te = { + name: "MP3Demuxer" + }; + class ie extends c { + resetInitSegment(e, t) { + this.audioConfig = void 0, this.audioTrack = void 0, this.duration = t + } + static probe(e, t) { + var i = new M(e, t); + let r, n; + if (i.hasTimeStamp) + for (r = i.length, n = Math.min(e.length - 1, r + 100); r < n; r++) + if (ee.probe(e, r)) return t.warn(te, "MPEG Audio sync word found !"), !0; + return !1 + } + append(e, t, i, r, n) { + var s = new M(e, this.logger), + a = 90 * s.timeStamp; + if (this.audioConfig || (this.audioConfig = ee.getAudioConfig(e, s.length)), !this.audioConfig) throw "unable to parse mp3 header"; + if (!this.audioTrack) { + const e = { + id: 258, + inputTimescale: 9e4, + timescale: NaN, + duration: this.duration, + encrypted: !1, + keyTagInfo: n + }, + t = { + len: 0, + sequenceNumber: 0, + esSamples: [] + }; + this.audioTrack = { + info: e, + parsingData: t, + type: "audio", + config: this.audioConfig + } + } + ee.parse(this.audioTrack.parsingData, e, s.length, a, this.logger), this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, { + id3Samples: [{ + pts: a, + dts: a, + data: s.payload, + frames: s.frames + }], + inputTimescale: 9e4 + }, void 0, t, i, r) + } + } + + function re(e, t) { + if ("mp4a.40.2" === e) { + if (1 === t) return new Uint8Array([0, 200, 0, 128, 35, 128]); + if (2 === t) return new Uint8Array([33, 0, 73, 144, 2, 25, 0, 35, 128]); + if (3 === t) return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 142]); + if (4 === t) return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 128, 44, 128, 8, 2, 56]); + if (5 === t) return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 56]); + if (6 === t) return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 0, 178, 0, 32, 8, 224]) + } else { + if (1 === t) return new Uint8Array([1, 64, 34, 128, 163, 78, 230, 128, 186, 8, 0, 0, 0, 28, 6, 241, 193, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]); + if (2 === t) return new Uint8Array([1, 64, 34, 128, 163, 94, 230, 128, 186, 8, 0, 0, 0, 0, 149, 0, 6, 241, 161, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]); + if (3 === t) return new Uint8Array([1, 64, 34, 128, 163, 94, 230, 128, 186, 8, 0, 0, 0, 0, 149, 0, 6, 241, 161, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]) + } + return null + } + + function ne(e) { + return "number" == typeof e && isFinite(e) + } + + function se(e, t) { + return ne(e) ? e.toFixed(t) : `${e}` + } + + function ae(e, i = 3) { + return JSON.stringify(e, (e, t) => !isNaN(t) && null != t && t.toFixed ? Number(null == t ? void 0 : t.toFixed(i)) : t) + } + let oe = !0; + + function le(e) { + return oe ? "" : e + } + + function de(e) { + if (!e) return e; + if ("object" != typeof e) return e; { + if (Array.isArray(e)) return e.map(de); + const r = {}; + for (var [t, i] of Object.entries(e)) r[t] = de(i); + return r + } + } + + function ue(e) { + const t = [...e]; + for (let e = 0; e < t.length; e++) t[e] = Object.assign({}, t[e]), t[e].url = le(t[e].url), t[e].attrs && (t[e].attrs = Object.assign({}, t[e].attrs), t[e].attrs.URI = le(t[e].attrs.URI)); + return t + } + + function ce(e) { + const t = [...e]; + for (let e = 0; e < t.length; e++) t[e] = Object.assign({}, t[e]), t[e].url = le(t[e].url); + return t + } + const he = Math.pow(2, 32) - 1; + class pe { + static init() { + let e; + for (e in pe.types = { + avc1: [], + avcC: [], + btrt: [], + dinf: [], + dref: [], + esds: [], + free: [], + ftyp: [], + hdlr: [], + mdat: [], + mdhd: [], + mdia: [], + mfhd: [], + minf: [], + moof: [], + moov: [], + mp4a: [], + ".mp3": [], + dac3: [], + "ac-3": [], + dec3: [], + "ec-3": [], + mvex: [], + mvhd: [], + pasp: [], + sdtp: [], + stbl: [], + stco: [], + stsc: [], + stsd: [], + stsz: [], + stts: [], + tfdt: [], + tfhd: [], + traf: [], + trak: [], + trun: [], + trex: [], + tkhd: [], + vmhd: [], + smhd: [], + uuid: [], + encv: [], + enca: [], + frma: [], + schm: [], + schi: [], + senc: [], + saio: [], + saiz: [], + sinf: [], + tenc: [], + sbgp: [], + seig: [], + sgpd: [], + pssh: [] + }, pe.types) pe.types.hasOwnProperty(e) && (pe.types[e] = [e.charCodeAt(0), e.charCodeAt(1), e.charCodeAt(2), e.charCodeAt(3)]); + var t = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 118, 105, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 105, 100, 101, 111, 72, 97, 110, 100, 108, 101, 114, 0]), + i = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 115, 111, 117, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 111, 117, 110, 100, 72, 97, 110, 100, 108, 101, 114, 0]); + pe.HDLR_TYPES = { + video: t, + audio: i + }; + var r = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 117, 114, 108, 32, 0, 0, 0, 1]), + n = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]); + pe.STTS = pe.STSC = pe.STCO = n, pe.STSZ = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), pe.VMHD = new Uint8Array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), pe.SMHD = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]), pe.STSD = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1]); + t = new Uint8Array([105, 115, 111, 109]), i = new Uint8Array([97, 118, 99, 49]), n = new Uint8Array([0, 0, 0, 1]); + pe.FTYP = pe.box(pe.types.ftyp, t, n, t, i), pe.DINF = pe.box(pe.types.dinf, pe.box(pe.types.dref, r)) + } + static set16(e, t, i) { + return t[i] = e >> 8 & 255, t[i + 1] = 255 & e, i + 2 + } + static set32(e, t, i) { + return t[i] = e >> 24 & 255, t[i + 1] = e >> 16 & 255, t[i + 2] = e >> 8 & 255, t[i + 3] = 255 & e, i + 4 + } + static box(e) { + var t = Array.prototype.slice.call(arguments, 1); + let i = 8, + r = t.length; + for (var n = r; r--;) i += t[r].byteLength; + const s = new Uint8Array(i); + for (s[0] = i >> 24 & 255, s[1] = i >> 16 & 255, s[2] = i >> 8 & 255, s[3] = 255 & i, s.set(e, 4), r = 0, i = 8; r < n; r++) s.set(t[r], i), i += t[r].byteLength; + return s + } + static hdlr(e) { + return pe.box(pe.types.hdlr, pe.HDLR_TYPES[e]) + } + static mdat(e) { + return pe.box(pe.types.mdat, e) + } + static mdhd(e, t) { + t *= e; + var i = Math.floor(t / (1 + he)), + t = Math.floor(t % (1 + he)); + return pe.box(pe.types.mdhd, new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, t >> 24, t >> 16 & 255, t >> 8 & 255, 255 & t, 85, 196, 0, 0])) + } + static mdia(e) { + var t = pe.mdhd(e.info.timescale, e.info.duration), + i = pe.hdlr(e.type), + e = pe.minf(e); + return pe.box(pe.types.mdia, t, i, e) + } + static mfhd(e) { + return pe.box(pe.types.mfhd, new Uint8Array([0, 0, 0, 0, e >> 24, e >> 16 & 255, e >> 8 & 255, 255 & e])) + } + static minf(e) { + return "audio" === e.type ? pe.box(pe.types.minf, pe.box(pe.types.smhd, pe.SMHD), pe.DINF, pe.stbl(e)) : pe.box(pe.types.minf, pe.box(pe.types.vmhd, pe.VMHD), pe.DINF, pe.stbl(e)) + } + static moof(e, t) { + pe.types || pe.init(); + e = pe.traf(t, e); + return pe.box(pe.types.moof, pe.mfhd(t.sequenceNumber), e) + } + static moov(e) { + let t = e.length; + const i = []; + for (; t--;) i[t] = pe.trak(e[t]); + return pe.box.apply(null, [pe.types.moov, pe.mvhd(e[0].info.timescale, e[0].info.duration)].concat(i).concat(pe.mvex(e))) + } + static mvex(e) { + let t = e.length; + const i = []; + for (; t--;) i[t] = pe.trex(e[t]); + return pe.box(pe.types.mvex, ...i) + } + static mvhd(e, t) { + t *= e; + var i = Math.floor(t / (1 + he)), + t = Math.floor(t % (1 + he)), + t = new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, t >> 24, t >> 16 & 255, t >> 8 & 255, 255 & t, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255]); + return pe.box(pe.types.mvhd, t) + } + static sdtp(e) { + const t = e.samples || [], + i = new Uint8Array(4 + t.length); + let r, n; + for (n = 0; n < t.length; n++) r = t[n].flags, i[n + 4] = r.dependsOn << 4 | r.isDependedOn << 2 | r.hasRedundancy; + return pe.box(pe.types.sdtp, i) + } + static stbl(e) { + var t = pe.stsd(e), + i = pe.box(pe.types.stts, pe.STTS), + r = pe.box(pe.types.stsc, pe.STSC), + n = pe.box(pe.types.stsz, pe.STSZ), + e = pe.box(pe.types.stco, pe.STCO); + return pe.box(pe.types.stbl, t, i, r, n, e) + } + static avc1(e) { + let t, i, r, n = [], + s = []; + var a = e.info.encrypted ? pe.types.encv : pe.types.avc1; + for (t = 0; t < e.config.sps.length; t++) i = e.config.sps[t], r = i.byteLength, n.push(r >>> 8 & 255), n.push(255 & r), n = n.concat(Array.prototype.slice.call(i)); + for (t = 0; t < e.config.pps.length; t++) i = e.config.pps[t], r = i.byteLength, s.push(r >>> 8 & 255), s.push(255 & r), s = s.concat(Array.prototype.slice.call(i)); + var o = pe.box(pe.types.avcC, new Uint8Array([1, n[3], n[4], n[5], 255, 224 | e.config.sps.length].concat(n).concat([e.config.pps.length]).concat(s))), + l = e.config.width, + d = e.config.height, + u = e.config.pixelRatio[0], + c = e.config.pixelRatio[1], + h = e.info.encrypted && e.info.keyTagInfo ? pe.sinf(e.info.keyTagInfo, e.type, pe.types.avc1) : new Uint8Array; + return pe.box(a, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, l >> 8 & 255, 255 & l, d >> 8 & 255, 255 & d, 0, 72, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 1, 18, 100, 97, 105, 108, 121, 109, 111, 116, 105, 111, 110, 47, 104, 108, 115, 46, 106, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 17, 17]), o, h, pe.box(pe.types.btrt, new Uint8Array([0, 28, 156, 128, 0, 45, 198, 192, 0, 45, 198, 192])), pe.box(pe.types.pasp, new Uint8Array([u >> 24, u >> 16 & 255, u >> 8 & 255, 255 & u, c >> 24, c >> 16 & 255, c >> 8 & 255, 255 & c]))) + } + static esds(e) { + var t = e.esdsConfig.length; + return new Uint8Array([0, 0, 0, 0, 3, 23 + t, 0, 1, 0, 4, 15 + t, 64, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5].concat([t]).concat(e.esdsConfig).concat([6, 1, 2])) + } + static audioStsd(e) { + var t = e.samplerate; + return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, e.channelCount, 0, 16, 0, 0, 0, 0, t >> 8 & 255, 255 & t, 0, 0]) + } + static dac3(e) { + e = e.extraData; + return new Uint8Array([e >> 16 & 255, e >> 8 & 255, 255 & e]) + } + static dec3(e) { + return e.extraDataBytes + } + static mp4a(e, t) { + let i = pe.types.mp4a, + r = null; + r = e.encrypted && e.keyTagInfo ? (i = pe.types.enca, pe.sinf(e.keyTagInfo, "audio", pe.types.mp4a)) : new Uint8Array; + e = pe.audioStsd(t), t = pe.box(pe.types.esds, pe.esds(t)); + return pe.box(i, e, t, r) + } + static mp3(e) { + return pe.box(pe.types[".mp3"], pe.audioStsd(e)) + } + static ac3(e, t) { + let i = pe.types["ac-3"], + r = null; + return r = e.encrypted && e.keyTagInfo ? (i = pe.types.enca, pe.sinf(e.keyTagInfo, "audio", pe.types["ac-3"])) : new Uint8Array, pe.box(i, pe.audioStsd(t), pe.box(pe.types.dac3, pe.dac3(t)), r) + } + static ec3(e, t) { + let i = pe.types["ec-3"], + r = null; + return r = e.encrypted && e.keyTagInfo ? (i = pe.types.enca, pe.sinf(e.keyTagInfo, "audio", pe.types["ec-3"])) : new Uint8Array, pe.box(i, pe.audioStsd(t), pe.box(pe.types.dec3, pe.dec3(t)), r) + } + static stsd(e) { + if ("audio" !== e.type) return pe.box(pe.types.stsd, pe.STSD, pe.avc1(e)); + if ("mp3" === e.config.segmentCodec && "mp3" === e.config.codec) return pe.box(pe.types.stsd, pe.STSD, pe.mp3(e.config)); + if ("ac3" === e.config.segmentCodec) return pe.box(pe.types.stsd, pe.STSD, pe.ac3(e.info, e.config)); + if ("ec3" === e.config.segmentCodec) return pe.box(pe.types.stsd, pe.STSD, pe.ec3(e.info, e.config)); + if ("aac" === e.config.segmentCodec) return pe.box(pe.types.stsd, pe.STSD, pe.mp4a(e.info, e.config)); + throw `unknown segmentCodec ${e.config.segmentCodec}` + } + static tkhd(e) { + var t = e.info.id, + i = e.info.duration * e.info.timescale, + r = Math.floor(i / (1 + he)), + i = Math.floor(i % (1 + he)); + let n = 0, + s = 0; + return "video" === e.type && (n = e.config.width, s = e.config.height), pe.box(pe.types.tkhd, new Uint8Array([1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, t >> 24 & 255, t >> 16 & 255, t >> 8 & 255, 255 & t, 0, 0, 0, 0, r >> 24, r >> 16 & 255, r >> 8 & 255, 255 & r, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, n >> 8 & 255, 255 & n, 0, 0, s >> 8 & 255, 255 & s, 0, 0])) + } + static traf(e, t) { + var i = pe.senc(e), + r = pe.sdtp(e), + n = i.boxData, + s = n.length ? pe.saio(76) : new Uint8Array, + a = n.length ? pe.saiz(i.defaultSampleInfoSize, i.sampleInfoSizes) : new Uint8Array, + o = pe.sbgp(e), + l = pe.sgpd(e), + d = e.id, + i = Math.floor(t / (1 + he)), + t = Math.floor(t % (1 + he)); + return pe.box(pe.types.traf, pe.box(pe.types.tfhd, new Uint8Array([0, 2, 0, 0, d >> 24, d >> 16 & 255, d >> 8 & 255, 255 & d])), pe.box(pe.types.tfdt, new Uint8Array([1, 0, 0, 0, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, t >> 24, t >> 16 & 255, t >> 8 & 255, 255 & t])), n, s, a, o, l, pe.trun(e, r.length + n.length + o.length + l.length + s.length + a.length + 16 + 20 + 8 + 16 + 8 + 8), r) + } + static trak(e) { + if ("trakData" in e) return e.trakData; + e.info.duration = e.info.duration || 4294967295; + var t = pe.types.trak, + i = pe.tkhd(e), + e = pe.mdia(e); + return pe.box(t, i, e) + } + static trex(e) { + e = e.info.id; + return pe.box(pe.types.trex, new Uint8Array([0, 0, 0, 0, e >> 24, e >> 16 & 255, e >> 8 & 255, 255 & e, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1])) + } + static trun(e, t) { + const i = e.samples || [], + r = i.length, + n = 12 + 16 * r, + s = new Uint8Array(n); + let a, o, l, d, u, c; + for (t += 8 + n, s.set([0, 0, 15, 1, r >>> 24 & 255, r >>> 16 & 255, r >>> 8 & 255, 255 & r, t >>> 24 & 255, t >>> 16 & 255, t >>> 8 & 255, 255 & t], 0), a = 0; a < r; a++) l = (o = i[a]).duration, d = o.size, u = o.flags, c = o.cts, s.set([l >>> 24 & 255, l >>> 16 & 255, l >>> 8 & 255, 255 & l, d >>> 24 & 255, d >>> 16 & 255, d >>> 8 & 255, 255 & d, u.isLeading << 2 | u.dependsOn, u.isDependedOn << 6 | u.hasRedundancy << 4 | u.paddingValue << 1 | u.isNonSync, 61440 & u.degradPrio, 15 & u.degradPrio, c >>> 24 & 255, c >>> 16 & 255, c >>> 8 & 255, 255 & c], 12 + 16 * a); + return pe.box(pe.types.trun, s) + } + static initSegment(e) { + pe.types || pe.init(); + const t = pe.moov(e), + i = new Uint8Array(pe.FTYP.byteLength + t.byteLength); + return i.set(pe.FTYP), i.set(t, pe.FTYP.byteLength), i + } + static saio(e) { + e = e + 4 + 4; + return pe.box(pe.types.saio, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e])) + } + static saiz(e, t) { + ne(e) || (e = 0); + var i = t.length, + t = 0 === e ? new Uint8Array(t) : new Uint8Array; + return pe.box(pe.types.saiz, new Uint8Array([0, 0, 0, 0, e, i >> 24 & 255, i >> 16 & 255, i >> 8 & 255, 255 & i]), t) + } + static senc(e) { + const t = e.samples || [], + i = t.length; + let r = 0, + n = NaN, + s = !0; + const a = []; + if (!e.encrypted || i <= 0) return { + boxData: new Uint8Array, + sampleInfoSizes: a, + defaultSampleInfoSize: 0 + }; + e = e.defaultPerSampleIVSize || 0; + for (const d of t) d.subsamples && (r += d.subsamples.length); + if (r <= 0) return { + boxData: new Uint8Array, + sampleInfoSizes: a, + defaultSampleInfoSize: 0 + }; + const o = new Uint8Array(2 * i + i * e + 6 * r + 4); + let l = this.set32(i, o, 0); + for (const d of t) { + const t = d.subsamples || []; + let e = 2; + d.iv && (o.set(d.iv, l), l += d.iv.byteLength, e += d.iv.byteLength), l = this.set16(t.length, o, l); + for (const d of t) l = this.set16(d[0], o, l), l = this.set32(d[1], o, l), e += 6; + a.push(e), ne(n) || (n = e), s = s && n === e, n = e + } + return { + boxData: pe.box(pe.types.senc, new Uint8Array([0, 0, 0, 2]), o), + defaultSampleInfoSize: s ? n : 0, + sampleInfoSizes: a + } + } + static sinf(e, t, i) { + return pe.box(pe.types.sinf, pe.frma(i), pe.schm(), pe.schi(e, t)) + } + static frma(e) { + return pe.box(pe.types.frma, new Uint8Array(e)) + } + static schm() { + return pe.box(pe.types.schm, new Uint8Array([0, 0, 0, 0, 99, 98, 99, 115, 0, 1, 0, 0])) + } + static schi(e, t) { + return pe.box(pe.types.schi, pe.tenc(e, t)) + } + static tenc(e, t) { + let i = 0; + "video" === t && (i = 25); + const r = new Uint8Array(17); + if (r[0] = 16, e.iv && 16 === e.iv.byteLength && r.set(e.iv, 1), !e.keyId) throw "tenc: no key id found in decryptdata"; + return pe.box(pe.types.tenc, new Uint8Array([1, 0, 0, 0, 0, i, 1, 0]), e.keyId, r) + } + static sbgp(e) { + if (!e.encrypted || 0 === e.samples.length || !e.samples[0].keyTagInfo) return new Uint8Array; + e = e.samples.length; + return pe.box(pe.types.sbgp, new Uint8Array([0, 0, 0, 0]), new Uint8Array(pe.types.seig), new Uint8Array([0, 0, 0, 1, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e, 0, 1, 0, 1])) + } + static sgpd(e) { + if (!e.encrypted || 0 === e.samples.length || !e.samples[0].keyTagInfo) return new Uint8Array; + var t = e.samples[0].keyTagInfo; + let i = 0; + "video" === e.type && (i = 25); + const r = new Uint8Array(17); + if (r[0] = 16, t.iv && r.set(t.iv, 1), !t.keyId) throw "sgpd: no keyid in decryptdata"; + return pe.box(pe.types.sgpd, new Uint8Array([1, 0, 0, 0]), new Uint8Array(pe.types.seig), new Uint8Array([0, 0, 0, 37, 0, 0, 0, 1]), new Uint8Array([0, i, 1, 0]), t.keyId, r) + } + static pssh(e, t, i) { + if (pe.types || pe.init(), !e) throw new TypeError("Bad system id"); + if (16 !== e.byteLength) throw new RangeError("Invalid system id"); + let r, n, s; + if (t) { + r = 1, n = new Uint8Array(16 * t.length); + for (let e = 0; e < t.length; e++) { + const i = t[e]; + if (16 !== i.byteLength) throw new RangeError("Invalid key"); + n.set(i, 16 * e) + } + } else r = 0, n = new Uint8Array; + 0 < r ? (s = new Uint8Array(4), 0 < t.length && new DataView(s.buffer).setUint32(0, t.length, !1)) : s = new Uint8Array; + var a = new Uint8Array(4); + return i && 0 < i.byteLength && new DataView(a.buffer).setUint32(0, i.byteLength, !1), pe.box(pe.types.pssh, new Uint8Array([r, 0, 0, 0]), e, s, n, a, i || new Uint8Array) + } + } + var fe, me, ge = pe; + (vi = fe = fe || {})[vi.SDR = 0] = "SDR", vi[vi.HDR = 1] = "HDR", vi[vi.HDR10 = 2] = "HDR10", vi[vi.DolbyVision = 3] = "DolbyVision", vi[vi.HLG = 4] = "HLG", (bi = me = me || {})[bi.H264 = 16] = "H264", bi[bi.HEVC = 64] = "HEVC", bi[bi.VP09 = 65] = "VP09"; + const ye = new Set(["ac-3", "mp4a.a5", "mp4a.A5"]), + ve = new Set(["ec-3", "mp4a.a6", "mp4a.A6"]), + Se = { + aac: 1024, + mp3: 1024, + ac3: 1536, + ec3: 1536 + }, + be = { + isAC3: e => Boolean(e && ye.has(e)), + isEC3: e => Boolean(e && ve.has(e)), + isDolbyAtmos(e, t) { + const i = t.split("/"); + return Boolean(be.isEC3(e) && 1 < i.length && i[1].split(",").find(e => "JOC" === e)) + }, + isAAC(e) { + return Boolean(e && ("aac" === e || null !== (e = e.match(/^mp4a\.40\.(.*)/)) && "34" !== e[1])) + }, + isMP3(e) { + return Boolean(e && ("mp3" === e || null !== (e = e.match(/^mp4a\.40\.(.*)/)) && "34" === e[1])) + }, + isAVC: e => Boolean(e && e.match(/^avc[13]\.(.*)/)), + isXHEAAC: function(e) { + return Boolean("mp4a.40.42" === e) + }, + isALAC: function(e) { + return Boolean("alac" === e) + }, + isFLAC: function(e) { + return Boolean("fLaC" === e) + }, + isHEVC: e => Boolean(e && e.match(/^(hev|hvc)1\..*/)), + isDolby: e => Boolean(e && e.match(/^dv(h1|he|a1|av)\..*/)), + isVP09: e => Boolean(e && e.match(/^vp09\..*/)), + isCompatibleCodecString(e, t) { + const i = e.split(","), + r = t.split(","), + n = i.filter(e => be.isVideoCodec(e)), + s = r.filter(e => be.isVideoCodec(e)), + a = i.filter(e => be.isAudioCodec(e)), + o = r.filter(e => be.isAudioCodec(e)), + l = 0 === n.length && 0 === s.length || n.length === s.length && be.isCompatibleVideoCodec(n[0], s[0]), + d = 0 === a.length && 0 === o.length || a.length === o.length && be.isCompatibleAudioCodec(a[0], o[0]); + return l && d + }, + isVideoCodec: e => be.isAVC(e) || be.isDolby(e) || be.isHEVC(e) || be.isVP09(e), + isAudioCodec: e => be.isAC3(e) || be.isEC3(e) || be.isAAC(e) || be.isMP3(e), + isCompatibleVideoCodec: (e, t) => Boolean(e && t && (e === t || be.isDolby(e) && be.isDolby(t) || be.isHEVC(e) && be.isHEVC(t) || be.isAVC(e) && be.isAVC(t) || be.isVP09(e) && be.isVP09(t))), + isCompatibleAudioCodec: (e, t) => Boolean(e && t && (e === t || be.isAAC(e) && be.isAAC(t) || be.isAC3(e) && be.isAC3(t) || be.isEC3(e) && be.isEC3(t) || be.isMP3(e) && be.isMP3(t))), + getSegmentCodec(e) { + let t; + if (be.isAAC(e)) t = "aac"; + else if (be.isAC3(e)) t = "ac3"; + else if (be.isEC3(e)) t = "ec3"; + else { + if ("mp3" !== e) throw new Error(`invalid audio config, codec ${e}`); + t = "mp3" + } + return t + }, + getChannelCount(e) { + if (!e) return 0; + e = e.split("/"), e = parseInt(e[0]); + return ne(e) ? e : 0 + }, + avc1toavcoti(e) { + var t; + const i = e.split("."); + let r; + return 2 < i.length ? (r = i.shift() + ".", r += parseInt(null !== (t = i.shift()) && void 0 !== t ? t : "").toString(16), r += ("000" + parseInt(null !== (t = i.shift()) && void 0 !== t ? t : "").toString(16)).substr(-4)) : r = e, r + }, + getDynamicRangeType(e, t) { + let i = fe.SDR; + return "PQ" === e && be.isDolby(t) ? i = fe.DolbyVision : "PQ" === e && (be.isHEVC(t) || be.isVP09(t)) ? i = fe.HDR10 : "HLG" !== e || -1 === t.indexOf("hvc1") && !be.isVP09(t) || (i = fe.HLG), i + }, + getCompressionType(e) { + let t = me.H264; + return be.isHEVC(e) || be.isDolby(e) ? t = me.HEVC : be.isVP09(e) && (t = me.VP09), t + }, + isHigherCodecByFamily(e, t) { + if (!e) return !0; + const i = e.split("."), + r = t.split("."); + if (i[0] !== r[0]) throw new Error(`mismatch in codec family current/new: ${i[0]}/${r[0]}`); + switch (i[0]) { + case "avc1": + case "avc3": + return r[1] > i[1]; + case "vp09": + return e < t; + case "hvc1": + case "hev1": + var n = "H" === i[3].substring(0, 1) ? 1 : 0, + s = i[3].substring(1), + a = "H" === r[3].substring(0, 1) ? 1 : 0, + o = r[3].substring(1); + return r[1] > i[1] || r[2] > i[2] || n < a || s < o; + case "dvh1": + return r[1] > i[1] || r[2] > i[2] + } + } + }; + class Te { + static getTrack(e, t, i, r, n) { + let s; + switch (be.getSegmentCodec(i)) { + case "aac": + var a; + (a = E(e, 1 === r ? new Uint8Array([255, 241, 92, 64, 1, 127, 252]) : new Uint8Array([255, 241, 92, 128, 1, 191, 252]), 0, i)) && (s = { + type: "audio", + info: { + id: t, + timescale: a.samplerate, + duration: 0, + encrypted: !1, + keyTagInfo: void 0 + }, + config: a + }); + break; + case "ac3": + case "ec3": { + const i = j(e, new Uint8Array([11, 119, 69, 17, 128, 64, 47, 132]), 0); + i && (s = { + type: "audio", + info: { + id: t, + timescale: i.samplerate, + duration: 0, + encrypted: !1, + keyTagInfo: void 0 + }, + config: i + }) + } + } + return s + } + static getSample(e, t) { + let i; + switch (e) { + case "mp4a.40.2": + case "mp4a.40.5": + i = 1 === t ? new Uint8Array([0, 208, 0, 7]) : new Uint8Array([33, 0, 3, 64, 104, 28]); + break; + case "ac-3": + case "ec-3": + i = new Uint8Array([11, 119, 69, 17, 128, 64, 47, 132, 41, 3, 253, 214, 124, 253, 243, 215, 233, 95, 185, 123, 78, 20, 40, 106, 97, 190, 74, 253, 43, 218, 208, 140, 191, 176, 144, 120, 214, 181, 44, 124, 129, 251, 91, 109, 187, 109, 198, 225, 43, 172, 116, 140, 176, 123, 38, 144, 211, 247, 225, 64, 29, 53, 175, 96, 16, 57, 121, 87, 78, 203, 81, 37, 7, 72, 228, 132, 37, 169, 38, 231, 97, 229, 247, 194, 208, 8, 12, 83, 74, 139, 137, 17, 22, 26, 221, 203, 107, 113, 94, 93, 75, 33, 208, 247, 146, 105, 39, 143, 6, 36, 1, 227, 108, 70, 11, 180, 152, 218, 182, 218, 209, 59, 85, 104, 201, 70, 37, 82, 219, 68, 55, 225, 144, 99, 149, 0, 119, 26, 14, 69, 164, 241, 204, 222, 81, 177, 142, 80, 20, 100, 97, 143, 101, 221, 140, 113, 31, 208, 124, 25, 64, 29, 49, 77, 140, 30, 155, 74, 214, 204, 138, 229, 109, 172, 95, 130, 70, 230, 134, 88, 59, 179, 212, 155, 232, 0, 0, 0, 0, 0, 173, 234]) + } + return i + } + static getSegment(e, i, r, n) { + if (e) { + var s = e.info["timescale"], + a = e.config["segmentCodec"], + o = Te.getSample(e.config.codec, e.config.channelCount); + if (o) { + const l = [], + d = { + id: e.info.id, + sequenceNumber: i, + type: "audio", + encrypted: !1, + samples: l, + defaultPerSampleIVSize: 0 + }, + u = Se[a], + c = Math.ceil(n * s / u), + h = { + baseTime: Math.round(c * u + r), + timescale: s + }; + let t = 0; + const p = c * o.byteLength + 8, + f = new Uint8Array(p); + f[0] = p >> 24 & 255, f[1] = p >> 16 & 255, f[2] = p >> 8 & 255, f[3] = 255 & p, ge.types || ge.init(), f.set(ge.types.mdat, 4), t += 8; + for (let e = 0; e < c; e++) l.push({ + duration: u, + size: o.byteLength, + cts: 0, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 1, + isNonSync: 0, + paddingValue: 0 + } + }), f.set(o, t), t += o.byteLength; + const m = ge.moof(r, d), + g = new Uint8Array(m.byteLength + f.byteLength); + return g.set(m), g.set(f, m.byteLength), { + silentFragData: g, + endTs: h + } + } + } + } + } + class Ee extends h { + constructor(e, t, i, r, n) { + super(e, t, n), this.typeSupported = i, this.isVideoContiguous = !1, this.logger = n.child({ + name: "EsRemuxer" + }); + const s = navigator.userAgent; + this.isSafari = r && -1 < r.indexOf("Apple") && s && !s.match("CriOS") + } + resetTimeStamp(e) { + this._initPTS = this._initDTS = e + } + resetInitSegment() { + this.currentInitTrack = void 0, this._silentAudioTrack = void 0 + } + remuxEsTracks(r, n, s, a, o, l, d, u, c, h) { + let p; + l || (this.isVideoContiguous = !1); + c = void 0 === c ? o : c; + if (!this.currentInitTrack) { + if (r && r.config.codec && (this._audioTrackInfo = { + id: r.info.id, + codec: r.config.codec, + channelCount: r.config.channelCount + }), n && h && this._audioTrackInfo) { + const r = Te.getTrack(this.observer, this._audioTrackInfo.id, this._audioTrackInfo.codec, this._audioTrackInfo.channelCount, this.logger); + if (r) { + this._silentAudioTrack = Object.assign(Object.assign({}, r), { + info: Object.assign(Object.assign({}, r.info), { + inputTimescale: 9e4 + }), + parsingData: { + len: 0, + sequenceNumber: 0, + esSamples: [] + } + }); + const s = this._initPTS + Math.round(c * this._silentAudioTrack.info.timescale); + p = Te.getSegment(this._silentAudioTrack, n.parsingData.sequenceNumber, s, h), n.parsingData.sequenceNumber++ + } + } else this._silentAudioTrack = void 0; + this.updateInitPTSDTS(n, r, o), this.generateIS(this._silentAudioTrack || r, n) + } + if (this.currentInitTrack) { + const f = n && n.parsingData.esSamples.length, + m = this.isVideoContiguous; + let t, i, e; + if (n && h && this._silentAudioTrack && !p) { + const r = this._initPTS + Math.round((c + this.config.audioPrimingDelay) * this._silentAudioTrack.info.timescale); + p = Te.getSegment(this._silentAudioTrack, n.parsingData.sequenceNumber, r, h) + } + if (r && r.parsingData.esSamples.length) { + if (ne(r.info.timescale) || (this.logger.warn("regenerate InitSegment as audio detected"), this.updateInitPTSDTS(n, r, o), this.generateIS(r, n)), t = this.remuxAudio(r, c, l, d, u), f) { + let e; + t && (e = S(t.endPTS) - S(t.startPTS)), ne(n.info.timescale) || (this.logger.warn("regenerate InitSegment as video detected"), this.updateInitPTSDTS(n, r, o), this.generateIS(r, n)), i = this.remuxVideo(n, c, m, e, h) + } + } else f && (i = this.remuxVideo(n, c, m, void 0, h)), i && r && r.config.codec && (t = this.remuxEmptyAudio(r, c, l, d, i, u)); + p ? e = { + data1: i.data1, + data2: p.silentFragData, + startDTS: i.startDTS, + startPTS: i.startPTS, + endDTS: y(i.endDTS, p.endTs), + endPTS: y(i.endPTS, p.endTs), + type: "audiovideo", + track: this.currentInitTrack + } : i && t ? e = { + data1: i.data1, + data2: t.data1, + startDTS: g(i.startDTS, t.startDTS), + startPTS: g(i.startPTS, t.startPTS), + endDTS: y(i.endDTS, t.endDTS), + endPTS: y(i.endPTS, t.endPTS), + type: "audiovideo", + track: this.currentInitTrack, + dropped: i.dropped, + framesWithoutIDR: i.framesWithoutIDR, + firstKeyframePts: i.firstKeyframePts + } : i ? e = { + data1: i.data1, + startDTS: i.startDTS, + startPTS: i.startPTS, + endDTS: i.endDTS, + endPTS: i.endPTS, + type: "video", + track: this.currentInitTrack, + dropped: i.dropped, + framesWithoutIDR: i.framesWithoutIDR, + firstKeyframePts: i.firstKeyframePts + } : t ? e = { + data1: t.data1, + startDTS: t.startDTS, + startPTS: t.startPTS, + endDTS: t.endDTS, + endPTS: t.endPTS, + type: "audio", + track: this.currentInitTrack + } : this.logger.error("Missing video and audio data"), a && a.captionSamples.length && this.remuxText(a, e), null !== (a = null == s ? void 0 : s.id3Samples) && void 0 !== a && a.length && this.remuxID3(s, e), this.observer.trigger(v.FRAG_PARSING_DATA, e) + } else this.logger.error("failed to generate IS"); + this.observer.trigger(v.FRAG_PARSED) + } + updateInitPTSDTS(e, t, i) { + let r = 1 / 0, + n = 1 / 0; + var s = e ? e.parsingData.esSamples : [], + a = t ? t.parsingData.esSamples : []; + if (!ne(this._initPTS)) { + if (t && a.length && (r = n = a[0].pts - t.info.inputTimescale * i), e && s.length) { + const t = e.info.inputTimescale; + e.info.timescale = t, r = Math.min(r, s.reduce((e, t) => { + var i = t.pts - e; + return i < -4294967296 ? Ie(e, t.pts) : 0 < i ? e : t.pts + }, s[0].pts) - t * i), n = Math.min(n, s[0].dts - t * i), this.observer.trigger(v.INIT_PTS_FOUND, { + initPTS: B(r, t) + }) + } + if (ne(r) && ne(n)) this._initPTS = r, this._initDTS = n; + else { + const e = new D(!1, "invalid initPTS or initDTS", $.InvalidInitTimestamp); + this.observer.trigger(x.INTERNAL_ERROR, e) + } + } + } + generateIS(e, t) { + const i = t ? t.parsingData.esSamples : [], + r = this.typeSupported; + let n, s = "audio/mp4"; + if (e && t && i.length) { + const i = t.info.inputTimescale; + t.info.timescale = i, e.info.timescale = e.config.samplerate; + const r = pe.initSegment([t, e]); + n = { + type: "audiovideo", + container: "video/mp4", + codec: `${t.config.codec},${e.config.codec}`, + initSegment: r + } + } else if (e) { + "mp3" === (e.info.timescale = e.config.samplerate, e.config.segmentCodec) && (r.mpeg ? (s = "audio/mpeg", e.config.codec = "") : r.mp3 && (e.config.codec = "mp3")); + const t = "mp3" === e.config.segmentCodec && r.mpeg ? new Uint8Array : pe.initSegment([e]); + n = { + type: "audio", + container: s, + codec: e.config.codec, + initSegment: t + } + } else if (t && i.length) { + const e = t.info.inputTimescale; + t.info.timescale = e; + const i = pe.initSegment([t]); + n = { + type: "video", + container: "video/mp4", + codec: t.config.codec, + initSegment: i + } + } + if (n) { + this.currentInitTrack = n; + const e = { + track: n + }; + this.observer.trigger(v.FRAG_PARSING_INIT_SEGMENT, e) + } else { + const e = new D(!1, "no audio/video samples found", $.NoAVSamplesFound); + this.observer.trigger(x.INTERNAL_ERROR, e) + } + } + remuxVideo(n, e, s, a, o) { + let l, d, u, c, h, t, p = 8, + i = n.parsingData.dropped; + const r = !s && this.config.forceKeyFrameOnDiscontinuity, + f = n.parsingData.esSamples, + m = n.info.inputTimescale, + g = [], + y = n.info.encrypted; + let v, S; + v = s ? this.nextAvcDts : Ie(f[0].dts, f[0].pts), f.forEach(function(e) { + e.pts = Ie(e.pts, v), e.dts = Ie(e.dts, v) + }), f.sort(function(e, t) { + var i = e.dts - t.dts, + r = e.pts - t.pts; + return i || r || e.id - t.id + }); + var b = f.findIndex(e => e.key); + f[b] && (S = f[b].pts), r && (0 < b ? (this.logger.warn(`Dropped ${b} out of ${f.length} video samples due to a missing keyframe`), f.splice(0, b), i += b) : -1 === b && (this.logger.warn(`No keyframe found out of ${f.length} video samples`), i += f.length)); + var T = f[0], + E = f[f.length - 1], + I = f.reduce((e, t) => Math.max(Math.min(e, t.pts - t.dts), -18e3), 0); + if (I < 0) { + this.logger.warn(`PTS < DTS detected in video samples, shifting DTS by ${Math.round(I/90)} ms to overcome this issue`); + for (let e = 0; e < f.length; e++) f[e].dts += I + } + var w = this.isSafari; + if (l = Math.round((E.dts - T.dts) / (f.length - 1)), c = Math.max(T.dts, 0), u = Math.max(T.pts, 0), ne(o) && (c = e * m, u = e * m), s) { + const n = c - v, + M = n > l, + s = n < -1; + (M || s) && (M ? this.logger.warn(`AVC: ${n}/90000 hole between fragments detected`) : this.logger.warn(`AVC: ${n}/90000 overlapping between fragments detected`)) + } + let A = 0, + O = 0; + var k = f.length; + for (let e = 0; e < k; e++) { + const M = f[e], + s = M.units, + a = s.length; + let t = 0; + for (let e = 0; e < a; e++) t += s[e].data.length; + O += t, A += a, M.length = t, M.dts = w ? c + e * l : Math.max(M.dts, c), M.pts = Math.max(M.pts, M.dts) + } + t = Math.max(E.dts, 0), h = Math.max(E.pts, 0, t), ne(o) && (t = e * m, h = e * m); + e = O + 4 * A + 8; + try { + d = new Uint8Array(e) + } catch (n) { + const M = new F(!1, `fail allocating video mdat ${e}`, $.FailedToAllocateVideoMdat, e); + return void this.observer.trigger(x.INTERNAL_ERROR, M) + } + const C = new DataView(d.buffer); + C.setUint32(0, e), d.set(pe.types.mdat, 4); + for (let t = 0; t < k; t++) { + const M = f[t], + s = M.units; + let e, i = 0; + const x = []; + let r = 0; + for (let e = 0, t = s.length; e < t; e++) { + const M = s[e], + a = M.data, + o = M.data.byteLength; + if (C.setUint32(p, o), p += 4, d.set(a, p), p += o, i += 4 + o, y) + if (o <= 48 || 1 !== M.type && 5 !== M.type) r += 4 + o; + else { + let e = o - 32; + e % 16 == 0 && (e -= 16), x.push([r + 36, e]), r = o - 32 - e + } + } + if (0 < r && x.push([r, 0]), w) e = Math.max(0, l * Math.round((M.pts - M.dts) / l)); + else { + if (t < k - 1) l = f[t + 1].dts - M.dts; + else { + const s = this.config, + o = M.dts - f[0 < t ? t - 1 : t].dts; + if (s.stretchShortVideoTrack) { + const n = s.maxBufferHole, + d = s.maxSeekHole, + c = Math.floor(Math.min(n, d) * m), + h = (a ? u + a * m : this.nextAudioPts) - M.pts; + h > c ? (l = h - o, l < 0 && (l = o)) : l = o + } else l = o + } + e = Math.round(M.pts - M.dts) + } + ne(o) && (e = 0, l = o * m), g.push({ + size: i, + duration: l, + cts: e, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: M.key ? 2 : 1, + isNonSync: M.key ? 0 : 1, + paddingValue: 0 + }, + keyTagInfo: M.keyTagInfo, + subsamples: x + }) + } + if (this.nextAvcDts = t + l, this.isVideoContiguous = !0, g.length && -1 < navigator.userAgent.toLowerCase().indexOf("chrome")) { + const n = g[0].flags; + n.dependsOn = 2, n.isNonSync = 0 + } + e = { + sequenceNumber: n.parsingData.sequenceNumber++, + id: n.info.id, + type: n.type, + encrypted: n.info.encrypted, + samples: g, + defaultPerSampleIVSize: 0 + }, e = pe.moof(c + this.config.audioPrimingDelay * m, e); + n.parsingData.esSamples = []; + const D = new Uint8Array(e.byteLength + d.byteLength); + return D.set(e), D.set(d, e.byteLength), { + data1: D, + startPTS: B(u / m, m), + endPTS: B((h + l) / m, m), + startDTS: B(c / m, m), + endDTS: B(this.nextAvcDts / m, m), + type: "video", + dropped: i, + framesWithoutIDR: b, + firstKeyframePts: B(S / m, m) + } + } + remuxAudio(r, i, n, e, s) { + const a = r.info.inputTimescale, + o = a / r.info.timescale, + l = ("aac" === r.config.segmentCodec ? 1024 : "mp3" === r.config.segmentCodec ? 1152 : 1536) * o, + d = "mp3" === r.config.segmentCodec && this.typeSupported.mpeg, + u = [], + c = r.info.encrypted, + t = this._initPTS + i * a; + let h, p, f, m, g, y, v, S, b, T, E, I, w, A, O = d ? 0 : 8; + const k = new q, + C = r.parsingData.esSamples; + if (A = this.nextAudioPts, (n = n || C.length && A && (e && Math.abs(t - A) < 9e3 || Math.abs(Ie(C[0].pts - A, t)) < 20 * l)) || (A = Ie(C[0].pts, this._initPTS)), C.forEach(function(e) { + e.pts = e.dts = Ie(e.pts, A) + }), e && "aac" === r.config.segmentCodec) + for (let t = 0, i = A; t < C.length;) { + const M = C[t]; + T = M.pts; + const o = T - i, + d = Math.abs(1e3 * o / a); + if (o <= -l) this.logger.warn(`Dropping 1 audio frame @ ${(i/a).toFixed(3)}s due to ${d} ms overlap.`), C.splice(t, 1), r.parsingData.len -= M.unit.length; + else if (o >= l && d < 1e4 && i) { + const d = Math.round(o / l); + this.logger.warn(`Injecting ${d} audio frame @ ${(i/a).toFixed(3)}s due to ${Math.round(1e3*o/a)} ms gap.`); + for (let e = 0; e < d; e++) w = Math.max(i, 0), I = re(r.config.codec, r.config.channelCount), I || (this.logger.warn("Unable to get silent frame for given audio codec; duplicating last frame instead."), I = M.unit.subarray(0)), C.splice(t, 0, { + unit: I, + pts: w, + dts: w, + keyTagInfo: s + }), r.parsingData.len += I.length, i += l, t += 1; + M.pts = M.dts = i, i += l, t += 1 + } else i += l, M.pts = M.dts = 0 === t ? A : C[t - 1].pts + l, t += 1 + } + for (let e = 0, t = C.length; e < t; e++) { + if (p = C[e], m = p.unit, T = p.pts, E = p.dts, void 0 !== b) f.duration = Math.round((E - b) / o); + else { + const i = Math.round(1e3 * (T - A) / a); + let t = 0; + if (n && "aac" === r.config.segmentCodec && i) { + if (0 < i && i < 1e4) t = Math.round((T - A) / l), 0 < t && (I = re(r.config.codec, r.config.channelCount), I = I || m.subarray(0), r.parsingData.len += t * I.length); + else if (i < -12) { + r.parsingData.len -= m.byteLength; + continue + } + T = E = A + } + if (v = Math.max(0, T), S = Math.max(0, E), !(0 < r.parsingData.len)) return; { + const i = d ? r.parsingData.len : r.parsingData.len + 8; + try { + g = new Uint8Array(i) + } catch (r) { + const n = new F(!1, `fail allocating audio mdat ${i}`, $.FailedToAllocateAudioMdat, i); + return void this.observer.trigger(x.INTERNAL_ERROR, n) + } + d || (h = new DataView(g.buffer), h.setUint32(0, i), g.set(pe.types.mdat, 4)) + } + for (let e = 0; e < t; e++) w = T - (t - e) * l, I = re(r.config.codec, r.config.channelCount), I || (this.logger.warn("Unable to get silent frame for given audio codec; duplicating this frame instead."), I = m.subarray(0)), g.set(I, O), O += I.byteLength, f = { + size: I.byteLength, + cts: 0, + duration: 1024, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 1, + paddingValue: 0, + isNonSync: 0 + }, + keyTagInfo: p.keyTagInfo, + subsamples: c ? [ + [I.byteLength, 0] + ] : [] + }, u.push(f) + } + g.set(m, O); + const M = m.byteLength; + O += M; + const s = []; + if (c) + if ("ec3" === r.config.segmentCodec) { + let e = 0; + for (; e < m.byteLength;) { + const i = 2 * (k.bsReadAndUpdate(m, { + byteOffset: e + 2, + usedBits: 5 + }, 11) + 1); + e += i; + const n = Math.min(i, 16); + s.push([n, i - n]) + } + } else { + const r = Math.min(M, 16); + s.push([r, M - r]) + } f = { + size: M, + cts: 0, + duration: 0, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 1, + paddingValue: 0, + isNonSync: 0 + }, + keyTagInfo: p.keyTagInfo, + subsamples: s + }, u.push(f), b = E + } + let D = 0; + e = u.length; + if (2 <= e && (D = u[e - 2].duration, f.duration = D), e) { + if (this.nextAudioPts = T + o * D, r.parsingData.len = 0, d) y = new Uint8Array; + else { + const i = { + sequenceNumber: r.parsingData.sequenceNumber++, + id: r.info.id, + type: r.type, + encrypted: r.info.encrypted, + samples: u, + defaultPerSampleIVSize: 0 + }; + y = pe.moof((S + this.config.audioPrimingDelay * a) / o, i) + } + const i = new Uint8Array(y.byteLength + g.byteLength); + return i.set(y), i.set(g, y.byteLength), r.parsingData.esSamples = [], { + data1: i, + startPTS: B(v / a, a), + endPTS: B(this.nextAudioPts / a, a), + startDTS: B(S / a, a), + endDTS: B((E + o * D) / a, a), + type: "audio" + } + } + return null + } + remuxEmptyAudio(t, e, i, r, n, s) { + var a = t.info.inputTimescale, + o = a / (t.config.samplerate || a), + l = this.nextAudioPts, + d = (void 0 !== l ? l : S(n.startDTS) * a) + this._initDTS, + a = S(n.endDTS) * a + this._initDTS, + u = 1024 * o, + c = Math.ceil((a - d) / u), + h = re(t.config.codec, t.config.channelCount); + if (this.logger.warn("remux empty Audio"), !h) return this.logger.error("Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!"), null; + const p = []; + for (let e = 0; e < c; e++) { + const i = d + e * u; + p.push({ + unit: h, + pts: i, + dts: i, + keyTagInfo: s + }), t.parsingData.len += h.length + } + return t.parsingData.esSamples = p, this.remuxAudio(t, e, i, r, s) + } + remuxID3(t, e) { + var i = t.id3Samples.length; + let r; + var n = t.inputTimescale; + if (i) { + for (let e = 0; e < i; e++) r = t.id3Samples[e], r.pts = r.pts / n, r.dts = r.dts / n; + e.id3Samples = t.id3Samples + } + t.id3Samples = [] + } + remuxText(t, e) { + t.captionSamples.sort(function(e, t) { + return e.pts - t.pts + }); + var i = t.captionSamples.length; + let r; + var n = t.inputTimescale; + if (i) { + for (let e = 0; e < i; e++) r = t.captionSamples[e], r.pts = r.pts / n; + e.captionData || (e.captionData = {}), e.captionData.ts = t.captionSamples + } + t.captionSamples = [] + } + } + + function Ie(e, t) { + var i; + if (void 0 === t) return e; + for (i = t < e ? -8589934592 : 8589934592; 4294967296 < Math.abs(e - t);) e += i; + return e + } + e = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : void 0 !== Jy ? Jy : {}; + + function we(e) { + try { + return JSON.stringify(e) + } catch (e) { + return '"[Circular]"' + } + } + + function Ae(e, t, i) { + var r = i && i.stringify || we; + if ("object" == typeof e && null !== e) { + var n = t.length + 1; + if (1 === n) return e; + var s = new Array(n); + s[0] = r(e); + for (var a = 1; a < n; a++) s[a] = r(t[a]); + return s.join(" ") + } + if ("string" != typeof e) return e; + var o = t.length; + if (0 === o) return e; + for (var l = "", d = 0, u = -1, c = e && e.length || 0, h = 0; h < c;) { + if (37 === e.charCodeAt(h) && h + 1 < c) { + switch (u = -1 < u ? u : 0, e.charCodeAt(h + 1)) { + case 100: + if (o <= d) break; + if (u < h && (l += e.slice(u, h)), null == t[d]) break; + l += Number(t[d]), u = h += 2; + break; + case 79: + case 111: + case 106: + if (o <= d) break; + if (u < h && (l += e.slice(u, h)), void 0 === t[d]) break; + var p = typeof t[d]; + if ("string" == p) { + l += "'" + t[d] + "'", u = h + 2, h++; + break + } + if ("function" == p) { + l += t[d].name || "", u = h + 2, h++; + break + } + l += r(t[d]), u = h + 2, h++; + break; + case 115: + if (o <= d) break; + u < h && (l += e.slice(u, h)), l += String(t[d]), u = h + 2, h++; + break; + case 37: + u < h && (l += e.slice(u, h)), l += "%", u = h + 2, h++ + }++d + }++h + } + return -1 === u ? e : (u < c && (l += e.slice(u)), l) + } + var Oe = De; + const ke = function() { + function t(e) { + return void 0 !== e && e + } + try { + return "undefined" != typeof globalThis || Object.defineProperty(Object.prototype, "globalThis", { + get: function() { + return delete Object.prototype.globalThis, this.globalThis = this + }, + configurable: !0 + }), globalThis + } catch (e) { + return t(Jy) || t(window) || t(this) || {} + } + }().console || {}, + Ce = { + mapHttpRequest: Le, + mapHttpResponse: Le, + wrapRequestSerializer: _e, + wrapResponseSerializer: _e, + wrapErrorSerializer: _e, + req: Le, + res: Le, + err: function(e) { + const t = { + type: e.constructor.name, + msg: e.message, + stack: e.stack + }; + for (const i in e) void 0 === t[i] && (t[i] = e[i]); + return t + } + }; + + function De(s) { + (s = s || {}).browser = s.browser || {}; + const a = s.browser.transmit; + if (a && "function" != typeof a.send) throw Error("pino: transmit option must have a send function"); + const e = s.browser.write || ke; + s.browser.write && (s.browser.asObject = !0); + const o = s.serializers || {}, + l = (t = s.browser.serialize, i = o, Array.isArray(t) ? t.filter(function(e) { + return "!stdSerializers.err" !== e + }) : !0 === t && Object.keys(i)); + var t, i; + let r = s.browser.serialize; + Array.isArray(s.browser.serialize) && -1 < s.browser.serialize.indexOf("!stdSerializers.err") && (r = !1), "function" == typeof e && (e.error = e.fatal = e.warn = e.info = e.debug = e.trace = e), !1 === s.enabled && (s.level = "silent"); + const n = s.level || "info", + d = Object.create(e); + d.log || (d.log = Ne), Object.defineProperty(d, "levelVal", { + get: function() { + return "silent" === this.level ? 1 / 0 : this.levels.values[this.level] + } + }), Object.defineProperty(d, "level", { + get: function() { + return this._level + }, + set: function(e) { + if ("silent" !== e && !this.levels.values[e]) throw Error("unknown level " + e); + this._level = e, Me(u, d, "error", "log"), Me(u, d, "fatal", "error"), Me(u, d, "warn", "error"), Me(u, d, "info", "log"), Me(u, d, "debug", "log"), Me(u, d, "trace", "log") + } + }); + const u = { + transmit: a, + serialize: l, + asObject: s.browser.asObject, + levels: ["error", "fatal", "warn", "info", "debug", "trace"], + timestamp: "function" == typeof(i = s).timestamp ? i.timestamp : !1 === i.timestamp ? Fe : Be + }; + return d.levels = De.levels, d.level = n, d.setMaxListeners = d.getMaxListeners = d.emit = d.addListener = d.on = d.prependListener = d.once = d.prependOnceListener = d.removeListener = d.removeAllListeners = d.listeners = d.listenerCount = d.eventNames = d.write = d.flush = Ne, d.serializers = o, d._serialize = l, d._stdErrSerialize = r, d.child = function(t) { + if (!t) throw new Error("missing bindings for child Pino"); + var i, r, e = t.serializers; + + function n(e) { + this._childLevel = 1 + (0 | e._childLevel), this.error = Pe(e, t, "error"), this.fatal = Pe(e, t, "fatal"), this.warn = Pe(e, t, "warn"), this.info = Pe(e, t, "info"), this.debug = Pe(e, t, "debug"), this.trace = Pe(e, t, "trace"), i && (this.serializers = i, this._serialize = r), a && (this._logEvent = Re([].concat(e._logEvent.bindings, t))) + } + return l && e && (i = Object.assign({}, o, e), r = !0 === s.browser.serialize ? Object.keys(i) : l, delete t.serializers, xe([t], r, i, this._stdErrSerialize)), n.prototype = this, new n(this) + }, a && (d._logEvent = Re()), d + } + + function Me(e, t, i, r) { + var n, s, a, o, l = Object.getPrototypeOf(t); + t[i] = !(t.levelVal > t.levels.values[i]) && (l[i] || ke[i] || ke[r]) || Ne, s = t, a = i, !(n = e).transmit && s[a] === Ne || (s[a] = (o = s[a], function() { + const e = n.timestamp(), + t = new Array(arguments.length), + i = Object.getPrototypeOf && Object.getPrototypeOf(this) === ke ? ke : this; + for (var r = 0; r < t.length; r++) t[r] = arguments[r]; + if (n.serialize && !n.asObject && xe(t, this._serialize, this.serializers, this._stdErrSerialize), n.asObject ? o.call(i, function(e, t, i, r) { + e._serialize && xe(i, e._serialize, e.serializers, e._stdErrSerialize); + const n = i.slice(); + let s = n[0]; + const a = {}; + r && (a.time = r), a.level = De.levels.values[t]; + let o = 1 + (0 | e._childLevel); + if (o < 1 && (o = 1), null !== s && "object" == typeof s) { + for (; o-- && "object" == typeof n[0];) Object.assign(a, n.shift()); + s = n.length ? Ae(n.shift(), n) : void 0 + } else "string" == typeof s && (s = Ae(n.shift(), n)); + return void 0 !== s && (a.msg = s), a + }(this, a, t, e)) : o.apply(i, t), n.transmit) { + const o = n.transmit.level || s.level, + i = De.levels.values[o], + r = De.levels.values[a]; + r < i || function(e, t, i) { + const r = t.send, + n = t.ts, + s = t.methodLevel, + a = t.methodValue, + o = t.val, + l = e._logEvent.bindings; + xe(i, e._serialize || Object.keys(e.serializers), e.serializers, void 0 === e._stdErrSerialize || e._stdErrSerialize), e._logEvent.ts = n, e._logEvent.messages = i.filter(function(e) { + return -1 === l.indexOf(e) + }), e._logEvent.level.label = s, e._logEvent.level.value = a, r(s, e._logEvent, o), e._logEvent = Re(l) + }(this, { + ts: e, + methodLevel: a, + methodValue: r, + transmitLevel: o, + transmitValue: De.levels.values[n.transmit.level || s.level], + send: n.transmit.send, + val: s.levelVal + }, t) + } + })) + } + + function xe(e, t, i, r) { + for (const n in e) + if (r && e[n] instanceof Error) e[n] = De.stdSerializers.err(e[n]); + else if ("object" == typeof e[n] && !Array.isArray(e[n])) + for (const r in e[n]) t && -1 < t.indexOf(r) && r in i && (e[n][r] = i[r](e[n][r])) + } + + function Pe(i, r, n) { + return function() { + try{ const e = new Array(1 + arguments.length); + e[0] = r; + for (var t = 1; t < e.length; t++) + e[t] = arguments[t - 1]; + return i[n].apply(this, e) } catch (e){} + } + } + + function Re(e) { + return { + ts: 0, + messages: [], + bindings: e || [], + level: { + label: "", + value: 0 + } + } + } + + function Le() { + return {} + } + + function _e(e) { + return e + } + + function Ne() {} + + function Fe() { + return !1 + } + + function Be() { + return Date.now() + } + let Ue; + + function $e(e = {}) { + return Object.assign(Object.assign({}, e), { + customLevels: Object.assign(Object.assign({}, e.customLevels || {}), { + qe: 35 + }) + }) + } + De.levels = { + values: { + fatal: 60, + error: 50, + warn: 40, + info: 30, + debug: 20, + trace: 10 + }, + labels: { + 10: "trace", + 20: "debug", + 30: "info", + 40: "warn", + 50: "error", + 60: "fatal" + } + }, De.stdSerializers = Ce, De.stdTimeFunctions = Object.assign({}, { + nullTime: Fe, + epochTime: Be, + unixTime: function() { + return Math.round(Date.now() / 1e3) + }, + isoTime: function() { + return new Date(Date.now()).toISOString() + } + }); + const Ve = () => {}; + + function Ke(e, t) { + const i = (e = t in e ? e : console)[t] || e.log; + return i ? i.bind(e) : Ve + } + + function qe(r, n, e) { + var { + time: s, + sessionId: t, + critical: i, + name: a, + msg: o + } = e; + let l = ""; + if ("data" in e) try { + const r = [], + n = []; + l = JSON.stringify(e.data, (e, t) => { + if ("object" == typeof t && null !== t) { + var i = n.indexOf(t); + if (-1 !== i) return `[Circular object reference: '${r[i]}']`; + r.push(e), n.push(t) + } + return t + }) + } catch (r) { + l = `Log serialization error: "${r}"` + } + r(`${function(){const e=new Date(s),t=e.getTimezoneOffset(),i=He(Math.floor(Math.abs(t)/60)),r=He(Math.abs(t)%60);let n=t<=0?"UTC+"+i:"UTC-"+i;return n=r?n+":"+r:n,e.getFullYear()+"-"+He(e.getMonth()+1)+"-"+He(e.getDate())+" "+He(e.getHours())+":"+He(e.getMinutes())+":"+He(e.getSeconds())+"."+(e.getMilliseconds()/1e3).toFixed(3).slice(2,5)+" "+n}()}| [SessionID: ${t}] | [${n}] >${i?" [QE Critical]":""} [${a}] ${o||""} ${l}`) + } + + function He(e) { + return e < 10 ? "0" + e : e.toString() + } + + function je(e, t = 1 / 0) { + if (!e) return ""; + const i = new Uint8Array(e); + let r, n = ""; + for (r = 0; r < i.length && r < t; r++) { + let e = i[r].toString(16); + e.length < 2 && (e = "0" + e), n += e + } + return n + } + const Qe = () => (Ue || (Ue = Oe($e()).child({ + name: "hls" + }), Ue.qe = e => Ue.info(e), Ue.warn("getLogger called without hls object instantiated, returning a logger that is not configured")), Ue), + We = { + bin2str: e => String.fromCharCode.apply(null, Array.from(e)), + readUint16(e, t) { + t = e[t] << 8 | e[t + 1]; + return t < 0 ? 65536 + t : t + }, + readSint32: (e, t) => e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3], + readUint32(e, t) { + t = We.readSint32(e, t); + return t < 0 ? 4294967296 + t : t + }, + writeUint32(e, t, i) { + e[t] = i >> 24, e[t + 1] = i >> 16 & 255, e[t + 2] = i >> 8 & 255, e[t + 3] = 255 & i + }, + readUint64(e, t) { + var i = We.readUint32(e, t); + return i *= Math.pow(2, 32), i += We.readUint32(e, t + 4) + }, + writeUint64(e, t, i) { + var r = Math.pow(2, 32) - 1, + n = Math.floor(i / (1 + r)), + r = Math.floor(i % (1 + r)); + We.writeUint32(e, t, n), We.writeUint32(e, t + 4, r) + }, + findBox(e, t) { + let i, r, n, s, a, o = []; + if (!t.length) return []; + for (i = 0; i < e.byteLength;) r = We.readUint32(e, i), n = We.bin2str(e.subarray(i + 4, i + 8)), s = 1 < r ? i + r : e.byteLength, n === t[0] && (1 === t.length ? o.push(e.subarray(i + 8, s)) : (a = We.findBox(e.subarray(i + 8, s), t.slice(1))).length && (o = o.concat(a))), i = s; + return o + }, + findBoxWithOffset(e, t, i, r) { + let n, s, a, o, l, d = []; + if (!i.length) return []; + for (n = 0; n < e.byteLength;) s = We.readUint32(e, n), a = We.bin2str(e.subarray(n + 4, n + 8)), o = 1 < s ? n + s : e.byteLength, a === i[0] && (r && r.push({ + offset: n + t, + type: a, + size: s + }), 1 === i.length ? d.push({ + offset: n + t, + type: a, + data: e.subarray(n + 8, o), + boxSize: s, + walkedPath: r ? r.slice(0) : void 0 + }) : (l = We.findBoxWithOffset(e.subarray(n + 8, o), n + t + 8, i.slice(1), r ? r.slice(0) : void 0)).length && (d = d.concat(l), r = r ? r.slice(0, -1) : void 0)), n = o; + return d + } + }, + Ge = { + name: "MP4EncryptionRemuxer" + }; + class ze extends h { + constructor(e, t, i, r, n) { + super(e, t, n) + } + static _isCommonEncryptionInternal(e) { + return Boolean(e && !("NONE" === e || "AES-128" === e)) + } + static remuxInitSegment(c, h, p, f) { + if (!p) return c; + let e = c; + if (ze._isCommonEncryptionInternal(p.method)) { + const m = p.keyId; + let u = !1; + const g = []; + if (We.findBoxWithOffset(c, 0, ["moov", "trak"]).forEach(t => { + const o = t.data; + let l, i = 0; + const d = We.findBoxWithOffset(o, 0, ["mdia", "minf", "stbl", "stsd"], [])[0], + e = d.data.subarray(8); + let r = !0, + n = We.findBoxWithOffset(e, d.offset + 16, ["enca"]); + 0 === n.length && (r = !1, n = We.findBoxWithOffset(e, d.offset + 16, ["encv"])), n.forEach(s => { + let e = null, + a = null; + i = r ? (e = s.data.subarray(28), l = "audio", d.offset + 16 + 8 + 28) : (e = s.data.subarray(78), l = "video", d.offset + 16 + 8 + 78), e && We.findBoxWithOffset(e, i, ["sinf"]).forEach(e => { + const t = e.data, + i = We.findBox(t, ["frma"])[0], + r = We.findBox(t, ["schm"])[0]; + if (i) + if (r) { + var n = We.bin2str(r.subarray(4, 8)); + if ("aac " === We.bin2str(i.subarray(0, 4)) && (ge.types || ge.init(), i.set(ge.types.mp4a, 0)), "cbcs" === n || "cenc" === n) { + f && f.push(t); + const e = We.findBox(t, ["schi", "tenc"])[0]; + if (e) { + const h = 8; + e.subarray(8, 24), e.set(m, 8); + const f = e[6], + t = e[7]; + if (1 === f && 0 === t) { + const h = e[24]; + 0 < h && p.iv && h === p.iv.length && e.set(p.iv, 25) + } + } + } else if ("cbc2" === n) { + u = !0, ge.types || ge.init(); + const h = We.findBoxWithOffset(t, 0, ["frma"])[0], + f = ge.box(ge.types.schi, ge.tenc(p, l)), + m = ge.box(ge.types.sinf, t.subarray(h.offset, h.boxSize), ge.schm(), f); + a = ge.box(ge.types.trak, o.subarray(0, e.offset), m, o.subarray(e.offset + e.boxSize)); + const i = a.subarray(8), + r = m.byteLength - e.boxSize; + d.walkedPath && (d.walkedPath.push({ + type: "stsd", + offset: s.offset, + size: s.boxSize + }), d.walkedPath.forEach(e => { + We.writeUint32(i, e.offset, e.size + r) + })) + } + } else h.error(Ge, "missing schm box"); + else h.error(Ge, "missing frma box") + }), a = a || c.subarray(t.offset, t.offset + t.boxSize), g.push(a) + }); + var s = We.findBoxWithOffset(o, 0, ["edts"])[0]; + s && (ge.types || ge.init(), o.set(ge.types.free, s.offset + 4)) + }), u) { + const p = ze.remuxCbc2InitSegment(c, g, h); + e = p || c + } + } + return e + } + static remuxCbc2InitSegment(i, r, n) { + const s = We.findBoxWithOffset(i, 0, ["ftyp"])[0]; + if (s) { + const a = We.findBoxWithOffset(i, s.boxSize, ["moov"])[0]; + let e = [], + t = 0; + for (; t < a.data.byteLength;) { + const i = We.readUint32(a.data, t), + n = We.bin2str(a.data.subarray(t + 4, t + 8)), + s = 1 < i ? t + i : a.data.byteLength; + "trak" === n ? r && (e = e.concat(r), r = void 0) : e.push(a.data.subarray(t, s)), t = s + } + const o = ge.box(ge.types.moov, ...e), + l = new Uint8Array(s.boxSize + o.byteLength); + return l.set(i.subarray(0, s.boxSize)), l.set(o, s.boxSize), l + } + n.error(Ge, "no ftyp found") + } + static remuxOverflowSegment(i, e) { + ge.types || ge.init(); + const t = We.findBoxWithOffset(i, 0, ["moof", "traf", "tfdt"], []); + let r, n = i.byteLength; + if (t.forEach(e => { + 0 === e.data[0] && (n += 4) + }), n > i.byteLength) { + r = new Uint8Array(n); + let e = 0, + t = 0; + for (; t < i.byteLength;) { + const n = We.readUint32(i, t), + s = We.bin2str(i.subarray(t + 4, t + 8)), + a = 1 < n ? t + n : i.byteLength; + if ("moof" === s) { + const n = ze.remuxOverflowMoof(i.subarray(t + 8, a)); + r.set(n, e), e += n.byteLength + } else r.set(i.subarray(t, a), e), e += n; + t = a + } + } else e.warn(Ge, "no increase in size"); + return r || i + } + static remuxOverflowMoof(e) { + let t = 0; + const i = []; + for (; t < e.byteLength;) { + const r = We.readUint32(e, t); + if ("traf" === We.bin2str(e.subarray(t + 4, t + 8))) { + const s = ze.remuxOverflowTraf(e.subarray(t + 8, t + r)); + i.push(s) + } else i.push(e.subarray(t, t + r)); + t = 1 < r ? t + r : e.byteLength + } + const r = ge.box(ge.types.moof, ...i), + s = r.byteLength - e.byteLength - 8; + return We.findBoxWithOffset(r, 0, ["moof", "traf", "trun"], []).forEach(e => { + var t; + 0 != (1 & e.data[3]) && (t = We.readUint32(e.data, 8), We.writeUint32(e.data, 8, t + s)) + }), We.findBoxWithOffset(r, 0, ["moof", "traf", "saio"], []).forEach(t => { + const i = 1 & t.data[0]; + let r = 4; + 1 & t.data[3] && (r += 8); + var n = We.readUint32(t.data, r); + if (r += 4, i) + for (let e = 0; e < n; e++) { + const i = We.readUint64(t.data, r); + We.writeUint64(t.data, r, i + s), r += 8 + } else + for (let e = 0; e < n; e++) { + const i = We.readUint32(t.data, r); + We.writeUint32(t.data, r, i + s), r += 4 + } + }), r + } + static remuxOverflowTraf(e) { + let t = 0; + const i = []; + for (; t < e.byteLength;) { + var r, n = We.readUint32(e, t); + "tfdt" === We.bin2str(e.subarray(t + 4, t + 8)) && 0 === e[t + 8] ? (r = We.readUint32(e, t + 12), r = ge.box(ge.types.tfdt, new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, r >> 24, r >> 16 & 255, r >> 8 & 255, 255 & r])), i.push(r)) : i.push(e.subarray(t, t + n)), t = 1 < n ? t + n : e.byteLength + } + return ge.box(ge.types.traf, ...i) + } + remuxText(e, t) { + e.captionSamples.sort(function(e, t) { + return e.pts - t.pts + }), e.captionSamples.length && (t.captionData || (t.captionData = {}), t.captionData.mp4 = e.captionSamples), e.captionSamples = [] + } + remuxIFrame(e, t, i, r, n) { + if (!t.samples || !t.samples.length || !t.samples[0].data) return null; + let s; + const a = ge.moof(e * t.timescale, t), + o = new Uint8Array(a.byteLength + t.samples[0].data.byteLength + 8); + o.set(a), We.writeUint32(o, a.byteLength, t.samples[0].data.byteLength + 8), o.set(ge.types.mdat, a.byteLength + 4), o.set(t.samples[0].data, a.byteLength + 8), t.sequenceNumber++; + var l = t.timescale, + d = B(e + r, l), + l = B(e, l); + let u, c; + u = i ? (s = "audiovideo", i.sequenceNumber = t.sequenceNumber, t.sequenceNumber++, c = Te.getSegment(i, i.sequenceNumber, e * i.info.timescale, r), y(c.endTs, d)) : (s = "video", d); + n = { + data1: o, + data2: null == c ? void 0 : c.silentFragData, + startPTS: l, + startDTS: l, + endPTS: u, + endDTS: u, + type: s, + dropped: 0, + track: n + }; + this.observer.trigger(v.FRAG_PARSING_DATA, n), this.observer.trigger(v.FRAG_PARSED) + } + remuxEmsgAndRawData(e, t, i, r, n, s, a, o, l, d) { + let u; + t && r ? u = "audiovideo" : t ? u = "audio" : r && (u = "video"); + const c = Math.max(i, e), + h = { + data1: l, + track: d, + startPTS: B(a, o), + startDTS: B(a, o), + endPTS: void 0, + endDTS: void 0, + type: u, + dropped: 0 + }; + return c && (h.endPTS = B(a + c, o), h.endDTS = B(a + c, o)), n && n.captionSamples.length && this.remuxText(n, h), s && 0 < s.id3Samples.length && this.remuxID3(s, h), this.observer.trigger(v.FRAG_PARSING_DATA, h), this.observer.trigger(v.FRAG_PARSED), h + } + remuxID3(t, e) { + let i; + var r = t.id3Samples.length; + if (r) { + for (let e = 0; e < r; e++) i = t.id3Samples[e], i.pts = i.pts - 10, i.dts = i.dts - 10; + e.id3Samples = [...t.id3Samples] + } + t.id3Samples = [] + } + } + const Xe = Math.pow(2, 32) - 1, + Ye = Math.pow(2, 20) - 1, + Je = { + name: "MP4Demuxer" + }; + class Ze extends u { + constructor(e, t, i, r, n) { + super(e, t, i, {}, n), this.mp4Remuxer = t, this.audioPrimingDelay = i.audioPrimingDelay + } + resetTimeStamp(e) { + ne(e) ? this.initData.audio && !this.initData.video ? this.initPtsTs = { + baseTime: Math.round(e * this.initData.audio.timescale / 9e4), + timescale: this.initData.audio.timescale + } : this.initPtsTs = { + baseTime: e, + timescale: 9e4 + } : this.initPtsTs = void 0 + } + static isHEVCFlavor(e) { + if (!e) return !1; + var t = e.indexOf("."), + t = t < 0 ? e : e.substring(0, t); + return "hvc1" === t || "hev1" === t || "chvc" === t || "qhvc" === t || "qhev" === t || "muxa" === t || "dvh1" === t || "dvhe" === t || "cdh1" === t || "qdh1" === t || "qdhe" === t + } + resetInitSegment(t, i, r) { + if (this._silentAudioTrack = void 0, t && t.byteLength) { + var n = ze.remuxInitSegment(t, this.logger, r), + s = this.initData = Ze.parseInitSegment(n); + let e; + s.foundLargeTimescale && this.logger.warn(Je, "large timescale found, will check for 32 bit tfdts"); + var a = s.audioCodec, + r = s.videoCodec; + if (s.audio && s.video ? e = { + type: "audiovideo", + container: "video/mp4", + codec: a + "," + r, + initSegment: n + } : (s.audio && a && (e = { + type: "audio", + container: "audio/mp4", + codec: a, + initSegment: n + }), s.video && r && (e = { + type: "video", + container: "video/mp4", + codec: r, + initSegment: n + })), s.video) { + const o = s.video, + l = t.subarray(o.trakOffset, o.trakOffset + o.trakSize); + this._videoTrack = Object.assign(Object.assign({}, o), { + info: { + id: o.id, + timescale: o.timescale, + duration: i + }, + trakData: l, + sequenceNumber: 0, + samples: [] + }), this.trySEICaptions = !be.isVP09(r), this._captionTrack = Object.assign(Object.assign({}, s.caption), { + sequenceNumber: 0, + captionSamples: [] + }) + } + s.audio && a && (this._audioTrack = Object.assign({}, s.audio)), s.caption && (this.trySEICaptions = !1, this._captionTrack = Object.assign(Object.assign({}, s.caption), { + sequenceNumber: 0, + captionSamples: [] + })), this.remuxedInitDataTrack = e; + s = { + track: e + }; + this.observer.trigger(v.FRAG_PARSING_INIT_SEGMENT, s) + } + } + static probe(e, t) { + return 0 < We.findBox(e.subarray(0, Math.min(e.length, 512e3)), ["moof"]).length + } + static parseHvcC(e) { + let t; + var i, r; + return e ? 1 === (i = e[0]) ? (r = e[1], t = { + profileSpace: r >> 6, + tierFlag: (32 & r) >> 5 ? "H" : "L", + profileIDC: 31 & r, + profileCompat: We.readUint32(e, 2), + constraintIndicator: e.subarray(6, 12), + levelIDC: e[12] + }) : Qe().warn(Je, `Unhandled version ${i} in hvcC box`) : Qe().warn(Je, "No hvcC box"), t + } + static hvcCToCodecString(t, i) { + const r = t + "." + (i.profileSpace ? String.fromCharCode(i.profileSpace + "A" - 1) : "") + i.profileIDC + "." + i.profileCompat.toString(16).toUpperCase() + "." + i.tierFlag + i.levelIDC; + let n = ""; + for (let e = i.constraintIndicator.length - 1; 0 <= e; --e) { + const r = i.constraintIndicator[e]; + if (0 !== r || "" !== n) { + const t = r.toString(16).toUpperCase(); + n = "." + ("" === n ? t : t + n) + } + } + return r + n + } + static parseDvcC(e) { + let t; + return e ? t = { + versionMajor: e[0], + versionMinor: e[1], + profile: e[2] >> 1 & 127, + level: e[2] << 5 & 32 | e[3] >> 3 & 31 + } : Qe().warn(Je, "No dvcC box"), t + } + static dvcCToCodecString(e, t) { + return e + "." + Ze.checkAndAddLeadingZero(t.profile) + "." + Ze.checkAndAddLeadingZero(t.level) + } + static parseVpcC(e) { + let t; + return e ? t = { + profile: e[4], + level: e[5], + bitDepth: e[6] >> 4 & 15 + } : Qe().warn(Je, "No vpcC box"), t + } + static vpcCToCodecString(e, t) { + return e + "." + Ze.checkAndAddLeadingZero(t.profile) + "." + Ze.checkAndAddLeadingZero(t.level) + "." + Ze.checkAndAddLeadingZero(t.bitDepth) + } + static checkAndAddLeadingZero(e) { + return (e < 10 ? "0" : "") + e + } + static parseInitSegment(e) { + const c = { + foundLargeTimescale: !1, + tracksById: {} + }; + return We.findBoxWithOffset(e, 0, ["moov", "trak"]).forEach(t => { + const i = t.data, + r = We.findBox(i, ["tkhd"])[0]; + if (r) { + var n = 0 === (a = r[0]) ? 12 : 20, + s = We.readUint32(r, n), + e = We.findBox(i, ["mdia", "mdhd"])[0]; + if (e) { + var a, o = 0 === (a = e[0]) ? 12 : 20, + n = We.readUint32(e, o); + o += 4, 1e6 <= n && (c.foundLargeTimescale = !0); + const l = 0 === a ? We.readUint32(e, o) : 0, + d = We.findBox(i, ["mdia", "hdlr"])[0]; + if (d) { + const r = We.bin2str(d.subarray(8, 12)), + u = { + soun: "audio", + vide: "video", + clcp: "caption" + } [r] || r; + if (u) { + const r = We.findBox(i, ["mdia", "minf", "stbl", "stsd"]); + if (r.length) { + const i = r[0]; + We.bin2str(i.subarray(12, 16)); + o = Ze.parseStsd(i); + let e; + if ("caption" === u) { + const t = Object.assign({ + id: s, + type: u, + timescale: n, + duration: l, + isTimingTrack: !1, + sequenceNumber: 0, + captionSamples: [] + }, o); + c.caption = t, e = t + } else { + const i = Object.assign({ + id: s, + type: u, + timescale: n, + duration: l, + isTimingTrack: !0, + trakOffset: t.offset, + trakSize: t.boxSize, + sequenceNumber: 0, + samples: [], + fragmentDuration: 0 + }, o); + "video" === u ? (c.video = i, c.videoCodec = i.codec) : (c.audio = i, c.audioCodec = i.codec), e = i + } + c.tracksById[s] = e + } + } + } + } + } + }), We.findBoxWithOffset(e, 0, ["moov", "mvex", "trex"]).forEach(e => { + var t = e.data, + e = We.readUint32(t, 4), + t = We.readUint32(t, 16); + c.tracksById[e].defaultSampleSize = t + }), c + } + static parseStsd(e) { + let r, t; + const i = e.subarray(8); + let n = We.bin2str(i.subarray(4, 8)), + s = null, + a = null; + "enca" === n ? (s = We.findBox(i, ["enca"])[0], a = s.subarray(28)) : "encv" === n && (s = We.findBox(i, ["encv"])[0], a = s.subarray(78)); + e = !!a; + r = 0, a && We.findBox(a, ["sinf"]).forEach(e => { + const t = We.findBox(e, ["schm"])[0]; + if (t) { + var i = We.bin2str(t.subarray(4, 8)); + if ("cbcs" === i || "cenc" === i) { + const t = We.findBox(e, ["frma"])[0]; + t && (n = We.bin2str(t)); + e = We.findBox(e, ["schi", "tenc"])[0]; + e && (r = e[7]) + } + } + }); + let o; + var l = i.subarray(86); + switch (n) { + case "mp4a": + t = "mp4a.40.5"; + break; + case "ac-3": + case "ec-3": + case "alac": + case "fLaC": + t = n; + break; + case "avc1": + case "avc3": + t = n + ".640028"; + break; + case "hvc1": + case "hev1": + const d = We.findBox(l, ["hvcC"])[0]; + o = Ze.parseHvcC(d), t = o ? Ze.hvcCToCodecString(n, o) : n + ".2.4.H150.B0"; + break; + case "dvh1": + case "dvhe": + const r = We.findBox(l, ["dvcC"])[0]; + o = Ze.parseDvcC(r), t = o ? Ze.dvcCToCodecString(n, o) : n + ".05.01"; + break; + case "c608": + t = n; + break; + case "vp09": + const i = We.findBox(l, ["vpcC"])[0]; + o = Ze.parseVpcC(i), t = Ze.vpcCToCodecString(n, o); + break; + default: + t = n + } + return { + codec: t, + encrypted: e, + defaultPerSampleIVSize: r + } + } + static has32BitTfdts(e) { + const t = We.findBox(e, ["moof", "traf", "tfdt"]); + let i = !1; + return t.forEach(e => { + 0 === e[0] && (i = !0) + }), i + } + static getStartDtsTs(r, e) { + const t = We.findBox(e, ["moof", "traf"]); + let n, s = Number.MAX_SAFE_INTEGER; + return t.map(function(i) { + return We.findBox(i, ["tfhd"]).forEach(e => { + var t = We.readUint32(e, 4), + e = r.tracksById[t]; + if (e) { + if (!e.isTimingTrack) return 1 / 0; + t = e.timescale || 9e4, e = We.findBox(i, ["tfdt"]).map(function(e) { + let t; + var i = e[0]; + return t = We.readUint32(e, 4), 1 === i && (t > Ye && Qe().warn(Je, `Value larger than can be represented by float for upper 32 bits ${t}`), t *= Math.pow(2, 32), t += We.readUint32(e, 8)), t + }), e = 0 < e.length ? e[0] : 1 / 0; + isFinite(e) && e / t < s && (s = e / t, n = { + baseTime: e, + timescale: t + }) + } + }) + }), n + } + static offsetStartDTS(r, e, l, n) { + We.findBox(e, ["moof", "traf"]).map(function(i) { + return We.findBox(i, ["tfhd"]).map(function(e) { + const t = We.readUint32(e, 4), + s = r.tracksById[t]; + if (s) { + const a = s.timescale || 9e4, + o = "caption" === s.type ? 0 : n; + We.findBox(i, ["tfdt"]).map(function(t) { + const i = t[0], + r = s.type; + if (0 === i) { + let e = We.readUint32(t, 4) - Math.round(l.baseTime * a / l.timescale); + "video" === r && e < 0 && (Qe().warn(Je, `video tdft would have gone negative by ${e/a} seconds`), e = 0), e += Math.round(o * a), e = Math.max(e, 0), We.writeUint32(t, 4, e) + } else { + const i = We.readUint32(t, 4); + i > Ye && Qe().error(Je, `baseMediaDecodeTime larger than can be represented by float for upper 32 bits ${i}`); + let e = i; + e *= Math.pow(2, 32), e += We.readUint32(t, 8), e -= Math.round(l.baseTime * a / l.timescale), "video" === r && e < 0 && (Qe().warn(Je, `video tdft would have gone negative by ${e/a} seconds`), e = 0), e += Math.round(o * a), e = Math.max(e, 0); + const n = Math.floor(e / (1 + Xe)), + s = Math.floor(e % (1 + Xe)); + We.writeUint32(t, 4, n), We.writeUint32(t, 8, s) + } + }) + } + }) + }) + } + static writeStartDTS(i, e, s) { + We.findBox(e, ["moof", "traf"]).map(function(t) { + return We.findBox(t, ["tfhd"]).map(function(e) { + e = We.readUint32(e, 4), e = i.tracksById[e]; + if (e) { + const r = e.timescale || 9e4, + n = Math.round(s * r) / r; + .01 < Math.abs(n - s) && Qe().warn(Je, `[iframes] large rounding error when adjusting timestamps, startDTS: ${s}, roundedStartDTS: ${n}`), We.findBox(t, ["tfdt"]).map(function(e) { + var t, i; + 0 === e[0] ? We.writeUint32(e, 4, n * r) : (i = n * r, i = Math.max(i, 0), t = Math.floor(i / (1 + Xe)), i = Math.floor(i % (1 + Xe)), We.writeUint32(e, 4, t), We.writeUint32(e, 8, i)) + }) + } + }) + }) + } + static parseSAIO(e) { + let t = 0, + i = 0; + var r = e[0]; + i += 4, 0 != (1 & We.readUint32(e, 0)) && (i += 8); + var n = 16777215 & We.readUint32(e, i); + return 1 == n ? (i += 4, t = We.readUint32(e, i), 1 === r && (i += 4, t *= Math.pow(2, 32), t += We.readUint32(e, i))) : Qe().error(Je, `saio entry count error, count is: ${n}`), t + } + static parseSAIZ(e) { + let t = 0, + i = 0; + return i += 4, 0 != (1 & We.readUint32(e, 0)) && (i += 8), t = e[i], i++, i += 4, 0 === t && (t = e[i]), t + } + static parseSubsample(e, t) { + const i = { + subsamples: [] + }; + let r = 0; + for (e && (i.iv = t.subarray(0, e), r += e), r += 2; r + 6 <= t.byteLength;) { + const e = We.readUint16(t, r); + r += 2; + var n = We.readUint32(t, r); + r += 4, i.subsamples.push([e, n]) + } + return i + } + static isSEIMessage(e, t) { + return e ? 39 === t || 40 === t : 6 === t + } + static parseCLCPSample(e, t, i) { + let r = 0; + const n = []; + let s = 0; + for (; r < i;) { + var a = t + r, + o = We.readUint32(e, a); + a += 4; + var l = We.bin2str(e.subarray(a, a + 4)); + if (a += 4, "cdat" !== l) break; { + const t = o - 8, + d = e.subarray(a, a + t); + s += t, n.push(d), r += o + } + } + return { + cdatList: n, + cdatTotalSize: s + } + } + static parseSamples(e, S, b, T, E, I) { + const w = b.timescale, + d = b.id; + let A, O = e, + k = 0, + C = !1; + We.findBoxWithOffset(S, 0, ["moof"]).map(function(e) { + const t = e.data, + v = e.offset; + We.findBox(t, ["traf"]).map(function(l) { + var e = We.findBox(l, ["tfdt"]).map(function(e) { + let t; + var i = e[0]; + return t = We.readUint32(e, 4), 1 === i && (t *= Math.pow(2, 32), t += We.readUint32(e, 8)), t / w + })[0]; + return void 0 !== e && (O = e), We.findBox(l, ["tfhd"]).map(function(e) { + var t = We.readUint32(e, 4), + i = 16777215 & We.readUint32(e, 0), + r = 0 != (1 & i), + n = 0 != (2 & i), + s = 0 != (8 & i); + let g = 0; + var a = 0 != (16 & i); + let y = 0; + i = 0 != (32 & i); + let o = 8; + if (ne(b.defaultSampleSize) && (y = b.defaultSampleSize), t === d) { + if (r && (We.readUint32(e, o), o += 4, We.readUint32(e, o), o += 4), n && (We.readUint32(e, o), o += 4), s && (g = We.readUint32(e, o), o += 4), a && (y = We.readUint32(e, o), o += 4), i && (We.readUint32(e, o), o += 4), "video" === b.type) { + let t = 0, + i = 0; + We.findBox(l, ["saio"]).map(function(e) { + t = Ze.parseSAIO(e) + }), We.findBox(l, ["saiz"]).map(function(e) { + i = Ze.parseSAIZ(e) + }), t && i && (A = Ze.parseSubsample(b.defaultPerSampleIVSize, S.subarray(t, t + i))), C = Ze.isHEVCFlavor(b.codec) + } + We.findBox(l, ["trun"]).map(function(i) { + var t = i[0], + e = 16777215 & We.readUint32(i, 0), + r = 0 != (1 & e); + let n = 0; + var s = 0 != (4 & e), + a = 0 != (256 & e); + let o = 0; + var l = 0 != (512 & e); + let d = 0; + var u = 0 != (1024 & e), + c = 0 != (2048 & e); + let h = 0; + var p = We.readUint32(i, 4); + let f = 8; + r && (n = We.readUint32(i, f), f += 4), s && (f += 4); + let m = n + v; + for (let e = 0; e < p && (I < 0 || k < I); e++) { + if (a ? (o = We.readUint32(i, f), f += 4) : o = g, l ? (d = We.readUint32(i, f), f += 4) : d = y, u && (f += 4), c && (h = 0 === t ? We.readUint32(i, f) : We.readSint32(i, f), f += 4), "video" === b.type) { + if (ne(T)) b.samples.push({ + data: S.subarray(m, m + d), + size: d, + duration: T * w, + cts: 0, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 2, + isNonSync: 0, + paddingValue: 0 + }, + subsamples: A ? A.subsamples : [], + iv: A ? A.iv : void 0 + }); + else if (b.fragmentDuration += o, E) { + let e = 0; + for (; e < d;) { + const T = We.readUint32(S, m); + m += 4; + const E = 31 & S[m]; + if (b.seiSamples || (b.seiSamples = []), Ze.isSEIMessage(C, E)) { + const i = S.subarray(m, m + T); + b.seiSamples.push({ + pts: O + h / w, + type: E, + data: i, + sampleOffset: m, + naluSize: T + }) + } + m += T, e += T + 4 + } + } + } else if ("audio" === b.type) b.fragmentDuration += o; + else if ("caption" === b.type) { + const { + cdatList: i, + cdatTotalSize: T + } = Ze.parseCLCPSample(S, m, d); + if (m += d, i.length) { + let t; + if (1 === i.length) t = new Uint8Array(i[0]); + else if (1 < i.length) { + let e = 0; + t = new Uint8Array(T); + for (const T of i) t.set(T, e), e += T.length + } + b.captionSamples.push({ + type: 3, + pts: O, + bytes: t + }) + } + } + k++, O += o / w + } + }) + } + }) + }) + }) + } + static parseEmsg(e) { + let t, i, r, n, s, a = "", + o = "", + l = 0; + if (0 === e[0]) { + for (; + "\0" !== We.bin2str(e.subarray(l, l + 1));) a += We.bin2str(e.subarray(l, l + 1)), l += 1; + for (a += We.bin2str(e.subarray(l, l + 1)), l += 1; + "\0" !== We.bin2str(e.subarray(l, l + 1));) o += We.bin2str(e.subarray(l, l + 1)), l += 1; + o += We.bin2str(e.subarray(l, l + 1)), l += 1, t = We.readUint32(e, 12), i = We.readUint32(e, 16), n = We.readUint32(e, 20), s = We.readUint32(e, 24), l = 28 + } else { + l += 4, t = We.readUint32(e, l), l += 4; + const i = We.readUint32(e, l); + l += 4; + var d = We.readUint32(e, l); + for (l += 4, r = Math.pow(2, 32) * i + d, Number.isSafeInteger(r) || (r = Number.MAX_SAFE_INTEGER, Qe().warn(Je, "Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box")), n = We.readUint32(e, l), l += 4, s = We.readUint32(e, l), l += 4; + "\0" !== We.bin2str(e.subarray(l, l + 1));) a += We.bin2str(e.subarray(l, l + 1)), l += 1; + for (a += We.bin2str(e.subarray(l, l + 1)), l += 1; + "\0" !== We.bin2str(e.subarray(l, l + 1));) o += We.bin2str(e.subarray(l, l + 1)), l += 1; + o += We.bin2str(e.subarray(l, l + 1)), l += 1 + } + return { + schemeIdUri: a, + value: o, + timeScale: t, + presentationTime: r, + presentationTimeDelta: i, + eventDuration: n, + id: s, + payload: e.subarray(l, e.byteLength) + } + } + static extractID3PayloadCreateID3Track(e, t, i, r) { + const n = new M(e.payload, r), + s = new Uint8Array(e.payload), + a = s.byteLength; + let o = 0, + l = 0; + var d = ne(e.presentationTime) ? e.presentationTime / e.timeScale : t + e.presentationTimeDelta / e.timeScale; + if (ne(d)) { + const c = e.eventDuration, + h = s.subarray(0, 10), + p = We.bin2str(h.subarray(l, l + 3)); + l += 3, "ID3" !== p && Qe().error(Je, "No ID3 tag found when extracting ID3 payload"), l += 2; + var t = s.subarray(l, l + 1), + e = 64 & t[0], + u = 16 & t[0]; + if (l += 1, M.readSynchSafeUint32(s.subarray(l, l + 4)), l += 4, e) { + const f = M.readSynchSafeUint32(s.subarray(l, l + 4)); + l += 4, l += f + } + for (; l + 2 < a;) { + We.bin2str(s.subarray(l, l + 4)), l += 4; + const m = M.readSynchSafeUint32(s.subarray(l, l + 4)); + l += 4; + const r = d + o * c, + a = { + data: s, + pts: r, + dts: r, + keyTagInfo: void 0, + frames: n.frames + }; + i.id3Samples.push(a), l += m, o++, u && ("DI3" !== We.bin2str(s.subarray(l, l + 3)) && Qe().error(Je, "End should be DI3 if footer present in extracting ID3 payload"), l += 3, l += 7) + } + l + 2 === a && 0 !== We.readUint16(s, l) && Qe().warn(Je, "Padding should be 0 when extracting ID3 payload") + } else Qe().error(Je, "No pts found in emsg info when extracting ID3 payload") + } + append(e, t, i, r, n, s, a) { + let o = this.initData, + l = 0, + d = 0, + u = !1, + c = !1; + void 0 === o && (this.resetInitSegment(e, 0), o = this.initData); + let h, p = this.initPtsTs; + p || (h = Ze.getStartDtsTs(o, e), this.initPtsTs = p = { + baseTime: h.baseTime - Math.round(t * h.timescale), + timescale: h.timescale + }, this.observer.trigger(v.INIT_PTS_FOUND, { + initPTS: p + })), o.foundLargeTimescale && Ze.has32BitTfdts(e) && !a && (e = ze.remuxOverflowSegment(e, this.logger)), h = Ze.getStartDtsTs(o, e); + const f = We.findBox(e, ["emsg"]); + if (o.video && o.video.encrypted && (We.findBox(e, ["moof", "traf"]).find(function(e) { + return Boolean(We.findBox(e, ["senc"])[0] || We.findBox(e, ["saiz"])[0] && We.findBox(e, ["saio"])[0]) + }) || this.logger.warn(Je, `Missing subsample information for encrypted content codec=${o.videoCodec}`)), a) { + const t = this._videoTrack.timescale; + a = Math.ceil(a * t) / t; + const i = (h.baseTime + this.audioPrimingDelay * h.timescale) / h.timescale; + if (this._videoTrack && this._audioTrack && !this._silentAudioTrack) { + const e = Te.getTrack(this.observer, this._audioTrack.id, this._audioTrack.codec, 2, this.logger); + if (!e) throw `unable to create silent audio track for codec ${this._audioTrack.codec}`; + this._silentAudioTrack = Object.assign(Object.assign({}, e), { + sequenceNumber: 0 + }); + const t = ge.initSegment([this._videoTrack, this._silentAudioTrack]); + this.remuxedInitDataTrack = { + type: "audiovideo", + container: "video/mp4", + codec: this._silentAudioTrack.config.codec + "," + this._videoTrack.codec, + initSegment: t + }; + const i = { + track: this.remuxedInitDataTrack + }; + this.observer.trigger(v.FRAG_PARSING_INIT_SEGMENT, i) + } + Ze.parseSamples(i, e, this._videoTrack, a, !1, 1), this.mp4Remuxer.remuxIFrame(i, this._videoTrack, this._silentAudioTrack, a, this.remuxedInitDataTrack), this._videoTrack.samples = [] + } else { + a = (h.baseTime - this.audioPrimingDelay * h.timescale) / h.timescale, a = Math.max(0, a); + if (f && 0 < f.length) { + const e = f.map(e => { + e = Ze.parseEmsg(e); + return "https://aomedia.org/emsg/ID3\0" !== e.schemeIdUri || this._id3Track || (this._id3Track = { + id3Samples: [], + inputTimescale: 9e4 + }), e + }); + this._id3Track && e.map(e => { + Ze.extractID3PayloadCreateID3Track(e, t, this._id3Track, this.logger) + }) + } + this._videoTrack && (Ze.parseSamples(a, e, this._videoTrack, void 0, this.trySEICaptions, -1), l = this._videoTrack.fragmentDuration / this._videoTrack.timescale, u = !0, this._videoTrack.fragmentDuration = 0, this.trySEICaptions ? (Ze.extractSEICaptionsFromNALu(this._videoTrack.seiSamples, this._captionTrack), this._videoTrack.seiSamples = []) : this._captionTrack && Ze.parseSamples(a, e, this._captionTrack, void 0, !1, Number.MAX_SAFE_INTEGER)), this._audioTrack && (Ze.parseSamples(a, e, this._audioTrack, void 0, !1, -1), d = this._audioTrack.fragmentDuration / this._audioTrack.timescale, c = !0, this._audioTrack.fragmentDuration = 0), this.mp4Remuxer.remuxEmsgAndRawData(d, c, l, u, this._captionTrack, this._id3Track, a, h.timescale, e, this.remuxedInitDataTrack), this._id3Track && (this._id3Track.id3Samples = []) + } + } + static extractSEICaptionsFromNALu(a, o) { + if (a) { + for (let s = 0; s < a.length; ++s) { + var l = a[s], + d = l.pts; + let t = 0; + t++; + let e = 0, + i = 0, + r = !1, + n = 0; + for (; !r && t < l.data.length;) { + for (e = 0; !(t >= l.data.length) && (n = l.data[t++], e += n, 255 === n);); + for (i = 0; !(t >= l.data.length) && (n = l.data[t++], i += n, 255 === n);); + const a = l.data.length - t; + if (4 === e && t < l.data.length) { + if (r = !0, 181 === l.data[t++]) { + const a = We.readUint16(l.data, t); + if (t += 2, 49 === a) { + const a = We.readUint32(l.data, t); + if (t += 4, 1195456820 === a && 3 === l.data[t++]) { + const a = l.data[t++]; + t++; + const u = 31 & a, + c = []; + if (64 & a) + for (let e = 0; e < u; e++) { + const a = l.data[t++]; + if (a === (252 & a)) { + const o = 3 & a; + if (0 == o || 1 == o) { + const a = l.data[t++], + o = l.data[t++]; + c.push(a), c.push(o) + } + } else t += 2 + } + 0 < c.length && o.captionSamples.push({ + type: 3, + pts: d, + bytes: c + }) + } + } + } + } else if (i < a) t += i; + else if (i > a) break + } + } + return o + } + } + } + const et = { + name: "ExpGolomb" + }; + class tt { + constructor(e, t) { + this.data = e, this.logger = t, this._bytesAvailable = e.byteLength, this.word = 0, this.bitsAvailable = 0 + } + get bytesAvailable() { + return this._bytesAvailable + } + loadWord() { + const e = this.data, + t = this._bytesAvailable, + i = e.byteLength - t, + r = new Uint8Array(4), + n = Math.min(4, t); + if (0 === n) throw new Error("no bytes available"); + r.set(e.subarray(i, i + n)), this.word = new DataView(r.buffer).getUint32(0), this.bitsAvailable = 8 * n, this._bytesAvailable -= n + } + skipBits(e) { + var t; + this.bitsAvailable > e || (t = (e -= this.bitsAvailable) >> 3, e -= t >> 3, this._bytesAvailable -= t, this.loadWord()), this.word <<= e, this.bitsAvailable -= e + } + readBits(e) { + let t = Math.min(this.bitsAvailable, e); + var i = this.word >>> 32 - t; + return 32 < e && this.logger.error(et, "Cannot read more than 32 bits at a time"), this.bitsAvailable -= t, 0 < this.bitsAvailable ? this.word <<= t : 0 < this._bytesAvailable && this.loadWord(), t = e - t, 0 < t && this.bitsAvailable ? i << t | this.readBits(t) : i + } + skipLZ() { + let e; + for (e = 0; e < this.bitsAvailable; ++e) + if (0 != (this.word & 2147483648 >>> e)) return this.word <<= e, this.bitsAvailable -= e, e; + return this.loadWord(), e + this.skipLZ() + } + skipUEG() { + this.skipBits(1 + this.skipLZ()) + } + skipEG() { + this.skipBits(1 + this.skipLZ()) + } + readUEG() { + var e = this.skipLZ(); + return this.readBits(e + 1) - 1 + } + readEG() { + var e = this.readUEG(); + return 1 & e ? 1 + e >>> 1 : -1 * (e >>> 1) + } + readBoolean() { + return 1 === this.readBits(1) + } + readUByte() { + return this.readBits(8) + } + readUShort() { + return this.readBits(16) + } + readUInt() { + return this.readBits(32) + } + skipScalingList(e) { + let t, i, r = 8, + n = 8; + for (t = 0; t < e; t++) 0 !== n && (i = this.readEG(), n = (r + i + 256) % 256), r = 0 === n ? r : n + } + readSPS() { + let e, t, i, r = 0, + n = 0, + s = 0, + a = 0; + const o = this.readUByte.bind(this), + l = this.readBits.bind(this), + d = this.readUEG.bind(this), + u = this.readBoolean.bind(this), + c = this.skipBits.bind(this), + h = this.skipEG.bind(this), + p = this.skipUEG.bind(this), + f = this.skipScalingList.bind(this); + o(); + var m = o(); + if (l(5), c(3), o(), p(), 100 === m || 110 === m || 122 === m || 244 === m || 44 === m || 83 === m || 86 === m || 118 === m || 128 === m) { + const e = d(); + if (3 === e && c(1), p(), p(), c(1), u()) + for (t = 3 !== e ? 8 : 12, i = 0; i < t; i++) u() && f(i < 6 ? 16 : 64) + } + p(); + var g = d(); + if (0 === g) d(); + else if (1 === g) + for (c(1), h(), h(), e = d(), i = 0; i < e; i++) h(); + p(), c(1); + var y = d(), + m = d(), + g = l(1); + 0 === g && c(1), c(1), u() && (r = d(), n = d(), s = d(), a = d()); + let v = [1, 1]; + if (u() && u()) switch (o()) { + case 1: + v = [1, 1]; + break; + case 2: + v = [12, 11]; + break; + case 3: + v = [10, 11]; + break; + case 4: + v = [16, 11]; + break; + case 5: + v = [40, 33]; + break; + case 6: + v = [24, 11]; + break; + case 7: + v = [20, 11]; + break; + case 8: + v = [32, 11]; + break; + case 9: + v = [80, 33]; + break; + case 10: + v = [18, 11]; + break; + case 11: + v = [15, 11]; + break; + case 12: + v = [64, 33]; + break; + case 13: + v = [160, 99]; + break; + case 14: + v = [4, 3]; + break; + case 15: + v = [3, 2]; + break; + case 16: + v = [2, 1]; + break; + case 255: + v = [o() << 8 | o(), o() << 8 | o()] + } + return { + width: Math.ceil(16 * (y + 1) - 2 * r - 2 * n), + height: (2 - g) * (m + 1) * 16 - (g ? 2 : 4) * (s + a), + pixelRatio: v + } + } + readSliceType() { + return this.readUByte(), this.readUEG(), this.readUEG() + } + } + const it = { + name: "TS Demuxer" + }; + var rt, nt = class extends c { + constructor(e, t, i, r, n) { + super(e, t, i, r, n) + } + static probe(e, t) { + return 564 <= e.length && 71 === e[0] && 71 === e[188] && 71 === e[376] + } + resetInitSegment(e, t, i) { + this.pmtParsed = !1; + var r = { + id: this._pmtId = -1, + inputTimescale: 9e4, + timescale: NaN, + duration: 0, + encrypted: i && i.isEncrypted, + keyTagInfo: i + }, + i = { + len: 0, + sequenceNumber: 0 + }; + this._avcContext = { + info: Object.assign({}, r), + parsingData: Object.assign(Object.assign({}, i), { + esSamples: new Array, + dropped: 0 + }), + config: {}, + container: "video/mp2t", + type: "video" + }, this._audioContext = { + info: Object.assign({}, r), + parsingData: Object.assign(Object.assign({}, i), { + esSamples: new Array + }), + container: "video/mp2t", + type: "audio" + }, this._id3Track = { + id: -1, + inputTimescale: 9e4, + id3Samples: [] + }, this._txtTrack = { + inputTimescale: 9e4, + captionSamples: [] + }, this._duration = t, this._initSegment = e + } + append(e, t, i, r, n, s, a) { + let o, l, d, u, c, h = !1; + this.contiguous = i; + const p = this._avcContext, + f = this._audioContext, + m = this._id3Track; + let g = this.pmtParsed, + y = p.info.id, + v = f.info.id, + S = m.id, + b = this._pmtId, + T = p.pesData, + E = f.pesData, + I = m.pesData; + if (this.iframeMode = void 0 !== a, this._initSegment && 0 < this._initSegment.byteLength) { + const t = new Uint8Array(this._initSegment.byteLength + e.byteLength); + t.set(this._initSegment), t.set(e, this._initSegment.byteLength), this._initSegment = void 0, 71 === t[0] && (e = t) + } + let w, A, O = e.length; + for (O -= O % 188, o = 0; o < O; o += 188) { + if (71 !== e[o]) { + const e = new D(!1, "TS packet did not start with 0x47", $.NoTSSyncByteFound); + return void this.observer.trigger(x.INTERNAL_ERROR, e) + } + if (l = !!(64 & e[o + 1]), d = ((31 & e[o + 1]) << 8) + e[o + 2], 1 < (48 & e[o + 3]) >> 4) { + if (u = o + 5 + e[o + 4], u === o + 188) continue + } else u = o + 4; + switch (d) { + case y: + l && (T && (c = this._parsePES(T)) && this._parseAVCPES(c, !1), T = { + data: [], + size: 0, + keyTagInfo: n + }), T && (T.data.push(e.subarray(u, o + 188)), T.size += o + 188 - u); + break; + case v: + if (l && !this.iframeMode) { + if (E && (c = this._parsePES(E))) switch (f.segmentCodec) { + case "aac": + this._parseAACPES(c); + break; + case "mp3": + this._parseMPEGPES(c); + break; + case "ac3": + case "ec3": + this._parseDolbyPES(c) + } + E = { + data: [], + size: 0, + keyTagInfo: n + } + } + E && (E.data.push(e.subarray(u, o + 188)), E.size += o + 188 - u); + break; + case S: + l && (I && (c = this._parsePES(I)) && m.id3Samples.push(c), I = { + data: [], + size: 0 + }), I && (I.data.push(e.subarray(u, o + 188)), I.size += o + 188 - u); + break; + case 0: + l && (u += e[u] + 1), b = this._pmtId = this._parsePAT(e, u); + break; + case b: + l && (u += e[u] + 1); + const t = this._parsePMT(e, u, this.typeSupported); + y = t.avcId, 0 < y && (p.info.id = y, p.info.encrypted = t.videoEncrypted), v = t.audioId, 0 < v && (f.info.id = v, f.segmentCodec = t.audioSegmentCodec, f.info.encrypted = t.audioEncrypted), S = t.id3Id, 0 < S && (m.id = S), h && !g && (h = !1, o = -188), g = this.pmtParsed = !0; + break; + case 17: + case 8191: + break; + default: + h = !0 + } + } + if (T && (c = this._parsePES(T)) ? (this._parseAVCPES(c, !0), p.pesData = void 0) : p.pesData = T, E && (c = this._parsePES(E))) { + switch (f.segmentCodec) { + case "aac": + this._parseAACPES(c); + break; + case "mp3": + this._parseMPEGPES(c); + break; + case "ac3": + case "ec3": + this._parseDolbyPES(c) + } + f.pesData = void 0 + } else E && E.size && this.logger.warn(it, "last AAC PES packet truncated,might overlap between fragments"), f.pesData = E; + I && (c = this._parsePES(I)) ? (m.id3Samples.push(c), m.pesData = void 0) : m.pesData = I, f.config && f.segmentCodec && (w = { + type: "audio", + info: f.info, + config: f.config, + parsingData: f.parsingData + }); + var k, C = p.config; + "string" == typeof(k = C).codec && Array.isArray(k.sps) && Array.isArray(k.pps) && "number" == typeof k.width && "number" == typeof k.height && Array.isArray(k.pixelRatio) && (A = { + type: "video", + info: p.info, + config: C, + parsingData: p.parsingData + }), this.esRemuxer.remuxEsTracks(w, A, m, this._txtTrack, t, i, r, n, s, a) + } + destroy() { + this._duration = 0 + } + _parsePAT(e, t) { + return (31 & e[t + 10]) << 8 | e[t + 11] + } + _parsePMT(e, t, i) { + var r; + const n = { + audioId: -1, + avcId: -1, + id3Id: -1, + audioEncrypted: !1, + videoEncrypted: !1 + }, + s = t + 3 + ((15 & e[t + 1]) << 8 | e[t + 2]) - 4; + for (t += 12 + ((15 & e[t + 10]) << 8 | e[t + 11]); t < s;) { + switch (r = (31 & e[t + 1]) << 8 | e[t + 2], e[t]) { + case 207: + n.audioEncrypted = !0; + case 15: + -1 === n.audioId && (n.audioId = r, n.audioSegmentCodec = "aac"); + break; + case 21: + -1 === n.id3Id && (n.id3Id = r); + break; + case 219: + n.videoEncrypted = !0; + case 27: + -1 === n.avcId && (n.avcId = r); + break; + case 3: + case 4: + !0 !== i.mpeg && !0 !== i.mp3 ? this.logger.warn(it, "MPEG audio found, not supported in this browser for now") : -1 === n.audioId && (n.audioId = r, n.audioSegmentCodec = "mp3"); + break; + case 193: + n.audioEncrypted = !0; + case 129: + !0 !== i.ac3 ? this.logger.warn(it, "AC-3 audio found, not supported in this browser for now") : -1 === n.audioId && (n.audioId = r, n.audioSegmentCodec = "ac3"); + break; + case 194: + n.audioEncrypted = !0; + case 135: + !0 !== i.ec3 ? this.logger.warn(it, "EC-3 audio found, not supported in this browser for now") : -1 === n.audioId && (n.audioId = r, n.audioSegmentCodec = "ec3"); + break; + case 36: + this.logger.warn(it, "HEVC stream type found, not supported for now"); + break; + default: + this.logger.warn(it, "unkown stream type:" + e[t]) + } + t += 5 + ((15 & e[t + 3]) << 8 | e[t + 4]) + } + return n + } + _parsePES(e) { + let i, t, r, n, s, a, o = 0; + const l = e.data, + d = e.keyTagInfo; + let u = NaN, + c = NaN; + if (e && 0 !== e.size) { + for (; l[0].length < 19 && 1 < l.length;) { + const e = new Uint8Array(l[0].length + l[1].length); + e.set(l[0]), e.set(l[1], l[0].length), l[0] = e, l.splice(1, 1) + } + if (i = l[0], 1 === (i[0] << 16) + (i[1] << 8) + i[2] && (r = (i[4] << 8) + i[5], !(r && r > e.size - 6))) { + 192 & (t = i[7]) && (u = 536870912 * (14 & i[9]) + 4194304 * (255 & i[10]) + 16384 * (254 & i[11]) + 128 * (255 & i[12]) + (254 & i[13]) / 2, 64 & t ? (c = 536870912 * (14 & i[14]) + 4194304 * (255 & i[15]) + 16384 * (254 & i[16]) + 128 * (255 & i[17]) + (254 & i[18]) / 2, 54e5 < u - c && (this.logger.warn(it, `${Math.round((u-c)/9e4)}s delta between PTS and DTS, align them`), u = c)) : c = u), n = i[8], a = n + 9, e.size -= a, s = new Uint8Array(e.size); + for (let t = 0, e = l.length; t < e; t++) { + i = l[t]; + let e = i.byteLength; + if (a) { + if (a > e) { + a -= e; + continue + } + i = i.subarray(a), e -= a, a = 0 + } + s.set(i, o), o += e + } + return r && (r -= n + 3), { + data: s, + pts: u, + dts: c, + len: r, + keyTagInfo: d + } + } + } + } + pushAccesUnit(e, t) { + const i = e.avcSample; + if (i && i.units.length && i.frame) { + const r = e.parsingData.esSamples, + n = r.length; + (!0 === i.key || e.config.sps && (n || this.contiguous)) && (i.id = n, i.keyTagInfo = t, e.info.encrypted) && i.units.forEach(e => { + if (48 < e.data.byteLength) switch (e.type) { + case 1: + case 5: + e.data = this.discardEPB(e.data) + } + }), n || isFinite(i.pts) ? r.push(i) : e.parsingData.dropped++ + } + } + _parseAVCPES(o, e) { + if (!o.data) throw "invalid pes data"; + const l = this._avcContext, + t = this._parseAVCNALu(o.data); + let d, u, c, h = l.avcSample; + const p = o.keyTagInfo; + o.data = void 0, t.forEach(n => { + switch (n.type) { + case 1: + if (h && !this.iframeMode) { + u = !0, h.frame = !0; + const o = n.data; + if (4 < o.length) { + const n = new tt(o, this.logger).readSliceType(); + 2 !== n && 4 !== n && 7 !== n && 9 !== n || (h.key = !0) + } + } + break; + case 5: + u = !0, h && (h = h || (l.avcSample = this._createAVCSample(!0, o.pts, o.dts, "")), h.key = !0, h.frame = !0); + break; + case 6: + u = !0, d = new tt(this.discardEPB(n.data), this.logger), d.readUByte(); + let e = 0, + t = 0, + i = !1, + r = 0; + for (; !i && 1 < d.bytesAvailable;) { + for (e = 0; r = d.readUByte(), e += r, 255 === r;); + for (t = 0; r = d.readUByte(), t += r, 255 === r;); + if (4 === e && 0 !== d.bytesAvailable) { + if (i = !0, 181 === d.readUByte() && 49 === d.readUShort() && 1195456820 === d.readUInt() && 3 === d.readUByte()) { + const n = d.readUByte(), + l = 31 & n, + s = [n, d.readUByte()]; + for (c = 0; c < l; c++) s.push(d.readUByte()), s.push(d.readUByte()), s.push(d.readUByte()); + this._insertSampleInOrder(this._txtTrack.captionSamples, { + type: 3, + pts: o.pts, + bytes: s + }) + } + } else if (t < d.bytesAvailable) + for (c = 0; c < t; c++) d.readUByte() + } + break; + case 7: + if (u = !0, !l.config.sps) { + d = new tt(n.data, this.logger); + const o = d.readSPS(); + l.config.width = o.width, l.config.height = o.height, l.config.pixelRatio = o.pixelRatio, l.config.sps = [n.data], l.info.duration = this._duration; + const a = n.data.subarray(1, 4); + let t = "avc1."; + for (c = 0; c < 3; c++) { + let e = a[c].toString(16); + e.length < 2 && (e = "0" + e), t += e + } + l.config.codec = t + } + break; + case 8: + u = !0, l.config.pps || (l.config.pps = [n.data]); + break; + case 9: + u = !1, h && this.pushAccesUnit(l, p), h = l.avcSample = this._createAVCSample(!1, o.pts, o.dts, ""); + break; + case 12: + u = !1; + break; + default: + u = !1, h && (h.debug += "unknown NAL " + n.type + " ") + } + h && u && h.units.push(n) + }), e && h && (this.pushAccesUnit(l, p), l.avcSample = void 0) + } + _createAVCSample(e, t, i, r) { + return { + id: NaN, + key: e, + pts: t, + dts: i, + units: new Array, + debug: r + } + } + _insertSampleInOrder(t, i) { + var r = t.length; + if (0 < r) { + if (i.pts >= t[r - 1].pts) t.push(i); + else + for (let e = r - 1; 0 <= e; e--) + if (i.pts < t[e].pts) { + t.splice(e, 0, i); + break + } + } else t.push(i) + } + _getLastNalUnit() { + const e = this._avcContext; + let t, i = e.avcSample; + if (!i || 0 === i.units.length) { + const t = e.parsingData.esSamples; + i = t[t.length - 1] + } + if (i) { + const e = i.units; + t = e[e.length - 1] + } + return t + } + _parseAVCNALu(e) { + const t = e.byteLength; + let i, r, n = 0; + const s = this._avcContext; + let a = s.naluState || 0; + const o = a, + l = []; + let d, u, c, h = -1; + for (-1 === a && (h = 0, c = 31 & e[0], a = 0, n = 1); n < t;) + if (i = e[n++], a) + if (1 !== a) + if (i) + if (1 === i) { + if (0 <= h) d = { + data: e.subarray(h, n - a - 1), + type: c + }, l.push(d); + else { + const t = this._getLastNalUnit(); + if (t && (o && n <= 4 - o && t.state && (t.data = t.data.subarray(0, t.data.byteLength - o)), r = n - a - 1, 0 < r)) { + const i = new Uint8Array(t.data.byteLength + r); + i.set(t.data, 0), i.set(e.subarray(0, r), t.data.byteLength), t.data = i, t.state = 0 + } + } + a = n < t ? (u = 31 & e[n], h = n, c = u, 0) : -1 + } else a = 0; + else a = 3; + else a = i ? 0 : 2; + else a = i ? 0 : 1; + if (0 <= h && 0 <= a && (d = { + data: e.subarray(h, t), + type: c, + state: a + }, l.push(d)), 0 === l.length) { + const t = this._getLastNalUnit(); + if (t) { + const i = new Uint8Array(t.data.byteLength + e.byteLength); + i.set(t.data, 0), i.set(e, t.data.byteLength), t.data = i + } + } + return s.naluState = a, l + } + discardEPB(e) { + const t = e.byteLength, + i = []; + let r = 1; + for (; r < t - 2;) 0 === e[r] && 0 === e[r + 1] && 3 === e[r + 2] ? (i.push(r + 2), r += 2) : r++; + if (0 === i.length) return e; + const n = t - i.length, + s = new Uint8Array(n); + let a = 0; + for (r = 0; r < n; a++, r++) a === i[0] && (a++, i.shift()), s[r] = e[a]; + return s + } + _parseAACPES(e) { + const t = this._audioContext, + i = t.audioLastPTS, + r = e.keyTagInfo; + let n, s, a, o, l, d, u, c = e.data, + h = e.pts, + p = t.audioOverFlow; + if (p) { + const e = new Uint8Array(p.byteLength + c.byteLength); + e.set(p, 0), e.set(c, p.byteLength), c = e + } + for (a = 0, d = c.length; a < d - 1 && (255 !== c[a] || 240 != (240 & c[a + 1])); a++); + if (a) { + let e, t, i; + i = a < d - 1 ? (e = `AAC PES did not start with ADTS header,offset:${a}`, t = !1, $.PESDidNotStartWithADTS) : (e = "no ADTS header found in AAC PES", t = !0, $.NoADTSHeaderInPES), this.logger.warn(it, `parsing error:${e}`); + const r = new D(t, e, i); + if (this.observer.trigger(x.INTERNAL_ERROR, r), t) return + } + if (!t.config) { + const e = E(this.observer, c, a, void 0, this.logger); + if (!e) throw "unable to parse adts header"; + t.config = e + } + s = 0; + var f = 9216e4 / t.config.samplerate; + if (p && i) { + const e = i + f; + 1 < Math.abs(e - h) && (h = e) + } + for (; a + 5 < d && (o = 1 & c[a + 1] ? 7 : 9, n = (3 & c[a + 3]) << 11 | c[a + 4] << 3 | (224 & c[a + 5]) >>> 5, n -= o, 0 < n && a + o + n <= d);) + for (l = h + s * f, u = { + unit: c.subarray(a + o, a + o + n), + pts: l, + dts: l, + keyTagInfo: r + }, t.parsingData.esSamples.push(u), t.parsingData.len += n, a += n + o, s++; a < d - 1 && (255 !== c[a] || 240 != (240 & c[a + 1])); a++); + p = a < d ? c.subarray(a, d) : void 0, t.audioOverFlow = p, t.audioLastPTS = l + } + _parseMPEGPES(e) { + "mp3" === this._audioContext.segmentCodec && ee.parse(this._audioContext.parsingData, e.data, 0, e.pts, this.logger) + } + _parseDolbyPES(e) { + const t = this._audioContext; + let i = e.data, + r = e.pts; + var n = e.keyTagInfo; + let s = 0, + a = 0, + o = t.audioOverFlow; + e = t.audioLastPTS; + if (!t.config) { + let e; + if ("ac3" === t.segmentCodec ? e = j(this.observer, i, a, this.logger) : "ec3" === t.segmentCodec && (e = Y(this.observer, i, a, this.logger)), !e) throw "unable to parse dolby header"; + t.config = e + } + if ("ac3" !== t.config.segmentCodec && "ec3" !== t.config.segmentCodec) throw "unexpected config type"; + var l = 1536 / t.config.samplerate * t.info.inputTimescale; + if (o) { + const c = new Uint8Array(o.byteLength + i.byteLength); + c.set(o, 0), c.set(i, o.byteLength), i = c + } + var d = i.length; + if (o && e) { + const c = e + l; + 1 < Math.abs(c - r) && (r = c) + } + let u = 0; + for (; a + u <= d;) { + if (11 !== i[a] || 119 !== i[a + 1]) { + const c = new D(!0, "invalid dolby audio magic", $.InvalidDolbyAudioMagic); + return void this.observer.trigger(x.INTERNAL_ERROR, c) + } + "ac3" === t.segmentCodec ? u = Q(this.observer, i, a) : "ec3" === t.segmentCodec && (u = X(this.observer, i, a, this.logger)); + const c = r + s * l; + t.audioLastPTS = c; + const o = { + unit: i.subarray(a, a + u), + pts: c, + dts: c, + keyTagInfo: n + }; + t.parsingData.esSamples.push(o), t.info.duration = this._duration, t.parsingData.len += u, a += u, s++ + } + o = a < d ? i.subarray(a, d) : void 0, t.audioOverFlow = o + } + }; + class st extends a { + constructor(e, t, i, r) { + super(), this.typeSupported = e, this.config = t, this.vendor = i, this.logger = r + } + destroy() { + this.removeAllListeners(); + const e = this.demuxer, + t = this.remuxer; + e && e.destroy(), t && t.destroy() + } + push(t, i, r, n, s, a, o, l, d, u, c, h) { + if (t) { + let e = this.demuxer; + var p = new Uint8Array(t); + if (!e || (s || a) && !this.probeFn(p, this.logger)) { + const { + typeSupported: t, + config: i + } = this, r = [{ + demux: Ze, + remux: ze + }, { + demux: nt, + remux: Ee + }, { + demux: J, + remux: Ee + }, { + demux: z, + remux: Ee + }, { + demux: K, + remux: Ee + }, { + demux: ie, + remux: Ee + }]; + for (const n of r) { + const r = n.demux["probe"]; + if (r(p, this.logger)) { + this.remuxer = new n.remux(this, i, t, this.vendor, this.logger), e = new n.demux(this, this.remuxer, i, t, this.logger), this.probeFn = r; + break + } + } + if (!e) { + const t = new D(!0, "no demux matching with content found", $.DemuxerNotFound); + return void this.trigger(x.INTERNAL_ERROR, t) + } + this.demuxer = e + } + const f = this.remuxer, + m = !this.lastKeyTagInfo || i && "NONE" !== i.method && this.lastKeyTagInfo.uri !== i.uri; + if (this.lastKeyTagInfo = i, (s || a || m) && (e.resetInitSegment(new Uint8Array(r), l, i, s), f.resetInitSegment()), s) { + const t = u ? S(u) : void 0; + e.resetTimeStamp(t), f.resetTimeStamp(t) + } + e.append(p, n, o, d, i, c, h) + } + } + } + + function at() { + let e = `${Date.now()}-${Math.random()}`; + return "undefined" != typeof performance && "function" == typeof performance.now && (e += `-${performance.now()}`), e + } + class ot { + constructor(e, t) { + this.rpc = e, this.logger = t, this.init = (t, n, s) => e => { + const i = at(), + r = this.demuxers[i] = new st(t, n, s, this.logger); + [v.INIT_PTS_FOUND, v.FRAG_PARSING_INIT_SEGMENT, v.FRAG_PARSING_DATA, v.FRAG_PARSED, x.INTERNAL_ERROR].forEach(t => { + r.on(t, e => this.rpc.invoke("demuxer.event", [i, t, e])(() => {})) + }), e(i) + }, this.push = (i, r, n, s, a, o, l, d, u, c, h, p, f) => e => { + const t = this.demuxers[i]; + t ? (t.push(r, n, s, a, o, l, d, u, c, h, p, f), e()) : e(void 0, `Demuxer with id "${i}" does not exist on push`) + }, this.destroy = i => e => { + const t = this.demuxers[i]; + t ? (t.destroy(), delete this.demuxers[i], e()) : this.logger.error(`Demuxer with id "${i}" does not exist on destroy`) + }, this.demuxers = {}, e.register("demuxer.init", this.init), e.register("demuxer.push", this.push), e.register("demuxer.destroy", this.destroy) + } + } + class lt { + constructor(e) { + this.worker = e, this.handlers = {}, this.deferers = {}, this._messageHandler = e => { + var { + type: t, + id: i, + command: r, + args: n, + result: e, + error: s + } = e.data; + if (t === rt.Invoke) try { + if (null == this.handlers[r]) throw new Error(`command ${r} not found`); + this.handlers[r](...n)(this._respond.bind(this, i, r)) + } catch (s) { + this._respond(i, r, null, new Error(`command ${r} not found`)) + } else t === rt.Result && null != this.deferers[i] && (this.deferers[i](e, s), delete this.deferers[i]) + }, e.addEventListener("message", this._messageHandler) + } + register(e, t) { + if (null != this.handlers[e]) return !1; + this.handlers[e] = t + } + unregister(e) { + if (null != this.handlers[e]) return !1; + delete this.handlers[e] + } + invoke(i, r, n) { + return (e = lt._fallbackCallback) => { + var t = at(); + this.deferers[t] = e; + t = { + type: rt.Invoke, + id: t, + command: i, + args: r + }; + this._send(t, n) + } + } + teardown(e) { + this.worker.removeEventListener("message", this._messageHandler), e() + } + _respond(e, t, i, r, n) { + r instanceof Error && (r = `[${r.name}] ${r.message}\n${r.stack}`); + r = { + type: rt.Result, + id: e, + command: t, + result: i, + error: r + }; + this._send(r, n) + } + _send(e, t = []) { + this.worker.postMessage(e, t.map(e => ArrayBuffer.isView(e) ? e.buffer : e).filter(e => void 0 !== e)) + } + } + lt._fallbackCallback = (e, t) => { + if (null != t) throw t + }, (vr = rt = rt || {})[vr.Invoke = 0] = "Invoke", vr[vr.Result = 1] = "Result", ArrayBuffer.isView || (ArrayBuffer.isView = function(e) { + return null !== e && "object" == typeof e && e.buffer instanceof ArrayBuffer + }), void 0 !== Yy && Yy && (Vr = new lt(l), iu = (n => { + const t = (i = []) => { + const r = {}; + return ["fatal", "error", "warn", "info", "debug", "trace", "qe"].forEach(e => { + return r[e] = (t = e, (...e) => { + n.invoke("logger.log", [i, t, ...e])((e, t) => { + if (null != t) throw t + }) + }); + var t + }), r.child = e => t([...i, e]), r + }; + return t() + })(Vr), new i(Vr, iu), new ot(Vr, iu)); + var dt = function(e, t) { + return (dt = Object.setPrototypeOf || { + __proto__: [] + } + instanceof Array && function(e, t) { + e.__proto__ = t + } || function(e, t) { + for (var i in t) Object.prototype.hasOwnProperty.call(t, i) && (e[i] = t[i]) + })(e, t) + }; + + function ut(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Class extends value " + String(t) + " is not a constructor or null"); + + function i() { + this.constructor = e + } + dt(e, t), e.prototype = null === t ? Object.create(t) : (i.prototype = t.prototype, new i) + } + var ct = function() { + return (ct = Object.assign || function(e) { + for (var t, i = 1, r = arguments.length; i < r; i++) + for (var n in t = arguments[i]) Object.prototype.hasOwnProperty.call(t, n) && (e[n] = t[n]); + return e + }).apply(this, arguments) + }; + + function ht(e, t, i, r) { + var n, s = arguments.length, + a = s < 3 ? t : null === r ? r = Object.getOwnPropertyDescriptor(t, i) : r; + if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) a = Reflect.decorate(e, t, i, r); + else + for (var o = e.length - 1; 0 <= o; o--)(n = e[o]) && (a = (s < 3 ? n(a) : 3 < s ? n(t, i, a) : n(t, i)) || a); + return 3 < s && a && Object.defineProperty(t, i, a), a + } + + function pt(e, t) { + if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(e, t) + } + + function ft(e) { + var t = "function" == typeof Symbol && Symbol.iterator, + i = t && e[t], + r = 0; + if (i) return i.call(e); + if (e && "number" == typeof e.length) return { + next: function() { + return { + value: (e = e && r >= e.length ? void 0 : e) && e[r++], + done: !e + } + } + }; + throw new TypeError(t ? "Object is not iterable." : "Symbol.iterator is not defined.") + } + + function mt(e, t) { + var i = "function" == typeof Symbol && e[Symbol.iterator]; + if (!i) return e; + var r, n, s = i.call(e), + a = []; + try { + for (; + (void 0 === t || 0 < t--) && !(r = s.next()).done;) a.push(r.value) + } catch (e) { + n = { + error: e + } + } finally { + try { + r && !r.done && (i = s.return) && i.call(s) + } finally { + if (n) throw n.error + } + } + return a + } + + function gt() { + for (var e = [], t = 0; t < arguments.length; t++) e = e.concat(mt(arguments[t])); + return e + } + + function yt(e) { + return "function" == typeof e + } + var vt = !1, + St = { + Promise: void 0, + set useDeprecatedSynchronousErrorHandling(e) { + vt = e + }, + get useDeprecatedSynchronousErrorHandling() { + return vt + } + }; + + function bt(e) { + setTimeout(function() { + throw e + }, 0) + } + var Tt = { + closed: !0, + next: function(e) {}, + error: function(e) { + if (St.useDeprecatedSynchronousErrorHandling) throw e; + bt(e) + }, + complete: function() {} + }, + Et = Array.isArray || function(e) { + return e && "number" == typeof e.length + }; + + function It(e) { + return null !== e && "object" == typeof e + } + var wt = (kt.prototype = Object.create(Error.prototype), kt), + At = (Ot.prototype.unsubscribe = function() { + var t; + if (!this.closed) { + var e = this._parentOrParents, + i = this._ctorUnsubscribe, + r = this._unsubscribe, + n = this._subscriptions; + if (this.closed = !0, this._parentOrParents = null, this._subscriptions = null, e instanceof Ot) e.remove(this); + else if (null !== e) + for (var s = 0; s < e.length; ++s) e[s].remove(this); + if (yt(r)) { + i && (this._unsubscribe = void 0); + try { + r.call(this) + } catch (e) { + t = e instanceof wt ? Ct(e.errors) : [e] + } + } + if (Et(n)) + for (var s = -1, a = n.length; ++s < a;) { + var o = n[s]; + if (It(o)) try { + o.unsubscribe() + } catch (e) { + t = t || [], e instanceof wt ? t = t.concat(Ct(e.errors)) : t.push(e) + } + } + if (t) throw new wt(t) + } + }, Ot.prototype.add = function(e) { + var t, i = e; + if (!e) return Ot.EMPTY; + switch (typeof e) { + case "function": + i = new Ot(e); + case "object": + if (i === this || i.closed || "function" != typeof i.unsubscribe) return i; + if (this.closed) return i.unsubscribe(), i; + i instanceof Ot || (t = i, (i = new Ot)._subscriptions = [t]); + break; + default: + throw new Error("unrecognized teardown " + e + " added to Subscription.") + } + var r = i._parentOrParents; + if (null === r) i._parentOrParents = this; + else if (r instanceof Ot) { + if (r === this) return i; + i._parentOrParents = [r, this] + } else { + if (-1 !== r.indexOf(this)) return i; + r.push(this) + } + r = this._subscriptions; + return null === r ? this._subscriptions = [i] : r.push(i), i + }, Ot.prototype.remove = function(e) { + var t = this._subscriptions; + !t || -1 !== (e = t.indexOf(e)) && t.splice(e, 1) + }, Ot.EMPTY = ((dl = new Ot).closed = !0, dl), Ot); + + function Ot(e) { + this.closed = !1, this._parentOrParents = null, this._subscriptions = null, e && (this._ctorUnsubscribe = !0, this._unsubscribe = e) + } + + function kt(e) { + return Error.call(this), this.message = e ? e.length + " errors occurred during unsubscription:\n" + e.map(function(e, t) { + return t + 1 + ") " + e.toString() + }).join("\n ") : "", this.name = "UnsubscriptionError", this.errors = e, this + } + + function Ct(e) { + return e.reduce(function(e, t) { + return e.concat(t instanceof wt ? t.errors : t) + }, []) + } + var Dt, Mt, xt = "function" == typeof Symbol ? Symbol("rxSubscriber") : "@@rxSubscriber_" + Math.random(), + Pt = (ut(_t, Mt = At), _t.prototype[xt] = function() { + return this + }, _t.create = function(e, t, i) { + i = new _t(e, t, i); + return i.syncErrorThrowable = !1, i + }, _t.prototype.next = function(e) { + this.isStopped || this._next(e) + }, _t.prototype.error = function(e) { + this.isStopped || (this.isStopped = !0, this._error(e)) + }, _t.prototype.complete = function() { + this.isStopped || (this.isStopped = !0, this._complete()) + }, _t.prototype.unsubscribe = function() { + this.closed || (this.isStopped = !0, Mt.prototype.unsubscribe.call(this)) + }, _t.prototype._next = function(e) { + this.destination.next(e) + }, _t.prototype._error = function(e) { + this.destination.error(e), this.unsubscribe() + }, _t.prototype._complete = function() { + this.destination.complete(), this.unsubscribe() + }, _t.prototype._unsubscribeAndRecycle = function() { + var e = this._parentOrParents; + return this._parentOrParents = null, this.unsubscribe(), this.closed = !1, this.isStopped = !1, this._parentOrParents = e, this + }, _t), + Rt = (ut(Lt, Dt = Pt), Lt.prototype.next = function(e) { + var t; + !this.isStopped && this._next && (t = this._parentSubscriber, St.useDeprecatedSynchronousErrorHandling && t.syncErrorThrowable ? this.__tryOrSetError(t, this._next, e) && this.unsubscribe() : this.__tryOrUnsub(this._next, e)) + }, Lt.prototype.error = function(e) { + if (!this.isStopped) { + var t = this._parentSubscriber, + i = St.useDeprecatedSynchronousErrorHandling; + if (this._error) i && t.syncErrorThrowable ? this.__tryOrSetError(t, this._error, e) : this.__tryOrUnsub(this._error, e), this.unsubscribe(); + else if (t.syncErrorThrowable) i ? (t.syncErrorValue = e, t.syncErrorThrown = !0) : bt(e), this.unsubscribe(); + else { + if (this.unsubscribe(), i) throw e; + bt(e) + } + } + }, Lt.prototype.complete = function() { + var e, t, i = this; + this.isStopped || (e = this._parentSubscriber, this._complete && (t = function() { + return i._complete.call(i._context) + }, St.useDeprecatedSynchronousErrorHandling && e.syncErrorThrowable ? this.__tryOrSetError(e, t) : this.__tryOrUnsub(t)), this.unsubscribe()) + }, Lt.prototype.__tryOrUnsub = function(e, t) { + try { + e.call(this._context, t) + } catch (e) { + if (this.unsubscribe(), St.useDeprecatedSynchronousErrorHandling) throw e; + bt(e) + } + }, Lt.prototype.__tryOrSetError = function(e, t, i) { + if (!St.useDeprecatedSynchronousErrorHandling) throw new Error("bad call"); + try { + t.call(this._context, i) + } catch (t) { + return St.useDeprecatedSynchronousErrorHandling ? (e.syncErrorValue = t, e.syncErrorThrown = !0) : bt(t), !0 + } + return !1 + }, Lt.prototype._unsubscribe = function() { + var e = this._parentSubscriber; + this._context = null, this._parentSubscriber = null, e.unsubscribe() + }, Lt); + + function Lt(e, t, i, r) { + var n, s = Dt.call(this) || this; + s._parentSubscriber = e; + e = s; + return yt(t) ? n = t : t && (n = t.next, i = t.error, r = t.complete, t !== Tt && (yt((e = Object.create(t)).unsubscribe) && s.add(e.unsubscribe.bind(e)), e.unsubscribe = s.unsubscribe.bind(s))), s._context = e, s._next = n, s._error = i, s._complete = r, s + } + + function _t(e, t, i) { + var r = Mt.call(this) || this; + switch (r.syncErrorValue = null, r.syncErrorThrown = !1, r.syncErrorThrowable = !1, r.isStopped = !1, arguments.length) { + case 0: + r.destination = Tt; + break; + case 1: + if (!e) { + r.destination = Tt; + break + } + if ("object" == typeof e) { + e instanceof _t ? (r.syncErrorThrowable = e.syncErrorThrowable, (r.destination = e).add(r)) : (r.syncErrorThrowable = !0, r.destination = new Rt(r, e)); + break + } + default: + r.syncErrorThrowable = !0, r.destination = new Rt(r, e, t, i) + } + return r + } + var Nt = "function" == typeof Symbol && Symbol.observable || "@@observable"; + + function Ft(e) { + return e + } + + function Bt() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + return Ut(e) + } + + function Ut(t) { + return 0 === t.length ? Ft : 1 === t.length ? t[0] : function(e) { + return t.reduce(function(e, t) { + return t(e) + }, e) + } + } + var $t = (Vt.prototype.lift = function(e) { + var t = new Vt; + return t.source = this, t.operator = e, t + }, Vt.prototype.subscribe = function(e, t, i) { + var r = this.operator, + i = function(e, t, i) { + if (e) { + if (e instanceof Pt) return e; + if (e[xt]) return e[xt]() + } + return e || t || i ? new Pt(e, t, i) : new Pt(Tt) + }(e, t, i); + if (r ? i.add(r.call(i, this.source)) : i.add(this.source || St.useDeprecatedSynchronousErrorHandling && !i.syncErrorThrowable ? this._subscribe(i) : this._trySubscribe(i)), St.useDeprecatedSynchronousErrorHandling && i.syncErrorThrowable && (i.syncErrorThrowable = !1, i.syncErrorThrown)) throw i.syncErrorValue; + return i + }, Vt.prototype._trySubscribe = function(t) { + try { + return this._subscribe(t) + } catch (e) { + St.useDeprecatedSynchronousErrorHandling && (t.syncErrorThrown = !0, t.syncErrorValue = e), + function(e) { + for (; e;) { + var t = e, + i = t.closed, + r = t.destination, + t = t.isStopped; + if (i || t) return; + e = r && r instanceof Pt ? r : null + } + return 1 + }(t) ? t.error(e) : console.warn(e) + } + }, Vt.prototype.forEach = function(r, e) { + var n = this; + return new(e = Kt(e))(function(e, t) { + var i = n.subscribe(function(e) { + try { + r(e) + } catch (e) { + t(e), i && i.unsubscribe() + } + }, t, e) + }) + }, Vt.prototype._subscribe = function(e) { + var t = this.source; + return t && t.subscribe(e) + }, Vt.prototype[Nt] = function() { + return this + }, Vt.prototype.pipe = function() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + return 0 === e.length ? this : Ut(e)(this) + }, Vt.prototype.toPromise = function(e) { + var r = this; + return new(e = Kt(e))(function(e, t) { + var i; + r.subscribe(function(e) { + return i = e + }, function(e) { + return t(e) + }, function() { + return e(i) + }) + }) + }, Vt.create = function(e) { + return new Vt(e) + }, Vt); + + function Vt(e) { + this._isScalar = !1, e && (this._subscribe = e) + } + + function Kt(e) { + if (!(e = e || (St.Promise || Promise))) throw new Error("no Promise impl found"); + return e + } + var qt, Ht, jt, Qt, Wt = (ii.prototype = Object.create(Error.prototype), ii), + Gt = (ut(ti, Qt = At), ti.prototype.unsubscribe = function() { + var e, t; + this.closed || (this.closed = !0, e = (t = this.subject).observers, this.subject = null, !e || 0 === e.length || t.isStopped || t.closed || -1 !== (t = e.indexOf(this.subscriber)) && e.splice(t, 1)) + }, ti), + zt = (ut(ei, jt = Pt), ei), + Xt = (ut(Zt, Ht = $t), Zt.prototype[xt] = function() { + return new zt(this) + }, Zt.prototype.lift = function(e) { + var t = new Yt(this, this); + return t.operator = e, t + }, Zt.prototype.next = function(e) { + if (this.closed) throw new Wt; + if (!this.isStopped) + for (var t = this.observers, i = t.length, r = t.slice(), n = 0; n < i; n++) r[n].next(e) + }, Zt.prototype.error = function(e) { + if (this.closed) throw new Wt; + this.hasError = !0, this.thrownError = e, this.isStopped = !0; + for (var t = this.observers, i = t.length, r = t.slice(), n = 0; n < i; n++) r[n].error(e); + this.observers.length = 0 + }, Zt.prototype.complete = function() { + if (this.closed) throw new Wt; + this.isStopped = !0; + for (var e = this.observers, t = e.length, i = e.slice(), r = 0; r < t; r++) i[r].complete(); + this.observers.length = 0 + }, Zt.prototype.unsubscribe = function() { + this.isStopped = !0, this.closed = !0, this.observers = null + }, Zt.prototype._trySubscribe = function(e) { + if (this.closed) throw new Wt; + return Ht.prototype._trySubscribe.call(this, e) + }, Zt.prototype._subscribe = function(e) { + if (this.closed) throw new Wt; + return this.hasError ? (e.error(this.thrownError), At.EMPTY) : this.isStopped ? (e.complete(), At.EMPTY) : (this.observers.push(e), new Gt(this, e)) + }, Zt.prototype.asObservable = function() { + var e = new $t; + return e.source = this, e + }, Zt.create = function(e, t) { + return new Yt(e, t) + }, Zt), + Yt = (ut(Jt, qt = Xt), Jt.prototype.next = function(e) { + var t = this.destination; + t && t.next && t.next(e) + }, Jt.prototype.error = function(e) { + var t = this.destination; + t && t.error && this.destination.error(e) + }, Jt.prototype.complete = function() { + var e = this.destination; + e && e.complete && this.destination.complete() + }, Jt.prototype._subscribe = function(e) { + return this.source ? this.source.subscribe(e) : At.EMPTY + }, Jt); + + function Jt(e, t) { + var i = qt.call(this) || this; + return i.destination = e, i.source = t, i + } + + function Zt() { + var e = Ht.call(this) || this; + return e.observers = [], e.closed = !1, e.isStopped = !1, e.hasError = !1, e.thrownError = null, e + } + + function ei(e) { + var t = jt.call(this, e) || this; + return t.destination = e, t + } + + function ti(e, t) { + var i = Qt.call(this) || this; + return i.subject = e, i.subscriber = t, i.closed = !1, i + } + + function ii() { + return Error.call(this), this.message = "object unsubscribed", this.name = "ObjectUnsubscribedError", this + } + + function ri() { + return function(e) { + return e.lift(new pi(e)) + } + } + var ni, si, ai, oi, li, di, ui, ci, hi, pi = (Li.prototype.call = function(e, t) { + var i = this.connectable; + i._refCount++; + e = new fi(e, i), t = t.subscribe(e); + return e.closed || (e.connection = i.connect()), t + }, Li), + fi = (ut(Ri, hi = Pt), Ri.prototype._unsubscribe = function() { + var e, t = this.connectable; + t ? (this.connectable = null, (e = t._refCount) <= 0 ? this.connection = null : (t._refCount = e - 1, 1 < e ? this.connection = null : (e = this.connection, t = t._connection, this.connection = null, !t || e && t !== e || t.unsubscribe()))) : this.connection = null + }, Ri), + w = (ut(Pi, ci = $t), Pi.prototype._subscribe = function(e) { + return this.getSubject().subscribe(e) + }, Pi.prototype.getSubject = function() { + var e = this._subject; + return e && !e.isStopped || (this._subject = this.subjectFactory()), this._subject + }, Pi.prototype.connect = function() { + var e = this._connection; + return e || (this._isComplete = !1, (e = this._connection = new At).add(this.source.subscribe(new gi(this.getSubject(), this))), e.closed && (this._connection = null, e = At.EMPTY)), e + }, Pi.prototype.refCount = function() { + return ri()(this) + }, Pi), + mi = { + operator: { + value: null + }, + _refCount: { + value: 0, + writable: !0 + }, + _subject: { + value: null, + writable: !0 + }, + _connection: { + value: null, + writable: !0 + }, + _subscribe: { + value: (fl = w.prototype)._subscribe + }, + _isComplete: { + value: fl._isComplete, + writable: !0 + }, + getSubject: { + value: fl.getSubject + }, + connect: { + value: fl.connect + }, + refCount: { + value: fl.refCount + } + }, + gi = (ut(xi, ui = zt), xi.prototype._error = function(e) { + this._unsubscribe(), ui.prototype._error.call(this, e) + }, xi.prototype._complete = function() { + this.connectable._isComplete = !0, this._unsubscribe(), ui.prototype._complete.call(this) + }, xi.prototype._unsubscribe = function() { + var e, t = this.connectable; + t && (this.connectable = null, e = t._connection, t._refCount = 0, t._subject = null, t._connection = null, e && e.unsubscribe()) + }, xi), + yi = (ut(Mi, di = Xt), Object.defineProperty(Mi.prototype, "value", { + get: function() { + return this.getValue() + }, + enumerable: !0, + configurable: !0 + }), Mi.prototype._subscribe = function(e) { + var t = di.prototype._subscribe.call(this, e); + return t && !t.closed && e.next(this._value), t + }, Mi.prototype.getValue = function() { + if (this.hasError) throw this.thrownError; + if (this.closed) throw new Wt; + return this._value + }, Mi.prototype.next = function(e) { + di.prototype.next.call(this, this._value = e) + }, Mi), + A = (ut(Di, li = At), Di.prototype.schedule = function(e, t) { + return this + }, ut(Ci, oi = Di), Ci.prototype.schedule = function(e, t) { + if (void 0 === t && (t = 0), this.closed) return this; + this.state = e; + var i = this.id, + e = this.scheduler; + return null != i && (this.id = this.recycleAsyncId(e, i, t)), this.pending = !0, this.delay = t, this.id = this.id || this.requestAsyncId(e, this.id, t), this + }, Ci.prototype.requestAsyncId = function(e, t, i) { + return void 0 === i && (i = 0), setInterval(e.flush.bind(e, this), i) + }, Ci.prototype.recycleAsyncId = function(e, t, i) { + if (null !== (i = void 0 === i ? 0 : i) && this.delay === i && !1 === this.pending) return t; + clearInterval(t) + }, Ci.prototype.execute = function(e, t) { + if (this.closed) return new Error("executing a cancelled action"); + this.pending = !1; + t = this._execute(e, t); + if (t) return t; + !1 === this.pending && null != this.id && (this.id = this.recycleAsyncId(this.scheduler, this.id, null)) + }, Ci.prototype._execute = function(e, t) { + var i = !1, + r = void 0; + try { + this.work(e) + } catch (e) { + i = !0, r = !!e && e || new Error(e) + } + if (i) return this.unsubscribe(), r + }, Ci.prototype._unsubscribe = function() { + var e = this.id, + t = this.scheduler, + i = t.actions, + r = i.indexOf(this); + this.work = null, this.state = null, this.pending = !1, this.scheduler = null, -1 !== r && i.splice(r, 1), null != e && (this.id = this.recycleAsyncId(t, e, null)), this.delay = null + }, Ci), + vi = (ut(ki, ai = A), ki.prototype.schedule = function(e, t) { + return 0 < (t = void 0 === t ? 0 : t) ? ai.prototype.schedule.call(this, e, t) : (this.delay = t, this.state = e, this.scheduler.flush(this), this) + }, ki.prototype.execute = function(e, t) { + return 0 < t || this.closed ? ai.prototype.execute.call(this, e, t) : this._execute(e, t) + }, ki.prototype.requestAsyncId = function(e, t, i) { + return null !== (i = void 0 === i ? 0 : i) && 0 < i || null === i && 0 < this.delay ? ai.prototype.requestAsyncId.call(this, e, t, i) : e.flush(this) + }, ki), + Si = (Oi.prototype.schedule = function(e, t, i) { + return void 0 === t && (t = 0), new this.SchedulerAction(this, e).schedule(i, t) + }, Oi.now = function() { + return Date.now() + }, Oi), + bi = (ut(Ai, si = Si), Ai.prototype.schedule = function(e, t, i) { + return void 0 === t && (t = 0), Ai.delegate && Ai.delegate !== this ? Ai.delegate.schedule(e, t, i) : si.prototype.schedule.call(this, e, t, i) + }, Ai.prototype.flush = function(e) { + var t, i = this.actions; + if (this.active) i.push(e); + else { + this.active = !0; + do { + if (t = e.execute(e.state, e.delay)) break + } while (e = i.shift()); + if (this.active = !1, t) { + for (; e = i.shift();) e.unsubscribe(); + throw t + } + } + }, Ai), + Ti = (ut(wi, ni = bi), new wi(vi)), + Ei = Ti, + Ii = new $t(function(e) { + return e.complete() + }); + + function wi() { + return null !== ni && ni.apply(this, arguments) || this + } + + function Ai(e, t) { + void 0 === t && (t = Si.now); + var i = si.call(this, e, function() { + return Ai.delegate && Ai.delegate !== i ? Ai.delegate.now() : t() + }) || this; + return i.actions = [], i.active = !1, i.scheduled = void 0, i + } + + function Oi(e, t) { + void 0 === t && (t = Oi.now), this.SchedulerAction = e, this.now = t + } + + function ki(e, t) { + var i = ai.call(this, e, t) || this; + return i.scheduler = e, i.work = t, i + } + + function Ci(e, t) { + var i = oi.call(this, e, t) || this; + return i.scheduler = e, i.work = t, i.pending = !1, i + } + + function Di(e, t) { + return li.call(this) || this + } + + function Mi(e) { + var t = di.call(this) || this; + return t._value = e, t + } + + function xi(e, t) { + e = ui.call(this, e) || this; + return e.connectable = t, e + } + + function Pi(e, t) { + var i = ci.call(this) || this; + return i.source = e, i.subjectFactory = t, i._refCount = 0, i._isComplete = !1, i + } + + function Ri(e, t) { + e = hi.call(this, e) || this; + return e.connectable = t, e + } + + function Li(e) { + this.connectable = e + } + + function _i(e) { + return e ? (t = e, new $t(function(e) { + return t.schedule(function() { + return e.complete() + }) + })) : Ii; + var t + } + + function Ni(e) { + return e && "function" == typeof e.schedule + } + var Fi = function(r) { + return function(e) { + for (var t = 0, i = r.length; t < i && !e.closed; t++) e.next(r[t]); + e.complete() + } + }; + + function Bi(r, n) { + return new $t(function(e) { + var t = new At, + i = 0; + return t.add(n.schedule(function() { + i !== r.length ? (e.next(r[i++]), e.closed || t.add(this.schedule())) : e.complete() + })), t + }) + } + + function Ui(e, t) { + return t ? Bi(e, t) : new $t(Fi(e)) + } + + function $i() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + var i = e[e.length - 1]; + return Ni(i) ? (e.pop(), Bi(e, i)) : Ui(e) + } + + function Vi(t, i) { + return new $t(i ? function(e) { + return i.schedule(Ki, 0, { + error: t, + subscriber: e + }) + } : function(e) { + return e.error(t) + }) + } + + function Ki(e) { + var t = e.error; + e.subscriber.error(t) + } + var qi = (Hi.prototype.observe = function(e) { + switch (this.kind) { + case "N": + return e.next && e.next(this.value); + case "E": + return e.error && e.error(this.error); + case "C": + return e.complete && e.complete() + } + }, Hi.prototype.do = function(e, t, i) { + switch (this.kind) { + case "N": + return e && e(this.value); + case "E": + return t && t(this.error); + case "C": + return i && i() + } + }, Hi.prototype.accept = function(e, t, i) { + return e && "function" == typeof e.next ? this.observe(e) : this.do(e, t, i) + }, Hi.prototype.toObservable = function() { + switch (this.kind) { + case "N": + return $i(this.value); + case "E": + return Vi(this.error); + case "C": + return _i() + } + throw new Error("unexpected notification kind value") + }, Hi.createNext = function(e) { + return void 0 !== e ? new Hi("N", e) : Hi.undefinedValueNotification + }, Hi.createError = function(e) { + return new Hi("E", void 0, e) + }, Hi.createComplete = function() { + return Hi.completeNotification + }, Hi.completeNotification = new Hi("C"), Hi.undefinedValueNotification = new Hi("N", void 0), Hi); + + function Hi(e, t, i) { + this.kind = e, this.value = t, this.error = i, this.hasValue = "N" === e + } + + function ji(t, i) { + return void 0 === i && (i = 0), + function(e) { + return e.lift(new zi(t, i)) + } + } + var Qi, Wi, Gi, zi = (ar.prototype.call = function(e, t) { + return t.subscribe(new Xi(e, this.scheduler, this.delay)) + }, ar), + Xi = (ut(sr, Gi = Pt), sr.dispatch = function(e) { + var t = e.notification, + e = e.destination; + t.observe(e), this.unsubscribe() + }, sr.prototype.scheduleMessage = function(e) { + this.destination.add(this.scheduler.schedule(sr.dispatch, this.delay, new Yi(e, this.destination))) + }, sr.prototype._next = function(e) { + this.scheduleMessage(qi.createNext(e)) + }, sr.prototype._error = function(e) { + this.scheduleMessage(qi.createError(e)), this.unsubscribe() + }, sr.prototype._complete = function() { + this.scheduleMessage(qi.createComplete()), this.unsubscribe() + }, sr), + Yi = function(e, t) { + this.notification = e, this.destination = t + }, + Ji = (ut(nr, Wi = Xt), nr.prototype.nextInfiniteTimeWindow = function(e) { + var t; + this.isStopped || ((t = this._events).push(e), t.length > this._bufferSize && t.shift()), Wi.prototype.next.call(this, e) + }, nr.prototype.nextTimeWindow = function(e) { + this.isStopped || (this._events.push(new Zi(this._getNow(), e)), this._trimBufferThenGetEvents()), Wi.prototype.next.call(this, e) + }, nr.prototype._subscribe = function(e) { + var t, i = this._infiniteTimeWindow, + r = i ? this._events : this._trimBufferThenGetEvents(), + n = this.scheduler, + s = r.length; + if (this.closed) throw new Wt; + if (t = this.isStopped || this.hasError ? At.EMPTY : (this.observers.push(e), new Gt(this, e)), n && e.add(e = new Xi(e, n)), i) + for (var a = 0; a < s && !e.closed; a++) e.next(r[a]); + else + for (a = 0; a < s && !e.closed; a++) e.next(r[a].value); + return this.hasError ? e.error(this.thrownError) : this.isStopped && e.complete(), t + }, nr.prototype._getNow = function() { + return (this.scheduler || Ei).now() + }, nr.prototype._trimBufferThenGetEvents = function() { + for (var e = this._getNow(), t = this._bufferSize, i = this._windowTime, r = this._events, n = r.length, s = 0; s < n && !(e - r[s].time < i);) s++; + return 0 < (s = t < n ? Math.max(s, n - t) : s) && r.splice(0, s), r + }, nr), + Zi = function(e, t) { + this.time = e, this.value = t + }, + er = (ut(rr, Qi = Xt), rr.prototype._subscribe = function(e) { + return this.hasError ? (e.error(this.thrownError), At.EMPTY) : this.hasCompleted && this.hasNext ? (e.next(this.value), e.complete(), At.EMPTY) : Qi.prototype._subscribe.call(this, e) + }, rr.prototype.next = function(e) { + this.hasCompleted || (this.value = e, this.hasNext = !0) + }, rr.prototype.error = function(e) { + this.hasCompleted || Qi.prototype.error.call(this, e) + }, rr.prototype.complete = function() { + this.hasCompleted = !0, this.hasNext && Qi.prototype.next.call(this, this.value), Qi.prototype.complete.call(this) + }, rr), + tr = new bi(A), + ir = tr; + + function rr() { + var e = null !== Qi && Qi.apply(this, arguments) || this; + return e.value = null, e.hasNext = !1, e.hasCompleted = !1, e + } + + function nr(e, t, i) { + void 0 === e && (e = Number.POSITIVE_INFINITY), void 0 === t && (t = Number.POSITIVE_INFINITY); + var r = Wi.call(this) || this; + return r.scheduler = i, r._events = [], r._infiniteTimeWindow = !1, r._bufferSize = e < 1 ? 1 : e, r._windowTime = t < 1 ? 1 : t, t === Number.POSITIVE_INFINITY ? (r._infiniteTimeWindow = !0, r.next = r.nextInfiniteTimeWindow) : r.next = r.nextTimeWindow, r + } + + function sr(e, t, i) { + void 0 === i && (i = 0); + e = Gi.call(this, e) || this; + return e.scheduler = t, e.delay = i, e + } + + function ar(e, t) { + void 0 === t && (t = 0), this.scheduler = e, this.delay = t + } + + function or() {} + var lr = (cr.prototype = Object.create(Error.prototype), cr), + dr = (ur.prototype = Object.create(Error.prototype), ur); + + function ur() { + return Error.call(this), this.message = "Timeout has occurred", this.name = "TimeoutError", this + } + + function cr() { + return Error.call(this), this.message = "argument out of range", this.name = "ArgumentOutOfRangeError", this + } + + function hr(t, i) { + return function(e) { + if ("function" != typeof t) throw new TypeError("argument is not a function. Are you looking for `mapTo()`?"); + return e.lift(new gr(t, i)) + } + } + var pr, fr, mr, gr = (Ir.prototype.call = function(e, t) { + return t.subscribe(new yr(e, this.project, this.thisArg)) + }, Ir), + yr = (ut(Er, mr = Pt), Er.prototype._next = function(e) { + var t; + try { + t = this.project.call(this.thisArg, e, this.count++) + } catch (e) { + return void this.destination.error(e) + } + this.destination.next(t) + }, Er), + vr = (ut(Tr, fr = Pt), Tr.prototype.notifyNext = function(e, t, i, r, n) { + this.destination.next(t) + }, Tr.prototype.notifyError = function(e, t) { + this.destination.error(e) + }, Tr.prototype.notifyComplete = function(e) { + this.destination.complete() + }, Tr), + Sr = (ut(br, pr = Pt), br.prototype._next = function(e) { + this.parent.notifyNext(this.outerValue, e, this.outerIndex, this.index++, this) + }, br.prototype._error = function(e) { + this.parent.notifyError(e, this), this.unsubscribe() + }, br.prototype._complete = function() { + this.parent.notifyComplete(this), this.unsubscribe() + }, br); + + function br(e, t, i) { + var r = pr.call(this) || this; + return r.parent = e, r.outerValue = t, r.outerIndex = i, r.index = 0, r + } + + function Tr() { + return null !== fr && fr.apply(this, arguments) || this + } + + function Er(e, t, i) { + e = mr.call(this, e) || this; + return e.project = t, e.count = 0, e.thisArg = i || e, e + } + + function Ir(e, t) { + this.project = e, this.thisArg = t + } + var wr = "function" == typeof Symbol && Symbol.iterator ? Symbol.iterator : "@@iterator", + Ar = function(e) { + return e && "number" == typeof e.length && "function" != typeof e + }; + + function Or(e) { + return e && "function" != typeof e.subscribe && "function" == typeof e.then + } + var kr = function(e) { + if (e && "function" == typeof e[Nt]) return n = e, + function(e) { + var t = n[Nt](); + if ("function" != typeof t.subscribe) throw new TypeError("Provided object does not correctly implement Symbol.observable"); + return t.subscribe(e) + }; + if (Ar(e)) return Fi(e); + if (Or(e)) return i = e, + function(t) { + return i.then(function(e) { + t.closed || (t.next(e), t.complete()) + }, function(e) { + return t.error(e) + }).then(null, bt), t + }; + if (e && "function" == typeof e[wr]) return r = e, + function(t) { + for (var e = r[wr]();;) { + var i = void 0; + try { + i = e.next() + } catch (e) { + return t.error(e), t + } + if (i.done) { + t.complete(); + break + } + if (t.next(i.value), t.closed) break + } + return "function" == typeof e.return && t.add(function() { + e.return && e.return() + }), t + }; + var r, i, n, e = It(e) ? "an invalid object" : "'" + e + "'"; + throw new TypeError("You provided " + e + " where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.") + }; + + function Cr(e, t, i, r, n) { + if (!(n = void 0 === n ? new Sr(e, i, r) : n).closed) return t instanceof $t ? t.subscribe(n) : kr(t)(n) + } + var Dr = {}; + + function Mr() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + var i = void 0, + r = void 0; + return Ni(e[e.length - 1]) && (r = e.pop()), "function" == typeof e[e.length - 1] && (i = e.pop()), Ui(e = 1 === e.length && Et(e[0]) ? e[0] : e, r).lift(new Pr(i)) + } + var xr, Pr = (_r.prototype.call = function(e, t) { + return t.subscribe(new Rr(e, this.resultSelector)) + }, _r), + Rr = (ut(Lr, xr = vr), Lr.prototype._next = function(e) { + this.values.push(Dr), this.observables.push(e) + }, Lr.prototype._complete = function() { + var e = this.observables, + t = e.length; + if (0 === t) this.destination.complete(); + else { + this.active = t, this.toRespond = t; + for (var i = 0; i < t; i++) { + var r = e[i]; + this.add(Cr(this, r, void 0, i)) + } + } + }, Lr.prototype.notifyComplete = function(e) { + 0 == --this.active && this.destination.complete() + }, Lr.prototype.notifyNext = function(e, t, i) { + var r = this.values, + n = r[i], + n = this.toRespond ? n === Dr ? --this.toRespond : this.toRespond : 0; + r[i] = t, 0 === n && (this.resultSelector ? this._tryResultSelector(r) : this.destination.next(r.slice())) + }, Lr.prototype._tryResultSelector = function(e) { + var t; + try { + t = this.resultSelector.apply(this, e) + } catch (e) { + return void this.destination.error(e) + } + this.destination.next(t) + }, Lr); + + function Lr(e, t) { + e = xr.call(this, e) || this; + return e.resultSelector = t, e.active = 0, e.values = [], e.observables = [], e + } + + function _r(e) { + this.resultSelector = e + } + + function Nr(e, t) { + if (null != e) { + if (e && "function" == typeof e[Nt]) return s = e, a = t, new $t(function(t) { + var i = new At; + return i.add(a.schedule(function() { + var e = s[Nt](); + i.add(e.subscribe({ + next: function(e) { + i.add(a.schedule(function() { + return t.next(e) + })) + }, + error: function(e) { + i.add(a.schedule(function() { + return t.error(e) + })) + }, + complete: function() { + i.add(a.schedule(function() { + return t.complete() + })) + } + })) + })), i + }); + if (Or(e)) return r = e, n = t, new $t(function(t) { + var i = new At; + return i.add(n.schedule(function() { + return r.then(function(e) { + i.add(n.schedule(function() { + t.next(e), i.add(n.schedule(function() { + return t.complete() + })) + })) + }, function(e) { + i.add(n.schedule(function() { + return t.error(e) + })) + }) + })), i + }); + if (Ar(e)) return Bi(e, t); + if (e && "function" == typeof e[wr] || "string" == typeof e) return function(t, i) { + if (!t) throw new Error("Iterable cannot be null"); + return new $t(function(r) { + var n, e = new At; + return e.add(function() { + n && "function" == typeof n.return && n.return() + }), e.add(i.schedule(function() { + n = t[wr](), e.add(i.schedule(function() { + if (!r.closed) { + try { + var e = n.next(), + t = e.value, + i = e.done + } catch (t) { + return void r.error(t) + } + i ? r.complete() : (r.next(t), this.schedule()) + } + })) + })), e + }) + }(e, t) + } + var r, n, s, a; + throw new TypeError((null !== e && typeof e || e) + " is not observable") + } + + function Fr(e, t) { + return t ? Nr(e, t) : e instanceof $t ? e : new $t(kr(e)) + } + var Br, Ur, $r = (ut(qr, Ur = Pt), qr.prototype._next = function(e) { + this.parent.notifyNext(e) + }, qr.prototype._error = function(e) { + this.parent.notifyError(e), this.unsubscribe() + }, qr.prototype._complete = function() { + this.parent.notifyComplete(), this.unsubscribe() + }, qr), + Vr = (ut(Kr, Br = Pt), Kr.prototype.notifyNext = function(e) { + this.destination.next(e) + }, Kr.prototype.notifyError = function(e) { + this.destination.error(e) + }, Kr.prototype.notifyComplete = function() { + this.destination.complete() + }, Kr); + + function Kr() { + return null !== Br && Br.apply(this, arguments) || this + } + + function qr(e) { + var t = Ur.call(this) || this; + return t.parent = e, t + } + + function Hr(e, t) { + if (!t.closed) return e instanceof $t ? e.subscribe(t) : kr(e)(t) + } + + function jr(t, n, i) { + return void 0 === i && (i = Number.POSITIVE_INFINITY), "function" == typeof n ? function(e) { + return e.pipe(jr(function(i, r) { + return Fr(t(i, r)).pipe(hr(function(e, t) { + return n(i, e, r, t) + })) + }, i)) + } : ("number" == typeof n && (i = n), function(e) { + return e.lift(new Wr(t, i)) + }) + } + var Qr, Wr = (Xr.prototype.call = function(e, t) { + return t.subscribe(new Gr(e, this.project, this.concurrent)) + }, Xr), + Gr = (ut(zr, Qr = Vr), zr.prototype._next = function(e) { + this.active < this.concurrent ? this._tryNext(e) : this.buffer.push(e) + }, zr.prototype._tryNext = function(e) { + var t, i = this.index++; + try { + t = this.project(e, i) + } catch (e) { + return void this.destination.error(e) + } + this.active++, this._innerSub(t) + }, zr.prototype._innerSub = function(e) { + var t = new $r(this), + i = this.destination; + i.add(t); + e = Hr(e, t); + e !== t && i.add(e) + }, zr.prototype._complete = function() { + this.hasCompleted = !0, 0 === this.active && 0 === this.buffer.length && this.destination.complete(), this.unsubscribe() + }, zr.prototype.notifyNext = function(e) { + this.destination.next(e) + }, zr.prototype.notifyComplete = function() { + var e = this.buffer; + this.active--, 0 < e.length ? this._next(e.shift()) : 0 === this.active && this.hasCompleted && this.destination.complete() + }, zr); + + function zr(e, t, i) { + void 0 === i && (i = Number.POSITIVE_INFINITY); + e = Qr.call(this, e) || this; + return e.project = t, e.concurrent = i, e.hasCompleted = !1, e.buffer = [], e.active = 0, e.index = 0, e + } + + function Xr(e, t) { + void 0 === t && (t = Number.POSITIVE_INFINITY), this.project = e, this.concurrent = t + } + + function Yr(e) { + return jr(Ft, e = void 0 === e ? Number.POSITIVE_INFINITY : e) + } + + function Jr() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + return Yr(1)($i.apply(void 0, e)) + } + + function Zr(i) { + return new $t(function(t) { + var e; + try { + e = i() + } catch (e) { + return void t.error(e) + } + return (e ? Fr(e) : _i()).subscribe(t) + }) + } + + function en() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + if (1 === e.length) { + var i = e[0]; + if (Et(i)) return tn(i, null); + if (It(i) && Object.getPrototypeOf(i) === Object.prototype) { + var r = Object.keys(i); + return tn(r.map(function(e) { + return i[e] + }), r) + } + } + if ("function" != typeof e[e.length - 1]) return tn(e, null); + var n = e.pop(); + return tn(e = 1 === e.length && Et(e[0]) ? e[0] : e, null).pipe(hr(function(e) { + return n.apply(void 0, e) + })) + } + + function tn(l, d) { + return new $t(function(r) { + var n = l.length; + if (0 !== n) + for (var s = new Array(n), a = 0, o = 0, e = 0; e < n; e++) ! function(t) { + var e = Fr(l[t]), + i = !1; + r.add(e.subscribe({ + next: function(e) { + i || (i = !0, o++), s[t] = e + }, + error: function(e) { + return r.error(e) + }, + complete: function() { + ++a !== n && i || (o === n && r.next(d ? d.reduce(function(e, t, i) { + return e[t] = s[i], e + }, {}) : s), r.complete()) + } + })) + }(e); + else r.complete() + }) + } + + function rn(e, i, r, t) { + return yt(r) && (t = r, r = void 0), t ? rn(e, i, r).pipe(hr(function(e) { + return Et(e) ? t.apply(void 0, e) : t(e) + })) : new $t(function(t) { + ! function e(t, i, r, n, s) { + var a; + if (function(e) { + return e && "function" == typeof e.addEventListener && "function" == typeof e.removeEventListener + }(t)) { + var o = t; + t.addEventListener(i, r, s), a = function() { + return o.removeEventListener(i, r, s) + } + } else if (function(e) { + return e && "function" == typeof e.on && "function" == typeof e.off + }(t)) { + var l = t; + t.on(i, r), a = function() { + return l.off(i, r) + } + } else if (function(e) { + return e && "function" == typeof e.addListener && "function" == typeof e.removeListener + }(t)) { + var d = t; + t.addListener(i, r), a = function() { + return d.removeListener(i, r) + } + } else { + if (!t || !t.length) throw new TypeError("Invalid event target"); + for (var u = 0, c = t.length; u < c; u++) e(t[u], i, r, n, s) + } + n.add(a) + }(e, i, function(e) { + 1 < arguments.length ? t.next(Array.prototype.slice.call(arguments)) : t.next(e) + }, t, r) + }) + } + + function nn(e, t, i) { + return void 0 === t && (t = Ii), void 0 === i && (i = Ii), Zr(function() { + return e() ? t : i + }) + } + + function sn(e) { + return !Et(e) && 0 <= e - parseFloat(e) + 1 + } + + function an() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + var i = Number.POSITIVE_INFINITY, + r = null, + n = e[e.length - 1]; + return Ni(n) ? (r = e.pop(), 1 < e.length && "number" == typeof e[e.length - 1] && (i = e.pop())) : "number" == typeof n && (i = e.pop()), null === r && 1 === e.length && e[0] instanceof $t ? e[0] : Yr(i)(Ui(e, r)) + } + var on = new $t(or); + + function ln(t, i) { + return function(e) { + return e.lift(new un(t, i)) + } + } + var dn, un = (pn.prototype.call = function(e, t) { + return t.subscribe(new cn(e, this.predicate, this.thisArg)) + }, pn), + cn = (ut(hn, dn = Pt), hn.prototype._next = function(e) { + var t; + try { + t = this.predicate.call(this.thisArg, e, this.count++) + } catch (e) { + return void this.destination.error(e) + } + t && this.destination.next(e) + }, hn); + + function hn(e, t, i) { + e = dn.call(this, e) || this; + return e.predicate = t, e.thisArg = i, e.count = 0, e + } + + function pn(e, t) { + this.predicate = e, this.thisArg = t + } + + function fn() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + if (1 === e.length) { + if (!Et(e[0])) return e[0]; + e = e[0] + } + return Ui(e, void 0).lift(new gn) + } + var mn, gn = (Sn.prototype.call = function(e, t) { + return t.subscribe(new yn(e)) + }, Sn), + yn = (ut(vn, mn = vr), vn.prototype._next = function(e) { + this.observables.push(e) + }, vn.prototype._complete = function() { + var e = this.observables, + t = e.length; + if (0 === t) this.destination.complete(); + else { + for (var i = 0; i < t && !this.hasFirst; i++) { + var r = Cr(this, e[i], void 0, i); + this.subscriptions && this.subscriptions.push(r), this.add(r) + } + this.observables = null + } + }, vn.prototype.notifyNext = function(e, t, i) { + if (!this.hasFirst) { + this.hasFirst = !0; + for (var r, n = 0; n < this.subscriptions.length; n++) n !== i && ((r = this.subscriptions[n]).unsubscribe(), this.remove(r)); + this.subscriptions = null + } + this.destination.next(t) + }, vn); + + function vn(e) { + e = mn.call(this, e) || this; + return e.hasFirst = !1, e.observables = [], e.subscriptions = [], e + } + + function Sn() {} + + function bn(i, e, r) { + void 0 === i && (i = 0); + var n = -1; + return sn(e) ? n = Number(e) < 1 ? 1 : Number(e) : Ni(e) && (r = e), Ni(r) || (r = ir), new $t(function(e) { + var t = sn(i) ? i : +i - r.now(); + return r.schedule(Tn, t, { + index: 0, + period: n, + subscriber: e + }) + }) + } + + function Tn(e) { + var t = e.index, + i = e.period, + r = e.subscriber; + if (r.next(t), !r.closed) { + if (-1 === i) return r.complete(); + e.index = t + 1, this.schedule(e, i) + } + } + + function En() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + var i = e[e.length - 1]; + return "function" == typeof i && e.pop(), Ui(e, void 0).lift(new An(i)) + } + var In, wn, An = (Ln.prototype.call = function(e, t) { + return t.subscribe(new On(e, this.resultSelector)) + }, Ln), + On = (ut(Rn, wn = Pt), Rn.prototype._next = function(e) { + var t = this.iterators; + Et(e) ? t.push(new Cn(e)) : "function" == typeof e[wr] ? t.push(new kn(e[wr]())) : t.push(new Dn(this.destination, this, e)) + }, Rn.prototype._complete = function() { + var e = this.iterators, + t = e.length; + if (this.unsubscribe(), 0 !== t) { + this.active = t; + for (var i = 0; i < t; i++) { + var r = e[i]; + r.stillUnsubscribed ? this.destination.add(r.subscribe()) : this.active-- + } + } else this.destination.complete() + }, Rn.prototype.notifyInactive = function() { + this.active--, 0 === this.active && this.destination.complete() + }, Rn.prototype.checkIterators = function() { + for (var e = this.iterators, t = e.length, i = this.destination, r = 0; r < t; r++) + if ("function" == typeof(a = e[r]).hasValue && !a.hasValue()) return; + for (var n = !1, s = [], r = 0; r < t; r++) { + var a, o = (a = e[r]).next(); + if (a.hasCompleted() && (n = !0), o.done) return void i.complete(); + s.push(o.value) + } + this.resultSelector ? this._tryresultSelector(s) : i.next(s), n && i.complete() + }, Rn.prototype._tryresultSelector = function(e) { + var t; + try { + t = this.resultSelector.apply(this, e) + } catch (e) { + return void this.destination.error(e) + } + this.destination.next(t) + }, Rn), + kn = (Pn.prototype.hasValue = function() { + return !0 + }, Pn.prototype.next = function() { + var e = this.nextResult; + return this.nextResult = this.iterator.next(), e + }, Pn.prototype.hasCompleted = function() { + var e = this.nextResult; + return Boolean(e && e.done) + }, Pn), + Cn = (xn.prototype[wr] = function() { + return this + }, xn.prototype.next = function(e) { + var t = this.index++, + i = this.array; + return t < this.length ? { + value: i[t], + done: !1 + } : { + value: null, + done: !0 + } + }, xn.prototype.hasValue = function() { + return this.array.length > this.index + }, xn.prototype.hasCompleted = function() { + return this.array.length === this.index + }, xn), + Dn = (ut(Mn, In = Vr), Mn.prototype[wr] = function() { + return this + }, Mn.prototype.next = function() { + var e = this.buffer; + return 0 === e.length && this.isComplete ? { + value: null, + done: !0 + } : { + value: e.shift(), + done: !1 + } + }, Mn.prototype.hasValue = function() { + return 0 < this.buffer.length + }, Mn.prototype.hasCompleted = function() { + return 0 === this.buffer.length && this.isComplete + }, Mn.prototype.notifyComplete = function() { + 0 < this.buffer.length ? (this.isComplete = !0, this.parent.notifyInactive()) : this.destination.complete() + }, Mn.prototype.notifyNext = function(e) { + this.buffer.push(e), this.parent.checkIterators() + }, Mn.prototype.subscribe = function() { + return Hr(this.observable, new $r(this)) + }, Mn); + + function Mn(e, t, i) { + e = In.call(this, e) || this; + return e.parent = t, e.observable = i, e.stillUnsubscribed = !0, e.buffer = [], e.isComplete = !1, e + } + + function xn(e) { + this.array = e, this.index = 0, this.length = 0, this.length = e.length + } + + function Pn(e) { + this.iterator = e, this.nextResult = e.next() + } + + function Rn(e, t, i) { + e = wn.call(this, e) || this; + return e.resultSelector = t, e.iterators = [], e.active = 0, e.resultSelector = "function" == typeof t ? t : void 0, e + } + + function Ln(e) { + this.resultSelector = e + } + var _n, Nn = (Un.prototype.call = function(e, t) { + return t.subscribe(new Fn(e, this.durationSelector)) + }, Un), + Fn = (ut(Bn, _n = Vr), Bn.prototype._next = function(e) { + if (this.value = e, this.hasValue = !0, !this.throttled) { + var t = void 0; + try { + t = (0, this.durationSelector)(e) + } catch (e) { + return this.destination.error(e) + } + t = Hr(t, new $r(this)); + !t || t.closed ? this.clearThrottle() : this.add(this.throttled = t) + } + }, Bn.prototype.clearThrottle = function() { + var e = this.value, + t = this.hasValue, + i = this.throttled; + i && (this.remove(i), this.throttled = void 0, i.unsubscribe()), t && (this.value = void 0, this.hasValue = !1, this.destination.next(e)) + }, Bn.prototype.notifyNext = function() { + this.clearThrottle() + }, Bn.prototype.notifyComplete = function() { + this.clearThrottle() + }, Bn); + + function Bn(e, t) { + e = _n.call(this, e) || this; + return e.durationSelector = t, e.hasValue = !1, e + } + + function Un(e) { + this.durationSelector = e + } + + function $n(e, t) { + return void 0 === t && (t = ir), i = function() { + return bn(e, t) + }, + function(e) { + return e.lift(new Nn(i)) + }; + var i + } + + function Vn(i) { + return function(e) { + var t = new qn(i), + e = e.lift(t); + return t.caught = e + } + } + var Kn, qn = (Qn.prototype.call = function(e, t) { + return t.subscribe(new Hn(e, this.selector, this.caught)) + }, Qn), + Hn = (ut(jn, Kn = Vr), jn.prototype.error = function(e) { + if (!this.isStopped) { + var t = void 0; + try { + t = this.selector(e, this.caught) + } catch (e) { + return void Kn.prototype.error.call(this, e) + } + this._unsubscribeAndRecycle(); + var i = new $r(this); + this.add(i); + t = Hr(t, i); + t !== i && this.add(t) + } + }, jn); + + function jn(e, t, i) { + e = Kn.call(this, e) || this; + return e.selector = t, e.caught = i, e + } + + function Qn(e) { + this.selector = e + } + + function Wn(e, t) { + return jr(e, t, 1) + } + + function Gn(t, i) { + return void 0 === i && (i = ir), + function(e) { + return e.lift(new Xn(t, i)) + } + } + var zn, Xn = (Zn.prototype.call = function(e, t) { + return t.subscribe(new Yn(e, this.dueTime, this.scheduler)) + }, Zn), + Yn = (ut(Jn, zn = Pt), Jn.prototype._next = function(e) { + this.clearDebounce(), this.lastValue = e, this.hasValue = !0, this.add(this.debouncedSubscription = this.scheduler.schedule(es, this.dueTime, this)) + }, Jn.prototype._complete = function() { + this.debouncedNext(), this.destination.complete() + }, Jn.prototype.debouncedNext = function() { + var e; + this.clearDebounce(), this.hasValue && (e = this.lastValue, this.lastValue = null, this.hasValue = !1, this.destination.next(e)) + }, Jn.prototype.clearDebounce = function() { + var e = this.debouncedSubscription; + null !== e && (this.remove(e), e.unsubscribe(), this.debouncedSubscription = null) + }, Jn); + + function Jn(e, t, i) { + e = zn.call(this, e) || this; + return e.dueTime = t, e.scheduler = i, e.debouncedSubscription = null, e.lastValue = null, e.hasValue = !1, e + } + + function Zn(e, t) { + this.dueTime = e, this.scheduler = t + } + + function es(e) { + e.debouncedNext() + } + var ts, is = (ss.prototype.call = function(e, t) { + return t.subscribe(new rs(e, this.defaultValue)) + }, ss), + rs = (ut(ns, ts = Pt), ns.prototype._next = function(e) { + this.isEmpty = !1, this.destination.next(e) + }, ns.prototype._complete = function() { + this.isEmpty && this.destination.next(this.defaultValue), this.destination.complete() + }, ns); + + function ns(e, t) { + e = ts.call(this, e) || this; + return e.defaultValue = t, e.isEmpty = !0, e + } + + function ss(e) { + this.defaultValue = e + } + + function as(e) { + return e instanceof Date && !isNaN(+e) + } + var os, ls = (hs.prototype.call = function(e, t) { + return t.subscribe(new ds(e, this.delay, this.scheduler)) + }, hs), + ds = (ut(cs, os = Pt), cs.dispatch = function(e) { + for (var t, i = e.source, r = i.queue, n = e.scheduler, s = e.destination; 0 < r.length && r[0].time - n.now() <= 0;) r.shift().notification.observe(s); + 0 < r.length ? (t = Math.max(0, r[0].time - n.now()), this.schedule(e, t)) : (this.unsubscribe(), i.active = !1) + }, cs.prototype._schedule = function(e) { + this.active = !0, this.destination.add(e.schedule(cs.dispatch, this.delay, { + source: this, + destination: this.destination, + scheduler: e + })) + }, cs.prototype.scheduleNotification = function(e) { + var t; + !0 !== this.errored && (t = this.scheduler, e = new us(t.now() + this.delay, e), this.queue.push(e), !1 === this.active && this._schedule(t)) + }, cs.prototype._next = function(e) { + this.scheduleNotification(qi.createNext(e)) + }, cs.prototype._error = function(e) { + this.errored = !0, this.queue = [], this.destination.error(e), this.unsubscribe() + }, cs.prototype._complete = function() { + this.scheduleNotification(qi.createComplete()), this.unsubscribe() + }, cs), + us = function(e, t) { + this.time = e, this.notification = t + }; + + function cs(e, t, i) { + e = os.call(this, e) || this; + return e.delay = t, e.scheduler = i, e.queue = [], e.active = !1, e.errored = !1, e + } + + function hs(e, t) { + this.delay = e, this.scheduler = t + } + var ps, fs, ms, gs = (Es.prototype.call = function(e, t) { + return t.subscribe(new ys(e, this.delayDurationSelector)) + }, Es), + ys = (ut(Ts, ms = vr), Ts.prototype.notifyNext = function(e, t, i, r, n) { + this.destination.next(e), this.removeSubscription(n), this.tryComplete() + }, Ts.prototype.notifyError = function(e, t) { + this._error(e) + }, Ts.prototype.notifyComplete = function(e) { + e = this.removeSubscription(e); + e && this.destination.next(e), this.tryComplete() + }, Ts.prototype._next = function(e) { + var t = this.index++; + try { + var i = this.delayDurationSelector(e, t); + i && this.tryDelay(i, e) + } catch (e) { + this.destination.error(e) + } + }, Ts.prototype._complete = function() { + this.completed = !0, this.tryComplete(), this.unsubscribe() + }, Ts.prototype.removeSubscription = function(e) { + e.unsubscribe(); + var t = this.delayNotifierSubscriptions.indexOf(e); + return -1 !== t && this.delayNotifierSubscriptions.splice(t, 1), e.outerValue + }, Ts.prototype.tryDelay = function(e, t) { + t = Cr(this, e, t); + t && !t.closed && (this.destination.add(t), this.delayNotifierSubscriptions.push(t)) + }, Ts.prototype.tryComplete = function() { + this.completed && 0 === this.delayNotifierSubscriptions.length && this.destination.complete() + }, Ts), + vs = (ut(bs, fs = $t), bs.prototype._subscribe = function(e) { + this.subscriptionDelay.subscribe(new vs(e, this.source)) + }, ut(Ss, ps = Pt), Ss.prototype._next = function(e) { + this.subscribeToSource() + }, Ss.prototype._error = function(e) { + this.unsubscribe(), this.parent.error(e) + }, Ss.prototype._complete = function() { + this.unsubscribe(), this.subscribeToSource() + }, Ss.prototype.subscribeToSource = function() { + this.sourceSubscribed || (this.sourceSubscribed = !0, this.unsubscribe(), this.source.subscribe(this.parent)) + }, Ss); + + function Ss(e, t) { + var i = ps.call(this) || this; + return i.parent = e, i.source = t, i.sourceSubscribed = !1, i + } + + function bs(e, t) { + var i = fs.call(this) || this; + return i.source = e, i.subscriptionDelay = t, i + } + + function Ts(e, t) { + e = ms.call(this, e) || this; + return e.delayDurationSelector = t, e.completed = !1, e.delayNotifierSubscriptions = [], e.index = 0, e + } + + function Es(e) { + this.delayDurationSelector = e + } + + function Is(t, i) { + return function(e) { + return e.lift(new As(t, i)) + } + } + var ws, As = (Cs.prototype.call = function(e, t) { + return t.subscribe(new Os(e, this.compare, this.keySelector)) + }, Cs), + Os = (ut(ks, ws = Pt), ks.prototype.compare = function(e, t) { + return e === t + }, ks.prototype._next = function(e) { + try { + var t = this.keySelector, + i = t ? t(e) : e + } catch (e) { + return this.destination.error(e) + } + t = !1; + if (this.hasKey) try { + t = (0, this.compare)(this.key, i) + } catch (e) { + return this.destination.error(e) + } else this.hasKey = !0; + t || (this.key = i, this.destination.next(e)) + }, ks); + + function ks(e, t, i) { + e = ws.call(this, e) || this; + return e.keySelector = i, e.hasKey = !1, "function" == typeof t && (e.compare = t), e + } + + function Cs(e, t) { + this.compare = e, this.keySelector = t + } + + function Ds(t) { + return function(e) { + return 0 === t ? _i() : e.lift(new xs(t)) + } + } + var Ms, xs = (Ls.prototype.call = function(e, t) { + return t.subscribe(new Ps(e, this.total)) + }, Ls), + Ps = (ut(Rs, Ms = Pt), Rs.prototype._next = function(e) { + var t = this.total, + i = ++this.count; + i <= t && (this.destination.next(e), i === t && (this.destination.complete(), this.unsubscribe())) + }, Rs); + + function Rs(e, t) { + e = Ms.call(this, e) || this; + return e.total = t, e.count = 0, e + } + + function Ls(e) { + if (this.total = e, this.total < 0) throw new lr + } + + function _s(t, n) { + return n ? function(e) { + return e.pipe(_s(function(i, r) { + return Fr(t(i, r)).pipe(hr(function(e, t) { + return n(i, e, r, t) + })) + })) + } : function(e) { + return e.lift(new Fs(t)) + } + } + var Ns, Fs = ($s.prototype.call = function(e, t) { + return t.subscribe(new Bs(e, this.project)) + }, $s), + Bs = (ut(Us, Ns = Vr), Us.prototype._next = function(e) { + this.hasSubscription || this.tryNext(e) + }, Us.prototype.tryNext = function(e) { + var t, i = this.index++; + try { + t = this.project(e, i) + } catch (e) { + return void this.destination.error(e) + } + this.hasSubscription = !0, this._innerSub(t) + }, Us.prototype._innerSub = function(e) { + var t = new $r(this), + i = this.destination; + i.add(t); + e = Hr(e, t); + e !== t && i.add(e) + }, Us.prototype._complete = function() { + this.hasCompleted = !0, this.hasSubscription || this.destination.complete(), this.unsubscribe() + }, Us.prototype.notifyNext = function(e) { + this.destination.next(e) + }, Us.prototype.notifyError = function(e) { + this.destination.error(e) + }, Us.prototype.notifyComplete = function() { + this.hasSubscription = !1, this.hasCompleted && this.destination.complete() + }, Us); + + function Us(e, t) { + e = Ns.call(this, e) || this; + return e.project = t, e.hasSubscription = !1, e.hasCompleted = !1, e.index = 0, e + } + + function $s(e) { + this.project = e + } + + function Vs(t) { + return function(e) { + return e.lift(new qs(t)) + } + } + var Ks, qs = (Qs.prototype.call = function(e, t) { + return t.subscribe(new Hs(e, this.callback)) + }, Qs), + Hs = (ut(js, Ks = Pt), js); + + function js(e, t) { + e = Ks.call(this, e) || this; + return e.add(new At(t)), e + } + + function Qs(e) { + this.callback = e + } + + function Ws(t) { + return function(e) { + return 0 === t ? _i() : e.lift(new zs(t)) + } + } + var Gs, zs = (Js.prototype.call = function(e, t) { + return t.subscribe(new Xs(e, this.total)) + }, Js), + Xs = (ut(Ys, Gs = Pt), Ys.prototype._next = function(e) { + var t = this.ring, + i = this.total, + r = this.count++; + t.length < i ? t.push(e) : t[r % i] = e + }, Ys.prototype._complete = function() { + var e = this.destination, + t = this.count; + if (0 < t) + for (var i = this.count >= this.total ? this.total : this.count, r = this.ring, n = 0; n < i; n++) { + var s = t++ % i; + e.next(r[s]) + } + e.complete() + }, Ys); + + function Ys(e, t) { + e = Gs.call(this, e) || this; + return e.total = t, e.ring = new Array, e.count = 0, e + } + + function Js(e) { + if (this.total = e, this.total < 0) throw new lr + } + + function Zs(t) { + return function(e) { + return e.lift(new ta(t)) + } + } + var ea, ta = (na.prototype.call = function(e, t) { + return t.subscribe(new ia(e, this.value)) + }, na), + ia = (ut(ra, ea = Pt), ra.prototype._next = function(e) { + this.destination.next(this.value) + }, ra); + + function ra(e, t) { + e = ea.call(this, e) || this; + return e.value = t, e + } + + function na(e) { + this.value = e + } + + function sa(t, i) { + var r = 2 <= arguments.length ? !0 : !1; + return function(e) { + return e.lift(new oa(t, i, r)) + } + } + var aa, oa = (ua.prototype.call = function(e, t) { + return t.subscribe(new la(e, this.accumulator, this.seed, this.hasSeed)) + }, ua), + la = (ut(da, aa = Pt), Object.defineProperty(da.prototype, "seed", { + get: function() { + return this._seed + }, + set: function(e) { + this.hasSeed = !0, this._seed = e + }, + enumerable: !0, + configurable: !0 + }), da.prototype._next = function(e) { + if (this.hasSeed) return this._tryNext(e); + this.seed = e, this.destination.next(e) + }, da.prototype._tryNext = function(e) { + var t, i = this.index++; + try { + t = this.accumulator(this.seed, e, i) + } catch (e) { + this.destination.error(e) + } + this.seed = t, this.destination.next(t) + }, da); + + function da(e, t, i, r) { + e = aa.call(this, e) || this; + return e.accumulator = t, e._seed = i, e.hasSeed = r, e.index = 0, e + } + + function ua(e, t, i) { + void 0 === i && (i = !1), this.accumulator = e, this.seed = t, this.hasSeed = i + } + ca.prototype.call = function(e, t) { + var i = this.selector, + r = this.subjectFactory(), + e = i(r).subscribe(e); + return e.add(t.subscribe(r)), e + }; + + function ca(e, t) { + this.subjectFactory = e, this.selector = t + } + + function ha() { + return function(e) { + return e.lift(new fa) + } + } + var pa, fa = (ya.prototype.call = function(e, t) { + return t.subscribe(new ma(e)) + }, ya), + ma = (ut(ga, pa = Pt), ga.prototype._next = function(e) { + var t; + this.hasPrev ? t = [this.prev, e] : this.hasPrev = !0, this.prev = e, t && this.destination.next(t) + }, ga); + + function ga(e) { + e = pa.call(this, e) || this; + return e.hasPrev = !1, e + } + + function ya() {} + + function va(t) { + return function(e) { + return e.lift(new ba(t, e)) + } + } + var Sa, ba = (Ia.prototype.call = function(e, t) { + return t.subscribe(new Ta(e, this.notifier, this.source)) + }, Ia), + Ta = (ut(Ea, Sa = Vr), Ea.prototype.error = function(e) { + if (!this.isStopped) { + var t = this.errors, + i = this.retries, + r = this.retriesSubscription; + if (i) this.errors = void 0, this.retriesSubscription = void 0; + else { + t = new Xt; + try { + i = (0, this.notifier)(t) + } catch (e) { + return Sa.prototype.error.call(this, e) + } + r = Hr(i, new $r(this)) + } + this._unsubscribeAndRecycle(), this.errors = t, this.retries = i, this.retriesSubscription = r, t.next(e) + } + }, Ea.prototype._unsubscribe = function() { + var e = this.errors, + t = this.retriesSubscription; + e && (e.unsubscribe(), this.errors = void 0), t && (t.unsubscribe(), this.retriesSubscription = void 0), this.retries = void 0 + }, Ea.prototype.notifyNext = function() { + var e = this._unsubscribe; + this._unsubscribe = null, this._unsubscribeAndRecycle(), this._unsubscribe = e, this.source.subscribe(this) + }, Ea); + + function Ea(e, t, i) { + e = Sa.call(this, e) || this; + return e.notifier = t, e.source = i, e + } + + function Ia(e, t) { + this.notifier = e, this.source = t + } + + function wa() { + return new Xt + } + + function Aa() { + return function(e) { + return ri()((t = e, i = "function" == typeof(r = wa) ? r : function() { + return r + }, (e = Object.create(t, mi)).source = t, e.subjectFactory = i, e)); + var t, i, r + } + } + + function Oa(e, t, i) { + var c = e && "object" == typeof e ? e : { + bufferSize: e, + windowTime: t, + refCount: !1, + scheduler: i + }; + return function(e) { + return e.lift((e = c.bufferSize, n = void 0 === e ? Number.POSITIVE_INFINITY : e, e = c.windowTime, s = void 0 === e ? Number.POSITIVE_INFINITY : e, a = c.refCount, o = c.scheduler, l = 0, u = d = !1, function(e) { + var t; + l++, !i || d ? (d = !1, i = new Ji(n, s, o), t = i.subscribe(this), r = e.subscribe({ + next: function(e) { + i.next(e) + }, + error: function(e) { + d = !0, i.error(e) + }, + complete: function() { + u = !0, r = void 0, i.complete() + } + }), u && (r = void 0)) : t = i.subscribe(this), this.add(function() { + l--, t.unsubscribe(), t = void 0, r && !u && a && 0 === l && (r.unsubscribe(), i = r = void 0) + }) + })); + var i, r, n, s, a, o, l, d, u + } + } + + function ka(t) { + return function(e) { + return e.lift(new Da(t)) + } + } + var Ca, Da = (Pa.prototype.call = function(e, t) { + return t.subscribe(new Ma(e, this.total)) + }, Pa), + Ma = (ut(xa, Ca = Pt), xa.prototype._next = function(e) { + ++this.count > this.total && this.destination.next(e) + }, xa); + + function xa(e, t) { + e = Ca.call(this, e) || this; + return e.total = t, e.count = 0, e + } + + function Pa(e) { + this.total = e + } + + function Ra() { + for (var t = [], e = 0; e < arguments.length; e++) t[e] = arguments[e]; + var i = t[t.length - 1]; + return Ni(i) ? (t.pop(), function(e) { + return Jr(t, e, i) + }) : function(e) { + return Jr(t, e) + } + } + + function La(t, n) { + return "function" == typeof n ? function(e) { + return e.pipe(La(function(i, r) { + return Fr(t(i, r)).pipe(hr(function(e, t) { + return n(i, e, r, t) + })) + })) + } : function(e) { + return e.lift(new Na(t)) + } + } + var _a, Na = (Ua.prototype.call = function(e, t) { + return t.subscribe(new Fa(e, this.project)) + }, Ua), + Fa = (ut(Ba, _a = Vr), Ba.prototype._next = function(e) { + var t, i = this.index++; + try { + t = this.project(e, i) + } catch (e) { + return void this.destination.error(e) + } + this._innerSub(t) + }, Ba.prototype._innerSub = function(e) { + var t = this.innerSubscription; + t && t.unsubscribe(); + var i = new $r(this), + t = this.destination; + t.add(i), this.innerSubscription = Hr(e, i), this.innerSubscription !== i && t.add(this.innerSubscription) + }, Ba.prototype._complete = function() { + var e = this.innerSubscription; + e && !e.closed || _a.prototype._complete.call(this), this.unsubscribe() + }, Ba.prototype._unsubscribe = function() { + this.innerSubscription = void 0 + }, Ba.prototype.notifyComplete = function() { + this.innerSubscription = void 0, this.isStopped && _a.prototype._complete.call(this) + }, Ba.prototype.notifyNext = function(e) { + this.destination.next(e) + }, Ba); + + function Ba(e, t) { + e = _a.call(this, e) || this; + return e.project = t, e.index = 0, e + } + + function Ua(e) { + this.project = e + } + + function $a(e, t) { + return t ? La(function() { + return e + }, t) : La(function() { + return e + }) + } + + function Va(t) { + return function(e) { + return e.lift(new qa(t)) + } + } + var Ka, qa = (Qa.prototype.call = function(e, t) { + var i = new Ha(e), + e = Hr(this.notifier, new $r(i)); + return e && !i.seenValue ? (i.add(e), t.subscribe(i)) : i + }, Qa), + Ha = (ut(ja, Ka = Vr), ja.prototype.notifyNext = function() { + this.seenValue = !0, this.complete() + }, ja.prototype.notifyComplete = function() {}, ja); + + function ja(e) { + e = Ka.call(this, e) || this; + return e.seenValue = !1, e + } + + function Qa(e) { + this.notifier = e + } + + function Wa(t, i) { + return void 0 === i && (i = !1), + function(e) { + return e.lift(new za(t, i)) + } + } + var Ga, za = (Ja.prototype.call = function(e, t) { + return t.subscribe(new Xa(e, this.predicate, this.inclusive)) + }, Ja), + Xa = (ut(Ya, Ga = Pt), Ya.prototype._next = function(e) { + var t, i = this.destination; + try { + t = this.predicate(e, this.index++) + } catch (e) { + return void i.error(e) + } + this.nextOrComplete(e, t) + }, Ya.prototype.nextOrComplete = function(e, t) { + var i = this.destination; + Boolean(t) ? i.next(e) : (this.inclusive && i.next(e), i.complete()) + }, Ya); + + function Ya(e, t, i) { + e = Ga.call(this, e) || this; + return e.predicate = t, e.inclusive = i, e.index = 0, e + } + + function Ja(e, t) { + this.predicate = e, this.inclusive = t + } + + function Za(t, i, r) { + return function(e) { + return e.lift(new to(t, i, r)) + } + } + var eo, to = (so.prototype.call = function(e, t) { + return t.subscribe(new io(e, this.nextOrObserver, this.error, this.complete)) + }, so), + io = (ut(no, eo = Pt), no.prototype._next = function(e) { + try { + this._tapNext.call(this._context, e) + } catch (e) { + return void this.destination.error(e) + } + this.destination.next(e) + }, no.prototype._error = function(e) { + try { + this._tapError.call(this._context, e) + } catch (e) { + return void this.destination.error(e) + } + this.destination.error(e) + }, no.prototype._complete = function() { + try { + this._tapComplete.call(this._context) + } catch (e) { + return void this.destination.error(e) + } + return this.destination.complete() + }, no), + ro = { + leading: !0, + trailing: !1 + }; + + function no(e, t, i, r) { + e = eo.call(this, e) || this; + return e._tapNext = or, e._tapError = or, e._tapComplete = or, e._tapError = i || or, e._tapComplete = r || or, yt(t) ? (e._context = e)._tapNext = t : t && (e._context = t, e._tapNext = t.next || or, e._tapError = t.error || or, e._tapComplete = t.complete || or), e + } + + function so(e, t, i) { + this.nextOrObserver = e, this.error = t, this.complete = i + } + + function ao(t, i, r) { + return void 0 === i && (i = ir), void 0 === r && (r = ro), + function(e) { + return e.lift(new lo(t, i, r.leading, r.trailing)) + } + } + var oo, lo = (ho.prototype.call = function(e, t) { + return t.subscribe(new uo(e, this.duration, this.scheduler, this.leading, this.trailing)) + }, ho), + uo = (ut(co, oo = Pt), co.prototype._next = function(e) { + this.throttled ? this.trailing && (this._trailingValue = e, this._hasTrailingValue = !0) : (this.add(this.throttled = this.scheduler.schedule(po, this.duration, { + subscriber: this + })), this.leading ? this.destination.next(e) : this.trailing && (this._trailingValue = e, this._hasTrailingValue = !0)) + }, co.prototype._complete = function() { + this._hasTrailingValue && this.destination.next(this._trailingValue), this.destination.complete() + }, co.prototype.clearThrottle = function() { + var e = this.throttled; + e && (this.trailing && this._hasTrailingValue && (this.destination.next(this._trailingValue), this._trailingValue = null, this._hasTrailingValue = !1), e.unsubscribe(), this.remove(e), this.throttled = null) + }, co); + + function co(e, t, i, r, n) { + e = oo.call(this, e) || this; + return e.duration = t, e.scheduler = i, e.leading = r, e.trailing = n, e._hasTrailingValue = !1, e._trailingValue = null, e + } + + function ho(e, t, i, r) { + this.duration = e, this.scheduler = t, this.leading = i, this.trailing = r + } + + function po(e) { + e.subscriber.clearThrottle() + } + var fo, mo = (vo.prototype.call = function(e, t) { + return t.subscribe(new go(e, this.absoluteTimeout, this.waitFor, this.withObservable, this.scheduler)) + }, vo), + go = (ut(yo, fo = Vr), yo.dispatchTimeout = function(e) { + var t = e.withObservable; + e._unsubscribeAndRecycle(), e.add(Hr(t, new $r(e))) + }, yo.prototype.scheduleTimeout = function() { + var e = this.action; + e ? this.action = e.schedule(this, this.waitFor) : this.add(this.action = this.scheduler.schedule(yo.dispatchTimeout, this.waitFor, this)) + }, yo.prototype._next = function(e) { + this.absoluteTimeout || this.scheduleTimeout(), fo.prototype._next.call(this, e) + }, yo.prototype._unsubscribe = function() { + this.action = void 0, this.scheduler = null, this.withObservable = null + }, yo); + + function yo(e, t, i, r, n) { + e = fo.call(this, e) || this; + return e.absoluteTimeout = t, e.waitFor = i, e.withObservable = r, e.scheduler = n, e.scheduleTimeout(), e + } + + function vo(e, t, i, r) { + this.waitFor = e, this.absoluteTimeout = t, this.withObservable = i, this.scheduler = r + } + + function So(e, t) { + return void 0 === t && (t = ir), r = e, n = Vi(new dr), void 0 === (s = t) && (s = ir), + function(e) { + var t = as(r), + i = t ? +r - s.now() : Math.abs(r); + return e.lift(new mo(i, t, n, s)) + }; + var r, n, s + } + + function bo() { + for (var i = [], e = 0; e < arguments.length; e++) i[e] = arguments[e]; + return function(e) { + var t; + return "function" == typeof i[i.length - 1] && (t = i.pop()), e.lift(new Io(i, t)) + } + } + var To, Eo, Io = (Co.prototype.call = function(e, t) { + return t.subscribe(new wo(e, this.observables, this.project)) + }, Co), + wo = (ut(ko, To = vr), ko.prototype.notifyNext = function(e, t, i) { + this.values[i] = t; + t = this.toRespond; + 0 < t.length && (-1 !== (i = t.indexOf(i)) && t.splice(i, 1)) + }, ko.prototype.notifyComplete = function() {}, ko.prototype._next = function(e) { + 0 === this.toRespond.length && (e = [e].concat(this.values), this.project ? this._tryProject(e) : this.destination.next(e)) + }, ko.prototype._tryProject = function(e) { + var t; + try { + t = this.project.apply(this, e) + } catch (e) { + return void this.destination.error(e) + } + this.destination.next(t) + }, ko), + Ao = { + type: null, + entityIds: null, + skip: !1 + }, + Oo = !1; + + function ko(e, t, i) { + var r = To.call(this, e) || this; + r.observables = t, r.project = i, r.toRespond = []; + var n = t.length; + r.values = new Array(n); + for (var s = 0; s < n; s++) r.toRespond.push(s); + for (s = 0; s < n; s++) { + var a = t[s]; + r.add(Cr(r, a, void 0, s)) + } + return r + } + + function Co(e, t) { + this.observables = e, this.project = t + } + + function Do(e, t) { + Mo(e, t), Oo = !0 + } + + function Mo(e, t) { + !1 === Oo && (Ao.type = e, Ao.entityIds = t) + } + + function xo(e, t) { + return e.hasOwnProperty(t) + } + + function Po(e) { + return null == e + } + + function Ro(e) { + return Po(e) ? [] : Array.isArray(e) ? e : [e] + }(iu = Eo = Eo || {}).Set = "Set", iu.Add = "Add", iu.Update = "Update", iu.Remove = "Remove"; + var Lo = "undefined" != typeof window, + _o = !0; + + function No(e) { + var t = typeof e; + return null != e && ("object" == t || "function" == t) + } + + function Fo(e) { + return Array.isArray(e) + } + + function Bo(e) { + return !1 === Po(e) + } + + function Uo(e) { + return Fo(e) && 0 === e.length + } + + function $o(e) { + return "function" == typeof e + } + + function Vo(e) { + return void 0 === e + } + + function Ko(e) { + return e.hasOwnProperty("active") + } + + function qo(e) { + return Fo(e) + } + + function Ho(e) { + var t, i = e.active, + r = e.ids, + n = e.entities; + return qo(i) ? (t = r, (r = (e = i).filter(function(e) { + return -1 < t.indexOf(e) + })).length === e.length ? e : r) : !1 === xo(n, i) ? null : i + } + + function jo(e, t) { + var i, r, n = {}; + try { + for (var s = ft(Object.keys(e)), a = s.next(); !a.done; a = s.next()) { + var o = a.value; + n[o] = t(e[o]) + } + } catch (e) { + i = { + error: e + } + } finally { + try { + a && !a.done && (r = s.return) && r.call(s) + } finally { + if (i) throw i.error + } + } + return n + } + var Qo = { + resettable: !1, + ttl: null, + producerFn: void 0 + }; + + function Wo(t) { + Object.freeze(t); + var i = "function" == typeof t, + r = Object.prototype.hasOwnProperty; + return Object.getOwnPropertyNames(t).forEach(function(e) { + !r.call(t, e) || i && ("caller" === e || "callee" === e || "arguments" === e) || null === t[e] || "object" != typeof t[e] && "function" != typeof t[e] || Object.isFrozen(t[e]) || Wo(t[e]) + }), t + } + var Go, zo = new Xt, + Xo = new Ji(50, 5e3), + Yo = new Xt; + + function Jo(e) { + return null != e && "" + e != "false" + } + + function Zo(e) { + return Jo(e) && "Object" === e.constructor.name + } + ut(function(e) { + return Go.call(this, e) || this + }, Go = Error); + var el = {}, + tl = {}; + Lo && (window.$$stores = el, window.$$queries = tl); + var il = new Xt, + rl = new yi(!1), + nl = { + activeTransactions: 0, + batchTransaction: null + }; + + function sl() { + return 0 < nl.activeTransactions + } + + function al(e, t) { + void 0 === t && (t = void 0), sl() || (nl.batchTransaction = new Xt), nl.activeTransactions++, rl.next(!0); + try { + return e.apply(t) + } finally { + Do("@Transaction"), 0 == --nl.activeTransactions && (nl.batchTransaction.next(!0), nl.batchTransaction.complete(), rl.next(!1), il.next(!0)) + } + } + + function ol() { + return function(e, t, i) { + var r = i.value; + return i.value = function() { + for (var e = this, t = [], i = 0; i < arguments.length; i++) t[i] = arguments[i]; + return al(function() { + return r.apply(e, t) + }, this) + }, i + } + } + + function ll(t) { + return function(e) { + return e.pipe(Za(function(e) { + return al(function() { + return t(e) + }) + })) + } + } + var dl = (ul.prototype.setLoading = function(t) { + (t = void 0 === t ? !1 : t) !== this._value().loading && (_o && Mo("Set Loading"), this._setState(function(e) { + return ct({}, e, { + loading: t + }) + })) + }, ul.prototype.setHasCache = function(e, t) { + var i, r = this; + void 0 === t && (t = { + restartTTL: !1 + }), e !== this.cache.active.value && this.cache.active.next(e), t.restartTTL && (i = this.getCacheTTL()) && (null !== this.cache.ttl && clearTimeout(this.cache.ttl), this.cache.ttl = setTimeout(function() { + return r.setHasCache(!1) + }, i)) + }, ul.prototype.getValue = function() { + return this.storeValue + }, ul.prototype.setError = function(t) { + t !== this._value().error && (_o && Mo("Set Error"), this._setState(function(e) { + return ct({}, e, { + error: t + }) + })) + }, ul.prototype._select = function(t) { + return this.store.asObservable().pipe(hr(function(e) { + return t(e.state) + }), Is()) + }, ul.prototype._value = function() { + return this.storeValue + }, ul.prototype._cache = function() { + return this.cache.active + }, Object.defineProperty(ul.prototype, "config", { + get: function() { + return this.constructor.akitaConfig || {} + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(ul.prototype, "storeName", { + get: function() { + return this.config.storeName || this.options.storeName || this.options.name + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(ul.prototype, "deepFreeze", { + get: function() { + return this.config.deepFreezeFn || this.options.deepFreezeFn || Wo + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(ul.prototype, "cacheConfig", { + get: function() { + return this.config.cache || this.options.cache + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(ul.prototype, "_producerFn", { + get: function() { + return this.config.producerFn || this.options.producerFn || Qo.producerFn + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(ul.prototype, "resettable", { + get: function() { + return (Bo(this.config.resettable) ? this.config : this.options).resettable + }, + enumerable: !0, + configurable: !0 + }), ul.prototype._setState = function(e, t) { + var i, r = this; + if (void 0 === t && (t = !0), $o(e) ? (i = e(this._value()), this.storeValue = _o ? this.deepFreeze(i) : i) : this.storeValue = e, !this.store) return this.store = new yi({ + state: this.storeValue + }), void(_o && this.store.subscribe(function(e) { + var t = e.action; + t && (e = r.storeName, Yo.next({ + storeName: e, + action: t + })) + })); + sl() ? this.handleTransaction() : this.dispatch(this.storeValue, t) + }, ul.prototype.reset = function() { + var e = this; + this.isResettable() ? (_o && Mo("Reset"), this._setState(function() { + return Object.assign({}, e._initialState) + }), this.setHasCache(!1)) : _o && console.warn("You need to enable the reset functionality") + }, ul.prototype.update = function(e) { + _o && Mo("Update"); + var t = this._value(), + e = $o(e) ? $o(this._producerFn) ? this._producerFn(t, e) : e(t) : e, + e = this.akitaPreUpdate(t, ct({}, t, e)), + e = Zo(t) ? e : new t.constructor(e); + this._setState(e) + }, ul.prototype.updateStoreConfig = function(e) { + this.options = ct({}, this.options, e) + }, ul.prototype.akitaPreUpdate = function(e, t) { + return t + }, ul.prototype.ngOnDestroy = function() { + this.destroy() + }, ul.prototype.destroy = function() { + var e; + Lo && window.hmrEnabled || this !== el[this.storeName] || (delete el[this.storeName], e = this.storeName, zo.next(e), this.setHasCache(!1), this.cache.active.complete(), this.store.complete()) + }, ul.prototype.onInit = function(e) { + var t, i; + (el[this.storeName] = this)._setState(function() { + return e + }), i = this.storeName, Xo.next(i), this.isResettable() && (this._initialState = e), _o && (t = this.storeName, i = this.constructor.name, t || console.error("@StoreConfig({ name }) is missing in " + i)) + }, ul.prototype.dispatch = function(e, t) { + var i = void 0; + (t = void 0 === t ? !0 : t) && (i = Ao, Oo = !1), this.store.next({ + state: e, + action: i + }) + }, ul.prototype.watchTransaction = function() { + var e = this; + (nl.batchTransaction ? nl.batchTransaction.asObservable() : $i(!0)).subscribe(function() { + e.inTransaction = !1, e.dispatch(e._value()) + }) + }, ul.prototype.isResettable = function() { + return !1 !== this.resettable && (this.resettable || Qo.resettable) + }, ul.prototype.handleTransaction = function() { + this.inTransaction || (this.watchTransaction(), this.inTransaction = !0) + }, ul.prototype.getCacheTTL = function() { + return this.cacheConfig && this.cacheConfig.ttl || Qo.ttl + }, ul); + + function ul(e, t) { + this.options = t = void 0 === t ? {} : t, this.inTransaction = !1, this.cache = { + active: new yi(!1), + ttl: null + }, this.onInit(e) + } + var cl, hl, pl, fl = (ut(yl, pl = dl), Object.defineProperty(yl.prototype, "selectEntityAction$", { + get: function() { + return this.entityActions.asObservable() + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(yl.prototype, "selectEntityIdChanges$", { + get: function() { + return this.entityIdChanges.asObservable() + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(yl.prototype, "idKey", { + get: function() { + return this.config.idKey || this.options.idKey || "id" + }, + enumerable: !0, + configurable: !0 + }), yl.prototype.set = function(a, o) { + var l, d = this; + void 0 === o && (o = {}), Po(a) || (_o && Mo("Set Entity"), l = this.akitaPreAddEntity === yl.prototype.akitaPreAddEntity, this.setHasCache(!0, { + restartTTL: !0 + }), this._setState(function(e) { + var t, i, r, n, s, e = (t = { + state: e, + entities: a, + idKey: d.idKey, + preAddEntity: d.akitaPreAddEntity, + isNativePreAdd: l + }, r = t.state, n = t.entities, s = t.idKey, e = t.preAddEntity, t = t.isNativePreAdd, e = Fo(n) ? (i = (s = function(e, t, i) { + var r, n, s = { + entities: {}, + ids: [] + }; + try { + for (var a = ft(e), o = a.next(); !o.done; o = a.next()) { + var l = i(o.value); + s.entities[l[t]] = l, s.ids.push(l[t]) + } + } catch (e) { + r = { + error: e + } + } finally { + try { + o && !o.done && (n = a.return) && n.call(a) + } finally { + if (r) throw r.error + } + } + return s + }(n, s, e)).entities, s.ids) : n.entities && n.ids ? (i = t ? n.entities : jo(n.entities, e), n.ids) : (i = t ? n : jo(n, e), Object.keys(i).map(function(e) { + return isNaN(e) ? e : Number(e) + })), e = ct({}, r, { + entities: i, + ids: e, + loading: !1 + }), Ko(r) && (e.active = Ho(e)), e); + return !1 === Vo(o.activeId) && (e.active = o.activeId), e + }), this.hasInitialUIState() && this.handleUICreation(), this.entityActions.next({ + type: Eo.Set, + ids: this.ids + })) + }, yl.prototype.add = function(e, t) { + void 0 === t && (t = { + loading: !1 + }); + var i, e = Ro(e); + Uo(e) || (i = function(e) { + var t, i, r = e.state, + n = e.entities, + s = e.idKey, + a = e.options, + o = void 0 === a ? {} : a, + l = e.preAddEntity, + d = {}, + u = [], + c = !1; + try { + for (var h = ft(n), p = h.next(); !p.done; p = h.next()) { + var f, m, g = p.value; + !1 === xo(r.entities, g[s]) && (d[m = (f = l(g))[s]] = f, o.prepend ? u.unshift(m) : u.push(m), c = !0) + } + } catch (e) { + t = { + error: e + } + } finally { + try { + p && !p.done && (i = h.return) && i.call(h) + } finally { + if (t) throw t.error + } + } + return c ? { + newState: ct({}, r, { + entities: ct({}, r.entities, d), + ids: o.prepend ? gt(u, r.ids) : gt(r.ids, u) + }), + newIds: u + } : null + }({ + state: this._value(), + preAddEntity: this.akitaPreAddEntity, + entities: e, + idKey: this.idKey, + options: t + })) && (_o && Mo("Add Entity"), i.newState.loading = t.loading, this._setState(function() { + return i.newState + }), this.hasInitialUIState() && this.handleUICreation(!0), this.entityActions.next({ + type: Eo.Add, + ids: i.newIds + })) + }, yl.prototype.update = function(t, i) { + var r, n, s = this; + Vo(i) ? pl.prototype.update.call(this, t) : (n = [], Uo(n = $o(t) ? this.ids.filter(function(e) { + return t(s.entities[e]) + }) : Po(t) ? this.ids : Ro(t)) || (_o && Mo("Update Entity", n), this._setState(function(e) { + return function(e) { + var t = e.state, + i = e.ids, + r = e.idKey, + n = e.newStateOrFn, + s = e.preUpdateEntity, + a = e.producerFn, + o = e.onEntityIdChanges, + l = {}, + d = !1; + try { + for (var u = ft(i), c = u.next(); !c.done; c = u.next()) { + var h, p, f, m, g, y, v = c.value; + !1 !== xo(t.entities, v) && (h = t.entities[v], p = void 0, f = (p = $o(n) ? $o(a) ? a(h, n) : n(h) : n).hasOwnProperty(r) && p[r] !== h[r], y = void 0, m = v, f && (d = !0, m = p[r]), g = ct({}, h, p), y = Zo(h) ? g : new(Zo(p) ? h : p).constructor(g), l[m] = s(h, y)) + } + } catch (e) { + T = { + error: e + } + } finally { + try { + c && !c.done && (b = u.return) && b.call(u) + } finally { + if (T) throw T.error + } + } + var S, b = t.ids, + T = t.entities; + return d && (S = mt(i, 1)[0], T = function(e, t) { + var i = {}; + for (n in e) Object.prototype.hasOwnProperty.call(e, n) && t.indexOf(n) < 0 && (i[n] = e[n]); + if (null != e && "function" == typeof Object.getOwnPropertySymbols) + for (var r = 0, n = Object.getOwnPropertySymbols(e); r < n.length; r++) t.indexOf(n[r]) < 0 && Object.prototype.propertyIsEnumerable.call(e, n[r]) && (i[n[r]] = e[n[r]]); + return i + }(t.entities, ["symbol" == typeof S ? S : S + ""]), b = t.ids.map(function(e) { + return e === S ? m : e + }), o(S, m)), ct({}, t, { + entities: ct({}, T, l), + ids: b + }) + }({ + idKey: s.idKey, + ids: n, + preUpdateEntity: s.akitaPreUpdateEntity, + state: e, + newStateOrFn: i, + producerFn: s._producerFn, + onEntityIdChanges: function(e, t) { + r = { + oldId: e, + newId: t + }, s.entityIdChanges.next(ct({}, r, { + pending: !0 + })) + } + }) + }), r && this.entityIdChanges.next(ct({}, r, { + pending: !1 + })), this.entityActions.next({ + type: Eo.Update, + ids: n + }))) + }, yl.prototype.upsert = function(e, i, r, t) { + var n = this; + void 0 === t && (t = {}); + var s = Ro(e), + e = function(t) { + return function(e) { + return xo(n.entities, e) === t + } + }, + a = $o(r) ? t.baseClass : r ? r.baseClass : void 0, + o = $o(a), + t = s.filter(e(!0)), + e = s.filter(e(!1)).map(function(e) { + var t = "function" == typeof i ? i({}) : i, + t = $o(r) ? r(e, t) : t, + t = ct({}, t, ((t = {})[n.idKey] = e, t)); + return o ? new a(t) : t + }); + this.update(t, i), this.add(e), _o && Do("Upsert Entity") + }, yl.prototype.upsertMany = function(e, t) { + var i, r; + void 0 === t && (t = {}); + var n = [], + s = [], + a = {}; + try { + for (var o = ft(e), l = o.next(); !l.done; l = o.next()) { + var d, u, c, h, p, f, m = l.value, + g = this.akitaPreCheckEntity(m), + y = g[this.idKey]; + xo(this.entities, y) ? (d = this._value().entities[y], u = ct({}, this._value().entities[y], g), c = t.baseClass ? new t.baseClass(u) : u, f = (h = this.akitaPreUpdateEntity(d, c))[this.idKey], a[f] = h, s.push(f)) : (p = t.baseClass ? new t.baseClass(g) : g, f = (h = this.akitaPreAddEntity(p))[this.idKey], n.push(f), a[f] = h) + } + } catch (e) { + i = { + error: e + } + } finally { + try { + l && !l.done && (r = o.return) && r.call(o) + } finally { + if (i) throw i.error + } + } + _o && Do("Upsert Many"), this._setState(function(e) { + return ct({}, e, { + ids: n.length ? gt(e.ids, n) : e.ids, + entities: ct({}, e.entities, a), + loading: !!t.loading + }) + }), s.length && this.entityActions.next({ + type: Eo.Update, + ids: s + }), n.length && this.entityActions.next({ + type: Eo.Add, + ids: n + }), n.length && this.hasUIStore() && this.handleUICreation(!0) + }, yl.prototype.replace = function(e, t) { + var i, r, n = Ro(e); + if (!Uo(n)) { + var s = {}; + try { + for (var a = ft(n), o = a.next(); !o.done; o = a.next()) { + var l = o.value; + t[this.idKey] = l, s[l] = t + } + } catch (e) { + i = { + error: e + } + } finally { + try { + o && !o.done && (r = a.return) && r.call(a) + } finally { + if (i) throw i.error + } + } + _o && Mo("Replace Entity", e), this._setState(function(e) { + return ct({}, e, { + entities: ct({}, e.entities, s) + }) + }) + } + }, yl.prototype.move = function(e, t) { + var i = this.ids.slice(); + i.splice(t < 0 ? i.length + t : t, 0, i.splice(e, 1)[0]), _o && Mo("Move Entity"), this._setState(function(e) { + return ct({}, e, { + entities: ct({}, e.entities), + ids: i + }) + }) + }, yl.prototype.remove = function(t) { + var e, i, r = this; + Uo(this.ids) || (e = Bo(t), i = [], Uo(i = $o(t) ? this.ids.filter(function(e) { + return t(r.entities[e]) + }) : e ? Ro(t) : this.ids) || (_o && Mo("Remove Entity", i), this._setState(function(e) { + return function(e) { + var t, i = e.state, + r = e.ids; + if (Po(r)) return ct({}, i, { + entities: {}, + ids: [], + active: qo(i.active) ? [] : null + }); + var n = i.entities, + s = {}; + try { + for (var a = ft(i.ids), o = a.next(); !o.done; o = a.next()) { + var l = o.value; + !1 === r.includes(l) && (s[l] = n[l]) + } + } catch (e) { + d = { + error: e + } + } finally { + try { + o && !o.done && (t = a.return) && t.call(a) + } finally { + if (d) throw d.error + } + } + var d = ct({}, i, { + entities: s, + ids: i.ids.filter(function(e) { + return !1 === r.includes(e) + }) + }); + return Ko(i) && (d.active = Ho(d)), d + }({ + state: e, + ids: i + }) + }), e || this.setHasCache(!1), this.handleUIRemove(i), this.entityActions.next({ + type: Eo.Remove, + ids: i + }))) + }, yl.prototype.updateActive = function(e) { + var t = Ro(this.active); + _o && Mo("Update Active", t), this.update(t, e) + }, yl.prototype.setActive = function(e) { + e = function(e, t, i) { + var r; + if (Fo(e)) r = e; + else if (No(e)) { + if (Po(i)) return; + e = Object.assign({ + wrap: !0 + }, e); + var n = t.indexOf(i); + if (e.prev) { + var s = 0 === n; + if (s && !e.wrap) return; + r = s ? t[t.length - 1] : t[n - 1] + } else if (e.next) { + s = t.length === n + 1; + if (s && !e.wrap) return; + r = s ? t[0] : t[n + 1] + } + } else { + if (e === i) return; + r = e + } + return r + }(e, this.ids, this.active); + void 0 !== e && (_o && Mo("Set Active", e), this._setActive(e)) + }, yl.prototype.addActive = function(e) { + var t = this, + i = Ro(e); + Uo(i) || i.every(function(e) { + return -1 < t.active.indexOf(e) + }) || (_o && Mo("Add Active", e), this._setState(function(e) { + var t = Array.from(new Set(gt(e.active, i))); + return ct({}, e, { + active: t + }) + })) + }, yl.prototype.removeActive = function(e) { + var t = this, + i = Ro(e); + Uo(i) || i.some(function(e) { + return -1 < t.active.indexOf(e) + }) && (_o && Mo("Remove Active", e), this._setState(function(e) { + return ct({}, e, { + active: Array.isArray(e.active) ? e.active.filter(function(e) { + return -1 === i.indexOf(e) + }) : null + }) + })) + }, yl.prototype.toggleActive = function(e) { + var i = this, + t = Ro(e), + r = function(t) { + return function(e) { + return i.active.includes(e) === t + } + }, + e = t.filter(r(!0)), + r = t.filter(r(!1)); + this.removeActive(e), this.addActive(r), _o && Do("Toggle Active") + }, yl.prototype.createUIStore = function(e, t) { + var i = { + name: "UI/" + this.storeName, + idKey: this.idKey + }; + return this.ui = new ml(e = void 0 === e ? {} : e, ct({}, i, t = void 0 === t ? {} : t)), this.ui + }, yl.prototype.destroy = function() { + pl.prototype.destroy.call(this), this.ui instanceof yl && this.ui.destroy(), this.entityActions.complete() + }, yl.prototype.akitaPreUpdateEntity = function(e, t) { + return t + }, yl.prototype.akitaPreAddEntity = function(e) { + return e + }, yl.prototype.akitaPreCheckEntity = function(e) { + return e + }, Object.defineProperty(yl.prototype, "ids", { + get: function() { + return this._value().ids + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(yl.prototype, "entities", { + get: function() { + return this._value().entities + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(yl.prototype, "active", { + get: function() { + return this._value().active + }, + enumerable: !0, + configurable: !0 + }), yl.prototype._setActive = function(t) { + this._setState(function(e) { + return ct({}, e, { + active: t + }) + }) + }, yl.prototype.handleUICreation = function(e) { + var r = this, + t = this.ids, + n = $o(this.ui._akitaCreateEntityFn), + i = function(e) { + var t = r.entities[e], + i = n ? r.ui._akitaCreateEntityFn(t) : r.ui._akitaCreateEntityFn; + return ct(((e = {})[r.idKey] = t[r.idKey], e), i) + }, + i = ((e = void 0 === e ? !1 : e) ? this.ids.filter(function(e) { + return Vo(r.ui.entities[e]) + }) : t).map(i); + e ? this.ui.add(i) : this.ui.set(i) + }, yl.prototype.hasInitialUIState = function() { + return this.hasUIStore() && !1 === Vo(this.ui._akitaCreateEntityFn) + }, yl.prototype.handleUIRemove = function(e) { + this.hasUIStore() && this.ui.remove(e) + }, yl.prototype.hasUIStore = function() { + return this.ui instanceof ml + }, ht([ol(), pt("design:type", Function), pt("design:paramtypes", [Object, Object, Object, Object]), pt("design:returntype", void 0)], yl.prototype, "upsert", null), ht([ol(), pt("design:type", Function), pt("design:paramtypes", ["function" == typeof(w = "undefined" != typeof T && T) ? w : Object]), pt("design:returntype", void 0)], yl.prototype, "toggleActive", null), yl), + ml = (ut(gl, hl = fl), gl.prototype.setInitialEntityState = function(e) { + this._akitaCreateEntityFn = e + }, gl); + + function gl(e, t) { + return hl.call(this, e = void 0 === e ? {} : e, t = void 0 === t ? {} : t) || this + } + + function yl(e, t) { + void 0 === t && (t = {}); + e = pl.call(this, ct({}, { + entities: {}, + ids: [], + loading: !0, + error: null + }, e = void 0 === e ? {} : e), t) || this; + return e.options = t, e.entityActions = new Xt, e.entityIdChanges = new Xt, e + } + + function vl() { + return Is(function(e, t) { + return e === t || !1 !== Fo(e) && !1 !== Fo(t) && (!(!Uo(e) || !Uo(t)) || !Sl(t, e) && !1 === Sl(e, t)) + }) + } + + function Sl(e, t) { + return t.some(function(t) { + return void 0 === e.find(function(e) { + return e === t + }) + }) + } + + function bl(i, e) { + for (var r, n, s, a = [], o = i.ids, l = i.entities, d = e.filterBy, t = e.limitTo, u = e.sortBy, e = e.sortByOrder, c = 0; c < o.length; c++) ! function(t) { + var i = l[o[t]]; + if (!d) return a.push(i); + Ro(d).every(function(e) { + return e(i, t) + }) && a.push(i) + }(c); + u && (s = $o(u) ? u : (r = u, void 0 === (n = e) && (n = cl.ASC), function(e, t) { + if (!e.hasOwnProperty(r) || !t.hasOwnProperty(r)) return 0; + var i = "string" == typeof e[r] ? e[r].toUpperCase() : e[r], + e = "string" == typeof t[r] ? t[r].toUpperCase() : t[r], + t = 0; + return e < i ? t = 1 : i < e && (t = -1), n == cl.DESC ? -1 * t : t + }), a = a.sort(function(e, t) { + return s(e, t, i) + })); + t = Math.min(t || a.length, a.length); + return t === a.length ? a : a.slice(0, t) + } + + function Tl(e) { + return "string" == typeof e + } + + function El(t, i) { + return function(e) { + e = e[t]; + if (!Vo(e)) return i ? Tl(i) ? e[i] : i(e) : e + } + }(vi = cl = cl || {}).ASC = "asc", vi.DESC = "desc"; + Il.prototype.select = function(t) { + var e, n; + if ($o(t)) e = t; + else if (Tl(t)) e = function(e) { + return e[t] + }; + else { + if (Array.isArray(t)) return this.store._select(function(e) { + return e + }).pipe(Is((n = t, function(t, i) { + var r = $o(n[0]); + return !1 === n.some(function(e) { + return r ? e(t) !== e(i) : t[e] !== i[e] + }) + })), hr(function(i) { + return $o(t[0]) ? t.map(function(e) { + return e(i) + }) : t.reduce(function(e, t) { + return e[t] = i[t], e + }, {}) + })); + e = function(e) { + return e + } + } + return this.store._select(e) + }, Il.prototype.selectLoading = function() { + return this.select(function(e) { + return e.loading + }) + }, Il.prototype.selectError = function() { + return this.select(function(e) { + return e.error + }) + }, Il.prototype.getValue = function() { + return this.store._value() + }, Il.prototype.selectHasCache = function() { + return this.store._cache().asObservable() + }, Il.prototype.getHasCache = function() { + return this.store._cache().value + }, Object.defineProperty(Il.prototype, "config", { + get: function() { + return this.constructor.akitaQueryConfig + }, + enumerable: !0, + configurable: !0 + }), bi = Il; + + function Il(e) { + this.store = e, this.__store__ = e, _o && (tl[e.storeName] = this) + } + + function wl(e) { + return e.pipe(ln(function(e) { + return null != e + })) + } + var Al, Ol, kl = (ut(Ml, Ol = bi), Ml.prototype.selectAll = function(e) { + var t = this; + return void 0 === e && (e = { + asObject: !1 + }), this.select(function(e) { + return e.entities + }).pipe(hr(function() { + return t.getAll(e) + })) + }, Ml.prototype.getAll = function(e) { + return (e = void 0 === e ? { + asObject: !1, + filterBy: void 0, + limitTo: void 0 + } : e).asObject ? function(e, t) { + var r = {}, + n = t.filterBy, + s = t.limitTo, + a = e.ids, + o = e.entities; + if (!n && !s) return o; + e = !1 === Po(s); + if (n && e) + for (var l = 0, i = 0, d = a.length; i < d && "break" !== function(t) { + if (l === s) return "break"; + var e = a[t], + i = o[e]; + Ro(n).every(function(e) { + return e(i, t) + }) && (r[e] = i, l++) + }(i); i++); + else + for (var u = Math.min(s || a.length, a.length), i = 0; i < u; i++) ! function(t) { + var e = a[t], + i = o[e]; + if (!n) return r[e] = i; + Ro(n).every(function(e) { + return e(i, t) + }) && (r[e] = i) + }(i); + return r + }(this.getValue(), e) : (t = e, i = this.config || this.options, t.sortBy = t.sortBy || i && i.sortBy, t.sortByOrder = t.sortByOrder || i && i.sortByOrder, bl(this.getValue(), e)); + var t, i + }, Ml.prototype.selectMany = function(e, i) { + return e && e.length ? this.select(function(e) { + return e.entities + }).pipe(hr(function(t) { + return n = function(e) { + return El(e, i)(t) + }, e.reduce(function(e, t, i, r) { + t = n(t); + return void 0 !== t && e.push(t), e + }, []); + var n + }), vl()) : $i([]) + }, Ml.prototype.selectEntity = function(e, t) { + var i = e; + return $o(e) && (i = function(e, t) { + var i, r; + try { + for (var n = ft(Object.keys(t)), s = n.next(); !s.done; s = n.next()) { + var a = s.value; + if (!0 === e(t[a])) return a + } + } catch (e) { + i = { + error: e + } + } finally { + try { + s && !s.done && (r = n.return) && r.call(n) + } finally { + if (i) throw i.error + } + } + }(e, this.getValue().entities)), this.select(function(e) { + return e.entities + }).pipe(hr(El(i, t)), Is()) + }, Ml.prototype.getEntity = function(e) { + return this.getValue().entities[e] + }, Ml.prototype.selectActiveId = function() { + return this.select(function(e) { + return e.active + }) + }, Ml.prototype.getActiveId = function() { + return this.getValue().active + }, Ml.prototype.selectActive = function(t) { + var i = this; + return Fo(this.getActive()) ? this.selectActiveId().pipe(La(function(e) { + return i.selectMany(e, t) + })) : this.selectActiveId().pipe(La(function(e) { + return i.selectEntity(e, t) + })) + }, Ml.prototype.getActive = function() { + var t = this, + e = this.getActiveId(); + return Fo(e) ? e.map(function(e) { + return t.getValue().entities[e] + }) : Jo(e) ? this.getEntity(e) : void 0 + }, Ml.prototype.selectCount = function(e) { + var t = this; + return this.select(function(e) { + return e.entities + }).pipe(hr(function() { + return t.getCount(e) + })) + }, Ml.prototype.getCount = function(e) { + return ($o(e) ? this.getAll().filter(e) : this.getValue().ids).length + }, Ml.prototype.selectLast = function(e) { + return this.selectAt(function(e) { + return e[e.length - 1] + }, e) + }, Ml.prototype.selectFirst = function(e) { + return this.selectAt(function(e) { + return e[0] + }, e) + }, Ml.prototype.selectEntityAction = function(e) { + if (Po(e)) return this.store.selectEntityAction$; + var t = Fo(e) ? function(e) { + return e + } : function(e) { + return e.ids + }, + i = Ro(e); + return this.store.selectEntityAction$.pipe(ln(function(e) { + e = e.type; + return i.includes(e) + }), hr(function(e) { + return t(e) + })) + }, Ml.prototype.hasEntity = function(e) { + var t = this; + return Po(e) ? 0 < this.getValue().ids.length : $o(e) ? this.getAll().some(e) : Fo(e) ? e.every(function(e) { + return e in t.getValue().entities + }) : e in this.getValue().entities + }, Ml.prototype.hasActive = function(e) { + var t = this.getValue().active, + i = Bo(e); + return Array.isArray(t) ? i ? t.includes(e) : 0 < t.length : i ? t === e : Bo(t) + }, Ml.prototype.createUIQuery = function() { + this.ui = new Cl(this.__store__.ui) + }, Ml.prototype.selectAt = function(e, t) { + var i = this; + return this.select(function(e) { + return e.ids + }).pipe(hr(e), Is(), La(function(e) { + return i.selectEntity(e, t) + })) + }, Ml), + Cl = (ut(Dl, Al = kl), Dl); + + function Dl(e) { + return Al.call(this, e) || this + } + + function Ml(e, t) { + void 0 === t && (t = {}); + var i = Ol.call(this, e) || this; + return i.options = t, i.__store__ = e, i + } + + function xl(e, t) { + return 1 === t.split(".").length ? e : t.split(".").slice(1).join(".").split(".").reduce(function(e, t) { + return e && e[t] + }, e) + } + + function Pl(e, t, r) { + var i = t.split("."); + if (1 === i.length) return ct({}, e, r); + e = ct({}, e); + var n = i.length - 2; + return t.split(".").slice(1).reduce(function(e, t, i) { + return e[t] = i !== n ? ct({}, e[t]) : Array.isArray(e[t]) || !No(e[t]) ? r : ct({}, e[t], r), e && e[t] + }, e), e + } + new Ji(1); + var Rl, Ll, _l, Nl, A = (Bl.prototype.getQuery = function() { + return this.query + }, Bl.prototype.getStore = function() { + return this.getQuery().__store__ + }, Bl.prototype.isEntityBased = Jo, Bl.prototype.selectSource = function(e, t) { + var i = this; + return this.isEntityBased(e) ? this.getQuery().selectEntity(e).pipe(wl) : t ? this.getQuery().select(function(e) { + return xl(e, i.withStoreName(t)) + }) : this.getQuery().select() + }, Bl.prototype.getSource = function(e, t) { + if (this.isEntityBased(e)) return this.getQuery().getEntity(e); + e = this.getQuery().getValue(); + return t ? xl(e, this.withStoreName(t)) : e + }, Bl.prototype.withStoreName = function(e) { + return this.storeName + "." + e + }, Object.defineProperty(Bl.prototype, "storeName", { + get: function() { + return this.getStore().storeName + }, + enumerable: !0, + configurable: !0 + }), Bl.prototype.updateStore = function(t, e, i) { + var r = this; + this.isEntityBased(e) ? this.getStore().update(e, t) : i ? this.getStore()._setState(function(e) { + return Pl(e, r.withStoreName(i), t) + }) : this.getStore()._setState(function(e) { + return ct({}, e, t) + }) + }, Bl.prototype.onReset = function(i) { + var r = this, + n = this.getStore().reset; + this.getStore().reset = function() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + setTimeout(function() { + n.apply(r.getStore(), e), i() + }) + } + }, Bl), + Fl = { + pagesControls: !1, + range: !1, + startWith: 1, + cacheTimeout: void 0, + clearStoreWithCache: !0 + }; + + function Bl(e, t) { + this.query = e + } + + function Ul(e, t, i) { + void 0 === i && (i = {}); + var r = Rl.call(this, e) || this; + return r.query = e, r.factoryFnOrPath = t, r.params = i, r.params = ct({ + debounceTime: 300, + formKey: "akitaForm", + emitEvent: !1, + arrControlFactory: function(e) { + return r.builder.control(e) + } + }, i), r.isRootKeys = !1 === Jo(t), r.isKeyBased = Tl(t) || r.isRootKeys, r + } + + function $l(e, t) { + void 0 === t && (t = {}); + var i = Ll.call(this, e, { + resetFn: function() { + i.initial = !1, i.destroy({ + clearCache: !0, + currentPage: 1 + }) + } + }) || this; + i.query = e, i.config = t, i.metadata = new Map, i.pages = new Map, i.pagination = { + currentPage: 1, + perPage: 0, + total: 0, + lastPage: 0, + data: [] + }, i.initial = !0, i.isLoading$ = i.query.selectLoading().pipe(function(t) { + void 0 === t && (t = ir); + var i = as(0) ? 0 - t.now() : Math.abs(0); + return function(e) { + return e.lift(new ls(i, t)) + } + }()), i.config = Object.assign(Fl, t); + e = i.config, t = e.startWith, e = e.cacheTimeout; + return i.page = new yi(t), e && (e instanceof $t || "function" == typeof e.lift && "function" == typeof e.subscribe) && (i.clearCacheSubscription = e.subscribe(function() { + return i.clearCache() + })), i + } + ut($l, Ll = A), Object.defineProperty($l.prototype, "pageChanges", { + get: function() { + return this.page.asObservable() + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty($l.prototype, "currentPage", { + get: function() { + return this.pagination.currentPage + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty($l.prototype, "isFirst", { + get: function() { + return 1 === this.currentPage + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty($l.prototype, "isLast", { + get: function() { + return this.currentPage === this.pagination.lastPage + }, + enumerable: !0, + configurable: !0 + }), $l.prototype.withControls = function() { + return this.config.pagesControls = !0, this + }, $l.prototype.withRange = function() { + return this.config.range = !0, this + }, $l.prototype.setLoading = function(e) { + void 0 === e && (e = !0), this.getStore().setLoading(e) + }, $l.prototype.update = function(e) { + this.pagination = e, this.addPage(e.data) + }, $l.prototype.addPage = function(e) { + var t = this; + this.pages.set(this.currentPage, { + ids: e.map(function(e) { + return e[t.getStore().idKey] + }) + }), this.getStore().upsertMany(e) + }, $l.prototype.clearCache = function(e) { + void 0 === e && (e = {}), this.initial || (Do("@Pagination - Clear Cache"), !1 !== e.clearStore && (this.config.clearStoreWithCache || e.clearStore) && this.getStore().remove(), this.pages = new Map, this.metadata = new Map), this.initial = !1 + }, $l.prototype.clearPage = function(e) { + this.pages.delete(e) + }, $l.prototype.destroy = function(e) { + var t = void 0 === e ? {} : e, + e = t.clearCache, + t = t.currentPage; + this.clearCacheSubscription && this.clearCacheSubscription.unsubscribe(), e && this.clearCache(), Vo(t) || this.setPage(t), this.initial = !0 + }, $l.prototype.isPageActive = function(e) { + return this.currentPage === e + }, $l.prototype.setPage = function(e) { + e === this.currentPage && this.hasPage(e) || this.page.next(this.pagination.currentPage = e) + }, $l.prototype.nextPage = function() { + this.currentPage !== this.pagination.lastPage && this.setPage(this.pagination.currentPage + 1) + }, $l.prototype.prevPage = function() { + 1 < this.pagination.currentPage && this.setPage(this.pagination.currentPage - 1) + }, $l.prototype.setLastPage = function() { + this.setPage(this.pagination.lastPage) + }, $l.prototype.setFirstPage = function() { + this.setPage(1) + }, $l.prototype.hasPage = function(e) { + return this.pages.has(e) + }, $l.prototype.getPage = function(e) { + var t = this, + i = this.pagination.currentPage; + return this.hasPage(i) ? this.selectPage(i) : (this.setLoading(!0), Fr(e()).pipe(La(function(e) { + return i = e.currentPage, al(function() { + t.setLoading(!1), t.update(e) + }), t.selectPage(i) + }))) + }, $l.prototype.getQuery = function() { + return this.query + }, $l.prototype.refreshCurrentPage = function() { + !1 === Po(this.currentPage) && (this.clearPage(this.currentPage), this.setPage(this.currentPage)) + }, $l.prototype.getFrom = function() { + return this.isFirst ? 1 : (this.currentPage - 1) * this.pagination.perPage + 1 + }, $l.prototype.getTo = function() { + return this.isLast ? this.pagination.total : this.currentPage * this.pagination.perPage + }, $l.prototype.selectPage = function(n) { + var s = this; + return this.query.selectAll({ + asObject: !0 + }).pipe(Ds(1), hr(function(t) { + var e = ct({}, s.pagination, { + data: s.pages.get(n).ids.map(function(e) { + return t[e] + }) + }), + i = s.config, + r = i.range, + i = i.pagesControls; + return isNaN(s.pagination.total) && (1 === e.lastPage ? e.total = e.data ? e.data.length : 0 : e.total = e.perPage * e.lastPage, s.pagination.total = e.total), r && (e.from = s.getFrom(), e.to = s.getTo()), i && (e.pageControls = function(e, t) { + for (var i = Math.ceil(e / t), r = [], n = 0; n < i; n++) r.push(n + 1); + return r + }(s.pagination.total, s.pagination.perPage)), e + })) + }, ht([(_l = "@Pagination - New Page", function(e, t, i) { + var r = i.value; + return i.value = function() { + for (var e = [], t = 0; t < arguments.length; t++) e[t] = arguments[t]; + return Do(_l, Nl), r.apply(this, e) + }, i + }), pt("design:type", Function), pt("design:paramtypes", [Object]), pt("design:returntype", void 0)], $l.prototype, "update", null), ut(Ul, Rl = A), Ul.prototype.setForm = function(e, t) { + return this.form = e, this.builder = t, this.activate(), this + }, Ul.prototype.reset = function(e) { + var r = this, + e = e || (this.isKeyBased ? this.initialValue : this.factoryFnOrPath()); + this.isKeyBased && Object.keys(this.initialValue).forEach(function(i) { + var e, t = r.initialValue[i]; + Array.isArray(t) && r.builder && (e = r.form.controls[i], r.cleanArray(e), t.forEach(function(e, t) { + r.form.get(i).insert(t, r.params.arrControlFactory(e)) + })) + }), this.form.patchValue(e, { + emitEvent: this.params.emitEvent + }); + var t = this.isKeyBased ? Pl(this.getQuery().getValue(), this.getStore().storeName + "." + this.factoryFnOrPath, e) : ((t = {})[this.params.formKey] = e, t); + this.updateStore(t) + }, Ul.prototype.cleanArray = function(e) { + for (; 0 !== e.length;) e.removeAt(0) + }, Ul.prototype.resolveInitialValue = function(e, n) { + var s = this; + if (e) return Object.keys(e).reduce(function(e, i) { + var r, t = n[i]; + return Array.isArray(t) && s.builder && (r = s.params.arrControlFactory, s.cleanArray(s.form.get(i)), t.forEach(function(e, t) { + s.form.get(i).insert(t, r(e)) + })), e[i] = n[i], e + }, {}) + }, Ul.prototype.activate = function() { + var i, e, t, r = this; + this.isKeyBased ? (this.isRootKeys ? this.initialValue = this.resolveInitialValue(this.form.value, this.getQuery().getValue()) : (i = this.getStore().storeName + "." + this.factoryFnOrPath, e = xl(this.getQuery().getValue(), i), this.initialValue = this.resolveInitialValue(e, e)), this.form.patchValue(this.initialValue, { + emitEvent: this.params.emitEvent + })) : (this.getQuery().getValue()[this.params.formKey] || (Do("@PersistNgFormPlugin activate"), this.updateStore(((t = {})[this.params.formKey] = this.factoryFnOrPath(), t))), t = this.getQuery().getValue()[this.params.formKey], this.form.patchValue(t)), this.formChanges = this.form.valueChanges.pipe(Gn(this.params.debounceTime)).subscribe(function(t) { + var e; + Do("@PersistForm - Update"), e = r.isKeyBased ? r.isRootKeys ? function(e) { + return ct({}, e, t) + } : function(e) { + return Pl(e, i, t) + } : function() { + var e; + return (e = {})[r.params.formKey] = t, e + }, r.updateStore(e(r.getQuery().getValue())) + }) + }, Ul.prototype.destroy = function() { + this.formChanges && this.formChanges.unsubscribe(), this.form = null, this.builder = null + }; + var Vl, Kl, Vr = (jl.prototype.getEntity = function(e) { + return this.entities.get(e) + }, jl.prototype.hasEntity = function(e) { + return this.entities.has(e) + }, jl.prototype.removeEntity = function(e) { + return this.destroy(e), this.entities.delete(e) + }, jl.prototype.createEntity = function(e, t) { + return this.entities.set(e, t) + }, jl.prototype.getIds = function() { + return Vo(this.entityIds) ? this.query.getValue().ids : Ro(this.entityIds) + }, jl.prototype.resolvedIds = function(e) { + return Vo(e) ? this.getIds() : Ro(e) + }, jl.prototype.rebase = function(i, r) { + var n = this; + if (void 0 === r && (r = {}), Jo(i)) + if (Vo(this.entityIds)) { + for (var e = 0, t = i.length; e < t; e++) { + var s, a = i[e]; + !1 === this.hasEntity(a) && ($o(r.beforeAdd) && r.beforeAdd(a), s = this.instantiatePlugin(a), this.entities.set(a, s), $o(r.afterAdd) && r.afterAdd(s)) + } + this.entities.forEach(function(e, t) { + -1 === i.indexOf(t) && ($o(r.beforeRemove) && r.beforeRemove(e), n.removeEntity(t)) + }) + } else + for (var o = Ro(this.entityIds), e = 0, t = o.length; e < t; e++) a = o[e], -1 < i.indexOf(a) && !1 === this.hasEntity(a) ? ($o(r.beforeAdd) && r.beforeAdd(a), s = this.instantiatePlugin(a), this.entities.set(a, s), $o(r.afterAdd) && r.afterAdd(s)) : this.entities.forEach(function(e, t) { + -1 === i.indexOf(t) && !0 === n.hasEntity(t) && ($o(r.beforeRemove) && r.beforeRemove(e), n.removeEntity(t)) + }); + else this.getIds().forEach(function(e) { + n.hasEntity(e) || n.createEntity(e, n.instantiatePlugin(e)) + }) + }, jl.prototype.selectIds = function() { + return this.query.select(function(e) { + return e.ids + }) + }, jl.prototype.activate = function(e) { + this.rebase(e) + }, jl.prototype.forEachId = function(e, t) { + for (var i = this.resolvedIds(e), r = 0, n = i.length; r < n; r++) { + var s = i[r]; + this.hasEntity(s) && t(this.getEntity(s)) + } + }, jl), + ql = (ut(Hl, Vl = A), Object.defineProperty(Hl.prototype, "hasPast$", { + get: function() { + return this._hasPast$ + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(Hl.prototype, "hasFuture$", { + get: function() { + return this._hasFuture$ + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(Hl.prototype, "hasPast", { + get: function() { + return 0 < this.history.past.length + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(Hl.prototype, "hasFuture", { + get: function() { + return 0 < this.history.future.length + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(Hl.prototype, "property", { + get: function() { + return this.params.watchProperty + }, + enumerable: !0, + configurable: !0 + }), Hl.prototype.updateHasHistory = function() { + this.hasFutureSubject.next(this.hasFuture), this.hasPastSubject.next(this.hasPast) + }, Hl.prototype.activate = function() { + var r = this; + this.hasPastSubject = new yi(!1), this._hasPast$ = this.hasPastSubject.asObservable().pipe(Is()), this.hasFutureSubject = new yi(!1), this._hasFuture$ = this.hasFutureSubject.asObservable().pipe(Is()), this.history.present = this.getSource(this._entityId, this.property), this.subscription = this.selectSource(this._entityId, this.property).pipe(ha()).subscribe(function(e) { + var t = mt(e, 2), + i = t[0], + e = t[1]; + r.skip ? r.skip = !1 : (t = r.params.comparator(i, e), !r.skipUpdate && t && (r.history.past.length === r.params.maxAge && (r.history.past = r.history.past.slice(1)), r.history.past = gt(r.history.past, [i]), r.history.present = e, r.updateHasHistory())) + }) + }, Hl.prototype.undo = function() { + var e, t, i; + 0 < this.history.past.length && (e = (i = this.history).past, t = i.present, i = e[e.length - 1], this.history.past = e.slice(0, e.length - 1), this.history.present = i, this.history.future = gt([t], this.history.future), this.update()) + }, Hl.prototype.redo = function() { + var e, t, i, r; + 0 < this.history.future.length && (e = (r = this.history).past, t = r.present, i = this.history.future[0], r = this.history.future.slice(1), this.history.past = gt(e, [t]), this.history.present = i, this.history.future = r, this.update("Redo")) + }, Hl.prototype.jumpToPast = function(e) { + var t, i, r, n; + e < 0 || e >= this.history.past.length || (t = (r = this.history).past, n = r.future, i = r.present, r = t.slice(0, e), n = gt(t.slice(e + 1), [i], n), e = t[e], this.history.past = r, this.history.present = e, this.history.future = n, this.update()) + }, Hl.prototype.jumpToFuture = function(e) { + var t, i, r; + e < 0 || e >= this.history.future.length || (i = (r = this.history).past, t = r.future, i = gt(i, [r.present], t.slice(0, e)), r = t[e], e = t.slice(e + 1), this.history.past = i, this.history.present = r, this.history.future = e, this.update("Redo")) + }, Hl.prototype.jump = function(e) { + return 0 < e ? this.jumpToFuture(e - 1) : e < 0 ? this.jumpToPast(this.history.past.length + e) : void 0 + }, Hl.prototype.clear = function(e) { + this.history = $o(e) ? e(this.history) : { + past: [], + present: null, + future: [] + }, this.updateHasHistory() + }, Hl.prototype.destroy = function(e) { + (e = void 0 === e ? !1 : e) && this.clear(), this.subscription.unsubscribe() + }, Hl.prototype.ignoreNext = function() { + this.skip = !0 + }, Hl.prototype.update = function(e) { + void 0 === e && (e = "Undo"), this.skipUpdate = !0, Do("@StateHistory - " + e), this.updateStore(this.history.present, this._entityId, this.property), this.updateHasHistory(), this.skipUpdate = !1 + }, Hl); + + function Hl(e, t, i) { + void 0 === t && (t = {}); + var r = Vl.call(this, e, { + resetFn: function() { + return r.clear() + } + }) || this; + return r.query = e, r.params = t, r._entityId = i, r.skip = !1, r.history = { + past: [], + present: null, + future: [] + }, r.skipUpdate = !1, t.maxAge = t.maxAge || 10, t.comparator = t.comparator || function() { + return !0 + }, r.activate(), r + } + + function jl(e, t) { + this.query = e, this.entityIds = t, this.entities = new Map + } + + function Ql(e, t) { + var i = Kl.call(this, e, (t = void 0 === t ? {} : t).entityIds) || this; + return i.query = e, (i.params = t).maxAge = Jo(t.maxAge) ? t.maxAge : 10, i.activate(), i.selectIds().pipe(ka(1)).subscribe(function(e) { + return i.activate(e) + }), i + } + ut(Ql, Kl = Vr), Ql.prototype.redo = function(e) { + this.forEachId(e, function(e) { + return e.redo() + }) + }, Ql.prototype.undo = function(e) { + this.forEachId(e, function(e) { + return e.undo() + }) + }, Ql.prototype.hasPast = function(e) { + if (this.hasEntity(e)) return this.getEntity(e).hasPast + }, Ql.prototype.hasFuture = function(e) { + if (this.hasEntity(e)) return this.getEntity(e).hasFuture + }, Ql.prototype.jumpToFuture = function(e, t) { + this.forEachId(e, function(e) { + return e.jumpToFuture(t) + }) + }, Ql.prototype.jumpToPast = function(e, t) { + this.forEachId(e, function(e) { + return e.jumpToPast(t) + }) + }, Ql.prototype.clear = function(e) { + this.forEachId(e, function(e) { + return e.clear() + }) + }, Ql.prototype.destroy = function(e, t) { + void 0 === t && (t = !1), this.forEachId(e, function(e) { + return e.destroy(t) + }) + }, Ql.prototype.ignoreNext = function(e) { + this.forEachId(e, function(e) { + return e.ignoreNext() + }) + }, Ql.prototype.instantiatePlugin = function(e) { + return new ql(this.query, this.params, e) + }; + var Wl = { + comparator: function(e, t) { + return JSON.stringify(e) !== JSON.stringify(t) + } + }; + + function Gl(e, t) { + return t.split(".").reduce(function(e, t) { + return e && "undefined" !== e[t] ? e[t] : void 0 + }, e) + } + var zl, Xl, Yl = (ut(Jl, zl = A), Jl.prototype.reset = function(e) { + var t = this.head; + $o((e = void 0 === e ? {} : e).updateFn) && (t = this.isEntityBased(this._entityId) ? e.updateFn(this.head, this.getQuery().getEntity(this._entityId)) : e.updateFn(this.head, this.getQuery().getValue())), Do("@DirtyCheck - Revert"), this.updateStore(t, this._entityId), this._reset.next() + }, Jl.prototype.setHead = function() { + return this.active ? this.head = this._getHead() : (this.activate(), this.active = !0), this.updateDirtiness(!1), this + }, Jl.prototype.isDirty = function() { + return !!this.dirty.value + }, Jl.prototype.hasHead = function() { + return !!this.getHead() + }, Jl.prototype.destroy = function() { + this.head = null, this.subscription && this.subscription.unsubscribe(), this._reset && this._reset.complete() + }, Jl.prototype.isPathDirty = function(e) { + var t = this.getHead(), + i = Gl(this.getQuery().getValue(), e), + e = Gl(t, e); + return this.params.comparator(i, e) + }, Jl.prototype.getHead = function() { + return this.head + }, Jl.prototype.activate = function() { + var i = this; + this.head = this._getHead(); + var e = this.params.watchProperty ? this.params.watchProperty.map(function(t) { + return i.query.select(function(e) { + return e[t] + }).pipe(hr(function(e) { + return { + val: e, + __akitaKey: t + } + })) + }) : [this.selectSource(this._entityId)]; + this.subscription = Mr.apply(void 0, gt(e)).pipe(ka(1)).subscribe(function(e) { + Vo(i.head) || (e = e.some(function(e) { + var t = e.__akitaKey ? i.head[e.__akitaKey] : i.head, + e = e.__akitaKey ? e.val : e; + return i.params.comparator(t, e) + }), i.updateDirtiness(e)) + }) + }, Jl.prototype.updateDirtiness = function(e) { + this.dirty.next(e) + }, Jl.prototype._getHead = function() { + var e = this.getSource(this._entityId); + return e = this.params.watchProperty ? this.getWatchedValues(e) : e + }, Jl.prototype.getWatchedValues = function(i) { + return this.params.watchProperty.reduce(function(e, t) { + return e[t] = i[t], e + }, {}) + }, Jl); + + function Jl(e, t, i) { + var r = zl.call(this, e) || this; + return r.query = e, r.params = t, r._entityId = i, r.dirty = new yi(!1), r.active = !1, r._reset = new Xt, r.isDirty$ = r.dirty.asObservable().pipe(Is()), r.reset$ = r._reset.asObservable(), r.params = ct({}, Wl, t), r.params.watchProperty && (t = Ro(r.params.watchProperty), e instanceof kl && t.includes("entities") && !t.includes("ids") && t.push("ids"), r.params.watchProperty = t), r + } + + function Zl() { + return Math.random().toString(36).slice(2) + } + + function ed(e) { + return Mr(e).pipe($n(0)) + } + + function td(e, t) { + var i = Xl.call(this, e, (t = void 0 === t ? {} : t).entityIds) || this; + return i.query = e, i.params = t, i._someDirty = new Xt, i.someDirty$ = an(i.query.select(function(e) { + return e.entities + }), i._someDirty.asObservable()).pipe($n(0), hr(function() { + return i.checkSomeDirty() + })), i.params = ct({}, Wl, t), i.activate(), i.selectIds().pipe(ka(1)).subscribe(function(e) { + Xl.prototype.rebase.call(i, e, { + afterAdd: function(e) { + return e.setHead() + } + }) + }), i + } + ut(td, Xl = Vr), td.prototype.setHead = function(e) { + if (this.params.entityIds && e) { + var t = Ro(e); + if (!1 === Ro(this.params.entityIds).some(function(e) { + return -1 < t.indexOf(e) + })) return this + } + return this.forEachId(e, function(e) { + return e.setHead() + }), this._someDirty.next(), this + }, td.prototype.hasHead = function(e) { + return !!this.entities.has(e) && this.getEntity(e).hasHead() + }, td.prototype.reset = function(e, t) { + void 0 === t && (t = {}), this.forEachId(e, function(e) { + return e.reset(t) + }) + }, td.prototype.isDirty = function(e, t) { + if (void 0 === t && (t = !0), this.entities.has(e)) { + e = this.getEntity(e); + return t ? e.isDirty$ : e.isDirty() + } + return !1 + }, td.prototype.someDirty = function() { + return this.checkSomeDirty() + }, td.prototype.isPathDirty = function(e, t) { + if (this.entities.has(e)) { + var i = this.getEntity(e).getHead(), + e = Gl(this.query.getEntity(e), t), + t = Gl(i, t); + return this.params.comparator(e, t) + } + return null + }, td.prototype.destroy = function(e) { + this.forEachId(e, function(e) { + return e.destroy() + }), e || this._someDirty.complete() + }, td.prototype.instantiatePlugin = function(e) { + return new Yl(this.query, this.params, e) + }, td.prototype.checkSomeDirty = function() { + var e, t, i = this.resolvedIds(); + try { + for (var r = ft(i), n = r.next(); !n.done; n = r.next()) { + var s = n.value; + if (this.getEntity(s).isDirty()) return !0 + } + } catch (t) { + e = { + error: t + } + } finally { + try { + n && !n.done && (t = r.return) && t.call(r) + } finally { + if (e) throw e.error + } + } + return !1 + }, (tu = tu || {}).Update = "UPDATE", {} [tu.Update] = "update", (vr = ru = ru || {}).Update = "UPDATE", vr.AddEntities = "ADD_ENTITIES", vr.SetEntities = "SET_ENTITIES", vr.UpdateEntities = "UPDATE_ENTITIES", vr.RemoveEntities = "REMOVE_ENTITIES", vr.UpsertEntities = "UPSERT_ENTITIES", vr.UpsertManyEntities = "UPSERT_MANY_ENTITIES", (iu = {})[ru.Update] = "update", iu[ru.AddEntities] = "add", iu[ru.SetEntities] = "set", iu[ru.UpdateEntities] = "update", iu[ru.RemoveEntities] = "remove", iu[ru.UpsertEntities] = "upsert", iu[ru.UpsertManyEntities] = "upsertMany"; + w = {}; + Object.defineProperty(w, "__esModule", { + value: !0 + }); + var vi = "undefined" != typeof Symbol && "symbol" == typeof Symbol("x"), + id = "undefined" != typeof Map, + rd = "undefined" != typeof Set, + nd = "undefined" != typeof Proxy && void 0 !== Proxy.revocable && "undefined" != typeof Reflect, + sd = vi ? Symbol.for("immer-nothing") : ((nu = {})["immer-nothing"] = !0, nu), + ad = vi ? Symbol.for("immer-draftable") : "__$immer_draftable", + od = vi ? Symbol.for("immer-state") : "__$immer_state", + ld = "undefined" != typeof Symbol && Symbol.iterator || "@@iterator", + dd = { + 0: "Illegal state", + 1: "Immer drafts cannot have computed properties", + 2: "This object has been frozen and should not be mutated", + 3: function(e) { + return "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + e + }, + 4: "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.", + 5: "Immer forbids circular references", + 6: "The first or second argument to `produce` must be a function", + 7: "The third argument to `produce` must be a function or undefined", + 8: "First argument to `createDraft` must be a plain object, an array, or an immerable object", + 9: "First argument to `finishDraft` must be a draft returned by `createDraft`", + 10: "The given draft is already finalized", + 11: "Object.defineProperty() cannot be used on an Immer draft", + 12: "Object.setPrototypeOf() cannot be used on an Immer draft", + 13: "Immer only supports deleting array indices", + 14: "Immer only supports setting array indices and the 'length' property", + 15: function(e) { + return "Cannot apply patch, path doesn't resolve: " + e + }, + 16: 'Sets cannot have "replace" patches.', + 17: function(e) { + return "Unsupported patch operation: " + e + }, + 18: function(e) { + return "The plugin for '" + e + "' has not been loaded into Immer. To enable the plugin, import and call `enable" + e + "()` when initializing your application." + }, + 20: "Cannot use proxies if Proxy, Proxy.revocable or Reflect are not available", + 21: function(e) { + return "produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '" + e + "'" + }, + 22: function(e) { + return "'current' expects a draft, got: " + e + }, + 23: function(e) { + return "'original' expects a draft, got: " + e + } + }; + + function ud(e) { + for (var t = arguments.length, i = new Array(1 < t ? t - 1 : 0), r = 1; r < t; r++) i[r - 1] = arguments[r]; + var n = dd[e], + e = n ? "function" == typeof n ? n.apply(null, i) : n : "unknown error nr: " + e; + throw new Error("[Immer] " + e) + } + + function cd(e) { + return !!e && !!e[od] + } + + function hd(t) { + return !!t && (function() { + if (!t || "object" != typeof t) return !1; + var e = Object.getPrototypeOf(t); + return !e || e === Object.prototype + }() || Array.isArray(t) || !!t[ad] || !!t.constructor[ad] || Td(t) || Ed(t)) + } + var pd = "undefined" != typeof Reflect && Reflect.ownKeys ? Reflect.ownKeys : void 0 !== Object.getOwnPropertySymbols ? function(e) { + return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e)) + } : Object.getOwnPropertyNames, + fd = Object.getOwnPropertyDescriptors || function(t) { + var i = {}; + return pd(t).forEach(function(e) { + i[e] = Object.getOwnPropertyDescriptor(t, e) + }), i + }; + + function md(i, r, t) { + void 0 === t && (t = !1), 0 === gd(i) ? (t ? Object.keys : pd)(i).forEach(function(e) { + t && "symbol" == typeof e || r(e, i[e], i) + }) : i.forEach(function(e, t) { + return r(t, e, i) + }) + } + + function gd(e) { + var t = e[od]; + return t ? 3 < t.type_ ? t.type_ - 4 : t.type_ : Array.isArray(e) ? 1 : Td(e) ? 2 : Ed(e) ? 3 : 0 + } + + function yd(e, t) { + return 2 === gd(e) ? e.has(t) : Object.prototype.hasOwnProperty.call(e, t) + } + + function vd(e, t) { + return 2 === gd(e) ? e.get(t) : e[t] + } + + function Sd(e, t, i) { + var r = gd(e); + 2 === r ? e.set(t, i) : 3 === r ? (e.delete(t), e.add(i)) : e[t] = i + } + + function bd(e, t) { + return e === t ? 0 !== e || 1 / e == 1 / t : e != e && t != t + } + + function Td(e) { + return id && e instanceof Map + } + + function Ed(e) { + return rd && e instanceof Set + } + + function Id(e) { + return e.copy_ || e.base_ + } + + function wd(e) { + if (Array.isArray(e)) return Array.prototype.slice.call(e); + var t = fd(e); + delete t[od]; + for (var i = pd(t), r = 0; r < i.length; r++) { + var n = i[r], + s = t[n]; + !1 === s.writable && (s.writable = !0, s.configurable = !0), (s.get || s.set) && (t[n] = { + configurable: !0, + writable: !0, + enumerable: s.enumerable, + value: e[n] + }) + } + return Object.create(Object.getPrototypeOf(e), t) + } + + function Ad(e, t) { + kd(e) || cd(e) || !hd(e) || (1 < gd(e) && (e.set = e.add = e.clear = e.delete = Od), Object.freeze(e), t && md(e, function(e, t) { + return Ad(t, !0) + }, !0)) + } + + function Od() { + ud(2) + } + + function kd(e) { + return null == e || "object" != typeof e || Object.isFrozen(e) + } + var Cd, Dd = {}; + + function Md(e) { + var t = Dd[e]; + return t || ud(18, e), t + } + + function xd(e, t) { + Dd[e] || (Dd[e] = t) + } + + function Pd() { + return Cd || ud(0), Cd + } + + function Rd(e, t) { + t && (Md("Patches"), e.patches_ = [], e.inversePatches_ = [], e.patchListener_ = t) + } + + function Ld(e) { + _d(e), e.drafts_.forEach(Fd), e.drafts_ = null + } + + function _d(e) { + e === Cd && (Cd = e.parent_) + } + + function Nd(e) { + return Cd = { + drafts_: [], + parent_: Cd, + immer_: e, + canAutoFreeze_: !0, + unfinalizedDrafts_: 0 + } + } + + function Fd(e) { + e = e[od]; + 0 === e.type_ || 1 === e.type_ ? e.revoke_() : e.revoked_ = !0 + } + + function Bd(e, t) { + t.unfinalizedDrafts_ = t.drafts_.length; + var i = t.drafts_[0], + r = void 0 !== e && e !== i; + return t.immer_.useProxies_ || Md("ES5").willFinalizeES5_(t, e, r), r ? (i[od].modified_ && (Ld(t), ud(4)), hd(e) && (e = Ud(t, e), t.parent_ || Vd(t, e)), t.patches_ && Md("Patches").generateReplacementPatches_(i[od], e, t.patches_, t.inversePatches_)) : e = Ud(t, i, []), Ld(t), t.patches_ && t.patchListener_(t.patches_, t.inversePatches_), e !== sd ? e : void 0 + } + + function Ud(i, r, n) { + if (kd(r)) return r; + var s, a = r[od]; + return a ? a.scope_ !== i ? r : a.modified_ ? (a.finalized_ || (a.finalized_ = !0, a.scope_.unfinalizedDrafts_--, s = 4 === a.type_ || 5 === a.type_ ? a.copy_ = wd(a.draft_) : a.copy_, md(3 === a.type_ ? new Set(s) : s, function(e, t) { + return $d(i, a, s, e, t, n) + }), Vd(i, s, !1), n && i.patches_ && Md("Patches").generatePatches_(a, n, i.patches_, i.inversePatches_)), a.copy_) : (Vd(i, a.base_, !0), a.base_) : (md(r, function(e, t) { + return $d(i, a, r, e, t, n) + }, !0), r) + } + + function $d(e, t, i, r, n, s) { + if (n === i && ud(5), cd(n)) { + s = Ud(e, n, s && t && 3 !== t.type_ && !yd(t.assigned_, r) ? s.concat(r) : void 0); + if (Sd(i, r, s), !cd(s)) return; + e.canAutoFreeze_ = !1 + } + hd(n) && !kd(n) && (!e.immer_.autoFreeze_ && e.unfinalizedDrafts_ < 1 || (Ud(e, n), t && t.scope_.parent_ || Vd(e, n))) + } + + function Vd(e, t, i) { + void 0 === i && (i = !1), e.immer_.autoFreeze_ && e.canAutoFreeze_ && Ad(t, i) + } + var Kd = { + get: function(e, t) { + if (t === od) return e; + var i, r, n = Id(e); + if (!yd(n, t)) return i = e, (r = jd(n, t)) ? "value" in r ? r.value : null === (r = r.get) || void 0 === r ? void 0 : r.call(i.draft_) : void 0; + n = n[t]; + return !e.finalized_ && hd(n) && n === Hd(e.base_, t) ? (Wd(e), e.copy_[t] = zd(e.scope_.immer_, n, e)) : n + }, + has: function(e, t) { + return t in Id(e) + }, + ownKeys: function(e) { + return Reflect.ownKeys(Id(e)) + }, + set: function(e, t, i) { + var r = jd(Id(e), t); + if (null != r && r.set) return r.set.call(e.draft_, i), !0; + if (!e.modified_) { + var n = Hd(Id(e), t), + r = null == n ? void 0 : n[od]; + if (r && r.base_ === i) return e.copy_[t] = i, !(e.assigned_[t] = !1); + if (bd(i, n) && (void 0 !== i || yd(e.base_, t))) return !0; + Wd(e), Qd(e) + } + return e.copy_[t] = i, e.assigned_[t] = !0 + }, + deleteProperty: function(e, t) { + return void 0 !== Hd(e.base_, t) || t in e.base_ ? (e.assigned_[t] = !1, Wd(e), Qd(e)) : delete e.assigned_[t], e.copy_ && delete e.copy_[t], !0 + }, + getOwnPropertyDescriptor: function(e, t) { + var i = Id(e), + r = Reflect.getOwnPropertyDescriptor(i, t); + return r && { + writable: !0, + configurable: 1 !== e.type_ || "length" !== t, + enumerable: r.enumerable, + value: i[t] + } + }, + defineProperty: function() { + ud(11) + }, + getPrototypeOf: function(e) { + return Object.getPrototypeOf(e.base_) + }, + setPrototypeOf: function() { + ud(12) + } + }, + qd = {}; + + function Hd(e, t) { + var i = e[od]; + return (i ? Id(i) : e)[t] + } + + function jd(e, t) { + if (t in e) + for (var i = Object.getPrototypeOf(e); i;) { + var r = Object.getOwnPropertyDescriptor(i, t); + if (r) return r; + i = Object.getPrototypeOf(i) + } + } + + function Qd(e) { + e.modified_ || (e.modified_ = !0, e.parent_ && Qd(e.parent_)) + } + + function Wd(e) { + e.copy_ || (e.copy_ = wd(e.base_)) + } + md(Kd, function(e, t) { + qd[e] = function() { + return arguments[0] = arguments[0][0], t.apply(this, arguments) + } + }), qd.deleteProperty = function(e, t) { + return isNaN(parseInt(t)) && ud(13), Kd.deleteProperty.call(this, e[0], t) + }, qd.set = function(e, t, i) { + return "length" !== t && isNaN(parseInt(t)) && ud(14), Kd.set.call(this, e[0], t, i, e[0]) + }; + (A = Gd.prototype).produce = function(e, s, t) { + if ("function" == typeof e && "function" != typeof s) { + var a = s; + s = e; + var o = this; + return function(e) { + var t = this; + void 0 === e && (e = a); + for (var i = arguments.length, r = new Array(1 < i ? i - 1 : 0), n = 1; n < i; n++) r[n - 1] = arguments[n]; + return o.produce(e, function(e) { + return s.call.apply(s, [t, e].concat(r)) + }) + } + } + var i; + if ("function" != typeof s && ud(6), void 0 !== t && "function" != typeof t && ud(7), hd(e)) { + var r = Nd(this), + n = zd(this, e, void 0), + l = !0; + try { + i = s(n), l = !1 + } finally { + (l ? Ld : _d)(r) + } + return "undefined" != typeof Promise && i instanceof Promise ? i.then(function(e) { + return Rd(r, t), Bd(e, r) + }, function(e) { + throw Ld(r), e + }) : (Rd(r, t), Bd(i, r)) + } + if (!e || "object" != typeof e) return (i = s(e)) === sd ? void 0 : (void 0 === i && (i = e), this.autoFreeze_ && Ad(i, !0), i); + ud(21, e) + }, A.produceWithPatches = function(n, e, t) { + var i, r, s = this; + return "function" == typeof n ? function(e) { + for (var t = arguments.length, i = new Array(1 < t ? t - 1 : 0), r = 1; r < t; r++) i[r - 1] = arguments[r]; + return s.produceWithPatches(e, function(e) { + return n.apply(void 0, [e].concat(i)) + }) + } : [this.produce(n, e, function(e, t) { + i = e, r = t + }), i, r] + }, A.createDraft = function(e) { + hd(e) || ud(8), cd(e) && (e = Xd(e)); + var t = Nd(this), + e = zd(this, e, void 0); + return e[od].isManual_ = !0, _d(t), e + }, A.finishDraft = function(e, t) { + e = e && e[od]; + e && e.isManual_ || ud(9), e.finalized_ && ud(10); + e = e.scope_; + return Rd(e, t), Bd(void 0, e) + }, A.setAutoFreeze = function(e) { + this.autoFreeze_ = e + }, A.setUseProxies = function(e) { + e && !nd && ud(20), this.useProxies_ = e + }, A.applyPatches = function(e, t) { + for (var i = t.length - 1; 0 <= i; i--) { + var r = t[i]; + if (0 === r.path.length && "replace" === r.op) { + e = r.value; + break + } + } + var n = Md("Patches").applyPatches_; + return cd(e) ? n(e, t) : this.produce(e, function(e) { + return n(e, t.slice(i + 1)) + }) + }, Vr = Gd; + + function Gd(e) { + this.useProxies_ = nd, this.autoFreeze_ = !0, "boolean" == typeof(null == e ? void 0 : e.useProxies) && this.setUseProxies(e.useProxies), "boolean" == typeof(null == e ? void 0 : e.autoFreeze) && this.setAutoFreeze(e.autoFreeze), this.produce = this.produce.bind(this), this.produceWithPatches = this.produceWithPatches.bind(this) + } + + function zd(e, t, i) { + t = Td(t) ? Md("MapSet").proxyMap_(t, i) : Ed(t) ? Md("MapSet").proxySet_(t, i) : e.useProxies_ ? function(e, t) { + var i = Array.isArray(e), + r = { + type_: i ? 1 : 0, + scope_: t ? t.scope_ : Pd(), + modified_: !1, + finalized_: !1, + assigned_: {}, + parent_: t, + base_: e, + draft_: null, + copy_: null, + revoke_: null, + isManual_: !1 + }, + t = r, + e = Kd; + i && (t = [r], e = qd); + t = Proxy.revocable(t, e), e = t.revoke, t = t.proxy; + return r.draft_ = t, r.revoke_ = e, t + }(t, i) : Md("ES5").createES5Proxy_(t, i); + return (i ? i.scope_ : Pd()).drafts_.push(t), t + } + + function Xd(e) { + return cd(e) || ud(22, e), + function i(e) { + if (!hd(e)) return e; + var r, n = e[od], + t = gd(e); + if (n) { + if (!n.modified_ && (n.type_ < 4 || !Md("ES5").hasChanges_(n))) return n.base_; + n.finalized_ = !0, r = Yd(e, t), n.finalized_ = !1 + } else r = Yd(e, t); + return md(r, function(e, t) { + n && vd(n.base_, e) === t || Sd(r, e, i(t)) + }), 3 === t ? new Set(r) : r + }(e) + } + + function Yd(e, t) { + switch (t) { + case 2: + return new Map(e); + case 3: + return Array.from(e) + } + return wd(e) + } + + function Jd() { + var r = {}; + + function l(i, e) { + var t = r[i]; + return t ? t.enumerable = e : r[i] = t = { + configurable: !0, + enumerable: e, + get: function() { + var e = this[od]; + return a(e), Kd.get(e, i) + }, + set: function(e) { + var t = this[od]; + a(t), Kd.set(t, i, e) + } + }, t + } + + function n(e) { + for (var t = e.length - 1; 0 <= t; t--) { + var i = e[t][od]; + if (!i.modified_) switch (i.type_) { + case 5: + u(i) && Qd(i); + break; + case 4: + s(i) && Qd(i) + } + } + } + + function s(e) { + for (var t = e.base_, i = e.draft_, r = pd(i), n = r.length - 1; 0 <= n; n--) { + var s = r[n]; + if (s !== od) { + var a = t[s]; + if (void 0 === a && !yd(t, s)) return !0; + var o = i[s], + s = o && o[od]; + if (s ? s.base_ !== a : !bd(o, a)) return !0 + } + } + e = !!t[od]; + return r.length !== pd(t).length + (e ? 0 : 1) + } + + function u(e) { + var t = e.draft_; + if (t.length !== e.base_.length) return !0; + t = Object.getOwnPropertyDescriptor(t, t.length - 1); + return !(!t || t.get) + } + + function a(e) { + e.revoked_ && ud(3, JSON.stringify(Id(e))) + } + xd("ES5", { + createES5Proxy_: function(e, t) { + var i = Array.isArray(e), + r = function(e, t) { + if (e) { + for (var i = new Array(t.length), r = 0; r < t.length; r++) Object.defineProperty(i, "" + r, l(r, !0)); + return i + } + var n = fd(t); + delete n[od]; + for (var s = pd(n), a = 0; a < s.length; a++) { + var o = s[a]; + n[o] = l(o, e || !!n[o].enumerable) + } + return Object.create(Object.getPrototypeOf(t), n) + }(i, e), + e = { + type_: i ? 5 : 4, + scope_: t ? t.scope_ : Pd(), + modified_: !1, + finalized_: !1, + assigned_: {}, + parent_: t, + base_: e, + draft_: r, + copy_: null, + revoked_: !1, + isManual_: !1 + }; + return Object.defineProperty(r, od, { + value: e, + writable: !0 + }), r + }, + willFinalizeES5_: function(e, t, i) { + i ? cd(t) && t[od].scope_ === e && n(e.drafts_) : (e.patches_ && function t(e) { + if (e && "object" == typeof e) { + var i = e[od]; + if (i) { + var r = i.base_, + n = i.draft_, + s = i.assigned_; + if (4 === (e = i.type_)) md(n, function(e) { + e !== od && (void 0 !== r[e] || yd(r, e) ? s[e] || t(n[e]) : (s[e] = !0, Qd(i))) + }), md(r, function(e) { + void 0 !== n[e] || yd(n, e) || (s[e] = !1, Qd(i)) + }); + else if (5 === e) { + if (u(i) && (Qd(i), s.length = !0), n.length < r.length) + for (var a = n.length; a < r.length; a++) s[a] = !1; + else + for (var o = r.length; o < n.length; o++) s[o] = !0; + for (var l = Math.min(n.length, r.length), d = 0; d < l; d++) void 0 === s[d] && t(n[d]) + } + } + } + }(e.drafts_[0]), n(e.drafts_)) + }, + hasChanges_: function(e) { + return (4 === e.type_ ? s : u)(e) + } + }) + } + + function Zd() { + var m = "replace", + g = "add", + y = "remove"; + + function d(e) { + if (!hd(e)) return e; + if (Array.isArray(e)) return e.map(d); + if (Td(e)) return new Map(Array.from(e.entries()).map(function(e) { + return [e[0], d(e[1])] + })); + if (Ed(e)) return new Set(Array.from(e).map(d)); + var t, i = Object.create(Object.getPrototypeOf(e)); + for (t in e) i[t] = d(e[t]); + return i + } + + function v(e) { + return cd(e) ? d(e) : e + } + xd("Patches", { + applyPatches_: function(l, e) { + return e.forEach(function(e) { + for (var t = e.path, i = e.op, r = l, n = 0; n < t.length - 1; n++) "object" != typeof(r = vd(r, t[n])) && ud(15, t.join("/")); + var s = gd(r), + a = d(e.value), + o = t[t.length - 1]; + switch (i) { + case m: + switch (s) { + case 2: + return r.set(o, a); + case 3: + ud(16); + default: + return r[o] = a + } + case g: + switch (s) { + case 1: + return r.splice(o, 0, a); + case 2: + return r.set(o, a); + case 3: + return r.add(a); + default: + return r[o] = a + } + case y: + switch (s) { + case 1: + return r.splice(o, 1); + case 2: + return r.delete(o); + case 3: + return r.delete(e.value); + default: + return delete r[o] + } + default: + ud(17, i) + } + }), l + }, + generatePatches_: function(c, e, t, i) { + switch (c.type_) { + case 0: + case 4: + case 2: + return d = e, u = t, h = i, p = c.base_, f = c.copy_, void md(c.assigned_, function(e, t) { + var i = vd(p, e), + r = vd(f, e), + t = t ? yd(p, e) ? m : g : y; + i === r && t == m || (e = d.concat(e), u.push(t == y ? { + op: t, + path: e + } : { + op: t, + path: e, + value: r + }), h.push(t == g ? { + op: y, + path: e + } : t == y ? { + op: g, + path: e, + value: v(i) + } : { + op: m, + path: e, + value: v(i) + })) + }); + case 5: + case 1: + return function(e, t, i) { + var r, n = c.base_, + s = c.assigned_, + a = c.copy_; + a.length < n.length && (n = (r = [a, n])[0], a = r[1], t = (r = [i, t])[0], i = r[1]); + for (var o, l = 0; l < n.length; l++) s[l] && a[l] !== n[l] && (o = e.concat([l]), t.push({ + op: m, + path: o, + value: v(a[l]) + }), i.push({ + op: m, + path: o, + value: v(n[l]) + })); + for (var d = n.length; d < a.length; d++) { + var u = e.concat([d]); + t.push({ + op: g, + path: u, + value: v(a[d]) + }) + } + n.length < a.length && i.push({ + op: m, + path: e.concat(["length"]), + value: n.length + }) + }(e, t, i); + case 3: + return r = e, n = t, s = i, a = c.base_, o = c.copy_, l = 0, a.forEach(function(e) { + var t; + o.has(e) || (t = r.concat([l]), n.push({ + op: y, + path: t, + value: e + }), s.unshift({ + op: g, + path: t, + value: e + })), l++ + }), l = 0, void o.forEach(function(e) { + var t; + a.has(e) || (t = r.concat([l]), n.push({ + op: g, + path: t, + value: e + }), s.unshift({ + op: y, + path: t, + value: e + })), l++ + }) + } + var r, n, s, a, o, l, d, u, h, p, f + }, + generateReplacementPatches_: function(e, t, i, r) { + i.push({ + op: m, + path: [], + value: t + }), r.push({ + op: m, + path: [], + value: e.base_ + }) + } + }) + } + + function eu() { + var r = function(e, t) { + return (r = Object.setPrototypeOf || { + __proto__: [] + } + instanceof Array && function(e, t) { + e.__proto__ = t + } || function(e, t) { + for (var i in t) t.hasOwnProperty(i) && (e[i] = t[i]) + })(e, t) + }; + + function i(e, t) { + function i() { + this.constructor = e + } + r(e, t), e.prototype = (i.prototype = t.prototype, new i) + } + var n = function() { + function e(e, t) { + return this[od] = { + type_: 2, + parent_: t, + scope_: t ? t.scope_ : Pd(), + modified_: !1, + finalized_: !1, + copy_: void 0, + assigned_: void 0, + base_: e, + draft_: this, + isManual_: !1, + revoked_: !1 + }, this + } + i(e, Map); + var t = e.prototype; + return Object.defineProperty(t, "size", { + get: function() { + return Id(this[od]).size + } + }), t.has = function(e) { + return Id(this[od]).has(e) + }, t.set = function(e, t) { + var i = this[od]; + return l(i), Id(i).has(e) && Id(i).get(e) === t || (s(i), Qd(i), i.assigned_.set(e, !0), i.copy_.set(e, t), i.assigned_.set(e, !0)), this + }, t.delete = function(e) { + if (!this.has(e)) return !1; + var t = this[od]; + return l(t), s(t), Qd(t), t.assigned_.set(e, !1), t.copy_.delete(e), !0 + }, t.clear = function() { + var t = this[od]; + l(t), Id(t).size && (s(t), Qd(t), t.assigned_ = new Map, md(t.base_, function(e) { + t.assigned_.set(e, !1) + }), t.copy_.clear()) + }, t.forEach = function(r, n) { + var s = this; + Id(this[od]).forEach(function(e, t, i) { + r.call(n, s.get(t), t, s) + }) + }, t.get = function(e) { + var t = this[od]; + l(t); + var i = Id(t).get(e); + if (t.finalized_ || !hd(i)) return i; + if (i !== t.base_.get(e)) return i; + i = zd(t.scope_.immer_, i, t); + return s(t), t.copy_.set(e, i), i + }, t.keys = function() { + return Id(this[od]).keys() + }, t.values = function() { + var e, t = this, + i = this.keys(); + return (e = {})[ld] = function() { + return t.values() + }, e.next = function() { + var e = i.next(); + return e.done ? e : { + done: !1, + value: t.get(e.value) + } + }, e + }, t.entries = function() { + var e, i = this, + r = this.keys(); + return (e = {})[ld] = function() { + return i.entries() + }, e.next = function() { + var e = r.next(); + if (e.done) return e; + var t = i.get(e.value); + return { + done: !1, + value: [e.value, t] + } + }, e + }, t[ld] = function() { + return this.entries() + }, e + }(); + + function s(e) { + e.copy_ || (e.assigned_ = new Map, e.copy_ = new Map(e.base_)) + } + var a = function() { + function e(e, t) { + return this[od] = { + type_: 3, + parent_: t, + scope_: t ? t.scope_ : Pd(), + modified_: !1, + finalized_: !1, + copy_: void 0, + base_: e, + draft_: this, + drafts_: new Map, + revoked_: !1, + isManual_: !1 + }, this + } + i(e, Set); + var t = e.prototype; + return Object.defineProperty(t, "size", { + get: function() { + return Id(this[od]).size + } + }), t.has = function(e) { + var t = this[od]; + return l(t), t.copy_ ? !!t.copy_.has(e) || !(!t.drafts_.has(e) || !t.copy_.has(t.drafts_.get(e))) : t.base_.has(e) + }, t.add = function(e) { + var t = this[od]; + return l(t), this.has(e) || (o(t), Qd(t), t.copy_.add(e)), this + }, t.delete = function(e) { + if (!this.has(e)) return !1; + var t = this[od]; + return l(t), o(t), Qd(t), t.copy_.delete(e) || !!t.drafts_.has(e) && t.copy_.delete(t.drafts_.get(e)) + }, t.clear = function() { + var e = this[od]; + l(e), Id(e).size && (o(e), Qd(e), e.copy_.clear()) + }, t.values = function() { + var e = this[od]; + return l(e), o(e), e.copy_.values() + }, t.entries = function() { + var e = this[od]; + return l(e), o(e), e.copy_.entries() + }, t.keys = function() { + return this.values() + }, t[ld] = function() { + return this.values() + }, t.forEach = function(e, t) { + for (var i = this.values(), r = i.next(); !r.done;) e.call(t, r.value, r.value, this), r = i.next() + }, e + }(); + + function o(i) { + i.copy_ || (i.copy_ = new Set, i.base_.forEach(function(e) { + var t; + hd(e) ? (t = zd(i.scope_.immer_, e, i), i.drafts_.set(e, t), i.copy_.add(t)) : i.copy_.add(e) + })) + } + + function l(e) { + e.revoked_ && ud(3, JSON.stringify(Id(e))) + } + xd("MapSet", { + proxyMap_: function(e, t) { + return new n(e, t) + }, + proxySet_: function(e, t) { + return new a(e, t) + } + }) + } + var tu = new Vr, + vr = tu.produce, + iu = tu.produceWithPatches.bind(tu), + ru = tu.setAutoFreeze.bind(tu), + nu = tu.setUseProxies.bind(tu), + vi = tu.applyPatches.bind(tu), + A = tu.createDraft.bind(tu), + tu = tu.finishDraft.bind(tu); + w.Immer = Vr, w.applyPatches = vi, w.castDraft = function(e) { + return e + }, w.castImmutable = function(e) { + return e + }, w.createDraft = A, w.current = Xd, w.default = vr, w.enableAllPlugins = function() { + Jd(), eu(), Zd() + }, w.enableES5 = Jd; + A = w.enableMapSet = eu; + w.enablePatches = Zd, w.finishDraft = tu, w.immerable = ad, w.isDraft = cd, w.isDraftable = hd, w.nothing = sd, w.original = function(e) { + return cd(e) || ud(23, e), e[od].base_ + }; + var su = w.produce = vr; + w.produceWithPatches = iu; + var au = w.setAutoFreeze = ru; + w.setUseProxies = nu; + const ou = /^((?:[^\/;?#]+:)?)(\/\/[^\/\;?#]*)?(.*?)??(;.*?)?(\?.*?)?(#.*?)?$/, + lu = /^([^\/;?#]*)(.*)$/, + du = /(?:\/|^)\.(?=\/)/g, + uu = /(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g, + cu = { + buildAbsoluteURL: function(e, t, i) { + if (i = i || {}, e = e.trim(), !(t = t.trim())) { + if (!i.alwaysNormalize) return e; + const t = cu.parseURL(e); + if (!t) throw new Error("Error trying to parse base URL."); + return t.path = cu.normalizePath(t.path), cu.buildURLFromParts(t) + } + const r = cu.parseURL(t); + if (!r) throw new Error("Error trying to parse relative URL."); + if (r.scheme) return i.alwaysNormalize ? (r.path = cu.normalizePath(r.path), cu.buildURLFromParts(r)) : t; + const n = cu.parseURL(e); + if (!n) throw new Error("Error trying to parse base URL."); + if (!n.netLoc && n.path && "/" !== n.path[0]) { + const e = lu.exec(n.path); + n.netLoc = e[1], n.path = e[2] + } + n.netLoc && !n.path && (n.path = "/"); + const s = { + scheme: n.scheme, + netLoc: r.netLoc, + path: null, + params: r.params, + query: r.query, + fragment: r.fragment + }; + if (!r.netLoc && (s.netLoc = n.netLoc, "/" !== r.path[0])) + if (r.path) { + i.inheritQuery && (r.query || (s.query = n.query)); + const e = n.path, + t = e.substring(0, e.lastIndexOf("/") + 1) + r.path; + s.path = cu.normalizePath(t) + } else s.path = n.path, r.params || (s.params = n.params, r.query || (s.query = n.query)); + return null === s.path && (s.path = i.alwaysNormalize ? cu.normalizePath(r.path) : r.path), cu.buildURLFromParts(s) + }, + parseURL: function(e) { + e = ou.exec(e); + return e ? { + scheme: e[1] || "", + netLoc: e[2] || "", + path: e[3] || "", + params: e[4] || "", + query: e[5] || "", + fragment: e[6] || "" + } : null + }, + normalizePath: function(e) { + for (e = e.split("").reverse().join("").replace(du, ""); e.length !== (e = e.replace(uu, "")).length;); + return e.split("").reverse().join("") + }, + buildURLFromParts: function(e) { + return e.scheme + e.netLoc + e.path + e.params + e.query + e.fragment + }, + getHostName: function(e) { + let t; + return e && (t = -1 < e.indexOf("://") ? e.split("/")[2] : e.split("/")[0], t = t.split(":")[0], t = t.split("?")[0]), t + } + }; + var hu, pu, fu, mu, gu, yu, vu, Su, bu = cu; + + function Tu(e) { + return null != e && !e.startsWith("http://") && !e.startsWith("https://") + } + + function Eu(e) { + return null == e || Tu(e) ? null : cu.getHostName(e) + } + const Iu = [".*.itunes.apple.com"], + wu = { + deviceName: "&xapdn=", + deviceModel: "&xapdm=", + language: "&xapdl=", + dsid: "&xapdsid=", + subs: "&xapsub=" + }; + + function Au(e, t) { + return !e || e === Eu(t) + }(iu = hu = hu || {})[iu.DOVI = 4] = "DOVI", iu[iu.HEVC = 3] = "HEVC", iu[iu.VP09 = 2] = "VP09", iu[iu.AVC = 1] = "AVC", iu[iu.UNKNOWN = 0] = "UNKNOWN", (ru = pu = pu || {})[ru.PQ = 3] = "PQ", ru[ru.HLG = 2] = "HLG", ru[ru.SDR = 1] = "SDR", ru[ru.UNKNOWN = 0] = "UNKNOWN", (w = fu = fu || {})[w.ALAC = 7] = "ALAC", w[w.FLAC = 6] = "FLAC", w[w.EC3 = 5] = "EC3", w[w.AC3 = 4] = "AC3", w[w.XHEAAC = 3] = "XHEAAC", w[w.AAC = 2] = "AAC", w[w.MP3 = 1] = "MP3", w[w.UNKNOWN = 0] = "UNKNOWN", (nu = mu = mu || {})[nu.VALID = 1] = "VALID", nu[nu.INVALID = 0] = "INVALID"; + const Ou = ["via", "x-apple-request-uuid"], + ku = { + maxNumRetry: 4, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + Cu = { + maxNumRetry: 6, + retryDelayMs: 1e3, + maxRetryDelayMs: 8e3 + }, + Du = { + maxNumRetry: 0, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + Mu = { + default: { + maxTimeToFirstByteMs: 5e3, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: Du, + errorRetry: Du + }, + customURL: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: Du, + errorRetry: Du + } + }, + xu = { + maxNumRetry: 8, + retryDelayMs: 1e3, + maxRetryDelayMs: 2e4, + backoff: "linear" + }, + Pu = Object.assign(Object.assign({}, xu), { + maxNumRetry: 1 + }), + Ru = { + autoStartLoad: !0, + startPosition: NaN, + defaultAudioCodec: void 0, + defaultVideoCodec: void 0, + debug: !1, + debugLevel: "info", + buildType: void 0, + minFramesBeforeSwitchingLevel: 11, + minTargetDurations: 3, + maxBufferLength: 60, + maxBufferHole: .5, + maxSeekHole: 2, + nudgeFromEventSeek: !0, + jaggedSeekTolerance: 0, + discontinuitySeekTolerance: 2, + bufferedSegmentEjectionToleranceMs: .5, + almostDryBufferSec: .5, + maxTotalDurationTolerance: .1, + lowBufferThreshold: .5, + lowBufferWatchdogPeriod: .5, + highBufferWatchdogPeriod: 3, + seekWatchdogPeriod: 5, + nudgeOffset: .1, + nudgeMaxRetry: 3, + maxFragLookUpTolerance: .2, + initialLiveManifestSize: 1, + liveSyncDurationCount: 3, + liveMaxLatencyDurationCount: 1 / 0, + liveSyncDuration: void 0, + liveMaxLatencyDuration: void 0, + liveFlushExpiredFrags: !0, + liveMaxUnchangedPlaylistRefresh: 3, + liveEdgeForZeroStartPositon: !1, + livePlaylistUpdateStaleness: 2, + livePlaylistDurationNudge: .001, + allowFastSwitchUp: !1, + minMatchGroupDuration: 5, + desiredIframeFPS: 8, + initialIframeFPS: 6, + minRemainingTimeInMediaPipeline: 3, + leftMediaTimeToAutoPause: 10, + startTargetDurationFactor: .9, + minRequiredStartDuration: 4, + maxRequiredStartDuration: 15, + enableWorker: !0, + enableWebCrypto: !0, + keySystemPreference: void 0, + useMultipleKeySessions: !1, + enablePlayReadyKeySystem: !1, + useMediaKeySystemAccessFilter: !1, + playReadyMessageFormat: "utf16", + startLevel: void 0, + livePlaylistRefreshDelay: 2500, + liveMinPlayingBufferLen: 5, + enableIFramePreloading: !0, + useMediaCapabilities: !1, + enableID3Cues: !0, + certLoadPolicy: Mu, + keyLoadPolicy: { + default: { + maxTimeToFirstByteMs: 5e3, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: Pu, + errorRetry: xu + }, + customURL: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: Pu, + errorRetry: xu + } + }, + manifestLoadPolicy: { + default: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + errorRetry: { + maxNumRetry: 1, + retryDelayMs: 1e3, + maxRetryDelayMs: 8e3 + } + }, + customURL: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 1e4, + autoRetry: !1, + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + errorRetry: { + maxNumRetry: 1, + retryDelayMs: 1e3, + maxRetryDelayMs: 8e3 + } + } + }, + trickPlaybackConfig: { + enabled: !0, + minIframeDuration: 8 + }, + playlistLoadPolicy: { + default: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + errorRetry: { + maxNumRetry: 2, + retryDelayMs: 1e3, + maxRetryDelayMs: 8e3 + } + }, + customURL: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 1e4, + autoRetry: !1, + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + errorRetry: { + maxNumRetry: 2, + retryDelayMs: 1e3, + maxRetryDelayMs: 8e3 + } + } + }, + fragLoadPolicy: { + default: { + maxTimeToFirstByteMs: 5e3, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: ku, + errorRetry: Cu, + forceContentLenCheckIfNoHeader: !1, + reportCDNServer: !0 + }, + customURL: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: ku, + errorRetry: Cu, + reportCDNServer: !0 + } + }, + steeringManifestLoadPolicy: { + default: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 2e4, + autoRetry: !1, + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + errorRetry: { + maxNumRetry: 1, + retryDelayMs: 1e3, + maxRetryDelayMs: 8e3 + } + }, + customURL: { + maxTimeToFirstByteMs: 1e4, + maxLoadTimeMs: 1e4, + autoRetry: !1, + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0 + }, + errorRetry: { + maxNumRetry: 1, + retryDelayMs: 1e3, + maxRetryDelayMs: 8e3 + } + } + }, + maxNumAddLevelToPenaltyBox: 4, + firstAudioMustOverlapVideoStart: !1, + keyMinHoldTimeBeforeCleanup: 15e3, + startFragPrefetch: !1, + appendErrorMaxRetry: 3, + alwaysResetOnNewCC: !1, + fLoader: void 0, + pLoader: void 0, + xhrSetup: void 0, + iframeMaxExitSeekDuration: 2e3, + iframeStallMaxRetry: 5, + audioPrimingDelay: 0, + enableCEA708Captions: !0, + customTextTrackCueRenderer: !1, + enableWebVTT: !0, + captionsTextTrack1Label: "English", + captionsTextTrack1LanguageCode: "en", + captionsTextTrack2Label: "Spanish", + captionsTextTrack2LanguageCode: "es", + enableDualTrackSelection: !1, + condenseSubtitleTrack: !1, + nativeTextTrackChangeHandling: !0, + earlyFragTolerance: 7, + vttConcurrentLoadCount: 1, + trottleCheckInterval: 2e3, + subtitleLeadTime: 30, + lateTolerance: 2, + stretchShortVideoTrack: !1, + forceKeyFrameOnDiscontinuity: !0, + useFirstLevelAtIncompatDiscontinuity: !0, + abrBandwidthEstimator: "bandwidth-history-controller", + abrEwmaDefaultEstimate: 5e5, + abrDefaultEstimate: 5e5, + abrBandWidthFactor: .95, + abrBandWidthUpFactor: .9, + abrMaxWithRealBitrate: !1, + maxStarvationDelay: 4, + maxLoadingDelay: 4, + minAutoBitrate: 0, + enableRtcReporting: !1, + rtcIntervalTimeout: 3e5, + rtcSender: "HLSJS", + rtcSessionTag: "none", + useHTTPPlaybackSessionId: !1, + warmupCdms: !1, + enablePerformanceLogging: !1, + overridePlaybackRate: !1, + nativeControlsEnabled: !1, + useCustomMediaFunctions: !0, + seekEventThrottleMs: 150, + enableAdaptiveStartup: !0, + bandwidthHistoryWindowSize: 12e4, + bandwidthHistoryTTL: 6e5, + bandwidthHistoryAggregationMethod: "quadratic-time-weighted", + bandwidthHistoryGetEstimateThrottleMs: 1e3, + defaultTargetDuration: 10, + targetStartupMs: 4e3, + adaptiveStartupMetricsOverride: { + maxValidHeight: 1080, + maxValidBitrate: 1 / 0, + maxPreferredBitrate: 1 / 0 + }, + bandwidthHistoryStorageKey: "AppleHLS-bandwidth-estimation", + storageKeyPrefix: "AppleHLS-", + storage: { + get: "undefined" == typeof localStorage ? void 0 : localStorage.getItem.bind(localStorage), + set: "undefined" == typeof localStorage ? void 0 : localStorage.setItem.bind(localStorage) + }, + minFragmentCount: 10, + minPlaylistCount: 5, + enableCDNFallback: !0, + enableQueryParamsForITunes: !1, + gapless: !1, + useViewportSizeForLevelCap: !1, + statDefaults: { + playlistLoadTimeMs: 500, + playlistParseTimeMs: 50, + fragParseTimeMs: 50, + fragBufferCreationDelayMs: 200, + dataFragAppendMs: 50, + initFragAppendMs: 50 + }, + disableVideoCodecList: new Set([]), + disableAudioCodecList: new Set([fu.ALAC, fu.FLAC, fu.XHEAAC]), + useHighestVideoCodecPrivate: !0, + sessionDataAutoLoad: { + "com.apple.hls.chapters": !0 + } + }, + Lu = Object.assign(Object.assign({}, { + itemId: "Nah", + mediaOptionId: "Nah" + }), { + mediaOptionType: void 0 + }), + _u = e => { + var { + itemId: t, + mediaOptionId: e + } = e; + return "Nah" !== t && "Nah" !== e + }; + (iu = gu = gu || {})[iu.Variant = 0] = "Variant", iu[iu.AltAudio = 1] = "AltAudio", iu[iu.Subtitle = 2] = "Subtitle"; + const Nu = ["variant", "altAudio", "subtitle"], + Fu = [gu.Variant, gu.AltAudio, gu.Subtitle], + Bu = [gu.Variant, gu.AltAudio]; + (ru = yu = yu || {})[ru.Variant = 0] = "Variant", ru[ru.AltAudio = 1] = "AltAudio"; + const Uu = ["variant", "altAudio"]; + + function $u(e) { + switch (e) { + case gu.Variant: + return yu.Variant; + case gu.AltAudio: + return yu.AltAudio; + default: + return null + } + } + + function Vu(e) { + return e === yu.Variant ? gu.Variant : gu.AltAudio + }(w = vu = vu || {})[w.NO = 0] = "NO", w[w.YES = 1] = "YES", (nu = Su = Su || {}).UNKNOWN = "unkn", nu.VIDEO = "vide", nu.AUDIO = "soun", nu.SUBTITLE = "sbtl", nu.CLOSEDCAPTION = "clcp"; + const Ku = { + search: function(e, t) { + let i, r, n = 0, + s = (null == e ? void 0 : e.length) - 1; + for (; n <= s;) { + var a = t(r = e[i = (n + s) / 2 | 0]); + if (0 < a) n = 1 + i; + else { + if (!(a < 0)) return r; + s = i - 1 + } + } + return null + } + }; + var qu = Ku, + Hu = { + findFragmentBySNAndBuffer: function(e, t, i = 0, r = 0, n = 0) { + let s; + e = e ? t[e.mediaSeqNum - t[0].mediaSeqNum + 1] : null; + return s = i < r ? (r - n < i && (n = 0), e && !this.fragmentWithinToleranceTest(i, n, e) ? e : Ku.search(t, this.fragmentWithinToleranceTest.bind(null, i, n))) : t[t.length - 1], s + }, + fragmentWithinToleranceTest: function(e, t, i) { + t = Math.min(t, i.duration); + return i.start + i.duration - t <= e ? 1 : i.start - t > e && i.start ? -1 : 0 + } + }; + const ju = { + startFragmentInCC: function(e, t, i) { + let r = t - i.discoSeqNum; + if (0 === r) { + const t = e[i.mediaSeqNum - e[0].mediaSeqNum - 1]; + r = t && t.discoSeqNum === i.discoSeqNum ? -1 : 0 + } + return r + }, + endFragmentInCC: function(e, t, i) { + let r = t - i.discoSeqNum; + if (0 === r) { + const t = e[i.mediaSeqNum - e[0].mediaSeqNum + 1]; + r = t && t.discoSeqNum === i.discoSeqNum ? 1 : 0 + } + return r + }, + findStartEndFragmentsInCC: function(e, t, i) { + let r, n; + return 0 < (null == e ? void 0 : e.length) && ne(t) && (r = Ku.search(e, ju.startFragmentInCC.bind(null, e, t)), n = Ku.search(e, ju.endFragmentInCC.bind(null, e, t))), r && !ne(r.discoSeqNum) && (r = void 0), n && !ne(n.discoSeqNum) && (n = void 0), { + startFrag: r, + endFrag: n + } + }, + getTimeRangeDictForCC: function(e, t, i) { + var { + startFrag: t, + endFrag: i + } = ju.findStartEndFragmentsInCC(e, t, i); + return { + start: t.start, + end: i.start + i.duration + } + }, + getTimeRangeForCC: function(e, t, i) { + var { + startFrag: t, + endFrag: i + } = ju.findStartEndFragmentsInCC(e, t, i); + let r = []; + return t && i && (r = [t.start, i.start + i.duration]), r + }, + snapToCCTimeRange: function(e, t, i, r) { + r = ju.getTimeRangeForCC(t, i, r); + return null != r && r.length ? Math.min(r[1], Math.max(r[0], e)) : e + }, + getMinTimeForCC(e, t, i, r) { + if (null == e || !e.length) return 0; + let n = 0; + if (ne(i) && e) { + e = ju.getTimeRangeForCC(e, i, r); + if (e) { + const s = ju.getTimeRangeForCC(t, i, r); + n = null != s && s.length ? Math.max(s[0], e[0]) : e[0] + } + } + return n + }, + discoSeqNumForTime(e, t, i = 0) { + i = Ku.search(e, Hu.fragmentWithinToleranceTest.bind(null, t, i)); + return null == i ? void 0 : i.discoSeqNum + } + }; + var Qu = ju; + const Wu = $i(void 0); + + function Gu(e, t, i = 1) { + return e.pipe(ln(t), Ds(i)) + } + + function zu(e, t) { + var i = e.timeline; + return { + seconds: (e.seconds - i.rootTimeSeconds) / i.rate * t.rate + t.rootTimeSeconds, + timeline: t + } + } + class Xu { + constructor() { + this._timeline = null + } + get forward() { + var e; + return 0 < (null === (e = this.timeline) || void 0 === e ? void 0 : e.rate) + } + get isStarted() { + return Boolean(this.hostClock) + } + start(e) { + this.stopTime = null, this._timeline = Object.assign({}, e); + const t = { + rootTimeSeconds: performance.now() / 1e3, + rate: 1 + }; + this.hostClock = { + timeline: t, + getCurrentTime: () => ({ + seconds: performance.now() / 1e3, + timeline: t + }) + } + } + pause() { + this.isStarted && (this.stopTime = this.getCurrentTime()) + } + stop() { + this.pause(), this.hostClock = null, this._timeline = null + } + get timeline() { + return this._timeline + } + getCurrentTime() { + return this.stopTime || zu(this.hostClock.getCurrentTime(), this.timeline) + } + } + class Yu { + constructor(e) { + this._timeline = e, this.mediaRootTime = this.lastTimeSeconds = e.rootTimeSeconds + } + get timeline() { + return Object.assign({}, this._timeline) + } + getCurrentTime() { + return { + seconds: this.lastTimeSeconds, + timeline: Object.assign({}, this._timeline) + } + } + } + const Ju = { + name: "ifm" + }; + class Zu { + constructor(e, t) { + this.config = e, this.logger = t, this.scaledFragments = [], this.iframeClock = new Xu, this.hasMore$ = new yi(!0), this.logger = t.child(Ju) + } + destroy() { + this.stop() + } + resetScaledSegments() { + this.scaledFragments = [] + } + get anchorFrag() { + return this.scaledFragments.length ? this.scaledFragments[0] : null + } + get lastFrag() { + return this.scaledFragments.length ? this.scaledFragments.slice(-1)[0] : null + } + get isStarted() { + return Boolean(this.iframeClock.isStarted) + } + get iframeRate() { + var e; + return null !== (e = null === (e = this.iframeClock.timeline) || void 0 === e ? void 0 : e.rate) && void 0 !== e ? e : 0 + } + get iframeClockTimeSeconds() { + return Math.max(0, this.iframeClock.getCurrentTime().seconds) + } + get mediaAppendClockTimeSeconds() { + var e; + return null !== (e = null === (e = this.mediaAppendClock) || void 0 === e ? void 0 : e.getCurrentTime().seconds) && void 0 !== e ? e : 0 + } + get mediaRootTime() { + var e; + return null === (e = this.mediaAppendClock) || void 0 === e ? void 0 : e.mediaRootTime + } + pause() { + this.iframeClock.pause() + } + stop() { + this.hasMore$.next(!0), this.iframeClock.stop(), this.mediaAppendClock = null, this.resetScaledSegments() + } + checkHasMore() { + this.hasMore$.next(!0) + } + startClocksAndGetFirstFragment(e, t, i, r, n) { + let s = Ku.search(e, Hu.fragmentWithinToleranceTest.bind(null, r, 1e-4)); + if (!s && r >= e[e.length - 1].start && (s = e[e.length - 1]), !s) return this.logger.error(`startClocksAndGetFirstFragment => no anchorFrag for time ${r}`), this.hasMore$.next(!1), null; + var a = ne(n) ? n : s.discoSeqNum, + a = Qu.getMinTimeForCC(e, t, a, this.logger), + r = ne(n) && 1 < i ? a : r, + a = 1 < i ? Math.ceil(r) : Math.ceil(a); + return this.iframeClock.start({ + rootTimeSeconds: r, + rate: i + }), this.mediaAppendClock = new Yu({ + rootTimeSeconds: a, + rate: 1 + }), { + frag: s, + newMediaRootTime: a + } + } + getNextFragment(e, t, i) { + const r = this.lastFrag, + { + iframeClock: n, + mediaAppendClock: s + } = this, + a = n.timeline; + s.lastTimeSeconds = t; + var o = n.forward ? 1 : -1; + let l, d = Math.max(0, Math.min(r.mediaSeqNum - e[0].mediaSeqNum + o, e.length - 1)); + if (r.mediaSeqNum !== e[d].mediaSeqNum) + do { + l = e[d]; + const i = n.forward ? l.start : l.start + l.duration; + if (zu({ + seconds: i, + timeline: a + }, s.timeline).seconds >= t && (n.forward && i >= this.iframeClockTimeSeconds || !n.forward && i <= this.iframeClockTimeSeconds)) break + } while (d += o, 0 < d && d < e.length); + return l || (this.logger.error(`getNextFragment(bufferEnd: ${t}) => no more frags, but we should have found an end fragment, setting hasMore to false`), this.hasMore$.next(!1)), { + frag: l + } + } + nextFragment(e, t, i, r) { + let n, s; + if (this.isStarted && i !== this.iframeRate && (s = this.iframeClockTimeSeconds, this.stop()), this.isStarted) { + if (n = this.getNextFragment(e, r, i), !n.frag) return; + if (n.frag.discoSeqNum !== this.anchorFrag.discoSeqNum) { + const a = this.iframeClockTimeSeconds; + this.stop(); + const s = this.startClocksAndGetFirstFragment(e, t, i, a, n.frag.discoSeqNum)["newMediaRootTime"]; + n.newMediaRootTime = s + } + } else if (n = this.startClocksAndGetFirstFragment(e, t, i, null != s ? s : r), !n) return; + var r = n["frag"], + r = this.handleNextFrag(e, r); + return Object.assign(Object.assign({}, n), { + frag: r + }) + } + handleNextFrag(e, t) { + const i = Object.assign(Object.assign({}, t), { + iframeMediaStart: NaN, + iframeMediaDuration: NaN + }), + { + mediaAppendClock: r, + iframeClock: n + } = this; + this.iframeClockBounds = Qu.getTimeRangeDictForCC(e, i.discoSeqNum, this.logger); + var s = r.getCurrentTime().seconds, + t = n.timeline.rate; + return ne(i.iframeOriginalStart) || (i.iframeOriginalStart = i.start), i.start = i.iframeMediaStart = s, i.iframeMediaDuration = Math.max(i.duration / Math.abs(t), 1 / this.config.minIframeDuration), this.scaledFragments.push(i), this.isEndFrag(e, i) && this.hasMore$.next(!1), i + } + get hasMore() { + return this.hasMore$.value + } + handleWaitForMore() { + return this.isStarted ? (this.iframeClock.getCurrentTime(), Gu(this.hasMore$, e => !0 === e).pipe(Za(() => {}))) : Wu + } + isEndFrag(e, t) { + var i = e[0], + r = e[e.length - 1], + e = this.iframeClock.forward; + return !e && (null == i ? void 0 : i.mediaSeqNum) === t.mediaSeqNum || e && (null == r ? void 0 : r.mediaSeqNum) === t.mediaSeqNum + } + } + + function ec(e, t) { + for (var i = 0; i < t.length; i++) { + var r = t[i]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) + } + } + + function tc(t) { + return function(e) { + return e.lift(new nc(t)) + } + } + var ic, rc, nc = (ec(sc.prototype, [{ + key: "call", + value: function(e, t) { + return t.subscribe(e) + } + }]), sc); + + function sc(e) { + ! function(e) { + if (!(e instanceof sc)) throw new TypeError("Cannot call a class as a function") + }(this), "tag" in this ? Object.defineProperty(this, "tag", { + value: void 0, + enumerable: !0, + configurable: !0, + writable: !0 + }) : this.tag = void 0, this.tag = e + } + + function ac(e) { + const { + method: t, + isEncrypted: i, + uri: r, + format: n, + formatversions: s + } = e, a = { + method: t, + isEncrypted: i, + uri: r, + format: n, + formatversions: s, + iv: e.ivBuf ? new Uint8Array(e.ivBuf) : null + }; + return e.keyIdBuf && (a.keyId = new Uint8Array(e.keyIdBuf)), e.keyBuf && (a.key = new Uint8Array(e.keyBuf)), e.psshBuf && (a.pssh = new Uint8Array(e.psshBuf)), a + }(iu = ic = ic || {}).MustRequestResponse = "MustRequestResponse", iu.WaitingForKeyResponse = "WaitingForKeyResponse", iu.GotKeyResponse = "GotKeyResponse"; + class oc extends Error { + constructor(e, t) { + super(e), this.code = t + } + } + class lc extends p { + constructor(e, t, i, r, n, s) { + super(o, e, t, i, n), this.code = r, this.isTimeout = s, this.response = n + } + } + class dc extends lc { + constructor(e, t, i, r, n) { + super(n ? "manifestLoadTimeOut" : "manifestLoadError", e, t, i, r, n) + } + } + class uc extends lc { + constructor(e, t, i, r, n, s, a, o) { + switch (super("", e, t, i, r, n), this.mediaOptionType = s, this.mediaOptionId = a, this.url = o, s) { + case gu.Variant: + this.details = n ? "levelLoadTimeOut" : N; + break; + case gu.AltAudio: + this.details = n ? "audioTrackLoadTimeOut" : "audioTrackLoadError"; + break; + case gu.Subtitle: + this.details = n ? "subtitleTrackLoadTimeout" : "subtitleTrackLoadError" + } + } + } + class cc extends lc { + constructor(e, t, i, r) { + super("sessionDataLoadError", e, t, i, r, !1) + } + } + class hc extends lc { + constructor(e, t, i, r, n, s, a) { + super(n ? "fragLoadTimeOut" : "fragLoadError", e, t, i, r, n), this.mediaOptionId = s.mediaOptionId, this.mediaOptionType = s.mediaOptionType, this.stats = a + } + } + class pc extends dr { + constructor(e, t, i) { + super(), this.message = e, this.code = t, this.stats = i + } + } + class fc extends lc { + constructor(e, t, i) { + super("fragAbortError", !1, "Fragment abort", 0, i, !1), this.candidateMediaOptionId = t, this.mediaOptionId = e.mediaOptionId, this.mediaOptionType = e.mediaOptionType + } + } + class mc extends lc { + constructor(e, t, i, r = []) { + super("keyLoadTimeOut", !1, e, i.code, i, !0), this.keyuri = t, this.response = i, this.mediaOptionIds = r + } + }(ru = rc = rc || {})[ru.InvalidState = 0] = "InvalidState", ru[ru.Abort = 1] = "Abort", ru[ru.OutputRestricted = 2] = "OutputRestricted", ru[ru.AlreadyFailedKey = 3] = "AlreadyFailedKey", ru[ru.HttpError = 4] = "HttpError", ru[ru.InternalError = 5] = "InternalError", ru[ru.LicenseServerError = 6] = "LicenseServerError", ru[ru.InsufficientCPC = 7] = "InsufficientCPC"; + class gc extends lc { + constructor(e, t, i, r, n, s, a = !1, o = []) { + super("keyLoadError", a, e, i, r, !1), this.keyuri = t, this.isOkToRetry = n, this.keyErrorReason = s, this.mediaOptionIds = o + } + } + class yc extends p { + constructor(e, t, i, r, n) { + super(s, "keySystemGenericError", !0, e, r), this.keyuri = t, this.code = i, this.response = r, this.keysystemstring = n + } + } + + function vc(e, t) { + return e instanceof gc ? new gc(e.message, e.keyuri, e.code, e.response, e.isOkToRetry, e.keyErrorReason, e.fatal, t) : e instanceof mc ? new mc(e.message, e.keyuri, $.CryptResponseReceivedSlowly, t) : e ? new V(e.fatal, e.reason, $.InternalError) : null + } + const Sc = { + id: "fairplaystreaming", + systemStringPrefix: "com.apple.fps", + keyFormatString: "com.apple.streamingkeydelivery", + securityLevels: { + AppleBaseline: 0, + AppleMain: 1, + Main: 1, + Baseline: 0 + } + }; + class bc extends kl { + constructor(e) { + super(e), this.store = e + } + get unresolvedUriLoading$() { + return this.selectEntityAction(Eo.Add).pipe(hr(e => e.map(e => this.getEntity(e)))) + } + } + class Tc { + constructor(e) { + this.store = e + } + createUnresolvedUriLoading(e, t, i) { + Do("loader.create.unresolvedUriLoading"), this.store.add({ + uri: e, + responseType: t, + userAgent: i + }) + } + removeUnresolvedUriLoading(e) { + Do("loader.remove.unresolvedUriLoading"), this.store.remove(e) + } + } + const Ec = new class extends fl { + constructor() { + super({}, { + name: "loader", + producerFn: su, + idKey: "uri" + }) + } + }; + let Ic = null; + class wc extends t { + trigger(e, t) { + try { + this.emit(e, e, t), "hlsFragLoadProgress" !== e.toString() && ("hlsInternalError" !== e && "hlsError" !== e || !t.length || JSON.stringify(t[0], ["fatal", "details", "reason"]), e.toString()) + } catch (t) { + Qe().warn(`error in event listener for ${e}: ${t.message}`) + } + } + } + class Ac { + constructor(e, t) { + this.target = e, this._this = t + } + eventWithOptions(e, t, i, r = this._this) { + let n = rn(this.target, e, t); + return this.target instanceof wc && (n = n.pipe(hr(([, e]) => e))), i && (r && (i = i.bind(r)), n = n.pipe(Za(i))), n + } + event(e, t, i = this._this) { + return this.eventWithOptions(e, void 0, t, i) + } + listen(e, t, i, r = this._this) { + return this.event(e, i, r).pipe(Va(t)).subscribe() + } + } + + function Oc(e, t) { + return new Ac(e, t) + } + + function kc(e, t, i) { + var r; + return { + currentTarget: null !== (r = null == i ? void 0 : i.currentTarget) && void 0 !== r ? r : e, + target: null !== (i = null == i ? void 0 : i.target) && void 0 !== i ? i : e, + type: t + } + } + + function Cc(y, v) { + return new $t(e => { + const { + maxTimeToFirstByteMs: t, + maxLoadTimeMs: i + } = v, r = new XMLHttpRequest, n = { + trequest: performance.now(), + tfirst: NaN, + tload: NaN, + loaded: 0, + total: NaN, + complete: !1 + }, s = Oc(r), a = s.event("progress").pipe(Aa(), ao(300, Ti, { + leading: !0, + trailing: !0 + }), hr(e => (isNaN(n.tfirst) && (n.tfirst = performance.now()), n.loaded = e.loaded, e.lengthComputable && (n.total = e.total), e.target)), ln(e => 3 <= e.readyState)), o = s.event("readystatechange").pipe(Aa(), hr(e => e.target), ln(e => 2 <= e.readyState), Za(e => { + isNaN(n.tfirst) && 3 <= e.readyState && (n.tfirst = performance.now()) + })); + let l = Ii; + isFinite(t) && 0 < t && (l = an(a, o).pipe(Ds(1), So(0 < y.extendMaxTTFB ? y.extendMaxTTFB : t), La(() => Ii))); + let d = Ii; + isFinite(i) && 0 < i && (d = o.pipe(ln(e => 4 <= e.readyState), Ds(1), So(i), La(() => Ii))); + let u = Ii; + y.onProgress && (u = an($i(r), a).pipe(hr(e => { + const { + getData: t, + cb: i + } = y.onProgress; + return i(y.url, e.status, n, t ? e.response : void 0) + }), Wa(e => !e, !0)).pipe($a(Ii))); + const c = an(a.pipe(La(() => Ii)), o, l, d, u).pipe(ln(e => 4 <= e.readyState), Ds(1), La(e => { + if (n.complete = !0, 200 <= e.status && e.status < 300) { + if (n.tload = performance.now(), n.contentType = e.getResponseHeader("Content-Type"), v.reportCDNServer && (n.cdnServer = e.getResponseHeader("CDN-Server")), n.contentLength = v.forceContentLenCheckIfNoHeader ? function(e) { + let t; + const i = e.getResponseHeader("Content-Encoding"), + r = e.getResponseHeader("Transfer-Encoding"), + n = !i || i && "identity" === i.toLowerCase(), + s = !r || r && "identity" === r.toLowerCase(); + return n && s && (t = function(e) { + e = /([0-9]+)\-([0-9]+)\/([0-9]+)/.exec(e); + return e ? parseInt(e[2]) - parseInt(e[1]) + 1 : void 0 + }(e.getResponseHeader("Content-Range")), ne(t) || (t = parseInt(e.getResponseHeader("Content-Length")))), t + }(e) : null, i = e, (r = y).collectServerInstanceInfo && (r.serverInstanceInfo = {}, r.collectServerInstanceInfo.forEach(e => { + var t = i.getResponseHeader(e); + t && (r.serverInstanceInfo[e] = t) + })), "arraybuffer" === y.responseType ? n.loaded = e.response.byteLength : n.loaded = e.responseText.length, n.total = n.loaded, y.checkContentLength && (0 === n.total || ne(n.contentLength) && n.total != n.contentLength)) throw new oc("Network error", e.status); + return Nr($i([e, n]), Ti) + } + var i, r; + throw new oc("Network error", e.status) + }), Vn(e => { + if (e instanceof dr) throw new pc(e.message, 0, n); + if (!(e instanceof oc)) throw new oc(e.message, 0); + throw e + })).subscribe(e), + { + url: h, + method: p, + byteRangeOffset: f, + responseType: m, + body: g + } = y; + y.mimeType && r.overrideMimeType(y.mimeType); + try { + const v = y.xhrSetup; + if (v) try { + v(r, h) + } catch (e) { + r.open(p, y.url, !0), v(r, y.url) + } + r.readyState || r.open(p, y.url, !0) + } catch (e) { + throw new oc(e.message, r.status) + } + if (r.responseType = m, f && ne(f.start) && ne(f.end) && 0 <= f.start && f.end > f.start) { + const { + start: y, + end: v + } = f; + r.setRequestHeader("Range", `bytes=${y}-${v-1}`) + } + if (y.headers) + for (const [v, e] of Object.entries(y.headers)) r.setRequestHeader(v, e); + return "POST" === p && g ? r.send(g) : r.send(), () => { + r.abort(), c.unsubscribe() + } + }) + } + const Dc = { + name: "CustomUrlLoader" + }; + class Mc { + constructor(e) { + this.loaderService = e, this.requestMap = {}, this.logger = Qe() + } + load(a, o) { + return new $t(e => { + const t = a.url, + i = o["maxTimeToFirstByteMs"], + r = { + trequest: performance.now(), + tfirst: NaN, + tload: NaN, + loaded: 0, + total: NaN, + complete: !1 + }, + n = (this.requestMap[t] = new er).pipe(So(0 < a.extendMaxTTFB ? a.extendMaxTTFB : i), La(e => (r.tfirst = performance.now(), this.handleExternalResponse(e, a, o, r))), Vn(e => { + if (e instanceof dr) throw new pc(e.message, 0, r); + throw e + }), Vs(() => { + this.requestMap[t] = void 0, this.loaderService.removeUnresolvedUriLoading(t) + })); + a.onProgress && a.onProgress.cb(t, 0, r, void 0); + const s = n.subscribe(e); + return this.loaderService.createUnresolvedUriLoading(t, a.responseType, navigator.userAgent), () => { + s.unsubscribe(), this.requestMap[t] = void 0 + } + }) + } + setCustomUrlResponse(e, t) { + const i = this.requestMap[e]; + i && (i.next(t), i.complete(), this.requestMap[e] = void 0) + } + handleExternalResponse(e, t, i, r) { + r.tload = performance.now(); + var n = e.response.status || 200; + return 200 <= n && n < 300 ? ("arraybuffer" === t.responseType && e.response.data instanceof ArrayBuffer ? r.loaded = e.response.data.byteLength : r.loaded = e.response.data.toString().length, r.total = r.loaded, r.complete = !0, Nr($i({ + status: n, + data: e, + stats: r + }), Ti)) : 300 === n || 302 === n || 303 === n || 305 === n ? this.redirectRequest(e.response.uri, t, i, r) : (this.logger.warn(Dc, `unable to load custom url > uri=${le(e.response.uri)}, status=${n}`), Vi(new oc("Unable to load custom url", n))) + } + redirectRequest(e, t, i, n) { + var { + maxLoadTimeMs: r, + maxTimeToFirstByteMs: s + } = i, r = r - (performance.now() - n.trequest), s = 0 < t.extendMaxTTFB ? t.extendMaxTTFB : s - (performance.now() - n.trequest), i = Object.assign(Object.assign({}, i), { + maxLoadTimeMs: r, + maxTimeToFirstByteMs: s + }), e = Object.assign(Object.assign({}, t), { + url: e + }); + return r <= 0 || s <= 0 ? Vi(new dr) : Cc(e, i).pipe(hr(([e, t]) => { + var { + responseURL: i, + status: r + } = e, i = i || "", i = { + uri: i, + response: { + status: r, + uri: i, + data: e.response + } + }; + return n.loaded = n.total = t.loaded, n.tload = performance.now(), n.complete = !0, { + status: e.status, + data: i, + stats: n + } + })) + } + } + let xc; + + function Pc(e) { + return xc || (e = e || (Ic = Ic || new Tc(Ec), Ic), xc = new Mc(e)), xc + } + + function Rc(e, t) { + const i = Object.assign(Object.assign({}, e), { + method: "GET", + responseType: "arraybuffer" + }), + r = Pc(); + return Tu(i.url) ? r.load(i, t).pipe(hr(e => [e.data.response.data, e.stats, i.serverInstanceInfo])) : Cc(i, t).pipe(hr(([e, t]) => [e.response, t, i.serverInstanceInfo])) + } + + function Lc(e, t) { + return !e.url || Tu(e.url) ? t.customURL : t.default + } + + function _c(e, t) { + return e instanceof lc ? e.isTimeout ? t.timeoutRetry : t.errorRetry : null + } + + function Nc(e) { + var t = e.type, + i = e.liveOrEvent; + let r = "VOD"; + "EVENT" === t && i ? r = "EVENT" : t && 0 !== t.length && "LIVE" !== t || !i || (r = "LIVE"), e.type !== r && (e.type = r) + } + const Fc = { + id: "playready", + systemStringPrefix: "com.microsoft.playready", + keyFormatString: "com.microsoft.playready", + securityLevels: { + SL2000: 0, + SL3000: 1 + } + }, + Bc = { + id: "widevine", + systemStringPrefix: "com.widevine.alpha", + keyFormatString: "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed", + securityLevels: { + WIDEVINE_SOFTWARE: 0, + WIDEVINE_HARDWARE: 1 + } + }; + + function Uc(e) { + return e.replace(/\+/g, "-").replace(/\//g, "_").replace(/\=+$/, "") + } + class $c { + static strToBase64Encode(e) { + return btoa(e) + } + static base64DecodeToStr(e) { + return atob(e) + } + static base64Encode(e) { + return btoa(String.fromCharCode(...e)) + } + static base64UrlEncode(e) { + return Uc($c.base64Encode(e)) + } + static base64Decode(e) { + return Uint8Array.from(atob(e), e => e.charCodeAt(0)) + } + } + class Vc { + static strToBase64Encode(e) { + return l.Buffer.from(e).toString("base64") + } + static base64DecodeToStr(e) { + return l.Buffer.from(e, "base64").toString() + } + static base64Encode(e) { + return l.Buffer.from(e).toString("base64") + } + static base64UrlEncode(e) { + return Uc(Vc.base64Encode(e)) + } + static base64Decode(e) { + e = l.Buffer.from(e, "base64"); + return new Uint8Array(e.buffer, e.byteOffset, e.byteLength) + } + } + var Kc, qc = void 0 !== l.Buffer ? Vc : $c; + const Hc = { + avc1: "video/mp4", + avc3: "video/mp4", + dvav: "video/mp4", + dva1: "video/mp4", + hev1: "video/mp4", + hvc1: "video/mp4", + dvh1: "video/mp4", + dvhe: "video/mp4" + }, + jc = { + mp4a: "audio/mp4", + "ac-3": "audio/mp4", + "ec-3": "audio/mp4" + }; + + function Qc(e) { + const t = O.strToUtf8array(e).subarray(0, 16), + i = new Uint8Array(16); + return i.set(t, 16 - t.length), i + } + const Wc = { + getCapabilities: function(e, t) { + const i = { + videoCapabilities: [], + audioCapabilities: [] + }; + return e && e.forEach(e => { + var t = e.split(".")[0].trim(); + t in Hc && i.videoCapabilities.push({ + contentType: Hc[t] + ";codecs=" + e, + robustness: "" + }) + }), t && t.forEach(e => { + var t = e.split(".")[0].trim(); + t in jc && i.audioCapabilities.push({ + contentType: jc[t] + ";codecs=" + e, + robustness: "" + }) + }), i + }, + changeEndianness: function(e) { + function t(e, t, i) { + var r = e[t]; + e[t] = e[i], e[i] = r + } + t(e, 0, 3), t(e, 1, 2), t(e, 4, 5), t(e, 6, 7) + }, + getKeyIdBytes: Qc, + convertDataUriToArrayBytes: function(e) { + const t = e.split(":"); + let i = null; + if ("data" === t[0] && 2 === t.length) { + const e = t[1].split(";"), + r = e[e.length - 1].split(","); + if (2 === r.length) { + const t = "base64" === r[0], + n = r[1]; + i = t ? (e.splice(-1, 1), qc.base64Decode(n)) : Qc(n) + } + } + return i + }, + makeKeyIdsInitData: function(e) { + e = { + kids: e.map(qc.base64UrlEncode) + }; + return O.strToUtf8array(JSON.stringify(e)) + }, + parsePSSHList: function(e) { + const i = new DataView(e); + let r = 0; + const n = {}; + for (; r < i.buffer.byteLength;) { + const e = r, + t = i.getUint32(r); + r += 4; + var s = e + t; + if (1886614376 === i.getUint32(r)) { + switch (r += 4, i.getUint8(r)) { + case 0: + case 1: + r += 1; + break; + default: + r = s + } + r += 3; + let t = ""; + for (let e = 0; e < 16; ++e, ++r) switch (t += i.getUint8(r).toString(16), e) { + case 4: + case 6: + case 8: + case 10: + t += "-" + } + r += 4, n[t] = i.buffer.slice(e, s) + } else r = s + } + return n + } + }; + let Gc = {}; + class zc { + constructor(e, t, i, r, n) { + if (this.method = e, this.uri = t, this.iv = i, this.format = r, this.formatversions = n, this.isEncrypted = this.method && "NONE" !== this.method, this.formatversions && 0 !== this.formatversions.length || (this.formatversions = [1]), this.key = void 0, this.keyId = void 0, this.isEncrypted) { + const a = Wc.convertDataUriToArrayBytes(this.uri); + if (a) switch (r) { + case Fc.keyFormatString: { + this.pssh = a; + const e = new Uint16Array(a.buffer, a.byteOffset, a.byteLength / 2), + t = String.fromCharCode.apply(null, Array.from(e)), + i = t.substring(t.indexOf("<"), t.length), + r = (new DOMParser).parseFromString(i, "text/xml").getElementsByTagName("KID")[0]; + if (r) { + var s = null; + if (s = r.childNodes[0] ? r.childNodes[0].nodeValue : r.getAttribute("VALUE")) { + const t = qc.base64Decode(s).subarray(0, 16); + Wc.changeEndianness(t), this.keyId = t + } + } + break + } + case Bc.keyFormatString: + this.pssh = a, 22 <= a.length && (this.keyId = a.subarray(a.length - 22, a.length - 6)); + break; + default: { + let e = a.subarray(0, 16); + if (16 !== e.length) { + const t = new Uint8Array(16); + t.set(e, 16 - e.length), e = t + } + this.keyId = e; + break + } + } + if (!this.keyId || 16 !== this.keyId.byteLength) { + let e = Gc[this.uri]; + if (!e) { + const t = Object.keys(Gc).length % Number.MAX_SAFE_INTEGER; + e = new Uint8Array(16), new DataView(e.buffer, 12, 4).setUint32(0, t), Gc[this.uri] = e + } + this.keyId = e + } + } + } + get keyTagInfo() { + var { + method: e, + isEncrypted: t, + uri: i, + iv: r, + keyId: n, + key: s, + format: a, + formatversions: o + } = this; + return { + method: e, + isEncrypted: t, + uri: i, + iv: r, + keyId: n, + key: s, + format: a, + formatversions: o + } + } + static clearKeyUriToKeyIdMap() { + Gc = {} + } + }(w = Kc = Kc || {}).NONE = "NONE", w.GET_REQUEST_INFO = "GET_REQUEST_INFO", w.GET_CHALLENGE = "GET_CHALLENGE", w.GET_KEY_RESPONSE = "GET_KEY_RESPONSE", w.PROCESS_LICENSE = "PROCESS_LICENSE"; + class Xc { + constructor(e, t, i, r) { + this.session = e, this.onkeystatuseschange = t, this.onkeymessage = i, this.logger = r, this.isClosing$ = new yi(!1), this.closed$ = new yi(!1); + const n = Oc(this.session); + n.listen("keystatuseschange", this.isClosing$.pipe(ln(e => !0 === e)), this.onkeystatuseschange), n.listen("message", this.closed$.pipe(ln(e => !0 === e)), this.onkeymessage) + } + get isClosing() { + return this.isClosing$.value + } + get isClosed() { + return this.closed$.value + } + destroy() { + this.isClosing$.next(!0); + const e = this.session; + return Fr(e.remove().catch(e => {}).then(() => e.close()).catch(e => {})).pipe(Za(() => { + this.isClosing$.next(!1), this.closed$.next(!0) + }), Vs(() => { + this.isClosing$.next(!1), this.closed$.next(!0) + })) + } + } + class Yc { + constructor(e, t = null) { + this.decryptdata = e, this._requestState$ = new yi(Kc.NONE), this.destroy$ = new Xt, this.currentObservable = null, this.session = null, this.oldSessions = [], this.session = t + } + get requestState() { + return this._requestState$.value + } + get onKeyRequestState$() { + return this._requestState$ + } + destroy() { + this.destroy$.next() + } + abort() { + var e; + this.requestState !== Kc.NONE && (e = new gc("Aborted", this.decryptdata.uri, 0, $.KeySystemAbort, !0, rc.Abort), this.error(e)) + } + setKeyRequestState(e) { + if (this.currentObservable) { + const t = new gc(`Unexpected state transition ${this.requestState}->${e}`, this.decryptdata.uri, 0, $.KeySystemUnexpectedStateTransition, !0, rc.InvalidState); + this.error(t) + } + this._requestState$.next(e); + const t = new er; + return e === Kc.NONE ? (t.complete(), this.currentObservable = null) : this.currentObservable = t, t + } + resolveState(e, t) { + if (this.currentObservable) + if (e === this.requestState) + if (t instanceof Error) this.error(t); + else { + const e = this.currentObservable; + this.currentObservable = null, e.next(t), e.complete() + } + else { + const t = new gc(`Unexpected state ${this.requestState} != ${e}`, this.decryptdata.uri, 0, $.KeySystemUnexpectedState, !0, rc.InvalidState); + this.error(t) + } + } + error(e) { + if (this.currentObservable) { + const t = this.currentObservable; + this.currentObservable = null, t.error(e) + } + this.setKeyRequestState(Kc.NONE) + } + } + + function Jc(e) { + return `uri=${le(e.uri)} keyId=${je(e.keyId)}` + } + class Zc { + constructor(e, t, i, r, n, s, a) { + this.mediaKeys = e, this.systemString = t, this.config = i, this.eventEmitter = r, this.useSingleKeySession = n, this.sessionHandler = s, this.logger = a, this.destroy$ = new Xt, this.setCert = !1, this.certificate$ = new yi(null), this._keyStatusChange$ = new Xt, this.shouldDestroyMediaKeys = !1, this.itemId = "", this.sessions = [], this.keyIdToKeyInfo = {}, this.keyUriToKeyInfo = {}, this.sessionIdToKeyUri = {}, this.onkeystatuseschange = this.handleKeyStatusesChange.bind(this), this.onkeymessage = this.handleKeyMessage.bind(this) + } + get keyStatusChange$() { + return this._keyStatusChange$ + } + destroy() { + this.isDestroying = !0, this.destroy$.next(); + for (const e of Object.values(this.keyIdToKeyInfo)) this._abortKeyRequest(e); + const e = this.sessions.map(e => e.destroy()), + t = nn(() => 0 === e.length, Wu, en(e)).pipe(Zs(void 0), Vs(() => { + this.mediaKeys = void 0, this.keyIdToKeyInfo = {}, this.keyUriToKeyInfo = {}, this.sessionIdToKeyUri = {} + })); + return zc.clearKeyUriToKeyIdMap(), t + } + setServerCertificate(e = null) { + return this.needsCert ? (e && this.certificate$.next(e), Gu(this.certificate$, e => null != e).pipe(So(1e4)).pipe(La(e => this.setCert ? $i(!0) : !this.setCertSubject || this.setCertSubject.isStopped ? (this.setCertSubject = new er, Fr(this.mediaKeys.setServerCertificate(e)).pipe(Za(e => { + e = void 0 === e || e; + this.setCert = e, this.setCertSubject.next(e), this.setCertSubject.complete() + }), Vn(e => (this.setCert = !1, this.setCertSubject.error(e), Wu)), La(() => this.setCertSubject))) : this.setCertSubject), Vn(e => { + throw e + }))) : $i(!0) + } + ensureKeyContext(e) { + var t = e.uri; + this.keyUriToKeyInfo[t] || (this.keyUriToKeyInfo[t] = new Yc(e)); + const i = this.keyUriToKeyInfo[t]; + if (i.session) return i; + if (this.useSingleKeySession && 0 < this.sessions.length) return i.session = this.sessions[0].session, i; + t = this.mediaKeys.createSession(); + return t && this.sessions.push(new Xc(t, this.onkeystatuseschange, this.onkeymessage, this.logger)), i.session = t, i + } + startKeyRequest(t) { + const i = t.uri, + r = this.ensureKeyContext(t); + if (null == r || !r.session) return Vi(new yc("Could not create key session", t.uri, 0, $.KeySystemFailedToCreateSession, this.systemString)); + var e = O.utf8arrayToStr(t.keyId); + return this.keyIdToKeyInfo[e] = r, en([this.getKeyRequestInfo(r), this.setServerCertificate()]).pipe(hr(e => e[0]), La(e => { + var t; + return null === (t = this.sessionHandler) || void 0 === t || t.licenseChallengeSubmitted({ + keyuri: i, + keyFormat: this.systemString + }), this.generateLicenseChallenge(r, e).pipe(Vn(e => { + var t; + throw null === (t = this.sessionHandler) || void 0 === t || t.licenseChallengeError({ + keyuri: i + }), e + })) + }), La(e => { + var t; + return null === (t = this.sessionHandler) || void 0 === t || t.licenseChallengeCreated({ + keyuri: i, + cdmVersion: this.cdmVersion + }), this.getKeyRequestResponse(r, e) + }), La(e => { + var t; + return null === (t = this.sessionHandler) || void 0 === t || t.licenseResponseSubmitted({ + keyuri: i + }), this.handleParsedKeyResponse(r, e).pipe(Vn(e => { + var t; + throw null === (t = this.sessionHandler) || void 0 === t || t.licenseResponseError({ + keyuri: i + }), e + })) + }), hr(() => { + var e; + return null === (e = this.sessionHandler) || void 0 === e || e.licenseResponseProcessed({ + keyuri: i + }), r.setKeyRequestState(Kc.NONE), this.removeSessions(r.decryptdata, !1).subscribe(), t + }), Vn(e => { + throw this.handleKeyExchangeError(r, e), e + }), Vs(() => { + this._abortKeyRequest(r) + })) + } + _abortKeyRequest(e) { + var t, i; + e && (i = e.decryptdata.uri, O.utf8arrayToStr(e.decryptdata.keyId), e.requestState !== Kc.NONE && (null === (t = this.sessionHandler) || void 0 === t || t.keyAborted({ + keyuri: i + })), e.abort()) + } + handleKeyExchangeError(e, t) { + e.error(t), O.utf8arrayToStr(e.decryptdata.keyId) + } + updateItemId(e) { + this.itemId = e + } + removeKey(e) { + return this.removeKeyInternal(e) + } + removeKeyInternal(e) { + const t = this.keyUriToKeyInfo[e.uri]; + if (t && t.session) { + var i = t.session; + t.abort(), t.destroy(); + var r = O.utf8arrayToStr(e.keyId); + return this.keyIdToKeyInfo[r] = void 0, this.keyUriToKeyInfo[e.uri] = void 0, this.removeSession(i) + } + } + removeSessions(e, t) { + const i = this.keyUriToKeyInfo[e.uri]; + if (i) { + const r = i.oldSessions.map(e => this.removeSession(e)); + return i.oldSessions = [], nn(() => 0 === r.length, Wu, en(r)).pipe(La(() => t ? this.removeKeyInternal(e) : Wu)) + } + return Wu + } + removeSession(t) { + const e = this.sessions.findIndex(e => e.session === t), + i = this.sessions[e]; + return -1 < e && this.sessions.splice(e, 1), this.sessionIdToKeyUri[t.sessionId] = void 0, i ? i.destroy() : Wu + } + getKeyRequestInfo(e) { + var t = e.decryptdata, + i = t.uri, + e = e.setKeyRequestState(Kc.GET_REQUEST_INFO); + return this.eventEmitter.trigger(x.KEY_REQUEST_STARTED, { + keyuri: i, + decryptdata: t, + timestamp: Date.now() + }), e + } + setKeyRequestInfo(e, t) { + const i = this.keyUriToKeyInfo[e]; + i && i.resolveState(Kc.GET_REQUEST_INFO, t) + } + sanitizeRequest(e) { + return e + } + generateLicenseChallengeInternal(t, e, i) { + const r = t.decryptdata, + n = t.session, + s = r.uri, + a = r.keyId; + let o; + var l = t.setKeyRequestState(Kc.GET_CHALLENGE); + if (n.generateRequestPromise) o = Nr(n.generateRequestPromise, Ti).pipe(La(() => this.generateRequestInitialized(t, "usable" === i))); + else { + const i = this.generateInitData(a, r, e); + n.generateRequestPromise = n.generateRequest(i.initDataType, i.initData), o = Nr(n.generateRequestPromise, Ti).pipe(Za(() => { + this.sessionIdToKeyUri[n.sessionId] = s + }), Vn(e => { + throw new yc(e.message, t.decryptdata.uri, 0, $.KeySystemFailedToGenerateLicenseRequest, this.systemString) + })) + } + return en([l, o]).pipe(hr(e => new Uint8Array(e[0]))) + } + generateLicenseChallenge(e, t) { + const i = e.decryptdata, + r = e.session, + n = i.uri, + s = i.keyId; + let a, o; + if (O.utf8arrayToStr(i.keyId), e.licenseChallenge && e.resolveState(Kc.GET_CHALLENGE, e.licenseChallenge), t = this.sanitizeRequest(t), e.requestInfo = t, this.sessionId = this.sessionId || t && t.sessionId || this.itemId, this.systemString === Fc.systemStringPrefix) { + const e = new Uint8Array(s); + Wc.changeEndianness(e), a = r.keyStatuses.get(e) + } else a = r.keyStatuses.get(s); + switch (a) { + case "status-pending": + case "usable": + case "expired": + case void 0: + o = this.generateLicenseChallengeInternal(e, t, a); + break; + default: + o = Vi(new yc(`Bad internal state state=${a}`, n, 0, $.KeySystemUnexpectedState, this.systemString)) + } + return o + } + setParsedResponse(e, t) { + const i = this.keyUriToKeyInfo[e]; + i && i.resolveState(Kc.GET_KEY_RESPONSE, t) + } + handleKeyStatusesChange(e) { + e.target.keyStatuses.forEach((e, t, i) => { + t = new Uint8Array(t); + this.systemString === Fc.systemStringPrefix && Wc.changeEndianness(t); + t = O.utf8arrayToStr(t), t = this.keyIdToKeyInfo[t]; + t && this.handleKeyStatusForKey(e, t) + }) + } + handleKeyStatusForKey(e, t) { + if (t) { + var i = t.decryptdata, + r = i.uri; + switch (e) { + case "internal-error": + this.logger.error(`${this.systemString} internal-error for key ${Jc(i)}`), this._signalError(t, new gc("Got internal error from key system", r, 0, $.KeySystemInternalError, !1, rc.InternalError)); + break; + case "usable": + t.requestState === Kc.PROCESS_LICENSE && t.resolveState(Kc.PROCESS_LICENSE, void 0); + break; + case "output-restricted": + this.logger.warn(`${this.systemString} output-restricted for key ${Jc(i)}`), t.session && this.removeSession(t.session).pipe(Va(this.destroy$)).subscribe(), this._signalError(t, new gc("output-restricted", r, 0, $.KeySystemOutputRestricted, !1, rc.OutputRestricted)); + break; + case "expired": + this.logger.warn(`${this.systemString} expired for key ${Jc(i)}. Attempting renewal`), this._signalRenewal(t) + } + } + } + _scheduleRenewal(e, t) { + bn(t).pipe(Za(() => this._signalRenewal(e)), Va(fn(e.destroy$, this.destroy$, Gu(e.onKeyRequestState$, e => e === Kc.GET_REQUEST_INFO)))).subscribe() + } + _signalRenewal(e) { + this._keyStatusChange$.next({ + decryptdata: e.decryptdata, + status: "needs-renewal" + }) + } + _signalError(e, t) { + this._keyStatusChange$.next({ + decryptdata: e.decryptdata, + status: "error", + error: t + }), e.error(t) + } + } + const eh = "org.w3.clearkey", + th = { + id: "clearkey", + systemStringPrefix: eh, + keyFormatString: eh, + securityLevels: { + NONE: 0 + } + }, + ih = ["clearkey", "fairplaystreaming", "playready", "widevine"], + rh = { + initDataTypes: ["keyids", "cenc"] + }; + var nh, nu = class extends Zc { + constructor(e, t, i, r, n, s) { + super(e, t, i, r, !1, n, s) + } + static get requestAccessConfig() { + return rh + } + get needsCert() { + return !1 + } + getKeyRequestResponse(e, t) { + return Rc({ + url: e.decryptdata.uri, + xhrSetup: this.config.xhrSetup + }, { + maxLoadTimeMs: 0, + maxTimeToFirstByteMs: 0, + autoRetry: !1, + timeoutRetry: null, + errorRetry: null + }).pipe(hr(([e]) => { + e = new Uint8Array(e); + return { + response: this.parseResponse(t, e) + } + })) + } + parseResponse(e, t) { + t = { + kty: "oct", + kid: qc.base64UrlEncode(e), + k: qc.base64UrlEncode(t) + }; + return O.strToUtf8array(JSON.stringify({ + keys: [t] + })) + } + handleParsedKeyResponse(i, e) { + e = e.response; + return en([i.setKeyRequestState(Kc.PROCESS_LICENSE), Fr(i.session.update(e)).pipe(Za(() => { + var e = i.decryptdata.keyId, + e = i.session.keyStatuses.get(e); + this.handleKeyStatusForKey(e, i) + }), Vn(e => { + var t = { + code: e.code, + text: "Failed to update with key response" + }; + throw new yc(e.message, i.decryptdata.uri, e.code, t, this.systemString) + }))]).pipe(Zs(void 0)) + } + generateInitData(e) { + return { + initData: Wc.makeKeyIdsInitData([e]), + initDataType: "keyids" + } + } + generateRequestInitialized() { + return Wu + } + sanitizeRequest(e) { + return e + } + handleKeyMessage(e) { + if (!this.isDestroying && "license-request" === e.messageType) { + e = new Uint8Array(e.message), e = JSON.parse(O.utf8arrayToStr(e).trim()); + if (1 === e.kids.length) { + const t = qc.base64Decode(e.kids[0]), + i = O.utf8arrayToStr(t), + r = this.keyIdToKeyInfo[i]; + r && r.resolveState(Kc.GET_CHALLENGE, t) + } + } + } + }; + const sh = { + initDataTypes: ["cenc"] + }, + ah = new Uint8Array([148, 206, 134, 251, 7, 255, 79, 67, 173, 184, 147, 210, 250, 150, 140, 162]); + (iu = nh = nh || {})[iu.CENC = 1667591779] = "CENC", iu[iu.CBCS = 1667392371] = "CBCS"; + class oh extends Zc { + constructor(e, t, i, r, n, s, a) { + super(e, t, i, r, n, s, a), this._hasSetRenewal = !1 + } + static get systemId() { + return ah + } + static get requestAccessConfig() { + return sh + } + get needsCert() { + return !0 + } + sanitizeRequest(e) { + return { + assetId: e && e.assetId ? new Uint8Array(e.assetId) : void 0, + ssc: e && e.ssc ? new Uint8Array(e.ssc) : void 0, + sessionId: e && e.sessionId ? e.sessionId : void 0 + } + } + _scheduleRenewal(e, t) { + this.useSingleKeySession ? this._hasSetRenewal || (this._hasSetRenewal = !0, bn(t).pipe(Za(() => { + var e = Object.values(this.keyUriToKeyInfo)[0]; + e && this._signalRenewal(e) + }), Vs(() => { + this._hasSetRenewal = !1 + }), Va(this.destroy$)).subscribe()) : super._scheduleRenewal(e, t) + } + handleParsedKeyResponse(t, e) { + var i = t.decryptdata.uri, + r = e.statusCode, + n = e.ckc && 0 !== e.ckc.byteLength ? e.ckc : e.license && 0 !== e.license.byteLength ? e.license : void 0; + if (0 === r && !n) return Vi(new gc("License request resulted in HTTP Error", i, r, { + code: r, + text: "HTTP Error" + }, !0, rc.HttpError)); + if (0 !== r) return Vi(new gc("License server responded with error", i, r, { + code: r, + text: "Server Error" + }, !1, rc.LicenseServerError)); + if (!n) return Vi(new gc("License server responded with invalid license", i, r, { + code: r, + text: "Invalid license" + }, !1, rc.LicenseServerError)); + const s = e.renewalDate, + a = new Date, + o = s > a ? s.getTime() - a.getTime() : 0; + 0 < o && this._scheduleRenewal(t, o); + const l = this.makeProcessLicenseRequestMessage(t, n, o), + d = t.session, + u = Fr(d.update(l)).pipe(Za(() => { + var e = t.decryptdata.keyId, + e = d.keyStatuses.get(e); + this.handleKeyStatusForKey(e, t) + }), Vn(e => { + throw new yc(e.message, t.decryptdata.uri, 0, $.KeySystemFailedToUpdateSession, this.systemString) + })); + return en([t.setKeyRequestState(Kc.PROCESS_LICENSE), u]).pipe(Zs(void 0)) + } + makeKeyRequests(e) { + const t = []; + for (const i of e) { + const e = i.decryptdata, + r = i.requestInfo, + n = e.keyId; + t.push({ + keyId: n, + assetId: r ? r.assetId : void 0, + ssc: r ? r.ssc : void 0, + versionList: e.formatversions + }) + } + return t + } + getSchemeAndFlags(e) { + return { + scheme: "ISO-23001-7" === e.method ? nh.CENC : nh.CBCS, + flags: 0 + } + } + generateInitData(e, t, i) { + var { + scheme: r, + flags: n + } = this.getSchemeAndFlags(t), i = this.makeKeyRequests([{ + decryptdata: t, + requestInfo: i + }]); + return { + initData: this.makeFpsKeySystemInitData(r, n, i), + initDataType: "cenc" + } + } + generateRequestInitialized(t, e) { + tc(`[Keys] challenge create start uri=${le(t.decryptdata.uri)} versions=${JSON.stringify(t.decryptdata.formatversions)}`); + e = this.makeKeyRequestMessage(t, e); + return e ? Fr(t.session.update(e)).pipe(Za(() => { + t.requestInfo = void 0 + }), Vn(e => { + throw tc(`[Keys] ${this.systemString} FAIL: generateRequestInitialized keyuri=${le(t.decryptdata.uri)} message=${e.message}`), new yc(e.message, t.decryptdata.uri, 0, $.KeySystemFailedToGenerateLicenseRenewal, this.systemString) + })) : Vi(new gc("Unable to generate request using existing keySession", t.decryptdata.uri, 0, $.KeySystemFailedToGenerateLicenseRequest, !0, rc.InvalidState)) + } + getKeyRequestResponse(e, t) { + var i = e.decryptdata.uri, + e = e.setKeyRequestState(Kc.GET_KEY_RESPONSE); + return this.eventEmitter.trigger(x.LICENSE_CHALLENGE_CREATED, { + keyuri: i, + licenseChallenge: t, + keysystem: this.systemString + }), e + } + resolveSPCPromise(e, t) { + e.resolveState(Kc.GET_CHALLENGE, t) + } + } + const lh = {}, + dh = 1919710053; + + function uh(e, t, i) { + if (!(i + 4 > e.byteLength)) { + t = t.getUint32(i); + if (!((i += 4) + t > e.byteLength)) { + e = e.slice(i, i + t); + return { + pos: i += t, + data: e + } + } + } + } + + function ch(t) { + const i = {}, + r = new DataView(t.buffer); + let n = 4; + const s = r.getUint32(n); + n += 4; + for (let e = 0; e < s && n < t.byteLength && !(n + 16 > t.byteLength); ++e) { + const s = t.slice(n, n + 16); + if (n += 16, n + 4 > t.byteLength) break; + var a = uh(t, r, n); + if (!a) break; + n = a.pos, i[O.utf8arrayToStr(s)] = a.data + } + return i + } + + function hh(e, t, i, r) { + var n = r ? r.byteLength : 0; + return t.setUint32(i, n), n && e.set(r, i + 4), i + (4 + n) + } + + function ph(e) { + let t = 4; + for (const i of e) t += 28 + (i.assetId ? i.assetId.byteLength : 0) + (i.ssc ? i.ssc.byteLength : 0) + (i.versionList ? 4 * i.versionList.length : 0); + return t + } + + function fh(e, t, i, r) { + t.setUint32(i, r.length), i += 4; + for (const n of r) + if (e.set(n.keyId, i), i = hh(e, t, i += 16, n.assetId), i = hh(e, t, i, n.ssc), t.setUint32(i, n.versionList ? n.versionList.length : 0), i += 4, n.versionList) + for (const e of n.versionList) t.setUint32(i, e), i += 4; + return i + } + class mh extends oh { + constructor(e, t, i, r, n, s) { + super(e, t, i, r, void 0 === i.useMultipleKeySessions || !i.useMultipleKeySessions, n, s) + } + makeProcessLicenseRequestMessage(e, t, i) { + t = new Uint8Array(t); + return function(e) { + let t = 0; + for (const i of e) t += 24 + i.ckc.byteLength; + let i = 0; + const r = new Uint8Array(8 + t), + n = new DataView(r.buffer); + n.setUint32(0, 1667982195), n.setUint32(4, e.length), i += 8; + for (const t of e) r.set(t.keyId, i), i += 16, n.setUint32(i, t.expirySec), i += 4, i = hh(r, n, i, t.ckc); + return r + }([{ + keyId: e.decryptdata.keyId, + expirySec: i / 1e3, + ckc: t + }]) + } + makeFpsKeySystemInitData(e, t, i) { + i = function(e, t, i) { + var r = ph(i); + const n = new Uint8Array(8 + r), + s = new DataView(n.buffer); + return s.setUint32(0, e), s.setUint32(4, 1 << 24 | 16777215 & t), fh(n, s, 8, i), n + }(e, t, i); + return ge.pssh(mh.systemId, [], i) + } + makeKeyRequestMessage(e) { + return function(e) { + var t = ph(e); + const i = new Uint8Array(4 + t), + r = new DataView(i.buffer); + return r.setUint32(0, 1668442994), fh(i, r, 4, e), i + }([{ + keyId: e.decryptdata.keyId, + assetId: e.requestInfo ? e.requestInfo.assetId : void 0, + ssc: e.requestInfo ? e.requestInfo.ssc : void 0, + versionList: e.decryptdata.formatversions + }]) + } + handleKeyMessage(e) { + if (e.message.byteLength < 4) this.logger.warn("Unexpected message"); + else { + const t = new Uint8Array(e.message), + i = new DataView(e.message), + r = i.getUint32(0); + if (this.isDestroying && r !== dh) this.logger.warn(`In the middle of destroying, ignore command: ${r.toString(16)}`); + else switch (r) { + case 1667592820: + this.logger.warn("Certificate not set!"); + break; + case 1919837559: { + const e = ch(t); + for (const t in e) + if (Object.prototype.hasOwnProperty.call(e, t)) { + const e = this.keyIdToKeyInfo[t]; + e && this._signalRenewal(e) + } break + } + case 1936745331: { + const e = ch(t); + for (const t in e) + if (Object.prototype.hasOwnProperty.call(e, t)) { + const i = this.keyIdToKeyInfo[t], + r = e[t]; + i && r && this.resolveSPCPromise(i, r) + } break + } + case dh: + this._handleLicenseRelease(t); + break; + case 1667525993: { + const e = uh(t, i, 4); + e && (this.cdmVersion = O.utf8arrayToStr(e.data)); + break + } + default: + this.logger.warn(`Unrecognized command:'0x${r.toString(16)}'`) + } + } + } + _handleLicenseRelease(e) { + const t = {}, + i = new DataView(e.buffer); + switch (i.getUint32(4)) { + case 1936946288: + lh, 0, t[lh.SessionId] = this.sessionId; + var r; + if (e.byteLength < 12) break; + t[lh.APIProvider] = i.getUint32(8) === nh.CENC ? "EC396D13-FB13-4993-9D0D-71518ACF3D6F" : "F19BF03B-7470-41A4-9655-86D078307D59", 0; + var n = uh(e, i, 12); + if (!n) break; + if (r = n.pos, t[lh.MovieID] = O.utf8arrayToStr(n.data), !(n = uh(e, i, r))) break; + if (r = n.pos, t[lh.SecureStopSPC] = n.data, !(n = uh(e, i, r))) break; + n.pos, t[lh.SessionLifespanSPC] = n.data + } + this.eventEmitter.trigger(x.LICENSE_RELEASED, { + keysystem: this.systemString, + itemId: this.itemId, + releaseRecord: t + }) + } + } + ru = mh; + const gh = { + fpsd: O.strToUtf8array("fpsd"), + fpsi: O.strToUtf8array("fpsi"), + fpsk: O.strToUtf8array("fpsk"), + fkri: O.strToUtf8array("fkri"), + fkai: O.strToUtf8array("fkai"), + fkcx: O.strToUtf8array("fkcx"), + fkvl: O.strToUtf8array("fkvl") + }; + t = class extends oh { + constructor(e, t, i, r, n, s) { + super(e, t, i, r, !1, n, s), this.sessions = [], this.keyIdToKeyInfo = {}, this.keyUriToKeyInfo = {}, this.sessionIdToKeyUri = {} + } + static get needsCert() { + return !0 + } + handleKeyExchangeError(e, t) { + this.removeKey(e.decryptdata).subscribe(), super.handleKeyExchangeError(e, t) + } + _abortKeyRequest(e) { + return !this.isDestroying && e && e.requestState !== Kc.NONE && this.removeKey(e.decryptdata).subscribe(), super._abortKeyRequest(e) + } + makeFpsKeySystemInitData(e, t, i) { + const r = [gh.fpsd, (n = e, e = t, t = new Uint8Array(4), ge.set32(n, t, 0), ge.box(gh.fpsi, new Uint8Array([0, e >> 16 & 255, e >> 8 & 255, 255 & e]), t))]; + var n; + for (const s of i) r.push(function(t, e, i, r) { + const n = [gh.fpsk], + s = ge.box(gh.fkri, new Uint8Array([0, 0, 0, 0]), t); + if (n.push(s), e && e.byteLength && n.push(ge.box(gh.fkai, e)), i && i.byteLength && n.push(ge.box(gh.fkcx, i)), r && r.length) { + const t = new Uint8Array(4 * r.length); + let e = 0; + for (const i of r) ge.set32(i, t, e), e += 4; + n.push(ge.box(gh.fkvl, t)) + } + return ge.box.apply(null, n) + }(s.keyId, s.assetId, s.ssc, s.versionList)); + i = ge.box.apply(null, r); + return ge.pssh(oh.systemId, null, i) + } + makeKeyRequestMessage(e, t) { + if (t) return O.strToUtf8array("renew") + } + makeProcessLicenseRequestMessage(e, t, i) { + t = JSON.stringify([{ + keyID: qc.base64Encode(e.decryptdata.keyId), + payload: qc.base64Encode(new Uint8Array(t)) + }]); + return O.strToUtf8array(t) + } + handleKeyMessage(e) { + const t = e.target, + i = t.sessionId, + r = e.messageType, + n = this.sessionIdToKeyUri[i]; + let s; + if (n) s = this.keyUriToKeyInfo[n]; + else + for (const e of Object.values(this.keyUriToKeyInfo)) e && e.session === t && (s = e); + if (s) switch (r) { + case "license-request": { + const t = new Uint8Array(e.message), + i = O.utf8arrayToStr(t); + try { + JSON.parse(i).forEach(e => { + var t = qc.base64DecodeToStr(e.keyID), + e = qc.base64Decode(e.payload), + t = this.keyIdToKeyInfo[t]; + t && this.resolveSPCPromise(t, e) + }) + } catch (e) { + this.logger.warn("[Keys] got unexpected license-request format"), this.resolveSPCPromise(s, t) + } + break + } + case "license-renewal": { + const t = new Uint8Array(e.message); + this.resolveSPCPromise(s, t); + break + } + case "license-release": + this._handleLicenseRelease(t); + break; + default: + this.logger.warn(`[Keys] Unexpected messageType ${r}`) + } else this.logger.warn("[Keys] No key associated with session") + } + _handleLicenseRelease(e) { + e.update(O.strToUtf8array("acknowledged")).catch(e => { + this.logger.error(`Promise error: ${e.message}`) + }) + } + }; + const yh = { + initDataTypes: ["cenc"] + }, + vh = new Uint8Array([154, 4, 240, 121, 152, 64, 66, 134, 171, 146, 230, 91, 224, 136, 95, 149]); + class Sh extends Zc { + constructor(e, t, i, r, n, s) { + super(e, t, i, r, !1, n, s), this.shouldDestroyMediaKeys = !0 + } + static get systemId() { + return vh + } + static get requestAccessConfig() { + return yh + } + get needsCert() { + return !1 + } + generateInitData(e, t) { + t = t.pssh; + return { + initData: ge.pssh(Sh.systemId, [], t), + initDataType: "cenc" + } + } + removeKey(e) { + return super.removeSessions(e, !0) + } + ensureKeyContext(e) { + const t = e.uri, + i = this.keyUriToKeyInfo[t]; + return null != i && i.session && (i.oldSessions.push(i.session), i.session = null), super.ensureKeyContext(e) + } + getKeyRequestResponse(e, t) { + var i = e.decryptdata.uri, + r = e.setKeyRequestState(Kc.GET_KEY_RESPONSE); + return this.eventEmitter.trigger(x.LICENSE_CHALLENGE_CREATED, { + keyuri: i, + licenseChallenge: t, + keysystem: this.systemString, + keyId: e.decryptdata.keyId + }), r + } + generateRequestInitialized(e) { + var t = e.licenseChallenge; + return e.requestInfo = void 0, e.resolveState(Kc.GET_CHALLENGE, t), Wu + } + handleParsedKeyResponse(t, e) { + const i = t.decryptdata.uri, + r = e.statusCode; + if (0 !== r) return Vi(new gc("License server responded with error", i, r, { + code: r, + text: "Server error" + }, !1, rc.LicenseServerError)); + if (!e.license || !e.license.byteLength) return Vi(new gc("License server responded with invalid license", i, r, { + code: r, + text: "Invalid license" + }, !1, rc.LicenseServerError)); + if (e.renewalDate) { + const i = e.renewalDate, + r = new Date, + n = i > r ? i.getTime() - r.getTime() : 0; + 0 < n && this._scheduleRenewal(t, n) + } + return en([t.setKeyRequestState(Kc.PROCESS_LICENSE), Fr(t.session.update(e.license)).pipe(Za(() => { + t.resolveState(Kc.PROCESS_LICENSE, void 0) + }), Vn(e => { + throw this.logger.error(`${this.systemString} FAIL: Failed to update with key response message=${e.message}`), new yc(e.message, t.decryptdata.uri, 0, $.KeySystemFailedToUpdateSession, this.systemString) + }))]).pipe(Zs(void 0)) + } + handleKeyMessage(e) { + if (this.isDestroying) this.logger.warn("In the middle of destroying, ignore key message"); + else { + const t = new DOMParser, + i = new("utf16" === this.config.playReadyMessageFormat ? Uint16Array : Uint8Array)(e.message.buffer || e.message), + r = String.fromCharCode.apply(null, Array.from(i)), + n = t.parseFromString(r, "application/xml").getElementsByTagName("PlayReadyKeyMessage")[0]; + if (n && "LicenseAcquisition" === n.getAttribute("type")) { + const s = t.parseFromString(r, "application/xml").getElementsByTagName("Challenge")[0]; + if (s && "base64encoded" === s.getAttribute("encoding") && 0 !== s.childNodes.length) { + const a = qc.base64Decode(s.childNodes[0].nodeValue), + o = O.utf8arrayToStr(a), + l = t.parseFromString(o, "application/xml").getElementsByTagName("KID")[0]; + e = null, e = l.childNodes[0] ? l.childNodes[0].nodeValue : l.getAttribute("VALUE"), e = qc.base64Decode(e).subarray(0, 16); + Wc.changeEndianness(e); + const d = this.keyIdToKeyInfo[O.utf8arrayToStr(e)]; + d && (d.licenseChallenge = a, d.resolveState(Kc.GET_CHALLENGE, a)) + } else this.logger.warn(`${this.systemString} wrong challenge format or empty challenge`) + } else this.logger.warn(`${this.systemString} unrecognized message ignore it`) + } + } + } + w = Sh; + const bh = { + initDataTypes: ["cenc", "keyids"] + }, + Th = new Uint8Array([237, 239, 139, 169, 121, 214, 74, 206, 163, 200, 39, 220, 213, 29, 33, 237]), + Eh = { + clearkey: th, + fairplaystreaming: Sc, + playready: Fc, + widevine: Bc + }, + Ih = { + clearkey: [ + ["org.w3.clearkey", nu] + ], + fairplaystreaming: [ + ["com.apple.fps.3_0", t], + ["com.apple.fps", ru] + ], + playready: [ + ["com.microsoft.playready.recommendation", w] + ], + widevine: [ + ["com.widevine.alpha", class extends Zc { + constructor(e, t, i, r, n, s) { + super(e, t, i, r, !1, n, s), this.shouldDestroyMediaKeys = !0 + } + static get systemId() { + return Th + } + static get requestAccessConfig() { + return bh + } + get needsCert() { + return !0 + } + removeKey(e) { + return super.removeSessions(e, !0) + } + ensureKeyContext(e) { + const t = e.uri, + i = this.keyUriToKeyInfo[t]; + return null != i && i.session && (i.oldSessions.push(i.session), i.session = null), super.ensureKeyContext(e) + } + getKeyRequestResponse(e, t) { + var i = e.decryptdata.uri, + r = e.setKeyRequestState(Kc.GET_KEY_RESPONSE); + return this.eventEmitter.trigger(x.LICENSE_CHALLENGE_CREATED, { + keyuri: i, + licenseChallenge: t, + keysystem: this.systemString, + keyId: e.decryptdata.keyId + }), r + } + handleParsedKeyResponse(t, e) { + t.licenseChallenge = void 0; + const i = t.decryptdata.uri, + r = e.statusCode; + if (0 !== r) return Vi(new gc("License server responded with error", i, r, { + code: r, + text: "Server error" + }, !1, rc.LicenseServerError)); + if (!e.license || !e.license.byteLength) return Vi(new gc("License server responded with invalid license", i, r, { + code: r, + text: "Invalid license" + }, !1, rc.LicenseServerError)); + if (e.renewalDate) { + const i = e.renewalDate, + r = new Date, + n = i > r ? i.getTime() - r.getTime() : 0; + 0 < n && this._scheduleRenewal(t, n) + } + return en([t.setKeyRequestState(Kc.PROCESS_LICENSE), Fr(t.session.update(e.license)).pipe(Za(() => { + var e = t.decryptdata.keyId, + e = t.session.keyStatuses.get(e); + this.handleKeyStatusForKey(e, t) + }), Vn(e => { + throw this.logger.error(`${this.systemString} FAIL: Failed to update with key response code=${e.code} message=${e.message}`), new yc(e.message, t.decryptdata.uri, e.code, { + code: e.code, + text: "Failed to update with key response" + }, this.systemString) + }))]).pipe(Zs(void 0)) + } + generateInitData(e, t) { + return { + initData: t.pssh, + initDataType: "cenc" + } + } + generateRequestInitialized(e) { + var t = e.licenseChallenge; + return e.requestInfo = void 0, e.resolveState(Kc.GET_CHALLENGE, t), Wu + } + handleKeyMessage(i) { + if (this.isDestroying) this.logger.warn("In the middle of destroying, ignore key message"); + else { + const r = i.target; + let e = null, + t = null; + if (r.sessionId in this.sessionIdToKeyUri) e = this.sessionIdToKeyUri[r.sessionId], t = this.keyUriToKeyInfo[e]; + else + for (const [i, n] of Object.entries(this.keyUriToKeyInfo)) + if (n.session === r) { + e = i, t = n; + break + } if (t) switch (i.messageType) { + case "license-request": { + const r = new Uint8Array(i.message); + t.resolveState(Kc.GET_CHALLENGE, r); + break + } + } else this.logger.warn(`${this.systemString} empty keyuri and keyInfo`) + } + } + }] + ] + }, + wh = th.id; + class Ah { + createMediaKeys(t, e, i, r, n) { + let s = Ah.idToMediaKeysInfoMap[t]; + if (!s) { + const a = Wc.getCapabilities(e, i), + o = new er; + Ah.requestKeySystemAccess(t, a, n, r).pipe(La(function(e) { + return Fr((Ah.idToMediaKeysInfoMap[t].keySystemAccess = e).createMediaKeys()) + }), Za(e => { + o.next(e), o.complete() + }), Vn(e => (o.error(new yc(`could not initialize key system: ${e.message}`, void 0, 0, $.KeySystemFailedToInitialize, t)), Ii)), Va(Ah.destroy$)).subscribe(), s = Ah.idToMediaKeysInfoMap[t] = { + mediaKeys$: o, + keySystemAccess: null + } + } + return s.mediaKeys$ + } + destroyMediaKeys() { + Ah.destroy$.next(), Ah.idToMediaKeysInfoMap = {} + } + static getKeySystemIdForDecryptData(e) { + let t; + if (e) { + t = wh; + var i = e.format; + for (const e of ih) { + var r = Eh[e]; + if ((null == r ? void 0 : r.keyFormatString) === i) { + t = e; + break + } + } + } + if (!t) throw Error("No matching key system"); + return t + } + static requestKeySystemAccess(e, t, i, r) { + if ("undefined" == typeof navigator || void 0 === navigator.requestMediaKeySystemAccess) return Vi(new yc("navigator undefined", void 0, 0, $.KeySystemUndefinedNavigator, e)); + const n = Ih[e]; + let s = Vi(new yc("no key systems to try", void 0, 0, $.KeySystemNoKeySystemsToTry, e)); + for (const e of n) { + const n = e[0], + o = e[1], + l = (a = i) && "object" == typeof a ? i : o.requestAccessConfig, + d = [Object.assign({}, l, t)]; + s = s.pipe(Vn(() => Ah.requestKeySystemInternal(n, d, r))) + } + var a; + return s + } + static requestKeySystemInternal(e, t, i) { + return Zr(() => Fr(navigator.requestMediaKeySystemAccess(e, t))) + } + make(e, t, i, r, n, s) { + var a = null === (l = Ah.idToMediaKeysInfoMap[e]) || void 0 === l ? void 0 : l.keySystemAccess; + if (!a) throw new yc(`No keySystemAccess for ${e}`, void 0, 0, $.KeySystemNoKeySystemAccess, e); + let o; + var l = Eh[e].systemStringPrefix; + for (const t of Ih[e]) + if (t[0] === a.keySystem) { + o = t[1]; + break + } if (!o) throw new yc(`No constructor associated with ${e}`, void 0, 0, $.KeySystemNoConstructor, l); + return new o(t, l, i, r, n, s) + } + static get availableKeySystems() { + return Object.keys(Eh) + } + static getKeySystemFormat(e) { + e = Eh[e]; + return e ? e.keyFormatString : "" + } + static getKeySystemSecurityLevel(e) { + e = Eh[e]; + return e ? e.securityLevels : void 0 + } + } + Ah.idToMediaKeysInfoMap = {}, Ah.destroy$ = new Xt; + const Oh = ["avc1.42E01E"], + kh = ["mp4a.40.2"]; + + function Ch(e, t, i) { + if (t) { + if (t instanceof dr) t = new mc("Key request timed out", e, $.KeySystemRequestTimedOut); + else if (t instanceof yc) { + const i = (null == t ? void 0 : t.response) || $.InternalError; + t = new gc(t.message, e, 0, i, !1, rc.InternalError, !0) + } + } else t = new gc("Unknown error from CDM", e, 0, $.KeySystemCDMUnknownError, !1, rc.InternalError); + return (t instanceof gc || t instanceof mc) && (t.mediaOptionIds = [...i]), t + } + class Dh { + constructor(e, t, i, r, n, s, a, o = new Ah) { + this.ksService = e, this.mediaSink = t, this.config = i, this.platformQuery = r, this.eventEmitter = n, this.sessionHandler = s, this.keySystemFactory = o, this.reset$ = new Xt, this.keyRequest$ = new Xt, this.abort$ = new Xt, this.keySystem$ = new yi(null), this._keyStatusChange$ = new Xt, this.protectionData = {}, this.keySystemId = null, this.keyUriToRequest = {}, this.ksQuery = e.getQuery(), this.logger = a.child({ + name: "eme" + }), this.config.warmupCdms && this.keySystemFactory.createMediaKeys(Sc.id, Oh, kh, this.logger, void 0).subscribe(), an(r.platformInfo$.pipe(Is((e, t) => e && t && e.requiresCDMAttachOnStart === t.requiresCDMAttachOnStart), La(e => null != e && e.requiresCDMAttachOnStart ? this.attachMediaKeys().pipe(Vn(e => (this.handleKeySystemError(e), Ii))) : Wu), $a(Ii)), this.keyRequest$.pipe(jr(e => e.pipe(Vn(() => Ii)))), this.keySystem$.pipe(La(e => e ? e.keyStatusChange$.pipe(Za(e => { + var t = e.decryptdata.uri, + i = this.ksQuery.getKeyInfo(t); + "needs-renewal" === e.status ? this.ksService.updateKeyRequestState(t, ic.MustRequestResponse, e => e === ic.GotKeyResponse) : (i = Ch(t, e.error, null !== (i = null == i ? void 0 : i.mediaOptionIds) && void 0 !== i ? i : []), this.ksService.setError(t, i)), this._keyStatusChange$.next(e) + })) : Ii)), this.isKeyCleanupSupported() ? this.mediaSink.mediaQuery.bufferedSegmentsTuple$.pipe(jr(e => { + const [t, i] = e, r = new Set; + return t.forEach(e => { + e = null === (e = null === (e = e.frag) || void 0 === e ? void 0 : e.keyTagInfo) || void 0 === e ? void 0 : e.uri; + e && r.add(e) + }), i.forEach(e => { + e = null === (e = null === (e = e.frag) || void 0 === e ? void 0 : e.keyTagInfo) || void 0 === e ? void 0 : e.uri; + e && r.add(e) + }), this.handleKeyCleanup(r) + })) : Wu).pipe(Va(this.reset$)).subscribe() + } + get keyStatusChange$() { + return this._keyStatusChange$ + } + get keySystem() { + return this.keySystem$.value + } + destroy() { + this.reset$.next(), this.ksService.removeAll(), this.keySystemId = null; + const e = this.keySystem; + let t = Wu; + return e && (this.keySystem$.next(null), e.shouldDestroyMediaKeys && this.keySystemFactory.destroyMediaKeys(), t = e.destroy()), Mr([t, this.mediaSink.clearMediaKeys()]).pipe(Zs(void 0)) + } + attachMediaKeys() { + if (this.keySystem) return Wu; + var e = this.config.keySystemPreference ? Ah.getKeySystemFormat(this.config.keySystemPreference) : Sc.keyFormatString; + return this.makeKeySystem(new zc("NONE", null, null, e, [1])).pipe(Zs(void 0)) + } + isKeyCleanupSupported() { + return !0 === this.config.useMultipleKeySessions || "widevine" === this.config.keySystemPreference || "playready" === this.config.keySystemPreference + } + handleKeyCleanup(i) { + if (this.ksQuery.getCount() < 6) return Wu; + const r = performance.now(), + e = this.ksQuery.getAll().map(e => { + var t = e.keyUri; + if (!i.has(t)) { + const i = ac(e.decryptdata); + if ("AES-128" !== i.method && r > e.minHoldTime) return this._removeKey(t, i) + } + return Wu + }); + return e.length ? en(e).pipe($a(Wu)) : Wu + } + _removeKey(e, t) { + return this.abort$.next(e), this.ksService.removeKey(e), this.keySystem.removeKey(t) + } + removeKeysForItems(i) { + const r = []; + return al(() => { + for (const e of i) { + this.ksService.removeAllKeysForItem(e); + const i = this.ksQuery.getAll({ + filterBy: e => 0 === e.itemIds.length + }); + for (const t of i) r.push(this._removeKey(t.keyUri, ac(t.decryptdata))) + } + }), r.length ? en(r).pipe(La(() => Wu)) : Wu + } + get availableKeySystems() { + return Ah.availableKeySystems + } + initialize(e) { + var t = this.protectionData; + this.protectionData = {}; + var i = this.config.keySystemPreference; + for (const a of Ah.availableKeySystems) { + var r = e[a]; + if (r) + if (i === a) { + var n, s = r.certificate, + r = r.serverCertUrl ? bu.buildAbsoluteURL(window.location.href, r.serverCertUrl) : void 0; + let e; + this.protectionData[a] = { + serverCertUrl: r, + certificate: s + }, s ? e = $i({ + keysystem: a, + certificate: s + }) : r && (null === (n = null == t ? void 0 : t[a]) || void 0 === n ? void 0 : n.serverCertUrl) !== r && (n = Tu(r) ? this.config.certLoadPolicy.customURL : this.config.certLoadPolicy.default, e = Rc({ + url: r, + xhrSetup: this.config.xhrSetup + }, n).pipe(hr(([e]) => ({ + keysystem: a, + certificate: new Uint8Array(e) + })))), e && e.pipe(La(e => this.onServerCertificateLoaded(e)), Vn(e => { + throw this.logger.error(`Error loading cert: ${e.message}`), this.eventEmitter.trigger(x.INTERNAL_ERROR, { + type: o, + details: "certificateLoadError", + fatal: !1, + handled: !0, + reason: "Error handling cert", + response: $.KeySystemCertificateLoadError, + message: e.message, + name: "certificateLoadError" + }), e + }), Va(this.reset$)).subscribe() + } else this.logger.warn(`Key system ${a} does not match preference ${i}, ignoring`) + } + } + generateRequest(e, t) { + this.keySystem && this.keySystem.setKeyRequestInfo(e, t) + } + setLicenseResponse(e, t) { + this.keySystem && this.keySystem.setParsedResponse(e, t) + } + getKeyFromDecryptData(e, t) { + if (!e || !e.isEncrypted) return $i(e); + let i; + return al(() => { + i = this._getKeyFromDecryptData(e, t) + }), i + } + _getKeyFromDecryptData(t, i) { + let r = null, + n = null; + i && (r = i.itemId, n = i.mediaOptionId); + const s = t.uri, + e = this.ksQuery.getKeyInfo(s); + if (e && null != i && this.ksService.addMediaOption(s, i), (null == e ? void 0 : e.error) instanceof gc && !1 === e.error.isOkToRetry) return Vi(e.error); + if (e && e.requestState !== ic.MustRequestResponse) return e.requestState === ic.GotKeyResponse ? $i(ac(e.decryptdata)) : this.keyUriToRequest[s]; { + const o = performance.now() + this.config.keyMinHoldTimeBeforeCleanup; + let e; + this.abort$.next(s), this.ksService.upsertKey({ + keyUri: s, + decryptdata: function(e) { + var { + method: t, + isEncrypted: i, + uri: r, + format: n, + formatversions: s + } = e; + return { + method: t, + isEncrypted: i, + uri: r, + format: n, + formatversions: s, + ivBuf: null !== (s = null === (s = e.iv) || void 0 === s ? void 0 : s.buffer) && void 0 !== s ? s : null, + keyIdBuf: null === (s = e.keyId) || void 0 === s ? void 0 : s.buffer, + keyBuf: null === (s = e.key) || void 0 === s ? void 0 : s.buffer, + psshBuf: null === (e = e.key) || void 0 === e ? void 0 : e.buffer + } + }(t), + minHoldTime: o, + mediaOptionIds: [n], + requestState: ic.WaitingForKeyResponse, + itemIds: [r] + }); + var a = t.method; + switch (a) { + case "SAMPLE-AES": + case "ISO-23001-7": + case "SAMPLE-AES-CTR": { + const o = this.config.keyLoadPolicy.customURL; + e = this.fetchKeyEME(t).pipe(So(o.maxLoadTimeMs)); + break + } + case "AES-128": + e = this.fetchKeyHTTP(t.uri, t, this.config.keyLoadPolicy); + break; + default: + return Vi(new V(!1, `Unexpected METHOD attribute ${a}`, $.KeySystemUnexpectedMETHOD)) + } + i = this.keyUriToRequest[s] = e.pipe(hr(e => { + var t = e.decryptdata; + return this.ksService.updateKeyValue(s, t.key), this.eventEmitter.trigger(x.KEY_LOADED, e), e.decryptdata + }), Vn(e => { + var t = this.ksQuery.getKeyInfo(s); + return e = Ch(s, e, null !== (t = null == t ? void 0 : t.mediaOptionIds) && void 0 !== t ? t : []), this.ksService.setError(s, e), Vi(e) + }), Vs(() => { + this.ksService.updateKeyRequestState(s, ic.MustRequestResponse, e => e === ic.WaitingForKeyResponse), this.keyUriToRequest[s] = null + }), Aa(), Va(fn(this.abort$.pipe(ln(e => e === s)), this.reset$).pipe(Za(e => this.logger.warn(e ? `aborted ${le(e)}` : "got reset"))))); + return this.keyRequest$.next(i), i + } + } + fetchKeyEME(e) { + return this.requestKey(e).pipe(hr(e => ({ + timestamp: performance.now(), + keyuri: e.uri, + decryptdata: e + }))) + } + fetchKeyHTTP(e, t, i) { + return Dh.fetchKeyHTTP(e, this.config, t, i) + } + static fetchKeyHTTP(t, e, i, r) { + e = { + url: t, + xhrSetup: e.xhrSetup + }; + return Rc(e, Lc(e, r)).pipe(hr(([e]) => (i.key = new Uint8Array(e), { + decryptdata: i, + keyuri: t, + timestamp: performance.now() + }))) + } + requestKey(t) { + return this.makeKeySystem(t).pipe(La(e => e.startKeyRequest(t))) + } + ensureKeySystem(t) { + return Zr(() => { + if (!this.keySystem && this.keySystemId) { + this.keySystem$.next(this.keySystemFactory.make(this.keySystemId, t, this.config, this.eventEmitter, this.sessionHandler, this.logger)); + var e = this.protectionData && this.protectionData[this.keySystemId]; + if (e) return this.keySystem.setServerCertificate(e.certificate).pipe(Zs(this.keySystem)) + } + return $i(this.keySystem) + }) + } + makeKeySystem(e) { + return this.ensureMediaKeys(e).pipe(La(e => this.mediaSink.setMediaKeys(e).pipe(La(() => this.ensureKeySystem(e))))) + } + ensureMediaKeys(e) { + var t = Ah.getKeySystemIdForDecryptData(e); + if (null == this.keySystemId) this.keySystemId = t; + else if (this.keySystemId !== t) return Vi(new gc(`New key system string does not match existing ${t} !== ${this.keySystemId}`, e.uri, 0, $.KeySystemUnmatchedString, !1, rc.InternalError)); + return this.keySystemFactory.createMediaKeys(this.keySystemId, Oh, kh, this.logger, null === (e = this.platformQuery.platformInfo) || void 0 === e ? void 0 : e.keySystemConfig) + } + onServerCertificateLoaded(e) { + var t = e.keysystem, + e = e.certificate; + return this.protectionData[t].certificate = e, this.keySystem && this.keySystemId === t ? this.keySystem.setServerCertificate(e).pipe(Zs(void 0)) : Wu + } + handleKeySystemError(e) { + e = new yc(e.message, void 0, void 0, $.KeySystemSetupError, void 0); + this.eventEmitter.trigger(x.INTERNAL_ERROR, e) + } + } + class Mh extends kl { + constructor(e) { + super(e) + } + getKeyInfo(e) { + e = this.getEntity(e); + return e ? Object.assign(Object.assign({}, e), { + error: vc(e.error, e.mediaOptionIds) + }) : null + } + getKeyInfo$(e) { + return this.selectEntity(e).pipe(hr(e => e ? Object.assign(Object.assign({}, e), { + error: vc(e.error, e.mediaOptionIds) + }) : null)) + } + getKeyRequestState$(e) { + return this.selectEntity(e, e => null == e ? void 0 : e.requestState) + } + getKeyStatus$(e) { + return this.selectEntity(e, e => null == e ? void 0 : e.status) + } + getKeyError$(e) { + return this.selectEntity(e, e => vc(null == e ? void 0 : e.error, null == e ? void 0 : e.mediaOptionIds)).pipe(wl) + } + } + class xh { + constructor(e) { + this.store = e + } + getQuery() { + return new Mh(this.store) + } + upsertKey(i) { + Do("keys.upsert", i.keyUri); + const r = new Set(i.itemIds.filter(e => null != e)), + n = new Set(i.mediaOptionIds.filter(e => null != e)); + this.store.upsert(i.keyUri, e => { + const t = Object.assign(Object.assign({}, e), i); + if ("itemIds" in e) + for (const i of e.itemIds) r.add(i); + if (t.itemIds = Array.from(r), "mediaOptionIds" in e) + for (const i of e.mediaOptionIds) n.add(i); + return t.mediaOptionIds = Array.from(n), t + }, () => Object.assign(Object.assign({}, i), { + itemIds: Array.from(r), + mediaOptionIds: Array.from(n) + })) + } + removeKey(e) { + Do("keys.removeKey", e), this.store.remove(e) + } + removeAllKeysForItem(i) { + Do(`keys.removeAllKeysForItem ${i}`), this.store.update(null, e => { + var t = e.itemIds.findIndex(e => e === i); + 0 <= t && e.itemIds.splice(t, 1) + }) + } + removeAll() { + Do("keys.remove"), this.store.remove() + } + updateKeyValue(e, t) { + Do("keys.updateKeyValue", e), this.store.update(e, e => { + null == e.decryptdata.keyBuf && null != t && (e.decryptdata.keyBuf = t.buffer), e.requestState = ic.GotKeyResponse + }) + } + updateKeyStatus(e, t) { + Do(`keys.updateKeyStatus ${t}`, e), this.store.update(e, e => { + e.status = t + }) + } + updateKeyRequestState(e, t, i) { + Do(`keys.updateKeyRequestState ${t}`, e), this.store.update(e, e => { + i && !i(e.requestState) || (e.requestState = t) + }) + } + addMediaOption(e, t) { + const { + itemId: i, + mediaOptionId: r + } = t; + Do(`keys.addMediaOption itemId: ${i}, mediaOptionId: ${r}`, e), this.store.update(e, e => { + null != r && e.mediaOptionIds.every(e => e !== r) && e.mediaOptionIds.push(r), null != i && e.itemIds.every(e => e !== i) && e.itemIds.push(i) + }) + } + setError(e, t) { + var i; + Do(`keys.setError ${null===(i=null==t?void 0:t.constructor)||void 0===i?void 0:i.name}`, e), this.store.update(e, e => { + e.error = vc(t), e.requestState = ic.MustRequestResponse + }) + } + } + const Ph = new class extends fl { + constructor() { + super({}, { + name: "key-system-store", + idKey: "keyUri", + producerFn: su + }) + } + }; + let Rh = null; + + function Lh(e) { + let t = e; + return Nh.hasOwnProperty(e) && (t = Nh[e]), String.fromCharCode(t) + } + + function _h(t) { + const i = []; + for (let e = 0; e < t.length; e++) i.push(t[e].toString(16)); + return i + } + const Nh = { + 42: 225, + 92: 233, + 94: 237, + 95: 243, + 96: 250, + 123: 231, + 124: 247, + 125: 209, + 126: 241, + 127: 9608, + 128: 174, + 129: 176, + 130: 189, + 131: 191, + 132: 8482, + 133: 162, + 134: 163, + 135: 9834, + 136: 224, + 137: 32, + 138: 232, + 139: 226, + 140: 234, + 141: 238, + 142: 244, + 143: 251, + 144: 193, + 145: 201, + 146: 211, + 147: 218, + 148: 220, + 149: 252, + 150: 8216, + 151: 161, + 152: 42, + 153: 8217, + 154: 9473, + 155: 169, + 156: 8480, + 157: 8226, + 158: 8220, + 159: 8221, + 160: 192, + 161: 194, + 162: 199, + 163: 200, + 164: 202, + 165: 203, + 166: 235, + 167: 206, + 168: 207, + 169: 239, + 170: 212, + 171: 217, + 172: 249, + 173: 219, + 174: 171, + 175: 187, + 176: 195, + 177: 227, + 178: 205, + 179: 204, + 180: 236, + 181: 210, + 182: 242, + 183: 213, + 184: 245, + 185: 123, + 186: 125, + 187: 92, + 188: 94, + 189: 95, + 190: 124, + 191: 8764, + 192: 196, + 193: 228, + 194: 214, + 195: 246, + 196: 223, + 197: 165, + 198: 164, + 199: 9475, + 200: 197, + 201: 229, + 202: 216, + 203: 248, + 204: 9487, + 205: 9491, + 206: 9495, + 207: 9499 + }, + Fh = 100, + Bh = { + 17: 1, + 18: 3, + 21: 5, + 22: 7, + 23: 9, + 16: 11, + 19: 12, + 20: 14 + }, + Uh = { + 17: 2, + 18: 4, + 21: 6, + 22: 8, + 23: 10, + 19: 13, + 20: 15 + }, + $h = { + 25: 1, + 26: 3, + 29: 5, + 30: 7, + 31: 9, + 24: 11, + 27: 12, + 28: 14 + }, + Vh = { + 25: 2, + 26: 4, + 29: 6, + 30: 8, + 31: 10, + 27: 13, + 28: 15 + }, + Kh = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "black", "transparent"], + qh = { + verboseFilter: { + DATA: 3, + DEBUG: 3, + INFO: 2, + WARNING: 2, + TEXT: 1, + ERROR: 0 + }, + time: null, + verboseLevel: 0, + setTime: function(e) { + this.time = e + }, + log: function(e, t) { + var i = this.verboseFilter[e]; + this.verboseLevel >= i && console.log(this.time + " [" + e + "] " + t) + } + }; + class Hh { + constructor(e, t, i, r, n) { + this.foreground = e || "white", this.underline = t || !1, this.italics = i || !1, this.background = r || "black", this.flash = n || !1 + } + reset() { + this.foreground = "white", this.underline = !1, this.italics = !1, this.background = "black", this.flash = !1 + } + setStyles(e) { + Object.assign(this, e) + } + isDefault() { + return "white" === this.foreground && !this.underline && !this.italics && "black" === this.background && !this.flash + } + equals(e) { + return this.foreground === e.foreground && this.underline === e.underline && this.italics === e.italics && this.background === e.background && this.flash === e.flash + } + copy(e) { + this.foreground = e.foreground, this.underline = e.underline, this.italics = e.italics, this.background = e.background, this.flash = e.flash + } + toString() { + return "color=" + this.foreground + ", underline=" + this.underline + ", italics=" + this.italics + ", background=" + this.background + ", flash=" + this.flash + } + } + class jh { + constructor(e, t, i, r, n, s) { + this.uchar = e || " ", this.penState = new Hh(t, i, r, n, s) + } + reset() { + this.uchar = " ", this.penState.reset() + } + setChar(e, t) { + this.uchar = e, this.penState.copy(t) + } + setPenState(e) { + this.penState.copy(e) + } + equals(e) { + return this.uchar === e.uchar && this.penState.equals(e.penState) + } + copy(e) { + this.uchar = e.uchar, this.penState.copy(e.penState) + } + isEmpty() { + return " " === this.uchar && this.penState.isDefault() + } + } + class Qh { + constructor() { + this.chars = []; + for (let e = 0; e < Fh; e++) this.chars.push(new jh); + this.pos = 0, this.currPenState = new Hh + } + equals(t) { + let i = !0; + for (let e = 0; e < Fh; e++) + if (!this.chars[e].equals(t.chars[e])) { + i = !1; + break + } return i + } + copy(t) { + for (let e = 0; e < Fh; e++) this.chars[e].copy(t.chars[e]) + } + isEmpty() { + let t = !0; + for (let e = 0; e < Fh; e++) + if (!this.chars[e].isEmpty()) { + t = !1; + break + } return t + } + setCursor(e) { + this.pos !== e && (this.pos = e), this.pos < 0 ? (qh.log("ERROR", "Negative cursor position " + this.pos), this.pos = 0) : this.pos > Fh && (qh.log("ERROR", "Too large cursor position " + this.pos), this.pos = Fh) + } + moveCursor(e) { + var t = this.pos + e; + if (1 < e) + for (let e = this.pos + 1; e < t + 1; e++) this.chars[e].setPenState(this.currPenState); + this.setCursor(t) + } + backSpace() { + this.moveCursor(-1), this.chars[this.pos].setChar(" ", this.currPenState) + } + insertChar(e) { + 144 <= e && this.backSpace(); + var t = Lh(e); + this.pos >= Fh ? qh.log("ERROR", "Cannot insert " + e.toString(16) + " (" + t + ") at position " + this.pos + ". Skipping it!") : (this.chars[this.pos].setChar(t, this.currPenState), this.moveCursor(1)) + } + clearFromPos(e) { + let t; + for (t = e; t < Fh; t++) this.chars[t].reset() + } + clear() { + this.clearFromPos(0), this.pos = 0, this.currPenState.reset() + } + clearToEndOfRow() { + this.clearFromPos(this.pos) + } + getTextString() { + const t = []; + let i = !0; + for (let e = 0; e < Fh; e++) { + var r = this.chars[e].uchar; + " " !== r && (i = !1), t.push(r) + } + return i ? "" : t.join("") + } + setPenStyles(e) { + this.currPenState.setStyles(e), this.chars[this.pos].setPenState(this.currPenState) + } + } + class Wh { + constructor() { + this.rows = []; + for (let e = 0; e < 15; e++) this.rows.push(new Qh); + this.currRow = 14, this.nrRollUpRows = null, this.reset() + } + reset() { + for (let e = 0; e < 15; e++) this.rows[e].clear(); + this.currRow = 14 + } + equals(t) { + let i = !0; + for (let e = 0; e < 15; e++) + if (!this.rows[e].equals(t.rows[e])) { + i = !1; + break + } return i + } + copy(t) { + for (let e = 0; e < 15; e++) this.rows[e].copy(t.rows[e]) + } + isEmpty() { + let t = !0; + for (let e = 0; e < 15; e++) + if (!this.rows[e].isEmpty()) { + t = !1; + break + } return t + } + backSpace() { + this.rows[this.currRow].backSpace() + } + clearToEndOfRow() { + this.rows[this.currRow].clearToEndOfRow() + } + insertChar(e) { + this.rows[this.currRow].insertChar(e) + } + setPen(e) { + this.rows[this.currRow].setPenStyles(e) + } + moveCursor(e) { + this.rows[this.currRow].moveCursor(e) + } + setCursor(e) { + qh.log("INFO", "setCursor: " + e), this.rows[this.currRow].setCursor(e) + } + setPAC(t) { + qh.log("INFO", "pacData = " + JSON.stringify(t)); + let i = t.row - 1; + if (this.nrRollUpRows && i < this.nrRollUpRows - 1 && (i = this.nrRollUpRows - 1), this.nrRollUpRows && this.currRow !== i) { + for (let e = 0; e < 15; e++) this.rows[e].clear(); + const t = this.currRow + 1 - this.nrRollUpRows, + r = this.lastOutputScreen; + if (r) { + const e = r.rows[t].cueStartTime; + if (e && e < qh.time) + for (let e = 0; e < this.nrRollUpRows; e++) this.rows[i - this.nrRollUpRows + e + 1].copy(r.rows[t + e]) + } + } + this.currRow = i; + const r = this.rows[this.currRow]; + if (null !== t.indent) { + const i = t.indent, + e = Math.max(i - 1, 0); + r.setCursor(t.indent), t.color = r.chars[e].penState.foreground + } + const e = { + foreground: t.color, + underline: t.underline, + italics: t.italics, + background: "black", + flash: !1 + }; + this.setPen(e) + } + setBkgData(e) { + qh.log("INFO", "bkgData = " + JSON.stringify(e)), this.backSpace(), this.setPen(e), this.insertChar(32) + } + setRollUpRows(e) { + this.nrRollUpRows = e + } + rollUp() { + if (null !== this.nrRollUpRows) { + qh.log("INFO", "TEXT " + this.getDisplayText()); + const e = this.currRow + 1 - this.nrRollUpRows, + t = this.rows.splice(e, 1)[0]; + t.clear(), this.rows.splice(this.currRow, 0, t), qh.log("INFO", "Rolling up") + } else qh.log("DEBUG", "roll_up but nrRollUpRows not set yet") + } + getDisplayText(t) { + t = t || !1; + const i = []; + let e = "", + r; + for (let e = 0; e < 15; e++) { + const n = this.rows[e].getTextString(); + n && (r = e + 1, t ? i.push("Row " + r + ": '" + n + "'") : i.push(n.trim())) + } + return 0 < i.length && (e = t ? "[" + i.join(" | ") + "]" : i.join("\n")), e + } + getTextAndFormat() { + return this.rows + } + } + class Gh { + constructor(e, t) { + this.chNr = e, this.outputFilter = t, this.mode = null, this.verbose = 0, this.displayedMemory = new Wh, this.nonDisplayedMemory = new Wh, this.lastOutputScreen = new Wh, this.currRollUpRow = this.displayedMemory.rows[14], this.writeScreen = this.displayedMemory, this.mode = null, this.cueStartTime = null + } + reset() { + this.mode = null, this.displayedMemory.reset(), this.nonDisplayedMemory.reset(), this.lastOutputScreen.reset(), this.currRollUpRow = this.displayedMemory.rows[14], this.writeScreen = this.displayedMemory, this.mode = null, this.cueStartTime = null, this.lastCueEndTime = null + } + getHandler() { + return this.outputFilter + } + setHandler(e) { + this.outputFilter = e + } + setPAC(e) { + this.writeScreen.setPAC(e) + } + setBkgData(e) { + this.writeScreen.setBkgData(e) + } + setMode(e) { + e !== this.mode && (this.mode = e, qh.log("INFO", "MODE=" + e), "MODE_POP-ON" === this.mode ? this.writeScreen = this.nonDisplayedMemory : (this.writeScreen = this.displayedMemory, this.writeScreen.reset()), "MODE_ROLL-UP" !== this.mode && (this.displayedMemory.nrRollUpRows = null, this.nonDisplayedMemory.nrRollUpRows = null), this.mode = e) + } + insertChars(t) { + for (let e = 0; e < t.length; e++) this.writeScreen.insertChar(t[e]); + var e = this.writeScreen === this.displayedMemory ? "DISP" : "NON_DISP"; + qh.log("INFO", e + ": " + this.writeScreen.getDisplayText(!0)), "MODE_PAINT-ON" !== this.mode && "MODE_ROLL-UP" !== this.mode || (qh.log("TEXT", "DISPLAYED: " + this.displayedMemory.getDisplayText(!0)), this.outputDataUpdate()) + } + ccRCL() { + qh.log("INFO", "RCL - Resume Caption Loading"), this.setMode("MODE_POP-ON") + } + ccBS() { + qh.log("INFO", "BS - BackSpace"), "MODE_TEXT" !== this.mode && (this.writeScreen.backSpace(), this.writeScreen === this.displayedMemory && this.outputDataUpdate()) + } + ccAOF() {} + ccAON() {} + ccDER() { + qh.log("INFO", "DER- Delete to End of Row"), this.writeScreen.clearToEndOfRow(), this.outputDataUpdate() + } + ccRU(e) { + qh.log("INFO", "RU(" + e + ") - Roll Up"), this.writeScreen = this.displayedMemory, this.setMode("MODE_ROLL-UP"), this.writeScreen.setRollUpRows(e) + } + ccFON() { + qh.log("INFO", "FON - Flash On"), this.writeScreen.setPen({ + flash: !0 + }) + } + ccRDC() { + qh.log("INFO", "RDC - Resume Direct Captioning"), this.setMode("MODE_PAINT-ON") + } + ccTR() { + qh.log("INFO", "TR"), this.setMode("MODE_TEXT") + } + ccRTD() { + qh.log("INFO", "RTD"), this.setMode("MODE_TEXT") + } + ccEDM() { + qh.log("INFO", "EDM - Erase Displayed Memory"), this.displayedMemory.reset(), this.outputDataUpdate(!0) + } + ccCR() { + qh.log("INFO", "CR - Carriage Return"), this.writeScreen.rollUp(), this.outputDataUpdate(!0) + } + ccENM() { + qh.log("INFO", "ENM - Erase Non-displayed Memory"), this.nonDisplayedMemory.reset() + } + ccEOC() { + var e; + qh.log("INFO", "EOC - End Of Caption"), "MODE_POP-ON" === this.mode && (e = this.displayedMemory, this.displayedMemory = this.nonDisplayedMemory, this.nonDisplayedMemory = e, this.writeScreen = this.nonDisplayedMemory, qh.log("TEXT", "DISP: " + this.displayedMemory.getDisplayText())), this.outputDataUpdate(!0) + } + ccTO(e) { + qh.log("INFO", "TO(" + e + ") - Tab Offset"), this.writeScreen.moveCursor(e) + } + ccMIDROW(e) { + const t = { + flash: !1, + underline: !1, + italics: !1 + }; + t.underline = e % 2 == 1, t.italics = 46 <= e, t.italics ? t.foreground = "white" : (e = Math.floor(e / 2) - 16, t.foreground = ["white", "green", "blue", "cyan", "red", "yellow", "magenta"][e]), qh.log("INFO", "MIDROW: " + JSON.stringify(t)), this.writeScreen.setPen(t) + } + outputDataUpdate(e = !1) { + var t = qh.time; + null !== t && this.outputFilter && (this.outputFilter.updateData && this.outputFilter.updateData(t, this.displayedMemory), null !== this.cueStartTime || this.displayedMemory.isEmpty() ? this.displayedMemory.equals(this.lastOutputScreen) || (this.outputFilter.newCue && (this.outputFilter.newCue(this.cueStartTime, t, this.lastOutputScreen), !0 === e && this.outputFilter.dispatchCue && this.outputFilter.dispatchCue()), this.cueStartTime = this.displayedMemory.isEmpty() ? null : t) : this.cueStartTime = t, this.lastOutputScreen.copy(this.displayedMemory)) + } + cueSplitAtTime(e) { + this.outputFilter && (this.displayedMemory.isEmpty() || (this.outputFilter.newCue && this.outputFilter.newCue(this.cueStartTime, e, this.displayedMemory), this.cueStartTime = e)) + } + } + var zh = class { + constructor(e = 1, t, i) { + this.field = e, this.currChNr = -1, this.lastCmdA = null, this.lastCmdB = null, this.channels = [new Gh(1, t), new Gh(2, i)], this.dataCounters = { + padding: 0, + char: 0, + cmd: 0, + other: 0 + } + } + getHandler(e) { + return this.channels[e].getHandler() + } + setHandler(e, t) { + this.channels[e].setHandler(t) + } + addData(e, t) { + let i, r, n, s = null; + qh.setTime(e); + for (let e = 0; e < t.length; e += 2) r = 127 & t[e], n = 127 & t[e + 1], 16 <= r && r <= 31 && r === this.lastCmdA && n === this.lastCmdB ? (this.lastCmdA = null, this.lastCmdB = null, qh.log("DEBUG", "Repeated command (" + _h([r, n]) + ") is dropped")) : 0 != r || 0 != n ? (qh.log("DATA", "[" + _h([t[e], t[e + 1]]) + "] -> (" + _h([r, n]) + ")"), i = this.parseCmd(r, n), i = i || this.parseMidrow(r, n), i = i || this.parsePAC(r, n), i = i || this.parseBackgroundAttributes(r, n), !i && (s = this.parseChars(r, n), s) && (this.currChNr && 0 <= this.currChNr ? this.channels[this.currChNr - 1].insertChars(s) : qh.log("WARNING", "No channel found yet. TEXT-MODE?")), i ? this.dataCounters.cmd += 2 : s ? this.dataCounters.char += 2 : (this.dataCounters.other += 2, qh.log("WARNING", "Couldn't parse cleaned data " + _h([r, n]) + " orig: " + _h([t[e], t[e + 1]])))) : this.dataCounters.padding += 2 + } + parseCmd(e, t) { + var i; + if (!((20 === e || 21 === e || 28 === e || 29 === e) && 32 <= t && t <= 47 || (23 === e || 31 === e) && 33 <= t && t <= 35)) return !1; + const r = this.channels[(i = 20 === e || 23 === e ? 1 : 2) - 1]; + return 20 === e || 21 === e || 28 === e || 29 === e ? 32 === t ? r.ccRCL() : 33 === t ? r.ccBS() : 34 === t ? r.ccAOF() : 35 === t ? r.ccAON() : 36 === t ? r.ccDER() : 37 === t ? r.ccRU(2) : 38 === t ? r.ccRU(3) : 39 === t ? r.ccRU(4) : 40 === t ? r.ccFON() : 41 === t ? r.ccRDC() : 42 === t ? r.ccTR() : 43 === t ? r.ccRTD() : 44 === t ? r.ccEDM() : 45 === t ? r.ccCR() : 46 === t ? r.ccENM() : 47 === t && r.ccEOC() : r.ccTO(t - 32), this.lastCmdA = e, this.lastCmdB = t, this.currChNr = i, !0 + } + parseMidrow(e, t) { + var i; + if ((17 === e || 25 === e) && 32 <= t && t <= 47) { + if ((i = 17 === e ? 1 : 2) !== this.currChNr) return qh.log("ERROR", "Mismatch channel in midrow parsing"), !1; + const r = this.channels[i - 1]; + return r.insertChars([32]), r.ccMIDROW(t), qh.log("DEBUG", "MIDROW (" + _h([e, t]) + ")"), this.lastCmdA = e, this.lastCmdB = t, !0 + } + return !1 + } + parsePAC(e, t) { + if (!((17 <= e && e <= 23 || 25 <= e && e <= 31) && 64 <= t && t <= 127 || (16 === e || 24 === e) && 64 <= t && t <= 95)) return !1; + var i = e <= 23 ? 1 : 2, + r = (64 <= t && t <= 95 ? 1 == i ? Bh : $h : 1 == i ? Uh : Vh)[e], + r = this.interpretPAC(r, t); + return this.channels[i - 1].setPAC(r), this.lastCmdA = e, this.lastCmdB = t, this.currChNr = i, !0 + } + interpretPAC(e, t) { + var i; + const r = { + color: null, + italics: !1, + indent: null, + underline: !1, + row: e + }; + return i = 95 < t ? t - 96 : t - 64, r.underline = 1 == (1 & i), i <= 13 ? r.color = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "white"][Math.floor(i / 2)] : i <= 15 ? (r.italics = !0, r.color = "white") : r.indent = 4 * Math.floor((i - 16) / 2), r + } + parseChars(e, t) { + let i = null, + r = null, + n = null; + var s; + if (n = 25 <= e ? (i = 2, e - 8) : (i = 1, e), 17 <= n && n <= 19 ? (s = t, s = 17 === n ? t + 80 : 18 === n ? t + 112 : t + 144, qh.log("INFO", "Special char '" + Lh(s) + "' in channel " + i), r = [s], this.lastCmdA = e, this.lastCmdB = t) : 32 <= e && e <= 127 && (r = 0 === t ? [e] : [e, t], this.lastCmdA = null, this.lastCmdB = null), r) { + const e = _h(r); + qh.log("DEBUG", `Char codes = ${e.join(",")}`) + } + return r + } + parseBackgroundAttributes(e, t) { + let i, r, n; + return ((16 === e || 24 === e) && 32 <= t && t <= 47 || (23 === e || 31 === e) && 45 <= t && t <= 47) && (i = { + underline: !1 + }, 16 === e || 24 === e ? (r = Math.floor((t - 32) / 2), i.background = Kh[r], t % 2 == 1 && (i.background = i.background + "_semi")) : 45 === t ? i.background = "transparent" : (i.foreground = "black", 47 === t && (i.underline = !0)), n = this.channels[(e < 24 ? 1 : 2) - 1], n.setBkgData(i), this.lastCmdA = null, !(this.lastCmdB = null)) + } + reset() { + for (let e = 0; e < this.channels.length; e++) this.channels[e] && this.channels[e].reset(); + this.lastCmdA = null, this.lastCmdB = null + } + cueSplitAtTime(t) { + for (let e = 0; e < this.channels.length; e++) this.channels[e] && this.channels[e].cueSplitAtTime(t) + } + }; + class Xh { + constructor(e, t) { + this.handler = e, this.track = t, this.startTime = null, this.endTime = null, this.screen = null + } + dispatchCue() { + null !== this.startTime && (this.handler.addCues("cc" + this.track, this.startTime, this.endTime, this.screen), this.startTime = null) + } + newCue(e, t, i) { + (null === this.startTime || this.startTime > e) && (this.startTime = e), this.endTime = t, this.screen = i, this.handler.createHTMLCaptionsTrack(this.track) + } + } + var Yh = {}, + iu = {}, + nu = {}, + t = {}; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.isValidPercentValue = function(e) { + return "number" == typeof e && 0 <= e && e <= 100 + }, t.isValidAlignSetting = function(e) { + return "string" == typeof e && ["start", "center", "end", "left", "right", "middle"].includes(e) + }, t.isValidDirectionSetting = function(e) { + return "string" == typeof e && ["", "rl", "lr"].includes(e) + }, t.isValidLineAndPositionSetting = function(e) { + return "number" == typeof e || "auto" === e + }, t.isValidLineAlignSetting = function(e) { + return "string" == typeof e && ["start", "center", "end"].includes(e) + }, t.isValidPositionAlignSetting = function(e) { + return "string" == typeof e && ["line-left", "center", "line-right", "auto", "left", "start", "middle", "end", "right"].includes(e) + }, t.isValidScrollSetting = function(e) { + return ["", "up"].includes(e) + }; + ru = {}; + Object.defineProperty(ru, "__esModule", { + value: !0 + }); + const Jh = { + "&": "&", + "<": "<", + ">": ">", + "‎": "Ãĸâ‚ŦÅŊ", + "‏": "Ãĸâ‚Ŧ", + " ": " " + }, + Zh = { + c: "span", + i: "i", + b: "b", + u: "u", + ruby: "ruby", + rt: "rt", + v: "span", + lang: "span" + }, + ep = { + v: "title", + lang: "lang" + }, + tp = { + rt: "ruby" + }, + ip = { + "text-combine-upright": "-webkit-text-combine:horizontal; text-orientation: mixed;" + }; + class rp { + static parseTimeStamp(e) { + function t(e) { + var [t, i, r, e] = e.map(e => e ? parseInt("" + e) : 0); + return 3600 * t + 60 * i + r + e / 1e3 + } + const i = /^(\d+):(\d{2})(:\d{2})?\.(\d{3})/.exec(e); + return i ? i[3] ? t([i[1], i[2], i[3].substring(1), i[4]]) : 59 < parseInt(i[1]) ? t([i[1], i[2], null, i[4]]) : t([null, i[1], i[2], i[4]]) : null + } + static parseContent(s, t, a) { + let i = t.text; + + function e(e) { + return Jh[e] + } + const r = s.document.createElement("div"), + n = []; + let o, l, d = r; + for (; null !== (o = function() { + if (!i) return null; + var e = (e = /^([^<]*)(<[^>]+>?)?/.exec(i))[1] || e[2]; + return i = i.substr(e.length), e + }());) + if ("<" !== o[0]) d.appendChild(s.document.createTextNode(o.replace(/&(amp|lt|gt|lrm|rlm|nbsp);/g, e))); + else { + if ("/" === o[1]) { + n.length && n[n.length - 1] === o.substr(2).replace(">", "") && (n.pop(), d = d.parentNode); + continue + } + const t = rp.parseTimeStamp(o.substr(1, o.length - 2)); + let e; + if (t) { + e = s.document.createProcessingInstruction("timestamp", t.toString()), d.appendChild(e); + continue + } + if (!(l = /^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/.exec(o))) continue; + if (e = function(e, t, i) { + var r = Zh[e]; + if (!r) return null; + const n = s.document.createElement(r); + if (n.dataset.localName = r, (e = ep[e]) && i && (n[e] = i.trim()), t) + if (a[t]) { + const s = function(e) { + let t = ""; + for (const i in e) t += ip[i] || i + ":" + e[i] + ";"; + return t + }(a[t]); + n.setAttribute("style", s) + } else console.info(`WebVTT: parseContent: Style referenced, but no style defined for '${t}'!`); + return n + }(l[1], l[2], l[3]), !e) continue; + if (u = d, c = e, tp[c.dataset.localName] && tp[c.dataset.localName] !== u.dataset.localName) continue; + n.push(l[1]), d.appendChild(e), d = e + } var u, c; + return r + } + } + ru.default = rp; + w = e && e.__decorate || function(e, t, i, r) { + var n, s = arguments.length, + a = s < 3 ? t : null === r ? r = Object.getOwnPropertyDescriptor(t, i) : r; + if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) a = Reflect.decorate(e, t, i, r); + else + for (var o = e.length - 1; 0 <= o; o--)(n = e[o]) && (a = (s < 3 ? n(a) : 3 < s ? n(t, i, a) : n(t, i)) || a); + return 3 < s && a && Object.defineProperty(t, i, a), a + }; + Object.defineProperty(nu, "__esModule", { + value: !0 + }); + const np = t, + sp = ru; + w = w([function(e) { + let t = e; + return "undefined" != typeof window && null != window.VTTCue && (t = window.VTTCue, t.create = e.create, t.fromJSON = e.fromJSON, t.prototype.toJSON = e.prototype.toJSON), t + }], w = class { + constructor(e, t, i) { + this._id = "", this._pauseOnExit = !1, this._region = null, this._vertical = "", this._snapToLines = !0, this._line = "auto", this._lineAlign = "start", this._position = "auto", this._positionAlign = "auto", this._size = 100, this._align = "center", this.hasBeenReset = !1, this._startTime = e, this._endTime = t, this._text = i + } + get id() { + return this._id + } + set id(e) { + this._id = "" + e + } + get pauseOnExit() { + return this._pauseOnExit + } + set pauseOnExit(e) { + this._pauseOnExit = !!e + } + get startTime() { + return this._startTime + } + set startTime(e) { + if ("number" != typeof e) throw new TypeError(`Start time must be set to a number: ${e}`); + this._startTime = e, this.hasBeenReset = !0 + } + get endTime() { + return this._endTime + } + set endTime(e) { + if ("number" != typeof e) throw new TypeError(`End time must be set to a number: ${e}`); + this._endTime = e, this.hasBeenReset = !0 + } + get text() { + return this._text + } + set text(e) { + this._text = "" + e, this.hasBeenReset = !0 + } + get region() { + return this._region + } + set region(e) { + this._region = e, this.hasBeenReset = !0 + } + get vertical() { + return this._vertical + } + set vertical(e) { + if (!np.isValidDirectionSetting(e)) throw new SyntaxError(`An invalid or illegal string was specified for vertical: ${e}`); + this._vertical = e, this.hasBeenReset = !0 + } + get snapToLines() { + return this._snapToLines + } + set snapToLines(e) { + this._snapToLines = !!e, this.hasBeenReset = !0 + } + get line() { + return this._line + } + set line(e) { + if (!np.isValidLineAndPositionSetting(e)) throw new SyntaxError(`An invalid number or illegal string was specified for line: ${e}`); + this._line = e, this.hasBeenReset = !0 + } + get lineAlign() { + return this._lineAlign + } + set lineAlign(e) { + if (!np.isValidLineAlignSetting(e)) throw new SyntaxError(`An invalid or illegal string was specified for lineAlign: ${e}`); + this._lineAlign = e, this.hasBeenReset = !0 + } + get position() { + return this._position + } + set position(e) { + if (!np.isValidLineAndPositionSetting(e)) throw new Error(`Position must be between 0 and 100 or auto: ${e}`); + this._position = e, this.hasBeenReset = !0 + } + get positionAlign() { + return this._positionAlign + } + set positionAlign(e) { + if (!np.isValidPositionAlignSetting(e)) throw new SyntaxError(`An invalid or illegal string was specified for positionAlign: ${e}`); + this._positionAlign = e, this.hasBeenReset = !0 + } + get size() { + return this._size + } + set size(e) { + if (e < 0 || 100 < e) throw new Error(`Size must be between 0 and 100: ${e}`); + this._size = e, this.hasBeenReset = !0 + } + get align() { + return this._align + } + set align(e) { + if (!np.isValidAlignSetting(e)) throw new SyntaxError(`An invalid or illegal string was specified for align: ${e}`); + this._align = e, this.hasBeenReset = !0 + } + getCueAsHTML() { + return sp.default.parseContent(window, this, {}) + } + static create(t) { + if (!t.hasOwnProperty("startTime") || !t.hasOwnProperty("endTime") || !t.hasOwnProperty("text")) throw new Error("You must at least have start time, end time, and text."); + const i = new this(t.startTime, t.endTime, t.text); + return Object.keys(t).forEach(e => { + i.hasOwnProperty(e) && (i[e] = t[e]) + }), i + } + static fromJSON(e) { + return this.create(JSON.parse(e)) + } + toJSON() { + const t = {}; + return Object.keys(this).forEach(e => { + this.hasOwnProperty(e) && "getCueAsHTML" !== e && "hasBeenReset" !== e && "displayState" !== e && (t[e] = this[e]) + }), t + } + }); + nu.VTTCue = w; + w = {}, e = e && e.__decorate || function(e, t, i, r) { + var n, s = arguments.length, + a = s < 3 ? t : null === r ? r = Object.getOwnPropertyDescriptor(t, i) : r; + if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) a = Reflect.decorate(e, t, i, r); + else + for (var o = e.length - 1; 0 <= o; o--)(n = e[o]) && (a = (s < 3 ? n(a) : 3 < s ? n(t, i, a) : n(t, i)) || a); + return 3 < s && a && Object.defineProperty(t, i, a), a + }; + Object.defineProperty(w, "__esModule", { + value: !0 + }); + const ap = t; + e = e([function(e) { + let t = e; + return "undefined" != typeof window && null != window.VTTRegion && (t = window.VTTRegion, t.create = e.create, t.fromJSON = e.fromJSON, t.prototype.toJSON = e.prototype.toJSON), t + }], e = class { + constructor() { + this._id = "", this._lines = 3, this._regionAnchorX = 0, this._regionAnchorY = 100, this._scroll = "", this._viewportAnchorX = 0, this._viewportAnchorY = 100, this._width = 100 + } + get id() { + return this._id + } + set id(e) { + if ("string" != typeof e) throw new Error("ID must be a string."); + this._id = e + } + get lines() { + return this._lines + } + set lines(e) { + if ("number" != typeof e) throw new TypeError("Lines must be set to a number."); + this._lines = e + } + get regionAnchorX() { + return this._regionAnchorX + } + set regionAnchorX(e) { + if (!ap.isValidPercentValue(e)) throw new TypeError("RegionAnchorX must be between 0 and 100."); + this._regionAnchorX = e + } + get regionAnchorY() { + return this._regionAnchorY + } + set regionAnchorY(e) { + if (!ap.isValidPercentValue(e)) throw new TypeError("RegionAnchorY must be between 0 and 100."); + this._regionAnchorY = e + } + get scroll() { + return this._scroll + } + set scroll(e) { + if ("string" == typeof e) { + e = e.toLowerCase(); + if (ap.isValidScrollSetting(e)) return void(this._scroll = e) + } + throw new SyntaxError("An invalid or illegal string was specified.") + } + get viewportAnchorX() { + return this._viewportAnchorX + } + set viewportAnchorX(e) { + if (!ap.isValidPercentValue(e)) throw new TypeError("ViewportAnchorX must be between 0 and 100."); + this._viewportAnchorX = e + } + get viewportAnchorY() { + return this._viewportAnchorY + } + set viewportAnchorY(e) { + if (!ap.isValidPercentValue(e)) throw new TypeError("ViewportAnchorY must be between 0 and 100."); + this._viewportAnchorY = e + } + get width() { + return this._width + } + set width(e) { + if (!ap.isValidPercentValue(e)) throw new TypeError("Width must be between 0 and 100."); + this._lines = e + } + toJSON() { + const t = {}; + return Object.keys(this).forEach(e => { + this.hasOwnProperty(e) && (t[e] = this[e]) + }), t + } + static create(t) { + const i = new this; + return Object.keys(t).forEach(e => { + i.hasOwnProperty(e) && (i[e] = t[e]) + }), i + } + static fromJSON(e) { + return this.create(JSON.parse(e)) + } + }); + w.VTTRegion = e, Object.defineProperty(iu, "__esModule", { + value: !0 + }); + const op = nu; + iu.VTTCue = op.VTTCue; + const lp = w; + iu.VTTRegion = lp.VTTRegion; + const dp = ru; + class up extends Error { + constructor(e, t) { + super(), this.name = "ParsingError", this.code = "number" == typeof e ? e : e.code, t ? this.message = t : e instanceof up && (this.message = e.message) + } + }(iu.ParsingError = up).Errors = { + BadSignature: new up(0, "Malformed WebVTT signature."), + BadTimeStamp: new up(1, "Malformed time stamp.") + }; + class cp { + constructor() { + this.values = {} + } + set(e, t) { + this.get(e) || "" === t || (this.values[e] = t) + } + get(e, t, i) { + return "object" == typeof t && "string" == typeof i ? this.has(e) ? this.values[e] : t[i] : this.has(e) ? this.values[e] : t + } + has(e) { + return e in this.values + } + alt(t, i, r) { + for (let e = 0; e < r.length; ++e) + if (i === r[e]) { + this.set(t, i); + break + } + } + integer(e, t) { + /^-?\d+$/.test(t) && this.set(e, parseInt(t, 10)) + } + percent(e, t) { + if (t.match(/^([\d]{1,3})(\.[\d]*)?%$/)) try { + var i = parseFloat(t); + if (0 <= i && i <= 100) return this.set(e, i), !0 + } catch (e) { + return !1 + } + return !1 + } + } + class hp { + constructor(e, t, i) { + this.window = e, this.state = "INITIAL", this.styleCollector = "", this.buffer = "", this.decoder = t || new TextDecoder("utf8"), this.regionList = [], this.onStylesParsedCallback = i, this._styles = {} + } + static StringDecoder() { + return { + decode: e => { + if (!e) return ""; + if ("string" != typeof e) throw new Error("Error - expected string data."); + return decodeURIComponent(encodeURIComponent(e)) + } + } + } + reportOrThrowError(e) { + if (!(e instanceof up && "function" == typeof this.onparsingerror)) throw e; + this.onparsingerror(e) + } + parseOptions(e, t, i, r) { + e = r ? e.split(r) : [e]; + for (const n of e) + if ("string" == typeof n) { + const r = n.split(i); + 2 === r.length && t(r[0], r[1]) + } + } + parseCue(t, e, a) { + const i = t, + r = () => { + var e = dp.default.parseTimeStamp(t); + if (null === e) throw new up(up.Errors.BadTimeStamp, "Malformed timestamp: " + i); + return t = t.replace(/^[^\sa-zA-Z-]+/, ""), e + }, + n = () => { + t = t.replace(/^\s+/, "") + }; + if (n(), e.startTime = r(), n(), "--\x3e" !== t.substr(0, 3)) throw new up(up.Errors.BadTimeStamp, `Malformed time stamp (time stamps must be separated by '--\x3e'): ${i}`); + t = t.substr(3), n(), e.endTime = r(), n(), ((e, t) => { + const s = new cp; + this.parseOptions(e, (t, i) => { + let e, r; + switch (t) { + case "region": + for (let e = a.length - 1; 0 <= e; e--) + if (a[e].id === i) { + s.set(t, a[e].region); + break + } break; + case "vertical": + s.alt(t, i, ["rl", "lr"]); + break; + case "line": + e = i.split(","), r = e[0], s.integer(t, r), s.percent(t, r) && s.set("snapToLines", !1), s.alt(t, r, ["auto"]), 2 === e.length && s.alt("lineAlign", e[1], ["start", "center", "end"]); + break; + case "position": + e = i.split(","), s.percent(t, e[0]), 2 === e.length && (n = ["line-left", "line-right", "center", "auto", "left", "start", "middle", "end", "right"], s.alt("positionAlign", e[1], n)); + break; + case "size": + s.percent(t, i); + break; + case "align": + var n = ["start", "center", "end", "left", "right", "middle"]; + s.alt(t, i, n) + } + }, /:/, /\s/), t.region = s.get("region", null), t.vertical = s.get("vertical", ""), t.line = s.get("line", void 0 === t.line ? "auto" : t.line), t.lineAlign = s.get("lineAlign", "start"), t.snapToLines = s.get("snapToLines", !0), t.size = s.get("size", 100); + e = s.get("align", "center"); + t.align = "middle" === e ? "center" : e, t.position = s.get("position", "auto"); + e = s.get("positionAlign", { + start: "start", + left: "start", + center: "center", + right: "end", + end: "end" + }, t.align); + t.positionAlign = { + start: "start", + "line-left": "start", + left: "start", + center: "center", + middle: "center", + "line-right": "end", + right: "end", + end: "end" + } [e] + })(t, e) + } + parseRegion(e) { + const n = new cp; + if (this.parseOptions(e, (e, t) => { + switch (e) { + case "id": + n.set(e, t); + break; + case "width": + n.percent(e, t); + break; + case "lines": + n.integer(e, t); + break; + case "regionanchor": + case "viewportanchor": { + var i = t.split(","); + if (2 !== i.length) break; + const r = new cp; + if (r.percent("x", i[0]), r.percent("y", i[1]), !r.has("x") || !r.has("y")) break; + n.set(e + "X", r.get("x")), n.set(e + "Y", r.get("y")); + break + } + case "scroll": + n.alt(e, t, ["up"]) + } + }, /=/, /\s/), n.has("id")) { + const e = new lp.VTTRegion; + e.width = n.get("width", 100), e.lines = n.get("lines", 3), e.regionAnchorX = n.get("regionanchorX", 0), e.regionAnchorY = n.get("regionanchorY", 100), e.viewportAnchorX = n.get("viewportanchorX", 0), e.viewportAnchorY = n.get("viewportanchorY", 100), e.scroll = n.get("scroll", ""), this.onregion && this.onregion(e), this.regionList.push({ + id: n.get("id"), + region: e + }) + } + } + parseStyle(i) { + const e = i.split("}"); + e.pop(); + for (const i of e) { + let e = null, + t = null; + const r = i.split("{"); + r[0] && (e = r[0].trim()), r[1] && (t = (e => { + const t = {}, + i = e.split(";"); + for (let e = 0; e < i.length; e++) + if (i[e].includes(":")) { + const r = i[e].split(":", 2), + n = r[0].trim(), + s = r[1].trim(); + "" !== n && "" !== s && (t[n] = s) + } return t + })(r[1])), e && t && (this._styles[e] = t) + } + this.onStylesParsedCallback && this.onStylesParsedCallback(this._styles) + } + parseHeader(e) { + this.parseOptions(e, function(e, t) { + "Region" === e && this.parseRegion(t) + }, /:/) + } + parse(i) { + i && (this.buffer += this.decoder.decode(i, { + stream: !0 + })); + const r = () => { + const e = this.buffer; + let t = 0; + let i = { + start: e.length, + length: 0 + }; + for (; t < e.length;) { + const r = ((t, i) => { + const r = { + start: -1, + length: -1 + }; + if ("\r" === t[i]) r.start = i, r.length = 1; + else if ("\n" === t[i]) r.start = i, r.length = 1; + else if ("<" === t[i] && i + 1 < t.length && "b" === t[i + 1] && i + 2 < t.length && "r" === t[i + 2]) { + let e = i + 2; + for (; e < t.length && ">" !== t[e++];); + r.start = i, r.length = e - i + } + return r + })(e, t); + if (0 < r.length) { + i = r; + break + }++t + } + const r = e.substr(0, i.start); + return this.buffer = e.substr(i.start + i.length), r + }; + try { + let e; + if ("INITIAL" === this.state) { + if (!/\r\n|\n/.test(this.buffer)) return this; + e = r(); + var n = /^(ïÂÂģÂÂŋ)?WEBVTT([ \t].*)?$/.exec(e); + if (!n || !n[0]) throw new up(up.Errors.BadSignature); + this.state = "HEADER" + } + let t = !1; + for (; this.buffer;) { + if (!/\r\n|\n/.test(this.buffer)) return this; + switch (t ? t = !1 : e = r(), this.state) { + case "HEADER": + e.includes(":") ? this.parseHeader(e) : e || (this.state = "ID"); + continue; + case "NOTE": + e || (this.state = "ID"); + continue; + case "STYLE": + e ? this.styleCollector += e : (this.parseStyle(this.styleCollector), this.state = "ID", this.styleCollector = ""); + continue; + case "ID": + if (/^NOTE($|[ \t])/.test(e)) { + this.state = "NOTE"; + break + } + if (/^STYLE($|[ \t])/.test(e)) { + this.state = "STYLE"; + break + } + if (!e) continue; + if (this.cue = new op.VTTCue(0, 0, ""), this.state = "CUE", !e.includes("--\x3e")) { + this.cue.id = e; + continue + } + case "CUE": + try { + this.parseCue(e, this.cue, this.regionList) + } catch (i) { + this.reportOrThrowError(i), this.cue = null, this.state = "BADCUE"; + continue + } + this.state = "CUETEXT"; + continue; + case "CUETEXT": { + const r = e.includes("--\x3e"); + if (!e || r) { + t = !0, this.oncue && this.oncue(this.cue), this.cue = null, this.state = "ID"; + continue + } + this.cue.text && (this.cue.text += "\n"), this.cue.text += e; + continue + } + case "BADCUE": + e || (this.state = "ID"); + continue + } + } + } catch (i) { + this.reportOrThrowError(i), "CUETEXT" === this.state && this.cue && this.oncue && this.oncue(this.cue), this.cue = null, this.state = "INITIAL" === this.state ? "BADWEBVTT" : "BADCUE" + } + return this + } + flush() { + try { + if (this.buffer += this.decoder.decode(), !this.cue && "HEADER" !== this.state || (this.buffer += "\n\n", this.parse()), "INITIAL" === this.state) throw new up(up.Errors.BadSignature) + } catch (e) { + this.reportOrThrowError(e) + } + return this.onflush && this.onflush(), this + } + styles() { + return this._styles + } + } + iu.default = hp, iu.WebVTTParser = hp; + var pp, w = {}; + Object.defineProperty(w, "__esModule", { + value: !0 + }); + const fp = nu; + w.VTTCue = fp.VTTCue; + const mp = ru, + gp = [/^(::cue\()(\..*)(\))/, /^(::cue\()(#.*)(\))/, /^(::cue\()(c|i|b|u|ruby|rt|v|lang)(\))/], + yp = [ + [1470, 1470], + [1472, 1472], + [1475, 1475], + [1478, 1478], + [1488, 1514], + [1520, 1524], + [1544, 1544], + [1547, 1547], + [1549, 1549], + [1563, 1563], + [1566, 1610], + [1645, 1647], + [1649, 1749], + [1765, 1766], + [1774, 1775], + [1786, 1805], + [1807, 1808], + [1810, 1839], + [1869, 1957], + [1969, 1969], + [1984, 2026], + [2036, 2037], + [2042, 2042], + [2048, 2069], + [2074, 2074], + [2084, 2084], + [2088, 2088], + [2096, 2110], + [2112, 2136], + [2142, 2142], + [2208, 2208], + [2210, 2220], + [8207, 8207], + [64285, 64285], + [64287, 64296], + [64298, 64310], + [64312, 64316], + [64318, 64318], + [64320, 64321], + [64323, 64324], + [64326, 64449], + [64467, 64829], + [64848, 64911], + [64914, 64967], + [65008, 65020], + [65136, 65140], + [65142, 65276], + [67584, 67589], + [67592, 67592], + [67594, 67637], + [67639, 67640], + [67644, 67644], + [67647, 67669], + [67671, 67679], + [67840, 67867], + [67872, 67897], + [67903, 67903], + [67968, 68023], + [68030, 68031], + [68096, 68096], + [68112, 68115], + [68117, 68119], + [68121, 68147], + [68160, 68167], + [68176, 68184], + [68192, 68223], + [68352, 68405], + [68416, 68437], + [68440, 68466], + [68472, 68479], + [68608, 68680], + [126464, 126467], + [126469, 126495], + [126497, 126498], + [126500, 126500], + [126503, 126503], + [126505, 126514], + [126516, 126519], + [126521, 126521], + [126523, 126523], + [126530, 126530], + [126535, 126535], + [126537, 126537], + [126539, 126539], + [126541, 126543], + [126545, 126546], + [126548, 126548], + [126551, 126551], + [126553, 126553], + [126555, 126555], + [126557, 126557], + [126559, 126559], + [126561, 126562], + [126564, 126564], + [126567, 126570], + [126572, 126578], + [126580, 126583], + [126585, 126588], + [126590, 126590], + [126592, 126601], + [126603, 126619], + [126625, 126627], + [126629, 126633], + [126635, 126651], + [1114109, 1114109] + ]; + class vp { + applyStyles(e, t) { + t = t || this.div; + for (const i in e) e.hasOwnProperty(i) && (t.style[i] = e[i]) + } + formatStyle(e, t) { + return 0 === e ? "0" : e + t + } + } + w.StyleBox = vp; + class Sp extends vp { + constructor(e, t, i, r, n) { + super(); + let s = { + textAlign: { + start: "left", + "line-left": "left", + left: "left", + center: "center", + middle: "center", + "line-right": "right", + right: "right", + end: "right" + } [(this.cue = t).positionAlign] || t.align, + whiteSpace: "pre-line", + position: "absolute" + }; + s.direction = this.determineBidi(this.cueDiv), s.writingMode = this.directionSettingToWritingMode(t.vertical), s.unicodeBidi = "plaintext", this.div = e.document.createElement("div"), this.applyStyles(s), s = { + backgroundColor: r.backgroundColor, + display: "inline-block" + }, this.parseOpacity(s.backgroundColor) && (s.padding = "5px", s.borderRadius = "5px"), this.backgroundDiv = e.document.createElement("div"), this.applyStyles(s, this.backgroundDiv), s = { + color: i.color, + backgroundColor: i.backgroundColor, + textShadow: i.textShadow, + fontSize: i.fontSize, + fontFamily: i.fontFamily, + position: "relative", + left: "0", + right: "0", + top: "0", + bottom: "0", + display: "inline-block", + textOrientation: "upright" + }, s.writingMode = this.directionSettingToWritingMode(t.vertical), s.unicodeBidi = "plaintext", this.cueDiv = mp.default.parseContent(e, t, n), this.applyStyles(s, this.cueDiv), this.backgroundDiv.appendChild(this.cueDiv), this.div.appendChild(this.backgroundDiv); + let a = 0; + if ("number" == typeof t.position) { + n = t.positionAlign || t.align; + if (n) switch (n) { + case "start": + case "left": + a = t.position; + break; + case "center": + case "middle": + a = t.position - t.size / 2; + break; + case "end": + case "right": + a = t.position - t.size + } + } + "" === t.vertical ? this.applyStyles({ + left: this.formatStyle(a, "%"), + width: this.formatStyle(t.size, "%") + }) : this.applyStyles({ + top: this.formatStyle(a, "%"), + height: this.formatStyle(t.size, "%") + }) + } + determineBidi(e) { + let t = [], + i = ""; + if (!e || !e.childNodes) return "ltr"; + + function n(t, i) { + for (let e = i.childNodes.length - 1; 0 <= e; e--) t.push(i.childNodes[e]) + } + for (n(t, e); i = function e(t) { + if (!t || !t.length) return null; + let i = t.pop(), + r = i.textContent || i.innerText; + if (r) { + const i = /^.*(\n|\r)/.exec(r); + return i ? i[t.length = 0] : r + } + return "ruby" === i.tagName ? e(t) : i.childNodes ? (n(t, i), e(t)) : void 0 + }(t);) + for (let e = 0; e < i.length; e++) + if (function(e, t) { + for (const i of t) + if (e >= i[0] && e <= i[1]) return 1 + }(i.charCodeAt(e), yp)) return "rtl"; + return "ltr" + } + parseOpacity(e) { + if (!e || "string" != typeof e) return null; + e = (e = e.replace(/ /g, "").replace("rgba(", "").replace(")", "")).split(","); + return e && 4 <= e.length ? e[3] : null + } + directionSettingToWritingMode(e) { + return "" === e ? "horizontal-tb" : "lr" === e ? "vertical-lr" : "vertical-rl" + } + move(e) { + this.applyStyles({ + top: this.formatStyle(e.top, "px"), + bottom: this.formatStyle(e.bottom, "px"), + left: this.formatStyle(e.left, "px"), + right: this.formatStyle(e.right, "px"), + height: this.formatStyle(e.height, "px"), + width: this.formatStyle(e.width, "px") + }) + } + } + w.CueStyleBox = Sp; + class bp { + constructor(e) { + var t; + let i, r, n, s, a, o; + if (e instanceof Sp && e.cue ? (t = e.cue) && "" !== t.vertical ? this.property = "width" : this.property = "height" : e instanceof bp && (this.property = e.property || "height"), e instanceof Sp && e.div) { + n = e.div.offsetHeight, s = e.div.offsetWidth, a = e.div.offsetTop; + const t = e.div.firstChild; + if (o = (t || e.div).getBoundingClientRect(), i = o && o[this.property] || null, t && t.firstChild) { + const e = t.firstChild; + e && "string" == typeof e.textContent && (r = i / this.calculateNewLines(e.textContent)) + } + } else e instanceof bp && (o = e); + this.left = o.left, this.right = o.right, this.top = o.top || a, this.height = o.height || n, this.bottom = o.bottom || a + (o.height || n), this.width = o.width || s, this.lineHeight = null !== i ? i : o.lineHeight, this.singleLineHeight = null !== r ? r : o.singleLineHeight, this.singleLineHeight || (this.singleLineHeight = 41) + } + calculateNewLines(t) { + let i = 1; + for (let e = 0; e < t.length; e++) "\n" === t[e] && i++; + return i + } + move(e, t) { + switch (t = void 0 !== t ? t : this.singleLineHeight, e) { + case "+x": + this.left += t, this.right += t; + break; + case "-x": + this.left -= t, this.right -= t; + break; + case "+y": + this.top += t, this.bottom += t; + break; + case "-y": + this.top -= t, this.bottom -= t + } + } + overlaps(e) { + return this.left < e.right && this.right > e.left && this.top < e.bottom && this.bottom > e.top + } + overlapsAny(e) { + for (const t of e) + if (this.overlaps(t)) return !0; + return !1 + } + within(e) { + return this.top >= e.top && this.bottom <= e.bottom && this.left >= e.left && this.right <= e.right + } + moveIfOutOfBounds(e, t) { + switch (t) { + case "+x": + this.left < e.left && (this.left = e.left, this.right = this.left + this.width); + break; + case "-x": + this.right > e.right && (this.right = e.right, this.left = this.right - this.width); + break; + case "+y": + this.top < e.top && (this.top = e.top, this.bottom = this.top + this.height); + break; + case "-y": + this.bottom > e.bottom && (this.bottom = e.bottom, this.top = this.bottom - this.height) + } + } + toCSSCompatValues(e) { + return { + top: this.top - e.top, + bottom: e.bottom - this.bottom, + left: this.left - e.left, + right: e.right - this.right, + height: this.height, + width: this.width + } + } + static getSimpleBoxPosition(e) { + let t = null; + e instanceof vp && e.div ? t = e.div : e instanceof HTMLElement && (t = e); + let i = t.offsetHeight || 0, + r = t.offsetWidth || 0, + n = t.offsetTop || 0, + s = n + i, + a = t.getBoundingClientRect(); + var { + left: o, + right: e + } = a; + return a.top && (n = a.top), a.height && (i = a.height), a.width && (r = a.width), a.bottom && (s = a.bottom), { + left: o, + right: e, + top: n, + height: i, + bottom: s, + width: r + } + } + static getBoxPosition(r, n) { + if (r && 0 < r.length) { + let t = 0, + i = r[0][n]; + for (let e = 0; e < r.length; e++) n in ["top", "right"] ? r[e][n] > i && (t = e, i = r[e][n]) : n in ["bottom", "left"] && r[e][n] < i && (t = e, i = r[e][n]); + return r[t] + } + return null + } + static moveToMinimumDistancePlacement(e, t, i) { + "height" === e.property ? "+y" === t ? (e.top = i.topMostBoxPosition.bottom + 0, e.bottom = e.top + e.height) : "-y" === t && (e.bottom = +i.bottomMostBoxPosition.top, e.top = e.bottom - e.height) : "width" === e.property && ("+x" === t ? (e.left = i.rightMostBoxPosition.right + 0, e.right = e.left + e.width) : "-x" === t && (e.right = +i.leftMostBoxPosition.left, e.left = e.right - e.width)) + } + static moveBoxToLinePosition(e, a, o) { + var n = e.cue; + let i, r = new bp(e), + s = function() { + if ("number" == typeof n.line && (n.snapToLines || 0 <= n.line && n.line <= 100)) return n.line; + if (!n.track || !n.track.textTrackList || !n.track.textTrackList.mediaElement) return -1; + let t = 0; + var i = n.track, + r = i.textTrackList; + for (let e = 0; e < r.length && r[e] !== i; e++) "showing" === r[e].mode && t++; + return -1 * ++t + }(), + l = []; + if (n.snapToLines) { + let t = 0; + switch (n.vertical) { + case "": + l = ["+y", "-y"], i = "height"; + break; + case "rl": + l = ["+x", "-x"], i = "width"; + break; + case "lr": + l = ["-x", "+x"], i = "width" + } + const o = r.lineHeight, + d = a[i] + o, + u = l[0]; + if (s < 0) { + let e = 0; + switch (n.vertical) { + case "": + e = a.height - o - .05 * a.height; + break; + case "rl": + case "lr": + e = -a.width + o + .05 * a.width + } + t = e, l = l.reverse() + } else { + switch (n.vertical) { + case "": + t = o * Math.round(s); + break; + case "rl": + t = a.width - o * Math.round(s); + break; + case "lr": + t = o * Math.round(s) + } + Math.abs(t) > d && (t = t < 0 ? -1 : 1, t *= Math.ceil(d / o) * o) + } + r.move(u, t) + } else { + const o = "" === n.vertical ? a.height : a.width, + i = r.lineHeight / o * 100; + switch (n.lineAlign) { + case "center": + s -= i / 2; + break; + case "end": + s -= i + } + switch (n.vertical) { + case "": + e.applyStyles({ + top: e.formatStyle(s, "%") + }); + break; + case "rl": + e.applyStyles({ + right: e.formatStyle(s, "%") + }); + break; + case "lr": + e.applyStyles({ + left: e.formatStyle(s, "%") + }) + } + l = ["+y", "-y", "+x", "-x"], "+y" === n.axis ? l = ["+y", "-y", "+x", "-x"] : "-y" === n.axis && (l = ["-y", "+y", "+x", "-x"]), r = new bp(e) + } + const d = function(r, n) { + let s; + for (let i = 0; i < n.length; i++) { + r.moveIfOutOfBounds(a, n[i]); + let e = 0, + t = !1; + for (; r.overlapsAny(o) && !(9 < e);) t ? r.move(n[i]) : (o && 0 < o.length && (s = s || { + topMostBoxPosition: bp.getBoxPosition(o, "top"), + bottomMostBoxPosition: bp.getBoxPosition(o, "bottom"), + leftMostBoxPosition: bp.getBoxPosition(o, "left"), + rightMostBoxPosition: bp.getBoxPosition(o, "right") + }, bp.moveToMinimumDistancePlacement(r, n[i], s)), t = !0), e++ + } + return r + }(r, l); + e.move(d.toCSSCompatValues(a)) + } + } + w.BoxPosition = bp; + class Tp { + constructor(e, t, i = !0) { + if (!e) return null; + this.window = e, this.overlay = t, this.loggingEnabled = i, this.foregroundStyleOptions = { + fontFamily: "Helvetica", + fontSize: "36px", + color: "rgba(255, 255, 255, 1)", + textShadow: "", + backgroundColor: "rgba(0, 0, 0, 0)" + }, this.backgroundStyleOptions = { + backgroundColor: "rgba(0, 0, 0, 0.5)" + }, this.globalStyleCollection = {}; + const r = e.document.createElement("div"); + r.style.position = "absolute", r.style.left = "0", r.style.right = "0", r.style.top = "0", r.style.bottom = "0", r.style.margin = "1.5%", this.paddedOverlay = r, t.appendChild(this.paddedOverlay), this.initSubtitleCSS() + } + initSubtitleCSS() { + var e = [new fp.VTTCue(0, 0, "String to init CSS - Won't be visible to user")]; + this.paddedOverlay.style.opacity = "0", this.processCues(e), this.processCues([]), this.paddedOverlay.style.opacity = "1" + } + convertCueToDOMTree(e) { + return e ? mp.default.parseContent(this.window, e, this.globalStyleCollection) : null + } + setStyles(i) { + function r(e, t, i) { + for (const r in t) t.hasOwnProperty(r) && (!0 === i && void 0 !== e[r] || !1 === i) && (e[r] = t[r]) + } + for (const a in i) { + let t = !1, + e = null; + "::cue" === a ? (e = this.foregroundStyleOptions, t = !0) : "::-webkit-media-text-track-display" === a && (e = this.backgroundStyleOptions, t = !0); + var n = i[a]; + if (!0 === t) r(e, n, t); + else + for (let e = 0; e < gp.length; e++) { + var s = gp[e].exec(a); + if (s && 4 === s.length) { + const i = s[2], + o = {}; + r(o, n, t), this.globalStyleCollection[i] = o + } + } + } + this.initSubtitleCSS(), this.loggingEnabled && (console.log("WebVTTRenderer setStyles foregroundStyleOptions: " + JSON.stringify(this.foregroundStyleOptions)), console.log("WebVTTRenderer setStyles backgroundStyleOptions: " + JSON.stringify(this.backgroundStyleOptions)), console.log("WebVTTRenderer setStyles globalStyleCollection: " + JSON.stringify(this.globalStyleCollection))) + } + processCues(r) { + if (r) { + for (; this.paddedOverlay.firstChild;) this.paddedOverlay.removeChild(this.paddedOverlay.firstChild); + if (function(t) { + for (let e = 0; e < t.length; e++) + if (t[e].hasBeenReset || !t[e].displayState) return 1 + }(r)) { + const n = [], + s = bp.getSimpleBoxPosition(this.paddedOverlay); + 1 < r.length && (r = function(t) { + const i = []; + let r = 0; + for (let e = 0; e < t.length; e++) { + var n = t[e]; + if ("number" != typeof n.line) return t; + r += n.line, i.push(n) + } + return r /= t.length, 50 < r ? (i.forEach(function(e) { + e.axis = "-y" + }), i.sort((e, t) => t.line - e.line)) : (i.forEach(function(e) { + e.axis = "+y" + }), i.sort((e, t) => e.line - t.line)), i + }(r)); + for (let i = 0; i < r.length; i++) { + let e = r[i], + t = new Sp(this.window, e, this.foregroundStyleOptions, this.backgroundStyleOptions, this.globalStyleCollection); + this.paddedOverlay.appendChild(t.div), bp.moveBoxToLinePosition(t, s, n), e.displayState = t.div, n.push(bp.getSimpleBoxPosition(t)) + } + } else + for (let e = 0; e < r.length; e++) this.paddedOverlay.appendChild(r[e].displayState) + } + } + setSize(e, t) { + e && (this.overlay.style.width = e + "px"), t && (this.overlay.style.height = t + "px") + } + getOverlay() { + return this.overlay + } + } + + function Ep(e) { + for (var t in e) pp.hasOwnProperty(t) || (pp[t] = e[t]) + } + w.default = Tp, w.WebVTTRenderer = Tp, pp = Yh, Object.defineProperty(pp, "__esModule", { + value: !0 + }), Ep(iu), Ep(w); + + function Ip(e, t, i) { + return e.substr(i || 0, t.length) === t + } + + function wp(e) { + let t = 5381, + i = e.length; + for (; i;) t = 33 * t ^ e.charCodeAt(--i); + return (t >>> 0).toString() + } + + function Ap(e) { + var t = Math.floor(e), + i = t + .5, + r = t + 1; + return i <= e ? r - e <= e - i ? r : i : i - e <= e - t ? i : t + } + + function Op(e, t = 0, i = 8589934592) { + if (!Number.isFinite(t)) return e; + var r = i / 2, + n = Math.abs(e - t) % i; + return t + (t < e ? -1 : 1) * (r < n ? i - n : -n) + } + var kp, Cp, Dp, Mp = function(e, t, i, r, n, s, a, o) { + const l = O.utf8arrayToStr(new Uint8Array(e)).trim().replace(/\r\n|\n\r|\n|\r/g, "\n").split("\n"), + d = { + baseTime: Math.floor(9e4 * t.baseTime / t.timescale), + timescale: 9e4 + }; + let u = 0, + c = 0; + const h = []; + let p = null, + f = !0; + const m = new Yh.WebVTTParser(window, Yh.WebVTTParser.StringDecoder(), a); + m.oncue = function(e) { + var t = S({ + baseTime: Op(Op(u) - d.baseTime, 9e4 * i), + timescale: 9e4 + }); + e.startTime = Op(e.startTime + t - c, 0, 95443.7176888889), e.endTime = Op(e.endTime + t - c, 0, 95443.7176888889), e.id = wp(Ap(e.startTime).toString()) + wp(Ap(e.endTime - e.startTime).toString()) + wp(e.text), e.text = decodeURIComponent(encodeURIComponent(e.text)), 0 < e.endTime && h.push(e) + }, m.onparsingerror = function(e) { + p = e + }, m.onflush = function() { + p && s ? s(p) : n(h) + }, l.forEach(a => f && Ip(a, "X-TIMESTAMP-MAP=") ? (f = !1, void a.substr(16).split(",").forEach(e => { + if (Ip(e, "LOCAL:")) { + let t; + try { + t = (i = e.substr(6), r = parseInt(i.substr(-3)), n = parseInt(i.substr(-6, 2)), s = parseInt(i.substr(-9, 2)), i = 9 < i.length ? parseInt(i.substr(0, i.indexOf(":"))) : 0, ne(r) && ne(n) && ne(s) && ne(i) ? (r += 1e3 * n, r += 6e4 * s, r += 36e5 * i) : -1) + } catch (e) { + t = -1 + } - 1 !== t ? c = t / 1e3 : p = new Error(`Malformed X-TIMESTAMP-MAP: ${a}`) + } else Ip(e, "MPEGTS:") && (u = parseInt(e.substr(7))); + var i, r, n, s + })) : void m.parse(a + "\n")), m.flush() + }, + xp = { + newCue: function(e, t, i, r, n) { + let s, a, o, l, d; + var u, c, h = { + foreground: !1, + background: !1, + italics: !1, + underline: !1, + flash: !1, + styleStack: [] + }; + for ([u, c] of r.rows.entries()) + if (a = !0, o = 0, l = "", !c.isEmpty()) { + for (let e = 0; e < c.chars.length; e++) c.chars[e].uchar.match(/\s/) && a ? o++ : (l += this.getFormattedChar(c.chars[e], h), a = !1); + (c.cueStartTime = t) === i && (i += 1e-4), l = l.trim().replace(//gi, "\n"), l += this.closeStyles(h), s = new Yh.VTTCue(t, i, l), 16 <= o ? o-- : o++, d = !navigator.userAgent.match(/Firefox\//) && 7 < u ? u : u + 1, s.snapToLines = !1, s.line = 10 + 5.33 * d, s.align = "left", s.position = this.getPosition(o, n), e.addCue(s) + } + }, + getPosition: function(e, t) { + let i = 1.3333333333333333; + t && t.offsetWidth && t.offsetHeight && 1.6 <= t.offsetWidth / t.offsetHeight && (i = 1.7777777777777777); + let r = 10 + e / 32 * 80, + n = 10, + s = 90; + return 1.7777777777777777 === i && (r = 12.5 + .75 * r, n = 20, s = 80), Math.max(n, Math.min(s, r + (navigator.userAgent.match(/Firefox\//) ? 50 : 0))) + }, + getRootStyleTag: function(e) { + var t = e[0]; + return "c" === t ? t : e + }, + closeStyles: function(t) { + let i = ""; + for (let e = t.styleStack.length - 1; 0 <= e; --e) i += "", t.styleStack.pop(); + return i + }, + beginStyleAndBalance: function(e, t) { + let i = ""; + return "c" === t[0] && (i += this.closeStyleAndBalance(e, "c")), i += "<" + t + ">", e.styleStack.push(t), i + }, + closeStyleAndBalance: function(t, i) { + var r = t.styleStack.length; + let n = 0, + s = ""; + for (let e = r - 1; 0 <= e; --e) { + var a = t.styleStack[e], + o = this.getRootStyleTag(a); + if (i[0] === a[0]) { + s += "", t.styleStack.splice(r - 1 - n); + break + } + "c" === o[0] ? (t.background = "", t.foreground = "", t.flash = !1, s += "") : "u" === o[0] ? (t.underline = !1, s += "") : "i" === o[0] && (t.italics = !1, s += ""), n++ + } + return s + }, + getFormattedChar: function(e, t) { + let i = "", + r = e.uchar, + n = ""; + var s = e.penState.foreground !== t.foreground, + a = e.penState.background !== t.background, + o = e.penState.flash !== t.flash; + return (s || a || o) && (n = "." + e.penState.foreground, n += ".bg_" + e.penState.background, e.penState.flash && o && (n += ".blink"), e.penState.foreground || e.penState.background || e.penState.blink ? i += this.beginStyleAndBalance(t, "c" + n) : i += this.closeStyleAndBalance(t, "c"), s && (t.foreground = e.penState.foreground), a && (t.background = e.penState.background), o && (t.flash = e.penState.flash)), e.penState.underline !== t.underline && (i += e.penState.underline ? this.beginStyleAndBalance(t, "u") : this.closeStyleAndBalance(t, "u"), t.underline = e.penState.underline), e.penState.italics !== t.italics && (i += e.penState.italics ? this.beginStyleAndBalance(t, "i") : this.closeStyleAndBalance(t, "i"), t.italics = e.penState.italics), i + r + } + }; + (w = kp = kp || {}).CloseEnough = "CloseEnough", w.TooFar = "TooFar", w.Unknown = "Unknown"; + const Pp = e => "cc1" === e || "cc2" === e; + + function Rp(t) { + const i = []; + for (let e = 0; e < t.length; e++) { + var r = t[e]; + ("captions" === r.kind || "subtitles" === r.kind || "metadata" === r.kind && r.customTextTrackCueRenderer) && i.push(r) + } + return i + } + + function Lp(e) { + if (e && e.cues) + for (; 0 < e.cues.length;) e.removeCue(e.cues[0]) + } + class _p extends $t { + constructor(e, t, i, r) { + super(e => { + const t = Oc(this.hls, this); + if (e.add(t.event(x.INLINE_STYLES_PARSED, this.onInlineStylesParsed).pipe(Vs(() => this.destroy())).subscribe()), e.add(bn(0, this.config.trottleCheckInterval).pipe(La(() => (this.checkReadyToLoadNextSubtitleFragment(), Wu))).subscribe()), this.config.nativeTextTrackChangeHandling) + if (this.mediaSink.textTracks && "onchange" in this.mediaSink.textTracks) { + const t = Oc(this.mediaSink.textTracks, this); + e.add(t.event("change", this._onTextTracksChanged).subscribe()) + } else e.add(bn(0, 500).pipe(La(() => (this._onTextTracksChanged(), Wu))).subscribe()) + }), this.config = t, this.hls = i, this.logger = r.child({ + name: "legible" + }), this.mediaSink = e, this.id3Track = e.id3TextTrack, this.enableCaption = !0, this.Cues = xp, this.tracks = [], this.cueRanges = [], this.channelToTrackMap = {}, this.htmlTextTrackMap = new Map, this.lastCueEndTime = 0, this.gotTracks = !1, this.tryAgain$ = new yi(!0), this.needNextSubtitle$ = new yi(!0) + } + destroy() { + Lp(this.textTrack1), Lp(this.textTrack2), this.mediaSink = void 0, this.nativeSubtitleTrackChange$ = void 0 + } + convertCuesIntoSubtitleFragInfo(t) { + const i = {}; + if (null != t && 0 < t.length) + for (let e = 0; e < t.length; e++) { + var r = t[e]; + if (ne(r.fragSN)) { + const n = i[r.fragSN]; + n ? (n.count++, n.startTime = Math.min(r.startTime, n.startTime), n.endTime = Math.max(r.endTime, n.endTime)) : i[r.fragSN] = { + count: 1, + startTime: r.startTime, + endTime: r.endTime + } + } + } + return i + } + checkReadyToLoadNextSubtitleFragment() { + let e = !1; + this.mediaSink.mediaQuery.currentTime >= this.lastCueEndTime - this.config.subtitleLeadTime && (e = !0), this.needNextSubtitle$.next(e) + } + checkReadyToLoadNextSubtitleFragment$(e, t) { + return e.mediaSeqNum === (null === (t = t[0]) || void 0 === t ? void 0 : t.mediaSeqNum) ? $i(!0) : (this.checkReadyToLoadNextSubtitleFragment(), this.needNextSubtitle$) + } + getNextFragment(e, t) { + t = t.mediaSeqNum + 1; + return t < e.fragments.length ? e.fragments[t - e.startSN] : null + } + calculateFragInfoMap(e, t, i, r) { + var n = this.convertCuesIntoSubtitleFragInfo(t); + let s = { + len: 0, + start: e, + end: e + }, + a = e, + o = e, + l = null, + d = null; + for (const t in n) + if (Object.prototype.hasOwnProperty.call(n, t)) { + var u = Number(t); + if (ne(u)) { + var c = n[u]; + if (this.isFragmentCompleteOrEmpty(u, c.count, i)) + if (u === r.startSN && e < c.startTime && (a = o = s.start = s.end = e = c.startTime), e >= c.startTime && (a === e || ne(l) && 1 < u - l) && (a = o = c.startTime), e >= c.startTime) o = c.endTime, l = u; + else { + if (!ne(l) || u - l != 1) { + d = u; + break + } + o = c.endTime, l = u + } + } else this.logger.warn(`$fragInfoMap has invalid key ${u}`) + } return s = { + len: o - a, + start: a, + end: o + }, { + fragInfoMap: n, + bufferInfo: s, + prevFragSN: l, + nextFragSN: d + } + } + findFrags$(t, i) { + return this.tryAgain$.pipe(ji(tr), La(() => { + var e = this.findFragmentsForPosition(this.mediaSink.mediaQuery.currentTime, i, t); + return e.foundFrags ? (this.lastCueEndTime = 0, this.needNextSubtitle$.next(!0), $i(e)) : Ii + })) + } + reviewParsedFrag(e, i, r) { + var n = e.frag, + s = e.cueRange, + t = i.subtitleBufferInfo, + a = i.subtitleParsedInfo, + o = this.mediaSink.mediaQuery.currentTime, + e = i.foundFrags; + let l = !0; + if (n.mediaSeqNum === e[0].mediaSeqNum) { + if (!i.timelineEstablished) return kp.TooFar; + if (!s) return this.logger.warn(`[subtitle] 1st frag sn ${n.mediaSeqNum} has no cue; details ${r.fragments.length} frags`), kp.Unknown; + if (s.startTime < o) { + const d = r.fragments, + i = n.mediaSeqNum - r.startSN; + let e = i, + t = s.startTime; + for (; e < d.length && (t += d[e].duration, !(t >= o)); ++e); + l = e - i + 1 <= this.config.earlyFragTolerance + } else if (s.startTime > o && n.mediaSeqNum !== r.startSN) { + const d = s.startTime - o, + i = t.prevFragSN; + l = n.mediaSeqNum === i + 1 && (null === (t = t.fragInfoMap[i]) || void 0 === t ? void 0 : t.count) === (null === (a = a[i]) || void 0 === a ? void 0 : a.count) || d <= this.config.lateTolerance + } + } + return l ? kp.CloseEnough : kp.TooFar + } + isFragmentEmpty(e) { + return e && !ne(e.startTime) && 0 === e.count + } + isFragmentCompleteOrEmpty(e, t, i) { + e = i ? i[e] : null; + return (null == e ? void 0 : e.count) === t || this.isFragmentEmpty(e) + } + getEarlierFragmentInSameDisco(e, t, i) { + var r = t.mediaSeqNum - e.startSN - 1; + if (r < 0 || r > e.fragments.length - 1) return this.logger.error(`[subtitle] getEarlierFragmentInSameDisco index ${r} out of range`), t; + r = e.fragments[r]; + return r && r.discoSeqNum === t.discoSeqNum && !i[t.mediaSeqNum] ? r : t + } + inferSubtitleFragmentForPosition(i, r, t, n, s) { + let a, o, e, l, d; + if (ne(n.prevFragSN) && (o = n.prevFragSN - s.startSN, e = t[n.prevFragSN]), ne(n.nextFragSN) && (l = n.nextFragSN - s.startSN, d = t[n.nextFragSN]), ne(o) && 0 <= o && o < s.fragments.length && e) { + let t = e.startTime; + const n = ne(l) ? l : s.fragments.length; + for (let e = o; e < n; ++e) { + const l = s.fragments[e]; + if (!ne(r) || l.discoSeqNum === r) { + if (e === n - 1) { + a = { + foundFrag: l, + timelineEstablished: !0 + }; + break + } + if (t + l.duration > i && e > o) { + a = { + foundFrag: l, + timelineEstablished: !0 + }; + break + } + t += l.duration + } + } + } else if (ne(l) && 0 <= l && l < s.fragments.length && d) { + let t = d.startTime; + for (let e = l - 1; 0 <= e; --e) { + const o = s.fragments[e]; + if (!ne(r) || o.discoSeqNum === r) { + if (t <= i) { + a = { + foundFrag: o, + timelineEstablished: !0 + }; + break + } + t -= o.duration + } + } + } else + for (let e = 0; e < s.fragments.length; ++e) { + const t = s.fragments[e]; + if (ne(r) && t.discoSeqNum === r) { + a = { + foundFrag: t, + timelineEstablished: !1 + }; + break + } + } + return a + } + generateFragmentBatch(t, i, e, r, n, s) { + var a; + const o = [], + l = null == e ? void 0 : e.foundFrag; + if (!l) return { + foundFrags: void 0, + subtitleParsedInfo: void 0, + subtitleBufferInfo: void 0, + timelineEstablished: null == e ? void 0 : e.timelineEstablished + }; + for (let e = l ? l.mediaSeqNum - s.startSN : s.fragments.length; e < s.fragments.length && o.length < t; ++e) { + const t = s.fragments[e]; + if (t.discoSeqNum === i) { + const l = null === (a = n.fragInfoMap[t.mediaSeqNum]) || void 0 === a ? void 0 : a.count; + this.isFragmentCompleteOrEmpty(t.mediaSeqNum, null != l ? l : 0, r) || o.push(t) + } + } + return { + foundFrags: o, + subtitleParsedInfo: r, + subtitleBufferInfo: n, + timelineEstablished: null == e ? void 0 : e.timelineEstablished + } + } + findFragmentsForPosition(e, t, i) { + var r = this.mediaSink.mediaQuery.getParsedSubtitleRecordsForMediaOption(this.selectedTrack.persistentID), + n = this.getCuesOfEnabledTrack(this.selectedMediaOption.mediaOptionId, !1), + s = this.calculateFragInfoMap(e, n, r, i), + n = s.bufferInfo, + n = Math.max(e, n.end), + n = this.inferSubtitleFragmentForPosition(n, t, r, s, i); + return this.generateFragmentBatch(1 / 0, t, n, r, s, i) + } + get selectedMediaOption() { + return this.selectedTrack || this._disabledMediaOption + } + set selectedMediaOption(e) { + this.selectedTrack = "groupId" in e ? e : void 0 + } + get selectedTrack() { + return this._selectedMediaOption + } + set selectedTrack(e) { + e !== this._selectedMediaOption && (this._selectedMediaOption = e, this.updateTextTrackState()) + } + getTrack(t) { + return this._availableMediaOptions.find(e => e.mediaOptionId === t) + } + updateTextTrackState() { + if (this.mediaSink.textTracks) { + const i = this.selectedTrack ? this.getExistingHTMLTextTrack(this.selectedTrack) : void 0, + r = Rp(this.mediaSink.textTracks); + for (let e = 0; e < r.length; e++) { + var t = r[e]; + t === i && "showing" !== r[e].mode ? r[e].mode = "showing" : t !== i && "hidden" !== r[e].mode && (r[e].mode = "hidden") + } + } + } + mapHTMLTextTrackIndexToMediaOptionId(e) { + const i = this.mediaSink.textTracks[e]; + let r; + return this.htmlTextTrackMap.forEach((e, t) => { + i === e && (r = t) + }), r + } + get mediaSelectionOptions() { + return this._availableMediaOptions + } + _makeDisableOption(e) { + return { + itemId: e.itemId, + mediaOptionType: e.mediaOptionType, + mediaOptionId: "Nah" + } + } + _onTextTracksChanged() { + if (this.mediaSink) { + let t, i = !1; + const r = Rp(this.mediaSink.textTracks); + for (let e = 0; e < r.length; e++) r[e].seen ? "showing" === r[e].mode && (t = r[e].persistentId) : (r[e].seen = !0, i = !0); + if (!i) { + const e = this.selectedTrack; + if ((null == e ? void 0 : e.persistentID) !== t) { + const e = this.mediaSelectionOptions.find(function(e) { + return e.persistentID === t + }); + this.nativeSubtitleTrackChange$.next(e || this._disabledMediaOption) + } + } + } + } + addCues(e, t, i, r) { + const n = this.cueRanges; + let s = !1; + for (let e = n.length; e--;) { + const r = n[e], + d = (a = r[0], o = r[1], l = t, Math.min(o, i) - Math.max(a, l)); + if (0 <= d && (r[0] = Math.min(r[0], t), r[1] = Math.max(r[1], i), s = !0, .5 < d / (i - t))) return + } + var a, o, l; + s || n.push([t, i]), this.Cues.newCue(this.channelToTrackMap[e], t, i, r, this.mediaSink) + } + getExistingHTMLTextTrackWithChannelNumber(t) { + var i = this.mediaSink; + if (i) + for (let e = 0; e < i.textTracks.length; e++) { + var r = i.textTracks[e], + n = "cc" + t; + if (Pp(n) && !0 === r[n]) return r + } + return null + } + sendAddTrackEvent(e, t) { + let i = null; + try { + i = new window.Event("addtrack") + } catch (e) { + i = document.createEvent("Event"), i.initEvent("addtrack", !1, !1) + } + i.track = e, t.dispatchEvent(i) + } + createHTMLCaptionsTrackGuts(e, t, i, r) { + var n = "cc" + e; + if (!this.channelToTrackMap[n]) { + e = this.getExistingHTMLTextTrackWithChannelNumber(e); + if (e) this.channelToTrackMap[n] = e, Lp(this.channelToTrackMap[n]), this.sendAddTrackEvent(this.channelToTrackMap[n], this.mediaSink); + else { + const s = this.createHTMLTextTrackGuts("captions", t, i, r); + s && Pp(n) && (s[n] = !0, this.channelToTrackMap[n] = s) + } + } + return this.channelToTrackMap[n] + } + createHTMLCaptionsTrack(e) { + return this.createHTMLCaptionsTrackGuts(e, this.config[1 === e ? "captionsTextTrack1Label" : "captionsTextTrack2Label"], this.config.captionsTextTrack1LanguageCode, !1) + } + getExistingHTMLTextTrack(e) { + return this.config.condenseSubtitleTrack ? this.htmlTextTrackMap.get(e.persistentID) : this.htmlTextTrackMap.get(e.id) + } + getExistingHTMLTextTrackWithSubtitleTrackId(t) { + var e = this._availableMediaOptions.find(e => e.id === t); + return e ? this.getExistingHTMLTextTrack(e) : void 0 + } + getExistingHTMLTextTrackIndex(e) { + var t = this.getExistingHTMLTextTrack(e), + i = this.mediaSink.textTracks; + let r = -1; + for (let e = 0; e < i.length; ++e) + if (i[e] === t) { + r = e; + break + } return r + } + setExistingHTMLTextTrack(e, t) { + return t.persistentId = e.persistentID, this.config.condenseSubtitleTrack ? this.htmlTextTrackMap.set(e.persistentID, t) : this.htmlTextTrackMap.set(e.id, t) + } + createHTMLTextTrack(t) { + let i = this.getExistingHTMLTextTrack(t); + if (i) this.tracksReused += 1; + else { + if ("sbtl" === t.mediaType) this.subtitleTracksCreated += 1, i = this.createHTMLTextTrackGuts("subtitles", t.name, t.lang, t.forced); + else { + let e = 1; + t.inStreamID && (e = Number(t.inStreamID.substring(2))), this.captionTracksCreated += 1, i = this.createHTMLCaptionsTrackGuts(e, t.name, t.lang, !1) + } + i ? this.setExistingHTMLTextTrack(t, i) : (this.logger.error(`failed to create HTML text track for track ${t.id}: persistent id ${t.persistentID} name ${t.name} lang ${t.lang} inStreamID ${t.inStreamID}`), this.tracksFailed += 1) + } + return i + } + createHTMLTextTrackGuts(t, i, r, e) { + const n = this.mediaSink; + if (n) { + let e = !1; + "metadata" !== t && this.config.customTextTrackCueRenderer && (e = !0, t = "metadata"); + const s = n.addTextTrack(t, i, r); + return e && (s.customTextTrackCueRenderer = !0), s + } + } + resetLoadSource() { + this.resetTracks() + } + resetTracks() { + this._cleanTracks(), this.cueRanges = [] + } + _cleanTracks() { + var e = this.mediaSink; + if (e) { + var t = e.textTracks; + if (t) + for (let e = 0; e < t.length; e++) Lp(t[e]) + } + } + getCuesOfEnabledTrack(e, t = !1) { + let i = []; + if (t) { + const t = this._getCuesOfEnabledTrack(e); + for (let e = 0; e < t.length; e++) { + var r = t[e]; + Boolean(r.webVTTCue) && i.push(r) + } + } else i = this._getCuesOfEnabledTrack(e); + return i + } + _getCuesOfEnabledTrack(e) { + e = this.getTrack(e), e = this.config.condenseSubtitleTrack ? null == e ? void 0 : e.persistentID : null == e ? void 0 : e.id, e = this.htmlTextTrackMap.get(e); + return e && e.cues ? Array.from(e.cues) : [] + } + attachSubtitleTracks() { + this.gotTracks && (this.subtitleTracksCreated = 0, this.captionTracksCreated = 0, this.tracksReused = 0, this.tracksFailed = 0, this.tracks.forEach(e => { + this.createHTMLTextTrack(e) + })) + } + setTracks(e, t, i) { + this._cleanTracks(), this.htmlTextTrackMap = new Map, this.cueRanges = [], this.config.enableWebVTT && (this.tracks = e || []), this.gotTracks = !0, this._availableMediaOptions = e, this._disabledMediaOption = i, this.attachSubtitleTracks(), this.selectedTrack = t, this.nativeSubtitleTrackChange$ = new Xt, this.mediaSink.textTracksCreated = !0 + } + onInlineStylesParsed(e) {} + processSubtitleFrag(e, t, i, r) { + var n = new Uint8Array(r), + e = this.getExistingHTMLTextTrackIndex(e); + if (t && r.byteLength) { + const s = this._parseVTTs(e, t, i, n); + return s && ne(s.startTime) && (this.lastCueEndTime = Math.max(this.lastCueEndTime, s.endTime)), s + } + } + _parseVTTs(r, n, e, t) { + let s; + return Mp(t, e, n.start, n.discoSeqNum, e => { + const t = this.mediaSink.textTracks[r], + i = { + count: 0, + startTime: Number.POSITIVE_INFINITY, + endTime: 0 + }; + e.map(e => { + !t || t.cues && t.cues.getCueById(e.id) || (e.fragSN = n.mediaSeqNum, e.webVTTCue = !0, t.addCue(e), i.count++), i.startTime = Math.min(e.startTime, i.startTime), i.endTime = Math.max(e.endTime, i.endTime) + }), s = i, this.mediaSink.archiveParsedSubtitleFragmentRecord(this.selectedTrack.persistentID, n.mediaSeqNum, i) + }, e => {}, e => { + this.hls.trigger(x.INLINE_STYLES_PARSED, { + styles: e + }) + }, this.logger), s + } + _ensureParser() { + var e, t; + this.cea608Parser || (e = new Xh(this, 1), t = new Xh(this, 2), this.cea608Parser = new zh(0, e, t)) + } + setupForFrag(e) { + e && e.mediaOptionType === gu.Variant && !e.iframe && ((e = e.mediaSeqNum) !== this.lastVariantSeqNum + 1 && this.resetClosedCaptionParser(), this.lastVariantSeqNum = e) + } + resetClosedCaptionParser() { + var e; + null === (e = this.cea608Parser) || void 0 === e || e.reset() + } + addLegibleSamples(e, t, i, r) { + t && this.addClosedCaptionSamples(e, t), i && 0 < i.length && this.addId3Samples(e, i, S(r)) + } + addClosedCaptionSamples(e, t) { + t.mp4 ? this.addMP4CaptionSamples(e, t.mp4) : t.ts && this.addTSCaptionSamples(e, t.ts) + } + addMP4CaptionSamples(e, i) { + if (this.enableCaption && this.config.enableCEA708Captions) { + var r = S(e); + this._ensureParser(); + for (let e = 0; e < i.length; e++) { + let t = i[e].pts - r; + var n = i[e].bytes; + for (let e = 0; e < n.length; e += 2) { + const i = []; + i.push(n[e]), e + 1 < n.length ? i.push(n[e + 1]) : i.push(80), this.cea608Parser.addData(t, i), t += .03336666666666667 + } + } + } + } + addTSCaptionSamples(e, t) { + if (this.enableCaption && this.config.enableCEA708Captions) { + var i = S(e); + this._ensureParser(); + for (let e = 0; e < t.length; e++) { + var r = t[e].pts - i, + n = _p.extractCea608Data(t[e].bytes); + this.cea608Parser.addData(r, n) + } + } + } + addId3Samples(e, t, r) { + if (this.config.enableID3Cues) { + const n = window.WebKitDataCue || window.VTTCue || window.TextTrackCue, + s = S(e); + for (let e = 0; e < t.length; e++) { + const a = t[e].pts - s; + let i = (e < t.length - 1 ? t[e + 1].pts : r) - s; + a === i && (i += 1e-4), t[e].frames && t[e].frames.forEach(e => { + if (e && !this.id3shouldIgnore(e)) { + const t = new n(a, i, ""); + t.value = e, this.id3Track.addCue(t) + } + }) + } + } + } + id3shouldIgnore(e) { + return "PRIV" === e.key && ("com.apple.streaming.transportStreamTimestamp" === e.info || "com.apple.streaming.audioDescription" === e.info) + } + static extractCea608Data(t) { + var i = 31 & t[0]; + let r, n, s, a = 2; + const o = []; + for (let e = 0; e < i; e++) r = t[a++], n = 127 & t[a++], s = 127 & t[a++], 0 == n && 0 == s || 0 != (4 & r) && 0 == (3 & r) && (o.push(n), o.push(s)); + return o + } + } + const Np = { + name: "plist" + }; + class Fp { + constructor(e, t, i, r) { + this.config = e, this.xhrLoader = t, this.customUrlLoader = i, this.sessionDataCheckForCompleteness = e => { + const t = this.config["sessionDataAutoLoad"], + i = Object.assign({}, e); + return e.complete || (e.itemList ? i.complete = e.itemList.every(e => t[e["DATA-ID"]] && !e.VALUE && !e._STATUS && e.URI ? (this.logger.warn(`Incomplete because ${e["DATA-ID"]} was autoloaded but no response yet`), !1) : (t[e["DATA-ID"]] && !e.URI && this.logger.warn(`id=${e["DATA-ID"]} missing uri`), !0)) : this.logger.warn("Uninitialized SessionData")), i + }, this.logger = r.child({ + name: "SessionDataLoader" + }) + } + loadSessionData(r) { + const n = this.config["sessionDataAutoLoad"], + t = r.itemList || []; + let s = $i(r); + return t.forEach(e => { + const i = e["DATA-ID"], + t = e.URI; + if (t && n[i]) { + const n = bu.buildAbsoluteURL(r.baseUrl, t, { + alwaysNormalize: !0 + }), + e = ""; + s = s.pipe(La(t => this.loadSessionDataItemWithUrl(n, i, "", this.config, t, this.xhrLoader, this.customUrlLoader).pipe(Vn(e => (this.logger.error(`Error loading SessionData > url=${n}, id=${i}, err=${e}`), $i(t)))))) + } + }), s.pipe(hr(e => { + if (t.length < 1) return e; + e = this.sessionDataCheckForCompleteness(e); + if (e.complete) return e; + throw new V(!1, "Session data not complete after loading all items", $.IncompleteSessionData) + }), Vs(() => {})) + } + loadSessionDataItemWithUrl(e, t, i, r, n, s, a) { + const o = Qe(), + l = { + url: e, + method: "GET", + responseType: i, + xhrSetup: r.xhrSetup, + mimeType: "application/xml" + }, + d = Lc({ + url: e + }, r.fragLoadPolicy); + let u; + return u = Tu(e) ? a(l, d).pipe(hr(e => this.onLoadSuccess(n, t, e.data.response.data.toString(), e.data.response.data))) : s(l, d).pipe(hr(([e]) => this.onLoadSuccess(n, t, e.response, e.responseXML))), u.pipe(Vn(e => (e instanceof dr ? e = new cc(!1, e.message, 0, $.SessionDataLoadTimeout) : e instanceof oc && (e = new cc(!1, e.message, e.code, { + code: e.code, + text: "Failed to load SessionData" + })), o.error(`Unable to load SessionData > err=${e}`), $i(this.onLoadError(n, t, e))))) + } + onLoadSuccess(e, t, i, r) { + let n = null, + s = e; + if (function(e) { + const t = /[\s]*<\?xml/i; + t.lastIndex = 0; + var i = t.exec(e); + return i || /[\s]*"), null) + } else if ("string" === i) { + const e = a[0]; + s = e ? e.nodeValue : null + } else if ("integer" === i) { + const e = a[0]; + s = e ? parseInt(e.nodeValue) : 0 + } else if ("float" === i) { + const e = a[0]; + s = e ? parseFloat(e.nodeValue) : 0 + } else if ("date" === i) { + const e = a[0]; + s = e ? new Date(e.nodeValue) : null + } else if ("data" === i) { + const e = a[0]; + s = e ? atob(e.nodeValue) : null + } else "true" === i ? s = !0 : "false" === i && (s = !1) + } else if (a.length < 1) t.warn(Np, `unknown node with unknown value > nodeType=${e.nodeType} tagName=${e.tagName} nodeName=${e.nodeName} value=${e.nodeValue}`); + else { + s = []; + for (let e = 0; e < a.length; ++e) { + const r = a[e]; + r.tagName && s.push(n(r)) + } + 1 === s.length && (s = s[0]) + } + return s + }(n); + s = this.setSessionData(e, t, "VALUE", i) + } else if (function(e) { + const t = /[\s]*[\{\[]/; + return t.lastIndex = 0, t.exec(e) + }(i)) try { + const r = JSON.parse(i); + s = this.setSessionData(e, t, "VALUE", r) + } catch (r) { + this.logger.error(`JSON parser error: ${r}`), s = this.setSessionData(e, t, "VALUE", i), s = this.setSessionData(s, t, "_STATUS", -1) + } else s = this.setSessionData(e, t, "VALUE", i); + return s + } + setSessionData(t, i, r, n) { + let s = t; + if (t.itemList) { + let e; + const a = [...t.itemList]; + for (e = 0; e < t.itemList.length; ++e) { + const t = Object.assign({}, a[e]); + if (t["DATA-ID"] === i) { + t[r] = n, a[e] = t; + break + } + } + e === t.itemList.length && this.logger.error(`Can't set ${r} of session data ${i}`), s = Object.assign(Object.assign({}, t), { + itemList: a + }) + } else this.logger.error(`Can't set ${r} on uninitialized session data`); + return s + } + onLoadError(e, t, i) { + return this.setSessionData(e, t, "_STATUS", null === (i = i.response) || void 0 === i ? void 0 : i.code) + } + } + + function Bp(e, t) { + let i, r = 0; + for (const a of e) + if (a.start <= t.endPTS && a.end > t.startPTS) { + const e = (n = t, s = a, Math.min(n.endPTS, s.end) - Math.max(n.startPTS, s.start)); + e > r && (i = a, r = e) + } else if (0 < r) break; + var n, s; + return i + } + + function Up(e) { + return null != e && "iframeMediaDuration" in e && "iframeMediaStart" in e + } + + function $p(e, t) { + return e === t || e && t && e.itemId === t.itemId && e.mediaOptionId === t.mediaOptionId && e.mediaSeqNum === t.mediaSeqNum && e.discoSeqNum === t.discoSeqNum + } + + function Vp(e) { + return JSON.stringify(e, ["mediaOptionId", "mediaSeqNum", "discoSeqNum", "start", "duration"]) + } + + function Kp() { + return e => e.pipe(ln(e => null != e), hr(e => e)) + } + + function qp(e) { + return be.isDolby(e) ? hu.DOVI : be.isHEVC(e) ? hu.HEVC : be.isVP09(e) ? hu.VP09 : be.isAVC(e) ? hu.AVC : hu.UNKNOWN + } + + function Hp(e) { + return null == e ? void 0 : e.split(".")[0] + } + + function jp(e) { + return be.isALAC(e) ? fu.ALAC : be.isFLAC(e) ? fu.FLAC : be.isEC3(e) ? fu.EC3 : be.isAC3(e) ? fu.AC3 : be.isXHEAAC(e) ? fu.XHEAAC : be.isAAC(e) ? fu.AAC : be.isMP3(e) ? fu.MP3 : fu.UNKNOWN + } + class Qp { + constructor(...e) { + this.identifier = e + } + ensureSameIdentifierLength(e) { + if (this.identifier.length !== e.identifier.length) throw new Error(`Identifiers have non-matching lengths! (${this.identifier.length} vs ${e.identifier.length})`) + } + isGreaterThan(t) { + this.ensureSameIdentifierLength(t); + for (let e = 0; e < this.identifier.length; ++e) { + if (this.identifier[e] < t.identifier[e]) return !1; + if (this.identifier[e] > t.identifier[e]) return !0 + } + return !1 + } + isEqualTo(i) { + return this.ensureSameIdentifierLength(i), this.identifier.every((e, t) => e === i.identifier[t]) + } + } + + function Wp(e) { + return ne(e) && 0 !== e && 1 !== e + } + class Gp extends Error {} + class zp { + constructor(e) { + this.value = e, this.waiters = [], this.wcounter = 0, this.rcounter = 0 + } + lock(e, t = !1) { + return this._lock(!0, e, t) + } + unlock() { + this._unlock(!0) + } + readLock(e, t = !1) { + return this._lock(!1, e, t) + } + readUnlock() { + this._unlock(!1) + } + _schedule() { + const t = []; + this.waiters = this.waiters.filter(e => !this._canLock(e.rw) || (e.rw ? ++this.wcounter : ++this.rcounter, t.push(e), !1)); + for (const e of t) e.observer.next(this.value), e.observer.complete() + } + _canLock(e) { + return e && 0 === this.wcounter && 0 === this.rcounter || !e && 0 === this.wcounter + } + _lock(i, e, r = !1) { + "boolean" == typeof e && ([r, e] = [e, void 0]); + const t = new $t(e => { + var t = this._canLock(i); + if (r && !t) throw new Gp; + t ? (i ? ++this.wcounter : ++this.rcounter, e.next(), e.complete()) : this.waiters.push({ + rw: i, + observer: e + }) + }); + return e ? t.pipe(jr(() => ((e, t, i, r) => { + if (!r) return $i(e); + let n, s; + try { + n = r(e, t) + } catch (e) { + s = Vi(() => e) + } + return s = s || (void 0 === n ? $i(e) : Fr(n)), s.pipe(Vs(i)) + })(this.value, e => { + this.value = e + }, () => this._unlock(i), e))) : t + } + _unlock(e) { + e ? this.wcounter = Math.max(this.wcounter - 1, 0) : this.rcounter = Math.max(this.rcounter - 1, 0), this._schedule() + } + } + class Xp extends $t { + constructor() { + super(e => this._count$.pipe(ln(e => 0 === e), Ds(1), Zs(void 0)).subscribe(e)), this._count$ = new yi(0) + } + wrap(e) { + return Zr(() => (this.add(), Fr(e))).pipe(Za({ + error: e => this._count$.error(e) + }), Vs(() => this.done())) + } + add(e = 1) { + this._count$.next(this._count$.value + e) + } + done(e = 1) { + this._count$.next(this._count$.value - e) + } + } + const Yp = { + isBuffered(t, i) { + for (let e = 0; t && e < t.length; e++) + if (i >= t.start(e) && i <= t.end(e)) return !0; + return !1 + }, + timeRangesToBufferedRange(t) { + const i = []; + for (let e = 0; t && e < t.length; e++) i.push({ + start: t.start(e), + end: t.end(e) + }); + return i + }, + subtitleBufferInfo(e, t, i) { + if (e) { + e = this.bufferedCues(e); + return this.getBufferedInfo(e, t, i) + } + return { + len: 0, + start: t, + end: t, + nextStart: void 0 + } + }, + fragmentsBufferedInfo(e, t, i) { + const r = []; + for (const t of e) r.push({ + start: t.start, + end: t.start + t.duration + }); + return this.getBufferedInfo(r, t, i) + }, + bufferedCues(t) { + const i = []; + if (t) + for (let e = 0; e < t.length; e++) i.push({ + start: t[e].startTime, + end: t[e].endTime + }); + return i + }, + bufferedInfoFromMedia: (e, t, i) => Yp.getBufferedInfo(Yp.timeRangesToBufferedRange(e.buffered), t, i), + getBufferedInfo(e, t, i) { + const r = []; + let n, s, a, o, l; + const d = e.map(({ + start: e, + end: t + }) => ({ + start: e, + end: t + })); + for (d.sort((e, t) => { + return e.start - t.start || t.end - e.end + }), l = 0; l < d.length; l++) { + const e = r.length; + if (e) { + const t = r[e - 1].end; + d[l].start - t < i ? d[l].end > t && (r[e - 1].end = d[l].end) : r.push(d[l]) + } else r.push(d[l]) + } + for (l = 0, n = 0, s = a = t; l < r.length; l++) { + const e = r[l]["start"], + d = r[l]["end"]; + if (t + i >= e && t < d) s = e, a = d, n = a - t; + else if (t + i < e) { + o = e; + break + } + } + return { + len: n, + start: s, + end: a, + nextStart: o + } + }, + toRangeString: e => `[${e.start.toFixed(3)},${e.end.toFixed(3)}]` + }; + (w = Cp = Cp || {}).Seek = "Seek", w.HighBuffer = "HighBuffer", w.LowBuffer = "LowBuffer", (w = Dp = Dp || {}).AlmostDry = "AlmostDry", w.LowWater = "LowWater", w.HighWater = "HighWater", w.AboveHighWater = "AboveHighWater"; + const Jp = { + [Dp.AlmostDry]: 0, + [Dp.LowWater]: 1, + [Dp.HighWater]: 2, + [Dp.AboveHighWater]: 3 + }; + + function Zp(t, e) { + return [{ + threshold: e.highWaterLevelSeconds, + level: Dp.HighWater + }, { + threshold: e.lowWaterLevelSeconds, + level: Dp.LowWater + }, { + threshold: e.almostDryWaterLevelSeconds, + level: Dp.AlmostDry + }].find(({ + threshold: e + }) => e < t) + } + + function ef(t, e) { + return [{ + threshold: e.almostDryWaterLevelSeconds, + level: Dp.AlmostDry + }, { + threshold: e.lowWaterLevelSeconds, + level: Dp.LowWater + }, { + threshold: e.highWaterLevelSeconds, + level: Dp.HighWater + }, { + threshold: 1 / 0, + level: Dp.AboveHighWater + }].find(({ + threshold: e + }) => t <= e) + } + + function tf(t, i) { + const e = ef(t.getCurrentWaterLevel(i), t.bufferMonitorInfo).level, + r = [null, null]; + return [yu.Variant, yu.AltAudio].forEach(e => { + null != t.sourceBufferEntityByType(e) && (r[e] = ef(t.getCurrentWaterLevelByType(e, i), t.bufferMonitorInfo).level) + }), { + combined: e, + sbTuple: r + } + } + + function rf(s, a) { + return ed([s.combinedBuffer$, s.gotPlaying$, s.seeking$, s.waterLevelChangedForType$(null), s.stallInfo$]).pipe(La(([e, t, i, r, n]) => 0 === e.length || !t || i || null == r || null != n ? Ii : function t(i, r, e) { + const n = i.getCurrentWaterLevel(r), + s = Zp(n, i.bufferMonitorInfo); + if (s) { + const e = s["threshold"]; + return bn(Math.ceil(1e3 * (n - e))).pipe(La(() => { + const e = Zp(i.getCurrentWaterLevel(r), i.bufferMonitorInfo); + return (null == e ? void 0 : e.level) === s.level ? t(i, r) : Wu + }), hr(() => tf(i, r))) + } + return Ii + }(s, a))) + } + class nf extends kl { + constructor(e, t) { + super(t), this.mediaElement = e + } + get mediaElementDuration$() { + return this.selectActive(({ + mediaElementDuration: e + }) => e) + } + get mediaElementDuration() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.mediaElementDuration) && void 0 !== e ? e : 1 / 0 + } + get msDuration() { + var e; + return null !== (e = null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.duration) && void 0 !== e ? e : 1 / 0 + } + get minSBDuration() { + var e; + let i = Number.POSITIVE_INFINITY; + return null === (e = null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e || e.forEach((e, t) => { + e && (i = ne(e.totalDuration) ? Math.min(i, e.totalDuration) : Number.NEGATIVE_INFINITY) + }), ne(i) ? i : 1 / 0 + } + get currentTime() { + return this.mediaElement.currentTime + } + get clientWidth() { + return this.mediaElement.clientWidth + } + get clientHeight() { + return this.mediaElement.clientHeight + } + getBufferedDuration(e = .5) { + var t = Yp.timeRangesToBufferedRange(this.mediaElement.buffered), + e = Yp.getBufferedInfo(t, this.currentTime, e); + return e.end - e.start + } + get mediaSourceEntity() { + var e; + return null === (e = this.getActive()) || void 0 === e ? void 0 : e.mediaSourceEntity + } + get msReadyState() { + var e; + return null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.readyState + } + get sourceBufferEntities() { + var e; + return null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities + } + sourceBufferEntityByType(e) { + var t; + return null === (t = this.sourceBufferEntities) || void 0 === t ? void 0 : t[e] + } + initSegmentEntityByType(e) { + return null === (e = this.sourceBufferEntityByType(e)) || void 0 === e ? void 0 : e.initSegmentInfo + } + get maxBufferSize() { + var e = null === (e = this.sourceBufferEntities) || void 0 === e ? void 0 : e[yu.Variant]; + let t = 1 / 0; + return null != e && e.gotQuotaExceeded && (t = null !== (e = e.maxTotalBytes) && void 0 !== e ? e : 1 / 0), t + } + get postFlushSeek() { + var e; + return null === (e = this.getActive()) || void 0 === e ? void 0 : e.postFlushSeek + } + get seekable() { + return this.mediaElement.seekable + } + get desiredRate() { + var e; + return (null === (e = this.getActive()) || void 0 === e ? void 0 : e.desiredRate) || 0 + } + get desiredRate$() { + return this.selectActive(({ + desiredRate: e + }) => null != e ? e : 0) + } + get effectiveRate() { + return this.isIframeRate ? this.desiredRate : this.paused ? 0 : 1 + } + get playbackRate() { + return this.mediaElement.playbackRate + } + get isIframeRate() { + return Wp(this.desiredRate) + } + get isIframeRate$() { + return this.desiredRate$.pipe(hr(Wp)) + } + get msObjectUrl$() { + return this.selectActive(({ + mediaSourceEntity: e + }) => null == e ? void 0 : e.objectUrl).pipe(Is()) + } + get msReadyState$() { + return this.selectActive(({ + mediaSourceEntity: e + }) => { + return null !== (e = null == e ? void 0 : e.readyState) && void 0 !== e ? e : null + }) + } + get readyState() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.readyState) && void 0 !== e ? e : 0 + } + get readyState$() { + return this.selectActive(({ + readyState: e + }) => null != e ? e : 0) + } + get mediaSourceEntity$() { + return this.selectActive(({ + mediaSourceEntity: e + }) => e) + } + get expectedSbCount$() { + return this.selectActive(({ + expectedSbCount: e + }) => e) + } + get expectedSbCount() { + var e; + return null === (e = this.getActive()) || void 0 === e ? void 0 : e.expectedSbCount + } + get paused$() { + return this.selectActive(({ + paused: e + }) => e) + } + get paused() { + var e; + return null === (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.paused) || void 0 === e || e + } + get playbackStarted() { + var e; + return ne(null === (e = this.getActive()) || void 0 === e ? void 0 : e.firstPlayTime) + } + get flushing$() { + return this.selectActive(({ + flushing: e + }) => e) + } + get flushing() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.flushing) && void 0 !== e && e + } + get waitingForDisco$() { + return this.selectActive(({ + waitingForDisco: e + }) => e) + } + get waitingForDisco() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.waitingForDisco) && void 0 !== e && e + } + get gotPlaying() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.gotPlaying) && void 0 !== e && e + } + get gotPlaying$() { + return this.selectActive(({ + gotPlaying: e + }) => e) + } + get gotLoadStart$() { + return this.selectActive(({ + gotLoadStart: e + }) => e) + } + get seekTo() { + var e; + return null === (e = this.getActive()) || void 0 === e ? void 0 : e.seekTo + } + get seekTo$() { + return this.selectActive(({ + seekTo: e + }) => e) + } + get seeking() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.seeking) && void 0 !== e && e + } + get seeking$() { + return this.selectActive(({ + seeking: e + }) => e) + } + get nudgeTarget$() { + return this.selectActive(({ + nudgeInfo: e + }) => null == e ? void 0 : e.nudgeTarget) + } + get nudgeCount() { + var e; + return null !== (e = null === (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.nudgeInfo) || void 0 === e ? void 0 : e.nudgeCount) && void 0 !== e ? e : 0 + } + get sourceBufferEntities$() { + return this.selectActive(({ + mediaSourceEntity: e + }) => null == e ? void 0 : e.sourceBufferEntities) + } + sourceBufferEntityByType$(t) { + return this.selectActive(({ + mediaSourceEntity: e + }) => { + return null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t] + }) + } + bufferedSegmentsByType$(t) { + return this.selectActive(({ + mediaSourceEntity: e + }) => { + return null !== (e = null === (e = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t]) || void 0 === e ? void 0 : e.bufferedSegments) && void 0 !== e ? e : [] + }) + } + getBufferedSegmentsByType(e) { + return null !== (e = null === (e = this.sourceBufferEntityByType(e)) || void 0 === e ? void 0 : e.bufferedSegments) && void 0 !== e ? e : [] + } + get bufferedSegmentsTuple$() { + return ed([this.bufferedSegmentsByType$(yu.Variant), this.bufferedSegmentsByType$(yu.AltAudio)]).pipe(Gn(10)) + } + get timeupdate$() { + return Oc(this.mediaElement).event("timeupdate").pipe(ji(tr), Aa(), ao(125, void 0, { + leading: !0, + trailing: !0 + }), hr(e => this.currentTime), ln(e => ne(e))) + } + get playingEvent$() { + return Oc(this.mediaElement).event("playing").pipe(hr(() => {})) + } + get mediaElementEntity$() { + return this.selectActive(e => Boolean(e)) + } + get ended$() { + return this.selectActive(e => { + return null !== (e = null == e ? void 0 : e.ended) && void 0 !== e && e + }) + } + sbUpdating$(t) { + return this.selectActive(e => { + return null !== (e = null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t]) || void 0 === e ? void 0 : e.updating) && void 0 !== e && e + }) + } + sbUpdating(e) { + var t; + return null !== (e = null === (e = null === (t = null === (t = null === (t = this.getActive()) || void 0 === t ? void 0 : t.mediaSourceEntity) || void 0 === t ? void 0 : t.sourceBufferEntities) || void 0 === t ? void 0 : t[e]) || void 0 === e ? void 0 : e.updating) && void 0 !== e && e + } + sbError$(t) { + return this.selectActive(e => { + return null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t]) || void 0 === e ? void 0 : e.error + }) + } + get updating$() { + return ed([this.sbUpdating$(yu.Variant), this.sbUpdating$(yu.AltAudio)]).pipe(hr(e => e.some(e => e))) + } + get bufferedRangeTuple$() { + return ed([this.selectActive(e => { + return null !== (e = null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[gu.Variant]) || void 0 === e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : null + }), this.selectActive(e => { + return null !== (e = null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[gu.AltAudio]) || void 0 === e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : null + })]) + } + getBufferedRangeByType(e) { + return null !== (e = null === (e = this.sourceBufferEntities[e]) || void 0 === e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : [] + } + get combinedBuffer$() { + return this.selectActive(e => { + return null !== (e = null == e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : [] + }) + } + getBufferInfo(n, s) { + var e; + const t = null === (e = this.sourceBufferEntities) || void 0 === e ? void 0 : e.map(e => null == e ? void 0 : e.bufferedRanges), + i = { + buffered: { + start: n, + end: n, + len: 0 + }, + bufferedSegments: [] + }, + a = [i, i]; + return t && t.forEach((e, t) => { + if (e) { + const i = Yp.getBufferedInfo(e, n, s), + r = (null !== (e = this.sourceBufferEntities[t].bufferedSegments) && void 0 !== e ? e : []).filter(e => !(e.endPTS < i.start || e.startPTS > i.end)); + a[t] = { + buffered: i, + bufferedSegments: r + } + } + }), a + } + getCombinedBufferInfo(e, t) { + var i = this.getActive(); + return i ? Yp.getBufferedInfo(i.bufferedRanges, e, t) : null + } + get bufferMonitorInfo() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.bufferMonitorInfo) && void 0 !== e ? e : null + } + get bufferMonitorThresholds$() { + return this.selectActive(e => { + var t = null == e ? void 0 : e.bufferMonitorInfo; + if (!t) return null; + var { + almostDryWaterLevelSeconds: i, + lowWaterLevelSeconds: r, + highWaterLevelSeconds: e, + maxBufferSeconds: t + } = t; + return { + almostDryWaterLevelSeconds: i, + lowWaterLevelSeconds: r, + highWaterLevelSeconds: e, + maxBufferSeconds: t + } + }).pipe(Is((e, t) => (null == e ? void 0 : e.lowWaterLevelSeconds) === (null == t ? void 0 : t.lowWaterLevelSeconds))) + } + get waterLevelType$() { + return this.selectActive(e => { + return null !== (e = null == e ? void 0 : e.bufferMonitorInfo.waterLevelType) && void 0 !== e ? e : null + }) + } + waterLevelForType(e) { + var t; + return null !== (e = null === (t = null === (t = this.getActive()) || void 0 === t ? void 0 : t.bufferMonitorInfo.waterLevelType) || void 0 === t ? void 0 : t.sbTuple[e]) && void 0 !== e ? e : null + } + waterLevelChangedForType$(t) { + return this.waterLevelType$.pipe(hr(e => null == e ? null : null == t ? e.combined : e.sbTuple[t])) + } + get fellBelowLowWater$() { + return this.waterLevelChangedForType$(yu.Variant).pipe(ha(), hr(([e, t]) => function(e, t) { + return Jp[e] > Jp[t] + }(e, t) && (t === Dp.LowWater || t === Dp.AlmostDry)), bo(this.seekTo$, this.waitingForDisco$), hr(([e, t, i]) => e && !ne(null == t ? void 0 : t.pos) && !i), Ra(!1)) + } + isBufferedToEnd$(s, a = !0) { + return ed([this.combinedBuffer$, this.selectActive(e => e.bufferMonitorInfo).pipe(Kp(), hr(e => a ? e.almostDryWaterLevelSeconds : Math.max(e.almostDryWaterLevelSeconds, e.lowWaterLevelSeconds / 2))), this.seeking$]).pipe(hr(([e, t]) => { + var i = this.minSBDuration; + if (!e || !ne(i) && a) return !1; + e = Yp.getBufferedInfo(e, this.currentTime, s).end; + let r, n; + return n = a ? (r = i, Math.abs(r - e) <= t) : (r = this.mediaElementDuration, r - e <= t), n + }), Is()) + } + needData$(e, n = !1) { + var t = !n; + return ed([this.msReadyState$, this.waterLevelChangedForType$(null), this.isBufferedToEnd$(e, t), this.bufferedRangeTuple$, this.seekTo$, this.mediaElementDuration$]).pipe(Gn(10), hr(([e, t, i, , r]) => { + if ("closed" === e) return !1; + if (n) return !0; + i = null == t || !i && t !== Dp.AboveHighWater, r = this.isIframeRate || !!r; + return i || t !== Dp.AboveHighWater && r + }), tc("needData")) + } + getSourceBufferInfoAction(e, t, i, r) { + var { + currentTime: n, + sourceBufferEntities: s, + msReadyState: a + } = this; + let o = [null, null]; + return !e && i.every(e => !(null != e && e.userInitiated)) ? null : "open" === a && s && null != s[0] ? (o = this.getBufferInfo(n, r), { + position: n, + discoSeqNum: null == t ? void 0 : t.discoSeqNum, + bufferInfoTuple: o, + switchContexts: i + }) : { + position: null == t ? void 0 : t.pos, + discoSeqNum: null == t ? void 0 : t.discoSeqNum, + bufferInfoTuple: o, + switchContexts: i + } + } + get haveEnough() { + var e; + return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.haveEnough) && void 0 !== e && e + } + get haveEnough$() { + return this.selectActive(({ + haveEnough: e + }) => e) + } + static likelyToKeepUp(e, t, i) { + return t && i >= e.HAVE_FUTURE_DATA + } + get playbackLikelyToKeepUp() { + return nf.likelyToKeepUp(this.mediaElement, this.haveEnough, this.readyState) + } + get playbackLikelyToKeepUp$() { + return ed([this.haveEnough$, this.readyState$]).pipe(hr(([e, t]) => nf.likelyToKeepUp(this.mediaElement, e, t))) + } + getCurrentWaterLevel(e) { + var t = this.currentTime, + i = null !== (i = null === (i = this.getActive()) || void 0 === i ? void 0 : i.bufferedRanges) && void 0 !== i ? i : []; + return Yp.getBufferedInfo(i, t, e).len + } + getCombinedMediaSourceBufferInfo(e) { + var t = this.currentTime, + [i, r] = null === (r = null === (i = this.getActive()) || void 0 === i ? void 0 : i.mediaSourceEntity) || void 0 === r ? void 0 : r.sourceBufferEntities; + return [Yp.getBufferedInfo(null !== (i = null == i ? void 0 : i.bufferedRanges) && void 0 !== i ? i : [], t, e), Yp.getBufferedInfo(null !== (r = null == r ? void 0 : r.bufferedRanges) && void 0 !== r ? r : [], t, e)] + } + getCurrentWaterLevelByType(e, t) { + var i = this.currentTime, + e = this.sourceBufferEntityByType(e), + e = null !== (e = null == e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : []; + return Yp.getBufferedInfo(e, i, t).len + } + canContinuePlaybackWithoutGap(e, t, i, r) { + if ("LIVE" !== e.type) return !0; + if (!e.ptsKnown) return !1; + var n = this.currentTime, + i = performance.now() + i.avgPlaylistLoadTimeMs + 1e3 * e.targetduration, + t = e.fragments[0].start + (i - t) / 1e3; + let s = this.getCombinedBufferInfo(n, r).end; + return s >= e.fragments[0].start - r && s <= e.fragments[0].start + e.totalduration && (s = e.fragments[0].start + e.totalduration), t <= s + } + get stallInfo$() { + return this.selectActive(e => { + return null !== (e = null == e ? void 0 : e.stallInfo) && void 0 !== e ? e : null + }) + } + get textTracks() { + return this.mediaElement.textTracks + } + get textTracksCreated$() { + return this.selectActive(e => null == e ? void 0 : e.textTracksCreated) + } + get mediaOptionParsedSubtitleRecord() { + var e; + return null === (e = this.getActive()) || void 0 === e ? void 0 : e.mediaOptionParsedSubtitleRecord + } + getParsedSubtitleRecordsForMediaOption(e) { + return this.mediaOptionParsedSubtitleRecord ? this.mediaOptionParsedSubtitleRecord[e] || {} : null + } + } + class sf { + constructor(e, t, i, r) { + this.mediaSink = e, this.media = t, this.logger = r, this.useCustomMediaFunctions = i.useCustomMediaFunctions, this.overridePlaybackRate = i.overridePlaybackRate + } + install() { + const e = this.media; + e && (this.useCustomMediaFunctions && e && e.play && e.pause && (e.originalPlay || (e.originalPlay = e.play.bind(e)), e.originalPause || (e.originalPause = e.pause.bind(e)), e.play = () => (this.mediaSink.checkForReplay(), this.mediaSink.desiredRate = 1, 0 < e.currentTime && !e.paused && !e.ended && 2 < e.readyState ? Promise.resolve() : new Promise((e, t) => { + this.pendingPlayPromises || (this.pendingPlayPromises = []), this.pendingPlayPromises.push({ + resolve: e, + reject: t + }) + })), e.pause = () => { + this.mediaSink.desiredRate = 0 + }), "function" == typeof HTMLMediaElement && this.overridePlaybackRate && Object.defineProperty(e, "playbackRate", { + enumerable: !0, + configurable: !0, + get: function() { + return 1 + }, + set: function(e) { + Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, "playbackRate").set.call(this, e) + } + }), this.playPromise = null, this.expectPauseEvent = this.expectPlayEvent = !1) + } + uninstall() { + const e = this.media; + e && (e.originalPlay && (e.play = e.originalPlay, delete e.originalPlay), e.originalPause && (e.pause = e.originalPause, delete e.originalPause), this.overridePlaybackRate && (e.playbackRate = 1, delete e.playbackRate)), this.playPromise = null, this.expectPauseEvent = this.expectPlayEvent = !1 + } + play() { + var e; + this.media && (e = this.mediaSink.flushing, this.playPromise || e ? this.logger.warn(`Ignoring play command playPromise/flushing ${Boolean(this.playPromise)}/${e}`) : (this.expectPlayEvent = this.expectPlayEvent || this.media.paused, this.playPromise = this._mediaPlayInternal(), this.playPromise && this.playPromise.then(function() { + this.playPromise = null, this._handlePendingPlayPromises(null) + }.bind(this)).catch(function(e) { + this.playPromise = null, this.expectPlayEvent = !1, this._handlePendingPlayPromises(e || new Error("Play rejected for unknown reason")), "NotAllowedError" === (null == e ? void 0 : e.name) ? (this.logger.warn("play() not allowed, going back to rate 0"), this.mediaSink.desiredRate = 0) : this.logger.error(`play() error: ${null==e?void 0:e.message}`) + }.bind(this)))) + } + pause() { + this.media && (this.playPromise ? this.playPromise.then(() => { + var e = this.mediaSink.mediaQuery; + (0 === this.mediaSink.desiredRate || e.seeking && !e.playbackLikelyToKeepUp) && this._mediaPauseInternal() + }).catch(e => { + this.logger.error(`Promise error in pause(): ${e.message}`) + }) : this._mediaPauseInternal()) + } + _handlePendingPlayPromises(t) { + var e, i = null === (e = this.pendingPlayPromises) || void 0 === e ? void 0 : e.length; + if (t) + for (let e = 0; e < i; e++) this.pendingPlayPromises[e].reject(t); + else + for (let e = 0; e < i; e++) this.pendingPlayPromises[e].resolve(); + this.pendingPlayPromises = [] + } + _mediaPlayInternal() { + return (this.media.originalPlay || this.media.play.bind(this.media))() + } + _mediaPauseInternal() { + return this.expectPauseEvent = this.expectPauseEvent || !this.media.paused, (this.media.originalPause || this.media.pause.bind(this.media))() + } + } + class af extends Error {} + class of extends p { + constructor(e, t, i, r, n) { + super(L, e, t, i, r), this.sbType = n, this.response = r + } + } + class lf extends of { + constructor(e, t, i, r) { + super("bufferAddCodecError", !1, e, t, i), this.mediaOptionId = r, this.mediaOptionType = Vu(this.sbType) + } + } + class df extends of { + constructor(e, t, i, r, n, s) { + super(e, t, i, r, n), this.isTimeout = s, this.mediaOptionType = Vu(this.sbType) + } + } + class uf extends df { + constructor(e, t, i, r) { + super("bufferFullError", !1, e, t, i, !1), this.maxTotalBytes = r + } + } + class cf extends df { + constructor(e, t, i) { + super(n, !1, e, t, i, !0) + } + } + class hf extends df { + constructor(e, t, i, r) { + super(n, !1, e, t, i, !1), this.mediaOptionId = r, this.mediaOptionType = Vu(this.sbType) + } + } + class pf extends p { + constructor(e, t, i, r, n, s, a = NaN) { + super(L, e, t, i, r), this.stallType = n, this.bufferLen = s, this.nudgePosition = a, this.response = r + } + } + class ff extends $t { + constructor(n, e, s, a, o, l, d, u, c) { + super(e => { + const t = Oc(l), + i = u.child({ + sb: o + }); + n.setSourceBufferEntity(o, d), d.mimeType.includes("audio/mpeg") && (this.updateMp3Timestamps = !0); + const r = an(t.event("updatestart").pipe(Za(() => { + n.setSourceBufferUpdating(o) + })), t.event("updateend").pipe(ji(tr), Za(() => { + var e = Yp.timeRangesToBufferedRange(l.buffered), + t = Yp.timeRangesToBufferedRange(s.buffered); + n.setBufferedRangesUpdated(o, e, t, !1, c) + })), t.event("error").pipe(Za(() => { + n.setSourceBufferError(o, "Got source buffer error") + }))).pipe(La(() => Ii)).subscribe(e); + return () => { + r.unsubscribe(); + try { + "open" === a.readyState && l.abort(), a.removeSourceBuffer(l) + } catch (e) { + i.error(`Error aborting SourceBuffer on unsubscribe: ${e.message}`) + } + } + }), this.mediaElementStore = n, this.mediaElementQuery = e, this.mediaElement = s, this.type = o, this.sourceBuffer = l, this.config = c, this.updateMp3Timestamps = !1 + } + get buffered() { + return this.sourceBuffer.buffered + } + appendBuffer(e, t) { + return Zr(() => this.sourceBuffer.updating ? this._waitForUpdateEndOrError().pipe(La(() => this.appendBuffer(e, t))) : this._appendBufferAsync(e, t)) + } + _appendBufferAsync(e, t) { + let i = NaN, + r = null; + const n = ("startPTS" in t ? t.frag : t).mediaOptionId; + try { + "startPTS" in t && (r = { + startPTS: t.startPTS, + endPTS: t.endPTS, + bytes: t.bytes, + frag: Object.assign({}, t.frag) + }), this.mediaElementStore.setInflightSegment(this.type, r), i = performance.now(), this.sourceBuffer.appendBuffer(e) + } catch (e) { + return 22 !== e.code ? (this.mediaElementStore.setInflightSegment(this.type, null), this.mediaElement.error ? Vi(new hf(e.message, $.VideoDecoderBadDataErr, this.type, n)) : Vi(e)) : (this.mediaElementStore.setBufferedRangesUpdated(this.type, Yp.timeRangesToBufferedRange(this.sourceBuffer.buffered), Yp.timeRangesToBufferedRange(this.mediaElement.buffered), !0, this.config), Vi(new uf(e.message, $.AllocationFailed, this.type, this.maxTotalBytes))) + } + return this._waitForUpdateEndOrError().pipe(hr(() => ({ + startAppend: i, + endAppend: performance.now(), + bytesAppend: e.byteLength + })), So(1e4), Vn(e => { + throw e instanceof dr ? (this.sourceBuffer.abort(), e = new cf("Append took longer than 10000ms", $.InternalError, this.type)) : e instanceof of && (e = new hf("Decode error", $.VideoDecoderBadDataErr, this.type, n)), e + })) + } + remove(e, t) { + return this._waitForUpdateEndOrError().pipe(La(this._removeAsync.bind(this, e, t))) + } + _removeAsync(e, t) { + try { + this.sourceBuffer.remove(e, t) + } catch (e) { + return Vi(new of (r, !1, e.message, $.InternalError, this.type)) + } + return this._waitForUpdateEndOrError() + } + abort() { + try { + this.sourceBuffer.abort() + } catch (e) { + return Vi(new of (r, !1, e.message, $.InternalError, this.type)) + } + return this._waitForUpdateEndOrError() + } + get updating() { + return this.sourceBuffer.updating + } + get timestampOffset() { + return this.sourceBuffer.timestampOffset + } + set timestampOffset(e) { + this.sourceBuffer.timestampOffset = e + } + get gotQuotaExceeded() { + var e; + return null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.gotQuotaExceeded) && void 0 !== e && e + } + get bufferedSegments() { + var e; + return null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.bufferedSegments) && void 0 !== e ? e : [] + } + get totalBytes() { + var e; + return null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.totalBytes) && void 0 !== e ? e : 0 + } + get maxTotalBytes() { + var e = null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.maxTotalBytes) && void 0 !== e ? e : 1 / 0; + return this.gotQuotaExceeded ? e : 1 / 0 + } + _waitForUpdateEndOrError() { + return this.sourceBuffer.updating && this.mediaElementStore.setSourceBufferUpdating(this.type), this.mediaElementQuery.sbUpdating$(this.type).pipe(ln(e => !1 === e), bo(this.mediaElementQuery.sbError$(this.type)), hr(([, e]) => { + if (e) throw new of (r, !1, "Got error during sourceBuffer operation", $.InternalError, this.type) + }), Ds(1)) + } + } + class mf extends $t { + constructor(a, o, e, l, t) { + super(e => { + const t = Oc(l), + i = an(t.event("sourceopen"), t.event("sourceclose"), t.event("sourceended")).pipe(Za(e => { + e = (null !== (e = null == e ? void 0 : e.target) && void 0 !== e ? e : l).readyState; + o.msReadyState = e + })), + r = this.sourceBuffers$.pipe(La(e => e ? an(...e.filter(e => null != e)) : Ii)), + n = an(i, r).pipe(La(() => Ii)).subscribe(e), + s = URL.createObjectURL(l); + return a.src = s, o.setMediaSourceEntity(s, l.readyState), () => { + n.unsubscribe(), URL.revokeObjectURL(s), a.src === s && (a.removeAttribute("src"), a.load(), o.setMediaSourceEntity(null)), this.sourceBuffers$.next(null) + } + }), this.mediaElement = a, this.mediaElementStore = o, this.mediaElementQuery = e, this.mediaSource = l, this.logger = t, this.sourceBuffers$ = new yi(null) + } + get readyState() { + return this.mediaSource.readyState + } + set duration(e) { + this.mediaSource.duration = e + } + get duration() { + return this.mediaSource.duration + } + endOfStream(e) { + this.mediaSource.endOfStream(e) + } + createSourceBuffers(e, a) { + const o = this.mediaSource; + al(() => { + try { + const s = [null, null]; + e.forEach((t, i) => { + if (t) { + var { + mimeType: r, + mediaOptionId: n + } = t; + let e; + try { + e = o.addSourceBuffer(r) + } catch (t) { + throw new lf(t.message, $.IncompatibleAsset, i, n) + } + s[i] = new ff(this.mediaElementStore, this.mediaElementQuery, this.mediaElement, this.mediaSource, i, e, t, this.logger, a) + } + }), this.sourceBuffers$.next(s) + } catch (e) { + if (!(e instanceof p)) throw new af(`error initializing sourcebuffers ${e.message} readyState=${o.readyState}`); + throw e + } + }) + } + get needSourceBuffers() { + return null == this.sourceBuffers$.value || null == this.sourceBuffers$.value[0] + } + get sourceBuffers() { + return this.sourceBuffers$.value + } + getSourceBufferByType(e) { + var t = this.sourceBuffers$.value; + return t ? t[e] : null + } + updateLiveSeekableRange(e, t) { + const i = this.mediaSource; + null != i && i.setLiveSeekableRange && "open" === (null == i ? void 0 : i.readyState) && i.setLiveSeekableRange(e, t) + } + clearLiveSeekableRange() { + const e = this.mediaSource; + null != e && e.clearLiveSeekableRange && "open" === (null == e ? void 0 : e.readyState) && e.clearLiveSeekableRange() + } + } + + function gf(e, c, t) { + const { + lowBufferThreshold: h, + lowBufferWatchdogPeriod: p, + highBufferWatchdogPeriod: f, + seekWatchdogPeriod: m + } = t, i = ed([c.desiredRate$, c.ended$, c.combinedBuffer$, c.seekTo$]).pipe(hr(e => { + var t, [i, r, n, s] = e; + return t = c.currentTime, e = i, i = r, r = n, n = isFinite(null == s ? void 0 : s.pos), s = r.some(e => e.start <= t && e.end > t), !(1 !== e || i || 0 === r.length || n && !s) + }), Is()), r = c.combinedBuffer$.pipe(hr(() => c.getCurrentWaterLevel(0) <= t.lowBufferThreshold || !c.haveEnough ? Cp.LowBuffer : Cp.HighBuffer), Is()), n = ed([i, c.seekTo$, c.gotPlaying$, r]).pipe(La(e => { + var [t, i, r] = e; + if (!t) return $i(null); + var n, s, a, o, l, d, u, e = c.nudgeCount, + t = m + +e; + return isFinite(null == i ? void 0 : i.pos) || !r ? (n = c, s = performance.now(), t = t, a = h, bn(1e3 * t).pipe(hr(() => { + var e = n.currentTime, + t = n.getCombinedBufferInfo(e, 0); + return yf(Cp.Seek, e, s, t, a, n.haveEnough) + }))) : (o = c, l = p, d = f + +e, u = h, an($i(o.currentTime), o.timeupdate$).pipe(La(e => { + const t = performance.now(), + i = o.getCombinedBufferInfo(e, 0); + let r, n; + return r = i.len <= u || !o.haveEnough ? (n = l, Cp.LowBuffer) : (n = d, Cp.HighBuffer), bn(Math.max(100, 1e3 * n)).pipe(hr(() => e < o.currentTime ? null : yf(r, e, t, i, u, o.haveEnough))) + }))) + })), s = n.pipe(Kp(), bo(c.combinedBuffer$), La(([]) => ed([c.seeking$, c.paused$])), La(([e, t]) => e || t ? Ii : c.timeupdate$.pipe(ha(), ln(([e, t]) => ne(e) && ne(t) && e < t), Ds(1))), hr(() => null)); + return an(n, s) + } + + function yf(e, t, i, r, n, s) { + var a = performance.now() - i; + return { + type: e, + isLowBufferStall: r.len <= n || !s, + tstalled: i, + stallDurationMs: a, + currentTime: t + } + } + class vf extends $t { + constructor(w, A, e, t, i, r, n) { + super(e => { + const t = this.config, + i = A.startMediaSession(w, t.maxBufferLength, t.almostDryBufferSec, t.defaultTargetDuration), + r = Sf(w, A, this._mediaQuery, this, this.hlsGapless, t, this.logger, this.rtcService), + n = this.mediaSource$.pipe(La(e => e || Ii)), + s = this._mediaQuery.seekTo$.pipe((u = w, c = this._mediaQuery, p = (h = this).config, f = (f = this.logger).child({ + name: "seek" + }), e => e.pipe(Za(e => {}), ln(e => e && ne(e.pos)), La(e => c.readyState$.pipe(ln(e => e >= u.HAVE_METADATA), Ds(1), Zs(e), La(({ + pos: e, + fromEvent: t + }) => (h.checkForInconsistentStoreBufferRangesAndUpdate(), u.paused || h.pause(), t || (u.currentTime = e), Gu(c.haveEnough$, e => e).pipe(Zs({ + pos: e, + fromEvent: t + })))), La(({ + pos: e, + fromEvent: t + }) => { + var i = c.getCombinedBufferInfo(e, 0), + r = i.nextStart; + return (!t || p.nudgeFromEventSeek) && 0 === i.len && ne(r) && e < r && r - e <= p.maxSeekHole ? (h.seekTo = r, Ii) : $i(e) + }), bo(c.desiredRate$), hr(([, e]) => { + u.paused && 0 !== e && h.play() + }), $a(Ii), Vn(e => (f.error(`error during seek ${e.message}`), Ii))))))), + a = this._mediaQuery.desiredRate$.pipe((o = w, l = this._mediaQuery, d = this, e => e.pipe(bo(l.seekTo$), La(([e, t]) => ne(null == t ? void 0 : t.pos) ? Ii : 0 === e ? (o.paused || d.pause(), Ii) : Gu(l.haveEnough$, e => e).pipe(Za(() => { + o.paused && d.play() + }))), $a(Ii)))); + var o, l, d, u, c, h, p, f; + this.liveSeekableWindow = { + start: NaN, + end: NaN + }, this.mediaFunctions = this.mediaFunctions || new sf(this, w, t, this.logger), this.mediaFunctions.install(); + var m, g, y, v, S, b, T, E, I = an(gf(this.logger, this._mediaQuery, this.config).pipe(Za(e => { + A.setStallInfo(e) + })), this.mediaQuery.stallInfo$.pipe((g = A, y = (m = this).config, v = this.logger, e => e.pipe(_s(e => e ? function(i, e, r, n) { + const s = i.mediaQuery; + return an(ed([s.seekTo$, s.nudgeTarget$]).pipe(ln(([e, t]) => e && ne(e.pos) && ne(t) && (e.pos < t || e.pos - t > r.maxSeekHole)), Zs(null)), s.stallInfo$).pipe(bo(s.desiredRate$), ji(tr), hr(([c, e], t) => { + if (!c) return NaN; + var h = s.getCombinedBufferInfo(c.currentTime, 0), + e = Wp(e); + return function(e, t, i, r, n) { + var { + type: s, + isLowBufferStall: a, + currentTime: o + } = c, l = h.len, d = t.maxSeekHole; + let u = NaN; + if (a) { + const t = h.nextStart - o <= d ? h.nextStart : 1 / 0; + ne(t) ? u = t : e.mediaQuery.msDuration - o < .1 && (u = o + .1) + } else if (n < t.nudgeMaxRetry) u = o + t.nudgeOffset; + else { + if (!r) throw i.error(`still stuck in high buffer @${o} after ${t.nudgeMaxRetry}, raise fatal error`), new pf("bufferStalledError", !0, "got fatal buffer error", $.VideoDecoderBadDataErr, s, l); + i.error(`still stuck in high buffer @${o} after ${t.nudgeMaxRetry}, non fatal in iframeMode`) + } + return ne(u) && e.nudgeSeek(u, n + 1), u + }(i, r, n, e, t) + }), Wa(e => ne(e)), Vs(() => { + e.setNudgeInfo(null) + })) + }(m, g, y, v) : $i(NaN)))))); + an(r, n, s, a, I, (S = this.mediaQuery, b = A, I = t.maxBufferHole, an((E = I, ed([(T = S).bufferMonitorThresholds$, T.combinedBuffer$, T.seeking$]).pipe(hr(([e]) => null == e ? null : tf(T, E)))), rf(S, I)).pipe(ji(tr), Za(({ + combined: e, + sbTuple: t + }) => { + b.updateWaterLevels(e, t) + })))).pipe($a(Ii), Vs(() => { + A.remove(i), this.mediaFunctions.uninstall(), this.mediaFunctions = void 0 + })).subscribe(e) + }), this.mediaElement = w, this.mediaElementStore = A, this.config = e, this.hlsGapless = t, this.logger = i, this.teardownWG$ = r, this.rtcService = n, this.mediaSource$ = new yi(null), this.mediaKeysMutex = new zp, this._mediaQuery = new nf(w, A), this.logger = i.child({ + name: "mse" + }), this.createId3Track(w), this.mediaFunctions = new sf(this, w, e, this.logger) + } + get mediaSourceAdapter() { + return this.mediaSource$.value + } + get sourceBuffers() { + var e; + return null !== (e = null === (e = this.mediaSourceAdapter) || void 0 === e ? void 0 : e.sourceBuffers) && void 0 !== e ? e : [] + } + get needSourceBuffers() { + return !this.sourceBuffers[0] + } + get mediaQuery() { + return this._mediaQuery + } + sourceBuffersBufferedRangeByType(e) { + var t, e = null === (t = null === (t = this.mediaSourceAdapter) || void 0 === t ? void 0 : t.sourceBuffers) || void 0 === t ? void 0 : t[e]; + return e ? Yp.timeRangesToBufferedRange(e.sourceBuffer.buffered) : null + } + createId3Track(e) { + this.id3Track = e.addTextTrack("metadata", "id3"), this.id3Track.mode = "hidden" + } + checkForInconsistentStoreBufferRangesAndUpdate() { + var e = Yp.timeRangesToBufferedRange(this.mediaElement.buffered), + t = this.sourceBuffersBufferedRangeByType(yu.Variant), + i = this.sourceBuffersBufferedRangeByType(yu.AltAudio), + r = null !== (n = null === (r = this.mediaQuery.sourceBufferEntityByType(yu.Variant)) || void 0 === r ? void 0 : r.bufferedRanges) && void 0 !== n ? n : null, + n = null !== (n = null === (n = this.mediaQuery.sourceBufferEntityByType(yu.AltAudio)) || void 0 === n ? void 0 : n.bufferedRanges) && void 0 !== n ? n : null; + this.shouldUpdateStoreValues(t, r) && (this.logger.warn(`[${Uu[yu.Variant]}] SourceBuffer's loaded bufferedRanges ${JSON.stringify(t)} & mediaElementStore's bufferedRanges ${JSON.stringify(r)} are out of sync!`), this.updateMediaElementStoreBufferedRanges(e, yu.Variant)), this.shouldUpdateStoreValues(i, n) && (this.logger.warn(`[${Uu[yu.AltAudio]}] SourceBuffer's loaded bufferedRanges ${JSON.stringify(i)} & mediaElementStore's bufferedRanges ${JSON.stringify(n)} are out of sync!`), this.updateMediaElementStoreBufferedRanges(e, yu.AltAudio)) + } + shouldUpdateStoreValues(e, i) { + return !(null == e && null == i || (null == e ? void 0 : e.length) == (null == i ? void 0 : i.length) && !e.find(t => { + var e = Ku.search(i, e => t.start >= e.start && t.end <= e.end ? 0 : t.end < e.start ? -1 : 1); + return null == e || e.start != t.start || e.end != t.end || void 0 + })) + } + updateMediaElementStoreBufferedRanges(e, t) { + var i = this.sourceBuffersBufferedRangeByType(t); + i && !this.mediaQuery.sbUpdating(t) && this.mediaElementStore.setBufferedRangesUpdated(t, i, e, !1, this.config) + } + destroyMediaSource() { + this.mediaSource$.next(null) + } + makeMediaSource() { + return new MediaSource + } + openMediaSource(t) { + al(() => { + var e; + t ? (e = new mf(this.mediaElement, this.mediaElementStore, this.mediaQuery, t, this.logger), this.mediaSource$.next(e)) : this.mediaSource$.next(null) + }) + } + createSourceBuffers(e) { + const t = this.mediaSource$.value; + if (!t) throw new Error("createSourceBuffers empty mediaSource"); + t.createSourceBuffers(e, this.config) + } + _waitForMediaSourceOpen(i) { + const r = this.mediaQuery.mediaSourceEntity.objectUrl; + return ed([this.mediaQuery.msReadyState$, this.mediaQuery.msObjectUrl$]).pipe(La(([e, t]) => t !== r ? $i(null) : "open" === e || "ended" === e ? $i(i) : Ii)) + } + get appendOrder() { + return this.mediaQuery.isIframeRate ? [yu.Variant, yu.AltAudio] : [yu.AltAudio, yu.Variant] + } + clearFlush(e) { + e.forEach(e => { + e && (e.dataSeg.flushBeforeAppend = { + start: 0, + end: 0 + }) + }) + } + getSwitchPosition(e) { + return e.reduce((e, t) => { + t = t ? t.dataSeg.switchPosition : void 0; + return ne(t) ? ne(e) ? Math.min(e, t) : t : e + }, void 0) + } + checkForReplay() { + var e = this.mediaElement; + e.paused && !e.seeking && e.duration && e.currentTime && e.currentTime >= e.duration - this.config.maxTotalDurationTolerance && (this.seekTo = 0) + } + resetMediaSourceIfNeeded(r) { + const n = this["mediaQuery"], + e = n["sourceBufferEntities"], + t = n.getActive()["expectedSbCount"]; + if (!e || this.needSourceBuffers) return this._waitForMediaSourceOpen(r); + const s = function(e, s, t, i) { + const r = s.filter(e => Boolean(e)).length, + n = e.filter(e => Boolean(e)).length, + l = [null, null]; + e.forEach((e, t) => { + var i, r, n, s, a, o; + e && (s = e["offsetTimestamp"], a = S(s), i = e.initSeg.mimeType, { + audioCodec: r, + videoCodec: n + } = e.initSeg.initParsedData, o = e["dataSeg"], s = S(o.startPts) - a, a = S(o.endPts) - a, o = o.discoSeqNum, l[t] = { + audioCodec: r, + videoCodec: n, + mimeType: i, + startPTSSec: s, + endPTSSec: a, + discoSeqNum: o, + mediaOptionId: e.initSeg.mediaOptionId + }) + }); + let a = r === t, + o = n === t; + if (1 === n && n < t && 0 !== r) { + const t = e[gu.Variant] ? gu.Variant : gu.AltAudio, + h = 1 - t, + r = l[t], + n = l[h] = function(e, i, r, n, t, s) { + const a = null == e ? void 0 : e.bufferedSegments; + if (!a) return s.warn("getMatchingInfo trying to query null sbEntity"), null; + s = a.find(e => { + var t = e.frag.discoSeqNum === n, + e = Math.max(i, e.startPTS) < Math.min(r, e.endPTS); + return t && e + }); + if (null == s) return null; { + const { + audioCodec: i, + videoCodec: r, + mimeType: o + } = e; + return { + mimeType: o, + audioCodec: i, + videoCodec: r, + startPTSSec: s.startPTS, + endPTSSec: s.endPTS, + discoSeqNum: n, + mediaOptionId: t + } + } + }(s[h], r.startPTSSec, r.endPTSSec, r.discoSeqNum, r.mediaOptionId, i); + if (!n) + if (null !== (e = null === (e = e[gu.Variant]) || void 0 === e ? void 0 : e.dataSeg) && void 0 !== e && e.iframe && t === gu.Variant && l[t]) { + const p = s[t].videoCodec, + h = l[t].videoCodec; + if (a = a && (p === h || be.isCompatibleVideoCodec(p, h)), a) return { + compatible: a, + boundary: NaN, + allowance: NaN, + discoSeqNum: l[t].discoSeqNum + } + } else i.warn(`${Nu[t]} No matching frag found ${ae(r)} buffered=${ae(s[h].bufferedSegments.map(e=>{var{mediaSeqNum:t,discoSeqNum:i}=e.frag;return{mediaSeqNum:t,discoSeqNum:i,startPTS:e.startPTS,endPTS:e.endPTS}}))}`); + o = null != n + } + let d = NaN, + u = NaN, + c = NaN; + return o && l.forEach((e, t) => { + if (!e) return null; + ne(c) ? c !== e.discoSeqNum && (c = NaN) : c = e.discoSeqNum; + t = s[t]; + if (t) { + const s = t.audioCodec, + i = t.videoCodec, + { + audioCodec: r, + videoCodec: n + } = e; + a = a && (i === n || be.isCompatibleVideoCodec(i, n)), a = a && (s === r || be.isCompatibleAudioCodec(s, r)) + } else a = !1; + d = ne(d) ? (u = Math.abs(e.startPTSSec - d), Math.max(e.startPTSSec, d)) : (u = 0, e.startPTSSec) + }), { + compatible: a && o, + boundary: d, + allowance: u, + discoSeqNum: c + } + }(r, e, t, (this.config.maxBufferHole, this.logger)); + if (s.compatible) return this._waitForMediaSourceOpen(r); + let i = s.boundary; + const a = s.allowance, + o = this.getSwitchPosition(r); + if (ne(o) && (i = o), !ne(i)) return this.logger.warn("not enough info #disco"), $i(null); + const l = fn(Gu(an($i(n.currentTime), n.timeupdate$), e => e >= i), Gu(n.stallInfo$.pipe(hr(e => { + return null !== (e = null == e ? void 0 : e.currentTime) && void 0 !== e ? e : NaN + })), e => e >= i - a - this.config.discontinuitySeekTolerance)); + return this.mediaElementStore.waitingForDisco = !0, l.pipe(Zs(i), La(e => { + performance.now(); + const t = n.currentTime, + i = this.msDuration; + return this.resetMediaSource(Math.max(t, e), s.discoSeqNum), this._waitForMediaSourceOpen(r).pipe(Za(() => { + performance.now(), this.msDuration = i + })) + }), Vs(() => { + this.mediaElementStore.waitingForDisco = !1 + })) + } + resetMediaSource(e = NaN, t) { + var i; + ne(e) || (e = null !== (i = null === (i = this.mediaQuery.seekTo) || void 0 === i ? void 0 : i.pos) && void 0 !== i ? i : this.mediaQuery.currentTime), ne(t) || (t = null === (i = this.mediaQuery.seekTo) || void 0 === i ? void 0 : i.discoSeqNum), 0 < this.sourceBuffers.length && (this.openMediaSource(this.makeMediaSource()), this.setSeekToWithDiscontinuity(e, t)) + } + setExpectedSbCount(e) { + this.mediaElementStore.expectedSbCount = e + } + appendInitSegments(l, d) { + const { + mediaQuery: e, + mediaElementStore: u, + sourceBuffers: c + } = this, h = e["sourceBufferEntities"]; + if (!c) throw new Error("appendInitSegments: null sourceBuffers"); + if (!h) throw new Error("appendInitSegments: null sourceBufferEntities"); + var t = this.appendOrder.map(t => { + if (l[t]) { + const i = c[t], + r = l[t], + n = h[t], + s = r["initSeg"]; + if (!n) throw new Error(`appendInitSegments: sb[${Uu[t]}] null currentSbEntity`); + if (!i) throw new Error(`appendInitSegments: sb[${Uu[t]}] null source buffer`); + const a = n.initSegmentInfo, + o = function() { + var { + itemId: e, + mediaOptionId: t, + discoSeqNum: i, + keyTagInfo: r + } = s; + return { + itemId: e, + mediaOptionId: t, + discoSeqNum: i, + keyId: je(null == r ? void 0 : r.keyId) + } + }(); + if ((e = o) && a && e.itemId === a.itemId && e.mediaOptionId === a.mediaOptionId && e.discoSeqNum === a.discoSeqNum && e.keyId === a.keyId) return $i(null); + var e = Vu(t); + return i.appendBuffer(s.data, s).pipe(Za(e => { + u.setInitSegmentEntity(t, o) + }), d(i, e, s.mediaOptionId, this.config, this.mediaQuery)) + } + }).filter(e => Boolean(e)); + return 0 === t.length ? $i(null) : en(t) + } + appendDataSegments(m, g) { + var e = this.appendOrder.map(e => { + const t = m[e], + { + mediaQuery: i, + sourceBuffers: r + } = this, + n = i["sourceBufferEntities"]; + if (!r) throw new Error("appendDataSegments: null sourceBuffers"); + if (!n) throw new Error("appendDataSegments: null sourceBufferEntities"); + if (!t) return null; + const s = r[e], + a = m[e], + o = n[e]; + if (!o) throw new Error("appendDataSegments: null currentSbEntity"); + const l = o.initSegmentInfo, + d = a["dataSeg"]; + if (!l) throw new Error(`appendDataSegments: sb[${Uu[e]}] null currentInitSegmentInfo`); + if (!o) throw new Error(`appendDataSegments: sb[${Uu[e]}] null currentSbEntity`); + if (!s) throw new Error(`appendDataSegments: sb[${Uu[e]}] null source buffer`); + const u = s.timestampOffset, + c = { + startPTS: S(d.startPts) + u, + endPTS: S(d.endPts) + u, + firstKeyframePts: d.firstKeyframePts ? S(d.firstKeyframePts) + u : void 0, + bytes: d.data2 ? d.data1.byteLength + d.data2.byteLength : d.data1.byteLength, + frag: { + itemId: d.itemId, + mediaOptionId: d.mediaOptionId, + mediaSeqNum: d.mediaSeqNum, + discoSeqNum: d.discoSeqNum, + keyTagInfo: d.keyTagInfo, + isLastFragment: d.isLastFragment, + iframe: d.iframe, + framesWithoutIDR: d.framesWithoutIDR, + dropped: d.dropped + } + }, + h = Vu(e); + let p = Wu; + var f = t.dataSeg.flushBeforeAppend; + return f && f.start !== f.end && (p = this.flushData(e, f.start, f.end)), p.pipe(La(() => $i(d.data1, d.data2).pipe(Kp()).pipe(Wn(e => s.appendBuffer(e, c).pipe(g(s, h, d.mediaOptionId, this.config, this.mediaQuery))))), Za(() => { + i.getBufferedRangeByType(e) + })) + }).filter(e => Boolean(e)); + return 0 === e.length ? $i(null) : en(e) + } + setStoreSbTimeoffsets(s) { + const { + mediaElementStore: a, + sourceBuffers: e + } = this; + e.forEach((t, i) => { + if (t && s[i]) { + var { + offsetTimestamp: r, + dataSeg: n + } = s[i], n = S(n.startPts); + let e = -1 * S(r); + t.updateMp3Timestamps && .1 < Math.abs(t.timestampOffset - n) && (e = n + e), t.timestampOffset !== e && (t.timestampOffset = e, a.setTimestampOffset(i, t.timestampOffset)) + } + }) + } + adjustJaggedStart(e) { + const { + mediaQuery: t, + logger: n + } = this, { + sourceBufferEntities: i, + currentTime: r, + seekTo: s + } = t, a = e.reduce((e, t) => null != t && t.dataSeg.endPts ? Math.min(b(t.dataSeg.endPts, t.offsetTimestamp), e) : e, Number.POSITIVE_INFINITY); + if (!i) throw new Error("appendSourceBufferData null currentSbEntity"); + const o = (null == s ? void 0 : s.pos) || r; + let l = NaN; + i.forEach((e, t) => { + if (e) { + e = Yp.getBufferedInfo(e.bufferedRanges, o, 0); + if (0 === e.len) { + const i = e["nextStart"], + r = ne(this.config.jaggedSeekTolerance) ? this.config.jaggedSeekTolerance : 0; + n.warn(`sb[${Uu[t]}] jagged start: ${i} appendEndTime=${a} current=${l} tolerance=${r}`), ne(i) && (!ne(l) || i - l > r) && (l = i) + } + } + }), ne(l) && a > l && (n.warn(`[seek] jagged start, adjusting currentTime:${r.toFixed(3)} seekTo=${null===(e=null==s?void 0:s.pos)||void 0===e?void 0:e.toFixed(3)}->${l} appendEndTime=${a}`), this.seekTo = l) + } + addCues(e, t) { + const i = this.mediaElement.textTracks[e]; + i && t.forEach(e => { + i.addCue(e) + }) + } + _flushInternal(e, t, i) { + return Zr(() => e.remove(t, i)).pipe(Za(() => {})) + } + flushAll(i, r, n = !1) { + return 0 === this.sourceBuffers.length ? Wu : en(this.sourceBuffers.map((e, t) => e ? this.flushData(t, i, r, n) : Wu)).pipe(Zs(void 0)) + } + flushData(o, l, d, u = !1) { + const { + mediaQuery: t, + logger: c + } = this; + return Gu(t.updating$, e => !1 === e).pipe(La(() => { + var e = t["sourceBufferEntities"], + e = e[o]; + null != e && e.updating && this.logger.warn(`trying to flush while updating ${o}`); + const r = this.sourceBuffers[o]; + if (!r) return Wu; + let n, s, a = Wu; + e = -1 === navigator.userAgent.toLowerCase().indexOf("firefox"); + if (this.flushing = !0, e) return this._flushInternal(r, l, d); + for (let i = 0; i < r.buffered.length; i++) { + let e, t; + n = r.buffered.start(i), s = r.buffered.end(i), t = d === 1 / 0 ? (e = l, d) : (e = Math.max(n, l), Math.min(s, d)), Math.min(t, s) > e && (u || .5 < Math.min(t, s) - e) ? a = a.pipe($a(this._flushInternal(r, e, t))) : c.warn(`ignoring sb[${Uu[o]}] flush ${e},${t}`) + } + return a + }), Vs(() => { + this.flushing = !1 + })) + } + static convertInitSegToCompatInfo(e) { + return { + mimeType: e.mimeType, + audioCodec: e.initParsedData.audioCodec, + videoCodec: e.initParsedData.videoCodec, + startPTSSec: void 0, + endPTSSec: void 0, + discoSeqNum: e.discoSeqNum, + mediaOptionId: e.mediaOptionId + } + } + static combineAppendDataInfoWithCompatInfo(e, t, i, r = 0) { + const n = [...t]; + e.forEach((e, t) => null != e && e.initSeg ? n[t] = vf.convertInitSegToCompatInfo(e.initSeg) : null); + t = n[yu.Variant].videoCodec, e = Hp(t); + if (i && i.has(e)) { + const s = i.get(e); + n[yu.Variant].mimeType = n[yu.Variant].mimeType.replace(t, s), n[yu.Variant].videoCodec = s + } + return n + } + convertSourceBufferEntitiesToCompatInfo(e) { + const t = e.sourceBufferEntities, + i = [null, null]; + return t.forEach((e, t) => { + e && (i[t] = { + mimeType: e.mimeType, + audioCodec: e.audioCodec, + videoCodec: e.videoCodec, + startPTSSec: void 0, + endPTSSec: void 0, + discoSeqNum: void 0, + mediaOptionId: null === (e = e.initSegmentInfo) || void 0 === e ? void 0 : e.mediaOptionId + }) + }), i + } + appendData(e, i, r) { + const { + mediaQuery: t, + logger: n + } = this, o = this.convertSourceBufferEntitiesToCompatInfo(t); + return e.every(e => null == e) ? $i([]) : this.resetMediaSourceIfNeeded(e).pipe(La(e => e ? t.updating$.pipe(ln(e => !1 === e), Ds(1), Zs(e)) : $i(null)), La(t => { + if (!t) return $i([]); + let s = NaN, + a = NaN; + if (this.needSourceBuffers) { + s = performance.now(); + const i = vf.combineAppendDataInfoWithCompatInfo(t, o, r, n); + this.createSourceBuffers(i), a = performance.now(), this.clearFlush(t) + } + return t.forEach(e => { + e = null == e ? void 0 : e.dataSeg; + null != e && e.cues && ne(null == e ? void 0 : e.texttrackIdx) && this.addCues(e.texttrackIdx, e.cues) + }), this.setStoreSbTimeoffsets(t), Jr(Zr(() => this.appendInitSegments(t, i)), Zr(() => this.appendDataSegments(t, i))).pipe(function(r, i) { + return 2 <= arguments.length ? function(e) { + return Bt(sa(r, i), Ws(1), (void 0 === (t = i) && (t = null), function(e) { + return e.lift(new is(t)) + }))(e); + var t + } : function(e) { + return Bt(sa(function(e, t, i) { + return r(e, t) + }), Ws(1))(e) + } + }((e, t) => (e.push(t), e), new Array), hr(([i, r]) => { + const n = [null, null]; + return [yu.Variant, yu.AltAudio].forEach(e => { + var t; + null != (null == i ? void 0 : i[e]) && (t = { + fragmentType: Vu(e), + bufferCreationStart: s, + bufferCreationEnd: a, + startInitAppend: i[e].startAppend, + endInitAppend: i[e].endAppend, + initBytesAppend: i[e].bytesAppend, + startDataAppend: r[e].startAppend, + endDataAppend: r[e].endAppend, + dataBytesAppend: r[e].bytesAppend + }, n[e] = t) + }), n + }), Za(e => { + this.adjustJaggedStart(t) + })) + }), Ds(1)) + } + endStream() { + try { + this.mediaSourceAdapter.endOfStream() + } catch (e) { + this.logger.warn(`endOfStream failed: ${e.message}`) + } + } + setMediaKeys(e) { + return this.teardownWG$.wrap(this.mediaKeysMutex.lock(() => Fr(this.mediaElement.setMediaKeys(e))).pipe(Za(() => {}), va(e => e.pipe(jr((e, t) => { + if (t < 3) return bn(100 * t); + throw e + }))))) + } + clearMediaKeys() { + return Zr(() => { + if (!this.mediaElement) return Wu; + const e = -1 < navigator.userAgent.toLowerCase().indexOf("chrome"), + t = this.mediaElement.src; + return e && (this.mediaElement.src = ""), this.setMediaKeys(null).pipe(Za(() => this.mediaElement.src = t)) + }) + } + set postFlushSeek(e) { + this.mediaElementStore.postFlushSeek = e + } + schedulePostFlushSeek(e) { + al(() => { + this.mediaQuery.seekTo && (this.seekTo = null), this.postFlushSeek = e + }) + } + set seekTo(e) { + this.mediaElementStore.setSeekToPos(e, !1) + } + setSeekToWithDiscontinuity(e, t) { + this.mediaElementStore.setSeekToPos(e, !1, t) + } + nudgeSeek(e, t) { + al(() => { + this.mediaElementStore.setSeekToPos(e, !1), this.mediaElementStore.setNudgeInfo({ + nudgeTarget: e, + nudgeCount: t + }) + }) + } + set desiredRate(e) { + this.mediaElementStore.desiredRate = e + } + toggleTrickPlaybackMode(e) { + if (this.config.overridePlaybackRate) { + const t = e ? 2 : 1; + try { + this.mediaElement.playbackRate = t + } catch (e) { + this.logger.error({ + name: "iframes" + }, `Exception when setting playbackRate=${t}: ${e.message}`) + } + } + const t = this.muteValueOnTrickPlaybackToggle; + e && void 0 === t ? (this.muteValueOnTrickPlaybackToggle = this.mediaElement.muted, this.mediaElement.muted = e) : e || void 0 === t || (this.mediaElement.muted = t, this.muteValueOnTrickPlaybackToggle = void 0) + } + play() { + this.mediaFunctions.play() + } + pause() { + this.mediaFunctions.pause() + } + get expectPlayEvent() { + return this.mediaFunctions.expectPlayEvent + } + set expectPlayEvent(e) { + this.mediaFunctions.expectPlayEvent = e + } + get expectPauseEvent() { + return this.mediaFunctions.expectPauseEvent + } + set expectPauseEvent(e) { + this.mediaFunctions.expectPauseEvent = e + } + set textTracksCreated(e) { + const t = this["mediaElementStore"]; + t.textTracksCreated = e + } + get msDuration() { + return this._mediaQuery.msDuration + } + set msDuration(e) { + try { + const t = this["mediaElementStore"], + i = this.mediaSource$.value; + i.duration !== e && (i.duration = e, t.msDuration = e) + } catch (e) { + this.logger.warn(`Error setting duration ${e.message}`) + } + } + set haveEnough(e) { + this.mediaElementStore.haveEnough = e + } + set flushing(e) { + this.mediaElementStore.flushing = e + } + set bufferMonitorTargetDuration(e) { + this.mediaElementStore.bufferMonitorTargetDuration = e + } + get textTracks() { + return this.mediaElement.textTracks + } + get id3TextTrack() { + return this.id3Track + } + addTextTrack(e, t, i) { + return this.mediaElement.addTextTrack(e, t, i) + } + dispatchEvent(e) { + return this.mediaElement.dispatchEvent(e) + } + get offsetWidth() { + return this.mediaElement.offsetWidth + } + get offsetHeight() { + return this.mediaElement.offsetHeight + } + getliveSeekableWindow() { + return this.liveSeekableWindow + } + archiveParsedSubtitleFragmentRecord(e, t, i) { + return this.mediaElementStore.archiveParsedSubtitleFragmentRecord(e, t, i) + } + updateLiveSeekableRange(e) { + var t = e.fragments, + e = t.length; + if (1 < e) { + const i = Math.max(t[0].start, 0), + r = t[e - 1].start + t[e - 1].duration; + this.mediaSource$.value.updateLiveSeekableRange(i, r), this.liveSeekableWindow.start = i, this.liveSeekableWindow.end = r + } + } + clearLiveSeekableRange() { + this.mediaSource$.value.clearLiveSeekableRange(), this.liveSeekableWindow.start = NaN, this.liveSeekableWindow.end = NaN + } + } + const Sf = (t, r, n, s, a, o, l, i) => { + if (!t) return Ii; + const e = Oc(t); + return an(e.event("durationchange").pipe(hr(e => kc(t, "durationchange", e)), Za(e => { + e = e.currentTarget; + r.mediaElementDuration = e.duration + })), e.event("seeking").pipe(ao(o.seekEventThrottleMs), hr(e => kc(t, "seeking", e)), Za(e => { + var t = e.currentTarget, + e = t.currentTime; + if (t.readyState >= t.HAVE_METADATA) { + const i = n.seekTo; + !i || !i.fromEvent && 1e-5 < Math.abs(i.pos - e) ? a.inGaplessMode ? function(e, t, i, r, n) { + let s = !1; + e < t.playingItem.itemStartOffset && (n.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${t.playingItem.itemStartOffset}`), e = t.playingItem.itemStartOffset, s = !0), t.isPreloading && (e > t.loadingItem.itemStartOffset && (n.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${t.loadingItem.itemStartOffset}`), e = t.loadingItem.itemStartOffset, s = !0), t.dequeueSource("SeekToUnbufferedTimeRanges")), s ? i.resetMediaSource(e) : r.setSeekToPos(e, !0) + }(e, a, s, r, l) : s && s.hasOwnProperty("liveSeekableWindow") && ne(s.getliveSeekableWindow().start) && ne(s.getliveSeekableWindow().end) && (e < s.getliveSeekableWindow().start || e > s.getliveSeekableWindow().end) ? function(e, t, i, r, n, s) { + let a = e; + if (e < t) a = t; + else if (i < e) { + let e = r.defaultTargetDuration; + ne(r.liveSyncDuration) ? e = r.liveSyncDuration : ne(r.liveSyncDurationCount) && (e = r.liveSyncDurationCount * r.defaultTargetDuration), a = Math.max(0, i - e) + } + s.warn(`[live] liveAdjustedSeek seekTo:${se(e,3)}, adjustedSeek:${se(a,3)}, liveWindowStart:${se(t,3)}, liveWindowEnd:${se(i,3)}`), n.setSeekToPos(a, !0) + }(e, s.getliveSeekableWindow().start, s.getliveSeekableWindow().end, o, r, l) : r.setSeekToPos(e, !0) : r.seeking = !0 + } + })), e.event("seeked").pipe(hr(e => kc(t, "seeked", e)), Za(() => { + r.setSeekToPos(null, !0) + })), e.event("play").pipe(hr(e => kc(t, "play", e)), bo(n.desiredRate$), hr(([e]) => { + var t = e.currentTarget; + r.paused = t.paused; + var i = s.expectPlayEvent, + t = t.controls || o.nativeControlsEnabled; + return !i && t && (s.checkForReplay(), r.desiredRate = 1), s.expectPlayEvent = !1, e + })), e.event("playing").pipe(hr(e => kc(t, "playing", e)), Za(e => { + e = e.currentTarget; + r.paused = e.paused, r.gotPlayingEvent() + })), e.event("loadstart").pipe(hr(e => kc(t, "loadstart", e)), Za(() => { + r.gotLoadStartEvent() + })), e.event("pause").pipe(hr(e => kc(t, "pause", e)), Za(e => { + var t = e.currentTarget; + r.paused = t.paused; + e = s.expectPauseEvent, t = t.controls || o.nativeControlsEnabled; + !e && t && (r.desiredRate = 0), s.expectPauseEvent = !1 + })), e.event("loadedmetadata").pipe(hr(e => kc(t, "loadedmetadata", e))), e.event("loadeddata").pipe(hr(e => kc(t, "loadeddata", e))), e.event("canplay").pipe(hr(e => kc(t, "canplay", e))), e.event("canplaythrough").pipe(hr(e => kc(t, "canplaythrough", e))), e.event("waiting").pipe(hr(e => kc(t, "waiting", e))), e.event("emptied").pipe(hr(e => kc(t, "emptied", e))), e.event("error").pipe(hr(e => kc(t, "error", e)), Wn(e => Vi(t.error))), e.event("ended").pipe(hr(e => kc(t, "ended", e)))).pipe(bo(n.bufferedRangeTuple$), ll(([e]) => { + var t = e.currentTarget, + e = t.readyState; + r.readyState = e, r.ended = t.ended + }), Vn(e => (e instanceof MediaError ? (l.warn(`mediaElementError, code: ${e.code}, message: ${e.message}`), null == i || i.handleMediaElementError(e)) : l.error(`media event error: ${e.message}`), Ii)), $a(on), Vn(e => e instanceof MediaError ? (l.warn(`mediaElementError, code: ${e.code}, message: ${e.message}`), Vi(e)) : (l.error(`media event error: ${e.message}`), Ii))) + }, + bf = new class extends fl { + constructor() { + super({}, { + name: "media-element-store", + producerFn: su + }), this._activeId = "" + } + get activeId() { + return this._activeId + } + startMediaSession(i, r, n, s) { + return Do("playback.session.start"), this._activeId = `media session: ${(new Date).toISOString()}`, al(() => { + var e = s, + t = Math.max(e, r - e), + t = { + id: this.activeId, + desiredRate: !i.autoplay && i.paused ? 0 : 1, + paused: i.paused, + gotPlaying: !1, + gotLoadStart: !1, + firstPlayTime: void 0, + seeking: i.seeking, + flushing: !1, + readyState: i.readyState, + ended: i.ended, + bufferedRanges: [], + haveEnough: !1, + mediaSourceEntity: null, + expectedSbCount: NaN, + bufferMonitorInfo: { + waterLevelType: null, + almostDryWaterLevelSeconds: n, + lowWaterLevelSeconds: e, + highWaterLevelSeconds: t, + maxBufferSeconds: r + }, + mediaOptionParsedSubtitleRecord: [], + textTracksCreated: !1, + waitingForDisco: !1 + }; + this.add(t), this.setActive(this.activeId) + }), this.logger = Qe().child({ + name: "UpdateBufferedSegments" + }), this.activeId + } + setMediaSourceEntity(t, i) { + Do("playback.set.msObjectUrl"), this.updateActive(e => { + e.mediaSourceEntity = null != t && null != i ? { + objectUrl: t, + readyState: i, + duration: NaN, + sourceBufferEntities: [null, null] + } : null, e.bufferedRanges = [], e.haveEnough = !1, e.readyState = 0, e.bufferMonitorInfo.waterLevelType = null + }) + } + set mediaElementDuration(t) { + Do("playback.set.mediaElementDuration"), this.updateActive(e => { + e && (e.mediaElementDuration = t) + }) + } + set msReadyState(t) { + Do("playback.set.msReadyState"), this.updateActive(({ + mediaSourceEntity: e + }) => { + e && (e.readyState = t) + }) + } + set readyState(t) { + Do(`playback.set.readyState ${t}`), this.updateActive(e => { + e.readyState = t + }) + } + set ended(t) { + Do(`playback.set.ended ${t}`), this.updateActive(e => { + e.ended = t + }) + } + set msDuration(t) { + Do("playback.set.msDuration"), this.updateActive(e => { + e.mediaSourceEntity.duration = t + }) + } + set textTracksCreated(t) { + Do("playback.set.textTracksCreated ${created}"), this.updateActive(e => { + e.textTracksCreated = t + }) + } + set expectedSbCount(t) { + Do("playback.set.expectedSbCount"), this.updateActive(e => { + e.expectedSbCount = t + }) + } + set postFlushSeek(e) { + this.updateActive({ + postFlushSeek: e + }) + } + setSeekToPos(t, i, r) { + Do(`playback.set.seekToPos: ${null==t?void 0:t.toFixed(3)} cc: ${r}`), this.updateActive(e => { + ne(t) ? (e.seekTo = { + pos: t, + fromEvent: i, + discoSeqNum: r + }, e.gotPlaying = !1, e.haveEnough = !1) : (e.seekTo = null, e.postFlushSeek = void 0), i && (e.seeking = ne(t)) + }) + } + set seeking(t) { + Do(`playback.set.seeking: ${t}`), this.updateActive(e => { + e.seeking = t + }) + } + set paused(t) { + Do(`playback.set.paused: ${t}`), this.updateActive(e => { + (e.paused = t) && (e.gotPlaying = !1) + }) + } + gotPlayingEvent() { + Do("playback.set.playing"), this.updateActive(e => { + e.paused || (e.gotPlaying = !0, e.firstPlayTime = e.firstPlayTime || performance.now()) + }) + } + gotLoadStartEvent() { + Do("playback.set.loadstart"), this.updateActive(e => { + e.gotLoadStart = !0 + }) + } + set desiredRate(t) { + Do(`playback.set.desiredRate: ${t}`), this.updateActive(e => { + e.desiredRate = t + }) + } + set haveEnough(t) { + Do(`playback.set.haveEnough: ${t}`), this.updateActive(e => { + e.haveEnough = t + }) + } + set flushing(e) { + Do(`playback.set.flushing: ${e}`), this.updateActive({ + flushing: e + }) + } + set waitingForDisco(t) { + Do(`playback.set.waitingForDisco: ${t}`), this.updateActive(e => { + e && (e.waitingForDisco = t) + }) + } + setSourceBufferUpdating(i) { + Do(`playback.set.sourcebuffers[${Uu[i]}].updating`), this.updateActive(({ + mediaSourceEntity: e + }) => { + const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; + t && (t.updating = !0, t.error = void 0) + }) + } + setTimestampOffset(i, r) { + Do(`playback.set.sourcebuffers[${Uu[i]}].timestampOffset`), this.updateActive(({ + mediaSourceEntity: e + }) => { + const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; + t && (t.timestampOffset = r) + }) + } + setBufferedRangesUpdated(a, o, l, d, u) { + Do(`playback.set.sourcebuffers[${Uu[a]}].bufferupdated`), this.updateActive(e => { + var t, i, r; + const n = null == e ? void 0 : e.mediaSourceEntity, + s = null === (r = null == n ? void 0 : n.sourceBufferEntities) || void 0 === r ? void 0 : r[a]; + if (s) { + const a = null == n ? void 0 : n.duration; + s.updating = !1, s.bufferedRanges = [...o], t = s, i = t.inFlight, r = t.bufferedSegments, i && ne(i.startPTS) && ne(i.endPTS) && function(t, i) { + let r = !1; + for (let e = t.length - 1; - 1 < e; e--) { + const s = t[e], + a = Math.max(i.startPTS, s.startPTS), + o = Math.min(i.endPTS, s.endPTS); + var n; + o <= a || ((n = (1 - (o - a) / (s.endPTS - s.startPTS)) * s.bytes) <= 0 ? t.splice(e, 1) : (s.bytes = n, s.startPTS < i.startPTS ? s.endPTS = a : (s.startPTS = o, r || (t.splice(e, 0, i), r = !0)))) + } + r || t.push(i) + }(r, i), t.inFlight = null, + function(e, t, i, r, n) { + const { + maxBufferHole: s, + bufferedSegmentEjectionToleranceMs: a + } = r, o = e.bufferedSegments, l = e.bufferedRanges; + let d, u = 0, + c = !1; + if (l.length) + for (let e = o.length - 1; - 1 < e; e--) { + const t = o[e], + r = !t.frag.iframe; + r && t.frag.isLastFragment && (d = t.frag); + var h = t.endPTS - t.startPTS; + if (h <= 0) o.splice(e, 1), null == n || n.warn(`Ejecting segment from bufferedSegments due to segmentDuration <= 0 > segment=${ae(t)}`), c = t.frag === d; + else { + var p = Bp(l, t); + if (p) { + var f = Math.max(p.start, t.startPTS), + p = Math.min(p.end, t.endPTS), + f = p - f; + if (u += t.bytes * f / h, r) + if (f < Math.min(h, s)) o.splice(e, 1), null == n || n.warn(`Ejecting segment from bufferedSegments due to tiny overlaps > segment=${ae(t)}, bufferedRanges=${ae(l)}`), c = t.frag === d; + else { + const r = t.appendedDuration, + u = (r || 0) - f, + m = Math.min(.001 * a, h); + r ? !(u > m && f != h) || t.frag.isLastFragment && p === i || (o.splice(e, 1), null == n || n.warn(`Ejecting segment from bufferedSegments due to change in current overlap > segment=${ae(t)}, delta=${u}, bufferedRanges=${ae(l)}`), c = t.frag === d) : t.appendedDuration = f + } + } else null == n || n.warn(`Ejecting segment from bufferedSegments due to no overlap > segment=${ae(t)}, bufferedRanges=${ae(l)}`), o.splice(e, 1), c = t.frag === d + } + } else o.length && o.splice(0, o.length); + e.totalDuration = d && !c && 0 < l.length ? l[l.length - 1].end : 1 / 0, e.gotQuotaExceeded = e.gotQuotaExceeded || t, e.totalBytes = u, e.maxTotalBytes = Math.max(e.totalBytes, e.maxTotalBytes) + }(s, d, a, u, this.logger) + } + e.bufferedRanges = [...l] + }) + } + setSourceBufferEntity(n, s) { + Do(`playback.set.sourcebuffers[${Uu[n]}].setSourceBufferEntity`), this.updateActive(({ + mediaSourceEntity: e + }) => { + var t, i, r; + e && ({ + mimeType: t, + audioCodec: i, + videoCodec: r + } = s, e.sourceBufferEntities[n] = { + mimeType: t, + audioCodec: i, + videoCodec: r, + updating: !1, + bufferedRanges: [], + timestampOffset: 0, + inFlight: null, + bufferedSegments: [], + totalBytes: 0, + maxTotalBytes: 0, + gotQuotaExceeded: !1, + totalDuration: 1 / 0 + }) + }) + } + setInflightSegment(i, r) { + Do(`playback.set.sourcebuffers[${Uu[i]}].setInflightSegment`), this.updateActive(({ + mediaSourceEntity: e + }) => { + const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; + t && (t.inFlight = r) + }) + } + setInitSegmentEntity(i, r) { + Do(`playback.set.sourcebuffers[${Uu[i]}].setInitSegmentEntity`), this.updateActive(({ + mediaSourceEntity: e + }) => { + const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; + t && (t.initSegmentInfo = r) + }) + } + setSourceBufferError(i, r) { + Do(`playback.set.sourcebuffers[${i}].error: ${r}`), this.updateActive(({ + mediaSourceEntity: e + }) => { + const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; + t && (t.inFlight = null, t.updating = !1, t.error = r) + }) + } + setStallInfo(t) { + Do(`playback.set.stallInfo stalled=${null!=t}`), this.updateActive(e => { + e.stallInfo = t + }) + } + setNudgeInfo(t) { + Do(`playback.set.nudgeInfo ${ae(t)}`), this.updateActive(e => { + e.nudgeInfo = t + }) + } + updateWaterLevels(t, i) { + Do("playback.set.updateWaterLevels"), this.updateActive(e => { + e.bufferMonitorInfo.waterLevelType = { + combined: t, + sbTuple: [...i] + } + }) + } + set bufferMonitorTargetDuration(i) { + Do(`playback.set.targetDuration: ${i}`), this.updateActive(e => { + if (ne(i) && 0 < i) { + const t = e.bufferMonitorInfo; + t.lowWaterLevelSeconds = Math.min(i, t.maxBufferSeconds), t.highWaterLevelSeconds = Math.max(t.lowWaterLevelSeconds, t.maxBufferSeconds - i) + } + }) + } + archiveParsedSubtitleFragmentRecord(i, r, n) { + Do(`playback.cues.set persistentId ${i} mediaSeqNum ${r}: parsed ${n.count} time-range ${n.startTime}:${n.endTime}`), this.updateActive(e => { + let t = e.mediaOptionParsedSubtitleRecord[i]; + t || (t = {}, e.mediaOptionParsedSubtitleRecord[i] = t), t[r] = n + }) + } + }; + class Tf extends bi { + constructor(e) { + super(e), this.store = e, this.displaySupportsHdr$ = this.select("supportsHdr"), this.platformInfo$ = this.select("platformInfo"), this.viewportInfo$ = this.select("viewportInfo") + } + get platformInfo() { + return this.getValue().platformInfo + } + get displaySupportsHdr() { + return this.getValue().supportsHdr + } + get viewportInfo() { + return this.getValue().viewportInfo + } + } + class Ef { + constructor(e) { + this.store = e + } + getQuery() { + return new Tf(this.store) + } + updateSupportsHdr(t) { + this.store.update(e => { + e.supportsHdr = t + }) + } + updatePlatformInfo(e) { + this.store.update({ + platformInfo: e + }) + } + updateViewportInfo(t) { + this.store.update(e => { + e.viewportInfo = t + }) + } + } + const If = new class extends dl { + constructor() { + super({ + supportsHdr: !0 + }, { + name: "platform", + producerFn: su + }) + } + }; + let wf = null; + + function Af() { + return wf = wf || new Ef(If), wf + } + class Of extends $t { + constructor(e, t) { + super(e => { + null == t || t.add(), e.add(this._handler$.pipe(jr(([e, t, i]) => e(...t).pipe(Za({ + next(e) { + i(e, null) + }, + error(e) { + i(null, e) + } + })))).subscribe()) + }), this._vanillaRPC = e, this.teardownWG$ = t, this._handler$ = new Xt + } + register(e, i) { + return this._vanillaRPC.register(e, (...t) => e => { + this._handler$.next([i, t, e]) + }) + } + invoke(e, t, r) { + return new $t(i => { + this._vanillaRPC.invoke(e, t, r)((e, t) => { + null != t ? i.error(t) : (i.next(e), i.complete()) + }) + }) + } + } + class kf extends Of { + constructor(e) { + super(e) + } + decrypt(e, t, i, r, n) { + return this.invoke("decrypt", [e, t, i, r, n], [e, t, r]) + } + } + class Cf extends Of { + constructor(e) { + super(e), this.rpcService = e, this.sessions = {}, this._onEvent = (e, t, i) => () => { + null != this.sessions[e] && this.sessions[e].observer.trigger(t, i) + }, this.rpcService.register("demuxer.event", this._onEvent) + } + init(e, t, i) { + return [{ + maxSeekHole: r, + maxBufferHole: n, + audioPrimingDelay: s, + stretchShortVideoTrack: a, + forceKeyFrameOnDiscontinuity: o + }] = [t], this.invoke("demuxer.init", [e, t = { + maxSeekHole: r, + maxBufferHole: n, + audioPrimingDelay: s, + stretchShortVideoTrack: a, + forceKeyFrameOnDiscontinuity: o + }, i], []).pipe(hr(e => { + var t = new Df(this, e); + return this.sessions[e] = t + })); + var r, n, s, a, o + } + } + class Df { + constructor(e, t) { + this.rpc = e, this.demuxSessionID = t, this.observer = new a + } + push(e, t, i, r, n, s, a, o, l, d, u, c, h) { + return this.rpc.invoke("demuxer.push", [this.demuxSessionID, e, t, i, r, n, s, a, o, l, d, u, c], null != h ? h : [e]) + } + pushWithoutTransfer(e, t, i, r, n, s, a, o, l, d, u, c) { + return this.push(e, t, i, r, n, s, a, o, l, d, u, c, []) + } + destroy() { + this.observer.removeAllListeners(), this.rpc.invoke("demuxer.destroy", [this.demuxSessionID], []).subscribe() + } + } + class Mf { + constructor() { + this.handlers = {} + } + register(e, t) { + if (null != this.handlers[e]) return !1; + this.handlers[e] = t + } + unregister(e) { + if (null != this.handlers[e]) return !1; + delete this.handlers[e] + } + invoke(e, i) { + return (t = Mf._fallbackCallback) => { + try { + if (null == this.handlers[e]) throw new Error(`command ${e} not found`); + this.handlers[e](...i)(t) + } catch (e) { + t(void 0, e) + } + } + } + teardown(e) { + this.handlers = null, e() + } + } + Mf._fallbackCallback = (e, t) => { + if (null != t) throw t + }; + const xf = e => { + e = e.child({ + name: "InlineRPCService" + }); + var t = new Mf; + return new i(t, e), new ot(t, e), t + }; + let Pf; + const Rf = e => { + try { + if (null == Pf) { + const e = new Blob(["var exports = {};var module = { exports: exports };function define(f){f()};define.amd = true;(" + Xy.toString() + ")(true);"], { + type: "text/javascript" + }), + r = URL.createObjectURL(e); + Pf = new Worker(r) + } + var t = new lt(Pf); + return i = t, n = e.child({ + name: "WorkerRPCService" + }), i.register("logger.log", (e, i, ...r) => t => { + try { + for (const i of e) n = n.child(i); + "function" == typeof n[i] && n[i](...r), t() + } catch (e) { + t(void 0, e) + } + }), t + } catch (e) { + throw new Error("Failed to create WebWorker") + } + var i, n + }, + Lf = (...r) => i => { + for (let t = 0; t < r.length; t++) { + const e = r[t]; + try { + return e(i) + } catch (e) { + if (t === r.length - 1) throw e; + i.warn(e) + } + } + }, + _f = e => Lf(Rf, xf)(e); + class Nf {} + Nf.PlayEnded = 6101, Nf.Periodic = 6110, Nf.PlayStalled = 6103, Nf.KeySessionComplete = 6104, Nf.PlayLikelyToKeepUp = 6105, Nf.PlayRateChanged = 6106, Nf.PlayError = 6107, Nf.MediaEngineStalled = 6108, Nf.SwitchComplete = 6109, Nf.VariantEnded = 6111, Nf.NwError = 6202; + const Ff = { + avc1: 1, + avc3: 1, + hvc1: { + SDR: 2, + HLG: 10, + PQ: 11 + }, + hev1: { + SDR: 2, + HLG: 10, + PQ: 11 + }, + vp09: { + SDR: 3, + HLG: 14, + PQ: 13 + }, + dvh1: { + PQ: 12 + } + }; + class Bf { + constructor(e, t) { + this.query = e, this.logger = t + } + setReportingAgent(e) { + this.reportingAgent = e + } + sendPlayEnded(e) { + var t = Nf.PlayEnded; + this.fillAndFire(t, this.query.playEnded(e)) + } + sendPlayStalled(e) { + var t = Nf.PlayStalled; + this.fillAndFire(t, this.query.playStalled(e)) + } + sendMediaEngineStalled(e) { + var t = Nf.MediaEngineStalled; + this.fillAndFire(t, this.query.mediaEngineStalled(e)) + } + sendKeySessionComplete(e) { + var t = Nf.KeySessionComplete; + this.fillAndFire(t, this.query.keySessionComplete(e)) + } + sendPlayLikelyToKeepUp(e) { + var t = Nf.PlayLikelyToKeepUp; + this.fillAndFire(t, this.query.playLikelyToKeepUp(e)) + } + sendPlayRateChange(e) { + var t = Nf.PlayRateChanged; + this.fillAndFire(t, this.query.playRateChanged(e)) + } + sendSwitchComplete(e) { + var t = Nf.SwitchComplete; + this.fillAndFire(t, this.query.switchComplete(e)) + } + sendVariantEnded(e) { + var t = Nf.VariantEnded; + this.fillAndFire(t, this.query.variantEnded(e)) + } + sendPlayError(e) { + var t = Nf.PlayError; + this.fillAndFire(t, this.query.playError(e)) + } + sendNwError(e) { + var t = Nf.NwError; + this.fillAndFire(t, this.query.nwError(e)) + } + sendPeriodic(e) { + var t = Nf.Periodic; + this.fillAndFire(t, this.query.periodic(e)) + } + fillAndFire(e, t) { + if (e !== Nf.Periodic || t.PlayTimeWC || t.ADT) { + var r = e === Nf.PlayEnded || e === Nf.Periodic ? 1 : 0; + if (this.reportingAgent) { + let i = {}; + Object.entries(t).forEach(([e, t]) => { + "object" == typeof(t = ne(t) ? Number(Number(t).toFixed(2)) : t) ? "ServerInfo" === e && Object.entries(t).forEach(([e, t]) => { + i[e] = t + }): i[e] = t + }), i = JSON.parse(JSON.stringify(i)); + try { + this.reportingAgent.issueReportingEvent(e, i, r) + } catch (e) {} + } + } + } + } + class Uf extends kl { + constructor(e, t) { + super(e), this.logger = t + } + get activeEntity() { + return this.getActive() + } + entity(e) { + return this.getEntity(e) + } + playEnded(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playEndedRecord + } + periodic(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.periodicRecord + } + playStalled(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playStalledRecord + } + mediaEngineStalled(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.mediaEngineStalledRecord + } + keySessionComplete(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.keySessionCompleteRecord + } + playLikelyToKeepUp(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playLikelyToKeepUpRecord + } + playRateChanged(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playRateChangedRecord + } + switchComplete(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.switchCompleteRecord + } + variantEnded(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.variantEndedRecord + } + playError(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playErrorRecord + } + nwError(e) { + return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.nwErrorRecord + } + } + class $f extends fl { + constructor(e) { + super({}, { + name: "rtc-store", + idKey: "itemId", + producerFn: su, + resettable: !0 + }), this.logger = e + } + createEntity(e) { + e = { + itemId: e, + sessionControlRecord: { + state: "RTC_STATE_INIT", + rate: 0, + oldRate: 0, + eventStartTime: Date.now(), + sessionStartTime: Date.now(), + lastLikelyToKeepUpTime: Date.now(), + lastPeriodicTime: Date.now(), + playLikelyToKeepUpEventCounter: 1, + periodicEventCounter: 1, + activeKeySessions: {}, + intervalVariantList: {}, + sessionVariantList: {} + }, + playEndedRecord: {}, + periodicRecord: {}, + playStalledRecord: {}, + keySessionCompleteRecord: {}, + playLikelyToKeepUpRecord: {}, + playRateChangedRecord: {}, + playErrorRecord: {}, + mediaEngineStalledRecord: {}, + switchCompleteRecord: {}, + variantEndedRecord: {}, + nwErrorRecord: {} + }; + this.add(e) + } + updateEnded(e) { + this._prepareEventPlayEnded(e) + } + updatePeriodic(e, t) { + this._prepareEventPeriodic(e, { + isFinal: t + }) + } + updateBufferStalled(e, t) { + this.update(e, ({ + sessionControlRecord: e, + variantEndedRecord: t, + periodicRecord: i, + playEndedRecord: r + }) => { + e.rate = 0, t.StallCount = (t.StallCount || 0) + 1, i.StallCount = (i.StallCount || 0) + 1, r.StallCount = (r.StallCount || 0) + 1 + }), this._prepareEventPlayStalled(e, t) + } + updateSegmentKeyLoaded(e, r) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = {}, + i = r.timestamp; + t.keyFormat = "identity", t.keyDeliveryTime = r.adt, t.currentMediaTime = r.currentTime, "RTC_STATE_INIT" === e.state && (t.keyInitTime = i - e.sessionStartTime), e.activeKeySessions[r.keyuri] = t + }), this._prepareEventKeySessionComplete(e, r) + } + updateLicenseResponseProcessed(e, i) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = e.activeKeySessions[i.keyuri]; + t.licenseResponseProcessTime = i.timestamp - t.licenseResponseSubmitTime, e.lastKeyDeliveryTime = t.keyDeliveryTime = i.timestamp - t.licenseChallengeStartTime, t.currentMediaTime = i.currentTime, e.finishedKeyUri = i.keyuri + }), this._prepareEventKeySessionComplete(e, i) + } + updateLicenseChallengeError(e, i) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = e.activeKeySessions[i.keyuri]; + e.lastKeyErrorType = t.keyErrorType = "licenseChallengeError", e.finishedKeyUri = i.keyuri + }), this._prepareEventKeySessionComplete(e, i) + } + updateLicenseResponseError(e, i) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = e.activeKeySessions[i.keyuri]; + e.lastKeyErrorType = t.keyErrorType = "licenseResponseError", e.finishedKeyUri = i.keyuri + }), this._prepareEventKeySessionComplete(e, i) + } + updateKeyAborted(e, t) { + this.update(e, ({ + sessionControlRecord: e + }) => { + e.activeKeySessions[t.keyuri].keyErrorType = "keyAborted", e.finishedKeyUri = t.keyuri + }), this._prepareEventKeySessionComplete(e, t) + } + updateCanPlay(e, t) { + this.update(e, ({}) => {}), this._prepareEventPlayLikelyToKeepUp(e, t) + } + updateRateChanged(e, t) { + this.update(e, ({ + sessionControlRecord: e + }) => { + e.rate = 100 * t.rate, 0 < t.rate && 0 === e.oldRate && (e.playInfo || (e.playInfo = []), e.playInfo.push({ + latency: t.latency + }), e.curLevelUrl || (e.curLevelUrl = t.url)) + }), this._prepareEventPlayRateChanged(e, t) + } + updateMediaError(e, r) { + this.update(e, ({ + sessionControlRecord: e, + periodicRecord: t, + playEndedRecord: i + }) => { + t.PlayerErrCount = (t.PlayerErrCount || 0) + 1, i.PlayerErrCount = (i.PlayerErrCount || 0) + 1, r.fatal && (e.rate = 0, t.FatalPlayerErrCount = (t.FatalPlayerErrCount || 0) + 1, i.FatalPlayerErrCount = (i.FatalPlayerErrCount || 0) + 1, i.ErrCode = r.details, i.ErrReason = r.code, i.ErrIsFatal = !0, i.ErrDomain = "mediaError") + }), r.fatal ? this._prepareEventPlayError(e, r) : this.update(e, ({ + sessionControlRecord: e + }) => { + var t = r.details + "/" + r.code; + e.nonFatalPlayErrList[t] = (e.nonFatalPlayErrList[t] || 0) + 1 + }) + } + updateMediaElementError(e, t) { + let i; + try { + i = JSON.parse(t.message) + } catch (e) { + this.logger.warn(`message is not JSON, ignoring; ${t.message}`) + } + var r = i ? parseInt(i.ErrReason) : null, + n = i ? parseInt(i.ErrDetail) : null; + this._prepareEventPlayError(e, { + domain: "mediaElementError", + mediaElemCode: t.code, + mediaElemReason: r, + mediaElemDetail: n, + code: null, + details: null, + fatal: null + }) + } + updateMediaEngineStalled(e, t) { + this.update(e, ({ + sessionControlRecord: e, + variantEndedRecord: t, + periodicRecord: i, + playEndedRecord: r + }) => { + e.rate = 0, t.MediaEngineStallCount = (t.MediaEngineStallCount || 0) + 1, i.MediaEngineStallCount = (i.MediaEngineStallCount || 0) + 1, r.MediaEngineStallCount = (r.MediaEngineStallCount || 0) + 1 + }), this._prepareEventMediaEngineStalled(e, t) + } + updateLevelSwitched(e, d) { + this.update(e, ({ + sessionControlRecord: e, + switchCompleteRecord: t, + periodicRecord: i, + playEndedRecord: r + }) => { + i.SwCnt = (i.SwCnt || 0) + 1, r.SwCnt = (r.SwCnt || 0) + 1; + var n = Date.now(), + s = e.curLevelUrl, + a = d.url, + i = this._getVariantInfo(s, e), + r = this._getVariantInfo(a, e); + let o, l = !1; + s && (o = r.bandwidth < i.bandwidth ? "Down" : "Up", l = r.iframes), t.BadSw = this._isBadSw(o, e.lastSwitchDir || o, l, e.lastLevelIsIframe || l, n, e.lastSwitchTime || n, d.isSeeking), e.lastSwitchDir = o, e.lastSwitchTime = n, e.lastLevelIsIframe = l, e.curLevelUrl = a, e.variantStartTimeMedia = d.currentTime + }), this._prepareEventSwitchComplete(e, d) + } + updateLevelLoadError(e, o) { + this.update(e, ({ + sessionControlRecord: e, + switchCompleteRecord: t, + periodicRecord: i, + playEndedRecord: r + }) => { + var n = Date.now(); + let s, a = !1; + if (e.curLevelUrl) { + const t = this._getVariantInfo(e.curLevelUrl, e), + i = this._getVariantInfo(o.url, e); + s = i.bandwidth < t.bandwidth ? "Down" : "Up", a = i.iframes + } + i.SwCnt = (i.SwCnt || 0) + 1, r.SwCnt = (r.SwCnt || 0) + 1, t.BadSw = this._isBadSw(s, e.lastSwitchDir || s, a, e.lastLevelIsIframe || a, n, e.lastSwitchTime || n, o.isSeeking), t.SwFail = !0 + }), this._prepareEventSwitchComplete(e, o) + } + updateVariantEnd(e, t) { + this._prepareEventVariantEnded(e, t) + } + updateNwError(e, r) { + this.update(e, ({ + sessionControlRecord: e, + periodicRecord: t, + playEndedRecord: i + }) => { + t.NwErrCount = (t.NwErrCount || 0) + 1, i.NwErrCount = (i.NwErrCount || 0) + 1, r.fatal && (e.rate = 0, t.FatalNwErrCount = (t.FatalNwErrCount || 0) + 1, i.FatalNwErrCount = (i.FatalNwErrCount || 0) + 1, i.ErrCode = r.details, i.ErrReason = r.code, i.ErrIsFatal = !0, i.ErrDomain = "networkError") + }), r.fatal ? this._prepareEventNwError(e, r) : this.update(e, ({ + sessionControlRecord: e + }) => { + var t = r.details + "/" + r.code; + e.nonFatalNwErrList[t] = (e.nonFatalNwErrList[t] || 0) + 1 + }) + } + finalize(e, t) { + switch (t) { + case Nf.PlayEnded: + this.update(e, ({ + sessionControlRecord: e + }) => { + e.state = "RTC_STATE_STOP", e.oldRate = 0 + }), this.update(e, e => { + e.playEndedRecord = {} + }); + break; + case Nf.Periodic: + this.update(e, ({ + sessionControlRecord: t + }) => { + t.lastPeriodicTime = Date.now(), t.periodicEventCounter += 1, Object.keys(t.intervalVariantList).forEach(e => { + t.intervalVariantList[e].playTime = 0 + }) + }), this.update(e, e => { + e.periodicRecord = {} + }); + break; + case Nf.PlayStalled: + this.update(e, ({ + sessionControlRecord: e + }) => { + e.state = "RTC_STATE_STALL", e.oldRate = 0 + }), this.update(e, e => { + e.playStalledRecord = {} + }); + break; + case Nf.KeySessionComplete: + this.update(e, ({ + sessionControlRecord: e + }) => { + delete e.activeKeySessions[e.finishedKeyUri] + }), this.update(e, e => { + e.keySessionCompleteRecord = {} + }); + break; + case Nf.PlayLikelyToKeepUp: + this.update(e, ({ + sessionControlRecord: e + }) => { + "RTC_STATE_PLAY" !== e.state && (e.state = "RTC_STATE_CANPLAY", e.lastLikelyToKeepUpTime = Date.now(), e.playLikelyToKeepUpEventCounter += 1) + }), this.update(e, e => { + e.playLikelyToKeepUpRecord = {} + }); + break; + case Nf.PlayRateChanged: + this.update(e, ({ + sessionControlRecord: e, + playEndedRecord: t, + playStalledRecord: i, + mediaEngineStalledRecord: r, + playErrorRecord: n, + nwErrorRecord: s + }) => { + 0 !== e.rate ? (e.state = "RTC_STATE_PLAY", delete t.LastStall, delete t.LastMediaEngineStall, delete t.LastPause, delete n.LastPause, delete s.LastPause) : (e.state = "RTC_STATE_PAUSE", delete i.LastResume, delete r.LastResume, delete n.LastResume, delete s.LastResume), e.oldRate = e.rate + }), this.update(e, e => { + e.playRateChangedRecord = {} + }); + break; + case Nf.PlayError: + this.update(e, ({ + sessionControlRecord: e + }) => { + e.state = "RTC_STATE_PLAYERROR" + }), this.update(e, e => { + e.playErrorRecord = {} + }); + break; + case Nf.MediaEngineStalled: + this.update(e, ({ + sessionControlRecord: e + }) => { + e.state = "RTC_STATE_MEDIAENGINESTALL", e.oldRate = 0 + }), this.update(e, e => { + e.mediaEngineStalledRecord = {} + }); + break; + case Nf.SwitchComplete: + this.update(e, e => { + e.switchCompleteRecord = {}, e.sessionControlRecord.prevLevelUrl = e.sessionControlRecord.curLevelUrl + }); + break; + case Nf.VariantEnded: + this.update(e, ({ + sessionControlRecord: e + }) => { + e.decodedFramesForVariant = 0, e.decodedFramesForVariantSampleCount = 0 + }), this.update(e, e => { + e.variantEndedRecord = {} + }); + break; + case Nf.NwError: + this.update(e, ({ + sessionControlRecord: e + }) => { + e.state = "RTC_STATE_NWERROR" + }), this.update(e, e => { + e.nwErrorRecord = {} + }) + } + this.update(e, ({ + sessionControlRecord: e + }) => { + e.eventStartTime = Date.now() + }) + } + updatePlaybackInfo(e, s) { + this.update(e, ({ + sessionControlRecord: e, + periodicRecord: t, + playEndedRecord: i + }) => { + s.droppedVideoFrames < e.droppedVideoFrames && (e.droppedVideoFrames = 0), s.decodedFrameCount < e.decodedFrameCount && (e.decodedFrameCount = 0); + var r = s.droppedVideoFrames - (e.droppedVideoFrames || 0), + n = s.decodedFrameCount - (e.decodedFrameCount || 0); + e.droppedVideoFrames = s.droppedVideoFrames, e.decodedFrameCount = s.decodedFrameCount, e.decodedFramesForVariant += n, e.decodedFramesForVariantSampleCount += 1, r && (3 <= r ? (t.GroupViFrDr = (t.GroupViFrDr || 0) + r, t.GroupViFrDrEvtCount = (t.GroupViFrDrEvtCount || 0) + 1, i.GroupViFrDr = (i.GroupViFrDr || 0) + r, i.GroupViFrDrEvtCount = (i.GroupViFrDrEvtCount || 0) + 1) : (t.SparseViFrDr = (t.SparseViFrDr || 0) + r, t.SparseViFrDrEvtCount = (t.SparseViFrDrEvtCount || 0) + 1, i.SparseViFrDr = (i.SparseViFrDr || 0) + r, i.SparseViFrDrEvtCount = (i.SparseViFrDrEvtCount || 0) + 1)) + }) + } + updateBufferAppended(e, t) { + this.update(e, ({ + sessionControlRecord: e + }) => { + e.bufferAppendInfo || (e.bufferAppendInfo = []), e.bufferAppendInfo.push(t) + }) + } + updateSeeked(e, t) { + this.update(e, ({ + sessionControlRecord: e + }) => { + e.seekInfo || (e.seekInfo = []), e.seekInfo.push(t) + }) + } + updateManifestParsed(e, r) { + this.update(e, ({ + sessionControlRecord: e, + periodicRecord: t, + playEndedRecord: i + }) => { + t.MasterPlaylistADT = (t.MasterPlaylistADT || 0) + r.adt, i.MasterPlaylistADT = (i.MasterPlaylistADT || 0) + r.adt; + t = this._computeVariantInfo(r.levels); + i.IsAudioOnly = r.isAudioOnly, i.IsGapless = r.isGapless, i.IsFirstItem = r.isFirstItem, i.ItemID = r.itemID, i.MaxVideoQltyIndex = t.maxVideoQltyIndex, i.MaxReWd = t.maxWidth, i.MaxReHt = t.maxHeight, e.manifestData = { + variantList: t.variantList, + varListString: t.varListString + } + }) + } + updateFragLoaded(e, r) { + this.update(e, ({ + sessionControlRecord: e, + periodicRecord: t, + playEndedRecord: i + }) => { + if (t.MediaRequestsSent = (t.MediaRequestsSent || 0) + 1, i.MediaRequestsSent = (i.MediaRequestsSent || 0) + 1, r.cdnServer) { + const e = r.cdnServer.toLowerCase(); + "aapl" !== e && "akam" !== e && "llnw" !== e || (i.LastMediaCDNServer = e) + } + r.serverInfo && (i.ServerInfo = r.serverInfo), e.segmentMimeTypes || (e.segmentMimeTypes = []), void 0 === e.segmentMimeTypes.find(e => e == r.contentType) && e.segmentMimeTypes.push(r.contentType), r.fragType === gu.Variant ? (e.variantVideoBytes = (e.variantVideoBytes || 0) + r.bytes, e.variantVideoDuration = (e.variantVideoDuration || 0) + r.duration, e.intervalVideoBytes = (e.intervalVideoBytes || 0) + r.bytes, e.intervalVideoDuration = (e.intervalVideoDuration || 0) + r.duration, e.sessionVideoBytes = (e.sessionVideoBytes || 0) + r.bytes, e.sessionVideoDuration = (e.sessionVideoDuration || 0) + r.duration, e.obrLast = 8 * r.bytes / (r.duration / 1e3), t.NetBytes = (t.NetBytes || 0) + r.bytes, t.ADT = (t.ADT || 0) + r.adt, t.SegmentProcessTime = (t.SegmentProcessTime || 0) + r.processTime, i.ADT = (i.ADT || 0) + r.adt, i.NetBytes = (i.NetBytes || 0) + r.bytes, i.SegmentProcessTime = (i.SegmentProcessTime || 0) + r.processTime) : r.fragType === gu.AltAudio && (e.variantAudioBytes = (e.variantAudioBytes || 0) + r.bytes, e.variantAudioDuration = (e.variantAudioDuration || 0) + r.duration, e.intervalAudioBytes = (e.intervalAudioBytes || 0) + r.bytes, e.intervalAudioDuration = (e.intervalAudioDuration || 0) + r.duration, e.sessionAudioBytes = (e.sessionAudioBytes || 0) + r.bytes, e.sessionAudioDuration = (e.sessionAudioDuration || 0) + r.duration) + }) + } + updateFragBuffered(e, i) { + this.update(e, ({ + periodicRecord: e, + playEndedRecord: t + }) => { + i.fragType === gu.Variant && (e.SegmentParseTime = (e.SegmentParseTime || 0) + i.parseTime, t.SegmentParseTime = (t.SegmentParseTime || 0) + i.parseTime) + }) + } + updateLevelLoaded(e, n) { + this.update(e, ({ + sessionControlRecord: e, + playLikelyToKeepUpRecord: t, + periodicRecord: i, + playEndedRecord: r + }) => { + t.PlaylistADT = (t.PlaylistADT || 0) + n.adt, i.PlaylistADT = (i.PlaylistADT || 0) + n.adt, r.PlaylistADT = (r.PlaylistADT || 0) + n.adt, i.MaxPlaylistDT = n.adt > i.MaxPlaylistDT ? n.adt : i.MaxPlaylistDT, r.MaxPlaylistDT = n.adt > r.MaxPlaylistDT ? n.adt : r.MaxPlaylistDT, r.PlayType = n.playType, this._setTargetDuration(n.url, n.targetduration, e), e.playlistMimeTypes || (e.playlistMimeTypes = []), void 0 === e.playlistMimeTypes.find(e => e == n.contentType) && e.playlistMimeTypes.push(n.contentType); + i = n.url, r = this._getVariantInfo(i, e); + e.intervalVariantList[i] || (e.intervalVariantList[i] = Object.assign({}, r)), e.sessionVariantList[i] || (e.sessionVariantList[i] = Object.assign({}, r)) + }) + } + updateLevelsChanged(e, r) { + this.update(e, ({ + sessionControlRecord: t, + playEndedRecord: e + }) => { + const i = this._computeVariantInfo(r.levels); + e.MaxVideoQltyIndex = i.maxVideoQltyIndex, e.MaxReWd = i.maxWidth, e.MaxReHt = i.maxHeight, t.manifestData = { + variantList: i.variantList, + varListString: i.varListString + }, Object.keys(i.variantList).forEach(e => { + t.intervalVariantList[e] && (t.intervalVariantList[e].brRnk = i.variantList[e].brRnk), t.sessionVariantList[e] && (t.sessionVariantList[e].brRnk = i.variantList[e].brRnk) + }) + }) + } + updateLicenseChallengeRequested(e, r) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = {}, + i = r.timestamp; + t.licenseChallengeStartTime = i, "RTC_STATE_INIT" === e.state && (t.keyInitTime = i - e.sessionStartTime), e.activeKeySessions[r.keyuri] = t + }) + } + updateLicenseChallengeReceived(e, i) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = e.activeKeySessions[i.keyuri]; + t.licenseChallengeRequestTime = i.timestamp - t.licenseChallengeStartTime + }) + } + updateLicenseChallengeSubmitted(e, i) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = e.activeKeySessions[i.keyuri]; + t.keyFormat = i.keyFormat, t.licenseChallengeSubmitTime = i.timestamp + }) + } + updateLicenseChallengeCreated(e, i) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = e.activeKeySessions[i.keyuri]; + t.cdmVersion = i.cdmVersion, t.licenseChallengeCreationTime = i.timestamp - t.licenseChallengeSubmitTime + }) + } + updateLicenseResponseRequested(e, t) { + this.update(e, ({ + sessionControlRecord: e + }) => { + e.activeKeySessions[t.keyuri].licenseResponseRequestTime = t.timestamp + }) + } + updateLicenseResponseReceived(e, i) { + this.update(e, ({ + sessionControlRecord: e + }) => { + const t = e.activeKeySessions[i.keyuri]; + t.licenseResponseReceiveTime = i.timestamp - t.licenseResponseRequestTime + }) + } + updateLicenseResponseSubmitted(e, t) { + this.update(e, ({ + sessionControlRecord: e + }) => { + e.activeKeySessions[t.keyuri].licenseResponseSubmitTime = t.timestamp + }) + } + _prepareEventPlayEnded(e) { + this.update(e, ({ + sessionControlRecord: e, + playEndedRecord: t + }) => { + t.AvgVideoBitrate = 8 * (e.sessionVideoBytes || 0) / (e.sessionVideoDuration || 1), t.AvgAudioBitrate = 8 * (e.sessionAudioBytes || 0) / (e.sessionAudioDuration || 1); + var i = 1e3 * Math.round((t.NetBytes || 0) / 1e3); + t.NetBytes = i; + var r = t.ADT || 1, + n = t.ADT + t.SegmentProcessTime || 1, + s = t.ADT + t.SegmentProcessTime + t.SegmentParseTime || 1; + t.TWOBR = 8 * i / (r / 1e3), t.PerceivedTWOBR = 8 * i / (n / 1e3), t.NetTWOBR = 8 * i / (s / 1e3); + var s = this._findTimeWeightedValues("RTC_STATE_PLAY" === e.state ? Date.now() - e.eventStartTime : 0, e.sessionVariantList, e.curLevelUrl); + t.PlayerTWIBR = s.twIBR, t.PlayerTWIABR = s.twIABR, t.TWBitRk = s.twBRnk; + s = this._getVariantInfo(e.curLevelUrl, e); + t.TargetDur = s.targetduration, t.ReWd = s.width, t.ReHt = s.height, t.VariantList = null === (s = e.manifestData) || void 0 === s ? void 0 : s.varListString; + let a = ""; + e.playlistMimeTypes && (e.playlistMimeTypes.forEach(e => { + a += e + "," + }), a = a.slice(0, -1)); + let o = ""; + e.segmentMimeTypes && (e.segmentMimeTypes.forEach(e => { + o += e + "," + }), o = o.slice(0, -1)), t.PlaylistMimeType = a, t.SegmentMimeType = o, t.Rate = e.rate + }), this._aggregateTimes(e) + } + _prepareEventPeriodic(e, o) { + this.update(e, ({ + sessionControlRecord: e, + periodicRecord: t, + playEndedRecord: i + }) => { + t.EventCounter = e.periodicEventCounter, t.PInterval = Date.now() - e.lastPeriodicTime, t.AvgVideoBitrate = 8 * (e.intervalVideoBytes || 0) / (e.intervalVideoDuration || 1), t.AvgAudioBitrate = 8 * (e.intervalAudioBytes || 0) / (e.intervalAudioDuration || 1); + let r = t.NetBytes || 0; + o.isFinal && (t.NetBytes = r = 1e3 * Math.round(r / 1e3)); + var n = t.ADT || 1, + s = t.ADT + t.SegmentProcessTime || 1, + a = t.ADT + t.SegmentProcessTime + t.SegmentParseTime || 1; + t.TWOBR = 8 * r / (n / 1e3), t.PerceivedTWOBR = 8 * r / (s / 1e3), t.NetTWOBR = 8 * r / (a / 1e3); + var a = this._findTimeWeightedValues("RTC_STATE_PLAY" === e.state ? Date.now() - e.eventStartTime : 0, e.intervalVariantList, e.curLevelUrl); + t.PlayerTWIBR = a.twIBR, t.PlayerTWIABR = a.twIABR, t.TWBitRk = a.twBRnk; + a = this._getVariantInfo(e.curLevelUrl, e); + t.TargetDur = a.targetduration, t.ReWd = a.width, t.ReHt = a.height, t.VariantList = null === (a = e.manifestData) || void 0 === a ? void 0 : a.varListString, t.Rate = e.rate; + e = this._computeMediaStats(e); + e && (t.MedianBufferAppendLatency = e.bufLatencyInfo.median, t.MaxBufferAppendLatency = e.bufLatencyInfo.max, t.MedianBufferAppendSize = e.bufSizeInfo.median, t.MaxBufferAppendSize = e.bufSizeInfo.max, t.MedianSeekLatency = e.seekLatencyInfo.median, t.MaxSeekLatency = e.seekLatencyInfo.max, t.MedianPlayLatency = e.playLatencyInfo.median, t.MaxPlayLatency = e.playLatencyInfo.max), this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventPlayStalled(e, s) { + this.update(e, ({ + sessionControlRecord: e, + playStalledRecord: t, + playEndedRecord: i + }) => { + var r = this._getVariantInfo(e.curLevelUrl, e), + n = Date.now(); + t.MediaDur = s.mediaDur, t.BitRnk = r.brRnk, t.Codecs = r.codecs, t.LastLikelyToKeepUp = n - e.lastLikelyToKeepUpTime, t.LastSwitch = n - e.lastSwitchTime, t.StallDetectionTime = s.stallDurationMs, t.StallType = s.type, t.BufferLength = s.bufferLen, "networkError" === i.ErrDomain && (t.NwErrTime = i.NwErrTime, t.NwErrCode = i.ErrCode), t.LaSwDir = e.lastSwitchDir, t.TargetDur = r.targetduration, t.PlayerIABR = r.avgBandwidth, t.PlayerIBR = r.bandwidth, t.Rate = e.rate, t.OBRLast = e.obrLast, t.OBRMean = 8 * i.NetBytes / (i.ADT / 1e3), this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventKeySessionComplete(e, r) { + this.update(e, ({ + sessionControlRecord: e, + keySessionCompleteRecord: t, + playEndedRecord: i + }) => { + e = e.activeKeySessions[r.keyuri]; + e ? (t.KeyFormat = e.keyFormat, t.CDMVersion = e.cdmVersion, t.LicenseChallengeRequestTime = e.licenseChallengeRequestTime, t.LicenseChallengeCreationTime = e.licenseChallengeCreationTime, t.LicenseResponseReceiveTime = e.licenseResponseReceiveTime, t.LicenseResponseProcessTime = e.licenseResponseProcessTime, t.KeyDeliveryTime = e.keyDeliveryTime, t.CurrentMediaTime = 1e3 * e.currentMediaTime, t.KeyInitTime = e.keyInitTime, t.KeyErrorType = e.keyErrorType, this._copyCommonKeys(t, i)) : this.logger.warn(`_prepareEventKeySessionComplete no keySessionInfo for ${le(r.keyuri)}`) + }), this._aggregateTimes(e) + } + _prepareEventPlayLikelyToKeepUp(e, n) { + this.update(e, ({ + sessionControlRecord: e, + playLikelyToKeepUpRecord: t, + playEndedRecord: i + }) => { + var r = this._getVariantInfo(e.curLevelUrl, e); + t.EventCounter = e.playLikelyToKeepUpEventCounter, t.PlayerIABR = r.avgBandwidth, t.PlayerIBR = r.bandwidth, t.MediaDur = n.mediaDur, t.BitRnk = r.brRnk, t.Codecs = r.codecs, t.TargetDur = r.targetduration, this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventPlayRateChanged(e, n) { + this.update(e, ({ + sessionControlRecord: e, + playRateChangedRecord: t, + playEndedRecord: i + }) => { + var r = this._getVariantInfo(e.curLevelUrl, e); + t.Rate = e.rate, t.StNPT = n.currentTime, t.PlayerIABR = r.avgBandwidth, t.PlayerIBR = r.bandwidth, t.BitRnk = r.brRnk, t.MediaDur = n.mediaDur, t.Codecs = r.codecs, this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventPlayError(e, s) { + this.update(e, ({ + sessionControlRecord: e, + playErrorRecord: t, + playEndedRecord: i + }) => { + var r = this._getVariantInfo(e.curLevelUrl, e), + n = Date.now(); + "mediaElementError" == s.domain ? (t.ErrDomain = t.ErrCode = "mediaElementError", t.ErrIsFatal = !0, t.ErrCodeMediaElement = s.mediaElemCode, t.ErrReason = s.mediaElemReason, t.ErrDetail = s.mediaElemDetail) : (t.ErrCode = s.details, t.ErrReason = s.code, t.ErrIsFatal = s.fatal, t.ErrDomain = "mediaError"), t.PlayerErrCount = s.count || 1, t.BitRnk = r.brRnk, t.MediaDur = s.mediaDur, t.PlayTime = i.PlayTime, t.PlayTimeWC = i.PlayTimeWC, t.PlayerIABR = r.avgBandwidth, t.PlayerIBR = r.bandwidth, t.LastLikelyToKeepUp = n - e.lastLikelyToKeepUpTime, t.LastSwitch = n - e.lastSwitchTime, t.VideoQltyIndex = r.qltyIndex, t.Rate = e.rate, t.KeyErrorType = e.lastKeyErrorType, t.KeyDeliveryTime = e.lastKeyDeliveryTime, this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventMediaEngineStalled(e, s) { + this.update(e, ({ + sessionControlRecord: e, + mediaEngineStalledRecord: t, + playEndedRecord: i + }) => { + var r = Date.now(), + n = this._getVariantInfo(e.curLevelUrl, e); + t.MediaDur = s.mediaDur, t.BitRnk = n.brRnk, t.Codecs = n.codecs, t.LastLikelyToKeepUp = r - e.lastLikelyToKeepUpTime, t.LastSwitch = r - e.lastSwitchTime, t.StallDetectionTime = s.stallDurationMs, t.StallType = s.type, t.BufferLength = s.bufferLen, t.LaSwDir = e.lastSwitchDir, t.TargetDur = n.targetduration, t.PlayerIABR = n.avgBandwidth, t.PlayerIBR = n.bandwidth, t.Rate = e.rate, t.OBRLast = e.obrLast, t.OBRMean = 8 * i.NetBytes / (i.ADT / 1e3), this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventSwitchComplete(e, s) { + this.update(e, ({ + sessionControlRecord: e, + switchCompleteRecord: t, + playEndedRecord: i + }) => { + var r = this._getVariantInfo(e.prevLevelUrl, e), + n = this._getVariantInfo(e.curLevelUrl, e); + t.FrBitRnk = r.brRnk, t.ToBitRnk = n.brRnk, t.TimeToBitrate = Date.now() - e.sessionStartTime, t.MediaDur = s.mediaDur, t.Rate = e.rate, t.PlayerIBR = n.bandwidth, t.PlayerIABR = n.avgBandwidth, t.LastPlayerIBR = r.bandwidth, t.LastPlayerIABR = r.avgBandwidth, t.ReWd = n.width, t.ReHt = n.height, this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventVariantEnded(e, n) { + this.update(e, ({ + sessionControlRecord: e, + variantEndedRecord: t, + playEndedRecord: i + }) => { + var r = this._getVariantInfo(e.curLevelUrl, e); + t.Rate = e.rate, t.VarAvgBitrate = r.avgBandwidth, t.VarPeakBitrate = r.bandwidth, t.VarBitRk = r.brRnk, t.VarSTTime = e.variantStartTimeMedia, t.VarEndTime = 1e3 * n.currentTime, t.IFR = r.framerate, t.ODR = e.decodedFramesForVariant / e.decodedFramesForVariantSampleCount, t.ReWd = r.width, t.ReHt = r.height, t.Codecs = r.codecs, t.AvgVideoBitrate = 8 * (e.variantVideoBytes || 0) / (e.variantVideoDuration || 1), t.AvgAudioBitrate = 8 * (e.variantAudioBytes || 0) / (e.variantAudioDuration || 1), this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _prepareEventNwError(e, n) { + this.update(e, ({ + sessionControlRecord: e, + nwErrorRecord: t, + playEndedRecord: i + }) => { + var r = this._getVariantInfo(e.curLevelUrl, e); + t.ErrCode = n.details, t.ErrReason = n.code, t.ErrIsFatal = n.fatal, t.NwErrCount = n.count || 1, t.ErrDomain = "networkError", t.PlayTime = i.PlayTime, t.PlayTimeWC = i.PlayTimeWC, t.BitRnk = r.brRnk, t.Rate = e.rate, t.KeyErrorType = e.lastKeyErrorType, t.KeyDeliveryTime = e.lastKeyDeliveryTime, this._copyCommonKeys(t, i) + }), this._aggregateTimes(e) + } + _copyCommonKeys(e, t) { + e.PlayType = t.PlayType, e.LastMediaCDNServer = t.LastMediaCDNServer, e.MaxVideoQltyIndex = t.MaxVideoQltyIndex, e.MaxReWd = t.MaxReWd, e.MaxReHt = t.MaxReHt, e.IsGapless = t.IsGapless, e.IsAudioOnly = t.IsAudioOnly, e.IsFirstItem = t.IsFirstItem, e.ItemID = t.ItemID, e.ServerInfo = t.ServerInfo + } + _computeVariantInfo(e) { + const i = {}; + let r = 0, + n = 0, + s = 0, + a = 0; + const o = this._getMaxNormalizedPeak(e); + e.forEach(e => { + if (e.attrs) { + const r = this._getVideoFourCC(e.attrs.CODECS), + n = this._getVideoQualityIndex(r, e.attrs["VIDEO-RANGE"]) || 0, + s = { + codecs: e.attrs.CODECS, + width: e.width, + height: e.height, + bandwidth: e.attrs.BANDWIDTH, + avgBandwidth: e.attrs["AVERAGE-BANDWIDTH"], + framerate: e.attrs["FRAME-RATE"], + iframes: e.iframes, + brRnk: this._getBitrateRank(e.attrs.BANDWIDTH, r, o), + qltyIndex: n, + targetduration: 0, + playTime: 0 + }; + a = n > a ? n : a, i[e.url] = s + } + var t = e.width * e.height; + t > s && (s = t, r = e.width, n = e.height) + }); + e = 0 < Object.keys(i).length ? Object.values(i).map(e => e.bandwidth + ":" + e.avgBandwidth).join(",") : void 0; + return { + variantList: i, + varListString: e, + maxVideoQltyIndex: a, + maxWidth: r, + maxHeight: n + } + } + _getMaxNormalizedPeak(e) { + let n = 0; + return e.forEach(e => { + e = e.attrs; + if (e) { + const t = e.BANDWIDTH || 0, + i = this._getNormalizedPeak(t, this._getVideoFourCC(e.CODECS)), + r = Math.max(t, i); + n = r > n ? r : n + } + }), n + } + _getNormalizedPeak(e, t) { + return "object" == typeof Ff[t] ? 1.5 * e : +e + } + _getVideoFourCC(e) { + return e && e.split(",").map(e => e.split(".")[0].trim()).find(e => !!Ff[e]) + } + _getVideoQualityIndex(e, t) { + return "object" == typeof Ff[e] ? Ff[e][t] : Ff[e] + } + _getBitrateRank(e, t, i) { + t = Math.max(1, this._getNormalizedPeak(e, t)); + return Math.ceil(100 * t / i) + } + _findTimeWeightedValues(o, l, d) { + const e = { + twBRnk: 0, + twIBR: 0, + twIABR: 0 + }; + if (l) { + let i = 0, + r = 0, + n = 0, + s = 0, + a = 0; + Object.values(l).forEach(e => { + let t = e.playTime; + e === l[d] && (t += o || 0), t && (r += e.bandwidth * t, i += e.brRnk * t, n += t, e.avgBandwidth && (s += e.avgBandwidth * t, a += t)) + }), n && (e.twBRnk = i / n, e.twIBR = r / n), s && a && (e.twIABR = s / a) + } + return e + } + _computeMediaStats(e) { + const t = e.bufferAppendInfo; + let i = []; + const r = []; + t && t.forEach && t.forEach(e => { + i.push(e.latency), r.push(e.size) + }); + var n = this._computeStats(i), + s = this._computeStats(r), + a = e.seekInfo; + i = [], a && a.forEach && e.seekInfo.forEach(e => i.push(e.latency)); + var o = this._computeStats(i), + a = e.playInfo; + return i = [], a && a.forEach && e.playInfo.forEach(e => i.push(e.latency)), { + bufLatencyInfo: n, + bufSizeInfo: s, + seekLatencyInfo: o, + playLatencyInfo: this._computeStats(i) + } + } + _computeStats(e) { + let t, i; + if (e) { + const r = e.filter(e => 0 < e); + if (0 < r.length) { + t = r.reduce((e, t) => Math.max(e, t)); + const e = r.length, + n = r.sort((e, t) => e - t), + s = Math.ceil(e / 2); + i = e % 2 == 0 ? (n[s] + n[s - 1]) / 2 : n[s - 1] + } + } + return { + max: t, + median: i + } + } + _getVariantInfo(e, t) { + return e && t.manifestData && t.manifestData.variantList && t.manifestData.variantList[e] ? t.manifestData.variantList[e] : {} + } + _setTargetDuration(e, t, i) { + e && i.manifestData && i.manifestData.variantList && i.manifestData.variantList[e] && (i.manifestData.variantList[e].targetduration = t) + } + _isBadSw(e, t, i, r, n, s, a) { + let o = n - s < 1e4 && t !== e && r === i && !a ? !0 : !1; + return o + } + _aggregateTimes(e) { + this.update(e, ({ + sessionControlRecord: t, + playLikelyToKeepUpRecord: i, + playStalledRecord: r, + mediaEngineStalledRecord: n, + switchCompleteRecord: s, + playRateChangedRecord: a, + variantEndedRecord: o, + playErrorRecord: l, + nwErrorRecord: d, + periodicRecord: u, + playEndedRecord: c + }) => { + var h = Date.now() - t.eventStartTime; + switch (t.state) { + case "RTC_STATE_INIT": + i.StartupTime = (i.StartupTime || 0) + h, u.InitTime = (u.InitTime || 0) + h, c.InitTime = (c.InitTime || 0) + h; + break; + case "RTC_STATE_CANPLAY": + a.StartupTime = (a.StartupTime || 0) + h, u.InitTime = (u.InitTime || 0) + h, c.InitTime = (c.InitTime || 0) + h; + break; + case "RTC_STATE_PAUSE": + u.PauseTime = (u.PauseTime || 0) + h, c.PauseTime = (c.PauseTime || 0) + h, a.LastPause = (a.LastPause || 0) + h, c.LastPause = (c.LastPause || 0) + h, l.LastPause = (l.LastPause || 0) + h, d.LastPause = (d.LastPause || 0) + h; + break; + case "RTC_STATE_STALL": + o.StallTime = (o.StallTime || 0) + h, u.StallTime = (u.StallTime || 0) + h, c.StallTime = (c.StallTime || 0) + h, a.LastStall = (a.LastStall || 0) + h, l.LastStall = (l.LastStall || 0) + h, c.LastStall = (c.LastStall || 0) + h; + break; + case "RTC_STATE_MEDIAENGINESTALL": + o.MediaEngineStallTime = (o.MediaEngineStallTime || 0) + h, u.MediaEngineStallTime = (u.MediaEngineStallTime || 0) + h, c.MediaEngineStallTime = (c.MediaEngineStallTime || 0) + h, a.LastMediaEngineStall = (a.LastMediaEngineStall || 0) + h, l.LastMediaEngineStall = (l.LastMediaEngineStall || 0) + h, c.LastMediaEngineStall = (c.LastMediaEngineStall || 0) + h; + break; + case "RTC_STATE_NWERROR": + c.NwErrTime = (c.NwErrTime || 0) + h, u.NwErrTime = (u.NwErrTime || 0) + h; + break; + case "RTC_STATE_PLAYERROR": + u.PlayErrTime = (u.PlayErrTime || 0) + h, c.PlayErrTime = (c.PlayErrTime || 0) + h; + break; + case "RTC_STATE_PLAY": { + a.RateChangePlayTime = (a.RateChangePlayTime || 0) + h, s.PlayTime = (s.PlayTime || 0) + h, s.PlayTimeLastSW = (s.PlayTimeLastSW || 0) + h * (t.oldRate / 100), r.LastResume = (r.LastResume || 0) + h, n.LastResume = (n.LastResume || 0) + h, l.LastResume = (l.LastResume || 0) + h, d.LastResume = (d.LastResume || 0) + h, o.VarPlayTimeWC = (o.VarPlayTimeWC || 0) + h, o.VarPlayTime = (o.VarPlayTime || 0) + h * (t.oldRate / 100), u.PlayTimeWC = (u.PlayTimeWC || 0) + h, u.PlayTime = (u.PlayTime || 0) + h * (t.oldRate / 100), c.PlayTimeWC = (c.PlayTimeWC || 0) + h, c.PlayTime = (c.PlayTime || 0) + h * (t.oldRate / 100), n.PlayTime = c.PlayTime, r.PlayTime = c.PlayTime; + const i = t.curLevelUrl; + let e = t.intervalVariantList[i]; + e.playTime = (e.playTime || 0) + h, e = t.sessionVariantList[i], e.playTime = (e.playTime || 0) + h; + break + } + } + }) + } + } + const Vf = { + name: "rtc-service" + }; + class Kf { + constructor(e, t, i, r) { + this.hls = e, this.config = t, this.accessLog = i, this.logger = r, this.destroy$ = new Xt, this.isSeeking = !1, this.seekStart = null, this.periodicInterval = t.rtcIntervalTimeout || 3e5, this.intervalFunc = null, this.rtcStore = new $f(this.logger), this.rtcQuery = new Uf(this.rtcStore, this.logger), this.rtcComponent = new Bf(this.rtcQuery, this.logger), i.setRTCQuery(this.rtcQuery), this.subscribeAndUpdateStore(), this.registerForEvents() + } + destroy() { + this.destroy$.next(), this.clearPeriodic(), this.rtcStore.reset() + } + detachMedia() { + this.clearPeriodic(); + var e; + try { + e = this.hls.realCurrentTime, this.rtcStore.updateVariantEnd(this.rtcEventItemId(!0), { + currentTime: e + }), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.VariantEnded), this.rtcStore.updatePeriodic(this.rtcEventItemId(!0), !0), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.Periodic), this.rtcStore.updateEnded(this.rtcEventItemId(!0)), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.PlayEnded) + } catch (e) { + this.logger.warn(Vf, e) + } + } + handleError(e) { + var t = e instanceof p ? e : new V(!0, e.message, $.InternalError); + t instanceof uc && !t.fatal ? (this.rtcStore.updateLevelLoadError(this.rtcEventItemId(), { + url: t.url, + mediaDur: this.hls.bufferedDuration, + isSeeking: this.isSeeking + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.SwitchComplete)) : t.type === o ? (this.rtcStore.updateNwError(this.rtcEventItemId(), { + fatal: t.fatal, + details: t.details, + code: null === (e = t.response) || void 0 === e ? void 0 : e.code + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.NwError)) : (this.rtcStore.updateMediaError(this.rtcEventItemId(), { + fatal: t.fatal, + details: t.details, + code: null === (t = t.response) || void 0 === t ? void 0 : t.code + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.PlayError)) + } + handleMediaElementError(e) { + this.rtcStore.updateMediaElementError(this.rtcEventItemId(), e), this.sendAndFinalize(this.rtcEventItemId(), Nf.PlayError) + } + handleFragLoaded(e, t) { + var i, r, n; + this.checkMediaOptionType(e.mediaOptionType) && (e.itemId !== this.rtcEventItemId() && this.logger.warn(Vf, `Frag id does not match current item id. Frag Id=${e.itemId}, playing id=${this.rtcEventItemId(!0)}, loading id=${null===(n=this.hls.loadingItem)||void 0===n?void 0:n.itemId}`), i = t.tload - t.trequest, r = t.tload - t.tfirst, n = this.serverInfoInstance || {}, this.rtcStore.updateFragLoaded(e.itemId, { + fragType: e.mediaOptionType, + bytes: t.loaded, + duration: e.duration, + adt: i, + processTime: r, + contentType: t.contentType, + cdnServer: t.cdnServer, + serverInfo: n + }), this.accessLog.updateFragLoaded(e.itemId, this.isSeeking, { + fragType: e.mediaOptionType, + bytes: t.loaded, + duration: e.duration, + adt: i, + processTime: r, + startPTS: e.start, + endPTS: e.start + e.duration + })) + } + handleFragBuffered(e) { + var t; + this.checkMediaOptionType(e.fragmentType) && (t = e.endDataAppend - e.startDataAppend, this.rtcStore.updateFragBuffered(this.rtcEventItemId(), { + fragType: e.fragmentType, + bytes: e.dataBytesAppend, + parseTime: t + })) + } + handleLevelLoaded(e, t) { + var i; + e ? (e.itemId !== this.rtcEventItemId() && this.logger.warn(Vf, `media option id does not match current item id. media Id=${e.itemId}, current id=${this.rtcEventItemId}`), e.mediaOptionType === gu.Variant && (i = t.tload - t.trequest, this.rtcStore.updateLevelLoaded(this.rtcEventItemId(), { + url: e.url, + targetduration: e.targetduration, + adt: i, + contentType: t.contentType, + playType: e.type + }))) : this.logger.warn(`handleLevelLoaded called with mediaOptionDetails as ${e}`) + } + handleLevelSwitched(e) { + var t = { + url: e.url, + isSeeking: this.isSeeking, + mediaDur: this.hls.bufferedDuration, + currentTime: this.hls.realCurrentTime + }; + e.oldVariant && (this.rtcStore.updateVariantEnd(this.rtcEventItemId(), { + currentTime: this.hls.realCurrentTime + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.VariantEnded)), this.rtcStore.updateLevelSwitched(this.rtcEventItemId(), t), this.sendAndFinalize(this.rtcEventItemId(), Nf.SwitchComplete) + } + handleLevelSwitching(e) { + this.levelSwitchingUrl = e + } + handleLevelsChanged(e) { + this.rtcStore.updateLevelsChanged(this.rtcEventItemId(), { + levels: e + }) + } + handleManifestParsed(e) { + var t = e.stats.tload - e.stats.trequest; + this.rtcStore.updateManifestParsed(this.rtcEventItemId(), { + levels: e.levels, + adt: t, + contentType: e.stats.contentType, + isAudioOnly: this.hls.inGaplessMode, + isGapless: this.hls.inGaplessMode, + isFirstItem: this.hls.isFirstItem, + itemID: ((null === (e = this.hls.reportingAgent) || void 0 === e ? void 0 : e.SessionID) || Zl()) + "-" + this.rtcEventItemId() + }) + } + handleSeek(e) { + if ("SEEKING" === e) this.isSeeking = !0, this.seekStart = Date.now(); + else if ("SEEKED" === e) { + this.isSeeking = !1; + let e = 0; + this.seekStart && (e = Date.now() - this.seekStart), this.seekStart = null, this.rtcStore.updateSeeked(this.rtcEventItemId(!0), { + latency: e + }) + } + } + handleDesiredRateChanged(e, t) { + 0 === t || 1 < Math.abs(e) && 1 < Math.abs(t) ? (this.rtcStore.updateRateChanged(this.rtcEventItemId(!0), { + rate: t, + latency: 0, + mediaDur: this.hls.bufferedDuration, + currentTime: this.hls.realCurrentTime, + url: this.levelSwitchingUrl + }), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.PlayRateChanged)) : 1 !== e && 1 === t && (this.playStart = Date.now()), this.oldRate = e, this.newRate = t + } + handleVariantBufferAppended(e, t) { + let i = 0; + e && (i = Date.now() - e), this.rtcStore.updateBufferAppended(this.rtcEventItemId(), { + latency: i, + size: t + }) + } + handleStalled(e, t) { + var i = { + type: e.type, + stallDurationMs: e.stallDurationMs, + bufferLen: t, + mediaDur: this.hls.bufferedDuration + }, + t = this.rtcQuery.getEntity(this.rtcEventItemId(!0)).sessionControlRecord.state; + e.type === Cp.LowBuffer || e.type === Cp.Seek && e.isLowBufferStall ? "RTC_STATE_PLAY" === t && (this.rtcStore.updateBufferStalled(this.rtcEventItemId(!0), i), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.PlayStalled)) : "RTC_STATE_PLAY" === t && (this.rtcStore.updateMediaEngineStalled(this.rtcEventItemId(!0), i), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.MediaEngineStalled)) + } + handlePlaybackInfo(e, t) { + this.rtcStore.updatePlaybackInfo(this.rtcEventItemId(!0), { + droppedVideoFrames: e, + decodedFrameCount: t + }), this.accessLog.updatePlaybackInfo(this.rtcEventItemId(!0), { + droppedVideoFrames: e, + decodedFrameCount: t + }) + } + checkMediaOptionType(e) { + return e === gu.Variant || e === gu.AltAudio || (this.logger.error(Vf, 'Should not have media option type = "%s" in RTC', Nu[e]), !1) + } + rtcEventItemId(e = !1) { + return (this.hls.isPreloading ? e ? this.hls.playingItem : this.hls.loadingItem : this.hls.currentItem).itemId + } + subscribeAndUpdateStore() { + this.hls.publicQueries$.pipe(La(([, e]) => this.mediaElementQueryListener(e)), Va(this.destroy$)).subscribe(), this.hls.itemQueue.activeItemById$.pipe(Za(t => { + if (t) { + let e = !1; + if (this.hls.userInfo ? this.hls.userInfo.internalBuild ? e = !0 : this.hls.userInfo.diagnosticsAndUsage && (e = this.config.enableRtcReporting) : e = this.config.enableRtcReporting, e) { + const i = this.hls.reportingAgent; + i ? this.rtcComponent.setReportingAgent(i) : this.logger.warn(Vf, "[RTCA] - Reporting is enabled but reportingAgent is null") + } else this.rtcComponent.setReportingAgent(null); + this.serverInfoInstance = null; + t = t.itemId; + this.rtcStore.createEntity(t), !this.hls.isFirstItem && this.hls.inGaplessMode || this.setPeriodic(t) + } + }), Va(this.destroy$)).subscribe() + } + itemTransitioned(e, t) { + this.rtcStore.updateVariantEnd(e, { + currentTime: this.hls.realCurrentTime + }), this.sendAndFinalize(e, Nf.VariantEnded), this.rtcStore.updatePeriodic(e, !0), this.sendAndFinalize(e, Nf.Periodic), this.rtcStore.updateEnded(e), this.sendAndFinalize(e, Nf.PlayEnded), this.setPeriodic(t) + } + mediaElementQueryListener(e) { + return e.gotPlaying$.pipe(Za(e => { + if (e) { + const e = this.oldRate, + t = this.newRate || 1; + 1 < Math.abs(e) && 1 < Math.abs(t) || (this.rtcStore.updateCanPlay(this.rtcEventItemId(!0), { + mediaDur: this.hls.bufferedDuration + }), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.PlayLikelyToKeepUp), this.rtcStore.updateRateChanged(this.rtcEventItemId(!0), { + rate: t, + latency: ne(this.playStart) ? Date.now() - this.playStart : 0, + mediaDur: this.hls.bufferedDuration, + currentTime: this.hls.realCurrentTime, + url: this.levelSwitchingUrl + }), this.sendAndFinalize(this.rtcEventItemId(!0), Nf.PlayRateChanged)) + } + })) + } + registerForEvents() { + const e = Oc(this.hls, this); + an(e.event(P.KEY_REQUEST_STARTED, this.keyRequestStarted, this), e.event(P.KEY_LOADED, this.keyLoaded, this)).pipe(Va(this.destroy$)).subscribe() + } + keyRequestStarted(e) { + e.timestamp = Date.now(), this.rtcStore.updateLicenseChallengeRequested(this.rtcEventItemId(), e) + } + keyLoaded(e) { + e.timestamp = Date.now(), e.currentTime = this.hls.realCurrentTime, this.rtcStore.updateSegmentKeyLoaded(this.rtcEventItemId(), e) + } + licenseChallengeReceived(e) { + this.rtcStore.updateLicenseChallengeReceived(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri + }) + } + licenseChallengeSubmitted(e) { + this.rtcStore.updateLicenseChallengeSubmitted(this.rtcEventItemId(), { + timestamp: Date.now(), + keyFormat: e.keyFormat, + keyuri: e.keyuri + }) + } + licenseChallengeCreated(e) { + this.rtcStore.updateLicenseChallengeCreated(this.rtcEventItemId(), { + timestamp: Date.now(), + cdmVersion: e.cdmVersion, + keyuri: e.keyuri + }), this.rtcStore.updateLicenseResponseRequested(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri + }) + } + licenseResponseSubmitted(e) { + this.rtcStore.updateLicenseResponseReceived(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri + }), this.rtcStore.updateLicenseResponseSubmitted(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri + }) + } + licenseResponseProcessed(e) { + this.rtcStore.updateLicenseResponseProcessed(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri, + currentTime: this.hls.realCurrentTime + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.KeySessionComplete) + } + licenseChallengeError(e) { + this.rtcStore.updateLicenseChallengeError(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.KeySessionComplete) + } + licenseResponseError(e) { + this.rtcStore.updateLicenseResponseError(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.KeySessionComplete) + } + keyAborted(e) { + var t; + null != (null === (t = this.rtcQuery.getEntity(this.rtcEventItemId())) || void 0 === t ? void 0 : t.sessionControlRecord.activeKeySessions[e.keyuri]) ? (this.rtcStore.updateKeyAborted(this.rtcEventItemId(), { + timestamp: Date.now(), + keyuri: e.keyuri + }), this.sendAndFinalize(this.rtcEventItemId(), Nf.KeySessionComplete)) : this.logger.warn(`keyAbort called without active key session ${le(e.keyuri)}`) + } + setPeriodic(e) { + this.clearPeriodic(), this.intervalFunc = setInterval(this.handlePeriodic.bind(this, e), this.periodicInterval) + } + handlePeriodic(e) { + this.rtcStore.updatePeriodic(e, !1), this.sendAndFinalize(e, Nf.Periodic) + } + clearPeriodic() { + this.intervalFunc && clearInterval(this.intervalFunc), this.intervalFunc = null + } + sendAndFinalize(e, t) { + switch (this.accessLog.addPlayTime(e), t) { + case Nf.PlayEnded: + this.rtcComponent.sendPlayEnded(e); + break; + case Nf.Periodic: + this.rtcComponent.sendPeriodic(e); + break; + case Nf.PlayStalled: + this.accessLog.updateStallCount(e), this.rtcComponent.sendPlayStalled(e); + break; + case Nf.KeySessionComplete: + this.rtcComponent.sendKeySessionComplete(e); + break; + case Nf.PlayLikelyToKeepUp: + this.accessLog.updateCanPlay(e), this.rtcComponent.sendPlayLikelyToKeepUp(e); + break; + case Nf.PlayRateChanged: + this.rtcComponent.sendPlayRateChange(e); + break; + case Nf.PlayError: + this.accessLog.addToErrorLog(e, "mediaError"), this.rtcComponent.sendPlayError(e); + break; + case Nf.MediaEngineStalled: + this.accessLog.updateMediaEngineStallCount(e), this.rtcComponent.sendMediaEngineStalled(e); + break; + case Nf.SwitchComplete: + this.accessLog.addToAccessLog(e), this.rtcComponent.sendSwitchComplete(e); + break; + case Nf.VariantEnded: + this.rtcComponent.sendVariantEnded(e); + break; + case Nf.NwError: + this.accessLog.addToErrorLog(e, "networkError"), this.rtcComponent.sendNwError(e); + break; + default: + return void this.logger.error(Vf, `Unknown rtc event eventGroupId:${e}`) + } + this.rtcStore.finalize(e, t) + } + } + const qf = a => (e, t) => { + let i = 0, + r = 0; + for (var { + timestamp: n, + value: s + } of e) { + const e = Math.pow(Math.max(0, n - t) / 1e3, a); + i += e * s, r += e + } + return i / r + }, + Hf = { + "uniform-time-weighted": qf(0), + "linear-time-weighted": qf(1), + "quadratic-time-weighted": qf(2) + }; + class jf { + constructor(e, t = "quadratic-time-weighted", i = { + avgLatencyMs: NaN, + avgBandwidth: NaN + }) { + this.windowSize = e, this.aggregationMethod = t, this.latencyEntries = [], this.bandwidthEntries = [], this.minEntries = 1, this.cleanUpExpiredEntries = this.cleanUpExpiredEntries.bind(this), this.bwSubject = new yi(i) + } + get estimate$() { + return this.bwSubject.asObservable() + } + record(e) { + var { + trequest: t, + tfirst: i, + tload: r, + bitsDownloaded: e + } = e; + t !== r && (this.recordLatency(t, i), this.recordBandwidth(t, r, 1e3 * e / (r - t)), this.bwSubject.closed || (t = this.getEstimate(), this.bwSubject.next(t))) + } + getEstimate() { + if (this.latencyEntries.length < this.minEntries) return { + avgLatencyMs: NaN, + avgBandwidth: NaN + }; + const e = performance.now() - this.windowSize, + t = Hf[this.aggregationMethod], + i = this.latencyEntries.map(({ + start: e, + end: t + }) => ({ + timestamp: t, + value: t - e, + duration: 1 + })); + this.bandwidthEntries = function(r) { + function n(t, i) { + if (t.length) { + for (let e = 0; e < t.length; e++) + if (t[e].start > i.start || t[e].start === i.start && t[e].end > i.end) { + t.splice(e, 0, i); + break + } + } else t.push(i) + } + const s = [...r].sort((e, t) => e.start !== t.start ? e.start - t.start : e.end - t.end), + t = []; + for (; s.length;) { + const r = s[0]; + let e; + if (s.shift(), t.length && (e = t[t.length - 1]), 0 === t.length || e.end <= r.start) t.push(r); + else if (r.start === e.start) r.end === e.end ? e.bitsPerSec += r.bitsPerSec : r.end < e.end || (e.bitsPerSec += r.bitsPerSec, r.start = e.end, n(s, r)); + else { + var a = e.end, + o = e.bitsPerSec; + e.end = r.start; + var i = { + start: r.start, + end: Math.min(a, r.end), + bitsPerSec: r.bitsPerSec + o + }; + if (t.push(i), a !== r.end) { + let e = 0, + t = 0, + i = 0; + i = a < r.end ? (e = a, t = r.end, r.bitsPerSec) : (e = r.end, t = a, o), n(s, { + start: e, + end: t, + bitsPerSec: i + }) + } + } + } + return t + }(this.bandwidthEntries); + var r = this.bandwidthEntries.map(({ + end: e, + bitsPerSec: t + }) => ({ + timestamp: e, + duration: 1, + value: t + })); + return { + avgLatencyMs: t(i, e), + avgBandwidth: t(r, e) + } + } + getLatest() { + if (0 === this.latencyEntries.length) return { + avgLatencyMs: NaN, + avgBandwidth: NaN + }; + var e = this.latencyEntries[this.latencyEntries.length - 1], + t = this.bandwidthEntries[this.bandwidthEntries.length - 1]; + return { + avgLatencyMs: e.end - e.start, + avgBandwidth: t.bitsPerSec + } + } + recordLatency(e, t) { + this.latencyEntries.push({ + start: e, + end: t + }), this.updateCleanupTimeout(t) + } + recordBandwidth(e, t, i) { + this.bandwidthEntries.push({ + start: e, + end: t, + bitsPerSec: i + }), this.updateCleanupTimeout(t) + } + setCleanupTimeout(e) { + this.cleanupTimeout = setTimeout(this.cleanUpExpiredEntries, Math.max(e - performance.now(), 0)), this.cleanupTimestamp = e + } + clearCleanupTimeout() { + void 0 !== this.cleanupTimeout && (clearTimeout(this.cleanupTimeout), this.cleanupTimeout = void 0), this.cleanupTimestamp = void 0 + } + updateCleanupTimeout(e) { + e += this.windowSize; + (!this.cleanupTimestamp || e < this.cleanupTimestamp) && (this.clearCleanupTimeout(), this.setCleanupTimeout(e)) + } + cleanUpExpiredEntries() { + this.clearCleanupTimeout(); + const t = performance.now() - this.windowSize; + if (this.latencyEntries = this.latencyEntries.filter(e => e.end >= t), this.bandwidthEntries = this.bandwidthEntries.filter(e => e.end >= t), this.bwSubject.closed || this.bwSubject.next(this.getEstimate()), 0 < this.latencyEntries.length || 0 < this.bandwidthEntries.length) { + const t = Math.min(...this.latencyEntries.map(e => e.end), ...this.bandwidthEntries.map(e => e.end)); + this.updateCleanupTimeout(t) + } + } + destroy() { + this.clearCleanupTimeout() + } + } + const Qf = { + setCombinedEstimate: function(t, i, r) { + const n = Qe(); + if (void 0 !== t.storage.set) { + var s = t.bandwidthHistoryStorageKey, + a = { + avgLatencyMs: i.avgLatencyMs, + avgBandwidth: i.avgBandwidth + }, + a = Object.assign({}, a, { + expires: Date.now() + t.bandwidthHistoryTTL + }); + try { + t.storage.set(s, JSON.stringify(a)) + } catch (t) { + n.warn(`Error stringifying! Not persisting bandwidth estimates: ${t.message}`) + } + i = { + maxDuration: i.maxDurationSec, + avgFragParseTimeMs: i.avgParseTimeMs, + avgFragBufferCreationDelayMs: i.avgBufferCreateMs, + avgPlaylistLoadTimeMs: i.avgPlaylistLoadTimeMs, + avgPlaylistParseTimeMs: i.avgPlaylistParseTimeMs, + avgInitFragAppendMs: i.avgInitFragAppendMs, + avgDataFragAppendMs: i.avgDataFragAppendMs + }; + let e = t.storageKeyPrefix; + r && (e += r); + try { + t.storage.set(e, JSON.stringify(i)) + } catch (t) { + n.warn(`Error stringifying! Not persisting bandwidth estimates: ${t.message}`) + } + } else n.warn("storage.set is not supported! Not persisting bandwidth estimates") + }, + getCombinedEstimate: function(t, e) { + const i = Qe(); + let r = {}; + if (void 0 === t.storage.get) return i.warn("storage.get is not supported! unable to retreive bandwidth estimates"), this.convertStorageJsonToCombinedEstimate(r); + try { + let e = JSON.parse(t.storage.get(t.bandwidthHistoryStorageKey)); + e = null != e && e.expires && e.expires < Date.now() ? null : { + avgLatencyMs: null == e ? void 0 : e.avgLatencyMs, + avgBandwidth: null == e ? void 0 : e.avgBandwidth + }, r = Object.assign(Object.assign({}, r), e) + } catch (t) { + i.warn(`Unable to get persisted bandwidth history: ${t.message}`) + } + let n = t.storageKeyPrefix; + e && (n += e); + try { + const e = JSON.parse(t.storage.get(n)); + r = Object.assign(Object.assign({}, r), e) + } catch (t) { + i.warn(`Unable to get persisted bandwidth history: ${t.message}`) + } + return this.convertStorageJsonToCombinedEstimate(r) + }, + convertStorageJsonToCombinedEstimate: function(e) { + return { + avgLatencyMs: (null == e ? void 0 : e.avgLatencyMs) || NaN, + avgBandwidth: (null == e ? void 0 : e.avgBandwidth) || NaN, + maxDurationSec: (null == e ? void 0 : e.maxDuration) || NaN, + avgParseTimeMs: (null == e ? void 0 : e.avgFragParseTimeMs) || NaN, + avgBufferCreateMs: (null == e ? void 0 : e.avgFragBufferCreationDelayMs) || NaN, + avgPlaylistLoadTimeMs: (null == e ? void 0 : e.avgPlaylistLoadTimeMs) || NaN, + avgPlaylistParseTimeMs: (null == e ? void 0 : e.avgPlaylistParseTimeMs) || NaN, + avgInitFragAppendMs: (null == e ? void 0 : e.avgInitFragAppendMs) || NaN, + avgDataFragAppendMs: (null == e ? void 0 : e.avgDataFragAppendMs) || NaN + } + }, + getBandwidthEstimate: function(e, t) { + const i = this.getCombinedEstimate(e, t), + r = { + avgLatencyMs: null == i ? void 0 : i.avgLatencyMs, + avgBandwidth: null == i ? void 0 : i.avgBandwidth + }; + return ne(r.avgLatencyMs) || (r.avgLatencyMs = NaN), ne(r.avgBandwidth) || (r.avgBandwidth = NaN), r + }, + getPlaylistEstimate: function(e, t) { + const i = this.getCombinedEstimate(e, t), + r = { + avgPlaylistLoadTimeMs: null == i ? void 0 : i.avgPlaylistLoadTimeMs, + avgPlaylistParseTimeMs: null == i ? void 0 : i.avgPlaylistParseTimeMs + }; + return ne(r.avgPlaylistLoadTimeMs) || (r.avgPlaylistLoadTimeMs = NaN), ne(r.avgPlaylistParseTimeMs) || (r.avgPlaylistParseTimeMs = NaN), r + }, + getFragEstimate: function(e, t) { + const i = this.getCombinedEstimate(e, t), + r = { + maxDurationSec: null == i ? void 0 : i.maxDurationSec, + avgParseTimeMs: null == i ? void 0 : i.avgParseTimeMs + }; + return ne(r.maxDurationSec) || (r.maxDurationSec = NaN), ne(r.avgParseTimeMs) || (r.avgParseTimeMs = NaN), r + }, + getBufferEstimate: function(e, t) { + const i = this.getCombinedEstimate(e, t), + r = { + avgBufferCreateMs: null == i ? void 0 : i.avgBufferCreateMs, + avgInitFragAppendMs: null == i ? void 0 : i.avgInitFragAppendMs, + avgDataFragAppendMs: null == i ? void 0 : i.avgDataFragAppendMs + }; + return ne(r.avgBufferCreateMs) || (r.avgBufferCreateMs = NaN), ne(r.avgInitFragAppendMs) || (r.avgInitFragAppendMs = NaN), ne(r.avgDataFragAppendMs) || (r.avgDataFragAppendMs = NaN), r + } + }; + var Wf = Qf; + class Gf { + constructor(e = 0) { + this._minSamples = e, this._sum = 0, this._max = Number.NEGATIVE_INFINITY, this._numSamples = 0 + } + get avg() { + return this._numSamples < this._minSamples ? NaN : this._sum / this._numSamples + } + get max() { + return 0 < this.count ? this._max : NaN + } + get count() { + return this._numSamples + } + reset() { + this._sum = 0, this._numSamples = 0, this._max = Number.NEGATIVE_INFINITY + } + add(e) { + this._sum += e, this._max = Math.max(this._max, e), ++this._numSamples + } + } + class zf extends kl { + constructor(e, t) { + super(e), this.id = t + } + getBandwidthEstimate(e, t) { + var i; + const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.bandwidthEstimate); + if (ne(r.avgBandwidth) && ne(r.avgLatencyMs)) return r; + if (e) { + const i = Qf.getBandwidthEstimate(e, t); + ne(r.avgBandwidth) || (r.avgBandwidth = i.avgBandwidth), ne(r.avgLatencyMs) || (r.avgLatencyMs = i.avgLatencyMs) + } + return r + } + getPlaylistEstimate(e, t) { + var i; + const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.playlistEstimate), + n = e => ne(e.avgPlaylistLoadTimeMs) && ne(e.avgPlaylistParseTimeMs); + if (n(r)) return r; + if (e) { + const i = Qf.getPlaylistEstimate(e, t); + if (ne(r.avgPlaylistLoadTimeMs) || (r.avgPlaylistLoadTimeMs = i.avgPlaylistLoadTimeMs), ne(r.avgPlaylistParseTimeMs) || (r.avgPlaylistParseTimeMs = i.avgPlaylistParseTimeMs), n(r)) return r; + ne(r.avgPlaylistLoadTimeMs) || (r.avgPlaylistLoadTimeMs = e.statDefaults.playlistLoadTimeMs), ne(r.avgPlaylistParseTimeMs) || (r.avgPlaylistParseTimeMs = e.statDefaults.playlistParseTimeMs) + } + return r + } + getBufferEstimate(e, t) { + var i; + const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.bufferEstimate), + n = e => ne(e.avgBufferCreateMs) && ne(e.avgDataFragAppendMs) && ne(e.avgInitFragAppendMs); + if (n(r)) return r; + if (e) { + const i = Qf.getBufferEstimate(e, t); + if (ne(r.avgBufferCreateMs) || (r.avgBufferCreateMs = i.avgBufferCreateMs), ne(r.avgDataFragAppendMs) || (r.avgDataFragAppendMs = i.avgDataFragAppendMs), ne(r.avgInitFragAppendMs) || (r.avgInitFragAppendMs = i.avgInitFragAppendMs), n(r)) return r; + ne(r.avgBufferCreateMs) || (r.avgBufferCreateMs = e.statDefaults.fragBufferCreationDelayMs), ne(r.avgDataFragAppendMs) || (r.avgDataFragAppendMs = e.statDefaults.dataFragAppendMs), ne(r.avgInitFragAppendMs) || (r.avgInitFragAppendMs = e.statDefaults.initFragAppendMs) + } + return r + } + getFragEstimate(e, t) { + var i; + const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.fragEstimate), + n = e => ne(e.maxDurationSec) && ne(e.avgParseTimeMs); + if (n(r)) return r; + if (e) { + const i = Qf.getFragEstimate(e, t); + if (ne(r.maxDurationSec) || (r.maxDurationSec = i.maxDurationSec), ne(r.avgParseTimeMs) || (r.avgParseTimeMs = i.avgParseTimeMs), n(r)) return r; + ne(r.maxDurationSec) || (r.maxDurationSec = e.defaultTargetDuration), ne(r.avgParseTimeMs) || (r.avgParseTimeMs = e.statDefaults.fragParseTimeMs) + } + return r + } + getCombinedEstimate() { + return Object.assign(Object.assign(Object.assign(Object.assign({}, this.getFragEstimate()), this.getPlaylistEstimate()), this.getBufferEstimate()), this.getBandwidthEstimate()) + } + get statsEntity() { + return this.getEntity(this.id) + } + get bandwidthSample() { + var e; + return null === (e = this.statsEntity) || void 0 === e ? void 0 : e.bandwidthSample + } + get bandwidthStatus() { + var e; + return null === (e = this.statsEntity) || void 0 === e ? void 0 : e.bandwidthStatus + } + get fragSample() { + var e; + return null === (e = this.statsEntity) || void 0 === e ? void 0 : e.fragSample + } + get bandwidthEstimate$() { + return this.selectEntity(this.id, "bandwidthEstimate") + } + get fragEstimate$() { + return this.selectEntity(this.id, "fragEstimate") + } + get playlistEstimate$() { + return this.selectEntity(this.id, "playlistEstimate") + } + get bufferEstimate$() { + return this.selectEntity(this.id, "bufferEstimate") + } + get bandwidthSample$() { + return this.selectEntity(this.id, ({ + bandwidthSample: e + }) => e).pipe(Kp()) + } + get fragSample$() { + return this.selectEntity(this.id, ({ + fragSample: e + }) => e).pipe(Kp()) + } + get playlistSample$() { + return this.selectEntity(this.id, ({ + playlistSample: e + }) => e).pipe(Kp()) + } + get bufferMetric$() { + return this.selectEntity(this.id, ({ + bufferMetric: e + }) => e).pipe(Kp()) + } + } + class Xf { + constructor(e) { + this.statsStore = e + } + getQuery() { + return new kl(this.statsStore) + } + getQueryForItem(e) { + return new zf(this.statsStore, e) + } + remove(e) { + this.statsStore.remove(e) + } + removeAll() { + this.statsStore.remove() + } + setBandwidthSample(e) { + this.statsStore.bandwidthSample = e + } + setFragSample(e) { + this.statsStore.fragSample = e + } + setPlaylistSample(e) { + this.statsStore.playlistSample = e + } + setBufferMetric(e) { + this.statsStore.bufferMetric = e + } + setBandwidthEstimate(e) { + this.statsStore.bandwidthEstimate = e + } + setFragEstimate(e) { + this.statsStore.fragEstimate = e + } + setPlaylistEstimate(e) { + this.statsStore.playlistEstimate = e + } + setBufferEstimate(e) { + this.statsStore.bufferEstimate = e + } + } + const Yf = new class extends fl { + constructor() { + super({}, { + name: "stats-store", + producerFn: su + }) + } + set statsEntity(e) { + Do("statsStore.set.stats"), al(() => { + this.add(e), this.setActive(e.id) + }) + } + set playlistSample(t) { + Do(`stats.set.playlistSample: ${t}`), this.updateActive(e => { + e.playlistSample = t + }) + } + set bandwidthSample(t) { + Do(`stats.set.bandwidthSample: ${t}`), this.updateActive(e => { + e.bandwidthSample = t, e.bandwidthStatus.bandwidthSampleCount += 1, e.bandwidthStatus.instantBw = 8e3 * t.loaded / (t.tload - t.trequest) + }) + } + set fragSample(t) { + Do(`stats.set.fragSample: ${t}`), this.updateActive(e => { + e.fragSample = t + }) + } + set bufferMetric(t) { + Do(`stats.set.bufferMetric: ${t}`), this.updateActive(e => { + e.bufferMetric = t + }) + } + set bandwidthEstimate(t) { + Do(`stats.set.bandwidthEstimate: ${t}`), this.updateActive(e => { + e.bandwidthEstimate = t + }) + } + set fragEstimate(t) { + Do(`stats.set.fragEstimate: ${t}`), this.updateActive(e => { + e.fragEstimate = t + }) + } + set playlistEstimate(t) { + Do(`stats.set.playlistEstimate: ${t}`), this.updateActive(e => { + e.playlistEstimate = t + }) + } + set bufferEstimate(t) { + Do(`stats.set.bufferEstimate: ${t}`), this.updateActive(e => { + e.bufferEstimate = t + }) + } + }; + let Jf = null; + const Zf = e => new zf(Yf, e); + + function em(e, t) { + if (e === t) return !0; + if (!e || !t) return !1; + let i = Object.keys(e).length === Object.keys(t).length; + for (const r of Object.keys(e)) i = i && (isNaN(e[r]) && isNaN(t[r]) || e[r] === t[r]); + return i + } + + function tm(f, m, g) { + return new $t(e => { + (e => { + const t = Zf(e); + t.hasEntity(e) ? $i(t) : (i = Yf, e = e, Do("stats.loading"), i.setLoading(!0), i.statsEntity = { + id: e, + bandwidthEstimate: { + avgLatencyMs: NaN, + avgBandwidth: NaN + }, + bandwidthStatus: { + bandwidthSampleCount: 0, + instantBw: NaN + }, + fragEstimate: { + maxDurationSec: NaN, + avgParseTimeMs: NaN + }, + playlistEstimate: { + avgPlaylistLoadTimeMs: NaN, + avgPlaylistParseTimeMs: NaN + }, + bufferEstimate: { + avgBufferCreateMs: NaN, + avgInitFragAppendMs: NaN, + avgDataFragAppendMs: NaN + } + }, i.setLoading(!1), Do("stats.loaded")); + var i + })(g.itemId); + const t = Zf(g.itemId), + { + fragSample$: i, + playlistSample$: r, + bandwidthSample$: n, + bufferMetric$: s + } = t; + return an(r.pipe(ji(tr), (h = f, p = m, e => e.pipe(tc("statsPlaylistProcessingEpic.in"), sa((e, t) => (e.playlistLoadTimeMs.add(t.playlistLoadTimeMs), e.playlistParseTimeMs.add(t.playlistParseTimeMs), e), { + playlistLoadTimeMs: new Gf(h.minPlaylistCount), + playlistParseTimeMs: new Gf(h.minPlaylistCount) + }), hr(e => ({ + avgPlaylistLoadTimeMs: e.playlistLoadTimeMs.avg, + avgPlaylistParseTimeMs: e.playlistParseTimeMs.avg + })), Is(em), Za(e => { + p.setPlaylistEstimate(e) + })))), n.pipe(ji(tr), (u = f, c = m, n => new $t(e => { + let t = new jf(u.bandwidthHistoryWindowSize, u.bandwidthHistoryAggregationMethod, { + avgLatencyMs: NaN, + avgBandwidth: NaN + }); + const i = t.estimate$, + r = an(n.pipe(ln(e => e.complete), Za(e => {}), hr(e => ({ + trequest: e.trequest, + tfirst: e.tfirst, + tload: e.tload, + bitsDownloaded: 8 * e.loaded + })), tc("statsBandwidthProcessingEpic.in"), La(e => (t.record(e), Ii))), i.pipe(Is(), tc("statsBandwidthProcessingEpic.change"), Za(e => { + c && c.setBandwidthEstimate(e) + }))).subscribe(e); + return () => { + r.unsubscribe(), t.destroy(), t = void 0 + } + }))), i.pipe(ji(tr), (l = f, d = m, e => e.pipe(tc("statsFragProcessingEpic.in"), sa((e, t) => (e.durationSec.add(t.durationSec), e.fragParseMs.add(t.parseTimeMs), e), { + durationSec: new Gf, + fragParseMs: new Gf(l.minFragmentCount) + }), hr(e => ({ + maxDurationSec: e.durationSec.max, + avgParseTimeMs: e.fragParseMs.avg + })), Is(em), Za(e => d.setFragEstimate(e))))), s.pipe(ji(tr), (a = f, o = m, e => e.pipe(tc("statsBufferMetricProcessingEpic.in"), sa((e, t) => (ne(t.bufferCreationStart) && ne(t.bufferCreationEnd) && e.bufferCreateMs.add(t.bufferCreationEnd - t.bufferCreationStart), ne(t.startInitAppend) && ne(t.endInitAppend) && e.initFragAppendMs.add(t.endInitAppend - t.startInitAppend), ne(t.startDataAppend) && ne(t.endDataAppend) && e.dataFragAppendMs.add(t.endDataAppend - t.startDataAppend), e), { + bufferCreateMs: new Gf, + initFragAppendMs: new Gf, + dataFragAppendMs: new Gf(a.minFragmentCount) + }), hr(e => ({ + avgBufferCreateMs: e.bufferCreateMs.avg, + avgInitFragAppendMs: e.initFragAppendMs.avg, + avgDataFragAppendMs: e.dataFragAppendMs.avg + })), Is(em), Za(e => { + o.setBufferEstimate(e) + }))))).pipe($a(Ii)).subscribe(e), () => { + Wf.setCombinedEstimate(f, Object.assign(Object.assign(Object.assign(Object.assign({}, t.getFragEstimate()), t.getPlaylistEstimate()), t.getBufferEstimate()), t.getBandwidthEstimate()), g.serviceName), m.remove(g.itemId) + }; + var a, o, l, d, u, c, h, p + }) + } + const im = { + isWebkitMediaElement: e => "webkitDroppedFrameCount" in e, + isHtmlVideoElement: e => "getVideoPlaybackQuality" in e, + timeRangeToArray(t) { + const i = []; + for (let e = 0; e < t.length; e++) i.push([t.start(e), t.end(e)]); + return i + } + }; + class rm { + constructor(e, t) { + this.hls = e, this.sessionID = t, this.rtcQuery = null, this.accessLogData = this.createAccessLogEntry(), this.accesslog = [], this.errorlog = [] + } + destroy() { + this.rtcQuery = null, this.accesslog = [], this.errorlog = [], this.accessLogData = void 0, this.accessLogReporter = void 0 + } + setRTCQuery(e) { + this.rtcQuery = e + } + setupReporter(e) { + this.accessLogReporter = { + SessionID: this.sessionID, + ClientName: null == e ? void 0 : e.clientName, + ServiceName: null == e ? void 0 : e.serviceName + } + } + addPlayTime(e) { + var t, e = null === (t = this.rtcQuery) || void 0 === t ? void 0 : t.getEntity(e); + !e || "RTC_STATE_PLAY" === (e = e.sessionControlRecord).state && (this.accessLogData.PlayTimeWC = (this.accessLogData.PlayTimeWC || 0) + e.eventStartTime) + } + updatePlaybackInfo(e, t) { + this.accessLogData.ViFrDr = this.rtcQuery.getEntity(e).sessionControlRecord.droppedVideoFrames || 0 + } + updateStallCount(e) { + "RTC_STATE_PLAY" === this.rtcQuery.getEntity(e).sessionControlRecord.state && this.accessLogData.StallCount++ + } + updateMediaEngineStallCount(e) { + "RTC_STATE_PLAY" === this.rtcQuery.getEntity(e).sessionControlRecord.state && this.accessLogData.MediaEngineStallCount++ + } + updateCanPlay(e) { + this.accessLogData.StartupTime = this.rtcQuery.getEntity(e).sessionControlRecord.eventStartTime + } + updateFragLoaded(e, t, i) { + var r; + i.fragType === gu.Variant ? (this.accessLogData.NetBytes += i.bytes, this.accessLogData.ADT += i.adt, r = this.aggregateFragObserverdBitrate(i, ++this.accessLogData.fragmentCnt, this.accessLogData.NetBytes, this.accessLogData.ADT), this.accessLogData.OBRLast = r.obrLast, this.accessLogData.OBRMean = r.obrMean, this.aggregateFragMinMaxBitrate(this.accessLogData, r.obr), this.hls.realCurrentTime > i.startPTS && !t && this.accessLogData.overdue++, this.hasGap(i.startPTS, i.endPTS, this.accessLogData.lastStartPTS, this.accessLogData.lastEndPTS) && this.addToAccessLog(e), this.accessLogData.startPTS || (this.accessLogData.startPTS = i.startPTS), this.accessLogData.lastStartPTS = i.startPTS, this.accessLogData.lastEndPTS = i.endPTS, this.accessLogData.videoBytes += i.bytes, this.accessLogData.videoDuration += i.duration) : i.fragType === gu.AltAudio && (this.accessLogData.audioBytes += i.bytes, this.accessLogData.audioDuration += i.duration) + } + addToAccessLog(e) { + var t = this.getVariantInfo(e), + i = this.rtcQuery.getEntity(e).sessionControlRecord.curLevelUrl, + r = this.rtcQuery.getEntity(e).playEndedRecord.PlayType; + if (i && "" !== i) { + r = this.translateToAccessLogItem(e, i, t, r); + if (r) { + const n = this.accesslog.length - 20; + 0 < n && this.accesslog.splice(0, n), this.accesslog.push(r) + } + this.accessLogData = this.createAccessLogEntry(); + e = this.rtcQuery.getEntity(e).switchCompleteRecord.MediaDur; + this.accessLogData.lastMediaDur = e || this.hls.bufferedDuration + } + } + addToErrorLog(e, t) { + var i = null === (r = this.rtcQuery) || void 0 === r ? void 0 : r.getEntity(e); + if (i) { + var r = Number(("mediaError" === t ? i.playErrorRecord : i.nwErrorRecord).ErrCode), + i = i.sessionControlRecord.curLevelUrl, + r = this.translateToErrorLogItem(e, i, { + domain: t, + code: r + }); + if (r) { + const e = this.errorlog.length - 20; + 0 < e && this.errorlog.splice(0, e), this.errorlog.push(r) + } + } + } + getAccessLog(e) { + var t; + const i = this.accesslog.slice(0), + r = null === (t = this.rtcQuery) || void 0 === t ? void 0 : t.getEntity(e); + if (i && r) { + const t = r.sessionControlRecord.curLevelUrl; + if (t && "" !== t) { + const r = this.getVariantInfo(e), + n = this.translateToAccessLogItem(e, t, r, this.rtcQuery.getEntity(e).playEndedRecord.PlayType); + n && (n["c-provisional-entry"] = !0, i.push(n)) + } + } + return i + } + get errorLog() { + return this.errorlog + } + createAccessLogEntry() { + return { + fragmentCnt: 0, + overdue: 0, + startPTS: 0, + obrMax: 0, + obrMin: 0, + audioBytes: 0, + audioDuration: 0, + videoBytes: 0, + videoDuration: 0, + svrAddrChanged: 0, + svrAddr: "", + PlayTimeWC: 0, + ViFrDr: 0, + StallCount: 0, + MediaEngineStallCount: 0, + ADT: 0, + NetBytes: 0, + StartupTime: 0, + OBRMean: 0, + OBRLast: 0 + } + } + convertStringObjectToPrimitive(e) { + return e ? "object" == typeof e ? e.toString() : e : "" + } + updateSvrAddrStats(t) { + const i = bu.parseURL(t); + if (i && i.netLoc) { + const t = i.netLoc.indexOf(":"); + let e = 0 <= t ? i.netLoc.slice(0, t) : i.netLoc; + e.startsWith("//") && (e = e.slice(2)), this.accessLogData.svrAddr ? e !== this.accessLogData.svrAddr && this.accessLogData.svrAddrChanged++ : this.accessLogData.svrAddrChanged = 0, this.accessLogData.svrAddr = e + } + } + translateToAccessLogItem(e, t, i, r) { + t = this.convertStringObjectToPrimitive(t); + this.updateSvrAddrStats(t); + let n = this.rtcQuery.getEntity(e).switchCompleteRecord.MediaDur; + n = n || this.hls.bufferedDuration, n = n || 0; + const s = { + uri: t, + "s-ip": this.accessLogData.svrAddr, + "s-ip-changes": this.accessLogData.svrAddrChanged, + "sc-wwan-count": -1, + "c-transfer-duration": this.accessLogData.ADT, + bytes: this.accessLogData.NetBytes, + "c-total-media-requests": this.accessLogData.fragmentCnt, + "cs-guid": this.accessLogReporter.SessionID, + "c-start-time": this.accessLogData.startPTS, + "c-startup-time": this.accessLogData.StartupTime, + "c-duration-watched": this.accessLogData.PlayTimeWC / 1e3, + "c-frames-dropped": this.accessLogData.ViFrDr, + "c-stalls": this.accessLogData.StallCount + this.accessLogData.MediaEngineStallCount, + "c-duration-downloaded": this.accessLogData.lastMediaDur ? n - this.accessLogData.lastMediaDur : n, + "c-overdue": this.accessLogData.overdue, + "c-avg-video-bitrate": 8 * this.accessLogData.videoBytes / (this.accessLogData.videoDuration || 1), + "c-observed-max-bitrate": this.accessLogData.obrMax, + "c-observed-min-bitrate": this.accessLogData.obrMin, + "sc-indicated-bitrate": i.bandwidth || 0, + "sc-indicated-avg-bitrate": i.avgBandwidth || 0, + "c-observed-bitrate": this.accessLogData.OBRMean, + "c-switch-bitrate": this.accessLogData.OBRLast, + "c-provisional-entry": !1 + }; + return s["s-playback-type"] = r, this.accessLogData.audioBytes && (s["c-avg-audio-bitrate"] = 8 * this.accessLogData.audioBytes / (this.accessLogData.audioDuration || 1)), s + } + translateToErrorLogItem(e, t, i) { + t = this.convertStringObjectToPrimitive(t); + return this.updateSvrAddrStats(t), { + date: new Date, + "cs-guid": this.accessLogReporter.SessionID + "-" + e, + uri: t, + "s-ip": this.accessLogData.svrAddr, + status: "" + i.code, + domain: i.domain + } + } + hasGap(e, t, i, r) { + return void 0 !== e && void 0 !== i && (1 < e - r || 1 < i - t) + } + aggregateFragObserverdBitrate(e, t, i, r) { + r = 8 * i / (r / 1e3); + return { + obr: r, + obrLast: 8 * e.bytes / (e.adt / 1e3), + obrMean: r / t + } + } + aggregateFragMinMaxBitrate(e, t) { + (!e.obrMax || t > e.obrMax) && (e.obrMax = t), (!e.obrMin || t < e.obrMin) && (e.obrMin = t) + } + getVariantInfo(e) { + var t = this.rtcQuery.getEntity(e).sessionControlRecord.curLevelUrl, + e = null === (e = this.rtcQuery.getEntity(e).sessionControlRecord.manifestData) || void 0 === e ? void 0 : e.variantList; + return t && e && e[t] ? e[t] : {} + } + } + const nm = (r, e, t, i, n, s) => { + var a, { + absoluteUrl: o, + byteRangeOffset: l, + keyTagInfo: d, + iframe: u, + isInitSegment: c + } = r, + h = o, + p = d["method"], + { + start: o, + end: d + } = l, + t = Lc({ + url: h + }, t); + let f, m = o, + g = d, + y = !1, + v = ne(o) || ne(d) ? l : void 0; + if ("AES-128" === p && d && (u || c)) { + const r = d - o; + r % 16 && (g = d + (16 - r % 16)), 0 !== o && (y = !0, m = o - 16), v = { + start: m, + end: g + } + } + return n && ne(r.mediaSeqNum) && r.mediaOptionType === gu.Variant && (f = [], null === (n = t.reportHTTPResponseHeaders) || void 0 === n || n.forEach(function(e) { + Ou.includes(e) ? f.push(e) : Qe().warn({ + name: "load-media-fragment" + }, `${e} is not in approved privacy list. Actions required.`) + }), 0 === f.length && (f = void 0)), Rc({ + url: h, + byteRangeOffset: v, + checkContentLength: !0, + extendMaxTTFB: s, + collectServerInstanceInfo: f, + onProgress: i, + xhrSetup: e.xhrSetup + }, t).pipe(hr(([e, t, i]) => { + if (y) { + const t = e; + r.keyTagInfo.iv = new Uint8Array(t.slice(0, 16)), e = t.slice(16) + } + return [r, e, t, i] + }), (a = r, e => e.pipe(Vn(e => { + if (e instanceof pc) throw new hc(!1, "Timeout", 0, $.FragmentTimeoutError, !0, a, e.stats); + if (e instanceof oc) throw new hc(!1, e.message, e.code, { + code: e.code, + text: "Fragment Network Error" + }, !1, a); + throw e + })))) + }, + sm = { + clearkey: th, + fairplaystreaming: Sc, + playready: Fc, + widevine: Bc + }, + am = { + getKeySystemFormat(e) { + e = sm[e]; + return e ? e.keyFormatString : "" + }, + getKeySystemSecurityLevel(e) { + e = sm[e]; + return e ? e.securityLevels : null + } + }, + om = { + NONE: "", + "AES-128": "", + "ISO-23001-7": "", + "SAMPLE-AES": "", + "SAMPLE-AES-CTR": "" + }, + lm = { + NONE: 0, + "TYPE-0": 1, + "TYPE-1": 2, + "TYPE-2": 3 + }; + + function dm(e) { + return e in lm + } + + function um(e) { + return null == e ? 4 : lm[e] + } + const cm = ["SDR", "PQ", "HLG"], + hm = { + afr: "af", + aka: "ak", + amh: "am", + ara: "ar", + arg: "an", + asm: "as", + ava: "av", + ave: "ae", + aym: "ay", + aze: "az", + bam: "bm", + bel: "be", + ben: "bn", + bih: "bh", + bod: "bo", + bos: "bs", + bre: "br", + bul: "bg", + cat: "ca", + ces: "cs", + cha: "ch", + che: "ce", + chu: "cu", + chv: "cv", + cor: "kw", + cos: "co", + cre: "cr", + cym: "cy", + dan: "da", + deu: "de", + div: "dv", + dzo: "dz", + ell: "el", + eng: "en", + epo: "eo", + est: "et", + eus: "eu", + ewe: "ee", + fao: "fo", + fas: "fa", + fin: "fi", + fra: "fr", + fry: "fy", + ful: "ff", + gla: "gd", + gle: "ga", + glg: "gl", + glv: "gv", + grn: "gn", + guj: "gu", + hat: "ht", + heb: "he", + her: "hz", + hin: "hi", + hmo: "ho", + hrv: "hr", + hun: "hu", + hye: "hy", + ibo: "ig", + ido: "io", + iii: "ii", + iku: "iu", + ile: "ie", + ina: "ia", + ind: "id", + isl: "is", + ita: "it", + jav: "jv", + jpn: "ja", + kal: "kl", + kan: "kn", + kas: "ks", + kat: "ka", + kau: "kr", + kaz: "kk", + khm: "km", + kik: "ki", + kin: "rw", + kir: "ky", + kom: "kv", + kon: "kg", + kor: "ko", + kua: "kj", + kur: "ku", + lao: "lo", + lat: "la", + lav: "lv", + lim: "li", + lit: "lt", + ltz: "lb", + lub: "lu", + lug: "lg", + mah: "mh", + mal: "ml", + mar: "mr", + mkd: "mk", + mlg: "mg", + mlt: "mt", + mol: "mo", + mon: "mn", + mri: "mi", + msa: "ms", + mya: "my", + nav: "nv", + nbl: "nr", + nde: "nd", + ndo: "ng", + nep: "ne", + nld: "nl", + nno: "nn", + nob: "nb", + nya: "ny", + oci: "oc", + oji: "oj", + ori: "or", + orm: "om", + oss: "os", + pan: "pa", + pli: "pi", + pol: "pl", + por: "pt", + pus: "ps", + que: "qu", + roh: "rm", + ron: "ro", + run: "rn", + rus: "ru", + san: "sa", + sin: "si", + slk: "sk", + slv: "sl", + sme: "se", + snd: "sd", + som: "so", + spa: "es", + sqi: "sq", + srd: "sc", + srp: "sr", + sun: "su", + swa: "sw", + swe: "sv", + tah: "ty", + tam: "ta", + tat: "tt", + tel: "te", + tgk: "tg", + tgl: "tl", + tha: "th", + tir: "ti", + ton: "to", + tuk: "tk", + tur: "tr", + uig: "ug", + ukr: "uk", + urd: "ur", + uzb: "uz", + ven: "ve", + vie: "vi", + wln: "wa", + yid: "yi", + zha: "za", + zho: "zh" + }, + pm = { + isLanguageCode: e => e in hm, + shortenLanguageCode(e) { + let t; + var i, r; + return e && (r = 0 <= (i = e.indexOf("-")) ? e.slice(0, i) : e, pm.isLanguageCode(r) && (t = hm[r]), t = t || r, 0 < i && (t += "-" + e.slice(i + 1))), t + } + }, + fm = { + getRichestVideoCodec(e) { + if (e && e.length) { + e = e.sort((e, t) => qp(t) - qp(e)); + return e && e.length ? e[0] : void 0 + } + }, + getRichestAudioCodec(e) { + if (e && e.length) { + e = e.sort((e, t) => jp(t) - jp(e)); + return e && e.length ? e[0] : void 0 + } + }, + getRichestChannelLayoutForGroupId(t, i) { + if (t && i && i.length) { + let e; + const r = i.filter(e => e.groupId === t); + if (r && r.length) { + const t = r.sort((e, t) => be.getChannelCount(t.channels) - be.getChannelCount(e.channels)); + t && t.length && (e = t[0].channels) + } + return e + } + } + }; + + function mm(e) { + return new R(L, "steeringManifestParsingError", !1, e, $.FormatError) + } + class gm { + constructor(e) { + this._url = null, this._programDateTime = null, this._byteRange = null, this.relurl = null, this.baseurl = null, this.isInitSegment = !1, this.mediaSeqNum = NaN, this.cc = NaN, this.iframe = !1, this.bitrate = NaN, this.start = NaN, this.duration = NaN, this.lastByteRangeEndOffset = NaN, this.inheritQuery = e, this.tagList = new Array, this.iframe = !1 + } + getMediaFragment(e, t, i) { + const r = { + mediaOptionType: i, + absoluteUrl: this.url, + start: this.start, + duration: this.duration, + mediaSeqNum: this.mediaSeqNum, + discoSeqNum: this.cc, + mediaOptionId: t, + itemId: e, + isLastFragment: !1, + isInitSegment: this.isInitSegment + }; + return null !== (e = this.byteRange) && void 0 !== e && e.length && (r.byteRangeOffset = { + start: this.byteRangeStartOffset, + end: this.byteRangeEndOffset + }), this.iframe && (r.iframe = this.iframe), this.levelkey && (r.keyTagInfo = this.levelkey), this.programDateTime && (r.programDateTime = this.programDateTime), r + } + get url() { + return !this._url && this.relurl && this.baseurl && (this._url = bu.buildAbsoluteURL(this.baseurl, this.relurl, { + alwaysNormalize: !0, + inheritQuery: this.inheritQuery + })), this._url + } + set url(e) { + this._url = e + } + get programDateTime() { + return !this._programDateTime && this.rawProgramDateTime && (this._programDateTime = new Date(Date.parse(this.rawProgramDateTime))), this._programDateTime + } + get byteRange() { + if (!this._byteRange) { + const i = new Array(2); + var e, t; + this.rawByteRange && (1 === (e = this.rawByteRange.split("@", 2)).length ? (t = this["lastByteRangeEndOffset"], i[0] = t || 0) : i[0] = parseInt(e[1]), i[1] = parseInt(e[0]) + i[0]), this._byteRange = i + } + return this._byteRange + } + get byteRangeStartOffset() { + return this.byteRange[0] + } + get byteRangeEndOffset() { + return this.byteRange[1] + } + get rangeString() { + return 0 <= this.start && 0 <= this.duration ? `${this.start.toFixed(2)}-${(this.start+this.duration).toFixed(2)}` : "N/A" + } + get fragTag() { + return `sn/cc/levelId: ${this.mediaSeqNum}/${this.cc}` + } + } + const ym = { + parseMediaCharacteristics: e => e ? e.split(/\s*,\s*/) : new Array, + addMediaToSelectionArray(e, t, i) { + if (void 0 === e) return -1; + const r = e.MediaSelectionGroupOptions; + let n = r.find(e => e.MediaSelectionOptionsMediaType === t.mediaType && e.MediaSelectionOptionsName === t.name && e.MediaSelectionOptionsExtendedLanguageTag === t.lang); + return n || (n = { + MediaSelectionOptionsMediaType: t.mediaType, + MediaSelectionOptionsExtendedLanguageTag: t.lang, + MediaSelectionOptionsIsDefault: t.default, + MediaSelectionOptionsName: t.name, + MediaSelectionOptionsPersistentID: i, + MediaSelectionOptionsTaggedMediaCharacteristics: t.characteristics + }, t.mediaType === Su.SUBTITLE && (n.MediaSelectionOptionsDisplaysNonForcedSubtitles = t.forced ? vu.NO : vu.YES), i++, r.push(n)), t.persistentID = n.MediaSelectionOptionsPersistentID, i + }, + addDefaultClosedCaptionOption(e, t, i, r) { + e = { + itemId: e, + mediaOptionType: gu.Subtitle, + id: 0, + mediaOptionId: "cc1_" + Zl(), + mediaType: Su.CLOSEDCAPTION, + inStreamID: "CC1", + groupId: "cc", + name: "English-CC", + type: "CLOSED-CAPTIONS", + default: !1, + autoselect: !1, + forced: !1, + lang: "en", + characteristics: ["public.accessibility.transcribes-spoken-dialog", "public.accessibility.describes-music-and-sound"], + persistentID: r + }; + t.push(e), ym.addMediaToSelectionArray(i, e, r) + } + }, + vm = { + BANDWIDTH: NaN, + "AVERAGE-BANDWIDTH": NaN + }, + Sm = { + "TIME-OFFSET": NaN, + "FRAME-RATE": NaN, + SCORE: NaN, + "PLANNED-DURATION": NaN, + DURATION: NaN + }, + bm = /^(\d+)x(\d+)$/, + Tm = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; + class Em { + constructor(e) { + this.validTags = e + } + isKey(e) { + return e in this.validTags + } + trySetValue(e, t, i) { + return !!this.isKey(e) && (i[e] = this.parseFunc(t), !0) + } + } + class Im { + static parseTags(t) { + let i; + var r = {}; + if (!t) return r; + for (Tm.lastIndex = 0; null !== (i = Tm.exec(t));) { + const t = i[1].toUpperCase(); + let e = i[2]; + 0 === e.indexOf('"') && e.lastIndexOf('"') === e.length - 1 && (e = e.slice(1, -1)); + for (const i of Im.tagParsers) + if (i.trySetValue(t, e, r)) break + } + return r + } + } + Im.tagParsers = [new class extends Em { + parseFunc(e) { + return e + } + }({ + NAME: "", + TYPE: "", + DEFAULT: "", + AUTOSELECT: "", + FORCED: "", + LANGUAGE: "", + URI: "", + AUDIO: "", + "VIDEO-RANGE": "", + "CLOSED-CAPTIONS": "", + CODECS: "", + BYTERANGE: "", + "INSTREAM-ID": "", + "GROUP-ID": "", + CHANNELS: "", + CHARACTERISTICS: "", + KEYFORMAT: "", + KEYFORMATVERSIONS: "", + "DATA-ID": "", + VALUE: "", + METHOD: "", + "HDCP-LEVEL": "", + "ALLOWED-CPC": "", + SUBTITLES: "", + ID: "", + CLASS: "", + "START-DATE": "", + "END-DATE": "", + "END-ON-NEXT": "", + "SERVER-URI": "", + "PATHWAY-ID": "" + }), new class extends Em { + parseFunc(e) { + e = parseInt(e); + return e > Number.MAX_SAFE_INTEGER ? 1 / 0 : e + } + }(vm), new class extends Em { + constructor() { + super(...arguments), this.parseFunc = parseFloat + } + }(Sm), new class extends Em { + parseFunc(e) { + let t = (e || "0x").slice(2); + t = (1 & t.length ? "0" : "") + t; + const i = new Uint8Array(t.length / 2); + for (let e = 0; e < t.length / 2; e++) { + var r = parseInt(t.slice(2 * e, 2 * e + 2), 16); + if (!ne(r)) return; + i[e] = r + } + return i + } + }({ + IV: null + }), new class extends Em { + parseFunc(e) { + e = bm.exec(e); + let t; + return null !== e && (t = { + width: parseInt(e[1], 10), + height: parseInt(e[2], 10) + }), t + } + }({ + RESOLUTION: null + })]; + const wm = { + ExtractVariableParameter: /{\$(.*?)}/g, + LevelPlaylistFast: /#EXTINF:(\d*(?:\.\d+)?)(?:,(.*))?|(?!#)(\S.+)|#EXT-X-BYTERANGE: *(.+)|#EXT-X-PROGRAM-DATE-TIME:(.+)|#EXT-X-BITRATE:(.+)|#EXT-X-DATERANGE:(.+)|#.*/g, + LevelPlaylistSlow: /(?:(?:#(EXTM3U))|(?:#EXT-X-(PLAYLIST-TYPE):(.+))|(?:#EXT-X-(MEDIA-SEQUENCE): *(\d+))|(?:#EXT-X-(TARGETDURATION): *(\d+))|(?:#EXT-X-(KEY):(.+))|(?:#EXT-X-(START):(.+))|(?:#EXT-X-(ENDLIST))|(?:#EXT-X-(DISCONTINUITY-SEQ)UENCE:(\d+))|(?:#EXT-X-(DIS)CONTINUITY))|(?:#EXT-X-(VERSION):(\d+))|(?:#EXT-X-(MAP):(.+))|(?:#EXT-X-(I-FRAMES)-ONLY)|(?:#EXT-X-(DEFINE):(.+))|(?:(#)(.*):(.*))|(?:(#)(.*))(?:.*)\r?\n?/, + MasterPlaylist: /#EXT-X-STREAM-INF:([^\n\r]*)[\r\n]+([^\r\n]+)|#EXT-X-I-FRAME-STREAM-INF:([^\r\n]+)|#EXT-X-DEFINE:([^\n\r]*)|#EXT-X-CONTENT-STEERING:([^\n\r]*)/g, + MasterPlaylistAlternateMedia: /#EXT-X-MEDIA:(.*)/g, + SessionData: /#EXT-X-SESSION-DATA[^:]*:(.*)/g, + SessionKeys: /#EXT-X-SESSION-KEY:([^\n\r]*)/g, + VARIABLE_PLAYLIST_REGEX: /(NAME|VALUE)=\"(.*)\",(NAME|VALUE)=\"(.*)\"|(IMPORT)=\"(.*)\"/ + }; + + function Am(e, t, i) { + return cu.buildAbsoluteURL(t, e, { + alwaysNormalize: !0, + inheritQuery: i + }) + } + class Om { + static isValidPlaylist(e) { + return 0 === e.indexOf("#EXTM3U") + } + static isMediaPlaylist(e) { + return 0 < e.indexOf("#EXTINF:") || 0 < e.indexOf("#EXT-X-PLAYLIST-TYPE:") + } + static replaceVariables(e, t) { + let i, r = !1; + return e && t && (i = e.replace(wm.ExtractVariableParameter, e => { + wm.ExtractVariableParameter.lastIndex = 0; + e = wm.ExtractVariableParameter.exec(e)[1]; + if (e && t.hasOwnProperty(e)) return t[e]; + r = !0 + })), { + updatedString: i, + error: r + } + } + static parseDecryptData(e, t, i) { + const r = Im.parseTags(e), + n = (e = r.METHOD) && e in om ? r.METHOD : null; + e = null !== (e = r.KEYFORMAT) && void 0 !== e ? e : null; + if (n && Om.shouldSelectKeyTag(e, n, i)) { + const s = r.URI, + i = r.IV || null; + if (s && r.IV && !i) { + const s = new R(L, _, !0, `Invalid IV: ${r.IV}`, $.PlaylistErrorInvalidEntry); + throw s.url = t, s + } + const a = s ? cu.buildAbsoluteURL(t, s, { + alwaysNormalize: !0 + }) : t, + o = (r.KEYFORMATVERSIONS || "1").split("/").map(Number).filter(isFinite); + return new zc(n, a, i, e, o) + } + } + static shouldSelectKeyTag(e, t, i) { + return "AES-128" === t || "NONE" === t || null == i || e === am.getKeySystemFormat(i) + } + static optOutClosedCaption(t) { + let i = !1, + r = !1; + if (t) + for (let e = 0; e < t.length; ++e) { + const n = t[e]; + if (n.videoCodec && ((r = !0) !== n.iframes && n.closedcaption && "none" === n.closedcaption.toLowerCase())) { + i = !0; + break + } + } + return !r || i + } + static parseRootPlaylistAlternateMediaOptions(a, o, l, d, u, c) { + let h, p; + var f = { + MediaSelectionGroupAllowEmptySelection: 1, + MediaSelectionGroupMediaCharacteristics: ["public.audible"], + MediaSelectionGroupMediaType: Su.AUDIO, + MediaSelectionGroupOptions: [] + }, + m = { + MediaSelectionGroupAllowEmptySelection: 1, + MediaSelectionGroupMediaCharacteristics: ["public.legible"], + MediaSelectionGroupMediaType: Su.SUBTITLE, + MediaSelectionGroupOptions: [] + }, + g = { + videoAlternateOptions: [], + audioAlternateOptions: [], + subtitleAlternateOptions: [], + audioMediaSelectionGroup: f, + subtitleMediaSelectionGroup: m + }; + let y = 0; + for (wm.MasterPlaylistAlternateMedia.lastIndex = 0; null != (h = wm.MasterPlaylistAlternateMedia.exec(o));) { + const o = Om.replaceVariables(h[1], c); + if (o.error) { + p = new R(L, N, !0, $.PlaylistErrorInvalidEXTXDEFINE.text, $.PlaylistErrorInvalidEXTXDEFINE); + break + } + var v = Im.parseTags(o.updatedString); + let e, t, i, r = Su.UNKNOWN; + const S = ym.parseMediaCharacteristics(v.CHARACTERISTICS), + b = v["GROUP-ID"], + T = v.CHANNELS; + let n, s = null; + switch (v.TYPE) { + case "VIDEO": + r = Su.VIDEO, t = g.videoAlternateOptions; + break; + case "AUDIO": + r = Su.AUDIO, s = gu.AltAudio, t = g.audioAlternateOptions, i = f; + const a = d.find(e => e.audioGroupId === b); + n = a ? a.audioCodecList : []; + break; + case "SUBTITLES": + r = Su.SUBTITLE, s = gu.Subtitle, t = g.subtitleAlternateOptions, i = m; + break; + case "CLOSED-CAPTIONS": + r = Su.CLOSEDCAPTION, s = gu.Subtitle, e = v["INSTREAM-ID"], t = g.subtitleAlternateOptions, i = m + } + const E = { + itemId: a, + mediaOptionType: s, + mediaType: r, + groupId: b, + channels: T, + groupCodecList: n, + name: v.NAME, + type: v.TYPE, + default: "YES" === v.DEFAULT, + autoselect: "YES" === v.AUTOSELECT, + forced: "YES" === v.FORCED, + characteristics: S, + persistentID: y, + id: t ? t.length : 0, + mediaOptionId: `${v.NAME}_${b}_${y}`, + lang: pm.shortenLanguageCode(v.LANGUAGE) + }; + v.URI && (E.url = Am(v.URI, l, u)), E.name || (E.name = E.lang, E.mediaType === Su.CLOSEDCAPTION && (E.name += " CC")), E.mediaType === Su.CLOSEDCAPTION && e && (E.inStreamID = e), t && (E.id = t.length, t.push(E)), y = ym.addMediaToSelectionArray(i, E, y) + } + return 0 !== g.subtitleAlternateOptions.length || Om.optOutClosedCaption(d) || ym.addDefaultClosedCaptionOption(a, g.subtitleAlternateOptions, m, y), { + alternateMediaInfo: g, + playlistParsingError: p + } + } + static parseMediaOptionPlaylist(e, t, i = !0, r, n, s, a, o, l, d = 0, u = !1) { + var c; + let h = 0, + p = 0; + const f = { + itemId: s, + mediaOptionId: a, + mediaOptionType: o, + type: "", + version: 0, + url: t, + initSegments: {}, + fragments: [], + liveOrEvent: !0, + startSN: 0, + endSN: 0, + iframesOnly: u, + targetduration: 0, + totalduration: 0, + averagetargetduration: 0, + ptsKnown: !1 + }; + let m, g, y, v = new zc("NONE", t, null, null, null), + S = !1, + b = !1, + T = 0, + E = null, + I = new gm(i), + w = 0; + const A = {}; + let O, k, C, D = !0, + M = !0; + wm.LevelPlaylistFast.lastIndex = 0; + for (var x = () => new R(L, _, !0, "Invalid key system preference for the playlist", $.IncompatibleAsset); null !== (m = wm.LevelPlaylistFast.exec(e));) { + const e = m[1]; + if (e) { + I.duration = parseFloat(e); + const t = (" " + m[2]).slice(1); + I.title = t || null, I.tagList.push(t ? ["INF", e, t] : ["INF", e]) + } else if (m[3]) { + if (ne(I.duration)) { + const e = h++; + if (I.start = p + d, I.levelkey = v, b && !S) { + k = x(); + break + } + if (S = !1, b = !1, I.mediaSeqNum = e, I.cc = T, I.iframe = f.iframesOnly, I.baseurl = t, (O = Om.replaceVariables((" " + m[3]).slice(1), A)).error) { + k = new R(L, N, !0, $.PlaylistErrorInvalidEXTXDEFINE.text, $.PlaylistErrorInvalidEXTXDEFINE); + break + } + if (I.relurl = O.updatedString, I.bitrate = ne(I.byteRangeEndOffset) ? 8 * (I.byteRangeEndOffset - I.byteRangeStartOffset) / I.duration : w, null != y) { + I.rawProgramDateTime = y, I.tagList.push(["PROGRAM-DATE-TIME", I.rawProgramDateTime]); + const e = I.programDateTime.getTime(); + f.programDateTimeMap = null !== (c = f.programDateTimeMap) && void 0 !== c ? c : {}, f.programDateTimeMap[e] = I.mediaSeqNum, f.dateMediaTimePairs = null !== (c = f.dateMediaTimePairs) && void 0 !== c ? c : [], f.dateMediaTimePairs.push([e, I.start]), y = void 0 + } + if (f.fragments.push(I.getMediaFragment(s, a, o)), E = I, p += I.duration, D || !f.initSegments[T] || M) + if (f.iframesOnly && 0 < I.byteRangeStartOffset && !f.initSegments[T] && !M) { + const e = new gm(i); + if (e.url = I.url, e.rawByteRange = Math.min(I.byteRangeStartOffset, 1316) + "@0", e.baseurl = t, e.isInitSegment = !0, e.cc = T, e.levelkey = v, e.iframe = !0, b && !S) { + k = x(); + break + } + S = !1, b = !1, f.initSegments[T] = e.getMediaFragment(s, a, o) + } else C && (C.discoSeqNum = T, f.initSegments[T] = C); + D = !1, M = !1, I = new gm(i) + } + } else if (m[4]) { + if (I.rawByteRange = (" " + m[4]).slice(1), E) { + const e = E.byteRangeEndOffset; + e && (I.lastByteRangeEndOffset = e) + } + } else if (m[5]) y = (" " + m[5]).slice(1); + else if (m[6]) { + const e = parseInt(m[6]); + ne(e) && (w = 1e3 * e) + } else if (m[7]) { + const e = m[7], + t = Im.parseTags(e); + t.ID && (f.daterangeTags || (f.daterangeTags = {}), f.daterangeTags[t.ID] = t) + } else { + for (m = m[0].match(wm.LevelPlaylistSlow), g = 1; g < m.length && void 0 === m[g]; g++); + const e = Om.replaceVariables((" " + m[g + 1]).slice(1), A), + l = Om.replaceVariables((" " + m[g + 2]).slice(1), A); + if (e.error || l.error) { + k = new R(L, N, !0, $.PlaylistErrorInvalidEXTXDEFINE.text, $.PlaylistErrorInvalidEXTXDEFINE); + break + } + const d = e.updatedString, + u = l.updatedString; + switch (m[g]) { + case "#": + I.tagList.push(u ? [d, u] : [d]); + break; + case "PLAYLIST-TYPE": + f.type = d.toUpperCase(), "VOD" === f.type && (f.liveOrEvent = !1); + break; + case "MEDIA-SEQUENCE": + 0 === f.fragments.length && (h = f.startSN = parseInt(d)); + break; + case "TARGETDURATION": + f.targetduration = parseFloat(d); + break; + case "VERSION": + f.version = parseInt(d); + break; + case "EXTM3U": + break; + case "ENDLIST": + f.liveOrEvent = !1; + break; + case "DIS": + T++, I.tagList.push(["DIS"]), D = !0; + break; + case "DISCONTINUITY-SEQ": + T = parseInt(d); + break; + case "KEY": + const e = d; + if (b = !0, !S) { + try { + v = Om.parseDecryptData(e, t, r) + } catch (e) { + k = e + } + v && (S = !0) + } + break; + case "START": + const l = d, + P = Im.parseTags(l)["TIME-OFFSET"]; + ne(P) && (f.startTimeOffset = P); + break; + case "I-FRAMES": + f.iframesOnly = !0; + break; + case "MAP": + const c = Im.parseTags(d); + if (I.relurl = c.URI, I.rawByteRange = c.BYTERANGE, I.baseurl = t, I.isInitSegment = !0, I.levelkey = v, b && !S) { + k = x(); + break + } + S = !1, b = !1, C = I.getMediaFragment(s, a, o), M = !0, I = new gm(i); + break; + case "DEFINE": + const p = wm.VARIABLE_PLAYLIST_REGEX.exec(d), + m = "NAME" === p[1] ? p[2] : p[4], + g = "VALUE" === p[1] ? p[2] : p[4], + y = p[5], + N = p[6]; + if (m || g || "IMPORT" !== y || !n.hasOwnProperty(N)) { + if (!m || y || p[1] === p[3] || A.hasOwnProperty(m)) { + k = new R(L, _, !0, $.PlaylistErrorMissingImportReference.text, $.PlaylistErrorMissingImportReference); + break + } + A[m] = g + } else A[N] = n[N] + } + } + } + return I = E, I && !I.relurl && (f.fragments.pop(), p -= I.duration), !f.liveOrEvent && 0 < f.fragments.length && (f.fragments[f.fragments.length - 1].isLastFragment = !0), f.totalduration = p, f.averagetargetduration = p / f.fragments.length, f.endSN = h - 1, { + mediaOptionDetails: f, + playlistParsingError: k + } + } + static parseRootPlaylist(t, e, i, r) { + const n = [], + s = {}; + let a, o, l, d, u = null, + c = !0; + for (wm.MasterPlaylist.lastIndex = 0; null != (a = wm.MasterPlaylist.exec(e));) + if (a[4]) { + a = wm.VARIABLE_PLAYLIST_REGEX.exec(a[4]); + const t = "NAME" === a[1] ? a[2] : a[4], + e = "VALUE" === a[1] ? a[2] : a[4], + i = a[5]; + if (!t || s.hasOwnProperty(t) || i || a[1] === a[3]) { + d = new R(L, _, !0, $.PlaylistErrorInvalidEXTXDEFINE.text, $.PlaylistErrorInvalidEXTXDEFINE); + break + } + s[t] = e + } else if (a[5]) { + const t = Om.replaceVariables(a[5], s); + if (t.error) { + d = new R(L, _, !0, $.PlaylistErrorInvalidEXTXDEFINE.text, $.PlaylistErrorInvalidEXTXDEFINE); + break + } + const e = Im.parseTags(t.updatedString); + if ("string" != typeof e["SERVER-URI"]) { + d = new R(L, _, !0, $.PlaylistErrorInvalidSERVERURI.text, $.PlaylistErrorInvalidSERVERURI); + break + } + if (null != e["PATHWAY-ID"] && "string" != typeof e["PATHWAY-ID"]) { + d = new R(L, _, !0, $.PlaylistErrorInvalidPATHWAYID.text, $.PlaylistErrorInvalidPATHWAYID); + break + } + u = { + serverURI: Am(e["SERVER-URI"], i, !1), + initPathwayID: e["PATHWAY-ID"] || "." + } + } else { + l = Om.replaceVariables(a[1] || a[3], s); + const e = Im.parseTags(l.updatedString); + if (o = Om.replaceVariables(a[2] || e.URI, s), l.error || o.error) { + d = new R(L, _, !0, $.PlaylistErrorInvalidEXTXDEFINE.text, $.PlaylistErrorInvalidEXTXDEFINE); + break + } + if (void 0 !== e.SCORE && !ne(e.SCORE) || e.SCORE < 0) { + d = new R(L, _, !0, $.PlaylistErrorInvalidSCORE.text, $.PlaylistErrorInvalidSCORE), c = !1; + break + } + c && void 0 === e.SCORE && (c = !1); + const u = e.BANDWIDTH, + p = e["AVERAGE-BANDWIDTH"], + f = p || u, + m = null !== (h = e["VIDEO-RANGE"]) && void 0 !== h ? h : "SDR"; + if (null == (h = m) || !cm.includes(h)) continue; + const g = { + itemId: t, + mediaOptionId: `level_${(f||0)+n.length%1e3/1e3}`, + mediaOptionType: gu.Variant, + attrs: e, + url: Am(o.updatedString, i, r), + name: e.NAME, + audioGroupId: e.AUDIO, + subtitleGroupId: e.SUBTITLES, + iframes: !!a[3], + bandwidth: u, + avgBandwidth: p, + bitrate: f, + videoRange: m, + frameRate: e["FRAME-RATE"], + allowedCPCMap: Om.parseAllowedCPC(e["ALLOWED-CPC"]), + closedcaption: e["CLOSED-CAPTIONS"], + levelCodec: e.CODECS, + score: e.SCORE, + pathwayID: e["PATHWAY-ID"] || "." + }, + y = e["HDCP-LEVEL"]; + dm(y) && (g.hdcpLevel = y); + var h = e.RESOLUTION; + if (h && (g.width = h.width, g.height = h.height), e.CODECS) { + g.videoCodecList = new Array, g.audioCodecList = new Array; + const t = e.CODECS.split(/[ ,]+/), + i = t["length"]; + for (let e = 0; e < i; e++) { + const i = t[e]; + switch (i.slice(0, 4)) { + case "avc1": + g.videoCodec = be.avc1toavcoti(i), g.videoCodecList.push(g.videoCodec); + break; + case "avc3": + case "dvav": + case "dva1": + case "hev1": + case "hvc1": + case "dvh1": + case "dvhe": + case "vp09": + g.videoCodec = i, g.videoCodecList.push(g.videoCodec); + break; + default: + g.audioCodec = i, g.audioCodecList.push(g.audioCodec) + } + } + 1 < g.audioCodecList.length && (g.audioCodec = fm.getRichestAudioCodec(g.audioCodecList)), 1 < g.videoCodecList.length && (g.videoCodec = fm.getRichestVideoCodec(g.videoCodecList)) + } + if (null != (d = "string" != typeof(h = g.pathwayID) ? mm("invalid steering manifest PATHWAY-PRIORITY list item data type") : /^[\w\-\.]+$/.test(h) ? void 0 : mm("steering manifest contains invalid pathway ID: " + h))) break; + let cpc = g.allowedCPCMap ? JSON.stringify(g.allowedCPCMap) : "null"; + if (!cpc.includes("WIDEVINE_HARDWARE") && !g.url.includes('trickPlay') && !g.videoCodec.includes("hvc1")) + n.push(g) + } + try{ + // console.log(n, window.screen.width) + let ok = (n.map( function(item){return{height : item.height, content: item}})); + let screenHeight = (app.cfg.visual.videoRes ?? window.screen.height) ; + ok.sort(function (a, b) { + return a.height - b.height; + }); + for (var i = 0; i < ok.length; i++){ + if (ok[i].height > screenHeight){ + if (i == 0){n.splice(0,n.length);n.push(ok[i].content)} + else{n.splice(0,n.length);n.push(ok[i-1].content)} + console.log('selected' , n[0].height) + break; + + } + + } + if (n.length > 1){ + n.splice(0,n.length - 1); + } + // console.log(n) + // console.log(ok) + } catch (e){ console.log(e)} + return { + variantMediaOptions: n, + contentSteeringOption: u, + masterVariableList: s, + playlistParsingError: d, + scoreAvailable: c + } + } + static parseAllowedCPC(e) { + if ("string" != typeof e) return null; + const n = {}; + return e.split(",").forEach(e => { + const t = e.split(":"); + let i, r; + if (2 === t.length) i = t[0].trim(), r = t[1].trim(); + else { + if (!(2 < t.length)) return; + r = t[t.length - 1].trim(), t.pop(), i = t.join(":") + } + if (!(i in n)) { + let e = new Array; + "" !== r && (e = r.split("/").map(e => e.trim())), n[i] = e + } + }), n + } + static parseSessionKeys(e, t, i) { + var r; + const n = []; + for (wm.SessionData.lastIndex = 0; r = wm.SessionKeys.exec(e);) try { + const e = Om.parseDecryptData(r[1], t, i); + e && e.isEncrypted && n.push(e) + } catch (e) {} + return n + } + static parseSessionData(e, t) { + var i; + const r = [], + n = new Set; + for (wm.SessionData.lastIndex = 0; null != (i = wm.SessionData.exec(e));) { + const e = Im.parseTags(i[1]); + e.LANGUAGE = pm.shortenLanguageCode(e.LANGUAGE); + const t = e.LANGUAGE ? e["DATA-ID"] + "|" + e.LANGUAGE : void 0; + "DATA-ID" in e ? t && n.has(t) || ("com.apple.hls.other-tags" === e["DATA-ID"] && (e.VALUE = function(t) { + let i; + try { + i = JSON.parse(qc.base64DecodeToStr(t)) + } catch (e) { + i = t + } + return i + }(e.VALUE)), r.push(e), t && n.add(t)) : Qe().error(`Error processing DATA-ID ${e["DATA-ID"]} and LANGUAGE ${e.LANGUAGE}`) + } + return { + itemList: r, + baseUrl: t + } + } + } + var km, Cm, Dm, Mm, xm, Pm, Rm = Om; + const Lm = (e, t, i) => { + i = Object.assign(Object.assign({}, e), { + method: "GET", + responseType: "text", + extendMaxTTFB: i + }); + return Tu(i.url) ? Pc().load(i, t).pipe(hr(e => ({ + responseText: e.data.response.data.toString(), + responseURL: e.data.response.uri, + stats: e.stats + }))) : Cc(i, t).pipe(hr(([e, t]) => ({ + responseText: e.responseText, + responseURL: e.responseURL, + stats: t + }))) + }, + _m = (e, n, t, i, s, a, o, l, r) => { + const { + url: d, + itemId: u, + mediaOptionId: c, + mediaOptionType: h, + iframes: p = !1 + } = e, f = Lc(e, i); + return Lm({ + url: d, + xhrSetup: t.xhrSetup + }, f, r).pipe(hr(({ + responseText: e, + responseURL: t, + stats: i + }) => { + t || (s.warn("Missing response url. Reusing request url as base url"), t = d); + var r = performance.now(), + e = Om.parseMediaOptionPlaylist(e, t, !0, a, l, u, c, h, s, n, p); + Nc(e.mediaOptionDetails); + var t = performance.now(), + e = e["mediaOptionDetails"], + r = { + playlistLoadTimeMs: i.tload - i.trequest, + playlistParseTimeMs: t - r + }; + return o.setPlaylistSample(r), { + mediaOptionDetails: e, + stats: i + } + }), (m = h, g = c, y = d, e => e.pipe(Vn(e => { + if (e instanceof pc) throw new uc(!1, "Timeout", 0, $.PlaylistTimeoutError, !0, m, g, y); + if (e instanceof oc) throw new uc(!1, e.message, e.code, { + code: e.code, + text: "Playlist Network Error" + }, !1, m, g, y); + throw e + })))); + var m, g, y + }, + Nm = (f, e, m, t, g) => $i(e).pipe(La(e => { + const { + keyTagInfo: t, + isInitSegment: i, + iframe: r, + byteRangeOffset: n + } = f, s = t["method"], { + start: a, + end: o + } = n; + if ("AES-128" !== s) return $i(e); { + !t.uri || t.iv || t.format && "identity" !== t.format || (t.iv = function(t) { + const i = new Uint8Array(16); + for (let e = 12; e < 16; e++) i[e] = t >> 8 * (15 - e) & 255; + return i + }(f.mediaSeqNum)); + const n = e, + s = t.key.buffer, + l = t.iv.buffer, + d = o && (r || i) ? o - a : void 0, + u = !m.enableWebCrypto || !!d, + c = s.slice(0), + h = l.slice(0), + p = { + useJSCrypto: u, + plainTextLength: d + }; + return g.decrypt(c, h, "AES-CBC", n, p) + } + })); + + function Fm(e, t) { + var i = e.fragments, + r = t.mediaSeqNum - e.startSN; + return 0 <= r && r < e.fragments.length && $p(t, i[r]) + } + + function Bm(t, r, n, s, a = !1, o = !1) { + if (Fm(t, r)) { + var l = r.mediaSeqNum - t.startSN; + let i = t.fragments, + e = i[l]; + var { + startDtsTs: d, + startPts: u, + endPts: r + } = r; + a && (i = t.fragments = t.fragments.slice(), e = i[l] = Object.assign({}, e)), e.startDtsTs = d, e.startPts = u, e.endPts = r, !s && void 0 === e.isIframeStart || (e.isIframeStart = s), e.start = n, e.duration = b(r, u); + for (let e = l, t = !0; 0 < e && (o || t); e--) t = Um(i, e, e - 1, s, u.timescale, a); + for (let e = l, t = !0; e < i.length - 1 && (o || t); e++) t = Um(i, e, e + 1, s, u.timescale, a); + l = i[i.length - 1]; + t.totalduration = l.start + l.duration - i[0].start, t.ptsKnown = !0 + } + } + + function Um(e, t, i, r, n, s = !1) { + var a = e[t]; + let o = e[i]; + var l = null != r && null != o.isIframeStart && o.isIframeStart !== r && o.discoSeqNum === a.discoSeqNum; + let d = o.start; + !l && null != o.startPts || (d = t < i ? a.start + a.duration : Math.max(a.start - o.duration, 0)); + n = ne(n) ? 1 / n : Number.EPSILON, n = Math.abs(o.start - d) > n; + return !(!l && !n || (s && (o = e[i] = Object.assign({}, o)), n && (o.start = d), l && (o.isIframeStart = r), 0)) + } + + function $m(e) { + if (e.programDateTimeMap) { + e.dateMediaTimePairs = []; + for (var [t, i] of Object.entries(e.programDateTimeMap)) { + t = Number(t), i = e.fragments[i - e.startSN]; + i && (i = i.start, e.dateMediaTimePairs.push([t, i])) + } + e.dateMediaTimePairs.sort((e, t) => e[0] - t[0]) + } + } + class Vm { + constructor(e) { + this.option = e + } + get name() { + return this.option.name + } + get priority() { + return this.option.priority + } + get expiry() { + return this.option.expiry + } + filter(i, e) { + const r = this.option.initFn && this.option.initFn(i, e) || (e ? Object.assign({}, e) : {}); + let t = i; + return this.option.firstPassFn && i.forEach((e, t) => this.option.firstPassFn(e, t, r, i)), this.option.filterFn && (t = i.filter((e, t) => this.option.filterFn(e, t, r, i))), null != this.option.filterFn && 0 !== t.length || !this.option.minSortingFn || (t = i.sort((e, t) => this.option.minSortingFn(e, t, r, i))), this.option.finalFn && this.option.finalFn(t, r, i), t + } + } + + function Km(e, t, i) { + return (t || []).reduce((e, t) => t.filter(e, i), Array.from(e)) + } + + function qm(t, e) { + return e.filter(e => { + return Au(t, null !== (e = e.url) && void 0 !== e ? e : null) + }) + } + + function Hm() { + return [new Vm({ + name: "Remove Filter", + priority: 0, + filterFn: (t, e, i) => !i || i.removed.every(e => t.mediaOptionId !== e) + }), new Vm({ + name: "Penalty Box Filter", + priority: 1, + filterFn: (t, e, i) => { + const r = performance.now(); + return !i || i.penaltyBoxQueue.every(e => e.expiry <= r || t.mediaOptionId !== e.mediaOptionId) + } + }), new Vm({ + name: "Compatible IDs Filter", + priority: 1, + filterFn: (t, e, i) => !i || null == i.compatibleIds || i.compatibleIds.some(e => e === t.mediaOptionId) + })] + } + class jm extends kl { + constructor(e, t, i) { + super(e), this.itemId = t, this.mediaOptionType = i, this.allowFilters = this._initFilters() + } + get mediaOptionList() { + var e; + return (null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.mediaOptions) || null + } + get mediaOptionList$() { + return this.mediaOptionListInfo$.pipe(hr(({ + mediaOptions: e + }) => e)) + } + mediaOptionFromId(t) { + var e; + return null !== (e = (null !== (e = this.mediaOptionList) && void 0 !== e ? e : []).find(e => e.mediaOptionId === t)) && void 0 !== e ? e : null + } + _getFilteredList(e) { + return Km(e.mediaOptions, this.allowFilters, e) + } + get filteredMediaOptionList() { + return this.mediaOptionListInfo ? this._getFilteredList(this.mediaOptionListInfo) : null + } + get filteredMediaOptionList$() { + return this.mediaOptionListInfo$.pipe(La(e => { + const t = [Wu], + i = performance.now(); + for (const r of e.penaltyBoxQueue) ne(r.expiry) && r.expiry > i && t.push(bn(r.expiry - i)); + return an(...t).pipe(hr(() => this._getFilteredList(e))) + }), vl()) + } + get preferredMediaOptionList() { + return this.filteredMediaOptionList ? qm(this.preferredHost, this.filteredMediaOptionList) : [] + } + get preferredMediaOptionList$() { + return ed([this.preferredHost$, this.filteredMediaOptionList$]).pipe(hr(([e, t]) => qm(e, t))) + } + getNewHost(e) { + e = this.getFallbackVariant(e, !1, !0); + return null != e && e.url ? Eu(e.url) : this.preferredHost + } + } + + function Qm(e) { + return "PQ" === e.videoRange || "HLG" === e.videoRange + } + + function Wm(e, t) { + return t.iframes === e + } + + function Gm(e, t, i, r) { + return !r || i.bitrate > r.bitrate && i.bitrate <= e.bitrate ? km.Better : i.bitrate === r.bitrate ? km.Same : km.Worse + } + + function zm(e, t) { + return e && !t ? -1 : !e && t ? 1 : 0 + }(dl = km = km || {})[dl.Better = 1] = "Better", dl[dl.Same = 0] = "Same", dl[dl.Worse = -1] = "Worse"; + class Xm extends jm { + constructor(e, t) { + super(e, t, gu.Variant) + } + static makeFilters() { + return [...Hm().concat([new Vm({ + name: "HDR Filter", + priority: 1, + filterFn: (e, t, i) => !i || (i.hasHdrLevels && i.preferHDR) === Qm(e) + }), new Vm({ + name: "Viewport Filter", + priority: 1, + firstPassFn: (e, t, i) => { + if (i && e && !e.iframes && e.videoCodec) { + const t = !i.lowestBitrate || e.bitrate < i.lowestBitrate ? e.bitrate : i.lowestBitrate; + i.lowestBitrate = t + } + }, + filterFn: (e, t, i) => !(e && i && i.viewportInfo && e.videoCodec && i.lowestBitrate) || function(e, t) { + return e.width < 1.35 * t.width && e.height < 1.35 * t.height && e.width * e.height < t.width * t.height * 1.35 + }({ + width: e.width, + height: e.height + }, i.viewportInfo) || e.bitrate === i.lowestBitrate + }), new Vm({ + name: "HDCP Filter", + priority: 2, + filterFn: (e, t, i) => !i || !dm(i.maxHdcpLevel) || um(e.hdcpLevel) < um(i.maxHdcpLevel) + })])].sort((e, t) => { + return (null !== (e = e.priority) && void 0 !== e ? e : Number.MAX_SAFE_INTEGER) - (null !== (t = t.priority) && void 0 !== t ? t : Number.MAX_SAFE_INTEGER) + }) + } + _initFilters() { + return Xm.kAllowFilters + } + get preferredHost() { + var e; + return null !== (e = null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.preferredHost) && void 0 !== e ? e : null + } + get preferredHost$() { + return this.selectEntity(this.itemId, e => { + return null !== (e = null == e ? void 0 : e.mediaOptionListTuple[gu.Variant].preferredHost) && void 0 !== e ? e : null + }) + } + get mediaOptionListInfo() { + var e; + return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.mediaOptionListTuple[gu.Variant]) && void 0 !== e ? e : null + } + get mediaOptionListInfo$() { + return this.selectEntity(this.itemId, e => { + return null === (e = null == e ? void 0 : e.mediaOptionListTuple) || void 0 === e ? void 0 : e[gu.Variant] + }).pipe(Kp()) + } + get hdrMode$() { + return this.mediaOptionListInfo$.pipe(hr(e => !0 === e.preferHDR && e.hasHdrLevels), Is()) + } + get maxHdcpLevel$() { + return this.selectEntity(this.itemId, e => { + e = null === (e = null == e ? void 0 : e.mediaOptionListTuple) || void 0 === e ? void 0 : e[gu.Variant]; + return null == e ? void 0 : e.maxHdcpLevel + }).pipe(Is()) + } + listFallbackVariants(t, e, i, r, n) { + var s = this.mediaOptionListInfo, + a = null === (o = this.mediaOptionList) || void 0 === o ? void 0 : o.find(e => e.mediaOptionId === t); + if (!a || !s) return null; + var o = this.makeFilteredListFromVariant(a, e, n); + if (!o) return null; + e = Eu(a.url), s = s.hasScore; + return Xm._listFallbackVariants(o, a, e, s, i, r, n) + } + getFallbackVariant(t, e, i, r) { + var n = this.mediaOptionListInfo, + s = null === (s = this.mediaOptionList) || void 0 === s ? void 0 : s.find(e => e.mediaOptionId === t); + if (!s || !n) return null; + e = this.makeFilteredListFromVariant(s, e, r); + if (!e) return null; + r = Eu(s.url), n = n.hasScore; + return Xm._getFallbackVariant(e, s, r, n, i) + } + makeFilteredListFromVariant(e, t, i) { + let r = this.mediaOptionListInfo; + if (!e || !this.mediaOptionList || !r) return null; + r = Object.assign(Object.assign({}, r), { + includeAllEligiblePathways: !0 + }); + e = Array.from(this.mediaOptionList); + let n = t ? Km(e, this.allowFilters, Object.assign(Object.assign({}, r), { + preferHDR: !1, + compatibleIds: null + })) : this._getFilteredList(r); + return n ? (i && 0 < i.length && (n = n.filter(e => !i.includes(e.mediaOptionId))), n) : null + } + get hasIframes() { + var e; + return null !== (e = null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.hasIframeLevels) && void 0 !== e && e + } + canSwitchToSDR(e, t, i = !1) { + var r = this.mediaOptionListInfo; + if (!this.mediaOptionList || !r) return !1; + var n = this.mediaOptionFromId(e); + if (!n) return !1; + if (!Qm(n)) return !1; + var s = Eu(n.url), + e = Km(Array.from(this.mediaOptionList), this.allowFilters, Object.assign(Object.assign({}, r), { + preferHDR: !1, + compatibleIds: null + })), + r = r.hasScore; + return null != Xm._getFallbackVariant(e, n, s, r, t, i) + } + static _listFallbackVariants(e, r, n, t, s, a = !1, i = null) { + let o = !1; + const l = function(e, s, a) { + const t = [...e], + o = Eu(s.url), + l = s.audioGroupId; + return t.sort((e, t) => { + let i = 0; + var r = a && ne(e.score) && ne(t.score), + n = r ? e.score > t.score && e.score <= s.score : e.bitrate > t.bitrate && e.bitrate <= s.bitrate, + r = r ? e.score === t.score : e.bitrate === t.bitrate; + return n ? i = -1 : r ? (i = zm(Au(o, e.url), Au(o, t.url)), 0 === i && (i = zm(!l || e.audioGroupId === l, !l || t.audioGroupId === l))) : i = 1, i + }), t + }(e.filter(e => { + var t = !(e.iframes !== r.iframes || s && Au(n, e.url)), + i = a ? e.bitrate < r.bitrate : e.bitrate <= r.bitrate, + i = t && i; + return r.mediaOptionId === e.mediaOptionId ? (o = i, !1) : i + }), r, t); + return !o || i && i.includes(r.mediaOptionId) || l.unshift(r), l + } + static _getFallbackVariant(e, t, i, r, n, s = !1) { + let a = null; + e = (e = s ? e.filter(e => e.bitrate < t.bitrate) : e).filter(e => e.mediaOptionId !== t.mediaOptionId && e.iframes === t.iframes); + if (n && null != i) + for (const o of e) Gm(t, 0, o, a) !== km.Better || Au(i, o.url) || (a = o); + else + for (const o of e) { + const r = Gm(t, 0, o, a); + r !== km.Better && (r !== km.Same || !Au(i, o.url) || Au(i, a.url) && o.audioGroupId !== t.audioGroupId) || (a = o) + } + return a + } + getMatchingVariant(e, t) { + var i = this.mediaOptionFromId(e), + r = Eu(null == i ? void 0 : i.url), + n = t.mediaOptionType === gu.AltAudio ? "audioGroupId" : "subtitleGroupId"; + let s = null; + this.mediaOptionListInfo.hasScore; + for (const e of this.filteredMediaOptionList) + if (e[n] === t.groupId) { + if (!i) { + s = e; + break + } + var a = Gm(i, 0, e, s); + a !== km.Better && (a !== km.Same || s.mediaOptionId === i.mediaOptionId || e.mediaOptionId !== i.mediaOptionId && !Au(r, e.url)) || (s = e) + } return s + } + get currentPathwayID() { + var e; + return null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.currentPathwayID + } + } + + function Ym(e, t) { + switch (e) { + case Cm.SendAlternateToPenaltyBox: + e = Cm.RetryRequest, 401 !== t && 403 !== t && 407 !== t && t !== $.CorruptStream.code && t !== $.LivePlaylistUpdateError.code || (e = Cm.SendEndCallback); + break; + case Cm.RemoveAlternatePermanently: + e = Cm.SendEndCallback + } + return e + } + + function Jm(e, t, i, r, n, s, a, o = !1) { + const l = s.mediaOptionListQueries[n], + d = 0 != (e.errorActionFlags & Dm.MoveAllAlternatesMatchingHost), + u = s.mediaOptionListQueries[n].mediaOptionFromId(r), + c = a.getFallbackMediaOptionTupleFromMediaOptionId(s, n, r, u.backingMediaOptionId, !1, d, o); + let { + errorAction: h, + errorActionFlags: p + } = e; + return s.isValidMediaOptionTuple(c) ? Au(l.preferredHost, c[n].url) && (p &= ~Dm.MoveAllAlternatesMatchingHost) : (t || (h = Ym(h, i), p = 0), l instanceof Xm && (!0 === l.mediaOptionFromId(r).iframes ? (h = Cm.DoNothing, p = 0) : !t && a.canSwitchToSDR(s, r, d, o) && (h = e.errorAction, p = Dm.SwitchToSDR))), { + errorAction: h, + errorActionFlags: p + } + } + + function Zm(e) { + let t, i = 0; + switch (e) { + case 0: + t = Cm.SendAlternateToPenaltyBox, i = Dm.MoveAllAlternatesMatchingHost; + break; + case 410: + t = Cm.RemoveAlternatePermanently; + break; + case 500: + case 502: + case 503: + case 504: + case 404: + case 409: + case 401: + case 403: + case 407: + case $.LivePlaylistUpdateError.code: + case $.PlaylistNotReceived.code: + default: + t = Cm.SendAlternateToPenaltyBox, i = 0 + } + return { + errorAction: t, + errorActionFlags: i + } + } + + function eg(i, r, n, s, a, o, l) { + var { + errorAction: d, + errorActionFlags: u + } = i; + let e = !0; + switch (d) { + case Cm.RemoveAlternatePermanently: + case Cm.SendAlternateToPenaltyBox: { + if (null == a || null == o) return r.handled = !1; + const i = n.itemId; + let e = o, + t = n.mediaOptionListQueries[a].mediaOptionFromId(o); + t.backingMediaOptionId && (e = t.backingMediaOptionId, t = n.mediaOptionListQueries[a].mediaOptionFromId(e)); + var c = 0 != (u & Dm.MoveAllAlternatesMatchingHost), + h = 0 != (u & Dm.MoveAllAlternatesMatchingHDCP), + p = 0 != (u & Dm.SwitchToSDR), + f = d === Cm.RemoveAlternatePermanently; + if (h && "hdcpLevel" in t) { + const r = t.hdcpLevel; + s.setMaxHdcpLevel(i, r) + } + if (p && s.switchToSDROnly(i), c) { + const r = Eu(t.url); + s.moveAllWithMatchingHosts(i, a, r, f) + } else f ? s.removePermanently(i, a, e) : s.addToPenaltyBox(i, a, e); + if (n.enabledMediaOptionIdByType(a) === o) { + let e = [Lu, Lu, Lu]; + e = s.getFallbackMediaOptionTupleFromMediaOptionId(n, a, o, null, !1, c, l), n.isValidMediaOptionTuple(e) ? s.setPreferredHost(i, Eu(e[gu.Variant].url)) : r.fatal = !0, r.fatal && (e = [Lu, Lu, Lu]), s.setNextMediaOptions(n.itemId, e) + } + break + } + case Cm.SendEndCallback: + r.fatal = !0; + break; + case Cm.RetryRequest: + case Cm.DoNothing: + default: + e = !1 + } + return r.handled = e, e + } + + function tg(e, t) { + t instanceof dc || t instanceof uc || t instanceof hc || (t instanceof gc || t instanceof mc) && le(t.keyuri) + } + + function ig(t, i, r) { + if (t.handled = !0, r && i < r.maxNumRetry && ne(r.retryDelayMs)) { + let e; + return e = "linear" === r.backoff ? (i + 1) * r.retryDelayMs : Math.pow(2, i) * r.retryDelayMs, e = Math.min(r.maxRetryDelayMs, e), tg(0, t), bn(e) + } + return t.fatal = !0, tg(0, t), Vi(t) + } + + function rg(e, t, i, r, n, s, a, o, l = !1) { + return (null == r ? void 0 : r.errorAction) === Cm.RetryRequest ? ig(e, t, i, s.logger) : ng(e, 0, r, n, s, a, o, l) + } + + function ng(e, t, i, r, n, s, a, o = !1) { + const l = new er; + return al(() => { + i && (tg(n.logger, e), eg(i, e, r, n, s, a, o)), l.error(e) + }), l + } + + function sg(t, i, r, n) { + return e => e.pipe(Vn(e => { + if (t.logger.error(`Got demux error ${e.message}`), e instanceof D || e instanceof F) { + Cm.SendAlternateToPenaltyBox; + return ng(e, 0, { + errorAction: e.fatal ? Cm.SendEndCallback : e instanceof F ? Cm.SendAlternateToPenaltyBox : Cm.RemoveAlternatePermanently, + errorActionFlags: 0 + }, i, t, r, n) + } + throw e + })) + } + + function ag(e, t, i, r, n) { + e = null !== (e = null === (e = n.getKeyInfo(e)) || void 0 === e ? void 0 : e.mediaOptionIds) && void 0 !== e ? e : []; + for (const s of e) + for (const n of i.mediaOptionListQueries) null != n.mediaOptionFromId(s) && r.updateConsecutiveTimeouts(i.itemId, n.mediaOptionType, t, "key") + } + + function og(r, t, e, n, s, a) { + const o = n.logger, + i = s.enabledMediaOptionKeys, + l = []; + for (const t of r.mediaOptionIds) { + const r = i.some(e => e.mediaOptionId === t), + e = s.mediaOptionListQueries.find(e => null != e.mediaOptionFromId(t)); + if (e) { + const n = e.mediaOptionType, + a = { + mediaOptionId: t, + mediaOptionType: n + }; + r ? l.push(a) : l.unshift(a) + } else o.warn(`Couldn't find query for ${t}`) + } + const d = new er; + return al(() => { + const e = r instanceof mc; + ag(r.keyuri, e, s, n, a); + let t, i = !1; + for (const { + mediaOptionId: e, + mediaOptionType: a + } of l) t = function(e, t, i, r, n) { + let s = { + errorAction: Cm.SendAlternateToPenaltyBox, + errorActionFlags: 0 + }; + if (e instanceof mc) s.errorAction = Cm.SendAlternateToPenaltyBox; + else { + const t = e.isOkToRetry; + e.keyErrorReason === rc.OutputRestricted ? (s.errorAction = Cm.RemoveAlternatePermanently, s.errorActionFlags |= Dm.MoveAllAlternatesMatchingHDCP) : t ? s = Zm(e.code) : s.errorAction = Cm.RemoveAlternatePermanently + } + s.errorActionFlags &= ~Dm.MoveAllAlternatesMatchingHost; + var a = r.enabledMediaOptionIdByType(i); + return t === a ? Jm(s, !1, e.code, a, i, r, n, e.isTimeout) : s + }(r, e, a, s, n), o.error(`[Keys] handleNetworkError uri=${le(r.keyuri)} mediaOptionId=${e} mediaOptionType=${a} action=${JSON.stringify(t)}`), t.errorAction === Cm.RetryRequest && (i = !0), eg(t, r, s, n, a, e); + i ? (d.next(), d.complete()) : (tg(0, r), d.error(r)) + }), d.pipe(La(() => ig(r, t, e, n.logger))) + } + + function lg(t, i, r, n, s, a, o, l) { + return n = Math.max(0, n), e => e.pipe(Za(() => { + null != i && o.updateConsecutiveTimeouts(t, i, !1, "load") + }), va(e => e.pipe(jr((e, t) => function(e, t, i, r, n, s, a, o) { + var l; + if (!(e instanceof p)) return Vi(e); + let d, u, c, h = !1; + if (e instanceof dc) c = { + errorAction: Ym(Zm((l = e).response.code).errorAction, l.response.code), + errorActionFlags: 0 + }; + else if (e instanceof uc || e instanceof hc) { + ({ + mediaOptionType: u, + mediaOptionId: d, + isTimeout: h + } = e); + const t = null === (l = s.mediaOptionListQueries[u]) || void 0 === l ? void 0 : l.mediaOptionFromId(d); + if (!r && e.isTimeout && null != t && (!("iframes" in t) || !0 !== t.iframes) && (a.updateConsecutiveTimeouts(s.itemId, e.mediaOptionType, !0, "load"), e instanceof hc && e.stats)) { + const t = performance.now(); + o.setBandwidthSample(Object.assign(Object.assign({}, e.stats), { + tfirst: e.stats.tfirst || t, + tload: e.stats.tload || t, + complete: !0, + mediaOptionType: u + })) + } + c = function(e, t, i, r, n) { + var s = e.response.code; + let a = Zm(s); + var { + mediaOptionId: o, + mediaOptionType: l + } = e; + return t ? a.errorActionFlags &= ~Dm.MoveAllAlternatesMatchingHost : a = function(e, t, i, r, n) { + let { + errorAction: s, + errorActionFlags: a + } = t; + if (e.isTimeout) { + const t = e["mediaOptionType"], + o = null !== (n = null === (n = n.getErrorInfoByType(t)) || void 0 === n ? void 0 : n.timeouts.load) && void 0 !== n ? n : 0; + !i && r <= o && (s = Cm.DoNothing, a = 0) + } + return { + errorAction: s, + errorActionFlags: a + } + }(e, a, t, i, r), a = Jm(a, t, s, o, l, r, n, e.isTimeout), a + }(e, r, n, s, a) + } + return rg(e, t, i, c, s, a, u, d, h) + }(e, t, _c(e, r), s, n, a, o, l))))) + } + Xm.kAllowFilters = Xm.makeFilters(), (dl = Cm = Cm || {})[dl.DoNothing = 0] = "DoNothing", dl[dl.SendEndCallback = 1] = "SendEndCallback", dl[dl.SendAlternateToPenaltyBox = 2] = "SendAlternateToPenaltyBox", dl[dl.RemoveAlternatePermanently = 3] = "RemoveAlternatePermanently", dl[dl.InsertDiscontinuity = 4] = "InsertDiscontinuity", dl[dl.RetryRequest = 5] = "RetryRequest", (dl = Dm = Dm || {})[dl.MoveAllAlternatesMatchingHost = 1] = "MoveAllAlternatesMatchingHost", dl[dl.MoveAllAlternatesMatchingHDCP = 2] = "MoveAllAlternatesMatchingHDCP", dl[dl.SwitchToSDR = 4] = "SwitchToSDR"; + class dg extends kl { + constructor(e) { + super(e) + } + get currentConfig() { + var e; + return null === (e = this.getActive()) || void 0 === e ? void 0 : e.config + } + get extendMaxTTFB() { + var e; + return null === (e = this.getActive()) || void 0 === e ? void 0 : e.extendMaxTTFB + } + get config$() { + return this.selectActive(e => null == e ? void 0 : e.config) + } + get userSeek$() { + return this.selectActive(e => null == e ? void 0 : e.userSeek) + } + } + A(); + class ug extends fl { + constructor() { + super({}, { + name: "hls-store", + producerFn: su + }) + } + } + class cg { + constructor(e) { + this.store = e + } + getQuery() { + return new dg(this.store) + } + setHlsEntity(e) { + const t = e.id; + Do(`hls.set.entity ${t}`), al(() => { + this.store.add(de(e)), this.store.setActive(t) + }) + } + removeEntity(e) { + Do(`hls.remove ${e}`), this.store.remove(e) + } + setStartTime(t) { + this.store.updateActive(e => { + e.config.startPosition = t + }) + } + setUserSeek(t) { + this.store.updateActive(e => { + e.userSeek = t + }) + } + setExtendMaxTTFB(t) { + this.store.updateActive(e => { + e.extendMaxTTFB = t + }) + } + } + let hg, pg; + + function fg() { + return hg = hg || new cg(new ug), hg + } + + function mg() { + return fg().getQuery().currentConfig + } + + function gg(r, n) { + if ("VOD" !== r.type && "VOD" !== n.type && r.iframesOnly === n.iframesOnly) { + const s = r.mediaOptionId === n.mediaOptionId, + a = Math.max(r.startSN, n.startSN) - n.startSN, + o = Math.min(r.endSN, n.endSN) - n.startSN, + l = n.startSN - r.startSN, + d = r.fragments, + u = n.fragments; + let t = 0; + for (let e = a; e <= o; ++e) + if (d[l + e] && u[e]) { + t = d[l + e].discoSeqNum - u[e].discoSeqNum; + break + } const c = {}; + let i = null; + for (let e = 0; e < u.length; e++) { + const h = d[l + e], + a = u[e]; + if (t) { + const r = a.discoSeqNum + t; + n.initSegments[a.discoSeqNum] && (n.initSegments[a.discoSeqNum].discoSeqNum = r, c[r] = n.initSegments[a.discoSeqNum], delete n.initSegments[a.discoSeqNum]), a.discoSeqNum = r + } + s && a.mediaSeqNum === (null == h ? void 0 : h.mediaSeqNum) && null != h.startPts && (a.start = h.start, a.duration = h.duration, a.startDtsTs = h.startDtsTs, a.endDtsTs = h.endDtsTs, a.startPts = h.startPts, a.endPts = h.endPts, i = a) + } + if (Object.keys(c).length && (n.initSegments = c), i) Bm(n, i, i.start, void 0, !1, !0); + else if (0 <= l && l < d.length) { + const r = d[l].start, + h = n.fragments; + for (let e = 0; e < u.length; e++) h[e].start += r + } + n.ptsKnown = n.ptsKnown || s && !0 === r.ptsKnown && r.endSN >= n.startSN, $m(n) + } + } + + function yg(e, t, i) { + let r = t.targetduration; + return ne(i.liveSyncDuration) ? r = i.liveSyncDuration : ne(i.liveSyncDurationCount) && (r = i.liveSyncDurationCount * t.targetduration), e + Math.max(0, t.totalduration - r) + } + + function vg(e, t, i, r, n) { + if (!t.ptsKnown) return 0; + var s = t.targetduration, + a = t.fragments[0].start, + r = n.canContinuePlaybackWithoutGap(t, i, { + avgPlaylistLoadTimeMs: 0, + avgPlaylistParseTimeMs: 0 + }, r); + let o = Math.max(0, e - s); + return e < a && !r && (o = a), o + } + + function Sg(e) { + return 1e3 * (e.averagetargetduration || e.targetduration) + } + + function bg(e, t) { + var i = Sg(e), + t = performance.now() - t; + return e.liveOrEvent && i <= t + } + + function Tg(t, i, r = NaN) { + var n = t.fragments; + for (let e = r > t.startSN ? r - t.startSN : 0; e < n.length; ++e) { + const t = n[e], + r = t["start"]; + if (i(t)) return { + timelineOffset: r, + mediaFragment: t + } + } + return null + } + + function Eg(e, t, i) { + var r = 0 < i.duration, + n = i.start + i.duration, + n = null == t || t < n || t - n < 1 && i.isLastFragment, + e = e.every(e => !$p(e.frag, i)); + return r && e && n + } + + function Ig(e, t, i, r, n) { + i = null !== (i = Tg(r, Eg.bind(null, n, void 0), i)) && void 0 !== i ? i : null; + let s = null; + i && (s = null !== (e = Tg(r, Eg.bind(null, n, e), i.mediaFragment.mediaSeqNum)) && void 0 !== e ? e : null, s || !r.liveOrEvent || r.ptsKnown || (s = i)); + let a = NaN; + null != s && ne(t) && s.mediaFragment.discoSeqNum !== t && (a = s.mediaFragment.discoSeqNum, s = null); + t = n.some(e => 0 < e.frag.framesWithoutIDR); + return s && t && n[n.length - 1].frag.mediaOptionId !== r.mediaOptionId && (s = null !== (r = Tg(r, e => e.mediaSeqNum === s.mediaFragment.mediaSeqNum - 1)) && void 0 !== r ? r : s), { + foundFrag: s, + nextDisco: a + } + } + + function wg(e) { + e = e.fragments[e.fragments.length - 1]; + return e ? e.start + e.duration : 0 + } + class Ag extends kl { + constructor(e, t) { + super(e), this.mediaOption = t + } + get itemId() { + return this.mediaOption.itemId + } + get mediaOptionId() { + return this.mediaOption.mediaOptionId + } + get initSegmentEntities() { + var e; + return null === (e = this.mediaOptionDetailsEntity) || void 0 === e ? void 0 : e.initSegmentCacheEntities + } + get mediaLibraryEntity() { + return this.getEntity(this.itemId) + } + get mediaOptionDetailsEntityRecord() { + var e; + return null === (e = this.mediaLibraryEntity) || void 0 === e ? void 0 : e.mediaOptionDetailsEntityRecord + } + get mediaOptionDetailsEntity() { + return this.mediaOptionDetailsEntityRecord ? this.mediaOptionDetailsEntityRecord[this.mediaOptionId] : null + } + get mediaOptionDetails() { + var e; + return null === (e = this.mediaOptionDetailsEntity) || void 0 === e ? void 0 : e.mediaOptionDetails + } + get playlistDuration() { + var e; + return null === (e = this.mediaOptionDetailsEntity) || void 0 === e ? void 0 : e.playlistDuration + } + get mediaOptionDetailsEntity$() { + const { + itemId: e, + mediaOptionId: t + } = this; + return this.selectEntity(e, e => { + if (null != e && e.mediaOptionDetailsEntityRecord) return null == e ? void 0 : e.mediaOptionDetailsEntityRecord[t] + }) + } + get mediaOptionDetails$() { + return this.selectEntity(this.itemId, e => { + return null === (e = null == e ? void 0 : e.mediaOptionDetailsEntityRecord[this.mediaOptionId]) || void 0 === e ? void 0 : e.mediaOptionDetails + }).pipe(Kp()) + } + get playlistDuration$() { + return this.mediaOptionDetailsEntity$.pipe(hr(e => null == e ? void 0 : e.playlistDuration), Kp(), Is()) + } + get live$() { + return this.mediaOptionDetails$.pipe(hr(e => null == e ? void 0 : e.liveOrEvent), Is()) + } + } + class Og extends fl { + constructor() { + super({}, { + name: "media-library-store", + idKey: "itemId", + producerFn: su + }) + } + } + class kg { + constructor(e) { + this.store = e + } + getQuery() { + return new kl(this.store) + } + getQueryForOption(e) { + return new Ag(this.store, e) + } + createMediaLibraryEntity(e) { + var t = { + itemId: e, + mediaOptionDetailsEntityRecord: {} + }; + Do(`library.entity.create: ${e}`), this.store.add(t) + } + setDetailsLoading(e) { + const { + itemId: t, + mediaOptionId: i + } = e; + Do(`library.details.loading: ${i}`), this.store.update(t, ({ + mediaOptionDetailsEntityRecord: e + }) => { + e[i] || (e[i] = { + initSegmentCacheEntities: {}, + unchangedCount: 0 + }), e[i].detailsLoading = !0 + }) + } + archiveMediaOptionDetails(i, r, n) { + const { + itemId: e, + mediaOptionId: s + } = i, a = performance.now(), o = wg(i); + Do(`library.details.loaded: ${s}`), this.store.update(e, e => { + const t = e.mediaOptionDetailsEntityRecord[s]; + t.detailsLoading = !1, t.mediaOptionDetails = i, t.lastUpdateMillis = a, n ? t.unchangedCount = 0 : ++t.unchangedCount, t.playlistDuration = o, t.stats = r, e.liveOrEvent = i.liveOrEvent + }) + } + setInitSegmentLoading(e) { + const { + itemId: t, + mediaOptionId: i, + discoSeqNum: r + } = e; + Do(`library.initsegs.loading: ${i}/${r}`), this.store.update(t, e => { + e.mediaOptionDetailsEntityRecord[i].initSegLoading = r + }) + } + archiveInitSegmentEntity(i, r) { + const { + itemId: e, + mediaOptionId: n, + discoSeqNum: s + } = i; + Do(`library.initseg.loaded: ${n}/${s}`), this.store.update(e, ({ + mediaOptionDetailsEntityRecord: e + }) => { + const t = e[n]; + t.initSegmentCacheEntities[s] = [i, r], t.initSegLoading = null + }) + } + updatePTSDTS(e, i, t, r) { + var n = null === (n = this.getQueryForOption({ + itemId: e, + mediaOptionId: i + })) || void 0 === n ? void 0 : n.mediaOptionDetails; + if (n && Fm(n, r)) { + const s = r["startDtsTs"], + { + variantDTS: a, + timelineOffset: o, + iframeMode: l + } = t, + d = b(s, a) + o, + u = Object.assign({}, n); + Bm(u, r, d, l, !0), $m(u); + const c = wg(u); + this.store.update(e, ({ + mediaOptionDetailsEntityRecord: e + }) => { + const t = e[i]; + null != t && t.mediaOptionDetails && (t.mediaOptionDetails = u, t.playlistDuration = c) + }) + } + } + remove(e) { + this.store.remove(e) + } + clear() { + this.store.remove() + } + } + + function Cg() { + return pg = pg || new kg(new Og), pg + } + const Dg = e => Cg().getQueryForOption(e), + Mg = (d, e, t = !1, i = !1) => { + if (null == e || !_u(e)) return $i(null); + const r = e["itemId"], + n = d["mediaLibraryService"], + s = n.getQueryForOption(e); + s.hasEntity(r) || n.createMediaLibraryEntity(r); + var a = s.mediaOptionDetailsEntity, + o = s.mediaOptionDetails; + return null == o || i || "VOD" !== o.type && (!o.liveOrEvent || bg(o, a.lastUpdateMillis)) ? (n.setDetailsLoading(e), function(u, e) { + var t; + const { + logger: i, + config: c, + rootPlaylistQuery: h, + rootPlaylistService: p, + statsService: r, + mediaLibraryService: f, + mediaSink: n + } = d, m = n.mediaQuery, s = c.playlistLoadPolicy, a = c.keySystemPreference, o = h.masterVariableList, l = null === (t = null === (t = fg()) || void 0 === t ? void 0 : t.getQuery()) || void 0 === t ? void 0 : t.extendMaxTTFB; + return _m(u, h.itemStartOffset, c, s, i, a, r, o, l).pipe(hr(e => { + const t = f.getQueryForOption(u), + i = t.mediaOptionDetails, + r = e["mediaOptionDetails"], + n = e["stats"]; + let s = !0; + if (r.liveOrEvent) { + const d = r["mediaOptionType"]; + e = r, s = null == i || e.endSN !== i.endSN || e.liveOrEvent !== i.liveOrEvent, i && gg(i, r); + const u = h.lastLoadedMediaOptionByType(d), + t = u ? null === (l = f.getQueryForOption(u)) || void 0 === l ? void 0 : l.mediaOptionDetails : null; + !r.ptsKnown && t && t.mediaOptionId !== (null == i ? void 0 : i.mediaOptionId) && gg(t, r) + } + r && al(() => { + f.archiveMediaOptionDetails(r, n, s), p.setLastLoadedMediaOptionByType(h.itemId, u.mediaOptionType, u) + }); + const a = !s && t.mediaOptionDetailsEntity.unchangedCount >= c.liveMaxUnchangedPlaylistRefresh, + o = function(e, t, i, r) { + t = vg(r.currentTime, e, t, i, r), i = e.fragments[e.fragments.length - 1], r = (null == i ? void 0 : i.start) + (null == i ? void 0 : i.duration); + return { + expired: null != i && e.liveOrEvent && e.ptsKnown && r < t, + windowEnd: r, + minPosition: t + } + }(r, n.tload, c.maxBufferHole, m); + if (a || o.expired) { + var l = a ? $.LivePlaylistUpdateError : { + text: `Live window too far in the past end:${o.windowEnd.toFixed(3)} minPosition:${o.minPosition}`, + code: 0 + }; + throw new uc(!1, l.text, l.code, l, !1, u.mediaOptionType, u.mediaOptionId, u.url) + } + return r + }), tc("getMediaOptionDetailsCommon.emit.loaded"), lg(u.itemId, u.mediaOptionType, Lc(u, s), c.maxNumAddLevelToPenaltyBox, e, h, p, r)).pipe(Ds(1)) + }(e, t)) : $i(o).pipe(tc("retrieveMediaOptionDetails.emit.cached")).pipe(Ds(1)) + }; + const xg = (t, i) => { + if (!i) return $i(null); + const r = t["logger"], + { + mediaLibraryService: e, + mediaParser: n + } = t, + s = e.getQueryForOption(i), + { + mediaOption: a, + mediaOptionDetailsEntityRecord: o, + mediaOptionDetails: l + } = s, + d = a["mediaOptionId"]; + if (null == o || !o[d]) throw new Error("retrieveInitSegmentCacheEntity no details entity"); + if (!l) throw new Error("retrieveInitSegmentCacheEntity no details"); + var u = o[d]["initSegmentCacheEntities"], + c = l["initSegments"], + h = i["discoSeqNum"]; + if (u[h]) { + const [t, r] = u[h]; + let e = t; + return r && (e = n.willBeTrackSwitch(i) ? t : r), $i(e) + } + const p = c[h]; + return p ? (e.setInitSegmentLoading(p), r.child({ + name: "timing" + }), Rg(t, p, !1, !1).pipe(Za(() => {}), ji(tr), La(e => Pg(e, p, t)), Za(() => {}))) : $i(null) + }; + + function Pg(e, n, t) { + const { + logger: s, + mediaSink: i, + rootPlaylistService: r, + rootPlaylistQuery: a, + mediaParser: o, + mediaLibraryService: l, + gaplessInstance: d + } = t, u = i["mediaQuery"], c = l.getQueryForOption(n), { + mediaOption: h, + mediaOptionDetails: p + } = c, { + itemId: f, + mediaOptionId: m + } = h, { + keyTagInfo: g, + discoSeqNum: y, + mediaOptionType: v + } = n, S = u.seeking, b = p.liveOrEvent, T = v === gu.Variant && p.ptsKnown; + let E, I; + n.isInitSegment ? I = new Uint8Array(e) : E = new Uint8Array(e); + var e = { + segment: E, + initSegment: I, + frag: n, + ptsKnown: T, + seeking: S, + live: b, + totalDuration: p.totalduration + }; + return o.parseInitSegment(e, null !== (e = null === navigator || void 0 === navigator ? void 0 : navigator.vendor) && void 0 !== e ? e : "").pipe(hr(e => { + var { + track: t, + moovData: i, + mimeType: r + } = e, e = t["initSegment"]; + d.inGaplessMode && be.isVideoCodec(t.codec) && (s.warn(`Video codec discovered in gapless mode codec:${t.codec}`), d.dequeueSource("InvalidFormat")); + r = { + itemId: f, + mediaOptionId: m, + discoSeqNum: y, + initParsedData: i, + data: e, + mimeType: r, + keyTagInfo: g, + fragment: n + }; + return l.archiveInitSegmentEntity(r), r + }), sg(r, a, v, m)) + } + + function Rg(n, s, i, r) { + var e; + const { + rootPlaylistQuery: t, + rootPlaylistService: a, + config: o, + rtcService: l, + statsService: d + } = n, { + itemId: u, + mediaOptionType: c + } = s, h = o.fragLoadPolicy, p = ne(s.mediaSeqNum); + let f; + p && (f = { + getData: !1, + cb: (e, t, i, r) => (a.updateInflightFrag(u, s.mediaOptionType, s, "loading", i), !1) + }); + let m = !1; + r && null === l.serverInfoInstance && (m = !0); + const g = nm(s, o, h, f, m, null === (e = null === (e = fg()) || void 0 === e ? void 0 : e.getQuery()) || void 0 === e ? void 0 : e.extendMaxTTFB).pipe(Za(([, , e, t]) => { + i && d.setBandwidthSample(Object.assign(Object.assign({}, e), { + mediaOptionType: s.mediaOptionType + })), r && m && (l.serverInfoInstance = t), p && a.updateInflightFrag(u, s.mediaOptionType, s, "loaded", e) + }), Za(([e, , t]) => { + r && l.handleFragLoaded(e, t) + }), lg(u, c, Lc(s, h), o.maxNumAddLevelToPenaltyBox, !1, t, a, d)); + return "AES-128" === (null === (e = s.keyTagInfo) || void 0 === e ? void 0 : e.method) ? en([_g(n, s.keyTagInfo, { + itemId: s.itemId, + mediaOptionId: s.mediaOptionId + }), g]).pipe(La(([e, t]) => { + const [i, r] = t; + return i.keyTagInfo.key = e.key, Nm(i, r, o, n.logger, n.rpcClients.crypto) + })) : g.pipe(hr(e => e[1])) + } + const Lg = (i, r, e) => { + const { + rootPlaylistService: n, + rootPlaylistQuery: s + } = i, { + timelineOffset: a, + mediaFragment: o + } = e.foundFrag, { + itemId: l, + discoSeqNum: d + } = o; + return xg(i, o).pipe(La(t => (n.updateInflightFrag(l, o.mediaOptionType, o, "loading", null), Rg(i, o, !0, !0).pipe(La(e => { + return n.updateInflightFrag(l, r, o, "parsing", null), + function(e, t, i, y, v, S) { + const r = new Uint8Array(e), + { + legibleSystemAdapter: n, + rootPlaylistService: s, + mediaSink: a, + mediaParser: o, + rootPlaylistQuery: l, + mediaLibraryService: b + } = S, + d = a["mediaQuery"], + u = b.getQueryForOption(y), + { + mediaOption: c, + mediaOptionDetails: h + } = u, + p = h["initSegments"], + { + itemId: T, + mediaOptionId: E + } = c, + { + discoSeqNum: I, + mediaSeqNum: w, + mediaOptionType: f, + isLastFragment: A + } = y, + m = d.seeking, + g = h.liveOrEvent, + O = p[I], + k = f === gu.Variant && h.ptsKnown, + C = { + segment: r, + frag: y, + seeking: m, + live: g, + ptsKnown: k, + totalDuration: h.totalduration, + defaultInitPTS: t, + iframeMediaStart: Up(y) ? y.iframeMediaStart : void 0, + iframeDuration: Up(y) ? y.iframeMediaDuration : void 0, + iframeOriginalStart: Up(y) ? y.iframeOriginalStart : void 0 + }; + let D; + if (null != i && (null === (t = y.keyTagInfo) || void 0 === t ? void 0 : t.uri) === (null === (t = i.keyTagInfo) || void 0 === t ? void 0 : t.uri)) D = $i(i); + else if (null != i) { + const M = Object.assign(Object.assign({}, i.fragment), { + keyTagInfo: y.keyTagInfo + }); + D = Pg(O ? i.data : e, M, S) + } else D = Pg(e, y, S); + return D.pipe(La(m => { + const g = performance.now(); + if (null != m) { + const g = m["data"], + e = new Uint8Array(g); + C.initSegment = e + } + return y.mediaOptionType === gu.Variant && (null == n || n.setupForFrag(y)), o.parseSegment(C, "").pipe(hr(e => { + var t = performance.now(), + { + startPTS: i, + startDTS: r, + endPTS: n, + endDTS: s, + firstKeyframePts: a, + framesWithoutIDR: o, + dropped: l, + data1: d, + data2: u, + captionData: c, + id3Samples: h, + parsedInitSegment: e + } = e, + t = { + durationSec: n.baseTime / n.timescale - i.baseTime / i.timescale, + parseTimeMs: t - g + }; + S.statsService.setFragSample(t); + let p = Object.assign({}, m); + if (e) { + const { + track: g, + moovData: f, + mimeType: v + } = e, S = g["initSegment"]; + p = { + itemId: T, + mediaOptionId: E, + discoSeqNum: I, + initParsedData: f, + data: S, + mimeType: v, + keyTagInfo: y.keyTagInfo, + fragment: y + }, b.archiveInitSegmentEntity(m, p) + } + e = y.keyTagInfo; + return [p, { + itemId: T, + mediaOptionId: E, + mediaSeqNum: w, + discoSeqNum: I, + startDtsTs: r, + endDtsTs: s, + timelineOffset: v, + firstKeyframePts: a, + framesWithoutIDR: o, + dropped: l, + data1: d, + data2: u, + startPts: i, + endPts: n, + keyTagInfo: e, + isLastFragment: A, + iframe: null !== (e = y.iframe) && void 0 !== e && e, + duration: y.duration, + iframeMediaDuration: Up(y) ? y.iframeMediaDuration : void 0, + iframeOriginalStart: Up(y) ? y.iframeOriginalStart : void 0, + captionData: c, + id3Samples: h + }] + })) + }), sg(s, l, f, E)) + }(e, null === (e = s.getInitPTS(d)) || void 0 === e ? void 0 : e.offsetTimestamp, t, o, a, i) + }), Za(e => { + n.updateInflightFrag(l, r, o, "parsed", null) + }), tc(`retrieveMediaFragmentCacheEntity.${r}.emit`)))), Ds(1)) + }; + + function _g(e, t, i) { + const { + keySystemAdapter: r, + rootPlaylistQuery: n, + rootPlaylistService: s, + config: a + } = e; + return r.getKeyFromDecryptData(t, i).pipe((o = t.uri, l = Lc({ + url: t.uri + }, a.keyLoadPolicy), d = n, u = s, c = r.ksQuery, e => e.pipe(ll(() => { + ag(o, !1, d, u, c) + }), va(e => e.pipe(jr((e, t) => { + if (e instanceof mc || e instanceof gc) return og(e, t, _c(e, l), u, d, c); + throw e + })))))); + var o, l, d, u, c + } + class Ng { + constructor(e, t, i) { + this.hls = e, this.destroy$ = new Xt, this.iframeSwitchStart = 0, this.logger = t.child({ + name: "hls-player-events" + }), this.rtc = i, this.subscribeAndEmit() + } + destroy() { + this.destroy$.next() + } + subscribeAndEmit() { + var e = this.loaderQueryListener(new bc(Ec)), + t = this.hls.publicQueries$.pipe(La(([e, t]) => an(this.rootPlaylistQueryListener(e, t), this.mediaElementQueryListener(t, e)))); + an(e, t, this.activeItemListener(this.hls.itemQueue)).pipe(Vn(e => { + var t = e.message; + return this.logger.error(`Got error in HlsPlayerEvents ${t}`, e), Ii + }), Va(this.destroy$), Vs(() => {})).subscribe() + } + activeItemListener(e) { + return e.activeItemById$.pipe(Kp(), La(e => { + e = e.url; + return this.hls.trigger(P.MANIFEST_LOADING, { + url: e + }), Ii + })) + } + rootPlaylistQueryListener(t, e) { + var i = t.enabledMediaOptionByType$(gu.Variant).pipe(ln(e => !!e), La(e => { + var t; + return this.hls.trigger(P.LEVEL_SWITCHING, e), null === (t = this.rtc) || void 0 === t || t.handleLevelSwitching(e.url), Ii + })), + r = t.enabledMediaOptionByType$(gu.Variant).pipe(La(i => Dg(i).mediaOptionDetailsEntity$.pipe(ln(e => !0 === (null == e ? void 0 : e.detailsLoading)), Za(e => { + var t = { + url: le(null == i ? void 0 : i.url), + level: i.mediaOptionId, + type: Nu[i.mediaOptionType] + }; + return this.hls.trigger(P.LEVEL_LOADING, t), Ii + })))), + n = t.enabledMediaOptionByType$(gu.Variant).pipe(La(e => { + const t = Dg(e); + let i = 0; + return t.mediaOptionDetailsEntity$.pipe(Kp(), ln(e => { + var t = null !== e.stats && !1 === e.detailsLoading && e.lastUpdateMillis > i; + return i = null !== (e = e.lastUpdateMillis) && void 0 !== e ? e : 0, t + })) + }), La(e => { + var t = e.mediaOptionDetails, + i = e.stats, + r = { + mediaOptionId: t.mediaOptionId, + details: t, + playlistType: t.type, + stats: i + }; + if (null === (i = this.rtc) || void 0 === i || i.handleLevelLoaded(t, r.stats), this.hls.trigger(P.LEVEL_LOADED, r), 0 === e.unchangedCount) { + const e = { + level: 0, + details: t + }; + this.hls.trigger(P.LEVEL_UPDATED, e) + } + if (null != t && t.daterangeTags) { + const e = { + daterangeTags: t.daterangeTags + }; + this.hls.trigger(P.DATERANGE_UPDATED, e) + } + return Ii + })), + s = t.enableMediaOptionSwitchedForType$(gu.AltAudio).pipe(La(e => { + e = t.alternateMediaOptionById(gu.AltAudio, e.mediaOptionId); + return e && this.triggerAudioSwitch(e), Ii + })), + a = t.rootPlaylistEntity$.pipe(ln(e => null !== e.enabledMediaOptionKeys[gu.AltAudio].mediaOptionId), Ds(1), La(e => { + const t = e.enabledMediaOptionKeys[gu.AltAudio].mediaOptionId; + return t && (e = e.mediaOptionListTuple[gu.AltAudio].mediaOptions.find(e => e.mediaOptionId === t), this.triggerAudioSwitch(Object.assign(Object.assign({}, e), { + url: le(null == e ? void 0 : e.url) + }))), Ii + })); + return an(i, s, Gu(e.textTracksCreated$, e => e).pipe(La(() => t.enabledMediaOptionByType$(gu.Subtitle).pipe(La(e => { + e = t.alternateMediaOptionById(gu.Subtitle, e.mediaOptionId); + return e ? this.hls.trigger(P.SUBTITLE_TRACK_SWITCH, { + track: Object.assign({}, e), + hidden: !1 + }) : this.hls.trigger(P.SUBTITLE_TRACK_SWITCH, { + track: void 0, + hidden: !1 + }), Ii + })))), t.sessionData$.pipe(ln(e => null != e.complete), Ds(1), Za(e => {}), hr(e => { + this.hls.trigger(P.SESSION_DATA_COMPLETE, e) + })), t.getPreferredMediaOptionsByType$(gu.Variant).pipe(ka(1), hr(e => { + const t = e; + null === (e = this.rtc) || void 0 === e || e.handleLevelsChanged(t), t.forEach(e => {}), this.hls.trigger(P.LEVELS_CHANGED, { + requiresReset: !1, + levels: t + }) + })), t.getPreferredMediaOptionsByType$(gu.AltAudio).pipe(hr(e => { + this.hls.trigger(P.AUDIO_TRACKS_UPDATED, { + audioTracks: e + }) + })), Gu(e.textTracksCreated$, e => e).pipe(La(() => t.getPreferredMediaOptionsByType$(gu.Subtitle).pipe(Ds(1), hr(e => { + this.hls.trigger(P.SUBTITLE_TRACKS_UPDATED, { + subtitleTracks: e + }), this.hls.trigger(P.SUBTITLE_TRACKS_CREATED) + })))), n, r, a) + } + mediaElementQueryListener(s, e) { + return an(s.seekTo$.pipe(hr(e => { + var t; + e && ne(e.pos) ? (null === (t = this.rtc) || void 0 === t || t.handleSeek("SEEKING"), this.hls.trigger(P.SEEKING, { + seekToPos: e.pos + })) : null === e && (null === (e = this.rtc) || void 0 === e || e.handleSeek("SEEKED"), this.hls.trigger(P.SEEKED)) + })), s.desiredRate$.pipe(Ra(0), ha(), hr(e => { + var t = e[0], + i = e[1]; + Wp(i) ? 0 == this.iframeSwitchStart && (this.iframeSwitchStart = performance.now()) : this.iframeSwitchStart = 0, this.hls.trigger(P.DESIRED_RATE_CHANGED, { + oldRate: t, + newRate: i + }), null === (e = this.rtc) || void 0 === e || e.handleDesiredRateChanged(t, i) + })), s.sourceBufferEntityByType$(yu.AltAudio).pipe(ln(e => !!e), Is((e, t) => e.totalBytes === t.totalBytes), hr(e => { + this.hls.trigger(P.BUFFER_APPENDED) + })), s.sourceBufferEntityByType$(yu.Variant).pipe(ln(e => !!e), Is((e, t) => e.totalBytes === t.totalBytes), hr(e => { + var t; + null === (t = this.rtc) || void 0 === t || t.handleVariantBufferAppended(e.timestampOffset, e.totalBytes), this.hls.trigger(P.BUFFER_APPENDED) + })), s.stallInfo$.pipe(Kp(), bo(s.combinedBuffer$), hr(([e]) => { + var t; + null === (t = this.rtc) || void 0 === t || t.handleStalled(e, s.getCombinedBufferInfo(e.currentTime, 0).len), this.hls.trigger(P.STALLED, e) + })), Mr([$i(e), ed([s.timeupdate$, s.bufferedSegmentsByType$(yu.Variant)]).pipe(ao(1e3), hr(([t, e]) => null == e ? void 0 : e.find(e => e.startPTS <= t && e.endPTS > t)), ln(e => !!e), Ra(null), ha())]).pipe(La(([e, [t, i]]) => { + var r = null == i ? void 0 : i.frag, + t = null == t ? void 0 : t.frag; + if (r && !$p(t, r) && (this.hls.trigger(P.FRAG_CHANGED, i), this.hls.inGaplessMode && this.checkAndTriggerReadyForNext(s, i), !t || r.mediaOptionId !== t.mediaOptionId)) { + const s = e.mediaOptionListQueries[gu.Variant].mediaOptionFromId(r.mediaOptionId); + if (!s) return this.logger.warn("variantInfo is undefined in fragChangeMonitor"), Ii; + const n = t ? t.mediaOptionId : "", + i = r.mediaOptionId; + s.iframes && (performance.now(), this.iframeSwitchStart), null === (r = this.rtc) || void 0 === r || r.handleLevelSwitched({ + url: s.url, + mediaOptionId: s.mediaOptionId, + oldVariant: "" !== n ? n : void 0, + newVariant: i + }), this.hls.trigger(P.LEVEL_SWITCHED, s) + } + return Ii + })), s.isBufferedToEnd$(this.hls.config.maxBufferHole, !1).pipe(ln(e => !0 === e), ji(tr), hr(e => { + if (e && !this.hls.itemQueue.isPreloading() && this.hls.inGaplessMode) { + const i = s.getCombinedBufferInfo(s.currentTime, 0); + var t = 0; + i && (t = i.end, e = s.mediaElementDuration, 0 < t && e - s.currentTime < 10 && this.hls.trigger(P.READY_FOR_NEXT_ITEM, { + duration: t + })) + } + }))) + } + checkAndTriggerReadyForNext(e, t) { + var i, r; + t && t.frag && (i = e.currentTime, (r = e.getCombinedBufferInfo(i, 0)) && (i = r.end, r = e.mediaElementDuration, e = e.bufferMonitorInfo, e = Math.max(e.almostDryWaterLevelSeconds, e.lowWaterLevelSeconds / 2), (r - t.endPTS <= e || t.frag.isLastFragment) && this.hls.inGaplessMode && !this.hls.isPreloading && this.hls.trigger(P.READY_FOR_NEXT_ITEM, { + duration: i + }))) + } + loaderQueryListener(e) { + return an(e.unresolvedUriLoading$.pipe(hr(e => e.map(e => { + e = { + uri: e.uri, + responseType: e.responseType, + userAgent: e.userAgent + }; + this.hls.trigger(P.UNRESOLVED_URI_LOADING, e) + })))) + } + triggerAudioSwitch(e) { + e && this.hls.trigger(P.AUDIO_TRACK_SWITCHED, { + id: e.id + }) + } + triggerManifestLoaded(e) { + e = { + levels: e.rootMediaOptionsTuple[gu.Variant], + audioTracks: e.rootMediaOptionsTuple[gu.AltAudio], + subtitleTracks: e.rootMediaOptionsTuple[gu.Subtitle], + url: e.baseUrl, + audioMediaSelectionGroup: e.audioMediaSelectionGroup, + subtitleMediaSelectionGroup: e.subtitleMediaSelectionGroup, + stats: e.stats, + isMediaPlaylist: e.isMediaPlaylist + }; + this.hls.trigger(P.MANIFEST_LOADED, e) + } + triggerManifestParsed(e) { + var t = { + levels: e.mediaOptionListQueries[gu.Variant].filteredMediaOptionList, + firstLevel: 0, + audio: !1, + video: !0, + altAudio: !1, + audioTracks: e.mediaOptionListQueries[gu.AltAudio].filteredMediaOptionList, + audioMediaSelectionGroup: e.audioMediaSelectionGroup, + subtitleMediaSelectionGroup: e.subtitleMediaSelectionGroup, + stats: e.loadStats + }; + null === (e = this.rtc) || void 0 === e || e.handleManifestParsed(t), this.hls.trigger(P.MANIFEST_PARSED, t) + } + urlRedactedManifestLoaded(e) { + const t = Object.assign({}, e); + return t.url = le(t.url), t.levels = ue(t.levels), t.audioTracks = ce(t.audioTracks), t.subtitleTracks = ce(t.subtitleTracks), t + } + urlRedactedManifestParsed(e) { + const t = Object.assign({}, e); + return t.levels = ue(t.levels), t.audioTracks = ce(t.audioTracks), t + } + }(A = Mm = Mm || {}).LowBandwidth = "LowBandwidth", A.HighBandwidth = "HighBandwidth", A.PreferredListChanged = "PreferredListChanged", A.IframeModeChange = "IframeModeChange", A.None = ""; + const Fg = { + minValidBitrate: 2e6, + maxValidBitrate: 5e6, + maxPreferredBitrate: 3e6, + minValidHeight: 480, + maxValidHeight: 720 + }; + + function Bg(e, a, o, l, d, u) { + return e.reduce((e, t) => { + if (t.iframes) return e; + let i = e; + const r = (n = t.score, s = a && o && l && d && !Ug(t, a, o, l, d, u) ? mu.INVALID : mu.VALID, new Qp(s, n)); + var n, s; + return (!e || r.isGreaterThan(e.bestRank) || r.isEqualTo(e.bestRank) && t.bandwidth < e.selected.bandwidth) && (i = { + selected: t, + bestRank: r + }), i + }, null).selected + } + + function Ug(e, t, i, r, n, s) { + var { + targetDuration: a, + targetStartupMs: o + } = i, l = r["avgPlaylistLoadTimeMs"], d = n["avgParseTimeMs"], { + avgBufferCreateMs: i, + avgInitFragAppendMs: r, + avgDataFragAppendMs: n + } = s, { + avgBandwidth: s, + avgLatencyMs: t + } = t; + return e.bandwidth <= s && (e.avgBandwidth || e.bandwidth) * a / s * 1e3 + l + i + +(t + d + (r + n)) <= o + } + const $g = { + name: "abr" + }; + + function Vg(e, t) { + return ne(e) ? Math.min(e, t) : t + } + + function Kg(e) { + return ne(null == e ? void 0 : e.avgBandwidth) + } + + function qg(e, t) { + return e.getCurrentWaterLevelByType(yu.Variant, t) / (0 !== e.playbackRate ? Math.abs(e.playbackRate) : 1) + } + + function Hg(t, i, e, r) { + if (e) return t; + let n = -1; + if (t < 0) return n; + for (let e = t; e < i.length; ++e) { + const t = Qg(i[e], r); + if (t.altAudio && t.subtitle) { + n = e; + break + } + } + return n + } + + function jg(t, e, i, r, n, s, a) { + const o = i.preferredMediaOptions[gu.Variant].filter(e => e.iframes === t); + if (!o.length) return { + variantMediaOption: Lu.mediaOptionId, + holdOffDuration: 0, + lowestCandidate: null + }; + let l = 0; + const d = i.nextMinAutoOptionId; + if (d !== Lu.mediaOptionId) { + const t = o.findIndex(e => e.mediaOptionId === d); + 0 <= t && (l = t) + } + if (l = Hg(l, o, t, i), l < 0) return { + variantMediaOption: Lu.mediaOptionId, + holdOffDuration: 0, + lowestCandidate: null + }; + let u = o.length - 1; + const c = i.nextMaxAutoOptionId; + if (c !== Lu.mediaOptionId) { + const t = o.findIndex(e => e.mediaOptionId === c); + 0 <= t && (u = t) + } + var h = i.variantMediaOptionById(r.mediaOptionId), + p = r.mediaOptionDetails, + f = (null == h ? void 0 : h.iframes) !== t ? 0 : qg(n, e.maxBufferHole); + let m, g; + if (t) { + const t = e.desiredIframeFPS; + g = p ? p.targetduration / t : 0, g = Math.max(1 / t, g) + } else g = p ? p.targetduration : 0; + h = e.abrBandWidthUpFactor, p = e.abrBandWidthFactor; + return m = Wg(o, g, l, u, f, t, s.getCombinedEstimate(), s.bandwidthStatus, p, h, e, i, r, n, a), m.variantMediaOption === Lu.mediaOptionId && (m = Wg(o, g, l, u, f + Vg(g, e.maxStarvationDelay), t, s.getCombinedEstimate(), s.bandwidthStatus, p, h, e, i, r, n, a), m.variantMediaOption === Lu.mediaOptionId && 0 <= l && (m.variantMediaOption = o[l].mediaOptionId, m.alternates = t ? null : Qg(o[l], i))), m + } + + function Qg(e, t) { + var i = t.enabledMediaOptionKeys, + r = i[gu.AltAudio], + r = _u(r) ? t.mediaOptionListQueries[gu.AltAudio].getMatchingAlternate(r.mediaOptionId, e) : Lu, + i = i[gu.Subtitle]; + return { + altAudio: r, + subtitle: _u(i) ? t.mediaOptionListQueries[gu.Subtitle].getMatchingAlternate(i.mediaOptionId, e) : Lu + } + } + + function Wg(i, r, n, e, s, a, o, l, t, d, u, c, h, p, f) { + "bandwidth-history-controller" !== u.abrBandwidthEstimator && f.warn(`Unsupported configuration: ${u.abrBandwidthEstimator} for ABR bandwidth estimator`); + const m = l.bandwidthSampleCount, + g = c.abrStatus, + y = p.maxBufferSize, + v = u.minTargetDurations || 1, + S = c.mediaOptionListQueries[gu.Variant].mediaOptionListInfo.hasScore; + if (!i.length) return { + variantMediaOption: Lu.mediaOptionId, + holdOffDuration: -1, + lowestCandidate: null + }; + const b = c.enabledMediaOptionIdByType(gu.Variant), + T = c.variantMediaOptionById(b), + E = null != i.find(e => e.mediaOptionId === b), + I = T && T.iframes === a, + w = T && I ? T.score : void 0, + A = T && I ? T.frameRate : void 0, + O = T && I ? T.height : void 0, + k = I ? qg(p, u.maxBufferHole) : 0; + e = Math.max(0, Math.min(i.length - 1, e)), n = Math.max(0, Math.min(i.length - 1, n)); + var C = h.mediaOptionDetailsEntityRecord, + D = Gg(o.avgBandwidth, d, t, m); + let M; + for (let t = e; t >= n; t--) { + const n = i[t]; + let e = n.mediaOptionId; + const u = n.score, + h = C && C[e] ? C[e].mediaOptionDetails : void 0, + p = C && C[e] ? C[e].lastUpdateMillis : null, + f = h ? h.totalduration / h.fragments.length : r, + B = null != T && n.bitrate > T.bitrate, + m = null != T && n.bitrate < T.bitrate, + U = !(null != A && (B && n.frameRate < A || m && n.frameRate > A)), + $ = !(B && null != O && O > n.height), + V = !(m && (n.bitrate === T.bitrate - 1 || n.bitrate === T.bitrate + 1)), + K = !(S && B && null != w && (u < w || u === w && T && n.bitrate >= T.bitrate)), + q = n.iframes === a; + if (ne(f) && q && U && $ && V && K) { + var { + adjustedbw: x, + bitrate: P, + fetchDuration: R, + rejectLevelDueToPeakBW: L, + canFitMultipleSegments: _, + requireAlternates: N, + alternates: F + } = function(e, t, i, r, n, s, a, o, l, d, u, c) { + var h = n ? a.bwUp : a.bwDown, + n = e.bitrate, + a = t ? t.totalduration / t.fragments.length : o, + s = zg(e, t, o, h, ne(s.avgPlaylistLoadTimeMs) ? s.avgPlaylistLoadTimeMs : s.avgLatencyMs, d), + d = e.bandwidth, + i = n < h && h < d && i <= 2 * a, + l = r * ((d || n || 0) * ((null == t ? void 0 : t.targetduration) || a)) / 8 <= l; + let p = null; + u = !u; + return u && (p = Qg(e, c), p.altAudio && p.subtitle || (p = null)), { + adjustedbw: h, + bitrate: n, + fetchDuration: s, + rejectLevelDueToPeakBW: i, + canFitMultipleSegments: l, + requireAlternates: u, + alternates: p + } + }(n, h, k, v, B, o, D, r, y, p, a, c); + if (N && Boolean(F) && (M = e), P < x && _ && !L && (!N || Boolean(F)) && (a || !R || R < s)) { + if (L = x, N = g, x = (x = l).instantBw, (N.fragDownloadSlow || N.fragDownloadTooSlow || ne(x) && x < L) && E && I) + if (k <= 2 * f && B) e = b; + else if (B && d * l.instantBw < P) continue; + return { + variantMediaOption: e, + holdOffDuration: R, + alternates: F, + lowestCandidate: M + } + } + } + } + return { + variantMediaOption: Lu.mediaOptionId, + holdOffDuration: -1, + lowestCandidate: M + } + } + + function Gg(e, t, i, r) { + let n, s; + return 4 <= r ? (n = e * t, s = e * i) : n = s = e / 1.8, { + bwUp: n, + bwDown: s + } + } + + function zg(e, t, i, r, n, s) { + let a = e.bitrate * (t ? t.totalduration / t.fragments.length : i) / r; + return null == t || !t.liveOrEvent || t.ptsKnown && !Yg(t.totalduration, n, s) || (a *= 2), ne(n) && (!ne(s) || null != t && t.liveOrEvent) && (a += n / 1e3), a + } + + function Xg(t, e) { + let i = 1 / 0; + if (t === Lu.mediaOptionId) return i; + var r = e.find(e => e.mediaOptionId === t); + if (!r) return 1 / 0; + const n = r.iframes, + s = r.bitrate, + a = r.frameRate, + o = e.find(e => e.iframes === n && (void 0 === a || e.frameRate >= a) && e.bitrate > s); + return o && (i = o.bitrate), i + } + + function Yg(e, t, i) { + return t = ne(t) ? t : 0, !ne(i) || performance.now() - i + t > 1e3 * e + } + + function Jg(e, t) { + return (null == e ? void 0 : e.fragDownloadSlow) === (null == t ? void 0 : t.fragDownloadSlow) && e.fragDownloadTooSlow === (null == t ? void 0 : t.fragDownloadTooSlow) + } + + function Zg(e) { + return "loading" === (null == e ? void 0 : e.state) && ne(null === (e = e.bwSample) || void 0 === e ? void 0 : e.trequest) + } + const ey = 2e3; + + function ty(e, t, i, r) { + let { + fragDownloadSlow: n, + fragDownloadTooSlow: s + } = t; + var a = i.variantMediaOptionById(e.mediaOptionId).bitrate, + t = e.bwSample; + r = r.child($g); + i = t.total || Math.max(t.loaded, Math.round(e.duration * a / 8)), a = performance.now() - t.tfirst, i = t.loaded * e.duration * 1e3 / i; + return a >= ey && 1e3 <= a - i && (n || r.warn(`flow indicates low bandwidth, after time/duration behind real time: ${a}/${a-i}`), n = !0), a >= 1e3 * e.duration && (s || r.warn(`too much time spent downloading fragment, likely to switch down ${a} > ${1e3*e.duration}`), s = !0), { + fragDownloadSlow: n, + fragDownloadTooSlow: s + } + } + + function iy(e, t, i, r, n) { + var s; + const a = n.logger.child($g), + o = r.isIframeRate, + l = i.mediaOptionListQueries[gu.Variant].preferredMediaOptionList, + d = i.enabledMediaOptionKeys[gu.Variant]; + let u = e; + if (u !== Mm.None || l.some(e => e.mediaOptionId === d.mediaOptionId) || (u = Mm.PreferredListChanged), u !== Mm.None && !(o && u !== Mm.IframeModeChange && r.getBufferedSegmentsByType(yu.Variant).filter(e => e.frag.iframe).length < t.minFramesBeforeSwitchingLevel)) { + o && u === Mm.IframeModeChange && n.setEnabledVariantMediaOptionIdBeforeTrickplaySwitch(i.itemId, d.mediaOptionId); + const h = Zf(i.itemId), + p = Dg(d), + f = [Lu, Lu, Lu]; + if (!o && e === Mm.IframeModeChange) { + const e = function(e, t, i, r) { + const n = i.mediaOptionListQueries[gu.Variant].preferredMediaOptionList, + s = t.targetStartupMs, + a = { + avgPlaylistParseTimeMs: 0, + avgPlaylistLoadTimeMs: 0 + }, + o = r.getFragEstimate(), + l = { + avgBufferCreateMs: 0, + avgInitFragAppendMs: 0, + avgDataFragAppendMs: 0 + }, + d = o.maxDurationSec, + u = { + avgLatencyMs: 0, + avgBandwidth: r.getBandwidthEstimate().avgBandwidth + }, + c = { + targetDuration: d, + targetStartupMs: s, + metricsOverride: { + maxValidHeight: 0, + maxValidBitrate: 0, + maxPreferredBitrate: 0 + } + }, + h = n.filter(e => !e.iframes && (!e.width || !e.height || e.width * e.height <= 2488320)); + let p = e; + 0 < h.length && (p = h[0].mediaOptionId); + e = h.filter(e => Ug(e, u, c, a, o, l)); + return 0 < e.length && (p = e[e.length - 1].mediaOptionId), p + }(i.enabledVariantMediaOptionIdBeforeTrickplaySwitch, t, i, h); + n.setNextMaxAutoOptionId(i.itemId, e), n.setEnabledVariantMediaOptionIdBeforeTrickplaySwitch(i.itemId, void 0) + } + var c = function(e, t, i, r, n, s, a) { + let o = t.nextMaxAutoOptionId; + if (o === Lu.mediaOptionId || Kg(s.getBandwidthEstimate())) return l = e, d = t, u = r, e = n, r = s, s = a.child({ + name: "abr" + }), a = e.isIframeRate, d.enabledMediaOptionIdByType(gu.Variant), jg(a, l, d, u, e, r, s); + if (n.isIframeRate) return { + variantMediaOption: o, + holdOffDuration: 0, + lowestCandidate: null + }; { + const c = t.variantMediaOptionById(o), + h = t.enabledAlternateMediaOptionByType(gu.Subtitle), + n = t.enabledAlternateMediaOptionByType(gu.AltAudio), + p = null == n ? void 0 : n.persistentID, + f = null == h ? void 0 : h.persistentID, + m = !t.preferHDR, + g = i.getBestMediaOptionTupleFromVariantAndPersistentId(t, c, p, f, void 0, [], m, !1, !1); + return t.isValidMediaOptionTuple(g) ? (o = g[gu.Variant].mediaOptionId, { + variantMediaOption: o, + holdOffDuration: 0, + alternates: { + altAudio: g[gu.AltAudio], + subtitle: g[gu.Subtitle] + }, + lowestCandidate: null + }) : { + variantMediaOption: t.enabledMediaOptionKeys[gu.Variant].mediaOptionId, + holdOffDuration: 0, + lowestCandidate: null + } + } + var l, d, u + }(t, i, n, p, r, h, a); + if (o || e !== Mm.IframeModeChange || n.setNextMaxAutoOptionId(i.itemId, Lu.mediaOptionId), c.variantMediaOption !== d.mediaOptionId) { + f[gu.Variant] = { + itemId: i.itemId, + mediaOptionId: c.variantMediaOption + }; + for (const e of [gu.AltAudio, gu.Subtitle]) { + const t = i.enabledMediaOptionIdByType(e); + if (t !== Lu.mediaOptionId) { + const r = e === gu.AltAudio ? null === (s = c.alternates) || void 0 === s ? void 0 : s.altAudio : null === (s = c.alternates) || void 0 === s ? void 0 : s.subtitle; + f[e] = r || { + itemId: i.itemId, + mediaOptionId: t + } + } + } + return n.setEnabledMediaOptions(i.itemId, f), 1 + } + } + } + const ry = { + name: "iframes" + }; + (A = xm = xm || {})[A.DISABLED = 0] = "DISABLED", A[A.ERRORED = 1] = "ERRORED", A[A.SUCCESS = 2] = "SUCCESS"; + const ny = new fl({}, { + name: "item-queue", + producerFn: su, + idKey: "itemId", + resettable: !0 + }), + sy = new class extends kl {}(ny); + class ay { + constructor() { + this.firstItem = !0, this.playingEntity = null, this.loadingEntity = null + } + static createItem(e, t, i = NaN, r, n) { + const s = new Date, + a = `${s.getHours()}:${s.getMinutes()}:${s.getSeconds()}`; + Qe(); + var o = function(e) { + e = cu.parseURL(e).fragment.substr(1); + if (0 === e.length) return null; + const t = new URLSearchParams(e); + if (!t.has("t")) return null; + e = Number(t.get("t")); + return ne(e) ? e : null + }(t); + if (ne(o)) i = o; + else { + const e = mg(); + ne(null == e ? void 0 : e.startPosition) && (i = e.startPosition) + } + return { + itemId: `${e}_${a}`, + name: e, + url: t, + serviceName: n, + createTime: a, + initialSeekTime: i, + itemStartOffset: 0, + platformInfo: r, + config: {} + } + } + get activeItemById$() { + return sy.selectActiveId().pipe(hr(e => sy.getActive())) + } + get removedItems$() { + return sy.selectEntityAction(Eo.Remove).pipe(hr(e => e)) + } + get activeItem() { + return sy.getActive() + } + get queueItems$() { + return sy.selectAll().pipe(hr(e => null != e ? e : [])) + } + get isFirstItem() { + return this.firstItem + } + get playingItem() { + return this.playingEntity + } + get loadingItem() { + return this.loadingEntity + } + addQueueItem(e, t, i, r, n, s) { + sy.getCount(); + const a = ay.createItem(e, t, i, r, s); + null != this.playingEntity && (a.initialSeekTime = void 0), n && (a.itemStartOffset = n, this.firstItem = !1, this.playingEntity = this.activeItem, this.loadingEntity = a), Do(`queue.add.item: ${e}`), al(() => { + ny.add(a), ny.setActive(a.itemId) + }) + } + updatePlayingItemId() { + this.playingEntity = this.loadingEntity, this.loadingEntity = null, this.clearAllButActive() + } + resetLoadingItem() { + this.removeQueueItem(this.loadingEntity.itemId), this.loadingEntity = null, al(() => { + ny.setActive(this.playingEntity.itemId) + }) + } + isPreloading() { + return null !== this.playingEntity && null !== this.loadingEntity + } + setQueueItem(t, i, r, n, s) { + Do("queue.set.item"), this.loadingEntity = null, al(() => { + ny.reset(); + var e = ay.createItem(t, i, r, n, s); + ny.add(e), ny.setActive(e.itemId) + }), this.playingEntity = this.activeItem + } + removeQueueItem(e) { + ny.remove(e) + } + clearQueue() { + ny.reset() + } + clearAllButActive() { + var e; + const t = null === (e = this.activeItem) || void 0 === e ? void 0 : e.itemId; + al(() => { + sy.getAll().forEach(e => { + e.itemId !== t && ny.remove(e.itemId) + }) + }) + } + set earlyAudioSelection(t) { + ny.updateActive(e => { + e.earlySelection || (e.earlySelection = {}), e.earlySelection.audioPersistentId = t + }) + } + get earlyAudioSelection() { + var e; + return null === (e = this.activeItem.earlySelection) || void 0 === e ? void 0 : e.audioPersistentId + } + set earlySubtitleSelection(t) { + ny.updateActive(e => { + e.earlySelection || (e.earlySelection = {}), e.earlySelection.subtitlePersistentId = t + }) + } + get earlySubtitleSelection() { + var e; + return null === (e = this.activeItem.earlySelection) || void 0 === e ? void 0 : e.subtitlePersistentId + } + } + + function oy(e, t, i, r, n, s) { + return ng(e, 0, Jm({ + errorAction: Cm.RemoveAlternatePermanently, + errorActionFlags: 0 + }, !1, e.response.code, i, t, s, n), s, n, t, i).pipe(Vn(e => { + throw !1 === e.fatal && r.resetMediaSource(), e + })) + } + class ly { + constructor(e, t, i, r, n, s) { + this.logger = e, this._rootPlaylistService = t, this._rootQuery = i, this._mediaQuery = r, this._iframeMachine = n, this._anchorMSNs = [NaN, NaN], this._avDetails = [null, null], this.logger = e.child({ + name: "fpicker" + }), this._discoSeqNum = NaN, this.lookUpTolerance = Math.max(s.maxBufferHole, s.maxFragLookUpTolerance), this.firstAudioMustOverlapVideoStart = s.firstAudioMustOverlapVideoStart, this.lookUpToleranceAlt = s.firstAudioMustOverlapVideoStart ? 0 : s.maxFragLookUpTolerance + } + destroy() { + this._anchorMSNs = [NaN, NaN], this._avDetails = [null, null], this._rootQuery = null, this._mediaQuery = null, this._rootPlaylistService = null, this._iframeMachine = null + } + get discoSeqNum() { + return this._discoSeqNum + } + get _discoSeqNum() { + return this._rootQuery.discoSeqNum + } + set _discoSeqNum(e) { + this._rootPlaylistService.setDiscoSeqNum(this._rootQuery.itemId, e) + } + get anchorMSNs() { + return this._anchorMSNs + } + _resolvePosition(e, t, i) { + let r = e; + var t = this._avDetails[t]; + if ((null == t ? void 0 : t.mediaOptionId) !== (null == i ? void 0 : i.mediaOptionId) && i.liveOrEvent && !1 === i.ptsKnown && (!t || Math.max(t.startSN, i.startSN) > Math.min(t.endSN, i.endSN))) { + const e = 3 * i.targetduration, + n = (null === (t = i.fragments[0]) || void 0 === t ? void 0 : t.start) + i.totalduration; + r = Math.max(0, n - e) + } + return r + } + getDiscoSeqNumForTime(e, t) { + return this._mediaQuery.isIframeRate && e.iframesOnly ? Qu.discoSeqNumForTime(e.fragments, t) : (r = t, null == (e = null !== (e = Tg(e, e => { + var t = 0 < e.duration, + i = e.start + e.duration, + e = r < i || r - i < 1 && e.isLastFragment; + return t && e + })) && void 0 !== e ? e : null) ? void 0 : e.mediaFragment.discoSeqNum); + var r + } + _updateAnchorByPosition(e, t) { + let i = NaN; + const r = t[yu.Variant]; + let n = e; + if (r) { + const t = r.fragments; + if (n = this._resolvePosition(e, yu.Variant, r), i = this.getDiscoSeqNumForTime(r, n), !ne(i)) { + const r = t[0], + s = t[t.length - 1], + a = null == r ? void 0 : r.start, + o = (null == s ? void 0 : s.start) + (null == s ? void 0 : s.duration); + this.logger.warn(`${e.toFixed(3)} out of range [${null==a?void 0:a.toFixed(3)},${null==o?void 0:o.toFixed(3)}]`), n <= a ? i = r.discoSeqNum : n >= o ? i = s.discoSeqNum : this.logger.warn(`Unable to determine newCC. fragFirst: ${JSON.stringify(r)} fragLast: ${JSON.stringify(s)}`), ne(i) || this.logger.warn(`Unable to determine newCC. fragFirst: ${JSON.stringify(r)} fragLast: ${JSON.stringify(s)}`) + } + } else this.logger.warn("No variant details for anchoring"); + return this._updateAnchor(i, t), n + } + _updateAnchor(e, s) { + const a = e !== this._discoSeqNum; + a && (this._discoSeqNum = e), Bu.forEach(e => { + const t = this._avDetails[e], + i = s[e], + r = (null == t ? void 0 : t.mediaOptionId) !== (null == i ? void 0 : i.mediaOptionId); + if (a || r) this._updateAnchorForType($u(e), i); + else if (i) { + const { + mediaOptionId: s, + ptsKnown: a, + dateMediaTimePairs: t, + startSN: r, + endSN: n + } = i; + this._avDetails[e] = { + mediaOptionId: s, + ptsKnown: a, + dateMediaTimePairs: t, + startSN: r, + endSN: n + } + } + }) + } + getNextFragments(i, r, n) { + const { + position: s, + bufferInfoTuple: e, + switchContexts: a + } = i; + let t = e.map((e, t) => dy(s, r[t], a[t], null == e ? void 0 : e.buffered, t === gu.AltAudio ? this.lookUpToleranceAlt : this.lookUpTolerance)).reduce((e, t) => Math.min(t, e), Number.POSITIVE_INFINITY); + if (ne(i.discoSeqNum)) { + const s = r.reduce((e, t) => { + if (!t) return e; + t = Qu.getTimeRangeForCC(t.fragments, i.discoSeqNum, n); + return [Math.max(e[0], t[0]), Math.min(e[1], t[1])] + }, [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY]); + t = Math.min(Math.max(t, s[0]), s[1]) + } + return i.position = this._updateAnchorByPosition(t, r), this._getNextFragmentsInternal(i, r) + } + _getNextFragmentsInternal(r, n) { + const s = [null, null]; + let a; + n.forEach((e, t) => { + var i; + this.firstAudioMustOverlapVideoStart && t === gu.AltAudio && this._mediaQuery.seeking && null !== (i = s[gu.Variant]) && void 0 !== i && i.foundFrag && (a = r.position, r.position = s[gu.Variant].foundFrag.mediaFragment.start), s[t] = this._getNextFragmentForType(r, n, t) + }); + var e = s[yu.Variant], + t = s[yu.AltAudio], + i = null === (o = null == e ? void 0 : e.foundFrag) || void 0 === o ? void 0 : o.mediaFragment, + o = null === (o = null == t ? void 0 : t.foundFrag) || void 0 === o ? void 0 : o.mediaFragment; + if (i && o && (o.start > i.start + i.duration ? (this.logger.warn("Audio too far ahead"), s[yu.AltAudio] = ly.noopResult) : i.start > o.start + o.duration && !this._mediaQuery.isIframeRate && (this.logger.warn("Video too far ahead"), s[yu.Variant] = ly.noopResult)), !isFinite(null == e ? void 0 : e.nextDisco) || null != t && !ne(t.nextDisco)) return s; { + const l = s[yu.Variant].nextDisco; + return this._updateAnchor(l, n), ne(a) && (r.position = a, a = NaN), this._getNextFragmentsInternal(r, n) + } + } + _getNextFragmentForType(e, t, i) { + var { + position: r, + bufferInfoTuple: n, + switchContexts: s + } = e, a = t[i], o = null !== (d = null === (c = n[i]) || void 0 === c ? void 0 : c.buffered) && void 0 !== d ? d : { + start: r, + end: r, + len: 0 + }, l = this._mediaQuery.getBufferedSegmentsByType(i), d = null !== (c = null === (e = s[i]) || void 0 === e ? void 0 : e.userInitiated) && void 0 !== c && c, u = dy(r, a, s[i], o, this.lookUpTolerance); + if (!a) return null; + var { + highWaterLevelSeconds: e, + lowWaterLevelSeconds: c + } = this._mediaQuery.bufferMonitorInfo, r = o.len; + if (!d && e <= r) return ly.noopResult; + var e = i === yu.Variant ? yu.AltAudio : yu.Variant, + n = null === (n = n[e]) || void 0 === n ? void 0 : n.buffered, + e = null !== (e = null === (e = s[e]) || void 0 === e ? void 0 : e.userInitiated) && void 0 !== e && e; + let h = !1; + i === yu.Variant && c <= r && 1 < this._mediaQuery.expectedSbCount && null != n && n.end < o.end && (e || n.end - n.start < c) && (h = !0); + let p, f = null, + m = NaN; + if (this._mediaQuery.isIframeRate && i === yu.Variant && a.iframesOnly) { + const g = function(e, t, i) { + e = i.nextFragment(a.fragments, (null == e ? void 0 : e.fragments) || [], t, u); + if (!e) return null; + var { + frag: t, + newMediaRootTime: e + } = e; + return { + foundFrag: { + timelineOffset: t.iframeMediaStart, + mediaFragment: t + }, + nextDisco: NaN, + newMediaRootTime: e + } + }(t[yu.AltAudio], this._mediaQuery.desiredRate, this._iframeMachine); + if (g) { + ({ + foundFrag: f, + nextDisco: m, + newMediaRootTime: p + } = g); + const i = f.mediaFragment; + i.discoSeqNum !== this._discoSeqNum && this._updateAnchor(i.discoSeqNum, t) + } + } else { + const g = this._anchorMSNs[i]; + ({ + foundFrag: f, + nextDisco: m, + newMediaRootTime: p + } = Ig(u, this._discoSeqNum, g, a, l)) + } + return h && this._rootQuery.getInitPTS(null == f ? void 0 : f.mediaFragment.discoSeqNum) ? ly.noopResult : { + foundFrag: f, + nextDisco: m, + newMediaRootTime: p + } + } + _updateAnchorForType(e, t) { + var i, r, n, s, a; + if (!t) return this._anchorMSNs[e] = NaN, void(this._avDetails[e] = null); + ne(this._discoSeqNum) ? (a = this._discoSeqNum, a = null !== (s = null == (n = (r = t.fragments, i = a, r.find(e => e.discoSeqNum === i))) ? void 0 : n.mediaSeqNum) && void 0 !== s ? s : t.startSN, this._anchorMSNs[e] = a, { + mediaOptionId: r, + ptsKnown: n, + dateMediaTimePairs: s, + startSN: a, + endSN: t + } = t, this._avDetails[e] = { + mediaOptionId: r, + ptsKnown: n, + dateMediaTimePairs: s, + startSN: a, + endSN: t + }) : this.logger.warn("Trying to anchor with non-finite discoSeqNum") + } + } + + function dy(e, t, i, r, n) { + r = null != r ? r : { + start: e, + end: e, + len: 0 + }; + i = null !== (i = null == i ? void 0 : i.userInitiated) && void 0 !== i && i, n = null != t && t.iframesOnly ? 0 : n; + return i || 0 === r.len ? e : r.end + n + } + ly.noopResult = { + foundFrag: null, + nextDisco: NaN + }; + const uy = { + name: "avpipe" + }; + + function cy(r) { + const { + config: o, + rootPlaylistService: l, + rootPlaylistQuery: d, + mediaSink: e, + gaplessInstance: t + } = r, u = e.mediaQuery, i = ed(Bu.map(e => d.enabledMediaOptionSwitchForType$(e).pipe(Za(e => {})))).pipe(La(e => { + if (!_u({ + itemId: d.itemId, + mediaOptionId: e[gu.Variant].toId + })) throw new V(!0, `No valid variant enabled id:${e[gu.Variant].toId}`, $.NoValidAlternates); + e = e.map(({ + fromId: e, + toId: t + }, i) => function(t, i, r, n, s) { + var a, o; + const { + rootPlaylistQuery: l, + rootPlaylistService: d, + mediaSink: u, + mediaParser: c, + config: h, + iframeMachine: p + } = t, f = u.mediaQuery; + if (!n || !s || n === s && (r === gu.AltAudio || !p.isStarted)) return Wu; + switch (r) { + case gu.Variant: { + n !== s && c.reset(gu.Variant); + const t = $u(r), + g = l.variantMediaOptionById(n), + y = l.variantMediaOptionById(s), + v = l.itemId; + if (null == y || null == g) return Wu; + var e = !y.iframes && p.isStarted; + if (g.iframes !== y.iframes || e) return u.toggleTrickPlaybackMode(y.iframes), e && (ne(u.mediaQuery.postFlushSeek) || (u.postFlushSeek = p.iframeClockTimeSeconds), p.stop()), u.pause(), (e ? u.flushAll(0, 1 / 0, !0) : u.flushData(t, 0, 1 / 0, !0)).pipe(Za(() => { + var e = u.mediaQuery.postFlushSeek; + ne(e) && d.setPendingSeek(v, e) + })); + if (!h.allowFastSwitchUp || y.iframes) return Wu; + var m = Dg(g).mediaOptionDetails; + if (null != m && null != y && g.bitrate < y.bitrate) { + const r = m.targetduration, + n = Dg(y), + s = n.mediaOptionDetails, + d = n.mediaOptionDetailsEntity.lastUpdateMillis, + c = f.getCurrentWaterLevelByType(t, h.maxBufferHole), + p = function(e, t, i, r, n, s, a, o) { + if (n.nextMaxAutoOptionId !== Lu.mediaOptionId && !Kg(s.getBandwidthEstimate())) return Number.POSITIVE_INFINITY; + a = Gg(s.getBandwidthEstimate().avgBandwidth, a.abrBandWidthUpFactor, a.abrBandWidthFactor, s.bandwidthStatus.bandwidthSampleCount), s = ne(s.getPlaylistEstimate().avgPlaylistLoadTimeMs) ? s.getPlaylistEstimate().avgPlaylistLoadTimeMs : s.getBandwidthEstimate().avgLatencyMs, a = t.bitrate > e.bitrate ? a.bwUp : a.bwDown; + return null == i || !i.liveOrEvent || i.ptsKnown && !Yg(i.totalduration, s, o) ? zg(t, i, r, a, s, o) : Number.POSITIVE_INFINITY + }(g, y, s, r, l.abrStatus, i, h, d) + h.maxStarvationDelay, + S = f.currentTime + p, + b = null === (o = null === (a = f.sourceBufferEntityByType(t)) || void 0 === a ? void 0 : a.bufferedSegments) || void 0 === o ? void 0 : o.find(e => e.startPTS >= S); + let e; + if (b) { + const t = b.endPTS - b.startPTS; + e = b.startPTS + Math.min(Math.max(t - h.maxFragLookUpTolerance, .5 * t), .75 * t) + } + if (ne(e) && c >= p) return u.flushData(t, e, 1 / 0) + } + } + break; + case gu.AltAudio: + e = l, m = s, o = "Nah" === (a = n) ? null : e.alternateMediaOptionById(gu.AltAudio, a), o = Boolean(o && o.url), m = "Nah" === a ? null : e.alternateMediaOptionById(gu.AltAudio, m), m = Boolean(m && m.url), o && !m && (d.setEnabledMediaOptionSwitchContextByType(l.itemId, gu.AltAudio, s, void 0), u.resetMediaSource(f.currentTime)), c.reset(gu.AltAudio) + } + return Wu + }(r, n, i, e, t)); + return Jr($i(!0), en(e).pipe(Zs(!1))) + }), tc("mediaOptionSwitch.audiovideo.out")), n = Zf(d.itemId), s = r.logger.child(uy), a = new ly(s, l, d, u, r.iframeMachine, o); + return ed([d.anchorTime$.pipe(tc("anchorTime.audiovideo.in")), i]).pipe(La(([i, e]) => e ? Ii : u.needData$(o.maxBufferHole, t.inGaplessMode).pipe(hr(e => { + var t = [d.enabledMediaOptionSwitchContexts[gu.Variant], d.enabledMediaOptionSwitchContexts[gu.AltAudio]]; + return u.getSourceBufferInfoAction(e, i, t, o.maxBufferHole) + }), _s(e => e ? fn($i(e).pipe(hy(r, a), my(r)), Gu(function(e) { + const { + mediaSink: t, + rootPlaylistQuery: i, + rootPlaylistService: r + } = e, n = t.mediaQuery, s = e.logger.child($g); + return an((a = i, o = s, ed([n.fellBelowLowWater$, a.getInFlightFragByType$(gu.Variant)]).pipe(La(e => { + var [, t] = e; + if (!Zg(t)) return Ii; + const i = performance.now() - t.bwSample.trequest, + r = ey - i, + n = 1e3 * t.duration - i, + s = [Wu]; + return 0 < r && s.push(bn(r)), 0 < n && s.push(bn(n)), an(...s).pipe(Zs(e)) + }), sa((e, [t, i]) => { + const r = Object.assign({}, e); + return t && (r.fragDownloadSlow = !0), ty(i, r, a, o) + }, { + fragDownloadSlow: !1, + fragDownloadTooSlow: !1 + }), Ra({ + fragDownloadSlow: !1, + fragDownloadTooSlow: !1 + }), Is(Jg))), function(r) { + const s = r.mediaSink.mediaQuery, + { + rootPlaylistQuery: e, + config: a + } = r; + return s.desiredRate$.pipe(La(t => 0 === t ? Ii : ed([e.getInFlightFragByType$(gu.Variant), e.mediaOptionListQueries[gu.Variant].preferredMediaOptionList$.pipe(hr(e => e.filter(Wm.bind(null, Wp(t)))))])), ao(100), La(e => { + const [t, i] = e; + if (!Zg(t) || i.findIndex(e => e.mediaOptionId === t.mediaOptionId) <= 0) return Ii; + var r = performance.now() - t.bwSample.trequest, + n = Vg(t.duration, a.maxStarvationDelay), + n = Math.min(1e3 * n, 500 * t.duration / s.playbackRate); + return bn(Math.max(0, n - r), 100).pipe(Zs(e)) + })).pipe(sa((e, [t, i]) => function(t, i, r, e) { + let { + fragDownloadSlow: n, + fragDownloadTooSlow: s + } = t; + const { + config: a, + rootPlaylistService: o, + rootPlaylistQuery: l, + mediaSink: d, + statsService: u, + mediaLibraryService: c + } = e, h = e.logger.child($g), p = d.mediaQuery; + if (p.paused) return t; + e = i.bwSample; + if (!ne(e.tfirst)) return t; + const f = performance.now(), + m = f - e.trequest, + g = Vg(i.duration, a.maxStarvationDelay), + y = gu.Variant, + v = i.mediaOptionId, + S = l.variantMediaOptionById(v), + b = c.getQueryForOption(S), + T = S.bitrate, + E = Math.max(1, 8e3 * e.loaded / m), + I = 8 * ((ne(e.total) ? e.total : Math.max(e.loaded, Math.round(i.duration * T / 8))) - e.loaded) / E, + w = qg(p, a.maxBufferHole); + let A; + if (ne(w) && 0 < w && !ne(null === (O = p.seekTo) || void 0 === O ? void 0 : O.pos)) A = w; + else { + const N = m / 1e3; + A = N < g ? g - N : g + } + var O = n; + ({ + fragDownloadSlow: n, + fragDownloadTooSlow: s + } = ty(i, t, l, h)); + t = 2 * ((null === (t = b.mediaOptionDetails) || void 0 === t ? void 0 : t.targetduration) || i.duration); + if (!(w <= t && (I >= A || n))) return fg().getQuery().extendMaxTTFB && fg().setExtendMaxTTFB(0), { + fragDownloadSlow: n, + fragDownloadTooSlow: s + }; + O || h.warn(`likely to stall ${ae({maxTimeToLoadSec:A,minSwitchDuration:t,stats:e,elapsedMs:m,remainingTimeSec:I,instantBw:E,bufferAheadSec:w,fragDownloadSlow:n})}`), n = !0, fg().getQuery().extendMaxTTFB || fg().setExtendMaxTTFB(6e5); + let k; + const C = i.itemId, + D = u.getQueryForItem(C), + M = D.getCombinedEstimate(), + x = Object.assign(Object.assign({}, M), { + avgBandwidth: E + }), + P = D.bandwidthStatus, + R = S.iframes, + L = I >= A && !R, + _ = Hg(0, r, R, l); + if (_ < 0) return { + fragDownloadSlow: n, + fragDownloadTooSlow: s + }; + t = Math.max(_, r.findIndex(e => e && e.mediaOptionId === S.mediaOptionId)); + if (L) { + let e = Wg(r, i.duration, _, t, A, R, x, P, 1, 1, a, l, b, p, h); + const F = Lu.mediaOptionId; + k = e.variantMediaOption !== F || (e = Wg(r, i.duration, _, t, I, R, x, P, 1, 1, a, l, b, p, h)).variantMediaOption !== F ? e.variantMediaOption : e.lowestCandidate + } else { + const N = Hg(0, r.slice(_, t).reverse(), R, l), + i = t - 1 - N; + (0 <= N || t === _) && (k = r[i].mediaOptionId) + } + if (null != k && k !== l.abrStatus.nextMaxAutoOptionId && o.setNextMaxAutoOptionId(C, k), L) throw h.warn(`loading too slow, abort fragment loading and switch to level ${k}`), u.setBandwidthSample(Object.assign(Object.assign({}, e), { + tfirst: e.tfirst || f, + tload: e.tload || f, + complete: !0, + mediaOptionType: y + })), s = !0, new fc({ + mediaOptionType: y, + mediaOptionId: v + }, k, $.FragmentAbortError); + return { + fragDownloadSlow: n, + fragDownloadTooSlow: s + } + }(e, t, i, r), { + fragDownloadSlow: !1, + fragDownloadTooSlow: !1 + }), Ra({ + fragDownloadSlow: !1, + fragDownloadTooSlow: !1 + }), Is(Jg)) + }(e)).pipe(Ra({ + fragDownloadSlow: !1, + fragDownloadTooSlow: !1 + }), sa((e, t) => ({ + fragDownloadSlow: e.fragDownloadSlow || t.fragDownloadSlow, + fragDownloadTooSlow: e.fragDownloadTooSlow || t.fragDownloadTooSlow + })), Is(Jg), hr(e => (r.setFragLoadSlow(i.itemId, e), !1)), Vn(e => { + if (e instanceof fc) { + const e = { + fragDownloadSlow: !0, + fragDownloadTooSlow: !0 + }; + return r.setFragLoadSlow(i.itemId, e), $i(!0) + } + return Vi(e) + })); + var a, o + }(r), e => e)).pipe(Ds(1), Vs(() => { + Bu.forEach(e => { + l.updateInflightFrag(d.itemId, e, null, null, null) + }) + })) : Ii))), hr(() => { + if (!d.getEntity(d.itemId).manualMode) { + let e = Mm.None; + var i, r, n, s; + i = Af(), r = u, n = o, s = null == r ? void 0 : r.clientWidth, a = null == r ? void 0 : r.clientHeight, r = "object" == typeof window && window.devicePixelRatio ? window.devicePixelRatio : 1, a = s && a ? { + width: s * r, + height: a * r + } : void 0, r = (r = (null === (r = i.getQuery()) || void 0 === r ? void 0 : r.viewportInfo) || {}) && a && (r.width !== a.width || r.height !== a.height), n.useViewportSizeForLevelCap && r && (i.updateViewportInfo(a), 1) && (e = Mm.PreferredListChanged); + let t = !1; + var a = d.enabledVariantMediaOption; + ! function(e, t) { + const i = l.logger.child($g), + r = e.abrStatus, + n = r.fragDownloadSlow || r.fragDownloadTooSlow, + s = ne(null === (t = t.seekTo) || void 0 === t ? void 0 : t.pos); + return n && !r.fragDownloadTooSlow && s ? (i.warn("could be ignoring low bandwidth due to seek"), 0) : n + }(d, u) ? u.playbackStarted && function(e, t) { + const i = Zf(t.itemId), + r = i.getBandwidthEstimate(), + n = t.abrStatus; + if (Kg(r)) { + var t = (null === (t = i.bandwidthStatus) || void 0 === t ? void 0 : t.bandwidthSampleCount) || 0, + t = Gg(r.avgBandwidth, e.abrBandWidthUpFactor, e.abrBandWidthFactor, t)["bwUp"]; + return t > n.highBWTrigger + } + }(o, d) && (e = Mm.HighBandwidth, l.setNextMinAutoOptionId(a.itemId, a.mediaOptionId)): (e = Mm.LowBandwidth, d.nextMaxAutoOptionId === Lu.mediaOptionId && (l.setNextMaxAutoOptionId(a.itemId, a.mediaOptionId), t = !0)), iy(e, o, d, u, l), t ? l.setNextMaxAutoOptionId(a.itemId, Lu.mediaOptionId) : e === Mm.HighBandwidth && l.setNextMinAutoOptionId(a.itemId, Lu.mediaOptionId) + } + }), Vs(() => {})) + } + const hy = (r, n) => e => { + const { + rootPlaylistQuery: t, + mediaSink: a + } = r, i = r.logger.child(uy); + return e.pipe(ji(tr), bo(t.enabledMediaOptionKeys$), La(([s, e]) => En(py(s, gu.Variant, r, e).pipe(Za(e => { + var e = e.detailsEntity; + if (!e.mediaOptionDetails.liveOrEvent || e.mediaOptionDetails.ptsKnown) { + const t = e.playlistDuration, + i = (null === (e = s.bufferInfoTuple[0]) || void 0 === e ? void 0 : e.buffered.end) || 0, + r = (null === (e = s.bufferInfoTuple[1]) || void 0 === e ? void 0 : e.buffered.end) || 0, + n = Math.max(i, r); + a.msDuration = ne(a.msDuration) ? Math.max(a.msDuration, t, n) : t + } + })), py(s, gu.AltAudio, r, e)).pipe(hr(e => ({ + action: s, + detailsAndContext: e + })))), La(({ + action: e, + detailsAndContext: t + }) => function t(n, s, a, i, d) { + var e; + const { + mediaSink: u, + iframeMachine: c, + rootPlaylistQuery: o + } = a, r = [d[gu.Variant].detailsEntity.mediaOptionDetails, null === (e = null === (e = d[gu.AltAudio]) || void 0 === e ? void 0 : e.detailsEntity) || void 0 === e ? void 0 : e.mediaOptionDetails]; + let l = s.getNextFragments(i, r, n); + const h = l.reduce((e, t) => Math.max(e, ne(null == t ? void 0 : t.newMediaRootTime) ? t.newMediaRootTime : -1 / 0), -1 / 0); + return ne(h) && (u.seekTo = h, l = [null, null]), l.every(e => null == (null == e ? void 0 : e.foundFrag)) ? $i(null) : En(...l.map((t, l) => { + if (t && null != t.foundFrag) { + const i = t.foundFrag["mediaFragment"], + r = _g(a, i.keyTagInfo, { + itemId: i.itemId, + mediaOptionId: i.mediaOptionId + }); + let e = Lg(a, l, t).pipe(Za(e => { + const t = e[1], + i = d[l].switchContext; + t.switchPosition = null == i ? void 0 : i.switchPosition; + const r = null !== (e = null == i ? void 0 : i.userInitiated) && void 0 !== e && e, + n = u["mediaQuery"], + { + desiredRate: s, + isIframeRate: a + } = n, + o = a && c.isStarted && s && s < 0 && s !== c.iframeRate; + (r || o) && (t.flushBeforeAppend = { + start: 0, + end: Number.POSITIVE_INFINITY + }) + })); + return e = l === gu.Variant ? e.pipe(Za(e => { + const t = function(t, i, r, n) { + if (!r) return null; + const { + rootPlaylistService: s, + rootPlaylistQuery: a + } = i, o = a.itemId, l = r[1], d = l.iframe; + let u = a.getInitPTS(n); + if (null == u || !d && u.iframeMode) { + const i = null !== (r = l.startDtsTs) && void 0 !== r ? r : null; + if (null == i) return t.warn("updateInitPTS: Variant data missing."), null; + let e = null !== (t = l.timelineOffset) && void 0 !== t ? t : 0; + d && (e = null !== (t = l.iframeOriginalStart) && void 0 !== t ? t : 0), i.timescale < 1e3 && (i.timescale = 1e3 * i.timescale, i.baseTime = 1e3 * i.baseTime); + const a = B(e, i.timescale), + c = { + baseTime: i.baseTime - a.baseTime, + timescale: i.timescale + }; + s.setInitPTS(o, n, i, e, c, d), u = { + variantDTS: i, + timelineOffset: e, + offsetTimestamp: c, + iframeMode: d + } + } + return u + }(n, a, e, s.discoSeqNum); + fy(n, a, e, t) + })) : en([e, Gu(o.initPTS$(s.discoSeqNum), e => { + const t = u.mediaQuery.isIframeRate; + return null != e && (t || !e.iframeMode) + })]).pipe(hr(([e, t]) => (fy(n, a, e, t), e))), en([r, e]).pipe(hr(e => e[1])) + } + return $i(null) + })).pipe(hr(e => function(g, t, e, i) { + const { + rootPlaylistQuery: r, + mediaSink: n, + config: y + } = t, v = n.mediaQuery, s = v.isIframeRate, a = r.getInitPTS(e); + if (null == a) return g.warn("No initPTS info found"), null; + const o = i[gu.Variant], + l = null == o ? void 0 : o[1]; + if (l && l.iframe !== s) return g.warn(`frag mediaSeqNum ${l.mediaSeqNum} discoSeqNum ${l.discoSeqNum} mediaOptionId ${l.mediaOptionId} doesn't match mediaSink's iframeMode ${s}; discard`), null; + const S = [null, null]; + if (o) { + const [g, t] = o; + let e = a.offsetTimestamp; + if (s) { + const g = t.startDtsTs, + i = B(t.timelineOffset, g.timescale); + e = { + baseTime: g.baseTime - i.baseTime, + timescale: g.timescale + } + } + S[yu.Variant] = { + initSeg: g, + dataSeg: t, + offsetTimestamp: e + } + } + const d = i[gu.AltAudio]; + if (null != d) { + const [g, t] = d; + S[yu.AltAudio] = { + initSeg: g, + dataSeg: t, + offsetTimestamp: a.offsetTimestamp + } + } + const u = S.map((e, t) => { + const i = null == e ? void 0 : e.dataSeg; + if (i) { + const { + itemId: r, + mediaOptionId: n, + mediaSeqNum: s, + discoSeqNum: a, + startPts: o, + endPts: l, + duration: d, + iframe: u + } = i, c = e["offsetTimestamp"], h = b(o, c), p = b(l, c), f = Dg(i), m = S[0]; + return m && m.dataSeg.dropped || i.flushBeforeAppend || !((null === (e = null === (e = v.getBufferInfo(h, y.maxBufferHole)[t]) || void 0 === e ? void 0 : e.buffered) || void 0 === e ? void 0 : e.len) >= p - h) ? { + start: h, + duration: u ? d : p - h, + itemId: r, + mediaOptionId: n, + mediaSeqNum: s, + discoSeqNum: a, + targetDuration: f.mediaOptionDetails.targetduration + } : (g.warn(`${Nu[t]} Discarding append due to complete overlap with existing buffer`), S[t] = null) + } + return null + }); + return u.every(e => !e) ? null : { + appendDataTuple: S, + inFlightFrags: u, + initPTSInfo: a + } + }(n, a, s.discoSeqNum, e)), La(e => { + if (e) return $i(e); { + const e = function(e, r) { + const n = e.enabledMediaOptionKeys, + s = [null, null], + a = [null, null]; + return Bu.map(e => { + var t; + if (_u(n[e])) { + const i = Dg(n[e]).mediaOptionDetailsEntity; + a[e] = null === (t = i.mediaOptionDetails) || void 0 === t ? void 0 : t.ptsKnown, s[e] = { + detailsEntity: i, + switchContext: null === (e = r[e]) || void 0 === e ? void 0 : e.switchContext + } + } + }), s + }(o, d); + return t(n, s, a, i, e) + } + })) + }(i, n, r, e, t)), tc("mediaProducerEpic.emit")) + }; + + function py(e, i, t, r) { + const { + rootPlaylistQuery: n, + mediaLibraryService: s, + config: a + } = t, o = r[i]; + if (t.logger.child({ + name: Nu[i] + }), !o || "Nah" === o.mediaOptionId) return $i({ + detailsEntity: null, + switchContext: null + }); + const l = s.getQueryForOption(o); + return Mr([$i(e), l.mediaOptionDetailsEntity$.pipe(Is((e, t) => (null == e ? void 0 : e.lastUpdateMillis) === (null == t ? void 0 : t.lastUpdateMillis)), ln(e => { + var t = null == e ? void 0 : e.mediaOptionDetails; + if (!t) return !0; + var i = performance.now(), + r = e.lastUpdateMillis || i, + e = t.liveOrEvent, + t = t.targetduration; + return !e || i - r < a.livePlaylistUpdateStaleness * t * 1e3 + }))]).pipe(ln(([, e]) => { + if (i === gu.AltAudio && !n.altMediaOptionHasValidUrl(i, o.mediaOptionId)) return !0; + var t = null == e ? void 0 : e.mediaOptionDetails; + return null != t && (e = null !== (e = e.lastUpdateMillis) && void 0 !== e ? e : 0, !t.liveOrEvent || !t.ptsKnown || !Yg(null == t ? void 0 : t.totalduration, 0, e)) + }), Ds(1), bo(n.enabledMediaOptionSwitchContextsByType$(i)), hr(([ + [, e], t + ]) => ({ + detailsEntity: e, + switchContext: t + }))) + } + + function fy(e, t, i, r) { + const { + mediaLibraryService: n, + rootPlaylistQuery: s, + mediaSink: a + } = t, o = s.itemId; + null != r && (a.mediaQuery.isIframeRate || !r.iframeMode ? i && !ne(i[1].iframeMediaDuration) && (performance.now(), n.updatePTSDTS(o, i[1].mediaOptionId, r, i[1])) : e.warn("updatePTSDTS iframeMode mismatch")) + } + const my = t => e => { + const { + rootPlaylistQuery: g, + rootPlaylistService: y, + mediaSink: v, + legibleSystemAdapter: o, + statsService: l, + rtcService: d + } = t; + return e.pipe(tc("mediaConsumerEpic.in"), La(e => { + if (!e) return $i(!1); + const { + appendDataTuple: r, + inFlightFrags: m, + initPTSInfo: t + } = e, i = t["offsetTimestamp"]; + return m.forEach((e, t) => { + e && y.updateInflightFrag(e.itemId, t, e, "appending", null) + }), r.forEach(e => { + e && (e = e.dataSeg, o.addLegibleSamples(i, e.captionData, e.id3Samples, e.endPts)) + }), v.appendData(r, (e, t, i, r, n) => { + var s, a, o, l, d, u, c, h, p, f = null !== (f = m[t].targetDuration) && void 0 !== f ? f : 10; + return s = v, a = e, o = t, l = i, d = f, u = r, c = g, h = y, p = n, e => e.pipe(Za(() => { + h.updateConsecutiveTimeouts(c.itemId, o, !1, "append") + }), va(e => e.pipe(jr((e, t) => { + var i = e instanceof df && e.isTimeout; + if (h.updateConsecutiveTimeouts(c.itemId, o, i, "append"), i) return function(e, t, i, r, n, s, a, o) { + let l = { + errorAction: Cm.SendAlternateToPenaltyBox, + errorActionFlags: 0 + }; + var d = s.getCurrentWaterLevel(i.maxBufferHole), + u = d < i.almostDryBufferSec; + let c = NaN; + s = i.appendErrorMaxRetry, i = a.rootPlaylistEntity.errorsByType[r].timeouts.append; + u && s <= i || s <= t ? l.errorAction = Cm.SendEndCallback : c = 1e3 * d; + s = { + retryDelayMs: c, + maxNumRetry: s, + maxRetryDelayMs: c + }; + return l = Jm(l, !1, e.response.code, n, r, a, o), rg(e, t, s, l, a, o, r, n).pipe() + }(e, t, u, o, l, p, c, h); + if (e instanceof uf) return function(e, t, i, r, n, s, a, o, l, d) { + var u = t.type, + u = o.getCurrentWaterLevelByType(u, n.maxBufferHole); + if (u >= n.almostDryBufferSec && !o.isIframeRate) { + const t = 1e3 * r, + n = { + errorAction: Cm.RetryRequest, + errorActionFlags: 0 + }; + return 1e3 * u < t && (d.hasFallbackMediaOptionTuple(l, s, a, !1) ? n.errorAction = Cm.SendAlternateToPenaltyBox : n.errorAction = Cm.SendEndCallback), rg(e, i, { + retryDelayMs: t, + maxNumRetry: 1 / 0, + maxRetryDelayMs: t + }, n, l, d, s, a) + } + return i < n.appendErrorMaxRetry ? t.remove(0, Number.POSITIVE_INFINITY) : (e.fatal = !0, Vi(e)) + }(e, a, t, d, u, o, l, p, c, h); + if (e instanceof hf) { + const { + mediaOptionType: a, + mediaOptionId: o + } = e; + return oy(e, a, o, s, h, c) + } + throw e + })))) + }, g.highestVideoCodec).pipe(hr(e => { + m.forEach((e, t) => { + e && y.updateInflightFrag(e.itemId, t, e, "appended", null) + }); + var t = e.filter(e => (null == e ? void 0 : e.fragmentType) === gu.Variant); + t.length && (l.setBufferMetric(t[0]), null == d || d.handleFragBuffered(t[0])); + e = r[yu.AltAudio]; + if (null !== (t = null == e ? void 0 : e.dataSeg) && void 0 !== t && t.flushBeforeAppend || ne(null === (t = null == e ? void 0 : e.dataSeg) || void 0 === t ? void 0 : t.switchPosition)) { + const { + itemId: i, + mediaOptionId: r + } = e.dataSeg; + y.setEnabledMediaOptionSwitchContextByType(i, gu.AltAudio, r, void 0) + } + return !0 + }), (n = v, s = y, a = g, e => e.pipe(Vn(e => { + if (e instanceof lf) { + var { + mediaOptionType: t, + mediaOptionId: i + } = e; + return oy(e, t, i, n, s, a) + } + throw e + })))); + var n, s, a + })) + }; + + function gy(d, u, c, h, p, f) { + return u = u.child({ + name: "seek" + }), e => e.pipe(La((e, t) => { + if (null == e) return Ii; + var i, r, n, s, a, o, l = c.mediaQuery.seekTo$.pipe(ka(1), Kp()); + return i = 0 === t, r = d, n = u, s = p, t = f, (null == (e = e) ? Ii : e instanceof Date ? (a = e, o = t, s.enabledMediaOptionByType$(gu.Variant).pipe(La(e => o.getQueryForOption(e).mediaOptionDetails$), hr(e => function(e, t) { + if (!e || 0 === e.length) return 0; + const i = [...e].sort((e, t) => t[0] - e[0]), + r = t.getTime(), + n = null !== (t = i.find(([e]) => r >= e)) && void 0 !== t ? t : i[i.length - 1], + [s, a] = n, + o = a + (r - s) / 1e3; + return Math.max(0, o) + }(e.dateMediaTimePairs, a)), Ds(1))) : function(r, e, a, n, t, o) { + let i = n.enabledMediaOptionByType$(gu.Variant).pipe(La(e => t.getQueryForOption(e).mediaOptionDetails$), ln(e => ne(null == e ? void 0 : e.totalduration)), Ds(1), hr(s => { + var e = !s.liveOrEvent, + t = s.totalduration, + i = n.itemStartOffset; + return e ? ne(r) ? 0 <= r ? r : i + (t + r) : i + (ne(s.startTimeOffset) ? s.startTimeOffset : 0) : !ne(r) || r < 0 || 0 === r && a.liveEdgeForZeroStartPositon ? yg(0, s, a) : function(e, t) { + let i = e; + var r = s.fragments[0].start, + n = s.fragments[s.fragments.length - 1].start + s.fragments[s.fragments.length - 1].duration; + return e < r ? i = r : n < e && (i = yg(0, s, a)), (e < r || n < e) && t.warn(`[live] sanitizeLiveSeek seekTo:${se(e,3)}, sanitizedSeek:${se(i,3)}, liveWindowStart:${se(r,3)}, liveWindowEnd:${se(n,3)}`), i + }(r, o) + })); + return e && (i = i.pipe(Za(e => {}))), i + }(e, i, r, s, t, n)).pipe(Vs(() => { + h.setPendingSeek(p.itemId, void 0) + }), Va(l)) + }), Za(e => { + ne(e) && (c.seekTo = e) + })) + } + + function yy(e) { + const { + logger: r, + rootPlaylistService: n, + rootPlaylistQuery: t + } = e, s = t.itemId; + return e => e.pipe(va(e => e.pipe(jr(e => { + if (r.error(`Got error in pipeline ${e.message} fatal:${null==e?void 0:e.fatal} handled:${null==e?void 0:e.handled}`), !(e instanceof p) || e.fatal) throw e; + return e.handled ? (t = n, i = s, bn(0).pipe(hr(() => { + t.updateEnabledMediaOptions(i) + }))) : Ii; + var t, i + })))) + } + const vy = () => e => e.pipe(tc("mediaFragmentPipelineEpic.in"), La(i => { + if (!i) return Ii; + const { + logger: e, + config: t, + platformService: r, + rootPlaylistService: n, + rootPlaylistQuery: s, + keySystemAdapter: a, + mediaSink: o, + mediaParser: l, + gaplessInstance: d, + mediaLibraryService: u + } = i, c = s["itemId"], h = o["mediaQuery"], p = a.keyStatusChange$.pipe((f = i, e => e.pipe(La(e => { + const { + decryptdata: t, + status: i, + error: r + } = e, n = f["rootPlaylistQuery"]; + if ("needs-renewal" === i) return _g(f, t, null); + if ("error" !== i || !(r instanceof gc || r instanceof mc) || r.handled) return Ii; { + const { + rootPlaylistService: e, + keySystemAdapter: t + } = f; + return og(r, 0, null, e, n, t.ksQuery) + } + }), La(() => Ii)))); + var f; + const m = r.getQuery(), + g = m.displaySupportsHdr$.pipe(Is(), La(e => (n.setHDRPreference(c, e, !0), Ii))), + y = m.viewportInfo$.pipe(Is((e, t) => e && t && e.width === t.width && e.height === t.height), Za(e => { + t.useViewportSizeForLevelCap && n.setViewportInfo(c, e) + }), $a(Ii)), + v = ed([s.hdrMode$.pipe(Is()), s.maxHdcpLevel$.pipe(Is())]).pipe(La(([]) => (d.inGaplessMode || 0 !== s.itemStartOffset || (o.resetMediaSource(), l.reset()), Ii))), + S = an(function(i) { + const { + rootPlaylistQuery: t, + mediaSink: r + } = i, e = t.enabledMediaOptions$.pipe(Kp(), Za(e => { + e = e[gu.AltAudio], e = _u(e) && null != (null == e ? void 0 : e.url) ? 2 : 1; + r.setExpectedSbCount(e) + })), n = en([t.enabledMediaOptionByType$(gu.Variant).pipe(ln(e => _u(e)), La(e => Dg(e).mediaOptionDetails$), Ds(1)), Gu(r.mediaQuery.updating$, e => e)]).pipe(ji(tr), Za(([e]) => { + r.bufferMonitorTargetDuration = e.targetduration + })), s = Fu.map(e => t.enabledMediaOptionByType$(e).pipe(tc("mediaOptionRetrieve.switch"), La(t => { + if (!t || !t.url || !_u(t)) return Ii; + var e = r.mediaQuery.desiredRate$.pipe(hr(e => 0 !== e), Is()); + return Mg(i, t).pipe(tc("mediaOptionRetrieve.first"), $a(e), La(e => e ? function e(t, i) { + const r = t.mediaLibraryService; + return function(e) { + if (!e) return Ii; + var { + mediaOptionDetails: t, + lastUpdateMillis: i, + unchangedCount: e + } = e; + if (null == t || !t.liveOrEvent) return Ii; + if (bg(t, i)) return bn(0).pipe(Za(() => {})); + let r = Sg(t); + return 0 < e && (r /= 2, r = Math.max(r, 5e3)), r -= performance.now() - i, r += 0, r = Math.max(1e3, Math.round(r)), bn(r).pipe(Za(() => {})) + }(r.getQueryForOption(i).mediaOptionDetailsEntity).pipe(La(() => Mg(t, i, !1, !0)), La(() => e(t, i))) + }(i, t) : Ii)) + }))); + return an(e, n, an(...s)).pipe($a(Ii)) + }(i), cy(i), function(t) { + const { + rootPlaylistQuery: i, + mediaSink: e + } = t; + return Gu(e.mediaQuery.mediaElementEntity$, e => e).pipe(La(e => i.anchorTime$.pipe(tc("anchorTime.subtitle.in"), ln(e => ne(null == e ? void 0 : e.pos)), (s => e => { + const { + rootPlaylistQuery: i, + rootPlaylistService: t, + legibleSystemAdapter: r + } = s, n = i.enabledAlternateMediaOptionByType(gu.Subtitle); + if (r.gotTracks) r.selectedTrack = n; + else { + const s = i.preferredMediaOptions[gu.Subtitle]; + r.setTracks(s, n, i.getDisabledMediaOption(gu.Subtitle)) + } + return e.pipe(tc("subtitleEpic.select.in"), La(() => an(r.nativeSubtitleTrackChange$.pipe(La(e => (e.mediaOptionId !== r.selectedMediaOption.mediaOptionId && t.setEnabledMediaOptionByType(e.itemId, gu.Subtitle, e), Ii))), i.enabledMediaOptionByType$(gu.Subtitle).pipe(hr(e => { + const t = _u(e) ? i.alternateMediaOptionById(gu.Subtitle, e.mediaOptionId) : e; + return r.selectedMediaOption = t, t + })).pipe(Is((e, t) => (null == e ? void 0 : e.mediaOptionId) === (null == t ? void 0 : t.mediaOptionId))))), tc("subtitleEpic.select.emit")) + })(t), (s => e => { + const { + mediaSink: t, + rootPlaylistQuery: i, + legibleSystemAdapter: r, + logger: n + } = s; + return e.pipe(tc("subtitleEpic.process.in"), La(e => { + if (!e || !e.url || !_u(e)) return $i([null, null, null]); + return ed([Dg(e).mediaOptionDetails$, i.discoSeqNum$.pipe(ln(e => ne(e)))]).pipe(La(([e, t]) => ((i, r, e) => { + const { + legibleSystemAdapter: n, + rootPlaylistQuery: t + } = i; + return t.initPTS$(e).pipe(La(t => !t || t.iframeMode ? on : n.findFrags$(r, e).pipe(La(e => r && (null == e ? void 0 : e.foundFrags) ? Sy(i, t.offsetTimestamp, e, r) : Wu)))) + })(s, e, t))) + }), tc("subtitleEpic.process.emit")) + })(t)))) + }(i), p).pipe(Zs(void 0), yy(i)), + b = h.seekTo$.pipe(ln(e => ne(null == e ? void 0 : e.pos)), Is((e, t) => Math.abs(e.pos - t.pos) < Number.EPSILON), La(e => (n.setAnchorTime(c, e), Ii))), + T = h.gotPlaying$.pipe(ln(e => e), Za(e => { + s.mediaOptionListQueries[gu.Variant].filteredMediaOptionList.forEach(e => {}) + }), Ds(1), $a(Ii)); + return an(s.pendingSeek$.pipe(gy(t, e, o, n, s, u)), function() { + const { + config: n, + mediaSink: s, + rootPlaylistQuery: e, + mediaLibraryService: t + } = i, a = (i.logger.child({ + name: "live" + }), s.mediaQuery); + return e.enabledMediaOptionByType$(gu.Variant).pipe(ln(_u), La(e => t.getQueryForOption(e).mediaOptionDetailsEntity$.pipe(ln(e => { + var t; + return (null === (t = null == e ? void 0 : e.mediaOptionDetails) || void 0 === t ? void 0 : t.ptsKnown) && e.mediaOptionDetails.liveOrEvent + }), Is((e, t) => (null == e ? void 0 : e.lastUpdateMillis) === (null == t ? void 0 : t.lastUpdateMillis)))), hr(e => { + var t = e.mediaOptionDetails, + i = a.currentTime; + a.msDuration < e.playlistDuration ? s.msDuration = e.playlistDuration : ne(s.msDuration) && (s.msDuration = s.msDuration + n.livePlaylistDurationNudge); + let r = NaN; + return i < vg(i, t, e.lastUpdateMillis, n.maxBufferHole, a) && (r = yg(t.fragments[0].start, t, n), s.seekTo = r), r + })) + }(), b, S, g, y, v, function() { + const e = i.mediaSink.mediaQuery; + return Mr([$i(i), e.desiredRate$.pipe(ha())]).pipe(La(([e, [t, i]]) => { + const { + rootPlaylistQuery: s, + rootPlaylistService: r, + config: a, + mediaSink: n, + mediaLibraryService: o, + statsService: l + } = e, d = n.mediaQuery; + if (Wp(t) !== Wp(i)) iy(Mm.IframeModeChange, a, s, d, r); + else if (0 === t && 1 === i && !Bu.every(e => { + const t = s.enabledMediaOptionKeys[e], + i = o.getQueryForOption(t), + r = l.getQueryForItem(s.itemId), + n = i.mediaOptionDetailsEntity; + return !(null !== (e = null == n ? void 0 : n.mediaOptionDetails) && void 0 !== e && e.ptsKnown) || d.canContinuePlaybackWithoutGap(n.mediaOptionDetails, n.lastUpdateMillis, r.getPlaylistEstimate(), a.maxBufferHole) + })) return n.pause(), n.flushAll(0, 1 / 0, !0); + return Ii + }), $a(Ii)) + }(), function(e) { + const t = e.rootPlaylistQuery, + i = e.mediaSink.mediaQuery, + r = t.enabledMediaOptionByType$(gu.Variant); + return Mr([$i(e), i.desiredRate$.pipe(ha())]).pipe(Is((e, t) => e[1] === t[1]), bo(r), La(([ + [e, [t, i]], r + ]) => { + t = Wp(t), i = Wp(i); + if (t === i) return Ii; + const n = e["rootPlaylistService"]; + return i && e.rootPlaylistQuery.nextMaxAutoOptionId === Lu.mediaOptionId && n.setNextMaxAutoOptionId(e.rootPlaylistQuery.itemId, r.mediaOptionId), Ii + })) + }(i), T).pipe(tc("mediaFragmentPiplineEpic.emit"), Zs(void 0)) + })), + Sy = (r, e, t, i) => { + const n = r.legibleSystemAdapter, + s = t.foundFrags; + return Fr(s).pipe(hr(t => { + return ((e, t, i) => { + const { + rootPlaylistQuery: r, + legibleSystemAdapter: n + } = e; + return Zr(() => ((t, i) => Rg(e, i, !1, !1).pipe(hr(e => ({ + initPTS: t, + data: e, + mediaFragment: i + })), tc("retrieveSubtitleFragmentCacheEntity.emit")))(t, i).pipe(hr(({ + initPTS: e, + data: t, + mediaFragment: i + }) => ({ + frag: i, + cueRange: function(e, t, i, r, n) { + if (e) return n.processSubtitleFrag(e, t, i, r) + }(r.enabledAlternateMediaOptionByType(gu.Subtitle), i, e, t, n) + })))) + })(r, e, t).pipe((i = e => n.checkReadyToLoadNextSubtitleFragment$(t, s).pipe(ln(e => e)), function(e) { + return e.lift(new gs(i)) + })); + var i + }), Yr(r.config.vttConcurrentLoadCount), Za(e => { + n.reviewParsedFrag(e, t, i) !== kp.CloseEnough && r.legibleSystemAdapter.tryAgain$.next(!0) + })) + }, + by = (e, t) => { + let i, r = ""; + return i = e.videoCodec && e.audioCodec ? (r = `${e.videoCodec}, ${e.audioCodec}`, t = null != t ? t : "video/mp4", "audiovideo") : e.videoCodec ? (r = `${e.videoCodec}`, t = null != t ? t : "video/mp4", "video") : (r = `${null!==(e=e.audioCodec)&&void 0!==e?e:""}`, t = null != t ? t : "audio/mp4", "audio"), { + mimeType: `${t};codecs=${r}`, + codec: r, + container: t, + type: i + } + }; + class Ty { + constructor(e, t, i) { + this.config = e, this.logger = t, this.demuxClient = i, this.typeSupported = { + mp4: MediaSource.isTypeSupported("video/mp4"), + mpeg: MediaSource.isTypeSupported("audio/mpeg"), + mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'), + ac3: MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"'), + ec3: MediaSource.isTypeSupported('audio/mp4; codecs="ec-3"') + }, this.demuxers = [], this.lastInitFrags = [], this.lastFrags = [] + } + parseInitSegment(h, e) { + return this.getDemuxerInfo(h, this.lastInitFrags, e, this.demuxClient).pipe(La(({ + demuxer: e, + contiguous: t, + trackSwitch: i, + discontinuity: r, + accurateTimeOffset: n + }) => { + const s = h["frag"], + { + keyTagInfo: a, + start: o, + mediaOptionType: l + } = s; + if (this.lastInitFrags[l] = s, h.initSegment) { + const e = ze.remuxInitSegment(new Uint8Array(h.initSegment), this.logger, a), + t = Ze.parseInitSegment(e), + { + mimeType: i, + type: r, + codec: n, + container: s + } = by(t); + return $i({ + moovData: t, + mimeType: i, + track: { + type: r, + codec: n, + initSegment: e, + container: s + } + }) + } + const d = h.segment || h.initSegment, + u = d ? h.initSegment : void 0, + c = Oc(e.observer); + return $i(c.event(v.FRAG_PARSING_INIT_SEGMENT).pipe(hr(this.handleInitSegmentData)), c.event(x.INTERNAL_ERROR).pipe(La(this.handleError)), e.pushWithoutTransfer(d, a, u, o, r, i, t, h.totalDuration, n, void 0, h.iframeMediaStart, h.iframeDuration).pipe($a(Ii))).pipe(Yr(), Ds(1)) + })) + } + parseSegment(y, e) { + return this.getDemuxerInfo(y, this.lastFrags, e, this.demuxClient).pipe(La(({ + demuxer: e, + contiguous: t, + trackSwitch: i, + discontinuity: r, + accurateTimeOffset: n + }) => { + const { + frag: h, + defaultInitPTS: p + } = y, { + keyTagInfo: s, + start: a, + duration: f, + mediaOptionType: m + } = h; + let g; + this.lastFrags[m] = h; + const o = Oc(e.observer); + return $i(o.event(v.FRAG_PARSING_INIT_SEGMENT).pipe(La(e => { + var t; + return e.track.initSegment.byteLength !== (null === (t = y.initSegment) || void 0 === t ? void 0 : t.byteLength) && (g = this.handleInitSegmentData(e)), Ii + })), o.event(v.FRAG_PARSING_DATA).pipe(hr(e => { + var { + startPTS: t, + startDTS: i, + firstKeyframePts: r, + framesWithoutIDR: n, + dropped: s, + data1: a, + data2: o, + captionData: l, + id3Samples: d + } = e; + let { + endPTS: u, + endDTS: c + } = e; + return null == u && (this.logger.warn(`${Nu[m]} ${Vp(h)}: null endPTS parsed, using duration ${f}`), u = Object.assign(Object.assign({}, t), { + baseTime: t.baseTime + B(f, t.timescale).baseTime + })), null == c && (this.logger.warn(`${Nu[m]} ${Vp(h)}: null endDTS parsed, using duration ${f}`), c = Object.assign(Object.assign({}, i), { + baseTime: i.baseTime + B(f, i.timescale).baseTime + })), ne(y.iframeMediaStart) || function(e, t, i, r) { + let n = NaN, + s = NaN; + if (ne(i)) s = i, n = .01, isFinite(s) && isFinite(r) && (s += r); + else { + { + const o = void 0 + } + } + var { + startPTS: a, + startDTS: i, + endPTS: r, + endDTS: t + } = t; + if (!(0 <= a.baseTime && 0 <= i.baseTime && 0 < e.duration && (null == r || 0 < b(r, a)) && (null == t || 0 < b(t, i)) && (!ne(n) || !ne(s) || Math.abs(S(i) - s) <= n))) throw new D(!1, `Failed demuxer sanity check frag=${Vp(e)} parsed=${JSON.stringify({startPTS:a,endPTS:r,startDTS:i,endDTS:t})} ${ae({expectedStartDTS:s,fudge:n})}`, $.FailedDemuxerSanityCheck) + }(h, e, (p, y.iframeMediaStart), this.config.audioPrimingDelay), { + startPTS: t, + endPTS: u, + startDTS: i, + endDTS: c, + firstKeyframePts: r, + framesWithoutIDR: n, + dropped: s, + data1: a, + data2: o, + captionData: l, + id3Samples: d, + parsedInitSegment: g + } + })), o.event(x.INTERNAL_ERROR).pipe(La(this.handleError)), e.push(y.segment, s, y.initSegment, a, r, i, t, y.totalDuration, n, p, y.iframeMediaStart, y.iframeDuration).pipe($a(Ii))).pipe(Yr(), Ds(1)) + })) + } + reset(e) { + if (null == e) return this.demuxers.forEach(e => { + e && e.destroy() + }), void(this.demuxers = []); + const t = this.demuxers[e]; + null == t || t.destroy(), this.demuxers[e] = null + } + destroy(e) { + null != e ? this.reset(e) : this.reset() + } + willBeTrackSwitch(e, t) { + var { + mediaOptionType: i, + mediaOptionId: e + } = e, i = (t || this.lastFrags)[i]; + return !(i && i.mediaOptionId === e) + } + getDemuxerInfo(e, r, t, i) { + const { + frag: n, + ptsKnown: s, + seeking: a, + live: o + } = e, { + discoSeqNum: l, + mediaSeqNum: d, + mediaOptionType: u + } = n; + return Zr(() => { + var e = this.demuxers[u]; + return e ? $i(e) : i.init(this.typeSupported, this.config, t).pipe(Za(e => this.demuxers[u] = e)) + }).pipe(hr(e => { + var t = r[u], + i = this.willBeTrackSwitch(n, r); + return { + demuxer: e, + trackSwitch: i, + discontinuity: !(t && l === t.discoSeqNum), + contiguous: !!t && !i && t.mediaSeqNum + 1 === d, + accurateTimeOffset: !a && (s || !o) + } + })) + } + handleInitSegmentData(e) { + var t = e["track"], + i = t["initSegment"], + r = Ze.parseInitSegment(i), + { + mimeType: n, + type: s, + codec: a, + container: e + } = by(r, t.container); + return { + moovData: r, + mimeType: n, + track: Object.assign(Object.assign({}, t), { + type: s, + codec: a, + initSegment: i, + container: e + }) + } + } + handleError(e) { + return Vi(e) + } + } + + function Ey(a, e, t, h, p, i, r, n) { + var s = h["combined"], + o = function(e) { + let t = 1 / 0; + h.playingFrag && (t = null !== (s = null === (n = e.fragments[h.playingFrag.mediaSeqNum - e.startSN]) || void 0 === n ? void 0 : n.duration) && void 0 !== s ? s : 1 / 0); + var { + minRequiredStartDuration: i, + maxRequiredStartDuration: r, + startTargetDurationFactor: n + } = a, { + targetduration: s, + averagetargetduration: e + } = e, r = n * Math.min(t, e, s, r); + return Math.max(i, r) + }(t.details); + let l = function(e, t, i) { + const { + pos: r, + combined: n, + playingFrag: s + } = h; + if (0 === n.len) return !1; + var a = t.details, + o = a.fragments; + let l = 0 != p && 1 != p || n.len >= i; + var d = o[a.fragments.length - 1], + t = o[0].start + a.totalduration; + let u = !1; + if (s) { + const c = qu.search(o, e => s.discoSeqNum - e.discoSeqNum); + u = e && s.discoSeqNum !== e.discoSeqNum || null == c || $p(c, s) + } + return l && a.liveOrEvent ? l = r <= t - d.duration : a.liveOrEvent || (l = l || t - i <= r), l = l || u, l + }(e, t, o); + return !l && 0 < s.len && null != e && e.state && (l = function(n, e, t, i, r, s, a) { + var o = null === (l = h.sbTuple[gu.Variant]) || void 0 === l ? void 0 : l.buffered, + l = null === (l = h.sbTuple[gu.AltAudio]) || void 0 === l ? void 0 : l.buffered; + if ((null == o ? void 0 : o.len) >= t && (!l || l.len >= t)) return 0; + if (!(o && n && (d = h.pos, (l = n.start + n.duration) > o.end && (n.start - o.end <= a || n.start <= o.end) && t <= l - d))) return 1 / 0; + var d = n.state; + let u = n.tstart, + c = 0; + switch (d) { + case "loading": + c += function(e, t) { + var { + bwSample: i, + duration: r + } = n; + if (!i) return 1 / 0; + r = ne(i.total) ? 8 * i.total : Math.ceil(r * e), e = 8 * i.loaded, r -= e, i = e / (performance.now() - i.tfirst) * 1e3; + if (!ne(i)) return 1 / 0; + t = t.avgBandwidth; + return r / Math.min(t, i) + }(e, i), u = n.tstart + 1e3 * c; + case "loaded": + case "parsing": + c += function(e, t) { + t = ne(t.avgParseTimeMs) ? t.avgParseTimeMs : 0; + return performance.now() < e ? t / 1e3 : Math.max(0, t - (performance.now() - e)) / 1e3 + }(u, r), u = n.tstart + 1e3 * c; + case "parsed": + case "appending": + c += function(e, t) { + t = ne(t.avgDataFragAppendMs) ? t.avgDataFragAppendMs : 0; + return performance.now() < e ? t / 1e3 : Math.max(0, t - (performance.now() - e)) / 1e3 + }(u, s); + break; + default: + c = 1 / 0 + } + return c + }(e, t.variant.bitrate, o, i, r, n, a.maxBufferHole) <= s.len), l + } + + function Iy(e, t, i, r) { + if (200 === t && r && 10 < r.length) { + if (Rm.isValidPlaylist(r)) return !0; { + const t = new R(o, _, !0, "response doesnt have #EXTM3U tag", $.PlaylistErrorMissingEXTM3U); + throw t.url = e, t + } + } + return !1 + } + const wy = { + name: "pltfrm" + }; + + function Ay(e, t) { + t = Ah.getKeySystemSecurityLevel(t); + return null != e && void 0 !== t[e] + } + + function Oy(e) { + return e.every(e => e.iframes) + } + + function ky(e, t) { + return !ne(e) || !ne(t) || e <= t + } + + function Cy() { + const n = new Set, + s = new Set; + return e => { + const i = (e, t) => { + t = t ? "audio" : "video"; + n.has(e) || s.has(e) || (((e, t) => { + let i = MediaSource.isTypeSupported(`${e}/mp4;codecs=${t}`); + return "mp4a.40.34" !== t || i || (i = MediaSource.isTypeSupported(`${e}/mpeg`)), i + })(t, e) ? n : s).add(e) + }, + t = (e, t) => (i(e, t), s.has(e)); + let r = !1; + return e.audioCodecList && (r = e.audioCodecList.some(e => t(e, !0))), !r && e.videoCodecList && (r = e.videoCodecList.some(e => t(e, !1))), !r + } + } + + function Dy(e, t) { + for (const i in e) + if (e[i].type === t) return e[i]; + return {} + } + + function My(e, t, i) { + t.filter(e => !i.includes(e)).map(e => e.mediaOptionId) + } + + function xy(e, i, s) { + const a = new Map, + r = new Array; + return e.forEach(t => { + var e = Array(); + ! function(e, t, i) { + var r = Wc.getCapabilities(t.videoCodecList, t.audioCodecList), + t = JSON.stringify(r); + let n; + a.has(t) ? n = a.get(t) : (n = Ah.requestKeySystemAccess(e, r, void 0, s).pipe(hr(() => !0), Vn(e => (s.warn(`Request key system error: ${e.message}`), $i(!1))), Oa({ + bufferSize: 1, + refCount: !0 + })), a.set(t, n)), i.push(n) + }(i, t, e); + e = en(e).pipe(hr(e => { + if (void 0 === e.find(e => !1 === e)) return t + })); + r.push(e) + }), en(r).pipe(hr(e => e.filter(e => Boolean(e)))) + } + + function Py(e, r) { + const o = new Set, + l = new Set, + d = !MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.2"; channels="-1"'), + u = d && !MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.2"; channels="2"; features="INVALID"'), + t = e.filter(e => { + let t = !1; + var i; + return e.audioCodecList && e.audioGroupId && (i = fm.getRichestChannelLayoutForGroupId(e.audioGroupId, r), 0 < e.audioCodecList.length && i && (t = ((e, t) => { + var i, r, n, s = be.isDolbyAtmos(e, t); + if (u || d && !s) { + n = `${i=e}/${r=t}`, o.has(n) || l.has(n) || (((e, t) => { + const i = t.split("/"), + r = parseInt(i[0]); + let n, s; + if (1 < i.length) { + const t = i[1].split(",")[0]; + n = `audio/mp4;codecs="${e}";channels="${r}";features="${t}"`, s = `audio/mp4;codecs="${e}";channels="8";features="${t}"` + } else n = `audio/mp4;codecs="${e}";channels="${r}"`; + let a = MediaSource.isTypeSupported(n); + return !a && s && (a = MediaSource.isTypeSupported(s)), a + })(i, r) ? o : l).add(n); + const a = `${e}/${t}`; + return l.has(a) + } + return !!s + })(fm.getRichestAudioCodec(e.audioCodecList), i))), !t + }); + return My(0, e, t), t + } + + function Ry(e, t, l) { + const n = 0 < (null == t ? void 0 : t.length), + i = e.filter(o => { + var e = function() { + if (!l) return { + highestPlayableAverageBitRate: void 0, + highestPlayablePeakBitRate: void 0, + highestPlayableWidth: void 0, + highestPlayableHeight: void 0, + highestPlayableFrameRate: void 0 + }; + const e = o.videoCodec, + t = o.videoRange, + i = l.videoDynamicRangeFormats, + r = l.videoCodecs, + n = be.getDynamicRangeType(t, e), + s = be.getCompressionType(e), + a = function(e, t, i, r) { + if (!r && !i) return {}; + var n, s, t = i ? Dy(i, t) : {}, + r = r ? Dy(r, e) : {}; + let a, o; + return o = e === fe.SDR ? (a = t, r) : (a = r, t), n = Object.assign({}, a), s = o, Object.keys(s).forEach(e => { + n[e] || (n[e] = s[e]) + }), n + }(n, s, r, i); + return s !== me.VP09 && (a.highestPlayablePeakBitRateForClearContent = void 0), a + }(), + t = e["highestPlayablePeakBitRateForClearContent"], + i = o.allowedCPCMap || n, + r = ky(o.bandwidth, e.highestPlayablePeakBitRate); + return (i || !t ? r : r || ky(o.bandwidth, t)) && ky(o.avgBandwidth, e.highestPlayableAverageBitRate) && ky(o.width, e.highestPlayableWidth) && ky(o.height, e.highestPlayableHeight) && ky(o.frameRate, e.highestPlayableFrameRate) + }); + return My(0, e, i), i + } + + function Ly(e, a, o, l, d, u) { + var r = (null == l ? void 0 : l.maxHdcpLevel) || void 0; + let c = [...e]; + (0 < d.disableVideoCodecList.size || 0 < d.disableAudioCodecList.size) && (c = function(e, t, i) { + let r = e.filter(e => !e.videoCodec || e.videoCodecList.every(e => { + e = qp(e); + return !t.has(e) + })); + return r = r.filter(e => !(!e.iframes && e.audioCodec) || e.audioCodecList.every(e => { + e = jp(e); + return !i.has(e) + })), My(0, e, r), r + }(c, d.disableVideoCodecList, d.disableAudioCodecList)), r && dm(r) && (c = function(e) { + const t = um(r), + i = e.filter(e => { + e = e.hdcpLevel; + return !e || um(e) <= t + }); + return My(0, e, i), i + }(c)); + var t = null == l ? void 0 : l.maxSecurityLevel, + e = null == d ? void 0 : d.keySystemPreference; + t && e && Ay(t, e) && (c = function(e, t, i) { + function r(e) { + return Ay(e, i) ? n[e] : -1 + } + const n = Ah.getKeySystemSecurityLevel(i), + s = Ah.getKeySystemFormat(i), + a = r(t), + o = e.filter(e => { + e = null !== (e = null === (e = e.allowedCPCMap) || void 0 === e ? void 0 : e[s]) && void 0 !== e ? e : []; + let t = !0; + for (const i of e) + if (t = r(i) <= a, !t) break; + return t + }); + return My(0, e, o), [...o] + }(c, t, e)), c = c.map(t => { + var e; + return t.audioCodecList && t.audioGroupId && ((e = null == (e = a.find(e => e.groupId === t.audioGroupId)) ? void 0 : e.channels) && (t.audioChannelCount = parseInt(e))), t + }); + const h = !(null == d || !d.useMediaKeySystemAccessFilter) && e && navigator && "function" == typeof navigator.requestMediaKeySystemAccess; + return (h ? xy(c, e, u) : $i(c)).pipe(La(e => { + if (0 === e.length || Oy(e)) throw new R(L, f, void 0, "no media option with compatible codecs found in playlist", void 0); + h && My(0, c, e); + const t = navigator && navigator.mediaCapabilities, + n = !(null == d || !d.useMediaCapabilities) && t && "function" == typeof t.decodingInfo; + let i; + return i = n ? function(e, n, s) { + const a = [], + o = Cy(), + l = function(o) { + const l = new Map, + d = navigator && navigator.mediaCapabilities; + return (i, e, t, n, r) => { + const s = { + type: "media-source" + }; + n ? s.video = function(e) { + const t = { + contentType: `video/mp4;codecs=${e}`, + width: i.width, + height: i.height, + bitrate: i.bandwidth || i.avgBandwidth, + framerate: i.iframes ? 8 : i.frameRate + }; + if (i.videoRange) switch (i.videoRange) { + case "PQ": + be.isDolby(e) ? (t.hdrMetadataType = Pm.DoVi, t.colorGamut = "rec2020") : (be.isHEVC(e) || be.isVP09(e)) && (t.hdrMetadataType = Pm.HDR10, t.colorGamut = "rec2020"), t.transferFunction = "pq"; + break; + case "HLG": + t.colorGamut = "rec2020", t.transferFunction = "hlg" + } + return t + }(t) : s.audio = function(e, t, i) { + const r = { + contentType: `audio/mp4;codecs=${e}` + }, + n = fm.getRichestChannelLayoutForGroupId(t.audioGroupId, i); + return n && (r.channels = be.getChannelCount(n).toString(), r.spatialRendering = be.isDolbyAtmos(e, n)), r + }(t, i, e); + e = JSON.stringify(s); + let a; + return l.has(e) ? a = l.get(e) : (a = Fr(d.decodingInfo(s)).pipe(hr(e => { + const t = e.configuration || e.supportedConfiguration, + i = t instanceof Object && (!s.video || null == Object.keys(s.video).find(e => !(e in t.video))) && (!s.audio || null == Object.keys(s.audio).find(e => !(e in t.audio))), + r = e.supported && (!n || e.powerEfficient) && i; + return r || o.warn(wy, `Unsupported config ${e.supported}/${e.powerEfficient}/${i} ${JSON.stringify(s)} supportedConfig=${JSON.stringify(t)}`), r + })), l.set(e, a)), [...r, a] + } + }(s); + return e.forEach(t => { + var e; + let i = []; + if (null === (e = t.videoCodecList) || void 0 === e || e.forEach(e => { + i = l(t, n, e, !0, i) + }), 0 < (null === (e = t.audioCodecList) || void 0 === e ? void 0 : e.length)) { + const s = fm.getRichestAudioCodec(t.audioCodecList); + i = l(t, n, s, !1, i) + } + let r = $i(t); + 0 < i.length && (r = en(i).pipe(hr(e => null == e.find(e => !1 === e) ? t : null), Vn(e => (s.warn(wy, `decodingInfo errror: ${e.message}`), $i(o(t) ? t : null))))), a.push(r) + }), en(a).pipe(hr(e => e.filter(e => Boolean(e)))) + }(e, a, u) : $i(e = Py((r = e, s = Cy(), s = r.filter(s), My(0, r, s), e = s), a)), i.pipe(hr(e => { + if (0 === e.length || Oy(e)) throw new R(L, f, void 0, "no media option with compatible codecs found in manifest", void 0); + if (0 === (t = e = Ry(e, o, l), r = t.filter(e => !e.iframes || !e.width || !e.height || e.width * e.height <= 2488320), My(0, t, r), (e = r).length) || Oy(e)) throw new R(L, f, void 0, "no media option with compatible codecs found in manifest", void 0); + var t; + let i = (null == l ? void 0 : l.videoDynamicRangeFormats) || []; + n && 0 === i.length && (i = [{ + type: fe.SDR + }, { + type: fe.HDR + }, { + type: fe.HDR10 + }, { + type: fe.DolbyVision + }, { + type: fe.HLG + }]); + var { + hdrMediaOptions: r, + sdrMediaOptions: e + } = function(e, t) { + const i = t.reduce((e, t) => { + switch (t.type) { + case fe.DolbyVision: + e.doViSupported = !0; + break; + case fe.HDR10: + e.hdr10Supported = !0; + break; + case fe.HLG: + e.hlgSupported = !0 + } + return e + }, { + doViSupported: !1, + hdr10Supported: !1, + hlgSupported: !1 + }), + { + doViSupported: r, + hdr10Supported: n, + hlgSupported: s + } = i; + return e.reduce((e, t) => { + var i; + switch (be.getDynamicRangeType(t.videoRange, null !== (i = t.videoCodec) && void 0 !== i ? i : "")) { + case fe.HDR: + case fe.HDR10: + n && e.hdrMediaOptions.push(t); + break; + case fe.DolbyVision: + r && e.hdrMediaOptions.push(t); + break; + case fe.HLG: + s && e.hdrMediaOptions.push(t); + break; + default: + "SDR" !== t.videoRange && null != t.videoRange || e.sdrMediaOptions.push(t) + } + return e + }, { + hdrMediaOptions: new Array, + sdrMediaOptions: new Array + }) + }(e, i); + if (0 === r.length && 0 === e.length || Oy(r) && Oy(e)) throw new R(L, "manifestIncompatibleVideoRangeError", void 0, "mediaOption with compatible VIDEO-RANGE not found in manifest", void 0); + return { + hdrMediaOptions: r, + sdrMediaOptions: e + } + }), Vn(e => { + throw e instanceof R && (e.fatal = !0, e.response = $.IncompatibleAsset), e + })); + var r, s + })) + } + + function _y(e, t) { + return t.mediaOptionId !== e.mediaOptionId && t.persistentID === e.persistentID && t.groupId !== e.groupId + }(A = Pm = Pm || {}).HDR10 = "smpteSt2086", A.DoVi = "smpteSt2094-10", A.HDR10Plus = "smpteSt2094-40"; + class Ny extends jm { + constructor(e, t, i) { + super(e, t, i) + } + static makeFilters() { + return Hm() + } + _initFilters() { + return Ny.kAllowFilters + } + get _mediaOptionType() { + return this.mediaOptionType + } + get preferredHost() { + return null + } + get preferredHost$() { + return $i(null) + } + get mediaOptionListInfo() { + var e; + return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.mediaOptionListTuple[this._mediaOptionType]) && void 0 !== e ? e : null + } + get mediaOptionListInfo$() { + return this.selectEntity(this.itemId, e => e && e.mediaOptionListTuple ? e.mediaOptionListTuple[this._mediaOptionType] : null).pipe(Kp()) + } + getFallbackVariant(t, e, i, r) { + var n; + const s = null === (n = this.mediaOptionList) || void 0 === n ? void 0 : n.find(e => e.mediaOptionId === t); + if (!s) return null; + const a = this.filteredMediaOptionList; + if (!a) return null; + const o = Eu(s.url); + if (i) return null !== (i = a.find(e => _y(s, e) && !Au(o, e.url))) && void 0 !== i ? i : null; + let l = null; + for (const t of a) !_y(s, t) || l && !Au(o, t.url) || (l = t); + return l + } + getMatchingAlternateWithPersistentId(t, i, r) { + var e; + return null !== (e = this.preferredMediaOptionList.find(e => !(0 < (null == r ? void 0 : r.length) && r.includes(e.mediaOptionId)) && (!ne(t) || e.persistentID === t) && (!i || this.matchGroup(e, i.audioGroupId, i.subtitleGroupId, i.closedcaption)))) && void 0 !== e ? e : null + } + matchGroup(e, t, i, r) { + let n = !1; + switch (e.type) { + case "CLOSED-CAPTIONS": + n = !r || e.groupId === r; + break; + case "SUBTITLES": + n = !i || e.groupId === i; + break; + case "AUDIO": + n = !t || e.groupId === t + } + return n + } + getMatchingAlternate(e, t) { + e = this.mediaOptionFromId(e); + return this.getMatchingAlternateWithPersistentId(null == e ? void 0 : e.persistentID, t, []) + } + packageAlternateMediaOption(e, t, i) { + return t.mediaType === Su.CLOSEDCAPTION ? this.augmentClosedCaptionsWithForcedSubtitles(null == e ? void 0 : e.subtitleGroupId, t, i) : t + } + augmentClosedCaptionsWithForcedSubtitles(e, t, i) { + i = this.pairForcedSubtitleMediaOptionWithClosedCaption(e, t, i); + return i ? Object.assign(Object.assign({}, t), { + url: i.url, + backingMediaOptionId: i.mediaOptionId + }) : t + } + pairForcedSubtitleMediaOptionWithClosedCaption(t, i, r) { + let n; + if (i && i.mediaType === Su.CLOSEDCAPTION) { + let e = this.mediaOptionList; + r && (e = this.preferredMediaOptionList), n = Ny.pairForcedSubtitleMediaOptionWithClosedCaptionInList(t, i, e) + } + return n + } + static pairForcedSubtitleMediaOptionWithClosedCaptionInList(t, i, e) { + return e.find(function(e) { + return e.mediaType === Su.SUBTITLE && e.lang === i.lang && e.forced && e.autoselect && (!t || e.groupId === t) + }) + } + } + Ny.kAllowFilters = Ny.makeFilters(); + class Fy extends kl { + constructor(e, t) { + super(e), this.itemId = t, this.mediaOptionListQueries = [new Xm(e, this.itemId), new Ny(e, this.itemId, gu.AltAudio), new Ny(e, this.itemId, gu.Subtitle)] + } + get rootPlaylistEntity() { + return this.getEntity(this.itemId) + } + get rootMediaOptionsTuple() { + var e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.mediaOptionListTuple; + return e ? [e[0].mediaOptions, e[1].mediaOptions, e[2].mediaOptions] : [ + [], + [], + [] + ] + } + get itemStartOffset() { + var e, t; + return null !== (e = this.rootPlaylistEntity) && void 0 !== e && e.itemStartOffset && ne(null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.itemStartOffset) ? null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.itemStartOffset : 0 + } + get highestVideoCodec() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.highestVideoCodec + } + get baseUrl() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.baseUrl + } + get anchorTime() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.anchorTime + } + get discoSeqNum() { + var e; + return null !== (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.discoSeqNum) && void 0 !== e ? e : NaN + } + get discoSeqNum$() { + return this.selectEntity(this.itemId, "discoSeqNum") + } + get audioMediaSelectionGroup() { + var e; + return null !== (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.audioMediaSelectionGroup) && void 0 !== e ? e : null + } + get subtitleMediaSelectionGroup() { + var e; + return null !== (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.subtitleMediaSelectionGroup) && void 0 !== e ? e : null + } + get audioMediaSelectionOptions() { + var e; + return null !== (e = null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.audioMediaSelectionGroup) || void 0 === e ? void 0 : e.MediaSelectionGroupOptions) && void 0 !== e ? e : [] + } + get subtitleMediaSelectionOptions() { + var e; + return null !== (e = null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.subtitleMediaSelectionGroup) || void 0 === e ? void 0 : e.MediaSelectionGroupOptions) && void 0 !== e ? e : [] + } + get contentSteeringOption() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.contentSteeringOption + } + get masterVariableList() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.masterVariableList + } + get loadStats() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.loadStats + } + get isMediaPlaylist() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.isMediaPlaylist + } + getInitPTS(e) { + var t; + return null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.initPtsRecord[e] + } + get abrStatus$() { + return this.selectEntity(this.itemId, e => null == e ? void 0 : e.abrStatus) + } + get abrStatus() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.abrStatus + } + get nextMaxAutoOptionId() { + var e; + return null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.abrStatus) || void 0 === e ? void 0 : e.nextMaxAutoOptionId + } + get nextMinAutoOptionId() { + var e; + return null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.abrStatus) || void 0 === e ? void 0 : e.nextMinAutoOptionId + } + initPTS$(t) { + return this.selectEntity(this.itemId, ({ + initPtsRecord: e + }) => e[t]) + } + get rootPlaylistEntity$() { + return this.selectEntity(this.itemId).pipe(ln(e => Boolean(e)), hr(e => e)) + } + get rootPlaylistEntityAdded$() { + return this.selectEntityAction(Eo.Add).pipe(hr(e => e.map(e => this.getEntity(e)))) + } + get rootMediaOptionsTuple$() { + return ed([this.selectEntity(this.itemId, e => e.mediaOptionListTuple[0].mediaOptions), this.selectEntity(this.itemId, e => e.mediaOptionListTuple[1].mediaOptions), this.selectEntity(this.itemId, e => e.mediaOptionListTuple[2].mediaOptions)]) + } + get sessionData() { + var e; + return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.sessionData + } + get sessionData$() { + return this.selectEntity(this.itemId, ({ + sessionData: e + }) => e).pipe(Kp()) + } + get anchorTime$() { + return this.selectEntity(this.itemId, "anchorTime").pipe(La(e => { + var t; + return ne(null == e ? void 0 : e.pos) ? (null == e ? void 0 : e.pos) !== (null === (t = this.anchorTime) || void 0 === t ? void 0 : t.pos) ? (Qe().warn(`anchorTime doesn't match stored value! ${null==e?void 0:e.pos} !== ${null===(t=this.anchorTime)||void 0===t?void 0:t.pos}`), Ii) : $i(e) : Ii + })) + } + get pendingSeek$() { + return this.selectEntity(this.itemId, ({ + pendingSeek: e + }) => e).pipe(Is((e, t) => e === t || "number" == typeof e && "number" == typeof t && isNaN(e) && isNaN(t))) + } + get enabledMediaOptionKeys$() { + return this.selectEntity(this.itemId, "enabledMediaOptionKeys").pipe(ln(e => Boolean(e))) + } + get enabledMediaOptionKeys() { + var e; + return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.enabledMediaOptionKeys) && void 0 !== e ? e : [Lu, Lu, Lu] + } + get enabledMediaOptionSwitchContexts() { + var e; + return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.mediaOptionSwitchContexts) && void 0 !== e ? e : [null, null, null] + } + enabledMediaOptionSwitchContextsByType$(t) { + return this.selectEntity(this.itemId, "mediaOptionSwitchContexts").pipe(hr(e => null == e ? void 0 : e[t])) + } + get enabledMediaOptions$() { + return ed([this.enabledMediaOptionByType$(gu.Variant), this.enabledMediaOptionByType$(gu.AltAudio), this.enabledMediaOptionByType$(gu.Subtitle)]) + } + get enabledAVOptions$() { + return ed([this.enabledMediaOptionByType$(gu.Variant), this.enabledMediaOptionByType$(gu.AltAudio)]) + } + rawEnabledMediaOptionByType$(t) { + return this.enabledMediaOptionKeys$.pipe(hr(e => { + const i = e[t]; + return _u(i) && this.rootMediaOptionsTuple[t].find(e => { + return t = i, e.itemId === t.itemId && e.mediaOptionId === t.mediaOptionId; + var t + }) || Lu + })) + } + enabledMediaOptionByType$(e) { + return this.rawEnabledMediaOptionByType$(e).pipe(Is((e, t) => e.mediaOptionId === t.mediaOptionId && e.url === t.url)) + } + enabledMediaOptionSwitchForType$(e) { + return this.rawEnabledMediaOptionByType$(e).pipe(bo(this.enabledMediaOptionSwitchContextsByType$(e)), Ra(null), ha(), hr(([e, t]) => ({ + fromId: null == e ? void 0 : e[0].mediaOptionId, + toId: null == t ? void 0 : t[0].mediaOptionId, + switchContext: null == t ? void 0 : t[1] + })), Is((e, t) => e.fromId === t.fromId && e.toId === t.toId)) + } + enableMediaOptionSwitchedForType$(t) { + return this.enabledMediaOptionByType$(t).pipe(La(e => Gu(Mr([$i(e), this.enabledMediaOptionSwitchContextsByType$(t).pipe(ha())]), ([, e]) => e[0] && !e[1])), hr(([e]) => e)) + } + enabledMediaOptionIdByType(e) { + return this.getEntity(this.itemId).enabledMediaOptionKeys[e].mediaOptionId + } + get enabledVariantMediaOptionIdBeforeTrickplaySwitch() { + return this.getEntity(this.itemId).enabledVariantMediaOptionIdBeforeTrickplaySwitch + } + variantMediaOptionById(e) { + return this.mediaOptionListQueries[gu.Variant].mediaOptionFromId(e) + } + alternateMediaOptionById(e, t) { + return this.mediaOptionListQueries[e].mediaOptionFromId(t) + } + enabledAlternateMediaOptionByType(e) { + var t = this.enabledMediaOptionIdByType(e); + return this.alternateMediaOptionById(e, t) + } + get enabledVariantMediaOption() { + var e = this.enabledMediaOptionIdByType(gu.Variant); + return this.variantMediaOptionById(e) + } + lastLoadedMediaOptionByType(e) { + var t; + return null === (t = this.getEntity(this.itemId).lastLoadedMediaOptionKeys) || void 0 === t ? void 0 : t[e] + } + get nextMediaOptionsKeys$() { + return this.selectEntity(this.itemId, "nextMediaOptionKeys") + } + get preferredMediaOptions() { + return [this.mediaOptionListQueries[0].preferredMediaOptionList, this.mediaOptionListQueries[1].preferredMediaOptionList, this.mediaOptionListQueries[2].preferredMediaOptionList] + } + get preferredMediaOptions$() { + return ed([this.mediaOptionListQueries[0].preferredMediaOptionList$, this.mediaOptionListQueries[1].preferredMediaOptionList$, this.mediaOptionListQueries[2].preferredMediaOptionList$]) + } + get filteredMediaOptions() { + return [this.mediaOptionListQueries[0].filteredMediaOptionList, this.mediaOptionListQueries[1].filteredMediaOptionList, this.mediaOptionListQueries[2].filteredMediaOptionList] + } + getDisabledMediaOption(e) { + return { + itemId: this.itemId, + mediaOptionType: e, + mediaOptionId: "Nah" + } + } + getEnabledMediaOptionMask() { + return this.enabledMediaOptionKeys.map(e => _u(e)) + } + getPreferredMediaOptionsByType$(e) { + return this.mediaOptionListQueries[e].preferredMediaOptionList$ + } + altMediaOptionHasValidUrl(e, t) { + t = this.alternateMediaOptionById(e, t); + return Boolean(null == t ? void 0 : t.url) + } + get hdrMode$() { + return this.mediaOptionListQueries[gu.Variant].hdrMode$ + } + get maxHdcpLevel$() { + return this.mediaOptionListQueries[gu.Variant].maxHdcpLevel$ + } + get currentPathwayID() { + return this.mediaOptionListQueries[gu.Variant].currentPathwayID + } + get preferredHost() { + return this.mediaOptionListQueries[gu.Variant].preferredHost + } + getErrorInfoByType(e) { + var t; + return null != (null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.errorsByType) ? this.rootPlaylistEntity.errorsByType[e] : null + } + getInFlightFragByType(e) { + var t; + return null !== (e = null === (t = null === (t = this.getEntity(this.itemId)) || void 0 === t ? void 0 : t.inFlightFrags) || void 0 === t ? void 0 : t[e]) && void 0 !== e ? e : null + } + getInFlightFragByType$(t) { + return this.selectEntity(this.itemId, e => { + return null === (e = null == e ? void 0 : e.inFlightFrags) || void 0 === e ? void 0 : e[t] + }) + } + matchAlternates(e, t, i, r) { + t = ne(t) ? this.mediaOptionListQueries[gu.AltAudio].getMatchingAlternateWithPersistentId(t, e, r) : void 0, r = ne(i) ? this.mediaOptionListQueries[gu.Subtitle].getMatchingAlternateWithPersistentId(i, e, r) : void 0; + return [t || Lu, r || Lu] + } + getLegacyMatchingAlternateWithPersistentId(e, t, i) { + let r = this.mediaOptionListQueries[e].getMatchingAlternateWithPersistentId(t, i, []); + return r = r || this.mediaOptionListQueries[e].getMatchingAlternateWithPersistentId(t, void 0, []), r + } + isValidMediaOptionTuple(i, e) { + const r = e || this.getEnabledMediaOptionMask(); + return [gu.Variant, gu.AltAudio, gu.Subtitle].reduce((e, t) => e && r[t] === _u(i[t]), !0) + } + matchGroup(e, t, i, r) { + var n = e.mediaOptionType; + return this.mediaOptionListQueries[n].matchGroup(e, t, i, r) + } + get preferHDR() { + return this.mediaOptionListQueries[gu.Variant].mediaOptionListInfo.preferHDR + } + } + const By = { + name: "rps" + }; + class Uy { + constructor(e, t) { + this.store = e, this.logger = t + } + getQuery() { + return new kl(this.store) + } + getQueryForId(e) { + return new Fy(this.store, e) + } + set rootPlaylistEntity(e) { + Do("root.add.rootPlaylist"), this.store.add(e) + } + removeItems(e) { + Do(`root.add.remove ${JSON.stringify(e)}`), this.store.remove(e) + } + removeAll() { + Do("root.add.clear"), this.store.remove() + } + setRootPlaylistEntity(e, t) { + Do("root.set.rootPlaylistEntity"), this.store.update(e, e => t) + } + setSessionData(e, t) { + Do("root.set.sessionData"), this.store.update(e, e => { + e.sessionData = t + }) + } + setAnchorTime(e, t) { + Do(`root.set.anchorTime: ${null==t?void 0:t.pos} ${null==t?void 0:t.discoSeqNum}`), this.store.update(e, e => { + e.anchorTime = t + }) + } + setDiscoSeqNum(e, t) { + Do(`root.set.discoSeqNum: ${t}`), this.store.update(e, e => { + e.discoSeqNum = t + }) + } + setPendingSeek(e, t) { + Do("root.set.pendingSeek"), this.store.update(e, e => { + e.pendingSeek = t + }), void 0 === t && fg().setUserSeek(t) + } + setEnabledMediaOptionSwitchContextByType(e, i, r, n) { + this.store.update(e, e => { + var t; + if (e.enabledMediaOptionKeys[i].mediaOptionId === r) { + const r = null !== (t = e.mediaOptionSwitchContexts) && void 0 !== t ? t : [null, null, null]; + r[i] = n ? { + userInitiated: n.userInitiated, + switchPosition: n.switchPosition + } : null, e.mediaOptionSwitchContexts = r + } else Do(`root.set.mediaOptionSwitchContextByType ${r} doesn't match existing mediaOption ${e.enabledMediaOptionKeys[i].mediaOptionId}`) + }) + } + setEnabledVariantMediaOptionIdBeforeTrickplaySwitch(e, t) { + this.store.update(e, e => { + e.enabledVariantMediaOptionIdBeforeTrickplaySwitch = t + }) + } + setEnabledMediaOptionByType(r, n, s, a = !1, o) { + s = s || { + itemId: r, + mediaOptionType: n, + mediaOptionId: "Nah" + }, this.store.update(r, e => { + var t; + const i = null !== (t = [...e.enabledMediaOptionKeys]) ? t : [Lu, Lu, Lu]; + if (i[n] = { + itemId: r, + mediaOptionId: s.mediaOptionId + }, this._updateEnabledMediaOptionKeys(e, i), a) { + const r = null !== (t = e.mediaOptionSwitchContexts) && void 0 !== t ? t : [null, null, null]; + r[n] = o ? { + userInitiated: o.userInitiated, + switchPosition: o.switchPosition + } : null, e.mediaOptionSwitchContexts = r + } + }) + } + _associateForcedSubtitleWithClosedCaption(e, t, i, r) { + if ((null == i ? void 0 : i.mediaType) === Su.CLOSEDCAPTION) { + t = r.variantMediaOptionById(t), r = r.mediaOptionListQueries[gu.Subtitle].packageAlternateMediaOption(t, i, !0); + if (r.url !== i.url) { + const n = jy(t, r, e.mediaOptionListTuple[gu.Subtitle].mediaOptions, Qe()); + e.mediaOptionListTuple[gu.Subtitle].mediaOptions = n + } + } + } + _updateEnabledMediaOptionKeys(t, i) { + var e, r; + const n = null !== (e = t.enabledMediaOptionKeys) && void 0 !== e ? e : [Lu, Lu, Lu]; + let s; + for (let e = 0; e < i.length; ++e) { + var a = i[e], + o = n[e].mediaOptionId !== a.mediaOptionId; + if (o && (n[e] = Object.assign({}, a)), e === gu.Variant) { + const i = this.getQueryForId(a.itemId).mediaOptionListQueries[e].mediaOptionList; + o ? t.abrStatus = (r = a.mediaOptionId, o = i, o = Xg(r, o), { + fragDownloadSlow: !1, + fragDownloadTooSlow: !1, + nextMinAutoOptionId: Lu.mediaOptionId, + nextMaxAutoOptionId: Lu.mediaOptionId, + highBWTrigger: o + }) : t.abrStatus.highBWTrigger = Xg(a.mediaOptionId, i), s = a + } else if (e === gu.Subtitle && _u(a)) { + const i = this.getQueryForId(a.itemId), + n = i.alternateMediaOptionById(e, a.mediaOptionId); + this._associateForcedSubtitleWithClosedCaption(t, s.mediaOptionId, n, i) + } + } + t.enabledMediaOptionKeys = n, t.nextMediaOptionKeys = void 0 + } + setManualMode(e, t) { + this.store.update(e, e => { + e.manualMode = t + }) + } + setEnabledMediaOptions(e, i) { + this.store.update(e, e => { + var t = i.map(({ + mediaOptionId: e, + itemId: t + }) => ({ + mediaOptionId: e, + itemId: t + })); + this._updateEnabledMediaOptionKeys(e, t) + }) + } + setEnabledMediaOptionsAndSwitchContexts(e, i, r) { + this.store.update(e, e => { + var t = i.map(({ + mediaOptionId: e, + itemId: t + }) => ({ + mediaOptionId: e, + itemId: t + })); + this._updateEnabledMediaOptionKeys(e, t), e.mediaOptionSwitchContexts = r + }) + } + setNextMediaOptions(e, i) { + Do(`root.set.nextMediaOptions: ${JSON.stringify(null==i?void 0:i.map(e=>e.mediaOptionId))}`), this.store.update(e, e => { + var t = i ? i.map(({ + itemId: e, + mediaOptionId: t + }) => ({ + itemId: e, + mediaOptionId: t + })) : null; + e.nextMediaOptionKeys = t + }) + } + updateEnabledMediaOptions(e) { + Do("root.set.updateEnabledMediaOptions"), this.store.update(e, e => { + e.nextMediaOptionKeys && !0 !== e.manualMode && (Do(`root.set.updateEnabledMediaOptions ${JSON.stringify(e.nextMediaOptionKeys)}`), this._updateEnabledMediaOptionKeys(e, [...e.nextMediaOptionKeys])), e.nextMediaOptionKeys = void 0 + }) + } + setLastLoadedMediaOptionByType(r, n, s) { + Do(`root.set.lastLoadedMediaOptionByType: ${n} ${(s=s||{itemId:r,mediaOptionType:n,mediaOptionId:"Nah"}).mediaOptionId}`), this.store.update(r, e => { + var t; + const i = null !== (t = e.lastLoadedMediaOptionKeys) && void 0 !== t ? t : [Lu, Lu, Lu]; + i[n] = { + itemId: r, + mediaOptionId: s.mediaOptionId + }, e.lastLoadedMediaOptionKeys = i + }) + } + setPreferredHost(e, t) { + Do(`root.set.preferredHost: ${t}`), this.store.update(e, e => { + e && (e.mediaOptionListTuple[gu.Variant].preferredHost = t) + }) + } + setViewportInfo(e, t) { + Do(`root.set.viewportInfo: ${JSON.stringify(t)}`), this.store.update(e, e => { + e && (e.mediaOptionListTuple[gu.Variant].viewportInfo = t) + }) + } + static getExistingPersistentIds(e) { + var t; + const i = {}, + r = null === (t = e.enabledMediaOptionKeys[gu.AltAudio]) || void 0 === t ? void 0 : t.mediaOptionId; + if ("Nah" !== r) { + const s = e.mediaOptionListTuple[gu.AltAudio], + t = Km(s.mediaOptions, Ny.kAllowFilters, s).find(e => e.mediaOptionId === r); + i.audioPersistentId = null == t ? void 0 : t.persistentID + } + const n = null === (t = e.enabledMediaOptionKeys[gu.Subtitle]) || void 0 === t ? void 0 : t.mediaOptionId; + if ("Nah" !== n) { + const s = e.mediaOptionListTuple[gu.Subtitle], + t = Km(s.mediaOptions, Ny.kAllowFilters, s).find(e => e.mediaOptionId === n); + i.subtitlePersistentId = null == t ? void 0 : t.persistentID + } + return i + } + static doUpdateRootHDRSwitch(e, t, i, r) { + const n = e.mediaOptionListTuple.map(e => Object.assign({}, e)); + n[gu.Variant].preferHDR = t, n[gu.Variant].hasHdrLevels = i; + const s = mg(), + a = sy.getEntity(e.itemId), + o = Zf(e.itemId), + l = o.getBandwidthEstimate(s, null == a ? void 0 : a.serviceName), + d = o.getPlaylistEstimate(s, null == a ? void 0 : a.serviceName), + u = o.getFragEstimate(s, null == a ? void 0 : a.serviceName), + c = o.getBufferEstimate(s, null == a ? void 0 : a.serviceName), + h = { + targetDuration: u.maxDurationSec || (null == s ? void 0 : s.defaultTargetDuration), + targetStartupMs: null == s ? void 0 : s.targetStartupMs + }, + p = Uy.getExistingPersistentIds(e); + return Qy(Object.assign(Object.assign({}, e), { + mediaOptionListTuple: n, + nextMediaOptionKeys: null + }), p, r, l, h, d, u, c) + } + switchToSDROnly(e) { + Do("root.switchToSDROnly"), this.store.update(e, e => { + var t = Uy.doUpdateRootHDRSwitch(e, !1, !1, this.logger)["mediaOptionListTuple"]; + e.mediaOptionListTuple = t + }) + } + setHDRPreference(e, i, r) { + Do(`root.set.HDRPreference: ${i}`), this.store.update(e, e => { + var t = e.mediaOptionListTuple[gu.Variant]; + if (t.preferHDR !== i && (!i || t.hasHdrLevels)) { + t = Uy.doUpdateRootHDRSwitch(e, i, t.hasHdrLevels, this.logger); + if (r) return t; + e.mediaOptionListTuple = t.mediaOptionListTuple + } + }) + } + setPathwayPriority(e, i) { + Do(`root.set.PathwayPriority: [ ${i.join(", ")} ]`), this.store.update(e, e => { + if (e) { + const t = e.mediaOptionListTuple[gu.Variant]; + t.pathwayPriority = i, t.preferredHost = null + } + }) + } + setCurrentPathwayID(e, t) { + Do(`root.set.currentPathwayID: ${t}`), this.store.update(e, e => { + e && (e.mediaOptionListTuple[gu.Variant].currentPathwayID = t) + }) + } + setInitPTS(e, t, i, r, n, s) { + Do(`root.set.initPTS: ${e} ${t} variantDTS:${JSON.stringify(i)} timelineOffset: ${r}`), this.store.update(e, e => { + e.initPtsRecord[t] = { + variantDTS: i, + timelineOffset: r, + offsetTimestamp: n, + iframeMode: s + } + }) + } + static prunePenaltyBox(e, t) { + return e.filter(e => !(e.expiry <= t)) + } + static addToPenaltyBox(e, t, i) { + return e.push({ + mediaOptionId: i, + expiry: t + 12e4 + }) + } + addToPenaltyBox(e, r, n) { + Do(`root.set.penaltyBox: ${r}: ${n}`), this.store.update(e, ({ + mediaOptionListTuple: e + }) => { + const t = e[r], + i = performance.now(); + t.penaltyBoxQueue = Uy.prunePenaltyBox(t.penaltyBoxQueue, i), Uy.addToPenaltyBox(t.penaltyBoxQueue, i, n) + }) + } + prunePenaltyBox(e, r = null) { + Do(`root.set.prunePenaltyBox: ${r}`), this.store.update(e, ({ + mediaOptionListTuple: e + }) => { + var e = r ? [e[r]] : e, + t = performance.now(); + for (const i of e) i.penaltyBoxQueue = Uy.prunePenaltyBox(i.penaltyBoxQueue, t) + }) + } + removePermanently(e, r, n) { + Do(`root.set.removePermanently: ${r}: ${n}`), this.store.update(e, ({ + mediaOptionListTuple: e + }) => { + const t = e[r], + i = new Set(t.removed); + i.add(n), t.removed = Array.from(i) + }) + } + moveAllWithMatchingHosts(e, r, n, s) { + Do(`root.set.moveAllMatchingHosts: ${r}:${n} remove:${s}`), this.store.update(e, ({ + mediaOptionListTuple: e + }) => { + const t = e[r], + i = [...t.mediaOptions].filter(e => Au(n, e.url)).map(e => e.mediaOptionId); + if (s) { + const e = new Set([...t.removed, ...i]); + t.removed = Array.from(e) + } else { + const e = performance.now(); + t.penaltyBoxQueue = Uy.prunePenaltyBox(t.penaltyBoxQueue, e); + for (const r of i) Uy.addToPenaltyBox(t.penaltyBoxQueue, e, r) + } + }) + } + setMaxHdcpLevel(e, i, r = !1) { + Do(`root.set.maxHdcpLevel: ${i}`), this.store.update(e, ({ + mediaOptionListTuple: e + }) => { + const t = e[gu.Variant]; + (r || um(i) < um(t.maxHdcpLevel)) && (t.maxHdcpLevel = i) + }) + } + updateConsecutiveTimeouts(e, i, r, n) { + this.store.update(e, e => { + const t = e.errorsByType || [{ + timeouts: { + load: 0, + append: 0, + key: 0 + } + }, { + timeouts: { + load: 0, + append: 0, + key: 0 + } + }, { + timeouts: { + load: 0, + append: 0, + key: 0 + } + }]; + r ? ++t[i].timeouts[n] : t[i].timeouts[n] = 0, e.errorsByType = t + }) + } + updateInflightFrag(l, d, u, c, h) { + Do("root.set.updateInflightFrag"), this.store.update(l, r => { + if (r.inFlightFrags || (r.inFlightFrags = [null, null]), !(d === gu.Subtitle || u && u.itemId !== l)) + if (u) { + let { + start: e, + duration: t + } = u; + var { + mediaOptionId: n, + mediaSeqNum: s, + discoSeqNum: a + } = u, o = r.inFlightFrags[d]; + let i = null == o ? void 0 : o.tstart; + c !== (null == o ? void 0 : o.state) && (i = performance.now()), $p(o, u) && (e = o.start, t = o.duration), r.inFlightFrags[d] = { + itemId: l, + mediaOptionId: n, + mediaSeqNum: s, + discoSeqNum: a, + start: e, + duration: t, + tstart: i, + state: c, + bwSample: Object.assign({}, h) + } + } else r.inFlightFrags[d] = null + }) + } + setNextMaxAutoOptionId(e, t) { + Do(`root.set.nextMaxAutoOptionId: ${t}`), this.store.update(e, ({ + abrStatus: e + }) => { + e.nextMaxAutoOptionId = t + }) + } + setNextMinAutoOptionId(e, t) { + Do(`root.set.nextMinAutoOptionId: ${t}`), this.store.update(e, ({ + abrStatus: e + }) => { + e.nextMinAutoOptionId = t + }) + } + setHighBWTrigger(e, t) { + Do(`root.set.setHighBWTrigger: ${t}`), this.store.update(e, ({ + abrStatus: e + }) => { + e.highBWTrigger = t + }) + } + setFragLoadSlow(e, t) { + Do(`root.set.setFragLoadSlow ${e} ${JSON.stringify(t)}`), this.store.update(e, ({ + abrStatus: e + }) => { + e.fragDownloadSlow = t.fragDownloadSlow, e.fragDownloadTooSlow = t.fragDownloadTooSlow + }) + } + pickMediaOptionTupleByPersistentId(e, t, i, r = !1, n = !1) { + var s = e.enabledMediaOptionIdByType(gu.Variant), + s = e.variantMediaOptionById(s); + let a, o; + if (t === gu.AltAudio) { + const t = e.enabledAlternateMediaOptionByType(gu.Subtitle); + o = null == t ? void 0 : t.persistentID, a = i + } else { + const t = e.enabledAlternateMediaOptionByType(gu.AltAudio); + a = null == t ? void 0 : t.persistentID, o = i + } + const l = e.getEnabledMediaOptionMask(); + return l[t] = !!(ne(i) && 0 <= i), s ? this.getBestMediaOptionTupleFromVariantAndPersistentId(e, s, a, o, l, void 0, r, n, !1) : [Lu, Lu, Lu] + } + getFallbackMediaOptionTupleFromMediaOptionId(e, t, i, r, n = !1, s = !1, a = !1) { + var o = r ? [r] : [i], + l = e.enabledMediaOptionIdByType(gu.Variant), + r = e.variantMediaOptionById(l), + l = t === gu.AltAudio ? e.alternateMediaOptionById(gu.AltAudio, i) : e.enabledAlternateMediaOptionByType(gu.AltAudio), + l = null == l ? void 0 : l.persistentID, + i = t === gu.Subtitle ? e.alternateMediaOptionById(gu.Subtitle, i) : e.enabledAlternateMediaOptionByType(gu.Subtitle), + i = null == i ? void 0 : i.persistentID; + return r ? this.getBestMediaOptionTupleFromVariantAndPersistentId(e, r, l, i, void 0, o, n, s, a) : [Lu, Lu, Lu] + } + hasFallbackMediaOptionTuple(e, t, i, r) { + var n = e.mediaOptionListQueries[t].mediaOptionFromId(i); + return e.isValidMediaOptionTuple(this.getFallbackMediaOptionTupleFromMediaOptionId(e, t, i, n.backingMediaOptionId, !1, r)) + } + setLegacyAlternateMediaOption(e, t, i, r, n) { + var s = e.enabledMediaOptionIdByType(gu.Variant), + s = e.variantMediaOptionById(s), + s = e.getLegacyMatchingAlternateWithPersistentId(i, r, s); + s ? this.setEnabledMediaOptionByType(t, i, s, !0, n) : this.logger.warn(`${Nu[i]} can't find matching mediaOption for persistent id ${r}`) + } + setEnabledMediaOptionTupleWithMatchedGroups(t, i, e, r) { + const n = Ky(t), + s = this.pickMediaOptionTupleByPersistentId(n, i, e); + if (!n.isValidMediaOptionTuple(s)) return this.setLegacyAlternateMediaOption(n, t, i, e, r); + al(() => { + this.setEnabledMediaOptionByType(t, i, s[i], !0, r), s[gu.Variant].mediaOptionId !== n.enabledMediaOptionIdByType(gu.Variant) && this.setPreferredHost(t, Eu(s[gu.Variant].url)), this.setEnabledMediaOptionByType(t, gu.Variant, s[gu.Variant]); + var e = i === gu.AltAudio ? gu.Subtitle : gu.AltAudio; + s[e].mediaOptionId !== n.enabledMediaOptionIdByType(e) && this.setEnabledMediaOptionByType(t, e, s[e], !1) + }) + } + canSwitchToSDR(e, t, i, r = !1) { + var n = e.mediaOptionListQueries[gu.Variant].mediaOptionFromId(t), + r = this.getFallbackMediaOptionTupleFromMediaOptionId(e, gu.Variant, t, n.backingMediaOptionId, !0, i, r); + return e.isValidMediaOptionTuple(r) + } + getBestMediaOptionTupleFromVariantAndPersistentId(t, e, i, r, n, s, a, o, l) { + var d, u = t.mediaOptionListQueries[gu.Variant].listFallbackVariants(e.mediaOptionId, a, o, l, s); + let c = [Lu, Lu, Lu]; + for (let e = 0; e < u.length; ++e) { + const a = u[e]; + if (d = t.matchAlternates(a, i, r, s), t.isValidMediaOptionTuple([a, ...d], n)) { + c = [a, ...d]; + break + } + } + return c + } + } + const $y = new class extends fl { + constructor() { + super({}, { + name: "root-playlist-store", + idKey: "itemId", + producerFn: su + }) + } + akitaPreAddEntity(e) { + return null == e.errorsByType ? Object.assign(Object.assign({}, e), { + errorsByType: [{ + timeouts: { + load: 0, + append: 0, + key: 0 + } + }, { + timeouts: { + load: 0, + append: 0, + key: 0 + } + }, { + timeouts: { + load: 0, + append: 0, + key: 0 + } + }] + }) : e + } + }; + new kl($y); + let Vy = null; + + function Ky(e) { + return new Fy($y, e) + } + const qy = (n, e, t, s, i) => { + const { + rootMediaOptionsTuple: r, + sessionKeys: a + } = n, o = Array.from(r[gu.Variant]), l = Array.from(r[gu.AltAudio]); + let d = !1, + u = !1, + c = o.map(e => (d = d || Boolean(e.videoCodec), u = u || Boolean(e.audioCodec) || Boolean(e.audioGroupId), e)); + return d && u && (c = c.filter(({ + videoCodec: e + }) => Boolean(e))), Ly(o, l, a, e, t, i).pipe(hr(({ + hdrMediaOptions: e, + sdrMediaOptions: t + }) => { + var i = e.concat(t), + r = 0 < e.length; + return e.concat(t), + function(e, t, i, r) { + var { + itemId: n, + itemStartOffset: s, + rootMediaOptionsTuple: a, + audioMediaSelectionGroup: o, + subtitleMediaSelectionGroup: l + } = e, d = Array.from(a[gu.AltAudio]), u = Array.from(a[gu.Subtitle]), c = t.every(e => ne(e.score)), h = t.some(e => Wm(!0, e)), p = function(e, t) { + const i = [...e]; + return t ? i.sort((e, t) => e.score - t.score || t.bitrate - e.bitrate) : i.sort((e, t) => e.bitrate - t.bitrate), i + }(t, c), f = e.baseUrl, t = null === (a = e.contentSteeringOption) || void 0 === a ? void 0 : a.initPathwayID, a = e.sessionData; + return { + itemId: n, + baseUrl: f, + mediaOptionListTuple: [{ + mediaOptions: p, + hasHdrLevels: i, + hasIframeLevels: h, + hasScore: c, + preferHDR: r, + compatibleIds: null, + penaltyBoxQueue: [], + removed: [], + currentPathwayID: t + }, { + mediaOptions: d, + compatibleIds: null, + penaltyBoxQueue: [], + removed: [] + }, { + mediaOptions: u, + penaltyBoxQueue: [], + removed: [] + }], + audioMediaSelectionGroup: o, + subtitleMediaSelectionGroup: l, + enabledMediaOptionKeys: [Lu, Lu, Lu], + mediaOptionSwitchContexts: [null, null, null], + anchorTime: { + pos: 0 + }, + discoSeqNum: NaN, + pendingSeek: void 0, + itemStartOffset: s, + initPtsRecord: {}, + contentSteeringOption: e.contentSteeringOption, + masterVariableList: e.masterVariableList, + loadStats: e.stats, + isMediaPlaylist: e.isMediaPlaylist, + abrStatus: { + fragDownloadSlow: !1, + fragDownloadTooSlow: !1, + nextMinAutoOptionId: Lu.mediaOptionId, + nextMaxAutoOptionId: Lu.mediaOptionId, + highBWTrigger: NaN + }, + sessionData: a + } + }(n, i, r, s) + })) + }; + + function Hy(e, t, i, r, n, s, a) { + var o, l, d, u, c, h, p, f = e.mediaOptionListTuple[gu.Variant], + m = Km(f.mediaOptions, Xm.kAllowFilters, Object.assign(Object.assign({}, f), { + compatibleIds: null + })), + g = qm(f.preferredHost, m); + return { + firstVariant: (o = g, e = Fg, f = f.hasScore, t = t, i = i, r = r, n = n, s = s, a = a, !o || o.length < 1 || o.every(e => e.iframes) ? void t.warn("no non-iframe media option found") : ((o = f ? Bg(o, i, r, n, s, a) : (l = e, d = i, u = r, c = n, h = s, p = a, o.reduce((e, t) => { + if (t.iframes) return e; + let i = e; + const r = function(e, t, i, r, n, s, a) { + var o, l, d = (o = e.bitrate, u = e.height, (l = (e, t, i) => (e - t) * (e - i) <= 0)(o, t.minValidBitrate, t.maxValidBitrate) && l(u, t.minValidHeight, t.maxValidHeight) ? mu.VALID : mu.INVALID), + o = "PQ" === (c = e.videoRange) ? pu.PQ : "HLG" === c ? pu.HLG : "SDR" === c ? pu.SDR : pu.UNKNOWN, + { + videoCodecRank: u, + audioCodecRank: c + } = { + videoCodecRank: qp((l = e).videoCodec), + audioCodecRank: jp(l.audioCodec) + }, + l = e.bitrate < t.maxPreferredBitrate ? mu.VALID : mu.INVALID, + t = e.audioChannelCount || 1, + a = i && r && n && s && !Ug(e, i, r, n, s, a) ? mu.INVALID : mu.VALID; + return new Qp(d, o, u, t, c, a, l, e.height) + }(t, l, d, u, c, h, p); + return (!e || r.isGreaterThan(e.bestRank) || r.isEqualTo(e.bestRank) && t.bitrate > e.selected.bitrate) && (i = { + selected: t, + bestRank: r + }), i + }, null).selected)) || t.warn("no valid first media option found"), o)), + filteredVariants: m, + preferredVariants: g + } + } + + function jy(e, t, i) { + if ((null == t ? void 0 : t.mediaType) === Su.CLOSEDCAPTION) { + const r = Ny.pairForcedSubtitleMediaOptionWithClosedCaptionInList(e.subtitleGroupId, t, i); + if (r) return t = Object.assign(Object.assign({}, t), { + url: r.url, + backingMediaOptionId: r.mediaOptionId + }), i.map(e => e.mediaOptionId === t.mediaOptionId ? t : e) + } + return i + } + + function Qy(e, t, i, r, n, s, a, o) { + var l; + const d = e.itemId, + u = e.mediaOptionListTuple[gu.Variant], + c = e.mediaOptionListTuple[gu.AltAudio], + h = e.mediaOptionListTuple[gu.Subtitle], + p = Km(c.mediaOptions, Ny.kAllowFilters, c), + f = Km(h.mediaOptions, Ny.kAllowFilters, h); + let { + firstVariant: m, + filteredVariants: g + } = Hy(e, i, r, n, s, a, o); + if (!m) { + const U = u.preferHDR; + u.preferHDR = !U && u.hasHdrLevels, u.preferHDR !== U && (i.warn(`No valid first variant found, toggling hdr preference=${U}->${u.preferHDR}`), { + firstVariant: m, + filteredVariants: g + } = Hy(e, i, r, n, s, a, o)) + } + if (!m) throw new V(!0, "No valid first variant found", $.NoValidAlternates); + const y = Eu(m.url), + v = { + itemId: d, + mediaOptionId: null !== (o = null == m ? void 0 : m.mediaOptionId) && void 0 !== o ? o : null + }, + S = null != p && p.length ? null === (o = ((i, r, e, n) => { + if (e) { + let t; + return t = ne(i) ? e.MediaSelectionGroupOptions.find(function(e) { + return e.MediaSelectionOptionsPersistentID === i + }) : e.MediaSelectionGroupOptions.find(function(e) { + return e.MediaSelectionOptionsIsDefault + }), t = t || e.MediaSelectionGroupOptions[0], n.find(e => (!r || e.groupId === r) && e.persistentID === (null == t ? void 0 : t.MediaSelectionOptionsPersistentID)) + } + })(null == t ? void 0 : t.audioPersistentId, m.audioGroupId, e.audioMediaSelectionGroup, p)) || void 0 === o ? void 0 : o.mediaOptionId : null, + b = S ? { + itemId: d, + mediaOptionId: S + } : Lu, + T = ((i, r, n, s, a, o) => { + if (s) { + let t, e; + return t = ne(i) ? s.MediaSelectionGroupOptions.find(function(e) { + return e.MediaSelectionOptionsPersistentID === i + }) : s.MediaSelectionGroupOptions.find(function(e) { + return e.MediaSelectionOptionsIsDefault + }), t && (e = a.find(e => e.mediaType === Su.CLOSEDCAPTION ? (!r || e.groupId === r) && e.persistentID === t.MediaSelectionOptionsPersistentID : e.mediaType === Su.SUBTITLE ? (!n || e.groupId === n) && e.persistentID === t.MediaSelectionOptionsPersistentID : void o.warn(By, `subtitle media option has unknown type ${e.mediaType}`))), e + } + })(null == t ? void 0 : t.subtitlePersistentId, m.closedcaption, m.subtitleGroupId, e.subtitleMediaSelectionGroup, f, i), + E = null != f && f.length ? null == T ? void 0 : T.mediaOptionId : null, + I = E ? { + itemId: d, + mediaOptionId: E, + mediaOptionType: gu.Subtitle + } : Lu, + { + mediaOptions: w, + audioGroups: A, + subtitleGroups: O + } = (t = g, l = m, t.reduce((e, t) => { + if (((e, t) => { + let i = !0; + e.videoCodec && t.videoCodec && (i = be.isCompatibleVideoCodec(e.videoCodec, t.videoCodec)); + let r = !1; + e.videoRange && t.videoRange ? r = e.videoRange == t.videoRange : e.videoRange || t.videoRange || (r = !0); + let n = !0; + return e.audioCodec && t.audioCodec && (n = be.isCompatibleAudioCodec(e.audioCodec, t.audioCodec)), i && r && n + })(l, t)) { + const l = t.audioGroupId; + l && e.audioGroups.add(l), e.mediaOptions.add(t) + } + var i = t.subtitleGroupId; + i && e.subtitleGroups.add(i); + t = t.closedcaption; + return t && e.closedCaptionGroups.add(t), e + }, { + mediaOptions: new Set, + audioGroups: new Set, + subtitleGroups: new Set, + closedCaptionGroups: new Set + })), + k = Array.from(w).map(e => e.mediaOptionId), + C = m.pathwayID, + D = Object.assign(Object.assign({}, u), { + compatibleIds: k, + preferredHost: y, + currentPathwayID: C + }), + M = [], + x = c.mediaOptions.reduce((e, t) => (A.has(t.groupId) && (e.persistentIds.add(t.persistentID), M.push(t.mediaOptionId), e.filteredAudioMediaOptions.push(t), e.altAudio || (e.altAudio = !!t.url)), e), { + filteredAudioMediaOptions: [], + persistentIds: new Set, + altAudio: !1 + }), + P = Object.assign(Object.assign({}, c), { + compatibleIds: M + }); + let R = e.audioMediaSelectionGroup; + const L = null == R ? void 0 : R.MediaSelectionGroupOptions; + if (L) { + const e = L.reduce((e, t) => (x.persistentIds.has(t.MediaSelectionOptionsPersistentID) && e.push(t), e), new Array); + R = Object.assign(Object.assign({}, R), { + MediaSelectionGroupOptions: e + }) + } + h.mediaOptions = jy(m, T, h.mediaOptions); + const _ = h.mediaOptions.reduce((e, t) => (O.has(t.groupId) && (e.persistentIds.add(t.persistentID), e.filteredSubtitleMediaOptions.push(t)), e), { + filteredSubtitleMediaOptions: [], + persistentIds: new Set + }); + let N = e.subtitleMediaSelectionGroup; + const F = null == N ? void 0 : N.MediaSelectionGroupOptions; + if (F) { + const e = F.reduce((e, t) => (_.persistentIds.has(t.MediaSelectionOptionsPersistentID) && e.push(t), e), new Array); + N = Object.assign(Object.assign({}, N), { + MediaSelectionGroupOptions: e + }) + } + i = [D, P, h]; + let B = new Map; + mg().useHighestVideoCodecPrivate && (B = null == D ? void 0 : D.mediaOptions.reduce((e, t) => { + const i = t.videoCodecList; + if (i) + for (const t of i) { + const i = Hp(t), + r = e.get(i); + be.isHigherCodecByFamily(r, t) && e.set(i, t) + } + return e + }, B)), B.size && B.forEach((e, t) => {}); + t = { + fragDownloadSlow: !1, + fragDownloadTooSlow: !1, + nextMinAutoOptionId: Lu.mediaOptionId, + nextMaxAutoOptionId: Lu.mediaOptionId, + highBWTrigger: Xg(v.mediaOptionId, D.mediaOptions) + }; + return Object.assign(Object.assign({}, e), { + enabledMediaOptionKeys: [v, b, I], + mediaOptionListTuple: i, + audioMediaSelectionGroup: R, + abrStatus: t, + highestVideoCodec: B + }) + } + const Wy = (o, l, d, u, c, h, p) => e => e.pipe(tc("retrieveRootMediaOptions.input"), La(t => { + var e; + if (!t) return Ii; + const { + itemId: i, + platformInfo: r + } = t, n = Ky(i), s = l["logger"]; + if (n.hasEntity(i)) return $i(n); + $y.setLoading(!0); + const a = performance.now(); + return function(e, t, u, c, i) { + const { + itemId: h, + url: p, + itemStartOffset: f + } = e, r = Lc(e, t); + return Lm({ + url: p, + onProgress: { + getData: !0, + cb: Iy + }, + xhrSetup: c.xhrSetup + }, r, i).pipe(hr(({ + responseText: e, + responseURL: t, + stats: i + }) => { + var r = c["keySystemPreference"]; + if (t || (u.warn("Missing response url. Reusing request url as base url"), t = p), Rm.isMediaPlaylist(e)) { + const c = "media-pl-" + Zl(), + d = Rm.parseMediaOptionPlaylist(e, t, !0, r, {}, h, c, gu.Variant, u, f); + Nc(d.mediaOptionDetails); + var n = { + itemId: h, + mediaOptionId: c, + mediaOptionType: gu.Variant, + url: p, + bandwidth: 0, + bitrate: 0, + iframes: d.mediaOptionDetails.iframesOnly, + pathwayID: "." + }; + return { + itemId: h, + itemStartOffset: f, + rootMediaOptionsTuple: [ + [n], + [], + [] + ], + stats: i, + baseUrl: t, + initialDetails: d.mediaOptionDetails, + isMediaPlaylist: !0 + } + } { + const u = Rm.parseSessionData(e, t), + c = Rm.parseSessionKeys(e, t, r), + p = Rm.parseRootPlaylist(h, e, t, !0); + if (p.playlistParsingError) throw p.playlistParsingError; + var { + variantMediaOptions: s, + contentSteeringOption: a, + masterVariableList: o + } = p, l = Rm.parseRootPlaylistAlternateMediaOptions(h, e, t, p.variantMediaOptions, !0, o); + if (l.playlistParsingError) throw l.playlistParsingError; + var { + audioAlternateOptions: n, + subtitleAlternateOptions: r, + audioMediaSelectionGroup: e, + subtitleMediaSelectionGroup: l + } = l.alternateMediaInfo; + return { + itemId: h, + itemStartOffset: f, + rootMediaOptionsTuple: [s, n, r], + stats: i, + baseUrl: t, + audioMediaSelectionGroup: e, + subtitleMediaSelectionGroup: l, + contentSteeringOption: a, + sessionData: u, + sessionKeys: c, + masterVariableList: o + } + } + }), e => e.pipe(Vn(e => { + if (e instanceof pc) throw new dc(!1, "Timeout", 0, $.ManifestTimeoutError, !0); + if (e instanceof oc) throw new dc(!1, e.message, e.code, { + code: e.code, + text: "Manifest network error" + }, !1); + throw e + }))) + }(t, o, s, d, null === (e = null === (e = fg()) || void 0 === e ? void 0 : e.getQuery()) || void 0 === e ? void 0 : e.extendMaxTTFB).pipe(Za(e => p.triggerManifestLoaded(e)), Za(({ + initialDetails: e, + stats: t + }) => { + e && (e = e, t = t, Cg().archiveMediaOptionDetails(e, t, !0)) + }), bo(u.displaySupportsHdr$), La(([e, t]) => qy(e, r, d, t, s)), hr(e => (l.rootPlaylistEntity = function(e, t, i, r, n, s) { + const { + itemId: a, + initialSeekTime: o + } = e, l = Zf(a), d = n.enableAdaptiveStartup ? l.getBandwidthEstimate(n, e.serviceName) : void 0, u = n.enableAdaptiveStartup ? l.getPlaylistEstimate(n, e.serviceName) : void 0, c = n.enableAdaptiveStartup ? l.getFragEstimate(n, e.serviceName) : void 0, h = n.enableAdaptiveStartup ? l.getBufferEstimate(n, e.serviceName) : void 0, p = performance.now() - r; + let f; + n.targetStartupMs > p ? f = n.targetStartupMs - p : (f = n.targetStartupMs, s.warn(`Manifest load took ${p}ms and exceeds targetStartupMs: ${n.targetStartupMs}; resetting targetStartupMs to ${n.targetStartupMs}`)); + const m = n.enableAdaptiveStartup ? { + targetDuration: c.maxDurationSec || n.defaultTargetDuration, + targetStartupMs: f + } : void 0, + g = Qy(t, i, s, d, m, u, c, h); + return g.pendingSeek = o, g + }(t, e, c, a, d, s), n)), lg(i, null, Lc(t, o), 0, !1, n, l, h), Vs(() => { + $y.setLoading(!1) + })) + }), tc("retrieveRootMediaOptions.emit")); + + function Gy(t, o, l, d, u, c, h) { + return e => e.pipe(Kp(), La(e => { + return e ? Mr([$i(e).pipe(Wy(t.manifestLoadPolicy, l, t, d, null, u, c)), (n = t, s = o, a = h.mux, new $t(e => { + const t = new Ty(n, s, a); + return e.next(t), () => { + t.destroy() + } + })), (i = t.trickPlaybackConfig, r = o, new $t(e => { + var t = new Zu(i, r); + return e.next(t), () => {} + }))]).pipe(hr(([e, t, i]) => ({ + rootPlaylistQuery: e, + mediaParser: t, + iframeMachine: i + }))) : $i(null); + var i, r, n, s, a + })) + } + wc; + return class zy extends wc { + constructor(e = {}, t) { + var i; + if (super(), this.destroy$ = new Xt, this.mediaElement$ = new yi(null), this.publicQueriesInternal$ = new yi(null), this.mediaElementAdapter = null, this.rpcService = null, this.rpcClients = null, this.platformService = Af(), this.keySystemAdapter = null, this.legibleSystemAdapter = null, this.sessionID = Zl(), this.statsService = (Jf = Jf || new Xf(Yf), Jf), this.gaplessCapable = !0, this.teardownWG$ = new Xp, this.itemQueue = new ay, (e.liveSyncDurationCount || e.liveMaxLatencyDurationCount) && (e.liveSyncDuration || e.liveMaxLatencyDuration)) throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration"); + const m = Object.assign(Object.assign({}, Ru), e); + if (m.maxRequiredStartDuration < m.minRequiredStartDuration || m.minRequiredStartDuration < 0) throw new Error("Illegal config: bad maxRequiredStartDuration or minRequiredStartDuration"); + i = (this.hlsConfig = m).buildType, oe = "production" === i; + const r = this.sessionID; + let n = "silent"; + e.debug && (n = m.debugLevel), au(!0), this.logger = null !== (i = this.logger) && void 0 !== i ? i : ([M, h = {}] = [r, (c = { + sendLogs: m.sendLogs || null, + level: "log" === n ? "debug" : n, + consoleOverride: "boolean" != typeof e.debug ? e.debug : void 0, + buildType: m.buildType + }, x = c.consoleOverride, Object.assign({ + name: "hls", + timestamp: c.sendLogs ? Oe.stdTimeFunctions.epochTime : Oe.stdTimeFunctions.isoTime, + browser: { + asObject: !0, + serialize: !0, + transmit: { + send: (e, t) => {} + }, + write: { + debug: qe.bind(null, Ke(x || console, "debug"), "debug"), + info: qe.bind(null, Ke(x || console, "info"), "info"), + warn: qe.bind(null, Ke(x || console, "warn"), "warn"), + error: qe.bind(null, Ke(x || console, "error"), "error"), + fatal: qe.bind(null, Ke(x || console, "error"), "fatal") + } + } + }, c))], Ue && Ue.sessionId === M ? Ue.warn("Logger Singleton already setup, returning existing singleton") : (Ue = Oe($e(h)).child({ + sessionId: M, + name: "hls" + }), Ue.qe = e => Ue.info(e), Ue.sessionId = M), Ue), _o = !1, Lo && (delete window.$$stores, delete window.$$queries), this.hlsConfig.audioPrimingDelay = 0, this.rootPlaylistService = (x = this.logger, Vy = new Uy($y, x), Vy), this.customUrlLoader = Pc(), this.sessionDataLoader = new Fp(m, Cc, this.customUrlLoader.load, this.logger); + var s, a, o, l, d, u, c = m.liveMaxLatencyDurationCount, + h = m.liveSyncDurationCount; + if (ne(c) && ne(h) && c <= h) throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be gt "liveSyncDurationCount"'); + if (ne(m.liveMaxLatencyDuration) && (m.liveMaxLatencyDuration <= m.liveSyncDuration || !ne(m.liveSyncDuration))) throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be gt "liveSyncDuration"'); + const p = fg(); + p.setHlsEntity({ + id: r, + config: m + }); + const f = Cg(), + g = new Tf(If), + y = (Rh = Rh || new xh(Ph), Rh); + this.accessLogInstance = new rm(this, r), this.rtcService = new Kf(this, m, this.accessLogInstance, this.logger), this.playerEvents = new Ng(this, this.logger, this.rtcService); + const v = (M = this.platformService, u = M, (() => { + if ("function" == typeof matchMedia) { + var e = matchMedia("(dynamic-range: high)"), + t = matchMedia("bad query"); + if (e.media !== t.media) return an($i(e), rn(e, "change")).pipe(hr(e => e.matches)) + } + return $i(!0) + })().pipe(Za(e => { + u.updateSupportsHdr(e) + })).pipe($a(Ii))), + S = this.mediaElement$.pipe((s = m, o = (a = this).logger, l = this.teardownWG$, d = this.rtcService, e => e.pipe(tc("playback.mediaElementServiceEpic.in"), La(e => { + if (!e) return $i(null); + const t = new vf(e, bf, s, a, o, l, d); + return t.openMediaSource(new MediaSource), an($i(t), t) + }), tc("playback.mediaElementServiceEpic.emit"))), Aa()), + b = this.itemQueue.activeItemById$.pipe(La(e => e ? tm(m, this.statsService, e, this.logger) : Ii)); + this.rpcService = (() => { + let e = null; + return null != m.createRPCService && (e = Lf(m.createRPCService, xf)), m.enableWorker && null == e && (e = _f), null == e && (e = xf), e(this.logger) + })(), this.rpcClients = (x = this.rpcService, { + crypto: new kf(x), + mux: new Cf(x) + }); + var T, E, I, w, A, O, k, C, D, c = Mr([this.itemQueue.activeItemById$.pipe(Gy(m, this.logger, this.rootPlaylistService, g, this.statsService, this.playerEvents, this.rpcClients), Za(e => { + var t = null == e ? void 0 : e.rootPlaylistQuery; + this.publicQueriesInternal$.next([t, null]), this.iframeMachine = null == e ? void 0 : e.iframeMachine, t && this.playerEvents.triggerManifestParsed(t) + })), S.pipe((I = this.itemQueue.removedItems$, w = y, A = m, O = g, C = (k = this).rtcService, D = this.logger, e => Mr([((n, s, a, o, l, d, u) => e.pipe(tc("[Keys] playback.keySystemServiceEpic.in"), La(r => r ? new $t(e => { + let t = new Dh(n, r, a, o, l, d, u); + const i = an($i(t), s.pipe(jr(e => t.removeKeysForItems(e)), $a(Ii))).subscribe(e); + return function() { + u.warn("[Keys] playback.keySystemServiceEpic.unsubscribe"), i.unsubscribe(), t.destroy().subscribe(), t = void 0 + } + }) : $i(null)), tc("[Keys] playback.keySystemServiceEpic.emit")))(w, I, A, O, k, C, D), ((t, i, r) => e.pipe(tc("playback.legibleServiceEpic.in"), La(e => e ? an($i(e = new _p(e, t, i, r)), e) : $i(null)), tc("playback.legibleServiceEpic.emit")))(A, k, D), e]).pipe(hr(([e, t, i]) => ({ + keySystemAdapter: e, + legibleSystemAdapter: t, + mediaSink: i + })))), Za(({ + keySystemAdapter: e, + legibleSystemAdapter: t, + mediaSink: i + }) => { + this.keySystemAdapter = e, this.legibleSystemAdapter = t, this.mediaElementAdapter = i + }))]).pipe(hr(([e, t]) => { + var { + keySystemAdapter: i, + legibleSystemAdapter: r, + mediaSink: n + } = t; + if (!(e && i && r && n)) return null; + var { + rootPlaylistQuery: s, + iframeMachine: t, + mediaParser: e + } = e; + return { + logger: this.logger, + config: m, + platformService: this.platformService, + statsService: this.statsService, + rtcService: this.rtcService, + rpcClients: this.rpcClients, + rootPlaylistService: this.rootPlaylistService, + rootPlaylistQuery: s, + mediaLibraryService: f, + keySystemAdapter: i, + legibleSystemAdapter: r, + mediaSink: n, + mediaParser: e, + iframeMachine: t, + customUrlLoader: this.customUrlLoader, + gaplessInstance: this + } + }), Aa()).pipe(La(u => { + if (!u) return Ii; + const { + rootPlaylistQuery: t, + mediaSink: e, + mediaLibraryService: i + } = u; + this.publicQueriesInternal$.next([t, e.mediaQuery]); + const n = e.mediaQuery, + r = $i(u).pipe(vy()), + s = t.rootPlaylistEntity$.pipe(Kp(), Ds(1), Za(() => { + this.commitEarlySelection(u.logger) + })), + a = Gu(Mr([n.haveEnough$, t.sessionData$]), ([e]) => !0 === e, 1).pipe(La(([, e]) => this.sessionDataLoader.loadSessionData(e)), Za(e => { + this.rootPlaylistService.setSessionData(t.itemId, e) + }), Vn(e => (this.logger.error(e.message), Ii))), + o = Zf(t.itemId), + l = function(d, r, u, n, s) { + const a = u.mediaQuery; + return Gu(a.combinedBuffer$, e => 0 < (null == e ? void 0 : e.length)).pipe(La(() => { + var e = ed([a.seekTo$, a.bufferedSegmentsByType$(yu.Variant)]).pipe(hr(([e, t]) => { + const i = ne(null == e ? void 0 : e.pos) ? e.pos : a.currentTime, + r = t.find(e => e.startPTS <= i && e.endPTS > i), + n = a.getBufferInfo(i, d.maxBufferHole), + s = a.getCombinedBufferInfo(i, d.maxBufferHole); + return { + pos: i, + sbTuple: n, + combined: s, + playingFrag: null !== (t = null == r ? void 0 : r.frag) && void 0 !== t ? t : null + } + })), + t = ed([r.getInFlightFragByType$(gu.Variant), r.enabledMediaOptionByType$(gu.Variant)]).pipe(La(([e, t]) => { + var i = n.getQueryForOption(t); + return En($i(e), $i(t), i.mediaOptionDetails$) + }), hr(([e, t, i]) => [e, { + variant: t, + details: i + }])), + i = ed([s.bandwidthEstimate$, s.fragEstimate$, s.bufferEstimate$]); + return ed([a.readyState$, t, e, a.desiredRate$, i]) + }), ao(100, tr, { + leading: !0, + trailing: !0 + }), hr(([, e, t, i, r]) => { + var [n, s] = e, [a, e, r] = r; + let o = e, + l = r; + return e && (o = { + maxDurationSec: ne(e.maxDurationSec) ? e.maxDurationSec : d.defaultTargetDuration, + avgParseTimeMs: ne(e.avgParseTimeMs) ? e.avgParseTimeMs : d.statDefaults.fragParseTimeMs + }), r && (l = { + avgBufferCreateMs: ne(r.avgBufferCreateMs) ? r.avgBufferCreateMs : d.statDefaults.fragBufferCreationDelayMs, + avgInitFragAppendMs: ne(r.avgInitFragAppendMs) ? r.avgInitFragAppendMs : d.statDefaults.initFragAppendMs, + avgDataFragAppendMs: ne(r.avgDataFragAppendMs) ? r.avgDataFragAppendMs : d.statDefaults.dataFragAppendMs + }), a = Ey(d, n, s, t, i, a, o, l), u.haveEnough = a + }), Is(), Za(e => {}), $a(Ii)) + }(m, (this.logger, t), e, i, o), + d = function() { + const { + config: e, + mediaSink: t, + rootPlaylistQuery: i, + mediaLibraryService: r, + gaplessInstance: n + } = u, s = t.mediaQuery, a = i.enabledAVOptions$.pipe(La(e => En(...e.map(e => _u(e) ? r.getQueryForOption(e).mediaOptionDetails$ : $i(null))))); + return Gu(s.combinedBuffer$, e => 0 < (null == e ? void 0 : e.length)).pipe($a(ed([a, s.msReadyState$, s.updating$, s.isIframeRate$, s.isBufferedToEnd$(e.maxBufferHole, !n.inGaplessMode)])), tc("checkForEndOfStream"), ln(([, e, t, i, r]) => "open" === e && !1 === t && !i && r), Za(([e]) => { + null != e[0] && e.every(e => null == e || !1 === e.liveOrEvent && !1 === e.iframesOnly) && !n.inGaplessMode && t.endStream() + }), $a(Ii)) + }(), + c = function() { + const { + config: o, + iframeMachine: l, + mediaSink: i + } = u, d = i.mediaQuery; + return d.desiredRate$.pipe(La(a => Wp(a) ? bn(0, Math.abs(1e3 / a)).pipe(hr(() => { + let e = null; + const t = d.seekable; + if (!l.isStarted || t.length < 1) return e; + var i = l.iframeClockTimeSeconds, + r = o.leftMediaTimeToAutoPause, + n = t.start(0), + s = t.end(t.length - 1); + return 1 < a && s - i < r ? (e = { + newRate: 0, + postFlushSeek: s - r + }, l.pause()) : a < 0 && i - n < a / -2 && (e = { + newRate: 1, + postFlushSeek: n + }), e + }), Kp(), Za(({ + newRate: e, + postFlushSeek: t + }) => { + i.postFlushSeek = t, i.desiredRate = e + }), $a(Ii)) : Ii)) + }(), + h = (f = u).config.enableIFramePreloading ? function(t) { + const { + mediaSink: e, + rootPlaylistQuery: r, + mediaLibraryService: n + } = t, i = e.mediaQuery; + return ed([i.desiredRate$, i.waterLevelChangedForType$(yu.Variant)]).pipe(La(([e, t]) => Wp(e) || t !== Dp.AboveHighWater ? Ii : r.enabledMediaOptionByType$(gu.Variant).pipe(hr(e => { + var t = r.mediaOptionListQueries[gu.Variant].hasIframes, + i = null !== (i = null === (i = n.getQuery().getEntity(r.itemId)) || void 0 === i ? void 0 : i.liveOrEvent) && void 0 !== i && i; + return !t || i ? xm.DISABLED : e + }))), Ds(1), _s(e => function(e, t) { + const i = t.logger; + return e === xm.DISABLED ? $i(e) : function(e, t) { + const { + rootPlaylistQuery: i, + logger: r, + config: n, + mediaSink: s, + statsService: a + } = t, o = s.mediaQuery, l = a.getQueryForItem(i.itemId), d = Dg(e), u = jg(!0, n, i, d, o, l, r), c = i.variantMediaOptionById(u.variantMediaOption); + return Mg(t, c, !0) + }(e, t).pipe(_s(r => function(e) { + var { + mediaSink: t, + rootPlaylistQuery: i + } = e, t = Ig((t = t.mediaQuery).currentTime, i.discoSeqNum, 0, r, []); + return null !== (i = null == t ? void 0 : t.foundFrag) && void 0 !== i && i.mediaFragment ? (t = t.foundFrag.mediaFragment, en([_g(e, t.keyTagInfo, { + itemId: t.itemId, + mediaOptionId: t.mediaOptionId + }), xg(e, t)]).pipe(Za(() => {}), Zs(xm.SUCCESS))) : Vi("Unable to find fragment for iframe prefetch") + }(t)), Zs(xm.SUCCESS), Vn(e => (i.error(ry, `got error ${e.message} in prefetch`), $i(xm.ERRORED)))) + }(e, t)), Vs(() => {})) + }(f) : $i(xm.DISABLED), + p = [s, r, a, l, Gu(ed([n.gotPlaying$, n.gotLoadStart$, n.readyState$]), ([e, t, i]) => !0 === e || !0 === t || 1 <= i).pipe(La(() => n.ended$), La(e => bn(0, e ? void 0 : 1e3)), Za(() => { + this.playbackInfo(m, n) + })), c, h, n.timeupdate$.pipe(hr(e => { + if (this.inGaplessMode && this.isPreloading && ne(this.loadingItem.itemStartOffset) && e >= this.loadingItem.itemStartOffset) { + const e = this.itemQueue.playingItem.itemId, + t = this.itemQueue.loadingItem.itemId, + i = { + prevItemId: e, + nextItemId: t, + nextStartTime: this.loadingItem.itemStartOffset, + nextDuration: n.msDuration - this.loadingItem.itemStartOffset + }; + this.itemQueue.updatePlayingItemId(), this.trigger(P.ITEM_TRANSITIONED, i), this.rtcService.itemTransitioned(e, t) + } + })), this.updateLiveSeekableRange(t, e), d]; + var f; + if (m.enablePerformanceLogging) { + this.logger.child({ + name: "timing" + }); + const u = En(...Bu.map(r => t.getInFlightFragByType$(r).pipe(Is((e, t) => (null == e ? void 0 : e.state) === (null == t ? void 0 : t.state)), Kp(), bo(n.bufferedRangeTuple$), Za(([e, t]) => { + const i = Object.assign(Object.assign({}, e), { + event: "fragment", + name: Nu[r], + buffered: void 0 + }); + "appended" === e.state && (i.buffered = t) + }), Vn(() => Ii)))), + e = En(...Fu.map(e => t.enabledMediaOptionByType$(e).pipe(La(t => null != (null == t ? void 0 : t.url) && _u(t) ? Dg(t).mediaOptionDetailsEntity$.pipe(Kp(), hr(e => ({ + entity: e, + option: t + })), Is((e, t) => (null == e ? void 0 : e.entity.detailsLoading) === (null == t ? void 0 : t.entity.detailsLoading)), Za(({}) => {})) : Ii), Vn(() => Ii)))); + p.push(u, e) + } + return an(...p) + })), + h = this.itemQueue.removedItems$.pipe(ll(e => { + var t; + t = e, Cg().remove(t), this.rootPlaylistService.removeItems(e) + })), + M = p.getQuery().userSeek$.pipe((T = this.itemQueue, E = this.rootPlaylistService, e => e.pipe(Kp(), La(e => en([$i(e), T.activeItemById$.pipe(Kp(), La(e => E.getQueryForId(e.itemId).rootPlaylistEntity$), Ds(1))])), hr(([e, t]) => (E.setPendingSeek(t.itemId, e), e))))), + x = p.getQuery().selectEntityAction(Eo.Add).pipe(Za(() => { + this.logger.warn(`new Hls instance added while old one still active sessionId:${r}`) + })); + an(S.pipe(Vn(() => Ii)), an(v, M, b, h, c, this.teardownWG$).pipe(Vn(e => this._handleError(e)))).pipe(Vs(() => { + var e, t; + try { + this.detachMedia(), this.trigger(P.DESTROYING), this.playerEvents.destroy(), null === (e = this.accessLogInstance) || void 0 === e || e.destroy(), null === (t = this.rtcService) || void 0 === t || t.destroy(), Cg().clear(), this.rootPlaylistService.removeAll(), this.itemQueue.clearQueue(), p.removeEntity(this.sessionID) + } catch (e) { + this.logger.error(`Got error in finalize ${e.message}`) + } + }), Va(fn(this.destroy$, x))).subscribe() + } + get publicQueries$() { + return this.publicQueriesInternal$.pipe(ln(e => Boolean(e) && Boolean(e[0]) && Boolean(e[1]))) + } + get _activeRootQuery() { + var e = this.publicQueriesInternal$.value; + return null !== (e = null == e ? void 0 : e[0]) && void 0 !== e ? e : null + } + get _mediaElementQuery() { + var e = this.publicQueriesInternal$.value; + return null !== (e = null == e ? void 0 : e[1]) && void 0 !== e ? e : null + } + static get version() { + return "2.162.2" + } + static get Events() { + return P + } + get Events() { + return zy.Events + } + static get DefaultConfig() { + return de(Ru) + } + get DefaultConfig() { + return zy.DefaultConfig + } + static isSupported() { + try { + const e = window.MediaSource || window.WebKitMediaSource, + t = window.SourceBuffer || window.WebKitSourceBuffer, + i = e && "function" == typeof e.isTypeSupported && e.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'), + r = !t || t.prototype && "function" == typeof t.prototype.appendBuffer && "function" == typeof t.prototype.remove; + return !!i && !!r + } catch (e) { + return !1 + } + } + commitEarlySelection(e) { + var t = this.itemQueue.earlyAudioSelection; + ne(t) && (this.audioSelectedPersistentID = t, this.itemQueue.earlyAudioSelection = null), ne(t = this.itemQueue.earlySubtitleSelection) && (this.subtitleSelectedPersistentID = t, this.itemQueue.earlySubtitleSelection = null) + } + _handleError(i) { + var r; + try { + let t, e = i.message; + if (this.logger.error(`Got unhandled or fatal error ${e}`, i), null === (r = this.rtcService) || void 0 === r || r.handleError(i), t = i instanceof p ? i : new V(!0, i.message, $.InternalError), t.fatal && this.isPreloading && (this.logger.warn("Fatal error seen while preloading, calling dequeueSource"), this.dequeueSource("FatalErrorWhileLoading")), t.fatal) { + let e = Wu; + if (this.mediaElementAdapter) { + const r = this.mediaElementAdapter.mediaQuery, + n = r.getCombinedBufferInfo(r.currentTime, 0); + 0 < (null == n ? void 0 : n.len) && (e = Gu(this.mediaElementAdapter.mediaQuery.stallInfo$, e => null != e).pipe(hr(() => {}))) + } + return e.pipe(La(() => (this.trigger(P.ERROR, t), Ii))) + } + this.trigger(P.ERROR, t) + } catch (i) { + throw this.logger.error(`Error thrown inside _handleError ${i.message}`, i), i + } + return Ii + } + updateLiveSeekableRange(e, t) { + return e.enabledMediaOptionByType$(gu.Variant).pipe(La(e => { + const t = Dg(e); + let i = 0; + return t.mediaOptionDetailsEntity$.pipe(Kp(), ln(e => { + var t = null !== e.stats && !1 === e.detailsLoading && e.lastUpdateMillis > i; + return i = null !== (e = e.lastUpdateMillis) && void 0 !== e ? e : 0, t + })) + }), La(e => (0 === e.unchangedCount && (e.mediaOptionDetails.liveOrEvent ? t.updateLiveSeekableRange(e.mediaOptionDetails) : t.clearLiveSeekableRange()), Ii))) + } + playbackInfo(i, r) { + const n = this.mediaElement$.getValue(); + if (n) { + const s = n.readyState >= n.HAVE_FUTURE_DATA, + a = { + readyToPlay: s, + playbackLikelyToKeepUp: r.haveEnough && s, + rate: n.playbackRate, + paused: n.paused, + position: n.currentTime, + duration: n.duration, + seekableTimeRanges: im.timeRangeToArray(n.seekable), + loadedTimeRanges: im.timeRangeToArray(n.buffered) + }; + let e = 0, + t = 0; + if (im.isHtmlVideoElement(n)) { + const o = n.getVideoPlaybackQuality; + if (o && typeof o == typeof Function) { + const o = n.getVideoPlaybackQuality(); + e = a.droppedVideoFrames = o.droppedVideoFrames, a.corruptedVideoFrames = o.corruptedVideoFrames, a.totalVideoFrames = o.totalVideoFrames, t = a.totalVideoFrames - e + } + } else im.isWebkitMediaElement(n) && (e = a.droppedVideoFrames = n.webkitDroppedFrameCount, t = a.decodedFrameCount = n.webkitDecodedFrameCount); + i.enablePerformanceLogging && r.getCombinedMediaSourceBufferInfo(i.maxBufferHole), null === (i = this.rtcService) || void 0 === i || i.handlePlaybackInfo(e, t) + } + } + get currentItem() { + return this.isPreloading ? this.playingItem : this.itemQueue.activeItem + } + get realCurrentTime() { + var e, t = this._mediaElementQuery; + if (!t) return NaN; + if (null !== (e = this.iframeMachine) && void 0 !== e && e.isStarted) { + const r = t.mediaElementDuration, + e = this.iframeMachine.iframeClockTimeSeconds; + return e > r ? r : e + } + let i = ne(t.postFlushSeek) ? t.postFlushSeek : t.currentTime; + return ne(i) && ne(null === (e = this.playingItem) || void 0 === e ? void 0 : e.itemStartOffset) && (i -= this.playingItem.itemStartOffset), i + } + set realCurrentTime(e) { + var t; + ne(null === (t = this.playingItem) || void 0 === t ? void 0 : t.itemStartOffset) && (e += this.playingItem.itemStartOffset), this.seekTo = e + } + get bufferedDuration() { + var e; + const t = this._mediaElementQuery; + return null !== (e = null == t ? void 0 : t.getBufferedDuration()) && void 0 !== e ? e : 0 + } + get sessionData() { + var e = this._activeRootQuery; + return null == e ? void 0 : e.sessionData + } + get supportedFrameRates() { + const e = this.hlsConfig.trickPlaybackConfig.enabled, + t = [0, 1], + i = this._activeRootQuery, + r = Cg().getQuery(); + return e && i && r.getEntity(i.itemId) && !1 === r.getEntity(i.itemId).liveOrEvent && t.push(8, 24, 48, 96), t + } + loadSource(e, i, t) { + var r, n, s, a, o, l; + if ("playready" === this.config.keySystemPreference && !this.config.enablePlayReadyKeySystem) throw new V(!0, "Playready key system is not supported now", $.UnsupportedKeySystemError); + if (!e || !e.trim().length) throw new V(!0, "Empty loadSource url", $.EmptyLoadSourceError); + if (e = bu.buildAbsoluteURL(window.location.href, e, { + alwaysNormalize: !0 + }), i && Object.keys(i).filter(e => 0 <= ["itemId", "streamID"].indexOf(e)).reduce((e, t) => t in i ? Object.assign(e, { + [t]: i[t] + }) : e, {}), null !== (l = null == i ? void 0 : i.appData) && void 0 !== l && l.reportingAgent && (this.reportingAgent = i.appData.reportingAgent), null != i && i.userInfo && (this.userInfo = i.userInfo), null === (a = this.accessLogInstance) || void 0 === a || a.setupReporter(i.appData), null != i && i.platformInfo && this.platformService.updatePlatformInfo(i.platformInfo), function(e, t) { + if (t) { + const t = Eu(e); + return void 0 !== Iu.find(e => new RegExp(e).exec(t)) + } + }(e, this.config.enableQueryParamsForITunes)) { + const d = { + language: i.language, + dsid: i.dsid, + subs: i.subs + }; + r = e, n = null == i ? void 0 : i.platformInfo, s = d, o = n.model, l = n.manufacturer, o && l || Qe().warn(`Missing model/manufacturer in platformInfo model ${o} manufacturer ${l}`), o && l && (a = r, o = n.model, l = n.manufacturer, n = -1 !== a.indexOf("?"), o = encodeURIComponent(o), l = encodeURIComponent(l), r = (a = n ? a : a + "?") + wu.deviceName + l + wu.deviceModel + o), e = function(e, t) { + let i; + e = -1 !== e.indexOf("?") ? e : e + "?"; + const r = Qe(); + for (i in t) t[i] ? e += wu[i] + ("subs" === i ? encodeURIComponent(t[i]) : t[i]) : r.warn(`Missing ${i} info`); + return e + }(r, s), i.inheritQuery = !1 + } + this.itemQueue.setQueueItem(`item:${null!==(s=null==i?void 0:i.itemId)&&void 0!==s?s:Zl()}`, e, t, null == i ? void 0 : i.platformInfo, null === (t = null == i ? void 0 : i.appData) || void 0 === t ? void 0 : t.serviceName), fg().setStartTime(void 0) + } + queueSource(e, t, i) { + var r; + null != t && t.userInfo && (this.userInfo = t.userInfo); + var n = null === (r = this._mediaElementQuery) || void 0 === r ? void 0 : r.getCombinedBufferInfo(null === (n = this._mediaElementQuery) || void 0 === n ? void 0 : n.currentTime, 0); + let s = 0; + n && (s = n.end), this.itemQueue.addQueueItem(`item:${null!==(n=null==t?void 0:t.itemId)&&void 0!==n?n:Zl()}`, e, i, null == t ? void 0 : t.platformInfo, s, null === (t = null == t ? void 0 : t.appData) || void 0 === t ? void 0 : t.serviceName) + } + dequeueSource(e = "ApplicationInitiated") { + if (!this.isPreloading && "InvalidFormat" === e && this.isFirstItem) return this.logger.error("First item has invalid format for gapless. Probably video. Disabling gapless."), void(this.gaplessCapable = !1); + var t, i; + this.isPreloading ? (t = this.loadingItem.url, i = this.loadingItem.itemId, this.mediaElementAdapter.flushData(yu.Variant, this.loadingItem.itemStartOffset, 1 / 0), this.mediaElementAdapter.msDuration = this.loadingItem.itemStartOffset, this.itemQueue.resetLoadingItem(), "InvalidFormat" !== e && "FatalErrorWhileLoading" !== e || (this.gaplessCapable = !1), this.triggerItemEvicted({ + url: t, + itemId: i + }, e)) : this.logger.warn(`Nothing to dequeue, no item is preloading dequeue reason: ${e}`) + } + triggerItemEvicted(e, t) { + null !== e ? (t = { + url: e.url, + evictedItemId: e.itemId, + reason: t + }, Object.assign(Object.assign({}, t), { + url: le(e.url) + }), this.trigger(P.ITEM_EVICTED, t)) : this.logger.error("dequeueSource called with no playing or loading item") + } + endSource() { + this.gaplessCapable = !1, this.isPreloading && (this.logger.warn("EndSource called during preloading. Loading item will be removed"), this.mediaElementAdapter.flushData(yu.Variant, this.loadingItem.itemStartOffset, 1 / 0), this.mediaElementAdapter.msDuration = this.loadingItem.itemStartOffset, this.itemQueue.resetLoadingItem()) + } + get inGaplessMode() { + return mg().gapless && this.gaplessCapable + } + get isPreloading() { + return this.itemQueue.isPreloading() + } + get isFirstItem() { + return this.itemQueue.isFirstItem + } + get loadingItem() { + return this.itemQueue.loadingItem + } + get playingItem() { + return this.itemQueue.playingItem + } + get url() { + return this.playingItem ? this.playingItem.url : this.loadingItem ? this.loadingItem.url : void 0 + } + destroy() { + const t = this.logger; + return this.destroy$.next(), null != this.rpcService && (this.teardownWG$.add(), this.rpcService.teardown(e => { + e && t.error("RPCService teardown error:", e), this.teardownWG$.done() + }), this.rpcService = null), null != this.iframeMachine && (this.iframeMachine.destroy(), this.iframeMachine = null), this.teardownWG$.toPromise() + } + attachMedia(e) { + this.trigger(P.MEDIA_ATTACHING, { + media: e + }), this.mediaElement$.next(e), this.trigger(P.MEDIA_ATTACHED, { + media: e + }) + } + detachMedia() { + var e; + this.mediaElement$.getValue() && (this.trigger(P.MEDIA_DETACHING), null === (e = this.rtcService) || void 0 === e || e.detachMedia(), null != this.iframeMachine && this.iframeMachine.stop(), this.mediaElement$.next(null), this.trigger(P.MEDIA_DETACHED)) + } + handleResolvedUri(e, t) { + this.customUrlLoader.setCustomUrlResponse(e, { + uri: t.uri, + response: t + }) + } + get variantOptions$() { + return this.publicQueries$.pipe(La(e => { + const [t, i] = e; + return Mr([t.preferredMediaOptions$, i.desiredRate$]).pipe(hr(([e]) => { + const t = i.isIframeRate; + return e[gu.Variant].filter(e => (null !== (e = e.iframes) && void 0 !== e && e) === t).map(e => e.mediaOptionId) + })) + })) + } + get altAudioOptions$() { + return this.publicQueries$.pipe(La(e => { + var [e] = e; + return $i(e.audioMediaSelectionOptions) + })) + } + get subtitleOptions$() { + return this.publicQueries$.pipe(La(e => { + var [e] = e; + return $i([{ + MediaSelectionOptionsName: "Disable subtitle", + MediaSelectionOptionsPersistentID: -1 + }].concat(e.subtitleMediaSelectionOptions)) + })) + } + get levels() { + var e; + return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.preferredMediaOptions[gu.Variant]) && void 0 !== e ? e : [] + } + get audioTracks() { + var e; + return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.preferredMediaOptions[gu.AltAudio]) && void 0 !== e ? e : [] + } + get audioMediaOptions() { + var e; + return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.audioMediaSelectionOptions) && void 0 !== e ? e : [] + } + get subtitleMediaOptions() { + var e; + return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.subtitleMediaSelectionOptions) && void 0 !== e ? e : [] + } + get playbackLikelyToKeepUp() { + var e; + return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.playbackLikelyToKeepUp) && void 0 !== e && e + } + get duration$() { + return this.publicQueries$.pipe(La(e => { + var [, e] = e; + return e.mediaElementDuration$ + })) + } + get timeupdate$() { + return this.publicQueries$.pipe(La(e => { + var [, e] = e; + return e.timeupdate$ + })) + } + get playing$() { + return this.publicQueries$.pipe(La(e => { + var [, e] = e; + return e.gotPlaying$ + })) + } + get desiredRate$() { + return this.publicQueries$.pipe(La(e => { + var [, e] = e; + return e.desiredRate$ + })) + } + set desiredRate(e) { + null != e && this.setRate(e) + } + get desiredRate() { + var e; + return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.desiredRate) && void 0 !== e ? e : 0 + } + get effectiveRate() { + var e; + return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.effectiveRate) && void 0 !== e ? e : 0 + } + get iframeMode() { + var e; + return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.isIframeRate) && void 0 !== e && e + } + get accessLog() { + return this.accessLogInstance && this._activeRootQuery ? this.accessLogInstance.getAccessLog(this._activeRootQuery.itemId) : [] + } + get errorLog() { + return this.accessLogInstance ? this.accessLogInstance.errorLog : [] + } + setRate(e) { + var t; + const i = this.logger.child({ + name: "iframes" + }); + if (e === this.desiredRate) return -2; + const r = this.mediaElementAdapter; + if (!r || isNaN(e)) return i.warn("unable to switch to rate, missing adapter or newRate isNaN"), -1; + e = Number(e); + const n = Math.abs(e); + if (!this.supportedFrameRates.some(e => e === n)) return i.warn(`unsupported rate(${e})`), -3; + const s = Wp(e), + a = this.iframeMachine; + if (s) { + const e = this._activeRootQuery; + if (null == e || !e.mediaOptionListQueries[gu.Variant].hasIframes) return i.warn("no iframe variants available"), -1; + r.postFlushSeek = null + } else null != a && a.isStarted && !ne(null === (t = r.mediaQuery) || void 0 === t ? void 0 : t.postFlushSeek) && (a.pause(), r.postFlushSeek = a.iframeClockTimeSeconds); + return r.desiredRate = e, 0 + } + get sessionData$() { + return this.publicQueries$.pipe(La(([e]) => e.sessionData$)) + } + set skip(e) { + this._mediaElementQuery && (this.realCurrentTime = Math.max(0, this.realCurrentTime + e)) + } + gaplessSeekTo(e) { + e < this.playingItem.itemStartOffset && (this.logger.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${this.playingItem.itemStartOffset}`), e = this.playingItem.itemStartOffset), this.isPreloading && (e > this.loadingItem.itemStartOffset && (this.logger.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${this.loadingItem.itemStartOffset}`), e = this.loadingItem.itemStartOffset), e < this._mediaElementQuery.getBufferInfo(this._mediaElementQuery.currentTime, this.config.maxBufferHole)[0].buffered.start && this.dequeueSource("SeekToUnbufferedTimeRanges")), fg().setUserSeek(e) + } + isIframeInternalSeek(e) { + return e === (null === (e = this.iframeMachine) || void 0 === e ? void 0 : e.mediaRootTime) + } + set seekTo(e) { + var t, i = Number(e); + if (ne(i)) + if (this.inGaplessMode) this.gaplessSeekTo(i); + else { + const r = this.mediaElementAdapter; + !r || !ne(null === (t = r.mediaQuery) || void 0 === t ? void 0 : t.postFlushSeek) || r.mediaQuery.seekTo && !this.isIframeInternalSeek(r.mediaQuery.seekTo.pos) ? fg().setUserSeek(i) : r.schedulePostFlushSeek(i) + } + else this.logger.error(`[seek] got invalid seek value ${e}`) + } + seekToDate(e) { + fg().setUserSeek(e) + } + get availableProgramDateTime() { + return new Map(this._currentDateToMediaTimeTuple) + } + get _currentDateToMediaTimeTuple() { + if (!this._activeRootQuery) return []; + var e = this._activeRootQuery.enabledMediaOptionKeys[gu.Variant]; + return _u(e) && null !== (e = null === (e = Cg().getQueryForOption(e).mediaOptionDetails) || void 0 === e ? void 0 : e.dateMediaTimePairs) && void 0 !== e ? e : [] + } + get playingDate() { + return function(e, t) { + if (e && 0 !== e.length) { + const i = [...e].sort((e, t) => t[1] - e[1]), + r = null !== (e = i.find(([, e]) => e <= t)) && void 0 !== e ? e : i[i.length - 1], + [n, s] = r; + return new Date(n + 1e3 * (t - s)) + } + }(this._currentDateToMediaTimeTuple, this.realCurrentTime) + } + set variantId(e) {} + set audioSelectedPersistentID(e) { + var t = this._activeRootQuery; + null != t && t.preferredMediaOptions[gu.AltAudio] ? (t = t.itemId, e !== this.audioSelectedPersistentID && this.rootPlaylistService.setEnabledMediaOptionTupleWithMatchedGroups(t, gu.AltAudio, e, { + userInitiated: !0 + })) : !ne(e) || e < 0 || (this.logger.warn(`[audio] no active item, defer audio track selection: persistentId ${e}`), this.itemQueue.earlyAudioSelection = e) + } + get audioSelectedPersistentID() { + var e; + return this._activeRootQuery ? null === (e = this._activeRootQuery.enabledAlternateMediaOptionByType(gu.AltAudio)) || void 0 === e ? void 0 : e.persistentID : this.itemQueue.earlyAudioSelection + } + set subtitleSelectedPersistentID(e) { + var t = this._activeRootQuery, + i = null == t ? void 0 : t.preferredMediaOptions[gu.Subtitle]; + i ? e !== this.subtitleSelectedPersistentID && (t = t.itemId, 0 === i.length && (!ne(e) || e < 0) || (ne(e) && -1 !== e ? this.rootPlaylistService.setEnabledMediaOptionTupleWithMatchedGroups(t, gu.Subtitle, e) : this.rootPlaylistService.setEnabledMediaOptionByType(t, gu.Subtitle, Lu))) : !ne(e) || e < 0 || (this.logger.warn(`[subtitle] no active item, defer subtitle track selection: persistentId ${e}`), this.itemQueue.earlySubtitleSelection = e) + } + get subtitleSelectedPersistentID() { + var e; + return this._activeRootQuery ? null === (e = this._activeRootQuery.enabledAlternateMediaOptionByType(gu.Subtitle)) || void 0 === e ? void 0 : e.persistentID : this.itemQueue.earlySubtitleSelection + } + get selectedMediaArray() { + const e = this._activeRootQuery; + if (!e) return []; + const t = [], + i = e.enabledAlternateMediaOptionByType(gu.AltAudio), + r = e.enabledAlternateMediaOptionByType(gu.Subtitle), + n = i ? e.audioMediaSelectionOptions.find(e => e.MediaSelectionOptionsPersistentID === i.persistentID) : void 0, + s = r ? e.subtitleMediaSelectionOptions.find(e => e.MediaSelectionOptionsPersistentID === r.persistentID) : void 0; + if (n) { + const e = { + MediaSelectionGroupMediaType: Su.AUDIO, + MediaSelectionOptionsPersistentID: n.MediaSelectionOptionsPersistentID + }; + t.push(e) + } + if (s) { + let e = vu.NO; + s.MediaSelectionOptionsDisplaysNonForcedSubtitles && (e = s.MediaSelectionOptionsDisplaysNonForcedSubtitles); + const i = { + MediaSelectionGroupMediaType: Su.SUBTITLE, + MediaSelectionOptionsDisplaysNonForcedSubtitles: e, + MediaSelectionOptionsPersistentID: s.MediaSelectionOptionsPersistentID + }; + t.push(i) + } + return t + } + set selectedMediaArray(e) { + this._activeRootQuery ? e.forEach(e => { + e.MediaSelectionGroupMediaType === Su.AUDIO || e.MediaSelectionOptionsMediaType === Su.AUDIO ? this.audioSelectedPersistentID = e.MediaSelectionOptionsPersistentID : e.MediaSelectionGroupMediaType !== Su.SUBTITLE && e.MediaSelectionOptionsMediaType !== Su.SUBTITLE && e.MediaSelectionOptionsMediaType !== Su.CLOSEDCAPTION || (this.subtitleSelectedPersistentID = e.MediaSelectionOptionsPersistentID) + }) : this.logger.warn("selectedMediaArray: no active item") + } + getHTMLTextTrack(e) { + return this.legibleSystemAdapter.getExistingHTMLTextTrackWithSubtitleTrackId(e) + } + get keysystems() { + return this.keySystemAdapter.availableKeySystems + } + setProtectionData(e) { + this.keySystemAdapter.initialize(e) + } + generateKeyRequest(e, t) { + this.keySystemAdapter.generateRequest(e, t), this.rtcService.licenseChallengeReceived({ + keyuri: e + }) + } + setLicenseResponse(e, t) { + this.keySystemAdapter.setLicenseResponse(e, t) + } + get bufferInfo$() { + return this.publicQueries$.pipe(La(e => { + const [, t] = e, i = fg().getQuery().currentConfig; + return an(t.timeupdate$, t.bufferedRangeTuple$).pipe(ao(1e3), hr(() => { + var e = t.currentTime; + return { + combined: t.getCombinedBufferInfo(e, i.maxBufferHole), + sbTuple: t.getBufferInfo(e, i.maxBufferHole) + } + })) + })) + } + bufferInfoByType$(t) { + return this.bufferInfo$.pipe(hr(e => null === (e = null == e ? void 0 : e.sbTuple) || void 0 === e ? void 0 : e[t])) + } + levelWithPersistentId(e) { + this.logger.warn("levelWithPersistentId is deprecated") + } + startLoad(e) { + this.logger.warn("startLoad is deprecated"), ne(e) && (this.logger.warn(`[seek] Seeking to ${null==e?void 0:e.toFixed(3)} via deprecated "startLoad" method. Use loadSource(url, options, startTime) instead.`), this.seekTo = e) + } + stopLoad() {} + get config() { + return Object.assign(Object.assign({}, de(mg())), { + set startPosition(e) { + Qe().warn(`Setting start position ${null==e?void 0:e.toFixed(3)} using deprecated method`), fg().setStartTime(e) + } + }) + } + get media() { + return null != this.mediaElement$.value + } + set subtitleDisplay(e) { + this.logger.warn(`set subtitleDisplay ${e} is deprecated`) + } + } + }, "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || Jy).Hls = t() +}(!1); +//# sourceMappingURL=hls.js.map \ No newline at end of file diff --git a/src/renderer/apple-hls.js b/src/renderer/apple-hls.js index 854c4bc8..7b414d26 100644 --- a/src/renderer/apple-hls.js +++ b/src/renderer/apple-hls.js @@ -1,31057 +1,49963 @@ -/*! For license information please see hls.js.LICENSE.txt */ -!function Ky(Hy) { - const jy = this; - var e, t; - e = this, - t = function() { - "use strict"; - var x, e = e=>e && e.Math === Math && e, d = e("object" == typeof globalThis && globalThis) || e("object" == typeof window && window) || e("object" == typeof jy && jy) || e("object" == typeof global && global) || Function("return this")(); - class l { - constructor() { - this.keySize = null, - this.ksRows = null, - this.keySchedule = null, - this.invKeySchedule = null, - this.rcon = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54], - this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)], - this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)], - this.sBox = new Uint32Array(256), - this.invSBox = new Uint32Array(256), - this.key = new Uint32Array(0), - this.initTable() - } - uint8ArrayToUint32Array_(e) { - const t = new DataView(e) - , i = Math.floor(t.byteLength / 4) - , r = new Uint32Array(i); - for (let e = 0; e < i; e++) - r[e] = t.getUint32(4 * e); - return r - } - initTable() { - const e = this["sBox"] - , t = this["invSBox"] - , i = this["subMix"] - , r = i[0] - , n = i[1] - , s = i[2] - , a = i[3] - , o = this["invSubMix"] - , d = o[0] - , l = o[1] - , u = o[2] - , c = o[3] - , h = new Uint32Array(256); - let p = 0 - , f = 0 - , m = 0; - for (m = 0; m < 256; m++) - h[m] = m < 128 ? m << 1 : m << 1 ^ 283; - for (m = 0; m < 256; m++) { - var g = (g = f ^ f << 1 ^ f << 2 ^ f << 3 ^ f << 4) >>> 8 ^ 255 & g ^ 99; - e[p] = g, - t[g] = p; - const o = h[p] - , m = h[o] - , v = h[m]; - var y = 257 * h[g] ^ 16843008 * g; - r[p] = y << 24 | y >>> 8, - n[p] = y << 16 | y >>> 16, - s[p] = y << 8 | y >>> 24, - a[p] = y, - y = 16843009 * v ^ 65537 * m ^ 257 * o ^ 16843008 * p, - d[g] = y << 24 | y >>> 8, - l[g] = y << 16 | y >>> 16, - u[g] = y << 8 | y >>> 24, - c[g] = y, - p ? (p = o ^ h[h[h[v ^ o]]], - f ^= h[h[f]]) : p = f = 1 +/*! For license information please see hls.js.LICENSE.txt +TL,DR: Don't misuse this file for piracy purpose, all rights of this file and its usage belong to Apple and media copyright holders*/ +(function __HLS_UMD_BUNDLE__(__IN_WORKER__){const self = this; + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Hls = factory()); + })(this, (function () { 'use strict'; + + function hasUMDWorker() { + return typeof __HLS_UMD_BUNDLE__ === 'function'; + } + + const check = (it) => it && it.Math === Math && it; + var global$1 = // eslint-disable-next-line no-undef + (check(typeof globalThis == 'object' && globalThis) || + check(typeof window == 'object' && window) || + check(typeof self == 'object' && self) || + check(typeof global == 'object' && global) || + Function('return this')()); + + + class JSAESDecryptor { + constructor() { + this.keySize = null; + this.ksRows = null; + this.keySchedule = null; + this.invKeySchedule = null; + // Static after running initTable + this.rcon = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54]; + this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]; + this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]; + this.sBox = new Uint32Array(256); + this.invSBox = new Uint32Array(256); + // Changes during runtime + this.key = new Uint32Array(0); + this.initTable(); + } + // Using view.getUint32() also swaps the byte order. + uint8ArrayToUint32Array_(arrayBuffer) { + const view = new DataView(arrayBuffer); + const length = Math.floor(view.byteLength / 4); + const newArray = new Uint32Array(length); + for (let i = 0; i < length; i++) { + newArray[i] = view.getUint32(i * 4); + } + return newArray; + } + initTable() { + const { sBox } = this; + const { invSBox } = this; + const { subMix } = this; + const subMix0 = subMix[0]; + const subMix1 = subMix[1]; + const subMix2 = subMix[2]; + const subMix3 = subMix[3]; + const { invSubMix } = this; + const invSubMix0 = invSubMix[0]; + const invSubMix1 = invSubMix[1]; + const invSubMix2 = invSubMix[2]; + const invSubMix3 = invSubMix[3]; + const d = new Uint32Array(256); + let x = 0; + let xi = 0; + let i = 0; + for (i = 0; i < 256; i++) { + if (i < 128) { + d[i] = i << 1; + } + else { + d[i] = (i << 1) ^ 283; + } + } + for (i = 0; i < 256; i++) { + let sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); + sx = (sx >>> 8) ^ (sx & 255) ^ 99; + sBox[x] = sx; + invSBox[sx] = x; + // Compute multiplication + const x2 = d[x]; + const x4 = d[x2]; + const x8 = d[x4]; + // Compute sub/invSub bytes, mix columns tables + let t = (d[sx] * 257) ^ (sx * 16843008); + subMix0[x] = (t << 24) | (t >>> 8); + subMix1[x] = (t << 16) | (t >>> 16); + subMix2[x] = (t << 8) | (t >>> 24); + subMix3[x] = t; + // Compute inv sub bytes, inv mix columns tables + t = (x8 * 16843009) ^ (x4 * 65537) ^ (x2 * 257) ^ (x * 16843008); + invSubMix0[sx] = (t << 24) | (t >>> 8); + invSubMix1[sx] = (t << 16) | (t >>> 16); + invSubMix2[sx] = (t << 8) | (t >>> 24); + invSubMix3[sx] = t; + // Compute next counter + if (!x) { + x = xi = 1; + } + else { + x = x2 ^ d[d[d[x8 ^ x2]]]; + xi ^= d[d[xi]]; + } + } + } + expandKey(keyBuffer) { + // convert keyBuffer to Uint32Array + const key = this.uint8ArrayToUint32Array_(keyBuffer); + let sameKey = true; + let offset = 0; + while (offset < key.length && sameKey) { + sameKey = key[offset] === this.key[offset]; + offset++; + } + if (sameKey) { + return; + } + this.key = key; + const keySize = (this.keySize = key.length); + if (keySize !== 4 && keySize !== 6 && keySize !== 8) { + throw new Error('Invalid aes key size=' + keySize); + } + const ksRows = (this.ksRows = (keySize + 6 + 1) * 4); + let ksRow; + let invKsRow; + const keySchedule = (this.keySchedule = new Uint32Array(ksRows)); + const invKeySchedule = (this.invKeySchedule = new Uint32Array(ksRows)); + const sbox = this.sBox; + const { rcon } = this; + const { invSubMix } = this; + const invSubMix0 = invSubMix[0]; + const invSubMix1 = invSubMix[1]; + const invSubMix2 = invSubMix[2]; + const invSubMix3 = invSubMix[3]; + let prev; + let t; + for (ksRow = 0; ksRow < ksRows; ksRow++) { + if (ksRow < keySize) { + prev = keySchedule[ksRow] = key[ksRow]; + continue; + } + t = prev; + if (ksRow % keySize === 0) { + // Rot word + t = (t << 8) | (t >>> 24); + // Sub word + t = (sbox[t >>> 24] << 24) | (sbox[(t >>> 16) & 255] << 16) | (sbox[(t >>> 8) & 255] << 8) | sbox[t & 255]; + // Mix Rcon + t ^= rcon[(ksRow / keySize) | 0] << 24; + } + else if (keySize > 6 && ksRow % keySize === 4) { + // Sub word + t = (sbox[t >>> 24] << 24) | (sbox[(t >>> 16) & 255] << 16) | (sbox[(t >>> 8) & 255] << 8) | sbox[t & 255]; + } + keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0; + } + for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { + ksRow = ksRows - invKsRow; + if (invKsRow & 3) { + t = keySchedule[ksRow]; + } + else { + t = keySchedule[ksRow - 4]; + } + if (invKsRow < 4 || ksRow <= 4) { + invKeySchedule[invKsRow] = t; + } + else { + invKeySchedule[invKsRow] = invSubMix0[sbox[t >>> 24]] ^ invSubMix1[sbox[(t >>> 16) & 255]] ^ invSubMix2[sbox[(t >>> 8) & 255]] ^ invSubMix3[sbox[t & 255]]; + } + invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0; + } + } + // Adding this as a method greatly improves performance. + networkToHostOrderSwap(word) { + return (word << 24) | ((word & 65280) << 8) | ((word & 16711680) >> 8) | (word >>> 24); + } + decrypt(inputArrayBuffer, offset, aesIV) { + const nRounds = this.keySize + 6; + const { invKeySchedule } = this; + const invSBOX = this.invSBox; + const { invSubMix } = this; + const invSubMix0 = invSubMix[0]; + const invSubMix1 = invSubMix[1]; + const invSubMix2 = invSubMix[2]; + const invSubMix3 = invSubMix[3]; + const initVector = this.uint8ArrayToUint32Array_(aesIV); + let initVector0 = initVector[0]; + let initVector1 = initVector[1]; + let initVector2 = initVector[2]; + let initVector3 = initVector[3]; + const inputInt32 = new Int32Array(inputArrayBuffer); + const outputInt32 = new Int32Array(inputInt32.length); + let t0, t1, t2, t3; + let s0, s1, s2, s3; + let inputWords0, inputWords1, inputWords2, inputWords3; + let ksRow, i; + const swapWord = this.networkToHostOrderSwap; + while (offset < inputInt32.length) { + inputWords0 = swapWord(inputInt32[offset]); + inputWords1 = swapWord(inputInt32[offset + 1]); + inputWords2 = swapWord(inputInt32[offset + 2]); + inputWords3 = swapWord(inputInt32[offset + 3]); + s0 = inputWords0 ^ invKeySchedule[0]; + s1 = inputWords3 ^ invKeySchedule[1]; + s2 = inputWords2 ^ invKeySchedule[2]; + s3 = inputWords1 ^ invKeySchedule[3]; + ksRow = 4; + // Iterate through the rounds of decryption + for (i = 1; i < nRounds; i++) { + t0 = invSubMix0[s0 >>> 24] ^ invSubMix1[(s1 >> 16) & 255] ^ invSubMix2[(s2 >> 8) & 255] ^ invSubMix3[s3 & 255] ^ invKeySchedule[ksRow]; + t1 = invSubMix0[s1 >>> 24] ^ invSubMix1[(s2 >> 16) & 255] ^ invSubMix2[(s3 >> 8) & 255] ^ invSubMix3[s0 & 255] ^ invKeySchedule[ksRow + 1]; + t2 = invSubMix0[s2 >>> 24] ^ invSubMix1[(s3 >> 16) & 255] ^ invSubMix2[(s0 >> 8) & 255] ^ invSubMix3[s1 & 255] ^ invKeySchedule[ksRow + 2]; + t3 = invSubMix0[s3 >>> 24] ^ invSubMix1[(s0 >> 16) & 255] ^ invSubMix2[(s1 >> 8) & 255] ^ invSubMix3[s2 & 255] ^ invKeySchedule[ksRow + 3]; + // Update state + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + ksRow = ksRow + 4; + } + // Shift rows, sub bytes, add round key + t0 = (invSBOX[s0 >>> 24] << 24) ^ (invSBOX[(s1 >> 16) & 255] << 16) ^ (invSBOX[(s2 >> 8) & 255] << 8) ^ invSBOX[s3 & 255] ^ invKeySchedule[ksRow]; + t1 = (invSBOX[s1 >>> 24] << 24) ^ (invSBOX[(s2 >> 16) & 255] << 16) ^ (invSBOX[(s3 >> 8) & 255] << 8) ^ invSBOX[s0 & 255] ^ invKeySchedule[ksRow + 1]; + t2 = (invSBOX[s2 >>> 24] << 24) ^ (invSBOX[(s3 >> 16) & 255] << 16) ^ (invSBOX[(s0 >> 8) & 255] << 8) ^ invSBOX[s1 & 255] ^ invKeySchedule[ksRow + 2]; + t3 = (invSBOX[s3 >>> 24] << 24) ^ (invSBOX[(s0 >> 16) & 255] << 16) ^ (invSBOX[(s1 >> 8) & 255] << 8) ^ invSBOX[s2 & 255] ^ invKeySchedule[ksRow + 3]; + ksRow = ksRow + 3; + // Write + outputInt32[offset] = swapWord(t0 ^ initVector0); + outputInt32[offset + 1] = swapWord(t3 ^ initVector1); + outputInt32[offset + 2] = swapWord(t2 ^ initVector2); + outputInt32[offset + 3] = swapWord(t1 ^ initVector3); + // reset initVector to last 4 unsigned int + initVector0 = inputWords0; + initVector1 = inputWords1; + initVector2 = inputWords2; + initVector3 = inputWords3; + offset = offset + 4; + } + return outputInt32.buffer; + } + destroy() { + this.key = undefined; + this.keySize = undefined; + this.ksRows = undefined; + this.sBox = undefined; + this.invSBox = undefined; + this.subMix = undefined; + this.invSubMix = undefined; + this.keySchedule = undefined; + this.invKeySchedule = undefined; + this.rcon = undefined; + } + } + + function removePadding(decryptedData) { + const decryptedDataView = new Uint8Array(decryptedData); + const padding = decryptedDataView[decryptedData.byteLength - 1]; + const endOffset = decryptedData.byteLength - 1; + // Check for PKCS-7 padding: https://tools.ietf.org/html/rfc2315#section-10.3 + let checkedBytes = 0; + if (padding >= 1 && padding <= 16) { + for (let i = endOffset; i > endOffset - padding; i--) { + if (decryptedDataView[i] !== padding) { + break; + } + checkedBytes++; + } + } + if (checkedBytes === padding) { + decryptedData = decryptedData.slice(0, endOffset - padding + 1); // keep 0 till 'endOffset - padding', both inclusive, to remove the padding bytes + } + return decryptedData; + } + + // CryptoRPCServer can run in either Worker or main process depending on config. + // So we want to minimize the dependency for it in case it's running in Worker. + // Thus we use the vanilla RPCService interface that uses old-school callback + // patterns. It has zero dependency: no Promise, no RxJS, just plain JavaScript. + class CryptoRPCServer { + constructor(rpc, logger) { + this.rpc = rpc; + this.logger = logger; + this.decrypt = (key, iv, alg, cipherText, options) => callback => { + const crypto = global$1.crypto; + if ((options === null || options === void 0 ? void 0 : options.useJSCrypto) || !(crypto === null || crypto === void 0 ? void 0 : crypto.subtle)) { + /** + * JSCrypto + */ + const jsCrypto = new JSAESDecryptor(); + let plainText; + jsCrypto.expandKey(key); + const result = jsCrypto.decrypt(cipherText, 0, iv); + if (options.plainTextLength) { + plainText = result.slice(0, options.plainTextLength); // The input buffer doesn't have padding, just return the expected bytes. + } + else { + plainText = removePadding(result); + } + this.logger.info(`[JSCrypto]: ${cipherText.byteLength} => ${plainText.byteLength} bytes`); + callback(plainText, undefined, [plainText]); + } + else { + /** + * WebCrypto + */ + crypto.subtle + .importKey('raw', key, alg, false, ['decrypt']) + .then((key) => crypto.subtle.decrypt({ name: alg, iv }, key, cipherText)) + .then((plainText) => { + this.logger.info(`[WebCrypto]: ${cipherText.byteLength} => ${plainText.byteLength} bytes`); + callback(plainText, undefined, [plainText]); + }) + .catch((error) => callback(undefined, error)); + } + }; + rpc.register('decrypt', this.decrypt); + } + } + + const LoggerRPCClient = (rpcService) => { + const bindLogger = (bindings = []) => { + const logFn = (level) => (...args) => { + rpcService.invoke('logger.log', [bindings, level, ...args])((res, err) => { + if (err != null) + throw err; + }); + }; + const logger = {}; + ['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'qe'].forEach((k) => (logger[k] = logFn(k))); + logger.child = (b) => bindLogger([...bindings, b]); + return logger; + }; + return bindLogger(); + }; + + /** + * HLS Events + * + * + * + * + */ + /** + * @readonly + * @enum {string} + */ + var HlsEvent; + (function (HlsEvent) { + // fired before MediaSource is attaching to media element - data: { media } + HlsEvent["MEDIA_ATTACHING"] = "hlsMediaAttaching"; + // fired when MediaSource has been succesfully attached to media element - data: { media } + HlsEvent["MEDIA_ATTACHED"] = "hlsMediaAttached"; + // fired before detaching MediaSource from media element - data: { } + HlsEvent["MEDIA_DETACHING"] = "hlsMediaDetaching"; + // fired when MediaSource has been detached from media element + HlsEvent["MEDIA_DETACHED"] = "hlsMediaDetached"; + // fired when sourcebuffers have been created - data: { tracks : tracks } + HlsEvent["BUFFER_CREATED"] = "hlsBufferCreated"; + // fired when we append a segment to the buffer - data: { segment: segment object } + HlsEvent["BUFFER_APPENDING"] = "hlsBufferAppending"; + // fired when we are done with appending a media segment to the buffer - data : { parent : segment parent that triggered BUFFER_APPENDING, pending : nb of segments waiting for appending for this segment, timeRanges : bufferd time ranges } + HlsEvent["BUFFER_APPENDED"] = "hlsBufferAppended"; + // fired when the media buffer has been flushed + HlsEvent["BUFFER_FLUSHED"] = "hlsBufferFlushed"; + // fired to signal that a manifest loading starts - data: { url: manifestURL } + HlsEvent["MANIFEST_LOADING"] = "hlsManifestLoading"; + // fired after manifest has been loaded - data: { levels : [available quality levels including iframe levels], audioTracks : [ available audio tracks], subtitleTracks : [ available subtitle tracks], url : manifestURL, stats : { trequest, tfirst, tload, mtime}, audioMediaSelectionGroup: audio selection group, subtitleMediaSelectionGroup: subtitle selection group} + HlsEvent["MANIFEST_LOADED"] = "hlsManifestLoaded"; + // fired after manifest has been parsed - data: { levels : [available quality levels including iframe levels], firstLevel : index of first quality level appearing in Manifest, stats: stats, audio: audio codec, video: video codec, altAudio: if alternate audio present (true/false), audioTracks: audio tracks, audioMediaSelectionGroup: audio selection group} + HlsEvent["MANIFEST_PARSED"] = "hlsManifestParsed"; + // fired when a level switch is requested - data: { level : id of new level } + HlsEvent["LEVEL_SWITCHING"] = "hlsLevelSwitching"; + // fired when a level switch is effective - data: { level : id of new level } + HlsEvent["LEVEL_SWITCHED"] = "hlsLevelSwitched"; + // fired when a level playlist loading starts - data: { url : level URL, level : level, persistentId: persistent id of level being loaded} + HlsEvent["LEVEL_LOADING"] = "hlsLevelLoading"; + // fired when a level playlist loading finishes - data: { details : levelDetails object, level : level, persistentId : persistent id of loaded level, stats : { trequest, tfirst, tload, mtime}, playlistType : playlist type } + HlsEvent["LEVEL_LOADED"] = "hlsLevelLoaded"; + // fired when a level's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, level : id of updated level } + HlsEvent["LEVEL_UPDATED"] = "hlsLevelUpdated"; + // fired when levels list has changed due to any error + HlsEvent["LEVELS_CHANGED"] = "hlsLevelsChanged"; + // fired to notify that audio track lists has been updated - data: { audioTracks : audioTracks } + HlsEvent["AUDIO_TRACKS_UPDATED"] = "hlsAudioTracksUpdated"; + // fired when an audio track switch occurs - data: { id : audio track id, type: track type, url: url } // deprecated in favor AUDIO_TRACK_SWITCHING + HlsEvent["AUDIO_TRACK_SWITCH"] = "hlsAudioTrackSwitch"; + // fired when an audio track switch actually occurs - data: { id : audio track id } + HlsEvent["AUDIO_TRACK_SWITCHED"] = "hlsAudioTrackSwitched"; + // fired when an audio track loading finishes - data: { details : levelDetails object, id : audio track id, stats : { trequest, tfirst, tload, mtime } } + HlsEvent["AUDIO_TRACK_LOADED"] = "hlsAudioTrackLoaded"; + // fired to notify that subtitle track lists has been updated - data: { subtitleTracks : subtitleTracks } + HlsEvent["SUBTITLE_TRACKS_UPDATED"] = "hlsSubtitleTracksUpdated"; + // fired to notify that subtitle HTML5 text tracks have been created - data: undefined + HlsEvent["SUBTITLE_TRACKS_CREATED"] = "hlsSubtitleTracksCreated"; + // fired when an subtitle track switch occurs - data: { track : subtitle track } + HlsEvent["SUBTITLE_TRACK_SWITCH"] = "hlsSubtitleTrackSwitch"; + // fired when inline webvtt styles have been parsed - data: { styles: styles } + HlsEvent["INLINE_STYLES_PARSED"] = "hlsInlineStylesParsed"; + // fired when all the session data URI loading finished - data: { } + HlsEvent["SESSION_DATA_COMPLETE"] = "hlsSessionDataComplete"; + // fired when a fragment loading starts - data: { frag : fragment object } + HlsEvent["FRAG_LOADING"] = "hlsFragLoading"; + // fired when a fragment loading is completed - data: { frag : fragment object, payload : fragment payload, stats : { trequest, tfirst, tload, length } } + HlsEvent["FRAG_LOADED"] = "hlsFragLoaded"; + // fired when fragment remuxed MP4 boxes have all been appended into SourceBuffer - data: { id : demuxer id, frag : fragment object, stats : { trequest, tfirst, tload, tparsed, tappendStart, tbuffered, length, bwEstimate } } + HlsEvent["FRAG_BUFFERED"] = "hlsFragBuffered"; + // fired when fragment matching with current media position is changing - data : { frag : fragment object } + HlsEvent["FRAG_CHANGED"] = "hlsFragChanged"; + // Identifier for an internal error event - data: { type : error type, details : error details, fatal : emitter's suggestion whether the error is fatal or not. can be overruled by handler } + HlsEvent["INTERNAL_ERROR"] = "hlsInternalError"; + // Identifier for an public error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data } + HlsEvent["ERROR"] = "hlsError"; + // fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example - data: { } + HlsEvent["DESTROYING"] = "hlsDestroying"; + // Key request started data: { keyuri: '' , decryptdata: DecryptData object, timestamp: timestamp of the event } + HlsEvent["KEY_REQUEST_STARTED"] = "hlsKeyRequestStarted"; + // data: { 'keyuri': 'licenseChallenge': Uint8Array(challengeBytes) keysystem: } + HlsEvent["LICENSE_CHALLENGE_CREATED"] = "hlsLicenseChallengeCreated"; + // EME: + // Session remove() was called and returned license-release message. data: { keysystem: '', itemId: itemId, releaseRecord: { CDM specific record destruction } } + HlsEvent["LICENSE_RELEASED"] = "hlsLicenseReleased"; + // fired when a decrypt key loading is completed - data: { decryptdata: '', keyuri: '', stats : { trequest, tfirst, tload }, timestamp: timestamp of the event } + HlsEvent["KEY_LOADED"] = "hlsKeyLoaded"; + // We encountered a url that doesn't start with http data: { uri: ''} + HlsEvent["UNRESOLVED_URI_LOADING"] = "hlsUnresolvedUriLoading"; + // fired when trickplay rate changing completed + HlsEvent["DESIRED_RATE_CHANGED"] = "hlsDesiredRateChanged"; + // data: { playbackLikelyToKeepUp } + HlsEvent["PLAYER_STATE_CHANGE"] = "hlsPlayerStateChange"; + // When seek starts data: {} + HlsEvent["SEEKING"] = "hlsSeeking"; + // When seek ends data: {} + HlsEvent["SEEKED"] = "hlsSeeked"; + // When stall detected. Stream controller decides if it will report an error. data: { isLowBufferStall: true|false } + HlsEvent["STALLED"] = "hlsStalled"; + // When resumed from stall, either playback restart or user hit pause. + HlsEvent["RESUME_FROM_STALL"] = "hlsResumeFromStall"; + // Item fully appended + HlsEvent["READY_FOR_NEXT_ITEM"] = "hlsReadyForNextItem"; + // Playback transitioned to next item + HlsEvent["ITEM_TRANSITIONED"] = "hlsItemTransitioned"; + // Evict loading item + HlsEvent["ITEM_EVICTED"] = "hlsItemEvicted"; + // New EXT-X-DATERANGE data available + HlsEvent["DATERANGE_UPDATED"] = "hlsDaterangeUpdated"; + })(HlsEvent || (HlsEvent = {})); + var HlsEvent$1 = HlsEvent; + + /* + * Demuxer Events + * + * + */ + /** + * @readonly + * @enum {string} + */ + var DemuxerEvent; + (function (DemuxerEvent) { + // fired when Init Segment has been extracted from fragment - data: { tracks: tracks } + DemuxerEvent["FRAG_PARSING_INIT_SEGMENT"] = "hlsFragParsingInitSegment"; + // fired when data have been extracted from fragment - data: { data1: segment, startPTS: start PTS, endPTS: end PTS, startDTS: start DTS, endDTS: end DTS, type: video / audio, nb: number of samples, dropped: is dropped } + DemuxerEvent["FRAG_PARSING_DATA"] = "hlsFragParsingData"; + // fired when fragment parsing is completed + DemuxerEvent["FRAG_PARSED"] = "hlsFragParsed"; + // fired when the first timestamp is found - data: { initPTS90k: initPTS90k } + DemuxerEvent["INIT_PTS_FOUND"] = "hlsInitPtsFound"; + })(DemuxerEvent || (DemuxerEvent = {})); + + /** + * HLS Error + * + * + * + * + */ + class HlsError extends Error { + constructor(type, details, fatal, reason, response) { + super(reason); + this.type = type; + this.details = details; + this.fatal = fatal; + this.reason = reason; + this.response = response; + this.handled = false; + } + } + // Inherited error codes from Core Media + const PlaylistNotReceived = { code: -12884, text: 'Playlist not received' }; + const CryptResponseReceivedSlowly = { code: -16833, text: 'Crypt key received slowly' }; + const LivePlaylistUpdateError = { code: -12888, text: 'Live playlist not updated' }; + const NoResponseFromMediaRequest = { code: -12889, text: 'No response for fragment' }; + const IncompatibleAsset = { code: -12927, text: 'IncompatibleAsset' }; + const CorruptStream = { code: -16041, text: 'Corrupt fragment' }; + const InternalError = { code: -12645, text: 'InternalException' }; + const CantSwitchInTime = { code: -12644, text: 'CantSwitchInTime' }; + const VideoDecoderBadDataErr = { code: -12909, text: 'Buffer error' }; + const InsufficientDataAvailable = { code: -12928, text: 'Incomplete data' }; + const AllocationFailed = { code: -12862, text: 'AllocationFailed' }; + const PlaylistErrorMissingEXTM3U = { code: -12269, text: 'Response doesnt have #EXTM3U tag' }; + const PlaylistErrorInvalidEntry = { code: -12264, text: 'Invalid entry' }; + const PlaylistErrorBadTargetDuration = { code: -12271, text: 'Invalid targetduration' }; + const NoValidAlternates = { code: -12925, text: 'No valid alternates' }; + const FormatError = { code: -12642, text: 'Incorrect playlist format' }; + // HLSJS Specific error codes + const UnsupportedKeySystemError = { code: -60000, text: 'Unsupported Key System' }; + const EmptyLoadSourceError = { code: -60001, text: 'Empty loadSource url' }; + const UndefinedItemIdError = { code: -60002, text: 'Undefined itemId' }; + const ManifestParseError = { code: -60003, text: 'Manifest parse error' }; + const DemuxWorkerError = { code: -60004, text: 'Demux worker error' }; + const DecryptWorkerError = { code: -60005, text: 'Decrypt worker error' }; + const OutOfRangeSeekError = { code: -60006, text: 'Seeked out of playable range' }; + const ExceptionInKeyLoadError = { code: -60007, text: 'Exception in Key load' }; + const FragmentAbortError$1 = { code: -60008, text: 'Fragment abort error' }; + const ManifestTimeoutError = { code: -60009, text: 'Manifest Timeout Error' }; + const PlaylistTimeoutError = { code: -60010, text: 'Playlist Timeout Error' }; + const FragmentTimeoutError = { code: -60011, text: 'Fragment Timeout Error' }; + const IncompleteSessionData = { code: -60012, text: 'Session data not complete after loading all items' }; + const SessionDataLoadTimeout = { code: -60013, text: 'Session data load timeout' }; + const FailedDemuxerSanityCheck = { code: -60014, text: 'Failed demuxer sanity check' }; + const InvalidADTSSamplingIndex = { code: -60015, text: 'Invalid ADTS sampling index' }; + const DemuxerNotFound = { code: -60016, text: 'No demux matching with content found' }; + const InvalidInitTimestamp = { code: -60017, text: 'Invalid initPTS or initDTS' }; + const NoAVSamplesFound = { code: -60018, text: 'no audio/video samples found' }; + const NoTSSyncByteFound = { code: -60019, text: 'TS packet did not start with 0x47' }; + const PESDidNotStartWithADTS = { code: -60020, text: 'AAC PES did not start with ADTS header' }; + const NoADTSHeaderInPES = { code: -60021, text: 'No ADTS header found in AAC PES' }; + const InvalidDolbyAudioMagic = { code: -60022, text: 'Invalid dolby audio magic' }; + const FailedToAllocateVideoMdat = { code: -60023, text: 'Fail allocating video mdat' }; + const FailedToAllocateAudioMdat = { code: -60024, text: 'Fail allocating audio mdat' }; + const InsufficientEC3Data = { code: -60025, text: 'Error parsing ec-3, not enough data' }; + const InvalidEC3Magic = { code: -60026, text: 'Invalid ec-3 magic' }; + const ReservedStreamType = { code: -60027, text: 'Reserved stream type' }; + const InsufficientAC3Data = { code: -60028, text: 'error parsing ac-3, not enough data' }; + const InvalidAC3Magic = { code: -60029, text: 'Invalid ac-3 magic' }; + const InvalidAC3SamplingRateCode = { code: -60030, text: 'Invalid ac-3 samplingRateCode' }; + const PlaylistErrorInvalidEXTXDEFINE = { code: -61000, text: 'Encountered undefined/not imported EXT-X-DEFINE property' }; + const PlaylistErrorMissingImportReference = { code: -61001, text: 'IMPORT references variable not in master playlist and/or NAME' }; + const PlaylistErrorInvalidSERVERURI = { code: -61002, text: 'Encountered undefined/invalid SERVER-URI attribute for EXT-X-CONTENT-STEERING tag' }; + const PlaylistErrorInvalidPATHWAYID = { code: -61003, text: 'Encountered invalid PATHWAY-ID attribute for EXT-X-CONTENT-STEERING tag' }; + const PlaylistErrorInvalidSCORE = { code: -61004, text: 'Encountered negative/non-number SCORE property' }; + const KeySystemFailedToUpdateSession = { code: -62000, text: 'KeySystem: Promise Rejected while updating session' }; + const KeySystemFailedToGenerateLicenseRenewal = { code: -62001, text: 'KeySystem: Failed to generate license renewal' }; + const KeySystemFailedToGenerateLicenseRequest = { code: -62002, text: 'KeySystem: Failed to generate license request' }; + const KeySystemAbort = { code: -62003, text: 'KeySystem: Aborted' }; + const KeySystemUnexpectedStateTransition = { code: -62004, text: 'KeySystem: Unexpected state transition' }; + const KeySystemUnexpectedState = { code: -62005, text: 'KeySystem: Unexpected state' }; + const KeySystemCDMUnknownError = { code: -62006, text: 'KeySystem: Unknown error from CDM' }; + const KeySystemRequestTimedOut = { code: -62007, text: 'Key request timed out' }; + const KeySystemUnexpectedMETHOD = { code: -62008, text: 'Unexpected METHOD attribute' }; + const KeySystemUnmatchedString = { code: -62009, text: 'KeySystem: string does not match' }; + const KeySystemInternalError = { code: -62010, text: 'KeySystem: internal-error' }; + const KeySystemOutputRestricted = { code: -62011, text: 'KeySystem: output-restricted' }; + const KeySystemSetupError = { code: -62012, text: 'KeySystem: setup error' }; + const KeySystemFailedToInitialize = { code: -62013, text: 'KeySystem: could not initialize' }; + const KeySystemFailedToCreateSession = { code: -62014, text: 'KeySystem: could not create session' }; + const KeySystemUndefinedNavigator = { code: -62015, text: 'KeySystem: navigator undefined' }; + const KeySystemNoKeySystemsToTry = { code: -62016, text: 'KeySystem: no key systems to try' }; + const KeySystemNoConstructor = { code: -62017, text: 'KeySystem: No constructor' }; + const KeySystemNoKeySystemAccess = { code: -62018, text: 'KeySystem: No KeySystemAccess' }; + const KeySystemCertificateLoadError = { code: -62019, text: 'KeySystem: Certificate Load Error' }; + class PlaylistParsingError extends HlsError { + constructor(type, details, fatal, reason, response) { + super(type, details, fatal, reason, response); + this.response = response; + } + } + const ErrorResponses = { + // Inherited error codes from Core Media + PlaylistNotReceived, + CryptResponseReceivedSlowly, + LivePlaylistUpdateError, + NoResponseFromMediaRequest, + IncompatibleAsset, + CorruptStream, + InternalError, + CantSwitchInTime, + VideoDecoderBadDataErr, + InsufficientDataAvailable, + AllocationFailed, + PlaylistErrorMissingEXTM3U, + PlaylistErrorInvalidEntry, + PlaylistErrorBadTargetDuration, + NoValidAlternates, + FormatError, + // HLSJS Specific error codes + UnsupportedKeySystemError, + EmptyLoadSourceError, + UndefinedItemIdError, + ManifestParseError, + DemuxWorkerError, + DecryptWorkerError, + OutOfRangeSeekError, + ExceptionInKeyLoadError, + FragmentAbortError: FragmentAbortError$1, + ManifestTimeoutError, + PlaylistTimeoutError, + FragmentTimeoutError, + IncompleteSessionData, + SessionDataLoadTimeout, + FailedDemuxerSanityCheck, + InvalidADTSSamplingIndex, + DemuxerNotFound, + InvalidAC3Magic, + InvalidInitTimestamp, + NoAVSamplesFound, + NoTSSyncByteFound, + PESDidNotStartWithADTS, + NoADTSHeaderInPES, + InvalidDolbyAudioMagic, + FailedToAllocateVideoMdat, + FailedToAllocateAudioMdat, + InsufficientEC3Data, + InvalidEC3Magic, + ReservedStreamType, + InsufficientAC3Data, + InvalidAC3SamplingRateCode, + PlaylistErrorInvalidEXTXDEFINE, + PlaylistErrorMissingImportReference, + PlaylistErrorInvalidSERVERURI, + PlaylistErrorInvalidPATHWAYID, + PlaylistErrorInvalidSCORE, + KeySystemFailedToUpdateSession, + KeySystemFailedToGenerateLicenseRenewal, + KeySystemFailedToGenerateLicenseRequest, + KeySystemAbort, + KeySystemUnexpectedStateTransition, + KeySystemUnexpectedState, + KeySystemCDMUnknownError, + KeySystemRequestTimedOut, + KeySystemUnexpectedMETHOD, + KeySystemUnmatchedString, + KeySystemInternalError, + KeySystemOutputRestricted, + KeySystemSetupError, + KeySystemFailedToInitialize, + KeySystemFailedToCreateSession, + KeySystemUndefinedNavigator, + KeySystemNoKeySystemsToTry, + KeySystemNoConstructor, + KeySystemNoKeySystemAccess, + KeySystemCertificateLoadError, + }; + const ErrorTypes = { + // Identifier for a network error (loading error / timeout ...) + NETWORK_ERROR: 'networkError', + // Identifier for a media Error (video/parsing/mediasource error) + MEDIA_ERROR: 'mediaError', + // Identifier for a mux Error (demuxing/remuxing) + MUX_ERROR: 'muxError', + // Identifier for a key system error (EME) + KEY_SYSTEM_ERROR: 'keySystemError', + // Identifier for all other errors + OTHER_ERROR: 'otherError', + }; + const ErrorDetails = { + // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }} + MANIFEST_LOAD_ERROR: 'manifestLoadError', + // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }} + MANIFEST_LOAD_TIMEOUT: 'manifestLoadTimeOut', + // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }} + MANIFEST_PARSING_ERROR: 'manifestParsingError', + // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }} + MANIFEST_INCOMPATIBLE_CODECS_ERROR: 'manifestIncompatibleCodecsError', + // Identifier for a manifest with only incompatible video-range error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }} + MANIFEST_INCOMPATIBLE_VIDEO_RANGE_ERROR: 'manifestIncompatibleVideoRangeError', + // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }} + LEVEL_LOAD_ERROR: 'levelLoadError', + // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }} + LEVEL_LOAD_TIMEOUT: 'levelLoadTimeOut', + // Identifier for a level switch error - data: { level : faulty level Id, event : error description, response : { code: error code, text: error text }} + LEVEL_SWITCH_ERROR: 'levelSwitchError', + // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }} + AUDIO_TRACK_LOAD_ERROR: 'audioTrackLoadError', + // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }} + AUDIO_TRACK_LOAD_TIMEOUT: 'audioTrackLoadTimeOut', + // Identifier for an subtitle track load error - data: { url : faulty URL, response : { code: error code, text: error text }} + SUBTITLE_TRACK_LOAD_ERROR: 'subtitleTrackLoadError', + // Identifier for an subtitle track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }} + SUBTITLE_TRACK_LOAD_TIMEOUT: 'subtitleTrackLoadTimeout', + // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }} + FRAG_LOAD_ERROR: 'fragLoadError', + // Identifier for fragment loop loading error - data: { frag : fragment object, fatal:, response: { code: error code, text: error text }} + FRAG_LOOP_LOADING_ERROR: 'fragLoopLoadingError', + // Identifier for fragment load timeout error - data: { frag : fragment object, response : { code: error code, text: error text }} + FRAG_LOAD_TIMEOUT: 'fragLoadTimeOut', + // Identifier for a fragment decryption error event - data: {id : demuxer Id,frag: fragment object, reason : parsing error description , response : { code: error code, text: error text }} + FRAG_DECRYPT_ERROR: 'fragDecryptError', + // Identifier for a fragment parsing error event - data: { id : demuxer Id, reason : parsing error description, response : { code: error code, text: error text } } + // will be renamed DEMUX_PARSING_ERROR and switched to MUX_ERROR in the next major release + FRAG_PARSING_ERROR: 'fragParsingError', + // Identifier for a remux alloc error event - data: { id : demuxer Id, frag : fragment object, bytes : nb of bytes on which allocation failed , reason : error text, response: { code: error code, text: error text }} + REMUX_ALLOC_ERROR: 'remuxAllocError', + // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { err : exception , mimeType : mimeType , response : { code: error code, text: error text }} + BUFFER_ADD_CODEC_ERROR: 'bufferAddCodecError', + // Identifier for a buffer append error - data: {append error description, response : { code: error code, text: error text }} + BUFFER_APPEND_ERROR: 'bufferAppendError', + // Identifier for a buffer appending error event - data: {appending error description, response : { code: error code, text: error text }} + BUFFER_APPENDING_ERROR: 'bufferAppendingError', + // Identifier for a buffer stalled error event - data: {fatal:, bufferLen: , response : { code: error code, text: error text }} + BUFFER_STALLED_ERROR: 'bufferStalledError', + // Identifier for a buffer full event - data: {fatal:, response : { code: error code, text: error text }} + BUFFER_FULL_ERROR: 'bufferFullError', + // Identifier for a buffer seek over hole event- data: {fatal:, response : { code: error code, text: error text }} + BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole', + // Identifier for a buffer nudge on stall (playback is stuck although currentTime is in a buffered area) data: {fatal:, response : { code: error code, text: error text }} + BUFFER_NUDGE_ON_STALL: 'bufferNudgeOnStall', + // Identifier for an internal exception happening inside hls.js while handling an event + // data: { url: , fatal:, response: { code: error code, text: error text } } + INTERNAL_EXCEPTION: 'internalException', + // Malformed WebVTT contents + WEBVTT_EXCEPTION: 'webVTTException', + // KEY REQUEST ERRORS + // Identifier for decrypt key load error - data: { decryptdata: DecryptData object, stats: { tfirstissue, tlastissue, failCount } response: {code: status code returned from server, text: error message}} + KEY_LOAD_ERROR: 'keyLoadError', + // Identifier for decrypt key load timeout error - data: { decryptdata: DecryptData object, stats: { tfirstissue, tlastissue, failCount }, response: { code: error code, text: error message }} + KEY_LOAD_TIMEOUT: 'keyLoadTimeOut', + // Identifier for CDM error - data: { decryptdata: DecryptData object, stats: { tfirstissue, tlastissue, failCount }, reason: error message, response: { code: error code, text: error message }} + KEY_SYSTEM_GENERIC_ERROR: 'keySystemGenericError', + // data: { url: , fatal:, response: { code: error code, text: error text } } + CERT_LOAD_ERROR: 'certificateLoadError', + // data: { url: , fatal:, response: { code: error code, text: error text } } + CERT_LOAD_TIMEOUT: 'certificateLoadTimeOut', + // Identifier for session data item load error - data: { sessionId: '', response : { code: error code, text: error text }} + SESSION_DATA_LOAD_ERROR: 'sessionDataLoadError', + // Identifier for session data item load timeout error - data: { sessionId: '' , response : { code: error code, text: error text }} + SESSION_DATA_LOAD_TIMEOUT: 'sessionDataLoadTimeOut', + // Identifier for a Conetent Steering manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }} + STEERING_MANIFEST_LOAD_ERROR: 'steeringManifestLoadError', + // Identifier for a Conetent Steering manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }} + STEERING_MANIFEST_LOAD_TIMEOUT: 'steeringManifestLoadTimeOut', + // Identifier for a Conetent Steering manifest parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }} + STEERING_MANIFEST_PARSING_ERROR: 'steeringManifestParsingError', + }; + /** + * @brief If no other error fits, use this error. + */ + class ExceptionError extends HlsError { + constructor(fatal, reason, response) { + super(ErrorTypes.OTHER_ERROR, ErrorDetails.INTERNAL_EXCEPTION, fatal, reason, response); + } + } + + class FragParsingError extends HlsError { + constructor(fatal, reason, response) { + super(ErrorTypes.MEDIA_ERROR, ErrorDetails.FRAG_PARSING_ERROR, fatal, reason, response); + } + } + class RemuxAllocError extends HlsError { + constructor(fatal, reason, response, bytes) { + super(ErrorTypes.MUX_ERROR, ErrorDetails.REMUX_ALLOC_ERROR, fatal, reason, response); + this.bytes = bytes; + } + } + + function convertTimestampToSeconds(ts) { + return ts.baseTime / ts.timescale; + } + function convertSecondsToTimestamp(sec, timescale) { + return { + baseTime: Math.floor(sec * timescale), + timescale, + }; + } + function convertTimescale(ts, timescale) { + return { + baseTime: Math.floor((ts.baseTime * timescale) / ts.timescale), + timescale, + }; + } + function determineMinTimestamp(a, b) { + const aSec = convertTimestampToSeconds(a); + const bSec = convertTimestampToSeconds(b); + return aSec < bSec ? a : b; + } + function determineMaxTimestamp(a, b) { + const aSec = convertTimestampToSeconds(a); + const bSec = convertTimestampToSeconds(b); + return aSec > bSec ? a : b; + } + /** + * @returns returns a - b in seconds + */ + function diffSeconds(a, b) { + return convertTimestampToSeconds(a) - convertTimestampToSeconds(b); + } + + class EventEmitterPolyfill { + constructor() { + this.eventMap = {}; + } + _on(eventName, eventRecord, prepend = false) { + if (this.eventMap[eventName] == null) { + this.eventMap[eventName] = []; + } + if (prepend) { + this.eventMap[eventName].splice(0, 0, eventRecord); + } + else { + this.eventMap[eventName].push(eventRecord); + } + return this; + } + _off(eventName, record) { + if (this.eventMap[eventName] != null) { + this.eventMap[eventName] = this.eventMap[eventName].filter(r => r.listener !== record.listener); + if (this.eventMap[eventName].length === 0) { + delete this.eventMap[eventName]; + } + } + return this; + } + on(eventName, listener) { + return this._on(eventName, { listener, once: false }); + } + off(eventName, listener) { + return this._off(eventName, { listener }); + } + addListener(eventName, listener) { + return this.on(eventName, listener); + } + once(eventName, listener) { + return this._on(eventName, { listener, once: true }); + } + removeListener(eventName, listener) { + return this.off(eventName, listener); + } + removeAllListeners(event) { + delete this.eventMap[event]; + return this; + } + setMaxListeners(n) { + return this; + } + getMaxListeners() { + return Infinity; + } + // eslint-disable-next-line @typescript-eslint/ban-types + listeners(eventName) { + if (this.eventMap[eventName] == null) { + return []; + } + return this.eventMap[eventName].map(r => r.listener); + } + // eslint-disable-next-line @typescript-eslint/ban-types + rawListeners(eventName) { + return this.listeners(eventName); + } + emit(eventName, ...args) { + if (this.eventMap[eventName] == null) { + return false; + } + let emitted = false; + for (const record of this.eventMap[eventName]) { + try { + record.listener.apply(this, args); + // eslint-disable-next-line no-empty + } + catch (err) { } + emitted = true; + } + return emitted; + } + listenerCount(eventName) { + if (this.eventMap[eventName] == null) { + return 0; + } + return this.eventMap[eventName].length; + } + prependListener(eventName, listener) { + return this._on(eventName, { listener, once: false }, true); + } + prependOnceListener(eventName, listener) { + return this._on(eventName, { listener, once: true }, true); + } + eventNames() { + return Object.keys(this.eventMap); + } + } + const EventEmitter = typeof global$1.Buffer !== 'undefined' ? (r => r('events'))(require).EventEmitter : EventEmitterPolyfill; + + /** + * Simple adapter sub-class of Nodejs-like EventEmitter. + */ + class Observer extends EventEmitter { + /** + * We simply want to pass along the event-name itself + * in every call to a handler, which is the purpose of our `trigger` method + * extending the standard API. + */ + trigger(event, data) { + this.emit(event, data); + } + } + + + const loggerName$l = { name: 'ADTS' }; + const ADTS = { + getAudioConfig: function (observer, data, offset, audioCodec, logger) { + let adtsObjectType; // :int + let extensionSamplingIndex; // :int + let adtsChanelConfig; // :int + let config; + const userAgent = navigator.userAgent.toLowerCase(); + const adtsSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350]; + // byte 2 + adtsObjectType = ((data[offset + 2] & 192) >>> 6) + 1; + const adtsSamplingIndex = (data[offset + 2] & 60) >>> 2; + if (adtsSamplingIndex > adtsSamplingRates.length - 1) { + const payload = new FragParsingError(true, `invalid ADTS sampling index:${adtsSamplingIndex}`, ErrorResponses.InvalidADTSSamplingIndex); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return; + } + adtsChanelConfig = (data[offset + 2] & 1) << 2; + // byte 3 + adtsChanelConfig |= (data[offset + 3] & 192) >>> 6; + logger.info(loggerName$l, `manifest codec:${audioCodec},ADTS data:type:${adtsObjectType},samplingIndex:${adtsSamplingIndex}[${adtsSamplingRates[adtsSamplingIndex]}Hz],channelConfig:${adtsChanelConfig}`); + // firefox: freq less than 24kHz = AAC SBR (HE-AAC) + if (/firefox/i.test(userAgent)) { + if (adtsSamplingIndex >= 6) { + adtsObjectType = 5; + config = new Array(4); + // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies + // there is a factor 2 between frame sample rate and output sample rate + // multiply frequency by 2 (see table below, equivalent to substract 3) + extensionSamplingIndex = adtsSamplingIndex - 3; + } + else { + adtsObjectType = 2; + config = new Array(2); + } + // Android : always use AAC + } + else if (userAgent.indexOf('android') !== -1) { + adtsObjectType = 2; + config = new Array(2); + } + else { + /* for other browsers (Chrome/Vivaldi/Opera ...) + always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...) + */ + adtsObjectType = 5; + config = new Array(4); + // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz) + if ((audioCodec && (audioCodec.indexOf('mp4a.40.29') !== -1 || audioCodec.indexOf('mp4a.40.5') !== -1)) || (!audioCodec && adtsSamplingIndex >= 6)) { + // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies + // there is a factor 2 between frame sample rate and output sample rate + // multiply frequency by 2 (see table below, equivalent to substract 3) + extensionSamplingIndex = adtsSamplingIndex - 3; + } + else { + // if (manifest codec is AAC) OR (manifest codec not specified and mono audio) + // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo. + if ((audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1) || (!audioCodec && adtsChanelConfig === 1)) { + adtsObjectType = 2; + config = new Array(2); + } + extensionSamplingIndex = adtsSamplingIndex; + } + } + /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config + ISO 14496-3 (AAC).pdf - Table 1.13 Ãĸâ‚Ŧ” Syntax of AudioSpecificConfig() + Audio Profile / Audio Object Type + 0: Null + 1: AAC Main + 2: AAC LC (Low Complexity) + 3: AAC SSR (Scalable Sample Rate) + 4: AAC LTP (Long Term Prediction) + 5: SBR (Spectral Band Replication) + 6: AAC Scalable + sampling freq + 0: 96000 Hz + 1: 88200 Hz + 2: 64000 Hz + 3: 48000 Hz + 4: 44100 Hz + 5: 32000 Hz + 6: 24000 Hz + 7: 22050 Hz + 8: 16000 Hz + 9: 12000 Hz + 10: 11025 Hz + 11: 8000 Hz + 12: 7350 Hz + 13: Reserved + 14: Reserved + 15: frequency is written explictly + Channel Configurations + These are the channel configurations: + 0: Defined in AOT Specifc Config + 1: 1 channel: front-center + 2: 2 channels: front-left, front-right + */ + // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1 + config[0] = adtsObjectType << 3; + // samplingFrequencyIndex + config[0] |= (adtsSamplingIndex & 14) >> 1; + config[1] |= (adtsSamplingIndex & 1) << 7; + // channelConfiguration + config[1] |= adtsChanelConfig << 3; + if (adtsObjectType === 5) { + // extensionSamplingIndex + config[1] |= (extensionSamplingIndex & 14) >> 1; + config[2] = (extensionSamplingIndex & 1) << 7; + // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ??? + // https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc + config[2] |= 2 << 2; + config[3] = 0; + } + const audioConfig = { esdsConfig: config, samplerate: adtsSamplingRates[adtsSamplingIndex], channelCount: adtsChanelConfig, segmentCodec: 'aac', codec: 'mp4a.40.' + adtsObjectType }; + return audioConfig; + }, + }; + + class DemuxerBase { + constructor(observer, remuxer, config, typeSupported, logger) { + this.observer = observer; + this.remuxer = remuxer; + this.config = config; + this.typeSupported = typeSupported; + this.logger = logger; + } + static probe(data, logger) { + throw new Error('Method not implemented'); + } + resetTimeStamp(initPTS90k) { } + resetInitSegment(initSegment, duration, keyTagInfo, discontinuity) { } + destroy() { } + } + class EsDemuxer extends DemuxerBase { + constructor(observer, remuxer, config, typeSupported, logger) { + super(observer, remuxer, config, typeSupported, logger); + this.observer = observer; + this.remuxer = remuxer; + this.config = config; + this.typeSupported = typeSupported; + this.logger = logger; + this.esRemuxer = remuxer; + } + } + class RemuxerBase { + constructor(observer, config, logger) { + this.observer = observer; + this.config = config; + this.logger = logger; + } + resetInitSegment() { } + resetTimeStamp(initPTS90k) { } + destroy() { } + } + + /* + * 2018 Apple Inc. All rights reserved. + */ + var _a$1; + let te; + let td; + const BrowserBufferUtils = { + /** + * Convert a string object into a uint8Array containing utf-8 encoded text + * @param str The string to convert + * @returns A uint8Array containing utf-8 encoded text + + + */ + strToUtf8array(str) { + if (!te) { + te = new TextEncoder(); + } + return te.encode(str); + }, + /** + * Convert a uint8Array containing utf-8 encoded text into a string object + * @param array The array to convert containing utf-8 encoded text + * @returns A DOMString containing the decoded text + */ + utf8arrayToStr(array) { + if (!td) { + td = new TextDecoder('utf-8'); + } + return td.decode(array); + }, + }; + const NodeJSBufferUtils = { + /** + * Convert a string object into a uint8Array containing utf-8 encoded text + * @param str The string to convert + * @returns A uint8Array containing utf-8 encoded text + */ + strToUtf8array(str) { + const buffer = global$1.Buffer.from(str, 'utf-8'); + return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); + }, + /** + * Convert a uint8Array containing utf-8 encoded text into a string object + * @param array The array to convert containing utf-8 encoded text + * @returns A DOMString containing the decoded text + */ + utf8arrayToStr(array) { + return global$1.Buffer.from(array).toString('utf-8'); + }, + }; + const FallbackBufferUtils = { + /** + * Convert a string object into a uint8Array containing utf-8 encoded text + * @param str The string to convert + * @returns A uint8Array containing utf-8 encoded text + */ + strToUtf8array(str) { + const utf8 = unescape(encodeURIComponent(str)); + const result = new Uint8Array(utf8.length); + for (let i = 0; i < utf8.length; i++) { + result[i] = utf8.charCodeAt(i); + } + return result; + }, + /** + * Convert a uint8Array containing utf-8 encoded text into a string object + * @param array The array to convert containing utf-8 encoded text + * @returns A DOMString containing the decoded text + */ + utf8arrayToStr(array) { + return String.fromCharCode.apply(null, Array.from(array)); + }, + }; + let BufferUtils = FallbackBufferUtils; + if (typeof TextEncoder !== 'undefined' && typeof TextDecoder !== 'undefined') { + BufferUtils = BrowserBufferUtils; + } + else if (typeof ((_a$1 = global$1.Buffer) === null || _a$1 === void 0 ? void 0 : _a$1.from) === 'function') { + BufferUtils = NodeJSBufferUtils; + } + + + const loggerName$k = { name: 'ID3' }; + class ID3 { + // TODO: I am not comfortable with infinite loop .... + constructor(data, logger) { + this.logger = logger; + this._hasTimeStamp = false; + this._audioType = null; + this._length = 0; + this._frames = []; + let offset = 0, tagSize, endPos, header, len; + do { + header = ID3.readUTF(data, offset, 3); + offset += 3; + // first check for ID3 header + if (header === 'ID3') { + // v2.* tags only + // skip 16 bit version + this._minor = data[offset++]; + this._revision = data[offset++]; + const tagFlags = data[offset++]; // 1 byte flag (top 3 bits used) + if (tagFlags & 128) { + // is unsynchroized + this._unsynchronized = true; + this.logger.error(loggerName$k, 'id3 tag is unsynchronized'); + } + if (tagFlags & 64) { + this._hasExtendedHeader = true; + this.logger.warn(loggerName$k, 'id3 tag has extended header'); + } + // retrieve tag(s) length + // The ID3v2 tag size is the sum of the byte length of the extended + // header, the padding and the frames after unsynchronisation. If a + // footer is present this equals to ('total size' - 20) bytes, otherwise + // ('total size' - 10) bytes. + tagSize = ID3.readSynchSafeUint32(data.subarray(offset, offset + 4)); + offset += 4; + endPos = offset + tagSize; // tagSize accounts for extended header + if (this._hasExtendedHeader) { + // has extended header + const extendedHeaderSize = ID3.readSynchSafeUint32(data.subarray(offset, offset + 4)); + this.logger.warn(loggerName$k, `id3 tag has ${extendedHeaderSize}-byte extended header. usually 6 or 10 bytes`); + offset += extendedHeaderSize; + } + // read ID3 frames + if (this.minor > 2) { + this._parseID3Frames(data, offset, endPos); + } + else { + this.logger.error(loggerName$k, '[id3] doesn\'t support older than v2.3 tags'); + } + offset = endPos; + } + else if (header === '3DI') { + // http://id3.org/id3v2.4.0-structure chapter 3.4. ID3v2 footer + offset += 7; + } + else { + offset -= 3; + len = offset; + if (len) { + if (!this.hasTimeStamp) { + this.logger.warn(loggerName$k, 'ID3 tag found, but no timestamp'); + } + this._length = len; + this._payload = data.slice(0, len); + } + return; + } + } while (true); // eslint-disable-line + } + static isHeader(data, offset) { + if (data[offset] === 73 && data[offset + 1] === 68 && data[offset + 2] === 51) { + // check version is within range + if (data[offset + 3] < 255 && data[offset + 4] < 255) { + // check size is within range + if (data[offset + 6] < 128 && data[offset + 7] < 128 && data[offset + 8] < 128 && data[offset + 9] < 128) { + return true; + } + } + } + return false; + } + static readSynchSafeUint32(data) { + return (data[0] & 127) * 2097152 + (data[1] & 127) * 16384 + (data[2] & 127) * 128 + (data[3] & 127); + } + static readUTF(data, start, len) { + let result = '', offset = start; + const end = start + len; + do { + result += String.fromCharCode(data[offset++]); + } while (offset < end); + return result; + } + isID3Frame(data, offset) { + if (data[offset + 4] < 128 && data[offset + 5] < 128 && data[offset + 6] < 128 && data[offset + 7] < 128) { + return true; + } + return false; + } + decodeID3Frame(frame) { + if (frame.type === 'TXXX') { + return this.decodeTxxxFrame(frame); + } + else if (frame.type === 'WXXX') { + return this.decodeWxxxFrame(frame); + } + else if (frame.type === 'PRIV') { + return this.decodePrivFrame(frame); + } + else if (frame.type[0] === 'T') { + return this.decodeTextFrame(frame); + } + else { + return { key: frame.type, data: frame.data }; + } + } + decodeTxxxFrame(frame) { + /* + Format: + [0] = {Text Encoding} + [1-?] = {Description}\0{Value} + */ + if (frame.size < 2) { + return undefined; + } + if (frame.data[0] !== 3) { + // only support UTF-8 + return undefined; + } + let index = 1; + const description = this.id3utf8ArrayToStr(frame.data.subarray(index)); + index += description.length + 1; + const value = this.id3utf8ArrayToStr(frame.data.subarray(index)); + return { key: 'TXXX', description, data: value }; + } + decodeWxxxFrame(frame) { + /* + Format: + [0] = {Text Encoding} + [1-?] = {Description}\0{Value} + */ + if (frame.size < 2) { + return undefined; + } + if (frame.data[0] !== 3) { + // only support UTF-8 + return undefined; + } + let index = 1; + const description = this.id3utf8ArrayToStr(frame.data.subarray(index)); + index += description.length + 1; + // Need to use the BufferUtils version of utf8arrayToStr since it works + // with arrays that doesn't have a '\0' in the end of the array. + const value = BufferUtils.utf8arrayToStr(frame.data.subarray(index)); + return { key: 'WXXX', description, data: value }; + } + decodeTextFrame(frame) { + /* + Format: + [0] = {Text Encoding} + [1-?] = {Value} + */ + if (frame.size < 2) { + return undefined; + } + if (frame.data[0] !== 3) { + // only support UTF-8 + return undefined; + } + const data = frame.data.subarray(1); + return { key: frame.type, data: this.id3utf8ArrayToStr(data) }; + } + decodePrivFrame(frame) { + /* + Format: \0 + */ + if (frame.size < 2) { + return undefined; + } + const owner = this.id3utf8ArrayToStr(frame.data); + const privateData = frame.data.slice(owner.length + 1); + return { key: 'PRIV', info: owner, data: privateData }; + } + _extractID3Frame(data, frameId, frameLen, frameBodyOffset, endPos) { + const frameEnd = frameBodyOffset + frameLen; + let frame; + if (frameEnd <= endPos) { + frame = { type: frameId, data: data.slice(frameBodyOffset, frameEnd) }; + } + else { + this.logger.error(loggerName$k, `id3 frame ${frameId} size ${frameLen} exceeded ${endPos}`); + } + return frame; + } + _parseID3Frames(data, offset, endPos) { + let tagId, tagLen, tagStart, timestamp; + while (offset + 8 <= endPos) { + this.logger.info(loggerName$k, `[id3] _parseID3Frames ${offset} ${endPos}`); + if (!this.isID3Frame(data, offset)) { + this.logger.error(loggerName$k, `[id3] illegal id3 frame @ offset ${offset}. skip this id3 tag`); + return; + } + tagId = ID3.readUTF(data, offset, 4); + offset += 4; + if (tagId === '') { + this.logger.info(loggerName$k, '[id3] empty tagId. padding.'); + return; + } + tagLen = ID3.readSynchSafeUint32(data.subarray(offset, offset + 4)); + if (tagLen === 0) { + this.logger.info(loggerName$k, '[id3] zero tag length. padding.'); + return; + } + offset += 4; + data[offset++] << (8 + data[offset++]); + tagStart = offset; + this.logger.info(loggerName$k, '[id3] tag id:' + tagId + ' tagLen ' + tagLen + ' offset ' + offset + ' endPos ' + endPos); + this.logger.qe({ critical: true, name: 'id3Parsed', data: { tagId, tagLen, offset, endPos } }); + const frame = this._extractID3Frame(data, tagId, tagLen, tagStart, endPos); + if (frame) { + const id3Frame = this.decodeID3Frame(frame); + this._frames.push(id3Frame); + } + switch (tagId) { + case 'PRIV': + // this.logger.info(loggerName, 'parse frame:' + Hex.hexDump(data.subarray(offset,endPos))); + // owner should be "com.apple.streaming.transportStreamTimestamp" + if (tagLen === 53 && ID3.readUTF(data, offset, 44) === 'com.apple.streaming.transportStreamTimestamp') { + offset += 44; + // smelling even better ! we found the right descriptor + // skip null character (string end) + 3 first bytes + offset += 4; + // timestamp is 33 bit expressed as a big-endian eight-octet number, with the upper 31 bits set to zero. + const pts33Bit = data[offset++] & 1; + this._hasTimeStamp = true; + timestamp = ((data[offset++] << 23) + (data[offset++] << 15) + (data[offset++] << 7) + data[offset++]) / 45; + if (pts33Bit) { + timestamp += 47721858.84; // 2^32 / 90 + } + timestamp = Math.round(timestamp); + this.logger.info(loggerName$k, `ID3 timestamp found: ${timestamp}`); + this._timeStamp = timestamp; + } + else if (tagLen >= 45 && ID3.readUTF(data, offset, 36) === 'com.apple.streaming.audioDescription') { + offset += 37; // skip tag and null terminator + this._audioType = ID3.readUTF(data, offset, 4); + offset += 4; + // skip everything else for now, don't think we need anything from the audio setup + offset += tagLen - 41; + this.logger.info(loggerName$k, `ID3 audio description found: ${this._audioType}`); + } + else { + offset += tagLen; + } + break; + default: + { + offset += tagLen; + } + break; + } + this.logger.info(loggerName$k, `[id3] ${tagId} default tagLen ${tagLen} offset ${offset} endPos ${endPos}`); + } + } + // id3utf8ArrayToStr is different from BufferUtils.utfarrayToStr. It exists when the string ends. + // BufferUtils.utfarrayToStr will decode the entire array. + // http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197 + // http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt + /** utf.js - UTF-8 <=> UTF-16 convertion + * + * Copyright (C) 1999 Masanao Izumo + * Version: 1.0 + * LastModified: Dec 25 1999 + * This library is free. You can redistribute it and/or modify it. + */ + id3utf8ArrayToStr(array) { + let char2; + let char3; + let out = ''; + let i = 0; + const length = array.length; + while (i < length) { + const c = array[i++]; + switch (c >> 4) { + case 0: + return out; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + // 0xxxxxxx + out += String.fromCharCode(c); + break; + case 12: + case 13: + // 110x xxxx 10xx xxxx + char2 = array[i++]; + out += String.fromCharCode(((c & 31) << 6) | (char2 & 63)); + break; + case 14: + // 1110 xxxx 10xx xxxx 10xx xxxx + char2 = array[i++]; + char3 = array[i++]; + out += String.fromCharCode(((c & 15) << 12) | ((char2 & 63) << 6) | ((char3 & 63) << 0)); + break; + } + } + } + get hasTimeStamp() { + return this._hasTimeStamp; + } + get timeStamp() { + return this._timeStamp; + } + get audioType() { + return this._audioType; + } + get length() { + return this._length; + } + get payload() { + return this._payload; + } + get frames() { + return this._frames; + } + get minor() { + return this._minor; + } + get revision() { + return this._revision; + } + } + var ID3$1 = ID3; + + + const loggerName$j = { name: 'AACDemuxer' }; + class AACDemuxer extends EsDemuxer { + resetInitSegment(initSegment, duration) { + this.audioConfig = undefined; + this.audioTrack = undefined; + this.duration = duration; + } + static probe(data, logger) { + // check if data contains ID3 timestamp and ADTS sync word + const id3 = new ID3$1(data, logger); + let offset, length; + // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1 + // Layer bits (position 14 and 15) in header should be always 0 for ADTS + // More info https://wiki.multimedia.cx/index.php?title=ADTS + for (offset = id3.length, length = Math.min(data.length - 1, offset + 100); offset < length; offset++) { + if (data[offset] === 255 && (data[offset + 1] & 246) === 240) { + return true; + } + } + return false; + } + // feed incoming data to the front of the parsing pipeline + append(data, timeOffset, contiguous, accurateTimeOffset, keyTagInfo) { + const id3 = new ID3$1(data, this.logger); + const pts = id3.hasTimeStamp ? 90 * id3.timeStamp : 90000 * timeOffset; + if (!id3.hasTimeStamp) { + this.logger.info(loggerName$j, `missing id3 timestamp at timeOffset ${timeOffset.toFixed(3)}`); + } + let frameLength, frameIndex, offset, headerLength, stamp, length; + let aacSample; + let id3Track = undefined; + let frames = undefined; + let payload = undefined; + if (id3.length) { + payload = id3.payload; + if (id3.frames.length) { + frames = id3.frames; + } + this.logger.info(loggerName$j, `[id3] init id3 tag pts=${pts} frames=${id3.frames.length}`); + id3Track = { id3Samples: [{ pts: pts, dts: pts, data: payload, frames: frames }], inputTimescale: 90000 }; + } + // Look for ADTS header + for (offset = id3.length, length = data.length; offset < length - 1; offset++) { + if (data[offset] === 255 && (data[offset + 1] & 246) === 240) { + break; + } + } + if (!this.audioConfig) { + this.audioConfig = ADTS.getAudioConfig(this.observer, data, offset, undefined, this.logger); + if (!this.audioConfig) { + throw 'failed to parse adts config'; + } + this.logger.info(loggerName$j, `parsed codec:${this.audioConfig.codec},rate:${this.audioConfig.samplerate},nb channel:${this.audioConfig.channelCount}`); + } + if (!this.audioTrack) { + const info = { id: 258, inputTimescale: 90000, timescale: NaN, duration: this.duration, encrypted: false, keyTagInfo }; + const parsingData = { len: 0, sequenceNumber: 0, esSamples: [] }; + this.audioTrack = { info, parsingData, type: 'audio', config: this.audioConfig }; + } + if (id3.audioType === 'zaac' || id3.audioType === 'zach' || id3.audioType === 'zacp') { + this.audioTrack.info.encrypted = true; + this.logger.info(loggerName$j, 'found encrypted aac'); + } + frameIndex = 0; + const frameDuration = 92160000 / this.audioConfig.samplerate; + while (offset + 5 < length) { + // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header + headerLength = data[offset + 1] & 1 ? 7 : 9; + // retrieve frame size + frameLength = ((data[offset + 3] & 3) << 11) | (data[offset + 4] << 3) | ((data[offset + 5] & 224) >>> 5); + frameLength -= headerLength; + // stamp = pes.pts; + if (frameLength > 0 && offset + headerLength + frameLength <= length) { + stamp = pts + frameIndex * frameDuration; + aacSample = { unit: data.subarray(offset + headerLength, offset + headerLength + frameLength), pts: stamp, dts: stamp, keyTagInfo: keyTagInfo }; + this.audioTrack.parsingData.esSamples.push(aacSample); + this.audioTrack.parsingData.len += frameLength; + offset += frameLength + headerLength; + frameIndex++; + // look for ADTS header (0xFFFx) + for (; offset < length - 1; offset++) { + if (ID3$1.isHeader(data, offset)) { + const embedId3 = new ID3$1(data.subarray(offset), this.logger); + if (embedId3.length > 0) { + offset += embedId3.length; // parses the interleaved ID3 packet + const localPts = embedId3.hasTimeStamp ? 90 * embedId3.timeStamp : pts; + id3Track.id3Samples.push({ pts: localPts, dts: localPts, data: embedId3.payload, frames: embedId3.frames }); + } + else { + this.logger.error(loggerName$j, `[id3] invalid length ${length}`); + } + } + if (data[offset] === 255 && (data[offset + 1] & 246) === 240) { + break; + } + } + } + else { + break; + } + } + this.esRemuxer.remuxEsTracks(this.audioTrack, undefined, id3Track, undefined, timeOffset, contiguous, accurateTimeOffset, keyTagInfo); + } + } + + /* + * Utility methods to perform bit manipulations. + * + * 2019 Apple Inc. All rights reserved. + */ + class BitstreamUtils { + /** + * This method is used to read a value from a bit-range in the data buffer. + * + * @param {Uint8Array} data - Data buffer. + * @param {BitStream} bitStream - Current position in the data buffer; gets updated by this method. + * @param {number} numBits - Total number of bits to read. + * + * @return {number} Numeric value of the bits read. + * + * Usage: bsReadAndUpdate(data, {byteOffset: 1, usedBits: 3}, 7) + * => will read 5 bits from data[1] and 2 bits from data[2] and return the numeric value of those 7 bits. + * => will update the bitStream to {byteOffset: 2, usedBits: 2} + */ + bsReadAndUpdate(data, bitStream, numBits) { + const result = this.readBits(data, bitStream, numBits); + this.updateOffset(bitStream, numBits); + return result; + } + /** + * This method is used to write a value to a bit-range in the data buffer. + * + * @param {Uint8Array} data - Data buffer. + * @param {BitStream} bitStream - Current position in the data buffer; gets updated by this method. + * @param {number} numBits - Total number of bits to write. + * @param {number} value - The value to write. + * + * Usage: bsWriteAndUpdate(data, {byteOffset: 1, usedBits: 3}, 7) + * => will write most significant 5 bits of value to data[1] and remaining 4 bits to data[2]. + * => will update the bitStream to {byteOffset: 2, usedBits: 2} + */ + bsWriteAndUpdate(data, bitStream, numBits, value) { + const result = this.writeBits(data, bitStream, numBits, value); + this.updateOffset(bitStream, numBits); + return result; + } + /** + * This method is used to update the bitStream offsets. + * + * @param {BitStream} bitStream - Current offset (In) / New offset (Out). + * @param {number} numBits - Total number of bits to skip. + * + * Usage: bsSkip({byteOffset: 1, usedBits: 3}, 7) + * => will update the bitStream to {byteOffset: 2, usedBits: 2} + */ + bsSkip(bitStream, numBits) { + this.updateOffset(bitStream, numBits); + } + // private helper methods + readBits(data, bitStream, numBits) { + if (!data || !bitStream) { + return undefined; + } + let offset = bitStream.byteOffset; + const { usedBits } = bitStream; + if (usedBits >= 8 || usedBits + numBits > 32) { + return undefined; + } + let result; + // some strong typed variables for reliable bit manipulation + const temp = new Uint32Array(1); // unsigned 32 bit for temporary storage + const mask = new Uint32Array(1); // unsigned 32 bit mask value + const byte = new Uint8Array(1); // unsigned 8 bit for temporary storage + if (usedBits >= 8 || numBits > 32) { + return undefined; + } + /* + * read msb to lsb from data[offset] starting from the first unused bit of data[offset] + * for e.g. data[0] => 11110010 + * data[1] => 00111101 + * data[2] => 00101001 + * numBits => 18 + * usedBits => 2 + * byteOffset => 0 + * will fetch bits + * data[0] => xx100011 + * data[1] => 11011100 + * data[2] => 1011xxxx + * and return + * 00000000 00000010 00111101 11001011 + */ + if (usedBits) { + // read unused bits from the partial byte + const bits = 8 - usedBits; + const shift = numBits < bits ? bits - numBits : 0; + mask[0] = 4278190080 >>> (32 - bits); + result = (data[offset] & mask[0]) >>> shift; + offset += 1; + numBits -= bits; + } + while (numBits > 0) { + byte[0] = data[offset]; + // read remaining bits, upto 8 bits at a time + const bits = Math.min(numBits, 8); + const shift = 8 - bits; + mask[0] = (4278190080 >>> (24 + shift)) << shift; + temp[0] = (byte[0] & mask[0]) >> shift; + result = !result ? temp[0] : (result << bits) | temp[0]; + offset += 1; + numBits -= bits; + } + return result; + } + writeBits(data, bitStream, numBits, value) { + if (!data || !bitStream) { + return undefined; + } + let offset = bitStream.byteOffset; + const { usedBits } = bitStream; + if (usedBits >= 8 || usedBits + numBits > 32) { + return undefined; + } + // some strong typed variables for reliable bit manipulation + const tval = new Uint32Array(1); // unsigned 32 bit to store the incoming value + const temp = new Uint32Array(1); // unsigned 32 bit for temporary storage + const mask = new Uint32Array(1); // unsigned 32 bit mask value + const byte = new Uint8Array(1); // unsigned 8 bit for temporary storage + tval[0] = value; + /* + * write msb to lsb from value into data[offset] starting from the first unused bit of data[offset] + * for e.g. value => 00000000 00000010 00111101 11001011 + * numBits => 18 + * usedBits => 2 + * byteOffset => 0 + * will get written as + * data[0] => xx100011 + * data[1] => 11011100 + * data[2] => 1011xxxx + */ + if (usedBits) { + // left align the value, mask the bits, and then right align to exclude the used bits + temp[0] = tval[0] << (32 - numBits); + mask[0] = 4278190080; + byte[0] = (temp[0] & mask[0]) >>> (24 + usedBits); + // clear the bits and write + data[offset] &= ~(mask[0] >>> (24 + usedBits)); + data[offset] |= byte[0]; + offset += 1; + numBits -= 8 - usedBits; + } + while (numBits > 0) { + // left align the remaining bits of value and write in blocks of 8 + temp[0] = tval[0] << (32 - numBits); + mask[0] = 4278190080; + byte[0] = (temp[0] & mask[0]) >>> 24; + // right align the mask, and then right shift and left shift to clear the used bits + const shift = numBits < 0 ? 8 - numBits : 0; + data[offset] &= ~(((mask[0] >>> 24) >>> shift) << shift); + // write the bits + data[offset] |= byte[0]; + numBits -= 8; + offset += 1; + } + return 0; + } + updateOffset(bitStream, numBits) { + if (!bitStream || !numBits || bitStream.usedBits + numBits > 32) { + return; + } + // calculate the number of bits seen in the current byte offset + const bitsSeenInByte = bitStream.usedBits % 8; + // calculate the bytes and bits based on the last read/write operation + const bytesAdvanced = Math.floor((bitsSeenInByte + numBits) / 8); + const bitsAdvanced = (bitsSeenInByte + numBits) % 8; + // update the new position + bitStream.byteOffset += bytesAdvanced; + bitStream.usedBits = bitsAdvanced; + } + } + + const loggerName$i = { name: 'Dolby' }; + const samplingRateMap = [48000, 44100, 32000]; + const frameSizeMap = [ + 64, + 69, + 96, + 64, + 70, + 96, + 80, + 87, + 120, + 80, + 88, + 120, + 96, + 104, + 144, + 96, + 105, + 144, + 112, + 121, + 168, + 112, + 122, + 168, + 128, + 139, + 192, + 128, + 140, + 192, + 160, + 174, + 240, + 160, + 175, + 240, + 192, + 208, + 288, + 192, + 209, + 288, + 224, + 243, + 336, + 224, + 244, + 336, + 256, + 278, + 384, + 256, + 279, + 384, + 320, + 348, + 480, + 320, + 349, + 480, + 384, + 417, + 576, + 384, + 418, + 576, + 448, + 487, + 672, + 448, + 488, + 672, + 512, + 557, + 768, + 512, + 558, + 768, + 640, + 696, + 960, + 640, + 697, + 960, + 768, + 835, + 1152, + 768, + 836, + 1152, + 896, + 975, + 1344, + 896, + 976, + 1344, + 1024, + 1114, + 1536, + 1024, + 1115, + 1536, + 1152, + 1253, + 1728, + 1152, + 1254, + 1728, + 1280, + 1393, + 1920, + 1280, + 1394, + 1920, + ]; + const Dolby = { + getFrameDuration: function (config, timescale) { + return (1536 / config.samplerate) * timescale; + }, + getAudioConfig: function (observer, data, offset, logger) { + let payload; + if (offset + 8 > data.length) { + payload = new FragParsingError(true, 'error parsing ac-3, not enough data', ErrorResponses.InsufficientAC3Data); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + if (data[offset] !== 11 || data[offset + 1] !== 119) { + // payload = { type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.FRAG_PARSING_ERROR, fatal: true, reason: 'invalid ac-3 magic' }; + payload = new FragParsingError(true, 'invalid ac-3 magic', ErrorResponses.InvalidAC3Magic); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + const samplingRateCode = data[offset + 4] >> 6; + if (samplingRateCode >= 3) { + payload = new FragParsingError(true, `invalid ac-3 samplingRateCode:${samplingRateCode}`, ErrorResponses.InvalidAC3SamplingRateCode); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // get frame size + const frameSizeCode = data[offset + 4] & 63; + const frameLength = frameSizeMap[frameSizeCode * 3 + samplingRateCode] * 2; + const channelMode = data[offset + 6] >> 5; + let skipCount = 0; + if (channelMode === 2) { + skipCount += 2; + } + else { + if (channelMode & 1 && channelMode !== 1) { + skipCount += 2; + } + if (channelMode & 4) { + skipCount += 2; + } + } + const lfeon = (((data[offset + 6] << 8) | data[offset + 7]) >> (12 - skipCount)) & 1; + const channelsMap = [2, 1, 2, 3, 3, 4, 4, 5]; + const channelCount = channelsMap[channelMode] + lfeon; + const bsid = data[offset + 5] >> 3; + const bsmod = data[offset + 5] & 7; + const extraData = (samplingRateCode << 22) | (bsid << 17) | (bsmod << 14) | (channelMode << 11) | (lfeon << 10) | ((frameSizeCode >> 1) << 5); + const samplerate = samplingRateMap[samplingRateCode]; + logger.info(loggerName$i, `parsed codec: ac-3, rate:${samplerate}, nb channel:${channelCount}, first frameLength:${frameLength}`); + const audioConfig = { samplerate: samplerate, channelCount: channelCount, segmentCodec: 'ac3', codec: 'ac-3', extraData: extraData }; + return audioConfig; + }, + getFrameLength: function (observer, data, offset) { + let payload; + if (offset + 8 > data.length) { + payload = new FragParsingError(true, 'error parsing ac-3, not enough data', ErrorResponses.InsufficientAC3Data); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + if (data[offset] !== 11 || data[offset + 1] !== 119) { + payload = new FragParsingError(true, 'invalid ac-3 magic', ErrorResponses.InvalidAC3Magic); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + const samplingRateCode = data[offset + 4] >> 6; + if (samplingRateCode >= 3) { + payload = new FragParsingError(true, `invalid ac-3 samplingRateCode:${samplingRateCode}`, ErrorResponses.InvalidAC3SamplingRateCode); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // get frame size + const frameSizeCode = data[offset + 4] & 63; + return frameSizeMap[frameSizeCode * 3 + samplingRateCode] * 2; + }, + }; + + const loggerName$h = { name: 'AC3Demuxer' }; + class AC3Demuxer extends EsDemuxer { + resetInitSegment(initSegment, duration) { + this.audioConfig = undefined; + this.audioTrack = undefined; + this.duration = duration; + } + static probe(data, logger) { + // check if data contains ID3 timestamp and AC3 sync bytes + const id3 = new ID3$1(data, logger), offset = id3.length; + // look for the ac-3 sync bytes + if (id3.hasTimeStamp && data[offset] === 11 && data[offset + 1] === 119) { + // check the bsid to confirm ac-3 + const bu = new BitstreamUtils(); + const bsid = bu.bsReadAndUpdate(data, { byteOffset: offset + 5, usedBits: 0 }, 5); + if (bsid < 16) { + return true; + } + } + return false; + } + // feed incoming data to the front of the parsing pipeline + append(data, timeOffset, contiguous, accurateTimeOffset, keyTagInfo) { + const id3 = new ID3$1(data, this.logger); + const pts = 90 * id3.timeStamp; + const length = data.byteLength; + let frameIndex = 0; + let offset = id3.length; + if (!this.audioConfig) { + this.audioConfig = Dolby.getAudioConfig(this.observer, data, offset, this.logger); + } + if (!this.audioConfig) { + throw 'failed to parse ac3 config'; + } + if (!this.audioTrack) { + const info = { id: 258, inputTimescale: 90000, timescale: NaN, duration: this.duration, encrypted: false, keyTagInfo }; + const parsingData = { len: 0, sequenceNumber: 0, esSamples: [] }; + this.audioTrack = { info, parsingData, type: 'audio', config: this.audioConfig }; + } + const frameDuration = Dolby.getFrameDuration(this.audioConfig, this.audioTrack.info.inputTimescale); // (1536 / this.audioConfig.samplerate) * this.audioTrack.inputTimescale; + if (id3.audioType === 'zac3') { + this.audioTrack.info.encrypted = true; + this.logger.info(loggerName$h, 'found encrypted ac3'); + } + while (offset < length) { + if (ID3$1.isHeader(data, offset)) { + const id3 = new ID3$1(data.subarray(offset), this.logger); + offset += id3.length; // skip the interleaved ID3 packet + } + if (data[offset] !== 11 || data[offset + 1] !== 119) { + const payload = new FragParsingError(true, 'invalid ac-3 magic', ErrorResponses.InvalidAC3Magic); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return; + } + const frameLength = Dolby.getFrameLength(this.observer, data, offset); + const stamp = pts + frameIndex * frameDuration; + const ac3Sample = { unit: data.subarray(offset, offset + frameLength), pts: stamp, dts: stamp, keyTagInfo: keyTagInfo }; + this.audioTrack.parsingData.esSamples.push(ac3Sample); + this.audioTrack.parsingData.len += frameLength; + offset += frameLength; + frameIndex++; + } + this.esRemuxer.remuxEsTracks(this.audioTrack, undefined, { id3Samples: [{ pts: pts, dts: pts, data: id3.payload, frames: id3.frames }], inputTimescale: this.audioTrack.info.inputTimescale }, undefined, timeOffset, contiguous, accurateTimeOffset, keyTagInfo); + } + } + + const loggerName$g = { name: 'DDPlus' }; + const DDPlus = { + getFrameLength: function (observer, data, offset, logger) { + const bs = new BitstreamUtils(); + let firstIndSubstream = false; + let totalFrameLength = 0; + let payload; + while (offset < data.length) { + if (offset + 8 > data.length) { + payload = new FragParsingError(true, 'error parsing ec-3, not enough data', ErrorResponses.InsufficientEC3Data); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // skip the ID3 packet, if present + let id3Length = 0; + if (ID3$1.isHeader(data, offset)) { + const id3 = new ID3$1(data.subarray(offset), logger); + id3Length = id3.length || 0; + offset += id3Length; + } + // get syncword (16 bits) + if (data[offset] !== 11 || data[offset + 1] !== 119) { + payload = new FragParsingError(true, 'invalid ec-3 magic', ErrorResponses.InvalidEC3Magic); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // skip the syncword and start parsing + const bitStream = { byteOffset: offset + 2, usedBits: 0 }; + // get strmtyp & substreamid + const strmtyp = bs.bsReadAndUpdate(data, bitStream, 2); + const substreamid = bs.bsReadAndUpdate(data, bitStream, 3); + if (strmtyp === 0 || strmtyp === 2) { + if (firstIndSubstream === true) { + if (substreamid === 0) { + // we're seen all dependent sub-streams + break; + } + } + else { + firstIndSubstream = true; // mark that the first independent substream is seen + } + } + else if (strmtyp !== 1) { + payload = new FragParsingError(true, 'reserved stream type', ErrorResponses.ReservedStreamType); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // get frmsiz + const frmsiz = bs.bsReadAndUpdate(data, bitStream, 11); + // advance to the next syncframe + const frameLength = (frmsiz + 1) * 2; + offset += frameLength; + totalFrameLength += frameLength + (id3Length || 0); + } + return totalFrameLength; + }, + getAudioConfig: function (observer, data, offset, logger) { + const frameInfo = { + frmsiz: 0, + fscod: 0, + numblkscod: 0, + acmod: 0, + lfeon: 0, + bsid: 0, + strmtyp: 0, + substreamid: 0, + chanmape: 0, + chanmap: 0, + mixdef: 0, + mixdeflen: 0, + bsmod: 0, + }; + const sampleInfo = { + fscod: 0, + acmod: 0, + lfeon: 0, + bsid: 0, + bsmod: 0, + chan_loc: 0, + data_rate: 0, + num_ind_sub: 0, + num_dep_sub: [], + complexity_index_type_a: 0, + }; + const bs = new BitstreamUtils(); + let firstIndSubstream = false; + let totalFrameLength = 0; + let payload; + while (offset < data.length) { + if (offset + 8 > data.length) { + payload = new FragParsingError(true, 'error parsing ec-3, not enough data', ErrorResponses.InsufficientEC3Data); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // skip the ID3 packet, if present + let id3Length = 0; + if (ID3$1.isHeader(data, offset)) { + const id3 = new ID3$1(data.subarray(offset), logger); + id3Length = id3.length || 0; + offset += id3Length; + } + // get syncword (16 bits) + if (data[offset] !== 11 || data[offset + 1] !== 119) { + payload = new FragParsingError(true, 'invalid ec-3 magic', ErrorResponses.InvalidEC3Magic); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // skip the syncword and start parsing + const bitStream = { byteOffset: offset + 2, usedBits: 0 }; + // get strmtyp & substreamid + frameInfo.strmtyp = bs.bsReadAndUpdate(data, bitStream, 2); + frameInfo.substreamid = bs.bsReadAndUpdate(data, bitStream, 3); + if (frameInfo.strmtyp === 0 || frameInfo.strmtyp === 2) { + if (firstIndSubstream === true) { + if (frameInfo.substreamid === 0) { + // we're seen all dependent sub-streams + break; + } + } + else { + firstIndSubstream = true; // mark that the first independent substream is seen + } + sampleInfo.num_ind_sub++; // independent substream + sampleInfo.num_dep_sub.push(0); // initialize the dependent sub-stream count to 0 + } + else if (frameInfo.strmtyp === 1) { + sampleInfo.num_dep_sub[sampleInfo.num_ind_sub - 1]++; // dependent substream + } + else { + payload = new FragParsingError(true, 'reserved stream type', ErrorResponses.ReservedStreamType); + observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return undefined; + } + // get frmsiz + frameInfo.frmsiz = bs.bsReadAndUpdate(data, bitStream, 11); + // get fscod, numblkscod + frameInfo.fscod = bs.bsReadAndUpdate(data, bitStream, 2); + if (frameInfo.fscod === 3) { + bs.bsSkip(bitStream, 2); + frameInfo.numblkscod = 3; + } + else { + frameInfo.numblkscod = bs.bsReadAndUpdate(data, bitStream, 2); + } + // get acmod + frameInfo.acmod = bs.bsReadAndUpdate(data, bitStream, 3); + // get lfeon + frameInfo.lfeon = bs.bsReadAndUpdate(data, bitStream, 1); + // get bsid + frameInfo.bsid = bs.bsReadAndUpdate(data, bitStream, 5); + bs.bsSkip(bitStream, 5); + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 8); + } + if (frameInfo.acmod === 0) { + bs.bsSkip(bitStream, 5); + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 8); + } + } + if (frameInfo.strmtyp === 1) { + // get chanmape + frameInfo.chanmape = bs.bsReadAndUpdate(data, bitStream, 1); + if (frameInfo.chanmape) { + // get chanmap + frameInfo.chanmap = bs.bsReadAndUpdate(data, bitStream, 16); + } + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + if (frameInfo.acmod > 2) { + bs.bsSkip(bitStream, 2); + } + if (frameInfo.acmod & 1 && frameInfo.acmod > 2) { + bs.bsSkip(bitStream, 6); + } + if (frameInfo.acmod & 4) { + bs.bsSkip(bitStream, 6); + } + if (frameInfo.lfeon) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 5); + } + } + if (frameInfo.strmtyp === 0) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 6); + } + if (frameInfo.acmod === 0) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 6); + } + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 6); + } + // get mixdef + frameInfo.mixdef = bs.bsReadAndUpdate(data, bitStream, 2); + if (frameInfo.mixdef === 1) { + bs.bsSkip(bitStream, 5); + } + else if (frameInfo.mixdef === 2) { + bs.bsSkip(bitStream, 12); + } + else if (frameInfo.mixdef === 3) { + // get mixdeflen + frameInfo.mixdeflen = bs.bsReadAndUpdate(data, bitStream, 5); + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 5); + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 4); + } + } + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 5); + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 7); + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 8); + } + } + } + // skip entire block that includes mixdata and mixdatafill + const skipBytes = frameInfo.mixdeflen + 2 + (bitStream.usedBits ? 1 : 0); + bitStream.byteOffset += skipBytes; + } + if (frameInfo.acmod < 2) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 14); + } + if (frameInfo.acmod === 0) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 14); + } + } + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + if (frameInfo.numblkscod === 0) { + bs.bsSkip(bitStream, 5); + } + else { + for (let i = 0; i < frameInfo.numblkscod; i++) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 5); + } + } + } + } + } + } + frameInfo.bsmod = 0; + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + frameInfo.bsmod = bs.bsReadAndUpdate(data, bitStream, 3); + bs.bsSkip(bitStream, 2); + if (frameInfo.acmod === 2) { + bs.bsSkip(bitStream, 4); + } + if (frameInfo.acmod >= 6) { + bs.bsSkip(bitStream, 2); + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 8); + } + if (frameInfo.acmod === 0) { + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + bs.bsSkip(bitStream, 8); + } + } + if (frameInfo.fscod < 3) { + bs.bsSkip(bitStream, 1); + } + } + if (frameInfo.strmtyp === 0 && frameInfo.numblkscod !== 3) { + bs.bsSkip(bitStream, 1); + } + if (frameInfo.strmtyp === 2) { + let blkid; + if (frameInfo.numblkscod === 3) { + blkid = 1; + } + else { + blkid = bs.bsReadAndUpdate(data, bitStream, 1); + } + if (blkid) { + bs.bsReadAndUpdate(data, bitStream, 6); + } + } + if (bs.bsReadAndUpdate(data, bitStream, 1)) { + const addbsil = bs.bsReadAndUpdate(data, bitStream, 6); + if (frameInfo.strmtyp === 0 && frameInfo.substreamid === 0 && addbsil === 1) { + const flag_ec3_extension_type_reserved = bs.bsReadAndUpdate(data, bitStream, 7); + const flag_ec3_extension_type_a = bs.bsReadAndUpdate(data, bitStream, 1); + const complexity_index_type_a = bs.bsReadAndUpdate(data, bitStream, 8); + // Make sure the values are in range and if yes, flag ATMOS + if (flag_ec3_extension_type_reserved === 0 && flag_ec3_extension_type_a === 1 && complexity_index_type_a >= 1 && complexity_index_type_a <= 16) { + sampleInfo.complexity_index_type_a = complexity_index_type_a; + } + } + } + // find channel map + if (frameInfo.chanmape) { + sampleInfo.chan_loc |= frameInfo.chanmap; + } + else { + // look up channel map using acmod + const acmodToChannelMap = [ + 40960, + 16384, + 40960, + 57344, + 41472, + 57856, + 47104, + 63488, + ]; + sampleInfo.chan_loc |= acmodToChannelMap[frameInfo.acmod]; + } + if (frameInfo.strmtyp === 0) { + sampleInfo.fscod = frameInfo.fscod; + sampleInfo.bsid = frameInfo.bsid; + sampleInfo.bsmod = frameInfo.bsmod; + sampleInfo.acmod = frameInfo.acmod; + sampleInfo.lfeon = frameInfo.lfeon; + } + sampleInfo.chan_loc |= frameInfo.lfeon ? 1 : 0; + // advance to the next syncframe + const frameLength = (frameInfo.frmsiz + 1) * 2; + offset += frameLength; + totalFrameLength += frameLength + (id3Length || 0); + } + let channelCount = 0; + // get channel count + for (let i = 0; i < 16; i++) { + if (sampleInfo.chan_loc & (1 << i)) { + channelCount++; + } + } + if (sampleInfo.lfeon) { + channelCount++; + } + // generate DD+ magic cookie + let cookieSize = 10 + sampleInfo.num_ind_sub * 3; + const samplingRateMap = [48000, 44100, 32000]; + const samplerate = samplingRateMap[sampleInfo.fscod]; + sampleInfo.data_rate = (samplerate / 1536) * totalFrameLength * 8; + cookieSize = 10 + sampleInfo.num_ind_sub * 3; + for (let i = 0; i < sampleInfo.num_ind_sub; i++) { + if (sampleInfo.num_dep_sub[i] > 0) { + cookieSize++; + } + } + // for ATMOS + if (sampleInfo.complexity_index_type_a > 0) { + cookieSize += 2; + } + // write the cookie + const extraDataBytes = new Uint8Array(cookieSize); + const bitStream = { byteOffset: 0, usedBits: 0 }; + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 32, cookieSize); + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 32, 1684366131); // 'dec3' + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 13, sampleInfo.data_rate); // data_rate + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 3, sampleInfo.num_ind_sub); // num_ind_sub + for (let i = 0; i < sampleInfo.num_ind_sub; i++) { + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 2, sampleInfo.fscod); // fscod + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 5, sampleInfo.bsid); // bsid + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 1, 0); // reserved + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 1, i === 0 ? 0 : 1); // asvc + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 3, sampleInfo.bsmod); // bsmod + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 3, sampleInfo.acmod); // acmod + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 1, sampleInfo.lfeon); // lfeon + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 3, 0); // reserved + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 4, sampleInfo.num_dep_sub[i]); // num_dep_sub + if (sampleInfo.num_dep_sub[i] > 0) { + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 9, sampleInfo.chan_loc); // chan_loc + } + else { + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 1, 0); // reserved + } + } + if (sampleInfo.complexity_index_type_a > 0) { + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 7, 0); // flag_ec3_extension_type_reserved; reserved as 0 + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 1, 1); // flag_ec3_extension_type_a + bs.bsWriteAndUpdate(extraDataBytes, bitStream, 8, sampleInfo.complexity_index_type_a); // complexity_index_type_a + } + logger.debug(loggerName$g, `EC3 sampleInfo:${JSON.stringify(sampleInfo)}`); + logger.info(loggerName$g, `parsed codec:ec-3, isAtmos: ${sampleInfo.complexity_index_type_a > 0}, rate:${samplerate}, nb channel:${channelCount}, first totalFrameLength:${totalFrameLength}`); + const audioConfig = { samplerate: samplerate, channelCount: channelCount, segmentCodec: 'ec3', codec: 'ec-3', extraDataBytes: extraDataBytes }; + return audioConfig; + }, + }; + var DDPlus$1 = DDPlus; + + const loggerName$f = { name: 'EC3Demuxer' }; + class EC3Demuxer extends EsDemuxer { + resetInitSegment(initSegment, duration) { + this.audioConfig = undefined; + this.audioTrack = undefined; + this.duration = duration; + } + static probe(data, logger) { + // check if data contains ID3 timestamp and EC3 sync bytes + const id3 = new ID3$1(data, logger), offset = id3.length; + // look for the ec-3 sync bytes + if (id3.hasTimeStamp && data[offset] === 11 && data[offset + 1] === 119) { + // check the bsid to confirm ec-3 + const bu = new BitstreamUtils(); + const bsid = bu.bsReadAndUpdate(data, { byteOffset: offset + 5, usedBits: 0 }, 5); + if (bsid === 16) { + return true; + } + } + return false; + } + // feed incoming data to the front of the parsing pipeline + append(data, timeOffset, contiguous, accurateTimeOffset, keyTagInfo) { + const id3 = new ID3$1(data, this.logger); + const pts = 90 * id3.timeStamp; + const length = data.length; + let frameIndex = 0; + let offset = id3.length; + if (!this.audioConfig) { + this.audioConfig = DDPlus$1.getAudioConfig(this.observer, data, offset, this.logger); + } + if (!this.audioConfig) { + throw 'failed to parse ec-3 config'; + } + if (!this.audioTrack) { + const info = { id: 258, inputTimescale: 90000, timescale: NaN, duration: this.duration, encrypted: false, keyTagInfo }; + const parsingData = { len: 0, sequenceNumber: 0, esSamples: [] }; + this.audioTrack = { info, parsingData, type: 'audio', config: this.audioConfig }; + } + const frameDuration = Dolby.getFrameDuration(this.audioConfig, this.audioTrack.info.inputTimescale); // (1536 / this.audioConfig.samplerate) * this.audioTrack.inputTimescale; + if (id3.audioType === 'zec3') { + this.audioTrack.info.encrypted = true; + this.logger.info(loggerName$f, 'found encrypted ec3'); + } + while (offset < length) { + const frameLength = DDPlus$1.getFrameLength(this.observer, data, offset, this.logger); + const stamp = pts + frameIndex * frameDuration; + const ec3Sample = { unit: data.subarray(offset, offset + frameLength), pts: stamp, dts: stamp, keyTagInfo: keyTagInfo }; + this.audioTrack.parsingData.esSamples.push(ec3Sample); + this.audioTrack.parsingData.len += frameLength; + offset += frameLength; + frameIndex++; + } + this.esRemuxer.remuxEsTracks(this.audioTrack, undefined, { id3Samples: [{ pts: pts, dts: pts, data: id3.payload, frames: id3.frames }], inputTimescale: this.audioTrack.info.inputTimescale }, undefined, timeOffset, contiguous, accurateTimeOffset, keyTagInfo); + } + } + + + const MpegAudio = { + BitratesMap: [ + 32, + 64, + 96, + 128, + 160, + 192, + 224, + 256, + 288, + 320, + 352, + 384, + 416, + 448, + 32, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 160, + 192, + 224, + 256, + 320, + 384, + 32, + 40, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 160, + 192, + 224, + 256, + 320, + 32, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 144, + 160, + 176, + 192, + 224, + 256, + 8, + 16, + 24, + 32, + 40, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 144, + 160, + ], + SamplingRateMap: [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000], + SamplesCoefficients: [ + // MPEG 2.5 + [ + 0, + 72, + 144, + 12, + ], + // Reserved + [ + 0, + 0, + 0, + 0, + ], + // MPEG 2 + [ + 0, + 72, + 144, + 12, + ], + // MPEG 1 + [ + 0, + 144, + 144, + 12, + ], + ], + BytesInSlot: [ + 0, + 1, + 1, + 4, + ], + onFrame: function (parsingData, data, bitRate, samplerate, channelCount, frameIndex, pts) { + const frameDuration = 103680000 / samplerate; + const stamp = pts + frameIndex * frameDuration; + parsingData.esSamples.push({ unit: data, pts: stamp, dts: stamp }); + parsingData.len += data.length; + }, + onNoise: function (data, logger) { + logger.warn('mpeg audio has noise: ' + data.length + ' bytes'); + }, + parseFrames: function (parsingData, data, start, end, frameIndex, pts, logger) { + const BitratesMap = [ + 32, + 64, + 96, + 128, + 160, + 192, + 224, + 256, + 288, + 320, + 352, + 384, + 416, + 448, + 32, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 160, + 192, + 224, + 256, + 320, + 384, + 32, + 40, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 160, + 192, + 224, + 256, + 320, + 32, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 144, + 160, + 176, + 192, + 224, + 256, + 8, + 16, + 24, + 32, + 40, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 144, + 160, + ]; + const SamplingRateMap = [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000]; + if (start + 2 > end) { + return -1; // we need at least 2 bytes to detect sync pattern + } + if (data[start] === 255 || (data[start + 1] & 224) === 224) { + // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference + if (start + 24 > end) { + return -1; + } + const headerB = (data[start + 1] >> 3) & 3; + const headerC = (data[start + 1] >> 1) & 3; + const headerE = (data[start + 2] >> 4) & 15; + const headerF = (data[start + 2] >> 2) & 3; + const headerG = !!(data[start + 2] & 2); + if (headerB !== 1 && headerE !== 0 && headerE !== 15 && headerF !== 3) { + const columnInBitrates = headerB === 3 ? 3 - headerC : headerC === 3 ? 3 : 4; + const bitRate = BitratesMap[columnInBitrates * 14 + headerE - 1] * 1000; + const columnInSampleRates = headerB === 3 ? 0 : headerB === 2 ? 1 : 2; + const sampleRate = SamplingRateMap[columnInSampleRates * 3 + headerF]; + const padding = headerG ? 1 : 0; + const channelCount = data[start + 3] >> 6 === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono) + const frameLength = headerC === 3 ? (((headerB === 3 ? 12 : 6) * bitRate) / sampleRate + padding) << 2 : (((headerB === 3 ? 144 : 72) * bitRate) / sampleRate + padding) | 0; + if (start + frameLength > end) { + return -1; + } + MpegAudio.onFrame(parsingData, data.subarray(start, start + frameLength), bitRate, sampleRate, channelCount, frameIndex, pts); + return frameLength; + } + } + // noise or ID3, trying to skip + let offset = start + 2; + while (offset < end) { + if (data[offset - 1] === 255 && (data[offset] & 224) === 224) { + // sync pattern is found + MpegAudio.onNoise(data.subarray(start, offset - 1), logger); + return offset - start - 1; + } + offset++; + } + return -1; + }, + parse: function (parsingData, data, offset, pts, logger) { + const length = data.length; + let frameIndex = 0; + let parsed; + while (offset < length && (parsed = MpegAudio.parseFrames(parsingData, data, offset, length, frameIndex++, pts, logger)) > 0) { + offset += parsed; + } + }, + getAudioConfig: function (data, offset) { + const headerB = (data[offset + 1] >> 3) & 3; + const headerC = (data[offset + 1] >> 1) & 3; + const headerE = (data[offset + 2] >> 4) & 15; + const headerF = (data[offset + 2] >> 2) & 3; + const headerG = (data[offset + 2] >> 1) & 1; + if (headerB !== 1 && headerE !== 0 && headerE !== 15 && headerF !== 3) { + const columnInBitrates = headerB === 3 ? 3 - headerC : headerC === 3 ? 3 : 4; + const bitRate = MpegAudio.BitratesMap[columnInBitrates * 14 + headerE - 1] * 1000; + const columnInSampleRates = headerB === 3 ? 0 : headerB === 2 ? 1 : 2; + const samplerate = MpegAudio.SamplingRateMap[columnInSampleRates * 3 + headerF]; + const channelCount = data[offset + 3] >> 6 === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono) + const sampleCoefficient = MpegAudio.SamplesCoefficients[headerB][headerC]; + const bytesInSlot = MpegAudio.BytesInSlot[headerC]; + const frameLength = parseInt(((sampleCoefficient * bitRate) / samplerate + headerG), 10) * bytesInSlot; + const result = { segmentCodec: 'mp3', codec: 'mp3', samplerate, channelCount, frameLength }; + return result; + } + return undefined; + }, + isHeaderPattern: function (data, offset) { + return data[offset] === 255 && (data[offset + 1] & 224) === 224 && (data[offset + 1] & 6) !== 0; + }, + probe: function (data, offset) { + // same as isHeader but we also check that MPEG frame follows last MPEG frame + // or end of data is reached + if (offset + 1 < data.length && MpegAudio.isHeaderPattern(data, offset)) { + // MPEG header Length + const headerLength = 4; + // MPEG frame Length + const header = MpegAudio.getAudioConfig(data, offset); + let frameLength = headerLength; + if (header && header.frameLength) { + frameLength = header.frameLength; + } + const newOffset = offset + frameLength; + if (newOffset === data.length || (newOffset + 1 < data.length && MpegAudio.isHeaderPattern(data, newOffset))) { + return true; + } + } + return false; + }, + }; + var MpegAudio$1 = MpegAudio; + + + const loggerName$e = { name: 'MP3Demuxer' }; + class MP3Demuxer extends EsDemuxer { + resetInitSegment(initSegment, duration) { + this.audioConfig = undefined; + this.audioTrack = undefined; + this.duration = duration; + } + static probe(data, logger) { + // check if data contains ID3 timestamp and MPEG sync word + const id3 = new ID3$1(data, logger); + let offset, length; + if (id3.hasTimeStamp) { + // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1 + // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III) + // More info http://www.mp3-tech.org/programmer/frame_header.html + for (offset = id3.length, length = Math.min(data.length - 1, offset + 100); offset < length; offset++) { + if (MpegAudio$1.probe(data, offset)) { + logger.warn(loggerName$e, 'MPEG Audio sync word found !'); + return true; + } + } + } + return false; + } + // feed incoming data to the front of the parsing pipeline + append(data, timeOffset, contiguous, accurateTimeOffset, keyTagInfo) { + const id3 = new ID3$1(data, this.logger); + const pts = 90 * id3.timeStamp; + if (!this.audioConfig) { + this.audioConfig = MpegAudio$1.getAudioConfig(data, id3.length); + } + if (!this.audioConfig) { + throw 'unable to parse mp3 header'; + } + if (!this.audioTrack) { + const info = { id: 258, inputTimescale: 90000, timescale: NaN, duration: this.duration, encrypted: false, keyTagInfo }; + const parsingData = { len: 0, sequenceNumber: 0, esSamples: [] }; + this.audioTrack = { info, parsingData, type: 'audio', config: this.audioConfig }; + } + MpegAudio$1.parse(this.audioTrack.parsingData, data, id3.length, pts, this.logger); + this.esRemuxer.remuxEsTracks(this.audioTrack, undefined, { id3Samples: [{ pts: pts, dts: pts, data: id3.payload, frames: id3.frames }], inputTimescale: 90000 }, undefined, timeOffset, contiguous, accurateTimeOffset); + } + } + + /** + * AAC Helper + * + * + * + * + */ + function getSilentFrame(codec, channelCount) { + switch (codec) { + case 'mp4a.40.2': + if (channelCount === 1) { + return new Uint8Array([0, 200, 0, 128, 35, 128]); + } + else if (channelCount === 2) { + return new Uint8Array([33, 0, 73, 144, 2, 25, 0, 35, 128]); + } + else if (channelCount === 3) { + return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 142]); + } + else if (channelCount === 4) { + return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 128, 44, 128, 8, 2, 56]); + } + else if (channelCount === 5) { + return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 56]); + } + else if (channelCount === 6) { + return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 0, 178, 0, 32, 8, 224]); + } + break; + // handle HE-AAC below (mp4a.40.5 / mp4a.40.29) + default: + if (channelCount === 1) { + // ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac + return new Uint8Array([ + 1, + 64, + 34, + 128, + 163, + 78, + 230, + 128, + 186, + 8, + 0, + 0, + 0, + 28, + 6, + 241, + 193, + 10, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 94, + ]); + } + else if (channelCount === 2) { + // ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac + return new Uint8Array([ + 1, + 64, + 34, + 128, + 163, + 94, + 230, + 128, + 186, + 8, + 0, + 0, + 0, + 0, + 149, + 0, + 6, + 241, + 161, + 10, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 94, + ]); + } + else if (channelCount === 3) { + // ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac + return new Uint8Array([ + 1, + 64, + 34, + 128, + 163, + 94, + 230, + 128, + 186, + 8, + 0, + 0, + 0, + 0, + 149, + 0, + 6, + 241, + 161, + 10, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 94, + ]); + } + break; + } + return null; + } + + function isFiniteNumber(value) { + return typeof value === 'number' && isFinite(value); + } + /** + * For getting float string for a given value with type checking + * @param val Number + * @param precision Number of digits after decimal + */ + function toFixed(val, precision) { + if (isFiniteNumber(val)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return val.toFixed(precision); + } + return `${val}`; + } + /** + * Stringify except print numbers with fixed precision + * @param obj the value to stringify + * @param precision Number of digits after decimal. Default 3 + */ + function stringifyWithPrecision(obj, precision = 3) { + return JSON.stringify(obj, (_key, value) => { + return !isNaN(value) && (value === null || value === void 0 ? void 0 : value.toFixed) ? Number(value === null || value === void 0 ? void 0 : value.toFixed(precision)) : value; + }); + } + /** + * Replace all occurrences of an instance in a string + * + * @param {string|RegExp} search - What to change + * @param {string} replacement - Replace search for this + * @param {string} target - Target string to have elements replaced + * @returns {string} + */ + const replaceAll = (search, replacement, target = '') => target.split(search).join(replacement); + let shouldRedactUrl = true; + function setupRedactUrl(buildType) { + shouldRedactUrl = buildType === 'production'; + } + function redactUrl(url) { + return shouldRedactUrl ? '' : url; + } + // Naive deep copy of any serializable object + // shallow copy for function, symbol + function deepCpy(obj) { + if (!obj) { + return obj; + } + switch (typeof obj) { + case 'object': + if (Array.isArray(obj)) { + return obj.map(deepCpy); + } + const result = {}; + for (const [key, value] of Object.entries(obj)) { + result[key] = deepCpy(value); + } + return result; + default: + return obj; + } + } + function urlRedactedLevelInfo(indata) { + const outdata = [...indata]; + for (let i = 0; i < outdata.length; i++) { + outdata[i] = Object.assign({}, outdata[i]); + outdata[i].url = redactUrl(outdata[i].url); + if (outdata[i].attrs) { + outdata[i].attrs = Object.assign({}, outdata[i].attrs); + outdata[i].attrs.URI = redactUrl(outdata[i].attrs.URI); + } + } + return outdata; + } + function urlRedactedAltMediaOption(indata) { + const outdata = [...indata]; + for (let i = 0; i < outdata.length; i++) { + outdata[i] = Object.assign({}, outdata[i]); + outdata[i].url = redactUrl(outdata[i].url); + } + return outdata; + } + + /** + * Generate MP4 Box + * + * + * + * + */ + const UINT32_MAX$1 = Math.pow(2, 32) - 1; + class MP4 { + static init() { + MP4.types = { + avc1: [], + avcC: [], + btrt: [], + dinf: [], + dref: [], + esds: [], + free: [], + ftyp: [], + hdlr: [], + mdat: [], + mdhd: [], + mdia: [], + mfhd: [], + minf: [], + moof: [], + moov: [], + mp4a: [], + '.mp3': [], + dac3: [], + 'ac-3': [], + dec3: [], + 'ec-3': [], + mvex: [], + mvhd: [], + pasp: [], + sdtp: [], + stbl: [], + stco: [], + stsc: [], + stsd: [], + stsz: [], + stts: [], + tfdt: [], + tfhd: [], + traf: [], + trak: [], + trun: [], + trex: [], + tkhd: [], + vmhd: [], + smhd: [], + uuid: [], + encv: [], + enca: [], + // map encryption boxes + frma: [], + schm: [], + schi: [], + senc: [], + saio: [], + saiz: [], + sinf: [], + tenc: [], + // moof encryption boxes + sbgp: [], + seig: [], + sgpd: [], + pssh: [], + }; + let i; + for (i in MP4.types) { + // eslint-disable-next-line no-prototype-builtins + if (MP4.types.hasOwnProperty(i)) { + MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)]; + } + } + const videoHdlr = new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 118, + 105, + 100, + 101, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 86, + 105, + 100, + 101, + 111, + 72, + 97, + 110, + 100, + 108, + 101, + 114, + 0, + ]); + const audioHdlr = new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 115, + 111, + 117, + 110, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 83, + 111, + 117, + 110, + 100, + 72, + 97, + 110, + 100, + 108, + 101, + 114, + 0, + ]); + MP4.HDLR_TYPES = { + video: videoHdlr, + audio: audioHdlr, + }; + const dref = new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 12, + 117, + 114, + 108, + 32, + 0, + 0, + 0, + 1, + ]); + const stco = new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]); + MP4.STTS = MP4.STSC = MP4.STCO = stco; + MP4.STSZ = new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]); + MP4.VMHD = new Uint8Array([ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]); + MP4.SMHD = new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]); + MP4.STSD = new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + ]); // entry_count + const majorBrand = new Uint8Array([105, 115, 111, 109]); // isom + const avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1 + const minorVersion = new Uint8Array([0, 0, 0, 1]); + MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand); + MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref)); + } + static set16(num, data, index) { + data[index] = (num >> 8) & 255; + data[index + 1] = num & 255; + return index + 2; + } + static set32(num, data, index) { + data[index] = (num >> 24) & 255; + data[index + 1] = (num >> 16) & 255; + data[index + 2] = (num >> 8) & 255; + data[index + 3] = num & 255; + return index + 4; + } + static box(type, ...params) { + // eslint-disable-next-line prefer-rest-params + const payload = Array.prototype.slice.call(arguments, 1); + let size = 8, i = payload.length; + const len = i; + // calculate the total size we need to allocate + while (i--) { + size += payload[i].byteLength; + } + const result = new Uint8Array(size); + result[0] = (size >> 24) & 255; + result[1] = (size >> 16) & 255; + result[2] = (size >> 8) & 255; + result[3] = size & 255; + result.set(type, 4); + // copy the payload into the result + for (i = 0, size = 8; i < len; i++) { + // copy payload[i] array @ offset size + result.set(payload[i], size); + size += payload[i].byteLength; + } + return result; + } + static hdlr(type) { + return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]); + } + static mdat(data) { + return MP4.box(MP4.types.mdat, data); + } + static mdhd(timescale, duration) { + duration *= timescale; + const upperWordDuration = Math.floor(duration / (UINT32_MAX$1 + 1)); + const lowerWordDuration = Math.floor(duration % (UINT32_MAX$1 + 1)); + return MP4.box(MP4.types.mdhd, new Uint8Array([ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + (timescale >> 24) & 255, + (timescale >> 16) & 255, + (timescale >> 8) & 255, + timescale & 255, + upperWordDuration >> 24, + (upperWordDuration >> 16) & 255, + (upperWordDuration >> 8) & 255, + upperWordDuration & 255, + lowerWordDuration >> 24, + (lowerWordDuration >> 16) & 255, + (lowerWordDuration >> 8) & 255, + lowerWordDuration & 255, + 85, + 196, + 0, + 0, + ])); + } + static mdia(track) { + const mdhd = MP4.mdhd(track.info.timescale, track.info.duration); + const hdlr = MP4.hdlr(track.type); + const minf = MP4.minf(track); + return MP4.box(MP4.types.mdia, mdhd, hdlr, minf); + } + static mfhd(sequenceNumber) { + return MP4.box(MP4.types.mfhd, new Uint8Array([ + 0, + 0, + 0, + 0, + sequenceNumber >> 24, + (sequenceNumber >> 16) & 255, + (sequenceNumber >> 8) & 255, + sequenceNumber & 255, // sequence_number + ])); + } + static minf(track) { + if (track.type === 'audio') { + return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track)); + } + else { + return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track)); + } + } + static moof(baseMediaDecodeTime, track) { + if (!MP4.types) { + MP4.init(); + } + const traf = MP4.traf(track, baseMediaDecodeTime); + const moof = MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), traf); + return moof; + } + /** + * @param tracks... (optional) {array} the tracks associated with this movie + */ + static moov(tracks) { + let i = tracks.length; + const boxes = []; + while (i--) { + boxes[i] = MP4.trak(tracks[i]); + } + return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].info.timescale, tracks[0].info.duration)].concat(boxes).concat(MP4.mvex(tracks))); + } + static mvex(tracks) { + let i = tracks.length; + const boxes = []; + while (i--) { + boxes[i] = MP4.trex(tracks[i]); + } + return MP4.box(MP4.types.mvex, ...boxes); + // return MP4.box.apply(null, [MP4.types.mvex, .concat(boxes)); + } + static mvhd(timescale, duration) { + duration *= timescale; + const upperWordDuration = Math.floor(duration / (UINT32_MAX$1 + 1)); + const lowerWordDuration = Math.floor(duration % (UINT32_MAX$1 + 1)); + const bytes = new Uint8Array([ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + (timescale >> 24) & 255, + (timescale >> 16) & 255, + (timescale >> 8) & 255, + timescale & 255, + upperWordDuration >> 24, + (upperWordDuration >> 16) & 255, + (upperWordDuration >> 8) & 255, + upperWordDuration & 255, + lowerWordDuration >> 24, + (lowerWordDuration >> 16) & 255, + (lowerWordDuration >> 8) & 255, + lowerWordDuration & 255, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + ]); + return MP4.box(MP4.types.mvhd, bytes); + } + static sdtp(track) { + const samples = track.samples || [], bytes = new Uint8Array(4 + samples.length); + let flags, i; + // leave the full box header (4 bytes) all zero + // write the sample table + for (i = 0; i < samples.length; i++) { + flags = samples[i].flags; + bytes[i + 4] = (flags.dependsOn << 4) | (flags.isDependedOn << 2) | flags.hasRedundancy; + } + return MP4.box(MP4.types.sdtp, bytes); + } + static stbl(track) { + const stsd = MP4.stsd(track); + const stts = MP4.box(MP4.types.stts, MP4.STTS); + const stsc = MP4.box(MP4.types.stsc, MP4.STSC); + const stsz = MP4.box(MP4.types.stsz, MP4.STSZ); + const stco = MP4.box(MP4.types.stco, MP4.STCO); + return MP4.box(MP4.types.stbl, stsd, stts, stsc, stsz, stco); + } + static avc1(track) { + let sps = [], pps = [], i, data, len; + // assemble the SPSs + const codingName = track.info.encrypted ? MP4.types.encv : MP4.types.avc1; + for (i = 0; i < track.config.sps.length; i++) { + data = track.config.sps[i]; + len = data.byteLength; + sps.push((len >>> 8) & 255); + sps.push(len & 255); + sps = sps.concat(Array.prototype.slice.call(data)); // SPS + } + // assemble the PPSs + for (i = 0; i < track.config.pps.length; i++) { + data = track.config.pps[i]; + len = data.byteLength; + pps.push((len >>> 8) & 255); + pps.push(len & 255); + pps = pps.concat(Array.prototype.slice.call(data)); + } + const avcc = MP4.box(MP4.types.avcC, new Uint8Array([ + 1, + sps[3], + sps[4], + sps[5], + 255, + 224 | track.config.sps.length, // 3bit reserved (111) + numOfSequenceParameterSets + ] + .concat(sps) + .concat([ + track.config.pps.length, // numOfPictureParameterSets + ]) + .concat(pps))), // "PPS" + width = track.config.width, height = track.config.height, hSpacing = track.config.pixelRatio[0], vSpacing = track.config.pixelRatio[1]; + // console.log('avcc:' + Hex.hexDump(avcc)); + const sinf = track.info.encrypted && track.info.keyTagInfo ? MP4.sinf(track.info.keyTagInfo, track.type, MP4.types.avc1) : new Uint8Array(); + // console.log('video sinf:' + Hex.hexDump(sinf)); + return MP4.box(codingName, new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + (width >> 8) & 255, + width & 255, + (height >> 8) & 255, + height & 255, + 0, + 72, + 0, + 0, + 0, + 72, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 18, + 100, + 97, + 105, + 108, + 121, + 109, + 111, + 116, + 105, + 111, + 110, + 47, + 104, + 108, + 115, + 46, + 106, + 115, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24, + 17, + 17, + ]), // pre_defined = -1 + avcc, sinf, MP4.box(MP4.types.btrt, new Uint8Array([ + 0, + 28, + 156, + 128, + 0, + 45, + 198, + 192, + 0, + 45, + 198, + 192, + ])), // avgBitrate + MP4.box(MP4.types.pasp, new Uint8Array([ + hSpacing >> 24, + (hSpacing >> 16) & 255, + (hSpacing >> 8) & 255, + hSpacing & 255, + vSpacing >> 24, + (vSpacing >> 16) & 255, + (vSpacing >> 8) & 255, + vSpacing & 255, + ]))); + } + static esds(config) { + const configlen = config.esdsConfig.length; + return new Uint8Array([ + 0, + 0, + 0, + 0, + 3, + 23 + configlen, + 0, + 1, + 0, + 4, + 15 + configlen, + 64, + 21, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + ] + .concat([configlen]) + .concat(config.esdsConfig) + .concat([6, 1, 2])); // GASpecificConfig)); // length + audio config descriptor + } + static audioStsd(config) { + const samplerate = config.samplerate; + return new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + config.channelCount, + 0, + 16, + 0, + 0, + 0, + 0, + (samplerate >> 8) & 255, + samplerate & 255, + 0, + 0, + ]); + } + static dac3(config) { + const extraData = config.extraData; + return new Uint8Array([(extraData >> 16) & 255, (extraData >> 8) & 255, extraData & 255]); + } + static dec3(config) { + return config.extraDataBytes; + } + static mp4a(info, config) { + let codingName = MP4.types.mp4a; + let sinf = null; + if (info.encrypted && info.keyTagInfo) { + codingName = MP4.types.enca; + sinf = MP4.sinf(info.keyTagInfo, 'audio', MP4.types.mp4a); + } + else { + sinf = new Uint8Array(); + } + const stsd = MP4.audioStsd(config); + const esds = MP4.box(MP4.types.esds, MP4.esds(config)); + return MP4.box(codingName, stsd, esds, sinf); + } + static mp3(config) { + return MP4.box(MP4.types['.mp3'], MP4.audioStsd(config)); + } + static ac3(info, config) { + let codingName = MP4.types['ac-3']; + let sinf = null; + if (info.encrypted && info.keyTagInfo) { + codingName = MP4.types.enca; + sinf = MP4.sinf(info.keyTagInfo, 'audio', MP4.types['ac-3']); + } + else { + sinf = new Uint8Array(); + } + return MP4.box(codingName, MP4.audioStsd(config), MP4.box(MP4.types.dac3, MP4.dac3(config)), sinf); + } + static ec3(info, config) { + let codingName = MP4.types['ec-3']; + let sinf = null; + if (info.encrypted && info.keyTagInfo) { + codingName = MP4.types.enca; + sinf = MP4.sinf(info.keyTagInfo, 'audio', MP4.types['ec-3']); + } + else { + sinf = new Uint8Array(); + } + return MP4.box(codingName, MP4.audioStsd(config), MP4.box(MP4.types.dec3, MP4.dec3(config)), sinf); + } + static stsd(track) { + if (track.type === 'audio') { + if (track.config.segmentCodec === 'mp3' && track.config.codec === 'mp3') { + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track.config)); + } + if (track.config.segmentCodec === 'ac3') { + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track.info, track.config)); + } + else if (track.config.segmentCodec === 'ec3') { + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ec3(track.info, track.config)); + } + else if (track.config.segmentCodec === 'aac') { + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track.info, track.config)); + } + else { + throw `unknown segmentCodec ${track.config.segmentCodec}`; + } + } + else { + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track)); + } + } + static tkhd(track) { + const id = track.info.id; + const duration = track.info.duration * track.info.timescale; + const upperWordDuration = Math.floor(duration / (UINT32_MAX$1 + 1)); + const lowerWordDuration = Math.floor(duration % (UINT32_MAX$1 + 1)); + let width = 0; + let height = 0; + if (track.type === 'video') { + width = track.config.width; + height = track.config.height; + } + return MP4.box(MP4.types.tkhd, new Uint8Array([ + 1, + 0, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + (id >> 24) & 255, + (id >> 16) & 255, + (id >> 8) & 255, + id & 255, + 0, + 0, + 0, + 0, + upperWordDuration >> 24, + (upperWordDuration >> 16) & 255, + (upperWordDuration >> 8) & 255, + upperWordDuration & 255, + lowerWordDuration >> 24, + (lowerWordDuration >> 16) & 255, + (lowerWordDuration >> 8) & 255, + lowerWordDuration & 255, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 0, + 0, + 0, + (width >> 8) & 255, + width & 255, + 0, + 0, + (height >> 8) & 255, + height & 255, + 0, + 0, + ])); + } + static traf(track, baseMediaDecodeTime) { + const sencOffset = 76; // mdat header + const sampleEncryptionBoxTuple = MP4.senc(track); + const sampleDependencyTable = MP4.sdtp(track), sampleEncryptionBox = sampleEncryptionBoxTuple.boxData, sampleEncryptionOffsetBox = sampleEncryptionBox.length ? MP4.saio(sencOffset) : new Uint8Array(), sampleEncryptionSizeBox = sampleEncryptionBox.length ? MP4.saiz(sampleEncryptionBoxTuple.defaultSampleInfoSize, sampleEncryptionBoxTuple.sampleInfoSizes) : new Uint8Array(), sampleToGroupBox = MP4.sbgp(track), sampleGroupDescriptionBox = MP4.sgpd(track), id = track.id, upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX$1 + 1)), lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX$1 + 1)); + // console.log('sampleToGroupBox:' + Hex.hexDump(sampleToGroupBox)); + // console.log('sampleGroupDescriptionBox:' + Hex.hexDump(sampleGroupDescriptionBox)); + return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([ + 0, + 2, + 0, + 0, + id >> 24, + (id >> 16) & 255, + (id >> 8) & 255, + id & 255, // track_ID + ])), MP4.box(MP4.types.tfdt, new Uint8Array([ + 1, + 0, + 0, + 0, + upperWordBaseMediaDecodeTime >> 24, + (upperWordBaseMediaDecodeTime >> 16) & 255, + (upperWordBaseMediaDecodeTime >> 8) & 255, + upperWordBaseMediaDecodeTime & 255, + lowerWordBaseMediaDecodeTime >> 24, + (lowerWordBaseMediaDecodeTime >> 16) & 255, + (lowerWordBaseMediaDecodeTime >> 8) & 255, + lowerWordBaseMediaDecodeTime & 255, + ])), sampleEncryptionBox, sampleEncryptionOffsetBox, sampleEncryptionSizeBox, sampleToGroupBox, sampleGroupDescriptionBox, MP4.trun(track, sampleDependencyTable.length + + sampleEncryptionBox.length + + sampleToGroupBox.length + + sampleGroupDescriptionBox.length + + sampleEncryptionOffsetBox.length + + sampleEncryptionSizeBox.length + 16 + // tfhd + 20 + // tfdt + 8 + // traf header + 16 + // mfhd + 8 + // moof header + 8), // mdat header + sampleDependencyTable); + } + /** + * Generate a track box. + * @param track {object} a track definition + * @return {Uint8Array} the track box + */ + static trak(track) { + if ('trakData' in track) { + // cached trak + return track.trakData; + } + track.info.duration = track.info.duration || 4294967295; + const trak = MP4.types.trak; + const thkd = MP4.tkhd(track); + const mdia = MP4.mdia(track); + return MP4.box(trak, thkd, mdia); + } + static trex(track) { + const id = track.info.id; + return MP4.box(MP4.types.trex, new Uint8Array([ + 0, + 0, + 0, + 0, + id >> 24, + (id >> 16) & 255, + (id >> 8) & 255, + id & 255, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + ])); + } + static trun(track, offset) { + const samples = track.samples || [], len = samples.length, arraylen = 12 + 16 * len, array = new Uint8Array(arraylen); + let i, sample, duration, size, flags, cts; + offset += 8 + arraylen; + array.set([ + 0, + 0, + 15, + 1, + (len >>> 24) & 255, + (len >>> 16) & 255, + (len >>> 8) & 255, + len & 255, + (offset >>> 24) & 255, + (offset >>> 16) & 255, + (offset >>> 8) & 255, + offset & 255, // data_offset + ], 0); + for (i = 0; i < len; i++) { + sample = samples[i]; + duration = sample.duration; + size = sample.size; + flags = sample.flags; + cts = sample.cts; + array.set([ + (duration >>> 24) & 255, + (duration >>> 16) & 255, + (duration >>> 8) & 255, + duration & 255, + (size >>> 24) & 255, + (size >>> 16) & 255, + (size >>> 8) & 255, + size & 255, + (flags.isLeading << 2) | flags.dependsOn, + (flags.isDependedOn << 6) | (flags.hasRedundancy << 4) | (flags.paddingValue << 1) | flags.isNonSync, + flags.degradPrio & (240 << 8), + flags.degradPrio & 15, + (cts >>> 24) & 255, + (cts >>> 16) & 255, + (cts >>> 8) & 255, + cts & 255, // sample_composition_time_offset + ], 12 + 16 * i); + } + return MP4.box(MP4.types.trun, array); + } + static initSegment(tracks) { + if (!MP4.types) { + MP4.init(); + } + const movie = MP4.moov(tracks); + const result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength); + result.set(MP4.FTYP); + result.set(movie, MP4.FTYP.byteLength); + return result; + } + // encryption boxes + static saio(sencOffset) { + const subOffset = sencOffset + 4 + 4; // skip version/flags and sample_count + return MP4.box(MP4.types.saio, new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + (subOffset >> 24) & 255, + (subOffset >> 16) & 255, + (subOffset >> 8) & 255, + subOffset & 255, + ])); + } + static saiz(defaultSampleInfoSize, sampleInfoSizes) { + if (!isFiniteNumber(defaultSampleInfoSize)) { + defaultSampleInfoSize = 0; + } + const sampleCount = sampleInfoSizes.length; + const perSampleSizeData = defaultSampleInfoSize === 0 ? new Uint8Array(sampleInfoSizes) : new Uint8Array(); + return MP4.box(MP4.types.saiz, new Uint8Array([ + 0, + 0, + 0, + 0, + defaultSampleInfoSize, + (sampleCount >> 24) & 255, + (sampleCount >> 16) & 255, + (sampleCount >> 8) & 255, + sampleCount & 255, + ]), perSampleSizeData); + } + static senc(track) { + const samples = track.samples || [], sampleCount = samples.length; + let totalSubsamples = 0; + let lastSize = NaN; + let hasDefaultSampleSize = true; + const sampleInfoSizes = []; + if (!track.encrypted || sampleCount <= 0) { + return { boxData: new Uint8Array(), sampleInfoSizes, defaultSampleInfoSize: 0 }; + } + const defaultPerSampleIVSize = track.defaultPerSampleIVSize ? track.defaultPerSampleIVSize : 0; + for (const sample of samples) { + if (sample.subsamples) { + totalSubsamples += sample.subsamples.length; + } + } + if (totalSubsamples <= 0) { + // don't create a senc if there are no subsamples + return { boxData: new Uint8Array(), sampleInfoSizes, defaultSampleInfoSize: 0 }; + } + // 4 bytes for sample_count + // 2 bytes per sample for subsample_count + // 6 bytes per subsample for unsigned int(16) BytesOfClearData and unsigned int(32) BytesOfProtectedData; + // defaultPerSampleIVSize bytes per sample + const boxdata = new Uint8Array(4 + (sampleCount * 2 + sampleCount * defaultPerSampleIVSize + totalSubsamples * 6)); + let offset = this.set32(sampleCount, boxdata, 0); + for (const sample of samples) { + const subsamples = sample.subsamples ? sample.subsamples : []; + let subsampleSize = 2; // size in bytes of the subsample entry - start with 2 for the subsample count + if (sample.iv) { + // per sample IV from cenc aux data + boxdata.set(sample.iv, offset); + offset += sample.iv.byteLength; + subsampleSize += sample.iv.byteLength; + } + offset = this.set16(subsamples.length, boxdata, offset); + for (const subsample of subsamples) { + offset = this.set16(subsample[0], boxdata, offset); + offset = this.set32(subsample[1], boxdata, offset); + subsampleSize += 6; + } + sampleInfoSizes.push(subsampleSize); + if (!isFiniteNumber(lastSize)) { + lastSize = subsampleSize; + } + hasDefaultSampleSize = hasDefaultSampleSize && lastSize === subsampleSize; + lastSize = subsampleSize; + } + const boxData = MP4.box(MP4.types.senc, new Uint8Array([ + 0, + 0, + 0, + 2, + ]), boxdata); + return { boxData, defaultSampleInfoSize: hasDefaultSampleSize ? lastSize : 0, sampleInfoSizes }; + } + static sinf(decryptdata, type, originalCodingName) { + return MP4.box(MP4.types.sinf, MP4.frma(originalCodingName), MP4.schm(), MP4.schi(decryptdata, type)); + } + static frma(originalCodingName) { + return MP4.box(MP4.types.frma, new Uint8Array(originalCodingName)); + } + static schm() { + return MP4.box(MP4.types.schm, new Uint8Array([ + 0, + 0, + 0, + 0, + 99, + 98, + 99, + 115, + 0, + 1, + 0, + 0, + ])); + } + static schi(decryptdata, type) { + return MP4.box(MP4.types.schi, MP4.tenc(decryptdata, type)); + } + static tenc(decryptdata, trackType) { + let skipPattern = 0; + if (trackType === 'video') { + skipPattern = 25; // 1 default_crypt_byte_block, 9 default_skip_byte_block + } + const defaultIV = new Uint8Array(17); + defaultIV[0] = 16; // default_constant_IV_size (16) + if (decryptdata.iv && decryptdata.iv.byteLength === 16) { + defaultIV.set(decryptdata.iv, 1); + } + if (!decryptdata.keyId) { + throw 'tenc: no key id found in decryptdata'; + } + return MP4.box(MP4.types.tenc, new Uint8Array([ + 1, + 0, + 0, + 0, + 0, + skipPattern, + 1, + 0, + ]), decryptdata.keyId, // default_KID, 16 bytes + defaultIV); + } + // only using this to write seig entries + static sbgp(track) { + if (!track.encrypted || track.samples.length === 0 || !track.samples[0].keyTagInfo) { + return new Uint8Array(); + } + // at this point we're assuming all samples in the track have the same key id + // this should hold true for the current ts/mp4 remux path + const sampleCount = track.samples.length; + return MP4.box(MP4.types.sbgp, new Uint8Array([ + 0, + 0, + 0, + 0, + ]), new Uint8Array(MP4.types.seig), // grouping_type + new Uint8Array([ + 0, + 0, + 0, + 1, + (sampleCount >> 24) & 255, + (sampleCount >> 16) & 255, + (sampleCount >> 8) & 255, + sampleCount & 255, + 0, + 1, + 0, + 1, + ])); + } + // only using this to write seig entries + static sgpd(track) { + if (!track.encrypted || track.samples.length === 0 || !track.samples[0].keyTagInfo) { + return new Uint8Array(); + } + const sDecryptdata = track.samples[0].keyTagInfo; + let skipPattern = 0; + if (track.type === 'video') { + skipPattern = 25; // 1 default_crypt_byte_block, 9 default_skip_byte_block + } + const sizeAndIv = new Uint8Array(17); + sizeAndIv[0] = 16; + if (sDecryptdata.iv) { + sizeAndIv.set(sDecryptdata.iv, 1); + } + if (!sDecryptdata.keyId) { + throw 'sgpd: no keyid in decryptdata'; + } + return MP4.box(MP4.types.sgpd, new Uint8Array([ + 1, + 0, + 0, + 0, + ]), new Uint8Array(MP4.types.seig), // grouping_type + new Uint8Array([ + 0, + 0, + 0, + 37, + 0, + 0, + 0, + 1, + ]), new Uint8Array([ + 0, + skipPattern, + 1, + 0, + ]), sDecryptdata.keyId, sizeAndIv); + } + /** + * @param {Uint8Array} systemId 16 bytes + * @param {array of Uint8Array} keyids The list of key ids described by this PSSH box + * @param {Uint8Array} An arbitrary buffer of data to be used in the data field of the PSSH box + * @returns {Uint8Array} Bytes representing a PSSH box + */ + static pssh(systemId, keyids, data) { + if (!MP4.types) { + MP4.init(); + } + if (!systemId) { + throw new TypeError('Bad system id'); + } + if (systemId.byteLength !== 16) { + throw new RangeError('Invalid system id'); + } + let version; + let kids; + if (keyids) { + version = 1; + kids = new Uint8Array(keyids.length * 16); + for (let ix = 0; ix < keyids.length; ix++) { + const k = keyids[ix]; // uint8array + if (k.byteLength !== 16) { + throw new RangeError('Invalid key'); + } + kids.set(k, ix * 16); + } + } + else { + version = 0; + kids = new Uint8Array(); + } + let kidCount; + if (version > 0) { + kidCount = new Uint8Array(4); + if (keyids.length > 0) { + new DataView(kidCount.buffer).setUint32(0, keyids.length, false); // Big endian + } + } + else { + kidCount = new Uint8Array(); + } + const dataSize = new Uint8Array(4); // Mandatory field + if (data && data.byteLength > 0) { + new DataView(dataSize.buffer).setUint32(0, data.byteLength, false); // Big endian + } + return MP4.box(MP4.types.pssh, new Uint8Array([ + version, + 0, + 0, + 0, + ]), systemId, // 16 bytes + kidCount, kids, dataSize, data || new Uint8Array()); + } + } + var MP4$1 = MP4; + + var VideoDynamicRangeType; + (function (VideoDynamicRangeType) { + // should be same as AirPlayVideoDynamicRangeFormat + VideoDynamicRangeType[VideoDynamicRangeType["SDR"] = 0] = "SDR"; + VideoDynamicRangeType[VideoDynamicRangeType["HDR"] = 1] = "HDR"; + VideoDynamicRangeType[VideoDynamicRangeType["HDR10"] = 2] = "HDR10"; + VideoDynamicRangeType[VideoDynamicRangeType["DolbyVision"] = 3] = "DolbyVision"; + VideoDynamicRangeType[VideoDynamicRangeType["HLG"] = 4] = "HLG"; + })(VideoDynamicRangeType || (VideoDynamicRangeType = {})); + var CompressionType; + (function (CompressionType) { + // should be same as AirPlayCompressionType + CompressionType[CompressionType["H264"] = 16] = "H264"; + CompressionType[CompressionType["HEVC"] = 64] = "HEVC"; + CompressionType[CompressionType["VP09"] = 65] = "VP09"; + })(CompressionType || (CompressionType = {})); + + // import { AudioSegmentCodecType } from '../types/tracks'; + /* + * 2018 Apple Inc. All rights reserved. + */ + const ac3Codecs = new Set(['ac-3', 'mp4a.a5', 'mp4a.A5']); + const ec3Codecs = new Set(['ec-3', 'mp4a.a6', 'mp4a.A6']); + const SampleDurationMap = { aac: 1024, mp3: 1024, ac3: 1536, ec3: 1536 }; + const MediaUtil = { + isAC3(codec) { + return Boolean(codec && ac3Codecs.has(codec)); + }, + isEC3(codec) { + return Boolean(codec && ec3Codecs.has(codec)); + }, + isDolbyAtmos(codec, channels) { + const parameters = channels.split('/'); + return Boolean(MediaUtil.isEC3(codec) && parameters.length > 1 && parameters[1].split(',').find((x) => x === 'JOC')); + }, + isAAC(codec) { + let match; + return Boolean(codec && (codec === 'aac' || ((match = codec.match(/^mp4a\.40\.(.*)/)) !== null && match[1] !== '34'))); + }, + isMP3(codec) { + let match; + return Boolean(codec && (codec === 'mp3' || ((match = codec.match(/^mp4a\.40\.(.*)/)) !== null && match[1] === '34'))); + }, + isAVC(codec) { + // basic match without validation + return Boolean(codec && codec.match(/^avc[13]\.(.*)/)); + }, + isXHEAAC: function (codec) { + return Boolean(codec === 'mp4a.40.42'); + }, + isALAC: function (codec) { + return Boolean(codec === 'alac'); + }, + isFLAC: function (codec) { + return Boolean(codec === 'fLaC'); + }, + isHEVC(codec) { + // basic match without validation + return Boolean(codec && codec.match(/^(hev|hvc)1\..*/)); + }, + isDolby(codec) { + return Boolean(codec && codec.match(/^dv(h1|he|a1|av)\..*/)); + }, + isVP09(codec) { + // basic match without validation + return Boolean(codec && codec.match(/^vp09\..*/)); + }, + isCompatibleCodecString(c1, c2) { + const codecs1 = c1.split(','); + const codecs2 = c2.split(','); + const videoCodec1 = codecs1.filter((codec) => MediaUtil.isVideoCodec(codec)); + const videoCodec2 = codecs2.filter((codec) => MediaUtil.isVideoCodec(codec)); + const audioCodec1 = codecs1.filter((codec) => MediaUtil.isAudioCodec(codec)); + const audioCodec2 = codecs2.filter((codec) => MediaUtil.isAudioCodec(codec)); + const videoOk = (videoCodec1.length === 0 && videoCodec2.length === 0) || (videoCodec1.length === videoCodec2.length && MediaUtil.isCompatibleVideoCodec(videoCodec1[0], videoCodec2[0])); + const audioOk = (audioCodec1.length === 0 && audioCodec2.length === 0) || (audioCodec1.length === audioCodec2.length && MediaUtil.isCompatibleAudioCodec(audioCodec1[0], audioCodec2[0])); + return videoOk && audioOk; + }, + isVideoCodec(codec) { + return MediaUtil.isAVC(codec) || MediaUtil.isDolby(codec) || MediaUtil.isHEVC(codec) || MediaUtil.isVP09(codec); + }, + isAudioCodec(codec) { + return MediaUtil.isAC3(codec) || MediaUtil.isEC3(codec) || MediaUtil.isAAC(codec) || MediaUtil.isMP3(codec); + }, + isCompatibleVideoCodec(c1, c2) { + return Boolean(c1 && + c2 && + (c1 === c2 || + (MediaUtil.isDolby(c1) && MediaUtil.isDolby(c2)) || + (MediaUtil.isHEVC(c1) && MediaUtil.isHEVC(c2)) || + (MediaUtil.isAVC(c1) && MediaUtil.isAVC(c2)) || + (MediaUtil.isVP09(c1) && MediaUtil.isVP09(c2)))); + }, + isCompatibleAudioCodec(c1, c2) { + return Boolean(c1 && + c2 && + (c1 === c2 || + (MediaUtil.isAAC(c1) && MediaUtil.isAAC(c2)) || + (MediaUtil.isAC3(c1) && MediaUtil.isAC3(c2)) || + (MediaUtil.isEC3(c1) && MediaUtil.isEC3(c2)) || + (MediaUtil.isMP3(c1) && MediaUtil.isMP3(c2)))); + }, + getSegmentCodec(audioCodec) { + let segmentCodec; + if (MediaUtil.isAAC(audioCodec)) { + segmentCodec = 'aac'; + } + else if (MediaUtil.isAC3(audioCodec)) { + segmentCodec = 'ac3'; + } + else if (MediaUtil.isEC3(audioCodec)) { + segmentCodec = 'ec3'; + } + else if (audioCodec === 'mp3') { + segmentCodec = 'mp3'; + } + else { + throw new Error(`invalid audio config, codec ${audioCodec}`); + } + return segmentCodec; + }, + getChannelCount(channels) { + if (!channels) { + return 0; + } + const parameters = channels.split('/'); + const channelCount = parseInt(parameters[0]); + if (!isFiniteNumber(channelCount)) { + return 0; + } + return channelCount; + }, + avc1toavcoti(codec) { + var _a, _b; + const avcdata = codec.split('.'); + let result; + if (avcdata.length > 2) { + result = avcdata.shift() + '.'; + result += parseInt((_a = avcdata.shift()) !== null && _a !== void 0 ? _a : '').toString(16); + result += ('000' + parseInt((_b = avcdata.shift()) !== null && _b !== void 0 ? _b : '').toString(16)).substr(-4); + } + else { + result = codec; + } + return result; + }, + getDynamicRangeType(videoRange, videoCodec) { + let type = VideoDynamicRangeType.SDR; // default to SDR + if (videoRange === 'PQ' && MediaUtil.isDolby(videoCodec)) { + type = VideoDynamicRangeType.DolbyVision; + } + else if (videoRange === 'PQ' && (MediaUtil.isHEVC(videoCodec) || MediaUtil.isVP09(videoCodec))) { + type = VideoDynamicRangeType.HDR10; + } + else if (videoRange === 'HLG' && (videoCodec.indexOf('hvc1') !== -1 || MediaUtil.isVP09(videoCodec))) { + type = VideoDynamicRangeType.HLG; + } + return type; + }, + getCompressionType(videoCodec) { + let compressionType = CompressionType.H264; + if (MediaUtil.isHEVC(videoCodec) || MediaUtil.isDolby(videoCodec)) { + compressionType = CompressionType.HEVC; + } + else if (MediaUtil.isVP09(videoCodec)) { + compressionType = CompressionType.VP09; + } + return compressionType; + }, + isHigherCodecByFamily(currentCodec, newCodec) { + if (!currentCodec) { + return true; + } + const splitCurrentCodec = currentCodec.split('.'); + const splitNewCodec = newCodec.split('.'); + if (splitCurrentCodec[0] !== splitNewCodec[0]) { + throw new Error(`mismatch in codec family current/new: ${splitCurrentCodec[0]}/${splitNewCodec[0]}`); + } + switch (splitCurrentCodec[0]) { + case 'avc1': + case 'avc3': + return splitNewCodec[1] > splitCurrentCodec[1]; + case 'vp09': + return newCodec > currentCodec; + case 'hvc1': + case 'hev1': + const currentTier = splitCurrentCodec[3].substring(0, 1) === 'H' ? 1 : 0; + const currentLevel = splitCurrentCodec[3].substring(1); + const newTier = splitNewCodec[3].substring(0, 1) === 'H' ? 1 : 0; + const newLevel = splitNewCodec[3].substring(1); + return splitNewCodec[1] > splitCurrentCodec[1] || splitNewCodec[2] > splitCurrentCodec[2] || newTier > currentTier || newLevel > currentLevel; + case 'dvh1': + return splitNewCodec[1] > splitCurrentCodec[1] || splitNewCodec[2] > splitCurrentCodec[2]; + } + }, + }; + + class SilentAudio { + static getTrack(observer, id, codec, channelCount, logger) { + let track; + const segmentCodec = MediaUtil.getSegmentCodec(codec); + switch (segmentCodec) { + case 'aac': + { + let config; + if (channelCount === 1) { + config = ADTS.getAudioConfig(observer, new Uint8Array([255, 241, 92, 64, 1, 127, 252]), 0, codec, logger); + } + else { + config = ADTS.getAudioConfig(observer, new Uint8Array([255, 241, 92, 128, 1, 191, 252]), 0, codec, logger); + } + if (config) { + const info = { id, timescale: config.samplerate, duration: 0, encrypted: false, keyTagInfo: undefined }; + track = { type: 'audio', info, config }; + } + } + break; + case 'ac3': + case 'ec3': + { + const config = Dolby.getAudioConfig(observer, new Uint8Array([11, 119, 69, 17, 128, 64, 47, 132]), 0, logger); + if (config) { + const info = { id, timescale: config.samplerate, duration: 0, encrypted: false, keyTagInfo: undefined }; + track = { type: 'audio', info, config }; + } + } + break; + } + return track; + } + static getSample(codec, channelCount) { + let sample; + switch (codec) { + case 'mp4a.40.2': + case 'mp4a.40.5': + if (channelCount === 1) { + sample = new Uint8Array([0, 208, 0, 7]); + } + else { + sample = new Uint8Array([33, 0, 3, 64, 104, 28]); + } + break; + case 'ac-3': + case 'ec-3': + sample = new Uint8Array([ + 11, + 119, + 69, + 17, + 128, + 64, + 47, + 132, + 41, + 3, + 253, + 214, + 124, + 253, + 243, + 215, + 233, + 95, + 185, + 123, + 78, + 20, + 40, + 106, + 97, + 190, + 74, + 253, + 43, + 218, + 208, + 140, + 191, + 176, + 144, + 120, + 214, + 181, + 44, + 124, + 129, + 251, + 91, + 109, + 187, + 109, + 198, + 225, + 43, + 172, + 116, + 140, + 176, + 123, + 38, + 144, + 211, + 247, + 225, + 64, + 29, + 53, + 175, + 96, + 16, + 57, + 121, + 87, + 78, + 203, + 81, + 37, + 7, + 72, + 228, + 132, + 37, + 169, + 38, + 231, + 97, + 229, + 247, + 194, + 208, + 8, + 12, + 83, + 74, + 139, + 137, + 17, + 22, + 26, + 221, + 203, + 107, + 113, + 94, + 93, + 75, + 33, + 208, + 247, + 146, + 105, + 39, + 143, + 6, + 36, + 1, + 227, + 108, + 70, + 11, + 180, + 152, + 218, + 182, + 218, + 209, + 59, + 85, + 104, + 201, + 70, + 37, + 82, + 219, + 68, + 55, + 225, + 144, + 99, + 149, + 0, + 119, + 26, + 14, + 69, + 164, + 241, + 204, + 222, + 81, + 177, + 142, + 80, + 20, + 100, + 97, + 143, + 101, + 221, + 140, + 113, + 31, + 208, + 124, + 25, + 64, + 29, + 49, + 77, + 140, + 30, + 155, + 74, + 214, + 204, + 138, + 229, + 109, + 172, + 95, + 130, + 70, + 230, + 134, + 88, + 59, + 179, + 212, + 155, + 232, + 0, + 0, + 0, + 0, + 0, + 173, + 234, + ]); + break; + } + return sample; + } + static getSegment(silentTrack, sequenceNumber, startDtsTimescale, segmentDuration) { + if (!silentTrack) { + return; + } + const { timescale } = silentTrack.info; + const { segmentCodec } = silentTrack.config; + const silentFrame = SilentAudio.getSample(silentTrack.config.codec, silentTrack.config.channelCount); + if (!silentFrame) { + return; + } + const samples = []; + const track = { + id: silentTrack.info.id, + sequenceNumber, + type: 'audio', + encrypted: false, + samples, + defaultPerSampleIVSize: 0, + }; + const sampleDuration = SampleDurationMap[segmentCodec]; + const nbSamples = Math.ceil((segmentDuration * timescale) / sampleDuration); + const baseTime = Math.round(nbSamples * sampleDuration + startDtsTimescale); + const endTs = { baseTime, timescale }; + let offset = 0; + const mdatSize = nbSamples * silentFrame.byteLength + 8; + const mdat = new Uint8Array(mdatSize); + mdat[0] = (mdatSize >> 24) & 255; + mdat[1] = (mdatSize >> 16) & 255; + mdat[2] = (mdatSize >> 8) & 255; + mdat[3] = mdatSize & 255; + if (!MP4$1.types) { + MP4$1.init(); + } + mdat.set(MP4$1.types.mdat, 4); + offset += 8; + for (let i = 0; i < nbSamples; i++) { + samples.push({ + duration: sampleDuration, + size: silentFrame.byteLength, + cts: 0, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 1, + isNonSync: 0, + paddingValue: 0, + }, + }); + mdat.set(silentFrame, offset); + offset += silentFrame.byteLength; + } + const moof = MP4$1.moof(startDtsTimescale, track); + const silentFragData = new Uint8Array(moof.byteLength + mdat.byteLength); + silentFragData.set(moof); + silentFragData.set(mdat, moof.byteLength); + return { silentFragData, endTs }; + } + } + + // 10 seconds + const MAX_SILENT_FRAME_DURATION = 10000; + class EsRemuxer extends RemuxerBase { + constructor(observer, config, typeSupported, vendor, logger) { + super(observer, config, logger); + this.typeSupported = typeSupported; + this.isVideoContiguous = false; + this.logger = logger.child({ name: 'EsRemuxer' }); + const userAgent = navigator.userAgent; + this.isSafari = vendor && vendor.indexOf('Apple') > -1 && userAgent && !userAgent.match('CriOS'); + } + resetTimeStamp(defaultTimeStamp) { + this._initPTS = this._initDTS = defaultTimeStamp; + } + resetInitSegment() { + this.currentInitTrack = undefined; + this._silentAudioTrack = undefined; + } + /** + * @param timeOffset The position in the media element corresponding to this fragment when playback rate = 1 + * @param contiguous Whether this fragment is contiguous with previously appended fragment + * @param accurateTimeOffset Whether timeOffset is reliable + * @param keyTagInfo Information from EXT-X-KEY tag + * @param iframeMediaStart in iframe mode, the desired start DTS of the remuxed fragment + * @param iframeDuration in iframe mode, the desired duration of the remuxed fragment + */ + remuxEsTracks(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset, keyTagInfo, iframeMediaStart, iframeDuration) { + var _a; + if (!contiguous) { + this.isVideoContiguous = false; + } + // generate Init Segment if needed + let silentAudioSegment; + const timelineOffset = typeof iframeMediaStart === 'undefined' ? timeOffset : iframeMediaStart; + if (!this.currentInitTrack) { + if (audioTrack && audioTrack.config.codec) { + // when we start out in non-iframe mode we need to store the audio parameters + // we won't get this info from the iframe playlist since the demuxer will skip audio samples + this._audioTrackInfo = { id: audioTrack.info.id, codec: audioTrack.config.codec, channelCount: audioTrack.config.channelCount }; + } + if (videoTrack && iframeDuration && this._audioTrackInfo) { + const silentAudioBase = SilentAudio.getTrack(this.observer, this._audioTrackInfo.id, this._audioTrackInfo.codec, this._audioTrackInfo.channelCount, this.logger); + if (silentAudioBase) { + this._silentAudioTrack = Object.assign(Object.assign({}, silentAudioBase), { info: Object.assign(Object.assign({}, silentAudioBase.info), { inputTimescale: 90000 }), parsingData: { len: 0, sequenceNumber: 0, esSamples: [] } }); + // need to populate samples for generateIS + const segmentStartPTS = this._initPTS + Math.round(timelineOffset * this._silentAudioTrack.info.timescale); + silentAudioSegment = SilentAudio.getSegment(this._silentAudioTrack, videoTrack.parsingData.sequenceNumber, segmentStartPTS, iframeDuration); + videoTrack.parsingData.sequenceNumber++; + } + } + else { + this._silentAudioTrack = undefined; + } + this.updateInitPTSDTS(videoTrack, audioTrack, timeOffset); // Use real audioTrack info to update PTSDTS + this.generateIS(this._silentAudioTrack ? this._silentAudioTrack : audioTrack, videoTrack); + } + if (this.currentInitTrack) { + const remuxVideo = videoTrack && videoTrack.parsingData.esSamples.length; + const isVideoContiguous = this.isVideoContiguous; + let audioData, videoData; + // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is + // calculated in remuxAudio. + if (videoTrack && iframeDuration && this._silentAudioTrack && !silentAudioSegment) { + // samples could have been generated before init segment generation + const segmentStartPTS = this._initPTS + Math.round((timelineOffset + this.config.audioPrimingDelay) * this._silentAudioTrack.info.timescale); + silentAudioSegment = SilentAudio.getSegment(this._silentAudioTrack, videoTrack.parsingData.sequenceNumber, segmentStartPTS, iframeDuration); + } + if (audioTrack && audioTrack.parsingData.esSamples.length) { + // if initSegment was generated without video samples, regenerate it again + if (!isFiniteNumber(audioTrack.info.timescale)) { + this.logger.warn('regenerate InitSegment as audio detected'); + this.updateInitPTSDTS(videoTrack, audioTrack, timeOffset); // Use real audioTrack info to update PTSDTS + this.generateIS(audioTrack, videoTrack); + } + audioData = this.remuxAudio(audioTrack, timelineOffset, contiguous, accurateTimeOffset, keyTagInfo); + if (remuxVideo) { + let audioTrackLength; + if (audioData) { + audioTrackLength = convertTimestampToSeconds(audioData.endPTS) - convertTimestampToSeconds(audioData.startPTS); + } + // if initSegment was generated without video samples, regenerate it again + if (!isFiniteNumber(videoTrack.info.timescale)) { + this.logger.warn('regenerate InitSegment as video detected'); + this.updateInitPTSDTS(videoTrack, audioTrack, timeOffset); // Use real audioTrack info to update PTSDTS + this.generateIS(audioTrack, videoTrack); + } + videoData = this.remuxVideo(videoTrack, timelineOffset, isVideoContiguous, audioTrackLength, iframeDuration); + } + } + else { + if (remuxVideo) { + videoData = this.remuxVideo(videoTrack, timelineOffset, isVideoContiguous, undefined, iframeDuration); + } + if (videoData && audioTrack && audioTrack.config.codec) { + audioData = this.remuxEmptyAudio(audioTrack, timelineOffset, contiguous, accurateTimeOffset, videoData, keyTagInfo); + } + } + let parsingData; + if (silentAudioSegment) { + parsingData = { + data1: videoData.data1, + data2: silentAudioSegment.silentFragData, + startDTS: videoData.startDTS, + startPTS: videoData.startPTS, + endDTS: determineMaxTimestamp(videoData.endDTS, silentAudioSegment.endTs), + endPTS: determineMaxTimestamp(videoData.endPTS, silentAudioSegment.endTs), + type: 'audiovideo', + track: this.currentInitTrack, + }; + } + else if (videoData && audioData) { + parsingData = { + data1: videoData.data1, + data2: audioData.data1, + startDTS: determineMinTimestamp(videoData.startDTS, audioData.startDTS), + startPTS: determineMinTimestamp(videoData.startPTS, audioData.startPTS), + endDTS: determineMaxTimestamp(videoData.endDTS, audioData.endDTS), + endPTS: determineMaxTimestamp(videoData.endPTS, audioData.endPTS), + type: 'audiovideo', + track: this.currentInitTrack, + dropped: videoData.dropped, + framesWithoutIDR: videoData.framesWithoutIDR, + firstKeyframePts: videoData.firstKeyframePts, + }; + } + else if (videoData) { + parsingData = { + data1: videoData.data1, + startDTS: videoData.startDTS, + startPTS: videoData.startPTS, + endDTS: videoData.endDTS, + endPTS: videoData.endPTS, + type: 'video', + track: this.currentInitTrack, + dropped: videoData.dropped, + framesWithoutIDR: videoData.framesWithoutIDR, + firstKeyframePts: videoData.firstKeyframePts, + }; + } + else if (audioData) { + parsingData = { + data1: audioData.data1, + startDTS: audioData.startDTS, + startPTS: audioData.startPTS, + endDTS: audioData.endDTS, + endPTS: audioData.endPTS, + type: 'audio', + track: this.currentInitTrack, + }; + } + else { + this.logger.error('Missing video and audio data'); + } + if (textTrack && textTrack.captionSamples.length) { + this.remuxText(textTrack, parsingData); + } + if ((_a = id3Track === null || id3Track === void 0 ? void 0 : id3Track.id3Samples) === null || _a === void 0 ? void 0 : _a.length) { + this.remuxID3(id3Track, parsingData); + } + this.observer.trigger(DemuxerEvent.FRAG_PARSING_DATA, parsingData); + } + else { + this.logger.error('failed to generate IS'); + } + // notify end of parsing + this.observer.trigger(DemuxerEvent.FRAG_PARSED); + } + /** + * @param videoTrack + * @param audioTrack + * @param timeOffset Position in media element corresponding to the beginning of this segment + */ + updateInitPTSDTS(videoTrack, audioTrack, timeOffset) { + let initPTS = Infinity, initDTS = Infinity; + const videoSamples = videoTrack ? videoTrack.parsingData.esSamples : []; + const audioSamples = audioTrack ? audioTrack.parsingData.esSamples : []; + if (isFiniteNumber(this._initPTS)) { + return; + } + if (audioTrack && audioSamples.length) { + // remember first PTS of this demuxing context. for audio, PTS = DTS + initPTS = initDTS = audioSamples[0].pts - audioTrack.info.inputTimescale * timeOffset; + } + if (videoTrack && videoSamples.length) { + // let's use input time scale as MP4 video timescale + // we use input time scale straight away to avoid rounding issues on frame duration / cts computation + const inputTimeScale = videoTrack.info.inputTimescale; + videoTrack.info.timescale = inputTimeScale; + initPTS = Math.min(initPTS, getVideoStartPts(videoSamples) - inputTimeScale * timeOffset); + initDTS = Math.min(initDTS, videoSamples[0].dts - inputTimeScale * timeOffset); + this.observer.trigger(DemuxerEvent.INIT_PTS_FOUND, { initPTS: convertSecondsToTimestamp(initPTS, inputTimeScale) }); + } + if (isFiniteNumber(initPTS) && isFiniteNumber(initDTS)) { + this._initPTS = initPTS; + this._initDTS = initDTS; + } + else { + const payload = new FragParsingError(false, 'invalid initPTS or initDTS', ErrorResponses.InvalidInitTimestamp); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + } + } + generateIS(audioTrack, videoTrack) { + // const observer = this.observer; + const videoSamples = videoTrack ? videoTrack.parsingData.esSamples : []; + const typeSupported = this.typeSupported; + let container = 'audio/mp4'; + let track; + if (audioTrack && videoTrack && videoSamples.length) { + const inputTimeScale = videoTrack.info.inputTimescale; + videoTrack.info.timescale = inputTimeScale; + audioTrack.info.timescale = audioTrack.config.samplerate; + const initSegment = MP4.initSegment([videoTrack, audioTrack]); + track = { + type: 'audiovideo', + container: 'video/mp4', + codec: `${videoTrack.config.codec},${audioTrack.config.codec}`, + initSegment, + }; + } + else if (audioTrack) { + // let's use audio sampling rate as MP4 time scale. + // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC) + // using audio sampling rate here helps having an integer MP4 frame duration + // this avoids potential rounding issue and AV sync issue + audioTrack.info.timescale = audioTrack.config.samplerate; + this.logger.info(`audio sampling rate : ${audioTrack.config.samplerate}`); + switch (audioTrack.config.segmentCodec) { + case 'mp3': + if (typeSupported.mpeg) { + // Chrome and Safari + container = 'audio/mpeg'; + audioTrack.config.codec = ''; + } + else if (typeSupported.mp3) { + // Firefox + audioTrack.config.codec = 'mp3'; + } + break; + } + const initSegment = audioTrack.config.segmentCodec === 'mp3' && typeSupported.mpeg ? new Uint8Array() : MP4.initSegment([audioTrack]); + track = { + type: 'audio', + container: container, + codec: audioTrack.config.codec, + initSegment, + }; + } + else if (videoTrack && videoSamples.length) { + // let's use input time scale as MP4 video timescale + // we use input time scale straight away to avoid rounding issues on frame duration / cts computation + const inputTimeScale = videoTrack.info.inputTimescale; + videoTrack.info.timescale = inputTimeScale; + const initSegment = MP4.initSegment([videoTrack]); + track = { + type: 'video', + container: 'video/mp4', + codec: videoTrack.config.codec, + initSegment, + }; + } + if (track) { + this.currentInitTrack = track; + const data = { track }; + this.observer.trigger(DemuxerEvent.FRAG_PARSING_INIT_SEGMENT, data); + } + else { + const payload = new FragParsingError(false, 'no audio/video samples found', ErrorResponses.NoAVSamplesFound); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + } + } + remuxVideo(track, timeOffset, contiguous, audioTrackLength, iframeDuration) { + let offset = 8; + let mp4SampleDuration; + let mdat; + let firstPTS; + let firstDTS; + let lastPTS; + let lastDTS; + let dropped = track.parsingData.dropped; + const dropFrames = !contiguous && this.config.forceKeyFrameOnDiscontinuity; + const inputSamples = track.parsingData.esSamples; + const timeScale = track.info.inputTimescale; + const outputSamples = []; + const encrypted = track.info.encrypted; + // PTS is coded on 33bits, and can loop from -2^32 to 2^32 + // normalizePts will make PTS/DTS value monotonic, we use last known DTS value as reference value + let nextAvcDts; + // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1) + if (contiguous) { + // if parsed fragment is contiguous with last one, let's use last DTS value as reference + nextAvcDts = this.nextAvcDts; + } + else { + // if not contiguous, let's use sample + nextAvcDts = normalizePts(inputSamples[0].dts, inputSamples[0].pts); + } + inputSamples.forEach(function (sample) { + sample.pts = normalizePts(sample.pts, nextAvcDts); + sample.dts = normalizePts(sample.dts, nextAvcDts); + }); + // sort video samples by DTS then PTS then demux id order + inputSamples.sort(function (a, b) { + const deltadts = a.dts - b.dts; + const deltapts = a.pts - b.pts; + return deltadts ? deltadts : deltapts ? deltapts : a.id - b.id; + }); + let firstKeyframePts; + const firstKeyframeIndex = inputSamples.findIndex((sample) => sample.key); + if (inputSamples[firstKeyframeIndex]) { + firstKeyframePts = inputSamples[firstKeyframeIndex].pts; + } + if (dropFrames) { + if (firstKeyframeIndex > 0) { + this.logger.warn(`Dropped ${firstKeyframeIndex} out of ${inputSamples.length} video samples due to a missing keyframe`); + inputSamples.splice(0, firstKeyframeIndex); + dropped += firstKeyframeIndex; + } + else if (firstKeyframeIndex === -1) { + this.logger.warn(`No keyframe found out of ${inputSamples.length} video samples`); + dropped += inputSamples.length; + } + } + const firstSample = inputSamples[0]; + const lastSample = inputSamples[inputSamples.length - 1]; + // handle broken streams with PTS < DTS, tolerance up 200ms (18000 in 90kHz timescale) + const PTSDTSshift = inputSamples.reduce((prev, curr) => Math.max(Math.min(prev, curr.pts - curr.dts), -18000), 0); + if (PTSDTSshift < 0) { + this.logger.warn(`PTS < DTS detected in video samples, shifting DTS by ${Math.round(PTSDTSshift / 90)} ms to overcome this issue`); + for (let i = 0; i < inputSamples.length; i++) { + inputSamples[i].dts += PTSDTSshift; + } + } + const isSafari = this.isSafari; + // on Safari let's signal the same sample duration for all samples + // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS + // set this constant duration as being the avg delta between consecutive DTS. + mp4SampleDuration = Math.round((lastSample.dts - firstSample.dts) / (inputSamples.length - 1)); + // compute first DTS/PTS, normalize them against reference value + firstDTS = Math.max(firstSample.dts, 0); + firstPTS = Math.max(firstSample.pts, 0); + if (isFiniteNumber(iframeDuration)) { + firstDTS = timeOffset * timeScale; + firstPTS = timeOffset * timeScale; + } + // if fragment are contiguous, detect hole/overlapping between fragments + if (contiguous) { + // check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole) + const delta = firstDTS - nextAvcDts; + const foundHole = delta > mp4SampleDuration; + const foundOverlap = delta < -1; + if (foundHole || foundOverlap) { + if (foundHole) { + this.logger.warn(`AVC: ${delta}/90000 hole between fragments detected`); + } + else { + this.logger.warn(`AVC: ${delta}/90000 overlapping between fragments detected`); + } + } + } + let nbNalu = 0; + let naluLen = 0; + const nbSamples = inputSamples.length; + for (let i = 0; i < nbSamples; i++) { + // compute total/avc sample length and nb of NAL units + const sample = inputSamples[i], units = sample.units, nbUnits = units.length; + let sampleLen = 0; + for (let j = 0; j < nbUnits; j++) { + sampleLen += units[j].data.length; + } + naluLen += sampleLen; + nbNalu += nbUnits; + sample.length = sampleLen; + // normalize PTS/DTS + if (isSafari) { + // sample DTS is computed using a constant decoding offset (mp4SampleDuration) between samples + sample.dts = firstDTS + i * mp4SampleDuration; + } + else { + // ensure sample monotonic DTS + sample.dts = Math.max(sample.dts, firstDTS); + } + // ensure that computed value is greater or equal than sample DTS + sample.pts = Math.max(sample.pts, sample.dts); + } + // compute lastPTS/lastDTS + lastDTS = Math.max(lastSample.dts, 0); + lastPTS = Math.max(lastSample.pts, 0, lastDTS); + if (isFiniteNumber(iframeDuration)) { + lastDTS = timeOffset * timeScale; + lastPTS = timeOffset * timeScale; + } + /* concatenate the video data and construct the mdat in place + (need 8 more bytes to fill length and mpdat type) */ + const mdatSize = naluLen + 4 * nbNalu + 8; + try { + mdat = new Uint8Array(mdatSize); + } + catch (err) { + const payload = new RemuxAllocError(false, `fail allocating video mdat ${mdatSize}`, ErrorResponses.FailedToAllocateVideoMdat, mdatSize); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return; + } + const view = new DataView(mdat.buffer); + view.setUint32(0, mdatSize); + mdat.set(MP4.types.mdat, 4); + for (let i = 0; i < nbSamples; i++) { + const avcSample = inputSamples[i], avcSampleUnits = avcSample.units; + let mp4SampleLength = 0, compositionTimeOffset; + // convert NALU bitstream to MP4 format (prepend NALU with size field) + const subsamples = []; + let bytesClear = 0; + for (let j = 0, nbUnits = avcSampleUnits.length; j < nbUnits; j++) { + const unit = avcSampleUnits[j], unitData = unit.data, unitDataLen = unit.data.byteLength; + view.setUint32(offset, unitDataLen); + offset += 4; + mdat.set(unitData, offset); + offset += unitDataLen; + mp4SampleLength += 4 + unitDataLen; + if (encrypted) { + if (unitDataLen <= 48 || (unit.type !== 1 && unit.type !== 5)) { + bytesClear += 4 + unitDataLen; + } + else { + let encryptedDataLen = unitDataLen - 32; + if (encryptedDataLen % 16 === 0) { + encryptedDataLen -= 16; // different than fMP4 encryption - TS always requires at least 1 clear byte at the end + } + subsamples.push([bytesClear + 36, encryptedDataLen]); + bytesClear = unitDataLen - 32 - encryptedDataLen; + } + } + } + if (bytesClear > 0) { + subsamples.push([bytesClear, 0]); + } + if (!isSafari) { + // expected sample duration is the Decoding Timestamp diff of consecutive samples + if (i < nbSamples - 1) { + mp4SampleDuration = inputSamples[i + 1].dts - avcSample.dts; + } + else { + const config = this.config, lastFrameDuration = avcSample.dts - inputSamples[i > 0 ? i - 1 : i].dts; + if (config.stretchShortVideoTrack) { + // In some cases, a segment's audio track duration may exceed the video track duration. + // Since we've already remuxed audio, and we know how long the audio track is, we look to + // see if the delta to the next segment is longer than the minimum of maxBufferHole and + // maxSeekHole. If so, playback would potentially get stuck, so we artificially inflate + // the duration of the last frame to minimize any potential gap between segments. + const maxBufferHole = config.maxBufferHole, maxSeekHole = config.maxSeekHole, gapTolerance = Math.floor(Math.min(maxBufferHole, maxSeekHole) * timeScale), deltaToFrameEnd = (audioTrackLength ? firstPTS + audioTrackLength * timeScale : this.nextAudioPts) - avcSample.pts; + if (deltaToFrameEnd > gapTolerance) { + // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video + // frame overlap. maxBufferHole/maxSeekHole should be >> lastFrameDuration anyway. + mp4SampleDuration = deltaToFrameEnd - lastFrameDuration; + if (mp4SampleDuration < 0) { + mp4SampleDuration = lastFrameDuration; + } + this.logger.info(`It is approximately ${deltaToFrameEnd / 90} ms to the next segment; using duration ${mp4SampleDuration / 90} ms for the last video frame.`); + } + else { + mp4SampleDuration = lastFrameDuration; + } + } + else { + mp4SampleDuration = lastFrameDuration; + } + } + compositionTimeOffset = Math.round(avcSample.pts - avcSample.dts); + } + else { + compositionTimeOffset = Math.max(0, mp4SampleDuration * Math.round((avcSample.pts - avcSample.dts) / mp4SampleDuration)); + } + if (isFiniteNumber(iframeDuration)) { + compositionTimeOffset = 0; + mp4SampleDuration = iframeDuration * timeScale; + } + outputSamples.push({ + size: mp4SampleLength, + // constant duration + duration: mp4SampleDuration, + cts: compositionTimeOffset, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: avcSample.key ? 2 : 1, + isNonSync: avcSample.key ? 0 : 1, + paddingValue: 0, + }, + keyTagInfo: avcSample.keyTagInfo, + subsamples: subsamples, + }); + } + // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale) + this.nextAvcDts = lastDTS + mp4SampleDuration; + this.isVideoContiguous = true; + if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { + const flags = outputSamples[0].flags; + // chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue + // https://code.google.com/p/chromium/issues/detail?id=229412 + flags.dependsOn = 2; + flags.isNonSync = 0; + } + const moofSegment = { + sequenceNumber: track.parsingData.sequenceNumber++, + id: track.info.id, + type: track.type, + encrypted: track.info.encrypted, + samples: outputSamples, + defaultPerSampleIVSize: 0, + }; + const moof = MP4.moof(firstDTS + this.config.audioPrimingDelay * timeScale, moofSegment); + track.parsingData.esSamples = []; + const fullSegment = new Uint8Array(moof.byteLength + mdat.byteLength); + fullSegment.set(moof); + fullSegment.set(mdat, moof.byteLength); + const type = 'video'; + const data = { + data1: fullSegment, + startPTS: convertSecondsToTimestamp(firstPTS / timeScale, timeScale), + endPTS: convertSecondsToTimestamp((lastPTS + mp4SampleDuration) / timeScale, timeScale), + startDTS: convertSecondsToTimestamp(firstDTS / timeScale, timeScale), + endDTS: convertSecondsToTimestamp(this.nextAvcDts / timeScale, timeScale), + type, + dropped, + framesWithoutIDR: firstKeyframeIndex, + firstKeyframePts: convertSecondsToTimestamp(firstKeyframePts / timeScale, timeScale), + }; + return data; + } + remuxAudio(track, timeOffset, contiguous, accurateTimeOffset, keyTagInfo) { + const inputTimeScale = track.info.inputTimescale, mp4timeScale = track.info.timescale, scaleFactor = inputTimeScale / mp4timeScale, mp4SampleDuration = track.config.segmentCodec === 'aac' ? 1024 : track.config.segmentCodec === 'mp3' ? 1152 : 1536, inputSampleDuration = mp4SampleDuration * scaleFactor, rawMPEG = track.config.segmentCodec === 'mp3' && this.typeSupported.mpeg, outputSamples = [], encrypted = track.info.encrypted, timeOffsetMpegTS = this._initPTS + timeOffset * inputTimeScale; + let view, offset = rawMPEG ? 0 : 8, audioSample, mp4Sample, unit, mdat, moof, firstPTS, firstDTS, lastDTS, pts, dts, fillFrame, newStamp, nextAudioPts; + const bu = new BitstreamUtils(); + const inputSamples = track.parsingData.esSamples; + // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs), + // for sake of clarity: + // consecutive fragments are frags with + // - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR + // - less than 20 audio frames distance + // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1) + // this helps ensuring audio continuity + // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame + nextAudioPts = this.nextAudioPts; + contiguous = + contiguous || + (inputSamples.length && + nextAudioPts && + ((accurateTimeOffset && Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000) || Math.abs(normalizePts(inputSamples[0].pts - nextAudioPts, timeOffsetMpegTS)) < 20 * inputSampleDuration)); + if (!contiguous) { + // if fragments are not contiguous, let's use sample + nextAudioPts = normalizePts(inputSamples[0].pts, this._initPTS); + } + // compute normalized PTS + inputSamples.forEach(function (sample) { + sample.pts = sample.dts = normalizePts(sample.pts, nextAudioPts); + }); + // If the audio track is missing samples, the frames seem to get "left-shifted" within the + // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment. + // In an effort to prevent this from happening, we inject frames here where there are gaps. + // When possible, we inject a silent frame; when that's not possible, we duplicate the last + // frame. + // only inject/drop audio frames in case time offset is accurate + if (accurateTimeOffset && track.config.segmentCodec === 'aac') { + for (let i = 0, nextPts = nextAudioPts; i < inputSamples.length;) { + // First, let's see how far off this frame is from where we expect it to be + const sample = inputSamples[i]; + pts = sample.pts; + const delta = pts - nextPts; + const duration = Math.abs((1000 * delta) / inputTimeScale); + // If we're overlapping by more than a duration, drop this sample + if (delta <= -inputSampleDuration) { + this.logger.warn(`Dropping 1 audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${duration} ms overlap.`); + inputSamples.splice(i, 1); + track.parsingData.len -= sample.unit.length; + // Don't touch nextPtsNorm or i + // Insert missing frames if: + // 1: We're more than one frame away + // 2: Not more than MAX_SILENT_FRAME_DURATION away + // 3: currentTime (aka nextPtsNorm) is not 0 + } + else if (delta >= inputSampleDuration && duration < MAX_SILENT_FRAME_DURATION && nextPts) { + const missing = Math.round(delta / inputSampleDuration); + this.logger.warn(`Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round((1000 * delta) / inputTimeScale)} ms gap.`); + for (let j = 0; j < missing; j++) { + newStamp = Math.max(nextPts, 0); + fillFrame = getSilentFrame(track.config.codec, track.config.channelCount); + if (!fillFrame) { + this.logger.warn('Unable to get silent frame for given audio codec; duplicating last frame instead.'); + fillFrame = sample.unit.subarray(0); + } + inputSamples.splice(i, 0, { unit: fillFrame, pts: newStamp, dts: newStamp, keyTagInfo: keyTagInfo }); + track.parsingData.len += fillFrame.length; + nextPts += inputSampleDuration; + i += 1; + } + // Adjust sample to next expected pts + sample.pts = sample.dts = nextPts; + nextPts += inputSampleDuration; + i += 1; + // Otherwise, just adjust pts + } + else { + nextPts += inputSampleDuration; + if (i === 0) { + sample.pts = sample.dts = nextAudioPts; + } + else { + sample.pts = sample.dts = inputSamples[i - 1].pts + inputSampleDuration; + } + i += 1; + } + } + } + for (let j = 0, nbSamples = inputSamples.length; j < nbSamples; j++) { + audioSample = inputSamples[j]; + unit = audioSample.unit; + pts = audioSample.pts; + dts = audioSample.dts; + // if not first sample + if (lastDTS !== undefined) { + mp4Sample.duration = Math.round((dts - lastDTS) / scaleFactor); + } + else { + const delta = Math.round((1000 * (pts - nextAudioPts)) / inputTimeScale); + let numMissingFrames = 0; + // if fragment are contiguous, detect hole/overlapping between fragments + // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1) + if (contiguous && track.config.segmentCodec === 'aac') { + // log delta + if (delta) { + if (delta > 0 && delta < MAX_SILENT_FRAME_DURATION) { + numMissingFrames = Math.round((pts - nextAudioPts) / inputSampleDuration); + this.logger.info(`${delta} ms hole between AAC samples detected,filling it`); + if (numMissingFrames > 0) { + fillFrame = getSilentFrame(track.config.codec, track.config.channelCount); + if (!fillFrame) { + fillFrame = unit.subarray(0); + } + track.parsingData.len += numMissingFrames * fillFrame.length; + } + // if we have frame overlap, overlapping for more than half a frame duraion + } + else if (delta < -12) { + // drop overlapping audio frames... browser will deal with it + this.logger.info(`drop overlapping AAC sample, expected/parsed/delta:${(nextAudioPts / inputTimeScale).toFixed(3)}s/${(pts / inputTimeScale).toFixed(3)}s/${-delta}ms`); + track.parsingData.len -= unit.byteLength; + continue; + } + // set PTS/DTS to expected PTS/DTS + pts = dts = nextAudioPts; + } + } + // remember first PTS of our audioSamples, ensure value is positive + firstPTS = Math.max(0, pts); + firstDTS = Math.max(0, dts); + if (track.parsingData.len > 0) { + /* concatenate the audio data and construct the mdat in place + (need 8 more bytes to fill length and mdat type) */ + const mdatSize = rawMPEG ? track.parsingData.len : track.parsingData.len + 8; + try { + mdat = new Uint8Array(mdatSize); + } + catch (err) { + const payload = new RemuxAllocError(false, `fail allocating audio mdat ${mdatSize}`, ErrorResponses.FailedToAllocateAudioMdat, mdatSize); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return; + } + if (!rawMPEG) { + view = new DataView(mdat.buffer); + view.setUint32(0, mdatSize); + mdat.set(MP4.types.mdat, 4); + } + } + else { + // no audio samples + return; + } + for (let i = 0; i < numMissingFrames; i++) { + newStamp = pts - (numMissingFrames - i) * inputSampleDuration; + fillFrame = getSilentFrame(track.config.codec, track.config.channelCount); + if (!fillFrame) { + this.logger.warn('Unable to get silent frame for given audio codec; duplicating this frame instead.'); + fillFrame = unit.subarray(0); + } + mdat.set(fillFrame, offset); + offset += fillFrame.byteLength; + mp4Sample = { + size: fillFrame.byteLength, + cts: 0, + duration: 1024, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 1, + paddingValue: 0, + isNonSync: 0, + }, + keyTagInfo: audioSample.keyTagInfo, + subsamples: encrypted ? [[fillFrame.byteLength, 0]] : [], + }; + outputSamples.push(mp4Sample); + } + } + mdat.set(unit, offset); + const unitLen = unit.byteLength; + offset += unitLen; + const subsamples = []; + if (encrypted) { + if (track.config.segmentCodec === 'ec3') { + let bytesSeen = 0; + // for ec3, a protected block is a single sync frame; the sample may have one or more sync frames + while (bytesSeen < unit.byteLength) { + const frameLength = (bu.bsReadAndUpdate(unit, { byteOffset: bytesSeen + 2, usedBits: 5 }, 11) + 1) * 2; + bytesSeen += frameLength; + const clearBytes = Math.min(frameLength, 16); // 16 bytes in the clear + subsamples.push([clearBytes, frameLength - clearBytes]); + } + } + else { + const clearBytes = Math.min(unitLen, 16); // both aac and ac3 have 16 bytes in the clear + subsamples.push([clearBytes, unitLen - clearBytes]); + } + } + mp4Sample = { + size: unitLen, + cts: 0, + duration: 0, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 1, + paddingValue: 0, + isNonSync: 0, + }, + keyTagInfo: audioSample.keyTagInfo, + subsamples: subsamples, + }; + outputSamples.push(mp4Sample); + lastDTS = dts; + } + let lastSampleDuration = 0; + const nbSamples = outputSamples.length; + // set last sample duration as being identical to previous sample + if (nbSamples >= 2) { + lastSampleDuration = outputSamples[nbSamples - 2].duration; + mp4Sample.duration = lastSampleDuration; + } + if (nbSamples) { + // next audio sample PTS should be equal to last sample PTS + duration + this.nextAudioPts = pts + scaleFactor * lastSampleDuration; + track.parsingData.len = 0; + if (rawMPEG) { + moof = new Uint8Array(); + } + else { + const moofSegment = { + sequenceNumber: track.parsingData.sequenceNumber++, + id: track.info.id, + type: track.type, + encrypted: track.info.encrypted, + samples: outputSamples, + defaultPerSampleIVSize: 0, + }; + moof = MP4.moof((firstDTS + this.config.audioPrimingDelay * inputTimeScale) / scaleFactor, moofSegment); + } + const fullSegment = new Uint8Array(moof.byteLength + mdat.byteLength); + fullSegment.set(moof); + fullSegment.set(mdat, moof.byteLength); + track.parsingData.esSamples = []; + const audioData = { + data1: fullSegment, + startPTS: convertSecondsToTimestamp(firstPTS / inputTimeScale, inputTimeScale), + endPTS: convertSecondsToTimestamp(this.nextAudioPts / inputTimeScale, inputTimeScale), + startDTS: convertSecondsToTimestamp(firstDTS / inputTimeScale, inputTimeScale), + endDTS: convertSecondsToTimestamp((dts + scaleFactor * lastSampleDuration) / inputTimeScale, inputTimeScale), + type: 'audio', + }; + return audioData; + } + return null; + } + remuxEmptyAudio(track, timeOffset, contiguous, accurateTimeOffset, videoData, keyTagInfo) { + const inputTimeScale = track.info.inputTimescale, mp4timeScale = track.config.samplerate ? track.config.samplerate : inputTimeScale, scaleFactor = inputTimeScale / mp4timeScale, nextAudioPts = this.nextAudioPts, + // sync with video's timestamp + startDTS = (nextAudioPts !== undefined ? nextAudioPts : convertTimestampToSeconds(videoData.startDTS) * inputTimeScale) + this._initDTS, endDTS = convertTimestampToSeconds(videoData.endDTS) * inputTimeScale + this._initDTS, + // one sample's duration value + sampleDuration = 1024, frameDuration = scaleFactor * sampleDuration, + // samples count of this segment's duration + nbSamples = Math.ceil((endDTS - startDTS) / frameDuration), + // silent frame + silentFrame = getSilentFrame(track.config.codec, track.config.channelCount); + this.logger.warn('remux empty Audio'); + // Can't remux if we can't generate a silent frame... + if (!silentFrame) { + this.logger.error('Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!'); + return null; + } + const samples = []; + for (let i = 0; i < nbSamples; i++) { + const stamp = startDTS + i * frameDuration; + samples.push({ unit: silentFrame, pts: stamp, dts: stamp, keyTagInfo: keyTagInfo }); + track.parsingData.len += silentFrame.length; + } + track.parsingData.esSamples = samples; + return this.remuxAudio(track, timeOffset, contiguous, accurateTimeOffset, keyTagInfo); + } + remuxID3(track, parsingData) { + const length = track.id3Samples.length; + let sample; + const inputTimeScale = track.inputTimescale; + // consume samples + if (length) { + for (let index = 0; index < length; index++) { + sample = track.id3Samples[index]; + // setting id3 pts, dts to relative time + sample.pts = sample.pts / inputTimeScale; + sample.dts = sample.dts / inputTimeScale; + } + parsingData.id3Samples = track.id3Samples; + } + track.id3Samples = []; + } + remuxText(track, parsingData) { + track.captionSamples.sort(function (a, b) { + return a.pts - b.pts; + }); + const length = track.captionSamples.length; + let sample; + const inputTimeScale = track.inputTimescale; + // consume samples + if (length) { + for (let index = 0; index < length; index++) { + sample = track.captionSamples[index]; + // setting text pts, dts to relative time + sample.pts = sample.pts / inputTimeScale; + } + if (!parsingData.captionData) { + parsingData.captionData = {}; + } + parsingData.captionData.ts = track.captionSamples; + } + track.captionSamples = []; + } + } + function normalizePts(value, reference) { + let offset; + if (reference === undefined) { + return value; + } + if (reference < value) { + // - 2^33 + offset = -8589934592; + } + else { + // + 2^33 + offset = 8589934592; + } + /* PTS is 33bit (from 0 to 2^33 -1) + if diff between value and reference is bigger than half of the amplitude (2^32) then it means that + PTS looping occured. fill the gap */ + while (Math.abs(value - reference) > 4294967296) { + value += offset; + } + return value; + } + function getVideoStartPts(videoSamples) { + const startPTS = videoSamples.reduce((minPTS, sample) => { + const delta = sample.pts - minPTS; + if (delta < -4294967296) { + // 2^32, see normalizePts for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation + return normalizePts(minPTS, sample.pts); + } + else if (delta > 0) { + return minPTS; + } + else { + return sample.pts; + } + }, videoSamples[0].pts); + return startPTS; + } + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function tryStringify (o) { + try { return JSON.stringify(o) } catch(e) { return '"[Circular]"' } + } + + var quickFormatUnescaped = format$1; + + function format$1(f, args, opts) { + var ss = (opts && opts.stringify) || tryStringify; + var offset = 1; + if (typeof f === 'object' && f !== null) { + var len = args.length + offset; + if (len === 1) return f + var objects = new Array(len); + objects[0] = ss(f); + for (var index = 1; index < len; index++) { + objects[index] = ss(args[index]); + } + return objects.join(' ') + } + if (typeof f !== 'string') { + return f + } + var argLen = args.length; + if (argLen === 0) return f + var str = ''; + var a = 1 - offset; + var lastPos = -1; + var flen = (f && f.length) || 0; + for (var i = 0; i < flen;) { + if (f.charCodeAt(i) === 37 && i + 1 < flen) { + lastPos = lastPos > -1 ? lastPos : 0; + switch (f.charCodeAt(i + 1)) { + case 100: // 'd' + if (a >= argLen) + break + if (lastPos < i) + str += f.slice(lastPos, i); + if (args[a] == null) break + str += Number(args[a]); + lastPos = i = i + 2; + break + case 79: // 'O' + case 111: // 'o' + case 106: // 'j' + if (a >= argLen) + break + if (lastPos < i) + str += f.slice(lastPos, i); + if (args[a] === undefined) break + var type = typeof args[a]; + if (type === 'string') { + str += '\'' + args[a] + '\''; + lastPos = i + 2; + i++; + break } - } - expandKey(e) { - var n = this.uint8ArrayToUint32Array_(e); - let t = !0 - , i = 0; - for (; i < n.length && t; ) - t = n[i] === this.key[i], - i++; - if (!t) { - this.key = n; - var s = this.keySize = n.length; - if (4 !== s && 6 !== s && 8 !== s) - throw new Error("Invalid aes key size=" + s); - var a = this.ksRows = 4 * (s + 6 + 1); - let e, t; - const o = this.keySchedule = new Uint32Array(a) - , d = this.invKeySchedule = new Uint32Array(a) - , l = this.sBox - , u = this["rcon"] - , c = this["invSubMix"] - , h = c[0] - , p = c[1] - , f = c[2] - , m = c[3]; - let i, r; - for (e = 0; e < a; e++) - e < s ? i = o[e] = n[e] : (r = i, - e % s == 0 ? (r = r << 8 | r >>> 24, - r = l[r >>> 24] << 24 | l[r >>> 16 & 255] << 16 | l[r >>> 8 & 255] << 8 | l[255 & r], - r ^= u[e / s | 0] << 24) : 6 < s && e % s == 4 && (r = l[r >>> 24] << 24 | l[r >>> 16 & 255] << 16 | l[r >>> 8 & 255] << 8 | l[255 & r]), - o[e] = i = (o[e - s] ^ r) >>> 0); - for (t = 0; t < a; t++) - e = a - t, - r = 3 & t ? o[e] : o[e - 4], - d[t] = t < 4 || e <= 4 ? r : h[l[r >>> 24]] ^ p[l[r >>> 16 & 255]] ^ f[l[r >>> 8 & 255]] ^ m[l[255 & r]], - d[t] = d[t] >>> 0 + if (type === 'function') { + str += args[a].name || ''; + lastPos = i + 2; + i++; + break } + str += ss(args[a]); + lastPos = i + 2; + i++; + break + case 115: // 's' + if (a >= argLen) + break + if (lastPos < i) + str += f.slice(lastPos, i); + str += String(args[a]); + lastPos = i + 2; + i++; + break + case 37: // '%' + if (lastPos < i) + str += f.slice(lastPos, i); + str += '%'; + lastPos = i + 2; + i++; + break } - networkToHostOrderSwap(e) { - return e << 24 | (65280 & e) << 8 | (16711680 & e) >> 8 | e >>> 24 - } - decrypt(e, t, i) { - var r = this.keySize + 6 - , n = this["invKeySchedule"] - , s = this.invSBox - , a = this["invSubMix"] - , o = a[0] - , d = a[1] - , l = a[2] - , u = a[3] - , i = this.uint8ArrayToUint32Array_(i); - let c = i[0] - , h = i[1] - , p = i[2] - , f = i[3]; - const m = new Int32Array(e) - , g = new Int32Array(m.length); - let y, v, S, b, T, E, I, w, A, O, k, C, D, M; - const P = this.networkToHostOrderSwap; - for (; t < m.length; ) { - for (A = P(m[t]), - O = P(m[t + 1]), - k = P(m[t + 2]), - C = P(m[t + 3]), - T = A ^ n[0], - E = C ^ n[1], - I = k ^ n[2], - w = O ^ n[3], - D = 4, - M = 1; M < r; M++) - y = o[T >>> 24] ^ d[E >> 16 & 255] ^ l[I >> 8 & 255] ^ u[255 & w] ^ n[D], - v = o[E >>> 24] ^ d[I >> 16 & 255] ^ l[w >> 8 & 255] ^ u[255 & T] ^ n[D + 1], - S = o[I >>> 24] ^ d[w >> 16 & 255] ^ l[T >> 8 & 255] ^ u[255 & E] ^ n[D + 2], - b = o[w >>> 24] ^ d[T >> 16 & 255] ^ l[E >> 8 & 255] ^ u[255 & I] ^ n[D + 3], - T = y, - E = v, - I = S, - w = b, - D += 4; - y = s[T >>> 24] << 24 ^ s[E >> 16 & 255] << 16 ^ s[I >> 8 & 255] << 8 ^ s[255 & w] ^ n[D], - v = s[E >>> 24] << 24 ^ s[I >> 16 & 255] << 16 ^ s[w >> 8 & 255] << 8 ^ s[255 & T] ^ n[D + 1], - S = s[I >>> 24] << 24 ^ s[w >> 16 & 255] << 16 ^ s[T >> 8 & 255] << 8 ^ s[255 & E] ^ n[D + 2], - b = s[w >>> 24] << 24 ^ s[T >> 16 & 255] << 16 ^ s[E >> 8 & 255] << 8 ^ s[255 & I] ^ n[D + 3], - D += 3, - g[t] = P(y ^ c), - g[t + 1] = P(b ^ h), - g[t + 2] = P(S ^ p), - g[t + 3] = P(v ^ f), - c = A, - h = O, - p = k, - f = C, - t += 4 - } - return g.buffer - } - destroy() { - this.key = void 0, - this.keySize = void 0, - this.ksRows = void 0, - this.sBox = void 0, - this.invSBox = void 0, - this.subMix = void 0, - this.invSubMix = void 0, - this.keySchedule = void 0, - this.invKeySchedule = void 0, - this.rcon = void 0 - } + ++a; + } + ++i; } - class i { - constructor(e, t) { - this.rpc = e, - this.logger = t, - this.decrypt = (r,n,s,a,o)=>t=>{ - const i = d.crypto; - if (null != o && o.useJSCrypto || null == i || !i.subtle) { - const s = new l; - var e; - s.expandKey(r); - const i = s.decrypt(a, 0, n); - e = o.plainTextLength ? i.slice(0, o.plainTextLength) : function(e) { - var t = new Uint8Array(e) - , i = t[e.byteLength - 1] - , r = e.byteLength - 1; - let n = 0; - if (1 <= i && i <= 16) - for (let e = r; e > r - i && t[e] === i; e--) - n++; - return e = n === i ? e.slice(0, r - i + 1) : e - }(i), - t(e, void 0, [e]) - } else - i.subtle.importKey("raw", r, s, !1, ["decrypt"]).then(e=>i.subtle.decrypt({ - name: s, - iv: n - }, e, a)).then(e=>{ - t(e, void 0, [e]) - } - ).catch(e=>t(void 0, e)) - } - , - e.register("decrypt", this.decrypt) - } + if (lastPos === -1) + return f + else if (lastPos < flen) { + str += f.slice(lastPos); } - (gr = x = x || {}).MEDIA_ATTACHING = "hlsMediaAttaching", - gr.MEDIA_ATTACHED = "hlsMediaAttached", - gr.MEDIA_DETACHING = "hlsMediaDetaching", - gr.MEDIA_DETACHED = "hlsMediaDetached", - gr.BUFFER_CREATED = "hlsBufferCreated", - gr.BUFFER_APPENDING = "hlsBufferAppending", - gr.BUFFER_APPENDED = "hlsBufferAppended", - gr.BUFFER_FLUSHED = "hlsBufferFlushed", - gr.MANIFEST_LOADING = "hlsManifestLoading", - gr.MANIFEST_LOADED = "hlsManifestLoaded", - gr.MANIFEST_PARSED = "hlsManifestParsed", - gr.LEVEL_SWITCHING = "hlsLevelSwitching", - gr.LEVEL_SWITCHED = "hlsLevelSwitched", - gr.LEVEL_LOADING = "hlsLevelLoading", - gr.LEVEL_LOADED = "hlsLevelLoaded", - gr.LEVEL_UPDATED = "hlsLevelUpdated", - gr.LEVELS_CHANGED = "hlsLevelsChanged", - gr.AUDIO_TRACKS_UPDATED = "hlsAudioTracksUpdated", - gr.AUDIO_TRACK_SWITCH = "hlsAudioTrackSwitch", - gr.AUDIO_TRACK_SWITCHED = "hlsAudioTrackSwitched", - gr.AUDIO_TRACK_LOADED = "hlsAudioTrackLoaded", - gr.SUBTITLE_TRACKS_UPDATED = "hlsSubtitleTracksUpdated", - gr.SUBTITLE_TRACKS_CREATED = "hlsSubtitleTracksCreated", - gr.SUBTITLE_TRACK_SWITCH = "hlsSubtitleTrackSwitch", - gr.INLINE_STYLES_PARSED = "hlsInlineStylesParsed", - gr.SESSION_DATA_COMPLETE = "hlsSessionDataComplete", - gr.FRAG_LOADING = "hlsFragLoading", - gr.FRAG_LOADED = "hlsFragLoaded", - gr.FRAG_BUFFERED = "hlsFragBuffered", - gr.FRAG_CHANGED = "hlsFragChanged", - gr.INTERNAL_ERROR = "hlsInternalError", - gr.ERROR = "hlsError", - gr.DESTROYING = "hlsDestroying", - gr.KEY_REQUEST_STARTED = "hlsKeyRequestStarted", - gr.LICENSE_CHALLENGE_CREATED = "hlsLicenseChallengeCreated", - gr.LICENSE_RELEASED = "hlsLicenseReleased", - gr.KEY_LOADED = "hlsKeyLoaded", - gr.UNRESOLVED_URI_LOADING = "hlsUnresolvedUriLoading", - gr.DESIRED_RATE_CHANGED = "hlsDesiredRateChanged", - gr.PLAYER_STATE_CHANGE = "hlsPlayerStateChange", - gr.SEEKING = "hlsSeeking", - gr.SEEKED = "hlsSeeked", - gr.STALLED = "hlsStalled", - gr.RESUME_FROM_STALL = "hlsResumeFromStall", - gr.READY_FOR_NEXT_ITEM = "hlsReadyForNextItem", - gr.ITEM_TRANSITIONED = "hlsItemTransitioned", - gr.ITEM_EVICTED = "hlsItemEvicted", - gr.DATERANGE_UPDATED = "hlsDaterangeUpdated"; - var v, P = x; - (dd = v = v || {}).FRAG_PARSING_INIT_SEGMENT = "hlsFragParsingInitSegment", - dd.FRAG_PARSING_DATA = "hlsFragParsingData", - dd.FRAG_PARSED = "hlsFragParsed", - dd.INIT_PTS_FOUND = "hlsInitPtsFound"; - class p extends Error { - constructor(e, t, i, r, n) { - super(r), - this.type = e, - this.details = t, - this.fatal = i, - this.reason = r, - this.response = n, - this.handled = !1 - } + + return str + } + + const format = quickFormatUnescaped; + + var browser = pino; + + const _console = pfGlobalThisOrFallback().console || {}; + const stdSerializers = { + mapHttpRequest: mock, + mapHttpResponse: mock, + wrapRequestSerializer: passthrough, + wrapResponseSerializer: passthrough, + wrapErrorSerializer: passthrough, + req: mock, + res: mock, + err: asErrValue + }; + + function shouldSerialize (serialize, serializers) { + if (Array.isArray(serialize)) { + const hasToFilter = serialize.filter(function (k) { + return k !== '!stdSerializers.err' + }); + return hasToFilter + } else if (serialize === true) { + return Object.keys(serializers) } - class R extends p { - constructor(e, t, i, r, n) { - super(e, t, i, r, n), - this.response = n - } + + return false + } + + function pino (opts) { + opts = opts || {}; + opts.browser = opts.browser || {}; + + const transmit = opts.browser.transmit; + if (transmit && typeof transmit.send !== 'function') { throw Error('pino: transmit option must have a send function') } + + const proto = opts.browser.write || _console; + if (opts.browser.write) opts.browser.asObject = true; + const serializers = opts.serializers || {}; + const serialize = shouldSerialize(opts.browser.serialize, serializers); + let stdErrSerialize = opts.browser.serialize; + + if ( + Array.isArray(opts.browser.serialize) && + opts.browser.serialize.indexOf('!stdSerializers.err') > -1 + ) stdErrSerialize = false; + + const levels = ['error', 'fatal', 'warn', 'info', 'debug', 'trace']; + + if (typeof proto === 'function') { + proto.error = proto.fatal = proto.warn = + proto.info = proto.debug = proto.trace = proto; } - const $ = { - PlaylistNotReceived: { - code: -12884, - text: "Playlist not received" - }, - CryptResponseReceivedSlowly: { - code: -16833, - text: "Crypt key received slowly" - }, - LivePlaylistUpdateError: { - code: -12888, - text: "Live playlist not updated" - }, - NoResponseFromMediaRequest: { - code: -12889, - text: "No response for fragment" - }, - IncompatibleAsset: { - code: -12927, - text: "IncompatibleAsset" - }, - CorruptStream: { - code: -16041, - text: "Corrupt fragment" - }, - InternalError: { - code: -12645, - text: "InternalException" - }, - CantSwitchInTime: { - code: -12644, - text: "CantSwitchInTime" - }, - VideoDecoderBadDataErr: { - code: -12909, - text: "Buffer error" - }, - InsufficientDataAvailable: { - code: -12928, - text: "Incomplete data" - }, - AllocationFailed: { - code: -12862, - text: "AllocationFailed" - }, - PlaylistErrorMissingEXTM3U: { - code: -12269, - text: "Response doesnt have #EXTM3U tag" - }, - PlaylistErrorInvalidEntry: { - code: -12264, - text: "Invalid entry" - }, - PlaylistErrorBadTargetDuration: { - code: -12271, - text: "Invalid targetduration" - }, - NoValidAlternates: { - code: -12925, - text: "No valid alternates" - }, - FormatError: { - code: -12642, - text: "Incorrect playlist format" - }, - UnsupportedKeySystemError: { - code: -6e4, - text: "Unsupported Key System" - }, - EmptyLoadSourceError: { - code: -60001, - text: "Empty loadSource url" - }, - UndefinedItemIdError: { - code: -60002, - text: "Undefined itemId" - }, - ManifestParseError: { - code: -60003, - text: "Manifest parse error" - }, - DemuxWorkerError: { - code: -60004, - text: "Demux worker error" - }, - DecryptWorkerError: { - code: -60005, - text: "Decrypt worker error" - }, - OutOfRangeSeekError: { - code: -60006, - text: "Seeked out of playable range" - }, - ExceptionInKeyLoadError: { - code: -60007, - text: "Exception in Key load" - }, - FragmentAbortError: { - code: -60008, - text: "Fragment abort error" - }, - ManifestTimeoutError: { - code: -60009, - text: "Manifest Timeout Error" - }, - PlaylistTimeoutError: { - code: -60010, - text: "Playlist Timeout Error" - }, - FragmentTimeoutError: { - code: -60011, - text: "Fragment Timeout Error" - }, - IncompleteSessionData: { - code: -60012, - text: "Session data not complete after loading all items" - }, - SessionDataLoadTimeout: { - code: -60013, - text: "Session data load timeout" - }, - FailedDemuxerSanityCheck: { - code: -60014, - text: "Failed demuxer sanity check" - }, - InvalidADTSSamplingIndex: { - code: -60015, - text: "Invalid ADTS sampling index" - }, - DemuxerNotFound: { - code: -60016, - text: "No demux matching with content found" - }, - InvalidAC3Magic: { - code: -60029, - text: "Invalid ac-3 magic" - }, - InvalidInitTimestamp: { - code: -60017, - text: "Invalid initPTS or initDTS" - }, - NoAVSamplesFound: { - code: -60018, - text: "no audio/video samples found" - }, - NoTSSyncByteFound: { - code: -60019, - text: "TS packet did not start with 0x47" - }, - PESDidNotStartWithADTS: { - code: -60020, - text: "AAC PES did not start with ADTS header" - }, - NoADTSHeaderInPES: { - code: -60021, - text: "No ADTS header found in AAC PES" - }, - InvalidDolbyAudioMagic: { - code: -60022, - text: "Invalid dolby audio magic" - }, - FailedToAllocateVideoMdat: { - code: -60023, - text: "Fail allocating video mdat" - }, - FailedToAllocateAudioMdat: { - code: -60024, - text: "Fail allocating audio mdat" - }, - InsufficientEC3Data: { - code: -60025, - text: "Error parsing ec-3, not enough data" - }, - InvalidEC3Magic: { - code: -60026, - text: "Invalid ec-3 magic" - }, - ReservedStreamType: { - code: -60027, - text: "Reserved stream type" - }, - InsufficientAC3Data: { - code: -60028, - text: "error parsing ac-3, not enough data" - }, - InvalidAC3SamplingRateCode: { - code: -60030, - text: "Invalid ac-3 samplingRateCode" - }, - PlaylistErrorInvalidEXTXDEFINE: { - code: -61e3, - text: "Encountered undefined/not imported EXT-X-DEFINE property" - }, - PlaylistErrorMissingImportReference: { - code: -61001, - text: "IMPORT references variable not in master playlist and/or NAME" - }, - PlaylistErrorInvalidSERVERURI: { - code: -61002, - text: "Encountered undefined/invalid SERVER-URI attribute for EXT-X-CONTENT-STEERING tag" - }, - PlaylistErrorInvalidPATHWAYID: { - code: -61003, - text: "Encountered invalid PATHWAY-ID attribute for EXT-X-CONTENT-STEERING tag" - }, - PlaylistErrorInvalidSCORE: { - code: -61004, - text: "Encountered negative/non-number SCORE property" - }, - KeySystemFailedToUpdateSession: { - code: -62e3, - text: "KeySystem: Promise Rejected while updating session" - }, - KeySystemFailedToGenerateLicenseRenewal: { - code: -62001, - text: "KeySystem: Failed to generate license renewal" - }, - KeySystemFailedToGenerateLicenseRequest: { - code: -62002, - text: "KeySystem: Failed to generate license request" - }, - KeySystemAbort: { - code: -62003, - text: "KeySystem: Aborted" - }, - KeySystemUnexpectedStateTransition: { - code: -62004, - text: "KeySystem: Unexpected state transition" - }, - KeySystemUnexpectedState: { - code: -62005, - text: "KeySystem: Unexpected state" - }, - KeySystemCDMUnknownError: { - code: -62006, - text: "KeySystem: Unknown error from CDM" - }, - KeySystemRequestTimedOut: { - code: -62007, - text: "Key request timed out" - }, - KeySystemUnexpectedMETHOD: { - code: -62008, - text: "Unexpected METHOD attribute" - }, - KeySystemUnmatchedString: { - code: -62009, - text: "KeySystem: string does not match" - }, - KeySystemInternalError: { - code: -62010, - text: "KeySystem: internal-error" - }, - KeySystemOutputRestricted: { - code: -62011, - text: "KeySystem: output-restricted" - }, - KeySystemSetupError: { - code: -62012, - text: "KeySystem: setup error" - }, - KeySystemFailedToInitialize: { - code: -62013, - text: "KeySystem: could not initialize" - }, - KeySystemFailedToCreateSession: { - code: -62014, - text: "KeySystem: could not create session" - }, - KeySystemUndefinedNavigator: { - code: -62015, - text: "KeySystem: navigator undefined" - }, - KeySystemNoKeySystemsToTry: { - code: -62016, - text: "KeySystem: no key systems to try" - }, - KeySystemNoConstructor: { - code: -62017, - text: "KeySystem: No constructor" - }, - KeySystemNoKeySystemAccess: { - code: -62018, - text: "KeySystem: No KeySystemAccess" - }, - KeySystemCertificateLoadError: { - code: -62019, - text: "KeySystem: Certificate Load Error" - } - } - , o = "networkError" - , L = "mediaError" - , s = "otherError" - , _ = "manifestParsingError" - , f = "manifestIncompatibleCodecsError" - , N = "levelLoadError" - , n = "bufferAppendError" - , r = "internalException"; - class V extends p { - constructor(e, t, i) { - super(s, r, e, t, i) - } - } - class D extends p { - constructor(e, t, i) { - super(L, "fragParsingError", e, t, i) - } - } - class F extends p { - constructor(e, t, i, r) { - super("muxError", "remuxAllocError", e, t, i), - this.bytes = r - } - } - function S(e) { - return e.baseTime / e.timescale - } - function B(e, t) { - return { - baseTime: Math.floor(e * t), - timescale: t - } - } - function g(e, t) { - return S(e) < S(t) ? e : t - } - function y(e, t) { - return S(e) > S(t) ? e : t - } - function b(e, t) { - return S(e) - S(t) - } - var t = void 0 !== d.Buffer ? require("events").EventEmitter : class { - constructor() { - this.eventMap = {} - } - _on(e, t, i=!1) { - return null == this.eventMap[e] && (this.eventMap[e] = []), - i ? this.eventMap[e].splice(0, 0, t) : this.eventMap[e].push(t), - this - } - _off(e, t) { - return null != this.eventMap[e] && (this.eventMap[e] = this.eventMap[e].filter(e=>e.listener !== t.listener), - 0 === this.eventMap[e].length && delete this.eventMap[e]), - this - } - on(e, t) { - return this._on(e, { - listener: t, - once: !1 - }) - } - off(e, t) { - return this._off(e, { - listener: t - }) - } - addListener(e, t) { - return this.on(e, t) - } - once(e, t) { - return this._on(e, { - listener: t, - once: !0 - }) - } - removeListener(e, t) { - return this.off(e, t) - } - removeAllListeners(e) { - return delete this.eventMap[e], - this - } - setMaxListeners(e) { - return this - } - getMaxListeners() { - return 1 / 0 - } - listeners(e) { - return null == this.eventMap[e] ? [] : this.eventMap[e].map(e=>e.listener) - } - rawListeners(e) { - return this.listeners(e) - } - emit(e, ...t) { - if (null == this.eventMap[e]) - return !1; - let i = !1; - for (const r of this.eventMap[e]) { - try { - r.listener.apply(this, t) - } catch (e) {} - i = !0 - } - return i - } - listenerCount(e) { - return null == this.eventMap[e] ? 0 : this.eventMap[e].length - } - prependListener(e, t) { - return this._on(e, { - listener: t, - once: !1 - }, !0) - } - prependOnceListener(e, t) { - return this._on(e, { - listener: t, - once: !0 - }, !0) - } - eventNames() { - return Object.keys(this.eventMap) - } - } - ; - class a extends t { - trigger(e, t) { - this.emit(e, t) - } - } - function E(e, t, i, r, n) { - let s, a, o, d; - const l = navigator.userAgent.toLowerCase() - , u = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350]; - s = 1 + ((192 & t[i + 2]) >>> 6); - var c = (60 & t[i + 2]) >>> 2; - if (!(u.length - 1 < c)) - return o = (1 & t[i + 2]) << 2, - o |= (192 & t[i + 3]) >>> 6, - /firefox/i.test(l) ? 6 <= c ? (s = 5, - d = new Array(4), - a = c - 3) : (s = 2, - d = new Array(2)) : -1 !== l.indexOf("android") ? (s = 2, - d = new Array(2)) : (s = 5, - d = new Array(4), - a = r && (-1 !== r.indexOf("mp4a.40.29") || -1 !== r.indexOf("mp4a.40.5")) || !r && 6 <= c ? c - 3 : ((r && -1 !== r.indexOf("mp4a.40.2") || !r && 1 == o) && (s = 2, - d = new Array(2)), - c)), - d[0] = s << 3, - d[0] |= (14 & c) >> 1, - d[1] |= (1 & c) << 7, - d[1] |= o << 3, - 5 === s && (d[1] |= (14 & a) >> 1, - d[2] = (1 & a) << 7, - d[2] |= 8, - d[3] = 0), - { - esdsConfig: d, - samplerate: u[c], - channelCount: o, - segmentCodec: "aac", - codec: "mp4a.40." + s - }; - { - const t = new D(!0,`invalid ADTS sampling index:${c}`,$.InvalidADTSSamplingIndex); - e.trigger(P.INTERNAL_ERROR, t) - } - } - class u { - constructor(e, t, i, r, n) { - this.observer = e, - this.remuxer = t, - this.config = i, - this.typeSupported = r, - this.logger = n - } - static probe(e, t) { - throw new Error("Method not implemented") - } - resetTimeStamp(e) {} - resetInitSegment(e, t, i, r) {} - destroy() {} - } - class c extends u { - constructor(e, t, i, r, n) { - super(e, t, i, r, n), - this.observer = e, - this.remuxer = t, - this.config = i, - this.typeSupported = r, - this.logger = n, - this.esRemuxer = t - } - } - class h { - constructor(e, t, i) { - this.observer = e, - this.config = t, - this.logger = i - } - resetInitSegment() {} - resetTimeStamp(e) {} - destroy() {} - } - let m, I; - var w = { - strToUtf8array: e=>(m = m || new TextEncoder, - m.encode(e)), - utf8arrayToStr: e=>(I = I || new TextDecoder("utf-8"), - I.decode(e)) - } - , A = { - strToUtf8array(e) { - e = d.Buffer.from(e, "utf-8"); - return new Uint8Array(e.buffer,e.byteOffset,e.byteLength) - }, - utf8arrayToStr: e=>d.Buffer.from(e).toString("utf-8") + if (opts.enabled === false) opts.level = 'silent'; + const level = opts.level || 'info'; + const logger = Object.create(proto); + if (!logger.log) logger.log = noop$2; + + Object.defineProperty(logger, 'levelVal', { + get: getLevelVal + }); + Object.defineProperty(logger, 'level', { + get: getLevel, + set: setLevel + }); + + const setOpts = { + transmit, + serialize, + asObject: opts.browser.asObject, + levels, + timestamp: getTimeFunction(opts) }; - let O = { - strToUtf8array(e) { - const t = unescape(encodeURIComponent(e)) - , i = new Uint8Array(t.length); - for (let e = 0; e < t.length; e++) - i[e] = t.charCodeAt(e); - return i - }, - utf8arrayToStr: e=>String.fromCharCode.apply(null, Array.from(e)) - }; - "undefined" != typeof TextEncoder && "undefined" != typeof TextDecoder ? O = w : "function" == typeof (null === (pd = d.Buffer) || void 0 === pd ? void 0 : pd.from) && (O = A); - const k = { - name: "ID3" - }; - class C { - constructor(e, t) { - this.logger = t, - this._hasTimeStamp = !1, - this._audioType = null, - this._length = 0, - this._frames = []; - let i, r, n, s, a = 0; - for (; ; ) - if (n = C.readUTF(e, a, 3), - a += 3, - "ID3" === n) { - this._minor = e[a++], - this._revision = e[a++]; - const t = e[a++]; - if (128 & t && (this._unsynchronized = !0, - this.logger.error(k, "id3 tag is unsynchronized")), - 64 & t && (this._hasExtendedHeader = !0, - this.logger.warn(k, "id3 tag has extended header")), - i = C.readSynchSafeUint32(e.subarray(a, a + 4)), - a += 4, - r = a + i, - this._hasExtendedHeader) { - const t = C.readSynchSafeUint32(e.subarray(a, a + 4)); - this.logger.warn(k, `id3 tag has ${t}-byte extended header. usually 6 or 10 bytes`), - a += t - } - 2 < this.minor ? this._parseID3Frames(e, a, r) : this.logger.error(k, "[id3] doesn't support older than v2.3 tags"), - a = r - } else { - if ("3DI" !== n) - return a -= 3, - void ((s = a) && (this.hasTimeStamp || this.logger.warn(k, "ID3 tag found, but no timestamp"), - this._length = s, - this._payload = e.slice(0, s))); - a += 7 - } - } - static isHeader(e, t) { - return 73 === e[t] && 68 === e[t + 1] && 51 === e[t + 2] && e[t + 3] < 255 && e[t + 4] < 255 && e[t + 6] < 128 && e[t + 7] < 128 && e[t + 8] < 128 && e[t + 9] < 128 - } - static readSynchSafeUint32(e) { - return 2097152 * (127 & e[0]) + 16384 * (127 & e[1]) + 128 * (127 & e[2]) + (127 & e[3]) - } - static readUTF(e, t, i) { - let r = "" - , n = t; - for (var s = t + i; r += String.fromCharCode(e[n++]), - n < s; ) - ; - return r - } - isID3Frame(e, t) { - return e[t + 4] < 128 && e[t + 5] < 128 && e[t + 6] < 128 && e[t + 7] < 128 - } - decodeID3Frame(e) { - return "TXXX" === e.type ? this.decodeTxxxFrame(e) : "WXXX" === e.type ? this.decodeWxxxFrame(e) : "PRIV" === e.type ? this.decodePrivFrame(e) : "T" === e.type[0] ? this.decodeTextFrame(e) : { - key: e.type, - data: e.data - } - } - decodeTxxxFrame(e) { - if (!(e.size < 2) && 3 === e.data[0]) { - var t = 1 - , i = this.id3utf8ArrayToStr(e.data.subarray(1)); - return t += i.length + 1, - { - key: "TXXX", - description: i, - data: this.id3utf8ArrayToStr(e.data.subarray(t)) - } - } - } - decodeWxxxFrame(e) { - if (!(e.size < 2) && 3 === e.data[0]) { - var t = 1 - , i = this.id3utf8ArrayToStr(e.data.subarray(1)); - return t += i.length + 1, - { - key: "WXXX", - description: i, - data: O.utf8arrayToStr(e.data.subarray(t)) - } - } - } - decodeTextFrame(e) { - if (!(e.size < 2) && 3 === e.data[0]) { - var t = e.data.subarray(1); - return { - key: e.type, - data: this.id3utf8ArrayToStr(t) - } - } - } - decodePrivFrame(e) { - if (!(e.size < 2)) { - var t = this.id3utf8ArrayToStr(e.data); - return { - key: "PRIV", - info: t, - data: e.data.slice(t.length + 1) - } - } - } - _extractID3Frame(e, t, i, r, n) { - var s = r + i; - let a; - return s <= n ? a = { - type: t, - data: e.slice(r, s) - } : this.logger.error(k, `id3 frame ${t} size ${i} exceeded ${n}`), - a - } - _parseID3Frames(e, t, i) { - let r, n, s, a; - for (; t + 8 <= i; ) { - if (!this.isID3Frame(e, t)) - return void this.logger.error(k, `[id3] illegal id3 frame @ offset ${t}. skip this id3 tag`); - if (r = C.readUTF(e, t, 4), - t += 4, - "" === r) - return; - if (0 === (n = C.readSynchSafeUint32(e.subarray(t, t + 4)))) - return; - t += 4, - e[t++], - e[t++], - s = t; - var o = this._extractID3Frame(e, r, n, s, i); - if (o) { - const e = this.decodeID3Frame(o); - this._frames.push(e) - } - if ("PRIV" === r) - if (53 === n && "com.apple.streaming.transportStreamTimestamp" === C.readUTF(e, t, 44)) { - t += 44, - t += 4; - const i = 1 & e[t++]; - this._hasTimeStamp = !0, - a = ((e[t++] << 23) + (e[t++] << 15) + (e[t++] << 7) + e[t++]) / 45, - i && (a += 47721858.84), - a = Math.round(a), - this._timeStamp = a - } else - 45 <= n && "com.apple.streaming.audioDescription" === C.readUTF(e, t, 36) ? (t += 37, - this._audioType = C.readUTF(e, t, 4), - t += 4, - t += n - 41) : t += n; - else - t += n - } - } - id3utf8ArrayToStr(e) { - let t, i, r = "", n = 0; - const s = e.length; - for (; n < s; ) { - const s = e[n++]; - switch (s >> 4) { - case 0: - return r; - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - r += String.fromCharCode(s); - break; - case 12: - case 13: - t = e[n++], - r += String.fromCharCode((31 & s) << 6 | 63 & t); - break; - case 14: - t = e[n++], - i = e[n++], - r += String.fromCharCode((15 & s) << 12 | (63 & t) << 6 | (63 & i) << 0) - } - } - } - get hasTimeStamp() { - return this._hasTimeStamp - } - get timeStamp() { - return this._timeStamp - } - get audioType() { - return this._audioType - } - get length() { - return this._length - } - get payload() { - return this._payload - } - get frames() { - return this._frames - } - get minor() { - return this._minor - } - get revision() { - return this._revision - } + logger.levels = pino.levels; + logger.level = level; + + logger.setMaxListeners = logger.getMaxListeners = + logger.emit = logger.addListener = logger.on = + logger.prependListener = logger.once = + logger.prependOnceListener = logger.removeListener = + logger.removeAllListeners = logger.listeners = + logger.listenerCount = logger.eventNames = + logger.write = logger.flush = noop$2; + logger.serializers = serializers; + logger._serialize = serialize; + logger._stdErrSerialize = stdErrSerialize; + logger.child = child; + + if (transmit) logger._logEvent = createLogEventShape(); + + function getLevelVal () { + return this.level === 'silent' + ? Infinity + : this.levels.values[this.level] } - var M = C; - const U = { - name: "AACDemuxer" - }; - class K extends c { - resetInitSegment(e, t) { - this.audioConfig = void 0, - this.audioTrack = void 0, - this.duration = t - } - static probe(e, t) { - let i, r; - for (i = new M(e,t).length, - r = Math.min(e.length - 1, i + 100); i < r; i++) - if (255 === e[i] && 240 == (246 & e[i + 1])) - return !0; - return !1 - } - append(e, t, i, r, n) { - var s = new M(e,this.logger) - , a = s.hasTimeStamp ? 90 * s.timeStamp : 9e4 * t; - let o, d, l, u, c, h, p, f, m, g; - for (s.length && (g = s.payload, - s.frames.length && (m = s.frames), - f = { - id3Samples: [{ - pts: a, - dts: a, - data: g, - frames: m - }], - inputTimescale: 9e4 - }), - l = s.length, - h = e.length; l < h - 1 && (255 !== e[l] || 240 != (246 & e[l + 1])); l++) - ; - if (!this.audioConfig && (this.audioConfig = E(this.observer, e, l, void 0, this.logger), - !this.audioConfig)) - throw "failed to parse adts config"; - if (!this.audioTrack) { - const e = { - id: 258, - inputTimescale: 9e4, - timescale: NaN, - duration: this.duration, - encrypted: !1, - keyTagInfo: n - } - , t = { - len: 0, - sequenceNumber: 0, - esSamples: [] - }; - this.audioTrack = { - info: e, - parsingData: t, - type: "audio", - config: this.audioConfig - } - } - "zaac" !== s.audioType && "zach" !== s.audioType && "zacp" !== s.audioType || (this.audioTrack.info.encrypted = !0), - d = 0; - for (var y = 9216e4 / this.audioConfig.samplerate; l + 5 < h && (u = 1 & e[l + 1] ? 7 : 9, - o = (3 & e[l + 3]) << 11 | e[l + 4] << 3 | (224 & e[l + 5]) >>> 5, - o -= u, - 0 < o && l + u + o <= h); ) - for (c = a + d * y, - p = { - unit: e.subarray(l + u, l + u + o), - pts: c, - dts: c, - keyTagInfo: n - }, - this.audioTrack.parsingData.esSamples.push(p), - this.audioTrack.parsingData.len += o, - l += o + u, - d++; l < h - 1; l++) { - if (M.isHeader(e, l)) { - const t = new M(e.subarray(l),this.logger); - if (0 < t.length) { - l += t.length; - const e = t.hasTimeStamp ? 90 * t.timeStamp : a; - f.id3Samples.push({ - pts: e, - dts: e, - data: t.payload, - frames: t.frames - }) - } else - this.logger.error(U, `[id3] invalid length ${h}`) - } - if (255 === e[l] && 240 == (246 & e[l + 1])) - break - } - this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, f, void 0, t, i, r, n) - } + + function getLevel () { + return this._level } - class H { - bsReadAndUpdate(e, t, i) { - e = this.readBits(e, t, i); - return this.updateOffset(t, i), - e - } - bsWriteAndUpdate(e, t, i, r) { - r = this.writeBits(e, t, i, r); - return this.updateOffset(t, i), - r - } - bsSkip(e, t) { - this.updateOffset(e, t) - } - readBits(i, r, n) { - if (i && r) { - let t = r.byteOffset; - const s = r["usedBits"]; - if (!(8 <= s || 32 < s + n)) { - let e; - const a = new Uint32Array(1) - , o = new Uint32Array(1) - , d = new Uint8Array(1); - if (!(8 <= s || 32 < n)) { - if (s) { - const r = 8 - s - , a = n < r ? r - n : 0; - o[0] = 4278190080 >>> 32 - r, - e = (i[t] & o[0]) >>> a, - t += 1, - n -= r - } - for (; 0 < n; ) { - d[0] = i[t]; - const r = Math.min(n, 8) - , s = 8 - r; - o[0] = 4278190080 >>> 24 + s << s, - a[0] = (d[0] & o[0]) >> s, - e = e ? e << r | a[0] : a[0], - t += 1, - n -= r - } - return e - } - } - } - } - writeBits(t, i, r, n) { - if (t && i) { - let e = i.byteOffset; - var i = i["usedBits"]; - if (!(8 <= i || 32 < i + r)) { - const s = new Uint32Array(1) - , a = new Uint32Array(1) - , o = new Uint32Array(1) - , d = new Uint8Array(1); - for (s[0] = n, - i && (a[0] = s[0] << 32 - r, - o[0] = 4278190080, - d[0] = (a[0] & o[0]) >>> 24 + i, - t[e] &= ~(o[0] >>> 24 + i), - t[e] |= d[0], - e += 1, - r -= 8 - i); 0 < r; ) { - a[0] = s[0] << 32 - r, - o[0] = 4278190080, - d[0] = (a[0] & o[0]) >>> 24; - const l = r < 0 ? 8 - r : 0; - t[e] &= ~(o[0] >>> 24 >>> l << l), - t[e] |= d[0], - r -= 8, - e += 1 - } - return 0 - } - } - } - updateOffset(e, t) { - var i, r; - !e || !t || 32 < e.usedBits + t || (i = e.usedBits % 8, - r = Math.floor((i + t) / 8), - t = (i + t) % 8, - e.byteOffset += r, - e.usedBits = t) - } + function setLevel (level) { + if (level !== 'silent' && !this.levels.values[level]) { + throw Error('unknown level ' + level) + } + this._level = level; + + set$1(setOpts, logger, 'error', 'log'); // <-- must stay first + set$1(setOpts, logger, 'fatal', 'error'); + set$1(setOpts, logger, 'warn', 'error'); + set$1(setOpts, logger, 'info', 'log'); + set$1(setOpts, logger, 'debug', 'log'); + set$1(setOpts, logger, 'trace', 'log'); } - function j(e, t) { - return 1536 / e.samplerate * t + + function child (bindings) { + if (!bindings) { + throw new Error('missing bindings for child Pino') + } + const bindingsSerializers = bindings.serializers; + if (serialize && bindingsSerializers) { + var childSerializers = Object.assign({}, serializers, bindingsSerializers); + var childSerialize = opts.browser.serialize === true + ? Object.keys(childSerializers) + : serialize; + delete bindings.serializers; + applySerializers([bindings], childSerialize, childSerializers, this._stdErrSerialize); + } + function Child (parent) { + this._childLevel = (parent._childLevel | 0) + 1; + this.error = bind(parent, bindings, 'error'); + this.fatal = bind(parent, bindings, 'fatal'); + this.warn = bind(parent, bindings, 'warn'); + this.info = bind(parent, bindings, 'info'); + this.debug = bind(parent, bindings, 'debug'); + this.trace = bind(parent, bindings, 'trace'); + if (childSerializers) { + this.serializers = childSerializers; + this._serialize = childSerialize; + } + if (transmit) { + this._logEvent = createLogEventShape( + [].concat(parent._logEvent.bindings, bindings) + ); + } + } + Child.prototype = this; + return new Child(this) } - function q(e, t, i, r) { - let n; - if (i + 8 > t.length) - return n = new D(!0,"error parsing ac-3, not enough data",$.InsufficientAC3Data), - void e.trigger(P.INTERNAL_ERROR, n); - if (11 !== t[i] || 119 !== t[i + 1]) - return n = new D(!0,"invalid ac-3 magic",$.InvalidAC3Magic), - void e.trigger(P.INTERNAL_ERROR, n); - var s = t[i + 4] >> 6; - if (3 <= s) - return n = new D(!0,`invalid ac-3 samplingRateCode:${s}`,$.InvalidAC3SamplingRateCode), - void e.trigger(P.INTERNAL_ERROR, n); - var a = 63 & t[i + 4] - , o = t[i + 6] >> 5; - let d = 0; - 2 == o ? d += 2 : (1 & o && 1 != o && (d += 2), - 4 & o && (d += 2)); - var l = (t[i + 6] << 8 | t[i + 7]) >> 12 - d & 1 - , u = [2, 1, 2, 3, 3, 4, 4, 5][o] + l - , e = t[i + 5] >> 3 - , i = 7 & t[i + 5]; - return { - samplerate: G[s], - channelCount: u, - segmentCodec: "ac3", - codec: "ac-3", - extraData: s << 22 | e << 17 | i << 14 | o << 11 | l << 10 | a >> 1 << 5 - } - } - function Q(e, t, i) { - let r; - if (i + 8 > t.length) - return r = new D(!0,"error parsing ac-3, not enough data",$.InsufficientAC3Data), - void e.trigger(P.INTERNAL_ERROR, r); - if (11 !== t[i] || 119 !== t[i + 1]) - return r = new D(!0,"invalid ac-3 magic",$.InvalidAC3Magic), - void e.trigger(P.INTERNAL_ERROR, r); - var n = t[i + 4] >> 6; - return 3 <= n ? (r = new D(!0,`invalid ac-3 samplingRateCode:${n}`,$.InvalidAC3SamplingRateCode), - void e.trigger(P.INTERNAL_ERROR, r)) : (i = 63 & t[i + 4], - 2 * W[3 * i + n]) - } - const G = [48e3, 44100, 32e3] - , W = [64, 69, 96, 64, 70, 96, 80, 87, 120, 80, 88, 120, 96, 104, 144, 96, 105, 144, 112, 121, 168, 112, 122, 168, 128, 139, 192, 128, 140, 192, 160, 174, 240, 160, 175, 240, 192, 208, 288, 192, 209, 288, 224, 243, 336, 224, 244, 336, 256, 278, 384, 256, 279, 384, 320, 348, 480, 320, 349, 480, 384, 417, 576, 384, 418, 576, 448, 487, 672, 448, 488, 672, 512, 557, 768, 512, 558, 768, 640, 696, 960, 640, 697, 960, 768, 835, 1152, 768, 836, 1152, 896, 975, 1344, 896, 976, 1344, 1024, 1114, 1536, 1024, 1115, 1536, 1152, 1253, 1728, 1152, 1254, 1728, 1280, 1393, 1920, 1280, 1394, 1920]; - class z extends c { - resetInitSegment(e, t) { - this.audioConfig = void 0, - this.audioTrack = void 0, - this.duration = t - } - static probe(e, t) { - var i = new M(e,t) - , t = i.length; - return !!(i.hasTimeStamp && 11 === e[t] && 119 === e[t + 1] && (new H).bsReadAndUpdate(e, { - byteOffset: t + 5, - usedBits: 0 - }, 5) < 16) - } - append(e, t, i, r, n) { - var s = new M(e,this.logger) - , a = 90 * s.timeStamp - , o = e.byteLength; - let d = 0 - , l = s.length; - if (this.audioConfig || (this.audioConfig = q(this.observer, e, l, this.logger)), - !this.audioConfig) - throw "failed to parse ac3 config"; - if (!this.audioTrack) { - const e = { - id: 258, - inputTimescale: 9e4, - timescale: NaN, - duration: this.duration, - encrypted: !1, - keyTagInfo: n - } - , t = { - len: 0, - sequenceNumber: 0, - esSamples: [] - }; - this.audioTrack = { - info: e, - parsingData: t, - type: "audio", - config: this.audioConfig - } - } - var u = j(this.audioConfig, this.audioTrack.info.inputTimescale); - for ("zac3" === s.audioType && (this.audioTrack.info.encrypted = !0); l < o; ) { - if (M.isHeader(e, l) && (l += new M(e.subarray(l),this.logger).length), - 11 !== e[l] || 119 !== e[l + 1]) { - const e = new D(!0,"invalid ac-3 magic",$.InvalidAC3Magic); - return void this.observer.trigger(P.INTERNAL_ERROR, e) - } - const t = Q(this.observer, e, l) - , i = a + d * u - , r = { - unit: e.subarray(l, l + t), - pts: i, - dts: i, - keyTagInfo: n - }; - this.audioTrack.parsingData.esSamples.push(r), - this.audioTrack.parsingData.len += t, - l += t, - d++ - } - this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, { - id3Samples: [{ - pts: a, - dts: a, - data: s.payload, - frames: s.frames - }], - inputTimescale: this.audioTrack.info.inputTimescale - }, void 0, t, i, r, n) - } - } - var X = function(t, i, r, n) { - const s = new H; - let a, o = !1, d = 0; - for (; r < i.length; ) { - if (r + 8 > i.length) - return a = new D(!0,"error parsing ec-3, not enough data",$.InsufficientEC3Data), - void t.trigger(P.INTERNAL_ERROR, a); - let e = 0; - if (M.isHeader(i, r) && (e = new M(i.subarray(r),n).length || 0, - r += e), - 11 !== i[r] || 119 !== i[r + 1]) - return a = new D(!0,"invalid ec-3 magic",$.InvalidEC3Magic), - void t.trigger(P.INTERNAL_ERROR, a); - var l = { - byteOffset: r + 2, - usedBits: 0 - } - , u = s.bsReadAndUpdate(i, l, 2) - , c = s.bsReadAndUpdate(i, l, 3); - if (0 === u || 2 === u) - if (!0 === o) { - if (0 === c) - break - } else - o = !0; - else if (1 !== u) - return a = new D(!0,"reserved stream type",$.ReservedStreamType), - void t.trigger(P.INTERNAL_ERROR, a); - l = 2 * (s.bsReadAndUpdate(i, l, 11) + 1); - r += l, - d += l + (e || 0) - } - return d - } - , Y = function(t, i, r, n) { - const s = { - frmsiz: 0, - fscod: 0, - numblkscod: 0, - acmod: 0, - lfeon: 0, - bsid: 0, - strmtyp: 0, - substreamid: 0, - chanmape: 0, - chanmap: 0, - mixdef: 0, - mixdeflen: 0, - bsmod: 0 - } - , a = { - fscod: 0, - acmod: 0, - lfeon: 0, - bsid: 0, - bsmod: 0, - chan_loc: 0, - data_rate: 0, - num_ind_sub: 0, - num_dep_sub: [], - complexity_index_type_a: 0 - } - , o = new H; - let d, l = !1, u = 0; - for (; r < i.length; ) { - if (r + 8 > i.length) - return d = new D(!0,"error parsing ec-3, not enough data",$.InsufficientEC3Data), - void t.trigger(P.INTERNAL_ERROR, d); - let e = 0; - if (M.isHeader(i, r) && (e = new M(i.subarray(r),n).length || 0, - r += e), - 11 !== i[r] || 119 !== i[r + 1]) - return d = new D(!0,"invalid ec-3 magic",$.InvalidEC3Magic), - void t.trigger(P.INTERNAL_ERROR, d); - const h = { - byteOffset: r + 2, - usedBits: 0 - }; - if (s.strmtyp = o.bsReadAndUpdate(i, h, 2), - s.substreamid = o.bsReadAndUpdate(i, h, 3), - 0 === s.strmtyp || 2 === s.strmtyp) { - if (!0 === l) { - if (0 === s.substreamid) - break - } else - l = !0; - a.num_ind_sub++, - a.num_dep_sub.push(0) - } else { - if (1 !== s.strmtyp) - return d = new D(!0,"reserved stream type",$.ReservedStreamType), - void t.trigger(P.INTERNAL_ERROR, d); - a.num_dep_sub[a.num_ind_sub - 1]++ - } - if (s.frmsiz = o.bsReadAndUpdate(i, h, 11), - s.fscod = o.bsReadAndUpdate(i, h, 2), - 3 === s.fscod ? (o.bsSkip(h, 2), - s.numblkscod = 3) : s.numblkscod = o.bsReadAndUpdate(i, h, 2), - s.acmod = o.bsReadAndUpdate(i, h, 3), - s.lfeon = o.bsReadAndUpdate(i, h, 1), - s.bsid = o.bsReadAndUpdate(i, h, 5), - o.bsSkip(h, 5), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8), - 0 === s.acmod && (o.bsSkip(h, 5), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8)), - 1 === s.strmtyp && (s.chanmape = o.bsReadAndUpdate(i, h, 1), - s.chanmape && (s.chanmap = o.bsReadAndUpdate(i, h, 16))), - o.bsReadAndUpdate(i, h, 1) && (2 < s.acmod && o.bsSkip(h, 2), - 1 & s.acmod && 2 < s.acmod && o.bsSkip(h, 6), - 4 & s.acmod && o.bsSkip(h, 6), - s.lfeon && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 5), - 0 === s.strmtyp)) { - if (o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 6), - 0 === s.acmod && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 6), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 6), - s.mixdef = o.bsReadAndUpdate(i, h, 2), - 1 === s.mixdef) - o.bsSkip(h, 5); - else if (2 === s.mixdef) - o.bsSkip(h, 12); - else if (3 === s.mixdef) { - s.mixdeflen = o.bsReadAndUpdate(i, h, 5), - o.bsReadAndUpdate(i, h, 1) && (o.bsSkip(h, 5), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && (o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 4))), - o.bsReadAndUpdate(i, h, 1) && (o.bsSkip(h, 5), - o.bsReadAndUpdate(i, h, 1) && (o.bsSkip(h, 7), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8))); - const t = s.mixdeflen + 2 + (h.usedBits ? 1 : 0); - h.byteOffset += t - } - if (s.acmod < 2 && (o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 14), - 0 === s.acmod && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 14)), - o.bsReadAndUpdate(i, h, 1)) - if (0 === s.numblkscod) - o.bsSkip(h, 5); - else - for (let e = 0; e < s.numblkscod; e++) - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 5) - } - if (s.bsmod = 0, - o.bsReadAndUpdate(i, h, 1) && (s.bsmod = o.bsReadAndUpdate(i, h, 3), - o.bsSkip(h, 2), - 2 === s.acmod && o.bsSkip(h, 4), - 6 <= s.acmod && o.bsSkip(h, 2), - o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8), - 0 === s.acmod && o.bsReadAndUpdate(i, h, 1) && o.bsSkip(h, 8), - s.fscod < 3 && o.bsSkip(h, 1)), - 0 === s.strmtyp && 3 !== s.numblkscod && o.bsSkip(h, 1), - 2 !== s.strmtyp || (3 === s.numblkscod ? 1 : o.bsReadAndUpdate(i, h, 1)) && o.bsReadAndUpdate(i, h, 6), - o.bsReadAndUpdate(i, h, 1)) { - const t = o.bsReadAndUpdate(i, h, 6); - if (0 === s.strmtyp && 0 === s.substreamid && 1 === t) { - const t = o.bsReadAndUpdate(i, h, 7) - , r = o.bsReadAndUpdate(i, h, 1) - , n = o.bsReadAndUpdate(i, h, 8); - 0 === t && 1 === r && 1 <= n && n <= 16 && (a.complexity_index_type_a = n) - } - } - if (s.chanmape) - a.chan_loc |= s.chanmap; - else { - const t = [40960, 16384, 40960, 57344, 41472, 57856, 47104, 63488]; - a.chan_loc |= t[s.acmod] - } - 0 === s.strmtyp && (a.fscod = s.fscod, - a.bsid = s.bsid, - a.bsmod = s.bsmod, - a.acmod = s.acmod, - a.lfeon = s.lfeon), - a.chan_loc |= s.lfeon ? 1 : 0; - const p = 2 * (s.frmsiz + 1); - r += p, - u += p + (e || 0) - } - let c = 0; - for (let e = 0; e < 16; e++) - a.chan_loc & 1 << e && c++; - a.lfeon && c++; - let h = 10 + 3 * a.num_ind_sub; - const p = [48e3, 44100, 32e3][a.fscod]; - a.data_rate = p / 1536 * u * 8, - h = 10 + 3 * a.num_ind_sub; - for (let e = 0; e < a.num_ind_sub; e++) - 0 < a.num_dep_sub[e] && h++; - 0 < a.complexity_index_type_a && (h += 2); - var f = new Uint8Array(h) - , m = { - byteOffset: 0, - usedBits: 0 - }; - o.bsWriteAndUpdate(f, m, 32, h), - o.bsWriteAndUpdate(f, m, 32, 1684366131), - o.bsWriteAndUpdate(f, m, 13, a.data_rate), - o.bsWriteAndUpdate(f, m, 3, a.num_ind_sub); - for (let e = 0; e < a.num_ind_sub; e++) - o.bsWriteAndUpdate(f, m, 2, a.fscod), - o.bsWriteAndUpdate(f, m, 5, a.bsid), - o.bsWriteAndUpdate(f, m, 1, 0), - o.bsWriteAndUpdate(f, m, 1, 0 === e ? 0 : 1), - o.bsWriteAndUpdate(f, m, 3, a.bsmod), - o.bsWriteAndUpdate(f, m, 3, a.acmod), - o.bsWriteAndUpdate(f, m, 1, a.lfeon), - o.bsWriteAndUpdate(f, m, 3, 0), - o.bsWriteAndUpdate(f, m, 4, a.num_dep_sub[e]), - 0 < a.num_dep_sub[e] ? o.bsWriteAndUpdate(f, m, 9, a.chan_loc) : o.bsWriteAndUpdate(f, m, 1, 0); - return 0 < a.complexity_index_type_a && (o.bsWriteAndUpdate(f, m, 7, 0), - o.bsWriteAndUpdate(f, m, 1, 1), - o.bsWriteAndUpdate(f, m, 8, a.complexity_index_type_a)), - { - samplerate: p, - channelCount: c, - segmentCodec: "ec3", - codec: "ec-3", - extraDataBytes: f - } - }; - class J extends c { - resetInitSegment(e, t) { - this.audioConfig = void 0, - this.audioTrack = void 0, - this.duration = t - } - static probe(e, t) { - var i = new M(e,t) - , t = i.length; - return !(!i.hasTimeStamp || 11 !== e[t] || 119 !== e[t + 1] || 16 !== (new H).bsReadAndUpdate(e, { - byteOffset: t + 5, - usedBits: 0 - }, 5)) - } - append(e, t, i, r, n) { - var s = new M(e,this.logger) - , a = 90 * s.timeStamp - , o = e.length; - let d = 0 - , l = s.length; - if (this.audioConfig || (this.audioConfig = Y(this.observer, e, l, this.logger)), - !this.audioConfig) - throw "failed to parse ec-3 config"; - if (!this.audioTrack) { - const e = { - id: 258, - inputTimescale: 9e4, - timescale: NaN, - duration: this.duration, - encrypted: !1, - keyTagInfo: n - } - , t = { - len: 0, - sequenceNumber: 0, - esSamples: [] - }; - this.audioTrack = { - info: e, - parsingData: t, - type: "audio", - config: this.audioConfig - } - } - var u = j(this.audioConfig, this.audioTrack.info.inputTimescale); - for ("zec3" === s.audioType && (this.audioTrack.info.encrypted = !0); l < o; ) { - const t = X(this.observer, e, l, this.logger) - , i = a + d * u - , r = { - unit: e.subarray(l, l + t), - pts: i, - dts: i, - keyTagInfo: n - }; - this.audioTrack.parsingData.esSamples.push(r), - this.audioTrack.parsingData.len += t, - l += t, - d++ - } - this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, { - id3Samples: [{ - pts: a, - dts: a, - data: s.payload, - frames: s.frames - }], - inputTimescale: this.audioTrack.info.inputTimescale - }, void 0, t, i, r, n) - } - } - const Z = { - BitratesMap: [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160], - SamplingRateMap: [44100, 48e3, 32e3, 22050, 24e3, 16e3, 11025, 12e3, 8e3], - SamplesCoefficients: [[0, 72, 144, 12], [0, 0, 0, 0], [0, 72, 144, 12], [0, 144, 144, 12]], - BytesInSlot: [0, 1, 1, 4], - onFrame: function(e, t, i, r, n, s, a) { - r = a + s * (10368e4 / r); - e.esSamples.push({ - unit: t, - pts: r, - dts: r - }), - e.len += t.length - }, - onNoise: function(e, t) { - t.warn("mpeg audio has noise: " + e.length + " bytes") - }, - parseFrames: function(e, t, i, r, n, s, a) { - if (r < i + 2) - return -1; - if (255 === t[i] || 224 == (224 & t[i + 1])) { - if (r < i + 24) - return -1; - const a = t[i + 1] >> 3 & 3 - , c = t[i + 1] >> 1 & 3 - , h = t[i + 2] >> 4 & 15 - , p = t[i + 2] >> 2 & 3 - , f = !!(2 & t[i + 2]); - if (1 != a && 0 != h && 15 != h && 3 != p) { - var o = 1e3 * [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160][14 * (3 == a ? 3 - c : 3 == c ? 3 : 4) + h - 1] - , d = [44100, 48e3, 32e3, 22050, 24e3, 16e3, 11025, 12e3, 8e3][3 * (3 == a ? 0 : 2 == a ? 1 : 2) + p] - , l = f ? 1 : 0 - , u = t[i + 3] >> 6 == 3 ? 1 : 2 - , l = 3 == c ? (3 == a ? 12 : 6) * o / d + l << 2 : (3 == a ? 144 : 72) * o / d + l | 0; - return r < i + l ? -1 : (Z.onFrame(e, t.subarray(i, i + l), o, d, u, n, s), - l) - } - } - let c = i + 2; - for (; c < r; ) { - if (255 === t[c - 1] && 224 == (224 & t[c])) - return Z.onNoise(t.subarray(i, c - 1), a), - c - i - 1; - c++ - } - return -1 - }, - parse: function(e, t, i, r, n) { - var s = t.length; - let a, o = 0; - for (; i < s && 0 < (a = Z.parseFrames(e, t, i, s, o++, r, n)); ) - i += a - }, - getAudioConfig: function(e, t) { - var i = e[t + 1] >> 3 & 3 - , r = e[t + 1] >> 1 & 3 - , n = e[t + 2] >> 4 & 15 - , s = e[t + 2] >> 2 & 3 - , a = e[t + 2] >> 1 & 1; - if (1 != i && 0 != n && 15 != n && 3 != s) { - var o = 3 == i ? 3 - r : 3 == r ? 3 : 4 - , o = 1e3 * Z.BitratesMap[14 * o + n - 1] - , n = 3 == i ? 0 : 2 == i ? 1 : 2 - , s = Z.SamplingRateMap[3 * n + s] - , t = e[t + 3] >> 6 == 3 ? 1 : 2 - , i = Z.SamplesCoefficients[i][r] - , r = Z.BytesInSlot[r]; - return { - segmentCodec: "mp3", - codec: "mp3", - samplerate: s, - channelCount: t, - frameLength: parseInt(i * o / s + a, 10) * r - } - } - }, - isHeaderPattern: function(e, t) { - return 255 === e[t] && 224 == (224 & e[t + 1]) && 0 != (6 & e[t + 1]) - }, - probe: function(t, i) { - if (i + 1 < t.length && Z.isHeaderPattern(t, i)) { - var r = Z.getAudioConfig(t, i); - let e = 4; - r && r.frameLength && (e = r.frameLength); - i = i + e; - if (i === t.length || i + 1 < t.length && Z.isHeaderPattern(t, i)) - return !0 - } - return !1 - } - }; - var ee = Z; - const te = { - name: "MP3Demuxer" - }; - class ie extends c { - resetInitSegment(e, t) { - this.audioConfig = void 0, - this.audioTrack = void 0, - this.duration = t - } - static probe(e, t) { - var i = new M(e,t); - let r, n; - if (i.hasTimeStamp) - for (r = i.length, - n = Math.min(e.length - 1, r + 100); r < n; r++) - if (ee.probe(e, r)) - return t.warn(te, "MPEG Audio sync word found !"), - !0; - return !1 - } - append(e, t, i, r, n) { - var s = new M(e,this.logger) - , a = 90 * s.timeStamp; - if (this.audioConfig || (this.audioConfig = ee.getAudioConfig(e, s.length)), - !this.audioConfig) - throw "unable to parse mp3 header"; - if (!this.audioTrack) { - const e = { - id: 258, - inputTimescale: 9e4, - timescale: NaN, - duration: this.duration, - encrypted: !1, - keyTagInfo: n - } - , t = { - len: 0, - sequenceNumber: 0, - esSamples: [] - }; - this.audioTrack = { - info: e, - parsingData: t, - type: "audio", - config: this.audioConfig - } - } - ee.parse(this.audioTrack.parsingData, e, s.length, a, this.logger), - this.esRemuxer.remuxEsTracks(this.audioTrack, void 0, { - id3Samples: [{ - pts: a, - dts: a, - data: s.payload, - frames: s.frames - }], - inputTimescale: 9e4 - }, void 0, t, i, r) - } - } - function re(e, t) { - if ("mp4a.40.2" === e) { - if (1 === t) - return new Uint8Array([0, 200, 0, 128, 35, 128]); - if (2 === t) - return new Uint8Array([33, 0, 73, 144, 2, 25, 0, 35, 128]); - if (3 === t) - return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 142]); - if (4 === t) - return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 128, 44, 128, 8, 2, 56]); - if (5 === t) - return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 56]); - if (6 === t) - return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 0, 178, 0, 32, 8, 224]) - } else { - if (1 === t) - return new Uint8Array([1, 64, 34, 128, 163, 78, 230, 128, 186, 8, 0, 0, 0, 28, 6, 241, 193, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]); - if (2 === t) - return new Uint8Array([1, 64, 34, 128, 163, 94, 230, 128, 186, 8, 0, 0, 0, 0, 149, 0, 6, 241, 161, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]); - if (3 === t) - return new Uint8Array([1, 64, 34, 128, 163, 94, 230, 128, 186, 8, 0, 0, 0, 0, 149, 0, 6, 241, 161, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]) - } - return null - } - function ne(e) { - return "number" == typeof e && isFinite(e) - } - function se(e, i=3) { - return JSON.stringify(e, (e,t)=>!isNaN(t) && null != t && t.toFixed ? Number(null == t ? void 0 : t.toFixed(i)) : t) - } - let ae = !0; - function oe(e) { - return ae ? "" : e - } - function de(e) { - if (!e) - return e; - if ("object" != typeof e) - return e; - { - if (Array.isArray(e)) - return e.map(de); - const r = {}; - for (var [t,i] of Object.entries(e)) - r[t] = de(i); - return r - } - } - function le(e) { - const t = [...e]; - for (let e = 0; e < t.length; e++) - t[e] = Object.assign({}, t[e]), - t[e].url = oe(t[e].url), - t[e].attrs && (t[e].attrs = Object.assign({}, t[e].attrs), - t[e].attrs.URI = oe(t[e].attrs.URI)); - return t - } - function ue(e) { - const t = [...e]; - for (let e = 0; e < t.length; e++) - t[e] = Object.assign({}, t[e]), - t[e].url = oe(t[e].url); - return t - } - const ce = Math.pow(2, 32) - 1; - class he { - static init() { - let e; - for (e in he.types = { - avc1: [], - avcC: [], - btrt: [], - dinf: [], - dref: [], - esds: [], - free: [], - ftyp: [], - hdlr: [], - mdat: [], - mdhd: [], - mdia: [], - mfhd: [], - minf: [], - moof: [], - moov: [], - mp4a: [], - ".mp3": [], - dac3: [], - "ac-3": [], - dec3: [], - "ec-3": [], - mvex: [], - mvhd: [], - pasp: [], - sdtp: [], - stbl: [], - stco: [], - stsc: [], - stsd: [], - stsz: [], - stts: [], - tfdt: [], - tfhd: [], - traf: [], - trak: [], - trun: [], - trex: [], - tkhd: [], - vmhd: [], - smhd: [], - uuid: [], - encv: [], - enca: [], - frma: [], - schm: [], - schi: [], - senc: [], - saio: [], - saiz: [], - sinf: [], - tenc: [], - sbgp: [], - seig: [], - sgpd: [], - pssh: [] - }, - he.types) - he.types.hasOwnProperty(e) && (he.types[e] = [e.charCodeAt(0), e.charCodeAt(1), e.charCodeAt(2), e.charCodeAt(3)]); - var t = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 118, 105, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 105, 100, 101, 111, 72, 97, 110, 100, 108, 101, 114, 0]) - , i = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 115, 111, 117, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 111, 117, 110, 100, 72, 97, 110, 100, 108, 101, 114, 0]); - he.HDLR_TYPES = { - video: t, - audio: i - }; - var r = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 117, 114, 108, 32, 0, 0, 0, 1]) - , n = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]); - he.STTS = he.STSC = he.STCO = n, - he.STSZ = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - he.VMHD = new Uint8Array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), - he.SMHD = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]), - he.STSD = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1]); - t = new Uint8Array([105, 115, 111, 109]), - i = new Uint8Array([97, 118, 99, 49]), - n = new Uint8Array([0, 0, 0, 1]); - he.FTYP = he.box(he.types.ftyp, t, n, t, i), - he.DINF = he.box(he.types.dinf, he.box(he.types.dref, r)) - } - static set16(e, t, i) { - return t[i] = e >> 8 & 255, - t[i + 1] = 255 & e, - i + 2 - } - static set32(e, t, i) { - return t[i] = e >> 24 & 255, - t[i + 1] = e >> 16 & 255, - t[i + 2] = e >> 8 & 255, - t[i + 3] = 255 & e, - i + 4 - } - static box(e) { - var t = Array.prototype.slice.call(arguments, 1); - let i = 8 - , r = t.length; - for (var n = r; r--; ) - i += t[r].byteLength; - const s = new Uint8Array(i); - for (s[0] = i >> 24 & 255, - s[1] = i >> 16 & 255, - s[2] = i >> 8 & 255, - s[3] = 255 & i, - s.set(e, 4), - r = 0, - i = 8; r < n; r++) - s.set(t[r], i), - i += t[r].byteLength; - return s - } - static hdlr(e) { - return he.box(he.types.hdlr, he.HDLR_TYPES[e]) - } - static mdat(e) { - return he.box(he.types.mdat, e) - } - static mdhd(e, t) { - t *= e; - var i = Math.floor(t / (1 + ce)) - , t = Math.floor(t % (1 + ce)); - return he.box(he.types.mdhd, new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, t >> 24, t >> 16 & 255, t >> 8 & 255, 255 & t, 85, 196, 0, 0])) - } - static mdia(e) { - var t = he.mdhd(e.info.timescale, e.info.duration) - , i = he.hdlr(e.type) - , e = he.minf(e); - return he.box(he.types.mdia, t, i, e) - } - static mfhd(e) { - return he.box(he.types.mfhd, new Uint8Array([0, 0, 0, 0, e >> 24, e >> 16 & 255, e >> 8 & 255, 255 & e])) - } - static minf(e) { - return "audio" === e.type ? he.box(he.types.minf, he.box(he.types.smhd, he.SMHD), he.DINF, he.stbl(e)) : he.box(he.types.minf, he.box(he.types.vmhd, he.VMHD), he.DINF, he.stbl(e)) - } - static moof(e, t) { - he.types || he.init(); - e = he.traf(t, e); - return he.box(he.types.moof, he.mfhd(t.sequenceNumber), e) - } - static moov(e) { - let t = e.length; - const i = []; - for (; t--; ) - i[t] = he.trak(e[t]); - return he.box.apply(null, [he.types.moov, he.mvhd(e[0].info.timescale, e[0].info.duration)].concat(i).concat(he.mvex(e))) - } - static mvex(e) { - let t = e.length; - const i = []; - for (; t--; ) - i[t] = he.trex(e[t]); - return he.box(he.types.mvex, ...i) - } - static mvhd(e, t) { - t *= e; - var i = Math.floor(t / (1 + ce)) - , t = Math.floor(t % (1 + ce)) - , t = new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, t >> 24, t >> 16 & 255, t >> 8 & 255, 255 & t, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255]); - return he.box(he.types.mvhd, t) - } - static sdtp(e) { - const t = e.samples || [] - , i = new Uint8Array(4 + t.length); - let r, n; - for (n = 0; n < t.length; n++) - r = t[n].flags, - i[n + 4] = r.dependsOn << 4 | r.isDependedOn << 2 | r.hasRedundancy; - return he.box(he.types.sdtp, i) - } - static stbl(e) { - var t = he.stsd(e) - , i = he.box(he.types.stts, he.STTS) - , r = he.box(he.types.stsc, he.STSC) - , n = he.box(he.types.stsz, he.STSZ) - , e = he.box(he.types.stco, he.STCO); - return he.box(he.types.stbl, t, i, r, n, e) - } - static avc1(e) { - let t, i, r, n = [], s = []; - var a = e.info.encrypted ? he.types.encv : he.types.avc1; - for (t = 0; t < e.config.sps.length; t++) - i = e.config.sps[t], - r = i.byteLength, - n.push(r >>> 8 & 255), - n.push(255 & r), - n = n.concat(Array.prototype.slice.call(i)); - for (t = 0; t < e.config.pps.length; t++) - i = e.config.pps[t], - r = i.byteLength, - s.push(r >>> 8 & 255), - s.push(255 & r), - s = s.concat(Array.prototype.slice.call(i)); - var o = he.box(he.types.avcC, new Uint8Array([1, n[3], n[4], n[5], 255, 224 | e.config.sps.length].concat(n).concat([e.config.pps.length]).concat(s))) - , d = e.config.width - , l = e.config.height - , u = e.config.pixelRatio[0] - , c = e.config.pixelRatio[1] - , h = e.info.encrypted && e.info.keyTagInfo ? he.sinf(e.info.keyTagInfo, e.type, he.types.avc1) : new Uint8Array; - return he.box(a, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, d >> 8 & 255, 255 & d, l >> 8 & 255, 255 & l, 0, 72, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 1, 18, 100, 97, 105, 108, 121, 109, 111, 116, 105, 111, 110, 47, 104, 108, 115, 46, 106, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 17, 17]), o, h, he.box(he.types.btrt, new Uint8Array([0, 28, 156, 128, 0, 45, 198, 192, 0, 45, 198, 192])), he.box(he.types.pasp, new Uint8Array([u >> 24, u >> 16 & 255, u >> 8 & 255, 255 & u, c >> 24, c >> 16 & 255, c >> 8 & 255, 255 & c]))) - } - static esds(e) { - var t = e.esdsConfig.length; - return new Uint8Array([0, 0, 0, 0, 3, 23 + t, 0, 1, 0, 4, 15 + t, 64, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5].concat([t]).concat(e.esdsConfig).concat([6, 1, 2])) - } - static audioStsd(e) { - var t = e.samplerate; - return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, e.channelCount, 0, 16, 0, 0, 0, 0, t >> 8 & 255, 255 & t, 0, 0]) - } - static dac3(e) { - e = e.extraData; - return new Uint8Array([e >> 16 & 255, e >> 8 & 255, 255 & e]) - } - static dec3(e) { - return e.extraDataBytes - } - static mp4a(e, t) { - let i = he.types.mp4a - , r = null; - r = e.encrypted && e.keyTagInfo ? (i = he.types.enca, - he.sinf(e.keyTagInfo, "audio", he.types.mp4a)) : new Uint8Array; - e = he.audioStsd(t), - t = he.box(he.types.esds, he.esds(t)); - return he.box(i, e, t, r) - } - static mp3(e) { - return he.box(he.types[".mp3"], he.audioStsd(e)) - } - static ac3(e, t) { - let i = he.types["ac-3"] - , r = null; - return r = e.encrypted && e.keyTagInfo ? (i = he.types.enca, - he.sinf(e.keyTagInfo, "audio", he.types["ac-3"])) : new Uint8Array, - he.box(i, he.audioStsd(t), he.box(he.types.dac3, he.dac3(t)), r) - } - static ec3(e, t) { - let i = he.types["ec-3"] - , r = null; - return r = e.encrypted && e.keyTagInfo ? (i = he.types.enca, - he.sinf(e.keyTagInfo, "audio", he.types["ec-3"])) : new Uint8Array, - he.box(i, he.audioStsd(t), he.box(he.types.dec3, he.dec3(t)), r) - } - static stsd(e) { - if ("audio" !== e.type) - return he.box(he.types.stsd, he.STSD, he.avc1(e)); - if ("mp3" === e.config.segmentCodec && "mp3" === e.config.codec) - return he.box(he.types.stsd, he.STSD, he.mp3(e.config)); - if ("ac3" === e.config.segmentCodec) - return he.box(he.types.stsd, he.STSD, he.ac3(e.info, e.config)); - if ("ec3" === e.config.segmentCodec) - return he.box(he.types.stsd, he.STSD, he.ec3(e.info, e.config)); - if ("aac" === e.config.segmentCodec) - return he.box(he.types.stsd, he.STSD, he.mp4a(e.info, e.config)); - throw `unknown segmentCodec ${e.config.segmentCodec}` - } - static tkhd(e) { - var t = e.info.id - , i = e.info.duration * e.info.timescale - , r = Math.floor(i / (1 + ce)) - , i = Math.floor(i % (1 + ce)); - let n = 0 - , s = 0; - return "video" === e.type && (n = e.config.width, - s = e.config.height), - he.box(he.types.tkhd, new Uint8Array([1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, t >> 24 & 255, t >> 16 & 255, t >> 8 & 255, 255 & t, 0, 0, 0, 0, r >> 24, r >> 16 & 255, r >> 8 & 255, 255 & r, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, n >> 8 & 255, 255 & n, 0, 0, s >> 8 & 255, 255 & s, 0, 0])) - } - static traf(e, t) { - var i = he.senc(e) - , r = he.sdtp(e) - , n = i.boxData - , s = n.length ? he.saio(76) : new Uint8Array - , a = n.length ? he.saiz(i.defaultSampleInfoSize, i.sampleInfoSizes) : new Uint8Array - , o = he.sbgp(e) - , d = he.sgpd(e) - , l = e.id - , i = Math.floor(t / (1 + ce)) - , t = Math.floor(t % (1 + ce)); - return he.box(he.types.traf, he.box(he.types.tfhd, new Uint8Array([0, 2, 0, 0, l >> 24, l >> 16 & 255, l >> 8 & 255, 255 & l])), he.box(he.types.tfdt, new Uint8Array([1, 0, 0, 0, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, t >> 24, t >> 16 & 255, t >> 8 & 255, 255 & t])), n, s, a, o, d, he.trun(e, r.length + n.length + o.length + d.length + s.length + a.length + 16 + 20 + 8 + 16 + 8 + 8), r) - } - static trak(e) { - if ("trakData"in e) - return e.trakData; - e.info.duration = e.info.duration || 4294967295; - var t = he.types.trak - , i = he.tkhd(e) - , e = he.mdia(e); - return he.box(t, i, e) - } - static trex(e) { - e = e.info.id; - return he.box(he.types.trex, new Uint8Array([0, 0, 0, 0, e >> 24, e >> 16 & 255, e >> 8 & 255, 255 & e, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1])) - } - static trun(e, t) { - const i = e.samples || [] - , r = i.length - , n = 12 + 16 * r - , s = new Uint8Array(n); - let a, o, d, l, u, c; - for (t += 8 + n, - s.set([0, 0, 15, 1, r >>> 24 & 255, r >>> 16 & 255, r >>> 8 & 255, 255 & r, t >>> 24 & 255, t >>> 16 & 255, t >>> 8 & 255, 255 & t], 0), - a = 0; a < r; a++) - d = (o = i[a]).duration, - l = o.size, - u = o.flags, - c = o.cts, - s.set([d >>> 24 & 255, d >>> 16 & 255, d >>> 8 & 255, 255 & d, l >>> 24 & 255, l >>> 16 & 255, l >>> 8 & 255, 255 & l, u.isLeading << 2 | u.dependsOn, u.isDependedOn << 6 | u.hasRedundancy << 4 | u.paddingValue << 1 | u.isNonSync, 61440 & u.degradPrio, 15 & u.degradPrio, c >>> 24 & 255, c >>> 16 & 255, c >>> 8 & 255, 255 & c], 12 + 16 * a); - return he.box(he.types.trun, s) - } - static initSegment(e) { - he.types || he.init(); - const t = he.moov(e) - , i = new Uint8Array(he.FTYP.byteLength + t.byteLength); - return i.set(he.FTYP), - i.set(t, he.FTYP.byteLength), - i - } - static saio(e) { - e = e + 4 + 4; - return he.box(he.types.saio, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e])) - } - static saiz(e, t) { - ne(e) || (e = 0); - var i = t.length - , t = 0 === e ? new Uint8Array(t) : new Uint8Array; - return he.box(he.types.saiz, new Uint8Array([0, 0, 0, 0, e, i >> 24 & 255, i >> 16 & 255, i >> 8 & 255, 255 & i]), t) - } - static senc(e) { - const t = e.samples || [] - , i = t.length; - let r = 0 - , n = NaN - , s = !0; - const a = []; - if (!e.encrypted || i <= 0) - return { - boxData: new Uint8Array, - sampleInfoSizes: a, - defaultSampleInfoSize: 0 - }; - e = e.defaultPerSampleIVSize || 0; - for (const l of t) - l.subsamples && (r += l.subsamples.length); - if (r <= 0) - return { - boxData: new Uint8Array, - sampleInfoSizes: a, - defaultSampleInfoSize: 0 - }; - const o = new Uint8Array(2 * i + i * e + 6 * r + 4); - let d = this.set32(i, o, 0); - for (const l of t) { - const t = l.subsamples || []; - let e = 2; - l.iv && (o.set(l.iv, d), - d += l.iv.byteLength, - e += l.iv.byteLength), - d = this.set16(t.length, o, d); - for (const l of t) - d = this.set16(l[0], o, d), - d = this.set32(l[1], o, d), - e += 6; - a.push(e), - ne(n) || (n = e), - s = s && n === e, - n = e - } - return { - boxData: he.box(he.types.senc, new Uint8Array([0, 0, 0, 2]), o), - defaultSampleInfoSize: s ? n : 0, - sampleInfoSizes: a - } - } - static sinf(e, t, i) { - return he.box(he.types.sinf, he.frma(i), he.schm(), he.schi(e, t)) - } - static frma(e) { - return he.box(he.types.frma, new Uint8Array(e)) - } - static schm() { - return he.box(he.types.schm, new Uint8Array([0, 0, 0, 0, 99, 98, 99, 115, 0, 1, 0, 0])) - } - static schi(e, t) { - return he.box(he.types.schi, he.tenc(e, t)) - } - static tenc(e, t) { - let i = 0; - "video" === t && (i = 25); - const r = new Uint8Array(17); - if (r[0] = 16, - e.iv && 16 === e.iv.byteLength && r.set(e.iv, 1), - !e.keyId) - throw "tenc: no key id found in decryptdata"; - return he.box(he.types.tenc, new Uint8Array([1, 0, 0, 0, 0, i, 1, 0]), e.keyId, r) - } - static sbgp(e) { - if (!e.encrypted || 0 === e.samples.length || !e.samples[0].keyTagInfo) - return new Uint8Array; - e = e.samples.length; - return he.box(he.types.sbgp, new Uint8Array([0, 0, 0, 0]), new Uint8Array(he.types.seig), new Uint8Array([0, 0, 0, 1, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e, 0, 1, 0, 1])) - } - static sgpd(e) { - if (!e.encrypted || 0 === e.samples.length || !e.samples[0].keyTagInfo) - return new Uint8Array; - var t = e.samples[0].keyTagInfo; - let i = 0; - "video" === e.type && (i = 25); - const r = new Uint8Array(17); - if (r[0] = 16, - t.iv && r.set(t.iv, 1), - !t.keyId) - throw "sgpd: no keyid in decryptdata"; - return he.box(he.types.sgpd, new Uint8Array([1, 0, 0, 0]), new Uint8Array(he.types.seig), new Uint8Array([0, 0, 0, 37, 0, 0, 0, 1]), new Uint8Array([0, i, 1, 0]), t.keyId, r) - } - static pssh(e, t, i) { - if (he.types || he.init(), - !e) - throw new TypeError("Bad system id"); - if (16 !== e.byteLength) - throw new RangeError("Invalid system id"); - let r, n, s; - if (t) { - r = 1, - n = new Uint8Array(16 * t.length); - for (let e = 0; e < t.length; e++) { - const i = t[e]; - if (16 !== i.byteLength) - throw new RangeError("Invalid key"); - n.set(i, 16 * e) - } - } else - r = 0, - n = new Uint8Array; - 0 < r ? (s = new Uint8Array(4), - 0 < t.length && new DataView(s.buffer).setUint32(0, t.length, !1)) : s = new Uint8Array; - var a = new Uint8Array(4); - return i && 0 < i.byteLength && new DataView(a.buffer).setUint32(0, i.byteLength, !1), - he.box(he.types.pssh, new Uint8Array([r, 0, 0, 0]), e, s, n, a, i || new Uint8Array) - } - } - var pe, fe, me = he; - (yi = pe = pe || {})[yi.SDR = 0] = "SDR", - yi[yi.HDR = 1] = "HDR", - yi[yi.HDR10 = 2] = "HDR10", - yi[yi.DolbyVision = 3] = "DolbyVision", - yi[yi.HLG = 4] = "HLG", - (Si = fe = fe || {})[Si.H264 = 16] = "H264", - Si[Si.HEVC = 64] = "HEVC", - Si[Si.VP09 = 65] = "VP09"; - const ge = new Set(["ac-3", "mp4a.a5", "mp4a.A5"]) - , ye = new Set(["ec-3", "mp4a.a6", "mp4a.A6"]) - , ve = { - aac: 1024, - mp3: 1024, - ac3: 1536, - ec3: 1536 - } - , Se = { - isAC3: e=>Boolean(e && ge.has(e)), - isEC3: e=>Boolean(e && ye.has(e)), - isDolbyAtmos(e, t) { - const i = t.split("/"); - return Boolean(Se.isEC3(e) && 1 < i.length && i[1].split(",").find(e=>"JOC" === e)) - }, - isAAC(e) { - return Boolean(e && ("aac" === e || null !== (e = e.match(/^mp4a\.40\.(.*)/)) && "34" !== e[1])) - }, - isMP3(e) { - return Boolean(e && ("mp3" === e || null !== (e = e.match(/^mp4a\.40\.(.*)/)) && "34" === e[1])) - }, - isAVC: e=>Boolean(e && e.match(/^avc[13]\.(.*)/)), - isXHEAAC: function(e) { - return Boolean("mp4a.40.42" === e) - }, - isALAC: function(e) { - return Boolean("alac" === e) - }, - isFLAC: function(e) { - return Boolean("fLaC" === e) - }, - isHEVC: e=>Boolean(e && e.match(/^(hev|hvc)1\..*/)), - isDolby: e=>Boolean(e && e.match(/^dv(h1|he|a1|av)\..*/)), - isVP09: e=>Boolean(e && e.match(/^vp09\..*/)), - isCompatibleCodecString(e, t) { - const i = e.split(",") - , r = t.split(",") - , n = i.filter(e=>Se.isVideoCodec(e)) - , s = r.filter(e=>Se.isVideoCodec(e)) - , a = i.filter(e=>Se.isAudioCodec(e)) - , o = r.filter(e=>Se.isAudioCodec(e)) - , d = 0 === n.length && 0 === s.length || n.length === s.length && Se.isCompatibleVideoCodec(n[0], s[0]) - , l = 0 === a.length && 0 === o.length || a.length === o.length && Se.isCompatibleAudioCodec(a[0], o[0]); - return d && l - }, - isVideoCodec: e=>Se.isAVC(e) || Se.isDolby(e) || Se.isHEVC(e), - isAudioCodec: e=>Se.isAC3(e) || Se.isEC3(e) || Se.isAAC(e) || Se.isMP3(e), - isCompatibleVideoCodec: (e,t)=>Boolean(e && t && (e === t || Se.isDolby(e) && Se.isDolby(t) || Se.isHEVC(e) && Se.isHEVC(t) || Se.isAVC(e) && Se.isAVC(t))), - isCompatibleAudioCodec: (e,t)=>Boolean(e && t && (e === t || Se.isAAC(e) && Se.isAAC(t) || Se.isAC3(e) && Se.isAC3(t) || Se.isEC3(e) && Se.isEC3(t) || Se.isMP3(e) && Se.isMP3(t))), - getSegmentCodec(e) { - let t; - if (Se.isAAC(e)) - t = "aac"; - else if (Se.isAC3(e)) - t = "ac3"; - else if (Se.isEC3(e)) - t = "ec3"; - else { - if ("mp3" !== e) - throw new Error(`invalid audio config, codec ${e}`); - t = "mp3" - } - return t - }, - getChannelCount(e) { - if (!e) - return 0; - e = e.split("/"), - e = parseInt(e[0]); - return ne(e) ? e : 0 - }, - avc1toavcoti(e) { - var t; - const i = e.split("."); - let r; - return 2 < i.length ? (r = i.shift() + ".", - r += parseInt(null !== (t = i.shift()) && void 0 !== t ? t : "").toString(16), - r += ("000" + parseInt(null !== (t = i.shift()) && void 0 !== t ? t : "").toString(16)).substr(-4)) : r = e, - r - }, - getDynamicRangeType(e, t) { - let i = pe.SDR; - return "PQ" === e && Se.isDolby(t) ? i = pe.DolbyVision : "PQ" === e && (Se.isHEVC(t) || Se.isVP09(t)) ? i = pe.HDR10 : "HLG" !== e || -1 === t.indexOf("hvc1") && !Se.isVP09(t) || (i = pe.HLG), - i - }, - getCompressionType(e) { - let t = fe.H264; - return Se.isHEVC(e) || Se.isDolby(e) ? t = fe.HEVC : Se.isVP09(e) && (t = fe.VP09), - t - }, - isHigherCodecByFamily(e, t) { - if (!e) - return !0; - const i = e.split(".") - , r = t.split("."); - if (i[0] !== r[0]) - throw new Error(`mismatch in codec family current/new: ${i[0]}/${r[0]}`); - switch (i[0]) { - case "avc1": - case "avc3": - return r[1] > i[1]; - case "vp09": - return e < t; - case "hvc1": - case "hev1": - var n = "H" === i[3].substring(0, 1) ? 1 : 0 - , s = i[3].substring(1) - , a = "H" === r[3].substring(0, 1) ? 1 : 0 - , o = r[3].substring(1); - return r[1] > i[1] || r[2] > i[2] || n < a || s < o; - case "dvh1": - return r[1] > i[1] || r[2] > i[2] - } - } - }; - class be { - static getTrack(e, t, i, r, n) { - let s; - switch (Se.getSegmentCodec(i)) { - case "aac": - var a; - (a = E(e, 1 === r ? new Uint8Array([255, 241, 92, 64, 1, 127, 252]) : new Uint8Array([255, 241, 92, 128, 1, 191, 252]), 0, i)) && (s = { - type: "audio", - info: { - id: t, - timescale: a.samplerate, - duration: 0, - encrypted: !1, - keyTagInfo: void 0 - }, - config: a - }); - break; - case "ac3": - case "ec3": - { - const i = q(e, new Uint8Array([11, 119, 69, 17, 128, 64, 47, 132]), 0); - i && (s = { - type: "audio", - info: { - id: t, - timescale: i.samplerate, - duration: 0, - encrypted: !1, - keyTagInfo: void 0 - }, - config: i - }) - } - } - return s - } - static getSample(e, t) { - let i; - switch (e) { - case "mp4a.40.2": - case "mp4a.40.5": - i = 1 === t ? new Uint8Array([0, 208, 0, 7]) : new Uint8Array([33, 0, 3, 64, 104, 28]); - break; - case "ac-3": - case "ec-3": - i = new Uint8Array([11, 119, 69, 17, 128, 64, 47, 132, 41, 3, 253, 214, 124, 253, 243, 215, 233, 95, 185, 123, 78, 20, 40, 106, 97, 190, 74, 253, 43, 218, 208, 140, 191, 176, 144, 120, 214, 181, 44, 124, 129, 251, 91, 109, 187, 109, 198, 225, 43, 172, 116, 140, 176, 123, 38, 144, 211, 247, 225, 64, 29, 53, 175, 96, 16, 57, 121, 87, 78, 203, 81, 37, 7, 72, 228, 132, 37, 169, 38, 231, 97, 229, 247, 194, 208, 8, 12, 83, 74, 139, 137, 17, 22, 26, 221, 203, 107, 113, 94, 93, 75, 33, 208, 247, 146, 105, 39, 143, 6, 36, 1, 227, 108, 70, 11, 180, 152, 218, 182, 218, 209, 59, 85, 104, 201, 70, 37, 82, 219, 68, 55, 225, 144, 99, 149, 0, 119, 26, 14, 69, 164, 241, 204, 222, 81, 177, 142, 80, 20, 100, 97, 143, 101, 221, 140, 113, 31, 208, 124, 25, 64, 29, 49, 77, 140, 30, 155, 74, 214, 204, 138, 229, 109, 172, 95, 130, 70, 230, 134, 88, 59, 179, 212, 155, 232, 0, 0, 0, 0, 0, 173, 234]) - } - return i - } - static getSegment(e, i, r, n) { - if (e) { - var s = e.info["timescale"] - , a = e.config["segmentCodec"] - , o = be.getSample(e.config.codec, e.config.channelCount); - if (o) { - const d = [] - , l = { - id: e.info.id, - sequenceNumber: i, - type: "audio", - encrypted: !1, - samples: d, - defaultPerSampleIVSize: 0 - } - , u = ve[a] - , c = Math.ceil(n * s / u) - , h = { - baseTime: Math.round(c * u + r), - timescale: s - }; - let t = 0; - const p = c * o.byteLength + 8 - , f = new Uint8Array(p); - f[0] = p >> 24 & 255, - f[1] = p >> 16 & 255, - f[2] = p >> 8 & 255, - f[3] = 255 & p, - me.types || me.init(), - f.set(me.types.mdat, 4), - t += 8; - for (let e = 0; e < c; e++) - d.push({ - duration: u, - size: o.byteLength, - cts: 0, - flags: { - isLeading: 0, - isDependedOn: 0, - hasRedundancy: 0, - degradPrio: 0, - dependsOn: 1, - isNonSync: 0, - paddingValue: 0 - } - }), - f.set(o, t), - t += o.byteLength; - const m = me.moof(r, l) - , g = new Uint8Array(m.byteLength + f.byteLength); - return g.set(m), - g.set(f, m.byteLength), - { - silentFragData: g, - endTs: h - } - } - } - } - } - class Te extends h { - constructor(e, t, i, r, n) { - super(e, t, n), - this.typeSupported = i, - this.isVideoContiguous = !1, - this.logger = n.child({ - name: "EsRemuxer" - }); - const s = navigator.userAgent; - this.isSafari = r && -1 < r.indexOf("Apple") && s && !s.match("CriOS") - } - resetTimeStamp(e) { - this._initPTS = this._initDTS = e - } - resetInitSegment() { - this.currentInitTrack = void 0, - this._silentAudioTrack = void 0 - } - remuxEsTracks(r, n, s, a, o, d, l, u, c, h) { - let p; - d || (this.isVideoContiguous = !1); - c = void 0 === c ? o : c; - if (!this.currentInitTrack) { - if (r && r.config.codec && (this._audioTrackInfo = { - id: r.info.id, - codec: r.config.codec, - channelCount: r.config.channelCount - }), - n && h && this._audioTrackInfo) { - const r = be.getTrack(this.observer, this._audioTrackInfo.id, this._audioTrackInfo.codec, this._audioTrackInfo.channelCount, this.logger); - if (r) { - this._silentAudioTrack = Object.assign(Object.assign({}, r), { - info: Object.assign(Object.assign({}, r.info), { - inputTimescale: 9e4 - }), - parsingData: { - len: 0, - sequenceNumber: 0, - esSamples: [] - } - }); - const s = this._initPTS + Math.round(c * this._silentAudioTrack.info.timescale); - p = be.getSegment(this._silentAudioTrack, n.parsingData.sequenceNumber, s, h), - n.parsingData.sequenceNumber++ - } - } else - this._silentAudioTrack = void 0; - this.updateInitPTSDTS(n, r, o), - this.generateIS(this._silentAudioTrack || r, n) - } - if (this.currentInitTrack) { - const f = n && n.parsingData.esSamples.length - , m = this.isVideoContiguous; - let t, i, e; - if (n && h && this._silentAudioTrack && !p) { - const r = this._initPTS + Math.round((c + this.config.audioPrimingDelay) * this._silentAudioTrack.info.timescale); - p = be.getSegment(this._silentAudioTrack, n.parsingData.sequenceNumber, r, h) - } - if (r && r.parsingData.esSamples.length) { - if (ne(r.info.timescale) || (this.logger.warn("regenerate InitSegment as audio detected"), - this.updateInitPTSDTS(n, r, o), - this.generateIS(r, n)), - t = this.remuxAudio(r, c, d, l, u), - f) { - let e; - t && (e = S(t.endPTS) - S(t.startPTS)), - ne(n.info.timescale) || (this.logger.warn("regenerate InitSegment as video detected"), - this.updateInitPTSDTS(n, r, o), - this.generateIS(r, n)), - i = this.remuxVideo(n, c, m, e, h) - } - } else - f && (i = this.remuxVideo(n, c, m, void 0, h)), - i && r && r.config.codec && (t = this.remuxEmptyAudio(r, c, d, l, i, u)); - p ? e = { - data1: i.data1, - data2: p.silentFragData, - startDTS: i.startDTS, - startPTS: i.startPTS, - endDTS: y(i.endDTS, p.endTs), - endPTS: y(i.endPTS, p.endTs), - type: "audiovideo", - track: this.currentInitTrack - } : i && t ? e = { - data1: i.data1, - data2: t.data1, - startDTS: g(i.startDTS, t.startDTS), - startPTS: g(i.startPTS, t.startPTS), - endDTS: y(i.endDTS, t.endDTS), - endPTS: y(i.endPTS, t.endPTS), - type: "audiovideo", - track: this.currentInitTrack, - dropped: i.dropped, - framesWithoutIDR: i.framesWithoutIDR, - firstKeyframePts: i.firstKeyframePts - } : i ? e = { - data1: i.data1, - startDTS: i.startDTS, - startPTS: i.startPTS, - endDTS: i.endDTS, - endPTS: i.endPTS, - type: "video", - track: this.currentInitTrack, - dropped: i.dropped, - framesWithoutIDR: i.framesWithoutIDR, - firstKeyframePts: i.firstKeyframePts - } : t ? e = { - data1: t.data1, - startDTS: t.startDTS, - startPTS: t.startPTS, - endDTS: t.endDTS, - endPTS: t.endPTS, - type: "audio", - track: this.currentInitTrack - } : this.logger.error("Missing video and audio data"), - a && a.captionSamples.length && this.remuxText(a, e), - null !== (a = null == s ? void 0 : s.id3Samples) && void 0 !== a && a.length && this.remuxID3(s, e), - this.observer.trigger(v.FRAG_PARSING_DATA, e) - } else - this.logger.error("failed to generate IS"); - this.observer.trigger(v.FRAG_PARSED) - } - updateInitPTSDTS(e, t, i) { - let r = 1 / 0 - , n = 1 / 0; - var s = e ? e.parsingData.esSamples : [] - , a = t ? t.parsingData.esSamples : []; - if (!ne(this._initPTS)) { - if (t && a.length && (r = n = a[0].pts - t.info.inputTimescale * i), - e && s.length) { - const t = e.info.inputTimescale; - e.info.timescale = t, - r = Math.min(r, s.reduce((e,t)=>{ - var i = t.pts - e; - return i < -4294967296 ? Ee(e, t.pts) : 0 < i ? e : t.pts - } - , s[0].pts) - t * i), - n = Math.min(n, s[0].dts - t * i), - this.observer.trigger(v.INIT_PTS_FOUND, { - initPTS: B(r, t) - }) - } - if (ne(r) && ne(n)) - this._initPTS = r, - this._initDTS = n; - else { - const e = new D(!1,"invalid initPTS or initDTS",$.InvalidInitTimestamp); - this.observer.trigger(P.INTERNAL_ERROR, e) - } - } - } - generateIS(e, t) { - const i = t ? t.parsingData.esSamples : [] - , r = this.typeSupported; - let n, s = "audio/mp4"; - if (e && t && i.length) { - const i = t.info.inputTimescale; - t.info.timescale = i, - e.info.timescale = e.config.samplerate; - const r = he.initSegment([t, e]); - n = { - type: "audiovideo", - container: "video/mp4", - codec: `${t.config.codec},${e.config.codec}`, - initSegment: r - } - } else if (e) { - "mp3" === (e.info.timescale = e.config.samplerate, - e.config.segmentCodec) && (r.mpeg ? (s = "audio/mpeg", - e.config.codec = "") : r.mp3 && (e.config.codec = "mp3")); - const t = "mp3" === e.config.segmentCodec && r.mpeg ? new Uint8Array : he.initSegment([e]); - n = { - type: "audio", - container: s, - codec: e.config.codec, - initSegment: t - } - } else if (t && i.length) { - const e = t.info.inputTimescale; - t.info.timescale = e; - const i = he.initSegment([t]); - n = { - type: "video", - container: "video/mp4", - codec: t.config.codec, - initSegment: i - } - } - if (n) { - this.currentInitTrack = n; - const e = { - track: n - }; - this.observer.trigger(v.FRAG_PARSING_INIT_SEGMENT, e) - } else { - const e = new D(!1,"no audio/video samples found",$.NoAVSamplesFound); - this.observer.trigger(P.INTERNAL_ERROR, e) - } - } - remuxVideo(n, e, s, a, o) { - let d, l, u, c, h, t, p = 8, i = n.parsingData.dropped; - const r = !s && this.config.forceKeyFrameOnDiscontinuity - , f = n.parsingData.esSamples - , m = n.info.inputTimescale - , g = [] - , y = n.info.encrypted; - let v, S; - v = s ? this.nextAvcDts : Ee(f[0].dts, f[0].pts), - f.forEach(function(e) { - e.pts = Ee(e.pts, v), - e.dts = Ee(e.dts, v) - }), - f.sort(function(e, t) { - var i = e.dts - t.dts - , r = e.pts - t.pts; - return i || r || e.id - t.id - }); - var b = f.findIndex(e=>e.key); - f[b] && (S = f[b].pts), - r && (0 < b ? (this.logger.warn(`Dropped ${b} out of ${f.length} video samples due to a missing keyframe`), - f.splice(0, b), - i += b) : -1 === b && (this.logger.warn(`No keyframe found out of ${f.length} video samples`), - i += f.length)); - var T = f[0] - , E = f[f.length - 1] - , I = f.reduce((e,t)=>Math.max(Math.min(e, t.pts - t.dts), -18e3), 0); - if (I < 0) { - this.logger.warn(`PTS < DTS detected in video samples, shifting DTS by ${Math.round(I / 90)} ms to overcome this issue`); - for (let e = 0; e < f.length; e++) - f[e].dts += I - } - var w = this.isSafari; - if (d = Math.round((E.dts - T.dts) / (f.length - 1)), - c = Math.max(T.dts, 0), - u = Math.max(T.pts, 0), - ne(o) && (c = e * m, - u = e * m), - s) { - const n = c - v - , M = n > d - , s = n < -1; - (M || s) && (M ? this.logger.warn(`AVC: ${n}/90000 hole between fragments detected`) : this.logger.warn(`AVC: ${n}/90000 overlapping between fragments detected`)) - } - let A = 0 - , O = 0; - var k = f.length; - for (let e = 0; e < k; e++) { - const M = f[e] - , s = M.units - , a = s.length; - let t = 0; - for (let e = 0; e < a; e++) - t += s[e].data.length; - O += t, - A += a, - M.length = t, - M.dts = w ? c + e * d : Math.max(M.dts, c), - M.pts = Math.max(M.pts, M.dts) - } - t = Math.max(E.dts, 0), - h = Math.max(E.pts, 0, t), - ne(o) && (t = e * m, - h = e * m); - e = O + 4 * A + 8; - try { - l = new Uint8Array(e) - } catch (n) { - const M = new F(!1,`fail allocating video mdat ${e}`,$.FailedToAllocateVideoMdat,e); - return void this.observer.trigger(P.INTERNAL_ERROR, M) - } - const C = new DataView(l.buffer); - C.setUint32(0, e), - l.set(he.types.mdat, 4); - for (let t = 0; t < k; t++) { - const M = f[t] - , s = M.units; - let e, i = 0; - const h = []; - let r = 0; - for (let e = 0, t = s.length; e < t; e++) { - const M = s[e] - , a = M.data - , o = M.data.byteLength; - if (C.setUint32(p, o), - p += 4, - l.set(a, p), - p += o, - i += 4 + o, - y) - if (o <= 48 || 1 !== M.type && 5 !== M.type) - r += 4 + o; - else { - let e = o - 32; - e % 16 == 0 && (e -= 16), - h.push([r + 36, e]), - r = o - 32 - e - } - } - if (0 < r && h.push([r, 0]), - w) - e = Math.max(0, d * Math.round((M.pts - M.dts) / d)); - else { - if (t < k - 1) - d = f[t + 1].dts - M.dts; - else { - const s = this.config - , o = M.dts - f[0 < t ? t - 1 : t].dts; - if (s.stretchShortVideoTrack) { - const n = s.maxBufferHole - , l = s.maxSeekHole - , c = Math.floor(Math.min(n, l) * m) - , P = (a ? u + a * m : this.nextAudioPts) - M.pts; - P > c ? (d = P - o, - d < 0 && (d = o)) : d = o - } else - d = o - } - e = Math.round(M.pts - M.dts) - } - ne(o) && (e = 0, - d = o * m), - g.push({ - size: i, - duration: d, - cts: e, - flags: { - isLeading: 0, - isDependedOn: 0, - hasRedundancy: 0, - degradPrio: 0, - dependsOn: M.key ? 2 : 1, - isNonSync: M.key ? 0 : 1, - paddingValue: 0 - }, - keyTagInfo: M.keyTagInfo, - subsamples: h - }) - } - if (this.nextAvcDts = t + d, - this.isVideoContiguous = !0, - g.length && -1 < navigator.userAgent.toLowerCase().indexOf("chrome")) { - const n = g[0].flags; - n.dependsOn = 2, - n.isNonSync = 0 - } - e = { - sequenceNumber: n.parsingData.sequenceNumber++, - id: n.info.id, - type: n.type, - encrypted: n.info.encrypted, - samples: g, - defaultPerSampleIVSize: 0 - }, - e = he.moof(c + this.config.audioPrimingDelay * m, e); - n.parsingData.esSamples = []; - const D = new Uint8Array(e.byteLength + l.byteLength); - return D.set(e), - D.set(l, e.byteLength), - { - data1: D, - startPTS: B(u / m, m), - endPTS: B((h + d) / m, m), - startDTS: B(c / m, m), - endDTS: B(this.nextAvcDts / m, m), - type: "video", - dropped: i, - framesWithoutIDR: b, - firstKeyframePts: B(S / m, m) - } - } - remuxAudio(r, i, n, e, s) { - const a = r.info.inputTimescale - , o = a / r.info.timescale - , d = ("aac" === r.config.segmentCodec ? 1024 : "mp3" === r.config.segmentCodec ? 1152 : 1536) * o - , l = "mp3" === r.config.segmentCodec && this.typeSupported.mpeg - , u = [] - , c = r.info.encrypted - , t = this._initPTS + i * a; - let h, p, f, m, g, y, v, S, b, T, E, I, w, A, O = l ? 0 : 8; - const k = new H - , C = r.parsingData.esSamples; - if (A = this.nextAudioPts, - (n = n || C.length && A && (e && Math.abs(t - A) < 9e3 || Math.abs(Ee(C[0].pts - A, t)) < 20 * d)) || (A = Ee(C[0].pts, this._initPTS)), - C.forEach(function(e) { - e.pts = e.dts = Ee(e.pts, A) - }), - e && "aac" === r.config.segmentCodec) - for (let t = 0, i = A; t < C.length; ) { - const M = C[t]; - T = M.pts; - const o = T - i - , l = Math.abs(1e3 * o / a); - if (o <= -d) - this.logger.warn(`Dropping 1 audio frame @ ${(i / a).toFixed(3)}s due to ${l} ms overlap.`), - C.splice(t, 1), - r.parsingData.len -= M.unit.length; - else if (o >= d && l < 1e4 && i) { - const l = Math.round(o / d); - this.logger.warn(`Injecting ${l} audio frame @ ${(i / a).toFixed(3)}s due to ${Math.round(1e3 * o / a)} ms gap.`); - for (let e = 0; e < l; e++) - w = Math.max(i, 0), - I = re(r.config.codec, r.config.channelCount), - I || (this.logger.warn("Unable to get silent frame for given audio codec; duplicating last frame instead."), - I = M.unit.subarray(0)), - C.splice(t, 0, { - unit: I, - pts: w, - dts: w, - keyTagInfo: s - }), - r.parsingData.len += I.length, - i += d, - t += 1; - M.pts = M.dts = i, - i += d, - t += 1 - } else - i += d, - M.pts = M.dts = 0 === t ? A : C[t - 1].pts + d, - t += 1 - } - for (let e = 0, t = C.length; e < t; e++) { - if (p = C[e], - m = p.unit, - T = p.pts, - E = p.dts, - void 0 !== b) - f.duration = Math.round((E - b) / o); - else { - const i = Math.round(1e3 * (T - A) / a); - let t = 0; - if (n && "aac" === r.config.segmentCodec && i) { - if (0 < i && i < 1e4) - t = Math.round((T - A) / d), - 0 < t && (I = re(r.config.codec, r.config.channelCount), - I = I || m.subarray(0), - r.parsingData.len += t * I.length); - else if (i < -12) { - r.parsingData.len -= m.byteLength; - continue - } - T = E = A - } - if (v = Math.max(0, T), - S = Math.max(0, E), - !(0 < r.parsingData.len)) - return; - { - const i = l ? r.parsingData.len : r.parsingData.len + 8; - try { - g = new Uint8Array(i) - } catch (r) { - const n = new F(!1,`fail allocating audio mdat ${i}`,$.FailedToAllocateAudioMdat,i); - return void this.observer.trigger(P.INTERNAL_ERROR, n) - } - l || (h = new DataView(g.buffer), - h.setUint32(0, i), - g.set(he.types.mdat, 4)) - } - for (let e = 0; e < t; e++) - w = T - (t - e) * d, - I = re(r.config.codec, r.config.channelCount), - I || (this.logger.warn("Unable to get silent frame for given audio codec; duplicating this frame instead."), - I = m.subarray(0)), - g.set(I, O), - O += I.byteLength, - f = { - size: I.byteLength, - cts: 0, - duration: 1024, - flags: { - isLeading: 0, - isDependedOn: 0, - hasRedundancy: 0, - degradPrio: 0, - dependsOn: 1, - paddingValue: 0, - isNonSync: 0 - }, - keyTagInfo: p.keyTagInfo, - subsamples: c ? [[I.byteLength, 0]] : [] - }, - u.push(f) - } - g.set(m, O); - const M = m.byteLength; - O += M; - const s = []; - if (c) - if ("ec3" === r.config.segmentCodec) { - let e = 0; - for (; e < m.byteLength; ) { - const i = 2 * (k.bsReadAndUpdate(m, { - byteOffset: e + 2, - usedBits: 5 - }, 11) + 1); - e += i; - const n = Math.min(i, 16); - s.push([n, i - n]) - } - } else { - const r = Math.min(M, 16); - s.push([r, M - r]) - } - f = { - size: M, - cts: 0, - duration: 0, - flags: { - isLeading: 0, - isDependedOn: 0, - hasRedundancy: 0, - degradPrio: 0, - dependsOn: 1, - paddingValue: 0, - isNonSync: 0 - }, - keyTagInfo: p.keyTagInfo, - subsamples: s - }, - u.push(f), - b = E - } - let D = 0; - e = u.length; - if (2 <= e && (D = u[e - 2].duration, - f.duration = D), - e) { - if (this.nextAudioPts = T + o * D, - r.parsingData.len = 0, - l) - y = new Uint8Array; - else { - const i = { - sequenceNumber: r.parsingData.sequenceNumber++, - id: r.info.id, - type: r.type, - encrypted: r.info.encrypted, - samples: u, - defaultPerSampleIVSize: 0 - }; - y = he.moof((S + this.config.audioPrimingDelay * a) / o, i) - } - const i = new Uint8Array(y.byteLength + g.byteLength); - return i.set(y), - i.set(g, y.byteLength), - r.parsingData.esSamples = [], - { - data1: i, - startPTS: B(v / a, a), - endPTS: B(this.nextAudioPts / a, a), - startDTS: B(S / a, a), - endDTS: B((E + o * D) / a, a), - type: "audio" - } - } - return null - } - remuxEmptyAudio(t, e, i, r, n, s) { - var a = t.info.inputTimescale - , o = a / (t.config.samplerate || a) - , d = this.nextAudioPts - , l = (void 0 !== d ? d : S(n.startDTS) * a) + this._initDTS - , a = S(n.endDTS) * a + this._initDTS - , u = 1024 * o - , c = Math.ceil((a - l) / u) - , h = re(t.config.codec, t.config.channelCount); - if (this.logger.warn("remux empty Audio"), - !h) - return this.logger.error("Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!"), - null; - const p = []; - for (let e = 0; e < c; e++) { - const i = l + e * u; - p.push({ - unit: h, - pts: i, - dts: i, - keyTagInfo: s - }), - t.parsingData.len += h.length - } - return t.parsingData.esSamples = p, - this.remuxAudio(t, e, i, r, s) - } - remuxID3(t, e) { - var i = t.id3Samples.length; - let r; - var n = t.inputTimescale; - if (i) { - for (let e = 0; e < i; e++) - r = t.id3Samples[e], - r.pts = r.pts / n, - r.dts = r.dts / n; - e.id3Samples = t.id3Samples - } - t.id3Samples = [] - } - remuxText(t, e) { - t.captionSamples.sort(function(e, t) { - return e.pts - t.pts - }); - var i = t.captionSamples.length; - let r; - var n = t.inputTimescale; - if (i) { - for (let e = 0; e < i; e++) - r = t.captionSamples[e], - r.pts = r.pts / n; - e.captionData || (e.captionData = {}), - e.captionData.ts = t.captionSamples - } - t.captionSamples = [] - } - } - function Ee(e, t) { - var i; - if (void 0 === t) - return e; - for (i = t < e ? -8589934592 : 8589934592; 4294967296 < Math.abs(e - t); ) - e += i; - return e - } - e = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : void 0 !== jy ? jy : {}; - function Ie(e) { - try { - return JSON.stringify(e) - } catch (e) { - return '"[Circular]"' - } - } - function we(e, t, i) { - var r = i && i.stringify || Ie; - if ("object" == typeof e && null !== e) { - var n = t.length + 1; - if (1 === n) - return e; - var s = new Array(n); - s[0] = r(e); - for (var a = 1; a < n; a++) - s[a] = r(t[a]); - return s.join(" ") - } - if ("string" != typeof e) - return e; - var o = t.length; - if (0 === o) - return e; - for (var d = "", l = 0, u = -1, c = e && e.length || 0, h = 0; h < c; ) { - if (37 === e.charCodeAt(h) && h + 1 < c) { - switch (u = -1 < u ? u : 0, - e.charCodeAt(h + 1)) { - case 100: - if (o <= l) - break; - if (u < h && (d += e.slice(u, h)), - null == t[l]) - break; - d += Number(t[l]), - u = h += 2; - break; - case 79: - case 111: - case 106: - if (o <= l) - break; - if (u < h && (d += e.slice(u, h)), - void 0 === t[l]) - break; - var p = typeof t[l]; - if ("string" == p) { - d += "'" + t[l] + "'", - u = h + 2, - h++; - break - } - if ("function" == p) { - d += t[l].name || "", - u = h + 2, - h++; - break - } - d += r(t[l]), - u = h + 2, - h++; - break; - case 115: - if (o <= l) - break; - u < h && (d += e.slice(u, h)), - d += String(t[l]), - u = h + 2, - h++; - break; - case 37: - u < h && (d += e.slice(u, h)), - d += "%", - u = h + 2, - h++ - } - ++l - } - ++h - } - return -1 === u ? e : (u < c && (d += e.slice(u)), - d) - } - var Ae = Ce; - const Oe = function() { - function t(e) { - return void 0 !== e && e - } - try { - return "undefined" != typeof globalThis || Object.defineProperty(Object.prototype, "globalThis", { - get: function() { - return delete Object.prototype.globalThis, - this.globalThis = this - }, - configurable: !0 - }), - globalThis - } catch (e) { - return t(jy) || t(window) || t(this) || {} - } - }().console || {} - , ke = { - mapHttpRequest: Re, - mapHttpResponse: Re, - wrapRequestSerializer: Le, - wrapResponseSerializer: Le, - wrapErrorSerializer: Le, - req: Re, - res: Re, - err: function(e) { - const t = { - type: e.constructor.name, - msg: e.message, - stack: e.stack - }; - for (const i in e) - void 0 === t[i] && (t[i] = e[i]); - return t - } - }; - function Ce(s) { - (s = s || {}).browser = s.browser || {}; - const a = s.browser.transmit; - if (a && "function" != typeof a.send) - throw Error("pino: transmit option must have a send function"); - const e = s.browser.write || Oe; - s.browser.write && (s.browser.asObject = !0); - const o = s.serializers || {} - , d = (t = s.browser.serialize, - i = o, - Array.isArray(t) ? t.filter(function(e) { - return "!stdSerializers.err" !== e - }) : !0 === t && Object.keys(i)); - var t, i; - let r = s.browser.serialize; - Array.isArray(s.browser.serialize) && -1 < s.browser.serialize.indexOf("!stdSerializers.err") && (r = !1), - "function" == typeof e && (e.error = e.fatal = e.warn = e.info = e.debug = e.trace = e), - !1 === s.enabled && (s.level = "silent"); - const n = s.level || "info" - , l = Object.create(e); - l.log || (l.log = _e), - Object.defineProperty(l, "levelVal", { - get: function() { - return "silent" === this.level ? 1 / 0 : this.levels.values[this.level] - } - }), - Object.defineProperty(l, "level", { - get: function() { - return this._level - }, - set: function(e) { - if ("silent" !== e && !this.levels.values[e]) - throw Error("unknown level " + e); - this._level = e, - De(u, l, "error", "log"), - De(u, l, "fatal", "error"), - De(u, l, "warn", "error"), - De(u, l, "info", "log"), - De(u, l, "debug", "log"), - De(u, l, "trace", "log") - } - }); - const u = { - transmit: a, - serialize: d, - asObject: s.browser.asObject, - levels: ["error", "fatal", "warn", "info", "debug", "trace"], - timestamp: "function" == typeof (i = s).timestamp ? i.timestamp : !1 === i.timestamp ? Ne : Fe - }; - return l.levels = Ce.levels, - l.level = n, - l.setMaxListeners = l.getMaxListeners = l.emit = l.addListener = l.on = l.prependListener = l.once = l.prependOnceListener = l.removeListener = l.removeAllListeners = l.listeners = l.listenerCount = l.eventNames = l.write = l.flush = _e, - l.serializers = o, - l._serialize = d, - l._stdErrSerialize = r, - l.child = function(t) { - if (!t) - throw new Error("missing bindings for child Pino"); - var i, r, e = t.serializers; - function n(e) { - this._childLevel = 1 + (0 | e._childLevel), - this.error = Pe(e, t, "error"), - this.fatal = Pe(e, t, "fatal"), - this.warn = Pe(e, t, "warn"), - this.info = Pe(e, t, "info"), - this.debug = Pe(e, t, "debug"), - this.trace = Pe(e, t, "trace"), - i && (this.serializers = i, - this._serialize = r), - a && (this._logEvent = xe([].concat(e._logEvent.bindings, t))) - } - return d && e && (i = Object.assign({}, o, e), - r = !0 === s.browser.serialize ? Object.keys(i) : d, - delete t.serializers, - Me([t], r, i, this._stdErrSerialize)), - n.prototype = this, - new n(this) - } - , - a && (l._logEvent = xe()), - l - } - function De(e, t, i, r) { - var n, s, a, o, d = Object.getPrototypeOf(t); - t[i] = !(t.levelVal > t.levels.values[i]) && (d[i] || Oe[i] || Oe[r]) || _e, - s = t, - a = i, - !(n = e).transmit && s[a] === _e || (s[a] = (o = s[a], - function() { - const e = n.timestamp() - , t = new Array(arguments.length) - , i = Object.getPrototypeOf && Object.getPrototypeOf(this) === Oe ? Oe : this; - for (var r = 0; r < t.length; r++) - t[r] = arguments[r]; - if (n.serialize && !n.asObject && Me(t, this._serialize, this.serializers, this._stdErrSerialize), - n.asObject ? o.call(i, function(e, t, i, r) { - e._serialize && Me(i, e._serialize, e.serializers, e._stdErrSerialize); - const n = i.slice(); - let s = n[0]; - const a = {}; - r && (a.time = r), - a.level = Ce.levels.values[t]; - let o = 1 + (0 | e._childLevel); - if (o < 1 && (o = 1), - null !== s && "object" == typeof s) { - for (; o-- && "object" == typeof n[0]; ) - Object.assign(a, n.shift()); - s = n.length ? we(n.shift(), n) : void 0 - } else - "string" == typeof s && (s = we(n.shift(), n)); - return void 0 !== s && (a.msg = s), - a - }(this, a, t, e)) : o.apply(i, t), - n.transmit) { - const o = n.transmit.level || s.level - , i = Ce.levels.values[o] - , r = Ce.levels.values[a]; - r < i || function(e, t, i) { - const r = t.send - , n = t.ts - , s = t.methodLevel - , a = t.methodValue - , o = t.val - , d = e._logEvent.bindings; - Me(i, e._serialize || Object.keys(e.serializers), e.serializers, void 0 === e._stdErrSerialize || e._stdErrSerialize), - e._logEvent.ts = n, - e._logEvent.messages = i.filter(function(e) { - return -1 === d.indexOf(e) - }), - e._logEvent.level.label = s, - e._logEvent.level.value = a, - r(s, e._logEvent, o), - e._logEvent = xe(d) - }(this, { - ts: e, - methodLevel: a, - methodValue: r, - transmitLevel: o, - transmitValue: Ce.levels.values[n.transmit.level || s.level], - send: n.transmit.send, - val: s.levelVal - }, t) - } - } - )) - } - function Me(e, t, i, r) { - for (const n in e) - if (r && e[n]instanceof Error) - e[n] = Ce.stdSerializers.err(e[n]); - else if ("object" == typeof e[n] && !Array.isArray(e[n])) - for (const r in e[n]) - t && -1 < t.indexOf(r) && r in i && (e[n][r] = i[r](e[n][r])) - } - function Pe(i, r, n) { - return function() { - try{ const e = new Array(1 + arguments.length); - e[0] = r; - for (var t = 1; t < e.length; t++) - e[t] = arguments[t - 1]; - return i[n].apply(this, e) } catch (e){} - } - } - function xe(e) { - return { - ts: 0, - messages: [], - bindings: e || [], - level: { - label: "", - value: 0 - } - } - } - function Re() { - return {} - } - function Le(e) { - return e - } - function _e() {} - function Ne() { - return !1 - } - function Fe() { - return Date.now() - } - let Be; - function Ue(e={}) { - return Object.assign(Object.assign({}, e), { - customLevels: Object.assign(Object.assign({}, e.customLevels || {}), { - qe: 35 - }) - }) - } - Ce.levels = { - values: { - fatal: 60, - error: 50, - warn: 40, - info: 30, - debug: 20, - trace: 10 - }, - labels: { - 10: "trace", - 20: "debug", - 30: "info", - 40: "warn", - 50: "error", - 60: "fatal" - } + return logger + } + + pino.levels = { + values: { + fatal: 60, + error: 50, + warn: 40, + info: 30, + debug: 20, + trace: 10 }, - Ce.stdSerializers = ke, - Ce.stdTimeFunctions = Object.assign({}, { - nullTime: Ne, - epochTime: Fe, - unixTime: function() { - return Math.round(Date.now() / 1e3) - }, - isoTime: function() { - return new Date(Date.now()).toISOString() - } - }); - const $e = ()=>{} - ; - function Ve(e, t) { - const i = (e = t in e ? e : console)[t] || e.log; - return i ? i.bind(e) : $e - } - function Ke(r, n, e) { - var {time: s, sessionId: t, critical: i, name: a, msg: o} = e; - let d = ""; - if ("data"in e) - try { - const r = [] - , n = []; - d = JSON.stringify(e.data, (e,t)=>{ - if ("object" == typeof t && null !== t) { - var i = n.indexOf(t); - if (-1 !== i) - return `[Circular object reference: '${r[i]}']`; - r.push(e), - n.push(t) - } - return t - } - ) - } catch (r) { - d = `Log serialization error: "${r}"` - } - r(`${function() { - const e = new Date(s) - , t = e.getTimezoneOffset() - , i = He(Math.floor(Math.abs(t) / 60)) - , r = He(Math.abs(t) % 60); - let n = t <= 0 ? "UTC+" + i : "UTC-" + i; - return n = r ? n + ":" + r : n, - e.getFullYear() + "-" + He(e.getMonth() + 1) + "-" + He(e.getDate()) + " " + He(e.getHours()) + ":" + He(e.getMinutes()) + ":" + He(e.getSeconds()) + "." + (e.getMilliseconds() / 1e3).toFixed(3).slice(2, 5) + " " + n - }()}| [SessionID: ${t}] | [${n}] >${i ? " [QE Critical]" : ""} [${a}] ${o || ""} ${d}`) - } - function He(e) { - return e < 10 ? "0" + e : e.toString() - } - function je(e, t=1 / 0) { - if (!e) - return ""; - const i = new Uint8Array(e); - let r, n = ""; - for (r = 0; r < i.length && r < t; r++) { - let e = i[r].toString(16); - e.length < 2 && (e = "0" + e), - n += e - } - return n - } - const qe = ()=>(Be || (Be = Ae(Ue()).child({ - name: "hls" - }), - Be.qe = e=>Be.info(e), - Be.warn("getLogger called without hls object instantiated, returning a logger that is not configured")), - Be) - , Qe = { - bin2str: e=>String.fromCharCode.apply(null, Array.from(e)), - readUint16(e, t) { - t = e[t] << 8 | e[t + 1]; - return t < 0 ? 65536 + t : t - }, - readSint32: (e,t)=>e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3], - readUint32(e, t) { - t = Qe.readSint32(e, t); - return t < 0 ? 4294967296 + t : t - }, - writeUint32(e, t, i) { - e[t] = i >> 24, - e[t + 1] = i >> 16 & 255, - e[t + 2] = i >> 8 & 255, - e[t + 3] = 255 & i - }, - readUint64(e, t) { - var i = Qe.readUint32(e, t); - return i *= Math.pow(2, 32), - i += Qe.readUint32(e, t + 4) - }, - writeUint64(e, t, i) { - var r = Math.pow(2, 32) - 1 - , n = Math.floor(i / (1 + r)) - , r = Math.floor(i % (1 + r)); - Qe.writeUint32(e, t, n), - Qe.writeUint32(e, t + 4, r) - }, - findBox(e, t) { - let i, r, n, s, a, o = []; - if (!t.length) - return []; - for (i = 0; i < e.byteLength; ) - r = Qe.readUint32(e, i), - n = Qe.bin2str(e.subarray(i + 4, i + 8)), - s = 1 < r ? i + r : e.byteLength, - n === t[0] && (1 === t.length ? o.push(e.subarray(i + 8, s)) : (a = Qe.findBox(e.subarray(i + 8, s), t.slice(1))).length && (o = o.concat(a))), - i = s; - return o - }, - findBoxWithOffset(e, t, i, r) { - let n, s, a, o, d, l = []; - if (!i.length) - return []; - for (n = 0; n < e.byteLength; ) - s = Qe.readUint32(e, n), - a = Qe.bin2str(e.subarray(n + 4, n + 8)), - o = 1 < s ? n + s : e.byteLength, - a === i[0] && (r && r.push({ - offset: n + t, - type: a, - size: s - }), - 1 === i.length ? l.push({ - offset: n + t, - type: a, - data: e.subarray(n + 8, o), - boxSize: s, - walkedPath: r ? r.slice(0) : void 0 - }) : (d = Qe.findBoxWithOffset(e.subarray(n + 8, o), n + t + 8, i.slice(1), r ? r.slice(0) : void 0)).length && (l = l.concat(d), - r = r ? r.slice(0, -1) : void 0)), - n = o; - return l - } - } - , Ge = { - name: "MP4EncryptionRemuxer" - }; - class We extends h { - constructor(e, t, i, r, n) { - super(e, t, n) - } - static _isCommonEncryptionInternal(e) { - return Boolean(e && !("NONE" === e || "AES-128" === e)) - } - static remuxInitSegment(c, h, p, f) { - if (!p) - return c; - let e = c; - if (We._isCommonEncryptionInternal(p.method)) { - const m = p.keyId; - let u = !1; - const g = []; - if (Qe.findBoxWithOffset(c, 0, ["moov", "trak"]).forEach(t=>{ - const o = t.data; - let d, i = 0; - const l = Qe.findBoxWithOffset(o, 0, ["mdia", "minf", "stbl", "stsd"], [])[0] - , e = l.data.subarray(8); - let r = !0 - , n = Qe.findBoxWithOffset(e, l.offset + 16, ["enca"]); - 0 === n.length && (r = !1, - n = Qe.findBoxWithOffset(e, l.offset + 16, ["encv"])), - n.forEach(s=>{ - let e = null - , a = null; - i = r ? (e = s.data.subarray(28), - d = "audio", - l.offset + 16 + 8 + 28) : (e = s.data.subarray(78), - d = "video", - l.offset + 16 + 8 + 78), - e && Qe.findBoxWithOffset(e, i, ["sinf"]).forEach(e=>{ - const t = e.data - , i = Qe.findBox(t, ["frma"])[0] - , r = Qe.findBox(t, ["schm"])[0]; - if (i) - if (r) { - var n = Qe.bin2str(r.subarray(4, 8)); - if ("aac " === Qe.bin2str(i.subarray(0, 4)) && (me.types || me.init(), - i.set(me.types.mp4a, 0)), - "cbcs" === n || "cenc" === n) { - f && f.push(t); - const e = Qe.findBox(t, ["schi", "tenc"])[0]; - if (e) { - const h = 8; - e.subarray(8, 24), - e.set(m, 8); - const f = e[6] - , t = e[7]; - if (1 === f && 0 === t) { - const h = e[24]; - 0 < h && p.iv && h === p.iv.length && e.set(p.iv, 25) - } - } - } else if ("cbc2" === n) { - u = !0, - me.types || me.init(); - const h = Qe.findBoxWithOffset(t, 0, ["frma"])[0] - , f = me.box(me.types.schi, me.tenc(p, d)) - , m = me.box(me.types.sinf, t.subarray(h.offset, h.boxSize), me.schm(), f); - a = me.box(me.types.trak, o.subarray(0, e.offset), m, o.subarray(e.offset + e.boxSize)); - const i = a.subarray(8) - , r = m.byteLength - e.boxSize; - l.walkedPath && (l.walkedPath.push({ - type: "stsd", - offset: s.offset, - size: s.boxSize - }), - l.walkedPath.forEach(e=>{ - Qe.writeUint32(i, e.offset, e.size + r) - } - )) - } - } else - h.error(Ge, "missing schm box"); - else - h.error(Ge, "missing frma box") - } - ), - a = a || c.subarray(t.offset, t.offset + t.boxSize), - g.push(a) - } - ); - var s = Qe.findBoxWithOffset(o, 0, ["edts"])[0]; - s && (me.types || me.init(), - o.set(me.types.free, s.offset + 4)) - } - ), - u) { - const p = We.remuxCbc2InitSegment(c, g, h); - e = p || c - } - } - return e - } - static remuxCbc2InitSegment(i, r, n) { - const s = Qe.findBoxWithOffset(i, 0, ["ftyp"])[0]; - if (s) { - const a = Qe.findBoxWithOffset(i, s.boxSize, ["moov"])[0]; - let e = [] - , t = 0; - for (; t < a.data.byteLength; ) { - const i = Qe.readUint32(a.data, t) - , n = Qe.bin2str(a.data.subarray(t + 4, t + 8)) - , s = 1 < i ? t + i : a.data.byteLength; - "trak" === n ? r && (e = e.concat(r), - r = void 0) : e.push(a.data.subarray(t, s)), - t = s - } - const o = me.box(me.types.moov, ...e) - , d = new Uint8Array(s.boxSize + o.byteLength); - return d.set(i.subarray(0, s.boxSize)), - d.set(o, s.boxSize), - d - } - n.error(Ge, "no ftyp found") - } - static remuxOverflowSegment(i, e) { - me.types || me.init(); - const t = Qe.findBoxWithOffset(i, 0, ["moof", "traf", "tfdt"], []); - let r, n = i.byteLength; - if (t.forEach(e=>{ - 0 === e.data[0] && (n += 4) - } - ), - n > i.byteLength) { - r = new Uint8Array(n); - let e = 0 - , t = 0; - for (; t < i.byteLength; ) { - const n = Qe.readUint32(i, t) - , s = Qe.bin2str(i.subarray(t + 4, t + 8)) - , a = 1 < n ? t + n : i.byteLength; - if ("moof" === s) { - const n = We.remuxOverflowMoof(i.subarray(t + 8, a)); - r.set(n, e), - e += n.byteLength - } else - r.set(i.subarray(t, a), e), - e += n; - t = a - } - } else - e.warn(Ge, "no increase in size"); - return r || i - } - static remuxOverflowMoof(e) { - let t = 0; - const i = []; - for (; t < e.byteLength; ) { - const r = Qe.readUint32(e, t); - if ("traf" === Qe.bin2str(e.subarray(t + 4, t + 8))) { - const s = We.remuxOverflowTraf(e.subarray(t + 8, t + r)); - i.push(s) - } else - i.push(e.subarray(t, t + r)); - t = 1 < r ? t + r : e.byteLength - } - const r = me.box(me.types.moof, ...i) - , s = r.byteLength - e.byteLength - 8; - return Qe.findBoxWithOffset(r, 0, ["moof", "traf", "trun"], []).forEach(e=>{ - var t; - 0 != (1 & e.data[3]) && (t = Qe.readUint32(e.data, 8), - Qe.writeUint32(e.data, 8, t + s)) - } - ), - Qe.findBoxWithOffset(r, 0, ["moof", "traf", "saio"], []).forEach(t=>{ - const i = 1 & t.data[0]; - let r = 4; - 1 & t.data[3] && (r += 8); - var n = Qe.readUint32(t.data, r); - if (r += 4, - i) - for (let e = 0; e < n; e++) { - const i = Qe.readUint64(t.data, r); - Qe.writeUint64(t.data, r, i + s), - r += 8 - } - else - for (let e = 0; e < n; e++) { - const i = Qe.readUint32(t.data, r); - Qe.writeUint32(t.data, r, i + s), - r += 4 - } - } - ), - r - } - static remuxOverflowTraf(e) { - let t = 0; - const i = []; - for (; t < e.byteLength; ) { - var r, n = Qe.readUint32(e, t); - "tfdt" === Qe.bin2str(e.subarray(t + 4, t + 8)) && 0 === e[t + 8] ? (r = Qe.readUint32(e, t + 12), - r = me.box(me.types.tfdt, new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, r >> 24, r >> 16 & 255, r >> 8 & 255, 255 & r])), - i.push(r)) : i.push(e.subarray(t, t + n)), - t = 1 < n ? t + n : e.byteLength - } - return me.box(me.types.traf, ...i) - } - remuxText(e, t) { - e.captionSamples.sort(function(e, t) { - return e.pts - t.pts - }), - e.captionSamples.length && (t.captionData || (t.captionData = {}), - t.captionData.mp4 = e.captionSamples), - e.captionSamples = [] - } - remuxIFrame(e, t, i, r, n) { - if (!t.samples || !t.samples.length || !t.samples[0].data) - return null; - let s; - const a = me.moof(e * t.timescale, t) - , o = new Uint8Array(a.byteLength + t.samples[0].data.byteLength + 8); - o.set(a), - Qe.writeUint32(o, a.byteLength, t.samples[0].data.byteLength + 8), - o.set(me.types.mdat, a.byteLength + 4), - o.set(t.samples[0].data, a.byteLength + 8), - t.sequenceNumber++; - var d = t.timescale - , l = B(e + r, d) - , d = B(e, d); - let u, c; - u = i ? (s = "audiovideo", - i.sequenceNumber = t.sequenceNumber, - t.sequenceNumber++, - c = be.getSegment(i, i.sequenceNumber, e * i.info.timescale, r), - y(c.endTs, l)) : (s = "video", - l); - n = { - data1: o, - data2: null == c ? void 0 : c.silentFragData, - startPTS: d, - startDTS: d, - endPTS: u, - endDTS: u, - type: s, - dropped: 0, - track: n - }; - this.observer.trigger(v.FRAG_PARSING_DATA, n), - this.observer.trigger(v.FRAG_PARSED) - } - remuxRawData(e, t, i, r, n, s, a, o, d) { - let l; - t && r ? l = "audiovideo" : t ? l = "audio" : r && (l = "video"); - const u = Math.max(i, e) - , c = { - data1: o, - track: d, - startPTS: B(s, a), - startDTS: B(s, a), - endPTS: void 0, - endDTS: void 0, - type: l, - dropped: 0 - }; - return u && (c.endPTS = B(s + u, a), - c.endDTS = B(s + u, a)), - n && n.captionSamples.length && this.remuxText(n, c), - this.observer.trigger(v.FRAG_PARSING_DATA, c), - this.observer.trigger(v.FRAG_PARSED), - c - } - remuxEmsg(e, t, i, r, n, s, a) { - let o = ""; - e && (o += "audio"), - t && (o += "video"); - n = B(r, n), - a = { - data1: s, - startPTS: n, - startDTS: n, - endPTS: void 0, - endDTS: void 0, - type: o, - dropped: 0, - track: a - }; - return i && 0 < i.id3Samples.length && this.remuxID3(i, a), - this.observer.trigger(v.FRAG_PARSING_DATA, a), - this.observer.trigger(v.FRAG_PARSED), - a - } - remuxID3(t, e) { - let i; - var r = t.id3Samples.length; - if (r) { - for (let e = 0; e < r; e++) - i = t.id3Samples[e], - i.pts = i.pts - 10, - i.dts = i.dts - 10; - e.id3Samples = [...t.id3Samples] - } - t.id3Samples = [] - } - } - const ze = Math.pow(2, 32) - 1 - , Xe = Math.pow(2, 20) - 1 - , Ye = { - name: "MP4Demuxer" - }; - class Je extends u { - constructor(e, t, i, r, n) { - super(e, t, i, {}, n), - this.mp4Remuxer = t, - this.audioPrimingDelay = i.audioPrimingDelay - } - resetTimeStamp(e) { - ne(e) ? this.initData.audio && !this.initData.video ? this.initPtsTs = { - baseTime: Math.round(e * this.initData.audio.timescale / 9e4), - timescale: this.initData.audio.timescale - } : this.initPtsTs = { - baseTime: e, - timescale: 9e4 - } : this.initPtsTs = void 0 - } - static isHEVCFlavor(e) { - if (!e) - return !1; - var t = e.indexOf(".") - , t = t < 0 ? e : e.substring(0, t); - return "hvc1" === t || "hev1" === t || "chvc" === t || "qhvc" === t || "qhev" === t || "muxa" === t || "dvh1" === t || "dvhe" === t || "cdh1" === t || "qdh1" === t || "qdhe" === t - } - resetInitSegment(t, i, r) { - if (this._silentAudioTrack = void 0, - t && t.byteLength) { - var n = We.remuxInitSegment(t, this.logger, r) - , s = this.initData = Je.parseInitSegment(n); - let e; - s.foundLargeTimescale && this.logger.warn(Ye, "large timescale found, will check for 32 bit tfdts"); - var a = s.audioCodec - , r = s.videoCodec; - if (s.audio && s.video ? e = { - type: "audiovideo", - container: "video/mp4", - codec: a + "," + r, - initSegment: n - } : (s.audio && a && (e = { - type: "audio", - container: "audio/mp4", - codec: a, - initSegment: n - }), - s.video && r && (e = { - type: "video", - container: "video/mp4", - codec: r, - initSegment: n - })), - s.video) { - const o = s.video - , d = t.subarray(o.trakOffset, o.trakOffset + o.trakSize); - this._videoTrack = Object.assign(Object.assign({}, o), { - info: { - id: o.id, - timescale: o.timescale, - duration: i - }, - trakData: d, - sequenceNumber: 0, - samples: [] - }), - this.trySEICaptions = !Se.isVP09(r), - this._captionTrack = Object.assign(Object.assign({}, s.caption), { - sequenceNumber: 0, - captionSamples: [] - }) - } - s.audio && a && (this._audioTrack = Object.assign({}, s.audio)), - s.caption && (this.trySEICaptions = !1, - this._captionTrack = Object.assign(Object.assign({}, s.caption), { - sequenceNumber: 0, - captionSamples: [] - })), - this.remuxedInitDataTrack = e; - s = { - track: e - }; - this.observer.trigger(v.FRAG_PARSING_INIT_SEGMENT, s) - } - } - static probe(e, t) { - return 0 < Qe.findBox(e.subarray(0, Math.min(e.length, 512e3)), ["moof"]).length - } - static parseHvcC(e) { - let t; - var i, r; - return e ? 1 === (i = e[0]) ? (r = e[1], - t = { - profileSpace: r >> 6, - tierFlag: (32 & r) >> 5 ? "H" : "L", - profileIDC: 31 & r, - profileCompat: Qe.readUint32(e, 2), - constraintIndicator: e.subarray(6, 12), - levelIDC: e[12] - }) : qe().warn(Ye, `Unhandled version ${i} in hvcC box`) : qe().warn(Ye, "No hvcC box"), - t - } - static hvcCToCodecString(t, i) { - const r = t + "." + (i.profileSpace ? String.fromCharCode(i.profileSpace + "A" - 1) : "") + i.profileIDC + "." + i.profileCompat.toString(16).toUpperCase() + "." + i.tierFlag + i.levelIDC; - let n = ""; - for (let e = i.constraintIndicator.length - 1; 0 <= e; --e) { - const r = i.constraintIndicator[e]; - if (0 !== r || "" !== n) { - const t = r.toString(16).toUpperCase(); - n = "." + ("" === n ? t : t + n) - } - } - return r + n - } - static parseDvcC(e) { - let t; - return e ? t = { - versionMajor: e[0], - versionMinor: e[1], - profile: e[2] >> 1 & 127, - level: e[2] << 5 & 32 | e[3] >> 3 & 31 - } : qe().warn(Ye, "No dvcC box"), - t - } - static dvcCToCodecString(e, t) { - return e + "." + (t.profile < 10 ? "0" + t.profile : t.profile) + "." + (t.level < 10 ? "0" + t.level : t.level) - } - static parseVpcC(e) { - let t; - return e ? t = { - profile: e[4], - level: e[5], - bitDepth: e[6] >> 4 & 15 - } : qe().warn(Ye, "No vpcC box"), - t - } - static vpcCToCodecString(e, t) { - return e + "." + (t.profile < 10 ? "0" + t.profile : t.profile) + "." + (t.level < 10 ? "0" + t.level : t.level) + "." + t.bitDepth - } - static parseInitSegment(e) { - const c = { - foundLargeTimescale: !1, - tracksById: {} - }; - return Qe.findBoxWithOffset(e, 0, ["moov", "trak"]).forEach(t=>{ - const i = t.data - , r = Qe.findBox(i, ["tkhd"])[0]; - if (r) { - var n = 0 === (a = r[0]) ? 12 : 20 - , s = Qe.readUint32(r, n) - , e = Qe.findBox(i, ["mdia", "mdhd"])[0]; - if (e) { - var a, o = 0 === (a = e[0]) ? 12 : 20, n = Qe.readUint32(e, o); - o += 4, - 1e6 <= n && (c.foundLargeTimescale = !0); - const d = 0 === a ? Qe.readUint32(e, o) : 0 - , l = Qe.findBox(i, ["mdia", "hdlr"])[0]; - if (l) { - const r = Qe.bin2str(l.subarray(8, 12)) - , u = { - soun: "audio", - vide: "video", - clcp: "caption" - }[r] || r; - if (u) { - const r = Qe.findBox(i, ["mdia", "minf", "stbl", "stsd"]); - if (r.length) { - const i = r[0]; - Qe.bin2str(i.subarray(12, 16)); - o = Je.parseStsd(i); - let e; - if ("caption" === u) { - const t = Object.assign({ - id: s, - type: u, - timescale: n, - duration: d, - isTimingTrack: !1, - sequenceNumber: 0, - captionSamples: [] - }, o); - c.caption = t, - e = t - } else { - const i = Object.assign({ - id: s, - type: u, - timescale: n, - duration: d, - isTimingTrack: !0, - trakOffset: t.offset, - trakSize: t.boxSize, - sequenceNumber: 0, - samples: [], - fragmentDuration: 0 - }, o); - "video" === u ? (c.video = i, - c.videoCodec = i.codec) : (c.audio = i, - c.audioCodec = i.codec), - e = i - } - c.tracksById[s] = e - } - } - } - } - } - } - ), - Qe.findBoxWithOffset(e, 0, ["moov", "mvex", "trex"]).forEach(e=>{ - var t = e.data - , e = Qe.readUint32(t, 4) - , t = Qe.readUint32(t, 16); - c.tracksById[e].defaultSampleSize = t - } - ), - c - } - static parseStsd(e) { - let r, t; - const i = e.subarray(8); - let n = Qe.bin2str(i.subarray(4, 8)) - , s = null - , a = null; - "enca" === n ? (s = Qe.findBox(i, ["enca"])[0], - a = s.subarray(28)) : "encv" === n && (s = Qe.findBox(i, ["encv"])[0], - a = s.subarray(78)); - e = !!a; - r = 0, - a && Qe.findBox(a, ["sinf"]).forEach(e=>{ - const t = Qe.findBox(e, ["schm"])[0]; - if (t) { - var i = Qe.bin2str(t.subarray(4, 8)); - if ("cbcs" === i || "cenc" === i) { - const t = Qe.findBox(e, ["frma"])[0]; - t && (n = Qe.bin2str(t)); - e = Qe.findBox(e, ["schi", "tenc"])[0]; - e && (r = e[7]) - } - } - } - ); - let o; - var d = i.subarray(86); - switch (n) { - case "mp4a": - t = "mp4a.40.5"; - break; - case "ac-3": - case "ec-3": - case "alac": - case "fLaC": - t = n; - break; - case "avc1": - case "avc3": - t = n + ".640028"; - break; - case "hvc1": - case "hev1": - const l = Qe.findBox(d, ["hvcC"])[0]; - o = Je.parseHvcC(l), - t = o ? Je.hvcCToCodecString(n, o) : n + ".2.4.H150.B0"; - break; - case "dvh1": - case "dvhe": - const r = Qe.findBox(d, ["dvcC"])[0]; - o = Je.parseDvcC(r), - t = o ? Je.dvcCToCodecString(n, o) : n + ".05.01"; - break; - case "c608": - t = n; - break; - case "vp09": - const i = Qe.findBox(d, ["vpcC"])[0]; - o = Je.parseVpcC(i), - t = Je.vpcCToCodecString(n, o); - break; - default: - t = n - } - return { - codec: t, - encrypted: e, - defaultPerSampleIVSize: r - } - } - static has32BitTfdts(e) { - const t = Qe.findBox(e, ["moof", "traf", "tfdt"]); - let i = !1; - return t.forEach(e=>{ - 0 === e[0] && (i = !0) - } - ), - i - } - static getStartDtsTs(r, e) { - const t = Qe.findBox(e, ["moof", "traf"]); - let n, s = Number.MAX_SAFE_INTEGER; - return t.map(function(i) { - return Qe.findBox(i, ["tfhd"]).forEach(e=>{ - var t = Qe.readUint32(e, 4) - , e = r.tracksById[t]; - if (e) { - if (!e.isTimingTrack) - return 1 / 0; - t = e.timescale || 9e4, - e = Qe.findBox(i, ["tfdt"]).map(function(e) { - let t; - var i = e[0]; - return t = Qe.readUint32(e, 4), - 1 === i && (t > Xe && qe().warn(Ye, `Value larger than can be represented by float for upper 32 bits ${t}`), - t *= Math.pow(2, 32), - t += Qe.readUint32(e, 8)), - t - }), - e = 0 < e.length ? e[0] : 1 / 0; - isFinite(e) && e / t < s && (s = e / t, - n = { - baseTime: e, - timescale: t - }) - } - } - ) - }), - n - } - static offsetStartDTS(r, e, d, n) { - Qe.findBox(e, ["moof", "traf"]).map(function(i) { - return Qe.findBox(i, ["tfhd"]).map(function(e) { - const t = Qe.readUint32(e, 4) - , s = r.tracksById[t]; - if (s) { - const a = s.timescale || 9e4 - , o = "caption" === s.type ? 0 : n; - Qe.findBox(i, ["tfdt"]).map(function(t) { - const i = t[0] - , r = s.type; - if (0 === i) { - let e = Qe.readUint32(t, 4) - Math.round(d.baseTime * a / d.timescale); - "video" === r && e < 0 && (qe().warn(Ye, `video tdft would have gone negative by ${e / a} seconds`), - e = 0), - e += Math.round(o * a), - e = Math.max(e, 0), - Qe.writeUint32(t, 4, e) - } else { - const i = Qe.readUint32(t, 4); - i > Xe && qe().error(Ye, `baseMediaDecodeTime larger than can be represented by float for upper 32 bits ${i}`); - let e = i; - e *= Math.pow(2, 32), - e += Qe.readUint32(t, 8), - e -= Math.round(d.baseTime * a / d.timescale), - "video" === r && e < 0 && (qe().warn(Ye, `video tdft would have gone negative by ${e / a} seconds`), - e = 0), - e += Math.round(o * a), - e = Math.max(e, 0); - const n = Math.floor(e / (1 + ze)) - , s = Math.floor(e % (1 + ze)); - Qe.writeUint32(t, 4, n), - Qe.writeUint32(t, 8, s) - } - }) - } - }) - }) - } - static writeStartDTS(i, e, s) { - Qe.findBox(e, ["moof", "traf"]).map(function(t) { - return Qe.findBox(t, ["tfhd"]).map(function(e) { - e = Qe.readUint32(e, 4), - e = i.tracksById[e]; - if (e) { - const r = e.timescale || 9e4 - , n = Math.round(s * r) / r; - .01 < Math.abs(n - s) && qe().warn(Ye, `[iframes] large rounding error when adjusting timestamps, startDTS: ${s}, roundedStartDTS: ${n}`), - Qe.findBox(t, ["tfdt"]).map(function(e) { - var t, i; - 0 === e[0] ? Qe.writeUint32(e, 4, n * r) : (i = n * r, - i = Math.max(i, 0), - t = Math.floor(i / (1 + ze)), - i = Math.floor(i % (1 + ze)), - Qe.writeUint32(e, 4, t), - Qe.writeUint32(e, 8, i)) - }) - } - }) - }) - } - static parseSAIO(e) { - let t = 0 - , i = 0; - var r = e[0]; - i += 4, - 0 != (1 & Qe.readUint32(e, 0)) && (i += 8); - var n = 16777215 & Qe.readUint32(e, i); - return 1 == n ? (i += 4, - t = Qe.readUint32(e, i), - 1 === r && (i += 4, - t *= Math.pow(2, 32), - t += Qe.readUint32(e, i))) : qe().error(Ye, `saio entry count error, count is: ${n}`), - t - } - static parseSAIZ(e) { - let t = 0 - , i = 0; - return i += 4, - 0 != (1 & Qe.readUint32(e, 0)) && (i += 8), - t = e[i], - i++, - i += 4, - 0 === t && (t = e[i]), - t - } - static parseSubsample(e, t) { - const i = { - subsamples: [] - }; - let r = 0; - for (e && (i.iv = t.subarray(0, e), - r += e), - r += 2; r + 6 <= t.byteLength; ) { - const e = Qe.readUint16(t, r); - r += 2; - var n = Qe.readUint32(t, r); - r += 4, - i.subsamples.push([e, n]) - } - return i - } - static isSEIMessage(e, t) { - return e ? 39 === t || 40 === t : 6 === t - } - static parseCLCPSample(e, t, i) { - let r = 0; - const n = []; - let s = 0; - for (; r < i; ) { - var a = t + r - , o = Qe.readUint32(e, a); - a += 4; - var d = Qe.bin2str(e.subarray(a, a + 4)); - if (a += 4, - "cdat" !== d) - break; - { - const t = o - 8 - , l = e.subarray(a, a + t); - s += t, - n.push(l), - r += o - } - } - return { - cdatList: n, - cdatTotalSize: s - } - } - static parseSamples(e, S, b, T, E, I) { - const w = b.timescale - , l = b.id; - let A, O = e, k = 0, C = !1; - Qe.findBoxWithOffset(S, 0, ["moof"]).map(function(e) { - const t = e.data - , v = e.offset; - Qe.findBox(t, ["traf"]).map(function(d) { - var e = Qe.findBox(d, ["tfdt"]).map(function(e) { - let t; - var i = e[0]; - return t = Qe.readUint32(e, 4), - 1 === i && (t *= Math.pow(2, 32), - t += Qe.readUint32(e, 8)), - t / w - })[0]; - return void 0 !== e && (O = e), - Qe.findBox(d, ["tfhd"]).map(function(e) { - var t = Qe.readUint32(e, 4) - , i = 16777215 & Qe.readUint32(e, 0) - , r = 0 != (1 & i) - , n = 0 != (2 & i) - , s = 0 != (8 & i); - let g = 0; - var a = 0 != (16 & i); - let y = 0; - i = 0 != (32 & i); - let o = 8; - if (ne(b.defaultSampleSize) && (y = b.defaultSampleSize), - t === l) { - if (r && (Qe.readUint32(e, o), - o += 4, - Qe.readUint32(e, o), - o += 4), - n && (Qe.readUint32(e, o), - o += 4), - s && (g = Qe.readUint32(e, o), - o += 4), - a && (y = Qe.readUint32(e, o), - o += 4), - i && (Qe.readUint32(e, o), - o += 4), - "video" === b.type) { - let t = 0 - , i = 0; - Qe.findBox(d, ["saio"]).map(function(e) { - t = Je.parseSAIO(e) - }), - Qe.findBox(d, ["saiz"]).map(function(e) { - i = Je.parseSAIZ(e) - }), - t && i && (A = Je.parseSubsample(b.defaultPerSampleIVSize, S.subarray(t, t + i))), - C = Je.isHEVCFlavor(b.codec) - } - Qe.findBox(d, ["trun"]).map(function(i) { - var t = i[0] - , e = 16777215 & Qe.readUint32(i, 0) - , r = 0 != (1 & e); - let n = 0; - var s = 0 != (4 & e) - , a = 0 != (256 & e); - let o = 0; - var d = 0 != (512 & e); - let l = 0; - var u = 0 != (1024 & e) - , c = 0 != (2048 & e); - let h = 0; - var p = Qe.readUint32(i, 4); - let f = 8; - r && (n = Qe.readUint32(i, f), - f += 4), - s && (f += 4); - let m = n + v; - for (let e = 0; e < p && (I < 0 || k < I); e++) { - if (a ? (o = Qe.readUint32(i, f), - f += 4) : o = g, - d ? (l = Qe.readUint32(i, f), - f += 4) : l = y, - u && (f += 4), - c && (h = 0 === t ? Qe.readUint32(i, f) : Qe.readSint32(i, f), - f += 4), - "video" === b.type) { - if (ne(T)) - b.samples.push({ - data: S.subarray(m, m + l), - size: l, - duration: T * w, - cts: 0, - flags: { - isLeading: 0, - isDependedOn: 0, - hasRedundancy: 0, - degradPrio: 0, - dependsOn: 2, - isNonSync: 0, - paddingValue: 0 - }, - subsamples: A ? A.subsamples : [], - iv: A ? A.iv : void 0 - }); - else if (b.fragmentDuration += o, - E) { - let e = 0; - for (; e < l; ) { - const T = Qe.readUint32(S, m); - m += 4; - const E = 31 & S[m]; - if (b.seiSamples || (b.seiSamples = []), - Je.isSEIMessage(C, E)) { - const i = S.subarray(m, m + T); - b.seiSamples.push({ - pts: O + h / w, - type: E, - data: i, - sampleOffset: m, - naluSize: T - }) - } - m += T, - e += T + 4 - } - } - } else if ("audio" === b.type) - b.fragmentDuration += o; - else if ("caption" === b.type) { - const {cdatList: i, cdatTotalSize: T} = Je.parseCLCPSample(S, m, l); - if (m += l, - i.length) { - let t; - if (1 === i.length) - t = new Uint8Array(i[0]); - else if (1 < i.length) { - let e = 0; - t = new Uint8Array(T); - for (const T of i) - t.set(T, e), - e += T.length - } - b.captionSamples.push({ - type: 3, - pts: O, - bytes: t - }) - } - } - k++, - O += o / w - } - }) - } - }) - }) - }) - } - static parseEmsg(e) { - let t, i, r, n, s, a = "", o = "", d = 0; - if (0 === e[0]) { - for (; "\0" !== Qe.bin2str(e.subarray(d, d + 1)); ) - a += Qe.bin2str(e.subarray(d, d + 1)), - d += 1; - for (a += Qe.bin2str(e.subarray(d, d + 1)), - d += 1; "\0" !== Qe.bin2str(e.subarray(d, d + 1)); ) - o += Qe.bin2str(e.subarray(d, d + 1)), - d += 1; - o += Qe.bin2str(e.subarray(d, d + 1)), - d += 1, - t = Qe.readUint32(e, 12), - i = Qe.readUint32(e, 16), - n = Qe.readUint32(e, 20), - s = Qe.readUint32(e, 24), - d = 28 - } else { - d += 4, - t = Qe.readUint32(e, d), - d += 4; - const i = Qe.readUint32(e, d); - d += 4; - var l = Qe.readUint32(e, d); - for (d += 4, - r = Math.pow(2, 32) * i + l, - Number.isSafeInteger(r) || (r = Number.MAX_SAFE_INTEGER, - qe().warn(Ye, "Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box")), - n = Qe.readUint32(e, d), - d += 4, - s = Qe.readUint32(e, d), - d += 4; "\0" !== Qe.bin2str(e.subarray(d, d + 1)); ) - a += Qe.bin2str(e.subarray(d, d + 1)), - d += 1; - for (a += Qe.bin2str(e.subarray(d, d + 1)), - d += 1; "\0" !== Qe.bin2str(e.subarray(d, d + 1)); ) - o += Qe.bin2str(e.subarray(d, d + 1)), - d += 1; - o += Qe.bin2str(e.subarray(d, d + 1)), - d += 1 - } - return { - schemeIdUri: a, - value: o, - timeScale: t, - presentationTime: r, - presentationTimeDelta: i, - eventDuration: n, - id: s, - payload: e.subarray(d, e.byteLength) - } - } - static extractID3PayloadCreateID3Track(e, t, i, r) { - const n = new M(e.payload,r) - , s = new Uint8Array(e.payload) - , a = s.byteLength; - let o = 0 - , d = 0; - var l = ne(e.presentationTime) ? e.presentationTime / e.timeScale : t + e.presentationTimeDelta / e.timeScale; - if (ne(l)) { - const c = e.eventDuration - , h = s.subarray(0, 10) - , p = Qe.bin2str(h.subarray(d, d + 3)); - d += 3, - "ID3" !== p && qe().error(Ye, "No ID3 tag found when extracting ID3 payload"), - d += 2; - var t = s.subarray(d, d + 1) - , e = 64 & t[0] - , u = 16 & t[0]; - if (d += 1, - M.readSynchSafeUint32(s.subarray(d, d + 4)), - d += 4, - e) { - const f = M.readSynchSafeUint32(s.subarray(d, d + 4)); - d += 4, - d += f - } - for (; d + 2 < a; ) { - Qe.bin2str(s.subarray(d, d + 4)), - d += 4; - const m = M.readSynchSafeUint32(s.subarray(d, d + 4)); - d += 4; - const r = l + o * c - , a = { - data: s, - pts: r, - dts: r, - keyTagInfo: void 0, - frames: n.frames - }; - i.id3Samples.push(a), - d += m, - o++, - u && ("DI3" !== Qe.bin2str(s.subarray(d, d + 3)) && qe().error(Ye, "End should be DI3 if footer present in extracting ID3 payload"), - d += 3, - d += 7) - } - d + 2 === a && 0 !== Qe.readUint16(s, d) && qe().warn(Ye, "Padding should be 0 when extracting ID3 payload") - } else - qe().error(Ye, "No pts found in emsg info when extracting ID3 payload") - } - append(e, t, i, r, n, s, a) { - let o = this.initData - , d = 0 - , l = 0 - , u = !1 - , c = !1; - void 0 === o && (this.resetInitSegment(e, 0), - o = this.initData); - let h, p = this.initPtsTs; - p || (h = Je.getStartDtsTs(o, e), - this.initPtsTs = p = { - baseTime: h.baseTime - Math.round(t * h.timescale), - timescale: h.timescale - }, - this.observer.trigger(v.INIT_PTS_FOUND, { - initPTS: p - })), - o.foundLargeTimescale && Je.has32BitTfdts(e) && !a && (e = We.remuxOverflowSegment(e, this.logger)), - h = Je.getStartDtsTs(o, e); - const f = Qe.findBox(e, ["emsg"]); - if (o.video && o.video.encrypted && (Qe.findBox(e, ["moof", "traf"]).find(function(e) { - return Boolean(Qe.findBox(e, ["senc"])[0] || Qe.findBox(e, ["saiz"])[0] && Qe.findBox(e, ["saio"])[0]) - }) || this.logger.warn(Ye, `Missing subsample information for encrypted content codec=${o.videoCodec}`)), - a) { - const t = this._videoTrack.timescale; - a = Math.ceil(a * t) / t; - const i = (h.baseTime + this.audioPrimingDelay * h.timescale) / h.timescale; - if (this._videoTrack && this._audioTrack && !this._silentAudioTrack) { - const e = be.getTrack(this.observer, this._audioTrack.id, this._audioTrack.codec, 2, this.logger); - if (!e) - throw `unable to create silent audio track for codec ${this._audioTrack.codec}`; - this._silentAudioTrack = Object.assign(Object.assign({}, e), { - sequenceNumber: 0 - }); - const t = me.initSegment([this._videoTrack, this._silentAudioTrack]); - this.remuxedInitDataTrack = { - type: "audiovideo", - container: "video/mp4", - codec: this._silentAudioTrack.config.codec + "," + this._videoTrack.codec, - initSegment: t - }; - const i = { - track: this.remuxedInitDataTrack - }; - this.observer.trigger(v.FRAG_PARSING_INIT_SEGMENT, i) - } - Je.parseSamples(i, e, this._videoTrack, a, !1, 1), - this.mp4Remuxer.remuxIFrame(i, this._videoTrack, this._silentAudioTrack, a, this.remuxedInitDataTrack), - this._videoTrack.samples = [] - } else if (f && 0 < f.length) { - var m = (h.baseTime - this.audioPrimingDelay * h.timescale) / h.timescale - , m = Math.max(0, m); - const r = f.map(e=>{ - e = Je.parseEmsg(e); - return "https://aomedia.org/emsg/ID3\0" !== e.schemeIdUri || this._id3Track || (this._id3Track = { - id3Samples: [], - inputTimescale: 9e4 - }), - e - } - ); - this._id3Track && r.map(e=>{ - Je.extractID3PayloadCreateID3Track(e, t, this._id3Track, this.logger) - } - ), - this.mp4Remuxer.remuxEmsg(!!o.audio, !!o.video, this._id3Track, m, h.timescale, e, this.remuxedInitDataTrack), - this._id3Track && (this._id3Track.id3Samples = []) - } else { - m = (h.baseTime - this.audioPrimingDelay * h.timescale) / h.timescale, - m = Math.max(0, m); - this._videoTrack && (Je.parseSamples(m, e, this._videoTrack, void 0, this.trySEICaptions, -1), - d = this._videoTrack.fragmentDuration / this._videoTrack.timescale, - u = !0, - this._videoTrack.fragmentDuration = 0, - this.trySEICaptions ? (Je.extractSEICaptionsFromNALu(this._videoTrack.seiSamples, this._captionTrack), - this._videoTrack.seiSamples = []) : this._captionTrack && Je.parseSamples(m, e, this._captionTrack, void 0, !1, Number.MAX_SAFE_INTEGER)), - this._audioTrack && (Je.parseSamples(m, e, this._audioTrack, void 0, !1, -1), - l = this._audioTrack.fragmentDuration / this._audioTrack.timescale, - c = !0, - this._audioTrack.fragmentDuration = 0), - this.mp4Remuxer.remuxRawData(l, c, d, u, this._captionTrack, m, h.timescale, e, this.remuxedInitDataTrack) - } - } - static extractSEICaptionsFromNALu(a, o) { - if (a) { - for (let s = 0; s < a.length; ++s) { - var d = a[s] - , l = d.pts; - let t = 0; - t++; - let e = 0 - , i = 0 - , r = !1 - , n = 0; - for (; !r && t < d.data.length; ) { - for (e = 0; !(t >= d.data.length) && (n = d.data[t++], - e += n, - 255 === n); ) - ; - for (i = 0; !(t >= d.data.length) && (n = d.data[t++], - i += n, - 255 === n); ) - ; - const a = d.data.length - t; - if (4 === e && t < d.data.length) { - if (r = !0, - 181 === d.data[t++]) { - const a = Qe.readUint16(d.data, t); - if (t += 2, - 49 === a) { - const a = Qe.readUint32(d.data, t); - if (t += 4, - 1195456820 === a && 3 === d.data[t++]) { - const a = d.data[t++]; - t++; - const u = 31 & a - , c = []; - if (64 & a) - for (let e = 0; e < u; e++) { - const a = d.data[t++]; - if (a === (252 & a)) { - const o = 3 & a; - if (0 == o || 1 == o) { - const a = d.data[t++] - , o = d.data[t++]; - c.push(a), - c.push(o) - } - } else - t += 2 - } - 0 < c.length && o.captionSamples.push({ - type: 3, - pts: l, - bytes: c - }) - } - } - } - } else if (i < a) - t += i; - else if (i > a) - break - } - } - return o - } - } - } - const Ze = { - name: "ExpGolomb" - }; - class et { - constructor(e, t) { - this.data = e, - this.logger = t, - this._bytesAvailable = e.byteLength, - this.word = 0, - this.bitsAvailable = 0 - } - get bytesAvailable() { - return this._bytesAvailable - } - loadWord() { - const e = this.data - , t = this._bytesAvailable - , i = e.byteLength - t - , r = new Uint8Array(4) - , n = Math.min(4, t); - if (0 === n) - throw new Error("no bytes available"); - r.set(e.subarray(i, i + n)), - this.word = new DataView(r.buffer).getUint32(0), - this.bitsAvailable = 8 * n, - this._bytesAvailable -= n - } - skipBits(e) { - var t; - this.bitsAvailable > e || (t = (e -= this.bitsAvailable) >> 3, - e -= t >> 3, - this._bytesAvailable -= t, - this.loadWord()), - this.word <<= e, - this.bitsAvailable -= e - } - readBits(e) { - let t = Math.min(this.bitsAvailable, e); - var i = this.word >>> 32 - t; - return 32 < e && this.logger.error(Ze, "Cannot read more than 32 bits at a time"), - this.bitsAvailable -= t, - 0 < this.bitsAvailable ? this.word <<= t : 0 < this._bytesAvailable && this.loadWord(), - t = e - t, - 0 < t && this.bitsAvailable ? i << t | this.readBits(t) : i - } - skipLZ() { - let e; - for (e = 0; e < this.bitsAvailable; ++e) - if (0 != (this.word & 2147483648 >>> e)) - return this.word <<= e, - this.bitsAvailable -= e, - e; - return this.loadWord(), - e + this.skipLZ() - } - skipUEG() { - this.skipBits(1 + this.skipLZ()) - } - skipEG() { - this.skipBits(1 + this.skipLZ()) - } - readUEG() { - var e = this.skipLZ(); - return this.readBits(e + 1) - 1 - } - readEG() { - var e = this.readUEG(); - return 1 & e ? 1 + e >>> 1 : -1 * (e >>> 1) - } - readBoolean() { - return 1 === this.readBits(1) - } - readUByte() { - return this.readBits(8) - } - readUShort() { - return this.readBits(16) - } - readUInt() { - return this.readBits(32) - } - skipScalingList(e) { - let t, i, r = 8, n = 8; - for (t = 0; t < e; t++) - 0 !== n && (i = this.readEG(), - n = (r + i + 256) % 256), - r = 0 === n ? r : n - } - readSPS() { - let e, t, i, r = 0, n = 0, s = 0, a = 0; - const o = this.readUByte.bind(this) - , d = this.readBits.bind(this) - , l = this.readUEG.bind(this) - , u = this.readBoolean.bind(this) - , c = this.skipBits.bind(this) - , h = this.skipEG.bind(this) - , p = this.skipUEG.bind(this) - , f = this.skipScalingList.bind(this); - o(); - var m = o(); - if (d(5), - c(3), - o(), - p(), - 100 === m || 110 === m || 122 === m || 244 === m || 44 === m || 83 === m || 86 === m || 118 === m || 128 === m) { - const e = l(); - if (3 === e && c(1), - p(), - p(), - c(1), - u()) - for (t = 3 !== e ? 8 : 12, - i = 0; i < t; i++) - u() && f(i < 6 ? 16 : 64) - } - p(); - var g = l(); - if (0 === g) - l(); - else if (1 === g) - for (c(1), - h(), - h(), - e = l(), - i = 0; i < e; i++) - h(); - p(), - c(1); - var y = l() - , m = l() - , g = d(1); - 0 === g && c(1), - c(1), - u() && (r = l(), - n = l(), - s = l(), - a = l()); - let v = [1, 1]; - if (u() && u()) - switch (o()) { - case 1: - v = [1, 1]; - break; - case 2: - v = [12, 11]; - break; - case 3: - v = [10, 11]; - break; - case 4: - v = [16, 11]; - break; - case 5: - v = [40, 33]; - break; - case 6: - v = [24, 11]; - break; - case 7: - v = [20, 11]; - break; - case 8: - v = [32, 11]; - break; - case 9: - v = [80, 33]; - break; - case 10: - v = [18, 11]; - break; - case 11: - v = [15, 11]; - break; - case 12: - v = [64, 33]; - break; - case 13: - v = [160, 99]; - break; - case 14: - v = [4, 3]; - break; - case 15: - v = [3, 2]; - break; - case 16: - v = [2, 1]; - break; - case 255: - v = [o() << 8 | o(), o() << 8 | o()] - } - return { - width: Math.ceil(16 * (y + 1) - 2 * r - 2 * n), - height: (2 - g) * (m + 1) * 16 - (g ? 2 : 4) * (s + a), - pixelRatio: v - } - } - readSliceType() { - return this.readUByte(), - this.readUEG(), - this.readUEG() - } - } - const tt = { - name: "TS Demuxer" - }; - var it, rt = class extends c { - constructor(e, t, i, r, n) { - super(e, t, i, r, n) - } - static probe(e, t) { - return 564 <= e.length && 71 === e[0] && 71 === e[188] && 71 === e[376] - } - resetInitSegment(e, t, i) { - this.pmtParsed = !1; - var r = { - id: this._pmtId = -1, - inputTimescale: 9e4, - timescale: NaN, - duration: 0, - encrypted: i && i.isEncrypted, - keyTagInfo: i - } - , i = { - len: 0, - sequenceNumber: 0 - }; - this._avcContext = { - info: Object.assign({}, r), - parsingData: Object.assign(Object.assign({}, i), { - esSamples: new Array, - dropped: 0 - }), - config: {}, - container: "video/mp2t", - type: "video" - }, - this._audioContext = { - info: Object.assign({}, r), - parsingData: Object.assign(Object.assign({}, i), { - esSamples: new Array - }), - container: "video/mp2t", - type: "audio" - }, - this._id3Track = { - id: -1, - inputTimescale: 9e4, - id3Samples: [] - }, - this._txtTrack = { - inputTimescale: 9e4, - captionSamples: [] - }, - this._duration = t, - this._initSegment = e - } - append(e, t, i, r, n, s, a) { - let o, d, l, u, c, h = !1; - this.contiguous = i; - const p = this._avcContext - , f = this._audioContext - , m = this._id3Track; - let g = this.pmtParsed - , y = p.info.id - , v = f.info.id - , S = m.id - , b = this._pmtId - , T = p.pesData - , E = f.pesData - , I = m.pesData; - if (this.iframeMode = void 0 !== a, - this._initSegment && 0 < this._initSegment.byteLength) { - const t = new Uint8Array(this._initSegment.byteLength + e.byteLength); - t.set(this._initSegment), - t.set(e, this._initSegment.byteLength), - this._initSegment = void 0, - 71 === t[0] && (e = t) - } - let w, A, O = e.length; - for (O -= O % 188, - o = 0; o < O; o += 188) { - if (71 !== e[o]) { - const e = new D(!1,"TS packet did not start with 0x47",$.NoTSSyncByteFound); - return void this.observer.trigger(P.INTERNAL_ERROR, e) - } - if (d = !!(64 & e[o + 1]), - l = ((31 & e[o + 1]) << 8) + e[o + 2], - 1 < (48 & e[o + 3]) >> 4) { - if (u = o + 5 + e[o + 4], - u === o + 188) - continue - } else - u = o + 4; - switch (l) { - case y: - d && (T && (c = this._parsePES(T)) && this._parseAVCPES(c, !1), - T = { - data: [], - size: 0, - keyTagInfo: n - }), - T && (T.data.push(e.subarray(u, o + 188)), - T.size += o + 188 - u); - break; - case v: - if (d && !this.iframeMode) { - if (E && (c = this._parsePES(E))) - switch (f.segmentCodec) { - case "aac": - this._parseAACPES(c); - break; - case "mp3": - this._parseMPEGPES(c); - break; - case "ac3": - case "ec3": - this._parseDolbyPES(c) - } - E = { - data: [], - size: 0, - keyTagInfo: n - } - } - E && (E.data.push(e.subarray(u, o + 188)), - E.size += o + 188 - u); - break; - case S: - d && (I && (c = this._parsePES(I)) && m.id3Samples.push(c), - I = { - data: [], - size: 0 - }), - I && (I.data.push(e.subarray(u, o + 188)), - I.size += o + 188 - u); - break; - case 0: - d && (u += e[u] + 1), - b = this._pmtId = this._parsePAT(e, u); - break; - case b: - d && (u += e[u] + 1); - const t = this._parsePMT(e, u, this.typeSupported); - y = t.avcId, - 0 < y && (p.info.id = y, - p.info.encrypted = t.videoEncrypted), - v = t.audioId, - 0 < v && (f.info.id = v, - f.segmentCodec = t.audioSegmentCodec, - f.info.encrypted = t.audioEncrypted), - S = t.id3Id, - 0 < S && (m.id = S), - h && !g && (h = !1, - o = -188), - g = this.pmtParsed = !0; - break; - case 17: - case 8191: - break; - default: - h = !0 - } - } - if (T && (c = this._parsePES(T)) ? (this._parseAVCPES(c, !0), - p.pesData = void 0) : p.pesData = T, - E && (c = this._parsePES(E))) { - switch (f.segmentCodec) { - case "aac": - this._parseAACPES(c); - break; - case "mp3": - this._parseMPEGPES(c); - break; - case "ac3": - case "ec3": - this._parseDolbyPES(c) - } - f.pesData = void 0 - } else - E && E.size && this.logger.warn(tt, "last AAC PES packet truncated,might overlap between fragments"), - f.pesData = E; - I && (c = this._parsePES(I)) ? (m.id3Samples.push(c), - m.pesData = void 0) : m.pesData = I, - f.config && f.segmentCodec && (w = { - type: "audio", - info: f.info, - config: f.config, - parsingData: f.parsingData - }); - var k, C = p.config; - "string" == typeof (k = C).codec && Array.isArray(k.sps) && Array.isArray(k.pps) && "number" == typeof k.width && "number" == typeof k.height && Array.isArray(k.pixelRatio) && (A = { - type: "video", - info: p.info, - config: C, - parsingData: p.parsingData - }), - this.esRemuxer.remuxEsTracks(w, A, m, this._txtTrack, t, i, r, n, s, a) - } - destroy() { - this._duration = 0 - } - _parsePAT(e, t) { - return (31 & e[t + 10]) << 8 | e[t + 11] - } - _parsePMT(e, t, i) { - var r; - const n = { - audioId: -1, - avcId: -1, - id3Id: -1, - audioEncrypted: !1, - videoEncrypted: !1 - } - , s = t + 3 + ((15 & e[t + 1]) << 8 | e[t + 2]) - 4; - for (t += 12 + ((15 & e[t + 10]) << 8 | e[t + 11]); t < s; ) { - switch (r = (31 & e[t + 1]) << 8 | e[t + 2], - e[t]) { - case 207: - n.audioEncrypted = !0; - case 15: - -1 === n.audioId && (n.audioId = r, - n.audioSegmentCodec = "aac"); - break; - case 21: - -1 === n.id3Id && (n.id3Id = r); - break; - case 219: - n.videoEncrypted = !0; - case 27: - -1 === n.avcId && (n.avcId = r); - break; - case 3: - case 4: - !0 !== i.mpeg && !0 !== i.mp3 ? this.logger.warn(tt, "MPEG audio found, not supported in this browser for now") : -1 === n.audioId && (n.audioId = r, - n.audioSegmentCodec = "mp3"); - break; - case 193: - n.audioEncrypted = !0; - case 129: - !0 !== i.ac3 ? this.logger.warn(tt, "AC-3 audio found, not supported in this browser for now") : -1 === n.audioId && (n.audioId = r, - n.audioSegmentCodec = "ac3"); - break; - case 194: - n.audioEncrypted = !0; - case 135: - !0 !== i.ec3 ? this.logger.warn(tt, "EC-3 audio found, not supported in this browser for now") : -1 === n.audioId && (n.audioId = r, - n.audioSegmentCodec = "ec3"); - break; - case 36: - this.logger.warn(tt, "HEVC stream type found, not supported for now"); - break; - default: - this.logger.warn(tt, "unkown stream type:" + e[t]) - } - t += 5 + ((15 & e[t + 3]) << 8 | e[t + 4]) - } - return n - } - _parsePES(e) { - let i, t, r, n, s, a, o = 0; - const d = e.data - , l = e.keyTagInfo; - let u = NaN - , c = NaN; - if (e && 0 !== e.size) { - for (; d[0].length < 19 && 1 < d.length; ) { - const e = new Uint8Array(d[0].length + d[1].length); - e.set(d[0]), - e.set(d[1], d[0].length), - d[0] = e, - d.splice(1, 1) - } - if (i = d[0], - 1 === (i[0] << 16) + (i[1] << 8) + i[2] && (r = (i[4] << 8) + i[5], - !(r && r > e.size - 6))) { - 192 & (t = i[7]) && (u = 536870912 * (14 & i[9]) + 4194304 * (255 & i[10]) + 16384 * (254 & i[11]) + 128 * (255 & i[12]) + (254 & i[13]) / 2, - 64 & t ? (c = 536870912 * (14 & i[14]) + 4194304 * (255 & i[15]) + 16384 * (254 & i[16]) + 128 * (255 & i[17]) + (254 & i[18]) / 2, - 54e5 < u - c && (this.logger.warn(tt, `${Math.round((u - c) / 9e4)}s delta between PTS and DTS, align them`), - u = c)) : c = u), - n = i[8], - a = n + 9, - e.size -= a, - s = new Uint8Array(e.size); - for (let t = 0, e = d.length; t < e; t++) { - i = d[t]; - let e = i.byteLength; - if (a) { - if (a > e) { - a -= e; - continue - } - i = i.subarray(a), - e -= a, - a = 0 - } - s.set(i, o), - o += e - } - return r && (r -= n + 3), - { - data: s, - pts: u, - dts: c, - len: r, - keyTagInfo: l - } - } - } - } - pushAccesUnit(e, t) { - const i = e.avcSample; - if (i && i.units.length && i.frame) { - const r = e.parsingData.esSamples - , n = r.length; - (!0 === i.key || e.config.sps && (n || this.contiguous)) && (i.id = n, - i.keyTagInfo = t, - e.info.encrypted) && i.units.forEach(e=>{ - if (48 < e.data.byteLength) - switch (e.type) { - case 1: - case 5: - e.data = this.discardEPB(e.data) - } - } - ), - n || isFinite(i.pts) ? r.push(i) : e.parsingData.dropped++ - } - } - _parseAVCPES(o, e) { - if (!o.data) - throw "invalid pes data"; - const d = this._avcContext - , t = this._parseAVCNALu(o.data); - let l, u, c, h = d.avcSample; - const p = o.keyTagInfo; - o.data = void 0, - t.forEach(n=>{ - switch (n.type) { - case 1: - if (h && !this.iframeMode) { - u = !0, - h.frame = !0; - const o = n.data; - if (4 < o.length) { - const n = new et(o,this.logger).readSliceType(); - 2 !== n && 4 !== n && 7 !== n && 9 !== n || (h.key = !0) - } - } - break; - case 5: - u = !0, - h && (h = h || (d.avcSample = this._createAVCSample(!0, o.pts, o.dts, "")), - h.key = !0, - h.frame = !0); - break; - case 6: - u = !0, - l = new et(this.discardEPB(n.data),this.logger), - l.readUByte(); - let e = 0 - , t = 0 - , i = !1 - , r = 0; - for (; !i && 1 < l.bytesAvailable; ) { - for (e = 0; r = l.readUByte(), - e += r, - 255 === r; ) - ; - for (t = 0; r = l.readUByte(), - t += r, - 255 === r; ) - ; - if (4 === e && 0 !== l.bytesAvailable) { - if (i = !0, - 181 === l.readUByte() && 49 === l.readUShort() && 1195456820 === l.readUInt() && 3 === l.readUByte()) { - const n = l.readUByte() - , d = 31 & n - , s = [n, l.readUByte()]; - for (c = 0; c < d; c++) - s.push(l.readUByte()), - s.push(l.readUByte()), - s.push(l.readUByte()); - this._insertSampleInOrder(this._txtTrack.captionSamples, { - type: 3, - pts: o.pts, - bytes: s - }) - } - } else if (t < l.bytesAvailable) - for (c = 0; c < t; c++) - l.readUByte() - } - break; - case 7: - if (u = !0, - !d.config.sps) { - l = new et(n.data,this.logger); - const o = l.readSPS(); - d.config.width = o.width, - d.config.height = o.height, - d.config.pixelRatio = o.pixelRatio, - d.config.sps = [n.data], - d.info.duration = this._duration; - const a = n.data.subarray(1, 4); - let t = "avc1."; - for (c = 0; c < 3; c++) { - let e = a[c].toString(16); - e.length < 2 && (e = "0" + e), - t += e - } - d.config.codec = t - } - break; - case 8: - u = !0, - d.config.pps || (d.config.pps = [n.data]); - break; - case 9: - u = !1, - h && this.pushAccesUnit(d, p), - h = d.avcSample = this._createAVCSample(!1, o.pts, o.dts, ""); - break; - case 12: - u = !1; - break; - default: - u = !1, - h && (h.debug += "unknown NAL " + n.type + " ") - } - h && u && h.units.push(n) - } - ), - e && h && (this.pushAccesUnit(d, p), - d.avcSample = void 0) - } - _createAVCSample(e, t, i, r) { - return { - id: NaN, - key: e, - pts: t, - dts: i, - units: new Array, - debug: r - } - } - _insertSampleInOrder(t, i) { - var r = t.length; - if (0 < r) { - if (i.pts >= t[r - 1].pts) - t.push(i); - else - for (let e = r - 1; 0 <= e; e--) - if (i.pts < t[e].pts) { - t.splice(e, 0, i); - break - } - } else - t.push(i) - } - _getLastNalUnit() { - const e = this._avcContext; - let t, i = e.avcSample; - if (!i || 0 === i.units.length) { - const t = e.parsingData.esSamples; - i = t[t.length - 1] - } - if (i) { - const e = i.units; - t = e[e.length - 1] - } - return t - } - _parseAVCNALu(e) { - const t = e.byteLength; - let i, r, n = 0; - const s = this._avcContext; - let a = s.naluState || 0; - const o = a - , d = []; - let l, u, c, h = -1; - for (-1 === a && (h = 0, - c = 31 & e[0], - a = 0, - n = 1); n < t; ) - if (i = e[n++], - a) - if (1 !== a) - if (i) - if (1 === i) { - if (0 <= h) - l = { - data: e.subarray(h, n - a - 1), - type: c - }, - d.push(l); - else { - const t = this._getLastNalUnit(); - if (t && (o && n <= 4 - o && t.state && (t.data = t.data.subarray(0, t.data.byteLength - o)), - r = n - a - 1, - 0 < r)) { - const i = new Uint8Array(t.data.byteLength + r); - i.set(t.data, 0), - i.set(e.subarray(0, r), t.data.byteLength), - t.data = i - } - } - a = n < t ? (u = 31 & e[n], - h = n, - c = u, - 0) : -1 - } else - a = 0; - else - a = 3; - else - a = i ? 0 : 2; - else - a = i ? 0 : 1; - if (0 <= h && 0 <= a && (l = { - data: e.subarray(h, t), - type: c, - state: a - }, - d.push(l)), - 0 === d.length) { - const t = this._getLastNalUnit(); - if (t) { - const i = new Uint8Array(t.data.byteLength + e.byteLength); - i.set(t.data, 0), - i.set(e, t.data.byteLength), - t.data = i - } - } - return s.naluState = a, - d - } - discardEPB(e) { - const t = e.byteLength - , i = []; - let r = 1; - for (; r < t - 2; ) - 0 === e[r] && 0 === e[r + 1] && 3 === e[r + 2] ? (i.push(r + 2), - r += 2) : r++; - if (0 === i.length) - return e; - const n = t - i.length - , s = new Uint8Array(n); - let a = 0; - for (r = 0; r < n; a++, - r++) - a === i[0] && (a++, - i.shift()), - s[r] = e[a]; - return s - } - _parseAACPES(e) { - const t = this._audioContext - , i = t.audioLastPTS - , r = e.keyTagInfo; - let n, s, a, o, d, l, u, c = e.data, h = e.pts, p = t.audioOverFlow; - if (p) { - const e = new Uint8Array(p.byteLength + c.byteLength); - e.set(p, 0), - e.set(c, p.byteLength), - c = e - } - for (a = 0, - l = c.length; a < l - 1 && (255 !== c[a] || 240 != (240 & c[a + 1])); a++) - ; - if (a) { - let e, t, i; - i = a < l - 1 ? (e = `AAC PES did not start with ADTS header,offset:${a}`, - t = !1, - $.PESDidNotStartWithADTS) : (e = "no ADTS header found in AAC PES", - t = !0, - $.NoADTSHeaderInPES), - this.logger.warn(tt, `parsing error:${e}`); - const r = new D(t,e,i); - if (this.observer.trigger(P.INTERNAL_ERROR, r), - t) - return - } - if (!t.config) { - const e = E(this.observer, c, a, void 0, this.logger); - if (!e) - throw "unable to parse adts header"; - t.config = e - } - s = 0; - var f = 9216e4 / t.config.samplerate; - if (p && i) { - const e = i + f; - 1 < Math.abs(e - h) && (h = e) - } - for (; a + 5 < l && (o = 1 & c[a + 1] ? 7 : 9, - n = (3 & c[a + 3]) << 11 | c[a + 4] << 3 | (224 & c[a + 5]) >>> 5, - n -= o, - 0 < n && a + o + n <= l); ) - for (d = h + s * f, - u = { - unit: c.subarray(a + o, a + o + n), - pts: d, - dts: d, - keyTagInfo: r - }, - t.parsingData.esSamples.push(u), - t.parsingData.len += n, - a += n + o, - s++; a < l - 1 && (255 !== c[a] || 240 != (240 & c[a + 1])); a++) - ; - p = a < l ? c.subarray(a, l) : void 0, - t.audioOverFlow = p, - t.audioLastPTS = d - } - _parseMPEGPES(e) { - "mp3" === this._audioContext.segmentCodec && ee.parse(this._audioContext.parsingData, e.data, 0, e.pts, this.logger) - } - _parseDolbyPES(e) { - const t = this._audioContext; - let i = e.data - , r = e.pts; - var n = e.keyTagInfo; - let s = 0 - , a = 0 - , o = t.audioOverFlow; - e = t.audioLastPTS; - if (!t.config) { - let e; - if ("ac3" === t.segmentCodec ? e = q(this.observer, i, a, this.logger) : "ec3" === t.segmentCodec && (e = Y(this.observer, i, a, this.logger)), - !e) - throw "unable to parse dolby header"; - t.config = e - } - if ("ac3" !== t.config.segmentCodec && "ec3" !== t.config.segmentCodec) - throw "unexpected config type"; - var d = 1536 / t.config.samplerate * t.info.inputTimescale; - if (o) { - const c = new Uint8Array(o.byteLength + i.byteLength); - c.set(o, 0), - c.set(i, o.byteLength), - i = c - } - var l = i.length; - if (o && e) { - const c = e + d; - 1 < Math.abs(c - r) && (r = c) - } - let u = 0; - for (; a + u <= l; ) { - if (11 !== i[a] || 119 !== i[a + 1]) { - const c = new D(!0,"invalid dolby audio magic",$.InvalidDolbyAudioMagic); - return void this.observer.trigger(P.INTERNAL_ERROR, c) - } - "ac3" === t.segmentCodec ? u = Q(this.observer, i, a) : "ec3" === t.segmentCodec && (u = X(this.observer, i, a, this.logger)); - const c = r + s * d; - t.audioLastPTS = c; - const o = { - unit: i.subarray(a, a + u), - pts: c, - dts: c, - keyTagInfo: n - }; - t.parsingData.esSamples.push(o), - t.info.duration = this._duration, - t.parsingData.len += u, - a += u, - s++ - } - o = a < l ? i.subarray(a, l) : void 0, - t.audioOverFlow = o - } - } - ; - class nt extends a { - constructor(e, t, i, r) { - super(), - this.typeSupported = e, - this.config = t, - this.vendor = i, - this.logger = r - } - destroy() { - this.removeAllListeners(); - const e = this.demuxer - , t = this.remuxer; - e && e.destroy(), - t && t.destroy() - } - push(t, i, r, n, s, a, o, d, l, u, c, h) { - if (t) { - let e = this.demuxer; - var p = new Uint8Array(t); - if (!e || (s || a) && !this.probeFn(p, this.logger)) { - const {typeSupported: t, config: i} = this - , r = [{ - demux: Je, - remux: We - }, { - demux: rt, - remux: Te - }, { - demux: J, - remux: Te - }, { - demux: z, - remux: Te - }, { - demux: K, - remux: Te - }, { - demux: ie, - remux: Te - }]; - for (const n of r) { - const r = n.demux["probe"]; - if (r(p, this.logger)) { - this.remuxer = new n.remux(this,i,t,this.vendor,this.logger), - e = new n.demux(this,this.remuxer,i,t,this.logger), - this.probeFn = r; - break - } - } - if (!e) { - const t = new D(!0,"no demux matching with content found",$.DemuxerNotFound); - return void this.trigger(P.INTERNAL_ERROR, t) - } - this.demuxer = e - } - const f = this.remuxer - , m = !this.lastKeyTagInfo || i && "NONE" !== i.method && this.lastKeyTagInfo.uri !== i.uri; - if (this.lastKeyTagInfo = i, - (s || a || m) && (e.resetInitSegment(new Uint8Array(r), d, i, s), - f.resetInitSegment()), - s) { - const t = u ? S(u) : void 0; - e.resetTimeStamp(t), - f.resetTimeStamp(t) - } - e.append(p, n, o, l, i, c, h) - } - } - } - function st() { - let e = `${Date.now()}-${Math.random()}`; - return "undefined" != typeof performance && "function" == typeof performance.now && (e += `-${performance.now()}`), - e - } - class at { - constructor(e, t) { - this.rpc = e, - this.logger = t, - this.init = (t,n,s)=>e=>{ - const i = st() - , r = this.demuxers[i] = new nt(t,n,s,this.logger); - [v.INIT_PTS_FOUND, v.FRAG_PARSING_INIT_SEGMENT, v.FRAG_PARSING_DATA, v.FRAG_PARSED, P.INTERNAL_ERROR].forEach(t=>{ - r.on(t, e=>this.rpc.invoke("demuxer.event", [i, t, e])(()=>{} - )) - } - ), - e(i) - } - , - this.push = (i,r,n,s,a,o,d,l,u,c,h,p,f)=>e=>{ - const t = this.demuxers[i]; - t ? (t.push(r, n, s, a, o, d, l, u, c, h, p, f), - e()) : e(void 0, `Demuxer with id "${i}" does not exist on push`) - } - , - this.destroy = i=>e=>{ - const t = this.demuxers[i]; - t ? (t.destroy(), - delete this.demuxers[i], - e()) : this.logger.error(`Demuxer with id "${i}" does not exist on destroy`) - } - , - this.demuxers = {}, - e.register("demuxer.init", this.init), - e.register("demuxer.push", this.push), - e.register("demuxer.destroy", this.destroy) - } - } - class ot { - constructor(e) { - this.worker = e, - this.handlers = {}, - this.deferers = {}, - this._messageHandler = e=>{ - var {type: t, id: i, command: r, args: n, result: e, error: s} = e.data; - if (t === it.Invoke) - try { - if (null == this.handlers[r]) - throw new Error(`command ${r} not found`); - this.handlers[r](...n)(this._respond.bind(this, i, r)) - } catch (s) { - this._respond(i, r, null, new Error(`command ${r} not found`)) - } - else - t === it.Result && null != this.deferers[i] && (this.deferers[i](e, s), - delete this.deferers[i]) - } - , - e.addEventListener("message", this._messageHandler) - } - register(e, t) { - if (null != this.handlers[e]) - return !1; - this.handlers[e] = t - } - unregister(e) { - if (null != this.handlers[e]) - return !1; - delete this.handlers[e] - } - invoke(i, r, n) { - return (e=ot._fallbackCallback)=>{ - var t = st(); - this.deferers[t] = e; - t = { - type: it.Invoke, - id: t, - command: i, - args: r - }; - this._send(t, n) - } - } - teardown() { - this.worker.removeEventListener("message", this._messageHandler) - } - _respond(e, t, i, r, n) { - r instanceof Error && (r = `[${r.name}] ${r.message}\n${r.stack}`); - r = { - type: it.Result, - id: e, - command: t, - result: i, - error: r - }; - this._send(r, n) - } - _send(e, t=[]) { - this.worker.postMessage(e, t.map(e=>ArrayBuffer.isView(e) ? e.buffer : e).filter(e=>void 0 !== e)) - } - } - ot._fallbackCallback = (e,t)=>{ - if (null != t) - throw t - } - , - (gr = it = it || {})[gr.Invoke = 0] = "Invoke", - gr[gr.Result = 1] = "Result", - ArrayBuffer.isView || (ArrayBuffer.isView = function(e) { - return null !== e && "object" == typeof e && e.buffer instanceof ArrayBuffer - } - ), - void 0 !== Hy && Hy && (Br = new ot(d), - mu = (r=>{ - const t = (i=[])=>{ - const e = Object.fromEntries(["fatal", "error", "warn", "info", "debug", "trace", "qe"].map(e=>{ - return [e, (t = e, - (...e)=>{ - r.invoke("logger.log", [i, t, ...e])((e,t)=>{ - if (null != t) - throw t - } - ) - } - )]; - var t - } - )); - return e.child = e=>t([...i, e]), - e - } - ; - return t() - } - )(Br), - new i(Br,mu), - new at(Br,mu)); - var dt = function(e, t) { - return (dt = Object.setPrototypeOf || { - __proto__: [] - }instanceof Array && function(e, t) { - e.__proto__ = t - } - || function(e, t) { - for (var i in t) - Object.prototype.hasOwnProperty.call(t, i) && (e[i] = t[i]) - } - )(e, t) - }; - function lt(e, t) { - if ("function" != typeof t && null !== t) - throw new TypeError("Class extends value " + String(t) + " is not a constructor or null"); - function i() { - this.constructor = e - } - dt(e, t), - e.prototype = null === t ? Object.create(t) : (i.prototype = t.prototype, - new i) - } - var ut = function() { - return (ut = Object.assign || function(e) { - for (var t, i = 1, r = arguments.length; i < r; i++) - for (var n in t = arguments[i]) - Object.prototype.hasOwnProperty.call(t, n) && (e[n] = t[n]); - return e - } - ).apply(this, arguments) - }; - function ct(e, t, i, r) { - var n, s = arguments.length, a = s < 3 ? t : null === r ? r = Object.getOwnPropertyDescriptor(t, i) : r; - if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) - a = Reflect.decorate(e, t, i, r); - else - for (var o = e.length - 1; 0 <= o; o--) - (n = e[o]) && (a = (s < 3 ? n(a) : 3 < s ? n(t, i, a) : n(t, i)) || a); - return 3 < s && a && Object.defineProperty(t, i, a), - a - } - function ht(e, t) { - if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) - return Reflect.metadata(e, t) - } - function pt(e) { - var t = "function" == typeof Symbol && Symbol.iterator - , i = t && e[t] - , r = 0; - if (i) - return i.call(e); - if (e && "number" == typeof e.length) - return { - next: function() { - return { - value: (e = e && r >= e.length ? void 0 : e) && e[r++], - done: !e - } - } - }; - throw new TypeError(t ? "Object is not iterable." : "Symbol.iterator is not defined.") - } - function ft(e, t) { - var i = "function" == typeof Symbol && e[Symbol.iterator]; - if (!i) - return e; - var r, n, s = i.call(e), a = []; - try { - for (; (void 0 === t || 0 < t--) && !(r = s.next()).done; ) - a.push(r.value) - } catch (e) { - n = { - error: e - } - } finally { - try { - r && !r.done && (i = s.return) && i.call(s) - } finally { - if (n) - throw n.error - } - } - return a - } - function mt() { - for (var e = [], t = 0; t < arguments.length; t++) - e = e.concat(ft(arguments[t])); - return e - } - function gt(e) { - return "function" == typeof e - } - var yt = !1 - , vt = { - Promise: void 0, - set useDeprecatedSynchronousErrorHandling(e) { - yt = e - }, - get useDeprecatedSynchronousErrorHandling() { - return yt - } - }; - function St(e) { - setTimeout(function() { - throw e - }, 0) - } - var bt = { - closed: !0, - next: function(e) {}, - error: function(e) { - if (vt.useDeprecatedSynchronousErrorHandling) - throw e; - St(e) - }, - complete: function() {} - } - , Tt = Array.isArray || function(e) { - return e && "number" == typeof e.length - } - ; - function Et(e) { - return null !== e && "object" == typeof e - } - var It = (Ot.prototype = Object.create(Error.prototype), - Ot) - , wt = (At.prototype.unsubscribe = function() { - var t; - if (!this.closed) { - var e = this._parentOrParents - , i = this._ctorUnsubscribe - , r = this._unsubscribe - , n = this._subscriptions; - if (this.closed = !0, - this._parentOrParents = null, - this._subscriptions = null, - e instanceof At) - e.remove(this); - else if (null !== e) - for (var s = 0; s < e.length; ++s) - e[s].remove(this); - if (gt(r)) { - i && (this._unsubscribe = void 0); - try { - r.call(this) - } catch (e) { - t = e instanceof It ? kt(e.errors) : [e] - } - } - if (Tt(n)) - for (var s = -1, a = n.length; ++s < a; ) { - var o = n[s]; - if (Et(o)) - try { - o.unsubscribe() - } catch (e) { - t = t || [], - e instanceof It ? t = t.concat(kt(e.errors)) : t.push(e) - } - } - if (t) - throw new It(t) - } - } - , - At.prototype.add = function(e) { - var t, i = e; - if (!e) - return At.EMPTY; - switch (typeof e) { - case "function": - i = new At(e); - case "object": - if (i === this || i.closed || "function" != typeof i.unsubscribe) - return i; - if (this.closed) - return i.unsubscribe(), - i; - i instanceof At || (t = i, - (i = new At)._subscriptions = [t]); - break; - default: - throw new Error("unrecognized teardown " + e + " added to Subscription.") - } - var r = i._parentOrParents; - if (null === r) - i._parentOrParents = this; - else if (r instanceof At) { - if (r === this) - return i; - i._parentOrParents = [r, this] - } else { - if (-1 !== r.indexOf(this)) - return i; - r.push(this) - } - r = this._subscriptions; - return null === r ? this._subscriptions = [i] : r.push(i), - i - } - , - At.prototype.remove = function(e) { - var t = this._subscriptions; - !t || -1 !== (e = t.indexOf(e)) && t.splice(e, 1) - } - , - At.EMPTY = ((dd = new At).closed = !0, - dd), - At); - function At(e) { - this.closed = !1, - this._parentOrParents = null, - this._subscriptions = null, - e && (this._ctorUnsubscribe = !0, - this._unsubscribe = e) - } - function Ot(e) { - return Error.call(this), - this.message = e ? e.length + " errors occurred during unsubscription:\n" + e.map(function(e, t) { - return t + 1 + ") " + e.toString() - }).join("\n ") : "", - this.name = "UnsubscriptionError", - this.errors = e, - this - } - function kt(e) { - return e.reduce(function(e, t) { - return e.concat(t instanceof It ? t.errors : t) - }, []) - } - var Ct, Dt, Mt = "function" == typeof Symbol ? Symbol("rxSubscriber") : "@@rxSubscriber_" + Math.random(), Pt = (lt(Lt, Dt = wt), - Lt.prototype[Mt] = function() { - return this - } - , - Lt.create = function(e, t, i) { - i = new Lt(e,t,i); - return i.syncErrorThrowable = !1, - i - } - , - Lt.prototype.next = function(e) { - this.isStopped || this._next(e) - } - , - Lt.prototype.error = function(e) { - this.isStopped || (this.isStopped = !0, - this._error(e)) - } - , - Lt.prototype.complete = function() { - this.isStopped || (this.isStopped = !0, - this._complete()) - } - , - Lt.prototype.unsubscribe = function() { - this.closed || (this.isStopped = !0, - Dt.prototype.unsubscribe.call(this)) - } - , - Lt.prototype._next = function(e) { - this.destination.next(e) - } - , - Lt.prototype._error = function(e) { - this.destination.error(e), - this.unsubscribe() - } - , - Lt.prototype._complete = function() { - this.destination.complete(), - this.unsubscribe() - } - , - Lt.prototype._unsubscribeAndRecycle = function() { - var e = this._parentOrParents; - return this._parentOrParents = null, - this.unsubscribe(), - this.closed = !1, - this.isStopped = !1, - this._parentOrParents = e, - this - } - , - Lt), xt = (lt(Rt, Ct = Pt), - Rt.prototype.next = function(e) { - var t; - !this.isStopped && this._next && (t = this._parentSubscriber, - vt.useDeprecatedSynchronousErrorHandling && t.syncErrorThrowable ? this.__tryOrSetError(t, this._next, e) && this.unsubscribe() : this.__tryOrUnsub(this._next, e)) - } - , - Rt.prototype.error = function(e) { - if (!this.isStopped) { - var t = this._parentSubscriber - , i = vt.useDeprecatedSynchronousErrorHandling; - if (this._error) - i && t.syncErrorThrowable ? this.__tryOrSetError(t, this._error, e) : this.__tryOrUnsub(this._error, e), - this.unsubscribe(); - else if (t.syncErrorThrowable) - i ? (t.syncErrorValue = e, - t.syncErrorThrown = !0) : St(e), - this.unsubscribe(); - else { - if (this.unsubscribe(), - i) - throw e; - St(e) - } - } - } - , - Rt.prototype.complete = function() { - var e, t, i = this; - this.isStopped || (e = this._parentSubscriber, - this._complete && (t = function() { - return i._complete.call(i._context) - } - , - vt.useDeprecatedSynchronousErrorHandling && e.syncErrorThrowable ? this.__tryOrSetError(e, t) : this.__tryOrUnsub(t)), - this.unsubscribe()) - } - , - Rt.prototype.__tryOrUnsub = function(e, t) { - try { - e.call(this._context, t) - } catch (e) { - if (this.unsubscribe(), - vt.useDeprecatedSynchronousErrorHandling) - throw e; - St(e) - } - } - , - Rt.prototype.__tryOrSetError = function(e, t, i) { - if (!vt.useDeprecatedSynchronousErrorHandling) - throw new Error("bad call"); - try { - t.call(this._context, i) - } catch (t) { - return vt.useDeprecatedSynchronousErrorHandling ? (e.syncErrorValue = t, - e.syncErrorThrown = !0) : St(t), - !0 - } - return !1 - } - , - Rt.prototype._unsubscribe = function() { - var e = this._parentSubscriber; - this._context = null, - this._parentSubscriber = null, - e.unsubscribe() - } - , - Rt); - function Rt(e, t, i, r) { - var n, s = Ct.call(this) || this; - s._parentSubscriber = e; - e = s; - return gt(t) ? n = t : t && (n = t.next, - i = t.error, - r = t.complete, - t !== bt && (gt((e = Object.create(t)).unsubscribe) && s.add(e.unsubscribe.bind(e)), - e.unsubscribe = s.unsubscribe.bind(s))), - s._context = e, - s._next = n, - s._error = i, - s._complete = r, - s - } - function Lt(e, t, i) { - var r = Dt.call(this) || this; - switch (r.syncErrorValue = null, - r.syncErrorThrown = !1, - r.syncErrorThrowable = !1, - r.isStopped = !1, - arguments.length) { - case 0: - r.destination = bt; - break; - case 1: - if (!e) { - r.destination = bt; - break - } - if ("object" == typeof e) { - e instanceof Lt ? (r.syncErrorThrowable = e.syncErrorThrowable, - (r.destination = e).add(r)) : (r.syncErrorThrowable = !0, - r.destination = new xt(r,e)); - break - } - default: - r.syncErrorThrowable = !0, - r.destination = new xt(r,e,t,i) - } - return r - } - var _t = "function" == typeof Symbol && Symbol.observable || "@@observable"; - function Nt(e) { - return e - } - function Ft() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - return Bt(e) - } - function Bt(t) { - return 0 === t.length ? Nt : 1 === t.length ? t[0] : function(e) { - return t.reduce(function(e, t) { - return t(e) - }, e) - } - } - var Ut = ($t.prototype.lift = function(e) { - var t = new $t; - return t.source = this, - t.operator = e, - t - } - , - $t.prototype.subscribe = function(e, t, i) { - var r = this.operator - , i = function(e, t, i) { - if (e) { - if (e instanceof Pt) - return e; - if (e[Mt]) - return e[Mt]() - } - return e || t || i ? new Pt(e,t,i) : new Pt(bt) - }(e, t, i); - if (r ? i.add(r.call(i, this.source)) : i.add(this.source || vt.useDeprecatedSynchronousErrorHandling && !i.syncErrorThrowable ? this._subscribe(i) : this._trySubscribe(i)), - vt.useDeprecatedSynchronousErrorHandling && i.syncErrorThrowable && (i.syncErrorThrowable = !1, - i.syncErrorThrown)) - throw i.syncErrorValue; - return i - } - , - $t.prototype._trySubscribe = function(t) { - try { - return this._subscribe(t) - } catch (e) { - vt.useDeprecatedSynchronousErrorHandling && (t.syncErrorThrown = !0, - t.syncErrorValue = e), - function(e) { - for (; e; ) { - var t = e - , i = t.closed - , r = t.destination - , t = t.isStopped; - if (i || t) - return; - e = r && r instanceof Pt ? r : null - } - return 1 - }(t) ? t.error(e) : console.warn(e) - } - } - , - $t.prototype.forEach = function(r, e) { - var n = this; - return new (e = Vt(e))(function(e, t) { - var i = n.subscribe(function(e) { - try { - r(e) - } catch (e) { - t(e), - i && i.unsubscribe() - } - }, t, e) - } - ) - } - , - $t.prototype._subscribe = function(e) { - var t = this.source; - return t && t.subscribe(e) - } - , - $t.prototype[_t] = function() { - return this - } - , - $t.prototype.pipe = function() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - return 0 === e.length ? this : Bt(e)(this) - } - , - $t.prototype.toPromise = function(e) { - var r = this; - return new (e = Vt(e))(function(e, t) { - var i; - r.subscribe(function(e) { - return i = e - }, function(e) { - return t(e) - }, function() { - return e(i) - }) - } - ) - } - , - $t.create = function(e) { - return new $t(e) - } - , - $t); - function $t(e) { - this._isScalar = !1, - e && (this._subscribe = e) - } - function Vt(e) { - if (!(e = e || (vt.Promise || Promise))) - throw new Error("no Promise impl found"); - return e - } - var Kt, Ht, jt, qt, Qt = (ti.prototype = Object.create(Error.prototype), - ti), Gt = (lt(ei, qt = wt), - ei.prototype.unsubscribe = function() { - var e, t; - this.closed || (this.closed = !0, - e = (t = this.subject).observers, - this.subject = null, - !e || 0 === e.length || t.isStopped || t.closed || -1 !== (t = e.indexOf(this.subscriber)) && e.splice(t, 1)) - } - , - ei), Wt = (lt(Zt, jt = Pt), - Zt), zt = (lt(Jt, Ht = Ut), - Jt.prototype[Mt] = function() { - return new Wt(this) - } - , - Jt.prototype.lift = function(e) { - var t = new Xt(this,this); - return t.operator = e, - t - } - , - Jt.prototype.next = function(e) { - if (this.closed) - throw new Qt; - if (!this.isStopped) - for (var t = this.observers, i = t.length, r = t.slice(), n = 0; n < i; n++) - r[n].next(e) - } - , - Jt.prototype.error = function(e) { - if (this.closed) - throw new Qt; - this.hasError = !0, - this.thrownError = e, - this.isStopped = !0; - for (var t = this.observers, i = t.length, r = t.slice(), n = 0; n < i; n++) - r[n].error(e); - this.observers.length = 0 - } - , - Jt.prototype.complete = function() { - if (this.closed) - throw new Qt; - this.isStopped = !0; - for (var e = this.observers, t = e.length, i = e.slice(), r = 0; r < t; r++) - i[r].complete(); - this.observers.length = 0 - } - , - Jt.prototype.unsubscribe = function() { - this.isStopped = !0, - this.closed = !0, - this.observers = null - } - , - Jt.prototype._trySubscribe = function(e) { - if (this.closed) - throw new Qt; - return Ht.prototype._trySubscribe.call(this, e) - } - , - Jt.prototype._subscribe = function(e) { - if (this.closed) - throw new Qt; - return this.hasError ? (e.error(this.thrownError), - wt.EMPTY) : this.isStopped ? (e.complete(), - wt.EMPTY) : (this.observers.push(e), - new Gt(this,e)) - } - , - Jt.prototype.asObservable = function() { - var e = new Ut; - return e.source = this, - e - } - , - Jt.create = function(e, t) { - return new Xt(e,t) - } - , - Jt), Xt = (lt(Yt, Kt = zt), - Yt.prototype.next = function(e) { - var t = this.destination; - t && t.next && t.next(e) - } - , - Yt.prototype.error = function(e) { - var t = this.destination; - t && t.error && this.destination.error(e) - } - , - Yt.prototype.complete = function() { - var e = this.destination; - e && e.complete && this.destination.complete() - } - , - Yt.prototype._subscribe = function(e) { - return this.source ? this.source.subscribe(e) : wt.EMPTY - } - , - Yt); - function Yt(e, t) { - var i = Kt.call(this) || this; - return i.destination = e, - i.source = t, - i - } - function Jt() { - var e = Ht.call(this) || this; - return e.observers = [], - e.closed = !1, - e.isStopped = !1, - e.hasError = !1, - e.thrownError = null, - e - } - function Zt(e) { - var t = jt.call(this, e) || this; - return t.destination = e, - t - } - function ei(e, t) { - var i = qt.call(this) || this; - return i.subject = e, - i.subscriber = t, - i.closed = !1, - i - } - function ti() { - return Error.call(this), - this.message = "object unsubscribed", - this.name = "ObjectUnsubscribedError", - this - } - function ii() { - return function(e) { - return e.lift(new hi(e)) - } - } - var ri, ni, si, ai, oi, di, li, ui, ci, hi = (xi.prototype.call = function(e, t) { - var i = this.connectable; - i._refCount++; - e = new pi(e,i), - t = t.subscribe(e); - return e.closed || (e.connection = i.connect()), - t - } - , - xi), pi = (lt(Pi, ci = Pt), - Pi.prototype._unsubscribe = function() { - var e, t = this.connectable; - t ? (this.connectable = null, - (e = t._refCount) <= 0 ? this.connection = null : (t._refCount = e - 1, - 1 < e ? this.connection = null : (e = this.connection, - t = t._connection, - this.connection = null, - !t || e && t !== e || t.unsubscribe()))) : this.connection = null - } - , - Pi), w = (lt(Mi, ui = Ut), - Mi.prototype._subscribe = function(e) { - return this.getSubject().subscribe(e) - } - , - Mi.prototype.getSubject = function() { - var e = this._subject; - return e && !e.isStopped || (this._subject = this.subjectFactory()), - this._subject - } - , - Mi.prototype.connect = function() { - var e = this._connection; - return e || (this._isComplete = !1, - (e = this._connection = new wt).add(this.source.subscribe(new mi(this.getSubject(),this))), - e.closed && (this._connection = null, - e = wt.EMPTY)), - e - } - , - Mi.prototype.refCount = function() { - return ii()(this) - } - , - Mi), fi = { - operator: { - value: null - }, - _refCount: { - value: 0, - writable: !0 - }, - _subject: { - value: null, - writable: !0 - }, - _connection: { - value: null, - writable: !0 - }, - _subscribe: { - value: (pd = w.prototype)._subscribe - }, - _isComplete: { - value: pd._isComplete, - writable: !0 - }, - getSubject: { - value: pd.getSubject - }, - connect: { - value: pd.connect - }, - refCount: { - value: pd.refCount - } - }, mi = (lt(Di, li = Wt), - Di.prototype._error = function(e) { - this._unsubscribe(), - li.prototype._error.call(this, e) - } - , - Di.prototype._complete = function() { - this.connectable._isComplete = !0, - this._unsubscribe(), - li.prototype._complete.call(this) - } - , - Di.prototype._unsubscribe = function() { - var e, t = this.connectable; - t && (this.connectable = null, - e = t._connection, - t._refCount = 0, - t._subject = null, - t._connection = null, - e && e.unsubscribe()) - } - , - Di), gi = (lt(Ci, di = zt), - Object.defineProperty(Ci.prototype, "value", { - get: function() { - return this.getValue() - }, - enumerable: !0, - configurable: !0 - }), - Ci.prototype._subscribe = function(e) { - var t = di.prototype._subscribe.call(this, e); - return t && !t.closed && e.next(this._value), - t - } - , - Ci.prototype.getValue = function() { - if (this.hasError) - throw this.thrownError; - if (this.closed) - throw new Qt; - return this._value - } - , - Ci.prototype.next = function(e) { - di.prototype.next.call(this, this._value = e) - } - , - Ci), A = (lt(ki, oi = wt), - ki.prototype.schedule = function(e, t) { - return this - } - , - lt(Oi, ai = ki), - Oi.prototype.schedule = function(e, t) { - if (void 0 === t && (t = 0), - this.closed) - return this; - this.state = e; - var i = this.id - , e = this.scheduler; - return null != i && (this.id = this.recycleAsyncId(e, i, t)), - this.pending = !0, - this.delay = t, - this.id = this.id || this.requestAsyncId(e, this.id, t), - this - } - , - Oi.prototype.requestAsyncId = function(e, t, i) { - return void 0 === i && (i = 0), - setInterval(e.flush.bind(e, this), i) - } - , - Oi.prototype.recycleAsyncId = function(e, t, i) { - if (null !== (i = void 0 === i ? 0 : i) && this.delay === i && !1 === this.pending) - return t; - clearInterval(t) - } - , - Oi.prototype.execute = function(e, t) { - if (this.closed) - return new Error("executing a cancelled action"); - this.pending = !1; - t = this._execute(e, t); - if (t) - return t; - !1 === this.pending && null != this.id && (this.id = this.recycleAsyncId(this.scheduler, this.id, null)) - } - , - Oi.prototype._execute = function(e, t) { - var i = !1 - , r = void 0; - try { - this.work(e) - } catch (e) { - i = !0, - r = !!e && e || new Error(e) - } - if (i) - return this.unsubscribe(), - r - } - , - Oi.prototype._unsubscribe = function() { - var e = this.id - , t = this.scheduler - , i = t.actions - , r = i.indexOf(this); - this.work = null, - this.state = null, - this.pending = !1, - this.scheduler = null, - -1 !== r && i.splice(r, 1), - null != e && (this.id = this.recycleAsyncId(t, e, null)), - this.delay = null - } - , - Oi), yi = (lt(Ai, si = A), - Ai.prototype.schedule = function(e, t) { - return 0 < (t = void 0 === t ? 0 : t) ? si.prototype.schedule.call(this, e, t) : (this.delay = t, - this.state = e, - this.scheduler.flush(this), - this) - } - , - Ai.prototype.execute = function(e, t) { - return 0 < t || this.closed ? si.prototype.execute.call(this, e, t) : this._execute(e, t) - } - , - Ai.prototype.requestAsyncId = function(e, t, i) { - return null !== (i = void 0 === i ? 0 : i) && 0 < i || null === i && 0 < this.delay ? si.prototype.requestAsyncId.call(this, e, t, i) : e.flush(this) - } - , - Ai), vi = (wi.prototype.schedule = function(e, t, i) { - return void 0 === t && (t = 0), - new this.SchedulerAction(this,e).schedule(i, t) - } - , - wi.now = function() { - return Date.now() - } - , - wi), Si = (lt(Ii, ni = vi), - Ii.prototype.schedule = function(e, t, i) { - return void 0 === t && (t = 0), - Ii.delegate && Ii.delegate !== this ? Ii.delegate.schedule(e, t, i) : ni.prototype.schedule.call(this, e, t, i) - } - , - Ii.prototype.flush = function(e) { - var t, i = this.actions; - if (this.active) - i.push(e); - else { - this.active = !0; - do { - if (t = e.execute(e.state, e.delay)) - break - } while (e = i.shift()); - if (this.active = !1, - t) { - for (; e = i.shift(); ) - e.unsubscribe(); - throw t - } - } - } - , - Ii), bi = (lt(Ei, ri = Si), - new Ei(yi)), Ti = new Ut(function(e) { - return e.complete() - } + labels: { + 10: 'trace', + 20: 'debug', + 30: 'info', + 40: 'warn', + 50: 'error', + 60: 'fatal' + } + }; + + pino.stdSerializers = stdSerializers; + pino.stdTimeFunctions = Object.assign({}, { nullTime, epochTime, unixTime, isoTime }); + + function set$1 (opts, logger, level, fallback) { + const proto = Object.getPrototypeOf(logger); + logger[level] = logger.levelVal > logger.levels.values[level] + ? noop$2 + : (proto[level] ? proto[level] : (_console[level] || _console[fallback] || noop$2)); + + wrap(opts, logger, level); + } + + function wrap (opts, logger, level) { + if (!opts.transmit && logger[level] === noop$2) return + + logger[level] = (function (write) { + return function LOG () { + const ts = opts.timestamp(); + const args = new Array(arguments.length); + const proto = (Object.getPrototypeOf && Object.getPrototypeOf(this) === _console) ? _console : this; + for (var i = 0; i < args.length; i++) args[i] = arguments[i]; + + if (opts.serialize && !opts.asObject) { + applySerializers(args, this._serialize, this.serializers, this._stdErrSerialize); + } + if (opts.asObject) write.call(proto, asObject(this, level, args, ts)); + else write.apply(proto, args); + + if (opts.transmit) { + const transmitLevel = opts.transmit.level || logger.level; + const transmitValue = pino.levels.values[transmitLevel]; + const methodValue = pino.levels.values[level]; + if (methodValue < transmitValue) return + transmit(this, { + ts, + methodLevel: level, + methodValue, + transmitLevel, + transmitValue: pino.levels.values[opts.transmit.level || logger.level], + send: opts.transmit.send, + val: logger.levelVal + }, args); + } + } + })(logger[level]); + } + + function asObject (logger, level, args, ts) { + if (logger._serialize) applySerializers(args, logger._serialize, logger.serializers, logger._stdErrSerialize); + const argsCloned = args.slice(); + let msg = argsCloned[0]; + const o = {}; + if (ts) { + o.time = ts; + } + o.level = pino.levels.values[level]; + let lvl = (logger._childLevel | 0) + 1; + if (lvl < 1) lvl = 1; + // deliberate, catching objects, arrays + if (msg !== null && typeof msg === 'object') { + while (lvl-- && typeof argsCloned[0] === 'object') { + Object.assign(o, argsCloned.shift()); + } + msg = argsCloned.length ? format(argsCloned.shift(), argsCloned) : undefined; + } else if (typeof msg === 'string') msg = format(argsCloned.shift(), argsCloned); + if (msg !== undefined) o.msg = msg; + return o + } + + function applySerializers (args, serialize, serializers, stdErrSerialize) { + for (const i in args) { + if (stdErrSerialize && args[i] instanceof Error) { + args[i] = pino.stdSerializers.err(args[i]); + } else if (typeof args[i] === 'object' && !Array.isArray(args[i])) { + for (const k in args[i]) { + if (serialize && serialize.indexOf(k) > -1 && k in serializers) { + args[i][k] = serializers[k](args[i][k]); + } + } + } + } + } + + function bind (parent, bindings, level) { + return function () { + try{ + const args = new Array(1 + arguments.length); + args[0] = bindings; + for (var i = 1; i < args.length; i++) { + args[i] = arguments[i - 1]; + } + return parent[level].apply(this, args)} + catch(e){ + + } + } + } + + function transmit (logger, opts, args) { + const send = opts.send; + const ts = opts.ts; + const methodLevel = opts.methodLevel; + const methodValue = opts.methodValue; + const val = opts.val; + const bindings = logger._logEvent.bindings; + + applySerializers( + args, + logger._serialize || Object.keys(logger.serializers), + logger.serializers, + logger._stdErrSerialize === undefined ? true : logger._stdErrSerialize ); - function Ei() { - return null !== ri && ri.apply(this, arguments) || this - } - function Ii(e, t) { - void 0 === t && (t = vi.now); - var i = ni.call(this, e, function() { - return Ii.delegate && Ii.delegate !== i ? Ii.delegate.now() : t() - }) || this; - return i.actions = [], - i.active = !1, - i.scheduled = void 0, - i - } - function wi(e, t) { - void 0 === t && (t = wi.now), - this.SchedulerAction = e, - this.now = t - } - function Ai(e, t) { - var i = si.call(this, e, t) || this; - return i.scheduler = e, - i.work = t, - i - } - function Oi(e, t) { - var i = ai.call(this, e, t) || this; - return i.scheduler = e, - i.work = t, - i.pending = !1, - i - } - function ki(e, t) { - return oi.call(this) || this - } - function Ci(e) { - var t = di.call(this) || this; - return t._value = e, - t - } - function Di(e, t) { - e = li.call(this, e) || this; - return e.connectable = t, - e - } - function Mi(e, t) { - var i = ui.call(this) || this; - return i.source = e, - i.subjectFactory = t, - i._refCount = 0, - i._isComplete = !1, - i - } - function Pi(e, t) { - e = ci.call(this, e) || this; - return e.connectable = t, - e - } - function xi(e) { - this.connectable = e - } - function Ri(e) { - return e ? (t = e, - new Ut(function(e) { - return t.schedule(function() { - return e.complete() - }) - } - )) : Ti; - var t - } - function Li(e) { - return e && "function" == typeof e.schedule - } - var _i = function(r) { - return function(e) { - for (var t = 0, i = r.length; t < i && !e.closed; t++) - e.next(r[t]); - e.complete() - } - }; - function Ni(r, n) { - return new Ut(function(e) { - var t = new wt - , i = 0; - return t.add(n.schedule(function() { - i !== r.length ? (e.next(r[i++]), - e.closed || t.add(this.schedule())) : e.complete() - })), - t - } - ) - } - function Fi(e, t) { - return t ? Ni(e, t) : new Ut(_i(e)) - } - function Bi() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - var i = e[e.length - 1]; - return Li(i) ? (e.pop(), - Ni(e, i)) : Fi(e) - } - function Ui(t, i) { - return new Ut(i ? function(e) { - return i.schedule($i, 0, { - error: t, - subscriber: e - }) - } - : function(e) { - return e.error(t) - } - ) - } - function $i(e) { - var t = e.error; - e.subscriber.error(t) - } - var Vi = (Ki.prototype.observe = function(e) { - switch (this.kind) { - case "N": - return e.next && e.next(this.value); - case "E": - return e.error && e.error(this.error); - case "C": - return e.complete && e.complete() - } - } - , - Ki.prototype.do = function(e, t, i) { - switch (this.kind) { - case "N": - return e && e(this.value); - case "E": - return t && t(this.error); - case "C": - return i && i() - } - } - , - Ki.prototype.accept = function(e, t, i) { - return e && "function" == typeof e.next ? this.observe(e) : this.do(e, t, i) - } - , - Ki.prototype.toObservable = function() { - switch (this.kind) { - case "N": - return Bi(this.value); - case "E": - return Ui(this.error); - case "C": - return Ri() - } - throw new Error("unexpected notification kind value") - } - , - Ki.createNext = function(e) { - return void 0 !== e ? new Ki("N",e) : Ki.undefinedValueNotification - } - , - Ki.createError = function(e) { - return new Ki("E",void 0,e) - } - , - Ki.createComplete = function() { - return Ki.completeNotification - } - , - Ki.completeNotification = new Ki("C"), - Ki.undefinedValueNotification = new Ki("N",void 0), - Ki); - function Ki(e, t, i) { - this.kind = e, - this.value = t, - this.error = i, - this.hasValue = "N" === e - } - function Hi(t, i) { - return void 0 === i && (i = 0), - function(e) { - return e.lift(new Gi(t,i)) - } - } - var ji, qi, Qi, Gi = (nr.prototype.call = function(e, t) { - return t.subscribe(new Wi(e,this.scheduler,this.delay)) - } - , - nr), Wi = (lt(rr, Qi = Pt), - rr.dispatch = function(e) { - var t = e.notification - , e = e.destination; - t.observe(e), - this.unsubscribe() - } - , - rr.prototype.scheduleMessage = function(e) { - this.destination.add(this.scheduler.schedule(rr.dispatch, this.delay, new zi(e,this.destination))) - } - , - rr.prototype._next = function(e) { - this.scheduleMessage(Vi.createNext(e)) - } - , - rr.prototype._error = function(e) { - this.scheduleMessage(Vi.createError(e)), - this.unsubscribe() - } - , - rr.prototype._complete = function() { - this.scheduleMessage(Vi.createComplete()), - this.unsubscribe() - } - , - rr), zi = function(e, t) { - this.notification = e, - this.destination = t - }, Xi = (lt(ir, qi = zt), - ir.prototype.nextInfiniteTimeWindow = function(e) { - var t; - this.isStopped || ((t = this._events).push(e), - t.length > this._bufferSize && t.shift()), - qi.prototype.next.call(this, e) - } - , - ir.prototype.nextTimeWindow = function(e) { - this.isStopped || (this._events.push(new Yi(this._getNow(),e)), - this._trimBufferThenGetEvents()), - qi.prototype.next.call(this, e) - } - , - ir.prototype._subscribe = function(e) { - var t, i = this._infiniteTimeWindow, r = i ? this._events : this._trimBufferThenGetEvents(), n = this.scheduler, s = r.length; - if (this.closed) - throw new Qt; - if (t = this.isStopped || this.hasError ? wt.EMPTY : (this.observers.push(e), - new Gt(this,e)), - n && e.add(e = new Wi(e,n)), - i) - for (var a = 0; a < s && !e.closed; a++) - e.next(r[a]); - else - for (a = 0; a < s && !e.closed; a++) - e.next(r[a].value); - return this.hasError ? e.error(this.thrownError) : this.isStopped && e.complete(), - t - } - , - ir.prototype._getNow = function() { - return (this.scheduler || bi).now() - } - , - ir.prototype._trimBufferThenGetEvents = function() { - for (var e = this._getNow(), t = this._bufferSize, i = this._windowTime, r = this._events, n = r.length, s = 0; s < n && !(e - r[s].time < i); ) - s++; - return 0 < (s = t < n ? Math.max(s, n - t) : s) && r.splice(0, s), - r - } - , - ir), Yi = function(e, t) { - this.time = e, - this.value = t - }, Ji = (lt(tr, ji = zt), - tr.prototype._subscribe = function(e) { - return this.hasError ? (e.error(this.thrownError), - wt.EMPTY) : this.hasCompleted && this.hasNext ? (e.next(this.value), - e.complete(), - wt.EMPTY) : ji.prototype._subscribe.call(this, e) - } - , - tr.prototype.next = function(e) { - this.hasCompleted || (this.value = e, - this.hasNext = !0) - } - , - tr.prototype.error = function(e) { - this.hasCompleted || ji.prototype.error.call(this, e) - } - , - tr.prototype.complete = function() { - this.hasCompleted = !0, - this.hasNext && ji.prototype.next.call(this, this.value), - ji.prototype.complete.call(this) - } - , - tr), Zi = new Si(A), er = Zi; - function tr() { - var e = null !== ji && ji.apply(this, arguments) || this; - return e.value = null, - e.hasNext = !1, - e.hasCompleted = !1, - e - } - function ir(e, t, i) { - void 0 === e && (e = Number.POSITIVE_INFINITY), - void 0 === t && (t = Number.POSITIVE_INFINITY); - var r = qi.call(this) || this; - return r.scheduler = i, - r._events = [], - r._infiniteTimeWindow = !1, - r._bufferSize = e < 1 ? 1 : e, - r._windowTime = t < 1 ? 1 : t, - t === Number.POSITIVE_INFINITY ? (r._infiniteTimeWindow = !0, - r.next = r.nextInfiniteTimeWindow) : r.next = r.nextTimeWindow, - r - } - function rr(e, t, i) { - void 0 === i && (i = 0); - e = Qi.call(this, e) || this; - return e.scheduler = t, - e.delay = i, - e - } - function nr(e, t) { - void 0 === t && (t = 0), - this.scheduler = e, - this.delay = t - } - function sr() {} - var ar = (lr.prototype = Object.create(Error.prototype), - lr) - , or = (dr.prototype = Object.create(Error.prototype), - dr); - function dr() { - return Error.call(this), - this.message = "Timeout has occurred", - this.name = "TimeoutError", - this - } - function lr() { - return Error.call(this), - this.message = "argument out of range", - this.name = "ArgumentOutOfRangeError", - this - } - function ur(t, i) { - return function(e) { - if ("function" != typeof t) - throw new TypeError("argument is not a function. Are you looking for `mapTo()`?"); - return e.lift(new fr(t,i)) - } - } - var cr, hr, pr, fr = (Tr.prototype.call = function(e, t) { - return t.subscribe(new mr(e,this.project,this.thisArg)) - } - , - Tr), mr = (lt(br, pr = Pt), - br.prototype._next = function(e) { - var t; - try { - t = this.project.call(this.thisArg, e, this.count++) - } catch (e) { - return void this.destination.error(e) - } - this.destination.next(t) - } - , - br), gr = (lt(Sr, hr = Pt), - Sr.prototype.notifyNext = function(e, t, i, r, n) { - this.destination.next(t) - } - , - Sr.prototype.notifyError = function(e, t) { - this.destination.error(e) - } - , - Sr.prototype.notifyComplete = function(e) { - this.destination.complete() - } - , - Sr), yr = (lt(vr, cr = Pt), - vr.prototype._next = function(e) { - this.parent.notifyNext(this.outerValue, e, this.outerIndex, this.index++, this) - } - , - vr.prototype._error = function(e) { - this.parent.notifyError(e, this), - this.unsubscribe() - } - , - vr.prototype._complete = function() { - this.parent.notifyComplete(this), - this.unsubscribe() - } - , - vr); - function vr(e, t, i) { - var r = cr.call(this) || this; - return r.parent = e, - r.outerValue = t, - r.outerIndex = i, - r.index = 0, - r - } - function Sr() { - return null !== hr && hr.apply(this, arguments) || this - } - function br(e, t, i) { - e = pr.call(this, e) || this; - return e.project = t, - e.count = 0, - e.thisArg = i || e, - e - } - function Tr(e, t) { - this.project = e, - this.thisArg = t - } - var Er = "function" == typeof Symbol && Symbol.iterator ? Symbol.iterator : "@@iterator" - , Ir = function(e) { - return e && "number" == typeof e.length && "function" != typeof e - }; - function wr(e) { - return e && "function" != typeof e.subscribe && "function" == typeof e.then - } - var Ar = function(e) { - if (e && "function" == typeof e[_t]) - return n = e, - function(e) { - var t = n[_t](); - if ("function" != typeof t.subscribe) - throw new TypeError("Provided object does not correctly implement Symbol.observable"); - return t.subscribe(e) - } - ; - if (Ir(e)) - return _i(e); - if (wr(e)) - return i = e, - function(t) { - return i.then(function(e) { - t.closed || (t.next(e), - t.complete()) - }, function(e) { - return t.error(e) - }).then(null, St), - t - } - ; - if (e && "function" == typeof e[Er]) - return r = e, - function(t) { - for (var e = r[Er](); ; ) { - var i = void 0; - try { - i = e.next() - } catch (e) { - return t.error(e), - t - } - if (i.done) { - t.complete(); - break - } - if (t.next(i.value), - t.closed) - break - } - return "function" == typeof e.return && t.add(function() { - e.return && e.return() - }), - t - } - ; - var r, i, n, e = Et(e) ? "an invalid object" : "'" + e + "'"; - throw new TypeError("You provided " + e + " where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.") - }; - function Or(e, t, i, r, n) { - if (!(n = void 0 === n ? new yr(e,i,r) : n).closed) - return t instanceof Ut ? t.subscribe(n) : Ar(t)(n) - } - var kr = {}; - function Cr() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - var i = void 0 - , r = void 0; - return Li(e[e.length - 1]) && (r = e.pop()), - "function" == typeof e[e.length - 1] && (i = e.pop()), - Fi(e = 1 === e.length && Tt(e[0]) ? e[0] : e, r).lift(new Mr(i)) - } - var Dr, Mr = (Rr.prototype.call = function(e, t) { - return t.subscribe(new Pr(e,this.resultSelector)) - } - , - Rr), Pr = (lt(xr, Dr = gr), - xr.prototype._next = function(e) { - this.values.push(kr), - this.observables.push(e) - } - , - xr.prototype._complete = function() { - var e = this.observables - , t = e.length; - if (0 === t) - this.destination.complete(); - else { - this.active = t, - this.toRespond = t; - for (var i = 0; i < t; i++) { - var r = e[i]; - this.add(Or(this, r, void 0, i)) - } - } - } - , - xr.prototype.notifyComplete = function(e) { - 0 == --this.active && this.destination.complete() - } - , - xr.prototype.notifyNext = function(e, t, i) { - var r = this.values - , n = r[i] - , n = this.toRespond ? n === kr ? --this.toRespond : this.toRespond : 0; - r[i] = t, - 0 === n && (this.resultSelector ? this._tryResultSelector(r) : this.destination.next(r.slice())) - } - , - xr.prototype._tryResultSelector = function(e) { - var t; - try { - t = this.resultSelector.apply(this, e) - } catch (e) { - return void this.destination.error(e) - } - this.destination.next(t) - } - , - xr); - function xr(e, t) { - e = Dr.call(this, e) || this; - return e.resultSelector = t, - e.active = 0, - e.values = [], - e.observables = [], - e - } - function Rr(e) { - this.resultSelector = e - } - function Lr(e, t) { - return t ? function(e, t) { - if (null != e) { - if (e && "function" == typeof e[_t]) - return s = e, - a = t, - new Ut(function(t) { - var i = new wt; - return i.add(a.schedule(function() { - var e = s[_t](); - i.add(e.subscribe({ - next: function(e) { - i.add(a.schedule(function() { - return t.next(e) - })) - }, - error: function(e) { - i.add(a.schedule(function() { - return t.error(e) - })) - }, - complete: function() { - i.add(a.schedule(function() { - return t.complete() - })) - } - })) - })), - i - } - ); - if (wr(e)) - return r = e, - n = t, - new Ut(function(t) { - var i = new wt; - return i.add(n.schedule(function() { - return r.then(function(e) { - i.add(n.schedule(function() { - t.next(e), - i.add(n.schedule(function() { - return t.complete() - })) - })) - }, function(e) { - i.add(n.schedule(function() { - return t.error(e) - })) - }) - })), - i - } - ); - if (Ir(e)) - return Ni(e, t); - if (e && "function" == typeof e[Er] || "string" == typeof e) - return function(t, i) { - if (!t) - throw new Error("Iterable cannot be null"); - return new Ut(function(r) { - var n, e = new wt; - return e.add(function() { - n && "function" == typeof n.return && n.return() - }), - e.add(i.schedule(function() { - n = t[Er](), - e.add(i.schedule(function() { - if (!r.closed) { - try { - var e = n.next() - , t = e.value - , i = e.done - } catch (t) { - return void r.error(t) - } - i ? r.complete() : (r.next(t), - this.schedule()) - } - })) - })), - e - } - ) - }(e, t) - } - var r, n, s, a; - throw new TypeError((null !== e && typeof e || e) + " is not observable") - }(e, t) : e instanceof Ut ? e : new Ut(Ar(e)) - } - var _r, Nr, Fr = (lt($r, Nr = Pt), - $r.prototype._next = function(e) { - this.parent.notifyNext(e) - } - , - $r.prototype._error = function(e) { - this.parent.notifyError(e), - this.unsubscribe() - } - , - $r.prototype._complete = function() { - this.parent.notifyComplete(), - this.unsubscribe() - } - , - $r), Br = (lt(Ur, _r = Pt), - Ur.prototype.notifyNext = function(e) { - this.destination.next(e) - } - , - Ur.prototype.notifyError = function(e) { - this.destination.error(e) - } - , - Ur.prototype.notifyComplete = function() { - this.destination.complete() - } - , - Ur); - function Ur() { - return null !== _r && _r.apply(this, arguments) || this - } - function $r(e) { - var t = Nr.call(this) || this; - return t.parent = e, - t - } - function Vr(e, t) { - if (!t.closed) - return e instanceof Ut ? e.subscribe(t) : Ar(e)(t) - } - function Kr(t, n, i) { - return void 0 === i && (i = Number.POSITIVE_INFINITY), - "function" == typeof n ? function(e) { - return e.pipe(Kr(function(i, r) { - return Lr(t(i, r)).pipe(ur(function(e, t) { - return n(i, e, r, t) - })) - }, i)) - } - : ("number" == typeof n && (i = n), - function(e) { - return e.lift(new jr(t,i)) - } - ) - } - var Hr, jr = (Gr.prototype.call = function(e, t) { - return t.subscribe(new qr(e,this.project,this.concurrent)) - } - , - Gr), qr = (lt(Qr, Hr = Br), - Qr.prototype._next = function(e) { - this.active < this.concurrent ? this._tryNext(e) : this.buffer.push(e) - } - , - Qr.prototype._tryNext = function(e) { - var t, i = this.index++; - try { - t = this.project(e, i) - } catch (e) { - return void this.destination.error(e) - } - this.active++, - this._innerSub(t) - } - , - Qr.prototype._innerSub = function(e) { - var t = new Fr(this) - , i = this.destination; - i.add(t); - e = Vr(e, t); - e !== t && i.add(e) - } - , - Qr.prototype._complete = function() { - this.hasCompleted = !0, - 0 === this.active && 0 === this.buffer.length && this.destination.complete(), - this.unsubscribe() - } - , - Qr.prototype.notifyNext = function(e) { - this.destination.next(e) - } - , - Qr.prototype.notifyComplete = function() { - var e = this.buffer; - this.active--, - 0 < e.length ? this._next(e.shift()) : 0 === this.active && this.hasCompleted && this.destination.complete() - } - , - Qr); - function Qr(e, t, i) { - void 0 === i && (i = Number.POSITIVE_INFINITY); - e = Hr.call(this, e) || this; - return e.project = t, - e.concurrent = i, - e.hasCompleted = !1, - e.buffer = [], - e.active = 0, - e.index = 0, - e - } - function Gr(e, t) { - void 0 === t && (t = Number.POSITIVE_INFINITY), - this.project = e, - this.concurrent = t - } - function Wr(e) { - return Kr(Nt, e = void 0 === e ? Number.POSITIVE_INFINITY : e) - } - function zr() { - return Wr(1) - } - function Xr() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - return zr()(Bi.apply(void 0, e)) - } - function Yr(i) { - return new Ut(function(t) { - var e; - try { - e = i() - } catch (e) { - return void t.error(e) - } - return (e ? Lr(e) : Ri()).subscribe(t) - } - ) - } - function Jr() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - if (1 === e.length) { - var i = e[0]; - if (Tt(i)) - return Zr(i, null); - if (Et(i) && Object.getPrototypeOf(i) === Object.prototype) { - var r = Object.keys(i); - return Zr(r.map(function(e) { - return i[e] - }), r) - } - } - if ("function" != typeof e[e.length - 1]) - return Zr(e, null); - var n = e.pop(); - return Zr(e = 1 === e.length && Tt(e[0]) ? e[0] : e, null).pipe(ur(function(e) { - return n.apply(void 0, e) - })) - } - function Zr(d, l) { - return new Ut(function(r) { - var n = d.length; - if (0 !== n) - for (var s = new Array(n), a = 0, o = 0, e = 0; e < n; e++) - !function(t) { - var e = Lr(d[t]) - , i = !1; - r.add(e.subscribe({ - next: function(e) { - i || (i = !0, - o++), - s[t] = e - }, - error: function(e) { - return r.error(e) - }, - complete: function() { - ++a !== n && i || (o === n && r.next(l ? l.reduce(function(e, t, i) { - return e[t] = s[i], - e - }, {}) : s), - r.complete()) - } - })) - }(e); - else - r.complete() - } - ) - } - function en(e, i, r, t) { - return gt(r) && (t = r, - r = void 0), - t ? en(e, i, r).pipe(ur(function(e) { - return Tt(e) ? t.apply(void 0, e) : t(e) - })) : new Ut(function(t) { - !function e(t, i, r, n, s) { - var a; - if (function(e) { - return e && "function" == typeof e.addEventListener && "function" == typeof e.removeEventListener - }(t)) { - var o = t; - t.addEventListener(i, r, s), - a = function() { - return o.removeEventListener(i, r, s) - } - } else if (function(e) { - return e && "function" == typeof e.on && "function" == typeof e.off - }(t)) { - var d = t; - t.on(i, r), - a = function() { - return d.off(i, r) - } - } else if (function(e) { - return e && "function" == typeof e.addListener && "function" == typeof e.removeListener - }(t)) { - var l = t; - t.addListener(i, r), - a = function() { - return l.removeListener(i, r) - } - } else { - if (!t || !t.length) - throw new TypeError("Invalid event target"); - for (var u = 0, c = t.length; u < c; u++) - e(t[u], i, r, n, s) - } - n.add(a) - }(e, i, function(e) { - 1 < arguments.length ? t.next(Array.prototype.slice.call(arguments)) : t.next(e) - }, t, r) - } - ) - } - function tn(e, t, i) { - return void 0 === t && (t = Ti), - void 0 === i && (i = Ti), - Yr(function() { - return e() ? t : i - }) - } - function rn(e) { - return !Tt(e) && 0 <= e - parseFloat(e) + 1 - } - function nn() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - var i = Number.POSITIVE_INFINITY - , r = null - , n = e[e.length - 1]; - return Li(n) ? (r = e.pop(), - 1 < e.length && "number" == typeof e[e.length - 1] && (i = e.pop())) : "number" == typeof n && (i = e.pop()), - null === r && 1 === e.length && e[0]instanceof Ut ? e[0] : Wr(i)(Fi(e, r)) - } - var sn = new Ut(sr); - function an(t, i) { - return function(e) { - return e.lift(new dn(t,i)) - } - } - var on, dn = (cn.prototype.call = function(e, t) { - return t.subscribe(new ln(e,this.predicate,this.thisArg)) - } - , - cn), ln = (lt(un, on = Pt), - un.prototype._next = function(e) { - var t; - try { - t = this.predicate.call(this.thisArg, e, this.count++) - } catch (e) { - return void this.destination.error(e) - } - t && this.destination.next(e) - } - , - un); - function un(e, t, i) { - e = on.call(this, e) || this; - return e.predicate = t, - e.thisArg = i, - e.count = 0, - e - } - function cn(e, t) { - this.predicate = e, - this.thisArg = t - } - function hn() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - if (1 === e.length) { - if (!Tt(e[0])) - return e[0]; - e = e[0] - } - return Fi(e, void 0).lift(new fn) - } - var pn, fn = (yn.prototype.call = function(e, t) { - return t.subscribe(new mn(e)) - } - , - yn), mn = (lt(gn, pn = gr), - gn.prototype._next = function(e) { - this.observables.push(e) - } - , - gn.prototype._complete = function() { - var e = this.observables - , t = e.length; - if (0 === t) - this.destination.complete(); - else { - for (var i = 0; i < t && !this.hasFirst; i++) { - var r = Or(this, e[i], void 0, i); - this.subscriptions && this.subscriptions.push(r), - this.add(r) - } - this.observables = null - } - } - , - gn.prototype.notifyNext = function(e, t, i) { - if (!this.hasFirst) { - this.hasFirst = !0; - for (var r, n = 0; n < this.subscriptions.length; n++) - n !== i && ((r = this.subscriptions[n]).unsubscribe(), - this.remove(r)); - this.subscriptions = null - } - this.destination.next(t) - } - , - gn); - function gn(e) { - e = pn.call(this, e) || this; - return e.hasFirst = !1, - e.observables = [], - e.subscriptions = [], - e - } - function yn() {} - function vn(i, e, r) { - void 0 === i && (i = 0); - var n = -1; - return rn(e) ? n = Number(e) < 1 ? 1 : Number(e) : Li(e) && (r = e), - Li(r) || (r = er), - new Ut(function(e) { - var t = rn(i) ? i : +i - r.now(); - return r.schedule(Sn, t, { - index: 0, - period: n, - subscriber: e - }) - } - ) - } - function Sn(e) { - var t = e.index - , i = e.period - , r = e.subscriber; - if (r.next(t), - !r.closed) { - if (-1 === i) - return r.complete(); - e.index = t + 1, - this.schedule(e, i) - } - } - function bn() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - var i = e[e.length - 1]; - return "function" == typeof i && e.pop(), - Fi(e, void 0).lift(new In(i)) - } - var Tn, En, In = (xn.prototype.call = function(e, t) { - return t.subscribe(new wn(e,this.resultSelector)) - } - , - xn), wn = (lt(Pn, En = Pt), - Pn.prototype._next = function(e) { - var t = this.iterators; - Tt(e) ? t.push(new On(e)) : "function" == typeof e[Er] ? t.push(new An(e[Er]())) : t.push(new kn(this.destination,this,e)) - } - , - Pn.prototype._complete = function() { - var e = this.iterators - , t = e.length; - if (this.unsubscribe(), - 0 !== t) { - this.active = t; - for (var i = 0; i < t; i++) { - var r = e[i]; - r.stillUnsubscribed ? this.destination.add(r.subscribe()) : this.active-- - } - } else - this.destination.complete() - } - , - Pn.prototype.notifyInactive = function() { - this.active--, - 0 === this.active && this.destination.complete() - } - , - Pn.prototype.checkIterators = function() { - for (var e = this.iterators, t = e.length, i = this.destination, r = 0; r < t; r++) - if ("function" == typeof (a = e[r]).hasValue && !a.hasValue()) - return; - for (var n = !1, s = [], r = 0; r < t; r++) { - var a, o = (a = e[r]).next(); - if (a.hasCompleted() && (n = !0), - o.done) - return void i.complete(); - s.push(o.value) - } - this.resultSelector ? this._tryresultSelector(s) : i.next(s), - n && i.complete() - } - , - Pn.prototype._tryresultSelector = function(e) { - var t; - try { - t = this.resultSelector.apply(this, e) - } catch (e) { - return void this.destination.error(e) - } - this.destination.next(t) - } - , - Pn), An = (Mn.prototype.hasValue = function() { - return !0 - } - , - Mn.prototype.next = function() { - var e = this.nextResult; - return this.nextResult = this.iterator.next(), - e - } - , - Mn.prototype.hasCompleted = function() { - var e = this.nextResult; - return Boolean(e && e.done) - } - , - Mn), On = (Dn.prototype[Er] = function() { - return this - } - , - Dn.prototype.next = function(e) { - var t = this.index++ - , i = this.array; - return t < this.length ? { - value: i[t], - done: !1 - } : { - value: null, - done: !0 - } - } - , - Dn.prototype.hasValue = function() { - return this.array.length > this.index - } - , - Dn.prototype.hasCompleted = function() { - return this.array.length === this.index - } - , - Dn), kn = (lt(Cn, Tn = Br), - Cn.prototype[Er] = function() { - return this - } - , - Cn.prototype.next = function() { - var e = this.buffer; - return 0 === e.length && this.isComplete ? { - value: null, - done: !0 - } : { - value: e.shift(), - done: !1 - } - } - , - Cn.prototype.hasValue = function() { - return 0 < this.buffer.length - } - , - Cn.prototype.hasCompleted = function() { - return 0 === this.buffer.length && this.isComplete - } - , - Cn.prototype.notifyComplete = function() { - 0 < this.buffer.length ? (this.isComplete = !0, - this.parent.notifyInactive()) : this.destination.complete() - } - , - Cn.prototype.notifyNext = function(e) { - this.buffer.push(e), - this.parent.checkIterators() - } - , - Cn.prototype.subscribe = function() { - return Vr(this.observable, new Fr(this)) - } - , - Cn); - function Cn(e, t, i) { - e = Tn.call(this, e) || this; - return e.parent = t, - e.observable = i, - e.stillUnsubscribed = !0, - e.buffer = [], - e.isComplete = !1, - e - } - function Dn(e) { - this.array = e, - this.index = 0, - this.length = 0, - this.length = e.length - } - function Mn(e) { - this.iterator = e, - this.nextResult = e.next() - } - function Pn(e, t, i) { - e = En.call(this, e) || this; - return e.resultSelector = t, - e.iterators = [], - e.active = 0, - e.resultSelector = "function" == typeof t ? t : void 0, - e - } - function xn(e) { - this.resultSelector = e - } - var Rn, Ln = (Fn.prototype.call = function(e, t) { - return t.subscribe(new _n(e,this.durationSelector)) - } - , - Fn), _n = (lt(Nn, Rn = Br), - Nn.prototype._next = function(e) { - if (this.value = e, - this.hasValue = !0, - !this.throttled) { - var t = void 0; - try { - t = (0, - this.durationSelector)(e) - } catch (e) { - return this.destination.error(e) - } - t = Vr(t, new Fr(this)); - !t || t.closed ? this.clearThrottle() : this.add(this.throttled = t) - } - } - , - Nn.prototype.clearThrottle = function() { - var e = this.value - , t = this.hasValue - , i = this.throttled; - i && (this.remove(i), - this.throttled = void 0, - i.unsubscribe()), - t && (this.value = void 0, - this.hasValue = !1, - this.destination.next(e)) - } - , - Nn.prototype.notifyNext = function() { - this.clearThrottle() - } - , - Nn.prototype.notifyComplete = function() { - this.clearThrottle() - } - , - Nn); - function Nn(e, t) { - e = Rn.call(this, e) || this; - return e.durationSelector = t, - e.hasValue = !1, - e - } - function Fn(e) { - this.durationSelector = e - } - function Bn(e, t) { - return void 0 === t && (t = er), - i = function() { - return vn(e, t) - } - , - function(e) { - return e.lift(new Ln(i)) - } - ; - var i - } - function Un(i) { - return function(e) { - var t = new Vn(i) - , e = e.lift(t); - return t.caught = e - } - } - var $n, Vn = (jn.prototype.call = function(e, t) { - return t.subscribe(new Kn(e,this.selector,this.caught)) - } - , - jn), Kn = (lt(Hn, $n = Br), - Hn.prototype.error = function(e) { - if (!this.isStopped) { - var t = void 0; - try { - t = this.selector(e, this.caught) - } catch (e) { - return void $n.prototype.error.call(this, e) - } - this._unsubscribeAndRecycle(); - var i = new Fr(this); - this.add(i); - t = Vr(t, i); - t !== i && this.add(t) - } - } - , - Hn); - function Hn(e, t, i) { - e = $n.call(this, e) || this; - return e.selector = t, - e.caught = i, - e - } - function jn(e) { - this.selector = e - } - function qn(e, t) { - return Kr(e, t, 1) - } - function Qn(t, i) { - return void 0 === i && (i = er), - function(e) { - return e.lift(new Wn(t,i)) - } - } - var Gn, Wn = (Yn.prototype.call = function(e, t) { - return t.subscribe(new zn(e,this.dueTime,this.scheduler)) - } - , - Yn), zn = (lt(Xn, Gn = Pt), - Xn.prototype._next = function(e) { - this.clearDebounce(), - this.lastValue = e, - this.hasValue = !0, - this.add(this.debouncedSubscription = this.scheduler.schedule(Jn, this.dueTime, this)) - } - , - Xn.prototype._complete = function() { - this.debouncedNext(), - this.destination.complete() - } - , - Xn.prototype.debouncedNext = function() { - var e; - this.clearDebounce(), - this.hasValue && (e = this.lastValue, - this.lastValue = null, - this.hasValue = !1, - this.destination.next(e)) - } - , - Xn.prototype.clearDebounce = function() { - var e = this.debouncedSubscription; - null !== e && (this.remove(e), - e.unsubscribe(), - this.debouncedSubscription = null) - } - , - Xn); - function Xn(e, t, i) { - e = Gn.call(this, e) || this; - return e.dueTime = t, - e.scheduler = i, - e.debouncedSubscription = null, - e.lastValue = null, - e.hasValue = !1, - e - } - function Yn(e, t) { - this.dueTime = e, - this.scheduler = t - } - function Jn(e) { - e.debouncedNext() - } - var Zn, es = (rs.prototype.call = function(e, t) { - return t.subscribe(new ts(e,this.defaultValue)) - } - , - rs), ts = (lt(is, Zn = Pt), - is.prototype._next = function(e) { - this.isEmpty = !1, - this.destination.next(e) - } - , - is.prototype._complete = function() { - this.isEmpty && this.destination.next(this.defaultValue), - this.destination.complete() - } - , - is); - function is(e, t) { - e = Zn.call(this, e) || this; - return e.defaultValue = t, - e.isEmpty = !0, - e - } - function rs(e) { - this.defaultValue = e - } - function ns(e) { - return e instanceof Date && !isNaN(+e) - } - function ss(e, t) { - void 0 === t && (t = er); - var i = ns(e) ? +e - t.now() : Math.abs(e); - return function(e) { - return e.lift(new os(i,t)) - } - } - var as, os = (cs.prototype.call = function(e, t) { - return t.subscribe(new ds(e,this.delay,this.scheduler)) - } - , - cs), ds = (lt(us, as = Pt), - us.dispatch = function(e) { - for (var t, i = e.source, r = i.queue, n = e.scheduler, s = e.destination; 0 < r.length && r[0].time - n.now() <= 0; ) - r.shift().notification.observe(s); - 0 < r.length ? (t = Math.max(0, r[0].time - n.now()), - this.schedule(e, t)) : (this.unsubscribe(), - i.active = !1) - } - , - us.prototype._schedule = function(e) { - this.active = !0, - this.destination.add(e.schedule(us.dispatch, this.delay, { - source: this, - destination: this.destination, - scheduler: e - })) - } - , - us.prototype.scheduleNotification = function(e) { - var t; - !0 !== this.errored && (t = this.scheduler, - e = new ls(t.now() + this.delay,e), - this.queue.push(e), - !1 === this.active && this._schedule(t)) - } - , - us.prototype._next = function(e) { - this.scheduleNotification(Vi.createNext(e)) - } - , - us.prototype._error = function(e) { - this.errored = !0, - this.queue = [], - this.destination.error(e), - this.unsubscribe() - } - , - us.prototype._complete = function() { - this.scheduleNotification(Vi.createComplete()), - this.unsubscribe() - } - , - us), ls = function(e, t) { - this.time = e, - this.notification = t - }; - function us(e, t, i) { - e = as.call(this, e) || this; - return e.delay = t, - e.scheduler = i, - e.queue = [], - e.active = !1, - e.errored = !1, - e - } - function cs(e, t) { - this.delay = e, - this.scheduler = t - } - var hs, ps, fs, ms = (Ts.prototype.call = function(e, t) { - return t.subscribe(new gs(e,this.delayDurationSelector)) - } - , - Ts), gs = (lt(bs, fs = gr), - bs.prototype.notifyNext = function(e, t, i, r, n) { - this.destination.next(e), - this.removeSubscription(n), - this.tryComplete() - } - , - bs.prototype.notifyError = function(e, t) { - this._error(e) - } - , - bs.prototype.notifyComplete = function(e) { - e = this.removeSubscription(e); - e && this.destination.next(e), - this.tryComplete() - } - , - bs.prototype._next = function(e) { - var t = this.index++; - try { - var i = this.delayDurationSelector(e, t); - i && this.tryDelay(i, e) - } catch (e) { - this.destination.error(e) - } - } - , - bs.prototype._complete = function() { - this.completed = !0, - this.tryComplete(), - this.unsubscribe() - } - , - bs.prototype.removeSubscription = function(e) { - e.unsubscribe(); - var t = this.delayNotifierSubscriptions.indexOf(e); - return -1 !== t && this.delayNotifierSubscriptions.splice(t, 1), - e.outerValue - } - , - bs.prototype.tryDelay = function(e, t) { - t = Or(this, e, t); - t && !t.closed && (this.destination.add(t), - this.delayNotifierSubscriptions.push(t)) - } - , - bs.prototype.tryComplete = function() { - this.completed && 0 === this.delayNotifierSubscriptions.length && this.destination.complete() - } - , - bs), ys = (lt(Ss, ps = Ut), - Ss.prototype._subscribe = function(e) { - this.subscriptionDelay.subscribe(new ys(e,this.source)) - } - , - lt(vs, hs = Pt), - vs.prototype._next = function(e) { - this.subscribeToSource() - } - , - vs.prototype._error = function(e) { - this.unsubscribe(), - this.parent.error(e) - } - , - vs.prototype._complete = function() { - this.unsubscribe(), - this.subscribeToSource() - } - , - vs.prototype.subscribeToSource = function() { - this.sourceSubscribed || (this.sourceSubscribed = !0, - this.unsubscribe(), - this.source.subscribe(this.parent)) - } - , - vs); - function vs(e, t) { - var i = hs.call(this) || this; - return i.parent = e, - i.source = t, - i.sourceSubscribed = !1, - i - } - function Ss(e, t) { - var i = ps.call(this) || this; - return i.source = e, - i.subscriptionDelay = t, - i - } - function bs(e, t) { - e = fs.call(this, e) || this; - return e.delayDurationSelector = t, - e.completed = !1, - e.delayNotifierSubscriptions = [], - e.index = 0, - e - } - function Ts(e) { - this.delayDurationSelector = e - } - function Es(t, i) { - return function(e) { - return e.lift(new ws(t,i)) - } - } - var Is, ws = (ks.prototype.call = function(e, t) { - return t.subscribe(new As(e,this.compare,this.keySelector)) - } - , - ks), As = (lt(Os, Is = Pt), - Os.prototype.compare = function(e, t) { - return e === t - } - , - Os.prototype._next = function(e) { - try { - var t = this.keySelector - , i = t ? t(e) : e - } catch (e) { - return this.destination.error(e) - } - t = !1; - if (this.hasKey) - try { - t = (0, - this.compare)(this.key, i) - } catch (e) { - return this.destination.error(e) - } - else - this.hasKey = !0; - t || (this.key = i, - this.destination.next(e)) - } - , - Os); - function Os(e, t, i) { - e = Is.call(this, e) || this; - return e.keySelector = i, - e.hasKey = !1, - "function" == typeof t && (e.compare = t), - e - } - function ks(e, t) { - this.compare = e, - this.keySelector = t - } - function Cs(t) { - return function(e) { - return 0 === t ? Ri() : e.lift(new Ms(t)) - } - } - var Ds, Ms = (Rs.prototype.call = function(e, t) { - return t.subscribe(new Ps(e,this.total)) - } - , - Rs), Ps = (lt(xs, Ds = Pt), - xs.prototype._next = function(e) { - var t = this.total - , i = ++this.count; - i <= t && (this.destination.next(e), - i === t && (this.destination.complete(), - this.unsubscribe())) - } - , - xs); - function xs(e, t) { - e = Ds.call(this, e) || this; - return e.total = t, - e.count = 0, - e - } - function Rs(e) { - if (this.total = e, - this.total < 0) - throw new ar - } - function Ls(t, n) { - return n ? function(e) { - return e.pipe(Ls(function(i, r) { - return Lr(t(i, r)).pipe(ur(function(e, t) { - return n(i, e, r, t) - })) - })) - } - : function(e) { - return e.lift(new Ns(t)) - } - } - var _s, Ns = (Us.prototype.call = function(e, t) { - return t.subscribe(new Fs(e,this.project)) - } - , - Us), Fs = (lt(Bs, _s = Br), - Bs.prototype._next = function(e) { - this.hasSubscription || this.tryNext(e) - } - , - Bs.prototype.tryNext = function(e) { - var t, i = this.index++; - try { - t = this.project(e, i) - } catch (e) { - return void this.destination.error(e) - } - this.hasSubscription = !0, - this._innerSub(t) - } - , - Bs.prototype._innerSub = function(e) { - var t = new Fr(this) - , i = this.destination; - i.add(t); - e = Vr(e, t); - e !== t && i.add(e) - } - , - Bs.prototype._complete = function() { - this.hasCompleted = !0, - this.hasSubscription || this.destination.complete(), - this.unsubscribe() - } - , - Bs.prototype.notifyNext = function(e) { - this.destination.next(e) - } - , - Bs.prototype.notifyError = function(e) { - this.destination.error(e) - } - , - Bs.prototype.notifyComplete = function() { - this.hasSubscription = !1, - this.hasCompleted && this.destination.complete() - } - , - Bs); - function Bs(e, t) { - e = _s.call(this, e) || this; - return e.project = t, - e.hasSubscription = !1, - e.hasCompleted = !1, - e.index = 0, - e - } - function Us(e) { - this.project = e - } - function $s(t) { - return function(e) { - return e.lift(new Ks(t)) - } - } - var Vs, Ks = (qs.prototype.call = function(e, t) { - return t.subscribe(new Hs(e,this.callback)) - } - , - qs), Hs = (lt(js, Vs = Pt), - js); - function js(e, t) { - e = Vs.call(this, e) || this; - return e.add(new wt(t)), - e - } - function qs(e) { - this.callback = e - } - function Qs(t) { - return function(e) { - return 0 === t ? Ri() : e.lift(new Ws(t)) - } - } - var Gs, Ws = (Ys.prototype.call = function(e, t) { - return t.subscribe(new zs(e,this.total)) - } - , - Ys), zs = (lt(Xs, Gs = Pt), - Xs.prototype._next = function(e) { - var t = this.ring - , i = this.total - , r = this.count++; - t.length < i ? t.push(e) : t[r % i] = e - } - , - Xs.prototype._complete = function() { - var e = this.destination - , t = this.count; - if (0 < t) - for (var i = this.count >= this.total ? this.total : this.count, r = this.ring, n = 0; n < i; n++) { - var s = t++ % i; - e.next(r[s]) - } - e.complete() - } - , - Xs); - function Xs(e, t) { - e = Gs.call(this, e) || this; - return e.total = t, - e.ring = new Array, - e.count = 0, - e - } - function Ys(e) { - if (this.total = e, - this.total < 0) - throw new ar - } - function Js(t) { - return function(e) { - return e.lift(new ea(t)) - } - } - var Zs, ea = (ra.prototype.call = function(e, t) { - return t.subscribe(new ta(e,this.value)) - } - , - ra), ta = (lt(ia, Zs = Pt), - ia.prototype._next = function(e) { - this.destination.next(this.value) - } - , - ia); - function ia(e, t) { - e = Zs.call(this, e) || this; - return e.value = t, - e - } - function ra(e) { - this.value = e - } - function na(t, i) { - var r = 2 <= arguments.length ? !0 : !1; - return function(e) { - return e.lift(new aa(t,i,r)) - } - } - var sa, aa = (la.prototype.call = function(e, t) { - return t.subscribe(new oa(e,this.accumulator,this.seed,this.hasSeed)) - } - , - la), oa = (lt(da, sa = Pt), - Object.defineProperty(da.prototype, "seed", { - get: function() { - return this._seed - }, - set: function(e) { - this.hasSeed = !0, - this._seed = e - }, - enumerable: !0, - configurable: !0 - }), - da.prototype._next = function(e) { - if (this.hasSeed) - return this._tryNext(e); - this.seed = e, - this.destination.next(e) - } - , - da.prototype._tryNext = function(e) { - var t, i = this.index++; - try { - t = this.accumulator(this.seed, e, i) - } catch (e) { - this.destination.error(e) - } - this.seed = t, - this.destination.next(t) - } - , - da); - function da(e, t, i, r) { - e = sa.call(this, e) || this; - return e.accumulator = t, - e._seed = i, - e.hasSeed = r, - e.index = 0, - e - } - function la(e, t, i) { - void 0 === i && (i = !1), - this.accumulator = e, - this.seed = t, - this.hasSeed = i - } - ua.prototype.call = function(e, t) { - var i = this.selector - , r = this.subjectFactory() - , e = i(r).subscribe(e); - return e.add(t.subscribe(r)), - e - } - ; - function ua(e, t) { - this.subjectFactory = e, - this.selector = t - } - function ca() { - return function(e) { - return e.lift(new pa) - } - } - var ha, pa = (ga.prototype.call = function(e, t) { - return t.subscribe(new fa(e)) - } - , - ga), fa = (lt(ma, ha = Pt), - ma.prototype._next = function(e) { - var t; - this.hasPrev ? t = [this.prev, e] : this.hasPrev = !0, - this.prev = e, - t && this.destination.next(t) - } - , - ma); - function ma(e) { - e = ha.call(this, e) || this; - return e.hasPrev = !1, - e - } - function ga() {} - function ya(t) { - return function(e) { - return e.lift(new Sa(t,e)) - } - } - var va, Sa = (Ea.prototype.call = function(e, t) { - return t.subscribe(new ba(e,this.notifier,this.source)) - } - , - Ea), ba = (lt(Ta, va = Br), - Ta.prototype.error = function(e) { - if (!this.isStopped) { - var t = this.errors - , i = this.retries - , r = this.retriesSubscription; - if (i) - this.errors = void 0, - this.retriesSubscription = void 0; - else { - t = new zt; - try { - i = (0, - this.notifier)(t) - } catch (e) { - return va.prototype.error.call(this, e) - } - r = Vr(i, new Fr(this)) - } - this._unsubscribeAndRecycle(), - this.errors = t, - this.retries = i, - this.retriesSubscription = r, - t.next(e) - } - } - , - Ta.prototype._unsubscribe = function() { - var e = this.errors - , t = this.retriesSubscription; - e && (e.unsubscribe(), - this.errors = void 0), - t && (t.unsubscribe(), - this.retriesSubscription = void 0), - this.retries = void 0 - } - , - Ta.prototype.notifyNext = function() { - var e = this._unsubscribe; - this._unsubscribe = null, - this._unsubscribeAndRecycle(), - this._unsubscribe = e, - this.source.subscribe(this) - } - , - Ta); - function Ta(e, t, i) { - e = va.call(this, e) || this; - return e.notifier = t, - e.source = i, - e - } - function Ea(e, t) { - this.notifier = e, - this.source = t - } - function Ia() { - return new zt - } - function wa() { - return function(e) { - return ii()((t = e, - i = "function" == typeof (r = Ia) ? r : function() { - return r - } - , - (e = Object.create(t, fi)).source = t, - e.subjectFactory = i, - e)); - var t, i, r - } - } - function Aa(e, t, i) { - var c = e && "object" == typeof e ? e : { - bufferSize: e, - windowTime: t, - refCount: !1, - scheduler: i - }; - return function(e) { - return e.lift((e = c.bufferSize, - n = void 0 === e ? Number.POSITIVE_INFINITY : e, - e = c.windowTime, - s = void 0 === e ? Number.POSITIVE_INFINITY : e, - a = c.refCount, - o = c.scheduler, - d = 0, - u = l = !1, - function(e) { - var t; - d++, - !i || l ? (l = !1, - i = new Xi(n,s,o), - t = i.subscribe(this), - r = e.subscribe({ - next: function(e) { - i.next(e) - }, - error: function(e) { - l = !0, - i.error(e) - }, - complete: function() { - u = !0, - r = void 0, - i.complete() - } - }), - u && (r = void 0)) : t = i.subscribe(this), - this.add(function() { - d--, - t.unsubscribe(), - t = void 0, - r && !u && a && 0 === d && (r.unsubscribe(), - i = r = void 0) - }) - } - )); - var i, r, n, s, a, o, d, l, u - } - } - function Oa(t) { - return function(e) { - return e.lift(new Ca(t)) - } - } - var ka, Ca = (Pa.prototype.call = function(e, t) { - return t.subscribe(new Da(e,this.total)) - } - , - Pa), Da = (lt(Ma, ka = Pt), - Ma.prototype._next = function(e) { - ++this.count > this.total && this.destination.next(e) - } - , - Ma); - function Ma(e, t) { - e = ka.call(this, e) || this; - return e.total = t, - e.count = 0, - e - } - function Pa(e) { - this.total = e - } - function xa() { - for (var t = [], e = 0; e < arguments.length; e++) - t[e] = arguments[e]; - var i = t[t.length - 1]; - return Li(i) ? (t.pop(), - function(e) { - return Xr(t, e, i) - } - ) : function(e) { - return Xr(t, e) - } - } - function Ra(t, n) { - return "function" == typeof n ? function(e) { - return e.pipe(Ra(function(i, r) { - return Lr(t(i, r)).pipe(ur(function(e, t) { - return n(i, e, r, t) - })) - })) - } - : function(e) { - return e.lift(new _a(t)) - } - } - var La, _a = (Ba.prototype.call = function(e, t) { - return t.subscribe(new Na(e,this.project)) - } - , - Ba), Na = (lt(Fa, La = Br), - Fa.prototype._next = function(e) { - var t, i = this.index++; - try { - t = this.project(e, i) - } catch (e) { - return void this.destination.error(e) - } - this._innerSub(t) - } - , - Fa.prototype._innerSub = function(e) { - var t = this.innerSubscription; - t && t.unsubscribe(); - var i = new Fr(this) - , t = this.destination; - t.add(i), - this.innerSubscription = Vr(e, i), - this.innerSubscription !== i && t.add(this.innerSubscription) - } - , - Fa.prototype._complete = function() { - var e = this.innerSubscription; - e && !e.closed || La.prototype._complete.call(this), - this.unsubscribe() - } - , - Fa.prototype._unsubscribe = function() { - this.innerSubscription = void 0 - } - , - Fa.prototype.notifyComplete = function() { - this.innerSubscription = void 0, - this.isStopped && La.prototype._complete.call(this) - } - , - Fa.prototype.notifyNext = function(e) { - this.destination.next(e) - } - , - Fa); - function Fa(e, t) { - e = La.call(this, e) || this; - return e.project = t, - e.index = 0, - e - } - function Ba(e) { - this.project = e - } - function Ua(e, t) { - return t ? Ra(function() { - return e - }, t) : Ra(function() { - return e - }) - } - function $a(t) { - return function(e) { - return e.lift(new Ka(t)) - } - } - var Va, Ka = (qa.prototype.call = function(e, t) { - var i = new Ha(e) - , e = Vr(this.notifier, new Fr(i)); - return e && !i.seenValue ? (i.add(e), - t.subscribe(i)) : i - } - , - qa), Ha = (lt(ja, Va = Br), - ja.prototype.notifyNext = function() { - this.seenValue = !0, - this.complete() - } - , - ja.prototype.notifyComplete = function() {} - , - ja); - function ja(e) { - e = Va.call(this, e) || this; - return e.seenValue = !1, - e - } - function qa(e) { - this.notifier = e - } - function Qa(t, i) { - return void 0 === i && (i = !1), - function(e) { - return e.lift(new Wa(t,i)) - } - } - var Ga, Wa = (Ya.prototype.call = function(e, t) { - return t.subscribe(new za(e,this.predicate,this.inclusive)) - } - , - Ya), za = (lt(Xa, Ga = Pt), - Xa.prototype._next = function(e) { - var t, i = this.destination; - try { - t = this.predicate(e, this.index++) - } catch (e) { - return void i.error(e) - } - this.nextOrComplete(e, t) - } - , - Xa.prototype.nextOrComplete = function(e, t) { - var i = this.destination; - Boolean(t) ? i.next(e) : (this.inclusive && i.next(e), - i.complete()) - } - , - Xa); - function Xa(e, t, i) { - e = Ga.call(this, e) || this; - return e.predicate = t, - e.inclusive = i, - e.index = 0, - e - } - function Ya(e, t) { - this.predicate = e, - this.inclusive = t - } - function Ja(t, i, r) { - return function(e) { - return e.lift(new eo(t,i,r)) - } - } - var Za, eo = (no.prototype.call = function(e, t) { - return t.subscribe(new to(e,this.nextOrObserver,this.error,this.complete)) - } - , - no), to = (lt(ro, Za = Pt), - ro.prototype._next = function(e) { - try { - this._tapNext.call(this._context, e) - } catch (e) { - return void this.destination.error(e) - } - this.destination.next(e) - } - , - ro.prototype._error = function(e) { - try { - this._tapError.call(this._context, e) - } catch (e) { - return void this.destination.error(e) - } - this.destination.error(e) - } - , - ro.prototype._complete = function() { - try { - this._tapComplete.call(this._context) - } catch (e) { - return void this.destination.error(e) - } - return this.destination.complete() - } - , - ro), io = { - leading: !0, - trailing: !1 - }; - function ro(e, t, i, r) { - e = Za.call(this, e) || this; - return e._tapNext = sr, - e._tapError = sr, - e._tapComplete = sr, - e._tapError = i || sr, - e._tapComplete = r || sr, - gt(t) ? (e._context = e)._tapNext = t : t && (e._context = t, - e._tapNext = t.next || sr, - e._tapError = t.error || sr, - e._tapComplete = t.complete || sr), - e - } - function no(e, t, i) { - this.nextOrObserver = e, - this.error = t, - this.complete = i - } - function so(t, i, r) { - return void 0 === i && (i = er), - void 0 === r && (r = io), - function(e) { - return e.lift(new oo(t,i,r.leading,r.trailing)) - } - } - var ao, oo = (co.prototype.call = function(e, t) { - return t.subscribe(new lo(e,this.duration,this.scheduler,this.leading,this.trailing)) - } - , - co), lo = (lt(uo, ao = Pt), - uo.prototype._next = function(e) { - this.throttled ? this.trailing && (this._trailingValue = e, - this._hasTrailingValue = !0) : (this.add(this.throttled = this.scheduler.schedule(ho, this.duration, { - subscriber: this - })), - this.leading ? this.destination.next(e) : this.trailing && (this._trailingValue = e, - this._hasTrailingValue = !0)) - } - , - uo.prototype._complete = function() { - this._hasTrailingValue && this.destination.next(this._trailingValue), - this.destination.complete() - } - , - uo.prototype.clearThrottle = function() { - var e = this.throttled; - e && (this.trailing && this._hasTrailingValue && (this.destination.next(this._trailingValue), - this._trailingValue = null, - this._hasTrailingValue = !1), - e.unsubscribe(), - this.remove(e), - this.throttled = null) - } - , - uo); - function uo(e, t, i, r, n) { - e = ao.call(this, e) || this; - return e.duration = t, - e.scheduler = i, - e.leading = r, - e.trailing = n, - e._hasTrailingValue = !1, - e._trailingValue = null, - e - } - function co(e, t, i, r) { - this.duration = e, - this.scheduler = t, - this.leading = i, - this.trailing = r - } - function ho(e) { - e.subscriber.clearThrottle() - } - var po, fo = (yo.prototype.call = function(e, t) { - return t.subscribe(new mo(e,this.absoluteTimeout,this.waitFor,this.withObservable,this.scheduler)) - } - , - yo), mo = (lt(go, po = Br), - go.dispatchTimeout = function(e) { - var t = e.withObservable; - e._unsubscribeAndRecycle(), - e.add(Vr(t, new Fr(e))) - } - , - go.prototype.scheduleTimeout = function() { - var e = this.action; - e ? this.action = e.schedule(this, this.waitFor) : this.add(this.action = this.scheduler.schedule(go.dispatchTimeout, this.waitFor, this)) - } - , - go.prototype._next = function(e) { - this.absoluteTimeout || this.scheduleTimeout(), - po.prototype._next.call(this, e) - } - , - go.prototype._unsubscribe = function() { - this.action = void 0, - this.scheduler = null, - this.withObservable = null - } - , - go); - function go(e, t, i, r, n) { - e = po.call(this, e) || this; - return e.absoluteTimeout = t, - e.waitFor = i, - e.withObservable = r, - e.scheduler = n, - e.scheduleTimeout(), - e - } - function yo(e, t, i, r) { - this.waitFor = e, - this.absoluteTimeout = t, - this.withObservable = i, - this.scheduler = r - } - function vo(e, t) { - return void 0 === t && (t = er), - r = e, - n = Ui(new or), - void 0 === (s = t) && (s = er), - function(e) { - var t = ns(r) - , i = t ? +r - s.now() : Math.abs(r); - return e.lift(new fo(i,t,n,s)) - } - ; - var r, n, s - } - function So() { - for (var i = [], e = 0; e < arguments.length; e++) - i[e] = arguments[e]; - return function(e) { - var t; - return "function" == typeof i[i.length - 1] && (t = i.pop()), - e.lift(new Eo(i,t)) - } - } - var bo, To, Eo = (ko.prototype.call = function(e, t) { - return t.subscribe(new Io(e,this.observables,this.project)) - } - , - ko), Io = (lt(Oo, bo = gr), - Oo.prototype.notifyNext = function(e, t, i) { - this.values[i] = t; - t = this.toRespond; - 0 < t.length && (-1 !== (i = t.indexOf(i)) && t.splice(i, 1)) - } - , - Oo.prototype.notifyComplete = function() {} - , - Oo.prototype._next = function(e) { - 0 === this.toRespond.length && (e = [e].concat(this.values), - this.project ? this._tryProject(e) : this.destination.next(e)) - } - , - Oo.prototype._tryProject = function(e) { - var t; - try { - t = this.project.apply(this, e) - } catch (e) { - return void this.destination.error(e) - } - this.destination.next(t) - } - , - Oo), wo = { - type: null, - entityIds: null, - skip: !1 - }, Ao = !1; - function Oo(e, t, i) { - var r = bo.call(this, e) || this; - r.observables = t, - r.project = i, - r.toRespond = []; - var n = t.length; - r.values = new Array(n); - for (var s = 0; s < n; s++) - r.toRespond.push(s); - for (s = 0; s < n; s++) { - var a = t[s]; - r.add(Or(r, a, void 0, s)) - } - return r - } - function ko(e, t) { - this.observables = e, - this.project = t - } - function Co(e, t) { - Do(e, t), - Ao = !0 - } - function Do(e, t) { - !1 === Ao && (wo.type = e, - wo.entityIds = t) - } - function Mo(e, t) { - return e.hasOwnProperty(t) - } - function Po(e) { - return null == e - } - function xo(e) { - return Po(e) ? [] : Array.isArray(e) ? e : [e] - } - (mu = To = To || {}).Set = "Set", - mu.Add = "Add", - mu.Update = "Update", - mu.Remove = "Remove"; - var Ro = "undefined" != typeof window - , Lo = !0; - function _o(e) { - var t = typeof e; - return null != e && ("object" == t || "function" == t) - } - function No(e) { - return Array.isArray(e) - } - function Fo(e) { - return !1 === Po(e) - } - function Bo(e) { - return No(e) && 0 === e.length - } - function Uo(e) { - return "function" == typeof e - } - function $o(e) { - return void 0 === e - } - function Vo(e) { - return e.hasOwnProperty("active") - } - function Ko(e) { - return No(e) - } - function Ho(e) { - var t, i = e.active, r = e.ids, n = e.entities; - return Ko(i) ? (t = r, - (r = (e = i).filter(function(e) { - return -1 < t.indexOf(e) - })).length === e.length ? e : r) : !1 === Mo(n, i) ? null : i - } - function jo(e, t) { - var i, r, n = {}; - try { - for (var s = pt(Object.keys(e)), a = s.next(); !a.done; a = s.next()) { - var o = a.value; - n[o] = t(e[o]) - } - } catch (e) { - i = { - error: e - } - } finally { - try { - a && !a.done && (r = s.return) && r.call(s) - } finally { - if (i) - throw i.error - } - } - return n - } - var qo = { - resettable: !1, - ttl: null, - producerFn: void 0 - }; - function Qo(t) { - Object.freeze(t); - var i = "function" == typeof t - , r = Object.prototype.hasOwnProperty; - return Object.getOwnPropertyNames(t).forEach(function(e) { - !r.call(t, e) || i && ("caller" === e || "callee" === e || "arguments" === e) || null === t[e] || "object" != typeof t[e] && "function" != typeof t[e] || Object.isFrozen(t[e]) || Qo(t[e]) - }), - t - } - var Go, Wo = new zt, zo = new Xi(50,5e3), Xo = new zt; - function Yo(e) { - return null != e && "" + e != "false" - } - function Jo(e) { - return Yo(e) && "Object" === e.constructor.name - } - lt(function(e) { - return Go.call(this, e) || this - }, Go = Error); - var Zo = {} - , ed = {}; - Ro && (window.$$stores = Zo, - window.$$queries = ed); - var td = new zt - , id = new gi(!1) - , rd = { - activeTransactions: 0, - batchTransaction: null - }; - function nd() { - return 0 < rd.activeTransactions - } - function sd(e, t) { - void 0 === t && (t = void 0), - nd() || (rd.batchTransaction = new zt), - rd.activeTransactions++, - id.next(!0); - try { - return e.apply(t) - } finally { - Co("@Transaction"), - 0 == --rd.activeTransactions && (rd.batchTransaction.next(!0), - rd.batchTransaction.complete(), - id.next(!1), - td.next(!0)) - } - } - function ad() { - return function(e, t, i) { - var r = i.value; - return i.value = function() { - for (var e = this, t = [], i = 0; i < arguments.length; i++) - t[i] = arguments[i]; - return sd(function() { - return r.apply(e, t) - }, this) - } - , - i - } - } - function od(t) { - return function(e) { - return e.pipe(Ja(function(e) { - return sd(function() { - return t(e) - }) - })) - } - } - var dd = (ld.prototype.setLoading = function(t) { - (t = void 0 === t ? !1 : t) !== this._value().loading && (Lo && Do("Set Loading"), - this._setState(function(e) { - return ut({}, e, { - loading: t - }) - })) - } - , - ld.prototype.setHasCache = function(e, t) { - var i, r = this; - void 0 === t && (t = { - restartTTL: !1 - }), - e !== this.cache.active.value && this.cache.active.next(e), - t.restartTTL && (i = this.getCacheTTL()) && (null !== this.cache.ttl && clearTimeout(this.cache.ttl), - this.cache.ttl = setTimeout(function() { - return r.setHasCache(!1) - }, i)) - } - , - ld.prototype.getValue = function() { - return this.storeValue - } - , - ld.prototype.setError = function(t) { - t !== this._value().error && (Lo && Do("Set Error"), - this._setState(function(e) { - return ut({}, e, { - error: t - }) - })) - } - , - ld.prototype._select = function(t) { - return this.store.asObservable().pipe(ur(function(e) { - return t(e.state) - }), Es()) - } - , - ld.prototype._value = function() { - return this.storeValue - } - , - ld.prototype._cache = function() { - return this.cache.active - } - , - Object.defineProperty(ld.prototype, "config", { - get: function() { - return this.constructor.akitaConfig || {} - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(ld.prototype, "storeName", { - get: function() { - return this.config.storeName || this.options.storeName || this.options.name - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(ld.prototype, "deepFreeze", { - get: function() { - return this.config.deepFreezeFn || this.options.deepFreezeFn || Qo - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(ld.prototype, "cacheConfig", { - get: function() { - return this.config.cache || this.options.cache - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(ld.prototype, "_producerFn", { - get: function() { - return this.config.producerFn || this.options.producerFn || qo.producerFn - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(ld.prototype, "resettable", { - get: function() { - return (Fo(this.config.resettable) ? this.config : this.options).resettable - }, - enumerable: !0, - configurable: !0 - }), - ld.prototype._setState = function(e, t) { - var i, r = this; - if (void 0 === t && (t = !0), - Uo(e) ? (i = e(this._value()), - this.storeValue = Lo ? this.deepFreeze(i) : i) : this.storeValue = e, - !this.store) - return this.store = new gi({ - state: this.storeValue - }), - void (Lo && this.store.subscribe(function(e) { - var t = e.action; - t && (e = r.storeName, - Xo.next({ - storeName: e, - action: t - })) - })); - nd() ? this.handleTransaction() : this.dispatch(this.storeValue, t) - } - , - ld.prototype.reset = function() { - var e = this; - this.isResettable() ? (Lo && Do("Reset"), - this._setState(function() { - return Object.assign({}, e._initialState) - }), - this.setHasCache(!1)) : Lo && console.warn("You need to enable the reset functionality") - } - , - ld.prototype.update = function(e) { - Lo && Do("Update"); - var t = this._value() - , e = Uo(e) ? Uo(this._producerFn) ? this._producerFn(t, e) : e(t) : e - , e = this.akitaPreUpdate(t, ut({}, t, e)) - , e = Jo(t) ? e : new t.constructor(e); - this._setState(e) - } - , - ld.prototype.updateStoreConfig = function(e) { - this.options = ut({}, this.options, e) - } - , - ld.prototype.akitaPreUpdate = function(e, t) { - return t - } - , - ld.prototype.ngOnDestroy = function() { - this.destroy() - } - , - ld.prototype.destroy = function() { - var e; - Ro && window.hmrEnabled || this !== Zo[this.storeName] || (delete Zo[this.storeName], - e = this.storeName, - Wo.next(e), - this.setHasCache(!1), - this.cache.active.complete(), - this.store.complete()) - } - , - ld.prototype.onInit = function(e) { - var t, i; - (Zo[this.storeName] = this)._setState(function() { - return e - }), - i = this.storeName, - zo.next(i), - this.isResettable() && (this._initialState = e), - Lo && (t = this.storeName, - i = this.constructor.name, - t || console.error("@StoreConfig({ name }) is missing in " + i)) - } - , - ld.prototype.dispatch = function(e, t) { - var i = void 0; - (t = void 0 === t ? !0 : t) && (i = wo, - Ao = !1), - this.store.next({ - state: e, - action: i - }) - } - , - ld.prototype.watchTransaction = function() { - var e = this; - (rd.batchTransaction ? rd.batchTransaction.asObservable() : Bi(!0)).subscribe(function() { - e.inTransaction = !1, - e.dispatch(e._value()) - }) - } - , - ld.prototype.isResettable = function() { - return !1 !== this.resettable && (this.resettable || qo.resettable) - } - , - ld.prototype.handleTransaction = function() { - this.inTransaction || (this.watchTransaction(), - this.inTransaction = !0) - } - , - ld.prototype.getCacheTTL = function() { - return this.cacheConfig && this.cacheConfig.ttl || qo.ttl - } - , - ld); - function ld(e, t) { - this.options = t = void 0 === t ? {} : t, - this.inTransaction = !1, - this.cache = { - active: new gi(!1), - ttl: null - }, - this.onInit(e) - } - var ud, cd, hd, pd = (lt(gd, hd = dd), - Object.defineProperty(gd.prototype, "selectEntityAction$", { - get: function() { - return this.entityActions.asObservable() - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(gd.prototype, "selectEntityIdChanges$", { - get: function() { - return this.entityIdChanges.asObservable() - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(gd.prototype, "idKey", { - get: function() { - return this.config.idKey || this.options.idKey || "id" - }, - enumerable: !0, - configurable: !0 - }), - gd.prototype.set = function(a, o) { - var d, l = this; - void 0 === o && (o = {}), - Po(a) || (Lo && Do("Set Entity"), - d = this.akitaPreAddEntity === gd.prototype.akitaPreAddEntity, - this.setHasCache(!0, { - restartTTL: !0 - }), - this._setState(function(e) { - var t, i, r, n, s, e = (t = { - state: e, - entities: a, - idKey: l.idKey, - preAddEntity: l.akitaPreAddEntity, - isNativePreAdd: d - }, - r = t.state, - n = t.entities, - s = t.idKey, - e = t.preAddEntity, - t = t.isNativePreAdd, - e = No(n) ? (i = (s = function(e, t, i) { - var r, n, s = { - entities: {}, - ids: [] - }; - try { - for (var a = pt(e), o = a.next(); !o.done; o = a.next()) { - var d = i(o.value); - s.entities[d[t]] = d, - s.ids.push(d[t]) - } - } catch (e) { - r = { - error: e - } - } finally { - try { - o && !o.done && (n = a.return) && n.call(a) - } finally { - if (r) - throw r.error - } - } - return s - }(n, s, e)).entities, - s.ids) : n.entities && n.ids ? (i = t ? n.entities : jo(n.entities, e), - n.ids) : (i = t ? n : jo(n, e), - Object.keys(i).map(function(e) { - return isNaN(e) ? e : Number(e) - })), - e = ut({}, r, { - entities: i, - ids: e, - loading: !1 - }), - Vo(r) && (e.active = Ho(e)), - e); - return !1 === $o(o.activeId) && (e.active = o.activeId), - e - }), - this.hasInitialUIState() && this.handleUICreation(), - this.entityActions.next({ - type: To.Set, - ids: this.ids - })) - } - , - gd.prototype.add = function(e, t) { - void 0 === t && (t = { - loading: !1 - }); - var i, e = xo(e); - Bo(e) || (i = function(e) { - var t, i, r = e.state, n = e.entities, s = e.idKey, a = e.options, o = void 0 === a ? {} : a, d = e.preAddEntity, l = {}, u = [], c = !1; - try { - for (var h = pt(n), p = h.next(); !p.done; p = h.next()) { - var f, m, g = p.value; - !1 === Mo(r.entities, g[s]) && (l[m = (f = d(g))[s]] = f, - o.prepend ? u.unshift(m) : u.push(m), - c = !0) - } - } catch (e) { - t = { - error: e - } - } finally { - try { - p && !p.done && (i = h.return) && i.call(h) - } finally { - if (t) - throw t.error - } - } - return c ? { - newState: ut({}, r, { - entities: ut({}, r.entities, l), - ids: o.prepend ? mt(u, r.ids) : mt(r.ids, u) - }), - newIds: u - } : null - }({ - state: this._value(), - preAddEntity: this.akitaPreAddEntity, - entities: e, - idKey: this.idKey, - options: t - })) && (Lo && Do("Add Entity"), - i.newState.loading = t.loading, - this._setState(function() { - return i.newState - }), - this.hasInitialUIState() && this.handleUICreation(!0), - this.entityActions.next({ - type: To.Add, - ids: i.newIds - })) - } - , - gd.prototype.update = function(t, i) { - var r, n, s = this; - $o(i) ? hd.prototype.update.call(this, t) : (n = [], - Bo(n = Uo(t) ? this.ids.filter(function(e) { - return t(s.entities[e]) - }) : Po(t) ? this.ids : xo(t)) || (Lo && Do("Update Entity", n), - this._setState(function(e) { - return function(e) { - var t = e.state - , i = e.ids - , r = e.idKey - , n = e.newStateOrFn - , s = e.preUpdateEntity - , a = e.producerFn - , o = e.onEntityIdChanges - , d = {} - , l = !1; - try { - for (var u = pt(i), c = u.next(); !c.done; c = u.next()) { - var h, p, f, m, g, y, v = c.value; - !1 !== Mo(t.entities, v) && (h = t.entities[v], - p = void 0, - f = (p = Uo(n) ? Uo(a) ? a(h, n) : n(h) : n).hasOwnProperty(r) && p[r] !== h[r], - y = void 0, - m = v, - f && (l = !0, - m = p[r]), - g = ut({}, h, p), - y = Jo(h) ? g : new (Jo(p) ? h : p).constructor(g), - d[m] = s(h, y)) - } - } catch (e) { - T = { - error: e - } - } finally { - try { - c && !c.done && (b = u.return) && b.call(u) - } finally { - if (T) - throw T.error - } - } - var S, b = t.ids, T = t.entities; - return l && (S = ft(i, 1)[0], - T = function(e, t) { - var i = {}; - for (n in e) - Object.prototype.hasOwnProperty.call(e, n) && t.indexOf(n) < 0 && (i[n] = e[n]); - if (null != e && "function" == typeof Object.getOwnPropertySymbols) - for (var r = 0, n = Object.getOwnPropertySymbols(e); r < n.length; r++) - t.indexOf(n[r]) < 0 && Object.prototype.propertyIsEnumerable.call(e, n[r]) && (i[n[r]] = e[n[r]]); - return i - }(t.entities, ["symbol" == typeof S ? S : S + ""]), - b = t.ids.map(function(e) { - return e === S ? m : e - }), - o(S, m)), - ut({}, t, { - entities: ut({}, T, d), - ids: b - }) - }({ - idKey: s.idKey, - ids: n, - preUpdateEntity: s.akitaPreUpdateEntity, - state: e, - newStateOrFn: i, - producerFn: s._producerFn, - onEntityIdChanges: function(e, t) { - r = { - oldId: e, - newId: t - }, - s.entityIdChanges.next(ut({}, r, { - pending: !0 - })) - } - }) - }), - r && this.entityIdChanges.next(ut({}, r, { - pending: !1 - })), - this.entityActions.next({ - type: To.Update, - ids: n - }))) - } - , - gd.prototype.upsert = function(e, i, r, t) { - var n = this; - void 0 === t && (t = {}); - var s = xo(e) - , e = function(t) { - return function(e) { - return Mo(n.entities, e) === t - } - } - , a = Uo(r) ? t.baseClass : r ? r.baseClass : void 0 - , o = Uo(a) - , t = s.filter(e(!0)) - , e = s.filter(e(!1)).map(function(e) { - var t = "function" == typeof i ? i({}) : i - , t = Uo(r) ? r(e, t) : t - , t = ut({}, t, ((t = {})[n.idKey] = e, - t)); - return o ? new a(t) : t - }); - this.update(t, i), - this.add(e), - Lo && Co("Upsert Entity") - } - , - gd.prototype.upsertMany = function(e, t) { - var i, r; - void 0 === t && (t = {}); - var n = [] - , s = [] - , a = {}; - try { - for (var o = pt(e), d = o.next(); !d.done; d = o.next()) { - var l, u, c, h, p, f, m = d.value, g = this.akitaPreCheckEntity(m), y = g[this.idKey]; - Mo(this.entities, y) ? (l = this._value().entities[y], - u = ut({}, this._value().entities[y], g), - c = t.baseClass ? new t.baseClass(u) : u, - f = (h = this.akitaPreUpdateEntity(l, c))[this.idKey], - a[f] = h, - s.push(f)) : (p = t.baseClass ? new t.baseClass(g) : g, - f = (h = this.akitaPreAddEntity(p))[this.idKey], - n.push(f), - a[f] = h) - } - } catch (e) { - i = { - error: e - } - } finally { - try { - d && !d.done && (r = o.return) && r.call(o) - } finally { - if (i) - throw i.error - } - } - Lo && Co("Upsert Many"), - this._setState(function(e) { - return ut({}, e, { - ids: n.length ? mt(e.ids, n) : e.ids, - entities: ut({}, e.entities, a), - loading: !!t.loading - }) - }), - s.length && this.entityActions.next({ - type: To.Update, - ids: s - }), - n.length && this.entityActions.next({ - type: To.Add, - ids: n - }), - n.length && this.hasUIStore() && this.handleUICreation(!0) - } - , - gd.prototype.replace = function(e, t) { - var i, r, n = xo(e); - if (!Bo(n)) { - var s = {}; - try { - for (var a = pt(n), o = a.next(); !o.done; o = a.next()) { - var d = o.value; - t[this.idKey] = d, - s[d] = t - } - } catch (e) { - i = { - error: e - } - } finally { - try { - o && !o.done && (r = a.return) && r.call(a) - } finally { - if (i) - throw i.error - } - } - Lo && Do("Replace Entity", e), - this._setState(function(e) { - return ut({}, e, { - entities: ut({}, e.entities, s) - }) - }) - } - } - , - gd.prototype.move = function(e, t) { - var i = this.ids.slice(); - i.splice(t < 0 ? i.length + t : t, 0, i.splice(e, 1)[0]), - Lo && Do("Move Entity"), - this._setState(function(e) { - return ut({}, e, { - entities: ut({}, e.entities), - ids: i - }) - }) - } - , - gd.prototype.remove = function(t) { - var e, i, r = this; - Bo(this.ids) || (e = Fo(t), - i = [], - Bo(i = Uo(t) ? this.ids.filter(function(e) { - return t(r.entities[e]) - }) : e ? xo(t) : this.ids) || (Lo && Do("Remove Entity", i), - this._setState(function(e) { - return function(e) { - var t, i = e.state, r = e.ids; - if (Po(r)) - return ut({}, i, { - entities: {}, - ids: [], - active: Ko(i.active) ? [] : null - }); - var n = i.entities - , s = {}; - try { - for (var a = pt(i.ids), o = a.next(); !o.done; o = a.next()) { - var d = o.value; - !1 === r.includes(d) && (s[d] = n[d]) - } - } catch (e) { - l = { - error: e - } - } finally { - try { - o && !o.done && (t = a.return) && t.call(a) - } finally { - if (l) - throw l.error - } - } - var l = ut({}, i, { - entities: s, - ids: i.ids.filter(function(e) { - return !1 === r.includes(e) - }) - }); - return Vo(i) && (l.active = Ho(l)), - l - }({ - state: e, - ids: i - }) - }), - e || this.setHasCache(!1), - this.handleUIRemove(i), - this.entityActions.next({ - type: To.Remove, - ids: i - }))) - } - , - gd.prototype.updateActive = function(e) { - var t = xo(this.active); - Lo && Do("Update Active", t), - this.update(t, e) - } - , - gd.prototype.setActive = function(e) { - e = function(e, t, i) { - var r; - if (No(e)) - r = e; - else if (_o(e)) { - if (Po(i)) - return; - e = Object.assign({ - wrap: !0 - }, e); - var n = t.indexOf(i); - if (e.prev) { - var s = 0 === n; - if (s && !e.wrap) - return; - r = s ? t[t.length - 1] : t[n - 1] - } else if (e.next) { - s = t.length === n + 1; - if (s && !e.wrap) - return; - r = s ? t[0] : t[n + 1] - } - } else { - if (e === i) - return; - r = e - } - return r - }(e, this.ids, this.active); - void 0 !== e && (Lo && Do("Set Active", e), - this._setActive(e)) - } - , - gd.prototype.addActive = function(e) { - var t = this - , i = xo(e); - Bo(i) || i.every(function(e) { - return -1 < t.active.indexOf(e) - }) || (Lo && Do("Add Active", e), - this._setState(function(e) { - var t = Array.from(new Set(mt(e.active, i))); - return ut({}, e, { - active: t - }) - })) - } - , - gd.prototype.removeActive = function(e) { - var t = this - , i = xo(e); - Bo(i) || i.some(function(e) { - return -1 < t.active.indexOf(e) - }) && (Lo && Do("Remove Active", e), - this._setState(function(e) { - return ut({}, e, { - active: Array.isArray(e.active) ? e.active.filter(function(e) { - return -1 === i.indexOf(e) - }) : null - }) - })) - } - , - gd.prototype.toggleActive = function(e) { - var i = this - , t = xo(e) - , r = function(t) { - return function(e) { - return i.active.includes(e) === t - } - } - , e = t.filter(r(!0)) - , r = t.filter(r(!1)); - this.removeActive(e), - this.addActive(r), - Lo && Co("Toggle Active") - } - , - gd.prototype.createUIStore = function(e, t) { - var i = { - name: "UI/" + this.storeName, - idKey: this.idKey - }; - return this.ui = new fd(e = void 0 === e ? {} : e,ut({}, i, t = void 0 === t ? {} : t)), - this.ui - } - , - gd.prototype.destroy = function() { - hd.prototype.destroy.call(this), - this.ui instanceof gd && this.ui.destroy(), - this.entityActions.complete() - } - , - gd.prototype.akitaPreUpdateEntity = function(e, t) { - return t - } - , - gd.prototype.akitaPreAddEntity = function(e) { - return e - } - , - gd.prototype.akitaPreCheckEntity = function(e) { - return e - } - , - Object.defineProperty(gd.prototype, "ids", { - get: function() { - return this._value().ids - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(gd.prototype, "entities", { - get: function() { - return this._value().entities - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(gd.prototype, "active", { - get: function() { - return this._value().active - }, - enumerable: !0, - configurable: !0 - }), - gd.prototype._setActive = function(t) { - this._setState(function(e) { - return ut({}, e, { - active: t - }) - }) - } - , - gd.prototype.handleUICreation = function(e) { - var r = this - , t = this.ids - , n = Uo(this.ui._akitaCreateEntityFn) - , i = function(e) { - var t = r.entities[e] - , i = n ? r.ui._akitaCreateEntityFn(t) : r.ui._akitaCreateEntityFn; - return ut(((e = {})[r.idKey] = t[r.idKey], - e), i) - } - , i = ((e = void 0 === e ? !1 : e) ? this.ids.filter(function(e) { - return $o(r.ui.entities[e]) - }) : t).map(i); - e ? this.ui.add(i) : this.ui.set(i) - } - , - gd.prototype.hasInitialUIState = function() { - return this.hasUIStore() && !1 === $o(this.ui._akitaCreateEntityFn) - } - , - gd.prototype.handleUIRemove = function(e) { - this.hasUIStore() && this.ui.remove(e) - } - , - gd.prototype.hasUIStore = function() { - return this.ui instanceof fd - } - , - ct([ad(), ht("design:type", Function), ht("design:paramtypes", [Object, Object, Object, Object]), ht("design:returntype", void 0)], gd.prototype, "upsert", null), - ct([ad(), ht("design:type", Function), ht("design:paramtypes", ["function" == typeof (w = "undefined" != typeof T && T) ? w : Object]), ht("design:returntype", void 0)], gd.prototype, "toggleActive", null), - gd), fd = (lt(md, cd = pd), - md.prototype.setInitialEntityState = function(e) { - this._akitaCreateEntityFn = e - } - , - md); - function md(e, t) { - return cd.call(this, e = void 0 === e ? {} : e, t = void 0 === t ? {} : t) || this - } - function gd(e, t) { - void 0 === t && (t = {}); - e = hd.call(this, ut({}, { - entities: {}, - ids: [], - loading: !0, - error: null - }, e = void 0 === e ? {} : e), t) || this; - return e.options = t, - e.entityActions = new zt, - e.entityIdChanges = new zt, - e - } - function yd() { - return Es(function(e, t) { - return e === t || !1 !== No(e) && !1 !== No(t) && (!(!Bo(e) || !Bo(t)) || !vd(t, e) && !1 === vd(e, t)) - }) - } - function vd(e, t) { - return t.some(function(t) { - return void 0 === e.find(function(e) { - return e === t - }) - }) - } - function Sd(i, e) { - for (var r, n, s, a = [], o = i.ids, d = i.entities, l = e.filterBy, t = e.limitTo, u = e.sortBy, e = e.sortByOrder, c = 0; c < o.length; c++) - !function(t) { - var i = d[o[t]]; - if (!l) - return a.push(i); - xo(l).every(function(e) { - return e(i, t) - }) && a.push(i) - }(c); - u && (s = Uo(u) ? u : (r = u, - void 0 === (n = e) && (n = ud.ASC), - function(e, t) { - if (!e.hasOwnProperty(r) || !t.hasOwnProperty(r)) - return 0; - var i = "string" == typeof e[r] ? e[r].toUpperCase() : e[r] - , e = "string" == typeof t[r] ? t[r].toUpperCase() : t[r] - , t = 0; - return e < i ? t = 1 : i < e && (t = -1), - n == ud.DESC ? -1 * t : t - } - ), - a = a.sort(function(e, t) { - return s(e, t, i) - })); - t = Math.min(t || a.length, a.length); - return t === a.length ? a : a.slice(0, t) - } - function bd(e) { - return "string" == typeof e - } - function Td(t, i) { - return function(e) { - e = e[t]; - if (!$o(e)) - return i ? bd(i) ? e[i] : i(e) : e - } - } - (yi = ud = ud || {}).ASC = "asc", - yi.DESC = "desc"; - Ed.prototype.select = function(t) { - var e, n; - if (Uo(t)) - e = t; - else if (bd(t)) - e = function(e) { - return e[t] - } - ; - else { - if (Array.isArray(t)) - return this.store._select(function(e) { - return e - }).pipe(Es((n = t, - function(t, i) { - var r = Uo(n[0]); - return !1 === n.some(function(e) { - return r ? e(t) !== e(i) : t[e] !== i[e] - }) - } - )), ur(function(i) { - return Uo(t[0]) ? t.map(function(e) { - return e(i) - }) : t.reduce(function(e, t) { - return e[t] = i[t], - e - }, {}) - })); - e = function(e) { - return e - } - } - return this.store._select(e) - } - , - Ed.prototype.selectLoading = function() { - return this.select(function(e) { - return e.loading - }) - } - , - Ed.prototype.selectError = function() { - return this.select(function(e) { - return e.error - }) - } - , - Ed.prototype.getValue = function() { - return this.store._value() - } - , - Ed.prototype.selectHasCache = function() { - return this.store._cache().asObservable() - } - , - Ed.prototype.getHasCache = function() { - return this.store._cache().value - } - , - Object.defineProperty(Ed.prototype, "config", { - get: function() { - return this.constructor.akitaQueryConfig - }, - enumerable: !0, - configurable: !0 - }), - Si = Ed; - function Ed(e) { - this.store = e, - this.__store__ = e, - Lo && (ed[e.storeName] = this) - } - function Id(e) { - return e.pipe(an(function(e) { - return null != e - })) - } - var wd, Ad, Od = (lt(Dd, Ad = Si), - Dd.prototype.selectAll = function(e) { - var t = this; - return void 0 === e && (e = { - asObject: !1 - }), - this.select(function(e) { - return e.entities - }).pipe(ur(function() { - return t.getAll(e) - })) - } - , - Dd.prototype.getAll = function(e) { - return (e = void 0 === e ? { - asObject: !1, - filterBy: void 0, - limitTo: void 0 - } : e).asObject ? function(e, t) { - var r = {} - , n = t.filterBy - , s = t.limitTo - , a = e.ids - , o = e.entities; - if (!n && !s) - return o; - e = !1 === Po(s); - if (n && e) - for (var d = 0, i = 0, l = a.length; i < l && "break" !== function(t) { - if (d === s) - return "break"; - var e = a[t] - , i = o[e]; - xo(n).every(function(e) { - return e(i, t) - }) && (r[e] = i, - d++) - }(i); i++) - ; - else - for (var u = Math.min(s || a.length, a.length), i = 0; i < u; i++) - !function(t) { - var e = a[t] - , i = o[e]; - if (!n) - return r[e] = i; - xo(n).every(function(e) { - return e(i, t) - }) && (r[e] = i) - }(i); - return r - }(this.getValue(), e) : (t = e, - i = this.config || this.options, - t.sortBy = t.sortBy || i && i.sortBy, - t.sortByOrder = t.sortByOrder || i && i.sortByOrder, - Sd(this.getValue(), e)); - var t, i - } - , - Dd.prototype.selectMany = function(e, i) { - return e && e.length ? this.select(function(e) { - return e.entities - }).pipe(ur(function(t) { - return n = function(e) { - return Td(e, i)(t) - } - , - e.reduce(function(e, t, i, r) { - t = n(t); - return void 0 !== t && e.push(t), - e - }, []); - var n - }), yd()) : Bi([]) - } - , - Dd.prototype.selectEntity = function(e, t) { - var i = e; - return Uo(e) && (i = function(e, t) { - var i, r; - try { - for (var n = pt(Object.keys(t)), s = n.next(); !s.done; s = n.next()) { - var a = s.value; - if (!0 === e(t[a])) - return a - } - } catch (e) { - i = { - error: e - } - } finally { - try { - s && !s.done && (r = n.return) && r.call(n) - } finally { - if (i) - throw i.error - } - } - }(e, this.getValue().entities)), - this.select(function(e) { - return e.entities - }).pipe(ur(Td(i, t)), Es()) - } - , - Dd.prototype.getEntity = function(e) { - return this.getValue().entities[e] - } - , - Dd.prototype.selectActiveId = function() { - return this.select(function(e) { - return e.active - }) - } - , - Dd.prototype.getActiveId = function() { - return this.getValue().active - } - , - Dd.prototype.selectActive = function(t) { - var i = this; - return No(this.getActive()) ? this.selectActiveId().pipe(Ra(function(e) { - return i.selectMany(e, t) - })) : this.selectActiveId().pipe(Ra(function(e) { - return i.selectEntity(e, t) - })) - } - , - Dd.prototype.getActive = function() { - var t = this - , e = this.getActiveId(); - return No(e) ? e.map(function(e) { - return t.getValue().entities[e] - }) : Yo(e) ? this.getEntity(e) : void 0 - } - , - Dd.prototype.selectCount = function(e) { - var t = this; - return this.select(function(e) { - return e.entities - }).pipe(ur(function() { - return t.getCount(e) - })) - } - , - Dd.prototype.getCount = function(e) { - return (Uo(e) ? this.getAll().filter(e) : this.getValue().ids).length - } - , - Dd.prototype.selectLast = function(e) { - return this.selectAt(function(e) { - return e[e.length - 1] - }, e) - } - , - Dd.prototype.selectFirst = function(e) { - return this.selectAt(function(e) { - return e[0] - }, e) - } - , - Dd.prototype.selectEntityAction = function(e) { - if (Po(e)) - return this.store.selectEntityAction$; - var t = No(e) ? function(e) { - return e - } - : function(e) { - return e.ids - } - , i = xo(e); - return this.store.selectEntityAction$.pipe(an(function(e) { - e = e.type; - return i.includes(e) - }), ur(function(e) { - return t(e) - })) - } - , - Dd.prototype.hasEntity = function(e) { - var t = this; - return Po(e) ? 0 < this.getValue().ids.length : Uo(e) ? this.getAll().some(e) : No(e) ? e.every(function(e) { - return e in t.getValue().entities - }) : e in this.getValue().entities - } - , - Dd.prototype.hasActive = function(e) { - var t = this.getValue().active - , i = Fo(e); - return Array.isArray(t) ? i ? t.includes(e) : 0 < t.length : i ? t === e : Fo(t) - } - , - Dd.prototype.createUIQuery = function() { - this.ui = new kd(this.__store__.ui) - } - , - Dd.prototype.selectAt = function(e, t) { - var i = this; - return this.select(function(e) { - return e.ids - }).pipe(ur(e), Es(), Ra(function(e) { - return i.selectEntity(e, t) - })) - } - , - Dd), kd = (lt(Cd, wd = Od), - Cd); - function Cd(e) { - return wd.call(this, e) || this - } - function Dd(e, t) { - void 0 === t && (t = {}); - var i = Ad.call(this, e) || this; - return i.options = t, - i.__store__ = e, - i - } - function Md(e, t) { - return 1 === t.split(".").length ? e : t.split(".").slice(1).join(".").split(".").reduce(function(e, t) { - return e && e[t] - }, e) - } - function Pd(e, t, r) { - var i = t.split("."); - if (1 === i.length) - return ut({}, e, r); - e = ut({}, e); - var n = i.length - 2; - return t.split(".").slice(1).reduce(function(e, t, i) { - return e[t] = i !== n ? ut({}, e[t]) : Array.isArray(e[t]) || !_o(e[t]) ? r : ut({}, e[t], r), - e && e[t] - }, e), - e - } - new Xi(1); - var xd, Rd, Ld, _d, A = (Fd.prototype.getQuery = function() { - return this.query - } - , - Fd.prototype.getStore = function() { - return this.getQuery().__store__ - } - , - Fd.prototype.isEntityBased = Yo, - Fd.prototype.selectSource = function(e, t) { - var i = this; - return this.isEntityBased(e) ? this.getQuery().selectEntity(e).pipe(Id) : t ? this.getQuery().select(function(e) { - return Md(e, i.withStoreName(t)) - }) : this.getQuery().select() - } - , - Fd.prototype.getSource = function(e, t) { - if (this.isEntityBased(e)) - return this.getQuery().getEntity(e); - e = this.getQuery().getValue(); - return t ? Md(e, this.withStoreName(t)) : e - } - , - Fd.prototype.withStoreName = function(e) { - return this.storeName + "." + e - } - , - Object.defineProperty(Fd.prototype, "storeName", { - get: function() { - return this.getStore().storeName - }, - enumerable: !0, - configurable: !0 - }), - Fd.prototype.updateStore = function(t, e, i) { - var r = this; - this.isEntityBased(e) ? this.getStore().update(e, t) : i ? this.getStore()._setState(function(e) { - return Pd(e, r.withStoreName(i), t) - }) : this.getStore()._setState(function(e) { - return ut({}, e, t) - }) - } - , - Fd.prototype.onReset = function(i) { - var r = this - , n = this.getStore().reset; - this.getStore().reset = function() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - setTimeout(function() { - n.apply(r.getStore(), e), - i() - }) - } - } - , - Fd), Nd = { - pagesControls: !1, - range: !1, - startWith: 1, - cacheTimeout: void 0, - clearStoreWithCache: !0 - }; - function Fd(e, t) { - this.query = e - } - function Bd(e, t, i) { - void 0 === i && (i = {}); - var r = xd.call(this, e) || this; - return r.query = e, - r.factoryFnOrPath = t, - r.params = i, - r.params = ut({ - debounceTime: 300, - formKey: "akitaForm", - emitEvent: !1, - arrControlFactory: function(e) { - return r.builder.control(e) - } - }, i), - r.isRootKeys = !1 === Yo(t), - r.isKeyBased = bd(t) || r.isRootKeys, - r - } - function Ud(e, t) { - void 0 === t && (t = {}); - var i = Rd.call(this, e, { - resetFn: function() { - i.initial = !1, - i.destroy({ - clearCache: !0, - currentPage: 1 - }) - } - }) || this; - i.query = e, - i.config = t, - i.metadata = new Map, - i.pages = new Map, - i.pagination = { - currentPage: 1, - perPage: 0, - total: 0, - lastPage: 0, - data: [] - }, - i.initial = !0, - i.isLoading$ = i.query.selectLoading().pipe(ss(0)), - i.config = Object.assign(Nd, t); - e = i.config, - t = e.startWith, - e = e.cacheTimeout; - return i.page = new gi(t), - e && (e instanceof Ut || "function" == typeof e.lift && "function" == typeof e.subscribe) && (i.clearCacheSubscription = e.subscribe(function() { - return i.clearCache() - })), - i - } - lt(Ud, Rd = A), - Object.defineProperty(Ud.prototype, "pageChanges", { - get: function() { - return this.page.asObservable() - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(Ud.prototype, "currentPage", { - get: function() { - return this.pagination.currentPage - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(Ud.prototype, "isFirst", { - get: function() { - return 1 === this.currentPage - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(Ud.prototype, "isLast", { - get: function() { - return this.currentPage === this.pagination.lastPage - }, - enumerable: !0, - configurable: !0 - }), - Ud.prototype.withControls = function() { - return this.config.pagesControls = !0, - this - } - , - Ud.prototype.withRange = function() { - return this.config.range = !0, - this - } - , - Ud.prototype.setLoading = function(e) { - void 0 === e && (e = !0), - this.getStore().setLoading(e) - } - , - Ud.prototype.update = function(e) { - this.pagination = e, - this.addPage(e.data) - } - , - Ud.prototype.addPage = function(e) { - var t = this; - this.pages.set(this.currentPage, { - ids: e.map(function(e) { - return e[t.getStore().idKey] - }) - }), - this.getStore().upsertMany(e) - } - , - Ud.prototype.clearCache = function(e) { - void 0 === e && (e = {}), - this.initial || (Co("@Pagination - Clear Cache"), - !1 !== e.clearStore && (this.config.clearStoreWithCache || e.clearStore) && this.getStore().remove(), - this.pages = new Map, - this.metadata = new Map), - this.initial = !1 - } - , - Ud.prototype.clearPage = function(e) { - this.pages.delete(e) - } - , - Ud.prototype.destroy = function(e) { - var t = void 0 === e ? {} : e - , e = t.clearCache - , t = t.currentPage; - this.clearCacheSubscription && this.clearCacheSubscription.unsubscribe(), - e && this.clearCache(), - $o(t) || this.setPage(t), - this.initial = !0 - } - , - Ud.prototype.isPageActive = function(e) { - return this.currentPage === e - } - , - Ud.prototype.setPage = function(e) { - e === this.currentPage && this.hasPage(e) || this.page.next(this.pagination.currentPage = e) - } - , - Ud.prototype.nextPage = function() { - this.currentPage !== this.pagination.lastPage && this.setPage(this.pagination.currentPage + 1) - } - , - Ud.prototype.prevPage = function() { - 1 < this.pagination.currentPage && this.setPage(this.pagination.currentPage - 1) - } - , - Ud.prototype.setLastPage = function() { - this.setPage(this.pagination.lastPage) - } - , - Ud.prototype.setFirstPage = function() { - this.setPage(1) - } - , - Ud.prototype.hasPage = function(e) { - return this.pages.has(e) - } - , - Ud.prototype.getPage = function(e) { - var t = this - , i = this.pagination.currentPage; - return this.hasPage(i) ? this.selectPage(i) : (this.setLoading(!0), - Lr(e()).pipe(Ra(function(e) { - return i = e.currentPage, - sd(function() { - t.setLoading(!1), - t.update(e) - }), - t.selectPage(i) - }))) - } - , - Ud.prototype.getQuery = function() { - return this.query - } - , - Ud.prototype.refreshCurrentPage = function() { - !1 === Po(this.currentPage) && (this.clearPage(this.currentPage), - this.setPage(this.currentPage)) - } - , - Ud.prototype.getFrom = function() { - return this.isFirst ? 1 : (this.currentPage - 1) * this.pagination.perPage + 1 - } - , - Ud.prototype.getTo = function() { - return this.isLast ? this.pagination.total : this.currentPage * this.pagination.perPage - } - , - Ud.prototype.selectPage = function(n) { - var s = this; - return this.query.selectAll({ - asObject: !0 - }).pipe(Cs(1), ur(function(t) { - var e = ut({}, s.pagination, { - data: s.pages.get(n).ids.map(function(e) { - return t[e] - }) - }) - , i = s.config - , r = i.range - , i = i.pagesControls; - return isNaN(s.pagination.total) && (1 === e.lastPage ? e.total = e.data ? e.data.length : 0 : e.total = e.perPage * e.lastPage, - s.pagination.total = e.total), - r && (e.from = s.getFrom(), - e.to = s.getTo()), - i && (e.pageControls = function(e, t) { - for (var i = Math.ceil(e / t), r = [], n = 0; n < i; n++) - r.push(n + 1); - return r - }(s.pagination.total, s.pagination.perPage)), - e - })) - } - , - ct([(Ld = "@Pagination - New Page", - function(e, t, i) { - var r = i.value; - return i.value = function() { - for (var e = [], t = 0; t < arguments.length; t++) - e[t] = arguments[t]; - return Co(Ld, _d), - r.apply(this, e) - } - , - i - } - ), ht("design:type", Function), ht("design:paramtypes", [Object]), ht("design:returntype", void 0)], Ud.prototype, "update", null), - lt(Bd, xd = A), - Bd.prototype.setForm = function(e, t) { - return this.form = e, - this.builder = t, - this.activate(), - this - } - , - Bd.prototype.reset = function(e) { - var r = this - , e = e || (this.isKeyBased ? this.initialValue : this.factoryFnOrPath()); - this.isKeyBased && Object.keys(this.initialValue).forEach(function(i) { - var e, t = r.initialValue[i]; - Array.isArray(t) && r.builder && (e = r.form.controls[i], - r.cleanArray(e), - t.forEach(function(e, t) { - r.form.get(i).insert(t, r.params.arrControlFactory(e)) - })) - }), - this.form.patchValue(e, { - emitEvent: this.params.emitEvent - }); - var t = this.isKeyBased ? Pd(this.getQuery().getValue(), this.getStore().storeName + "." + this.factoryFnOrPath, e) : ((t = {})[this.params.formKey] = e, - t); - this.updateStore(t) - } - , - Bd.prototype.cleanArray = function(e) { - for (; 0 !== e.length; ) - e.removeAt(0) - } - , - Bd.prototype.resolveInitialValue = function(e, n) { - var s = this; - if (e) - return Object.keys(e).reduce(function(e, i) { - var r, t = n[i]; - return Array.isArray(t) && s.builder && (r = s.params.arrControlFactory, - s.cleanArray(s.form.get(i)), - t.forEach(function(e, t) { - s.form.get(i).insert(t, r(e)) - })), - e[i] = n[i], - e - }, {}) - } - , - Bd.prototype.activate = function() { - var i, e, t, r = this; - this.isKeyBased ? (this.isRootKeys ? this.initialValue = this.resolveInitialValue(this.form.value, this.getQuery().getValue()) : (i = this.getStore().storeName + "." + this.factoryFnOrPath, - e = Md(this.getQuery().getValue(), i), - this.initialValue = this.resolveInitialValue(e, e)), - this.form.patchValue(this.initialValue, { - emitEvent: this.params.emitEvent - })) : (this.getQuery().getValue()[this.params.formKey] || (Co("@PersistNgFormPlugin activate"), - this.updateStore(((t = {})[this.params.formKey] = this.factoryFnOrPath(), - t))), - t = this.getQuery().getValue()[this.params.formKey], - this.form.patchValue(t)), - this.formChanges = this.form.valueChanges.pipe(Qn(this.params.debounceTime)).subscribe(function(t) { - var e; - Co("@PersistForm - Update"), - e = r.isKeyBased ? r.isRootKeys ? function(e) { - return ut({}, e, t) - } - : function(e) { - return Pd(e, i, t) - } - : function() { - var e; - return (e = {})[r.params.formKey] = t, - e - } - , - r.updateStore(e(r.getQuery().getValue())) - }) - } - , - Bd.prototype.destroy = function() { - this.formChanges && this.formChanges.unsubscribe(), - this.form = null, - this.builder = null - } - ; - var $d, Vd, Br = (jd.prototype.getEntity = function(e) { - return this.entities.get(e) - } - , - jd.prototype.hasEntity = function(e) { - return this.entities.has(e) - } - , - jd.prototype.removeEntity = function(e) { - return this.destroy(e), - this.entities.delete(e) - } - , - jd.prototype.createEntity = function(e, t) { - return this.entities.set(e, t) - } - , - jd.prototype.getIds = function() { - return $o(this.entityIds) ? this.query.getValue().ids : xo(this.entityIds) - } - , - jd.prototype.resolvedIds = function(e) { - return $o(e) ? this.getIds() : xo(e) - } - , - jd.prototype.rebase = function(i, r) { - var n = this; - if (void 0 === r && (r = {}), - Yo(i)) - if ($o(this.entityIds)) { - for (var e = 0, t = i.length; e < t; e++) { - var s, a = i[e]; - !1 === this.hasEntity(a) && (Uo(r.beforeAdd) && r.beforeAdd(a), - s = this.instantiatePlugin(a), - this.entities.set(a, s), - Uo(r.afterAdd) && r.afterAdd(s)) - } - this.entities.forEach(function(e, t) { - -1 === i.indexOf(t) && (Uo(r.beforeRemove) && r.beforeRemove(e), - n.removeEntity(t)) - }) - } else - for (var o = xo(this.entityIds), e = 0, t = o.length; e < t; e++) - a = o[e], - -1 < i.indexOf(a) && !1 === this.hasEntity(a) ? (Uo(r.beforeAdd) && r.beforeAdd(a), - s = this.instantiatePlugin(a), - this.entities.set(a, s), - Uo(r.afterAdd) && r.afterAdd(s)) : this.entities.forEach(function(e, t) { - -1 === i.indexOf(t) && !0 === n.hasEntity(t) && (Uo(r.beforeRemove) && r.beforeRemove(e), - n.removeEntity(t)) - }); - else - this.getIds().forEach(function(e) { - n.hasEntity(e) || n.createEntity(e, n.instantiatePlugin(e)) - }) - } - , - jd.prototype.selectIds = function() { - return this.query.select(function(e) { - return e.ids - }) - } - , - jd.prototype.activate = function(e) { - this.rebase(e) - } - , - jd.prototype.forEachId = function(e, t) { - for (var i = this.resolvedIds(e), r = 0, n = i.length; r < n; r++) { - var s = i[r]; - this.hasEntity(s) && t(this.getEntity(s)) - } - } - , - jd), Kd = (lt(Hd, $d = A), - Object.defineProperty(Hd.prototype, "hasPast$", { - get: function() { - return this._hasPast$ - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(Hd.prototype, "hasFuture$", { - get: function() { - return this._hasFuture$ - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(Hd.prototype, "hasPast", { - get: function() { - return 0 < this.history.past.length - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(Hd.prototype, "hasFuture", { - get: function() { - return 0 < this.history.future.length - }, - enumerable: !0, - configurable: !0 - }), - Object.defineProperty(Hd.prototype, "property", { - get: function() { - return this.params.watchProperty - }, - enumerable: !0, - configurable: !0 - }), - Hd.prototype.updateHasHistory = function() { - this.hasFutureSubject.next(this.hasFuture), - this.hasPastSubject.next(this.hasPast) - } - , - Hd.prototype.activate = function() { - var r = this; - this.hasPastSubject = new gi(!1), - this._hasPast$ = this.hasPastSubject.asObservable().pipe(Es()), - this.hasFutureSubject = new gi(!1), - this._hasFuture$ = this.hasFutureSubject.asObservable().pipe(Es()), - this.history.present = this.getSource(this._entityId, this.property), - this.subscription = this.selectSource(this._entityId, this.property).pipe(ca()).subscribe(function(e) { - var t = ft(e, 2) - , i = t[0] - , e = t[1]; - r.skip ? r.skip = !1 : (t = r.params.comparator(i, e), - !r.skipUpdate && t && (r.history.past.length === r.params.maxAge && (r.history.past = r.history.past.slice(1)), - r.history.past = mt(r.history.past, [i]), - r.history.present = e, - r.updateHasHistory())) - }) - } - , - Hd.prototype.undo = function() { - var e, t, i; - 0 < this.history.past.length && (e = (i = this.history).past, - t = i.present, - i = e[e.length - 1], - this.history.past = e.slice(0, e.length - 1), - this.history.present = i, - this.history.future = mt([t], this.history.future), - this.update()) - } - , - Hd.prototype.redo = function() { - var e, t, i, r; - 0 < this.history.future.length && (e = (r = this.history).past, - t = r.present, - i = this.history.future[0], - r = this.history.future.slice(1), - this.history.past = mt(e, [t]), - this.history.present = i, - this.history.future = r, - this.update("Redo")) - } - , - Hd.prototype.jumpToPast = function(e) { - var t, i, r, n; - e < 0 || e >= this.history.past.length || (t = (r = this.history).past, - n = r.future, - i = r.present, - r = t.slice(0, e), - n = mt(t.slice(e + 1), [i], n), - e = t[e], - this.history.past = r, - this.history.present = e, - this.history.future = n, - this.update()) - } - , - Hd.prototype.jumpToFuture = function(e) { - var t, i, r; - e < 0 || e >= this.history.future.length || (i = (r = this.history).past, - t = r.future, - i = mt(i, [r.present], t.slice(0, e)), - r = t[e], - e = t.slice(e + 1), - this.history.past = i, - this.history.present = r, - this.history.future = e, - this.update("Redo")) - } - , - Hd.prototype.jump = function(e) { - return 0 < e ? this.jumpToFuture(e - 1) : e < 0 ? this.jumpToPast(this.history.past.length + e) : void 0 - } - , - Hd.prototype.clear = function(e) { - this.history = Uo(e) ? e(this.history) : { - past: [], - present: null, - future: [] - }, - this.updateHasHistory() - } - , - Hd.prototype.destroy = function(e) { - (e = void 0 === e ? !1 : e) && this.clear(), - this.subscription.unsubscribe() - } - , - Hd.prototype.ignoreNext = function() { - this.skip = !0 - } - , - Hd.prototype.update = function(e) { - void 0 === e && (e = "Undo"), - this.skipUpdate = !0, - Co("@StateHistory - " + e), - this.updateStore(this.history.present, this._entityId, this.property), - this.updateHasHistory(), - this.skipUpdate = !1 - } - , - Hd); - function Hd(e, t, i) { - void 0 === t && (t = {}); - var r = $d.call(this, e, { - resetFn: function() { - return r.clear() - } - }) || this; - return r.query = e, - r.params = t, - r._entityId = i, - r.skip = !1, - r.history = { - past: [], - present: null, - future: [] - }, - r.skipUpdate = !1, - t.maxAge = t.maxAge || 10, - t.comparator = t.comparator || function() { - return !0 - } - , - r.activate(), - r - } - function jd(e, t) { - this.query = e, - this.entityIds = t, - this.entities = new Map - } - function qd(e, t) { - var i = Vd.call(this, e, (t = void 0 === t ? {} : t).entityIds) || this; - return i.query = e, - (i.params = t).maxAge = Yo(t.maxAge) ? t.maxAge : 10, - i.activate(), - i.selectIds().pipe(Oa(1)).subscribe(function(e) { - return i.activate(e) - }), - i - } - lt(qd, Vd = Br), - qd.prototype.redo = function(e) { - this.forEachId(e, function(e) { - return e.redo() - }) - } - , - qd.prototype.undo = function(e) { - this.forEachId(e, function(e) { - return e.undo() - }) - } - , - qd.prototype.hasPast = function(e) { - if (this.hasEntity(e)) - return this.getEntity(e).hasPast - } - , - qd.prototype.hasFuture = function(e) { - if (this.hasEntity(e)) - return this.getEntity(e).hasFuture - } - , - qd.prototype.jumpToFuture = function(e, t) { - this.forEachId(e, function(e) { - return e.jumpToFuture(t) - }) - } - , - qd.prototype.jumpToPast = function(e, t) { - this.forEachId(e, function(e) { - return e.jumpToPast(t) - }) - } - , - qd.prototype.clear = function(e) { - this.forEachId(e, function(e) { - return e.clear() - }) - } - , - qd.prototype.destroy = function(e, t) { - void 0 === t && (t = !1), - this.forEachId(e, function(e) { - return e.destroy(t) - }) - } - , - qd.prototype.ignoreNext = function(e) { - this.forEachId(e, function(e) { - return e.ignoreNext() - }) - } - , - qd.prototype.instantiatePlugin = function(e) { - return new Kd(this.query,this.params,e) - } - ; - var Qd = { - comparator: function(e, t) { - return JSON.stringify(e) !== JSON.stringify(t) - } - }; - function Gd(e, t) { - return t.split(".").reduce(function(e, t) { - return e && "undefined" !== e[t] ? e[t] : void 0 - }, e) - } - var Wd, zd, Xd = (lt(Yd, Wd = A), - Yd.prototype.reset = function(e) { - var t = this.head; - Uo((e = void 0 === e ? {} : e).updateFn) && (t = this.isEntityBased(this._entityId) ? e.updateFn(this.head, this.getQuery().getEntity(this._entityId)) : e.updateFn(this.head, this.getQuery().getValue())), - Co("@DirtyCheck - Revert"), - this.updateStore(t, this._entityId), - this._reset.next() - } - , - Yd.prototype.setHead = function() { - return this.active ? this.head = this._getHead() : (this.activate(), - this.active = !0), - this.updateDirtiness(!1), - this - } - , - Yd.prototype.isDirty = function() { - return !!this.dirty.value - } - , - Yd.prototype.hasHead = function() { - return !!this.getHead() - } - , - Yd.prototype.destroy = function() { - this.head = null, - this.subscription && this.subscription.unsubscribe(), - this._reset && this._reset.complete() - } - , - Yd.prototype.isPathDirty = function(e) { - var t = this.getHead() - , i = Gd(this.getQuery().getValue(), e) - , e = Gd(t, e); - return this.params.comparator(i, e) - } - , - Yd.prototype.getHead = function() { - return this.head - } - , - Yd.prototype.activate = function() { - var i = this; - this.head = this._getHead(); - var e = this.params.watchProperty ? this.params.watchProperty.map(function(t) { - return i.query.select(function(e) { - return e[t] - }).pipe(ur(function(e) { - return { - val: e, - __akitaKey: t - } - })) - }) : [this.selectSource(this._entityId)]; - this.subscription = Cr.apply(void 0, mt(e)).pipe(Oa(1)).subscribe(function(e) { - $o(i.head) || (e = e.some(function(e) { - var t = e.__akitaKey ? i.head[e.__akitaKey] : i.head - , e = e.__akitaKey ? e.val : e; - return i.params.comparator(t, e) - }), - i.updateDirtiness(e)) - }) - } - , - Yd.prototype.updateDirtiness = function(e) { - this.dirty.next(e) - } - , - Yd.prototype._getHead = function() { - var e = this.getSource(this._entityId); - return e = this.params.watchProperty ? this.getWatchedValues(e) : e - } - , - Yd.prototype.getWatchedValues = function(i) { - return this.params.watchProperty.reduce(function(e, t) { - return e[t] = i[t], - e - }, {}) - } - , - Yd); - function Yd(e, t, i) { - var r = Wd.call(this, e) || this; - return r.query = e, - r.params = t, - r._entityId = i, - r.dirty = new gi(!1), - r.active = !1, - r._reset = new zt, - r.isDirty$ = r.dirty.asObservable().pipe(Es()), - r.reset$ = r._reset.asObservable(), - r.params = ut({}, Qd, t), - r.params.watchProperty && (t = xo(r.params.watchProperty), - e instanceof Od && t.includes("entities") && !t.includes("ids") && t.push("ids"), - r.params.watchProperty = t), - r - } - function Jd() { - return Math.random().toString(36).slice(2) - } - function Zd(e) { - return Cr(e).pipe(Bn(0)) - } - function el(e, t) { - var i = zd.call(this, e, (t = void 0 === t ? {} : t).entityIds) || this; - return i.query = e, - i.params = t, - i._someDirty = new zt, - i.someDirty$ = nn(i.query.select(function(e) { - return e.entities - }), i._someDirty.asObservable()).pipe(Bn(0), ur(function() { - return i.checkSomeDirty() - })), - i.params = ut({}, Qd, t), - i.activate(), - i.selectIds().pipe(Oa(1)).subscribe(function(e) { - zd.prototype.rebase.call(i, e, { - afterAdd: function(e) { - return e.setHead() - } - }) - }), - i - } - lt(el, zd = Br), - el.prototype.setHead = function(e) { - if (this.params.entityIds && e) { - var t = xo(e); - if (!1 === xo(this.params.entityIds).some(function(e) { - return -1 < t.indexOf(e) - })) - return this - } - return this.forEachId(e, function(e) { - return e.setHead() - }), - this._someDirty.next(), - this - } - , - el.prototype.hasHead = function(e) { - return !!this.entities.has(e) && this.getEntity(e).hasHead() - } - , - el.prototype.reset = function(e, t) { - void 0 === t && (t = {}), - this.forEachId(e, function(e) { - return e.reset(t) - }) - } - , - el.prototype.isDirty = function(e, t) { - if (void 0 === t && (t = !0), - this.entities.has(e)) { - e = this.getEntity(e); - return t ? e.isDirty$ : e.isDirty() - } - return !1 - } - , - el.prototype.someDirty = function() { - return this.checkSomeDirty() - } - , - el.prototype.isPathDirty = function(e, t) { - if (this.entities.has(e)) { - var i = this.getEntity(e).getHead() - , e = Gd(this.query.getEntity(e), t) - , t = Gd(i, t); - return this.params.comparator(e, t) - } - return null - } - , - el.prototype.destroy = function(e) { - this.forEachId(e, function(e) { - return e.destroy() - }), - e || this._someDirty.complete() - } - , - el.prototype.instantiatePlugin = function(e) { - return new Xd(this.query,this.params,e) - } - , - el.prototype.checkSomeDirty = function() { - var e, t, i = this.resolvedIds(); - try { - for (var r = pt(i), n = r.next(); !n.done; n = r.next()) { - var s = n.value; - if (this.getEntity(s).isDirty()) - return !0 - } - } catch (t) { - e = { - error: t - } - } finally { - try { - n && !n.done && (t = r.return) && t.call(r) - } finally { - if (e) - throw e.error - } - } - return !1 - } - , - (gc = gc || {}).Update = "UPDATE", - {}[gc.Update] = "update", - (gr = gu = gu || {}).Update = "UPDATE", - gr.AddEntities = "ADD_ENTITIES", - gr.SetEntities = "SET_ENTITIES", - gr.UpdateEntities = "UPDATE_ENTITIES", - gr.RemoveEntities = "REMOVE_ENTITIES", - gr.UpsertEntities = "UPSERT_ENTITIES", - gr.UpsertManyEntities = "UPSERT_MANY_ENTITIES", - (mu = {})[gu.Update] = "update", - mu[gu.AddEntities] = "add", - mu[gu.SetEntities] = "set", - mu[gu.UpdateEntities] = "update", - mu[gu.RemoveEntities] = "remove", - mu[gu.UpsertEntities] = "upsert", - mu[gu.UpsertManyEntities] = "upsertMany"; - const tl = /^((?:[^\/;?#]+:)?)(\/\/[^\/\;?#]*)?(.*?)??(;.*?)?(\?.*?)?(#.*?)?$/ - , il = /^([^\/;?#]*)(.*)$/ - , rl = /(?:\/|^)\.(?=\/)/g - , nl = /(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g - , sl = { - buildAbsoluteURL: function(e, t, i) { - if (i = i || {}, - e = e.trim(), - !(t = t.trim())) { - if (!i.alwaysNormalize) - return e; - const t = sl.parseURL(e); - if (!t) - throw new Error("Error trying to parse base URL."); - return t.path = sl.normalizePath(t.path), - sl.buildURLFromParts(t) - } - const r = sl.parseURL(t); - if (!r) - throw new Error("Error trying to parse relative URL."); - if (r.scheme) - return i.alwaysNormalize ? (r.path = sl.normalizePath(r.path), - sl.buildURLFromParts(r)) : t; - const n = sl.parseURL(e); - if (!n) - throw new Error("Error trying to parse base URL."); - if (!n.netLoc && n.path && "/" !== n.path[0]) { - const e = il.exec(n.path); - n.netLoc = e[1], - n.path = e[2] - } - n.netLoc && !n.path && (n.path = "/"); - const s = { - scheme: n.scheme, - netLoc: r.netLoc, - path: null, - params: r.params, - query: r.query, - fragment: r.fragment - }; - if (!r.netLoc && (s.netLoc = n.netLoc, - "/" !== r.path[0])) - if (r.path) { - i.inheritQuery && (r.query || (s.query = n.query)); - const e = n.path - , t = e.substring(0, e.lastIndexOf("/") + 1) + r.path; - s.path = sl.normalizePath(t) - } else - s.path = n.path, - r.params || (s.params = n.params, - r.query || (s.query = n.query)); - return null === s.path && (s.path = i.alwaysNormalize ? sl.normalizePath(r.path) : r.path), - sl.buildURLFromParts(s) - }, - parseURL: function(e) { - e = tl.exec(e); - return e ? { - scheme: e[1] || "", - netLoc: e[2] || "", - path: e[3] || "", - params: e[4] || "", - query: e[5] || "", - fragment: e[6] || "" - } : null - }, - normalizePath: function(e) { - for (e = e.split("").reverse().join("").replace(rl, ""); e.length !== (e = e.replace(nl, "")).length; ) - ; - return e.split("").reverse().join("") - }, - buildURLFromParts: function(e) { - return e.scheme + e.netLoc + e.path + e.params + e.query + e.fragment - }, - getHostName: function(e) { - let t; - return e && (t = -1 < e.indexOf("://") ? e.split("/")[2] : e.split("/")[0], - t = t.split(":")[0], - t = t.split("?")[0]), - t - } - }; - var al, ol, dl, ll, ul, cl, hl, pl, fl = sl; - function ml(e) { - return null != e && !e.startsWith("http://") && !e.startsWith("https://") - } - function gl(e) { - return null == e || ml(e) ? null : sl.getHostName(e) - } - function yl(e, t) { - return !e || e === gl(t) - } - (w = al = al || {})[w.DOVI = 4] = "DOVI", - w[w.HEVC = 3] = "HEVC", - w[w.VP09 = 2] = "VP09", - w[w.AVC = 1] = "AVC", - w[w.UNKNOWN = 0] = "UNKNOWN", - (yi = ol = ol || {})[yi.PQ = 3] = "PQ", - yi[yi.HLG = 2] = "HLG", - yi[yi.SDR = 1] = "SDR", - yi[yi.UNKNOWN = 0] = "UNKNOWN", - (A = dl = dl || {})[A.ALAC = 7] = "ALAC", - A[A.FLAC = 6] = "FLAC", - A[A.EC3 = 5] = "EC3", - A[A.AC3 = 4] = "AC3", - A[A.XHEAAC = 3] = "XHEAAC", - A[A.AAC = 2] = "AAC", - A[A.MP3 = 1] = "MP3", - A[A.UNKNOWN = 0] = "UNKNOWN", - (Br = ll = ll || {})[Br.VALID = 1] = "VALID", - Br[Br.INVALID = 0] = "INVALID"; - const vl = ["via", "x-apple-request-uuid"] - , Sl = { - maxNumRetry: 4, - retryDelayMs: 0, - maxRetryDelayMs: 0 - } - , bl = { - maxNumRetry: 6, - retryDelayMs: 1e3, - maxRetryDelayMs: 8e3 - } - , Tl = { - maxNumRetry: 0, - retryDelayMs: 0, - maxRetryDelayMs: 0 - } - , El = { - default: { - maxTimeToFirstByteMs: 5e3, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: Tl, - errorRetry: Tl - }, - customURL: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: Tl, - errorRetry: Tl - } - } - , Il = { - maxNumRetry: 8, - retryDelayMs: 1e3, - maxRetryDelayMs: 2e4, - backoff: "linear" - } - , wl = Object.assign(Object.assign({}, Il), { - maxNumRetry: 1 - }) - , Al = { - autoStartLoad: !0, - startPosition: NaN, - defaultAudioCodec: void 0, - defaultVideoCodec: void 0, - debug: !1, - debugLevel: "info", - buildType: void 0, - minFramesBeforeSwitchingLevel: 11, - minTargetDurations: 3, - maxBufferLength: 60, - maxBufferHole: .5, - maxSeekHole: 2, - discontinuitySeekTolerance: 2, - almostDryBufferSec: .5, - maxTotalDurationTolerance: .1, - lowBufferThreshold: .5, - lowBufferWatchdogPeriod: .5, - highBufferWatchdogPeriod: 3, - seekWatchdogPeriod: 5, - nudgeOffset: .1, - nudgeMaxRetry: 3, - maxFragLookUpTolerance: .2, - initialLiveManifestSize: 1, - liveSyncDurationCount: 3, - liveMaxLatencyDurationCount: 1 / 0, - liveSyncDuration: void 0, - liveMaxLatencyDuration: void 0, - liveFlushExpiredFrags: !0, - liveMaxUnchangedPlaylistRefresh: 3, - liveEdgeForZeroStartPositon: !1, - allowFastSwitchUp: !1, - minMatchGroupDuration: 5, - desiredIframeFPS: 8, - initialIframeFPS: 6, - minRemainingTimeInMediaPipeline: 3, - leftMediaTimeToAutoPause: 10, - startTargetDurationFactor: .9, - enableWorker: !0, - enableWebCrypto: !0, - keySystemPreference: void 0, - clearMediaKeysOnPromise: !0, - useMultipleKeySessions: !1, - enablePlayReadyKeySystem: !1, - useMediaKeySystemAccessFilter: !1, - playReadyMessageFormat: "utf16", - startLevel: void 0, - livePlaylistRefreshDelay: 2500, - liveMinPlayingBufferLen: 5, - enableIFramePreloading: !0, - useMediaCapabilities: !1, - enableID3Cues: !0, - certLoadPolicy: El, - keyLoadPolicy: { - default: { - maxTimeToFirstByteMs: 5e3, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: wl, - errorRetry: Il - }, - customURL: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: wl, - errorRetry: Il - } - }, - manifestLoadPolicy: { - default: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: { - maxNumRetry: 2, - retryDelayMs: 0, - maxRetryDelayMs: 0 - }, - errorRetry: { - maxNumRetry: 1, - retryDelayMs: 1e3, - maxRetryDelayMs: 8e3 - } - }, - customURL: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 1e4, - autoRetry: !1, - timeoutRetry: { - maxNumRetry: 2, - retryDelayMs: 0, - maxRetryDelayMs: 0 - }, - errorRetry: { - maxNumRetry: 1, - retryDelayMs: 1e3, - maxRetryDelayMs: 8e3 - } - } - }, - trickPlaybackConfig: { - enabled: !0, - minIframeDuration: 8 - }, - playlistLoadPolicy: { - default: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: { - maxNumRetry: 2, - retryDelayMs: 0, - maxRetryDelayMs: 0 - }, - errorRetry: { - maxNumRetry: 2, - retryDelayMs: 1e3, - maxRetryDelayMs: 8e3 - } - }, - customURL: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 1e4, - autoRetry: !1, - timeoutRetry: { - maxNumRetry: 2, - retryDelayMs: 0, - maxRetryDelayMs: 0 - }, - errorRetry: { - maxNumRetry: 2, - retryDelayMs: 1e3, - maxRetryDelayMs: 8e3 - } - } - }, - fragLoadPolicy: { - default: { - maxTimeToFirstByteMs: 5e3, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: Sl, - errorRetry: bl, - forceContentLenCheckIfNoHeader: !1, - reportCDNServer: !0 - }, - customURL: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: Sl, - errorRetry: bl, - reportCDNServer: !0 - } - }, - steeringManifestLoadPolicy: { - default: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 2e4, - autoRetry: !1, - timeoutRetry: { - maxNumRetry: 2, - retryDelayMs: 0, - maxRetryDelayMs: 0 - }, - errorRetry: { - maxNumRetry: 1, - retryDelayMs: 1e3, - maxRetryDelayMs: 8e3 - } - }, - customURL: { - maxTimeToFirstByteMs: 1e4, - maxLoadTimeMs: 1e4, - autoRetry: !1, - timeoutRetry: { - maxNumRetry: 2, - retryDelayMs: 0, - maxRetryDelayMs: 0 - }, - errorRetry: { - maxNumRetry: 1, - retryDelayMs: 1e3, - maxRetryDelayMs: 8e3 - } - } - }, - maxNumAddLevelToPenaltyBox: 4, - firstAudioMustOverlapVideoStart: !1, - keyMinHoldTimeBeforeCleanup: 15e3, - startFragPrefetch: !1, - appendErrorMaxRetry: 3, - alwaysResetOnNewCC: !1, - fLoader: void 0, - pLoader: void 0, - xhrSetup: void 0, - iframeMaxExitSeekDuration: 2e3, - iframeStallMaxRetry: 5, - audioPrimingDelay: 0, - enableCEA708Captions: !0, - customTextTrackCueRenderer: !1, - enableWebVTT: !0, - captionsTextTrack1Label: "English", - captionsTextTrack1LanguageCode: "en", - captionsTextTrack2Label: "Spanish", - captionsTextTrack2LanguageCode: "es", - enableDualTrackSelection: !1, - condenseSubtitleTrack: !1, - earlyFragTolerance: 7, - vttConcurrentLoadCount: 1, - trottleCheckInterval: 2e3, - subtitleLeadTime: 30, - lateTolerance: 2, - stretchShortVideoTrack: !1, - forceKeyFrameOnDiscontinuity: !0, - useFirstLevelAtIncompatDiscontinuity: !0, - abrBandwidthEstimator: "bandwidth-history-controller", - abrEwmaDefaultEstimate: 5e5, - abrDefaultEstimate: 5e5, - abrBandWidthFactor: .95, - abrBandWidthUpFactor: .9, - abrMaxWithRealBitrate: !1, - maxStarvationDelay: 4, - maxLoadingDelay: 4, - minAutoBitrate: 0, - enableRtcReporting: !1, - rtcIntervalTimeout: 3e5, - rtcSender: "HLSJS", - rtcSessionTag: "none", - useHTTPPlaybackSessionId: !1, - warmupCdms: !1, - enablePerformanceLogging: !1, - overridePlaybackRate: !1, - nativeControlsEnabled: !1, - useCustomMediaFunctions: !0, - seekEventThrottleMs: 150, - enableAdaptiveStartup: !0, - bandwidthHistoryWindowSize: 12e4, - bandwidthHistoryTTL: 6e5, - bandwidthHistoryAggregationMethod: "quadratic-time-weighted", - bandwidthHistoryGetEstimateThrottleMs: 1e3, - defaultTargetDuration: 10, - targetStartupMs: 4e3, - adaptiveStartupMetricsOverride: { - maxValidHeight: 1080, - maxValidBitrate: 1 / 0, - maxPreferredBitrate: 1 / 0 - }, - bandwidthHistoryStorageKey: "AppleHLS-bandwidth-estimation", - storageKeyPrefix: "AppleHLS-", - storage: { - get: "undefined" == typeof localStorage ? void 0 : localStorage.getItem.bind(localStorage), - set: "undefined" == typeof localStorage ? void 0 : localStorage.setItem.bind(localStorage) - }, - minFragmentCount: 10, - minPlaylistCount: 5, - enableCDNFallback: !0, - enableQueryParamsForITunes: !1, - gapless: !1, - useViewportSizeForLevelCap: !1, - statDefaults: { - playlistLoadTimeMs: 500, - playlistParseTimeMs: 50, - fragParseTimeMs: 50, - fragBufferCreationDelayMs: 200, - dataFragAppendMs: 50, - initFragAppendMs: 50 - }, - disableVideoCodecList: new Set([]), - disableAudioCodecList: new Set([dl.ALAC, dl.FLAC, dl.XHEAAC]), - useHighestVideoCodecPrivate: !0, - sessionDataAutoLoad: { - "com.apple.hls.chapters": !0 - } - } - , Ol = Object.assign(Object.assign({}, { - itemId: "Nah", - mediaOptionId: "Nah" - }), { - mediaOptionType: void 0 - }) - , kl = e=>{ - var {itemId: t, mediaOptionId: e} = e; - return "Nah" !== t && "Nah" !== e - } - ; - (gc = ul = ul || {})[gc.Variant = 0] = "Variant", - gc[gc.AltAudio = 1] = "AltAudio", - gc[gc.Subtitle = 2] = "Subtitle"; - const Cl = ["variant", "altAudio", "subtitle"] - , Dl = [ul.Variant, ul.AltAudio, ul.Subtitle] - , Ml = [ul.Variant, ul.AltAudio]; - (gr = cl = cl || {})[gr.Variant = 0] = "Variant", - gr[gr.AltAudio = 1] = "AltAudio"; - const Pl = ["variant", "altAudio"]; - function xl(e) { - switch (e) { - case ul.Variant: - return cl.Variant; - case ul.AltAudio: - return cl.AltAudio; - default: - return null - } - } - function Rl(e) { - return e === cl.Variant ? ul.Variant : ul.AltAudio - } - (mu = hl = hl || {})[mu.NO = 0] = "NO", - mu[mu.YES = 1] = "YES", - (gu = pl = pl || {}).UNKNOWN = "unkn", - gu.VIDEO = "vide", - gu.AUDIO = "soun", - gu.SUBTITLE = "sbtl", - gu.CLOSEDCAPTION = "clcp"; - const Ll = { - search: function(e, t) { - let i, r, n = 0, s = (null == e ? void 0 : e.length) - 1; - for (; n <= s; ) { - var a = t(r = e[i = (n + s) / 2 | 0]); - if (0 < a) - n = 1 + i; - else { - if (!(a < 0)) - return r; - s = i - 1 - } - } - return null - } - }; - var _l = Ll - , Nl = { - findFragmentBySNAndBuffer: function(e, t, i=0, r=0, n=0) { - let s; - e = e ? t[e.mediaSeqNum - t[0].mediaSeqNum + 1] : null; - return s = i < r ? (r - n < i && (n = 0), - e && !this.fragmentWithinToleranceTest(i, n, e) ? e : Ll.search(t, this.fragmentWithinToleranceTest.bind(null, i, n))) : t[t.length - 1], - s - }, - fragmentWithinToleranceTest: function(e, t, i) { - t = Math.min(t, i.duration); - return i.start + i.duration - t <= e ? 1 : i.start - t > e && i.start ? -1 : 0 - } - }; - const Fl = { - startFragmentInCC: function(e, t, i) { - let r = t - i.discoSeqNum; - if (0 === r) { - const t = e[i.mediaSeqNum - e[0].mediaSeqNum - 1]; - r = t && t.discoSeqNum === i.discoSeqNum ? -1 : 0 - } - return r - }, - endFragmentInCC: function(e, t, i) { - let r = t - i.discoSeqNum; - if (0 === r) { - const t = e[i.mediaSeqNum - e[0].mediaSeqNum + 1]; - r = t && t.discoSeqNum === i.discoSeqNum ? 1 : 0 - } - return r - }, - findStartEndFragmentsInCC: function(e, t, i) { - let r, n; - return 0 < (null == e ? void 0 : e.length) && ne(t) && (r = Ll.search(e, Fl.startFragmentInCC.bind(null, e, t)), - n = Ll.search(e, Fl.endFragmentInCC.bind(null, e, t))), - r && !ne(r.discoSeqNum) && (r = void 0), - n && !ne(n.discoSeqNum) && (n = void 0), - { - startFrag: r, - endFrag: n - } - }, - getTimeRangeDictForCC: function(e, t, i) { - var {startFrag: t, endFrag: i} = Fl.findStartEndFragmentsInCC(e, t, i); - return { - start: t.start, - end: i.start + i.duration - } - }, - getTimeRangeForCC: function(e, t, i) { - var {startFrag: t, endFrag: i} = Fl.findStartEndFragmentsInCC(e, t, i); - let r = []; - return t && i && (r = [t.start, i.start + i.duration]), - r - }, - snapToCCTimeRange: function(e, t, i, r) { - r = Fl.getTimeRangeForCC(t, i, r); - return null != r && r.length ? Math.min(r[1], Math.max(r[0], e)) : e - }, - getMinTimeForCC(e, t, i, r) { - if (null == e || !e.length) - return 0; - let n = 0; - if (ne(i) && e) { - e = Fl.getTimeRangeForCC(e, i, r); - if (e) { - const s = Fl.getTimeRangeForCC(t, i, r); - n = null != s && s.length ? Math.max(s[0], e[0]) : e[0] - } - } - return n - }, - ccForTime(e, t) { - t = Ll.search(e, Nl.fragmentWithinToleranceTest.bind(null, t, 0)); - return null == t ? void 0 : t.discoSeqNum - } - }; - var Bl = Fl; - const Ul = Bi(void 0); - function $l(e, t, i=1) { - return e.pipe(an(t), Cs(i)) - } - function Vl(e, t) { - var i = e.timeline; - return { - seconds: (e.seconds - i.rootTimeSeconds) / i.rate * t.rate + t.rootTimeSeconds, - timeline: t - } - } - class Kl { - constructor() { - this._timeline = null - } - get forward() { - var e; - return 0 < (null === (e = this.timeline) || void 0 === e ? void 0 : e.rate) - } - get isStarted() { - return Boolean(this.hostClock) - } - start(e) { - this.stopTime = null, - this._timeline = Object.assign({}, e); - const t = { - rootTimeSeconds: performance.now() / 1e3, - rate: 1 - }; - this.hostClock = { - timeline: t, - getCurrentTime: ()=>({ - seconds: performance.now() / 1e3, - timeline: t - }) - } - } - stop() { - this.isStarted && (this.stopTime = this.getCurrentTime()), - this.hostClock = null, - this._timeline = null - } - get timeline() { - return this._timeline - } - getCurrentTime() { - return this.stopTime || Vl(this.hostClock.getCurrentTime(), this.timeline) - } - } - class Hl { - constructor(e) { - this._timeline = e, - this.lastTimeSeconds = e.rootTimeSeconds - } - get timeline() { - return Object.assign({}, this._timeline) - } - getCurrentTime() { - return { - seconds: this.lastTimeSeconds, - timeline: Object.assign({}, this._timeline) - } - } - } - const jl = { - name: "ifm" - }; - class ql { - constructor(e, t) { - this.config = e, - this.logger = t, - this.scaledFragments = [], - this.iframeClock = new Kl, - this.hasMore$ = new gi(!0), - this.logger = t.child(jl) - } - destroy() { - this.stop() - } - resetScaledSegments() { - this.scaledFragments = [] - } - get anchorFrag() { - return this.scaledFragments.length ? this.scaledFragments[0] : null - } - get lastFrag() { - return this.scaledFragments.length ? this.scaledFragments.slice(-1)[0] : null - } - get isStarted() { - return Boolean(this.iframeClock.isStarted) - } - get iframeRate() { - var e; - return null !== (e = null === (e = this.iframeClock.timeline) || void 0 === e ? void 0 : e.rate) && void 0 !== e ? e : 0 - } - get iframeClockTimeSeconds() { - return this.iframeClock.getCurrentTime().seconds - } - get mediaAppendClockTimeSeconds() { - var e; - return null !== (e = null === (e = this.mediaAppendClock) || void 0 === e ? void 0 : e.getCurrentTime().seconds) && void 0 !== e ? e : 0 - } - stop() { - this.hasMore$.next(!0), - this.iframeClock.stop(), - this.mediaAppendClock = null, - this.resetScaledSegments() - } - checkHasMore() { - this.hasMore$.next(!0) - } - startClocksAndGetFirstFragment(e, t, i, r, n) { - let s = Ll.search(e, Nl.fragmentWithinToleranceTest.bind(null, r, 1e-4)); - if (!s && r >= e[e.length - 1].start && (s = e[e.length - 1]), - !s) - return this.logger.error(`startClocksAndGetFirstFragment => no anchorFrag for time ${r}`), - this.hasMore$.next(!1), - null; - var a = ne(n) ? n : s.discoSeqNum - , a = Bl.getMinTimeForCC(e, t, a, this.logger) - , r = ne(n) && 1 < i ? a : r - , a = 1 < i ? Math.ceil(r) : Math.ceil(a); - return this.iframeClock.start({ - rootTimeSeconds: r, - rate: i - }), - this.mediaAppendClock = new Hl({ - rootTimeSeconds: a, - rate: 1 - }), - { - frag: s, - newMediaRootTime: a - } - } - getNextFragment(e, t, i) { - const r = this.lastFrag - , {iframeClock: n, mediaAppendClock: s} = this - , a = n.timeline; - s.lastTimeSeconds = t; - var o = n.forward ? 1 : -1; - let d, l = Math.max(0, Math.min(r.mediaSeqNum - e[0].mediaSeqNum + o, e.length - 1)); - if (r.mediaSeqNum !== e[l].mediaSeqNum) - do { - d = e[l]; - const i = n.forward ? d.start : d.start + d.duration; - if (Vl({ - seconds: i, - timeline: a - }, s.timeline).seconds >= t && (n.forward && i >= this.iframeClockTimeSeconds || !n.forward && i <= this.iframeClockTimeSeconds)) - break - } while (l += o, - 0 < l && l < e.length); - return d || (this.logger.error(`getNextFragment(bufferEnd: ${t}) => no more frags, but we should have found an end fragment, setting hasMore to false`), - this.hasMore$.next(!1)), - { - frag: d - } - } - nextFragment(e, t, i, r) { - let n, s; - if (this.isStarted && i !== this.iframeRate && (s = this.iframeClockTimeSeconds, - this.stop()), - this.isStarted) { - if (n = this.getNextFragment(e, r, i), - !n.frag) - return; - if (n.frag.discoSeqNum !== this.anchorFrag.discoSeqNum) { - const a = this.iframeClockTimeSeconds; - this.stop(); - const s = this.startClocksAndGetFirstFragment(e, t, i, a, n.frag.discoSeqNum)["newMediaRootTime"]; - n.newMediaRootTime = s - } - } else if (n = this.startClocksAndGetFirstFragment(e, t, i, null != s ? s : r), - !n) - return; - var r = n["frag"] - , r = this.handleNextFrag(e, r); - return Object.assign(Object.assign({}, n), { - frag: r - }) - } - handleNextFrag(e, t) { - const i = Object.assign(Object.assign({}, t), { - iframeMediaStart: NaN, - iframeMediaDuration: NaN - }) - , {mediaAppendClock: r, iframeClock: n} = this; - this.iframeClockBounds = Bl.getTimeRangeDictForCC(e, i.discoSeqNum, this.logger); - var s = r.getCurrentTime().seconds - , t = n.timeline.rate; - return i.start = i.iframeMediaStart = s, - i.iframeMediaDuration = Math.max(i.duration / Math.abs(t), 1 / this.config.minIframeDuration), - this.scaledFragments.push(i), - this.isEndFrag(e, i) && this.hasMore$.next(!1), - i - } - get hasMore() { - return this.hasMore$.value - } - handleWaitForMore() { - return this.isStarted ? (this.iframeClock.getCurrentTime(), - $l(this.hasMore$, e=>!0 === e).pipe(Ja(()=>{} - ))) : Ul - } - isEndFrag(e, t) { - var i = e[0] - , r = e[e.length - 1] - , e = this.iframeClock.forward; - return !e && (null == i ? void 0 : i.mediaSeqNum) === t.mediaSeqNum || e && (null == r ? void 0 : r.mediaSeqNum) === t.mediaSeqNum - } - } - var Ql = {} - , w = {}; - Object.defineProperty(w, "__esModule", { - value: !0 - }), - w.hide = void 0, - w.hide = function() { - return function(e) { - return e.lift(new Gl) - } - } - ; - var Gl = (Wl.prototype.call = function(e, t) { - return t.subscribe(e) - } - , - Wl) - , yi = {}; - function Wl() { - this.hide = !0 - } - Object.defineProperty(yi, "__esModule", { - value: !0 - }), - yi.tag = void 0, - yi.tag = function(t) { - return function(e) { - return e.lift(new Jl(t)) - } - } - ; - var zl, Xl, Yl, Jl = (Zl.prototype.call = function(e, t) { - return t.subscribe(e) - } - , - Zl); - function Zl(e) { - this.tag = e - } - function eu(e) { - const {method: t, isEncrypted: i, uri: r, format: n, formatversions: s} = e - , a = { - method: t, - isEncrypted: i, - uri: r, - format: n, - formatversions: s, - iv: e.ivBuf ? new Uint8Array(e.ivBuf) : null - }; - return e.keyIdBuf && (a.keyId = new Uint8Array(e.keyIdBuf)), - e.keyBuf && (a.key = new Uint8Array(e.keyBuf)), - e.psshBuf && (a.pssh = new Uint8Array(e.psshBuf)), - a - } - A = Ql, - Yl = e && e.__createBinding || (Object.create ? function(e, t, i, r) { - void 0 === r && (r = i), - Object.defineProperty(e, r, { - enumerable: !0, - get: function() { - return t[i] - } - }) - } - : function(e, t, i, r) { - e[r = void 0 === r ? i : r] = t[i] - } - ), - Br = e && e.__exportStar || function(e, t) { - for (var i in e) - "default" === i || t.hasOwnProperty(i) || Yl(t, e, i) - } - , - Object.defineProperty(A, "__esModule", { - value: !0 - }), - Br(w, A), - Br(yi, A), - (gc = zl = zl || {}).MustRequestResponse = "MustRequestResponse", - gc.WaitingForKeyResponse = "WaitingForKeyResponse", - gc.GotKeyResponse = "GotKeyResponse"; - class tu extends Error { - constructor(e, t) { - super(e), - this.code = t - } - } - class iu extends p { - constructor(e, t, i, r, n, s) { - super(o, e, t, i, n), - this.code = r, - this.isTimeout = s, - this.response = n - } - } - class ru extends iu { - constructor(e, t, i, r, n) { - super(n ? "manifestLoadTimeOut" : "manifestLoadError", e, t, i, r, n) - } - } - class nu extends iu { - constructor(e, t, i, r, n, s, a, o) { - switch (super("", e, t, i, r, n), - this.mediaOptionType = s, - this.mediaOptionId = a, - this.url = o, - s) { - case ul.Variant: - this.details = n ? "levelLoadTimeOut" : N; - break; - case ul.AltAudio: - this.details = n ? "audioTrackLoadTimeOut" : "audioTrackLoadError"; - break; - case ul.Subtitle: - this.details = n ? "subtitleTrackLoadTimeout" : "subtitleTrackLoadError" - } - } - } - class su extends iu { - constructor(e, t, i, r) { - super("sessionDataLoadError", e, t, i, r, !1) - } - } - class au extends iu { - constructor(e, t, i, r, n, s, a) { - super(n ? "fragLoadTimeOut" : "fragLoadError", e, t, i, r, n), - this.mediaOptionId = s.mediaOptionId, - this.mediaOptionType = s.mediaOptionType, - this.stats = a - } - } - class ou extends or { - constructor(e, t, i) { - super(), - this.message = e, - this.code = t, - this.stats = i - } - } - class du extends iu { - constructor(e, t, i) { - super("fragAbortError", !1, "Fragment abort", 0, i, !1), - this.candidateMediaOptionId = t, - this.mediaOptionId = e.mediaOptionId, - this.mediaOptionType = e.mediaOptionType - } - } - class lu extends iu { - constructor(e, t, i, r=[]) { - super("keyLoadTimeOut", !1, e, i.code, i, !0), - this.keyuri = t, - this.response = i, - this.mediaOptionIds = r - } - } - (gr = Xl = Xl || {})[gr.InvalidState = 0] = "InvalidState", - gr[gr.Abort = 1] = "Abort", - gr[gr.OutputRestricted = 2] = "OutputRestricted", - gr[gr.AlreadyFailedKey = 3] = "AlreadyFailedKey", - gr[gr.HttpError = 4] = "HttpError", - gr[gr.InternalError = 5] = "InternalError", - gr[gr.LicenseServerError = 6] = "LicenseServerError", - gr[gr.InsufficientCPC = 7] = "InsufficientCPC"; - class uu extends iu { - constructor(e, t, i, r, n, s, a=!1, o=[]) { - super("keyLoadError", a, e, i, r, !1), - this.keyuri = t, - this.isOkToRetry = n, - this.keyErrorReason = s, - this.mediaOptionIds = o - } - } - class cu extends p { - constructor(e, t, i, r, n) { - super(s, "keySystemGenericError", !0, e, r), - this.keyuri = t, - this.code = i, - this.response = r, - this.keysystemstring = n - } - } - function hu(e, t) { - return e instanceof uu ? new uu(e.message,e.keyuri,e.code,e.response,e.isOkToRetry,e.keyErrorReason,e.fatal,t) : e instanceof lu ? new lu(e.message,e.keyuri,$.CryptResponseReceivedSlowly,t) : e ? new V(e.fatal,e.reason,$.InternalError) : null - } - const pu = { - id: "fairplaystreaming", - systemStringPrefix: "com.apple.fps", - keyFormatString: "com.apple.streamingkeydelivery", - securityLevels: { - AppleBaseline: 0, - AppleMain: 1, - Main: 1, - Baseline: 0 - } - }; - class fu extends Od { - constructor(e) { - super(e), - this.store = e - } - get unresolvedUriLoading$() { - return this.selectEntityAction(To.Add).pipe(ur(e=>e.map(e=>this.getEntity(e)))) - } - } - var mu = {}; - Object.defineProperty(mu, "__esModule", { - value: !0 + logger._logEvent.ts = ts; + logger._logEvent.messages = args.filter(function (arg) { + // bindings can only be objects, so reference equality check via indexOf is fine + return bindings.indexOf(arg) === -1 }); - var gu = "undefined" != typeof Symbol && "symbol" == typeof Symbol("x") - , yu = "undefined" != typeof Map - , vu = "undefined" != typeof Set - , Su = "undefined" != typeof Proxy && void 0 !== Proxy.revocable && "undefined" != typeof Reflect - , bu = gu ? Symbol.for("immer-nothing") : ((yc = {})["immer-nothing"] = !0, - yc) - , Tu = gu ? Symbol.for("immer-draftable") : "__$immer_draftable" - , Eu = gu ? Symbol.for("immer-state") : "__$immer_state" - , Iu = "undefined" != typeof Symbol && Symbol.iterator || "@@iterator" - , wu = { - 0: "Illegal state", - 1: "Immer drafts cannot have computed properties", - 2: "This object has been frozen and should not be mutated", - 3: function(e) { - return "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + e - }, - 4: "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.", - 5: "Immer forbids circular references", - 6: "The first or second argument to `produce` must be a function", - 7: "The third argument to `produce` must be a function or undefined", - 8: "First argument to `createDraft` must be a plain object, an array, or an immerable object", - 9: "First argument to `finishDraft` must be a draft returned by `createDraft`", - 10: "The given draft is already finalized", - 11: "Object.defineProperty() cannot be used on an Immer draft", - 12: "Object.setPrototypeOf() cannot be used on an Immer draft", - 13: "Immer only supports deleting array indices", - 14: "Immer only supports setting array indices and the 'length' property", - 15: function(e) { - return "Cannot apply patch, path doesn't resolve: " + e - }, - 16: 'Sets cannot have "replace" patches.', - 17: function(e) { - return "Unsupported patch operation: " + e - }, - 18: function(e) { - return "The plugin for '" + e + "' has not been loaded into Immer. To enable the plugin, import and call `enable" + e + "()` when initializing your application." - }, - 20: "Cannot use proxies if Proxy, Proxy.revocable or Reflect are not available", - 21: function(e) { - return "produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '" + e + "'" - }, - 22: function(e) { - return "'current' expects a draft, got: " + e - }, - 23: function(e) { - return "'original' expects a draft, got: " + e - } + + logger._logEvent.level.label = methodLevel; + logger._logEvent.level.value = methodValue; + + send(methodLevel, logger._logEvent, val); + + logger._logEvent = createLogEventShape(bindings); + } + + function createLogEventShape (bindings) { + return { + ts: 0, + messages: [], + bindings: bindings || [], + level: { label: '', value: 0 } + } + } + + function asErrValue (err) { + const obj = { + type: err.constructor.name, + msg: err.message, + stack: err.stack }; - function Au(e) { - for (var t = arguments.length, i = new Array(1 < t ? t - 1 : 0), r = 1; r < t; r++) - i[r - 1] = arguments[r]; - var n = wu[e] - , e = n ? "function" == typeof n ? n.apply(null, i) : n : "unknown error nr: " + e; - throw new Error("[Immer] " + e) + for (const key in err) { + if (obj[key] === undefined) { + obj[key] = err[key]; + } } - function Ou(e) { - return !!e && !!e[Eu] + return obj + } + + function getTimeFunction (opts) { + if (typeof opts.timestamp === 'function') { + return opts.timestamp } - function ku(t) { - return !!t && (function() { - if (!t || "object" != typeof t) - return !1; - var e = Object.getPrototypeOf(t); - return !e || e === Object.prototype - }() || Array.isArray(t) || !!t[Tu] || !!t.constructor[Tu] || Nu(t) || Fu(t)) + if (opts.timestamp === false) { + return nullTime } - var Cu = "undefined" != typeof Reflect && Reflect.ownKeys ? Reflect.ownKeys : void 0 !== Object.getOwnPropertySymbols ? function(e) { - return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e)) - } - : Object.getOwnPropertyNames - , Du = Object.getOwnPropertyDescriptors || function(t) { - var i = {}; - return Cu(t).forEach(function(e) { - i[e] = Object.getOwnPropertyDescriptor(t, e) - }), - i - } - ; - function Mu(i, r, t) { - void 0 === t && (t = !1), - 0 === Pu(i) ? (t ? Object.keys : Cu)(i).forEach(function(e) { - t && "symbol" == typeof e || r(e, i[e], i) - }) : i.forEach(function(e, t) { - return r(t, e, i) - }) - } - function Pu(e) { - var t = e[Eu]; - return t ? 3 < t.type_ ? t.type_ - 4 : t.type_ : Array.isArray(e) ? 1 : Nu(e) ? 2 : Fu(e) ? 3 : 0 - } - function xu(e, t) { - return 2 === Pu(e) ? e.has(t) : Object.prototype.hasOwnProperty.call(e, t) - } - function Ru(e, t) { - return 2 === Pu(e) ? e.get(t) : e[t] - } - function Lu(e, t, i) { - var r = Pu(e); - 2 === r ? e.set(t, i) : 3 === r ? (e.delete(t), - e.add(i)) : e[t] = i - } - function _u(e, t) { - return e === t ? 0 !== e || 1 / e == 1 / t : e != e && t != t - } - function Nu(e) { - return yu && e instanceof Map - } - function Fu(e) { - return vu && e instanceof Set - } - function Bu(e) { - return e.copy_ || e.base_ - } - function Uu(e) { - if (Array.isArray(e)) - return Array.prototype.slice.call(e); - var t = Du(e); - delete t[Eu]; - for (var i = Cu(t), r = 0; r < i.length; r++) { - var n = i[r] - , s = t[n]; - !1 === s.writable && (s.writable = !0, - s.configurable = !0), - (s.get || s.set) && (t[n] = { - configurable: !0, - writable: !0, - enumerable: s.enumerable, - value: e[n] - }) - } - return Object.create(Object.getPrototypeOf(e), t) - } - function $u(e, t) { - Ku(e) || Ou(e) || !ku(e) || (1 < Pu(e) && (e.set = e.add = e.clear = e.delete = Vu), - Object.freeze(e), - t && Mu(e, function(e, t) { - return $u(t, !0) - }, !0)) - } - function Vu() { - Au(2) - } - function Ku(e) { - return null == e || "object" != typeof e || Object.isFrozen(e) - } - var Hu, ju = {}; - function qu(e) { - var t = ju[e]; - return t || Au(18, e), - t - } - function Qu(e, t) { - ju[e] || (ju[e] = t) - } - function Gu() { - return Hu || Au(0), - Hu - } - function Wu(e, t) { - t && (qu("Patches"), - e.patches_ = [], - e.inversePatches_ = [], - e.patchListener_ = t) - } - function zu(e) { - Xu(e), - e.drafts_.forEach(Ju), - e.drafts_ = null - } - function Xu(e) { - e === Hu && (Hu = e.parent_) - } - function Yu(e) { - return Hu = { - drafts_: [], - parent_: Hu, - immer_: e, - canAutoFreeze_: !0, - unfinalizedDrafts_: 0 - } - } - function Ju(e) { - e = e[Eu]; - 0 === e.type_ || 1 === e.type_ ? e.revoke_() : e.revoked_ = !0 - } - function Zu(e, t) { - t.unfinalizedDrafts_ = t.drafts_.length; - var i = t.drafts_[0] - , r = void 0 !== e && e !== i; - return t.immer_.useProxies_ || qu("ES5").willFinalizeES5_(t, e, r), - r ? (i[Eu].modified_ && (zu(t), - Au(4)), - ku(e) && (e = ec(t, e), - t.parent_ || ic(t, e)), - t.patches_ && qu("Patches").generateReplacementPatches_(i[Eu], e, t.patches_, t.inversePatches_)) : e = ec(t, i, []), - zu(t), - t.patches_ && t.patchListener_(t.patches_, t.inversePatches_), - e !== bu ? e : void 0 - } - function ec(i, r, n) { - if (Ku(r)) - return r; - var s, a = r[Eu]; - return a ? a.scope_ !== i ? r : a.modified_ ? (a.finalized_ || (a.finalized_ = !0, - a.scope_.unfinalizedDrafts_--, - s = 4 === a.type_ || 5 === a.type_ ? a.copy_ = Uu(a.draft_) : a.copy_, - Mu(3 === a.type_ ? new Set(s) : s, function(e, t) { - return tc(i, a, s, e, t, n) - }), - ic(i, s, !1), - n && i.patches_ && qu("Patches").generatePatches_(a, n, i.patches_, i.inversePatches_)), - a.copy_) : (ic(i, a.base_, !0), - a.base_) : (Mu(r, function(e, t) { - return tc(i, a, r, e, t, n) - }, !0), - r) - } - function tc(e, t, i, r, n, s) { - if (n === i && Au(5), - Ou(n)) { - s = ec(e, n, s && t && 3 !== t.type_ && !xu(t.assigned_, r) ? s.concat(r) : void 0); - if (Lu(i, r, s), - !Ou(s)) - return; - e.canAutoFreeze_ = !1 - } - ku(n) && !Ku(n) && (!e.immer_.autoFreeze_ && e.unfinalizedDrafts_ < 1 || (ec(e, n), - t && t.scope_.parent_ || ic(e, n))) - } - function ic(e, t, i) { - void 0 === i && (i = !1), - e.immer_.autoFreeze_ && e.canAutoFreeze_ && $u(t, i) - } - var rc = { - get: function(e, t) { - if (t === Eu) - return e; - var i, r, n = Bu(e); - if (!xu(n, t)) - return i = e, - (r = ac(n, t)) ? "value"in r ? r.value : null === (r = r.get) || void 0 === r ? void 0 : r.call(i.draft_) : void 0; - n = n[t]; - return !e.finalized_ && ku(n) && n === sc(e.base_, t) ? (dc(e), - e.copy_[t] = uc(e.scope_.immer_, n, e)) : n + return epochTime + } + + function mock () { return {} } + function passthrough (a) { return a } + function noop$2 () {} + + function nullTime () { return false } + function epochTime () { return Date.now() } + function unixTime () { return Math.round(Date.now() / 1000.0) } + function isoTime () { return new Date(Date.now()).toISOString() } // using Date.now() for testability + + /* eslint-disable */ + /* istanbul ignore next */ + function pfGlobalThisOrFallback () { + function defd (o) { return typeof o !== 'undefined' && o } + try { + if (typeof globalThis !== 'undefined') return globalThis + Object.defineProperty(Object.prototype, 'globalThis', { + get: function () { + delete Object.prototype.globalThis; + return (this.globalThis = this) }, - has: function(e, t) { - return t in Bu(e) - }, - ownKeys: function(e) { - return Reflect.ownKeys(Bu(e)) - }, - set: function(e, t, i) { - var r = ac(Bu(e), t); - if (null != r && r.set) - return r.set.call(e.draft_, i), - !0; - if (!e.modified_) { - var n = sc(Bu(e), t) - , r = null == n ? void 0 : n[Eu]; - if (r && r.base_ === i) - return e.copy_[t] = i, - !(e.assigned_[t] = !1); - if (_u(i, n) && (void 0 !== i || xu(e.base_, t))) - return !0; - dc(e), - oc(e) - } - return e.copy_[t] = i, - e.assigned_[t] = !0 - }, - deleteProperty: function(e, t) { - return void 0 !== sc(e.base_, t) || t in e.base_ ? (e.assigned_[t] = !1, - dc(e), - oc(e)) : delete e.assigned_[t], - e.copy_ && delete e.copy_[t], - !0 - }, - getOwnPropertyDescriptor: function(e, t) { - var i = Bu(e) - , r = Reflect.getOwnPropertyDescriptor(i, t); - return r && { - writable: !0, - configurable: 1 !== e.type_ || "length" !== t, - enumerable: r.enumerable, - value: i[t] - } - }, - defineProperty: function() { - Au(11) - }, - getPrototypeOf: function(e) { - return Object.getPrototypeOf(e.base_) - }, - setPrototypeOf: function() { - Au(12) - } - } - , nc = {}; - function sc(e, t) { - var i = e[Eu]; - return (i ? Bu(i) : e)[t] - } - function ac(e, t) { - if (t in e) - for (var i = Object.getPrototypeOf(e); i; ) { - var r = Object.getOwnPropertyDescriptor(i, t); - if (r) - return r; - i = Object.getPrototypeOf(i) - } - } - function oc(e) { - e.modified_ || (e.modified_ = !0, - e.parent_ && oc(e.parent_)) - } - function dc(e) { - e.copy_ || (e.copy_ = Uu(e.base_)) - } - Mu(rc, function(e, t) { - nc[e] = function() { - return arguments[0] = arguments[0][0], - t.apply(this, arguments) - } - }), - nc.deleteProperty = function(e, t) { - return isNaN(parseInt(t)) && Au(13), - rc.deleteProperty.call(this, e[0], t) - } - , - nc.set = function(e, t, i) { - return "length" !== t && isNaN(parseInt(t)) && Au(14), - rc.set.call(this, e[0], t, i, e[0]) - } - ; - (w = lc.prototype).produce = function(e, s, t) { - if ("function" == typeof e && "function" != typeof s) { - var a = s; - s = e; - var o = this; - return function(e) { - var t = this; - void 0 === e && (e = a); - for (var i = arguments.length, r = new Array(1 < i ? i - 1 : 0), n = 1; n < i; n++) - r[n - 1] = arguments[n]; - return o.produce(e, function(e) { - return s.call.apply(s, [t, e].concat(r)) - }) - } - } - var i; - if ("function" != typeof s && Au(6), - void 0 !== t && "function" != typeof t && Au(7), - ku(e)) { - var r = Yu(this) - , n = uc(this, e, void 0) - , d = !0; - try { - i = s(n), - d = !1 - } finally { - (d ? zu : Xu)(r) - } - return "undefined" != typeof Promise && i instanceof Promise ? i.then(function(e) { - return Wu(r, t), - Zu(e, r) - }, function(e) { - throw zu(r), - e - }) : (Wu(r, t), - Zu(i, r)) - } - if (!e || "object" != typeof e) - return (i = s(e)) === bu ? void 0 : (void 0 === i && (i = e), - this.autoFreeze_ && $u(i, !0), - i); - Au(21, e) - } - , - w.produceWithPatches = function(n, e, t) { - var i, r, s = this; - return "function" == typeof n ? function(e) { - for (var t = arguments.length, i = new Array(1 < t ? t - 1 : 0), r = 1; r < t; r++) - i[r - 1] = arguments[r]; - return s.produceWithPatches(e, function(e) { - return n.apply(void 0, [e].concat(i)) - }) - } - : [this.produce(n, e, function(e, t) { - i = e, - r = t - }), i, r] - } - , - w.createDraft = function(e) { - ku(e) || Au(8), - Ou(e) && (e = cc(e)); - var t = Yu(this) - , e = uc(this, e, void 0); - return e[Eu].isManual_ = !0, - Xu(t), - e - } - , - w.finishDraft = function(e, t) { - e = e && e[Eu]; - e && e.isManual_ || Au(9), - e.finalized_ && Au(10); - e = e.scope_; - return Wu(e, t), - Zu(void 0, e) - } - , - w.setAutoFreeze = function(e) { - this.autoFreeze_ = e - } - , - w.setUseProxies = function(e) { - e && !Su && Au(20), - this.useProxies_ = e - } - , - w.applyPatches = function(e, t) { - for (var i = t.length - 1; 0 <= i; i--) { - var r = t[i]; - if (0 === r.path.length && "replace" === r.op) { - e = r.value; - break - } - } - var n = qu("Patches").applyPatches_; - return Ou(e) ? n(e, t) : this.produce(e, function(e) { - return n(e, t.slice(i + 1)) - }) - } - , - Br = lc; - function lc(e) { - this.useProxies_ = Su, - this.autoFreeze_ = !0, - "boolean" == typeof (null == e ? void 0 : e.useProxies) && this.setUseProxies(e.useProxies), - "boolean" == typeof (null == e ? void 0 : e.autoFreeze) && this.setAutoFreeze(e.autoFreeze), - this.produce = this.produce.bind(this), - this.produceWithPatches = this.produceWithPatches.bind(this) - } - function uc(e, t, i) { - t = Nu(t) ? qu("MapSet").proxyMap_(t, i) : Fu(t) ? qu("MapSet").proxySet_(t, i) : e.useProxies_ ? function(e, t) { - var i = Array.isArray(e) - , r = { - type_: i ? 1 : 0, - scope_: t ? t.scope_ : Gu(), - modified_: !1, - finalized_: !1, - assigned_: {}, - parent_: t, - base_: e, - draft_: null, - copy_: null, - revoke_: null, - isManual_: !1 - } - , t = r - , e = rc; - i && (t = [r], - e = nc); - t = Proxy.revocable(t, e), - e = t.revoke, - t = t.proxy; - return r.draft_ = t, - r.revoke_ = e, - t - }(t, i) : qu("ES5").createES5Proxy_(t, i); - return (i ? i.scope_ : Gu()).drafts_.push(t), - t - } - function cc(e) { - return Ou(e) || Au(22, e), - function i(e) { - if (!ku(e)) - return e; - var r, n = e[Eu], t = Pu(e); - if (n) { - if (!n.modified_ && (n.type_ < 4 || !qu("ES5").hasChanges_(n))) - return n.base_; - n.finalized_ = !0, - r = hc(e, t), - n.finalized_ = !1 - } else - r = hc(e, t); - return Mu(r, function(e, t) { - n && Ru(n.base_, e) === t || Lu(r, e, i(t)) - }), - 3 === t ? new Set(r) : r - }(e) - } - function hc(e, t) { - switch (t) { - case 2: - return new Map(e); - case 3: - return Array.from(e) - } - return Uu(e) - } - function pc() { - var r = {}; - function d(i, e) { - var t = r[i]; - return t ? t.enumerable = e : r[i] = t = { - configurable: !0, - enumerable: e, - get: function() { - var e = this[Eu]; - return a(e), - rc.get(e, i) - }, - set: function(e) { - var t = this[Eu]; - a(t), - rc.set(t, i, e) - } - }, - t - } - function n(e) { - for (var t = e.length - 1; 0 <= t; t--) { - var i = e[t][Eu]; - if (!i.modified_) - switch (i.type_) { - case 5: - u(i) && oc(i); - break; - case 4: - s(i) && oc(i) - } - } - } - function s(e) { - for (var t = e.base_, i = e.draft_, r = Cu(i), n = r.length - 1; 0 <= n; n--) { - var s = r[n]; - if (s !== Eu) { - var a = t[s]; - if (void 0 === a && !xu(t, s)) - return !0; - var o = i[s] - , s = o && o[Eu]; - if (s ? s.base_ !== a : !_u(o, a)) - return !0 - } - } - e = !!t[Eu]; - return r.length !== Cu(t).length + (e ? 0 : 1) - } - function u(e) { - var t = e.draft_; - if (t.length !== e.base_.length) - return !0; - t = Object.getOwnPropertyDescriptor(t, t.length - 1); - return !(!t || t.get) - } - function a(e) { - e.revoked_ && Au(3, JSON.stringify(Bu(e))) - } - Qu("ES5", { - createES5Proxy_: function(e, t) { - var i = Array.isArray(e) - , r = function(e, t) { - if (e) { - for (var i = new Array(t.length), r = 0; r < t.length; r++) - Object.defineProperty(i, "" + r, d(r, !0)); - return i - } - var n = Du(t); - delete n[Eu]; - for (var s = Cu(n), a = 0; a < s.length; a++) { - var o = s[a]; - n[o] = d(o, e || !!n[o].enumerable) - } - return Object.create(Object.getPrototypeOf(t), n) - }(i, e) - , e = { - type_: i ? 5 : 4, - scope_: t ? t.scope_ : Gu(), - modified_: !1, - finalized_: !1, - assigned_: {}, - parent_: t, - base_: e, - draft_: r, - copy_: null, - revoked_: !1, - isManual_: !1 - }; - return Object.defineProperty(r, Eu, { - value: e, - writable: !0 - }), - r - }, - willFinalizeES5_: function(e, t, i) { - i ? Ou(t) && t[Eu].scope_ === e && n(e.drafts_) : (e.patches_ && function t(e) { - if (e && "object" == typeof e) { - var i = e[Eu]; - if (i) { - var r = i.base_ - , n = i.draft_ - , s = i.assigned_; - if (4 === (e = i.type_)) - Mu(n, function(e) { - e !== Eu && (void 0 !== r[e] || xu(r, e) ? s[e] || t(n[e]) : (s[e] = !0, - oc(i))) - }), - Mu(r, function(e) { - void 0 !== n[e] || xu(n, e) || (s[e] = !1, - oc(i)) - }); - else if (5 === e) { - if (u(i) && (oc(i), - s.length = !0), - n.length < r.length) - for (var a = n.length; a < r.length; a++) - s[a] = !1; - else - for (var o = r.length; o < n.length; o++) - s[o] = !0; - for (var d = Math.min(n.length, r.length), l = 0; l < d; l++) - void 0 === s[l] && t(n[l]) - } - } - } - }(e.drafts_[0]), - n(e.drafts_)) - }, - hasChanges_: function(e) { - return (4 === e.type_ ? s : u)(e) - } - }) - } - function fc() { - var m = "replace" - , g = "add" - , y = "remove"; - function l(e) { - if (!ku(e)) - return e; - if (Array.isArray(e)) - return e.map(l); - if (Nu(e)) - return new Map(Array.from(e.entries()).map(function(e) { - return [e[0], l(e[1])] - })); - if (Fu(e)) - return new Set(Array.from(e).map(l)); - var t, i = Object.create(Object.getPrototypeOf(e)); - for (t in e) - i[t] = l(e[t]); - return i - } - function v(e) { - return Ou(e) ? l(e) : e - } - Qu("Patches", { - applyPatches_: function(d, e) { - return e.forEach(function(e) { - for (var t = e.path, i = e.op, r = d, n = 0; n < t.length - 1; n++) - "object" != typeof (r = Ru(r, t[n])) && Au(15, t.join("/")); - var s = Pu(r) - , a = l(e.value) - , o = t[t.length - 1]; - switch (i) { - case m: - switch (s) { - case 2: - return r.set(o, a); - case 3: - Au(16); - default: - return r[o] = a - } - case g: - switch (s) { - case 1: - return r.splice(o, 0, a); - case 2: - return r.set(o, a); - case 3: - return r.add(a); - default: - return r[o] = a - } - case y: - switch (s) { - case 1: - return r.splice(o, 1); - case 2: - return r.delete(o); - case 3: - return r.delete(e.value); - default: - return delete r[o] - } - default: - Au(17, i) - } - }), - d - }, - generatePatches_: function(c, e, t, i) { - switch (c.type_) { - case 0: - case 4: - case 2: - return l = e, - u = t, - h = i, - p = c.base_, - f = c.copy_, - void Mu(c.assigned_, function(e, t) { - var i = Ru(p, e) - , r = Ru(f, e) - , t = t ? xu(p, e) ? m : g : y; - i === r && t == m || (e = l.concat(e), - u.push(t == y ? { - op: t, - path: e - } : { - op: t, - path: e, - value: r - }), - h.push(t == g ? { - op: y, - path: e - } : t == y ? { - op: g, - path: e, - value: v(i) - } : { - op: m, - path: e, - value: v(i) - })) - }); - case 5: - case 1: - return function(e, t, i) { - var r, n = c.base_, s = c.assigned_, a = c.copy_; - a.length < n.length && (n = (r = [a, n])[0], - a = r[1], - t = (r = [i, t])[0], - i = r[1]); - for (var o, d = 0; d < n.length; d++) - s[d] && a[d] !== n[d] && (o = e.concat([d]), - t.push({ - op: m, - path: o, - value: v(a[d]) - }), - i.push({ - op: m, - path: o, - value: v(n[d]) - })); - for (var l = n.length; l < a.length; l++) { - var u = e.concat([l]); - t.push({ - op: g, - path: u, - value: v(a[l]) - }) - } - n.length < a.length && i.push({ - op: m, - path: e.concat(["length"]), - value: n.length - }) - }(e, t, i); - case 3: - return r = e, - n = t, - s = i, - a = c.base_, - o = c.copy_, - d = 0, - a.forEach(function(e) { - var t; - o.has(e) || (t = r.concat([d]), - n.push({ - op: y, - path: t, - value: e - }), - s.unshift({ - op: g, - path: t, - value: e - })), - d++ - }), - d = 0, - void o.forEach(function(e) { - var t; - a.has(e) || (t = r.concat([d]), - n.push({ - op: g, - path: t, - value: e - }), - s.unshift({ - op: y, - path: t, - value: e - })), - d++ - }) - } - var r, n, s, a, o, d, l, u, h, p, f - }, - generateReplacementPatches_: function(e, t, i, r) { - i.push({ - op: m, - path: [], - value: t - }), - r.push({ - op: m, - path: [], - value: e.base_ - }) - } - }) - } - function mc() { - var r = function(e, t) { - return (r = Object.setPrototypeOf || { - __proto__: [] - }instanceof Array && function(e, t) { - e.__proto__ = t - } - || function(e, t) { - for (var i in t) - t.hasOwnProperty(i) && (e[i] = t[i]) - } - )(e, t) - }; - function i(e, t) { - function i() { - this.constructor = e - } - r(e, t), - e.prototype = (i.prototype = t.prototype, - new i) - } - var n = function() { - function e(e, t) { - return this[Eu] = { - type_: 2, - parent_: t, - scope_: t ? t.scope_ : Gu(), - modified_: !1, - finalized_: !1, - copy_: void 0, - assigned_: void 0, - base_: e, - draft_: this, - isManual_: !1, - revoked_: !1 - }, - this - } - i(e, Map); - var t = e.prototype; - return Object.defineProperty(t, "size", { - get: function() { - return Bu(this[Eu]).size - } - }), - t.has = function(e) { - return Bu(this[Eu]).has(e) - } - , - t.set = function(e, t) { - var i = this[Eu]; - return d(i), - Bu(i).has(e) && Bu(i).get(e) === t || (s(i), - oc(i), - i.assigned_.set(e, !0), - i.copy_.set(e, t), - i.assigned_.set(e, !0)), - this - } - , - t.delete = function(e) { - if (!this.has(e)) - return !1; - var t = this[Eu]; - return d(t), - s(t), - oc(t), - t.assigned_.set(e, !1), - t.copy_.delete(e), - !0 - } - , - t.clear = function() { - var t = this[Eu]; - d(t), - Bu(t).size && (s(t), - oc(t), - t.assigned_ = new Map, - Mu(t.base_, function(e) { - t.assigned_.set(e, !1) - }), - t.copy_.clear()) - } - , - t.forEach = function(r, n) { - var s = this; - Bu(this[Eu]).forEach(function(e, t, i) { - r.call(n, s.get(t), t, s) - }) - } - , - t.get = function(e) { - var t = this[Eu]; - d(t); - var i = Bu(t).get(e); - if (t.finalized_ || !ku(i)) - return i; - if (i !== t.base_.get(e)) - return i; - i = uc(t.scope_.immer_, i, t); - return s(t), - t.copy_.set(e, i), - i - } - , - t.keys = function() { - return Bu(this[Eu]).keys() - } - , - t.values = function() { - var e, t = this, i = this.keys(); - return (e = {})[Iu] = function() { - return t.values() - } - , - e.next = function() { - var e = i.next(); - return e.done ? e : { - done: !1, - value: t.get(e.value) - } - } - , - e - } - , - t.entries = function() { - var e, i = this, r = this.keys(); - return (e = {})[Iu] = function() { - return i.entries() - } - , - e.next = function() { - var e = r.next(); - if (e.done) - return e; - var t = i.get(e.value); - return { - done: !1, - value: [e.value, t] - } - } - , - e - } - , - t[Iu] = function() { - return this.entries() - } - , - e - }(); - function s(e) { - e.copy_ || (e.assigned_ = new Map, - e.copy_ = new Map(e.base_)) - } - var a = function() { - function e(e, t) { - return this[Eu] = { - type_: 3, - parent_: t, - scope_: t ? t.scope_ : Gu(), - modified_: !1, - finalized_: !1, - copy_: void 0, - base_: e, - draft_: this, - drafts_: new Map, - revoked_: !1, - isManual_: !1 - }, - this - } - i(e, Set); - var t = e.prototype; - return Object.defineProperty(t, "size", { - get: function() { - return Bu(this[Eu]).size - } - }), - t.has = function(e) { - var t = this[Eu]; - return d(t), - t.copy_ ? !!t.copy_.has(e) || !(!t.drafts_.has(e) || !t.copy_.has(t.drafts_.get(e))) : t.base_.has(e) - } - , - t.add = function(e) { - var t = this[Eu]; - return d(t), - this.has(e) || (o(t), - oc(t), - t.copy_.add(e)), - this - } - , - t.delete = function(e) { - if (!this.has(e)) - return !1; - var t = this[Eu]; - return d(t), - o(t), - oc(t), - t.copy_.delete(e) || !!t.drafts_.has(e) && t.copy_.delete(t.drafts_.get(e)) - } - , - t.clear = function() { - var e = this[Eu]; - d(e), - Bu(e).size && (o(e), - oc(e), - e.copy_.clear()) - } - , - t.values = function() { - var e = this[Eu]; - return d(e), - o(e), - e.copy_.values() - } - , - t.entries = function() { - var e = this[Eu]; - return d(e), - o(e), - e.copy_.entries() - } - , - t.keys = function() { - return this.values() - } - , - t[Iu] = function() { - return this.values() - } - , - t.forEach = function(e, t) { - for (var i = this.values(), r = i.next(); !r.done; ) - e.call(t, r.value, r.value, this), - r = i.next() - } - , - e - }(); - function o(i) { - i.copy_ || (i.copy_ = new Set, - i.base_.forEach(function(e) { - var t; - ku(e) ? (t = uc(i.scope_.immer_, e, i), - i.drafts_.set(e, t), - i.copy_.add(t)) : i.copy_.add(e) - })) - } - function d(e) { - e.revoked_ && Au(3, JSON.stringify(Bu(e))) - } - Qu("MapSet", { - proxyMap_: function(e, t) { - return new n(e,t) - }, - proxySet_: function(e, t) { - return new a(e,t) - } - }) - } - var yi = new Br - , A = yi.produce - , gc = yi.produceWithPatches.bind(yi) - , gr = yi.setAutoFreeze.bind(yi) - , yc = yi.setUseProxies.bind(yi) - , gu = yi.applyPatches.bind(yi) - , w = yi.createDraft.bind(yi) - , yi = yi.finishDraft.bind(yi); - mu.Immer = Br, - mu.applyPatches = gu, - mu.castDraft = function(e) { - return e - } - , - mu.castImmutable = function(e) { - return e - } - , - mu.createDraft = w, - mu.current = cc, - mu.default = A, - mu.enableAllPlugins = function() { - pc(), - mc(), - fc() - } - , - mu.enableES5 = pc; - w = mu.enableMapSet = mc; - mu.enablePatches = fc, - mu.finishDraft = yi, - mu.immerable = Tu, - mu.isDraft = Ou, - mu.isDraftable = ku, - mu.nothing = bu, - mu.original = function(e) { - return Ou(e) || Au(23, e), - e[Eu].base_ - } - ; - var vc = mu.produce = A; - mu.produceWithPatches = gc, - mu.setAutoFreeze = gr, - mu.setUseProxies = yc; - class Sc { - constructor(e) { - this.store = e - } - createUnresolvedUriLoading(e, t, i) { - Co("loader.create.unresolvedUriLoading"), - this.store.add({ - uri: e, - responseType: t, - userAgent: i - }) - } - removeUnresolvedUriLoading(e) { - Co("loader.remove.unresolvedUriLoading"), - this.store.remove(e) - } - } - const bc = new class extends pd { - constructor() { - super({}, { - name: "loader", - producerFn: vc, - idKey: "uri" - }) - } - } - ; - let Tc = null; - class Ec extends t { - trigger(e, t) { - try { - this.emit(e, e, t), - "hlsFragLoadProgress" !== e.toString() && ("hlsInternalError" !== e && "hlsError" !== e || !t.length || JSON.stringify(t[0], ["fatal", "details", "reason"]), - e.toString()) - } catch (t) { - qe().warn(`error in event listener for ${e}: ${t.message}`) - } - } - } - class Ic { - constructor(e, t) { - this.target = e, - this._this = t - } - eventWithOptions(e, t, i, r=this._this) { - let n = en(this.target, e, t); - return this.target instanceof Ec && (n = n.pipe(ur(([,e])=>e))), - i && (r && (i = i.bind(r)), - n = n.pipe(Ja(i))), - n - } - event(e, t, i=this._this) { - return this.eventWithOptions(e, void 0, t, i) - } - listen(e, t, i, r=this._this) { - return this.event(e, i, r).pipe($a(t)).subscribe() - } - } - function wc(e, t) { - return new Ic(e,t) - } - function Ac(e, t, i) { - var r; - return { - currentTarget: null !== (r = null == i ? void 0 : i.currentTarget) && void 0 !== r ? r : e, - target: null !== (i = null == i ? void 0 : i.target) && void 0 !== i ? i : e, - type: t - } - } - function Oc(y, v) { - return new Ut(e=>{ - const {maxTimeToFirstByteMs: t, maxLoadTimeMs: i} = v - , r = new XMLHttpRequest - , n = { - trequest: performance.now(), - tfirst: NaN, - tload: NaN, - loaded: 0, - total: NaN, - complete: !1 - } - , s = wc(r) - , a = s.event("progress").pipe(wa(), so(300, Zi, { - leading: !0, - trailing: !0 - }), ur(e=>(isNaN(n.tfirst) && (n.tfirst = performance.now()), - n.loaded = e.loaded, - e.lengthComputable && (n.total = e.total), - e.target)), an(e=>3 <= e.readyState)) - , o = s.event("readystatechange").pipe(wa(), Hi(Zi), ur(e=>e.target), an(e=>2 <= e.readyState), Ja(e=>{ - isNaN(n.tfirst) && 3 <= e.readyState && (n.tfirst = performance.now()) - } - )); - let d = Ti; - isFinite(t) && 0 < t && (d = nn(a, o).pipe(Cs(1), vo(0 < y.extendMaxTTFB ? y.extendMaxTTFB : t), Ra(()=>Ti))); - let l = Ti; - isFinite(i) && 0 < i && (l = o.pipe(an(e=>4 <= e.readyState), Cs(1), vo(i), Ra(()=>Ti))); - let u = Ti; - y.onProgress && (u = nn(Bi(r), a).pipe(ur(e=>{ - const {getData: t, cb: i} = y.onProgress; - return i(y.url, e.status, n, t ? e.response : void 0) - } - ), Qa(e=>!e, !0)).pipe(Ua(Ti))); - const c = nn(a.pipe(Ra(()=>Ti)), o, d, l, u).pipe(Ra(e=>{ - if (4 <= e.readyState) { - if (n.complete = !0, - 200 <= e.status && e.status < 300) { - if (n.tload = performance.now(), - n.contentType = e.getResponseHeader("Content-Type"), - v.reportCDNServer && (n.cdnServer = e.getResponseHeader("CDN-Server")), - n.contentLength = v.forceContentLenCheckIfNoHeader ? function(e) { - let t; - const i = e.getResponseHeader("Content-Encoding") - , r = e.getResponseHeader("Transfer-Encoding") - , n = !i || i && "identity" === i.toLowerCase() - , s = !r || r && "identity" === r.toLowerCase(); - return n && s && (t = function(e) { - e = /([0-9]+)\-([0-9]+)\/([0-9]+)/.exec(e); - return e ? parseInt(e[2]) - parseInt(e[1]) + 1 : void 0 - }(e.getResponseHeader("Content-Range")), - ne(t) || (t = parseInt(e.getResponseHeader("Content-Length")))), - t - }(e) : null, - i = e, - (r = y).collectServerInstanceInfo && (r.serverInstanceInfo = {}, - r.collectServerInstanceInfo.forEach(e=>{ - var t = i.getResponseHeader(e); - t && (r.serverInstanceInfo[e] = t) - } - )), - "arraybuffer" === y.responseType ? n.loaded = e.response.byteLength : n.loaded = e.responseText.length, - n.total = n.loaded, - y.checkContentLength && (0 === n.total || ne(n.contentLength) && n.total != n.contentLength)) - throw new tu("Network error",e.status); - return Bi([e, n]) - } - throw new tu("Network error",e.status) - } - var i, r; - return Ti - } - ), Cs(1), Un(e=>{ - if (e instanceof or) - throw new ou(e.message,0,n); - if (!(e instanceof tu)) - throw new tu(e.message,0); - throw e - } - )).subscribe(e) - , {url: h, method: p, byteRangeOffset: f, responseType: m, body: g} = y; - y.mimeType && r.overrideMimeType(y.mimeType); - try { - const v = y.xhrSetup; - if (v) - try { - v(r, h) - } catch (e) { - r.open(p, y.url, !0), - v(r, y.url) - } - r.readyState || r.open(p, y.url, !0) - } catch (e) { - throw new tu(e.message,r.status) - } - if (r.responseType = m, - f && ne(f.start) && ne(f.end) && 0 <= f.start && f.end > f.start) { - const {start: y, end: v} = f; - r.setRequestHeader("Range", `bytes=${y}-${v - 1}`) - } - if (y.headers) - for (const [v,e] of Object.entries(y.headers)) - r.setRequestHeader(v, e); - return "POST" === p && g ? r.send(g) : r.send(), - ()=>{ - r.abort(), - c.unsubscribe() - } - } - ) - } - const kc = { - name: "CustomUrlLoader" - }; - class Cc { - constructor(e) { - this.loaderService = e, - this.requestMap = {}, - this.logger = qe() - } - load(a, o) { - return new Ut(e=>{ - const t = a.url - , i = o["maxTimeToFirstByteMs"] - , r = { - trequest: performance.now(), - tfirst: NaN, - tload: NaN, - loaded: 0, - total: NaN, - complete: !1 - } - , n = (this.requestMap[t] = new Ji).pipe(vo(0 < a.extendMaxTTFB ? a.extendMaxTTFB : i), Ra(e=>(r.tfirst = performance.now(), - this.handleExternalResponse(e, a, o, r))), Un(e=>{ - if (e instanceof or) - throw new ou(e.message,0,r); - throw e - } - ), $s(()=>{ - this.requestMap[t] = void 0, - this.loaderService.removeUnresolvedUriLoading(t) - } - )); - a.onProgress && a.onProgress.cb(t, 0, r, void 0); - const s = n.subscribe(e); - return this.loaderService.createUnresolvedUriLoading(t, a.responseType, navigator.userAgent), - ()=>{ - s.unsubscribe(), - this.requestMap[t] = void 0 - } - } - ) - } - setCustomUrlResponse(e, t) { - const i = this.requestMap[e]; - i && (i.next(t), - i.complete(), - this.requestMap[e] = void 0) - } - handleExternalResponse(e, t, i, r) { - r.tload = performance.now(); - var n = e.response.status || 200; - return 200 <= n && n < 300 ? ("arraybuffer" === t.responseType && e.response.data instanceof ArrayBuffer ? r.loaded = e.response.data.byteLength : r.loaded = e.response.data.length, - r.total = r.loaded, - r.complete = !0, - Bi({ - status: n, - data: e, - stats: r - })) : 300 === n || 302 === n || 303 === n || 305 === n ? this.redirectRequest(e.response.uri, t, i, r) : (this.logger.warn(kc, `unable to load custom url > uri=${oe(e.response.uri)}, status=${n}`), - Ui(new tu("Unable to load custom url",n))) - } - redirectRequest(e, t, i, n) { - var {maxLoadTimeMs: r, maxTimeToFirstByteMs: s} = i - , r = r - (performance.now() - n.trequest) - , s = 0 < t.extendMaxTTFB ? t.extendMaxTTFB : s - (performance.now() - n.trequest) - , i = Object.assign(Object.assign({}, i), { - maxLoadTimeMs: r, - maxTimeToFirstByteMs: s - }) - , e = Object.assign(Object.assign({}, t), { - url: e - }); - return r <= 0 || s <= 0 ? Ui(new or) : Oc(e, i).pipe(ur(([e,t])=>{ - var {responseURL: i, status: r} = e - , i = i || "" - , i = { - uri: i, - response: { - status: r, - uri: i, - data: e.response - } - }; - return n.loaded = n.total = t.loaded, - n.tload = performance.now(), - n.complete = !0, - { - status: e.status, - data: i, - stats: n - } - } - )) - } - } - let Dc; - function Mc(e) { - return Dc || (e = e || (Tc = Tc || new Sc(bc), - Tc), - Dc = new Cc(e)), - Dc - } - function Pc(e, t) { - const i = Object.assign(Object.assign({}, e), { - method: "GET", - responseType: "arraybuffer" - }) - , r = Mc(); - return ml(i.url) ? r.load(i, t).pipe(ur(e=>[e.data.response.data, e.stats, i.serverInstanceInfo])) : Oc(i, t).pipe(ur(([e,t])=>[e.response, t, i.serverInstanceInfo])) - } - function xc(e, t) { - return !e.url || ml(e.url) ? t.customURL : t.default - } - function Rc(e, t) { - return e instanceof iu ? e.isTimeout ? t.timeoutRetry : t.errorRetry : null - } - function Lc(e) { - var t = e.type - , i = e.liveOrEvent; - let r = "VOD"; - "EVENT" === t && i ? r = "EVENT" : t && 0 !== t.length && "LIVE" !== t || !i || (r = "LIVE"), - e.type !== r && (e.type = r) - } - const _c = { - id: "playready", - systemStringPrefix: "com.microsoft.playready", - keyFormatString: "com.microsoft.playready", - securityLevels: { - SL2000: 0, - SL3000: 1 - } - } - , Nc = { - id: "widevine", - systemStringPrefix: "com.widevine.alpha", - keyFormatString: "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed", - securityLevels: { - WIDEVINE_SOFTWARE: 0, - WIDEVINE_HARDWARE: 1 - } - }; - function Fc(e) { - return e.replace(/\+/g, "-").replace(/\//g, "_").replace(/\=+$/, "") - } - class Bc { - static strToBase64Encode(e) { - return btoa(e) - } - static base64DecodeToStr(e) { - return atob(e) - } - static base64Encode(e) { - return btoa(String.fromCharCode(...e)) - } - static base64UrlEncode(e) { - return Fc(Bc.base64Encode(e)) - } - static base64Decode(e) { - return Uint8Array.from(atob(e), e=>e.charCodeAt(0)) - } - } - class Uc { - static strToBase64Encode(e) { - return d.Buffer.from(e).toString("base64") - } - static base64DecodeToStr(e) { - return d.Buffer.from(e, "base64").toString() - } - static base64Encode(e) { - return d.Buffer.from(e).toString("base64") - } - static base64UrlEncode(e) { - return Fc(Uc.base64Encode(e)) - } - static base64Decode(e) { - e = d.Buffer.from(e, "base64"); - return new Uint8Array(e.buffer,e.byteOffset,e.byteLength) - } - } - var $c, Vc = void 0 !== d.Buffer ? Uc : Bc; - const Kc = { - avc1: "video/mp4", - avc3: "video/mp4", - dvav: "video/mp4", - dva1: "video/mp4", - hev1: "video/mp4", - hvc1: "video/mp4", - dvh1: "video/mp4", - dvhe: "video/mp4" - } - , Hc = { - mp4a: "audio/mp4", - "ac-3": "audio/mp4", - "ec-3": "audio/mp4" - }; - function jc(e) { - const t = O.strToUtf8array(e).subarray(0, 16) - , i = new Uint8Array(16); - return i.set(t, 16 - t.length), - i - } - const qc = { - getCapabilities: function(e, t) { - const i = { - videoCapabilities: [], - audioCapabilities: [] - }; - return e && e.forEach(e=>{ - var t = e.split(".")[0].trim(); - t in Kc && i.videoCapabilities.push({ - contentType: Kc[t] + ";codecs=" + e, - robustness: "" - }) - } - ), - t && t.forEach(e=>{ - var t = e.split(".")[0].trim(); - t in Hc && i.audioCapabilities.push({ - contentType: Hc[t] + ";codecs=" + e, - robustness: "" - }) - } - ), - i - }, - changeEndianness: function(e) { - function t(e, t, i) { - var r = e[t]; - e[t] = e[i], - e[i] = r - } - t(e, 0, 3), - t(e, 1, 2), - t(e, 4, 5), - t(e, 6, 7) - }, - getKeyIdBytes: jc, - convertDataUriToArrayBytes: function(e) { - const t = e.split(":"); - let i = null; - if ("data" === t[0] && 2 === t.length) { - const e = t[1].split(";") - , r = e[e.length - 1].split(","); - if (2 === r.length) { - const t = "base64" === r[0] - , n = r[1]; - i = t ? (e.splice(-1, 1), - Vc.base64Decode(n)) : jc(n) - } - } - return i - }, - makeKeyIdsInitData: function(e) { - e = { - kids: e.map(Vc.base64UrlEncode) - }; - return O.strToUtf8array(JSON.stringify(e)) - }, - parsePSSHList: function(e) { - const i = new DataView(e); - let r = 0; - const n = {}; - for (; r < i.buffer.byteLength; ) { - const e = r - , t = i.getUint32(r); - r += 4; - var s = e + t; - if (1886614376 === i.getUint32(r)) { - switch (r += 4, - i.getUint8(r)) { - case 0: - case 1: - r += 1; - break; - default: - r = s - } - r += 3; - let t = ""; - for (let e = 0; e < 16; ++e, - ++r) - switch (t += i.getUint8(r).toString(16), - e) { - case 4: - case 6: - case 8: - case 10: - t += "-" - } - r += 4, - n[t] = i.buffer.slice(e, s) - } else - r = s - } - return n - } - }; - let Qc = {}; - class Gc { - constructor(e, t, i, r, n) { - if (this.method = e, - this.uri = t, - this.iv = i, - this.format = r, - this.formatversions = n, - this.isEncrypted = this.method && "NONE" !== this.method, - this.formatversions && 0 !== this.formatversions.length || (this.formatversions = [1]), - this.key = void 0, - this.keyId = void 0, - this.isEncrypted) { - const a = qc.convertDataUriToArrayBytes(this.uri); - if (a) - switch (r) { - case _c.keyFormatString: - { - this.pssh = a; - const e = new Uint16Array(a.buffer,a.byteOffset,a.byteLength / 2) - , t = String.fromCharCode.apply(null, Array.from(e)) - , i = t.substring(t.indexOf("<"), t.length) - , r = (new DOMParser).parseFromString(i, "text/xml").getElementsByTagName("KID")[0]; - if (r) { - var s = null; - if (s = r.childNodes[0] ? r.childNodes[0].nodeValue : r.getAttribute("VALUE")) { - const t = Vc.base64Decode(s).subarray(0, 16); - qc.changeEndianness(t), - this.keyId = t - } - } - break - } - case Nc.keyFormatString: - this.pssh = a, - 22 <= a.length && (this.keyId = a.subarray(a.length - 22, a.length - 6)); - break; - default: - { - let e = a.subarray(0, 16); - if (16 !== e.length) { - const t = new Uint8Array(16); - t.set(e, 16 - e.length), - e = t - } - this.keyId = e; - break - } - } - if (!this.keyId || 16 !== this.keyId.byteLength) { - let e = Qc[this.uri]; - if (!e) { - const t = Object.keys(Qc).length % Number.MAX_SAFE_INTEGER; - e = new Uint8Array(16), - new DataView(e.buffer,12,4).setUint32(0, t), - Qc[this.uri] = e - } - this.keyId = e - } - } - } - get keyTagInfo() { - var {method: e, isEncrypted: t, uri: i, iv: r, keyId: n, key: s, format: a, formatversions: o} = this; - return { - method: e, - isEncrypted: t, - uri: i, - iv: r, - keyId: n, - key: s, - format: a, - formatversions: o - } - } - static clearKeyUriToKeyIdMap() { - Qc = {} - } - } - (gc = $c = $c || {}).NONE = "NONE", - gc.GET_REQUEST_INFO = "GET_REQUEST_INFO", - gc.GET_CHALLENGE = "GET_CHALLENGE", - gc.GET_KEY_RESPONSE = "GET_KEY_RESPONSE", - gc.PROCESS_LICENSE = "PROCESS_LICENSE"; - class Wc { - constructor(e, t, i, r) { - this.session = e, - this.onkeystatuseschange = t, - this.onkeymessage = i, - this.logger = r, - this.isClosing$ = new gi(!1), - this.closed$ = new gi(!1); - const n = wc(this.session); - n.listen("keystatuseschange", this.isClosing$.pipe(an(e=>!0 === e)), this.onkeystatuseschange), - n.listen("message", this.closed$.pipe(an(e=>!0 === e)), this.onkeymessage) - } - get isClosing() { - return this.isClosing$.value - } - get isClosed() { - return this.closed$.value - } - destroy() { - this.isClosing$.next(!0); - const e = this.session; - return Lr(e.remove().catch(e=>{} - ).then(()=>e.close()).catch(e=>{} - )).pipe(Ja(()=>{ - this.isClosing$.next(!1), - this.closed$.next(!0) - } - ), $s(()=>{ - this.isClosing$.next(!1), - this.closed$.next(!0) - } - )) - } - } - class zc { - constructor(e, t=null) { - this.decryptdata = e, - this._requestState$ = new gi($c.NONE), - this.destroy$ = new zt, - this.currentObservable = null, - this.session = null, - this.oldSessions = [], - this.session = t - } - get requestState() { - return this._requestState$.value - } - get onKeyRequestState$() { - return this._requestState$ - } - destroy() { - this.destroy$.next() - } - abort() { - var e; - this.requestState !== $c.NONE && (e = new uu("Aborted",this.decryptdata.uri,0,$.KeySystemAbort,!0,Xl.Abort), - this.error(e)) - } - setKeyRequestState(e) { - if (this.currentObservable) { - const t = new uu(`Unexpected state transition ${this.requestState}->${e}`,this.decryptdata.uri,0,$.KeySystemUnexpectedStateTransition,!0,Xl.InvalidState); - this.error(t) - } - this._requestState$.next(e); - const t = new Ji; - return e === $c.NONE ? (t.complete(), - this.currentObservable = null) : this.currentObservable = t, - t - } - resolveState(e, t) { - if (this.currentObservable) - if (e === this.requestState) - if (t instanceof Error) - this.error(t); - else { - const e = this.currentObservable; - this.currentObservable = null, - e.next(t), - e.complete() - } - else { - const t = new uu(`Unexpected state ${this.requestState} != ${e}`,this.decryptdata.uri,0,$.KeySystemUnexpectedState,!0,Xl.InvalidState); - this.error(t) - } - } - error(e) { - if (this.currentObservable) { - const t = this.currentObservable; - this.currentObservable = null, - t.error(e) - } - this.setKeyRequestState($c.NONE) - } - } - function Xc(e) { - return `uri=${oe(e.uri)} keyId=${je(e.keyId)}` - } - class Yc { - constructor(e, t, i, r, n, s, a) { - this.mediaKeys = e, - this.systemString = t, - this.config = i, - this.eventEmitter = r, - this.useSingleKeySession = n, - this.sessionHandler = s, - this.logger = a, - this.destroy$ = new zt, - this.setCert = !1, - this.certificate$ = new gi(null), - this._keyStatusChange$ = new zt, - this.shouldDestroyMediaKeys = !1, - this.itemId = "", - this.sessions = [], - this.keyIdToKeyInfo = {}, - this.keyUriToKeyInfo = {}, - this.sessionIdToKeyUri = {}, - this.onkeystatuseschange = this.handleKeyStatusesChange.bind(this), - this.onkeymessage = this.handleKeyMessage.bind(this) - } - get keyStatusChange$() { - return this._keyStatusChange$ - } - destroy() { - this.isDestroying = !0, - this.destroy$.next(); - for (const e of Object.values(this.keyIdToKeyInfo)) - this._abortKeyRequest(e); - const e = this.sessions.map(e=>e.destroy()) - , t = tn(()=>0 === e.length, Ul, Jr(e)).pipe(Js(void 0), $s(()=>{ - this.mediaKeys = void 0, - this.keyIdToKeyInfo = {}, - this.keyUriToKeyInfo = {}, - this.sessionIdToKeyUri = {} - } - )); - return Gc.clearKeyUriToKeyIdMap(), - t - } - setServerCertificate(e=null) { - return this.needsCert ? (e && this.certificate$.next(e), - $l(this.certificate$, e=>null != e).pipe(vo(1e4)).pipe(Ra(e=>this.setCert ? Bi(!0) : !this.setCertSubject || this.setCertSubject.isStopped ? (this.setCertSubject = new Ji, - Lr(this.mediaKeys.setServerCertificate(e)).pipe(Ja(e=>{ - e = void 0 === e || e; - this.setCert = e, - this.setCertSubject.next(e), - this.setCertSubject.complete() - } - ), Un(e=>(this.setCert = !1, - this.setCertSubject.error(e), - Ul)), Ra(()=>this.setCertSubject))) : this.setCertSubject), Un(e=>{ - throw e - } - ))) : Bi(!0) - } - ensureKeyContext(e) { - var t = e.uri; - this.keyUriToKeyInfo[t] || (this.keyUriToKeyInfo[t] = new zc(e)); - const i = this.keyUriToKeyInfo[t]; - if (i.session) - return i; - if (this.useSingleKeySession && 0 < this.sessions.length) - return i.session = this.sessions[0].session, - i; - t = this.mediaKeys.createSession(); - return t && this.sessions.push(new Wc(t,this.onkeystatuseschange,this.onkeymessage,this.logger)), - i.session = t, - i - } - startKeyRequest(t) { - const i = t.uri - , r = this.ensureKeyContext(t); - if (!r.session) - return Ui(new cu("Could not create key session",t.uri,0,$.KeySystemFailedToCreateSession,this.systemString)); - var e = O.utf8arrayToStr(t.keyId); - return this.keyIdToKeyInfo[e] = r, - Jr([this.getKeyRequestInfo(r), this.setServerCertificate()]).pipe(ur(e=>e[0]), Ra(e=>{ - var t; - return null === (t = this.sessionHandler) || void 0 === t || t.licenseChallengeSubmitted({ - keyuri: i, - keyFormat: this.systemString - }), - this.generateLicenseChallenge(r, e).pipe(Un(e=>{ - var t; - throw null === (t = this.sessionHandler) || void 0 === t || t.licenseChallengeError({ - keyuri: i - }), - e - } - )) - } - ), Ra(e=>{ - var t; - return null === (t = this.sessionHandler) || void 0 === t || t.licenseChallengeCreated({ - keyuri: i, - cdmVersion: this.cdmVersion - }), - this.getKeyRequestResponse(r, e) - } - ), Ra(e=>{ - var t; - return null === (t = this.sessionHandler) || void 0 === t || t.licenseResponseSubmitted({ - keyuri: i - }), - this.handleParsedKeyResponse(r, e).pipe(Un(e=>{ - var t; - throw null === (t = this.sessionHandler) || void 0 === t || t.licenseResponseError({ - keyuri: i - }), - e - } - )) - } - ), ur(()=>{ - var e; - return null === (e = this.sessionHandler) || void 0 === e || e.licenseResponseProcessed({ - keyuri: i - }), - r.setKeyRequestState($c.NONE), - this.removeSessions(r.decryptdata, !1).subscribe(), - t - } - ), Un(e=>{ - throw this.handleKeyExchangeError(r, e), - e - } - ), $s(()=>{ - this._abortKeyRequest(r) - } - )) - } - _abortKeyRequest(e) { - var t, i; - e && (i = e.decryptdata.uri, - O.utf8arrayToStr(e.decryptdata.keyId), - e.requestState !== $c.NONE && (null === (t = this.sessionHandler) || void 0 === t || t.keyAborted({ - keyuri: i - })), - e.abort()) - } - handleKeyExchangeError(e, t) { - e.error(t), - O.utf8arrayToStr(e.decryptdata.keyId) - } - updateItemId(e) { - this.itemId = e - } - removeKey(e) { - return this.removeKeyInternal(e) - } - removeKeyInternal(e) { - const t = this.keyUriToKeyInfo[e.uri]; - if (t && t.session) { - var i = t.session; - t.abort(), - t.destroy(); - var r = O.utf8arrayToStr(e.keyId); - return this.keyIdToKeyInfo[r] = void 0, - this.keyUriToKeyInfo[e.uri] = void 0, - this.removeSession(i) - } - } - removeSessions(e, t) { - const i = this.keyUriToKeyInfo[e.uri]; - if (i) { - const r = i.oldSessions.map(e=>this.removeSession(e)); - return i.oldSessions = [], - tn(()=>0 === r.length, Ul, Jr(r)).pipe(Ra(()=>t ? this.removeKeyInternal(e) : Ul)) - } - return Ul - } - removeSession(t) { - const e = this.sessions.findIndex(e=>e.session === t) - , i = this.sessions[e]; - return -1 < e && this.sessions.splice(e, 1), - this.sessionIdToKeyUri[t.sessionId] = void 0, - i ? i.destroy() : Ul - } - getKeyRequestInfo(e) { - var t = e.decryptdata - , i = t.uri - , e = e.setKeyRequestState($c.GET_REQUEST_INFO); - return this.eventEmitter.trigger(P.KEY_REQUEST_STARTED, { - keyuri: i, - decryptdata: t, - timestamp: Date.now() - }), - e - } - setKeyRequestInfo(e, t) { - const i = this.keyUriToKeyInfo[e]; - i && i.resolveState($c.GET_REQUEST_INFO, t) - } - sanitizeRequest(e) { - return e - } - generateLicenseChallengeInternal(t, e, i) { - const r = t.decryptdata - , n = t.session - , s = r.uri - , a = r.keyId; - let o; - var d = t.setKeyRequestState($c.GET_CHALLENGE); - if (n.generateRequestPromise) - o = Lr(n.generateRequestPromise).pipe(Ra(()=>this.generateRequestInitialized(t, "usable" === i))); - else { - const i = this.generateInitData(a, r, e); - n.generateRequestPromise = n.generateRequest(i.initDataType, i.initData), - o = Lr(n.generateRequestPromise).pipe(Ja(()=>{ - this.sessionIdToKeyUri[n.sessionId] = s - } - ), Un(e=>{ - throw new cu(e.message,t.decryptdata.uri,0,$.KeySystemFailedToGenerateLicenseRequest,this.systemString) - } - )) - } - return Jr([d, o]).pipe(ur(e=>new Uint8Array(e[0]))) - } - generateLicenseChallenge(e, t) { - const i = e.decryptdata - , r = e.session - , n = i.uri - , s = i.keyId; - let a, o; - if (O.utf8arrayToStr(i.keyId), - e.licenseChallenge && e.resolveState($c.GET_CHALLENGE, e.licenseChallenge), - t = this.sanitizeRequest(t), - e.requestInfo = t, - this.sessionId = this.sessionId || t && t.sessionId || this.itemId, - this.systemString === _c.systemStringPrefix) { - const e = new Uint8Array(s); - qc.changeEndianness(e), - a = r.keyStatuses.get(e) - } else - a = r.keyStatuses.get(s); - switch (a) { - case "status-pending": - case "usable": - case "expired": - case void 0: - o = this.generateLicenseChallengeInternal(e, t, a); - break; - default: - o = Ui(new cu(`Bad internal state state=${a}`,n,0,$.KeySystemUnexpectedState,this.systemString)) - } - return o - } - setParsedResponse(e, t) { - this.keyUriToKeyInfo[e].resolveState($c.GET_KEY_RESPONSE, t) - } - handleKeyStatusesChange(e) { - e.target.keyStatuses.forEach((e,t,i)=>{ - t = new Uint8Array(t); - this.systemString === _c.systemStringPrefix && qc.changeEndianness(t); - t = O.utf8arrayToStr(t), - t = this.keyIdToKeyInfo[t]; - this.handleKeyStatusForKey(e, t) - } - ) - } - handleKeyStatusForKey(e, t) { - if (t) { - var i = t.decryptdata - , r = i.uri; - switch (e) { - case "internal-error": - this.logger.error(`${this.systemString} internal-error for key ${Xc(i)}`), - this._signalError(t, new uu("Got internal error from key system",r,0,$.KeySystemInternalError,!1,Xl.InternalError)); - break; - case "usable": - t.requestState === $c.PROCESS_LICENSE && t.resolveState($c.PROCESS_LICENSE, void 0); - break; - case "output-restricted": - this.logger.warn(`${this.systemString} output-restricted for key ${Xc(i)}`), - t.session && this.removeSession(t.session).pipe($a(this.destroy$)).subscribe(), - this._signalError(t, new uu("output-restricted",r,0,$.KeySystemOutputRestricted,!1,Xl.OutputRestricted)) - } - } - } - _scheduleRenewal(e, t) { - vn(t).pipe(Ja(()=>this._signalRenewal(e)), $a(hn(e.destroy$, this.destroy$, $l(e.onKeyRequestState$, e=>e === $c.GET_REQUEST_INFO)))).subscribe() - } - _signalRenewal(e) { - this._keyStatusChange$.next({ - decryptdata: e.decryptdata, - status: "needs-renewal" - }) - } - _signalError(e, t) { - this._keyStatusChange$.next({ - decryptdata: e.decryptdata, - status: "error", - error: t - }), - e.error(t) - } - } - const Jc = "org.w3.clearkey" - , Zc = { - id: "clearkey", - systemStringPrefix: Jc, - keyFormatString: Jc, - securityLevels: { - NONE: 0 - } - } - , eh = ["clearkey", "fairplaystreaming", "playready", "widevine"] - , th = { - initDataTypes: ["keyids", "cenc"] - }; - var ih, gr = class extends Yc { - constructor(e, t, i, r, n, s) { - super(e, t, i, r, !1, n, s) - } - static get requestAccessConfig() { - return th - } - get needsCert() { - return !1 - } - getKeyRequestResponse(e, t) { - return Pc({ - url: e.decryptdata.uri, - xhrSetup: this.config.xhrSetup - }, { - maxLoadTimeMs: 0, - maxTimeToFirstByteMs: 0, - autoRetry: !1, - timeoutRetry: null, - errorRetry: null - }).pipe(ur(([e])=>{ - e = new Uint8Array(e); - return { - response: this.parseResponse(t, e) - } - } - )) - } - parseResponse(e, t) { - t = { - kty: "oct", - kid: Vc.base64UrlEncode(e), - k: Vc.base64UrlEncode(t) - }; - return O.strToUtf8array(JSON.stringify({ - keys: [t] - })) - } - handleParsedKeyResponse(i, e) { - e = e.response; - return Jr([i.setKeyRequestState($c.PROCESS_LICENSE), Lr(i.session.update(e)).pipe(Ja(()=>{ - var e = i.decryptdata.keyId - , e = i.session.keyStatuses.get(e); - this.handleKeyStatusForKey(e, i) - } - ), Un(e=>{ - var t = { - code: e.code, - text: "Failed to update with key response" - }; - throw new cu(e.message,i.decryptdata.uri,e.code,t,this.systemString) - } - ))]).pipe(Js(void 0)) - } - generateInitData(e) { - return { - initData: qc.makeKeyIdsInitData([e]), - initDataType: "keyids" - } - } - generateRequestInitialized() { - return Ul - } - sanitizeRequest(e) { - return e - } - handleKeyMessage(e) { - if (!this.isDestroying && "license-request" === e.messageType) { - e = new Uint8Array(e.message), - e = JSON.parse(O.utf8arrayToStr(e).trim()); - if (1 === e.kids.length) { - const t = Vc.base64Decode(e.kids[0]) - , i = O.utf8arrayToStr(t) - , r = this.keyIdToKeyInfo[i]; - r && r.resolveState($c.GET_CHALLENGE, t) - } - } - } - } - ; - const rh = { - initDataTypes: ["cenc"] - } - , nh = new Uint8Array([148, 206, 134, 251, 7, 255, 79, 67, 173, 184, 147, 210, 250, 150, 140, 162]); - (mu = ih = ih || {})[mu.CENC = 1667591779] = "CENC", - mu[mu.CBCS = 1667392371] = "CBCS"; - class sh extends Yc { - constructor(e, t, i, r, n, s, a) { - super(e, t, i, r, n, s, a), - this._hasSetRenewal = !1 - } - static get systemId() { - return nh - } - static get requestAccessConfig() { - return rh - } - get needsCert() { - return !0 - } - sanitizeRequest(e) { - return { - assetId: e && e.assetId ? new Uint8Array(e.assetId) : void 0, - ssc: e && e.ssc ? new Uint8Array(e.ssc) : void 0, - sessionId: e && e.sessionId ? e.sessionId : void 0 - } - } - _scheduleRenewal(e, t) { - this.useSingleKeySession ? this._hasSetRenewal || (this._hasSetRenewal = !0, - vn(t).pipe(Ja(()=>{ - var e = Object.values(this.keyUriToKeyInfo)[0]; - this._signalRenewal(e) - } - ), $s(()=>{ - this._hasSetRenewal = !1 - } - ), $a(this.destroy$)).subscribe()) : super._scheduleRenewal(e, t) - } - handleParsedKeyResponse(t, e) { - var i = t.decryptdata.uri - , r = e.statusCode - , n = e.ckc && 0 !== e.ckc.byteLength ? e.ckc : e.license && 0 !== e.license.byteLength ? e.license : void 0; - if (0 === r && !n) - return Ui(new uu("License request resulted in HTTP Error",i,r,{ - code: r, - text: "HTTP Error" - },!0,Xl.HttpError)); - if (0 !== r) - return Ui(new uu("License server responded with error",i,r,{ - code: r, - text: "Server Error" - },!1,Xl.LicenseServerError)); - if (!n) - return Ui(new uu("License server responded with invalid license",i,r,{ - code: r, - text: "Invalid license" - },!1,Xl.LicenseServerError)); - const s = e.renewalDate - , a = new Date - , o = s > a ? s.getTime() - a.getTime() : 0; - 0 < o && this._scheduleRenewal(t, o); - const d = this.makeProcessLicenseRequestMessage(t, n, o) - , l = t.session - , u = Lr(l.update(d)).pipe(Ja(()=>{ - var e = t.decryptdata.keyId - , e = l.keyStatuses.get(e); - this.handleKeyStatusForKey(e, t) - } - ), Un(e=>{ - throw new cu(e.message,t.decryptdata.uri,0,$.KeySystemFailedToUpdateSession,this.systemString) - } - )); - return Jr([t.setKeyRequestState($c.PROCESS_LICENSE), u]).pipe(Js(void 0)) - } - makeKeyRequests(e) { - const t = []; - for (const i of e) { - const e = i.decryptdata - , r = i.requestInfo - , n = e.keyId; - t.push({ - keyId: n, - assetId: r ? r.assetId : void 0, - ssc: r ? r.ssc : void 0, - versionList: e.formatversions - }) - } - return t - } - getSchemeAndFlags(e) { - return { - scheme: "ISO-23001-7" === e.method ? ih.CENC : ih.CBCS, - flags: 0 - } - } - generateInitData(e, t, i) { - var {scheme: r, flags: n} = this.getSchemeAndFlags(t) - , i = this.makeKeyRequests([{ - decryptdata: t, - requestInfo: i - }]); - return { - initData: this.makeFpsKeySystemInitData(r, n, i), - initDataType: "cenc" - } - } - generateRequestInitialized(t, e) { - Ql.tag(`[Keys] challenge create start uri=${oe(t.decryptdata.uri)} versions=${JSON.stringify(t.decryptdata.formatversions)}`); - e = this.makeKeyRequestMessage(t, e); - return e ? Lr(t.session.update(e)).pipe(Ja(()=>{ - t.requestInfo = void 0 - } - ), Un(e=>{ - throw Ql.tag(`[Keys] ${this.systemString} FAIL: generateRequestInitialized keyuri=${oe(t.decryptdata.uri)} message=${e.message}`), - new cu(e.message,t.decryptdata.uri,0,$.KeySystemFailedToGenerateLicenseRenewal,this.systemString) - } - )) : Ui(new uu("Unable to generate request using existing keySession",t.decryptdata.uri,0,$.KeySystemFailedToGenerateLicenseRequest,!0,Xl.InvalidState)) - } - getKeyRequestResponse(e, t) { - var i = e.decryptdata.uri - , e = e.setKeyRequestState($c.GET_KEY_RESPONSE); - return this.eventEmitter.trigger(P.LICENSE_CHALLENGE_CREATED, { - keyuri: i, - licenseChallenge: t, - keysystem: this.systemString - }), - e - } - resolveSPCPromise(e, t) { - e.resolveState($c.GET_CHALLENGE, t) - } - } - const ah = {} - , oh = 1919710053; - function dh(e, t, i) { - if (!(i + 4 > e.byteLength)) { - t = t.getUint32(i); - if (!((i += 4) + t > e.byteLength)) { - e = e.slice(i, i + t); - return { - pos: i += t, - data: e - } - } - } - } - function lh(t) { - const i = {} - , r = new DataView(t.buffer); - let n = 4; - const s = r.getUint32(n); - n += 4; - for (let e = 0; e < s && n < t.byteLength && !(n + 16 > t.byteLength); ++e) { - const s = t.slice(n, n + 16); - if (n += 16, - n + 4 > t.byteLength) - break; - var a = dh(t, r, n); - if (!a) - break; - n = a.pos, - i[O.utf8arrayToStr(s)] = a.data - } - return i - } - function uh(e, t, i, r) { - var n = r ? r.byteLength : 0; - return t.setUint32(i, n), - n && e.set(r, i + 4), - i + (4 + n) - } - function ch(e) { - let t = 4; - for (const i of e) - t += 28 + (i.assetId ? i.assetId.byteLength : 0) + (i.ssc ? i.ssc.byteLength : 0) + (i.versionList ? 4 * i.versionList.length : 0); - return t - } - function hh(e, t, i, r) { - t.setUint32(i, r.length), - i += 4; - for (const n of r) - if (e.set(n.keyId, i), - i = uh(e, t, i += 16, n.assetId), - i = uh(e, t, i, n.ssc), - t.setUint32(i, n.versionList ? n.versionList.length : 0), - i += 4, - n.versionList) - for (const e of n.versionList) - t.setUint32(i, e), - i += 4; - return i - } - class ph extends sh { - constructor(e, t, i, r, n, s) { - super(e, t, i, r, void 0 === i.useMultipleKeySessions || !i.useMultipleKeySessions, n, s) - } - makeProcessLicenseRequestMessage(e, t, i) { - t = new Uint8Array(t); - return function(e) { - let t = 0; - for (const i of e) - t += 24 + i.ckc.byteLength; - let i = 0; - const r = new Uint8Array(8 + t) - , n = new DataView(r.buffer); - n.setUint32(0, 1667982195), - n.setUint32(4, e.length), - i += 8; - for (const t of e) - r.set(t.keyId, i), - i += 16, - n.setUint32(i, t.expirySec), - i += 4, - i = uh(r, n, i, t.ckc); - return r - }([{ - keyId: e.decryptdata.keyId, - expirySec: i / 1e3, - ckc: t - }]) - } - makeFpsKeySystemInitData(e, t, i) { - i = function(e, t, i) { - var r = ch(i); - const n = new Uint8Array(8 + r) - , s = new DataView(n.buffer); - return s.setUint32(0, e), - s.setUint32(4, 1 << 24 | 16777215 & t), - hh(n, s, 8, i), - n - }(e, t, i); - return me.pssh(ph.systemId, [], i) - } - makeKeyRequestMessage(e) { - return function(e) { - var t = ch(e); - const i = new Uint8Array(4 + t) - , r = new DataView(i.buffer); - return r.setUint32(0, 1668442994), - hh(i, r, 4, e), - i - }([{ - keyId: e.decryptdata.keyId, - assetId: e.requestInfo ? e.requestInfo.assetId : void 0, - ssc: e.requestInfo ? e.requestInfo.ssc : void 0, - versionList: e.decryptdata.formatversions - }]) - } - handleKeyMessage(e) { - if (e.message.byteLength < 4) - this.logger.warn("Unexpected message"); - else { - const t = new Uint8Array(e.message) - , i = new DataView(e.message) - , r = i.getUint32(0); - if (this.isDestroying && r !== oh) - this.logger.warn(`In the middle of destroying, ignore command: ${r.toString(16)}`); - else - switch (r) { - case 1667592820: - this.logger.warn("Certificate not set!"); - break; - case 1919837559: - { - const e = lh(t); - for (const t in e) - if (Object.prototype.hasOwnProperty.call(e, t)) { - const e = this.keyIdToKeyInfo[t]; - this._signalRenewal(e) - } - break - } - case 1936745331: - { - const e = lh(t); - for (const t in e) - if (Object.prototype.hasOwnProperty.call(e, t)) { - const i = this.keyIdToKeyInfo[t] - , r = e[t]; - this.resolveSPCPromise(i, r) - } - break - } - case oh: - this._handleLicenseRelease(t); - break; - case 1667525993: - { - const e = dh(t, i, 4); - e && (this.cdmVersion = O.utf8arrayToStr(e.data)); - break - } - default: - this.logger.warn(`Unrecognized command:'0x${r.toString(16)}'`) - } - } - } - _handleLicenseRelease(e) { - const t = {} - , i = new DataView(e.buffer); - switch (i.getUint32(4)) { - case 1936946288: - ah, - 0, - t[ah.SessionId] = this.sessionId; - var r; - if (e.byteLength < 12) - break; - t[ah.APIProvider] = i.getUint32(8) === ih.CENC ? "EC396D13-FB13-4993-9D0D-71518ACF3D6F" : "F19BF03B-7470-41A4-9655-86D078307D59", - 0; - var n = dh(e, i, 12); - if (!n) - break; - if (r = n.pos, - t[ah.MovieID] = O.utf8arrayToStr(n.data), - !(n = dh(e, i, r))) - break; - if (r = n.pos, - t[ah.SecureStopSPC] = n.data, - !(n = dh(e, i, r))) - break; - n.pos, - t[ah.SessionLifespanSPC] = n.data - } - this.eventEmitter.trigger(P.LICENSE_RELEASED, { - keysystem: this.systemString, - itemId: this.itemId, - releaseRecord: t - }) - } - } - yc = ph; - const fh = { - fpsd: O.strToUtf8array("fpsd"), - fpsi: O.strToUtf8array("fpsi"), - fpsk: O.strToUtf8array("fpsk"), - fkri: O.strToUtf8array("fkri"), - fkai: O.strToUtf8array("fkai"), - fkcx: O.strToUtf8array("fkcx"), - fkvl: O.strToUtf8array("fkvl") - }; - t = class extends sh { - constructor(e, t, i, r, n, s) { - super(e, t, i, r, !1, n, s), - this.sessions = [], - this.keyIdToKeyInfo = {}, - this.keyUriToKeyInfo = {}, - this.sessionIdToKeyUri = {} - } - static get needsCert() { - return !0 - } - handleKeyExchangeError(e, t) { - this.removeKey(e.decryptdata).subscribe(), - super.handleKeyExchangeError(e, t) - } - _abortKeyRequest(e) { - return !this.isDestroying && e && e.requestState !== $c.NONE && this.removeKey(e.decryptdata).subscribe(), - super._abortKeyRequest(e) - } - makeFpsKeySystemInitData(e, t, i) { - const r = [fh.fpsd, (n = e, - e = t, - t = new Uint8Array(4), - me.set32(n, t, 0), - me.box(fh.fpsi, new Uint8Array([0, e >> 16 & 255, e >> 8 & 255, 255 & e]), t))]; - var n; - for (const s of i) - r.push(function(t, e, i, r) { - const n = [fh.fpsk] - , s = me.box(fh.fkri, new Uint8Array([0, 0, 0, 0]), t); - if (n.push(s), - e && e.byteLength && n.push(me.box(fh.fkai, e)), - i && i.byteLength && n.push(me.box(fh.fkcx, i)), - r && r.length) { - const t = new Uint8Array(4 * r.length); - let e = 0; - for (const i of r) - me.set32(i, t, e), - e += 4; - n.push(me.box(fh.fkvl, t)) - } - return me.box.apply(null, n) - }(s.keyId, s.assetId, s.ssc, s.versionList)); - i = me.box.apply(null, r); - return me.pssh(sh.systemId, null, i) - } - makeKeyRequestMessage(e, t) { - if (t) - return O.strToUtf8array("renew") - } - makeProcessLicenseRequestMessage(e, t, i) { - t = JSON.stringify([{ - keyID: Vc.base64Encode(e.decryptdata.keyId), - payload: Vc.base64Encode(new Uint8Array(t)) - }]); - return O.strToUtf8array(t) - } - handleKeyMessage(e) { - const t = e.target - , i = t.sessionId - , r = e.messageType - , n = this.sessionIdToKeyUri[i]; - let s; - if (n) - s = this.keyUriToKeyInfo[n]; - else - for (const e of Object.values(this.keyUriToKeyInfo)) - e && e.session === t && (s = e); - if (s) - switch (r) { - case "license-request": - { - const t = new Uint8Array(e.message) - , i = O.utf8arrayToStr(t); - try { - JSON.parse(i).forEach(e=>{ - var t = Vc.base64DecodeToStr(e.keyID) - , e = Vc.base64Decode(e.payload) - , t = this.keyIdToKeyInfo[t]; - this.resolveSPCPromise(t, e) - } - ) - } catch (e) { - this.logger.warn("[Keys] got unexpected license-request format"), - this.resolveSPCPromise(s, t) - } - break - } - case "license-renewal": - { - const t = new Uint8Array(e.message); - this.resolveSPCPromise(s, t); - break - } - case "license-release": - this._handleLicenseRelease(t); - break; - default: - this.logger.warn(`[Keys] Unexpected messageType ${r}`) - } - else - this.logger.warn("[Keys] No key associated with session") - } - _handleLicenseRelease(e) { - e.update(O.strToUtf8array("acknowledged")).catch(e=>{ - this.logger.error(`Promise error: ${e.message}`) - } - ) - } - } - ; - const mh = { - initDataTypes: ["cenc"] - } - , gh = new Uint8Array([154, 4, 240, 121, 152, 64, 66, 134, 171, 146, 230, 91, 224, 136, 95, 149]); - class yh extends Yc { - constructor(e, t, i, r, n, s) { - super(e, t, i, r, !1, n, s), - this.shouldDestroyMediaKeys = !0 - } - static get systemId() { - return gh - } - static get requestAccessConfig() { - return mh - } - get needsCert() { - return !1 - } - generateInitData(e, t) { - t = t.pssh; - return { - initData: me.pssh(yh.systemId, [], t), - initDataType: "cenc" - } - } - removeKey(e) { - return super.removeSessions(e, !0) - } - ensureKeyContext(e) { - const t = e.uri - , i = this.keyUriToKeyInfo[t]; - return null != i && i.session && (i.oldSessions.push(i.session), - i.session = null), - super.ensureKeyContext(e) - } - getKeyRequestResponse(e, t) { - var i = e.decryptdata.uri - , r = e.setKeyRequestState($c.GET_KEY_RESPONSE); - return this.eventEmitter.trigger(P.LICENSE_CHALLENGE_CREATED, { - keyuri: i, - licenseChallenge: t, - keysystem: this.systemString, - keyId: e.decryptdata.keyId - }), - r - } - generateRequestInitialized(e) { - var t = e.licenseChallenge; - return e.requestInfo = void 0, - e.resolveState($c.GET_CHALLENGE, t), - Ul - } - handleParsedKeyResponse(t, e) { - const i = t.decryptdata.uri - , r = e.statusCode; - if (0 !== r) - return Ui(new uu("License server responded with error",i,r,{ - code: r, - text: "Server error" - },!1,Xl.LicenseServerError)); - if (!e.license || !e.license.byteLength) - return Ui(new uu("License server responded with invalid license",i,r,{ - code: r, - text: "Invalid license" - },!1,Xl.LicenseServerError)); - if (e.renewalDate) { - const i = e.renewalDate - , r = new Date - , n = i > r ? i.getTime() - r.getTime() : 0; - 0 < n && this._scheduleRenewal(t, n) - } - return Jr([t.setKeyRequestState($c.PROCESS_LICENSE), Lr(t.session.update(e.license)).pipe(Ja(()=>{ - t.resolveState($c.PROCESS_LICENSE, void 0) - } - ), Un(e=>{ - throw this.logger.error(`${this.systemString} FAIL: Failed to update with key response message=${e.message}`), - new cu(e.message,t.decryptdata.uri,0,$.KeySystemFailedToUpdateSession,this.systemString) - } - ))]).pipe(Js(void 0)) - } - handleKeyMessage(e) { - if (this.isDestroying) - this.logger.warn("In the middle of destroying, ignore key message"); - else { - const t = new DOMParser - , i = new ("utf16" === this.config.playReadyMessageFormat ? Uint16Array : Uint8Array)(e.message.buffer || e.message) - , r = String.fromCharCode.apply(null, Array.from(i)) - , n = t.parseFromString(r, "application/xml").getElementsByTagName("PlayReadyKeyMessage")[0]; - if (n && "LicenseAcquisition" === n.getAttribute("type")) { - const s = t.parseFromString(r, "application/xml").getElementsByTagName("Challenge")[0]; - if (s && "base64encoded" === s.getAttribute("encoding") && 0 !== s.childNodes.length) { - const a = Vc.base64Decode(s.childNodes[0].nodeValue) - , o = O.utf8arrayToStr(a) - , d = t.parseFromString(o, "application/xml").getElementsByTagName("KID")[0]; - e = null, - e = d.childNodes[0] ? d.childNodes[0].nodeValue : d.getAttribute("VALUE"), - e = Vc.base64Decode(e).subarray(0, 16); - qc.changeEndianness(e); - const l = this.keyIdToKeyInfo[O.utf8arrayToStr(e)]; - l.licenseChallenge = a, - l.resolveState($c.GET_CHALLENGE, a) - } else - this.logger.warn(`${this.systemString} wrong challenge format or empty challenge`) - } else - this.logger.warn(`${this.systemString} unrecognized message ignore it`) - } - } - } - gc = yh; - const vh = { - initDataTypes: ["cenc", "keyids"] - } - , Sh = new Uint8Array([237, 239, 139, 169, 121, 214, 74, 206, 163, 200, 39, 220, 213, 29, 33, 237]) - , bh = { - clearkey: Zc, - fairplaystreaming: pu, - playready: _c, - widevine: Nc - } - , Th = { - clearkey: [["org.w3.clearkey", gr]], - fairplaystreaming: [["com.apple.fps.3_0", t], ["com.apple.fps", yc]], - playready: [["com.microsoft.playready.recommendation", gc]], - widevine: [["com.widevine.alpha", class extends Yc { - constructor(e, t, i, r, n, s) { - super(e, t, i, r, !1, n, s), - this.shouldDestroyMediaKeys = !0 - } - static get systemId() { - return Sh - } - static get requestAccessConfig() { - return vh - } - get needsCert() { - return !0 - } - removeKey(e) { - return super.removeSessions(e, !0) - } - ensureKeyContext(e) { - const t = e.uri - , i = this.keyUriToKeyInfo[t]; - return null != i && i.session && (i.oldSessions.push(i.session), - i.session = null), - super.ensureKeyContext(e) - } - getKeyRequestResponse(e, t) { - var i = e.decryptdata.uri - , r = e.setKeyRequestState($c.GET_KEY_RESPONSE); - return this.eventEmitter.trigger(P.LICENSE_CHALLENGE_CREATED, { - keyuri: i, - licenseChallenge: t, - keysystem: this.systemString, - keyId: e.decryptdata.keyId - }), - r - } - handleParsedKeyResponse(t, e) { - t.licenseChallenge = void 0; - const i = t.decryptdata.uri - , r = e.statusCode; - if (0 !== r) - return Ui(new uu("License server responded with error",i,r,{ - code: r, - text: "Server error" - },!1,Xl.LicenseServerError)); - if (!e.license || !e.license.byteLength) - return Ui(new uu("License server responded with invalid license",i,r,{ - code: r, - text: "Invalid license" - },!1,Xl.LicenseServerError)); - if (e.renewalDate) { - const i = e.renewalDate - , r = new Date - , n = i > r ? i.getTime() - r.getTime() : 0; - 0 < n && this._scheduleRenewal(t, n) - } - return Jr([t.setKeyRequestState($c.PROCESS_LICENSE), Lr(t.session.update(e.license)).pipe(Ja(()=>{ - var e = t.decryptdata.keyId - , e = t.session.keyStatuses.get(e); - this.handleKeyStatusForKey(e, t) - } - ), Un(e=>{ - throw this.logger.error(`${this.systemString} FAIL: Failed to update with key response code=${e.code} message=${e.message}`), - new cu(e.message,t.decryptdata.uri,e.code,{ - code: e.code, - text: "Failed to update with key response" - },this.systemString) - } - ))]).pipe(Js(void 0)) - } - generateInitData(e, t) { - return { - initData: t.pssh, - initDataType: "cenc" - } - } - generateRequestInitialized(e) { - var t = e.licenseChallenge; - return e.requestInfo = void 0, - e.resolveState($c.GET_CHALLENGE, t), - Ul - } - handleKeyMessage(i) { - if (this.isDestroying) - this.logger.warn("In the middle of destroying, ignore key message"); - else { - const r = i.target; - let e = null - , t = null; - if (r.sessionId in this.sessionIdToKeyUri) - e = this.sessionIdToKeyUri[r.sessionId], - t = this.keyUriToKeyInfo[e]; - else - for (const [i,n] of Object.entries(this.keyUriToKeyInfo)) - if (n.session === r) { - e = i, - t = n; - break - } - if (t) - switch (i.messageType) { - case "license-request": - { - const r = new Uint8Array(i.message); - t.resolveState($c.GET_CHALLENGE, r); - break - } - } - else - this.logger.warn(`${this.systemString} empty keyuri and keyInfo`) - } - } - } - ]] - } - , Eh = Zc.id; - class Ih { - createMediaKeys(t, e, i, r, n) { - let s = Ih.idToMediaKeysInfoMap[t]; - if (!s) { - const a = qc.getCapabilities(e, i) - , o = new Ji; - Ih.requestKeySystemAccess(t, a, n, r).pipe(Ra(function(e) { - return Lr((Ih.idToMediaKeysInfoMap[t].keySystemAccess = e).createMediaKeys()) - }), Ja(e=>{ - o.next(e), - o.complete() - } - ), Un(e=>(o.error(new cu(`could not initialize key system: ${e.message}`,void 0,0,$.KeySystemFailedToInitialize,t)), - Ti)), $a(Ih.destroy$)).subscribe(), - s = Ih.idToMediaKeysInfoMap[t] = { - mediaKeys$: o, - keySystemAccess: null - } - } - return s.mediaKeys$ - } - destroyMediaKeys() { - Ih.destroy$.next(), - Ih.idToMediaKeysInfoMap = {} - } - static getKeySystemIdForDecryptData(e) { - let t; - if (e) { - t = Eh; - var i = e.format; - for (const e of eh) { - var r = bh[e]; - if ((null == r ? void 0 : r.keyFormatString) === i) { - t = e; - break - } - } - } - if (!t) - throw Error("No matching key system"); - return t - } - static requestKeySystemAccess(e, t, i, r) { - if ("undefined" == typeof navigator || void 0 === navigator.requestMediaKeySystemAccess) - return Ui(new cu("navigator undefined",void 0,0,$.KeySystemUndefinedNavigator,e)); - const n = Th[e]; - let s = Ui(new cu("no key systems to try",void 0,0,$.KeySystemNoKeySystemsToTry,e)); - for (const e of n) { - const n = e[0] - , o = e[1] - , d = (a = i) && "object" == typeof a ? i : o.requestAccessConfig - , l = [Object.assign({}, d, t)]; - s = s.pipe(Un(()=>Ih.requestKeySystemInternal(n, l, r))) - } - var a; - return s - } - static requestKeySystemInternal(e, t, i) { - return Yr(()=>Lr(navigator.requestMediaKeySystemAccess(e, t))) - } - make(e, t, i, r, n, s) { - var a = null === (d = Ih.idToMediaKeysInfoMap[e]) || void 0 === d ? void 0 : d.keySystemAccess; - if (!a) - throw new cu(`No keySystemAccess for ${e}`,void 0,0,$.KeySystemNoKeySystemAccess,e); - let o; - var d = bh[e].systemStringPrefix; - for (const t of Th[e]) - if (t[0] === a.keySystem) { - o = t[1]; - break - } - if (!o) - throw new cu(`No constructor associated with ${e}`,void 0,0,$.KeySystemNoConstructor,d); - return new o(t,d,i,r,n,s) - } - static get availableKeySystems() { - return Object.keys(bh) - } - static getKeySystemFormat(e) { - e = bh[e]; - return e ? e.keyFormatString : "" - } - static getKeySystemSecurityLevel(e) { - e = bh[e]; - return e ? e.securityLevels : void 0 - } - } - Ih.idToMediaKeysInfoMap = {}, - Ih.destroy$ = new zt; - const wh = ["avc1.42E01E"] - , Ah = ["mp4a.40.2"]; - function Oh(e, t, i) { - if (t) { - if (t instanceof or) - t = new lu("Key request timed out",e,$.KeySystemRequestTimedOut); - else if (t instanceof cu) { - const i = (null == t ? void 0 : t.response) || $.InternalError; - t = new uu(t.message,e,0,i,!1,Xl.InternalError,!0) - } - } else - t = new uu("Unknown error from CDM",e,0,$.KeySystemCDMUnknownError,!1,Xl.InternalError); - return (t instanceof uu || t instanceof lu) && (t.mediaOptionIds = [...i]), - t - } - class kh { - constructor(e, t, i, r, n, s, a, o=new Ih) { - this.ksService = e, - this.mediaSink = t, - this.config = i, - this.platformQuery = r, - this.eventEmitter = n, - this.sessionHandler = s, - this.keySystemFactory = o, - this.reset$ = new zt, - this.keyRequest$ = new zt, - this.abort$ = new zt, - this.keySystem$ = new gi(null), - this._keyStatusChange$ = new zt, - this.protectionData = {}, - this.keySystemId = null, - this.keyUriToRequest = {}, - this.ksQuery = e.getQuery(), - this.logger = a.child({ - name: "eme" - }), - this.config.warmupCdms && this.keySystemFactory.createMediaKeys(pu.id, wh, Ah, this.logger, void 0).subscribe(), - nn(r.platformInfo$.pipe(Es((e,t)=>e && t && e.requiresCDMAttachOnStart === t.requiresCDMAttachOnStart), Ra(e=>null != e && e.requiresCDMAttachOnStart ? this.attachMediaKeys().pipe(Un(e=>(this.handleKeySystemError(e), - Ti))) : Ul), Ua(Ti)), this.keyRequest$.pipe(Kr(e=>e.pipe(Un(()=>Ti)))), this.keySystem$.pipe(Ra(e=>e ? e.keyStatusChange$.pipe(Ja(e=>{ - var t = e.decryptdata.uri - , i = this.ksQuery.getKeyInfo(t); - "needs-renewal" === e.status ? this.ksService.updateKeyRequestState(t, zl.MustRequestResponse, e=>e === zl.GotKeyResponse) : (i = Oh(t, e.error, null !== (i = null == i ? void 0 : i.mediaOptionIds) && void 0 !== i ? i : []), - this.ksService.setError(t, i)), - this._keyStatusChange$.next(e) - } - )) : Ti)), this.isKeyCleanupSupported() ? this.mediaSink.mediaQuery.bufferedSegmentsTuple$.pipe(Kr(e=>{ - const [t,i] = e - , r = new Set; - return t.forEach(e=>{ - e = null === (e = null === (e = e.frag) || void 0 === e ? void 0 : e.keyTagInfo) || void 0 === e ? void 0 : e.uri; - e && r.add(e) - } - ), - i.forEach(e=>{ - e = null === (e = null === (e = e.frag) || void 0 === e ? void 0 : e.keyTagInfo) || void 0 === e ? void 0 : e.uri; - e && r.add(e) - } - ), - this.handleKeyCleanup(r) - } - )) : Ul).pipe($a(this.reset$)).subscribe() - } - get keyStatusChange$() { - return this._keyStatusChange$ - } - get keySystem() { - return this.keySystem$.value - } - destroy() { - this.reset$.next(), - this.ksService.removeAll(), - this.keySystemId = null; - const e = this.keySystem; - let t = Ul; - return e && (this.keySystem$.next(null), - e.shouldDestroyMediaKeys && this.keySystemFactory.destroyMediaKeys(), - t = e.destroy()), - Cr([t, this.mediaSink.clearMediaKeys(this.config.clearMediaKeysOnPromise)]).pipe(Js(void 0)) - } - attachMediaKeys() { - if (this.keySystem) - return Ul; - var e = this.config.keySystemPreference ? Ih.getKeySystemFormat(this.config.keySystemPreference) : pu.keyFormatString; - return this.makeKeySystem(new Gc("NONE",null,null,e,[1])).pipe(Js(void 0)) - } - isKeyCleanupSupported() { - return !0 === this.config.useMultipleKeySessions || "widevine" === this.config.keySystemPreference || "playready" === this.config.keySystemPreference - } - handleKeyCleanup(i) { - if (this.ksQuery.getCount() < 6) - return Ul; - const r = performance.now() - , e = this.ksQuery.getAll().map(e=>{ - var t = e.keyUri; - if (!i.has(t)) { - const i = eu(e.decryptdata); - if ("AES-128" !== i.method && r > e.minHoldTime) - return this._removeKey(t, i) - } - return Ul - } - ); - return e.length ? Jr(e).pipe(Ua(Ul)) : Ul - } - _removeKey(e, t) { - return this.abort$.next(e), - this.ksService.removeKey(e), - this.keySystem.removeKey(t) - } - removeKeysForItems(i) { - const r = []; - return sd(()=>{ - for (const e of i) { - this.ksService.removeAllKeysForItem(e); - const i = this.ksQuery.getAll({ - filterBy: e=>0 === e.itemIds.length - }); - for (const t of i) - r.push(this._removeKey(t.keyUri, eu(t.decryptdata))) - } - } - ), - r.length ? Jr(r).pipe(Ra(()=>Ul)) : Ul - } - get availableKeySystems() { - return Ih.availableKeySystems - } - initialize(e) { - var t = this.protectionData; - this.protectionData = {}; - var i = this.config.keySystemPreference; - for (const a of Ih.availableKeySystems) { - var r = e[a]; - if (r) - if (i === a) { - var n, s = r.certificate, r = r.serverCertUrl ? fl.buildAbsoluteURL(window.location.href, r.serverCertUrl) : void 0; - let e; - this.protectionData[a] = { - serverCertUrl: r, - certificate: s - }, - s ? e = Bi({ - keysystem: a, - certificate: s - }) : r && (null === (n = null == t ? void 0 : t[a]) || void 0 === n ? void 0 : n.serverCertUrl) !== r && (n = ml(r) ? this.config.certLoadPolicy.customURL : this.config.certLoadPolicy.default, - e = Pc({ - url: r, - xhrSetup: this.config.xhrSetup - }, n).pipe(ur(([e])=>({ - keysystem: a, - certificate: new Uint8Array(e) - })))), - e && e.pipe(Ra(e=>this.onServerCertificateLoaded(e)), Un(e=>{ - throw this.eventEmitter.trigger(P.INTERNAL_ERROR, { - type: o, - details: "certificateLoadError", - fatal: !1, - handled: !0, - reason: "Error handling cert", - response: $.KeySystemCertificateLoadError, - message: e.message, - name: "certificateLoadError" - }), - e - } - ), $a(this.reset$)).subscribe() - } else - this.logger.warn(`Key system ${a} does not match preference ${i}, ignoring`) - } - } - generateRequest(e, t) { - this.keySystem && this.keySystem.setKeyRequestInfo(e, t) - } - setLicenseResponse(e, t) { - this.keySystem && this.keySystem.setParsedResponse(e, t) - } - getKeyFromDecryptData(e, t) { - if (!e || !e.isEncrypted) - return Bi(e); - let i; - return sd(()=>{ - i = this._getKeyFromDecryptData(e, t) - } - ), - i - } - _getKeyFromDecryptData(t, i) { - let r = null - , n = null; - i && (r = i.itemId, - n = i.mediaOptionId); - const s = t.uri - , e = this.ksQuery.getKeyInfo(s); - if (e && null != i && this.ksService.addMediaOption(s, i), - (null == e ? void 0 : e.error)instanceof uu && !1 === e.error.isOkToRetry) - return Ui(e.error); - if (e && e.requestState !== zl.MustRequestResponse) - return e.requestState === zl.GotKeyResponse ? Bi(eu(e.decryptdata)) : this.keyUriToRequest[s]; - { - const o = performance.now() + this.config.keyMinHoldTimeBeforeCleanup; - let e; - this.abort$.next(s), - this.ksService.upsertKey({ - keyUri: s, - decryptdata: function(e) { - var {method: t, isEncrypted: i, uri: r, format: n, formatversions: s} = e; - return { - method: t, - isEncrypted: i, - uri: r, - format: n, - formatversions: s, - ivBuf: null !== (s = null === (s = e.iv) || void 0 === s ? void 0 : s.buffer) && void 0 !== s ? s : null, - keyIdBuf: null === (s = e.keyId) || void 0 === s ? void 0 : s.buffer, - keyBuf: null === (s = e.key) || void 0 === s ? void 0 : s.buffer, - psshBuf: null === (e = e.key) || void 0 === e ? void 0 : e.buffer - } - }(t), - minHoldTime: o, - mediaOptionIds: [n], - requestState: zl.WaitingForKeyResponse, - itemIds: [r] - }); - var a = t.method; - switch (a) { - case "SAMPLE-AES": - case "ISO-23001-7": - case "SAMPLE-AES-CTR": - { - const o = this.config.keyLoadPolicy.customURL; - e = this.fetchKeyEME(t).pipe(vo(o.maxLoadTimeMs)); - break - } - case "AES-128": - e = this.fetchKeyHTTP(t.uri, t, this.config.keyLoadPolicy); - break; - default: - return Ui(new V(!1,`Unexpected METHOD attribute ${a}`,$.KeySystemUnexpectedMETHOD)) - } - i = this.keyUriToRequest[s] = e.pipe(ur(e=>{ - var t = e.decryptdata; - return this.ksService.updateKeyValue(s, t.key), - this.eventEmitter.trigger(P.KEY_LOADED, e), - e.decryptdata - } - ), Un(e=>{ - var t = this.ksQuery.getKeyInfo(s); - return e = Oh(s, e, null !== (t = null == t ? void 0 : t.mediaOptionIds) && void 0 !== t ? t : []), - this.ksService.setError(s, e), - Ui(e) - } - ), $s(()=>{ - this.ksService.updateKeyRequestState(s, zl.MustRequestResponse, e=>e === zl.WaitingForKeyResponse), - this.keyUriToRequest[s] = null - } - ), wa(), $a(hn(this.abort$.pipe(an(e=>e === s)), this.reset$).pipe(Ja(e=>this.logger.warn(e ? `aborted ${oe(e)}` : "got reset"))))); - return this.keyRequest$.next(i), - i - } - } - fetchKeyEME(e) { - return this.requestKey(e).pipe(ur(e=>({ - timestamp: performance.now(), - keyuri: e.uri, - decryptdata: e - }))) - } - fetchKeyHTTP(e, t, i) { - return kh.fetchKeyHTTP(e, this.config, t, i) - } - static fetchKeyHTTP(t, e, i, r) { - e = { - url: t, - xhrSetup: e.xhrSetup - }; - return Pc(e, xc(e, r)).pipe(ur(([e])=>(i.key = new Uint8Array(e), - { - decryptdata: i, - keyuri: t, - timestamp: performance.now() - }))) - } - requestKey(t) { - return this.makeKeySystem(t).pipe(Ra(e=>e.startKeyRequest(t))) - } - ensureKeySystem(t) { - return Yr(()=>{ - if (!this.keySystem && this.keySystemId) { - this.keySystem$.next(this.keySystemFactory.make(this.keySystemId, t, this.config, this.eventEmitter, this.sessionHandler, this.logger)); - var e = this.protectionData && this.protectionData[this.keySystemId]; - if (e) - return this.keySystem.setServerCertificate(e.certificate).pipe(Js(this.keySystem)) - } - return Bi(this.keySystem) - } - ) - } - makeKeySystem(e) { - return this.ensureMediaKeys(e).pipe(Ra(e=>this.mediaSink.setMediaKeys(e).pipe(Ra(()=>this.ensureKeySystem(e))))) - } - ensureMediaKeys(e) { - var t = Ih.getKeySystemIdForDecryptData(e); - if (null == this.keySystemId) - this.keySystemId = t; - else if (this.keySystemId !== t) - return Ui(new uu(`New key system string does not match existing ${t} !== ${this.keySystemId}`,e.uri,0,$.KeySystemUnmatchedString,!1,Xl.InternalError)); - return this.keySystemFactory.createMediaKeys(this.keySystemId, wh, Ah, this.logger, null === (e = this.platformQuery.platformInfo) || void 0 === e ? void 0 : e.keySystemConfig) - } - onServerCertificateLoaded(e) { - var t = e.keysystem - , e = e.certificate; - return this.protectionData[t].certificate = e, - this.keySystem && this.keySystemId === t ? this.keySystem.setServerCertificate(e).pipe(Js(void 0)) : Ul - } - handleKeySystemError(e) { - e = new cu(e.message,void 0,void 0,$.KeySystemSetupError,void 0); - this.eventEmitter.trigger(P.INTERNAL_ERROR, e) - } - } - class Ch extends Od { - constructor(e) { - super(e) - } - getKeyInfo(e) { - e = this.getEntity(e); - return e ? Object.assign(Object.assign({}, e), { - error: hu(e.error, e.mediaOptionIds) - }) : null - } - getKeyInfo$(e) { - return this.selectEntity(e).pipe(ur(e=>e ? Object.assign(Object.assign({}, e), { - error: hu(e.error, e.mediaOptionIds) - }) : null)) - } - getKeyRequestState$(e) { - return this.selectEntity(e, e=>null == e ? void 0 : e.requestState) - } - getKeyStatus$(e) { - return this.selectEntity(e, e=>null == e ? void 0 : e.status) - } - getKeyError$(e) { - return this.selectEntity(e, e=>hu(null == e ? void 0 : e.error, null == e ? void 0 : e.mediaOptionIds)).pipe(Id) - } - } - class Dh { - constructor(e) { - this.store = e - } - getQuery() { - return new Ch(this.store) - } - upsertKey(i) { - Co("keys.upsert", i.keyUri); - const r = new Set(i.itemIds.filter(e=>null != e)) - , n = new Set(i.mediaOptionIds.filter(e=>null != e)); - this.store.upsert(i.keyUri, e=>{ - const t = Object.assign(Object.assign({}, e), i); - if ("itemIds"in e) - for (const i of e.itemIds) - r.add(i); - if (t.itemIds = Array.from(r), - "mediaOptionIds"in e) - for (const i of e.mediaOptionIds) - n.add(i); - return t.mediaOptionIds = Array.from(n), - t - } - , ()=>Object.assign(Object.assign({}, i), { - itemIds: Array.from(r), - mediaOptionIds: Array.from(n) - })) - } - removeKey(e) { - Co("keys.removeKey", e), - this.store.remove(e) - } - removeAllKeysForItem(i) { - Co(`keys.removeAllKeysForItem ${i}`), - this.store.update(null, e=>{ - var t = e.itemIds.findIndex(e=>e === i); - 0 <= t && e.itemIds.splice(t, 1) - } - ) - } - removeAll() { - Co("keys.remove"), - this.store.remove() - } - updateKeyValue(e, t) { - Co("keys.updateKeyValue", e), - this.store.update(e, e=>{ - null == e.decryptdata.keyBuf && null != t && (e.decryptdata.keyBuf = t.buffer), - e.requestState = zl.GotKeyResponse - } - ) - } - updateKeyStatus(e, t) { - Co(`keys.updateKeyStatus ${t}`, e), - this.store.update(e, e=>{ - e.status = t - } - ) - } - updateKeyRequestState(e, t, i) { - Co(`keys.updateKeyRequestState ${t}`, e), - this.store.update(e, e=>{ - i && !i(e.requestState) || (e.requestState = t) - } - ) - } - addMediaOption(e, t) { - const {itemId: i, mediaOptionId: r} = t; - Co(`keys.addMediaOption itemId: ${i}, mediaOptionId: ${r}`, e), - this.store.update(e, e=>{ - null != r && e.mediaOptionIds.every(e=>e !== r) && e.mediaOptionIds.push(r), - null != i && e.itemIds.every(e=>e !== i) && e.itemIds.push(i) - } - ) - } - setError(e, t) { - var i; - Co(`keys.setError ${null === (i = null == t ? void 0 : t.constructor) || void 0 === i ? void 0 : i.name}`, e), - this.store.update(e, e=>{ - e.error = hu(t), - e.requestState = zl.MustRequestResponse - } - ) - } - } - const Mh = new class extends pd { - constructor() { - super({}, { - name: "key-system-store", - idKey: "keyUri", - producerFn: vc - }) - } - } - ; - let Ph = null; - function xh(e) { - let t = e; - return Lh.hasOwnProperty(e) && (t = Lh[e]), - String.fromCharCode(t) - } - function Rh(t) { - const i = []; - for (let e = 0; e < t.length; e++) - i.push(t[e].toString(16)); - return i - } - const Lh = { - 42: 225, - 92: 233, - 94: 237, - 95: 243, - 96: 250, - 123: 231, - 124: 247, - 125: 209, - 126: 241, - 127: 9608, - 128: 174, - 129: 176, - 130: 189, - 131: 191, - 132: 8482, - 133: 162, - 134: 163, - 135: 9834, - 136: 224, - 137: 32, - 138: 232, - 139: 226, - 140: 234, - 141: 238, - 142: 244, - 143: 251, - 144: 193, - 145: 201, - 146: 211, - 147: 218, - 148: 220, - 149: 252, - 150: 8216, - 151: 161, - 152: 42, - 153: 8217, - 154: 9473, - 155: 169, - 156: 8480, - 157: 8226, - 158: 8220, - 159: 8221, - 160: 192, - 161: 194, - 162: 199, - 163: 200, - 164: 202, - 165: 203, - 166: 235, - 167: 206, - 168: 207, - 169: 239, - 170: 212, - 171: 217, - 172: 249, - 173: 219, - 174: 171, - 175: 187, - 176: 195, - 177: 227, - 178: 205, - 179: 204, - 180: 236, - 181: 210, - 182: 242, - 183: 213, - 184: 245, - 185: 123, - 186: 125, - 187: 92, - 188: 94, - 189: 95, - 190: 124, - 191: 8764, - 192: 196, - 193: 228, - 194: 214, - 195: 246, - 196: 223, - 197: 165, - 198: 164, - 199: 9475, - 200: 197, - 201: 229, - 202: 216, - 203: 248, - 204: 9487, - 205: 9491, - 206: 9495, - 207: 9499 - } - , _h = 100 - , Nh = { - 17: 1, - 18: 3, - 21: 5, - 22: 7, - 23: 9, - 16: 11, - 19: 12, - 20: 14 - } - , Fh = { - 17: 2, - 18: 4, - 21: 6, - 22: 8, - 23: 10, - 19: 13, - 20: 15 - } - , Bh = { - 25: 1, - 26: 3, - 29: 5, - 30: 7, - 31: 9, - 24: 11, - 27: 12, - 28: 14 - } - , Uh = { - 25: 2, - 26: 4, - 29: 6, - 30: 8, - 31: 10, - 27: 13, - 28: 15 - } - , $h = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "black", "transparent"] - , Vh = { - verboseFilter: { - DATA: 3, - DEBUG: 3, - INFO: 2, - WARNING: 2, - TEXT: 1, - ERROR: 0 - }, - time: null, - verboseLevel: 0, - setTime: function(e) { - this.time = e - }, - log: function(e, t) { - var i = this.verboseFilter[e]; - this.verboseLevel >= i && console.log(this.time + " [" + e + "] " + t) - } - }; - class Kh { - constructor(e, t, i, r, n) { - this.foreground = e || "white", - this.underline = t || !1, - this.italics = i || !1, - this.background = r || "black", - this.flash = n || !1 - } - reset() { - this.foreground = "white", - this.underline = !1, - this.italics = !1, - this.background = "black", - this.flash = !1 - } - setStyles(e) { - Object.assign(this, e) - } - isDefault() { - return "white" === this.foreground && !this.underline && !this.italics && "black" === this.background && !this.flash - } - equals(e) { - return this.foreground === e.foreground && this.underline === e.underline && this.italics === e.italics && this.background === e.background && this.flash === e.flash - } - copy(e) { - this.foreground = e.foreground, - this.underline = e.underline, - this.italics = e.italics, - this.background = e.background, - this.flash = e.flash - } - toString() { - return "color=" + this.foreground + ", underline=" + this.underline + ", italics=" + this.italics + ", background=" + this.background + ", flash=" + this.flash - } - } - class Hh { - constructor(e, t, i, r, n, s) { - this.uchar = e || " ", - this.penState = new Kh(t,i,r,n,s) - } - reset() { - this.uchar = " ", - this.penState.reset() - } - setChar(e, t) { - this.uchar = e, - this.penState.copy(t) - } - setPenState(e) { - this.penState.copy(e) - } - equals(e) { - return this.uchar === e.uchar && this.penState.equals(e.penState) - } - copy(e) { - this.uchar = e.uchar, - this.penState.copy(e.penState) - } - isEmpty() { - return " " === this.uchar && this.penState.isDefault() - } - } - class jh { - constructor() { - this.chars = []; - for (let e = 0; e < _h; e++) - this.chars.push(new Hh); - this.pos = 0, - this.currPenState = new Kh - } - equals(t) { - let i = !0; - for (let e = 0; e < _h; e++) - if (!this.chars[e].equals(t.chars[e])) { - i = !1; - break - } - return i - } - copy(t) { - for (let e = 0; e < _h; e++) - this.chars[e].copy(t.chars[e]) - } - isEmpty() { - let t = !0; - for (let e = 0; e < _h; e++) - if (!this.chars[e].isEmpty()) { - t = !1; - break - } - return t - } - setCursor(e) { - this.pos !== e && (this.pos = e), - this.pos < 0 ? (Vh.log("ERROR", "Negative cursor position " + this.pos), - this.pos = 0) : this.pos > _h && (Vh.log("ERROR", "Too large cursor position " + this.pos), - this.pos = _h) - } - moveCursor(e) { - var t = this.pos + e; - if (1 < e) - for (let e = this.pos + 1; e < t + 1; e++) - this.chars[e].setPenState(this.currPenState); - this.setCursor(t) - } - backSpace() { - this.moveCursor(-1), - this.chars[this.pos].setChar(" ", this.currPenState) - } - insertChar(e) { - 144 <= e && this.backSpace(); - var t = xh(e); - this.pos >= _h ? Vh.log("ERROR", "Cannot insert " + e.toString(16) + " (" + t + ") at position " + this.pos + ". Skipping it!") : (this.chars[this.pos].setChar(t, this.currPenState), - this.moveCursor(1)) - } - clearFromPos(e) { - let t; - for (t = e; t < _h; t++) - this.chars[t].reset() - } - clear() { - this.clearFromPos(0), - this.pos = 0, - this.currPenState.reset() - } - clearToEndOfRow() { - this.clearFromPos(this.pos) - } - getTextString() { - const t = []; - let i = !0; - for (let e = 0; e < _h; e++) { - var r = this.chars[e].uchar; - " " !== r && (i = !1), - t.push(r) - } - return i ? "" : t.join("") - } - setPenStyles(e) { - this.currPenState.setStyles(e), - this.chars[this.pos].setPenState(this.currPenState) - } - } - class qh { - constructor() { - this.rows = []; - for (let e = 0; e < 15; e++) - this.rows.push(new jh); - this.currRow = 14, - this.nrRollUpRows = null, - this.reset() - } - reset() { - for (let e = 0; e < 15; e++) - this.rows[e].clear(); - this.currRow = 14 - } - equals(t) { - let i = !0; - for (let e = 0; e < 15; e++) - if (!this.rows[e].equals(t.rows[e])) { - i = !1; - break - } - return i - } - copy(t) { - for (let e = 0; e < 15; e++) - this.rows[e].copy(t.rows[e]) - } - isEmpty() { - let t = !0; - for (let e = 0; e < 15; e++) - if (!this.rows[e].isEmpty()) { - t = !1; - break - } - return t - } - backSpace() { - this.rows[this.currRow].backSpace() - } - clearToEndOfRow() { - this.rows[this.currRow].clearToEndOfRow() - } - insertChar(e) { - this.rows[this.currRow].insertChar(e) - } - setPen(e) { - this.rows[this.currRow].setPenStyles(e) - } - moveCursor(e) { - this.rows[this.currRow].moveCursor(e) - } - setCursor(e) { - Vh.log("INFO", "setCursor: " + e), - this.rows[this.currRow].setCursor(e) - } - setPAC(t) { - Vh.log("INFO", "pacData = " + JSON.stringify(t)); - let i = t.row - 1; - if (this.nrRollUpRows && i < this.nrRollUpRows - 1 && (i = this.nrRollUpRows - 1), - this.nrRollUpRows && this.currRow !== i) { - for (let e = 0; e < 15; e++) - this.rows[e].clear(); - const t = this.currRow + 1 - this.nrRollUpRows - , r = this.lastOutputScreen; - if (r) { - const e = r.rows[t].cueStartTime; - if (e && e < Vh.time) - for (let e = 0; e < this.nrRollUpRows; e++) - this.rows[i - this.nrRollUpRows + e + 1].copy(r.rows[t + e]) - } - } - this.currRow = i; - const r = this.rows[this.currRow]; - if (null !== t.indent) { - const i = t.indent - , e = Math.max(i - 1, 0); - r.setCursor(t.indent), - t.color = r.chars[e].penState.foreground - } - const e = { - foreground: t.color, - underline: t.underline, - italics: t.italics, - background: "black", - flash: !1 - }; - this.setPen(e) - } - setBkgData(e) { - Vh.log("INFO", "bkgData = " + JSON.stringify(e)), - this.backSpace(), - this.setPen(e), - this.insertChar(32) - } - setRollUpRows(e) { - this.nrRollUpRows = e - } - rollUp() { - if (null !== this.nrRollUpRows) { - Vh.log("INFO", "TEXT " + this.getDisplayText()); - const e = this.currRow + 1 - this.nrRollUpRows - , t = this.rows.splice(e, 1)[0]; - t.clear(), - this.rows.splice(this.currRow, 0, t), - Vh.log("INFO", "Rolling up") - } else - Vh.log("DEBUG", "roll_up but nrRollUpRows not set yet") - } - getDisplayText(t) { - t = t || !1; - const i = []; - let e = "", r; - for (let e = 0; e < 15; e++) { - const n = this.rows[e].getTextString(); - n && (r = e + 1, - t ? i.push("Row " + r + ": '" + n + "'") : i.push(n.trim())) - } - return 0 < i.length && (e = t ? "[" + i.join(" | ") + "]" : i.join("\n")), - e - } - getTextAndFormat() { - return this.rows - } - } - class Qh { - constructor(e, t) { - this.chNr = e, - this.outputFilter = t, - this.mode = null, - this.verbose = 0, - this.displayedMemory = new qh, - this.nonDisplayedMemory = new qh, - this.lastOutputScreen = new qh, - this.currRollUpRow = this.displayedMemory.rows[14], - this.writeScreen = this.displayedMemory, - this.mode = null, - this.cueStartTime = null - } - reset() { - this.mode = null, - this.displayedMemory.reset(), - this.nonDisplayedMemory.reset(), - this.lastOutputScreen.reset(), - this.currRollUpRow = this.displayedMemory.rows[14], - this.writeScreen = this.displayedMemory, - this.mode = null, - this.cueStartTime = null, - this.lastCueEndTime = null - } - getHandler() { - return this.outputFilter - } - setHandler(e) { - this.outputFilter = e - } - setPAC(e) { - this.writeScreen.setPAC(e) - } - setBkgData(e) { - this.writeScreen.setBkgData(e) - } - setMode(e) { - e !== this.mode && (this.mode = e, - Vh.log("INFO", "MODE=" + e), - "MODE_POP-ON" === this.mode ? this.writeScreen = this.nonDisplayedMemory : (this.writeScreen = this.displayedMemory, - this.writeScreen.reset()), - "MODE_ROLL-UP" !== this.mode && (this.displayedMemory.nrRollUpRows = null, - this.nonDisplayedMemory.nrRollUpRows = null), - this.mode = e) - } - insertChars(t) { - for (let e = 0; e < t.length; e++) - this.writeScreen.insertChar(t[e]); - var e = this.writeScreen === this.displayedMemory ? "DISP" : "NON_DISP"; - Vh.log("INFO", e + ": " + this.writeScreen.getDisplayText(!0)), - "MODE_PAINT-ON" !== this.mode && "MODE_ROLL-UP" !== this.mode || (Vh.log("TEXT", "DISPLAYED: " + this.displayedMemory.getDisplayText(!0)), - this.outputDataUpdate()) - } - ccRCL() { - Vh.log("INFO", "RCL - Resume Caption Loading"), - this.setMode("MODE_POP-ON") - } - ccBS() { - Vh.log("INFO", "BS - BackSpace"), - "MODE_TEXT" !== this.mode && (this.writeScreen.backSpace(), - this.writeScreen === this.displayedMemory && this.outputDataUpdate()) - } - ccAOF() {} - ccAON() {} - ccDER() { - Vh.log("INFO", "DER- Delete to End of Row"), - this.writeScreen.clearToEndOfRow(), - this.outputDataUpdate() - } - ccRU(e) { - Vh.log("INFO", "RU(" + e + ") - Roll Up"), - this.writeScreen = this.displayedMemory, - this.setMode("MODE_ROLL-UP"), - this.writeScreen.setRollUpRows(e) - } - ccFON() { - Vh.log("INFO", "FON - Flash On"), - this.writeScreen.setPen({ - flash: !0 - }) - } - ccRDC() { - Vh.log("INFO", "RDC - Resume Direct Captioning"), - this.setMode("MODE_PAINT-ON") - } - ccTR() { - Vh.log("INFO", "TR"), - this.setMode("MODE_TEXT") - } - ccRTD() { - Vh.log("INFO", "RTD"), - this.setMode("MODE_TEXT") - } - ccEDM() { - Vh.log("INFO", "EDM - Erase Displayed Memory"), - this.displayedMemory.reset(), - this.outputDataUpdate(!0) - } - ccCR() { - Vh.log("INFO", "CR - Carriage Return"), - this.writeScreen.rollUp(), - this.outputDataUpdate(!0) - } - ccENM() { - Vh.log("INFO", "ENM - Erase Non-displayed Memory"), - this.nonDisplayedMemory.reset() - } - ccEOC() { - var e; - Vh.log("INFO", "EOC - End Of Caption"), - "MODE_POP-ON" === this.mode && (e = this.displayedMemory, - this.displayedMemory = this.nonDisplayedMemory, - this.nonDisplayedMemory = e, - this.writeScreen = this.nonDisplayedMemory, - Vh.log("TEXT", "DISP: " + this.displayedMemory.getDisplayText())), - this.outputDataUpdate(!0) - } - ccTO(e) { - Vh.log("INFO", "TO(" + e + ") - Tab Offset"), - this.writeScreen.moveCursor(e) - } - ccMIDROW(e) { - const t = { - flash: !1, - underline: !1, - italics: !1 - }; - t.underline = e % 2 == 1, - t.italics = 46 <= e, - t.italics ? t.foreground = "white" : (e = Math.floor(e / 2) - 16, - t.foreground = ["white", "green", "blue", "cyan", "red", "yellow", "magenta"][e]), - Vh.log("INFO", "MIDROW: " + JSON.stringify(t)), - this.writeScreen.setPen(t) - } - outputDataUpdate(e=!1) { - var t = Vh.time; - null !== t && this.outputFilter && (this.outputFilter.updateData && this.outputFilter.updateData(t, this.displayedMemory), - null !== this.cueStartTime || this.displayedMemory.isEmpty() ? this.displayedMemory.equals(this.lastOutputScreen) || (this.outputFilter.newCue && (this.outputFilter.newCue(this.cueStartTime, t, this.lastOutputScreen), - !0 === e && this.outputFilter.dispatchCue && this.outputFilter.dispatchCue()), - this.cueStartTime = this.displayedMemory.isEmpty() ? null : t) : this.cueStartTime = t, - this.lastOutputScreen.copy(this.displayedMemory)) - } - cueSplitAtTime(e) { - this.outputFilter && (this.displayedMemory.isEmpty() || (this.outputFilter.newCue && this.outputFilter.newCue(this.cueStartTime, e, this.displayedMemory), - this.cueStartTime = e)) - } - } - var Gh = class { - constructor(e=1, t, i) { - this.field = e, - this.currChNr = -1, - this.lastCmdA = null, - this.lastCmdB = null, - this.channels = [new Qh(1,t), new Qh(2,i)], - this.dataCounters = { - padding: 0, - char: 0, - cmd: 0, - other: 0 - } - } - getHandler(e) { - return this.channels[e].getHandler() - } - setHandler(e, t) { - this.channels[e].setHandler(t) - } - addData(e, t) { - let i, r, n, s = null; - Vh.setTime(e); - for (let e = 0; e < t.length; e += 2) - r = 127 & t[e], - n = 127 & t[e + 1], - 16 <= r && r <= 31 && r === this.lastCmdA && n === this.lastCmdB ? (this.lastCmdA = null, - this.lastCmdB = null, - Vh.log("DEBUG", "Repeated command (" + Rh([r, n]) + ") is dropped")) : 0 != r || 0 != n ? (Vh.log("DATA", "[" + Rh([t[e], t[e + 1]]) + "] -> (" + Rh([r, n]) + ")"), - i = this.parseCmd(r, n), - i = i || this.parseMidrow(r, n), - i = i || this.parsePAC(r, n), - i = i || this.parseBackgroundAttributes(r, n), - !i && (s = this.parseChars(r, n), - s) && (this.currChNr && 0 <= this.currChNr ? this.channels[this.currChNr - 1].insertChars(s) : Vh.log("WARNING", "No channel found yet. TEXT-MODE?")), - i ? this.dataCounters.cmd += 2 : s ? this.dataCounters.char += 2 : (this.dataCounters.other += 2, - Vh.log("WARNING", "Couldn't parse cleaned data " + Rh([r, n]) + " orig: " + Rh([t[e], t[e + 1]])))) : this.dataCounters.padding += 2 - } - parseCmd(e, t) { - var i; - if (!((20 === e || 21 === e || 28 === e || 29 === e) && 32 <= t && t <= 47 || (23 === e || 31 === e) && 33 <= t && t <= 35)) - return !1; - const r = this.channels[(i = 20 === e || 23 === e ? 1 : 2) - 1]; - return 20 === e || 21 === e || 28 === e || 29 === e ? 32 === t ? r.ccRCL() : 33 === t ? r.ccBS() : 34 === t ? r.ccAOF() : 35 === t ? r.ccAON() : 36 === t ? r.ccDER() : 37 === t ? r.ccRU(2) : 38 === t ? r.ccRU(3) : 39 === t ? r.ccRU(4) : 40 === t ? r.ccFON() : 41 === t ? r.ccRDC() : 42 === t ? r.ccTR() : 43 === t ? r.ccRTD() : 44 === t ? r.ccEDM() : 45 === t ? r.ccCR() : 46 === t ? r.ccENM() : 47 === t && r.ccEOC() : r.ccTO(t - 32), - this.lastCmdA = e, - this.lastCmdB = t, - this.currChNr = i, - !0 - } - parseMidrow(e, t) { - var i; - if ((17 === e || 25 === e) && 32 <= t && t <= 47) { - if ((i = 17 === e ? 1 : 2) !== this.currChNr) - return Vh.log("ERROR", "Mismatch channel in midrow parsing"), - !1; - const r = this.channels[i - 1]; - return r.insertChars([32]), - r.ccMIDROW(t), - Vh.log("DEBUG", "MIDROW (" + Rh([e, t]) + ")"), - this.lastCmdA = e, - this.lastCmdB = t, - !0 - } - return !1 - } - parsePAC(e, t) { - if (!((17 <= e && e <= 23 || 25 <= e && e <= 31) && 64 <= t && t <= 127 || (16 === e || 24 === e) && 64 <= t && t <= 95)) - return !1; - var i = e <= 23 ? 1 : 2 - , r = (64 <= t && t <= 95 ? 1 == i ? Nh : Bh : 1 == i ? Fh : Uh)[e] - , r = this.interpretPAC(r, t); - return this.channels[i - 1].setPAC(r), - this.lastCmdA = e, - this.lastCmdB = t, - this.currChNr = i, - !0 - } - interpretPAC(e, t) { - var i; - const r = { - color: null, - italics: !1, - indent: null, - underline: !1, - row: e - }; - return i = 95 < t ? t - 96 : t - 64, - r.underline = 1 == (1 & i), - i <= 13 ? r.color = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "white"][Math.floor(i / 2)] : i <= 15 ? (r.italics = !0, - r.color = "white") : r.indent = 4 * Math.floor((i - 16) / 2), - r - } - parseChars(e, t) { - let i = null - , r = null - , n = null; - var s; - if (n = 25 <= e ? (i = 2, - e - 8) : (i = 1, - e), - 17 <= n && n <= 19 ? (s = t, - s = 17 === n ? t + 80 : 18 === n ? t + 112 : t + 144, - Vh.log("INFO", "Special char '" + xh(s) + "' in channel " + i), - r = [s], - this.lastCmdA = e, - this.lastCmdB = t) : 32 <= e && e <= 127 && (r = 0 === t ? [e] : [e, t], - this.lastCmdA = null, - this.lastCmdB = null), - r) { - const e = Rh(r); - Vh.log("DEBUG", `Char codes = ${e.join(",")}`) - } - return r - } - parseBackgroundAttributes(e, t) { - let i, r, n; - return ((16 === e || 24 === e) && 32 <= t && t <= 47 || (23 === e || 31 === e) && 45 <= t && t <= 47) && (i = { - underline: !1 - }, - 16 === e || 24 === e ? (r = Math.floor((t - 32) / 2), - i.background = $h[r], - t % 2 == 1 && (i.background = i.background + "_semi")) : 45 === t ? i.background = "transparent" : (i.foreground = "black", - 47 === t && (i.underline = !0)), - n = this.channels[(e < 24 ? 1 : 2) - 1], - n.setBkgData(i), - this.lastCmdA = null, - !(this.lastCmdB = null)) - } - reset() { - for (let e = 0; e < this.channels.length; e++) - this.channels[e] && this.channels[e].reset(); - this.lastCmdA = null, - this.lastCmdB = null - } - cueSplitAtTime(t) { - for (let e = 0; e < this.channels.length; e++) - this.channels[e] && this.channels[e].cueSplitAtTime(t) - } - } - ; - class Wh { - constructor(e, t) { - this.handler = e, - this.track = t, - this.startTime = null, - this.endTime = null, - this.screen = null - } - dispatchCue() { - null !== this.startTime && (this.handler.addCues("cc" + this.track, this.startTime, this.endTime, this.screen), - this.startTime = null) - } - newCue(e, t, i) { - (null === this.startTime || this.startTime > e) && (this.startTime = e), - this.endTime = t, - this.screen = i, - this.handler.createHTMLCaptionsTrack(this.track) - } - } - var zh = {} - , mu = {} - , gr = {} - , t = {}; - Object.defineProperty(t, "__esModule", { - value: !0 - }), - t.isValidPercentValue = function(e) { - return "number" == typeof e && 0 <= e && e <= 100 - } - , - t.isValidAlignSetting = function(e) { - return "string" == typeof e && ["start", "center", "end", "left", "right", "middle"].includes(e) - } - , - t.isValidDirectionSetting = function(e) { - return "string" == typeof e && ["", "rl", "lr"].includes(e) - } - , - t.isValidLineAndPositionSetting = function(e) { - return "number" == typeof e || "auto" === e - } - , - t.isValidLineAlignSetting = function(e) { - return "string" == typeof e && ["start", "center", "end"].includes(e) - } - , - t.isValidPositionAlignSetting = function(e) { - return "string" == typeof e && ["line-left", "center", "line-right", "auto", "left", "start", "middle", "end", "right"].includes(e) - } - , - t.isValidScrollSetting = function(e) { - return ["", "up"].includes(e) - } - ; - yc = {}; - Object.defineProperty(yc, "__esModule", { - value: !0 - }); - const Xh = { - "&": "&", - "<": "<", - ">": ">", - "‎": "‎", - "‏": "‏", - " ": " " - } - , Yh = { - c: "span", - i: "i", - b: "b", - u: "u", - ruby: "ruby", - rt: "rt", - v: "span", - lang: "span" - } - , Jh = { - v: "title", - lang: "lang" - } - , Zh = { - rt: "ruby" - } - , ep = { - "text-combine-upright": "-webkit-text-combine:horizontal; text-orientation: mixed;" - }; - class tp { - static parseTimeStamp(e) { - function t(e) { - var [t,i,r,e] = e.map(e=>e ? parseInt("" + e) : 0); - return 3600 * t + 60 * i + r + e / 1e3 - } - const i = /^(\d+):(\d{2})(:\d{2})?\.(\d{3})/.exec(e); - return i ? i[3] ? t([i[1], i[2], i[3].substring(1), i[4]]) : 59 < parseInt(i[1]) ? t([i[1], i[2], null, i[4]]) : t([null, i[1], i[2], i[4]]) : null - } - static parseContent(s, t, a) { - let i = t.text; - function e(e) { - return Xh[e] - } - const r = s.document.createElement("div") - , n = []; - let o, d, l = r; - for (; null !== (o = function() { - if (!i) - return null; - var e = (e = /^([^<]*)(<[^>]+>?)?/.exec(i))[1] || e[2]; - return i = i.substr(e.length), - e - }()); ) - if ("<" !== o[0]) - l.appendChild(s.document.createTextNode(o.replace(/&(amp|lt|gt|lrm|rlm|nbsp);/g, e))); - else { - if ("/" === o[1]) { - n.length && n[n.length - 1] === o.substr(2).replace(">", "") && (n.pop(), - l = l.parentNode); - continue - } - const t = tp.parseTimeStamp(o.substr(1, o.length - 2)); - let e; - if (t) { - e = s.document.createProcessingInstruction("timestamp", t.toString()), - l.appendChild(e); - continue - } - if (!(d = /^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/.exec(o))) - continue; - if (e = function(e, t, i) { - var r = Yh[e]; - if (!r) - return null; - const n = s.document.createElement(r); - if (n.dataset.localName = r, - (e = Jh[e]) && i && (n[e] = i.trim()), - t) - if (a[t]) { - const s = function(e) { - let t = ""; - for (const i in e) - t += ep[i] || i + ":" + e[i] + ";"; - return t - }(a[t]); - n.setAttribute("style", s) - } else - console.info(`WebVTT: parseContent: Style referenced, but no style defined for '${t}'!`); - return n - }(d[1], d[2], d[3]), - !e) - continue; - if (u = l, - c = e, - Zh[c.dataset.localName] && Zh[c.dataset.localName] !== u.dataset.localName) - continue; - n.push(d[1]), - l.appendChild(e), - l = e - } - var u, c; - return r - } - } - yc.default = tp; - gc = e && e.__decorate || function(e, t, i, r) { - var n, s = arguments.length, a = s < 3 ? t : null === r ? r = Object.getOwnPropertyDescriptor(t, i) : r; - if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) - a = Reflect.decorate(e, t, i, r); - else - for (var o = e.length - 1; 0 <= o; o--) - (n = e[o]) && (a = (s < 3 ? n(a) : 3 < s ? n(t, i, a) : n(t, i)) || a); - return 3 < s && a && Object.defineProperty(t, i, a), - a - } - ; - Object.defineProperty(gr, "__esModule", { - value: !0 - }); - const ip = t - , rp = yc; - gc = gc([function(e) { - let t = e; - return "undefined" != typeof window && null != window.VTTCue && (t = window.VTTCue, - t.create = e.create, - t.fromJSON = e.fromJSON, - t.prototype.toJSON = e.prototype.toJSON), - t - } - ], gc = class { - constructor(e, t, i) { - this._id = "", - this._pauseOnExit = !1, - this._region = null, - this._vertical = "", - this._snapToLines = !0, - this._line = "auto", - this._lineAlign = "start", - this._position = "auto", - this._positionAlign = "auto", - this._size = 100, - this._align = "center", - this.hasBeenReset = !1, - this._startTime = e, - this._endTime = t, - this._text = i - } - get id() { - return this._id - } - set id(e) { - this._id = "" + e - } - get pauseOnExit() { - return this._pauseOnExit - } - set pauseOnExit(e) { - this._pauseOnExit = !!e - } - get startTime() { - return this._startTime - } - set startTime(e) { - if ("number" != typeof e) - throw new TypeError(`Start time must be set to a number: ${e}`); - this._startTime = e, - this.hasBeenReset = !0 - } - get endTime() { - return this._endTime - } - set endTime(e) { - if ("number" != typeof e) - throw new TypeError(`End time must be set to a number: ${e}`); - this._endTime = e, - this.hasBeenReset = !0 - } - get text() { - return this._text - } - set text(e) { - this._text = "" + e, - this.hasBeenReset = !0 - } - get region() { - return this._region - } - set region(e) { - this._region = e, - this.hasBeenReset = !0 - } - get vertical() { - return this._vertical - } - set vertical(e) { - if (!ip.isValidDirectionSetting(e)) - throw new SyntaxError(`An invalid or illegal string was specified for vertical: ${e}`); - this._vertical = e, - this.hasBeenReset = !0 - } - get snapToLines() { - return this._snapToLines - } - set snapToLines(e) { - this._snapToLines = !!e, - this.hasBeenReset = !0 - } - get line() { - return this._line - } - set line(e) { - if (!ip.isValidLineAndPositionSetting(e)) - throw new SyntaxError(`An invalid number or illegal string was specified for line: ${e}`); - this._line = e, - this.hasBeenReset = !0 - } - get lineAlign() { - return this._lineAlign - } - set lineAlign(e) { - if (!ip.isValidLineAlignSetting(e)) - throw new SyntaxError(`An invalid or illegal string was specified for lineAlign: ${e}`); - this._lineAlign = e, - this.hasBeenReset = !0 - } - get position() { - return this._position - } - set position(e) { - if (!ip.isValidLineAndPositionSetting(e)) - throw new Error(`Position must be between 0 and 100 or auto: ${e}`); - this._position = e, - this.hasBeenReset = !0 - } - get positionAlign() { - return this._positionAlign - } - set positionAlign(e) { - if (!ip.isValidPositionAlignSetting(e)) - throw new SyntaxError(`An invalid or illegal string was specified for positionAlign: ${e}`); - this._positionAlign = e, - this.hasBeenReset = !0 - } - get size() { - return this._size - } - set size(e) { - if (e < 0 || 100 < e) - throw new Error(`Size must be between 0 and 100: ${e}`); - this._size = e, - this.hasBeenReset = !0 - } - get align() { - return this._align - } - set align(e) { - if (!ip.isValidAlignSetting(e)) - throw new SyntaxError(`An invalid or illegal string was specified for align: ${e}`); - this._align = e, - this.hasBeenReset = !0 - } - getCueAsHTML() { - return rp.default.parseContent(window, this, {}) - } - static create(t) { - if (!t.hasOwnProperty("startTime") || !t.hasOwnProperty("endTime") || !t.hasOwnProperty("text")) - throw new Error("You must at least have start time, end time, and text."); - const i = new this(t.startTime,t.endTime,t.text); - return Object.keys(t).forEach(e=>{ - i.hasOwnProperty(e) && (i[e] = t[e]) - } - ), - i - } - static fromJSON(e) { - return this.create(JSON.parse(e)) - } - toJSON() { - const t = {}; - return Object.keys(this).forEach(e=>{ - this.hasOwnProperty(e) && "getCueAsHTML" !== e && "hasBeenReset" !== e && "displayState" !== e && (t[e] = this[e]) - } - ), - t - } - } - ); - gr.VTTCue = gc; - gc = {}, - e = e && e.__decorate || function(e, t, i, r) { - var n, s = arguments.length, a = s < 3 ? t : null === r ? r = Object.getOwnPropertyDescriptor(t, i) : r; - if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) - a = Reflect.decorate(e, t, i, r); - else - for (var o = e.length - 1; 0 <= o; o--) - (n = e[o]) && (a = (s < 3 ? n(a) : 3 < s ? n(t, i, a) : n(t, i)) || a); - return 3 < s && a && Object.defineProperty(t, i, a), - a - } - ; - Object.defineProperty(gc, "__esModule", { - value: !0 - }); - const np = t; - e = e([function(e) { - let t = e; - return "undefined" != typeof window && null != window.VTTRegion && (t = window.VTTRegion, - t.create = e.create, - t.fromJSON = e.fromJSON, - t.prototype.toJSON = e.prototype.toJSON), - t - } - ], e = class { - constructor() { - this._id = "", - this._lines = 3, - this._regionAnchorX = 0, - this._regionAnchorY = 100, - this._scroll = "", - this._viewportAnchorX = 0, - this._viewportAnchorY = 100, - this._width = 100 - } - get id() { - return this._id - } - set id(e) { - if ("string" != typeof e) - throw new Error("ID must be a string."); - this._id = e - } - get lines() { - return this._lines - } - set lines(e) { - if ("number" != typeof e) - throw new TypeError("Lines must be set to a number."); - this._lines = e - } - get regionAnchorX() { - return this._regionAnchorX - } - set regionAnchorX(e) { - if (!np.isValidPercentValue(e)) - throw new TypeError("RegionAnchorX must be between 0 and 100."); - this._regionAnchorX = e - } - get regionAnchorY() { - return this._regionAnchorY - } - set regionAnchorY(e) { - if (!np.isValidPercentValue(e)) - throw new TypeError("RegionAnchorY must be between 0 and 100."); - this._regionAnchorY = e - } - get scroll() { - return this._scroll - } - set scroll(e) { - if ("string" == typeof e) { - e = e.toLowerCase(); - if (np.isValidScrollSetting(e)) - return void (this._scroll = e) - } - throw new SyntaxError("An invalid or illegal string was specified.") - } - get viewportAnchorX() { - return this._viewportAnchorX - } - set viewportAnchorX(e) { - if (!np.isValidPercentValue(e)) - throw new TypeError("ViewportAnchorX must be between 0 and 100."); - this._viewportAnchorX = e - } - get viewportAnchorY() { - return this._viewportAnchorY - } - set viewportAnchorY(e) { - if (!np.isValidPercentValue(e)) - throw new TypeError("ViewportAnchorY must be between 0 and 100."); - this._viewportAnchorY = e - } - get width() { - return this._width - } - set width(e) { - if (!np.isValidPercentValue(e)) - throw new TypeError("Width must be between 0 and 100."); - this._lines = e - } - toJSON() { - const t = {}; - return Object.keys(this).forEach(e=>{ - this.hasOwnProperty(e) && (t[e] = this[e]) - } - ), - t - } - static create(t) { - const i = new this; - return Object.keys(t).forEach(e=>{ - i.hasOwnProperty(e) && (i[e] = t[e]) - } - ), - i - } - static fromJSON(e) { - return this.create(JSON.parse(e)) - } - } - ); - gc.VTTRegion = e, - Object.defineProperty(mu, "__esModule", { - value: !0 - }); - const sp = gr; - mu.VTTCue = sp.VTTCue; - const ap = gc; - mu.VTTRegion = ap.VTTRegion; - const op = yc; - class dp extends Error { - constructor(e, t) { - super(), - this.name = "ParsingError", - this.code = "number" == typeof e ? e : e.code, - t ? this.message = t : e instanceof dp && (this.message = e.message) - } - } - (mu.ParsingError = dp).Errors = { - BadSignature: new dp(0,"Malformed WebVTT signature."), - BadTimeStamp: new dp(1,"Malformed time stamp.") - }; - class lp { - constructor() { - this.values = {} - } - set(e, t) { - this.get(e) || "" === t || (this.values[e] = t) - } - get(e, t, i) { - return "object" == typeof t && "string" == typeof i ? this.has(e) ? this.values[e] : t[i] : this.has(e) ? this.values[e] : t - } - has(e) { - return e in this.values - } - alt(t, i, r) { - for (let e = 0; e < r.length; ++e) - if (i === r[e]) { - this.set(t, i); - break - } - } - integer(e, t) { - /^-?\d+$/.test(t) && this.set(e, parseInt(t, 10)) - } - percent(e, t) { - if (t.match(/^([\d]{1,3})(\.[\d]*)?%$/)) - try { - var i = parseFloat(t); - if (0 <= i && i <= 100) - return this.set(e, i), - !0 - } catch (e) { - return !1 - } - return !1 - } - } - class up { - constructor(e, t, i) { - this.window = e, - this.state = "INITIAL", - this.styleCollector = "", - this.buffer = "", - this.decoder = t || new TextDecoder("utf8"), - this.regionList = [], - this.onStylesParsedCallback = i, - this._styles = {} - } - static StringDecoder() { - return { - decode: e=>{ - if (!e) - return ""; - if ("string" != typeof e) - throw new Error("Error - expected string data."); - return decodeURIComponent(encodeURIComponent(e)) - } - } - } - reportOrThrowError(e) { - if (!(e instanceof dp && "function" == typeof this.onparsingerror)) - throw e; - this.onparsingerror(e) - } - parseOptions(e, t, i, r) { - e = r ? e.split(r) : [e]; - for (const n of e) - if ("string" == typeof n) { - const r = n.split(i); - 2 === r.length && t(r[0], r[1]) - } - } - parseCue(t, e, a) { - const i = t - , r = ()=>{ - var e = op.default.parseTimeStamp(t); - if (null === e) - throw new dp(dp.Errors.BadTimeStamp,"Malformed timestamp: " + i); - return t = t.replace(/^[^\sa-zA-Z-]+/, ""), - e - } - , n = ()=>{ - t = t.replace(/^\s+/, "") - } - ; - if (n(), - e.startTime = r(), - n(), - "--\x3e" !== t.substr(0, 3)) - throw new dp(dp.Errors.BadTimeStamp,`Malformed time stamp (time stamps must be separated by '--\x3e'): ${i}`); - t = t.substr(3), - n(), - e.endTime = r(), - n(), - ((e,t)=>{ - const s = new lp; - this.parseOptions(e, (t,i)=>{ - let e, r; - switch (t) { - case "region": - for (let e = a.length - 1; 0 <= e; e--) - if (a[e].id === i) { - s.set(t, a[e].region); - break - } - break; - case "vertical": - s.alt(t, i, ["rl", "lr"]); - break; - case "line": - e = i.split(","), - r = e[0], - s.integer(t, r), - s.percent(t, r) && s.set("snapToLines", !1), - s.alt(t, r, ["auto"]), - 2 === e.length && s.alt("lineAlign", e[1], ["start", "center", "end"]); - break; - case "position": - e = i.split(","), - s.percent(t, e[0]), - 2 === e.length && (n = ["line-left", "line-right", "center", "auto", "left", "start", "middle", "end", "right"], - s.alt("positionAlign", e[1], n)); - break; - case "size": - s.percent(t, i); - break; - case "align": - var n = ["start", "center", "end", "left", "right", "middle"]; - s.alt(t, i, n) - } - } - , /:/, /\s/), - t.region = s.get("region", null), - t.vertical = s.get("vertical", ""), - t.line = s.get("line", void 0 === t.line ? "auto" : t.line), - t.lineAlign = s.get("lineAlign", "start"), - t.snapToLines = s.get("snapToLines", !0), - t.size = s.get("size", 100); - e = s.get("align", "center"); - t.align = "middle" === e ? "center" : e, - t.position = s.get("position", "auto"); - e = s.get("positionAlign", { - start: "start", - left: "start", - center: "center", - right: "end", - end: "end" - }, t.align); - t.positionAlign = { - start: "start", - "line-left": "start", - left: "start", - center: "center", - middle: "center", - "line-right": "end", - right: "end", - end: "end" - }[e] - } - )(t, e) - } - parseRegion(e) { - const n = new lp; - if (this.parseOptions(e, (e,t)=>{ - switch (e) { - case "id": - n.set(e, t); - break; - case "width": - n.percent(e, t); - break; - case "lines": - n.integer(e, t); - break; - case "regionanchor": - case "viewportanchor": - { - var i = t.split(","); - if (2 !== i.length) - break; - const r = new lp; - if (r.percent("x", i[0]), - r.percent("y", i[1]), - !r.has("x") || !r.has("y")) - break; - n.set(e + "X", r.get("x")), - n.set(e + "Y", r.get("y")); - break - } - case "scroll": - n.alt(e, t, ["up"]) - } - } - , /=/, /\s/), - n.has("id")) { - const e = new ap.VTTRegion; - e.width = n.get("width", 100), - e.lines = n.get("lines", 3), - e.regionAnchorX = n.get("regionanchorX", 0), - e.regionAnchorY = n.get("regionanchorY", 100), - e.viewportAnchorX = n.get("viewportanchorX", 0), - e.viewportAnchorY = n.get("viewportanchorY", 100), - e.scroll = n.get("scroll", ""), - this.onregion && this.onregion(e), - this.regionList.push({ - id: n.get("id"), - region: e - }) - } - } - parseStyle(i) { - const e = i.split("}"); - e.pop(); - for (const i of e) { - let e = null - , t = null; - const r = i.split("{"); - r[0] && (e = r[0].trim()), - r[1] && (t = (e=>{ - const t = {} - , i = e.split(";"); - for (let e = 0; e < i.length; e++) - if (i[e].includes(":")) { - const r = i[e].split(":", 2) - , n = r[0].trim() - , s = r[1].trim(); - "" !== n && "" !== s && (t[n] = s) - } - return t - } - )(r[1])), - e && t && (this._styles[e] = t) - } - this.onStylesParsedCallback && this.onStylesParsedCallback(this._styles) - } - parseHeader(e) { - this.parseOptions(e, function(e, t) { - "Region" === e && this.parseRegion(t) - }, /:/) - } - parse(i) { - i && (this.buffer += this.decoder.decode(i, { - stream: !0 - })); - const r = ()=>{ - const e = this.buffer; - let t = 0; - let i = { - start: e.length, - length: 0 - }; - for (; t < e.length; ) { - const r = ((t,i)=>{ - const r = { - start: -1, - length: -1 - }; - if ("\r" === t[i]) - r.start = i, - r.length = 1; - else if ("\n" === t[i]) - r.start = i, - r.length = 1; - else if ("<" === t[i] && i + 1 < t.length && "b" === t[i + 1] && i + 2 < t.length && "r" === t[i + 2]) { - let e = i + 2; - for (; e < t.length && ">" !== t[e++]; ) - ; - r.start = i, - r.length = e - i - } - return r - } - )(e, t); - if (0 < r.length) { - i = r; - break - } - ++t - } - const r = e.substr(0, i.start); - return this.buffer = e.substr(i.start + i.length), - r - } - ; - try { - let e; - if ("INITIAL" === this.state) { - if (!/\r\n|\n/.test(this.buffer)) - return this; - e = r(); - var n = /^(ïÂģÂŋ)?WEBVTT([ \t].*)?$/.exec(e); - if (!n || !n[0]) - throw new dp(dp.Errors.BadSignature); - this.state = "HEADER" - } - let t = !1; - for (; this.buffer; ) { - if (!/\r\n|\n/.test(this.buffer)) - return this; - switch (t ? t = !1 : e = r(), - this.state) { - case "HEADER": - e.includes(":") ? this.parseHeader(e) : e || (this.state = "ID"); - continue; - case "NOTE": - e || (this.state = "ID"); - continue; - case "STYLE": - e ? this.styleCollector += e : (this.parseStyle(this.styleCollector), - this.state = "ID", - this.styleCollector = ""); - continue; - case "ID": - if (/^NOTE($|[ \t])/.test(e)) { - this.state = "NOTE"; - break - } - if (/^STYLE($|[ \t])/.test(e)) { - this.state = "STYLE"; - break - } - if (!e) - continue; - if (this.cue = new sp.VTTCue(0,0,""), - this.state = "CUE", - !e.includes("--\x3e")) { - this.cue.id = e; - continue - } - case "CUE": - try { - this.parseCue(e, this.cue, this.regionList) - } catch (i) { - this.reportOrThrowError(i), - this.cue = null, - this.state = "BADCUE"; - continue - } - this.state = "CUETEXT"; - continue; - case "CUETEXT": - { - const r = e.includes("--\x3e"); - if (!e || r) { - t = !0, - this.oncue && this.oncue(this.cue), - this.cue = null, - this.state = "ID"; - continue - } - this.cue.text && (this.cue.text += "\n"), - this.cue.text += e; - continue - } - case "BADCUE": - e || (this.state = "ID"); - continue - } - } - } catch (i) { - this.reportOrThrowError(i), - "CUETEXT" === this.state && this.cue && this.oncue && this.oncue(this.cue), - this.cue = null, - this.state = "INITIAL" === this.state ? "BADWEBVTT" : "BADCUE" - } - return this - } - flush() { - try { - if (this.buffer += this.decoder.decode(), - !this.cue && "HEADER" !== this.state || (this.buffer += "\n\n", - this.parse()), - "INITIAL" === this.state) - throw new dp(dp.Errors.BadSignature) - } catch (e) { - this.reportOrThrowError(e) - } - return this.onflush && this.onflush(), - this - } - styles() { - return this._styles - } - } - mu.default = up, - mu.WebVTTParser = up; - var cp, gc = {}; - Object.defineProperty(gc, "__esModule", { - value: !0 - }); - const hp = gr; - gc.VTTCue = hp.VTTCue; - const pp = yc - , fp = [/^(::cue\()(\..*)(\))/, /^(::cue\()(#.*)(\))/, /^(::cue\()(c|i|b|u|ruby|rt|v|lang)(\))/] - , mp = [[1470, 1470], [1472, 1472], [1475, 1475], [1478, 1478], [1488, 1514], [1520, 1524], [1544, 1544], [1547, 1547], [1549, 1549], [1563, 1563], [1566, 1610], [1645, 1647], [1649, 1749], [1765, 1766], [1774, 1775], [1786, 1805], [1807, 1808], [1810, 1839], [1869, 1957], [1969, 1969], [1984, 2026], [2036, 2037], [2042, 2042], [2048, 2069], [2074, 2074], [2084, 2084], [2088, 2088], [2096, 2110], [2112, 2136], [2142, 2142], [2208, 2208], [2210, 2220], [8207, 8207], [64285, 64285], [64287, 64296], [64298, 64310], [64312, 64316], [64318, 64318], [64320, 64321], [64323, 64324], [64326, 64449], [64467, 64829], [64848, 64911], [64914, 64967], [65008, 65020], [65136, 65140], [65142, 65276], [67584, 67589], [67592, 67592], [67594, 67637], [67639, 67640], [67644, 67644], [67647, 67669], [67671, 67679], [67840, 67867], [67872, 67897], [67903, 67903], [67968, 68023], [68030, 68031], [68096, 68096], [68112, 68115], [68117, 68119], [68121, 68147], [68160, 68167], [68176, 68184], [68192, 68223], [68352, 68405], [68416, 68437], [68440, 68466], [68472, 68479], [68608, 68680], [126464, 126467], [126469, 126495], [126497, 126498], [126500, 126500], [126503, 126503], [126505, 126514], [126516, 126519], [126521, 126521], [126523, 126523], [126530, 126530], [126535, 126535], [126537, 126537], [126539, 126539], [126541, 126543], [126545, 126546], [126548, 126548], [126551, 126551], [126553, 126553], [126555, 126555], [126557, 126557], [126559, 126559], [126561, 126562], [126564, 126564], [126567, 126570], [126572, 126578], [126580, 126583], [126585, 126588], [126590, 126590], [126592, 126601], [126603, 126619], [126625, 126627], [126629, 126633], [126635, 126651], [1114109, 1114109]]; - class gp { - applyStyles(e, t) { - t = t || this.div; - for (const i in e) - e.hasOwnProperty(i) && (t.style[i] = e[i]) - } - formatStyle(e, t) { - return 0 === e ? "0" : e + t - } - } - gc.StyleBox = gp; - class yp extends gp { - constructor(e, t, i, r, n) { - super(); - let s = { - textAlign: { - start: "left", - "line-left": "left", - left: "left", - center: "center", - middle: "center", - "line-right": "right", - right: "right", - end: "right" - }[(this.cue = t).positionAlign] || t.align, - whiteSpace: "pre-line", - position: "absolute" - }; - s.direction = this.determineBidi(this.cueDiv), - s.writingMode = this.directionSettingToWritingMode(t.vertical), - s.unicodeBidi = "plaintext", - this.div = e.document.createElement("div"), - this.applyStyles(s), - s = { - backgroundColor: r.backgroundColor, - display: "inline-block" - }, - this.parseOpacity(s.backgroundColor) && (s.padding = "5px", - s.borderRadius = "5px"), - this.backgroundDiv = e.document.createElement("div"), - this.applyStyles(s, this.backgroundDiv), - s = { - color: i.color, - backgroundColor: i.backgroundColor, - textShadow: i.textShadow, - fontSize: i.fontSize, - fontFamily: i.fontFamily, - position: "relative", - left: "0", - right: "0", - top: "0", - bottom: "0", - display: "inline-block", - textOrientation: "upright" - }, - s.writingMode = this.directionSettingToWritingMode(t.vertical), - s.unicodeBidi = "plaintext", - this.cueDiv = pp.default.parseContent(e, t, n), - this.applyStyles(s, this.cueDiv), - this.backgroundDiv.appendChild(this.cueDiv), - this.div.appendChild(this.backgroundDiv); - let a = 0; - if ("number" == typeof t.position) { - n = t.positionAlign || t.align; - if (n) - switch (n) { - case "start": - case "left": - a = t.position; - break; - case "center": - case "middle": - a = t.position - t.size / 2; - break; - case "end": - case "right": - a = t.position - t.size - } - } - "" === t.vertical ? this.applyStyles({ - left: this.formatStyle(a, "%"), - width: this.formatStyle(t.size, "%") - }) : this.applyStyles({ - top: this.formatStyle(a, "%"), - height: this.formatStyle(t.size, "%") - }) - } - determineBidi(e) { - let t = [] - , i = ""; - if (!e || !e.childNodes) - return "ltr"; - function n(t, i) { - for (let e = i.childNodes.length - 1; 0 <= e; e--) - t.push(i.childNodes[e]) - } - for (n(t, e); i = function e(t) { - if (!t || !t.length) - return null; - let i = t.pop() - , r = i.textContent || i.innerText; - if (r) { - const i = /^.*(\n|\r)/.exec(r); - return i ? i[t.length = 0] : r - } - return "ruby" === i.tagName ? e(t) : i.childNodes ? (n(t, i), - e(t)) : void 0 - }(t); ) - for (let e = 0; e < i.length; e++) - if (function(e, t) { - for (const i of t) - if (e >= i[0] && e <= i[1]) - return 1 - }(i.charCodeAt(e), mp)) - return "rtl"; - return "ltr" - } - parseOpacity(e) { - if (!e || "string" != typeof e) - return null; - e = (e = e.replace(/ /g, "").replace("rgba(", "").replace(")", "")).split(","); - return e && 4 <= e.length ? e[3] : null - } - directionSettingToWritingMode(e) { - return "" === e ? "horizontal-tb" : "lr" === e ? "vertical-lr" : "vertical-rl" - } - move(e) { - this.applyStyles({ - top: this.formatStyle(e.top, "px"), - bottom: this.formatStyle(e.bottom, "px"), - left: this.formatStyle(e.left, "px"), - right: this.formatStyle(e.right, "px"), - height: this.formatStyle(e.height, "px"), - width: this.formatStyle(e.width, "px") - }) - } - } - gc.CueStyleBox = yp; - class vp { - constructor(e) { - var t; - let i, r, n, s, a, o; - if (e instanceof yp && e.cue ? (t = e.cue) && "" !== t.vertical ? this.property = "width" : this.property = "height" : e instanceof vp && (this.property = e.property || "height"), - e instanceof yp && e.div) { - n = e.div.offsetHeight, - s = e.div.offsetWidth, - a = e.div.offsetTop; - const t = e.div.firstChild; - if (o = (t || e.div).getBoundingClientRect(), - i = o && o[this.property] || null, - t && t.firstChild) { - const e = t.firstChild; - e && "string" == typeof e.textContent && (r = i / this.calculateNewLines(e.textContent)) - } - } else - e instanceof vp && (o = e); - this.left = o.left, - this.right = o.right, - this.top = o.top || a, - this.height = o.height || n, - this.bottom = o.bottom || a + (o.height || n), - this.width = o.width || s, - this.lineHeight = null !== i ? i : o.lineHeight, - this.singleLineHeight = null !== r ? r : o.singleLineHeight, - this.singleLineHeight || (this.singleLineHeight = 41) - } - calculateNewLines(t) { - let i = 1; - for (let e = 0; e < t.length; e++) - "\n" === t[e] && i++; - return i - } - move(e, t) { - switch (t = void 0 !== t ? t : this.singleLineHeight, - e) { - case "+x": - this.left += t, - this.right += t; - break; - case "-x": - this.left -= t, - this.right -= t; - break; - case "+y": - this.top += t, - this.bottom += t; - break; - case "-y": - this.top -= t, - this.bottom -= t - } - } - overlaps(e) { - return this.left < e.right && this.right > e.left && this.top < e.bottom && this.bottom > e.top - } - overlapsAny(e) { - for (const t of e) - if (this.overlaps(t)) - return !0; - return !1 - } - within(e) { - return this.top >= e.top && this.bottom <= e.bottom && this.left >= e.left && this.right <= e.right - } - moveIfOutOfBounds(e, t) { - switch (t) { - case "+x": - this.left < e.left && (this.left = e.left, - this.right = this.left + this.width); - break; - case "-x": - this.right > e.right && (this.right = e.right, - this.left = this.right - this.width); - break; - case "+y": - this.top < e.top && (this.top = e.top, - this.bottom = this.top + this.height); - break; - case "-y": - this.bottom > e.bottom && (this.bottom = e.bottom, - this.top = this.bottom - this.height) - } - } - toCSSCompatValues(e) { - return { - top: this.top - e.top, - bottom: e.bottom - this.bottom, - left: this.left - e.left, - right: e.right - this.right, - height: this.height, - width: this.width - } - } - static getSimpleBoxPosition(e) { - let t = null; - e instanceof gp && e.div ? t = e.div : e instanceof HTMLElement && (t = e); - let i = t.offsetHeight || 0 - , r = t.offsetWidth || 0 - , n = t.offsetTop || 0 - , s = n + i - , a = t.getBoundingClientRect(); - var {left: o, right: e} = a; - return a.top && (n = a.top), - a.height && (i = a.height), - a.width && (r = a.width), - a.bottom && (s = a.bottom), - { - left: o, - right: e, - top: n, - height: i, - bottom: s, - width: r - } - } - static getBoxPosition(r, n) { - if (r && 0 < r.length) { - let t = 0 - , i = r[0][n]; - for (let e = 0; e < r.length; e++) - n in ["top", "right"] ? r[e][n] > i && (t = e, - i = r[e][n]) : n in ["bottom", "left"] && r[e][n] < i && (t = e, - i = r[e][n]); - return r[t] - } - return null - } - static moveToMinimumDistancePlacement(e, t, i) { - "height" === e.property ? "+y" === t ? (e.top = i.topMostBoxPosition.bottom + 0, - e.bottom = e.top + e.height) : "-y" === t && (e.bottom = +i.bottomMostBoxPosition.top, - e.top = e.bottom - e.height) : "width" === e.property && ("+x" === t ? (e.left = i.rightMostBoxPosition.right + 0, - e.right = e.left + e.width) : "-x" === t && (e.right = +i.leftMostBoxPosition.left, - e.left = e.right - e.width)) - } - static moveBoxToLinePosition(e, a, o) { - var n = e.cue; - let i, r = new vp(e), s = function() { - if ("number" == typeof n.line && (n.snapToLines || 0 <= n.line && n.line <= 100)) - return n.line; - if (!n.track || !n.track.textTrackList || !n.track.textTrackList.mediaElement) - return -1; - let t = 0; - var i = n.track - , r = i.textTrackList; - for (let e = 0; e < r.length && r[e] !== i; e++) - "showing" === r[e].mode && t++; - return -1 * ++t - }(), d = []; - if (n.snapToLines) { - let t = 0; - switch (n.vertical) { - case "": - d = ["+y", "-y"], - i = "height"; - break; - case "rl": - d = ["+x", "-x"], - i = "width"; - break; - case "lr": - d = ["-x", "+x"], - i = "width" - } - const o = r.lineHeight - , l = a[i] + o - , u = d[0]; - if (s < 0) { - let e = 0; - switch (n.vertical) { - case "": - e = a.height - o - .05 * a.height; - break; - case "rl": - case "lr": - e = -a.width + o + .05 * a.width - } - t = e, - d = d.reverse() - } else { - switch (n.vertical) { - case "": - t = o * Math.round(s); - break; - case "rl": - t = a.width - o * Math.round(s); - break; - case "lr": - t = o * Math.round(s) - } - Math.abs(t) > l && (t = t < 0 ? -1 : 1, - t *= Math.ceil(l / o) * o) - } - r.move(u, t) - } else { - const o = "" === n.vertical ? a.height : a.width - , i = r.lineHeight / o * 100; - switch (n.lineAlign) { - case "center": - s -= i / 2; - break; - case "end": - s -= i - } - switch (n.vertical) { - case "": - e.applyStyles({ - top: e.formatStyle(s, "%") - }); - break; - case "rl": - e.applyStyles({ - right: e.formatStyle(s, "%") - }); - break; - case "lr": - e.applyStyles({ - left: e.formatStyle(s, "%") - }) - } - d = ["+y", "-y", "+x", "-x"], - "+y" === n.axis ? d = ["+y", "-y", "+x", "-x"] : "-y" === n.axis && (d = ["-y", "+y", "+x", "-x"]), - r = new vp(e) - } - const l = function(r, n) { - let s; - for (let i = 0; i < n.length; i++) { - r.moveIfOutOfBounds(a, n[i]); - let e = 0 - , t = !1; - for (; r.overlapsAny(o) && !(9 < e); ) - t ? r.move(n[i]) : (o && 0 < o.length && (s = s || { - topMostBoxPosition: vp.getBoxPosition(o, "top"), - bottomMostBoxPosition: vp.getBoxPosition(o, "bottom"), - leftMostBoxPosition: vp.getBoxPosition(o, "left"), - rightMostBoxPosition: vp.getBoxPosition(o, "right") - }, - vp.moveToMinimumDistancePlacement(r, n[i], s)), - t = !0), - e++ - } - return r - }(r, d); - e.move(l.toCSSCompatValues(a)) - } - } - gc.BoxPosition = vp; - class Sp { - constructor(e, t, i=!0) { - if (!e) - return null; - this.window = e, - this.overlay = t, - this.loggingEnabled = i, - this.foregroundStyleOptions = { - fontFamily: "Helvetica", - fontSize: "36px", - color: "rgba(255, 255, 255, 1)", - textShadow: "", - backgroundColor: "rgba(0, 0, 0, 0)" - }, - this.backgroundStyleOptions = { - backgroundColor: "rgba(0, 0, 0, 0.5)" - }, - this.globalStyleCollection = {}; - const r = e.document.createElement("div"); - r.style.position = "absolute", - r.style.left = "0", - r.style.right = "0", - r.style.top = "0", - r.style.bottom = "0", - r.style.margin = "1.5%", - this.paddedOverlay = r, - t.appendChild(this.paddedOverlay), - this.initSubtitleCSS() - } - initSubtitleCSS() { - var e = [new hp.VTTCue(0,0,"String to init CSS - Won't be visible to user")]; - this.paddedOverlay.style.opacity = "0", - this.processCues(e), - this.processCues([]), - this.paddedOverlay.style.opacity = "1" - } - convertCueToDOMTree(e) { - return e ? pp.default.parseContent(this.window, e, this.globalStyleCollection) : null - } - setStyles(i) { - function r(e, t, i) { - for (const r in t) - t.hasOwnProperty(r) && (!0 === i && void 0 !== e[r] || !1 === i) && (e[r] = t[r]) - } - for (const a in i) { - let t = !1 - , e = null; - "::cue" === a ? (e = this.foregroundStyleOptions, - t = !0) : "::-webkit-media-text-track-display" === a && (e = this.backgroundStyleOptions, - t = !0); - var n = i[a]; - if (!0 === t) - r(e, n, t); - else - for (let e = 0; e < fp.length; e++) { - var s = fp[e].exec(a); - if (s && 4 === s.length) { - const i = s[2] - , o = {}; - r(o, n, t), - this.globalStyleCollection[i] = o - } - } - } - this.initSubtitleCSS(), - this.loggingEnabled && (console.log("WebVTTRenderer setStyles foregroundStyleOptions: " + JSON.stringify(this.foregroundStyleOptions)), - console.log("WebVTTRenderer setStyles backgroundStyleOptions: " + JSON.stringify(this.backgroundStyleOptions)), - console.log("WebVTTRenderer setStyles globalStyleCollection: " + JSON.stringify(this.globalStyleCollection))) - } - processCues(r) { - if (r) { - for (; this.paddedOverlay.firstChild; ) - this.paddedOverlay.removeChild(this.paddedOverlay.firstChild); - if (function(t) { - for (let e = 0; e < t.length; e++) - if (t[e].hasBeenReset || !t[e].displayState) - return 1 - }(r)) { - const n = [] - , s = vp.getSimpleBoxPosition(this.paddedOverlay); - 1 < r.length && (r = function(t) { - const i = []; - let r = 0; - for (let e = 0; e < t.length; e++) { - var n = t[e]; - if ("number" != typeof n.line) - return t; - r += n.line, - i.push(n) - } - return r /= t.length, - 50 < r ? (i.forEach(function(e) { - e.axis = "-y" - }), - i.sort((e,t)=>t.line - e.line)) : (i.forEach(function(e) { - e.axis = "+y" - }), - i.sort((e,t)=>e.line - t.line)), - i - }(r)); - for (let i = 0; i < r.length; i++) { - let e = r[i] - , t = new yp(this.window,e,this.foregroundStyleOptions,this.backgroundStyleOptions,this.globalStyleCollection); - this.paddedOverlay.appendChild(t.div), - vp.moveBoxToLinePosition(t, s, n), - e.displayState = t.div, - n.push(vp.getSimpleBoxPosition(t)) - } - } else - for (let e = 0; e < r.length; e++) - this.paddedOverlay.appendChild(r[e].displayState) - } - } - setSize(e, t) { - e && (this.overlay.style.width = e + "px"), - t && (this.overlay.style.height = t + "px") - } - getOverlay() { - return this.overlay - } - } - function bp(e) { - for (var t in e) - cp.hasOwnProperty(t) || (cp[t] = e[t]) - } - gc.default = Sp, - gc.WebVTTRenderer = Sp, - cp = zh, - Object.defineProperty(cp, "__esModule", { - value: !0 - }), - bp(mu), - bp(gc); - function Tp(e, t, i) { - return e.substr(i || 0, t.length) === t - } - function Ep(e) { - let t = 5381 - , i = e.length; - for (; i; ) - t = 33 * t ^ e.charCodeAt(--i); - return (t >>> 0).toString() - } - function Ip(e) { - var t = Math.floor(e) - , i = t + .5 - , r = t + 1; - return i <= e ? r - e <= e - i ? r : i : i - e <= e - t ? i : t - } - function wp(e, t=0, i=8589934592) { - if (!Number.isFinite(t)) - return e; - var r = i / 2 - , n = Math.abs(e - t) % i; - return t + (t < e ? -1 : 1) * (r < n ? i - n : -n) - } - var Ap, Op, kp, Cp = function(e, t, i, r, n, s, a, o) { - const d = O.utf8arrayToStr(new Uint8Array(e)).trim().replace(/\r\n|\n\r|\n|\r/g, "\n").split("\n") - , l = { - baseTime: Math.floor(9e4 * t.baseTime / t.timescale), - timescale: 9e4 - }; - let u = 0 - , c = 0; - const h = []; - let p = null - , f = !0; - const m = new zh.WebVTTParser(window,zh.WebVTTParser.StringDecoder(),a); - m.oncue = function(e) { - var t = S({ - baseTime: wp(wp(u) - l.baseTime, 9e4 * i), - timescale: 9e4 - }); - e.startTime = wp(e.startTime + t - c, 0, 95443.7176888889), - e.endTime = wp(e.endTime + t - c, 0, 95443.7176888889), - e.id = Ep(Ip(e.startTime).toString()) + Ep(Ip(e.endTime - e.startTime).toString()) + Ep(e.text), - e.text = decodeURIComponent(encodeURIComponent(e.text)), - 0 < e.endTime && h.push(e) - } - , - m.onparsingerror = function(e) { - p = e - } - , - m.onflush = function() { - p && s ? s(p) : n(h) - } - , - d.forEach(a=>f && Tp(a, "X-TIMESTAMP-MAP=") ? (f = !1, - void a.substr(16).split(",").forEach(e=>{ - if (Tp(e, "LOCAL:")) { - let t; - try { - t = (i = e.substr(6), - r = parseInt(i.substr(-3)), - n = parseInt(i.substr(-6, 2)), - s = parseInt(i.substr(-9, 2)), - i = 9 < i.length ? parseInt(i.substr(0, i.indexOf(":"))) : 0, - ne(r) && ne(n) && ne(s) && ne(i) ? (r += 1e3 * n, - r += 6e4 * s, - r += 36e5 * i) : -1) - } catch (e) { - t = -1 - } - -1 !== t ? c = t / 1e3 : p = new Error(`Malformed X-TIMESTAMP-MAP: ${a}`) - } else - Tp(e, "MPEGTS:") && (u = parseInt(e.substr(7))); - var i, r, n, s - } - )) : void m.parse(a + "\n")), - m.flush() - }, Dp = { - newCue: function(e, t, i, r, n) { - let s, a, o, d, l; - var u, c, h = { - foreground: !1, - background: !1, - italics: !1, - underline: !1, - flash: !1, - styleStack: [] - }; - for ([u,c] of r.rows.entries()) - if (a = !0, - o = 0, - d = "", - !c.isEmpty()) { - for (let e = 0; e < c.chars.length; e++) - c.chars[e].uchar.match(/\s/) && a ? o++ : (d += this.getFormattedChar(c.chars[e], h), - a = !1); - (c.cueStartTime = t) === i && (i += 1e-4), - d = d.trim().replace(//gi, "\n"), - d += this.closeStyles(h), - s = new zh.VTTCue(t,i,d), - 16 <= o ? o-- : o++, - l = !navigator.userAgent.match(/Firefox\//) && 7 < u ? u : u + 1, - s.snapToLines = !1, - s.line = 10 + 5.33 * l, - s.align = "left", - s.position = this.getPosition(o, n), - e.addCue(s) - } - }, - getPosition: function(e, t) { - let i = 1.3333333333333333; - t && t.offsetWidth && t.offsetHeight && 1.6 <= t.offsetWidth / t.offsetHeight && (i = 1.7777777777777777); - let r = 10 + e / 32 * 80 - , n = 10 - , s = 90; - return 1.7777777777777777 === i && (r = 12.5 + .75 * r, - n = 20, - s = 80), - Math.max(n, Math.min(s, r + (navigator.userAgent.match(/Firefox\//) ? 50 : 0))) - }, - getRootStyleTag: function(e) { - var t = e[0]; - return "c" === t ? t : e - }, - closeStyles: function(t) { - let i = ""; - for (let e = t.styleStack.length - 1; 0 <= e; --e) - i += "", - t.styleStack.pop(); - return i - }, - beginStyleAndBalance: function(e, t) { - let i = ""; - return "c" === t[0] && (i += this.closeStyleAndBalance(e, "c")), - i += "<" + t + ">", - e.styleStack.push(t), - i - }, - closeStyleAndBalance: function(t, i) { - var r = t.styleStack.length; - let n = 0 - , s = ""; - for (let e = r - 1; 0 <= e; --e) { - var a = t.styleStack[e] - , o = this.getRootStyleTag(a); - if (i[0] === a[0]) { - s += "", - t.styleStack.splice(r - 1 - n); - break - } - "c" === o[0] ? (t.background = "", - t.foreground = "", - t.flash = !1, - s += "") : "u" === o[0] ? (t.underline = !1, - s += "") : "i" === o[0] && (t.italics = !1, - s += ""), - n++ - } - return s - }, - getFormattedChar: function(e, t) { - let i = "" - , r = e.uchar - , n = ""; - var s = e.penState.foreground !== t.foreground - , a = e.penState.background !== t.background - , o = e.penState.flash !== t.flash; - return (s || a || o) && (n = "." + e.penState.foreground, - n += ".bg_" + e.penState.background, - e.penState.flash && o && (n += ".blink"), - e.penState.foreground || e.penState.background || e.penState.blink ? i += this.beginStyleAndBalance(t, "c" + n) : i += this.closeStyleAndBalance(t, "c"), - s && (t.foreground = e.penState.foreground), - a && (t.background = e.penState.background), - o && (t.flash = e.penState.flash)), - e.penState.underline !== t.underline && (i += e.penState.underline ? this.beginStyleAndBalance(t, "u") : this.closeStyleAndBalance(t, "u"), - t.underline = e.penState.underline), - e.penState.italics !== t.italics && (i += e.penState.italics ? this.beginStyleAndBalance(t, "i") : this.closeStyleAndBalance(t, "i"), - t.italics = e.penState.italics), - i + r - } - }; - (gc = Ap = Ap || {}).CloseEnough = "CloseEnough", - gc.TooFar = "TooFar", - gc.Unknown = "Unknown"; - const Mp = e=>"cc1" === e || "cc2" === e; - function Pp(t) { - const i = []; - for (let e = 0; e < t.length; e++) { - var r = t[e]; - ("captions" === r.kind || "subtitles" === r.kind || "metadata" === r.kind && r.customTextTrackCueRenderer) && i.push(r) - } - return i - } - function xp(e) { - if (e && e.cues) - for (; 0 < e.cues.length; ) - e.removeCue(e.cues[0]) - } - class Rp extends Ut { - constructor(e, t, i, r) { - super(e=>{ - const t = wc(this.hls, this); - if (e.add(t.event(P.INLINE_STYLES_PARSED, this.onInlineStylesParsed).pipe($s(()=>this.destroy())).subscribe()), - e.add(vn(0, this.config.trottleCheckInterval).pipe(Ra(()=>(this.checkReadyToLoadNextSubtitleFragment(), - Ul))).subscribe()), - this.mediaSink.textTracks && "onchange"in this.mediaSink.textTracks) { - const t = wc(this.mediaSink.textTracks, this); - e.add(t.event("change", this._onTextTracksChanged).subscribe()) - } else - e.add(vn(0, 500).pipe(Ra(()=>(this._onTextTracksChanged(), - Ul))).subscribe()) - } - ), - this.config = t, - this.hls = i, - this.logger = r.child({ - name: "legible" - }), - this.mediaSink = e, - this.enableCaption = !0, - this.Cues = Dp, - this.tracks = [], - this.cueRanges = [], - this.channelToTrackMap = {}, - this.htmlTextTrackMap = new Map, - this.lastCueEndTime = 0, - this.gotTracks = !1, - this.tryAgain$ = new gi(!0), - this.needNextSubtitle$ = new gi(!0) - } - destroy() { - xp(this.textTrack1), - xp(this.textTrack2), - this.mediaSink = void 0, - this.nativeSubtitleTrackChange$ = void 0 - } - convertCuesIntoSubtitleFragInfo(t) { - const i = {}; - if (null != t && 0 < t.length) - for (let e = 0; e < t.length; e++) { - var r = t[e]; - if (ne(r.fragSN)) { - const n = i[r.fragSN]; - n ? (n.count++, - n.startTime = Math.min(r.startTime, n.startTime), - n.endTime = Math.max(r.endTime, n.endTime)) : i[r.fragSN] = { - count: 1, - startTime: r.startTime, - endTime: r.endTime - } - } - } - return i - } - checkReadyToLoadNextSubtitleFragment() { - let e = !1; - this.mediaSink.mediaQuery.currentTime >= this.lastCueEndTime - this.config.subtitleLeadTime && (e = !0), - this.needNextSubtitle$.next(e) - } - checkReadyToLoadNextSubtitleFragment$(e, t) { - return e.mediaSeqNum === (null === (t = t[0]) || void 0 === t ? void 0 : t.mediaSeqNum) ? Bi(!0) : (this.checkReadyToLoadNextSubtitleFragment(), - this.needNextSubtitle$) - } - getNextFragment(e, t) { - t = t.mediaSeqNum + 1; - return t < e.fragments.length ? e.fragments[t - e.startSN] : null - } - calculateFragInfoMap(e, t, i, r) { - var n = this.convertCuesIntoSubtitleFragInfo(t); - let s = { - len: 0, - start: e, - end: e - } - , a = e - , o = e - , d = null - , l = null; - for (const t in n) - if (Object.prototype.hasOwnProperty.call(n, t)) { - var u = Number(t); - if (ne(u)) { - var c = n[u]; - if (this.isFragmentComplete(u, c.count, i)) - if (u === r.startSN && e < c.startTime && (a = o = s.start = s.end = e = c.startTime), - e >= c.startTime && (a === e || ne(d) && 1 < u - d) && (a = o = c.startTime), - e >= c.startTime) - o = c.endTime, - d = u; - else { - if (!ne(d) || u - d != 1) { - l = u; - break - } - o = c.endTime, - d = u - } - } else - this.logger.warn(`$fragInfoMap has invalid key ${u}`) - } - return s = { - len: o - a, - start: a, - end: o - }, - { - fragInfoMap: n, - bufferInfo: s, - prevFragSN: d, - nextFragSN: l - } - } - findFrags$(t, i) { - return this.tryAgain$.pipe(Hi(Zi), Ra(()=>{ - var e = this.findFragmentsForPosition(this.mediaSink.mediaQuery.currentTime, i, t); - return e.foundFrags ? (this.lastCueEndTime = 0, - this.needNextSubtitle$.next(!0), - Bi(e)) : Ti - } - )) - } - reviewParsedFrag(e, i, r) { - var n = e.frag - , s = e.cueRange - , t = i.subtitleBufferInfo - , a = i.subtitleParsedInfo - , o = this.mediaSink.mediaQuery.currentTime - , e = i.foundFrags; - let d = !0; - if (n.mediaSeqNum === e[0].mediaSeqNum) { - if (!i.timelineEstablished) - return Ap.TooFar; - if (!s) - return this.logger.warn(`[subtitle] 1st frag sn ${n.mediaSeqNum} has no cue; details ${r.fragments.length} frags`), - Ap.Unknown; - if (s.startTime < o) { - const l = r.fragments - , i = n.mediaSeqNum - r.startSN; - let e = i - , t = s.startTime; - for (; e < l.length && (t += l[e].duration, - !(t >= o)); ++e) - ; - d = e - i + 1 <= this.config.earlyFragTolerance - } else if (s.startTime > o && n.mediaSeqNum !== r.startSN) { - const l = s.startTime - o - , i = t.prevFragSN; - d = n.mediaSeqNum === i + 1 && (null === (t = t.fragInfoMap[i]) || void 0 === t ? void 0 : t.count) === (null === (a = a[i]) || void 0 === a ? void 0 : a.count) || l <= this.config.lateTolerance - } - } - return d ? Ap.CloseEnough : Ap.TooFar - } - isFragmentComplete(e, t, i) { - e = i ? i[e] : null; - return (null == e ? void 0 : e.count) === t - } - getEarlierFragmentInSameDisco(e, t, i) { - var r = t.mediaSeqNum - e.startSN - 1; - if (r < 0 || r > e.fragments.length - 1) - return this.logger.error(`[subtitle] getEarlierFragmentInSameDisco index ${r} out of range`), - t; - r = e.fragments[r]; - return r && r.discoSeqNum === t.discoSeqNum && !i[t.mediaSeqNum] ? r : t - } - inferSubtitleFragmentForPosition(i, r, t, n, s) { - let a, o, e, d, l; - if (ne(n.prevFragSN) && (o = n.prevFragSN - s.startSN, - e = t[n.prevFragSN]), - ne(n.nextFragSN) && (d = n.nextFragSN - s.startSN, - l = t[n.nextFragSN]), - ne(o) && 0 <= o && o < s.fragments.length && e) { - let t = e.startTime; - const n = ne(d) ? d : s.fragments.length; - for (let e = o; e < n; ++e) { - const d = s.fragments[e]; - if (!ne(r) || d.discoSeqNum === r) { - if (e === n - 1) { - a = { - foundFrag: d, - timelineEstablished: !0 - }; - break - } - if (t + d.duration > i && e > o) { - a = { - foundFrag: d, - timelineEstablished: !0 - }; - break - } - t += d.duration - } - } - } else if (ne(d) && 0 <= d && d < s.fragments.length && l) { - let t = l.startTime; - for (let e = d - 1; 0 <= e; --e) { - const o = s.fragments[e]; - if (!ne(r) || o.discoSeqNum === r) { - if (t <= i) { - a = { - foundFrag: o, - timelineEstablished: !0 - }; - break - } - t -= o.duration - } - } - } else - for (let e = 0; e < s.fragments.length; ++e) { - const t = s.fragments[e]; - if (ne(r) && t.discoSeqNum === r) { - a = { - foundFrag: t, - timelineEstablished: !1 - }; - break - } - } - return a - } - generateFragmentBatch(t, i, e, r, n, s) { - var a; - const o = [] - , d = null == e ? void 0 : e.foundFrag; - if (!d) - return { - foundFrags: void 0, - subtitleParsedInfo: void 0, - subtitleBufferInfo: void 0, - timelineEstablished: null == e ? void 0 : e.timelineEstablished - }; - for (let e = d ? d.mediaSeqNum - s.startSN : s.fragments.length; e < s.fragments.length && o.length < t; ++e) { - const t = s.fragments[e]; - if (t.discoSeqNum === i) { - const d = null === (a = n.fragInfoMap[t.mediaSeqNum]) || void 0 === a ? void 0 : a.count; - this.isFragmentComplete(t.mediaSeqNum, null != d ? d : 0, r) || o.push(t) - } - } - return { - foundFrags: o, - subtitleParsedInfo: r, - subtitleBufferInfo: n, - timelineEstablished: null == e ? void 0 : e.timelineEstablished - } - } - findFragmentsForPosition(e, t, i) { - var r = this.mediaSink.mediaQuery.getParsedSubtitleRecordsForMediaOption(this.selectedTrack.persistentID) - , n = this.getCuesOfEnabledTrack(this.selectedMediaOption.mediaOptionId, !1) - , s = this.calculateFragInfoMap(e, n, r, i) - , n = s.bufferInfo - , n = Math.max(e, n.end) - , n = this.inferSubtitleFragmentForPosition(n, t, r, s, i); - return this.generateFragmentBatch(1 / 0, t, n, r, s, i) - } - get selectedMediaOption() { - return this.selectedTrack || this._disabledMediaOption - } - set selectedMediaOption(e) { - this.selectedTrack = "groupId"in e ? e : void 0 - } - get selectedTrack() { - return this._selectedMediaOption - } - set selectedTrack(e) { - e !== this._selectedMediaOption && (this._selectedMediaOption = e, - this.updateTextTrackState()) - } - getTrack(t) { - return this._availableMediaOptions.find(e=>e.mediaOptionId === t) - } - updateTextTrackState() { - if (this.mediaSink.textTracks) { - const i = this.selectedTrack ? this.getExistingHTMLTextTrack(this.selectedTrack) : void 0 - , r = Pp(this.mediaSink.textTracks); - for (let e = 0; e < r.length; e++) { - var t = r[e]; - t === i && "showing" !== r[e].mode ? r[e].mode = "showing" : t !== i && "hidden" !== r[e].mode && (r[e].mode = "hidden") - } - } - } - mapHTMLTextTrackIndexToMediaOptionId(e) { - const i = this.mediaSink.textTracks[e]; - let r; - return this.htmlTextTrackMap.forEach((e,t)=>{ - i === e && (r = t) - } - ), - r - } - get mediaSelectionOptions() { - return this._availableMediaOptions - } - _makeDisableOption(e) { - return { - itemId: e.itemId, - mediaOptionType: e.mediaOptionType, - mediaOptionId: "Nah" - } - } - _onTextTracksChanged() { - if (this.mediaSink) { - let t, i = !1; - const r = Pp(this.mediaSink.textTracks); - for (let e = 0; e < r.length; e++) - r[e].seen ? "showing" === r[e].mode && (t = r[e].persistentId) : (r[e].seen = !0, - i = !0); - if (!i) { - const e = this.selectedTrack; - if ((null == e ? void 0 : e.persistentID) !== t) { - const e = this.mediaSelectionOptions.find(function(e) { - return e.persistentID === t - }); - this.nativeSubtitleTrackChange$.next(e || this._disabledMediaOption) - } - } - } - } - addCues(e, t, i, r) { - const n = this.cueRanges; - let s = !1; - for (let e = n.length; e--; ) { - const r = n[e] - , l = (a = r[0], - o = r[1], - d = t, - Math.min(o, i) - Math.max(a, d)); - if (0 <= l && (r[0] = Math.min(r[0], t), - r[1] = Math.max(r[1], i), - s = !0, - .5 < l / (i - t))) - return - } - var a, o, d; - s || n.push([t, i]), - this.Cues.newCue(this.channelToTrackMap[e], t, i, r, this.mediaSink) - } - getExistingHTMLTextTrackWithChannelNumber(t) { - var i = this.mediaSink; - if (i) - for (let e = 0; e < i.textTracks.length; e++) { - var r = i.textTracks[e] - , n = "cc" + t; - if (Mp(n) && !0 === r[n]) - return r - } - return null - } - sendAddTrackEvent(e, t) { - let i = null; - try { - i = new window.Event("addtrack") - } catch (e) { - i = document.createEvent("Event"), - i.initEvent("addtrack", !1, !1) - } - i.track = e, - t.dispatchEvent(i) - } - createHTMLCaptionsTrackGuts(e, t, i, r) { - var n = "cc" + e; - if (!this.channelToTrackMap[n]) { - e = this.getExistingHTMLTextTrackWithChannelNumber(e); - if (e) - this.channelToTrackMap[n] = e, - xp(this.channelToTrackMap[n]), - this.sendAddTrackEvent(this.channelToTrackMap[n], this.mediaSink); - else { - const s = this.createHTMLTextTrackGuts("captions", t, i, r); - s && Mp(n) && (s[n] = !0, - this.channelToTrackMap[n] = s) - } - } - return this.channelToTrackMap[n] - } - createHTMLCaptionsTrack(e) { - return this.createHTMLCaptionsTrackGuts(e, this.config[1 === e ? "captionsTextTrack1Label" : "captionsTextTrack2Label"], this.config.captionsTextTrack1LanguageCode, !1) - } - getExistingHTMLTextTrack(e) { - return this.config.condenseSubtitleTrack ? this.htmlTextTrackMap.get(e.persistentID) : this.htmlTextTrackMap.get(e.id) - } - getExistingHTMLTextTrackWithSubtitleTrackId(t) { - var e = this._availableMediaOptions.find(e=>e.id === t); - return e ? this.getExistingHTMLTextTrack(e) : void 0 - } - getExistingHTMLTextTrackIndex(e) { - var t = this.getExistingHTMLTextTrack(e) - , i = this.mediaSink.textTracks; - let r = -1; - for (let e = 0; e < i.length; ++e) - if (i[e] === t) { - r = e; - break - } - return r - } - setExistingHTMLTextTrack(e, t) { - return t.persistentId = e.persistentID, - this.config.condenseSubtitleTrack ? this.htmlTextTrackMap.set(e.persistentID, t) : this.htmlTextTrackMap.set(e.id, t) - } - createHTMLTextTrack(t) { - let i = this.getExistingHTMLTextTrack(t); - if (!i) { - if ("sbtl" === t.mediaType) - i = this.createHTMLTextTrackGuts("subtitles", t.name, t.lang, t.forced); - else { - let e = 1; - t.inStreamID && (e = Number(t.inStreamID.substring(2))), - i = this.createHTMLCaptionsTrackGuts(e, t.name, t.lang, !1) - } - i ? this.setExistingHTMLTextTrack(t, i) : this.logger.error(`failed to create HTML text track for track ${t.id}: persistent id ${t.persistentID} name ${t.name} lang ${t.lang} inStreamID ${t.inStreamID}`) - } - return i - } - createHTMLTextTrackGuts(t, i, r, e) { - const n = this.mediaSink; - if (n) { - let e = !1; - "metadata" !== t && this.config.customTextTrackCueRenderer && (e = !0, - t = "metadata"); - const s = n.addTextTrack(t, i, r); - return e && (s.customTextTrackCueRenderer = !0), - s - } - } - resetLoadSource() { - this.resetTracks() - } - resetTracks() { - this._cleanTracks(), - this.cueRanges = [] - } - _cleanTracks() { - var e = this.mediaSink; - if (e) { - var t = e.textTracks; - if (t) - for (let e = 0; e < t.length; e++) - xp(t[e]) - } - } - getCuesOfEnabledTrack(e, t=!1) { - let i = []; - if (t) { - const t = this._getCuesOfEnabledTrack(e); - for (let e = 0; e < t.length; e++) { - var r = t[e]; - Boolean(r.webVTTCue) && i.push(r) - } - } else - i = this._getCuesOfEnabledTrack(e); - return i - } - _getCuesOfEnabledTrack(e) { - e = this.getTrack(e), - e = this.config.condenseSubtitleTrack ? null == e ? void 0 : e.persistentID : null == e ? void 0 : e.id, - e = this.htmlTextTrackMap.get(e); - return e && e.cues ? Array.from(e.cues) : [] - } - attachSubtitleTracks() { - this.gotTracks && this.tracks.forEach(e=>{ - this.createHTMLTextTrack(e) - } - ) - } - attachId3Tracks() { - this.id3Track = this.mediaSink.addTextTrack("metadata", "id3"), - this.id3Track.mode = "hidden" - } - setTracks(e, t, i) { - this._cleanTracks(), - this.htmlTextTrackMap = new Map, - this.cueRanges = [], - this.config.enableWebVTT && (this.tracks = e || []), - this.gotTracks = !0, - this._availableMediaOptions = e, - this._disabledMediaOption = i, - this.attachSubtitleTracks(), - this.attachId3Tracks(), - this.selectedTrack = t, - this.nativeSubtitleTrackChange$ = new zt, - this.mediaSink.textTracksCreated = !0 - } - onInlineStylesParsed(e) {} - processSubtitleFrag(e, t, i, r) { - var n = new Uint8Array(r) - , e = this.getExistingHTMLTextTrackIndex(e); - if (t && r.byteLength) { - const s = this._parseVTTs(e, t, i, n); - return s && (this.lastCueEndTime = Math.max(this.lastCueEndTime, s.endTime)), - s - } - } - _parseVTTs(r, n, e, t) { - let s; - return Cp(t, e, n.start, n.discoSeqNum, e=>{ - const t = this.mediaSink.textTracks[r] - , i = { - count: 0, - startTime: Number.POSITIVE_INFINITY, - endTime: 0 - }; - e.map(e=>{ - !t || t.cues && t.cues.getCueById(e.id) || (e.fragSN = n.mediaSeqNum, - e.webVTTCue = !0, - t.addCue(e), - i.count++), - i.startTime = Math.min(e.startTime, i.startTime), - i.endTime = Math.max(e.endTime, i.endTime) - } - ), - ne(i.startTime) && (s = i, - this.mediaSink.archiveParsedSubtitleFragmentRecord(this.selectedTrack.persistentID, n.mediaSeqNum, i)) - } - , e=>{} - , e=>{ - this.hls.trigger(P.INLINE_STYLES_PARSED, { - styles: e - }) - } - , this.logger), - s - } - _ensureParser() { - var e, t; - this.cea608Parser || (e = new Wh(this,1), - t = new Wh(this,2), - this.cea608Parser = new Gh(0,e,t)) - } - anchorTimeChanged() { - this.resetClosedCaptionParser() - } - resetClosedCaptionParser() { - var e; - null === (e = this.cea608Parser) || void 0 === e || e.reset() - } - addLegibleSamples(e, t, i, r) { - t && this.addClosedCaptionSamples(e, t), - i && 0 < i.length && this.addId3Samples(e, i, S(r)) - } - addClosedCaptionSamples(e, t) { - t.mp4 ? this.addMP4CaptionSamples(e, t.mp4) : t.ts && this.addTSCaptionSamples(e, t.ts) - } - addMP4CaptionSamples(e, i) { - if (this.enableCaption && this.config.enableCEA708Captions) { - var r = S(e); - this._ensureParser(); - for (let e = 0; e < i.length; e++) { - let t = i[e].pts - r; - var n = i[e].bytes; - for (let e = 0; e < n.length; e += 2) { - const i = []; - i.push(n[e]), - e + 1 < n.length ? i.push(n[e + 1]) : i.push(80), - this.cea608Parser.addData(t, i), - t += .03336666666666667 - } - } - } - } - addTSCaptionSamples(e, t) { - if (this.enableCaption && this.config.enableCEA708Captions) { - var i = S(e); - this._ensureParser(); - for (let e = 0; e < t.length; e++) { - var r = t[e].pts - i - , n = Rp.extractCea608Data(t[e].bytes); - this.cea608Parser.addData(r, n) - } - } - } - addId3Samples(e, t, r) { - if (this.config.enableID3Cues) { - const n = window.WebKitDataCue || window.VTTCue || window.TextTrackCue - , s = S(e); - for (let e = 0; e < t.length; e++) { - const a = t[e].pts - s; - let i = (e < t.length - 1 ? t[e + 1].pts : r) - s; - a === i && (i += 1e-4), - t[e].frames && t[e].frames.forEach(e=>{ - if (e && !this.id3shouldIgnore(e)) { - const t = new n(a,i,""); - t.value = e, - this.id3Track.addCue(t) - } - } - ) - } - } - } - id3shouldIgnore(e) { - return "PRIV" === e.key && ("com.apple.streaming.transportStreamTimestamp" === e.info || "com.apple.streaming.audioDescription" === e.info) - } - static extractCea608Data(t) { - var i = 31 & t[0]; - let r, n, s, a = 2; - const o = []; - for (let e = 0; e < i; e++) - r = t[a++], - n = 127 & t[a++], - s = 127 & t[a++], - 0 == n && 0 == s || 0 != (4 & r) && 0 == (3 & r) && (o.push(n), - o.push(s)); - return o - } - } - const Lp = { - name: "plist" - }; - class _p { - constructor(e, t, i, r) { - this.config = e, - this.xhrLoader = t, - this.customUrlLoader = i, - this.sessionDataCheckForCompleteness = e=>{ - const t = this.config["sessionDataAutoLoad"] - , i = Object.assign({}, e); - return e.complete || (e.itemList ? i.complete = e.itemList.every(e=>t[e["DATA-ID"]] && !e.VALUE && !e._STATUS && e.URI ? (this.logger.warn(`Incomplete because ${e["DATA-ID"]} was autoloaded but no response yet`), - !1) : (t[e["DATA-ID"]] && !e.URI && this.logger.warn(`id=${e["DATA-ID"]} missing uri`), - !0)) : this.logger.warn("Uninitialized SessionData")), - i - } - , - this.logger = r.child({ - name: "SessionDataLoader" - }) - } - loadSessionData(r) { - const n = this.config["sessionDataAutoLoad"] - , t = r.itemList || []; - let s = Bi(r); - return t.forEach(e=>{ - const i = e["DATA-ID"] - , t = e.URI; - if (t && n[i]) { - const n = fl.buildAbsoluteURL(r.baseUrl, t, { - alwaysNormalize: !0 - }) - , e = ""; - s = s.pipe(Ra(t=>this.loadSessionDataItemWithUrl(n, i, "", this.config, t, this.xhrLoader, this.customUrlLoader).pipe(Un(e=>(this.logger.error(`Error loading SessionData > url=${n}, id=${i}, err=${e}`), - Bi(t)))))) - } - } - ), - s.pipe(ur(e=>{ - if (t.length < 1) - return e; - e = this.sessionDataCheckForCompleteness(e); - if (e.complete) - return e; - throw new V(!1,"Session data not complete after loading all items",$.IncompleteSessionData) - } - ), $s(()=>{} - )) - } - loadSessionDataItemWithUrl(e, t, i, r, n, s, a) { - const o = qe() - , d = { - url: e, - method: "GET", - responseType: i, - xhrSetup: r.xhrSetup, - mimeType: "application/xml" - } - , l = xc({ - url: e - }, r.fragLoadPolicy); - let u; - return u = ml(e) ? a(d, l).pipe(ur(e=>this.onLoadSuccess(n, t, e.data.response.data, e.data.response.data))) : s(d, l).pipe(ur(([e])=>this.onLoadSuccess(n, t, e.response, e.responseXML))), - u.pipe(Un(e=>(e instanceof or ? e = new su(!1,e.message,0,$.SessionDataLoadTimeout) : e instanceof tu && (e = new su(!1,e.message,e.code,{ - code: e.code, - text: "Failed to load SessionData" - })), - o.error(`Unable to load SessionData > err=${e}`), - Bi(this.onLoadError(n, t, e))))) - } - onLoadSuccess(e, t, i, r) { - let n = null - , s = e; - if (function(e) { - const t = /[\s]*<\?xml/i; - t.lastIndex = 0; - var i = t.exec(e); - return i || /[\s]*"), - null) - } else if ("string" === i) { - const e = a[0]; - s = e ? e.nodeValue : null - } else if ("integer" === i) { - const e = a[0]; - s = e ? parseInt(e.nodeValue) : 0 - } else if ("float" === i) { - const e = a[0]; - s = e ? parseFloat(e.nodeValue) : 0 - } else if ("date" === i) { - const e = a[0]; - s = e ? new Date(e.nodeValue) : null - } else if ("data" === i) { - const e = a[0]; - s = e ? atob(e.nodeValue) : null - } else - "true" === i ? s = !0 : "false" === i && (s = !1) - } else if (a.length < 1) - t.warn(Lp, `unknown node with unknown value > nodeType=${e.nodeType} tagName=${e.tagName} nodeName=${e.nodeName} value=${e.nodeValue}`); - else { - s = []; - for (let e = 0; e < a.length; ++e) { - const r = a[e]; - r.tagName && s.push(n(r)) - } - 1 === s.length && (s = s[0]) - } - return s - }(n); - s = this.setSessionData(e, t, "VALUE", i) - } else if (function(e) { - const t = /[\s]*[\{\[]/; - return t.lastIndex = 0, - t.exec(e) - }(i)) - try { - const r = JSON.parse(i); - s = this.setSessionData(e, t, "VALUE", r) - } catch (r) { - this.logger.error(`JSON parser error: ${r}`), - s = this.setSessionData(e, t, "VALUE", i), - s = this.setSessionData(s, t, "_STATUS", -1) - } - else - s = this.setSessionData(e, t, "VALUE", i); - return s - } - setSessionData(t, i, r, n) { - let s = t; - if (t.itemList) { - let e; - const a = [...t.itemList]; - for (e = 0; e < t.itemList.length; ++e) { - const t = Object.assign({}, a[e]); - if (t["DATA-ID"] === i) { - t[r] = n, - a[e] = t; - break - } - } - e === t.itemList.length && this.logger.error(`Can't set ${r} of session data ${i}`), - s = Object.assign(Object.assign({}, t), { - itemList: a - }) - } else - this.logger.error(`Can't set ${r} on uninitialized session data`); - return s - } - onLoadError(e, t, i) { - return this.setSessionData(e, t, "_STATUS", null === (i = i.response) || void 0 === i ? void 0 : i.code) - } - } - function Np(e) { - return null != e && "iframeMediaDuration"in e && "iframeMediaStart"in e - } - function Fp(e, t) { - return e === t || e && t && e.itemId === t.itemId && e.mediaOptionId === t.mediaOptionId && e.mediaSeqNum === t.mediaSeqNum && e.discoSeqNum === t.discoSeqNum - } - function Bp(e) { - return JSON.stringify(e, ["mediaOptionId", "mediaSeqNum", "discoSeqNum", "start", "duration"]) - } - function Up() { - return e=>e.pipe(an(e=>null != e), ur(e=>e)) - } - function $p(e) { - return Se.isDolby(e) ? al.DOVI : Se.isHEVC(e) ? al.HEVC : Se.isVP09(e) ? al.VP09 : Se.isAVC(e) ? al.AVC : al.UNKNOWN - } - function Vp(e) { - return null == e ? void 0 : e.split(".")[0] - } - function Kp(e) { - return Se.isALAC(e) ? dl.ALAC : Se.isFLAC(e) ? dl.FLAC : Se.isEC3(e) ? dl.EC3 : Se.isAC3(e) ? dl.AC3 : Se.isXHEAAC(e) ? dl.XHEAAC : Se.isAAC(e) ? dl.AAC : Se.isMP3(e) ? dl.MP3 : dl.UNKNOWN - } - class Hp { - constructor(...e) { - this.identifier = e - } - ensureSameIdentifierLength(e) { - if (this.identifier.length !== e.identifier.length) - throw new Error(`Identifiers have non-matching lengths! (${this.identifier.length} vs ${e.identifier.length})`) - } - isGreaterThan(t) { - this.ensureSameIdentifierLength(t); - for (let e = 0; e < this.identifier.length; ++e) { - if (this.identifier[e] < t.identifier[e]) - return !1; - if (this.identifier[e] > t.identifier[e]) - return !0 - } - return !1 - } - isEqualTo(i) { - return this.ensureSameIdentifierLength(i), - this.identifier.every((e,t)=>e === i.identifier[t]) - } - } - function jp(e) { - return ne(e) && 0 !== e && 1 !== e - } - const qp = { - isBuffered(t, i) { - for (let e = 0; t && e < t.length; e++) - if (i >= t.start(e) && i <= t.end(e)) - return !0; - return !1 - }, - timeRangesToBufferedRange(t) { - const i = []; - for (let e = 0; t && e < t.length; e++) - i.push({ - start: t.start(e), - end: t.end(e) - }); - return i - }, - subtitleBufferInfo(e, t, i) { - if (e) { - e = this.bufferedCues(e); - return this.getBufferedInfo(e, t, i) - } - return { - len: 0, - start: t, - end: t, - nextStart: void 0 - } - }, - fragmentsBufferedInfo(e, t, i) { - const r = []; - for (const t of e) - r.push({ - start: t.start, - end: t.start + t.duration - }); - return this.getBufferedInfo(r, t, i) - }, - bufferedCues(t) { - const i = []; - if (t) - for (let e = 0; e < t.length; e++) - i.push({ - start: t[e].startTime, - end: t[e].endTime - }); - return i - }, - bufferedInfoFromMedia: (e,t,i)=>qp.getBufferedInfo(qp.timeRangesToBufferedRange(e.buffered), t, i), - getBufferedInfo(e, t, i) { - const r = []; - let n, s, a, o, d; - const l = e.map(({start: e, end: t})=>({ - start: e, - end: t - })); - for (l.sort((e,t)=>{ - return e.start - t.start || t.end - e.end - } - ), - d = 0; d < l.length; d++) { - const e = r.length; - if (e) { - const t = r[e - 1].end; - l[d].start - t < i ? l[d].end > t && (r[e - 1].end = l[d].end) : r.push(l[d]) - } else - r.push(l[d]) - } - for (d = 0, - n = 0, - s = a = t; d < r.length; d++) { - const e = r[d]["start"] - , l = r[d]["end"]; - if (t + i >= e && t < l) - s = e, - a = l, - n = a - t; - else if (t + i < e) { - o = e; - break - } - } - return { - len: n, - start: s, - end: a, - nextStart: o - } - }, - toRangeString: e=>`[${e.start.toFixed(3)},${e.end.toFixed(3)}]` - }; - (gc = Op = Op || {}).Seek = "Seek", - gc.HighBuffer = "HighBuffer", - gc.LowBuffer = "LowBuffer", - (gc = kp = kp || {}).AlmostDry = "AlmostDry", - gc.LowWater = "LowWater", - gc.HighWater = "HighWater", - gc.AboveHighWater = "AboveHighWater"; - const Qp = { - [kp.AlmostDry]: 0, - [kp.LowWater]: 1, - [kp.HighWater]: 2, - [kp.AboveHighWater]: 3 - }; - function Gp(t, e) { - return [{ - threshold: e.highWaterLevelSeconds, - level: kp.HighWater - }, { - threshold: e.lowWaterLevelSeconds, - level: kp.LowWater - }, { - threshold: e.almostDryWaterLevelSeconds, - level: kp.AlmostDry - }].find(({threshold: e})=>e < t) - } - function Wp(t, e) { - return [{ - threshold: e.almostDryWaterLevelSeconds, - level: kp.AlmostDry - }, { - threshold: e.lowWaterLevelSeconds, - level: kp.LowWater - }, { - threshold: e.highWaterLevelSeconds, - level: kp.HighWater - }, { - threshold: 1 / 0, - level: kp.AboveHighWater - }].find(({threshold: e})=>t <= e) - } - function zp(t, i) { - const e = Wp(t.getCurrentWaterLevel(i), t.bufferMonitorInfo).level - , r = [null, null]; - return [cl.Variant, cl.AltAudio].forEach(e=>{ - null != t.sourceBufferEntityByType(e) && (r[e] = Wp(t.getCurrentWaterLevelByType(e, i), t.bufferMonitorInfo).level) - } - ), - { - combined: e, - sbTuple: r - } - } - function Xp(s, a) { - return Zd([s.combinedBuffer$, s.gotPlaying$, s.seeking$, s.waterLevelChangedForType$(null), s.stallInfo$]).pipe(Ra(([e,t,i,r,n])=>0 === e.length || !t || i || null == r || null != n ? Ti : function t(i, r, e) { - const n = i.getCurrentWaterLevel(r) - , s = Gp(n, i.bufferMonitorInfo); - if (s) { - const e = s["threshold"]; - return vn(Math.ceil(1e3 * (n - e))).pipe(Ra(()=>{ - const e = Gp(i.getCurrentWaterLevel(r), i.bufferMonitorInfo); - return (null == e ? void 0 : e.level) === s.level ? t(i, r) : Ul - } - ), ur(()=>zp(i, r))) - } - return Ti - }(s, a))) - } - class Yp extends Od { - constructor(e, t) { - super(t), - this.mediaElement = e - } - get mediaElementDuration$() { - return this.selectActive(({mediaElementDuration: e})=>e) - } - get mediaElementDuration() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.mediaElementDuration) && void 0 !== e ? e : 1 / 0 - } - get msDuration() { - var e; - return null !== (e = null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.duration) && void 0 !== e ? e : 1 / 0 - } - get minSBDuration() { - var e; - let t = 1 / 0; - return null === (e = null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e || e.forEach(e=>{ - return t = Math.min(t, null !== (e = null == e ? void 0 : e.totalDuration) && void 0 !== e ? e : 1 / 0) - } - ), - t - } - get currentTime() { - return this.mediaElement.currentTime - } - get clientWidth() { - return this.mediaElement.clientWidth - } - get clientHeight() { - return this.mediaElement.clientHeight - } - getBufferedDuration(e=.5) { - var t = qp.timeRangesToBufferedRange(this.mediaElement.buffered) - , e = qp.getBufferedInfo(t, this.currentTime, e); - return e.end - e.start - } - get mediaSourceEntity() { - var e; - return null === (e = this.getActive()) || void 0 === e ? void 0 : e.mediaSourceEntity - } - get msReadyState() { - var e; - return null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.readyState - } - get sourceBufferEntities() { - var e; - return null === (e = this.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities - } - sourceBufferEntityByType(e) { - var t; - return null === (t = this.sourceBufferEntities) || void 0 === t ? void 0 : t[e] - } - initSegmentEntityByType(e) { - return null === (e = this.sourceBufferEntityByType(e)) || void 0 === e ? void 0 : e.initSegmentInfo - } - get maxBufferSize() { - var e = null === (e = this.sourceBufferEntities) || void 0 === e ? void 0 : e[cl.Variant]; - let t = 1 / 0; - return null != e && e.gotQuotaExceeded && (t = null !== (e = e.maxTotalBytes) && void 0 !== e ? e : 1 / 0), - t - } - get autoPausedRestartTime() { - return this.getActive().autoPausedRestartTime - } - get seekable() { - return this.mediaElement.seekable - } - get desiredRate() { - var e; - return (null === (e = this.getActive()) || void 0 === e ? void 0 : e.desiredRate) || 0 - } - get desiredRate$() { - return this.selectActive(({desiredRate: e})=>null != e ? e : 0) - } - get effectiveRate() { - return this.isIframeRate ? this.desiredRate : this.paused ? 0 : 1 - } - get playbackRate() { - return this.mediaElement.playbackRate - } - get isIframeRate() { - return jp(this.desiredRate) - } - get isIframeRate$() { - return this.desiredRate$.pipe(ur(jp)) - } - get msObjectUrl$() { - return this.selectActive(({mediaSourceEntity: e})=>null == e ? void 0 : e.objectUrl).pipe(Es()) - } - get msReadyState$() { - return this.selectActive(({mediaSourceEntity: e})=>{ - return null !== (e = null == e ? void 0 : e.readyState) && void 0 !== e ? e : null - } - ) - } - get readyState() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.readyState) && void 0 !== e ? e : 0 - } - get readyState$() { - return this.selectActive(({readyState: e})=>null != e ? e : 0) - } - get mediaSourceEntity$() { - return this.selectActive(({mediaSourceEntity: e})=>e) - } - get expectedSbCount$() { - return this.selectActive(({expectedSbCount: e})=>e) - } - get expectedSbCount() { - var e; - return null === (e = this.getActive()) || void 0 === e ? void 0 : e.expectedSbCount - } - get paused$() { - return this.selectActive(({paused: e})=>e) - } - get paused() { - var e; - return null === (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.paused) || void 0 === e || e - } - get flushing$() { - return this.selectActive(({flushing: e})=>e) - } - get flushing() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.flushing) && void 0 !== e && e - } - get waitingForDisco$() { - return this.selectActive(({waitingForDisco: e})=>e) - } - get waitingForDisco() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.waitingForDisco) && void 0 !== e && e - } - get gotPlaying() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.gotPlaying) && void 0 !== e && e - } - get gotPlaying$() { - return this.selectActive(({gotPlaying: e})=>e) - } - get gotLoadStart$() { - return this.selectActive(({gotLoadStart: e})=>e) - } - get seekTo() { - var e; - return null === (e = this.getActive()) || void 0 === e ? void 0 : e.seekTo - } - get seekTo$() { - return this.selectActive(({seekTo: e})=>e) - } - get seeking() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.seeking) && void 0 !== e && e - } - get seeking$() { - return this.selectActive(({seeking: e})=>e) - } - get nudgeTarget$() { - return this.selectActive(({nudgeInfo: e})=>null == e ? void 0 : e.nudgeTarget) - } - get nudgeCount() { - var e; - return null !== (e = null === (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.nudgeInfo) || void 0 === e ? void 0 : e.nudgeCount) && void 0 !== e ? e : 0 - } - get sourceBufferEntities$() { - return this.selectActive(({mediaSourceEntity: e})=>null == e ? void 0 : e.sourceBufferEntities) - } - sourceBufferEntityByType$(t) { - return this.selectActive(({mediaSourceEntity: e})=>{ - return null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t] - } - ) - } - bufferedSegmentsByType$(t) { - return this.selectActive(({mediaSourceEntity: e})=>{ - return null !== (e = null === (e = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t]) || void 0 === e ? void 0 : e.bufferedSegments) && void 0 !== e ? e : [] - } - ) - } - getBufferedSegmentsByType(e) { - return null !== (e = null === (e = this.sourceBufferEntityByType(e)) || void 0 === e ? void 0 : e.bufferedSegments) && void 0 !== e ? e : [] - } - get bufferedSegmentsTuple$() { - return Zd([this.bufferedSegmentsByType$(cl.Variant), this.bufferedSegmentsByType$(cl.AltAudio)]).pipe(Hi(Zi), wa(), Qn(10)) - } - get timeupdate$() { - return wc(this.mediaElement).event("timeupdate").pipe(Hi(Zi), wa(), so(125), ur(e=>this.currentTime), an(e=>ne(e))) - } - get playingEvent$() { - return wc(this.mediaElement).event("playing").pipe(ur(()=>{} - )) - } - get mediaElementEntity$() { - return this.selectActive(e=>Boolean(e)) - } - get ended$() { - return this.selectActive(e=>{ - return null !== (e = null == e ? void 0 : e.ended) && void 0 !== e && e - } - ) - } - sbUpdating$(t) { - return this.selectActive(e=>{ - return null !== (e = null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t]) || void 0 === e ? void 0 : e.updating) && void 0 !== e && e - } - ) - } - sbUpdating(e) { - var t; - return null !== (e = null === (e = null === (t = null === (t = null === (t = this.getActive()) || void 0 === t ? void 0 : t.mediaSourceEntity) || void 0 === t ? void 0 : t.sourceBufferEntities) || void 0 === t ? void 0 : t[e]) || void 0 === e ? void 0 : e.updating) && void 0 !== e && e - } - sbError$(t) { - return this.selectActive(e=>{ - return null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[t]) || void 0 === e ? void 0 : e.error - } - ) - } - get updating$() { - return Zd([this.sbUpdating$(cl.Variant), this.sbUpdating$(cl.AltAudio)]).pipe(ur(e=>e.some(e=>e))) - } - get bufferedRangeTuple$() { - return Zd([this.selectActive(e=>{ - return null !== (e = null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[ul.Variant]) || void 0 === e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : null - } - ), this.selectActive(e=>{ - return null !== (e = null === (e = null === (e = null === (e = null == e ? void 0 : e.mediaSourceEntity) || void 0 === e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[ul.AltAudio]) || void 0 === e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : null - } - )]) - } - getBufferedRangeByType(e) { - return null !== (e = null === (e = this.sourceBufferEntities[e]) || void 0 === e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : [] - } - get combinedBuffer$() { - return this.selectActive(e=>{ - return null !== (e = null == e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : [] - } - ) - } - getBufferInfo(n, s) { - var e; - const t = null === (e = this.sourceBufferEntities) || void 0 === e ? void 0 : e.map(e=>null == e ? void 0 : e.bufferedRanges) - , i = { - buffered: { - start: n, - end: n, - len: 0 - }, - bufferedSegments: [] - } - , a = [i, i]; - return t && t.forEach((e,t)=>{ - if (e) { - const i = qp.getBufferedInfo(e, n, s) - , r = (null !== (e = this.sourceBufferEntities[t].bufferedSegments) && void 0 !== e ? e : []).filter(e=>!(e.endPTS < i.start || e.startPTS > i.end)); - a[t] = { - buffered: i, - bufferedSegments: r - } - } - } - ), - a - } - getCombinedBufferInfo(e, t) { - var i = this.getActive(); - return i ? qp.getBufferedInfo(i.bufferedRanges, e, t) : null - } - get bufferMonitorInfo() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.bufferMonitorInfo) && void 0 !== e ? e : null - } - get bufferMonitorThresholds$() { - return this.selectActive(e=>{ - var t = null == e ? void 0 : e.bufferMonitorInfo; - if (!t) - return null; - var {almostDryWaterLevelSeconds: i, lowWaterLevelSeconds: r, highWaterLevelSeconds: e, maxBufferSeconds: t} = t; - return { - almostDryWaterLevelSeconds: i, - lowWaterLevelSeconds: r, - highWaterLevelSeconds: e, - maxBufferSeconds: t - } - } - ).pipe(Es((e,t)=>(null == e ? void 0 : e.lowWaterLevelSeconds) === (null == t ? void 0 : t.lowWaterLevelSeconds))) - } - get waterLevelType$() { - return this.selectActive(e=>{ - return null !== (e = null == e ? void 0 : e.bufferMonitorInfo.waterLevelType) && void 0 !== e ? e : null - } - ) - } - waterLevelForType(e) { - var t; - return null !== (e = null === (t = null === (t = this.getActive()) || void 0 === t ? void 0 : t.bufferMonitorInfo.waterLevelType) || void 0 === t ? void 0 : t.sbTuple[e]) && void 0 !== e ? e : null - } - waterLevelChangedForType$(t) { - return this.waterLevelType$.pipe(ur(e=>null == e ? null : null == t ? e.combined : e.sbTuple[t])) - } - get fellBelowLowWater$() { - return this.waterLevelChangedForType$(cl.Variant).pipe(ca(), ur(([e,t])=>function(e, t) { - return Qp[e] > Qp[t] - }(e, t) && (t === kp.LowWater || t === kp.AlmostDry)), So(this.seekTo$, this.waitingForDisco$), ur(([e,t,i])=>e && !ne(null == t ? void 0 : t.pos) && !i), xa(!1)) - } - isBufferedToEnd$(r, n=!0) { - return Zd([this.combinedBuffer$, this.selectActive(e=>e.bufferMonitorInfo).pipe(Up(), ur(e=>Math.max(e.almostDryWaterLevelSeconds, e.lowWaterLevelSeconds / 2))), this.seeking$]).pipe(ur(([e,t])=>{ - if (!e || !ne(this.minSBDuration) && n) - return !1; - e = qp.getBufferedInfo(e, this.currentTime, r).end; - let i = this.mediaElementDuration; - return n && (i = Math.min(this.mediaElementDuration, this.minSBDuration)), - i - e <= t - } - ), Es()) - } - needData$(e, r=!1, t) { - var i = !r; - return Zd([this.msReadyState$, this.waterLevelChangedForType$(null), this.isBufferedToEnd$(e, i), this.bufferedRangeTuple$]).pipe(Hi(Zi), Qn(10), wa(), ur(([e,t,i])=>"closed" !== e && (!!r || null == t || !i && t !== kp.AboveHighWater)), Ql.tag("needData")) - } - getSourceBufferInfoAction(e, t, i, r) { - var {currentTime: n, sourceBufferEntities: s, msReadyState: a} = this; - let o = [null, null]; - return !e && i.every(e=>!(null != e && e.userInitiated)) ? null : "open" === a && s && null != s[0] ? (o = this.getBufferInfo(n, r), - { - position: n, - bufferInfoTuple: o, - switchContexts: i - }) : { - position: t, - bufferInfoTuple: o, - switchContexts: i - } - } - get haveEnough() { - var e; - return null !== (e = null === (e = this.getActive()) || void 0 === e ? void 0 : e.haveEnough) && void 0 !== e && e - } - get haveEnough$() { - return this.selectActive(({haveEnough: e})=>e) - } - static likelyToKeepUp(e, t, i) { - return t && i >= e.HAVE_FUTURE_DATA - } - get playbackLikelyToKeepUp() { - return Yp.likelyToKeepUp(this.mediaElement, this.haveEnough, this.readyState) - } - get playbackLikelyToKeepUp$() { - return Zd([this.haveEnough$, this.readyState$]).pipe(ur(([e,t])=>Yp.likelyToKeepUp(this.mediaElement, e, t))) - } - getCurrentWaterLevel(e) { - var t = this.currentTime - , i = null !== (i = null === (i = this.getActive()) || void 0 === i ? void 0 : i.bufferedRanges) && void 0 !== i ? i : []; - return qp.getBufferedInfo(i, t, e).len - } - getCombinedMediaSourceBufferInfo(e) { - var t = this.currentTime - , [i,r] = null === (r = null === (i = this.getActive()) || void 0 === i ? void 0 : i.mediaSourceEntity) || void 0 === r ? void 0 : r.sourceBufferEntities; - return [qp.getBufferedInfo(null !== (i = null == i ? void 0 : i.bufferedRanges) && void 0 !== i ? i : [], t, e), qp.getBufferedInfo(null !== (r = null == r ? void 0 : r.bufferedRanges) && void 0 !== r ? r : [], t, e)] - } - getCurrentWaterLevelByType(e, t) { - var i = this.currentTime - , e = this.sourceBufferEntityByType(e) - , e = null !== (e = null == e ? void 0 : e.bufferedRanges) && void 0 !== e ? e : []; - return qp.getBufferedInfo(e, i, t).len - } - canContinuePlaybackWithoutGap(e, t, i, r) { - if (!e.liveOrEvent) - return !0; - if (!e.ptsKnown) - return !1; - var n = this.currentTime - , i = performance.now() + i.avgPlaylistLoadTimeMs; - return e.fragments[0].start + (i - t) / 1e3 <= this.getCombinedBufferInfo(n, r).end - } - get stallInfo$() { - return this.selectActive(e=>{ - return null !== (e = null == e ? void 0 : e.stallInfo) && void 0 !== e ? e : null - } - ) - } - get textTracks() { - return this.mediaElement.textTracks - } - get textTracksCreated$() { - return this.selectActive(e=>null == e ? void 0 : e.textTracksCreated) - } - get mediaOptionParsedSubtitleRecord() { - var e; - return null === (e = this.getActive()) || void 0 === e ? void 0 : e.mediaOptionParsedSubtitleRecord - } - getParsedSubtitleRecordsForMediaOption(e) { - return this.mediaOptionParsedSubtitleRecord ? this.mediaOptionParsedSubtitleRecord[e] || {} : null - } - } - class Jp { - constructor(e, t, i, r) { - this.mediaSink = e, - this.media = t, - this.logger = r, - this.useCustomMediaFunctions = i.useCustomMediaFunctions, - this.overridePlaybackRate = i.overridePlaybackRate - } - install() { - const e = this.media; - e && (this.useCustomMediaFunctions && e && e.play && e.pause && (e.originalPlay || (e.originalPlay = e.play.bind(e)), - e.originalPause || (e.originalPause = e.pause.bind(e)), - e.play = ()=>(this.mediaSink.checkForReplay(), - this.mediaSink.desiredRate = 1, - 0 < e.currentTime && !e.paused && !e.ended && 2 < e.readyState ? Promise.resolve() : new Promise((e,t)=>{ - this.pendingPlayPromises || (this.pendingPlayPromises = []), - this.pendingPlayPromises.push({ - resolve: e, - reject: t - }) - } - )), - e.pause = ()=>{ - this.mediaSink.desiredRate = 0 - } - ), - "function" == typeof HTMLMediaElement && this.overridePlaybackRate && Object.defineProperty(e, "playbackRate", { - enumerable: !0, - configurable: !0, - get: function() { - return 1 - }, - set: function(e) { - Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, "playbackRate").set.call(this, e) - } - }), - this.playPromise = null, - this.expectPauseEvent = this.expectPlayEvent = !1) - } - uninstall() { - const e = this.media; - e && (e.originalPlay && (e.play = e.originalPlay, - delete e.originalPlay), - e.originalPause && (e.pause = e.originalPause, - delete e.originalPause), - this.overridePlaybackRate && (e.playbackRate = 1, - delete e.playbackRate)), - this.playPromise = null, - this.expectPauseEvent = this.expectPlayEvent = !1 - } - play() { - var e; - this.media && (e = this.mediaSink.flushing, - this.playPromise || e ? this.logger.warn(`Ignoring play command playPromise/flushing ${Boolean(this.playPromise)}/${e}`) : (this.expectPlayEvent = this.expectPlayEvent || this.media.paused, - this.playPromise = this._mediaPlayInternal(), - this.playPromise && this.playPromise.then(function() { - this.playPromise = null, - this._handlePendingPlayPromises(null) - } - .bind(this)).catch(function(e) { - this.playPromise = null, - this.expectPlayEvent = !1, - this._handlePendingPlayPromises(e || new Error("Play rejected for unknown reason")), - "NotAllowedError" === (null == e ? void 0 : e.name) ? (this.logger.warn("play() not allowed, going back to rate 0"), - this.mediaSink.desiredRate = 0) : this.logger.error(`play() error: ${null == e ? void 0 : e.message}`) - } - .bind(this)))) - } - pause() { - this.media && (this.playPromise ? this.playPromise.then(()=>{ - var e = this.mediaSink.mediaQuery; - (0 === this.mediaSink.desiredRate || e.seeking && !e.playbackLikelyToKeepUp) && this._mediaPauseInternal() - } - ).catch(e=>{ - this.logger.error(`Promise error in pause(): ${e.message}`) - } - ) : this._mediaPauseInternal()) - } - _handlePendingPlayPromises(t) { - var e, i = null === (e = this.pendingPlayPromises) || void 0 === e ? void 0 : e.length; - if (t) - for (let e = 0; e < i; e++) - this.pendingPlayPromises[e].reject(t); - else - for (let e = 0; e < i; e++) - this.pendingPlayPromises[e].resolve(); - this.pendingPlayPromises = [] - } - _mediaPlayInternal() { - return (this.media.originalPlay || this.media.play.bind(this.media))() - } - _mediaPauseInternal() { - return this.expectPauseEvent = this.expectPauseEvent || !this.media.paused, - (this.media.originalPause || this.media.pause.bind(this.media))() - } - } - class Zp extends Error { - } - class ef extends p { - constructor(e, t, i, r, n) { - super(L, e, t, i, r), - this.sbType = n, - this.response = r - } - } - class tf extends ef { - constructor(e, t, i, r) { - super("bufferAddCodecError", !1, e, t, i), - this.mediaOptionId = r, - this.mediaOptionType = Rl(this.sbType) - } - } - class rf extends ef { - constructor(e, t, i, r, n, s) { - super(e, t, i, r, n), - this.isTimeout = s, - this.mediaOptionType = Rl(this.sbType) - } - } - class nf extends rf { - constructor(e, t, i, r) { - super("bufferFullError", !1, e, t, i, !1), - this.maxTotalBytes = r - } - } - class sf extends rf { - constructor(e, t, i) { - super(n, !1, e, t, i, !0) - } - } - class af extends rf { - constructor(e, t, i, r) { - super(n, !1, e, t, i, !1), - this.mediaOptionId = r, - this.mediaOptionType = Rl(this.sbType) - } - } - class of extends p { - constructor(e, t, i, r, n, s, a=NaN) { - super(L, e, t, i, r), - this.stallType = n, - this.bufferLen = s, - this.nudgePosition = a, - this.response = r - } - } - class df extends Ut { - constructor(n, e, s, a, o, d, l, u, c) { - super(e=>{ - const t = wc(d) - , i = u.child({ - sb: o - }); - n.setSourceBufferEntity(o, l), - l.mimeType.includes("audio/mpeg") && (this.updateMp3Timestamps = !0); - const r = nn(t.event("updatestart").pipe(Ja(()=>{ - n.setSourceBufferUpdating(o) - } - )), t.event("updateend").pipe(Hi(Zi), Ja(()=>{ - var e = qp.timeRangesToBufferedRange(d.buffered) - , t = qp.timeRangesToBufferedRange(s.buffered); - n.setBufferedRangesUpdated(o, e, t, !1, c.maxBufferHole) - } - )), t.event("error").pipe(Ja(()=>{ - n.setSourceBufferError(o, "Got source buffer error") - } - ))).pipe(Ra(()=>Ti)).subscribe(e); - return ()=>{ - r.unsubscribe(); - try { - "open" === a.readyState && d.abort(), - a.removeSourceBuffer(d) - } catch (e) { - i.error(`Error aborting SourceBuffer on unsubscribe: ${e.message}`) - } - } - } - ), - this.mediaElementStore = n, - this.mediaElementQuery = e, - this.mediaElement = s, - this.type = o, - this.sourceBuffer = d, - this.config = c, - this.updateMp3Timestamps = !1 - } - get buffered() { - return this.sourceBuffer.buffered - } - appendBuffer(e, t) { - return Yr(()=>this.sourceBuffer.updating ? this._waitForUpdateEndOrError().pipe(Ra(()=>this.appendBuffer(e, t))) : this._appendBufferAsync(e, t)) - } - _appendBufferAsync(e, t) { - let i = NaN - , r = null; - const n = ("startPTS"in t ? t.frag : t).mediaOptionId; - try { - "startPTS"in t && (r = { - startPTS: t.startPTS, - endPTS: t.endPTS, - bytes: t.bytes, - frag: Object.assign({}, t.frag) - }), - this.mediaElementStore.setInflightSegment(this.type, r), - i = performance.now(), - this.sourceBuffer.appendBuffer(e) - } catch (e) { - return 22 !== e.code ? (this.mediaElementStore.setInflightSegment(this.type, null), - this.mediaElement.error ? Ui(new af(e.message,$.VideoDecoderBadDataErr,this.type,n)) : Ui(e)) : (this.mediaElementStore.setBufferedRangesUpdated(this.type, qp.timeRangesToBufferedRange(this.sourceBuffer.buffered), qp.timeRangesToBufferedRange(this.mediaElement.buffered), !0, this.config.maxBufferHole), - Ui(new nf(e.message,$.AllocationFailed,this.type,this.maxTotalBytes))) - } - return this._waitForUpdateEndOrError().pipe(ur(()=>({ - startAppend: i, - endAppend: performance.now(), - bytesAppend: e.byteLength - })), vo(1e4), Un(e=>{ - throw e instanceof or ? (this.sourceBuffer.abort(), - e = new sf("Append took longer than 10000ms",$.InternalError,this.type)) : e instanceof ef && (e = new af("Decode error",$.VideoDecoderBadDataErr,this.type,n)), - e - } - )) - } - remove(e, t) { - return this._waitForUpdateEndOrError().pipe(Ra(this._removeAsync.bind(this, e, t))) - } - _removeAsync(e, t) { - try { - this.sourceBuffer.remove(e, t) - } catch (e) { - return Ui(new ef(r,!1,e.message,$.InternalError,this.type)) - } - return this._waitForUpdateEndOrError() - } - abort() { - try { - this.sourceBuffer.abort() - } catch (e) { - return Ui(new ef(r,!1,e.message,$.InternalError,this.type)) - } - return this._waitForUpdateEndOrError() - } - get updating() { - return this.sourceBuffer.updating - } - get timestampOffset() { - return this.sourceBuffer.timestampOffset - } - set timestampOffset(e) { - this.sourceBuffer.timestampOffset = e - } - get gotQuotaExceeded() { - var e; - return null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.gotQuotaExceeded) && void 0 !== e && e - } - get bufferedSegments() { - var e; - return null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.bufferedSegments) && void 0 !== e ? e : [] - } - get totalBytes() { - var e; - return null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.totalBytes) && void 0 !== e ? e : 0 - } - get maxTotalBytes() { - var e = null !== (e = null === (e = this.mediaElementQuery.sourceBufferEntityByType(this.type)) || void 0 === e ? void 0 : e.maxTotalBytes) && void 0 !== e ? e : 1 / 0; - return this.gotQuotaExceeded ? e : 1 / 0 - } - _waitForUpdateEndOrError() { - return this.sourceBuffer.updating && this.mediaElementStore.setSourceBufferUpdating(this.type), - this.mediaElementQuery.sbUpdating$(this.type).pipe(an(e=>!1 === e), So(this.mediaElementQuery.sbError$(this.type)), ur(([,e])=>{ - if (e) - throw new ef(r,!1,"Got error during sourceBuffer operation",$.InternalError,this.type) - } - ), Cs(1)) - } - } - class lf extends Ut { - constructor(a, o, e, d, t, i) { - super(e=>{ - const t = wc(d) - , i = nn(t.event("sourceopen"), t.event("sourceclose"), t.event("sourceended")).pipe(Ja(e=>{ - e = (null !== (e = null == e ? void 0 : e.target) && void 0 !== e ? e : d).readyState; - o.msReadyState = e - } - )) - , r = this.sourceBuffers$.pipe(Ra(e=>e ? nn(...e.filter(e=>null != e)) : Ti)) - , n = nn(i, r).pipe(Ra(()=>Ti)).subscribe(e) - , s = URL.createObjectURL(d); - return a.src = s, - o.setMediaSourceEntity(s, d.readyState), - ()=>{ - n.unsubscribe(), - this.teardownWorker.addWork(Yr(()=>(URL.revokeObjectURL(s), - a.src === s && (a.removeAttribute("src"), - a.load(), - o.setMediaSourceEntity(null)), - Ul))), - this.sourceBuffers$.next(null) - } - } - ), - this.mediaElement = a, - this.mediaElementStore = o, - this.mediaElementQuery = e, - this.mediaSource = d, - this.teardownWorker = t, - this.logger = i, - this.sourceBuffers$ = new gi(null) - } - get readyState() { - return this.mediaSource.readyState - } - set duration(e) { - this.mediaSource.duration = e - } - get duration() { - return this.mediaSource.duration - } - endOfStream(e) { - this.mediaSource.endOfStream(e) - } - createSourceBuffers(e, a) { - const o = this.mediaSource; - sd(()=>{ - try { - const s = [null, null]; - e.forEach((t,i)=>{ - if (t) { - var {mimeType: r, mediaOptionId: n} = t; - let e; - try { - e = o.addSourceBuffer(r) - } catch (t) { - throw new tf(t.message,$.IncompatibleAsset,i,n) - } - s[i] = new df(this.mediaElementStore,this.mediaElementQuery,this.mediaElement,this.mediaSource,i,e,t,this.logger,a) - } - } - ), - this.sourceBuffers$.next(s) - } catch (e) { - if (!(e instanceof p)) - throw new Zp(`error initializing sourcebuffers ${e.message} readyState=${o.readyState}`); - throw e - } - } - ) - } - get needSourceBuffers() { - return null == this.sourceBuffers$.value || null == this.sourceBuffers$.value[0] - } - get sourceBuffers() { - return this.sourceBuffers$.value - } - getSourceBufferByType(e) { - var t = this.sourceBuffers$.value; - return t ? t[e] : null - } - updateLiveSeekableRange(e, t) { - const i = this.mediaSource; - null != i && i.setLiveSeekableRange && "open" === (null == i ? void 0 : i.readyState) && i.setLiveSeekableRange(e, t) - } - clearLiveSeekableRange() { - const e = this.mediaSource; - null != e && e.clearLiveSeekableRange && "open" === (null == e ? void 0 : e.readyState) && e.clearLiveSeekableRange() - } - } - function uf(e, c, t) { - const {lowBufferThreshold: h, lowBufferWatchdogPeriod: p, highBufferWatchdogPeriod: f, seekWatchdogPeriod: m} = t - , i = Zd([c.desiredRate$, c.ended$, c.combinedBuffer$, c.seekTo$]).pipe(ur(e=>{ - var t, [i,r,n,s] = e; - return t = c.currentTime, - e = i, - i = r, - r = n, - n = isFinite(null == s ? void 0 : s.pos), - s = r.some(e=>e.start <= t && e.end > t), - !(1 !== e || i || 0 === r.length || n && !s) - } - ), Es()) - , r = c.combinedBuffer$.pipe(ur(()=>c.getCurrentWaterLevel(0) <= t.lowBufferThreshold || !c.haveEnough ? Op.LowBuffer : Op.HighBuffer), Es()) - , n = Zd([i, c.seekTo$, c.gotPlaying$, r]).pipe(Ra(e=>{ - var [t,i,r] = e; - if (!t) - return Bi(null); - var n, s, a, o, d, l, u, e = c.nudgeCount, t = m + +e; - return isFinite(null == i ? void 0 : i.pos) || !r ? (n = c, - s = performance.now(), - t = t, - a = h, - vn(1e3 * t).pipe(ur(()=>{ - var e = n.currentTime - , t = n.getCombinedBufferInfo(e, 0); - return cf(Op.Seek, e, s, t, a, n.haveEnough) - } - ))) : (o = c, - d = p, - l = f + +e, - u = h, - nn(Bi(o.currentTime), o.timeupdate$).pipe(Ra(e=>{ - const t = performance.now() - , i = o.getCombinedBufferInfo(e, 0); - let r, n; - return r = i.len <= u || !o.haveEnough ? (n = d, - Op.LowBuffer) : (n = l, - Op.HighBuffer), - vn(Math.max(100, 1e3 * n)).pipe(ur(()=>e < o.currentTime ? null : cf(r, e, t, i, u, o.haveEnough))) - } - ))) - } - )) - , s = n.pipe(Up(), So(c.combinedBuffer$), Ra(([])=>Zd([c.seeking$, c.paused$])), Ra(([e,t])=>e || t ? Ti : c.timeupdate$.pipe(ca(), an(([e,t])=>ne(e) && ne(t) && e < t), Cs(1))), ur(()=>null)); - return nn(n, s) - } - function cf(e, t, i, r, n, s) { - var a = performance.now() - i; - return { - type: e, - isLowBufferStall: r.len <= n || !s, - tstalled: i, - stallDurationMs: a, - currentTime: t - } - } - class hf extends Ut { - constructor(w, A, e, t, i, r, n) { - super(e=>{ - const t = this.config - , i = A.startMediaSession(w, t.maxBufferLength, t.almostDryBufferSec, t.defaultTargetDuration) - , r = Bi(w).pipe(pf(A, this._mediaQuery, this, this.hlsGapless, t, this.logger, this.rtcService)) - , n = this.mediaSource$.pipe(Ra(e=>e || Ti)) - , s = this._mediaQuery.seekTo$.pipe((u = w, - c = this._mediaQuery, - p = (h = this).config, - f = (f = this.logger).child({ - name: "seek" - }), - e=>e.pipe(Ja(e=>{} - ), an(e=>e && ne(e.pos)), Ra(e=>c.readyState$.pipe(an(e=>e >= u.HAVE_METADATA), Cs(1), Js(e), Ra(({pos: e, fromEvent: t})=>(h.checkForInconsistentStoreBufferRangesAndUpdate(), - u.paused || h.pause(), - t || (u.currentTime = e), - $l(c.haveEnough$, e=>e).pipe(Js(e)))), Ra(e=>{ - var t = c.getCombinedBufferInfo(e, 0) - , i = t.nextStart; - return 0 === t.len && ne(i) && e < i && i - e <= p.maxSeekHole ? (h.seekTo = i, - Ti) : Bi(e) - } - ), So(c.desiredRate$), ur(([,e])=>{ - u.paused && 0 !== e && h.play() - } - ), Ua(Ti), Un(e=>(f.error(`error during seek ${e.message}`), - Ti))))))) - , a = this._mediaQuery.desiredRate$.pipe((o = w, - d = this._mediaQuery, - l = this, - e=>e.pipe(So(d.seekTo$), Ra(([e,t])=>ne(null == t ? void 0 : t.pos) ? Ti : 0 === e ? (o.paused || l.pause(), - Ti) : $l(d.haveEnough$, e=>e).pipe(Ja(()=>{ - o.paused && l.play() - } - ))), Ua(Ti)))); - var o, d, l, u, c, h, p, f; - this.mediaFunctions = this.mediaFunctions || new Jp(this,w,t,this.logger), - this.mediaFunctions.install(); - var m, g, y, v, S, b, T, E, I = nn(uf(this.logger, this._mediaQuery, this.config).pipe(Ja(e=>{ - A.setStallInfo(e) - } - )), this.mediaQuery.stallInfo$.pipe((g = A, - y = (m = this).config, - v = this.logger, - e=>e.pipe(Ls(e=>e ? function(i, e, r, n) { - const s = i.mediaQuery; - return nn(Zd([s.seekTo$, s.nudgeTarget$]).pipe(an(([e,t])=>e && ne(e.pos) && ne(t) && (e.pos < t || e.pos - t > r.maxSeekHole)), Js(null)), s.stallInfo$).pipe(So(s.desiredRate$), Hi(Zi), ur(([c,e],t)=>{ - if (!c) - return NaN; - var h = s.getCombinedBufferInfo(c.currentTime, 0) - , e = jp(e); - return function(e, t, i, r, n) { - var {type: s, isLowBufferStall: a, currentTime: o} = c - , d = h.len - , l = t.maxSeekHole; - let u = NaN; - if (a) { - const t = h.nextStart - o <= l ? h.nextStart : 1 / 0; - ne(t) ? u = t : e.mediaQuery.msDuration - o < .1 && (u = o + .1) - } else if (n < t.nudgeMaxRetry) - u = o + t.nudgeOffset; - else { - if (!r) - throw i.error(`still stuck in high buffer @${o} after ${t.nudgeMaxRetry}, raise fatal error`), - new of("bufferStalledError",!0,"got fatal buffer error",$.VideoDecoderBadDataErr,s,d); - i.error(`still stuck in high buffer @${o} after ${t.nudgeMaxRetry}, non fatal in iframeMode`) - } - return ne(u) && e.nudgeSeek(u, n + 1), - u - }(i, r, n, e, t) - } - ), Qa(e=>ne(e)), $s(()=>{ - e.setNudgeInfo(null) - } - )) - }(m, g, y, v) : Bi(NaN)))))); - nn(r, n, s, a, I, (S = this.mediaQuery, - b = A, - I = t.maxBufferHole, - nn((E = I, - Zd([(T = S).bufferMonitorThresholds$, T.combinedBuffer$, T.seeking$]).pipe(ur(([e])=>null == e ? null : zp(T, E)))), Xp(S, I)).pipe(Hi(Zi), Ja(({combined: e, sbTuple: t})=>{ - b.updateWaterLevels(e, t) - } - )))).pipe(Ua(Ti), $s(()=>{ - A.remove(i), - this.mediaFunctions.uninstall(), - this.mediaFunctions = void 0 - } - )).subscribe(e) - } - ), - this.mediaElement = w, - this.mediaElementStore = A, - this.config = e, - this.hlsGapless = t, - this.logger = i, - this.teardownWorker = r, - this.rtcService = n, - this.mediaSource$ = new gi(null), - this._mediaQuery = new Yp(w,A), - this.logger = i.child({ - name: "mse" - }), - this.mediaFunctions = new Jp(this,w,e,this.logger) - } - get mediaSourceAdapter() { - return this.mediaSource$.value - } - get sourceBuffers() { - var e; - return null !== (e = null === (e = this.mediaSourceAdapter) || void 0 === e ? void 0 : e.sourceBuffers) && void 0 !== e ? e : [] - } - get needSourceBuffers() { - return !this.sourceBuffers[0] - } - get mediaQuery() { - return this._mediaQuery - } - sourceBuffersBufferedRangeByType(e) { - var t, e = null === (t = null === (t = this.mediaSourceAdapter) || void 0 === t ? void 0 : t.sourceBuffers) || void 0 === t ? void 0 : t[e]; - return e ? qp.timeRangesToBufferedRange(e.sourceBuffer.buffered) : null - } - checkForInconsistentStoreBufferRangesAndUpdate() { - var e = qp.timeRangesToBufferedRange(this.mediaElement.buffered) - , t = this.sourceBuffersBufferedRangeByType(cl.Variant) - , i = this.sourceBuffersBufferedRangeByType(cl.AltAudio) - , r = null !== (n = null === (r = this.mediaQuery.sourceBufferEntityByType(cl.Variant)) || void 0 === r ? void 0 : r.bufferedRanges) && void 0 !== n ? n : null - , n = null !== (n = null === (n = this.mediaQuery.sourceBufferEntityByType(cl.AltAudio)) || void 0 === n ? void 0 : n.bufferedRanges) && void 0 !== n ? n : null; - this.shouldUpdateStoreValues(t, r) && (this.logger.warn(`[${Pl[cl.Variant]}] SourceBuffer's loaded bufferedRanges ${JSON.stringify(t)} & mediaElementStore's bufferedRanges ${JSON.stringify(r)} are out of sync!`), - this.updateMediaElementStoreBufferedRanges(e, cl.Variant)), - this.shouldUpdateStoreValues(i, n) && (this.logger.warn(`[${Pl[cl.AltAudio]}] SourceBuffer's loaded bufferedRanges ${JSON.stringify(i)} & mediaElementStore's bufferedRanges ${JSON.stringify(n)} are out of sync!`), - this.updateMediaElementStoreBufferedRanges(e, cl.AltAudio)) - } - shouldUpdateStoreValues(e, i) { - return !(null == e && null == i || (null == e ? void 0 : e.length) == (null == i ? void 0 : i.length) && !e.find(t=>{ - var e = Ll.search(i, e=>t.start >= e.start && t.end <= e.end ? 0 : t.end < e.start ? -1 : 1); - return null == e || e.start != t.start || e.end != t.end || void 0 - } - )) - } - updateMediaElementStoreBufferedRanges(e, t) { - var i = this.sourceBuffersBufferedRangeByType(t); - i && !this.mediaQuery.sbUpdating(t) && this.mediaElementStore.setBufferedRangesUpdated(t, i, e, !1, this.config.maxBufferHole) - } - destroyMediaSource() { - this.mediaSource$.next(null) - } - makeMediaSource() { - return new MediaSource - } - openMediaSource(t) { - sd(()=>{ - var e; - t ? (e = new lf(this.mediaElement,this.mediaElementStore,this.mediaQuery,t,this.teardownWorker,this.logger), - this.mediaSource$.next(e)) : this.mediaSource$.next(null) - } - ) - } - createSourceBuffers(e) { - const t = this.mediaSource$.value; - if (!t) - throw new Error("createSourceBuffers empty mediaSource"); - t.createSourceBuffers(e, this.config) - } - _waitForMediaSourceOpen(i) { - const r = this.mediaQuery.mediaSourceEntity.objectUrl; - return Zd([this.mediaQuery.msReadyState$, this.mediaQuery.msObjectUrl$]).pipe(Ra(([e,t])=>t !== r ? Bi(null) : "open" === e || "ended" === e ? Bi(i) : Ti)) - } - get appendOrder() { - return this.mediaQuery.isIframeRate ? [cl.Variant, cl.AltAudio] : [cl.AltAudio, cl.Variant] - } - clearFlush(e) { - e.forEach(e=>{ - e && (e.dataSeg.flushBeforeAppend = { - start: 0, - end: 0 - }) - } - ) - } - getSwitchPosition(e) { - return e.reduce((e,t)=>{ - t = t ? t.dataSeg.switchPosition : void 0; - return ne(t) ? ne(e) ? Math.min(e, t) : t : e - } - , void 0) - } - checkForReplay() { - var e = this.mediaElement; - e.paused && !e.seeking && e.duration && e.currentTime && e.currentTime >= e.duration - this.config.maxTotalDurationTolerance && (this.seekTo = 0) - } - resetMediaSourceIfNeeded(r) { - const n = this["mediaQuery"] - , e = n["sourceBufferEntities"] - , t = n.getActive()["expectedSbCount"]; - if (!e || this.needSourceBuffers) - return this._waitForMediaSourceOpen(r); - var i = function(e, s, t, i, r) { - const n = s.filter(e=>Boolean(e)).length - , a = e.filter(e=>Boolean(e)).length - , d = [null, null]; - e.forEach((e,t)=>{ - var i, r, n, s, a, o; - e && (s = e["offsetTimestamp"], - a = S(s), - i = e.initSeg.mimeType, - {audioCodec: r, videoCodec: n} = e.initSeg.initParsedData, - o = e["dataSeg"], - s = S(o.startPts) - a, - a = S(o.endPts) - a, - o = o.discoSeqNum, - d[t] = { - audioCodec: r, - videoCodec: n, - mimeType: i, - startPTSSec: s, - endPTSSec: a, - discoSeqNum: o, - mediaOptionId: e.initSeg.mediaOptionId - }) - } - ); - let o = n === t - , l = a === t; - if (1 === a && a < t && 0 !== n) { - const t = e[ul.Variant] ? ul.Variant : ul.AltAudio - , n = 1 - t - , a = d[t] - , o = d[n] = ff(s[n], a.startPTSSec, a.discoSeqNum, i, a.mediaOptionId, r) || ff(s[n], a.endPTSSec, a.discoSeqNum, i, a.mediaOptionId, r); - o || r.warn(`${Cl[t]} No matching frag found ${se(a)} buffered=${se(s[n].bufferedSegments.map(e=>{ - var {mediaSeqNum: t, discoSeqNum: i} = e.frag; - return { - mediaSeqNum: t, - discoSeqNum: i, - startPTS: e.startPTS, - endPTS: e.endPTS - } - } - ))}`), - l = null != o - } - let u = NaN - , c = NaN; - return l && d.forEach((e,t)=>{ - if (!e) - return null; - t = s[t]; - if (t) { - const s = t.audioCodec - , i = t.videoCodec - , {audioCodec: r, videoCodec: n} = e; - o = o && (i === n || Se.isCompatibleVideoCodec(i, n)), - o = o && (s === r || Se.isCompatibleAudioCodec(s, r)) - } else - o = !1; - u = ne(u) ? (c = Math.abs(e.startPTSSec - u), - Math.max(e.startPTSSec, u)) : (c = 0, - e.startPTSSec) - } - ), - { - compatible: o && l, - boundary: u, - allowance: c - } - }(r, e, t, this.config.maxBufferHole, this.logger); - if (i.compatible) - return this._waitForMediaSourceOpen(r); - let s = i.boundary; - const a = i.allowance - , o = this.getSwitchPosition(r); - if (ne(o) && (s = o), - !ne(s)) - return this.logger.warn("not enough info #disco"), - Bi(null); - const d = hn($l(nn(Bi(n.currentTime), n.timeupdate$), e=>e >= s), $l(n.stallInfo$.pipe(ur(e=>{ - return null !== (e = null == e ? void 0 : e.currentTime) && void 0 !== e ? e : NaN - } - )), e=>e >= s - a - this.config.discontinuitySeekTolerance)); - return this.mediaElementStore.waitingForDisco = !0, - d.pipe(Js(s), Ra(e=>{ - performance.now(); - const t = n.currentTime - , i = this.msDuration; - return this.resetMediaSource(Math.max(t, e)), - this._waitForMediaSourceOpen(r).pipe(Ja(()=>{ - performance.now(), - this.msDuration = i - } - )) - } - ), $s(()=>{ - this.mediaElementStore.waitingForDisco = !1 - } - )) - } - resetMediaSource(e=NaN) { - var t; - ne(e) || (e = null !== (t = null === (t = this.mediaQuery.seekTo) || void 0 === t ? void 0 : t.pos) && void 0 !== t ? t : this.mediaQuery.currentTime), - 0 < this.sourceBuffers.length && (this.openMediaSource(this.makeMediaSource()), - this.seekTo = e) - } - setExpectedSbCount(e) { - this.mediaElementStore.expectedSbCount = e - } - appendInitSegments(d, l) { - const {mediaQuery: e, mediaElementStore: u, sourceBuffers: c} = this - , h = e["sourceBufferEntities"]; - if (!c) - throw new Error("appendInitSegments: null sourceBuffers"); - if (!h) - throw new Error("appendInitSegments: null sourceBufferEntities"); - var t = this.appendOrder.map(t=>{ - if (d[t]) { - const i = c[t] - , r = d[t] - , n = h[t] - , s = r["initSeg"]; - if (!n) - throw new Error(`appendInitSegments: sb[${Pl[t]}] null currentSbEntity`); - if (!i) - throw new Error(`appendInitSegments: sb[${Pl[t]}] null source buffer`); - const a = n.initSegmentInfo - , o = function() { - var {itemId: e, mediaOptionId: t, discoSeqNum: i, keyTagInfo: r} = s; - return { - itemId: e, - mediaOptionId: t, - discoSeqNum: i, - keyId: je(null == r ? void 0 : r.keyId) - } - }(); - if ((e = o) && a && e.itemId === a.itemId && e.mediaOptionId === a.mediaOptionId && e.discoSeqNum === a.discoSeqNum && e.keyId === a.keyId) - return Bi(null); - var e = Rl(t); - return i.appendBuffer(s.data, s).pipe(Ja(e=>{ - u.setInitSegmentEntity(t, o) - } - ), l(i, e, s.mediaOptionId, this.config, this.mediaQuery)) - } - } - ).filter(e=>Boolean(e)); - return 0 === t.length ? Bi(null) : Jr(t) - } - appendDataSegments(m, g) { - var e = this.appendOrder.map(e=>{ - const t = m[e] - , {mediaQuery: i, sourceBuffers: r} = this - , n = i["sourceBufferEntities"]; - if (!r) - throw new Error("appendDataSegments: null sourceBuffers"); - if (!n) - throw new Error("appendDataSegments: null sourceBufferEntities"); - if (!t) - return null; - const s = r[e] - , a = m[e] - , o = n[e]; - if (!o) - throw new Error("appendDataSegments: null currentSbEntity"); - const d = o.initSegmentInfo - , l = a["dataSeg"]; - if (!d) - throw new Error(`appendDataSegments: sb[${Pl[e]}] null currentInitSegmentInfo`); - if (!o) - throw new Error(`appendDataSegments: sb[${Pl[e]}] null currentSbEntity`); - if (!s) - throw new Error(`appendDataSegments: sb[${Pl[e]}] null source buffer`); - const u = s.timestampOffset - , c = { - startPTS: S(l.startPts) + u, - endPTS: S(l.endPts) + u, - firstKeyframePts: l.firstKeyframePts ? S(l.firstKeyframePts) + u : void 0, - bytes: l.data2 ? l.data1.byteLength + l.data2.byteLength : l.data1.byteLength, - frag: { - itemId: l.itemId, - mediaOptionId: l.mediaOptionId, - mediaSeqNum: l.mediaSeqNum, - discoSeqNum: l.discoSeqNum, - keyTagInfo: l.keyTagInfo, - isLastFragment: l.isLastFragment, - iframe: l.iframe, - framesWithoutIDR: l.framesWithoutIDR, - dropped: l.dropped - } - } - , h = Rl(e); - let p = Ul; - var f = t.dataSeg.flushBeforeAppend; - return f && f.start !== f.end && (p = this.flushData(e, f.start, f.end)), - p.pipe(Ra(()=>Bi(l.data1, l.data2).pipe(Up()).pipe(qn(e=>s.appendBuffer(e, c).pipe(g(s, h, l.mediaOptionId, this.config, this.mediaQuery))))), Ja(()=>{ - i.getBufferedRangeByType(e) - } - )) - } - ).filter(e=>Boolean(e)); - return 0 === e.length ? Bi(null) : Jr(e) - } - setStoreSbTimeoffsets(s) { - const {mediaElementStore: a, sourceBuffers: e} = this; - e.forEach((t,i)=>{ - if (t && s[i]) { - var {offsetTimestamp: r, dataSeg: n} = s[i] - , n = S(n.startPts); - let e = -1 * S(r); - t.updateMp3Timestamps && .1 < Math.abs(t.timestampOffset - n) && (e = n + e), - t.timestampOffset !== e && (t.timestampOffset = e, - a.setTimestampOffset(i, t.timestampOffset)) - } - } - ) - } - adjustJaggedStart() { - var e; - const {mediaQuery: t, logger: r} = this - , {sourceBufferEntities: i, currentTime: n, seekTo: s} = t; - if (!i) - throw new Error("appendSourceBufferData null currentSbEntity"); - const a = (null == s ? void 0 : s.pos) || n; - let o = NaN; - i.forEach((e,t)=>{ - if (e) { - e = qp.getBufferedInfo(e.bufferedRanges, a, 0); - if (0 === e.len) { - const i = e["nextStart"]; - r.warn(`sb[${Pl[t]}] jagged start: ${i} current=${o}`), - ne(i) && (!ne(o) || o < i) && (o = i) - } - } - } - ), - ne(o) && (r.warn(`[seek] jagged start, adjusting currentTime:${n.toFixed(3)} seekTo=${null === (e = null == s ? void 0 : s.pos) || void 0 === e ? void 0 : e.toFixed(3)}->${o}`), - this.seekTo = o) - } - addCues(e, t) { - const i = this.mediaElement.textTracks[e]; - i && t.forEach(e=>{ - i.addCue(e) - } - ) - } - _flushInternal(e, t, i) { - return Yr(()=>e.remove(t, i)).pipe(Ja(()=>{} - )) - } - flushAll(i, r, n=!1) { - return 0 === this.sourceBuffers.length ? Ul : Jr(this.sourceBuffers.map((e,t)=>e ? this.flushData(t, i, r, n) : Ul)).pipe(Js(void 0)) - } - flushData(o, d, l, u=!1) { - const {mediaQuery: t, logger: c} = this; - return $l(t.updating$, e=>!1 === e).pipe(Ra(()=>{ - var e = t["sourceBufferEntities"] - , e = e[o]; - null != e && e.updating && this.logger.warn(`trying to flush while updating ${o}`); - const r = this.sourceBuffers[o]; - let n, s, a = Ul; - e = -1 === navigator.userAgent.toLowerCase().indexOf("firefox"); - if (this.flushing = !0, - e) - return this._flushInternal(r, d, l); - for (let i = 0; i < r.buffered.length; i++) { - let e, t; - n = r.buffered.start(i), - s = r.buffered.end(i), - t = l === 1 / 0 ? (e = d, - l) : (e = Math.max(n, d), - Math.min(s, l)), - Math.min(t, s) > e && (u || .5 < Math.min(t, s) - e) ? a = a.pipe(Ua(this._flushInternal(r, e, t))) : c.warn(`ignoring sb[${Pl[o]}] flush ${e},${t}`) - } - return a - } - ), $s(()=>{ - this.flushing = !1 - } - )) - } - static convertInitSegToCompatInfo(e) { - return { - mimeType: e.mimeType, - audioCodec: e.initParsedData.audioCodec, - videoCodec: e.initParsedData.videoCodec, - startPTSSec: void 0, - endPTSSec: void 0, - discoSeqNum: e.discoSeqNum, - mediaOptionId: e.mediaOptionId - } - } - static combineAppendDataInfoWithCompatInfo(e, t, i, r=0) { - const n = [...t]; - e.forEach((e,t)=>null != e && e.initSeg ? n[t] = hf.convertInitSegToCompatInfo(e.initSeg) : null); - t = n[cl.Variant].videoCodec, - e = Vp(t); - if (i && i.has(e)) { - const s = i.get(e); - n[cl.Variant].mimeType = n[cl.Variant].mimeType.replace(t, s), - n[cl.Variant].videoCodec = s - } - return n - } - convertSourceBufferEntitiesToCompatInfo(e) { - const t = e.sourceBufferEntities - , i = [null, null]; - return t.forEach((e,t)=>{ - e && (i[t] = { - mimeType: e.mimeType, - audioCodec: e.audioCodec, - videoCodec: e.videoCodec, - startPTSSec: void 0, - endPTSSec: void 0, - discoSeqNum: void 0, - mediaOptionId: null === (e = e.initSegmentInfo) || void 0 === e ? void 0 : e.mediaOptionId - }) - } - ), - i - } - appendData(e, t, i) { - const {mediaQuery: r, logger: n} = this - , o = this.convertSourceBufferEntitiesToCompatInfo(r); - return e.every(e=>null == e) ? Bi([]) : this.resetMediaSourceIfNeeded(e).pipe(Ra(e=>e ? r.updating$.pipe(an(e=>!1 === e), Cs(1), Js(e)) : Bi(null)), Ra(e=>{ - if (!e) - return Bi([]); - let s = NaN - , a = NaN; - if (this.needSourceBuffers) { - s = performance.now(); - const t = hf.combineAppendDataInfoWithCompatInfo(e, o, i, n); - this.createSourceBuffers(t), - a = performance.now(), - this.clearFlush(e) - } - return e.forEach(e=>{ - e = null == e ? void 0 : e.dataSeg; - null != e && e.cues && ne(null == e ? void 0 : e.texttrackIdx) && this.addCues(e.texttrackIdx, e.cues) - } - ), - this.setStoreSbTimeoffsets(e), - Xr(Yr(()=>this.appendInitSegments(e, t)), Yr(()=>this.appendDataSegments(e, t))).pipe(function(r, i) { - return 2 <= arguments.length ? function(e) { - return Ft(na(r, i), Qs(1), (void 0 === (t = i) && (t = null), - function(e) { - return e.lift(new es(t)) - } - ))(e); - var t - } - : function(e) { - return Ft(na(function(e, t, i) { - return r(e, t) - }), Qs(1))(e) - } - }((e,t)=>(e.push(t), - e), new Array), ur(([i,r])=>{ - const n = [null, null]; - return [cl.Variant, cl.AltAudio].forEach(e=>{ - var t; - null != (null == i ? void 0 : i[e]) && (t = { - fragmentType: Rl(e), - bufferCreationStart: s, - bufferCreationEnd: a, - startInitAppend: i[e].startAppend, - endInitAppend: i[e].endAppend, - initBytesAppend: i[e].bytesAppend, - startDataAppend: r[e].startAppend, - endDataAppend: r[e].endAppend, - dataBytesAppend: r[e].bytesAppend - }, - n[e] = t) - } - ), - n - } - ), Ja(e=>{ - this.adjustJaggedStart() - } - )) - } - ), Cs(1)) - } - endStream() { - try { - this.mediaSourceAdapter.endOfStream() - } catch (e) { - this.logger.warn(`endOfStream failed: ${e.message}`) - } - } - setMediaKeys(e) { - const t = this.mediaElement; - return t.done$ || (t.done$ = new gi(!1)), - nn(Ul, t.done$).pipe(Ra(()=>!0 === t.updating ? Ti : t.mediaKeys === e ? Ul : (t.updating = !0, - Lr(t.setMediaKeys(e).then(()=>{ - t.updating = !1, - t.done$.next(!0) - } - ).catch(e=>{ - throw t.updating = !1, - t.done$.next(!0), - e - } - )))), Cs(1), Ja(()=>{} - ), ya(e=>e.pipe(Kr((e,t)=>{ - if (t < 3) - return vn(100 * t); - throw e - } - ))), wa()) - } - clearMediaKeys(i) { - return Yr(()=>{ - if (!this.mediaElement) - return Ul; - const e = -1 < navigator.userAgent.toLowerCase().indexOf("chrome") - , t = this.mediaElement.src; - return e && (this.mediaElement.src = ""), - i ? this.setMediaKeys(null).pipe(qn(()=>(this.mediaElement.src = t, - Ul))) : nn(Lr(this.mediaElement.setMediaKeys(null)).pipe(qn(()=>(this.mediaElement.src = t, - Ul))), Ul) - } - ) - } - set autoPausedRestartTime(e) { - this.mediaElementStore.autoPausedRestartTime = e - } - set seekTo(e) { - this.mediaElementStore.setSeekToPos(e, !1) - } - set skip(e) { - this.seekTo = this.mediaElement.currentTime + e - } - nudgeSeek(e, t) { - sd(()=>{ - this.mediaElementStore.setSeekToPos(e, !1), - this.mediaElementStore.setNudgeInfo({ - nudgeTarget: e, - nudgeCount: t - }) - } - ) - } - set desiredRate(e) { - this.mediaElementStore.desiredRate = e - } - toggleTrickPlaybackMode(e) { - if (this.config.overridePlaybackRate) { - const t = e ? 2 : 1; - try { - this.mediaElement.playbackRate = t - } catch (e) { - this.logger.error({ - name: "iframes" - }, `Exception when setting playbackRate=${t}: ${e.message}`) - } - } - const t = this.muteValueOnTrickPlaybackToggle; - e && void 0 === t ? (this.muteValueOnTrickPlaybackToggle = this.mediaElement.muted, - this.mediaElement.muted = e) : e || void 0 === t || (this.mediaElement.muted = t, - this.muteValueOnTrickPlaybackToggle = void 0) - } - play() { - this.mediaFunctions.play() - } - pause() { - this.mediaFunctions.pause() - } - get expectPlayEvent() { - return this.mediaFunctions.expectPlayEvent - } - set expectPlayEvent(e) { - this.mediaFunctions.expectPlayEvent = e - } - get expectPauseEvent() { - return this.mediaFunctions.expectPauseEvent - } - set expectPauseEvent(e) { - this.mediaFunctions.expectPauseEvent = e - } - set textTracksCreated(e) { - const t = this["mediaElementStore"]; - t.textTracksCreated = e - } - get msDuration() { - return this._mediaQuery.msDuration - } - set msDuration(e) { - try { - const t = this["mediaElementStore"] - , i = this.mediaSource$.value; - i.duration !== e && (i.duration = e, - t.msDuration = e) - } catch (e) { - this.logger.warn(`Error setting duration ${e.message}`) - } - } - set haveEnough(e) { - this.mediaElementStore.haveEnough = e - } - set flushing(e) { - this.mediaElementStore.flushing = e - } - set bufferMonitorTargetDuration(e) { - this.mediaElementStore.bufferMonitorTargetDuration = e - } - get textTracks() { - return this.mediaElement.textTracks - } - addTextTrack(e, t, i) { - return this.mediaElement.addTextTrack(e, t, i) - } - dispatchEvent(e) { - return this.mediaElement.dispatchEvent(e) - } - get offsetWidth() { - return this.mediaElement.offsetWidth - } - get offsetHeight() { - return this.mediaElement.offsetHeight - } - archiveParsedSubtitleFragmentRecord(e, t, i) { - return this.mediaElementStore.archiveParsedSubtitleFragmentRecord(e, t, i) - } - updateLiveSeekableRange(e) { - var t = e.fragments - , e = t.length; - if (1 < e) { - const i = t[0].start - , r = t[e - 1].start + t[e - 1].duration; - this.mediaSource$.value.updateLiveSeekableRange(i, r) - } - } - clearLiveSeekableRange() { - this.mediaSource$.value.clearLiveSeekableRange() - } - } - const pf = (r,n,s,a,o,d,i)=>e=>e.pipe(Ra(t=>{ - if (!t) - return Ti; - const e = wc(t); - return nn(e.event("durationchange").pipe(ur(e=>Ac(t, "durationchange", e)), Ja(e=>{ - e = e.currentTarget; - r.mediaElementDuration = e.duration - } - )), e.event("seeking").pipe(so(o.seekEventThrottleMs), ur(e=>Ac(t, "seeking", e)), Ja(e=>{ - var t = e.currentTarget - , e = t.currentTime; - if (t.readyState >= t.HAVE_METADATA) { - const i = n.seekTo; - !i || !i.fromEvent && 1e-5 < Math.abs(i.pos - e) ? a.inGaplessMode ? function(e, t, i, r, n) { - let s = !1; - e < t.playingItem.itemStartOffset && (n.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${t.playingItem.itemStartOffset}`), - e = t.playingItem.itemStartOffset, - s = !0), - t.isPreloading && (e > t.loadingItem.itemStartOffset && (n.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${t.loadingItem.itemStartOffset}`), - e = t.loadingItem.itemStartOffset, - s = !0), - t.dequeueSource("SeekToUnbufferedTimeRanges")), - s ? i.resetMediaSource(e) : r.setSeekToPos(e, !0) - }(e, a, s, r, d) : r.setSeekToPos(e, !0) : r.seeking = !0 - } - } - )), e.event("seeked").pipe(ur(e=>Ac(t, "seeked", e)), Ja(()=>{ - r.setSeekToPos(null, !0) - } - )), e.event("play").pipe(ur(e=>Ac(t, "play", e)), So(n.desiredRate$), ur(([e])=>{ - var t = e.currentTarget; - r.paused = t.paused; - var i = s.expectPlayEvent - , t = t.controls || o.nativeControlsEnabled; - return !i && t && (s.checkForReplay(), - r.desiredRate = 1), - s.expectPlayEvent = !1, - e - } - )), e.event("playing").pipe(ur(e=>Ac(t, "playing", e)), Ja(e=>{ - e = e.currentTarget; - r.paused = e.paused, - r.gotPlayingEvent() - } - )), e.event("loadstart").pipe(ur(e=>Ac(t, "loadstart", e)), Ja(()=>{ - r.gotLoadStartEvent() - } - )), e.event("pause").pipe(ur(e=>Ac(t, "pause", e)), Ja(e=>{ - var t = e.currentTarget; - r.paused = t.paused; - e = s.expectPauseEvent, - t = t.controls || o.nativeControlsEnabled; - !e && t && (r.desiredRate = 0), - s.expectPauseEvent = !1 - } - )), e.event("loadedmetadata").pipe(ur(e=>Ac(t, "loadedmetadata", e))), e.event("loadeddata").pipe(ur(e=>Ac(t, "loadeddata", e))), e.event("canplay").pipe(ur(e=>Ac(t, "canplay", e))), e.event("canplaythrough").pipe(ur(e=>Ac(t, "canplaythrough", e))), e.event("waiting").pipe(ur(e=>Ac(t, "waiting", e))), e.event("emptied").pipe(ur(e=>Ac(t, "emptied", e))), e.event("error").pipe(ur(e=>Ac(t, "error", e)), qn(e=>Ui(t.error))), e.event("ended").pipe(ur(e=>Ac(t, "ended", e)))).pipe(So(n.bufferedRangeTuple$), od(([e])=>{ - var t = e.currentTarget - , e = t.readyState; - r.readyState = e, - r.ended = t.ended - } - ), Un(e=>(e instanceof MediaError ? (d.warn(`mediaElementError, code: ${e.code}, message: ${e.message}`), - null == i || i.handleMediaElementError(e)) : d.error(`media event error: ${e.message}`), - Ti))) - } - ), Ra(()=>Ti)); - function ff(e, t, i, r, n, s) { - const a = null == e ? void 0 : e.bufferedSegments; - if (!a) - return s.warn("getMatchingInfo trying to query null sbEntity"), - null; - let o = a.find(e=>t >= e.startPTS && t < e.endPTS && e.frag.discoSeqNum === i); - if (!o) { - const e = a[0] && Math.abs(+a[0].startPTS) < r ? a[0] : void 0; - e && t < e.startPTS && i === e.frag.discoSeqNum && (o = e) - } - if (null == o) - return null; - { - const {audioCodec: t, videoCodec: r, mimeType: s} = e; - return { - mimeType: s, - audioCodec: t, - videoCodec: r, - startPTSSec: o.startPTS, - endPTSSec: o.endPTS, - discoSeqNum: i, - mediaOptionId: n - } - } - } - const mf = new class extends pd { - constructor() { - super({}, { - name: "media-element-store", - producerFn: vc - }), - this._activeId = "" - } - get activeId() { - return this._activeId - } - startMediaSession(i, r, n, s) { - return Co("playback.session.start"), - this._activeId = `media session: ${(new Date).toISOString()}`, - sd(()=>{ - var e = s - , t = Math.max(e, r - e) - , t = { - id: this.activeId, - desiredRate: !i.autoplay && i.paused ? 0 : 1, - paused: i.paused, - gotPlaying: !1, - gotLoadStart: !1, - seeking: i.seeking, - flushing: !1, - readyState: i.readyState, - ended: i.ended, - bufferedRanges: [], - haveEnough: !1, - mediaSourceEntity: null, - expectedSbCount: NaN, - bufferMonitorInfo: { - waterLevelType: null, - almostDryWaterLevelSeconds: n, - lowWaterLevelSeconds: e, - highWaterLevelSeconds: t, - maxBufferSeconds: r - }, - mediaOptionParsedSubtitleRecord: [], - textTracksCreated: !1, - waitingForDisco: !1 - }; - this.add(t), - this.setActive(this.activeId) - } - ), - this.activeId - } - setMediaSourceEntity(t, i) { - Co("playback.set.msObjectUrl"), - this.updateActive(e=>{ - e.mediaSourceEntity = null != t && null != i ? { - objectUrl: t, - readyState: i, - duration: NaN, - sourceBufferEntities: [null, null] - } : null, - e.bufferedRanges = [], - e.haveEnough = !1, - e.readyState = 0, - e.bufferMonitorInfo.waterLevelType = null - } - ) - } - set mediaElementDuration(t) { - Co("playback.set.mediaElementDuration"), - this.updateActive(e=>{ - e && (e.mediaElementDuration = t) - } - ) - } - set msReadyState(t) { - Co("playback.set.msReadyState"), - this.updateActive(({mediaSourceEntity: e})=>{ - e && (e.readyState = t) - } - ) - } - set readyState(t) { - Co(`playback.set.readyState ${t}`), - this.updateActive(e=>{ - e.readyState = t - } - ) - } - set ended(t) { - Co(`playback.set.ended ${t}`), - this.updateActive(e=>{ - e.ended = t - } - ) - } - set msDuration(t) { - Co("playback.set.msDuration"), - this.updateActive(e=>{ - e.mediaSourceEntity.duration = t - } - ) - } - set textTracksCreated(t) { - Co("playback.set.textTracksCreated ${created}"), - this.updateActive(e=>{ - e.textTracksCreated = t - } - ) - } - set expectedSbCount(t) { - Co("playback.set.expectedSbCount"), - this.updateActive(e=>{ - e.expectedSbCount = t - } - ) - } - set autoPausedRestartTime(e) { - this.updateActive({ - autoPausedRestartTime: e - }) - } - setSeekToPos(t, i) { - Co(`playback.set.seekToPos: ${null == t ? void 0 : t.toFixed(3)}`), - this.updateActive(e=>{ - ne(t) ? (e.seekTo = { - pos: t, - fromEvent: i - }, - e.gotPlaying = !1, - e.haveEnough = !1) : e.seekTo = null, - i && (e.seeking = ne(t)) - } - ) - } - set seeking(t) { - Co(`playback.set.seeking: ${t}`), - this.updateActive(e=>{ - e.seeking = t - } - ) - } - set paused(t) { - Co(`playback.set.paused: ${t}`), - this.updateActive(e=>{ - (e.paused = t) && (e.gotPlaying = !1) - } - ) - } - gotPlayingEvent() { - Co("playback.set.playing"), - this.updateActive(e=>{ - e.paused || (e.gotPlaying = !0) - } - ) - } - gotLoadStartEvent() { - Co("playback.set.loadstart"), - this.updateActive(e=>{ - e.gotLoadStart = !0 - } - ) - } - set desiredRate(t) { - Co(`playback.set.desiredRate: ${t}`), - this.updateActive(e=>{ - e.desiredRate = t - } - ) - } - set haveEnough(t) { - Co(`playback.set.haveEnough: ${t}`), - this.updateActive(e=>{ - e.haveEnough = t - } - ) - } - set flushing(e) { - Co(`playback.set.flushing: ${e}`), - this.updateActive({ - flushing: e - }) - } - set waitingForDisco(t) { - Co(`playback.set.waitingForDisco: ${t}`), - this.updateActive(e=>{ - e && (e.waitingForDisco = t) - } - ) - } - setSourceBufferUpdating(i) { - Co(`playback.set.sourcebuffers[${Pl[i]}].updating`), - this.updateActive(({mediaSourceEntity: e})=>{ - const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; - t && (t.updating = !0, - t.error = void 0) - } - ) - } - setTimestampOffset(i, r) { - Co(`playback.set.sourcebuffers[${Pl[i]}].timestampOffset`), - this.updateActive(({mediaSourceEntity: e})=>{ - const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; - t && (t.timestampOffset = r) - } - ) - } - setBufferedRangesUpdated(n, s, a, o, d) { - Co(`playback.set.sourcebuffers[${Pl[n]}].bufferupdated`), - this.updateActive(e=>{ - var t; - const i = null == e ? void 0 : e.mediaSourceEntity - , r = null === (t = null == i ? void 0 : i.sourceBufferEntities) || void 0 === t ? void 0 : t[n]; - if (r) { - const n = null == i ? void 0 : i.duration; - r.updating = !1, - r.bufferedRanges = [...s], - function(e, t, i, r) { - const n = e.inFlight - , s = e.bufferedSegments; - n && ne(n.startPTS) && ne(n.endPTS) && function(t, i) { - let r = !1; - for (let e = t.length - 1; -1 < e; e--) { - const s = t[e] - , a = Math.max(i.startPTS, s.startPTS) - , o = Math.min(i.endPTS, s.endPTS); - var n; - o <= a || ((n = (1 - (o - a) / (s.endPTS - s.startPTS)) * s.bytes) <= 0 ? t.splice(e, 1) : (s.bytes = n, - s.startPTS < i.startPTS ? s.endPTS = a : (s.startPTS = o, - r || (t.splice(e, 0, i), - r = !0)))) - } - r || t.push(i) - }(s, n); - const a = e.bufferedRanges; - let o, d = 0; - for (let e = s.length - 1; -1 < e; e--) { - const t = s[e] - , n = !t.frag.iframe; - n && t.frag.isLastFragment && (o = t.frag); - var l = t.endPTS - t.startPTS; - if (l <= 0) - s.splice(e, 1); - else { - var u = a.find(e=>e.start <= t.endPTS && e.end > t.startPTS); - if (u) { - const a = Math.max(u.start, t.startPTS) - , o = Math.min(u.end, t.endPTS) - , c = o - a; - if (d += t.bytes * c / l, - n) - if (c < Math.min(l, i)) - s.splice(e, 1); - else { - const n = t.appendedDuration; - n ? !(n > c && c != l) || t.frag.isLastFragment && o === r || s.splice(e, 1) : t.appendedDuration = c - } - } else - s.splice(e, 1) - } - } - e.totalDuration = o && 0 < a.length ? a[a.length - 1].end : 1 / 0, - e.inFlight = null, - e.gotQuotaExceeded = e.gotQuotaExceeded || t, - e.totalBytes = d, - e.maxTotalBytes = Math.max(e.totalBytes, e.maxTotalBytes) - }(r, o, d, n) - } - e.bufferedRanges = [...a] - } - ) - } - setSourceBufferEntity(n, s) { - Co(`playback.set.sourcebuffers[${Pl[n]}].setSourceBufferEntity`), - this.updateActive(({mediaSourceEntity: e})=>{ - var t, i, r; - e && ({mimeType: t, audioCodec: i, videoCodec: r} = s, - e.sourceBufferEntities[n] = { - mimeType: t, - audioCodec: i, - videoCodec: r, - updating: !1, - bufferedRanges: [], - timestampOffset: 0, - inFlight: null, - bufferedSegments: [], - totalBytes: 0, - maxTotalBytes: 0, - gotQuotaExceeded: !1, - totalDuration: 1 / 0 - }) - } - ) - } - setInflightSegment(i, r) { - Co(`playback.set.sourcebuffers[${Pl[i]}].setInflightSegment`), - this.updateActive(({mediaSourceEntity: e})=>{ - const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; - t && (t.inFlight = r) - } - ) - } - setInitSegmentEntity(i, r) { - Co(`playback.set.sourcebuffers[${Pl[i]}].setInitSegmentEntity`), - this.updateActive(({mediaSourceEntity: e})=>{ - const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; - t && (t.initSegmentInfo = r) - } - ) - } - setSourceBufferError(i, r) { - Co(`playback.set.sourcebuffers[${i}].error: ${r}`), - this.updateActive(({mediaSourceEntity: e})=>{ - const t = null === (e = null == e ? void 0 : e.sourceBufferEntities) || void 0 === e ? void 0 : e[i]; - t && (t.inFlight = null, - t.updating = !1, - t.error = r) - } - ) - } - setStallInfo(t) { - Co(`playback.set.stallInfo stalled=${null != t}`), - this.updateActive(e=>{ - e.stallInfo = t - } - ) - } - setNudgeInfo(t) { - Co(`playback.set.nudgeInfo ${se(t)}`), - this.updateActive(e=>{ - e.nudgeInfo = t - } - ) - } - updateWaterLevels(t, i) { - Co("playback.set.updateWaterLevels"), - this.updateActive(e=>{ - e.bufferMonitorInfo.waterLevelType = { - combined: t, - sbTuple: [...i] - } - } - ) - } - set bufferMonitorTargetDuration(i) { - Co(`playback.set.targetDuration: ${i}`), - this.updateActive(e=>{ - if (ne(i) && 0 < i) { - const t = e.bufferMonitorInfo; - t.lowWaterLevelSeconds = Math.min(i, t.maxBufferSeconds), - t.highWaterLevelSeconds = Math.max(t.lowWaterLevelSeconds, t.maxBufferSeconds - i) - } - } - ) - } - archiveParsedSubtitleFragmentRecord(i, r, n) { - Co(`playback.cues.set persistentId ${i} mediaSeqNum ${r}: parsed ${n.count} time-range ${n.startTime}:${n.endTime}`), - this.updateActive(e=>{ - let t = e.mediaOptionParsedSubtitleRecord[i]; - t || (t = {}, - e.mediaOptionParsedSubtitleRecord[i] = t), - t[r] = n - } - ) - } - } - ; - class gf extends Si { - constructor(e) { - super(e), - this.store = e, - this.displaySupportsHdr$ = this.select("supportsHdr"), - this.platformInfo$ = this.select("platformInfo"), - this.viewportInfo$ = this.select("viewportInfo") - } - get platformInfo() { - return this.getValue().platformInfo - } - get displaySupportsHdr() { - return this.getValue().supportsHdr - } - get viewportInfo() { - return this.getValue().viewportInfo - } - } - class yf { - constructor(e) { - this.store = e - } - getQuery() { - return new gf(this.store) - } - updateSupportsHdr(t) { - this.store.update(e=>{ - e.supportsHdr = t - } - ) - } - updatePlatformInfo(e) { - this.store.update({ - platformInfo: e - }) - } - updateViewportInfo(t) { - this.store.update(e=>{ - e.viewportInfo = t - } - ) - } - } - const vf = new class extends dd { - constructor() { - super({ - supportsHdr: !0 - }, { - name: "platform", - producerFn: vc - }) - } - } - ; - let Sf = null; - function bf() { - return Sf = Sf || new yf(vf), - Sf - } - class Tf extends Ut { - constructor(e) { - super(), - this._vanillaRPC = e, - this._handler$ = new zt - } - _subscribe(e) { - return e.add(this._handler$.pipe(Kr(([e,t,i])=>e(...t).pipe(Ja({ - next(e) { - i(e, null) - }, - error(e) { - i(null, e) - } - })))).subscribe()), - ()=>{ - this.teardown() - } - } - register(e, i) { - return this._vanillaRPC.register(e, (...t)=>e=>{ - this._handler$.next([i, t, e]) - } - ) - } - invoke(e, t, r) { - return new Ut(i=>{ - this._vanillaRPC.invoke(e, t, r)((e,t)=>{ - null != t ? i.error(t) : (i.next(e), - i.complete()) - } - ) - } - ) - } - teardown() {} - } - class Ef extends Tf { - constructor(e) { - super(e) - } - decrypt(e, t, i, r, n) { - return this.invoke("decrypt", [e, t, i, r, n], [e, t, r]) - } - } - class If extends Tf { - constructor(e) { - super(e), - this.rpcService = e, - this.sessions = {}, - this._onEvent = (e,t,i)=>()=>{ - null != this.sessions[e] && this.sessions[e].observer.trigger(t, i) - } - , - this.rpcService.register("demuxer.event", this._onEvent) - } - teardown() { - this.rpcService.unregister("demuxer.event") - } - init(e, t, i) { - return [{maxSeekHole: r, maxBufferHole: n, audioPrimingDelay: s, stretchShortVideoTrack: a, forceKeyFrameOnDiscontinuity: o}] = [t], - this.invoke("demuxer.init", [e, t = { - maxSeekHole: r, - maxBufferHole: n, - audioPrimingDelay: s, - stretchShortVideoTrack: a, - forceKeyFrameOnDiscontinuity: o - }, i], []).pipe(ur(e=>{ - var t = new wf(this,e); - return this.sessions[e] = t - } - )); - var r, n, s, a, o - } - } - class wf { - constructor(e, t) { - this.rpc = e, - this.demuxSessionID = t, - this.observer = new a - } - push(e, t, i, r, n, s, a, o, d, l, u, c, h) { - return this.rpc.invoke("demuxer.push", [this.demuxSessionID, e, t, i, r, n, s, a, o, d, l, u, c], null != h ? h : [e]) - } - pushWithoutTransfer(e, t, i, r, n, s, a, o, d, l, u, c) { - return this.push(e, t, i, r, n, s, a, o, d, l, u, c, []) - } - destroy() { - this.observer.removeAllListeners(), - this.rpc.invoke("demuxer.destroy", [this.demuxSessionID], []).subscribe() - } - } - class Af { - constructor() { - this.handlers = {} - } - register(e, t) { - if (null != this.handlers[e]) - return !1; - this.handlers[e] = t - } - unregister(e) { - if (null != this.handlers[e]) - return !1; - delete this.handlers[e] - } - invoke(e, i) { - return (t=Af._fallbackCallback)=>{ - try { - if (null == this.handlers[e]) - throw new Error(`command ${e} not found`); - this.handlers[e](...i)(t) - } catch (e) { - t(void 0, e) - } - } - } - teardown() { - this.handlers = null - } - } - Af._fallbackCallback = (e,t)=>{ - if (null != t) - throw t - } - ; - const Of = e=>{ - e = e.child({ - name: "InlineRPCService" - }); - var t = new Af; - return new i(t,e), - new at(t,e), - t - } - ; - let kf; - const Cf = t=>{ - try { - return (e=>{ - try { - if (null == kf) { - const e = new Blob(["(" + Ky.toString() + ")(true);"],{ - type: "text/javascript" - }) - , r = URL.createObjectURL(e); - kf = new Worker(r) - } - var t = new ot(kf); - return i = t, - n = e.child({ - name: "WorkerRPCService" - }), - i.register("logger.log", (e,i,...r)=>t=>{ - try { - for (const i of e) - n = n.child(i); - "function" == typeof n[i] && n[i](...r), - t() - } catch (e) { - t(void 0, e) - } - } - ), - t - } catch (e) { - throw new Error("Failed to create WebWorker") - } - var i, n - } - )(t) - } catch (e) { - t.warn(e) - } - return Of(t) - } - ; - class Df { - } - Df.PlayEnded = 6101, - Df.Periodic = 6110, - Df.PlayStalled = 6103, - Df.KeySessionComplete = 6104, - Df.PlayLikelyToKeepUp = 6105, - Df.PlayRateChanged = 6106, - Df.PlayError = 6107, - Df.MediaEngineStalled = 6108, - Df.SwitchComplete = 6109, - Df.VariantEnded = 6111, - Df.NwError = 6202; - const Mf = { - avc1: 1, - avc3: 1, - hvc1: { - SDR: 2, - HLG: 10, - PQ: 11 - }, - hev1: { - SDR: 2, - HLG: 10, - PQ: 11 - }, - vp09: { - SDR: 3, - HLG: 14, - PQ: 13 - }, - dvh1: { - PQ: 12 - } - }; - class Pf { - constructor(e, t) { - this.query = e, - this.logger = t - } - setReportingAgent(e) { - this.reportingAgent = e - } - sendPlayEnded(e) { - var t = Df.PlayEnded; - this.fillAndFire(t, this.query.playEnded(e)) - } - sendPlayStalled(e) { - var t = Df.PlayStalled; - this.fillAndFire(t, this.query.playStalled(e)) - } - sendMediaEngineStalled(e) { - var t = Df.MediaEngineStalled; - this.fillAndFire(t, this.query.mediaEngineStalled(e)) - } - sendKeySessionComplete(e) { - var t = Df.KeySessionComplete; - this.fillAndFire(t, this.query.keySessionComplete(e)) - } - sendPlayLikelyToKeepUp(e) { - var t = Df.PlayLikelyToKeepUp; - this.fillAndFire(t, this.query.playLikelyToKeepUp(e)) - } - sendPlayRateChange(e) { - var t = Df.PlayRateChanged; - this.fillAndFire(t, this.query.playRateChanged(e)) - } - sendSwitchComplete(e) { - var t = Df.SwitchComplete; - this.fillAndFire(t, this.query.switchComplete(e)) - } - sendVariantEnded(e) { - var t = Df.VariantEnded; - this.fillAndFire(t, this.query.variantEnded(e)) - } - sendPlayError(e) { - var t = Df.PlayError; - this.fillAndFire(t, this.query.playError(e)) - } - sendNwError(e) { - var t = Df.NwError; - this.fillAndFire(t, this.query.nwError(e)) - } - sendPeriodic(e) { - var t = Df.Periodic; - this.fillAndFire(t, this.query.periodic(e)) - } - fillAndFire(e, t) { - var r = e === Df.PlayEnded || e === Df.Periodic ? 1 : 0; - if (this.reportingAgent) { - let i = {}; - Object.entries(t).forEach(([e,t])=>{ - "object" == typeof (t = ne(t) ? Number(Number(t).toFixed(2)) : t) ? "ServerInfo" === e && Object.entries(t).forEach(([e,t])=>{ - i[e] = t - } - ) : i[e] = t - } - ), - i = JSON.parse(JSON.stringify(i)); - try { - this.reportingAgent.issueReportingEvent(e, i, r) - } catch (e) {} - } - } - } - class xf extends Od { - constructor(e, t) { - super(e), - this.logger = t - } - get activeEntity() { - return this.getActive() - } - entity(e) { - return this.getEntity(e) - } - playEnded(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playEndedRecord - } - periodic(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.periodicRecord - } - playStalled(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playStalledRecord - } - mediaEngineStalled(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.mediaEngineStalledRecord - } - keySessionComplete(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.keySessionCompleteRecord - } - playLikelyToKeepUp(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playLikelyToKeepUpRecord - } - playRateChanged(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playRateChangedRecord - } - switchComplete(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.switchCompleteRecord - } - variantEnded(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.variantEndedRecord - } - playError(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.playErrorRecord - } - nwError(e) { - return null === (e = this.getEntity(e)) || void 0 === e ? void 0 : e.nwErrorRecord - } - } - class Rf extends pd { - constructor(e) { - super({}, { - name: "rtc-store", - idKey: "itemId", - producerFn: vc, - resettable: !0 - }), - this.logger = e - } - createEntity(e) { - e = { - itemId: e, - sessionControlRecord: { - state: "RTC_STATE_INIT", - rate: 0, - oldRate: 0, - eventStartTime: Date.now(), - sessionStartTime: Date.now(), - lastLikelyToKeepUpTime: Date.now(), - lastPeriodicTime: Date.now(), - playLikelyToKeepUpEventCounter: 1, - periodicEventCounter: 1, - activeKeySessions: {}, - intervalVariantList: {}, - sessionVariantList: {} - }, - playEndedRecord: {}, - periodicRecord: {}, - playStalledRecord: {}, - keySessionCompleteRecord: {}, - playLikelyToKeepUpRecord: {}, - playRateChangedRecord: {}, - playErrorRecord: {}, - mediaEngineStalledRecord: {}, - switchCompleteRecord: {}, - variantEndedRecord: {}, - nwErrorRecord: {} - }; - this.add(e) - } - updateEnded(e) { - this._prepareEventPlayEnded(e) - } - updatePeriodic(e, t) { - this._prepareEventPeriodic(e, { - isFinal: t - }) - } - updateBufferStalled(e, t) { - this.update(e, ({sessionControlRecord: e, variantEndedRecord: t, periodicRecord: i, playEndedRecord: r})=>{ - e.rate = 0, - t.StallCount = (t.StallCount || 0) + 1, - i.StallCount = (i.StallCount || 0) + 1, - r.StallCount = (r.StallCount || 0) + 1 - } - ), - this._prepareEventPlayStalled(e, t) - } - updateSegmentKeyLoaded(e, r) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = {} - , i = r.timestamp; - t.keyFormat = "identity", - t.keyDeliveryTime = r.adt, - t.currentMediaTime = r.currentTime, - "RTC_STATE_INIT" === e.state && (t.keyInitTime = i - e.sessionStartTime), - e.activeKeySessions[r.keyuri] = t - } - ), - this._prepareEventKeySessionComplete(e, r) - } - updateLicenseResponseProcessed(e, i) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = e.activeKeySessions[i.keyuri]; - t.licenseResponseProcessTime = i.timestamp - t.licenseResponseSubmitTime, - e.lastKeyDeliveryTime = t.keyDeliveryTime = i.timestamp - t.licenseChallengeStartTime, - t.currentMediaTime = i.currentTime, - e.finishedKeyUri = i.keyuri - } - ), - this._prepareEventKeySessionComplete(e, i) - } - updateLicenseChallengeError(e, i) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = e.activeKeySessions[i.keyuri]; - e.lastKeyErrorType = t.keyErrorType = "licenseChallengeError", - e.finishedKeyUri = i.keyuri - } - ), - this._prepareEventKeySessionComplete(e, i) - } - updateLicenseResponseError(e, i) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = e.activeKeySessions[i.keyuri]; - e.lastKeyErrorType = t.keyErrorType = "licenseResponseError", - e.finishedKeyUri = i.keyuri - } - ), - this._prepareEventKeySessionComplete(e, i) - } - updateKeyAborted(e, t) { - this.update(e, ({sessionControlRecord: e})=>{ - e.activeKeySessions[t.keyuri].keyErrorType = "keyAborted", - e.finishedKeyUri = t.keyuri - } - ), - this._prepareEventKeySessionComplete(e, t) - } - updateCanPlay(e, t) { - this.update(e, ({})=>{} - ), - this._prepareEventPlayLikelyToKeepUp(e, t) - } - updateRateChanged(e, t) { - this.update(e, ({sessionControlRecord: e})=>{ - e.rate = 100 * t.rate, - 0 < t.rate && 0 === e.oldRate && (e.playInfo || (e.playInfo = []), - e.playInfo.push({ - latency: t.latency - }), - e.curLevelUrl || (e.curLevelUrl = t.url)) - } - ), - this._prepareEventPlayRateChanged(e, t) - } - updateMediaError(e, r) { - this.update(e, ({sessionControlRecord: e, periodicRecord: t, playEndedRecord: i})=>{ - t.PlayerErrCount = (t.PlayerErrCount || 0) + 1, - i.PlayerErrCount = (i.PlayerErrCount || 0) + 1, - r.fatal && (e.rate = 0, - t.FatalPlayerErrCount = (t.FatalPlayerErrCount || 0) + 1, - i.FatalPlayerErrCount = (i.FatalPlayerErrCount || 0) + 1, - i.ErrCode = r.details, - i.ErrReason = r.code, - i.ErrIsFatal = !0, - i.ErrDomain = "mediaError") - } - ), - r.fatal ? this._prepareEventPlayError(e, r) : this.update(e, ({sessionControlRecord: e})=>{ - var t = r.details + "/" + r.code; - e.nonFatalPlayErrList[t] = (e.nonFatalPlayErrList[t] || 0) + 1 - } - ) - } - updateMediaElementError(e, t) { - let i; - try { - i = JSON.parse(t.message) - } catch (e) { - this.logger.warn(`message is not JSON, ignoring; ${t.message}`) - } - var r = i ? parseInt(i.ErrReason) : null - , n = i ? parseInt(i.ErrDetail) : null; - this._prepareEventPlayError(e, { - domain: "mediaElementError", - mediaElemCode: t.code, - mediaElemReason: r, - mediaElemDetail: n, - code: null, - details: null, - fatal: null - }) - } - updateMediaEngineStalled(e, t) { - this.update(e, ({sessionControlRecord: e, variantEndedRecord: t, periodicRecord: i, playEndedRecord: r})=>{ - e.rate = 0, - t.MediaEngineStallCount = (t.MediaEngineStallCount || 0) + 1, - i.MediaEngineStallCount = (i.MediaEngineStallCount || 0) + 1, - r.MediaEngineStallCount = (r.MediaEngineStallCount || 0) + 1 - } - ), - this._prepareEventMediaEngineStalled(e, t) - } - updateLevelSwitched(e, l) { - this.update(e, ({sessionControlRecord: e, switchCompleteRecord: t, periodicRecord: i, playEndedRecord: r})=>{ - i.SwCnt = (i.SwCnt || 0) + 1, - r.SwCnt = (r.SwCnt || 0) + 1; - var n = Date.now() - , s = e.curLevelUrl - , a = l.url - , i = this._getVariantInfo(s, e) - , r = this._getVariantInfo(a, e); - let o, d = !1; - s && (o = r.bandwidth < i.bandwidth ? "Down" : "Up", - d = r.iframes), - t.BadSw = this._isBadSw(o, e.lastSwitchDir || o, d, e.lastLevelIsIframe || d, n, e.lastSwitchTime || n, l.isSeeking), - e.lastSwitchDir = o, - e.lastSwitchTime = n, - e.lastLevelIsIframe = d, - e.curLevelUrl = a, - e.variantStartTimeMedia = l.currentTime - } - ), - this._prepareEventSwitchComplete(e, l) - } - updateLevelLoadError(e, o) { - this.update(e, ({sessionControlRecord: e, switchCompleteRecord: t, periodicRecord: i, playEndedRecord: r})=>{ - var n = Date.now(); - let s, a = !1; - if (e.curLevelUrl) { - const t = this._getVariantInfo(e.curLevelUrl, e) - , i = this._getVariantInfo(o.url, e); - s = i.bandwidth < t.bandwidth ? "Down" : "Up", - a = i.iframes - } - i.SwCnt = (i.SwCnt || 0) + 1, - r.SwCnt = (r.SwCnt || 0) + 1, - t.BadSw = this._isBadSw(s, e.lastSwitchDir || s, a, e.lastLevelIsIframe || a, n, e.lastSwitchTime || n, o.isSeeking), - t.SwFail = !0 - } - ), - this._prepareEventSwitchComplete(e, o) - } - updateVariantEnd(e, t) { - this._prepareEventVariantEnded(e, t) - } - updateNwError(e, r) { - this.update(e, ({sessionControlRecord: e, periodicRecord: t, playEndedRecord: i})=>{ - t.NwErrCount = (t.NwErrCount || 0) + 1, - i.NwErrCount = (i.NwErrCount || 0) + 1, - r.fatal && (e.rate = 0, - t.FatalNwErrCount = (t.FatalNwErrCount || 0) + 1, - i.FatalNwErrCount = (i.FatalNwErrCount || 0) + 1, - i.ErrCode = r.details, - i.ErrReason = r.code, - i.ErrIsFatal = !0, - i.ErrDomain = "networkError") - } - ), - r.fatal ? this._prepareEventNwError(e, r) : this.update(e, ({sessionControlRecord: e})=>{ - var t = r.details + "/" + r.code; - e.nonFatalNwErrList[t] = (e.nonFatalNwErrList[t] || 0) + 1 - } - ) - } - finalize(e, t) { - switch (t) { - case Df.PlayEnded: - this.update(e, ({sessionControlRecord: e})=>{ - e.state = "RTC_STATE_STOP", - e.oldRate = 0 - } - ), - this.update(e, e=>{ - e.playEndedRecord = {} - } - ); - break; - case Df.Periodic: - this.update(e, ({sessionControlRecord: t})=>{ - t.lastPeriodicTime = Date.now(), - t.periodicEventCounter += 1, - Object.keys(t.intervalVariantList).forEach(e=>{ - t.intervalVariantList[e].playTime = 0 - } - ) - } - ), - this.update(e, e=>{ - e.periodicRecord = {} - } - ); - break; - case Df.PlayStalled: - this.update(e, ({sessionControlRecord: e})=>{ - e.state = "RTC_STATE_STALL", - e.oldRate = 0 - } - ), - this.update(e, e=>{ - e.playStalledRecord = {} - } - ); - break; - case Df.KeySessionComplete: - this.update(e, ({sessionControlRecord: e})=>{ - delete e.activeKeySessions[e.finishedKeyUri] - } - ), - this.update(e, e=>{ - e.keySessionCompleteRecord = {} - } - ); - break; - case Df.PlayLikelyToKeepUp: - this.update(e, ({sessionControlRecord: e})=>{ - "RTC_STATE_PLAY" !== e.state && (e.state = "RTC_STATE_CANPLAY", - e.lastLikelyToKeepUpTime = Date.now(), - e.playLikelyToKeepUpEventCounter += 1) - } - ), - this.update(e, e=>{ - e.playLikelyToKeepUpRecord = {} - } - ); - break; - case Df.PlayRateChanged: - this.update(e, ({sessionControlRecord: e, playEndedRecord: t, playStalledRecord: i, mediaEngineStalledRecord: r, playErrorRecord: n, nwErrorRecord: s})=>{ - 0 !== e.rate ? (e.state = "RTC_STATE_PLAY", - delete t.LastStall, - delete t.LastMediaEngineStall, - delete t.LastPause, - delete n.LastPause, - delete s.LastPause) : (e.state = "RTC_STATE_PAUSE", - delete i.LastResume, - delete r.LastResume, - delete n.LastResume, - delete s.LastResume), - e.oldRate = e.rate - } - ), - this.update(e, e=>{ - e.playRateChangedRecord = {} - } - ); - break; - case Df.PlayError: - this.update(e, ({sessionControlRecord: e})=>{ - e.state = "RTC_STATE_PLAYERROR" - } - ), - this.update(e, e=>{ - e.playErrorRecord = {} - } - ); - break; - case Df.MediaEngineStalled: - this.update(e, ({sessionControlRecord: e})=>{ - e.state = "RTC_STATE_MEDIAENGINESTALL", - e.oldRate = 0 - } - ), - this.update(e, e=>{ - e.mediaEngineStalledRecord = {} - } - ); - break; - case Df.SwitchComplete: - this.update(e, e=>{ - e.switchCompleteRecord = {}, - e.sessionControlRecord.prevLevelUrl = e.sessionControlRecord.curLevelUrl - } - ); - break; - case Df.VariantEnded: - this.update(e, ({sessionControlRecord: e})=>{ - e.decodedFramesForVariant = 0, - e.decodedFramesForVariantSampleCount = 0 - } - ), - this.update(e, e=>{ - e.variantEndedRecord = {} - } - ); - break; - case Df.NwError: - this.update(e, ({sessionControlRecord: e})=>{ - e.state = "RTC_STATE_NWERROR" - } - ), - this.update(e, e=>{ - e.nwErrorRecord = {} - } - ) - } - this.update(e, ({sessionControlRecord: e})=>{ - e.eventStartTime = Date.now() - } - ) - } - updatePlaybackInfo(e, s) { - this.update(e, ({sessionControlRecord: e, periodicRecord: t, playEndedRecord: i})=>{ - s.droppedVideoFrames < e.droppedVideoFrames && (e.droppedVideoFrames = 0), - s.decodedFrameCount < e.decodedFrameCount && (e.decodedFrameCount = 0); - var r = s.droppedVideoFrames - (e.droppedVideoFrames || 0) - , n = s.decodedFrameCount - (e.decodedFrameCount || 0); - e.droppedVideoFrames = s.droppedVideoFrames, - e.decodedFrameCount = s.decodedFrameCount, - e.decodedFramesForVariant += n, - e.decodedFramesForVariantSampleCount += 1, - r && (3 <= r ? (t.GroupViFrDr = (t.GroupViFrDr || 0) + r, - t.GroupViFrDrEvtCount = (t.GroupViFrDrEvtCount || 0) + 1, - i.GroupViFrDr = (i.GroupViFrDr || 0) + r, - i.GroupViFrDrEvtCount = (i.GroupViFrDrEvtCount || 0) + 1) : (t.SparseViFrDr = (t.SparseViFrDr || 0) + r, - t.SparseViFrDrEvtCount = (t.SparseViFrDrEvtCount || 0) + 1, - i.SparseViFrDr = (i.SparseViFrDr || 0) + r, - i.SparseViFrDrEvtCount = (i.SparseViFrDrEvtCount || 0) + 1)) - } - ) - } - updateBufferAppended(e, t) { - this.update(e, ({sessionControlRecord: e})=>{ - e.bufferAppendInfo || (e.bufferAppendInfo = []), - e.bufferAppendInfo.push(t) - } - ) - } - updateSeeked(e, t) { - this.update(e, ({sessionControlRecord: e})=>{ - e.seekInfo || (e.seekInfo = []), - e.seekInfo.push(t) - } - ) - } - updateManifestParsed(e, r) { - this.update(e, ({sessionControlRecord: e, periodicRecord: t, playEndedRecord: i})=>{ - t.MasterPlaylistADT = (t.MasterPlaylistADT || 0) + r.adt, - i.MasterPlaylistADT = (i.MasterPlaylistADT || 0) + r.adt; - t = this._computeVariantInfo(r.levels); - i.IsAudioOnly = r.isAudioOnly, - i.IsGapless = r.isGapless, - i.IsFirstItem = r.isFirstItem, - i.ItemID = r.itemID, - i.MaxVideoQltyIndex = t.maxVideoQltyIndex, - i.MaxReWd = t.maxWidth, - i.MaxReHt = t.maxHeight, - e.manifestData = { - variantList: t.variantList, - varListString: t.varListString - } - } - ) - } - updateFragLoaded(e, r) { - this.update(e, ({sessionControlRecord: e, periodicRecord: t, playEndedRecord: i})=>{ - if (t.MediaRequestsSent = (t.MediaRequestsSent || 0) + 1, - i.MediaRequestsSent = (i.MediaRequestsSent || 0) + 1, - r.cdnServer) { - const e = r.cdnServer.toLowerCase(); - "aapl" !== e && "akam" !== e && "llnw" !== e || (i.LastMediaCDNServer = e) - } - r.serverInfo && (i.ServerInfo = r.serverInfo), - e.segmentMimeTypes || (e.segmentMimeTypes = []), - void 0 === e.segmentMimeTypes.find(e=>e == r.contentType) && e.segmentMimeTypes.push(r.contentType), - r.fragType === ul.Variant ? (e.variantVideoBytes = (e.variantVideoBytes || 0) + r.bytes, - e.variantVideoDuration = (e.variantVideoDuration || 0) + r.duration, - e.intervalVideoBytes = (e.intervalVideoBytes || 0) + r.bytes, - e.intervalVideoDuration = (e.intervalVideoDuration || 0) + r.duration, - e.sessionVideoBytes = (e.sessionVideoBytes || 0) + r.bytes, - e.sessionVideoDuration = (e.sessionVideoDuration || 0) + r.duration, - e.obrLast = 8 * r.bytes / (r.duration / 1e3), - t.NetBytes = (t.NetBytes || 0) + r.bytes, - t.ADT = (t.ADT || 0) + r.adt, - t.SegmentProcessTime = (t.SegmentProcessTime || 0) + r.processTime, - i.ADT = (i.ADT || 0) + r.adt, - i.NetBytes = (i.NetBytes || 0) + r.bytes, - i.SegmentProcessTime = (i.SegmentProcessTime || 0) + r.processTime) : r.fragType === ul.AltAudio && (e.variantAudioBytes = (e.variantAudioBytes || 0) + r.bytes, - e.variantAudioDuration = (e.variantAudioDuration || 0) + r.duration, - e.intervalAudioBytes = (e.intervalAudioBytes || 0) + r.bytes, - e.intervalAudioDuration = (e.intervalAudioDuration || 0) + r.duration, - e.sessionAudioBytes = (e.sessionAudioBytes || 0) + r.bytes, - e.sessionAudioDuration = (e.sessionAudioDuration || 0) + r.duration) - } - ) - } - updateFragBuffered(e, i) { - this.update(e, ({periodicRecord: e, playEndedRecord: t})=>{ - i.fragType === ul.Variant && (e.SegmentParseTime = (e.SegmentParseTime || 0) + i.parseTime, - t.SegmentParseTime = (t.SegmentParseTime || 0) + i.parseTime) - } - ) - } - updateLevelLoaded(e, n) { - this.update(e, ({sessionControlRecord: e, playLikelyToKeepUpRecord: t, periodicRecord: i, playEndedRecord: r})=>{ - t.PlaylistADT = (t.PlaylistADT || 0) + n.adt, - i.PlaylistADT = (i.PlaylistADT || 0) + n.adt, - r.PlaylistADT = (r.PlaylistADT || 0) + n.adt, - i.MaxPlaylistDT = n.adt > i.MaxPlaylistDT ? n.adt : i.MaxPlaylistDT, - r.MaxPlaylistDT = n.adt > r.MaxPlaylistDT ? n.adt : r.MaxPlaylistDT, - r.PlayType = n.playType, - this._setTargetDuration(n.url, n.targetduration, e), - e.playlistMimeTypes || (e.playlistMimeTypes = []), - void 0 === e.playlistMimeTypes.find(e=>e == n.contentType) && e.playlistMimeTypes.push(n.contentType); - i = n.url, - r = this._getVariantInfo(i, e); - e.intervalVariantList[i] || (e.intervalVariantList[i] = Object.assign({}, r)), - e.sessionVariantList[i] || (e.sessionVariantList[i] = Object.assign({}, r)) - } - ) - } - updateLevelsChanged(e, r) { - this.update(e, ({sessionControlRecord: t, playEndedRecord: e})=>{ - const i = this._computeVariantInfo(r.levels); - e.MaxVideoQltyIndex = i.maxVideoQltyIndex, - e.MaxReWd = i.maxWidth, - e.MaxReHt = i.maxHeight, - t.manifestData = { - variantList: i.variantList, - varListString: i.varListString - }, - Object.keys(i.variantList).forEach(e=>{ - t.intervalVariantList[e] && (t.intervalVariantList[e].brRnk = i.variantList[e].brRnk), - t.sessionVariantList[e] && (t.sessionVariantList[e].brRnk = i.variantList[e].brRnk) - } - ) - } - ) - } - updateLicenseChallengeRequested(e, r) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = {} - , i = r.timestamp; - t.licenseChallengeStartTime = i, - "RTC_STATE_INIT" === e.state && (t.keyInitTime = i - e.sessionStartTime), - e.activeKeySessions[r.keyuri] = t - } - ) - } - updateLicenseChallengeReceived(e, i) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = e.activeKeySessions[i.keyuri]; - t.licenseChallengeRequestTime = i.timestamp - t.licenseChallengeStartTime - } - ) - } - updateLicenseChallengeSubmitted(e, i) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = e.activeKeySessions[i.keyuri]; - t.keyFormat = i.keyFormat, - t.licenseChallengeSubmitTime = i.timestamp - } - ) - } - updateLicenseChallengeCreated(e, i) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = e.activeKeySessions[i.keyuri]; - t.cdmVersion = i.cdmVersion, - t.licenseChallengeCreationTime = i.timestamp - t.licenseChallengeSubmitTime - } - ) - } - updateLicenseResponseRequested(e, t) { - this.update(e, ({sessionControlRecord: e})=>{ - e.activeKeySessions[t.keyuri].licenseResponseRequestTime = t.timestamp - } - ) - } - updateLicenseResponseReceived(e, i) { - this.update(e, ({sessionControlRecord: e})=>{ - const t = e.activeKeySessions[i.keyuri]; - t.licenseResponseReceiveTime = i.timestamp - t.licenseResponseRequestTime - } - ) - } - updateLicenseResponseSubmitted(e, t) { - this.update(e, ({sessionControlRecord: e})=>{ - e.activeKeySessions[t.keyuri].licenseResponseSubmitTime = t.timestamp - } - ) - } - _prepareEventPlayEnded(e) { - this.update(e, ({sessionControlRecord: e, playEndedRecord: t})=>{ - t.AvgVideoBitrate = 8 * (e.sessionVideoBytes || 0) / (e.sessionVideoDuration || 1), - t.AvgAudioBitrate = 8 * (e.sessionAudioBytes || 0) / (e.sessionAudioDuration || 1); - var i = 1e3 * Math.round((t.NetBytes || 0) / 1e3); - t.NetBytes = i; - var r = t.ADT || 1 - , n = t.ADT + t.SegmentProcessTime || 1 - , s = t.ADT + t.SegmentProcessTime + t.SegmentParseTime || 1; - t.TWOBR = 8 * i / (r / 1e3), - t.PerceivedTWOBR = 8 * i / (n / 1e3), - t.NetTWOBR = 8 * i / (s / 1e3); - var s = this._findTimeWeightedValues("RTC_STATE_PLAY" === e.state ? Date.now() - e.eventStartTime : 0, e.sessionVariantList, e.curLevelUrl); - t.PlayerTWIBR = s.twIBR, - t.PlayerTWIABR = s.twIABR, - t.TWBitRk = s.twBRnk; - s = this._getVariantInfo(e.curLevelUrl, e); - t.TargetDur = s.targetduration, - t.ReWd = s.width, - t.ReHt = s.height, - t.VariantList = null === (s = e.manifestData) || void 0 === s ? void 0 : s.varListString; - let a = ""; - e.playlistMimeTypes && (e.playlistMimeTypes.forEach(e=>{ - a += e + "," - } - ), - a = a.slice(0, -1)); - let o = ""; - e.segmentMimeTypes && (e.segmentMimeTypes.forEach(e=>{ - o += e + "," - } - ), - o = o.slice(0, -1)), - t.PlaylistMimeType = a, - t.SegmentMimeType = o, - t.Rate = e.rate - } - ), - this._aggregateTimes(e) - } - _prepareEventPeriodic(e, o) { - this.update(e, ({sessionControlRecord: e, periodicRecord: t, playEndedRecord: i})=>{ - t.EventCounter = e.periodicEventCounter, - t.PInterval = Date.now() - e.lastPeriodicTime, - t.AvgVideoBitrate = 8 * (e.intervalVideoBytes || 0) / (e.intervalVideoDuration || 1), - t.AvgAudioBitrate = 8 * (e.intervalAudioBytes || 0) / (e.intervalAudioDuration || 1); - let r = t.NetBytes || 0; - o.isFinal && (t.NetBytes = r = 1e3 * Math.round(r / 1e3)); - var n = t.ADT || 1 - , s = t.ADT + t.SegmentProcessTime || 1 - , a = t.ADT + t.SegmentProcessTime + t.SegmentParseTime || 1; - t.TWOBR = 8 * r / (n / 1e3), - t.PerceivedTWOBR = 8 * r / (s / 1e3), - t.NetTWOBR = 8 * r / (a / 1e3); - var a = this._findTimeWeightedValues("RTC_STATE_PLAY" === e.state ? Date.now() - e.eventStartTime : 0, e.intervalVariantList, e.curLevelUrl); - t.PlayerTWIBR = a.twIBR, - t.PlayerTWIABR = a.twIABR, - t.TWBitRk = a.twBRnk; - a = this._getVariantInfo(e.curLevelUrl, e); - t.TargetDur = a.targetduration, - t.ReWd = a.width, - t.ReHt = a.height, - t.VariantList = null === (a = e.manifestData) || void 0 === a ? void 0 : a.varListString, - t.Rate = e.rate; - e = this._computeMediaStats(e); - e && (t.MedianBufferAppendLatency = e.bufLatencyInfo.median, - t.MaxBufferAppendLatency = e.bufLatencyInfo.max, - t.MedianBufferAppendSize = e.bufSizeInfo.median, - t.MaxBufferAppendSize = e.bufSizeInfo.max, - t.MedianSeekLatency = e.seekLatencyInfo.median, - t.MaxSeekLatency = e.seekLatencyInfo.max, - t.MedianPlayLatency = e.playLatencyInfo.median, - t.MaxPlayLatency = e.playLatencyInfo.max), - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventPlayStalled(e, s) { - this.update(e, ({sessionControlRecord: e, playStalledRecord: t, playEndedRecord: i})=>{ - var r = this._getVariantInfo(e.curLevelUrl, e) - , n = Date.now(); - t.MediaDur = s.mediaDur, - t.BitRnk = r.brRnk, - t.Codecs = r.codecs, - t.LastLikelyToKeepUp = n - e.lastLikelyToKeepUpTime, - t.LastSwitch = n - e.lastSwitchTime, - t.StallDetectionTime = s.stallDurationMs, - t.StallType = s.type, - t.BufferLength = s.bufferLen, - "networkError" === i.ErrDomain && (t.NwErrTime = i.NwErrTime, - t.NwErrCode = i.ErrCode), - t.LaSwDir = e.lastSwitchDir, - t.TargetDur = r.targetduration, - t.PlayerIABR = r.avgBandwidth, - t.PlayerIBR = r.bandwidth, - t.Rate = e.rate, - t.OBRLast = e.obrLast, - t.OBRMean = 8 * i.NetBytes / (i.ADT / 1e3), - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventKeySessionComplete(e, r) { - this.update(e, ({sessionControlRecord: e, keySessionCompleteRecord: t, playEndedRecord: i})=>{ - e = e.activeKeySessions[r.keyuri]; - e ? (t.KeyFormat = e.keyFormat, - t.CDMVersion = e.cdmVersion, - t.LicenseChallengeRequestTime = e.licenseChallengeRequestTime, - t.LicenseChallengeCreationTime = e.licenseChallengeCreationTime, - t.LicenseResponseReceiveTime = e.licenseResponseReceiveTime, - t.LicenseResponseProcessTime = e.licenseResponseProcessTime, - t.KeyDeliveryTime = e.keyDeliveryTime, - t.CurrentMediaTime = 1e3 * e.currentMediaTime, - t.KeyInitTime = e.keyInitTime, - t.KeyErrorType = e.keyErrorType, - this._copyCommonKeys(t, i)) : this.logger.warn(`_prepareEventKeySessionComplete no keySessionInfo for ${oe(r.keyuri)}`) - } - ), - this._aggregateTimes(e) - } - _prepareEventPlayLikelyToKeepUp(e, n) { - this.update(e, ({sessionControlRecord: e, playLikelyToKeepUpRecord: t, playEndedRecord: i})=>{ - var r = this._getVariantInfo(e.curLevelUrl, e); - t.EventCounter = e.playLikelyToKeepUpEventCounter, - t.PlayerIABR = r.avgBandwidth, - t.PlayerIBR = r.bandwidth, - t.MediaDur = n.mediaDur, - t.BitRnk = r.brRnk, - t.Codecs = r.codecs, - t.TargetDur = r.targetduration, - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventPlayRateChanged(e, n) { - this.update(e, ({sessionControlRecord: e, playRateChangedRecord: t, playEndedRecord: i})=>{ - var r = this._getVariantInfo(e.curLevelUrl, e); - t.Rate = e.rate, - t.StNPT = n.currentTime, - t.PlayerIABR = r.avgBandwidth, - t.PlayerIBR = r.bandwidth, - t.BitRnk = r.brRnk, - t.MediaDur = n.mediaDur, - t.Codecs = r.codecs, - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventPlayError(e, s) { - this.update(e, ({sessionControlRecord: e, playErrorRecord: t, playEndedRecord: i})=>{ - var r = this._getVariantInfo(e.curLevelUrl, e) - , n = Date.now(); - "mediaElementError" == s.domain ? (t.ErrDomain = t.ErrCode = "mediaElementError", - t.ErrIsFatal = !0, - t.ErrCodeMediaElement = s.mediaElemCode, - t.ErrReason = s.mediaElemReason, - t.ErrDetail = s.mediaElemDetail) : (t.ErrCode = s.details, - t.ErrReason = s.code, - t.ErrIsFatal = s.fatal, - t.ErrDomain = "mediaError"), - t.PlayerErrCount = s.count || 1, - t.BitRnk = r.brRnk, - t.MediaDur = s.mediaDur, - t.PlayTime = i.PlayTime, - t.PlayTimeWC = i.PlayTimeWC, - t.PlayerIABR = r.avgBandwidth, - t.PlayerIBR = r.bandwidth, - t.LastLikelyToKeepUp = n - e.lastLikelyToKeepUpTime, - t.LastSwitch = n - e.lastSwitchTime, - t.VideoQltyIndex = r.qltyIndex, - t.Rate = e.rate, - t.KeyErrorType = e.lastKeyErrorType, - t.KeyDeliveryTime = e.lastKeyDeliveryTime, - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventMediaEngineStalled(e, s) { - this.update(e, ({sessionControlRecord: e, mediaEngineStalledRecord: t, playEndedRecord: i})=>{ - var r = Date.now() - , n = this._getVariantInfo(e.curLevelUrl, e); - t.MediaDur = s.mediaDur, - t.BitRnk = n.brRnk, - t.Codecs = n.codecs, - t.LastLikelyToKeepUp = r - e.lastLikelyToKeepUpTime, - t.LastSwitch = r - e.lastSwitchTime, - t.StallDetectionTime = s.stallDurationMs, - t.StallType = s.type, - t.BufferLength = s.bufferLen, - t.LaSwDir = e.lastSwitchDir, - t.TargetDur = n.targetduration, - t.PlayerIABR = n.avgBandwidth, - t.PlayerIBR = n.bandwidth, - t.Rate = e.rate, - t.OBRLast = e.obrLast, - t.OBRMean = 8 * i.NetBytes / (i.ADT / 1e3), - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventSwitchComplete(e, s) { - this.update(e, ({sessionControlRecord: e, switchCompleteRecord: t, playEndedRecord: i})=>{ - var r = this._getVariantInfo(e.prevLevelUrl, e) - , n = this._getVariantInfo(e.curLevelUrl, e); - t.FrBitRnk = r.brRnk, - t.ToBitRnk = n.brRnk, - t.TimeToBitrate = Date.now() - e.sessionStartTime, - t.MediaDur = s.mediaDur, - t.Rate = e.rate, - t.PlayerIBR = n.bandwidth, - t.PlayerIABR = n.avgBandwidth, - t.LastPlayerIBR = r.bandwidth, - t.LastPlayerIABR = r.avgBandwidth, - t.ReWd = n.width, - t.ReHt = n.height, - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventVariantEnded(e, n) { - this.update(e, ({sessionControlRecord: e, variantEndedRecord: t, playEndedRecord: i})=>{ - var r = this._getVariantInfo(e.curLevelUrl, e); - t.Rate = e.rate, - t.VarAvgBitrate = r.avgBandwidth, - t.VarPeakBitrate = r.bandwidth, - t.VarBitRk = r.brRnk, - t.VarSTTime = e.variantStartTimeMedia, - t.VarEndTime = 1e3 * n.currentTime, - t.IFR = r.framerate, - t.ODR = e.decodedFramesForVariant / e.decodedFramesForVariantSampleCount, - t.ReWd = r.width, - t.ReHt = r.height, - t.Codecs = r.codecs, - t.AvgVideoBitrate = 8 * (e.variantVideoBytes || 0) / (e.variantVideoDuration || 1), - t.AvgAudioBitrate = 8 * (e.variantAudioBytes || 0) / (e.variantAudioDuration || 1), - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _prepareEventNwError(e, n) { - this.update(e, ({sessionControlRecord: e, nwErrorRecord: t, playEndedRecord: i})=>{ - var r = this._getVariantInfo(e.curLevelUrl, e); - t.ErrCode = n.details, - t.ErrReason = n.code, - t.ErrIsFatal = n.fatal, - t.NwErrCount = n.count || 1, - t.ErrDomain = "networkError", - t.PlayTime = i.PlayTime, - t.PlayTimeWC = i.PlayTimeWC, - t.BitRnk = r.brRnk, - t.Rate = e.rate, - t.KeyErrorType = e.lastKeyErrorType, - t.KeyDeliveryTime = e.lastKeyDeliveryTime, - this._copyCommonKeys(t, i) - } - ), - this._aggregateTimes(e) - } - _copyCommonKeys(e, t) { - e.PlayType = t.PlayType, - e.LastMediaCDNServer = t.LastMediaCDNServer, - e.MaxVideoQltyIndex = t.MaxVideoQltyIndex, - e.MaxReWd = t.MaxReWd, - e.MaxReHt = t.MaxReHt, - e.IsGapless = t.IsGapless, - e.IsAudioOnly = t.IsAudioOnly, - e.IsFirstItem = t.IsFirstItem, - e.ItemID = t.ItemID, - e.ServerInfo = t.ServerInfo - } - _computeVariantInfo(e) { - const i = {}; - let r = 0 - , n = 0 - , s = 0 - , a = 0; - const o = this._getMaxNormalizedPeak(e); - e.forEach(e=>{ - if (e.attrs) { - const r = this._getVideoFourCC(e.attrs.CODECS) - , n = this._getVideoQualityIndex(r, e.attrs["VIDEO-RANGE"]) || 0 - , s = { - codecs: e.attrs.CODECS, - width: e.width, - height: e.height, - bandwidth: e.attrs.BANDWIDTH, - avgBandwidth: e.attrs["AVERAGE-BANDWIDTH"], - framerate: e.attrs["FRAME-RATE"], - iframes: e.iframes, - brRnk: this._getBitrateRank(e.attrs.BANDWIDTH, r, o), - qltyIndex: n, - targetduration: 0, - playTime: 0 - }; - a = n > a ? n : a, - i[e.url] = s - } - var t = e.width * e.height; - t > s && (s = t, - r = e.width, - n = e.height) - } - ); - e = 0 < Object.keys(i).length ? Object.values(i).map(e=>e.bandwidth + ":" + e.avgBandwidth).join(",") : void 0; - return { - variantList: i, - varListString: e, - maxVideoQltyIndex: a, - maxWidth: r, - maxHeight: n - } - } - _getMaxNormalizedPeak(e) { - let n = 0; - return e.forEach(e=>{ - e = e.attrs; - if (e) { - const t = e.BANDWIDTH || 0 - , i = this._getNormalizedPeak(t, this._getVideoFourCC(e.CODECS)) - , r = Math.max(t, i); - n = r > n ? r : n - } - } - ), - n - } - _getNormalizedPeak(e, t) { - return "object" == typeof Mf[t] ? 1.5 * e : +e - } - _getVideoFourCC(e) { - return e && e.split(",").map(e=>e.split(".")[0].trim()).find(e=>!!Mf[e]) - } - _getVideoQualityIndex(e, t) { - return "object" == typeof Mf[e] ? Mf[e][t] : Mf[e] - } - _getBitrateRank(e, t, i) { - t = Math.max(1, this._getNormalizedPeak(e, t)); - return Math.ceil(100 * t / i) - } - _findTimeWeightedValues(o, d, l) { - const e = { - twBRnk: 0, - twIBR: 0, - twIABR: 0 - }; - if (d) { - let i = 0 - , r = 0 - , n = 0 - , s = 0 - , a = 0; - Object.values(d).forEach(e=>{ - let t = e.playTime; - e === d[l] && (t += o || 0), - t && (r += e.bandwidth * t, - i += e.brRnk * t, - n += t, - e.avgBandwidth && (s += e.avgBandwidth * t, - a += t)) - } - ), - n && (e.twBRnk = i / n, - e.twIBR = r / n), - s && a && (e.twIABR = s / a) - } - return e - } - _computeMediaStats(e) { - const t = e.bufferAppendInfo; - let i = []; - const r = []; - t && t.forEach && t.forEach(e=>{ - i.push(e.latency), - r.push(e.size) - } - ); - var n = this._computeStats(i) - , s = this._computeStats(r) - , a = e.seekInfo; - i = [], - a && a.forEach && e.seekInfo.forEach(e=>i.push(e.latency)); - var o = this._computeStats(i) - , a = e.playInfo; - return i = [], - a && a.forEach && e.playInfo.forEach(e=>i.push(e.latency)), - { - bufLatencyInfo: n, - bufSizeInfo: s, - seekLatencyInfo: o, - playLatencyInfo: this._computeStats(i) - } - } - _computeStats(e) { - let t, i; - if (e) { - const r = e.filter(e=>0 < e); - if (0 < r.length) { - t = r.reduce((e,t)=>Math.max(e, t)); - const e = r.length - , n = r.sort((e,t)=>e - t) - , s = Math.ceil(e / 2); - i = e % 2 == 0 ? (n[s] + n[s - 1]) / 2 : n[s - 1] - } - } - return { - max: t, - median: i - } - } - _getVariantInfo(e, t) { - return e && t.manifestData && t.manifestData.variantList && t.manifestData.variantList[e] ? t.manifestData.variantList[e] : {} - } - _setTargetDuration(e, t, i) { - e && i.manifestData && i.manifestData.variantList && i.manifestData.variantList[e] && (i.manifestData.variantList[e].targetduration = t) - } - _isBadSw(e, t, i, r, n, s, a) { - let o = n - s < 1e4 && t !== e && r === i && !a ? !0 : !1; - return o - } - _aggregateTimes(e) { - this.update(e, ({sessionControlRecord: t, playLikelyToKeepUpRecord: i, playStalledRecord: r, mediaEngineStalledRecord: n, switchCompleteRecord: s, playRateChangedRecord: a, variantEndedRecord: o, playErrorRecord: d, nwErrorRecord: l, periodicRecord: u, playEndedRecord: c})=>{ - var h = Date.now() - t.eventStartTime; - switch (t.state) { - case "RTC_STATE_INIT": - i.StartupTime = (i.StartupTime || 0) + h, - u.InitTime = (u.InitTime || 0) + h, - c.InitTime = (c.InitTime || 0) + h; - break; - case "RTC_STATE_CANPLAY": - a.StartupTime = (a.StartupTime || 0) + h, - u.InitTime = (u.InitTime || 0) + h, - c.InitTime = (c.InitTime || 0) + h; - break; - case "RTC_STATE_PAUSE": - u.PauseTime = (u.PauseTime || 0) + h, - c.PauseTime = (c.PauseTime || 0) + h, - a.LastPause = (a.LastPause || 0) + h, - c.LastPause = (c.LastPause || 0) + h, - d.LastPause = (d.LastPause || 0) + h, - l.LastPause = (l.LastPause || 0) + h; - break; - case "RTC_STATE_STALL": - o.StallTime = (o.StallTime || 0) + h, - u.StallTime = (u.StallTime || 0) + h, - c.StallTime = (c.StallTime || 0) + h, - a.LastStall = (a.LastStall || 0) + h, - d.LastStall = (d.LastStall || 0) + h, - c.LastStall = (c.LastStall || 0) + h; - break; - case "RTC_STATE_MEDIAENGINESTALL": - o.MediaEngineStallTime = (o.MediaEngineStallTime || 0) + h, - u.MediaEngineStallTime = (u.MediaEngineStallTime || 0) + h, - c.MediaEngineStallTime = (c.MediaEngineStallTime || 0) + h, - a.LastMediaEngineStall = (a.LastMediaEngineStall || 0) + h, - d.LastMediaEngineStall = (d.LastMediaEngineStall || 0) + h, - c.LastMediaEngineStall = (c.LastMediaEngineStall || 0) + h; - break; - case "RTC_STATE_NWERROR": - c.NwErrTime = (c.NwErrTime || 0) + h, - u.NwErrTime = (u.NwErrTime || 0) + h; - break; - case "RTC_STATE_PLAYERROR": - u.PlayErrTime = (u.PlayErrTime || 0) + h, - c.PlayErrTime = (c.PlayErrTime || 0) + h; - break; - case "RTC_STATE_PLAY": - { - a.RateChangePlayTime = (a.RateChangePlayTime || 0) + h, - s.PlayTime = (s.PlayTime || 0) + h, - s.PlayTimeLastSW = (s.PlayTimeLastSW || 0) + h * (t.oldRate / 100), - r.LastResume = (r.LastResume || 0) + h, - n.LastResume = (n.LastResume || 0) + h, - d.LastResume = (d.LastResume || 0) + h, - l.LastResume = (l.LastResume || 0) + h, - o.VarPlayTimeWC = (o.VarPlayTimeWC || 0) + h, - o.VarPlayTime = (o.VarPlayTime || 0) + h * (t.oldRate / 100), - u.PlayTimeWC = (u.PlayTimeWC || 0) + h, - u.PlayTime = (u.PlayTime || 0) + h * (t.oldRate / 100), - c.PlayTimeWC = (c.PlayTimeWC || 0) + h, - c.PlayTime = (c.PlayTime || 0) + h * (t.oldRate / 100), - n.PlayTime = c.PlayTime, - r.PlayTime = c.PlayTime; - const i = t.curLevelUrl; - let e = t.intervalVariantList[i]; - e.playTime = (e.playTime || 0) + h, - e = t.sessionVariantList[i], - e.playTime = (e.playTime || 0) + h; - break - } - } - } - ) - } - } - const Lf = { - name: "rtc-service" - }; - class _f { - constructor(e, t, i, r) { - this.hls = e, - this.config = t, - this.accessLog = i, - this.logger = r, - this.destroy$ = new zt, - this.isSeeking = !1, - this.seekStart = null, - this.periodicInterval = t.rtcIntervalTimeout || 3e5, - this.intervalFunc = null, - this.rtcStore = new Rf(this.logger), - this.rtcQuery = new xf(this.rtcStore,this.logger), - this.rtcComponent = new Pf(this.rtcQuery,this.logger), - i.setRTCQuery(this.rtcQuery), - this.subscribeAndUpdateStore(), - this.registerForEvents() - } - destroy() { - this.destroy$.next(), - this.clearPeriodic(), - this.rtcStore.reset() - } - detachMedia() { - this.clearPeriodic(); - var e; - try { - e = this.hls.realCurrentTime, - this.rtcStore.updateVariantEnd(this.rtcEventItemId(!0), { - currentTime: e - }), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.VariantEnded), - this.rtcStore.updatePeriodic(this.rtcEventItemId(!0), !0), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.Periodic), - this.rtcStore.updateEnded(this.rtcEventItemId(!0)), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.PlayEnded) - } catch (e) { - this.logger.warn(Lf, e) - } - } - handleError(e) { - var t = e instanceof p ? e : new V(!0,e.message,$.InternalError); - t instanceof nu && !t.fatal ? (this.rtcStore.updateLevelLoadError(this.rtcEventItemId(), { - url: t.url, - mediaDur: this.hls.bufferedDuration, - isSeeking: this.isSeeking - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.SwitchComplete)) : t.type === o ? (this.rtcStore.updateNwError(this.rtcEventItemId(), { - fatal: t.fatal, - details: t.details, - code: null === (e = t.response) || void 0 === e ? void 0 : e.code - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.NwError)) : (this.rtcStore.updateMediaError(this.rtcEventItemId(), { - fatal: t.fatal, - details: t.details, - code: null === (t = t.response) || void 0 === t ? void 0 : t.code - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.PlayError)) - } - handleMediaElementError(e) { - this.rtcStore.updateMediaElementError(this.rtcEventItemId(), e), - this.sendAndFinalize(this.rtcEventItemId(), Df.PlayError) - } - handleFragLoaded(e, t) { - var i, r, n; - this.checkMediaOptionType(e.mediaOptionType) && (e.itemId !== this.rtcEventItemId() && this.logger.warn(Lf, `Frag id does not match current item id. Frag Id=${e.itemId}, playing id=${this.rtcEventItemId(!0)}, loading id=${null === (n = this.hls.loadingItem) || void 0 === n ? void 0 : n.itemId}`), - i = t.tload - t.trequest, - r = t.tload - t.tfirst, - n = this.serverInfoInstance || {}, - this.rtcStore.updateFragLoaded(e.itemId, { - fragType: e.mediaOptionType, - bytes: t.loaded, - duration: e.duration, - adt: i, - processTime: r, - contentType: t.contentType, - cdnServer: t.cdnServer, - serverInfo: n - }), - this.accessLog.updateFragLoaded(e.itemId, this.isSeeking, { - fragType: e.mediaOptionType, - bytes: t.loaded, - duration: e.duration, - adt: i, - processTime: r, - startPTS: e.start, - endPTS: e.start + e.duration - })) - } - handleFragBuffered(e) { - var t; - this.checkMediaOptionType(e.fragmentType) && (t = e.endDataAppend - e.startDataAppend, - this.rtcStore.updateFragBuffered(this.rtcEventItemId(), { - fragType: e.fragmentType, - bytes: e.dataBytesAppend, - parseTime: t - })) - } - handleLevelLoaded(e, t) { - var i; - e ? (e.itemId !== this.rtcEventItemId() && this.logger.warn(Lf, `media option id does not match current item id. media Id=${e.itemId}, current id=${this.rtcEventItemId}`), - e.mediaOptionType === ul.Variant && (i = t.tload - t.trequest, - this.rtcStore.updateLevelLoaded(this.rtcEventItemId(), { - url: e.url, - targetduration: e.targetduration, - adt: i, - contentType: t.contentType, - playType: e.type - }))) : this.logger.warn(`handleLevelLoaded called with mediaOptionDetails as ${e}`) - } - handleLevelSwitched(e) { - var t = { - url: e.url, - isSeeking: this.isSeeking, - mediaDur: this.hls.bufferedDuration, - currentTime: this.hls.realCurrentTime - }; - e.oldVariant && (this.rtcStore.updateVariantEnd(this.rtcEventItemId(), { - currentTime: this.hls.realCurrentTime - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.VariantEnded)), - this.rtcStore.updateLevelSwitched(this.rtcEventItemId(), t), - this.sendAndFinalize(this.rtcEventItemId(), Df.SwitchComplete) - } - handleLevelSwitching(e) { - this.levelSwitchingUrl = e - } - handleLevelsChanged(e) { - this.rtcStore.updateLevelsChanged(this.rtcEventItemId(), { - levels: e - }) - } - handleManifestParsed(e) { - var t = e.stats.tload - e.stats.trequest; - this.rtcStore.updateManifestParsed(this.rtcEventItemId(), { - levels: e.levels, - adt: t, - contentType: e.stats.contentType, - isAudioOnly: this.hls.inGaplessMode, - isGapless: this.hls.inGaplessMode, - isFirstItem: this.hls.isFirstItem, - itemID: ((null === (e = this.hls.reportingAgent) || void 0 === e ? void 0 : e.SessionID) || Jd()) + "-" + this.rtcEventItemId() - }) - } - handleSeek(e) { - if ("SEEKING" === e) - this.isSeeking = !0, - this.seekStart = Date.now(); - else if ("SEEKED" === e) { - this.isSeeking = !1; - let e = 0; - this.seekStart && (e = Date.now() - this.seekStart), - this.seekStart = null, - this.rtcStore.updateSeeked(this.rtcEventItemId(!0), { - latency: e - }) - } - } - handleDesiredRateChanged(e, t) { - 0 === t || 1 < Math.abs(e) && 1 < Math.abs(t) ? (this.rtcStore.updateRateChanged(this.rtcEventItemId(!0), { - rate: t, - latency: 0, - mediaDur: this.hls.bufferedDuration, - currentTime: this.hls.realCurrentTime, - url: this.levelSwitchingUrl - }), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.PlayRateChanged)) : 1 !== e && 1 === t && (this.playStart = Date.now()), - this.oldRate = e, - this.newRate = t - } - handleVariantBufferAppended(e, t) { - let i = 0; - e && (i = Date.now() - e), - this.rtcStore.updateBufferAppended(this.rtcEventItemId(), { - latency: i, - size: t - }) - } - handleStalled(e, t) { - var i = { - type: e.type, - stallDurationMs: e.stallDurationMs, - bufferLen: t, - mediaDur: this.hls.bufferedDuration - } - , t = this.rtcQuery.getEntity(this.rtcEventItemId(!0)).sessionControlRecord.state; - e.type === Op.LowBuffer || e.type === Op.Seek && e.isLowBufferStall ? "RTC_STATE_PLAY" === t && (this.rtcStore.updateBufferStalled(this.rtcEventItemId(!0), i), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.PlayStalled)) : "RTC_STATE_PLAY" === t && (this.rtcStore.updateMediaEngineStalled(this.rtcEventItemId(!0), i), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.MediaEngineStalled)) - } - handlePlaybackInfo(e, t) { - this.rtcStore.updatePlaybackInfo(this.rtcEventItemId(!0), { - droppedVideoFrames: e, - decodedFrameCount: t - }), - this.accessLog.updatePlaybackInfo(this.rtcEventItemId(!0), { - droppedVideoFrames: e, - decodedFrameCount: t - }) - } - checkMediaOptionType(e) { - return e === ul.Variant || e === ul.AltAudio || (this.logger.error(Lf, 'Should not have media option type = "%s" in RTC', Cl[e]), - !1) - } - rtcEventItemId(e=!1) { - return (this.hls.isPreloading ? e ? this.hls.playingItem : this.hls.loadingItem : this.hls.currentItem).itemId - } - subscribeAndUpdateStore() { - this.hls.publicQueries$.pipe(Ra(([,e])=>this.mediaElementQueryListener(e)), $a(this.destroy$)).subscribe(), - this.hls.itemQueue.activeItemById$.pipe(Ja(t=>{ - if (t) { - let e = !1; - if (this.hls.userInfo ? this.hls.userInfo.internalBuild ? e = !0 : this.hls.userInfo.diagnosticsAndUsage && (e = this.config.enableRtcReporting) : e = this.config.enableRtcReporting, - e) { - const i = this.hls.reportingAgent; - i ? this.rtcComponent.setReportingAgent(i) : this.logger.warn(Lf, "[RTCA] - Reporting is enabled but reportingAgent is null") - } else - this.rtcComponent.setReportingAgent(null); - this.serverInfoInstance = null; - t = t.itemId; - this.rtcStore.createEntity(t), - !this.hls.isFirstItem && this.hls.inGaplessMode || this.setPeriodic(t) - } - } - ), $a(this.destroy$)).subscribe() - } - itemTransitioned(e, t) { - this.rtcStore.updateVariantEnd(e, { - currentTime: this.hls.realCurrentTime - }), - this.sendAndFinalize(e, Df.VariantEnded), - this.rtcStore.updatePeriodic(e, !0), - this.sendAndFinalize(e, Df.Periodic), - this.rtcStore.updateEnded(e), - this.sendAndFinalize(e, Df.PlayEnded), - this.setPeriodic(t) - } - mediaElementQueryListener(e) { - return e.gotPlaying$.pipe(Ja(e=>{ - if (e) { - const e = this.oldRate - , t = this.newRate || 1; - 1 < Math.abs(e) && 1 < Math.abs(t) || (this.rtcStore.updateCanPlay(this.rtcEventItemId(!0), { - mediaDur: this.hls.bufferedDuration - }), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.PlayLikelyToKeepUp), - this.rtcStore.updateRateChanged(this.rtcEventItemId(!0), { - rate: t, - latency: ne(this.playStart) ? Date.now() - this.playStart : 0, - mediaDur: this.hls.bufferedDuration, - currentTime: this.hls.realCurrentTime, - url: this.levelSwitchingUrl - }), - this.sendAndFinalize(this.rtcEventItemId(!0), Df.PlayRateChanged)) - } - } - )) - } - registerForEvents() { - const e = wc(this.hls, this); - nn(e.event(x.KEY_REQUEST_STARTED, this.keyRequestStarted, this), e.event(x.KEY_LOADED, this.keyLoaded, this)).pipe($a(this.destroy$)).subscribe() - } - keyRequestStarted(e) { - e.timestamp = Date.now(), - this.rtcStore.updateLicenseChallengeRequested(this.rtcEventItemId(), e) - } - keyLoaded(e) { - e.timestamp = Date.now(), - e.currentTime = this.hls.realCurrentTime, - this.rtcStore.updateSegmentKeyLoaded(this.rtcEventItemId(), e) - } - licenseChallengeReceived(e) { - this.rtcStore.updateLicenseChallengeReceived(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri - }) - } - licenseChallengeSubmitted(e) { - this.rtcStore.updateLicenseChallengeSubmitted(this.rtcEventItemId(), { - timestamp: Date.now(), - keyFormat: e.keyFormat, - keyuri: e.keyuri - }) - } - licenseChallengeCreated(e) { - this.rtcStore.updateLicenseChallengeCreated(this.rtcEventItemId(), { - timestamp: Date.now(), - cdmVersion: e.cdmVersion, - keyuri: e.keyuri - }), - this.rtcStore.updateLicenseResponseRequested(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri - }) - } - licenseResponseSubmitted(e) { - this.rtcStore.updateLicenseResponseReceived(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri - }), - this.rtcStore.updateLicenseResponseSubmitted(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri - }) - } - licenseResponseProcessed(e) { - this.rtcStore.updateLicenseResponseProcessed(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri, - currentTime: this.hls.realCurrentTime - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.KeySessionComplete) - } - licenseChallengeError(e) { - this.rtcStore.updateLicenseChallengeError(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.KeySessionComplete) - } - licenseResponseError(e) { - this.rtcStore.updateLicenseResponseError(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.KeySessionComplete) - } - keyAborted(e) { - var t; - null != (null === (t = this.rtcQuery.getEntity(this.rtcEventItemId())) || void 0 === t ? void 0 : t.sessionControlRecord.activeKeySessions[e.keyuri]) ? (this.rtcStore.updateKeyAborted(this.rtcEventItemId(), { - timestamp: Date.now(), - keyuri: e.keyuri - }), - this.sendAndFinalize(this.rtcEventItemId(), Df.KeySessionComplete)) : this.logger.warn(`keyAbort called without active key session ${oe(e.keyuri)}`) - } - setPeriodic(e) { - this.clearPeriodic(), - this.intervalFunc = setInterval(this.handlePeriodic.bind(this, e), this.periodicInterval) - } - handlePeriodic(e) { - this.rtcStore.updatePeriodic(e, !1), - this.sendAndFinalize(e, Df.Periodic) - } - clearPeriodic() { - this.intervalFunc && clearInterval(this.intervalFunc), - this.intervalFunc = null - } - sendAndFinalize(e, t) { - switch (this.accessLog.addPlayTime(e), - t) { - case Df.PlayEnded: - this.rtcComponent.sendPlayEnded(e); - break; - case Df.Periodic: - this.rtcComponent.sendPeriodic(e); - break; - case Df.PlayStalled: - this.accessLog.updateStallCount(e), - this.rtcComponent.sendPlayStalled(e); - break; - case Df.KeySessionComplete: - this.rtcComponent.sendKeySessionComplete(e); - break; - case Df.PlayLikelyToKeepUp: - this.accessLog.updateCanPlay(e), - this.rtcComponent.sendPlayLikelyToKeepUp(e); - break; - case Df.PlayRateChanged: - this.rtcComponent.sendPlayRateChange(e); - break; - case Df.PlayError: - this.accessLog.addToErrorLog(e, "mediaError"), - this.rtcComponent.sendPlayError(e); - break; - case Df.MediaEngineStalled: - this.accessLog.updateMediaEngineStallCount(e), - this.rtcComponent.sendMediaEngineStalled(e); - break; - case Df.SwitchComplete: - this.accessLog.addToAccessLog(e), - this.rtcComponent.sendSwitchComplete(e); - break; - case Df.VariantEnded: - this.rtcComponent.sendVariantEnded(e); - break; - case Df.NwError: - this.accessLog.addToErrorLog(e, "networkError"), - this.rtcComponent.sendNwError(e); - break; - default: - return void this.logger.error(Lf, `Unknown rtc event eventGroupId:${e}`) - } - this.rtcStore.finalize(e, t) - } - } - const Nf = a=>(e,t)=>{ - let i = 0 - , r = 0; - for (var {timestamp: n, value: s} of e) { - const e = Math.pow(Math.max(0, n - t) / 1e3, a); - i += e * s, - r += e - } - return i / r - } - , Ff = { - "uniform-time-weighted": Nf(0), - "linear-time-weighted": Nf(1), - "quadratic-time-weighted": Nf(2) - }; - class Bf { - constructor(e, t="quadratic-time-weighted", i={ - avgLatencyMs: NaN, - avgBandwidth: NaN - }) { - this.windowSize = e, - this.aggregationMethod = t, - this.latencyEntries = [], - this.bandwidthEntries = [], - this.minEntries = 1, - this.cleanUpExpiredEntries = this.cleanUpExpiredEntries.bind(this), - this.bwSubject = new gi(i) - } - get estimate$() { - return this.bwSubject.asObservable() - } - record(e) { - var {trequest: t, tfirst: i, tload: r, bitsDownloaded: e} = e; - t !== r && (this.recordLatency(t, i), - this.recordBandwidth(t, r, 1e3 * e / (r - t)), - this.bwSubject.closed || (t = this.getEstimate(), - this.bwSubject.next(t))) - } - getEstimate() { - if (this.latencyEntries.length < this.minEntries) - return { - avgLatencyMs: NaN, - avgBandwidth: NaN - }; - const e = performance.now() - this.windowSize - , t = Ff[this.aggregationMethod] - , i = this.latencyEntries.map(({start: e, end: t})=>({ - timestamp: t, - value: t - e, - duration: 1 - })); - this.bandwidthEntries = function(r) { - function n(t, i) { - if (t.length) { - for (let e = 0; e < t.length; e++) - if (t[e].start > i.start || t[e].start === i.start && t[e].end > i.end) { - t.splice(e, 0, i); - break - } - } else - t.push(i) - } - const s = [...r].sort((e,t)=>e.start !== t.start ? e.start - t.start : e.end - t.end) - , t = []; - for (; s.length; ) { - const r = s[0]; - let e; - if (s.shift(), - t.length && (e = t[t.length - 1]), - 0 === t.length || e.end <= r.start) - t.push(r); - else if (r.start === e.start) - r.end === e.end ? e.bitsPerSec += r.bitsPerSec : r.end < e.end || (e.bitsPerSec += r.bitsPerSec, - r.start = e.end, - n(s, r)); - else { - var a = e.end - , o = e.bitsPerSec; - e.end = r.start; - var i = { - start: r.start, - end: Math.min(a, r.end), - bitsPerSec: r.bitsPerSec + o - }; - if (t.push(i), - a !== r.end) { - let e = 0 - , t = 0 - , i = 0; - i = a < r.end ? (e = a, - t = r.end, - r.bitsPerSec) : (e = r.end, - t = a, - o), - n(s, { - start: e, - end: t, - bitsPerSec: i - }) - } - } - } - return t - }(this.bandwidthEntries); - var r = this.bandwidthEntries.map(({end: e, bitsPerSec: t})=>({ - timestamp: e, - duration: 1, - value: t - })); - return { - avgLatencyMs: t(i, e), - avgBandwidth: t(r, e) - } - } - getLatest() { - if (0 === this.latencyEntries.length) - return { - avgLatencyMs: NaN, - avgBandwidth: NaN - }; - var e = this.latencyEntries[this.latencyEntries.length - 1] - , t = this.bandwidthEntries[this.bandwidthEntries.length - 1]; - return { - avgLatencyMs: e.end - e.start, - avgBandwidth: t.bitsPerSec - } - } - recordLatency(e, t) { - this.latencyEntries.push({ - start: e, - end: t - }), - this.updateCleanupTimeout(t) - } - recordBandwidth(e, t, i) { - this.bandwidthEntries.push({ - start: e, - end: t, - bitsPerSec: i - }), - this.updateCleanupTimeout(t) - } - setCleanupTimeout(e) { - this.cleanupTimeout = setTimeout(this.cleanUpExpiredEntries, Math.max(e - performance.now(), 0)), - this.cleanupTimestamp = e - } - clearCleanupTimeout() { - void 0 !== this.cleanupTimeout && (clearTimeout(this.cleanupTimeout), - this.cleanupTimeout = void 0), - this.cleanupTimestamp = void 0 - } - updateCleanupTimeout(e) { - e += this.windowSize; - (!this.cleanupTimestamp || e < this.cleanupTimestamp) && (this.clearCleanupTimeout(), - this.setCleanupTimeout(e)) - } - cleanUpExpiredEntries() { - this.clearCleanupTimeout(); - const t = performance.now() - this.windowSize; - if (this.latencyEntries = this.latencyEntries.filter(e=>e.end >= t), - this.bandwidthEntries = this.bandwidthEntries.filter(e=>e.end >= t), - this.bwSubject.closed || this.bwSubject.next(this.getEstimate()), - 0 < this.latencyEntries.length || 0 < this.bandwidthEntries.length) { - const t = Math.min(...this.latencyEntries.map(e=>e.end), ...this.bandwidthEntries.map(e=>e.end)); - this.updateCleanupTimeout(t) - } - } - destroy() { - this.clearCleanupTimeout() - } - } - const Uf = { - setCombinedEstimate: function(t, i, r) { - const n = qe(); - if (void 0 !== t.storage.set) { - var s = t.bandwidthHistoryStorageKey - , a = { - avgLatencyMs: i.avgLatencyMs, - avgBandwidth: i.avgBandwidth - } - , a = Object.assign({}, a, { - expires: Date.now() + t.bandwidthHistoryTTL - }); - try { - t.storage.set(s, JSON.stringify(a)) - } catch (t) { - n.warn(`Error stringifying! Not persisting bandwidth estimates: ${t.message}`) - } - i = { - maxDuration: i.maxDurationSec, - avgFragParseTimeMs: i.avgParseTimeMs, - avgFragBufferCreationDelayMs: i.avgBufferCreateMs, - avgPlaylistLoadTimeMs: i.avgPlaylistLoadTimeMs, - avgPlaylistParseTimeMs: i.avgPlaylistParseTimeMs, - avgInitFragAppendMs: i.avgInitFragAppendMs, - avgDataFragAppendMs: i.avgDataFragAppendMs - }; - let e = t.storageKeyPrefix; - r && (e += r); - try { - t.storage.set(e, JSON.stringify(i)) - } catch (t) { - n.warn(`Error stringifying! Not persisting bandwidth estimates: ${t.message}`) - } - } else - n.warn("storage.set is not supported! Not persisting bandwidth estimates") - }, - getCombinedEstimate: function(t, e) { - const i = qe(); - let r = {}; - if (void 0 === t.storage.get) - return i.warn("storage.get is not supported! unable to retreive bandwidth estimates"), - this.convertStorageJsonToCombinedEstimate(r); - try { - let e = JSON.parse(t.storage.get(t.bandwidthHistoryStorageKey)); - e = null != e && e.expires && e.expires < Date.now() ? null : { - avgLatencyMs: null == e ? void 0 : e.avgLatencyMs, - avgBandwidth: null == e ? void 0 : e.avgBandwidth - }, - r = Object.assign(Object.assign({}, r), e) - } catch (t) { - i.warn(`Unable to get persisted bandwidth history: ${t.message}`) - } - let n = t.storageKeyPrefix; - e && (n += e); - try { - const e = JSON.parse(t.storage.get(n)); - r = Object.assign(Object.assign({}, r), e) - } catch (t) { - i.warn(`Unable to get persisted bandwidth history: ${t.message}`) - } - return this.convertStorageJsonToCombinedEstimate(r) - }, - convertStorageJsonToCombinedEstimate: function(e) { - return { - avgLatencyMs: (null == e ? void 0 : e.avgLatencyMs) || NaN, - avgBandwidth: (null == e ? void 0 : e.avgBandwidth) || NaN, - maxDurationSec: (null == e ? void 0 : e.maxDuration) || NaN, - avgParseTimeMs: (null == e ? void 0 : e.avgFragParseTimeMs) || NaN, - avgBufferCreateMs: (null == e ? void 0 : e.avgFragBufferCreationDelayMs) || NaN, - avgPlaylistLoadTimeMs: (null == e ? void 0 : e.avgPlaylistLoadTimeMs) || NaN, - avgPlaylistParseTimeMs: (null == e ? void 0 : e.avgPlaylistParseTimeMs) || NaN, - avgInitFragAppendMs: (null == e ? void 0 : e.avgInitFragAppendMs) || NaN, - avgDataFragAppendMs: (null == e ? void 0 : e.avgDataFragAppendMs) || NaN - } - }, - getBandwidthEstimate: function(e, t) { - const i = this.getCombinedEstimate(e, t) - , r = { - avgLatencyMs: null == i ? void 0 : i.avgLatencyMs, - avgBandwidth: null == i ? void 0 : i.avgBandwidth - }; - return ne(r.avgLatencyMs) || (r.avgLatencyMs = NaN), - ne(r.avgBandwidth) || (r.avgBandwidth = NaN), - r - }, - getPlaylistEstimate: function(e, t) { - const i = this.getCombinedEstimate(e, t) - , r = { - avgPlaylistLoadTimeMs: null == i ? void 0 : i.avgPlaylistLoadTimeMs, - avgPlaylistParseTimeMs: null == i ? void 0 : i.avgPlaylistParseTimeMs - }; - return ne(r.avgPlaylistLoadTimeMs) || (r.avgPlaylistLoadTimeMs = NaN), - ne(r.avgPlaylistParseTimeMs) || (r.avgPlaylistParseTimeMs = NaN), - r - }, - getFragEstimate: function(e, t) { - const i = this.getCombinedEstimate(e, t) - , r = { - maxDurationSec: null == i ? void 0 : i.maxDurationSec, - avgParseTimeMs: null == i ? void 0 : i.avgParseTimeMs - }; - return ne(r.maxDurationSec) || (r.maxDurationSec = NaN), - ne(r.avgParseTimeMs) || (r.avgParseTimeMs = NaN), - r - }, - getBufferEstimate: function(e, t) { - const i = this.getCombinedEstimate(e, t) - , r = { - avgBufferCreateMs: null == i ? void 0 : i.avgBufferCreateMs, - avgInitFragAppendMs: null == i ? void 0 : i.avgInitFragAppendMs, - avgDataFragAppendMs: null == i ? void 0 : i.avgDataFragAppendMs - }; - return ne(r.avgBufferCreateMs) || (r.avgBufferCreateMs = NaN), - ne(r.avgInitFragAppendMs) || (r.avgInitFragAppendMs = NaN), - ne(r.avgDataFragAppendMs) || (r.avgDataFragAppendMs = NaN), - r - } - }; - var $f = Uf; - class Vf { - constructor(e=0) { - this._minSamples = e, - this._sum = 0, - this._max = Number.NEGATIVE_INFINITY, - this._numSamples = 0 - } - get avg() { - return this._numSamples < this._minSamples ? NaN : this._sum / this._numSamples - } - get max() { - return 0 < this.count ? this._max : NaN - } - get count() { - return this._numSamples - } - reset() { - this._sum = 0, - this._numSamples = 0, - this._max = Number.NEGATIVE_INFINITY - } - add(e) { - this._sum += e, - this._max = Math.max(this._max, e), - ++this._numSamples - } - } - class Kf extends Od { - constructor(e, t) { - super(e), - this.id = t - } - getBandwidthEstimate(e, t) { - var i; - const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.bandwidthEstimate); - if (ne(r.avgBandwidth) && ne(r.avgLatencyMs)) - return r; - if (e) { - const i = Uf.getBandwidthEstimate(e, t); - ne(r.avgBandwidth) || (r.avgBandwidth = i.avgBandwidth), - ne(r.avgLatencyMs) || (r.avgLatencyMs = i.avgLatencyMs) - } - return r - } - getPlaylistEstimate(e, t) { - var i; - const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.playlistEstimate) - , n = e=>ne(e.avgPlaylistLoadTimeMs) && ne(e.avgPlaylistParseTimeMs); - if (n(r)) - return r; - if (e) { - const i = Uf.getPlaylistEstimate(e, t); - if (ne(r.avgPlaylistLoadTimeMs) || (r.avgPlaylistLoadTimeMs = i.avgPlaylistLoadTimeMs), - ne(r.avgPlaylistParseTimeMs) || (r.avgPlaylistParseTimeMs = i.avgPlaylistParseTimeMs), - n(r)) - return r; - ne(r.avgPlaylistLoadTimeMs) || (r.avgPlaylistLoadTimeMs = e.statDefaults.playlistLoadTimeMs), - ne(r.avgPlaylistParseTimeMs) || (r.avgPlaylistParseTimeMs = e.statDefaults.playlistParseTimeMs) - } - return r - } - getBufferEstimate(e, t) { - var i; - const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.bufferEstimate) - , n = e=>ne(e.avgBufferCreateMs) && ne(e.avgDataFragAppendMs) && ne(e.avgInitFragAppendMs); - if (n(r)) - return r; - if (e) { - const i = Uf.getBufferEstimate(e, t); - if (ne(r.avgBufferCreateMs) || (r.avgBufferCreateMs = i.avgBufferCreateMs), - ne(r.avgDataFragAppendMs) || (r.avgDataFragAppendMs = i.avgDataFragAppendMs), - ne(r.avgInitFragAppendMs) || (r.avgInitFragAppendMs = i.avgInitFragAppendMs), - n(r)) - return r; - ne(r.avgBufferCreateMs) || (r.avgBufferCreateMs = e.statDefaults.fragBufferCreationDelayMs), - ne(r.avgDataFragAppendMs) || (r.avgDataFragAppendMs = e.statDefaults.dataFragAppendMs), - ne(r.avgInitFragAppendMs) || (r.avgInitFragAppendMs = e.statDefaults.initFragAppendMs) - } - return r - } - getFragEstimate(e, t) { - var i; - const r = Object.assign({}, null === (i = this.statsEntity) || void 0 === i ? void 0 : i.fragEstimate) - , n = e=>ne(e.maxDurationSec) && ne(e.avgParseTimeMs); - if (n(r)) - return r; - if (e) { - const i = Uf.getFragEstimate(e, t); - if (ne(r.maxDurationSec) || (r.maxDurationSec = i.maxDurationSec), - ne(r.avgParseTimeMs) || (r.avgParseTimeMs = i.avgParseTimeMs), - n(r)) - return r; - ne(r.maxDurationSec) || (r.maxDurationSec = e.defaultTargetDuration), - ne(r.avgParseTimeMs) || (r.avgParseTimeMs = e.statDefaults.fragParseTimeMs) - } - return r - } - getCombinedEstimate() { - return Object.assign(Object.assign(Object.assign(Object.assign({}, this.getFragEstimate()), this.getPlaylistEstimate()), this.getBufferEstimate()), this.getBandwidthEstimate()) - } - get statsEntity() { - return this.getEntity(this.id) - } - get bandwidthSample() { - var e; - return null === (e = this.statsEntity) || void 0 === e ? void 0 : e.bandwidthSample - } - get bandwidthStatus() { - var e; - return null === (e = this.statsEntity) || void 0 === e ? void 0 : e.bandwidthStatus - } - get fragSample() { - var e; - return null === (e = this.statsEntity) || void 0 === e ? void 0 : e.fragSample - } - get bandwidthEstimate$() { - return this.selectEntity(this.id, "bandwidthEstimate") - } - get fragEstimate$() { - return this.selectEntity(this.id, "fragEstimate") - } - get playlistEstimate$() { - return this.selectEntity(this.id, "playlistEstimate") - } - get bufferEstimate$() { - return this.selectEntity(this.id, "bufferEstimate") - } - get bandwidthSample$() { - return this.selectEntity(this.id, ({bandwidthSample: e})=>e).pipe(Up()) - } - get fragSample$() { - return this.selectEntity(this.id, ({fragSample: e})=>e).pipe(Up()) - } - get playlistSample$() { - return this.selectEntity(this.id, ({playlistSample: e})=>e).pipe(Up()) - } - get bufferMetric$() { - return this.selectEntity(this.id, ({bufferMetric: e})=>e).pipe(Up()) - } - } - class Hf { - constructor(e) { - this.statsStore = e - } - getQuery() { - return new Od(this.statsStore) - } - getQueryForItem(e) { - return new Kf(this.statsStore,e) - } - remove(e) { - this.statsStore.remove(e) - } - removeAll() { - this.statsStore.remove() - } - setBandwidthSample(e) { - this.statsStore.bandwidthSample = e - } - setFragSample(e) { - this.statsStore.fragSample = e - } - setPlaylistSample(e) { - this.statsStore.playlistSample = e - } - setBufferMetric(e) { - this.statsStore.bufferMetric = e - } - setBandwidthEstimate(e) { - this.statsStore.bandwidthEstimate = e - } - setFragEstimate(e) { - this.statsStore.fragEstimate = e - } - setPlaylistEstimate(e) { - this.statsStore.playlistEstimate = e - } - setBufferEstimate(e) { - this.statsStore.bufferEstimate = e - } - } - const jf = new class extends pd { - constructor() { - super({}, { - name: "stats-store", - producerFn: vc - }) - } - set statsEntity(e) { - Co("statsStore.set.stats"), - sd(()=>{ - this.add(e), - this.setActive(e.id) - } - ) - } - set playlistSample(t) { - Co(`stats.set.playlistSample: ${t}`), - this.updateActive(e=>{ - e.playlistSample = t - } - ) - } - set bandwidthSample(t) { - Co(`stats.set.bandwidthSample: ${t}`), - this.updateActive(e=>{ - e.bandwidthSample = t, - e.bandwidthStatus.bandwidthSampleCount += 1, - e.bandwidthStatus.instantBw = 8e3 * t.loaded / (t.tload - t.trequest) - } - ) - } - set fragSample(t) { - Co(`stats.set.fragSample: ${t}`), - this.updateActive(e=>{ - e.fragSample = t - } - ) - } - set bufferMetric(t) { - Co(`stats.set.bufferMetric: ${t}`), - this.updateActive(e=>{ - e.bufferMetric = t - } - ) - } - set bandwidthEstimate(t) { - Co(`stats.set.bandwidthEstimate: ${t}`), - this.updateActive(e=>{ - e.bandwidthEstimate = t - } - ) - } - set fragEstimate(t) { - Co(`stats.set.fragEstimate: ${t}`), - this.updateActive(e=>{ - e.fragEstimate = t - } - ) - } - set playlistEstimate(t) { - Co(`stats.set.playlistEstimate: ${t}`), - this.updateActive(e=>{ - e.playlistEstimate = t - } - ) - } - set bufferEstimate(t) { - Co(`stats.set.bufferEstimate: ${t}`), - this.updateActive(e=>{ - e.bufferEstimate = t - } - ) - } - } - ; - let qf = null; - const Qf = e=>new Kf(jf,e); - function Gf(e, t) { - if (e === t) - return !0; - if (!e || !t) - return !1; - let i = Object.keys(e).length === Object.keys(t).length; - for (const r of Object.keys(e)) - i = i && (isNaN(e[r]) && isNaN(t[r]) || e[r] === t[r]); - return i - } - function Wf(f, m, g) { - return new Ut(e=>{ - (e=>{ - const t = Qf(e); - t.hasEntity(e) ? Bi(t) : (i = jf, - e = e, - Co("stats.loading"), - i.setLoading(!0), - i.statsEntity = { - id: e, - bandwidthEstimate: { - avgLatencyMs: NaN, - avgBandwidth: NaN - }, - bandwidthStatus: { - bandwidthSampleCount: 0, - instantBw: NaN - }, - fragEstimate: { - maxDurationSec: NaN, - avgParseTimeMs: NaN - }, - playlistEstimate: { - avgPlaylistLoadTimeMs: NaN, - avgPlaylistParseTimeMs: NaN - }, - bufferEstimate: { - avgBufferCreateMs: NaN, - avgInitFragAppendMs: NaN, - avgDataFragAppendMs: NaN - } - }, - i.setLoading(!1), - Co("stats.loaded")); - var i - } - )(g.itemId); - const t = Qf(g.itemId) - , {fragSample$: i, playlistSample$: r, bandwidthSample$: n, bufferMetric$: s} = t; - return nn(r.pipe(Hi(Zi), (h = f, - p = m, - e=>e.pipe(Ql.tag("statsPlaylistProcessingEpic.in"), na((e,t)=>(e.playlistLoadTimeMs.add(t.playlistLoadTimeMs), - e.playlistParseTimeMs.add(t.playlistParseTimeMs), - e), { - playlistLoadTimeMs: new Vf(h.minPlaylistCount), - playlistParseTimeMs: new Vf(h.minPlaylistCount) - }), ur(e=>({ - avgPlaylistLoadTimeMs: e.playlistLoadTimeMs.avg, - avgPlaylistParseTimeMs: e.playlistParseTimeMs.avg - })), Es(Gf), Ja(e=>{ - p.setPlaylistEstimate(e) - } - )))), n.pipe(Hi(Zi), (u = f, - c = m, - n=>new Ut(e=>{ - let t = new Bf(u.bandwidthHistoryWindowSize,u.bandwidthHistoryAggregationMethod,{ - avgLatencyMs: NaN, - avgBandwidth: NaN - }); - const i = t.estimate$ - , r = nn(n.pipe(an(e=>e.complete), Ja(e=>{} - ), ur(e=>({ - trequest: e.trequest, - tfirst: e.tfirst, - tload: e.tload, - bitsDownloaded: 8 * e.loaded - })), Ql.tag("statsBandwidthProcessingEpic.in"), Ra(e=>(t.record(e), - Ti))), i.pipe(Es(), Ql.tag("statsBandwidthProcessingEpic.change"), Ja(e=>{ - c && c.setBandwidthEstimate(e) - } - ))).subscribe(e); - return ()=>{ - r.unsubscribe(), - t.destroy(), - t = void 0 - } - } - ))), i.pipe(Hi(Zi), (d = f, - l = m, - e=>e.pipe(Ql.tag("statsFragProcessingEpic.in"), na((e,t)=>(e.durationSec.add(t.durationSec), - e.fragParseMs.add(t.parseTimeMs), - e), { - durationSec: new Vf, - fragParseMs: new Vf(d.minFragmentCount) - }), ur(e=>({ - maxDurationSec: e.durationSec.max, - avgParseTimeMs: e.fragParseMs.avg - })), Es(Gf), Ja(e=>l.setFragEstimate(e))))), s.pipe(Hi(Zi), (a = f, - o = m, - e=>e.pipe(Ql.tag("statsBufferMetricProcessingEpic.in"), na((e,t)=>(ne(t.bufferCreationStart) && ne(t.bufferCreationEnd) && e.bufferCreateMs.add(t.bufferCreationEnd - t.bufferCreationStart), - ne(t.startInitAppend) && ne(t.endInitAppend) && e.initFragAppendMs.add(t.endInitAppend - t.startInitAppend), - ne(t.startDataAppend) && ne(t.endDataAppend) && e.dataFragAppendMs.add(t.endDataAppend - t.startDataAppend), - e), { - bufferCreateMs: new Vf, - initFragAppendMs: new Vf, - dataFragAppendMs: new Vf(a.minFragmentCount) - }), ur(e=>({ - avgBufferCreateMs: e.bufferCreateMs.avg, - avgInitFragAppendMs: e.initFragAppendMs.avg, - avgDataFragAppendMs: e.dataFragAppendMs.avg - })), Es(Gf), Ja(e=>{ - o.setBufferEstimate(e) - } - ))))).pipe(Ua(Ti)).subscribe(e), - ()=>{ - $f.setCombinedEstimate(f, Object.assign(Object.assign(Object.assign(Object.assign({}, t.getFragEstimate()), t.getPlaylistEstimate()), t.getBufferEstimate()), t.getBandwidthEstimate()), g.serviceName), - m.remove(g.itemId) - } - ; - var a, o, d, l, u, c, h, p - } - ) - } - const zf = { - isWebkitMediaElement: e=>"webkitDroppedFrameCount"in e, - isHtmlVideoElement: e=>"getVideoPlaybackQuality"in e, - timeRangeToArray(t) { - const i = []; - for (let e = 0; e < t.length; e++) - i.push([t.start(e), t.end(e)]); - return i - } - }; - class Xf extends Ut { - constructor() { - super(e=>this.works$.pipe(ur(e=>Lr(e)), zr()).subscribe(e)), - this.works$ = new zt - } - addWork(e) { - this.works$.next(e) - } - complete() { - this.works$.complete() - } - } - class Yf { - constructor(e, t) { - this.hls = e, - this.sessionID = t, - this.rtcQuery = null, - this.accessLogData = this.createAccessLogEntry(), - this.accesslog = [], - this.errorlog = [] - } - destroy() { - this.rtcQuery = null, - this.accesslog = [], - this.errorlog = [], - this.accessLogData = void 0, - this.accessLogReporter = void 0 - } - setRTCQuery(e) { - this.rtcQuery = e - } - setupReporter(e) { - this.accessLogReporter = { - SessionID: this.sessionID, - ClientName: null == e ? void 0 : e.clientName, - ServiceName: null == e ? void 0 : e.serviceName - } - } - addPlayTime(e) { - var t, e = null === (t = this.rtcQuery) || void 0 === t ? void 0 : t.getEntity(e); - !e || "RTC_STATE_PLAY" === (e = e.sessionControlRecord).state && (this.accessLogData.PlayTimeWC = (this.accessLogData.PlayTimeWC || 0) + e.eventStartTime) - } - updatePlaybackInfo(e, t) { - this.accessLogData.ViFrDr = this.rtcQuery.getEntity(e).sessionControlRecord.droppedVideoFrames || 0 - } - updateStallCount(e) { - "RTC_STATE_PLAY" === this.rtcQuery.getEntity(e).sessionControlRecord.state && this.accessLogData.StallCount++ - } - updateMediaEngineStallCount(e) { - "RTC_STATE_PLAY" === this.rtcQuery.getEntity(e).sessionControlRecord.state && this.accessLogData.MediaEngineStallCount++ - } - updateCanPlay(e) { - this.accessLogData.StartupTime = this.rtcQuery.getEntity(e).sessionControlRecord.eventStartTime - } - updateFragLoaded(e, t, i) { - var r; - i.fragType === ul.Variant ? (this.accessLogData.NetBytes += i.bytes, - this.accessLogData.ADT += i.adt, - r = this.aggregateFragObserverdBitrate(i, ++this.accessLogData.fragmentCnt, this.accessLogData.NetBytes, this.accessLogData.ADT), - this.accessLogData.OBRLast = r.obrLast, - this.accessLogData.OBRMean = r.obrMean, - this.aggregateFragMinMaxBitrate(this.accessLogData, r.obr), - this.hls.realCurrentTime > i.startPTS && !t && this.accessLogData.overdue++, - this.hasGap(i.startPTS, i.endPTS, this.accessLogData.lastStartPTS, this.accessLogData.lastEndPTS) && this.addToAccessLog(e), - this.accessLogData.startPTS || (this.accessLogData.startPTS = i.startPTS), - this.accessLogData.lastStartPTS = i.startPTS, - this.accessLogData.lastEndPTS = i.endPTS, - this.accessLogData.videoBytes += i.bytes, - this.accessLogData.videoDuration += i.duration) : i.fragType === ul.AltAudio && (this.accessLogData.audioBytes += i.bytes, - this.accessLogData.audioDuration += i.duration) - } - addToAccessLog(e) { - var t = this.getVariantInfo(e) - , i = this.rtcQuery.getEntity(e).sessionControlRecord.curLevelUrl - , r = this.rtcQuery.getEntity(e).playEndedRecord.PlayType; - if (i && "" !== i) { - r = this.translateToAccessLogItem(e, i, t, r); - if (r) { - const n = this.accesslog.length - 20; - 0 < n && this.accesslog.splice(0, n), - this.accesslog.push(r) - } - this.accessLogData = this.createAccessLogEntry(); - e = this.rtcQuery.getEntity(e).switchCompleteRecord.MediaDur; - this.accessLogData.lastMediaDur = e || this.hls.bufferedDuration - } - } - addToErrorLog(e, t) { - var i = null === (r = this.rtcQuery) || void 0 === r ? void 0 : r.getEntity(e); - if (i) { - var r = Number(("mediaError" === t ? i.playErrorRecord : i.nwErrorRecord).ErrCode) - , i = i.sessionControlRecord.curLevelUrl - , r = this.translateToErrorLogItem(e, i, { - domain: t, - code: r - }); - if (r) { - const e = this.errorlog.length - 20; - 0 < e && this.errorlog.splice(0, e), - this.errorlog.push(r) - } - } - } - getAccessLog(e) { - var t; - const i = this.accesslog.slice(0) - , r = null === (t = this.rtcQuery) || void 0 === t ? void 0 : t.getEntity(e); - if (i && r) { - const t = r.sessionControlRecord.curLevelUrl; - if (t && "" !== t) { - const r = this.getVariantInfo(e) - , n = this.translateToAccessLogItem(e, t, r, this.rtcQuery.getEntity(e).playEndedRecord.PlayType); - n && (n["c-provisional-entry"] = !0, - i.push(n)) - } - } - return i - } - get errorLog() { - return this.errorlog - } - createAccessLogEntry() { - return { - fragmentCnt: 0, - overdue: 0, - startPTS: 0, - obrMax: 0, - obrMin: 0, - audioBytes: 0, - audioDuration: 0, - videoBytes: 0, - videoDuration: 0, - svrAddrChanged: 0, - svrAddr: "", - PlayTimeWC: 0, - ViFrDr: 0, - StallCount: 0, - MediaEngineStallCount: 0, - ADT: 0, - NetBytes: 0, - StartupTime: 0, - OBRMean: 0, - OBRLast: 0 - } - } - convertStringObjectToPrimitive(e) { - return e ? "object" == typeof e ? e.toString() : e : "" - } - updateSvrAddrStats(t) { - const i = fl.parseURL(t); - if (i && i.netLoc) { - const t = i.netLoc.indexOf(":"); - let e = 0 <= t ? i.netLoc.slice(0, t) : i.netLoc; - e.startsWith("//") && (e = e.slice(2)), - this.accessLogData.svrAddr ? e !== this.accessLogData.svrAddr && this.accessLogData.svrAddrChanged++ : this.accessLogData.svrAddrChanged = 0, - this.accessLogData.svrAddr = e - } - } - translateToAccessLogItem(e, t, i, r) { - t = this.convertStringObjectToPrimitive(t); - this.updateSvrAddrStats(t); - let n = this.rtcQuery.getEntity(e).switchCompleteRecord.MediaDur; - n = n || this.hls.bufferedDuration, - n = n || 0; - const s = { - uri: t, - "s-ip": this.accessLogData.svrAddr, - "s-ip-changes": this.accessLogData.svrAddrChanged, - "sc-wwan-count": -1, - "c-transfer-duration": this.accessLogData.ADT, - bytes: this.accessLogData.NetBytes, - "c-total-media-requests": this.accessLogData.fragmentCnt, - "cs-guid": this.accessLogReporter.SessionID, - "c-start-time": this.accessLogData.startPTS, - "c-startup-time": this.accessLogData.StartupTime, - "c-duration-watched": this.accessLogData.PlayTimeWC / 1e3, - "c-frames-dropped": this.accessLogData.ViFrDr, - "c-stalls": this.accessLogData.StallCount + this.accessLogData.MediaEngineStallCount, - "c-duration-downloaded": this.accessLogData.lastMediaDur ? n - this.accessLogData.lastMediaDur : n, - "c-overdue": this.accessLogData.overdue, - "c-avg-video-bitrate": 8 * this.accessLogData.videoBytes / (this.accessLogData.videoDuration || 1), - "c-observed-max-bitrate": this.accessLogData.obrMax, - "c-observed-min-bitrate": this.accessLogData.obrMin, - "sc-indicated-bitrate": i.bandwidth || 0, - "sc-indicated-avg-bitrate": i.avgBandwidth || 0, - "c-observed-bitrate": this.accessLogData.OBRMean, - "c-switch-bitrate": this.accessLogData.OBRLast, - "c-provisional-entry": !1 - }; - return s["s-playback-type"] = r, - this.accessLogData.audioBytes && (s["c-avg-audio-bitrate"] = 8 * this.accessLogData.audioBytes / (this.accessLogData.audioDuration || 1)), - s - } - translateToErrorLogItem(e, t, i) { - t = this.convertStringObjectToPrimitive(t); - return this.updateSvrAddrStats(t), - { - date: new Date, - "cs-guid": this.accessLogReporter.SessionID + "-" + e, - uri: t, - "s-ip": this.accessLogData.svrAddr, - status: "" + i.code, - domain: i.domain - } - } - hasGap(e, t, i, r) { - return void 0 !== e && void 0 !== i && (1 < e - r || 1 < i - t) - } - aggregateFragObserverdBitrate(e, t, i, r) { - r = 8 * i / (r / 1e3); - return { - obr: r, - obrLast: 8 * e.bytes / (e.adt / 1e3), - obrMean: r / t - } - } - aggregateFragMinMaxBitrate(e, t) { - (!e.obrMax || t > e.obrMax) && (e.obrMax = t), - (!e.obrMin || t < e.obrMin) && (e.obrMin = t) - } - getVariantInfo(e) { - var t = this.rtcQuery.getEntity(e).sessionControlRecord.curLevelUrl - , e = null === (e = this.rtcQuery.getEntity(e).sessionControlRecord.manifestData) || void 0 === e ? void 0 : e.variantList; - return t && e && e[t] ? e[t] : {} - } - } - const Jf = (r,e,t,i,n,s)=>{ - var a, {absoluteUrl: o, byteRangeOffset: d, keyTagInfo: l, iframe: u, isInitSegment: c} = r, h = o, p = l["method"], {start: o, end: l} = d, t = xc({ - url: h - }, t); - let f, m = o, g = l, y = !1, v = ne(o) || ne(l) ? d : void 0; - if ("AES-128" === p && l && (u || c)) { - const r = l - o; - r % 16 && (g = l + (16 - r % 16)), - 0 !== o && (y = !0, - m = o - 16), - v = { - start: m, - end: g - } - } - return n && ne(r.mediaSeqNum) && r.mediaOptionType === ul.Variant && (f = [], - null === (n = t.reportHTTPResponseHeaders) || void 0 === n || n.forEach(function(e) { - vl.includes(e) ? f.push(e) : qe().warn({ - name: "load-media-fragment" - }, `${e} is not in approved privacy list. Actions required.`) - }), - 0 === f.length && (f = void 0)), - Pc({ - url: h, - byteRangeOffset: v, - checkContentLength: !0, - extendMaxTTFB: s, - collectServerInstanceInfo: f, - onProgress: i, - xhrSetup: e.xhrSetup - }, t).pipe(ur(([e,t,i])=>{ - if (y) { - const t = e; - r.keyTagInfo.iv = new Uint8Array(t.slice(0, 16)), - e = t.slice(16) - } - return [r, e, t, i] - } - ), (a = r, - e=>e.pipe(Un(e=>{ - if (e instanceof ou) - throw new au(!1,"Timeout",0,$.FragmentTimeoutError,!0,a,e.stats); - if (e instanceof tu) - throw new au(!1,e.message,e.code,{ - code: e.code, - text: "Fragment Network Error" - },!1,a); - throw e - } - )))) - } - , Zf = { - clearkey: Zc, - fairplaystreaming: pu, - playready: _c, - widevine: Nc - } - , em = { - getKeySystemFormat(e) { - e = Zf[e]; - return e ? e.keyFormatString : "" - }, - getKeySystemSecurityLevel(e) { - e = Zf[e]; - return e ? e.securityLevels : null - } - } - , tm = { - NONE: "", - "AES-128": "", - "ISO-23001-7": "", - "SAMPLE-AES": "", - "SAMPLE-AES-CTR": "" - } - , im = { - NONE: 0, - "TYPE-0": 1, - "TYPE-1": 2, - "TYPE-2": 3 - }; - function rm(e) { - return e in im - } - function nm(e) { - return null == e ? 4 : im[e] - } - const sm = ["SDR", "PQ", "HLG"] - , am = { - afr: "af", - aka: "ak", - amh: "am", - ara: "ar", - arg: "an", - asm: "as", - ava: "av", - ave: "ae", - aym: "ay", - aze: "az", - bam: "bm", - bel: "be", - ben: "bn", - bih: "bh", - bod: "bo", - bos: "bs", - bre: "br", - bul: "bg", - cat: "ca", - ces: "cs", - cha: "ch", - che: "ce", - chu: "cu", - chv: "cv", - cor: "kw", - cos: "co", - cre: "cr", - cym: "cy", - dan: "da", - deu: "de", - div: "dv", - dzo: "dz", - ell: "el", - eng: "en", - epo: "eo", - est: "et", - eus: "eu", - ewe: "ee", - fao: "fo", - fas: "fa", - fin: "fi", - fra: "fr", - fry: "fy", - ful: "ff", - gla: "gd", - gle: "ga", - glg: "gl", - glv: "gv", - grn: "gn", - guj: "gu", - hat: "ht", - heb: "he", - her: "hz", - hin: "hi", - hmo: "ho", - hrv: "hr", - hun: "hu", - hye: "hy", - ibo: "ig", - ido: "io", - iii: "ii", - iku: "iu", - ile: "ie", - ina: "ia", - ind: "id", - isl: "is", - ita: "it", - jav: "jv", - jpn: "ja", - kal: "kl", - kan: "kn", - kas: "ks", - kat: "ka", - kau: "kr", - kaz: "kk", - khm: "km", - kik: "ki", - kin: "rw", - kir: "ky", - kom: "kv", - kon: "kg", - kor: "ko", - kua: "kj", - kur: "ku", - lao: "lo", - lat: "la", - lav: "lv", - lim: "li", - lit: "lt", - ltz: "lb", - lub: "lu", - lug: "lg", - mah: "mh", - mal: "ml", - mar: "mr", - mkd: "mk", - mlg: "mg", - mlt: "mt", - mol: "mo", - mon: "mn", - mri: "mi", - msa: "ms", - mya: "my", - nav: "nv", - nbl: "nr", - nde: "nd", - ndo: "ng", - nep: "ne", - nld: "nl", - nno: "nn", - nob: "nb", - nya: "ny", - oci: "oc", - oji: "oj", - ori: "or", - orm: "om", - oss: "os", - pan: "pa", - pli: "pi", - pol: "pl", - por: "pt", - pus: "ps", - que: "qu", - roh: "rm", - ron: "ro", - run: "rn", - rus: "ru", - san: "sa", - sin: "si", - slk: "sk", - slv: "sl", - sme: "se", - snd: "sd", - som: "so", - spa: "es", - sqi: "sq", - srd: "sc", - srp: "sr", - sun: "su", - swa: "sw", - swe: "sv", - tah: "ty", - tam: "ta", - tat: "tt", - tel: "te", - tgk: "tg", - tgl: "tl", - tha: "th", - tir: "ti", - ton: "to", - tuk: "tk", - tur: "tr", - uig: "ug", - ukr: "uk", - urd: "ur", - uzb: "uz", - ven: "ve", - vie: "vi", - wln: "wa", - yid: "yi", - zha: "za", - zho: "zh" - } - , om = { - isLanguageCode: e=>e in am, - shortenLanguageCode(e) { - let t; - var i, r; - return e && (r = 0 <= (i = e.indexOf("-")) ? e.slice(0, i) : e, - om.isLanguageCode(r) && (t = am[r]), - t = t || r, - 0 < i && (t += "-" + e.slice(i + 1))), - t - } - } - , dm = { - getRichestVideoCodec(e) { - if (e && e.length) { - e = e.sort((e,t)=>$p(t) - $p(e)); - return e && e.length ? e[0] : void 0 - } - }, - getRichestAudioCodec(e) { - if (e && e.length) { - e = e.sort((e,t)=>Kp(t) - Kp(e)); - return e && e.length ? e[0] : void 0 - } - }, - getRichestChannelLayoutForGroupId(t, i) { - if (t && i && i.length) { - let e; - const r = i.filter(e=>e.groupId === t); - if (r && r.length) { - const t = r.sort((e,t)=>Se.getChannelCount(t.channels) - Se.getChannelCount(e.channels)); - t && t.length && (e = t[0].channels) - } - return e - } - } - }; - function lm(e) { - return new R(L,"steeringManifestParsingError",!1,e,$.FormatError) - } - class um { - constructor(e) { - this._url = null, - this._programDateTime = null, - this._byteRange = null, - this.relurl = null, - this.baseurl = null, - this.isInitSegment = !1, - this.mediaSeqNum = NaN, - this.cc = NaN, - this.iframe = !1, - this.bitrate = NaN, - this.start = NaN, - this.duration = NaN, - this.lastByteRangeEndOffset = NaN, - this.inheritQuery = e, - this.tagList = new Array, - this.iframe = !1 - } - getMediaFragment(e, t, i) { - const r = { - mediaOptionType: i, - absoluteUrl: this.url, - start: this.start, - duration: this.duration, - mediaSeqNum: this.mediaSeqNum, - discoSeqNum: this.cc, - mediaOptionId: t, - itemId: e, - isLastFragment: !1, - isInitSegment: this.isInitSegment - }; - return null !== (e = this.byteRange) && void 0 !== e && e.length && (r.byteRangeOffset = { - start: this.byteRangeStartOffset, - end: this.byteRangeEndOffset - }), - this.iframe && (r.iframe = this.iframe), - this.levelkey && (r.keyTagInfo = this.levelkey), - this.programDateTime && (r.programDateTime = this.programDateTime), - r - } - get url() { - return !this._url && this.relurl && this.baseurl && (this._url = fl.buildAbsoluteURL(this.baseurl, this.relurl, { - alwaysNormalize: !0, - inheritQuery: this.inheritQuery - })), - this._url - } - set url(e) { - this._url = e - } - get programDateTime() { - return !this._programDateTime && this.rawProgramDateTime && (this._programDateTime = new Date(Date.parse(this.rawProgramDateTime))), - this._programDateTime - } - get byteRange() { - if (!this._byteRange) { - const i = new Array(2); - var e, t; - this.rawByteRange && (1 === (e = this.rawByteRange.split("@", 2)).length ? (t = this["lastByteRangeEndOffset"], - i[0] = t || 0) : i[0] = parseInt(e[1]), - i[1] = parseInt(e[0]) + i[0]), - this._byteRange = i - } - return this._byteRange - } - get byteRangeStartOffset() { - return this.byteRange[0] - } - get byteRangeEndOffset() { - return this.byteRange[1] - } - get rangeString() { - return 0 <= this.start && 0 <= this.duration ? `${this.start.toFixed(2)}-${(this.start + this.duration).toFixed(2)}` : "N/A" - } - get fragTag() { - return `sn/cc/levelId: ${this.mediaSeqNum}/${this.cc}` - } - } - const cm = { - parseMediaCharacteristics: e=>e ? e.split(/\s*,\s*/) : new Array, - addMediaToSelectionArray(e, t, i) { - if (void 0 === e) - return -1; - const r = e.MediaSelectionGroupOptions; - let n = r.find(e=>e.MediaSelectionOptionsMediaType === t.mediaType && e.MediaSelectionOptionsName === t.name && e.MediaSelectionOptionsExtendedLanguageTag === t.lang); - return n || (n = { - MediaSelectionOptionsMediaType: t.mediaType, - MediaSelectionOptionsExtendedLanguageTag: t.lang, - MediaSelectionOptionsIsDefault: t.default, - MediaSelectionOptionsName: t.name, - MediaSelectionOptionsPersistentID: i, - MediaSelectionOptionsTaggedMediaCharacteristics: t.characteristics - }, - t.mediaType === pl.SUBTITLE && (n.MediaSelectionOptionsDisplaysNonForcedSubtitles = t.forced ? hl.NO : hl.YES), - i++, - r.push(n)), - t.persistentID = n.MediaSelectionOptionsPersistentID, - i - }, - addDefaultClosedCaptionOption(e, t, i, r) { - e = { - itemId: e, - mediaOptionType: ul.Subtitle, - id: 0, - mediaOptionId: "cc1_" + Jd(), - mediaType: pl.CLOSEDCAPTION, - inStreamID: "CC1", - groupId: "cc", - name: "English-CC", - type: "CLOSED-CAPTIONS", - default: !1, - autoselect: !1, - forced: !1, - lang: "en", - characteristics: ["public.accessibility.transcribes-spoken-dialog", "public.accessibility.describes-music-and-sound"], - persistentID: r - }; - t.push(e), - cm.addMediaToSelectionArray(i, e, r) - } - } - , hm = { - BANDWIDTH: NaN, - "AVERAGE-BANDWIDTH": NaN - } - , pm = { - "TIME-OFFSET": NaN, - "FRAME-RATE": NaN, - SCORE: NaN, - "PLANNED-DURATION": NaN, - DURATION: NaN - } - , fm = /^(\d+)x(\d+)$/ - , mm = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; - class gm { - constructor(e) { - this.validTags = e - } - isKey(e) { - return e in this.validTags - } - trySetValue(e, t, i) { - return !!this.isKey(e) && (i[e] = this.parseFunc(t), - !0) - } - } - class ym { - static parseTags(t) { - let i; - var r = {}; - if (!t) - return r; - for (mm.lastIndex = 0; null !== (i = mm.exec(t)); ) { - const t = i[1].toUpperCase(); - let e = i[2]; - 0 === e.indexOf('"') && e.lastIndexOf('"') === e.length - 1 && (e = e.slice(1, -1)); - for (const i of ym.tagParsers) - if (i.trySetValue(t, e, r)) - break - } - return r - } - } - ym.tagParsers = [new class extends gm { - parseFunc(e) { - return e - } - } - ({ - NAME: "", - TYPE: "", - DEFAULT: "", - AUTOSELECT: "", - FORCED: "", - LANGUAGE: "", - URI: "", - AUDIO: "", - "VIDEO-RANGE": "", - "CLOSED-CAPTIONS": "", - CODECS: "", - BYTERANGE: "", - "INSTREAM-ID": "", - "GROUP-ID": "", - CHANNELS: "", - CHARACTERISTICS: "", - KEYFORMAT: "", - KEYFORMATVERSIONS: "", - "DATA-ID": "", - VALUE: "", - METHOD: "", - "HDCP-LEVEL": "", - "ALLOWED-CPC": "", - SUBTITLES: "", - ID: "", - CLASS: "", - "START-DATE": "", - "END-DATE": "", - "END-ON-NEXT": "", - "SERVER-URI": "", - "PATHWAY-ID": "" - }), new class extends gm { - parseFunc(e) { - e = parseInt(e); - return e > Number.MAX_SAFE_INTEGER ? 1 / 0 : e - } - } - (hm), new class extends gm { - constructor() { - super(...arguments), - this.parseFunc = parseFloat - } - } - (pm), new class extends gm { - parseFunc(e) { - let t = (e || "0x").slice(2); - t = (1 & t.length ? "0" : "") + t; - const i = new Uint8Array(t.length / 2); - for (let e = 0; e < t.length / 2; e++) { - var r = parseInt(t.slice(2 * e, 2 * e + 2), 16); - if (!ne(r)) - return; - i[e] = r - } - return i - } - } - ({ - IV: null - }), new class extends gm { - parseFunc(e) { - e = fm.exec(e); - let t; - return null !== e && (t = { - width: parseInt(e[1], 10), - height: parseInt(e[2], 10) - }), - t - } - } - ({ - RESOLUTION: null - })]; - const vm = { - ExtractVariableParameter: /{\$(.*?)}/g, - LevelPlaylistFast: /#EXTINF:(\d*(?:\.\d+)?)(?:,(.*))?|(?!#)(\S.+)|#EXT-X-BYTERANGE: *(.+)|#EXT-X-PROGRAM-DATE-TIME:(.+)|#EXT-X-BITRATE:(.+)|#EXT-X-DATERANGE:(.+)|#.*/g, - LevelPlaylistSlow: /(?:(?:#(EXTM3U))|(?:#EXT-X-(PLAYLIST-TYPE):(.+))|(?:#EXT-X-(MEDIA-SEQUENCE): *(\d+))|(?:#EXT-X-(TARGETDURATION): *(\d+))|(?:#EXT-X-(KEY):(.+))|(?:#EXT-X-(START):(.+))|(?:#EXT-X-(ENDLIST))|(?:#EXT-X-(DISCONTINUITY-SEQ)UENCE:(\d+))|(?:#EXT-X-(DIS)CONTINUITY))|(?:#EXT-X-(VERSION):(\d+))|(?:#EXT-X-(MAP):(.+))|(?:#EXT-X-(I-FRAMES)-ONLY)|(?:#EXT-X-(DEFINE):(.+))|(?:(#)(.*):(.*))|(?:(#)(.*))(?:.*)\r?\n?/, - MasterPlaylist: /#EXT-X-STREAM-INF:([^\n\r]*)[\r\n]+([^\r\n]+)|#EXT-X-I-FRAME-STREAM-INF:([^\r\n]+)|#EXT-X-DEFINE:([^\n\r]*)|#EXT-X-CONTENT-STEERING:([^\n\r]*)/g, - MasterPlaylistAlternateMedia: /#EXT-X-MEDIA:(.*)/g, - SessionData: /#EXT-X-SESSION-DATA[^:]*:(.*)/g, - SessionKeys: /#EXT-X-SESSION-KEY:([^\n\r]*)/g, - VARIABLE_PLAYLIST_REGEX: /(NAME|VALUE)=\"(.*)\",(NAME|VALUE)=\"(.*)\"|(IMPORT)=\"(.*)\"/ - }; - function Sm(e, t, i) { - return sl.buildAbsoluteURL(t, e, { - alwaysNormalize: !0, - inheritQuery: i - }) - } - class bm { - static isValidPlaylist(e) { - return 0 === e.indexOf("#EXTM3U") - } - static isMediaPlaylist(e) { - return 0 < e.indexOf("#EXTINF:") || 0 < e.indexOf("#EXT-X-PLAYLIST-TYPE:") - } - static replaceVariables(e, t) { - let i, r = !1; - return e && t && (i = e.replace(vm.ExtractVariableParameter, e=>{ - vm.ExtractVariableParameter.lastIndex = 0; - e = vm.ExtractVariableParameter.exec(e)[1]; - if (e && t.hasOwnProperty(e)) - return t[e]; - r = !0 - } - )), - { - updatedString: i, - error: r - } - } - static parseDecryptData(e, t, i) { - const r = ym.parseTags(e) - , n = (e = r.METHOD) && e in tm ? r.METHOD : null; - e = null !== (e = r.KEYFORMAT) && void 0 !== e ? e : null; - if (n && bm.shouldSelectKeyTag(e, n, i)) { - const s = r.URI - , i = r.IV || null; - if (s && r.IV && !i) { - const s = new R(L,_,!0,`Invalid IV: ${r.IV}`,$.PlaylistErrorInvalidEntry); - throw s.url = t, - s - } - const a = s ? sl.buildAbsoluteURL(t, s, { - alwaysNormalize: !0 - }) : t - , o = (r.KEYFORMATVERSIONS || "1").split("/").map(Number).filter(isFinite); - return new Gc(n,a,i,e,o) - } - } - static shouldSelectKeyTag(e, t, i) { - return "AES-128" === t || "NONE" === t || null == i || e === em.getKeySystemFormat(i) - } - static optOutClosedCaption(t) { - let i = !1 - , r = !1; - if (t) - for (let e = 0; e < t.length; ++e) { - const n = t[e]; - if (n.videoCodec && ((r = !0) !== n.iframes && n.closedcaption && "none" === n.closedcaption.toLowerCase())) { - i = !0; - break - } - } - return !r || i - } - static parseRootPlaylistAlternateMediaOptions(a, o, d, l, u, c) { - let h, p; - var f = { - MediaSelectionGroupAllowEmptySelection: 1, - MediaSelectionGroupMediaCharacteristics: ["public.audible"], - MediaSelectionGroupMediaType: pl.AUDIO, - MediaSelectionGroupOptions: [] - } - , m = { - MediaSelectionGroupAllowEmptySelection: 1, - MediaSelectionGroupMediaCharacteristics: ["public.legible"], - MediaSelectionGroupMediaType: pl.SUBTITLE, - MediaSelectionGroupOptions: [] - } - , g = { - videoAlternateOptions: [], - audioAlternateOptions: [], - subtitleAlternateOptions: [], - audioMediaSelectionGroup: f, - subtitleMediaSelectionGroup: m - }; - let y = 0; - for (vm.MasterPlaylistAlternateMedia.lastIndex = 0; null != (h = vm.MasterPlaylistAlternateMedia.exec(o)); ) { - const o = bm.replaceVariables(h[1], c); - if (o.error) { - p = new R(L,N,!0,$.PlaylistErrorInvalidEXTXDEFINE.text,$.PlaylistErrorInvalidEXTXDEFINE); - break - } - var v = ym.parseTags(o.updatedString); - let e, t, i, r = pl.UNKNOWN; - const S = cm.parseMediaCharacteristics(v.CHARACTERISTICS) - , b = v["GROUP-ID"] - , T = v.CHANNELS; - let n, s = null; - switch (v.TYPE) { - case "VIDEO": - r = pl.VIDEO, - t = g.videoAlternateOptions; - break; - case "AUDIO": - r = pl.AUDIO, - s = ul.AltAudio, - t = g.audioAlternateOptions, - i = f; - const a = l.find(e=>e.audioGroupId === b); - n = a ? a.audioCodecList : []; - break; - case "SUBTITLES": - r = pl.SUBTITLE, - s = ul.Subtitle, - t = g.subtitleAlternateOptions, - i = m; - break; - case "CLOSED-CAPTIONS": - r = pl.CLOSEDCAPTION, - s = ul.Subtitle, - e = v["INSTREAM-ID"], - t = g.subtitleAlternateOptions, - i = m - } - const E = { - itemId: a, - mediaOptionType: s, - mediaType: r, - groupId: b, - channels: T, - groupCodecList: n, - name: v.NAME, - type: v.TYPE, - default: "YES" === v.DEFAULT, - autoselect: "YES" === v.AUTOSELECT, - forced: "YES" === v.FORCED, - characteristics: S, - persistentID: y, - id: t ? t.length : 0, - mediaOptionId: `${v.NAME}_${b}_${y}`, - lang: om.shortenLanguageCode(v.LANGUAGE) - }; - v.URI && (E.url = Sm(v.URI, d, u)), - E.name || (E.name = E.lang, - E.mediaType === pl.CLOSEDCAPTION && (E.name += " CC")), - E.mediaType === pl.CLOSEDCAPTION && e && (E.inStreamID = e), - t && (E.id = t.length, - t.push(E)), - y = cm.addMediaToSelectionArray(i, E, y) - } - return 0 !== g.subtitleAlternateOptions.length || bm.optOutClosedCaption(l) || cm.addDefaultClosedCaptionOption(a, g.subtitleAlternateOptions, m, y), - { - alternateMediaInfo: g, - playlistParsingError: p - } - } - static parseMediaOptionPlaylist(e, t, i=!0, r, n, s, a, o, d, l=0) { - var u; - let c = 0 - , h = 0; - const p = { - itemId: s, - mediaOptionId: a, - mediaOptionType: o, - type: "", - version: 0, - url: t, - initSegments: {}, - fragments: [], - liveOrEvent: !0, - startSN: 0, - endSN: 0, - iframesOnly: !1, - targetduration: 0, - totalduration: 0, - averagetargetduration: 0, - ptsKnown: !1 - }; - let f, m, g, y = new Gc("NONE",t,null,null,null), v = !1, S = !1, b = 0, T = null, E = new um(i), I = 0; - const w = {}; - let A, O, k, C = !0, D = !0; - vm.LevelPlaylistFast.lastIndex = 0; - for (var M = ()=>new R(L,_,!0,"Invalid key system preference for the playlist",$.IncompatibleAsset); null !== (f = vm.LevelPlaylistFast.exec(e)); ) { - const e = f[1]; - if (e) { - E.duration = parseFloat(e); - const t = (" " + f[2]).slice(1); - E.title = t || null, - E.tagList.push(t ? ["INF", e, t] : ["INF", e]) - } else if (f[3]) { - if (ne(E.duration)) { - const e = c++; - if (E.start = h + l, - E.levelkey = y, - S && !v) { - O = M(); - break - } - if (v = !1, - S = !1, - E.mediaSeqNum = e, - E.cc = b, - E.iframe = p.iframesOnly, - E.baseurl = t, - (A = bm.replaceVariables((" " + f[3]).slice(1), w)).error) { - O = new R(L,N,!0,$.PlaylistErrorInvalidEXTXDEFINE.text,$.PlaylistErrorInvalidEXTXDEFINE); - break - } - if (E.relurl = A.updatedString, - E.bitrate = ne(E.byteRangeEndOffset) ? 8 * (E.byteRangeEndOffset - E.byteRangeStartOffset) / E.duration : I, - null != g) { - E.rawProgramDateTime = g, - E.tagList.push(["PROGRAM-DATE-TIME", E.rawProgramDateTime]); - const e = E.programDateTime.getTime(); - p.programDateTimeMap = null !== (u = p.programDateTimeMap) && void 0 !== u ? u : {}, - p.programDateTimeMap[e] = E.mediaSeqNum, - p.dateMediaTimePairs = null !== (u = p.dateMediaTimePairs) && void 0 !== u ? u : [], - p.dateMediaTimePairs.push([e, E.start]), - g = void 0 - } - if (p.fragments.push(E.getMediaFragment(s, a, o)), - T = E, - h += E.duration, - C || !p.initSegments[b] || D) - if (p.iframesOnly && 0 < E.byteRangeStartOffset && !p.initSegments[b] && !D) { - const e = new um(i); - if (e.url = E.url, - e.rawByteRange = Math.min(E.byteRangeStartOffset, 1316) + "@0", - e.baseurl = t, - e.isInitSegment = !0, - e.cc = b, - e.levelkey = y, - e.iframe = !0, - S && !v) { - O = M(); - break - } - v = !1, - S = !1, - p.initSegments[b] = e.getMediaFragment(s, a, o) - } else - k && (k.discoSeqNum = b, - p.initSegments[b] = k); - C = !1, - D = !1, - E = new um(i) - } - } else if (f[4]) { - if (E.rawByteRange = (" " + f[4]).slice(1), - T) { - const e = T.byteRangeEndOffset; - e && (E.lastByteRangeEndOffset = e) - } - } else if (f[5]) - g = (" " + f[5]).slice(1); - else if (f[6]) { - const e = parseInt(f[6]); - ne(e) && (I = 1e3 * e) - } else if (f[7]) { - const e = f[7] - , t = ym.parseTags(e); - t.ID && (p.daterangeTags || (p.daterangeTags = {}), - p.daterangeTags[t.ID] = t) - } else { - for (f = f[0].match(vm.LevelPlaylistSlow), - m = 1; m < f.length && void 0 === f[m]; m++) - ; - const e = bm.replaceVariables((" " + f[m + 1]).slice(1), w) - , d = bm.replaceVariables((" " + f[m + 2]).slice(1), w); - if (e.error || d.error) { - O = new R(L,N,!0,$.PlaylistErrorInvalidEXTXDEFINE.text,$.PlaylistErrorInvalidEXTXDEFINE); - break - } - const l = e.updatedString - , P = d.updatedString; - switch (f[m]) { - case "#": - E.tagList.push(P ? [l, P] : [l]); - break; - case "PLAYLIST-TYPE": - p.type = l.toUpperCase(), - "VOD" === p.type && (p.liveOrEvent = !1); - break; - case "MEDIA-SEQUENCE": - 0 === p.fragments.length && (c = p.startSN = parseInt(l)); - break; - case "TARGETDURATION": - p.targetduration = parseFloat(l); - break; - case "VERSION": - p.version = parseInt(l); - break; - case "EXTM3U": - break; - case "ENDLIST": - p.liveOrEvent = !1; - break; - case "DIS": - b++, - E.tagList.push(["DIS"]), - C = !0; - break; - case "DISCONTINUITY-SEQ": - b = parseInt(l); - break; - case "KEY": - const e = l; - if (S = !0, - !v) { - try { - y = bm.parseDecryptData(e, t, r) - } catch (e) { - O = e - } - y && (v = !0) - } - break; - case "START": - const d = l - , u = ym.parseTags(d)["TIME-OFFSET"]; - ne(u) && (p.startTimeOffset = u); - break; - case "I-FRAMES": - p.iframesOnly = !0; - break; - case "MAP": - const h = ym.parseTags(l); - if (E.relurl = h.URI, - E.rawByteRange = h.BYTERANGE, - E.baseurl = t, - E.isInitSegment = !0, - E.levelkey = y, - S && !v) { - O = M(); - break - } - v = !1, - S = !1, - k = E.getMediaFragment(s, a, o), - D = !0, - E = new um(i); - break; - case "DEFINE": - const f = vm.VARIABLE_PLAYLIST_REGEX.exec(l) - , m = "NAME" === f[1] ? f[2] : f[4] - , g = "VALUE" === f[1] ? f[2] : f[4] - , N = f[5] - , T = f[6]; - if (m || g || "IMPORT" !== N || !n.hasOwnProperty(T)) { - if (!m || N || f[1] === f[3] || w.hasOwnProperty(m)) { - O = new R(L,_,!0,$.PlaylistErrorMissingImportReference.text,$.PlaylistErrorMissingImportReference); - break - } - w[m] = g - } else - w[T] = n[T] - } - } - } - return E = T, - E && !E.relurl && (p.fragments.pop(), - h -= E.duration), - !p.liveOrEvent && 0 < p.fragments.length && (p.fragments[p.fragments.length - 1].isLastFragment = !0), - p.totalduration = h, - p.averagetargetduration = h / p.fragments.length, - p.endSN = c - 1, - { - mediaOptionDetails: p, - playlistParsingError: O - } - } - static parseRootPlaylist(t, e, i, r) { - const n = [] - , s = {}; - let a, o, d, l, u = null, c = !0; - for (vm.MasterPlaylist.lastIndex = 0; null != (a = vm.MasterPlaylist.exec(e)); ) - if (a[4]) { - a = vm.VARIABLE_PLAYLIST_REGEX.exec(a[4]); - const t = "NAME" === a[1] ? a[2] : a[4] - , e = "VALUE" === a[1] ? a[2] : a[4] - , i = a[5]; - if (!t || s.hasOwnProperty(t) || i || a[1] === a[3]) { - l = new R(L,_,!0,$.PlaylistErrorInvalidEXTXDEFINE.text,$.PlaylistErrorInvalidEXTXDEFINE); - break - } - s[t] = e - } else if (a[5]) { - const t = bm.replaceVariables(a[5], s); - if (t.error) { - l = new R(L,_,!0,$.PlaylistErrorInvalidEXTXDEFINE.text,$.PlaylistErrorInvalidEXTXDEFINE); - break - } - const e = ym.parseTags(t.updatedString); - if ("string" != typeof e["SERVER-URI"]) { - l = new R(L,_,!0,$.PlaylistErrorInvalidSERVERURI.text,$.PlaylistErrorInvalidSERVERURI); - break - } - if (null != e["PATHWAY-ID"] && "string" != typeof e["PATHWAY-ID"]) { - l = new R(L,_,!0,$.PlaylistErrorInvalidPATHWAYID.text,$.PlaylistErrorInvalidPATHWAYID); - break - } - u = { - serverURI: Sm(e["SERVER-URI"], i, !1), - initPathwayID: e["PATHWAY-ID"] || "." - } - } else { - d = bm.replaceVariables(a[1] || a[3], s); - const e = ym.parseTags(d.updatedString); - if (o = bm.replaceVariables(a[2] || e.URI, s), - d.error || o.error) { - l = new R(L,_,!0,$.PlaylistErrorInvalidEXTXDEFINE.text,$.PlaylistErrorInvalidEXTXDEFINE); - break - } - if (void 0 !== e.SCORE && !ne(e.SCORE) || e.SCORE < 0) { - l = new R(L,_,!0,$.PlaylistErrorInvalidSCORE.text,$.PlaylistErrorInvalidSCORE), - c = !1; - break - } - c && void 0 === e.SCORE && (c = !1); - const u = e.BANDWIDTH - , p = e["AVERAGE-BANDWIDTH"] - , f = p || u - , m = null !== (h = e["VIDEO-RANGE"]) && void 0 !== h ? h : "SDR"; - if (null == (h = m) || !sm.includes(h)) - continue; - const g = { - itemId: t, - mediaOptionId: `level_${(f || 0) + n.length % 1e3 / 1e3}`, - mediaOptionType: ul.Variant, - attrs: e, - url: Sm(o.updatedString, i, r), - name: e.NAME, - audioGroupId: e.AUDIO, - subtitleGroupId: e.SUBTITLES, - iframes: !!a[3], - bandwidth: u, - avgBandwidth: p, - bitrate: f, - videoRange: m, - frameRate: e["FRAME-RATE"], - allowedCPCMap: bm.parseAllowedCPC(e["ALLOWED-CPC"]), - closedcaption: e["CLOSED-CAPTIONS"], - levelCodec: e.CODECS, - score: e.SCORE, - pathwayID: e["PATHWAY-ID"] || "." - } - , y = e["HDCP-LEVEL"]; - rm(y) && (g.hdcpLevel = y); - var h = e.RESOLUTION; - if (h && (g.width = h.width, - g.height = h.height), - e.CODECS) { - g.videoCodecList = new Array, - g.audioCodecList = new Array; - const t = e.CODECS.split(/[ ,]+/) - , i = t["length"]; - for (let e = 0; e < i; e++) { - const i = t[e]; - switch (i.slice(0, 4)) { - case "avc1": - g.videoCodec = Se.avc1toavcoti(i), - g.videoCodecList.push(g.videoCodec); - break; - case "avc3": - case "dvav": - case "dva1": - case "hev1": - case "hvc1": - case "dvh1": - case "dvhe": - case "vp09": - g.videoCodec = i, - g.videoCodecList.push(g.videoCodec); - break; - default: - g.audioCodec = i, - g.audioCodecList.push(g.audioCodec) - } - } - 1 < g.audioCodecList.length && (g.audioCodec = dm.getRichestAudioCodec(g.audioCodecList)), - 1 < g.videoCodecList.length && (g.videoCodec = dm.getRichestVideoCodec(g.videoCodecList)) - } - if (null != (l = "string" != typeof (h = g.pathwayID) ? lm("invalid steering manifest PATHWAY-PRIORITY list item data type") : /^[\w\-\.]+$/.test(h) ? void 0 : lm("steering manifest contains invalid pathway ID: " + h))) - break; - let cpc = g.allowedCPCMap ? JSON.stringify(g.allowedCPCMap) : "null"; - if (!cpc.includes("WIDEVINE_HARDWARE") && !g.url.includes('trickPlay') && !g.videoCodec.includes("hvc1")) - n.push(g) - } - - try{ - // console.log(n, window.screen.width) - let ok = (n.map( function(item){return{height : item.height, content: item}})); - let screenHeight = (app.cfg.visual.videoRes ?? window.screen.height) ; - ok.sort(function (a, b) { - return a.height - b.height; + configurable: true + }); + return globalThis + } catch (e) { + return defd(self) || defd(window) || defd(this) || {} + } + } + + let LoggerSingleton; + function addQELevel(options = {}) { + return Object.assign(Object.assign({}, options), { customLevels: Object.assign(Object.assign({}, (options.customLevels || {})), { qe: 35 }) }); + } + const setupLoggerSingleton = (sessionId, name, options = {}, stream) => { + if (!LoggerSingleton || LoggerSingleton.sessionId !== sessionId) { + LoggerSingleton = browser(addQELevel(options)).child({ sessionId, name: name }); + LoggerSingleton.qe = (msg) => LoggerSingleton.info(msg); + LoggerSingleton.sessionId = sessionId; + } + else { + LoggerSingleton.warn('Logger Singleton already setup, returning existing singleton'); + } + return LoggerSingleton; + }; + /** + * Get the configuration for the Pino logger + * + * @param {object} config - Configuration that overrides/extends the defaults set by this function + * @return {object} + */ + function getLoggerConfig(config = {}) { + const { consoleOverride } = config; + return Object.assign({ name: 'hls', timestamp: !config.sendLogs ? browser.stdTimeFunctions.isoTime : browser.stdTimeFunctions.epochTime, browser: { + asObject: true, + serialize: true, + transmit: { + send: (level, logEvent) => { + if (config.sendLogs && logEvent) { + config.sendLogs(level, logEvent); // Custom send function + } + }, + }, + write: { + debug: consoleWriteFn.bind(null, logFn(consoleOverride || console, 'debug'), 'debug'), + info: consoleWriteFn.bind(null, logFn(consoleOverride || console, 'info'), 'info'), + warn: consoleWriteFn.bind(null, logFn(consoleOverride || console, 'warn'), 'warn'), + error: consoleWriteFn.bind(null, logFn(consoleOverride || console, 'error'), 'error'), + fatal: consoleWriteFn.bind(null, logFn(consoleOverride || console, 'error'), 'fatal'), + }, + } }, config); + } + const noop$1 = () => { }; + function logFn(consoleObj, consoleLevel) { + consoleObj = consoleLevel in consoleObj ? consoleObj : console; + const logFn = consoleObj[consoleLevel] || consoleObj.log; + if (logFn) { + return logFn.bind(consoleObj); + } + return noop$1; + } + function consoleWriteFn(method, logLevel, o) { + const { time, sessionId, critical, name, msg } = o; + let logData = ''; + if ('data' in o) { + try { + const keys = []; + const refs = []; + logData = JSON.stringify(o.data, (key, value) => { + if (typeof value === 'object' && value !== null) { + const circularRefIndex = refs.indexOf(value); + if (circularRefIndex !== -1) { + return `[Circular object reference: '${keys[circularRefIndex]}']`; + } + keys.push(key); + refs.push(value); + } + return value; + }); + } + catch (e) { + logData = `Log serialization error: "${e}"`; + } + } + method(`${getCustomLocaleTimeString(time)}| [SessionID: ${sessionId}] | [${logLevel}] >${critical ? ' [QE Critical]' : ''} [${name}] ${msg ? msg : ''} ${logData}`); + } + /** + * Returns local date and time with millisecond precision and timezone identifier + */ + function getCustomLocaleTimeString(isoDateTime) { + const date = new Date(isoDateTime); + const off = date.getTimezoneOffset(); + const hrs = pad(Math.floor(Math.abs(off) / 60)); + const min = pad(Math.abs(off) % 60); + let tz = off <= 0 ? 'UTC+' + hrs : 'UTC-' + hrs; + tz = min ? tz + ':' + min : tz; + return (date.getFullYear() + '-' + + pad(date.getMonth() + 1) + '-' + + pad(date.getDate()) + ' ' + + pad(date.getHours()) + ':' + + pad(date.getMinutes()) + ':' + + pad(date.getSeconds()) + '.' + + (date.getMilliseconds() / 1000).toFixed(3).slice(2, 5) + ' ' + + tz); + } + /** Print Helpers **/ + function pad(number) { + if (number < 10) { + return '0' + number; + } + return number.toString(); + } + /** + * getLogger get the logger singleton defined in hls.ts + * + * Usage: + * getLogger().info({ name: "yourModuleName" }, 'msg to log'); + * if you do not provide { name: "yourModuleName" }, log line will have 'name: "hls"'. A default name + */ + const getLogger = () => { + if (!LoggerSingleton) { + LoggerSingleton = browser(addQELevel()).child({ name: 'hls' }); + LoggerSingleton.qe = (msg) => LoggerSingleton.info(msg); + LoggerSingleton.warn('getLogger called without hls object instantiated, returning a logger that is not configured'); + } + return LoggerSingleton; + }; + + const MuxerHelper = { + bin2str(buffer) { + return String.fromCharCode.apply(null, Array.from(buffer)); + }, + readUint16(buffer, offset) { + const val = (buffer[offset] << 8) | buffer[offset + 1]; + return val < 0 ? 65536 + val : val; + }, + readSint32(buffer, offset) { + const val = (buffer[offset] << 24) | (buffer[offset + 1] << 16) | (buffer[offset + 2] << 8) | buffer[offset + 3]; + return val; + }, + readUint32(buffer, offset) { + const val = MuxerHelper.readSint32(buffer, offset); + return val < 0 ? 4294967296 + val : val; + }, + writeUint32(buffer, offset, value) { + buffer[offset] = value >> 24; + buffer[offset + 1] = (value >> 16) & 255; + buffer[offset + 2] = (value >> 8) & 255; + buffer[offset + 3] = value & 255; + }, + readUint64(buffer, offset) { + let result = MuxerHelper.readUint32(buffer, offset); + result *= Math.pow(2, 32); + result += MuxerHelper.readUint32(buffer, offset + 4); + return result; + }, + writeUint64(buffer, offset, value) { + const UINT32_MAX = Math.pow(2, 32) - 1; + const upper = Math.floor(value / (UINT32_MAX + 1)); + const lower = Math.floor(value % (UINT32_MAX + 1)); + MuxerHelper.writeUint32(buffer, offset, upper); + MuxerHelper.writeUint32(buffer, offset + 4, lower); + }, + // Find the data for a box specified by its path + findBox(data, path) { + let results = []; + let ix; + let size; + let type; + let end; + let subresults; + if (!path.length) { + // short-circuit the search for empty paths + return []; + } + for (ix = 0; ix < data.byteLength;) { + size = MuxerHelper.readUint32(data, ix); + type = MuxerHelper.bin2str(data.subarray(ix + 4, ix + 8)); + end = size > 1 ? ix + size : data.byteLength; + if (type === path[0]) { + if (path.length === 1) { + // this is the end of the path and we've found the box we were + // looking for + results.push(data.subarray(ix + 8, end)); + } + else { + // recursively search for the next box along the path + subresults = MuxerHelper.findBox(data.subarray(ix + 8, end), path.slice(1)); + if (subresults.length) { + results = results.concat(subresults); + } + } + } + ix = end; + } + // we've finished searching all of data + return results; + }, + // Find the offset and data for a box specified by its path + findBoxWithOffset(data, offset, path, walkedPath) { + let results = []; + let ix; + let size; + let type; + let end; + let subresults; + if (!path.length) { + // short-circuit the search for empty paths + return []; + } + for (ix = 0; ix < data.byteLength;) { + size = MuxerHelper.readUint32(data, ix); + type = MuxerHelper.bin2str(data.subarray(ix + 4, ix + 8)); + end = size > 1 ? ix + size : data.byteLength; + if (type === path[0]) { + if (walkedPath) { + walkedPath.push({ offset: ix + offset, type: type, size: size }); + } + if (path.length === 1) { + // this is the end of the path and we've found the box we were + // looking for + results.push({ offset: ix + offset, type: type, data: data.subarray(ix + 8, end), boxSize: size, walkedPath: walkedPath ? walkedPath.slice(0) : undefined }); + } + else { + // recursively search for the next box along the path + subresults = MuxerHelper.findBoxWithOffset(data.subarray(ix + 8, end), ix + offset + 8, path.slice(1), walkedPath ? walkedPath.slice(0) : undefined); + if (subresults.length) { + results = results.concat(subresults); + walkedPath = walkedPath ? walkedPath.slice(0, -1) : undefined; + } + } + } + ix = end; + } + // we've finished searching all of data + return results; + }, + }; + + /** + * Hex dumper class + * + * + * + * + */ + const Hex = { + hexDump: function (array, limit = Infinity) { + if (!array) { + return ''; + } + const buffer = new Uint8Array(array); + let i, str = ''; + for (i = 0; i < buffer.length && i < limit; i++) { + let h = buffer[i].toString(16); + if (h.length < 2) { + h = '0' + h; + } + str += h; + } + return str; + }, + }; + var Hex$1 = Hex; + + const loggerName$d = { name: 'MP4EncryptionRemuxer' }; + class MP4EncryptionRemuxer extends RemuxerBase { + constructor(observer, config, typeSupported, vendor, logger) { + super(observer, config, logger); + } + static _isCommonEncryptionInternal(decryptMethod) { + return Boolean(decryptMethod && !(decryptMethod === 'NONE' || decryptMethod === 'AES-128')); + } + static remuxInitSegment(initSegment, logger, keyTagInfo, sinfArray) { + if (!keyTagInfo) { + return initSegment; + } + let remuxedInitSegment = initSegment; + if (MP4EncryptionRemuxer._isCommonEncryptionInternal(keyTagInfo.method)) { + const keyId = keyTagInfo.keyId; + let isCbc2 = false; + const newTraks = []; // list of trak boxes + const traks = MuxerHelper.findBoxWithOffset(initSegment, 0, ['moov', 'trak']); + logger.info(loggerName$d, 'trying to patch map'); + traks.forEach((trakTuple) => { + const trak = trakTuple.data; + let mediaType; + let encBoxChildrenOffset = 0; + const stsdTuple = MuxerHelper.findBoxWithOffset(trak, 0, ['mdia', 'minf', 'stbl', 'stsd'], [])[0]; + // skip the sample entry count + const sampleEntries = stsdTuple.data.subarray(8); + let isAudio = true; + let encBoxes = MuxerHelper.findBoxWithOffset(sampleEntries, stsdTuple.offset + 16, ['enca']); + if (encBoxes.length === 0) { + isAudio = false; + encBoxes = MuxerHelper.findBoxWithOffset(sampleEntries, stsdTuple.offset + 16, ['encv']); + } + encBoxes.forEach((encBoxTuple) => { + let encBoxChildren = null; + let newTrak = null; + if (isAudio) { + // encrypted AudioSampleEntry - skip 28 bytes + encBoxChildren = encBoxTuple.data.subarray(28); + mediaType = 'audio'; + encBoxChildrenOffset = stsdTuple.offset + 16 + 8 + 28; + } + else { + // encrypted VisualSampleEntry - skip 78 bytes + encBoxChildren = encBoxTuple.data.subarray(78); + mediaType = 'video'; + encBoxChildrenOffset = stsdTuple.offset + 16 + 8 + 78; + } + if (encBoxChildren) { + const sinfTuples = MuxerHelper.findBoxWithOffset(encBoxChildren, encBoxChildrenOffset, ['sinf']); + sinfTuples.forEach((sinfTuple) => { + const sinf = sinfTuple.data; + const frma = MuxerHelper.findBox(sinf, ['frma'])[0]; + const schm = MuxerHelper.findBox(sinf, ['schm'])[0]; + if (!frma) { + logger.error(loggerName$d, 'missing frma box'); + return; + } + else if (!schm) { + logger.error(loggerName$d, 'missing schm box'); + return; + } + const scheme = MuxerHelper.bin2str(schm.subarray(4, 8)); + const format = MuxerHelper.bin2str(frma.subarray(0, 4)); + if (format === 'aac ') { + if (!MP4$1.types) { + MP4$1.init(); + } + logger.info(loggerName$d, 'found frma with type \'aac \', patching to \'mp4a\''); + frma.set(MP4$1.types.mp4a, 0); + } + if (scheme === 'cbcs' || scheme === 'cenc') { + if (sinfArray) { + sinfArray.push(sinf); // used for unit tests until we get a more generic parser + } + const tenc = MuxerHelper.findBox(sinf, ['schi', 'tenc'])[0]; + if (tenc) { + const kKeyIdOffset = 8; // keyID offset is always 8 within the tenc box + // Look for default key id: + const tencKeyId = tenc.subarray(kKeyIdOffset, kKeyIdOffset + 16); + logger.info(loggerName$d, `found 'tenc' patching map with keyId default:${Hex$1.hexDump(tencKeyId)}->${Hex$1.hexDump(keyId)}`); + tenc.set(keyId, kKeyIdOffset); + // we may not need to do this, but at some point we were authoring content with zeros for the IV + // chrome does use this value, so set it to be safe + const defaultIsProtected = tenc[6]; + const defaultPerSampleIVSize = tenc[7]; + if (defaultIsProtected === 1 && defaultPerSampleIVSize === 0) { + const defaultConstantIVSize = tenc[24]; + if (defaultConstantIVSize > 0 && keyTagInfo.iv && defaultConstantIVSize === keyTagInfo.iv.length) { + logger.info(loggerName$d, 'patching iv for good measure'); + tenc.set(keyTagInfo.iv, 25); + } + } + } + } + else if (scheme === 'cbc2') { + logger.info(loggerName$d, 'found \'cbc2\' scheme, converting to \'cbcs\''); + isCbc2 = true; + if (!MP4$1.types) { + MP4$1.init(); + } + // create a sinf from the existing format and new scheme and scheme info boxes + const frmaTuple = MuxerHelper.findBoxWithOffset(sinf, 0, ['frma'])[0]; + const newSchi = MP4$1.box(MP4$1.types.schi, MP4$1.tenc(keyTagInfo, mediaType)); + const newSinf = MP4$1.box(MP4$1.types.sinf, sinf.subarray(frmaTuple.offset, frmaTuple.boxSize), MP4$1.schm(), newSchi); + // create a new track from the existing trak with the new sinf spliced in + newTrak = MP4$1.box(MP4$1.types.trak, trak.subarray(0, sinfTuple.offset), newSinf, trak.subarray(sinfTuple.offset + sinfTuple.boxSize)); + const newTrackData = newTrak.subarray(8); + // need to update all the sizes down the box path in the new track + // we can re-use the offsets from the already parsed path since they're before the splice point + const sizeIncrease = newSinf.byteLength - sinfTuple.boxSize; + if (stsdTuple.walkedPath) { + stsdTuple.walkedPath.push({ type: 'stsd', offset: encBoxTuple.offset, size: encBoxTuple.boxSize }); // enc* offset is special + stsdTuple.walkedPath.forEach((step) => { + MuxerHelper.writeUint32(newTrackData, step.offset, step.size + sizeIncrease); + }); + } + } + }); + } + if (!newTrak) { + newTrak = initSegment.subarray(trakTuple.offset, trakTuple.offset + trakTuple.boxSize); + } + newTraks.push(newTrak); + }); + const edtsTuple = MuxerHelper.findBoxWithOffset(trak, 0, ['edts'])[0]; + if (edtsTuple) { + if (!MP4$1.types) { + MP4$1.init(); + } + logger.info(loggerName$d, 'overwriting edts box'); + trak.set(MP4$1.types.free, edtsTuple.offset + 4); + } + }); + if (isCbc2) { + const cbcsInitSegment = MP4EncryptionRemuxer.remuxCbc2InitSegment(initSegment, newTraks, logger); + remuxedInitSegment = cbcsInitSegment ? cbcsInitSegment : initSegment; + } + } + return remuxedInitSegment; + } + /** + * @param traksToAppend Array of trak boxes to replace traks in initSegment with. + */ + static remuxCbc2InitSegment(initSegment, traksToAppend, logger) { + const ftypTuple = MuxerHelper.findBoxWithOffset(initSegment, 0, ['ftyp'])[0]; + if (!ftypTuple) { + logger.error(loggerName$d, 'no ftyp found'); + return; + } + const moovTuple = MuxerHelper.findBoxWithOffset(initSegment, ftypTuple.boxSize, ['moov'])[0]; + let moovChildren = []; + let ix = 0; + while (ix < moovTuple.data.byteLength) { + const size = MuxerHelper.readUint32(moovTuple.data, ix); + const type = MuxerHelper.bin2str(moovTuple.data.subarray(ix + 4, ix + 8)); + const end = size > 1 ? ix + size : moovTuple.data.byteLength; + switch (type) { + case 'trak': { + if (traksToAppend) { + // Just append these here where the traks used to be + moovChildren = moovChildren.concat(traksToAppend); + traksToAppend = undefined; + } + break; + } + default: + moovChildren.push(moovTuple.data.subarray(ix, end)); + break; + } + ix = end; + } + const newMoov = MP4$1.box(MP4$1.types.moov, ...moovChildren); + const newInitSegment = new Uint8Array(ftypTuple.boxSize + newMoov.byteLength); + newInitSegment.set(initSegment.subarray(0, ftypTuple.boxSize)); + newInitSegment.set(newMoov, ftypTuple.boxSize); + return newInitSegment; + } + static remuxOverflowSegment(data, logger) { + if (!MP4$1.types) { + MP4$1.init(); + } + const tfdts = MuxerHelper.findBoxWithOffset(data, 0, ['moof', 'traf', 'tfdt'], []); + let newDataSize = data.byteLength; + let newData; + // total all tfdts in segment so we know the size increase (can have multiple moofs in a segment) + tfdts.forEach((tfdt) => { + // increase the data size by 4 bytes for each 32 bit tfdt + if (tfdt.data[0] === 0) { + newDataSize += 4; + } + }); + if (newDataSize > data.byteLength) { + newData = new Uint8Array(newDataSize); + let newOffset = 0; + let dataBoxIndex = 0; + while (dataBoxIndex < data.byteLength) { + const size = MuxerHelper.readUint32(data, dataBoxIndex); + const type = MuxerHelper.bin2str(data.subarray(dataBoxIndex + 4, dataBoxIndex + 8)); + const dataBoxEnd = size > 1 ? dataBoxIndex + size : data.byteLength; + if (type === 'moof') { + const newMoof = MP4EncryptionRemuxer.remuxOverflowMoof(data.subarray(dataBoxIndex + 8, dataBoxEnd)); + newData.set(newMoof, newOffset); + newOffset += newMoof.byteLength; + } + else { + newData.set(data.subarray(dataBoxIndex, dataBoxEnd), newOffset); + newOffset += size; + } + dataBoxIndex = dataBoxEnd; + } + } + else { + logger.warn(loggerName$d, 'no increase in size'); + } + return newData ? newData : data; + } + static remuxOverflowMoof(moofData) { + let moofIndex = 0; + const moofChildren = []; + while (moofIndex < moofData.byteLength) { + const size = MuxerHelper.readUint32(moofData, moofIndex); + const type = MuxerHelper.bin2str(moofData.subarray(moofIndex + 4, moofIndex + 8)); + if (type === 'traf') { + const newTraf = MP4EncryptionRemuxer.remuxOverflowTraf(moofData.subarray(moofIndex + 8, moofIndex + size)); + moofChildren.push(newTraf); + } + else { + moofChildren.push(moofData.subarray(moofIndex, moofIndex + size)); + } + moofIndex = size > 1 ? moofIndex + size : moofData.byteLength; + } + const newMoof = MP4$1.box(MP4$1.types.moof, ...moofChildren); + const sizeDiff = newMoof.byteLength - moofData.byteLength - 8; // moofData doesn't include header, so subtract 8 + const truns = MuxerHelper.findBoxWithOffset(newMoof, 0, ['moof', 'traf', 'trun'], []); + truns.forEach((trun) => { + const dataOffsetPresent = (trun.data[3] & 1) !== 0; + if (dataOffsetPresent) { + const dataOffset = MuxerHelper.readUint32(trun.data, 8); + MuxerHelper.writeUint32(trun.data, 8, dataOffset + sizeDiff); + } + }); + const saios = MuxerHelper.findBoxWithOffset(newMoof, 0, ['moof', 'traf', 'saio'], []); + saios.forEach((saio) => { + const version = saio.data[0] & 1; + let dataOffset = 4; + if (saio.data[3] & 1) { + // aux info type and parameter + dataOffset += 8; + } + const ec = MuxerHelper.readUint32(saio.data, dataOffset); + dataOffset += 4; + if (!version) { + for (let i = 0; i < ec; i++) { + const value = MuxerHelper.readUint32(saio.data, dataOffset); + MuxerHelper.writeUint32(saio.data, dataOffset, value + sizeDiff); + dataOffset += 4; + } + } + else { + for (let i = 0; i < ec; i++) { + const value = MuxerHelper.readUint64(saio.data, dataOffset); + MuxerHelper.writeUint64(saio.data, dataOffset, value + sizeDiff); + dataOffset += 8; + } + } + }); + return newMoof; + } + static remuxOverflowTraf(trafData) { + let trafIndex = 0; + const trafChildren = []; + while (trafIndex < trafData.byteLength) { + const size = MuxerHelper.readUint32(trafData, trafIndex); + const type = MuxerHelper.bin2str(trafData.subarray(trafIndex + 4, trafIndex + 8)); + if (type === 'tfdt' && trafData[trafIndex + 8] === 0) { + const tfdtValue = MuxerHelper.readUint32(trafData, trafIndex + 12); + const newTfdt = MP4$1.box(MP4$1.types.tfdt, new Uint8Array([ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + tfdtValue >> 24, + (tfdtValue >> 16) & 255, + (tfdtValue >> 8) & 255, + tfdtValue & 255, + ])); + trafChildren.push(newTfdt); + } + else { + trafChildren.push(trafData.subarray(trafIndex, trafIndex + size)); + } + trafIndex = size > 1 ? trafIndex + size : trafData.byteLength; + } + const newTraf = MP4$1.box(MP4$1.types.traf, ...trafChildren); + return newTraf; + } + remuxText(track, parsingData) { + track.captionSamples.sort(function (a, b) { + return a.pts - b.pts; + }); + const length = track.captionSamples.length; + if (length) { + if (!parsingData.captionData) { + parsingData.captionData = {}; + } + parsingData.captionData.mp4 = track.captionSamples; + } + track.captionSamples = []; + } + remuxIFrame(startDTS, videoTrack, audioTrack, iframeDuration, track) { + if (!videoTrack.samples || !videoTrack.samples.length || !videoTrack.samples[0].data) { + return null; + } + let streamType; + const moof = MP4$1.moof(startDTS * videoTrack.timescale, videoTrack); + const iframeSegment = new Uint8Array(moof.byteLength + videoTrack.samples[0].data.byteLength + 8); + iframeSegment.set(moof); + MuxerHelper.writeUint32(iframeSegment, moof.byteLength, videoTrack.samples[0].data.byteLength + 8); + iframeSegment.set(MP4$1.types.mdat, moof.byteLength + 4); + iframeSegment.set(videoTrack.samples[0].data, moof.byteLength + 8); + videoTrack.sequenceNumber++; + const videoTimescale = videoTrack.timescale; + const videoEndTs = convertSecondsToTimestamp(startDTS + iframeDuration, videoTimescale); + const videoStartTs = convertSecondsToTimestamp(startDTS, videoTimescale); + let endTs; + let audioSegment; + if (audioTrack) { + streamType = 'audiovideo'; + audioTrack.sequenceNumber = videoTrack.sequenceNumber; + videoTrack.sequenceNumber++; + audioSegment = SilentAudio.getSegment(audioTrack, audioTrack.sequenceNumber, startDTS * audioTrack.info.timescale, iframeDuration); + endTs = determineMaxTimestamp(audioSegment.endTs, videoEndTs); + } + else { + streamType = 'video'; + endTs = videoEndTs; + } + const data = { + data1: iframeSegment, + data2: audioSegment === null || audioSegment === void 0 ? void 0 : audioSegment.silentFragData, + startPTS: videoStartTs, + startDTS: videoStartTs, + endPTS: endTs, + endDTS: endTs, + type: streamType, + dropped: 0, + track, + }; + // send the data + this.observer.trigger(DemuxerEvent.FRAG_PARSING_DATA, data); + // notify end of parsing + this.observer.trigger(DemuxerEvent.FRAG_PARSED); + } + remuxEmsgAndRawData(audioDuration, hasAudio, videoDuration, hasVideo, textTrack, id3Track, timeOffset, timescale, rawFragment, track) { + let streamType; + if (hasAudio && hasVideo) { + streamType = 'audiovideo'; + } + else if (hasAudio) { + streamType = 'audio'; + } + else if (hasVideo) { + streamType = 'video'; + } + const fragDuration = Math.max(videoDuration, audioDuration); + const data = { + data1: rawFragment, + track, + startPTS: convertSecondsToTimestamp(timeOffset, timescale), + startDTS: convertSecondsToTimestamp(timeOffset, timescale), + endPTS: undefined, + endDTS: undefined, + type: streamType, + dropped: 0, + }; + if (fragDuration) { + data.endPTS = convertSecondsToTimestamp(timeOffset + fragDuration, timescale); + data.endDTS = convertSecondsToTimestamp(timeOffset + fragDuration, timescale); + } + if (textTrack && textTrack.captionSamples.length) { + this.remuxText(textTrack, data); + } + if (id3Track && id3Track.id3Samples.length > 0) { + this.remuxID3(id3Track, data); + } + this.observer.trigger(DemuxerEvent.FRAG_PARSING_DATA, data); + this.observer.trigger(DemuxerEvent.FRAG_PARSED); + return data; + } + remuxID3(track, parsingData) { + let sample; + const length = track.id3Samples.length; + const PTSOffset = 10; + const DTSOffset = 10; + if (length) { + for (let index = 0; index < length; index++) { + sample = track.id3Samples[index]; + // emsg pts is aligned with media content and have 10s offset to avoid negative time in audio samples + sample.pts = sample.pts - PTSOffset; + sample.dts = sample.dts - DTSOffset; + } + parsingData.id3Samples = [...track.id3Samples]; + } + track.id3Samples = []; + } + } + + + const UINT32_MAX = Math.pow(2, 32) - 1; + const MAX_UPPER_32_VALUE = Math.pow(2, 20) - 1; // 52 bit integer float precision + const LARGE_TIMESCALE = 1000000; + const loggerName$c = { name: 'MP4Demuxer' }; + class MP4Demuxer extends DemuxerBase { + constructor(observer, remuxer, config, typeSupported = undefined, logger) { + super(observer, remuxer, config, {}, logger); + this.mp4Remuxer = remuxer; + // may need a little headroom for priming audio samples, so shift everything by the max value we expect + // that should be 2112 audio samples at 22050 hz + this.audioPrimingDelay = config.audioPrimingDelay; + if (this.audioPrimingDelay > 0) { + this.logger.info(loggerName$c, `using audioPrimingDelay of ${this.audioPrimingDelay}`); + } + } + resetTimeStamp(initPTS90k) { + if (isFiniteNumber(initPTS90k)) { + if (this.initData.audio && !this.initData.video) { + // if this is an audio only track go ahead and convert initPTS to the sample rate to avoid cumulative rounding errors + this.initPtsTs = { baseTime: Math.round((initPTS90k * this.initData.audio.timescale) / 90000), timescale: this.initData.audio.timescale }; + } + else { + this.initPtsTs = { baseTime: initPTS90k, timescale: 90000 }; + } + } + else { + this.initPtsTs = undefined; + } + } + static isHEVCFlavor(codec) { + if (!codec) { + return false; + } + const delimit = codec.indexOf('.'); + const baseCodec = delimit < 0 ? codec : codec.substring(0, delimit); + return (baseCodec === 'hvc1' || + baseCodec === 'hev1' /* + baseCodec === 'phvc' || + baseCodec === 'ehvc' || + baseCodec === 'zhvc' ||*/ + || + baseCodec === 'chvc' || + baseCodec === 'qhvc' || + baseCodec === 'qhev' || + baseCodec === 'muxa' || + // Dolby Vision + baseCodec === 'dvh1' || + baseCodec === 'dvhe' /* + baseCodec === 'ddh1' || + baseCodec === 'zdh1' ||*/ + || + baseCodec === 'cdh1' || + baseCodec === 'qdh1' || + baseCodec === 'qdhe'); + } + resetInitSegment(initSegment, duration, keyTagInfo) { + // jshint unused:false + this._silentAudioTrack = undefined; + if (initSegment && initSegment.byteLength) { + const remuxedInitSegment = MP4EncryptionRemuxer.remuxInitSegment(initSegment, this.logger, keyTagInfo); + const initData = (this.initData = MP4Demuxer.parseInitSegment(remuxedInitSegment)); + let track; + if (initData.foundLargeTimescale) { + this.logger.warn(loggerName$c, 'large timescale found, will check for 32 bit tfdts'); + } + const parsedAudioCodec = initData.audioCodec; + const parsedVideoCodec = initData.videoCodec; + if (initData.audio && initData.video) { + track = { type: 'audiovideo', container: 'video/mp4', codec: parsedAudioCodec + ',' + parsedVideoCodec, initSegment: remuxedInitSegment }; + } + else { + if (initData.audio && parsedAudioCodec) { + track = { type: 'audio', container: 'audio/mp4', codec: parsedAudioCodec, initSegment: remuxedInitSegment }; + } + if (initData.video && parsedVideoCodec) { + track = { type: 'video', container: 'video/mp4', codec: parsedVideoCodec, initSegment: remuxedInitSegment }; + } + } + if (initData.video) { + // needed to generate moofs for iframe mode frames + // we need the track data to create a new moof for muxed iframe mode + const parsedVideoTrack = initData.video; + const trakData = initSegment.subarray(parsedVideoTrack.trakOffset, parsedVideoTrack.trakOffset + parsedVideoTrack.trakSize); + this._videoTrack = Object.assign(Object.assign({}, parsedVideoTrack), { info: { id: parsedVideoTrack.id, timescale: parsedVideoTrack.timescale, duration }, trakData: trakData, sequenceNumber: 0, samples: [] }); + this.trySEICaptions = !MediaUtil.isVP09(parsedVideoCodec); + this._captionTrack = Object.assign(Object.assign({}, initData.caption), { sequenceNumber: 0, captionSamples: [] }); + this.logger.info(loggerName$c, 'assume SEI closed caption exists'); + } + if (initData.audio && parsedAudioCodec) { + // only need id and codec for silent audio generation + this._audioTrack = Object.assign({}, initData.audio); + } + if (initData.caption) { + // use clcp track if present + this.trySEICaptions = false; + this.logger.info(loggerName$c, `use clcp track id ${initData.caption.id}`); + this._captionTrack = Object.assign(Object.assign({}, initData.caption), { sequenceNumber: 0, captionSamples: [] }); + } + this.remuxedInitDataTrack = track; + const eventData = { track }; + this.observer.trigger(DemuxerEvent.FRAG_PARSING_INIT_SEGMENT, eventData); + } + } + static probe(data, logger) { + // ensure we find a moof box in the first 128kB + return MuxerHelper.findBox(data.subarray(0, Math.min(data.length, 512000)), ['moof']).length > 0; + } + static parseHvcC(data) { + let codecConfig; + if (data) { + const version = data[0]; + if (version === 1) { + const tmpByte = data[1]; + codecConfig = { + profileSpace: tmpByte >> 6, + tierFlag: (tmpByte & 32) >> 5 ? 'H' : 'L', + profileIDC: tmpByte & 31, + profileCompat: MuxerHelper.readUint32(data, 2), + constraintIndicator: data.subarray(6, 12), + levelIDC: data[12], + }; + } + else { + getLogger().warn(loggerName$c, `Unhandled version ${version} in hvcC box`); + } + } + else { + getLogger().warn(loggerName$c, 'No hvcC box'); + } + return codecConfig; + } + static hvcCToCodecString(baseCodecType, codecConfig) { + const profileSpaceStr = codecConfig.profileSpace ? String.fromCharCode(codecConfig.profileSpace + 'A' - 1) : ''; + const codecString = baseCodecType + '.' + profileSpaceStr + codecConfig.profileIDC + '.' + codecConfig.profileCompat.toString(16).toUpperCase() + '.' + codecConfig.tierFlag + codecConfig.levelIDC; + // append constraint indicators, ignoring trailing zero bytes + let constraintIndicatorStr = ''; + for (let i = codecConfig.constraintIndicator.length - 1; i >= 0; --i) { + const byte = codecConfig.constraintIndicator[i]; + if (!(byte === 0 && constraintIndicatorStr === '')) { + const encodedByte = byte.toString(16).toUpperCase(); + constraintIndicatorStr = '.' + (constraintIndicatorStr === '' ? encodedByte : encodedByte + constraintIndicatorStr); + } + } + return codecString + constraintIndicatorStr; + } + static parseDvcC(data) { + let codecConfig; + if (data) { + codecConfig = { + versionMajor: data[0], + versionMinor: data[1], + profile: (data[2] >> 1) & 127, + level: ((data[2] << 5) & 32) | ((data[3] >> 3) & 31), + }; + } + else { + getLogger().warn(loggerName$c, 'No dvcC box'); + } + return codecConfig; + } + static dvcCToCodecString(baseCodecType, codecConfig) { + const profileStr = MP4Demuxer.checkAndAddLeadingZero(codecConfig.profile); + const levelStr = MP4Demuxer.checkAndAddLeadingZero(codecConfig.level); + return baseCodecType + '.' + profileStr + '.' + levelStr; + } + static parseVpcC(data) { + let codecConfig; + if (data) { + codecConfig = { + profile: data[4], + level: data[5], + bitDepth: (data[6] >> 4) & 15, + }; + } + else { + getLogger().warn(loggerName$c, 'No vpcC box'); + } + return codecConfig; + } + static vpcCToCodecString(baseCodecType, codecConfig) { + const profileStr = MP4Demuxer.checkAndAddLeadingZero(codecConfig.profile); + const levelStr = MP4Demuxer.checkAndAddLeadingZero(codecConfig.level); + const subsampling = MP4Demuxer.checkAndAddLeadingZero(codecConfig.bitDepth); + return baseCodecType + '.' + profileStr + '.' + levelStr + '.' + subsampling; + } + static checkAndAddLeadingZero(num) { + return (num < 10 ? '0' : '') + num; + } + /** + * Parses an MP4 initialization segment and extracts stream type and + * timescale values for any declared tracks. Timescale values indicate the + * number of clock ticks per second to assume for time-based values + * elsewhere in the MP4. + * + * To determine the start time of an MP4, you need two pieces of + * information: the timescale unit and the earliest base media decode + * time. Multiple timescales can be specified within an MP4 but the + * base media decode time is always expressed in the timescale from + * the media header box for the track: + * ``` + * moov > trak > mdia > mdhd.timescale + * moov > trak > mdia > hdlr + * ``` + * @param init {Uint8Array} the bytes of the init segment + * @return {object} a hash of track type to timescale values or null if + * the init segment is malformed. + */ + static parseInitSegment(initSegment) { + const result = { foundLargeTimescale: false, tracksById: {} }; + const traksTuple = MuxerHelper.findBoxWithOffset(initSegment, 0, ['moov', 'trak']); + traksTuple.forEach((trakTuple) => { + const trak = trakTuple.data; + const tkhd = MuxerHelper.findBox(trak, ['tkhd'])[0]; + if (tkhd) { + let version = tkhd[0]; + const index = version === 0 ? 12 : 20; + const id = MuxerHelper.readUint32(tkhd, index); + const mdhd = MuxerHelper.findBox(trak, ['mdia', 'mdhd'])[0]; + if (mdhd) { + version = mdhd[0]; + let timescaleIndex = version === 0 ? 12 : 20; + const timescale = MuxerHelper.readUint32(mdhd, timescaleIndex); + timescaleIndex += 4; + if (timescale >= LARGE_TIMESCALE) { + result.foundLargeTimescale = true; + } + const duration = version === 0 ? MuxerHelper.readUint32(mdhd, timescaleIndex) : 0; // TODO: read 64 bit? Maybe we don't care, but TS sets this value and we're trying to share track data + const hdlr = MuxerHelper.findBox(trak, ['mdia', 'hdlr'])[0]; + if (hdlr) { + const hdlrType = MuxerHelper.bin2str(hdlr.subarray(8, 12)); + const hdlrToTypeMap = { soun: 'audio', vide: 'video', clcp: 'caption' }; + const type = hdlrToTypeMap[hdlrType] || hdlrType; + if (type) { + // extract codec info. TODO : parse codec details to be able to build MIME type + const codecBoxes = MuxerHelper.findBox(trak, ['mdia', 'minf', 'stbl', 'stsd']); + let codecType; + if (codecBoxes.length) { + const codecBox = codecBoxes[0]; + codecType = MuxerHelper.bin2str(codecBox.subarray(12, 16)); + getLogger().info(loggerName$c, `MP4Demuxer:${type}:${codecType} found`); + const stsdData = MP4Demuxer.parseStsd(codecBox); + let newTrack; + if (type === 'caption') { + const captionTrack = Object.assign({ id, type, timescale, duration, isTimingTrack: false, sequenceNumber: 0, captionSamples: [] }, stsdData); + result.caption = captionTrack; + newTrack = captionTrack; + } + else { + const mediaTrack = Object.assign({ id, + type, + timescale, + duration, isTimingTrack: true, trakOffset: trakTuple.offset, trakSize: trakTuple.boxSize, sequenceNumber: 0, samples: [], fragmentDuration: 0 }, stsdData); + if (type === 'video') { + result.video = mediaTrack; + result.videoCodec = mediaTrack.codec; + } + else { + result.audio = mediaTrack; + result.audioCodec = mediaTrack.codec; + } + newTrack = mediaTrack; + } + result.tracksById[id] = newTrack; + } + } + } + } + } + }); + const trexTuple = MuxerHelper.findBoxWithOffset(initSegment, 0, ['moov', 'mvex', 'trex']); + trexTuple.forEach((trexTuple) => { + const trex = trexTuple.data; + const id = MuxerHelper.readUint32(trex, 4); + const defaultSampleSize = MuxerHelper.readUint32(trex, 16); + result.tracksById[id].defaultSampleSize = defaultSampleSize; + }); + return result; + } + static parseStsd(stsd) { + let defaultPerSampleIVSize; + let codec; + // skip the sample entry count + const sampleEntries = stsd.subarray(8); + let baseCodecType = MuxerHelper.bin2str(sampleEntries.subarray(4, 8)); + let encBox = null; + let encBoxChildren = null; + if (baseCodecType === 'enca') { + // audio + encBox = MuxerHelper.findBox(sampleEntries, ['enca'])[0]; + encBoxChildren = encBox.subarray(28); + } + else if (baseCodecType === 'encv') { + // video + encBox = MuxerHelper.findBox(sampleEntries, ['encv'])[0]; + // FIXME: May have optional clap and pasp atoms after 78 bytes + encBoxChildren = encBox.subarray(78); + } + const encrypted = !!encBoxChildren; + defaultPerSampleIVSize = 0; + if (encBoxChildren) { + const sinfs = MuxerHelper.findBox(encBoxChildren, ['sinf']); + sinfs.forEach((sinf) => { + const schm = MuxerHelper.findBox(sinf, ['schm'])[0]; + if (schm) { + const scheme = MuxerHelper.bin2str(schm.subarray(4, 8)); + if (scheme === 'cbcs' || scheme === 'cenc') { + const frma = MuxerHelper.findBox(sinf, ['frma'])[0]; + if (frma) { + // for encrypted content baseCodecType will be in frma + baseCodecType = MuxerHelper.bin2str(frma); + } + const tenc = MuxerHelper.findBox(sinf, ['schi', 'tenc'])[0]; + if (tenc) { + defaultPerSampleIVSize = tenc[7]; + } + } + } + }); + } + let codecConfig; + const sampleEntriesEnd = sampleEntries.subarray(86); + switch (baseCodecType) { + case 'mp4a': + codec = 'mp4a.40.5'; + break; + case 'ac-3': + case 'ec-3': + case 'alac': + case 'fLaC': + codec = baseCodecType; + break; + case 'avc1': + case 'avc3': + codec = baseCodecType + '.640028'; + break; + case 'hvc1': + case 'hev1': + const hvcCBox = MuxerHelper.findBox(sampleEntriesEnd, ['hvcC'])[0]; // There may be other atoms right after sampleEntries + codecConfig = MP4Demuxer.parseHvcC(hvcCBox); + codec = codecConfig ? MP4Demuxer.hvcCToCodecString(baseCodecType, codecConfig) : baseCodecType + '.2.4.H150.B0'; + break; + case 'dvh1': + case 'dvhe': + const dvcCBox = MuxerHelper.findBox(sampleEntriesEnd, ['dvcC'])[0]; + codecConfig = MP4Demuxer.parseDvcC(dvcCBox); + codec = codecConfig ? MP4Demuxer.dvcCToCodecString(baseCodecType, codecConfig) : baseCodecType + '.05.01'; + break; + case 'c608': + codec = baseCodecType; + break; + case 'vp09': + const vpcCBox = MuxerHelper.findBox(sampleEntriesEnd, ['vpcC'])[0]; + codecConfig = MP4Demuxer.parseVpcC(vpcCBox); + codec = MP4Demuxer.vpcCToCodecString(baseCodecType, codecConfig); + break; + default: + codec = baseCodecType; + break; + } + return { codec, encrypted, defaultPerSampleIVSize }; + } + static has32BitTfdts(fragment) { + const tfdts = MuxerHelper.findBox(fragment, ['moof', 'traf', 'tfdt']); + let found = false; + tfdts.forEach((tfdt) => { + if (tfdt[0] === 0) { + // version 0 means 32 bit tfdt + found = true; + } + }); + return found; + } + /** + * Determine the base media decode start time, in seconds, for an MP4 + * fragment. If multiple fragments are specified, the earliest time is + * returned. + * + * The base media decode time can be parsed from track fragment + * metadata: + * ``` + * moof > traf > tfdt.baseMediaDecodeTime + * ``` + * It requires the timescale value from the mdhd to interpret. + * + * @param timescale {object} a hash of track ids to timescale values. + * @return {number} the earliest base media decode start time for the + * fragment, in seconds + */ + static getStartDtsTs(initData, fragment) { + // we need info from two childrend of each track fragment box + const trafs = MuxerHelper.findBox(fragment, ['moof', 'traf']); + let minTime = Number.MAX_SAFE_INTEGER; + let result; + // determine the start times for each track + trafs.map(function (traf) { + return MuxerHelper.findBox(traf, ['tfhd']).forEach((tfhd) => { + // get the track id from the tfhd + const id = MuxerHelper.readUint32(tfhd, 4); + const parsedTrak = initData.tracksById[id]; + let timescale; + if (!parsedTrak) { + return; + } + if (parsedTrak.isTimingTrack) { + // assume a 90kHz clock if no timescale was specified + timescale = parsedTrak.timescale || 90000; + } + else { + return Infinity; // Should just not be considered for time calculation + } + // get the base media decode time from the tfdt + const tfdtTimes = MuxerHelper.findBox(traf, ['tfdt']).map(function (tfdt) { + let result; + const version = tfdt[0]; + result = MuxerHelper.readUint32(tfdt, 4); + if (version === 1) { + if (result > MAX_UPPER_32_VALUE) { + getLogger().warn(loggerName$c, `Value larger than can be represented by float for upper 32 bits ${result}`); + } + result *= Math.pow(2, 32); + result += MuxerHelper.readUint32(tfdt, 8); + } + return result; + }); + const baseTime = tfdtTimes.length > 0 ? tfdtTimes[0] : Infinity; + if (isFinite(baseTime) && baseTime / timescale < minTime) { + minTime = baseTime / timescale; + result = { baseTime, timescale }; + } + }); + }); + return result; + } + static offsetStartDTS(initData, fragment, timeOffsetTs, audioPrimingDelaySec) { + MuxerHelper.findBox(fragment, ['moof', 'traf']).map(function (traf) { + return MuxerHelper.findBox(traf, ['tfhd']).map(function (tfhd) { + // get the track id from the tfhd + const id = MuxerHelper.readUint32(tfhd, 4); + const parsedTrak = initData.tracksById[id]; + if (!parsedTrak) { + return; + } + // assume a 90kHz clock if no timescale was specified + const timescale = parsedTrak.timescale || 90000; + const audioPrimingOffset = parsedTrak.type === 'caption' ? 0 : audioPrimingDelaySec; + // get the base media decode time from the tfdt + MuxerHelper.findBox(traf, ['tfdt']).map(function (tfdt) { + const version = tfdt[0]; + const mediaType = parsedTrak.type; + if (version === 0) { + const baseMediaDecodeTime = MuxerHelper.readUint32(tfdt, 4); + let offsetBaseMediaDecodeTime = baseMediaDecodeTime - Math.round((timeOffsetTs.baseTime * timescale) / timeOffsetTs.timescale); + // need to make sure video doesn't go negative after timestampOffset is applied + if (mediaType === 'video' && offsetBaseMediaDecodeTime < 0) { + getLogger().warn(loggerName$c, `video tdft would have gone negative by ${offsetBaseMediaDecodeTime / timescale} seconds`); + offsetBaseMediaDecodeTime = 0; + } + offsetBaseMediaDecodeTime = offsetBaseMediaDecodeTime + Math.round(audioPrimingOffset * timescale); + offsetBaseMediaDecodeTime = Math.max(offsetBaseMediaDecodeTime, 0); + MuxerHelper.writeUint32(tfdt, 4, offsetBaseMediaDecodeTime); + } + else { + const baseMediaDecodeTime = MuxerHelper.readUint32(tfdt, 4); + if (baseMediaDecodeTime > MAX_UPPER_32_VALUE) { + getLogger().error(loggerName$c, `baseMediaDecodeTime larger than can be represented by float for upper 32 bits ${baseMediaDecodeTime}`); + } + let offsetBaseMediaDecodeTime = baseMediaDecodeTime; + offsetBaseMediaDecodeTime *= Math.pow(2, 32); + offsetBaseMediaDecodeTime += MuxerHelper.readUint32(tfdt, 8); + offsetBaseMediaDecodeTime = offsetBaseMediaDecodeTime - Math.round((timeOffsetTs.baseTime * timescale) / timeOffsetTs.timescale); + // need to make sure video doesn't go negative after timestampOffset is applied + if (mediaType === 'video' && offsetBaseMediaDecodeTime < 0) { + getLogger().warn(loggerName$c, `video tdft would have gone negative by ${offsetBaseMediaDecodeTime / timescale} seconds`); + offsetBaseMediaDecodeTime = 0; + } + offsetBaseMediaDecodeTime = offsetBaseMediaDecodeTime + Math.round(audioPrimingOffset * timescale); + offsetBaseMediaDecodeTime = Math.max(offsetBaseMediaDecodeTime, 0); + const upper = Math.floor(offsetBaseMediaDecodeTime / (UINT32_MAX + 1)); + const lower = Math.floor(offsetBaseMediaDecodeTime % (UINT32_MAX + 1)); + MuxerHelper.writeUint32(tfdt, 4, upper); + MuxerHelper.writeUint32(tfdt, 8, lower); + } + }); + }); + }); + } + static writeStartDTS(initData, fragmentData, startDTS) { + MuxerHelper.findBox(fragmentData, ['moof', 'traf']).map(function (traf) { + return MuxerHelper.findBox(traf, ['tfhd']).map(function (tfhd) { + // get the track id from the tfhd + const id = MuxerHelper.readUint32(tfhd, 4); + const parsedTrak = initData.tracksById[id]; + if (!parsedTrak) { + return; + } + // assume a 90kHz clock if no timescale was specified + const timescale = parsedTrak.timescale || 90000; + // everything is in decimal seconds, so we need round timestamps or they'll get truncated and lose accuracy + const roundedStartDTS = Math.round(startDTS * timescale) / timescale; + if (Math.abs(roundedStartDTS - startDTS) > 0.01) { + // the rounding errors should be very small since we snap durations to the timescale + getLogger().warn(loggerName$c, `[iframes] large rounding error when adjusting timestamps, startDTS: ${startDTS}, roundedStartDTS: ${roundedStartDTS}`); + } + // get the base media decode time from the tfdt + MuxerHelper.findBox(traf, ['tfdt']).map(function (tfdt) { + const version = tfdt[0]; + if (version === 0) { + MuxerHelper.writeUint32(tfdt, 4, roundedStartDTS * timescale); + } + else { + let baseMediaDecodeTime = roundedStartDTS * timescale; + baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0); + const upper = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)); + const lower = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1)); + MuxerHelper.writeUint32(tfdt, 4, upper); + MuxerHelper.writeUint32(tfdt, 8, lower); + } + }); + }); + }); + } + static parseSAIO(saio) { + let subsampleOffset = 0; + let offset = 0; + const version = saio[0]; + const flags = MuxerHelper.readUint32(saio, 0) & 16777215; + offset += 4; + if ((flags & 1) !== 0) { + offset += 8; + } + const entryCount = MuxerHelper.readUint32(saio, offset) & 16777215; + if (entryCount === 1) { + offset += 4; + subsampleOffset = MuxerHelper.readUint32(saio, offset); + if (version === 1) { + offset += 4; + subsampleOffset *= Math.pow(2, 32); + subsampleOffset += MuxerHelper.readUint32(saio, offset); + } + } + else { + getLogger().error(loggerName$c, `saio entry count error, count is: ${entryCount}`); + } + return subsampleOffset; + } + static parseSAIZ(saiz) { + let sampleSize = 0; + let offset = 0; + const flags = MuxerHelper.readUint32(saiz, 0) & 16777215; + offset += 4; + if ((flags & 1) !== 0) { + offset += 8; + } + sampleSize = saiz[offset]; + offset++; + // let sampleCount = MP4Demuxer.readUint32(saiz, offset); + offset += 4; // just get the first sample + if (sampleSize === 0) { + sampleSize = saiz[offset]; + } + return sampleSize; + } + static parseSubsample(perSampleIVSize, entry) { + const sampleAuxInfo = { subsamples: [] }; + let offset = 0; + if (perSampleIVSize) { + sampleAuxInfo.iv = entry.subarray(0, perSampleIVSize); + offset += perSampleIVSize; + } + offset += 2; // skip entry length + // need at least 6 bytes to read a subsample entry + while (offset + 6 <= entry.byteLength) { + const bytesClear = MuxerHelper.readUint16(entry, offset); + offset += 2; + const bytesEncrypted = MuxerHelper.readUint32(entry, offset); + offset += 4; + sampleAuxInfo.subsamples.push([bytesClear, bytesEncrypted]); + } + return sampleAuxInfo; + } + static isSEIMessage(isHEVCFlavor, naluType) { + return isHEVCFlavor ? naluType === 39 || naluType === 40 : naluType === 6; + } + static parseCLCPSample(fragment, startSampleOffset, sampleSize) { + let sampleIndex = 0; + const samples = []; + let totalSize = 0; + while (sampleIndex < sampleSize) { + let sampleOffset = startSampleOffset + sampleIndex; + const cdatSize = MuxerHelper.readUint32(fragment, sampleOffset); // get actual cdat size + sampleOffset += 4; + const cdatType = MuxerHelper.bin2str(fragment.subarray(sampleOffset, sampleOffset + 4)); + sampleOffset += 4; + if (cdatType === 'cdat') { + if (cdatSize !== sampleSize) { + getLogger().debug(loggerName$c, `clcp track: cdatSize ${cdatSize} @ offset ${sampleOffset}; sampleSize ${sampleSize}`); + } + const actualDataSize = cdatSize - 8; + const rawData = fragment.subarray(sampleOffset, sampleOffset + actualDataSize); + totalSize += actualDataSize; + samples.push(rawData); + sampleIndex += cdatSize; // actualDataSize + 8 + } + else { + getLogger().debug(loggerName$c, `clcp track: unknown atom type ${cdatType}`); + break; + } + } + return { cdatList: samples, cdatTotalSize: totalSize }; + } + // TODOs: + // * Parse cdt2 data + // * Handle 64-bit length in tfhd > baseDataOffset + static parseSamples(startDTS, fragment, track, iframeDuration, useSEICaptions, maxSamples) { + const timescale = track.timescale; + const trackId = track.id; + let pts = startDTS; + let parsedSampleCount = 0; + let sampleAuxInfo; + let isHEVCFlavor = false; + const moofs = MuxerHelper.findBoxWithOffset(fragment, 0, ['moof']); + moofs.map(function (moofTuple) { + const moof = moofTuple.data; + const moofOffset = moofTuple.offset; + const trafs = MuxerHelper.findBox(moof, ['traf']); + trafs.map(function (traf) { + // get the base media decode time from the tfdt + const baseTime = MuxerHelper.findBox(traf, ['tfdt']).map(function (tfdt) { + let result; + const version = tfdt[0]; + result = MuxerHelper.readUint32(tfdt, 4); + if (version === 1) { + result *= Math.pow(2, 32); + result += MuxerHelper.readUint32(tfdt, 8); + } + return result / timescale; + })[0]; + if (baseTime !== undefined) { + pts = baseTime; + } + return MuxerHelper.findBox(traf, ['tfhd']).map(function (tfhd) { + // tfhd default values + const id = MuxerHelper.readUint32(tfhd, 4); + const tfhdFlags = MuxerHelper.readUint32(tfhd, 0) & 16777215; + const baseDataOffsetPresent = (tfhdFlags & 1) !== 0; + const sampleDescriptionIndexPresent = (tfhdFlags & 2) !== 0; + const defaultSampleDurationPresent = (tfhdFlags & 8) !== 0; + let defaultSampleDuration = 0; + const defaultSampleSizePresent = (tfhdFlags & 16) !== 0; + let defaultSampleSize = 0; + const defaultSampleFlagsPresent = (tfhdFlags & 32) !== 0; + // let durationIsEmpty = (tfhdFlags & 0x010000) !== 0; + // let defaultBaseIsMoof = (tfhdFlags & 0x020000) !== 0; + let tfhdOffset = 8; + if (isFiniteNumber(track.defaultSampleSize)) { + defaultSampleSize = track.defaultSampleSize; + } + if (id === trackId) { + if (baseDataOffsetPresent) { + MuxerHelper.readUint32(tfhd, tfhdOffset); // Should be 64-bit + tfhdOffset += 4; + const mustBeZeroes = MuxerHelper.readUint32(tfhd, tfhdOffset); + tfhdOffset += 4; + if (mustBeZeroes !== 0) { + getLogger().info(loggerName$c, 'tfhd baseDataOffset has 64-bit value. Caption should be turned off'); + } + } + if (sampleDescriptionIndexPresent) { + MuxerHelper.readUint32(tfhd, tfhdOffset); + tfhdOffset += 4; + } + if (defaultSampleDurationPresent) { + defaultSampleDuration = MuxerHelper.readUint32(tfhd, tfhdOffset); + tfhdOffset += 4; + } + if (defaultSampleSizePresent) { + defaultSampleSize = MuxerHelper.readUint32(tfhd, tfhdOffset); + tfhdOffset += 4; + } + if (defaultSampleFlagsPresent) { + MuxerHelper.readUint32(tfhd, tfhdOffset); + tfhdOffset += 4; + } + if (track.type === 'video') { + let subsampleOffset = 0, subsampleSize = 0; + // only use the first one + MuxerHelper.findBox(traf, ['saio']).map(function (saio) { + subsampleOffset = MP4Demuxer.parseSAIO(saio); + }); + MuxerHelper.findBox(traf, ['saiz']).map(function (saiz) { + subsampleSize = MP4Demuxer.parseSAIZ(saiz); + }); + if (subsampleOffset && subsampleSize) { + sampleAuxInfo = MP4Demuxer.parseSubsample(track.defaultPerSampleIVSize, fragment.subarray(subsampleOffset, subsampleOffset + subsampleSize)); + } + isHEVCFlavor = MP4Demuxer.isHEVCFlavor(track.codec); + } + MuxerHelper.findBox(traf, ['trun']).map(function (trun) { + // trun specific values + const version = trun[0]; + const flags = MuxerHelper.readUint32(trun, 0) & 16777215; + const dataOffsetPresent = (flags & 1) !== 0; + let dataOffset = 0; + const firstSampleFlagsPresent = (flags & 4) !== 0; + const sampleDurationPresent = (flags & 256) !== 0; + let sampleDuration = 0; + const sampleSizePresent = (flags & 512) !== 0; + let sampleSize = 0; + const sampleFlagsPresent = (flags & 1024) !== 0; + const sampleCompositionOffsetsPresent = (flags & 2048) !== 0; + let compositionOffset = 0; + const sampleCount = MuxerHelper.readUint32(trun, 4); + let trunOffset = 8; // past version, flags, and sample count + if (dataOffsetPresent) { + dataOffset = MuxerHelper.readUint32(trun, trunOffset); + trunOffset += 4; + } + if (firstSampleFlagsPresent) { + trunOffset += 4; + } + let sampleOffset = dataOffset + moofOffset; + for (let ix = 0; ix < sampleCount && (maxSamples < 0 || parsedSampleCount < maxSamples); ix++) { + if (sampleDurationPresent) { + sampleDuration = MuxerHelper.readUint32(trun, trunOffset); + trunOffset += 4; + } + else { + sampleDuration = defaultSampleDuration; + } + if (sampleSizePresent) { + sampleSize = MuxerHelper.readUint32(trun, trunOffset); + trunOffset += 4; + } + else { + sampleSize = defaultSampleSize; + } + if (sampleFlagsPresent) { + trunOffset += 4; + } + if (sampleCompositionOffsetsPresent) { + if (version === 0) { + compositionOffset = MuxerHelper.readUint32(trun, trunOffset); + } + else { + compositionOffset = MuxerHelper.readSint32(trun, trunOffset); + } + trunOffset += 4; + } + // TODO: make this more generic + if (track.type === 'video') { + if (!isFiniteNumber(iframeDuration)) { + // non iframe + track.fragmentDuration += sampleDuration; + if (useSEICaptions) { + let naluTotalSize = 0; + // hijacking sei parsing to get video duration + while (naluTotalSize < sampleSize) { + const naluSize = MuxerHelper.readUint32(fragment, sampleOffset); + sampleOffset += 4; + const naluType = fragment[sampleOffset] & 31; + if (!track.seiSamples) { + track.seiSamples = []; + } + if (MP4Demuxer.isSEIMessage(isHEVCFlavor, naluType)) { + const sampleData = fragment.subarray(sampleOffset, sampleOffset + naluSize); + track.seiSamples.push({ pts: pts + compositionOffset / timescale, type: naluType, data: sampleData, sampleOffset: sampleOffset, naluSize: naluSize }); + } + sampleOffset += naluSize; + naluTotalSize += naluSize + 4; + } + } + } + else { + // iframe + track.samples.push({ + data: fragment.subarray(sampleOffset, sampleOffset + sampleSize), + size: sampleSize, + duration: iframeDuration * timescale, + cts: 0, + flags: { + isLeading: 0, + isDependedOn: 0, + hasRedundancy: 0, + degradPrio: 0, + dependsOn: 2, + isNonSync: 0, + paddingValue: 0, + }, + subsamples: sampleAuxInfo ? sampleAuxInfo.subsamples : [], + iv: sampleAuxInfo ? sampleAuxInfo.iv : undefined, + }); + } + } + else if (track.type === 'audio') { + track.fragmentDuration += sampleDuration; + } + else if (track.type === 'caption') { + const { cdatList, cdatTotalSize } = MP4Demuxer.parseCLCPSample(fragment, sampleOffset, sampleSize); + sampleOffset += sampleSize; + if (cdatList.length) { + let cdatArray; + if (cdatList.length === 1) { + cdatArray = new Uint8Array(cdatList[0]); + } + else if (cdatList.length > 1) { + let offset = 0; + cdatArray = new Uint8Array(cdatTotalSize); + for (const arr of cdatList) { + cdatArray.set(arr, offset); + offset += arr.length; + } + } + track.captionSamples.push({ type: 3, pts: pts, bytes: cdatArray }); + } + } + parsedSampleCount++; + pts += sampleDuration / timescale; + } // for ix + }); // trun map + } // if (id == trackId) + }); // tfhd map + }); // traf map + }); // moof map + } + static parseEmsg(data) { + const version = data[0]; + let schemeIdUri = ''; + let value = ''; + let timeScale; + let presentationTimeDelta; + let presentationTime; + let eventDuration; + let id; + let offset = 0; + if (version === 0) { + while (MuxerHelper.bin2str(data.subarray(offset, offset + 1)) !== '\0') { + schemeIdUri += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + } + schemeIdUri += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + while (MuxerHelper.bin2str(data.subarray(offset, offset + 1)) !== '\0') { + value += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + } + value += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + timeScale = MuxerHelper.readUint32(data, 12); + presentationTimeDelta = MuxerHelper.readUint32(data, 16); + eventDuration = MuxerHelper.readUint32(data, 20); + id = MuxerHelper.readUint32(data, 24); + offset = 28; + } + else { + offset += 4; + timeScale = MuxerHelper.readUint32(data, offset); + offset += 4; + const leftPresentationTime = MuxerHelper.readUint32(data, offset); + offset += 4; + const rightPresentationTime = MuxerHelper.readUint32(data, offset); + offset += 4; + presentationTime = Math.pow(2, 32) * leftPresentationTime + rightPresentationTime; + if (!Number.isSafeInteger(presentationTime)) { + presentationTime = Number.MAX_SAFE_INTEGER; + getLogger().warn(loggerName$c, 'Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box'); + } + eventDuration = MuxerHelper.readUint32(data, offset); + offset += 4; + id = MuxerHelper.readUint32(data, offset); + offset += 4; + while (MuxerHelper.bin2str(data.subarray(offset, offset + 1)) !== '\0') { + schemeIdUri += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + } + schemeIdUri += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + while (MuxerHelper.bin2str(data.subarray(offset, offset + 1)) !== '\0') { + value += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + } + value += MuxerHelper.bin2str(data.subarray(offset, offset + 1)); + offset += 1; + } + const payload = data.subarray(offset, data.byteLength); + return { schemeIdUri, value, timeScale, presentationTime, presentationTimeDelta, eventDuration, id, payload }; + } + static extractID3PayloadCreateID3Track(emsgInfo, timeOffset, id3Track, logger) { + const id3 = new ID3$1(emsgInfo.payload, logger); + const data = new Uint8Array(emsgInfo.payload); + const length = data.byteLength; + let frameIndex = 0; + let offset = 0; + const pts = isFiniteNumber(emsgInfo.presentationTime) ? emsgInfo.presentationTime / emsgInfo.timeScale : timeOffset + emsgInfo.presentationTimeDelta / emsgInfo.timeScale; + if (!isFiniteNumber(pts)) { + getLogger().error(loggerName$c, 'No pts found in emsg info when extracting ID3 payload'); + return; + } + const frameDuration = emsgInfo.eventDuration; + const header = data.subarray(0, 10); + const fileIdentifier = MuxerHelper.bin2str(header.subarray(offset, offset + 3)); + offset += 3; + if (fileIdentifier !== 'ID3') { + getLogger().error(loggerName$c, 'No ID3 tag found when extracting ID3 payload'); + } + // skip versions + offset += 2; + const flags = data.subarray(offset, offset + 1); + const extendedHeader = flags[0] & 64; + const footerPresent = flags[0] & 16; + offset += 1; + ID3$1.readSynchSafeUint32(data.subarray(offset, offset + 4)); + offset += 4; + if (extendedHeader) { + const extHeaderSize = ID3$1.readSynchSafeUint32(data.subarray(offset, offset + 4)); + offset += 4; + offset += extHeaderSize; + } + while (offset + 2 < length) { + let frameId = ''; + frameId += MuxerHelper.bin2str(data.subarray(offset, offset + 4)); + offset += 4; + const frameLength = ID3$1.readSynchSafeUint32(data.subarray(offset, offset + 4)); + offset += 4; + const stamp = pts + frameIndex * frameDuration; + const id3Sample = { data: data, pts: stamp, dts: stamp, keyTagInfo: undefined, frames: id3.frames }; + id3Track.id3Samples.push(id3Sample); + offset += frameLength; + frameIndex++; + if (footerPresent) { + const di3 = MuxerHelper.bin2str(data.subarray(offset, offset + 3)); + if (di3 !== 'DI3') { + getLogger().error(loggerName$c, 'End should be DI3 if footer present in extracting ID3 payload'); + } + offset += 3; + // skip remaining 7 bits + offset += 7; + } + } + if (offset + 2 === length) { + const padding = MuxerHelper.readUint16(data, offset); + if (padding !== 0) { + getLogger().warn(loggerName$c, 'Padding should be 0 when extracting ID3 payload'); + } + } + } + /** + * @param data + * @param timeOffset The position in the media element corresponding to this fragment at rate 1 + * @param contiguous Contiguous with previously appeneded fragment + * @param keyTagInfo Object describing information about the key that was used to encrypt data + * @param iframeMediaStart If remuxing for iframe, the time in media element to remux fragment to + * @param iframeDuration If remuxing for iframe, the duration to remux fragment to + */ + append(data, timeOffset, contiguous, accurateTimeOffset, keyTagInfo, iframeMediaStart, iframeDuration) { + let initData = this.initData; + let videoDuration = 0, audioDuration = 0; + let hasVideo = false, hasAudio = false; + if (typeof initData === 'undefined') { + this.resetInitSegment(data, 0); + initData = this.initData; + } + let initPtsTs = this.initPtsTs; + let startDtsTs; + if (!initPtsTs) { + startDtsTs = MP4Demuxer.getStartDtsTs(initData, data); + this.initPtsTs = initPtsTs = { baseTime: startDtsTs.baseTime - Math.round(timeOffset * startDtsTs.timescale), timescale: startDtsTs.timescale }; + this.observer.trigger(DemuxerEvent.INIT_PTS_FOUND, { initPTS: initPtsTs }); + } + if (initData.foundLargeTimescale && MP4Demuxer.has32BitTfdts(data) && !iframeDuration) { + data = MP4EncryptionRemuxer.remuxOverflowSegment(data, this.logger); + } + // Don't remux start DTS, will be adjusted in source buffer timestampOffset instead + startDtsTs = MP4Demuxer.getStartDtsTs(initData, data); + const emsgs = MuxerHelper.findBox(data, ['emsg']); + if (initData.video && initData.video.encrypted) { + // Check for 'senc' or 'saiz' && 'saio' + const trafs = MuxerHelper.findBox(data, ['moof', 'traf']); + const gotSubsamples = trafs.find(function (traf) { + return Boolean(MuxerHelper.findBox(traf, ['senc'])[0] || (MuxerHelper.findBox(traf, ['saiz'])[0] && MuxerHelper.findBox(traf, ['saio'])[0])); + }); + if (!gotSubsamples) { + this.logger.warn(loggerName$c, `Missing subsample information for encrypted content codec=${initData.videoCodec}`); + } + } + if (iframeDuration) { + const timescale = this._videoTrack.timescale; + // snap the iframe durations so added the durations will result in timestamps that are always accurately representable when converted to uints + // we want to use ceil so durations aren't reduced, otherwise the same iframe could get chosen in the next round. + iframeDuration = Math.ceil(iframeDuration * timescale) / timescale; + // iframe timestamps are written directly, not offset, so we have to add the audioPrimingDelay since it'll + // still be shifted by the sourceBuffer.timestampOffset + const startDtsSec = (startDtsTs.baseTime + this.audioPrimingDelay * startDtsTs.timescale) / startDtsTs.timescale; + if (this._videoTrack && this._audioTrack && !this._silentAudioTrack) { + const silentTrackBase = SilentAudio.getTrack(this.observer, this._audioTrack.id, this._audioTrack.codec, 2, this.logger); + if (!silentTrackBase) { + throw `unable to create silent audio track for codec ${this._audioTrack.codec}`; + } + this._silentAudioTrack = Object.assign(Object.assign({}, silentTrackBase), { sequenceNumber: 0 }); + const iframeInitSegment = MP4$1.initSegment([this._videoTrack, this._silentAudioTrack]); + this.remuxedInitDataTrack = { type: 'audiovideo', container: 'video/mp4', codec: this._silentAudioTrack.config.codec + ',' + this._videoTrack.codec, initSegment: iframeInitSegment }; + const data = { track: this.remuxedInitDataTrack }; + this.observer.trigger(DemuxerEvent.FRAG_PARSING_INIT_SEGMENT, data); + } + MP4Demuxer.parseSamples(startDtsSec, data, this._videoTrack, iframeDuration, false, 1); + this.mp4Remuxer.remuxIFrame(startDtsSec, this._videoTrack, this._silentAudioTrack, iframeDuration, this.remuxedInitDataTrack); + this._videoTrack.samples = []; + } + else { + let startDtsSec = (startDtsTs.baseTime - this.audioPrimingDelay * startDtsTs.timescale) / startDtsTs.timescale; + startDtsSec = Math.max(0, startDtsSec); + if (emsgs && emsgs.length > 0) { + const emsgsInfos = emsgs.map((emsg) => { + const emsgInfo = MP4Demuxer.parseEmsg(emsg); + // HLSJS only processes id3 tags in emsgs + if (emsgInfo.schemeIdUri === 'https://aomedia.org/emsg/ID3\0' && !this._id3Track) { + this._id3Track = { id3Samples: [], inputTimescale: 90000 }; + } + return emsgInfo; + }); + if (this._id3Track) { + emsgsInfos.map((emsgInfo) => { + MP4Demuxer.extractID3PayloadCreateID3Track(emsgInfo, timeOffset, this._id3Track, this.logger); }); - for (var i = 0; i < ok.length; i++){ - if (ok[i].height > screenHeight){ - if (i == 0){n.splice(0,n.length);n.push(ok[i].content)} - else{n.splice(0,n.length);n.push(ok[i-1].content)} - console.log('selected' , n[0].height) - break; - - } - - } - if (n.length > 1){ - n.splice(0,n.length - 1); - } - // console.log(n) - // console.log(ok) - } catch (e){ console.log(e)} - return { - variantMediaOptions: n, - contentSteeringOption: u, - masterVariableList: s, - playlistParsingError: l, - scoreAvailable: c - } - } - static parseAllowedCPC(e) { - if ("string" != typeof e) - return null; - const n = {}; - return e.split(",").forEach(e=>{ - const t = e.split(":"); - let i, r; - if (2 === t.length) - i = t[0].trim(), - r = t[1].trim(); - else { - if (!(2 < t.length)) - return; - r = t[t.length - 1].trim(), - t.pop(), - i = t.join(":") - } - if (!(i in n)) { - let e = new Array; - "" !== r && (e = r.split("/").map(e=>e.trim())), - n[i] = e - } - } - ), - n - } - static parseSessionKeys(e, t, i) { - var r; - const n = []; - for (vm.SessionData.lastIndex = 0; r = vm.SessionKeys.exec(e); ) - try { - const e = bm.parseDecryptData(r[1], t, i); - e && e.isEncrypted && n.push(e) - } catch (e) {} - return n - } - static parseSessionData(e, t) { - var i; - const r = [] - , n = new Set; - for (vm.SessionData.lastIndex = 0; null != (i = vm.SessionData.exec(e)); ) { - const e = ym.parseTags(i[1]); - e.LANGUAGE = om.shortenLanguageCode(e.LANGUAGE); - const t = e.LANGUAGE ? e["DATA-ID"] + "|" + e.LANGUAGE : void 0; - "DATA-ID"in e ? t && n.has(t) || ("com.apple.hls.other-tags" === e["DATA-ID"] && (e.VALUE = function(t) { - let i; - try { - i = JSON.parse(Vc.base64DecodeToStr(t)) - } catch (e) { - i = t - } - return i - }(e.VALUE)), - r.push(e), - t && n.add(t)) : qe().error(`Error processing DATA-ID ${e["DATA-ID"]} and LANGUAGE ${e.LANGUAGE}`) - } - return { - itemList: r, - baseUrl: t - } - } + } + } + if (this._videoTrack) { + MP4Demuxer.parseSamples(startDtsSec, data, this._videoTrack, undefined, this.trySEICaptions, -1); + videoDuration = this._videoTrack.fragmentDuration / this._videoTrack.timescale; + hasVideo = true; + this._videoTrack.fragmentDuration = 0; + this.logger.info(loggerName$c, `frag video duration: ${videoDuration}`); + if (this.trySEICaptions) { + MP4Demuxer.extractSEICaptionsFromNALu(this._videoTrack.seiSamples, this._captionTrack); + this._videoTrack.seiSamples = []; + this.logger.info(loggerName$c, `sei samples: ${this._captionTrack.captionSamples.length}`); + } + else if (this._captionTrack) { + // clcp text track + MP4Demuxer.parseSamples(startDtsSec, data, this._captionTrack, undefined, false, Number.MAX_SAFE_INTEGER); + } + } + if (this._audioTrack) { + MP4Demuxer.parseSamples(startDtsSec, data, this._audioTrack, undefined, false, -1); + audioDuration = this._audioTrack.fragmentDuration / this._audioTrack.timescale; + hasAudio = true; + this._audioTrack.fragmentDuration = 0; + } + this.mp4Remuxer.remuxEmsgAndRawData(audioDuration, hasAudio, videoDuration, hasVideo, this._captionTrack, this._id3Track, startDtsSec, startDtsTs.timescale, data, this.remuxedInitDataTrack); + if (this._id3Track) { + this._id3Track.id3Samples = []; + } + } + } + static extractSEICaptionsFromNALu(units, textTrack) { + if (!units) { + return; + } + for (let u = 0; u < units.length; ++u) { + const unit = units[u]; + const pts = unit.pts; + let seiPtr = 0; + seiPtr++; + let payloadType = 0; + let payloadSize = 0; + let endOfCaptions = false; + let b = 0; + while (!endOfCaptions && seiPtr < unit.data.length) { + payloadType = 0; + do { + if (seiPtr >= unit.data.length) { + break; + } + b = unit.data[seiPtr++]; + payloadType += b; + } while (b === 255); + // Parse payload size. + payloadSize = 0; + do { + if (seiPtr >= unit.data.length) { + break; + } + b = unit.data[seiPtr++]; + payloadSize += b; + } while (b === 255); + const leftOver = unit.data.length - seiPtr; + if (payloadType === 4 && seiPtr < unit.data.length) { + endOfCaptions = true; + const countryCode = unit.data[seiPtr++]; + if (countryCode === 181) { + const providerCode = MuxerHelper.readUint16(unit.data, seiPtr); + seiPtr += 2; + if (providerCode === 49) { + const userStructure = MuxerHelper.readUint32(unit.data, seiPtr); + seiPtr += 4; + if (userStructure === 1195456820) { + const userDataType = unit.data[seiPtr++]; + // Raw CEA-608 bytes wrapped in CEA-708 packet + if (userDataType === 3) { + const firstByte = unit.data[seiPtr++]; + seiPtr++; // skip second byte + const totalCCs = 31 & firstByte; + const enabled = 64 & firstByte; + const byteArray = []; + if (enabled) { + for (let i = 0; i < totalCCs; i++) { + const ccData = unit.data[seiPtr++]; + const ccDataChecked = ccData & 252; + if (ccData === ccDataChecked) { + // valid ccData + const ccType = ccData & 3; + if (0 === ccType || 1 === ccType) { + // Exclude CEA708 CC data. + const b1 = unit.data[seiPtr++]; + const b2 = unit.data[seiPtr++]; + byteArray.push(b1); + byteArray.push(b2); + } + } + else { + seiPtr += 2; // Skip byte pair too + } + } + } + if (byteArray.length > 0) { + textTrack.captionSamples.push({ type: 3, pts: pts, bytes: byteArray }); + } + } + } + } + } + } + else if (payloadSize < leftOver) { + seiPtr += payloadSize; + } + else if (payloadSize > leftOver) { + break; + } + } + } + return textTrack; + } + } + + + const loggerName$b = { name: 'ExpGolomb' }; + class ExpGolomb { + constructor(data, logger) { + this.data = data; + this.logger = logger; + // the number of bytes left to examine in this.data + this._bytesAvailable = data.byteLength; + // the current word being examined + this.word = 0; // :uint + // the number of bits left to examine in the current word + this.bitsAvailable = 0; // :uint + } + get bytesAvailable() { + return this._bytesAvailable; + } + loadWord() { + const data = this.data, bytesAvailable = this._bytesAvailable, position = data.byteLength - bytesAvailable, workingBytes = new Uint8Array(4), availableBytes = Math.min(4, bytesAvailable); + if (availableBytes === 0) { + throw new Error('no bytes available'); + } + workingBytes.set(data.subarray(position, position + availableBytes)); + this.word = new DataView(workingBytes.buffer).getUint32(0); + // track the amount of this.data that has been processed + this.bitsAvailable = availableBytes * 8; + this._bytesAvailable -= availableBytes; + } + skipBits(count) { + let skipBytes; // :int + if (this.bitsAvailable > count) { + this.word <<= count; + this.bitsAvailable -= count; + } + else { + count -= this.bitsAvailable; + skipBytes = count >> 3; + count -= skipBytes >> 3; + this._bytesAvailable -= skipBytes; + this.loadWord(); + this.word <<= count; + this.bitsAvailable -= count; + } + } + readBits(size) { + let bits = Math.min(this.bitsAvailable, size); // :uint + const valu = this.word >>> (32 - bits); // :uint + if (size > 32) { + this.logger.error(loggerName$b, 'Cannot read more than 32 bits at a time'); + } + this.bitsAvailable -= bits; + if (this.bitsAvailable > 0) { + this.word <<= bits; + } + else if (this._bytesAvailable > 0) { + this.loadWord(); + } + bits = size - bits; + if (bits > 0 && this.bitsAvailable) { + return (valu << bits) | this.readBits(bits); + } + else { + return valu; + } + } + // ():uint + skipLZ() { + let leadingZeroCount; // :uint + for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) { + if (0 !== (this.word & (2147483648 >>> leadingZeroCount))) { + // the first bit of working word is 1 + this.word <<= leadingZeroCount; + this.bitsAvailable -= leadingZeroCount; + return leadingZeroCount; + } + } + // we exhausted word and still have not found a 1 + this.loadWord(); + return leadingZeroCount + this.skipLZ(); + } + // ():void + skipUEG() { + this.skipBits(1 + this.skipLZ()); + } + // ():void + skipEG() { + this.skipBits(1 + this.skipLZ()); + } + // ():uint + readUEG() { + const clz = this.skipLZ(); // :uint + return this.readBits(clz + 1) - 1; + } + // ():int + readEG() { + const valu = this.readUEG(); // :int + if (1 & valu) { + // the number is odd if the low order bit is set + return (1 + valu) >>> 1; // add 1 to make it even, and divide by 2 + } + else { + return -1 * (valu >>> 1); // divide by two then make it negative + } + } + // Some convenience functions + // :Boolean + readBoolean() { + return 1 === this.readBits(1); + } + // ():int + readUByte() { + return this.readBits(8); + } + // ():int + readUShort() { + return this.readBits(16); + } + // ():int + readUInt() { + return this.readBits(32); + } + /** + * Advance the ExpGolomb decoder past a scaling list. The scaling + * list is optionally transmitted as part of a sequence parameter + * set and is not relevant to transmuxing. + * @param count {number} the number of entries in this scaling list + * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1 + */ + skipScalingList(count) { + let lastScale = 8, nextScale = 8, j, deltaScale; + for (j = 0; j < count; j++) { + if (nextScale !== 0) { + deltaScale = this.readEG(); + nextScale = (lastScale + deltaScale + 256) % 256; + } + lastScale = nextScale === 0 ? lastScale : nextScale; + } + } + /** + * Read a sequence parameter set and return some interesting video + * properties. A sequence parameter set is the H264 metadata that + * describes the properties of upcoming video frames. + * @param data {Uint8Array} the bytes of a sequence parameter set + * @return {object} an object with configuration parsed from the + * sequence parameter set, including the dimensions of the + * associated video frames. + */ + readSPS() { + let frameCropLeftOffset = 0, frameCropRightOffset = 0, frameCropTopOffset = 0, frameCropBottomOffset = 0, numRefFramesInPicOrderCntCycle, scalingListCount, i; + const readUByte = this.readUByte.bind(this), readBits = this.readBits.bind(this), readUEG = this.readUEG.bind(this), readBoolean = this.readBoolean.bind(this), skipBits = this.skipBits.bind(this), skipEG = this.skipEG.bind(this), skipUEG = this.skipUEG.bind(this), skipScalingList = this.skipScalingList.bind(this); + readUByte(); + const profileIdc = readUByte(); // profile_idc + readBits(5); // constraint_set[0-4]_flag, u(5) + skipBits(3); // reserved_zero_3bits u(3), + readUByte(); // level_idc u(8) + skipUEG(); // seq_parameter_set_id + // some profiles have more optional data we don't need + if (profileIdc === 100 || + profileIdc === 110 || + profileIdc === 122 || + profileIdc === 244 || + profileIdc === 44 || + profileIdc === 83 || + profileIdc === 86 || + profileIdc === 118 || + profileIdc === 128) { + const chromaFormatIdc = readUEG(); + if (chromaFormatIdc === 3) { + skipBits(1); // separate_colour_plane_flag + } + skipUEG(); // bit_depth_luma_minus8 + skipUEG(); // bit_depth_chroma_minus8 + skipBits(1); // qpprime_y_zero_transform_bypass_flag + if (readBoolean()) { + // seq_scaling_matrix_present_flag + scalingListCount = chromaFormatIdc !== 3 ? 8 : 12; + for (i = 0; i < scalingListCount; i++) { + if (readBoolean()) { + // seq_scaling_list_present_flag[ i ] + if (i < 6) { + skipScalingList(16); + } + else { + skipScalingList(64); + } + } + } + } + } + skipUEG(); // log2_max_frame_num_minus4 + const picOrderCntType = readUEG(); + if (picOrderCntType === 0) { + readUEG(); // log2_max_pic_order_cnt_lsb_minus4 + } + else if (picOrderCntType === 1) { + skipBits(1); // delta_pic_order_always_zero_flag + skipEG(); // offset_for_non_ref_pic + skipEG(); // offset_for_top_to_bottom_field + numRefFramesInPicOrderCntCycle = readUEG(); + for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) { + skipEG(); // offset_for_ref_frame[ i ] + } + } + skipUEG(); // max_num_ref_frames + skipBits(1); // gaps_in_frame_num_value_allowed_flag + const picWidthInMbsMinus1 = readUEG(); + const picHeightInMapUnitsMinus1 = readUEG(); + const frameMbsOnlyFlag = readBits(1); + if (frameMbsOnlyFlag === 0) { + skipBits(1); // mb_adaptive_frame_field_flag + } + skipBits(1); // direct_8x8_inference_flag + if (readBoolean()) { + // frame_cropping_flag + frameCropLeftOffset = readUEG(); + frameCropRightOffset = readUEG(); + frameCropTopOffset = readUEG(); + frameCropBottomOffset = readUEG(); + } + let pixelRatio = [1, 1]; + if (readBoolean()) { + // vui_parameters_present_flag + if (readBoolean()) { + // aspect_ratio_info_present_flag + const aspectRatioIdc = readUByte(); + switch (aspectRatioIdc) { + case 1: + pixelRatio = [1, 1]; + break; + case 2: + pixelRatio = [12, 11]; + break; + case 3: + pixelRatio = [10, 11]; + break; + case 4: + pixelRatio = [16, 11]; + break; + case 5: + pixelRatio = [40, 33]; + break; + case 6: + pixelRatio = [24, 11]; + break; + case 7: + pixelRatio = [20, 11]; + break; + case 8: + pixelRatio = [32, 11]; + break; + case 9: + pixelRatio = [80, 33]; + break; + case 10: + pixelRatio = [18, 11]; + break; + case 11: + pixelRatio = [15, 11]; + break; + case 12: + pixelRatio = [64, 33]; + break; + case 13: + pixelRatio = [160, 99]; + break; + case 14: + pixelRatio = [4, 3]; + break; + case 15: + pixelRatio = [3, 2]; + break; + case 16: + pixelRatio = [2, 1]; + break; + case 255: { + pixelRatio = [(readUByte() << 8) | readUByte(), (readUByte() << 8) | readUByte()]; + break; + } + } + } + } + return { + width: Math.ceil((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2), + height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset), + pixelRatio: pixelRatio, + }; + } + readSliceType() { + // skip NALu type + this.readUByte(); + // discard first_mb_in_slice + this.readUEG(); + // return slice_type + return this.readUEG(); + } + } + + + const TIMESCALE = 90000; + const loggerName$a = { name: 'TS Demuxer' }; + function isCompleteVideoConfig(config) { + const is = typeof config.codec === 'string' && + Array.isArray(config.sps) && + Array.isArray(config.pps) && + typeof config.width === 'number' && + typeof config.height === 'number' && + Array.isArray(config.pixelRatio); + return is; + } + class TsDemuxer extends EsDemuxer { + constructor(observer, remuxer, config, typeSupported, logger) { + super(observer, remuxer, config, typeSupported, logger); + } + static probe(data, logger) { + // a TS fragment should contain at least 3 TS packets, a PAT, a PMT, and one PID, each starting with 0x47 + if (data.length >= 564 && data[0] === 71 && data[188] === 71 && data[376] === 71) { + return true; + } + else { + return false; + } + } + resetInitSegment(initSegment, duration, keyTagInfo) { + this.pmtParsed = false; + this._pmtId = -1; + const baseInfo = { id: -1, inputTimescale: TIMESCALE, timescale: NaN, duration: 0, encrypted: keyTagInfo && keyTagInfo.isEncrypted, keyTagInfo }; + const baseParsingInfo = { len: 0, sequenceNumber: 0 }; + this._avcContext = { info: Object.assign({}, baseInfo), parsingData: Object.assign(Object.assign({}, baseParsingInfo), { esSamples: new Array(), dropped: 0 }), config: {}, container: 'video/mp2t', type: 'video' }; + this._audioContext = { info: Object.assign({}, baseInfo), parsingData: Object.assign(Object.assign({}, baseParsingInfo), { esSamples: new Array() }), container: 'video/mp2t', type: 'audio' }; + this._id3Track = { id: -1, inputTimescale: TIMESCALE, id3Samples: [] }; + this._txtTrack = { inputTimescale: TIMESCALE, captionSamples: [] }; + this._duration = duration; + this._initSegment = initSegment; + } + // feed incoming data to the front of the parsing pipeline + append(data, timeOffset, contiguous, accurateTimeOffset, keyTagInfo, iframeMediaStart, iframeDuration) { + let start, stt, pid, atf, offset, pes, unknownPIDs = false; + this.contiguous = contiguous; + const avcContext = this._avcContext, audioContext = this._audioContext, id3Track = this._id3Track; + let pmtParsed = this.pmtParsed, avcId = avcContext.info.id, audioId = audioContext.info.id, id3Id = id3Track.id, pmtId = this._pmtId, avcData = avcContext.pesData, audioData = audioContext.pesData, id3Data = id3Track.pesData; + this.iframeMode = typeof iframeDuration !== 'undefined'; + if (this._initSegment && this._initSegment.byteLength > 0) { + // if there's an init segment then it needs to be prepended to the first data + const newData = new Uint8Array(this._initSegment.byteLength + data.byteLength); + newData.set(this._initSegment); + newData.set(data, this._initSegment.byteLength); + this._initSegment = undefined; + // make sure its still valid TS + if (newData[0] === 71) { + data = newData; + } + } + let len = data.length; + // don't parse last TS packet if incomplete + len -= len % 188; + // loop through TS packets + for (start = 0; start < len; start += 188) { + if (data[start] === 71) { + // payload unit start indicator - pes immediately follows the ts header + stt = !!(data[start + 1] & 64); + // pid is a 13-bit field starting at the last bit of TS[1] + pid = ((data[start + 1] & 31) << 8) + data[start + 2]; + atf = (data[start + 3] & 48) >> 4; + // if an adaption field is present, its length is specified by the fifth byte of the TS packet header. + if (atf > 1) { + offset = start + 5 + data[start + 4]; + // continue if there is only adaptation field + if (offset === start + 188) { + continue; + } + } + else { + offset = start + 4; + } + switch (pid) { + case avcId: + if (stt) { + if (avcData && (pes = this._parsePES(avcData))) { + // new pes is starting and we have an current one, therefore the current pes is complete, so lets parse it + this._parseAVCPES(pes, false); + } + // reset the current pes data + avcData = { data: [], size: 0, keyTagInfo: keyTagInfo }; + } + if (avcData) { + avcData.data.push(data.subarray(offset, start + 188)); + avcData.size += start + 188 - offset; + } + break; + case audioId: + if (stt && !this.iframeMode) { + if (audioData && (pes = this._parsePES(audioData))) { + switch (audioContext.segmentCodec) { + case 'aac': + this._parseAACPES(pes); + break; + case 'mp3': + this._parseMPEGPES(pes); + break; + case 'ac3': + case 'ec3': + this._parseDolbyPES(pes); + break; + } + } + audioData = { data: [], size: 0, keyTagInfo: keyTagInfo }; + } + if (audioData) { + audioData.data.push(data.subarray(offset, start + 188)); + audioData.size += start + 188 - offset; + } + break; + case id3Id: + if (stt) { + if (id3Data && (pes = this._parsePES(id3Data))) { + id3Track.id3Samples.push(pes); + } + id3Data = { data: [], size: 0 }; + } + if (id3Data) { + id3Data.data.push(data.subarray(offset, start + 188)); + id3Data.size += start + 188 - offset; + } + break; + case 0: + if (stt) { + offset += data[offset] + 1; + } + pmtId = this._pmtId = this._parsePAT(data, offset); + break; + case pmtId: + if (stt) { + offset += data[offset] + 1; + } + const parsedPIDs = this._parsePMT(data, offset, this.typeSupported); + // only update track id if track PID found while parsing PMT + // this is to avoid resetting the PID to -1 in case + // track PID transiently disappears from the stream + // this could happen in case of transient missing audio samples for example + avcId = parsedPIDs.avcId; + if (avcId > 0) { + avcContext.info.id = avcId; + avcContext.info.encrypted = parsedPIDs.videoEncrypted; + } + audioId = parsedPIDs.audioId; + if (audioId > 0) { + audioContext.info.id = audioId; + audioContext.segmentCodec = parsedPIDs.audioSegmentCodec; + audioContext.info.encrypted = parsedPIDs.audioEncrypted; + } + id3Id = parsedPIDs.id3Id; + if (id3Id > 0) { + id3Track.id = id3Id; + } + if (unknownPIDs && !pmtParsed) { + this.logger.info(loggerName$a, 'reparse from beginning'); + unknownPIDs = false; + // we set it to -188, the += 188 in the for loop will reset start to 0 + start = -188; + } + pmtParsed = this.pmtParsed = true; + break; + case 17: // eslint-disable-line + case 8191: + break; + default: + unknownPIDs = true; + break; + } + } + else { + const payload = new FragParsingError(false, 'TS packet did not start with 0x47', ErrorResponses.NoTSSyncByteFound); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return; + } + } + // try to parse last PES packets + if (avcData && (pes = this._parsePES(avcData))) { + this._parseAVCPES(pes, true); + avcContext.pesData = undefined; + } + else { + // either avcData null or PES truncated, keep it for next frag parsing + avcContext.pesData = avcData; + } + if (audioData && (pes = this._parsePES(audioData))) { + switch (audioContext.segmentCodec) { + case 'aac': + this._parseAACPES(pes); + break; + case 'mp3': + this._parseMPEGPES(pes); + break; + case 'ac3': + case 'ec3': + this._parseDolbyPES(pes); + break; + } + audioContext.pesData = undefined; + } + else { + if (audioData && audioData.size) { + this.logger.warn(loggerName$a, 'last AAC PES packet truncated,might overlap between fragments'); + } + // either audioData null or PES truncated, keep it for next frag parsing + audioContext.pesData = audioData; + } + if (id3Data && (pes = this._parsePES(id3Data))) { + id3Track.id3Samples.push(pes); + id3Track.pesData = undefined; + } + else { + // either id3Data null or PES truncated, keep it for next frag parsing + id3Track.pesData = id3Data; + } + let audioTrack; + if (audioContext.config && audioContext.segmentCodec) { + audioTrack = { type: 'audio', info: audioContext.info, config: audioContext.config, parsingData: audioContext.parsingData }; + } + let videoTrack; + const pc = avcContext.config; + if (isCompleteVideoConfig(pc)) { + videoTrack = { type: 'video', info: avcContext.info, config: pc, parsingData: avcContext.parsingData }; + } + this.esRemuxer.remuxEsTracks(audioTrack, videoTrack, id3Track, this._txtTrack, timeOffset, contiguous, accurateTimeOffset, keyTagInfo, iframeMediaStart, iframeDuration); + } + destroy() { + this._duration = 0; + } + _parsePAT(data, offset) { + // skip the PSI header and parse the first PMT entry + return ((data[offset + 10] & 31) << 8) | data[offset + 11]; + } + _parsePMT(data, offset, typeSupported) { + let pid; // result = { audio : -1, avc : -1, id3 : -1, segmentCodec : 'aac', videoEncrypted : false, audioEncrypted :false }; + const result = { + audioId: -1, + avcId: -1, + id3Id: -1, + audioEncrypted: false, + videoEncrypted: false, + }; + const sectionLength = ((data[offset + 1] & 15) << 8) | data[offset + 2]; + const tableEnd = offset + 3 + sectionLength - 4; + // to determine where the table is, we have to figure out how + // long the program info descriptors are + const programInfoLength = ((data[offset + 10] & 15) << 8) | data[offset + 11]; + // advance the offset to the first entry in the mapping table + offset += 12 + programInfoLength; + while (offset < tableEnd) { + pid = ((data[offset + 1] & 31) << 8) | data[offset + 2]; + switch (data[offset]) { + case 207: + result.audioEncrypted = true; + /* falls through */ + // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio) + case 15: + // logger.info('AAC PID:' + pid); + if (result.audioId === -1) { + result.audioId = pid; + result.audioSegmentCodec = 'aac'; + } + break; + // Packetized metadata (ID3) + case 21: + // logger.info('ID3 PID:' + pid); + if (result.id3Id === -1) { + result.id3Id = pid; + } + break; + case 219: + result.videoEncrypted = true; + /* falls through */ + // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video) + case 27: + // logger.info('AVC PID:' + pid); + if (result.avcId === -1) { + result.avcId = pid; + } + break; + // ISO/IEC 11172-3 (MPEG-1 audio) + // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio) + case 3: + case 4: + // logger.info('MPEG PID:' + pid); + if (typeSupported.mpeg !== true && typeSupported.mp3 !== true) { + this.logger.warn(loggerName$a, 'MPEG audio found, not supported in this browser for now'); + } + else if (result.audioId === -1) { + result.audioId = pid; + result.audioSegmentCodec = 'mp3'; + } + break; + case 193: + result.audioEncrypted = true; + this.logger.info(loggerName$a, 'TS encrypted AC-3 audio found'); + /* falls through */ + case 129: + if (typeSupported.ac3 !== true) { + this.logger.warn(loggerName$a, 'AC-3 audio found, not supported in this browser for now'); + } + else if (result.audioId === -1) { + result.audioId = pid; + result.audioSegmentCodec = 'ac3'; + } + break; + case 194: + result.audioEncrypted = true; + this.logger.info(loggerName$a, 'TS encrypted EC-3 audio found'); + /* falls through */ + case 135: + if (typeSupported.ec3 !== true) { + this.logger.warn(loggerName$a, 'EC-3 audio found, not supported in this browser for now'); + } + else if (result.audioId === -1) { + result.audioId = pid; + result.audioSegmentCodec = 'ec3'; + } + break; + case 36: + this.logger.warn(loggerName$a, 'HEVC stream type found, not supported for now'); + break; + default: + this.logger.warn(loggerName$a, 'unkown stream type:' + data[offset]); + break; + } + // move to the next table entry + // skip past the elementary stream descriptors, if present + offset += (((data[offset + 3] & 15) << 8) | data[offset + 4]) + 5; + } + return result; + } + _parsePES(stream) { + let i = 0, frag, pesFlags, pesLen, pesHdrLen, pesData, payloadStartOffset; + const data = stream.data, keyTagInfo = stream.keyTagInfo; + let pesPts = NaN, pesDts = NaN; + // safety check + if (!stream || stream.size === 0) { + return undefined; + } + // we might need up to 19 bytes to read PES header + // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes + // usually only one merge is needed (and this is rare ...) + while (data[0].length < 19 && data.length > 1) { + const newData = new Uint8Array(data[0].length + data[1].length); + newData.set(data[0]); + newData.set(data[1], data[0].length); + data[0] = newData; + data.splice(1, 1); + } + // retrieve PTS/DTS from first fragment + frag = data[0]; + const pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2]; + if (pesPrefix === 1) { + pesLen = (frag[4] << 8) + frag[5]; + // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated + // minus 6 : PES header size + if (pesLen && pesLen > stream.size - 6) { + return undefined; + } + pesFlags = frag[7]; + if (pesFlags & 192) { + /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html + as PTS / DTS is 33 bit we cannot use bitwise operator in JS, + as Bitwise operators treat their operands as a sequence of 32 bits */ + pesPts = + (frag[9] & 14) * 536870912 + // 1 << 29 + (frag[10] & 255) * 4194304 + // 1 << 22 + (frag[11] & 254) * 16384 + // 1 << 14 + (frag[12] & 255) * 128 + // 1 << 7 + (frag[13] & 254) / 2; + if (pesFlags & 64) { + pesDts = + (frag[14] & 14) * 536870912 + // 1 << 29 + (frag[15] & 255) * 4194304 + // 1 << 22 + (frag[16] & 254) * 16384 + // 1 << 14 + (frag[17] & 255) * 128 + // 1 << 7 + (frag[18] & 254) / 2; + if (pesPts - pesDts > 5400000) { + this.logger.warn(loggerName$a, `${Math.round((pesPts - pesDts) / 90000)}s delta between PTS and DTS, align them`); + pesPts = pesDts; + } + } + else { + pesDts = pesPts; + } + } + pesHdrLen = frag[8]; + // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension + payloadStartOffset = pesHdrLen + 9; + stream.size -= payloadStartOffset; + // reassemble PES packet + pesData = new Uint8Array(stream.size); + for (let j = 0, dataLen = data.length; j < dataLen; j++) { + frag = data[j]; + let len = frag.byteLength; + if (payloadStartOffset) { + if (payloadStartOffset > len) { + // trim full frag if PES header bigger than frag + payloadStartOffset -= len; + continue; + } + else { + // trim partial frag if PES header smaller than frag + frag = frag.subarray(payloadStartOffset); + len -= payloadStartOffset; + payloadStartOffset = 0; + } + } + pesData.set(frag, i); + i += len; + } + if (pesLen) { + // payload size : remove PES header + PES extension + pesLen -= pesHdrLen + 3; + } + return { data: pesData, pts: pesPts, dts: pesDts, len: pesLen, keyTagInfo: keyTagInfo }; + } + else { + return undefined; + } + } + pushAccesUnit(avcContext, keyTagInfo) { + const avcSample = avcContext.avcSample; + if (avcSample && avcSample.units.length && avcSample.frame) { + const samples = avcContext.parsingData.esSamples; + const nbSamples = samples.length; + if (avcSample.key === true || (avcContext.config.sps && (nbSamples || this.contiguous))) { + avcSample.id = nbSamples; + avcSample.keyTagInfo = keyTagInfo; + if (avcContext.info.encrypted) { + const units = avcSample.units; + units.forEach((unit) => { + if (unit.data.byteLength > 48) { + switch (unit.type) { + case 1: + case 5: + // need to remove EPBs from encrypted NALs now that they're parsed into units + unit.data = this.discardEPB(unit.data); + break; + } + } + }); + } + } + if (!nbSamples && !isFinite(avcSample.pts)) { + // dropping samples, no timestamp found + avcContext.parsingData.dropped++; + return; + } + samples.push(avcSample); + } + if (avcSample && avcSample.debug.length) { + this.logger.info(loggerName$a, avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug); + } + } + _parseAVCPES(pes, last) { + if (!pes.data) { + throw 'invalid pes data'; + } + const avcContext = this._avcContext, units = this._parseAVCNALu(pes.data); + let expGolombDecoder, avcSample = avcContext.avcSample, push, i; + const keyTagInfo = pes.keyTagInfo; + // free pes.data to save up some memory + pes.data = undefined; + units.forEach((unit) => { + switch (unit.type) { + // NDR + case 1: + if (avcSample && !this.iframeMode) { + // TODO: demuxer needs better support for partial nal units + push = true; + avcSample.frame = true; + // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR + const data = unit.data; + if (data.length > 4) { + const sliceType = new ExpGolomb(data, this.logger).readSliceType(); + // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice + // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples. + // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice. + // I slice: A slice that is not an SI slice that is decoded using intra prediction only. + // if (sliceType === 2 || sliceType === 7) { + if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) { + avcSample.key = true; + } + } + } + break; + // IDR + case 5: + push = true; + if (avcSample) { + // handle PES not starting with AUD + if (!avcSample) { + avcSample = avcContext.avcSample = this._createAVCSample(true, pes.pts, pes.dts, ''); + } + avcSample.key = true; + avcSample.frame = true; + } + break; + // SEI + case 6: + push = true; + expGolombDecoder = new ExpGolomb(this.discardEPB(unit.data), this.logger); + // skip frameType + expGolombDecoder.readUByte(); + let payloadType = 0; + let payloadSize = 0; + let endOfCaptions = false; + let b = 0; + while (!endOfCaptions && expGolombDecoder.bytesAvailable > 1) { + payloadType = 0; + do { + b = expGolombDecoder.readUByte(); + payloadType += b; + } while (b === 255); + // Parse payload size. + payloadSize = 0; + do { + b = expGolombDecoder.readUByte(); + payloadSize += b; + } while (b === 255); + // TODO: there can be more than one payload in an SEI packet... + // TODO: need to read type and size in a while loop to get them all + if (payloadType === 4 && expGolombDecoder.bytesAvailable !== 0) { + endOfCaptions = true; + const countryCode = expGolombDecoder.readUByte(); + if (countryCode === 181) { + const providerCode = expGolombDecoder.readUShort(); + if (providerCode === 49) { + const userStructure = expGolombDecoder.readUInt(); + if (userStructure === 1195456820) { + const userDataType = expGolombDecoder.readUByte(); + // Raw CEA-608 bytes wrapped in CEA-708 packet + if (userDataType === 3) { + const firstByte = expGolombDecoder.readUByte(); + const secondByte = expGolombDecoder.readUByte(); + const totalCCs = 31 & firstByte; + const byteArray = [firstByte, secondByte]; + for (i = 0; i < totalCCs; i++) { + // 3 bytes per CC + byteArray.push(expGolombDecoder.readUByte()); + byteArray.push(expGolombDecoder.readUByte()); + byteArray.push(expGolombDecoder.readUByte()); + } + this._insertSampleInOrder(this._txtTrack.captionSamples, { type: 3, pts: pes.pts, bytes: byteArray }); + } + } + } + } + } + else if (payloadSize < expGolombDecoder.bytesAvailable) { + for (i = 0; i < payloadSize; i++) { + expGolombDecoder.readUByte(); + } + } + } + break; + // SPS + case 7: + push = true; + if (!avcContext.config.sps) { + expGolombDecoder = new ExpGolomb(unit.data, this.logger); + const config = expGolombDecoder.readSPS(); + avcContext.config.width = config.width; + avcContext.config.height = config.height; + avcContext.config.pixelRatio = config.pixelRatio; + avcContext.config.sps = [unit.data]; + avcContext.info.duration = this._duration; + const codecarray = unit.data.subarray(1, 4); + let codecstring = 'avc1.'; + for (i = 0; i < 3; i++) { + let h = codecarray[i].toString(16); + if (h.length < 2) { + h = '0' + h; + } + codecstring += h; + } + avcContext.config.codec = codecstring; + } + break; + // PPS + case 8: + push = true; + if (!avcContext.config.pps) { + avcContext.config.pps = [unit.data]; + } + break; + // AUD + case 9: + push = false; + if (avcSample) { + this.pushAccesUnit(avcContext, keyTagInfo); + } + avcSample = avcContext.avcSample = this._createAVCSample(false, pes.pts, pes.dts, ''); + break; + // Filler Data + case 12: + push = false; + break; + default: + push = false; + if (avcSample) { + avcSample.debug += 'unknown NAL ' + unit.type + ' '; + } + break; + } + if (avcSample && push) { + const units = avcSample.units; + units.push(unit); + } + }); + // if last PES packet, push samples + if (last && avcSample) { + this.pushAccesUnit(avcContext, keyTagInfo); + avcContext.avcSample = undefined; + } + } + _createAVCSample(key, pts, dts, debug) { + return { id: NaN, key: key, pts: pts, dts: dts, units: new Array(), debug: debug }; + } + _insertSampleInOrder(arr, data) { + const len = arr.length; + if (len > 0) { + if (data.pts >= arr[len - 1].pts) { + arr.push(data); + } + else { + for (let pos = len - 1; pos >= 0; pos--) { + if (data.pts < arr[pos].pts) { + arr.splice(pos, 0, data); + break; + } + } + } + } + else { + arr.push(data); + } + } + _getLastNalUnit() { + const avcContext = this._avcContext; + let avcSample = avcContext.avcSample, lastUnit; + // try to fallback to previous sample if current one is empty + if (!avcSample || avcSample.units.length === 0) { + const samples = avcContext.parsingData.esSamples; + avcSample = samples[samples.length - 1]; + } + if (avcSample) { + const units = avcSample.units; + lastUnit = units[units.length - 1]; + } + return lastUnit; + } + _parseAVCNALu(array) { + const len = array.byteLength; + let i = 0, value, overflow; + const avcContext = this._avcContext; + let state = avcContext.naluState || 0; + const lastState = state; + const units = []; + let unit, unitType, lastUnitStart = -1, lastUnitType; + if (state === -1) { + // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet + lastUnitStart = 0; + // NALu type is value read from offset 0 + lastUnitType = array[0] & 31; + state = 0; + i = 1; + } + while (i < len) { + value = array[i++]; + // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case + if (!state) { + state = value ? 0 : 1; + continue; + } + if (state === 1) { + state = value ? 0 : 2; + continue; + } + // here we have state either equal to 2 or 3 + if (!value) { + state = 3; + } + else if (value === 1) { + if (lastUnitStart >= 0) { + unit = { data: array.subarray(lastUnitStart, i - state - 1), type: lastUnitType }; + units.push(unit); + } + else { + // lastUnitStart is -1 => this is the first start code found in this PES packet + // first check if start code delimiter is overlapping between 2 PES packets, + // ie it started in last packet (lastState not zero) + // and ended at the beginning of this PES packet (i <= 4 - lastState) + const lastUnit = this._getLastNalUnit(); + if (lastUnit) { + if (lastState && i <= 4 - lastState) { + // start delimiter overlapping between PES packets + // strip start delimiter bytes from the end of last NAL unit + // check if lastUnit had a state different from zero + if (lastUnit.state) { + // strip last bytes + lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState); + } + } + // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit. + overflow = i - state - 1; + if (overflow > 0) { + const tmp = new Uint8Array(lastUnit.data.byteLength + overflow); + tmp.set(lastUnit.data, 0); + tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength); + lastUnit.data = tmp; + lastUnit.state = 0; + } + } + } + // check if we can read unit type + if (i < len) { + unitType = array[i] & 31; + lastUnitStart = i; + lastUnitType = unitType; + state = 0; + } + else { + // not enough byte to read unit type. let's read it on next PES parsing + state = -1; + } + } + else { + state = 0; + } + } + if (lastUnitStart >= 0 && state >= 0) { + unit = { data: array.subarray(lastUnitStart, len), type: lastUnitType, state }; + units.push(unit); + } + // no NALu found + if (units.length === 0) { + // append pes.data to previous NAL unit + const lastUnit = this._getLastNalUnit(); + if (lastUnit) { + const tmp = new Uint8Array(lastUnit.data.byteLength + array.byteLength); + tmp.set(lastUnit.data, 0); + tmp.set(array, lastUnit.data.byteLength); + lastUnit.data = tmp; + } + } + avcContext.naluState = state; + return units; + } + /** + * remove Emulation Prevention bytes from a RBSP + */ + discardEPB(data) { + const length = data.byteLength, EPBPositions = []; + let i = 1; + // Find all `Emulation Prevention Bytes` + while (i < length - 2) { + if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 3) { + EPBPositions.push(i + 2); + i += 2; + } + else { + i++; + } + } + // If no Emulation Prevention Bytes were found just return the original + // array + if (EPBPositions.length === 0) { + return data; + } + // Create a new array to hold the NAL unit data + const newLength = length - EPBPositions.length; + const newData = new Uint8Array(newLength); + let sourceIndex = 0; + for (i = 0; i < newLength; sourceIndex++, i++) { + if (sourceIndex === EPBPositions[0]) { + // Skip this byte + sourceIndex++; + // Remove this position index + EPBPositions.shift(); + } + newData[i] = data[sourceIndex]; + } + return newData; + } + _parseAACPES(pes) { + const audioContext = this._audioContext, audioLastPTS = audioContext.audioLastPTS, startOffset = 0, keyTagInfo = pes.keyTagInfo; + let data = pes.data, pts = pes.pts, audioOverFlow = audioContext.audioOverFlow, frameLength, frameIndex, offset, headerLength, stamp, len, aacSample; + if (audioOverFlow) { + const tmp = new Uint8Array(audioOverFlow.byteLength + data.byteLength); + tmp.set(audioOverFlow, 0); + tmp.set(data, audioOverFlow.byteLength); + data = tmp; + } + // look for ADTS header (0xFFFx) + for (offset = startOffset, len = data.length; offset < len - 1; offset++) { + if (data[offset] === 255 && (data[offset + 1] & 240) === 240) { + break; + } + } + // if ADTS header does not start straight from the beginning of the PES payload, raise an error + if (offset) { + let reason, fatal, response; + if (offset < len - 1) { + reason = `AAC PES did not start with ADTS header,offset:${offset}`; + fatal = false; + response = ErrorResponses.PESDidNotStartWithADTS; + } + else { + reason = 'no ADTS header found in AAC PES'; + fatal = true; + response = ErrorResponses.NoADTSHeaderInPES; + } + this.logger.warn(loggerName$a, `parsing error:${reason}`); + const payload = new FragParsingError(fatal, reason, response); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + if (fatal) { + return; + } + } + if (!audioContext.config) { + const config = ADTS.getAudioConfig(this.observer, data, offset, undefined, this.logger); + if (!config) { + throw 'unable to parse adts header'; + } + audioContext.config = config; + this.logger.info(loggerName$a, `parsed codec:${config.codec},rate:${config.samplerate},nb channel:${config.channelCount}`); + } + frameIndex = 0; + const frameDuration = 92160000 / audioContext.config.samplerate; + // if last AAC frame is overflowing, we should ensure timestamps are contiguous: + // first sample PTS should be equal to last sample PTS + frameDuration + if (audioOverFlow && audioLastPTS) { + const newPTS = audioLastPTS + frameDuration; + if (Math.abs(newPTS - pts) > 1) { + this.logger.info(loggerName$a, `AAC: align PTS for overlapping frames by ${Math.round((newPTS - pts) / 90)}`); + pts = newPTS; + } + } + while (offset + 5 < len) { + // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header + headerLength = data[offset + 1] & 1 ? 7 : 9; + // retrieve frame size + frameLength = ((data[offset + 3] & 3) << 11) | (data[offset + 4] << 3) | ((data[offset + 5] & 224) >>> 5); + frameLength -= headerLength; + if (frameLength > 0 && offset + headerLength + frameLength <= len) { + stamp = pts + frameIndex * frameDuration; + aacSample = { unit: data.subarray(offset + headerLength, offset + headerLength + frameLength), pts: stamp, dts: stamp, keyTagInfo: keyTagInfo }; + audioContext.parsingData.esSamples.push(aacSample); + audioContext.parsingData.len += frameLength; + offset += frameLength + headerLength; + frameIndex++; + // look for ADTS header (0xFFFx) + for (; offset < len - 1; offset++) { + if (data[offset] === 255 && (data[offset + 1] & 240) === 240) { + break; + } + } + } + else { + break; + } + } + if (offset < len) { + audioOverFlow = data.subarray(offset, len); + } + else { + audioOverFlow = undefined; + } + audioContext.audioOverFlow = audioOverFlow; + audioContext.audioLastPTS = stamp; + } + _parseMPEGPES(pes) { + if (this._audioContext.segmentCodec === 'mp3') { + MpegAudio$1.parse(this._audioContext.parsingData, pes.data, 0, pes.pts, this.logger); + } + } + _parseDolbyPES(pes) { + const audioContext = this._audioContext; + let data = pes.data; + let pts = pes.pts; + const keyTagInfo = pes.keyTagInfo; + let frameIndex = 0; + let offset = 0; + let audioOverFlow = audioContext.audioOverFlow; + const audioLastPTS = audioContext.audioLastPTS; + if (!audioContext.config) { + let config; + if (audioContext.segmentCodec === 'ac3') { + config = Dolby.getAudioConfig(this.observer, data, offset, this.logger); + } + else if (audioContext.segmentCodec === 'ec3') { + config = DDPlus$1.getAudioConfig(this.observer, data, offset, this.logger); + } + if (!config) { + throw 'unable to parse dolby header'; + } + audioContext.config = config; + } + if (audioContext.config.segmentCodec !== 'ac3' && audioContext.config.segmentCodec !== 'ec3') { + throw 'unexpected config type'; + } + const frameDuration = (1536 / audioContext.config.samplerate) * audioContext.info.inputTimescale; + if (audioOverFlow) { + const tmp = new Uint8Array(audioOverFlow.byteLength + data.byteLength); + tmp.set(audioOverFlow, 0); + tmp.set(data, audioOverFlow.byteLength); + data = tmp; + } + const length = data.length; + if (audioOverFlow && audioLastPTS) { + const newPTS = audioLastPTS + frameDuration; + if (Math.abs(newPTS - pts) > 1) { + pts = newPTS; + } + } + let frameLength = 0; + while (offset + frameLength <= length) { + if (data[offset] !== 11 || data[offset + 1] !== 119) { + const payload = new FragParsingError(true, 'invalid dolby audio magic', ErrorResponses.InvalidDolbyAudioMagic); + this.observer.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return; + } + if (audioContext.segmentCodec === 'ac3') { + frameLength = Dolby.getFrameLength(this.observer, data, offset); + } + else if (audioContext.segmentCodec === 'ec3') { + frameLength = DDPlus$1.getFrameLength(this.observer, data, offset, this.logger); + } + const stamp = pts + frameIndex * frameDuration; + audioContext.audioLastPTS = stamp; + const dolbySample = { unit: data.subarray(offset, offset + frameLength), pts: stamp, dts: stamp, keyTagInfo: keyTagInfo }; + audioContext.parsingData.esSamples.push(dolbySample); + audioContext.info.duration = this._duration; + audioContext.parsingData.len += frameLength; + offset += frameLength; + frameIndex++; + } + if (offset < length) { + audioOverFlow = data.subarray(offset, length); + } + else { + audioOverFlow = undefined; + } + audioContext.audioOverFlow = audioOverFlow; + } + } + var TsDemuxer$1 = TsDemuxer; + + + class DemuxerInline extends Observer { + constructor(typeSupported, config, vendor, logger) { + super(); + this.typeSupported = typeSupported; + this.config = config; + this.vendor = vendor; + this.logger = logger; + } + destroy() { + this.removeAllListeners(); + const demuxer = this.demuxer; + const remuxer = this.remuxer; + if (demuxer) { + demuxer.destroy(); + } + if (remuxer) { + remuxer.destroy(); + } + } + push(data, keyTagInfo, initSegment, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS, iframeMediaStart, iframeDuration) { + if (!data) { + // if data is undefined and this.probeFn exists, + // all the demuxers will fail probing. We will still end up with the old probeFn. + // We will push Uint8Array(undefined) to the demuxer that owns this.probeFn, which will be fatal + return; + } + let demuxer = this.demuxer; + const _data = new Uint8Array(data); + if (!demuxer || + // in case of continuity change, we might switch from content type (AAC container to TS container for example). this is signaled through the discontinuity argument. + // also a variant switch can also change the content type (TS container to fMP4 contaner for example). this is signaled through the trackSwitch argument. + // so let's check that current demuxer is still valid + ((discontinuity || trackSwitch) && !this.probeFn(_data, this.logger))) { + const { typeSupported, config } = this; + const muxConfig = [ + { demux: MP4Demuxer, remux: MP4EncryptionRemuxer }, + { demux: TsDemuxer$1, remux: EsRemuxer }, + { demux: EC3Demuxer, remux: EsRemuxer }, + { demux: AC3Demuxer, remux: EsRemuxer }, + { demux: AACDemuxer, remux: EsRemuxer }, + { demux: MP3Demuxer, remux: EsRemuxer }, + ]; // move MP3Demuxer to last to avoid false positive mp3 detection. + // probe for content type + for (const mux of muxConfig) { + const { probe } = mux.demux; + if (probe(_data, this.logger)) { + this.remuxer = new mux.remux(this, config, typeSupported, this.vendor, this.logger); + demuxer = new mux.demux(this, this.remuxer, config, typeSupported, this.logger); + this.probeFn = probe; + break; + } + } + if (!demuxer) { + const payload = new FragParsingError(true, 'no demux matching with content found', ErrorResponses.DemuxerNotFound); + this.trigger(HlsEvent$1.INTERNAL_ERROR, payload); + return; + } + this.demuxer = demuxer; + } + const remuxer = this.remuxer; + const keyChange = !this.lastKeyTagInfo || (keyTagInfo && keyTagInfo.method !== 'NONE' && this.lastKeyTagInfo.uri !== keyTagInfo.uri); + this.lastKeyTagInfo = keyTagInfo; + if (discontinuity || trackSwitch || keyChange) { + // resetInitSegment error handling may need to know if we are in a discontinuity or track switch + demuxer.resetInitSegment(new Uint8Array(initSegment), duration, keyTagInfo, discontinuity); + remuxer.resetInitSegment(); + } + if (discontinuity) { + const pts = defaultInitPTS ? convertTimestampToSeconds(defaultInitPTS) : undefined; + demuxer.resetTimeStamp(pts); + remuxer.resetTimeStamp(pts); + } + demuxer.append(_data, timeOffset, contiguous, accurateTimeOffset, keyTagInfo, iframeMediaStart, iframeDuration); + } + } + + function generateUniqueID() { + let id = `${Date.now()}-${Math.random()}`; + if (typeof performance !== 'undefined' && typeof performance.now === 'function') { + id += `-${performance.now()}`; + } + return id; + } + + class DemuxRPCServer { + constructor(rpc, logger) { + this.rpc = rpc; + this.logger = logger; + this.init = (typeSupported, config, vendor) => callback => { + const demuxSessionID = generateUniqueID(); + const demuxer = (this.demuxers[demuxSessionID] = new DemuxerInline(typeSupported, config, vendor, this.logger)); + [ + DemuxerEvent.INIT_PTS_FOUND, + DemuxerEvent.FRAG_PARSING_INIT_SEGMENT, + DemuxerEvent.FRAG_PARSING_DATA, + DemuxerEvent.FRAG_PARSED, + HlsEvent$1.INTERNAL_ERROR + ].forEach(event => { + demuxer.on(event, (data) => this.rpc.invoke('demuxer.event', [demuxSessionID, event, data])(() => { })); + }); + callback(demuxSessionID); + }; + this.push = (id, data, keyTagInfo, initSegment, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS, iframeMediaStart, iframeDuration) => callback => { + const demuxer = this.demuxers[id]; + if (!demuxer) { + callback(undefined, `Demuxer with id "${id}" does not exist on push`); + return; + } + demuxer.push(data, keyTagInfo, initSegment, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS, iframeMediaStart, iframeDuration); + callback(); + }; + this.destroy = (id) => callback => { + const demuxer = this.demuxers[id]; + if (!demuxer) { + this.logger.error(`Demuxer with id "${id}" does not exist on destroy`); + return; + } + demuxer.destroy(); + delete this.demuxers[id]; + callback(); + }; + this.demuxers = {}; + rpc.register('demuxer.init', this.init); + rpc.register('demuxer.push', this.push); + rpc.register('demuxer.destroy', this.destroy); + } + } + + // RPCWorkerService has client and server counterparts, where the service server + // runs in a Web Worker process, while the client remains in the main process. + class RPCWorkerService { + constructor(worker) { + this.worker = worker; + this.handlers = {}; + this.deferers = {}; + this._messageHandler = (event) => { + const { type, id, command, args, result, error } = event.data; + if (type === RPCWorkerMessageType.Invoke) { + try { + if (this.handlers[command] == null) { + throw new Error(`command ${command} not found`); + } + this.handlers[command](...args)(this._respond.bind(this, id, command)); + } + catch (error) { + this._respond(id, command, null, new Error(`command ${command} not found`)); + } + } + else if (type === RPCWorkerMessageType.Result) { + if (this.deferers[id] == null) { + return; + } + this.deferers[id](result, error); + delete this.deferers[id]; + } + }; + worker.addEventListener('message', this._messageHandler); + } + register(command, handler) { + if (this.handlers[command] != null) { + return false; + } + this.handlers[command] = handler; + } + unregister(command) { + if (this.handlers[command] != null) { + return false; + } + delete this.handlers[command]; + } + invoke(command, args, transfer) { + return (callback = RPCWorkerService._fallbackCallback) => { + const id = generateUniqueID(); + this.deferers[id] = callback; + const message = { + type: RPCWorkerMessageType.Invoke, + id, + command, + args, + }; + this._send(message, transfer); + }; + } + teardown(done) { + this.worker.removeEventListener('message', this._messageHandler); + done(); + } + _respond(id, command, result, error, transfer) { + if (error instanceof Error) { + error = `[${error.name}] ${error.message}\n${error.stack}`; + } + const message = { + type: RPCWorkerMessageType.Result, + id, + command, + result, + error, + }; + this._send(message, transfer); + } + _send(message, transfer = []) { + this.worker.postMessage(message, transfer.map((value) => (ArrayBuffer.isView(value) ? value.buffer : value)).filter((value) => value !== undefined)); + } + } + RPCWorkerService._fallbackCallback = (result, error) => { + if (error != null) { + throw error; + } + }; + var RPCWorkerMessageType; + (function (RPCWorkerMessageType) { + RPCWorkerMessageType[RPCWorkerMessageType["Invoke"] = 0] = "Invoke"; + RPCWorkerMessageType[RPCWorkerMessageType["Result"] = 1] = "Result"; + })(RPCWorkerMessageType || (RPCWorkerMessageType = {})); + // Minimal polyfill + // ArrayBuffer.isView() is relatively new + // https://caniuse.com/?search=arraybuffer + if (!ArrayBuffer['isView']) { + ArrayBuffer.isView = function isView(a) { + return a !== null && typeof a === 'object' && a['buffer'] instanceof ArrayBuffer; + }; + } + + const startWorker = () => { + const ctx = global$1; + const rpcService = new RPCWorkerService(ctx); + const logger = LoggerRPCClient(rpcService); + new CryptoRPCServer(rpcService, logger); + new DemuxRPCServer(rpcService, logger); + logger.info('WebWorker RPCService has started'); + }; + + if (hasUMDWorker() && typeof __IN_WORKER__ !== 'undefined' && __IN_WORKER__) { + startWorker(); + } + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + + function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function __decorate$2(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + } + + function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + } + + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + } + + /** @deprecated */ + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function isFunction$1(x) { + return typeof x === 'function'; + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var _enable_super_gross_mode_that_will_cause_bad_things = false; + var config = { + Promise: undefined, + set useDeprecatedSynchronousErrorHandling(value) { + _enable_super_gross_mode_that_will_cause_bad_things = value; + }, + get useDeprecatedSynchronousErrorHandling() { + return _enable_super_gross_mode_that_will_cause_bad_things; + }, + }; + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function hostReportError(err) { + setTimeout(function () { throw err; }, 0); + } + + /** PURE_IMPORTS_START _config,_util_hostReportError PURE_IMPORTS_END */ + var empty$1 = { + closed: true, + next: function (value) { }, + error: function (err) { + if (config.useDeprecatedSynchronousErrorHandling) { + throw err; + } + else { + hostReportError(err); + } + }, + complete: function () { } + }; + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var isArray$1 = /*@__PURE__*/ (function () { return Array.isArray || (function (x) { return x && typeof x.length === 'number'; }); })(); + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function isObject$1(x) { + return x !== null && typeof x === 'object'; + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var UnsubscriptionErrorImpl = /*@__PURE__*/ (function () { + function UnsubscriptionErrorImpl(errors) { + Error.call(this); + this.message = errors ? + errors.length + " errors occurred during unsubscription:\n" + errors.map(function (err, i) { return i + 1 + ") " + err.toString(); }).join('\n ') : ''; + this.name = 'UnsubscriptionError'; + this.errors = errors; + return this; + } + UnsubscriptionErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return UnsubscriptionErrorImpl; + })(); + var UnsubscriptionError = UnsubscriptionErrorImpl; + + /** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_UnsubscriptionError PURE_IMPORTS_END */ + var Subscription = /*@__PURE__*/ (function () { + function Subscription(unsubscribe) { + this.closed = false; + this._parentOrParents = null; + this._subscriptions = null; + if (unsubscribe) { + this._ctorUnsubscribe = true; + this._unsubscribe = unsubscribe; + } + } + Subscription.prototype.unsubscribe = function () { + var errors; + if (this.closed) { + return; + } + var _a = this, _parentOrParents = _a._parentOrParents, _ctorUnsubscribe = _a._ctorUnsubscribe, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; + this.closed = true; + this._parentOrParents = null; + this._subscriptions = null; + if (_parentOrParents instanceof Subscription) { + _parentOrParents.remove(this); + } + else if (_parentOrParents !== null) { + for (var index = 0; index < _parentOrParents.length; ++index) { + var parent_1 = _parentOrParents[index]; + parent_1.remove(this); + } + } + if (isFunction$1(_unsubscribe)) { + if (_ctorUnsubscribe) { + this._unsubscribe = undefined; + } + try { + _unsubscribe.call(this); + } + catch (e) { + errors = e instanceof UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e]; + } + } + if (isArray$1(_subscriptions)) { + var index = -1; + var len = _subscriptions.length; + while (++index < len) { + var sub = _subscriptions[index]; + if (isObject$1(sub)) { + try { + sub.unsubscribe(); + } + catch (e) { + errors = errors || []; + if (e instanceof UnsubscriptionError) { + errors = errors.concat(flattenUnsubscriptionErrors(e.errors)); + } + else { + errors.push(e); + } + } + } + } + } + if (errors) { + throw new UnsubscriptionError(errors); + } + }; + Subscription.prototype.add = function (teardown) { + var subscription = teardown; + if (!teardown) { + return Subscription.EMPTY; + } + switch (typeof teardown) { + case 'function': + subscription = new Subscription(teardown); + case 'object': + if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') { + return subscription; + } + else if (this.closed) { + subscription.unsubscribe(); + return subscription; + } + else if (!(subscription instanceof Subscription)) { + var tmp = subscription; + subscription = new Subscription(); + subscription._subscriptions = [tmp]; + } + break; + default: { + throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); + } + } + var _parentOrParents = subscription._parentOrParents; + if (_parentOrParents === null) { + subscription._parentOrParents = this; + } + else if (_parentOrParents instanceof Subscription) { + if (_parentOrParents === this) { + return subscription; + } + subscription._parentOrParents = [_parentOrParents, this]; + } + else if (_parentOrParents.indexOf(this) === -1) { + _parentOrParents.push(this); + } + else { + return subscription; + } + var subscriptions = this._subscriptions; + if (subscriptions === null) { + this._subscriptions = [subscription]; + } + else { + subscriptions.push(subscription); + } + return subscription; + }; + Subscription.prototype.remove = function (subscription) { + var subscriptions = this._subscriptions; + if (subscriptions) { + var subscriptionIndex = subscriptions.indexOf(subscription); + if (subscriptionIndex !== -1) { + subscriptions.splice(subscriptionIndex, 1); + } + } + }; + Subscription.EMPTY = (function (empty) { + empty.closed = true; + return empty; + }(new Subscription())); + return Subscription; + }()); + function flattenUnsubscriptionErrors(errors) { + return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError) ? err.errors : err); }, []); + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var rxSubscriber = /*@__PURE__*/ (function () { + return typeof Symbol === 'function' + ? /*@__PURE__*/ Symbol('rxSubscriber') + : '@@rxSubscriber_' + /*@__PURE__*/ Math.random(); + })(); + + /** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ + var Subscriber = /*@__PURE__*/ (function (_super) { + __extends(Subscriber, _super); + function Subscriber(destinationOrNext, error, complete) { + var _this = _super.call(this) || this; + _this.syncErrorValue = null; + _this.syncErrorThrown = false; + _this.syncErrorThrowable = false; + _this.isStopped = false; + switch (arguments.length) { + case 0: + _this.destination = empty$1; + break; + case 1: + if (!destinationOrNext) { + _this.destination = empty$1; + break; + } + if (typeof destinationOrNext === 'object') { + if (destinationOrNext instanceof Subscriber) { + _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; + _this.destination = destinationOrNext; + destinationOrNext.add(_this); + } + else { + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext); + } + break; + } + default: + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); + break; + } + return _this; + } + Subscriber.prototype[rxSubscriber] = function () { return this; }; + Subscriber.create = function (next, error, complete) { + var subscriber = new Subscriber(next, error, complete); + subscriber.syncErrorThrowable = false; + return subscriber; + }; + Subscriber.prototype.next = function (value) { + if (!this.isStopped) { + this._next(value); + } + }; + Subscriber.prototype.error = function (err) { + if (!this.isStopped) { + this.isStopped = true; + this._error(err); + } + }; + Subscriber.prototype.complete = function () { + if (!this.isStopped) { + this.isStopped = true; + this._complete(); + } + }; + Subscriber.prototype.unsubscribe = function () { + if (this.closed) { + return; + } + this.isStopped = true; + _super.prototype.unsubscribe.call(this); + }; + Subscriber.prototype._next = function (value) { + this.destination.next(value); + }; + Subscriber.prototype._error = function (err) { + this.destination.error(err); + this.unsubscribe(); + }; + Subscriber.prototype._complete = function () { + this.destination.complete(); + this.unsubscribe(); + }; + Subscriber.prototype._unsubscribeAndRecycle = function () { + var _parentOrParents = this._parentOrParents; + this._parentOrParents = null; + this.unsubscribe(); + this.closed = false; + this.isStopped = false; + this._parentOrParents = _parentOrParents; + return this; + }; + return Subscriber; + }(Subscription)); + var SafeSubscriber = /*@__PURE__*/ (function (_super) { + __extends(SafeSubscriber, _super); + function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { + var _this = _super.call(this) || this; + _this._parentSubscriber = _parentSubscriber; + var next; + var context = _this; + if (isFunction$1(observerOrNext)) { + next = observerOrNext; + } + else if (observerOrNext) { + next = observerOrNext.next; + error = observerOrNext.error; + complete = observerOrNext.complete; + if (observerOrNext !== empty$1) { + context = Object.create(observerOrNext); + if (isFunction$1(context.unsubscribe)) { + _this.add(context.unsubscribe.bind(context)); + } + context.unsubscribe = _this.unsubscribe.bind(_this); + } + } + _this._context = context; + _this._next = next; + _this._error = error; + _this._complete = complete; + return _this; + } + SafeSubscriber.prototype.next = function (value) { + if (!this.isStopped && this._next) { + var _parentSubscriber = this._parentSubscriber; + if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._next, value); + } + else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + var useDeprecatedSynchronousErrorHandling = config.useDeprecatedSynchronousErrorHandling; + if (this._error) { + if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._error, err); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, this._error, err); + this.unsubscribe(); + } + } + else if (!_parentSubscriber.syncErrorThrowable) { + this.unsubscribe(); + if (useDeprecatedSynchronousErrorHandling) { + throw err; + } + hostReportError(err); + } + else { + if (useDeprecatedSynchronousErrorHandling) { + _parentSubscriber.syncErrorValue = err; + _parentSubscriber.syncErrorThrown = true; + } + else { + hostReportError(err); + } + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.complete = function () { + var _this = this; + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + if (this._complete) { + var wrappedComplete = function () { return _this._complete.call(_this._context); }; + if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(wrappedComplete); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, wrappedComplete); + this.unsubscribe(); + } + } + else { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { + try { + fn.call(this._context, value); + } + catch (err) { + this.unsubscribe(); + if (config.useDeprecatedSynchronousErrorHandling) { + throw err; + } + else { + hostReportError(err); + } + } + }; + SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { + if (!config.useDeprecatedSynchronousErrorHandling) { + throw new Error('bad call'); + } + try { + fn.call(this._context, value); + } + catch (err) { + if (config.useDeprecatedSynchronousErrorHandling) { + parent.syncErrorValue = err; + parent.syncErrorThrown = true; + return true; + } + else { + hostReportError(err); + return true; + } + } + return false; + }; + SafeSubscriber.prototype._unsubscribe = function () { + var _parentSubscriber = this._parentSubscriber; + this._context = null; + this._parentSubscriber = null; + _parentSubscriber.unsubscribe(); + }; + return SafeSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START _Subscriber PURE_IMPORTS_END */ + function canReportError(observer) { + while (observer) { + var _a = observer, closed_1 = _a.closed, destination = _a.destination, isStopped = _a.isStopped; + if (closed_1 || isStopped) { + return false; + } + else if (destination && destination instanceof Subscriber) { + observer = destination; + } + else { + observer = null; + } + } + return true; + } + + /** PURE_IMPORTS_START _Subscriber,_symbol_rxSubscriber,_Observer PURE_IMPORTS_END */ + function toSubscriber(nextOrObserver, error, complete) { + if (nextOrObserver) { + if (nextOrObserver instanceof Subscriber) { + return nextOrObserver; + } + if (nextOrObserver[rxSubscriber]) { + return nextOrObserver[rxSubscriber](); + } + } + if (!nextOrObserver && !error && !complete) { + return new Subscriber(empty$1); + } + return new Subscriber(nextOrObserver, error, complete); + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var observable = /*@__PURE__*/ (function () { return typeof Symbol === 'function' && Symbol.observable || '@@observable'; })(); + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function identity(x) { + return x; + } + + /** PURE_IMPORTS_START _identity PURE_IMPORTS_END */ + function pipe() { + var fns = []; + for (var _i = 0; _i < arguments.length; _i++) { + fns[_i] = arguments[_i]; + } + return pipeFromArray(fns); + } + function pipeFromArray(fns) { + if (fns.length === 0) { + return identity; + } + if (fns.length === 1) { + return fns[0]; + } + return function piped(input) { + return fns.reduce(function (prev, fn) { return fn(prev); }, input); + }; + } + + /** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ + var Observable = /*@__PURE__*/ (function () { + function Observable(subscribe) { + this._isScalar = false; + if (subscribe) { + this._subscribe = subscribe; + } + } + Observable.prototype.lift = function (operator) { + var observable = new Observable(); + observable.source = this; + observable.operator = operator; + return observable; + }; + Observable.prototype.subscribe = function (observerOrNext, error, complete) { + var operator = this.operator; + var sink = toSubscriber(observerOrNext, error, complete); + if (operator) { + sink.add(operator.call(sink, this.source)); + } + else { + sink.add(this.source || (config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? + this._subscribe(sink) : + this._trySubscribe(sink)); + } + if (config.useDeprecatedSynchronousErrorHandling) { + if (sink.syncErrorThrowable) { + sink.syncErrorThrowable = false; + if (sink.syncErrorThrown) { + throw sink.syncErrorValue; + } + } + } + return sink; + }; + Observable.prototype._trySubscribe = function (sink) { + try { + return this._subscribe(sink); + } + catch (err) { + if (config.useDeprecatedSynchronousErrorHandling) { + sink.syncErrorThrown = true; + sink.syncErrorValue = err; + } + if (canReportError(sink)) { + sink.error(err); + } + else { + console.warn(err); + } + } + }; + Observable.prototype.forEach = function (next, promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function (resolve, reject) { + var subscription; + subscription = _this.subscribe(function (value) { + try { + next(value); + } + catch (err) { + reject(err); + if (subscription) { + subscription.unsubscribe(); + } + } + }, reject, resolve); + }); + }; + Observable.prototype._subscribe = function (subscriber) { + var source = this.source; + return source && source.subscribe(subscriber); + }; + Observable.prototype[observable] = function () { + return this; + }; + Observable.prototype.pipe = function () { + var operations = []; + for (var _i = 0; _i < arguments.length; _i++) { + operations[_i] = arguments[_i]; + } + if (operations.length === 0) { + return this; + } + return pipeFromArray(operations)(this); + }; + Observable.prototype.toPromise = function (promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function (resolve, reject) { + var value; + _this.subscribe(function (x) { return value = x; }, function (err) { return reject(err); }, function () { return resolve(value); }); + }); + }; + Observable.create = function (subscribe) { + return new Observable(subscribe); + }; + return Observable; + }()); + function getPromiseCtor(promiseCtor) { + if (!promiseCtor) { + promiseCtor = config.Promise || Promise; + } + if (!promiseCtor) { + throw new Error('no Promise impl found'); + } + return promiseCtor; + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var ObjectUnsubscribedErrorImpl = /*@__PURE__*/ (function () { + function ObjectUnsubscribedErrorImpl() { + Error.call(this); + this.message = 'object unsubscribed'; + this.name = 'ObjectUnsubscribedError'; + return this; + } + ObjectUnsubscribedErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return ObjectUnsubscribedErrorImpl; + })(); + var ObjectUnsubscribedError = ObjectUnsubscribedErrorImpl; + + /** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ + var SubjectSubscription = /*@__PURE__*/ (function (_super) { + __extends(SubjectSubscription, _super); + function SubjectSubscription(subject, subscriber) { + var _this = _super.call(this) || this; + _this.subject = subject; + _this.subscriber = subscriber; + _this.closed = false; + return _this; + } + SubjectSubscription.prototype.unsubscribe = function () { + if (this.closed) { + return; + } + this.closed = true; + var subject = this.subject; + var observers = subject.observers; + this.subject = null; + if (!observers || observers.length === 0 || subject.isStopped || subject.closed) { + return; + } + var subscriberIndex = observers.indexOf(this.subscriber); + if (subscriberIndex !== -1) { + observers.splice(subscriberIndex, 1); + } + }; + return SubjectSubscription; + }(Subscription)); + + /** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ + var SubjectSubscriber = /*@__PURE__*/ (function (_super) { + __extends(SubjectSubscriber, _super); + function SubjectSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + return _this; + } + return SubjectSubscriber; + }(Subscriber)); + var Subject = /*@__PURE__*/ (function (_super) { + __extends(Subject, _super); + function Subject() { + var _this = _super.call(this) || this; + _this.observers = []; + _this.closed = false; + _this.isStopped = false; + _this.hasError = false; + _this.thrownError = null; + return _this; + } + Subject.prototype[rxSubscriber] = function () { + return new SubjectSubscriber(this); + }; + Subject.prototype.lift = function (operator) { + var subject = new AnonymousSubject(this, this); + subject.operator = operator; + return subject; + }; + Subject.prototype.next = function (value) { + if (this.closed) { + throw new ObjectUnsubscribedError(); + } + if (!this.isStopped) { + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].next(value); + } + } + }; + Subject.prototype.error = function (err) { + if (this.closed) { + throw new ObjectUnsubscribedError(); + } + this.hasError = true; + this.thrownError = err; + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].error(err); + } + this.observers.length = 0; + }; + Subject.prototype.complete = function () { + if (this.closed) { + throw new ObjectUnsubscribedError(); + } + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].complete(); + } + this.observers.length = 0; + }; + Subject.prototype.unsubscribe = function () { + this.isStopped = true; + this.closed = true; + this.observers = null; + }; + Subject.prototype._trySubscribe = function (subscriber) { + if (this.closed) { + throw new ObjectUnsubscribedError(); + } + else { + return _super.prototype._trySubscribe.call(this, subscriber); + } + }; + Subject.prototype._subscribe = function (subscriber) { + if (this.closed) { + throw new ObjectUnsubscribedError(); + } + else if (this.hasError) { + subscriber.error(this.thrownError); + return Subscription.EMPTY; + } + else if (this.isStopped) { + subscriber.complete(); + return Subscription.EMPTY; + } + else { + this.observers.push(subscriber); + return new SubjectSubscription(this, subscriber); + } + }; + Subject.prototype.asObservable = function () { + var observable = new Observable(); + observable.source = this; + return observable; + }; + Subject.create = function (destination, source) { + return new AnonymousSubject(destination, source); + }; + return Subject; + }(Observable)); + var AnonymousSubject = /*@__PURE__*/ (function (_super) { + __extends(AnonymousSubject, _super); + function AnonymousSubject(destination, source) { + var _this = _super.call(this) || this; + _this.destination = destination; + _this.source = source; + return _this; + } + AnonymousSubject.prototype.next = function (value) { + var destination = this.destination; + if (destination && destination.next) { + destination.next(value); + } + }; + AnonymousSubject.prototype.error = function (err) { + var destination = this.destination; + if (destination && destination.error) { + this.destination.error(err); + } + }; + AnonymousSubject.prototype.complete = function () { + var destination = this.destination; + if (destination && destination.complete) { + this.destination.complete(); + } + }; + AnonymousSubject.prototype._subscribe = function (subscriber) { + var source = this.source; + if (source) { + return this.source.subscribe(subscriber); + } + else { + return Subscription.EMPTY; + } + }; + return AnonymousSubject; + }(Subject)); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function refCount() { + return function refCountOperatorFunction(source) { + return source.lift(new RefCountOperator(source)); + }; + } + var RefCountOperator = /*@__PURE__*/ (function () { + function RefCountOperator(connectable) { + this.connectable = connectable; + } + RefCountOperator.prototype.call = function (subscriber, source) { + var connectable = this.connectable; + connectable._refCount++; + var refCounter = new RefCountSubscriber(subscriber, connectable); + var subscription = source.subscribe(refCounter); + if (!refCounter.closed) { + refCounter.connection = connectable.connect(); + } + return subscription; + }; + return RefCountOperator; + }()); + var RefCountSubscriber = /*@__PURE__*/ (function (_super) { + __extends(RefCountSubscriber, _super); + function RefCountSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; + } + RefCountSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (!connectable) { + this.connection = null; + return; + } + this.connectable = null; + var refCount = connectable._refCount; + if (refCount <= 0) { + this.connection = null; + return; + } + connectable._refCount = refCount - 1; + if (refCount > 1) { + this.connection = null; + return; + } + var connection = this.connection; + var sharedConnection = connectable._connection; + this.connection = null; + if (sharedConnection && (!connection || sharedConnection === connection)) { + sharedConnection.unsubscribe(); + } + }; + return RefCountSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subject,_Observable,_Subscriber,_Subscription,_operators_refCount PURE_IMPORTS_END */ + var ConnectableObservable = /*@__PURE__*/ (function (_super) { + __extends(ConnectableObservable, _super); + function ConnectableObservable(source, subjectFactory) { + var _this = _super.call(this) || this; + _this.source = source; + _this.subjectFactory = subjectFactory; + _this._refCount = 0; + _this._isComplete = false; + return _this; + } + ConnectableObservable.prototype._subscribe = function (subscriber) { + return this.getSubject().subscribe(subscriber); + }; + ConnectableObservable.prototype.getSubject = function () { + var subject = this._subject; + if (!subject || subject.isStopped) { + this._subject = this.subjectFactory(); + } + return this._subject; + }; + ConnectableObservable.prototype.connect = function () { + var connection = this._connection; + if (!connection) { + this._isComplete = false; + connection = this._connection = new Subscription(); + connection.add(this.source + .subscribe(new ConnectableSubscriber(this.getSubject(), this))); + if (connection.closed) { + this._connection = null; + connection = Subscription.EMPTY; + } + } + return connection; + }; + ConnectableObservable.prototype.refCount = function () { + return refCount()(this); + }; + return ConnectableObservable; + }(Observable)); + var connectableObservableDescriptor = /*@__PURE__*/ (function () { + var connectableProto = ConnectableObservable.prototype; + return { + operator: { value: null }, + _refCount: { value: 0, writable: true }, + _subject: { value: null, writable: true }, + _connection: { value: null, writable: true }, + _subscribe: { value: connectableProto._subscribe }, + _isComplete: { value: connectableProto._isComplete, writable: true }, + getSubject: { value: connectableProto.getSubject }, + connect: { value: connectableProto.connect }, + refCount: { value: connectableProto.refCount } + }; + })(); + var ConnectableSubscriber = /*@__PURE__*/ (function (_super) { + __extends(ConnectableSubscriber, _super); + function ConnectableSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; + } + ConnectableSubscriber.prototype._error = function (err) { + this._unsubscribe(); + _super.prototype._error.call(this, err); + }; + ConnectableSubscriber.prototype._complete = function () { + this.connectable._isComplete = true; + this._unsubscribe(); + _super.prototype._complete.call(this); + }; + ConnectableSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (connectable) { + this.connectable = null; + var connection = connectable._connection; + connectable._refCount = 0; + connectable._subject = null; + connectable._connection = null; + if (connection) { + connection.unsubscribe(); + } + } + }; + return ConnectableSubscriber; + }(SubjectSubscriber)); + + /** PURE_IMPORTS_START tslib,_Subject,_util_ObjectUnsubscribedError PURE_IMPORTS_END */ + var BehaviorSubject = /*@__PURE__*/ (function (_super) { + __extends(BehaviorSubject, _super); + function BehaviorSubject(_value) { + var _this = _super.call(this) || this; + _this._value = _value; + return _this; + } + Object.defineProperty(BehaviorSubject.prototype, "value", { + get: function () { + return this.getValue(); + }, + enumerable: true, + configurable: true + }); + BehaviorSubject.prototype._subscribe = function (subscriber) { + var subscription = _super.prototype._subscribe.call(this, subscriber); + if (subscription && !subscription.closed) { + subscriber.next(this._value); + } + return subscription; + }; + BehaviorSubject.prototype.getValue = function () { + if (this.hasError) { + throw this.thrownError; + } + else if (this.closed) { + throw new ObjectUnsubscribedError(); + } + else { + return this._value; + } + }; + BehaviorSubject.prototype.next = function (value) { + _super.prototype.next.call(this, this._value = value); + }; + return BehaviorSubject; + }(Subject)); + + /** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ + var Action = /*@__PURE__*/ (function (_super) { + __extends(Action, _super); + function Action(scheduler, work) { + return _super.call(this) || this; + } + Action.prototype.schedule = function (state, delay) { + return this; + }; + return Action; + }(Subscription)); + + /** PURE_IMPORTS_START tslib,_Action PURE_IMPORTS_END */ + var AsyncAction = /*@__PURE__*/ (function (_super) { + __extends(AsyncAction, _super); + function AsyncAction(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + _this.pending = false; + return _this; + } + AsyncAction.prototype.schedule = function (state, delay) { + if (delay === void 0) { + delay = 0; + } + if (this.closed) { + return this; + } + this.state = state; + var id = this.id; + var scheduler = this.scheduler; + if (id != null) { + this.id = this.recycleAsyncId(scheduler, id, delay); + } + this.pending = true; + this.delay = delay; + this.id = this.id || this.requestAsyncId(scheduler, this.id, delay); + return this; + }; + AsyncAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + return setInterval(scheduler.flush.bind(scheduler, this), delay); + }; + AsyncAction.prototype.recycleAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if (delay !== null && this.delay === delay && this.pending === false) { + return id; + } + clearInterval(id); + return undefined; + }; + AsyncAction.prototype.execute = function (state, delay) { + if (this.closed) { + return new Error('executing a cancelled action'); + } + this.pending = false; + var error = this._execute(state, delay); + if (error) { + return error; + } + else if (this.pending === false && this.id != null) { + this.id = this.recycleAsyncId(this.scheduler, this.id, null); + } + }; + AsyncAction.prototype._execute = function (state, delay) { + var errored = false; + var errorValue = undefined; + try { + this.work(state); + } + catch (e) { + errored = true; + errorValue = !!e && e || new Error(e); + } + if (errored) { + this.unsubscribe(); + return errorValue; + } + }; + AsyncAction.prototype._unsubscribe = function () { + var id = this.id; + var scheduler = this.scheduler; + var actions = scheduler.actions; + var index = actions.indexOf(this); + this.work = null; + this.state = null; + this.pending = false; + this.scheduler = null; + if (index !== -1) { + actions.splice(index, 1); + } + if (id != null) { + this.id = this.recycleAsyncId(scheduler, id, null); + } + this.delay = null; + }; + return AsyncAction; + }(Action)); + + /** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ + var QueueAction = /*@__PURE__*/ (function (_super) { + __extends(QueueAction, _super); + function QueueAction(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + return _this; + } + QueueAction.prototype.schedule = function (state, delay) { + if (delay === void 0) { + delay = 0; + } + if (delay > 0) { + return _super.prototype.schedule.call(this, state, delay); + } + this.delay = delay; + this.state = state; + this.scheduler.flush(this); + return this; + }; + QueueAction.prototype.execute = function (state, delay) { + return (delay > 0 || this.closed) ? + _super.prototype.execute.call(this, state, delay) : + this._execute(state, delay); + }; + QueueAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { + return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); + } + return scheduler.flush(this); + }; + return QueueAction; + }(AsyncAction)); + + var Scheduler = /*@__PURE__*/ (function () { + function Scheduler(SchedulerAction, now) { + if (now === void 0) { + now = Scheduler.now; + } + this.SchedulerAction = SchedulerAction; + this.now = now; + } + Scheduler.prototype.schedule = function (work, delay, state) { + if (delay === void 0) { + delay = 0; + } + return new this.SchedulerAction(this, work).schedule(state, delay); + }; + Scheduler.now = function () { return Date.now(); }; + return Scheduler; + }()); + + /** PURE_IMPORTS_START tslib,_Scheduler PURE_IMPORTS_END */ + var AsyncScheduler = /*@__PURE__*/ (function (_super) { + __extends(AsyncScheduler, _super); + function AsyncScheduler(SchedulerAction, now) { + if (now === void 0) { + now = Scheduler.now; + } + var _this = _super.call(this, SchedulerAction, function () { + if (AsyncScheduler.delegate && AsyncScheduler.delegate !== _this) { + return AsyncScheduler.delegate.now(); + } + else { + return now(); + } + }) || this; + _this.actions = []; + _this.active = false; + _this.scheduled = undefined; + return _this; + } + AsyncScheduler.prototype.schedule = function (work, delay, state) { + if (delay === void 0) { + delay = 0; + } + if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) { + return AsyncScheduler.delegate.schedule(work, delay, state); + } + else { + return _super.prototype.schedule.call(this, work, delay, state); + } + }; + AsyncScheduler.prototype.flush = function (action) { + var actions = this.actions; + if (this.active) { + actions.push(action); + return; + } + var error; + this.active = true; + do { + if (error = action.execute(action.state, action.delay)) { + break; + } + } while (action = actions.shift()); + this.active = false; + if (error) { + while (action = actions.shift()) { + action.unsubscribe(); + } + throw error; + } + }; + return AsyncScheduler; + }(Scheduler)); + + /** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ + var QueueScheduler = /*@__PURE__*/ (function (_super) { + __extends(QueueScheduler, _super); + function QueueScheduler() { + return _super !== null && _super.apply(this, arguments) || this; + } + return QueueScheduler; + }(AsyncScheduler)); + + /** PURE_IMPORTS_START _QueueAction,_QueueScheduler PURE_IMPORTS_END */ + var queueScheduler = /*@__PURE__*/ new QueueScheduler(QueueAction); + var queue = queueScheduler; + + /** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + var EMPTY = /*@__PURE__*/ new Observable(function (subscriber) { return subscriber.complete(); }); + function empty(scheduler) { + return scheduler ? emptyScheduled(scheduler) : EMPTY; + } + function emptyScheduled(scheduler) { + return new Observable(function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); }); + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function isScheduler(value) { + return value && typeof value.schedule === 'function'; + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var subscribeToArray = function (array) { + return function (subscriber) { + for (var i = 0, len = array.length; i < len && !subscriber.closed; i++) { + subscriber.next(array[i]); + } + subscriber.complete(); + }; + }; + + /** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ + function scheduleArray(input, scheduler) { + return new Observable(function (subscriber) { + var sub = new Subscription(); + var i = 0; + sub.add(scheduler.schedule(function () { + if (i === input.length) { + subscriber.complete(); + return; + } + subscriber.next(input[i++]); + if (!subscriber.closed) { + sub.add(this.schedule()); + } + })); + return sub; + }); + } + + /** PURE_IMPORTS_START _Observable,_util_subscribeToArray,_scheduled_scheduleArray PURE_IMPORTS_END */ + function fromArray(input, scheduler) { + if (!scheduler) { + return new Observable(subscribeToArray(input)); + } + else { + return scheduleArray(input, scheduler); + } + } + + /** PURE_IMPORTS_START _util_isScheduler,_fromArray,_scheduled_scheduleArray PURE_IMPORTS_END */ + function of() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var scheduler = args[args.length - 1]; + if (isScheduler(scheduler)) { + args.pop(); + return scheduleArray(args, scheduler); + } + else { + return fromArray(args); + } + } + + /** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + function throwError(error, scheduler) { + if (!scheduler) { + return new Observable(function (subscriber) { return subscriber.error(error); }); + } + else { + return new Observable(function (subscriber) { return scheduler.schedule(dispatch$1, 0, { error: error, subscriber: subscriber }); }); + } + } + function dispatch$1(_a) { + var error = _a.error, subscriber = _a.subscriber; + subscriber.error(error); + } + + /** PURE_IMPORTS_START _observable_empty,_observable_of,_observable_throwError PURE_IMPORTS_END */ + var Notification = /*@__PURE__*/ (function () { + function Notification(kind, value, error) { + this.kind = kind; + this.value = value; + this.error = error; + this.hasValue = kind === 'N'; + } + Notification.prototype.observe = function (observer) { + switch (this.kind) { + case 'N': + return observer.next && observer.next(this.value); + case 'E': + return observer.error && observer.error(this.error); + case 'C': + return observer.complete && observer.complete(); + } + }; + Notification.prototype.do = function (next, error, complete) { + var kind = this.kind; + switch (kind) { + case 'N': + return next && next(this.value); + case 'E': + return error && error(this.error); + case 'C': + return complete && complete(); + } + }; + Notification.prototype.accept = function (nextOrObserver, error, complete) { + if (nextOrObserver && typeof nextOrObserver.next === 'function') { + return this.observe(nextOrObserver); + } + else { + return this.do(nextOrObserver, error, complete); + } + }; + Notification.prototype.toObservable = function () { + var kind = this.kind; + switch (kind) { + case 'N': + return of(this.value); + case 'E': + return throwError(this.error); + case 'C': + return empty(); + } + throw new Error('unexpected notification kind value'); + }; + Notification.createNext = function (value) { + if (typeof value !== 'undefined') { + return new Notification('N', value); + } + return Notification.undefinedValueNotification; + }; + Notification.createError = function (err) { + return new Notification('E', undefined, err); + }; + Notification.createComplete = function () { + return Notification.completeNotification; + }; + Notification.completeNotification = new Notification('C'); + Notification.undefinedValueNotification = new Notification('N', undefined); + return Notification; + }()); + + /** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ + function observeOn(scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + return function observeOnOperatorFunction(source) { + return source.lift(new ObserveOnOperator(scheduler, delay)); + }; + } + var ObserveOnOperator = /*@__PURE__*/ (function () { + function ObserveOnOperator(scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + this.scheduler = scheduler; + this.delay = delay; + } + ObserveOnOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ObserveOnSubscriber(subscriber, this.scheduler, this.delay)); + }; + return ObserveOnOperator; + }()); + var ObserveOnSubscriber = /*@__PURE__*/ (function (_super) { + __extends(ObserveOnSubscriber, _super); + function ObserveOnSubscriber(destination, scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + var _this = _super.call(this, destination) || this; + _this.scheduler = scheduler; + _this.delay = delay; + return _this; + } + ObserveOnSubscriber.dispatch = function (arg) { + var notification = arg.notification, destination = arg.destination; + notification.observe(destination); + this.unsubscribe(); + }; + ObserveOnSubscriber.prototype.scheduleMessage = function (notification) { + var destination = this.destination; + destination.add(this.scheduler.schedule(ObserveOnSubscriber.dispatch, this.delay, new ObserveOnMessage(notification, this.destination))); + }; + ObserveOnSubscriber.prototype._next = function (value) { + this.scheduleMessage(Notification.createNext(value)); + }; + ObserveOnSubscriber.prototype._error = function (err) { + this.scheduleMessage(Notification.createError(err)); + this.unsubscribe(); + }; + ObserveOnSubscriber.prototype._complete = function () { + this.scheduleMessage(Notification.createComplete()); + this.unsubscribe(); + }; + return ObserveOnSubscriber; + }(Subscriber)); + var ObserveOnMessage = /*@__PURE__*/ (function () { + function ObserveOnMessage(notification, destination) { + this.notification = notification; + this.destination = destination; + } + return ObserveOnMessage; + }()); + + /** PURE_IMPORTS_START tslib,_Subject,_scheduler_queue,_Subscription,_operators_observeOn,_util_ObjectUnsubscribedError,_SubjectSubscription PURE_IMPORTS_END */ + var ReplaySubject = /*@__PURE__*/ (function (_super) { + __extends(ReplaySubject, _super); + function ReplaySubject(bufferSize, windowTime, scheduler) { + if (bufferSize === void 0) { + bufferSize = Number.POSITIVE_INFINITY; + } + if (windowTime === void 0) { + windowTime = Number.POSITIVE_INFINITY; + } + var _this = _super.call(this) || this; + _this.scheduler = scheduler; + _this._events = []; + _this._infiniteTimeWindow = false; + _this._bufferSize = bufferSize < 1 ? 1 : bufferSize; + _this._windowTime = windowTime < 1 ? 1 : windowTime; + if (windowTime === Number.POSITIVE_INFINITY) { + _this._infiniteTimeWindow = true; + _this.next = _this.nextInfiniteTimeWindow; + } + else { + _this.next = _this.nextTimeWindow; + } + return _this; + } + ReplaySubject.prototype.nextInfiniteTimeWindow = function (value) { + if (!this.isStopped) { + var _events = this._events; + _events.push(value); + if (_events.length > this._bufferSize) { + _events.shift(); + } + } + _super.prototype.next.call(this, value); + }; + ReplaySubject.prototype.nextTimeWindow = function (value) { + if (!this.isStopped) { + this._events.push(new ReplayEvent(this._getNow(), value)); + this._trimBufferThenGetEvents(); + } + _super.prototype.next.call(this, value); + }; + ReplaySubject.prototype._subscribe = function (subscriber) { + var _infiniteTimeWindow = this._infiniteTimeWindow; + var _events = _infiniteTimeWindow ? this._events : this._trimBufferThenGetEvents(); + var scheduler = this.scheduler; + var len = _events.length; + var subscription; + if (this.closed) { + throw new ObjectUnsubscribedError(); + } + else if (this.isStopped || this.hasError) { + subscription = Subscription.EMPTY; + } + else { + this.observers.push(subscriber); + subscription = new SubjectSubscription(this, subscriber); + } + if (scheduler) { + subscriber.add(subscriber = new ObserveOnSubscriber(subscriber, scheduler)); + } + if (_infiniteTimeWindow) { + for (var i = 0; i < len && !subscriber.closed; i++) { + subscriber.next(_events[i]); + } + } + else { + for (var i = 0; i < len && !subscriber.closed; i++) { + subscriber.next(_events[i].value); + } + } + if (this.hasError) { + subscriber.error(this.thrownError); + } + else if (this.isStopped) { + subscriber.complete(); + } + return subscription; + }; + ReplaySubject.prototype._getNow = function () { + return (this.scheduler || queue).now(); + }; + ReplaySubject.prototype._trimBufferThenGetEvents = function () { + var now = this._getNow(); + var _bufferSize = this._bufferSize; + var _windowTime = this._windowTime; + var _events = this._events; + var eventsCount = _events.length; + var spliceCount = 0; + while (spliceCount < eventsCount) { + if ((now - _events[spliceCount].time) < _windowTime) { + break; + } + spliceCount++; + } + if (eventsCount > _bufferSize) { + spliceCount = Math.max(spliceCount, eventsCount - _bufferSize); + } + if (spliceCount > 0) { + _events.splice(0, spliceCount); + } + return _events; + }; + return ReplaySubject; + }(Subject)); + var ReplayEvent = /*@__PURE__*/ (function () { + function ReplayEvent(time, value) { + this.time = time; + this.value = value; + } + return ReplayEvent; + }()); + + /** PURE_IMPORTS_START tslib,_Subject,_Subscription PURE_IMPORTS_END */ + var AsyncSubject = /*@__PURE__*/ (function (_super) { + __extends(AsyncSubject, _super); + function AsyncSubject() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.value = null; + _this.hasNext = false; + _this.hasCompleted = false; + return _this; + } + AsyncSubject.prototype._subscribe = function (subscriber) { + if (this.hasError) { + subscriber.error(this.thrownError); + return Subscription.EMPTY; + } + else if (this.hasCompleted && this.hasNext) { + subscriber.next(this.value); + subscriber.complete(); + return Subscription.EMPTY; + } + return _super.prototype._subscribe.call(this, subscriber); + }; + AsyncSubject.prototype.next = function (value) { + if (!this.hasCompleted) { + this.value = value; + this.hasNext = true; + } + }; + AsyncSubject.prototype.error = function (error) { + if (!this.hasCompleted) { + _super.prototype.error.call(this, error); + } + }; + AsyncSubject.prototype.complete = function () { + this.hasCompleted = true; + if (this.hasNext) { + _super.prototype.next.call(this, this.value); + } + _super.prototype.complete.call(this); + }; + return AsyncSubject; + }(Subject)); + + /** PURE_IMPORTS_START _AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ + var asyncScheduler = /*@__PURE__*/ new AsyncScheduler(AsyncAction); + var async = asyncScheduler; + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function noop() { } + + /** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + function isObservable(obj) { + return !!obj && (obj instanceof Observable || (typeof obj.lift === 'function' && typeof obj.subscribe === 'function')); + } + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var ArgumentOutOfRangeErrorImpl = /*@__PURE__*/ (function () { + function ArgumentOutOfRangeErrorImpl() { + Error.call(this); + this.message = 'argument out of range'; + this.name = 'ArgumentOutOfRangeError'; + return this; + } + ArgumentOutOfRangeErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return ArgumentOutOfRangeErrorImpl; + })(); + var ArgumentOutOfRangeError = ArgumentOutOfRangeErrorImpl; + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var TimeoutErrorImpl = /*@__PURE__*/ (function () { + function TimeoutErrorImpl() { + Error.call(this); + this.message = 'Timeout has occurred'; + this.name = 'TimeoutError'; + return this; + } + TimeoutErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return TimeoutErrorImpl; + })(); + var TimeoutError = TimeoutErrorImpl; + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function map(project, thisArg) { + return function mapOperation(source) { + if (typeof project !== 'function') { + throw new TypeError('argument is not a function. Are you looking for `mapTo()`?'); + } + return source.lift(new MapOperator(project, thisArg)); + }; + } + var MapOperator = /*@__PURE__*/ (function () { + function MapOperator(project, thisArg) { + this.project = project; + this.thisArg = thisArg; + } + MapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg)); + }; + return MapOperator; + }()); + var MapSubscriber = /*@__PURE__*/ (function (_super) { + __extends(MapSubscriber, _super); + function MapSubscriber(destination, project, thisArg) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.count = 0; + _this.thisArg = thisArg || _this; + return _this; + } + MapSubscriber.prototype._next = function (value) { + var result; + try { + result = this.project.call(this.thisArg, value, this.count++); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return MapSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + var OuterSubscriber = /*@__PURE__*/ (function (_super) { + __extends(OuterSubscriber, _super); + function OuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(innerValue); + }; + OuterSubscriber.prototype.notifyError = function (error, innerSub) { + this.destination.error(error); + }; + OuterSubscriber.prototype.notifyComplete = function (innerSub) { + this.destination.complete(); + }; + return OuterSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + var InnerSubscriber = /*@__PURE__*/ (function (_super) { + __extends(InnerSubscriber, _super); + function InnerSubscriber(parent, outerValue, outerIndex) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.outerValue = outerValue; + _this.outerIndex = outerIndex; + _this.index = 0; + return _this; + } + InnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this); + }; + InnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error, this); + this.unsubscribe(); + }; + InnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(this); + this.unsubscribe(); + }; + return InnerSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START _hostReportError PURE_IMPORTS_END */ + var subscribeToPromise = function (promise) { + return function (subscriber) { + promise.then(function (value) { + if (!subscriber.closed) { + subscriber.next(value); + subscriber.complete(); + } + }, function (err) { return subscriber.error(err); }) + .then(null, hostReportError); + return subscriber; + }; + }; + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function getSymbolIterator() { + if (typeof Symbol !== 'function' || !Symbol.iterator) { + return '@@iterator'; + } + return Symbol.iterator; + } + var iterator = /*@__PURE__*/ getSymbolIterator(); + + /** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ + var subscribeToIterable = function (iterable) { + return function (subscriber) { + var iterator$1 = iterable[iterator](); + do { + var item = void 0; + try { + item = iterator$1.next(); + } + catch (err) { + subscriber.error(err); + return subscriber; + } + if (item.done) { + subscriber.complete(); + break; + } + subscriber.next(item.value); + if (subscriber.closed) { + break; + } + } while (true); + if (typeof iterator$1.return === 'function') { + subscriber.add(function () { + if (iterator$1.return) { + iterator$1.return(); + } + }); + } + return subscriber; + }; + }; + + /** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ + var subscribeToObservable = function (obj) { + return function (subscriber) { + var obs = obj[observable](); + if (typeof obs.subscribe !== 'function') { + throw new TypeError('Provided object does not correctly implement Symbol.observable'); + } + else { + return obs.subscribe(subscriber); + } + }; + }; + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; }); + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function isPromise(value) { + return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function'; + } + + /** PURE_IMPORTS_START _subscribeToArray,_subscribeToPromise,_subscribeToIterable,_subscribeToObservable,_isArrayLike,_isPromise,_isObject,_symbol_iterator,_symbol_observable PURE_IMPORTS_END */ + var subscribeTo = function (result) { + if (!!result && typeof result[observable] === 'function') { + return subscribeToObservable(result); + } + else if (isArrayLike(result)) { + return subscribeToArray(result); + } + else if (isPromise(result)) { + return subscribeToPromise(result); + } + else if (!!result && typeof result[iterator] === 'function') { + return subscribeToIterable(result); + } + else { + var value = isObject$1(result) ? 'an invalid object' : "'" + result + "'"; + var msg = "You provided " + value + " where a stream was expected." + + ' You can provide an Observable, Promise, Array, or Iterable.'; + throw new TypeError(msg); + } + }; + + /** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo,_Observable PURE_IMPORTS_END */ + function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, innerSubscriber) { + if (innerSubscriber === void 0) { + innerSubscriber = new InnerSubscriber(outerSubscriber, outerValue, outerIndex); + } + if (innerSubscriber.closed) { + return undefined; + } + if (result instanceof Observable) { + return result.subscribe(innerSubscriber); + } + return subscribeTo(result)(innerSubscriber); + } + + /** PURE_IMPORTS_START tslib,_util_isScheduler,_util_isArray,_OuterSubscriber,_util_subscribeToResult,_fromArray PURE_IMPORTS_END */ + var NONE = {}; + function combineLatest() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var resultSelector = undefined; + var scheduler = undefined; + if (isScheduler(observables[observables.length - 1])) { + scheduler = observables.pop(); + } + if (typeof observables[observables.length - 1] === 'function') { + resultSelector = observables.pop(); + } + if (observables.length === 1 && isArray$1(observables[0])) { + observables = observables[0]; + } + return fromArray(observables, scheduler).lift(new CombineLatestOperator(resultSelector)); + } + var CombineLatestOperator = /*@__PURE__*/ (function () { + function CombineLatestOperator(resultSelector) { + this.resultSelector = resultSelector; + } + CombineLatestOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CombineLatestSubscriber(subscriber, this.resultSelector)); + }; + return CombineLatestOperator; + }()); + var CombineLatestSubscriber = /*@__PURE__*/ (function (_super) { + __extends(CombineLatestSubscriber, _super); + function CombineLatestSubscriber(destination, resultSelector) { + var _this = _super.call(this, destination) || this; + _this.resultSelector = resultSelector; + _this.active = 0; + _this.values = []; + _this.observables = []; + return _this; + } + CombineLatestSubscriber.prototype._next = function (observable) { + this.values.push(NONE); + this.observables.push(observable); + }; + CombineLatestSubscriber.prototype._complete = function () { + var observables = this.observables; + var len = observables.length; + if (len === 0) { + this.destination.complete(); + } + else { + this.active = len; + this.toRespond = len; + for (var i = 0; i < len; i++) { + var observable = observables[i]; + this.add(subscribeToResult(this, observable, undefined, i)); + } + } + }; + CombineLatestSubscriber.prototype.notifyComplete = function (unused) { + if ((this.active -= 1) === 0) { + this.destination.complete(); + } + }; + CombineLatestSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { + var values = this.values; + var oldVal = values[outerIndex]; + var toRespond = !this.toRespond + ? 0 + : oldVal === NONE ? --this.toRespond : this.toRespond; + values[outerIndex] = innerValue; + if (toRespond === 0) { + if (this.resultSelector) { + this._tryResultSelector(values); + } + else { + this.destination.next(values.slice()); + } + } + }; + CombineLatestSubscriber.prototype._tryResultSelector = function (values) { + var result; + try { + result = this.resultSelector.apply(this, values); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return CombineLatestSubscriber; + }(OuterSubscriber)); + + /** PURE_IMPORTS_START _Observable,_Subscription,_symbol_observable PURE_IMPORTS_END */ + function scheduleObservable(input, scheduler) { + return new Observable(function (subscriber) { + var sub = new Subscription(); + sub.add(scheduler.schedule(function () { + var observable$1 = input[observable](); + sub.add(observable$1.subscribe({ + next: function (value) { sub.add(scheduler.schedule(function () { return subscriber.next(value); })); }, + error: function (err) { sub.add(scheduler.schedule(function () { return subscriber.error(err); })); }, + complete: function () { sub.add(scheduler.schedule(function () { return subscriber.complete(); })); }, + })); + })); + return sub; + }); + } + + /** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ + function schedulePromise(input, scheduler) { + return new Observable(function (subscriber) { + var sub = new Subscription(); + sub.add(scheduler.schedule(function () { + return input.then(function (value) { + sub.add(scheduler.schedule(function () { + subscriber.next(value); + sub.add(scheduler.schedule(function () { return subscriber.complete(); })); + })); + }, function (err) { + sub.add(scheduler.schedule(function () { return subscriber.error(err); })); + }); + })); + return sub; + }); + } + + /** PURE_IMPORTS_START _Observable,_Subscription,_symbol_iterator PURE_IMPORTS_END */ + function scheduleIterable(input, scheduler) { + if (!input) { + throw new Error('Iterable cannot be null'); + } + return new Observable(function (subscriber) { + var sub = new Subscription(); + var iterator$1; + sub.add(function () { + if (iterator$1 && typeof iterator$1.return === 'function') { + iterator$1.return(); + } + }); + sub.add(scheduler.schedule(function () { + iterator$1 = input[iterator](); + sub.add(scheduler.schedule(function () { + if (subscriber.closed) { + return; + } + var value; + var done; + try { + var result = iterator$1.next(); + value = result.value; + done = result.done; + } + catch (err) { + subscriber.error(err); + return; + } + if (done) { + subscriber.complete(); + } + else { + subscriber.next(value); + this.schedule(); + } + })); + })); + return sub; + }); + } + + /** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ + function isInteropObservable(input) { + return input && typeof input[observable] === 'function'; + } + + /** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ + function isIterable(input) { + return input && typeof input[iterator] === 'function'; + } + + /** PURE_IMPORTS_START _scheduleObservable,_schedulePromise,_scheduleArray,_scheduleIterable,_util_isInteropObservable,_util_isPromise,_util_isArrayLike,_util_isIterable PURE_IMPORTS_END */ + function scheduled(input, scheduler) { + if (input != null) { + if (isInteropObservable(input)) { + return scheduleObservable(input, scheduler); + } + else if (isPromise(input)) { + return schedulePromise(input, scheduler); + } + else if (isArrayLike(input)) { + return scheduleArray(input, scheduler); + } + else if (isIterable(input) || typeof input === 'string') { + return scheduleIterable(input, scheduler); + } + } + throw new TypeError((input !== null && typeof input || input) + ' is not observable'); + } + + /** PURE_IMPORTS_START _Observable,_util_subscribeTo,_scheduled_scheduled PURE_IMPORTS_END */ + function from(input, scheduler) { + if (!scheduler) { + if (input instanceof Observable) { + return input; + } + return new Observable(subscribeTo(input)); + } + else { + return scheduled(input, scheduler); + } + } + + /** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_util_subscribeTo PURE_IMPORTS_END */ + var SimpleInnerSubscriber = /*@__PURE__*/ (function (_super) { + __extends(SimpleInnerSubscriber, _super); + function SimpleInnerSubscriber(parent) { + var _this = _super.call(this) || this; + _this.parent = parent; + return _this; + } + SimpleInnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(value); + }; + SimpleInnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error); + this.unsubscribe(); + }; + SimpleInnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(); + this.unsubscribe(); + }; + return SimpleInnerSubscriber; + }(Subscriber)); + var SimpleOuterSubscriber = /*@__PURE__*/ (function (_super) { + __extends(SimpleOuterSubscriber, _super); + function SimpleOuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + SimpleOuterSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + SimpleOuterSubscriber.prototype.notifyError = function (err) { + this.destination.error(err); + }; + SimpleOuterSubscriber.prototype.notifyComplete = function () { + this.destination.complete(); + }; + return SimpleOuterSubscriber; + }(Subscriber)); + function innerSubscribe(result, innerSubscriber) { + if (innerSubscriber.closed) { + return undefined; + } + if (result instanceof Observable) { + return result.subscribe(innerSubscriber); + } + return subscribeTo(result)(innerSubscriber); + } + + /** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + function mergeMap(project, resultSelector, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + if (typeof resultSelector === 'function') { + return function (source) { return source.pipe(mergeMap(function (a, i) { return from(project(a, i)).pipe(map(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); }; + } + else if (typeof resultSelector === 'number') { + concurrent = resultSelector; + } + return function (source) { return source.lift(new MergeMapOperator(project, concurrent)); }; + } + var MergeMapOperator = /*@__PURE__*/ (function () { + function MergeMapOperator(project, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + this.project = project; + this.concurrent = concurrent; + } + MergeMapOperator.prototype.call = function (observer, source) { + return source.subscribe(new MergeMapSubscriber(observer, this.project, this.concurrent)); + }; + return MergeMapOperator; + }()); + var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { + __extends(MergeMapSubscriber, _super); + function MergeMapSubscriber(destination, project, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.concurrent = concurrent; + _this.hasCompleted = false; + _this.buffer = []; + _this.active = 0; + _this.index = 0; + return _this; + } + MergeMapSubscriber.prototype._next = function (value) { + if (this.active < this.concurrent) { + this._tryNext(value); + } + else { + this.buffer.push(value); + } + }; + MergeMapSubscriber.prototype._tryNext = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (err) { + this.destination.error(err); + return; + } + this.active++; + this._innerSub(result); + }; + MergeMapSubscriber.prototype._innerSub = function (ish) { + var innerSubscriber = new SimpleInnerSubscriber(this); + var destination = this.destination; + destination.add(innerSubscriber); + var innerSubscription = innerSubscribe(ish, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); + } + }; + MergeMapSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (this.active === 0 && this.buffer.length === 0) { + this.destination.complete(); + } + this.unsubscribe(); + }; + MergeMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + MergeMapSubscriber.prototype.notifyComplete = function () { + var buffer = this.buffer; + this.active--; + if (buffer.length > 0) { + this._next(buffer.shift()); + } + else if (this.active === 0 && this.hasCompleted) { + this.destination.complete(); + } + }; + return MergeMapSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START _mergeMap,_util_identity PURE_IMPORTS_END */ + function mergeAll(concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + return mergeMap(identity, concurrent); + } + + /** PURE_IMPORTS_START _mergeAll PURE_IMPORTS_END */ + function concatAll() { + return mergeAll(1); + } + + /** PURE_IMPORTS_START _of,_operators_concatAll PURE_IMPORTS_END */ + function concat() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return concatAll()(of.apply(void 0, observables)); + } + + /** PURE_IMPORTS_START _Observable,_from,_empty PURE_IMPORTS_END */ + function defer(observableFactory) { + return new Observable(function (subscriber) { + var input; + try { + input = observableFactory(); + } + catch (err) { + subscriber.error(err); + return undefined; + } + var source = input ? from(input) : empty(); + return source.subscribe(subscriber); + }); + } + + /** PURE_IMPORTS_START _Observable,_util_isArray,_operators_map,_util_isObject,_from PURE_IMPORTS_END */ + function forkJoin() { + var sources = []; + for (var _i = 0; _i < arguments.length; _i++) { + sources[_i] = arguments[_i]; + } + if (sources.length === 1) { + var first_1 = sources[0]; + if (isArray$1(first_1)) { + return forkJoinInternal(first_1, null); + } + if (isObject$1(first_1) && Object.getPrototypeOf(first_1) === Object.prototype) { + var keys = Object.keys(first_1); + return forkJoinInternal(keys.map(function (key) { return first_1[key]; }), keys); + } + } + if (typeof sources[sources.length - 1] === 'function') { + var resultSelector_1 = sources.pop(); + sources = (sources.length === 1 && isArray$1(sources[0])) ? sources[0] : sources; + return forkJoinInternal(sources, null).pipe(map(function (args) { return resultSelector_1.apply(void 0, args); })); + } + return forkJoinInternal(sources, null); + } + function forkJoinInternal(sources, keys) { + return new Observable(function (subscriber) { + var len = sources.length; + if (len === 0) { + subscriber.complete(); + return; + } + var values = new Array(len); + var completed = 0; + var emitted = 0; + var _loop_1 = function (i) { + var source = from(sources[i]); + var hasValue = false; + subscriber.add(source.subscribe({ + next: function (value) { + if (!hasValue) { + hasValue = true; + emitted++; + } + values[i] = value; + }, + error: function (err) { return subscriber.error(err); }, + complete: function () { + completed++; + if (completed === len || !hasValue) { + if (emitted === len) { + subscriber.next(keys ? + keys.reduce(function (result, key, i) { return (result[key] = values[i], result); }, {}) : + values); + } + subscriber.complete(); + } + } + })); + }; + for (var i = 0; i < len; i++) { + _loop_1(i); + } + }); + } + + /** PURE_IMPORTS_START _Observable,_util_isArray,_util_isFunction,_operators_map PURE_IMPORTS_END */ + function fromEvent(target, eventName, options, resultSelector) { + if (isFunction$1(options)) { + resultSelector = options; + options = undefined; + } + if (resultSelector) { + return fromEvent(target, eventName, options).pipe(map(function (args) { return isArray$1(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); + } + return new Observable(function (subscriber) { + function handler(e) { + if (arguments.length > 1) { + subscriber.next(Array.prototype.slice.call(arguments)); + } + else { + subscriber.next(e); + } + } + setupSubscription(target, eventName, handler, subscriber, options); + }); + } + function setupSubscription(sourceObj, eventName, handler, subscriber, options) { + var unsubscribe; + if (isEventTarget(sourceObj)) { + var source_1 = sourceObj; + sourceObj.addEventListener(eventName, handler, options); + unsubscribe = function () { return source_1.removeEventListener(eventName, handler, options); }; + } + else if (isJQueryStyleEventEmitter(sourceObj)) { + var source_2 = sourceObj; + sourceObj.on(eventName, handler); + unsubscribe = function () { return source_2.off(eventName, handler); }; + } + else if (isNodeStyleEventEmitter(sourceObj)) { + var source_3 = sourceObj; + sourceObj.addListener(eventName, handler); + unsubscribe = function () { return source_3.removeListener(eventName, handler); }; + } + else if (sourceObj && sourceObj.length) { + for (var i = 0, len = sourceObj.length; i < len; i++) { + setupSubscription(sourceObj[i], eventName, handler, subscriber, options); + } + } + else { + throw new TypeError('Invalid event target'); + } + subscriber.add(unsubscribe); + } + function isNodeStyleEventEmitter(sourceObj) { + return sourceObj && typeof sourceObj.addListener === 'function' && typeof sourceObj.removeListener === 'function'; + } + function isJQueryStyleEventEmitter(sourceObj) { + return sourceObj && typeof sourceObj.on === 'function' && typeof sourceObj.off === 'function'; + } + function isEventTarget(sourceObj) { + return sourceObj && typeof sourceObj.addEventListener === 'function' && typeof sourceObj.removeEventListener === 'function'; + } + + /** PURE_IMPORTS_START _defer,_empty PURE_IMPORTS_END */ + function iif(condition, trueResult, falseResult) { + if (trueResult === void 0) { + trueResult = EMPTY; + } + if (falseResult === void 0) { + falseResult = EMPTY; + } + return defer(function () { return condition() ? trueResult : falseResult; }); + } + + /** PURE_IMPORTS_START _isArray PURE_IMPORTS_END */ + function isNumeric(val) { + return !isArray$1(val) && (val - parseFloat(val) + 1) >= 0; + } + + /** PURE_IMPORTS_START _Observable,_util_isScheduler,_operators_mergeAll,_fromArray PURE_IMPORTS_END */ + function merge() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var concurrent = Number.POSITIVE_INFINITY; + var scheduler = null; + var last = observables[observables.length - 1]; + if (isScheduler(last)) { + scheduler = observables.pop(); + if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') { + concurrent = observables.pop(); + } + } + else if (typeof last === 'number') { + concurrent = observables.pop(); + } + if (scheduler === null && observables.length === 1 && observables[0] instanceof Observable) { + return observables[0]; + } + return mergeAll(concurrent)(fromArray(observables, scheduler)); + } + + /** PURE_IMPORTS_START _Observable,_util_noop PURE_IMPORTS_END */ + var NEVER = /*@__PURE__*/ new Observable(noop); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function filter(predicate, thisArg) { + return function filterOperatorFunction(source) { + return source.lift(new FilterOperator(predicate, thisArg)); + }; + } + var FilterOperator = /*@__PURE__*/ (function () { + function FilterOperator(predicate, thisArg) { + this.predicate = predicate; + this.thisArg = thisArg; + } + FilterOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new FilterSubscriber(subscriber, this.predicate, this.thisArg)); + }; + return FilterOperator; + }()); + var FilterSubscriber = /*@__PURE__*/ (function (_super) { + __extends(FilterSubscriber, _super); + function FilterSubscriber(destination, predicate, thisArg) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.thisArg = thisArg; + _this.count = 0; + return _this; + } + FilterSubscriber.prototype._next = function (value) { + var result; + try { + result = this.predicate.call(this.thisArg, value, this.count++); + } + catch (err) { + this.destination.error(err); + return; + } + if (result) { + this.destination.next(value); + } + }; + return FilterSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_util_isArray,_fromArray,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + function race() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + if (observables.length === 1) { + if (isArray$1(observables[0])) { + observables = observables[0]; + } + else { + return observables[0]; + } + } + return fromArray(observables, undefined).lift(new RaceOperator()); + } + var RaceOperator = /*@__PURE__*/ (function () { + function RaceOperator() { + } + RaceOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RaceSubscriber(subscriber)); + }; + return RaceOperator; + }()); + var RaceSubscriber = /*@__PURE__*/ (function (_super) { + __extends(RaceSubscriber, _super); + function RaceSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.hasFirst = false; + _this.observables = []; + _this.subscriptions = []; + return _this; + } + RaceSubscriber.prototype._next = function (observable) { + this.observables.push(observable); + }; + RaceSubscriber.prototype._complete = function () { + var observables = this.observables; + var len = observables.length; + if (len === 0) { + this.destination.complete(); + } + else { + for (var i = 0; i < len && !this.hasFirst; i++) { + var observable = observables[i]; + var subscription = subscribeToResult(this, observable, undefined, i); + if (this.subscriptions) { + this.subscriptions.push(subscription); + } + this.add(subscription); + } + this.observables = null; + } + }; + RaceSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { + if (!this.hasFirst) { + this.hasFirst = true; + for (var i = 0; i < this.subscriptions.length; i++) { + if (i !== outerIndex) { + var subscription = this.subscriptions[i]; + subscription.unsubscribe(); + this.remove(subscription); + } + } + this.subscriptions = null; + } + this.destination.next(innerValue); + }; + return RaceSubscriber; + }(OuterSubscriber)); + + /** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ + function timer(dueTime, periodOrScheduler, scheduler) { + if (dueTime === void 0) { + dueTime = 0; + } + var period = -1; + if (isNumeric(periodOrScheduler)) { + period = Number(periodOrScheduler) < 1 && 1 || Number(periodOrScheduler); + } + else if (isScheduler(periodOrScheduler)) { + scheduler = periodOrScheduler; + } + if (!isScheduler(scheduler)) { + scheduler = async; + } + return new Observable(function (subscriber) { + var due = isNumeric(dueTime) + ? dueTime + : (+dueTime - scheduler.now()); + return scheduler.schedule(dispatch, due, { + index: 0, period: period, subscriber: subscriber + }); + }); + } + function dispatch(state) { + var index = state.index, period = state.period, subscriber = state.subscriber; + subscriber.next(index); + if (subscriber.closed) { + return; + } + else if (period === -1) { + return subscriber.complete(); + } + state.index = index + 1; + this.schedule(state, period); + } + + /** PURE_IMPORTS_START tslib,_fromArray,_util_isArray,_Subscriber,_.._internal_symbol_iterator,_innerSubscribe PURE_IMPORTS_END */ + function zip() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var resultSelector = observables[observables.length - 1]; + if (typeof resultSelector === 'function') { + observables.pop(); + } + return fromArray(observables, undefined).lift(new ZipOperator(resultSelector)); + } + var ZipOperator = /*@__PURE__*/ (function () { + function ZipOperator(resultSelector) { + this.resultSelector = resultSelector; + } + ZipOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ZipSubscriber(subscriber, this.resultSelector)); + }; + return ZipOperator; + }()); + var ZipSubscriber = /*@__PURE__*/ (function (_super) { + __extends(ZipSubscriber, _super); + function ZipSubscriber(destination, resultSelector, values) { + var _this = _super.call(this, destination) || this; + _this.resultSelector = resultSelector; + _this.iterators = []; + _this.active = 0; + _this.resultSelector = (typeof resultSelector === 'function') ? resultSelector : undefined; + return _this; + } + ZipSubscriber.prototype._next = function (value) { + var iterators = this.iterators; + if (isArray$1(value)) { + iterators.push(new StaticArrayIterator(value)); + } + else if (typeof value[iterator] === 'function') { + iterators.push(new StaticIterator(value[iterator]())); + } + else { + iterators.push(new ZipBufferIterator(this.destination, this, value)); + } + }; + ZipSubscriber.prototype._complete = function () { + var iterators = this.iterators; + var len = iterators.length; + this.unsubscribe(); + if (len === 0) { + this.destination.complete(); + return; + } + this.active = len; + for (var i = 0; i < len; i++) { + var iterator = iterators[i]; + if (iterator.stillUnsubscribed) { + var destination = this.destination; + destination.add(iterator.subscribe()); + } + else { + this.active--; + } + } + }; + ZipSubscriber.prototype.notifyInactive = function () { + this.active--; + if (this.active === 0) { + this.destination.complete(); + } + }; + ZipSubscriber.prototype.checkIterators = function () { + var iterators = this.iterators; + var len = iterators.length; + var destination = this.destination; + for (var i = 0; i < len; i++) { + var iterator = iterators[i]; + if (typeof iterator.hasValue === 'function' && !iterator.hasValue()) { + return; + } + } + var shouldComplete = false; + var args = []; + for (var i = 0; i < len; i++) { + var iterator = iterators[i]; + var result = iterator.next(); + if (iterator.hasCompleted()) { + shouldComplete = true; + } + if (result.done) { + destination.complete(); + return; + } + args.push(result.value); + } + if (this.resultSelector) { + this._tryresultSelector(args); + } + else { + destination.next(args); + } + if (shouldComplete) { + destination.complete(); + } + }; + ZipSubscriber.prototype._tryresultSelector = function (args) { + var result; + try { + result = this.resultSelector.apply(this, args); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return ZipSubscriber; + }(Subscriber)); + var StaticIterator = /*@__PURE__*/ (function () { + function StaticIterator(iterator) { + this.iterator = iterator; + this.nextResult = iterator.next(); + } + StaticIterator.prototype.hasValue = function () { + return true; + }; + StaticIterator.prototype.next = function () { + var result = this.nextResult; + this.nextResult = this.iterator.next(); + return result; + }; + StaticIterator.prototype.hasCompleted = function () { + var nextResult = this.nextResult; + return Boolean(nextResult && nextResult.done); + }; + return StaticIterator; + }()); + var StaticArrayIterator = /*@__PURE__*/ (function () { + function StaticArrayIterator(array) { + this.array = array; + this.index = 0; + this.length = 0; + this.length = array.length; + } + StaticArrayIterator.prototype[iterator] = function () { + return this; + }; + StaticArrayIterator.prototype.next = function (value) { + var i = this.index++; + var array = this.array; + return i < this.length ? { value: array[i], done: false } : { value: null, done: true }; + }; + StaticArrayIterator.prototype.hasValue = function () { + return this.array.length > this.index; + }; + StaticArrayIterator.prototype.hasCompleted = function () { + return this.array.length === this.index; + }; + return StaticArrayIterator; + }()); + var ZipBufferIterator = /*@__PURE__*/ (function (_super) { + __extends(ZipBufferIterator, _super); + function ZipBufferIterator(destination, parent, observable) { + var _this = _super.call(this, destination) || this; + _this.parent = parent; + _this.observable = observable; + _this.stillUnsubscribed = true; + _this.buffer = []; + _this.isComplete = false; + return _this; + } + ZipBufferIterator.prototype[iterator] = function () { + return this; + }; + ZipBufferIterator.prototype.next = function () { + var buffer = this.buffer; + if (buffer.length === 0 && this.isComplete) { + return { value: null, done: true }; + } + else { + return { value: buffer.shift(), done: false }; + } + }; + ZipBufferIterator.prototype.hasValue = function () { + return this.buffer.length > 0; + }; + ZipBufferIterator.prototype.hasCompleted = function () { + return this.buffer.length === 0 && this.isComplete; + }; + ZipBufferIterator.prototype.notifyComplete = function () { + if (this.buffer.length > 0) { + this.isComplete = true; + this.parent.notifyInactive(); + } + else { + this.destination.complete(); + } + }; + ZipBufferIterator.prototype.notifyNext = function (innerValue) { + this.buffer.push(innerValue); + this.parent.checkIterators(); + }; + ZipBufferIterator.prototype.subscribe = function () { + return innerSubscribe(this.observable, new SimpleInnerSubscriber(this)); + }; + return ZipBufferIterator; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + function audit(durationSelector) { + return function auditOperatorFunction(source) { + return source.lift(new AuditOperator(durationSelector)); + }; + } + var AuditOperator = /*@__PURE__*/ (function () { + function AuditOperator(durationSelector) { + this.durationSelector = durationSelector; + } + AuditOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new AuditSubscriber(subscriber, this.durationSelector)); + }; + return AuditOperator; + }()); + var AuditSubscriber = /*@__PURE__*/ (function (_super) { + __extends(AuditSubscriber, _super); + function AuditSubscriber(destination, durationSelector) { + var _this = _super.call(this, destination) || this; + _this.durationSelector = durationSelector; + _this.hasValue = false; + return _this; + } + AuditSubscriber.prototype._next = function (value) { + this.value = value; + this.hasValue = true; + if (!this.throttled) { + var duration = void 0; + try { + var durationSelector = this.durationSelector; + duration = durationSelector(value); + } + catch (err) { + return this.destination.error(err); + } + var innerSubscription = innerSubscribe(duration, new SimpleInnerSubscriber(this)); + if (!innerSubscription || innerSubscription.closed) { + this.clearThrottle(); + } + else { + this.add(this.throttled = innerSubscription); + } + } + }; + AuditSubscriber.prototype.clearThrottle = function () { + var _a = this, value = _a.value, hasValue = _a.hasValue, throttled = _a.throttled; + if (throttled) { + this.remove(throttled); + this.throttled = undefined; + throttled.unsubscribe(); + } + if (hasValue) { + this.value = undefined; + this.hasValue = false; + this.destination.next(value); + } + }; + AuditSubscriber.prototype.notifyNext = function () { + this.clearThrottle(); + }; + AuditSubscriber.prototype.notifyComplete = function () { + this.clearThrottle(); + }; + return AuditSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ + function auditTime(duration, scheduler) { + if (scheduler === void 0) { + scheduler = async; + } + return audit(function () { return timer(duration, scheduler); }); + } + + /** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + function catchError(selector) { + return function catchErrorOperatorFunction(source) { + var operator = new CatchOperator(selector); + var caught = source.lift(operator); + return (operator.caught = caught); + }; + } + var CatchOperator = /*@__PURE__*/ (function () { + function CatchOperator(selector) { + this.selector = selector; + } + CatchOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught)); + }; + return CatchOperator; + }()); + var CatchSubscriber = /*@__PURE__*/ (function (_super) { + __extends(CatchSubscriber, _super); + function CatchSubscriber(destination, selector, caught) { + var _this = _super.call(this, destination) || this; + _this.selector = selector; + _this.caught = caught; + return _this; + } + CatchSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var result = void 0; + try { + result = this.selector(err, this.caught); + } + catch (err2) { + _super.prototype.error.call(this, err2); + return; + } + this._unsubscribeAndRecycle(); + var innerSubscriber = new SimpleInnerSubscriber(this); + this.add(innerSubscriber); + var innerSubscription = innerSubscribe(result, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + this.add(innerSubscription); + } + } + }; + return CatchSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ + function concatMap(project, resultSelector) { + return mergeMap(project, resultSelector, 1); + } + + /** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ + function debounceTime(dueTime, scheduler) { + if (scheduler === void 0) { + scheduler = async; + } + return function (source) { return source.lift(new DebounceTimeOperator(dueTime, scheduler)); }; + } + var DebounceTimeOperator = /*@__PURE__*/ (function () { + function DebounceTimeOperator(dueTime, scheduler) { + this.dueTime = dueTime; + this.scheduler = scheduler; + } + DebounceTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DebounceTimeSubscriber(subscriber, this.dueTime, this.scheduler)); + }; + return DebounceTimeOperator; + }()); + var DebounceTimeSubscriber = /*@__PURE__*/ (function (_super) { + __extends(DebounceTimeSubscriber, _super); + function DebounceTimeSubscriber(destination, dueTime, scheduler) { + var _this = _super.call(this, destination) || this; + _this.dueTime = dueTime; + _this.scheduler = scheduler; + _this.debouncedSubscription = null; + _this.lastValue = null; + _this.hasValue = false; + return _this; + } + DebounceTimeSubscriber.prototype._next = function (value) { + this.clearDebounce(); + this.lastValue = value; + this.hasValue = true; + this.add(this.debouncedSubscription = this.scheduler.schedule(dispatchNext$1, this.dueTime, this)); + }; + DebounceTimeSubscriber.prototype._complete = function () { + this.debouncedNext(); + this.destination.complete(); + }; + DebounceTimeSubscriber.prototype.debouncedNext = function () { + this.clearDebounce(); + if (this.hasValue) { + var lastValue = this.lastValue; + this.lastValue = null; + this.hasValue = false; + this.destination.next(lastValue); + } + }; + DebounceTimeSubscriber.prototype.clearDebounce = function () { + var debouncedSubscription = this.debouncedSubscription; + if (debouncedSubscription !== null) { + this.remove(debouncedSubscription); + debouncedSubscription.unsubscribe(); + this.debouncedSubscription = null; + } + }; + return DebounceTimeSubscriber; + }(Subscriber)); + function dispatchNext$1(subscriber) { + subscriber.debouncedNext(); + } + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function defaultIfEmpty(defaultValue) { + if (defaultValue === void 0) { + defaultValue = null; + } + return function (source) { return source.lift(new DefaultIfEmptyOperator(defaultValue)); }; + } + var DefaultIfEmptyOperator = /*@__PURE__*/ (function () { + function DefaultIfEmptyOperator(defaultValue) { + this.defaultValue = defaultValue; + } + DefaultIfEmptyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue)); + }; + return DefaultIfEmptyOperator; + }()); + var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { + __extends(DefaultIfEmptySubscriber, _super); + function DefaultIfEmptySubscriber(destination, defaultValue) { + var _this = _super.call(this, destination) || this; + _this.defaultValue = defaultValue; + _this.isEmpty = true; + return _this; + } + DefaultIfEmptySubscriber.prototype._next = function (value) { + this.isEmpty = false; + this.destination.next(value); + }; + DefaultIfEmptySubscriber.prototype._complete = function () { + if (this.isEmpty) { + this.destination.next(this.defaultValue); + } + this.destination.complete(); + }; + return DefaultIfEmptySubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START PURE_IMPORTS_END */ + function isDate(value) { + return value instanceof Date && !isNaN(+value); + } + + /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ + function delay(delay, scheduler) { + if (scheduler === void 0) { + scheduler = async; + } + var absoluteDelay = isDate(delay); + var delayFor = absoluteDelay ? (+delay - scheduler.now()) : Math.abs(delay); + return function (source) { return source.lift(new DelayOperator(delayFor, scheduler)); }; + } + var DelayOperator = /*@__PURE__*/ (function () { + function DelayOperator(delay, scheduler) { + this.delay = delay; + this.scheduler = scheduler; + } + DelayOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DelaySubscriber(subscriber, this.delay, this.scheduler)); + }; + return DelayOperator; + }()); + var DelaySubscriber = /*@__PURE__*/ (function (_super) { + __extends(DelaySubscriber, _super); + function DelaySubscriber(destination, delay, scheduler) { + var _this = _super.call(this, destination) || this; + _this.delay = delay; + _this.scheduler = scheduler; + _this.queue = []; + _this.active = false; + _this.errored = false; + return _this; + } + DelaySubscriber.dispatch = function (state) { + var source = state.source; + var queue = source.queue; + var scheduler = state.scheduler; + var destination = state.destination; + while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) { + queue.shift().notification.observe(destination); + } + if (queue.length > 0) { + var delay_1 = Math.max(0, queue[0].time - scheduler.now()); + this.schedule(state, delay_1); + } + else { + this.unsubscribe(); + source.active = false; + } + }; + DelaySubscriber.prototype._schedule = function (scheduler) { + this.active = true; + var destination = this.destination; + destination.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, { + source: this, destination: this.destination, scheduler: scheduler + })); + }; + DelaySubscriber.prototype.scheduleNotification = function (notification) { + if (this.errored === true) { + return; + } + var scheduler = this.scheduler; + var message = new DelayMessage(scheduler.now() + this.delay, notification); + this.queue.push(message); + if (this.active === false) { + this._schedule(scheduler); + } + }; + DelaySubscriber.prototype._next = function (value) { + this.scheduleNotification(Notification.createNext(value)); + }; + DelaySubscriber.prototype._error = function (err) { + this.errored = true; + this.queue = []; + this.destination.error(err); + this.unsubscribe(); + }; + DelaySubscriber.prototype._complete = function () { + this.scheduleNotification(Notification.createComplete()); + this.unsubscribe(); + }; + return DelaySubscriber; + }(Subscriber)); + var DelayMessage = /*@__PURE__*/ (function () { + function DelayMessage(time, notification) { + this.time = time; + this.notification = notification; + } + return DelayMessage; + }()); + + /** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + function delayWhen(delayDurationSelector, subscriptionDelay) { + if (subscriptionDelay) { + return function (source) { + return new SubscriptionDelayObservable(source, subscriptionDelay) + .lift(new DelayWhenOperator(delayDurationSelector)); + }; + } + return function (source) { return source.lift(new DelayWhenOperator(delayDurationSelector)); }; + } + var DelayWhenOperator = /*@__PURE__*/ (function () { + function DelayWhenOperator(delayDurationSelector) { + this.delayDurationSelector = delayDurationSelector; + } + DelayWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DelayWhenSubscriber(subscriber, this.delayDurationSelector)); + }; + return DelayWhenOperator; + }()); + var DelayWhenSubscriber = /*@__PURE__*/ (function (_super) { + __extends(DelayWhenSubscriber, _super); + function DelayWhenSubscriber(destination, delayDurationSelector) { + var _this = _super.call(this, destination) || this; + _this.delayDurationSelector = delayDurationSelector; + _this.completed = false; + _this.delayNotifierSubscriptions = []; + _this.index = 0; + return _this; + } + DelayWhenSubscriber.prototype.notifyNext = function (outerValue, _innerValue, _outerIndex, _innerIndex, innerSub) { + this.destination.next(outerValue); + this.removeSubscription(innerSub); + this.tryComplete(); + }; + DelayWhenSubscriber.prototype.notifyError = function (error, innerSub) { + this._error(error); + }; + DelayWhenSubscriber.prototype.notifyComplete = function (innerSub) { + var value = this.removeSubscription(innerSub); + if (value) { + this.destination.next(value); + } + this.tryComplete(); + }; + DelayWhenSubscriber.prototype._next = function (value) { + var index = this.index++; + try { + var delayNotifier = this.delayDurationSelector(value, index); + if (delayNotifier) { + this.tryDelay(delayNotifier, value); + } + } + catch (err) { + this.destination.error(err); + } + }; + DelayWhenSubscriber.prototype._complete = function () { + this.completed = true; + this.tryComplete(); + this.unsubscribe(); + }; + DelayWhenSubscriber.prototype.removeSubscription = function (subscription) { + subscription.unsubscribe(); + var subscriptionIdx = this.delayNotifierSubscriptions.indexOf(subscription); + if (subscriptionIdx !== -1) { + this.delayNotifierSubscriptions.splice(subscriptionIdx, 1); + } + return subscription.outerValue; + }; + DelayWhenSubscriber.prototype.tryDelay = function (delayNotifier, value) { + var notifierSubscription = subscribeToResult(this, delayNotifier, value); + if (notifierSubscription && !notifierSubscription.closed) { + var destination = this.destination; + destination.add(notifierSubscription); + this.delayNotifierSubscriptions.push(notifierSubscription); + } + }; + DelayWhenSubscriber.prototype.tryComplete = function () { + if (this.completed && this.delayNotifierSubscriptions.length === 0) { + this.destination.complete(); + } + }; + return DelayWhenSubscriber; + }(OuterSubscriber)); + var SubscriptionDelayObservable = /*@__PURE__*/ (function (_super) { + __extends(SubscriptionDelayObservable, _super); + function SubscriptionDelayObservable(source, subscriptionDelay) { + var _this = _super.call(this) || this; + _this.source = source; + _this.subscriptionDelay = subscriptionDelay; + return _this; + } + SubscriptionDelayObservable.prototype._subscribe = function (subscriber) { + this.subscriptionDelay.subscribe(new SubscriptionDelaySubscriber(subscriber, this.source)); + }; + return SubscriptionDelayObservable; + }(Observable)); + var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { + __extends(SubscriptionDelaySubscriber, _super); + function SubscriptionDelaySubscriber(parent, source) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.source = source; + _this.sourceSubscribed = false; + return _this; + } + SubscriptionDelaySubscriber.prototype._next = function (unused) { + this.subscribeToSource(); + }; + SubscriptionDelaySubscriber.prototype._error = function (err) { + this.unsubscribe(); + this.parent.error(err); + }; + SubscriptionDelaySubscriber.prototype._complete = function () { + this.unsubscribe(); + this.subscribeToSource(); + }; + SubscriptionDelaySubscriber.prototype.subscribeToSource = function () { + if (!this.sourceSubscribed) { + this.sourceSubscribed = true; + this.unsubscribe(); + this.source.subscribe(this.parent); + } + }; + return SubscriptionDelaySubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function distinctUntilChanged(compare, keySelector) { + return function (source) { return source.lift(new DistinctUntilChangedOperator(compare, keySelector)); }; + } + var DistinctUntilChangedOperator = /*@__PURE__*/ (function () { + function DistinctUntilChangedOperator(compare, keySelector) { + this.compare = compare; + this.keySelector = keySelector; + } + DistinctUntilChangedOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector)); + }; + return DistinctUntilChangedOperator; + }()); + var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { + __extends(DistinctUntilChangedSubscriber, _super); + function DistinctUntilChangedSubscriber(destination, compare, keySelector) { + var _this = _super.call(this, destination) || this; + _this.keySelector = keySelector; + _this.hasKey = false; + if (typeof compare === 'function') { + _this.compare = compare; + } + return _this; + } + DistinctUntilChangedSubscriber.prototype.compare = function (x, y) { + return x === y; + }; + DistinctUntilChangedSubscriber.prototype._next = function (value) { + var key; + try { + var keySelector = this.keySelector; + key = keySelector ? keySelector(value) : value; + } + catch (err) { + return this.destination.error(err); + } + var result = false; + if (this.hasKey) { + try { + var compare = this.compare; + result = compare(this.key, key); + } + catch (err) { + return this.destination.error(err); + } + } + else { + this.hasKey = true; + } + if (!result) { + this.key = key; + this.destination.next(value); + } + }; + return DistinctUntilChangedSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ + function take(count) { + return function (source) { + if (count === 0) { + return empty(); + } + else { + return source.lift(new TakeOperator(count)); + } + }; + } + var TakeOperator = /*@__PURE__*/ (function () { + function TakeOperator(total) { + this.total = total; + if (this.total < 0) { + throw new ArgumentOutOfRangeError; + } + } + TakeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeSubscriber(subscriber, this.total)); + }; + return TakeOperator; + }()); + var TakeSubscriber = /*@__PURE__*/ (function (_super) { + __extends(TakeSubscriber, _super); + function TakeSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.count = 0; + return _this; + } + TakeSubscriber.prototype._next = function (value) { + var total = this.total; + var count = ++this.count; + if (count <= total) { + this.destination.next(value); + if (count === total) { + this.destination.complete(); + this.unsubscribe(); + } + } + }; + return TakeSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + function exhaustMap(project, resultSelector) { + if (resultSelector) { + return function (source) { return source.pipe(exhaustMap(function (a, i) { return from(project(a, i)).pipe(map(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; + } + return function (source) { + return source.lift(new ExhaustMapOperator(project)); + }; + } + var ExhaustMapOperator = /*@__PURE__*/ (function () { + function ExhaustMapOperator(project) { + this.project = project; + } + ExhaustMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ExhaustMapSubscriber(subscriber, this.project)); + }; + return ExhaustMapOperator; + }()); + var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { + __extends(ExhaustMapSubscriber, _super); + function ExhaustMapSubscriber(destination, project) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.hasSubscription = false; + _this.hasCompleted = false; + _this.index = 0; + return _this; + } + ExhaustMapSubscriber.prototype._next = function (value) { + if (!this.hasSubscription) { + this.tryNext(value); + } + }; + ExhaustMapSubscriber.prototype.tryNext = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (err) { + this.destination.error(err); + return; + } + this.hasSubscription = true; + this._innerSub(result); + }; + ExhaustMapSubscriber.prototype._innerSub = function (result) { + var innerSubscriber = new SimpleInnerSubscriber(this); + var destination = this.destination; + destination.add(innerSubscriber); + var innerSubscription = innerSubscribe(result, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); + } + }; + ExhaustMapSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (!this.hasSubscription) { + this.destination.complete(); + } + this.unsubscribe(); + }; + ExhaustMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + ExhaustMapSubscriber.prototype.notifyError = function (err) { + this.destination.error(err); + }; + ExhaustMapSubscriber.prototype.notifyComplete = function () { + this.hasSubscription = false; + if (this.hasCompleted) { + this.destination.complete(); + } + }; + return ExhaustMapSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber,_Subscription PURE_IMPORTS_END */ + function finalize$1(callback) { + return function (source) { return source.lift(new FinallyOperator(callback)); }; + } + var FinallyOperator = /*@__PURE__*/ (function () { + function FinallyOperator(callback) { + this.callback = callback; + } + FinallyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new FinallySubscriber(subscriber, this.callback)); + }; + return FinallyOperator; + }()); + var FinallySubscriber = /*@__PURE__*/ (function (_super) { + __extends(FinallySubscriber, _super); + function FinallySubscriber(destination, callback) { + var _this = _super.call(this, destination) || this; + _this.add(new Subscription(callback)); + return _this; + } + return FinallySubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ + function takeLast(count) { + return function takeLastOperatorFunction(source) { + if (count === 0) { + return empty(); + } + else { + return source.lift(new TakeLastOperator(count)); + } + }; + } + var TakeLastOperator = /*@__PURE__*/ (function () { + function TakeLastOperator(total) { + this.total = total; + if (this.total < 0) { + throw new ArgumentOutOfRangeError; + } + } + TakeLastOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeLastSubscriber(subscriber, this.total)); + }; + return TakeLastOperator; + }()); + var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { + __extends(TakeLastSubscriber, _super); + function TakeLastSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.ring = new Array(); + _this.count = 0; + return _this; + } + TakeLastSubscriber.prototype._next = function (value) { + var ring = this.ring; + var total = this.total; + var count = this.count++; + if (ring.length < total) { + ring.push(value); + } + else { + var index = count % total; + ring[index] = value; + } + }; + TakeLastSubscriber.prototype._complete = function () { + var destination = this.destination; + var count = this.count; + if (count > 0) { + var total = this.count >= this.total ? this.total : this.count; + var ring = this.ring; + for (var i = 0; i < total; i++) { + var idx = (count++) % total; + destination.next(ring[idx]); + } + } + destination.complete(); + }; + return TakeLastSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function mapTo(value) { + return function (source) { return source.lift(new MapToOperator(value)); }; + } + var MapToOperator = /*@__PURE__*/ (function () { + function MapToOperator(value) { + this.value = value; + } + MapToOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MapToSubscriber(subscriber, this.value)); + }; + return MapToOperator; + }()); + var MapToSubscriber = /*@__PURE__*/ (function (_super) { + __extends(MapToSubscriber, _super); + function MapToSubscriber(destination, value) { + var _this = _super.call(this, destination) || this; + _this.value = value; + return _this; + } + MapToSubscriber.prototype._next = function (x) { + this.destination.next(this.value); + }; + return MapToSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function scan(accumulator, seed) { + var hasSeed = false; + if (arguments.length >= 2) { + hasSeed = true; + } + return function scanOperatorFunction(source) { + return source.lift(new ScanOperator(accumulator, seed, hasSeed)); + }; + } + var ScanOperator = /*@__PURE__*/ (function () { + function ScanOperator(accumulator, seed, hasSeed) { + if (hasSeed === void 0) { + hasSeed = false; + } + this.accumulator = accumulator; + this.seed = seed; + this.hasSeed = hasSeed; + } + ScanOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed)); + }; + return ScanOperator; + }()); + var ScanSubscriber = /*@__PURE__*/ (function (_super) { + __extends(ScanSubscriber, _super); + function ScanSubscriber(destination, accumulator, _seed, hasSeed) { + var _this = _super.call(this, destination) || this; + _this.accumulator = accumulator; + _this._seed = _seed; + _this.hasSeed = hasSeed; + _this.index = 0; + return _this; + } + Object.defineProperty(ScanSubscriber.prototype, "seed", { + get: function () { + return this._seed; + }, + set: function (value) { + this.hasSeed = true; + this._seed = value; + }, + enumerable: true, + configurable: true + }); + ScanSubscriber.prototype._next = function (value) { + if (!this.hasSeed) { + this.seed = value; + this.destination.next(value); + } + else { + return this._tryNext(value); + } + }; + ScanSubscriber.prototype._tryNext = function (value) { + var index = this.index++; + var result; + try { + result = this.accumulator(this.seed, value, index); + } + catch (err) { + this.destination.error(err); + } + this.seed = result; + this.destination.next(result); + }; + return ScanSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ + function reduce(accumulator, seed) { + if (arguments.length >= 2) { + return function reduceOperatorFunctionWithSeed(source) { + return pipe(scan(accumulator, seed), takeLast(1), defaultIfEmpty(seed))(source); + }; + } + return function reduceOperatorFunction(source) { + return pipe(scan(function (acc, value, index) { return accumulator(acc, value, index + 1); }), takeLast(1))(source); + }; + } + + /** PURE_IMPORTS_START _observable_ConnectableObservable PURE_IMPORTS_END */ + function multicast(subjectOrSubjectFactory, selector) { + return function multicastOperatorFunction(source) { + var subjectFactory; + if (typeof subjectOrSubjectFactory === 'function') { + subjectFactory = subjectOrSubjectFactory; + } + else { + subjectFactory = function subjectFactory() { + return subjectOrSubjectFactory; + }; + } + if (typeof selector === 'function') { + return source.lift(new MulticastOperator(subjectFactory, selector)); + } + var connectable = Object.create(source, connectableObservableDescriptor); + connectable.source = source; + connectable.subjectFactory = subjectFactory; + return connectable; + }; + } + var MulticastOperator = /*@__PURE__*/ (function () { + function MulticastOperator(subjectFactory, selector) { + this.subjectFactory = subjectFactory; + this.selector = selector; + } + MulticastOperator.prototype.call = function (subscriber, source) { + var selector = this.selector; + var subject = this.subjectFactory(); + var subscription = selector(subject).subscribe(subscriber); + subscription.add(source.subscribe(subject)); + return subscription; + }; + return MulticastOperator; + }()); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function pairwise() { + return function (source) { return source.lift(new PairwiseOperator()); }; + } + var PairwiseOperator = /*@__PURE__*/ (function () { + function PairwiseOperator() { + } + PairwiseOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new PairwiseSubscriber(subscriber)); + }; + return PairwiseOperator; + }()); + var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { + __extends(PairwiseSubscriber, _super); + function PairwiseSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.hasPrev = false; + return _this; + } + PairwiseSubscriber.prototype._next = function (value) { + var pair; + if (this.hasPrev) { + pair = [this.prev, value]; + } + else { + this.hasPrev = true; + } + this.prev = value; + if (pair) { + this.destination.next(pair); + } + }; + return PairwiseSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subject,_innerSubscribe PURE_IMPORTS_END */ + function retryWhen(notifier) { + return function (source) { return source.lift(new RetryWhenOperator(notifier, source)); }; + } + var RetryWhenOperator = /*@__PURE__*/ (function () { + function RetryWhenOperator(notifier, source) { + this.notifier = notifier; + this.source = source; + } + RetryWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RetryWhenSubscriber(subscriber, this.notifier, this.source)); + }; + return RetryWhenOperator; + }()); + var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { + __extends(RetryWhenSubscriber, _super); + function RetryWhenSubscriber(destination, notifier, source) { + var _this = _super.call(this, destination) || this; + _this.notifier = notifier; + _this.source = source; + return _this; + } + RetryWhenSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var errors = this.errors; + var retries = this.retries; + var retriesSubscription = this.retriesSubscription; + if (!retries) { + errors = new Subject(); + try { + var notifier = this.notifier; + retries = notifier(errors); + } + catch (e) { + return _super.prototype.error.call(this, e); + } + retriesSubscription = innerSubscribe(retries, new SimpleInnerSubscriber(this)); + } + else { + this.errors = undefined; + this.retriesSubscription = undefined; + } + this._unsubscribeAndRecycle(); + this.errors = errors; + this.retries = retries; + this.retriesSubscription = retriesSubscription; + errors.next(err); + } + }; + RetryWhenSubscriber.prototype._unsubscribe = function () { + var _a = this, errors = _a.errors, retriesSubscription = _a.retriesSubscription; + if (errors) { + errors.unsubscribe(); + this.errors = undefined; + } + if (retriesSubscription) { + retriesSubscription.unsubscribe(); + this.retriesSubscription = undefined; + } + this.retries = undefined; + }; + RetryWhenSubscriber.prototype.notifyNext = function () { + var _unsubscribe = this._unsubscribe; + this._unsubscribe = null; + this._unsubscribeAndRecycle(); + this._unsubscribe = _unsubscribe; + this.source.subscribe(this); + }; + return RetryWhenSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ + function shareSubjectFactory() { + return new Subject(); + } + function share() { + return function (source) { return refCount()(multicast(shareSubjectFactory)(source)); }; + } + + /** PURE_IMPORTS_START _ReplaySubject PURE_IMPORTS_END */ + function shareReplay(configOrBufferSize, windowTime, scheduler) { + var config; + if (configOrBufferSize && typeof configOrBufferSize === 'object') { + config = configOrBufferSize; + } + else { + config = { + bufferSize: configOrBufferSize, + windowTime: windowTime, + refCount: false, + scheduler: scheduler, + }; + } + return function (source) { return source.lift(shareReplayOperator(config)); }; + } + function shareReplayOperator(_a) { + var _b = _a.bufferSize, bufferSize = _b === void 0 ? Number.POSITIVE_INFINITY : _b, _c = _a.windowTime, windowTime = _c === void 0 ? Number.POSITIVE_INFINITY : _c, useRefCount = _a.refCount, scheduler = _a.scheduler; + var subject; + var refCount = 0; + var subscription; + var hasError = false; + var isComplete = false; + return function shareReplayOperation(source) { + refCount++; + var innerSub; + if (!subject || hasError) { + hasError = false; + subject = new ReplaySubject(bufferSize, windowTime, scheduler); + innerSub = subject.subscribe(this); + subscription = source.subscribe({ + next: function (value) { + subject.next(value); + }, + error: function (err) { + hasError = true; + subject.error(err); + }, + complete: function () { + isComplete = true; + subscription = undefined; + subject.complete(); + }, + }); + if (isComplete) { + subscription = undefined; + } + } + else { + innerSub = subject.subscribe(this); + } + this.add(function () { + refCount--; + innerSub.unsubscribe(); + innerSub = undefined; + if (subscription && !isComplete && useRefCount && refCount === 0) { + subscription.unsubscribe(); + subscription = undefined; + subject = undefined; + } + }); + }; + } + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function skip(count) { + return function (source) { return source.lift(new SkipOperator(count)); }; + } + var SkipOperator = /*@__PURE__*/ (function () { + function SkipOperator(total) { + this.total = total; + } + SkipOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SkipSubscriber(subscriber, this.total)); + }; + return SkipOperator; + }()); + var SkipSubscriber = /*@__PURE__*/ (function (_super) { + __extends(SkipSubscriber, _super); + function SkipSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.count = 0; + return _this; + } + SkipSubscriber.prototype._next = function (x) { + if (++this.count > this.total) { + this.destination.next(x); + } + }; + return SkipSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START _observable_concat,_util_isScheduler PURE_IMPORTS_END */ + function startWith() { + var array = []; + for (var _i = 0; _i < arguments.length; _i++) { + array[_i] = arguments[_i]; + } + var scheduler = array[array.length - 1]; + if (isScheduler(scheduler)) { + array.pop(); + return function (source) { return concat(array, source, scheduler); }; + } + else { + return function (source) { return concat(array, source); }; + } + } + + /** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + function switchMap(project, resultSelector) { + if (typeof resultSelector === 'function') { + return function (source) { return source.pipe(switchMap(function (a, i) { return from(project(a, i)).pipe(map(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; + } + return function (source) { return source.lift(new SwitchMapOperator(project)); }; + } + var SwitchMapOperator = /*@__PURE__*/ (function () { + function SwitchMapOperator(project) { + this.project = project; + } + SwitchMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SwitchMapSubscriber(subscriber, this.project)); + }; + return SwitchMapOperator; + }()); + var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { + __extends(SwitchMapSubscriber, _super); + function SwitchMapSubscriber(destination, project) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.index = 0; + return _this; + } + SwitchMapSubscriber.prototype._next = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (error) { + this.destination.error(error); + return; + } + this._innerSub(result); + }; + SwitchMapSubscriber.prototype._innerSub = function (result) { + var innerSubscription = this.innerSubscription; + if (innerSubscription) { + innerSubscription.unsubscribe(); + } + var innerSubscriber = new SimpleInnerSubscriber(this); + var destination = this.destination; + destination.add(innerSubscriber); + this.innerSubscription = innerSubscribe(result, innerSubscriber); + if (this.innerSubscription !== innerSubscriber) { + destination.add(this.innerSubscription); + } + }; + SwitchMapSubscriber.prototype._complete = function () { + var innerSubscription = this.innerSubscription; + if (!innerSubscription || innerSubscription.closed) { + _super.prototype._complete.call(this); + } + this.unsubscribe(); + }; + SwitchMapSubscriber.prototype._unsubscribe = function () { + this.innerSubscription = undefined; + }; + SwitchMapSubscriber.prototype.notifyComplete = function () { + this.innerSubscription = undefined; + if (this.isStopped) { + _super.prototype._complete.call(this); + } + }; + SwitchMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + return SwitchMapSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ + function switchMapTo(innerObservable, resultSelector) { + return resultSelector ? switchMap(function () { return innerObservable; }, resultSelector) : switchMap(function () { return innerObservable; }); + } + + /** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + function takeUntil(notifier) { + return function (source) { return source.lift(new TakeUntilOperator(notifier)); }; + } + var TakeUntilOperator = /*@__PURE__*/ (function () { + function TakeUntilOperator(notifier) { + this.notifier = notifier; + } + TakeUntilOperator.prototype.call = function (subscriber, source) { + var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); + var notifierSubscription = innerSubscribe(this.notifier, new SimpleInnerSubscriber(takeUntilSubscriber)); + if (notifierSubscription && !takeUntilSubscriber.seenValue) { + takeUntilSubscriber.add(notifierSubscription); + return source.subscribe(takeUntilSubscriber); + } + return takeUntilSubscriber; + }; + return TakeUntilOperator; + }()); + var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { + __extends(TakeUntilSubscriber, _super); + function TakeUntilSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.seenValue = false; + return _this; + } + TakeUntilSubscriber.prototype.notifyNext = function () { + this.seenValue = true; + this.complete(); + }; + TakeUntilSubscriber.prototype.notifyComplete = function () { + }; + return TakeUntilSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + function takeWhile(predicate, inclusive) { + if (inclusive === void 0) { + inclusive = false; + } + return function (source) { + return source.lift(new TakeWhileOperator(predicate, inclusive)); + }; + } + var TakeWhileOperator = /*@__PURE__*/ (function () { + function TakeWhileOperator(predicate, inclusive) { + this.predicate = predicate; + this.inclusive = inclusive; + } + TakeWhileOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive)); + }; + return TakeWhileOperator; + }()); + var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { + __extends(TakeWhileSubscriber, _super); + function TakeWhileSubscriber(destination, predicate, inclusive) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.inclusive = inclusive; + _this.index = 0; + return _this; + } + TakeWhileSubscriber.prototype._next = function (value) { + var destination = this.destination; + var result; + try { + result = this.predicate(value, this.index++); + } + catch (err) { + destination.error(err); + return; + } + this.nextOrComplete(value, result); + }; + TakeWhileSubscriber.prototype.nextOrComplete = function (value, predicateResult) { + var destination = this.destination; + if (Boolean(predicateResult)) { + destination.next(value); + } + else { + if (this.inclusive) { + destination.next(value); + } + destination.complete(); + } + }; + return TakeWhileSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_Subscriber,_util_noop,_util_isFunction PURE_IMPORTS_END */ + function tap(nextOrObserver, error, complete) { + return function tapOperatorFunction(source) { + return source.lift(new DoOperator(nextOrObserver, error, complete)); + }; + } + var DoOperator = /*@__PURE__*/ (function () { + function DoOperator(nextOrObserver, error, complete) { + this.nextOrObserver = nextOrObserver; + this.error = error; + this.complete = complete; + } + DoOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete)); + }; + return DoOperator; + }()); + var TapSubscriber = /*@__PURE__*/ (function (_super) { + __extends(TapSubscriber, _super); + function TapSubscriber(destination, observerOrNext, error, complete) { + var _this = _super.call(this, destination) || this; + _this._tapNext = noop; + _this._tapError = noop; + _this._tapComplete = noop; + _this._tapError = error || noop; + _this._tapComplete = complete || noop; + if (isFunction$1(observerOrNext)) { + _this._context = _this; + _this._tapNext = observerOrNext; + } + else if (observerOrNext) { + _this._context = observerOrNext; + _this._tapNext = observerOrNext.next || noop; + _this._tapError = observerOrNext.error || noop; + _this._tapComplete = observerOrNext.complete || noop; + } + return _this; + } + TapSubscriber.prototype._next = function (value) { + try { + this._tapNext.call(this._context, value); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(value); + }; + TapSubscriber.prototype._error = function (err) { + try { + this._tapError.call(this._context, err); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.error(err); + }; + TapSubscriber.prototype._complete = function () { + try { + this._tapComplete.call(this._context); + } + catch (err) { + this.destination.error(err); + return; + } + return this.destination.complete(); + }; + return TapSubscriber; + }(Subscriber)); + + /** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + var defaultThrottleConfig = { + leading: true, + trailing: false + }; + + /** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ + function throttleTime(duration, scheduler, config) { + if (scheduler === void 0) { + scheduler = async; + } + if (config === void 0) { + config = defaultThrottleConfig; + } + return function (source) { return source.lift(new ThrottleTimeOperator(duration, scheduler, config.leading, config.trailing)); }; + } + var ThrottleTimeOperator = /*@__PURE__*/ (function () { + function ThrottleTimeOperator(duration, scheduler, leading, trailing) { + this.duration = duration; + this.scheduler = scheduler; + this.leading = leading; + this.trailing = trailing; + } + ThrottleTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ThrottleTimeSubscriber(subscriber, this.duration, this.scheduler, this.leading, this.trailing)); + }; + return ThrottleTimeOperator; + }()); + var ThrottleTimeSubscriber = /*@__PURE__*/ (function (_super) { + __extends(ThrottleTimeSubscriber, _super); + function ThrottleTimeSubscriber(destination, duration, scheduler, leading, trailing) { + var _this = _super.call(this, destination) || this; + _this.duration = duration; + _this.scheduler = scheduler; + _this.leading = leading; + _this.trailing = trailing; + _this._hasTrailingValue = false; + _this._trailingValue = null; + return _this; + } + ThrottleTimeSubscriber.prototype._next = function (value) { + if (this.throttled) { + if (this.trailing) { + this._trailingValue = value; + this._hasTrailingValue = true; + } + } + else { + this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, { subscriber: this })); + if (this.leading) { + this.destination.next(value); + } + else if (this.trailing) { + this._trailingValue = value; + this._hasTrailingValue = true; + } + } + }; + ThrottleTimeSubscriber.prototype._complete = function () { + if (this._hasTrailingValue) { + this.destination.next(this._trailingValue); + this.destination.complete(); + } + else { + this.destination.complete(); + } + }; + ThrottleTimeSubscriber.prototype.clearThrottle = function () { + var throttled = this.throttled; + if (throttled) { + if (this.trailing && this._hasTrailingValue) { + this.destination.next(this._trailingValue); + this._trailingValue = null; + this._hasTrailingValue = false; + } + throttled.unsubscribe(); + this.remove(throttled); + this.throttled = null; + } + }; + return ThrottleTimeSubscriber; + }(Subscriber)); + function dispatchNext(arg) { + var subscriber = arg.subscriber; + subscriber.clearThrottle(); + } + + /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_innerSubscribe PURE_IMPORTS_END */ + function timeoutWith(due, withObservable, scheduler) { + if (scheduler === void 0) { + scheduler = async; + } + return function (source) { + var absoluteTimeout = isDate(due); + var waitFor = absoluteTimeout ? (+due - scheduler.now()) : Math.abs(due); + return source.lift(new TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler)); + }; + } + var TimeoutWithOperator = /*@__PURE__*/ (function () { + function TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler) { + this.waitFor = waitFor; + this.absoluteTimeout = absoluteTimeout; + this.withObservable = withObservable; + this.scheduler = scheduler; + } + TimeoutWithOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TimeoutWithSubscriber(subscriber, this.absoluteTimeout, this.waitFor, this.withObservable, this.scheduler)); + }; + return TimeoutWithOperator; + }()); + var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { + __extends(TimeoutWithSubscriber, _super); + function TimeoutWithSubscriber(destination, absoluteTimeout, waitFor, withObservable, scheduler) { + var _this = _super.call(this, destination) || this; + _this.absoluteTimeout = absoluteTimeout; + _this.waitFor = waitFor; + _this.withObservable = withObservable; + _this.scheduler = scheduler; + _this.scheduleTimeout(); + return _this; + } + TimeoutWithSubscriber.dispatchTimeout = function (subscriber) { + var withObservable = subscriber.withObservable; + subscriber._unsubscribeAndRecycle(); + subscriber.add(innerSubscribe(withObservable, new SimpleInnerSubscriber(subscriber))); + }; + TimeoutWithSubscriber.prototype.scheduleTimeout = function () { + var action = this.action; + if (action) { + this.action = action.schedule(this, this.waitFor); + } + else { + this.add(this.action = this.scheduler.schedule(TimeoutWithSubscriber.dispatchTimeout, this.waitFor, this)); + } + }; + TimeoutWithSubscriber.prototype._next = function (value) { + if (!this.absoluteTimeout) { + this.scheduleTimeout(); + } + _super.prototype._next.call(this, value); + }; + TimeoutWithSubscriber.prototype._unsubscribe = function () { + this.action = undefined; + this.scheduler = null; + this.withObservable = null; + }; + return TimeoutWithSubscriber; + }(SimpleOuterSubscriber)); + + /** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ + function timeout(due, scheduler) { + if (scheduler === void 0) { + scheduler = async; + } + return timeoutWith(due, throwError(new TimeoutError()), scheduler); + } + + /** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + function withLatestFrom() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return function (source) { + var project; + if (typeof args[args.length - 1] === 'function') { + project = args.pop(); + } + var observables = args; + return source.lift(new WithLatestFromOperator(observables, project)); + }; + } + var WithLatestFromOperator = /*@__PURE__*/ (function () { + function WithLatestFromOperator(observables, project) { + this.observables = observables; + this.project = project; + } + WithLatestFromOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project)); + }; + return WithLatestFromOperator; + }()); + var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { + __extends(WithLatestFromSubscriber, _super); + function WithLatestFromSubscriber(destination, observables, project) { + var _this = _super.call(this, destination) || this; + _this.observables = observables; + _this.project = project; + _this.toRespond = []; + var len = observables.length; + _this.values = new Array(len); + for (var i = 0; i < len; i++) { + _this.toRespond.push(i); + } + for (var i = 0; i < len; i++) { + var observable = observables[i]; + _this.add(subscribeToResult(_this, observable, undefined, i)); + } + return _this; + } + WithLatestFromSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { + this.values[outerIndex] = innerValue; + var toRespond = this.toRespond; + if (toRespond.length > 0) { + var found = toRespond.indexOf(outerIndex); + if (found !== -1) { + toRespond.splice(found, 1); + } + } + }; + WithLatestFromSubscriber.prototype.notifyComplete = function () { + }; + WithLatestFromSubscriber.prototype._next = function (value) { + if (this.toRespond.length === 0) { + var args = [value].concat(this.values); + if (this.project) { + this._tryProject(args); + } + else { + this.destination.next(args); + } + } + }; + WithLatestFromSubscriber.prototype._tryProject = function (args) { + var result; + try { + result = this.project.apply(this, args); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return WithLatestFromSubscriber; + }(OuterSubscriber)); + + var currentAction = { + type: null, + entityIds: null, + skip: false, + }; + var customActionActive = false; + function resetCustomAction() { + customActionActive = false; + } + // public API for custom actions. Custom action always wins + function logAction(type, entityIds) { + setAction(type, entityIds); + customActionActive = true; + } + function setAction(type, entityIds) { + if (customActionActive === false) { + currentAction.type = type; + currentAction.entityIds = entityIds; + } + } + function action(action, entityIds) { + return function (target, propertyKey, descriptor) { + var originalMethod = descriptor.value; + descriptor.value = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + logAction(action, entityIds); + return originalMethod.apply(this, args); + }; + return descriptor; + }; + } + + // @internal + function hasEntity(entities, id) { + return entities.hasOwnProperty(id); + } + + // @internal + function addEntities(_a) { + var state = _a.state, entities = _a.entities, idKey = _a.idKey, _b = _a.options, options = _b === void 0 ? {} : _b, preAddEntity = _a.preAddEntity; + var e_1, _c; + var newEntities = {}; + var newIds = []; + var hasNewEntities = false; + try { + for (var entities_1 = __values(entities), entities_1_1 = entities_1.next(); !entities_1_1.done; entities_1_1 = entities_1.next()) { + var entity = entities_1_1.value; + if (hasEntity(state.entities, entity[idKey]) === false) { + // evaluate the middleware first to support dynamic ids + var current = preAddEntity(entity); + var entityId = current[idKey]; + newEntities[entityId] = current; + if (options.prepend) + newIds.unshift(entityId); + else + newIds.push(entityId); + hasNewEntities = true; + } + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (entities_1_1 && !entities_1_1.done && (_c = entities_1.return)) _c.call(entities_1); + } + finally { if (e_1) throw e_1.error; } + } + return hasNewEntities + ? { + newState: __assign({}, state, { entities: __assign({}, state.entities, newEntities), ids: options.prepend ? __spread(newIds, state.ids) : __spread(state.ids, newIds) }), + newIds: newIds + } + : null; + } + + // @internal + function isNil(v) { + return v === null || v === undefined; + } + + // @internal + function coerceArray(value) { + if (isNil(value)) { + return []; + } + return Array.isArray(value) ? value : [value]; + } + + var DEFAULT_ID_KEY = 'id'; + + var EntityActions; + (function (EntityActions) { + EntityActions["Set"] = "Set"; + EntityActions["Add"] = "Add"; + EntityActions["Update"] = "Update"; + EntityActions["Remove"] = "Remove"; + })(EntityActions || (EntityActions = {})); + + var isBrowser = typeof window !== 'undefined'; + + // @internal + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + // @internal + function isArray(value) { + return Array.isArray(value); + } + + // @internal + function getActiveEntities(idOrOptions, ids, currentActive) { + var result; + if (isArray(idOrOptions)) { + result = idOrOptions; + } + else { + if (isObject(idOrOptions)) { + if (isNil(currentActive)) + return; + idOrOptions = Object.assign({ wrap: true }, idOrOptions); + var currentIdIndex = ids.indexOf(currentActive); + if (idOrOptions.prev) { + var isFirst = currentIdIndex === 0; + if (isFirst && !idOrOptions.wrap) + return; + result = isFirst ? ids[ids.length - 1] : ids[currentIdIndex - 1]; + } + else if (idOrOptions.next) { + var isLast = ids.length === currentIdIndex + 1; + if (isLast && !idOrOptions.wrap) + return; + result = isLast ? ids[0] : ids[currentIdIndex + 1]; + } + } + else { + if (idOrOptions === currentActive) + return; + result = idOrOptions; + } + } + return result; + } + + // @internal + var getInitialEntitiesState = function () { + return ({ + entities: {}, + ids: [], + loading: true, + error: null + }); + }; + + // @internal + function isDefined(val) { + return isNil(val) === false; + } + + // @internal + function isEmpty(arr) { + if (isArray(arr)) { + return arr.length === 0; + } + return false; + } + + // @internal + function isFunction(value) { + return typeof value === 'function'; + } + + // @internal + function isUndefined(value) { + return value === undefined; + } + + // @internal + function hasActiveState(state) { + return state.hasOwnProperty('active'); + } + // @internal + function isMultiActiveState(active) { + return isArray(active); + } + // @internal + function resolveActiveEntity(_a) { + var active = _a.active, ids = _a.ids, entities = _a.entities; + if (isMultiActiveState(active)) { + return getExitingActives(active, ids); + } + if (hasEntity(entities, active) === false) { + return null; + } + return active; + } + // @internal + function getExitingActives(currentActivesIds, newIds) { + var filtered = currentActivesIds.filter(function (id) { return newIds.indexOf(id) > -1; }); + /** Return the same reference if nothing has changed */ + if (filtered.length === currentActivesIds.length) { + return currentActivesIds; + } + return filtered; + } + + // @internal + function removeEntities(_a) { + var state = _a.state, ids = _a.ids; + var e_1, _b; + if (isNil(ids)) + return removeAllEntities(state); + var entities = state.entities; + var newEntities = {}; + try { + for (var _c = __values(state.ids), _d = _c.next(); !_d.done; _d = _c.next()) { + var id = _d.value; + if (ids.includes(id) === false) { + newEntities[id] = entities[id]; + } + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (_d && !_d.done && (_b = _c.return)) _b.call(_c); + } + finally { if (e_1) throw e_1.error; } + } + var newState = __assign({}, state, { entities: newEntities, ids: state.ids.filter(function (current) { return ids.includes(current) === false; }) }); + if (hasActiveState(state)) { + newState.active = resolveActiveEntity(newState); + } + return newState; + } + // @internal + function removeAllEntities(state) { + return __assign({}, state, { entities: {}, ids: [], active: isMultiActiveState(state.active) ? [] : null }); + } + + // @internal + function toEntitiesObject(entities, idKey, preAddEntity) { + var e_1, _a; + var acc = { + entities: {}, + ids: [] + }; + try { + for (var entities_1 = __values(entities), entities_1_1 = entities_1.next(); !entities_1_1.done; entities_1_1 = entities_1.next()) { + var entity = entities_1_1.value; + // evaluate the middleware first to support dynamic ids + var current = preAddEntity(entity); + acc.entities[current[idKey]] = current; + acc.ids.push(current[idKey]); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1); + } + finally { if (e_1) throw e_1.error; } + } + return acc; + } + + // @internal + function isEntityState(state) { + return state.entities && state.ids; + } + // @internal + function applyMiddleware(entities, preAddEntity) { + var e_1, _a; + var mapped = {}; + try { + for (var _b = __values(Object.keys(entities)), _c = _b.next(); !_c.done; _c = _b.next()) { + var id = _c.value; + mapped[id] = preAddEntity(entities[id]); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } + finally { if (e_1) throw e_1.error; } + } + return mapped; + } + // @internal + function setEntities(_a) { + var state = _a.state, entities = _a.entities, idKey = _a.idKey, preAddEntity = _a.preAddEntity, isNativePreAdd = _a.isNativePreAdd; + var newEntities; + var newIds; + if (isArray(entities)) { + var resolve = toEntitiesObject(entities, idKey, preAddEntity); + newEntities = resolve.entities; + newIds = resolve.ids; + } + else if (isEntityState(entities)) { + newEntities = isNativePreAdd ? entities.entities : applyMiddleware(entities.entities, preAddEntity); + newIds = entities.ids; + } + else { + // it's an object + newEntities = isNativePreAdd ? entities : applyMiddleware(entities, preAddEntity); + newIds = Object.keys(newEntities).map(function (id) { return (isNaN(id) ? id : Number(id)); }); + } + var newState = __assign({}, state, { entities: newEntities, ids: newIds, loading: false }); + if (hasActiveState(state)) { + newState.active = resolveActiveEntity(newState); + } + return newState; + } + + var CONFIG = { + resettable: false, + ttl: null, + producerFn: undefined + }; + // @internal + function getAkitaConfig() { + return CONFIG; + } + function getGlobalProducerFn() { + return CONFIG.producerFn; + } + + // @internal + function deepFreeze(o) { + Object.freeze(o); + var oIsFunction = typeof o === 'function'; + var hasOwnProp = Object.prototype.hasOwnProperty; + Object.getOwnPropertyNames(o).forEach(function (prop) { + if (hasOwnProp.call(o, prop) && + (oIsFunction ? prop !== 'caller' && prop !== 'callee' && prop !== 'arguments' : true) && + o[prop] !== null && + (typeof o[prop] === 'object' || typeof o[prop] === 'function') && + !Object.isFrozen(o[prop])) { + deepFreeze(o[prop]); + } + }); + return o; + } + + // @internal + var $$deleteStore = new Subject(); + // @internal + var $$addStore = new ReplaySubject(50, 5000); + // @internal + var $$updateStore = new Subject(); + // @internal + function dispatchDeleted(storeName) { + $$deleteStore.next(storeName); + } + // @internal + function dispatchAdded(storeName) { + $$addStore.next(storeName); + } + // @internal + function dispatchUpdate(storeName, action) { + $$updateStore.next({ storeName: storeName, action: action }); + } + + // @internal + /** @class */ ((function (_super) { + __extends(AkitaError, _super); + function AkitaError(message) { + return _super.call(this, message) || this; + } + return AkitaError; + })(Error)); + // @internal + function assertStoreHasName(name, className) { + if (!name) { + console.error("@StoreConfig({ name }) is missing in " + className); + } + } + + // @internal + function toBoolean(value) { + return value != null && "" + value !== 'false'; + } + + // @internal + function isPlainObject$1(value) { + return toBoolean(value) && value.constructor.name === 'Object'; + } + + var configKey = 'akitaConfig'; + + // @internal + var __stores__ = {}; + // @internal + var __queries__ = {}; + if (isBrowser) { + window.$$stores = __stores__; + window.$$queries = __queries__; + } + + // @internal + var transactionFinished = new Subject(); + // @internal + var transactionInProcess = new BehaviorSubject(false); + // @internal + var transactionManager = { + activeTransactions: 0, + batchTransaction: null + }; + // @internal + function startBatch() { + if (!isTransactionInProcess()) { + transactionManager.batchTransaction = new Subject(); + } + transactionManager.activeTransactions++; + transactionInProcess.next(true); + } + // @internal + function endBatch() { + if (--transactionManager.activeTransactions === 0) { + transactionManager.batchTransaction.next(true); + transactionManager.batchTransaction.complete(); + transactionInProcess.next(false); + transactionFinished.next(true); + } + } + // @internal + function isTransactionInProcess() { + return transactionManager.activeTransactions > 0; + } + // @internal + function commit() { + return transactionManager.batchTransaction ? transactionManager.batchTransaction.asObservable() : of(true); + } + /** + * A logical transaction. + * Use this transaction to optimize the dispatch of all the stores. + * The following code will update the store, BUT emits only once + * + * @example + * applyTransaction(() => { + * this.todosStore.add(new Todo(1, title)); + * this.todosStore.add(new Todo(2, title)); + * }); + * + */ + function applyTransaction(action, thisArg) { + if (thisArg === void 0) { thisArg = undefined; } + startBatch(); + try { + return action.apply(thisArg); + } + finally { + logAction('@Transaction'); + endBatch(); + } + } + /** + * A logical transaction. + * Use this transaction to optimize the dispatch of all the stores. + * + * The following code will update the store, BUT emits only once. + * + * @example + * @transaction + * addTodos() { + * this.todosStore.add(new Todo(1, title)); + * this.todosStore.add(new Todo(2, title)); + * } + * + * + */ + function transaction() { + return function (target, propertyKey, descriptor) { + var originalMethod = descriptor.value; + descriptor.value = function () { + var _this = this; + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return applyTransaction(function () { + return originalMethod.apply(_this, args); + }, this); + }; + return descriptor; + }; + } + /** + * + * RxJS custom operator that wraps the callback inside transaction + * + * @example + * + * return http.get().pipe( + * withTransaction(response > { + * store.setActive(1); + * store.update(); + * store.updateEntity(1, {}); + * }) + * ) + * + */ + function withTransaction(next) { + return function (source) { + return source.pipe(tap(function (value) { return applyTransaction(function () { return next(value); }); })); + }; + } + + /** + * + * Store for managing any type of data + * + * @example + * + * export interface SessionState { + * token: string; + * userDetails: UserDetails + * } + * + * export function createInitialState(): SessionState { + * return { + * token: '', + * userDetails: null + * }; + * } + * + * @StoreConfig({ name: 'session' }) + * export class SessionStore extends Store { + * constructor() { + * super(createInitialState()); + * } + * } + */ + var Store = /** @class */ (function () { + function Store(initialState, options) { + if (options === void 0) { options = {}; } + this.options = options; + this.inTransaction = false; + this.cache = { + active: new BehaviorSubject(false), + ttl: null, + }; + this.onInit(initialState); + } + /** + * Set the loading state + * + * @example + * + * store.setLoading(true) + * + */ + Store.prototype.setLoading = function (loading) { + if (loading === void 0) { loading = false; } + if (loading !== this._value().loading) { + setAction('Set Loading'); + this._setState(function (state) { return (__assign({}, state, { loading: loading })); }); + } + }; + /** + * + * Set whether the data is cached + * + * @example + * + * store.setHasCache(true) + * store.setHasCache(false) + * store.setHasCache(true, { restartTTL: true }) + * + */ + Store.prototype.setHasCache = function (hasCache, options) { + var _this = this; + if (options === void 0) { options = { restartTTL: false }; } + if (hasCache !== this.cache.active.value) { + this.cache.active.next(hasCache); + } + if (options.restartTTL) { + var ttlConfig = this.getCacheTTL(); + if (ttlConfig) { + if (this.cache.ttl !== null) { + clearTimeout(this.cache.ttl); + } + this.cache.ttl = setTimeout(function () { return _this.setHasCache(false); }, ttlConfig); + } + } + }; + /** + * + * Sometimes we need to access the store value from a store + * + * @example middleware + * + */ + Store.prototype.getValue = function () { + return this.storeValue; + }; + /** + * Set the error state + * + * @example + * + * store.setError({text: 'unable to load data' }) + * + */ + Store.prototype.setError = function (error) { + if (error !== this._value().error) { + setAction('Set Error'); + this._setState(function (state) { return (__assign({}, state, { error: error })); }); + } + }; + // @internal + Store.prototype._select = function (project) { + return this.store.asObservable().pipe(map(function (snapshot) { return project(snapshot.state); }), distinctUntilChanged()); + }; + // @internal + Store.prototype._value = function () { + return this.storeValue; + }; + // @internal + Store.prototype._cache = function () { + return this.cache.active; + }; + Object.defineProperty(Store.prototype, "config", { + // @internal + get: function () { + return this.constructor[configKey] || {}; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Store.prototype, "storeName", { + // @internal + get: function () { + return this.config.storeName || this.options.storeName || this.options.name; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Store.prototype, "deepFreeze", { + // @internal + get: function () { + return this.config.deepFreezeFn || this.options.deepFreezeFn || deepFreeze; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Store.prototype, "cacheConfig", { + // @internal + get: function () { + return this.config.cache || this.options.cache; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Store.prototype, "_producerFn", { + get: function () { + return this.config.producerFn || this.options.producerFn || getGlobalProducerFn(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Store.prototype, "resettable", { + // @internal + get: function () { + return isDefined(this.config.resettable) ? this.config.resettable : this.options.resettable; + }, + enumerable: true, + configurable: true + }); + // @internal + Store.prototype._setState = function (newState, _dispatchAction) { + var _this = this; + if (_dispatchAction === void 0) { _dispatchAction = true; } + if (isFunction(newState)) { + var _newState = newState(this._value()); + this.storeValue = this.deepFreeze(_newState) ; + } + else { + this.storeValue = newState; + } + if (!this.store) { + this.store = new BehaviorSubject({ state: this.storeValue }); + { + this.store.subscribe(function (_a) { + var action = _a.action; + if (action) { + dispatchUpdate(_this.storeName, action); + } + }); + } + return; + } + if (isTransactionInProcess()) { + this.handleTransaction(); + return; + } + this.dispatch(this.storeValue, _dispatchAction); + }; + /** + * + * Reset the current store back to the initial value + * + * @example + * + * store.reset() + * + */ + Store.prototype.reset = function () { + var _this = this; + if (this.isResettable()) { + setAction('Reset'); + this._setState(function () { return Object.assign({}, _this._initialState); }); + this.setHasCache(false); + } + else { + console.warn("You need to enable the reset functionality"); + } + }; + Store.prototype.update = function (stateOrCallback) { + setAction('Update'); + var newState; + var currentState = this._value(); + if (isFunction(stateOrCallback)) { + newState = isFunction(this._producerFn) ? this._producerFn(currentState, stateOrCallback) : stateOrCallback(currentState); + } + else { + newState = stateOrCallback; + } + var withHook = this.akitaPreUpdate(currentState, __assign({}, currentState, newState)); + var resolved = isPlainObject$1(currentState) ? withHook : new currentState.constructor(withHook); + this._setState(resolved); + }; + Store.prototype.updateStoreConfig = function (newOptions) { + this.options = __assign({}, this.options, newOptions); + }; + // @internal + Store.prototype.akitaPreUpdate = function (_, nextState) { + return nextState; + }; + Store.prototype.ngOnDestroy = function () { + this.destroy(); + }; + /** + * + * Destroy the store + * + * @example + * + * store.destroy() + * + */ + Store.prototype.destroy = function () { + var hmrEnabled = isBrowser ? window.hmrEnabled : false; + if (!hmrEnabled && this === __stores__[this.storeName]) { + delete __stores__[this.storeName]; + dispatchDeleted(this.storeName); + this.setHasCache(false); + this.cache.active.complete(); + this.store.complete(); + } + }; + Store.prototype.onInit = function (initialState) { + __stores__[this.storeName] = this; + this._setState(function () { return initialState; }); + dispatchAdded(this.storeName); + if (this.isResettable()) { + this._initialState = initialState; + } + assertStoreHasName(this.storeName, this.constructor.name); + }; + Store.prototype.dispatch = function (state, _dispatchAction) { + if (_dispatchAction === void 0) { _dispatchAction = true; } + var action = undefined; + if (_dispatchAction) { + action = currentAction; + resetCustomAction(); + } + this.store.next({ state: state, action: action }); + }; + Store.prototype.watchTransaction = function () { + var _this = this; + commit().subscribe(function () { + _this.inTransaction = false; + _this.dispatch(_this._value()); + }); + }; + Store.prototype.isResettable = function () { + if (this.resettable === false) { + return false; + } + return this.resettable || getAkitaConfig().resettable; + }; + Store.prototype.handleTransaction = function () { + if (!this.inTransaction) { + this.watchTransaction(); + this.inTransaction = true; + } + }; + Store.prototype.getCacheTTL = function () { + return (this.cacheConfig && this.cacheConfig.ttl) || getAkitaConfig().ttl; + }; + return Store; + }()); + + // @internal + function updateEntities(_a) { + var state = _a.state, ids = _a.ids, idKey = _a.idKey, newStateOrFn = _a.newStateOrFn, preUpdateEntity = _a.preUpdateEntity, producerFn = _a.producerFn, onEntityIdChanges = _a.onEntityIdChanges; + var e_1, _b; + var updatedEntities = {}; + var isUpdatingIdKey = false; + var idToUpdate; + try { + for (var ids_1 = __values(ids), ids_1_1 = ids_1.next(); !ids_1_1.done; ids_1_1 = ids_1.next()) { + var id = ids_1_1.value; + // if the entity doesn't exist don't do anything + if (hasEntity(state.entities, id) === false) { + continue; + } + var oldEntity = state.entities[id]; + var newState = void 0; + if (isFunction(newStateOrFn)) { + newState = isFunction(producerFn) ? producerFn(oldEntity, newStateOrFn) : newStateOrFn(oldEntity); + } + else { + newState = newStateOrFn; + } + var isIdChanged = newState.hasOwnProperty(idKey) && newState[idKey] !== oldEntity[idKey]; + var newEntity = void 0; + idToUpdate = id; + if (isIdChanged) { + isUpdatingIdKey = true; + idToUpdate = newState[idKey]; + } + var merged = __assign({}, oldEntity, newState); + if (isPlainObject$1(oldEntity)) { + newEntity = merged; + } + else { + /** + * In case that new state is class of it's own, there's + * a possibility that it will be different than the old + * class. + * For example, Old state is an instance of animal class + * and new state is instance of person class. + * To avoid run over new person class with the old animal + * class we check if the new state is a class of it's own. + * If so, use it. Otherwise, use the old state class + */ + if (isPlainObject$1(newState)) { + newEntity = new oldEntity.constructor(merged); + } + else { + newEntity = new newState.constructor(merged); + } + } + updatedEntities[idToUpdate] = preUpdateEntity(oldEntity, newEntity); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (ids_1_1 && !ids_1_1.done && (_b = ids_1.return)) _b.call(ids_1); + } + finally { if (e_1) throw e_1.error; } + } + var updatedIds = state.ids; + var stateEntities = state.entities; + if (isUpdatingIdKey) { + var _c = __read(ids, 1), id_1 = _c[0]; + var _d = state.entities, _e = id_1, rest = __rest(_d, [typeof _e === "symbol" ? _e : _e + ""]); + stateEntities = rest; + updatedIds = state.ids.map(function (current) { return (current === id_1 ? idToUpdate : current); }); + onEntityIdChanges(id_1, idToUpdate); + } + return __assign({}, state, { entities: __assign({}, stateEntities, updatedEntities), ids: updatedIds }); + } + + /** + * + * Store for managing a collection of entities + * + * @example + * + * export interface WidgetsState extends EntityState { } + * + * @StoreConfig({ name: 'widgets' }) + * export class WidgetsStore extends EntityStore { + * constructor() { + * super(); + * } + * } + * + * + */ + var EntityStore = /** @class */ (function (_super) { + __extends(EntityStore, _super); + function EntityStore(initialState, options) { + if (initialState === void 0) { initialState = {}; } + if (options === void 0) { options = {}; } + var _this = _super.call(this, __assign({}, getInitialEntitiesState(), initialState), options) || this; + _this.options = options; + _this.entityActions = new Subject(); + _this.entityIdChanges = new Subject(); + return _this; + } + Object.defineProperty(EntityStore.prototype, "selectEntityAction$", { + // @internal + get: function () { + return this.entityActions.asObservable(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntityStore.prototype, "selectEntityIdChanges$", { + // @internal + get: function () { + return this.entityIdChanges.asObservable(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntityStore.prototype, "idKey", { + // @internal + get: function () { + return this.config.idKey || this.options.idKey || DEFAULT_ID_KEY; + }, + enumerable: true, + configurable: true + }); + /** + * + * Replace current collection with provided collection + * + * @example + * + * this.store.set([Entity, Entity]) + * this.store.set({ids: [], entities: {}}) + * this.store.set({ 1: {}, 2: {}}) + * + */ + EntityStore.prototype.set = function (entities, options) { + var _this = this; + if (options === void 0) { options = {}; } + if (isNil(entities)) + return; + setAction('Set Entity'); + var isNativePreAdd = this.akitaPreAddEntity === EntityStore.prototype.akitaPreAddEntity; + this.setHasCache(true, { restartTTL: true }); + this._setState(function (state) { + var newState = setEntities({ + state: state, + entities: entities, + idKey: _this.idKey, + preAddEntity: _this.akitaPreAddEntity, + isNativePreAdd: isNativePreAdd, + }); + if (isUndefined(options.activeId) === false) { + newState.active = options.activeId; + } + return newState; + }); + if (this.hasInitialUIState()) { + this.handleUICreation(); + } + this.entityActions.next({ type: EntityActions.Set, ids: this.ids }); + }; + /** + * Add entities + * + * @example + * + * this.store.add([Entity, Entity]) + * this.store.add(Entity) + * this.store.add(Entity, { prepend: true }) + * + * this.store.add(Entity, { loading: false }) + */ + EntityStore.prototype.add = function (entities, options) { + if (options === void 0) { options = { loading: false }; } + var collection = coerceArray(entities); + if (isEmpty(collection)) + return; + var data = addEntities({ + state: this._value(), + preAddEntity: this.akitaPreAddEntity, + entities: collection, + idKey: this.idKey, + options: options, + }); + if (data) { + setAction('Add Entity'); + data.newState.loading = options.loading; + this._setState(function () { return data.newState; }); + if (this.hasInitialUIState()) { + this.handleUICreation(true); + } + this.entityActions.next({ type: EntityActions.Add, ids: data.newIds }); + } + }; + EntityStore.prototype.update = function (idsOrFnOrState, newStateOrFn) { + var _this = this; + if (isUndefined(newStateOrFn)) { + _super.prototype.update.call(this, idsOrFnOrState); + return; + } + var ids = []; + if (isFunction(idsOrFnOrState)) { + // We need to filter according the predicate function + ids = this.ids.filter(function (id) { return idsOrFnOrState(_this.entities[id]); }); + } + else { + // If it's nil we want all of them + ids = isNil(idsOrFnOrState) ? this.ids : coerceArray(idsOrFnOrState); + } + if (isEmpty(ids)) + return; + setAction('Update Entity', ids); + var entityIdChanged; + this._setState(function (state) { + return updateEntities({ + idKey: _this.idKey, + ids: ids, + preUpdateEntity: _this.akitaPreUpdateEntity, + state: state, + newStateOrFn: newStateOrFn, + producerFn: _this._producerFn, + onEntityIdChanges: function (oldId, newId) { + entityIdChanged = { oldId: oldId, newId: newId }; + _this.entityIdChanges.next(__assign({}, entityIdChanged, { pending: true })); + }, + }); + }); + if (entityIdChanged) { + this.entityIdChanges.next(__assign({}, entityIdChanged, { pending: false })); + } + this.entityActions.next({ type: EntityActions.Update, ids: ids }); + }; + EntityStore.prototype.upsert = function (ids, newState, onCreate, options) { + var _this = this; + if (options === void 0) { options = {}; } + var toArray = coerceArray(ids); + var predicate = function (isUpdate) { return function (id) { return hasEntity(_this.entities, id) === isUpdate; }; }; + var baseClass = isFunction(onCreate) ? options.baseClass : onCreate ? onCreate.baseClass : undefined; + var isClassBased = isFunction(baseClass); + var updateIds = toArray.filter(predicate(true)); + var newEntities = toArray.filter(predicate(false)).map(function (id) { + var _a; + var newStateObj = typeof newState === 'function' ? newState({}) : newState; + var entity = isFunction(onCreate) ? onCreate(id, newStateObj) : newStateObj; + var withId = __assign({}, entity, (_a = {}, _a[_this.idKey] = id, _a)); + if (isClassBased) { + return new baseClass(withId); + } + return withId; + }); + // it can be any of the three types + this.update(updateIds, newState); + this.add(newEntities); + logAction('Upsert Entity'); + }; + /** + * + * Upsert entity collection (idKey must be present) + * + * @example + * + * store.upsertMany([ { id: 1 }, { id: 2 }]); + * + * store.upsertMany([ { id: 1 }, { id: 2 }], { loading: true }); + * store.upsertMany([ { id: 1 }, { id: 2 }], { baseClass: Todo }); + * + */ + EntityStore.prototype.upsertMany = function (entities, options) { + if (options === void 0) { options = {}; } + var e_1, _a; + var addedIds = []; + var updatedIds = []; + var updatedEntities = {}; + try { + // Update the state directly to optimize performance + for (var entities_1 = __values(entities), entities_1_1 = entities_1.next(); !entities_1_1.done; entities_1_1 = entities_1.next()) { + var entity = entities_1_1.value; + var withPreCheckHook = this.akitaPreCheckEntity(entity); + var id = withPreCheckHook[this.idKey]; + if (hasEntity(this.entities, id)) { + var prev = this._value().entities[id]; + var merged = __assign({}, this._value().entities[id], withPreCheckHook); + var next = options.baseClass ? new options.baseClass(merged) : merged; + var withHook = this.akitaPreUpdateEntity(prev, next); + var nextId = withHook[this.idKey]; + updatedEntities[nextId] = withHook; + updatedIds.push(nextId); + } + else { + var newEntity = options.baseClass ? new options.baseClass(withPreCheckHook) : withPreCheckHook; + var withHook = this.akitaPreAddEntity(newEntity); + var nextId = withHook[this.idKey]; + addedIds.push(nextId); + updatedEntities[nextId] = withHook; + } + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1); + } + finally { if (e_1) throw e_1.error; } + } + logAction('Upsert Many'); + this._setState(function (state) { return (__assign({}, state, { ids: addedIds.length ? __spread(state.ids, addedIds) : state.ids, entities: __assign({}, state.entities, updatedEntities), loading: !!options.loading })); }); + updatedIds.length && this.entityActions.next({ type: EntityActions.Update, ids: updatedIds }); + addedIds.length && this.entityActions.next({ type: EntityActions.Add, ids: addedIds }); + if (addedIds.length && this.hasUIStore()) { + this.handleUICreation(true); + } + }; + /** + * + * Replace one or more entities (except the id property) + * + * + * @example + * + * this.store.replace(5, newEntity) + * this.store.replace([1,2,3], newEntity) + */ + EntityStore.prototype.replace = function (ids, newState) { + var e_2, _a; + var toArray = coerceArray(ids); + if (isEmpty(toArray)) + return; + var replaced = {}; + try { + for (var toArray_1 = __values(toArray), toArray_1_1 = toArray_1.next(); !toArray_1_1.done; toArray_1_1 = toArray_1.next()) { + var id = toArray_1_1.value; + newState[this.idKey] = id; + replaced[id] = newState; + } + } + catch (e_2_1) { e_2 = { error: e_2_1 }; } + finally { + try { + if (toArray_1_1 && !toArray_1_1.done && (_a = toArray_1.return)) _a.call(toArray_1); + } + finally { if (e_2) throw e_2.error; } + } + setAction('Replace Entity', ids); + this._setState(function (state) { return (__assign({}, state, { entities: __assign({}, state.entities, replaced) })); }); + }; + /** + * + * Move entity inside the collection + * + * + * @example + * + * this.store.move(fromIndex, toIndex) + */ + EntityStore.prototype.move = function (from, to) { + var ids = this.ids.slice(); + ids.splice(to < 0 ? ids.length + to : to, 0, ids.splice(from, 1)[0]); + setAction('Move Entity'); + this._setState(function (state) { return (__assign({}, state, { + // Change the entities reference so that selectAll emit + entities: __assign({}, state.entities), ids: ids })); }); + }; + EntityStore.prototype.remove = function (idsOrFn) { + var _this = this; + if (isEmpty(this.ids)) + return; + var idPassed = isDefined(idsOrFn); + // null means remove all + var ids = []; + if (isFunction(idsOrFn)) { + ids = this.ids.filter(function (entityId) { return idsOrFn(_this.entities[entityId]); }); + } + else { + ids = idPassed ? coerceArray(idsOrFn) : this.ids; + } + if (isEmpty(ids)) + return; + setAction('Remove Entity', ids); + this._setState(function (state) { return removeEntities({ state: state, ids: ids }); }); + if (!idPassed) { + this.setHasCache(false); + } + this.handleUIRemove(ids); + this.entityActions.next({ type: EntityActions.Remove, ids: ids }); + }; + /** + * + * Update the active entity + * + * @example + * + * this.store.updateActive({ completed: true }) + * this.store.updateActive(active => { + * return { + * config: { + * ..active.config, + * date + * } + * } + * }) + */ + EntityStore.prototype.updateActive = function (newStateOrCallback) { + var ids = coerceArray(this.active); + setAction('Update Active', ids); + this.update(ids, newStateOrCallback); + }; + EntityStore.prototype.setActive = function (idOrOptions) { + var active = getActiveEntities(idOrOptions, this.ids, this.active); + if (active === undefined) { + return; + } + setAction('Set Active', active); + this._setActive(active); + }; + /** + * Add active entities + * + * @example + * + * store.addActive(2); + * store.addActive([3, 4, 5]); + */ + EntityStore.prototype.addActive = function (ids) { + var _this = this; + var toArray = coerceArray(ids); + if (isEmpty(toArray)) + return; + var everyExist = toArray.every(function (id) { return _this.active.indexOf(id) > -1; }); + if (everyExist) + return; + setAction('Add Active', ids); + this._setState(function (state) { + /** Protect against case that one of the items in the array exist */ + var uniques = Array.from(new Set(__spread(state.active, toArray))); + return __assign({}, state, { active: uniques }); + }); + }; + /** + * Remove active entities + * + * @example + * + * store.removeActive(2) + * store.removeActive([3, 4, 5]) + */ + EntityStore.prototype.removeActive = function (ids) { + var _this = this; + var toArray = coerceArray(ids); + if (isEmpty(toArray)) + return; + var someExist = toArray.some(function (id) { return _this.active.indexOf(id) > -1; }); + if (!someExist) + return; + setAction('Remove Active', ids); + this._setState(function (state) { + return __assign({}, state, { active: Array.isArray(state.active) ? state.active.filter(function (currentId) { return toArray.indexOf(currentId) === -1; }) : null }); + }); + }; + /** + * Toggle active entities + * + * @example + * + * store.toggle(2) + * store.toggle([3, 4, 5]) + */ + EntityStore.prototype.toggleActive = function (ids) { + var _this = this; + var toArray = coerceArray(ids); + var filterExists = function (remove) { return function (id) { return _this.active.includes(id) === remove; }; }; + var remove = toArray.filter(filterExists(true)); + var add = toArray.filter(filterExists(false)); + this.removeActive(remove); + this.addActive(add); + logAction('Toggle Active'); + }; + /** + * + * Create sub UI store for managing Entity's UI state + * + * @example + * + * export type ProductUI = { + * isLoading: boolean; + * isOpen: boolean + * } + * + * interface ProductsUIState extends EntityState {} + * + * export class ProductsStore EntityStore { + * ui: EntityUIStore; + * + * constructor() { + * super(); + * this.createUIStore(); + * } + * + * } + */ + EntityStore.prototype.createUIStore = function (initialState, storeConfig) { + if (initialState === void 0) { initialState = {}; } + if (storeConfig === void 0) { storeConfig = {}; } + var defaults = { name: "UI/" + this.storeName, idKey: this.idKey }; + this.ui = new EntityUIStore(initialState, __assign({}, defaults, storeConfig)); + return this.ui; + }; + // @internal + EntityStore.prototype.destroy = function () { + _super.prototype.destroy.call(this); + if (this.ui instanceof EntityStore) { + this.ui.destroy(); + } + this.entityActions.complete(); + }; + // @internal + EntityStore.prototype.akitaPreUpdateEntity = function (_, nextEntity) { + return nextEntity; + }; + // @internal + EntityStore.prototype.akitaPreAddEntity = function (newEntity) { + return newEntity; + }; + // @internal + EntityStore.prototype.akitaPreCheckEntity = function (newEntity) { + return newEntity; + }; + Object.defineProperty(EntityStore.prototype, "ids", { + get: function () { + return this._value().ids; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntityStore.prototype, "entities", { + get: function () { + return this._value().entities; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntityStore.prototype, "active", { + get: function () { + return this._value().active; + }, + enumerable: true, + configurable: true + }); + EntityStore.prototype._setActive = function (ids) { + this._setState(function (state) { + return __assign({}, state, { active: ids }); + }); + }; + EntityStore.prototype.handleUICreation = function (add) { + var _this = this; + if (add === void 0) { add = false; } + var ids = this.ids; + var isFunc = isFunction(this.ui._akitaCreateEntityFn); + var uiEntities; + var createFn = function (id) { + var _a; + var current = _this.entities[id]; + var ui = isFunc ? _this.ui._akitaCreateEntityFn(current) : _this.ui._akitaCreateEntityFn; + return __assign((_a = {}, _a[_this.idKey] = current[_this.idKey], _a), ui); + }; + if (add) { + uiEntities = this.ids.filter(function (id) { return isUndefined(_this.ui.entities[id]); }).map(createFn); + } + else { + uiEntities = ids.map(createFn); + } + add ? this.ui.add(uiEntities) : this.ui.set(uiEntities); + }; + EntityStore.prototype.hasInitialUIState = function () { + return this.hasUIStore() && isUndefined(this.ui._akitaCreateEntityFn) === false; + }; + EntityStore.prototype.handleUIRemove = function (ids) { + if (this.hasUIStore()) { + this.ui.remove(ids); + } + }; + EntityStore.prototype.hasUIStore = function () { + return this.ui instanceof EntityUIStore; + }; + var _b; + __decorate$2([ + transaction(), + __metadata("design:type", Function), + __metadata("design:paramtypes", [Object, Object, Object, Object]), + __metadata("design:returntype", void 0) + ], EntityStore.prototype, "upsert", null); + __decorate$2([ + transaction(), + __metadata("design:type", Function), + __metadata("design:paramtypes", [typeof (_b = typeof T !== "undefined" && T) === "function" ? _b : Object]), + __metadata("design:returntype", void 0) + ], EntityStore.prototype, "toggleActive", null); + return EntityStore; + }(Store)); + // @internal + var EntityUIStore = /** @class */ (function (_super) { + __extends(EntityUIStore, _super); + function EntityUIStore(initialState, storeConfig) { + if (initialState === void 0) { initialState = {}; } + if (storeConfig === void 0) { storeConfig = {}; } + return _super.call(this, initialState, storeConfig) || this; + } + /** + * + * Set the initial UI entity state. This function will determine the entity's + * initial state when we call `set()` or `add()`. + * + * @example + * + * constructor() { + * super(); + * this.createUIStore().setInitialEntityState(entity => ({ isLoading: false, isOpen: true })); + * this.createUIStore().setInitialEntityState({ isLoading: false, isOpen: true }); + * } + * + */ + EntityUIStore.prototype.setInitialEntityState = function (createFn) { + this._akitaCreateEntityFn = createFn; + }; + return EntityUIStore; + }(EntityStore)); + // @internal + function distinctUntilArrayItemChanged() { + return distinctUntilChanged(function (prevCollection, currentCollection) { + if (prevCollection === currentCollection) { + return true; + } + if (isArray(prevCollection) === false || isArray(currentCollection) === false) { + return false; + } + if (isEmpty(prevCollection) && isEmpty(currentCollection)) { + return true; + } + // if item is new in the current collection but not exist in the prev collection + var hasNewItem = hasChange(currentCollection, prevCollection); + if (hasNewItem) { + return false; + } + var isOneOfItemReferenceChanged = hasChange(prevCollection, currentCollection); + // return false means there is a change and we want to call next() + return isOneOfItemReferenceChanged === false; + }); + } + // @internal + function hasChange(first, second) { + var hasChange = second.some(function (currentItem) { + var oldItem = first.find(function (prevItem) { return prevItem === currentItem; }); + return oldItem === undefined; + }); + return hasChange; + } + + var Order; + (function (Order) { + Order["ASC"] = "asc"; + Order["DESC"] = "desc"; + })(Order || (Order = {})); + // @internal + function compareValues(key, order) { + if (order === void 0) { order = Order.ASC; } + return function (a, b) { + if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) { + return 0; + } + var varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]; + var varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]; + var comparison = 0; + if (varA > varB) { + comparison = 1; + } + else if (varA < varB) { + comparison = -1; + } + return order == Order.DESC ? comparison * -1 : comparison; + }; + } + + // @internal + function entitiesToArray(state, options) { + var arr = []; + var ids = state.ids, entities = state.entities; + var filterBy = options.filterBy, limitTo = options.limitTo, sortBy = options.sortBy, sortByOrder = options.sortByOrder; + var _loop_1 = function (i) { + var entity = entities[ids[i]]; + if (!filterBy) { + arr.push(entity); + return "continue"; + } + var toArray = coerceArray(filterBy); + var allPass = toArray.every(function (fn) { return fn(entity, i); }); + if (allPass) { + arr.push(entity); + } + }; + for (var i = 0; i < ids.length; i++) { + _loop_1(i); + } + if (sortBy) { + var _sortBy_1 = isFunction(sortBy) ? sortBy : compareValues(sortBy, sortByOrder); + arr = arr.sort(function (a, b) { return _sortBy_1(a, b, state); }); + } + var length = Math.min(limitTo || arr.length, arr.length); + return length === arr.length ? arr : arr.slice(0, length); + } + + // @internal + function entitiesToMap(state, options) { + var map = {}; + var filterBy = options.filterBy, limitTo = options.limitTo; + var ids = state.ids, entities = state.entities; + if (!filterBy && !limitTo) { + return entities; + } + var hasLimit = isNil(limitTo) === false; + if (filterBy && hasLimit) { + var count = 0; + var _loop_1 = function (i, length_1) { + if (count === limitTo) + return "break"; + var id = ids[i]; + var entity = entities[id]; + var allPass = coerceArray(filterBy).every(function (fn) { return fn(entity, i); }); + if (allPass) { + map[id] = entity; + count++; + } + }; + for (var i = 0, length_1 = ids.length; i < length_1; i++) { + var state_1 = _loop_1(i, length_1); + if (state_1 === "break") + break; + } + } + else { + var finalLength = Math.min(limitTo || ids.length, ids.length); + var _loop_2 = function (i) { + var id = ids[i]; + var entity = entities[id]; + if (!filterBy) { + map[id] = entity; + return "continue"; + } + var allPass = coerceArray(filterBy).every(function (fn) { return fn(entity, i); }); + if (allPass) { + map[id] = entity; + } + }; + for (var i = 0; i < finalLength; i++) { + _loop_2(i); + } + } + return map; + } + + // @internal + function isString(value) { + return typeof value === 'string'; + } + + // @internal + function findEntityByPredicate(predicate, entities) { + var e_1, _a; + try { + for (var _b = __values(Object.keys(entities)), _c = _b.next(); !_c.done; _c = _b.next()) { + var entityId = _c.value; + if (predicate(entities[entityId]) === true) { + return entityId; + } + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } + finally { if (e_1) throw e_1.error; } + } + return undefined; + } + // @internal + function getEntity(id, project) { + return function (entities) { + var entity = entities[id]; + if (isUndefined(entity)) { + return undefined; + } + if (!project) { + return entity; + } + if (isString(project)) { + return entity[project]; + } + return project(entity); + }; + } + + // @internal + function mapSkipUndefined(arr, callbackFn) { + return arr.reduce(function (result, value, index, array) { + var val = callbackFn(value, index, array); + if (val !== undefined) { + result.push(val); + } + return result; + }, []); + } + + var queryConfigKey = 'akitaQueryConfig'; + + function compareKeys(keysOrFuncs) { + return function (prevState, currState) { + var isFns = isFunction(keysOrFuncs[0]); + // Return when they are NOT changed + return keysOrFuncs.some(function (keyOrFunc) { + if (isFns) { + return keyOrFunc(prevState) !== keyOrFunc(currState); + } + return prevState[keyOrFunc] !== currState[keyOrFunc]; + }) === false; + }; + } + + var Query = /** @class */ (function () { + function Query(store) { + this.store = store; + this.__store__ = store; + { + // @internal + __queries__[store.storeName] = this; + } + } + Query.prototype.select = function (project) { + var mapFn; + if (isFunction(project)) { + mapFn = project; + } + else if (isString(project)) { + mapFn = function (state) { return state[project]; }; + } + else if (Array.isArray(project)) { + return this.store + ._select(function (state) { return state; }) + .pipe(distinctUntilChanged(compareKeys(project)), map(function (state) { + if (isFunction(project[0])) { + return project.map(function (func) { return func(state); }); + } + return project.reduce(function (acc, k) { + acc[k] = state[k]; + return acc; + }, {}); + })); + } + else { + mapFn = function (state) { return state; }; + } + return this.store._select(mapFn); + }; + /** + * Select the loading state + * + * @example + * + * this.query.selectLoading().subscribe(isLoading => {}) + */ + Query.prototype.selectLoading = function () { + return this.select(function (state) { return state.loading; }); + }; + /** + * Select the error state + * + * @example + * + * this.query.selectError().subscribe(error => {}) + */ + Query.prototype.selectError = function () { + return this.select(function (state) { return state.error; }); + }; + /** + * Get the store's value + * + * @example + * + * this.query.getValue() + * + */ + Query.prototype.getValue = function () { + return this.store._value(); + }; + /** + * Select the cache state + * + * @example + * + * this.query.selectHasCache().pipe( + * switchMap(hasCache => { + * return hasCache ? of() : http().pipe(res => store.set(res)) + * }) + * ) + */ + Query.prototype.selectHasCache = function () { + return this.store._cache().asObservable(); + }; + /** + * Whether we've cached data + * + * @example + * + * this.query.getHasCache() + * + */ + Query.prototype.getHasCache = function () { + return this.store._cache().value; + }; + Object.defineProperty(Query.prototype, "config", { + // @internal + get: function () { + return this.constructor[queryConfigKey]; + }, + enumerable: true, + configurable: true + }); + return Query; + }()); + + // @internal + function sortByOptions(options, config) { + options.sortBy = options.sortBy || (config && config.sortBy); + options.sortByOrder = options.sortByOrder || (config && config.sortByOrder); + } + + /** + * + * The Entity Query is similar to the general Query, with additional functionality tailored for EntityStores. + * + * class WidgetsQuery extends QueryEntity { + * constructor(protected store: WidgetsStore) { + * super(store); + * } + * } + * + * + * + */ + var QueryEntity = /** @class */ (function (_super) { + __extends(QueryEntity, _super); + function QueryEntity(store, options) { + if (options === void 0) { options = {}; } + var _this = _super.call(this, store) || this; + _this.options = options; + _this.__store__ = store; + return _this; + } + QueryEntity.prototype.selectAll = function (options) { + var _this = this; + if (options === void 0) { options = { + asObject: false, + }; } + return this.select(function (state) { return state.entities; }).pipe(map(function () { return _this.getAll(options); })); + }; + QueryEntity.prototype.getAll = function (options) { + if (options === void 0) { options = { asObject: false, filterBy: undefined, limitTo: undefined }; } + if (options.asObject) { + return entitiesToMap(this.getValue(), options); + } + sortByOptions(options, this.config || this.options); + return entitiesToArray(this.getValue(), options); + }; + QueryEntity.prototype.selectMany = function (ids, project) { + if (!ids || !ids.length) + return of([]); + return this.select(function (state) { return state.entities; }).pipe(map(function (entities) { return mapSkipUndefined(ids, function (id) { return getEntity(id, project)(entities); }); }), distinctUntilArrayItemChanged()); + }; + QueryEntity.prototype.selectEntity = function (idOrPredicate, project) { + var id = idOrPredicate; + if (isFunction(idOrPredicate)) { + // For performance reason we expect the entity to be in the store + id = findEntityByPredicate(idOrPredicate, this.getValue().entities); + } + return this.select(function (state) { return state.entities; }).pipe(map(getEntity(id, project)), distinctUntilChanged()); + }; + /** + * Get an entity by id + * + * @example + * + * this.query.getEntity(1); + */ + QueryEntity.prototype.getEntity = function (id) { + return this.getValue().entities[id]; + }; + /** + * Select the active entity's id + * + * @example + * + * this.query.selectActiveId() + */ + QueryEntity.prototype.selectActiveId = function () { + return this.select(function (state) { return state.active; }); + }; + /** + * Get the active id + * + * @example + * + * this.query.getActiveId() + */ + QueryEntity.prototype.getActiveId = function () { + return this.getValue().active; + }; + QueryEntity.prototype.selectActive = function (project) { + var _this = this; + if (isArray(this.getActive())) { + return this.selectActiveId().pipe(switchMap(function (ids) { return _this.selectMany(ids, project); })); + } + return this.selectActiveId().pipe(switchMap(function (ids) { return _this.selectEntity(ids, project); })); + }; + QueryEntity.prototype.getActive = function () { + var _this = this; + var activeId = this.getActiveId(); + if (isArray(activeId)) { + return activeId.map(function (id) { return _this.getValue().entities[id]; }); + } + return toBoolean(activeId) ? this.getEntity(activeId) : undefined; + }; + /** + * Select the store's entity collection length + * + * @example + * + * this.query.selectCount() + * this.query.selectCount(entity => entity.completed) + */ + QueryEntity.prototype.selectCount = function (predicate) { + var _this = this; + return this.select(function (state) { return state.entities; }).pipe(map(function () { return _this.getCount(predicate); })); + }; + /** + * Get the store's entity collection length + * + * @example + * + * this.query.getCount() + * this.query.getCount(entity => entity.completed) + */ + QueryEntity.prototype.getCount = function (predicate) { + if (isFunction(predicate)) { + return this.getAll().filter(predicate).length; + } + return this.getValue().ids.length; + }; + QueryEntity.prototype.selectLast = function (project) { + return this.selectAt(function (ids) { return ids[ids.length - 1]; }, project); + }; + QueryEntity.prototype.selectFirst = function (project) { + return this.selectAt(function (ids) { return ids[0]; }, project); + }; + QueryEntity.prototype.selectEntityAction = function (actionOrActions) { + if (isNil(actionOrActions)) { + return this.store.selectEntityAction$; + } + var project = isArray(actionOrActions) ? function (action) { return action; } : function (_a) { + var ids = _a.ids; + return ids; + }; + var actions = coerceArray(actionOrActions); + return this.store.selectEntityAction$.pipe(filter(function (_a) { + var type = _a.type; + return actions.includes(type); + }), map(function (action) { return project(action); })); + }; + QueryEntity.prototype.hasEntity = function (projectOrIds) { + var _this = this; + if (isNil(projectOrIds)) { + return this.getValue().ids.length > 0; + } + if (isFunction(projectOrIds)) { + return this.getAll().some(projectOrIds); + } + if (isArray(projectOrIds)) { + return projectOrIds.every(function (id) { return id in _this.getValue().entities; }); + } + return projectOrIds in this.getValue().entities; + }; + /** + * Returns whether entity store has an active entity + * + * @example + * + * this.query.hasActive() + * this.query.hasActive(3) + * + */ + QueryEntity.prototype.hasActive = function (id) { + var active = this.getValue().active; + var isIdProvided = isDefined(id); + if (Array.isArray(active)) { + if (isIdProvided) { + return active.includes(id); + } + return active.length > 0; + } + return isIdProvided ? active === id : isDefined(active); + }; + /** + * + * Create sub UI query for querying Entity's UI state + * + * @example + * + * + * export class ProductsQuery extends QueryEntity { + * ui: EntityUIQuery; + * + * constructor(protected store: ProductsStore) { + * super(store); + * this.createUIQuery(); + * } + * + * } + */ + QueryEntity.prototype.createUIQuery = function () { + this.ui = new EntityUIQuery(this.__store__.ui); + }; + QueryEntity.prototype.selectAt = function (mapFn, project) { + var _this = this; + return this.select(function (state) { return state.ids; }).pipe(map(mapFn), distinctUntilChanged(), switchMap(function (id) { return _this.selectEntity(id, project); })); + }; + return QueryEntity; + }(Query)); + // @internal + var EntityUIQuery = /** @class */ (function (_super) { + __extends(EntityUIQuery, _super); + function EntityUIQuery(store) { + return _super.call(this, store) || this; + } + return EntityUIQuery; + }(QueryEntity)); + + /** + * @example + * + * query.selectEntity(2).pipe(filterNil) + */ + var filterNil = function (source) { return source.pipe(filter(function (value) { return value !== null && typeof value !== 'undefined'; })); }; + + /** + * @internal + * + * @example + * + * getValue(state, 'todos.ui') + * + */ + function getValue(obj, prop) { + /** return the whole state */ + if (prop.split('.').length === 1) { + return obj; + } + var removeStoreName = prop + .split('.') + .slice(1) + .join('.'); + return removeStoreName.split('.').reduce(function (acc, part) { return acc && acc[part]; }, obj); + } + + /** + * @internal + * + * @example + * setValue(state, 'todos.ui', { filter: {} }) + */ + function setValue(obj, prop, val) { + var split = prop.split('.'); + if (split.length === 1) { + return __assign({}, obj, val); + } + obj = __assign({}, obj); + var lastIndex = split.length - 2; + var removeStoreName = prop.split('.').slice(1); + removeStoreName.reduce(function (acc, part, index) { + if (index !== lastIndex) { + acc[part] = __assign({}, acc[part]); + return acc && acc[part]; + } + acc[part] = Array.isArray(acc[part]) || !isObject(acc[part]) ? val : __assign({}, acc[part], val); + return acc && acc[part]; + }, obj); + return obj; + } + new ReplaySubject(1); + + var AkitaPlugin = /** @class */ (function () { + function AkitaPlugin(query, config) { + this.query = query; + } + /** This method is responsible for getting access to the query. */ + AkitaPlugin.prototype.getQuery = function () { + return this.query; + }; + /** This method is responsible for getting access to the store. */ + AkitaPlugin.prototype.getStore = function () { + return this.getQuery().__store__; + }; + /** This method is responsible tells whether the plugin is entityBased or not. */ + AkitaPlugin.prototype.isEntityBased = function (entityId) { + return toBoolean(entityId); + }; + /** This method is responsible for selecting the source; it can be the whole store or one entity. */ + AkitaPlugin.prototype.selectSource = function (entityId, property) { + var _this = this; + if (this.isEntityBased(entityId)) { + return this.getQuery().selectEntity(entityId).pipe(filterNil); + } + if (property) { + return this.getQuery().select(function (state) { return getValue(state, _this.withStoreName(property)); }); + } + return this.getQuery().select(); + }; + AkitaPlugin.prototype.getSource = function (entityId, property) { + if (this.isEntityBased(entityId)) { + return this.getQuery().getEntity(entityId); + } + var state = this.getQuery().getValue(); + if (property) { + return getValue(state, this.withStoreName(property)); + } + return state; + }; + AkitaPlugin.prototype.withStoreName = function (prop) { + return this.storeName + "." + prop; + }; + Object.defineProperty(AkitaPlugin.prototype, "storeName", { + get: function () { + return this.getStore().storeName; + }, + enumerable: true, + configurable: true + }); + /** This method is responsible for updating the store or one entity; it can be the whole store or one entity. */ + AkitaPlugin.prototype.updateStore = function (newState, entityId, property) { + var _this = this; + if (this.isEntityBased(entityId)) { + this.getStore().update(entityId, newState); + } + else { + if (property) { + this.getStore()._setState(function (state) { + return setValue(state, _this.withStoreName(property), newState); + }); + return; + } + this.getStore()._setState(function (state) { return (__assign({}, state, newState)); }); + } + }; + /** + * Function to invoke upon reset + */ + AkitaPlugin.prototype.onReset = function (fn) { + var _this = this; + var original = this.getStore().reset; + this.getStore().reset = function () { + var params = []; + for (var _i = 0; _i < arguments.length; _i++) { + params[_i] = arguments[_i]; + } + /** It should run after the plugin destroy method */ + setTimeout(function () { + original.apply(_this.getStore(), params); + fn(); + }); + }; + }; + return AkitaPlugin; + }()); + + var paginatorDefaults = { + pagesControls: false, + range: false, + startWith: 1, + cacheTimeout: undefined, + clearStoreWithCache: true + }; + /** @class */ ((function (_super) { + __extends(PaginatorPlugin, _super); + function PaginatorPlugin(query, config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, query, { + resetFn: function () { + _this.initial = false; + _this.destroy({ clearCache: true, currentPage: 1 }); + } + }) || this; + _this.query = query; + _this.config = config; + /** Save current filters, sorting, etc. in cache */ + _this.metadata = new Map(); + _this.pages = new Map(); + _this.pagination = { + currentPage: 1, + perPage: 0, + total: 0, + lastPage: 0, + data: [] + }; + /** + * When the user navigates to a different page and return + * we don't want to call `clearCache` on first time. + */ + _this.initial = true; + /** + * Proxy to the query loading + */ + _this.isLoading$ = _this.query.selectLoading().pipe(delay(0)); + _this.config = Object.assign(paginatorDefaults, config); + var _a = _this.config, startWith = _a.startWith, cacheTimeout = _a.cacheTimeout; + _this.page = new BehaviorSubject(startWith); + if (isObservable(cacheTimeout)) { + _this.clearCacheSubscription = cacheTimeout.subscribe(function () { return _this.clearCache(); }); + } + return _this; + } + Object.defineProperty(PaginatorPlugin.prototype, "pageChanges", { + /** + * Listen to page changes + */ + get: function () { + return this.page.asObservable(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(PaginatorPlugin.prototype, "currentPage", { + /** + * Get the current page number + */ + get: function () { + return this.pagination.currentPage; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(PaginatorPlugin.prototype, "isFirst", { + /** + * Check if current page is the first one + */ + get: function () { + return this.currentPage === 1; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(PaginatorPlugin.prototype, "isLast", { + /** + * Check if current page is the last one + */ + get: function () { + return this.currentPage === this.pagination.lastPage; + }, + enumerable: true, + configurable: true + }); + /** + * Whether to generate an array of pages for *ngFor + * [1, 2, 3, 4] + */ + PaginatorPlugin.prototype.withControls = function () { + this.config.pagesControls = true; + return this; + }; + /** + * Whether to generate the `from` and `to` keys + * [1, 2, 3, 4] + */ + PaginatorPlugin.prototype.withRange = function () { + this.config.range = true; + return this; + }; + /** + * Set the loading state + */ + PaginatorPlugin.prototype.setLoading = function (value) { + if (value === void 0) { value = true; } + this.getStore().setLoading(value); + }; + /** + * Update the pagination object and add the page + */ + PaginatorPlugin.prototype.update = function (response) { + this.pagination = response; + this.addPage(response.data); + }; + /** + * + * Set the ids and add the page to store + */ + PaginatorPlugin.prototype.addPage = function (data) { + var _this = this; + this.pages.set(this.currentPage, { ids: data.map(function (entity) { return entity[_this.getStore().idKey]; }) }); + this.getStore().upsertMany(data); + }; + /** + * Clear the cache. + */ + PaginatorPlugin.prototype.clearCache = function (options) { + if (options === void 0) { options = {}; } + if (!this.initial) { + logAction('@Pagination - Clear Cache'); + if (options.clearStore !== false && (this.config.clearStoreWithCache || options.clearStore)) { + this.getStore().remove(); + } + this.pages = new Map(); + this.metadata = new Map(); + } + this.initial = false; + }; + PaginatorPlugin.prototype.clearPage = function (page) { + this.pages.delete(page); + }; + /** + * Clear the cache timeout and optionally the pages + */ + PaginatorPlugin.prototype.destroy = function (_a) { + var _b = _a === void 0 ? {} : _a, clearCache = _b.clearCache, currentPage = _b.currentPage; + if (this.clearCacheSubscription) { + this.clearCacheSubscription.unsubscribe(); + } + if (clearCache) { + this.clearCache(); + } + if (!isUndefined(currentPage)) { + this.setPage(currentPage); + } + this.initial = true; + }; + /** + * Whether the provided page is active + */ + PaginatorPlugin.prototype.isPageActive = function (page) { + return this.currentPage === page; + }; + /** + * Set the current page + */ + PaginatorPlugin.prototype.setPage = function (page) { + if (page !== this.currentPage || !this.hasPage(page)) { + this.page.next((this.pagination.currentPage = page)); + } + }; + /** + * Increment current page + */ + PaginatorPlugin.prototype.nextPage = function () { + if (this.currentPage !== this.pagination.lastPage) { + this.setPage(this.pagination.currentPage + 1); + } + }; + /** + * Decrement current page + */ + PaginatorPlugin.prototype.prevPage = function () { + if (this.pagination.currentPage > 1) { + this.setPage(this.pagination.currentPage - 1); + } + }; + /** + * Set current page to last + */ + PaginatorPlugin.prototype.setLastPage = function () { + this.setPage(this.pagination.lastPage); + }; + /** + * Set current page to first + */ + PaginatorPlugin.prototype.setFirstPage = function () { + this.setPage(1); + }; + /** + * Check if page exists in cache + */ + PaginatorPlugin.prototype.hasPage = function (page) { + return this.pages.has(page); + }; + /** + * Get the current page if it's in cache, otherwise invoke the request + */ + PaginatorPlugin.prototype.getPage = function (req) { + var _this = this; + var page = this.pagination.currentPage; + if (this.hasPage(page)) { + return this.selectPage(page); + } + else { + this.setLoading(true); + return from(req()).pipe(switchMap(function (config) { + page = config.currentPage; + applyTransaction(function () { + _this.setLoading(false); + _this.update(config); + }); + return _this.selectPage(page); + })); + } + }; + PaginatorPlugin.prototype.getQuery = function () { + return this.query; + }; + PaginatorPlugin.prototype.refreshCurrentPage = function () { + if (isNil(this.currentPage) === false) { + this.clearPage(this.currentPage); + this.setPage(this.currentPage); + } + }; + PaginatorPlugin.prototype.getFrom = function () { + if (this.isFirst) { + return 1; + } + return (this.currentPage - 1) * this.pagination.perPage + 1; + }; + PaginatorPlugin.prototype.getTo = function () { + if (this.isLast) { + return this.pagination.total; + } + return this.currentPage * this.pagination.perPage; + }; + /** + * Select the page + */ + PaginatorPlugin.prototype.selectPage = function (page) { + var _this = this; + return this.query.selectAll({ asObject: true }).pipe(take(1), map(function (entities) { + var response = __assign({}, _this.pagination, { data: _this.pages.get(page).ids.map(function (id) { return entities[id]; }) }); + var _a = _this.config, range = _a.range, pagesControls = _a.pagesControls; + /** If no total - calc it */ + if (isNaN(_this.pagination.total)) { + if (response.lastPage === 1) { + response.total = response.data ? response.data.length : 0; + } + else { + response.total = response.perPage * response.lastPage; + } + _this.pagination.total = response.total; + } + if (range) { + response.from = _this.getFrom(); + response.to = _this.getTo(); + } + if (pagesControls) { + response.pageControls = generatePages(_this.pagination.total, _this.pagination.perPage); + } + return response; + })); + }; + __decorate$2([ + action('@Pagination - New Page'), + __metadata("design:type", Function), + __metadata("design:paramtypes", [Object]), + __metadata("design:returntype", void 0) + ], PaginatorPlugin.prototype, "update", null); + return PaginatorPlugin; + })(AkitaPlugin)); + /** + * Generate an array so we can ngFor them to navigate between pages + */ + function generatePages(total, perPage) { + var len = Math.ceil(total / perPage); + var arr = []; + for (var i = 0; i < len; i++) { + arr.push(i + 1); + } + return arr; + } + + /** @class */ ((function (_super) { + __extends(PersistNgFormPlugin, _super); + function PersistNgFormPlugin(query, factoryFnOrPath, params) { + if (params === void 0) { params = {}; } + var _this = _super.call(this, query) || this; + _this.query = query; + _this.factoryFnOrPath = factoryFnOrPath; + _this.params = params; + _this.params = __assign({ debounceTime: 300, formKey: 'akitaForm', emitEvent: false, arrControlFactory: function (v) { return _this.builder.control(v); } }, params); + _this.isRootKeys = toBoolean(factoryFnOrPath) === false; + _this.isKeyBased = isString(factoryFnOrPath) || _this.isRootKeys; + return _this; + } + PersistNgFormPlugin.prototype.setForm = function (form, builder) { + this.form = form; + this.builder = builder; + this.activate(); + return this; + }; + PersistNgFormPlugin.prototype.reset = function (initialState) { + var _this = this; + var _a; + var value; + if (initialState) { + value = initialState; + } + else { + value = this.isKeyBased ? this.initialValue : this.factoryFnOrPath(); + } + if (this.isKeyBased) { + Object.keys(this.initialValue).forEach(function (stateKey) { + var value = _this.initialValue[stateKey]; + if (Array.isArray(value) && _this.builder) { + var formArray = _this.form.controls[stateKey]; + _this.cleanArray(formArray); + value.forEach(function (v, i) { + _this.form.get(stateKey).insert(i, _this.params.arrControlFactory(v)); + }); + } + }); + } + this.form.patchValue(value, { emitEvent: this.params.emitEvent }); + var storeValue = this.isKeyBased ? setValue(this.getQuery().getValue(), this.getStore().storeName + "." + this.factoryFnOrPath, value) : (_a = {}, _a[this.params.formKey] = value, _a); + this.updateStore(storeValue); + }; + PersistNgFormPlugin.prototype.cleanArray = function (control) { + while (control.length !== 0) { + control.removeAt(0); + } + }; + PersistNgFormPlugin.prototype.resolveInitialValue = function (formValue, root) { + var _this = this; + if (!formValue) + return; + return Object.keys(formValue).reduce(function (acc, stateKey) { + var value = root[stateKey]; + if (Array.isArray(value) && _this.builder) { + var factory_1 = _this.params.arrControlFactory; + _this.cleanArray(_this.form.get(stateKey)); + value.forEach(function (v, i) { + _this.form.get(stateKey).insert(i, factory_1(v)); + }); + } + acc[stateKey] = root[stateKey]; + return acc; + }, {}); + }; + PersistNgFormPlugin.prototype.activate = function () { + var _this = this; + var _a; + var path; + if (this.isKeyBased) { + if (this.isRootKeys) { + this.initialValue = this.resolveInitialValue(this.form.value, this.getQuery().getValue()); + this.form.patchValue(this.initialValue, { emitEvent: this.params.emitEvent }); + } + else { + path = this.getStore().storeName + "." + this.factoryFnOrPath; + var root = getValue(this.getQuery().getValue(), path); + this.initialValue = this.resolveInitialValue(root, root); + this.form.patchValue(this.initialValue, { emitEvent: this.params.emitEvent }); + } + } + else { + if (!this.getQuery().getValue()[this.params.formKey]) { + logAction('@PersistNgFormPlugin activate'); + this.updateStore((_a = {}, _a[this.params.formKey] = this.factoryFnOrPath(), _a)); + } + var value = this.getQuery().getValue()[this.params.formKey]; + this.form.patchValue(value); + } + this.formChanges = this.form.valueChanges.pipe(debounceTime(this.params.debounceTime)).subscribe(function (value) { + logAction('@PersistForm - Update'); + var newState; + if (_this.isKeyBased) { + if (_this.isRootKeys) { + newState = function (state) { return (__assign({}, state, value)); }; + } + else { + newState = function (state) { return setValue(state, path, value); }; + } + } + else { + newState = function () { + var _a; + return (_a = {}, _a[_this.params.formKey] = value, _a); + }; + } + _this.updateStore(newState(_this.getQuery().getValue())); + }); + }; + PersistNgFormPlugin.prototype.destroy = function () { + this.formChanges && this.formChanges.unsubscribe(); + this.form = null; + this.builder = null; + }; + return PersistNgFormPlugin; + })(AkitaPlugin)); + + /** + * Each plugin that wants to add support for entities should extend this interface. + */ + var EntityCollectionPlugin = /** @class */ (function () { + function EntityCollectionPlugin(query, entityIds) { + this.query = query; + this.entityIds = entityIds; + this.entities = new Map(); + } + /** + * Get the entity plugin instance. + */ + EntityCollectionPlugin.prototype.getEntity = function (id) { + return this.entities.get(id); + }; + /** + * Whether the entity plugin exist. + */ + EntityCollectionPlugin.prototype.hasEntity = function (id) { + return this.entities.has(id); + }; + /** + * Remove the entity plugin instance. + */ + EntityCollectionPlugin.prototype.removeEntity = function (id) { + this.destroy(id); + return this.entities.delete(id); + }; + /** + * Set the entity plugin instance. + */ + EntityCollectionPlugin.prototype.createEntity = function (id, plugin) { + return this.entities.set(id, plugin); + }; + /** + * If the user passes `entityIds` we take them; otherwise, we take all. + */ + EntityCollectionPlugin.prototype.getIds = function () { + return isUndefined(this.entityIds) ? this.query.getValue().ids : coerceArray(this.entityIds); + }; + /** + * When you call one of the plugin methods, you can pass id/ids or undefined which means all. + */ + EntityCollectionPlugin.prototype.resolvedIds = function (ids) { + return isUndefined(ids) ? this.getIds() : coerceArray(ids); + }; + /** + * Call this method when you want to activate the plugin on init or when you need to listen to add/remove of entities dynamically. + * + * For example in your plugin you may do the following: + * + * this.query.select(state => state.ids).pipe(skip(1)).subscribe(ids => this.activate(ids)); + */ + EntityCollectionPlugin.prototype.rebase = function (ids, actions) { + var _this = this; + if (actions === void 0) { actions = {}; } + /** + * + * If the user passes `entityIds` & we have new ids check if we need to add/remove instances. + * + * This phase will be called only upon update. + */ + if (toBoolean(ids)) { + /** + * Which means all + */ + if (isUndefined(this.entityIds)) { + for (var i = 0, len = ids.length; i < len; i++) { + var entityId = ids[i]; + if (this.hasEntity(entityId) === false) { + isFunction(actions.beforeAdd) && actions.beforeAdd(entityId); + var plugin = this.instantiatePlugin(entityId); + this.entities.set(entityId, plugin); + isFunction(actions.afterAdd) && actions.afterAdd(plugin); + } + } + this.entities.forEach(function (plugin, entityId) { + if (ids.indexOf(entityId) === -1) { + isFunction(actions.beforeRemove) && actions.beforeRemove(plugin); + _this.removeEntity(entityId); + } + }); + } + else { + /** + * Which means the user passes specific ids + */ + var _ids = coerceArray(this.entityIds); + for (var i = 0, len = _ids.length; i < len; i++) { + var entityId = _ids[i]; + /** The Entity in current ids and doesn't exist, add it. */ + if (ids.indexOf(entityId) > -1 && this.hasEntity(entityId) === false) { + isFunction(actions.beforeAdd) && actions.beforeAdd(entityId); + var plugin = this.instantiatePlugin(entityId); + this.entities.set(entityId, plugin); + isFunction(actions.afterAdd) && actions.afterAdd(plugin); + } + else { + this.entities.forEach(function (plugin, entityId) { + /** The Entity not in current ids and exists, remove it. */ + if (ids.indexOf(entityId) === -1 && _this.hasEntity(entityId) === true) { + isFunction(actions.beforeRemove) && actions.beforeRemove(plugin); + _this.removeEntity(entityId); + } + }); + } + } + } + } + else { + /** + * Otherwise, start with the provided ids or all. + */ + this.getIds().forEach(function (id) { + if (!_this.hasEntity(id)) + _this.createEntity(id, _this.instantiatePlugin(id)); + }); + } + }; + /** + * Listen for add/remove entities. + */ + EntityCollectionPlugin.prototype.selectIds = function () { + return this.query.select(function (state) { return state.ids; }); + }; + /** + * Base method for activation, you can override it if you need to. + */ + EntityCollectionPlugin.prototype.activate = function (ids) { + this.rebase(ids); + }; + /** + * Loop over each id and invoke the plugin method. + */ + EntityCollectionPlugin.prototype.forEachId = function (ids, cb) { + var _ids = this.resolvedIds(ids); + for (var i = 0, len = _ids.length; i < len; i++) { + var id = _ids[i]; + if (this.hasEntity(id)) { + cb(this.getEntity(id)); + } + } + }; + return EntityCollectionPlugin; + }()); + + var StateHistoryPlugin = /** @class */ (function (_super) { + __extends(StateHistoryPlugin, _super); + function StateHistoryPlugin(query, params, _entityId) { + if (params === void 0) { params = {}; } + var _this = _super.call(this, query, { + resetFn: function () { return _this.clear(); } + }) || this; + _this.query = query; + _this.params = params; + _this._entityId = _entityId; + /** Allow skipping an update from outside */ + _this.skip = false; + _this.history = { + past: [], + present: null, + future: [] + }; + /** Skip the update when redo/undo */ + _this.skipUpdate = false; + params.maxAge = !!params.maxAge ? params.maxAge : 10; + params.comparator = params.comparator || (function () { return true; }); + _this.activate(); + return _this; + } + Object.defineProperty(StateHistoryPlugin.prototype, "hasPast$", { + /** + * Observable stream representing whether the history plugin has an available past + * + */ + get: function () { + return this._hasPast$; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(StateHistoryPlugin.prototype, "hasFuture$", { + /** + * Observable stream representing whether the history plugin has an available future + * + */ + get: function () { + return this._hasFuture$; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(StateHistoryPlugin.prototype, "hasPast", { + get: function () { + return this.history.past.length > 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(StateHistoryPlugin.prototype, "hasFuture", { + get: function () { + return this.history.future.length > 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(StateHistoryPlugin.prototype, "property", { + get: function () { + return this.params.watchProperty; + }, + enumerable: true, + configurable: true + }); + /* Updates the hasPast$ hasFuture$ observables*/ + StateHistoryPlugin.prototype.updateHasHistory = function () { + this.hasFutureSubject.next(this.hasFuture); + this.hasPastSubject.next(this.hasPast); + }; + StateHistoryPlugin.prototype.activate = function () { + var _this = this; + this.hasPastSubject = new BehaviorSubject(false); + this._hasPast$ = this.hasPastSubject.asObservable().pipe(distinctUntilChanged()); + this.hasFutureSubject = new BehaviorSubject(false); + this._hasFuture$ = this.hasFutureSubject.asObservable().pipe(distinctUntilChanged()); + this.history.present = this.getSource(this._entityId, this.property); + this.subscription = this + .selectSource(this._entityId, this.property) + .pipe(pairwise()) + .subscribe(function (_a) { + var _b = __read(_a, 2), past = _b[0], present = _b[1]; + if (_this.skip) { + _this.skip = false; + return; + } + /** + * comparator: (prev, current) => isEqual(prev, current) === false + */ + var shouldUpdate = _this.params.comparator(past, present); + if (!_this.skipUpdate && shouldUpdate) { + if (_this.history.past.length === _this.params.maxAge) { + _this.history.past = _this.history.past.slice(1); + } + _this.history.past = __spread(_this.history.past, [past]); + _this.history.present = present; + _this.updateHasHistory(); + } + }); + }; + StateHistoryPlugin.prototype.undo = function () { + if (this.history.past.length > 0) { + var _a = this.history, past = _a.past, present = _a.present; + var previous = past[past.length - 1]; + this.history.past = past.slice(0, past.length - 1); + this.history.present = previous; + this.history.future = __spread([present], this.history.future); + this.update(); + } + }; + StateHistoryPlugin.prototype.redo = function () { + if (this.history.future.length > 0) { + var _a = this.history, past = _a.past, present = _a.present; + var next = this.history.future[0]; + var newFuture = this.history.future.slice(1); + this.history.past = __spread(past, [present]); + this.history.present = next; + this.history.future = newFuture; + this.update('Redo'); + } + }; + StateHistoryPlugin.prototype.jumpToPast = function (index) { + if (index < 0 || index >= this.history.past.length) + return; + var _a = this.history, past = _a.past, future = _a.future, present = _a.present; + /** + * + * const past = [1, 2, 3, 4, 5]; + * const present = 6; + * const future = [7, 8, 9]; + * const index = 2; + * + * newPast = past.slice(0, index) = [1, 2]; + * newPresent = past[index] = 3; + * newFuture = [...past.slice(index + 1),present, ...future] = [4, 5, 6, 7, 8, 9]; + * + */ + var newPast = past.slice(0, index); + var newFuture = __spread(past.slice(index + 1), [present], future); + var newPresent = past[index]; + this.history.past = newPast; + this.history.present = newPresent; + this.history.future = newFuture; + this.update(); + }; + StateHistoryPlugin.prototype.jumpToFuture = function (index) { + if (index < 0 || index >= this.history.future.length) + return; + var _a = this.history, past = _a.past, future = _a.future, present = _a.present; + /** + * + * const past = [1, 2, 3, 4, 5]; + * const present = 6; + * const future = [7, 8, 9, 10] + * const index = 1 + * + * newPast = [...past, present, ...future.slice(0, index) = [1, 2, 3, 4, 5, 6, 7]; + * newPresent = future[index] = 8; + * newFuture = futrue.slice(index+1) = [9, 10]; + * + */ + var newPast = __spread(past, [present], future.slice(0, index)); + var newPresent = future[index]; + var newFuture = future.slice(index + 1); + this.history.past = newPast; + this.history.present = newPresent; + this.history.future = newFuture; + this.update('Redo'); + }; + /** + * + * jump n steps in the past or forward + * + */ + StateHistoryPlugin.prototype.jump = function (n) { + if (n > 0) + return this.jumpToFuture(n - 1); + if (n < 0) + return this.jumpToPast(this.history.past.length + n); + }; + /** + * Clear the history + * + * @param customUpdateFn Callback function for only clearing part of the history + * + * @example + * + * stateHistory.clear((history) => { + * return { + * past: history.past, + * present: history.present, + * future: [] + * }; + * }); + */ + StateHistoryPlugin.prototype.clear = function (customUpdateFn) { + this.history = isFunction(customUpdateFn) + ? customUpdateFn(this.history) + : { + past: [], + present: null, + future: [] + }; + this.updateHasHistory(); + }; + StateHistoryPlugin.prototype.destroy = function (clearHistory) { + if (clearHistory === void 0) { clearHistory = false; } + if (clearHistory) { + this.clear(); + } + this.subscription.unsubscribe(); + }; + StateHistoryPlugin.prototype.ignoreNext = function () { + this.skip = true; + }; + StateHistoryPlugin.prototype.update = function (action) { + if (action === void 0) { action = 'Undo'; } + this.skipUpdate = true; + logAction("@StateHistory - " + action); + this.updateStore(this.history.present, this._entityId, this.property); + this.updateHasHistory(); + this.skipUpdate = false; + }; + return StateHistoryPlugin; + }(AkitaPlugin)); + + /** @class */ ((function (_super) { + __extends(EntityStateHistoryPlugin, _super); + function EntityStateHistoryPlugin(query, params) { + if (params === void 0) { params = {}; } + var _this = _super.call(this, query, params.entityIds) || this; + _this.query = query; + _this.params = params; + params.maxAge = toBoolean(params.maxAge) ? params.maxAge : 10; + _this.activate(); + _this.selectIds() + .pipe(skip(1)) + .subscribe(function (ids) { return _this.activate(ids); }); + return _this; + } + EntityStateHistoryPlugin.prototype.redo = function (ids) { + this.forEachId(ids, function (e) { return e.redo(); }); + }; + EntityStateHistoryPlugin.prototype.undo = function (ids) { + this.forEachId(ids, function (e) { return e.undo(); }); + }; + EntityStateHistoryPlugin.prototype.hasPast = function (id) { + if (this.hasEntity(id)) { + return this.getEntity(id).hasPast; + } + }; + EntityStateHistoryPlugin.prototype.hasFuture = function (id) { + if (this.hasEntity(id)) { + return this.getEntity(id).hasFuture; + } + }; + EntityStateHistoryPlugin.prototype.jumpToFuture = function (ids, index) { + this.forEachId(ids, function (e) { return e.jumpToFuture(index); }); + }; + EntityStateHistoryPlugin.prototype.jumpToPast = function (ids, index) { + this.forEachId(ids, function (e) { return e.jumpToPast(index); }); + }; + EntityStateHistoryPlugin.prototype.clear = function (ids) { + this.forEachId(ids, function (e) { return e.clear(); }); + }; + EntityStateHistoryPlugin.prototype.destroy = function (ids, clearHistory) { + if (clearHistory === void 0) { clearHistory = false; } + this.forEachId(ids, function (e) { return e.destroy(clearHistory); }); + }; + EntityStateHistoryPlugin.prototype.ignoreNext = function (ids) { + this.forEachId(ids, function (e) { return e.ignoreNext(); }); + }; + EntityStateHistoryPlugin.prototype.instantiatePlugin = function (id) { + return new StateHistoryPlugin(this.query, this.params, id); + }; + return EntityStateHistoryPlugin; + })(EntityCollectionPlugin)); + + var ÉÂĩ0 = function (head, current) { return JSON.stringify(head) !== JSON.stringify(current); }; + var dirtyCheckDefaultParams = { + comparator: ÉÂĩ0 + }; + function getNestedPath(nestedObj, path) { + var pathAsArray = path.split('.'); + return pathAsArray.reduce(function (obj, key) { return (obj && obj[key] !== 'undefined' ? obj[key] : undefined); }, nestedObj); + } + var DirtyCheckPlugin = /** @class */ (function (_super) { + __extends(DirtyCheckPlugin, _super); + function DirtyCheckPlugin(query, params, _entityId) { + var _this = _super.call(this, query) || this; + _this.query = query; + _this.params = params; + _this._entityId = _entityId; + _this.dirty = new BehaviorSubject(false); + _this.active = false; + _this._reset = new Subject(); + _this.isDirty$ = _this.dirty.asObservable().pipe(distinctUntilChanged()); + _this.reset$ = _this._reset.asObservable(); + _this.params = __assign({}, dirtyCheckDefaultParams, params); + if (_this.params.watchProperty) { + var watchProp = coerceArray(_this.params.watchProperty); + if (query instanceof QueryEntity && watchProp.includes('entities') && !watchProp.includes('ids')) { + watchProp.push('ids'); + } + _this.params.watchProperty = watchProp; + } + return _this; + } + DirtyCheckPlugin.prototype.reset = function (params) { + if (params === void 0) { params = {}; } + var currentValue = this.head; + if (isFunction(params.updateFn)) { + if (this.isEntityBased(this._entityId)) { + currentValue = params.updateFn(this.head, this.getQuery().getEntity(this._entityId)); + } + else { + currentValue = params.updateFn(this.head, this.getQuery().getValue()); + } + } + logAction("@DirtyCheck - Revert"); + this.updateStore(currentValue, this._entityId); + this._reset.next(); + }; + DirtyCheckPlugin.prototype.setHead = function () { + if (!this.active) { + this.activate(); + this.active = true; + } + else { + this.head = this._getHead(); + } + this.updateDirtiness(false); + return this; + }; + DirtyCheckPlugin.prototype.isDirty = function () { + return !!this.dirty.value; + }; + DirtyCheckPlugin.prototype.hasHead = function () { + return !!this.getHead(); + }; + DirtyCheckPlugin.prototype.destroy = function () { + this.head = null; + this.subscription && this.subscription.unsubscribe(); + this._reset && this._reset.complete(); + }; + DirtyCheckPlugin.prototype.isPathDirty = function (path) { + var head = this.getHead(); + var current = this.getQuery().getValue(); + var currentPathValue = getNestedPath(current, path); + var headPathValue = getNestedPath(head, path); + return this.params.comparator(currentPathValue, headPathValue); + }; + DirtyCheckPlugin.prototype.getHead = function () { + return this.head; + }; + DirtyCheckPlugin.prototype.activate = function () { + var _this = this; + this.head = this._getHead(); + /** if we are tracking specific properties select only the relevant ones */ + var source = this.params.watchProperty + ? this.params.watchProperty.map(function (prop) { + return _this.query + .select(function (state) { return state[prop]; }) + .pipe(map(function (val) { return ({ + val: val, + __akitaKey: prop + }); })); + }) + : [this.selectSource(this._entityId)]; + this.subscription = combineLatest.apply(void 0, __spread(source)).pipe(skip(1)) + .subscribe(function (currentState) { + if (isUndefined(_this.head)) + return; + /** __akitaKey is used to determine if we are tracking a specific property or a store change */ + var isChange = currentState.some(function (state) { + var head = state.__akitaKey ? _this.head[state.__akitaKey] : _this.head; + var compareTo = state.__akitaKey ? state.val : state; + return _this.params.comparator(head, compareTo); + }); + _this.updateDirtiness(isChange); + }); + }; + DirtyCheckPlugin.prototype.updateDirtiness = function (isDirty) { + this.dirty.next(isDirty); + }; + DirtyCheckPlugin.prototype._getHead = function () { + var head = this.getSource(this._entityId); + if (this.params.watchProperty) { + head = this.getWatchedValues(head); + } + return head; + }; + DirtyCheckPlugin.prototype.getWatchedValues = function (source) { + return this.params.watchProperty.reduce(function (watched, prop) { + watched[prop] = source[prop]; + return watched; + }, {}); + }; + return DirtyCheckPlugin; + }(AkitaPlugin)); + + /** @class */ ((function (_super) { + __extends(EntityDirtyCheckPlugin, _super); + function EntityDirtyCheckPlugin(query, params) { + if (params === void 0) { params = {}; } + var _this = _super.call(this, query, params.entityIds) || this; + _this.query = query; + _this.params = params; + _this._someDirty = new Subject(); + _this.someDirty$ = merge(_this.query.select(function (state) { return state.entities; }), _this._someDirty.asObservable()).pipe(auditTime(0), map(function () { return _this.checkSomeDirty(); })); + _this.params = __assign({}, dirtyCheckDefaultParams, params); + // TODO lazy activate? + _this.activate(); + _this.selectIds() + .pipe(skip(1)) + .subscribe(function (ids) { + _super.prototype.rebase.call(_this, ids, { afterAdd: function (plugin) { return plugin.setHead(); } }); + }); + return _this; + } + EntityDirtyCheckPlugin.prototype.setHead = function (ids) { + if (this.params.entityIds && ids) { + var toArray_1 = coerceArray(ids); + var someAreWatched = coerceArray(this.params.entityIds).some(function (id) { return toArray_1.indexOf(id) > -1; }); + if (someAreWatched === false) { + return this; + } + } + this.forEachId(ids, function (e) { return e.setHead(); }); + this._someDirty.next(); + return this; + }; + EntityDirtyCheckPlugin.prototype.hasHead = function (id) { + if (this.entities.has(id)) { + var entity = this.getEntity(id); + return entity.hasHead(); + } + return false; + }; + EntityDirtyCheckPlugin.prototype.reset = function (ids, params) { + if (params === void 0) { params = {}; } + this.forEachId(ids, function (e) { return e.reset(params); }); + }; + EntityDirtyCheckPlugin.prototype.isDirty = function (id, asObservable) { + if (asObservable === void 0) { asObservable = true; } + if (this.entities.has(id)) { + var entity = this.getEntity(id); + return asObservable ? entity.isDirty$ : entity.isDirty(); + } + return false; + }; + EntityDirtyCheckPlugin.prototype.someDirty = function () { + return this.checkSomeDirty(); + }; + EntityDirtyCheckPlugin.prototype.isPathDirty = function (id, path) { + if (this.entities.has(id)) { + var head = this.getEntity(id).getHead(); + var current = this.query.getEntity(id); + var currentPathValue = getNestedPath(current, path); + var headPathValue = getNestedPath(head, path); + return this.params.comparator(currentPathValue, headPathValue); + } + return null; + }; + EntityDirtyCheckPlugin.prototype.destroy = function (ids) { + this.forEachId(ids, function (e) { return e.destroy(); }); + /** complete only when the plugin destroys */ + if (!ids) { + this._someDirty.complete(); + } + }; + EntityDirtyCheckPlugin.prototype.instantiatePlugin = function (id) { + return new DirtyCheckPlugin(this.query, this.params, id); + }; + EntityDirtyCheckPlugin.prototype.checkSomeDirty = function () { + var e_1, _a; + var entitiesIds = this.resolvedIds(); + try { + for (var entitiesIds_1 = __values(entitiesIds), entitiesIds_1_1 = entitiesIds_1.next(); !entitiesIds_1_1.done; entitiesIds_1_1 = entitiesIds_1.next()) { + var id = entitiesIds_1_1.value; + if (this.getEntity(id).isDirty()) { + return true; + } + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (entitiesIds_1_1 && !entitiesIds_1_1.done && (_a = entitiesIds_1.return)) _a.call(entitiesIds_1); + } + finally { if (e_1) throw e_1.error; } + } + return false; + }; + return EntityDirtyCheckPlugin; + })(EntityCollectionPlugin)); + + /** + * Generate random guid + * + * @example + * + * { + * id: guid() + * } + * + * @remarks this isn't a GUID, but a 10 char random alpha-num + */ + function guid() { + return Math.random() + .toString(36) + .slice(2); + } + + var _a, _b; + var StoreAction; + (function (StoreAction) { + StoreAction["Update"] = "UPDATE"; + })(StoreAction || (StoreAction = {})); + (_a = {}, + _a[StoreAction.Update] = 'update', + _a); + var EntityStoreAction; + (function (EntityStoreAction) { + EntityStoreAction["Update"] = "UPDATE"; + EntityStoreAction["AddEntities"] = "ADD_ENTITIES"; + EntityStoreAction["SetEntities"] = "SET_ENTITIES"; + EntityStoreAction["UpdateEntities"] = "UPDATE_ENTITIES"; + EntityStoreAction["RemoveEntities"] = "REMOVE_ENTITIES"; + EntityStoreAction["UpsertEntities"] = "UPSERT_ENTITIES"; + EntityStoreAction["UpsertManyEntities"] = "UPSERT_MANY_ENTITIES"; + })(EntityStoreAction || (EntityStoreAction = {})); + (_b = {}, + _b[EntityStoreAction.Update] = 'update', + _b[EntityStoreAction.AddEntities] = 'add', + _b[EntityStoreAction.SetEntities] = 'set', + _b[EntityStoreAction.UpdateEntities] = 'update', + _b[EntityStoreAction.RemoveEntities] = 'remove', + _b[EntityStoreAction.UpsertEntities] = 'upsert', + _b[EntityStoreAction.UpsertManyEntities] = 'upsertMany', + _b); + + function combineQueries(observables) { + return combineLatest(observables).pipe(auditTime(0)); + } + + var immer_cjs_development = {}; + + Object.defineProperty(immer_cjs_development, '__esModule', { value: true }); + + var _ref; + + // Should be no imports here! + // Some things that should be evaluated before all else... + // We only want to know if non-polyfilled symbols are available + var hasSymbol = typeof Symbol !== "undefined" && typeof + /*#__PURE__*/ + Symbol("x") === "symbol"; + var hasMap = typeof Map !== "undefined"; + var hasSet = typeof Set !== "undefined"; + var hasProxies = typeof Proxy !== "undefined" && typeof Proxy.revocable !== "undefined" && typeof Reflect !== "undefined"; + /** + * The sentinel value returned by producers to replace the draft with undefined. + */ + + var NOTHING = hasSymbol ? + /*#__PURE__*/ + Symbol.for("immer-nothing") : (_ref = {}, _ref["immer-nothing"] = true, _ref); + /** + * To let Immer treat your class instances as plain immutable objects + * (albeit with a custom prototype), you must define either an instance property + * or a static property on each of your custom classes. + * + * Otherwise, your class instance will never be drafted, which means it won't be + * safe to mutate in a produce callback. + */ + + var DRAFTABLE = hasSymbol ? + /*#__PURE__*/ + Symbol.for("immer-draftable") : "__$immer_draftable"; + var DRAFT_STATE = hasSymbol ? + /*#__PURE__*/ + Symbol.for("immer-state") : "__$immer_state"; // Even a polyfilled Symbol might provide Symbol.iterator + + var iteratorSymbol = typeof Symbol != "undefined" && Symbol.iterator || "@@iterator"; + + var errors = { + 0: "Illegal state", + 1: "Immer drafts cannot have computed properties", + 2: "This object has been frozen and should not be mutated", + 3: function _(data) { + return "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + data; + }, + 4: "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.", + 5: "Immer forbids circular references", + 6: "The first or second argument to `produce` must be a function", + 7: "The third argument to `produce` must be a function or undefined", + 8: "First argument to `createDraft` must be a plain object, an array, or an immerable object", + 9: "First argument to `finishDraft` must be a draft returned by `createDraft`", + 10: "The given draft is already finalized", + 11: "Object.defineProperty() cannot be used on an Immer draft", + 12: "Object.setPrototypeOf() cannot be used on an Immer draft", + 13: "Immer only supports deleting array indices", + 14: "Immer only supports setting array indices and the 'length' property", + 15: function _(path) { + return "Cannot apply patch, path doesn't resolve: " + path; + }, + 16: 'Sets cannot have "replace" patches.', + 17: function _(op) { + return "Unsupported patch operation: " + op; + }, + 18: function _(plugin) { + return "The plugin for '" + plugin + "' has not been loaded into Immer. To enable the plugin, import and call `enable" + plugin + "()` when initializing your application."; + }, + 20: "Cannot use proxies if Proxy, Proxy.revocable or Reflect are not available", + 21: function _(thing) { + return "produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '" + thing + "'"; + }, + 22: function _(thing) { + return "'current' expects a draft, got: " + thing; + }, + 23: function _(thing) { + return "'original' expects a draft, got: " + thing; } - var Tm, Em, Im, wm, Am, Om = bm; - const km = (e,t,i)=>{ - i = Object.assign(Object.assign({}, e), { - method: "GET", - responseType: "text", - extendMaxTTFB: i - }); - return ml(i.url) ? Mc().load(i, t).pipe(ur(e=>({ - responseText: e.data.response.data, - responseURL: e.data.response.uri, - stats: e.stats - }))) : Oc(i, t).pipe(ur(([e,t])=>({ - responseText: e.responseText, - responseURL: e.responseURL, - stats: t - }))) + }; + function die(error) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; } - , Cm = (e,n,t,i,s,a,o,d,r)=>{ - const {url: l, itemId: u, mediaOptionId: c, mediaOptionType: h} = e - , p = xc(e, i); - return km({ - url: l, - xhrSetup: t.xhrSetup - }, p, r).pipe(ur(({responseText: e, stats: t})=>{ - var i = performance.now() - , r = bm.parseMediaOptionPlaylist(e, l, !0, a, d, u, c, h, s, n); - Lc(r.mediaOptionDetails); - var e = performance.now() - , r = r["mediaOptionDetails"] - , i = { - playlistLoadTimeMs: t.tload - t.trequest, - playlistParseTimeMs: e - i - }; - return o.setPlaylistSample(i), - { - mediaOptionDetails: r, - stats: t - } - } - ), (f = h, - m = c, - g = l, - e=>e.pipe(Un(e=>{ - if (e instanceof ou) - throw new nu(!1,"Timeout",0,$.PlaylistTimeoutError,!0,f,m,g); - if (e instanceof tu) - throw new nu(!1,e.message,e.code,{ - code: e.code, - text: "Playlist Network Error" - },!1,f,m,g); - throw e - } - )))); - var f, m, g + + { + var e = errors[error]; + var msg = !e ? "unknown error nr: " + error : typeof e === "function" ? e.apply(null, args) : e; + throw new Error("[Immer] " + msg); } - , Dm = (f,e,m,t,g)=>Bi(e).pipe(Ra(e=>{ - const {keyTagInfo: t, isInitSegment: i, iframe: r, byteRangeOffset: n} = f - , s = t["method"] - , {start: a, end: o} = n; - if ("AES-128" !== s) - return Bi(e); - { - !t.uri || t.iv || t.format && "identity" !== t.format || (t.iv = function(t) { - const i = new Uint8Array(16); - for (let e = 12; e < 16; e++) - i[e] = t >> 8 * (15 - e) & 255; - return i - }(f.mediaSeqNum)); - const n = e - , s = t.key.buffer - , d = t.iv.buffer - , l = o && (r || i) ? o - a : void 0 - , u = !m.enableWebCrypto || !!l - , c = s.slice(0) - , h = d.slice(0) - , p = { - useJSCrypto: u, - plainTextLength: l - }; - return g.decrypt(c, h, "AES-CBC", n, p) - } + } + + var ArchtypeObject = 0; + var ArchtypeArray = 1; + var ArchtypeMap = 2; + var ArchtypeSet = 3; + var ProxyTypeProxyObject = 0; + var ProxyTypeProxyArray = 1; + var ProxyTypeES5Object = 4; + var ProxyTypeES5Array = 5; + var ProxyTypeMap = 2; + var ProxyTypeSet = 3; + + /** Returns true if the given value is an Immer draft */ + + + + function isDraft(value) { + return !!value && !!value[DRAFT_STATE]; + } + /** Returns true if the given value can be drafted by Immer */ + + + + function isDraftable(value) { + if (!value) return false; + return isPlainObject(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!value.constructor[DRAFTABLE] || isMap(value) || isSet(value); + } + + + function isPlainObject(value) { + if (!value || typeof value !== "object") return false; + var proto = Object.getPrototypeOf(value); + return !proto || proto === Object.prototype; + } + function original(value) { + if (!isDraft(value)) die(23, value); + return value[DRAFT_STATE].base_; + } + + + var ownKeys = typeof Reflect !== "undefined" && Reflect.ownKeys ? Reflect.ownKeys : typeof Object.getOwnPropertySymbols !== "undefined" ? function (obj) { + return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)); + } : + /* istanbul ignore next */ + Object.getOwnPropertyNames; + var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || function getOwnPropertyDescriptors(target) { + // Polyfill needed for Hermes and IE, see https://github.com/facebook/hermes/issues/274 + var res = {}; + ownKeys(target).forEach(function (key) { + res[key] = Object.getOwnPropertyDescriptor(target, key); + }); + return res; + }; + function each(obj, iter, enumerableOnly) { + if (enumerableOnly === void 0) { + enumerableOnly = false; } - )); - class Mm { - constructor(e) { - this.option = e - } - get name() { - return this.option.name - } - get priority() { - return this.option.priority - } - get expiry() { - return this.option.expiry - } - filter(i, e) { - const r = this.option.initFn && this.option.initFn(i, e) || (e ? Object.assign({}, e) : {}); - let t = i; - return this.option.firstPassFn && i.forEach((e,t)=>this.option.firstPassFn(e, t, r, i)), - this.option.filterFn && (t = i.filter((e,t)=>this.option.filterFn(e, t, r, i))), - null != this.option.filterFn && 0 !== t.length || !this.option.minSortingFn || (t = i.sort((e,t)=>this.option.minSortingFn(e, t, r, i))), - this.option.finalFn && this.option.finalFn(t, r, i), - t - } + + if (getArchtype(obj) === ArchtypeObject) { + (enumerableOnly ? Object.keys : ownKeys)(obj).forEach(function (key) { + if (!enumerableOnly || typeof key !== "symbol") iter(key, obj[key], obj); + }); + } else { + obj.forEach(function (entry, index) { + return iter(index, entry, obj); + }); } - function Pm(e, t, i) { - return (t || []).reduce((e,t)=>t.filter(e, i), Array.from(e)) + } + + + function getArchtype(thing) { + /* istanbul ignore next */ + var state = thing[DRAFT_STATE]; + return state ? state.type_ > 3 ? state.type_ - 4 // cause Object and Array map back from 4 and 5 + : state.type_ // others are the same + : Array.isArray(thing) ? ArchtypeArray : isMap(thing) ? ArchtypeMap : isSet(thing) ? ArchtypeSet : ArchtypeObject; + } + + + function has(thing, prop) { + return getArchtype(thing) === ArchtypeMap ? thing.has(prop) : Object.prototype.hasOwnProperty.call(thing, prop); + } + + + function get(thing, prop) { + // @ts-ignore + return getArchtype(thing) === ArchtypeMap ? thing.get(prop) : thing[prop]; + } + + + function set(thing, propOrOldValue, value) { + var t = getArchtype(thing); + if (t === ArchtypeMap) thing.set(propOrOldValue, value);else if (t === ArchtypeSet) { + thing.delete(propOrOldValue); + thing.add(value); + } else thing[propOrOldValue] = value; + } + + + function is(x, y) { + // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js + if (x === y) { + return x !== 0 || 1 / x === 1 / y; + } else { + return x !== x && y !== y; } - function xm(t, e) { - return e.filter(e=>{ - return yl(t, null !== (e = e.url) && void 0 !== e ? e : null) - } - ) + } + + + function isMap(target) { + return hasMap && target instanceof Map; + } + + + function isSet(target) { + return hasSet && target instanceof Set; + } + + + function latest(state) { + return state.copy_ || state.base_; + } + + + function shallowCopy(base) { + if (Array.isArray(base)) return Array.prototype.slice.call(base); + var descriptors = getOwnPropertyDescriptors(base); + delete descriptors[DRAFT_STATE]; + var keys = ownKeys(descriptors); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var desc = descriptors[key]; + + if (desc.writable === false) { + desc.writable = true; + desc.configurable = true; + } // like object.assign, we will read any _own_, get/set accessors. This helps in dealing + // with libraries that trap values, like mobx or vue + // unlike object.assign, non-enumerables will be copied as well + + + if (desc.get || desc.set) descriptors[key] = { + configurable: true, + writable: true, + enumerable: desc.enumerable, + value: base[key] + }; } - function Rm() { - return [new Mm({ - name: "Remove Filter", - priority: 0, - filterFn: (t,e,i)=>!i || i.removed.every(e=>t.mediaOptionId !== e) - }), new Mm({ - name: "Penalty Box Filter", - priority: 1, - filterFn: (t,e,i)=>{ - const r = performance.now(); - return !i || i.penaltyBoxQueue.every(e=>e.expiry <= r || t.mediaOptionId !== e.mediaOptionId) - } - }), new Mm({ - name: "Compatible IDs Filter", - priority: 1, - filterFn: (t,e,i)=>!i || null == i.compatibleIds || i.compatibleIds.some(e=>e === t.mediaOptionId) - })] + + return Object.create(Object.getPrototypeOf(base), descriptors); + } + function freeze(obj, deep) { + if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj)) return; + + if (getArchtype(obj) > 1 + /* Map or Set */ + ) { + obj.set = obj.add = obj.clear = obj.delete = dontMutateFrozenCollections; + } + + Object.freeze(obj); + if (deep) each(obj, function (key, value) { + return freeze(value, true); + }, true); + } + + function dontMutateFrozenCollections() { + die(2); + } + + function isFrozen(obj) { + if (obj == null || typeof obj !== "object") return true; // See #600, IE dies on non-objects in Object.isFrozen + + return Object.isFrozen(obj); + } + + /** Plugin utilities */ + + var plugins = {}; + function getPlugin(pluginKey) { + var plugin = plugins[pluginKey]; + + if (!plugin) { + die(18, pluginKey); + } // @ts-ignore + + + return plugin; + } + function loadPlugin(pluginKey, implementation) { + if (!plugins[pluginKey]) plugins[pluginKey] = implementation; + } + + var currentScope; + function getCurrentScope() { + if ( !currentScope) die(0); + return currentScope; + } + + function createScope(parent_, immer_) { + return { + drafts_: [], + parent_: parent_, + immer_: immer_, + // Whenever the modified draft contains a draft from another scope, we + // need to prevent auto-freezing so the unowned draft can be finalized. + canAutoFreeze_: true, + unfinalizedDrafts_: 0 + }; + } + + function usePatchesInScope(scope, patchListener) { + if (patchListener) { + getPlugin("Patches"); // assert we have the plugin + + scope.patches_ = []; + scope.inversePatches_ = []; + scope.patchListener_ = patchListener; } - class Lm extends Od { - constructor(e, t, i) { - super(e), - this.itemId = t, - this.mediaOptionType = i, - this.allowFilters = this._initFilters() - } - get mediaOptionList() { - var e; - return (null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.mediaOptions) || null - } - get mediaOptionList$() { - return this.mediaOptionListInfo$.pipe(ur(({mediaOptions: e})=>e)) - } - mediaOptionFromId(t) { - var e; - return null !== (e = (null !== (e = this.mediaOptionList) && void 0 !== e ? e : []).find(e=>e.mediaOptionId === t)) && void 0 !== e ? e : null - } - _getFilteredList(e) { - return Pm(e.mediaOptions, this.allowFilters, e) - } - get filteredMediaOptionList() { - return this.mediaOptionListInfo ? this._getFilteredList(this.mediaOptionListInfo) : null - } - get filteredMediaOptionList$() { - return this.mediaOptionListInfo$.pipe(Ra(e=>{ - const t = [Ul] - , i = performance.now(); - for (const r of e.penaltyBoxQueue) - ne(r.expiry) && r.expiry > i && t.push(vn(r.expiry - i)); - return nn(...t).pipe(ur(()=>this._getFilteredList(e))) - } - ), yd()) - } - get preferredMediaOptionList() { - return this.filteredMediaOptionList ? xm(this.preferredHost, this.filteredMediaOptionList) : [] - } - get preferredMediaOptionList$() { - return Zd([this.preferredHost$, this.filteredMediaOptionList$]).pipe(ur(([e,t])=>xm(e, t))) - } - getNewHost(e) { - e = this.getFallbackVariant(e, !1, !0); - return null != e && e.url ? gl(e.url) : this.preferredHost - } + } + function revokeScope(scope) { + leaveScope(scope); + scope.drafts_.forEach(revokeDraft); // @ts-ignore + + scope.drafts_ = null; + } + function leaveScope(scope) { + if (scope === currentScope) { + currentScope = scope.parent_; } - function _m(e) { - return "PQ" === e.videoRange || "HLG" === e.videoRange + } + function enterScope(immer) { + return currentScope = createScope(currentScope, immer); + } + + function revokeDraft(draft) { + var state = draft[DRAFT_STATE]; + if (state.type_ === ProxyTypeProxyObject || state.type_ === ProxyTypeProxyArray) state.revoke_();else state.revoked_ = true; + } + + function processResult(result, scope) { + scope.unfinalizedDrafts_ = scope.drafts_.length; + var baseDraft = scope.drafts_[0]; + var isReplaced = result !== undefined && result !== baseDraft; + if (!scope.immer_.useProxies_) getPlugin("ES5").willFinalizeES5_(scope, result, isReplaced); + + if (isReplaced) { + if (baseDraft[DRAFT_STATE].modified_) { + revokeScope(scope); + die(4); + } + + if (isDraftable(result)) { + // Finalize the result in case it contains (or is) a subset of the draft. + result = finalize(scope, result); + if (!scope.parent_) maybeFreeze(scope, result); + } + + if (scope.patches_) { + getPlugin("Patches").generateReplacementPatches_(baseDraft[DRAFT_STATE], result, scope.patches_, scope.inversePatches_); + } + } else { + // Finalize the base draft. + result = finalize(scope, baseDraft, []); } - function Nm(e, t) { - return t.iframes === e + + revokeScope(scope); + + if (scope.patches_) { + scope.patchListener_(scope.patches_, scope.inversePatches_); } - function Fm(e, t, i, r) { - return !r || i.bitrate > r.bitrate && i.bitrate <= e.bitrate ? Tm.Better : i.bitrate === r.bitrate ? Tm.Same : Tm.Worse + + return result !== NOTHING ? result : undefined; + } + + function finalize(rootScope, value, path) { + // Don't recurse in tho recursive data structures + if (isFrozen(value)) return value; + var state = value[DRAFT_STATE]; // A plain object, might need freezing, might contain drafts + + if (!state) { + each(value, function (key, childValue) { + return finalizeProperty(rootScope, state, value, key, childValue, path); + }, true // See #590, don't recurse into non-enumarable of non drafted objects + ); + return value; + } // Never finalize drafts owned by another scope. + + + if (state.scope_ !== rootScope) return value; // Unmodified draft, return the (frozen) original + + if (!state.modified_) { + maybeFreeze(rootScope, state.base_, true); + return state.base_; + } // Not finalized yet, let's do that now + + + if (!state.finalized_) { + state.finalized_ = true; + state.scope_.unfinalizedDrafts_--; + var result = // For ES5, create a good copy from the draft first, with added keys and without deleted keys. + state.type_ === ProxyTypeES5Object || state.type_ === ProxyTypeES5Array ? state.copy_ = shallowCopy(state.draft_) : state.copy_; // Finalize all children of the copy + // For sets we clone before iterating, otherwise we can get in endless loop due to modifying during iteration, see #628 + // Although the original test case doesn't seem valid anyway, so if this in the way we can turn the next line + // back to each(result, ....) + + each(state.type_ === ProxyTypeSet ? new Set(result) : result, function (key, childValue) { + return finalizeProperty(rootScope, state, result, key, childValue, path); + }); // everything inside is frozen, we can freeze here + + maybeFreeze(rootScope, result, false); // first time finalizing, let's create those patches + + if (path && rootScope.patches_) { + getPlugin("Patches").generatePatches_(state, path, rootScope.patches_, rootScope.inversePatches_); + } } - function Bm(e, t) { - return e && !t ? -1 : !e && t ? 1 : 0 + + return state.copy_; + } + + function finalizeProperty(rootScope, parentState, targetObject, prop, childValue, rootPath) { + if ( childValue === targetObject) die(5); + + if (isDraft(childValue)) { + var path = rootPath && parentState && parentState.type_ !== ProxyTypeSet && // Set objects are atomic since they have no keys. + !has(parentState.assigned_, prop) // Skip deep patches for assigned keys. + ? rootPath.concat(prop) : undefined; // Drafts owned by `scope` are finalized here. + + var res = finalize(rootScope, childValue, path); + set(targetObject, prop, res); // Drafts from another scope must prevented to be frozen + // if we got a draft back from finalize, we're in a nested produce and shouldn't freeze + + if (isDraft(res)) { + rootScope.canAutoFreeze_ = false; + } else return; + } // Search new objects for unfinalized drafts. Frozen objects should never contain drafts. + + + if (isDraftable(childValue) && !isFrozen(childValue)) { + if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) { + // optimization: if an object is not a draft, and we don't have to + // deepfreeze everything, and we are sure that no drafts are left in the remaining object + // cause we saw and finalized all drafts already; we can stop visiting the rest of the tree. + // This benefits especially adding large data tree's without further processing. + // See add-data.js perf test + return; + } + + finalize(rootScope, childValue); // immer deep freezes plain objects, so if there is no parent state, we freeze as well + + if (!parentState || !parentState.scope_.parent_) maybeFreeze(rootScope, childValue); } - (dd = Tm = Tm || {})[dd.Better = 1] = "Better", - dd[dd.Same = 0] = "Same", - dd[dd.Worse = -1] = "Worse"; - class Um extends Lm { - constructor(e, t) { - super(e, t, ul.Variant) - } - static makeFilters() { - return [...Rm().concat([new Mm({ - name: "HDR Filter", - priority: 1, - filterFn: (e,t,i)=>!i || (i.hasHdrLevels && i.preferHDR) === _m(e) - }), new Mm({ - name: "Viewport Filter", - priority: 1, - firstPassFn: (e,t,i)=>{ - if (i && e && !e.iframes && e.videoCodec) { - const t = !i.lowestBitrate || e.bitrate < i.lowestBitrate ? e.bitrate : i.lowestBitrate; - i.lowestBitrate = t - } - } - , - filterFn: (e,t,i)=>!(e && i && i.viewportInfo && e.videoCodec && i.lowestBitrate) || function(e, t) { - return e.width < 1.35 * t.width && e.height < 1.35 * t.height && e.width * e.height < t.width * t.height * 1.35 - }({ - width: e.width, - height: e.height - }, i.viewportInfo) || e.bitrate === i.lowestBitrate - }), new Mm({ - name: "HDCP Filter", - priority: 2, - filterFn: (e,t,i)=>!i || !rm(i.maxHdcpLevel) || nm(e.hdcpLevel) < nm(i.maxHdcpLevel) - })])].sort((e,t)=>{ - return (null !== (e = e.priority) && void 0 !== e ? e : Number.MAX_SAFE_INTEGER) - (null !== (t = t.priority) && void 0 !== t ? t : Number.MAX_SAFE_INTEGER) - } - ) - } - _initFilters() { - return Um.kAllowFilters - } - get preferredHost() { - var e; - return null !== (e = null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.preferredHost) && void 0 !== e ? e : null - } - get preferredHost$() { - return this.selectEntity(this.itemId, e=>{ - return null !== (e = null == e ? void 0 : e.mediaOptionListTuple[ul.Variant].preferredHost) && void 0 !== e ? e : null - } - ) - } - get mediaOptionListInfo() { - var e; - return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.mediaOptionListTuple[ul.Variant]) && void 0 !== e ? e : null - } - get mediaOptionListInfo$() { - return this.selectEntity(this.itemId, e=>{ - return null === (e = null == e ? void 0 : e.mediaOptionListTuple) || void 0 === e ? void 0 : e[ul.Variant] - } - ).pipe(Up()) - } - get hdrMode$() { - return this.mediaOptionListInfo$.pipe(ur(e=>!0 === e.preferHDR && e.hasHdrLevels), Es()) - } - get maxHdcpLevel$() { - return this.selectEntity(this.itemId, e=>{ - e = null === (e = null == e ? void 0 : e.mediaOptionListTuple) || void 0 === e ? void 0 : e[ul.Variant]; - return null == e ? void 0 : e.maxHdcpLevel - } - ).pipe(Es()) - } - listFallbackVariants(t, e, i, r, n) { - var s = this.mediaOptionListInfo - , a = null === (o = this.mediaOptionList) || void 0 === o ? void 0 : o.find(e=>e.mediaOptionId === t); - if (!a || !s) - return null; - var o = this.makeFilteredListFromVariant(a, e, n); - if (!o) - return null; - e = gl(a.url), - s = s.hasScore; - return Um._listFallbackVariants(o, a, e, s, i, r, n) - } - getFallbackVariant(t, e, i, r) { - var n = this.mediaOptionListInfo - , s = null === (s = this.mediaOptionList) || void 0 === s ? void 0 : s.find(e=>e.mediaOptionId === t); - if (!s || !n) - return null; - e = this.makeFilteredListFromVariant(s, e, r); - if (!e) - return null; - r = gl(s.url), - n = n.hasScore; - return Um._getFallbackVariant(e, s, r, n, i) - } - makeFilteredListFromVariant(e, t, i) { - let r = this.mediaOptionListInfo; - if (!e || !this.mediaOptionList || !r) - return null; - r = Object.assign(Object.assign({}, r), { - includeAllEligiblePathways: !0 - }); - e = Array.from(this.mediaOptionList); - let n = t ? Pm(e, this.allowFilters, Object.assign(Object.assign({}, r), { - preferHDR: !1, - compatibleIds: null - })) : this._getFilteredList(r); - return n ? (i && 0 < i.length && (n = n.filter(e=>!i.includes(e.mediaOptionId))), - n) : null - } - get hasIframes() { - var e; - return null !== (e = null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.hasIframeLevels) && void 0 !== e && e - } - canSwitchToSDR(e, t, i=!1) { - var r = this.mediaOptionListInfo; - if (!this.mediaOptionList || !r) - return !1; - var n = this.mediaOptionFromId(e); - if (!n) - return !1; - if (!_m(n)) - return !1; - var s = gl(n.url) - , e = Pm(Array.from(this.mediaOptionList), this.allowFilters, Object.assign(Object.assign({}, r), { - preferHDR: !1, - compatibleIds: null - })) - , r = r.hasScore; - return null != Um._getFallbackVariant(e, n, s, r, t, i) - } - static _listFallbackVariants(e, r, n, t, s, a=!1, i=null) { - let o = !1; - const d = function(e, s, a) { - const t = [...e] - , o = gl(s.url) - , d = s.audioGroupId; - return t.sort((e,t)=>{ - let i = 0; - var r = a && ne(e.score) && ne(t.score) - , n = r ? e.score > t.score && e.score <= s.score : e.bitrate > t.bitrate && e.bitrate <= s.bitrate - , r = r ? e.score === t.score : e.bitrate === t.bitrate; - return n ? i = -1 : r ? (i = Bm(yl(o, e.url), yl(o, t.url)), - 0 === i && (i = Bm(!d || e.audioGroupId === d, !d || t.audioGroupId === d))) : i = 1, - i - } - ), - t - }(e.filter(e=>{ - var t = !(e.iframes !== r.iframes || s && yl(n, e.url)) - , i = a ? e.bitrate < r.bitrate : e.bitrate <= r.bitrate - , i = t && i; - return r.mediaOptionId === e.mediaOptionId ? (o = i, - !1) : i - } - ), r, t); - return !o || i && i.includes(r.mediaOptionId) || d.unshift(r), - d - } - static _getFallbackVariant(e, t, i, r, n, s=!1) { - let a = null; - e = (e = s ? e.filter(e=>e.bitrate < t.bitrate) : e).filter(e=>e.mediaOptionId !== t.mediaOptionId && e.iframes === t.iframes); - if (n && null != i) - for (const o of e) - Fm(t, 0, o, a) !== Tm.Better || yl(i, o.url) || (a = o); - else - for (const o of e) { - const r = Fm(t, 0, o, a); - r !== Tm.Better && (r !== Tm.Same || !yl(i, o.url) || yl(i, a.url) && o.audioGroupId !== t.audioGroupId) || (a = o) - } - return a - } - getMatchingVariant(e, t) { - var i = this.mediaOptionFromId(e) - , r = gl(null == i ? void 0 : i.url) - , n = t.mediaOptionType === ul.AltAudio ? "audioGroupId" : "subtitleGroupId"; - let s = null; - this.mediaOptionListInfo.hasScore; - for (const e of this.filteredMediaOptionList) - if (e[n] === t.groupId) { - if (!i) { - s = e; - break - } - var a = Fm(i, 0, e, s); - a !== Tm.Better && (a !== Tm.Same || s.mediaOptionId === i.mediaOptionId || e.mediaOptionId !== i.mediaOptionId && !yl(r, e.url)) || (s = e) - } - return s - } - get currentPathwayID() { - var e; - return null === (e = this.mediaOptionListInfo) || void 0 === e ? void 0 : e.currentPathwayID - } + } + + function maybeFreeze(scope, value, deep) { + if (deep === void 0) { + deep = false; } - function $m(e, t) { - switch (e) { - case Em.SendAlternateToPenaltyBox: - e = Em.RetryRequest, - 401 !== t && 403 !== t && 407 !== t && t !== $.CorruptStream.code && t !== $.LivePlaylistUpdateError.code || (e = Em.SendEndCallback); - break; - case Em.RemoveAlternatePermanently: - e = Em.SendEndCallback - } - return e + + if (scope.immer_.autoFreeze_ && scope.canAutoFreeze_) { + freeze(value, deep); } - function Vm(e, t, i, r, n, s, a, o=!1) { - const d = s.mediaOptionListQueries[n] - , l = 0 != (e.errorActionFlags & Im.MoveAllAlternatesMatchingHost) - , u = s.mediaOptionListQueries[n].mediaOptionFromId(r) - , c = a.getFallbackMediaOptionTupleFromMediaOptionId(s, n, r, u.backingMediaOptionId, !1, l, o); - let {errorAction: h, errorActionFlags: p} = e; - return s.isValidMediaOptionTuple(c) ? yl(d.preferredHost, c[n].url) && (p &= ~Im.MoveAllAlternatesMatchingHost) : (t || (h = $m(h, i), - p = 0), - d instanceof Um && (!0 === d.mediaOptionFromId(r).iframes ? (h = Em.DoNothing, - p = 0) : !t && a.canSwitchToSDR(s, r, l, o) && (h = e.errorAction, - p = Im.SwitchToSDR))), - { - errorAction: h, - errorActionFlags: p - } + } + + /** + * Returns a new draft of the `base` object. + * + * The second argument is the parent draft-state (used internally). + */ + + function createProxyProxy(base, parent) { + var isArray = Array.isArray(base); + var state = { + type_: isArray ? ProxyTypeProxyArray : ProxyTypeProxyObject, + // Track which produce call this is associated with. + scope_: parent ? parent.scope_ : getCurrentScope(), + // True for both shallow and deep changes. + modified_: false, + // Used during finalization. + finalized_: false, + // Track which properties have been assigned (true) or deleted (false). + assigned_: {}, + // The parent draft state. + parent_: parent, + // The base state. + base_: base, + // The base proxy. + draft_: null, + // The base copy with any updated values. + copy_: null, + // Called by the `produce` function. + revoke_: null, + isManual_: false + }; // the traps must target something, a bit like the 'real' base. + // but also, we need to be able to determine from the target what the relevant state is + // (to avoid creating traps per instance to capture the state in closure, + // and to avoid creating weird hidden properties as well) + // So the trick is to use 'state' as the actual 'target'! (and make sure we intercept everything) + // Note that in the case of an array, we put the state in an array to have better Reflect defaults ootb + + var target = state; + var traps = objectTraps; + + if (isArray) { + target = [state]; + traps = arrayTraps; } - function Km(e) { - let t, i = 0; - switch (e) { - case 0: - t = Em.SendAlternateToPenaltyBox, - i = Im.MoveAllAlternatesMatchingHost; - break; - case 410: - t = Em.RemoveAlternatePermanently; - break; - case 500: - case 502: - case 503: - case 504: - case 404: - case 409: - case 401: - case 403: - case 407: - case $.LivePlaylistUpdateError.code: - case $.PlaylistNotReceived.code: - default: - t = Em.SendAlternateToPenaltyBox, - i = 0 - } - return { - errorAction: t, - errorActionFlags: i + + var _Proxy$revocable = Proxy.revocable(target, traps), + revoke = _Proxy$revocable.revoke, + proxy = _Proxy$revocable.proxy; + + state.draft_ = proxy; + state.revoke_ = revoke; + return proxy; + } + /** + * Object drafts + */ + + var objectTraps = { + get: function get(state, prop) { + if (prop === DRAFT_STATE) return state; + var source = latest(state); + + if (!has(source, prop)) { + // non-existing or non-own property... + return readPropFromProto(state, source, prop); + } + + var value = source[prop]; + + if (state.finalized_ || !isDraftable(value)) { + return value; + } // Check for existing draft in modified state. + // Assigned values are never drafted. This catches any drafts we created, too. + + + if (value === peek(state.base_, prop)) { + prepareCopy(state); + return state.copy_[prop] = createProxy(state.scope_.immer_, value, state); + } + + return value; + }, + has: function has(state, prop) { + return prop in latest(state); + }, + ownKeys: function ownKeys(state) { + return Reflect.ownKeys(latest(state)); + }, + set: function set(state, prop + /* strictly not, but helps TS */ + , value) { + var desc = getDescriptorFromProto(latest(state), prop); + + if (desc === null || desc === void 0 ? void 0 : desc.set) { + // special case: if this write is captured by a setter, we have + // to trigger it with the correct context + desc.set.call(state.draft_, value); + return true; + } + + if (!state.modified_) { + // the last check is because we need to be able to distinguish setting a non-existig to undefined (which is a change) + // from setting an existing property with value undefined to undefined (which is not a change) + var current = peek(latest(state), prop); // special case, if we assigning the original value to a draft, we can ignore the assignment + + var currentState = current === null || current === void 0 ? void 0 : current[DRAFT_STATE]; + + if (currentState && currentState.base_ === value) { + state.copy_[prop] = value; + state.assigned_[prop] = false; + return true; } + + if (is(value, current) && (value !== undefined || has(state.base_, prop))) return true; + prepareCopy(state); + markChanged(state); + } // @ts-ignore + + + state.copy_[prop] = value; + state.assigned_[prop] = true; + return true; + }, + deleteProperty: function deleteProperty(state, prop) { + // The `undefined` check is a fast path for pre-existing keys. + if (peek(state.base_, prop) !== undefined || prop in state.base_) { + state.assigned_[prop] = false; + prepareCopy(state); + markChanged(state); + } else { + // if an originally not assigned property was deleted + delete state.assigned_[prop]; + } // @ts-ignore + + + if (state.copy_) delete state.copy_[prop]; + return true; + }, + // Note: We never coerce `desc.value` into an Immer draft, because we can't make + // the same guarantee in ES5 mode. + getOwnPropertyDescriptor: function getOwnPropertyDescriptor(state, prop) { + var owner = latest(state); + var desc = Reflect.getOwnPropertyDescriptor(owner, prop); + if (!desc) return desc; + return { + writable: true, + configurable: state.type_ !== ProxyTypeProxyArray || prop !== "length", + enumerable: desc.enumerable, + value: owner[prop] + }; + }, + defineProperty: function defineProperty() { + die(11); + }, + getPrototypeOf: function getPrototypeOf(state) { + return Object.getPrototypeOf(state.base_); + }, + setPrototypeOf: function setPrototypeOf() { + die(12); } - function Hm(i, r, n, s, a, o, d) { - var {errorAction: l, errorActionFlags: u} = i; - let e = !0; - switch (l) { - case Em.RemoveAlternatePermanently: - case Em.SendAlternateToPenaltyBox: - { - if (null == a || null == o) - return r.handled = !1; - const i = n.itemId; - let e = o - , t = n.mediaOptionListQueries[a].mediaOptionFromId(o); - t.backingMediaOptionId && (e = t.backingMediaOptionId, - t = n.mediaOptionListQueries[a].mediaOptionFromId(e)); - var c = 0 != (u & Im.MoveAllAlternatesMatchingHost) - , h = 0 != (u & Im.MoveAllAlternatesMatchingHDCP) - , p = 0 != (u & Im.SwitchToSDR) - , f = l === Em.RemoveAlternatePermanently; - if (h && "hdcpLevel"in t) { - const r = t.hdcpLevel; - s.setMaxHdcpLevel(i, r) - } - if (p && s.switchToSDROnly(i), - c) { - const r = gl(t.url); - s.moveAllWithMatchingHosts(i, a, r, f) - } else - f ? s.removePermanently(i, a, e) : s.addToPenaltyBox(i, a, e); - if (n.enabledMediaOptionIdByType(a) === o) { - let e = [Ol, Ol, Ol]; - e = s.getFallbackMediaOptionTupleFromMediaOptionId(n, a, o, null, !1, c, d), - n.isValidMediaOptionTuple(e) ? s.setPreferredHost(i, gl(e[ul.Variant].url)) : r.fatal = !0, - r.fatal && (e = [Ol, Ol, Ol]), - s.setNextMediaOptions(n.itemId, e) - } - break - } - case Em.SendEndCallback: - r.fatal = !0; - break; - case Em.RetryRequest: - case Em.DoNothing: - default: - e = !1 - } - return r.handled = e, - e + }; + /** + * Array drafts + */ + + var arrayTraps = {}; + each(objectTraps, function (key, fn) { + // @ts-ignore + arrayTraps[key] = function () { + arguments[0] = arguments[0][0]; + return fn.apply(this, arguments); + }; + }); + + arrayTraps.deleteProperty = function (state, prop) { + if ( isNaN(parseInt(prop))) die(13); + return objectTraps.deleteProperty.call(this, state[0], prop); + }; + + arrayTraps.set = function (state, prop, value) { + if ( prop !== "length" && isNaN(parseInt(prop))) die(14); + return objectTraps.set.call(this, state[0], prop, value, state[0]); + }; // Access a property without creating an Immer draft. + + + function peek(draft, prop) { + var state = draft[DRAFT_STATE]; + var source = state ? latest(state) : draft; + return source[prop]; + } + + function readPropFromProto(state, source, prop) { + var _desc$get; + + var desc = getDescriptorFromProto(source, prop); + return desc ? "value" in desc ? desc.value : // This is a very special case, if the prop is a getter defined by the + // prototype, we should invoke it with the draft as context! + (_desc$get = desc.get) === null || _desc$get === void 0 ? void 0 : _desc$get.call(state.draft_) : undefined; + } + + function getDescriptorFromProto(source, prop) { + // 'in' checks proto! + if (!(prop in source)) return undefined; + var proto = Object.getPrototypeOf(source); + + while (proto) { + var desc = Object.getOwnPropertyDescriptor(proto, prop); + if (desc) return desc; + proto = Object.getPrototypeOf(proto); } - function jm(e, t) { - t instanceof ru || t instanceof nu || t instanceof au || (t instanceof uu || t instanceof lu) && oe(t.keyuri) + + return undefined; + } + + function markChanged(state) { + if (!state.modified_) { + state.modified_ = true; + + if (state.parent_) { + markChanged(state.parent_); + } } - function qm(t, i, r) { - if (t.handled = !0, - r && i < r.maxNumRetry && ne(r.retryDelayMs)) { - let e; - return e = "linear" === r.backoff ? (i + 1) * r.retryDelayMs : Math.pow(2, i) * r.retryDelayMs, - e = Math.min(r.maxRetryDelayMs, e), - jm(0, t), - vn(e) - } - return t.fatal = !0, - jm(0, t), - Ui(t) + } + function prepareCopy(state) { + if (!state.copy_) { + state.copy_ = shallowCopy(state.base_); } - function Qm(e, t, i, r, n, s, a, o, d=!1) { - return (null == r ? void 0 : r.errorAction) === Em.RetryRequest ? qm(e, t, i, s.logger) : Gm(e, 0, r, n, s, a, o, d) + } + + var Immer = + /*#__PURE__*/ + function () { + function Immer(config) { + this.useProxies_ = hasProxies; + this.autoFreeze_ = true + /* istanbul ignore next */ + ; + if (typeof (config === null || config === void 0 ? void 0 : config.useProxies) === "boolean") this.setUseProxies(config.useProxies); + if (typeof (config === null || config === void 0 ? void 0 : config.autoFreeze) === "boolean") this.setAutoFreeze(config.autoFreeze); + this.produce = this.produce.bind(this); + this.produceWithPatches = this.produceWithPatches.bind(this); } - function Gm(e, t, i, r, n, s, a, o=!1) { - const d = new Ji; - return sd(()=>{ - i && (jm(n.logger, e), - Hm(i, e, r, n, s, a, o)), - d.error(e) - } - ), - d - } - function Wm(t, i, r, n) { - return e=>e.pipe(Un(e=>{ - if (t.logger.error(`Got demux error ${e.message}`), - e instanceof D || e instanceof F) { - Em.SendAlternateToPenaltyBox; - return Gm(e, 0, { - errorAction: e.fatal ? Em.SendEndCallback : e instanceof F ? Em.SendAlternateToPenaltyBox : Em.RemoveAlternatePermanently, - errorActionFlags: 0 - }, i, t, r, n) - } - throw e - } - )) - } - function zm(e, t, i, r, n) { - e = null !== (e = null === (e = n.getKeyInfo(e)) || void 0 === e ? void 0 : e.mediaOptionIds) && void 0 !== e ? e : []; - for (const s of e) - for (const n of i.mediaOptionListQueries) - null != n.mediaOptionFromId(s) && r.updateConsecutiveTimeouts(i.itemId, n.mediaOptionType, t, "key") - } - function Xm(r, t, e, n, s, a) { - const o = n.logger - , i = s.enabledMediaOptionKeys - , d = []; - for (const t of r.mediaOptionIds) { - const r = i.some(e=>e.mediaOptionId === t) - , e = s.mediaOptionListQueries.find(e=>null != e.mediaOptionFromId(t)); - if (e) { - const n = e.mediaOptionType - , a = { - mediaOptionId: t, - mediaOptionType: n - }; - r ? d.push(a) : d.unshift(a) - } else - o.warn(`Couldn't find query for ${t}`) - } - const l = new Ji; - return sd(()=>{ - const e = r instanceof lu; - zm(r.keyuri, e, s, n, a); - let t, i = !1; - for (const {mediaOptionId: e, mediaOptionType: a} of d) - t = function(e, t, i, r, n) { - let s = { - errorAction: Em.SendAlternateToPenaltyBox, - errorActionFlags: 0 - }; - if (e instanceof lu) - s.errorAction = Em.SendAlternateToPenaltyBox; - else { - const t = e.isOkToRetry; - e.keyErrorReason === Xl.OutputRestricted ? (s.errorAction = Em.RemoveAlternatePermanently, - s.errorActionFlags |= Im.MoveAllAlternatesMatchingHDCP) : t ? s = Km(e.code) : s.errorAction = Em.RemoveAlternatePermanently - } - s.errorActionFlags &= ~Im.MoveAllAlternatesMatchingHost; - var a = r.enabledMediaOptionIdByType(i); - return t === a ? Vm(s, !1, e.code, a, i, r, n, e.isTimeout) : s - }(r, e, a, s, n), - o.error(`[Keys] handleNetworkError uri=${oe(r.keyuri)} mediaOptionId=${e} mediaOptionType=${a} action=${JSON.stringify(t)}`), - t.errorAction === Em.RetryRequest && (i = !0), - Hm(t, r, s, n, a, e); - i ? (l.next(), - l.complete()) : (jm(0, r), - l.error(r)) - } - ), - l.pipe(Ra(()=>qm(r, t, e, n.logger))) - } - function Ym(t, i, r, n, s, a, o, d) { - return n = Math.max(0, n), - e=>e.pipe(Ja(()=>{ - null != i && o.updateConsecutiveTimeouts(t, i, !1, "load") - } - ), ya(e=>e.pipe(Kr((e,t)=>function(e, t, i, r, n, s, a, o) { - var d; - if (!(e instanceof p)) - return Ui(e); - let l, u, c, h = !1; - if (e instanceof ru) - c = { - errorAction: $m(Km((d = e).response.code).errorAction, d.response.code), - errorActionFlags: 0 - }; - else if (e instanceof nu || e instanceof au) { - ({mediaOptionType: u, mediaOptionId: l, isTimeout: h} = e); - const t = null === (d = s.mediaOptionListQueries[u]) || void 0 === d ? void 0 : d.mediaOptionFromId(l); - if (!r && e.isTimeout && null != t && (!("iframes"in t) || !0 !== t.iframes) && (a.updateConsecutiveTimeouts(s.itemId, e.mediaOptionType, !0, "load"), - e instanceof au && e.stats)) { - const t = performance.now(); - o.setBandwidthSample(Object.assign(Object.assign({}, e.stats), { - tfirst: e.stats.tfirst || t, - tload: e.stats.tload || t, - complete: !0, - mediaOptionType: u - })) - } - c = function(e, t, i, r, n) { - var s = e.response.code; - let a = Km(s); - var {mediaOptionId: o, mediaOptionType: d} = e; - return t ? a.errorActionFlags &= ~Im.MoveAllAlternatesMatchingHost : a = function(e, t, i, r, n) { - let {errorAction: s, errorActionFlags: a} = t; - if (e.isTimeout) { - const t = e["mediaOptionType"] - , o = null !== (n = null === (n = n.getErrorInfoByType(t)) || void 0 === n ? void 0 : n.timeouts.load) && void 0 !== n ? n : 0; - !i && r <= o && (s = Em.DoNothing, - a = 0) - } - return { - errorAction: s, - errorActionFlags: a - } - }(e, a, t, i, r), - a = Vm(a, t, s, o, d, r, n, e.isTimeout), - a - }(e, r, n, s, a) - } - return Qm(e, t, i, c, s, a, u, l, h) - }(e, t, Rc(e, r), s, n, a, o, d))))) - } - Um.kAllowFilters = Um.makeFilters(), - (dd = Em = Em || {})[dd.DoNothing = 0] = "DoNothing", - dd[dd.SendEndCallback = 1] = "SendEndCallback", - dd[dd.SendAlternateToPenaltyBox = 2] = "SendAlternateToPenaltyBox", - dd[dd.RemoveAlternatePermanently = 3] = "RemoveAlternatePermanently", - dd[dd.InsertDiscontinuity = 4] = "InsertDiscontinuity", - dd[dd.RetryRequest = 5] = "RetryRequest", - (dd = Im = Im || {})[dd.MoveAllAlternatesMatchingHost = 1] = "MoveAllAlternatesMatchingHost", - dd[dd.MoveAllAlternatesMatchingHDCP = 2] = "MoveAllAlternatesMatchingHDCP", - dd[dd.SwitchToSDR = 4] = "SwitchToSDR"; - class Jm extends Od { - constructor(e) { - super(e) - } - get currentConfig() { - var e; - return null === (e = this.getActive()) || void 0 === e ? void 0 : e.config - } - get extendMaxTTFB() { - var e; - return null === (e = this.getActive()) || void 0 === e ? void 0 : e.extendMaxTTFB - } - get config$() { - return this.selectActive(e=>null == e ? void 0 : e.config) - } - get userSeek$() { - return this.selectActive(e=>null == e ? void 0 : e.userSeek) - } - } - w(); - class Zm extends pd { - constructor() { - super({}, { - name: "hls-store", - producerFn: vc - }) - } - } - class eg { - constructor(e) { - this.store = e - } - getQuery() { - return new Jm(this.store) - } - setHlsEntity(e) { - const t = e.id; - Co(`hls.set.entity ${t}`), - sd(()=>{ - this.store.add(de(e)), - this.store.setActive(t) - } - ) - } - removeEntity(e) { - Co(`hls.remove ${e}`), - this.store.remove(e) - } - setStartTime(t) { - this.store.updateActive(e=>{ - e.config.startPosition = t - } - ) - } - setUserSeek(t) { - this.store.updateActive(e=>{ - e.userSeek = t - } - ) - } - setExtendMaxTTFB(t) { - this.store.updateActive(e=>{ - e.extendMaxTTFB = t - } - ) - } - } - let tg, ig; - function rg() { - return tg = tg || new eg(new Zm), - tg - } - function ng() { - return rg().getQuery().currentConfig - } - function sg(e, t, i, r) { - var n = t.mediaSeqNum - e.startSN; - if (n < 0 || n >= e.fragments.length) - return e; - const s = Object.assign(Object.assign({}, e), { - fragments: e.fragments.map(e=>Object.assign({}, e)) - }) - , a = s.fragments - , o = a[n]; - if (!Fp(t, a[n])) - return null == r || r.warn("Parsed and existing fragments don't match"), - e; - var {startDtsTs: d, startPts: e, endPts: t} = t; - o.startDtsTs = d, - o.startPts = e, - o.endPts = t, - o.start = i, - o.duration = b(o.endPts, o.startPts); - for (let e = n; 0 < e; e--) - ag(a, e, e - 1, r); - for (let e = n; e < a.length - 1; e++) - ag(a, e, e + 1, r); - s.totalduration = 0; - for (const l of a) - s.totalduration += l.duration; - return s.ptsKnown = !0, - og(s), - s - } - function ag(e, t, i, r) { - const n = e[t] - , s = e[i]; - s.startPts ? (t < i && n.start + n.duration > s.start || i < t && s.start + s.duration > n.start) && (null == r || r.warn(`overlapping segments found ${n.mediaSeqNum}->${s.mediaSeqNum}`)) : s.start = t < i ? n.start + n.duration : Math.max(n.start - s.duration, 0) - } - function og(e) { - if (e.programDateTimeMap) { - e.dateMediaTimePairs = []; - for (var [t,i] of Object.entries(e.programDateTimeMap)) { - t = Number(t), - i = e.fragments[i - e.startSN]; - i && (i = i.start, - e.dateMediaTimePairs.push([t, i])) - } - e.dateMediaTimePairs.sort((e,t)=>e[0] - t[0]) - } - } - function dg(t, i) { - if ("VOD" === t.type || "VOD" === i.type || t.iframesOnly !== i.iframesOnly) - return i; - var r = t.mediaOptionId === i.mediaOptionId; - let n = Object.assign(Object.assign({}, i), { - initSegments: {}, - fragments: [], - ptsKnown: !1 - }); - const s = Math.max(t.startSN, n.startSN) - n.startSN - , a = Math.min(t.endSN, n.endSN) - n.startSN - , o = n.startSN - t.startSN - , d = t.fragments - , l = i.fragments; - let u = 0; - for (let e = s; e <= a; ++e) - if (d[o + e] && l[e]) { - u = d[o + e].discoSeqNum - l[e].discoSeqNum; - break - } - const c = n.initSegments; - let h = null; - for (let e = 0; e < l.length; e++) { - const p = d[o + e] - , s = l[e] - , a = Object.assign({}, s) - , f = s.discoSeqNum + u; - i.initSegments[s.discoSeqNum] && (c[f] = Object.assign(Object.assign({}, i.initSegments[s.discoSeqNum]), { - discoSeqNum: f - })), - a.discoSeqNum = f, - r && a.mediaSeqNum === (null == p ? void 0 : p.mediaSeqNum) && null != p.startPts && (a.start = p.start, - a.duration = p.duration, - a.startDtsTs = p.startDtsTs, - a.endDtsTs = p.endDtsTs, - a.startPts = p.startPts, - a.endPts = p.endPts, - h = a), - n.fragments.push(a) - } - if (h) - n = sg(n, h, h.start); - else if (0 <= o && o < d.length) { - const t = d[o].start - , i = n.fragments; - for (let e = 0; e < l.length; e++) - i[e].start += t - } - return n.ptsKnown = n.ptsKnown || r && !0 === t.ptsKnown && t.endSN >= i.startSN, - og(n), - n - } - function lg(e, t, i) { - let r = t.targetduration; - return ne(i.liveSyncDuration) ? r = i.liveSyncDuration : ne(i.liveSyncDurationCount) && (r = i.liveSyncDurationCount * t.targetduration), - e + Math.max(0, t.totalduration - r) - } - function ug(e, t, i, r, n) { - if (!t.ptsKnown) - return 0; - var s = t.targetduration - , a = t.fragments[0].start - , r = n.canContinuePlaybackWithoutGap(t, i, { - avgPlaylistLoadTimeMs: 0, - avgPlaylistParseTimeMs: 0 - }, r); - let o = Math.max(0, e - s); - return e < a && !r && (o = a), - o - } - function cg(e) { - return 1e3 * (e.averagetargetduration || e.targetduration) - } - function hg(e, t) { - var i = cg(e) - , t = performance.now() - t; - return e.liveOrEvent && i <= t - } - function pg(e, t) { - return function(e) { - const t = [] - , i = e.fragments; - for (const e of i) { - const {discoSeqNum: i, start: r} = e; - t.push({ - timelineOffset: r, - mediaFragment: e - }) - } - return t - }(e).find(e=>t(e.mediaFragment)) - } - function fg(s, e, a, t, o) { - var i; - const d = !t.liveOrEvent || t.ptsKnown; - let r = null !== (i = pg(t, t=>{ - var e = t.mediaSeqNum >= a - , i = 0 < t.duration - , r = t.start + t.duration - , n = !d || s < r || s - r < 1 && t.isLastFragment - , r = o.every(e=>!Fp(e.frag, t)); - return e && i && n && r - } - )) && void 0 !== i ? i : null - , n = NaN; - null != r && ne(e) && r.mediaFragment.discoSeqNum !== e && (n = r.mediaFragment.discoSeqNum, - r = null); - e = o.some(e=>0 < e.frag.framesWithoutIDR); - return r && e && o[o.length - 1].frag.mediaOptionId !== t.mediaOptionId && (r = null !== (t = pg(t, e=>e.mediaSeqNum === r.mediaFragment.mediaSeqNum - 1)) && void 0 !== t ? t : r), - { - foundFrag: r, - nextDisco: n - } - } - function mg(e) { - const t = e.fragments; - return t.map(e=>e.duration).reduce((e,t)=>e + t, null !== (e = t[0].start) && void 0 !== e ? e : 0) - } - class gg extends Od { - constructor(e, t) { - super(e), - this.mediaOption = t - } - get itemId() { - return this.mediaOption.itemId - } - get mediaOptionId() { - return this.mediaOption.mediaOptionId - } - get initSegmentEntities() { - var e; - return null === (e = this.mediaOptionDetailsEntity) || void 0 === e ? void 0 : e.initSegmentCacheEntities - } - get mediaLibraryEntity() { - return this.getEntity(this.itemId) - } - get mediaOptionDetailsEntityRecord() { - var e; - return null === (e = this.mediaLibraryEntity) || void 0 === e ? void 0 : e.mediaOptionDetailsEntityRecord - } - get mediaOptionDetailsEntity() { - return this.mediaOptionDetailsEntityRecord ? this.mediaOptionDetailsEntityRecord[this.mediaOptionId] : null - } - get mediaOptionDetails() { - var e; - return null === (e = this.mediaOptionDetailsEntity) || void 0 === e ? void 0 : e.mediaOptionDetails - } - get playlistDuration() { - var e; - return null === (e = this.mediaOptionDetailsEntity) || void 0 === e ? void 0 : e.playlistDuration - } - get mediaOptionDetailsEntity$() { - const {itemId: e, mediaOptionId: t} = this; - return this.selectEntity(e, e=>{ - if (null != e && e.mediaOptionDetailsEntityRecord) - return null == e ? void 0 : e.mediaOptionDetailsEntityRecord[t] - } - ) - } - get mediaOptionDetails$() { - return this.selectEntity(this.itemId, e=>{ - return null === (e = null == e ? void 0 : e.mediaOptionDetailsEntityRecord[this.mediaOptionId]) || void 0 === e ? void 0 : e.mediaOptionDetails - } - ).pipe(Up()) - } - get playlistDuration$() { - return this.mediaOptionDetailsEntity$.pipe(ur(e=>null == e ? void 0 : e.playlistDuration), Up(), Es()) - } - get live$() { - return this.mediaOptionDetails$.pipe(ur(e=>null == e ? void 0 : e.liveOrEvent), Es()) - } - } - class yg extends pd { - constructor() { - super({}, { - name: "media-library-store", - idKey: "itemId", - producerFn: vc - }) - } - } - class vg { - constructor(e) { - this.store = e - } - getQuery() { - return new Od(this.store) - } - getQueryForOption(e) { - return new gg(this.store,e) - } - createMediaLibraryEntity(e) { - var t = { - itemId: e, - mediaOptionDetailsEntityRecord: {} - }; - Co(`library.entity.create: ${e}`), - this.store.add(t) - } - setDetailsLoading(e) { - const {itemId: t, mediaOptionId: i} = e; - Co(`library.details.loading: ${i}`), - this.store.update(t, ({mediaOptionDetailsEntityRecord: e})=>{ - e[i] || (e[i] = { - initSegmentCacheEntities: {}, - unchangedCount: 0 - }), - e[i].detailsLoading = !0 - } - ) - } - archiveMediaOptionDetails(i, r, n) { - const {itemId: e, mediaOptionId: s} = i - , a = performance.now() - , o = mg(i); - Co(`library.details.loaded: ${s}`), - this.store.update(e, e=>{ - const t = e.mediaOptionDetailsEntityRecord[s]; - t.detailsLoading = !1, - t.mediaOptionDetails = i, - t.lastUpdateMillis = a, - n ? t.unchangedCount = 0 : ++t.unchangedCount, - t.playlistDuration = o, - t.stats = r, - e.liveOrEvent = i.liveOrEvent - } - ) - } - setInitSegmentLoading(e) { - const {itemId: t, mediaOptionId: i, discoSeqNum: r} = e; - Co(`library.initsegs.loading: ${i}/${r}`), - this.store.update(t, e=>{ - e.mediaOptionDetailsEntityRecord[i].initSegLoading = r - } - ) - } - archiveInitSegmentEntity(i, r) { - const {itemId: e, mediaOptionId: n, discoSeqNum: s} = i; - Co(`library.initseg.loaded: ${n}/${s}`), - this.store.update(e, ({mediaOptionDetailsEntityRecord: e})=>{ - const t = e[n]; - t.initSegmentCacheEntities[s] = [i, r], - t.initSegLoading = null - } - ) - } - updatePTSDTS(e, r, n, s) { - this.store.update(e, ({mediaOptionDetailsEntityRecord: e})=>{ - const t = e[r]; - var i; - null != t && t.mediaOptionDetails && ({variantDTS: i, timelineOffset: e} = n, - e = S(s.startDtsTs) - S(i) + e, - e = sg(t.mediaOptionDetails, s, e), - t.mediaOptionDetails = e, - t.playlistDuration = mg(e)) - } - ) - } - remove(e) { - this.store.remove(e) - } - clear() { - this.store.remove() - } - } - function Sg() { - return ig = ig || new vg(new yg), - ig - } - const bg = e=>Sg().getQueryForOption(e) - , Tg = (d,e,t=!1)=>{ - if (!kl(e)) - return Bi(null); - const i = e["itemId"] - , r = d["mediaLibraryService"] - , n = r.getQueryForOption(e); - n.hasEntity(i) || r.createMediaLibraryEntity(i); - var s = n.mediaOptionDetailsEntity - , a = n.mediaOptionDetails; - return null == a || t || "VOD" !== a.type && (!a.liveOrEvent || hg(a, s.lastUpdateMillis)) ? (r.setDetailsLoading(e), - function(l) { - var e; - const {logger: t, config: u, rootPlaylistQuery: c, rootPlaylistService: h, statsService: i, mediaLibraryService: p, mediaSink: r} = d - , f = r.mediaQuery - , n = u.playlistLoadPolicy - , s = u.keySystemPreference - , a = c.masterVariableList - , o = null === (e = null === (e = rg()) || void 0 === e ? void 0 : e.getQuery()) || void 0 === e ? void 0 : e.extendMaxTTFB; - return Cm(l, c.itemStartOffset, u, n, t, s, i, a, o).pipe(Hi(Zi), ur(t=>{ - const i = p.getQueryForOption(l) - , r = i.mediaOptionDetails; - let n = t["mediaOptionDetails"]; - var e = t["stats"]; - let s = !0; - if (n.liveOrEvent) { - const d = n["mediaOptionType"]; - t = n, - s = null == r || t.endSN !== r.endSN || t.liveOrEvent !== r.liveOrEvent; - let e = n; - r && (e = dg(r, n)); - const i = c.lastLoadedMediaOptionByType(d) - , u = i ? null === (t = p.getQueryForOption(i)) || void 0 === t ? void 0 : t.mediaOptionDetails : null; - !e.ptsKnown && u && u.mediaOptionId !== (null == r ? void 0 : r.mediaOptionId) && (e = dg(u, n)), - n = e - } - n && (p.archiveMediaOptionDetails(n, e, s), - h.setLastLoadedMediaOptionByType(c.itemId, l.mediaOptionType, l)); - const a = !s && i.mediaOptionDetailsEntity.unchangedCount >= u.liveMaxUnchangedPlaylistRefresh - , o = function(e, t, i, r) { - t = ug(r.currentTime, e, t, i, r), - i = e.fragments[e.fragments.length - 1], - r = i.start + i.duration; - return { - expired: null != i && e.liveOrEvent && e.ptsKnown && r < t, - windowEnd: r, - minPosition: t - } - }(n, e.tload, u.maxBufferHole, f); - if (a || o.expired) { - e = a ? $.LivePlaylistUpdateError : { - text: `Live window too far in the past end:${o.windowEnd.toFixed(3)} minPosition:${o.minPosition}`, - code: 0 - }; - throw new nu(!1,e.text,e.code,e,!1,l.mediaOptionType,l.mediaOptionId,l.url) - } - return n - } - ), Ql.tag("getMediaOptionDetailsCommon.emit.loaded"), Ym(l.itemId, l.mediaOptionType, xc(l, n), u.maxNumAddLevelToPenaltyBox, !1, c, h, i)).pipe(Cs(1)) - }(e)) : Bi(a).pipe(Ql.tag("retrieveMediaOptionDetails.emit.cached")).pipe(Cs(1)) - } - ; - const Eg = (t,i)=>{ - if (!i) - return Bi(null); - const {mediaLibraryService: r, mediaParser: n} = t - , e = r.getQueryForOption(i) - , {mediaOption: s, mediaOptionDetailsEntityRecord: a, mediaOptionDetails: o} = e - , d = s["mediaOptionId"]; - if (null == a || !a[d]) - throw new Error("retrieveInitSegmentCacheEntity no details entity"); - if (!o) - throw new Error("retrieveInitSegmentCacheEntity no details"); - var l = a[d]["initSegmentCacheEntities"] - , u = o["initSegments"] - , c = i["discoSeqNum"]; - if (l[c]) { - const [t,r] = l[c]; - let e = t; - return r && (e = n.willBeTrackSwitch(i) ? t : r), - Bi(e) - } - const h = u[c]; - return h ? (r.setInitSegmentLoading(h), - wg(t, h, !1, !1).pipe(Hi(Zi), Ra(e=>Ig(e, h, t)), Ql.tag("retrieveInitSegmentCacheEntity.emit"))) : Bi(null) - } - ; - function Ig(e, n, t) { - const {logger: s, mediaSink: i, rootPlaylistService: r, rootPlaylistQuery: a, mediaParser: o, mediaLibraryService: d, gaplessInstance: l} = t - , u = i["mediaQuery"] - , c = d.getQueryForOption(n) - , {mediaOption: h, mediaOptionDetails: p} = c - , {itemId: f, mediaOptionId: m} = h - , {keyTagInfo: g, discoSeqNum: y, mediaOptionType: v} = n - , S = u.seeking - , b = p.liveOrEvent - , T = v === ul.Variant && p.ptsKnown; - let E, I; - n.isInitSegment ? I = new Uint8Array(e) : E = new Uint8Array(e); - var e = { - segment: E, - initSegment: I, - frag: n, - ptsKnown: T, - seeking: S, - live: b, - totalDuration: p.totalduration + /** + * The `produce` function takes a value and a "recipe function" (whose + * return value often depends on the base state). The recipe function is + * free to mutate its first argument however it wants. All mutations are + * only ever applied to a __copy__ of the base state. + * + * Pass only a function to create a "curried producer" which relieves you + * from passing the recipe function every time. + * + * Only plain objects and arrays are made mutable. All other objects are + * considered uncopyable. + * + * Note: This function is __bound__ to its `Immer` instance. + * + * @param {any} base - the initial state + * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified + * @param {Function} patchListener - optional function that will be called with all the patches produced here + * @returns {any} a new state, or the initial state if nothing was modified + */ + + + var _proto = Immer.prototype; + + _proto.produce = function produce(base, recipe, patchListener) { + // curried invocation + if (typeof base === "function" && typeof recipe !== "function") { + var defaultBase = recipe; + recipe = base; + var self = this; + return function curriedProduce(base) { + var _this = this; + + if (base === void 0) { + base = defaultBase; + } + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return self.produce(base, function (draft) { + var _recipe; + + return (_recipe = recipe).call.apply(_recipe, [_this, draft].concat(args)); + }); // prettier-ignore }; - return o.parseInitSegment(e, null !== (e = null === navigator || void 0 === navigator ? void 0 : navigator.vendor) && void 0 !== e ? e : "").pipe(ur(e=>{ - var {track: t, moovData: i, mimeType: r} = e - , e = t["initSegment"]; - l.inGaplessMode && Se.isVideoCodec(t.codec) && (s.warn(`Video codec discovered in gapless mode codec:${t.codec}`), - l.dequeueSource("InvalidFormat")); - r = { - itemId: f, - mediaOptionId: m, - discoSeqNum: y, - initParsedData: i, - data: e, - mimeType: r, - keyTagInfo: g, - fragment: n - }; - return d.archiveInitSegmentEntity(r), - r + } + + if (typeof recipe !== "function") die(6); + if (patchListener !== undefined && typeof patchListener !== "function") die(7); + var result; // Only plain objects, arrays, and "immerable classes" are drafted. + + if (isDraftable(base)) { + var scope = enterScope(this); + var proxy = createProxy(this, base, undefined); + var hasError = true; + + try { + result = recipe(proxy); + hasError = false; + } finally { + // finally instead of catch + rethrow better preserves original stack + if (hasError) revokeScope(scope);else leaveScope(scope); } - ), Wm(r, a, v, m)) - } - function wg(n, s, i, r) { - var e; - const {rootPlaylistQuery: t, rootPlaylistService: a, config: o, rtcService: d, statsService: l} = n - , {itemId: u, mediaOptionType: c} = s - , h = o.fragLoadPolicy - , p = ne(s.mediaSeqNum); - let f; - p && (f = { - getData: !1, - cb: (e,t,i,r)=>(a.updateInflightFrag(u, s.mediaOptionType, s, "loading", i), - !1) - }); - let m = !1; - return r && null === d.serverInfoInstance && (m = !0), - Jr([Og(n, s.keyTagInfo, { - itemId: s.itemId, - mediaOptionId: s.mediaOptionId - }), Jf(s, o, h, f, m, null === (e = null === (e = rg()) || void 0 === e ? void 0 : e.getQuery()) || void 0 === e ? void 0 : e.extendMaxTTFB).pipe(Ja(([,,e,t])=>{ - i && l.setBandwidthSample(Object.assign(Object.assign({}, e), { - mediaOptionType: s.mediaOptionType - })), - r && m && (d.serverInfoInstance = t), - p && a.updateInflightFrag(u, s.mediaOptionType, s, "loaded", e) - } - ), Ym(u, c, xc(s, h), o.maxNumAddLevelToPenaltyBox, !1, t, a, l))]).pipe(Cs(1), Ja(([,e])=>{ - var t; - r && ([t,,e] = e, - d.handleFragLoaded(t, e)) - } - ), Ra(([e,t])=>{ - const [i,r] = t; - return i.keyTagInfo.key = e.key, - Dm(i, r, o, n.logger, n.rpcClients.crypto) - } - ), Ql.tag("getMediaFragmentCommon.emit")) - } - const Ag = (i,e,t)=>{ - const {rootPlaylistService: r, rootPlaylistQuery: n} = i - , {timelineOffset: s, mediaFragment: a} = t.foundFrag - , {itemId: o, discoSeqNum: d} = a; - return r.updateInflightFrag(o, a.mediaOptionType, a, "loading", null), - Jr([Og(i, a.keyTagInfo, { - itemId: a.itemId, - mediaOptionId: a.mediaOptionId - }), Eg(i, a).pipe(Ra(t=>wg(i, a, !0, !0).pipe(Ra(e=>{ - return function(e, t, i, y, v, S) { - const r = new Uint8Array(e) - , {rootPlaylistService: n, mediaSink: s, mediaParser: a, rootPlaylistQuery: o, mediaLibraryService: b} = S - , d = s["mediaQuery"] - , l = b.getQueryForOption(y) - , {mediaOption: u, mediaOptionDetails: c} = l - , {itemId: T, mediaOptionId: E} = u - , {discoSeqNum: I, mediaSeqNum: w, mediaOptionType: h, isLastFragment: A} = y - , p = d.seeking - , f = c.liveOrEvent - , m = h === ul.Variant && c.ptsKnown - , O = { - segment: r, - frag: y, - seeking: p, - live: f, - ptsKnown: m, - totalDuration: c.totalduration, - defaultInitPTS: t, - iframeMediaStart: Np(y) ? y.iframeMediaStart : void 0, - iframeDuration: Np(y) ? y.iframeMediaDuration : void 0 - }; - let g; - if (null != i && (null === (t = y.keyTagInfo) || void 0 === t ? void 0 : t.uri) === (null === (t = i.keyTagInfo) || void 0 === t ? void 0 : t.uri)) - g = Bi(i); - else if (null != i) { - const e = Object.assign(Object.assign({}, i.fragment), { - keyTagInfo: y.keyTagInfo - }); - g = Ig(i.data, e, S) - } else - g = Ig(e, y, S); - return g.pipe(Ra(m=>{ - const g = performance.now(); - if (null != m) { - const g = m["data"] - , e = new Uint8Array(g); - O.initSegment = e - } - return a.parseSegment(O, "").pipe(ur(e=>{ - var t = performance.now() - , {startPTS: i, startDTS: r, endPTS: n, endDTS: s, firstKeyframePts: a, framesWithoutIDR: o, dropped: d, data1: l, data2: u, captionData: c, id3Samples: h, parsedInitSegment: e} = e - , t = { - durationSec: n.baseTime / n.timescale - i.baseTime / i.timescale, - parseTimeMs: t - g - }; - S.statsService.setFragSample(t); - let p = Object.assign({}, m); - if (e) { - const {track: g, moovData: f, mimeType: v} = e - , S = g["initSegment"]; - p = { - itemId: T, - mediaOptionId: E, - discoSeqNum: I, - initParsedData: f, - data: S, - mimeType: v, - keyTagInfo: y.keyTagInfo, - fragment: y - }, - b.archiveInitSegmentEntity(m, p) - } - e = y.keyTagInfo; - return [p, { - itemId: T, - mediaOptionId: E, - mediaSeqNum: w, - discoSeqNum: I, - startDtsTs: r, - endDtsTs: s, - timelineOffset: v, - firstKeyframePts: a, - framesWithoutIDR: o, - dropped: d, - data1: l, - data2: u, - startPts: i, - endPts: n, - keyTagInfo: e, - isLastFragment: A, - iframe: null !== (e = y.iframe) && void 0 !== e && e, - duration: y.duration, - iframeMediaDuration: Np(y) ? y.iframeMediaDuration : void 0, - captionData: c, - id3Samples: h - }] - } - )) - } - ), Wm(n, o, h, E)) - }(e, null === (e = n.getInitPTS(d)) || void 0 === e ? void 0 : e.offsetTimestamp, t, a, s, i) - } - ), Ja(e=>{} - ), Ql.tag(`retrieveMediaFragmentCacheEntity.${e}.emit`)))).pipe(Cs(1))]).pipe(Ra(([,e])=>Bi(e))) + + if (typeof Promise !== "undefined" && result instanceof Promise) { + return result.then(function (result) { + usePatchesInScope(scope, patchListener); + return processResult(result, scope); + }, function (error) { + revokeScope(scope); + throw error; + }); + } + + usePatchesInScope(scope, patchListener); + return processResult(result, scope); + } else if (!base || typeof base !== "object") { + result = recipe(base); + if (result === NOTHING) return undefined; + if (result === undefined) result = base; + if (this.autoFreeze_) freeze(result, true); + return result; + } else die(21, base); + }; + + _proto.produceWithPatches = function produceWithPatches(arg1, arg2, arg3) { + var _this2 = this; + + if (typeof arg1 === "function") { + return function (state) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + return _this2.produceWithPatches(state, function (draft) { + return arg1.apply(void 0, [draft].concat(args)); + }); + }; + } + + var patches, inversePatches; + var nextState = this.produce(arg1, arg2, function (p, ip) { + patches = p; + inversePatches = ip; + }); + return [nextState, patches, inversePatches]; + }; + + _proto.createDraft = function createDraft(base) { + if (!isDraftable(base)) die(8); + if (isDraft(base)) base = current(base); + var scope = enterScope(this); + var proxy = createProxy(this, base, undefined); + proxy[DRAFT_STATE].isManual_ = true; + leaveScope(scope); + return proxy; + }; + + _proto.finishDraft = function finishDraft(draft, patchListener) { + var state = draft && draft[DRAFT_STATE]; + + { + if (!state || !state.isManual_) die(9); + if (state.finalized_) die(10); + } + + var scope = state.scope_; + usePatchesInScope(scope, patchListener); + return processResult(undefined, scope); } + /** + * Pass true to automatically freeze all copies created by Immer. + * + * By default, auto-freezing is disabled in production. + */ ; - function Og(e, t, i) { - const {keySystemAdapter: r, rootPlaylistQuery: n, rootPlaylistService: s, config: a} = e; - return r.getKeyFromDecryptData(t, i).pipe((o = t.uri, - d = xc({ - url: t.uri - }, a.keyLoadPolicy), - l = n, - u = s, - c = r.ksQuery, - e=>e.pipe(od(()=>{ - zm(o, !1, l, u, c) - } - ), ya(e=>e.pipe(Kr((e,t)=>{ - if (e instanceof lu || e instanceof uu) - return Xm(e, t, Rc(e, d), u, l, c); - throw e - } - )))))); - var o, d, l, u, c + + _proto.setAutoFreeze = function setAutoFreeze(value) { + this.autoFreeze_ = value; } - class kg { - constructor(e, t, i) { - this.hls = e, - this.destroy$ = new zt, - this.iframeSwitchStart = 0, - this.logger = t.child({ - name: "hls-player-events" - }), - this.rtc = i, - this.subscribeAndEmit() - } - destroy() { - this.destroy$.next() - } - subscribeAndEmit() { - var e = this.loaderQueryListener(new fu(bc)) - , t = this.hls.publicQueries$.pipe(Ra(([e,t])=>nn(this.rootPlaylistQueryListener(e, t), this.mediaElementQueryListener(t, e)))); - nn(e, t, this.activeItemListener(this.hls.itemQueue)).pipe(Un(e=>{ - var t = e.message; - return this.logger.error(`Got error in HlsPlayerEvents ${t}`, e), - Ti - } - ), $a(this.destroy$), $s(()=>{} - )).subscribe() - } - activeItemListener(e) { - return e.activeItemById$.pipe(Up(), Ra(e=>{ - e = e.url; - return this.hls.trigger(x.MANIFEST_LOADING, { - url: e - }), - Ti - } - )) - } - rootPlaylistQueryListener(t, e) { - var i = t.enabledMediaOptionByType$(ul.Variant).pipe(an(e=>!!e), Ra(e=>{ - var t; - return this.hls.trigger(x.LEVEL_SWITCHING, e), - null === (t = this.rtc) || void 0 === t || t.handleLevelSwitching(e.url), - Ti - } - )) - , r = t.enabledMediaOptionByType$(ul.Variant).pipe(Ra(i=>bg(i).mediaOptionDetailsEntity$.pipe(an(e=>!0 === (null == e ? void 0 : e.detailsLoading)), Ja(e=>{ - var t = { - url: oe(null == i ? void 0 : i.url), - level: i.mediaOptionId, - type: Cl[i.mediaOptionType] - }; - return this.hls.trigger(x.LEVEL_LOADING, t), - Ti - } - )))) - , n = t.enabledMediaOptionByType$(ul.Variant).pipe(Ra(e=>{ - const t = bg(e); - let i = 0; - return t.mediaOptionDetailsEntity$.pipe(Up(), an(e=>{ - var t = null !== e.stats && !1 === e.detailsLoading && e.lastUpdateMillis > i; - return i = null !== (e = e.lastUpdateMillis) && void 0 !== e ? e : 0, - t - } - )) - } - ), Ra(e=>{ - var t = e.mediaOptionDetails - , i = e.stats - , r = { - mediaOptionId: t.mediaOptionId, - details: t, - playlistType: t.type, - stats: i - }; - if (null === (i = this.rtc) || void 0 === i || i.handleLevelLoaded(t, r.stats), - this.hls.trigger(x.LEVEL_LOADED, r), - 0 === e.unchangedCount) { - const e = { - level: 0, - details: t - }; - this.hls.trigger(x.LEVEL_UPDATED, e) - } - if (null != t && t.daterangeTags) { - const e = { - daterangeTags: t.daterangeTags - }; - this.hls.trigger(x.DATERANGE_UPDATED, e) - } - return Ti - } - )) - , s = t.enableMediaOptionSwitchedForType$(ul.AltAudio).pipe(Ra(e=>{ - e = t.alternateMediaOptionById(ul.AltAudio, e.mediaOptionId); - return e && this.triggerAudioSwitch(e), - Ti - } - )) - , a = t.rootPlaylistEntity$.pipe(an(e=>null !== e.enabledMediaOptionKeys[ul.AltAudio].mediaOptionId), Cs(1), Ra(e=>{ - const t = e.enabledMediaOptionKeys[ul.AltAudio].mediaOptionId; - return t && (e = e.mediaOptionListTuple[ul.AltAudio].mediaOptions.find(e=>e.mediaOptionId === t), - this.triggerAudioSwitch(e)), - Ti - } - )); - return nn(i, s, $l(e.textTracksCreated$, e=>e).pipe(Ra(()=>t.enabledMediaOptionByType$(ul.Subtitle).pipe(Ra(e=>{ - e = t.alternateMediaOptionById(ul.Subtitle, e.mediaOptionId); - return e ? this.hls.trigger(x.SUBTITLE_TRACK_SWITCH, { - track: Object.assign({}, e), - hidden: !1 - }) : this.hls.trigger(x.SUBTITLE_TRACK_SWITCH, { - track: void 0, - hidden: !1 - }), - Ti - } - )))), t.sessionData$.pipe(an(e=>null != e.complete), Cs(1), Ja(e=>{} - ), ur(e=>{ - this.hls.trigger(x.SESSION_DATA_COMPLETE, e) - } - )), t.getPreferredMediaOptionsByType$(ul.Variant).pipe(Oa(1), ur(e=>{ - const t = e; - null === (e = this.rtc) || void 0 === e || e.handleLevelsChanged(t), - t.forEach(e=>{} - ), - this.hls.trigger(x.LEVELS_CHANGED, { - requiresReset: !1, - levels: t - }) - } - )), t.getPreferredMediaOptionsByType$(ul.AltAudio).pipe(ur(e=>{ - this.hls.trigger(x.AUDIO_TRACKS_UPDATED, { - audioTracks: e - }) - } - )), $l(e.textTracksCreated$, e=>e).pipe(Ra(()=>t.getPreferredMediaOptionsByType$(ul.Subtitle).pipe(Cs(1), ur(e=>{ - this.hls.trigger(x.SUBTITLE_TRACKS_UPDATED, { - subtitleTracks: e - }), - this.hls.trigger(x.SUBTITLE_TRACKS_CREATED) - } - )))), n, r, a) - } - mediaElementQueryListener(s, e) { - return nn(s.seekTo$.pipe(ur(e=>{ - var t; - e && ne(e.pos) ? (null === (t = this.rtc) || void 0 === t || t.handleSeek("SEEKING"), - this.hls.trigger(x.SEEKING, { - seekToPos: e.pos - })) : null === e && (null === (e = this.rtc) || void 0 === e || e.handleSeek("SEEKED"), - this.hls.trigger(x.SEEKED)) - } - )), s.desiredRate$.pipe(xa(0), ca(), ur(e=>{ - var t = e[0] - , i = e[1]; - jp(i) ? 0 == this.iframeSwitchStart && (this.iframeSwitchStart = performance.now()) : this.iframeSwitchStart = 0, - this.hls.trigger(x.DESIRED_RATE_CHANGED, { - oldRate: t, - newRate: i - }), - null === (e = this.rtc) || void 0 === e || e.handleDesiredRateChanged(t, i) - } - )), s.sourceBufferEntityByType$(cl.AltAudio).pipe(an(e=>!!e), Es((e,t)=>e.totalBytes === t.totalBytes), ur(e=>{ - this.hls.trigger(x.BUFFER_APPENDED) - } - )), s.sourceBufferEntityByType$(cl.Variant).pipe(an(e=>!!e), Es((e,t)=>e.totalBytes === t.totalBytes), ur(e=>{ - var t; - null === (t = this.rtc) || void 0 === t || t.handleVariantBufferAppended(e.timestampOffset, e.totalBytes), - this.hls.trigger(x.BUFFER_APPENDED) - } - )), s.stallInfo$.pipe(Up(), So(s.combinedBuffer$), ur(([e])=>{ - var t; - null === (t = this.rtc) || void 0 === t || t.handleStalled(e, s.getCombinedBufferInfo(e.currentTime, 0).len), - this.hls.trigger(x.STALLED, e) - } - )), Cr([Bi(e), Zd([s.timeupdate$, s.bufferedSegmentsByType$(cl.Variant)]).pipe(so(1e3), ur(([t,e])=>null == e ? void 0 : e.find(e=>e.startPTS <= t && e.endPTS > t)), an(e=>!!e), xa(null), ca())]).pipe(Ra(([e,[t,i]])=>{ - var r = null == i ? void 0 : i.frag - , t = null == t ? void 0 : t.frag; - if (r && !Fp(t, r) && (this.hls.trigger(x.FRAG_CHANGED, i), - this.hls.inGaplessMode && this.checkAndTriggerReadyForNext(s, i), - !t || r.mediaOptionId !== t.mediaOptionId)) { - const s = e.mediaOptionListQueries[ul.Variant].mediaOptionFromId(r.mediaOptionId); - if (!s) - return this.logger.warn("variantInfo is undefined in fragChangeMonitor"), - Ti; - const n = t ? t.mediaOptionId : "" - , i = r.mediaOptionId; - s.iframes && (performance.now(), - this.iframeSwitchStart), - null === (r = this.rtc) || void 0 === r || r.handleLevelSwitched({ - url: s.url, - mediaOptionId: s.mediaOptionId, - oldVariant: "" !== n ? n : void 0, - newVariant: i - }), - this.hls.trigger(x.LEVEL_SWITCHED, s) - } - return Ti - } - )), s.isBufferedToEnd$(this.hls.config.maxBufferHole, !1).pipe(an(e=>!0 === e), Hi(Zi), ur(e=>{ - if (e && !this.hls.itemQueue.isPreloading() && this.hls.inGaplessMode) { - const i = s.getCombinedBufferInfo(s.currentTime, 0); - var t = 0; - i && (t = i.end, - e = s.mediaElementDuration, - 0 < t && e - s.currentTime < 10 && this.hls.trigger(x.READY_FOR_NEXT_ITEM, { - duration: t - })) - } - } - ))) - } - checkAndTriggerReadyForNext(e, t) { - var i, r; - t && t.frag && (i = e.currentTime, - (r = e.getCombinedBufferInfo(i, 0)) && (i = r.end, - r = e.mediaElementDuration, - e = e.bufferMonitorInfo, - e = Math.max(e.almostDryWaterLevelSeconds, e.lowWaterLevelSeconds / 2), - (r - t.endPTS <= e || t.frag.isLastFragment) && this.hls.inGaplessMode && !this.hls.isPreloading && this.hls.trigger(x.READY_FOR_NEXT_ITEM, { - duration: i - }))) - } - loaderQueryListener(e) { - return nn(e.unresolvedUriLoading$.pipe(ur(e=>e.map(e=>{ - e = { - uri: e.uri, - responseType: e.responseType, - userAgent: e.userAgent - }; - this.hls.trigger(x.UNRESOLVED_URI_LOADING, e) - } - )))) - } - triggerAudioSwitch(e) { - e && this.hls.trigger(x.AUDIO_TRACK_SWITCHED, { - id: e.id - }) - } - triggerManifestLoaded(e) { - e = { - levels: e.rootMediaOptionsTuple[ul.Variant], - audioTracks: e.rootMediaOptionsTuple[ul.AltAudio], - subtitleTracks: e.rootMediaOptionsTuple[ul.Subtitle], - url: e.baseUrl, - audioMediaSelectionGroup: e.audioMediaSelectionGroup, - subtitleMediaSelectionGroup: e.subtitleMediaSelectionGroup, - stats: e.stats, - isMediaPlaylist: e.isMediaPlaylist - }; - this.hls.trigger(x.MANIFEST_LOADED, e) - } - triggerManifestParsed(e) { - var t = { - levels: e.mediaOptionListQueries[ul.Variant].filteredMediaOptionList, - firstLevel: 0, - audio: !1, - video: !0, - altAudio: !1, - audioTracks: e.mediaOptionListQueries[ul.AltAudio].filteredMediaOptionList, - audioMediaSelectionGroup: e.audioMediaSelectionGroup, - subtitleMediaSelectionGroup: e.subtitleMediaSelectionGroup, - stats: e.loadStats - }; - null === (e = this.rtc) || void 0 === e || e.handleManifestParsed(t), - this.hls.trigger(x.MANIFEST_PARSED, t) - } - urlRedactedManifestLoaded(e) { - const t = Object.assign({}, e); - return t.url = oe(t.url), - t.levels = le(t.levels), - t.audioTracks = ue(t.audioTracks), - t.subtitleTracks = ue(t.subtitleTracks), - t - } - urlRedactedManifestParsed(e) { - const t = Object.assign({}, e); - return t.levels = le(t.levels), - t.audioTracks = ue(t.audioTracks), - t - } - } - (w = wm = wm || {}).LowBandwidth = "LowBandwidth", - w.HighBandwidth = "HighBandwidth", - w.PreferredListChanged = "PreferredListChanged", - w.IframeModeChange = "IframeModeChange", - w.None = ""; - const Cg = { - minValidBitrate: 2e6, - maxValidBitrate: 5e6, - maxPreferredBitrate: 3e6, - minValidHeight: 480, - maxValidHeight: 720 + /** + * Pass true to use the ES2015 `Proxy` class when creating drafts, which is + * always faster than using ES5 proxies. + * + * By default, feature detection is used, so calling this is rarely necessary. + */ + ; + + _proto.setUseProxies = function setUseProxies(value) { + if (value && !hasProxies) { + die(20); + } + + this.useProxies_ = value; }; - function Dg(e, a, o, d, l, u) { - return e.reduce((e,t)=>{ - if (t.iframes) - return e; - let i = e; - const r = (n = t.score, - s = a && o && d && l && !Mg(t, a, o, d, l, u) ? ll.INVALID : ll.VALID, - new Hp(s,n)); - var n, s; - return (!e || r.isGreaterThan(e.bestRank) || r.isEqualTo(e.bestRank) && t.bandwidth < e.selected.bandwidth) && (i = { - selected: t, - bestRank: r - }), - i + + _proto.applyPatches = function applyPatches(base, patches) { + // If a patch replaces the entire state, take that replacement as base + // before applying patches + var i; + + for (i = patches.length - 1; i >= 0; i--) { + var patch = patches[i]; + + if (patch.path.length === 0 && patch.op === "replace") { + base = patch.value; + break; } - , null).selected - } - function Mg(e, t, i, r, n, s) { - var {targetDuration: a, targetStartupMs: o} = i - , d = r["avgPlaylistLoadTimeMs"] - , l = n["avgParseTimeMs"] - , {avgBufferCreateMs: i, avgInitFragAppendMs: r, avgDataFragAppendMs: n} = s - , {avgBandwidth: s, avgLatencyMs: t} = t; - return e.bandwidth <= s && (e.avgBandwidth || e.bandwidth) * a / s * 1e3 + d + i + +(t + l + (r + n)) <= o - } - const Pg = { - name: "abr" + } + + var applyPatchesImpl = getPlugin("Patches").applyPatches_; + + if (isDraft(base)) { + // N.B: never hits if some patch a replacement, patches are never drafts + return applyPatchesImpl(base, patches); + } // Otherwise, produce a copy of the base state. + + + return this.produce(base, function (draft) { + return applyPatchesImpl(draft, patches.slice(i + 1)); + }); }; - function xg(e, t) { - return ne(e) ? Math.min(e, t) : t + + return Immer; + }(); + function createProxy(immer, value, parent) { + // precondition: createProxy should be guarded by isDraftable, so we know we can safely draft + var draft = isMap(value) ? getPlugin("MapSet").proxyMap_(value, parent) : isSet(value) ? getPlugin("MapSet").proxySet_(value, parent) : immer.useProxies_ ? createProxyProxy(value, parent) : getPlugin("ES5").createES5Proxy_(value, parent); + var scope = parent ? parent.scope_ : getCurrentScope(); + scope.drafts_.push(draft); + return draft; + } + + function current(value) { + if (!isDraft(value)) die(22, value); + return currentImpl(value); + } + + function currentImpl(value) { + if (!isDraftable(value)) return value; + var state = value[DRAFT_STATE]; + var copy; + var archType = getArchtype(value); + + if (state) { + if (!state.modified_ && (state.type_ < 4 || !getPlugin("ES5").hasChanges_(state))) return state.base_; // Optimization: avoid generating new drafts during copying + + state.finalized_ = true; + copy = copyHelper(value, archType); + state.finalized_ = false; + } else { + copy = copyHelper(value, archType); } - function Rg(e) { - return ne(null == e ? void 0 : e.avgBandwidth) + + each(copy, function (key, childValue) { + if (state && get(state.base_, key) === childValue) return; // no need to copy or search in something that didn't change + + set(copy, key, currentImpl(childValue)); + }); // In the future, we might consider freezing here, based on the current settings + + return archType === ArchtypeSet ? new Set(copy) : copy; + } + + function copyHelper(value, archType) { + // creates a shallow copy, even if it is a map or set + switch (archType) { + case ArchtypeMap: + return new Map(value); + + case ArchtypeSet: + // Set will be cloned as array temporarily, so that we can replace individual items + return Array.from(value); } - function Lg(e, t) { - return e.getCurrentWaterLevelByType(cl.Variant, t) / (0 !== e.playbackRate ? Math.abs(e.playbackRate) : 1) + + return shallowCopy(value); + } + + function enableES5() { + function willFinalizeES5_(scope, result, isReplaced) { + if (!isReplaced) { + if (scope.patches_) { + markChangesRecursively(scope.drafts_[0]); + } // This is faster when we don't care about which attributes changed. + + + markChangesSweep(scope.drafts_); + } // When a child draft is returned, look for changes. + else if (isDraft(result) && result[DRAFT_STATE].scope_ === scope) { + markChangesSweep(scope.drafts_); + } } - function _g(t, i, e, r) { - if (e) - return t; - let n = -1; - if (t < 0) - return n; - for (let e = t; e < i.length; ++e) { - const t = Fg(i[e], r); - if (t.altAudio && t.subtitle) { - n = e; - break + + function createES5Draft(isArray, base) { + if (isArray) { + var draft = new Array(base.length); + + for (var i = 0; i < base.length; i++) { + Object.defineProperty(draft, "" + i, proxyProperty(i, true)); + } + + return draft; + } else { + var _descriptors = getOwnPropertyDescriptors(base); + + delete _descriptors[DRAFT_STATE]; + var keys = ownKeys(_descriptors); + + for (var _i = 0; _i < keys.length; _i++) { + var key = keys[_i]; + _descriptors[key] = proxyProperty(key, isArray || !!_descriptors[key].enumerable); + } + + return Object.create(Object.getPrototypeOf(base), _descriptors); + } + } + + function createES5Proxy_(base, parent) { + var isArray = Array.isArray(base); + var draft = createES5Draft(isArray, base); + var state = { + type_: isArray ? ProxyTypeES5Array : ProxyTypeES5Object, + scope_: parent ? parent.scope_ : getCurrentScope(), + modified_: false, + finalized_: false, + assigned_: {}, + parent_: parent, + // base is the object we are drafting + base_: base, + // draft is the draft object itself, that traps all reads and reads from either the base (if unmodified) or copy (if modified) + draft_: draft, + copy_: null, + revoked_: false, + isManual_: false + }; + Object.defineProperty(draft, DRAFT_STATE, { + value: state, + // enumerable: false <- the default + writable: true + }); + return draft; + } // property descriptors are recycled to make sure we don't create a get and set closure per property, + // but share them all instead + + + var descriptors = {}; + + function proxyProperty(prop, enumerable) { + var desc = descriptors[prop]; + + if (desc) { + desc.enumerable = enumerable; + } else { + descriptors[prop] = desc = { + configurable: true, + enumerable: enumerable, + get: function get() { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); // @ts-ignore + + return objectTraps.get(state, prop); + }, + set: function set(value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); // @ts-ignore + + objectTraps.set(state, prop, value); + } + }; + } + + return desc; + } // This looks expensive, but only proxies are visited, and only objects without known changes are scanned. + + + function markChangesSweep(drafts) { + // The natural order of drafts in the `scope` array is based on when they + // were accessed. By processing drafts in reverse natural order, we have a + // better chance of processing leaf nodes first. When a leaf node is known to + // have changed, we can avoid any traversal of its ancestor nodes. + for (var i = drafts.length - 1; i >= 0; i--) { + var state = drafts[i][DRAFT_STATE]; + + if (!state.modified_) { + switch (state.type_) { + case ProxyTypeES5Array: + if (hasArrayChanges(state)) markChanged(state); + break; + + case ProxyTypeES5Object: + if (hasObjectChanges(state)) markChanged(state); + break; + } + } + } + } + + function markChangesRecursively(object) { + if (!object || typeof object !== "object") return; + var state = object[DRAFT_STATE]; + if (!state) return; + var base_ = state.base_, + draft_ = state.draft_, + assigned_ = state.assigned_, + type_ = state.type_; + + if (type_ === ProxyTypeES5Object) { + // Look for added keys. + // probably there is a faster way to detect changes, as sweep + recurse seems to do some + // unnecessary work. + // also: probably we can store the information we detect here, to speed up tree finalization! + each(draft_, function (key) { + if (key === DRAFT_STATE) return; // The `undefined` check is a fast path for pre-existing keys. + + if (base_[key] === undefined && !has(base_, key)) { + assigned_[key] = true; + markChanged(state); + } else if (!assigned_[key]) { + // Only untouched properties trigger recursion. + markChangesRecursively(draft_[key]); + } + }); // Look for removed keys. + + each(base_, function (key) { + // The `undefined` check is a fast path for pre-existing keys. + if (draft_[key] === undefined && !has(draft_, key)) { + assigned_[key] = false; + markChanged(state); + } + }); + } else if (type_ === ProxyTypeES5Array) { + if (hasArrayChanges(state)) { + markChanged(state); + assigned_.length = true; + } + + if (draft_.length < base_.length) { + for (var i = draft_.length; i < base_.length; i++) { + assigned_[i] = false; + } + } else { + for (var _i2 = base_.length; _i2 < draft_.length; _i2++) { + assigned_[_i2] = true; + } + } // Minimum count is enough, the other parts has been processed. + + + var min = Math.min(draft_.length, base_.length); + + for (var _i3 = 0; _i3 < min; _i3++) { + // Only untouched indices trigger recursion. + if (assigned_[_i3] === undefined) markChangesRecursively(draft_[_i3]); + } + } + } + + function hasObjectChanges(state) { + var base_ = state.base_, + draft_ = state.draft_; // Search for added keys and changed keys. Start at the back, because + // non-numeric keys are ordered by time of definition on the object. + + var keys = ownKeys(draft_); + + for (var i = keys.length - 1; i >= 0; i--) { + var key = keys[i]; + if (key === DRAFT_STATE) continue; + var baseValue = base_[key]; // The `undefined` check is a fast path for pre-existing keys. + + if (baseValue === undefined && !has(base_, key)) { + return true; + } // Once a base key is deleted, future changes go undetected, because its + // descriptor is erased. This branch detects any missed changes. + else { + var value = draft_[key]; + + var _state = value && value[DRAFT_STATE]; + + if (_state ? _state.base_ !== baseValue : !is(value, baseValue)) { + return true; } - } - return n + } + } // At this point, no keys were added or changed. + // Compare key count to determine if keys were deleted. + + + var baseIsDraft = !!base_[DRAFT_STATE]; + return keys.length !== ownKeys(base_).length + (baseIsDraft ? 0 : 1); // + 1 to correct for DRAFT_STATE } - function Ng(t, e, i, r, n, s, a) { - const o = i.preferredMediaOptions[ul.Variant].filter(e=>e.iframes === t); - if (!o.length) - return { - variantMediaOption: Ol.mediaOptionId, - holdOffDuration: 0, - lowestCandidate: null - }; - let d = 0; - const l = i.nextMinAutoOptionId; - if (l !== Ol.mediaOptionId) { - const t = o.findIndex(e=>e.mediaOptionId === l); - 0 <= t && (d = t) + + function hasArrayChanges(state) { + var draft_ = state.draft_; + if (draft_.length !== state.base_.length) return true; // See #116 + // If we first shorten the length, our array interceptors will be removed. + // If after that new items are added, result in the same original length, + // those last items will have no intercepting property. + // So if there is no own descriptor on the last position, we know that items were removed and added + // N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check + // the last one + + var descriptor = Object.getOwnPropertyDescriptor(draft_, draft_.length - 1); // descriptor can be null, but only for newly created sparse arrays, eg. new Array(10) + + if (descriptor && !descriptor.get) return true; // For all other cases, we don't have to compare, as they would have been picked up by the index setters + + return false; + } + + function hasChanges_(state) { + return state.type_ === ProxyTypeES5Object ? hasObjectChanges(state) : hasArrayChanges(state); + } + + function assertUnrevoked(state + /*ES5State | MapState | SetState*/ + ) { + if (state.revoked_) die(3, JSON.stringify(latest(state))); + } + + loadPlugin("ES5", { + createES5Proxy_: createES5Proxy_, + willFinalizeES5_: willFinalizeES5_, + hasChanges_: hasChanges_ + }); + } + + function enablePatches() { + var REPLACE = "replace"; + var ADD = "add"; + var REMOVE = "remove"; + + function generatePatches_(state, basePath, patches, inversePatches) { + switch (state.type_) { + case ProxyTypeProxyObject: + case ProxyTypeES5Object: + case ProxyTypeMap: + return generatePatchesFromAssigned(state, basePath, patches, inversePatches); + + case ProxyTypeES5Array: + case ProxyTypeProxyArray: + return generateArrayPatches(state, basePath, patches, inversePatches); + + case ProxyTypeSet: + return generateSetPatches(state, basePath, patches, inversePatches); + } + } + + function generateArrayPatches(state, basePath, patches, inversePatches) { + var base_ = state.base_, + assigned_ = state.assigned_; + var copy_ = state.copy_; // Reduce complexity by ensuring `base` is never longer. + + if (copy_.length < base_.length) { + var _ref = [copy_, base_]; + base_ = _ref[0]; + copy_ = _ref[1]; + var _ref2 = [inversePatches, patches]; + patches = _ref2[0]; + inversePatches = _ref2[1]; + } // Process replaced indices. + + + for (var i = 0; i < base_.length; i++) { + if (assigned_[i] && copy_[i] !== base_[i]) { + var path = basePath.concat([i]); + patches.push({ + op: REPLACE, + path: path, + // Need to maybe clone it, as it can in fact be the original value + // due to the base/copy inversion at the start of this function + value: clonePatchValueIfNeeded(copy_[i]) + }); + inversePatches.push({ + op: REPLACE, + path: path, + value: clonePatchValueIfNeeded(base_[i]) + }); } - if (d = _g(d, o, t, i), - d < 0) - return { - variantMediaOption: Ol.mediaOptionId, - holdOffDuration: 0, - lowestCandidate: null - }; - let u = o.length - 1; - const c = i.nextMaxAutoOptionId; - if (c !== Ol.mediaOptionId) { - const t = o.findIndex(e=>e.mediaOptionId === c); - 0 <= t && (u = t) + } // Process added indices. + + + for (var _i = base_.length; _i < copy_.length; _i++) { + var _path = basePath.concat([_i]); + + patches.push({ + op: ADD, + path: _path, + // Need to maybe clone it, as it can in fact be the original value + // due to the base/copy inversion at the start of this function + value: clonePatchValueIfNeeded(copy_[_i]) + }); + } + + if (base_.length < copy_.length) { + inversePatches.push({ + op: REPLACE, + path: basePath.concat(["length"]), + value: base_.length + }); + } + } // This is used for both Map objects and normal objects. + + + function generatePatchesFromAssigned(state, basePath, patches, inversePatches) { + var base_ = state.base_, + copy_ = state.copy_; + each(state.assigned_, function (key, assignedValue) { + var origValue = get(base_, key); + var value = get(copy_, key); + var op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD; + if (origValue === value && op === REPLACE) return; + var path = basePath.concat(key); + patches.push(op === REMOVE ? { + op: op, + path: path + } : { + op: op, + path: path, + value: value + }); + inversePatches.push(op === ADD ? { + op: REMOVE, + path: path + } : op === REMOVE ? { + op: ADD, + path: path, + value: clonePatchValueIfNeeded(origValue) + } : { + op: REPLACE, + path: path, + value: clonePatchValueIfNeeded(origValue) + }); + }); + } + + function generateSetPatches(state, basePath, patches, inversePatches) { + var base_ = state.base_, + copy_ = state.copy_; + var i = 0; + base_.forEach(function (value) { + if (!copy_.has(value)) { + var path = basePath.concat([i]); + patches.push({ + op: REMOVE, + path: path, + value: value + }); + inversePatches.unshift({ + op: ADD, + path: path, + value: value + }); } - var h = i.variantMediaOptionById(r.mediaOptionId) - , p = r.mediaOptionDetails - , f = (null == h ? void 0 : h.iframes) !== t ? 0 : Lg(n, e.maxBufferHole); - let m, g; - if (t) { - const t = e.desiredIframeFPS; - g = p ? p.targetduration / t : 0, - g = Math.max(1 / t, g) + + i++; + }); + i = 0; + copy_.forEach(function (value) { + if (!base_.has(value)) { + var path = basePath.concat([i]); + patches.push({ + op: ADD, + path: path, + value: value + }); + inversePatches.unshift({ + op: REMOVE, + path: path, + value: value + }); + } + + i++; + }); + } + + function generateReplacementPatches_(rootState, replacement, patches, inversePatches) { + patches.push({ + op: REPLACE, + path: [], + value: replacement + }); + inversePatches.push({ + op: REPLACE, + path: [], + value: rootState.base_ + }); + } + + function applyPatches_(draft, patches) { + patches.forEach(function (patch) { + var path = patch.path, + op = patch.op; + var base = draft; + + for (var i = 0; i < path.length - 1; i++) { + base = get(base, path[i]); + if (typeof base !== "object") die(15, path.join("/")); + } + + var type = getArchtype(base); + var value = deepClonePatchValue(patch.value); // used to clone patch to ensure original patch is not modified, see #411 + + var key = path[path.length - 1]; + + switch (op) { + case REPLACE: + switch (type) { + case ArchtypeMap: + return base.set(key, value); + + /* istanbul ignore next */ + + case ArchtypeSet: + die(16); + + default: + // if value is an object, then it's assigned by reference + // in the following add or remove ops, the value field inside the patch will also be modifyed + // so we use value from the cloned patch + // @ts-ignore + return base[key] = value; + } + + case ADD: + switch (type) { + case ArchtypeArray: + return base.splice(key, 0, value); + + case ArchtypeMap: + return base.set(key, value); + + case ArchtypeSet: + return base.add(value); + + default: + return base[key] = value; + } + + case REMOVE: + switch (type) { + case ArchtypeArray: + return base.splice(key, 1); + + case ArchtypeMap: + return base.delete(key); + + case ArchtypeSet: + return base.delete(patch.value); + + default: + return delete base[key]; + } + + default: + die(17, op); + } + }); + return draft; + } + + function deepClonePatchValue(obj) { + if (!isDraftable(obj)) return obj; + if (Array.isArray(obj)) return obj.map(deepClonePatchValue); + if (isMap(obj)) return new Map(Array.from(obj.entries()).map(function (_ref3) { + var k = _ref3[0], + v = _ref3[1]; + return [k, deepClonePatchValue(v)]; + })); + if (isSet(obj)) return new Set(Array.from(obj).map(deepClonePatchValue)); + var cloned = Object.create(Object.getPrototypeOf(obj)); + + for (var key in obj) { + cloned[key] = deepClonePatchValue(obj[key]); + } + + return cloned; + } + + function clonePatchValueIfNeeded(obj) { + if (isDraft(obj)) { + return deepClonePatchValue(obj); + } else return obj; + } + + loadPlugin("Patches", { + applyPatches_: applyPatches_, + generatePatches_: generatePatches_, + generateReplacementPatches_: generateReplacementPatches_ + }); + } + + // types only! + function enableMapSet() { + /* istanbul ignore next */ + var _extendStatics = function extendStatics(d, b) { + _extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) { + if (b.hasOwnProperty(p)) d[p] = b[p]; + } + }; + + return _extendStatics(d, b); + }; // Ugly hack to resolve #502 and inherit built in Map / Set + + + function __extends(d, b) { + _extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = ( // @ts-ignore + __.prototype = b.prototype, new __()); + } + + var DraftMap = function (_super) { + __extends(DraftMap, _super); // Create class manually, cause #502 + + + function DraftMap(target, parent) { + this[DRAFT_STATE] = { + type_: ProxyTypeMap, + parent_: parent, + scope_: parent ? parent.scope_ : getCurrentScope(), + modified_: false, + finalized_: false, + copy_: undefined, + assigned_: undefined, + base_: target, + draft_: this, + isManual_: false, + revoked_: false + }; + return this; + } + + var p = DraftMap.prototype; + Object.defineProperty(p, "size", { + get: function get() { + return latest(this[DRAFT_STATE]).size; + } // enumerable: false, + // configurable: true + + }); + + p.has = function (key) { + return latest(this[DRAFT_STATE]).has(key); + }; + + p.set = function (key, value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (!latest(state).has(key) || latest(state).get(key) !== value) { + prepareMapCopy(state); + markChanged(state); + state.assigned_.set(key, true); + state.copy_.set(key, value); + state.assigned_.set(key, true); + } + + return this; + }; + + p.delete = function (key) { + if (!this.has(key)) { + return false; + } + + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareMapCopy(state); + markChanged(state); + state.assigned_.set(key, false); + state.copy_.delete(key); + return true; + }; + + p.clear = function () { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (latest(state).size) { + prepareMapCopy(state); + markChanged(state); + state.assigned_ = new Map(); + each(state.base_, function (key) { + state.assigned_.set(key, false); + }); + state.copy_.clear(); + } + }; + + p.forEach = function (cb, thisArg) { + var _this = this; + + var state = this[DRAFT_STATE]; + latest(state).forEach(function (_value, key, _map) { + cb.call(thisArg, _this.get(key), key, _this); + }); + }; + + p.get = function (key) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + var value = latest(state).get(key); + + if (state.finalized_ || !isDraftable(value)) { + return value; + } + + if (value !== state.base_.get(key)) { + return value; // either already drafted or reassigned + } // despite what it looks, this creates a draft only once, see above condition + + + var draft = createProxy(state.scope_.immer_, value, state); + prepareMapCopy(state); + state.copy_.set(key, draft); + return draft; + }; + + p.keys = function () { + return latest(this[DRAFT_STATE]).keys(); + }; + + p.values = function () { + var _this2 = this, + _ref; + + var iterator = this.keys(); + return _ref = {}, _ref[iteratorSymbol] = function () { + return _this2.values(); + }, _ref.next = function next() { + var r = iterator.next(); + /* istanbul ignore next */ + + if (r.done) return r; + + var value = _this2.get(r.value); + + return { + done: false, + value: value + }; + }, _ref; + }; + + p.entries = function () { + var _this3 = this, + _ref2; + + var iterator = this.keys(); + return _ref2 = {}, _ref2[iteratorSymbol] = function () { + return _this3.entries(); + }, _ref2.next = function next() { + var r = iterator.next(); + /* istanbul ignore next */ + + if (r.done) return r; + + var value = _this3.get(r.value); + + return { + done: false, + value: [r.value, value] + }; + }, _ref2; + }; + + p[iteratorSymbol] = function () { + return this.entries(); + }; + + return DraftMap; + }(Map); + + function proxyMap_(target, parent) { + // @ts-ignore + return new DraftMap(target, parent); + } + + function prepareMapCopy(state) { + if (!state.copy_) { + state.assigned_ = new Map(); + state.copy_ = new Map(state.base_); + } + } + + var DraftSet = function (_super) { + __extends(DraftSet, _super); // Create class manually, cause #502 + + + function DraftSet(target, parent) { + this[DRAFT_STATE] = { + type_: ProxyTypeSet, + parent_: parent, + scope_: parent ? parent.scope_ : getCurrentScope(), + modified_: false, + finalized_: false, + copy_: undefined, + base_: target, + draft_: this, + drafts_: new Map(), + revoked_: false, + isManual_: false + }; + return this; + } + + var p = DraftSet.prototype; + Object.defineProperty(p, "size", { + get: function get() { + return latest(this[DRAFT_STATE]).size; + } // enumerable: true, + + }); + + p.has = function (value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); // bit of trickery here, to be able to recognize both the value, and the draft of its value + + if (!state.copy_) { + return state.base_.has(value); + } + + if (state.copy_.has(value)) return true; + if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value))) return true; + return false; + }; + + p.add = function (value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (!this.has(value)) { + prepareSetCopy(state); + markChanged(state); + state.copy_.add(value); + } + + return this; + }; + + p.delete = function (value) { + if (!this.has(value)) { + return false; + } + + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareSetCopy(state); + markChanged(state); + return state.copy_.delete(value) || (state.drafts_.has(value) ? state.copy_.delete(state.drafts_.get(value)) : + /* istanbul ignore next */ + false); + }; + + p.clear = function () { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (latest(state).size) { + prepareSetCopy(state); + markChanged(state); + state.copy_.clear(); + } + }; + + p.values = function () { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareSetCopy(state); + return state.copy_.values(); + }; + + p.entries = function entries() { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareSetCopy(state); + return state.copy_.entries(); + }; + + p.keys = function () { + return this.values(); + }; + + p[iteratorSymbol] = function () { + return this.values(); + }; + + p.forEach = function forEach(cb, thisArg) { + var iterator = this.values(); + var result = iterator.next(); + + while (!result.done) { + cb.call(thisArg, result.value, result.value, this); + result = iterator.next(); + } + }; + + return DraftSet; + }(Set); + + function proxySet_(target, parent) { + // @ts-ignore + return new DraftSet(target, parent); + } + + function prepareSetCopy(state) { + if (!state.copy_) { + // create drafts for all entries to preserve insertion order + state.copy_ = new Set(); + state.base_.forEach(function (value) { + if (isDraftable(value)) { + var draft = createProxy(state.scope_.immer_, value, state); + state.drafts_.set(value, draft); + state.copy_.add(draft); + } else { + state.copy_.add(value); + } + }); + } + } + + function assertUnrevoked(state + /*ES5State | MapState | SetState*/ + ) { + if (state.revoked_) die(3, JSON.stringify(latest(state))); + } + + loadPlugin("MapSet", { + proxyMap_: proxyMap_, + proxySet_: proxySet_ + }); + } + + function enableAllPlugins() { + enableES5(); + enableMapSet(); + enablePatches(); + } + + var immer = + /*#__PURE__*/ + new Immer(); + /** + * The `produce` function takes a value and a "recipe function" (whose + * return value often depends on the base state). The recipe function is + * free to mutate its first argument however it wants. All mutations are + * only ever applied to a __copy__ of the base state. + * + * Pass only a function to create a "curried producer" which relieves you + * from passing the recipe function every time. + * + * Only plain objects and arrays are made mutable. All other objects are + * considered uncopyable. + * + * Note: This function is __bound__ to its `Immer` instance. + * + * @param {any} base - the initial state + * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified + * @param {Function} patchListener - optional function that will be called with all the patches produced here + * @returns {any} a new state, or the initial state if nothing was modified + */ + + var produce = immer.produce; + /** + * Like `produce`, but `produceWithPatches` always returns a tuple + * [nextState, patches, inversePatches] (instead of just the next state) + */ + + var produceWithPatches = + /*#__PURE__*/ + immer.produceWithPatches.bind(immer); + /** + * Pass true to automatically freeze all copies created by Immer. + * + * By default, auto-freezing is disabled in production. + */ + + var setAutoFreeze = + /*#__PURE__*/ + immer.setAutoFreeze.bind(immer); + /** + * Pass true to use the ES2015 `Proxy` class when creating drafts, which is + * always faster than using ES5 proxies. + * + * By default, feature detection is used, so calling this is rarely necessary. + */ + + var setUseProxies = + /*#__PURE__*/ + immer.setUseProxies.bind(immer); + /** + * Apply an array of Immer patches to the first argument. + * + * This function is a producer, which means copy-on-write is in effect. + */ + + var applyPatches = + /*#__PURE__*/ + immer.applyPatches.bind(immer); + /** + * Create an Immer draft from the given base state, which may be a draft itself. + * The draft can be modified until you finalize it with the `finishDraft` function. + */ + + var createDraft = + /*#__PURE__*/ + immer.createDraft.bind(immer); + /** + * Finalize an Immer draft from a `createDraft` call, returning the base state + * (if no changes were made) or a modified copy. The draft must *not* be + * mutated afterwards. + * + * Pass a function as the 2nd argument to generate Immer patches based on the + * changes that were made. + */ + + var finishDraft = + /*#__PURE__*/ + immer.finishDraft.bind(immer); + /** + * This function is actually a no-op, but can be used to cast an immutable type + * to an draft type and make TypeScript happy + * + * @param value + */ + + function castDraft(value) { + return value; + } + /** + * This function is actually a no-op, but can be used to cast a mutable type + * to an immutable type and make TypeScript happy + * @param value + */ + + function castImmutable(value) { + return value; + } + + immer_cjs_development.Immer = Immer; + immer_cjs_development.applyPatches = applyPatches; + immer_cjs_development.castDraft = castDraft; + immer_cjs_development.castImmutable = castImmutable; + immer_cjs_development.createDraft = createDraft; + immer_cjs_development.current = current; + immer_cjs_development.default = produce; + immer_cjs_development.enableAllPlugins = enableAllPlugins; + immer_cjs_development.enableES5 = enableES5; + var enableMapSet_1 = immer_cjs_development.enableMapSet = enableMapSet; + immer_cjs_development.enablePatches = enablePatches; + immer_cjs_development.finishDraft = finishDraft; + immer_cjs_development.immerable = DRAFTABLE; + immer_cjs_development.isDraft = isDraft; + immer_cjs_development.isDraftable = isDraftable; + immer_cjs_development.nothing = NOTHING; + immer_cjs_development.original = original; + var produce_1 = immer_cjs_development.produce = produce; + immer_cjs_development.produceWithPatches = produceWithPatches; + var setAutoFreeze_1 = immer_cjs_development.setAutoFreeze = setAutoFreeze; + immer_cjs_development.setUseProxies = setUseProxies; + + var rtc = {exports: {}}; + + /** + * + * Copyright (c) 2018 Apple (http://www.apple.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + (function (module, exports) { + /*! Modules included in this bundle: + * name: process + * license: MIT + * version: 0.11.10 + * text: + * (The MIT License) + * + * Copyright (c) 2013 Roman Shtylman + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * name: semver + * license: ISC + * version: 5.5.0 + * text: + * The ISC License + * + * Copyright (c) Isaac Z. Schlueter and Contributors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * + * name: webpack + * license: MIT + * version: 4.41.2 + * text: + * Copyright JS Foundation and other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + */ + (function webpackUniversalModuleDefinition(root, factory) { + module.exports = factory(); + })(commonjsGlobal, function() { + return /******/ (function(modules) { // webpackBootstrap + /******/ // The module cache + /******/ var installedModules = {}; + /******/ + /******/ // The require function + /******/ function __webpack_require__(moduleId) { + /******/ + /******/ // Check if module is in cache + /******/ if(installedModules[moduleId]) { + /******/ return installedModules[moduleId].exports; + /******/ } + /******/ // Create a new module (and put it into the cache) + /******/ var module = installedModules[moduleId] = { + /******/ i: moduleId, + /******/ l: false, + /******/ exports: {} + /******/ }; + /******/ + /******/ // Execute the module function + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + /******/ + /******/ // Flag the module as loaded + /******/ module.l = true; + /******/ + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ } + /******/ + /******/ + /******/ // expose the modules object (__webpack_modules__) + /******/ __webpack_require__.m = modules; + /******/ + /******/ // expose the module cache + /******/ __webpack_require__.c = installedModules; + /******/ + /******/ // define getter function for harmony exports + /******/ __webpack_require__.d = function(exports, name, getter) { + /******/ if(!__webpack_require__.o(exports, name)) { + /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); + /******/ } + /******/ }; + /******/ + /******/ // define __esModule on exports + /******/ __webpack_require__.r = function(exports) { + /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { + /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); + /******/ } + /******/ Object.defineProperty(exports, '__esModule', { value: true }); + /******/ }; + /******/ + /******/ // create a fake namespace object + /******/ // mode & 1: value is a module id, require it + /******/ // mode & 2: merge all properties of value into the ns + /******/ // mode & 4: return value when already ns object + /******/ // mode & 8|1: behave like require + /******/ __webpack_require__.t = function(value, mode) { + /******/ if(mode & 1) value = __webpack_require__(value); + /******/ if(mode & 8) return value; + /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; + /******/ var ns = Object.create(null); + /******/ __webpack_require__.r(ns); + /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); + /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); + /******/ return ns; + /******/ }; + /******/ + /******/ // getDefaultExport function for compatibility with non-harmony modules + /******/ __webpack_require__.n = function(module) { + /******/ var getter = module && module.__esModule ? + /******/ function getDefault() { return module['default']; } : + /******/ function getModuleExports() { return module; }; + /******/ __webpack_require__.d(getter, 'a', getter); + /******/ return getter; + /******/ }; + /******/ + /******/ // Object.prototype.hasOwnProperty.call + /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + /******/ + /******/ // __webpack_public_path__ + /******/ __webpack_require__.p = ""; + /******/ + /******/ + /******/ // Load entry module and return exports + /******/ return __webpack_require__(__webpack_require__.s = "./src/rtc_reporting/reporting_agent.ts"); + /******/ }) + /************************************************************************/ + /******/ ({ + + /***/ "./node_modules/process/browser.js": + /*!*****************************************!*\ + !*** ./node_modules/process/browser.js ***! + \*****************************************/ + /*! no static exports found */ + /***/ (function(module, exports) { + + // shim for using process in browser + var process = module.exports = {}; + + // cached from whatever global is present so that test runners that stub it + // don't break things. But we need to wrap it in a try catch in case it is + // wrapped in strict mode code which doesn't define any globals. It's inside a + // function because try/catches deoptimize in certain engines. + + var cachedSetTimeout; + var cachedClearTimeout; + + function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); + } + function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); + } + (function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } + } ()); + function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + + } + function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + + } + var queue = []; + var draining = false; + var currentQueue; + var queueIndex = -1; + + function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } + } + + function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); + } + + process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } + }; + + // v8 likes predictible objects + function Item(fun, array) { + this.fun = fun; + this.array = array; + } + Item.prototype.run = function () { + this.fun.apply(null, this.array); + }; + process.title = 'browser'; + process.browser = true; + process.env = {}; + process.argv = []; + process.version = ''; // empty string to avoid regexp issues + process.versions = {}; + + function noop() {} + + process.on = noop; + process.addListener = noop; + process.once = noop; + process.off = noop; + process.removeListener = noop; + process.removeAllListeners = noop; + process.emit = noop; + process.prependListener = noop; + process.prependOnceListener = noop; + + process.listeners = function (name) { return [] }; + + process.binding = function (name) { + throw new Error('process.binding is not supported'); + }; + + process.cwd = function () { return '/' }; + process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); + }; + process.umask = function() { return 0; }; + + + /***/ }), + + /***/ "./node_modules/semver/semver.js": + /*!***************************************!*\ + !*** ./node_modules/semver/semver.js ***! + \***************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {exports = module.exports = SemVer; + + // The debug function is excluded entirely from the minified version. + /* nomin */ var debug; + /* nomin */ if (typeof process === 'object' && + /* nomin */ process.env && + /* nomin */ process.env.NODE_DEBUG && + /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) + /* nomin */ debug = function() { + /* nomin */ var args = Array.prototype.slice.call(arguments, 0); + /* nomin */ args.unshift('SEMVER'); + /* nomin */ console.log.apply(console, args); + /* nomin */ }; + /* nomin */ else + /* nomin */ debug = function() {}; + + // Note: this is the semver.org version of the spec that it implements + // Not necessarily the package version of this code. + exports.SEMVER_SPEC_VERSION = '2.0.0'; + + var MAX_LENGTH = 256; + var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + + // Max safe segment length for coercion. + var MAX_SAFE_COMPONENT_LENGTH = 16; + + // The actual regexps go on exports.re + var re = exports.re = []; + var src = exports.src = []; + var R = 0; + + // The following Regular Expressions can be used for tokenizing, + // validating, and parsing SemVer version strings. + + // ## Numeric Identifier + // A single `0`, or a non-zero digit followed by zero or more digits. + + var NUMERICIDENTIFIER = R++; + src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; + var NUMERICIDENTIFIERLOOSE = R++; + src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; + + + // ## Non-numeric Identifier + // Zero or more digits, followed by a letter or hyphen, and then zero or + // more letters, digits, or hyphens. + + var NONNUMERICIDENTIFIER = R++; + src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; + + + // ## Main Version + // Three dot-separated numeric identifiers. + + var MAINVERSION = R++; + src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')'; + + var MAINVERSIONLOOSE = R++; + src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; + + // ## Pre-release Version Identifier + // A numeric identifier, or a non-numeric identifier. + + var PRERELEASEIDENTIFIER = R++; + src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + + var PRERELEASEIDENTIFIERLOOSE = R++; + src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + + + // ## Pre-release Version + // Hyphen, followed by one or more dot-separated pre-release version + // identifiers. + + var PRERELEASE = R++; + src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; + + var PRERELEASELOOSE = R++; + src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; + + // ## Build Metadata Identifier + // Any combination of digits, letters, or hyphens. + + var BUILDIDENTIFIER = R++; + src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; + + // ## Build Metadata + // Plus sign, followed by one or more period-separated build metadata + // identifiers. + + var BUILD = R++; + src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; + + + // ## Full Version String + // A main version, followed optionally by a pre-release version and + // build metadata. + + // Note that the only major, minor, patch, and pre-release sections of + // the version string are capturing groups. The build metadata is not a + // capturing group, because it should not ever be used in version + // comparison. + + var FULL = R++; + var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?'; + + src[FULL] = '^' + FULLPLAIN + '$'; + + // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. + // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty + // common in the npm registry. + var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?'; + + var LOOSE = R++; + src[LOOSE] = '^' + LOOSEPLAIN + '$'; + + var GTLT = R++; + src[GTLT] = '((?:<|>)?=?)'; + + // Something like "2.*" or "1.2.x". + // Note that "x.x" is a valid xRange identifer, meaning "any version" + // Only the first item is strictly required. + var XRANGEIDENTIFIERLOOSE = R++; + src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; + var XRANGEIDENTIFIER = R++; + src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; + + var XRANGEPLAIN = R++; + src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + + var XRANGEPLAINLOOSE = R++; + src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + + var XRANGE = R++; + src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; + var XRANGELOOSE = R++; + src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; + + // Coercion. + // Extract anything that could conceivably be a part of a valid semver + var COERCE = R++; + src[COERCE] = '(?:^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])'; + + // Tilde ranges. + // Meaning is "reasonably at or greater than" + var LONETILDE = R++; + src[LONETILDE] = '(?:~>?)'; + + var TILDETRIM = R++; + src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; + re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); + var tildeTrimReplace = '$1~'; + + var TILDE = R++; + src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; + var TILDELOOSE = R++; + src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; + + // Caret ranges. + // Meaning is "at least and backwards compatible with" + var LONECARET = R++; + src[LONECARET] = '(?:\\^)'; + + var CARETTRIM = R++; + src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; + re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); + var caretTrimReplace = '$1^'; + + var CARET = R++; + src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; + var CARETLOOSE = R++; + src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; + + // A simple gt/lt/eq thing, or just "" to indicate "any version" + var COMPARATORLOOSE = R++; + src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; + var COMPARATOR = R++; + src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; + + + // An expression to strip any whitespace between the gtlt and the thing + // it modifies, so that `> 1.2.3` ==> `>1.2.3` + var COMPARATORTRIM = R++; + src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; + + // this one has to use the /g flag + re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); + var comparatorTrimReplace = '$1$2$3'; + + + // Something like `1.2.3 - 1.2.4` + // Note that these all use the loose form, because they'll be + // checked against either the strict or loose comparator form + // later. + var HYPHENRANGE = R++; + src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$'; + + var HYPHENRANGELOOSE = R++; + src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$'; + + // Star ranges basically just allow anything at all. + var STAR = R++; + src[STAR] = '(<|>)?=?\\s*\\*'; + + // Compile to actual regexp objects. + // All are flag-free, unless they were created above with a flag. + for (var i = 0; i < R; i++) { + debug(i, src[i]); + if (!re[i]) + re[i] = new RegExp(src[i]); + } + + exports.parse = parse; + function parse(version, loose) { + if (version instanceof SemVer) + return version; + + if (typeof version !== 'string') + return null; + + if (version.length > MAX_LENGTH) + return null; + + var r = loose ? re[LOOSE] : re[FULL]; + if (!r.test(version)) + return null; + + try { + return new SemVer(version, loose); + } catch (er) { + return null; + } + } + + exports.valid = valid; + function valid(version, loose) { + var v = parse(version, loose); + return v ? v.version : null; + } + + + exports.clean = clean; + function clean(version, loose) { + var s = parse(version.trim().replace(/^[=v]+/, ''), loose); + return s ? s.version : null; + } + + exports.SemVer = SemVer; + + function SemVer(version, loose) { + if (version instanceof SemVer) { + if (version.loose === loose) + return version; + else + version = version.version; + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version); + } + + if (version.length > MAX_LENGTH) + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + + if (!(this instanceof SemVer)) + return new SemVer(version, loose); + + debug('SemVer', version, loose); + this.loose = loose; + var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); + + if (!m) + throw new TypeError('Invalid Version: ' + version); + + this.raw = version; + + // these are actually numbers + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) + throw new TypeError('Invalid major version') + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) + throw new TypeError('Invalid minor version') + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) + throw new TypeError('Invalid patch version') + + // numberify any prerelease numeric ids + if (!m[4]) + this.prerelease = []; + else + this.prerelease = m[4].split('.').map(function(id) { + if (/^[0-9]+$/.test(id)) { + var num = +id; + if (num >= 0 && num < MAX_SAFE_INTEGER) + return num; + } + return id; + }); + + this.build = m[5] ? m[5].split('.') : []; + this.format(); + } + + SemVer.prototype.format = function() { + this.version = this.major + '.' + this.minor + '.' + this.patch; + if (this.prerelease.length) + this.version += '-' + this.prerelease.join('.'); + return this.version; + }; + + SemVer.prototype.toString = function() { + return this.version; + }; + + SemVer.prototype.compare = function(other) { + debug('SemVer.compare', this.version, this.loose, other); + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return this.compareMain(other) || this.comparePre(other); + }; + + SemVer.prototype.compareMain = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch); + }; + + SemVer.prototype.comparePre = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) + return -1; + else if (!this.prerelease.length && other.prerelease.length) + return 1; + else if (!this.prerelease.length && !other.prerelease.length) + return 0; + + var i = 0; + do { + var a = this.prerelease[i]; + var b = other.prerelease[i]; + debug('prerelease compare', i, a, b); + if (a === undefined && b === undefined) + return 0; + else if (b === undefined) + return 1; + else if (a === undefined) + return -1; + else if (a === b) + continue; + else + return compareIdentifiers(a, b); + } while (++i); + }; + + // preminor will bump the version up to the next minor release, and immediately + // down to pre-release. premajor and prepatch work the same way. + SemVer.prototype.inc = function(release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier); + break; + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier); + break; + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0; + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) + this.major++; + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break; + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) + this.minor++; + this.patch = 0; + this.prerelease = []; + break; + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) + this.patch++; + this.prerelease = []; + break; + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) + this.prerelease = [0]; + else { + var i = this.prerelease.length; + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++; + i = -2; + } + } + if (i === -1) // didn't increment anything + this.prerelease.push(0); + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) + this.prerelease = [identifier, 0]; + } else + this.prerelease = [identifier, 0]; + } + break; + + default: + throw new Error('invalid increment argument: ' + release); + } + this.format(); + this.raw = this.version; + return this; + }; + + exports.inc = inc; + function inc(version, release, loose, identifier) { + if (typeof(loose) === 'string') { + identifier = loose; + loose = undefined; + } + + try { + return new SemVer(version, loose).inc(release, identifier).version; + } catch (er) { + return null; + } + } + + exports.diff = diff; + function diff(version1, version2) { + if (eq(version1, version2)) { + return null; + } else { + var v1 = parse(version1); + var v2 = parse(version2); + if (v1.prerelease.length || v2.prerelease.length) { + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return 'pre'+key; + } + } + } + return 'prerelease'; + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return key; + } + } + } + } + } + + exports.compareIdentifiers = compareIdentifiers; + + var numeric = /^[0-9]+$/; + function compareIdentifiers(a, b) { + var anum = numeric.test(a); + var bnum = numeric.test(b); + + if (anum && bnum) { + a = +a; + b = +b; + } + + return (anum && !bnum) ? -1 : + (bnum && !anum) ? 1 : + a < b ? -1 : + a > b ? 1 : + 0; + } + + exports.rcompareIdentifiers = rcompareIdentifiers; + function rcompareIdentifiers(a, b) { + return compareIdentifiers(b, a); + } + + exports.major = major; + function major(a, loose) { + return new SemVer(a, loose).major; + } + + exports.minor = minor; + function minor(a, loose) { + return new SemVer(a, loose).minor; + } + + exports.patch = patch; + function patch(a, loose) { + return new SemVer(a, loose).patch; + } + + exports.compare = compare; + function compare(a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)); + } + + exports.compareLoose = compareLoose; + function compareLoose(a, b) { + return compare(a, b, true); + } + + exports.rcompare = rcompare; + function rcompare(a, b, loose) { + return compare(b, a, loose); + } + + exports.sort = sort; + function sort(list, loose) { + return list.sort(function(a, b) { + return exports.compare(a, b, loose); + }); + } + + exports.rsort = rsort; + function rsort(list, loose) { + return list.sort(function(a, b) { + return exports.rcompare(a, b, loose); + }); + } + + exports.gt = gt; + function gt(a, b, loose) { + return compare(a, b, loose) > 0; + } + + exports.lt = lt; + function lt(a, b, loose) { + return compare(a, b, loose) < 0; + } + + exports.eq = eq; + function eq(a, b, loose) { + return compare(a, b, loose) === 0; + } + + exports.neq = neq; + function neq(a, b, loose) { + return compare(a, b, loose) !== 0; + } + + exports.gte = gte; + function gte(a, b, loose) { + return compare(a, b, loose) >= 0; + } + + exports.lte = lte; + function lte(a, b, loose) { + return compare(a, b, loose) <= 0; + } + + exports.cmp = cmp; + function cmp(a, op, b, loose) { + var ret; + switch (op) { + case '===': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a === b; + break; + case '!==': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a !== b; + break; + case '': case '=': case '==': ret = eq(a, b, loose); break; + case '!=': ret = neq(a, b, loose); break; + case '>': ret = gt(a, b, loose); break; + case '>=': ret = gte(a, b, loose); break; + case '<': ret = lt(a, b, loose); break; + case '<=': ret = lte(a, b, loose); break; + default: throw new TypeError('Invalid operator: ' + op); + } + return ret; + } + + exports.Comparator = Comparator; + function Comparator(comp, loose) { + if (comp instanceof Comparator) { + if (comp.loose === loose) + return comp; + else + comp = comp.value; + } + + if (!(this instanceof Comparator)) + return new Comparator(comp, loose); + + debug('comparator', comp, loose); + this.loose = loose; + this.parse(comp); + + if (this.semver === ANY) + this.value = ''; + else + this.value = this.operator + this.semver.version; + + debug('comp', this); + } + + var ANY = {}; + Comparator.prototype.parse = function(comp) { + var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var m = comp.match(r); + + if (!m) + throw new TypeError('Invalid comparator: ' + comp); + + this.operator = m[1]; + if (this.operator === '=') + this.operator = ''; + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) + this.semver = ANY; + else + this.semver = new SemVer(m[2], this.loose); + }; + + Comparator.prototype.toString = function() { + return this.value; + }; + + Comparator.prototype.test = function(version) { + debug('Comparator.test', version, this.loose); + + if (this.semver === ANY) + return true; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + return cmp(version, this.operator, this.semver, this.loose); + }; + + Comparator.prototype.intersects = function(comp, loose) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required'); + } + + var rangeTmp; + + if (this.operator === '') { + rangeTmp = new Range(comp.value, loose); + return satisfies(this.value, rangeTmp, loose); + } else if (comp.operator === '') { + rangeTmp = new Range(this.value, loose); + return satisfies(comp.semver, rangeTmp, loose); + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>'); + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<'); + var sameSemVer = this.semver.version === comp.semver.version; + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<='); + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, loose) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')); + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, loose) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')); + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan; + }; + + + exports.Range = Range; + function Range(range, loose) { + if (range instanceof Range) { + if (range.loose === loose) { + return range; + } else { + return new Range(range.raw, loose); + } + } + + if (range instanceof Comparator) { + return new Range(range.value, loose); + } + + if (!(this instanceof Range)) + return new Range(range, loose); + + this.loose = loose; + + // First, split based on boolean or || + this.raw = range; + this.set = range.split(/\s*\|\|\s*/).map(function(range) { + return this.parseRange(range.trim()); + }, this).filter(function(c) { + // throw out any that are not relevant for whatever reason + return c.length; + }); + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range); + } + + this.format(); + } + + Range.prototype.format = function() { + this.range = this.set.map(function(comps) { + return comps.join(' ').trim(); + }).join('||').trim(); + return this.range; + }; + + Range.prototype.toString = function() { + return this.range; + }; + + Range.prototype.parseRange = function(range) { + var loose = this.loose; + range = range.trim(); + debug('range', range, loose); + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; + range = range.replace(hr, hyphenReplace); + debug('hyphen replace', range); + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range, re[COMPARATORTRIM]); + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace); + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + + // normalize spaces + range = range.split(/\s+/).join(' '); + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var set = range.split(' ').map(function(comp) { + return parseComparator(comp, loose); + }).join(' ').split(/\s+/); + if (this.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function(comp) { + return !!comp.match(compRe); + }); + } + set = set.map(function(comp) { + return new Comparator(comp, loose); + }); + + return set; + }; + + Range.prototype.intersects = function(range, loose) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required'); + } + + return this.set.some(function(thisComparators) { + return thisComparators.every(function(thisComparator) { + return range.set.some(function(rangeComparators) { + return rangeComparators.every(function(rangeComparator) { + return thisComparator.intersects(rangeComparator, loose); + }); + }); + }); + }); + }; + + // Mostly just for testing and legacy API reasons + exports.toComparators = toComparators; + function toComparators(range, loose) { + return new Range(range, loose).set.map(function(comp) { + return comp.map(function(c) { + return c.value; + }).join(' ').trim().split(' '); + }); + } + + // comprised of xranges, tildes, stars, and gtlt's at this point. + // already replaced the hyphen ranges + // turn into a set of JUST comparators. + function parseComparator(comp, loose) { + debug('comp', comp); + comp = replaceCarets(comp, loose); + debug('caret', comp); + comp = replaceTildes(comp, loose); + debug('tildes', comp); + comp = replaceXRanges(comp, loose); + debug('xrange', comp); + comp = replaceStars(comp, loose); + debug('stars', comp); + return comp; + } + + function isX(id) { + return !id || id.toLowerCase() === 'x' || id === '*'; + } + + // ~, ~> --> * (any, kinda silly) + // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 + // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 + // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 + // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 + // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 + function replaceTildes(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceTilde(comp, loose); + }).join(' '); + } + + function replaceTilde(comp, loose) { + var r = loose ? re[TILDELOOSE] : re[TILDE]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else if (pr) { + debug('replaceTilde pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + + debug('tilde return', ret); + return ret; + }); + } + + // ^ --> * (any, kinda silly) + // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 + // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 + // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 + // ^1.2.3 --> >=1.2.3 <2.0.0 + // ^1.2.0 --> >=1.2.0 <2.0.0 + function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); + } + + function replaceCaret(comp, loose) { + debug('caret', comp, loose); + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) { + if (M === '0') + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; + } else if (pr) { + debug('replaceCaret pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; } else - g = p ? p.targetduration : 0; - h = e.abrBandWidthUpFactor, - p = e.abrBandWidthFactor; - return m = Bg(o, g, d, u, f, t, s.getCombinedEstimate(), s.bandwidthStatus, p, h, e, i, r, n, a), - m.variantMediaOption === Ol.mediaOptionId && (m = Bg(o, g, d, u, f + xg(g, e.maxStarvationDelay), t, s.getCombinedEstimate(), s.bandwidthStatus, p, h, e, i, r, n, a), - m.variantMediaOption === Ol.mediaOptionId && 0 <= d && (m.variantMediaOption = o[d].mediaOptionId, - m.alternates = t ? null : Fg(o[d], i))), - m - } - function Fg(e, t) { - var i = t.enabledMediaOptionKeys - , r = i[ul.AltAudio] - , r = kl(r) ? t.mediaOptionListQueries[ul.AltAudio].getMatchingAlternate(r.mediaOptionId, e) : Ol - , i = i[ul.Subtitle]; - return { - altAudio: r, - subtitle: kl(i) ? t.mediaOptionListQueries[ul.Subtitle].getMatchingAlternate(i.mediaOptionId, e) : Ol + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0'; + } else { + debug('no pr'); + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0'; + } + + debug('caret return', ret); + return ret; + }); + } + + function replaceXRanges(comp, loose) { + debug('replaceXRanges', comp, loose); + return comp.split(/\s+/).map(function(comp) { + return replaceXRange(comp, loose); + }).join(' '); + } + + function replaceXRange(comp, loose) { + comp = comp.trim(); + var r = loose ? re[XRANGELOOSE] : re[XRANGE]; + return comp.replace(r, function(ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + var xM = isX(M); + var xm = xM || isX(m); + var xp = xm || isX(p); + var anyX = xp; + + if (gtlt === '=' && anyX) + gtlt = ''; + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0'; + } else { + // nothing is forbidden + ret = '*'; } + } else if (gtlt && anyX) { + // replace X with 0 + if (xm) + m = 0; + if (xp) + p = 0; + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>='; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else if (xp) { + m = +m + 1; + p = 0; + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<'; + if (xm) + M = +M + 1; + else + m = +m + 1; + } + + ret = gtlt + M + '.' + m + '.' + p; + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } + + debug('xRange return', ret); + + return ret; + }); + } + + // Because * is AND-ed with everything else in the comparator, + // and '' means "any version", just remove the *s entirely. + function replaceStars(comp, loose) { + debug('replaceStars', comp, loose); + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], ''); + } + + // This function is passed to string.replace(re[HYPHENRANGE]) + // M, m, patch, prerelease, build + // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 + // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do + // 1.2 - 3.4 => >=1.2.0 <3.5.0 + function hyphenReplace($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + + if (isX(fM)) + from = ''; + else if (isX(fm)) + from = '>=' + fM + '.0.0'; + else if (isX(fp)) + from = '>=' + fM + '.' + fm + '.0'; + else + from = '>=' + from; + + if (isX(tM)) + to = ''; + else if (isX(tm)) + to = '<' + (+tM + 1) + '.0.0'; + else if (isX(tp)) + to = '<' + tM + '.' + (+tm + 1) + '.0'; + else if (tpr) + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; + else + to = '<=' + to; + + return (from + ' ' + to).trim(); + } + + + // if ANY of the sets match ALL of its comparators, then pass + Range.prototype.test = function(version) { + if (!version) + return false; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version)) + return true; } - function Bg(i, r, n, e, s, a, o, d, t, l, u, c, h, p, f) { - "bandwidth-history-controller" !== u.abrBandwidthEstimator && f.warn(`Unsupported configuration: ${u.abrBandwidthEstimator} for ABR bandwidth estimator`); - const m = d.bandwidthSampleCount - , g = c.abrStatus - , y = p.maxBufferSize - , v = u.minTargetDurations || 1 - , S = c.mediaOptionListQueries[ul.Variant].mediaOptionListInfo.hasScore; - if (!i.length) - return { - variantMediaOption: Ol.mediaOptionId, - holdOffDuration: -1, - lowestCandidate: null + return false; + }; + + function testSet(set, version) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) + return false; + } + + if (version.prerelease.length) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (var i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === ANY) + continue; + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver; + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) + return true; + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false; + } + + return true; + } + + exports.satisfies = satisfies; + function satisfies(version, range, loose) { + try { + range = new Range(range, loose); + } catch (er) { + return false; + } + return range.test(version); + } + + exports.maxSatisfying = maxSatisfying; + function maxSatisfying(versions, range, loose) { + var max = null; + var maxSV = null; + try { + var rangeObj = new Range(range, loose); + } catch (er) { + return null; + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { // satisfies(v, range, loose) + if (!max || maxSV.compare(v) === -1) { // compare(max, v, true) + max = v; + maxSV = new SemVer(max, loose); + } + } + }); + return max; + } + + exports.minSatisfying = minSatisfying; + function minSatisfying(versions, range, loose) { + var min = null; + var minSV = null; + try { + var rangeObj = new Range(range, loose); + } catch (er) { + return null; + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { // satisfies(v, range, loose) + if (!min || minSV.compare(v) === 1) { // compare(min, v, true) + min = v; + minSV = new SemVer(min, loose); + } + } + }); + return min; + } + + exports.validRange = validRange; + function validRange(range, loose) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, loose).range || '*'; + } catch (er) { + return null; + } + } + + // Determine if version is less than all the versions possible in the range + exports.ltr = ltr; + function ltr(version, range, loose) { + return outside(version, range, '<', loose); + } + + // Determine if version is greater than all the versions possible in the range. + exports.gtr = gtr; + function gtr(version, range, loose) { + return outside(version, range, '>', loose); + } + + exports.outside = outside; + function outside(version, range, hilo, loose) { + version = new SemVer(version, loose); + range = new Range(range, loose); + + var gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case '>': + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = '>'; + ecomp = '>='; + break; + case '<': + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = '<'; + ecomp = '<='; + break; + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, loose)) { + return false; + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + + var high = null; + var low = null; + + comparators.forEach(function(comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0'); + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, loose)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, loose)) { + low = comparator; + } + }); + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false; + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false; + } + } + return true; + } + + exports.prerelease = prerelease; + function prerelease(version, loose) { + var parsed = parse(version, loose); + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null; + } + + exports.intersects = intersects; + function intersects(r1, r2, loose) { + r1 = new Range(r1, loose); + r2 = new Range(r2, loose); + return r1.intersects(r2) + } + + exports.coerce = coerce; + function coerce(version) { + if (version instanceof SemVer) + return version; + + if (typeof version !== 'string') + return null; + + var match = version.match(re[COERCE]); + + if (match == null) + return null; + + return parse((match[1] || '0') + '.' + (match[2] || '0') + '.' + (match[3] || '0')); + } + + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js"))); + + /***/ }), + + /***/ "./node_modules/webpack/buildin/harmony-module.js": + /*!*******************************************!*\ + !*** (webpack)/buildin/harmony-module.js ***! + \*******************************************/ + /*! no static exports found */ + /***/ (function(module, exports) { + + module.exports = function(originalModule) { + if (!originalModule.webpackPolyfill) { + var module = Object.create(originalModule); + // module.parent = undefined by default + if (!module.children) module.children = []; + Object.defineProperty(module, "loaded", { + enumerable: true, + get: function() { + return module.l; + } + }); + Object.defineProperty(module, "id", { + enumerable: true, + get: function() { + return module.i; + } + }); + Object.defineProperty(module, "exports", { + enumerable: true + }); + module.webpackPolyfill = 1; + } + return module; + }; + + + /***/ }), + + /***/ "./src/rtc_reporting/reporting_agent.ts": + /*!**********************************************!*\ + !*** ./src/rtc_reporting/reporting_agent.ts ***! + \**********************************************/ + /*! exports provided: default */ + /***/ (function(module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _reporting_reporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./reporting_reporter */ "./src/rtc_reporting/reporting_reporter.ts"); + /* harmony import */ var _reporting_event__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./reporting_event */ "./src/rtc_reporting/reporting_event.ts"); + /* harmony import */ var _reporting_storebag__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./reporting_storebag */ "./src/rtc_reporting/reporting_storebag.ts"); + /* harmony import */ var _reporting_config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./reporting_config */ "./src/rtc_reporting/reporting_config.ts"); + + + + const { RTCReportingStoreBag } = _reporting_storebag__WEBPACK_IMPORTED_MODULE_2__; + const ReportingVersion = '1'; + + class RTCObjectRef { + constructor(objectNotToDestroy = null) { + this._objectNotToDestroy = objectNotToDestroy; + this._objectToDestroy = null; + } + addInstantiatedObject(objectToDestroy) { + this._objectNotToDestroy = this._objectToDestroy = objectToDestroy; + } + get instance() { + return this._objectNotToDestroy; + } + destroy() { + if (this._objectToDestroy) { + this._objectToDestroy.destroy(); + } + this._objectNotToDestroy = this._objectNotToDestroy = null; + } + } + class RTCReportingAgent { + constructor(reportingConfig = {}) { + this._sessionInfo = {}; + this._reportingDisabled = false; + this.storebag = new RTCObjectRef(); + this.reporter = null; + this.reportingVersion = ReportingVersion; + this.fuzzFactor = 0; + this.sessionStartTime = 0; + this._initializeReportingAgent(reportingConfig); + } + destroy() { + this.endSession(); + } + get ReportingAllowed() { + return !(this._reportingDisabled); + } + static get version() { + return "0.1.36"; + } + issueReportingEvent(eventID, eventPayload, eventType = _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentEventTypes"].BatchEvent) { + let error = null; + if (this.ReportingAllowed && this.reporter) { + let event = new _reporting_event__WEBPACK_IMPORTED_MODULE_1__["RTCReportingEvent"](eventID, _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingSessionEventStatus"].EventStatusSessionBegin, eventPayload, this._FuzzFactor, eventType); + error = this.reporter.issueReportingEvent(event, this._sessionInfo); + } + else { + error = new _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingError"]('Reporting not allowed.'); + } + return error; + } + endSession() { + if (this.ReportingAllowed && this.reporter) { + this._issueSessionEndEvent(); + this.reporter.flushAllEvents(); + } + this._sessionInfo = null; + this.reporter = null; + this.storebag.destroy(); + this.storebag = null; + } + set SessionInfo(session_info) { + this._sessionInfo = session_info; + } + get SessionInfo() { + return this._sessionInfo; + } + get SessionID() { + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SessionID in this._sessionInfo) { + return this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SessionID]; + } + return ''; + } + get ClientName() { + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ClientName in this._sessionInfo) { + return this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ClientName]; + } + return ''; + } + get ServiceName() { + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceName in this._sessionInfo) { + return this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceName]; + } + return ''; + } + get _FuzzFactor() { + return this.fuzzFactor; + } + _initializeReportingAgent(reportingConfig) { + let clientName = null; + let serviceName = null; + let applicationName = ''; + let sender = null; + let deviceName = null; + let osVersion = null; + let storebagURL = null; + let reportingDisabled = false; + let startTime = (new Date()).getTime(); + let hlsEventEmitter = null; + let sessionID = null; + let userInfoDict = null; + let senderOSVersion = null; + let storeBag = null; + let senderServiceID = null; + let senderAltConfig = null; + let useHTTPHeaders = null; + if (!this._sessionInfo) { + this._sessionInfo = {}; + } + if (reportingConfig) { + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ClientName in reportingConfig) { + clientName = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ClientName]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceName in reportingConfig) { + serviceName = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceName]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ApplicationName in reportingConfig) { + applicationName = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ApplicationName]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].Sender in reportingConfig) { + sender = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].Sender]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].OSVersion in reportingConfig) { + osVersion = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].OSVersion]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].StorebagURL in reportingConfig) { + storebagURL = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].StorebagURL]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].DeviceName in reportingConfig) { + deviceName = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].DeviceName]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ReportingDisabled in reportingConfig) { + reportingDisabled = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ReportingDisabled]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].HLSEventEmitter in reportingConfig) { + hlsEventEmitter = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].HLSEventEmitter]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SessionID in reportingConfig) { + sessionID = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SessionID]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].UserInfoDict in reportingConfig) { + userInfoDict = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].UserInfoDict]; + if (userInfoDict && _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].SenderAltConfig in userInfoDict) { + senderAltConfig = userInfoDict[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].SenderAltConfig]; + delete userInfoDict[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].SenderAltConfig]; + if (senderAltConfig) { + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceIdentifier in senderAltConfig) { + senderServiceID = senderAltConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceIdentifier]; + } + if (Object.keys(senderAltConfig)) { + Object.assign(userInfoDict, senderAltConfig); + } + } + } + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SenderOSVersion in reportingConfig) { + senderOSVersion = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SenderOSVersion]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ReportingStoreBag in reportingConfig) { + storeBag = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ReportingStoreBag]; + } + if (_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].UseHTTPHeaders in reportingConfig) { + useHTTPHeaders = reportingConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].UseHTTPHeaders]; + } + } + if (!sessionID) { + sessionID = RTCReportingAgent._createSessionID(); + } + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ClientName] = clientName; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceName] = serviceName; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ApplicationName] = applicationName; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].DeviceName] = deviceName; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].OSVersion] = osVersion; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].Sender] = sender; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].RTCSchemeVersion] = this.reportingVersion; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].RTCReportingVersion] = RTCReportingAgent.version; + this._reportingDisabled = reportingDisabled; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SessionID] = sessionID; + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"].SenderOSVersion] = senderOSVersion; + if (applicationName && serviceName) { + serviceName = serviceName + '.' + applicationName; + } + if (senderServiceID && serviceName) { + serviceName = serviceName + '.' + senderServiceID; + } + this._sessionInfo[_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"].ServiceName] = serviceName; + this.fuzzFactor = startTime - Math.floor(startTime / 60000) * 60000; + this.sessionStartTime = startTime - this.fuzzFactor; + Object.keys(this._sessionInfo).forEach((key) => (this._sessionInfo[key] == null) && delete this._sessionInfo[key]); + if (userInfoDict && Object.keys(userInfoDict)) { + Object.assign(this._sessionInfo, userInfoDict); + } + if (this._reportingDisabled) { + return; + } + if (storeBag) { + this.storebag = new RTCObjectRef(storeBag); + } + else { + this.storebag.addInstantiatedObject(new RTCReportingStoreBag(storebagURL, clientName, serviceName, applicationName, deviceName, osVersion)); + } + this.reporter = new _reporting_reporter__WEBPACK_IMPORTED_MODULE_0__["RTCReporter"](clientName, serviceName, sender, this.storebag.instance, this.reportingVersion, hlsEventEmitter, applicationName, senderServiceID, useHTTPHeaders, sessionID); + console.log(_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentDefaultConfig"].LogMsgPrefix + 'Created reporting agent using rtc.js version ' + RTCReportingAgent.version); + this._issueSessionBeginEvent(); + } + _issueSessionBeginEvent() { + let event = new _reporting_event__WEBPACK_IMPORTED_MODULE_1__["RTCReportingEvent"](_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentMethods"].ReportingSessionMethod, _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingSessionEventStatus"].EventStatusSessionBegin, null, this._FuzzFactor, _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentEventTypes"].BatchEvent); + if (this.reporter && event) { + this.reporter.issueReportingEvent(event, this.SessionInfo); + } + } + _issueSessionEndEvent() { + let event = new _reporting_event__WEBPACK_IMPORTED_MODULE_1__["RTCReportingEvent"](_reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentMethods"].ReportingSessionMethod, _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingSessionEventStatus"].EventStatusSessionEnd, null, this._FuzzFactor, _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentEventTypes"].RealTimeEvent); + if (this.reporter) { + this.reporter.issueReportingEvent(event, this.SessionInfo); + } + } + static _createSessionID() { + let word0 = Math.random() * 0xffffffff | 0; + let word1 = Math.random() * 0xffffffff | 0; + let word2 = Math.random() * 0xffffffff | 0; + let word3 = Math.random() * 0xffffffff | 0; + const lastNibble = 0x0f; + const lastByte = 0xff; + const secondByteShift = 8; + const thirdByteShift = 16; + const fourthByteShift = 24; + const uuidVersion = 0x40; + const uuidVariant = 0x80; + const nByteMask = 0x3f; + let guid = []; + let radix = 16; + let guidLength = 256; + for (let i = 0; i < guidLength; ++i) { + guid[i] = (i < radix ? '0' : '') + (i).toString(radix); + } + return guid[word0 & lastByte] + guid[word0 >> secondByteShift & lastByte] + guid[word0 >> thirdByteShift & lastByte] + guid[word0 >> fourthByteShift & lastByte] + '-' + + guid[word1 & lastByte] + guid[word1 >> secondByteShift & lastByte] + '-' + + guid[word1 >> secondByteShift & lastNibble | uuidVersion] + guid[word1 >> thirdByteShift & lastByte] + '-' + + guid[word2 & nByteMask | uuidVariant] + guid[word2 >> secondByteShift & lastByte] + '-' + + guid[word2 >> secondByteShift & lastByte] + guid[word2 >> thirdByteShift & lastByte] + + guid[word3 & lastByte] + guid[word3 >> secondByteShift & lastByte] + guid[word3 >> thirdByteShift & lastByte] + guid[word3 >> fourthByteShift & lastByte]; + } + } + /* harmony default export */ __webpack_exports__["default"] = ({ + RTCReportingAgent, + RTCStorebag: _reporting_storebag__WEBPACK_IMPORTED_MODULE_2__, + RTCReportingAgentDefaultConfig: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentDefaultConfig"], + RTCReportingAgentConfigKeys: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentConfigKeys"], + RTCReportingAgentEventTypes: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingAgentEventTypes"], + RTCReportingHTTPHeaderDefault: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingHTTPHeaderDefault"], + RTCReportingHTTPHeaderKeys: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingHTTPHeaderKeys"], + RTCReportingEventMetadataKeys: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingEventMetadataKeys"], + RTC_REPORTING_EVENTS_DISPATCHED: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTC_REPORTING_EVENTS_DISPATCHED"], + RTCObjectRef, + RTCReportingStoreBagConfig: _reporting_config__WEBPACK_IMPORTED_MODULE_3__["RTCReportingStoreBagConfig"], + }); + + + /***/ }), + + /***/ "./src/rtc_reporting/reporting_config.ts": + /*!***********************************************!*\ + !*** ./src/rtc_reporting/reporting_config.ts ***! + \***********************************************/ + /*! exports provided: RTCReportingAgentDefaultConfig, RTCReportingAgentConfigKeys, RTCReportingAgentEventTypes, RTCReportingHTTPHeaderKeys, RTCReportingHTTPHeaderDefault, RTCReportingEventMetadataKeys, RTCReportingStoreBagConfig, RTCReportingReporterConfig, RTCReportingAgentMethods, RTCReportingSessionEventStatus, RTCReportingStoreBagKeys, RTCReportingError, RTCReportingBuildTypes, RTC_REPORTING_EVENTS_DISPATCHED */ + /***/ (function(module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingAgentDefaultConfig", function() { return RTCReportingAgentDefaultConfig; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingAgentConfigKeys", function() { return RTCReportingAgentConfigKeys; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingAgentEventTypes", function() { return RTCReportingAgentEventTypes; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingHTTPHeaderKeys", function() { return RTCReportingHTTPHeaderKeys; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingHTTPHeaderDefault", function() { return RTCReportingHTTPHeaderDefault; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingEventMetadataKeys", function() { return RTCReportingEventMetadataKeys; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingStoreBagConfig", function() { return RTCReportingStoreBagConfig; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingReporterConfig", function() { return RTCReportingReporterConfig; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingAgentMethods", function() { return RTCReportingAgentMethods; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingSessionEventStatus", function() { return RTCReportingSessionEventStatus; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingStoreBagKeys", function() { return RTCReportingStoreBagKeys; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingError", function() { return RTCReportingError; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingBuildTypes", function() { return RTCReportingBuildTypes; }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTC_REPORTING_EVENTS_DISPATCHED", function() { return RTC_REPORTING_EVENTS_DISPATCHED; }); + const RTCReportingHTTPHeaderKeys = { + ContentType: 'ContentType', + InternalBuild: 'X-RTC-Internal-Build', + ClientName: 'X-RTC-Client-Name', + ServiceName: 'X-RTC-Service-Name', + ClientVersion: 'X-RTC-Client-Version', + Sender: 'X-RTC-Sender', + UserAgent: 'User-Agent', + SessionID: 'X-RTC-Session-ID', + }; + const RTCReportingHTTPHeaderDefault = { + ContentTypekey: 'application/json;charset=UTF-8', + }; + const RTCReportingEventMetadataKeys = { + EventID: '_method', + EventType: '_eventType', + EventNumber: '_eventNumber', + EventTime: 'eventTime', + Sender: '_sender', + Status: '_status', + ClientTS: '_clientTS', + TimeZoneOffset: '_timezoneOffset', + PostTime: 'postTime', + Events: 'events', + SessionID: '_sessionID', + OSVersion: 'osVersion', + RTCReportingVersion: '_reportVers', + StoreBagVersion: 'StorebagVersion', + RTCSchemeVersion: '_reportScheme', + BagSchemeVersion: 'StorebagScheme', + StoreBagName: 'StorebagName', + SessionTag: 'SessionTag', + SenderOSVersion: 'SenderOSVersion', + }; + const RTCReportingAgentDefaultConfig = { + RunInlineIfNoWebWorker: true, + BatchEvent: true, + LogMsgPrefix: '[RTC_RA]: ', + }; + const RTCReportingAgentConfigKeys = { + ClientName: '_clientName', + ServiceName: '_serviceName', + StorebagURL: 'storebagURL', + ApplicationName: 'applicationName', + Sender: 'sender', + DeviceName: 'deviceName', + OSVersion: 'osVersion', + ReportingDisabled: 'reportingDisabled', + HLSEventEmitter: 'hlsEventEmitter', + BuildType: 'internal', + UserInfoDict: 'userInfoDict', + ReportingStoreBag: 'reportingStoreBag', + SenderAltConfig: 'senderAltConfig', + ServiceIdentifier: 'ServiceIdentifier', + UseHTTPHeaders: 'UseHTTPHeaders', + }; + const RTCReportingAgentEventTypes = { + BatchEvent: 0, + RealTimeEvent: 1, + }; + const RTCReportingAgentMethods = { + ReportingSessionMethod: 0, + }; + const RTCReportingStoreBagConfig = { + StoreBagFetchSyncMode: 0, + StoreBagFetchAsyncMode: 1, + StoreBagVersionSupported: 1, + }; + const RTCReportingReporterConfig = { + BatchThreshold: 50, + }; + const RTCReportingSessionEventStatus = { + EventStatusSessionBegin: 0, + EventStatusSessionEnd: 1, + EventStatusSessionEndWithError: 2, + }; + const RTCReportingStoreBagKeys = { + Version: 'Version', + Scheme: 'Scheme', + BagVersion: 'BagVersion', + Configurations: 'Configurations', + ConfigurationList: 'ConfigurationList', + PostURLs: 'PostURLs', + Filters: 'Filters', + BagList: 'BagList', + MinOSVersionDict: 'MinOSVersionDict', + ClientName: 'ClientName', + ServiceName: 'ServiceName', + ServiceNameList: 'ServiceNameList', + SenderServiceIDList: 'SenderServiceIDList', + ApplicationNameList: 'ApplicationNameList', + DeviceList: 'DeviceList', + Remove: 'Remove', + EventThreshold: 'EventThreshold', + SamplingThreshold: 'SamplingThreshold', + DeviceWhiteList: 'DeviceWhiteList', + FlushEventsInterval: 'FlushEventsInterval', + }; + const RTCReportingBuildTypes = { + BuildTypePublic: 0, + BuildTypeInternal: 1, + BuildTypeSeed: 2, + BuildTypeInternalSeed: 3 + }; + class RTCReportingError extends Error { + constructor(...args) { + super(...args); + Error.captureStackTrace(this, RTCReportingError); + } + } + const RTC_REPORTING_EVENTS_DISPATCHED = 'rtcReportingEventsDispatched'; + + + + /***/ }), + + /***/ "./src/rtc_reporting/reporting_event.ts": + /*!**********************************************!*\ + !*** ./src/rtc_reporting/reporting_event.ts ***! + \**********************************************/ + /*! exports provided: RTCReportingEvent */ + /***/ (function(module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingEvent", function() { return RTCReportingEvent; }); + /* harmony import */ var _reporting_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./reporting_config */ "./src/rtc_reporting/reporting_config.ts"); + + class RTCReportingEvent { + constructor(eventID, status = 0, eventPayload = {}, fuzzFactor = 0, eventType = _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingAgentEventTypes"].BatchEvent) { + this.payload = eventPayload ? eventPayload : {}; + this.payload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].EventID] = eventID; + this.payload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].Status] = status; + this.payload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].EventType] = eventType; + this.fuzzFactor = fuzzFactor; + this.isEventRealTime = (eventType === _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingAgentEventTypes"].RealTimeEvent); + this._addEventMetadata(); + } + prepareEventPayload(sessionInfo, sizeTillLastBatch, sizeOfLastBatch) { + Object.keys(sessionInfo).forEach(function (sessionInfoKey) { + this.payload[sessionInfoKey] = sessionInfo[sessionInfoKey]; + }.bind(this)); + if (this.isEventRealTime && sizeOfLastBatch && sizeTillLastBatch) { + this.payload.sizeOfLastBatch = sizeOfLastBatch; + this.payload.sizeTillLastBatch = sizeTillLastBatch; + } + } + get EventPayload() { + return this.payload; + } + get IsEventRealTime() { + return this.isEventRealTime; + } + _addEventMetadata() { + let date = new Date(); + this.payload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].EventTime] = (date.getTime()) / 1000; + this.payload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].TimeZoneOffset] = date.getTimezoneOffset() * 60; + } + } + + + + /***/ }), + + /***/ "./src/rtc_reporting/reporting_reporter.ts": + /*!*************************************************!*\ + !*** ./src/rtc_reporting/reporting_reporter.ts ***! + \*************************************************/ + /*! exports provided: RTCReporter */ + /***/ (function(module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + /* WEBPACK VAR INJECTION */(function(module) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReporter", function() { return RTCReporter; }); + /* harmony import */ var _reporting_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./reporting_config */ "./src/rtc_reporting/reporting_config.ts"); + + const ReportingContentType = 'application/json;charset=UTF-8'; + const ReportingVersion = 'RTCReportingJS/0.314'; + class EventDispatcher { + constructor(eventEmitter, sessionID, useHTTPHeaders = false) { + this._eventWriter = null; + this._sessionID = sessionID; + this._eventDispatcher = eventEmitter; + if (typeof navigator !== 'undefined' && navigator && (typeof navigator.sendBeacon !== 'undefined') && navigator.sendBeacon) { + this._eventWriter = this._sendEventDataWithHTTPPost; + } + else if ( this.module !== module) { + this._eventWriter = this._sendEventDataWithHTTPHeaders; + } + else { + this._eventWriter = this._sendEventDataWithHTTPPost; + } + if (useHTTPHeaders) { + this._eventWriter = this._sendEventDataWithHTTPHeaders; + } + } + sendEventData(url, eventDataAsJSON, clientName, serviceName, clientVersion, sender) { + if (this._eventWriter) { + this._eventWriter(url, eventDataAsJSON, clientName, serviceName, clientVersion, sender); + if (this._eventDispatcher) { + this._eventDispatcher.emit(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTC_REPORTING_EVENTS_DISPATCHED"], eventDataAsJSON); + } + } + } + _sendEventDataUsingBeacon(url, eventDataAsJSON, clientName, serviceName, clientVersion, sender) { + let headerJSON = this._createEventPayloadAsJSON(clientName, serviceName, clientVersion, sender); + let formData = new FormData(); + formData.append('headers', headerJSON); + formData.append('payload', eventDataAsJSON); + navigator.sendBeacon(url, formData); + } + _sendEventDataWithHTTPPost(url, eventDataAsJSON, clientName, serviceName, clientVersion, sender) { + let headerJSON = this._createEventPayloadAsJSON(clientName, serviceName, clientVersion, sender); + let formData = new FormData(); + formData.append('headers', headerJSON); + formData.append('payload', eventDataAsJSON); + let request = new XMLHttpRequest(); + const method = 'POST'; + const async = true; + request.open(method, url, async); + request.send(formData); + } + _createEventPayloadAsJSON(clientName, serviceName, clientVersion, sender) { + let header = {}; + header[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].InternalBuild] = 0; + header[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ClientName] = clientName; + header[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ServiceName] = serviceName; + header[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ClientVersion] = clientVersion; + header[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].Sender] = sender; + header[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ContentType] = 'application/json;charset=UTF-8'; + let headerJSON = JSON.stringify(header); + return headerJSON; + } + _sendEventDataWithHTTPHeaders(url, eventDataAsJSON, clientName, serviceName, clientVersion, sender) { + let request = new XMLHttpRequest(); + const method = 'POST'; + const async = true; + request.onload = function () { + }; + request.open(method, url, async); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ContentType, ReportingContentType); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].InternalBuild, '0'); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ClientName, clientName); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ServiceName, serviceName); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ClientVersion, clientVersion); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].Sender, sender); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].ClientVersion, ReportingVersion); + request.setRequestHeader(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingHTTPHeaderKeys"].SessionID, this._sessionID); + request.send(eventDataAsJSON); + } + } + class RTCReporter { + constructor(clientName, serviceName, sender, reportingStoreBag, clientVersion, hlsEventEmitter, applicationName = null, senderServiceID = null, useHTTPHeaders = false, sessionID = null) { + this.clientName = clientName; + this.serviceName = serviceName; + this.reportingStoreBag = reportingStoreBag; + this.sender = sender; + this.clientVersion = clientVersion; + this.eventList = []; + this._count = 0; + this._eventDispatcher = new EventDispatcher(hlsEventEmitter, sessionID, useHTTPHeaders); + this.sampleFactor = Math.random(); + this._storebagStats = {}; + this._canReport = undefined; + this._sizeTillLastBatch = this._sizeOfLastBatch = 0; + this.storeBag = null; + this.applicationName = applicationName; + this.senderServiceID = senderServiceID; + this.checkAndConfigureEventFlushTimeoutOnce = false; + } + issueReportingEvent(event, sessionInfo = {}) { + if (!event) { + return new _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingError"]('not a valid event to report'); + } + this._updateEventMetadata(event); + event.prepareEventPayload(sessionInfo, this._sizeTillLastBatch, this._sizeOfLastBatch); + this.eventList.push(event); + if (!this.checkAndConfigureEventFlushTimeoutOnce) { + if (this.canReportEvents()) { + this._configureEventFlushTimer(); + } + } + if ((this.eventList.length > _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingReporterConfig"].BatchThreshold) || event.IsEventRealTime) { + return this.flushAllEvents(); + } + return null; + } + canReportEvents() { + let sampleRate; + if (this._canReport !== undefined) { + return this._canReport; + } + if (this.reportingStoreBag && !this.storeBag) { + this.storeBag = this.reportingStoreBag.createParsedStoreBag(this.applicationName, this.senderServiceID); + if (!this.storeBag) { + return false; + } + } + if (this.storeBag && this.storeBag.IsValid) { + this._canReport = true; + sampleRate = this.storeBag.getStoreBagProperty(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].SamplingThreshold); + if (sampleRate && (parseFloat(sampleRate) < this.sampleFactor)) { + this._canReport = false; + } + } + else if (this.storeBag) { + console.log(`StoreBag for client ${this.clientName}, service ${this.serviceName}, app ${this.applicationName} senderService ${this.senderServiceID} not valid ${this.storeBag.IsValid} `); + } + if (this._canReport) { + this._storebagStats[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].SamplingThreshold] = sampleRate; + this._storebagStats[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].BagSchemeVersion] = this.storeBag.StoreBagSchemeVersion; + this._storebagStats[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].StoreBagVersion] = this.storeBag.StoreBagVersion; + this._storebagStats[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].StoreBagName] = this.storeBag.StoreBagName; + let bagMinVersionDict = this.storeBag.BagMinVersionDict; + if (typeof bagMinVersionDict === 'object' && bagMinVersionDict) { + for (let key in bagMinVersionDict) { + if (bagMinVersionDict.hasOwnProperty(key)) { + this._storebagStats[key] = bagMinVersionDict[key]; + } + } + } + } + console.log(`${_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingAgentDefaultConfig"].LogMsgPrefix} Event reporting is ${this._canReport} for client ${this.clientName} service ${this.serviceName}, app ${this.applicationName}, senderService ${this.senderServiceID}`); + return this._canReport; + } + flushEventTimeout() { + this.flushAllEvents(); + } + flushAllEvents() { + let error = null; + if (this.canReportEvents()) { + this._sendAllEvents(); + } + else { + error = new _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingError"]('no valid storebag configured or blocked by sampling threshold, ignoring events.'); + } + this.eventList = []; + return error; + } + batchedEventsCount() { + return this.eventList.length; + } + get _EventList() { + return this.eventList; + } + _updateEventMetadata(event) { + event.EventPayload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].EventNumber] = this._eventCounter(); + event.EventPayload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].ClientTS] = ((new Date()).getTime()) / 1000; + event.EventPayload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].Sender] = this.sender; + event.EventPayload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingAgentConfigKeys"].ClientName] = this.clientName; + event.EventPayload[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingAgentConfigKeys"].ServiceName] = this.serviceName; + } + _sendAllEvents() { + if (this.eventList.length === 0) { + return; + } + let backEnds = this.storeBag.listOfSupportedBackEnds(this.clientName, this.serviceName); + if (!backEnds || backEnds.length <= 0) { + return; + } + let blackListKeys = this.storeBag.listOfKeysToBlock(); + if (blackListKeys) { + this.eventList.forEach(function (event) { + event.prepareEventPayload(this._storebagStats, this._sizeTillLastBatch, this._sizeOfLastBatch); + blackListKeys.forEach(function (key) { + delete event.EventPayload[key]; + }); + }.bind(this)); + } + let eventData = this._marshallAsJSONString(); + this._sizeTillLastBatch += eventData.length; + this._sizeOfLastBatch = eventData.length; + backEnds.forEach(function (backEndURL) { + this._eventDispatcher.sendEventData(backEndURL, eventData, this.clientName, this.serviceName, this.clientVersion, this.sender); + }.bind(this)); + console.log(`${_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingAgentDefaultConfig"].LogMsgPrefix} events reported.`); + } + _marshallAsJSONString() { + let time = ((new Date()).getTime()) / 1000; + let postData = {}; + let events = []; + this.eventList.forEach(function (event) { + events.push(event.EventPayload); + }); + postData[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].PostTime] = time; + postData[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingEventMetadataKeys"].Events] = events; + let postBody = JSON.stringify(postData); + return postBody; + } + _eventCounter() { + return this._count++; + } + _configureEventFlushTimer() { + let flushTimeout = null; + this.checkAndConfigureEventFlushTimeoutOnce = true; + if (this.reportingStoreBag && !this.storeBag) { + this.storeBag = this.reportingStoreBag.createParsedStoreBag(this.applicationName, this.senderServiceID); + } + if (this.storeBag && this.storeBag.IsValid) { + flushTimeout = this.storeBag.getStoreBagProperty(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].FlushEventsInterval); + } + if (flushTimeout) { + flushTimeout = parseInt(flushTimeout, 10) * 1000; + if (flushTimeout >= 10000) { + setInterval(this.flushEventTimeout.bind(this), flushTimeout); + } + } + } + } + + + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/webpack/buildin/harmony-module.js */ "./node_modules/webpack/buildin/harmony-module.js")(module))); + + /***/ }), + + /***/ "./src/rtc_reporting/reporting_storebag.ts": + /*!*************************************************!*\ + !*** ./src/rtc_reporting/reporting_storebag.ts ***! + \*************************************************/ + /*! exports provided: RTCReportingStoreBag */ + /***/ (function(module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RTCReportingStoreBag", function() { return RTCReportingStoreBag; }); + /* harmony import */ var _reporting_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./reporting_config */ "./src/rtc_reporting/reporting_config.ts"); + /* harmony import */ var semver__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! semver */ "./node_modules/semver/semver.js"); + + + class RTCReportingParsedStoreBag { + constructor(storeBagConfig, selectedBagName, bagVersion, bagMinVersionDict) { + this.storeBagConfig = storeBagConfig; + this.selectedBagName = selectedBagName; + this.bagVersion = bagVersion; + this.bagMinVersionDict = bagMinVersionDict; + } + listOfSupportedBackEnds() { + return this.getStoreBagProperty(_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].PostURLs); + } + listOfKeysToBlock() { + if (!this.storeBagConfig) { + return null; + } + let filters = this.storeBagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].Filters]; + if (!filters) { + return null; + } + return filters[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].Remove]; + } + get IsValid() { + return Boolean(this.storeBagConfig); + } + get StoreBagName() { + return this.IsValid ? this.selectedBagName : null; + } + get StorebagVersion() { + return this.IsValid ? this.bagVersion : null; + } + get StoreBagSchemeVersion() { + return _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagConfig"].StoreBagVersionSupported; + } + get BagMinVersionDict() { + return this.bagMinVersionDict; + } + getStoreBagProperty(propertyKey) { + let propertyValue = null; + if (this.IsValid && propertyKey && propertyKey in this.storeBagConfig) { + propertyValue = this.storeBagConfig[propertyKey]; + } + return propertyValue; + } + } + class RTCReportingStoreBag { + constructor(storebagURL, clientName = null, serviceName = null, applicationName = null, deviceName = null, bagMinVersionDict = null, mode = _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagConfig"].StoreBagFetchAsyncMode, storebagAsJSON = null) { + this.storebagURL = storebagURL; + this.mode = mode; + this.storeBagConfig = null; + this.clientName = clientName; + this.serviceName = serviceName; + this.applicationName = applicationName; + this.deviceName = deviceName; + this.storebagLoader = null; + this.selectedBagName = null; + this.storebagAsJSON = storebagAsJSON; + this.bagVersion = null; + this.bagMinVersionDict = null; + if (typeof bagMinVersionDict === 'object') { + this.bagMinVersionDict = bagMinVersionDict; + } + this.fetchAndParseStoreBag(); + } + destroy() { + if (this.storebagLoader) { + this.storebagLoader.abort(); + this.storebagLoader = null; + } + } + fetchAndParseStoreBag() { + this._fetchStoreBag(); + } + createParsedStoreBag(applicationName = this.applicationName, senderServiceID = null) { + if (!this.storebagAsJSON) { + console.log('no bag available!'); + return null; + } + return this._parseAndReturnStoreBag(this.storebagAsJSON, applicationName, senderServiceID); + } + _checkbagMinVersion(bagMinVersionDict, currentVersionDict) { + if (bagMinVersionDict && currentVersionDict) { + for (let key in bagMinVersionDict) { + if (bagMinVersionDict.hasOwnProperty(key)) { + let bagMinVersion = bagMinVersionDict[key]; + if (currentVersionDict.hasOwnProperty(key)) { + let currentVersion = currentVersionDict[key]; + if (Object(semver__WEBPACK_IMPORTED_MODULE_1__["gte"])(currentVersion, bagMinVersion)) { + return true; + } + } + } + } + return false; + } + return true; + } + _parseAndReturnStoreBag(storebag, applicationName, senderServiceID) { + let selectedBag = null; + let selectedBagConfig = null; + let selectedBagConfigKey = null; + let selectedBagVersion = null; + storebag.forEach(function (bag) { + selectedBag = null; + if (bag[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].Scheme] === _reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagConfig"].StoreBagVersionSupported) { + let bagList = bag[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].BagList]; + Object.keys(bagList).some(function (bagConfigKey) { + let bagConfig = bagList[bagConfigKey]; + let bagMinVersionDict = bagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].MinOSVersionDict]; + if (!this._checkbagMinVersion(bagMinVersionDict, this.bagMinVersionDict)) { + console.log(`failed to match the version # `); + return false; + } + if (!this._canUseBagConfig(bagConfig, applicationName, senderServiceID)) { + return false; + } + selectedBag = bagConfig; + selectedBagConfigKey = bagConfigKey; + selectedBagVersion = bag[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].BagVersion]; + return false; + }.bind(this)); + } + if (selectedBag) { + selectedBagConfig = this._fillSelectedBagConfig(selectedBag, bag); + } + }.bind(this)); + if (!selectedBagConfig) { + console.log(`${_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingAgentDefaultConfig"].LogMsgPrefix} Failed to select a storebag.`); + } + return new RTCReportingParsedStoreBag(selectedBagConfig, selectedBagConfigKey, selectedBagVersion, this.bagMinVersionDict); + } + _fetchStoreBag() { + if (this.storebagURL && !this.storebagAsJSON) { + this._requestStoreBagAsync(); + } + } + _requestStoreBagAsync() { + this.storebagLoader = new XMLHttpRequest(); + this.storebagLoader.onreadystatechange = function () { + if (this.storebagLoader && this.storebagLoader.readyState === 4 && this.storebagLoader.status === 200 && this.storebagLoader.responseText) { + this.storebagAsJSON = JSON.parse(this.storebagLoader.responseText); + } + }.bind(this); + this.storebagLoader.open('GET', this.storebagURL, true); + this.storebagLoader.send(null); + } + _canUseBagConfig(bagConfig, applicationName, senderServiceID) { + let bagClientName = bagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].ClientName]; + if (bagClientName && bagClientName !== this.clientName) { + return false; + } + let bagServiceNameList = bagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].ServiceNameList]; + let bagServiceName = bagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].ServiceName]; + if (bagServiceNameList && bagServiceNameList.length > 0 && -1 === bagServiceNameList.indexOf(this.serviceName)) { + return false; + } + if (!bagServiceNameList && bagServiceName && bagServiceName !== this.serviceName) { + return false; + } + let bagApplicationNameList = bagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].ApplicationNameList]; + if (bagApplicationNameList && bagApplicationNameList.length > 0 && -1 === bagApplicationNameList.indexOf(applicationName)) { + return false; + } + let bagDeviceList = bagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].DeviceList]; + if (bagDeviceList && bagDeviceList.length > 0 && -1 === bagDeviceList.indexOf(this.deviceName)) { + return false; + } + let bagSenderServiceIDList = bagConfig[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].SenderServiceIDList]; + if (bagSenderServiceIDList && bagSenderServiceIDList.length > 0 && -1 === bagSenderServiceIDList.indexOf(senderServiceID)) { + return false; + } + return true; + } + _fillSelectedBagConfig(selectedBag, bag) { + let selectedBagConfig = null; + if (!selectedBag || !bag) { + return selectedBagConfig; + } + let configurationList = bag[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].ConfigurationList]; + let listOfConfigs = selectedBag[_reporting_config__WEBPACK_IMPORTED_MODULE_0__["RTCReportingStoreBagKeys"].Configurations]; + if (!listOfConfigs) { + return selectedBagConfig; + } + listOfConfigs.forEach(function (configName) { + let config = configurationList[configName]; + selectedBagConfig = selectedBagConfig ? selectedBagConfig : {}; + Object.assign(selectedBagConfig, config); + }); + return selectedBagConfig; + } + } + + + + /***/ }) + + /******/ })["default"]; + }); + + }(rtc)); + + var socket_io_min = {exports: {}}; + + /*! + * Socket.IO v4.0.2 + * (c) 2014-2021 Guillermo Rauch + * Released under the MIT License. + */ + + (function (module, exports) { + !function(t,e){module.exports=e();}(self,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r});},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0});},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=18)}([function(t,e,n){var r=n(24),o=n(25),i=String.fromCharCode(30);t.exports={protocol:4,encodePacket:r,encodePayload:function(t,e){var n=t.length,o=new Array(n),s=0;t.forEach((function(t,c){r(t,!1,(function(t){o[c]=t,++s===n&&e(o.join(i));}));}));},decodePacket:o,decodePayload:function(t,e){for(var n=t.split(i),r=[],s=0;s0;case l.ACK:case l.BINARY_ACK:return Array.isArray(e)}}}]),n}(h);e.Decoder=b;var m=function(){function t(e){u(this,t),this.packet=e,this.buffers=[],this.reconPack=e;}return p(t,[{key:"takeBinaryData",value:function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=y.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null}},{key:"finishedReconstruction",value:function(){this.reconPack=null,this.buffers=[];}}]),t}();},function(t,e){var n=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,r=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];t.exports=function(t){var e=t,o=t.indexOf("["),i=t.indexOf("]");-1!=o&&-1!=i&&(t=t.substring(0,o)+t.substring(o,i).replace(/:/g,";")+t.substring(i,t.length));for(var s,c,a=n.exec(t||""),u={},f=14;f--;)u[r[f]]=a[f]||"";return -1!=o&&-1!=i&&(u.source=e,u.host=u.host.substring(1,u.host.length-1).replace(/;/g,":"),u.authority=u.authority.replace("[","").replace("]","").replace(/;/g,":"),u.ipv6uri=!0),u.pathNames=function(t,e){var n=e.replace(/\/{2,9}/g,"/").split("/");"/"!=e.substr(0,1)&&0!==e.length||n.splice(0,1);"/"==e.substr(e.length-1,1)&&n.splice(n.length-1,1);return n}(0,u.path),u.queryKey=(s=u.query,c={},s.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,(function(t,e,n){e&&(c[e]=n);})),c),u};},function(t,e,n){function r(t){return (r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e){for(var n=0;n=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else {var n=this.backoff.duration();this._reconnecting=!0;var r=setTimeout((function(){e.skipReconnect||(t.emitReserved("reconnect_attempt",e.backoff.attempts),e.skipReconnect||e.open((function(n){n?(e._reconnecting=!1,e.reconnect(),t.emitReserved("reconnect_error",n)):e.onreconnect();})));}),n);this.opts.autoUnref&&r.unref(),this.subs.push((function(){clearTimeout(r);}));}}},{key:"onreconnect",value:function(){var t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t);}}])&&o(e.prototype,n),y}(n(17).StrictEventEmitter);e.Manager=y;},function(t,e,n){var r=n(9),o=n(23),i=n(27),s=n(28);e.polling=function(t){var e=!1,n=!1,s=!1!==t.jsonp;if("undefined"!=typeof location){var c="https:"===location.protocol,a=location.port;a||(a=c?443:80),e=t.hostname!==location.hostname||a!==t.port,n=t.secure!==c;}if(t.xdomain=e,t.xscheme=n,"open"in new r(t)&&!t.forceJSONP)return new o(t);if(!s)throw new Error("JSONP disabled");return new i(t)},e.websocket=s;},function(t,e,n){var r=n(22),o=n(2);t.exports=function(t){var e=t.xdomain,n=t.xscheme,i=t.enablesXDR;try{if("undefined"!=typeof XMLHttpRequest&&(!e||r))return new XMLHttpRequest}catch(t){}try{if("undefined"!=typeof XDomainRequest&&!n&&i)return new XDomainRequest}catch(t){}if(!e)try{return new(o[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}};},function(t,e,n){function r(t){return (r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var n=0;n0);return e}function u(){var t=a(+new Date);return t!==r?(s=0,r=t):t+"."+a(s++)}for(;c<64;c++)i[o[c]]=c;u.encode=a,u.decode=function(t){var e=0;for(c=0;c1?e-1:0),r=1;r=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,c=!0,a=!1;return {s:function(){n=t[Symbol.iterator]();},n:function(){var t=n.next();return c=t.done,t},e:function(t){a=!0,s=t;},f:function(){try{c||null==n.return||n.return();}finally{if(a)throw s}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n1?e-1:0),r=1;r1?n-1:0),o=1;o1?n-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2?arguments[2]:void 0,o=t;n=n||"undefined"!=typeof location&&location,null==t&&(t=n.protocol+"//"+n.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?n.protocol+t:n.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==n?n.protocol+"//"+t:"https://"+t),o=r(t)),o.port||(/^(http|ws)$/.test(o.protocol)?o.port="80":/^(http|ws)s$/.test(o.protocol)&&(o.port="443")),o.path=o.path||"/";var i=-1!==o.host.indexOf(":"),s=i?"["+o.host+"]":o.host;return o.id=o.protocol+"://"+s+":"+o.port+e,o.href=o.protocol+"://"+s+(n&&n.port===o.port?"":":"+o.port),o};},function(t,e,n){var r=n(21);t.exports=function(t,e){return new r(t,e)},t.exports.Socket=r,t.exports.protocol=r.protocol,t.exports.Transport=n(3),t.exports.transports=n(8),t.exports.parser=n(0);},function(t,e,n){function r(){return (r=Object.assign||function(t){for(var e=1;e1&&void 0!==arguments[1]?arguments[1]:{};return i(this,l),e=f.call(this),t&&"object"===o(t)&&(n=t,t=null),t?(t=y(t),n.hostname=t.host,n.secure="https"===t.protocol||"wss"===t.protocol,n.port=t.port,t.query&&(n.query=t.query)):n.host&&(n.hostname=y(n.host).host),e.secure=null!=n.secure?n.secure:"undefined"!=typeof location&&"https:"===location.protocol,n.hostname&&!n.port&&(n.port=e.secure?"443":"80"),e.hostname=n.hostname||("undefined"!=typeof location?location.hostname:"localhost"),e.port=n.port||("undefined"!=typeof location&&location.port?location.port:e.secure?443:80),e.transports=n.transports||["polling","websocket"],e.readyState="",e.writeBuffer=[],e.prevBufferLen=0,e.opts=r({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,jsonp:!0,timestampParam:"t",rememberUpgrade:!1,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{}},n),e.opts.path=e.opts.path.replace(/\/$/,"")+"/","string"==typeof e.opts.query&&(e.opts.query=d.decode(e.opts.query)),e.id=null,e.upgrades=null,e.pingInterval=null,e.pingTimeout=null,e.pingTimeoutTimer=null,"function"==typeof addEventListener&&(addEventListener("beforeunload",(function(){e.transport&&(e.transport.removeAllListeners(),e.transport.close());}),!1),"localhost"!==e.hostname&&(e.offlineEventListener=function(){e.onClose("transport close");},addEventListener("offline",e.offlineEventListener,!1))),e.open(),e}return e=l,(n=[{key:"createTransport",value:function(t){var e=function(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}(this.opts.query);e.EIO=h.protocol,e.transport=t,this.id&&(e.sid=this.id);var n=r({},this.opts.transportOptions[t],this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port});return new p[t](n)}},{key:"open",value:function(){var t;if(this.opts.rememberUpgrade&&l.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket"))t="websocket";else {if(0===this.transports.length){var e=this;return void setTimeout((function(){e.emit("error","No transports available");}),0)}t=this.transports[0];}this.readyState="opening";try{t=this.createTransport(t);}catch(t){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t);}},{key:"setTransport",value:function(t){var e=this;this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",(function(){e.onDrain();})).on("packet",(function(t){e.onPacket(t);})).on("error",(function(t){e.onError(t);})).on("close",(function(){e.onClose("transport close");}));}},{key:"probe",value:function(t){var e=this.createTransport(t,{probe:1}),n=!1,r=this;function o(){if(r.onlyBinaryUpgrades){var t=!this.supportsBinary&&r.transport.supportsBinary;n=n||t;}n||(e.send([{type:"ping",data:"probe"}]),e.once("packet",(function(t){if(!n)if("pong"===t.type&&"probe"===t.data){if(r.upgrading=!0,r.emit("upgrading",e),!e)return;l.priorWebsocketSuccess="websocket"===e.name,r.transport.pause((function(){n||"closed"!==r.readyState&&(f(),r.setTransport(e),e.send([{type:"upgrade"}]),r.emit("upgrade",e),e=null,r.upgrading=!1,r.flush());}));}else {var o=new Error("probe error");o.transport=e.name,r.emit("upgradeError",o);}})));}function i(){n||(n=!0,f(),e.close(),e=null);}function s(t){var n=new Error("probe error: "+t);n.transport=e.name,i(),r.emit("upgradeError",n);}function c(){s("transport closed");}function a(){s("socket closed");}function u(t){e&&t.name!==e.name&&i();}function f(){e.removeListener("open",o),e.removeListener("error",s),e.removeListener("close",c),r.removeListener("close",a),r.removeListener("upgrading",u);}l.priorWebsocketSuccess=!1,e.once("open",o),e.once("error",s),e.once("close",c),this.once("close",a),this.once("upgrading",u),e.open();}},{key:"onOpen",value:function(){if(this.readyState="open",l.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.opts.upgrade&&this.transport.pause)for(var t=0,e=this.upgrades.length;t0&&void 0!==arguments[0]?arguments[0]:{};return o(t,{xd:this.xd,xs:this.xs},this.opts),new w(this.uri(),t)}},{key:"doWrite",value:function(t,e){var n=this.request({method:"POST",data:t}),r=this;n.on("success",e),n.on("error",(function(t){r.onError("xhr post error",t);}));}},{key:"doPoll",value:function(){var t=this.request(),e=this;t.on("data",(function(t){e.onData(t);})),t.on("error",(function(t){e.onError("xhr poll error",t);})),this.pollXhr=t;}}]),n}(y),w=function(t){a(n,t);var e=f(n);function n(t,r){var o;return i(this,n),(o=e.call(this)).opts=r,o.method=r.method||"GET",o.uri=t,o.async=!1!==r.async,o.data=void 0!==r.data?r.data:null,o.create(),o}return c(n,[{key:"create",value:function(){var t=v(this.opts,"agent","enablesXDR","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");t.xdomain=!!this.opts.xd,t.xscheme=!!this.opts.xs;var e=this.xhr=new h(t),r=this;try{e.open(this.method,this.uri,this.async);try{if(this.opts.extraHeaders)for(var o in e.setDisableHeaderCheck&&e.setDisableHeaderCheck(!0),this.opts.extraHeaders)this.opts.extraHeaders.hasOwnProperty(o)&&e.setRequestHeader(o,this.opts.extraHeaders[o]);}catch(t){}if("POST"===this.method)try{e.setRequestHeader("Content-type","text/plain;charset=UTF-8");}catch(t){}try{e.setRequestHeader("Accept","*/*");}catch(t){}"withCredentials"in e&&(e.withCredentials=this.opts.withCredentials),this.opts.requestTimeout&&(e.timeout=this.opts.requestTimeout),this.hasXDR()?(e.onload=function(){r.onLoad();},e.onerror=function(){r.onError(e.responseText);}):e.onreadystatechange=function(){4===e.readyState&&(200===e.status||1223===e.status?r.onLoad():setTimeout((function(){r.onError("number"==typeof e.status?e.status:0);}),0));},e.send(this.data);}catch(t){return void setTimeout((function(){r.onError(t);}),0)}"undefined"!=typeof document&&(this.index=n.requestsCount++,n.requests[this.index]=this);}},{key:"onSuccess",value:function(){this.emit("success"),this.cleanup();}},{key:"onData",value:function(t){this.emit("data",t),this.onSuccess();}},{key:"onError",value:function(t){this.emit("error",t),this.cleanup(!0);}},{key:"cleanup",value:function(t){if(void 0!==this.xhr&&null!==this.xhr){if(this.hasXDR()?this.xhr.onload=this.xhr.onerror=m:this.xhr.onreadystatechange=m,t)try{this.xhr.abort();}catch(t){}"undefined"!=typeof document&&delete n.requests[this.index],this.xhr=null;}}},{key:"onLoad",value:function(){var t=this.xhr.responseText;null!==t&&this.onData(t);}},{key:"hasXDR",value:function(){return "undefined"!=typeof XDomainRequest&&!this.xs&&this.enablesXDR}},{key:"abort",value:function(){this.cleanup();}}]),n}(d);if(w.requestsCount=0,w.requests={},"undefined"!=typeof document)if("function"==typeof attachEvent)attachEvent("onunload",_);else if("function"==typeof addEventListener){addEventListener("onpagehide"in b?"pagehide":"unload",_,!1);}function _(){for(var t in w.requests)w.requests.hasOwnProperty(t)&&w.requests[t].abort();}t.exports=k,t.exports.Request=w;},function(t,e,n){var r=n(11).PACKET_TYPES,o="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),i="function"==typeof ArrayBuffer,s=function(t,e){var n=new FileReader;return n.onload=function(){var t=n.result.split(",")[1];e("b"+t);},n.readAsDataURL(t)};t.exports=function(t,e,n){var c,a=t.type,u=t.data;return o&&u instanceof Blob?e?n(u):s(u,n):i&&(u instanceof ArrayBuffer||(c=u,"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(c):c&&c.buffer instanceof ArrayBuffer))?e?n(u instanceof ArrayBuffer?u:u.buffer):s(new Blob([u]),n):n(r[a]+(u||""))};},function(t,e,n){var r,o=n(11),i=o.PACKET_TYPES_REVERSE,s=o.ERROR_PACKET;"function"==typeof ArrayBuffer&&(r=n(26));var c=function(t,e){if(r){var n=r.decode(t);return a(n,e)}return {base64:!0,data:t}},a=function(t,e){switch(e){case"blob":return t instanceof ArrayBuffer?new Blob([t]):t;case"arraybuffer":default:return t}};t.exports=function(t,e){if("string"!=typeof t)return {type:"message",data:a(t,e)};var n=t.charAt(0);return "b"===n?{type:"message",data:c(t.substring(1),e)}:i[n]?t.length>1?{type:i[n],data:t.substring(1)}:{type:i[n]}:s};},function(t,e){!function(t){e.encode=function(e){var n,r=new Uint8Array(e),o=r.length,i="";for(n=0;n>2],i+=t[(3&r[n])<<4|r[n+1]>>4],i+=t[(15&r[n+1])<<2|r[n+2]>>6],i+=t[63&r[n+2]];return o%3==2?i=i.substring(0,i.length-1)+"=":o%3==1&&(i=i.substring(0,i.length-2)+"=="),i},e.decode=function(e){var n,r,o,i,s,c=.75*e.length,a=e.length,u=0;"="===e[e.length-1]&&(c--,"="===e[e.length-2]&&c--);var f=new ArrayBuffer(c),p=new Uint8Array(f);for(n=0;n>4,p[u++]=(15&o)<<4|i>>2,p[u++]=(3&i)<<6|63&s;return f};}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");},function(t,e,n){function r(t){return (r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e){for(var n=0;n';n=document.createElement(t);}catch(t){(n=document.createElement("iframe")).name=r.iframeId,n.src="javascript:0";}n.id=r.iframeId,r.form.appendChild(n),r.iframe=n;}this.form.action=this.uri(),a(),t=t.replace(d,"\\\n"),this.area.value=t.replace(y,"\\n");try{this.form.submit();}catch(t){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===r.iframe.readyState&&c();}:this.iframe.onload=c;}},{key:"supportsBinary",get:function(){return !1}}])&&o(e.prototype,n),l}(l);t.exports=v;},function(t,e,n){function r(t){return (r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e){for(var n=0;n0&&t.jitter<=1?t.jitter:0,this.attempts=0;}t.exports=n,n.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n;}return 0|Math.min(t,this.max)},n.prototype.reset=function(){this.attempts=0;},n.prototype.setMin=function(t){this.ms=t;},n.prototype.setMax=function(t){this.max=t;},n.prototype.setJitter=function(t){this.jitter=t;};}])})); + + }(socket_io_min)); + + var lzString_min = {exports: {}}; + + (function (module) { + var LZString=function(){function o(o,r){if(!t[o]){t[o]={};for(var n=0;ne;e++){var s=r.charCodeAt(e);n[2*e]=s>>>8,n[2*e+1]=s%256;}return n},decompressFromUint8Array:function(o){if(null===o||void 0===o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;t>e;e++)n[e]=256*o[2*e]+o[2*e+1];var s=[];return n.forEach(function(o){s.push(r(o));}),i.decompress(s.join(""))},compressToEncodedURIComponent:function(o){return null==o?"":i._compress(o,6,function(o){return e.charAt(o)})},decompressFromEncodedURIComponent:function(r){return null==r?"":""==r?null:(r=r.replace(/ /g,"+"),i._decompress(r.length,32,function(n){return o(e,r.charAt(n))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(o,r,n){if(null==o)return "";var e,t,i,s={},p={},u="",c="",a="",l=2,f=3,h=2,d=[],m=0,v=0;for(i=0;ie;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;}else {for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a];}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++),s[c]=f++,a=String(u);}if(""!==a){if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;}else {for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a];}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++);}for(t=2,e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;for(;;){if(m<<=1,v==r-1){d.push(n(m));break}v++;}return d.join("")},decompress:function(o){return null==o?"":""==o?null:i._decompress(o.length,32768,function(r){return o.charCodeAt(r)})},_decompress:function(o,n,e){var i,s,p,u,c,a,l,f=[],h=4,d=4,m=3,v="",w=[],A={val:e(0),position:n,index:1};for(i=0;3>i;i+=1)f[i]=i;for(p=0,c=Math.pow(2,2),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 2:return ""}for(f[3]=l,s=l,w.push(l);;){if(A.index>o)return "";for(p=0,c=Math.pow(2,m),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(l=p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 2:return w.join("")}if(0==h&&(h=Math.pow(2,m),m++),f[l])v=f[l];else {if(l!==d)return null;v=s+s.charAt(0);}w.push(v),f[d++]=s+v.charAt(0),h--,s=v,0==h&&(h=Math.pow(2,m),m++);}}};return i}();null!=module&&(module.exports=LZString); + }(lzString_min)); + + var lzstring = lzString_min.exports; + + /** + * This file contains methods related to retrieving, storing and reading the logs + * from a remote server, it is used for QA only and all of them should not get + * included in the bundle when using production mode + */ + /** + * Logger utility methods used for debugging + * + * @param {store} store - A storage solution, either sessionStorage, localStorage, indexeddb, etc + * @constructor + */ + const LoggerExternals = (store = sessionStorage) => { + { + return { + /** + * Compress a string to take less space during transmission + * + * @param {string} string - The string to compress + * @returns {string} - The compressed string + */ + compress: (string) => { + return lzstring.compressToUTF16(string); + }, + /** + * Deletes the logs stored in the store + * + * @return {void} + */ + logClear: () => { + return store.clear(); + }, + /** + * Read the logs that were stored in the long term storage (compressed) + * + * @param {number} chunk - The chunk to read from the log file + * @param {number} chunkSize - The size of the chunk + * @return {string} + */ + logRead: (chunk = 0, chunkSize = LoggerExternals(store).logReadLength()) => { + const startPosition = chunk * chunkSize; + const endPosition = startPosition + chunkSize; + const log = []; + // Read each stored line until we read all the lines in a chunk + for (let i = startPosition; i <= endPosition; i += 1) { + const item = lzstring.decompress(store.getItem(String(i))); + if (item) + log.push(JSON.parse(item)); + } + return JSON.stringify(log); + }, + /** + * Read the size of the logs stored in the sessionStorage, used by the server to calculate + * chunk transmission size + * + * @return {number} + */ + logReadLength: () => { + return parseInt(store.getItem('logLength'), 10) || 0; + }, + /** + * Store logs in the storage mechanism for later retrieval + * + * @param {string} level - The console level (ex: info, warn, etc) + * @param {*} logEvent - The data + */ + logStore: (level, logEvent) => { + store.setItem('logLength', String(LoggerExternals(store).logReadLength() + 1)); + store.setItem(String(store.length), lzstring.compress(JSON.stringify(logEvent))); + }, + }; + } + }; + var LoggerExternals$1 = LoggerExternals; + + /** + * see https://tools.ietf.org/html/rfc1808 + * + * + * This file was modified by Apple Inc. + * Modifications Copyright (c) 2018- + * + * The initial developer is https://github.com/tjenkinson/url-toolkit. Copyright (c) 2016 Tom Jenkinson. + * + * Licensed under the Apache License, Version 2.0 (the Ãĸâ‚ŦœLicenseÃĸâ‚Ŧ); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an Ãĸâ‚ŦœAS ISÃĸâ‚Ŧ BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + const URL_REGEX = /^((?:[^\/;?#]+:)?)(\/\/[^\/\;?#]*)?(.*?)??(;.*?)?(\?.*?)?(#.*?)?$/; + const FIRST_SEGMENT_REGEX = /^([^\/;?#]*)(.*)$/; + const SLASH_DOT_REGEX = /(?:\/|^)\.(?=\/)/g; + const SLASH_DOT_DOT_REGEX = /(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g; + const URLToolkit = { + // jshint ignore:line + // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or // + // E.g + // With opts.alwaysNormalize = false (default, spec compliant) + // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g + // With opts.alwaysNormalize = true (default, not spec compliant) + // http://a.com/b/cd + /e/f/../g => http://a.com/e/g + buildAbsoluteURL: function (baseURL, relativeURL, opts) { + opts = opts || {}; + // remove any remaining space and CRLF + baseURL = baseURL.trim(); + relativeURL = relativeURL.trim(); + if (!relativeURL) { + // 2a) If the embedded URL is entirely empty, it inherits the + // entire base URL (i.e., is set equal to the base URL) + // and we are done. + if (!opts.alwaysNormalize) { + return baseURL; + } + const basePartsForNormalise = URLToolkit.parseURL(baseURL); + if (!basePartsForNormalise) { + throw new Error('Error trying to parse base URL.'); + } + basePartsForNormalise.path = URLToolkit.normalizePath(basePartsForNormalise.path); + return URLToolkit.buildURLFromParts(basePartsForNormalise); + } + const relativeParts = URLToolkit.parseURL(relativeURL); + if (!relativeParts) { + throw new Error('Error trying to parse relative URL.'); + } + if (relativeParts.scheme) { + // 2b) If the embedded URL starts with a scheme name, it is + // interpreted as an absolute URL and we are done. + if (!opts.alwaysNormalize) { + return relativeURL; + } + relativeParts.path = URLToolkit.normalizePath(relativeParts.path); + return URLToolkit.buildURLFromParts(relativeParts); + } + const baseParts = URLToolkit.parseURL(baseURL); + if (!baseParts) { + throw new Error('Error trying to parse base URL.'); + } + if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== '/') { + // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc + // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a' + const pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path); + baseParts.netLoc = pathParts[1]; + baseParts.path = pathParts[2]; + } + if (baseParts.netLoc && !baseParts.path) { + baseParts.path = '/'; + } + const builtParts = { + // 2c) Otherwise, the embedded URL inherits the scheme of + // the base URL. + scheme: baseParts.scheme, + netLoc: relativeParts.netLoc, + path: null, + params: relativeParts.params, + query: relativeParts.query, + fragment: relativeParts.fragment, + }; + if (!relativeParts.netLoc) { + // 3) If the embedded URL's is non-empty, we skip to + // Step 7. Otherwise, the embedded URL inherits the + // (if any) of the base URL. + builtParts.netLoc = baseParts.netLoc; + // 4) If the embedded URL path is preceded by a slash "/", the + // path is not relative and we skip to Step 7. + if (relativeParts.path[0] !== '/') { + if (!relativeParts.path) { + // 5) If the embedded URL path is empty (and not preceded by a + // slash), then the embedded URL inherits the base URL path + builtParts.path = baseParts.path; + // 5a) if the embedded URL's is non-empty, we skip to + // step 7; otherwise, it inherits the of the base + // URL (if any) and + if (!relativeParts.params) { + builtParts.params = baseParts.params; + // 5b) if the embedded URL's is non-empty, we skip to + // step 7; otherwise, it inherits the of the base + // URL (if any) and we skip to step 7. + if (!relativeParts.query) { + builtParts.query = baseParts.query; + } + } + } + else { + // Non-standard, allow non-empty paths to inherit the query + if (opts.inheritQuery) { + if (!relativeParts.query) { + builtParts.query = baseParts.query; + } + } + // 6) The last segment of the base URL's path (anything + // following the rightmost slash "/", or the entire path if no + // slash is present) is removed and the embedded URL's path is + // appended in its place. + const baseURLPath = baseParts.path; + const newPath = baseURLPath.substring(0, baseURLPath.lastIndexOf('/') + 1) + relativeParts.path; + builtParts.path = URLToolkit.normalizePath(newPath); + } + } + } + if (builtParts.path === null) { + builtParts.path = opts.alwaysNormalize ? URLToolkit.normalizePath(relativeParts.path) : relativeParts.path; + } + return URLToolkit.buildURLFromParts(builtParts); + }, + parseURL: function (url) { + const parts = URL_REGEX.exec(url); + if (!parts) { + return null; + } + return { + scheme: parts[1] || '', + netLoc: parts[2] || '', + path: parts[3] || '', + params: parts[4] || '', + query: parts[5] || '', + fragment: parts[6] || '', + }; + }, + normalizePath: function (path) { + // The following operations are + // then applied, in order, to the new path: + // 6a) All occurrences of "./", where "." is a complete path + // segment, are removed. + // 6b) If the path ends with "." as a complete path segment, + // that "." is removed. + path = path.split('').reverse().join('').replace(SLASH_DOT_REGEX, ''); + // 6c) All occurrences of "/../", where is a + // complete path segment not equal to "..", are removed. + // Removal of these path segments is performed iteratively, + // removing the leftmost matching pattern on each iteration, + // until no matching pattern remains. + // 6d) If the path ends with "/..", where is a + // complete path segment not equal to "..", that + // "/.." is removed. + while (path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, '')).length) { } // eslint-disable-line + return path.split('').reverse().join(''); + }, + buildURLFromParts: function (parts) { + return parts.scheme + parts.netLoc + parts.path + parts.params + parts.query + parts.fragment; + }, + getHostName: function (url) { + let hostname; + if (!url) { + return hostname; + } + if (url.indexOf('://') > -1) { + hostname = url.split('/')[2]; + } + else { + hostname = url.split('/')[0]; + } + // remove port and query if present + hostname = hostname.split(':')[0]; + hostname = hostname.split('?')[0]; + return hostname; + }, + }; + var URLToolkit$1 = URLToolkit; + + /** + * URL utils for hostname and other stuff + */ + function isCustomUrl(url) { + return url != null && !url.startsWith('http://') && !url.startsWith('https://'); + } + function getHostName(url) { + if (url == null) { + return null; + } + if (isCustomUrl(url)) { + return null; + } + return URLToolkit.getHostName(url); + } + const hostsRequiringQueries = ['.*.itunes.apple.com']; + const URLQueries = { + deviceName: '&xapdn=', + deviceModel: '&xapdm=', + language: '&xapdl=', + dsid: '&xapdsid=', + subs: '&xapsub=', + }; + function urlNeedsUpdate(url, enableQueryParamsForITunes) { + if (enableQueryParamsForITunes) { + const hostName = getHostName(url); + return (undefined !== + hostsRequiringQueries.find((regStr) => { + const regex = new RegExp(regStr); + return regex.exec(hostName); + })); + } + return false; + } + function shouldUpdateUrlWithDeviceNameAndModel(platformInfo) { + const deviceModel = platformInfo.model, deviceName = platformInfo.manufacturer; + if (!deviceModel || !deviceName) { + getLogger().warn(`Missing model/manufacturer in platformInfo model ${deviceModel} manufacturer ${deviceName}`); + } + return !!deviceModel && !!deviceName; + } + function updateUrlWithDeviceNameAndModel(url, platformInfo) { + const deviceModel = platformInfo.model, deviceName = platformInfo.manufacturer, urlHasQueryParams = url.indexOf('?') !== -1, deviceModelEnc = encodeURIComponent(deviceModel), deviceNameEnc = encodeURIComponent(deviceName); + url = urlHasQueryParams ? url : url + '?'; + return url + URLQueries.deviceName + deviceNameEnc + URLQueries.deviceModel + deviceModelEnc; + } + function updateUrlWithOptionsQuery(url, queryParameters) { + const urlHasQueryParams = url.indexOf('?') !== -1; + url = urlHasQueryParams ? url : url + '?'; + let query; + const logger = getLogger(); + for (query in queryParameters) { + if (!queryParameters[query]) { + logger.warn(`Missing ${query} info`); + } + else { + url += URLQueries[query] + (query === 'subs' ? encodeURIComponent(queryParameters[query]) : queryParameters[query]); + } + } + return url; + } + function updateUrlWithQueryStrings(url, platformInfo, queryParameters) { + if (shouldUpdateUrlWithDeviceNameAndModel(platformInfo)) { + url = updateUrlWithDeviceNameAndModel(url, platformInfo); + } + url = updateUrlWithOptionsQuery(url, queryParameters); + return url; + } + function hasMatchingHost(hostName, url) { + return !hostName || hostName === getHostName(url); + } + function isRedirectStatusCode(status) { + return status === 300 || status === 302 || status === 303 || status === 305; + } + /** + * Return all the GET parameters passed to a page + * This function is different from parseParamsFromURL(), + * where it just extracts all the parameters + * without trying to determine the correct type + * + * @param {string} href - The url to extract + * @param {array} exclude - A list of parameters to exclude from the list + * @return {object} - Key value pair with parameter name as key and value + */ + const getURLParams = (href, exclude = []) => { + const params = {}; + try { + const urlObject = new URL(href); + const urlSearch = urlObject.search; + const searchParams = new URLSearchParams(urlSearch); + for (const param of searchParams.entries()) { + if (!exclude.includes(param[0])) + params[param[0]] = param[1]; + } + } + catch (e) { + getLogger().error(e); + } + return params; + }; + function getTimeOffsetParameter(url) { + const paramString = URLToolkit.parseURL(url).fragment.substr(1); + if (paramString.length === 0) { + return null; + } + const searchParams = new URLSearchParams(paramString); + if (!searchParams.has('t')) { + return null; + } + const timeOffsetValue = Number(searchParams.get('t')); + if (isFiniteNumber(timeOffsetValue)) { + return timeOffsetValue; + } + return null; + } + /** + * Get specified parameters from the search query while + * trying to extract the correct type from each one. + * + * @param {array} extract - The list of parameters to extract + * @return {*} + */ + const parseParamsFromURL = (input, extract) => { + const url = new URL(input); + const params = url.searchParams; + const result = {}; + const getTypedParam = (name, defaultValue = undefined, json = false, transform) => { + const param = params.get(name); + let value; + switch (param) { + case 'undefined': + value = undefined; + break; + case 'null': + value = null; + break; + case 'False': + case 'false': + value = false; + break; + case 'True': + case 'true': + value = true; + break; + default: + if (param) { + const num = Number(param); + if (isFiniteNumber(num)) { + value = num; + } + else { + value = param; + } + } + break; + } + if (typeof value === 'string' && json) { + value = safeParseJSON(value); + } + if (typeof value === 'string' && transform) { + value = transform(value); + } + return value !== null && value !== void 0 ? value : defaultValue; + }; + extract.forEach((param) => { + result[param.name] = getTypedParam(param.name, param.default, param.json, param.transform); + }); + return result; + }; + /** + * Safely parse a json, prevent throwing an error on non-parseable input + * + * @param {string} data - Hopefully a JSON string + * @return {*} + */ + const safeParseJSON = (data) => { + let value; + if (typeof data !== 'string') + return data; + try { + value = JSON.parse(data); + } + catch (err) { + // eslint-disable-next-line no-console + console.error(`failed to parse param: ${data}`); + } + return value; + }; + /* + * Get a list of the dynamic range formats the user has selected + * + * Type 0: SDR + * Type 2: HDR10 + * Type 3: DV + * Type 4: HLG + * + * @returns {array} + */ + function getVideoDynamicRangeFormats(dynamicRangeFormatSDR, dynamicRangeFormatHDR10, dynamicRangeFormatDV, dynamicRangeFormatHLG, averageBitrateCap, peakBitrateCap, clearBitrateCap) { + const videoDynamicRangeFormats = [ + { type: 0, highestPlayableAverageBitRate: undefined, highestPlayablePeakBitRate: undefined }, + { type: 2, highestPlayableAverageBitRate: undefined, highestPlayablePeakBitRate: undefined }, + { type: 3, highestPlayableAverageBitRate: undefined, highestPlayablePeakBitRate: undefined }, + { type: 4, highestPlayableAverageBitRate: undefined, highestPlayablePeakBitRate: undefined }, + ]; + const videoDynamicRangeFormatsMap = { + 0: dynamicRangeFormatSDR, + 2: dynamicRangeFormatHDR10, + 3: dynamicRangeFormatDV, + 4: dynamicRangeFormatHLG, + }; + for (let formatIndex = 0; formatIndex < videoDynamicRangeFormats.length; ++formatIndex) { + videoDynamicRangeFormats[formatIndex].highestPlayableAverageBitRate = averageBitrateCap; + videoDynamicRangeFormats[formatIndex].highestPlayablePeakBitRate = peakBitrateCap; + videoDynamicRangeFormats[formatIndex].highestPlayablePeakBitRateForClearContent = clearBitrateCap; + } + return videoDynamicRangeFormats.filter(function (format) { + return !!videoDynamicRangeFormatsMap[format.type]; + }); + } + /* + * Get a list of the video codecs the user has selected + * + * Type 16: H264 + * Type 64: HEVC + * + * @returns {array} + */ + function getVideoCodecs(videoCodecH264, videoCodecHEVC, averageBitrateCap, peakBitrateCap) { + const videoCodecs = [ + { type: 16, highestPlayableAverageBitRate: undefined, highestPlayablePeakBitRate: undefined }, + { type: 64, highestPlayableAverageBitRate: undefined, highestPlayablePeakBitRate: undefined }, + ]; + const videoCodecsMap = { 16: videoCodecH264, 64: videoCodecHEVC }; + for (let formatIndex = 0; formatIndex < videoCodecs.length; ++formatIndex) { + videoCodecs[formatIndex].highestPlayableAverageBitRate = averageBitrateCap; + videoCodecs[formatIndex].highestPlayablePeakBitRate = peakBitrateCap; + } + return videoCodecs.filter(function (format) { + return !!videoCodecsMap[format.type]; + }); + } + + class AutomationRemote { + constructor() { + this.onStop$ = new Subject(); + this._logger = console; + this._playbackData = { + audio: [], + subtitles: [], + variants: [], + }; + this._timers$ = { + cpu: undefined, + memory: undefined, + system: undefined, + }; + /** + * Register the current parameters or player configuration + * This is used to check if the sockets from the automation server + * are requesting the page to be reloaded + * or the server is trying to load another player url + * + * @param {object} config - The list of GET parameters passed to the URL or other configuration values + * @return {void} + */ + this.setConfig = (config = {}) => { + this._config = JSON.stringify(config); + }; + /** + * Trigger a socket command back to the server to perform backend tasks + * + * @return {void} + */ + this.triggerSocketCommand = (command) => { + if (!command) + throw new Error('No command value was passed'); + this.socket.emit('action', { + type: 'SOCKETS/TRIGGER_CONTROL_SSH', + command, + }); + }; + } + /** + * Do setup/teardown if needed on hls change + * + * @param {object} hls + * @setter + * @return {void} + */ + setHls(hls) { + if (!hls) { + this.onStop$.next(); + this._hls = null; + this._playbackData = { + audio: [], + subtitles: [], + variants: [], + }; + return; + } + this._hls = hls; + this._hls.altAudioOptions$ + .pipe(tap((altAudioOptions) => (this._playbackData.audio = altAudioOptions)), takeUntil(this.onStop$)) + .subscribe(); + this._hls.subtitleOptions$ + .pipe(tap((subtitleOptions) => (this._playbackData.subtitles = subtitleOptions)), takeUntil(this.onStop$)) + .subscribe(); + this._hls.variantOptions$ + .pipe(tap((variantOptions) => (this._playbackData.variants = variantOptions)), takeUntil(this.onStop$)) + .subscribe(); + } + /** + * Set the logger instance + * + * @param {object} logger + * @setter + * @return {void} + */ + setLogger(logger) { + this._logger = logger; + } + /** + * Execute a function that matches the command name + * + * @param {string} command - The function name (ex: seek) + * @param {string} value - The value to pass to the function (ex: 1000) + * @return {*} + */ + applyCommand(command, value) { + if (typeof this[command] === 'function') { + try { + return this[command](value) || true; // Always return a value for the socket server to know we responded + } + catch (e) { + this._logger.error(e); + } + } + } + respondToSocketAction(data, callback) { + const loggerExternals = LoggerExternals$1(); + this._logger.qe({ critical: true, name: 'interact', data }); + if (!this._hls) { + return this._logger.warn(`hls object not initialized while trying to execute ${data.command}`); + } + switch (data.command) { + case 'cpu': + this._logger.qe({ critical: true, name: 'cpu', data: replaceAll('\n', ' | ', data.value) }); + break; + case 'free-memory': + this._logger.qe({ critical: true, name: 'freeMemory', data: replaceAll('\n', ' | ', data.value) }); + break; + case 'log-clear': + callback(loggerExternals.logClear()); + break; + case 'log-end': + //callback(utils.logEnd()); + break; + case 'log-read': + callback({ chunk: data.chunk, log: loggerExternals.compress(loggerExternals.logRead(data.chunk, data.chunkSize)) }); + break; + case 'log-read-length': + callback({ size: loggerExternals.logReadLength(), format: 'array' }); + break; + case 'log-start': + //callback(Utils.logStart()); + break; + case 'memory': + this._logger.qe({ critical: true, name: 'memory', data: getJSMemory() }); + break; + case 'access-log': + this._logger.qe({ critical: true, name: 'accessLog', data: { accessLogItems: this._hls.accessLog } }); + break; + case 'error-log': + this._logger.qe({ critical: true, name: 'errorLog', data: { errorLogItems: this._hls.errorLog } }); + break; + default: + callback(this.applyCommand(data.command, data.value)); + } + } + /** + * Connect to a remote socket.io server + * + * @return {object} + */ + initializeSocketService(socketurl, socketid) { + if (!socketurl) + throw new Error('Attempted to call logConnect() without a socket URL'); + if (!socketid) + throw new Error('Attempted to call logConnect() without a socket ID'); + this.socket = socket_io_min.exports.io(socketurl, { query: { ip: socketid } }); + this._logger.info(`Connecting socket service with server: ${socketurl} and id: ${socketid}`); + this.socket.on('connect', () => this._logger.info(`Connected to: ${socketurl}`)); + this.socket.on('disconnect', () => this._logger.info(`Disonnected from: ${socketurl}`)); + this.socket.on('error', (e) => this._logger.error(e)); + this.socket.on('action', this.respondToSocketAction.bind(this)); + } + /** + * Load a playlist + * + * @param {object} data - Server object containing data needed for playback + * @param {object} options + * @param {number} initialSeekTime + * @return {void} + */ + loadURL(data, options = {}, initialSeekTime = 0) { + var _a; + const pageUrl = data.fullURL || location.href; + const params = parseParamsFromURL(pageUrl, [ + { name: 'averageBitrateCap' }, + { name: 'dynamicRangeFormatSDR', default: true }, + { name: 'dynamicRangeFormatHDR10', default: true }, + { name: 'dynamicRangeFormatDV', default: true }, + { name: 'dynamicRangeFormatHLG', default: true }, + { name: 'maxHdcpLevel', default: 'TYPE-2', transform: decodeURIComponent }, + { name: 'maxSecurityLevel', transform: decodeURIComponent }, + { name: 'peakBitrateCap' }, + { name: 'requiresCDMAttachOnStart', default: false, json: true }, + { name: 'src' }, + { name: 'rand' }, + { name: 'videoCodecH264', default: false }, + { name: 'videoCodecHEVC', default: false }, + ]); + // Reload if the server requests a different player + if (this._config !== JSON.stringify(getURLParams(pageUrl, ['src', 'rand'])) && !((_a = getURLParams(location === null || location === void 0 ? void 0 : location.href)) === null || _a === void 0 ? void 0 : _a.dev)) { + location.href = pageUrl; + return; + } + const platformInfo = { + videoDynamicRangeFormats: getVideoDynamicRangeFormats(params.dynamicRangeFormatSDR, params.dynamicRangeFormatHDR10, params.dynamicRangeFormatDV, params.dynamicRangeFormatHLG, params.averageBitrateCap, params.peakBitrateCap, params.clearBitrateCap), + videoCodecs: getVideoCodecs(params.videoCodecH264, params.videoCodecHEVC, params.averageBitrateCap, params.peakBitrateCap), + requiresCDMAttachOnStart: params.requiresCDMAttachOnStart, + maxHdcpLevel: params.maxHdcpLevel, + maxSecurityLevel: params.maxSecurityLevel, + }; + const storebag_url = 'https://mediaservices.cdn-apple.com/store_bags/hlsjs_qa/v1/rtc_storebag.json'; + const reportingStorebag = new rtc.exports.RTCStorebag.RTCReportingStoreBag(storebag_url, 'HLSJSDemoPlayer', 'com.apple.hlsjs.demo', 'DemoPage', '', 1, 0); + const reportingAgent = new rtc.exports.RTCReportingAgent({ + sender: 'HLSJS', + _clientName: 'HLSJSDemoPlayer', + _serviceName: 'com.apple.hlsjs.demo', + reportingStoreBag: reportingStorebag, + applicationName: 'DemoPage', + }); + const copyOptions = Object.assign({ appData: { clientName: 'HLSJSDemoPlayer', serviceName: 'com.apple.hlsjs.demo', appName: 'DemoPage', reportingAgent: reportingAgent }, userInfo: { internalBuild: true }, platformInfo }, options); + this._hls.loadSource(data.url, copyOptions, initialSeekTime); + } + /** + * Start playback if video is not detached + */ + play() { + this._hls.desiredRate = 1; + } + /** + * Set the scrubbing speed + * + * @param {number|string} rate + */ + playbackRate(rate) { + this._hls.setRate(rate); + } + /** + * Pause playback + */ + pause() { + this._hls.desiredRate = 0; + } + /** + * Reload page + */ + reload() { + window.location.reload(); + } + /** + * Seek to a time value + * + * @param {number} time - Seek position + */ + seekTo(time) { + this._hls.seekTo = time; + } + /** + * Seek to a date + * + * @param {Date} date - Seek position + */ + seekToDate(date) { + this._hls.seekToDate(date); + } + /** + * Set the current audio + * + * @param {string} lang (ex: French) + */ + setAudio(lang) { + const mediaOption = this._playbackData.audio.find((option) => { + return option.MediaSelectionOptionsExtendedLanguageTag === lang || option.MediaSelectionOptionsName === lang; + }) || {}; + this._hls.audioSelectedPersistentID = mediaOption.MediaSelectionOptionsPersistentID; + } + /** + * Set the current caption given a language + * + * @param {string} lang (ex: fr) + */ + setCaption(lang) { + const mediaOption = this._playbackData.subtitles.find((option) => { + return option.MediaSelectionOptionsExtendedLanguageTag === lang || option.MediaSelectionOptionsName === lang; + }) || {}; + this._hls.subtitleSelectedPersistentID = mediaOption.MediaSelectionOptionsPersistentID; + } + /** + * Start a timer tied to the lifecycle of this class + * that will request a cpu value from the server + * + * @param schedule The periodicity of the timer + * @public + */ + setTimerCpu(schedule = 2000) { + if (this._timers$.cpu) + return; + this._timers$.cpu = timer(200, schedule) + .pipe(tap(() => { + this.triggerSocketCommand('cpu'); + }), takeUntil(this.onStop$)) + .subscribe(); + return this._timers$.cpu; + } + /** + * Start a timer tied to the lifecycle of this class + * that will request the JS memory + * + * @param schedule The periodicity of the timer + * @public + */ + setTimerJSMemory(schedule = 2000) { + if (this._timers$.memory) + return; + this._timers$.memory = timer(200, schedule) + .pipe(tap(() => { + const { jsHeapSizeLimit, totalJSHeapSize, usedJSHeapSize } = getJSMemory(); + this._logger.qe({ critical: true, name: 'memory', data: { jsHeapSizeLimit, totalJSHeapSize, usedJSHeapSize } }); + }), takeUntil(this.onStop$)) + .subscribe(); + return this._timers$.memory; + } + /** + * Start a timer tied to the lifecycle of this class + * that will request the system memory (RAM) value from the server + * + * @param schedule The periodicity of the timer + * @public + */ + setTimerSystemMemory(schedule = 2000) { + if (this._timers$.system) + return; + this._timers$.system = timer(200, schedule) + .pipe(tap(() => { + this.triggerSocketCommand('free-memory'); + }), takeUntil(this.onStop$)) + .subscribe(); + return this._timers$.system; + } + /** + * Trigger onStop observable + * + * @return {void} + */ + stop() { + if (!this._hls) + return; + this.onStop$.next(); + } + } + let remote; + /** + * Get the JS memory if supported by the browser, otherwise return defaults + * + * @return {object} + */ + const getJSMemory = () => { + const defaultMemory = { + usedJSHeapSize: 0, + jsHeapSizeLimit: 0, + }; + const performance = window.performance || {}; + return performance.memory || defaultMemory; + }; + /** + * Create an automation instance singleton. + * + * @param socketurl The socket server URL + * @param socketid The socket identifier + */ + function initialize(socketurl, socketid) { + if (socketurl && socketid) { + if (!remote) { + remote = new AutomationRemote(); + remote.initializeSocketService(socketurl, socketid); + } + return remote; + } + } + /** + * Set the hls instance on the automation remote + */ + function setHls(hls) { + remote === null || remote === void 0 ? void 0 : remote.setHls(hls); + } + /** + * Set the logger instance + */ + function setLogger(logger) { + remote === null || remote === void 0 ? void 0 : remote.setLogger(logger); + } + + var VideoCodecRank; + (function (VideoCodecRank) { + VideoCodecRank[VideoCodecRank["DOVI"] = 4] = "DOVI"; + VideoCodecRank[VideoCodecRank["HEVC"] = 3] = "HEVC"; + VideoCodecRank[VideoCodecRank["VP09"] = 2] = "VP09"; + VideoCodecRank[VideoCodecRank["AVC"] = 1] = "AVC"; + VideoCodecRank[VideoCodecRank["UNKNOWN"] = 0] = "UNKNOWN"; + })(VideoCodecRank || (VideoCodecRank = {})); + var VideoRangeRank; + (function (VideoRangeRank) { + VideoRangeRank[VideoRangeRank["PQ"] = 3] = "PQ"; + VideoRangeRank[VideoRangeRank["HLG"] = 2] = "HLG"; + VideoRangeRank[VideoRangeRank["SDR"] = 1] = "SDR"; + VideoRangeRank[VideoRangeRank["UNKNOWN"] = 0] = "UNKNOWN"; + })(VideoRangeRank || (VideoRangeRank = {})); + var AudioCodecRank; + (function (AudioCodecRank) { + AudioCodecRank[AudioCodecRank["ALAC"] = 7] = "ALAC"; + AudioCodecRank[AudioCodecRank["FLAC"] = 6] = "FLAC"; + AudioCodecRank[AudioCodecRank["EC3"] = 5] = "EC3"; + AudioCodecRank[AudioCodecRank["AC3"] = 4] = "AC3"; + AudioCodecRank[AudioCodecRank["XHEAAC"] = 3] = "XHEAAC"; + AudioCodecRank[AudioCodecRank["AAC"] = 2] = "AAC"; + AudioCodecRank[AudioCodecRank["MP3"] = 1] = "MP3"; + AudioCodecRank[AudioCodecRank["UNKNOWN"] = 0] = "UNKNOWN"; + })(AudioCodecRank || (AudioCodecRank = {})); + var MatchRanking; + (function (MatchRanking) { + MatchRanking[MatchRanking["VALID"] = 1] = "VALID"; + MatchRanking[MatchRanking["INVALID"] = 0] = "INVALID"; + })(MatchRanking || (MatchRanking = {})); + + + // List of privacy allowed config headers for ServerInfo + // Headers need to be approved by Privacy. Here is a sample radar on how to request approval + // rdar://78172175 + const privacyAllowedLoadConfigHeaders = ['via', 'x-apple-request-uuid']; + const defaultManifestLoadPolicy = () => ({ + default: { + // Overall request configs + maxTimeToFirstByteMs: 10000, + maxLoadTimeMs: 20000, + autoRetry: false, + // Retries: + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0, // Maximum delay between retries + }, + errorRetry: { + maxNumRetry: 1, + retryDelayMs: 1000, + maxRetryDelayMs: 8000, // Maximum delay between retries + }, + }, + customURL: { + // Overall request configs + maxTimeToFirstByteMs: 10000, + maxLoadTimeMs: 10000, + autoRetry: false, + // Retries: + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0, // Maximum delay between retries + }, + errorRetry: { + maxNumRetry: 1, + retryDelayMs: 1000, + maxRetryDelayMs: 8000, // Maximum delay between retries + }, + }, + }); + const fragTimeoutRetryDefaultConfig = { + // Timeout Retries default value + maxNumRetry: 4, + retryDelayMs: 0, + maxRetryDelayMs: 0, // Maximum delay between retries + }; + const fragErrorRetryDefaultConfig = { + // Error Retries default value + maxNumRetry: 6, + retryDelayMs: 1000, + maxRetryDelayMs: 8000, // Maximum delay between retries + }; + const defaultSessionDataAutoLoad = { + 'com.apple.hls.chapters': true, + }; + const defaultCertRetry = { + maxNumRetry: 0, + retryDelayMs: 0, + maxRetryDelayMs: 0, // Maximum delay between retries + }; + const defaultCertLoadPolicy = { + default: { + maxTimeToFirstByteMs: 5000, + maxLoadTimeMs: 20000, + autoRetry: false, + timeoutRetry: defaultCertRetry, + errorRetry: defaultCertRetry, + }, + customURL: { + maxTimeToFirstByteMs: 10000, + maxLoadTimeMs: 20000, + autoRetry: false, + timeoutRetry: defaultCertRetry, + errorRetry: defaultCertRetry, + }, + }; + // max overall load time should be ~30s ish + const defaultKeyRetry = { + maxNumRetry: 8, + retryDelayMs: 1000, + maxRetryDelayMs: 20000, + backoff: 'linear', + }; + const timeoutKeyRetry = Object.assign(Object.assign({}, defaultKeyRetry), { maxNumRetry: 1 }); + const defaultKeyLoadPolicy = { + default: { + maxTimeToFirstByteMs: 5000, + maxLoadTimeMs: 20000, + autoRetry: false, + timeoutRetry: timeoutKeyRetry, + errorRetry: defaultKeyRetry, + }, + customURL: { + maxTimeToFirstByteMs: 10000, + maxLoadTimeMs: 20000, + autoRetry: false, + timeoutRetry: timeoutKeyRetry, + errorRetry: defaultKeyRetry, + }, + }; + const defaultTrickPlaybackConfig = { + enabled: true, + minIframeDuration: 8, + }; + const hlsDefaultConfig = { + autoStartLoad: true, + startPosition: NaN, + defaultAudioCodec: void 0, + defaultVideoCodec: void 0, + debug: false, + debugLevel: 'info', + buildType: void 0, + minFramesBeforeSwitchingLevel: 11, + minTargetDurations: 3, + maxBufferLength: 60, + maxBufferHole: 0.5, + maxSeekHole: 2, + nudgeFromEventSeek: true, + jaggedSeekTolerance: 0, + discontinuitySeekTolerance: 2, + bufferedSegmentEjectionToleranceMs: 0.5, + almostDryBufferSec: 0.5, + maxTotalDurationTolerance: 0.1, + lowBufferThreshold: 0.5, + lowBufferWatchdogPeriod: 0.5, + highBufferWatchdogPeriod: 3, + seekWatchdogPeriod: 5, + nudgeOffset: 0.1, + nudgeMaxRetry: 3, + maxFragLookUpTolerance: 0.2, + initialLiveManifestSize: 1, + liveSyncDurationCount: 3, + liveMaxLatencyDurationCount: Infinity, + liveSyncDuration: void 0, + liveMaxLatencyDuration: void 0, + liveFlushExpiredFrags: true, + liveMaxUnchangedPlaylistRefresh: 3, + liveEdgeForZeroStartPositon: false, + livePlaylistUpdateStaleness: 2, + livePlaylistDurationNudge: 0.001, + allowFastSwitchUp: false, + minMatchGroupDuration: 5, + desiredIframeFPS: 8, + initialIframeFPS: 6, + minRemainingTimeInMediaPipeline: 3, + leftMediaTimeToAutoPause: 10, + startTargetDurationFactor: 0.9, + minRequiredStartDuration: 4, + maxRequiredStartDuration: 15, + enableWorker: true, + enableWebCrypto: true, + keySystemPreference: void 0, + useMultipleKeySessions: false, + enablePlayReadyKeySystem: false, + useMediaKeySystemAccessFilter: false, + playReadyMessageFormat: 'utf16', + startLevel: void 0, + livePlaylistRefreshDelay: 2500, + liveMinPlayingBufferLen: 5, + enableIFramePreloading: true, + useMediaCapabilities: false, + enableID3Cues: true, + certLoadPolicy: defaultCertLoadPolicy, + keyLoadPolicy: defaultKeyLoadPolicy, + manifestLoadPolicy: defaultManifestLoadPolicy(), + trickPlaybackConfig: defaultTrickPlaybackConfig, + playlistLoadPolicy: { + default: { + // Overall request configs + maxTimeToFirstByteMs: 10000, + maxLoadTimeMs: 20000, + autoRetry: false, + // Retries: + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0, // Maximum delay between retries + }, + errorRetry: { + maxNumRetry: 2, + retryDelayMs: 1000, + maxRetryDelayMs: 8000, // Maximum delay between retries + }, + }, + customURL: { + // Overall request configs + maxTimeToFirstByteMs: 10000, + maxLoadTimeMs: 10000, + autoRetry: false, + // Retries: + timeoutRetry: { + maxNumRetry: 2, + retryDelayMs: 0, + maxRetryDelayMs: 0, // Maximum delay between retries + }, + errorRetry: { + maxNumRetry: 2, + retryDelayMs: 1000, + maxRetryDelayMs: 8000, // Maximum delay between retries + }, + }, + }, + fragLoadPolicy: { + default: { + // Overall request configs + maxTimeToFirstByteMs: 5000, + maxLoadTimeMs: 20000, + autoRetry: false, + // Retries: + timeoutRetry: fragTimeoutRetryDefaultConfig, + errorRetry: fragErrorRetryDefaultConfig, + forceContentLenCheckIfNoHeader: false, + reportCDNServer: true, + }, + customURL: { + // Overall request configs + maxTimeToFirstByteMs: 10000, + maxLoadTimeMs: 20000, + autoRetry: false, + // Retries: + timeoutRetry: fragTimeoutRetryDefaultConfig, + errorRetry: fragErrorRetryDefaultConfig, + reportCDNServer: true, + }, + }, + steeringManifestLoadPolicy: defaultManifestLoadPolicy(), + maxNumAddLevelToPenaltyBox: 4, + firstAudioMustOverlapVideoStart: false, + keyMinHoldTimeBeforeCleanup: 15000, + startFragPrefetch: false, + appendErrorMaxRetry: 3, + alwaysResetOnNewCC: false, + // loader: XhrLoader, // deprecated in favor of rxjs fetch + // loader: FetchLoader, // deprecated in favor of rxjs fetch + fLoader: void 0, + pLoader: void 0, + xhrSetup: void 0, + // fetchSetup: undefined, + // abrController: AbrController, // deprecated in favor or redux/rxjs + // bufferController: BufferController, // deprecated in favor or redux/rxjs + // #if altaudio + // audioStreamController: AudioStreamController, // deprecated in favor or redux/rxjs + // audioTrackController: AudioTrackController, // deprecated in favor or redux/rxjs + iframeMaxExitSeekDuration: 2000, + iframeStallMaxRetry: 5, + audioPrimingDelay: 0, + // #endif + // #if subtitle + // subtitleStreamController: SubtitleStreamController, // deprecated in favor or redux/rxjs + // subtitleTrackController: SubtitleTrackController, // deprecated in favor or redux/rxjs + // timelineController: TimelineController, // deprecated in favor or redux/rxjs + enableCEA708Captions: true, + customTextTrackCueRenderer: false, + enableWebVTT: true, + captionsTextTrack1Label: 'English', + captionsTextTrack1LanguageCode: 'en', + captionsTextTrack2Label: 'Spanish', + captionsTextTrack2LanguageCode: 'es', + enableDualTrackSelection: false, + condenseSubtitleTrack: false, + nativeTextTrackChangeHandling: true, + earlyFragTolerance: 7, + vttConcurrentLoadCount: 1, + trottleCheckInterval: 2000, + subtitleLeadTime: 30, + lateTolerance: 2, + // #endif + stretchShortVideoTrack: false, + forceKeyFrameOnDiscontinuity: true, + useFirstLevelAtIncompatDiscontinuity: true, + abrBandwidthEstimator: 'bandwidth-history-controller', + abrEwmaDefaultEstimate: 500000, + abrDefaultEstimate: 500000, + abrBandWidthFactor: 0.95, + abrBandWidthUpFactor: 0.9, + abrMaxWithRealBitrate: false, + maxStarvationDelay: 4, + maxLoadingDelay: 4, + minAutoBitrate: 0, + enableRtcReporting: false, + rtcIntervalTimeout: 300000, + rtcSender: 'HLSJS', + rtcSessionTag: 'none', + useHTTPPlaybackSessionId: false, + warmupCdms: false, + enablePerformanceLogging: false, + overridePlaybackRate: false, + nativeControlsEnabled: false, + useCustomMediaFunctions: true, + seekEventThrottleMs: 150, + enableAdaptiveStartup: true, + bandwidthHistoryWindowSize: 120000, + bandwidthHistoryTTL: 600000, + bandwidthHistoryAggregationMethod: 'quadratic-time-weighted', + bandwidthHistoryGetEstimateThrottleMs: 1000, + defaultTargetDuration: 10, + targetStartupMs: 4000, + adaptiveStartupMetricsOverride: { + maxValidHeight: 1080, + maxValidBitrate: Infinity, + maxPreferredBitrate: Infinity, // the purpose of `maxPreferredBitrate` is to limit startup time. In adaptive startup we use `targetStartupMs` instead. + }, + bandwidthHistoryStorageKey: 'AppleHLS-bandwidth-estimation', + storageKeyPrefix: 'AppleHLS-', + storage: { + get: typeof localStorage === 'undefined' ? undefined : localStorage.getItem.bind(localStorage), + set: typeof localStorage === 'undefined' ? undefined : localStorage.setItem.bind(localStorage), + }, + minFragmentCount: 10, + minPlaylistCount: 5, + enableCDNFallback: true, + enableQueryParamsForITunes: false, + gapless: false, + useViewportSizeForLevelCap: false, + statDefaults: { + playlistLoadTimeMs: 500, + playlistParseTimeMs: 50, + fragParseTimeMs: 50, + fragBufferCreationDelayMs: 200, + dataFragAppendMs: 50, + initFragAppendMs: 50, + }, + disableVideoCodecList: new Set([ + // codecs that will be ignored during playback + ]), + disableAudioCodecList: new Set([AudioCodecRank.ALAC, AudioCodecRank.FLAC, AudioCodecRank.XHEAAC]), + useHighestVideoCodecPrivate: true, + sessionDataAutoLoad: defaultSessionDataAutoLoad, // Attributes listed here will be auto-fetched if its URI is given. + }; + + const NoMediaOptionKey = { itemId: 'Nah', mediaOptionId: 'Nah' }; + const NoMediaOption = Object.assign(Object.assign({}, NoMediaOptionKey), { mediaOptionType: undefined }); + const isEnabledMediaOption = (mediaOptionInfo) => { + const { itemId, mediaOptionId } = mediaOptionInfo; + return itemId !== 'Nah' && mediaOptionId !== 'Nah'; + }; + const mediaOptionKeyEquals = (firstMediaOption, secondMediaOption) => { + return firstMediaOption.itemId === secondMediaOption.itemId && firstMediaOption.mediaOptionId === secondMediaOption.mediaOptionId; + }; + var MediaOptionType; + (function (MediaOptionType) { + MediaOptionType[MediaOptionType["Variant"] = 0] = "Variant"; + MediaOptionType[MediaOptionType["AltAudio"] = 1] = "AltAudio"; + MediaOptionType[MediaOptionType["Subtitle"] = 2] = "Subtitle"; + })(MediaOptionType || (MediaOptionType = {})); + const MediaOptionNames = ['variant', 'altAudio', 'subtitle']; + const MediaOptionTypes = [MediaOptionType.Variant, MediaOptionType.AltAudio, MediaOptionType.Subtitle]; + const AVMediaOptionTypes = [MediaOptionType.Variant, MediaOptionType.AltAudio]; + + var SourceBufferType; + (function (SourceBufferType) { + SourceBufferType[SourceBufferType["Variant"] = 0] = "Variant"; + SourceBufferType[SourceBufferType["AltAudio"] = 1] = "AltAudio"; + })(SourceBufferType || (SourceBufferType = {})); + const SourceBufferNames = ['variant', 'altAudio']; + function mediaOptionTypeToSourceBufferType(optionType) { + switch (optionType) { + case MediaOptionType.Variant: + return SourceBufferType.Variant; + case MediaOptionType.AltAudio: + return SourceBufferType.AltAudio; + default: + return null; + } + } + function sourceBufferTypeToMediaOptionType(sbType) { + return sbType === SourceBufferType.Variant ? MediaOptionType.Variant : MediaOptionType.AltAudio; + } + function initSegmentEquals(a, b) { + const equals = a && b && a.itemId === b.itemId && a.mediaOptionId === b.mediaOptionId && a.discoSeqNum === b.discoSeqNum && a.keyId === b.keyId; + return equals; + } + + var Allowed; + (function (Allowed) { + Allowed[Allowed["NO"] = 0] = "NO"; + Allowed[Allowed["YES"] = 1] = "YES"; + })(Allowed || (Allowed = {})); + + var MediaTypeFourCC; + (function (MediaTypeFourCC) { + MediaTypeFourCC["UNKNOWN"] = "unkn"; + MediaTypeFourCC["VIDEO"] = "vide"; + MediaTypeFourCC["AUDIO"] = "soun"; + MediaTypeFourCC["SUBTITLE"] = "sbtl"; + MediaTypeFourCC["CLOSEDCAPTION"] = "clcp"; + })(MediaTypeFourCC || (MediaTypeFourCC = {})); + + + const BinarySearch = { + /** + * Searches for an item in an array which matches a certain condition. + * This requires the condition to only match one item in the array, + * and for the array to be ordered. + * + * @param {Array} list The array to search. + * @param {Function} comparisonFunction + * Called and provided a candidate item as the first argument. + * Should return: + * > -1 if the item should be located at a lower index than the provided item. + * > 1 if the item should be located at a higher index than the provided item. + * > 0 if the item is the item you're looking for. + * + * @return {*} The object if it is found or undefined otherwise. + */ + search: function (list, comparisonFunction) { + let minIndex = 0; + let maxIndex = (list === null || list === void 0 ? void 0 : list.length) - 1; + let currentIndex; + let currentElement; + while (minIndex <= maxIndex) { + currentIndex = ((minIndex + maxIndex) / 2) | 0; + currentElement = list[currentIndex]; + const comparisonResult = comparisonFunction(currentElement); + if (comparisonResult > 0) { + minIndex = currentIndex + 1; + } + else if (comparisonResult < 0) { + maxIndex = currentIndex - 1; + } + else { + return currentElement; + } + } + return null; + }, + }; + var BinarySearch$1 = BinarySearch; + + /** + * Fragment finder utils, providing methods for determining next fragment to fetch + * + * + * + * + */ + function fragTag(frag, level) { + return `sn/cc/level: ${frag.mediaSeqNum}/${frag.discoSeqNum}/${level}`; + } + function rangeString(frag) { + let result = 'N/A'; + if (frag.start >= 0 && frag.duration >= 0) { + result = `${frag.start.toFixed(2)}-${(frag.start + frag.duration).toFixed(2)}`; + } + return result; + } + const FragmentFetchHelper = { + /** + * Finds a fragment based on the SN of the previous fragment and current buffer. + * @param fragPrevious - The last frag successfully appended + * @param fragments - The array of fragments in level + * @param bufferEnd - The end of the contiguous buffer range within which playhead is + * @param end - End time of the level + * @param maxFragLookUpTolerance - acceptable tolerance limit + */ + findFragmentBySNAndBuffer: function (fragPrevious, fragments, bufferEnd = 0, end = 0, maxFragLookUpTolerance = 0) { + let foundFrag; + const fragNext = fragPrevious ? fragments[fragPrevious.mediaSeqNum - fragments[0].mediaSeqNum + 1] : null; + if (bufferEnd < end) { + if (bufferEnd > end - maxFragLookUpTolerance) { + maxFragLookUpTolerance = 0; + } + // Prefer the next fragment if it's within tolerance + if (fragNext && !this.fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext)) { + foundFrag = fragNext; + } + else { + foundFrag = BinarySearch.search(fragments, this.fragmentWithinToleranceTest.bind(null, bufferEnd, maxFragLookUpTolerance)); + } + } + else { + // reach end of playlist + foundFrag = fragments[fragments.length - 1]; + } + return foundFrag; + }, + fragmentWithinToleranceTest: function (bufferEnd, maxFragLookUpTolerance, candidate) { + // offset should be within fragment boundary - config.maxFragLookUpTolerance + // this is to cope with situations like + // bufferEnd = 9.991 + // frag[Ø] : [0,10] + // frag[1] : [10,20] + // bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here + // frag start frag start+duration + // |-----------------------------| + // <---> <---> + // ...--------><-----------------------------><---------.... + // previous frag matching fragment next frag + // return -1 return 0 return 1 + // logger.info(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`); + // Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments + const candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration); + if (candidate.start + candidate.duration - candidateLookupTolerance <= bufferEnd) { + return 1; + } + else if (candidate.start - candidateLookupTolerance > bufferEnd && candidate.start) { + // if maxFragLookUpTolerance will have negative value then don't return -1 for first element + return -1; + } + return 0; + }, + }; + var FragmentFetchHelper$1 = FragmentFetchHelper; + + const loggerName$9 = { name: 'disco' }; + const DiscoHelper = { + startFragmentInCC: function (fragments, cc, candidate) { + let rank = cc - candidate.discoSeqNum; + if (rank === 0) { + const fragPrevious = fragments[candidate.mediaSeqNum - fragments[0].mediaSeqNum - 1]; + rank = fragPrevious && fragPrevious.discoSeqNum === candidate.discoSeqNum ? -1 : 0; + } + return rank; + }, + endFragmentInCC: function (fragments, cc, candidate) { + let rank = cc - candidate.discoSeqNum; + if (rank === 0) { + const fragNext = fragments[candidate.mediaSeqNum - fragments[0].mediaSeqNum + 1]; + rank = fragNext && fragNext.discoSeqNum === candidate.discoSeqNum ? 1 : 0; + } + return rank; + }, + findStartEndFragmentsInCC: function (fragments, cc, logger) { + let startFrag; + let endFrag; + if ((fragments === null || fragments === void 0 ? void 0 : fragments.length) > 0 && isFiniteNumber(cc)) { + startFrag = BinarySearch.search(fragments, DiscoHelper.startFragmentInCC.bind(null, fragments, cc)); + endFrag = BinarySearch.search(fragments, DiscoHelper.endFragmentInCC.bind(null, fragments, cc)); + } + if (!endFrag) { + logger.info(loggerName$9, `cc ${cc} does not appear in fragments anymore`); + } + // handle bogus results due to undefined cc + if (startFrag && !isFiniteNumber(startFrag.discoSeqNum)) { + logger.info(loggerName$9, `findStartEndFragmentsInCC startFrag ${startFrag.mediaSeqNum} has undefined cc ${cc}`); + startFrag = undefined; + } + if (endFrag && !isFiniteNumber(endFrag.discoSeqNum)) { + logger.info(loggerName$9, `findStartEndFragmentsInCC endFrag ${endFrag.mediaSeqNum} has undefined cc ${cc}`); + endFrag = undefined; + } + return { startFrag, endFrag }; + }, + getTimeRangeDictForCC: function (fragments, cc, logger) { + const ccFragRange = DiscoHelper.findStartEndFragmentsInCC(fragments, cc, logger); + const { startFrag, endFrag } = ccFragRange; + const start = startFrag.start; + const end = endFrag.start + endFrag.duration; + return { start, end }; + }, + getTimeRangeForCC: function (fragments, cc, logger) { + const ccFragRange = DiscoHelper.findStartEndFragmentsInCC(fragments, cc, logger); + const { startFrag, endFrag } = ccFragRange; + let ccTimeRange = []; + if (startFrag && endFrag) { + ccTimeRange = [startFrag.start, endFrag.start + endFrag.duration]; + } + return ccTimeRange; + }, + snapToCCTimeRange: function (targetTime, fragments, cc, logger) { + const ccRange = DiscoHelper.getTimeRangeForCC(fragments, cc, logger); + if (!(ccRange === null || ccRange === void 0 ? void 0 : ccRange.length)) { + return targetTime; + } + return Math.min(ccRange[1], Math.max(ccRange[0], targetTime)); + }, + getMinTimeForCC(mainFragments, audioFragments, cc, logger) { + if (!(mainFragments === null || mainFragments === void 0 ? void 0 : mainFragments.length)) { + return 0; + } + // const fragments = this.variantManager.getVariantInfoIfValid(this.currentVariantId)?.details?.fragments; + let startCCTime = 0; + if (isFiniteNumber(cc) && mainFragments) { + const ccRange = DiscoHelper.getTimeRangeForCC(mainFragments, cc, logger); + if (ccRange) { + const audioCCRange = DiscoHelper.getTimeRangeForCC(audioFragments, cc, logger); // this.audioStreamController?.getAudioTimeRangeForCC(cc); + if (audioCCRange === null || audioCCRange === void 0 ? void 0 : audioCCRange.length) { + startCCTime = Math.max(audioCCRange[0], ccRange[0]); + } + else { + startCCTime = ccRange[0]; + } + } + } + return startCCTime; + }, + discoSeqNumForTime(fragments, pos, tolerance = 0) { + const foundFrag = BinarySearch.search(fragments, FragmentFetchHelper$1.fragmentWithinToleranceTest.bind(null, pos, tolerance)); + return foundFrag === null || foundFrag === void 0 ? void 0 : foundFrag.discoSeqNum; + }, + }; + var DiscoHelper$1 = DiscoHelper; + + const VOID = of(void 0); + /** + * Wait for some condition to be true on an observable + * @param source Source observable + * @param condition Condition to apply + * @param times How many times to allow observable to fire before completing. By default, 1 + */ + function waitFor(source, condition, times = 1) { + return source.pipe(filter(condition), take(times)); + } + + /* + * Simple clock abstraction to help transform between clocks and their timelines + * + * 2020 Apple Inc. All rights reserved. + */ + /** + * Convert a SyncTimelineValue into a different timeline + * + * @param sourceValue The value to map to a different timeline + * @param destTimeline The timeline to map into + * + * @returns A new SyncTimelineValue in destTimeline + */ + function mapValueToTimeline(sourceValue, destTimeline) { + const sourceTimeline = sourceValue.timeline; + const newValue = ((sourceValue.seconds - sourceTimeline.rootTimeSeconds) / sourceTimeline.rate) * destTimeline.rate + destTimeline.rootTimeSeconds; + return { seconds: newValue, timeline: destTimeline }; + } + + class IframeClock { + constructor() { + this._timeline = null; + } + get forward() { + var _a; + return ((_a = this.timeline) === null || _a === void 0 ? void 0 : _a.rate) > 0; + } + get isStarted() { + return Boolean(this.hostClock); + } + start(timeline) { + this.stopTime = null; + this._timeline = Object.assign({}, timeline); + const performanceTimeline = { rootTimeSeconds: performance.now() / 1000, rate: 1 }; + this.hostClock = { + timeline: performanceTimeline, + getCurrentTime: () => { + return { seconds: performance.now() / 1000, timeline: performanceTimeline }; + }, + }; + } + pause() { + if (this.isStarted) { + this.stopTime = this.getCurrentTime(); + } + } + stop() { + this.pause(); + this.hostClock = null; + this._timeline = null; + } + // ClockSyncAdapter interface + get timeline() { + return this._timeline; + } + getCurrentTime() { + if (this.stopTime) { + return this.stopTime; + } + // map the performance clock into the iframe timeline + const hostValue = this.hostClock.getCurrentTime(); + const myValue = mapValueToTimeline(hostValue, this.timeline); + return myValue; + } + } + + /** + * This is a view into our media element we're appending into. We don't care about any time other + * than the buffer end, so that's our time source + */ + class MediaAppendClock { + constructor(_timeline) { + this._timeline = _timeline; + // our start time is our current buffer end + this.mediaRootTime = this.lastTimeSeconds = _timeline.rootTimeSeconds; + } + // ClockSyncAdapter interface + get timeline() { + return Object.assign({}, this._timeline); + } + getCurrentTime() { + // the latest time we know about + return { seconds: this.lastTimeSeconds, timeline: Object.assign({}, this._timeline) }; + } + } + + /* + * Trickplay implementation + * + * 2020 Apple Inc. All rights reserved. + */ + const loggerName$8 = { name: 'ifm' }; + /** + * + * A sort of 'controller' for iframes + * + * Managages two clocks: + * The iframe clock has a real time host and is untied to the media progression + * The media append clock represents the media element, where we are actually appending the iframes + * + * The responsibility of this class is to supply the iframes fragments via nextFragment so that + * the media append clock keeps pace with the iframe clock (no drift) + * + */ + class IframeMachine { + constructor(config, logger) { + this.config = config; + this.logger = logger; + // Fragments we've modified and need to cleanup + this.scaledFragments = []; + // this is the 'iframe clock', running at the iframe rate + // with a timebase anchored at the time trickplay startart + this.iframeClock = new IframeClock(); + this.hasMore$ = new BehaviorSubject(true); + this.logger = logger.child(loggerName$8); + } + destroy() { + this.stop(); + } + resetScaledSegments() { + this.scaledFragments = []; + } + get anchorFrag() { + return this.scaledFragments.length ? this.scaledFragments[0] : null; + } + get lastFrag() { + return this.scaledFragments.length ? this.scaledFragments.slice(-1)[0] : null; + } + get isStarted() { + return Boolean(this.iframeClock.isStarted); + } + get iframeRate() { + var _a, _b; + return (_b = (_a = this.iframeClock.timeline) === null || _a === void 0 ? void 0 : _a.rate) !== null && _b !== void 0 ? _b : 0; + } + get iframeClockTimeSeconds() { + return Math.max(0, this.iframeClock.getCurrentTime().seconds); + } + get mediaAppendClockTimeSeconds() { + var _a, _b; + return (_b = (_a = this.mediaAppendClock) === null || _a === void 0 ? void 0 : _a.getCurrentTime().seconds) !== null && _b !== void 0 ? _b : 0; + } + get mediaRootTime() { + var _a; + return (_a = this.mediaAppendClock) === null || _a === void 0 ? void 0 : _a.mediaRootTime; + } + pause() { + this.iframeClock.pause(); + } + stop() { + this.logger.debug('stop'); + this.hasMore$.next(true); + this.iframeClock.stop(); + this.mediaAppendClock = null; + this.resetScaledSegments(); + } + checkHasMore() { + this.hasMore$.next(true); + } + /** + * Re-anchor the iframe clock + * @param iframeFragments + * @param audioFragments + * @param rate + * @param pos + */ + startClocksAndGetFirstFragment(iframeFragments, audioFragments, rate, pos, disco) { + this.logger.info(`startClocksAndGetFirstFragment: rate(${rate}), pos(${pos})`); + let anchorFrag = BinarySearch.search(iframeFragments, FragmentFetchHelper$1.fragmentWithinToleranceTest.bind(null, pos, 0.0001)); + if (!anchorFrag && pos >= iframeFragments[iframeFragments.length - 1].start) { + this.logger.info(`startClocksAndGetFirstFragment: pick last frag, start=${iframeFragments[iframeFragments.length - 1].start}`); + anchorFrag = iframeFragments[iframeFragments.length - 1]; + } + if (!anchorFrag) { + this.logger.error(`startClocksAndGetFirstFragment => no anchorFrag for time ${pos}`); + this.hasMore$.next(false); + return null; + } + const nextDisco = isFiniteNumber(disco) ? disco : anchorFrag.discoSeqNum; + const startCCTime = DiscoHelper$1.getMinTimeForCC(iframeFragments, audioFragments, nextDisco, this.logger); + const newPosition = isFiniteNumber(disco) && rate > 1 ? startCCTime : pos; + let newMediaRootTime; + if (rate > 1) { + // fast forward should always have enough to anchor at the current point + newMediaRootTime = Math.ceil(newPosition); + } + else { + newMediaRootTime = Math.ceil(startCCTime); + } + this.iframeClock.start({ rootTimeSeconds: newPosition, rate }); + this.mediaAppendClock = new MediaAppendClock({ rootTimeSeconds: newMediaRootTime, rate: 1 }); + return { frag: anchorFrag, newMediaRootTime }; + } + getNextFragment(fragments, bufferEnd, rate) { + const lastFrag = this.lastFrag; + const { iframeClock, mediaAppendClock } = this; + const iframeTimeline = iframeClock.timeline; + mediaAppendClock.lastTimeSeconds = bufferEnd; + this.logger.qe({ + critical: true, + name: 'iframes', + data: { maxMediaTime: bufferEnd, rate, ifmat: this.mediaAppendClock.timeline.rootTimeSeconds, ifbt: this.iframeClock.timeline.rootTimeSeconds }, + }); + const ixStep = iframeClock.forward ? 1 : -1; + let ix = Math.max(0, Math.min(lastFrag.mediaSeqNum - fragments[0].mediaSeqNum + ixStep, fragments.length - 1)); + let nextFrag; + if (lastFrag.mediaSeqNum !== fragments[ix].mediaSeqNum) { + // always allow first step to work for EOS cleanliness + do { + nextFrag = fragments[ix]; + const seconds = iframeClock.forward ? nextFrag.start : nextFrag.start + nextFrag.duration; + const startAppendTime = mapValueToTimeline({ seconds, timeline: iframeTimeline }, mediaAppendClock.timeline); + if (startAppendTime.seconds >= bufferEnd && ((iframeClock.forward && seconds >= this.iframeClockTimeSeconds) || (!iframeClock.forward && seconds <= this.iframeClockTimeSeconds))) { + break; + } + ix += ixStep; + } while (ix > 0 && ix < fragments.length); + } + if (!nextFrag) { + // stream controller should have stopped and waited until we said so, and we should have found something new + this.logger.error(`getNextFragment(bufferEnd: ${bufferEnd}) => no more frags, but we should have found an end fragment, setting hasMore to false`); + this.hasMore$.next(false); + } + return { frag: nextFrag }; + } + /** + * Get the next fragment to fetch + * @param iframeFragments + * @param audioFragments + * @param rate + * @param pos + * @param bufferLen + * @return anchor fragment + */ + nextFragment(iframeFragments, audioFragments, rate, pos) { + let foundFrag; + let rateSwitchPos; + if (this.isStarted && rate !== this.iframeRate) { + rateSwitchPos = this.iframeClockTimeSeconds; + this.stop(); + } + if (!this.isStarted) { + foundFrag = this.startClocksAndGetFirstFragment(iframeFragments, audioFragments, rate, rateSwitchPos !== null && rateSwitchPos !== void 0 ? rateSwitchPos : pos); + if (!foundFrag) { + return; + } + } + else { + foundFrag = this.getNextFragment(iframeFragments, pos, rate); + if (!foundFrag.frag) { + return; + } + else if (foundFrag.frag.discoSeqNum !== this.anchorFrag.discoSeqNum) { + const iframeTimeSeconds = this.iframeClockTimeSeconds; + this.logger.info(`nextFragment iframeClockTime(${iframeTimeSeconds.toFixed(3)}) => found new disco, ${this.anchorFrag.discoSeqNum} to ${foundFrag.frag.discoSeqNum}`); + this.stop(); + const { newMediaRootTime } = this.startClocksAndGetFirstFragment(iframeFragments, audioFragments, rate, iframeTimeSeconds, foundFrag.frag.discoSeqNum); + foundFrag.newMediaRootTime = newMediaRootTime; + } + } + const { frag, newMediaRootTime } = foundFrag; + const updatedFrag = this.handleNextFrag(iframeFragments, frag); + const appendStart = updatedFrag.iframeMediaStart, appendEnd = appendStart + updatedFrag.iframeMediaDuration; + this.logger.info(`nextFragment iframeClockTime(${this.iframeClockTimeSeconds.toFixed(3)}) => picked frag: ${fragTag(updatedFrag)}, source range: ${rangeString(updatedFrag)}, media append times: ${appendStart.toFixed(3)}-${appendEnd.toFixed(3)}${isFiniteNumber(newMediaRootTime) ? ', newMediaRootTime: ' + newMediaRootTime.toFixed(3) : ''}`); + return Object.assign(Object.assign({}, foundFrag), { frag: updatedFrag }); + } + handleNextFrag(fragments, frag) { + const cpFrag = Object.assign(Object.assign({}, frag), { iframeMediaStart: NaN, iframeMediaDuration: NaN }); + const { mediaAppendClock, iframeClock } = this; + // update our bounds just in case we're live + this.iframeClockBounds = DiscoHelper$1.getTimeRangeDictForCC(fragments, cpFrag.discoSeqNum, this.logger); + // the start of our iframe is the latest time of the media append clock + const bufferEnd = mediaAppendClock.getCurrentTime().seconds; + const iframeRate = iframeClock.timeline.rate; + if (!isFiniteNumber(cpFrag.iframeOriginalStart)) { + // iframe mode shouldn't have mangled frag.start + // we need the original frag.start to calculate initPTS. + // stash it in frag.iframeOriginalStart + cpFrag.iframeOriginalStart = cpFrag.start; + } + cpFrag.start = cpFrag.iframeMediaStart = bufferEnd; + cpFrag.iframeMediaDuration = Math.max(cpFrag.duration / Math.abs(iframeRate), 1 / this.config.minIframeDuration); + // track which frags we've modifed - TODO find a better way to do this + this.scaledFragments.push(cpFrag); + // check for EOS + if (this.isEndFrag(fragments, cpFrag)) { + this.logger.info(`checkEOS(frag: ${cpFrag.mediaSeqNum}) => found end frag, setting hasMore to false`); + this.hasMore$.next(false); + } + return cpFrag; + } + get hasMore() { + return this.hasMore$.value; + } + // anchor isn't necessary valid in this function, so don't reference it + /** + * Wait for there to be more fragments to be downloaded + */ + handleWaitForMore() { + this.logger.trace(`handleWaitForMore(): isStarted: ${this.isStarted}`); + if (!this.isStarted) { + return VOID; + } + const currentIframeTime = this.iframeClock.getCurrentTime(); + const iframeClockTime = currentIframeTime.seconds; + const rate = currentIframeTime.timeline.rate; + const edgeTime = rate > 1 ? this.iframeClockBounds.end : this.iframeClockBounds.start; + const diff = edgeTime - currentIframeTime.seconds; + const wait = diff / rate; // the +/- work out with the rate and the diff + this.logger.info(`handleWaitForMore(): iframeClockTime: ${iframeClockTime}, edgeTime: ${edgeTime}, diff ${diff} => wait: ${wait}`); + return waitFor(this.hasMore$, (hasMore) => hasMore === true).pipe(tap(() => { + this.logger.info(`handleWaitForMore(): iframeClockTime: ${iframeClockTime} => hasMore became true while waiting`); + })); + } + isEndFrag(fragments, frag) { + const startFrag = fragments[0]; + const endFrag = fragments[fragments.length - 1]; + const ff = this.iframeClock.forward; + const rw = !ff; + return (rw && (startFrag === null || startFrag === void 0 ? void 0 : startFrag.mediaSeqNum) === frag.mediaSeqNum) || (ff && (endFrag === null || endFrag === void 0 ? void 0 : endFrag.mediaSeqNum) === frag.mediaSeqNum); + } + } + function createIframeMachine(config, logger) { + return new Observable((subscriber) => { + const iframeMachine = new IframeMachine(config, logger); + subscriber.next(iframeMachine); + return () => { + // cleanup + }; + }); + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + /** + * Use of this source code is governed by an MIT-style license that + * can be found in the LICENSE file at https://github.com/cartant/rxjs-spy + */ + + /*tslint:disable:no-use-before-declare*/ + function tag(tag) { + return function tagOperation(source) { + return source.lift(new TagOperator(tag)); + }; + } + + var TagOperator = /*#__PURE__*/function () { + // It would be better if this were a symbol. However ... + // error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + function TagOperator(tag) { + _classCallCheck(this, TagOperator); + + _defineProperty(this, "tag", void 0); + + this.tag = tag; + } + + _createClass(TagOperator, [{ + key: "call", + value: function call(subscriber, source) { + return source.subscribe(subscriber); + } + }]); + + return TagOperator; + }(); + + // Key request state from a macro level (substates in KeyRequestContext) + var KeyRequestMacroState; + (function (KeyRequestMacroState) { + KeyRequestMacroState["MustRequestResponse"] = "MustRequestResponse"; + KeyRequestMacroState["WaitingForKeyResponse"] = "WaitingForKeyResponse"; + KeyRequestMacroState["GotKeyResponse"] = "GotKeyResponse"; + })(KeyRequestMacroState || (KeyRequestMacroState = {})); + // TODO convert DecryptData types to ArrayBuffer so we don't need these anymore + function keyTagInfoToEntity(keyInfo) { + var _a, _b, _c, _d, _e; + const { method, isEncrypted, uri, format, formatversions } = keyInfo; + return { + method, + isEncrypted, + uri, + format, + formatversions, + ivBuf: (_b = (_a = keyInfo.iv) === null || _a === void 0 ? void 0 : _a.buffer) !== null && _b !== void 0 ? _b : null, + keyIdBuf: (_c = keyInfo.keyId) === null || _c === void 0 ? void 0 : _c.buffer, + keyBuf: (_d = keyInfo.key) === null || _d === void 0 ? void 0 : _d.buffer, + psshBuf: (_e = keyInfo.key) === null || _e === void 0 ? void 0 : _e.buffer, + }; + } + function entityToKeyTagInfo(entity) { + const { method, isEncrypted, uri, format, formatversions } = entity; + const keyTagInfo = { + method, + isEncrypted, + uri, + format, + formatversions, + iv: entity.ivBuf ? new Uint8Array(entity.ivBuf) : null, + }; + if (entity.keyIdBuf) { + keyTagInfo.keyId = new Uint8Array(entity.keyIdBuf); + } + if (entity.keyBuf) { + keyTagInfo.key = new Uint8Array(entity.keyBuf); + } + if (entity.psshBuf) { + keyTagInfo.pssh = new Uint8Array(entity.psshBuf); + } + return keyTagInfo; + } + + // Generic network error + class GenericNetworkError extends Error { + constructor(message, code) { + super(message); + this.code = code; + } + } + class HlsNetworkError extends HlsError { + constructor(details, fatal, reason, code, response, isTimeout) { + super(ErrorTypes.NETWORK_ERROR, details, fatal, reason, response); + this.code = code; + this.isTimeout = isTimeout; + this.response = response; + } + } + class ManifestNetworkError extends HlsNetworkError { + constructor(fatal, reason, code, response, isTimeout) { + super(isTimeout ? ErrorDetails.MANIFEST_LOAD_TIMEOUT : ErrorDetails.MANIFEST_LOAD_ERROR, fatal, reason, code, response, isTimeout); + } + } + // Problem when loading playlist or manifest + class PlaylistNetworkError extends HlsNetworkError { + constructor(fatal, reason, code, response, isTimeout, mediaOptionType, mediaOptionId, url) { + super('', fatal, reason, code, response, isTimeout); + this.mediaOptionType = mediaOptionType; + this.mediaOptionId = mediaOptionId; + this.url = url; + switch (mediaOptionType) { + case MediaOptionType.Variant: + this.details = isTimeout ? ErrorDetails.LEVEL_LOAD_TIMEOUT : ErrorDetails.LEVEL_LOAD_ERROR; + break; + case MediaOptionType.AltAudio: + this.details = isTimeout ? ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT : ErrorDetails.AUDIO_TRACK_LOAD_ERROR; + break; + case MediaOptionType.Subtitle: + this.details = isTimeout ? ErrorDetails.SUBTITLE_TRACK_LOAD_TIMEOUT : ErrorDetails.SUBTITLE_TRACK_LOAD_ERROR; + break; + } + } + } + // Problem when loading SessionData + class SessionDataNetworkError extends HlsNetworkError { + constructor(fatal, reason, code, response) { + super(ErrorDetails.SESSION_DATA_LOAD_ERROR, fatal, reason, code, response, false); + } + } + // Problem when loading fragment + class FragmentNetworkError extends HlsNetworkError { + constructor(fatal, reason, code, response, isTimeout, frag, stats) { + super(isTimeout ? ErrorDetails.FRAG_LOAD_TIMEOUT : ErrorDetails.FRAG_LOAD_ERROR, fatal, reason, code, response, isTimeout); + this.mediaOptionId = frag.mediaOptionId; + this.mediaOptionType = frag.mediaOptionType; + this.stats = stats; + } + } + class GenericTimeoutError extends TimeoutError { + constructor(message, code, stats) { + super(); + this.message = message; + this.code = code; + this.stats = stats; + } + } + class FragmentAbortError extends HlsNetworkError { + constructor(frag, candidateMediaOptionId, response) { + super('fragAbortError', false, 'Fragment abort', 0, response, false); + this.candidateMediaOptionId = candidateMediaOptionId; + this.mediaOptionId = frag.mediaOptionId; + this.mediaOptionType = frag.mediaOptionType; + } + } + + // Errors generated by CDM / KeySystem + class KeyRequestTimeoutError extends HlsNetworkError { + constructor(message, keyuri, response, mediaOptionIds = []) { + super(ErrorDetails.KEY_LOAD_TIMEOUT, false, message, response.code, response, true); + this.keyuri = keyuri; + this.response = response; + this.mediaOptionIds = mediaOptionIds; + } + } + var KeyRequestErrorReason; + (function (KeyRequestErrorReason) { + KeyRequestErrorReason[KeyRequestErrorReason["InvalidState"] = 0] = "InvalidState"; + KeyRequestErrorReason[KeyRequestErrorReason["Abort"] = 1] = "Abort"; + KeyRequestErrorReason[KeyRequestErrorReason["OutputRestricted"] = 2] = "OutputRestricted"; + KeyRequestErrorReason[KeyRequestErrorReason["AlreadyFailedKey"] = 3] = "AlreadyFailedKey"; + KeyRequestErrorReason[KeyRequestErrorReason["HttpError"] = 4] = "HttpError"; + KeyRequestErrorReason[KeyRequestErrorReason["InternalError"] = 5] = "InternalError"; + KeyRequestErrorReason[KeyRequestErrorReason["LicenseServerError"] = 6] = "LicenseServerError"; + KeyRequestErrorReason[KeyRequestErrorReason["InsufficientCPC"] = 7] = "InsufficientCPC"; + })(KeyRequestErrorReason || (KeyRequestErrorReason = {})); + // Something that failed in the actual request to the license server + class KeyRequestError extends HlsNetworkError { + constructor(message, keyuri, code, response, isOkToRetry, keyErrorReason, fatal = false, mediaOptionIds = []) { + super(ErrorDetails.KEY_LOAD_ERROR, fatal, message, code, response, false); + this.keyuri = keyuri; + this.isOkToRetry = isOkToRetry; + this.keyErrorReason = keyErrorReason; + this.mediaOptionIds = mediaOptionIds; + } + } + // Something that failed due to key exchange or key system initialization + class KeySystemError extends HlsError { + constructor(message, keyuri, code, response, keysystemstring) { + super(ErrorTypes.OTHER_ERROR, ErrorDetails.KEY_SYSTEM_GENERIC_ERROR, true, message, response); + this.keyuri = keyuri; + this.code = code; + this.response = response; + this.keysystemstring = keysystemstring; + } + } + function copyKeyError(error, mediaOptionIds) { + if (error instanceof KeyRequestError) { + return new KeyRequestError(error.message, error.keyuri, error.code, error.response, error.isOkToRetry, error.keyErrorReason, error.fatal, mediaOptionIds); + } + else if (error instanceof KeyRequestTimeoutError) { + return new KeyRequestTimeoutError(error.message, error.keyuri, ErrorResponses.CryptResponseReceivedSlowly, mediaOptionIds); + } + else if (error) { + return new ExceptionError(error.fatal, error.reason, ErrorResponses.InternalError); + } + return null; + } + + /* + * FairPlayStreaming key system constants + * + * 2018 Apple Inc. All rights reserved. + */ + const FairPlaySecurityLevels = { + AppleBaseline: 0, + AppleMain: 1, + Main: 1, + Baseline: 0, + }; + const FairPlayStreamingKeySystemProperties = { + id: 'fairplaystreaming', + systemStringPrefix: 'com.apple.fps', + keyFormatString: 'com.apple.streamingkeydelivery', + securityLevels: FairPlaySecurityLevels, + }; + + class LoaderQuery extends QueryEntity { + constructor(store) { + super(store); + this.store = store; + } + get unresolvedUriLoading$() { + return this.selectEntityAction(EntityActions.Add).pipe(map((entityIds) => entityIds.map((id) => this.getEntity(id)))); + } + } + + class LoaderStore extends EntityStore { + constructor() { + super({}, { name: 'loader', producerFn: produce_1, idKey: 'uri' }); + } + } + + class LoaderService { + constructor(store) { + this.store = store; + } + createUnresolvedUriLoading(uri, responseType, userAgent) { + logAction('loader.create.unresolvedUriLoading'); + this.store.add({ uri, responseType, userAgent }); + } + removeUnresolvedUriLoading(uri) { + logAction('loader.remove.unresolvedUriLoading'); + this.store.remove(uri); + } + } + const store$1 = new LoaderStore(); + let service$2 = null; // To be instantiated in loaderService() + /*********************************************** + * Static helper functions that specifically use the above singletons + */ + function createLoaderQuery() { + return new LoaderQuery(store$1); + } + /** + * @returns The global instance of LoaderService that operates on global LoaderStore + */ + function getLoaderService() { + if (!service$2) { + service$2 = new LoaderService(store$1); + } + return service$2; + } + + /* + * HLS Event Emitter + * + * + */ + /** + * Simple adapter sub-class of Nodejs-like EventEmitter. + */ + class HlsEventEmitter extends EventEmitter { + /** + * We simply want to pass along the event-name itself + * in every call to a handler, which is the purpose of our `trigger` method + * extending the standard API. + */ + trigger(event, data) { + try { + this.emit(event, event, data); + if (event.toString() !== 'hlsFragLoadProgress') { + // do not log fragLoadProgress, too noisy + // Do NOT log data, which can be very large (for instance the data1: and data2: arguments from demuxer + // console will hold onto the arguments in here until the next event loop and can cause memory to balloon over time + let details = ''; + if ((event === 'hlsInternalError' || event === 'hlsError') && data.length) { + details = JSON.stringify(data[0], ['fatal', 'details', 'reason']); + } + const eventData = { event: event.toString() }; + if (details.length > 0) { + eventData.details = details; + } + getLogger().qe({ critical: true, name: 'eventTrigger', data: eventData }); + } + } + catch (err) { + getLogger().warn(`error in event listener for ${event}: ${err.message}`); + } + } + } + + class EventTarget { + constructor(target, _this) { + this.target = target; + this._this = _this; + } + eventWithOptions(event, options, handler, _this = this._this) { + let observable = fromEvent(this.target, event, options); + if (this.target instanceof HlsEventEmitter) { + // HLS's raw event handlers accepts two arguments: + // - event: _Event + // - data: EventData<_EventDataMap, _Event> + // We need to map it to single data argument + observable = observable.pipe(map(([_, data]) => data)); + } + if (handler) { + if (_this) { + handler = handler.bind(_this); + } + observable = observable.pipe(tap(handler)); + } + return observable; + } + event(event, handler, _this = this._this) { + return this.eventWithOptions(event, undefined, handler, _this); + } + listen(event, notifier, handler, _this = this._this) { + return this.event(event, handler, _this).pipe(takeUntil(notifier)).subscribe(); + } + } + function fromEventTarget(target, _this) { + return new EventTarget(target, _this); + } + // Note that vuze doesn't implement some events so may not be safe to use ev directly. Use to fill + function convertEvent(currentTarget, type, ev) { + var _b, _c; + return { + currentTarget: (_b = ev === null || ev === void 0 ? void 0 : ev.currentTarget) !== null && _b !== void 0 ? _b : currentTarget, + target: (_c = ev === null || ev === void 0 ? void 0 : ev.target) !== null && _c !== void 0 ? _c : currentTarget, + type: type, + }; + } + + + function getByteRangeLength(byteRangeHeader) { + const BYTERANGE = /([0-9]+)\-([0-9]+)\/([0-9]+)/; + const result = BYTERANGE.exec(byteRangeHeader); + return result ? parseInt(result[2]) - parseInt(result[1]) + 1 : undefined; + } + function getContentLength(xhr) { + let contentLength; + const contentEncoding = xhr.getResponseHeader('Content-Encoding'); + const transferEncoding = xhr.getResponseHeader('Transfer-Encoding'); + const noContentEncoding = !contentEncoding || (contentEncoding && contentEncoding.toLowerCase() === 'identity'); + const noTransferEncoding = !transferEncoding || (transferEncoding && transferEncoding.toLowerCase() === 'identity'); + if (noContentEncoding && noTransferEncoding) { + // Length only makes sense without encoding/compression + contentLength = getByteRangeLength(xhr.getResponseHeader('Content-Range')); + if (!isFiniteNumber(contentLength)) { + contentLength = parseInt(xhr.getResponseHeader('Content-Length')); + } + } + return contentLength; + } + function fromXMLHttpRequest(context, loadConfig) { + return new Observable((subscriber) => { + const { maxTimeToFirstByteMs, maxLoadTimeMs } = loadConfig; + const xhr = new XMLHttpRequest(); + const stats = { + trequest: performance.now(), + tfirst: NaN, + tload: NaN, + loaded: 0, + total: NaN, + complete: false, + }; + const xhrTarget = fromEventTarget(xhr); + // register for events + const onprogress$ = xhrTarget.event('progress').pipe(share(), throttleTime(300, queueScheduler, { leading: true, trailing: true }), map((progressEvent) => { + if (isNaN(stats.tfirst)) { + stats.tfirst = performance.now(); + } + stats.loaded = progressEvent.loaded; + if (progressEvent.lengthComputable) { + stats.total = progressEvent.total; + } + return progressEvent.target; + }), filter((req) => req.readyState >= 3)); + const onreadystate$ = xhrTarget.event('readystatechange').pipe(share(), map((event) => event.target), filter((req) => req.readyState >= 2), tap((req) => { + if (isNaN(stats.tfirst) && req.readyState >= 3) { + stats.tfirst = performance.now(); + } + })); + let timeToFirstByteTimeout$ = EMPTY; + if (isFinite(maxTimeToFirstByteMs) && maxTimeToFirstByteMs > 0) { + timeToFirstByteTimeout$ = merge(onprogress$, onreadystate$).pipe(take(1), timeout(context.extendMaxTTFB > 0 ? context.extendMaxTTFB : maxTimeToFirstByteMs), switchMap(() => EMPTY)); + } + let totalLoadTimeout$ = EMPTY; + if (isFinite(maxLoadTimeMs) && maxLoadTimeMs > 0) { + totalLoadTimeout$ = onreadystate$.pipe(filter((req) => req.readyState >= 4), take(1), timeout(maxLoadTimeMs), switchMap(() => EMPTY)); + } + let onProgressCb$ = EMPTY; + if (context.onProgress) { + onProgressCb$ = merge(of(xhr), onprogress$) // Emit on subscribe and then on every 'onprogress' event + .pipe(map((xhrReq) => { + const { getData, cb } = context.onProgress; + return cb(context.url, xhrReq.status, stats, getData ? xhrReq.response : undefined); + }), takeWhile((done) => !done, true)) + .pipe(switchMapTo(EMPTY)); + } + const sub = merge(onprogress$.pipe(switchMap(() => EMPTY)), onreadystate$, timeToFirstByteTimeout$, totalLoadTimeout$, onProgressCb$) + .pipe(filter((req) => req.readyState >= 4), take(1), switchMap((req) => { + stats.complete = true; + if (req.status >= 200 && req.status < 300) { + stats.tload = performance.now(); + stats.contentType = req.getResponseHeader('Content-Type'); + if (loadConfig.reportCDNServer) { + stats.cdnServer = req.getResponseHeader('CDN-Server'); + } + stats.contentLength = loadConfig.forceContentLenCheckIfNoHeader ? getContentLength(req) : null; // forceContentLenCheckIfNoHeader is true only for non-browser platforms + _relateServerInstanceInfoToRequest(req, context); + if (context.responseType === 'arraybuffer') { + stats.loaded = req.response.byteLength; + } + else { + stats.loaded = req.responseText.length; + } + stats.total = stats.loaded; + if (context.checkContentLength && // checkContentLength is true only when loading fragment + (stats.total === 0 || (isFiniteNumber(stats.contentLength) && stats.total != stats.contentLength))) { + throw new GenericNetworkError('Network error', req.status); + } + const res = [req, stats]; + return scheduled(of(res), queueScheduler); + } + else { + throw new GenericNetworkError('Network error', req.status); + } + }), catchError((err) => { + if (err instanceof TimeoutError) { + throw new GenericTimeoutError(err.message, 0, stats); + } + if (!(err instanceof GenericNetworkError)) { + throw new GenericNetworkError(err.message, 0); + } + throw err; + })) + .subscribe(subscriber); + // Setup XHR request + const { url, method, byteRangeOffset, responseType, body } = context; + if (context.mimeType) { + xhr.overrideMimeType(context.mimeType); + } + try { + const xhrSetup = context.xhrSetup; + if (xhrSetup) { + try { + xhrSetup(xhr, url); + } + catch (e) { + // fix xhrSetup: (xhr, url) => {xhr.setRequestHeader("Content-Language", "test");} + // not working, as xhr.setRequestHeader expects xhr.readyState === OPEN + xhr.open(method, context.url, true); + xhrSetup(xhr, context.url); + } + } + if (!xhr.readyState) { + xhr.open(method, context.url, true); + } + } + catch (e) { + // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS + throw new GenericNetworkError(e.message, xhr.status); + } + xhr.responseType = responseType; + // Set headers + if (byteRangeOffset && isFiniteNumber(byteRangeOffset.start) && isFiniteNumber(byteRangeOffset.end) && byteRangeOffset.start >= 0 && byteRangeOffset.end > byteRangeOffset.start) { + const { start, end } = byteRangeOffset; + xhr.setRequestHeader('Range', `bytes=${start}-${end - 1}`); + } + if (context.headers) { + for (const [name, value] of Object.entries(context.headers)) { + xhr.setRequestHeader(name, value); + } + } + // Start request + if (method === 'POST' && body) { + xhr.send(body); + } + else { + xhr.send(); + } + return () => { + xhr.abort(); + sub.unsubscribe(); + }; + }); + } + function _relateServerInstanceInfoToRequest(xhr, context) { + if (context.collectServerInstanceInfo) { + context.serverInstanceInfo = {}; + context.collectServerInstanceInfo.forEach((header) => { + const headerValue = xhr.getResponseHeader(header); + if (headerValue) { + context.serverInstanceInfo[header] = headerValue; + } + }); + } + } + + const loggerName$7 = { name: 'CustomUrlLoader' }; + class CustomUrlLoader { + constructor(loaderService) { + this.loaderService = loaderService; + this.requestMap = {}; + this.logger = getLogger(); + } + load(context, loadConfig) { + return new Observable((observer) => { + const url = context.url; + const { maxTimeToFirstByteMs } = loadConfig; + const stats = { + trequest: performance.now(), + tfirst: NaN, + tload: NaN, + loaded: 0, + total: NaN, + complete: false, + }; + const request = (this.requestMap[url] = new AsyncSubject()); + const source = request.pipe(timeout(context.extendMaxTTFB > 0 ? context.extendMaxTTFB : maxTimeToFirstByteMs), switchMap((response) => { + this.logger.info(loggerName$7, `loaded originalUri=${redactUrl(url)} uri=${redactUrl(response.uri)} durationMs=${performance.now() - stats.trequest}`); + stats.tfirst = performance.now(); + return this.handleExternalResponse(response, context, loadConfig, stats); + }), catchError((err) => { + if (err instanceof TimeoutError) { + throw new GenericTimeoutError(err.message, 0, stats); + } + throw err; + }), finalize$1(() => { + this.requestMap[url] = undefined; + this.loaderService.removeUnresolvedUriLoading(url); + })); + this.logger.info(loggerName$7, `loading originalUri=${redactUrl(url)}`); + if (context.onProgress) { + context.onProgress.cb(url, 0, stats, undefined); + } + const sub = source.subscribe(observer); + this.loaderService.createUnresolvedUriLoading(url, context.responseType, navigator.userAgent); + return () => { + sub.unsubscribe(); + this.requestMap[url] = undefined; + }; + }); + } + setCustomUrlResponse(url, response) { + const source = this.requestMap[url]; + if (source) { + source.next(response); + source.complete(); + this.requestMap[url] = undefined; + } + } + handleExternalResponse(data, context, loadConfig, stats) { + stats.tload = performance.now(); + const status = data.response.status || 200; + // http status of 200 to 299 are all successfull + if (status >= 200 && status < 300) { + if (context.responseType === 'arraybuffer' && data.response.data instanceof ArrayBuffer) { + stats.loaded = data.response.data.byteLength; + } + else { + stats.loaded = data.response.data.toString().length; + } + stats.total = stats.loaded; + stats.complete = true; + return scheduled(of({ status, data, stats }), queueScheduler); + } + else if (isRedirectStatusCode(status)) { + this.logger.info(loggerName$7, `redirect status=${status} url=${redactUrl(data.response.uri)}`); + return this.redirectRequest(data.response.uri, context, loadConfig, stats); + } + else { + this.logger.warn(loggerName$7, `unable to load custom url > uri=${redactUrl(data.response.uri)}, status=${status}`); + return throwError(new GenericNetworkError('Unable to load custom url', status)); + } + } + redirectRequest(uri, context, loadConfig, stats) { + const { maxLoadTimeMs, maxTimeToFirstByteMs } = loadConfig; + const updatedMaxLoadTimeMs = maxLoadTimeMs - (performance.now() - stats.trequest); // Recalculate timeout based on request time + const updatedMaxTimeToFirstByteMs = context.extendMaxTTFB > 0 ? context.extendMaxTTFB : maxTimeToFirstByteMs - (performance.now() - stats.trequest); // Recalculate timeout based on request time + const newConfig = Object.assign(Object.assign({}, loadConfig), { maxLoadTimeMs: updatedMaxLoadTimeMs, maxTimeToFirstByteMs: updatedMaxTimeToFirstByteMs }); + const newContext = Object.assign(Object.assign({}, context), { url: uri }); + if (updatedMaxLoadTimeMs <= 0 || updatedMaxTimeToFirstByteMs <= 0) { + return throwError(new TimeoutError()); + } + return fromXMLHttpRequest(newContext, newConfig).pipe(map(([xhr, sample]) => { + const { responseURL, status } = xhr; + const uri = responseURL || ''; + const data = { + uri, + response: { + status: status, + uri, + data: xhr.response, + }, + }; + stats.loaded = stats.total = sample.loaded; + stats.tload = performance.now(); + stats.complete = true; + return { status: xhr.status, data, stats }; + })); + } + } + let loader; + function getCustomUrlLoader(loaderService) { + if (!loader) { + const service = loaderService || getLoaderService(); + loader = new CustomUrlLoader(service); + } + return loader; + } + + function fromUrlArrayBuffer(context, loadConfig) { + const ctx = Object.assign(Object.assign({}, context), { method: 'GET', responseType: 'arraybuffer' }); + const customUrlLoader = getCustomUrlLoader(); + return isCustomUrl(ctx.url) + ? customUrlLoader.load(ctx, loadConfig).pipe(map((res) => [res.data.response.data, res.stats, ctx.serverInstanceInfo])) + : fromXMLHttpRequest(ctx, loadConfig).pipe(map(([xhr, bwSample]) => [xhr.response, bwSample, ctx.serverInstanceInfo])); + } + + /** + * Generic load utils for retry and such + */ + function getLoadConfig(loadable, policy) { + return !loadable.url || isCustomUrl(loadable.url) ? policy.customURL : policy.default; + } + function getRetryConfig(error, config) { + if (error instanceof HlsNetworkError) { + return error.isTimeout ? config.timeoutRetry : config.errorRetry; + } + return null; + } + /** + * Operator for converting TimeoutError & GenericNetworkError into ManifestNetworkError + */ + function convertToManifestNetworkError(fatal) { + return (source) => source.pipe(catchError((err) => { + if (err instanceof GenericTimeoutError) { + throw new ManifestNetworkError(fatal, 'Timeout', 0, ErrorResponses.ManifestTimeoutError, true); + } + else if (err instanceof GenericNetworkError) { + throw new ManifestNetworkError(fatal, err.message, err.code, { code: err.code, text: 'Manifest network error' }, false); + } + throw err; + })); + } + /** + * Operator for converting TimeoutError & GenericNetworkError into PlaylistNetworkError + */ + function convertToPlaylistNetworkError(mediaOptionType, mediaOptionId, fatal, url) { + return (source) => source.pipe(catchError((err) => { + if (err instanceof GenericTimeoutError) { + throw new PlaylistNetworkError(fatal, 'Timeout', 0, ErrorResponses.PlaylistTimeoutError, true, mediaOptionType, mediaOptionId, url); + } + else if (err instanceof GenericNetworkError) { + throw new PlaylistNetworkError(fatal, err.message, err.code, { code: err.code, text: 'Playlist Network Error' }, false, mediaOptionType, mediaOptionId, url); + } + throw err; + })); + } + /** + * Operator for converting TimeoutError & GenericNetworkError into FragmentError + */ + function convertToFragmentNetworkError(frag, fatal) { + return (source) => source.pipe(catchError((err) => { + if (err instanceof GenericTimeoutError) { + throw new FragmentNetworkError(fatal, 'Timeout', 0, ErrorResponses.FragmentTimeoutError, true, frag, err.stats); + } + else if (err instanceof GenericNetworkError) { + throw new FragmentNetworkError(fatal, err.message, err.code, { code: err.code, text: 'Fragment Network Error' }, false, frag); + } + throw err; + })); + } + /** + * Helper function to update playtype of levels + */ + function updatePlaylistAttributes(levelDetails) { + const playlistTypeString = levelDetails.type; + const isLive = levelDetails.liveOrEvent; + let playlistType = 'VOD'; + if (playlistTypeString === 'EVENT' && isLive) { + playlistType = 'EVENT'; + } + else if ((!playlistTypeString || playlistTypeString.length === 0 || playlistTypeString === 'LIVE') && isLive) { + playlistType = 'LIVE'; + } + if (levelDetails.type !== playlistType) { + getLogger().info(`Playlist type updated from ${levelDetails.type} to ${playlistType}`); + levelDetails.type = playlistType; + } + } + + /** + * 2018 Apple Inc. All rights reserved. + */ + const PlayReadySecurityLevels = { + SL2000: 0, + SL3000: 1, + }; + const PlayReadyKeySystemProperties = { + id: 'playready', + systemStringPrefix: 'com.microsoft.playready', + keyFormatString: 'com.microsoft.playready', + securityLevels: PlayReadySecurityLevels, + }; + + /** + * 2018 Apple Inc. All rights reserved. + */ + const WidevineSecurityLevels = { + WIDEVINE_SOFTWARE: 0, + WIDEVINE_HARDWARE: 1, + }; + const WidevineKeySystemProperties = { + id: 'widevine', + systemStringPrefix: 'com.widevine.alpha', + keyFormatString: 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed', + securityLevels: WidevineSecurityLevels, + }; + + /* + * Utilities for numeric encodings + * + * 2018 Apple Inc. All rights reserved. + */ + function base64ToBase64Url(base64encodedStr) { + return base64encodedStr.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''); + } + class BrowserNumericEncodingUtils { + static strToBase64Encode(str) { + return btoa(str); + } + static base64DecodeToStr(str) { + return atob(str); + } + static base64Encode(input) { + return btoa(String.fromCharCode(...input)); + } + static base64UrlEncode(input) { + return base64ToBase64Url(BrowserNumericEncodingUtils.base64Encode(input)); + } + static base64Decode(base64encodedStr) { + return Uint8Array.from(atob(base64encodedStr), (c) => c.charCodeAt(0)); + } + } + class NodeJSNumericEncodingUtils { + static strToBase64Encode(str) { + return global$1.Buffer.from(str).toString('base64'); + } + static base64DecodeToStr(str) { + return global$1.Buffer.from(str, 'base64').toString(); + } + static base64Encode(input) { + return global$1.Buffer.from(input).toString('base64'); + } + static base64UrlEncode(input) { + return base64ToBase64Url(NodeJSNumericEncodingUtils.base64Encode(input)); + } + static base64Decode(base64encodedStr) { + const buffer = global$1.Buffer.from(base64encodedStr, 'base64'); + return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); + } + } + const NumericEncodingUtils = typeof global$1.Buffer !== 'undefined' ? NodeJSNumericEncodingUtils : BrowserNumericEncodingUtils; + var NumericEncodingUtils$1 = NumericEncodingUtils; + + /* + * Utilities for key systems + * + * 2018 Apple Inc. All rights reserved. + */ + // Map of prefix to mimeType + const kVideoCodecToMimeType = { + // AVC + avc1: 'video/mp4', + avc3: 'video/mp4', + dvav: 'video/mp4', + dva1: 'video/mp4', + // HEVC + hev1: 'video/mp4', + hvc1: 'video/mp4', + dvh1: 'video/mp4', + dvhe: 'video/mp4', // Dolby vission + }; + const kAudioCodecToMimeType = { + mp4a: 'audio/mp4', + 'ac-3': 'audio/mp4', + 'ec-3': 'audio/mp4', + }; + function isMediaKeySystemConfig(config) { + return config && typeof config === 'object'; // requestMediaKeySystemAccess accepts {} + } + // Input: set of codec strings for each type + // Output: + // { + // videoCapabilities: [ + // { contentType: 'video/mp4;codecs=avc.###', robustness: '' } ], + // audioCapabilities: [] + // } + function getMediaKeysystemMediaCapability(videoCodecs, audioCodecs) { + const result = { + videoCapabilities: [], + audioCapabilities: [], + }; + if (videoCodecs) { + videoCodecs.forEach((videoCodec) => { + const prefix = videoCodec.split('.')[0].trim(); + if (prefix in kVideoCodecToMimeType) { + result.videoCapabilities.push({ + contentType: kVideoCodecToMimeType[prefix] + ';codecs=' + videoCodec, + robustness: '', + }); + } + }); + } + if (audioCodecs) { + audioCodecs.forEach((audioCodec) => { + const prefix = audioCodec.split('.')[0].trim(); + if (prefix in kAudioCodecToMimeType) { + result.audioCapabilities.push({ + contentType: kAudioCodecToMimeType[prefix] + ';codecs=' + audioCodec, + robustness: '', + }); + } + }); + } + return result; + } + /** + * Utility to change the endianness of Key ID + * @param keyID uint8array representing the keyId + * @returns uint8array the keyId after changing the endianness + */ + function changeEndianness(keyId) { + // eslint-disable-next-line func-style + const swap = function (array, from, to) { + const cur = array[from]; + array[from] = array[to]; + array[to] = cur; + }; + swap(keyId, 0, 3); + swap(keyId, 1, 2); + swap(keyId, 4, 5); + swap(keyId, 6, 7); + } + /** + * Generate key id from an arbitrary string + * @param str String to convert into a 16 byte key + * @returns uint8array representing the keyId + */ + function getKeyIdBytes(str) { + const keyIdbytes = BufferUtils.strToUtf8array(str).subarray(0, 16); + const paddedkeyIdbytes = new Uint8Array(16); + paddedkeyIdbytes.set(keyIdbytes, 16 - keyIdbytes.length); + return paddedkeyIdbytes; + } + /** + * @param URI string + * @returns Uint8Array of URI data + */ + function convertDataUriToArrayBytes(uri) { + // data:[ + const colonsplit = uri.split(':'); + let keydata = null; + if (colonsplit[0] === 'data' && colonsplit.length === 2) { + const semicolonsplit = colonsplit[1].split(';'); + const commasplit = semicolonsplit[semicolonsplit.length - 1].split(','); + if (commasplit.length === 2) { + const isbase64 = commasplit[0] === 'base64'; + const data = commasplit[1]; + if (isbase64) { + semicolonsplit.splice(-1, 1); // remove from processing + keydata = NumericEncodingUtils$1.base64Decode(data); + } + else { + keydata = getKeyIdBytes(data); + } + } + } + return keydata; + } + /** + * Generate 'keyids' init data from an array of key ids + * @param keyIds Array of key ids represented as uint8array[16] objects + * @returns The initData string to pass to generateRequest as part of EME + */ + function makeKeyIdsInitData(keyIds) { + const initDataObj = { + kids: keyIds.map(NumericEncodingUtils$1.base64UrlEncode), + }; + // Convert string to utf-8 array + return BufferUtils.strToUtf8array(JSON.stringify(initDataObj)); + } + // parse pssh list and convert to dictionary: + function parsePSSHList(psshList) { + const dv = new DataView(psshList); + let whichByte = 0; + const pssh = {}; // PSSH: systemID => data + while (whichByte < dv.buffer.byteLength) { + const thisBox = whichByte; + const boxSize = dv.getUint32(whichByte); + whichByte += 4; + const nextBox = thisBox + boxSize; + if (dv.getUint32(whichByte) !== 1886614376) { + whichByte = nextBox; + continue; // next box + } + whichByte += 4; + const version = dv.getUint8(whichByte); + switch (version) { + case 0: // NO KEY IDS + case 1: + whichByte += 1; + break; + default: + whichByte = nextBox; + break; + } + whichByte += 3; // flags + // UUID: 4 bytes - 2 bytes - 2 bytes - 2 bytes - 6 bytes + let systemID = ''; + // 16 bytes + for (let i = 0; i < 16; ++i, ++whichByte) { + systemID += dv.getUint8(whichByte).toString(16); + switch (i) { + case 4: + case 6: + case 8: + case 10: + systemID += '-'; + break; + } + } + whichByte += 4; // Data size + pssh[systemID] = dv.buffer.slice(thisBox, nextBox); + } + return pssh; + } + const keysystemutil = { + getCapabilities: getMediaKeysystemMediaCapability, + changeEndianness, + getKeyIdBytes, + convertDataUriToArrayBytes, + makeKeyIdsInitData, + parsePSSHList, + }; + + /* + * Decrypt data + * + * 2018 Apple Inc. All rights reserved. + */ + // Note that this will not get copied into Worker + let keyUriToKeyIdMap = {}; + // Created in playlist-loader, modified in demux / remux + class DecryptData { + /** + * @param method From METHOD attribute, mandatory + * @param uri Absolute url of the key (calculated from URI) + * @param iv 128-bit unsigned int representing Initialization Vector, used when KEYFORMAT="identity", optional + * @param format From KEYFORMAT, optional with default value of "identity" + * @param formatversions Array From KEYFORMATVERSION, an array of unsigned int, optional + */ + constructor(method, uri, iv, format, formatversions) { + this.method = method; + this.uri = uri; + this.iv = iv; + this.format = format; + this.formatversions = formatversions; + this.isEncrypted = this.method && this.method !== 'NONE'; + if (!this.formatversions || this.formatversions.length === 0) { + this.formatversions = [1]; + } + // Set later + this.key = undefined; + this.keyId = undefined; + if (!this.isEncrypted) { + return; + } + // Initialize keyId if possible + const keyBytes = keysystemutil.convertDataUriToArrayBytes(this.uri); + if (keyBytes) { + switch (format) { + case PlayReadyKeySystemProperties.keyFormatString: { + // Playready + this.pssh = keyBytes; + const keyBytesUtf16 = new Uint16Array(keyBytes.buffer, keyBytes.byteOffset, keyBytes.byteLength / 2); + const keyByteStr = String.fromCharCode.apply(null, Array.from(keyBytesUtf16)); + // we got entire PSSH data. Incase of Playready it's WRMHEADER XML object. Parse it. + const xmlKeyBytes = keyByteStr.substring(keyByteStr.indexOf('<'), keyByteStr.length); + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(xmlKeyBytes, 'text/xml'); + const keyData = xmlDoc.getElementsByTagName('KID')[0]; + if (keyData) { + let keyId = null; + if (keyData.childNodes[0]) { + keyId = keyData.childNodes[0].nodeValue; + } + else { + keyId = keyData.getAttribute('VALUE'); + } + if (keyId) { + const keyIdArray = NumericEncodingUtils$1.base64Decode(keyId).subarray(0, 16); + // KID value in PRO is a base64-encoded little endian GUID interpretation of UUID + // KID value in Ãĸâ‚Ŧ˜tencÃĸâ‚Ŧâ„ĸ is a big endian UUID GUID interpretation of UUID + keysystemutil.changeEndianness(keyIdArray); + this.keyId = keyIdArray; + } + } + break; + } + case WidevineKeySystemProperties.keyFormatString: { + // Widevine + this.pssh = keyBytes; + // In case of widevine keyID is embedded in PSSH box. Read Key ID. + if (keyBytes.length >= 22) { + this.keyId = keyBytes.subarray(keyBytes.length - 22, keyBytes.length - 6); + } + break; + } + default: { + // default handling + let keydata = keyBytes.subarray(0, 16); + if (keydata.length !== 16) { + const padded = new Uint8Array(16); + padded.set(keydata, 16 - keydata.length); + keydata = padded; + } + this.keyId = keydata; + break; + } + } + } + // Default behavior + if (!this.keyId || this.keyId.byteLength !== 16) { + let keyId = keyUriToKeyIdMap[this.uri]; + if (!keyId) { + const val = Object.keys(keyUriToKeyIdMap).length % Number.MAX_SAFE_INTEGER; + // MAX_SAFE_INTEGER is huge (9007199254740991) so this /should/ be safe... + keyId = new Uint8Array(16); + const dv = new DataView(keyId.buffer, 12, 4); // Just set the last 4 bytes + dv.setUint32(0, val); + keyUriToKeyIdMap[this.uri] = keyId; + } + this.keyId = keyId; + } + } + get keyTagInfo() { + const { method, isEncrypted, uri, iv, keyId, key, format, formatversions } = this; + const keyTagInfo = { method, isEncrypted, uri, iv, keyId, key, format, formatversions }; + return keyTagInfo; + } + static clearKeyUriToKeyIdMap() { + keyUriToKeyIdMap = {}; + } + } + + var KeyRequestState; + (function (KeyRequestState) { + KeyRequestState["NONE"] = "NONE"; + KeyRequestState["GET_REQUEST_INFO"] = "GET_REQUEST_INFO"; + KeyRequestState["GET_CHALLENGE"] = "GET_CHALLENGE"; + KeyRequestState["GET_KEY_RESPONSE"] = "GET_KEY_RESPONSE"; + KeyRequestState["PROCESS_LICENSE"] = "PROCESS_LICENSE"; + })(KeyRequestState || (KeyRequestState = {})); + // Wrap subscription and teardown of MediaKeySession callbacks + class MediaKeySessionContext { + constructor(session, onkeystatuseschange, onkeymessage, logger) { + this.session = session; + this.onkeystatuseschange = onkeystatuseschange; + this.onkeymessage = onkeymessage; + this.logger = logger; + this.isClosing$ = new BehaviorSubject(false); + this.closed$ = new BehaviorSubject(false); + const target = fromEventTarget(this.session); + target.listen('keystatuseschange', this.isClosing$.pipe(filter((x) => x === true)), this.onkeystatuseschange); + // Message is weird because we still want the message until after close() + target.listen('message', this.closed$.pipe(filter((x) => x === true)), this.onkeymessage); + } + get isClosing() { + return this.isClosing$.value; + } + get isClosed() { + return this.closed$.value; + } + /** + * Remove and close all keys in MediaKeySession + */ + destroy() { + this.logger.info(`[Keys] : remove licenses & keys for session : ${this.session.sessionId} and close it`); + this.isClosing$.next(true); + const session = this.session; + // Unabortable section. Should execute no matter what. + return from(session + .remove() + .catch((error) => { + this.logger.info(`Could not remove session: ${error.message}`); + }) + .then(() => { + return session.close(); + }) + .catch((error) => { + this.logger.info(`Could not close session: ${error.message}`); + })).pipe(tap(() => { + this.isClosing$.next(false); + this.closed$.next(true); + }), finalize$1(() => { + this.isClosing$.next(false); + this.closed$.next(true); + })); + } + } + /** + * @brief KeyContext keeps track of the current key request state and information about a given key. + * + * A key may exist without a key request being in progress. When a key request is in progress, there are + * multiple phases / states. Each state of a key request is asynchronous and can be completed either by + * the CDM or by the client. If we get out of sync with the current key request state, we will throw an error + * and all subscribers will be notified. We will also throw an error if aborted in the middle of the request. + * Note that subscribers will not get the abort error if they unsubscribe from the observable. + */ + class KeyContext { + constructor(decryptdata, session = null) { + this.decryptdata = decryptdata; + this._requestState$ = new BehaviorSubject(KeyRequestState.NONE); // Key request state. Note this is different from keystatus from CDM + this.destroy$ = new Subject(); // Destroy key. This should stop any renewal timers + // If in progress, the current observable + this.currentObservable = null; + this.session = null; // Current session. Could be shared by others (config.useMultipleKeySessions !== true) + this.oldSessions = []; + this.session = session; + } + get requestState() { + return this._requestState$.value; + } + get onKeyRequestState$() { + return this._requestState$; + } + destroy() { + this.destroy$.next(); + // TODO actual cleanup? + } + abort() { + if (this.requestState !== KeyRequestState.NONE) { + const err = new KeyRequestError('Aborted', this.decryptdata.uri, 0, ErrorResponses.KeySystemAbort, true, KeyRequestErrorReason.Abort); + this.error(err); + } + } + /** + * Change state and return observable that gets completed when resolveState is called + * + * @param state The state to switch to + */ + setKeyRequestState(state) { + if (this.currentObservable) { + const err = new KeyRequestError(`Unexpected state transition ${this.requestState}->${state}`, this.decryptdata.uri, 0, ErrorResponses.KeySystemUnexpectedStateTransition, true, KeyRequestErrorReason.InvalidState); + this.error(err); + } + this._requestState$.next(state); + const returnVal = new AsyncSubject(); + if (state === KeyRequestState.NONE) { + returnVal.complete(); + this.currentObservable = null; + } + else { + //@ts-ignore + this.currentObservable = returnVal; + } + return returnVal; + } + /** + * Resolve current state observable + * @param state State to resolve + * @param value The value to resolve current observable with + */ + resolveState(state, value) { + if (!this.currentObservable) { + return; + } + if (state !== this.requestState) { + const err = new KeyRequestError(`Unexpected state ${this.requestState} != ${state}`, this.decryptdata.uri, 0, ErrorResponses.KeySystemUnexpectedState, true, KeyRequestErrorReason.InvalidState); + this.error(err); + return; + } + if (value instanceof Error) { + this.error(value); + } + else { + const obs = this.currentObservable; + this.currentObservable = null; + obs.next(value); + obs.complete(); + } + } + /** + * Signal error for this key. Could be due to key request or some other internal error from CDM + * @param err The error + */ + error(err) { + if (this.currentObservable) { + const obs = this.currentObservable; + this.currentObservable = null; + obs.error(err); + } + this.setKeyRequestState(KeyRequestState.NONE); + // TODO: any other cleanup ? + } + } + + /* + * Base class for key systems + * + * 2018 Apple Inc. All rights reserved. + */ + const MAX_CERT_LOAD_TIME_MS = 10000; // Maximum time for loading the certificate + function printKeyTag(tag) { + return `uri=${redactUrl(tag.uri)} keyId=${Hex$1.hexDump(tag.keyId)}`; + } + class KeySystem { + constructor(mediaKeys, systemString, config, eventEmitter, useSingleKeySession, sessionHandler, logger) { + this.mediaKeys = mediaKeys; + this.systemString = systemString; + this.config = config; + this.eventEmitter = eventEmitter; + this.useSingleKeySession = useSingleKeySession; + this.sessionHandler = sessionHandler; + this.logger = logger; + this.destroy$ = new Subject(); + this.setCert = false; // Has set cert on MediaKeySession + this.certificate$ = new BehaviorSubject(null); + // This event will be signalled when a renewal request is needed or if an error occurs. + // The key system will not auto renew. Instead client is expected to call startKeyRequest + this._keyStatusChange$ = new Subject(); + this.shouldDestroyMediaKeys = false; + // TJH: will playingItem raise a license challenge ? + //this.itemId = hls.loadingItem?.itemId || ''; + this.itemId = ''; + this.sessions = []; + this.keyIdToKeyInfo = {}; + this.keyUriToKeyInfo = {}; + this.sessionIdToKeyUri = {}; + this.onkeystatuseschange = this.handleKeyStatusesChange.bind(this); + this.onkeymessage = this.handleKeyMessage.bind(this); + } + get keyStatusChange$() { + return this._keyStatusChange$; + } + destroy() { + this.isDestroying = true; + this.destroy$.next(); + for (const info of Object.values(this.keyIdToKeyInfo)) { + this._abortKeyRequest(info); + } + // Remove sessions + const destroyPromises = this.sessions.map((ctx) => ctx.destroy()); + const p = iif(() => destroyPromises.length === 0, VOID, forkJoin(destroyPromises)).pipe(mapTo(undefined), finalize$1(() => { + this.mediaKeys = undefined; + this.keyIdToKeyInfo = {}; + this.keyUriToKeyInfo = {}; + this.sessionIdToKeyUri = {}; + })); + DecryptData.clearKeyUriToKeyIdMap(); + return p; + } + /** + * @param certificate Used for generating challenge + * @returns {Promise} Fired when non-null certificate has been set on the object. + */ + setServerCertificate(certificate = null) { + this.logger.info(this.systemString + ' setServerCertificate(' + (certificate ? 'nonnull' : 'null') + ')'); + if (!this.needsCert) { + return of(true); + } + if (certificate) { + this.certificate$.next(certificate); + } + const waitForCert$ = waitFor(this.certificate$, (x) => x != null).pipe(timeout(MAX_CERT_LOAD_TIME_MS)); + return waitForCert$.pipe(switchMap((cert) => { + if (this.setCert) { + return of(true); + } + if (!this.setCertSubject || this.setCertSubject.isStopped) { + this.setCertSubject = new AsyncSubject(); + return from(this.mediaKeys.setServerCertificate(cert)).pipe(tap((v) => { + // Sometimes the promise returned by the CDM doesn't carry boolean + // This will cause playback failure. + const certStatus = v !== undefined ? v : true; + this.setCert = certStatus; + this.setCertSubject.next(certStatus); + this.setCertSubject.complete(); + }), catchError((err) => { + this.logger.info('Failed setServerCertificate'); + this.setCert = false; + this.setCertSubject.error(err); + return VOID; + }), switchMap(() => { + return this.setCertSubject; + })); + } + return this.setCertSubject; + }), catchError((err) => { + this.logger.info(`setServerCertificate err=${err.message}`); + throw err; + })); + } + ensureKeyContext(decryptdata) { + const keyuri = decryptdata.uri; + if (!this.keyUriToKeyInfo[keyuri]) { + this.keyUriToKeyInfo[keyuri] = new KeyContext(decryptdata); + } + const keyInfo = this.keyUriToKeyInfo[keyuri]; + if (keyInfo.session) { + return keyInfo; + } + if (this.useSingleKeySession && this.sessions.length > 0) { + keyInfo.session = this.sessions[0].session; + return keyInfo; + } + this.logger.info(`${this.systemString} createSession`); + const session = this.mediaKeys.createSession(); + if (session) { + this.sessions.push(new MediaKeySessionContext(session, this.onkeystatuseschange, this.onkeymessage, this.logger)); + } + else { + this.logger.info(`${this.systemString} FAIL: could not create MediaKeysSession`); + } + keyInfo.session = session; + return keyInfo; + } + /** + * Start a key request. called from key-system controller or internally on renewal. + * + * @param decryptdata DecryptData object from EXT-X-KEY + * @returns Promise (decryptdata) + */ + startKeyRequest(decryptdata) { + const keyuri = decryptdata.uri; + const keyInfo = this.ensureKeyContext(decryptdata); + const session = keyInfo === null || keyInfo === void 0 ? void 0 : keyInfo.session; + if (!session) { + return throwError(new KeySystemError('Could not create key session', decryptdata.uri, 0, ErrorResponses.KeySystemFailedToCreateSession, this.systemString)); + } + const keyIdStr = BufferUtils.utf8arrayToStr(decryptdata.keyId); + this.keyIdToKeyInfo[keyIdStr] = keyInfo; + this.logger.info(`${this.systemString} startKeyRequest ${printKeyTag(decryptdata)} state=${keyInfo.requestState}`); + this.logger.qe({ critical: true, name: 'startKeyRequest', data: { uri: keyuri, keyId: keyIdStr } }); + return forkJoin([this.getKeyRequestInfo(keyInfo), this.setServerCertificate()]).pipe(map((values) => values[0]), switchMap((requestInfo) => { + var _a; + (_a = this.sessionHandler) === null || _a === void 0 ? void 0 : _a.licenseChallengeSubmitted({ keyuri: keyuri, keyFormat: this.systemString }); + return this.generateLicenseChallenge(keyInfo, requestInfo).pipe(catchError((error) => { + var _a; + this.logger.info(`${this.systemString} generateLicenseChallenge Failed ${error.message} ${printKeyTag(decryptdata)}`); + (_a = this.sessionHandler) === null || _a === void 0 ? void 0 : _a.licenseChallengeError({ keyuri: keyuri }); + throw error; + })); + }), switchMap((licenseChallenge) => { + var _a; + this.logger.info(`${this.systemString} challenge created ${printKeyTag(decryptdata)}`); + this.logger.qe({ critical: true, name: 'challengeCreated', data: { uri: keyuri, keyId: keyIdStr } }); + (_a = this.sessionHandler) === null || _a === void 0 ? void 0 : _a.licenseChallengeCreated({ keyuri: keyuri, cdmVersion: this.cdmVersion }); + return this.getKeyRequestResponse(keyInfo, licenseChallenge); + }), switchMap((parsedKeyResponse) => { + var _a; + this.logger.info(`${this.systemString} onKeyResponseParsed ${printKeyTag(decryptdata)}`); + this.logger.qe({ critical: true, name: 'onKeyResponseParsed', data: { uri: keyuri, keyId: keyIdStr } }); + (_a = this.sessionHandler) === null || _a === void 0 ? void 0 : _a.licenseResponseSubmitted({ keyuri: keyuri }); + return this.handleParsedKeyResponse(keyInfo, parsedKeyResponse).pipe(catchError((error) => { + var _a; + this.logger.info(`${this.systemString} ParseKeyResponse Failed ${printKeyTag(decryptdata)} error=${error.message}`); + (_a = this.sessionHandler) === null || _a === void 0 ? void 0 : _a.licenseResponseError({ keyuri: keyuri }); + throw error; + })); + }), map(() => { + var _a; + this.logger.info(`${this.systemString} New usable key: ${printKeyTag(decryptdata)} CDMVersion=${this.cdmVersion}`); + this.logger.qe({ critical: true, name: 'newUsableKey', data: { uri: keyuri, keyId: keyIdStr } }); + (_a = this.sessionHandler) === null || _a === void 0 ? void 0 : _a.licenseResponseProcessed({ keyuri: keyuri }); + keyInfo.setKeyRequestState(KeyRequestState.NONE); + this.removeSessions(keyInfo.decryptdata, false).subscribe(); + return decryptdata; // Resolve + }), catchError((err) => { + this.handleKeyExchangeError(keyInfo, err); + throw err; + }), + // takeUntil(this.destroy$), + finalize$1(() => { + this._abortKeyRequest(keyInfo); + })); + } + /** + * Internal cleanup of key request + * @param keyInfo The key request to abort + */ + _abortKeyRequest(keyInfo) { + var _a; + if (keyInfo) { + const keyuri = keyInfo.decryptdata.uri; + const keyIdStr = BufferUtils.utf8arrayToStr(keyInfo.decryptdata.keyId); + if (keyInfo.requestState !== KeyRequestState.NONE) { + this.logger.info(`Aborting key ${redactUrl(keyuri)} state=${keyInfo.requestState}`); + this.logger.qe({ critical: true, name: 'keyAborted', data: { uri: keyuri, keyId: keyIdStr } }); + (_a = this.sessionHandler) === null || _a === void 0 ? void 0 : _a.keyAborted({ keyuri }); + } + keyInfo.abort(); + } + } + // Do cleanup if needed + handleKeyExchangeError(keyInfo, err) { + keyInfo.error(err); // Mark as error so we don't erroneously report abort + const keyuri = keyInfo.decryptdata.uri; + const keyIdStr = BufferUtils.utf8arrayToStr(keyInfo.decryptdata.keyId); + this.logger.qe({ critical: true, name: 'keyExchangeError', data: { uri: keyuri, keyId: keyIdStr, errMsg: err.message } }); + } + updateItemId(itemId) { + // Update the itemId to which the key belongs to. The license release message carries this info. + // When you generate challenge this itemId was being used. + this.itemId = itemId; + } + /** + * Remove a key from the keysystem + * @param decryptdata + */ + removeKey(decryptdata) { + return this.removeKeyInternal(decryptdata); + } + removeKeyInternal(decryptdata) { + this.logger.info(`removing key ${redactUrl(decryptdata.uri)}`); + const keyInfo = this.keyUriToKeyInfo[decryptdata.uri]; + if (keyInfo && keyInfo.session) { + const session = keyInfo.session; + keyInfo.abort(); + keyInfo.destroy(); + const keyIdStr = BufferUtils.utf8arrayToStr(decryptdata.keyId); + this.keyIdToKeyInfo[keyIdStr] = undefined; + this.keyUriToKeyInfo[decryptdata.uri] = undefined; + return this.removeSession(session); + } + } + removeSessions(decryptdata, shouldRemoveCurrentSession) { + const keyInfo = this.keyUriToKeyInfo[decryptdata.uri]; + if (keyInfo) { + // Remove all previous sessions + const oldRemoves = keyInfo.oldSessions.map((session) => { + return this.removeSession(session); + }); + keyInfo.oldSessions = []; + return iif(() => oldRemoves.length === 0, VOID, forkJoin(oldRemoves)).pipe(switchMap(() => { + if (shouldRemoveCurrentSession) { + // Finally remove the current session + return this.removeKeyInternal(decryptdata); + } + return VOID; + })); + } + return VOID; + } + removeSession(session) { + this.logger.info(`remove session ${session.sessionId}`); + const index = this.sessions.findIndex((sessionCtx) => { + return sessionCtx.session === session; + }); + const sessionCtx = this.sessions[index]; + if (index > -1) { + this.sessions.splice(index, 1); + } + this.sessionIdToKeyUri[session.sessionId] = undefined; + if (sessionCtx) { + return sessionCtx.destroy(); + } + return VOID; + } + getKeyRequestInfo(keyInfo) { + const decryptdata = keyInfo.decryptdata; + const keyuri = decryptdata.uri; + const obs = keyInfo.setKeyRequestState(KeyRequestState.GET_REQUEST_INFO); + this.eventEmitter.trigger(HlsEvent$1.KEY_REQUEST_STARTED, { keyuri: keyuri, decryptdata: decryptdata, timestamp: Date.now() }); + return obs; + } + setKeyRequestInfo(keyuri, requestInfo) { + const keyInfo = this.keyUriToKeyInfo[keyuri]; + if (!keyInfo) { + this.logger.info(`Unexpected key requested ${redactUrl(keyuri)}`); + return; + } + keyInfo.resolveState(KeyRequestState.GET_REQUEST_INFO, requestInfo); + } + sanitizeRequest(requestInfo) { + return requestInfo; + } + /** + * Generate a license challenge for the key + * @param keyInfo The key we're requesting + * @param requestInfo Additional parameters for making the key request + * @param state MediaKeyStatus for the keyId associated with keyInfo + */ + generateLicenseChallengeInternal(keyInfo, requestInfo, state) { + if (state === 'status-pending') { + this.logger.info('Request already in progress'); + } + const decryptdata = keyInfo.decryptdata; + const session = keyInfo.session; + const keyuri = decryptdata.uri; + const keyId = decryptdata.keyId; + let generateRequest$; + const getKeyResponse$ = keyInfo.setKeyRequestState(KeyRequestState.GET_CHALLENGE); + if (!session.generateRequestPromise) { + const initDataResult = this.generateInitData(keyId, decryptdata, requestInfo); + this.logger.info(`challenge create start uri=${redactUrl(keyInfo.decryptdata.uri)} versions=${JSON.stringify(keyInfo.decryptdata.formatversions)}`); + session.generateRequestPromise = session.generateRequest(initDataResult.initDataType, initDataResult.initData); + // May only be called once + generateRequest$ = scheduled(session.generateRequestPromise, queueScheduler).pipe(tap(() => { + this.sessionIdToKeyUri[session.sessionId] = keyuri; + }), catchError((reason) => { + this.logger.info(`${this.systemString} FAIL: generateRequest fail keyuri=${redactUrl(keyInfo.decryptdata.uri)} message=${reason.message}`); + throw new KeySystemError(reason.message, keyInfo.decryptdata.uri, 0, ErrorResponses.KeySystemFailedToGenerateLicenseRequest, this.systemString); + })); + } + else { + // If generateRequest was already called + generateRequest$ = scheduled(session.generateRequestPromise, queueScheduler).pipe(switchMap(() => this.generateRequestInitialized(keyInfo, state === 'usable'))); + } + return forkJoin([getKeyResponse$, generateRequest$]).pipe(map((result) => new Uint8Array(result[0]))); + } + /** + * This is different from startKeyRequest in that it could be triggered + * from an externally generated event. (Hls.generateKeyRequest) + * + * @param keyInfo Key info object + * @param requestInfo Extra information needed to make this request + */ + generateLicenseChallenge(keyInfo, requestInfo) { + const decryptdata = keyInfo.decryptdata; + const session = keyInfo.session; + const keyuri = decryptdata.uri; + const keyId = decryptdata.keyId; + const keyIdStr = BufferUtils.utf8arrayToStr(decryptdata.keyId); + this.logger.info(`${this.systemString} generateLicenseChallenge ${printKeyTag(decryptdata)}`); + this.logger.qe({ critical: true, name: 'generateLicenseChallenge', data: { uri: keyuri, keyId: keyIdStr } }); + if (keyInfo.licenseChallenge) { + // This is handling for key systems like Widevine where the license challenge for renewal is already generated and we just need to use it. + keyInfo.resolveState(KeyRequestState.GET_CHALLENGE, keyInfo.licenseChallenge); + } + requestInfo = this.sanitizeRequest(requestInfo); + keyInfo.requestInfo = requestInfo; + // In gapless mode itemId needs to be updated to the newly loading item + //this.itemId = this.hls.inGaplessMode ? this.hls.loadingItem.itemId : this.itemId; + this.sessionId = this.sessionId || (requestInfo && requestInfo.sessionId) || this.itemId; // Use first id + let state; + // If it's playready Key system we need to change the endianness of the keyid in the key status + if (this.systemString === PlayReadyKeySystemProperties.systemStringPrefix) { + // Use a different copy of KID, otherwise it will change the endianness of KID in DecryptData + // since it's a referrence + const curKid = new Uint8Array(keyId); + keysystemutil.changeEndianness(curKid); + state = session.keyStatuses.get(curKid); + } + else { + state = session.keyStatuses.get(keyId); // Keysystem state + } + let createRequestPromise; + switch (state) { + case 'status-pending': // Challenge created or key known + case 'usable': // Finished key request already, should renew + case 'expired': + case undefined: { + createRequestPromise = this.generateLicenseChallengeInternal(keyInfo, requestInfo, state); + break; + } + default: + createRequestPromise = throwError(new KeySystemError(`Bad internal state state=${state}`, keyuri, 0, ErrorResponses.KeySystemUnexpectedState, this.systemString)); + break; + } + return createRequestPromise; + } + /** + * Set the parsed license response + * @param keyuri URI of key corresponding to request + * @param parsedResponse The parsed response for the key request. Specific to key system + */ + setParsedResponse(keyuri, parsedResponse) { + const keyInfo = this.keyUriToKeyInfo[keyuri]; + if (keyInfo) { + keyInfo.resolveState(KeyRequestState.GET_KEY_RESPONSE, parsedResponse); + } + else { + this.logger.info(`${this.systemString} no keyInfo for keyuri: ${redactUrl(keyuri)}`); + } + } + // keystatuseschange handler + handleKeyStatusesChange(event) { + const ks = event.target; + ks.keyStatuses.forEach((status, keyid, parent) => { + const currentKeyId = new Uint8Array(keyid); + // If it's playready Key system we need to change the endianness of the keyid in the key status + if (this.systemString === PlayReadyKeySystemProperties.systemStringPrefix) { + keysystemutil.changeEndianness(currentKeyId); + } + const keyIdStr = BufferUtils.utf8arrayToStr(currentKeyId); + const keyInfo = this.keyIdToKeyInfo[keyIdStr]; + if (keyInfo) { + this.handleKeyStatusForKey(status, keyInfo); + } + }); + } + handleKeyStatusForKey(status, keyInfo) { + if (!keyInfo) { + return; + } + const decryptdata = keyInfo.decryptdata; + const keyuri = decryptdata.uri; + switch (status) { + case 'internal-error': { + this.logger.error(`${this.systemString} internal-error for key ${printKeyTag(decryptdata)}`); + this._signalError(keyInfo, new KeyRequestError('Got internal error from key system', keyuri, 0, ErrorResponses.KeySystemInternalError, false, KeyRequestErrorReason.InternalError)); + break; + } + case 'usable': { + if (keyInfo.requestState === KeyRequestState.PROCESS_LICENSE) { + keyInfo.resolveState(KeyRequestState.PROCESS_LICENSE, undefined); + } + break; + } + case 'output-restricted': { + this.logger.warn(`${this.systemString} output-restricted for key ${printKeyTag(decryptdata)}`); + if (keyInfo.session) { + // Cleanup the session, so that we don't keep the keys and try to renew it later + this.removeSession(keyInfo.session).pipe(takeUntil(this.destroy$)).subscribe(); + } + this._signalError(keyInfo, new KeyRequestError('output-restricted', keyuri, 0, ErrorResponses.KeySystemOutputRestricted, false, KeyRequestErrorReason.OutputRestricted)); + break; + } + case 'expired': { + this.logger.warn(`${this.systemString} expired for key ${printKeyTag(decryptdata)}. Attempting renewal`); + this._signalRenewal(keyInfo); + break; + } + default: + this.logger.info(`key status ${printKeyTag(decryptdata)} ${status}`); + break; + } + } + _scheduleRenewal(keyInfo, renewalMs) { + this.logger.info(`${this.systemString} Scheduling renewal for ${printKeyTag(keyInfo.decryptdata)} in ${renewalMs} ms`); + timer(renewalMs) + .pipe(tap(() => this._signalRenewal(keyInfo)), takeUntil(race(keyInfo.destroy$, this.destroy$, waitFor(keyInfo.onKeyRequestState$, (state) => state === KeyRequestState.GET_REQUEST_INFO)))) + .subscribe(); + } + _signalRenewal(keyInfo) { + this._keyStatusChange$.next({ decryptdata: keyInfo.decryptdata, status: 'needs-renewal' }); + } + _signalError(keyInfo, error) { + this._keyStatusChange$.next({ decryptdata: keyInfo.decryptdata, status: 'error', error }); + keyInfo.error(error); + } + } + + const kClearKeySystemString = 'org.w3.clearkey'; + const ClearKeySecurityLevels = { + NONE: 0, + }; + const ClearKeySystemProperties = { + id: 'clearkey', + systemStringPrefix: kClearKeySystemString, + keyFormatString: kClearKeySystemString, + securityLevels: ClearKeySecurityLevels, + }; + + /** + * 2018 Apple Inc. All rights reserved. + */ + const KeySystemIdValues = ['clearkey', 'fairplaystreaming', 'playready', 'widevine']; + + /** + * Clear key system implementation + * + * Uses July 2016 spec: + * https://www.w3.org/TR/2016/CR-encrypted-media-20160705/ + * + * 2018 Apple Inc. All rights reserved. + */ + // default configuration to pass into requestMediaKeySystemAccess + const kClearKeySystemConfig = { + initDataTypes: ['keyids', 'cenc'], + }; + class ClearKeySystem extends KeySystem { + constructor(mediaKeys, keySystemString, config, eventEmitter, sessionHandler, logger) { + super(mediaKeys, keySystemString, config, eventEmitter, false, sessionHandler, logger); + } + // destroy() + static get requestAccessConfig() { + return kClearKeySystemConfig; + } + get needsCert() { + return false; + } + getKeyRequestResponse(keyInfo, licenseChallenge) { + const keyuri = keyInfo.decryptdata.uri; + const loaderConfig = { + maxLoadTimeMs: 0, + maxTimeToFirstByteMs: 0, + autoRetry: false, + timeoutRetry: null, + errorRetry: null, + }; + return fromUrlArrayBuffer({ url: keyuri, xhrSetup: this.config.xhrSetup }, loaderConfig).pipe(map(([loadArrayBufferResult, _]) => { + const key = new Uint8Array(loadArrayBufferResult); + const response = { + response: this.parseResponse(licenseChallenge, key), + }; + return response; + })); + } + parseResponse(licenseChallenge, key) { + const keyObj = { + kty: 'oct', + kid: NumericEncodingUtils$1.base64UrlEncode(licenseChallenge), + k: NumericEncodingUtils$1.base64UrlEncode(key), + }; + return BufferUtils.strToUtf8array(JSON.stringify({ keys: [keyObj] })); + } + handleParsedKeyResponse(keyInfo, keyResponse) { + const responseBlob = keyResponse.response; + const processLicense = keyInfo.setKeyRequestState(KeyRequestState.PROCESS_LICENSE); + const updateSession = from(keyInfo.session.update(responseBlob)).pipe(tap(() => { + const keyId = keyInfo.decryptdata.keyId; + const state = keyInfo.session.keyStatuses.get(keyId); + this.handleKeyStatusForKey(state, keyInfo); + }), catchError((reason) => { + const response = { code: reason.code, text: 'Failed to update with key response' }; + const err = new KeySystemError(reason.message, keyInfo.decryptdata.uri, reason.code, response, this.systemString); + throw err; + })); + return forkJoin([processLicense, updateSession]).pipe(mapTo(undefined)); + } + generateInitData(keyId /* decryptdata, requestInfo*/) { + return { initData: keysystemutil.makeKeyIdsInitData([keyId]), initDataType: 'keyids' }; + } + generateRequestInitialized() { + return VOID; + } + sanitizeRequest(requestInfo) { + return requestInfo; + } + // message + handleKeyMessage(event) { + if (this.isDestroying) { + this.logger.info('In the middle of destroying, ignore key message'); + return; + } + if (event.messageType !== 'license-request') { + this.logger.info(`${this.systemString} Unexpected key message type ${event.messageType}`); + return; + } + const message = new Uint8Array(event.message); + const request = JSON.parse(BufferUtils.utf8arrayToStr(message).trim()); + if (request.kids.length !== 1) { + this.logger.info(`${this.systemString} Unexpected number of keyIds ${request.kids.length}`); + return; + } + const keyId = NumericEncodingUtils$1.base64Decode(request.kids[0]); // just care about the first for now + const keyIdStr = BufferUtils.utf8arrayToStr(keyId); + const keyInfo = this.keyIdToKeyInfo[keyIdStr]; + if (keyInfo) { + keyInfo.resolveState(KeyRequestState.GET_CHALLENGE, keyId); + } + else { + this.logger.info(`${this.systemString} no keyInfo for keyId ${JSON.stringify(keyId)}`); + } + } + } + var ClearKeySystem$1 = ClearKeySystem; + + /* + * FairPlayStreaming key system constants + * + * 2018 Apple Inc. All rights reserved. + */ + const kFairPlayStreamingKeySystemConfig = { + initDataTypes: ['cenc'], + }; + const kFairPlayStreamingKeySystemUUID = new Uint8Array([148, 206, 134, 251, 7, 255, 79, 67, 173, 184, 147, 210, 250, 150, 140, 162]); + var SchemeFourCC; + (function (SchemeFourCC) { + SchemeFourCC[SchemeFourCC["CENC"] = 1667591779] = "CENC"; + SchemeFourCC[SchemeFourCC["CBCS"] = 1667392371] = "CBCS"; + })(SchemeFourCC || (SchemeFourCC = {})); + /** + * Base class for FPS key systems + */ + class FairPlayStreamingKeySystemBase extends KeySystem { + constructor(mediaKeys, keySystemString, config, eventEmitter, useSingleKeySession, sessionHandler, logger) { + super(mediaKeys, keySystemString, config, eventEmitter, useSingleKeySession, sessionHandler, logger); + this._hasSetRenewal = false; + } + static get systemId() { + return kFairPlayStreamingKeySystemUUID; + } + static get requestAccessConfig() { + return kFairPlayStreamingKeySystemConfig; + } + get needsCert() { + return true; + } + sanitizeRequest(requestInfo) { + return { + assetId: requestInfo && requestInfo.assetId ? new Uint8Array(requestInfo.assetId) : undefined, + ssc: requestInfo && requestInfo.ssc ? new Uint8Array(requestInfo.ssc) : undefined, + sessionId: requestInfo && requestInfo.sessionId ? requestInfo.sessionId : undefined, + }; + } + _scheduleRenewal(keyInfo, renewalMs) { + if (!this.useSingleKeySession) { + // Each key has its own timer + super._scheduleRenewal(keyInfo, renewalMs); + } + else if (!this._hasSetRenewal) { + this._hasSetRenewal = true; + this.logger.info(`${this.systemString} Scheduling renewal in ${renewalMs} ms`); + timer(renewalMs) + .pipe(tap(() => { + // use first available keyInfo + const keyInfo = Object.values(this.keyUriToKeyInfo)[0]; + if (keyInfo) { + this._signalRenewal(keyInfo); + } + }), finalize$1(() => { + this._hasSetRenewal = false; + }), takeUntil(this.destroy$)) + .subscribe(); + } + } + /** + * Handle a parsed key response + * @param {Object} keyInfo Info about the key + * @param {Object} keyResponse The parsed key response object { statusCode, ckc, renewalData } + * @returns {Observable} message to pass to update() for processing license + */ + handleParsedKeyResponse(keyInfo, keyResponse) { + const keyuri = keyInfo.decryptdata.uri; + const statusCode = keyResponse.statusCode; + const licenseResponse = keyResponse.ckc && keyResponse.ckc.byteLength !== 0 ? keyResponse.ckc : keyResponse.license && keyResponse.license.byteLength !== 0 ? keyResponse.license : undefined; + // Special handling in case of HTTP Errors during key requests. + if (statusCode === 0 && !licenseResponse) { + return throwError(new KeyRequestError('License request resulted in HTTP Error', keyuri, statusCode, { code: statusCode, text: 'HTTP Error' }, true, KeyRequestErrorReason.HttpError)); + } + if (statusCode !== 0) { + return throwError(new KeyRequestError('License server responded with error', keyuri, statusCode, { code: statusCode, text: 'Server Error' }, false, KeyRequestErrorReason.LicenseServerError)); + } + if (!licenseResponse) { + const err = new KeyRequestError('License server responded with invalid license', keyuri, statusCode, { code: statusCode, text: 'Invalid license' }, false, KeyRequestErrorReason.LicenseServerError); + return throwError(err); + } + const renewalDate = keyResponse.renewalDate; + const now = new Date(); + const renewalMs = renewalDate > now ? renewalDate.getTime() - now.getTime() : 0; + if (renewalMs > 0) { + this._scheduleRenewal(keyInfo, renewalMs); + } + const ckcArray = this.makeProcessLicenseRequestMessage(keyInfo, licenseResponse, renewalMs); + // Only resolve if we got success, either from 'usable' keystatuschange event + // or on promise completion with 'usable' key status. Otherwise reject + const session = keyInfo.session; + const updateSession = from(session.update(ckcArray)).pipe(tap(() => { + const keyId = keyInfo.decryptdata.keyId; + const status = session.keyStatuses.get(keyId); + // Slightly faster than waiting for keystatuschange + this.handleKeyStatusForKey(status, keyInfo); + }), catchError((error) => { + const err = new KeySystemError(error.message, keyInfo.decryptdata.uri, 0, ErrorResponses.KeySystemFailedToUpdateSession, this.systemString); + throw err; + })); + const getLicense = keyInfo.setKeyRequestState(KeyRequestState.PROCESS_LICENSE); + return forkJoin([getLicense, updateSession]).pipe(mapTo(undefined)); + } + makeKeyRequests(requestInfoArray) { + const keyRequests = []; + for (const r of requestInfoArray) { + const decryptdata = r.decryptdata; + const requestInfo = r.requestInfo; + const keyId = decryptdata.keyId; + keyRequests.push({ + keyId: keyId, + assetId: requestInfo ? requestInfo.assetId : undefined, + ssc: requestInfo ? requestInfo.ssc : undefined, + versionList: decryptdata.formatversions, + }); + } + return keyRequests; + } + getSchemeAndFlags(decryptdata) { + const scheme = decryptdata.method === 'ISO-23001-7' ? SchemeFourCC.CENC : SchemeFourCC.CBCS; // TODO pass real scheme through. + const flags = 0; + // TODO + /* if (this.hls.playingItem.secureStop) { + flags |= 0x01; + } */ + return { scheme, flags }; + } + generateInitData(keyId, decryptdata, requestInfo) { + // Generate a PSSH + const { scheme, flags } = this.getSchemeAndFlags(decryptdata); + const keyRequests = this.makeKeyRequests([{ decryptdata, requestInfo }]); + const pssh = this.makeFpsKeySystemInitData(scheme, flags, keyRequests); + // console.log('PSSH=' + Hex.hexDump(pssh)); + return { initData: pssh, initDataType: 'cenc' }; + } + /** + * Generate a key renewal request on an already initialized session + * @param keyInfo Info about the key we're requesting + * @param isRenewal Is this a renewal requewst + * @returns promise for when update call is done. + **/ + generateRequestInitialized(keyInfo, isRenewal) { + tag(`[Keys] challenge create start uri=${redactUrl(keyInfo.decryptdata.uri)} versions=${JSON.stringify(keyInfo.decryptdata.formatversions)}`); + const message = this.makeKeyRequestMessage(keyInfo, isRenewal); + if (!message) { + const err = new KeyRequestError('Unable to generate request using existing keySession', keyInfo.decryptdata.uri, 0, ErrorResponses.KeySystemFailedToGenerateLicenseRequest, true, KeyRequestErrorReason.InvalidState); + return throwError(err); + } + return from(keyInfo.session.update(message)).pipe(tap(() => { + keyInfo.requestInfo = undefined; // Don't need requestInfo anymore. + }), catchError((reason) => { + tag(`[Keys] ${this.systemString} FAIL: generateRequestInitialized keyuri=${redactUrl(keyInfo.decryptdata.uri)} message=${reason.message}`); + throw new KeySystemError(reason.message, keyInfo.decryptdata.uri, 0, ErrorResponses.KeySystemFailedToGenerateLicenseRenewal, this.systemString); + })); + } + /** + * @param {Object} keyInfo Info about the key we're requesting + * @param {Uint8Array} licenseChallenge Challenge bytes + * @returns {Observable} Promise returning the license response + */ + getKeyRequestResponse(keyInfo, licenseChallenge) { + const keyuri = keyInfo.decryptdata.uri; + const getKeyResponse = keyInfo.setKeyRequestState(KeyRequestState.GET_KEY_RESPONSE); + this.eventEmitter.trigger(HlsEvent$1.LICENSE_CHALLENGE_CREATED, { + keyuri: keyuri, + licenseChallenge: licenseChallenge, + keysystem: this.systemString, + }); + return getKeyResponse; + } + resolveSPCPromise(keyInfo, spc) { + keyInfo.resolveState(KeyRequestState.GET_CHALLENGE, spc); + } + } + + /* + * FairPlayStreaming key system + * + * 2018 Apple Inc. All rights reserved. + */ + //declare var __SECURESTOP_KEYS__: IFPSSecureStopKeys; + //const SecureStopKeys = __SECURESTOP_KEYS__; + const SecureStopKeys = {}; + const MessageFourCC = { + NONE: 0, + CRKR: 1668442994, + RMKY: 1919773561, + CKCS: 1667982195, + CERT: 1667592820, + SPCS: 1936745331, + RNEW: 1919837559, + RLSE: 1919710053, + SSTP: 1936946288, + CDMI: 1667525993, + }; + const APIProviderId = { + CENC: 'EC396D13-FB13-4993-9D0D-71518ACF3D6F', + CBCS: 'F19BF03B-7470-41A4-9655-86D078307D59', + }; + /** + * Read a generic data field + * + * Format: 4B length of data, nB data bytes + * + * @param {Uint8Array} inBuf Buffer referenced by dv + * @param {DataView} dv DataView wrapper around inBuf + * @param {number} pos Starting position in buffer to read from + * @returns {Object} { pos: next byte to read, data: Uint8Array holding data parsed out of inBuf } + */ + function readDataField(inBuf, dv, pos) { + if (pos + 4 > inBuf.byteLength) { + return undefined; + } + const dataLen = dv.getUint32(pos); + pos += 4; + if (pos + dataLen > inBuf.byteLength) { + return undefined; + } + const data = inBuf.slice(pos, pos + dataLen); + pos += dataLen; + return { pos: pos, data: data }; + } + // Read message: + // cmd (4) + // arrayLen (4) + // keyId (16) + // dataLen (4) + // data (dataLen) + function parseData(message) { + const keyIdToData = {}; + const dv = new DataView(message.buffer); + let pos = 4; + const arrayLen = dv.getUint32(pos); + pos += 4; + for (let i = 0; i < arrayLen && pos < message.byteLength; ++i) { + if (pos + 16 > message.byteLength) { + break; + } + const keyId = message.slice(pos, pos + 16); + pos += 16; + if (pos + 4 > message.byteLength) { + break; + } + const tmp = readDataField(message, dv, pos); + if (tmp) { + pos = tmp.pos; + keyIdToData[BufferUtils.utf8arrayToStr(keyId)] = tmp.data; + } + else { + break; + } + } + return keyIdToData; + } + function addDataField(outBuf, dv, pos, data) { + const len = data ? data.byteLength : 0; + dv.setUint32(pos, len); + if (len) { + outBuf.set(data, pos + 4); + } + pos += 4 + len; + return pos; + } + // Including 4 byte arrayLen + function getKeyRequestArraySize(keyRequests) { + // arrayLen (4) + // --------- For each key: + // keyId(16) + // assetIdLen (4), assetId + // sscLen (4), ssc + // versionLen (4), versionList (each one 4B) + let bytesForArray = 4; + for (const kr of keyRequests) { + bytesForArray += 28 + (kr.assetId ? kr.assetId.byteLength : 0) + (kr.ssc ? kr.ssc.byteLength : 0) + (kr.versionList ? kr.versionList.length * 4 : 0); + } + return bytesForArray; + } + /** + * Fill existing array w/ key request data + * @param array uint8array + * @param dv dataview for array + * @param pos position to write to within array + * @param keyRequests Array of key requests [ { assetId, ssc, versionList } ] + * @returns + */ + function addKeyRequestArray(array, dv, pos, keyRequests) { + dv.setUint32(pos, keyRequests.length); // arrayLen + pos += 4; + for (const kr of keyRequests) { + array.set(kr.keyId, pos); + pos += 16; + pos = addDataField(array, dv, pos, kr.assetId); + pos = addDataField(array, dv, pos, kr.ssc); + dv.setUint32(pos, kr.versionList ? kr.versionList.length : 0); + pos += 4; + if (kr.versionList) { + for (const vl of kr.versionList) { + dv.setUint32(pos, vl); + pos += 4; + } + } + } + // console.log(`addKeyRequestArray: ${Hex.hexDump(array)}`); + return pos; + } + function makeFpsKeySystemInitData$1(scheme, protocol, flags, keyRequests) { + // Generate a PSSH + // Data for FPS: + // scheme: CC 4B + // protocol: 1B + // flags: 3B + // keyrequestarray + const keyRequestBytes = getKeyRequestArraySize(keyRequests); + let pos = 0; + const data = new Uint8Array(8 + keyRequestBytes); + const dv = new DataView(data.buffer); + dv.setUint32(pos, scheme); // schm + dv.setUint32(pos + 4, (protocol << 24) | (flags & 16777215)); // version | flags + pos += 8; + pos = addKeyRequestArray(data, dv, pos, keyRequests); + // console.log(`makeFpsKeySystemInitData: ${Hex.hexDump(data)}`); + return data; + } + function makeCreateKeyRequestMessage(keyRequests) { + // cmd (4) + // keyrequest array + // first calculate bytes to allocate + const bytesForArray = getKeyRequestArraySize(keyRequests); + let pos = 0; + const req = new Uint8Array(4 + bytesForArray); + const dv = new DataView(req.buffer); + dv.setUint32(0, MessageFourCC.CRKR); // cmd + pos += 4; + pos = addKeyRequestArray(req, dv, pos, keyRequests); + // console.log(`makeCreateKeyRequestMessage: ${Hex.hexDump(req)}`); + return req; + } + function makeProcessLicenseRequestMessage(licenses) { + // cmd (4) + // arrayLen (4) + // keyId (16) + // expiry (4) + // ckcLen (4) + // ckcBytes + // first calculate bytes to allocate + let bytesForArray = 0; + for (const l of licenses) { + bytesForArray += 24 + l.ckc.byteLength; + } + let pos = 0; + const req = new Uint8Array(8 + bytesForArray); + const dv = new DataView(req.buffer); + dv.setUint32(0, MessageFourCC.CKCS); // cmd + dv.setUint32(4, licenses.length); // arrayLen + pos += 8; + for (const l of licenses) { + req.set(l.keyId, pos); + pos += 16; + dv.setUint32(pos, l.expirySec); + pos += 4; + pos = addDataField(req, dv, pos, l.ckc); + } + // console.log(`makeProcessLicenseRequestMessage: ${Hex.hexDump(req)}`); + return req; + } + class FairPlayStreamingKeySystem extends FairPlayStreamingKeySystemBase { + constructor(mediaKeys, keySystemString, config, eventEmitter, sessionHandler, logger) { + const singleKeySession = typeof config.useMultipleKeySessions === 'undefined' || !config.useMultipleKeySessions; + super(mediaKeys, keySystemString, config, eventEmitter, singleKeySession, sessionHandler, logger); + } + makeProcessLicenseRequestMessage(keyInfo, licenseResponse, renewalMs) { + const ckcBytes = new Uint8Array(licenseResponse); + const ckcArray = makeProcessLicenseRequestMessage([ + { + keyId: keyInfo.decryptdata.keyId, + expirySec: renewalMs / 1000, + ckc: ckcBytes, + }, + ]); + return ckcArray; + } + makeFpsKeySystemInitData(scheme, flags, keyRequests) { + const protocol = 1; + const data = makeFpsKeySystemInitData$1(scheme, protocol, flags, keyRequests); + const pssh = MP4$1.pssh(FairPlayStreamingKeySystem.systemId, [], data); + return pssh; + } + makeKeyRequestMessage(keyInfo /* , isRenewal*/) { + const crkrArray = makeCreateKeyRequestMessage([ + { + keyId: keyInfo.decryptdata.keyId, + assetId: keyInfo.requestInfo ? keyInfo.requestInfo.assetId : undefined, + ssc: keyInfo.requestInfo ? keyInfo.requestInfo.ssc : undefined, + versionList: keyInfo.decryptdata.formatversions, + }, + ]); + return crkrArray; + } + handleKeyMessage(event) { + if (event.message.byteLength < 4) { + this.logger.warn('Unexpected message'); + return; + } + // event.message (ArrayBuffer) + const message = new Uint8Array(event.message); + const dv = new DataView(event.message); + const cmd = dv.getUint32(0); + if (this.isDestroying && cmd !== MessageFourCC.RLSE) { + this.logger.warn(`In the middle of destroying, ignore command: ${cmd.toString(16)}`); + return; + } + this.logger.info(`[Keys] ${this.systemString} message 0x${cmd.toString(16)}`); + switch (cmd) { + case MessageFourCC.CERT: + this.logger.warn('Certificate not set!'); + break; + case MessageFourCC.RNEW: { + const keyIdToData = parseData(message); + for (const keyIdStr in keyIdToData) { + if (Object.prototype.hasOwnProperty.call(keyIdToData, keyIdStr)) { + const keyInfo = this.keyIdToKeyInfo[keyIdStr]; + if (keyInfo) { + this._signalRenewal(keyInfo); + } + } + } + break; + } + case MessageFourCC.SPCS: { + const keyIdToData = parseData(message); + for (const keyIdStr in keyIdToData) { + if (Object.prototype.hasOwnProperty.call(keyIdToData, keyIdStr)) { + const keyInfo = this.keyIdToKeyInfo[keyIdStr]; + const spc = keyIdToData[keyIdStr]; + if (keyInfo && spc) { + this.resolveSPCPromise(keyInfo, spc); + } + } + } + break; + } + case MessageFourCC.RLSE: { + this._handleLicenseRelease(message); + break; + } + case MessageFourCC.CDMI: { + // Message length = 4 + // CDM version = remaining data + const pos = 4; + const tmp = readDataField(message, dv, pos); + if (tmp) { + const cdmVersion = (this.cdmVersion = BufferUtils.utf8arrayToStr(tmp.data)); + this.logger.info(`[Keys] ${this.systemString} CDM Version : ${cdmVersion}`); + } + break; + } + default: + this.logger.warn(`Unrecognized command:'0x${cmd.toString(16)}'`); + break; + } + } + _handleLicenseRelease(message) { + const releaseRecord = {}; + const dv = new DataView(message.buffer); + const type = dv.getUint32(4); // Release type + switch (type) { + case MessageFourCC.SSTP: { + // Secure stop + if (!SecureStopKeys) { + this.logger.warn('No secure stop keys defined'); + break; + } + releaseRecord[SecureStopKeys.SessionId] = this.sessionId; + // scheme (uint32) + // movieIdLen (uint32) + // movieIdStr + // secureStopSPCLen (uint32) + // secureStopSPC + // sessionLifespanSPCLen (uint32) + // sessionLifespanSPC + let pos = 8; + if (pos + 4 > message.byteLength) { + break; + } + releaseRecord[SecureStopKeys.APIProvider] = dv.getUint32(pos) === SchemeFourCC.CENC ? APIProviderId.CENC : APIProviderId.CBCS; + pos += 4; + let tmp = readDataField(message, dv, pos); + if (tmp) { + pos = tmp.pos; + releaseRecord[SecureStopKeys.MovieID] = BufferUtils.utf8arrayToStr(tmp.data); + } + else { + break; + } + tmp = readDataField(message, dv, pos); + if (tmp) { + pos = tmp.pos; + releaseRecord[SecureStopKeys.SecureStopSPC] = tmp.data; + } + else { + break; + } + tmp = readDataField(message, dv, pos); + if (tmp) { + pos = tmp.pos; + releaseRecord[SecureStopKeys.SessionLifespanSPC] = tmp.data; + } + else { + break; + } + break; + } + } + this.eventEmitter.trigger(HlsEvent$1.LICENSE_RELEASED, { + keysystem: this.systemString, + itemId: this.itemId, + releaseRecord: releaseRecord, + }); + } + } + var FPSKeySystem = FairPlayStreamingKeySystem; + + const FpsBoxTypes = { + fpsd: BufferUtils.strToUtf8array('fpsd'), + fpsi: BufferUtils.strToUtf8array('fpsi'), + fpsk: BufferUtils.strToUtf8array('fpsk'), + fkri: BufferUtils.strToUtf8array('fkri'), + fkai: BufferUtils.strToUtf8array('fkai'), + fkcx: BufferUtils.strToUtf8array('fkcx'), + fkvl: BufferUtils.strToUtf8array('fkvl'), // version list + }; + /** + * @param scheme cbcs or cenc + * @param flags keySystem flags + * @returns FpsKeySystemInitDataBox + */ + function makeFpsKeySystemInfoBox(scheme, flags) { + const schemeArray = new Uint8Array(4); + MP4$1.set32(scheme, schemeArray, 0); + return MP4$1.box(FpsBoxTypes.fpsi, new Uint8Array([ + 0, + (flags >> 16) & 255, + (flags >> 8) & 255, + flags & 255, + ]), schemeArray); + } + /** + * Generate a FpsKeyRequestBox + * @param {ArrayBuffer} keyId The key ID + * @param {ArrayBuffer} assetId AssetID + * @param {ArrayBuffer} ssc Remote secure context + * @param {Array} versionList A list of Number from EXT-X-KEY:KEYFORMATVERSIONS + * @returns {ArrayBuffer} a FpsKeyRequestBox + */ + function makeFpsKeyRequestBox(keyId, assetId, ssc, versionList) { + const args = [FpsBoxTypes.fpsk]; + // Mandatory + const fkri = MP4$1.box(FpsBoxTypes.fkri, new Uint8Array([0, 0, 0, 0]), keyId); + args.push(fkri); + // Optional boxes + if (assetId && assetId.byteLength) { + args.push(MP4$1.box(FpsBoxTypes.fkai, assetId)); + } + if (ssc && ssc.byteLength) { + args.push(MP4$1.box(FpsBoxTypes.fkcx, ssc)); + } + if (versionList && versionList.length) { + // List of integers + const versionListBuffer = new Uint8Array(4 * versionList.length); + let pos = 0; + for (const version of versionList) { + MP4$1.set32(version, versionListBuffer, pos); + pos += 4; + } + args.push(MP4$1.box(FpsBoxTypes.fkvl, versionListBuffer)); + } + const fpsk = MP4$1.box.apply(null, args); + return fpsk; + } + /** + * @param {SchemeFourCC} scheme cbcs or cenc (fourCC) + * @param {number} flags keySystem flags (number) + * @param {Array} keyRequests array of requests [ { keyId, assetId, ssc, versionList } ] + * @returns {Uint8Array} a PSSH box for initializing the key system + */ + function makeFpsKeySystemInitData(scheme, flags, keyRequests) { + // Mandatory box for key system initialization + const args = [FpsBoxTypes.fpsd, makeFpsKeySystemInfoBox(scheme, flags)]; + for (const kr of keyRequests) { + args.push(makeFpsKeyRequestBox(kr.keyId, kr.assetId, kr.ssc, kr.versionList)); + } + const data = MP4$1.box.apply(null, args); + const pssh = MP4$1.pssh(FairPlayStreamingKeySystemBase.systemId, null, data); + return pssh; + } + class FairPlayStreamingKeySystemV3 extends FairPlayStreamingKeySystemBase { + constructor(mediaKeys, keySystemString, config, eventEmitter, sessionHandler, logger) { + super(mediaKeys, keySystemString, config, eventEmitter, false, sessionHandler, logger); + this.sessions = []; + this.keyIdToKeyInfo = {}; + this.keyUriToKeyInfo = {}; + this.sessionIdToKeyUri = {}; + } + static get needsCert() { + return true; + } + handleKeyExchangeError(keyInfo, err) { + // If at any point we had an error during key exchange we need to destroy this session + this.removeKey(keyInfo.decryptdata).subscribe(); + super.handleKeyExchangeError(keyInfo, err); + } + _abortKeyRequest(keyInfo) { + if (!this.isDestroying && keyInfo && keyInfo.requestState !== KeyRequestState.NONE) { + this.removeKey(keyInfo.decryptdata).subscribe(); + } + return super._abortKeyRequest(keyInfo); + } + makeFpsKeySystemInitData(scheme, flags, keyRequests) { + return makeFpsKeySystemInitData(scheme, flags, keyRequests); + } + makeKeyRequestMessage(keyInfo, isRenewal) { + if (isRenewal) { + return BufferUtils.strToUtf8array('renew'); + } + return undefined; + } + makeProcessLicenseRequestMessage(keyInfo, licenseResponse, renewalMs) { + const responseStr = JSON.stringify([ + { + keyID: NumericEncodingUtils$1.base64Encode(keyInfo.decryptdata.keyId), + payload: NumericEncodingUtils$1.base64Encode(new Uint8Array(licenseResponse)), + }, + ]); + this.logger.debug(`[Keys] processLicense msg=${responseStr}`); + return BufferUtils.strToUtf8array(responseStr); + } + handleKeyMessage(event) { + const session = event.target; + const sessionId = session.sessionId; + const messageType = event.messageType; + this.logger.info(`[Keys] onKeyMessage sessionId=${sessionId} type=${messageType}`); + const keyuri = this.sessionIdToKeyUri[sessionId]; + let keyInfo; + if (!keyuri) { + // key message could happen before generateRequest() promise completes + for (const ki of Object.values(this.keyUriToKeyInfo)) { + if (ki && ki.session === session) { + keyInfo = ki; + } + } + } + else { + keyInfo = this.keyUriToKeyInfo[keyuri]; + } + if (!keyInfo) { + this.logger.warn('[Keys] No key associated with session'); + return; + } + switch (messageType) { + case 'license-request': { + const message = new Uint8Array(event.message); + const messagestr = BufferUtils.utf8arrayToStr(message); + try { + // Expect only one but we'll handle all of them anyway + const spcArray = JSON.parse(messagestr); + spcArray.forEach((payload) => { + const keyIdStr = NumericEncodingUtils$1.base64DecodeToStr(payload.keyID); + const spc = NumericEncodingUtils$1.base64Decode(payload.payload); + const keyInfo = this.keyIdToKeyInfo[keyIdStr]; + if (keyInfo) { + this.resolveSPCPromise(keyInfo, spc); + } + }); + } + catch (error) { + this.logger.warn('[Keys] got unexpected license-request format'); + this.resolveSPCPromise(keyInfo, message); // Last ditch effort + } + break; + } + case 'license-renewal': { + const spc = new Uint8Array(event.message); + this.resolveSPCPromise(keyInfo, spc); + break; + } + case 'license-release': + this._handleLicenseRelease(session); + break; + default: + this.logger.warn(`[Keys] Unexpected messageType ${messageType}`); + break; + } + } + _handleLicenseRelease(keySession) { + keySession.update(BufferUtils.strToUtf8array('acknowledged')).catch((error) => { + this.logger.error(`Promise error: ${error.message}`); + }); + } + } + var FPSKeySystemV3 = FairPlayStreamingKeySystemV3; + + /** + * PlayReady key system + */ + const kPlayReadyKeySystemConfig = { + initDataTypes: ['cenc'], + }; + const kPlayReadyKeySystemUUID = new Uint8Array([154, 4, 240, 121, 152, 64, 66, 134, 171, 146, 230, 91, 224, 136, 95, 149]); + class PlayReadyKeySystem extends KeySystem { + constructor(mediaKeys, systemString, config, eventEmitter, sessionHandler, logger) { + super(mediaKeys, systemString, config, eventEmitter, false, sessionHandler, logger); + this.shouldDestroyMediaKeys = true; + } + // destroy() + static get systemId() { + return kPlayReadyKeySystemUUID; + } + static get requestAccessConfig() { + return kPlayReadyKeySystemConfig; + } + get needsCert() { + return false; + } + generateInitData(keyId, decryptdata /* , requestInfo */) { + const data = decryptdata.pssh; + const pssh = MP4$1.pssh(PlayReadyKeySystem.systemId, [], data); + // console.log('PSSH=' + Hex.hexDump(pssh)); + return { initData: pssh, initDataType: 'cenc' }; + } + removeKey(decryptdata) { + return super.removeSessions(decryptdata, true); + } + ensureKeyContext(decryptdata) { + const keyuri = decryptdata.uri; + const keyInfo = this.keyUriToKeyInfo[keyuri]; + // Create a new session for current key request and preserve previous sessions for + // cleanup later + if (keyInfo === null || keyInfo === void 0 ? void 0 : keyInfo.session) { + keyInfo.oldSessions.push(keyInfo.session); + keyInfo.session = null; + } + return super.ensureKeyContext(decryptdata); + } + getKeyRequestResponse(keyInfo, licenseChallenge) { + const keyuri = keyInfo.decryptdata.uri; + const getKeyResponse = keyInfo.setKeyRequestState(KeyRequestState.GET_KEY_RESPONSE); + this.eventEmitter.trigger(HlsEvent$1.LICENSE_CHALLENGE_CREATED, { + keyuri: keyuri, + licenseChallenge: licenseChallenge, + keysystem: this.systemString, + keyId: keyInfo.decryptdata.keyId, + }); + return getKeyResponse; + } + /** + * Generate a key renewal request + * @param keyInfo Info about the key we're requesting + * @returns {Observable} Promise returning the license challenge + **/ + generateRequestInitialized(keyInfo) { + const keyuri = keyInfo.decryptdata.uri; + const challenge = keyInfo.licenseChallenge; + this.logger.debug(`[Keys] challenge create start uri=${redactUrl(keyuri)} versions=${JSON.stringify(keyInfo.decryptdata.formatversions)}`); + keyInfo.requestInfo = undefined; // Don't need requestInfo anymore. + keyInfo.resolveState(KeyRequestState.GET_CHALLENGE, challenge); + return VOID; + } + // Default behavior is to just update using data.response + handleParsedKeyResponse(keyInfo, keyResponse) { + const keyuri = keyInfo.decryptdata.uri; + const statusCode = keyResponse.statusCode; + if (statusCode !== 0) { + return throwError(new KeyRequestError('License server responded with error', keyuri, statusCode, { code: statusCode, text: 'Server error' }, false, KeyRequestErrorReason.LicenseServerError)); + } + if (!keyResponse.license || !keyResponse.license.byteLength) { + return throwError(new KeyRequestError('License server responded with invalid license', keyuri, statusCode, { code: statusCode, text: 'Invalid license' }, false, KeyRequestErrorReason.LicenseServerError)); + } + if (keyResponse.renewalDate) { + const renewalDate = keyResponse.renewalDate; + const now = new Date(); + const renewalMs = renewalDate > now ? renewalDate.getTime() - now.getTime() : 0; + if (renewalMs > 0) { + this._scheduleRenewal(keyInfo, renewalMs); + } + } + const processLicense = keyInfo.setKeyRequestState(KeyRequestState.PROCESS_LICENSE); + const updateSession = from(keyInfo.session.update(keyResponse.license)).pipe(tap(() => { + // PR CDM on Edge won't change key status till the buffers are pushed. To push buffer the key status should be usable + // So don't rely on key status to change the state like other key systems. + keyInfo.resolveState(KeyRequestState.PROCESS_LICENSE, undefined); + }), catchError((reason) => { + this.logger.error(`${this.systemString} FAIL: Failed to update with key response message=${reason.message}`); + const err = new KeySystemError(reason.message, keyInfo.decryptdata.uri, 0, ErrorResponses.KeySystemFailedToUpdateSession, this.systemString); + throw err; + })); + return forkJoin([processLicense, updateSession]).pipe(mapTo(undefined)); + } + // message + handleKeyMessage(event) { + if (this.isDestroying) { + this.logger.warn('In the middle of destroying, ignore key message'); + return; + } + const parser = new DOMParser(); + // Verify the message format encoding, based on that create the typed array + // TO DO + const messageBuffer = this.config.playReadyMessageFormat === 'utf16' ? new Uint16Array(event.message.buffer || event.message) : new Uint8Array(event.message.buffer || event.message); + const message = String.fromCharCode.apply(null, Array.from(messageBuffer)); + // Expected license challenge format + // + // + // base64Challenge + // + // + // + const keyMessage = parser.parseFromString(message, 'application/xml').getElementsByTagName('PlayReadyKeyMessage')[0]; + if (!keyMessage || keyMessage.getAttribute('type') !== 'LicenseAcquisition') { + this.logger.warn(`${this.systemString} unrecognized message ignore it`); + return; + } + const challengeNode = parser.parseFromString(message, 'application/xml').getElementsByTagName('Challenge')[0]; + if (!challengeNode || challengeNode.getAttribute('encoding') !== 'base64encoded' || challengeNode.childNodes.length === 0) { + this.logger.warn(`${this.systemString} wrong challenge format or empty challenge`); + return; + } + const challenge = NumericEncodingUtils$1.base64Decode(challengeNode.childNodes[0].nodeValue); + const challengeStr = BufferUtils.utf8arrayToStr(challenge); + // The license challenge contains the base64 encoded Key ID, extract it. + const keyData = parser.parseFromString(challengeStr, 'application/xml').getElementsByTagName('KID')[0]; + let keyIdBase64 = null; + if (keyData.childNodes[0]) { + keyIdBase64 = keyData.childNodes[0].nodeValue; + } + else { + keyIdBase64 = keyData.getAttribute('VALUE'); + } + // Using KeyID extract KeyInfo and Key URI + // KID value in PRO is a base64-encoded little endian GUID interpretation of UUID + // KID value in Ãĸâ‚Ŧ˜tencÃĸâ‚Ŧâ„ĸ is a big endian UUID GUID interpretation of UUID + const keyId = NumericEncodingUtils$1.base64Decode(keyIdBase64).subarray(0, 16); + keysystemutil.changeEndianness(keyId); + const keyInfo = this.keyIdToKeyInfo[BufferUtils.utf8arrayToStr(keyId)]; + if (!keyInfo) { + this.logger.info(`${this.systemString} no keyInfo for keyId ${JSON.stringify(keyId)}`); + return; + } + keyInfo.licenseChallenge = challenge; + // Check demo/index.xml for more details on how exactly license is acquired. There is switch-case statement for LICENSE_CHALLENGE_CREATED + keyInfo.resolveState(KeyRequestState.GET_CHALLENGE, challenge); + } + } + var PlayReadyKeySystem$1 = PlayReadyKeySystem; + + /** + * Widevine key system + */ + const kWidevineKeySystemConfig = { + initDataTypes: ['cenc', 'keyids'], + }; + const kWidevineKeySystemUUID = new Uint8Array([237, 239, 139, 169, 121, 214, 74, 206, 163, 200, 39, 220, 213, 29, 33, 237]); + class WidevineKeySystem extends KeySystem { + constructor(mediaKeys, systemString, config, eventEmitter, sessionHandler, logger) { + super(mediaKeys, systemString, config, eventEmitter, false, sessionHandler, logger); + this.shouldDestroyMediaKeys = true; + } + // destroy() + static get systemId() { + return kWidevineKeySystemUUID; + } + static get requestAccessConfig() { + return kWidevineKeySystemConfig; + } + get needsCert() { + return true; + } + removeKey(decryptdata) { + return super.removeSessions(decryptdata, true); + } + ensureKeyContext(decryptdata) { + const keyuri = decryptdata.uri; + const keyInfo = this.keyUriToKeyInfo[keyuri]; + // Create a new session for current key request and preserve previous sessions for + // cleanup later + if (keyInfo === null || keyInfo === void 0 ? void 0 : keyInfo.session) { + keyInfo.oldSessions.push(keyInfo.session); + keyInfo.session = null; + } + return super.ensureKeyContext(decryptdata); + } + getKeyRequestResponse(keyInfo, licenseChallenge) { + const keyuri = keyInfo.decryptdata.uri; + const getKeyResponse = keyInfo.setKeyRequestState(KeyRequestState.GET_KEY_RESPONSE); + this.eventEmitter.trigger(HlsEvent$1.LICENSE_CHALLENGE_CREATED, { + keyuri: keyuri, + licenseChallenge: licenseChallenge, + keysystem: this.systemString, + keyId: keyInfo.decryptdata.keyId, + }); + return getKeyResponse; + } + handleParsedKeyResponse(keyInfo, keyResponse) { + // clear the license challenge + keyInfo.licenseChallenge = undefined; + const keyuri = keyInfo.decryptdata.uri; + const statusCode = keyResponse.statusCode; + if (statusCode !== 0) { + return throwError(new KeyRequestError('License server responded with error', keyuri, statusCode, { code: statusCode, text: 'Server error' }, false, KeyRequestErrorReason.LicenseServerError)); + } + if (!keyResponse.license || !keyResponse.license.byteLength) { + const err = new KeyRequestError('License server responded with invalid license', keyuri, statusCode, { code: statusCode, text: 'Invalid license' }, false, KeyRequestErrorReason.LicenseServerError); + return throwError(err); + } + if (keyResponse.renewalDate) { + const renewalDate = keyResponse.renewalDate; + const now = new Date(); + const renewalMs = renewalDate > now ? renewalDate.getTime() - now.getTime() : 0; + if (renewalMs > 0) { + this._scheduleRenewal(keyInfo, renewalMs); + } + } + const processLicense = keyInfo.setKeyRequestState(KeyRequestState.PROCESS_LICENSE); + const updateSession = from(keyInfo.session.update(keyResponse.license)).pipe(tap(() => { + const keyId = keyInfo.decryptdata.keyId; + const state = keyInfo.session.keyStatuses.get(keyId); + this.handleKeyStatusForKey(state, keyInfo); + }), catchError((reason) => { + this.logger.error(`${this.systemString} FAIL: Failed to update with key response code=${reason.code} message=${reason.message}`); + const err = new KeySystemError(reason.message, keyInfo.decryptdata.uri, reason.code, { code: reason.code, text: 'Failed to update with key response' }, this.systemString); + throw err; + })); + return forkJoin([processLicense, updateSession]).pipe(mapTo(undefined)); + } + /* + The pssh has to be generated from the manifest: + 1. Extract the keyID from the EXT-X-KEY tag (for example URI =Ãĸâ‚Ŧœdata:;base64,DZ/7Ld9qTnyTi92l+VPlBg==Ãĸâ‚Ŧœ) + 2. Generate the initdata using generateInitData + + generate Widevine pssh + 0:3 : size of the 'pssh' box + 4:7 : 'pssh' + 8:11 : not set (all zeros) + 12:27 : Widevine Key System (edef8ba9-79d6-4ace-a3c8-27dcd51d21ed) + 28:31 : Widevine pssh data size (size of what follows) + 32:51 : Protobuf-encoded Widevine pssh data + 32 & 33 : (id = 0, wireType = int, value = 1) means this is using AES-CTR + 34 & 35 : (id = 1, wireType = bytes, length = 16) size of the keyId + 36:51 : KeyId bytes + */ + generateInitData(keyId, decryptdata /* , requestInfo*/) { + return { initData: decryptdata.pssh, initDataType: 'cenc' }; + } + /** + * Generate a key renewal request + * @param keyInfo Info about the key we're requesting + * @returns {Observable} Promise returning the license challenge + **/ + generateRequestInitialized(keyInfo) { + const keyuri = keyInfo.decryptdata.uri; + const challenge = keyInfo.licenseChallenge; + //this.logger.info(`[Keys] challenge create start uri=${this.hls.redactUrl(keyuri)} versions=${JSON.stringify(keyInfo.decryptdata.formatversions)}`); + this.logger.debug(`[Keys] challenge create start uri=${redactUrl(keyuri)} versions=${JSON.stringify(keyInfo.decryptdata.formatversions)}`); + keyInfo.requestInfo = undefined; // Don't need requestInfo anymore. + keyInfo.resolveState(KeyRequestState.GET_CHALLENGE, challenge); + return VOID; + } + // message + handleKeyMessage(event) { + if (this.isDestroying) { + this.logger.warn('In the middle of destroying, ignore key message'); + return; + } + this.logger.info(`[Keys] ${this.systemString} message : ${event.messageType}`); + // Extract KeyUri and KeyInfo from the sessions info strored. + const session = event.target; + let keyuri = null; + let keyInfo = null; + if (session.sessionId in this.sessionIdToKeyUri) { + keyuri = this.sessionIdToKeyUri[session.sessionId]; + keyInfo = this.keyUriToKeyInfo[keyuri]; + } + else { + for (const [uri, info] of Object.entries(this.keyUriToKeyInfo)) { + if (info.session === session) { + keyuri = uri; + keyInfo = info; + break; + } + } + } + if (!keyInfo) { + this.logger.warn(`${this.systemString} empty keyuri and keyInfo`); + return; + } + const cmd = event.messageType; + switch (cmd) { + case 'license-request': { + // For widevine just base64 encode the challenge returned by the browser. + const challenge = new Uint8Array(event.message); + // Check demo/index.xml for more details on how exactly license is acquired. There is switch-case statement for LICENSE_CHALLENGE_CREATED + keyInfo.resolveState(KeyRequestState.GET_CHALLENGE, challenge); + break; + } + } + } + } + var WidevineKeySystem$1 = WidevineKeySystem; + + /* + * Factory for making a key system + * + * + */ + const kKeySystemIdToPropertiesMap$1 = { + clearkey: ClearKeySystemProperties, + fairplaystreaming: FairPlayStreamingKeySystemProperties, + playready: PlayReadyKeySystemProperties, + widevine: WidevineKeySystemProperties, + }; + const kKeySystemIdToConstructorsMap = { + clearkey: [['org.w3.clearkey', ClearKeySystem$1]], + fairplaystreaming: [ + ['com.apple.fps.3_0', FPSKeySystemV3], + ['com.apple.fps', FPSKeySystem], + ], + playready: [['com.microsoft.playready.recommendation', PlayReadyKeySystem$1]], + widevine: [['com.widevine.alpha', WidevineKeySystem$1]], + }; + const DEFAULT_KEY_SYSTEM = ClearKeySystemProperties.id; + /** + * Generate a KeySystem object given a KeySystemProperties + */ + class KeySystemFactory$1 { + createMediaKeys(keysystemId, videoCodecs, audioCodecs, logger, keySystemConfig) { + let res = KeySystemFactory$1.idToMediaKeysInfoMap[keysystemId]; + if (!res) { + logger.info(`[Keys] ${keysystemId} requesting key system access`); + const mediaCapabilities = keysystemutil.getCapabilities(videoCodecs, audioCodecs); + const mediaKeys$ = new AsyncSubject(); + KeySystemFactory$1.requestKeySystemAccess(keysystemId, mediaCapabilities, keySystemConfig, logger) + .pipe(switchMap(function (keySystemAccess) { + KeySystemFactory$1.idToMediaKeysInfoMap[keysystemId].keySystemAccess = keySystemAccess; + // TODO: probably should use keySystemAccess.getConfiguration() to get supported types. + logger.info(`[Keys] ${keysystemId} creating CDM`); + return from(keySystemAccess.createMediaKeys()); + }), tap((mediaKeys) => { + logger.info(`[Keys] ${keysystemId} created CDM`); + mediaKeys$.next(mediaKeys); + mediaKeys$.complete(); + }), catchError((err) => { + logger.info(`[Keys] FAIL: could not initialize ${keysystemId} key system: ${err.message}`); + mediaKeys$.error(new KeySystemError(`could not initialize key system: ${err.message}`, undefined, 0, ErrorResponses.KeySystemFailedToInitialize, keysystemId)); + return EMPTY; + }), takeUntil(KeySystemFactory$1.destroy$) // Keep alive until destroyMediaKeys + ) + .subscribe(); + res = KeySystemFactory$1.idToMediaKeysInfoMap[keysystemId] = { mediaKeys$, keySystemAccess: null }; + } + return res.mediaKeys$; + } + destroyMediaKeys() { + // Remove keysystemstring => requestKeySystemAccess promise + KeySystemFactory$1.destroy$.next(); + KeySystemFactory$1.idToMediaKeysInfoMap = {}; + } + static getKeySystemIdForDecryptData(decryptdata) { + let selectedId; + if (decryptdata) { + selectedId = DEFAULT_KEY_SYSTEM; + const formatString = decryptdata.format; + for (const id of KeySystemIdValues) { + const p = kKeySystemIdToPropertiesMap$1[id]; + if ((p === null || p === void 0 ? void 0 : p.keyFormatString) === formatString) { + selectedId = id; + break; + } + } + } + if (!selectedId) { + throw Error('No matching key system'); + } + return selectedId; + } + // Pick the first key system that works for this id + static requestKeySystemAccess(keysystemId, mediaCapabilities, keySystemConfig, logger) { + if (typeof navigator === 'undefined' || typeof navigator.requestMediaKeySystemAccess === 'undefined') { + return throwError(new KeySystemError('navigator undefined', undefined, 0, ErrorResponses.KeySystemUndefinedNavigator, keysystemId)); + } + const keySystemConstructors = kKeySystemIdToConstructorsMap[keysystemId]; + let obs = throwError(new KeySystemError('no key systems to try', undefined, 0, ErrorResponses.KeySystemNoKeySystemsToTry, keysystemId)); + for (const pair of keySystemConstructors) { + const keySystemString = pair[0]; + const KeySystemConstructor = pair[1]; + const accesConfig = isMediaKeySystemConfig(keySystemConfig) ? keySystemConfig : KeySystemConstructor.requestAccessConfig; + const options = [Object.assign({}, accesConfig, mediaCapabilities)]; + obs = obs.pipe(catchError(() => { + return KeySystemFactory$1.requestKeySystemInternal(keySystemString, options, logger); + })); + } + return obs; + } + /** + * @param keySystemString keySystemString passed to requestMediaKeySystemAccess. e.g. 'com.apple.fps' + * @param options MediaKeySystemConfiguration passed to requestMediaKeySystemAccess + */ + static requestKeySystemInternal(keySystemString, options, logger) { + logger.info(`[Keys] requestKeySystemAccess ${keySystemString} ${JSON.stringify(options)}`); + return defer(() => from(navigator.requestMediaKeySystemAccess(keySystemString, options))); + } + /** + * Create KeySystem object + * + * @param keysystemId Identifier for key system used by HLS.js. e.g. 'fairplaystreaming' 'widevine' + * @param hls Hls object + * @param mediaKeys MediaKeys for KeySystem to manage + * @param keyLoader The loader object + */ + make(keysystemId, mediaKeys, config, eventEmitter, sessionHandler, logger) { + var _a; + const keySystemAccess = (_a = KeySystemFactory$1.idToMediaKeysInfoMap[keysystemId]) === null || _a === void 0 ? void 0 : _a.keySystemAccess; + if (!keySystemAccess) { + throw new KeySystemError(`No keySystemAccess for ${keysystemId}`, undefined, 0, ErrorResponses.KeySystemNoKeySystemAccess, keysystemId); + } + let KeySystemConstructor; + // NOTE: this system string is used in the LICENSE_CHALLENGE_CREATED event for playready and widevine + // as the "keysystem" parameter. Change with caution. + const systemString = kKeySystemIdToPropertiesMap$1[keysystemId].systemStringPrefix; + // Find the matching constructor for the key system string + for (const pair of kKeySystemIdToConstructorsMap[keysystemId]) { + if (pair[0] === keySystemAccess.keySystem) { + KeySystemConstructor = pair[1]; + break; + } + } + if (!KeySystemConstructor) { + throw new KeySystemError(`No constructor associated with ${keysystemId}`, undefined, 0, ErrorResponses.KeySystemNoConstructor, systemString); + } + const keySystem = new KeySystemConstructor(mediaKeys, systemString, config, eventEmitter, sessionHandler, logger); + return keySystem; + } + static get availableKeySystems() { + return Object.keys(kKeySystemIdToPropertiesMap$1); + } + /** + * Get the EXT-X-KEY:FORMAT value associated with the key system + * @param keySystemId Identifier string to request keyFormatString property for + */ + static getKeySystemFormat(keySystemId) { + const properties = kKeySystemIdToPropertiesMap$1[keySystemId]; + return properties ? properties.keyFormatString : ''; + } + static getKeySystemSecurityLevel(keySystemId) { + const properties = kKeySystemIdToPropertiesMap$1[keySystemId]; + return properties ? properties.securityLevels : undefined; + } + } + KeySystemFactory$1.idToMediaKeysInfoMap = {}; + KeySystemFactory$1.destroy$ = new Subject(); + + // Lets set the max slots as couple of slots less than the normally allowed max slot of 8 + const MAX_ALLOWED_KEY_SLOTS = 6; + const kMediaKeySystemConfigCodecs = { + video: ['avc1.42E01E'], + audio: ['mp4a.40.2'], + }; + function convertError(keyUri, error, mediaOptionIds) { + // Convert error if needed + if (!error) { + error = new KeyRequestError('Unknown error from CDM', keyUri, 0, ErrorResponses.KeySystemCDMUnknownError, false, KeyRequestErrorReason.InternalError); + } + else if (error instanceof TimeoutError) { + error = new KeyRequestTimeoutError('Key request timed out', keyUri, ErrorResponses.KeySystemRequestTimedOut); + } + else if (error instanceof KeySystemError) { + const response = (error === null || error === void 0 ? void 0 : error.response) || ErrorResponses.InternalError; + error = new KeyRequestError(error.message, keyUri, 0, response, false, KeyRequestErrorReason.InternalError, true); + } + if (error instanceof KeyRequestError || error instanceof KeyRequestTimeoutError) { + error.mediaOptionIds = [...mediaOptionIds]; + } + return error; + } + class KeySystemAdapter { + constructor(ksService, mediaSink, config, platformQuery, eventEmitter, sessionHandler, logger, keySystemFactory = new KeySystemFactory$1() // For testing + ) { + this.ksService = ksService; + this.mediaSink = mediaSink; + this.config = config; + this.platformQuery = platformQuery; + this.eventEmitter = eventEmitter; + this.sessionHandler = sessionHandler; + this.keySystemFactory = keySystemFactory; + this.reset$ = new Subject(); + this.keyRequest$ = new Subject(); + this.abort$ = new Subject(); // Abort(keyuri) + this.keySystem$ = new BehaviorSubject(null); + this._keyStatusChange$ = new Subject(); + this.protectionData = {}; + this.keySystemId = null; // Identifier for keySystem + this.keyUriToRequest = {}; // keyUri => request observable + this.ksQuery = ksService.getQuery(); + this.logger = logger.child({ name: 'eme' }); + if (this.config.warmupCdms) { + this.keySystemFactory.createMediaKeys(FairPlayStreamingKeySystemProperties.id, kMediaKeySystemConfigCodecs.video, kMediaKeySystemConfigCodecs.audio, this.logger, undefined).subscribe(); + } + const platformInfoChange$ = platformQuery.platformInfo$.pipe(distinctUntilChanged((a, b) => a && b && a.requiresCDMAttachOnStart === b.requiresCDMAttachOnStart), switchMap((platformInfo) => { + if (platformInfo === null || platformInfo === void 0 ? void 0 : platformInfo.requiresCDMAttachOnStart) { + return this.attachMediaKeys().pipe(catchError((err) => { + this.logger.info(`onMediaAttach err:${err.message}`); + this.handleKeySystemError(err); + return EMPTY; + })); + } + else { + return VOID; + } + }), switchMapTo(EMPTY)); + // This is where the key requests actually get subscribed + const keyRequests$ = this.keyRequest$.pipe(mergeMap((request) => { + return request.pipe(catchError(() => { + // In band error gets bubbled up to caller + return EMPTY; + })); + })); + const keyStatusChange$ = this.keySystem$.pipe(switchMap((ks) => { + if (!ks) { + return EMPTY; + } + return ks.keyStatusChange$.pipe(tap((event) => { + var _a; + const keyUri = event.decryptdata.uri; + this.logger.info(`key status change uri=${redactUrl(keyUri)} status=${event.status}`); + const entity = this.ksQuery.getKeyInfo(keyUri); + if (event.status === 'needs-renewal') { + this.ksService.updateKeyRequestState(keyUri, KeyRequestMacroState.MustRequestResponse, (state) => state === KeyRequestMacroState.GotKeyResponse); + } + else { + const error = convertError(keyUri, event.error, (_a = entity === null || entity === void 0 ? void 0 : entity.mediaOptionIds) !== null && _a !== void 0 ? _a : []); + this.ksService.setError(keyUri, error); + } + this._keyStatusChange$.next(event); + })); + })); + const bufferedKeyHandling$ = this.isKeyCleanupSupported() + ? this.mediaSink.mediaQuery.bufferedSegmentsTuple$.pipe(mergeMap((bufferedSegments) => { + const [videoSegments, audioSegments] = bufferedSegments; + const bufferedKeyUris = new Set(); + videoSegments.forEach((bufferedSegment) => { + var _a, _b; + const uri = (_b = (_a = bufferedSegment.frag) === null || _a === void 0 ? void 0 : _a.keyTagInfo) === null || _b === void 0 ? void 0 : _b.uri; + if (uri) { + bufferedKeyUris.add(uri); + } + }); + audioSegments.forEach((bufferedSegment) => { + var _a, _b; + const uri = (_b = (_a = bufferedSegment.frag) === null || _a === void 0 ? void 0 : _a.keyTagInfo) === null || _b === void 0 ? void 0 : _b.uri; + if (uri) { + bufferedKeyUris.add(uri); + } + }); + return this.handleKeyCleanup(bufferedKeyUris); + })) + : VOID; + merge(platformInfoChange$, keyRequests$, keyStatusChange$, bufferedKeyHandling$).pipe(takeUntil(this.reset$)).subscribe(); + } + get keyStatusChange$() { + return this._keyStatusChange$; + } + get keySystem() { + return this.keySystem$.value; + } + destroy() { + this.reset$.next(); // Stop all requests & stop listening to events + this.ksService.removeAll(); // Clear state + this.keySystemId = null; + const keySystem = this.keySystem; + let ksDestroyed$ = VOID; + if (keySystem) { + this.keySystem$.next(null); + if (keySystem.shouldDestroyMediaKeys) { + this.keySystemFactory.destroyMediaKeys(); + } + ksDestroyed$ = keySystem.destroy(); + } + return combineLatest([ksDestroyed$, this.mediaSink.clearMediaKeys()]).pipe(mapTo(undefined)); + } + attachMediaKeys() { + if (this.keySystem) { + // we already wait inside makeKeySystem. nothing to do. Could happen if + // detach happened after keysystem was created (recoverMediaError?) + return VOID; + } + else { + // Create and attach key system. + // Use 'NONE' so we don't get assigned a keyId for no reason + const keyFormatString = this.config.keySystemPreference ? KeySystemFactory$1.getKeySystemFormat(this.config.keySystemPreference) : FairPlayStreamingKeySystemProperties.keyFormatString; + return this.makeKeySystem(new DecryptData('NONE', null, null, keyFormatString, [1])).pipe(mapTo(void 0)); + } + } + isKeyCleanupSupported() { + // At this point of time we have two configurations for fairplay. One with single key session and one with multiple key sessions. + // In case of single key session, we cannot remove the session or key. The cleanup is supported only when multiple key sessions are supported + // Till the app enables that configuration, we should not call cleanup + // By default PlayReady and Widevine use multiple key sessions. But app doesn't pass useMultipleKeySessions in this case. So check for the preference and enable it based on that. + return this.config.useMultipleKeySessions === true || this.config.keySystemPreference === 'widevine' || this.config.keySystemPreference === 'playready'; + } + handleKeyCleanup(bufferedKeyUris) { + if (this.ksQuery.getCount() < MAX_ALLOWED_KEY_SLOTS) { + return VOID; + } + const currentTime = performance.now(); + const keyEntities = this.ksQuery.getAll(); + const removes$ = keyEntities.map((ksEntity) => { + const keyUri = ksEntity.keyUri; + if (!bufferedKeyUris.has(keyUri)) { + const keyTagInfo = entityToKeyTagInfo(ksEntity.decryptdata); + // We don't need to key cleanup for AES-128 and also check if the key has met the minimum holdtime + if (keyTagInfo.method !== 'AES-128' && currentTime > ksEntity.minHoldTime) { + // Remove the entry from store, so that it's no longer tracked + return this._removeKey(keyUri, keyTagInfo); + } + } + return VOID; + }); + return removes$.length ? forkJoin(removes$).pipe(switchMapTo(VOID)) : VOID; + } + _removeKey(keyUri, keyTagInfo) { + this.abort$.next(keyUri); + this.ksService.removeKey(keyUri); + return this.keySystem.removeKey(keyTagInfo); + } + removeKeysForItems(ids) { + const removes$ = []; + applyTransaction(() => { + for (const itemId of ids) { + this.ksService.removeAllKeysForItem(itemId); + const keyInfos = this.ksQuery.getAll({ + filterBy: (entity) => entity.itemIds.length === 0, + }); + for (const keyInfo of keyInfos) { + removes$.push(this._removeKey(keyInfo.keyUri, entityToKeyTagInfo(keyInfo.decryptdata))); + } + } + }); + return removes$.length ? forkJoin(removes$).pipe(switchMap(() => VOID)) : VOID; + } + get availableKeySystems() { + return KeySystemFactory$1.availableKeySystems; + } + initialize(config) { + var _a; + const oldProtectionData = this.protectionData; + this.protectionData = {}; + const preference = this.config.keySystemPreference; + for (const keySystemId of KeySystemFactory$1.availableKeySystems) { + const keysystemConfig = config[keySystemId]; + if (!keysystemConfig) { + continue; + } + if (preference !== keySystemId) { + this.logger.warn(`Key system ${keySystemId} does not match preference ${preference}, ignoring`); + continue; + } + this.logger.info(`Setting protectionData for ${keySystemId}`); + const cert = keysystemConfig.certificate; + const serverCertUrl = keysystemConfig.serverCertUrl ? URLToolkit$1.buildAbsoluteURL(window.location.href, keysystemConfig.serverCertUrl) : undefined; + this.protectionData[keySystemId] = { + serverCertUrl: serverCertUrl, + certificate: cert, + }; + let loadCert$; + if (cert) { + this.logger.info('Got cert'); + loadCert$ = of({ keysystem: keySystemId, certificate: cert }); + } + else if (serverCertUrl && ((_a = oldProtectionData === null || oldProtectionData === void 0 ? void 0 : oldProtectionData[keySystemId]) === null || _a === void 0 ? void 0 : _a.serverCertUrl) !== serverCertUrl) { + this.logger.info(`Loading cert ${redactUrl(serverCertUrl)} `); + let loaderConfig; + if (isCustomUrl(serverCertUrl)) { + loaderConfig = this.config.certLoadPolicy.customURL; + } + else { + loaderConfig = this.config.certLoadPolicy.default; + } + loadCert$ = fromUrlArrayBuffer({ url: serverCertUrl, xhrSetup: this.config.xhrSetup }, loaderConfig).pipe(map(([loadArrayBufferResult, _]) => { + return { keysystem: keySystemId, certificate: new Uint8Array(loadArrayBufferResult) }; + })); + } + if (loadCert$) { + loadCert$ + .pipe(switchMap((data) => this.onServerCertificateLoaded(data)), catchError((err) => { + this.logger.error(`Error loading cert: ${err.message}`); + this.eventEmitter.trigger(HlsEvent$1.INTERNAL_ERROR, { + type: ErrorTypes.NETWORK_ERROR, + details: ErrorDetails.CERT_LOAD_ERROR, + fatal: false, + handled: true, + reason: 'Error handling cert', + response: ErrorResponses.KeySystemCertificateLoadError, + message: err.message, + name: 'certificateLoadError', + }); + // TODO: Save the error and reject any key requests relying on this. + throw err; + }), takeUntil(this.reset$)) + .subscribe(); + } + } + } + /** + * Generate challenge using request info + */ + generateRequest(keyuri, requestInfo) { + if (this.keySystem) { + this.keySystem.setKeyRequestInfo(keyuri, requestInfo); + } + } + /** + * Set the challenge response + */ + setLicenseResponse(keyuri, response) { + if (this.keySystem) { + this.keySystem.setParsedResponse(keyuri, response); + } + } + /** + * Called from externally to retrieve key. + * @param decryptdata Info about the key to retrieve + * @param mediaOptionId Id of level associated with this key request. Used for error handling + * @returns Observable of type DecryptData. Will signal on success, or throw an Error + **/ + getKeyFromDecryptData(decryptdata, mediaOptionKey) { + if (!decryptdata || !decryptdata.isEncrypted) { + return of(decryptdata); // Return immediately + } + let obs; + applyTransaction(() => { + obs = this._getKeyFromDecryptData(decryptdata, mediaOptionKey); + }); + return obs; + } + _getKeyFromDecryptData(decryptdata, mediaOptionKey) { + let itemId = null; + let mediaOptionId = null; + if (mediaOptionKey) { + itemId = mediaOptionKey.itemId; + mediaOptionId = mediaOptionKey.mediaOptionId; + } + const keyUri = decryptdata.uri; + const keyEntity = this.ksQuery.getKeyInfo(keyUri); + if (keyEntity && mediaOptionKey != null) { + this.ksService.addMediaOption(keyUri, mediaOptionKey); + } + const permanentError = (keyEntity === null || keyEntity === void 0 ? void 0 : keyEntity.error) instanceof KeyRequestError && keyEntity.error.isOkToRetry === false; + if (permanentError) { + return throwError(keyEntity.error); + } + else if (!keyEntity || keyEntity.requestState === KeyRequestMacroState.MustRequestResponse) { + this.logger.info(`getKeyFromDecryptData mediaOptionId=${mediaOptionId} method=${decryptdata.method} keyuri=${redactUrl(keyUri)} state=${keyEntity === null || keyEntity === void 0 ? void 0 : keyEntity.requestState}`); + // specify minimum duration a key may exist in the system before itÃĸâ‚Ŧâ„ĸs eligible for eviction + const minHoldTime = performance.now() + this.config.keyMinHoldTimeBeforeCleanup; + // Abort any old requests + this.abort$.next(keyUri); + this.ksService.upsertKey({ + keyUri, + decryptdata: keyTagInfoToEntity(decryptdata), + minHoldTime, + mediaOptionIds: [mediaOptionId], + requestState: KeyRequestMacroState.WaitingForKeyResponse, + itemIds: [itemId], + }); + // Now start fetching key + let request; + const method = decryptdata.method; + switch (method) { + case 'SAMPLE-AES': + case 'ISO-23001-7': + case 'SAMPLE-AES-CTR': { + const loadPolicy = this.config.keyLoadPolicy.customURL; + request = this.fetchKeyEME(decryptdata).pipe(timeout(loadPolicy.maxLoadTimeMs)); + break; + } + case 'AES-128': + request = this.fetchKeyHTTP(decryptdata.uri, decryptdata, this.config.keyLoadPolicy); + break; + default: + const err = new ExceptionError(false, `Unexpected METHOD attribute ${method}`, ErrorResponses.KeySystemUnexpectedMETHOD); + return throwError(err); + } + // TODO: stats + const request$ = (this.keyUriToRequest[keyUri] = request.pipe(map((keyLoadedData) => { + const decryptdata = keyLoadedData.decryptdata; + this.ksService.updateKeyValue(keyUri, decryptdata.key); + this.eventEmitter.trigger(HlsEvent$1.KEY_LOADED, keyLoadedData); + return keyLoadedData.decryptdata; + }), catchError((err) => { + var _a; + const keyEntity = this.ksQuery.getKeyInfo(keyUri); + err = convertError(keyUri, err, (_a = keyEntity === null || keyEntity === void 0 ? void 0 : keyEntity.mediaOptionIds) !== null && _a !== void 0 ? _a : []); + this.ksService.setError(keyUri, err); + return throwError(err); + }), finalize$1(() => { + // Update state for abort() only if we were in progress + this.ksService.updateKeyRequestState(keyUri, KeyRequestMacroState.MustRequestResponse, (state) => state === KeyRequestMacroState.WaitingForKeyResponse); + this.keyUriToRequest[keyUri] = null; + this.logger.debug(`${printKeyTag(decryptdata)} finalize state=${this.ksQuery.getKeyInfo(keyUri).requestState}`); + }), share(), takeUntil(race(this.abort$.pipe(filter((uri) => uri === keyUri)), this.reset$).pipe(tap((uri) => this.logger.warn(uri ? `aborted ${redactUrl(uri)}` : 'got reset')))))); + this.keyRequest$.next(request$); // Subscribes to key request + return request$; + } + else if (keyEntity.requestState === KeyRequestMacroState.GotKeyResponse) { + return of(entityToKeyTagInfo(keyEntity.decryptdata)); + } + // requestState === KeyRequestMacroState.WaitingForKeyResponse + return this.keyUriToRequest[keyUri]; + } + fetchKeyEME(decryptdata) { + return this.requestKey(decryptdata).pipe(map((decryptdata) => { + const now = performance.now(); + const data = { + timestamp: now, + keyuri: decryptdata.uri, + decryptdata, + /*stats: { + trequest: keyInfo.stats.trequest, + tfirst: keyInfo.stats.tfirst, + tload: now + }*/ + }; + return data; + })); + } + /** + * Make generic HTTP request for key + * @param uri The URL to make request to + * @param decryptdata Associated DecryptData object + * @param loadTimeoutMs + */ + fetchKeyHTTP(uri, decryptdata, loadPolicy) { + return KeySystemAdapter.fetchKeyHTTP(uri, this.config, decryptdata, loadPolicy); + } + static fetchKeyHTTP(uri, config, decryptdata, loadPolicy) { + const loadable = { + url: uri, + xhrSetup: config.xhrSetup, + }; + return fromUrlArrayBuffer(loadable, getLoadConfig(loadable, loadPolicy)).pipe(map(([loadArrayBufferResult, _]) => { + decryptdata.key = new Uint8Array(loadArrayBufferResult); + const loadedData = { + decryptdata, + keyuri: uri, + timestamp: performance.now(), + /*stats: { + trequest: keyInfo.stats.trequest, + tfirst: keyInfo.stats.tfirst, + tload: now + }*/ + }; + return loadedData; + })); + } + requestKey(decryptdata) { + // Assumed called from key loader and that it already checked the method and that it's encrypted, etc. + this.logger.debug(`requestKey - uri=${redactUrl(decryptdata.uri)}`); + return this.makeKeySystem(decryptdata).pipe(switchMap((keySystem) => { + return keySystem.startKeyRequest(decryptdata); + })); + } + ensureKeySystem(mediaKeys) { + return defer(() => { + if (!this.keySystem && this.keySystemId) { + this.keySystem$.next(this.keySystemFactory.make(this.keySystemId, mediaKeys, this.config, this.eventEmitter, this.sessionHandler, this.logger)); + const protData = this.protectionData && this.protectionData[this.keySystemId]; + if (protData) { + return this.keySystem.setServerCertificate(protData.certificate).pipe(mapTo(this.keySystem)); + } + } + return of(this.keySystem); + }); + } + /** + * Make MediaKeys object for decryptdata and attach to current media element + * Also creates a KeySystem object + * @param decryptdata The KeyTagInfo object + */ + makeKeySystem(decryptdata) { + this.logger.debug(`makeKeySystem - uri=${redactUrl(decryptdata.uri)}`); + return this.ensureMediaKeys(decryptdata).pipe(switchMap((mediaKeys) => { + this.logger.debug(`setMediaKeys - uri=${redactUrl(decryptdata.uri)}`); + return this.mediaSink.setMediaKeys(mediaKeys).pipe(switchMap(() => { + this.logger.debug(`ensureKeySystem - uri=${redactUrl(decryptdata.uri)}`); + // Create KeySystem object + return this.ensureKeySystem(mediaKeys); + })); + })); + } + // Create MediaKeys object. + ensureMediaKeys(decryptdata) { + var _a; + const newKeySystemId = KeySystemFactory$1.getKeySystemIdForDecryptData(decryptdata); + if (this.keySystemId == null) { + this.keySystemId = newKeySystemId; + } + else if (this.keySystemId !== newKeySystemId) { + const err = new KeyRequestError(`New key system string does not match existing ${newKeySystemId} !== ${this.keySystemId}`, decryptdata.uri, 0, ErrorResponses.KeySystemUnmatchedString, false, KeyRequestErrorReason.InternalError); + return throwError(err); + } + // CreateMediaKeys will return the same promise for a given key system ID if it's already being created. + return this.keySystemFactory.createMediaKeys(this.keySystemId, kMediaKeySystemConfigCodecs.video, kMediaKeySystemConfigCodecs.audio, this.logger, (_a = this.platformQuery.platformInfo) === null || _a === void 0 ? void 0 : _a.keySystemConfig); + } + /** + * + * @param data { keysystem: keysystem identifier, certificate: the buffer containing the cert } + */ + onServerCertificateLoaded(data) { + const keySystemId = data.keysystem, certificate = data.certificate; + this.logger.info(`KeySystemAdapter: ${keySystemId} cert loaded ${certificate ? 'nonnull' : 'null'}`); + const protData = this.protectionData[keySystemId]; + protData.certificate = certificate; + this.logger.debug(`current keySystemId: ${this.keySystemId}`); + if (this.keySystem && this.keySystemId === keySystemId) { + return this.keySystem.setServerCertificate(certificate).pipe(mapTo(undefined)); + } + return VOID; + } + // Trigger error due to key system setup issue + handleKeySystemError(error) { + const keyError = new KeySystemError(error.message, undefined, undefined, ErrorResponses.KeySystemSetupError, undefined); + this.eventEmitter.trigger(HlsEvent$1.INTERNAL_ERROR, keyError); + } + } + + class KeySystemQuery extends QueryEntity { + constructor(store) { + super(store); + } + /** + * @returns the key info for a particular key + */ + getKeyInfo(keyuri) { + const entity = this.getEntity(keyuri); + if (entity) { + // Populate with proper mediaOptionIds every time + return Object.assign(Object.assign({}, entity), { error: copyKeyError(entity.error, entity.mediaOptionIds) }); + } + return null; + } + getKeyInfo$(keyuri) { + return this.selectEntity(keyuri).pipe(map((entity) => { + if (entity) { + // Populate with proper mediaOptionIds every time + return Object.assign(Object.assign({}, entity), { error: copyKeyError(entity.error, entity.mediaOptionIds) }); + } + else { + return null; + } + })); + } + getKeyRequestState$(keyuri) { + return this.selectEntity(keyuri, (entity) => entity === null || entity === void 0 ? void 0 : entity.requestState); + } + /** + * @returns an observable that emits whenever the key status changes + */ + getKeyStatus$(keyuri) { + return this.selectEntity(keyuri, (entity) => entity === null || entity === void 0 ? void 0 : entity.status); + } + /** + * @returns an observable that emits whenever we got an error on a particular key + */ + getKeyError$(keyuri) { + return this.selectEntity(keyuri, (entity) => copyKeyError(entity === null || entity === void 0 ? void 0 : entity.error, entity === null || entity === void 0 ? void 0 : entity.mediaOptionIds)).pipe(filterNil); + } + } + + /** + * @brief Backing store for the playback state + */ + class KeySystemStore extends EntityStore { + constructor() { + super({}, { name: 'key-system-store', idKey: 'keyUri', producerFn: produce_1 }); + } + } + + /** + * @brief Service that manages playback state + */ + class KeySystemService { + constructor(store) { + this.store = store; + } + getQuery() { + return new KeySystemQuery(this.store); + } + upsertKey(keyEntity) { + logAction('keys.upsert', keyEntity.keyUri); + const newItemIdSet = new Set(keyEntity.itemIds.filter((x) => x != null)); + const newMediaOptionIdSet = new Set(keyEntity.mediaOptionIds.filter((x) => x != null)); + this.store.upsert(keyEntity.keyUri, + // Update existing + (oldEntity) => { + const mergedEntity = Object.assign(Object.assign({}, oldEntity), keyEntity); + // Merge itemIds & mediaOptionIds + if ('itemIds' in oldEntity) { + for (const itemId of oldEntity.itemIds) { + newItemIdSet.add(itemId); + } + } + mergedEntity.itemIds = Array.from(newItemIdSet); + if ('mediaOptionIds' in oldEntity) { + for (const mediaOptionId of oldEntity.mediaOptionIds) { + newMediaOptionIdSet.add(mediaOptionId); + } + } + mergedEntity.mediaOptionIds = Array.from(newMediaOptionIdSet); + return mergedEntity; + }, + // Create new entity + () => (Object.assign(Object.assign({}, keyEntity), { itemIds: Array.from(newItemIdSet), mediaOptionIds: Array.from(newMediaOptionIdSet) }))); + } + removeKey(keyUri) { + logAction('keys.removeKey', keyUri); + this.store.remove(keyUri); + } + removeAllKeysForItem(itemId) { + logAction(`keys.removeAllKeysForItem ${itemId}`); + this.store.update(null, (entity) => { + // Remove itemid from itemId list + const idx = entity.itemIds.findIndex((id) => id === itemId); + if (idx >= 0) { + entity.itemIds.splice(idx, 1); + } + }); + } + removeAll() { + logAction('keys.remove'); + this.store.remove(); + } + updateKeyValue(keyUri, key) { + logAction('keys.updateKeyValue', keyUri); + this.store.update(keyUri, (entity) => { + if (entity.decryptdata.keyBuf == null && key != null) { + entity.decryptdata.keyBuf = key.buffer; + } + entity.requestState = KeyRequestMacroState.GotKeyResponse; + }); + } + updateKeyStatus(keyUri, status) { + logAction(`keys.updateKeyStatus ${status}`, keyUri); + this.store.update(keyUri, (entity) => { + entity.status = status; + }); + } + updateKeyRequestState(keyUri, requestState, predicate) { + logAction(`keys.updateKeyRequestState ${requestState}`, keyUri); + this.store.update(keyUri, (entity) => { + if (!predicate || predicate(entity.requestState)) { + entity.requestState = requestState; + } + }); + } + addMediaOption(keyUri, mediaOptionKey) { + const { itemId, mediaOptionId } = mediaOptionKey; + logAction(`keys.addMediaOption itemId: ${itemId}, mediaOptionId: ${mediaOptionId}`, keyUri); + this.store.update(keyUri, (entity) => { + if (mediaOptionId != null) { + if (entity.mediaOptionIds.every((id) => id !== mediaOptionId)) { + entity.mediaOptionIds.push(mediaOptionId); + } + } + if (itemId != null) { + if (entity.itemIds.every((id) => id !== itemId)) { + entity.itemIds.push(itemId); + } + } + }); + } + setError(keyUri, error) { + var _a; + logAction(`keys.setError ${(_a = error === null || error === void 0 ? void 0 : error.constructor) === null || _a === void 0 ? void 0 : _a.name}`, keyUri); + this.store.update(keyUri, (entity) => { + // Make a copy so that entity.error is not modified after storage + entity.error = copyKeyError(error); + entity.requestState = KeyRequestMacroState.MustRequestResponse; + }); + } + } + // state for the service functions + const keySystemStore = new KeySystemStore(); + let globalKeySystemService = null; + function keySystemService() { + if (!globalKeySystemService) { + globalKeySystemService = new KeySystemService(keySystemStore); + } + return globalKeySystemService; + } + const makeKeySystemService = (keySystemService, source$, itemRemove$, config, platformQuery, eventEmitter, sessionHandler, logger) => { + return source$.pipe(tag('[Keys] playback.keySystemServiceEpic.in'), switchMap((mediaSink) => { + if (!mediaSink) { + return of(null); + } + return new Observable((subscriber) => { + let keySystemAdapter = new KeySystemAdapter(keySystemService, mediaSink, config, platformQuery, eventEmitter, sessionHandler, logger); + const sub = merge(of(keySystemAdapter), itemRemove$.pipe(mergeMap((ids) => { + return keySystemAdapter.removeKeysForItems(ids); + }), switchMapTo(EMPTY))).subscribe(subscriber); + return function unsubscribe() { + logger.warn('[Keys] playback.keySystemServiceEpic.unsubscribe'); + sub.unsubscribe(); + keySystemAdapter.destroy().subscribe(); + keySystemAdapter = undefined; + }; + }); + }), tag('[Keys] playback.keySystemServiceEpic.emit')); + }; + + function isAlternateMediaOption(option) { + return 'groupId' in option; + } + + function safeAssignProperties(target, source) { + return Object.assign(target, source); + } + /** + * Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes + */ + const specialCea608CharsCodes = { + 42: 225, + 92: 233, + 94: 237, + 95: 243, + 96: 250, + 123: 231, + 124: 247, + 125: 209, + 126: 241, + 127: 9608, + // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS + // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F + // THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES + 128: 174, + 129: 176, + 130: 189, + 131: 191, + 132: 8482, + 133: 162, + 134: 163, + 135: 9834, + 136: 224, + 137: 32, + 138: 232, + 139: 226, + 140: 234, + 141: 238, + 142: 244, + 143: 251, + // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS + // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F + 144: 193, + 145: 201, + 146: 211, + 147: 218, + 148: 220, + 149: 252, + 150: 8216, + 151: 161, + 152: 42, + 153: 8217, + 154: 9473, + 155: 169, + 156: 8480, + 157: 8226, + 158: 8220, + 159: 8221, + 160: 192, + 161: 194, + 162: 199, + 163: 200, + 164: 202, + 165: 203, + 166: 235, + 167: 206, + 168: 207, + 169: 239, + 170: 212, + 171: 217, + 172: 249, + 173: 219, + 174: 171, + 175: 187, + // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS + // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F + 176: 195, + 177: 227, + 178: 205, + 179: 204, + 180: 236, + 181: 210, + 182: 242, + 183: 213, + 184: 245, + 185: 123, + 186: 125, + 187: 92, + 188: 94, + 189: 95, + 190: 124, + 191: 8764, + 192: 196, + 193: 228, + 194: 214, + 195: 246, + 196: 223, + 197: 165, + 198: 164, + 199: 9475, + 200: 197, + 201: 229, + 202: 216, + 203: 248, + 204: 9487, + 205: 9491, + 206: 9495, + 207: 9499, // Box drawings heavy up and left + }; + /** + * Utils + */ + const getCharForByte = function (byte) { + let charCode = byte; + // eslint-disable-next-line no-prototype-builtins + if (specialCea608CharsCodes.hasOwnProperty(byte)) { + charCode = specialCea608CharsCodes[byte]; + } + return String.fromCharCode(charCode); + }; + const NR_ROWS = 15, NR_COLS = 100; + // Tables to look up row from PAC data + const rowsLowCh1 = { 17: 1, 18: 3, 21: 5, 22: 7, 23: 9, 16: 11, 19: 12, 20: 14 }; + const rowsHighCh1 = { 17: 2, 18: 4, 21: 6, 22: 8, 23: 10, 19: 13, 20: 15 }; + const rowsLowCh2 = { 25: 1, 26: 3, 29: 5, 30: 7, 31: 9, 24: 11, 27: 12, 28: 14 }; + const rowsHighCh2 = { 25: 2, 26: 4, 29: 6, 30: 8, 31: 10, 27: 13, 28: 15 }; + const backgroundColors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'black', 'transparent']; + const logger = { + verboseFilter: { DATA: 3, DEBUG: 3, INFO: 2, WARNING: 2, TEXT: 1, ERROR: 0 }, + time: null, + verboseLevel: 0, + setTime: function (newTime) { + this.time = newTime; + }, + log: function (severity, msg) { + const minLevel = this.verboseFilter[severity]; + if (this.verboseLevel >= minLevel) { + // eslint-disable-next-line no-console + console.log(this.time + ' [' + severity + '] ' + msg); + } + }, + }; + const numArrayToHexArray = function (numArray) { + const hexArray = []; + for (let j = 0; j < numArray.length; j++) { + hexArray.push(numArray[j].toString(16)); + } + return hexArray; + }; + class PenState { + constructor(foreground, underline, italics, background, flash) { + this.foreground = foreground || 'white'; + this.underline = underline || false; + this.italics = italics || false; + this.background = background || 'black'; + this.flash = flash || false; + } + reset() { + this.foreground = 'white'; + this.underline = false; + this.italics = false; + this.background = 'black'; + this.flash = false; + } + setStyles(styles) { + safeAssignProperties(this, styles); + } + isDefault() { + return this.foreground === 'white' && !this.underline && !this.italics && this.background === 'black' && !this.flash; + } + equals(other) { + return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash; + } + copy(newPenState) { + this.foreground = newPenState.foreground; + this.underline = newPenState.underline; + this.italics = newPenState.italics; + this.background = newPenState.background; + this.flash = newPenState.flash; + } + toString() { + return 'color=' + this.foreground + ', underline=' + this.underline + ', italics=' + this.italics + ', background=' + this.background + ', flash=' + this.flash; + } + } + /** + * Unicode character with styling and background. + * @constructor + */ + class StyledUnicodeChar { + constructor(uchar, foreground, underline, italics, background, flash) { + this.uchar = uchar || ' '; // unicode character + this.penState = new PenState(foreground, underline, italics, background, flash); + } + reset() { + this.uchar = ' '; + this.penState.reset(); + } + setChar(uchar, newPenState) { + this.uchar = uchar; + this.penState.copy(newPenState); + } + setPenState(newPenState) { + this.penState.copy(newPenState); + } + equals(other) { + return this.uchar === other.uchar && this.penState.equals(other.penState); + } + copy(newChar) { + this.uchar = newChar.uchar; + this.penState.copy(newChar.penState); + } + isEmpty() { + return this.uchar === ' ' && this.penState.isDefault(); + } + } + /** + * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar. + * @constructor + */ + class Row { + constructor() { + this.chars = []; + for (let i = 0; i < NR_COLS; i++) { + this.chars.push(new StyledUnicodeChar()); + } + this.pos = 0; + this.currPenState = new PenState(); + } + equals(other) { + let equal = true; + for (let i = 0; i < NR_COLS; i++) { + if (!this.chars[i].equals(other.chars[i])) { + equal = false; + break; + } + } + return equal; + } + copy(other) { + for (let i = 0; i < NR_COLS; i++) { + this.chars[i].copy(other.chars[i]); + } + } + isEmpty() { + let empty = true; + for (let i = 0; i < NR_COLS; i++) { + if (!this.chars[i].isEmpty()) { + empty = false; + break; + } + } + return empty; + } + /** + * Set the cursor to a valid column. + */ + setCursor(absPos) { + if (this.pos !== absPos) { + this.pos = absPos; + } + if (this.pos < 0) { + logger.log('ERROR', 'Negative cursor position ' + this.pos); + this.pos = 0; + } + else if (this.pos > NR_COLS) { + logger.log('ERROR', 'Too large cursor position ' + this.pos); + this.pos = NR_COLS; + } + } + /** + * Move the cursor relative to current position. + */ + moveCursor(relPos) { + const newPos = this.pos + relPos; + if (relPos > 1) { + for (let i = this.pos + 1; i < newPos + 1; i++) { + this.chars[i].setPenState(this.currPenState); + } + } + this.setCursor(newPos); + } + /** + * Backspace, move one step back and clear character. + */ + backSpace() { + this.moveCursor(-1); + this.chars[this.pos].setChar(' ', this.currPenState); + } + insertChar(byte) { + if (byte >= 144) { + // Extended char + this.backSpace(); + } + const char = getCharForByte(byte); + if (this.pos >= NR_COLS) { + logger.log('ERROR', 'Cannot insert ' + byte.toString(16) + ' (' + char + ') at position ' + this.pos + '. Skipping it!'); + return; + } + this.chars[this.pos].setChar(char, this.currPenState); + this.moveCursor(1); + } + clearFromPos(startPos) { + let i; + for (i = startPos; i < NR_COLS; i++) { + this.chars[i].reset(); + } + } + clear() { + this.clearFromPos(0); + this.pos = 0; + this.currPenState.reset(); + } + clearToEndOfRow() { + this.clearFromPos(this.pos); + } + getTextString() { + const chars = []; + let empty = true; + for (let i = 0; i < NR_COLS; i++) { + const char = this.chars[i].uchar; + if (char !== ' ') { + empty = false; + } + chars.push(char); + } + if (empty) { + return ''; + } + else { + return chars.join(''); + } + } + setPenStyles(styles) { + this.currPenState.setStyles(styles); + const currChar = this.chars[this.pos]; + currChar.setPenState(this.currPenState); + } + } + /** + * Keep a CEA-608 screen of 32x15 styled characters + * @constructor + */ + class CaptionScreen { + constructor() { + this.rows = []; + for (let i = 0; i < NR_ROWS; i++) { + this.rows.push(new Row()); // Note that we use zero-based numbering (0-14) + } + this.currRow = NR_ROWS - 1; + this.nrRollUpRows = null; + this.reset(); + } + reset() { + for (let i = 0; i < NR_ROWS; i++) { + this.rows[i].clear(); + } + this.currRow = NR_ROWS - 1; + } + equals(other) { + let equal = true; + for (let i = 0; i < NR_ROWS; i++) { + if (!this.rows[i].equals(other.rows[i])) { + equal = false; + break; + } + } + return equal; + } + copy(other) { + for (let i = 0; i < NR_ROWS; i++) { + this.rows[i].copy(other.rows[i]); + } + } + isEmpty() { + let empty = true; + for (let i = 0; i < NR_ROWS; i++) { + if (!this.rows[i].isEmpty()) { + empty = false; + break; + } + } + return empty; + } + backSpace() { + const row = this.rows[this.currRow]; + row.backSpace(); + } + clearToEndOfRow() { + const row = this.rows[this.currRow]; + row.clearToEndOfRow(); + } + /** + * Insert a character (without styling) in the current row. + */ + insertChar(char) { + const row = this.rows[this.currRow]; + row.insertChar(char); + } + setPen(styles) { + const row = this.rows[this.currRow]; + row.setPenStyles(styles); + } + moveCursor(relPos) { + const row = this.rows[this.currRow]; + row.moveCursor(relPos); + } + setCursor(absPos) { + logger.log('INFO', 'setCursor: ' + absPos); + const row = this.rows[this.currRow]; + row.setCursor(absPos); + } + setPAC(pacData) { + logger.log('INFO', 'pacData = ' + JSON.stringify(pacData)); + let newRow = pacData.row - 1; + if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) { + newRow = this.nrRollUpRows - 1; + } + // Make sure this only affects Roll-up Captions by checking this.nrRollUpRows + if (this.nrRollUpRows && this.currRow !== newRow) { + // clear all rows first + for (let i = 0; i < NR_ROWS; i++) { + this.rows[i].clear(); + } + // Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location + // topRowIndex - the start of rows to copy (inclusive index) + const topRowIndex = this.currRow + 1 - this.nrRollUpRows; + // We only copy if the last position was already shown. + // We use the cueStartTime value to check this. + const lastOutputScreen = this.lastOutputScreen; + if (lastOutputScreen) { + const prevLineTime = lastOutputScreen.rows[topRowIndex].cueStartTime; + if (prevLineTime && prevLineTime < logger.time) { + for (let i = 0; i < this.nrRollUpRows; i++) { + this.rows[newRow - this.nrRollUpRows + i + 1].copy(lastOutputScreen.rows[topRowIndex + i]); + } + } + } + } + this.currRow = newRow; + const row = this.rows[this.currRow]; + if (pacData.indent !== null) { + const indent = pacData.indent; + const prevPos = Math.max(indent - 1, 0); + row.setCursor(pacData.indent); + pacData.color = row.chars[prevPos].penState.foreground; + } + const styles = { foreground: pacData.color, underline: pacData.underline, italics: pacData.italics, background: 'black', flash: false }; + this.setPen(styles); + } + /** + * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility). + */ + setBkgData(bkgData) { + logger.log('INFO', 'bkgData = ' + JSON.stringify(bkgData)); + this.backSpace(); + this.setPen(bkgData); + this.insertChar(32); // Space + } + setRollUpRows(nrRows) { + this.nrRollUpRows = nrRows; + } + rollUp() { + if (this.nrRollUpRows === null) { + logger.log('DEBUG', 'roll_up but nrRollUpRows not set yet'); + return; // Not properly setup + } + logger.log('INFO', 'TEXT ' + this.getDisplayText()); + const topRowIndex = this.currRow + 1 - this.nrRollUpRows; + const topRow = this.rows.splice(topRowIndex, 1)[0]; + topRow.clear(); + this.rows.splice(this.currRow, 0, topRow); + logger.log('INFO', 'Rolling up'); + } + /** + * Get all non-empty rows with as unicode text. + */ + getDisplayText(asOneRow) { + asOneRow = asOneRow || false; + const displayText = []; + let text = ''; + let rowNr = -1; + for (let i = 0; i < NR_ROWS; i++) { + const rowText = this.rows[i].getTextString(); + if (rowText) { + rowNr = i + 1; + if (asOneRow) { + displayText.push('Row ' + rowNr + ': \'' + rowText + '\''); + } + else { + displayText.push(rowText.trim()); + } + } + } + if (displayText.length > 0) { + if (asOneRow) { + text = '[' + displayText.join(' | ') + ']'; + } + else { + text = displayText.join('\n'); + } + } + return text; + } + getTextAndFormat() { + return this.rows; + } + } + // var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT']; + class Cea608Channel { + constructor(channelNumber, outputFilter) { + this.chNr = channelNumber; + this.outputFilter = outputFilter; + this.mode = null; + this.verbose = 0; + this.displayedMemory = new CaptionScreen(); + this.nonDisplayedMemory = new CaptionScreen(); + this.lastOutputScreen = new CaptionScreen(); + this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; + this.writeScreen = this.displayedMemory; + this.mode = null; + this.cueStartTime = null; // Keeps track of where a cue started. + } + reset() { + this.mode = null; + this.displayedMemory.reset(); + this.nonDisplayedMemory.reset(); + this.lastOutputScreen.reset(); + this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; + this.writeScreen = this.displayedMemory; + this.mode = null; + this.cueStartTime = null; + this.lastCueEndTime = null; + } + getHandler() { + return this.outputFilter; + } + setHandler(newHandler) { + this.outputFilter = newHandler; + } + setPAC(pacData) { + this.writeScreen.setPAC(pacData); + } + setBkgData(bkgData) { + this.writeScreen.setBkgData(bkgData); + } + setMode(newMode) { + if (newMode === this.mode) { + return; + } + this.mode = newMode; + logger.log('INFO', 'MODE=' + newMode); + if (this.mode === 'MODE_POP-ON') { + this.writeScreen = this.nonDisplayedMemory; + } + else { + this.writeScreen = this.displayedMemory; + this.writeScreen.reset(); + } + if (this.mode !== 'MODE_ROLL-UP') { + this.displayedMemory.nrRollUpRows = null; + this.nonDisplayedMemory.nrRollUpRows = null; + } + this.mode = newMode; + } + insertChars(chars) { + for (let i = 0; i < chars.length; i++) { + this.writeScreen.insertChar(chars[i]); + } + const screen = this.writeScreen === this.displayedMemory ? 'DISP' : 'NON_DISP'; + logger.log('INFO', screen + ': ' + this.writeScreen.getDisplayText(true)); + if (this.mode === 'MODE_PAINT-ON' || this.mode === 'MODE_ROLL-UP') { + logger.log('TEXT', 'DISPLAYED: ' + this.displayedMemory.getDisplayText(true)); + this.outputDataUpdate(); + } + } + ccRCL() { + // Resume Caption Loading (switch mode to Pop On) + logger.log('INFO', 'RCL - Resume Caption Loading'); + this.setMode('MODE_POP-ON'); + } + ccBS() { + // BackSpace + logger.log('INFO', 'BS - BackSpace'); + if (this.mode === 'MODE_TEXT') { + return; + } + this.writeScreen.backSpace(); + if (this.writeScreen === this.displayedMemory) { + this.outputDataUpdate(); + } + } + ccAOF() { + // Reserved (formerly Alarm Off) + return; + } + ccAON() { + // Reserved (formerly Alarm On) + return; + } + ccDER() { + // Delete to End of Row + logger.log('INFO', 'DER- Delete to End of Row'); + this.writeScreen.clearToEndOfRow(); + this.outputDataUpdate(); + } + ccRU(nrRows) { + // Roll-Up Captions-2,3,or 4 Rows + logger.log('INFO', 'RU(' + nrRows + ') - Roll Up'); + this.writeScreen = this.displayedMemory; + this.setMode('MODE_ROLL-UP'); + this.writeScreen.setRollUpRows(nrRows); + } + ccFON() { + // Flash On + logger.log('INFO', 'FON - Flash On'); + this.writeScreen.setPen({ flash: true }); + } + ccRDC() { + // Resume Direct Captioning (switch mode to PaintOn) + logger.log('INFO', 'RDC - Resume Direct Captioning'); + this.setMode('MODE_PAINT-ON'); + } + ccTR() { + // Text Restart in text mode (not supported, however) + logger.log('INFO', 'TR'); + this.setMode('MODE_TEXT'); + } + ccRTD() { + // Resume Text Display in Text mode (not supported, however) + logger.log('INFO', 'RTD'); + this.setMode('MODE_TEXT'); + } + ccEDM() { + // Erase Displayed Memory + logger.log('INFO', 'EDM - Erase Displayed Memory'); + this.displayedMemory.reset(); + this.outputDataUpdate(true); + } + ccCR() { + // Carriage Return + logger.log('INFO', 'CR - Carriage Return'); + this.writeScreen.rollUp(); + this.outputDataUpdate(true); + } + ccENM() { + // Erase Non-Displayed Memory + logger.log('INFO', 'ENM - Erase Non-displayed Memory'); + this.nonDisplayedMemory.reset(); + } + ccEOC() { + // End of Caption (Flip Memories) + logger.log('INFO', 'EOC - End Of Caption'); + if (this.mode === 'MODE_POP-ON') { + const tmp = this.displayedMemory; + this.displayedMemory = this.nonDisplayedMemory; + this.nonDisplayedMemory = tmp; + this.writeScreen = this.nonDisplayedMemory; + logger.log('TEXT', 'DISP: ' + this.displayedMemory.getDisplayText()); + } + this.outputDataUpdate(true); + } + ccTO(nrCols) { + // Tab Offset 1,2, or 3 columns + logger.log('INFO', 'TO(' + nrCols + ') - Tab Offset'); + this.writeScreen.moveCursor(nrCols); + } + ccMIDROW(secondByte) { + // Parse MIDROW command + const styles = { flash: false, underline: false, italics: false }; + styles.underline = secondByte % 2 === 1; + styles.italics = secondByte >= 46; + if (!styles.italics) { + const colorIndex = Math.floor(secondByte / 2) - 16; + const colors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta']; + styles.foreground = colors[colorIndex]; + } + else { + styles.foreground = 'white'; + } + logger.log('INFO', 'MIDROW: ' + JSON.stringify(styles)); + this.writeScreen.setPen(styles); + } + outputDataUpdate(dispatch = false) { + const t = logger.time; + if (t === null) { + return; + } + if (this.outputFilter) { + if (this.outputFilter.updateData) { + this.outputFilter.updateData(t, this.displayedMemory); + } + if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) { + // Start of a new cue + this.cueStartTime = t; + } + else { + if (!this.displayedMemory.equals(this.lastOutputScreen)) { + if (this.outputFilter.newCue) { + this.outputFilter.newCue(this.cueStartTime, t, this.lastOutputScreen); + if (dispatch === true && this.outputFilter.dispatchCue) { + this.outputFilter.dispatchCue(); + } + } + this.cueStartTime = this.displayedMemory.isEmpty() ? null : t; + } + } + this.lastOutputScreen.copy(this.displayedMemory); + } + } + cueSplitAtTime(t) { + if (this.outputFilter) { + if (!this.displayedMemory.isEmpty()) { + if (this.outputFilter.newCue) { + this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory); + } + this.cueStartTime = t; + } + } + } + } + class Cea608Parser { + constructor(field = 1, out1, out2) { + this.field = field; + this.currChNr = -1; // Will be 1 or 2 + this.lastCmdA = null; // First byte of last command + this.lastCmdB = null; // Second byte of last command + this.channels = [new Cea608Channel(1, out1), new Cea608Channel(2, out2)]; + this.dataCounters = { padding: 0, char: 0, cmd: 0, other: 0 }; + } + getHandler(index) { + return this.channels[index].getHandler(); + } + setHandler(index, newHandler) { + this.channels[index].setHandler(newHandler); + } + /** + * Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs. + */ + addData(t, byteList) { + let cmdFound, a, b; + let charsFound = null; + logger.setTime(t); + for (let i = 0; i < byteList.length; i += 2) { + a = byteList[i] & 127; + b = byteList[i + 1] & 127; + if (a >= 16 && a <= 31 && a === this.lastCmdA && b === this.lastCmdB) { + this.lastCmdA = null; + this.lastCmdB = null; + logger.log('DEBUG', 'Repeated command (' + numArrayToHexArray([a, b]) + ') is dropped'); + continue; // Repeated commands are dropped (once) + } + if (a === 0 && b === 0) { + this.dataCounters.padding += 2; + continue; + } + else { + logger.log('DATA', '[' + numArrayToHexArray([byteList[i], byteList[i + 1]]) + '] -> (' + numArrayToHexArray([a, b]) + ')'); + } + cmdFound = this.parseCmd(a, b); + if (!cmdFound) { + cmdFound = this.parseMidrow(a, b); + } + if (!cmdFound) { + cmdFound = this.parsePAC(a, b); + } + if (!cmdFound) { + cmdFound = this.parseBackgroundAttributes(a, b); + } + if (!cmdFound) { + charsFound = this.parseChars(a, b); + if (charsFound) { + if (this.currChNr && this.currChNr >= 0) { + const channel = this.channels[this.currChNr - 1]; + channel.insertChars(charsFound); + } + else { + logger.log('WARNING', 'No channel found yet. TEXT-MODE?'); + } + } + } + if (cmdFound) { + this.dataCounters.cmd += 2; + } + else if (charsFound) { + this.dataCounters.char += 2; + } + else { + this.dataCounters.other += 2; + logger.log('WARNING', 'Couldn\'t parse cleaned data ' + numArrayToHexArray([a, b]) + ' orig: ' + numArrayToHexArray([byteList[i], byteList[i + 1]])); + } + } + } + /** + * Parse Command. + * @returns {Boolean} Tells if a command was found + */ + parseCmd(a, b) { + let chNr = null; + const cond1 = (a === 20 || a === 21 || a === 28 || a === 29) && 32 <= b && b <= 47; + const cond2 = (a === 23 || a === 31) && 33 <= b && b <= 35; + if (!(cond1 || cond2)) { + return false; + } + if (a === 20 || a === 23) { + chNr = 1; + } + else { + chNr = 2; // (a === 0x1C || a=== 0x1f) + } + const channel = this.channels[chNr - 1]; + if (a === 20 || a === 21 || a === 28 || a === 29) { + if (b === 32) { + channel.ccRCL(); + } + else if (b === 33) { + channel.ccBS(); + } + else if (b === 34) { + channel.ccAOF(); + } + else if (b === 35) { + channel.ccAON(); + } + else if (b === 36) { + channel.ccDER(); + } + else if (b === 37) { + channel.ccRU(2); + } + else if (b === 38) { + channel.ccRU(3); + } + else if (b === 39) { + channel.ccRU(4); + } + else if (b === 40) { + channel.ccFON(); + } + else if (b === 41) { + channel.ccRDC(); + } + else if (b === 42) { + channel.ccTR(); + } + else if (b === 43) { + channel.ccRTD(); + } + else if (b === 44) { + channel.ccEDM(); + } + else if (b === 45) { + channel.ccCR(); + } + else if (b === 46) { + channel.ccENM(); + } + else if (b === 47) { + channel.ccEOC(); + } + } + else { + // a == 0x17 || a == 0x1F + channel.ccTO(b - 32); + } + this.lastCmdA = a; + this.lastCmdB = b; + this.currChNr = chNr; + return true; + } + /** + * Parse midrow styling command + * @returns {Boolean} + */ + parseMidrow(a, b) { + let chNr = null; + if ((a === 17 || a === 25) && 32 <= b && b <= 47) { + if (a === 17) { + chNr = 1; + } + else { + chNr = 2; + } + if (chNr !== this.currChNr) { + logger.log('ERROR', 'Mismatch channel in midrow parsing'); + return false; + } + const channel = this.channels[chNr - 1]; + // cea608 spec says midrow codes should inject a space + channel.insertChars([32]); + channel.ccMIDROW(b); + logger.log('DEBUG', 'MIDROW (' + numArrayToHexArray([a, b]) + ')'); + this.lastCmdA = a; + this.lastCmdB = b; + return true; + } + return false; + } + /** + * Parse Preable Access Codes (Table 53). + * @returns {Boolean} Tells if PAC found + */ + parsePAC(a, b) { + let chNr = null; + let row = null; + const case1 = ((17 <= a && a <= 23) || (25 <= a && a <= 31)) && 64 <= b && b <= 127; + const case2 = (a === 16 || a === 24) && 64 <= b && b <= 95; + if (!(case1 || case2)) { + return false; + } + chNr = a <= 23 ? 1 : 2; + if (64 <= b && b <= 95) { + row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a]; + } + else { + // 0x60 <= b <= 0x7F + row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a]; + } + const pacData = this.interpretPAC(row, b); + const channel = this.channels[chNr - 1]; + channel.setPAC(pacData); + this.lastCmdA = a; + this.lastCmdB = b; + this.currChNr = chNr; + return true; + } + /** + * Interpret the second byte of the pac, and return the information. + * @returns {Object} pacData with style parameters. + */ + interpretPAC(row, byte) { + let pacIndex = byte; + const pacData = { color: null, italics: false, indent: null, underline: false, row: row }; + if (byte > 95) { + pacIndex = byte - 96; + } + else { + pacIndex = byte - 64; + } + pacData.underline = (pacIndex & 1) === 1; + if (pacIndex <= 13) { + pacData.color = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'white'][Math.floor(pacIndex / 2)]; + } + else if (pacIndex <= 15) { + pacData.italics = true; + pacData.color = 'white'; + } + else { + pacData.indent = Math.floor((pacIndex - 16) / 2) * 4; + } + return pacData; // Note that row has zero offset. The spec uses 1. + } + /** + * Parse characters. + * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise. + */ + parseChars(a, b) { + let channelNr = null, charCodes = null, charCode1 = null; + if (a >= 25) { + channelNr = 2; + charCode1 = a - 8; + } + else { + channelNr = 1; + charCode1 = a; + } + if (17 <= charCode1 && charCode1 <= 19) { + // Special character + let oneCode = b; + if (charCode1 === 17) { + oneCode = b + 80; + } + else if (charCode1 === 18) { + oneCode = b + 112; + } + else { + oneCode = b + 144; + } + logger.log('INFO', 'Special char \'' + getCharForByte(oneCode) + '\' in channel ' + channelNr); + charCodes = [oneCode]; + this.lastCmdA = a; + this.lastCmdB = b; + } + else if (32 <= a && a <= 127) { + charCodes = b === 0 ? [a] : [a, b]; + this.lastCmdA = null; + this.lastCmdB = null; + } + if (charCodes) { + const hexCodes = numArrayToHexArray(charCodes); + logger.log('DEBUG', `Char codes = ${hexCodes.join(',')}`); + } + return charCodes; + } + /** + * Parse extended background attributes as well as new foreground color black. + * @returns{Boolean} Tells if background attributes are found + */ + parseBackgroundAttributes(a, b) { + let bkgData, index, chNr, channel; + const case1 = (a === 16 || a === 24) && 32 <= b && b <= 47; + const case2 = (a === 23 || a === 31) && 45 <= b && b <= 47; + if (!(case1 || case2)) { + return false; + } + // eslint-disable-next-line prefer-const + bkgData = { underline: false }; + if (a === 16 || a === 24) { + index = Math.floor((b - 32) / 2); + bkgData.background = backgroundColors[index]; + if (b % 2 === 1) { + bkgData.background = bkgData.background + '_semi'; + } + } + else if (b === 45) { + bkgData.background = 'transparent'; + } + else { + bkgData.foreground = 'black'; + if (b === 47) { + bkgData.underline = true; + } + } + // eslint-disable-next-line prefer-const + chNr = a < 24 ? 1 : 2; + // eslint-disable-next-line prefer-const + channel = this.channels[chNr - 1]; + channel.setBkgData(bkgData); + this.lastCmdA = null; + this.lastCmdB = null; + return true; + } + /** + * Reset state of parser and its channels. + */ + reset() { + for (let i = 0; i < this.channels.length; i++) { + if (this.channels[i]) { + this.channels[i].reset(); + } + } + this.lastCmdA = null; + this.lastCmdB = null; + } + /** + * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty. + */ + cueSplitAtTime(t) { + for (let i = 0; i < this.channels.length; i++) { + if (this.channels[i]) { + this.channels[i].cueSplitAtTime(t); + } + } + } + } + var Cea608Parser$1 = Cea608Parser; + + class OutputFilter { + constructor(handler, track) { + this.handler = handler; + this.track = track; + this.startTime = null; + this.endTime = null; + this.screen = null; + } + dispatchCue() { + if (this.startTime === null) { + return; + } + this.handler.addCues('cc' + this.track, this.startTime, this.endTime, this.screen); + this.startTime = null; + } + newCue(startTime, endTime, screen) { + if (this.startTime === null || this.startTime > startTime) { + this.startTime = startTime; + } + this.endTime = endTime; + this.screen = screen; + this.handler.createHTMLCaptionsTrack(this.track); + } + } + + var lib = {}; + + var vttparser = {}; + + var vttcue = {}; + + var vttvalidator = {}; + + /** + * Copyright 2019 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + Object.defineProperty(vttvalidator, "__esModule", { value: true }); + function isValidPercentValue(value) { + return typeof value === 'number' && value >= 0 && value <= 100; + } + vttvalidator.isValidPercentValue = isValidPercentValue; + function isValidAlignSetting(value) { + return (typeof value === 'string' && + ['start', 'center', 'end', 'left', 'right', 'middle'].includes(value)); + } + vttvalidator.isValidAlignSetting = isValidAlignSetting; + function isValidDirectionSetting(value) { + return typeof value === 'string' && ['', 'rl', 'lr'].includes(value); + } + vttvalidator.isValidDirectionSetting = isValidDirectionSetting; + function isValidLineAndPositionSetting(value) { + return typeof value === 'number' || value === 'auto'; + } + vttvalidator.isValidLineAndPositionSetting = isValidLineAndPositionSetting; + function isValidLineAlignSetting(value) { + return typeof value === 'string' && ['start', 'center', 'end'].includes(value); + } + vttvalidator.isValidLineAlignSetting = isValidLineAlignSetting; + function isValidPositionAlignSetting(value) { + return (typeof value === 'string' && + ['line-left', 'center', 'line-right', 'auto', 'left', 'start', 'middle', 'end', 'right'].includes(value)); + } + vttvalidator.isValidPositionAlignSetting = isValidPositionAlignSetting; + function isValidScrollSetting(value) { + return ['', 'up'].includes(value); + } + vttvalidator.isValidScrollSetting = isValidScrollSetting; + + var vttparserUtility = {}; + + Object.defineProperty(vttparserUtility, "__esModule", { value: true }); + const ESCAPE = { + '&': '&', + '<': '<', + '>': '>', + '‎': '\u200e', + '‏': '\u200f', + ' ': '\u00a0' + }; + const TAG_NAME = { + c: 'span', + i: 'i', + b: 'b', + u: 'u', + ruby: 'ruby', + rt: 'rt', + v: 'span', + lang: 'span' + }; + const TAG_ANNOTATION = { + v: 'title', + lang: 'lang' + }; + const NEEDS_PARENT = { + rt: 'ruby' + }; + // "text-combine-upright" must be remapped into "-webkit-text-combine" + // until browsers support this property + // In the future: https://developer.mozilla.org/en-US/docs/Web/CSS/text-combine-upright + const styleMap = { + 'text-combine-upright': '-webkit-text-combine:horizontal; text-orientation: mixed;' + }; + class ParserUtility { + // Try to parse input as a time stamp. + static parseTimeStamp(input) { + function computeSeconds(arr) { + const [h, m, s, f] = arr.map(n => (n ? parseInt('' + n) : 0)); + return h * 3600 + m * 60 + s + f / 1000; + } + const m = /^(\d+):(\d{2})(:\d{2})?\.(\d{3})/.exec(input); + if (!m) { + return null; + } + if (m[3]) { + // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds] + return computeSeconds([m[1], m[2], m[3].substring(1), m[4]]); + } + else if (parseInt(m[1]) > 59) { + // Timestamp takes the form of [hours]:[minutes].[milliseconds] + // First position is hours as it's over 59. + return computeSeconds([m[1], m[2], null, m[4]]); + } + else { + // Timestamp takes the form of [minutes]:[seconds].[milliseconds] + return computeSeconds([null, m[1], m[2], m[4]]); + } + } + // Parse content into a document fragment. + static parseContent(window, cue, globalStyleCollection) { + let input = cue.text; + function nextToken() { + // Check for end-of-string. + if (!input) { + return null; + } + // Consume 'n' characters from the input. + function consume(result) { + input = input.substr(result.length); + return result; + } + const m = /^([^<]*)(<[^>]+>?)?/.exec(input); + // If there is some text before the next tag, return it, otherwise return + // the tag. + return consume(m[1] ? m[1] : m[2]); + } + // Unescape a string 's'. + function unescape1(e) { + return ESCAPE[e]; + } + function unescape(s) { + return s.replace(/&(amp|lt|gt|lrm|rlm|nbsp);/g, unescape1); + } + function shouldAdd(current, element) { + return (!NEEDS_PARENT[element.dataset.localName] || + NEEDS_PARENT[element.dataset.localName] === current.dataset.localName); + } + // Create an element for this tag. + function createElement(type, cssSelector, annotation) { + function createStyleString(styles) { + let styleString = ''; + for (const key in styles) { + if (styleMap[key]) { + styleString += styleMap[key]; + } + else { + styleString += key + ':' + styles[key] + ';'; + } + } + return styleString; + } + const tagName = TAG_NAME[type]; + if (!tagName) { + return null; + } + const element = window.document.createElement(tagName); + // localName is a read only property, but we can store this as an HTML data-attribute + element.dataset.localName = tagName; + const name = TAG_ANNOTATION[type]; + if (name && annotation) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + element[name] = annotation.trim(); + } + if (cssSelector) { + if (globalStyleCollection[cssSelector]) { + const elementStyleCollection = globalStyleCollection[cssSelector]; + const styleString = createStyleString(elementStyleCollection); + element.setAttribute('style', styleString); + } + else { + console.info(`WebVTT: parseContent: Style referenced, but no style defined for '${cssSelector}'!`); + } + } + return element; + } + const rootDiv = window.document.createElement('div'), tagStack = []; + let current = rootDiv, t, m; + while ((t = nextToken()) !== null) { + if (t[0] === '<') { + if (t[1] === '/') { + // If the closing tag matches, move back up to the parent node. + if (tagStack.length && + tagStack[tagStack.length - 1] === t.substr(2).replace('>', '')) { + tagStack.pop(); + current = current.parentNode; + } + // Otherwise just ignore the end tag. + continue; + } + const ts = ParserUtility.parseTimeStamp(t.substr(1, t.length - 2)); + let node; + if (ts) { + // Timestamps are lead nodes as well. + node = window.document.createProcessingInstruction('timestamp', ts.toString() + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ); + current.appendChild(node); + continue; + } + m = /^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/.exec(t); + // If we can't parse the tag, skip to the next tag. + if (!m) { + continue; + } + // Try to construct an element, and ignore the tag if we couldn't. + node = createElement(m[1], m[2], m[3]); + if (!node) { + continue; + } + // Determine if the tag should be added based on the context of where it + // is placed in the cuetext. + if (!shouldAdd(current, node)) { + continue; + } + // Append the node to the current node, and enter the scope of the new + // node. + tagStack.push(m[1]); + current.appendChild(node); + current = node; + continue; + } + // Text nodes are leaf nodes. + current.appendChild(window.document.createTextNode(unescape(t))); + } + return rootDiv; + } + } + vttparserUtility.default = ParserUtility; + + /** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + var __decorate$1 = (commonjsGlobal && commonjsGlobal.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + Object.defineProperty(vttcue, "__esModule", { value: true }); + const vttvalidator_1$1 = vttvalidator; + const vttparser_utility_1$2 = vttparserUtility; + let VTTCue = class VTTCue { + constructor(startTime, endTime, text) { + /** + * VTTCue and TextTrackCue properties + * http://dev.w3.org/html5/webvtt/#vttcue-interface + */ + this._id = ''; + this._pauseOnExit = false; + this._region = null; + this._vertical = ''; + this._snapToLines = true; + this._line = 'auto'; + this._lineAlign = 'start'; + this._position = 'auto'; + this._positionAlign = 'auto'; + this._size = 100; + this._align = 'center'; + /** + * Other spec defined properties + */ + /** + * Shim implementation specific properties. These properties are not in + * the spec. + */ + // Lets us know when the VTTCue's data has changed in such a way that we need + // to recompute its display state. This lets us compute its display state + // lazily. + this.hasBeenReset = false; + this._startTime = startTime; + this._endTime = endTime; + this._text = text; + } + get id() { + return this._id; + } + set id(value) { + this._id = '' + value; + } + get pauseOnExit() { + return this._pauseOnExit; + } + set pauseOnExit(value) { + this._pauseOnExit = !!value; + } + get startTime() { + return this._startTime; + } + set startTime(value) { + if (typeof value !== 'number') { + throw new TypeError(`Start time must be set to a number: ${value}`); + } + this._startTime = value; + this.hasBeenReset = true; + } + get endTime() { + return this._endTime; + } + set endTime(value) { + if (typeof value !== 'number') { + throw new TypeError(`End time must be set to a number: ${value}`); + } + this._endTime = value; + this.hasBeenReset = true; + } + get text() { + return this._text; + } + set text(value) { + this._text = '' + value; + this.hasBeenReset = true; + } + get region() { + return this._region; + } + set region(value) { + this._region = value; + this.hasBeenReset = true; + } + get vertical() { + return this._vertical; + } + set vertical(value) { + if (!vttvalidator_1$1.isValidDirectionSetting(value)) { + throw new SyntaxError(`An invalid or illegal string was specified for vertical: ${value}`); + } + this._vertical = value; + this.hasBeenReset = true; + } + get snapToLines() { + return this._snapToLines; + } + set snapToLines(value) { + this._snapToLines = !!value; + this.hasBeenReset = true; + } + get line() { + return this._line; + } + set line(value) { + if (!vttvalidator_1$1.isValidLineAndPositionSetting(value)) { + throw new SyntaxError(`An invalid number or illegal string was specified for line: ${value}`); + } + this._line = value; + this.hasBeenReset = true; + } + get lineAlign() { + return this._lineAlign; + } + set lineAlign(value) { + if (!vttvalidator_1$1.isValidLineAlignSetting(value)) { + throw new SyntaxError(`An invalid or illegal string was specified for lineAlign: ${value}`); + } + this._lineAlign = value; + this.hasBeenReset = true; + } + get position() { + return this._position; + } + set position(value) { + if (!vttvalidator_1$1.isValidLineAndPositionSetting(value)) { + throw new Error(`Position must be between 0 and 100 or auto: ${value}`); + } + this._position = value; + this.hasBeenReset = true; + } + get positionAlign() { + return this._positionAlign; + } + set positionAlign(value) { + if (!vttvalidator_1$1.isValidPositionAlignSetting(value)) { + throw new SyntaxError(`An invalid or illegal string was specified for positionAlign: ${value}`); + } + this._positionAlign = value; + this.hasBeenReset = true; + } + get size() { + return this._size; + } + set size(value) { + if (value < 0 || value > 100) { + throw new Error(`Size must be between 0 and 100: ${value}`); + } + this._size = value; + this.hasBeenReset = true; + } + get align() { + return this._align; + } + set align(value) { + if (!vttvalidator_1$1.isValidAlignSetting(value)) { + throw new SyntaxError(`An invalid or illegal string was specified for align: ${value}`); + } + this._align = value; + this.hasBeenReset = true; + } + getCueAsHTML() { + return vttparser_utility_1$2.default.parseContent(window, this, {}); + } + static create(options) { + if (!options.hasOwnProperty('startTime') || + !options.hasOwnProperty('endTime') || + !options.hasOwnProperty('text')) { + throw new Error('You must at least have start time, end time, and text.'); + } + const cue = new this(options.startTime, options.endTime, options.text); + Object.keys(options).forEach((key) => { + if (cue.hasOwnProperty(key)) { + cue[key] = options[key]; + } + }); + return cue; + } + static fromJSON(json) { + return this.create(JSON.parse(json)); + } + toJSON() { + const json = {}; + Object.keys(this).forEach((key) => { + if (this.hasOwnProperty(key) && + key !== 'getCueAsHTML' && + key !== 'hasBeenReset' && + key !== 'displayState') { + json[key] = this[key]; + } + }); + return json; + } + }; + VTTCue = __decorate$1([ + replaceVTTCue + ], VTTCue); + vttcue.VTTCue = VTTCue; + function replaceVTTCue(constructor) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let cls = constructor; + if (typeof window !== 'undefined' && window.VTTCue != null) { + cls = window.VTTCue; + cls.create = constructor.create; + cls.fromJSON = constructor.fromJSON; + cls.prototype.toJSON = constructor.prototype.toJSON; + } + return cls; + } + + var vttregion = {}; + + /** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + var __decorate = (commonjsGlobal && commonjsGlobal.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + Object.defineProperty(vttregion, "__esModule", { value: true }); + const vttvalidator_1 = vttvalidator; + // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface + let VTTRegion = class VTTRegion { + constructor() { + this._id = ''; + this._lines = 3; + this._regionAnchorX = 0; + this._regionAnchorY = 100; + this._scroll = ''; + this._viewportAnchorX = 0; + this._viewportAnchorY = 100; + this._width = 100; + } + get id() { + return this._id; + } + set id(value) { + if (typeof value !== 'string') { + throw new Error('ID must be a string.'); + } + this._id = value; + } + get lines() { + return this._lines; + } + set lines(value) { + if (typeof value !== 'number') { + throw new TypeError('Lines must be set to a number.'); + } + this._lines = value; + } + get regionAnchorX() { + return this._regionAnchorX; + } + set regionAnchorX(value) { + if (!vttvalidator_1.isValidPercentValue(value)) { + throw new TypeError('RegionAnchorX must be between 0 and 100.'); + } + this._regionAnchorX = value; + } + get regionAnchorY() { + return this._regionAnchorY; + } + set regionAnchorY(value) { + if (!vttvalidator_1.isValidPercentValue(value)) { + throw new TypeError('RegionAnchorY must be between 0 and 100.'); + } + this._regionAnchorY = value; + } + get scroll() { + return this._scroll; + } + set scroll(value) { + if (typeof value === 'string') { + const setting = value.toLowerCase(); + if (vttvalidator_1.isValidScrollSetting(setting)) { + this._scroll = setting; + return; + } + } + throw new SyntaxError('An invalid or illegal string was specified.'); + } + get viewportAnchorX() { + return this._viewportAnchorX; + } + set viewportAnchorX(value) { + if (!vttvalidator_1.isValidPercentValue(value)) { + throw new TypeError('ViewportAnchorX must be between 0 and 100.'); + } + this._viewportAnchorX = value; + } + get viewportAnchorY() { + return this._viewportAnchorY; + } + set viewportAnchorY(value) { + if (!vttvalidator_1.isValidPercentValue(value)) { + throw new TypeError('ViewportAnchorY must be between 0 and 100.'); + } + this._viewportAnchorY = value; + } + get width() { + return this._width; + } + set width(value) { + if (!vttvalidator_1.isValidPercentValue(value)) { + throw new TypeError('Width must be between 0 and 100.'); + } + this._lines = value; + } + toJSON() { + const json = {}; + Object.keys(this).forEach((key) => { + if (this.hasOwnProperty(key)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + json[key] = this[key]; + } + }); + return json; + } + static create(options) { + const region = new this(); + Object.keys(options).forEach((key) => { + if (region.hasOwnProperty(key)) { + region[key] = options[key]; + } + }); + return region; + } + static fromJSON(json) { + return this.create(JSON.parse(json)); + } + }; + VTTRegion = __decorate([ + replaceVTTRegion + ], VTTRegion); + vttregion.VTTRegion = VTTRegion; + function replaceVTTRegion(constructor) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let cls = constructor; + if (typeof window !== 'undefined' && window.VTTRegion != null) { + cls = window.VTTRegion; + cls.create = constructor.create; + cls.fromJSON = constructor.fromJSON; + cls.prototype.toJSON = constructor.prototype.toJSON; + } + return cls; + } + + /** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + Object.defineProperty(vttparser, "__esModule", { value: true }); + const vttcue_1$1 = vttcue; + vttparser.VTTCue = vttcue_1$1.VTTCue; + const vttregion_1 = vttregion; + vttparser.VTTRegion = vttregion_1.VTTRegion; + const vttparser_utility_1$1 = vttparserUtility; + // Creates a new ParserError object from an errorData object. The errorData + // object should have default code and message properties. The default message + // property can be overridden by passing in a message parameter. + // See ParsingError.Errors below for acceptable errors. + class ParsingError extends Error { + constructor(errorData, message) { + super(); + this.name = 'ParsingError'; + if (typeof errorData === 'number') { + this.code = errorData; + } + else { + this.code = errorData.code; + } + if (message) { + this.message = message; + } + else if (errorData instanceof ParsingError) { + this.message = errorData.message; + } + } + } + vttparser.ParsingError = ParsingError; + // ParsingError metadata for acceptable ParsingErrors. + ParsingError.Errors = { + BadSignature: new ParsingError(0, 'Malformed WebVTT signature.'), + BadTimeStamp: new ParsingError(1, 'Malformed time stamp.') + }; + // A settings object holds key/value pairs and will ignore anything but the first + // assignment to a specific key. + class Settings { + constructor() { + this.values = {}; + } + // Only accept the first assignment to any key. + set(k, v) { + if (!this.get(k) && v !== '') { + this.values[k] = v; + } + } + get(k, dflt, defaultKey) { + if (typeof dflt === 'object' && typeof defaultKey === 'string') { + return this.has(k) ? this.values[k] : dflt[defaultKey]; + } + return this.has(k) ? this.values[k] : dflt; + } + // Check whether we have a value for a key. + has(k) { + return k in this.values; + } + // Accept a setting if its one of the given alternatives. + alt(k, v, a) { + for (let n = 0; n < a.length; ++n) { + if (v === a[n]) { + this.set(k, v); + break; + } + } + } + // Accept a setting if its a valid (signed) integer. + integer(k, v) { + if (/^-?\d+$/.test(v)) { + this.set(k, parseInt(v, 10)); + } + } + // Accept a setting if its a valid percentage. + percent(k, v) { + const m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/); + if (m) { + try { + const vf = parseFloat(v); + if (vf >= 0 && vf <= 100) { + this.set(k, vf); + return true; + } + } + catch (err) { + return false; + } + } + return false; + } + } + class WebVTTParser { + constructor(window, decoder, onStylesParsedCallback) { + this.window = window; + this.state = 'INITIAL'; + this.styleCollector = ''; + this.buffer = ''; + this.decoder = decoder || new TextDecoder('utf8'); + this.regionList = []; + this.onStylesParsedCallback = onStylesParsedCallback; + this._styles = {}; + } + // Helper to allow strings to be decoded instead of the default binary utf8 data. + static StringDecoder() { + return { + decode: (input) => { + if (!input) { + return ''; + } + if (typeof input !== 'string') { + throw new Error('Error - expected string data.'); + } + return decodeURIComponent(encodeURIComponent(input)); + } + }; + } + // If the error is a ParsingError then report it to the consumer if + // possible. If it's not a ParsingError then throw it like normal. + reportOrThrowError(e) { + if (e instanceof ParsingError && + typeof this.onparsingerror === 'function') { + this.onparsingerror(e); + } + else { + throw e; + } + } + // Helper function to parse input into groups separated by 'groupDelim', and + // interprete each group as a key/value pair separated by 'keyValueDelim'. + parseOptions(input, callback, keyValueDelim, groupDelim) { + const groups = groupDelim ? input.split(groupDelim) : [input]; + for (const group of groups) { + if (typeof group !== 'string') { + continue; + } + const kv = group.split(keyValueDelim); + if (kv.length !== 2) { + continue; + } + const k = kv[0]; + const v = kv[1]; + callback(k, v); + } + } + parseCue(input, cue, regionList) { + // Remember the original input if we need to throw an error. + const oInput = input; + // 4.1 WebVTT timestamp + const consumeTimeStamp = () => { + const ts = vttparser_utility_1$1.default.parseTimeStamp(input); + if (ts === null) { + throw new ParsingError(ParsingError.Errors.BadTimeStamp, 'Malformed timestamp: ' + oInput); + } + // Remove time stamp from input. + input = input.replace(/^[^\sa-zA-Z-]+/, ''); + return ts; + }; + // 4.4.2 WebVTT cue settings + const consumeCueSettings = (input, cue) => { + const settings = new Settings(); + this.parseOptions(input, (k, v) => { + let vals, vals0; + switch (k) { + case 'region': + // Find the last region we parsed with the same region id. + for (let i = regionList.length - 1; i >= 0; i--) { + if (regionList[i].id === v) { + settings.set(k, regionList[i].region); + break; + } + } + break; + case 'vertical': + settings.alt(k, v, ['rl', 'lr']); + break; + case 'line': + vals = v.split(','); + vals0 = vals[0]; + settings.integer(k, vals0); + if (settings.percent(k, vals0)) { + settings.set('snapToLines', false); + } + settings.alt(k, vals0, ['auto']); + if (vals.length === 2) { + settings.alt('lineAlign', vals[1], [ + 'start', + 'center', + 'end' + ]); + } + break; + case 'position': + vals = v.split(','); + settings.percent(k, vals[0]); + if (vals.length === 2) { + let positionAlignSettings = ['line-left', 'line-right', + 'center', 'auto', 'left', 'start', 'middle', 'end', 'right']; + settings.alt('positionAlign', vals[1], positionAlignSettings); + } + break; + case 'size': + settings.percent(k, v); + break; + case 'align': + let alignSettings = ['start', 'center', 'end', 'left', 'right', 'middle']; + settings.alt(k, v, alignSettings); + break; + } + }, /:/, /\s/); + // Apply default values for any missing fields. + cue.region = settings.get('region', null); + cue.vertical = settings.get('vertical', ''); + // Workaround to rdar://57719277 + // Waiting Webkit team to provide a proper fix, tracking in rdar://57778093 + cue.line = settings.get('line', typeof cue.line === 'undefined' ? 'auto' : cue.line); + cue.lineAlign = settings.get('lineAlign', 'start'); + cue.snapToLines = settings.get('snapToLines', true); + cue.size = settings.get('size', 100); + let tempAlign = settings.get('align', 'center'); + cue.align = tempAlign === 'middle' ? 'center' : tempAlign; + cue.position = settings.get('position', 'auto'); + let tempPositionAlign = settings.get('positionAlign', { + 'start': 'start', + 'left': 'start', + 'center': 'center', + 'right': 'end', + 'end': 'end', + }, cue.align // We should default to 'auto' here - but might break in other places + ); + let positionAlignMap = { + 'start': 'start', + 'line-left': 'start', + 'left': 'start', + 'center': 'center', + 'middle': 'center', + 'line-right': 'end', + 'right': 'end', + 'end': 'end', + }; + cue.positionAlign = positionAlignMap[tempPositionAlign]; + }; + const skipWhitespace = () => { + input = input.replace(/^\s+/, ''); + }; + // 4.1 WebVTT cue timings. + skipWhitespace(); + cue.startTime = consumeTimeStamp(); // (1) collect cue start time + skipWhitespace(); + if (input.substr(0, 3) !== '-->') { + // (3) next characters must match "-->" + throw new ParsingError(ParsingError.Errors.BadTimeStamp, `Malformed time stamp (time stamps must be separated by '-->'): ${oInput}`); + } + input = input.substr(3); + skipWhitespace(); + cue.endTime = consumeTimeStamp(); // (5) collect cue end time + // 4.1 WebVTT cue settings list. + skipWhitespace(); + consumeCueSettings(input, cue); + } + // 3.4 WebVTT region and WebVTT region settings syntax + parseRegion(input) { + const settings = new Settings(); + this.parseOptions(input, (k, v) => { + switch (k) { + case 'id': + settings.set(k, v); + break; + case 'width': + settings.percent(k, v); + break; + case 'lines': + settings.integer(k, v); + break; + case 'regionanchor': + case 'viewportanchor': { + const xy = v.split(','); + if (xy.length !== 2) { + break; + } + // We have to make sure both x and y parse, so use a temporary + // settings object here. + const anchor = new Settings(); + anchor.percent('x', xy[0]); + anchor.percent('y', xy[1]); + if (!anchor.has('x') || !anchor.has('y')) { + break; + } + settings.set(k + 'X', anchor.get('x')); + settings.set(k + 'Y', anchor.get('y')); + break; + } + case 'scroll': + settings.alt(k, v, ['up']); + break; + } + }, /=/, /\s/); + // Create the region, using default values for any values that were not + // specified. + if (settings.has('id')) { + const region = new vttregion_1.VTTRegion(); + region.width = settings.get('width', 100); + region.lines = settings.get('lines', 3); + region.regionAnchorX = settings.get('regionanchorX', 0); + region.regionAnchorY = settings.get('regionanchorY', 100); + region.viewportAnchorX = settings.get('viewportanchorX', 0); + region.viewportAnchorY = settings.get('viewportanchorY', 100); + region.scroll = settings.get('scroll', ''); + // Register the region. + if (this.onregion) { + this.onregion(region); + } + // Remember the VTTRegion for later in case we parse any VTTCues that + // reference it. + this.regionList.push({ + id: settings.get('id'), + region: region + }); + } + } + // 1.3 WebVTT style block syntax + // Works on single line CSS only + parseStyle(input) { + const parseStyles = (css) => { + const rules = {}; + const properties = css.split(';'); + for (let i = 0; i < properties.length; i++) { + if (properties[i].includes(':')) { + const keyValue = properties[i].split(':', 2); + const key = keyValue[0].trim(); + const value = keyValue[1].trim(); + if (key !== '' && value !== '') { + rules[key] = value; + } + } + } + return rules; + }; + const blocks = input.split('}'); + blocks.pop(); + for (const block of blocks) { + let selector = null; + let styles = null; + const pair = block.split('{'); + if (pair[0]) { + selector = pair[0].trim(); + } + if (pair[1]) { + styles = parseStyles(pair[1]); + } + if (selector && styles) { + this._styles[selector] = styles; + } + } + if (this.onStylesParsedCallback) { + this.onStylesParsedCallback(this._styles); + } + } + // 3.2 WebVTT metadata header syntax + parseHeader(input) { + this.parseOptions(input, function (k, v) { + switch (k) { + case 'Region': + // 3.3 WebVTT region metadata header syntax + this.parseRegion(v); + break; + } + }, /:/); + } + parse(data) { + // If there is no data then we won't decode it, but will just try to parse + // whatever is in buffer already. This may occur in circumstances, for + // example when flush() is called. + if (data) { + // Try to decode the data that we received. + this.buffer += this.decoder.decode(data, { stream: true }); + } + const collectNextLine = () => { + const buffer = this.buffer; + let pos = 0; + const calculateBreakPosition = (buffer, index) => { + const breakPosition = { start: -1, length: -1 }; + if (buffer[index] === '\r') { + breakPosition.start = index; + breakPosition.length = 1; + } + else if (buffer[index] === '\n') { + breakPosition.start = index; + breakPosition.length = 1; + } + else if (buffer[index] === '<') { + if (index + 1 < buffer.length && buffer[index + 1] === 'b') { + if (index + 2 < buffer.length && buffer[index + 2] === 'r') { + let endPosition = index + 2; + while (endPosition < buffer.length) { + if (buffer[endPosition++] === '>') { + break; + } + } + breakPosition.start = index; + breakPosition.length = endPosition - index; + } + } + } + return breakPosition; + }; + let breakPosition = { start: buffer.length, length: 0 }; + while (pos < buffer.length) { + const foundBreakPosition = calculateBreakPosition(buffer, pos); + if (foundBreakPosition.length > 0) { + breakPosition = foundBreakPosition; + break; + } + ++pos; + } + const line = buffer.substr(0, breakPosition.start); + this.buffer = buffer.substr(breakPosition.start + breakPosition.length); + return line; + }; + // 5.1 WebVTT file parsing. + try { + let line; + if (this.state === 'INITIAL') { + // We can't start parsing until we have the first line. + if (!/\r\n|\n/.test(this.buffer)) { + return this; + } + line = collectNextLine(); + // strip of UTF-8 BOM if any + // https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 + const m = /^(ïÂÂģÂÂŋ)?WEBVTT([ \t].*)?$/.exec(line); + if (!m || !m[0]) { + throw new ParsingError(ParsingError.Errors.BadSignature); + } + this.state = 'HEADER'; + } + let alreadyCollectedLine = false; + while (this.buffer) { + // We can't parse a line until we have the full line. + if (!/\r\n|\n/.test(this.buffer)) { + return this; + } + if (!alreadyCollectedLine) { + line = collectNextLine(); + } + else { + alreadyCollectedLine = false; + } + switch (this.state) { + case 'HEADER': + // 13-18 - Allow a header (metadata) under the WEBVTT line. + if (line.includes(':')) { + this.parseHeader(line); + } + else if (!line) { + // An empty line terminates the header and starts the body (cues). + this.state = 'ID'; + } + continue; + case 'NOTE': + // Ignore NOTE blocks. + if (!line) { + this.state = 'ID'; + } + continue; + case 'STYLE': + // Parse style blocks. + if (!line) { + this.parseStyle(this.styleCollector); + this.state = 'ID'; + this.styleCollector = ''; + } + else { + this.styleCollector += line; + } + continue; + case 'ID': + // Check for the start of NOTE blocks. + if (/^NOTE($|[ \t])/.test(line)) { + this.state = 'NOTE'; + break; + } + if (/^STYLE($|[ \t])/.test(line)) { + this.state = 'STYLE'; + break; + } + // 19-29 - Allow any number of line terminators, then initialize new cue values. + if (!line) { + continue; + } + this.cue = new vttcue_1$1.VTTCue(0, 0, ''); + this.state = 'CUE'; + // 30-39 - Check if self line contains an optional identifier or timing data. + if (!line.includes('-->')) { + this.cue.id = line; + continue; + } + // Process line as start of a cue. + /* falls through */ + case 'CUE': + // 40 - Collect cue timings and settings. + try { + this.parseCue(line, this.cue, this.regionList); + } + catch (e) { + this.reportOrThrowError(e); + // In case of an error ignore rest of the cue. + this.cue = null; + this.state = 'BADCUE'; + continue; + } + this.state = 'CUETEXT'; + continue; + case 'CUETEXT': { + const hasSubstring = line.includes('-->'); + // 34 - If we have an empty line then report the cue. + // 35 - If we have the special substring '-->' then report the cue, + // but do not collect the line as we need to process the current + // one as a new cue. + if (!line || hasSubstring) { + // We are done parsing self cue. + alreadyCollectedLine = true; + if (this.oncue) { + this.oncue(this.cue); + } + this.cue = null; + this.state = 'ID'; + continue; + } + if (this.cue.text) { + this.cue.text += '\n'; + } + this.cue.text += line; + continue; + } + case 'BADCUE': // BADCUE + // 54-62 - Collect and discard the remaining cue. + if (!line) { + this.state = 'ID'; + } + continue; + } + } + } + catch (e) { + this.reportOrThrowError(e); + // If we are currently parsing a cue, report what we have. + if (this.state === 'CUETEXT' && this.cue && this.oncue) { + this.oncue(this.cue); + } + this.cue = null; + // Enter BADWEBVTT state if header was not parsed correctly otherwise + // another exception occurred so enter BADCUE state. + this.state = this.state === 'INITIAL' ? 'BADWEBVTT' : 'BADCUE'; + } + return this; + } + flush() { + try { + // Finish decoding the stream. + this.buffer += this.decoder.decode(); + // Synthesize the end of the current cue or region. + if (this.cue || this.state === 'HEADER') { + this.buffer += '\n\n'; + this.parse(); + } + // If we've flushed, parsed, and we're still on the INITIAL state then + // that means we don't have enough of the stream to parse the first + // line. + if (this.state === 'INITIAL') { + throw new ParsingError(ParsingError.Errors.BadSignature); + } + } + catch (e) { + this.reportOrThrowError(e); + } + if (this.onflush) { + this.onflush(); + } + return this; + } + styles() { + return this._styles; + } + } + vttparser.default = WebVTTParser; + vttparser.WebVTTParser = WebVTTParser; + + var vtthtmlrenderer = {}; + + /** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + Object.defineProperty(vtthtmlrenderer, "__esModule", { value: true }); + const vttcue_1 = vttcue; + vtthtmlrenderer.VTTCue = vttcue_1.VTTCue; + const vttparser_utility_1 = vttparserUtility; + const CUE_BACKGROUND_PADDING = '1.5%'; + const OVERLAP_PADDING = 0; // Pixels + const PERCENT_EDGE_OFFSET = 0.05; + const MAX_PLACEMENT_ATTEMPTS = 10; + const DEFAULT_LINE_HEIGHT = 41; // line height for 36px Helvetica font + const foregroundStyleSelector = '::cue'; + const backgroundStyleSelector = '::-webkit-media-text-track-display'; + const classSelectorRegex = /^(::cue\()(\..*)(\))/; + const idSelectorRegex = /^(::cue\()(#.*)(\))/; + const typeSelectorRegex = /^(::cue\()(c|i|b|u|ruby|rt|v|lang)(\))/; + const globalStyleRegex = [ + classSelectorRegex, + idSelectorRegex, + typeSelectorRegex + ]; + // This is a list of all the Unicode characters that have a strong + // right-to-left category. What this means is that these characters are + // written right-to-left for sure. It was generated by pulling all the strong + // right-to-left characters out of the Unicode data table. That table can + // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt + const strongRTLRanges = [ + [0x5be, 0x5be], + [0x5c0, 0x5c0], + [0x5c3, 0x5c3], + [0x5c6, 0x5c6], + [0x5d0, 0x5ea], + [0x5f0, 0x5f4], + [0x608, 0x608], + [0x60b, 0x60b], + [0x60d, 0x60d], + [0x61b, 0x61b], + [0x61e, 0x64a], + [0x66d, 0x66f], + [0x671, 0x6d5], + [0x6e5, 0x6e6], + [0x6ee, 0x6ef], + [0x6fa, 0x70d], + [0x70f, 0x710], + [0x712, 0x72f], + [0x74d, 0x7a5], + [0x7b1, 0x7b1], + [0x7c0, 0x7ea], + [0x7f4, 0x7f5], + [0x7fa, 0x7fa], + [0x800, 0x815], + [0x81a, 0x81a], + [0x824, 0x824], + [0x828, 0x828], + [0x830, 0x83e], + [0x840, 0x858], + [0x85e, 0x85e], + [0x8a0, 0x8a0], + [0x8a2, 0x8ac], + [0x200f, 0x200f], + [0xfb1d, 0xfb1d], + [0xfb1f, 0xfb28], + [0xfb2a, 0xfb36], + [0xfb38, 0xfb3c], + [0xfb3e, 0xfb3e], + [0xfb40, 0xfb41], + [0xfb43, 0xfb44], + [0xfb46, 0xfbc1], + [0xfbd3, 0xfd3d], + [0xfd50, 0xfd8f], + [0xfd92, 0xfdc7], + [0xfdf0, 0xfdfc], + [0xfe70, 0xfe74], + [0xfe76, 0xfefc], + [0x10800, 0x10805], + [0x10808, 0x10808], + [0x1080a, 0x10835], + [0x10837, 0x10838], + [0x1083c, 0x1083c], + [0x1083f, 0x10855], + [0x10857, 0x1085f], + [0x10900, 0x1091b], + [0x10920, 0x10939], + [0x1093f, 0x1093f], + [0x10980, 0x109b7], + [0x109be, 0x109bf], + [0x10a00, 0x10a00], + [0x10a10, 0x10a13], + [0x10a15, 0x10a17], + [0x10a19, 0x10a33], + [0x10a40, 0x10a47], + [0x10a50, 0x10a58], + [0x10a60, 0x10a7f], + [0x10b00, 0x10b35], + [0x10b40, 0x10b55], + [0x10b58, 0x10b72], + [0x10b78, 0x10b7f], + [0x10c00, 0x10c48], + [0x1ee00, 0x1ee03], + [0x1ee05, 0x1ee1f], + [0x1ee21, 0x1ee22], + [0x1ee24, 0x1ee24], + [0x1ee27, 0x1ee27], + [0x1ee29, 0x1ee32], + [0x1ee34, 0x1ee37], + [0x1ee39, 0x1ee39], + [0x1ee3b, 0x1ee3b], + [0x1ee42, 0x1ee42], + [0x1ee47, 0x1ee47], + [0x1ee49, 0x1ee49], + [0x1ee4b, 0x1ee4b], + [0x1ee4d, 0x1ee4f], + [0x1ee51, 0x1ee52], + [0x1ee54, 0x1ee54], + [0x1ee57, 0x1ee57], + [0x1ee59, 0x1ee59], + [0x1ee5b, 0x1ee5b], + [0x1ee5d, 0x1ee5d], + [0x1ee5f, 0x1ee5f], + [0x1ee61, 0x1ee62], + [0x1ee64, 0x1ee64], + [0x1ee67, 0x1ee6a], + [0x1ee6c, 0x1ee72], + [0x1ee74, 0x1ee77], + [0x1ee79, 0x1ee7c], + [0x1ee7e, 0x1ee7e], + [0x1ee80, 0x1ee89], + [0x1ee8b, 0x1ee9b], + [0x1eea1, 0x1eea3], + [0x1eea5, 0x1eea9], + [0x1eeab, 0x1eebb], + [0x10fffd, 0x10fffd] + ]; + class StyleBox { + // Apply styles to a div. If there is no div passed then it defaults to the + // div on 'this'. + applyStyles(styles, div) { + div = div || this.div; + for (const prop in styles) { + if (styles.hasOwnProperty(prop)) { + div.style[prop] = styles[prop]; + } + } + } + formatStyle(val, unit) { + return val === 0 ? '0' : val + unit; + } + } + vtthtmlrenderer.StyleBox = StyleBox; + // Constructs the computed display state of the cue (a div). Places the div + // into the overlay which should be a block level element (usually a div). + class CueStyleBox extends StyleBox { + constructor(window, cue, foregroundStyleOptions, backgroundStyleOptions, globalStyleCollection) { + super(); + this.cue = cue; + let textAlignMap = { + 'start': 'left', + 'line-left': 'left', + 'left': 'left', + 'center': 'center', + 'middle': 'center', + 'line-right': 'right', + 'right': 'right', + 'end': 'right', + }; + let textAlign = textAlignMap[cue.positionAlign] || cue.align; + let styles = { + textAlign: textAlign, + whiteSpace: 'pre-line', + position: 'absolute' + }; + styles.direction = this.determineBidi(this.cueDiv); + styles.writingMode = this.directionSettingToWritingMode(cue.vertical); + styles.unicodeBidi = 'plaintext'; + // Create an absolutely positioned div that will be used to position the cue + // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS + // mirrors of them except "middle" which is "center" in CSS. + this.div = window.document.createElement('div'); + this.applyStyles(styles); + styles = { + backgroundColor: backgroundStyleOptions.backgroundColor, + display: 'inline-block' + }; + // If the background opacity is 0 or undefined don't want to increase + // the cue size by adding padding to the background div + if (this.parseOpacity(styles.backgroundColor)) { + styles.padding = '5px'; + styles.borderRadius = '5px'; + } + this.backgroundDiv = window.document.createElement('div'); + this.applyStyles(styles, this.backgroundDiv); + styles = { + color: foregroundStyleOptions.color, + backgroundColor: foregroundStyleOptions.backgroundColor, + textShadow: foregroundStyleOptions.textShadow, + fontSize: foregroundStyleOptions.fontSize, + fontFamily: foregroundStyleOptions.fontFamily, + position: 'relative', + left: '0', + right: '0', + top: '0', + bottom: '0', + display: 'inline-block', + textOrientation: 'upright' + }; + styles.writingMode = this.directionSettingToWritingMode(cue.vertical); + styles.unicodeBidi = 'plaintext'; + // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will + // have inline-block positioning and will function as the cue foreground box. + this.cueDiv = vttparser_utility_1.default.parseContent(window, cue, globalStyleCollection); + this.applyStyles(styles, this.cueDiv); + this.backgroundDiv.appendChild(this.cueDiv); + this.div.appendChild(this.backgroundDiv); + // Calculate the distance from the reference edge of the viewport to the text + // position of the cue box. The reference edge will be resolved later when + // the box orientation styles are applied. + let textPos = 0; + if (typeof cue.position === 'number') { + let cueAlignment = cue.positionAlign || cue.align; + if (cueAlignment) { + switch (cueAlignment) { + case 'start': + case 'left': + textPos = cue.position; + break; + case 'center': + case 'middle': + textPos = cue.position - cue.size / 2; + break; + case 'end': + case 'right': + textPos = cue.position - cue.size; + break; + } + } + } + // Horizontal box orientation; textPos is the distance from the left edge of the + // area to the left edge of the box and cue.size is the distance extending to + // the right from there. + if (cue.vertical === '') { + this.applyStyles({ + left: this.formatStyle(textPos, '%'), + width: this.formatStyle(cue.size, '%') + }); + // Vertical box orientation; textPos is the distance from the top edge of the + // area to the top edge of the box and cue.size is the height extending + // downwards from there. + } + else { + this.applyStyles({ + top: this.formatStyle(textPos, '%'), + height: this.formatStyle(cue.size, '%') + }); + } + } + determineBidi(cueDiv) { + let nodeStack = []; + let text = ''; + let charCode; + if (!cueDiv || !cueDiv.childNodes) { + return 'ltr'; + } + function pushNodes(nodeStack, node) { + for (let i = node.childNodes.length - 1; i >= 0; i--) { + nodeStack.push(node.childNodes[i]); + } + } + function nextTextNode(nodeStack) { + if (!nodeStack || !nodeStack.length) { + return null; + } + let node = nodeStack.pop(); + let text = node.textContent || node.innerText; + if (text) { + // TODO: This should match all unicode type B characters (paragraph + // separator characters). See issue #115. + const m = /^.*(\n|\r)/.exec(text); + if (m) { + nodeStack.length = 0; + return m[0]; + } + return text; + } + if (node.tagName === 'ruby') { + return nextTextNode(nodeStack); + } + if (node.childNodes) { + pushNodes(nodeStack, node); + return nextTextNode(nodeStack); + } + } + function isContainedInCharacterList(charCode, characterList) { + for (const currentRange of characterList) { + if (charCode >= currentRange[0] && charCode <= currentRange[1]) { + return true; + } + } + return false; + } + pushNodes(nodeStack, cueDiv); + while ((text = nextTextNode(nodeStack))) { + for (let i = 0; i < text.length; i++) { + charCode = text.charCodeAt(i); + if (isContainedInCharacterList(charCode, strongRTLRanges)) { + return 'rtl'; + } + } + } + return 'ltr'; + } + parseOpacity(colorString) { + if (!colorString || typeof colorString !== 'string') { + return null; + } + // Trim whitespace, strip out "rgba(" and ")" from the string + colorString = colorString.replace(/ /g, '').replace('rgba(', '').replace(')', ''); + // Split r, g, b, a into an array for easier processing - we just need the opacity + const parts = colorString.split(','); + if (parts && parts.length >= 4) { + return parts[3]; + } + return null; + } + directionSettingToWritingMode(directionSetting) { + if (directionSetting === '') { + return 'horizontal-tb'; + } + else if (directionSetting === 'lr') { + return 'vertical-lr'; + } + else { + return 'vertical-rl'; + } + } + move(box) { + this.applyStyles({ + top: this.formatStyle(box.top, 'px'), + bottom: this.formatStyle(box.bottom, 'px'), + left: this.formatStyle(box.left, 'px'), + right: this.formatStyle(box.right, 'px'), + height: this.formatStyle(box.height, 'px'), + width: this.formatStyle(box.width, 'px') + }); + } + } + vtthtmlrenderer.CueStyleBox = CueStyleBox; + // Represents the co-ordinates of an Element in a way that we can easily + // compute things with such as if it overlaps or intersects with another Element. + // Can initialize it with either a StyleBox or another BoxPosition. + class BoxPosition { + constructor(obj) { + function isVertical(cue) { + return cue && cue.vertical !== ''; + } + if (obj instanceof CueStyleBox && obj.cue) { + if (isVertical(obj.cue)) { + this.property = 'width'; + } + else { + this.property = 'height'; + } + } + else if (obj instanceof BoxPosition) { + this.property = obj.property || 'height'; + } + // Either a BoxPosition was passed in and we need to copy it, or a StyleBox + // was passed in and we need to copy the results of 'getBoundingClientRect' + // as the object returned is readonly. All co-ordinate values are in reference + // to the viewport origin (top left). + let lh, slh, height, width, top, rect; + if (obj instanceof CueStyleBox && obj.div) { + height = obj.div.offsetHeight; + width = obj.div.offsetWidth; + top = obj.div.offsetTop; + const outerDiv = obj.div.firstChild; + // When we're initializing a BoxPosition with a CueStyleBox want to use the child element which just has + // the width / length of the text, otherwise the full length will overflow outside of the container + // causing the CueStyleBox.within function to return false, and then the overlap algorithm to fail + if (outerDiv) { + rect = outerDiv.getBoundingClientRect(); + } + else { + rect = obj.div.getBoundingClientRect(); + } + lh = (rect && rect[this.property]) || null; + if (outerDiv && outerDiv.firstChild) { + const innerDiv = outerDiv.firstChild; + if (innerDiv && typeof innerDiv.textContent === 'string') { + const numOfLines = this.calculateNewLines(innerDiv.textContent); + slh = lh / numOfLines; + } + } + } + else if (obj instanceof BoxPosition) { + rect = obj; + } + this.left = rect.left; + this.right = rect.right; + this.top = rect.top || top; + this.height = rect.height || height; + this.bottom = rect.bottom || top + (rect.height || height); + this.width = rect.width || width; + this.lineHeight = lh !== null ? lh : rect.lineHeight; + this.singleLineHeight = slh !== null ? slh : rect.singleLineHeight; + if (!this.singleLineHeight) { + this.singleLineHeight = DEFAULT_LINE_HEIGHT; + } + } + calculateNewLines(str) { + let numOfLines = 1; + for (let i = 0; i < str.length; i++) { + if (str[i] === '\n') { + numOfLines++; + } + } + return numOfLines; + } + // Move the box along a particular axis. Optionally pass in an amount to move + // the box. If no amount is passed then the default is the line height of the + // box. + move(axis, toMove) { + toMove = toMove !== undefined ? toMove : this.singleLineHeight; + switch (axis) { + case '+x': + this.left += toMove; + this.right += toMove; + break; + case '-x': + this.left -= toMove; + this.right -= toMove; + break; + case '+y': + this.top += toMove; + this.bottom += toMove; + break; + case '-y': + this.top -= toMove; + this.bottom -= toMove; + break; + } + } + // Check if this box overlaps another box, b2. + overlaps(b2) { + return (this.left < b2.right && + this.right > b2.left && + this.top < b2.bottom && + this.bottom > b2.top); + } + // Check if this box overlaps any other boxes in boxes. + overlapsAny(boxes) { + for (const box of boxes) { + if (this.overlaps(box)) { + return true; + } + } + return false; + } + // Check if this box is within another box. + within(container) { + return (this.top >= container.top && + this.bottom <= container.bottom && + this.left >= container.left && + this.right <= container.right); + } + // Check if this box is entirely within the container or it is overlapping + // on the edge opposite of the axis direction passed. For example, if "+x" is + // passed and the box is overlapping on the left edge of the container, then + // move the left edge of the box to align with the left edge of the container + moveIfOutOfBounds(container, axis) { + switch (axis) { + case '+x': + if (this.left < container.left) { + this.left = container.left; + this.right = this.left + this.width; + } + break; + case '-x': + if (this.right > container.right) { + this.right = container.right; + this.left = this.right - this.width; + } + break; + case '+y': + if (this.top < container.top) { + this.top = container.top; + this.bottom = this.top + this.height; + } + break; + case '-y': + if (this.bottom > container.bottom) { + this.bottom = container.bottom; + this.top = this.bottom - this.height; + } + break; + } + } + // Convert the positions from this box to CSS compatible positions using + // the reference container's positions. This has to be done because this + // box's positions are in reference to the viewport origin, whereas, CSS + // values are in reference to their respective edges. + toCSSCompatValues(reference) { + return { + top: this.top - reference.top, + bottom: reference.bottom - this.bottom, + left: this.left - reference.left, + right: reference.right - this.right, + height: this.height, + width: this.width + }; + } + // Get an object that represents the box's position without anything extra. + // Can pass a StyleBox or HTMLElement. + static getSimpleBoxPosition(obj) { + let element = null; + if (obj instanceof StyleBox && obj.div) { + element = obj.div; + } + else if (obj instanceof HTMLElement) { + element = obj; + } + let height = element.offsetHeight || 0; + let width = element.offsetWidth || 0; + let top = element.offsetTop || 0; + let bottom = top + height; + let rect = element.getBoundingClientRect(); + const { left, right } = rect; + if (rect.top) { + top = rect.top; + } + if (rect.height) { + height = rect.height; + } + if (rect.width) { + width = rect.width; + } + if (rect.bottom) { + bottom = rect.bottom; + } + return { left, right, top, height, bottom, width }; + } + static getBoxPosition(boxPositions, direction) { + if (boxPositions && boxPositions.length > 0) { + let savedIndex = 0; + let maxValue = boxPositions[0][direction]; + for (let i = 0; i < boxPositions.length; i++) { + if (direction in ['top', 'right']) { + if (boxPositions[i][direction] > maxValue) { + savedIndex = i; + maxValue = boxPositions[i][direction]; + } + } + else if (direction in ['bottom', 'left']) { + if (boxPositions[i][direction] < maxValue) { + savedIndex = i; + maxValue = boxPositions[i][direction]; + } + } + } + return boxPositions[savedIndex]; + } + else { + return null; + } + } + // Move our box (cue), b, so there's no overlap with any other cues along that axis + // For example, if our axis is +y, we'll want to place our box right above the top-most cue + static moveToMinimumDistancePlacement(b, axis, boxes) { + if (b.property === 'height') { + if (axis === '+y') { + b.top = boxes.topMostBoxPosition.bottom + OVERLAP_PADDING; + b.bottom = b.top + b.height; + } + else if (axis === '-y') { + b.bottom = boxes.bottomMostBoxPosition.top - OVERLAP_PADDING; + b.top = b.bottom - b.height; + } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + } + else if (b.property === 'width') { + if (axis === '+x') { + b.left = boxes.rightMostBoxPosition.right + OVERLAP_PADDING; + b.right = b.left + b.width; + } + else if (axis === '-x') { + b.right = boxes.leftMostBoxPosition.left - OVERLAP_PADDING; + b.left = b.right - b.width; + } + } + } + // Move a StyleBox to its specified, or next best, position. The containerBox + // is the box that contains the StyleBox, such as a div. boxPositions are + // a list of other boxes that the styleBox can't overlap with. + static moveBoxToLinePosition(styleBox, containerBox, boxPositions) { + // Find the best position for a cue box, b, on the video. The axis parameter + // is a list of axis, the order of which, it will move the box along. For example: + // Passing ["+x", "-x"] will move the box first along the x axis in the positive + // direction. If it doesn't find a good position for it there it will then move + // it along the x axis in the negative direction. + function findBestPosition(b, axis) { + let minimumDistanceBoxes; + for (let i = 0; i < axis.length; i++) { + // Step 1. check if our current cue is within our render area boundary and re-position our cue if needed + b.moveIfOutOfBounds(containerBox, axis[i]); + // We'll do our best to place the next cue, but want + // another way to exit this while loop in case we get stuck + let currentAttempt = 0; + let attemptedMinimumDistancePlacement = false; + // Step 2. check if our current cue overlaps any other cues and re-position our cue if needed + while (b.overlapsAny(boxPositions)) { + if (currentAttempt > MAX_PLACEMENT_ATTEMPTS - 1) { + break; + } + if (!attemptedMinimumDistancePlacement) { + if (boxPositions && boxPositions.length > 0) { + // Calculating here so we don't spend time on this calculation unless there was collision + if (!minimumDistanceBoxes) { + minimumDistanceBoxes = { + topMostBoxPosition: BoxPosition.getBoxPosition(boxPositions, 'top'), + bottomMostBoxPosition: BoxPosition.getBoxPosition(boxPositions, 'bottom'), + leftMostBoxPosition: BoxPosition.getBoxPosition(boxPositions, 'left'), + rightMostBoxPosition: BoxPosition.getBoxPosition(boxPositions, 'right') + }; + } + BoxPosition.moveToMinimumDistancePlacement(b, axis[i], minimumDistanceBoxes); + } + attemptedMinimumDistancePlacement = true; + } + else { + b.move(axis[i]); + } + currentAttempt++; + } + } + // Our original position if we were already in bounds and + // didn't overlap with other cues, otherwise was moved by above + return b; + } + function computeLinePos(cue) { + if (typeof cue.line === 'number' && + (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) { + return cue.line; + } + if (!cue.track || + !cue.track.textTrackList || + !cue.track.textTrackList.mediaElement) { + return -1; + } + let count = 0; + const track = cue.track, trackList = track.textTrackList; + for (let i = 0; i < trackList.length && trackList[i] !== track; i++) { + if (trackList[i].mode === 'showing') { + count++; + } + } + return ++count * -1; + } + const cue = styleBox.cue; + let boxPosition = new BoxPosition(styleBox), linePos = computeLinePos(cue), axis = [], size; + // If we have a line number to align the cue to. + if (cue.snapToLines) { + let position = 0; + switch (cue.vertical) { + case '': + axis = ['+y', '-y']; + size = 'height'; + break; + case 'rl': + axis = ['+x', '-x']; + size = 'width'; + break; + case 'lr': + axis = ['-x', '+x']; + size = 'width'; + break; + } + const step = boxPosition.lineHeight, maxPosition = containerBox[size] + step, initialAxis = axis[0]; + // If computed line position returns negative then line numbers are + // relative to the bottom of the video instead of the top. Therefore, we + // need to increase our initial position by the length or width of the + // video, depending on the writing direction, and reverse our axis directions. + // Provide a reasonable automatic position that is closest to the "towards direction" + if (linePos < 0) { + let initialOffset = 0; + switch (cue.vertical) { + case '': + initialOffset = containerBox.height - step - containerBox.height * PERCENT_EDGE_OFFSET; // default to bottom + break; + // Depending on positioning, chromium will fip layout when writing-mode:vertical-rl is set + // https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/layout/README.md + // In this case, chromium writing-mode:vertical-lr property defaults the div to the left, and writing-mode:vertical-rl defaults the div to the right + // For WebVTT default values we want to render the initial values at the opposite end, so will use the equations below to adjust + case 'rl': + initialOffset = -containerBox.width + step + containerBox.width * PERCENT_EDGE_OFFSET; // rl: 100% <----- 0%; default to left + break; + case 'lr': + initialOffset = -containerBox.width + step + containerBox.width * PERCENT_EDGE_OFFSET; // lr: 0% -----> 100%; default to right + break; + } + position = initialOffset; + axis = axis.reverse(); + } + else { + // We have been given an actual line position. Calculate appropriate layout. + switch (cue.vertical) { + case '': + position = step * Math.round(linePos); // step down from top + break; + case 'rl': + position = containerBox.width - step * Math.round(linePos); // step down from right side + break; + case 'lr': + position = step * Math.round(linePos); // step down from left side + break; + } + // If the specified initial position is greater then the max position then + // clamp the box to the amount of steps it would take for the box to + // reach the max position. + if (Math.abs(position) > maxPosition) { + position = position < 0 ? -1 : 1; + position *= Math.ceil(maxPosition / step) * step; + } + } + // Move the box to the specified position. This may not be its best position. + boxPosition.move(initialAxis, position); + } + else { + // If we have a percentage line value for the cue. + const percentageBase = cue.vertical === '' ? containerBox.height : containerBox.width; + const calculatedPercentage = (boxPosition.lineHeight / percentageBase) * 100; + switch (cue.lineAlign) { + case 'center': + linePos -= calculatedPercentage / 2; + break; + case 'end': + linePos -= calculatedPercentage; + break; + } + // Apply initial line position to the cue box. + switch (cue.vertical) { + case '': + styleBox.applyStyles({ + top: styleBox.formatStyle(linePos, '%') // step down from top + }); + break; + case 'rl': + styleBox.applyStyles({ + right: styleBox.formatStyle(linePos, '%') // step down from right + }); + break; + case 'lr': + styleBox.applyStyles({ + left: styleBox.formatStyle(linePos, '%') // step down from left + }); + break; + } + axis = ['+y', '-y', '+x', '-x']; + // Using this as a hint of which direction we want to place the next cues + // Only doing this for horizontally positioned subtitles for now + // TODO: rdar://50386682 (Improve overlap rendering for vertical subtitles [Nice to Have]) + if (cue.axis === '+y') { + axis = ['+y', '-y', '+x', '-x']; + } + else if (cue.axis === '-y') { + axis = ['-y', '+y', '+x', '-x']; + } + // Get the box position again after we've applied the specified positioning to it. + boxPosition = new BoxPosition(styleBox); + } + const bestPosition = findBestPosition(boxPosition, axis); + styleBox.move(bestPosition.toCSSCompatValues(containerBox)); + } + } + vtthtmlrenderer.BoxPosition = BoxPosition; + class WebVTTRenderer { + constructor(window, overlay, loggingEnabled = true) { + if (!window) { + return null; + } + this.window = window; + this.overlay = overlay; + this.loggingEnabled = loggingEnabled; + this.foregroundStyleOptions = { + fontFamily: 'Helvetica', + fontSize: '36px', + color: 'rgba(255, 255, 255, 1)', + textShadow: '', + backgroundColor: 'rgba(0, 0, 0, 0)' // Text Highlight + }; + this.backgroundStyleOptions = { + backgroundColor: 'rgba(0, 0, 0, 0.5)' + }; + this.globalStyleCollection = {}; + const paddedOverlay = window.document.createElement('div'); + paddedOverlay.style.position = 'absolute'; + paddedOverlay.style.left = '0'; + paddedOverlay.style.right = '0'; + paddedOverlay.style.top = '0'; + paddedOverlay.style.bottom = '0'; + paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; + this.paddedOverlay = paddedOverlay; + overlay.appendChild(this.paddedOverlay); + this.initSubtitleCSS(); + } + /** + * Sometimes, certain CSS isn't being applied to the first cue rendered + * We can init some of the CSS here by rendering a dummy cue + */ + initSubtitleCSS() { + const dummyCue = new vttcue_1.VTTCue(0, 0, `String to init CSS - Won't be visible to user`); + const dummyCueTextTrack = [dummyCue]; + // Hide the overlay so we don't get a flash of the text + this.paddedOverlay.style.opacity = '0'; + this.processCues(dummyCueTextTrack); + this.processCues([]); + this.paddedOverlay.style.opacity = '1'; + } + convertCueToDOMTree(cue) { + if (!cue) { + return null; + } + return vttparser_utility_1.default.parseContent(this.window, cue, this.globalStyleCollection); + } + setStyles(styles) { + function applyStyles(collection, newStyles, confine) { + for (const prop in newStyles) { + if (newStyles.hasOwnProperty(prop)) { + if (confine === true && collection[prop] !== undefined) { + collection[prop] = newStyles[prop]; + } + else if (confine === false) { + collection[prop] = newStyles[prop]; + } + } + } + } + for (const selector in styles) { + let confinedStyleOption = false; + let styleOptions = null; + if (selector === foregroundStyleSelector) { + styleOptions = this.foregroundStyleOptions; + confinedStyleOption = true; + } + else if (selector === backgroundStyleSelector) { + styleOptions = this.backgroundStyleOptions; + confinedStyleOption = true; + } + const selectorStyles = styles[selector]; + if (confinedStyleOption === true) { + // Limited set of allowed styles to update + applyStyles(styleOptions, selectorStyles, confinedStyleOption); + } + else { + // Styles with a selector. Parse out selector: ::cue() + for (let index = 0; index < globalStyleRegex.length; index++) { + const regex = globalStyleRegex[index]; + const match = regex.exec(selector); + if (match && match.length === 4) { + const newSelector = match[2]; + const newCollection = {}; + applyStyles(newCollection, selectorStyles, confinedStyleOption); + this.globalStyleCollection[newSelector] = newCollection; + } + } + } + } + this.initSubtitleCSS(); + if (this.loggingEnabled) { + console.log('WebVTTRenderer setStyles foregroundStyleOptions: ' + JSON.stringify(this.foregroundStyleOptions)); + console.log('WebVTTRenderer setStyles backgroundStyleOptions: ' + JSON.stringify(this.backgroundStyleOptions)); + console.log('WebVTTRenderer setStyles globalStyleCollection: ' + JSON.stringify(this.globalStyleCollection)); + } + } + /** + * Runs the WebVTT processing model over the cues passed to it. + * See https://www.w3.org/TR/webvtt1/#rendering for implementation details. + * + * @param {VTTCue|TextTrackCueList} cues list of cues to be rendered + */ + processCues(cues) { + if (!cues) { + return; + } + // Remove all previous children. + while (this.paddedOverlay.firstChild) { + this.paddedOverlay.removeChild(this.paddedOverlay.firstChild); + } + function sortCues(cues) { + const cueList = []; + let avgLine = 0; + for (let i = 0; i < cues.length; i++) { + let cue = cues[i]; + // If any of the line positions aren't a number return our original TextTrackCueList + if (typeof cue.line !== 'number') { + return cues; + } + avgLine += cue.line; + cueList.push(cue); + } + avgLine = avgLine / cues.length; + if (avgLine > 50) { + // Render highest line value first + cueList.forEach(function (cue) { + cue.axis = '-y'; + }); + cueList.sort((a, b) => b.line - a.line); + } + else { + // Render lowest line value first + cueList.forEach(function (cue) { + cue.axis = '+y'; + }); + cueList.sort((a, b) => a.line - b.line); + } + // Just a normal array where we had a TextTrackCueList before, but should be okay + return cueList; + } + // Determine if we need to compute the display states of the cues. This could + // be the case if a cue's state has been changed since the last computation or + // if it has not been computed yet. + function shouldCompute(cues) { + for (let i = 0; i < cues.length; i++) { + if (cues[i].hasBeenReset || !cues[i].displayState) { + return true; + } + } + return false; + } + // We don't need to recompute the cues' display states. Just reuse them. + if (!shouldCompute(cues)) { + for (let i = 0; i < cues.length; i++) { + this.paddedOverlay.appendChild(cues[i].displayState); + } + return; + } + const boxPositions = [], containerBox = BoxPosition.getSimpleBoxPosition(this.paddedOverlay); + // cues is of type TextTrackCueList which has a length property + if (cues.length > 1) { + cues = sortCues(cues); + } + for (let i = 0; i < cues.length; i++) { + let cue = cues[i]; + // Compute the initial position and styles of the cue div. + let styleBox = new CueStyleBox(this.window, cue, this.foregroundStyleOptions, this.backgroundStyleOptions, this.globalStyleCollection); + this.paddedOverlay.appendChild(styleBox.div); + // Move the cue div to it's correct line position. + BoxPosition.moveBoxToLinePosition(styleBox, containerBox, boxPositions); + // Remember the computed div so that we don't have to recompute it later + // if we don't have too. + cue.displayState = styleBox.div; + boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); + } + } + /** + * Update the dimensions of the overlay container + * @param width width in pixels + * @param height height in pixels + */ + setSize(width, height) { + if (width) { + this.overlay.style.width = width + "px"; + } + if (height) { + this.overlay.style.height = height + "px"; + } + } + /** + * Returns the HTMLElement passed in to instantiate this class + */ + getOverlay() { + return this.overlay; + } + } + vtthtmlrenderer.default = WebVTTRenderer; + vtthtmlrenderer.WebVTTRenderer = WebVTTRenderer; + + (function (exports) { + /** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + Object.defineProperty(exports, "__esModule", { value: true }); + // Default exports for Node. Export the extended versions of VTTCue and + // VTTRegion in Node since we likely want the capability to convert back and + // forth between JSON. If we don't then it's not that big of a deal since we're + // off browser. + __export(vttparser); + __export(vtthtmlrenderer); + }(lib)); + + + const tsTimescale = 90000; // MPEG-TS timescale value + function isExtendedTextTrackCue(value) { + return Boolean(value.webVTTCue); + } + // String.prototype.startsWith is not supported in IE11 + function startsWith(input, search, position) { + return input.substr(position || 0, search.length) === search; + } + function cueString2millis(timeString) { + let ts = parseInt(timeString.substr(-3)); + const secs = parseInt(timeString.substr(-6, 2)); + const mins = parseInt(timeString.substr(-9, 2)); + const hours = timeString.length > 9 ? parseInt(timeString.substr(0, timeString.indexOf(':'))) : 0; + if (!isFiniteNumber(ts) || !isFiniteNumber(secs) || !isFiniteNumber(mins) || !isFiniteNumber(hours)) { + return -1; + } + ts += 1000 * secs; + ts += 60000 * mins; + ts += 3600000 * hours; + return ts; + } + // From https://github.com/darkskyapp/string-hash + function hash(text) { + let hash = 5381; + let i = text.length; + while (i) { + hash = (hash * 33) ^ text.charCodeAt(--i); + } + return (hash >>> 0).toString(); + } + function snapToHalfSecond(time) { + const lower = Math.floor(time); + const mid = lower + 0.5; + const upper = lower + 1; + let snappedTime; + if (time >= mid) { + snappedTime = time - mid >= upper - time ? upper : mid; + } + else { + snappedTime = time - lower >= mid - time ? mid : lower; + } + return snappedTime; + } + // find value x where: + // x = value + n * cardinality, for some integer n such that: + // |x - reference| <= cardinality / 2 + function wrapPtsInteger(value, reference = 0, cardinality = 8589934592) { + if (!Number.isFinite(reference)) { + return value; + } + const midpoint = cardinality / 2; + const diff = Math.abs(value - reference) % cardinality; + const offset = diff > midpoint ? cardinality - diff : -diff; + const direction = value > reference ? -1 : 1; + return reference + direction * offset; + } + const HLSVTTParser = { + parse: function (vttByteArray, initPTS, // initPTS of current cc + wrapReference, // reference time for wrapping overflowed timestamp (pick a time close to the actual time. e.g., frag.start) + cc, // current cc + callBack, errorCallBack, stylesParsedCallback, logger) { + // Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character. + const re = /\r\n|\n\r|\n|\r/g; + // Uint8Array.prototype.reduce is not implemented in IE11 + const vttLines = BufferUtils.utf8arrayToStr(new Uint8Array(vttByteArray)).trim().replace(re, '\n').split('\n'); + const initPTS90k = convertTimescale(initPTS, tsTimescale); // Convert initPTS to 90k timescale + // X-TIMESTAMP-MAP MPEGTS attribute integer value (in 90k timescale) + // assume MPEGTS = 0 if X-TIMESTAMP-MAP is absent + let mpegTs = 0; // basetime with timescale 90000 + // X-TIMESTAMP-MAP LOCAL attribute value parsed as number of seconds + let localTime = 0; + // Calculate wrapped ((MPEGTS - initPTS) / 90k) + // The number of seconds on the player timeline that the anchor point of the X-TIMESTAMP-MAP maps to + function calculateTimelineOffset() { + // wrapReference should be close to the final wrapped integer to prevent overflowed number after wrapped + // logger.debug(`mpegTs ${wrapPtsInteger(mpegTs)} - initPTS ${initPTS}, reference ${wrapReference} (${wrapReference * 90000})`); + return convertTimestampToSeconds({ + baseTime: wrapPtsInteger(wrapPtsInteger(mpegTs) - initPTS90k.baseTime, wrapReference * tsTimescale), + timescale: tsTimescale, + }); + } + const cues = []; + let parsingError = null; + let inHeader = true; + // let VTTCue = VTTCue || window.TextTrackCue; + // Create parser object using VTTCue with TextTrackCue fallback on certain browsers. + const parser = new lib.WebVTTParser(window, lib.WebVTTParser.StringDecoder(), stylesParsedCallback); + parser.oncue = function (cue) { + // cue offset = MPEGTS adjusted by InitPTS, assuming localtime is zero + const cueOffset = calculateTimelineOffset(); + // logger.log(`cueOffset ${cueOffset}`); + cue.startTime = wrapPtsInteger(cue.startTime + cueOffset - localTime, 0, 95443.7176888889); + cue.endTime = wrapPtsInteger(cue.endTime + cueOffset - localTime, 0, 95443.7176888889); + // Create a unique hash id for a cue based on start/end times and text. + // This helps timeline-controller to avoid showing repeated captions. + cue.id = hash(snapToHalfSecond(cue.startTime).toString()) + hash(snapToHalfSecond(cue.endTime - cue.startTime).toString()) + hash(cue.text); + // Fix encoding of special characters. TODO: Test with all sorts of weird characters. + cue.text = decodeURIComponent(encodeURIComponent(cue.text)); + if (cue.endTime > 0) { + cues.push(cue); + } + }; + parser.onparsingerror = function (e) { + parsingError = e; + }; + parser.onflush = function () { + if (parsingError && errorCallBack) { + errorCallBack(parsingError); + return; + } + callBack(cues); + }; + // Go through contents line by line. + vttLines.forEach((line) => { + if (inHeader) { + // Look for X-TIMESTAMP-MAP in header. + if (startsWith(line, 'X-TIMESTAMP-MAP=')) { + // Once found, no more are allowed anyway, so stop searching. + inHeader = false; + // Extract LOCAL and MPEGTS. + line + .substr(16) + .split(',') + .forEach((timestamp) => { + if (startsWith(timestamp, 'LOCAL:')) { + let localTimeMs; + try { + localTimeMs = cueString2millis(timestamp.substr(6)); + } + catch (e) { + localTimeMs = -1; + } + if (localTimeMs !== -1) { + localTime = localTimeMs / 1000; + } + else { + parsingError = new Error(`Malformed X-TIMESTAMP-MAP: ${line}`); + } + } + else if (startsWith(timestamp, 'MPEGTS:')) { + mpegTs = parseInt(timestamp.substr(7)); + } + }); + // Return without parsing X-TIMESTAMP-MAP line. + return; + } + } + // Parse line by default. + parser.parse(line + '\n'); + }); + parser.flush(); + }, + }; + var HLSVTTParser$1 = HLSVTTParser; + + + const Cues = { + newCue: function (track, startTime, endTime, screen, media) { + let cue; + let indenting; + let indent; + let text; + let line; + const context = { + foreground: false, + background: false, + italics: false, + underline: false, + flash: false, + styleStack: [], + }; + for (const [r, row] of screen.rows.entries()) { + indenting = true; + indent = 0; + text = ''; + if (!row.isEmpty()) { + for (let c = 0; c < row.chars.length; c++) { + if (row.chars[c].uchar.match(/\s/) && indenting) { + indent++; + } + else { + text += this.getFormattedChar(row.chars[c], context); + indenting = false; + } + } + // To be used for cleaning-up orphaned roll-up captions + row.cueStartTime = startTime; + // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE + if (startTime === endTime) { + endTime += 0.0001; + } + text = text.trim().replace(//gi, '\n'); + text += this.closeStyles(context); + // console.log('VTTCue ' + startTime + ' - ' + endTime + ': ' + text); + cue = new lib.VTTCue(startTime, endTime, text); + if (indent >= 16) { + indent--; + } + else { + indent++; + } + // VTTCue.line get's flakey when using controls, so let's now include line 13&14 + // also, drop line 1 since it's to close to the top + if (navigator.userAgent.match(/Firefox\//)) { + line = r + 1; + } + else { + line = r > 7 ? r : r + 1; + } + cue.snapToLines = false; // Need this to be false for position % to work + cue.line = 10 + line * 5.33; // ( 10% top padding + line number * (80% vertical render length / 15 rows) ) + cue.align = 'left'; + cue.position = this.getPosition(indent, media); + track.addCue(cue); + } + } + }, + getPosition: function (indent, media) { + // Assume our aspect ratio is 4:3 + let aspectRatio = 1.3333333333333333; + if (media && media.offsetWidth && media.offsetHeight) { + const mediaRatio = media.offsetWidth / media.offsetHeight; + // There are some 16:10 screens out there, which is closer to 16:9 than a 4:3 aspect ratio + // So, anything with a ratio of 16:10 or wider will treat as a 16:9 screen for our calculations + if (mediaRatio >= 1.6) { + aspectRatio = 1.7777777777777777; + } + } + // CEA-608 has 32 columns, and defines 10% padding on each side + // ( 10% left padding + indent * (80% horizontal render length / 32 columns) ) + let position = 10 + (indent / 32) * 80; + let leftBound = 10; + let rightBound = 90; + if (aspectRatio === 1.7777777777777777) { + // CEA-608 captions assume a 4:3 screen size, but since we'll be playing on a 16:9 need to adjust some numbers + // 4:3 => 12:9, and a 12:9 screen's width is 3/4 the size of a 16:9 screen + // 3/4 * 16 = 4, and 4/16 = 25%, which means we need to pad by 12.5% on each side + // Also, when calculating the left offset it was originally for a 4:3 screen, so need to divide by 3/4 to adjust to 16:9 percentages + position = 12.5 + position * 0.75; + leftBound = 20; + rightBound = 80; + } + // Clamp the position based on the aspect ratio - if out of these bounds, Firefox throws an exception and captions break + return Math.max(leftBound, Math.min(rightBound, position + (navigator.userAgent.match(/Firefox\//) ? 50 : 0))); + }, + // return 'c' for all possible class tags (for color and bg_color); or the given style tag untouched (e.g., u, i, blink) + getRootStyleTag: function (style) { + const styleKey = style[0]; + return styleKey === 'c' ? styleKey : style; + }, + closeStyles: function (context) { + let postfix = ''; + for (let i = context.styleStack.length - 1; i >= 0; --i) { + const styleTag = this.getRootStyleTag(context.styleStack[i]); + postfix += ''; + context.styleStack.pop(); + } + return postfix; + }, + beginStyleAndBalance: function (context, newStyle) { + let balancedStyles = ''; + if (newStyle[0] === 'c') { + balancedStyles += this.closeStyleAndBalance(context, 'c'); + } + balancedStyles += '<' + newStyle + '>'; + context.styleStack.push(newStyle); + return balancedStyles; + }, + closeStyleAndBalance: function (context, oldStyle) { + const totalStyleCount = context.styleStack.length; + let childrenStyleCount = 0; + let closingChildrenStyles = ''; + let balancedStyles = ''; + for (let i = totalStyleCount - 1; i >= 0; --i) { + const styleUsed = context.styleStack[i]; + const styleTag = this.getRootStyleTag(styleUsed); + if (oldStyle[0] === styleUsed[0]) { + closingChildrenStyles += ''; + context.styleStack.splice(totalStyleCount - 1 - childrenStyleCount); + break; + } + else { + if (styleTag[0] === 'c') { + context.background = ''; + context.foreground = ''; + context.flash = false; + closingChildrenStyles += ''; + } + else if (styleTag[0] === 'u') { + context.underline = false; + closingChildrenStyles += ''; + } + else if (styleTag[0] === 'i') { + context.italics = false; + closingChildrenStyles += ''; + } + childrenStyleCount++; + } + } + balancedStyles = closingChildrenStyles; + return balancedStyles; + }, + getFormattedChar: function (c, context) { + let prefix = ''; + let formattedChar = c.uchar; + // color styles + let newColorStyle = ''; + const foregroundChanged = c.penState.foreground !== context.foreground; + const backgroundChanged = c.penState.background !== context.background; + const blinkChanged = c.penState.flash !== context.flash; + if (foregroundChanged || backgroundChanged || blinkChanged) { + // always include current colors in tag + newColorStyle = '.' + c.penState.foreground; + newColorStyle += '.bg_' + c.penState.background; + if (c.penState.flash && blinkChanged) { + newColorStyle += '.blink'; // but blink may be optional + } + if (c.penState.foreground || c.penState.background || c.penState.blink) { + prefix += this.beginStyleAndBalance(context, 'c' + newColorStyle); + } + else { + // changed to undefined foreground _and_ background color + prefix += this.closeStyleAndBalance(context, 'c'); + } + if (foregroundChanged) { + context.foreground = c.penState.foreground; + } + if (backgroundChanged) { + context.background = c.penState.background; + } + if (blinkChanged) { + context.flash = c.penState.flash; + } + } + // other styles + if (c.penState.underline !== context.underline) { + prefix += c.penState.underline ? this.beginStyleAndBalance(context, 'u') : this.closeStyleAndBalance(context, 'u'); + context.underline = c.penState.underline; + } + if (c.penState.italics !== context.italics) { + prefix += c.penState.italics ? this.beginStyleAndBalance(context, 'i') : this.closeStyleAndBalance(context, 'i'); + context.italics = c.penState.italics; + } + formattedChar = prefix + formattedChar; + return formattedChar; + }, + }; + var Cues$1 = Cues; + + /* + * LegibleSystemAdapter + * + * + */ + var ParsedFragQuality; + (function (ParsedFragQuality) { + ParsedFragQuality["CloseEnough"] = "CloseEnough"; + ParsedFragQuality["TooFar"] = "TooFar"; + ParsedFragQuality["Unknown"] = "Unknown"; + })(ParsedFragQuality || (ParsedFragQuality = {})); + const isChannelTextTrackKey = (value) => { + return value === 'cc1' || value === 'cc2'; + }; + function filterSelectableTextTracks(textTrackList) { + const tracks = []; + for (let ix = 0; ix < textTrackList.length; ix++) { + const textTrack = textTrackList[ix]; + if (textTrack.kind === 'captions' || textTrack.kind === 'subtitles' || (textTrack.kind === 'metadata' && textTrack.customTextTrackCueRenderer)) { + tracks.push(textTrack); + } + } + return tracks; + } + const cea608Duration = 0.03336666666666667; + function clearCurrentCues(track) { + if (track && track.cues) { + while (track.cues.length > 0) { + track.removeCue(track.cues[0]); + } + } + } + function intersection(x1, x2, y1, y2) { + return Math.min(x2, y2) - Math.max(x1, y1); + } + class LegibleSystemAdapter extends Observable { + constructor(mediaSink, config, hls, logger) { + super((subscriber) => { + const hlsTarget = fromEventTarget(this.hls, this); + subscriber.add(hlsTarget + .event(HlsEvent$1.INLINE_STYLES_PARSED, this.onInlineStylesParsed) + .pipe(finalize$1(() => this.destroy())) + .subscribe()); + subscriber.add(timer(0, this.config.trottleCheckInterval) + .pipe(switchMap(() => { + this.checkReadyToLoadNextSubtitleFragment(); + return VOID; + })) + .subscribe()); + if (this.config.nativeTextTrackChangeHandling) { + const useTextTrackPolling = !(this.mediaSink.textTracks && 'onchange' in this.mediaSink.textTracks); + if (useTextTrackPolling) { + subscriber.add(timer(0, 500) + .pipe(switchMap(() => { + this._onTextTracksChanged(); + return VOID; + })) + .subscribe()); + } + else { + const textTrackListTarget = fromEventTarget(this.mediaSink.textTracks, this); + subscriber.add(textTrackListTarget.event('change', this._onTextTracksChanged).subscribe()); + } + } + }); + this.config = config; + this.hls = hls; + this.logger = logger.child({ name: 'legible' }); + this.mediaSink = mediaSink; + // Add the id3 text track to the legibleSystemAdapter + this.id3Track = mediaSink.id3TextTrack; + this.enableCaption = true; + this.Cues = Cues$1; + this.tracks = []; + this.cueRanges = []; + this.channelToTrackMap = {}; + this.htmlTextTrackMap = new Map(); + this.lastCueEndTime = 0; + this.gotTracks = false; + this.tryAgain$ = new BehaviorSubject(true); + this.needNextSubtitle$ = new BehaviorSubject(true); + } + destroy() { + clearCurrentCues(this.textTrack1); + clearCurrentCues(this.textTrack2); + this.mediaSink = undefined; + this.nativeSubtitleTrackChange$ = undefined; + } + convertCuesIntoSubtitleFragInfo(cues) { + const fragCueRecord = {}; + if (cues != null && cues.length > 0) { + // When we parse WebVTT cues, we assign the cue's containing + // fragment's sequence number to cue.fragSN. + for (let i = 0; i < cues.length; i++) { + const cue = cues[i]; + if (!isFiniteNumber(cue.fragSN)) { + continue; + } + const record = fragCueRecord[cue.fragSN]; + if (!record) { + fragCueRecord[cue.fragSN] = { count: 1, startTime: cue.startTime, endTime: cue.endTime }; + } + else { + record.count++; + record.startTime = Math.min(cue.startTime, record.startTime); + record.endTime = Math.max(cue.endTime, record.endTime); + } + } + } + return fragCueRecord; + } + checkReadyToLoadNextSubtitleFragment() { + const currentTime = this.mediaSink.mediaQuery.currentTime; + const lastParsedCue = this.lastCueEndTime; + let need = false; + if (currentTime >= lastParsedCue - this.config.subtitleLeadTime) { + need = true; // less than (default) 30 seconds away from last parsed cue + } + this.logger.trace(`[subtitle] needtoLoadNextSubtitle: ${need}: ${currentTime} >= ${lastParsedCue} - ${this.config.subtitleLeadTime}`); + this.needNextSubtitle$.next(need); + } + checkReadyToLoadNextSubtitleFragment$(frag, generatedFrags) { + var _a; + if (frag.mediaSeqNum === ((_a = generatedFrags[0]) === null || _a === void 0 ? void 0 : _a.mediaSeqNum)) { + return of(true); // don't delay the first fragment because we may need to reload if it's too far + } + this.checkReadyToLoadNextSubtitleFragment(); + return this.needNextSubtitle$; + } + getNextFragment(details, mediaFragment) { + const nextSN = mediaFragment.mediaSeqNum + 1; + const nextFrag = nextSN < details.fragments.length ? details.fragments[nextSN - details.startSN] : null; + return nextFrag; + } + // aggressive loading: always load subtitles until there is none left, + // without checking for waterlevel in the current HTML5 texttrack + // + // In mediaSink.archiveParsedSubtitleFragmentRecord(): + // After the legibleSystemAdapter parses a subtitle fragment, + // it records the startTime (of the first cue in the fragment), endTime (of the last cue), + // and number of added cues in the fragment on its corresponding fragInfo object. + // In this way, hls.js knows the time boundary of each parsed subtitle fragment and how many cues it has generated. + // In legibleSystemAdapter.calculateFragInfoMap(): + // Iterate through the cues in the current HTML5 texttrack + // to tally the cues for each fragment. + // * If this "remaining cue" count does not match the "added cue" count in archiveParsedSubtitleFragmentRecord(), + // we will pretend that the fragment has not been loaded (probably error'ed out during cue creation) + // + // When starting up, seeking or track switching, hls.js needs to find the first subtitle fragment to load. + // It is the first unloaded fragment beyond the playback position. + // * Ignore subtitle fragments earlier than the current playback position + // * Find any continuous series of loaded subtitle fragments that overlaps the current playback position. + // Determine the media sequence number of the last fragment in this series. hls.js will load the next fragment. + // * If no fragment overlaps the playback position, find the 1st fragment with start time >= + // playback position. + // * To deal with subtitle playlist timestamp inaccuracies, we use the parsed timestamps calculated in + // mediaSink.archiveParsedSubtitleFragmentRecord() to anchor the timeline. That way, we can use each fragment's + // parsed duration to approximate the right fragment to load. + calculateFragInfoMap(position, cues, subtitleParsedRecord, details) { + const actualFragInfoMap = this.convertCuesIntoSubtitleFragInfo(cues); + let bufferInfo = { len: 0, start: position, end: position }; + let start = position; + let end = position; + let prevFragSN = null; + let nextFragSN = null; + // ES6 will sort numeric property keys in ascending order automatically + // https://exploringjs.com/es6/ch_oop-besides-classes.html#_traversal-order-of-properties + for (const propertyKey in actualFragInfoMap) { + if (!Object.prototype.hasOwnProperty.call(actualFragInfoMap, propertyKey)) { + continue; + } + const sn = Number(propertyKey); + if (!isFiniteNumber(sn)) { + this.logger.warn(`$fragInfoMap has invalid key ${sn}`); + continue; // should not happen + } + const fragInfo = actualFragInfoMap[sn]; + if (!this.isFragmentCompleteOrEmpty(sn, fragInfo.count, subtitleParsedRecord)) { + continue; + } + // current search position is earlier than the very 1st cue in the entire fragment details + // re-adjust search position to 1st cue's start time so that we can anchor the search from this 1st (buffered) frag + if (sn === details.startSN && position < fragInfo.startTime) { + start = end = bufferInfo.start = bufferInfo.end = position = fragInfo.startTime; + } + // found a fragment where start < position and is the leading frag in a frag sequence + if (position >= fragInfo.startTime && + (start === position || // 1st frag in the loadPos + (isFiniteNumber(prevFragSN) && sn - prevFragSN > 1))) { + // frag disjoint from the last one + start = end = fragInfo.startTime; + } + // look for the overlapping fragment + if (position >= fragInfo.startTime) { + // potentially inside a frag, assume its endTime as our next load position, and keep going ... + end = fragInfo.endTime; + prevFragSN = sn; + continue; + } + if (isFiniteNumber(prevFragSN) && sn - prevFragSN === 1) { + // Consecutive SN between 2 neighboring cues, keep scanning down the frag chain + end = fragInfo.endTime; + prevFragSN = sn; + continue; + } + // found the end of a continuous fragment series which overlaps the current position + nextFragSN = sn; + break; + } + bufferInfo = { len: end - start, start, end }; + const subtitleBufferInfo = { fragInfoMap: actualFragInfoMap, bufferInfo, prevFragSN, nextFragSN }; + return subtitleBufferInfo; + } + findFrags$(details, activeDiscoSeq) { + return this.tryAgain$.pipe(observeOn(asyncScheduler), switchMap(() => { + const findFragResult = this.findFragmentsForPosition(this.mediaSink.mediaQuery.currentTime, activeDiscoSeq, details); + const nextFrags = findFragResult.foundFrags; + if (!nextFrags) { + return EMPTY; // no more frag left to process + } + this.lastCueEndTime = 0; // reset needNextSubtitle$ check + this.needNextSubtitle$.next(true); + return of(findFragResult); + })); + } + // return true to continue loading the entire fragment batch + reviewParsedFrag(parsedFragResult, findFragsResult, details) { + var _a, _b, _c, _d; + const frag = parsedFragResult.frag; + const parsedCueRecord = parsedFragResult.cueRange; + const subtitleBufferInfo = findFragsResult.subtitleBufferInfo; + const subtitleParsedInfo = findFragsResult.subtitleParsedInfo; + const currentTime = this.mediaSink.mediaQuery.currentTime; + const generatedFrags = findFragsResult.foundFrags; + let success = true; + if (frag.mediaSeqNum === generatedFrags[0].mediaSeqNum) { + if (!findFragsResult.timelineEstablished) { + this.logger.info(`[subtitle] frag sn ${frag.mediaSeqNum} parsed. retry findFrag`); + return ParsedFragQuality.TooFar; + } + // only check the starting frag + if (!parsedCueRecord) { + // missing parsed data: should not happen. let currentTime move until the findFrag returns another frag + this.logger.warn(`[subtitle] 1st frag sn ${frag.mediaSeqNum} has no cue; details ${details.fragments.length} frags`); + return ParsedFragQuality.Unknown; + } + // Check whether we inferred the first frag close enough. + if (parsedCueRecord.startTime < currentTime) { + const actualDurationToPlayHead = currentTime - parsedCueRecord.startTime; + const fragments = details.fragments; + const startIdx = frag.mediaSeqNum - details.startSN; + let i = startIdx; + let fragTime = parsedCueRecord.startTime; + for (; i < fragments.length; ++i) { + fragTime += fragments[i].duration; + if (fragTime >= currentTime) { + break; + } + } + const fragCount = i - startIdx + 1; + success = fragCount <= this.config.earlyFragTolerance; // find another frag if we are too many fragments away + this.logger.info(`[subtitle] 1st frag sn ${frag.mediaSeqNum} is ${actualDurationToPlayHead}s earlier and ${fragCount} frags away from currentTime ${currentTime}; success ${success}`); + } + else if (parsedCueRecord.startTime > currentTime && frag.mediaSeqNum !== details.startSN) { + const actualDurationToPlayHead = parsedCueRecord.startTime - currentTime; + const latestBufferedFrag = subtitleBufferInfo.prevFragSN; + this.logger.info(`[subtitle] last buffered frag is complete: ${(_a = subtitleBufferInfo.fragInfoMap[latestBufferedFrag]) === null || _a === void 0 ? void 0 : _a.count} vs ${(_b = subtitleParsedInfo[latestBufferedFrag]) === null || _b === void 0 ? void 0 : _b.count}`); + if (frag.mediaSeqNum === latestBufferedFrag + 1 && ((_c = subtitleBufferInfo.fragInfoMap[latestBufferedFrag]) === null || _c === void 0 ? void 0 : _c.count) === ((_d = subtitleParsedInfo[latestBufferedFrag]) === null || _d === void 0 ? void 0 : _d.count)) { + // parsed frag is later than currentTime, but it is just the next consecutive frag from a latest *processed* frag. success. + success = true; + this.logger.info(`[subtitle] parsed frag sn ${frag.mediaSeqNum} is ${actualDurationToPlayHead}s later than currentTime ${currentTime} but continues from previous frag ${subtitleBufferInfo.prevFragSN}; success ${success}`); + } + else { + // parsed frag is later than currentTime. This should not happen because the cues are usually later than the frag start time, + // causing the findFrag function to (always) return an earlier frag than expected. + success = actualDurationToPlayHead <= this.config.lateTolerance; + this.logger.info(`[subtitle] 1st frag sn ${frag.mediaSeqNum} is ${actualDurationToPlayHead}s later than currentTime ${currentTime} and is ${frag.duration}s long; success ${success}`); + } + } + } + return success ? ParsedFragQuality.CloseEnough : ParsedFragQuality.TooFar; + } + isFragmentEmpty(subtitleParsedRecord) { + return subtitleParsedRecord && !isFiniteNumber(subtitleParsedRecord.startTime) && subtitleParsedRecord.count === 0; + } + isFragmentCompleteOrEmpty(mediaSeqNum, cueCount, subtitleParsedRecord) { + const parsedRecord = subtitleParsedRecord ? subtitleParsedRecord[mediaSeqNum] : null; + const result = (parsedRecord === null || parsedRecord === void 0 ? void 0 : parsedRecord.count) === cueCount || this.isFragmentEmpty(parsedRecord); + return result; + } + // use one *unbuffered* fragment early because we used cue startTime as fragment startTime to find media fragment + getEarlierFragmentInSameDisco(details, frag, subtitleParsedRecord) { + const fragIdx = frag.mediaSeqNum - details.startSN - 1; + if (fragIdx < 0 || fragIdx > details.fragments.length - 1) { + this.logger.error(`[subtitle] getEarlierFragmentInSameDisco index ${fragIdx} out of range`); + return frag; // return original frag + } + const prevFrag = details.fragments[fragIdx]; + return prevFrag && prevFrag.discoSeqNum === frag.discoSeqNum && !subtitleParsedRecord[frag.mediaSeqNum] ? prevFrag : frag; + } + // subtitleParsedInfo: Records containing cue count, start and end time of parsed fragments. + // subtitleParsedInfo is calculated when we parse a frag to add its WebVTT cues + // (archiveParsedSubtitleFragmentRecord) + // subtitleBufferInfo: Records containing cue count, start and end time of buffered fragments. + // subtitleBufferInfo is calculated when we enumarate added (remaining) cues in text tracks + // (calculateFragInfoMap) + // 2 main differences: + // (1) subtitleParsedInfo is stored in akita store for the entire session. Each subtitle persistent id + // has one record (That means primary and backup subtitle track may share the same record). + // subtitleBufferInfo is calculated on-demand from the cues in the current enabled text track only. + // (2) The calculated frag (cue) start and end time in subtitleParsedInfo should be more accurate than + // the start and end time in subtitleBufferInfo. This is in case MSE or the app removes used cues from the text tracks. + inferSubtitleFragmentForPosition(position, activeDiscoSeqNum, subtitleParsedInfo, subtitleBufferInfo, details) { + let foundFrag; + let startFragIdx; + let startParsedRecord; + let endFragIdx; + let endParsedRecord; + if (isFiniteNumber(subtitleBufferInfo.prevFragSN)) { + startFragIdx = subtitleBufferInfo.prevFragSN - details.startSN; + startParsedRecord = subtitleParsedInfo[subtitleBufferInfo.prevFragSN]; + } + if (isFiniteNumber(subtitleBufferInfo.nextFragSN)) { + endFragIdx = subtitleBufferInfo.nextFragSN - details.startSN; + endParsedRecord = subtitleParsedInfo[subtitleBufferInfo.nextFragSN]; + } + if (isFiniteNumber(startFragIdx) && startFragIdx >= 0 && startFragIdx < details.fragments.length && startParsedRecord) { + let startPos = startParsedRecord.startTime; + const lastIdx = isFiniteNumber(endFragIdx) ? endFragIdx : details.fragments.length; + for (let i = startFragIdx; i < lastIdx; ++i) { + const mediaFragment = details.fragments[i]; + if (isFiniteNumber(activeDiscoSeqNum) && mediaFragment.discoSeqNum !== activeDiscoSeqNum) { + continue; + } + if (i === lastIdx - 1) { + // get the fragment before nextFragSN (in case we guessed too late during the last inference) + this.logger.info(`[subtitle] from frag sn ${subtitleBufferInfo.prevFragSN}, infer frag sn ${mediaFragment.mediaSeqNum} using lastIdx ${lastIdx}. startPos ${startPos} duration ${mediaFragment.duration} position ${position}`); + foundFrag = { foundFrag: mediaFragment, timelineEstablished: true }; + break; + } + else if (startPos + mediaFragment.duration > position && i > startFragIdx) { + // we have already loaded frag prevFragSN, so we are really only interested in frag (prevFragSN + 1) and beyond + this.logger.info(`[subtitle] from frag sn ${subtitleBufferInfo.prevFragSN}, infer frag sn ${mediaFragment.mediaSeqNum}: startPos ${startPos} + duration ${mediaFragment.duration} > ${position}`); + foundFrag = { foundFrag: mediaFragment, timelineEstablished: true }; + break; + } + startPos += mediaFragment.duration; + } + } + else if (isFiniteNumber(endFragIdx) && endFragIdx >= 0 && endFragIdx < details.fragments.length && endParsedRecord) { + let startPos = endParsedRecord.startTime; // endParsedRecord.startTime is fragments[endFragIdx].start + for (let i = endFragIdx - 1; i >= 0; --i) { + // keep probing the earlier fragment as long as the later/previous fragment's startPos > position + const mediaFragment = details.fragments[i]; + if (isFiniteNumber(activeDiscoSeqNum) && mediaFragment.discoSeqNum !== activeDiscoSeqNum) { + continue; + } + if (startPos <= position) { + // we want one fragment earlier than position, which is mediaFragment (because startPos belongs to the later/previous fragment) + this.logger.info(`[subtitle] from frag sn ${subtitleBufferInfo.nextFragSN}, infer frag sn ${mediaFragment.mediaSeqNum}: startPos ${startPos} <= ${position}`); + foundFrag = { foundFrag: mediaFragment, timelineEstablished: true }; + break; + } + startPos -= mediaFragment.duration; + } + } + else { + for (let i = 0; i < details.fragments.length; ++i) { + const mediaFragment = details.fragments[i]; + if (isFiniteNumber(activeDiscoSeqNum) && mediaFragment.discoSeqNum === activeDiscoSeqNum) { + this.logger.info(`[subtitle] infer frag sn ${mediaFragment.mediaSeqNum} in cc ${activeDiscoSeqNum}`); + foundFrag = { foundFrag: mediaFragment, timelineEstablished: false }; + break; + } + } + } + return foundFrag; + } + generateFragmentBatch(batchSize, activeDiscoSeqNum, fragResult, subtitleParsedInfo, subtitleBufferInfo, details) { + var _a; + const generatedFrags = []; + const anchorFrag = fragResult === null || fragResult === void 0 ? void 0 : fragResult.foundFrag; + if (!anchorFrag) { + return { foundFrags: undefined, subtitleParsedInfo: undefined, subtitleBufferInfo: undefined, timelineEstablished: fragResult === null || fragResult === void 0 ? void 0 : fragResult.timelineEstablished }; + } + const startIdx = anchorFrag ? anchorFrag.mediaSeqNum - details.startSN : details.fragments.length; + for (let i = startIdx; i < details.fragments.length && generatedFrags.length < batchSize; ++i) { + const frag = details.fragments[i]; + if (frag.discoSeqNum !== activeDiscoSeqNum) { + continue; + } + const bufferedCueCount = (_a = subtitleBufferInfo.fragInfoMap[frag.mediaSeqNum]) === null || _a === void 0 ? void 0 : _a.count; + if (!this.isFragmentCompleteOrEmpty(frag.mediaSeqNum, bufferedCueCount !== null && bufferedCueCount !== void 0 ? bufferedCueCount : 0, subtitleParsedInfo)) { + generatedFrags.push(frag); // include frag if not fully parsed + } + } + return { foundFrags: generatedFrags, subtitleParsedInfo, subtitleBufferInfo, timelineEstablished: fragResult === null || fragResult === void 0 ? void 0 : fragResult.timelineEstablished }; + } + findFragmentsForPosition(currentTime, activeDiscoSeqNum, details) { + // get past addCue records + const subtitleParsedRecord = this.mediaSink.mediaQuery.getParsedSubtitleRecordsForMediaOption(this.selectedTrack.persistentID); + // compose addCue records from remaining cues in current texttrack + const cues = this.getCuesOfEnabledTrack(this.selectedMediaOption.mediaOptionId, false /* this.enabledTrack.sideTrackId !== undefined */); + const subtitleBufferInfo = this.calculateFragInfoMap(currentTime, cues, subtitleParsedRecord, details); + const bufferInfo = subtitleBufferInfo.bufferInfo; + const loadPos = Math.max(currentTime, bufferInfo.end); + const fragResult = this.inferSubtitleFragmentForPosition(loadPos, activeDiscoSeqNum, subtitleParsedRecord, subtitleBufferInfo, details); + return this.generateFragmentBatch(Infinity, activeDiscoSeqNum, fragResult, subtitleParsedRecord, subtitleBufferInfo, details); + } + get selectedMediaOption() { + return this.selectedTrack ? this.selectedTrack : this._disabledMediaOption; + } + set selectedMediaOption(mediaOption) { + this.selectedTrack = isAlternateMediaOption(mediaOption) ? mediaOption : undefined; + } + get selectedTrack() { + return this._selectedMediaOption; + } + set selectedTrack(track) { + if (track === this._selectedMediaOption) { + return; + } + this.logger.info(`[subtitle] pick track #${track === null || track === void 0 ? void 0 : track.id} mediaOptionId ${track === null || track === void 0 ? void 0 : track.mediaOptionId} persistentId ${track === null || track === void 0 ? void 0 : track.persistentID}`); + this._selectedMediaOption = track; + this.updateTextTrackState(); + } + getTrack(mediaOptionId) { + return this._availableMediaOptions.find((mediaOption) => mediaOption.mediaOptionId === mediaOptionId); + } + updateTextTrackState() { + if (!this.mediaSink.textTracks) { + // catch an update later + return; + } + const selectedHTMLTextTrack = this.selectedTrack ? this.getExistingHTMLTextTrack(this.selectedTrack) : undefined; + const textTracks = filterSelectableTextTracks(this.mediaSink.textTracks); + for (let id = 0; id < textTracks.length; id++) { + const aTrack = textTracks[id]; + if (aTrack === selectedHTMLTextTrack && textTracks[id].mode !== 'showing') { + textTracks[id].mode = 'showing'; + this.logger.info(`textTracks[${id}].mode = 'showing'`); + } + else if (aTrack !== selectedHTMLTextTrack && textTracks[id].mode !== 'hidden') { + textTracks[id].mode = 'hidden'; + this.logger.info(`textTracks[${id}].mode = 'hidden'`); + } + } + } + mapHTMLTextTrackIndexToMediaOptionId(searchIndex) { + const searchTextTrack = this.mediaSink.textTracks[searchIndex]; + let foundOptionId; + this.htmlTextTrackMap.forEach((textTrack, optionId) => { + if (searchTextTrack === textTrack) { + foundOptionId = optionId; + } + }); + return foundOptionId; + } + get mediaSelectionOptions() { + return this._availableMediaOptions; + } + _makeDisableOption(mediaOption) { + return { itemId: mediaOption.itemId, mediaOptionType: mediaOption.mediaOptionType, mediaOptionId: 'Nah' }; + } + _onTextTracksChanged() { + // Media is undefined when switching streams via loadSource() + if (!this.mediaSink) { + return; + } + let newTrackEvent = false; + let showingPersistentId; + const textTracks = filterSelectableTextTracks(this.mediaSink.textTracks); + let newTracksSeenAndIgnored = 0; + for (let id = 0; id < textTracks.length; id++) { + if (textTracks[id].seen) { + // Existing text tracks + if (textTracks[id].mode === 'showing') { + showingPersistentId = textTracks[id].persistentId; + } + } + else { + // Newly added text track always has 'hidden' mode by default. + // We must not make any selection change based on "new track" event. + // A real track change event may be in-flight and will be overriden later if we re-select an active subtitle track or 'undefined' now. + textTracks[id].seen = true; + newTracksSeenAndIgnored += 1; + newTrackEvent = true; + } + } + this.logger.info(`New tracks marked seen and ignored: ${newTracksSeenAndIgnored} vs total: ${textTracks.length}`); + if (!newTrackEvent) { + const currentSelectedMediaOption = this.selectedTrack; + if ((currentSelectedMediaOption === null || currentSelectedMediaOption === void 0 ? void 0 : currentSelectedMediaOption.persistentID) !== showingPersistentId) { + const newOption = this.mediaSelectionOptions.find(function (mediaOption) { + return mediaOption.persistentID === showingPersistentId; + }); + this.nativeSubtitleTrackChange$.next(newOption ? newOption : this._disabledMediaOption); + } + } + } + addCues(channel, startTime, endTime, screen) { + // skip cues which overlap more than 50% with previously parsed time ranges + const ranges = this.cueRanges; + let merged = false; + for (let i = ranges.length; i--;) { + const cueRange = ranges[i]; + const overlap = intersection(cueRange[0], cueRange[1], startTime, endTime); + if (overlap >= 0) { + cueRange[0] = Math.min(cueRange[0], startTime); + cueRange[1] = Math.max(cueRange[1], endTime); + merged = true; + if (overlap / (endTime - startTime) > 0.5) { + return; + } + } + } + if (!merged) { + ranges.push([startTime, endTime]); + } + this.Cues.newCue(this.channelToTrackMap[channel], startTime, endTime, screen, this.mediaSink); + } + getExistingHTMLTextTrackWithChannelNumber(channelNumber) { + const mediaSink = this.mediaSink; + if (mediaSink) { + for (let i = 0; i < mediaSink.textTracks.length; i++) { + const textTrack = mediaSink.textTracks[i]; + const propName = 'cc' + channelNumber; + if (isChannelTextTrackKey(propName) && textTrack[propName] === true) { + return textTrack; + } + } + } + return null; + } + sendAddTrackEvent(track, mediaSink) { + let e = null; + try { + e = new window.Event('addtrack'); + } + catch (err) { + // for IE11 + e = document.createEvent('Event'); + e.initEvent('addtrack', false, false); + } + e.track = track; + mediaSink.dispatchEvent(e); + } + createHTMLCaptionsTrackGuts(channelNumber, name, languageCode, forced) { + const trackVar = 'cc' + channelNumber; + if (!this.channelToTrackMap[trackVar]) { + // Enable reuse of existing closed caption text track. + const existingHTMLTrack = this.getExistingHTMLTextTrackWithChannelNumber(channelNumber); + if (!existingHTMLTrack) { + const textTrack = this.createHTMLTextTrackGuts('captions', name, languageCode, forced); + if (textTrack && isChannelTextTrackKey(trackVar)) { + textTrack[trackVar] = true; + this.channelToTrackMap[trackVar] = textTrack; + } + } + else { + this.channelToTrackMap[trackVar] = existingHTMLTrack; + clearCurrentCues(this.channelToTrackMap[trackVar]); + this.sendAddTrackEvent(this.channelToTrackMap[trackVar], this.mediaSink); + } + } + return this.channelToTrackMap[trackVar]; + } + createHTMLCaptionsTrack(channel) { + return this.createHTMLCaptionsTrackGuts(channel, this.config[channel === 1 ? 'captionsTextTrack1Label' : 'captionsTextTrack2Label'], this.config.captionsTextTrack1LanguageCode, false); + } + getExistingHTMLTextTrack(track) { + // this.logger.info(`getExistingHTMLTextTrack condenseSubtitleTrack ${this.config.condenseSubtitleTrack} track.persistentID ${track.persistentID} track.id ${track.id}`); + return this.config.condenseSubtitleTrack ? this.htmlTextTrackMap.get(track.persistentID) : this.htmlTextTrackMap.get(track.id); + } + getExistingHTMLTextTrackWithSubtitleTrackId(id) { + const altOption = this._availableMediaOptions.find((mediaOption) => mediaOption.id === id); + const htmlTextTrack = altOption ? this.getExistingHTMLTextTrack(altOption) : undefined; + this.logger.debug(`[subtitle] map track id ${id} to ${htmlTextTrack === null || htmlTextTrack === void 0 ? void 0 : htmlTextTrack.label} ${htmlTextTrack === null || htmlTextTrack === void 0 ? void 0 : htmlTextTrack.kind} ${htmlTextTrack === null || htmlTextTrack === void 0 ? void 0 : htmlTextTrack.language}`); + return htmlTextTrack; + } + getExistingHTMLTextTrackIndex(track) { + const htmlTextTrack = this.getExistingHTMLTextTrack(track); + const tracks = this.mediaSink.textTracks; + let found = -1; + for (let i = 0; i < tracks.length; ++i) { + if (tracks[i] === htmlTextTrack) { + found = i; + break; + } + } + return found; + } + setExistingHTMLTextTrack(track, textTrack) { + textTrack.persistentId = track.persistentID; + if (this.config.condenseSubtitleTrack) { + // this.logger.info(`setExistingHTMLTextTrack: track.persistentID ${track.persistentID}, textTrack ${textTrack?.id} ${textTrack}`); + return this.htmlTextTrackMap.set(track.persistentID, textTrack); + } + else { + // this.logger.info(`setExistingHTMLTextTrack: track.id ${track.id}, textTrack ${textTrack?.id} ${textTrack}`); + return this.htmlTextTrackMap.set(track.id, textTrack); + } + } + createHTMLTextTrack(track) { + let HTMLTextTrack = this.getExistingHTMLTextTrack(track); + if (!HTMLTextTrack) { + if (track.mediaType === 'sbtl') { + // this.logger.info(`create subtitle track ${track.name} from manifest`); + this.subtitleTracksCreated += 1; + HTMLTextTrack = this.createHTMLTextTrackGuts('subtitles', track.name, track.lang, track.forced); + } + else { + let channelNumber = 1; + if (track.inStreamID) { + channelNumber = Number(track.inStreamID.substring(2)); + } + // this.logger.info(`create caption track ${track.name} from manifest`); + this.captionTracksCreated += 1; + HTMLTextTrack = this.createHTMLCaptionsTrackGuts(channelNumber, track.name, track.lang, false); + } + if (HTMLTextTrack) { + this.setExistingHTMLTextTrack(track, HTMLTextTrack); + /* const data = { + trackId: track.id, + mediaOptionId: track.mediaOptionId, + persistentId: track.persistentID, + kind: HTMLTextTrack.kind, + label: HTMLTextTrack.label, + language: HTMLTextTrack.language, + }; + this.logger.info(`textTrackCreated: ${JSON.stringify(data)}`); + */ + } + else { + this.logger.error(`failed to create HTML text track for track ${track.id}: persistent id ${track.persistentID} name ${track.name} lang ${track.lang} inStreamID ${track.inStreamID}`); + this.tracksFailed += 1; + } + } + else { + // this.logger.info(`reuse HTML text track for track ${track.id}: persistent id ${HTMLTextTrack.persistentId} kind ${HTMLTextTrack.kind} label ${HTMLTextTrack.label} lang ${HTMLTextTrack.language}`); + this.tracksReused += 1; + } + return HTMLTextTrack; + } + createHTMLTextTrackGuts(kind, label, lang, forced) { + const mediaSink = this.mediaSink; + if (mediaSink) { + let customTextTrackCueRenderer = false; + if (kind !== 'metadata' && this.config.customTextTrackCueRenderer) { + customTextTrackCueRenderer = true; + kind = 'metadata'; + } + const textTrack = mediaSink.addTextTrack(kind, label, lang); + if (customTextTrackCueRenderer) { + textTrack.customTextTrackCueRenderer = true; + } + return textTrack; + } + return undefined; + } + resetLoadSource() { + this.resetTracks(); + } + resetTracks() { + this.logger.info('clean out all cues and cueRanges'); + this._cleanTracks(); + this.cueRanges = []; + } + _cleanTracks() { + // clear outdated subtitles + const mediaSink = this.mediaSink; + if (mediaSink) { + const textTracks = mediaSink.textTracks; + if (textTracks) { + for (let i = 0; i < textTracks.length; i++) { + clearCurrentCues(textTracks[i]); + } + } + } + } + getCuesOfEnabledTrack(trackId, checkForWebVTTCue = false) { + let cues = []; + if (!checkForWebVTTCue) { + this.logger.info(`[subtitle] return regular cue list for track ${trackId}`); + cues = this._getCuesOfEnabledTrack(trackId); + } + else { + const sideTrackCues = this._getCuesOfEnabledTrack(trackId); + for (let i = 0; i < sideTrackCues.length; i++) { + const targetCue = sideTrackCues[i]; + if (isExtendedTextTrackCue(targetCue)) { + // this.logger.info(`[subtitle] consider WebVTT cue: ${targetCue.startTime} ${targetCue.endTime} '${targetCue.text}'`); + cues.push(targetCue); + } + } + } + return cues; + } + _getCuesOfEnabledTrack(trackId) { + const track = this.getTrack(trackId); + const htmlTrackKey = this.config.condenseSubtitleTrack ? track === null || track === void 0 ? void 0 : track.persistentID : track === null || track === void 0 ? void 0 : track.id; + const enabledHTMLTrack = this.htmlTextTrackMap.get(htmlTrackKey); + if (enabledHTMLTrack && enabledHTMLTrack.cues) { + return Array.from(enabledHTMLTrack.cues); + } + else { + return []; + } + } + attachSubtitleTracks() { + // We need both onSubtitleTrackUpdated and onMediaAttaching to resolve before attaching subtitle tracks + if (!this.gotTracks) { + return; + } + this.subtitleTracksCreated = 0; + this.captionTracksCreated = 0; + this.tracksReused = 0; + this.tracksFailed = 0; + this.tracks.forEach((track) => { + this.createHTMLTextTrack(track); + }); + const data = { + totalTracks: this.tracks.length, + subtitleTracksCreated: this.subtitleTracksCreated, + captionTracksCreated: this.captionTracksCreated, + tracksReused: this.tracksReused, + tracksFailed: this.tracksFailed, + }; + this.logger.qe({ critical: true, name: 'textTrackCreated', data }); + } + setTracks(mediaOptions, enabledMediaOption, disabledMediaOption) { + this._cleanTracks(); + this.htmlTextTrackMap = new Map(); + this.cueRanges = []; + if (this.config.enableWebVTT) { + this.tracks = mediaOptions || []; + } + this.gotTracks = true; + this._availableMediaOptions = mediaOptions; + this._disabledMediaOption = disabledMediaOption; + this.attachSubtitleTracks(); + this.selectedTrack = enabledMediaOption; + this.nativeSubtitleTrackChange$ = new Subject(); + this.mediaSink.textTracksCreated = true; + } + // Need this to suppress errors when no client is listening for these styles + onInlineStylesParsed(data) { } + processSubtitleFrag(enabledMediaOption, frag, initPTS, payload) { + const data = new Uint8Array(payload); + const trackIndex = this.getExistingHTMLTextTrackIndex(enabledMediaOption); + // Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character. + /* + let re = /\r\n|\n\r|\n|\r/g; + let vtt = BufferUtils.utf8arrayToStr(data).trim().replace(re, '\n').split('\n'); + vtt.forEach((line) => { + this.logger.info(`vtt.subtitle: ${line}`); + }); + */ + if (frag && payload.byteLength) { + const fragCueRange = this._parseVTTs(trackIndex, frag, initPTS, data); + if (fragCueRange && isFiniteNumber(fragCueRange.startTime)) { + // startTime is valid only if there are cues (duplicated or otherwise) in the fragment + this.lastCueEndTime = Math.max(this.lastCueEndTime, fragCueRange.endTime); + this.logger.debug(`[subtitle] update lastCueEndTime ${this.lastCueEndTime}`); + } + return fragCueRange; + } + return; + } + _parseVTTs(textTrackIdx, frag, initPTS, payload) { + // Parse the WebVTT file contents. + let parsedfragCueRecord; + HLSVTTParser$1.parse(payload, initPTS, frag.start, frag.discoSeqNum, (cues) => { + // Sometimes there are cue overlaps on segmented vtts so the same + // cue can appear more than once in different vtt files. + // This avoid showing duplicated cues with same timecode and text. + const textTrack = this.mediaSink.textTracks[textTrackIdx]; + // Add cues and trigger event with success true. + const fragCueRecord = { count: 0, startTime: Number.POSITIVE_INFINITY, endTime: 0 }; + cues.map((cue) => { + if (textTrack && (!textTrack.cues || !textTrack.cues.getCueById(cue.id))) { + this.logger.trace(`new cue for subtitle track[${frag.mediaOptionId}] frag sn ${frag.mediaSeqNum}: #${cue.id} [${cue.startTime}, ${cue.endTime}]: ${cue.text}`); + cue.fragSN = frag.mediaSeqNum; + cue.webVTTCue = true; + textTrack.addCue(cue); + fragCueRecord.count++; + this.logger.debug(`[subtitle] cue added. fragCueRecord ${JSON.stringify(fragCueRecord)}`); + } + fragCueRecord.startTime = Math.min(cue.startTime, fragCueRecord.startTime); + fragCueRecord.endTime = Math.max(cue.endTime, fragCueRecord.endTime); + this.logger.debug(`[subtitle] frag processed. fragCueRecord ${JSON.stringify(fragCueRecord)}`); + }); + this.logger.debug(`[subtitle] frag processing done. fragCueRecord ${JSON.stringify(fragCueRecord)}`); + // fragCueRecord: + // * startTime is a finite number only if there is at least 1 cue in the fragment + // * count may be zero if duplicated cue (finite startTime) or no cue (PostiveInfinity startTime) + parsedfragCueRecord = fragCueRecord; + this.mediaSink.archiveParsedSubtitleFragmentRecord(this.selectedTrack.persistentID, frag.mediaSeqNum, fragCueRecord); + }, (e) => { + // Something went wrong while parsing. Trigger event with success false. + this.logger.info(`Failed to parse VTT cue: ${e}`); + }, (styles) => { + this.hls.trigger(HlsEvent$1.INLINE_STYLES_PARSED, { styles: styles }); + }, this.logger); + return parsedfragCueRecord; + } + _ensureParser() { + if (!this.cea608Parser) { + const channel1 = new OutputFilter(this, 1); + const channel2 = new OutputFilter(this, 2); + this.cea608Parser = new Cea608Parser$1(0, channel1, channel2); + } + } + setupForFrag(frag) { + if (!frag || frag.mediaOptionType !== MediaOptionType.Variant || frag.iframe) { + return; + } + const sn = frag.mediaSeqNum; + // if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack + if (sn !== this.lastVariantSeqNum + 1) { + this.resetClosedCaptionParser(); + } + this.lastVariantSeqNum = sn; + } + resetClosedCaptionParser() { + var _a; + this.logger.info('reset cea608Parser'); + (_a = this.cea608Parser) === null || _a === void 0 ? void 0 : _a.reset(); + } + /** + * Add CLCP / ID3 samples + * @param offsetTimestamp offsetTimestamp is offset used for SourceBuffer timestampOffset calculation. All samples should be shifted by this value + * @param captionData Parsed caption data from demuxer + * @param id3Samples Parsed id3 samples from demuxer + * @param endPTS end Presentation Timestamp of the fragment + */ + addLegibleSamples(offsetTimestamp, captionData, id3Samples, endPTS) { + if (captionData) { + this.addClosedCaptionSamples(offsetTimestamp, captionData); + } + if (id3Samples && id3Samples.length > 0) { + this.addId3Samples(offsetTimestamp, id3Samples, convertTimestampToSeconds(endPTS)); + } + } + addClosedCaptionSamples(offsetTimestamp, captionData) { + if (captionData.mp4) { + this.addMP4CaptionSamples(offsetTimestamp, captionData.mp4); + } + else if (captionData.ts) { + this.addTSCaptionSamples(offsetTimestamp, captionData.ts); + } + } + addMP4CaptionSamples(offsetTimestamp, samples) { + // push all of the CEA-608 messages into the interpreter + // immediately. It will create the proper timestamps based on our PTS value + if (this.enableCaption && this.config.enableCEA708Captions) { + const offsetTimestampSec = convertTimestampToSeconds(offsetTimestamp); + this._ensureParser(); + for (let i = 0; i < samples.length; i++) { + let startSec = samples[i].pts - offsetTimestampSec; + const ccData = samples[i].bytes; + for (let j = 0; j < ccData.length; j += 2) { + const doubleByte = []; + doubleByte.push(ccData[j]); + if (j + 1 < ccData.length) { + doubleByte.push(ccData[j + 1]); + } + else { + this.logger.info(`CEA608 sample ${i} not even length (index ${j + 1} >= length ${ccData.length})`); + doubleByte.push(80); // safest character to push is 80 (noop) + } + this.cea608Parser.addData(startSec, doubleByte); + startSec += cea608Duration; + } + } + } + } + addTSCaptionSamples(offsetTimestamp, samples) { + if (this.enableCaption && this.config.enableCEA708Captions) { + const offsetTimestampSec = convertTimestampToSeconds(offsetTimestamp); + this._ensureParser(); + for (let i = 0; i < samples.length; i++) { + const startSec = samples[i].pts - offsetTimestampSec; + const ccdatas = LegibleSystemAdapter.extractCea608Data(samples[i].bytes); + this.cea608Parser.addData(startSec, ccdatas); + } + } + } + addId3Samples(offsetTimestamp, samples, endPTSSec) { + if (!this.config.enableID3Cues) { + this.logger.info('id3 cues disabled by config'); + return; + } + // Attempt to recreate Safari functionality by creating + // WebKitDataCue objects when available and store the decoded + // ID3 data in the value property of the cue + const Cue = window.WebKitDataCue || window.VTTCue || window.TextTrackCue; + const offsetTimestampSec = convertTimestampToSeconds(offsetTimestamp); + for (let i = 0; i < samples.length; i++) { + const startSec = samples[i].pts - offsetTimestampSec; + let endSec = (i < samples.length - 1 ? samples[i + 1].pts : endPTSSec) - offsetTimestampSec; + // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE + if (startSec === endSec) { + endSec += 0.0001; + } + if (samples[i].frames) { + samples[i].frames.forEach((frame) => { + if (frame && !this.id3shouldIgnore(frame)) { + const cue = new Cue(startSec, endSec, ''); + cue.value = frame; + this.logger.trace(`[id3] addCue [${startSec},${endSec}] ${JSON.stringify(cue.value).substr(0, 20)}...`); + this.id3Track.addCue(cue); + } + }); + } + } + } + id3shouldIgnore(frame) { + return frame.key === 'PRIV' && (frame.info === 'com.apple.streaming.transportStreamTimestamp' || frame.info === 'com.apple.streaming.audioDescription'); + } + static extractCea608Data(byteArray) { + const count = byteArray[0] & 31; + let position = 2; + let tmpByte, ccbyte1, ccbyte2, ccValid, ccType; + const actualCCBytes = []; + for (let j = 0; j < count; j++) { + tmpByte = byteArray[position++]; + ccbyte1 = 127 & byteArray[position++]; + ccbyte2 = 127 & byteArray[position++]; + ccValid = (4 & tmpByte) !== 0; + ccType = 3 & tmpByte; + if (ccbyte1 === 0 && ccbyte2 === 0) { + continue; + } + if (ccValid) { + if (ccType === 0) { + // || ccType === 1 + actualCCBytes.push(ccbyte1); + actualCCBytes.push(ccbyte2); + } + } + } + return actualCCBytes; + } + } + + const makeLegibleService = (source$, config, eventEmitter, logger) => { + return source$.pipe(tag('playback.legibleServiceEpic.in'), switchMap((mediaSink) => { + if (!mediaSink) { + return of(null); + } + const textTrackAdapter = new LegibleSystemAdapter(mediaSink, config, eventEmitter, logger); + return merge(of(textTrackAdapter), textTrackAdapter); + }), tag('playback.legibleServiceEpic.emit')); + }; + + const SessionDataStatusCode = { + // Typucally (positive) HTTP Status code for network errors. + // Plus these ... + JSON_PARSE_ERROR: -1, + }; + + const loggerName$6 = { name: 'plist' }; + function stringIsXMLPlist(data) { + const XML_TAG_REGEX = /[\s]*<\?xml/i; + const PLIST_TAG_REGEX = /[\s]* ${cTagName}`); + } + } + else { + value = convertPlistToJSON(child); + jsonObj[key] = value; + key = null; + value = null; + validIndex++; + } + } + } + if (key) { + // Last value may be missing. Treat it as NULL. + jsonObj[key] = value; + logger.info(loggerName$6, `Orphaned pair: ${key} = ${JSON.stringify(value)}`); + key = null; + value = null; + } + } + else if (tagName === 'key') { + // Leaf dict elements are wrapped in the sole child of TextNode. Reach down 1 level to get the value. + const firstChild = childNodes[0]; + if (firstChild) { + jsonObj = firstChild.nodeValue; + } + else { + // Should not happen + logger.warn(loggerName$6, 'Invalid dict key: Key is null, probably like this: '); + jsonObj = null; + } + } + else if (tagName === 'string') { + const firstChild = childNodes[0]; + if (firstChild) { + jsonObj = firstChild.nodeValue; + } + else { + jsonObj = null; + } + } + else if (tagName === 'integer') { + const firstChild = childNodes[0]; + if (firstChild) { + jsonObj = parseInt(firstChild.nodeValue); + } + else { + jsonObj = 0; + } + } + else if (tagName === 'float') { + const firstChild = childNodes[0]; + if (firstChild) { + jsonObj = parseFloat(firstChild.nodeValue); + } + else { + jsonObj = 0; + } + } + else if (tagName === 'date') { + const firstChild = childNodes[0]; + if (firstChild) { + jsonObj = new Date(firstChild.nodeValue); + } + else { + jsonObj = null; + } + } + else if (tagName === 'data') { + const firstChild = childNodes[0]; + if (firstChild) { + // base64 encoded + jsonObj = atob(firstChild.nodeValue); + } + else { + jsonObj = null; + } + } + else if (tagName === 'true') { + jsonObj = true; + } + else if (tagName === 'false') { + jsonObj = false; + } + } + else { + // Node without tagName may exist in the XML DOM tree. + // See if its child/children are valid plist elements. + if (childNodes.length < 1) { + // This should never happen + logger.warn(loggerName$6, `unknown node with unknown value > nodeType=${domNode.nodeType} tagName=${domNode.tagName} nodeName=${domNode.nodeName} value=${domNode.nodeValue}`); + } + else { + jsonObj = []; + for (let i = 0; i < childNodes.length; ++i) { + const child = childNodes[i]; + if (child.tagName) { + jsonObj.push(convertPlistToJSON(child)); + } + } + if (jsonObj.length === 1) { + // If unknown node has only 1 child, replace it with its child's value. + // Essentially drop the unknown node. + jsonObj = jsonObj[0]; + } + } + } + } + return jsonObj; + } + + class SessionDataLoader { + constructor(config, xhrLoader, customUrlLoader, logger) { + this.config = config; + this.xhrLoader = xhrLoader; + this.customUrlLoader = customUrlLoader; + this.sessionDataCheckForCompleteness = (sessionData) => { + const { sessionDataAutoLoad } = this.config; + const result = Object.assign({}, sessionData); + if (!sessionData.complete) { + if (sessionData.itemList) { + // Playlist wihout SESSION-DATA tag has an empty itemList array + result.complete = sessionData.itemList.every((metadata) => { + if (sessionDataAutoLoad[metadata['DATA-ID']] && !metadata.VALUE && !metadata._STATUS && metadata.URI) { + this.logger.warn(`Incomplete because ${metadata['DATA-ID']} was autoloaded but no response yet`); + return false; + } + if (sessionDataAutoLoad[metadata['DATA-ID']] && !metadata.URI) { + this.logger.warn(`id=${metadata['DATA-ID']} missing uri`); + } + return true; + }); + } + else { + this.logger.warn('Uninitialized SessionData'); + } + } + return result; + }; + this.logger = logger.child({ name: 'SessionDataLoader' }); + } + loadSessionData(sessionData) { + const { sessionDataAutoLoad } = this.config; + const itemList = sessionData.itemList || []; + let loadItems$ = of(sessionData); + itemList.forEach((item) => { + const id = item['DATA-ID']; + const uri = item.URI; + //this.logger.info(`SessionData autoload ${id}: ${JSON.stringify(sessionDataAutoLoad[id])}`); + if (uri && sessionDataAutoLoad[id]) { + const url = URLToolkit$1.buildAbsoluteURL(sessionData.baseUrl, uri, { alwaysNormalize: true }); + const responseType = ''; // Use default responseType to allow XML parsing where necessary + loadItems$ = loadItems$.pipe(switchMap((sd) => { + return this.loadSessionDataItemWithUrl(url, id, responseType, this.config, sd, this.xhrLoader, this.customUrlLoader).pipe(catchError((err) => { + this.logger.error(`Error loading SessionData > url=${url}, id=${id}, err=${err}`); + return of(sd); + })); + })); + } + }); + return loadItems$.pipe(map((sd) => { + if (itemList.length < 1) { + return sd; + } + const updated = this.sessionDataCheckForCompleteness(sd); + if (updated.complete) { + return updated; + } + else { + throw new ExceptionError(false, 'Session data not complete after loading all items', ErrorResponses.IncompleteSessionData); + } + }), finalize$1(() => { + this.logger.info('finalized'); + })); + } + // Loading session data + // url : session data attribute URL, id : sessionData attribute data-id, responseType: "text", "arraybuffer", or other XMLHTTPRequest responseType + loadSessionDataItemWithUrl(url, id, responseType, config, sessionData, xhrLoader, customUrlLoader) { + const logger = getLogger(); + const context = { + url, + method: 'GET', + responseType, + xhrSetup: config.xhrSetup, + mimeType: 'application/xml', + }; + const loadConfig = getLoadConfig({ url }, config.fragLoadPolicy); + let loader; + if (isCustomUrl(url)) { + loader = customUrlLoader(context, loadConfig).pipe(map((res) => { + return this.onLoadSuccess(sessionData, id, res.data.response.data.toString(), res.data.response.data); + })); + } + else { + loader = xhrLoader(context, loadConfig).pipe(map(([xhr]) => { + return this.onLoadSuccess(sessionData, id, xhr.response, xhr.responseXML); + })); + } + return loader.pipe(catchError((err) => { + if (err instanceof TimeoutError) { + err = new SessionDataNetworkError(false, err.message, 0, ErrorResponses.SessionDataLoadTimeout); + } + else if (err instanceof GenericNetworkError) { + err = new SessionDataNetworkError(false, err.message, err.code, { code: err.code, text: 'Failed to load SessionData' }); + } + logger.error(`Unable to load SessionData > err=${err}`); + return of(this.onLoadError(sessionData, id, err)); + })); + } + onLoadSuccess(sessionData, id, response, responseXML) { + let plistDOM = null; + let result = sessionData; + if (stringIsXMLPlist(response) && (plistDOM = responseXML)) { + // Looks like XML. Use built-in XMLHttpRequest XML parser. + const attrValue = convertPlistToJSON(plistDOM); + result = this.setSessionData(sessionData, id, 'VALUE', attrValue); + } + else if (stringIsJSONPlist(response)) { + // JSON format + try { + const attrValue = JSON.parse(response); + result = this.setSessionData(sessionData, id, 'VALUE', attrValue); + } + catch (err) { + this.logger.error(`JSON parser error: ${err}`); + result = this.setSessionData(sessionData, id, 'VALUE', response); + result = this.setSessionData(result, id, '_STATUS', SessionDataStatusCode.JSON_PARSE_ERROR); + } + } + else { + this.logger.info(`Unknown ${id} format. Using raw value`); + result = this.setSessionData(sessionData, id, 'VALUE', response); + } + return result; + } + setSessionData(sessionData, id, attrName, obj) { + let result = sessionData; + if (sessionData.itemList) { + let i; + const itemList = [...sessionData.itemList]; + for (i = 0; i < sessionData.itemList.length; ++i) { + const metadata = Object.assign({}, itemList[i]); + if (metadata['DATA-ID'] === id) { + metadata[attrName] = obj; + itemList[i] = metadata; + break; + } + } + if (i === sessionData.itemList.length) { + this.logger.error(`Can't set ${attrName} of session data ${id}`); + } + result = Object.assign(Object.assign({}, sessionData), { itemList }); + } + else { + this.logger.error(`Can't set ${attrName} on uninitialized session data`); + } + return result; + } + onLoadError(sessionData, id, err) { + var _a; + return this.setSessionData(sessionData, id, '_STATUS', (_a = err.response) === null || _a === void 0 ? void 0 : _a.code); + } + } + + function cacheEntityToInfoEntity(initSegmentEntity) { + const { itemId, mediaOptionId, discoSeqNum, keyTagInfo } = initSegmentEntity; + const initSegmentInfo = { itemId, mediaOptionId, discoSeqNum, keyId: Hex.hexDump(keyTagInfo === null || keyTagInfo === void 0 ? void 0 : keyTagInfo.keyId) }; + return initSegmentInfo; + } + class MediaElementStore extends EntityStore { + constructor() { + super({}, { name: 'media-element-store', producerFn: produce_1 }); + this._activeId = ''; + } + get activeId() { + return this._activeId; + } + startMediaSession(meState, maxBufferSeconds, almostDryWaterLevelSeconds, targetDurationSeconds) { + logAction('playback.session.start'); + this._activeId = `media session: ${new Date().toISOString()}`; + applyTransaction(() => { + const lowWaterLevelSeconds = targetDurationSeconds; + const highWaterLevelSeconds = Math.max(lowWaterLevelSeconds, maxBufferSeconds - lowWaterLevelSeconds); + const mediaElementEntity = { + id: this.activeId, + desiredRate: !meState.autoplay && meState.paused ? 0 : 1, + paused: meState.paused, + gotPlaying: false, + gotLoadStart: false, + firstPlayTime: undefined, + seeking: meState.seeking, + flushing: false, + readyState: meState.readyState, + ended: meState.ended, + bufferedRanges: [], + haveEnough: false, + mediaSourceEntity: null, + expectedSbCount: NaN, + bufferMonitorInfo: { + waterLevelType: null, + almostDryWaterLevelSeconds, + lowWaterLevelSeconds, + highWaterLevelSeconds, + maxBufferSeconds, + }, + mediaOptionParsedSubtitleRecord: [], + textTracksCreated: false, + waitingForDisco: false, + }; + this.add(mediaElementEntity); + this.setActive(this.activeId); + }); + this.logger = getLogger().child({ name: 'UpdateBufferedSegments' }); + return this.activeId; + } + setMediaSourceEntity(objectUrl, readyState) { + logAction('playback.set.msObjectUrl'); + this.updateActive((mediaElementEntity) => { + if (objectUrl != null && readyState != null) { + mediaElementEntity.mediaSourceEntity = { objectUrl, readyState, duration: NaN, sourceBufferEntities: [null, null] }; + } + else { + mediaElementEntity.mediaSourceEntity = null; + } + mediaElementEntity.bufferedRanges = []; + mediaElementEntity.haveEnough = false; + mediaElementEntity.readyState = 0; + mediaElementEntity.bufferMonitorInfo.waterLevelType = null; + }); + } + set mediaElementDuration(duration) { + logAction('playback.set.mediaElementDuration'); + this.updateActive((mediaElementEntity) => { + if (mediaElementEntity) { + mediaElementEntity.mediaElementDuration = duration; + } + }); + } + set msReadyState(readyState) { + logAction('playback.set.msReadyState'); + this.updateActive(({ mediaSourceEntity }) => { + if (mediaSourceEntity) { + mediaSourceEntity.readyState = readyState; + } + }); + } + set readyState(readyState) { + logAction(`playback.set.readyState ${readyState}`); + this.updateActive((active) => { + active.readyState = readyState; + }); + } + set ended(ended) { + logAction(`playback.set.ended ${ended}`); + this.updateActive((active) => { + active.ended = ended; + }); + } + set msDuration(duration) { + logAction('playback.set.msDuration'); + this.updateActive((mediaElementEntity) => { + mediaElementEntity.mediaSourceEntity.duration = duration; + }); + } + set textTracksCreated(created) { + logAction('playback.set.textTracksCreated ${created}'); + this.updateActive((mediaElementEntity) => { + mediaElementEntity.textTracksCreated = created; + }); + } + set expectedSbCount(expectedSbCount) { + logAction('playback.set.expectedSbCount'); + this.updateActive((active) => { + active.expectedSbCount = expectedSbCount; + }); + } + set postFlushSeek(postFlushSeek) { + this.updateActive({ postFlushSeek }); + } + setSeekToPos(seekToPos, fromEvent, discoSeqNum) { + logAction(`playback.set.seekToPos: ${seekToPos === null || seekToPos === void 0 ? void 0 : seekToPos.toFixed(3)} cc: ${discoSeqNum}`); + this.updateActive((entity) => { + if (isFiniteNumber(seekToPos)) { + entity.seekTo = { pos: seekToPos, fromEvent, discoSeqNum }; + entity.gotPlaying = false; + entity.haveEnough = false; + } + else { + entity.seekTo = null; + entity.postFlushSeek = undefined; + } + if (fromEvent) { + entity.seeking = isFiniteNumber(seekToPos); + } + }); + } + set seeking(seeking) { + logAction(`playback.set.seeking: ${seeking}`); + this.updateActive((entity) => { + entity.seeking = seeking; + }); + } + set paused(paused) { + logAction(`playback.set.paused: ${paused}`); + this.updateActive((entity) => { + entity.paused = paused; + if (paused) { + entity.gotPlaying = false; + } + }); + } + // Got playing event + gotPlayingEvent() { + logAction('playback.set.playing'); + this.updateActive((entity) => { + if (!entity.paused) { + entity.gotPlaying = true; + entity.firstPlayTime = entity.firstPlayTime || performance.now(); + } + }); + } + gotLoadStartEvent() { + logAction('playback.set.loadstart'); + this.updateActive((entity) => { + entity.gotLoadStart = true; + }); + } + set desiredRate(desiredRate) { + logAction(`playback.set.desiredRate: ${desiredRate}`); + this.updateActive((active) => { + active.desiredRate = desiredRate; + }); + } + set haveEnough(haveEnough) { + logAction(`playback.set.haveEnough: ${haveEnough}`); + this.updateActive((active) => { + active.haveEnough = haveEnough; + }); + } + set flushing(flushing) { + logAction(`playback.set.flushing: ${flushing}`); + this.updateActive({ flushing }); + } + set waitingForDisco(waitingForDisco) { + logAction(`playback.set.waitingForDisco: ${waitingForDisco}`); + this.updateActive((entity) => { + if (entity) { + entity.waitingForDisco = waitingForDisco; + } + }); + } + setSourceBufferUpdating(type) { + logAction(`playback.set.sourcebuffers[${SourceBufferNames[type]}].updating`); + this.updateActive(({ mediaSourceEntity }) => { + var _a; + const sbEntity = (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[type]; + if (sbEntity) { + sbEntity.updating = true; + sbEntity.error = undefined; + } + }); + } + setTimestampOffset(type, timestampOffset) { + logAction(`playback.set.sourcebuffers[${SourceBufferNames[type]}].timestampOffset`); + this.updateActive(({ mediaSourceEntity }) => { + var _a; + const sbEntity = (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[type]; + if (sbEntity) { + sbEntity.timestampOffset = timestampOffset; + } + }); + } + setBufferedRangesUpdated(type, bufferedRanges, combinedBuffer, gotQuotaExceeded, config) { + logAction(`playback.set.sourcebuffers[${SourceBufferNames[type]}].bufferupdated`); + this.updateActive((mediaElementEntity) => { + var _a; + const mediaSourceEntity = mediaElementEntity === null || mediaElementEntity === void 0 ? void 0 : mediaElementEntity.mediaSourceEntity; + const sbEntity = (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[type]; + if (sbEntity) { + const msDuration = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.duration; + sbEntity.updating = false; + sbEntity.bufferedRanges = [...bufferedRanges]; + mergeInflightSegment(sbEntity); + // updateBufferedSegments even if bufferedRanges is empty + updateBufferedSegments(sbEntity, gotQuotaExceeded, msDuration, config, this.logger); + } + mediaElementEntity.bufferedRanges = [...combinedBuffer]; + }); + } + setSourceBufferEntity(type, compatInfo) { + logAction(`playback.set.sourcebuffers[${SourceBufferNames[type]}].setSourceBufferEntity`); + this.updateActive(({ mediaSourceEntity }) => { + if (!mediaSourceEntity) + return; + const { mimeType, audioCodec, videoCodec } = compatInfo; + const sbEntity = { + mimeType, + audioCodec, + videoCodec, + updating: false, + bufferedRanges: [], + timestampOffset: 0, + // Calculated + inFlight: null, + bufferedSegments: [], + totalBytes: 0, + maxTotalBytes: 0, + gotQuotaExceeded: false, + totalDuration: Infinity, + }; + mediaSourceEntity.sourceBufferEntities[type] = sbEntity; + }); + } + setInflightSegment(type, segment) { + logAction(`playback.set.sourcebuffers[${SourceBufferNames[type]}].setInflightSegment`); + this.updateActive(({ mediaSourceEntity }) => { + var _a; + const sbEntity = (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[type]; + if (sbEntity) { + sbEntity.inFlight = segment; + } + }); + } + setInitSegmentEntity(type, initSegmentEntity) { + logAction(`playback.set.sourcebuffers[${SourceBufferNames[type]}].setInitSegmentEntity`); + this.updateActive(({ mediaSourceEntity }) => { + var _a; + const sbEntity = (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[type]; + if (sbEntity) { + sbEntity.initSegmentInfo = initSegmentEntity; + } + }); + } + setSourceBufferError(type, error) { + logAction(`playback.set.sourcebuffers[${type}].error: ${error}`); + this.updateActive(({ mediaSourceEntity }) => { + var _a; + const sbEntity = (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[type]; + if (sbEntity) { + sbEntity.inFlight = null; + sbEntity.updating = false; + sbEntity.error = error; + } + }); + } + setStallInfo(stallInfo) { + logAction(`playback.set.stallInfo stalled=${stallInfo != null}`); + this.updateActive((active) => { + active.stallInfo = stallInfo; + }); + } + setNudgeInfo(nudgeInfo) { + logAction(`playback.set.nudgeInfo ${stringifyWithPrecision(nudgeInfo)}`); + this.updateActive((active) => { + active.nudgeInfo = nudgeInfo; + }); + } + /** + * Update water level information + * @param combined Water level of combined buffer + * @param sbTuple Water level of each source buffer + */ + updateWaterLevels(combined, sbTuple) { + logAction('playback.set.updateWaterLevels'); + this.updateActive((entity) => { + entity.bufferMonitorInfo.waterLevelType = { combined, sbTuple: [...sbTuple] }; + }); + } + /** + * @param targetDurationSeconds The duration in seconds to use for determining low and high water. + * Low water threshold is 1 target duration, high water threshold is Math.max(lowWater, maxBuffer - targetDuration) + */ + set bufferMonitorTargetDuration(targetDurationSeconds) { + logAction(`playback.set.targetDuration: ${targetDurationSeconds}`); + this.updateActive((entity) => { + if (isFiniteNumber(targetDurationSeconds) && targetDurationSeconds > 0) { + const bufMonitorInfo = entity.bufferMonitorInfo; + bufMonitorInfo.lowWaterLevelSeconds = Math.min(targetDurationSeconds, bufMonitorInfo.maxBufferSeconds); + bufMonitorInfo.highWaterLevelSeconds = Math.max(bufMonitorInfo.lowWaterLevelSeconds, bufMonitorInfo.maxBufferSeconds - targetDurationSeconds); + } + }); + } + archiveParsedSubtitleFragmentRecord(persistentId, mediaSeqNum, fragCueRecord) { + logAction(`playback.cues.set persistentId ${persistentId} mediaSeqNum ${mediaSeqNum}: parsed ${fragCueRecord.count} time-range ${fragCueRecord.startTime}:${fragCueRecord.endTime}`); + this.updateActive((entity) => { + let trackInfo = entity.mediaOptionParsedSubtitleRecord[persistentId]; + if (!trackInfo) { + trackInfo = {}; + entity.mediaOptionParsedSubtitleRecord[persistentId] = trackInfo; + } + trackInfo[mediaSeqNum] = fragCueRecord; + }); + } + } + function mergeInflightSegment(sbEntity) { + const inFlight = sbEntity.inFlight; + const mergedBufferSeg = sbEntity.bufferedSegments; + if (inFlight && isFiniteNumber(inFlight.startPTS) && isFiniteNumber(inFlight.endPTS)) { + mergeToBuffer(mergedBufferSeg, inFlight); + } + sbEntity.inFlight = null; + } + // Helper functions for updating buffered segments, modifies sbEntity.bufferedSegments in-place + function updateBufferedSegments(sbEntity, gotQuotaExceeded, msDuration, config, logger) { + const { maxBufferHole, bufferedSegmentEjectionToleranceMs } = config; + // Modify in-place since we do not read anyway + const mergedBufferSeg = sbEntity.bufferedSegments; + const realBuffered = sbEntity.bufferedRanges; + let totalBytes = 0; + let lastFragEjected = false; + let lastFrag; + if (realBuffered.length) { + for (let i = mergedBufferSeg.length - 1; i > -1; i--) { + const segment = mergedBufferSeg[i]; + const notIframe = !segment.frag.iframe; + if (notIframe && segment.frag.isLastFragment) { + lastFrag = segment.frag; + } + const segmentDuration = segment.endPTS - segment.startPTS; + if (segmentDuration <= 0) { + mergedBufferSeg.splice(i, 1); + logger === null || logger === void 0 ? void 0 : logger.warn(`Ejecting segment from bufferedSegments due to segmentDuration <= 0 > segment=${stringifyWithPrecision(segment)}`); + lastFragEjected = segment.frag === lastFrag; + continue; // Should never happen but... + } + const overlapping = getMaxOverlappingRange(realBuffered, segment); + // startPTS/endPTS is sometimes a bit off from what is reported in buffered, + // especially for audio. Add the byteLength approximation with overlap factor. + if (overlapping) { + // Estimate total bytes using all buffered time ranges + const overlapStart = Math.max(overlapping.start, segment.startPTS); + const overlapEnd = Math.min(overlapping.end, segment.endPTS); + const appendedDuration = overlapEnd - overlapStart; + totalBytes += (segment.bytes * appendedDuration) / segmentDuration; + if (notIframe) { + // ignore tiny overlaps + if (appendedDuration < Math.min(segmentDuration, maxBufferHole)) { + mergedBufferSeg.splice(i, 1); + logger === null || logger === void 0 ? void 0 : logger.warn(`Ejecting segment from bufferedSegments due to tiny overlaps > segment=${stringifyWithPrecision(segment)}, bufferedRanges=${stringifyWithPrecision(realBuffered)}`); + lastFragEjected = segment.frag === lastFrag; + continue; + } + // Keep track of initial appended overlap, and remove the segment if the current overlap has changed + // except when the segment duration was modified because of an overlapping append in mergeToBuffer + const initialAppendedValue = segment.appendedDuration; + const appendedDurationDelta = (initialAppendedValue || 0) - appendedDuration; + // rdar://84943043 tolerance is used to avoid floating point arithmetic issues + const tolerance = Math.min(bufferedSegmentEjectionToleranceMs * 0.001, segmentDuration); + if (!initialAppendedValue) { + segment.appendedDuration = appendedDuration; + } + else if (appendedDurationDelta > tolerance && appendedDuration !== segmentDuration) { + // Eject, unless last segment and buffer end equals known mediaSink duration + if (!segment.frag.isLastFragment || overlapEnd !== msDuration) { + mergedBufferSeg.splice(i, 1); + logger === null || logger === void 0 ? void 0 : logger.warn(`Ejecting segment from bufferedSegments due to change in current overlap > segment=${stringifyWithPrecision(segment)}, delta=${appendedDurationDelta}, bufferedRanges=${stringifyWithPrecision(realBuffered)}`); + lastFragEjected = segment.frag === lastFrag; + continue; + } + } + } + } + else { + logger === null || logger === void 0 ? void 0 : logger.warn(`Ejecting segment from bufferedSegments due to no overlap > segment=${stringifyWithPrecision(segment)}, bufferedRanges=${stringifyWithPrecision(realBuffered)}`); + mergedBufferSeg.splice(i, 1); + lastFragEjected = segment.frag === lastFrag; + } + } + } + else if (mergedBufferSeg.length) { + logger === null || logger === void 0 ? void 0 : logger.info('Flushing buffered segments in response to flush'); + mergedBufferSeg.splice(0, mergedBufferSeg.length); // flushed out + } + // if last frag was ejected this round, realBuffered[realBuffered.length - 1].end will not have the right totalduration. + // if everything was flushed out, totalduration will remain unchanged (lastFrag will be false) + sbEntity.totalDuration = lastFrag && !lastFragEjected && realBuffered.length > 0 ? realBuffered[realBuffered.length - 1].end : Infinity; + sbEntity.gotQuotaExceeded = sbEntity.gotQuotaExceeded || gotQuotaExceeded; + sbEntity.totalBytes = totalBytes; + sbEntity.maxTotalBytes = Math.max(sbEntity.totalBytes, sbEntity.maxTotalBytes); + } + // Merge the newly appended segment into what we think we already have buffered + // Assumed buffered has no overlaps already and is sorted by startPTS + // Modifies in-place + function mergeToBuffer(buffered, appended) { + let appendedAdded = false; + for (let i = buffered.length - 1; i > -1; i--) { + const seg = buffered[i]; + const overlapStart = Math.max(appended.startPTS, seg.startPTS); + const overlapEnd = Math.min(appended.endPTS, seg.endPTS); + if (overlapStart >= overlapEnd) { + continue; + } + const bytes = (1 - (overlapEnd - overlapStart) / (seg.endPTS - seg.startPTS)) * seg.bytes; + if (bytes <= 0) { + buffered.splice(i, 1); + continue; + } + seg.bytes = bytes; + if (seg.startPTS < appended.startPTS) { + seg.endPTS = overlapStart; + } + else { + seg.startPTS = overlapEnd; + if (!appendedAdded) { + buffered.splice(i, 0, appended); + appendedAdded = true; + } + } + } + if (!appendedAdded) { + buffered.push(appended); + } + } + /** + * Returns length of overlap of segment with given bufferedRange + */ + function segmentOverlapLength(segment, range) { + return Math.min(segment.endPTS, range.end) - Math.max(segment.startPTS, range.start); + } + /** + * Returns the BufferedRange that has maximum ovelap with given segment. + */ + function getMaxOverlappingRange(bufferedRanges, segment) { + let maxOverlappingRange = undefined; + let lastOverlapLength = 0; + // TODO: Use binary search over bufferedRanges rdar://89159252 + for (const range of bufferedRanges) { + // Check only when there is overlap + if (range.start <= segment.endPTS && range.end > segment.startPTS) { + const currentOverlapLength = segmentOverlapLength(segment, range); + if (currentOverlapLength > lastOverlapLength) { + maxOverlappingRange = range; + lastOverlapLength = currentOverlapLength; + } + } + else if (lastOverlapLength > 0) { + // bufferedRanges is Normalized TimeRanges object i.e "The ranges in such an object are ordered, don't overlap, and don't touch" + // No point iterating through rest of ranges if overlap is found previously and no overlap afterwards. + break; + } + } + return maxOverlappingRange; + } + + function isIframeMediaFragment(frag) { + return frag != null && 'iframeMediaDuration' in frag && 'iframeMediaStart' in frag; + } + function fragEqual(a, b) { + return a === b || (a && b && a.itemId === b.itemId && a.mediaOptionId === b.mediaOptionId && a.mediaSeqNum === b.mediaSeqNum && a.discoSeqNum === b.discoSeqNum); + } + function fragPrint(frag) { + return JSON.stringify(frag, ['mediaOptionId', 'mediaSeqNum', 'discoSeqNum', 'start', 'duration']); + } + + function filterNullOrUndefined() { + return (source) => source.pipe(filter((x) => x != null), map((x) => x)); + } + + function getVideoCodecRanking(videoCodec) { + if (MediaUtil.isDolby(videoCodec)) { + return VideoCodecRank.DOVI; + } + else if (MediaUtil.isHEVC(videoCodec)) { + return VideoCodecRank.HEVC; + } + else if (MediaUtil.isVP09(videoCodec)) { + return VideoCodecRank.VP09; + } + else if (MediaUtil.isAVC(videoCodec)) { + return VideoCodecRank.AVC; + } + else { + return VideoCodecRank.UNKNOWN; + } + } + function getVideoCodecFamily(videoCodec) { + return videoCodec === null || videoCodec === void 0 ? void 0 : videoCodec.split('.')[0]; + } + function getAudioCodecRanking(audioCodec) { + if (MediaUtil.isALAC(audioCodec)) { + return AudioCodecRank.ALAC; + } + else if (MediaUtil.isFLAC(audioCodec)) { + return AudioCodecRank.FLAC; + } + else if (MediaUtil.isEC3(audioCodec)) { + return AudioCodecRank.EC3; + } + else if (MediaUtil.isAC3(audioCodec)) { + return AudioCodecRank.AC3; + } + else if (MediaUtil.isXHEAAC(audioCodec)) { + return AudioCodecRank.XHEAAC; + } + else if (MediaUtil.isAAC(audioCodec)) { + return AudioCodecRank.AAC; + } + else if (MediaUtil.isMP3(audioCodec)) { + return AudioCodecRank.MP3; + } + else { + return AudioCodecRank.UNKNOWN; + } + } + function getVideoRangeRanking(videoRange) { + if (videoRange === 'PQ') { + return VideoRangeRank.PQ; + } + else if (videoRange === 'HLG') { + return VideoRangeRank.HLG; + } + else if (videoRange === 'SDR') { + return VideoRangeRank.SDR; + } + else { + return VideoRangeRank.UNKNOWN; + } + } + function getAudioVideoCodecRanks(codecInfo) { + return { videoCodecRank: getVideoCodecRanking(codecInfo.videoCodec), audioCodecRank: getAudioCodecRanking(codecInfo.audioCodec) }; + } + class MediaOptionRank { + constructor(...identifier) { + this.identifier = identifier; + } + ensureSameIdentifierLength(rank) { + if (this.identifier.length !== rank.identifier.length) { + throw new Error(`Identifiers have non-matching lengths! (${this.identifier.length} vs ${rank.identifier.length})`); + } + } + isGreaterThan(rank) { + this.ensureSameIdentifierLength(rank); + for (let i = 0; i < this.identifier.length; ++i) { + if (this.identifier[i] < rank.identifier[i]) { + return false; + } + else if (this.identifier[i] > rank.identifier[i]) { + return true; + } + } + return false; + } + isEqualTo(rank) { + this.ensureSameIdentifierLength(rank); + return this.identifier.every((entry, i) => entry === rank.identifier[i]); + } + } + + function isIframeRate(rate) { + return isFiniteNumber(rate) && rate !== 0 && rate !== 1; + } + + class MutexBusyError extends Error { + } + const __executeAndUnlock = (value, update, unlock, operation) => { + if (!operation) { + // no operation() provided, caller should excplicitly call unlock() + return of(value); + } + let result; + let obs; + try { + result = operation(value, update); + } + catch (err) { + obs = throwError(() => err); + } + if (!obs) { + if (typeof result === 'undefined') { + obs = of(value); + } + else { + obs = from(result); + } + } + // auto-unlock if operation() has been called + return obs.pipe(finalize$1(unlock)); + }; + /** + * Mutex is a concept borrowed from multi-threaded programming. Although it's + * not the first time multi-thread syncing primitives are used in single + * threaded program. Python 3 for example has a collection of single threaded + * coroutine syncing primitives in the asyncio package. Any single threaded + * program with an event loop would have the problem of "data race" before and + * after the event loop context switch. Note that event loop achieves concurrent + * processing similar to system level process and thread scheduling on a single + * core. Therefore, classical syncing primitives are also applicable for event + * loops. + * + * IMPORTANT: Always justify your reason if you use Mutex in your code. The only + * permitable use-case is the protected operation can be called from different + * threads and only one can execute at one time. If the component has multiple + * such operations need this synchronization, please consider using command + * queue pattern instead of Mutex. + */ + class Mutex { + /** + * Mutex can optionally carry the data it's protecting. Doing so can make it + * more explicit that the data should be accessed while holing a lock of this + * mutex. + * @param value data to be stored on the Mutex + */ + constructor(value) { + this.value = value; + this.waiters = []; + this.wcounter = 0; + this.rcounter = 0; + } + lock(operation, tryLock = false) { + return this._lock(true, operation, tryLock); + } + /** + * Release a lock previously acquired on the mutex. + */ + unlock() { + this._unlock(true); + } + readLock(operation, tryLock = false) { + return this._lock(false, operation, tryLock); + } + /** + * Release a read-only lock previously acquired on the mutex. + */ + readUnlock() { + this._unlock(false); + } + _schedule() { + const _waitersToWake = []; + this.waiters = this.waiters.filter(waiter => { + if (this._canLock(waiter.rw)) { + if (waiter.rw) { + ++this.wcounter; + } + else { + ++this.rcounter; + } + _waitersToWake.push(waiter); + return false; + } + return true; + }); + for (const waiter of _waitersToWake) { + waiter.observer.next(this.value); + waiter.observer.complete(); + } + } + _canLock(rw) { + return (rw && this.wcounter === 0 && this.rcounter === 0) || (!rw && this.wcounter === 0); + } + _lock(rw, operation, tryLock = false) { + if (typeof operation === 'boolean') { + [tryLock, operation] = [operation, undefined]; + } + const obs = new Observable(observer => { + const canLock = this._canLock(rw); + if (tryLock && !canLock) { + throw new MutexBusyError(); + } + if (canLock) { + if (rw) { + ++this.wcounter; + } + else { + ++this.rcounter; + } + observer.next(); + observer.complete(); + } + else { + this.waiters.push({ rw, observer }); + } + }); + if (operation) { + return obs.pipe(mergeMap(() => __executeAndUnlock(this.value, newval => void (this.value = newval), () => this._unlock(rw), operation))); + } + return obs; + } + _unlock(rw) { + if (rw) { + this.wcounter = Math.max(this.wcounter - 1, 0); + } + else { + this.rcounter = Math.max(this.rcounter - 1, 0); + } + this._schedule(); + } + } + /** + * WaitGroup is a concept borrowed from Golang used to wait for async routines + * to finish. We can use it to signal async shutdown completion to subscribers. + * + * class Hls { + * public destroy$ = new Subject(); + * public destroyWG = new WaitGroup(); + * constructor() { + * observableWithAsyncTeardown(this).pipe( + * takeUntil(this.destroy$) // chain its lifecycle to Hls + * ).subscribe(); + * } + * public destroy(): Promise { + * this.destroy$.next(); + * // all lifecyles chained below Hls will teardown. Async routines + * // will be registered with hls.destroyWG.add() + * + * return this.destroyWG.toPromise(); + * // returned promise will resolve when all async routines + * // registered are finished with hls.destroyWG.done() + * } + * } + * const observableWithAsyncTeardown = (hls: Hls) => + * new Observable((subscriber) => { + * return () => { // teardown function + * hls.destroyWG.add(); // register an async routine + * setTimeout(() => { + * console.log('async teardown finished'); + * hls.destroyWG.done(); // signal finish of a async routine + * }, 1000); + * }; + * }); + * + * And there is a shorthand for Promise or Observable like async routine: + * + * wg.wrap(promise).subscribe(); + * + */ + class WaitGroup extends Observable { + constructor() { + super((subscriber) => this._count$ + .pipe( + // emits only when count reaches to zero + filter((count) => count === 0), + // completes once count reaches to zero + take(1), + // convert to empty value (undefined) + mapTo(void 0)) + .subscribe(subscriber)); + this._count$ = new BehaviorSubject(0); + } + /** + * Wrap an async operation to wait for. + * @param routine an async operation to wait for + */ + wrap(routine) { + return defer(() => { + this.add(); + return from(routine); + }).pipe( + // propagate error in the async routine + tap({ error: (e) => this._count$.error(e) }), + // decrement the count when the async routine finishes + finalize$1(() => this.done())); + } + /** + * Increase the wait counter. + * @param n delta to increase the counter + */ + add(n = 1) { + this._count$.next(this._count$.value + n); + } + /** + * Decrease the wait counter. + * @param n delta to decrease the counter + */ + done(n = 1) { + this._count$.next(this._count$.value - n); + } + } + + + const BufferHelper = { + isBuffered(buffered, position) { + for (let i = 0; buffered && i < buffered.length; i++) { + if (position >= buffered.start(i) && position <= buffered.end(i)) { + return true; + } + } + return false; + }, + /** + * Return Array of [ {start, end} ] + * @param media Something with a buffered TimeRanges property (HTMLMediaElement, SourceBuffer, etc) + */ + timeRangesToBufferedRange(timeRanges) { + const bufferedRangeArray = []; + for (let ix = 0; timeRanges && ix < timeRanges.length; ix++) { + bufferedRangeArray.push({ + start: timeRanges.start(ix), + end: timeRanges.end(ix), + }); + } + return bufferedRangeArray; + }, + subtitleBufferInfo(cues, pos, maxHoleDuration) { + if (cues) { + const buffered = this.bufferedCues(cues); + return this.getBufferedInfo(buffered, pos, maxHoleDuration); + } + return { len: 0, start: pos, end: pos, nextStart: undefined }; + }, + fragmentsBufferedInfo(bufferedFrags, pos, maxHoleDuration) { + const buffered = []; + for (const frag of bufferedFrags) { + buffered.push({ start: frag.start, end: frag.start + frag.duration }); + } + return this.getBufferedInfo(buffered, pos, maxHoleDuration); + }, + bufferedCues(cues) { + const buffered = []; + if (cues) { + for (let ix = 0; ix < cues.length; ix++) { + buffered.push({ start: cues[ix].startTime, end: cues[ix].endTime }); + } + } + return buffered; + }, + bufferedInfoFromMedia(media, pos, maxHoleDuration) { + return BufferHelper.getBufferedInfo(BufferHelper.timeRangesToBufferedRange(media.buffered), pos, maxHoleDuration); + }, + getBufferedInfo(inBufferedRanges, pos, maxHoleDuration) { + const buffered2 = []; + // bufferStart and bufferEnd are buffer boundaries around current video position + let bufferLen, bufferStart, bufferEnd, bufferStartNext, i; + // sort on buffer.start/smaller end (IE does not always return sorted buffered range) + const bufferedRanges = inBufferedRanges.map(({ start, end }) => ({ start, end })); + bufferedRanges.sort((a, b) => { + const diff = a.start - b.start; + if (diff) { + return diff; + } + return b.end - a.end; + }); + // there might be some small holes between buffer time range + // consider that holes smaller than maxHoleDuration are irrelevant and build another + // buffer time range representations that discards those holes + for (i = 0; i < bufferedRanges.length; i++) { + const buf2len = buffered2.length; + if (buf2len) { + const buf2end = buffered2[buf2len - 1].end; + // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative) + if (bufferedRanges[i].start - buf2end < maxHoleDuration) { + // merge overlapping time ranges + // update lastRange.end only if smaller than item.end + // e.g. [ 1, 15] with [ 2,8] => [ 1,15] (no need to modify lastRange.end) + // whereas [ 1, 8] with [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15]) + if (bufferedRanges[i].end > buf2end) { + buffered2[buf2len - 1].end = bufferedRanges[i].end; + } + } + else { + // big hole + buffered2.push(bufferedRanges[i]); + } + } + else { + // first value + buffered2.push(bufferedRanges[i]); + } + } + for (i = 0, bufferLen = 0, bufferStart = bufferEnd = pos; i < buffered2.length; i++) { + const { start } = buffered2[i], { end } = buffered2[i]; + if (pos + maxHoleDuration >= start && pos < end) { + // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length + bufferStart = start; + bufferEnd = end; + bufferLen = bufferEnd - pos; + } + else if (pos + maxHoleDuration < start) { + bufferStartNext = start; + break; + } + } + return { + len: bufferLen, + start: bufferStart, + end: bufferEnd, + nextStart: bufferStartNext, + }; + }, + toRangeString(bufferInfo) { + return `[${bufferInfo.start.toFixed(3)},${bufferInfo.end.toFixed(3)}]`; + }, + }; + + var StallType; + (function (StallType) { + StallType["Seek"] = "Seek"; + StallType["HighBuffer"] = "HighBuffer"; + StallType["LowBuffer"] = "LowBuffer"; + })(StallType || (StallType = {})); + var BufferWaterLevel; + (function (BufferWaterLevel) { + BufferWaterLevel["AlmostDry"] = "AlmostDry"; + BufferWaterLevel["LowWater"] = "LowWater"; + BufferWaterLevel["HighWater"] = "HighWater"; + BufferWaterLevel["AboveHighWater"] = "AboveHighWater"; + })(BufferWaterLevel || (BufferWaterLevel = {})); + const waterLevelToValue = { + [BufferWaterLevel.AlmostDry]: 0, + [BufferWaterLevel.LowWater]: 1, + [BufferWaterLevel.HighWater]: 2, + [BufferWaterLevel.AboveHighWater]: 3, + }; + /** + * @returns whether from water level is > to water level + */ + function waterLevelFell(from, to) { + return waterLevelToValue[from] > waterLevelToValue[to]; + } + + /** + * Highest threshold less than waterLevelSec + * @param waterLevelSec The waterlevel + */ + function getHighestThresholdBelowWater(waterLevelSec, info) { + const result = [ + { threshold: info.highWaterLevelSeconds, level: BufferWaterLevel.HighWater }, + { threshold: info.lowWaterLevelSeconds, level: BufferWaterLevel.LowWater }, + { threshold: info.almostDryWaterLevelSeconds, level: BufferWaterLevel.AlmostDry }, + ].find(({ threshold }) => { + return waterLevelSec > threshold; + }); + return result; + } + /** + * Lowest threshold higher than waterLevelSec + * @param waterLevelSec The water level + */ + function getLowestThresholdAboveWaterLevel(waterLevelSec, info) { + const result = [ + { threshold: info.almostDryWaterLevelSeconds, level: BufferWaterLevel.AlmostDry }, + { threshold: info.lowWaterLevelSeconds, level: BufferWaterLevel.LowWater }, + { threshold: info.highWaterLevelSeconds, level: BufferWaterLevel.HighWater }, + { threshold: Infinity, level: BufferWaterLevel.AboveHighWater }, + ].find(({ threshold }) => { + return waterLevelSec <= threshold; + }); + return result; + } + function updateWaterLevels(meQuery, maxBufferHole) { + const combined = getLowestThresholdAboveWaterLevel(meQuery.getCurrentWaterLevel(maxBufferHole), meQuery.bufferMonitorInfo).level; + const sbTuple = [null, null]; + [SourceBufferType.Variant, SourceBufferType.AltAudio].forEach((sbType) => { + if (meQuery.sourceBufferEntityByType(sbType) != null) { + sbTuple[sbType] = getLowestThresholdAboveWaterLevel(meQuery.getCurrentWaterLevelByType(sbType, maxBufferHole), meQuery.bufferMonitorInfo).level; + } + }); + return { combined, sbTuple }; + } + /** + * Observable that re-calculates water level when threshold or buffered range changes + */ + function waterLevelChangedFromBuffer(meQuery, maxBufferHole) { + return combineQueries([meQuery.bufferMonitorThresholds$, meQuery.combinedBuffer$, meQuery.seeking$]).pipe(map(([thresholds]) => { + if (thresholds == null) { + return null; + } + return updateWaterLevels(meQuery, maxBufferHole); + })); + } + /** + * Observable that re-calculates water level during regular playback + */ + function waterLevelChangedFromPlayback(meQuery, maxBufferHole, logger) { + return combineQueries([meQuery.combinedBuffer$, meQuery.gotPlaying$, meQuery.seeking$, meQuery.waterLevelChangedForType$(null), meQuery.stallInfo$]).pipe(switchMap(([combinedBuffer, playing, seeking, waterLevelType, stallInfo]) => { + if (combinedBuffer.length === 0 || !playing || seeking || waterLevelType == null || stallInfo != null) { + return EMPTY; + } + return scheduleWaterLevelCheck(meQuery, maxBufferHole); + })); + } + function scheduleWaterLevelCheck(meQuery, maxBufferHole, logger) { + // Combined water level should be minimum of the source buffers + const combinedWaterLevel = meQuery.getCurrentWaterLevel(maxBufferHole); + const thresholdInfo = getHighestThresholdBelowWater(combinedWaterLevel, meQuery.bufferMonitorInfo); + if (thresholdInfo) { + const { threshold } = thresholdInfo; + const delayMs = Math.ceil((combinedWaterLevel - threshold) * 1000); + return timer(delayMs).pipe(switchMap(() => { + const newCombinedWaterLevel = meQuery.getCurrentWaterLevel(maxBufferHole); + const newThresholdInfo = getHighestThresholdBelowWater(newCombinedWaterLevel, meQuery.bufferMonitorInfo); + if ((newThresholdInfo === null || newThresholdInfo === void 0 ? void 0 : newThresholdInfo.level) === thresholdInfo.level) { + // Didn't actually cross threshold, re-schedule check + return scheduleWaterLevelCheck(meQuery, maxBufferHole); + } + return VOID; + }), map(() => { + return updateWaterLevels(meQuery, maxBufferHole); + })); + } + return EMPTY; + } + /** + * Epic for updating the water level + */ + function bufferMonitorEpic(meQuery, meStore, maxBufferHole, logger) { + return merge(waterLevelChangedFromBuffer(meQuery, maxBufferHole), waterLevelChangedFromPlayback(meQuery, maxBufferHole)).pipe(observeOn(asyncScheduler), tap(({ combined, sbTuple }) => { + meStore.updateWaterLevels(combined, sbTuple); + })); + } + + /** + * @brief Query interface to playback state + */ + class MediaElementQuery extends QueryEntity { + constructor(mediaElement, mediaElementStore) { + super(mediaElementStore); + this.mediaElement = mediaElement; + } + get mediaElementDuration$() { + return this.selectActive(({ mediaElementDuration }) => mediaElementDuration); + } + get mediaElementDuration() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.mediaElementDuration) !== null && _b !== void 0 ? _b : Infinity; + } + get msDuration() { + var _a, _b; + return (_b = (_a = this.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.duration) !== null && _b !== void 0 ? _b : Infinity; + } + // return the smaller of all the sourceBuffer totaldurations + // return infinity if any of the source buffer is not fully buffered + get minSBDuration() { + var _a, _b; + let minDuration = Number.POSITIVE_INFINITY; + (_b = (_a = this.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.sourceBufferEntities) === null || _b === void 0 ? void 0 : _b.forEach((entity, index) => { + if (entity) { + // may be muxed or unmuxed + if (isFiniteNumber(entity.totalDuration)) { + // entity.totalDuration is a finite number if sb is fully buffered + minDuration = Math.min(minDuration, entity.totalDuration); + } + else { + // one of the SBs not fully buffered + minDuration = Number.NEGATIVE_INFINITY; + } + } + }); + return isFiniteNumber(minDuration) ? minDuration : Infinity; + } + get currentTime() { + return this.mediaElement.currentTime; + } + get clientWidth() { + return this.mediaElement.clientWidth; + } + get clientHeight() { + return this.mediaElement.clientHeight; + } + getBufferedDuration(maxBufferDuration = 0.5) { + const ranges = BufferHelper.timeRangesToBufferedRange(this.mediaElement.buffered); + const bufferInfo = BufferHelper.getBufferedInfo(ranges, this.currentTime, maxBufferDuration); + return bufferInfo.end - bufferInfo.start; + } + get mediaSourceEntity() { + var _a; + return (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.mediaSourceEntity; + } + get msReadyState() { + var _a; + return (_a = this.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.readyState; + } + get sourceBufferEntities() { + var _a; + return (_a = this.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.sourceBufferEntities; + } + sourceBufferEntityByType(sbType) { + var _a; + return (_a = this.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[sbType]; + } + initSegmentEntityByType(sbType) { + var _a; + return (_a = this.sourceBufferEntityByType(sbType)) === null || _a === void 0 ? void 0 : _a.initSegmentInfo; + } + get maxBufferSize() { + var _a, _b; + const entity = (_a = this.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[SourceBufferType.Variant]; + let maxBufferSize = Infinity; + if (entity === null || entity === void 0 ? void 0 : entity.gotQuotaExceeded) { + maxBufferSize = (_b = entity.maxTotalBytes) !== null && _b !== void 0 ? _b : Infinity; + } + return maxBufferSize; + } + get postFlushSeek() { + var _a; + return (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.postFlushSeek; + } + get seekable() { + return this.mediaElement.seekable; + } + get desiredRate() { + var _a; + return ((_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.desiredRate) || 0; + } + get desiredRate$() { + return this.selectActive(({ desiredRate }) => desiredRate !== null && desiredRate !== void 0 ? desiredRate : 0); + } + get effectiveRate() { + if (this.isIframeRate) { + return this.desiredRate; + } + return this.paused ? 0 : 1; + } + get playbackRate() { + return this.mediaElement.playbackRate; + } + get isIframeRate() { + const rate = this.desiredRate; + return isIframeRate(rate); + } + get isIframeRate$() { + return this.desiredRate$.pipe(map(isIframeRate)); + } + get msObjectUrl$() { + return this.selectActive(({ mediaSourceEntity }) => mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.objectUrl).pipe(distinctUntilChanged()); + } + get msReadyState$() { + return this.selectActive(({ mediaSourceEntity }) => { var _a; return (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.readyState) !== null && _a !== void 0 ? _a : null; }); + } + get readyState() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.readyState) !== null && _b !== void 0 ? _b : 0; + } + get readyState$() { + return this.selectActive(({ readyState }) => readyState !== null && readyState !== void 0 ? readyState : 0); + } + get mediaSourceEntity$() { + return this.selectActive(({ mediaSourceEntity }) => mediaSourceEntity); + } + get expectedSbCount$() { + return this.selectActive(({ expectedSbCount }) => expectedSbCount); + } + get expectedSbCount() { + var _a; + return (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.expectedSbCount; + } + get paused$() { + return this.selectActive(({ paused }) => paused); + } + get paused() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.paused) !== null && _b !== void 0 ? _b : true; + } + get playbackStarted() { + var _a; + return isFiniteNumber((_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.firstPlayTime); + } + get flushing$() { + return this.selectActive(({ flushing }) => flushing); + } + get flushing() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.flushing) !== null && _b !== void 0 ? _b : false; + } + get waitingForDisco$() { + return this.selectActive(({ waitingForDisco }) => waitingForDisco); + } + get waitingForDisco() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.waitingForDisco) !== null && _b !== void 0 ? _b : false; + } + get gotPlaying() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.gotPlaying) !== null && _b !== void 0 ? _b : false; + } + get gotPlaying$() { + return this.selectActive(({ gotPlaying }) => gotPlaying); + } + get gotLoadStart$() { + return this.selectActive(({ gotLoadStart }) => gotLoadStart); + } + get seekTo() { + var _a; + return (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.seekTo; + } + get seekTo$() { + return this.selectActive(({ seekTo }) => seekTo); + } + get seeking() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.seeking) !== null && _b !== void 0 ? _b : false; + } + get seeking$() { + return this.selectActive(({ seeking }) => seeking); + } + get nudgeTarget$() { + return this.selectActive(({ nudgeInfo }) => nudgeInfo === null || nudgeInfo === void 0 ? void 0 : nudgeInfo.nudgeTarget); + } + get nudgeCount() { + var _a, _b, _c; + return (_c = (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.nudgeInfo) === null || _b === void 0 ? void 0 : _b.nudgeCount) !== null && _c !== void 0 ? _c : 0; + } + get sourceBufferEntities$() { + return this.selectActive(({ mediaSourceEntity }) => mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities); + } + sourceBufferEntityByType$(sbType) { + return this.selectActive(({ mediaSourceEntity }) => { var _a; return (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[sbType]; }); + } + // Get info on what we think is currently in the buffer by type + bufferedSegmentsByType$(sbType) { + return this.selectActive(({ mediaSourceEntity }) => { var _a, _b, _c; return (_c = (_b = (_a = mediaSourceEntity === null || mediaSourceEntity === void 0 ? void 0 : mediaSourceEntity.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a[sbType]) === null || _b === void 0 ? void 0 : _b.bufferedSegments) !== null && _c !== void 0 ? _c : []; }); + } + getBufferedSegmentsByType(sbType) { + var _a, _b; + return (_b = (_a = this.sourceBufferEntityByType(sbType)) === null || _a === void 0 ? void 0 : _a.bufferedSegments) !== null && _b !== void 0 ? _b : []; + } + // Get info on what we think is currently in both source buffers + get bufferedSegmentsTuple$() { + return combineQueries([this.bufferedSegmentsByType$(SourceBufferType.Variant), this.bufferedSegmentsByType$(SourceBufferType.AltAudio)]).pipe(debounceTime(10)); + } + get timeupdate$() { + const target = fromEventTarget(this.mediaElement); + return target.event('timeupdate').pipe(observeOn(asyncScheduler), share(), throttleTime(125, undefined, { leading: true, trailing: true }), map((_) => this.currentTime), filter((pos) => isFiniteNumber(pos))); + } + get playingEvent$() { + const target = fromEventTarget(this.mediaElement); + return target.event('playing').pipe(map(() => undefined)); + } + get mediaElementEntity$() { + return this.selectActive((entity) => Boolean(entity)); + } + get ended$() { + return this.selectActive((entity) => { var _a; return (_a = entity === null || entity === void 0 ? void 0 : entity.ended) !== null && _a !== void 0 ? _a : false; }); + } + sbUpdating$(type) { + return this.selectActive((entity) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = entity === null || entity === void 0 ? void 0 : entity.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.sourceBufferEntities) === null || _b === void 0 ? void 0 : _b[type]) === null || _c === void 0 ? void 0 : _c.updating) !== null && _d !== void 0 ? _d : false; }); + } + sbUpdating(type) { + var _a, _b, _c, _d, _e; + return (_e = (_d = (_c = (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.mediaSourceEntity) === null || _b === void 0 ? void 0 : _b.sourceBufferEntities) === null || _c === void 0 ? void 0 : _c[type]) === null || _d === void 0 ? void 0 : _d.updating) !== null && _e !== void 0 ? _e : false; + } + sbError$(type) { + return this.selectActive((entity) => { var _a, _b, _c; return (_c = (_b = (_a = entity === null || entity === void 0 ? void 0 : entity.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.sourceBufferEntities) === null || _b === void 0 ? void 0 : _b[type]) === null || _c === void 0 ? void 0 : _c.error; }); + } + get updating$() { + return combineQueries([this.sbUpdating$(SourceBufferType.Variant), this.sbUpdating$(SourceBufferType.AltAudio)]).pipe(map((values) => values.some((updating) => updating))); + } + get bufferedRangeTuple$() { + return combineQueries([ + this.selectActive((entity) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = entity === null || entity === void 0 ? void 0 : entity.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.sourceBufferEntities) === null || _b === void 0 ? void 0 : _b[MediaOptionType.Variant]) === null || _c === void 0 ? void 0 : _c.bufferedRanges) !== null && _d !== void 0 ? _d : null; }), + this.selectActive((entity) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = entity === null || entity === void 0 ? void 0 : entity.mediaSourceEntity) === null || _a === void 0 ? void 0 : _a.sourceBufferEntities) === null || _b === void 0 ? void 0 : _b[MediaOptionType.AltAudio]) === null || _c === void 0 ? void 0 : _c.bufferedRanges) !== null && _d !== void 0 ? _d : null; }), + ]); + } + getBufferedRangeByType(type) { + var _a, _b; + return (_b = (_a = this.sourceBufferEntities[type]) === null || _a === void 0 ? void 0 : _a.bufferedRanges) !== null && _b !== void 0 ? _b : []; + } + get combinedBuffer$() { + return this.selectActive((entity) => { var _a; return (_a = entity === null || entity === void 0 ? void 0 : entity.bufferedRanges) !== null && _a !== void 0 ? _a : []; }); + } + getBufferInfo(pos, maxBufferHole) { + var _a; + const bufferedRanges = (_a = this.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a.map((x) => x === null || x === void 0 ? void 0 : x.bufferedRanges); + const defaultInfo = { buffered: { start: pos, end: pos, len: 0 }, bufferedSegments: [] }; + const res = [defaultInfo, defaultInfo]; + if (!bufferedRanges) { + return res; + } + bufferedRanges.forEach((ranges, type) => { + var _a; + if (ranges) { + const bufferInfo = BufferHelper.getBufferedInfo(ranges, pos, maxBufferHole); + const segments = (_a = this.sourceBufferEntities[type].bufferedSegments) !== null && _a !== void 0 ? _a : []; + const bufferedSegments = segments.filter((s) => !(s.endPTS < bufferInfo.start || s.startPTS > bufferInfo.end)); + res[type] = { buffered: bufferInfo, bufferedSegments }; + } + }); + return res; + } + getCombinedBufferInfo(pos, maxBufferHole) { + const entity = this.getActive(); + if (entity) { + return BufferHelper.getBufferedInfo(entity.bufferedRanges, pos, maxBufferHole); + } + return null; + } + get bufferMonitorInfo() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.bufferMonitorInfo) !== null && _b !== void 0 ? _b : null; + } + get bufferMonitorThresholds$() { + return this.selectActive((entity) => { + const info = entity === null || entity === void 0 ? void 0 : entity.bufferMonitorInfo; + if (!info) { + return null; + } + const { almostDryWaterLevelSeconds, lowWaterLevelSeconds, highWaterLevelSeconds, maxBufferSeconds } = info; + return { almostDryWaterLevelSeconds, lowWaterLevelSeconds, highWaterLevelSeconds, maxBufferSeconds }; + }).pipe(distinctUntilChanged((a, b) => (a === null || a === void 0 ? void 0 : a.lowWaterLevelSeconds) === (b === null || b === void 0 ? void 0 : b.lowWaterLevelSeconds))); + } + get waterLevelType$() { + return this.selectActive((entity) => { var _a; return (_a = entity === null || entity === void 0 ? void 0 : entity.bufferMonitorInfo.waterLevelType) !== null && _a !== void 0 ? _a : null; }); + } + waterLevelForType(sbType) { + var _a, _b, _c; + return (_c = (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.bufferMonitorInfo.waterLevelType) === null || _b === void 0 ? void 0 : _b.sbTuple[sbType]) !== null && _c !== void 0 ? _c : null; + } + waterLevelChangedForType$(sbType) { + return this.waterLevelType$.pipe(map((waterLevelType) => { + if (waterLevelType == null) { + return null; + } + if (sbType == null) { + return waterLevelType.combined; + } + return waterLevelType.sbTuple[sbType]; + })); + } + /** + * @returns emits whether we crossed LowWaterLevel or AlmostDryWater thresholds + */ + get fellBelowLowWater$() { + return this.waterLevelChangedForType$(SourceBufferType.Variant).pipe(pairwise(), map(([from, to]) => { + return waterLevelFell(from, to) && (to === BufferWaterLevel.LowWater || to === BufferWaterLevel.AlmostDry); + }), withLatestFrom(this.seekTo$, this.waitingForDisco$), map(([fellBelowThreshold, seekTo, waitingForDisco]) => { + return fellBelowThreshold && !isFiniteNumber(seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos) && !waitingForDisco; + }), startWith(false)); + } + /** + * @returns whether the current position has buffer all the way up to the end + * FIXME: Gapless mode uses mediaElementDuration because current sb.totalduration may confuse item preloading + * (consider reseting sb.totalduration or use another variable to track preloading state) + */ + isBufferedToEnd$(maxBufferHole, nonGapless = true) { + return combineQueries([ + this.combinedBuffer$, + this.selectActive((entity) => entity.bufferMonitorInfo).pipe(filterNullOrUndefined(), + // Threshold value + map((bufferInfo) => (nonGapless ? bufferInfo.almostDryWaterLevelSeconds : Math.max(bufferInfo.almostDryWaterLevelSeconds, bufferInfo.lowWaterLevelSeconds / 2)))), + this.seeking$, + ]).pipe(map(([combinedBuffer, closeToEndThreshold]) => { + const totalSBBufferedDuration = this.minSBDuration; + if (!combinedBuffer || (!isFiniteNumber(totalSBBufferedDuration) && nonGapless)) { + return false; + } + // TODO: may need to tweak this for gapless mode + const combined = BufferHelper.getBufferedInfo(combinedBuffer, this.currentTime, maxBufferHole); + const bufferEnd = combined.end; + let duration; + let ended; + if (nonGapless) { + // one last combined buffer duration check against known sb.totalduration (should be the same value) + duration = totalSBBufferedDuration; + ended = Math.abs(duration - bufferEnd) <= closeToEndThreshold; // remove closeToEndThreshould if we can confirm combined buffered len is as accurate as sb buffered len + } + else { + duration = this.mediaElementDuration; + ended = duration - bufferEnd <= closeToEndThreshold; + } + getLogger().trace('Fully buffered calculation duration=%d, bufferEnd=%d, closeToEndThreshold=%d ended=%d', totalSBBufferedDuration, bufferEnd, closeToEndThreshold, ended); + return ended; + }), distinctUntilChanged()); + } + needData$(maxBufferHole, inGaplessMode = false) { + const useMinSbDuration = !inGaplessMode; + return combineQueries([ + this.msReadyState$, + this.waterLevelChangedForType$(null), + this.isBufferedToEnd$(maxBufferHole, useMinSbDuration), + this.bufferedRangeTuple$, + this.seekTo$, + this.mediaElementDuration$, + ]).pipe(debounceTime(10), + // observeOn(asyncScheduler), debounceTime already uses asyncScheduler + map(([readyState, waterLevelType, bufferedToEnd, _, seekTo]) => { + if (readyState === 'closed') { + return false; // Allow append if 'ended' + } + if (inGaplessMode) { + getLogger().debug({ name: 'MediaQuery' }, 'Preloading is true, forcing needData to true'); + return true; + } + const haveRoomToLoad = waterLevelType == null || (!bufferedToEnd && waterLevelType !== BufferWaterLevel.AboveHighWater); + const userIsActive = this.isIframeRate || !!seekTo; // buffered to end but user may seek or trickplay away to unbuffered ranges + getLogger().debug({ name: 'MediaQuery' }, `needData = haveRoomToLoad ${haveRoomToLoad} = (bufferedToEnd: ${bufferedToEnd}, waterLevelType: ${waterLevelType}) or userIsActive ${userIsActive} = (isIframeRate: ${this.isIframeRate}, seekTo.pos: ${seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos})`); + return haveRoomToLoad || (waterLevelType !== BufferWaterLevel.AboveHighWater && userIsActive); + }), tag('needData')); + } + getSourceBufferInfoAction(needData, anchorTime, switchContexts, maxBufferHole) { + const { currentTime, sourceBufferEntities, msReadyState } = this; + let bufferInfoTuple = [null, null]; + if (!needData && switchContexts.every((x) => !(x === null || x === void 0 ? void 0 : x.userInitiated))) { + return null; + } + if (msReadyState !== 'open' || !sourceBufferEntities || sourceBufferEntities[0] == null) { + return { position: anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.pos, discoSeqNum: anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.discoSeqNum, bufferInfoTuple, switchContexts }; + } + bufferInfoTuple = this.getBufferInfo(currentTime, maxBufferHole); + return { position: currentTime, discoSeqNum: anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.discoSeqNum, bufferInfoTuple, switchContexts }; + } + get haveEnough() { + var _a, _b; + return (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.haveEnough) !== null && _b !== void 0 ? _b : false; + } + get haveEnough$() { + return this.selectActive(({ haveEnough }) => haveEnough); + } + static likelyToKeepUp(mediaElement, haveEnough, readyState) { + return haveEnough && readyState >= mediaElement.HAVE_FUTURE_DATA; + } + get playbackLikelyToKeepUp() { + return MediaElementQuery.likelyToKeepUp(this.mediaElement, this.haveEnough, this.readyState); + } + get playbackLikelyToKeepUp$() { + return combineQueries([this.haveEnough$, this.readyState$]).pipe(map(([haveEnough, readyState]) => MediaElementQuery.likelyToKeepUp(this.mediaElement, haveEnough, readyState))); + } + // Combined water level at current position + getCurrentWaterLevel(maxBufferHole) { + var _a, _b; + const currentTime = this.currentTime; + const bufferedRanges = (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.bufferedRanges) !== null && _b !== void 0 ? _b : []; + const bufferInfo = BufferHelper.getBufferedInfo(bufferedRanges, currentTime, maxBufferHole); + return bufferInfo.len; + } + //Returns buffer level info, this is only being used for QE logging. + getCombinedMediaSourceBufferInfo(maxBufferHole) { + var _a, _b, _c, _d; + const currentTime = this.currentTime; + const [variantBufferedRanges, altAudioBufferedRanges] = (_b = (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.mediaSourceEntity) === null || _b === void 0 ? void 0 : _b.sourceBufferEntities; + const variantBufferInfo = BufferHelper.getBufferedInfo((_c = variantBufferedRanges === null || variantBufferedRanges === void 0 ? void 0 : variantBufferedRanges.bufferedRanges) !== null && _c !== void 0 ? _c : [], currentTime, maxBufferHole); + const altAudioBufferInfo = BufferHelper.getBufferedInfo((_d = altAudioBufferedRanges === null || altAudioBufferedRanges === void 0 ? void 0 : altAudioBufferedRanges.bufferedRanges) !== null && _d !== void 0 ? _d : [], currentTime, maxBufferHole); + return [variantBufferInfo, altAudioBufferInfo]; + } + // SourceBuffer water level at current position + getCurrentWaterLevelByType(sbType, maxBufferHole) { + var _a; + const currentTime = this.currentTime; + const sbEntity = this.sourceBufferEntityByType(sbType); + const bufferedRanges = (_a = sbEntity === null || sbEntity === void 0 ? void 0 : sbEntity.bufferedRanges) !== null && _a !== void 0 ? _a : []; + const bufferInfo = BufferHelper.getBufferedInfo(bufferedRanges, currentTime, maxBufferHole); + return bufferInfo.len; + } + /** + * For live, returns true, If the live update, has overlap with + * already appended buffer, and therefore can be played back without gap + */ + canContinuePlaybackWithoutGap(details, lastUpdateMillis, playlistEstimate, maxBufferHole) { + if (details.type !== 'LIVE') { + // even for EVENT, return true as predictedStartPosition will be 0. + return true; + } + if (!details.ptsKnown) { + return false; + } + const position = this.currentTime; + const predictedReceiveTime = performance.now() + playlistEstimate.avgPlaylistLoadTimeMs + details.targetduration * 1000; + const predictedStartPosition = details.fragments[0].start + (predictedReceiveTime - lastUpdateMillis) / 1000; + const bufferInfo = this.getCombinedBufferInfo(position, maxBufferHole); + let end = bufferInfo.end; + if (end >= details.fragments[0].start - maxBufferHole && end <= details.fragments[0].start + details.totalduration) { + end = details.fragments[0].start + details.totalduration; + } + return predictedStartPosition <= end; + } + get stallInfo$() { + return this.selectActive((entity) => { var _a; return (_a = entity === null || entity === void 0 ? void 0 : entity.stallInfo) !== null && _a !== void 0 ? _a : null; }); + } + get textTracks() { + return this.mediaElement.textTracks; + } + get textTracksCreated$() { + return this.selectActive((entity) => entity === null || entity === void 0 ? void 0 : entity.textTracksCreated); + } + get mediaOptionParsedSubtitleRecord() { + var _a; + return (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.mediaOptionParsedSubtitleRecord; + } + getParsedSubtitleRecordsForMediaOption(persistentId) { + if (!this.mediaOptionParsedSubtitleRecord) + return null; + const subtitleParsedInfoDict = this.mediaOptionParsedSubtitleRecord[persistentId]; + return subtitleParsedInfoDict ? subtitleParsedInfoDict : {}; + } + } + + class MediaFunctions { + constructor(mediaSink, media, config, logger) { + this.mediaSink = mediaSink; + this.media = media; + this.logger = logger; + this.useCustomMediaFunctions = config.useCustomMediaFunctions; + this.overridePlaybackRate = config.overridePlaybackRate; + } + install() { + const media = this.media; + if (!media) { + return; + } + // * guarantee original play, pause methods will be in media.originalPlay and media.originalPause. + // * always override media.play and media.pause with new methods. + if (this.useCustomMediaFunctions && media && media.play && media.pause) { + // not a bogus media object for unit tests + // always preserve the original play, pause methods + if (!media.originalPlay) { + media.originalPlay = media.play.bind(media); + } + if (!media.originalPause) { + media.originalPause = media.pause.bind(media); + } + // always install new functions over old ones. + this.logger.debug('install custom pause & play methods'); + media.play = () => { + this.logger.debug('overridden play'); + this.mediaSink.checkForReplay(); + this.mediaSink.desiredRate = 1; + const isPlaying = media.currentTime > 0 && !media.paused && !media.ended && media.readyState > 2 ? true : false; + if (!isPlaying) { + // media is not playing now, save the promise and handle whenever the originalPlay promise returns + return new Promise((resolve, reject) => { + if (!this.pendingPlayPromises) { + this.pendingPlayPromises = []; + } + this.pendingPlayPromises.push({ resolve, reject }); + }); + } + else { + return Promise.resolve(); + } + }; + media.pause = () => { + this.logger.debug('overridden pause'); + this.mediaSink.desiredRate = 0; + }; + } + if (typeof HTMLMediaElement === 'function' && this.overridePlaybackRate) { + Object.defineProperty(media, 'playbackRate', { + enumerable: true, + configurable: true, + get: function () { + // pretend it's always 1 to all callers + return 1; + }, + set: function (newValue) { + // allow passthrough set to signal trickplay mode to the media engine + Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'playbackRate').set.call(this, newValue); + }, + }); + } + this.playPromise = null; + this.expectPauseEvent = this.expectPlayEvent = false; + } + uninstall() { + const media = this.media; + if (media) { + if (media.originalPlay) { + this.logger.debug('restore media.play'); + media.play = media.originalPlay; + delete media.originalPlay; + } + if (media.originalPause) { + this.logger.debug('restore media.pause'); + media.pause = media.originalPause; + delete media.originalPause; + } + if (this.overridePlaybackRate) { + media.playbackRate = 1; // restore original value + delete media.playbackRate; + } + } + this.playPromise = null; + this.expectPauseEvent = this.expectPlayEvent = false; + } + play() { + if (this.media) { + const flushing = this.mediaSink.flushing; + if (this.playPromise || flushing) { + this.logger.warn(`Ignoring play command playPromise/flushing ${Boolean(this.playPromise)}/${flushing}`); + return; + } + this.expectPlayEvent = this.expectPlayEvent || this.media.paused; + this.logger.info(`play() expectPlayEvent=${this.expectPlayEvent}`); + this.playPromise = this._mediaPlayInternal(); + if (this.playPromise) { + this.playPromise + .then(function () { + this.logger.info('play() complete'); + this.playPromise = null; + this._handlePendingPlayPromises(null); + }.bind(this)) + .catch(function (err) { + // Could be aborted by pause + this.playPromise = null; + this.expectPlayEvent = false; + this._handlePendingPlayPromises(err || new Error('Play rejected for unknown reason')); + if ((err === null || err === void 0 ? void 0 : err.name) === 'NotAllowedError') { + this.logger.warn('play() not allowed, going back to rate 0'); + this.mediaSink.desiredRate = 0; + } + else { + this.logger.error(`play() error: ${err === null || err === void 0 ? void 0 : err.message}`); + } + }.bind(this)); + } + } + } + pause() { + if (this.media) { + this.logger.info(`pause() playPromise=${Boolean(this.playPromise)}`); + if (this.playPromise) { + // this.playPromise is cleared as soon + // as it resolves in _mediaPlay so we shouldn't fall in here twice + this.playPromise + .then(() => { + const mediaQuery = this.mediaSink.mediaQuery; + if (this.mediaSink.desiredRate === 0 || (mediaQuery.seeking && !mediaQuery.playbackLikelyToKeepUp)) { + this._mediaPauseInternal(); + } + }) + .catch((error) => { + this.logger.error(`Promise error in pause(): ${error.message}`); + }); + } + else { + this._mediaPauseInternal(); + } + } + } + _handlePendingPlayPromises(err) { + var _a; + const count = (_a = this.pendingPlayPromises) === null || _a === void 0 ? void 0 : _a.length; + if (!err) { + // resolve all pending promises + for (let i = 0; i < count; i++) { + this.pendingPlayPromises[i].resolve(); + } + } + else { + // reject all pending promises + for (let i = 0; i < count; i++) { + this.pendingPlayPromises[i].reject(err); + } + } + this.pendingPlayPromises = []; + } + _mediaPlayInternal() { + const playFn = this.media.originalPlay || this.media.play.bind(this.media); + return playFn(); + } + _mediaPauseInternal() { + this.expectPauseEvent = this.expectPauseEvent || !this.media.paused; + this.logger.info(`pause() expectPauseEvent=${this.expectPauseEvent}`); + const pauseFn = this.media.originalPause || this.media.pause.bind(this.media); + return pauseFn(); + } + } + + class MseError extends Error { + } + // Generic SourceBuffer error + class SourceBufferError extends HlsError { + constructor(details, fatal, reason, response, sbType) { + super(ErrorTypes.MEDIA_ERROR, details, fatal, reason, response); + this.sbType = sbType; + this.response = response; + } + } + // Got error when calling addSourceBuffer (unsupported format) + class CreateSourceBufferError extends SourceBufferError { + constructor(message, response, sbType, mediaOptionId) { + super(ErrorDetails.BUFFER_ADD_CODEC_ERROR, false, message, response, sbType); + this.mediaOptionId = mediaOptionId; + this.mediaOptionType = sourceBufferTypeToMediaOptionType(this.sbType); + } + } + class AppendBufferError extends SourceBufferError { + constructor(details, fatal, reason, response, sbType, isTimeout) { + super(details, fatal, reason, response, sbType); + this.isTimeout = isTimeout; + this.mediaOptionType = sourceBufferTypeToMediaOptionType(this.sbType); + } + } + class BufferFullError extends AppendBufferError { + constructor(reason, response, sbType, maxTotalBytes) { + super(ErrorDetails.BUFFER_FULL_ERROR, false, reason, response, sbType, false); + this.maxTotalBytes = maxTotalBytes; + } + } + class AppendTimeoutError extends AppendBufferError { + constructor(reason, response, sbType) { + super(ErrorDetails.BUFFER_APPEND_ERROR, false, reason, response, sbType, true); + } + } + // Got decode error during append + class MediaDecodeError extends AppendBufferError { + constructor(reason, response, sbType, mediaOptionId) { + super(ErrorDetails.BUFFER_APPEND_ERROR, false, reason, response, sbType, false); + this.mediaOptionId = mediaOptionId; + this.mediaOptionType = sourceBufferTypeToMediaOptionType(this.sbType); + } + } + class BufferStallError extends HlsError { + constructor(details, fatal, reason, response, stallType, bufferLen, nudgePosition = NaN) { + super(ErrorTypes.MEDIA_ERROR, details, fatal, reason, response); + this.stallType = stallType; + this.bufferLen = bufferLen; + this.nudgePosition = nudgePosition; + this.response = response; + } + } + + /** + * Observable SourceBuffer adapter that cleans up after itself on unsubscribe + * From src/mse-rxjs/sourcebuffer-adapter.ts + */ + const APPEND_MAX_MS = 10000; // Failsafe append timeout value + class SourceBufferAdapter extends Observable { + constructor(mediaElementStore, mediaElementQuery, mediaElement, mediaSource, type, sourceBuffer, compatInfo, parentLogger, config) { + super((subscriber) => { + const target = fromEventTarget(sourceBuffer); + const logger = parentLogger.child({ sb: type }); + mediaElementStore.setSourceBufferEntity(type, compatInfo); + if (compatInfo.mimeType.includes('audio/mpeg')) { + this.updateMp3Timestamps = true; + } + const sub = merge(target.event('updatestart').pipe(tap(() => { + logger.trace(`[sb${this.type}] updatestart`); + mediaElementStore.setSourceBufferUpdating(type); + })), + // Note we need to do this to keep buffer data updated, + // unless we start allowing abort() as part of teardown / finalize on append/remove + target.event('updateend').pipe(observeOn(asyncScheduler), tap(() => { + const bufferedRanges = BufferHelper.timeRangesToBufferedRange(sourceBuffer.buffered); + const combinedBuffer = BufferHelper.timeRangesToBufferedRange(mediaElement.buffered); + logger.trace(`[sb${this.type}] updateend`); + mediaElementStore.setBufferedRangesUpdated(type, bufferedRanges, combinedBuffer, false, config); + })), target.event('error').pipe(tap(() => { + mediaElementStore.setSourceBufferError(type, 'Got source buffer error'); + }))) + .pipe(switchMap(() => EMPTY)) + .subscribe(subscriber); + return () => { + sub.unsubscribe(); + try { + if (mediaSource.readyState === 'open') { + sourceBuffer.abort(); + } + mediaSource.removeSourceBuffer(sourceBuffer); + } + catch (err) { + logger.error(`Error aborting SourceBuffer on unsubscribe: ${err.message}`); + } + }; + }); + this.mediaElementStore = mediaElementStore; + this.mediaElementQuery = mediaElementQuery; + this.mediaElement = mediaElement; + this.type = type; + this.sourceBuffer = sourceBuffer; + this.config = config; + this.updateMp3Timestamps = false; + } + get buffered() { + return this.sourceBuffer.buffered; + } + /** + * @param data The buffer to append + * @param segment Info about the segment. null means init segment + */ + appendBuffer(data, segment) { + // Use defer so that on re-subscribe we will call appendBuffer again + return defer(() => { + if (this.sourceBuffer.updating) { + return this._waitForUpdateEndOrError().pipe(switchMap(() => this.appendBuffer(data, segment))); + } + return this._appendBufferAsync(data, segment); + }); + } + _appendBufferAsync(data, segment) { + let startAppend = NaN; + let inFlight = null; + const mediaOptionId = 'startPTS' in segment ? segment.frag.mediaOptionId : segment.mediaOptionId; + try { + if ('startPTS' in segment) { + inFlight = { startPTS: segment.startPTS, endPTS: segment.endPTS, bytes: segment.bytes, frag: Object.assign({}, segment.frag) }; + } + this.mediaElementStore.setInflightSegment(this.type, inFlight); + startAppend = performance.now(); + this.sourceBuffer.appendBuffer(data); + } + catch (err) { + // Synchronous errors come from prepare append algorithm + // https://www.w3.org/TR/media-source/#sourcebuffer-prepare-append + switch (err.code) { + case 22: { + // QuotaExceededError: http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror + // let's stop appending any segments, and report BUFFER_FULL_ERROR error + this.mediaElementStore.setBufferedRangesUpdated(this.type, BufferHelper.timeRangesToBufferedRange(this.sourceBuffer.buffered), BufferHelper.timeRangesToBufferedRange(this.mediaElement.buffered), true, this.config); + return throwError(new BufferFullError(err.message, ErrorResponses.AllocationFailed, this.type, this.maxTotalBytes)); + } + default: + this.mediaElementStore.setInflightSegment(this.type, null); + if (this.mediaElement.error) { + return throwError(new MediaDecodeError(err.message, ErrorResponses.VideoDecoderBadDataErr, this.type, mediaOptionId)); + } + // 1. buffer removed from MediaSource + // 2. updating === true + // 3. other reason + return throwError(err); + } + } + return this._waitForUpdateEndOrError().pipe(map(() => ({ + startAppend: startAppend, + endAppend: performance.now(), + bytesAppend: data.byteLength, + })), timeout(APPEND_MAX_MS), catchError((err) => { + if (err instanceof TimeoutError) { + this.sourceBuffer.abort(); + err = new AppendTimeoutError(`Append took longer than ${APPEND_MAX_MS}ms`, ErrorResponses.InternalError, this.type); + } + else if (err instanceof SourceBufferError) { + err = new MediaDecodeError('Decode error', ErrorResponses.VideoDecoderBadDataErr, this.type, mediaOptionId); + } + throw err; // always throw + })); + } + remove(start, end) { + return this._waitForUpdateEndOrError().pipe(switchMap(this._removeAsync.bind(this, start, end))); + } + _removeAsync(start, end) { + try { + this.sourceBuffer.remove(start, end); + } + catch (err) { + return throwError(new SourceBufferError(ErrorDetails.INTERNAL_EXCEPTION, false, err.message, ErrorResponses.InternalError, this.type)); + } + return this._waitForUpdateEndOrError(); + } + abort() { + try { + this.sourceBuffer.abort(); + } + catch (err) { + return throwError(new SourceBufferError(ErrorDetails.INTERNAL_EXCEPTION, false, err.message, ErrorResponses.InternalError, this.type)); + } + return this._waitForUpdateEndOrError(); + } + get updating() { + return this.sourceBuffer.updating; + } + get timestampOffset() { + return this.sourceBuffer.timestampOffset; + } + set timestampOffset(value) { + this.sourceBuffer.timestampOffset = value; + } + /** + * Whether we ever got QuotaExceeded error + */ + get gotQuotaExceeded() { + var _a, _b; + return (_b = (_a = this.mediaElementQuery.sourceBufferEntityByType(this.type)) === null || _a === void 0 ? void 0 : _a.gotQuotaExceeded) !== null && _b !== void 0 ? _b : false; + } + /** + * Which segments we think are in the buffer + */ + get bufferedSegments() { + var _a, _b; + return (_b = (_a = this.mediaElementQuery.sourceBufferEntityByType(this.type)) === null || _a === void 0 ? void 0 : _a.bufferedSegments) !== null && _b !== void 0 ? _b : []; + } + /** + * Currently appended byte total + */ + get totalBytes() { + var _a, _b; + return (_b = (_a = this.mediaElementQuery.sourceBufferEntityByType(this.type)) === null || _a === void 0 ? void 0 : _a.totalBytes) !== null && _b !== void 0 ? _b : 0; + } + /** + * Max number of bytes we estimate this SourceBuffer can hold + */ + get maxTotalBytes() { + var _a, _b; + const maxTotalBytes = (_b = (_a = this.mediaElementQuery.sourceBufferEntityByType(this.type)) === null || _a === void 0 ? void 0 : _a.maxTotalBytes) !== null && _b !== void 0 ? _b : Infinity; + return this.gotQuotaExceeded ? maxTotalBytes : Infinity; + } + _waitForUpdateEndOrError() { + if (this.sourceBuffer.updating) { + // Just in case we haven't fired updatestart yet + this.mediaElementStore.setSourceBufferUpdating(this.type); + } + // Ensures we have up to date buffered range values by using updating$ + return this.mediaElementQuery.sbUpdating$(this.type).pipe(filter((updating) => updating === false), withLatestFrom(this.mediaElementQuery.sbError$(this.type)), map(([_updating, error]) => { + if (error) { + throw new SourceBufferError(ErrorDetails.INTERNAL_EXCEPTION, false, 'Got error during sourceBuffer operation', ErrorResponses.InternalError, this.type); + } + return undefined; + }), take(1)); + } + } + + /** + * Observable MediaSOurce adapter that cleans up after itself on unsubscribe + * From src/mse-rxjs/mediasource-adapter.ts + */ + class MediaSourceAdapter extends Observable { + constructor(mediaElement, mediaElementStore, mediaElementQuery, mediaSource, logger) { + // Register for events. This updates the mediaElementStore and also sets up teardown + // when this object is unsubscribed from + super((subscriber) => { + const target = fromEventTarget(mediaSource); + const readyStateChange$ = merge(target.event('sourceopen'), target.event('sourceclose'), target.event('sourceended')).pipe(tap((event) => { + var _a; + // Vuze doesn't implement event + const ms = (_a = event === null || event === void 0 ? void 0 : event.target) !== null && _a !== void 0 ? _a : mediaSource; + const readyState = ms.readyState; + mediaElementStore.msReadyState = readyState; + })); + const sourceBuffers$ = this.sourceBuffers$.pipe(switchMap((sbTuple) => { + if (!sbTuple) + return EMPTY; + return merge(...sbTuple.filter((info) => info != null)); + })); + const sub = merge(readyStateChange$, sourceBuffers$) + .pipe(switchMap(() => EMPTY)) + .subscribe(subscriber); + const objectUrl = URL.createObjectURL(mediaSource); + mediaElement.src = objectUrl; + logger.info(`set MediaSource ${objectUrl}`); + mediaElementStore.setMediaSourceEntity(objectUrl, mediaSource.readyState); + return () => { + sub.unsubscribe(); + // Hand off clean up to teardownWorker to avoid race with clearMediaKeys + logger.info(`remove MediaSource ${objectUrl}`); + URL.revokeObjectURL(objectUrl); + if (mediaElement.src === objectUrl) { + mediaElement.removeAttribute('src'); + mediaElement.load(); + mediaElementStore.setMediaSourceEntity(null); + } + this.sourceBuffers$.next(null); + }; + }); + this.mediaElement = mediaElement; + this.mediaElementStore = mediaElementStore; + this.mediaElementQuery = mediaElementQuery; + this.mediaSource = mediaSource; + this.logger = logger; + this.sourceBuffers$ = new BehaviorSubject(null); + } + get readyState() { + return this.mediaSource.readyState; + } + set duration(value) { + this.mediaSource.duration = value; + } + get duration() { + return this.mediaSource.duration; + } + endOfStream(error) { + this.mediaSource.endOfStream(error); + } + createSourceBuffers(compatInfoTuple, config) { + const mediaSource = this.mediaSource; + applyTransaction(() => { + try { + const newSbs = [null, null]; + compatInfoTuple.forEach((compatInfo, type) => { + if (compatInfo) { + const { mimeType, mediaOptionId } = compatInfo; + let sb; + try { + sb = mediaSource.addSourceBuffer(mimeType); + this.logger.info(`[${SourceBufferNames[type]}]: sourceBuffer added ${mimeType}`); + } + catch (err) { + throw new CreateSourceBufferError(err.message, ErrorResponses.IncompatibleAsset, type, mediaOptionId); + } + newSbs[type] = new SourceBufferAdapter(this.mediaElementStore, this.mediaElementQuery, this.mediaElement, this.mediaSource, type, sb, compatInfo, this.logger, config); + } + }); + this.sourceBuffers$.next(newSbs); + } + catch (err) { + if (!(err instanceof HlsError)) { + throw new MseError(`error initializing sourcebuffers ${err.message} readyState=${mediaSource.readyState}`); + } + throw err; + } + }); + } + get needSourceBuffers() { + return this.sourceBuffers$.value == null || this.sourceBuffers$.value[0] == null; + } + get sourceBuffers() { + return this.sourceBuffers$.value; + } + getSourceBufferByType(type) { + const sbAdapterTuple = this.sourceBuffers$.value; + if (!sbAdapterTuple) { + return null; + } + return sbAdapterTuple[type]; + } + updateLiveSeekableRange(start, end) { + const mediaSource = this.mediaSource; + if ((mediaSource === null || mediaSource === void 0 ? void 0 : mediaSource.setLiveSeekableRange) && (mediaSource === null || mediaSource === void 0 ? void 0 : mediaSource.readyState) === 'open') { + this.logger.debug(`setLiveSeekableRange range called with ${start} to ${end}`); + mediaSource.setLiveSeekableRange(start, end); + } + } + clearLiveSeekableRange() { + const mediaSource = this.mediaSource; + if ((mediaSource === null || mediaSource === void 0 ? void 0 : mediaSource.clearLiveSeekableRange) && (mediaSource === null || mediaSource === void 0 ? void 0 : mediaSource.readyState) === 'open') { + this.logger.debug('clearLiveSeekableRange called'); + mediaSource.clearLiveSeekableRange(); + } + } + } + + const MIN_STALL_CHECK_MS = 100; // Minimum time for next check + function shouldCheckForStall(pos, desiredRate, ended, combinedBuffer, seeking) { + const isBuffered = combinedBuffer.some((r) => r.start <= pos && r.end > pos); + return !(desiredRate !== 1 || ended || combinedBuffer.length === 0 || (seeking && !isBuffered)); + } + /** + * monitors the media element for stalling in low and high buffer or on seek + * It will update media store with information about the stall if the position has not changed + * after the configured period. emits stall info if stall is detected, null if we're not stalled + */ + function stallMonitor(logger, meQuery, config) { + const { lowBufferThreshold, lowBufferWatchdogPeriod, highBufferWatchdogPeriod, seekWatchdogPeriod } = config; + const shouldCheckForStall$ = combineQueries([meQuery.desiredRate$, meQuery.ended$, meQuery.combinedBuffer$, meQuery.seekTo$]).pipe(map((state) => { + const [desiredRate, ended, combinedBuffer, seekTo] = state; + const currentTime = meQuery.currentTime; + const seeking = isFinite(seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos); + return shouldCheckForStall(currentTime, desiredRate, ended, combinedBuffer, seeking); + }), distinctUntilChanged()); + const combinedBufferChanged$ = meQuery.combinedBuffer$.pipe(map(() => { + return meQuery.getCurrentWaterLevel(0) <= config.lowBufferThreshold || !meQuery.haveEnough ? StallType.LowBuffer : StallType.HighBuffer; + }), distinctUntilChanged()); + const gotStall$ = combineQueries([shouldCheckForStall$, meQuery.seekTo$, meQuery.gotPlaying$, combinedBufferChanged$]).pipe(switchMap((state) => { + const [shouldCheckForStall, seekTo, gotPlaying] = state; + logger.debug(`[stall] state=${stringifyWithPrecision({ shouldCheckForStall, seekTo, gotPlaying })}`); + if (!shouldCheckForStall) { + return of(null); + } + // some systems need longer wait period for seeks / playback resume, use backoff period + const backoffSec = 1; + const nudgeCount = meQuery.nudgeCount; + const seekPeriodSec = seekWatchdogPeriod + nudgeCount * backoffSec; + const seeking = isFinite(seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos); + if (seeking || !gotPlaying) { + logger.debug(`[stall] start seek stall watchdog period=${seekPeriodSec}s`); + return startSeekStallWatchdog(meQuery, performance.now(), seekPeriodSec, lowBufferThreshold); + } + const highBufferPeriodSec = highBufferWatchdogPeriod + nudgeCount * backoffSec; + logger.debug(`[stall] start playing stall watchdog low period=${lowBufferWatchdogPeriod} high period=${highBufferPeriodSec}`); + return startPlayingStallWatchdog(meQuery, logger, lowBufferWatchdogPeriod, highBufferPeriodSec, lowBufferThreshold); + })); + const gotResume$ = gotStall$.pipe(filterNullOrUndefined(), withLatestFrom(meQuery.combinedBuffer$), switchMap(([stallInfo, combinedBuffer]) => { + logger.debug(`[stall] got stall ${stringifyWithPrecision(stallInfo)} buffered:${stringifyWithPrecision(combinedBuffer)}`); + return combineQueries([meQuery.seeking$, meQuery.paused$]); + }), switchMap(([seeking, paused]) => { + if (seeking || paused) { + return EMPTY; + } + return meQuery.timeupdate$.pipe(pairwise(), filter(([a, b]) => isFiniteNumber(a) && isFiniteNumber(b) && b > a), take(1)); + }), map(() => { + logger.info('[stall] resume from stall'); + return null; + })); + return merge(gotStall$, gotResume$); + } + // start seek watchdog timer. Assumed that at start, seeking || !playing + // Fire if time from (seeking -> playing) or (seeked -> playing) >= seekWatchdogPeriod + function startSeekStallWatchdog(meQuery, tstalled, seekWatchdogPeriod, lowBufferThreshold) { + return timer(seekWatchdogPeriod * 1000).pipe(map(() => { + const currentTime = meQuery.currentTime; + const bufferInfo = meQuery.getCombinedBufferInfo(currentTime, 0); + return makeStallInfo(StallType.Seek, currentTime, tstalled, bufferInfo, lowBufferThreshold, meQuery.haveEnough); + })); + } + // start playing watchdog timer: when now - tlastCurrentTime > low or high buffer watchdog period + function startPlayingStallWatchdog(meQuery, logger, lowBufferWatchdogPeriod, highBufferWatchdogPeriod, lowBufferThreshold) { + // Current position hasn't changed for some period of time + return merge(of(meQuery.currentTime), meQuery.timeupdate$).pipe(switchMap((lastCurrentTime) => { + const tstalled = performance.now(); + const bufferInfo = meQuery.getCombinedBufferInfo(lastCurrentTime, 0); + let type; + let watchdogPeriod; // How long from reference point to schedule the check + const bufferLenSec = bufferInfo.len; + // prettier-ignore + if ((bufferLenSec <= lowBufferThreshold) || !meQuery.haveEnough) { + watchdogPeriod = lowBufferWatchdogPeriod; + type = StallType.LowBuffer; + } + else { + watchdogPeriod = highBufferWatchdogPeriod; + type = StallType.HighBuffer; + } + const stallCheckMs = Math.max(MIN_STALL_CHECK_MS, watchdogPeriod * 1000); + return timer(stallCheckMs).pipe(map(() => { + // Check once to see if playback has moved ahead before making stallInfo Object + // On Roku 'timeupdate' event (aka meQuery.timeupdate$ triggers) are inconsistent. + if (lastCurrentTime < meQuery.currentTime) { + return null; + } + return makeStallInfo(type, lastCurrentTime, tstalled, bufferInfo, lowBufferThreshold, meQuery.haveEnough); + })); + })); + } + /** + * Check if we've changed positions since we armed the timers + */ + function makeStallInfo(type, currentTime, tstalled, bufferInfo, lowBufferThreshold, haveEnough) { + const now = performance.now(); + const stallDurationMs = now - tstalled; + const bufferLenSec = bufferInfo.len; + // prettier-ignore + const isLowBufferStall = (bufferLenSec <= lowBufferThreshold) || !haveEnough; + return { type, isLowBufferStall, tstalled, stallDurationMs, currentTime }; + } + + class MediaSink extends Observable { + constructor(mediaElement, mediaElementStore, config, hlsGapless, logger, teardownWG$, rtcService) { + super((subscriber) => { + this.logger.info('subscribe MediaSink'); + const config = this.config; + const sessionId = mediaElementStore.startMediaSession(mediaElement, config.maxBufferLength, config.almostDryBufferSec, config.defaultTargetDuration); + const mediaElementEvents$ = hookMediaElementsEvents(mediaElement, mediaElementStore, this._mediaQuery, this, this.hlsGapless, config, this.logger, this.rtcService); + const mediaSource$ = this.mediaSource$.pipe(switchMap((ms) => ms || EMPTY)); + const seeks$ = this._mediaQuery.seekTo$.pipe(seekEpic(mediaElement, this._mediaQuery, this, this.config, this.logger)); + const rateChange$ = this._mediaQuery.desiredRate$.pipe(rateChangeEpic(mediaElement, this._mediaQuery, this)); + this.liveSeekableWindow = { start: NaN, end: NaN }; + // setup media functions overrides + this.mediaFunctions = this.mediaFunctions || new MediaFunctions(this, mediaElement, config, this.logger); + this.mediaFunctions.install(); + const stallHandling$ = merge(stallMonitor(this.logger, this._mediaQuery, this.config).pipe(tap((stallInfo) => { + mediaElementStore.setStallInfo(stallInfo); + })), this.mediaQuery.stallInfo$.pipe(stallEpic(this, mediaElementStore, this.config, this.logger))); + const bufferMonitor$ = bufferMonitorEpic(this.mediaQuery, mediaElementStore, config.maxBufferHole); + merge(mediaElementEvents$, mediaSource$, seeks$, rateChange$, stallHandling$, bufferMonitor$) + .pipe(switchMapTo(EMPTY), finalize$1(() => { + this.logger.info('finalize MediaSink'); + mediaElementStore.remove(sessionId); + this.mediaFunctions.uninstall(); + this.mediaFunctions = undefined; + })) + .subscribe(subscriber); // Propagates any errors up + // extra teardown ? + }); + this.mediaElement = mediaElement; + this.mediaElementStore = mediaElementStore; + this.config = config; + this.hlsGapless = hlsGapless; + this.logger = logger; + this.teardownWG$ = teardownWG$; + this.rtcService = rtcService; + this.mediaSource$ = new BehaviorSubject(null); + // We use a Mutex here because only one setMediaKeys() can run at one time, + // and multiple setMediaKeys() operations can be queued for execution from + // different threads. Since it's the only type of operation needs + // synchronization in the MediaSink component, using a Mutex makes more sense + // than converting to command queue pattern. + this.mediaKeysMutex = new Mutex(); + this._mediaQuery = new MediaElementQuery(mediaElement, mediaElementStore); + this.logger = logger.child({ name: 'mse' }); + // Muze/Vuze: Need to create id3 text track before MEDIA_ATTACHED + this.createId3Track(mediaElement); + this.mediaFunctions = new MediaFunctions(this, mediaElement, config, this.logger); + } + get mediaSourceAdapter() { + return this.mediaSource$.value; + } + get sourceBuffers() { + var _a, _b; + return (_b = (_a = this.mediaSourceAdapter) === null || _a === void 0 ? void 0 : _a.sourceBuffers) !== null && _b !== void 0 ? _b : []; + } + get needSourceBuffers() { + return this.sourceBuffers[0] ? false : true; + } + get mediaQuery() { + return this._mediaQuery; + } + sourceBuffersBufferedRangeByType(type) { + var _a, _b; + const sb = (_b = (_a = this.mediaSourceAdapter) === null || _a === void 0 ? void 0 : _a.sourceBuffers) === null || _b === void 0 ? void 0 : _b[type]; + if (sb) { + return BufferHelper.timeRangesToBufferedRange(sb.sourceBuffer.buffered); + } + else { + return null; + } + } + createId3Track(mediaElement) { + this.logger.info('create id3 texttrack'); + this.id3Track = mediaElement.addTextTrack('metadata', 'id3'); + this.id3Track.mode = 'hidden'; + } + /** + * Check if mediaElementStore buffer values are in-sync with real SourceBuffer + * especially when trying to seek. + */ + checkForInconsistentStoreBufferRangesAndUpdate() { + var _a, _b, _c, _d; + const mediaElementTimeRanges = BufferHelper.timeRangesToBufferedRange(this.mediaElement.buffered); + const realVariantBufferedRanges = this.sourceBuffersBufferedRangeByType(SourceBufferType.Variant); + const realAltAudioBufferedRanges = this.sourceBuffersBufferedRangeByType(SourceBufferType.AltAudio); + const storeVariantBufferedRanges = (_b = (_a = this.mediaQuery.sourceBufferEntityByType(SourceBufferType.Variant)) === null || _a === void 0 ? void 0 : _a.bufferedRanges) !== null && _b !== void 0 ? _b : null; + const storeAltAudioBufferedRanges = (_d = (_c = this.mediaQuery.sourceBufferEntityByType(SourceBufferType.AltAudio)) === null || _c === void 0 ? void 0 : _c.bufferedRanges) !== null && _d !== void 0 ? _d : null; + // If there is discrepency with any of sourceBufferRanges then update store values + if (this.shouldUpdateStoreValues(realVariantBufferedRanges, storeVariantBufferedRanges)) { + this.logger.warn(`[${SourceBufferNames[SourceBufferType.Variant]}] SourceBuffer's loaded bufferedRanges ${JSON.stringify(realVariantBufferedRanges)} & mediaElementStore's bufferedRanges ${JSON.stringify(storeVariantBufferedRanges)} are out of sync!`); + this.updateMediaElementStoreBufferedRanges(mediaElementTimeRanges, SourceBufferType.Variant); + } + if (this.shouldUpdateStoreValues(realAltAudioBufferedRanges, storeAltAudioBufferedRanges)) { + this.logger.warn(`[${SourceBufferNames[SourceBufferType.AltAudio]}] SourceBuffer's loaded bufferedRanges ${JSON.stringify(realAltAudioBufferedRanges)} & mediaElementStore's bufferedRanges ${JSON.stringify(storeAltAudioBufferedRanges)} are out of sync!`); + this.updateMediaElementStoreBufferedRanges(mediaElementTimeRanges, SourceBufferType.AltAudio); + } + } + shouldUpdateStoreValues(sbLoadedTimeRanges, storeBufferedRanges) { + if (sbLoadedTimeRanges == null && storeBufferedRanges == null) { + return false; + } + // Unequal lengths then we need updating + if ((sbLoadedTimeRanges === null || sbLoadedTimeRanges === void 0 ? void 0 : sbLoadedTimeRanges.length) != (storeBufferedRanges === null || storeBufferedRanges === void 0 ? void 0 : storeBufferedRanges.length)) { + return true; + } + // If there is discrepency with any of the loaded Ranges then update store values + return !!sbLoadedTimeRanges.find((sbCurrentLoadedTimeRange) => { + const binarySearchcompareFunction = (storeCurrentInterval) => { + if (sbCurrentLoadedTimeRange.start >= storeCurrentInterval.start && sbCurrentLoadedTimeRange.end <= storeCurrentInterval.end) { + return 0; + } + else if (sbCurrentLoadedTimeRange.end < storeCurrentInterval.start) { + return -1; + } + else { + return 1; + } + }; + // Binary search as SourceBuffer.buffered is normalized TimeRanges object. + const matchingStoreBufferedRange = BinarySearch.search(storeBufferedRanges, binarySearchcompareFunction); + // If no match we need updating + if (matchingStoreBufferedRange == null) { + return true; + } + if (matchingStoreBufferedRange.start != sbCurrentLoadedTimeRange.start || matchingStoreBufferedRange.end != sbCurrentLoadedTimeRange.end) { + return true; + } + }); + } + /** + * Update mediaElementStore with latest from SourceBuffers. + */ + updateMediaElementStoreBufferedRanges(mediaElementBuffered, type) { + const sb = this.sourceBuffersBufferedRangeByType(type); + if (sb && !this.mediaQuery.sbUpdating(type)) { + this.logger.info(`[${SourceBufferNames[type]}] Updating buffer status`); + this.mediaElementStore.setBufferedRangesUpdated(type, sb, mediaElementBuffered, false, this.config); + } + } + destroyMediaSource() { + this.mediaSource$.next(null); + } + // Can stub over this for testing if needed + makeMediaSource() { + return new MediaSource(); + } + openMediaSource(mediaSource) { + applyTransaction(() => { + if (mediaSource) { + const mediaAdapter = new MediaSourceAdapter(this.mediaElement, this.mediaElementStore, this.mediaQuery, mediaSource, this.logger); + this.mediaSource$.next(mediaAdapter); + } + else { + this.mediaSource$.next(null); + } + }); + } + createSourceBuffers(compatInfoTuple) { + this.logger.info(`createSourceBuffers ${JSON.stringify(compatInfoTuple.map((c) => c === null || c === void 0 ? void 0 : c.mimeType))}`); + const msAdapter = this.mediaSource$.value; + if (!msAdapter) { + throw new Error('createSourceBuffers empty mediaSource'); + } + msAdapter.createSourceBuffers(compatInfoTuple, this.config); + } + _waitForMediaSourceOpen(appendData) { + const msObjectUrl = this.mediaQuery.mediaSourceEntity.objectUrl; // msAdapter at the start of wait + return combineQueries([this.mediaQuery.msReadyState$, this.mediaQuery.msObjectUrl$]).pipe(switchMap(([state, msUrl]) => { + if (msUrl !== msObjectUrl) { + this.logger.info('media source changed while waiting'); + return of(null); + } + if (state === 'open' || state === 'ended') { + // Can append again even if ended + return of(appendData); + } + return EMPTY; + })); + } + get appendOrder() { + return this.mediaQuery.isIframeRate ? [SourceBufferType.Variant, SourceBufferType.AltAudio] : [SourceBufferType.AltAudio, SourceBufferType.Variant]; + } + clearFlush(appendData) { + appendData.forEach((sbData) => { + if (sbData) { + // hls will not reset the MediaOptionSwitchContext if flushBeforeAppend is null/undefined. + sbData.dataSeg.flushBeforeAppend = { start: 0, end: 0 }; + } + }); + } + getSwitchPosition(appendData) { + return appendData.reduce((prevSwitchPos, next) => { + const switchPos = next ? next.dataSeg.switchPosition : undefined; + if (isFiniteNumber(switchPos)) { + return isFiniteNumber(prevSwitchPos) ? Math.min(prevSwitchPos, switchPos) : switchPos; + } + else { + return prevSwitchPos; + } + }, undefined); + } + checkForReplay() { + const media = this.mediaElement; + // rdar://80790960 ([HLS JS 2.1 beta] Marcom - Retry playback fails). Pulled from 2.0 stream-controller.ts. + if (media.paused && !media.seeking && media.duration && media.currentTime && media.currentTime >= media.duration - this.config.maxTotalDurationTolerance) { + this.seekTo = 0; // auto-restart if scrubber is at end of video. media.ended may be reset upon seek or append. + } + } + /** + * Reset media source if needed and wait for 'open' + * @returns an observable that emits AppendDataTuple if we should append, null if we something did a reset + */ + resetMediaSourceIfNeeded(appendData) { + const { mediaQuery } = this; + const { sourceBufferEntities } = mediaQuery; + const { expectedSbCount } = mediaQuery.getActive(); + if (!sourceBufferEntities || this.needSourceBuffers) { + this.logger.info('need source buffers #disco'); + return this._waitForMediaSourceOpen(appendData); + } + const compatInfo = isCompatibleWithSourceBuffers(appendData, sourceBufferEntities, expectedSbCount, this.config.maxBufferHole, this.logger); + if (compatInfo.compatible) { + this.logger.info('got compatible source buffers #disco'); + this.logger.qe({ critical: true, name: 'disco', data: { type: 'compatible' } }); + return this._waitForMediaSourceOpen(appendData); + } + let boundary = compatInfo.boundary; + const boundaryAllowance = compatInfo.allowance; + const requestedSwitchPos = this.getSwitchPosition(appendData); + if (isFiniteNumber(requestedSwitchPos)) { + this.logger.info(`override boundary with switch position=${boundary.toFixed(3)}->${requestedSwitchPos}`); + boundary = requestedSwitchPos; + } + if (!isFiniteNumber(boundary)) { + this.logger.warn('not enough info #disco'); + return of(null); + } + this.logger.info(`start wait pos=${mediaQuery.currentTime.toFixed(3)} boundary=${boundary.toFixed(3)} allowance=${boundaryAllowance.toFixed(3)} #disco`); + this.logger.qe({ critical: true, name: 'disco', data: { type: 'incompatible' } }); + const hitDiscoBoundary$ = race( + // Play or seek across boundary (0 tolerance) + waitFor(merge(of(mediaQuery.currentTime), mediaQuery.timeupdate$), (pos) => pos >= boundary), + // Stalled playback and we're close enough + waitFor(mediaQuery.stallInfo$.pipe(map((stallInfo) => { var _a; return (_a = stallInfo === null || stallInfo === void 0 ? void 0 : stallInfo.currentTime) !== null && _a !== void 0 ? _a : NaN; })), (pos) => pos >= boundary - boundaryAllowance - this.config.discontinuitySeekTolerance)); + this.mediaElementStore.waitingForDisco = true; + return hitDiscoBoundary$.pipe(mapTo(boundary), switchMap((boundary) => { + const startResetTime = performance.now(); + const currentTime = mediaQuery.currentTime; + this.logger.info(`end wait pos=${currentTime.toFixed(3)} boundary=${boundary.toFixed(3)} #disco`); + this.logger.qe({ critical: true, name: 'disco', data: { type: 'resetStart' } }); + const duration = this.msDuration; + this.resetMediaSource(Math.max(currentTime, boundary), compatInfo.discoSeqNum); + return this._waitForMediaSourceOpen(appendData).pipe(tap(() => { + const resetDuration = performance.now() - startResetTime; + this.logger.qe({ critical: true, name: 'disco', data: { type: 'resetComplete', resetDuration } }); + this.msDuration = duration; + })); + }), finalize$1(() => { + this.mediaElementStore.waitingForDisco = false; + })); + } + /** + * @brief External hard media reset + * @param position The position to seek to on reset. NaN means use current seekTo or currentTime. seekTo has precedence > currentTime + */ + resetMediaSource(position = NaN, discoSeqNum) { + var _a, _b, _c; + this.logger.info(`resetMediaSource ${position} ${discoSeqNum}`); + if (!isFiniteNumber(position)) { + position = (_b = (_a = this.mediaQuery.seekTo) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : this.mediaQuery.currentTime; + } + if (!isFiniteNumber(discoSeqNum)) { + discoSeqNum = (_c = this.mediaQuery.seekTo) === null || _c === void 0 ? void 0 : _c.discoSeqNum; + } + if (this.sourceBuffers.length > 0) { + this.openMediaSource(this.makeMediaSource()); + this.logger.info(`resetMediaSource seek=${position} cc=${discoSeqNum}`); + this.setSeekToWithDiscontinuity(position, discoSeqNum); // always update after reset, use given cc + } + } + setExpectedSbCount(sbCount) { + this.mediaElementStore.expectedSbCount = sbCount; + } + appendInitSegments(appendData, appendErrorPolicy) { + const { mediaQuery, mediaElementStore, sourceBuffers, logger } = this; + const { sourceBufferEntities } = mediaQuery; + if (!sourceBuffers) { + throw new Error('appendInitSegments: null sourceBuffers'); + } + if (!sourceBufferEntities) { + throw new Error('appendInitSegments: null sourceBufferEntities'); + } + const initAppendOps$ = this.appendOrder + .map((type) => { + const sbDataTuple = appendData[type]; + if (!sbDataTuple) + return; + const sb = sourceBuffers[type]; + const sbAppendData = appendData[type]; + const currentSbEntity = sourceBufferEntities[type]; + const { initSeg } = sbAppendData; + if (!currentSbEntity) { + throw new Error(`appendInitSegments: sb[${SourceBufferNames[type]}] null currentSbEntity`); + } + if (!sb) { + throw new Error(`appendInitSegments: sb[${SourceBufferNames[type]}] null source buffer`); + } + const curInitInfo = currentSbEntity.initSegmentInfo; + const newInitInfo = cacheEntityToInfoEntity(initSeg); + if (initSegmentEquals(newInitInfo, curInitInfo)) { + logger.debug(`[${MediaOptionNames[type]}] skip init segment append ${JSON.stringify(newInitInfo)}`); + return of(null); // noop + } + const mediaOptionType = sourceBufferTypeToMediaOptionType(type); + return sb.appendBuffer(initSeg.data, initSeg).pipe(tap((am) => { + logger.info(`[${MediaOptionNames[type]}] append init segment ${JSON.stringify(newInitInfo)} ${am === null || am === void 0 ? void 0 : am.startAppend}/${am === null || am === void 0 ? void 0 : am.endAppend}/${am === null || am === void 0 ? void 0 : am.bytesAppend}`); + mediaElementStore.setInitSegmentEntity(type, newInitInfo); + }), appendErrorPolicy(sb, mediaOptionType, initSeg.mediaOptionId, this.config, this.mediaQuery)); + }) + .filter((initAppendOp) => Boolean(initAppendOp)); + if (initAppendOps$.length === 0) { + return of(null); // noop + } + return forkJoin(initAppendOps$); + } + appendDataSegments(appendData, appendErrorPolicy) { + const dataAppendOps$ = this.appendOrder + .map((type) => { + const sbDataTuple = appendData[type]; + const { mediaQuery, sourceBuffers, logger } = this; + const { sourceBufferEntities } = mediaQuery; + if (!sourceBuffers) { + throw new Error('appendDataSegments: null sourceBuffers'); + } + if (!sourceBufferEntities) { + throw new Error('appendDataSegments: null sourceBufferEntities'); + } + if (!sbDataTuple) + return null; + const sb = sourceBuffers[type]; + const sbAppendData = appendData[type]; + const currentSbEntity = sourceBufferEntities[type]; + if (!currentSbEntity) { + throw new Error('appendDataSegments: null currentSbEntity'); + } + const currentInitSegmentInfo = currentSbEntity.initSegmentInfo; + const { dataSeg } = sbAppendData; + if (!currentInitSegmentInfo) { + throw new Error(`appendDataSegments: sb[${SourceBufferNames[type]}] null currentInitSegmentInfo`); + } + if (!currentSbEntity) { + throw new Error(`appendDataSegments: sb[${SourceBufferNames[type]}] null currentSbEntity`); + } + if (!sb) { + throw new Error(`appendDataSegments: sb[${SourceBufferNames[type]}] null source buffer`); + } + const timestampOffset = sb.timestampOffset; + const startPTS = convertTimestampToSeconds(dataSeg.startPts) + timestampOffset; + const endPTS = convertTimestampToSeconds(dataSeg.endPts) + timestampOffset; + const firstKeyframePts = dataSeg.firstKeyframePts ? convertTimestampToSeconds(dataSeg.firstKeyframePts) + timestampOffset : undefined; + const seginfo = { + startPTS, + endPTS, + firstKeyframePts, + bytes: dataSeg.data2 ? dataSeg.data1.byteLength + dataSeg.data2.byteLength : dataSeg.data1.byteLength, + frag: { + itemId: dataSeg.itemId, + mediaOptionId: dataSeg.mediaOptionId, + mediaSeqNum: dataSeg.mediaSeqNum, + discoSeqNum: dataSeg.discoSeqNum, + keyTagInfo: dataSeg.keyTagInfo, + isLastFragment: dataSeg.isLastFragment, + iframe: dataSeg.iframe, + framesWithoutIDR: dataSeg.framesWithoutIDR, + dropped: dataSeg.dropped, + }, + }; + const mediaOptionType = sourceBufferTypeToMediaOptionType(type); + let optionalFlush = VOID; + const flushRange = sbDataTuple.dataSeg.flushBeforeAppend; + if (flushRange && flushRange.start !== flushRange.end) { + logger.info(`sb[${SourceBufferNames[type]}] flush [${flushRange.start},${flushRange.end}] before append`); + optionalFlush = this.flushData(type, flushRange.start, flushRange.end); + } + return optionalFlush.pipe(switchMap(() => { + const source = of(dataSeg.data1, dataSeg.data2).pipe(filterNullOrUndefined()); + return source.pipe(concatMap((data) => { + logger.info(`[${MediaOptionNames[type]}] appending timestampOffset:${currentSbEntity.timestampOffset} segment:${stringifyWithPrecision({ + startPTS, + endPTS, + frag: fragPrint(dataSeg), + key: redactUrl(dataSeg.keyTagInfo.uri), + })}`); + return sb.appendBuffer(data, seginfo).pipe(appendErrorPolicy(sb, mediaOptionType, dataSeg.mediaOptionId, this.config, this.mediaQuery)); + })); + }), tap(() => { + const bufferedRanges = mediaQuery.getBufferedRangeByType(type); + logger.info(`[${MediaOptionNames[type]}] appended pos:${mediaQuery.currentTime.toFixed(3)} buffered:${stringifyWithPrecision(bufferedRanges)}`); + })); + }) + .filter((dataAppendOp) => Boolean(dataAppendOp)); + if (dataAppendOps$.length === 0) { + return of(null); // noop + } + return forkJoin(dataAppendOps$); + } + setStoreSbTimeoffsets(appendDataTuple) { + const { mediaElementStore, sourceBuffers } = this; + sourceBuffers.forEach((sb, type) => { + if (!sb || !appendDataTuple[type]) { + return; + } + const { offsetTimestamp, dataSeg } = appendDataTuple[type]; + const startPts = convertTimestampToSeconds(dataSeg.startPts); + let timestampOffset = convertTimestampToSeconds(offsetTimestamp) * -1; + if (sb.updateMp3Timestamps) { + // Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended) + // in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset` + // is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos). At the time of change we issue + // More info here: https://github.com/video-dev/hls.js/issues/332#issuecomment-257986486 + const delta = Math.abs(sb.timestampOffset - startPts); + // adjust timestamp offset if time delta is greater than 100ms + if (delta > 0.1) { + timestampOffset = startPts + timestampOffset; + } + } + if (sb.timestampOffset !== timestampOffset) { + this.logger.info(`${MediaOptionNames[type]} timestampOffset=${timestampOffset}`); + sb.timestampOffset = timestampOffset; + mediaElementStore.setTimestampOffset(type, sb.timestampOffset); + } + }); + } + adjustJaggedStart(appendData) { + var _a; + const { mediaQuery, logger } = this; + const { sourceBufferEntities, currentTime, seekTo } = mediaQuery; + const appendEndTime = appendData.reduce((end, append) => { + return (append === null || append === void 0 ? void 0 : append.dataSeg.endPts) ? Math.min(diffSeconds(append.dataSeg.endPts, append.offsetTimestamp), end) : end; + }, Number.POSITIVE_INFINITY); + if (!sourceBufferEntities) { + throw new Error('appendSourceBufferData null currentSbEntity'); + } + const position = (seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos) || currentTime; + let seekToPos = NaN; + sourceBufferEntities.forEach((sbEntity, type) => { + if (!sbEntity) + return; + const bufferInfo = BufferHelper.getBufferedInfo(sbEntity.bufferedRanges, position, 0); + if (bufferInfo.len === 0) { + const { nextStart } = bufferInfo; + const tolerance = isFiniteNumber(this.config.jaggedSeekTolerance) ? this.config.jaggedSeekTolerance : 0; + logger.warn(`sb[${SourceBufferNames[type]}] jagged start: ${nextStart} appendEndTime=${appendEndTime} current=${seekToPos} tolerance=${tolerance}`); + if (isFiniteNumber(nextStart) && (!isFiniteNumber(seekToPos) || nextStart - seekToPos > tolerance)) { + seekToPos = nextStart; + } + } + }); + if (isFiniteNumber(seekToPos) && appendEndTime > seekToPos) { + // when appendEndTime < seekToPos, no need to initiate jagged seek. + // wait for subsequent append to fill the buffer. + logger.warn(`[seek] jagged start, adjusting currentTime:${currentTime.toFixed(3)} seekTo=${(_a = seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos) === null || _a === void 0 ? void 0 : _a.toFixed(3)}->${seekToPos} appendEndTime=${appendEndTime}`); + this.seekTo = seekToPos; + } + } + addCues(texttrackIdx, cues) { + const textTrack = this.mediaElement.textTracks[texttrackIdx]; + if (textTrack) { + cues.forEach((cue) => { + textTrack.addCue(cue); + }); + } + } + _flushInternal(sb, start, end) { + return defer(() => { + this.logger.info(`[${SourceBufferNames[sb.type]}] remove(${start},${end}) start`); + return sb.remove(start, end); + }).pipe(tap(() => { + this.logger.info(`[${SourceBufferNames[sb.type]}] remove(${start},${end}) end`); + })); + } + // Flush all source buffers + flushAll(start, end, force = false) { + if (this.sourceBuffers.length === 0) { + return VOID; + } + return forkJoin(this.sourceBuffers.map((sb, type) => (sb ? this.flushData(type, start, end, force) : VOID))).pipe(mapTo(undefined)); + } + flushData(sbType, start, end, force = false) { + var _a; + const { mediaQuery, logger } = this; + this.logger.info(`flushData ${start.toFixed(3)} ${end.toFixed(3)} updating=${(_a = mediaQuery.sourceBufferEntities) === null || _a === void 0 ? void 0 : _a.some((sb) => sb === null || sb === void 0 ? void 0 : sb.updating)}`); + return waitFor(mediaQuery.updating$, (updating) => updating === false).pipe(switchMap(() => { + const { sourceBufferEntities } = mediaQuery; + const sbEntity = sourceBufferEntities[sbType]; + if (sbEntity === null || sbEntity === void 0 ? void 0 : sbEntity.updating) { + this.logger.warn(`trying to flush while updating ${sbType}`); + } + const sb = this.sourceBuffers[sbType]; + if (!sb) { + return VOID; + } + let bufStart; + let bufEnd; + let flushes = VOID; + const flushSingleRange = navigator.userAgent.toLowerCase().indexOf('firefox') === -1; + this.flushing = true; + if (flushSingleRange) { + return this._flushInternal(sb, start, end); + } + // workaround firefox not able to properly flush multiple buffered range. + for (let i = 0; i < sb.buffered.length; i++) { + let flushStart; + let flushEnd; + bufStart = sb.buffered.start(i); + bufEnd = sb.buffered.end(i); + if (end === Infinity) { + flushStart = start; + flushEnd = end; + } + else { + flushStart = Math.max(bufStart, start); + flushEnd = Math.min(bufEnd, end); + } + /* + sometimes sourcebuffer.remove() does not flush + the exact expected time range. + to avoid rounding issues/infinite loop, + only flush buffer range of length greater than 500ms. + */ + if (Math.min(flushEnd, bufEnd) > flushStart && (force || Math.min(flushEnd, bufEnd) - flushStart > 0.5)) { + flushes = flushes.pipe(switchMapTo(this._flushInternal(sb, flushStart, flushEnd))); + } + else { + logger.warn(`ignoring sb[${SourceBufferNames[sbType]}] flush ${flushStart},${flushEnd}`); + } + } + return flushes; + }), finalize$1(() => { + // clear flushing + this.flushing = false; + })); + } + static convertInitSegToCompatInfo(initSeg) { + return { + mimeType: initSeg.mimeType, + audioCodec: initSeg.initParsedData.audioCodec, + videoCodec: initSeg.initParsedData.videoCodec, + startPTSSec: undefined, + endPTSSec: undefined, + discoSeqNum: initSeg.discoSeqNum, + mediaOptionId: initSeg.mediaOptionId, + }; + } + static combineAppendDataInfoWithCompatInfo(appendData, oldCompatInfoTuple, highestVideoCodec, logger = null) { + const newCompatInfo = [...oldCompatInfoTuple]; + appendData.forEach((d, type) => ((d === null || d === void 0 ? void 0 : d.initSeg) ? (newCompatInfo[type] = MediaSink.convertInitSegToCompatInfo(d.initSeg)) : null)); + const currentVideoCodecString = newCompatInfo[SourceBufferType.Variant].videoCodec; + const currentVideoCodecFamily = getVideoCodecFamily(currentVideoCodecString); + // Replace to highest video codec string. + if (highestVideoCodec && highestVideoCodec.has(currentVideoCodecFamily)) { + // if configured to use highestCodec + const highestVideoCodecString = highestVideoCodec.get(currentVideoCodecFamily); + logger === null || logger === void 0 ? void 0 : logger.info(`override with highest video codec ${highestVideoCodecString}`); + newCompatInfo[SourceBufferType.Variant].mimeType = newCompatInfo[SourceBufferType.Variant].mimeType.replace(currentVideoCodecString, highestVideoCodecString); + newCompatInfo[SourceBufferType.Variant].videoCodec = highestVideoCodecString; + logger === null || logger === void 0 ? void 0 : logger.info(`compatibility info overrridden from ${currentVideoCodecString} to ${newCompatInfo[SourceBufferType.Variant].videoCodec}/${newCompatInfo[SourceBufferType.Variant].mimeType}`); + } + return newCompatInfo; + } + convertSourceBufferEntitiesToCompatInfo(mediaQuery) { + const sbEntities = mediaQuery.sourceBufferEntities; + const compatInfos = [null, null]; + sbEntities.forEach((sbEntity, type) => { + var _a; + if (!sbEntity) + return; + compatInfos[type] = { + mimeType: sbEntity.mimeType, + audioCodec: sbEntity.audioCodec, + videoCodec: sbEntity.videoCodec, + startPTSSec: undefined, + endPTSSec: undefined, + discoSeqNum: undefined, + // right after resetMediaSource, sbEntity may not have initSegmentInfo yet. + // mediaOptionId to be filled in by combineAppendDataInfoWithCompatInfo before createSourceBuffers. + mediaOptionId: (_a = sbEntity.initSegmentInfo) === null || _a === void 0 ? void 0 : _a.mediaOptionId, + }; + }); + return compatInfos; + } + appendData(appendData, appendErrorPolicy, highestVideoCodec) { + const { mediaQuery, logger } = this; + const oldCompatInfoTuple = this.convertSourceBufferEntitiesToCompatInfo(mediaQuery); + if (appendData.every((data) => data == null)) { + return of([]); // noop + } + return this.resetMediaSourceIfNeeded(appendData).pipe(switchMap((appendData) => { + if (!appendData) { + return of(null); // Got an unexpected reset, stop what we're doing + } + // Don't want updating to trigger switchMap above which will abort the append below. + return mediaQuery.updating$.pipe(filter((updating) => updating === false), take(1), mapTo(appendData)); + }), switchMap((appendData) => { + if (!appendData) { + return of([]); + } + let bufferCreationStart = NaN; + let bufferCreationEnd = NaN; + if (this.needSourceBuffers) { + bufferCreationStart = performance.now(); + const newCompatInfoTuple = MediaSink.combineAppendDataInfoWithCompatInfo(appendData, oldCompatInfoTuple, highestVideoCodec, logger); + this.createSourceBuffers(newCompatInfoTuple); + bufferCreationEnd = performance.now(); + logger.info(`[Buffers] source buffers created start/end: ${bufferCreationStart}/${bufferCreationEnd}`); + this.clearFlush(appendData); + } + appendData.forEach((data) => { + const mediaData = data === null || data === void 0 ? void 0 : data.dataSeg; + if ((mediaData === null || mediaData === void 0 ? void 0 : mediaData.cues) && isFiniteNumber(mediaData === null || mediaData === void 0 ? void 0 : mediaData.texttrackIdx)) { + this.addCues(mediaData.texttrackIdx, mediaData.cues); + } + }); + this.setStoreSbTimeoffsets(appendData); + return concat(defer(() => this.appendInitSegments(appendData, appendErrorPolicy)), defer(() => this.appendDataSegments(appendData, appendErrorPolicy))).pipe(reduce((acc, value) => { + acc.push(value); + return acc; + }, new Array()), map(([initSegmentMetrics, dataSegmentMetrics]) => { + const metrics = [null, null]; + [SourceBufferType.Variant, SourceBufferType.AltAudio].forEach((type) => { + if ((initSegmentMetrics === null || initSegmentMetrics === void 0 ? void 0 : initSegmentMetrics[type]) == null) + return; + const metric = { + fragmentType: sourceBufferTypeToMediaOptionType(type), + bufferCreationStart, + bufferCreationEnd, + startInitAppend: initSegmentMetrics[type].startAppend, + endInitAppend: initSegmentMetrics[type].endAppend, + initBytesAppend: initSegmentMetrics[type].bytesAppend, + startDataAppend: dataSegmentMetrics[type].startAppend, + endDataAppend: dataSegmentMetrics[type].endAppend, + dataBytesAppend: dataSegmentMetrics[type].bytesAppend, + }; + metrics[type] = metric; + }); + return metrics; + }), tap((_) => { + this.adjustJaggedStart(appendData); + })); + }), take(1)); + } + endStream() { + // Will throw error if msReadyState !== open or any source buffer is updating + try { + this.mediaSourceAdapter.endOfStream(); + } + catch (err) { + this.logger.warn(`endOfStream failed: ${err.message}`); + } + } + /** + * Set CDM on media element + * @param mediaKeys The CDM to attach, or null + */ + setMediaKeys(mediaKeys) { + const { logger } = this; + return this.teardownWG$.wrap(this.mediaKeysMutex + .lock(() => from(this.mediaElement.setMediaKeys(mediaKeys))) + .pipe(tap(() => { + logger.info(`[Keys] setMediaKeys(${mediaKeys}) success`); + }), retryWhen((errors) => errors.pipe(mergeMap((err, i) => { + logger.info(`[Keys] setMediaKeys(${mediaKeys} fail ${err.message})`); + if (i < 3) { + logger.info(`[Keys] Retry setMediaKeys delay=${i * 100}`); + return timer(i * 100); + } + throw err; + }))))); + } + clearMediaKeys() { + return defer(() => { + if (!this.mediaElement) { + return VOID; + } + const isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1; + const src = this.mediaElement.src; + if (isChrome) { + //https://github.com/Dash-Industry-Forum/dash.js/issues/623 + this.mediaElement.src = ''; + } + return this.setMediaKeys(null).pipe(tap(() => (this.mediaElement.src = src))); + }); + } + set postFlushSeek(time) { + this.mediaElementStore.postFlushSeek = time; + } + schedulePostFlushSeek(newSeekTo) { + applyTransaction(() => { + if (this.mediaQuery.seekTo) { + // forget unfinished internal seek + this.seekTo = null; // this will also clear mediaSink.postFlushSeek + } + this.postFlushSeek = newSeekTo; + }); + } + set seekTo(seekTo) { + this.mediaElementStore.setSeekToPos(seekTo, false); + } + setSeekToWithDiscontinuity(seekTo, discoSeqNum) { + this.mediaElementStore.setSeekToPos(seekTo, false, discoSeqNum); + } + nudgeSeek(seekTo, nudgeCount) { + applyTransaction(() => { + this.mediaElementStore.setSeekToPos(seekTo, false); + this.mediaElementStore.setNudgeInfo({ nudgeTarget: seekTo, nudgeCount }); + }); + } + set desiredRate(desiredRate) { + this.mediaElementStore.desiredRate = desiredRate; + // play / pause done in rateChange epic + } + toggleTrickPlaybackMode(enabled) { + // Override playbackRate value + if (this.config.overridePlaybackRate) { + const mediaRate = enabled ? 2 : 1; + try { + this.mediaElement.playbackRate = mediaRate; + this.logger.info({ name: 'iframes' }, `setting playbackRate to ${mediaRate}`); + } + catch (err) { + this.logger.error({ name: 'iframes' }, `Exception when setting playbackRate=${mediaRate}: ${err.message}`); + } + } + // Toggle mute value + const prev = this.muteValueOnTrickPlaybackToggle; + if (enabled && prev === undefined) { + this.muteValueOnTrickPlaybackToggle = this.mediaElement.muted; + this.mediaElement.muted = enabled; + } + else if (!enabled && prev !== undefined) { + this.mediaElement.muted = prev; + this.muteValueOnTrickPlaybackToggle = undefined; + } + } + play() { + this.logger.info('play()'); + this.mediaFunctions.play(); + } + pause() { + this.logger.info('pause()'); + this.mediaFunctions.pause(); + } + get expectPlayEvent() { + return this.mediaFunctions.expectPlayEvent; + } + set expectPlayEvent(value) { + this.mediaFunctions.expectPlayEvent = value; + } + get expectPauseEvent() { + return this.mediaFunctions.expectPauseEvent; + } + set expectPauseEvent(value) { + this.mediaFunctions.expectPauseEvent = value; + } + set textTracksCreated(created) { + const { mediaElementStore } = this; + mediaElementStore.textTracksCreated = created; + } + get msDuration() { + return this._mediaQuery.msDuration; + } + set msDuration(duration) { + try { + const { mediaElementStore } = this; + const mediaSource = this.mediaSource$.value; + if (mediaSource.duration !== duration) { + this.logger.debug(`set msduration ${duration}`); + mediaSource.duration = duration; + mediaElementStore.msDuration = duration; + } + } + catch (err) { + this.logger.warn(`Error setting duration ${err.message}`); + } + } + set haveEnough(haveEnough) { + this.mediaElementStore.haveEnough = haveEnough; + } + set flushing(flushing) { + this.mediaElementStore.flushing = flushing; + } + set bufferMonitorTargetDuration(durationSeconds) { + this.mediaElementStore.bufferMonitorTargetDuration = durationSeconds; + } + get textTracks() { + return this.mediaElement.textTracks; + } + get id3TextTrack() { + return this.id3Track; + } + addTextTrack(kind, label, language) { + return this.mediaElement.addTextTrack(kind, label, language); + } + dispatchEvent(e) { + return this.mediaElement.dispatchEvent(e); + } + get offsetWidth() { + return this.mediaElement.offsetWidth; + } + get offsetHeight() { + return this.mediaElement.offsetHeight; + } + getliveSeekableWindow() { + return this.liveSeekableWindow; + } + archiveParsedSubtitleFragmentRecord(persistentId, mediaSeqNum, fragCueRecord) { + return this.mediaElementStore.archiveParsedSubtitleFragmentRecord(persistentId, mediaSeqNum, fragCueRecord); + } + updateLiveSeekableRange(levelDetails) { + const fragments = levelDetails.fragments; + const len = fragments.length; + if (len > 1) { + const start = Math.max(fragments[0].start, 0); + const end = fragments[len - 1].start + fragments[len - 1].duration; + this.mediaSource$.value.updateLiveSeekableRange(start, end); + this.liveSeekableWindow.start = start; + this.liveSeekableWindow.end = end; + } + } + clearLiveSeekableRange() { + this.mediaSource$.value.clearLiveSeekableRange(); + this.liveSeekableWindow.start = NaN; + this.liveSeekableWindow.end = NaN; + } + } + /** + * @brief Translate media element events to store updates + */ + const hookMediaElementsEvents = (mediaElement, mediaElementStore, mediaQuery, mediaSink, gaplessInstance, config, logger, rtcService) => { + if (!mediaElement) + return EMPTY; + const target = fromEventTarget(mediaElement); + return merge(target.event('durationchange').pipe(map((ev) => convertEvent(mediaElement, 'durationchange', ev)), tap((ev) => { + const media = ev.currentTarget; + mediaElementStore.mediaElementDuration = media.duration; + })), target.event('seeking').pipe(throttleTime(config.seekEventThrottleMs), map((ev) => convertEvent(mediaElement, 'seeking', ev)), tap((ev) => { + const media = ev.currentTarget; + const seekToValue = media.currentTime; + if (media.readyState >= media.HAVE_METADATA) { + const seekTo = mediaQuery.seekTo; + if (!seekTo || (!seekTo.fromEvent && Math.abs(seekTo.pos - seekToValue) > 0.00001)) { + // Gapless Stuff + if (gaplessInstance.inGaplessMode) { + gaplessSeek(seekToValue, gaplessInstance, mediaSink, mediaElementStore, logger); + return; + } + else { + if (mediaSink && + // eslint-disable-next-line no-prototype-builtins + mediaSink.hasOwnProperty('liveSeekableWindow') && + isFiniteNumber(mediaSink.getliveSeekableWindow().start) && + isFiniteNumber(mediaSink.getliveSeekableWindow().end) && + (seekToValue < mediaSink.getliveSeekableWindow().start || seekToValue > mediaSink.getliveSeekableWindow().end)) { + // Adjust seek to within live window + liveAdjustedSeek(seekToValue, mediaSink.getliveSeekableWindow().start, mediaSink.getliveSeekableWindow().end, config, mediaElementStore, logger); + } + else { + mediaElementStore.setSeekToPos(seekToValue, true); + } + } + } + else { + // seekTo is already set (not from event) so we just need to update seeking state until "seeked" + mediaElementStore.seeking = true; + } + } + })), target.event('seeked').pipe(map((ev) => convertEvent(mediaElement, 'seeked', ev)), tap(() => { + mediaElementStore.setSeekToPos(null, true); + const currentTime = mediaElement.currentTime; + if (isFiniteNumber(currentTime)) { + logger.qe({ critical: true, name: 'seeked', data: { seekTo: currentTime.toFixed(3) } }); + } + })), target.event('play').pipe(map((ev) => convertEvent(mediaElement, 'play', ev)), withLatestFrom(mediaQuery.desiredRate$), map(([ev, desiredRate]) => { + const media = ev.currentTarget; + mediaElementStore.paused = media.paused; + const expectPlayEvent = mediaSink.expectPlayEvent; + const allowSetRate = media.controls || config.nativeControlsEnabled; + logger.info(`media play desiredRate=${desiredRate} expectPlayEvent=${expectPlayEvent} allowed=${allowSetRate}`); + if (!expectPlayEvent && allowSetRate) { + mediaSink.checkForReplay(); + mediaElementStore.desiredRate = 1; + } + mediaSink.expectPlayEvent = false; + return ev; + })), target.event('playing').pipe(map((ev) => convertEvent(mediaElement, 'playing', ev)), tap((ev) => { + const media = ev.currentTarget; + // log playing event immediately. + logger.qe({ critical: true, name: 'playerEvent', data: { type: ev.type, pos: media.currentTime.toFixed(3), dur: media.duration.toFixed(3) } }); + mediaElementStore.paused = media.paused; + mediaElementStore.gotPlayingEvent(); + })), target.event('loadstart').pipe(map((ev) => convertEvent(mediaElement, 'loadstart', ev)), tap(() => { + mediaElementStore.gotLoadStartEvent(); + })), target.event('pause').pipe(map((ev) => convertEvent(mediaElement, 'pause', ev)), tap((ev) => { + const media = ev.currentTarget; + mediaElementStore.paused = media.paused; + const expectPauseEvent = mediaSink.expectPauseEvent; + const allowSetRate = media.controls || config.nativeControlsEnabled; + logger.info(`media pause desiredRate=${mediaQuery.desiredRate} expectPauseEvent=${expectPauseEvent} allowed=${allowSetRate}`); + if (!expectPauseEvent && allowSetRate) { + mediaElementStore.desiredRate = 0; + } + mediaSink.expectPauseEvent = false; + })), + // readystate change events. May not be fired for all platforms so take + // with a grain of salt + target.event('loadedmetadata').pipe(map((ev) => convertEvent(mediaElement, 'loadedmetadata', ev))), // HAVE_METADATA + target.event('loadeddata').pipe(map((ev) => convertEvent(mediaElement, 'loadeddata', ev))), // HAVE_CURRENT_DATA + target.event('canplay').pipe(map((ev) => convertEvent(mediaElement, 'canplay', ev))), // HAVE_FUTURE_DATA + target.event('canplaythrough').pipe(map((ev) => convertEvent(mediaElement, 'canplaythrough', ev))), // HAVE_ENOUGH_DATA + target.event('waiting').pipe(map((ev) => convertEvent(mediaElement, 'waiting', ev))), // less than HAVE_CURRENT_DATA and not paused + target.event('emptied').pipe(map((ev) => convertEvent(mediaElement, 'emptied', ev))), // HAVE_NOTHING (media.load() was called) + target.event('error').pipe(map((ev) => convertEvent(mediaElement, 'error', ev)), concatMap((ev) => { + return throwError(mediaElement.error); + })), // HAVE_NOTHING + target.event('ended').pipe(map((ev) => convertEvent(mediaElement, 'ended', ev)))).pipe(withLatestFrom(mediaQuery.bufferedRangeTuple$), withTransaction(([ev, bufferedRanges]) => { + const media = ev.currentTarget; + const readyState = media.readyState; + mediaElementStore.readyState = readyState; + mediaElementStore.ended = media.ended; + logger.info(`media event: ${ev.type} pos:${media.currentTime.toFixed(3)} dur:${media.duration.toFixed(3)} buffered:${stringifyWithPrecision(bufferedRanges)} readyState:${readyState}`); + // playing event is logged immediately when event occurs, so skip it here + if (ev.type != 'playing') { + logger.qe({ critical: true, name: 'playerEvent', data: { type: ev.type, pos: media.currentTime.toFixed(3), dur: media.duration.toFixed(3) } }); + } + }), catchError((err) => { + if (err instanceof MediaError) { + logger.warn(`mediaElementError, code: ${err.code}, message: ${err.message}`); + rtcService === null || rtcService === void 0 ? void 0 : rtcService.handleMediaElementError(err); + } + else { + logger.error(`media event error: ${err.message}`); + } + return EMPTY; + }), switchMapTo(NEVER), catchError((err) => { + if (err instanceof MediaError) { + logger.warn(`mediaElementError, code: ${err.code}, message: ${err.message}`); + return throwError(err); // re-throw media element errors for reporting + } + else { + logger.error(`media event error: ${err.message}`); + return EMPTY; + } + })); + }; + // Helper function for seeking when in gapless mode + function gaplessSeek(seekToValue, gaplessInstance, mediaSink, mediaElementStore, logger) { + let seekValueAdjusted = false; + // Adjust seekToValue if needed + logger.debug(`seekTo before gapless adjust: ${seekToValue}, startOffset: ${gaplessInstance.playingItem.itemStartOffset}`); + if (seekToValue < gaplessInstance.playingItem.itemStartOffset) { + logger.warn(`[Gapless] Seeking past track boundary oldSeek=${seekToValue}, adjustedSeek=${gaplessInstance.playingItem.itemStartOffset}`); + seekToValue = gaplessInstance.playingItem.itemStartOffset; + seekValueAdjusted = true; + } + if (gaplessInstance.isPreloading) { + if (seekToValue > gaplessInstance.loadingItem.itemStartOffset) { + logger.warn(`[Gapless] Seeking past track boundary oldSeek=${seekToValue}, adjustedSeek=${gaplessInstance.loadingItem.itemStartOffset}`); + seekToValue = gaplessInstance.loadingItem.itemStartOffset; + seekValueAdjusted = true; + } + // Unable to get the state before the seek event, hence need to dequeue on every seek. + gaplessInstance.dequeueSource('SeekToUnbufferedTimeRanges'); + } + if (seekValueAdjusted) { + mediaSink.resetMediaSource(seekToValue); + } + else { + mediaElementStore.setSeekToPos(seekToValue, true); + } + } + // TODO consolidate this with live-position sanitizeLiveSeek + function liveAdjustedSeek(seekValue, liveSeekableWindowStart, liveSeekableWindowEnd, config, mediaElementStore, logger) { + let adjustedSeek = seekValue; + if (seekValue < liveSeekableWindowStart) { + adjustedSeek = liveSeekableWindowStart; + } + else if (seekValue > liveSeekableWindowEnd) { + let targetLatency = config.defaultTargetDuration; + if (isFiniteNumber(config.liveSyncDuration)) { + targetLatency = config.liveSyncDuration; + } + else if (isFiniteNumber(config.liveSyncDurationCount)) { + targetLatency = config.liveSyncDurationCount * config.defaultTargetDuration; + } + adjustedSeek = Math.max(0, liveSeekableWindowEnd - targetLatency); + } + logger.warn(`[live] liveAdjustedSeek seekTo:${toFixed(seekValue, 3)}, adjustedSeek:${toFixed(adjustedSeek, 3)}, liveWindowStart:${toFixed(liveSeekableWindowStart, 3)}, liveWindowEnd:${toFixed(liveSeekableWindowEnd, 3)}`); + mediaElementStore.setSeekToPos(adjustedSeek, true); + } + function getMatchingInfo(sbEntity, fragStart, fragEnd, discoSeqNum, mediaOptionId, logger) { + const buffered = sbEntity === null || sbEntity === void 0 ? void 0 : sbEntity.bufferedSegments; + if (!buffered) { + logger.warn('getMatchingInfo trying to query null sbEntity'); + return null; + } + const seg = buffered.find((seg) => { + const matchDisco = seg.frag.discoSeqNum === discoSeqNum; + const overlap = Math.max(fragStart, seg.startPTS) < Math.min(fragEnd, seg.endPTS); + return matchDisco && overlap; + }); + if (seg != null) { + const { audioCodec, videoCodec, mimeType } = sbEntity; + return { mimeType, audioCodec, videoCodec, startPTSSec: seg.startPTS, endPTSSec: seg.endPTS, discoSeqNum, mediaOptionId }; + } + return null; + } + /** + * check whether the appendData is compatible with the curent source buffers. + * @param appendData the data to append. It is assumed that we will never have mismatched discoSeqNum for these two + * @param offsetTimestamp timestamp value that will be used to SourceBuffer.timestampOffset. Use for position calculation + * @param sourceBufferEntities info about the current set of buffers + * @param expectedSbCount the expected number of sourceBuffers + * @param logger a logger instance + * @returns compatible: if compatible with current source buffers + * boundary: the discontinuity boundary. NaN if we didn't get enough info + */ + function isCompatibleWithSourceBuffers(appendData, sourceBufferEntities, expectedSbCount, gapTolerance, logger) { + var _a, _b; + const curSbCount = sourceBufferEntities.filter((sbEntity) => Boolean(sbEntity)).length; + const newSbCount = appendData.filter((sbDataTuple) => Boolean(sbDataTuple)).length; + const compatInfos = [null, null]; + appendData.forEach((sbAppendData, type) => { + if (sbAppendData) { + const { offsetTimestamp } = sbAppendData; + const tsOffsetSec = convertTimestampToSeconds(offsetTimestamp); + const mimeType = sbAppendData.initSeg.mimeType; + const { audioCodec, videoCodec } = sbAppendData.initSeg.initParsedData; + const { dataSeg } = sbAppendData; + const startPTS = convertTimestampToSeconds(dataSeg.startPts) - tsOffsetSec; + const endPTS = convertTimestampToSeconds(dataSeg.endPts) - tsOffsetSec; + const discoSeqNum = dataSeg.discoSeqNum; + compatInfos[type] = { audioCodec, videoCodec, mimeType, startPTSSec: startPTS, endPTSSec: endPTS, discoSeqNum, mediaOptionId: sbAppendData.initSeg.mediaOptionId }; + logger.trace(`compatInfos[${type}] = { ${audioCodec}, ${videoCodec}, ${mimeType}, ${startPTS}, ${endPTS}, ${discoSeqNum}, ${sbAppendData.initSeg.mediaOptionId}`); + } + }); + let compatible = curSbCount === expectedSbCount; + let gotEnoughData = newSbCount === expectedSbCount; + // check appendData count against enabled tracks (expectedSbCount) instead of existing sourceBuffer counts (curSbCount). + // when switching between muxed and alt audio, curSbCount may be wrong and need a resetMediaSource before appending. + logger.trace(`mediaSink setup: enabledMediaOption# ${expectedSbCount} sourceBuffer# ${curSbCount} appendData# ${newSbCount}: compatible ${compatible} gotEnoughData ${gotEnoughData}`); + if (newSbCount === 1 && newSbCount < expectedSbCount && curSbCount !== 0) { + const curType = appendData[MediaOptionType.Variant] ? MediaOptionType.Variant : MediaOptionType.AltAudio; + const otherType = 1 - curType; + const curFrag = compatInfos[curType]; + const foundFrag = (compatInfos[otherType] = getMatchingInfo(sourceBufferEntities[otherType], curFrag.startPTSSec, curFrag.endPTSSec, curFrag.discoSeqNum, curFrag.mediaOptionId, logger)); + if (!foundFrag) { + const iframeMode = (_b = (_a = appendData[MediaOptionType.Variant]) === null || _a === void 0 ? void 0 : _a.dataSeg) === null || _b === void 0 ? void 0 : _b.iframe; + if (iframeMode && curType === MediaOptionType.Variant && compatInfos[curType]) { + // in iframe mode, audio may have large loading gaps. Allow iframes to append even when no matching audio frag is present. + const currentVideoCodec = sourceBufferEntities[curType].videoCodec; + const newVideoCodec = compatInfos[curType].videoCodec; + compatible = compatible && (currentVideoCodec === newVideoCodec || MediaUtil.isCompatibleVideoCodec(currentVideoCodec, newVideoCodec)); + if (compatible) { + logger.info(`${MediaOptionNames[curType]} allow iframe=${currentVideoCodec}->${newVideoCodec} with no matching audio #disco`); + return { compatible, boundary: NaN, allowance: NaN, discoSeqNum: compatInfos[curType].discoSeqNum }; + } + } + else { + logger.warn(`${MediaOptionNames[curType]} No matching frag found ${stringifyWithPrecision(curFrag)} buffered=${stringifyWithPrecision(sourceBufferEntities[otherType].bufferedSegments.map((seg) => { + const { mediaSeqNum, discoSeqNum } = seg.frag; + return { mediaSeqNum, discoSeqNum, startPTS: seg.startPTS, endPTS: seg.endPTS }; + }))}`); + } + } + else { + logger.trace(`foundFrag = compatInfos[${otherType}] = { ${foundFrag.audioCodec}, ${foundFrag.videoCodec}, ${foundFrag.mimeType}, ${foundFrag.startPTSSec}, ${foundFrag.endPTSSec}, ${foundFrag.discoSeqNum}, ${foundFrag.mediaOptionId}`); + } + gotEnoughData = foundFrag != null; + } + let boundary = NaN; + let allowance = NaN; + let cc = NaN; + if (gotEnoughData) { + compatInfos.forEach((info, type) => { + var _a; + if (!info) + return null; + // to be used for incompat. discontinuity only: + // set cc if all append & buffered data at this pos have the same cc + // determine the next discontinuity sequence number after resetMediaSource + if (!isFiniteNumber(cc)) { + cc = info.discoSeqNum; + } + else if (cc !== info.discoSeqNum) { + cc = NaN; + } + const currentSbEntity = sourceBufferEntities[type]; + if (!currentSbEntity) { + compatible = false; + } + else { + const currentAudioCodec = currentSbEntity.audioCodec; + const currentVideoCodec = currentSbEntity.videoCodec; + const { audioCodec: newAudioCodec, videoCodec: newVideoCodec } = info; + compatible = compatible && (currentVideoCodec === newVideoCodec || MediaUtil.isCompatibleVideoCodec(currentVideoCodec, newVideoCodec)); + compatible = compatible && (currentAudioCodec === newAudioCodec || MediaUtil.isCompatibleAudioCodec(currentAudioCodec, newAudioCodec)); + logger.info(`${MediaOptionNames[type]} video=${currentVideoCodec}->${newVideoCodec} audio=${currentAudioCodec}->${newAudioCodec} start=${(_a = info.startPTSSec) === null || _a === void 0 ? void 0 : _a.toFixed(3)} #disco`); + } + if (isFiniteNumber(boundary)) { + allowance = Math.abs(info.startPTSSec - boundary); + boundary = Math.max(info.startPTSSec, boundary); + } + else { + allowance = 0; + boundary = info.startPTSSec; + } + }); + } + return { compatible: compatible && gotEnoughData, boundary, allowance, discoSeqNum: cc }; + } + function seekEpic(mediaElement, mediaQuery, mediaSink, config, logger) { + logger = logger.child({ name: 'seek' }); + return (seekTo$) => seekTo$.pipe(tap((seekTo) => logger.info(`seekTo=${JSON.stringify(seekTo)}`)), filter((seekTo) => seekTo && isFiniteNumber(seekTo.pos)), switchMap((seekTo) => { + return mediaQuery.readyState$.pipe(filter((readyState) => readyState >= mediaElement.HAVE_METADATA), take(1), mapTo(seekTo), switchMap(({ pos, fromEvent }) => { + logger.info(`startSeek(${pos === null || pos === void 0 ? void 0 : pos.toFixed(3)},${fromEvent})`); + mediaSink.checkForInconsistentStoreBufferRangesAndUpdate(); + if (!mediaElement.paused) { + mediaSink.pause(); + } + if (!fromEvent) { + mediaElement.currentTime = pos; + } + return waitFor(mediaQuery.haveEnough$, (x) => x).pipe(mapTo({ pos, fromEvent })); + }), switchMap(({ pos, fromEvent }) => { + const combinedBuffer = mediaQuery.getCombinedBufferInfo(pos, 0); + const nextStart = combinedBuffer.nextStart; + const applyNudge = !fromEvent || config.nudgeFromEventSeek; + logger.info(`haveEnough readystate=${mediaQuery.readyState} fromEvent=${fromEvent} applyNudge=${applyNudge} nextStart ${nextStart} pos ${pos} combinedBuffer.len ${combinedBuffer.len}`); + if (applyNudge && combinedBuffer.len === 0 && isFiniteNumber(nextStart) && nextStart > pos && nextStart - pos <= config.maxSeekHole) { + logger.info(`haveEnough but current position not actually buffered, nudge ${pos.toFixed(3)}->${nextStart.toFixed(3)}`); + mediaSink.seekTo = nextStart; + return EMPTY; + } + return of(pos); + }), withLatestFrom(mediaQuery.desiredRate$), map(([pos, desiredRate]) => { + logger.info(`completeSeek(${pos === null || pos === void 0 ? void 0 : pos.toFixed(3)}) readyState=${mediaElement.readyState} paused=${mediaElement.paused} desiredRate=${desiredRate}`); + if (mediaElement.paused && desiredRate !== 0) { + mediaSink.play(); + } + }), switchMapTo(EMPTY), catchError((err) => { + logger.error(`error during seek ${err.message}`); + return EMPTY; + })); + })); + } + function rateChangeEpic(mediaElement, mediaQuery, mediaSink, logger) { + return (rateChange$) => rateChange$.pipe(withLatestFrom(mediaQuery.seekTo$), switchMap(([rate, seekTo]) => { + if (isFiniteNumber(seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos)) { + return EMPTY; // Taken care of by seekEpic + } + if (rate === 0) { + if (!mediaElement.paused) { + mediaSink.pause(); + } + return EMPTY; + } + return waitFor(mediaQuery.haveEnough$, (x) => x).pipe(tap(() => { + if (mediaElement.paused) { + mediaSink.play(); + } + })); + }), switchMapTo(EMPTY)); + } + function stallEpic(mediaSink, meStore, config, logger) { + return (stallInfo$) => stallInfo$.pipe(exhaustMap((stallInfo) => { + if (!stallInfo) { + return of(NaN); + } + return nudgeSeek(mediaSink, meStore, config, logger); + })); + } + function nudgeSeek(mediaSink, meStore, config, logger) { + const meQuery = mediaSink.mediaQuery; + const gotUserSeek$ = combineQueries([meQuery.seekTo$, meQuery.nudgeTarget$]).pipe(filter(([seekTo, nudgeTarget]) => seekTo && isFiniteNumber(seekTo.pos) && isFiniteNumber(nudgeTarget) && (seekTo.pos < nudgeTarget || seekTo.pos - nudgeTarget > config.maxSeekHole)), mapTo(null)); + return merge(gotUserSeek$, meQuery.stallInfo$).pipe(withLatestFrom(meQuery.desiredRate$), observeOn(asyncScheduler), map(([stallInfo, desiredRate], index) => { + if (!stallInfo) { + return NaN; + } + const bufferInfo = meQuery.getCombinedBufferInfo(stallInfo.currentTime, 0); // maxBufferHole 0 + const iframeMode = isIframeRate(desiredRate); + return nudgeIfNeeded(mediaSink, config, logger, stallInfo, bufferInfo, iframeMode, index); + }), takeWhile((nudgeTarget) => isFiniteNumber(nudgeTarget)), finalize$1(() => { + logger.debug('nudge seek finalize'); + meStore.setNudgeInfo(null); + })); + } + function nudgeIfNeeded(mediaSink, config, logger, stallInfo, bufferInfo, iframeMode, nudgeRetry) { + const { type, isLowBufferStall, currentTime } = stallInfo; + const bufferLen = bufferInfo.len; + const jumpThreshold = config.maxSeekHole; + let nudgePosition = NaN; + if (isLowBufferStall) { + // if buffer len is below threshold, try to jump to start of next buffer range if close + // no buffer available @ currentTime, check if next buffer is close (within a config.maxSeekHole second range) + const nextBufferStart = bufferInfo.nextStart - currentTime <= jumpThreshold ? bufferInfo.nextStart : Infinity; //this._ensureNudgeStartTimeForIncompatibleCC(bufferInfo.nextStart, currentTime, config.maxSeekHole); + if (isFiniteNumber(nextBufferStart)) { + // next buffer is close ! adjust currentTime to nextBufferStart + // this will ensure effective video decoding + logger.info(`adjust currentTime from ${currentTime} to next buffered @ ${nextBufferStart}`); + nudgePosition = nextBufferStart; + } + else if (mediaSink.mediaQuery.msDuration - currentTime < 0.1) { + nudgePosition = currentTime + 0.1; + } + } + else { + // if (this.relaxHighBufferStallRule) { + // this.relaxHighBufferStallRule--; + // logger.log(`ignore stall. ${this.relaxHighBufferStallRule} free pass available. staying put @ ${media.currentTime}`); + // payload = new BufferStallError(ErrorDetails.BUFFER_STALLED_ERROR, false, + // 'got buffer stalled error', ErrorResponses.VideoDecoderBadDataErr, type, bufferLen); + // } else + if (nudgeRetry < config.nudgeMaxRetry) { + // playback stalled in buffered area ... let's nudge currentTime to try to overcome this + nudgePosition = currentTime + config.nudgeOffset; + } + else if (iframeMode) { + // maxed number of nudges - but in iframeMode + logger.error(`still stuck in high buffer @${currentTime} after ${config.nudgeMaxRetry}, non fatal in iframeMode`); + } + else { + logger.error(`still stuck in high buffer @${currentTime} after ${config.nudgeMaxRetry}, raise fatal error`); + throw new BufferStallError(ErrorDetails.BUFFER_STALLED_ERROR, true, 'got fatal buffer error', ErrorResponses.VideoDecoderBadDataErr, type, bufferLen); + } + } + if (isFiniteNumber(nudgePosition)) { + logger.info(`stall ${type} nudge ${currentTime}->${nudgePosition} nudgeRetry=${nudgeRetry}`); + mediaSink.nudgeSeek(nudgePosition, nudgeRetry + 1); + } + return nudgePosition; + } + + /** + * @brief Service that manages playback state + */ + // state for the service functions + const mediaElementStore = new MediaElementStore(); + /** + * media component managment + */ + const mediaElementServiceEpic = (makeMediaSource, config, gaplessInstance, logger, teardownWG$, rtcService) => (mediaElementSource$) => { + return mediaElementSource$.pipe(tag('playback.mediaElementServiceEpic.in'), switchMap((mediaElement) => { + if (!mediaElement) { + return of(null); + } + const mediaSink = new MediaSink(mediaElement, mediaElementStore, config, gaplessInstance, logger, teardownWG$, rtcService); + mediaSink.openMediaSource(makeMediaSource()); + return merge(of(mediaSink), mediaSink); + }), tag('playback.mediaElementServiceEpic.emit')); + }; + + const displaySupportsHdr$ = () => { + if (typeof matchMedia === 'function') { + const mediaQueryList = matchMedia('(dynamic-range: high)'); + const badQuery = matchMedia('bad query'); + if (mediaQueryList.media !== badQuery.media) { + return merge(of(mediaQueryList), fromEvent(mediaQueryList, 'change')).pipe(map((e) => e.matches)); + } + } + // assume hdr is supported by display + return of(true); + }; + + class PlatformQuery extends Query { + constructor(store) { + super(store); + this.store = store; + this.displaySupportsHdr$ = this.select('supportsHdr'); + this.platformInfo$ = this.select('platformInfo'); + this.viewportInfo$ = this.select('viewportInfo'); + } + get platformInfo() { + return this.getValue().platformInfo; + } + get displaySupportsHdr() { + return this.getValue().supportsHdr; + } + get viewportInfo() { + return this.getValue().viewportInfo; + } + } + + function createInitialState() { + return { supportsHdr: true }; + } + class PlatformStore extends Store { + constructor() { + super(createInitialState(), { name: 'platform', producerFn: produce_1 }); + } + } + + class PlatformService { + constructor(store) { + this.store = store; + } + getQuery() { + return new PlatformQuery(this.store); + } + updateSupportsHdr(supported) { + this.store.update((state) => { + state.supportsHdr = supported; + }); + } + updatePlatformInfo(platformInfo) { + this.store.update({ platformInfo }); + } + updateViewportInfo(viewportInfo) { + this.store.update((state) => { + state.viewportInfo = viewportInfo; + }); + } + } + const store = new PlatformStore(); + let service$1 = null; // To be instantiated in platformService(); + /*********************************************** + * Static helper functions that specifically use the above singletons + */ + function createPlatformQuery() { + return new PlatformQuery(store); + } + /** + * @returns The global instance of PlatformService that operates on global PlatformStore + */ + function platformService() { + if (!service$1) { + service$1 = new PlatformService(store); + } + return service$1; + } + function listenForHdrUpdates(platformService) { + return displaySupportsHdr$().pipe(tap((supported) => { + platformService.updateSupportsHdr(supported); + })); + } + + // The vanilla RPCService uses old-school callback pattern to minimize the + // dependency surface in restricted environments, e.g. in Web Worker. + // However, if resource permitted, one can use this RPCServiceObservable wrapper + // to convert RPCService interface into Observable pattern for better + // interoperability with RxJs code. + class RPCServiceObservable extends Observable { + constructor(_vanillaRPC, teardownWG$) { + super(subscriber => { + teardownWG$ === null || teardownWG$ === void 0 ? void 0 : teardownWG$.add(); + subscriber.add(this._handler$ + .pipe(mergeMap(([handler, args, callback]) => handler(...args).pipe(tap({ + next(result) { + callback(result, null); + }, + error(error) { + callback(null, error); + }, + })))) + .subscribe()); + }); + this._vanillaRPC = _vanillaRPC; + this.teardownWG$ = teardownWG$; + this._handler$ = new Subject(); + } + register(command, handler) { + const asyncHandler = (...args) => (callback) => { + this._handler$.next([handler, args, callback]); + }; + return this._vanillaRPC.register(command, asyncHandler); + } + invoke(command, args, transfer) { + return new Observable((subscriber) => { + this._vanillaRPC.invoke(command, args, transfer)((result, error) => { + if (error != null) { + subscriber.error(error); + } + else { + subscriber.next(result); + subscriber.complete(); + } + }); + }); + } + } + + // CryptoRPCClient only runs in main process, so I has more resources to include + // the RxJS as dependency and use the Observable pattern. So we can extend on + // RPCServiceObservable instead of the vanilla RPCService class. + class CryptoRPCClient extends RPCServiceObservable { + constructor(rpcService) { + super(rpcService); + } + decrypt(key, iv, alg, cipherText, options) { + return this.invoke('decrypt', [key, iv, alg, cipherText, options], [key, iv, cipherText]); + } + } + + class DemuxRPCClient extends RPCServiceObservable { + constructor(rpcService) { + super(rpcService); + this.rpcService = rpcService; + this.sessions = {}; + this._onEvent = (demuxSessionID, event, data) => () => { + if (this.sessions[demuxSessionID] != null) { + this.sessions[demuxSessionID].observer.trigger(event, data); + } + }; + this.rpcService.register('demuxer.event', this._onEvent); + } + init(typeSupported, config, vendor) { + config = (({ maxSeekHole, maxBufferHole, audioPrimingDelay, stretchShortVideoTrack, forceKeyFrameOnDiscontinuity }) => ({ + maxSeekHole, + maxBufferHole, + audioPrimingDelay, + stretchShortVideoTrack, + forceKeyFrameOnDiscontinuity, + }))(config); + return this.invoke('demuxer.init', [typeSupported, config, vendor], []).pipe(map((demuxSessionID) => { + const session = new DemuxRPCSession(this, demuxSessionID); + this.sessions[demuxSessionID] = session; + return session; + })); + } + } + class DemuxRPCSession { + constructor(rpc, demuxSessionID) { + this.rpc = rpc; + this.demuxSessionID = demuxSessionID; + this.observer = new Observer(); + } + push(data, keyTagInfo, initSegment, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS, iframeMediaStart, iframeDuration, transfer) { + return this.rpc.invoke('demuxer.push', [this.demuxSessionID, data, keyTagInfo, initSegment, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS, iframeMediaStart, iframeDuration], transfer !== null && transfer !== void 0 ? transfer : [data]); + } + pushWithoutTransfer(data, keyTagInfo, initSegment, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS, iframeMediaStart, iframeDuration) { + return this.push(data, keyTagInfo, initSegment, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS, iframeMediaStart, iframeDuration, []); + } + destroy() { + this.observer.removeAllListeners(); + this.rpc.invoke('demuxer.destroy', [this.demuxSessionID], []).subscribe(); + } + } + + const createRPCClients = (rpcService) => ({ + crypto: new CryptoRPCClient(rpcService), + mux: new DemuxRPCClient(rpcService), + }); + + const LoggerRPCServer = (rpcService, logger) => { + rpcService.register('logger.log', (bindings, level, ...args) => (callback) => { + try { + for (const b of bindings) { + logger = logger.child(b); + } + if (typeof logger[level] === 'function') { + // eslint-disable-next-line @typescript-eslint/ban-types + logger[level](...args); + } + callback(); + } + catch (err) { + callback(undefined, err); + } + }); + }; + + // Inline service treat the client and server running in the same process, and + // just forward messages directly by function calls. + class RPCInlineService { + constructor() { + this.handlers = {}; + } + register(command, handler) { + if (this.handlers[command] != null) { + return false; + } + this.handlers[command] = handler; + } + unregister(command) { + if (this.handlers[command] != null) { + return false; + } + delete this.handlers[command]; + } + invoke(command, args) { + return (callback = RPCInlineService._fallbackCallback) => { + try { + if (this.handlers[command] == null) { + throw new Error(`command ${command} not found`); + } + this.handlers[command](...args)(callback); + } + catch (error) { + callback(undefined, error); + } + }; + } + teardown(done) { + this.handlers = null; + done(); + } + } + RPCInlineService._fallbackCallback = (result, error) => { + if (error != null) { + throw error; + } + }; + + const createRPCInlineService = (logger) => { + logger = logger.child({ name: 'InlineRPCService' }); + const rpcService = new RPCInlineService(); + new CryptoRPCServer(rpcService, logger); + new DemuxRPCServer(rpcService, logger); + logger.info('Inline RPCService has started'); + return rpcService; + }; + let worker; + const createRPCWorkerService = (logger) => { + if (!hasUMDWorker()) { + throw new Error('UMD WebWorker is not bundled in this file'); + } + try { + if (worker == null) { + const blob = new Blob(['var exports = {};var module = { exports: exports };function define(f){f()};define.amd = true;(' + __HLS_UMD_BUNDLE__.toString() + ')(true);'], { + type: 'text/javascript', + }); + const workerUrl = URL.createObjectURL(blob); + worker = new Worker(workerUrl); + } + const rpcService = new RPCWorkerService(worker); + LoggerRPCServer(rpcService, logger.child({ name: 'WorkerRPCService' })); + return rpcService; + } + catch (err) { + throw new Error('Failed to create WebWorker'); + } + }; + const createRPCServiceWithFallbacks = (...fallbacks) => (logger) => { + for (let i = 0; i < fallbacks.length; i++) { + const create = fallbacks[i]; + try { + return create(logger); + } + catch (err) { + if (i === fallbacks.length - 1) { + throw err; + } + logger.warn(err); + } + } + }; + const createRPCService = (logger) => { + return createRPCServiceWithFallbacks(createRPCWorkerService, createRPCInlineService)(logger); + }; + + /* + * RTC types + * + * + */ + /* + * Events that RTC sends out to the backend. + * https://confluence.sd.apple.com/display/ISM/Matchpoint+Event-Key+List + */ + class RTCEventGroup { + } + RTCEventGroup.PlayEnded = 6101; + RTCEventGroup.Periodic = 6110; + RTCEventGroup.PlayStalled = 6103; + RTCEventGroup.KeySessionComplete = 6104; + RTCEventGroup.PlayLikelyToKeepUp = 6105; + RTCEventGroup.PlayRateChanged = 6106; + RTCEventGroup.PlayError = 6107; + RTCEventGroup.MediaEngineStalled = 6108; + RTCEventGroup.SwitchComplete = 6109; + RTCEventGroup.VariantEnded = 6111; + RTCEventGroup.NwError = 6202; + const RTCVideoQualityIndex = { + avc1: 1, + avc3: 1, + hvc1: { SDR: 2, HLG: 10, PQ: 11 }, + hev1: { SDR: 2, HLG: 10, PQ: 11 }, + vp09: { SDR: 3, HLG: 14, PQ: 13 }, + dvh1: { PQ: 12 }, + }; + + const loggerName$5 = { name: 'rtc-component' }; + class RTCComponent { + constructor(query, logger) { + this.query = query; + this.logger = logger; + } + setReportingAgent(reportingAgent) { + this.reportingAgent = reportingAgent; + } + sendPlayEnded(id) { + this.logger.debug(loggerName$5, `sendPlayEnded id=${id}`); + const method = RTCEventGroup.PlayEnded; + this.fillAndFire(method, this.query.playEnded(id)); + } + sendPlayStalled(id) { + const method = RTCEventGroup.PlayStalled; + this.fillAndFire(method, this.query.playStalled(id)); + } + sendMediaEngineStalled(id) { + const method = RTCEventGroup.MediaEngineStalled; + this.fillAndFire(method, this.query.mediaEngineStalled(id)); + } + sendKeySessionComplete(id) { + const method = RTCEventGroup.KeySessionComplete; + this.fillAndFire(method, this.query.keySessionComplete(id)); + } + sendPlayLikelyToKeepUp(id) { + const method = RTCEventGroup.PlayLikelyToKeepUp; + this.fillAndFire(method, this.query.playLikelyToKeepUp(id)); + } + sendPlayRateChange(id) { + this.logger.debug(loggerName$5, `sendPlayRateChange id=${id}`); + const method = RTCEventGroup.PlayRateChanged; + this.fillAndFire(method, this.query.playRateChanged(id)); + } + sendSwitchComplete(id) { + const method = RTCEventGroup.SwitchComplete; + this.fillAndFire(method, this.query.switchComplete(id)); + } + sendVariantEnded(id) { + const method = RTCEventGroup.VariantEnded; + this.fillAndFire(method, this.query.variantEnded(id)); + } + sendPlayError(id) { + const method = RTCEventGroup.PlayError; + this.fillAndFire(method, this.query.playError(id)); + } + sendNwError(id) { + const method = RTCEventGroup.NwError; + this.fillAndFire(method, this.query.nwError(id)); + } + sendPeriodic(id) { + const method = RTCEventGroup.Periodic; + this.fillAndFire(method, this.query.periodic(id)); + } + fillAndFire(method, record) { + this.logger.debug(loggerName$5, 'RTC fillAndFire'); + // don't send periodic event if there is no playtime or active fragment download time + if (method === RTCEventGroup.Periodic && !record.PlayTimeWC && !record.ADT) { + this.logger.info(loggerName$5, `RTC Method: ${method}, Skipping due to no playback/download activity`); + return; + } + const type = method === RTCEventGroup.PlayEnded || method === RTCEventGroup.Periodic ? 1 : 0; + this.logger.info(loggerName$5, `RTC Method: ${method}, Type:${type}`); + if (this.reportingAgent) { + this.logger.debug(loggerName$5, 'Reporting Agent is set!'); + let eventPayload = {}; + Object.entries(record).forEach(([key, value]) => { + // round all numeric values to two decimal points + if (isFiniteNumber(value)) { + value = Number(Number(value).toFixed(2)); + } + // Extract keys from ServerInfo and populate the event payload; no other object types allowed. Ref: privacyAllowedLoadConfigHeaders + if (typeof value === 'object') { + if (key === 'ServerInfo') { + Object.entries(value).forEach(([k, v]) => { + eventPayload[k] = v; + }); + } + else { + this.logger.debug(loggerName$5, `Object type unsupported for key: ${key}`); + } + } + else { + eventPayload[key] = value; + } + }); + this.logger.debug(loggerName$5, 'RTC Method: %s, payload=%o', method, eventPayload); + // copy record into extensible payload + eventPayload = JSON.parse(JSON.stringify(eventPayload)); + try { + this.reportingAgent.issueReportingEvent(method, eventPayload, type); + } + catch (err) { + this.logger.info(loggerName$5, 'Cannot report, reportingAgent failed'); + } + } + } + } + + class RTCQuery extends QueryEntity { + constructor(rtcStore, logger) { + super(rtcStore); + this.logger = logger; + } + // generic getters + get activeEntity() { + return this.getActive(); + } + entity(id) { + return this.getEntity(id); + } + playEnded(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.playEndedRecord; + } + periodic(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.periodicRecord; + } + playStalled(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.playStalledRecord; + } + mediaEngineStalled(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.mediaEngineStalledRecord; + } + keySessionComplete(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.keySessionCompleteRecord; + } + playLikelyToKeepUp(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.playLikelyToKeepUpRecord; + } + playRateChanged(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.playRateChangedRecord; + } + switchComplete(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.switchCompleteRecord; + } + variantEnded(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.variantEndedRecord; + } + playError(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.playErrorRecord; + } + nwError(id) { + var _a; + return (_a = this.getEntity(id)) === null || _a === void 0 ? void 0 : _a.nwErrorRecord; + } + } + + class RTCStore extends EntityStore { + constructor(logger) { + super({}, { name: 'rtc-store', idKey: 'itemId', producerFn: produce_1, resettable: true }); + this.logger = logger; + } + /* + * Create an RTC Entity with the necessary records + */ + createEntity(itemId) { + const rtcEntity = { + itemId, + sessionControlRecord: { + state: 'RTC_STATE_INIT', + rate: 0, + oldRate: 0, + eventStartTime: Date.now(), + sessionStartTime: Date.now(), + lastLikelyToKeepUpTime: Date.now(), + lastPeriodicTime: Date.now(), + playLikelyToKeepUpEventCounter: 1, + periodicEventCounter: 1, + activeKeySessions: {}, + intervalVariantList: {}, + sessionVariantList: {}, + }, + playEndedRecord: {}, + periodicRecord: {}, + playStalledRecord: {}, + keySessionCompleteRecord: {}, + playLikelyToKeepUpRecord: {}, + playRateChangedRecord: {}, + playErrorRecord: {}, + mediaEngineStalledRecord: {}, + switchCompleteRecord: {}, + variantEndedRecord: {}, + nwErrorRecord: {}, + }; + this.add(rtcEntity); + } + /* + * The below updates require an RTC event to be sent out, and hence an event payload needs to be prepared. + * => PlayEnded (6101) + * => Periodic (6110) + * => PlayStalled (6103) + * => KeySessionComplete (6104) + * => PlayLikelyToKeepUp (6105) + * => PlayRateChanged (6106) + * => PlayError (6107) + * => MediaEngineStalled (6108) + * => SwitchComplete (6109) + * => VariantEnded (6111) + * => NwError (6202) + */ + /* Indicates playback ended */ + updateEnded(itemId) { + this._prepareEventPlayEnded(itemId); + } + /* Indicates periodic timer fired */ + updatePeriodic(itemId, isFinal) { + this._prepareEventPeriodic(itemId, { isFinal }); + } + /* Indicates playback stall due to bad network */ + updateBufferStalled(itemId, data) { + this.update(itemId, ({ sessionControlRecord, variantEndedRecord, periodicRecord, playEndedRecord }) => { + sessionControlRecord.rate = 0; + variantEndedRecord.StallCount = (variantEndedRecord.StallCount || 0) + 1; + periodicRecord.StallCount = (periodicRecord.StallCount || 0) + 1; + playEndedRecord.StallCount = (playEndedRecord.StallCount || 0) + 1; + }); + this._prepareEventPlayStalled(itemId, data); + } + /* Indicates identity key session success / failure */ + updateSegmentKeyLoaded(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = {}; + const now = data.timestamp; + keySessionInfo.keyFormat = 'identity'; + keySessionInfo.keyDeliveryTime = data.adt; + keySessionInfo.currentMediaTime = data.currentTime; + if (sessionControlRecord.state === 'RTC_STATE_INIT') { + keySessionInfo.keyInitTime = now - sessionControlRecord.sessionStartTime; + } + sessionControlRecord.activeKeySessions[data.keyuri] = keySessionInfo; + }); + this._prepareEventKeySessionComplete(itemId, data); + } + /* Indicates non-identity (FPS/Widevine/PlayReady) key session success / failure events */ + updateLicenseResponseProcessed(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.licenseResponseProcessTime = data.timestamp - keySessionInfo.licenseResponseSubmitTime; + sessionControlRecord.lastKeyDeliveryTime = keySessionInfo.keyDeliveryTime = data.timestamp - keySessionInfo.licenseChallengeStartTime; + keySessionInfo.currentMediaTime = data.currentTime; + sessionControlRecord.finishedKeyUri = data.keyuri; + }); + this._prepareEventKeySessionComplete(itemId, data); + } + updateLicenseChallengeError(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + sessionControlRecord.lastKeyErrorType = keySessionInfo.keyErrorType = 'licenseChallengeError'; + sessionControlRecord.finishedKeyUri = data.keyuri; + }); + this._prepareEventKeySessionComplete(itemId, data); + } + updateLicenseResponseError(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + sessionControlRecord.lastKeyErrorType = keySessionInfo.keyErrorType = 'licenseResponseError'; + sessionControlRecord.finishedKeyUri = data.keyuri; + }); + this._prepareEventKeySessionComplete(itemId, data); + } + updateKeyAborted(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.keyErrorType = 'keyAborted'; + sessionControlRecord.finishedKeyUri = data.keyuri; + }); + this._prepareEventKeySessionComplete(itemId, data); + } + /* Indicates likely to keep up */ + updateCanPlay(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + // if (sessionControlRecord.state === 'RTC_STATE_PLAY') { + // /* Ignore if we're already in PLAY */ + // return; + // } + }); + this._prepareEventPlayLikelyToKeepUp(itemId, data); + } + /* Indicates rate changed */ + updateRateChanged(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.rate = data.rate * 100; + if (data.rate > 0 && sessionControlRecord.oldRate === 0) { + if (!sessionControlRecord.playInfo) { + sessionControlRecord.playInfo = []; + } + sessionControlRecord.playInfo.push({ latency: data.latency }); + // if curLevelUrl is not set at this point, we are in a scenario where the play event beats the levelSwitched event in a race + // conditon. To avoid a crash, set the curLevelUrl here. + if (!sessionControlRecord.curLevelUrl) { + sessionControlRecord.curLevelUrl = data.url; + } + } + }); + this._prepareEventPlayRateChanged(itemId, data); + } + /* Indicates play error */ + updateMediaError(itemId, data) { + this.update(itemId, ({ sessionControlRecord, periodicRecord, playEndedRecord }) => { + periodicRecord.PlayerErrCount = (periodicRecord.PlayerErrCount || 0) + 1; + playEndedRecord.PlayerErrCount = (playEndedRecord.PlayerErrCount || 0) + 1; + if (data.fatal) { + sessionControlRecord.rate = 0; + periodicRecord.FatalPlayerErrCount = (periodicRecord.FatalPlayerErrCount || 0) + 1; + playEndedRecord.FatalPlayerErrCount = (playEndedRecord.FatalPlayerErrCount || 0) + 1; + playEndedRecord.ErrCode = data.details; + playEndedRecord.ErrReason = data.code; + playEndedRecord.ErrIsFatal = true; + playEndedRecord.ErrDomain = 'mediaError'; + } + }); + if (data.fatal) { + this._prepareEventPlayError(itemId, data); + } + else { + this.update(itemId, ({ sessionControlRecord }) => { + // Non-fatal errors won't be sent immediately for each occurrence. Instead, they will be sent before the periodic event with the count of occurrences. + // We send separate events if the error code and reason are different. For e.g. fragLoadError due to 403 and fragLoadError due to 404 are counted separately. + const key = data.details + '/' + data.code; + sessionControlRecord.nonFatalPlayErrList[key] = (sessionControlRecord.nonFatalPlayErrList[key] || 0) + 1; + }); + } + } + /* Indicates media element error */ + updateMediaElementError(itemId, data) { + /* + Parse the media element error message. Luna encodes ErrReason & ErrDetail as follows. + "message": '{ + "ErrReason": -5001, // Luna error code + "ErrDetail": "0xce0defba" // Third party error code + }' + + Note: mediaElementError is not inserted into the 6101 payload. + */ + let errJson; + try { + errJson = JSON.parse(data.message); + } + catch (error) { + this.logger.warn(`message is not JSON, ignoring; ${data.message}`); + } + const mediaElemReason = errJson ? parseInt(errJson['ErrReason']) : null; + const mediaElemDetail = errJson ? parseInt(errJson['ErrDetail']) : null; + this._prepareEventPlayError(itemId, { + domain: 'mediaElementError', + mediaElemCode: data.code, + mediaElemReason: mediaElemReason, + mediaElemDetail: mediaElemDetail, + // These are fixed values for mediaElementError and set in _prepareEventPlayError + code: null, + details: null, + fatal: null, + }); + } + /* Indicates plaback stall due to media engine problem */ + updateMediaEngineStalled(itemId, data) { + this.update(itemId, ({ sessionControlRecord, variantEndedRecord, periodicRecord, playEndedRecord }) => { + sessionControlRecord.rate = 0; + variantEndedRecord.MediaEngineStallCount = (variantEndedRecord.MediaEngineStallCount || 0) + 1; + periodicRecord.MediaEngineStallCount = (periodicRecord.MediaEngineStallCount || 0) + 1; + playEndedRecord.MediaEngineStallCount = (playEndedRecord.MediaEngineStallCount || 0) + 1; + }); + this._prepareEventMediaEngineStalled(itemId, data); + } + /* Indicates level switch complete */ + updateLevelSwitched(itemId, data) { + this.update(itemId, ({ sessionControlRecord, switchCompleteRecord, periodicRecord, playEndedRecord }) => { + periodicRecord.SwCnt = (periodicRecord.SwCnt || 0) + 1; + playEndedRecord.SwCnt = (playEndedRecord.SwCnt || 0) + 1; + const now = Date.now(); + const prevLevelUrl = sessionControlRecord.curLevelUrl; + const curLevelUrl = data.url; + const prevVarInfo = this._getVariantInfo(prevLevelUrl, sessionControlRecord); + const curVarInfo = this._getVariantInfo(curLevelUrl, sessionControlRecord); + let curSwDir; + let iframes = false; + if (prevLevelUrl) { + if (curVarInfo.bandwidth < prevVarInfo.bandwidth) { + curSwDir = 'Down'; + } + else { + curSwDir = 'Up'; + } + iframes = curVarInfo.iframes; + } + switchCompleteRecord.BadSw = this._isBadSw(curSwDir, sessionControlRecord.lastSwitchDir || curSwDir, iframes, sessionControlRecord.lastLevelIsIframe || iframes, now, sessionControlRecord.lastSwitchTime || now, data.isSeeking); + sessionControlRecord.lastSwitchDir = curSwDir; + sessionControlRecord.lastSwitchTime = now; + sessionControlRecord.lastLevelIsIframe = iframes; + sessionControlRecord.curLevelUrl = curLevelUrl; + sessionControlRecord.variantStartTimeMedia = data.currentTime; + }); + this._prepareEventSwitchComplete(itemId, data); + } + /* Indicates level switch error */ + updateLevelLoadError(itemId, data) { + this.update(itemId, ({ sessionControlRecord, switchCompleteRecord, periodicRecord, playEndedRecord }) => { + const now = Date.now(); + let curSwDir; + let iframes = false; + if (sessionControlRecord.curLevelUrl) { + const prevVarInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + const curVarInfo = this._getVariantInfo(data.url, sessionControlRecord); + if (curVarInfo.bandwidth < prevVarInfo.bandwidth) { + curSwDir = 'Down'; + } + else { + curSwDir = 'Up'; + } + iframes = curVarInfo.iframes; + } + periodicRecord.SwCnt = (periodicRecord.SwCnt || 0) + 1; + playEndedRecord.SwCnt = (playEndedRecord.SwCnt || 0) + 1; + switchCompleteRecord.BadSw = this._isBadSw(curSwDir, sessionControlRecord.lastSwitchDir || curSwDir, iframes, sessionControlRecord.lastLevelIsIframe || iframes, now, sessionControlRecord.lastSwitchTime || now, data.isSeeking); + switchCompleteRecord.SwFail = true; + }); + this._prepareEventSwitchComplete(itemId, data); + } + /* Indicates variant end */ + updateVariantEnd(itemId, data) { + this._prepareEventVariantEnded(itemId, data); + } + /* Indicates network error */ + updateNwError(itemId, data) { + this.update(itemId, ({ sessionControlRecord, periodicRecord, playEndedRecord }) => { + periodicRecord.NwErrCount = (periodicRecord.NwErrCount || 0) + 1; + playEndedRecord.NwErrCount = (playEndedRecord.NwErrCount || 0) + 1; + if (data.fatal) { + sessionControlRecord.rate = 0; + periodicRecord.FatalNwErrCount = (periodicRecord.FatalNwErrCount || 0) + 1; + playEndedRecord.FatalNwErrCount = (playEndedRecord.FatalNwErrCount || 0) + 1; + playEndedRecord.ErrCode = data.details; + playEndedRecord.ErrReason = data.code; + playEndedRecord.ErrIsFatal = true; + playEndedRecord.ErrDomain = 'networkError'; + } + }); + if (data.fatal) { + this._prepareEventNwError(itemId, data); + } + else { + this.update(itemId, ({ sessionControlRecord }) => { + // Non-fatal errors won't be sent immediately for each occurrence. Instead, they will be sent before the periodic event with the count of occurrences. + // We send separate events if the error code and reason are different. For e.g. fragLoadError due to 403 and fragLoadError due to 404 are counted separately. + const key = data.details + '/' + data.code; + sessionControlRecord.nonFatalNwErrList[key] = (sessionControlRecord.nonFatalNwErrList[key] || 0) + 1; + }); + } + } + /* + * The below method is called after an event is sent out, to update the internal states. + */ + finalize(itemId, event) { + switch (event) { + case RTCEventGroup.PlayEnded: { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.state = 'RTC_STATE_STOP'; + sessionControlRecord.oldRate = 0; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.playEndedRecord = {}; + }); + break; + } + case RTCEventGroup.Periodic: { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.lastPeriodicTime = Date.now(); + sessionControlRecord.periodicEventCounter += 1; + /* Re-initialize playtime for all levels */ + const levels = Object.keys(sessionControlRecord.intervalVariantList); + levels.forEach((level) => { + sessionControlRecord.intervalVariantList[level].playTime = 0; + }); + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.periodicRecord = {}; + }); + break; + } + case RTCEventGroup.PlayStalled: { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.state = 'RTC_STATE_STALL'; + sessionControlRecord.oldRate = 0; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.playStalledRecord = {}; + }); + break; + } + case RTCEventGroup.KeySessionComplete: { + this.update(itemId, ({ sessionControlRecord }) => { + delete sessionControlRecord.activeKeySessions[sessionControlRecord.finishedKeyUri]; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.keySessionCompleteRecord = {}; + }); + break; + } + case RTCEventGroup.PlayLikelyToKeepUp: { + this.update(itemId, ({ sessionControlRecord }) => { + if (sessionControlRecord.state !== 'RTC_STATE_PLAY') { + /* Ignore if we're already in PLAY */ + sessionControlRecord.state = 'RTC_STATE_CANPLAY'; + sessionControlRecord.lastLikelyToKeepUpTime = Date.now(); + sessionControlRecord.playLikelyToKeepUpEventCounter += 1; + } + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.playLikelyToKeepUpRecord = {}; + }); + break; + } + case RTCEventGroup.PlayRateChanged: { + this.update(itemId, ({ sessionControlRecord, playEndedRecord, playStalledRecord, mediaEngineStalledRecord, playErrorRecord, nwErrorRecord }) => { + if (sessionControlRecord.rate !== 0) { + sessionControlRecord.state = 'RTC_STATE_PLAY'; + // reset the below keys as we resume playback + delete playEndedRecord.LastStall; + delete playEndedRecord.LastMediaEngineStall; + delete playEndedRecord.LastPause; + delete playErrorRecord.LastPause; + delete nwErrorRecord.LastPause; + } + else { + sessionControlRecord.state = 'RTC_STATE_PAUSE'; + // reset the below keys as we pause playback + delete playStalledRecord.LastResume; + delete mediaEngineStalledRecord.LastResume; + delete playErrorRecord.LastResume; + delete nwErrorRecord.LastResume; + } + /* Update the old rate */ + sessionControlRecord.oldRate = sessionControlRecord.rate; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.playRateChangedRecord = {}; + }); + break; + } + case RTCEventGroup.PlayError: { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.state = 'RTC_STATE_PLAYERROR'; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.playErrorRecord = {}; + }); + break; + } + case RTCEventGroup.MediaEngineStalled: { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.state = 'RTC_STATE_MEDIAENGINESTALL'; + sessionControlRecord.oldRate = 0; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.mediaEngineStalledRecord = {}; + }); + break; + } + case RTCEventGroup.SwitchComplete: { + /* Reset the event record */ + this.update(itemId, (state) => { + state.switchCompleteRecord = {}; + // record the level transition + state.sessionControlRecord.prevLevelUrl = state.sessionControlRecord.curLevelUrl; + }); + break; + } + case RTCEventGroup.VariantEnded: { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.decodedFramesForVariant = 0; + sessionControlRecord.decodedFramesForVariantSampleCount = 0; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.variantEndedRecord = {}; + }); + break; + } + case RTCEventGroup.NwError: { + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.state = 'RTC_STATE_NWERROR'; + }); + /* Reset the event record */ + this.update(itemId, (state) => { + state.nwErrorRecord = {}; + }); + break; + } + } + /* Finally, reset the event clock */ + this.update(itemId, ({ sessionControlRecord }) => { + sessionControlRecord.eventStartTime = Date.now(); + }); + } + /* + * The below updates don't involve an RTC event to be sent out. + * These updates just aggregate data in the store for various RTC records. + */ + updatePlaybackInfo(itemId, data) { + this.update(itemId, ({ sessionControlRecord, periodicRecord, playEndedRecord }) => { + if (data.droppedVideoFrames < sessionControlRecord.droppedVideoFrames) { + // MSE counter reset, so reset ours too + sessionControlRecord.droppedVideoFrames = 0; + } + if (data.decodedFrameCount < sessionControlRecord.decodedFrameCount) { + // MSE counter reset, so reset ours too + sessionControlRecord.decodedFrameCount = 0; + } + // we get the dropped frames and decoded frames from the MSE object every second. Calculate the current frame drop and frame rate. + const curFrameDrop = data.droppedVideoFrames - (sessionControlRecord.droppedVideoFrames || 0); + const decodedFramesPerSec = data.decodedFrameCount - (sessionControlRecord.decodedFrameCount || 0); + sessionControlRecord.droppedVideoFrames = data.droppedVideoFrames; + sessionControlRecord.decodedFrameCount = data.decodedFrameCount; + // update the decode frames for the current variant to compute average decode frame count for the variant + sessionControlRecord.decodedFramesForVariant += decodedFramesPerSec; + sessionControlRecord.decodedFramesForVariantSampleCount += 1; + if (curFrameDrop) { + // if we drop 3 or more frames per second, then that's a group frame drop. + if (curFrameDrop >= 3) { + periodicRecord.GroupViFrDr = (periodicRecord.GroupViFrDr || 0) + curFrameDrop; + periodicRecord.GroupViFrDrEvtCount = (periodicRecord.GroupViFrDrEvtCount || 0) + 1; + playEndedRecord.GroupViFrDr = (playEndedRecord.GroupViFrDr || 0) + curFrameDrop; + playEndedRecord.GroupViFrDrEvtCount = (playEndedRecord.GroupViFrDrEvtCount || 0) + 1; + } + else { + periodicRecord.SparseViFrDr = (periodicRecord.SparseViFrDr || 0) + curFrameDrop; + periodicRecord.SparseViFrDrEvtCount = (periodicRecord.SparseViFrDrEvtCount || 0) + 1; + playEndedRecord.SparseViFrDr = (playEndedRecord.SparseViFrDr || 0) + curFrameDrop; + playEndedRecord.SparseViFrDrEvtCount = (playEndedRecord.SparseViFrDrEvtCount || 0) + 1; + } + } + }); + } + updateBufferAppended(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + if (!sessionControlRecord.bufferAppendInfo) { + sessionControlRecord.bufferAppendInfo = []; + } + sessionControlRecord.bufferAppendInfo.push(data); + }); + } + updateSeeked(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + if (!sessionControlRecord.seekInfo) { + sessionControlRecord.seekInfo = []; + } + sessionControlRecord.seekInfo.push(data); + }); + } + updateManifestParsed(itemId, data) { + this.update(itemId, ({ sessionControlRecord, periodicRecord, playEndedRecord }) => { + periodicRecord.MasterPlaylistADT = (periodicRecord.MasterPlaylistADT || 0) + data.adt; + playEndedRecord.MasterPlaylistADT = (playEndedRecord.MasterPlaylistADT || 0) + data.adt; + const result = this._computeVariantInfo(data.levels); + // update the common keys + playEndedRecord.IsAudioOnly = data.isAudioOnly; + playEndedRecord.IsGapless = data.isGapless; + playEndedRecord.IsFirstItem = data.isFirstItem; + playEndedRecord.ItemID = data.itemID; + playEndedRecord.MaxVideoQltyIndex = result.maxVideoQltyIndex; + playEndedRecord.MaxReWd = result.maxWidth; + playEndedRecord.MaxReHt = result.maxHeight; + sessionControlRecord.manifestData = { variantList: result.variantList, varListString: result.varListString }; + }); + } + updateFragLoaded(itemId, data) { + this.update(itemId, ({ sessionControlRecord, periodicRecord, playEndedRecord }) => { + periodicRecord.MediaRequestsSent = (periodicRecord.MediaRequestsSent || 0) + 1; + playEndedRecord.MediaRequestsSent = (playEndedRecord.MediaRequestsSent || 0) + 1; + if (data.cdnServer) { + const cdnServer = data.cdnServer.toLowerCase(); + if (cdnServer === 'aapl' || cdnServer === 'akam' || cdnServer === 'llnw') { + playEndedRecord.LastMediaCDNServer = cdnServer; + } + } + if (data.serverInfo) { + playEndedRecord.ServerInfo = data.serverInfo; + } + if (!sessionControlRecord.segmentMimeTypes) { + sessionControlRecord.segmentMimeTypes = []; + } + if (sessionControlRecord.segmentMimeTypes.find((mime) => mime == data.contentType) === undefined) { + sessionControlRecord.segmentMimeTypes.push(data.contentType); + } + if (data.fragType === MediaOptionType.Variant) { + // accumulate the 'main' (muxed) / 'video' (unmuxed) bytes & duration to calculate AvgVideoBitrate + sessionControlRecord.variantVideoBytes = (sessionControlRecord.variantVideoBytes || 0) + data.bytes; + sessionControlRecord.variantVideoDuration = (sessionControlRecord.variantVideoDuration || 0) + data.duration; + sessionControlRecord.intervalVideoBytes = (sessionControlRecord.intervalVideoBytes || 0) + data.bytes; + sessionControlRecord.intervalVideoDuration = (sessionControlRecord.intervalVideoDuration || 0) + data.duration; + sessionControlRecord.sessionVideoBytes = (sessionControlRecord.sessionVideoBytes || 0) + data.bytes; + sessionControlRecord.sessionVideoDuration = (sessionControlRecord.sessionVideoDuration || 0) + data.duration; + sessionControlRecord.obrLast = (data.bytes * 8) / (data.duration / 1000); + /* Update periodic record */ + periodicRecord.NetBytes = (periodicRecord.NetBytes || 0) + data.bytes; + periodicRecord.ADT = (periodicRecord.ADT || 0) + data.adt; + periodicRecord.SegmentProcessTime = (periodicRecord.SegmentProcessTime || 0) + data.processTime; + /* Update playEnded record */ + playEndedRecord.ADT = (playEndedRecord.ADT || 0) + data.adt; + playEndedRecord.NetBytes = (playEndedRecord.NetBytes || 0) + data.bytes; + playEndedRecord.SegmentProcessTime = (playEndedRecord.SegmentProcessTime || 0) + data.processTime; + } + else if (data.fragType === MediaOptionType.AltAudio) { + // accumulate the 'audio' bytes & duration to calculate AvgAudioBitrate + sessionControlRecord.variantAudioBytes = (sessionControlRecord.variantAudioBytes || 0) + data.bytes; + sessionControlRecord.variantAudioDuration = (sessionControlRecord.variantAudioDuration || 0) + data.duration; + sessionControlRecord.intervalAudioBytes = (sessionControlRecord.intervalAudioBytes || 0) + data.bytes; + sessionControlRecord.intervalAudioDuration = (sessionControlRecord.intervalAudioDuration || 0) + data.duration; + sessionControlRecord.sessionAudioBytes = (sessionControlRecord.sessionAudioBytes || 0) + data.bytes; + sessionControlRecord.sessionAudioDuration = (sessionControlRecord.sessionAudioDuration || 0) + data.duration; + } + }); + } + updateFragBuffered(itemId, data) { + this.update(itemId, ({ periodicRecord, playEndedRecord }) => { + // use only 'main' (muxed) / 'video' (unmuxed) data to calculate below keys + if (data.fragType === MediaOptionType.Variant) { + /* Update periodic record */ + periodicRecord.SegmentParseTime = (periodicRecord.SegmentParseTime || 0) + data.parseTime; + /* Update playEnded record */ + playEndedRecord.SegmentParseTime = (playEndedRecord.SegmentParseTime || 0) + data.parseTime; + } + }); + } + updateLevelLoaded(itemId, data) { + this.update(itemId, ({ sessionControlRecord, playLikelyToKeepUpRecord, periodicRecord, playEndedRecord }) => { + playLikelyToKeepUpRecord.PlaylistADT = (playLikelyToKeepUpRecord.PlaylistADT || 0) + data.adt; + periodicRecord.PlaylistADT = (periodicRecord.PlaylistADT || 0) + data.adt; + playEndedRecord.PlaylistADT = (playEndedRecord.PlaylistADT || 0) + data.adt; + periodicRecord.MaxPlaylistDT = data.adt > periodicRecord.MaxPlaylistDT ? data.adt : periodicRecord.MaxPlaylistDT; + playEndedRecord.MaxPlaylistDT = data.adt > playEndedRecord.MaxPlaylistDT ? data.adt : playEndedRecord.MaxPlaylistDT; + playEndedRecord.PlayType = data.playType; + this._setTargetDuration(data.url, data.targetduration, sessionControlRecord); + if (!sessionControlRecord.playlistMimeTypes) { + sessionControlRecord.playlistMimeTypes = []; + } + if (sessionControlRecord.playlistMimeTypes.find((mime) => mime == data.contentType) === undefined) { + sessionControlRecord.playlistMimeTypes.push(data.contentType); + } + const curLevelUrl = data.url; + const curVarInfo = this._getVariantInfo(curLevelUrl, sessionControlRecord); + // Initialize the variant info if it's not seen before + if (!sessionControlRecord.intervalVariantList[curLevelUrl]) { + sessionControlRecord.intervalVariantList[curLevelUrl] = Object.assign({}, curVarInfo); + } + if (!sessionControlRecord.sessionVariantList[curLevelUrl]) { + sessionControlRecord.sessionVariantList[curLevelUrl] = Object.assign({}, curVarInfo); + } + }); + } + updateLevelsChanged(itemId, data) { + this.update(itemId, ({ sessionControlRecord, playEndedRecord }) => { + const result = this._computeVariantInfo(data.levels); + playEndedRecord.MaxVideoQltyIndex = result.maxVideoQltyIndex; + playEndedRecord.MaxReWd = result.maxWidth; + playEndedRecord.MaxReHt = result.maxHeight; + sessionControlRecord.manifestData = { variantList: result.variantList, varListString: result.varListString }; + // Update bitrate rank in sessionVariantList and intervalVariantList + Object.keys(result.variantList).forEach((url) => { + if (sessionControlRecord.intervalVariantList[url]) { + sessionControlRecord.intervalVariantList[url].brRnk = result.variantList[url].brRnk; + } + if (sessionControlRecord.sessionVariantList[url]) { + sessionControlRecord.sessionVariantList[url].brRnk = result.variantList[url].brRnk; + } + }); + }); + } + updateLicenseChallengeRequested(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = {}; + const now = data.timestamp; + keySessionInfo.licenseChallengeStartTime = now; + // send the keyInitTime if we're initializing playback + if (sessionControlRecord.state === 'RTC_STATE_INIT') { + keySessionInfo.keyInitTime = now - sessionControlRecord.sessionStartTime; + } + sessionControlRecord.activeKeySessions[data.keyuri] = keySessionInfo; + }); + } + updateLicenseChallengeReceived(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.licenseChallengeRequestTime = data.timestamp - keySessionInfo.licenseChallengeStartTime; + }); + } + updateLicenseChallengeSubmitted(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.keyFormat = data.keyFormat; + keySessionInfo.licenseChallengeSubmitTime = data.timestamp; + }); + } + updateLicenseChallengeCreated(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.cdmVersion = data.cdmVersion; + keySessionInfo.licenseChallengeCreationTime = data.timestamp - keySessionInfo.licenseChallengeSubmitTime; + }); + } + updateLicenseResponseRequested(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.licenseResponseRequestTime = data.timestamp; + }); + } + updateLicenseResponseReceived(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.licenseResponseReceiveTime = data.timestamp - keySessionInfo.licenseResponseRequestTime; + }); + } + updateLicenseResponseSubmitted(itemId, data) { + this.update(itemId, ({ sessionControlRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + keySessionInfo.licenseResponseSubmitTime = data.timestamp; + }); + } + /* + * Private Methods + */ + _prepareEventPlayEnded(itemId) { + this.update(itemId, ({ sessionControlRecord, playEndedRecord }) => { + var _a; + playEndedRecord.AvgVideoBitrate = ((sessionControlRecord.sessionVideoBytes || 0) * 8) / (sessionControlRecord.sessionVideoDuration || 1); + playEndedRecord.AvgAudioBitrate = ((sessionControlRecord.sessionAudioBytes || 0) * 8) / (sessionControlRecord.sessionAudioDuration || 1); + // round off NetBytes to the nearest 1000 to obscure the content size - as requested by privacy team. + const netBytes = Math.round((playEndedRecord.NetBytes || 0) / 1000) * 1000; + playEndedRecord.NetBytes = netBytes; + const adt = playEndedRecord.ADT || 1; + const processTime = playEndedRecord.ADT + playEndedRecord.SegmentProcessTime || 1; + const parseTime = playEndedRecord.ADT + playEndedRecord.SegmentProcessTime + playEndedRecord.SegmentParseTime || 1; + playEndedRecord.TWOBR = (netBytes * 8) / (adt / 1000); + playEndedRecord.PerceivedTWOBR = (netBytes * 8) / (processTime / 1000); + playEndedRecord.NetTWOBR = (netBytes * 8) / (parseTime / 1000); + // Use the playtime for the current level too, before generating time weighted values + const twVal = this._findTimeWeightedValues(sessionControlRecord.state === 'RTC_STATE_PLAY' ? Date.now() - sessionControlRecord.eventStartTime : 0, sessionControlRecord.sessionVariantList, sessionControlRecord.curLevelUrl); + playEndedRecord.PlayerTWIBR = twVal.twIBR; + playEndedRecord.PlayerTWIABR = twVal.twIABR; + playEndedRecord.TWBitRk = twVal.twBRnk; + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + playEndedRecord.TargetDur = varInfo.targetduration; + playEndedRecord.ReWd = varInfo.width; + playEndedRecord.ReHt = varInfo.height; + playEndedRecord.VariantList = (_a = sessionControlRecord.manifestData) === null || _a === void 0 ? void 0 : _a.varListString; + let playlistMimeType = ''; + if (sessionControlRecord.playlistMimeTypes) { + sessionControlRecord.playlistMimeTypes.forEach((item) => { + playlistMimeType += item + ','; + }); + playlistMimeType = playlistMimeType.slice(0, -1); // remove the trailing comma + } + let segmentMimeType = ''; + if (sessionControlRecord.segmentMimeTypes) { + sessionControlRecord.segmentMimeTypes.forEach((item) => { + segmentMimeType += item + ','; + }); + segmentMimeType = segmentMimeType.slice(0, -1); // remove the trailing comma + } + playEndedRecord.PlaylistMimeType = playlistMimeType; + playEndedRecord.SegmentMimeType = segmentMimeType; + playEndedRecord.Rate = sessionControlRecord.rate; + }); + this._aggregateTimes(itemId); + } + _prepareEventPeriodic(itemId, data) { + this.update(itemId, ({ sessionControlRecord, periodicRecord, playEndedRecord }) => { + var _a; + periodicRecord.EventCounter = sessionControlRecord.periodicEventCounter; + periodicRecord.PInterval = Date.now() - sessionControlRecord.lastPeriodicTime; + periodicRecord.AvgVideoBitrate = ((sessionControlRecord.intervalVideoBytes || 0) * 8) / (sessionControlRecord.intervalVideoDuration || 1); + periodicRecord.AvgAudioBitrate = ((sessionControlRecord.intervalAudioBytes || 0) * 8) / (sessionControlRecord.intervalAudioDuration || 1); + let netBytes = periodicRecord.NetBytes || 0; + if (data.isFinal) { + // round off NetBytes to the nearest 1000 to obscure the content size - as requested by privacy team. (for periodic event, we need this only for the last event) + periodicRecord.NetBytes = netBytes = Math.round(netBytes / 1000) * 1000; + } + const adt = periodicRecord.ADT || 1; + const processTime = periodicRecord.ADT + periodicRecord.SegmentProcessTime || 1; + const parseTime = periodicRecord.ADT + periodicRecord.SegmentProcessTime + periodicRecord.SegmentParseTime || 1; + periodicRecord.TWOBR = (netBytes * 8) / (adt / 1000); + periodicRecord.PerceivedTWOBR = (netBytes * 8) / (processTime / 1000); + periodicRecord.NetTWOBR = (netBytes * 8) / (parseTime / 1000); + // Use the playtime for the current level too, before generating time weighted values + const twVal = this._findTimeWeightedValues(sessionControlRecord.state === 'RTC_STATE_PLAY' ? Date.now() - sessionControlRecord.eventStartTime : 0, sessionControlRecord.intervalVariantList, sessionControlRecord.curLevelUrl); + periodicRecord.PlayerTWIBR = twVal.twIBR; + periodicRecord.PlayerTWIABR = twVal.twIABR; + periodicRecord.TWBitRk = twVal.twBRnk; + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + periodicRecord.TargetDur = varInfo.targetduration; + periodicRecord.ReWd = varInfo.width; + periodicRecord.ReHt = varInfo.height; + periodicRecord.VariantList = (_a = sessionControlRecord.manifestData) === null || _a === void 0 ? void 0 : _a.varListString; + periodicRecord.Rate = sessionControlRecord.rate; + const stats = this._computeMediaStats(sessionControlRecord); + if (stats) { + periodicRecord.MedianBufferAppendLatency = stats.bufLatencyInfo.median; + periodicRecord.MaxBufferAppendLatency = stats.bufLatencyInfo.max; + periodicRecord.MedianBufferAppendSize = stats.bufSizeInfo.median; + periodicRecord.MaxBufferAppendSize = stats.bufSizeInfo.max; + periodicRecord.MedianSeekLatency = stats.seekLatencyInfo.median; + periodicRecord.MaxSeekLatency = stats.seekLatencyInfo.max; + periodicRecord.MedianPlayLatency = stats.playLatencyInfo.median; + periodicRecord.MaxPlayLatency = stats.playLatencyInfo.max; + } + this._copyCommonKeys(periodicRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventPlayStalled(itemId, data) { + this.update(itemId, ({ sessionControlRecord, playStalledRecord, playEndedRecord }) => { + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + const now = Date.now(); + playStalledRecord.MediaDur = data.mediaDur; + playStalledRecord.BitRnk = varInfo.brRnk; + playStalledRecord.Codecs = varInfo.codecs; + playStalledRecord.LastLikelyToKeepUp = now - sessionControlRecord.lastLikelyToKeepUpTime; + playStalledRecord.LastSwitch = now - sessionControlRecord.lastSwitchTime; + playStalledRecord.StallDetectionTime = data.stallDurationMs; + playStalledRecord.StallType = data.type; + playStalledRecord.BufferLength = data.bufferLen; + if (playEndedRecord.ErrDomain === 'networkError') { + playStalledRecord.NwErrTime = playEndedRecord.NwErrTime; + playStalledRecord.NwErrCode = playEndedRecord.ErrCode; + } + playStalledRecord.LaSwDir = sessionControlRecord.lastSwitchDir; + playStalledRecord.TargetDur = varInfo.targetduration; + playStalledRecord.PlayerIABR = varInfo.avgBandwidth; + playStalledRecord.PlayerIBR = varInfo.bandwidth; + playStalledRecord.Rate = sessionControlRecord.rate; + playStalledRecord.OBRLast = sessionControlRecord.obrLast; + playStalledRecord.OBRMean = (playEndedRecord.NetBytes * 8) / (playEndedRecord.ADT / 1000); + this._copyCommonKeys(playStalledRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventKeySessionComplete(itemId, data) { + this.update(itemId, ({ sessionControlRecord, keySessionCompleteRecord, playEndedRecord }) => { + const keySessionInfo = sessionControlRecord.activeKeySessions[data.keyuri]; + if (!keySessionInfo) { + this.logger.warn(`_prepareEventKeySessionComplete no keySessionInfo for ${redactUrl(data.keyuri)}`); + return; + } + keySessionCompleteRecord.KeyFormat = keySessionInfo.keyFormat; + keySessionCompleteRecord.CDMVersion = keySessionInfo.cdmVersion; + keySessionCompleteRecord.LicenseChallengeRequestTime = keySessionInfo.licenseChallengeRequestTime; + keySessionCompleteRecord.LicenseChallengeCreationTime = keySessionInfo.licenseChallengeCreationTime; + keySessionCompleteRecord.LicenseResponseReceiveTime = keySessionInfo.licenseResponseReceiveTime; + keySessionCompleteRecord.LicenseResponseProcessTime = keySessionInfo.licenseResponseProcessTime; + keySessionCompleteRecord.KeyDeliveryTime = keySessionInfo.keyDeliveryTime; + keySessionCompleteRecord.CurrentMediaTime = keySessionInfo.currentMediaTime * 1000; + keySessionCompleteRecord.KeyInitTime = keySessionInfo.keyInitTime; + keySessionCompleteRecord.KeyErrorType = keySessionInfo.keyErrorType; + this._copyCommonKeys(keySessionCompleteRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventPlayLikelyToKeepUp(itemId, data) { + this.update(itemId, ({ sessionControlRecord, playLikelyToKeepUpRecord, playEndedRecord }) => { + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + playLikelyToKeepUpRecord.EventCounter = sessionControlRecord.playLikelyToKeepUpEventCounter; + playLikelyToKeepUpRecord.PlayerIABR = varInfo.avgBandwidth; + playLikelyToKeepUpRecord.PlayerIBR = varInfo.bandwidth; + playLikelyToKeepUpRecord.MediaDur = data.mediaDur; + playLikelyToKeepUpRecord.BitRnk = varInfo.brRnk; + playLikelyToKeepUpRecord.Codecs = varInfo.codecs; + playLikelyToKeepUpRecord.TargetDur = varInfo.targetduration; + this._copyCommonKeys(playLikelyToKeepUpRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventPlayRateChanged(itemId, data) { + this.update(itemId, ({ sessionControlRecord, playRateChangedRecord, playEndedRecord }) => { + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + playRateChangedRecord.Rate = sessionControlRecord.rate; + playRateChangedRecord.StNPT = data.currentTime; + playRateChangedRecord.PlayerIABR = varInfo.avgBandwidth; + playRateChangedRecord.PlayerIBR = varInfo.bandwidth; + playRateChangedRecord.BitRnk = varInfo.brRnk; + playRateChangedRecord.MediaDur = data.mediaDur; + playRateChangedRecord.Codecs = varInfo.codecs; + this._copyCommonKeys(playRateChangedRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventPlayError(itemId, data) { + this.update(itemId, ({ sessionControlRecord, playErrorRecord, playEndedRecord }) => { + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + const now = Date.now(); + if (data.domain == 'mediaElementError') { + playErrorRecord.ErrDomain = playErrorRecord.ErrCode = 'mediaElementError'; + playErrorRecord.ErrIsFatal = true; + playErrorRecord.ErrCodeMediaElement = data.mediaElemCode; + playErrorRecord.ErrReason = data.mediaElemReason; + playErrorRecord.ErrDetail = data.mediaElemDetail; + } + else { + playErrorRecord.ErrCode = data.details; + playErrorRecord.ErrReason = data.code; + playErrorRecord.ErrIsFatal = data.fatal; + playErrorRecord.ErrDomain = 'mediaError'; + } + playErrorRecord.PlayerErrCount = data.count || 1; + playErrorRecord.BitRnk = varInfo.brRnk; + playErrorRecord.MediaDur = data.mediaDur; + playErrorRecord.PlayTime = playEndedRecord.PlayTime; + playErrorRecord.PlayTimeWC = playEndedRecord.PlayTimeWC; + playErrorRecord.PlayerIABR = varInfo.avgBandwidth; + playErrorRecord.PlayerIBR = varInfo.bandwidth; + playErrorRecord.LastLikelyToKeepUp = now - sessionControlRecord.lastLikelyToKeepUpTime; + playErrorRecord.LastSwitch = now - sessionControlRecord.lastSwitchTime; + playErrorRecord.VideoQltyIndex = varInfo.qltyIndex; + playErrorRecord.Rate = sessionControlRecord.rate; + playErrorRecord.KeyErrorType = sessionControlRecord.lastKeyErrorType; + playErrorRecord.KeyDeliveryTime = sessionControlRecord.lastKeyDeliveryTime; + this._copyCommonKeys(playErrorRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventMediaEngineStalled(itemId, data) { + this.update(itemId, ({ sessionControlRecord, mediaEngineStalledRecord, playEndedRecord }) => { + const now = Date.now(); + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + mediaEngineStalledRecord.MediaDur = data.mediaDur; + mediaEngineStalledRecord.BitRnk = varInfo.brRnk; + mediaEngineStalledRecord.Codecs = varInfo.codecs; + mediaEngineStalledRecord.LastLikelyToKeepUp = now - sessionControlRecord.lastLikelyToKeepUpTime; + mediaEngineStalledRecord.LastSwitch = now - sessionControlRecord.lastSwitchTime; + mediaEngineStalledRecord.StallDetectionTime = data.stallDurationMs; + mediaEngineStalledRecord.StallType = data.type; + mediaEngineStalledRecord.BufferLength = data.bufferLen; + mediaEngineStalledRecord.LaSwDir = sessionControlRecord.lastSwitchDir; + mediaEngineStalledRecord.TargetDur = varInfo.targetduration; + mediaEngineStalledRecord.PlayerIABR = varInfo.avgBandwidth; + mediaEngineStalledRecord.PlayerIBR = varInfo.bandwidth; + mediaEngineStalledRecord.Rate = sessionControlRecord.rate; + mediaEngineStalledRecord.OBRLast = sessionControlRecord.obrLast; + mediaEngineStalledRecord.OBRMean = (playEndedRecord.NetBytes * 8) / (playEndedRecord.ADT / 1000); + this._copyCommonKeys(mediaEngineStalledRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventSwitchComplete(itemId, data) { + this.update(itemId, ({ sessionControlRecord, switchCompleteRecord, playEndedRecord }) => { + const fromVarInfo = this._getVariantInfo(sessionControlRecord.prevLevelUrl, sessionControlRecord); + const toVarInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + switchCompleteRecord.FrBitRnk = fromVarInfo.brRnk; + switchCompleteRecord.ToBitRnk = toVarInfo.brRnk; + switchCompleteRecord.TimeToBitrate = Date.now() - sessionControlRecord.sessionStartTime; + switchCompleteRecord.MediaDur = data.mediaDur; + switchCompleteRecord.Rate = sessionControlRecord.rate; + switchCompleteRecord.PlayerIBR = toVarInfo.bandwidth; + switchCompleteRecord.PlayerIABR = toVarInfo.avgBandwidth; + switchCompleteRecord.LastPlayerIBR = fromVarInfo.bandwidth; + switchCompleteRecord.LastPlayerIABR = fromVarInfo.avgBandwidth; + switchCompleteRecord.ReWd = toVarInfo.width; + switchCompleteRecord.ReHt = toVarInfo.height; + this._copyCommonKeys(switchCompleteRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventVariantEnded(itemId, data) { + this.update(itemId, ({ sessionControlRecord, variantEndedRecord, playEndedRecord }) => { + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + variantEndedRecord.Rate = sessionControlRecord.rate; + variantEndedRecord.VarAvgBitrate = varInfo.avgBandwidth; + variantEndedRecord.VarPeakBitrate = varInfo.bandwidth; + variantEndedRecord.VarBitRk = varInfo.brRnk; + variantEndedRecord.VarSTTime = sessionControlRecord.variantStartTimeMedia; + variantEndedRecord.VarEndTime = data.currentTime * 1000; + variantEndedRecord.IFR = varInfo.framerate; + variantEndedRecord.ODR = sessionControlRecord.decodedFramesForVariant / sessionControlRecord.decodedFramesForVariantSampleCount; + variantEndedRecord.ReWd = varInfo.width; + variantEndedRecord.ReHt = varInfo.height; + variantEndedRecord.Codecs = varInfo.codecs; + variantEndedRecord.AvgVideoBitrate = ((sessionControlRecord.variantVideoBytes || 0) * 8) / (sessionControlRecord.variantVideoDuration || 1); + variantEndedRecord.AvgAudioBitrate = ((sessionControlRecord.variantAudioBytes || 0) * 8) / (sessionControlRecord.variantAudioDuration || 1); + this._copyCommonKeys(variantEndedRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _prepareEventNwError(itemId, data) { + this.update(itemId, ({ sessionControlRecord, nwErrorRecord, playEndedRecord }) => { + const varInfo = this._getVariantInfo(sessionControlRecord.curLevelUrl, sessionControlRecord); + nwErrorRecord.ErrCode = data.details; + nwErrorRecord.ErrReason = data.code; + nwErrorRecord.ErrIsFatal = data.fatal; + nwErrorRecord.NwErrCount = data.count || 1; + nwErrorRecord.ErrDomain = 'networkError'; + nwErrorRecord.PlayTime = playEndedRecord.PlayTime; + nwErrorRecord.PlayTimeWC = playEndedRecord.PlayTimeWC; + nwErrorRecord.BitRnk = varInfo.brRnk; + nwErrorRecord.Rate = sessionControlRecord.rate; + nwErrorRecord.KeyErrorType = sessionControlRecord.lastKeyErrorType; + nwErrorRecord.KeyDeliveryTime = sessionControlRecord.lastKeyDeliveryTime; + this._copyCommonKeys(nwErrorRecord, playEndedRecord); + }); + this._aggregateTimes(itemId); + } + _copyCommonKeys(dst, src) { + dst.PlayType = src.PlayType; + dst.LastMediaCDNServer = src.LastMediaCDNServer; + dst.MaxVideoQltyIndex = src.MaxVideoQltyIndex; + dst.MaxReWd = src.MaxReWd; + dst.MaxReHt = src.MaxReHt; + dst.IsGapless = src.IsGapless; + dst.IsAudioOnly = src.IsAudioOnly; + dst.IsFirstItem = src.IsFirstItem; + dst.ItemID = src.ItemID; + dst.ServerInfo = src.ServerInfo; + } + _computeVariantInfo(levels) { + const variantList = {}; + let maxWidth = 0; + let maxHeight = 0; + let maxProd = 0; + let maxVideoQltyIndex = 0; + const maxNormalizedPeak = this._getMaxNormalizedPeak(levels); + levels.forEach((item) => { + if (item.attrs) { + const fourCC = this._getVideoFourCC(item.attrs.CODECS); + const qltyIndex = this._getVideoQualityIndex(fourCC, item.attrs['VIDEO-RANGE']) || 0; + const variantInfo = { + codecs: item.attrs.CODECS, + width: item.width, + height: item.height, + bandwidth: item.attrs.BANDWIDTH, + avgBandwidth: item.attrs['AVERAGE-BANDWIDTH'], + framerate: item.attrs['FRAME-RATE'], + iframes: item.iframes, + brRnk: this._getBitrateRank(item.attrs.BANDWIDTH, fourCC, maxNormalizedPeak), + qltyIndex: qltyIndex, + targetduration: 0, + playTime: 0, + }; + maxVideoQltyIndex = qltyIndex > maxVideoQltyIndex ? qltyIndex : maxVideoQltyIndex; + // store variant data against the url + variantList[item.url] = variantInfo; + } + const prod = item.width * item.height; + if (prod > maxProd) { + maxProd = prod; + maxWidth = item.width; + maxHeight = item.height; + } + }); + const varListString = Object.keys(variantList).length > 0 + ? Object.values(variantList) + .map((item) => item.bandwidth + ':' + item.avgBandwidth) + .join(',') + : undefined; + return { variantList: variantList, varListString: varListString, maxVideoQltyIndex: maxVideoQltyIndex, maxWidth: maxWidth, maxHeight: maxHeight }; + } + _getMaxNormalizedPeak(levels) { + let maxNormalizedPeak = 0; + levels.forEach((level) => { + const attrs = level.attrs; + if (attrs) { + const peak = attrs.BANDWIDTH || 0; + const normPeak = this._getNormalizedPeak(peak, this._getVideoFourCC(attrs.CODECS)); + const curMax = Math.max(peak, normPeak); + maxNormalizedPeak = curMax > maxNormalizedPeak ? curMax : maxNormalizedPeak; + } + }); + return maxNormalizedPeak; + } + _getNormalizedPeak(peak, fourCC) { + // Normalization factor for avc family is 1 and for hevc/dolby family is 1.5. + return typeof RTCVideoQualityIndex[fourCC] === 'object' ? peak * 1.5 : peak * 1; + } + _getVideoFourCC(codecs) { + return codecs + ? codecs + .split(',') + .map((item) => item.split('.')[0].trim()) + .find((item) => !!RTCVideoQualityIndex[item]) + : codecs; + } + _getVideoQualityIndex(fourCC, range) { + return typeof RTCVideoQualityIndex[fourCC] === 'object' ? RTCVideoQualityIndex[fourCC][range] : RTCVideoQualityIndex[fourCC]; + } + _getBitrateRank(peak, fourCC, maxNormalizedPeak) { + const normPeak = Math.max(1, this._getNormalizedPeak(peak, fourCC)); + return Math.ceil((normPeak * 100) / maxNormalizedPeak); + } + _findTimeWeightedValues(playTime, list, curLevel) { + const result = { twBRnk: 0, twIBR: 0, twIABR: 0 }; + if (list) { + let totalBitRk = 0; + let totalTWIB = 0; + let totalPlaytime = 0; + let totalTWIAB = 0; + let totalPlaytimeForAvgBw = 0; + Object.values(list).forEach((item) => { + let varPlayTime = item.playTime; + if (item === list[curLevel]) { + varPlayTime += playTime || 0; + } + if (varPlayTime) { + totalTWIB += item.bandwidth * varPlayTime; + totalBitRk += item.brRnk * varPlayTime; + totalPlaytime += varPlayTime; + // Avg bandwidth is optional, use its playtime only if it's reported + if (item.avgBandwidth) { + totalTWIAB += item.avgBandwidth * varPlayTime; + totalPlaytimeForAvgBw += varPlayTime; + } + } + }); + if (totalPlaytime) { + result.twBRnk = totalBitRk / totalPlaytime; + result.twIBR = totalTWIB / totalPlaytime; + } + if (totalTWIAB && totalPlaytimeForAvgBw) { + result.twIABR = totalTWIAB / totalPlaytimeForAvgBw; + } + } + return result; + } + _computeMediaStats(record) { + const bufferAppendInfo = record.bufferAppendInfo; + let latencies = []; + const sizes = []; + if (bufferAppendInfo && bufferAppendInfo.forEach) { + bufferAppendInfo.forEach((item) => { + latencies.push(item.latency); + sizes.push(item.size); + }); + } + const bufLatencyInfo = this._computeStats(latencies); + const bufSizeInfo = this._computeStats(sizes); + // calculate seek stats + const seekInfo = record.seekInfo; + latencies = []; + if (seekInfo && seekInfo.forEach) { + record.seekInfo.forEach((item) => latencies.push(item.latency)); + } + const seekLatencyInfo = this._computeStats(latencies); + // calculate play stats + const playInfo = record.playInfo; + latencies = []; + if (playInfo && playInfo.forEach) { + record.playInfo.forEach((item) => latencies.push(item.latency)); + } + const playLatencyInfo = this._computeStats(latencies); + return { bufLatencyInfo, bufSizeInfo, seekLatencyInfo, playLatencyInfo }; + } + _computeStats(inputArr) { + let max; + let median; + if (inputArr) { + const arr = inputArr.filter((value) => value > 0); // ensure there are only positive values + if (arr.length > 0) { + max = arr.reduce((a, b) => { + return Math.max(a, b); + }); + const len = arr.length; + const sortedArr = arr.sort((a, b) => a - b); + const mid = Math.ceil(len / 2); + median = len % 2 === 0 ? (sortedArr[mid] + sortedArr[mid - 1]) / 2 : sortedArr[mid - 1]; + } + } + return { max, median }; + } + _getVariantInfo(url, record) { + return url && record.manifestData && record.manifestData.variantList && record.manifestData.variantList[url] ? record.manifestData.variantList[url] : {}; + } + _setTargetDuration(url, targetduration, record) { + if (url && record.manifestData && record.manifestData.variantList && record.manifestData.variantList[url]) { + record.manifestData.variantList[url].targetduration = targetduration; + } + } + _isBadSw(curSwDir, lastSwitchDir, curLevelIsIframe, lastLevelIsIframe, curSwitchTime, lastSwitchTime, isSeeking) { + const minSwitchWindow = 10000; // if we reverse the switch direction within this window, it's considered as a bad switch + let isBadSw = false; + if (curSwitchTime - lastSwitchTime < minSwitchWindow && lastSwitchDir !== curSwDir && lastLevelIsIframe === curLevelIsIframe && !isSeeking) { + isBadSw = true; + } + return isBadSw; + } + _aggregateTimes(itemId) { + this.update(itemId, ({ sessionControlRecord, playLikelyToKeepUpRecord, playStalledRecord, mediaEngineStalledRecord, switchCompleteRecord, playRateChangedRecord, variantEndedRecord, playErrorRecord, nwErrorRecord, periodicRecord, playEndedRecord, }) => { + const now = Date.now(); + const eventTime = now - sessionControlRecord.eventStartTime; + const state = sessionControlRecord.state; + switch (state) { + case 'RTC_STATE_INIT': { + playLikelyToKeepUpRecord.StartupTime = (playLikelyToKeepUpRecord.StartupTime || 0) + eventTime; + periodicRecord.InitTime = (periodicRecord.InitTime || 0) + eventTime; + playEndedRecord.InitTime = (playEndedRecord.InitTime || 0) + eventTime; + break; + } + case 'RTC_STATE_CANPLAY': { + playRateChangedRecord.StartupTime = (playRateChangedRecord.StartupTime || 0) + eventTime; + periodicRecord.InitTime = (periodicRecord.InitTime || 0) + eventTime; + playEndedRecord.InitTime = (playEndedRecord.InitTime || 0) + eventTime; + break; + } + case 'RTC_STATE_PAUSE': { + periodicRecord.PauseTime = (periodicRecord.PauseTime || 0) + eventTime; + playEndedRecord.PauseTime = (playEndedRecord.PauseTime || 0) + eventTime; + playRateChangedRecord.LastPause = (playRateChangedRecord.LastPause || 0) + eventTime; + playEndedRecord.LastPause = (playEndedRecord.LastPause || 0) + eventTime; + playErrorRecord.LastPause = (playErrorRecord.LastPause || 0) + eventTime; + nwErrorRecord.LastPause = (nwErrorRecord.LastPause || 0) + eventTime; + break; + } + case 'RTC_STATE_STALL': { + variantEndedRecord.StallTime = (variantEndedRecord.StallTime || 0) + eventTime; + periodicRecord.StallTime = (periodicRecord.StallTime || 0) + eventTime; + playEndedRecord.StallTime = (playEndedRecord.StallTime || 0) + eventTime; + playRateChangedRecord.LastStall = (playRateChangedRecord.LastStall || 0) + eventTime; + playErrorRecord.LastStall = (playErrorRecord.LastStall || 0) + eventTime; + playEndedRecord.LastStall = (playEndedRecord.LastStall || 0) + eventTime; + break; + } + case 'RTC_STATE_MEDIAENGINESTALL': { + variantEndedRecord.MediaEngineStallTime = (variantEndedRecord.MediaEngineStallTime || 0) + eventTime; + periodicRecord.MediaEngineStallTime = (periodicRecord.MediaEngineStallTime || 0) + eventTime; + playEndedRecord.MediaEngineStallTime = (playEndedRecord.MediaEngineStallTime || 0) + eventTime; + playRateChangedRecord.LastMediaEngineStall = (playRateChangedRecord.LastMediaEngineStall || 0) + eventTime; + playErrorRecord.LastMediaEngineStall = (playErrorRecord.LastMediaEngineStall || 0) + eventTime; + playEndedRecord.LastMediaEngineStall = (playEndedRecord.LastMediaEngineStall || 0) + eventTime; + break; + } + case 'RTC_STATE_NWERROR': { + playEndedRecord.NwErrTime = (playEndedRecord.NwErrTime || 0) + eventTime; + periodicRecord.NwErrTime = (periodicRecord.NwErrTime || 0) + eventTime; + break; + } + case 'RTC_STATE_PLAYERROR': { + periodicRecord.PlayErrTime = (periodicRecord.PlayErrTime || 0) + eventTime; + playEndedRecord.PlayErrTime = (playEndedRecord.PlayErrTime || 0) + eventTime; + break; + } + case 'RTC_STATE_PLAY': { + playRateChangedRecord.RateChangePlayTime = (playRateChangedRecord.RateChangePlayTime || 0) + eventTime; + switchCompleteRecord.PlayTime = (switchCompleteRecord.PlayTime || 0) + eventTime; + switchCompleteRecord.PlayTimeLastSW = (switchCompleteRecord.PlayTimeLastSW || 0) + eventTime * (sessionControlRecord.oldRate / 100); + playStalledRecord.LastResume = (playStalledRecord.LastResume || 0) + eventTime; + mediaEngineStalledRecord.LastResume = (mediaEngineStalledRecord.LastResume || 0) + eventTime; + playErrorRecord.LastResume = (playErrorRecord.LastResume || 0) + eventTime; + nwErrorRecord.LastResume = (nwErrorRecord.LastResume || 0) + eventTime; + variantEndedRecord.VarPlayTimeWC = (variantEndedRecord.VarPlayTimeWC || 0) + eventTime; + variantEndedRecord.VarPlayTime = (variantEndedRecord.VarPlayTime || 0) + eventTime * (sessionControlRecord.oldRate / 100); + periodicRecord.PlayTimeWC = (periodicRecord.PlayTimeWC || 0) + eventTime; + periodicRecord.PlayTime = (periodicRecord.PlayTime || 0) + eventTime * (sessionControlRecord.oldRate / 100); + playEndedRecord.PlayTimeWC = (playEndedRecord.PlayTimeWC || 0) + eventTime; + playEndedRecord.PlayTime = (playEndedRecord.PlayTime || 0) + eventTime * (sessionControlRecord.oldRate / 100); + // Update stall playtime + mediaEngineStalledRecord.PlayTime = playEndedRecord.PlayTime; + playStalledRecord.PlayTime = playEndedRecord.PlayTime; + // Update the playtime for the current level to calculate time weighted values + const curLevelUrl = sessionControlRecord.curLevelUrl; + let variantInfo = sessionControlRecord.intervalVariantList[curLevelUrl]; + variantInfo.playTime = (variantInfo.playTime || 0) + eventTime; + variantInfo = sessionControlRecord.sessionVariantList[curLevelUrl]; + variantInfo.playTime = (variantInfo.playTime || 0) + eventTime; + break; + } + } + }); + } + } + + const loggerName$4 = { name: 'rtc-service' }; + const defaultIntervalValue = 300000; + /* + * @brief RTC service is responsible for subscribing to queries and updating the RTC store. + */ + class RTCService { + constructor(hls, config, accessLog, logger) { + this.hls = hls; + this.config = config; + this.accessLog = accessLog; + this.logger = logger; + this.destroy$ = new Subject(); + this.isSeeking = false; + this.seekStart = null; + this.periodicInterval = config.rtcIntervalTimeout ? config.rtcIntervalTimeout : defaultIntervalValue; + this.intervalFunc = null; + this.rtcStore = new RTCStore(this.logger); + this.rtcQuery = new RTCQuery(this.rtcStore, this.logger); + this.rtcComponent = new RTCComponent(this.rtcQuery, this.logger); + accessLog.setRTCQuery(this.rtcQuery); + this.subscribeAndUpdateStore(); + this.registerForEvents(); + } + destroy() { + this.destroy$.next(); + this.clearPeriodic(); + this.rtcStore.reset(); + } + detachMedia() { + this.clearPeriodic(); + let t = 0; + try { + // if detach was as a result of an error, this will throw. + t = this.hls.realCurrentTime; + this.logger.qe({ critical: true, name: 'playEnded', data: { itemId: this.rtcEventItemId(true) } }); + this.rtcStore.updateVariantEnd(this.rtcEventItemId(true), { currentTime: t }); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.VariantEnded); + this.rtcStore.updatePeriodic(this.rtcEventItemId(true), true); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.Periodic); + this.rtcStore.updateEnded(this.rtcEventItemId(true)); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.PlayEnded); + } + catch (err) { + this.logger.warn(loggerName$4, err); + } + } + handleError(error) { + var _a, _b; + let newError; + if (error instanceof HlsError) { + newError = error; + } + else { + newError = new ExceptionError(true, error.message, ErrorResponses.InternalError); + } + if (newError instanceof PlaylistNetworkError && !newError.fatal) { + this.rtcStore.updateLevelLoadError(this.rtcEventItemId(), { url: newError.url, mediaDur: this.hls.bufferedDuration, isSeeking: this.isSeeking }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.SwitchComplete); + } + else if (newError.type === ErrorTypes.NETWORK_ERROR) { + this.rtcStore.updateNwError(this.rtcEventItemId(), { fatal: newError.fatal, details: newError.details, code: (_a = newError.response) === null || _a === void 0 ? void 0 : _a.code }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.NwError); + } + else { + this.rtcStore.updateMediaError(this.rtcEventItemId(), { fatal: newError.fatal, details: newError.details, code: (_b = newError.response) === null || _b === void 0 ? void 0 : _b.code }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.PlayError); + } + } + handleMediaElementError(err) { + this.rtcStore.updateMediaElementError(this.rtcEventItemId(), err); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.PlayError); + } + handleFragLoaded(frag, stats) { + var _a; + this.logger.trace(loggerName$4, 'MediaFragment=%o, Stats=%o', fragPrint(frag), stats); + if (!this.checkMediaOptionType(frag.mediaOptionType)) { + return; + } + if (frag.itemId !== this.rtcEventItemId()) { + this.logger.warn(loggerName$4, `Frag id does not match current item id. Frag Id=${frag.itemId}, playing id=${this.rtcEventItemId(true)}, loading id=${(_a = this.hls.loadingItem) === null || _a === void 0 ? void 0 : _a.itemId}`); + } + const adt = stats.tload - stats.trequest; + const processTime = stats.tload - stats.tfirst; + const serverInfo = this.serverInfoInstance ? this.serverInfoInstance : {}; + this.rtcStore.updateFragLoaded(frag.itemId, { + fragType: frag.mediaOptionType, + bytes: stats.loaded, + duration: frag.duration, + adt: adt, + processTime: processTime, + contentType: stats.contentType, + cdnServer: stats.cdnServer, + serverInfo: serverInfo, + }); + this.accessLog.updateFragLoaded(frag.itemId, this.isSeeking, { + fragType: frag.mediaOptionType, + bytes: stats.loaded, + duration: frag.duration, + adt: adt, + processTime: processTime, + startPTS: frag.start, + endPTS: frag.start + frag.duration, + }); + } + handleFragBuffered(metric) { + this.logger.trace(loggerName$4, 'Frag Buffered, metrics=%o', metric); + if (!this.checkMediaOptionType(metric.fragmentType)) { + return; + } + const parseTime = metric.endDataAppend - metric.startDataAppend; + this.rtcStore.updateFragBuffered(this.rtcEventItemId(), { fragType: metric.fragmentType, bytes: metric.dataBytesAppend, parseTime: parseTime }); + } + handleLevelLoaded(mediaOptionDetails, stats) { + if (!mediaOptionDetails) { + // This happens on Safari and FireFox, browsers that block autoplay. + // rdar://82312973 + this.logger.warn(`handleLevelLoaded called with mediaOptionDetails as ${mediaOptionDetails}`); + return; + } + if (mediaOptionDetails.itemId !== this.rtcEventItemId()) { + this.logger.warn(loggerName$4, `media option id does not match current item id. media Id=${mediaOptionDetails.itemId}, current id=${this.rtcEventItemId}`); + } + if (mediaOptionDetails.mediaOptionType === MediaOptionType.Variant) { + const adt = stats.tload - stats.trequest; + this.rtcStore.updateLevelLoaded(this.rtcEventItemId(), { + url: mediaOptionDetails.url, + targetduration: mediaOptionDetails.targetduration, + adt: adt, + contentType: stats.contentType, + playType: mediaOptionDetails.type, + }); + } + } + handleLevelSwitched(data) { + const levelData = { url: data.url, isSeeking: this.isSeeking, mediaDur: this.hls.bufferedDuration, currentTime: this.hls.realCurrentTime }; + this.logger.trace(loggerName$4, `RTC level Switched, oldVariant: ${data.oldVariant}, newVariant: ${data.newVariant}`); + if (data.oldVariant) { + // Playing variant ended. + this.rtcStore.updateVariantEnd(this.rtcEventItemId(), { currentTime: this.hls.realCurrentTime }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.VariantEnded); + } + // Playback switched to new variant. + this.rtcStore.updateLevelSwitched(this.rtcEventItemId(), levelData); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.SwitchComplete); + } + handleLevelSwitching(levelUrl) { + this.levelSwitchingUrl = levelUrl; + } + handleLevelsChanged(variantList) { + this.logger.trace(loggerName$4, 'Levels Changed Levels=%o', variantList); + this.rtcStore.updateLevelsChanged(this.rtcEventItemId(), { levels: variantList }); + } + handleManifestParsed(manifestParsedData) { + var _a; + this.logger.trace(loggerName$4, 'RTC Manifest Parsed, levels=%o, stats=%o', manifestParsedData.levels, manifestParsedData.stats); + const adt = manifestParsedData.stats.tload - manifestParsedData.stats.trequest; + this.rtcStore.updateManifestParsed(this.rtcEventItemId(), { + levels: manifestParsedData.levels, + adt: adt, + contentType: manifestParsedData.stats.contentType, + isAudioOnly: this.hls.inGaplessMode, + isGapless: this.hls.inGaplessMode, + isFirstItem: this.hls.isFirstItem, + itemID: (((_a = this.hls.reportingAgent) === null || _a === void 0 ? void 0 : _a.SessionID) || guid()) + '-' + this.rtcEventItemId(), + }); + this.logger.qe({ + critical: true, + name: 'gapless', + data: { + isGapless: this.hls.inGaplessMode, + isAudioOnly: this.hls.inGaplessMode, + isFirstItem: this.hls.isFirstItem, + sessionId: this.hls.sessionID, + itemId: this.rtcEventItemId(), + }, + }); + } + handleSeek(event) { + this.logger.trace(loggerName$4, `RTC seek event: ${event}`); + if (event === 'SEEKING') { + this.isSeeking = true; + this.seekStart = Date.now(); + } + else if (event === 'SEEKED') { + // seeked update store + this.isSeeking = false; + let latency = 0; + if (this.seekStart) { + latency = Date.now() - this.seekStart; + } + this.seekStart = null; + this.logger.trace(loggerName$4, `RTC seeked, latency=${latency}`); + this.rtcStore.updateSeeked(this.rtcEventItemId(true), { latency: latency }); + } + } + handleDesiredRateChanged(oldRate, newRate) { + if (newRate === 0 || (Math.abs(oldRate) > 1 && Math.abs(newRate) > 1)) { + /* Desired rate to actual rate transition is immediate for the following + - any rate to 0 + - between any trick play rates (2x <-> 4x etc.) + So, update the store right away. + */ + this.logger.trace(loggerName$4, `RTC rate changed oldRate=${oldRate} newRate=${newRate}`); + this.logger.qe({ critical: true, name: 'rateChanged', data: { oldRate, newRate } }); + this.rtcStore.updateRateChanged(this.rtcEventItemId(true), { + rate: newRate, + latency: 0, + mediaDur: this.hls.bufferedDuration, + currentTime: this.hls.realCurrentTime, + url: this.levelSwitchingUrl, + }); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.PlayRateChanged); + } + else if (oldRate !== 1 && newRate === 1) { + // moving from pause/trickplay to playing rate + this.playStart = Date.now(); + } + /* Save the desired rate and wait for playback to switch to that rate (store update happens later for those cases) */ + this.oldRate = oldRate; + this.newRate = newRate; + } + handleVariantBufferAppended(timestampOffset, totalBytes) { + this.logger.trace(loggerName$4, 'RTC Variant Buffer Appended'); + let latency = 0; + if (timestampOffset) { + latency = Date.now() - timestampOffset; + } + this.rtcStore.updateBufferAppended(this.rtcEventItemId(), { latency: latency, size: totalBytes }); + } + handleStalled(stallInfo, bufferLen) { + this.logger.trace(loggerName$4, 'Stall Info data=%o', stallInfo); + const data = { type: stallInfo.type, stallDurationMs: stallInfo.stallDurationMs, bufferLen: bufferLen, mediaDur: this.hls.bufferedDuration }; + const state = this.rtcQuery.getEntity(this.rtcEventItemId(true)).sessionControlRecord.state; + if (stallInfo.type === StallType.LowBuffer || (stallInfo.type === StallType.Seek && stallInfo.isLowBufferStall)) { + // Low Buffer Stall + if (state !== 'RTC_STATE_PLAY') { + // don't report stall events if we're not playing + this.logger.info(loggerName$4, `skipping low buffer stall event because we're not playing, state: ${state}`); + } + else { + this.rtcStore.updateBufferStalled(this.rtcEventItemId(true), data); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.PlayStalled); + } + } + else { + // High Buffer Stall + if (state !== 'RTC_STATE_PLAY') { + // don't report stall events if we're not playing + this.logger.info(loggerName$4, `skipping high buffer stall event because we're not playing, state: ${state}`); + } + else { + this.rtcStore.updateMediaEngineStalled(this.rtcEventItemId(true), data); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.MediaEngineStalled); + } + } + } + handlePlaybackInfo(droppedVideoFrames, decodedFrameCount) { + this.logger.trace(loggerName$4, `RTC Playback Info, droppedVideoFrames=${droppedVideoFrames}, decodedFrameCount=${decodedFrameCount}`); + this.rtcStore.updatePlaybackInfo(this.rtcEventItemId(true), { droppedVideoFrames: droppedVideoFrames, decodedFrameCount: decodedFrameCount }); + this.accessLog.updatePlaybackInfo(this.rtcEventItemId(true), { droppedVideoFrames: droppedVideoFrames, decodedFrameCount: decodedFrameCount }); + } + checkMediaOptionType(mediaOptionType) { + if (mediaOptionType === MediaOptionType.Variant || mediaOptionType === MediaOptionType.AltAudio) { + return true; + } + else { + this.logger.error(loggerName$4, 'Should not have media option type = "%s" in RTC', MediaOptionNames[mediaOptionType]); + return false; + } + } + // Return currently playing id or loading item id if preloading. + // Force return playing id if forcePlayingId is set to true. + rtcEventItemId(forcePlayingId = false) { + if (this.hls.isPreloading) { + if (forcePlayingId) { + return this.hls.playingItem.itemId; + } + return this.hls.loadingItem.itemId; + } + return this.hls.currentItem.itemId; + } + subscribeAndUpdateStore() { + this.hls.publicQueries$ + .pipe(switchMap(([, mediaElementQuery]) => { + return this.mediaElementQueryListener(mediaElementQuery); + }), takeUntil(this.destroy$)) + .subscribe(); + this.hls.itemQueue.activeItemById$ + .pipe(tap((item) => { + var _a, _b; + if (item) { + // if this is an internal build, always send RTC + // if D&U flag is true, use the configuration + // if there is no userInfo use the configuration + let enableRtc = false; + if (this.hls.userInfo) { + if (this.hls.userInfo.internalBuild) { + enableRtc = true; + } + else if (this.hls.userInfo.diagnosticsAndUsage) { + enableRtc = this.config.enableRtcReporting; + } + } + else { + enableRtc = this.config.enableRtcReporting; + } + if (enableRtc) { + // set reporting agent. + const reportingAgent = this.hls.reportingAgent; + if (reportingAgent) { + this.rtcComponent.setReportingAgent(reportingAgent); + this.logger.qe({ critical: true, name: 'rtcStart', data: { baseSessionId: reportingAgent.SessionID, itemId: (_a = this.hls.itemQueue.activeItem) === null || _a === void 0 ? void 0 : _a.itemId } }); + } + else { + this.logger.warn(loggerName$4, '[RTCA] - Reporting is enabled but reportingAgent is null'); + } + } + else { + // RTC is disabled. + this.rtcComponent.setReportingAgent(null); + this.logger.info(loggerName$4, '[RTCA] - Reporting is disabled'); + } + this.serverInfoInstance = null; + // create new entity with item.itemId + const id = item.itemId; + this.rtcStore.createEntity(id); + // if this is the first item or we are not in gapless mode, start the periodic timer + if (this.hls.isFirstItem || !this.hls.inGaplessMode) { + this.setPeriodic(id); + } + this.logger.trace(`RTC Manifest loading: ${(_b = this.hls.itemQueue.activeItem) === null || _b === void 0 ? void 0 : _b.url}`); + } + }), takeUntil(this.destroy$)) + .subscribe(); + } + itemTransitioned(oldItem, newItem) { + // item transitioned + this.logger.trace(loggerName$4, `RTC Item transitioned oldItem=${oldItem} newItem=${newItem}`); + this.rtcStore.updateVariantEnd(oldItem, { currentTime: this.hls.realCurrentTime }); + this.sendAndFinalize(oldItem, RTCEventGroup.VariantEnded); + this.rtcStore.updatePeriodic(oldItem, true); + this.sendAndFinalize(oldItem, RTCEventGroup.Periodic); + this.rtcStore.updateEnded(oldItem); + this.sendAndFinalize(oldItem, RTCEventGroup.PlayEnded); + // attach/subscribe to timer for periodic events. Note set periodic calls clearPeriodic + this.setPeriodic(newItem); + } + mediaElementQueryListener(mediaElementQuery) { + const playingSource$ = mediaElementQuery.gotPlaying$.pipe(tap((playing) => { + if (playing) { + const oldRate = this.oldRate; + const newRate = this.newRate || 1; // set 1 for default cases, e.g. autoplay + if (Math.abs(oldRate) > 1 && Math.abs(newRate) > 1) { + return; // Ignore gotPlaying notifications for transition between trick play rates + } + this.logger.info(loggerName$4, `RTC rate changed oldRate=${oldRate} newRate=${newRate}`); + this.logger.qe({ critical: true, name: 'rateChanged', data: { oldRate, newRate } }); + this.rtcStore.updateCanPlay(this.rtcEventItemId(true), { mediaDur: this.hls.bufferedDuration }); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.PlayLikelyToKeepUp); + this.rtcStore.updateRateChanged(this.rtcEventItemId(true), { + rate: newRate, + latency: isFiniteNumber(this.playStart) ? Date.now() - this.playStart : 0, + mediaDur: this.hls.bufferedDuration, + currentTime: this.hls.realCurrentTime, + url: this.levelSwitchingUrl, + }); + this.sendAndFinalize(this.rtcEventItemId(true), RTCEventGroup.PlayRateChanged); + } + })); + return playingSource$; + } + // Event based + registerForEvents() { + const target = fromEventTarget(this.hls, this); + merge(target.event(HlsEvent.KEY_REQUEST_STARTED, this.keyRequestStarted, this), target.event(HlsEvent.KEY_LOADED, this.keyLoaded, this)).pipe(takeUntil(this.destroy$)).subscribe(); + } + keyRequestStarted(data) { + this.logger.trace(loggerName$4, 'RTC key request started %o', data); + data.timestamp = Date.now(); + this.rtcStore.updateLicenseChallengeRequested(this.rtcEventItemId(), data); + } + keyLoaded(data) { + this.logger.trace(loggerName$4, 'RTC key loaded, data: %o', data); + data.timestamp = Date.now(); + data.currentTime = this.hls.realCurrentTime; + this.rtcStore.updateSegmentKeyLoaded(this.rtcEventItemId(), data); + } + // End of Event based + // Key session handler methods + licenseChallengeReceived(data) { + this.logger.trace(loggerName$4, 'RTC licenseChallenge received data: %o', data); + this.rtcStore.updateLicenseChallengeReceived(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri }); + } + licenseChallengeSubmitted(data) { + this.logger.trace(loggerName$4, 'RTC licenseChallenge submitted data: %o', data); + this.rtcStore.updateLicenseChallengeSubmitted(this.rtcEventItemId(), { timestamp: Date.now(), keyFormat: data.keyFormat, keyuri: data.keyuri }); + } + licenseChallengeCreated(data) { + this.logger.trace(loggerName$4, 'RTC licenseChallenge created data: %o', data); + this.rtcStore.updateLicenseChallengeCreated(this.rtcEventItemId(), { timestamp: Date.now(), cdmVersion: data.cdmVersion, keyuri: data.keyuri }); + this.rtcStore.updateLicenseResponseRequested(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri }); // both licenseChallengeCreated and licenseResponseRequested happen simultaneouly + } + licenseResponseSubmitted(data) { + this.logger.trace(loggerName$4, 'RTC licenseResponse submitted data: %o', data); + this.rtcStore.updateLicenseResponseReceived(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri }); // both licenseResponseReceived and licenseResponseSubmitted happen simultaneouly + this.rtcStore.updateLicenseResponseSubmitted(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri }); + } + licenseResponseProcessed(data) { + this.logger.trace(loggerName$4, 'RTC licenseResponse processed data: %o', data); + this.rtcStore.updateLicenseResponseProcessed(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri, currentTime: this.hls.realCurrentTime }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.KeySessionComplete); + } + licenseChallengeError(data) { + this.logger.trace(loggerName$4, 'RTC licenseChallenge error data: %o', data); + this.rtcStore.updateLicenseChallengeError(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.KeySessionComplete); + } + licenseResponseError(data) { + this.logger.trace(loggerName$4, 'RTC licenseResponse error data: %o', data); + this.rtcStore.updateLicenseResponseError(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.KeySessionComplete); + } + keyAborted(data) { + var _a; + this.logger.trace(loggerName$4, 'RTC key aborted data: %o', data); + if (((_a = this.rtcQuery.getEntity(this.rtcEventItemId())) === null || _a === void 0 ? void 0 : _a.sessionControlRecord.activeKeySessions[data.keyuri]) != null) { + this.rtcStore.updateKeyAborted(this.rtcEventItemId(), { timestamp: Date.now(), keyuri: data.keyuri }); + this.sendAndFinalize(this.rtcEventItemId(), RTCEventGroup.KeySessionComplete); + } + else { + this.logger.warn(`keyAbort called without active key session ${redactUrl(data.keyuri)}`); + } + } + // End of key session handler methods + setPeriodic(id) { + this.clearPeriodic(); + this.intervalFunc = setInterval(this.handlePeriodic.bind(this, id), this.periodicInterval); + } + handlePeriodic(id) { + this.logger.trace(loggerName$4, `sendPeriodic id=${id}`); + this.rtcStore.updatePeriodic(id, false); + this.sendAndFinalize(id, RTCEventGroup.Periodic); + } + clearPeriodic() { + if (this.intervalFunc) { + clearInterval(this.intervalFunc); + } + this.intervalFunc = null; + } + sendAndFinalize(id, rtcEvent) { + this.accessLog.addPlayTime(id); + switch (rtcEvent) { + case RTCEventGroup.PlayEnded: + this.rtcComponent.sendPlayEnded(id); + break; + case RTCEventGroup.Periodic: + this.rtcComponent.sendPeriodic(id); + break; + case RTCEventGroup.PlayStalled: + this.accessLog.updateStallCount(id); + this.rtcComponent.sendPlayStalled(id); + break; + case RTCEventGroup.KeySessionComplete: + this.rtcComponent.sendKeySessionComplete(id); + break; + case RTCEventGroup.PlayLikelyToKeepUp: + this.accessLog.updateCanPlay(id); + this.rtcComponent.sendPlayLikelyToKeepUp(id); + break; + case RTCEventGroup.PlayRateChanged: + this.rtcComponent.sendPlayRateChange(id); + break; + case RTCEventGroup.PlayError: + this.accessLog.addToErrorLog(id, 'mediaError'); + this.rtcComponent.sendPlayError(id); + break; + case RTCEventGroup.MediaEngineStalled: + this.accessLog.updateMediaEngineStallCount(id); + this.rtcComponent.sendMediaEngineStalled(id); + break; + case RTCEventGroup.SwitchComplete: + this.accessLog.addToAccessLog(id); + this.rtcComponent.sendSwitchComplete(id); + break; + case RTCEventGroup.VariantEnded: + this.rtcComponent.sendVariantEnded(id); + break; + case RTCEventGroup.NwError: + this.accessLog.addToErrorLog(id, 'networkError'); + this.rtcComponent.sendNwError(id); + break; + default: + this.logger.error(loggerName$4, `Unknown rtc event eventGroupId:${id}`); + return; + } + this.rtcStore.finalize(id, rtcEvent); + } + } + + const genericTimeWeightedAggregation = (power) => { + return (entries, windowStartTimestamp) => { + let totalValue = 0; + let totalWeight = 0; + for (const { timestamp, value } of entries) { + // Math.max(0, ...) to guard against privacy.resistFingerprinting or privacy.reduceTimerPrecision, + // which may leave expired entries in the array. + const weight = Math.pow(Math.max(0, timestamp - windowStartTimestamp) / 1000, power); + totalValue += weight * value; + totalWeight += weight; + } + return totalValue / totalWeight; + }; + }; + const AggregationImplementations = { + 'uniform-time-weighted': genericTimeWeightedAggregation(0), + 'linear-time-weighted': genericTimeWeightedAggregation(1), + 'quadratic-time-weighted': genericTimeWeightedAggregation(2), + }; + + /** + * Returns a new array of intervals where overlapping intervals are joined together + * into non-overlapping intervals. + * @param intervals An array of intervals + * @param join A function that takes in two overlapping intervals and joins them + * + * @note this function only joins strict overlaps, interval pairs such as ((1, 2), (2, 3)) + * are not joined. + */ + function accumulateBW(intervals) { + const sorted_intervals = [...intervals].sort((a, b) => { + if (a.start !== b.start) { + return a.start - b.start; + } + else { + return a.end - b.end; + } + }); + const result = []; + const insertEntry = function (arr, entry) { + if (!arr.length) { + arr.push(entry); + return; + } + for (let i = 0; i < arr.length; i++) { + if (arr[i].start > entry.start || (arr[i].start === entry.start && arr[i].end > entry.end)) { + arr.splice(i, 0, entry); + break; + } + } + }; + while (sorted_intervals.length) { + const interval = sorted_intervals[0]; + sorted_intervals.shift(); + let lastInterval; + if (result.length) { + lastInterval = result[result.length - 1]; + } + if (result.length === 0 || lastInterval.end <= interval.start) { + // No overlap + result.push(interval); + } + else if (interval.start === lastInterval.start) { + // Overlap with same start + if (interval.end === lastInterval.end) { + // same end also .. so just accumulate + lastInterval.bitsPerSec += interval.bitsPerSec; + } + else if (!(interval.end < lastInterval.end)) { + // End of interval in consideration is larger than last interval. + // Accumulate for the overlap. create an new entry for + // extended part and insert it back in sorted entries. + lastInterval.bitsPerSec += interval.bitsPerSec; + interval.start = lastInterval.end; + insertEntry(sorted_intervals, interval); + } + } + else { + // there is initial part that does not overlap + const prevend = lastInterval.end; + const prevBitsPerSec = lastInterval.bitsPerSec; + lastInterval.end = interval.start; + // make a new entry for the overlap + const entry = { + start: interval.start, + end: Math.min(prevend, interval.end), + bitsPerSec: interval.bitsPerSec + prevBitsPerSec, + }; + result.push(entry); + if (prevend !== interval.end) { + // create new entry for the extended part and insert it back + // in sorted entries. + let start = 0, end = 0, bitsPerSec = 0; + if (prevend < interval.end) { + start = prevend; + end = interval.end; + bitsPerSec = interval.bitsPerSec; + } + else { + start = interval.end; + end = prevend; + bitsPerSec = prevBitsPerSec; + } + const newEntry = { start, end, bitsPerSec }; + insertEntry(sorted_intervals, newEntry); + } + } + } + return result; + } + + class HistoryBasedBandwidthEstimator { + constructor(windowSize, aggregationMethod = 'quadratic-time-weighted', initValue = { + avgLatencyMs: NaN, + avgBandwidth: NaN, + }) { + this.windowSize = windowSize; + this.aggregationMethod = aggregationMethod; + this.latencyEntries = []; + this.bandwidthEntries = []; + this.minEntries = 1; + this.cleanUpExpiredEntries = this.cleanUpExpiredEntries.bind(this); + this.bwSubject = new BehaviorSubject(initValue); + } + get estimate$() { + return this.bwSubject.asObservable(); + } + record(details) { + // logger.debug(`Recording Bandwidth entry: ${JSON.stringify(details)}`); + const { trequest, tfirst, tload, bitsDownloaded } = details; + if (trequest === tload) { + return; + } + this.recordLatency(trequest, tfirst); + // tfirst tends to be delayed in the beginning of playback, which + // inflates bandwidth estimation (especially for small downloads) + // Thus we use trequest to get a more stable measurement of + // bandwidth. Note that this will decrease the bandwidth + // estimation by a little (~3% on a 40Mbps network at the office). + this.recordBandwidth(trequest, tload, (bitsDownloaded * 1000) / (tload - trequest)); + if (this.bwSubject.closed) { + return; + } + const estimate = this.getEstimate(); + this.bwSubject.next(estimate); + } + getEstimate() { + if (this.latencyEntries.length < this.minEntries) { + return { + avgLatencyMs: NaN, + avgBandwidth: NaN, + }; + } + const windowStartTimestamp = performance.now() - this.windowSize; + const aggregationFn = AggregationImplementations[this.aggregationMethod]; + const latencyEntries = this.latencyEntries.map(({ start, end }) => ({ + timestamp: end, + value: end - start, + duration: 1, + })); + this.bandwidthEntries = accumulateBW(this.bandwidthEntries); + const bandwidthEntries = this.bandwidthEntries.map(({ start, end, bitsPerSec }) => ({ + timestamp: end, + duration: 1, + value: bitsPerSec, // bits + })); + return { + avgLatencyMs: aggregationFn(latencyEntries, windowStartTimestamp), + avgBandwidth: aggregationFn(bandwidthEntries, windowStartTimestamp), + }; + } + getLatest() { + if (this.latencyEntries.length === 0) { + return { + avgLatencyMs: NaN, + avgBandwidth: NaN, + }; + } + const lastLatency = this.latencyEntries[this.latencyEntries.length - 1]; + const lastBw = this.bandwidthEntries[this.bandwidthEntries.length - 1]; + return { + avgLatencyMs: lastLatency.end - lastLatency.start, + avgBandwidth: lastBw.bitsPerSec, + }; + } + recordLatency(start, end) { + this.latencyEntries.push({ start, end }); + this.updateCleanupTimeout(end); + } + recordBandwidth(start, end, bitsPerSec) { + this.bandwidthEntries.push({ start, end, bitsPerSec }); + this.updateCleanupTimeout(end); + } + setCleanupTimeout(cleanupTimestamp) { + this.cleanupTimeout = setTimeout(this.cleanUpExpiredEntries, Math.max(cleanupTimestamp - performance.now(), 0)); + this.cleanupTimestamp = cleanupTimestamp; + } + clearCleanupTimeout() { + if (typeof this.cleanupTimeout !== 'undefined') { + clearTimeout(this.cleanupTimeout); + this.cleanupTimeout = undefined; + } + this.cleanupTimestamp = undefined; + } + updateCleanupTimeout(timestamp) { + const cleanupTimestamp = timestamp + this.windowSize; + if (!this.cleanupTimestamp || cleanupTimestamp < this.cleanupTimestamp) { + this.clearCleanupTimeout(); + this.setCleanupTimeout(cleanupTimestamp); + } + } + cleanUpExpiredEntries() { + this.clearCleanupTimeout(); + const windowStartTimestamp = performance.now() - this.windowSize; + this.latencyEntries = this.latencyEntries.filter((entry) => entry.end >= windowStartTimestamp); + this.bandwidthEntries = this.bandwidthEntries.filter((entry) => entry.end >= windowStartTimestamp); + // during cleanup + if (!this.bwSubject.closed) { + this.bwSubject.next(this.getEstimate()); + } + if (this.latencyEntries.length > 0 || this.bandwidthEntries.length > 0) { + const timestampOfEarliestEntry = Math.min(...this.latencyEntries.map((entry) => entry.end), ...this.bandwidthEntries.map((entry) => entry.end)); + this.updateCleanupTimeout(timestampOfEarliestEntry); + } + } + destroy() { + this.clearCleanupTimeout(); + } + } + + /** + * Helper functions that deal with storing data on device storage. + */ + const PersistStats = { + setCombinedEstimate: function (hlsStorage, estimate, serviceName) { + const logger = getLogger(); + if (typeof hlsStorage.storage.set === 'undefined') { + logger.warn('storage.set is not supported! Not persisting bandwidth estimates'); + return; + } + // splitting into two different records + const bwStorageKey = hlsStorage.bandwidthHistoryStorageKey; + const bwEstimate = { avgLatencyMs: estimate.avgLatencyMs, avgBandwidth: estimate.avgBandwidth }; + const bwRecord = Object.assign({}, bwEstimate, { expires: Date.now() + hlsStorage.bandwidthHistoryTTL }); + try { + hlsStorage.storage.set(bwStorageKey, JSON.stringify(bwRecord)); + } + catch (err) { + logger.warn(`Error stringifying! Not persisting bandwidth estimates: ${err.message}`); + } + const serviceStats = { + maxDuration: estimate.maxDurationSec, + avgFragParseTimeMs: estimate.avgParseTimeMs, + avgFragBufferCreationDelayMs: estimate.avgBufferCreateMs, + avgPlaylistLoadTimeMs: estimate.avgPlaylistLoadTimeMs, + avgPlaylistParseTimeMs: estimate.avgPlaylistParseTimeMs, + avgInitFragAppendMs: estimate.avgInitFragAppendMs, + avgDataFragAppendMs: estimate.avgDataFragAppendMs, + }; + let storageKey = hlsStorage.storageKeyPrefix; + if (serviceName) { + storageKey += serviceName; + } + try { + hlsStorage.storage.set(storageKey, JSON.stringify(serviceStats)); + } + catch (err) { + logger.warn(`Error stringifying! Not persisting bandwidth estimates: ${err.message}`); + } + }, + getCombinedEstimate: function (hlsStorage, serviceName) { + const logger = getLogger(); + let combinedEstimate = {}; + if (typeof hlsStorage.storage.get === 'undefined') { + logger.warn('storage.get is not supported! unable to retreive bandwidth estimates'); + return this.convertStorageJsonToCombinedEstimate(combinedEstimate); + } + try { + let bwParsed = JSON.parse(hlsStorage.storage.get(hlsStorage.bandwidthHistoryStorageKey)); + if ((bwParsed === null || bwParsed === void 0 ? void 0 : bwParsed.expires) && bwParsed.expires < Date.now()) { + bwParsed = null; + } + else { + bwParsed = { avgLatencyMs: bwParsed === null || bwParsed === void 0 ? void 0 : bwParsed.avgLatencyMs, avgBandwidth: bwParsed === null || bwParsed === void 0 ? void 0 : bwParsed.avgBandwidth }; + } + combinedEstimate = Object.assign(Object.assign({}, combinedEstimate), bwParsed); + } + catch (err) { + logger.warn(`Unable to get persisted bandwidth history: ${err.message}`); + } + let storageKey = hlsStorage.storageKeyPrefix; + if (serviceName) { + storageKey += serviceName; + } + try { + const restEstimateParsed = JSON.parse(hlsStorage.storage.get(storageKey)); + combinedEstimate = Object.assign(Object.assign({}, combinedEstimate), restEstimateParsed); + } + catch (err) { + logger.warn(`Unable to get persisted bandwidth history: ${err.message}`); + } + return this.convertStorageJsonToCombinedEstimate(combinedEstimate); + }, + convertStorageJsonToCombinedEstimate: function (storageJson) { + const combinedEstimate = { + avgLatencyMs: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgLatencyMs) || NaN, + avgBandwidth: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgBandwidth) || NaN, + maxDurationSec: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.maxDuration) || NaN, + avgParseTimeMs: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgFragParseTimeMs) || NaN, + avgBufferCreateMs: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgFragBufferCreationDelayMs) || NaN, + avgPlaylistLoadTimeMs: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgPlaylistLoadTimeMs) || NaN, + avgPlaylistParseTimeMs: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgPlaylistParseTimeMs) || NaN, + avgInitFragAppendMs: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgInitFragAppendMs) || NaN, + avgDataFragAppendMs: (storageJson === null || storageJson === void 0 ? void 0 : storageJson.avgDataFragAppendMs) || NaN, + }; + return combinedEstimate; + }, + getBandwidthEstimate: function (hlsStorage, serviceName) { + const estimate = this.getCombinedEstimate(hlsStorage, serviceName); + const bwEstimate = { avgLatencyMs: estimate === null || estimate === void 0 ? void 0 : estimate.avgLatencyMs, avgBandwidth: estimate === null || estimate === void 0 ? void 0 : estimate.avgBandwidth }; + if (!isFiniteNumber(bwEstimate.avgLatencyMs)) { + bwEstimate.avgLatencyMs = NaN; + } + if (!isFiniteNumber(bwEstimate.avgBandwidth)) { + bwEstimate.avgBandwidth = NaN; + } + return bwEstimate; + }, + getPlaylistEstimate: function (hlsStorage, serviceName) { + const estimate = this.getCombinedEstimate(hlsStorage, serviceName); + const playlistEstimate = { avgPlaylistLoadTimeMs: estimate === null || estimate === void 0 ? void 0 : estimate.avgPlaylistLoadTimeMs, avgPlaylistParseTimeMs: estimate === null || estimate === void 0 ? void 0 : estimate.avgPlaylistParseTimeMs }; + if (!isFiniteNumber(playlistEstimate.avgPlaylistLoadTimeMs)) { + playlistEstimate.avgPlaylistLoadTimeMs = NaN; + } + if (!isFiniteNumber(playlistEstimate.avgPlaylistParseTimeMs)) { + playlistEstimate.avgPlaylistParseTimeMs = NaN; + } + return playlistEstimate; + }, + getFragEstimate: function (hlsStorage, serviceName) { + const estimate = this.getCombinedEstimate(hlsStorage, serviceName); + const fragEstimate = { maxDurationSec: estimate === null || estimate === void 0 ? void 0 : estimate.maxDurationSec, avgParseTimeMs: estimate === null || estimate === void 0 ? void 0 : estimate.avgParseTimeMs }; + if (!isFiniteNumber(fragEstimate.maxDurationSec)) { + fragEstimate.maxDurationSec = NaN; + } + if (!isFiniteNumber(fragEstimate.avgParseTimeMs)) { + fragEstimate.avgParseTimeMs = NaN; + } + return fragEstimate; + }, + getBufferEstimate: function (hlsStorage, serviceName) { + const estimate = this.getCombinedEstimate(hlsStorage, serviceName); + const bufferEstimate = { + avgBufferCreateMs: estimate === null || estimate === void 0 ? void 0 : estimate.avgBufferCreateMs, + avgInitFragAppendMs: estimate === null || estimate === void 0 ? void 0 : estimate.avgInitFragAppendMs, + avgDataFragAppendMs: estimate === null || estimate === void 0 ? void 0 : estimate.avgDataFragAppendMs, + }; + if (!isFiniteNumber(bufferEstimate.avgBufferCreateMs)) { + bufferEstimate.avgBufferCreateMs = NaN; + } + if (!isFiniteNumber(bufferEstimate.avgInitFragAppendMs)) { + bufferEstimate.avgInitFragAppendMs = NaN; + } + if (!isFiniteNumber(bufferEstimate.avgDataFragAppendMs)) { + bufferEstimate.avgDataFragAppendMs = NaN; + } + return bufferEstimate; + }, + }; + var PersistStats$1 = PersistStats; + + // Accumulator for doing simple stats + class SimpleAccumulator { + constructor(_minSamples = 0) { + this._minSamples = _minSamples; + this._sum = 0; + this._max = Number.NEGATIVE_INFINITY; + this._numSamples = 0; + } + get avg() { + if (this._numSamples < this._minSamples) { + return NaN; + } + return this._sum / this._numSamples; + } + get max() { + return this.count > 0 ? this._max : NaN; + } + get count() { + return this._numSamples; + } + reset() { + this._sum = 0; + this._numSamples = 0; + this._max = Number.NEGATIVE_INFINITY; + } + add(value) { + this._sum += value; + this._max = Math.max(this._max, value); + ++this._numSamples; + } + } + + /** + * @brief Query interface to the stats store + */ + class StatsQuery extends QueryEntity { + constructor(statsStore, id) { + super(statsStore); + this.id = id; + } + getBandwidthEstimate(hlsStorage, serviceName) { + var _a; + const bwEstimate = Object.assign({}, (_a = this.statsEntity) === null || _a === void 0 ? void 0 : _a.bandwidthEstimate); + if (isFiniteNumber(bwEstimate.avgBandwidth) && isFiniteNumber(bwEstimate.avgLatencyMs)) { + return bwEstimate; + } + // fallback: check in persistent storage + if (hlsStorage) { + const parsedEstimate = PersistStats.getBandwidthEstimate(hlsStorage, serviceName); + if (!isFiniteNumber(bwEstimate.avgBandwidth)) { + bwEstimate.avgBandwidth = parsedEstimate.avgBandwidth; + } + if (!isFiniteNumber(bwEstimate.avgLatencyMs)) { + bwEstimate.avgLatencyMs = parsedEstimate.avgLatencyMs; + } + } + return bwEstimate; + } + getPlaylistEstimate(hlsStorage, serviceName) { + var _a; + const playlistEstimate = Object.assign({}, (_a = this.statsEntity) === null || _a === void 0 ? void 0 : _a.playlistEstimate); + const checkValidity = (playlistEstimate) => { + return isFiniteNumber(playlistEstimate.avgPlaylistLoadTimeMs) && isFiniteNumber(playlistEstimate.avgPlaylistParseTimeMs); + }; + if (checkValidity(playlistEstimate)) { + return playlistEstimate; + } + // fallback: check in persistent storage + if (hlsStorage) { + const parsedEstimate = PersistStats.getPlaylistEstimate(hlsStorage, serviceName); + if (!isFiniteNumber(playlistEstimate.avgPlaylistLoadTimeMs)) { + playlistEstimate.avgPlaylistLoadTimeMs = parsedEstimate.avgPlaylistLoadTimeMs; + } + if (!isFiniteNumber(playlistEstimate.avgPlaylistParseTimeMs)) { + playlistEstimate.avgPlaylistParseTimeMs = parsedEstimate.avgPlaylistParseTimeMs; + } + if (checkValidity(playlistEstimate)) { + return playlistEstimate; + } + //pick config default + if (!isFiniteNumber(playlistEstimate.avgPlaylistLoadTimeMs)) { + playlistEstimate.avgPlaylistLoadTimeMs = hlsStorage.statDefaults.playlistLoadTimeMs; + } + if (!isFiniteNumber(playlistEstimate.avgPlaylistParseTimeMs)) { + playlistEstimate.avgPlaylistParseTimeMs = hlsStorage.statDefaults.playlistParseTimeMs; + } + } + return playlistEstimate; + } + getBufferEstimate(hlsStorage, serviceName) { + var _a; + const bufferEstimate = Object.assign({}, (_a = this.statsEntity) === null || _a === void 0 ? void 0 : _a.bufferEstimate); + const checkValidity = (bufferEstimate) => { + return isFiniteNumber(bufferEstimate.avgBufferCreateMs) && isFiniteNumber(bufferEstimate.avgDataFragAppendMs) && isFiniteNumber(bufferEstimate.avgInitFragAppendMs); + }; + if (checkValidity(bufferEstimate)) { + return bufferEstimate; + } + // fallback: check in persistent storage + if (hlsStorage) { + const parsedEstimate = PersistStats.getBufferEstimate(hlsStorage, serviceName); + if (!isFiniteNumber(bufferEstimate.avgBufferCreateMs)) { + bufferEstimate.avgBufferCreateMs = parsedEstimate.avgBufferCreateMs; + } + if (!isFiniteNumber(bufferEstimate.avgDataFragAppendMs)) { + bufferEstimate.avgDataFragAppendMs = parsedEstimate.avgDataFragAppendMs; + } + if (!isFiniteNumber(bufferEstimate.avgInitFragAppendMs)) { + bufferEstimate.avgInitFragAppendMs = parsedEstimate.avgInitFragAppendMs; + } + if (checkValidity(bufferEstimate)) { + return bufferEstimate; + } + //pick config default + if (!isFiniteNumber(bufferEstimate.avgBufferCreateMs)) { + bufferEstimate.avgBufferCreateMs = hlsStorage.statDefaults.fragBufferCreationDelayMs; + } + if (!isFiniteNumber(bufferEstimate.avgDataFragAppendMs)) { + bufferEstimate.avgDataFragAppendMs = hlsStorage.statDefaults.dataFragAppendMs; + } + if (!isFiniteNumber(bufferEstimate.avgInitFragAppendMs)) { + bufferEstimate.avgInitFragAppendMs = hlsStorage.statDefaults.initFragAppendMs; + } + } + return bufferEstimate; + } + getFragEstimate(hlsStorage, serviceName) { + var _a; + const fragEstimate = Object.assign({}, (_a = this.statsEntity) === null || _a === void 0 ? void 0 : _a.fragEstimate); + const checkValidity = (fragEstimate) => { + return isFiniteNumber(fragEstimate.maxDurationSec) && isFiniteNumber(fragEstimate.avgParseTimeMs); + }; + if (checkValidity(fragEstimate)) { + return fragEstimate; + } + // fallback: check in persistent storage + if (hlsStorage) { + const parsedEstimate = PersistStats.getFragEstimate(hlsStorage, serviceName); + if (!isFiniteNumber(fragEstimate.maxDurationSec)) { + fragEstimate.maxDurationSec = parsedEstimate.maxDurationSec; + } + if (!isFiniteNumber(fragEstimate.avgParseTimeMs)) { + fragEstimate.avgParseTimeMs = parsedEstimate.avgParseTimeMs; + } + if (checkValidity(fragEstimate)) { + return fragEstimate; + } + //pick config default + if (!isFiniteNumber(fragEstimate.maxDurationSec)) { + fragEstimate.maxDurationSec = hlsStorage.defaultTargetDuration; + } + if (!isFiniteNumber(fragEstimate.avgParseTimeMs)) { + fragEstimate.avgParseTimeMs = hlsStorage.statDefaults.fragParseTimeMs; + } + } + return fragEstimate; + } + getCombinedEstimate() { + return Object.assign(Object.assign(Object.assign(Object.assign({}, this.getFragEstimate()), this.getPlaylistEstimate()), this.getBufferEstimate()), this.getBandwidthEstimate()); + } + // getters + get statsEntity() { + return this.getEntity(this.id); + } + get bandwidthSample() { + var _a; + return (_a = this.statsEntity) === null || _a === void 0 ? void 0 : _a.bandwidthSample; + } + get bandwidthStatus() { + var _a; + return (_a = this.statsEntity) === null || _a === void 0 ? void 0 : _a.bandwidthStatus; + } + get fragSample() { + var _a; + return (_a = this.statsEntity) === null || _a === void 0 ? void 0 : _a.fragSample; + } + // Aggregated data + get bandwidthEstimate$() { + return this.selectEntity(this.id, 'bandwidthEstimate'); + } + get fragEstimate$() { + return this.selectEntity(this.id, 'fragEstimate'); + } + get playlistEstimate$() { + return this.selectEntity(this.id, 'playlistEstimate'); + } + get bufferEstimate$() { + return this.selectEntity(this.id, 'bufferEstimate'); + } + // Individual samples + get bandwidthSample$() { + return this.selectEntity(this.id, ({ bandwidthSample }) => bandwidthSample).pipe(filterNullOrUndefined()); + } + get fragSample$() { + return this.selectEntity(this.id, ({ fragSample }) => fragSample).pipe(filterNullOrUndefined()); + } + get playlistSample$() { + return this.selectEntity(this.id, ({ playlistSample }) => playlistSample).pipe(filterNullOrUndefined()); + } + get bufferMetric$() { + return this.selectEntity(this.id, ({ bufferMetric }) => bufferMetric).pipe(filterNullOrUndefined()); + } + } + + /** + * @brief Backing store for stats + */ + /** + * @brief Store that keeps track of stats measured for network requests, + * demuxing, and buffering + */ + class StatsStore extends EntityStore { + constructor() { + super({}, { name: 'stats-store', producerFn: produce_1 }); + } + set statsEntity(statsEntity) { + logAction('statsStore.set.stats'); + applyTransaction(() => { + this.add(statsEntity); + this.setActive(statsEntity.id); + }); + } + set playlistSample(playlistSample) { + logAction(`stats.set.playlistSample: ${playlistSample}`); + this.updateActive((statsEntity) => { + statsEntity.playlistSample = playlistSample; + }); + } + set bandwidthSample(bandwidthSample) { + logAction(`stats.set.bandwidthSample: ${bandwidthSample}`); + this.updateActive((statsEntity) => { + statsEntity.bandwidthSample = bandwidthSample; + statsEntity.bandwidthStatus.bandwidthSampleCount += 1; + statsEntity.bandwidthStatus.instantBw = (bandwidthSample.loaded * 8000) / (bandwidthSample.tload - bandwidthSample.trequest); + }); + } + set fragSample(fragSample) { + logAction(`stats.set.fragSample: ${fragSample}`); + this.updateActive((statsEntity) => { + statsEntity.fragSample = fragSample; + }); + } + set bufferMetric(bufferMetric) { + logAction(`stats.set.bufferMetric: ${bufferMetric}`); + this.updateActive((statsEntity) => { + statsEntity.bufferMetric = bufferMetric; + }); + } + set bandwidthEstimate(bandwidthEstimate) { + logAction(`stats.set.bandwidthEstimate: ${bandwidthEstimate}`); + this.updateActive((statsEntity) => { + statsEntity.bandwidthEstimate = bandwidthEstimate; + }); + } + set fragEstimate(fragEstimate) { + logAction(`stats.set.fragEstimate: ${fragEstimate}`); + this.updateActive((statsEntity) => { + statsEntity.fragEstimate = fragEstimate; + }); + } + set playlistEstimate(playlistEstimate) { + logAction(`stats.set.playlistEstimate: ${playlistEstimate}`); + this.updateActive((statsEntity) => { + statsEntity.playlistEstimate = playlistEstimate; + }); + } + set bufferEstimate(bufferEstimate) { + logAction(`stats.set.bufferEstimate: ${bufferEstimate}`); + this.updateActive((statsEntity) => { + statsEntity.bufferEstimate = bufferEstimate; + }); + } + } + + /** + * @brief Service for managing stats samples and estimates + */ + class StatsService { + constructor(statsStore) { + this.statsStore = statsStore; + } + getQuery() { + return new QueryEntity(this.statsStore); + } + getQueryForItem(itemId) { + return new StatsQuery(this.statsStore, itemId); + } + remove(itemId) { + this.statsStore.remove(itemId); + } + removeAll() { + this.statsStore.remove(); + } + setBandwidthSample(bandwidthSample) { + this.statsStore.bandwidthSample = bandwidthSample; + } + setFragSample(fragSample) { + this.statsStore.fragSample = fragSample; + } + setPlaylistSample(playlistSample) { + this.statsStore.playlistSample = playlistSample; + } + setBufferMetric(bufferMetric) { + this.statsStore.bufferMetric = bufferMetric; + } + setBandwidthEstimate(bandwidthEstimate) { + this.statsStore.bandwidthEstimate = bandwidthEstimate; + } + setFragEstimate(fragEstimate) { + this.statsStore.fragEstimate = fragEstimate; + } + setPlaylistEstimate(playlistEstimate) { + this.statsStore.playlistEstimate = playlistEstimate; + } + setBufferEstimate(bufferEstimate) { + this.statsStore.bufferEstimate = bufferEstimate; + } + } + const statsStore = new StatsStore(); + let statsService = null; // + const createStatsQuery = (id) => { + return new StatsQuery(statsStore, id); + }; + function statsServiceSingleton() { + if (!statsService) { + statsService = new StatsService(statsStore); + } + return statsService; + } + const initializeStatsFunc = (itemId) => { + const statsQuery = createStatsQuery(itemId); + if (statsQuery.hasEntity(itemId)) { + return of(statsQuery); + } + return addStatsEntity(statsStore, itemId); + }; + function addStatsEntity(statsStore, itemId) { + logAction('stats.loading'); + statsStore.setLoading(true); + const statsEntity = { + id: itemId, + // bandwidthSample: { trequest: 0, tfirst: 0, tload: 0, loaded: 0, total: 0, complete: true }, + bandwidthEstimate: { avgLatencyMs: NaN, avgBandwidth: NaN }, + bandwidthStatus: { bandwidthSampleCount: 0, instantBw: NaN }, + // fragSample: { duration: 0, parseTimeMs: 0 }, + fragEstimate: { maxDurationSec: NaN, avgParseTimeMs: NaN }, + // playlistSample: { playlistLoadTimeMs: 0, playlistParseTimeMs: 0 }, + playlistEstimate: { avgPlaylistLoadTimeMs: NaN, avgPlaylistParseTimeMs: NaN }, + // bufferMetric: { + // fragmentType: MediaOptionType.Variant, + // startInitAppend: 0, + // endInitAppend: 0, + // initBytesAppend: 0, + // startDataAppend: 0, + // endDataAppend: 0, + // dataBytesAppend: 0, + // bufferCreationStart: 0, + // bufferCreationEnd: 0, + // }, + bufferEstimate: { + avgBufferCreateMs: NaN, + avgInitFragAppendMs: NaN, + avgDataFragAppendMs: NaN, + }, + }; + statsStore.statsEntity = statsEntity; + statsStore.setLoading(false); + logAction('stats.loaded'); + } + /** + * @brief Service that retrieves past stats and seeds + * the current sample and add to the store + */ + /* + export const initializeStats = () => (pipelineActionSource$: Observable<[RootPlaylistQuery, MediaElementQuery]>) => { + return pipelineActionSource$.pipe( + tag('stats.initializing'), + switchMap(item => { + if (!item) return EMPTY; + + const { itemId } = item; + // const configurationQuery = createConfigurationQuery(); + const statsQuery = createStatsQuery(itemId); + if(statsQuery.hasEntity(itemId)) { + return of(statsQuery); + } + statsStore.setLoading(true); + return of(item).pipe( + map(() => { + logAction(`stats.loaded`); + // TODO get it from persistent store + // or rebuild from configs + const statsEntity: StatsEntity = { + id: itemId, + bandwidthSample: {trequest: 0, tparsed: 0, tfirst: 0, tload: 0, loaded: 0}, + bandwidthEstimate: {avgLatencyMs: 0, avgBandwidth: 0}, + fragSample: { duration: 0, parseTimeMs: 0, bufferCreationDelayMs: 0, bufferTimeMs: 0}, + fragEstimate: { maxDuration: 0, maxParseTimeMs: 0, maxBufferCreationDelayMs: 0, maxBufferTimeMs: 0 }, + playlistSample: { playlistLoadTimeMs: 10 }, + playlistEstimate: { maxPlaylistLoadTimeMs: 10} }; - const b = c.enabledMediaOptionIdByType(ul.Variant) - , T = c.variantMediaOptionById(b) - , E = null != i.find(e=>e.mediaOptionId === b) - , I = T && T.iframes === a - , w = T && I ? T.score : void 0 - , A = T && I ? T.frameRate : void 0 - , O = T && I ? T.height : void 0 - , k = I ? Lg(p, u.maxBufferHole) : 0; - e = Math.max(0, Math.min(i.length - 1, e)), - n = Math.max(0, Math.min(i.length - 1, n)); - var C = h.mediaOptionDetailsEntityRecord - , D = Ug(o.avgBandwidth, l, t, m); - let M; - for (let t = e; t >= n; t--) { - const n = i[t]; - let e = n.mediaOptionId; - const l = n.score - , u = C && C[e] ? C[e].mediaOptionDetails : void 0 - , h = C && C[e] ? C[e].lastUpdateMillis : null - , p = u ? u.totalduration / u.fragments.length : r - , f = null != T && n.bitrate > T.bitrate - , B = null != T && n.bitrate < T.bitrate - , m = !(null != A && (f && n.frameRate < A || B && n.frameRate > A)) - , U = !(f && null != O && O > n.height) - , $ = !(B && (n.bitrate === T.bitrate - 1 || n.bitrate === T.bitrate + 1)) - , V = !(S && f && null != w && (l < w || l === w && T && n.bitrate >= T.bitrate)) - , K = n.iframes === a; - if (ne(p) && K && m && U && $ && V) { - var {adjustedbw: P, bitrate: x, fetchDuration: R, rejectLevelDueToPeakBW: L, canFitMultipleSegments: _, requireAlternates: N, alternates: F} = function(e, t, i, r, n, s, a, o, d, l, u, c) { - var h = n ? a.bwUp : a.bwDown - , n = e.bitrate - , a = t ? t.totalduration / t.fragments.length : o - , s = $g(e, t, o, h, ne(s.avgPlaylistLoadTimeMs) ? s.avgPlaylistLoadTimeMs : s.avgLatencyMs, l) - , l = e.bandwidth - , i = n < h && h < l && i <= 2 * a - , d = r * ((l || n || 0) * ((null == t ? void 0 : t.targetduration) || a)) / 8 <= d; - let p = null; - u = !u; - return u && (p = Fg(e, c), - p.altAudio && p.subtitle || (p = null)), - { - adjustedbw: h, - bitrate: n, - fetchDuration: s, - rejectLevelDueToPeakBW: i, - canFitMultipleSegments: d, - requireAlternates: u, - alternates: p - } - }(n, u, k, v, f, o, D, r, y, h, a, c); - if (N && Boolean(F) && (M = e), - x < P && _ && !L && (!N || Boolean(F)) && (a || !R || R < s)) - return L = P, - N = g, - P = (P = d).instantBw, - (N.fragDownloadSlow || N.fragDownloadTooSlow || ne(P) && P < L) && E && I && k <= 2 * p && f && (e = b), - { - variantMediaOption: e, - holdOffDuration: R, - alternates: F, - lowestCandidate: M - } - } - } - return { - variantMediaOption: Ol.mediaOptionId, - holdOffDuration: -1, - lowestCandidate: M - } - } - function Ug(e, t, i, r) { - let n, s; - return 4 <= r ? (n = e * t, - s = e * i) : n = s = e / 1.8, - { - bwUp: n, - bwDown: s - } - } - function $g(e, t, i, r, n, s) { - let a = e.bitrate * (t ? t.totalduration / t.fragments.length : i) / r; - return null == t || !t.liveOrEvent || t.ptsKnown && !Kg(t.totalduration, n, s) || (a *= 2), - ne(n) && (!ne(s) || null != t && t.liveOrEvent) && (a += n / 1e3), - a - } - function Vg(t, e) { - let i = 1 / 0; - if (t === Ol.mediaOptionId) - return i; - var r = e.find(e=>e.mediaOptionId === t); - if (!r) - return 1 / 0; - const n = r.iframes - , s = r.bitrate - , a = r.frameRate - , o = e.find(e=>e.iframes === n && (void 0 === a || e.frameRate >= a) && e.bitrate > s); - return o && (i = o.bitrate), - i - } - function Kg(e, t, i) { - return t = ne(t) ? t : 0, - !ne(i) || performance.now() - i + t > 1e3 * e - } - function Hg(e, t) { - return (null == e ? void 0 : e.fragDownloadSlow) === (null == t ? void 0 : t.fragDownloadSlow) && e.fragDownloadTooSlow === (null == t ? void 0 : t.fragDownloadTooSlow) - } - function jg(e) { - return "loading" === (null == e ? void 0 : e.state) && ne(null === (e = e.bwSample) || void 0 === e ? void 0 : e.trequest) - } - const qg = 2e3; - function Qg(e, t, i, r) { - let {fragDownloadSlow: n, fragDownloadTooSlow: s} = t; - var a = i.variantMediaOptionById(e.mediaOptionId).bitrate - , t = e.bwSample; - r = r.child(Pg); - i = t.total || Math.max(t.loaded, Math.round(e.duration * a / 8)), - a = performance.now() - t.tfirst, - i = t.loaded * e.duration * 1e3 / i; - return a >= qg && 1e3 <= a - i && (n || r.warn(`flow indicates low bandwidth, after time/duration behind real time: ${a}/${a - i}`), - n = !0), - a >= 1e3 * e.duration && (s || r.warn(`too much time spent downloading fragment, likely to switch down ${a} > ${1e3 * e.duration}`), - s = !0), - { - fragDownloadSlow: n, - fragDownloadTooSlow: s - } - } - function Gg(e, t, i, r, n) { - var s; - const a = n.logger.child(Pg) - , o = r.isIframeRate - , d = i.mediaOptionListQueries[ul.Variant].preferredMediaOptionList - , l = i.enabledMediaOptionKeys[ul.Variant]; - let u = e; - if (u !== wm.None || d.some(e=>e.mediaOptionId === l.mediaOptionId) || (u = wm.PreferredListChanged), - u !== wm.None && !(o && u !== wm.IframeModeChange && r.getBufferedSegmentsByType(cl.Variant).filter(e=>e.frag.iframe).length < t.minFramesBeforeSwitchingLevel)) { - const c = Qf(i.itemId) - , h = bg(l) - , p = [Ol, Ol, Ol] - , f = function(e, t, i, r, n, s, a) { - let o = t.nextMaxAutoOptionId; - if (o === Ol.mediaOptionId || Rg(s.getBandwidthEstimate())) - return d = e, - l = t, - u = r, - e = n, - r = s, - s = a.child({ - name: "abr" - }), - a = e.isIframeRate, - l.enabledMediaOptionIdByType(ul.Variant), - Ng(a, d, l, u, e, r, s); - if (n.isIframeRate) - return { - variantMediaOption: o, - holdOffDuration: 0, - lowestCandidate: null - }; - { - const c = t.variantMediaOptionById(o) - , h = t.enabledAlternateMediaOptionByType(ul.Subtitle) - , n = t.enabledAlternateMediaOptionByType(ul.AltAudio) - , p = null == n ? void 0 : n.persistentID - , f = null == h ? void 0 : h.persistentID - , m = !t.preferHDR - , g = i.getBestMediaOptionTupleFromVariantAndPersistentId(t, c, p, f, void 0, [], m, !1, !1); - return t.isValidMediaOptionTuple(g) ? (o = g[ul.Variant].mediaOptionId, - { - variantMediaOption: o, - holdOffDuration: 0, - alternates: { - altAudio: g[ul.AltAudio], - subtitle: g[ul.Subtitle] - }, - lowestCandidate: null - }) : { - variantMediaOption: t.enabledMediaOptionKeys[ul.Variant].mediaOptionId, - holdOffDuration: 0, - lowestCandidate: null - } - } - var d, l, u - }(t, i, n, h, r, c, a); - if (f.variantMediaOption !== l.mediaOptionId) { - p[ul.Variant] = { - itemId: i.itemId, - mediaOptionId: f.variantMediaOption - }; - for (const e of [ul.AltAudio, ul.Subtitle]) { - const t = i.enabledMediaOptionIdByType(e); - if (t !== Ol.mediaOptionId) { - const r = e === ul.AltAudio ? null === (s = f.alternates) || void 0 === s ? void 0 : s.altAudio : null === (s = f.alternates) || void 0 === s ? void 0 : s.subtitle; - p[e] = r || { - itemId: i.itemId, - mediaOptionId: t - } - } - } - return n.setEnabledMediaOptions(i.itemId, p), - 1 - } - } - } - const Wg = { - name: "iframes" - } - , zg = new pd({},{ - name: "item-queue", - producerFn: vc, - idKey: "itemId", - resettable: !0 - }) - , Xg = new class extends Od { - } - (zg); - class Yg { - constructor() { - this.firstItem = !0, - this.playingEntity = null, - this.loadingEntity = null - } - static createItem(e, t, i, r, n) { - const s = new Date - , a = `${s.getHours()}:${s.getMinutes()}:${s.getSeconds()}`; - qe(); - var o = function(e) { - e = sl.parseURL(e).fragment.substr(1); - if (0 === e.length) - return null; - const t = new URLSearchParams(e); - if (!t.has("t")) - return null; - e = Number(t.get("t")); - return ne(e) ? e : null - }(t); - if (o) - i = o; - else { - const e = ng(); - ne(null == e ? void 0 : e.startPosition) && (i = e.startPosition) - } - return { - itemId: `${e}_${a}`, - name: e, - url: t, - serviceName: n, - createTime: a, - initialSeekTime: i, - itemStartOffset: 0, - platformInfo: r, - config: {} - } - } - get activeItemById$() { - return Xg.selectActiveId().pipe(ur(e=>Xg.getActive())) - } - get removedItems$() { - return Xg.selectEntityAction(To.Remove).pipe(ur(e=>e)) - } - get activeItem() { - return Xg.getActive() - } - get queueItems$() { - return Xg.selectAll().pipe(ur(e=>null != e ? e : [])) - } - get isFirstItem() { - return this.firstItem - } - get playingItem() { - return this.playingEntity - } - get loadingItem() { - return this.loadingEntity - } - addQueueItem(e, t, i, r, n, s) { - Xg.getCount(); - const a = Yg.createItem(e, t, i, r, s); - null != this.playingEntity && (a.initialSeekTime = void 0), - n && (a.itemStartOffset = n, - this.firstItem = !1, - this.playingEntity = this.activeItem, - this.loadingEntity = a), - Co(`queue.add.item: ${e}`), - sd(()=>{ - zg.add(a), - zg.setActive(a.itemId) - } - ) - } - updatePlayingItemId() { - this.playingEntity = this.loadingEntity, - this.loadingEntity = null, - this.clearAllButActive() - } - resetLoadingItem() { - this.removeQueueItem(this.loadingEntity.itemId), - this.loadingEntity = null, - sd(()=>{ - zg.setActive(this.playingEntity.itemId) - } - ) - } - isPreloading() { - return null !== this.playingEntity && null !== this.loadingEntity - } - setQueueItem(t, i, r, n, s) { - Co("queue.set.item"), - this.loadingEntity = null, - sd(()=>{ - zg.reset(); - var e = Yg.createItem(t, i, r, n, s); - zg.add(e), - zg.setActive(e.itemId) - } - ), - this.playingEntity = this.activeItem - } - removeQueueItem(e) { - zg.remove(e) - } - clearQueue() { - zg.reset() - } - clearAllButActive() { - var e; - const t = null === (e = this.activeItem) || void 0 === e ? void 0 : e.itemId; - sd(()=>{ - Xg.getAll().forEach(e=>{ - e.itemId !== t && zg.remove(e.itemId) - } - ) - } - ) - } - set earlyAudioSelection(t) { - zg.updateActive(e=>{ - e.earlySelection || (e.earlySelection = {}), - e.earlySelection.audioPersistentId = t - } - ) - } - get earlyAudioSelection() { - var e; - return null === (e = this.activeItem.earlySelection) || void 0 === e ? void 0 : e.audioPersistentId - } - set earlySubtitleSelection(t) { - zg.updateActive(e=>{ - e.earlySelection || (e.earlySelection = {}), - e.earlySelection.subtitlePersistentId = t - } - ) - } - get earlySubtitleSelection() { - var e; - return null === (e = this.activeItem.earlySelection) || void 0 === e ? void 0 : e.subtitlePersistentId - } - } - function Jg(e, t, i, r, n, s) { - return Gm(e, 0, Vm({ - errorAction: Em.RemoveAlternatePermanently, - errorActionFlags: 0 - }, !1, e.response.code, i, t, s, n), s, n, t, i).pipe(Un(e=>{ - throw !1 === e.fatal && r.resetMediaSource(), - e - } - )) - } - function Zg(e, t) { - if (!e || 0 === e.length) - return 0; - const i = [...e].sort((e,t)=>t[0] - e[0]) - , r = t.getTime() - , n = null !== (t = i.find(([e])=>r >= e)) && void 0 !== t ? t : i[i.length - 1] - , [s,a] = n - , o = a + (r - s) / 1e3; - return Math.max(0, o) - } - function ey(e, t) { - if (e && 0 !== e.length) { - const i = [...e].sort((e,t)=>t[1] - e[1]) - , r = null !== (e = i.find(([,e])=>e <= t)) && void 0 !== e ? e : i[i.length - 1] - , [n,s] = r; - return new Date(n + 1e3 * (t - s)) - } - } - function ty(l, e, u, c, h, p) { - return e.child({ - name: "seek" - }), - e=>e.pipe(Ra((e,t)=>{ - var i, r, n, s, a, o, d = u.mediaQuery.seekTo$.pipe(Up()); - return i = 0 === t, - r = l, - n = h, - s = p, - (null == (t = e) ? Ti : t instanceof Date ? (a = t, - o = s, - n.enabledMediaOptionByType$(ul.Variant).pipe(Ra(e=>o.getQueryForOption(e).mediaOptionDetails$), ur(e=>Zg(e.dateMediaTimePairs, a)), Cs(1))) : function(n, e, s, a, t) { - let i = a.enabledMediaOptionByType$(ul.Variant).pipe(Ra(e=>t.getQueryForOption(e).mediaOptionDetails$), an(e=>ne(null == e ? void 0 : e.totalduration)), Cs(1), ur(e=>{ - var t = !e.liveOrEvent - , i = e.totalduration - , r = a.itemStartOffset; - return t ? ne(n) ? 0 <= n ? n : r + (i + n) : r + (ne(e.startTimeOffset) ? e.startTimeOffset : 0) : !ne(n) || n < 0 || 0 === n && s.liveEdgeForZeroStartPositon ? lg(0, e, s) : n - } - )); - return e && (i = i.pipe(Ja(e=>{} - ))), - i - }(t, i, r, n, s)).pipe($s(()=>{ - null != e && c.setPendingSeek(h.itemId, void 0) - } - ), $a(d)) - } - ), Ja(e=>{ - ne(e) && (u.seekTo = e) - } - )) - } - class iy { - constructor(e, t, i, r, n, s) { - this.logger = e, - this._rootPlaylistService = t, - this._rootQuery = i, - this._mediaQuery = r, - this._iframeMachine = n, - this._anchorMSNs = [NaN, NaN], - this._avDetails = [null, null], - this.logger = e.child({ - name: "fpicker" - }), - this._discoSeqNum = NaN, - this.lookUpTolerance = Math.max(s.maxBufferHole, s.maxFragLookUpTolerance) - } - destroy() { - this._anchorMSNs = [NaN, NaN], - this._avDetails = [null, null], - this._rootQuery = null, - this._mediaQuery = null, - this._rootPlaylistService = null, - this._iframeMachine = null - } - get discoSeqNum() { - return this._discoSeqNum - } - get _discoSeqNum() { - return this._rootQuery.discoSeqNum - } - set _discoSeqNum(e) { - this._rootPlaylistService.setDiscoSeqNum(this._rootQuery.itemId, e) - } - get anchorMSNs() { - return this._anchorMSNs - } - _resolvePosition(e, t, i) { - let r = e; - t = this._avDetails[t]; - if ((null == t ? void 0 : t.mediaOptionId) !== (null == i ? void 0 : i.mediaOptionId) && i.liveOrEvent && !1 === i.ptsKnown) - if (null != (null == t ? void 0 : t.dateMediaTimePairs) && i.dateMediaTimePairs) { - const n = ey(t.dateMediaTimePairs, e); - r = Zg(i.dateMediaTimePairs, n) - } else { - const e = 3 * i.targetduration - , n = i.fragments[0].start + i.totalduration; - r = Math.max(0, n - e) - } - return r - } - _updateAnchorByPosition(e, t) { - let i = NaN; - const r = t[cl.Variant]; - if (r) { - const t = r.fragments - , n = this._resolvePosition(e, cl.Variant, r); - if (i = Bl.ccForTime(t, n), - !ne(i)) { - const r = t[0] - , s = t[t.length - 1] - , a = r.start - , o = s.start + s.duration; - this.logger.warn(`${e.toFixed(3)} out of range [${a.toFixed(3)},${o.toFixed(3)}]`), - e <= a ? i = r.discoSeqNum : e >= o && (i = s.discoSeqNum) - } - } else - this.logger.warn("No variant details for anchoring"); - this._updateAnchor(i, t) - } - _updateAnchor(e, n) { - const s = e !== this._discoSeqNum; - s && (this._discoSeqNum = e), - Ml.forEach(e=>{ - const t = this._avDetails[e] - , i = n[e] - , r = (null == t ? void 0 : t.mediaOptionId) !== (null == i ? void 0 : i.mediaOptionId); - if (s || r) - this._updateAnchorForType(xl(e), i); - else if (i) { - const {mediaOptionId: n, ptsKnown: s, dateMediaTimePairs: t} = i; - this._avDetails[e] = { - mediaOptionId: n, - ptsKnown: s, - dateMediaTimePairs: t - } - } - } - ) - } - getNextFragments(e, i) { - const {position: r, bufferInfoTuple: t, switchContexts: n} = e - , s = t.map((e,t)=>ry(r, i[t], n[t], null == e ? void 0 : e.buffered, this.lookUpTolerance)).reduce((e,t)=>Math.min(t, e), Number.POSITIVE_INFINITY); - return this._updateAnchorByPosition(s, i), - this._getNextFragmentsInternal(e, i) - } - _getNextFragmentsInternal(i, r) { - const n = [null, null]; - r.forEach((e,t)=>{ - n[t] = this._getNextFragmentForType(i, r, t) - } - ); - var e = n[cl.Variant] - , t = n[cl.AltAudio] - , s = null === (a = null == e ? void 0 : e.foundFrag) || void 0 === a ? void 0 : a.mediaFragment - , a = null === (a = null == t ? void 0 : t.foundFrag) || void 0 === a ? void 0 : a.mediaFragment; - if (s && a && (a.start > s.start + s.duration ? (this.logger.warn("Audio too far ahead"), - n[cl.AltAudio] = iy.noopResult) : s.start > a.start + a.duration && !this._mediaQuery.isIframeRate && (this.logger.warn("Video too far ahead"), - n[cl.Variant] = iy.noopResult)), - !isFinite(null == e ? void 0 : e.nextDisco) || null != t && !ne(t.nextDisco)) - return n; - { - const o = n[cl.Variant].nextDisco; - return this._updateAnchor(o, r), - this._getNextFragmentsInternal(i, r) - } - } - _getNextFragmentForType(e, t, i) { - var {position: r, bufferInfoTuple: n, switchContexts: s} = e - , a = t[i] - , o = null !== (l = null === (c = n[i]) || void 0 === c ? void 0 : c.buffered) && void 0 !== l ? l : { - start: r, - end: r, - len: 0 - } - , d = this._mediaQuery.getBufferedSegmentsByType(i) - , l = null !== (c = null === (e = s[i]) || void 0 === e ? void 0 : e.userInitiated) && void 0 !== c && c - , u = ry(r, a, s[i], o, this.lookUpTolerance); - if (!a) - return null; - var {highWaterLevelSeconds: e, lowWaterLevelSeconds: c} = this._mediaQuery.bufferMonitorInfo - , r = o.len; - if (!l && e <= r) - return iy.noopResult; - var e = i === cl.Variant ? cl.AltAudio : cl.Variant - , n = null === (n = n[e]) || void 0 === n ? void 0 : n.buffered - , e = null !== (e = null === (e = s[e]) || void 0 === e ? void 0 : e.userInitiated) && void 0 !== e && e; - let h = !1; - i === cl.Variant && c <= r && 1 < this._mediaQuery.expectedSbCount && null != n && n.end < o.end && (e || n.end - n.start < c) && (h = !0); - let p, f = null, m = NaN; - if (this._mediaQuery.isIframeRate && i === cl.Variant && a.iframesOnly) { - const g = function(e, t, i) { - e = i.nextFragment(a.fragments, (null == e ? void 0 : e.fragments) || [], t, u); - if (!e) - return null; - var {frag: t, newMediaRootTime: e} = e; - return { - foundFrag: { - timelineOffset: t.iframeMediaStart, - mediaFragment: t - }, - nextDisco: NaN, - newMediaRootTime: e - } - }(t[cl.AltAudio], this._mediaQuery.desiredRate, this._iframeMachine); - if (g) { - ({foundFrag: f, nextDisco: m, newMediaRootTime: p} = g); - const i = f.mediaFragment; - i.discoSeqNum !== this._discoSeqNum && this._updateAnchor(i.discoSeqNum, t) - } - } else { - const g = this._anchorMSNs[i]; - ({foundFrag: f, nextDisco: m, newMediaRootTime: p} = fg(u, this._discoSeqNum, g, a, d)) - } - return h && this._rootQuery.getInitPTS(null == f ? void 0 : f.mediaFragment.discoSeqNum) ? iy.noopResult : { - foundFrag: f, - nextDisco: m, - newMediaRootTime: p - } - } - _updateAnchorForType(e, t) { - var i, r, n; - if (!t) - return this._anchorMSNs[e] = NaN, - void (this._avDetails[e] = null); - ne(this._discoSeqNum) ? (n = this._discoSeqNum, - n = null !== (r = null == (n = (r = t.fragments, - i = n, - r.find(e=>e.discoSeqNum === i))) ? void 0 : n.mediaSeqNum) && void 0 !== r ? r : t.startSN, - this._anchorMSNs[e] = n, - {mediaOptionId: r, ptsKnown: n, dateMediaTimePairs: t} = t, - this._avDetails[e] = { - mediaOptionId: r, - ptsKnown: n, - dateMediaTimePairs: t - }) : this.logger.warn("Trying to anchor with non-finite discoSeqNum") - } - } - function ry(e, t, i, r, n) { - r = null != r ? r : { - start: e, - end: e, - len: 0 - }; - i = null !== (i = null == i ? void 0 : i.userInitiated) && void 0 !== i && i, - n = null != t && t.iframesOnly ? 0 : n; - return i || 0 === r.len ? e : r.end + n - } - iy.noopResult = { - foundFrag: null, - nextDisco: NaN - }; - const ny = { - name: "avpipe" - }; - function sy(r) { - const {config: o, rootPlaylistService: d, rootPlaylistQuery: l, mediaSink: e, gaplessInstance: t} = r - , u = e.mediaQuery - , i = Zd(Ml.map(e=>l.enabledMediaOptionSwitchForType$(e).pipe(Ja(e=>{} - )))).pipe(Ra(e=>{ - if (!kl({ - itemId: l.itemId, - mediaOptionId: e[ul.Variant].toId - })) - throw new V(!0,`No valid variant enabled id:${e[ul.Variant].toId}`,$.NoValidAlternates); - e = e.map(({fromId: e, toId: t},i)=>function(t, i, r, n, s) { - var e, a, o; - const {rootPlaylistQuery: d, rootPlaylistService: l, mediaSink: u, mediaParser: c, config: h, iframeMachine: p} = t - , f = u.mediaQuery; - if (!n || !s || n === s) - return Ul; - switch (r) { - case ul.Variant: - { - c.reset(ul.Variant); - const t = xl(r) - , l = d.variantMediaOptionById(n) - , g = d.variantMediaOptionById(s); - if (null == g || null == l) - return Ul; - let e = NaN; - if (l.iframes !== g.iframes || !g.iframes && p.isStarted) { - if (u.toggleTrickPlaybackMode(g.iframes), - !g.iframes && p.isStarted) { - const t = u.mediaQuery.autoPausedRestartTime - , i = t || p.iframeClockTimeSeconds; - u.autoPausedRestartTime = void 0, - e = i, - p.stop() - } - return u.pause(), - u.flushData(t, 0, 1 / 0, !0).pipe(Ja(()=>{ - isFinite(e) && (u.seekTo = e) - } - )) - } - if (!h.allowFastSwitchUp || g.iframes) - return Ul; - var m = bg(l).mediaOptionDetails; - if (null != m && null != g && l.bitrate < g.bitrate) { - const r = m.targetduration - , n = bg(g) - , s = n.mediaOptionDetails - , c = n.mediaOptionDetailsEntity.lastUpdateMillis - , p = f.getCurrentWaterLevelByType(t, h.maxBufferHole) - , y = function(e, t, i, r, n, s, a, o) { - if (n.nextMaxAutoOptionId !== Ol.mediaOptionId && !Rg(s.getBandwidthEstimate())) - return Number.POSITIVE_INFINITY; - a = Ug(s.getBandwidthEstimate().avgBandwidth, a.abrBandWidthUpFactor, a.abrBandWidthFactor, s.bandwidthStatus.bandwidthSampleCount), - s = ne(s.getPlaylistEstimate().avgPlaylistLoadTimeMs) ? s.getPlaylistEstimate().avgPlaylistLoadTimeMs : s.getBandwidthEstimate().avgLatencyMs, - a = t.bitrate > e.bitrate ? a.bwUp : a.bwDown; - return null == i || !i.liveOrEvent || i.ptsKnown && !Kg(i.totalduration, s, o) ? $g(t, i, r, a, s, o) : Number.POSITIVE_INFINITY - }(l, g, s, r, d.abrStatus, i, h, c) + h.maxStarvationDelay - , v = f.currentTime + y - , S = null === (o = null === (a = f.sourceBufferEntityByType(t)) || void 0 === a ? void 0 : a.bufferedSegments) || void 0 === o ? void 0 : o.find(e=>e.startPTS >= v); - let e; - if (S) { - const t = S.endPTS - S.startPTS; - e = S.startPTS + Math.min(Math.max(t - h.maxFragLookUpTolerance, .5 * t), .75 * t) - } - if (ne(e) && p >= y) - return u.flushData(t, e, 1 / 0) - } - } - break; - case ul.AltAudio: - e = d, - m = s, - o = "Nah" === (a = n) ? null : e.alternateMediaOptionById(ul.AltAudio, a), - o = Boolean(o && o.url), - m = "Nah" === a ? null : e.alternateMediaOptionById(ul.AltAudio, m), - m = Boolean(m && m.url), - o && !m && (l.setEnabledMediaOptionSwitchContextByType(d.itemId, ul.AltAudio, s, void 0), - u.resetMediaSource(f.currentTime)), - c.reset(ul.AltAudio) - } - return Ul - }(r, n, i, e, t)); - return Xr(Bi(!0), Jr(e).pipe(Js(!1))) - } - ), Ql.tag("mediaOptionSwitch.audiovideo.out")) - , n = Qf(l.itemId) - , s = r.logger.child(ny) - , a = new iy(s,d,l,u,r.iframeMachine,o); - return Zd([l.anchorTime$.pipe(Ql.tag("anchorTime.audiovideo.in")), i]).pipe(Ra(([i,e])=>e ? Ti : u.needData$(o.maxBufferHole, t.inGaplessMode, t.isPreloading).pipe(ur(e=>{ - var t = [l.enabledMediaOptionSwitchContexts[ul.Variant], l.enabledMediaOptionSwitchContexts[ul.AltAudio]]; - return u.getSourceBufferInfoAction(e, i, t, o.maxBufferHole) - } - ), Ls(e=>{ - if (!e) - return Ti; - e = Bi(e).pipe(ay(r, a), dy(r)); - return hn($l(function(e) { - const {mediaSink: t, rootPlaylistQuery: i, rootPlaylistService: r} = e - , n = t.mediaQuery - , s = e.logger.child(Pg); - return nn((a = i, - o = s, - Zd([n.fellBelowLowWater$, a.getInFlightFragByType$(ul.Variant)]).pipe(Ra(e=>{ - var [,t] = e; - if (!jg(t)) - return Ti; - const i = performance.now() - t.bwSample.trequest - , r = qg - i - , n = 1e3 * t.duration - i - , s = [Ul]; - return 0 < r && s.push(vn(r)), - 0 < n && s.push(vn(n)), - nn(...s).pipe(Js(e)) - } - ), na((e,[t,i])=>{ - const r = Object.assign({}, e); - return t && (r.fragDownloadSlow = !0), - Qg(i, r, a, o) - } - , { - fragDownloadSlow: !1, - fragDownloadTooSlow: !1 - }), xa({ - fragDownloadSlow: !1, - fragDownloadTooSlow: !1 - }), Es(Hg))), function(r) { - const s = r.mediaSink.mediaQuery - , {rootPlaylistQuery: e, config: a} = r; - return s.desiredRate$.pipe(Ra(t=>0 === t ? Ti : Zd([e.getInFlightFragByType$(ul.Variant), e.mediaOptionListQueries[ul.Variant].preferredMediaOptionList$.pipe(ur(e=>e.filter(Nm.bind(null, jp(t)))))])), so(100), Ra(e=>{ - const [t,i] = e; - if (!jg(t) || i.findIndex(e=>e.mediaOptionId === t.mediaOptionId) <= 0) - return Ti; - var r = performance.now() - t.bwSample.trequest - , n = xg(t.duration, a.maxStarvationDelay) - , n = Math.min(1e3 * n, 500 * t.duration / s.playbackRate); - return vn(Math.max(0, n - r), 100).pipe(Js(e)) - } - )).pipe(na((e,[t,i])=>function(t, i, r, e) { - let {fragDownloadSlow: n, fragDownloadTooSlow: s} = t; - const {config: a, rootPlaylistService: o, rootPlaylistQuery: d, mediaSink: l, statsService: u, mediaLibraryService: c} = e - , h = e.logger.child(Pg) - , p = l.mediaQuery; - if (p.paused) - return t; - e = i.bwSample; - if (!ne(e.tfirst)) - return t; - const f = performance.now() - , m = f - e.trequest - , g = xg(i.duration, a.maxStarvationDelay) - , y = ul.Variant - , v = i.mediaOptionId - , S = d.variantMediaOptionById(v) - , b = c.getQueryForOption(S) - , T = S.bitrate - , E = Math.max(1, 8e3 * e.loaded / m) - , I = 8 * ((ne(e.total) ? e.total : Math.max(e.loaded, Math.round(i.duration * T / 8))) - e.loaded) / E - , w = Lg(p, a.maxBufferHole); - let A; - if (ne(w) && 0 < w && !ne(null === (O = p.seekTo) || void 0 === O ? void 0 : O.pos)) - A = w; - else { - const _ = m / 1e3; - A = _ < g ? g - _ : g - } - var O = n; - ({fragDownloadSlow: n, fragDownloadTooSlow: s} = Qg(i, t, d, h)); - t = 2 * ((null === (t = b.mediaOptionDetails) || void 0 === t ? void 0 : t.targetduration) || i.duration); - if (!(w <= t && (I >= A || n))) - return rg().getQuery().extendMaxTTFB && rg().setExtendMaxTTFB(0), - { - fragDownloadSlow: n, - fragDownloadTooSlow: s - }; - O || h.warn(`likely to stall ${se({ - maxTimeToLoadSec: A, - minSwitchDuration: t, - stats: e, - elapsedMs: m, - remainingTimeSec: I, - instantBw: E, - bufferAheadSec: w, - fragDownloadSlow: n - })}`), - n = !0, - rg().getQuery().extendMaxTTFB || rg().setExtendMaxTTFB(6e5); - O = I >= A; - let k; - const C = i.itemId - , D = u.getQueryForItem(C) - , M = D.getCombinedEstimate() - , P = Object.assign(Object.assign({}, M), { - avgBandwidth: E - }) - , x = D.bandwidthStatus - , R = S.iframes - , L = _g(0, r, R, d); - if (L < 0) - return { - fragDownloadSlow: n, - fragDownloadTooSlow: s - }; - t = Math.max(L, r.findIndex(e=>e && e.mediaOptionId === S.mediaOptionId)); - if (O) { - let e = Bg(r, i.duration, L, t, A, R, P, x, 1, 1, a, d, b, p, h); - const N = Ol.mediaOptionId; - k = e.variantMediaOption !== N || (e = Bg(r, i.duration, L, t, I, R, P, x, 1, 1, a, d, b, p, h)).variantMediaOption !== N ? e.variantMediaOption : e.lowestCandidate - } else { - const _ = _g(0, r.slice(L, t).reverse(), R, d) - , i = t - 1 - _; - (0 <= _ || t === L) && (k = r[i].mediaOptionId) - } - if (null != k && k !== d.abrStatus.nextMaxAutoOptionId && o.setNextMaxAutoOptionId(C, k), - O) - throw h.warn(`loading too slow, abort fragment loading and switch to level ${k}`), - u.setBandwidthSample(Object.assign(Object.assign({}, e), { - tfirst: e.tfirst || f, - tload: e.tload || f, - complete: !0, - mediaOptionType: y - })), - s = !0, - new du({ - mediaOptionType: y, - mediaOptionId: v - },k,$.FragmentAbortError); - return { - fragDownloadSlow: n, - fragDownloadTooSlow: s - } - }(e, t, i, r), { - fragDownloadSlow: !1, - fragDownloadTooSlow: !1 - }), xa({ - fragDownloadSlow: !1, - fragDownloadTooSlow: !1 - }), Es(Hg)) - }(e)).pipe(xa({ - fragDownloadSlow: !1, - fragDownloadTooSlow: !1 - }), na((e,t)=>({ - fragDownloadSlow: e.fragDownloadSlow || t.fragDownloadSlow, - fragDownloadTooSlow: e.fragDownloadTooSlow || t.fragDownloadTooSlow - })), Es(Hg), ur(e=>(r.setFragLoadSlow(i.itemId, e), - !1)), Un(e=>{ - if (e instanceof du) { - const e = { - fragDownloadSlow: !0, - fragDownloadTooSlow: !0 - }; - return r.setFragLoadSlow(i.itemId, e), - Bi(!0) - } - return Ui(e) - } - )); - var a, o - }(r), e=>e), e).pipe(Cs(1), $s(()=>{ - Ml.forEach(e=>{ - d.updateInflightFrag(l.itemId, e, null, null, null) - } - ) - } - )) - } - ))), ur(()=>{ - if (!l.getEntity(l.itemId).manualMode) { - let e = wm.None; - var i, r, n, s; - i = bf(), - r = u, - n = o, - s = null == r ? void 0 : r.clientWidth, - a = null == r ? void 0 : r.clientHeight, - r = "object" == typeof window && window.devicePixelRatio ? window.devicePixelRatio : 1, - a = s && a ? { - width: s * r, - height: a * r - } : void 0, - r = (r = (null === (r = i.getQuery()) || void 0 === r ? void 0 : r.viewportInfo) || {}) && a && (r.width !== a.width || r.height !== a.height), - n.useViewportSizeForLevelCap && r && (i.updateViewportInfo(a), - 1) && (e = wm.PreferredListChanged); - let t = !1; - var a = l.enabledVariantMediaOption; - !function(e, t) { - const i = d.logger.child(Pg) - , r = e.abrStatus - , n = r.fragDownloadSlow || r.fragDownloadTooSlow - , s = ne(null === (t = t.seekTo) || void 0 === t ? void 0 : t.pos); - return n && !r.fragDownloadTooSlow && s ? (i.warn("could be ignoring low bandwidth due to seek"), - 0) : n - }(l, u) ? function(e, t) { - const i = Qf(t.itemId) - , r = i.getBandwidthEstimate() - , n = t.abrStatus; - if (Rg(r)) { - var t = (null === (t = i.bandwidthStatus) || void 0 === t ? void 0 : t.bandwidthSampleCount) || 0 - , t = Ug(r.avgBandwidth, e.abrBandWidthUpFactor, e.abrBandWidthFactor, t)["bwUp"]; - return t > n.highBWTrigger - } - }(o, l) && (e = wm.HighBandwidth, - d.setNextMinAutoOptionId(a.itemId, a.mediaOptionId)) : (e = wm.LowBandwidth, - l.nextMaxAutoOptionId === Ol.mediaOptionId && (d.setNextMaxAutoOptionId(a.itemId, a.mediaOptionId), - t = !0)), - Gg(e, o, l, u, d), - t ? d.setNextMaxAutoOptionId(a.itemId, Ol.mediaOptionId) : e === wm.HighBandwidth && d.setNextMinAutoOptionId(a.itemId, Ol.mediaOptionId) - } - } - ), $s(()=>{} - )) - } - const ay = (r,n)=>e=>{ - const {rootPlaylistQuery: t, mediaSink: a} = r - , i = r.logger.child(ny); - return e.pipe(Hi(Zi), So(t.enabledMediaOptionKeys$), Ra(([s,e])=>bn(oy(s, ul.Variant, r, e).pipe(Ja(e=>{ - var e = e.detailsEntity; - if (!e.mediaOptionDetails.liveOrEvent || e.mediaOptionDetails.ptsKnown) { - const t = e.playlistDuration - , i = (null === (e = s.bufferInfoTuple[0]) || void 0 === e ? void 0 : e.buffered.end) || 0 - , r = (null === (e = s.bufferInfoTuple[1]) || void 0 === e ? void 0 : e.buffered.end) || 0 - , n = Math.max(i, r); - a.msDuration = ne(a.msDuration) ? Math.max(a.msDuration, t, n) : t - } - } - )), oy(s, ul.AltAudio, r, e)).pipe(ur(e=>({ - action: s, - detailsAndContext: e - })))), Ra(({action: e, detailsAndContext: t})=>function t(i, r, n, s, l) { - var e; - const {mediaSink: u, iframeMachine: c, rootPlaylistQuery: a} = n - , o = [l[ul.Variant].detailsEntity.mediaOptionDetails, null === (e = null === (e = l[ul.AltAudio]) || void 0 === e ? void 0 : e.detailsEntity) || void 0 === e ? void 0 : e.mediaOptionDetails]; - let d = r.getNextFragments(s, o); - const h = d.reduce((e,t)=>Math.max(e, ne(null == t ? void 0 : t.newMediaRootTime) ? t.newMediaRootTime : -1 / 0), -1 / 0); - return ne(h) && (u.seekTo = h, - d = [null, null]), - d.every(e=>null == (null == e ? void 0 : e.foundFrag)) ? Bi(null) : bn(...d.map((e,d)=>e && null != e.foundFrag ? Ag(n, d, e).pipe(Ja(e=>{ - const t = e[1] - , i = l[d].switchContext; - t.switchPosition = null == i ? void 0 : i.switchPosition; - const r = null !== (e = null == i ? void 0 : i.userInitiated) && void 0 !== e && e - , n = u["mediaQuery"] - , {desiredRate: s, isIframeRate: a} = n - , o = a && c.isStarted && s && s < 0 && s !== c.iframeRate; - (r || o) && (t.flushBeforeAppend = { - start: 0, - end: Number.POSITIVE_INFINITY - }) - } - )) : Bi(null))).pipe(ur(e=>function(g, e, t, i) { - const {rootPlaylistService: r, rootPlaylistQuery: n, mediaSink: s, mediaLibraryService: a, config: y} = e - , v = s.mediaQuery - , o = n.itemId - , d = v.isIframeRate; - let l = n.getInitPTS(t); - if (null == l || !d && l.iframeMode !== d) { - const c = null !== (e = null === (e = i[ul.Variant]) || void 0 === e ? void 0 : e[1].startDtsTs) && void 0 !== e ? e : null; - if (null == c) - return g.warn("updatePTSInfo: Variant data missing."), - null; - const n = null !== (e = null === (e = i[ul.Variant]) || void 0 === e ? void 0 : e[1].timelineOffset) && void 0 !== e ? e : 0 - , s = B(n, c.timescale) - , a = { - baseTime: c.baseTime - s.baseTime, - timescale: c.timescale - }; - r.setInitPTS(o, t, c, n, a, d), - l = { - variantDTS: c, - timelineOffset: n, - offsetTimestamp: a, - iframeMode: d - } - } - i.forEach(e=>{ - e && !ne(e[1].iframeMediaDuration) && a.updatePTSDTS(o, e[1].mediaOptionId, l, e[1]) - } - ); - const S = [null, null]; - if (i[ul.Variant]) { - const [g,c] = i[ul.Variant]; - let e = l.offsetTimestamp; - if (d) { - const g = c.startDtsTs - , i = B(c.timelineOffset, g.timescale); - e = { - baseTime: g.baseTime - i.baseTime, - timescale: g.timescale - } - } - S[cl.Variant] = { - initSeg: g, - dataSeg: c, - offsetTimestamp: e - } - } - if (i[ul.AltAudio]) { - const [g,c] = i[ul.AltAudio]; - S[cl.AltAudio] = { - initSeg: g, - dataSeg: c, - offsetTimestamp: l.offsetTimestamp - } - } - const u = S.map((e,t)=>{ - const i = null == e ? void 0 : e.dataSeg; - if (i) { - const {itemId: r, mediaOptionId: n, mediaSeqNum: s, discoSeqNum: a, startPts: o, endPts: d, duration: l, iframe: u} = i - , c = e["offsetTimestamp"] - , h = b(o, c) - , p = b(d, c) - , f = bg(i) - , m = S[0]; - return m && m.dataSeg.dropped || i.flushBeforeAppend || !((null === (e = null === (e = v.getBufferInfo(h, y.maxBufferHole)[t]) || void 0 === e ? void 0 : e.buffered) || void 0 === e ? void 0 : e.len) >= p - h) ? { - start: h, - duration: u ? l : p - h, - itemId: r, - mediaOptionId: n, - mediaSeqNum: s, - discoSeqNum: a, - targetDuration: f.mediaOptionDetails.targetduration - } : (g.warn(`${Cl[t]} Discarding append due to complete overlap with existing buffer`), - S[t] = null) - } - return null - } - ); - return u.every(e=>!e) ? null : { - appendDataTuple: S, - inFlightFrags: u, - initPTSInfo: l - } - }(i, n, r.discoSeqNum, e)), Ra(e=>{ - if (e) - return Bi(e); - { - const e = function(e, r) { - const n = e.enabledMediaOptionKeys - , s = [null, null] - , a = [null, null]; - return Ml.map(e=>{ - var t; - if (kl(n[e])) { - const i = bg(n[e]).mediaOptionDetailsEntity; - a[e] = null === (t = i.mediaOptionDetails) || void 0 === t ? void 0 : t.ptsKnown, - s[e] = { - detailsEntity: i, - switchContext: null === (e = r[e]) || void 0 === e ? void 0 : e.switchContext - } - } - } - ), - s - }(a, l); - return t(i, r, n, s, e) - } - } - )) - }(i, n, r, e, t)), Ql.tag("mediaProducerEpic.emit")) - } - ; - function oy(e, i, t, r) { - const {rootPlaylistQuery: n, mediaLibraryService: s} = t - , a = r[i]; - if (t.logger.child({ - name: Cl[i] - }), - !a || "Nah" === a.mediaOptionId) - return Bi({ - detailsEntity: null, - switchContext: null - }); - const o = s.getQueryForOption(a); - return Cr([Bi(e), o.mediaOptionDetailsEntity$.pipe(Es((e,t)=>(null == e ? void 0 : e.lastUpdateMillis) === (null == t ? void 0 : t.lastUpdateMillis)))]).pipe(an(([,e])=>{ - if (i === ul.AltAudio && !n.altMediaOptionHasValidUrl(i, a.mediaOptionId)) - return !0; - var t = null == e ? void 0 : e.mediaOptionDetails; - return null != t && (e = null !== (e = e.lastUpdateMillis) && void 0 !== e ? e : 0, - !t.liveOrEvent || !t.ptsKnown || !Kg(null == t ? void 0 : t.totalduration, 0, e)) - } - ), Cs(1), So(n.enabledMediaOptionSwitchContextsByType$(i)), ur(([[,e],t])=>({ - detailsEntity: e, - switchContext: t - }))) - } - const dy = t=>e=>{ - const {rootPlaylistQuery: g, rootPlaylistService: y, mediaSink: v, legibleSystemAdapter: o, statsService: d, rtcService: l} = t; - return e.pipe(Ql.tag("mediaConsumerEpic.in"), Ra(e=>{ - if (!e) - return Bi(!1); - const {appendDataTuple: r, inFlightFrags: m, initPTSInfo: t} = e - , i = t["offsetTimestamp"]; - return m.forEach((e,t)=>{ - e && y.updateInflightFrag(e.itemId, t, e, "appending", null) - } - ), - r.forEach(e=>{ - e && (e = e.dataSeg, - o.addLegibleSamples(i, e.captionData, e.id3Samples, e.endPts)) - } - ), - v.appendData(r, (e,t,i,r,n)=>{ - var s, a, o, d, l, u, c, h, p, f = null !== (f = m[t].targetDuration) && void 0 !== f ? f : 10; - return s = v, - a = e, - o = t, - d = i, - l = f, - u = r, - c = g, - h = y, - p = n, - e=>e.pipe(Ja(()=>{ - h.updateConsecutiveTimeouts(c.itemId, o, !1, "append") - } - ), ya(e=>e.pipe(Kr((e,t)=>{ - var i = e instanceof rf && e.isTimeout; - if (h.updateConsecutiveTimeouts(c.itemId, o, i, "append"), - i) - return function(e, t, i, r, n, s, a, o) { - let d = { - errorAction: Em.SendAlternateToPenaltyBox, - errorActionFlags: 0 - }; - var l = s.getCurrentWaterLevel(i.maxBufferHole) - , u = l < i.almostDryBufferSec; - let c = NaN; - s = i.appendErrorMaxRetry, - i = a.rootPlaylistEntity.errorsByType[r].timeouts.append; - u && s <= i || s <= t ? d.errorAction = Em.SendEndCallback : c = 1e3 * l; - s = { - retryDelayMs: c, - maxNumRetry: s, - maxRetryDelayMs: c - }; - return d = Vm(d, !1, e.response.code, n, r, a, o), - Qm(e, t, s, d, a, o, r, n).pipe() - }(e, t, u, o, d, p, c, h); - if (e instanceof nf) - return function(e, t, i, r, n, s, a, o, d, l) { - var u = t.type - , u = o.getCurrentWaterLevelByType(u, n.maxBufferHole); - if (u >= n.almostDryBufferSec) { - const t = 1e3 * r - , n = { - errorAction: Em.RetryRequest, - errorActionFlags: 0 - }; - return 1e3 * u < t && (l.hasFallbackMediaOptionTuple(d, s, a, !1) ? n.errorAction = Em.SendAlternateToPenaltyBox : n.errorAction = Em.SendEndCallback), - Qm(e, i, { - retryDelayMs: t, - maxNumRetry: 1 / 0, - maxRetryDelayMs: t - }, n, d, l, s, a) - } - return i < n.appendErrorMaxRetry ? t.remove(0, Number.POSITIVE_INFINITY) : (e.fatal = !0, - Ui(e)) - }(e, a, t, l, u, o, d, p, c, h); - if (e instanceof af) { - const {mediaOptionType: a, mediaOptionId: o} = e; - return Jg(e, a, o, s, h, c) - } - throw e - } - )))) - } - , g.highestVideoCodec).pipe(ur(e=>{ - m.forEach((e,t)=>{ - e && y.updateInflightFrag(e.itemId, t, e, "appended", null) - } - ); - var t = e.filter(e=>(null == e ? void 0 : e.fragmentType) === ul.Variant); - t.length && (d.setBufferMetric(t[0]), - null == l || l.handleFragBuffered(t[0])); - e = r[cl.AltAudio]; - if (null !== (t = null == e ? void 0 : e.dataSeg) && void 0 !== t && t.flushBeforeAppend || ne(null === (t = null == e ? void 0 : e.dataSeg) || void 0 === t ? void 0 : t.switchPosition)) { - const {itemId: i, mediaOptionId: r} = e.dataSeg; - y.setEnabledMediaOptionSwitchContextByType(i, ul.AltAudio, r, void 0) - } - return !0 - } - ), (n = v, - s = y, - a = g, - e=>e.pipe(Un(e=>{ - if (e instanceof tf) { - var {mediaOptionType: t, mediaOptionId: i} = e; - return Jg(e, t, i, n, s, a) - } - throw e - } - )))); - var n, s, a - } - )) - } - ; - function ly(e) { - const {logger: r, rootPlaylistService: n, rootPlaylistQuery: t} = e - , s = t.itemId; - return e=>e.pipe(ya(e=>e.pipe(Kr(e=>{ - if (r.error(`Got error in pipeline ${e.message} fatal:${null == e ? void 0 : e.fatal} handled:${null == e ? void 0 : e.handled}`), - !(e instanceof p) || e.fatal) - throw e; - return e.handled ? (t = n, - i = s, - vn(0).pipe(ur(()=>{ - t.updateEnabledMediaOptions(i) - } - ))) : Ti; - var t, i - } - )))) - } - const uy = ()=>e=>e.pipe(Ql.tag("mediaFragmentPipelineEpic.in"), Ra(i=>{ - if (!i) - return Ti; - const {logger: e, config: t, platformService: r, rootPlaylistService: n, rootPlaylistQuery: s, keySystemAdapter: a, mediaSink: o, mediaParser: d, gaplessInstance: l, mediaLibraryService: u} = i - , c = s["itemId"] - , h = o["mediaQuery"] - , p = a.keyStatusChange$.pipe((f = i, - e=>e.pipe(Ra(e=>{ - const {decryptdata: t, status: i, error: r} = e - , n = f["rootPlaylistQuery"]; - if ("needs-renewal" === i) - return Og(f, t, null); - if ("error" !== i || !(r instanceof uu || r instanceof lu) || r.handled) - return Ti; - { - const {rootPlaylistService: e, keySystemAdapter: t} = f; - return Xm(r, 0, null, e, n, t.ksQuery) - } - } - ), Ra(()=>Ti)))); - var f; - const m = r.getQuery() - , g = m.displaySupportsHdr$.pipe(Es(), Ra(e=>(n.setHDRPreference(c, e, !0), - Ti))) - , y = m.viewportInfo$.pipe(Es((e,t)=>e && t && e.width === t.width && e.height === t.height), Ja(e=>{ - t.useViewportSizeForLevelCap && n.setViewportInfo(c, e) - } - ), Ua(Ti)) - , v = Zd([s.hdrMode$.pipe(Es()), s.maxHdcpLevel$.pipe(Es())]).pipe(Ra(([])=>(l.inGaplessMode || 0 !== s.itemStartOffset || (o.resetMediaSource(), - d.reset()), - Ti))) - , S = nn(function(i) { - const {rootPlaylistQuery: t, mediaSink: r} = i - , e = t.enabledMediaOptions$.pipe(Up(), Ja(e=>{ - e = e[ul.AltAudio], - e = kl(e) && null != (null == e ? void 0 : e.url) ? 2 : 1; - r.setExpectedSbCount(e) - } - )) - , n = t.enabledMediaOptionByType$(ul.Variant).pipe(an(e=>kl(e)), Ra(e=>bg(e).mediaOptionDetails$), Cs(1), Ja(e=>{ - r.bufferMonitorTargetDuration = e.targetduration - } - )) - , s = Dl.map(e=>t.enabledMediaOptionByType$(e).pipe(Ql.tag("mediaOptionRetrieve.switch"), Ra(t=>{ - if (!t || !t.url || !kl(t)) - return Ti; - var e = r.mediaQuery.desiredRate$.pipe(ur(e=>0 !== e), Es()); - return Tg(i, t).pipe(Ql.tag("mediaOptionRetrieve.first"), Ua(e), Ra(e=>e ? function e(t, i) { - const r = t.mediaLibraryService; - return function(e) { - if (!e) - return Ti; - var {mediaOptionDetails: t, lastUpdateMillis: i, unchangedCount: e} = e; - if (null == t || !t.liveOrEvent) - return Ti; - if (hg(t, i)) - return vn(0).pipe(Ja(()=>{} - )); - let r = cg(t); - return 0 < e && (r /= 2, - r = Math.max(r, 5e3)), - r -= performance.now() - i, - r += 0, - r = Math.max(1e3, Math.round(r)), - vn(r).pipe(Ja(()=>{} - )) - }(r.getQueryForOption(i).mediaOptionDetailsEntity).pipe(Ra(()=>Tg(t, i, !0)), Ra(()=>e(t, i))) - }(i, t) : Ti)) - } - ))); - return nn(e, n, nn(...s)).pipe(Ua(Ti)) - }(i), sy(i), function(t) { - const {rootPlaylistQuery: i, mediaSink: e} = t; - return $l(e.mediaQuery.mediaElementEntity$, e=>!!e).pipe(Ra(e=>i.anchorTime$.pipe(Up(), Ql.tag("anchorTime.subtitle.in"), (s=>e=>{ - const {rootPlaylistQuery: i, rootPlaylistService: t, legibleSystemAdapter: r} = s - , n = i.enabledAlternateMediaOptionByType(ul.Subtitle); - if (r.gotTracks) - r.selectedTrack = n; - else { - const s = i.preferredMediaOptions[ul.Subtitle]; - r.setTracks(s, n, i.getDisabledMediaOption(ul.Subtitle)) - } - return e.pipe(Ql.tag("subtitleEpic.select.in"), Ra(()=>(r.anchorTimeChanged(), - nn(r.nativeSubtitleTrackChange$.pipe(Ra(e=>(e.mediaOptionId !== r.selectedMediaOption.mediaOptionId && t.setEnabledMediaOptionByType(e.itemId, ul.Subtitle, e), - Ti))), i.enabledMediaOptionByType$(ul.Subtitle).pipe(ur(e=>{ - const t = kl(e) ? i.alternateMediaOptionById(ul.Subtitle, e.mediaOptionId) : e; - return r.selectedMediaOption = t, - t - } - )).pipe(Es((e,t)=>(null == e ? void 0 : e.mediaOptionId) === (null == t ? void 0 : t.mediaOptionId)))))), Ql.tag("subtitleEpic.select.emit")) - } - )(t), (s=>e=>{ - const {mediaSink: t, rootPlaylistQuery: i, legibleSystemAdapter: r, logger: n} = s; - return e.pipe(Ql.tag("subtitleEpic.process.in"), Ra(e=>{ - if (!e || !e.url || !kl(e)) - return Bi([null, null, null]); - return Zd([bg(e).mediaOptionDetails$, i.discoSeqNum$.pipe(an(e=>ne(e)))]).pipe(Ra(([e,t])=>((i,r,e)=>{ - const {legibleSystemAdapter: n, rootPlaylistQuery: t} = i; - return t.initPTS$(e).pipe(Ra(t=>t ? n.findFrags$(r, e).pipe(Ra(e=>r && (null == e ? void 0 : e.foundFrags) ? cy(i, t.offsetTimestamp, e, r) : Ul)) : sn)) - } - )(s, e, t))) - } - ), Ql.tag("subtitleEpic.process.emit")) - } - )(t)))) - }(i), p).pipe(Js(void 0), ly(i)) - , b = h.seekTo$.pipe(ur(e=>null == e ? void 0 : e.pos), an(e=>ne(e)), Es((e,t)=>Math.abs(e - t) < Number.EPSILON), Ra(e=>(n.setAnchorTime(c, e), - Ti))) - , T = h.gotPlaying$.pipe(an(e=>e), Ja(e=>{ - s.mediaOptionListQueries[ul.Variant].filteredMediaOptionList.forEach(e=>{} - ) - } - ), Cs(1), Ua(Ti)); - return nn(s.pendingSeek$.pipe(ty(t, e, o, n, s, u)), function() { - const {config: s, mediaSink: a, rootPlaylistQuery: e, mediaLibraryService: t} = i - , o = i.logger.child({ - name: "live" - }) - , d = a.mediaQuery; - return e.enabledMediaOptionByType$(ul.Variant).pipe(an(kl), Ra(e=>t.getQueryForOption(e).mediaOptionDetailsEntity$.pipe(an(e=>{ - var t; - return (null === (t = null == e ? void 0 : e.mediaOptionDetails) || void 0 === t ? void 0 : t.ptsKnown) && e.mediaOptionDetails.liveOrEvent - } - ), Es((e,t)=>(null == e ? void 0 : e.lastUpdateMillis) === (null == t ? void 0 : t.lastUpdateMillis)))), ur(e=>{ - var t = e.mediaOptionDetails - , i = d.currentTime - , r = d.msDuration; - let n = NaN; - return i < ug(i, t, e.lastUpdateMillis, s.maxBufferHole, d) && (n = lg(t.fragments[0].start, t, s), - n >= r && (o.warn(`seekTo position > duration, updating ${a.msDuration}->${e.playlistDuration}`), - a.msDuration = e.playlistDuration), - a.seekTo = n), - n - } - )) - }(), b, S, g, y, v, function() { - const e = i.mediaSink.mediaQuery; - return Cr([Bi(i), e.desiredRate$.pipe(ca())]).pipe(Ra(([e,[t,i]])=>{ - const {rootPlaylistQuery: s, rootPlaylistService: r, config: a, mediaSink: n, mediaLibraryService: o, statsService: d} = e - , l = n.mediaQuery; - if (jp(t) !== jp(i)) - Gg(wm.IframeModeChange, a, s, l, r); - else if (0 === t && 1 === i && !Ml.every(e=>{ - const t = s.enabledMediaOptionKeys[e] - , i = o.getQueryForOption(t) - , r = d.getQueryForItem(s.itemId) - , n = i.mediaOptionDetailsEntity; - return !(null !== (e = null == n ? void 0 : n.mediaOptionDetails) && void 0 !== e && e.ptsKnown) || l.canContinuePlaybackWithoutGap(n.mediaOptionDetails, n.lastUpdateMillis, r.getPlaylistEstimate(), a.maxBufferHole) - } - )) - return n.pause(), - n.flushAll(0, 1 / 0, !0); - return Ti - } - ), Ua(Ti)) - }(), function(e) { - const s = e.rootPlaylistQuery - , t = e.mediaSink.mediaQuery - , i = s.enabledMediaOptionByType$(ul.Variant); - return Cr([Bi(e), t.desiredRate$.pipe(ca()), i]).pipe(Es((e,t)=>e[1] === t[1]), Ra(([e,[t,i],r])=>{ - t = jp(t), - i = jp(i); - if (t === i) - return Ti; - const n = e["rootPlaylistService"]; - return i ? e.rootPlaylistQuery.nextMaxAutoOptionId === Ol.mediaOptionId && n.setNextMaxAutoOptionId(e.rootPlaylistQuery.itemId, r.mediaOptionId) : n.setNextMaxAutoOptionId(s.itemId, Ol.mediaOptionId), - Ti - } - )) - }(i), T).pipe(Ql.tag("mediaFragmentPiplineEpic.emit"), Js(void 0)) - } - )) - , cy = (r,e,t,i)=>{ - const n = r.legibleSystemAdapter - , s = t.foundFrags; - return Lr(s).pipe(ur(t=>{ - return ((e,t,i)=>{ - const {rootPlaylistQuery: r, legibleSystemAdapter: n} = e; - return Yr(()=>((t,i)=>wg(e, i, !1, !1).pipe(ur(e=>({ - initPTS: t, - data: e, - mediaFragment: i - })), Ql.tag("retrieveSubtitleFragmentCacheEntity.emit")))(t, i).pipe(ur(({initPTS: e, data: t, mediaFragment: i})=>({ - frag: i, - cueRange: function(e, t, i, r, n) { - if (e) - return n.processSubtitleFrag(e, t, i, r) - }(r.enabledAlternateMediaOptionByType(ul.Subtitle), i, e, t, n) - })))) - } - )(r, e, t).pipe((i = e=>n.checkReadyToLoadNextSubtitleFragment$(t, s).pipe(an(e=>e)), - function(e) { - return e.lift(new ms(i)) - } - )); - var i - } - ), Wr(r.config.vttConcurrentLoadCount), Ja(e=>{ - n.reviewParsedFrag(e, t, i) !== Ap.CloseEnough && r.legibleSystemAdapter.tryAgain$.next(!0) - } - )) - } - , hy = (e,t)=>{ - let i, r = ""; - return i = e.videoCodec && e.audioCodec ? (r = `${e.videoCodec}, ${e.audioCodec}`, - t = null != t ? t : "video/mp4", - "audiovideo") : e.videoCodec ? (r = `${e.videoCodec}`, - t = null != t ? t : "video/mp4", - "video") : (r = `${null !== (e = e.audioCodec) && void 0 !== e ? e : ""}`, - t = null != t ? t : "audio/mp4", - "audio"), - { - mimeType: `${t};codecs=${r}`, - codec: r, - container: t, - type: i - } - } - ; - class py { - constructor(e, t, i) { - this.config = e, - this.logger = t, - this.demuxClient = i, - this.typeSupported = { - mp4: MediaSource.isTypeSupported("video/mp4"), - mpeg: MediaSource.isTypeSupported("audio/mpeg"), - mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'), - ac3: MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"'), - ec3: MediaSource.isTypeSupported('audio/mp4; codecs="ec-3"') - }, - this.demuxers = [], - this.lastInitFrags = [], - this.lastFrags = [] - } - parseInitSegment(h, e) { - return this.getDemuxerInfo(h, this.lastInitFrags, e, this.demuxClient).pipe(Ra(({demuxer: e, contiguous: t, trackSwitch: i, discontinuity: r, accurateTimeOffset: n})=>{ - const s = h["frag"] - , {keyTagInfo: a, start: o, mediaOptionType: d} = s; - if (this.lastInitFrags[d] = s, - h.initSegment) { - const e = We.remuxInitSegment(new Uint8Array(h.initSegment), this.logger, a) - , t = Je.parseInitSegment(e) - , {mimeType: i, type: r, codec: n, container: s} = hy(t); - return Bi({ - moovData: t, - mimeType: i, - track: { - type: r, - codec: n, - initSegment: e, - container: s - } - }) - } - const l = h.segment || h.initSegment - , u = l ? h.initSegment : void 0 - , c = wc(e.observer); - return Bi(c.event(v.FRAG_PARSING_INIT_SEGMENT).pipe(ur(this.handleInitSegmentData)), c.event(P.INTERNAL_ERROR).pipe(Ra(this.handleError)), e.pushWithoutTransfer(l, a, u, o, r, i, t, h.totalDuration, n, void 0, h.iframeMediaStart, h.iframeDuration).pipe(Ua(Ti))).pipe(Wr(), Cs(1)) - } - )) - } - parseSegment(y, e) { - return this.getDemuxerInfo(y, this.lastFrags, e, this.demuxClient).pipe(Ra(({demuxer: e, contiguous: t, trackSwitch: i, discontinuity: r, accurateTimeOffset: n})=>{ - const {frag: h, defaultInitPTS: p} = y - , {keyTagInfo: s, start: a, duration: f, mediaOptionType: m} = h; - let g; - this.lastFrags[m] = h; - const o = wc(e.observer); - return Bi(o.event(v.FRAG_PARSING_INIT_SEGMENT).pipe(Ra(e=>{ - var t; - return e.track.initSegment.byteLength !== (null === (t = y.initSegment) || void 0 === t ? void 0 : t.byteLength) && (g = this.handleInitSegmentData(e)), - Ti - } - )), o.event(v.FRAG_PARSING_DATA).pipe(ur(e=>{ - var {startPTS: t, startDTS: i, firstKeyframePts: r, framesWithoutIDR: n, dropped: s, data1: a, data2: o, captionData: d, id3Samples: l} = e; - let {endPTS: u, endDTS: c} = e; - return null == u && (this.logger.warn(`${Cl[m]} ${Bp(h)}: null endPTS parsed, using duration ${f}`), - u = Object.assign(Object.assign({}, t), { - baseTime: t.baseTime + B(f, t.timescale).baseTime - })), - null == c && (this.logger.warn(`${Cl[m]} ${Bp(h)}: null endDTS parsed, using duration ${f}`), - c = Object.assign(Object.assign({}, i), { - baseTime: i.baseTime + B(f, i.timescale).baseTime - })), - ne(y.iframeMediaStart) || function(e, t, i, r) { - let n = NaN - , s = NaN; - if (ne(i)) - s = i, - n = .01, - isFinite(s) && isFinite(r) && (s += r); - else { - { - const o = void 0 - } - } - var {startPTS: a, startDTS: i, endPTS: r, endDTS: t} = t; - if (!(0 <= a.baseTime && 0 <= i.baseTime && 0 < e.duration && (null == r || 0 < b(r, a)) && (null == t || 0 < b(t, i)) && (!ne(n) || !ne(s) || Math.abs(S(i) - s) <= n))) - throw new D(!1,`Failed demuxer sanity check frag=${Bp(e)} parsed=${JSON.stringify({ - startPTS: a, - endPTS: r, - startDTS: i, - endDTS: t - })} ${se({ - expectedStartDTS: s, - fudge: n - })}`,$.FailedDemuxerSanityCheck) - }(h, e, (p, - y.iframeMediaStart), this.config.audioPrimingDelay), - { - startPTS: t, - endPTS: u, - startDTS: i, - endDTS: c, - firstKeyframePts: r, - framesWithoutIDR: n, - dropped: s, - data1: a, - data2: o, - captionData: d, - id3Samples: l, - parsedInitSegment: g - } - } - )), o.event(P.INTERNAL_ERROR).pipe(Ra(this.handleError)), e.push(y.segment, s, y.initSegment, a, r, i, t, y.totalDuration, n, p, y.iframeMediaStart, y.iframeDuration).pipe(Ua(Ti))).pipe(Wr(), Cs(1)) - } - )) - } - reset(e) { - if (null == e) - return this.demuxers.forEach(e=>{ - e && e.destroy() - } - ), - void (this.demuxers = []); - const t = this.demuxers[e]; - null == t || t.destroy(), - this.demuxers[e] = null - } - destroy(e) { - null != e ? this.reset(e) : this.reset() - } - willBeTrackSwitch(e, t) { - var {mediaOptionType: i, mediaOptionId: e} = e - , i = (t || this.lastFrags)[i]; - return !(i && i.mediaOptionId === e) - } - getDemuxerInfo(e, r, t, i) { - const {frag: n, ptsKnown: s, seeking: a, live: o} = e - , {discoSeqNum: d, mediaSeqNum: l, mediaOptionType: u} = n; - return Yr(()=>{ - var e = this.demuxers[u]; - return e ? Bi(e) : i.init(this.typeSupported, this.config, t).pipe(Ja(e=>this.demuxers[u] = e)) - } - ).pipe(ur(e=>{ - var t = r[u] - , i = this.willBeTrackSwitch(n, r); - return { - demuxer: e, - trackSwitch: i, - discontinuity: !(t && d === t.discoSeqNum), - contiguous: !!t && !i && t.mediaSeqNum + 1 === l, - accurateTimeOffset: !a && (s || !o) - } - } - )) - } - handleInitSegmentData(e) { - var t = e["track"] - , i = t["initSegment"] - , r = Je.parseInitSegment(i) - , {mimeType: n, type: s, codec: a, container: e} = hy(r, t.container); - return { - moovData: r, - mimeType: n, - track: Object.assign(Object.assign({}, t), { - type: s, - codec: a, - initSegment: i, - container: e - }) - } - } - handleError(e) { - return Ui(e) - } - } - function fy(e) { - return Math.min(e.targetduration, 15) - } - function my(e, t, i, r) { - if (200 === t && r && 10 < r.length) { - if (Om.isValidPlaylist(r)) - return !0; - { - const t = new R(o,_,!0,"response doesnt have #EXTM3U tag",$.PlaylistErrorMissingEXTM3U); - throw t.url = e, - t - } - } - return !1 - } - const gy = { - name: "pltfrm" - }; - function yy(e, t) { - t = Ih.getKeySystemSecurityLevel(t); - return null != e && void 0 !== t[e] - } - function vy(e) { - return e.every(e=>e.iframes) - } - function Sy(e, t) { - return !ne(e) || !ne(t) || e <= t - } - function by() { - const n = new Set - , s = new Set; - return e=>{ - const i = (e,t)=>{ - t = t ? "audio" : "video"; - n.has(e) || s.has(e) || (((e,t)=>{ - let i = MediaSource.isTypeSupported(`${e}/mp4;codecs=${t}`); - return "mp4a.40.34" !== t || i || (i = MediaSource.isTypeSupported(`${e}/mpeg`)), - i - } - )(t, e) ? n : s).add(e) - } - , t = (e,t)=>(i(e, t), - s.has(e)); - let r = !1; - return e.audioCodecList && (r = e.audioCodecList.some(e=>t(e, !0))), - !r && e.videoCodecList && (r = e.videoCodecList.some(e=>t(e, !1))), - !r - } - } - function Ty(e, t) { - for (const i in e) - if (e[i].type === t) - return e[i]; - return {} - } - function Ey(e, t, i) { - t.filter(e=>!i.includes(e)).map(e=>e.mediaOptionId) - } - function Iy(e, i, s) { - const a = new Map - , r = new Array; - return e.forEach(t=>{ - var e = Array(); - !function(e, t, i) { - var r = qc.getCapabilities(t.videoCodecList, t.audioCodecList) - , t = JSON.stringify(r); - let n; - a.has(t) ? n = a.get(t) : (n = Ih.requestKeySystemAccess(e, r, void 0, s).pipe(ur(()=>!0), Un(e=>(s.warn(`Request key system error: ${e.message}`), - Bi(!1))), Aa({ - bufferSize: 1, - refCount: !0 - })), - a.set(t, n)), - i.push(n) - }(i, t, e); - e = Jr(e).pipe(ur(e=>{ - if (void 0 === e.find(e=>!1 === e)) - return t - } - )); - r.push(e) - } - ), - Jr(r).pipe(ur(e=>e.filter(e=>Boolean(e)))) - } - function wy(e, r) { - const o = new Set - , d = new Set - , l = !MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.2"; channels="-1"') - , u = l && !MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.2"; channels="2"; features="INVALID"') - , t = e.filter(e=>{ - let t = !1; - var i; - return e.audioCodecList && e.audioGroupId && (i = dm.getRichestChannelLayoutForGroupId(e.audioGroupId, r), - 0 < e.audioCodecList.length && i && (t = ((e,t)=>{ - var i, r, n, s = Se.isDolbyAtmos(e, t); - if (u || l && !s) { - n = `${i = e}/${r = t}`, - o.has(n) || d.has(n) || (((e,t)=>{ - const i = t.split("/") - , r = parseInt(i[0]); - let n, s; - if (1 < i.length) { - const t = i[1].split(",")[0]; - n = `audio/mp4;codecs="${e}";channels="${r}";features="${t}"`, - s = `audio/mp4;codecs="${e}";channels="8";features="${t}"` - } else - n = `audio/mp4;codecs="${e}";channels="${r}"`; - let a = MediaSource.isTypeSupported(n); - return !a && s && (a = MediaSource.isTypeSupported(s)), - a - } - )(i, r) ? o : d).add(n); - const a = `${e}/${t}`; - return d.has(a) - } - return !!s - } - )(dm.getRichestAudioCodec(e.audioCodecList), i))), - !t - } + statsStore.statsEntity = statsEntity; + return statsQuery; + }), + finalize(() => { + statsStore.setLoading(false); + }) ); - return Ey(0, e, t), - t - } - function Ay(e, t, d) { - const n = 0 < (null == t ? void 0 : t.length) - , i = e.filter(o=>{ - var e = function() { - if (!d) - return { - highestPlayableAverageBitRate: void 0, - highestPlayablePeakBitRate: void 0, - highestPlayableWidth: void 0, - highestPlayableHeight: void 0, - highestPlayableFrameRate: void 0 - }; - const e = o.videoCodec - , t = o.videoRange - , i = d.videoDynamicRangeFormats - , r = d.videoCodecs - , n = Se.getDynamicRangeType(t, e) - , s = Se.getCompressionType(e) - , a = function(e, t, i, r) { - if (!r && !i) - return {}; - var n, s, t = i ? Ty(i, t) : {}, r = r ? Ty(r, e) : {}; - let a, o; - return o = e === pe.SDR ? (a = t, - r) : (a = r, - t), - n = Object.assign({}, a), - s = o, - Object.keys(s).forEach(e=>{ - n[e] || (n[e] = s[e]) - } - ), - n - }(n, s, r, i); - return s !== fe.VP09 && (a.highestPlayablePeakBitRateForClearContent = void 0), - a - }() - , t = e["highestPlayablePeakBitRateForClearContent"] - , i = o.allowedCPCMap || n - , r = Sy(o.bandwidth, e.highestPlayablePeakBitRate); - return (i || !t ? r : r || Sy(o.bandwidth, t)) && Sy(o.avgBandwidth, e.highestPlayableAverageBitRate) && Sy(o.width, e.highestPlayableWidth) && Sy(o.height, e.highestPlayableHeight) && Sy(o.frameRate, e.highestPlayableFrameRate) - } - ); - return Ey(0, e, i), - i - } - function Oy(e, a, o, d, l, u) { - var r = (null == d ? void 0 : d.maxHdcpLevel) || void 0; - let c = [...e]; - (0 < l.disableVideoCodecList.size || 0 < l.disableAudioCodecList.size) && (c = function(e, t, i) { - let r = e.filter(e=>!e.videoCodec || e.videoCodecList.every(e=>{ - e = $p(e); - return !t.has(e) - } - )); - return r = r.filter(e=>!(!e.iframes && e.audioCodec) || e.audioCodecList.every(e=>{ - e = Kp(e); - return !i.has(e) - } - )), - Ey(0, e, r), - r - }(c, l.disableVideoCodecList, l.disableAudioCodecList)), - r && rm(r) && (c = function(e) { - const t = nm(r) - , i = e.filter(e=>{ - e = e.hdcpLevel; - return !e || nm(e) <= t - } - ); - return Ey(0, e, i), - i - }(c)); - var t = null == d ? void 0 : d.maxSecurityLevel - , e = null == l ? void 0 : l.keySystemPreference; - t && e && yy(t, e) && (c = function(e, t, i) { - function r(e) { - return yy(e, i) ? n[e] : -1 - } - const n = Ih.getKeySystemSecurityLevel(i) - , s = Ih.getKeySystemFormat(i) - , a = r(t) - , o = e.filter(e=>{ - e = null !== (e = null === (e = e.allowedCPCMap) || void 0 === e ? void 0 : e[s]) && void 0 !== e ? e : []; - let t = !0; - for (const i of e) - if (t = r(i) <= a, - !t) - break; - return t - } - ); - return Ey(0, e, o), - [...o] - }(c, t, e)), - c = c.map(t=>{ - var e; - return t.audioCodecList && t.audioGroupId && ((e = null == (e = a.find(e=>e.groupId === t.audioGroupId)) ? void 0 : e.channels) && (t.audioChannelCount = parseInt(e))), - t - } - ); - const h = !(null == l || !l.useMediaKeySystemAccessFilter) && e && navigator && "function" == typeof navigator.requestMediaKeySystemAccess; - return (h ? Iy(c, e, u) : Bi(c)).pipe(Ra(e=>{ - if (0 === e.length || vy(e)) - throw new R(L,f,void 0,"no media option with compatible codecs found in playlist",void 0); - h && Ey(0, c, e); - const t = navigator && navigator.mediaCapabilities - , n = !(null == l || !l.useMediaCapabilities) && t && "function" == typeof t.decodingInfo; - let i; - return i = n ? function(e, n, s) { - const a = [] - , o = by() - , d = function(o) { - const d = new Map - , l = navigator && navigator.mediaCapabilities; - return (i,e,t,n,r)=>{ - const s = { - type: "media-source" - }; - n ? s.video = function(e) { - const t = { - contentType: `video/mp4;codecs=${e}`, - width: i.width, - height: i.height, - bitrate: i.bandwidth || i.avgBandwidth, - framerate: i.iframes ? 8 : i.frameRate - }; - if (i.videoRange) - switch (i.videoRange) { - case "PQ": - Se.isDolby(e) ? (t.hdrMetadataType = Am.DoVi, - t.colorGamut = "rec2020") : (Se.isHEVC(e) || Se.isVP09(e)) && (t.hdrMetadataType = Am.HDR10, - t.colorGamut = "rec2020"), - t.transferFunction = "pq"; - break; - case "HLG": - t.colorGamut = "rec2020", - t.transferFunction = "hlg" - } - return t - }(t) : s.audio = function(e, t, i) { - const r = { - contentType: `audio/mp4;codecs=${e}` - } - , n = dm.getRichestChannelLayoutForGroupId(t.audioGroupId, i); - return n && (r.channels = Se.getChannelCount(n).toString(), - r.spatialRendering = Se.isDolbyAtmos(e, n)), - r - }(t, i, e); - e = JSON.stringify(s); - let a; - return d.has(e) ? a = d.get(e) : (a = Lr(l.decodingInfo(s)).pipe(ur(e=>{ - const t = e.configuration || e.supportedConfiguration - , i = t instanceof Object && (!s.video || null == Object.keys(s.video).find(e=>!(e in t.video))) && (!s.audio || null == Object.keys(s.audio).find(e=>!(e in t.audio))) - , r = e.supported && (!n || e.powerEfficient) && i; - return r || o.warn(gy, `Unsupported config ${e.supported}/${e.powerEfficient}/${i} ${JSON.stringify(s)} supportedConfig=${JSON.stringify(t)}`), - r - } - )), - d.set(e, a)), - [...r, a] - } - }(s); - return e.forEach(t=>{ - var e; - let i = []; - if (null === (e = t.videoCodecList) || void 0 === e || e.forEach(e=>{ - i = d(t, n, e, !0, i) - } - ), - 0 < (null === (e = t.audioCodecList) || void 0 === e ? void 0 : e.length)) { - const s = dm.getRichestAudioCodec(t.audioCodecList); - i = d(t, n, s, !1, i) - } - let r = Bi(t); - 0 < i.length && (r = Jr(i).pipe(ur(e=>null == e.find(e=>!1 === e) ? t : null), Un(e=>(s.warn(gy, `decodingInfo errror: ${e.message}`), - Bi(o(t) ? t : null))))), - a.push(r) - } - ), - Jr(a).pipe(ur(e=>e.filter(e=>Boolean(e)))) - }(e, a, u) : Bi(e = wy((r = e, - s = by(), - s = r.filter(s), - Ey(0, r, s), - e = s), a)), - i.pipe(ur(e=>{ - if (0 === e.length || vy(e)) - throw new R(L,f,void 0,"no media option with compatible codecs found in manifest",void 0); - if (0 === (t = e = Ay(e, o, d), - r = t.filter(e=>!e.iframes || !e.width || !e.height || e.width * e.height <= 2488320), - Ey(0, t, r), - (e = r).length) || vy(e)) - throw new R(L,f,void 0,"no media option with compatible codecs found in manifest",void 0); - var t; - let i = (null == d ? void 0 : d.videoDynamicRangeFormats) || []; - n && 0 === i.length && (i = [{ - type: pe.SDR - }, { - type: pe.HDR - }, { - type: pe.HDR10 - }, { - type: pe.DolbyVision - }, { - type: pe.HLG - }]); - var {hdrMediaOptions: r, sdrMediaOptions: e} = function(e, t) { - const i = t.reduce((e,t)=>{ - switch (t.type) { - case pe.DolbyVision: - e.doViSupported = !0; - break; - case pe.HDR10: - e.hdr10Supported = !0; - break; - case pe.HLG: - e.hlgSupported = !0 - } - return e - } - , { - doViSupported: !1, - hdr10Supported: !1, - hlgSupported: !1 - }) - , {doViSupported: r, hdr10Supported: n, hlgSupported: s} = i; - return e.reduce((e,t)=>{ - var i; - switch (Se.getDynamicRangeType(t.videoRange, null !== (i = t.videoCodec) && void 0 !== i ? i : "")) { - case pe.HDR: - case pe.HDR10: - n && e.hdrMediaOptions.push(t); - break; - case pe.DolbyVision: - r && e.hdrMediaOptions.push(t); - break; - case pe.HLG: - s && e.hdrMediaOptions.push(t); - break; - default: - "SDR" !== t.videoRange && null != t.videoRange || e.sdrMediaOptions.push(t) - } - return e - } - , { - hdrMediaOptions: new Array, - sdrMediaOptions: new Array - }) - }(e, i); - if (0 === r.length && 0 === e.length || vy(r) && vy(e)) - throw new R(L,"manifestIncompatibleVideoRangeError",void 0,"mediaOption with compatible VIDEO-RANGE not found in manifest",void 0); - return { - hdrMediaOptions: r, - sdrMediaOptions: e - } - } - ), Un(e=>{ - throw e instanceof R && (e.fatal = !0, - e.response = $.IncompatibleAsset), - e - } - )); - var r, s - } - )) - } - function ky(e, t) { - return t.mediaOptionId !== e.mediaOptionId && t.persistentID === e.persistentID && t.groupId !== e.groupId - } - (w = Am = Am || {}).HDR10 = "smpteSt2086", - w.DoVi = "smpteSt2094-10", - w.HDR10Plus = "smpteSt2094-40"; - class Cy extends Lm { - constructor(e, t, i) { - super(e, t, i) - } - static makeFilters() { - return Rm() - } - _initFilters() { - return Cy.kAllowFilters - } - get _mediaOptionType() { - return this.mediaOptionType - } - get preferredHost() { - return null - } - get preferredHost$() { - return Bi(null) - } - get mediaOptionListInfo() { - var e; - return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.mediaOptionListTuple[this._mediaOptionType]) && void 0 !== e ? e : null - } - get mediaOptionListInfo$() { - return this.selectEntity(this.itemId, e=>e && e.mediaOptionListTuple ? e.mediaOptionListTuple[this._mediaOptionType] : null).pipe(Up()) - } - getFallbackVariant(t, e, i, r) { - var n; - const s = null === (n = this.mediaOptionList) || void 0 === n ? void 0 : n.find(e=>e.mediaOptionId === t); - if (!s) - return null; - const a = this.filteredMediaOptionList; - if (!a) - return null; - const o = gl(s.url); - if (i) - return null !== (i = a.find(e=>ky(s, e) && !yl(o, e.url))) && void 0 !== i ? i : null; - let d = null; - for (const t of a) - !ky(s, t) || d && !yl(o, t.url) || (d = t); - return d - } - getMatchingAlternateWithPersistentId(t, i, r) { - var e; - return null !== (e = this.preferredMediaOptionList.find(e=>!(0 < (null == r ? void 0 : r.length) && r.includes(e.mediaOptionId)) && (!ne(t) || e.persistentID === t) && (!i || this.matchGroup(e, i.audioGroupId, i.subtitleGroupId, i.closedcaption)))) && void 0 !== e ? e : null - } - matchGroup(e, t, i, r) { - let n = !1; - switch (e.type) { - case "CLOSED-CAPTIONS": - n = !r || e.groupId === r; - break; - case "SUBTITLES": - n = !i || e.groupId === i; - break; - case "AUDIO": - n = !t || e.groupId === t - } - return n - } - getMatchingAlternate(e, t) { - e = this.mediaOptionFromId(e); - return this.getMatchingAlternateWithPersistentId(null == e ? void 0 : e.persistentID, t, []) - } - packageAlternateMediaOption(e, t, i) { - return t.mediaType === pl.CLOSEDCAPTION ? this.augmentClosedCaptionsWithForcedSubtitles(null == e ? void 0 : e.subtitleGroupId, t, i) : t - } - augmentClosedCaptionsWithForcedSubtitles(e, t, i) { - i = this.pairForcedSubtitleMediaOptionWithClosedCaption(e, t, i); - return i ? Object.assign(Object.assign({}, t), { - url: i.url, - backingMediaOptionId: i.mediaOptionId - }) : t - } - pairForcedSubtitleMediaOptionWithClosedCaption(t, i, r) { - let n; - if (i && i.mediaType === pl.CLOSEDCAPTION) { - let e = this.mediaOptionList; - r && (e = this.preferredMediaOptionList), - n = Cy.pairForcedSubtitleMediaOptionWithClosedCaptionInList(t, i, e) - } - return n - } - static pairForcedSubtitleMediaOptionWithClosedCaptionInList(t, i, e) { - return e.find(function(e) { - return e.mediaType === pl.SUBTITLE && e.lang === i.lang && e.forced && e.autoselect && (!t || e.groupId === t) - }) - } - } - Cy.kAllowFilters = Cy.makeFilters(); - class Dy extends Od { - constructor(e, t) { - super(e), - this.itemId = t, - this.mediaOptionListQueries = [new Um(e,this.itemId), new Cy(e,this.itemId,ul.AltAudio), new Cy(e,this.itemId,ul.Subtitle)] - } - get rootPlaylistEntity() { - return this.getEntity(this.itemId) - } - get rootMediaOptionsTuple() { - var e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.mediaOptionListTuple; - return e ? [e[0].mediaOptions, e[1].mediaOptions, e[2].mediaOptions] : [[], [], []] - } - get itemStartOffset() { - var e, t; - return null !== (e = this.rootPlaylistEntity) && void 0 !== e && e.itemStartOffset && ne(null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.itemStartOffset) ? null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.itemStartOffset : 0 - } - get highestVideoCodec() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.highestVideoCodec - } - get baseUrl() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.baseUrl - } - get anchorTime() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.anchorTime - } - get discoSeqNum() { - var e; - return null !== (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.discoSeqNum) && void 0 !== e ? e : NaN - } - get discoSeqNum$() { - return this.selectEntity(this.itemId, "discoSeqNum") - } - get audioMediaSelectionGroup() { - var e; - return null !== (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.audioMediaSelectionGroup) && void 0 !== e ? e : null - } - get subtitleMediaSelectionGroup() { - var e; - return null !== (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.subtitleMediaSelectionGroup) && void 0 !== e ? e : null - } - get audioMediaSelectionOptions() { - var e; - return null !== (e = null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.audioMediaSelectionGroup) || void 0 === e ? void 0 : e.MediaSelectionGroupOptions) && void 0 !== e ? e : [] - } - get subtitleMediaSelectionOptions() { - var e; - return null !== (e = null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.subtitleMediaSelectionGroup) || void 0 === e ? void 0 : e.MediaSelectionGroupOptions) && void 0 !== e ? e : [] - } - get contentSteeringOption() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.contentSteeringOption - } - get masterVariableList() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.masterVariableList - } - get loadStats() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.loadStats - } - get isMediaPlaylist() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.isMediaPlaylist - } - getInitPTS(e) { - var t; - return null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.initPtsRecord[e] - } - get abrStatus$() { - return this.selectEntity(this.itemId, e=>null == e ? void 0 : e.abrStatus) - } - get abrStatus() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.abrStatus - } - get nextMaxAutoOptionId() { - var e; - return null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.abrStatus) || void 0 === e ? void 0 : e.nextMaxAutoOptionId - } - get nextMinAutoOptionId() { - var e; - return null === (e = null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.abrStatus) || void 0 === e ? void 0 : e.nextMinAutoOptionId - } - initPTS$(t) { - return this.selectEntity(this.itemId, ({initPtsRecord: e})=>e[t]) - } - get rootPlaylistEntity$() { - return this.selectEntity(this.itemId).pipe(an(e=>Boolean(e)), ur(e=>e)) - } - get rootPlaylistEntityAdded$() { - return this.selectEntityAction(To.Add).pipe(ur(e=>e.map(e=>this.getEntity(e)))) - } - get rootMediaOptionsTuple$() { - return Zd([this.selectEntity(this.itemId, e=>e.mediaOptionListTuple[0].mediaOptions), this.selectEntity(this.itemId, e=>e.mediaOptionListTuple[1].mediaOptions), this.selectEntity(this.itemId, e=>e.mediaOptionListTuple[2].mediaOptions)]) - } - get sessionData() { - var e; - return null === (e = this.rootPlaylistEntity) || void 0 === e ? void 0 : e.sessionData - } - get sessionData$() { - return this.selectEntity(this.itemId, ({sessionData: e})=>e).pipe(Up()) - } - get anchorTime$() { - return this.selectEntity(this.itemId, "anchorTime").pipe(Ra(e=>ne(e) ? e !== this.anchorTime ? (qe().warn(`anchorTime doesn't match stored value! ${e} !== ${this.anchorTime}`), - Ti) : Bi(e) : Ti)) - } - get pendingSeek$() { - return this.selectEntity(this.itemId, ({pendingSeek: e})=>e).pipe(Es((e,t)=>e === t || "number" == typeof e && "number" == typeof t && isNaN(e) && isNaN(t))) - } - get enabledMediaOptionKeys$() { - return this.selectEntity(this.itemId, "enabledMediaOptionKeys").pipe(an(e=>Boolean(e))) - } - get enabledMediaOptionKeys() { - var e; - return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.enabledMediaOptionKeys) && void 0 !== e ? e : [Ol, Ol, Ol] - } - get enabledMediaOptionSwitchContexts() { - var e; - return null !== (e = null === (e = this.getEntity(this.itemId)) || void 0 === e ? void 0 : e.mediaOptionSwitchContexts) && void 0 !== e ? e : [null, null, null] - } - enabledMediaOptionSwitchContextsByType$(t) { - return this.selectEntity(this.itemId, "mediaOptionSwitchContexts").pipe(ur(e=>null == e ? void 0 : e[t])) - } - get enabledMediaOptions$() { - return Zd([this.enabledMediaOptionByType$(ul.Variant), this.enabledMediaOptionByType$(ul.AltAudio), this.enabledMediaOptionByType$(ul.Subtitle)]) - } - get enabledAVOptions$() { - return Zd([this.enabledMediaOptionByType$(ul.Variant), this.enabledMediaOptionByType$(ul.AltAudio)]) - } - rawEnabledMediaOptionByType$(t) { - return this.enabledMediaOptionKeys$.pipe(ur(e=>{ - const i = e[t]; - return kl(i) && this.rootMediaOptionsTuple[t].find(e=>{ - return t = i, - e.itemId === t.itemId && e.mediaOptionId === t.mediaOptionId; - var t - } - ) || Ol - } - )) - } - enabledMediaOptionByType$(e) { - return this.rawEnabledMediaOptionByType$(e).pipe(Es((e,t)=>e.mediaOptionId === t.mediaOptionId && e.url === t.url)) - } - enabledMediaOptionSwitchForType$(e) { - return this.rawEnabledMediaOptionByType$(e).pipe(So(this.enabledMediaOptionSwitchContextsByType$(e)), xa(null), ca(), ur(([e,t])=>({ - fromId: null == e ? void 0 : e[0].mediaOptionId, - toId: null == t ? void 0 : t[0].mediaOptionId, - switchContext: null == t ? void 0 : t[1] - })), Es((e,t)=>e.fromId === t.fromId && e.toId === t.toId)) - } - enableMediaOptionSwitchedForType$(t) { - return this.enabledMediaOptionByType$(t).pipe(Ra(e=>$l(Cr([Bi(e), this.enabledMediaOptionSwitchContextsByType$(t).pipe(ca())]), ([,e])=>e[0] && !e[1])), ur(([e])=>e)) - } - enabledMediaOptionIdByType(e) { - return this.getEntity(this.itemId).enabledMediaOptionKeys[e].mediaOptionId - } - variantMediaOptionById(e) { - return this.mediaOptionListQueries[ul.Variant].mediaOptionFromId(e) - } - alternateMediaOptionById(e, t) { - return this.mediaOptionListQueries[e].mediaOptionFromId(t) - } - enabledAlternateMediaOptionByType(e) { - var t = this.enabledMediaOptionIdByType(e); - return this.alternateMediaOptionById(e, t) - } - get enabledVariantMediaOption() { - var e = this.enabledMediaOptionIdByType(ul.Variant); - return this.variantMediaOptionById(e) - } - lastLoadedMediaOptionByType(e) { - var t; - return null === (t = this.getEntity(this.itemId).lastLoadedMediaOptionKeys) || void 0 === t ? void 0 : t[e] - } - get nextMediaOptionsKeys$() { - return this.selectEntity(this.itemId, "nextMediaOptionKeys") - } - get preferredMediaOptions() { - return [this.mediaOptionListQueries[0].preferredMediaOptionList, this.mediaOptionListQueries[1].preferredMediaOptionList, this.mediaOptionListQueries[2].preferredMediaOptionList] - } - get preferredMediaOptions$() { - return Zd([this.mediaOptionListQueries[0].preferredMediaOptionList$, this.mediaOptionListQueries[1].preferredMediaOptionList$, this.mediaOptionListQueries[2].preferredMediaOptionList$]) - } - get filteredMediaOptions() { - return [this.mediaOptionListQueries[0].filteredMediaOptionList, this.mediaOptionListQueries[1].filteredMediaOptionList, this.mediaOptionListQueries[2].filteredMediaOptionList] - } - getDisabledMediaOption(e) { - return { - itemId: this.itemId, - mediaOptionType: e, - mediaOptionId: "Nah" - } - } - getEnabledMediaOptionMask() { - return this.enabledMediaOptionKeys.map(e=>kl(e)) - } - getPreferredMediaOptionsByType$(e) { - return this.mediaOptionListQueries[e].preferredMediaOptionList$ - } - altMediaOptionHasValidUrl(e, t) { - t = this.alternateMediaOptionById(e, t); - return Boolean(null == t ? void 0 : t.url) - } - get hdrMode$() { - return this.mediaOptionListQueries[ul.Variant].hdrMode$ - } - get maxHdcpLevel$() { - return this.mediaOptionListQueries[ul.Variant].maxHdcpLevel$ - } - get currentPathwayID() { - return this.mediaOptionListQueries[ul.Variant].currentPathwayID - } - get preferredHost() { - return this.mediaOptionListQueries[ul.Variant].preferredHost - } - getErrorInfoByType(e) { - var t; - return null != (null === (t = this.rootPlaylistEntity) || void 0 === t ? void 0 : t.errorsByType) ? this.rootPlaylistEntity.errorsByType[e] : null - } - getInFlightFragByType(e) { - var t; - return null !== (e = null === (t = null === (t = this.getEntity(this.itemId)) || void 0 === t ? void 0 : t.inFlightFrags) || void 0 === t ? void 0 : t[e]) && void 0 !== e ? e : null - } - getInFlightFragByType$(t) { - return this.selectEntity(this.itemId, e=>{ - return null === (e = null == e ? void 0 : e.inFlightFrags) || void 0 === e ? void 0 : e[t] - } - ) - } - matchAlternates(e, t, i, r) { - t = ne(t) ? this.mediaOptionListQueries[ul.AltAudio].getMatchingAlternateWithPersistentId(t, e, r) : void 0, - r = ne(i) ? this.mediaOptionListQueries[ul.Subtitle].getMatchingAlternateWithPersistentId(i, e, r) : void 0; - return [t || Ol, r || Ol] - } - getLegacyMatchingAlternateWithPersistentId(e, t, i) { - let r = this.mediaOptionListQueries[e].getMatchingAlternateWithPersistentId(t, i, []); - return r = r || this.mediaOptionListQueries[e].getMatchingAlternateWithPersistentId(t, void 0, []), - r - } - isValidMediaOptionTuple(i, e) { - const r = e || this.getEnabledMediaOptionMask(); - return [ul.Variant, ul.AltAudio, ul.Subtitle].reduce((e,t)=>e && r[t] === kl(i[t]), !0) - } - matchGroup(e, t, i, r) { - var n = e.mediaOptionType; - return this.mediaOptionListQueries[n].matchGroup(e, t, i, r) - } - get preferHDR() { - return this.mediaOptionListQueries[ul.Variant].mediaOptionListInfo.preferHDR - } - } - const My = { - name: "rps" - }; - class Py { - constructor(e, t) { - this.store = e, - this.logger = t - } - getQuery() { - return new Od(this.store) - } - getQueryForId(e) { - return new Dy(this.store,e) - } - set rootPlaylistEntity(e) { - Co("root.add.rootPlaylist"), - this.store.add(e) - } - removeItems(e) { - Co(`root.add.remove ${JSON.stringify(e)}`), - this.store.remove(e) - } - removeAll() { - Co("root.add.clear"), - this.store.remove() - } - setRootPlaylistEntity(e, t) { - Co("root.set.rootPlaylistEntity"), - this.store.update(e, e=>t) - } - setSessionData(e, t) { - Co("root.set.sessionData"), - this.store.update(e, e=>{ - e.sessionData = t - } - ) - } - setAnchorTime(e, t) { - Co(`root.set.anchorTime: ${t}`), - this.store.update(e, e=>{ - e.anchorTime = t - } - ) - } - setDiscoSeqNum(e, t) { - Co(`root.set.discoSeqNum: ${t}`), - this.store.update(e, e=>{ - e.discoSeqNum = t - } - ) - } - setPendingSeek(e, t) { - Co("root.set.pendingSeek"), - this.store.update(e, e=>{ - e.pendingSeek = t - } - ), - void 0 === t && rg().setUserSeek(t) - } - setEnabledMediaOptionSwitchContextByType(e, i, r, n) { - this.store.update(e, e=>{ - var t; - if (e.enabledMediaOptionKeys[i].mediaOptionId === r) { - const r = null !== (t = e.mediaOptionSwitchContexts) && void 0 !== t ? t : [null, null, null]; - r[i] = n ? { - userInitiated: n.userInitiated, - switchPosition: n.switchPosition - } : null, - e.mediaOptionSwitchContexts = r - } else - Co(`root.set.mediaOptionSwitchContextByType ${r} doesn't match existing mediaOption ${e.enabledMediaOptionKeys[i].mediaOptionId}`) - } - ) - } - setEnabledMediaOptionByType(r, n, s, a=!1, o) { - s = s || { - itemId: r, - mediaOptionType: n, - mediaOptionId: "Nah" - }, - this.store.update(r, e=>{ - var t; - const i = null !== (t = [...e.enabledMediaOptionKeys]) ? t : [Ol, Ol, Ol]; - if (i[n] = { - itemId: r, - mediaOptionId: s.mediaOptionId - }, - this._updateEnabledMediaOptionKeys(e, i), - a) { - const r = null !== (t = e.mediaOptionSwitchContexts) && void 0 !== t ? t : [null, null, null]; - r[n] = o ? { - userInitiated: o.userInitiated, - switchPosition: o.switchPosition - } : null, - e.mediaOptionSwitchContexts = r - } - } - ) - } - _associateForcedSubtitleWithClosedCaption(e, t, i, r) { - if ((null == i ? void 0 : i.mediaType) === pl.CLOSEDCAPTION) { - t = r.variantMediaOptionById(t), - r = r.mediaOptionListQueries[ul.Subtitle].packageAlternateMediaOption(t, i, !0); - if (r.url !== i.url) { - const n = Fy(t, r, e.mediaOptionListTuple[ul.Subtitle].mediaOptions, qe()); - e.mediaOptionListTuple[ul.Subtitle].mediaOptions = n - } - } - } - _updateEnabledMediaOptionKeys(t, i) { - var e, r; - const n = null !== (e = t.enabledMediaOptionKeys) && void 0 !== e ? e : [Ol, Ol, Ol]; - let s; - for (let e = 0; e < i.length; ++e) { - var a = i[e] - , o = n[e].mediaOptionId !== a.mediaOptionId; - if (o && (n[e] = Object.assign({}, a)), - e === ul.Variant) { - const i = this.getQueryForId(a.itemId).mediaOptionListQueries[e].mediaOptionList; - o ? t.abrStatus = (r = a.mediaOptionId, - o = i, - o = Vg(r, o), - { - fragDownloadSlow: !1, - fragDownloadTooSlow: !1, - nextMinAutoOptionId: Ol.mediaOptionId, - nextMaxAutoOptionId: Ol.mediaOptionId, - highBWTrigger: o - }) : t.abrStatus.highBWTrigger = Vg(a.mediaOptionId, i), - s = a - } else if (e === ul.Subtitle && kl(a)) { - const i = this.getQueryForId(a.itemId) - , n = i.alternateMediaOptionById(e, a.mediaOptionId); - this._associateForcedSubtitleWithClosedCaption(t, s.mediaOptionId, n, i) - } - } - t.enabledMediaOptionKeys = n, - t.nextMediaOptionKeys = void 0 - } - setManualMode(e, t) { - this.store.update(e, e=>{ - e.manualMode = t - } - ) - } - setEnabledMediaOptions(e, i) { - this.store.update(e, e=>{ - var t = i.map(({mediaOptionId: e, itemId: t})=>({ - mediaOptionId: e, - itemId: t - })); - this._updateEnabledMediaOptionKeys(e, t) - } - ) - } - setEnabledMediaOptionsAndSwitchContexts(e, i, r) { - this.store.update(e, e=>{ - var t = i.map(({mediaOptionId: e, itemId: t})=>({ - mediaOptionId: e, - itemId: t - })); - this._updateEnabledMediaOptionKeys(e, t), - e.mediaOptionSwitchContexts = r - } - ) - } - setNextMediaOptions(e, i) { - Co(`root.set.nextMediaOptions: ${JSON.stringify(null == i ? void 0 : i.map(e=>e.mediaOptionId))}`), - this.store.update(e, e=>{ - var t = i ? i.map(({itemId: e, mediaOptionId: t})=>({ - itemId: e, - mediaOptionId: t - })) : null; - e.nextMediaOptionKeys = t - } - ) - } - updateEnabledMediaOptions(e) { - Co("root.set.updateEnabledMediaOptions"), - this.store.update(e, e=>{ - e.nextMediaOptionKeys && !0 !== e.manualMode && (Co(`root.set.updateEnabledMediaOptions ${JSON.stringify(e.nextMediaOptionKeys)}`), - this._updateEnabledMediaOptionKeys(e, [...e.nextMediaOptionKeys])), - e.nextMediaOptionKeys = void 0 - } - ) - } - setLastLoadedMediaOptionByType(r, n, s) { - Co(`root.set.lastLoadedMediaOptionByType: ${n} ${(s = s || { - itemId: r, - mediaOptionType: n, - mediaOptionId: "Nah" - }).mediaOptionId}`), - this.store.update(r, e=>{ - var t; - const i = null !== (t = e.lastLoadedMediaOptionKeys) && void 0 !== t ? t : [Ol, Ol, Ol]; - i[n] = { - itemId: r, - mediaOptionId: s.mediaOptionId - }, - e.lastLoadedMediaOptionKeys = i - } - ) - } - setPreferredHost(e, t) { - Co(`root.set.preferredHost: ${t}`), - this.store.update(e, e=>{ - e && (e.mediaOptionListTuple[ul.Variant].preferredHost = t) - } - ) - } - setViewportInfo(e, t) { - Co(`root.set.viewportInfo: ${JSON.stringify(t)}`), - this.store.update(e, e=>{ - e && (e.mediaOptionListTuple[ul.Variant].viewportInfo = t) - } - ) - } - static getExistingPersistentIds(e) { - var t; - const i = {} - , r = null === (t = e.enabledMediaOptionKeys[ul.AltAudio]) || void 0 === t ? void 0 : t.mediaOptionId; - if ("Nah" !== r) { - const s = e.mediaOptionListTuple[ul.AltAudio] - , t = Pm(s.mediaOptions, Cy.kAllowFilters, s).find(e=>e.mediaOptionId === r); - i.audioPersistentId = null == t ? void 0 : t.persistentID - } - const n = null === (t = e.enabledMediaOptionKeys[ul.Subtitle]) || void 0 === t ? void 0 : t.mediaOptionId; - if ("Nah" !== n) { - const s = e.mediaOptionListTuple[ul.Subtitle] - , t = Pm(s.mediaOptions, Cy.kAllowFilters, s).find(e=>e.mediaOptionId === n); - i.subtitlePersistentId = null == t ? void 0 : t.persistentID - } - return i - } - static doUpdateRootHDRSwitch(e, t, i, r) { - const n = e.mediaOptionListTuple.map(e=>Object.assign({}, e)); - n[ul.Variant].preferHDR = t, - n[ul.Variant].hasHdrLevels = i; - const s = ng() - , a = Xg.getEntity(e.itemId) - , o = Qf(e.itemId) - , d = o.getBandwidthEstimate(s, null == a ? void 0 : a.serviceName) - , l = o.getPlaylistEstimate(s, null == a ? void 0 : a.serviceName) - , u = o.getFragEstimate(s, null == a ? void 0 : a.serviceName) - , c = o.getBufferEstimate(s, null == a ? void 0 : a.serviceName) - , h = { - targetDuration: u.maxDurationSec || (null == s ? void 0 : s.defaultTargetDuration), - targetStartupMs: null == s ? void 0 : s.targetStartupMs - } - , p = Py.getExistingPersistentIds(e); - return By(Object.assign(Object.assign({}, e), { - mediaOptionListTuple: n, - nextMediaOptionKeys: null - }), p, r, d, h, l, u, c) - } - switchToSDROnly(e) { - Co("root.switchToSDROnly"), - this.store.update(e, e=>{ - var t = Py.doUpdateRootHDRSwitch(e, !1, !1, this.logger)["mediaOptionListTuple"]; - e.mediaOptionListTuple = t - } - ) - } - setHDRPreference(e, i, r) { - Co(`root.set.HDRPreference: ${i}`), - this.store.update(e, e=>{ - var t = e.mediaOptionListTuple[ul.Variant]; - if (t.preferHDR !== i && (!i || t.hasHdrLevels)) { - t = Py.doUpdateRootHDRSwitch(e, i, t.hasHdrLevels, this.logger); - if (r) - return t; - e.mediaOptionListTuple = t.mediaOptionListTuple - } - } - ) - } - setPathwayPriority(e, i) { - Co(`root.set.PathwayPriority: [ ${i.join(", ")} ]`), - this.store.update(e, e=>{ - if (e) { - const t = e.mediaOptionListTuple[ul.Variant]; - t.pathwayPriority = i, - t.preferredHost = null - } - } - ) - } - setCurrentPathwayID(e, t) { - Co(`root.set.currentPathwayID: ${t}`), - this.store.update(e, e=>{ - e && (e.mediaOptionListTuple[ul.Variant].currentPathwayID = t) - } - ) - } - setInitPTS(e, t, i, r, n, s) { - Co(`root.set.initPTS: ${e} ${t} variantDTS:${JSON.stringify(i)} timelineOffset: ${r}`), - this.store.update(e, e=>{ - e.initPtsRecord[t] = { - variantDTS: i, - timelineOffset: r, - offsetTimestamp: n, - iframeMode: s - } - } - ) - } - static prunePenaltyBox(e, t) { - return e.filter(e=>!(e.expiry <= t)) - } - static addToPenaltyBox(e, t, i) { - return e.push({ - mediaOptionId: i, - expiry: t + 12e4 - }) - } - addToPenaltyBox(e, r, n) { - Co(`root.set.penaltyBox: ${r}: ${n}`), - this.store.update(e, ({mediaOptionListTuple: e})=>{ - const t = e[r] - , i = performance.now(); - t.penaltyBoxQueue = Py.prunePenaltyBox(t.penaltyBoxQueue, i), - Py.addToPenaltyBox(t.penaltyBoxQueue, i, n) - } - ) - } - prunePenaltyBox(e, r=null) { - Co(`root.set.prunePenaltyBox: ${r}`), - this.store.update(e, ({mediaOptionListTuple: e})=>{ - var e = r ? [e[r]] : e - , t = performance.now(); - for (const i of e) - i.penaltyBoxQueue = Py.prunePenaltyBox(i.penaltyBoxQueue, t) - } - ) - } - removePermanently(e, r, n) { - Co(`root.set.removePermanently: ${r}: ${n}`), - this.store.update(e, ({mediaOptionListTuple: e})=>{ - const t = e[r] - , i = new Set(t.removed); - i.add(n), - t.removed = Array.from(i) - } - ) - } - moveAllWithMatchingHosts(e, r, n, s) { - Co(`root.set.moveAllMatchingHosts: ${r}:${n} remove:${s}`), - this.store.update(e, ({mediaOptionListTuple: e})=>{ - const t = e[r] - , i = [...t.mediaOptions].filter(e=>yl(n, e.url)).map(e=>e.mediaOptionId); - if (s) { - const e = new Set([...t.removed, ...i]); - t.removed = Array.from(e) - } else { - const e = performance.now(); - t.penaltyBoxQueue = Py.prunePenaltyBox(t.penaltyBoxQueue, e); - for (const r of i) - Py.addToPenaltyBox(t.penaltyBoxQueue, e, r) - } - } - ) - } - setMaxHdcpLevel(e, i, r=!1) { - Co(`root.set.maxHdcpLevel: ${i}`), - this.store.update(e, ({mediaOptionListTuple: e})=>{ - const t = e[ul.Variant]; - (r || nm(i) < nm(t.maxHdcpLevel)) && (t.maxHdcpLevel = i) - } - ) - } - updateConsecutiveTimeouts(e, i, r, n) { - this.store.update(e, e=>{ - const t = e.errorsByType || [{ - timeouts: { - load: 0, - append: 0, - key: 0 - } - }, { - timeouts: { - load: 0, - append: 0, - key: 0 - } - }, { - timeouts: { - load: 0, - append: 0, - key: 0 - } - }]; - r ? ++t[i].timeouts[n] : t[i].timeouts[n] = 0, - e.errorsByType = t - } - ) - } - updateInflightFrag(d, l, u, c, h) { - Co("root.set.updateInflightFrag"), - this.store.update(d, r=>{ - if (r.inFlightFrags || (r.inFlightFrags = [null, null]), - !(l === ul.Subtitle || u && u.itemId !== d)) - if (u) { - let {start: e, duration: t} = u; - var {mediaOptionId: n, mediaSeqNum: s, discoSeqNum: a} = u - , o = r.inFlightFrags[l]; - let i = null == o ? void 0 : o.tstart; - c !== (null == o ? void 0 : o.state) && (i = performance.now()), - Fp(o, u) && (e = o.start, - t = o.duration), - r.inFlightFrags[l] = { - itemId: d, - mediaOptionId: n, - mediaSeqNum: s, - discoSeqNum: a, - start: e, - duration: t, - tstart: i, - state: c, - bwSample: Object.assign({}, h) - } - } else - r.inFlightFrags[l] = null - } - ) - } - setNextMaxAutoOptionId(e, t) { - Co(`root.set.nextMaxAutoOptionId: ${t}`), - this.store.update(e, ({abrStatus: e})=>{ - e.nextMaxAutoOptionId = t - } - ) - } - setNextMinAutoOptionId(e, t) { - Co(`root.set.nextMinAutoOptionId: ${t}`), - this.store.update(e, ({abrStatus: e})=>{ - e.nextMinAutoOptionId = t - } - ) - } - setHighBWTrigger(e, t) { - Co(`root.set.setHighBWTrigger: ${t}`), - this.store.update(e, ({abrStatus: e})=>{ - e.highBWTrigger = t - } - ) - } - setFragLoadSlow(e, t) { - Co(`root.set.setFragLoadSlow ${e} ${JSON.stringify(t)}`), - this.store.update(e, ({abrStatus: e})=>{ - e.fragDownloadSlow = t.fragDownloadSlow, - e.fragDownloadTooSlow = t.fragDownloadTooSlow - } - ) - } - pickMediaOptionTupleByPersistentId(e, t, i, r=!1, n=!1) { - var s = e.enabledMediaOptionIdByType(ul.Variant) - , s = e.variantMediaOptionById(s); - let a, o; - if (t === ul.AltAudio) { - const t = e.enabledAlternateMediaOptionByType(ul.Subtitle); - o = null == t ? void 0 : t.persistentID, - a = i - } else { - const t = e.enabledAlternateMediaOptionByType(ul.AltAudio); - a = null == t ? void 0 : t.persistentID, - o = i - } - const d = e.getEnabledMediaOptionMask(); - return d[t] = !!(ne(i) && 0 <= i), - s ? this.getBestMediaOptionTupleFromVariantAndPersistentId(e, s, a, o, d, void 0, r, n, !1) : [Ol, Ol, Ol] - } - getFallbackMediaOptionTupleFromMediaOptionId(e, t, i, r, n=!1, s=!1, a=!1) { - var o = r ? [r] : [i] - , d = e.enabledMediaOptionIdByType(ul.Variant) - , r = e.variantMediaOptionById(d) - , d = t === ul.AltAudio ? e.alternateMediaOptionById(ul.AltAudio, i) : e.enabledAlternateMediaOptionByType(ul.AltAudio) - , d = null == d ? void 0 : d.persistentID - , i = t === ul.Subtitle ? e.alternateMediaOptionById(ul.Subtitle, i) : e.enabledAlternateMediaOptionByType(ul.Subtitle) - , i = null == i ? void 0 : i.persistentID; - return r ? this.getBestMediaOptionTupleFromVariantAndPersistentId(e, r, d, i, void 0, o, n, s, a) : [Ol, Ol, Ol] - } - hasFallbackMediaOptionTuple(e, t, i, r) { - var n = e.mediaOptionListQueries[t].mediaOptionFromId(i); - return e.isValidMediaOptionTuple(this.getFallbackMediaOptionTupleFromMediaOptionId(e, t, i, n.backingMediaOptionId, !1, r)) - } - setLegacyAlternateMediaOption(e, t, i, r, n) { - var s = e.enabledMediaOptionIdByType(ul.Variant) - , s = e.variantMediaOptionById(s) - , s = e.getLegacyMatchingAlternateWithPersistentId(i, r, s); - s ? this.setEnabledMediaOptionByType(t, i, s, !0, n) : this.logger.warn(`${Cl[i]} can't find matching mediaOption for persistent id ${r}`) - } - setEnabledMediaOptionTupleWithMatchedGroups(t, i, e, r) { - const n = Ly(t) - , s = this.pickMediaOptionTupleByPersistentId(n, i, e); - if (!n.isValidMediaOptionTuple(s)) - return this.setLegacyAlternateMediaOption(n, t, i, e, r); - sd(()=>{ - this.setEnabledMediaOptionByType(t, i, s[i], !0, r), - s[ul.Variant].mediaOptionId !== n.enabledMediaOptionIdByType(ul.Variant) && this.setPreferredHost(t, gl(s[ul.Variant].url)), - this.setEnabledMediaOptionByType(t, ul.Variant, s[ul.Variant]); - var e = i === ul.AltAudio ? ul.Subtitle : ul.AltAudio; - s[e].mediaOptionId !== n.enabledMediaOptionIdByType(e) && this.setEnabledMediaOptionByType(t, e, s[e], !1) - } - ) - } - canSwitchToSDR(e, t, i, r=!1) { - var n = e.mediaOptionListQueries[ul.Variant].mediaOptionFromId(t) - , r = this.getFallbackMediaOptionTupleFromMediaOptionId(e, ul.Variant, t, n.backingMediaOptionId, !0, i, r); - return e.isValidMediaOptionTuple(r) - } - getBestMediaOptionTupleFromVariantAndPersistentId(t, e, i, r, n, s, a, o, d) { - var l, u = t.mediaOptionListQueries[ul.Variant].listFallbackVariants(e.mediaOptionId, a, o, d, s); - let c = [Ol, Ol, Ol]; - for (let e = 0; e < u.length; ++e) { - const a = u[e]; - if (l = t.matchAlternates(a, i, r, s), - t.isValidMediaOptionTuple([a, ...l], n)) { - c = [a, ...l]; - break - } - } - return c - } - } - const xy = new class extends pd { - constructor() { - super({}, { - name: "root-playlist-store", - idKey: "itemId", - producerFn: vc - }) - } - akitaPreAddEntity(e) { - return null == e.errorsByType ? Object.assign(Object.assign({}, e), { - errorsByType: [{ - timeouts: { - load: 0, - append: 0, - key: 0 - } - }, { - timeouts: { - load: 0, - append: 0, - key: 0 - } - }, { - timeouts: { - load: 0, - append: 0, - key: 0 - } - }] - }) : e - } - } - ; - new Od(xy); - let Ry = null; - function Ly(e) { - return new Dy(xy,e) - } - const _y = (n,e,t,s,i)=>{ - const {rootMediaOptionsTuple: r, sessionKeys: a} = n - , o = Array.from(r[ul.Variant]) - , d = Array.from(r[ul.AltAudio]); - let l = !1 - , u = !1 - , c = o.map(e=>(l = l || Boolean(e.videoCodec), - u = u || Boolean(e.audioCodec) || Boolean(e.audioGroupId), - e)); - return l && u && (c = c.filter(({videoCodec: e})=>Boolean(e))), - Oy(o, d, a, e, t, i).pipe(ur(({hdrMediaOptions: e, sdrMediaOptions: t})=>{ - var i = e.concat(t) - , r = 0 < e.length; - return e.concat(t), - function(e, t, i, r) { - var {itemId: n, itemStartOffset: s, rootMediaOptionsTuple: a, audioMediaSelectionGroup: o, subtitleMediaSelectionGroup: d} = e - , l = Array.from(a[ul.AltAudio]) - , u = Array.from(a[ul.Subtitle]) - , c = t.every(e=>ne(e.score)) - , h = t.some(e=>Nm(!0, e)) - , p = function(e, t) { - const i = [...e]; - return t ? i.sort((e,t)=>e.score - t.score || t.bitrate - e.bitrate) : i.sort((e,t)=>e.bitrate - t.bitrate), - i - }(t, c) - , f = e.baseUrl - , t = null === (a = e.contentSteeringOption) || void 0 === a ? void 0 : a.initPathwayID - , a = e.sessionData; - return { - itemId: n, - baseUrl: f, - mediaOptionListTuple: [{ - mediaOptions: p, - hasHdrLevels: i, - hasIframeLevels: h, - hasScore: c, - preferHDR: r, - compatibleIds: null, - penaltyBoxQueue: [], - removed: [], - currentPathwayID: t - }, { - mediaOptions: l, - compatibleIds: null, - penaltyBoxQueue: [], - removed: [] - }, { - mediaOptions: u, - penaltyBoxQueue: [], - removed: [] - }], - audioMediaSelectionGroup: o, - subtitleMediaSelectionGroup: d, - enabledMediaOptionKeys: [Ol, Ol, Ol], - mediaOptionSwitchContexts: [null, null, null], - anchorTime: 0, - discoSeqNum: NaN, - pendingSeek: void 0, - itemStartOffset: s, - initPtsRecord: {}, - contentSteeringOption: e.contentSteeringOption, - masterVariableList: e.masterVariableList, - loadStats: e.stats, - isMediaPlaylist: e.isMediaPlaylist, - abrStatus: { - fragDownloadSlow: !1, - fragDownloadTooSlow: !1, - nextMinAutoOptionId: Ol.mediaOptionId, - nextMaxAutoOptionId: Ol.mediaOptionId, - highBWTrigger: NaN - }, - sessionData: a - } - }(n, i, r, s) - } - )) - } - ; - function Ny(e, t, i, r, n, s, a) { - var o, d, l, u, c, h, p, f = e.mediaOptionListTuple[ul.Variant], m = Pm(f.mediaOptions, Um.kAllowFilters, Object.assign(Object.assign({}, f), { - compatibleIds: null - })), g = xm(f.preferredHost, m); - return { - firstVariant: (o = g, - e = Cg, - f = f.hasScore, - t = t, - i = i, - r = r, - n = n, - s = s, - a = a, - !o || o.length < 1 || o.every(e=>e.iframes) ? void t.warn("no non-iframe media option found") : ((o = f ? Dg(o, i, r, n, s, a) : (d = e, - l = i, - u = r, - c = n, - h = s, - p = a, - o.reduce((e,t)=>{ - if (t.iframes) - return e; - let i = e; - const r = function(e, t, i, r, n, s, a) { - var o, d, l = (o = e.bitrate, - u = e.height, - (d = (e,t,i)=>(e - t) * (e - i) <= 0)(o, t.minValidBitrate, t.maxValidBitrate) && d(u, t.minValidHeight, t.maxValidHeight) ? ll.VALID : ll.INVALID), o = "PQ" === (c = e.videoRange) ? ol.PQ : "HLG" === c ? ol.HLG : "SDR" === c ? ol.SDR : ol.UNKNOWN, {videoCodecRank: u, audioCodecRank: c} = { - videoCodecRank: $p((d = e).videoCodec), - audioCodecRank: Kp(d.audioCodec) - }, d = e.bitrate < t.maxPreferredBitrate ? ll.VALID : ll.INVALID, t = e.audioChannelCount || 1, a = i && r && n && s && !Mg(e, i, r, n, s, a) ? ll.INVALID : ll.VALID; - return new Hp(l,o,u,t,c,a,d,e.height) - }(t, d, l, u, c, h, p); - return (!e || r.isGreaterThan(e.bestRank) || r.isEqualTo(e.bestRank) && t.bitrate > e.selected.bitrate) && (i = { - selected: t, - bestRank: r - }), - i - } - , null).selected)) || t.warn("no valid first media option found"), - o)), - filteredVariants: m, - preferredVariants: g - } - } - function Fy(e, t, i) { - if ((null == t ? void 0 : t.mediaType) === pl.CLOSEDCAPTION) { - const r = Cy.pairForcedSubtitleMediaOptionWithClosedCaptionInList(e.subtitleGroupId, t, i); - if (r) - return t = Object.assign(Object.assign({}, t), { - url: r.url, - backingMediaOptionId: r.mediaOptionId - }), - i.map(e=>e.mediaOptionId === t.mediaOptionId ? t : e) - } - return i - } - function By(e, t, i, r, n, s, a, o) { - var d; - const l = e.itemId - , u = e.mediaOptionListTuple[ul.Variant] - , c = e.mediaOptionListTuple[ul.AltAudio] - , h = e.mediaOptionListTuple[ul.Subtitle] - , p = Pm(c.mediaOptions, Cy.kAllowFilters, c) - , f = Pm(h.mediaOptions, Cy.kAllowFilters, h); - let {firstVariant: m, filteredVariants: g} = Ny(e, i, r, n, s, a, o); - if (!m) { - const U = u.preferHDR; - u.preferHDR = !U && u.hasHdrLevels, - u.preferHDR !== U && (i.warn(`No valid first variant found, toggling hdr preference=${U}->${u.preferHDR}`), - {firstVariant: m, filteredVariants: g} = Ny(e, i, r, n, s, a, o)) - } - if (!m) - throw new V(!0,"No valid first variant found",$.NoValidAlternates); - const y = gl(m.url) - , v = { - itemId: l, - mediaOptionId: null !== (o = null == m ? void 0 : m.mediaOptionId) && void 0 !== o ? o : null - } - , S = null != p && p.length ? null === (o = ((i,r,e,n)=>{ - if (e) { - let t; - return t = ne(i) ? e.MediaSelectionGroupOptions.find(function(e) { - return e.MediaSelectionOptionsPersistentID === i - }) : e.MediaSelectionGroupOptions.find(function(e) { - return e.MediaSelectionOptionsIsDefault - }), - t = t || e.MediaSelectionGroupOptions[0], - n.find(e=>(!r || e.groupId === r) && e.persistentID === (null == t ? void 0 : t.MediaSelectionOptionsPersistentID)) - } - } - )(null == t ? void 0 : t.audioPersistentId, m.audioGroupId, e.audioMediaSelectionGroup, p)) || void 0 === o ? void 0 : o.mediaOptionId : null - , b = S ? { - itemId: l, - mediaOptionId: S - } : Ol - , T = ((i,r,n,s,a,o)=>{ - if (s) { - let t, e; - return t = ne(i) ? s.MediaSelectionGroupOptions.find(function(e) { - return e.MediaSelectionOptionsPersistentID === i - }) : s.MediaSelectionGroupOptions.find(function(e) { - return e.MediaSelectionOptionsIsDefault - }), - t && (e = a.find(e=>e.mediaType === pl.CLOSEDCAPTION ? (!r || e.groupId === r) && e.persistentID === t.MediaSelectionOptionsPersistentID : e.mediaType === pl.SUBTITLE ? (!n || e.groupId === n) && e.persistentID === t.MediaSelectionOptionsPersistentID : void o.warn(My, `subtitle media option has unknown type ${e.mediaType}`))), - e - } - } - )(null == t ? void 0 : t.subtitlePersistentId, m.closedcaption, m.subtitleGroupId, e.subtitleMediaSelectionGroup, f, i) - , E = null != f && f.length ? null == T ? void 0 : T.mediaOptionId : null - , I = E ? { - itemId: l, - mediaOptionId: E, - mediaOptionType: ul.Subtitle - } : Ol - , {mediaOptions: w, audioGroups: A, subtitleGroups: O} = (t = g, - d = m, - t.reduce((e,t)=>{ - if (((e,t)=>{ - let i = !0; - e.videoCodec && t.videoCodec && (i = Se.isCompatibleVideoCodec(e.videoCodec, t.videoCodec)); - let r = !1; - e.videoRange && t.videoRange ? r = e.videoRange == t.videoRange : e.videoRange || t.videoRange || (r = !0); - let n = !0; - return e.audioCodec && t.audioCodec && (n = Se.isCompatibleAudioCodec(e.audioCodec, t.audioCodec)), - i && r && n - } - )(d, t)) { - const d = t.audioGroupId; - d && e.audioGroups.add(d), - e.mediaOptions.add(t) - } - var i = t.subtitleGroupId; - i && e.subtitleGroups.add(i); - t = t.closedcaption; - return t && e.closedCaptionGroups.add(t), - e - } - , { - mediaOptions: new Set, - audioGroups: new Set, - subtitleGroups: new Set, - closedCaptionGroups: new Set - })) - , k = Array.from(w).map(e=>e.mediaOptionId) - , C = m.pathwayID - , D = Object.assign(Object.assign({}, u), { - compatibleIds: k, - preferredHost: y, - currentPathwayID: C - }) - , M = [] - , P = c.mediaOptions.reduce((e,t)=>(A.has(t.groupId) && (e.persistentIds.add(t.persistentID), - M.push(t.mediaOptionId), - e.filteredAudioMediaOptions.push(t), - e.altAudio || (e.altAudio = !!t.url)), - e), { - filteredAudioMediaOptions: [], - persistentIds: new Set, - altAudio: !1 - }) - , x = Object.assign(Object.assign({}, c), { - compatibleIds: M + }), + tag('stats.initialized'), + ); + } + */ + + function objectIsEqual(a, b) { + if (a === b) + return true; + if (!a || !b) + return false; + let same = Object.keys(a).length === Object.keys(b).length; + for (const k of Object.keys(a)) { + same = same && ((isNaN(a[k]) && isNaN(b[k])) || a[k] === b[k]); + } + return same; + } + /** + Stats processing Epic. Listens to samples (bandwidth, playlist, + frag) and processes the data and sends back estimates to the store + */ + const statsBandwidthProcessingEpic = (config, statsService, logger) => (bandwidthSampleSource$) => { + return new Observable((subscriber) => { + let historyBasedBandwidthEstimator = new HistoryBasedBandwidthEstimator(config.bandwidthHistoryWindowSize, config.bandwidthHistoryAggregationMethod, { avgLatencyMs: NaN, avgBandwidth: NaN }); + const estimate$ = historyBasedBandwidthEstimator.estimate$; + const sub = merge( + // feed the estimator + bandwidthSampleSource$.pipe(filter((sample) => sample.complete), tap((sample) => { + logger.qe({ + critical: true, + name: 'bandwidthRecordDetails', + data: { + type: MediaOptionNames[sample.mediaOptionType], + observedBitrateExcludingLatency: ((sample.loaded * 8) / (sample.tload - sample.tfirst)) * 1000, + observedBitrate: ((sample.loaded * 8) / (sample.tload - sample.trequest)) * 1000, + }, + }); + }), map((bandwidthSample) => ({ + trequest: bandwidthSample.trequest, + tfirst: bandwidthSample.tfirst, + tload: bandwidthSample.tload, + bitsDownloaded: bandwidthSample.loaded * 8, + })), tag('statsBandwidthProcessingEpic.in'), switchMap((value) => { + historyBasedBandwidthEstimator.record(value); + return EMPTY; + })), estimate$.pipe(distinctUntilChanged(), tag('statsBandwidthProcessingEpic.change'), tap((value) => { + if (statsService) { + statsService.setBandwidthEstimate(value); + logger.qe({ critical: true, name: 'bandwidthEstimate', data: { bandwidthEstimate: value } }); + } + }))).subscribe(subscriber); + return () => { + sub.unsubscribe(); + historyBasedBandwidthEstimator.destroy(); + historyBasedBandwidthEstimator = undefined; + }; + }); + }; + const statsFragProcessingEpic = (config, statsService) => (fragSampleSource$) => { + return fragSampleSource$.pipe(tag('statsFragProcessingEpic.in'), scan((acc, sample) => { + acc.durationSec.add(sample.durationSec); + acc.fragParseMs.add(sample.parseTimeMs); + return acc; + }, { + durationSec: new SimpleAccumulator(), + fragParseMs: new SimpleAccumulator(config.minFragmentCount), + }), map((value) => ({ + maxDurationSec: value.durationSec.max, + avgParseTimeMs: value.fragParseMs.avg, + })), distinctUntilChanged(objectIsEqual), tap((estimate) => statsService.setFragEstimate(estimate))); + }; + const statsPlaylistProcessingEpic = (config, statsService) => (playlistSampleSource$) => { + return playlistSampleSource$.pipe(tag('statsPlaylistProcessingEpic.in'), scan((acc, sample) => { + acc.playlistLoadTimeMs.add(sample.playlistLoadTimeMs); + acc.playlistParseTimeMs.add(sample.playlistParseTimeMs); + return acc; + }, { + playlistLoadTimeMs: new SimpleAccumulator(config.minPlaylistCount), + playlistParseTimeMs: new SimpleAccumulator(config.minPlaylistCount), + }), map((value) => ({ + avgPlaylistLoadTimeMs: value.playlistLoadTimeMs.avg, + avgPlaylistParseTimeMs: value.playlistParseTimeMs.avg, + })), distinctUntilChanged(objectIsEqual), tap((estimate) => { + statsService.setPlaylistEstimate(estimate); + })); + }; + const statsBufferProcessingEpic = (config, statsService) => (bufferMetricSource$) => { + return bufferMetricSource$.pipe(tag('statsBufferMetricProcessingEpic.in'), scan((acc, metric) => { + if (isFiniteNumber(metric.bufferCreationStart) && isFiniteNumber(metric.bufferCreationEnd)) { + acc.bufferCreateMs.add(metric.bufferCreationEnd - metric.bufferCreationStart); + } + if (isFiniteNumber(metric.startInitAppend) && isFiniteNumber(metric.endInitAppend)) { + acc.initFragAppendMs.add(metric.endInitAppend - metric.startInitAppend); + } + if (isFiniteNumber(metric.startDataAppend) && isFiniteNumber(metric.endDataAppend)) { + acc.dataFragAppendMs.add(metric.endDataAppend - metric.startDataAppend); + } + return acc; + }, { + // Seed value + bufferCreateMs: new SimpleAccumulator(), + initFragAppendMs: new SimpleAccumulator(), + dataFragAppendMs: new SimpleAccumulator(config.minFragmentCount), + }), map((value) => ({ + avgBufferCreateMs: value.bufferCreateMs.avg, + avgInitFragAppendMs: value.initFragAppendMs.avg, + avgDataFragAppendMs: value.dataFragAppendMs.avg, + })), distinctUntilChanged(objectIsEqual), tap((estimate) => { + statsService.setBufferEstimate(estimate); + })); + }; + function statsProcessor(config, statsService, item, logger) { + return new Observable((subscriber) => { + initializeStatsFunc(item.itemId); + const statsQuery = createStatsQuery(item.itemId); + const { fragSample$, playlistSample$, bandwidthSample$, bufferMetric$ } = statsQuery; + merge(playlistSample$.pipe(observeOn(asyncScheduler), statsPlaylistProcessingEpic(config, statsService)), bandwidthSample$.pipe(observeOn(asyncScheduler), statsBandwidthProcessingEpic(config, statsService, logger)), fragSample$.pipe(observeOn(asyncScheduler), statsFragProcessingEpic(config, statsService)), bufferMetric$.pipe(observeOn(asyncScheduler), statsBufferProcessingEpic(config, statsService))) + .pipe(switchMapTo(EMPTY)) + .subscribe(subscriber); + return () => { + PersistStats$1.setCombinedEstimate(config, Object.assign(Object.assign(Object.assign(Object.assign({}, statsQuery.getFragEstimate()), statsQuery.getPlaylistEstimate()), statsQuery.getBufferEstimate()), statsQuery.getBandwidthEstimate()), item.serviceName); + statsService.remove(item.itemId); + }; + }); + } + + /** + * MediaSource helper + */ + function getMediaSource() { + return window.MediaSource || window.WebKitMediaSource; + } + + /** + * MediaSource helper + */ + function isSupported() { + try { + const mediaSource = getMediaSource(); + const sourceBuffer = window.SourceBuffer || window.WebKitSourceBuffer; + const isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'); + // if SourceBuffer is exposed ensure its API is valid + // safari and old version of Chrome do not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible + const sourceBufferValidAPI = !sourceBuffer || (sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === 'function' && typeof sourceBuffer.prototype.remove === 'function'); + return !!isTypeSupported && !!sourceBufferValidAPI; + } + catch (_a) { + return false; + } + } + + /* + * Media Element Helper: Contains wrapper class information for HTMLMediaElement + * + * + */ + const MediaElementHelper = { + isWebkitMediaElement(media) { + return 'webkitDroppedFrameCount' in media; + }, + isHtmlVideoElement(media) { + return 'getVideoPlaybackQuality' in media; + }, + timeRangeToArray(timeRange) { + const rangeArr = []; + for (let i = 0; i < timeRange.length; i++) { + rangeArr.push([timeRange.start(i), timeRange.end(i)]); + } + return rangeArr; + }, + }; + + /* + * Access Log Types + * + * + */ + const loggerName$3 = { name: 'access-log' }; + class AccessLog { + constructor(hls, sessionID) { + this.hls = hls; + this.sessionID = sessionID; + this.rtcQuery = null; + this.accessLogData = this.createAccessLogEntry(); + this.accesslog = []; + this.errorlog = []; + } + destroy() { + this.rtcQuery = null; + this.accesslog = []; + this.errorlog = []; + this.accessLogData = undefined; + this.accessLogReporter = undefined; + } + setRTCQuery(query) { + this.rtcQuery = query; + } + setupReporter(appData) { + this.accessLogReporter = { SessionID: this.sessionID, ClientName: appData === null || appData === void 0 ? void 0 : appData.clientName, ServiceName: appData === null || appData === void 0 ? void 0 : appData.serviceName }; + } + addPlayTime(itemId) { + var _a; + const entity = (_a = this.rtcQuery) === null || _a === void 0 ? void 0 : _a.getEntity(itemId); + if (!entity) { + return; + } + const sessionControlRecord = entity.sessionControlRecord; + if (sessionControlRecord.state === 'RTC_STATE_PLAY') { + this.accessLogData.PlayTimeWC = (this.accessLogData.PlayTimeWC || 0) + sessionControlRecord.eventStartTime; + } + getLogger().trace(loggerName$3, 'accessLogData playtime: %d', this.accessLogData.PlayTimeWC); + } + updatePlaybackInfo(itemId, data) { + this.accessLogData.ViFrDr = this.rtcQuery.getEntity(itemId).sessionControlRecord.droppedVideoFrames || 0; + getLogger().trace(loggerName$3, 'accessLogData Framedrop: %d', this.accessLogData.ViFrDr); + } + updateStallCount(itemId) { + const state = this.rtcQuery.getEntity(itemId).sessionControlRecord.state; + if (state !== 'RTC_STATE_PLAY') { + // don't report stall events if we're not playing + getLogger().info(loggerName$3, `skipping low buffer stall event because we're not playing, state: ${state}`); + return; + } + this.accessLogData.StallCount++; + } + updateMediaEngineStallCount(itemId) { + const state = this.rtcQuery.getEntity(itemId).sessionControlRecord.state; + if (state !== 'RTC_STATE_PLAY') { + // don't report stall events if we're not playing + getLogger().info(loggerName$3, `skipping high buffer stall event because we're not playing, state: ${state}`); + return; + } + this.accessLogData.MediaEngineStallCount++; + } + updateCanPlay(itemId) { + this.accessLogData.StartupTime = this.rtcQuery.getEntity(itemId).sessionControlRecord.eventStartTime; + } + updateFragLoaded(itemId, isSeeking, data) { + // use only 'main' (muxed) / 'video' (unmuxed) data to calculate below keys + if (data.fragType === MediaOptionType.Variant) { + this.accessLogData.NetBytes += data.bytes; + this.accessLogData.ADT += data.adt; + //this._accessLogData.SegmentProcessTime += data.processTime; + const accessLogBitrateStats = this.aggregateFragObserverdBitrate(data, ++this.accessLogData.fragmentCnt, this.accessLogData.NetBytes, this.accessLogData.ADT); + this.accessLogData.OBRLast = accessLogBitrateStats.obrLast; + this.accessLogData.OBRMean = accessLogBitrateStats.obrMean; + this.aggregateFragMinMaxBitrate(this.accessLogData, accessLogBitrateStats.obr); + const currentTime = this.hls.realCurrentTime; + if (currentTime > data.startPTS && !isSeeking) { + this.accessLogData.overdue++; + } + if (this.hasGap(data.startPTS, data.endPTS, this.accessLogData.lastStartPTS, this.accessLogData.lastEndPTS)) { + // New continuous playback stream due to timejump + getLogger().info(loggerName$3, 'summarize stats for seek to startPTS: ' + data.startPTS + 's'); + this.addToAccessLog(itemId); + } + if (!this.accessLogData.startPTS) { + // mark first ever fragment start time for fresh access log entry + this.accessLogData.startPTS = data.startPTS; + } + // Remember last loaded fragment start and end time to detect new seek later + this.accessLogData.lastStartPTS = data.startPTS; + this.accessLogData.lastEndPTS = data.endPTS; + // accumulate the 'main' (muxed) / 'video' (unmuxed) bytes & duration to calculate AvgVideoBitrate + this.accessLogData.videoBytes += data.bytes; + this.accessLogData.videoDuration += data.duration; + } + else if (data.fragType === MediaOptionType.AltAudio) { + // accumulate the 'audio' bytes & duration to calculate AvgAudioBitrate + this.accessLogData.audioBytes += data.bytes; + this.accessLogData.audioDuration += data.duration; + } + getLogger().trace(loggerName$3, 'Fragloaded, accessLogData=%o', this.accessLogData); + } + addToAccessLog(itemId) { + const varInfo = this.getVariantInfo(itemId); + const url = this.rtcQuery.getEntity(itemId).sessionControlRecord.curLevelUrl; + const playType = this.rtcQuery.getEntity(itemId).playEndedRecord.PlayType; + if (!url || url === '') { + // Too early, fields may be undefined. + return; + } + const translatedData = this.translateToAccessLogItem(itemId, url, varInfo, playType); + if (translatedData) { + const overage = this.accesslog.length - 20; + if (overage > 0) { + this.accesslog.splice(0, overage); // trim access log entries + } + this.accesslog.push(translatedData); + getLogger().trace(loggerName$3, 'accesslog=%o', this.accesslog); + } + // reset accessLogData after we added an entry to the log + this.accessLogData = this.createAccessLogEntry(); + const recordMediaDur = this.rtcQuery.getEntity(itemId).switchCompleteRecord.MediaDur; + this.accessLogData.lastMediaDur = recordMediaDur ? recordMediaDur : this.hls.bufferedDuration; + } + addToErrorLog(itemId, domain) { + var _a; + const entity = (_a = this.rtcQuery) === null || _a === void 0 ? void 0 : _a.getEntity(itemId); + if (!entity) { + return; + } + let code; + if (domain === 'mediaError') { + code = Number(entity.playErrorRecord.ErrCode); + } + else { + // else if (networkError) + code = Number(entity.nwErrorRecord.ErrCode); + } + const errorInfo = { domain, code }; + const url = entity.sessionControlRecord.curLevelUrl; + const translatedData = this.translateToErrorLogItem(itemId, url, errorInfo); + if (translatedData) { + const overage = this.errorlog.length - 20; + if (overage > 0) { + this.errorlog.splice(0, overage); // trim error log entries + } + this.errorlog.push(translatedData); + getLogger().trace(loggerName$3, 'errorlog=%o', this.errorlog); + } + } + getAccessLog(itemId) { + var _a; + const finalAccessLog = this.accesslog.slice(0); // Make a copy of the access log array + const entity = (_a = this.rtcQuery) === null || _a === void 0 ? void 0 : _a.getEntity(itemId); + if (finalAccessLog && entity) { + // Add the current "open" variant entry + const url = entity.sessionControlRecord.curLevelUrl; + if (url && url !== '') { + const varInfo = this.getVariantInfo(itemId); + const translatedData = this.translateToAccessLogItem(itemId, url, varInfo, this.rtcQuery.getEntity(itemId).playEndedRecord.PlayType); + if (translatedData) { + translatedData['c-provisional-entry'] = true; // mark item as incomplete + finalAccessLog.push(translatedData); + } + } + } + return finalAccessLog; + } + get errorLog() { + return this.errorlog; + } + createAccessLogEntry() { + const entry = { + fragmentCnt: 0, + overdue: 0, + startPTS: 0, + obrMax: 0, + obrMin: 0, + audioBytes: 0, + audioDuration: 0, + videoBytes: 0, + videoDuration: 0, + svrAddrChanged: 0, + svrAddr: '', + PlayTimeWC: 0, + ViFrDr: 0, + StallCount: 0, + MediaEngineStallCount: 0, + ADT: 0, + NetBytes: 0, + StartupTime: 0, + OBRMean: 0, + OBRLast: 0, + }; + return entry; + } + convertStringObjectToPrimitive(str) { + // Prevent crashing Netflix because it assumes url is always a valid string + let output; + if (!str) { + output = ''; + } + else if (typeof str === 'object') { + output = str.toString(); + } + else { + output = str; + } + return output; + } + updateSvrAddrStats(url) { + const urlParts = URLToolkit$1.parseURL(url); + if (urlParts && urlParts.netLoc) { + const portLoc = urlParts.netLoc.indexOf(':'); + let svrAddr = portLoc >= 0 ? urlParts.netLoc.slice(0, portLoc) : urlParts.netLoc; + if (svrAddr.startsWith('//')) { + svrAddr = svrAddr.slice(2); + } + if (!this.accessLogData.svrAddr) { + this.accessLogData.svrAddrChanged = 0; + } + else if (svrAddr !== this.accessLogData.svrAddr) { + this.accessLogData.svrAddrChanged++; + } + // server address + this.accessLogData.svrAddr = svrAddr; + } + } + translateToAccessLogItem(itemId, url, varInfo, playType) { + const uri = this.convertStringObjectToPrimitive(url); + this.updateSvrAddrStats(uri); + // accumulated duration of the media downloaded, in seconds + let currentMediaDur = this.rtcQuery.getEntity(itemId).switchCompleteRecord.MediaDur; + if (!currentMediaDur) { + // total data downloaded after seek, or live/last access log entry + currentMediaDur = this.hls.bufferedDuration; + } + if (!currentMediaDur) { + currentMediaDur = 0; + } + const item = { + // User info -- Internal use only. Commented out to prevent leaking project via access log serviceName (com.apple.hlsjs.airplay) + // item['c-client-name'] = this._accessLogReporter.ClientName; + // item['c-service-identifier'] = this._accessLogReporter.ServiceName; + // Server related + uri: uri, + 's-ip': this.accessLogData.svrAddr, + 's-ip-changes': this.accessLogData.svrAddrChanged, + // number of network read requests over WWAN, mediaRequestsWWAN. Not sure if TV is connected via WiFi. + 'sc-wwan-count': -1, + // transfer duration + 'c-transfer-duration': this.accessLogData.ADT, + // number of bytes transferred + bytes: this.accessLogData.NetBytes, + // number of media requests + 'c-total-media-requests': this.accessLogData.fragmentCnt, + // Playback related + // GUID identifies playback session + 'cs-guid': this.accessLogReporter.SessionID, + // start time + 'c-start-time': this.accessLogData.startPTS, + // startup time + 'c-startup-time': this.accessLogData.StartupTime, + // duration watched (in seconds) + 'c-duration-watched': this.accessLogData.PlayTimeWC / 1000, + // number of dropped video frames + 'c-frames-dropped': this.accessLogData.ViFrDr, + // total number of playback stalls encountered + 'c-stalls': this.accessLogData.StallCount + this.accessLogData.MediaEngineStallCount, + // subtract total data downloaded since last access log entry, if available + 'c-duration-downloaded': this.accessLogData.lastMediaDur ? currentMediaDur - this.accessLogData.lastMediaDur : currentMediaDur, + // total number of times the download of the segments took too long + 'c-overdue': this.accessLogData.overdue, + // video trackÃĸâ‚Ŧâ„ĸs average bit rate, in bits per second 'c-avg-video-bitrate' + 'c-avg-video-bitrate': (this.accessLogData.videoBytes * 8) / (this.accessLogData.videoDuration || 1), + // maximum observed segment download bit rate 'c-observed-max-bitrate' + 'c-observed-max-bitrate': this.accessLogData.obrMax, + // minimum observed segment download bit rate 'c-observed-min-bitrate' + 'c-observed-min-bitrate': this.accessLogData.obrMin, + // throughput, in bits per second, required to play the stream, as advertised by the server. + 'sc-indicated-bitrate': varInfo.bandwidth ? varInfo.bandwidth : 0, + // average throughput, in bits per second, required to play the stream, as advertised by the server + 'sc-indicated-avg-bitrate': varInfo.avgBandwidth ? varInfo.avgBandwidth : 0, + // empirical throughput, in bits per second, across all media downloaded. + 'c-observed-bitrate': this.accessLogData.OBRMean, + // bandwidth that caused a switch (up or down) 'c-switch-bitrate' + 'c-switch-bitrate': this.accessLogData.OBRLast, + // mark item as complete + 'c-provisional-entry': false, + }; + // playback type + item['s-playback-type'] = playType; + // audio trackÃĸâ‚Ŧâ„ĸs average bit rate, in bits per second 'c-avg-audio-bitrate' + if (this.accessLogData.audioBytes) { + // don't show this for muxed content + item['c-avg-audio-bitrate'] = (this.accessLogData.audioBytes * 8) / (this.accessLogData.audioDuration || 1); + } + return item; + } + translateToErrorLogItem(itemId, url, errorInfo) { + const uri = this.convertStringObjectToPrimitive(url); + this.updateSvrAddrStats(uri); // extract URL host name to svrAddr attribute + const item = { + date: new Date(), + 'cs-guid': this.accessLogReporter.SessionID + '-' + itemId, + uri: uri, + 's-ip': this.accessLogData.svrAddr, + status: '' + errorInfo.code, + domain: errorInfo.domain, + }; + return item; + } + hasGap(newStartPTS, newEndPTS, oldStartPTS, oldEndPTS) { + if (typeof newStartPTS === 'undefined' || typeof oldStartPTS === 'undefined') { + // ignore initSegment and newly create access log entry + return false; + } + // seek gap is at least 1 second + return newStartPTS - oldEndPTS > 1 || oldStartPTS - newEndPTS > 1; + } + aggregateFragObserverdBitrate(data, fragments, bytes, adt) { + const obr = (bytes * 8) / (adt / 1000); + const obrLast = (data.bytes * 8) / (data.adt / 1000); + const obrMean = obr / fragments; + return { obr: obr, obrLast: obrLast, obrMean: obrMean }; + } + aggregateFragMinMaxBitrate(target, obr) { + if (!target.obrMax || obr > target.obrMax) { + target.obrMax = obr; + } + if (!target.obrMin || obr < target.obrMin) { + target.obrMin = obr; + } + } + getVariantInfo(itemId) { + var _a; + const url = this.rtcQuery.getEntity(itemId).sessionControlRecord.curLevelUrl; + const variantList = (_a = this.rtcQuery.getEntity(itemId).sessionControlRecord.manifestData) === null || _a === void 0 ? void 0 : _a.variantList; + return url && variantList && variantList[url] ? variantList[url] : {}; + } + } + + const loadMediaFragment = (mediaFragment, config, loadPolicy, onProgress, requestServerInfo, extendMaxTTFB) => { + var _a; + const { absoluteUrl, byteRangeOffset, discoSeqNum, keyTagInfo, iframe, isInitSegment } = mediaFragment; + const url = absoluteUrl; + const { method } = keyTagInfo; + const { start, end } = byteRangeOffset; + const loadConfig = getLoadConfig({ url }, loadPolicy); + let byteRangeStart = start; + let byteRangeEnd = end; + let resetIV = false; + let byterange = !isFiniteNumber(start) && !isFiniteNumber(end) ? undefined : byteRangeOffset; + if (method === 'AES-128' && end && (iframe || isInitSegment)) { + // Map fragment encrypted with method 'AES-128', when served with HTTP Range, has the unencrypted size specified in the range. Modify the range to ensure we read the padding bytes as well. + /** + * Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6 + * + * If the encryption METHOD is AES-128 and the Media Segment is part of + * an I-frame Playlist (Section 4.4.3.6) and it has an EXT-X-BYTERANGE + * tag applied to it, special care needs to be taken in loading and + * decrypting the segment, because the resource identified by the URI is + * encrypted in 16-byte blocks from the start of the resource. + * + * The decrypted I-frame can be recovered by first widening its byte + * range, as specified by the EXT-X-BYTERANGE tag, so that it starts and + * ends on 16-byte boundaries from the start of the resource. + * */ + const fragmentLen = end - start; + if (fragmentLen % 16) { + byteRangeEnd = end + (16 - (fragmentLen % 16)); + } + /** + * Next, the byte range is widened further to include a 16-byte block at + * the beginning of the range. This 16-byte block allows the correct IV + * for the following block to be calculated. + * */ + if (start !== 0) { + resetIV = true; + byteRangeStart = start - 16; + } + byterange = { start: byteRangeStart, end: byteRangeEnd }; + } + let collectServerInstanceInfo = undefined; + if (requestServerInfo && isFiniteNumber(mediaFragment.mediaSeqNum) && mediaFragment.mediaOptionType === MediaOptionType.Variant) { + // Sanitize the list + collectServerInstanceInfo = []; + (_a = loadConfig.reportHTTPResponseHeaders) === null || _a === void 0 ? void 0 : _a.forEach(function (header) { + if (privacyAllowedLoadConfigHeaders.includes(header)) { + collectServerInstanceInfo.push(header); + } + else { + getLogger().warn({ name: 'load-media-fragment' }, `${header} is not in approved privacy list. Actions required.`); + } + }); + if (collectServerInstanceInfo.length === 0) { + collectServerInstanceInfo = undefined; + } + } + const context = { + url: url, + byteRangeOffset: byterange, + checkContentLength: true, + extendMaxTTFB: extendMaxTTFB, + collectServerInstanceInfo: collectServerInstanceInfo, + onProgress, + xhrSetup: config.xhrSetup, + }; + return fromUrlArrayBuffer(context, loadConfig).pipe(map(([loadedData, bwSample, serverInfo]) => { + if (resetIV) { + const buf = loadedData; + mediaFragment.keyTagInfo.iv = new Uint8Array(buf.slice(0, 16)); // First 16 bytes -> IV + loadedData = buf.slice(16); // rest is the actual fragment + } + return [mediaFragment, loadedData, bwSample, serverInfo]; + }), convertToFragmentNetworkError(mediaFragment, false)); + }; + + const kKeySystemIdToPropertiesMap = { + clearkey: ClearKeySystemProperties, + fairplaystreaming: FairPlayStreamingKeySystemProperties, + playready: PlayReadyKeySystemProperties, + widevine: WidevineKeySystemProperties, + }; + /** + * Get the EXT-X-KEY:FORMAT value associated with the key system + * @param keySystemId Identifier string to request keyFormatString property for + */ + const KeySystemFactory = { + getKeySystemFormat(keySystemId) { + const properties = kKeySystemIdToPropertiesMap[keySystemId]; + return properties ? properties.keyFormatString : ''; + }, + getKeySystemSecurityLevel(keySystemId) { + const properties = kKeySystemIdToPropertiesMap[keySystemId]; + return properties ? properties.securityLevels : null; + }, + }; + + const decryptmethods = { NONE: '', 'AES-128': '', 'ISO-23001-7': '', 'SAMPLE-AES': '', 'SAMPLE-AES-CTR': '' }; + function isDecryptMethod(tagValue) { + if (!tagValue) { + return false; + } + return tagValue in decryptmethods; + } + + const HdcpLevels = { + NONE: 0, + 'TYPE-0': 1, + 'TYPE-1': 2, + 'TYPE-2': 3, + }; + function isHdcpLevel(x) { + return x in HdcpLevels; + } + function hdcpLevelToInt(hdcpLevel) { + if (hdcpLevel == null) { + return 4; + } + return HdcpLevels[hdcpLevel]; + } + + const SessionDataKey = { + CHAPTER: 'com.apple.hls.chapters', + TITLE: 'com.apple.hls.title', + TITLE_DESCRIPTIONS: 'com.apple.hls.description', + EPISODE_TITLE: 'com.apple.hls.episode-title', + ARTWORK: 'com.apple.hls.poster', + ROTTEN_TOMATOES_RATING: 'com.apple.hls.rt-rating', + ROTTEN_TOMATOES_AUDIENCE_SCORE: 'com.apple.hls.rt-audience-score', + GENRE: 'com.apple.hls.genre', + RELEASE_DATE: 'com.apple.hls.release-date', + CONTENT_RATING_BADGE: 'com.apple.hls.rating-tag', + OTHER_TEXT_BADGES: 'com.apple.hls.other-tags', + FORMAT: 'com.apple.hls.format', + QUALITY: 'com.apple.hls.quality', + ACCESSIBILITY: 'com.apple.hls.accessibility', + }; + const isSessionDataItem = (item) => 'DATA-ID' in item; + + const VideoRangeValues = ['SDR', 'PQ', 'HLG']; + function isVideoRange(vr) { + return vr != null && VideoRangeValues.includes(vr); + } + + /* + * 2018 Apple Inc. All rights reserved. + */ + const bcp47ShortestLangCode = { + afr: 'af', + aka: 'ak', + amh: 'am', + ara: 'ar', + arg: 'an', + asm: 'as', + ava: 'av', + ave: 'ae', + aym: 'ay', + aze: 'az', + bam: 'bm', + bel: 'be', + ben: 'bn', + bih: 'bh', + bod: 'bo', + bos: 'bs', + bre: 'br', + bul: 'bg', + cat: 'ca', + ces: 'cs', + cha: 'ch', + che: 'ce', + chu: 'cu', + chv: 'cv', + cor: 'kw', + cos: 'co', + cre: 'cr', + cym: 'cy', + dan: 'da', + deu: 'de', + div: 'dv', + dzo: 'dz', + ell: 'el', + eng: 'en', + epo: 'eo', + est: 'et', + eus: 'eu', + ewe: 'ee', + fao: 'fo', + fas: 'fa', + fin: 'fi', + fra: 'fr', + fry: 'fy', + ful: 'ff', + gla: 'gd', + gle: 'ga', + glg: 'gl', + glv: 'gv', + grn: 'gn', + guj: 'gu', + hat: 'ht', + heb: 'he', + her: 'hz', + hin: 'hi', + hmo: 'ho', + hrv: 'hr', + hun: 'hu', + hye: 'hy', + ibo: 'ig', + ido: 'io', + iii: 'ii', + iku: 'iu', + ile: 'ie', + ina: 'ia', + ind: 'id', + isl: 'is', + ita: 'it', + jav: 'jv', + jpn: 'ja', + kal: 'kl', + kan: 'kn', + kas: 'ks', + kat: 'ka', + kau: 'kr', + kaz: 'kk', + khm: 'km', + kik: 'ki', + kin: 'rw', + kir: 'ky', + kom: 'kv', + kon: 'kg', + kor: 'ko', + kua: 'kj', + kur: 'ku', + lao: 'lo', + lat: 'la', + lav: 'lv', + lim: 'li', + lit: 'lt', + ltz: 'lb', + lub: 'lu', + lug: 'lg', + mah: 'mh', + mal: 'ml', + mar: 'mr', + mkd: 'mk', + mlg: 'mg', + mlt: 'mt', + mol: 'mo', + mon: 'mn', + mri: 'mi', + msa: 'ms', + mya: 'my', + nav: 'nv', + nbl: 'nr', + nde: 'nd', + ndo: 'ng', + nep: 'ne', + nld: 'nl', + nno: 'nn', + nob: 'nb', + nya: 'ny', + oci: 'oc', + oji: 'oj', + ori: 'or', + orm: 'om', + oss: 'os', + pan: 'pa', + pli: 'pi', + pol: 'pl', + por: 'pt', + pus: 'ps', + que: 'qu', + roh: 'rm', + ron: 'ro', + run: 'rn', + rus: 'ru', + san: 'sa', + sin: 'si', + slk: 'sk', + slv: 'sl', + sme: 'se', + snd: 'sd', + som: 'so', + spa: 'es', + sqi: 'sq', + srd: 'sc', + srp: 'sr', + sun: 'su', + swa: 'sw', + swe: 'sv', + tah: 'ty', + tam: 'ta', + tat: 'tt', + tel: 'te', + tgk: 'tg', + tgl: 'tl', + tha: 'th', + tir: 'ti', + ton: 'to', + tuk: 'tk', + tur: 'tr', + uig: 'ug', + ukr: 'uk', + urd: 'ur', + uzb: 'uz', + ven: 've', + vie: 'vi', + wln: 'wa', + yid: 'yi', + zha: 'za', + zho: 'zh', + }; + const bcp47Utils = { + isLanguageCode(value) { + return value in bcp47ShortestLangCode; + }, + shortenLanguageCode(langTag) { + let shortenedLangTag; + if (langTag) { + const langCodePos = langTag.indexOf('-'); + const langCode = langCodePos >= 0 ? langTag.slice(0, langCodePos) : langTag; + if (bcp47Utils.isLanguageCode(langCode)) { + shortenedLangTag = bcp47ShortestLangCode[langCode]; + } + if (!shortenedLangTag) { + shortenedLangTag = langCode; + } + if (langCodePos > 0) { + const theRest = langTag.slice(langCodePos + 1); + shortenedLangTag += '-' + theRest; + } + } + return shortenedLangTag; + }, + }; + + const RichestMedia = { + getRichestVideoCodec(videoCodecList) { + if (!videoCodecList || !videoCodecList.length) { + return undefined; + } + const sortedCodecs = videoCodecList.sort((codec1, codec2) => getVideoCodecRanking(codec2) - getVideoCodecRanking(codec1)); + return sortedCodecs && sortedCodecs.length ? sortedCodecs[0] : undefined; + }, + getRichestAudioCodec(audioCodecList) { + if (!audioCodecList || !audioCodecList.length) { + return undefined; + } + const sortedCodecs = audioCodecList.sort((codec1, codec2) => getAudioCodecRanking(codec2) - getAudioCodecRanking(codec1)); + return sortedCodecs && sortedCodecs.length ? sortedCodecs[0] : undefined; + }, + getRichestChannelLayoutForGroupId(audioGroupId, audioMediaOptions) { + if (!audioGroupId || !audioMediaOptions || !audioMediaOptions.length) { + return undefined; + } + let channels = undefined; + const tracksforGroupdId = audioMediaOptions.filter((track) => track.groupId === audioGroupId); + if (tracksforGroupdId && tracksforGroupdId.length) { + const sortedTracksForGroupId = tracksforGroupdId.sort((track1, track2) => MediaUtil.getChannelCount(track2.channels) - MediaUtil.getChannelCount(track1.channels)); + if (sortedTracksForGroupId && sortedTracksForGroupId.length) { + channels = sortedTracksForGroupId[0].channels; + } + } + return channels; + }, + }; + + function _formatError(msg) { + return new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.STEERING_MANIFEST_PARSING_ERROR, false, msg, ErrorResponses.FormatError); + } + function validatePathwayID(pathwayID) { + if (typeof pathwayID !== 'string') { + return _formatError('invalid steering manifest PATHWAY-PRIORITY list item data type'); + } + if (!/^[\w\-\.]+$/.test(pathwayID)) { + return _formatError('steering manifest contains invalid pathway ID: ' + pathwayID); + } + return void 0; + } + + /* + * Fragment + * + * 2018 Apple Inc. All rights reserved. + */ + class FragmentBuilder { + // public backtracked?: boolean; + // public dropped?: number; + // public startDTS?: number; + // public startPTS?: number; + // public endDTS?: number; + // public endPTS?: number; + // public deltaPTS?: number; + // public autoLevel?: boolean; + // public bitrateTest?: boolean; + // public loader?: any; // TODO: fix any + // public loadSuccess?: boolean; + // public data?: Uint8Array; + // public iframeMediaStart?: number; + // public iframeMediaDuration?: number; + // public trackId?: number; // used by subtitle-stream-controller, should be moved + // public loaded: number; // used by fragment loader + // public itemId: string; + constructor(inheritQuery) { + this._url = null; + this._programDateTime = null; + this._byteRange = null; + this.relurl = null; + this.baseurl = null; + this.isInitSegment = false; + this.mediaSeqNum = NaN; + this.cc = NaN; + this.iframe = false; + this.bitrate = NaN; + this.start = NaN; + this.duration = NaN; + this.lastByteRangeEndOffset = NaN; + this.inheritQuery = inheritQuery; + this.tagList = new Array(); + this.iframe = false; + } + getMediaFragment(itemId, mediaOptionId, mediaOptionType) { + var _a; + const fragment = { + mediaOptionType, + absoluteUrl: this.url, + start: this.start, + duration: this.duration, + mediaSeqNum: this.mediaSeqNum, + discoSeqNum: this.cc, + mediaOptionId, + itemId, + isLastFragment: false, + isInitSegment: this.isInitSegment, + }; + if ((_a = this.byteRange) === null || _a === void 0 ? void 0 : _a.length) { + fragment.byteRangeOffset = { start: this.byteRangeStartOffset, end: this.byteRangeEndOffset }; + } + if (this.iframe) { + fragment.iframe = this.iframe; + } + if (this.levelkey) { + fragment.keyTagInfo = this.levelkey; + } + if (this.programDateTime) { + fragment.programDateTime = this.programDateTime; + } + return fragment; + } + // static getStartEndString(frag: Fragment) { + // return `[${toFixed(frag.startDTS || frag.start, 3)},${toFixed(frag.endPTS || frag.start + frag.duration, 3)}]`; + // } + /* + * @returns whether this fragment is equivalent to another fragment + */ + // equals(fragInfo: Fragment) { + // return fragInfo.mediaSeqNum === this.mediaSeqNum && fragInfo.levelId === this.levelId; + // } + get url() { + if (!this._url && this.relurl && this.baseurl) { + this._url = URLToolkit$1.buildAbsoluteURL(this.baseurl, this.relurl, { alwaysNormalize: true, inheritQuery: this.inheritQuery }); + } + return this._url; + } + set url(value) { + this._url = value; + } + get programDateTime() { + if (!this._programDateTime && this.rawProgramDateTime) { + this._programDateTime = new Date(Date.parse(this.rawProgramDateTime)); + } + return this._programDateTime; + } + get byteRange() { + if (!this._byteRange) { + const byteRange = new Array(2); + if (this.rawByteRange) { + const params = this.rawByteRange.split('@', 2); + if (params.length === 1) { + const { lastByteRangeEndOffset } = this; + byteRange[0] = lastByteRangeEndOffset ? lastByteRangeEndOffset : 0; + } + else { + byteRange[0] = parseInt(params[1]); + } + byteRange[1] = parseInt(params[0]) + byteRange[0]; + } + this._byteRange = byteRange; + } + return this._byteRange; + } + get byteRangeStartOffset() { + return this.byteRange[0]; + } + get byteRangeEndOffset() { + return this.byteRange[1]; + } + get rangeString() { + if (this.start >= 0 && this.duration >= 0) { + return `${this.start.toFixed(2)}-${(this.start + this.duration).toFixed(2)}`; + } + return 'N/A'; + } + // useful for a consistent logging message tag + get fragTag() { + return `sn/cc/levelId: ${this.mediaSeqNum}/${this.cc}`; + } + } + + const MediaSelectionHelper = { + parseMediaCharacteristics(mediaCharacteristics) { + return mediaCharacteristics ? mediaCharacteristics.split(/\s*,\s*/) : new Array(); + }, + addMediaToSelectionArray(mediaSelectionGroup, mediaEntry, nextPersistentID) { + if (typeof mediaSelectionGroup === 'undefined') { + return -1; + } + const mediaSelectionGroupOptionArray = mediaSelectionGroup.MediaSelectionGroupOptions; + let mediaSelectionOption = mediaSelectionGroupOptionArray.find((mediaSelectionOption) => mediaSelectionOption.MediaSelectionOptionsMediaType === mediaEntry.mediaType && + mediaSelectionOption.MediaSelectionOptionsName === mediaEntry.name && + mediaSelectionOption.MediaSelectionOptionsExtendedLanguageTag === mediaEntry.lang + // TODO: need ISO 639 code - MediaSelectionOptionsLanguageCode + ); + if (!mediaSelectionOption) { + mediaSelectionOption = { + MediaSelectionOptionsMediaType: mediaEntry.mediaType, + MediaSelectionOptionsExtendedLanguageTag: mediaEntry.lang, + MediaSelectionOptionsIsDefault: mediaEntry.default, + MediaSelectionOptionsName: mediaEntry.name, + MediaSelectionOptionsPersistentID: nextPersistentID, + MediaSelectionOptionsTaggedMediaCharacteristics: mediaEntry.characteristics, + }; + if (mediaEntry.mediaType === MediaTypeFourCC.SUBTITLE) { + mediaSelectionOption.MediaSelectionOptionsDisplaysNonForcedSubtitles = mediaEntry.forced ? Allowed.NO : Allowed.YES; + } + nextPersistentID++; // created a new group, increment the next ID + mediaSelectionGroupOptionArray.push(mediaSelectionOption); + } + mediaEntry.persistentID = mediaSelectionOption.MediaSelectionOptionsPersistentID; + return nextPersistentID; + }, + addDefaultClosedCaptionOption(queueItemId, playlistSubtitleTracks, subtitleMediaSelectionGroup, nextPersistentID) { + const mediaEntry = { + // only 1 text track + itemId: queueItemId, + mediaOptionType: MediaOptionType.Subtitle, + id: 0, + mediaOptionId: 'cc1_' + guid(), + mediaType: MediaTypeFourCC.CLOSEDCAPTION, + inStreamID: 'CC1', + groupId: 'cc', + name: 'English-CC', + type: 'CLOSED-CAPTIONS', + default: false, + autoselect: false, + forced: false, + lang: 'en', + // 'public.easy-to-read' is not default in CoreMedia + characteristics: ['public.accessibility.transcribes-spoken-dialog', 'public.accessibility.describes-music-and-sound'], + persistentID: nextPersistentID, + }; + playlistSubtitleTracks.push(mediaEntry); + MediaSelectionHelper.addMediaToSelectionArray(subtitleMediaSelectionGroup, mediaEntry, nextPersistentID); + }, + }; + + const StringTags = { + NAME: '', + TYPE: '', + DEFAULT: '', + AUTOSELECT: '', + FORCED: '', + LANGUAGE: '', + URI: '', + AUDIO: '', + 'VIDEO-RANGE': '', + 'CLOSED-CAPTIONS': '', + CODECS: '', + BYTERANGE: '', + 'INSTREAM-ID': '', + 'GROUP-ID': '', + CHANNELS: '', + CHARACTERISTICS: '', + KEYFORMAT: '', + KEYFORMATVERSIONS: '', + 'DATA-ID': '', + VALUE: '', + METHOD: '', + 'HDCP-LEVEL': '', + 'ALLOWED-CPC': '', + SUBTITLES: '', + // ext-daterange + ID: '', + CLASS: '', + 'START-DATE': '', + 'END-DATE': '', + 'END-ON-NEXT': '', + // content-steering + 'SERVER-URI': '', + 'PATHWAY-ID': '', + }; + const IntegerTags = { + BANDWIDTH: NaN, + 'AVERAGE-BANDWIDTH': NaN, + }; + const FloatTags = { + 'TIME-OFFSET': NaN, + 'FRAME-RATE': NaN, + SCORE: NaN, + 'PLANNED-DURATION': NaN, + DURATION: NaN, + }; + const HexTags = { + IV: null, + }; + const ResolutionTags = { + RESOLUTION: null, + }; + + /* + * 2019 Apple Inc. All rights reserved. + */ + const DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/; + const ATTR_LIST_REGEX = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; + // T is a string union type of keys + // K is the value type + class TagParser { + constructor(validTags) { + this.validTags = validTags; + } + isKey(tag) { + return tag in this.validTags; + } + trySetValue(tag, tagValue, outBag) { + if (this.isKey(tag)) { + outBag[tag] = this.parseFunc(tagValue); + return true; + } + return false; + } + } + class StringTagParser extends TagParser { + parseFunc(tag) { + return tag; + } + } + class IntegerTagParser extends TagParser { + parseFunc(tagValue) { + const parsedValue = parseInt(tagValue); + if (parsedValue > Number.MAX_SAFE_INTEGER) { + return Infinity; + } + return parsedValue; + } + } + class FloatTagParser extends TagParser { + constructor() { + super(...arguments); + this.parseFunc = parseFloat; + } + } + class HexTagParser extends TagParser { + parseFunc(tagValue) { + let stringValue = (tagValue || '0x').slice(2); + stringValue = (stringValue.length & 1 ? '0' : '') + stringValue; + const value = new Uint8Array(stringValue.length / 2); + for (let i = 0; i < stringValue.length / 2; i++) { + const val = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16); + if (!isFiniteNumber(val)) { + return undefined; + } + value[i] = val; + } + return value; + } + } + class ResolutionTagParser extends TagParser { + parseFunc(tagValue) { + const res = DECIMAL_RESOLUTION_REGEX.exec(tagValue); + let resolution; + if (res !== null) { + resolution = { + width: parseInt(res[1], 10), + height: parseInt(res[2], 10), + }; + } + return resolution; + } + } + class PlaylistTagParser { + static parseTags(input) { + let match; + const parsedTags = {}; + if (!input) { + return parsedTags; + } + ATTR_LIST_REGEX.lastIndex = 0; + while ((match = ATTR_LIST_REGEX.exec(input)) !== null) { + const tag = match[1].toUpperCase(), quote = '"'; + let value = match[2]; + if (value.indexOf(quote) === 0 && value.lastIndexOf(quote) === value.length - 1) { + value = value.slice(1, -1); + } + for (const tagParser of PlaylistTagParser.tagParsers) { + if (tagParser.trySetValue(tag, value, parsedTags)) { + break; + } + } + } + return parsedTags; + } + } + PlaylistTagParser.tagParsers = [new StringTagParser(StringTags), new IntegerTagParser(IntegerTags), new FloatTagParser(FloatTags), new HexTagParser(HexTags), new ResolutionTagParser(ResolutionTags)]; + + /* + * Playlist Parser + * + * 2018 Apple Inc. All rights reserved. + */ + // https://regex101.com is your friend + const HlsRegex = { + ExtractVariableParameter: /{\$(.*?)}/g, + LevelPlaylistFast: /#EXTINF:(\d*(?:\.\d+)?)(?:,(.*))?|(?!#)(\S.+)|#EXT-X-BYTERANGE: *(.+)|#EXT-X-PROGRAM-DATE-TIME:(.+)|#EXT-X-BITRATE:(.+)|#EXT-X-DATERANGE:(.+)|#.*/g, + LevelPlaylistSlow: /(?:(?:#(EXTM3U))|(?:#EXT-X-(PLAYLIST-TYPE):(.+))|(?:#EXT-X-(MEDIA-SEQUENCE): *(\d+))|(?:#EXT-X-(TARGETDURATION): *(\d+))|(?:#EXT-X-(KEY):(.+))|(?:#EXT-X-(START):(.+))|(?:#EXT-X-(ENDLIST))|(?:#EXT-X-(DISCONTINUITY-SEQ)UENCE:(\d+))|(?:#EXT-X-(DIS)CONTINUITY))|(?:#EXT-X-(VERSION):(\d+))|(?:#EXT-X-(MAP):(.+))|(?:#EXT-X-(I-FRAMES)-ONLY)|(?:#EXT-X-(DEFINE):(.+))|(?:(#)(.*):(.*))|(?:(#)(.*))(?:.*)\r?\n?/, + MasterPlaylist: /#EXT-X-STREAM-INF:([^\n\r]*)[\r\n]+([^\r\n]+)|#EXT-X-I-FRAME-STREAM-INF:([^\r\n]+)|#EXT-X-DEFINE:([^\n\r]*)|#EXT-X-CONTENT-STEERING:([^\n\r]*)/g, + MasterPlaylistAlternateMedia: /#EXT-X-MEDIA:(.*)/g, + SessionData: /#EXT-X-SESSION-DATA[^:]*:(.*)/g, + SessionKeys: /#EXT-X-SESSION-KEY:([^\n\r]*)/g, + VARIABLE_PLAYLIST_REGEX: /(NAME|VALUE)=\"(.*)\",(NAME|VALUE)=\"(.*)\"|(IMPORT)=\"(.*)\"/, + }; + function resolve(url, baseUrl, inheritQuery) { + return URLToolkit.buildAbsoluteURL(baseUrl, url, { alwaysNormalize: true, inheritQuery }); + } + function tryDecodeBase64Metadata(data) { + let decodedObj; + try { + decodedObj = JSON.parse(NumericEncodingUtils$1.base64DecodeToStr(data)); + } + catch (err) { + // logger.error(`Error ${err} decoding metadata value: '${data}'`); + decodedObj = data; + } + return decodedObj; + } + class PlaylistParser { + static isValidPlaylist(playlist) { + return playlist.indexOf('#EXTM3U') === 0; + } + static isMediaPlaylist(playlist) { + return playlist.indexOf('#EXTINF:') > 0 || playlist.indexOf('#EXT-X-PLAYLIST-TYPE:') > 0; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static replaceVariables(input, variableMap) { + let updatedString, error = false; + if (input && variableMap) { + updatedString = input.replace(HlsRegex.ExtractVariableParameter, (result) => { + HlsRegex.ExtractVariableParameter.lastIndex = 0; + const variable = HlsRegex.ExtractVariableParameter.exec(result); + const property = variable[1]; + // eslint-disable-next-line no-prototype-builtins + if (property && variableMap.hasOwnProperty(property)) { + return variableMap[property]; + } + error = true; + }); + } + return { updatedString, error }; + } + static parseDecryptData(decryptparams, baseurl, keySystemPreference) { + var _a; + const keyAttrs = PlaylistTagParser.parseTags(decryptparams); + const decryptmethod = isDecryptMethod(keyAttrs.METHOD) ? keyAttrs.METHOD : null; + const decryptformat = (_a = keyAttrs.KEYFORMAT) !== null && _a !== void 0 ? _a : null; + if (decryptmethod && PlaylistParser.shouldSelectKeyTag(decryptformat, decryptmethod, keySystemPreference)) { + const decrypturi = keyAttrs.URI; + const decryptiv = keyAttrs.IV ? keyAttrs.IV : null; + if (decrypturi) { + // if there's an IV specified, make sure it's valid + if (keyAttrs.IV && !decryptiv) { + const playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, `Invalid IV: ${keyAttrs.IV}`, ErrorResponses.PlaylistErrorInvalidEntry); + playlistParsingError.url = baseurl; + throw playlistParsingError; + } + } + // do not use inheritQuery on key URIs + const resolvedUri = decrypturi ? URLToolkit.buildAbsoluteURL(baseurl, decrypturi, { alwaysNormalize: true }) : baseurl; + const decryptformatversions = (keyAttrs.KEYFORMATVERSIONS ? keyAttrs.KEYFORMATVERSIONS : '1').split('/').map(Number).filter(isFinite); + return new DecryptData(decryptmethod, resolvedUri, decryptiv, decryptformat, decryptformatversions); + } + } + /* + * Utility method to pick a desired key system based on the app preference, EXT-X-KEY tag values. + */ + static shouldSelectKeyTag(decryptformat, decryptmethod, keySystemPreference) { + // If it's Segment encryption or No encryption, just select that key system + // There is no app preference, so select the key system from the manifest + // Now try to match the app preference with the key system in the manifest + return 'AES-128' === decryptmethod || 'NONE' === decryptmethod || null == keySystemPreference || decryptformat === KeySystemFactory.getKeySystemFormat(keySystemPreference); + } + static optOutClosedCaption(levels) { + let noClosedCaption = false; + let hasVideo = false; + if (levels) { + // may be null for playlist with 1 audio only track + for (let i = 0; i < levels.length; ++i) { + const levelInfo = levels[i]; + if (levelInfo.videoCodec) { + hasVideo = true; + if (levelInfo.iframes !== true && levelInfo.closedcaption && levelInfo.closedcaption.toLowerCase() === 'none') { + noClosedCaption = true; // 'CLOSED-CAPTION=NONE' must be present in all levels if it exists in one. + break; + } + } + } + } + return !hasVideo || noClosedCaption; + } + static parseRootPlaylistAlternateMediaOptions(queueItemId, playlist, baseurl, levels, inheritQuery, masterVariableList) { + let result; + let playlistParsingError; + const audioMediaSelectionGroup = { + MediaSelectionGroupAllowEmptySelection: 1, + MediaSelectionGroupMediaCharacteristics: ['public.audible'], + MediaSelectionGroupMediaType: MediaTypeFourCC.AUDIO, + MediaSelectionGroupOptions: [], + }; + const subtitleMediaSelectionGroup = { + MediaSelectionGroupAllowEmptySelection: 1, + MediaSelectionGroupMediaCharacteristics: ['public.legible'], + MediaSelectionGroupMediaType: MediaTypeFourCC.SUBTITLE, + MediaSelectionGroupOptions: [], + }; + const alternateMediaInfo = { + videoAlternateOptions: [], + audioAlternateOptions: [], + subtitleAlternateOptions: [], + audioMediaSelectionGroup, + subtitleMediaSelectionGroup, + }; + let nextPersistentID = 0; + HlsRegex.MasterPlaylistAlternateMedia.lastIndex = 0; + while ((result = HlsRegex.MasterPlaylistAlternateMedia.exec(playlist)) != null) { + const updatedAttrList = PlaylistParser.replaceVariables(result[1], masterVariableList); + if (updatedAttrList.error) { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.LEVEL_LOAD_ERROR, true, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE.text, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE); + break; + } + const attrs = PlaylistTagParser.parseTags(updatedAttrList.updatedString); + let mediaType = MediaTypeFourCC.UNKNOWN; + let inStreamID; + let trackArray; + let mediaSelectionGroup; + const characteristics = MediaSelectionHelper.parseMediaCharacteristics(attrs.CHARACTERISTICS); + const groupId = attrs['GROUP-ID']; + const channels = attrs.CHANNELS; + let groupCodecList; + let mediaOptionType = null; + switch (attrs.TYPE) { + case 'VIDEO': + mediaType = MediaTypeFourCC.VIDEO; + // mediaOptionType = TODO + trackArray = alternateMediaInfo.videoAlternateOptions; + // no selection options yet + break; + case 'AUDIO': + mediaType = MediaTypeFourCC.AUDIO; + mediaOptionType = MediaOptionType.AltAudio; + trackArray = alternateMediaInfo.audioAlternateOptions; + mediaSelectionGroup = audioMediaSelectionGroup; + const matchingLevel = levels.find((level) => level.audioGroupId === groupId); + groupCodecList = matchingLevel ? matchingLevel.audioCodecList : []; + break; + case 'SUBTITLES': + mediaType = MediaTypeFourCC.SUBTITLE; + mediaOptionType = MediaOptionType.Subtitle; + trackArray = alternateMediaInfo.subtitleAlternateOptions; + mediaSelectionGroup = subtitleMediaSelectionGroup; + break; + case 'CLOSED-CAPTIONS': + mediaType = MediaTypeFourCC.CLOSEDCAPTION; + mediaOptionType = MediaOptionType.Subtitle; + inStreamID = attrs['INSTREAM-ID']; + trackArray = alternateMediaInfo.subtitleAlternateOptions; + mediaSelectionGroup = subtitleMediaSelectionGroup; + break; + } + const mediaEntry = { + itemId: queueItemId, + mediaOptionType, + mediaType, + groupId, + channels, + groupCodecList, + name: attrs.NAME, + type: attrs.TYPE, + default: attrs.DEFAULT === 'YES', + autoselect: attrs.AUTOSELECT === 'YES', + forced: attrs.FORCED === 'YES', + characteristics, + persistentID: nextPersistentID, + id: trackArray ? trackArray.length : 0, + mediaOptionId: `${attrs.NAME}_${groupId}_${nextPersistentID}`, + lang: bcp47Utils.shortenLanguageCode(attrs.LANGUAGE), + }; + if (attrs.URI) { + mediaEntry.url = resolve(attrs.URI, baseurl, inheritQuery); + } + if (!mediaEntry.name) { + mediaEntry.name = mediaEntry.lang; + if (mediaEntry.mediaType === MediaTypeFourCC.CLOSEDCAPTION) { + mediaEntry.name += ' CC'; + } + } + if (mediaEntry.mediaType === MediaTypeFourCC.CLOSEDCAPTION && inStreamID) { + mediaEntry.inStreamID = inStreamID; + } + if (trackArray) { + mediaEntry.id = trackArray.length; + trackArray.push(mediaEntry); + } + nextPersistentID = MediaSelectionHelper.addMediaToSelectionArray(mediaSelectionGroup, mediaEntry, nextPersistentID); + } + if (alternateMediaInfo.subtitleAlternateOptions.length === 0 && !PlaylistParser.optOutClosedCaption(levels)) { + MediaSelectionHelper.addDefaultClosedCaptionOption(queueItemId, alternateMediaInfo.subtitleAlternateOptions, subtitleMediaSelectionGroup, nextPersistentID); + } + return { alternateMediaInfo, playlistParsingError }; + } + static parseMediaOptionPlaylist(playlist, baseurl, inheritQuery = true, keySystemPreference, masterVariableList, itemId, mediaOptionId, mediaOptionType, logger, fragStartTime = 0, // itemStartOffset + iFrameStreamInf = false) { + var _a, _b; + let currentSN = 0; + let totalduration = 0; + const levelDetails = { + itemId, + mediaOptionId, + mediaOptionType, + type: '', + version: 0, + url: baseurl, + initSegments: {}, + fragments: [], + liveOrEvent: true, + startSN: 0, + endSN: 0, + iframesOnly: iFrameStreamInf, + targetduration: 0, + totalduration: 0, + averagetargetduration: 0, + ptsKnown: false, + }; + let decryptData = new DecryptData('NONE', baseurl, null, null, null); + let isKeySystemSelected = false; + let isEncrypted = false; + let cc = 0; + let prevFrag = null; + let frag = new FragmentBuilder(inheritQuery); + let result; + let ix; + let activeBitrate = 0; + let lastProgramDateTime; // Latest unmatched PROGRAM-DATE-TIME tag + const tempVariableList = {}; + let unprocessedRelURL; + let playlistParsingError; + let prevInitSegment; + let ensureMapForDiscontinuity = true; + let ensureMapRefresh = true; + HlsRegex.LevelPlaylistFast.lastIndex = 0; + const incompatibleAssetError = () => new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, 'Invalid key system preference for the playlist', ErrorResponses.IncompatibleAsset); + while ((result = HlsRegex.LevelPlaylistFast.exec(playlist)) !== null) { + const duration = result[1]; + if (duration) { + // INF + frag.duration = parseFloat(duration); + // avoid sliced strings https://github.com/video-dev/hls.js/issues/939 + const title = (' ' + result[2]).slice(1); + frag.title = title ? title : null; + frag.tagList.push(title ? ['INF', duration, title] : ['INF', duration]); + } + else if (result[3]) { + // url + if (isFiniteNumber(frag.duration)) { + const sn = currentSN++; + // frag.type = type; + frag.start = totalduration + fragStartTime; + frag.levelkey = decryptData; + if (isEncrypted && !isKeySystemSelected) { + playlistParsingError = incompatibleAssetError(); + break; + } + // The decrypt data has been associated with the fragment, reset the key system selected flag. + // So that if the key changes for the future segments, we can select it. + isKeySystemSelected = false; + isEncrypted = false; + frag.mediaSeqNum = sn; + // frag.levelId = levelId; // persistent level id + frag.cc = cc; + frag.iframe = levelDetails.iframesOnly; + frag.baseurl = baseurl; + // avoid sliced strings https://github.com/video-dev/hls.js/issues/939 + unprocessedRelURL = PlaylistParser.replaceVariables((' ' + result[3]).slice(1), tempVariableList); + if (unprocessedRelURL.error) { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.LEVEL_LOAD_ERROR, true, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE.text, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE); + break; + } + frag.relurl = unprocessedRelURL.updatedString; + // bitrate for fragment + frag.bitrate = isFiniteNumber(frag.byteRangeEndOffset) ? ((frag.byteRangeEndOffset - frag.byteRangeStartOffset) * 8) / frag.duration : activeBitrate; + if (lastProgramDateTime != null) { + frag.rawProgramDateTime = lastProgramDateTime; + frag.tagList.push(['PROGRAM-DATE-TIME', frag.rawProgramDateTime]); + const dt = frag.programDateTime.getTime(); + levelDetails.programDateTimeMap = (_a = levelDetails.programDateTimeMap) !== null && _a !== void 0 ? _a : {}; + levelDetails.programDateTimeMap[dt] = frag.mediaSeqNum; + levelDetails.dateMediaTimePairs = (_b = levelDetails.dateMediaTimePairs) !== null && _b !== void 0 ? _b : []; + levelDetails.dateMediaTimePairs.push([dt, frag.start]); + lastProgramDateTime = undefined; + } + levelDetails.fragments.push(frag.getMediaFragment(itemId, mediaOptionId, mediaOptionType)); + prevFrag = frag; + totalduration += frag.duration; + // implicit init segment for iframes or after a discontinuity + if (ensureMapForDiscontinuity || !levelDetails.initSegments[cc] || ensureMapRefresh) { + if (levelDetails.iframesOnly && frag.byteRangeStartOffset > 0 && !levelDetails.initSegments[cc] && !ensureMapRefresh) { + const ifrag = new FragmentBuilder(inheritQuery); + ifrag.url = frag.url; + // allow the init segment to be up to 7 * 188 (must be multiples of 188) + ifrag.rawByteRange = Math.min(frag.byteRangeStartOffset, 1316) + '@0'; + ifrag.baseurl = baseurl; + // ifrag.levelId = levelId; + // ifrag.type = type; + ifrag.isInitSegment = true; + ifrag.cc = cc; + ifrag.levelkey = decryptData; + ifrag.iframe = true; + if (isEncrypted && !isKeySystemSelected) { + playlistParsingError = incompatibleAssetError(); + break; + } + // The decrypt data has been associated with the fragment, reset the key system selected flag. + // So that if the key changes for the future segments, we can select it. + isKeySystemSelected = false; + isEncrypted = false; + levelDetails.initSegments[cc] = ifrag.getMediaFragment(itemId, mediaOptionId, mediaOptionType); + logger.info(`generated implicit initSegment in cc ${cc}`); + } + else if (prevInitSegment) { + if (isFiniteNumber(prevInitSegment.discoSeqNum)) { + // use the last cc's *declared* initSegment (for fmp4 when MAP for a discontinuity is not defined) + logger.info(`assume initSegment from ${prevInitSegment.discoSeqNum} in cc ${cc}`); + } + // deferred assignment of cc + prevInitSegment.discoSeqNum = cc; + levelDetails.initSegments[cc] = prevInitSegment; + } + } + ensureMapForDiscontinuity = false; + ensureMapRefresh = false; + frag = new FragmentBuilder(inheritQuery); + } + } + else if (result[4]) { + // X-BYTERANGE + frag.rawByteRange = (' ' + result[4]).slice(1); + if (prevFrag) { + const lastByteRangeEndOffset = prevFrag.byteRangeEndOffset; + if (lastByteRangeEndOffset) { + frag.lastByteRangeEndOffset = lastByteRangeEndOffset; + } + } + } + else if (result[5]) { + // PROGRAM-DATE-TIME + // avoid sliced strings https://github.com/video-dev/hls.js/issues/939 + lastProgramDateTime = (' ' + result[5]).slice(1); + } + else if (result[6]) { + // X-BITRATE + // Note that we assume that if this tag exists in the playlist then it should exist for every fragment + const parsedBitrate = parseInt(result[6]); + if (isFiniteNumber(parsedBitrate)) { + activeBitrate = parsedBitrate * 1000; + } + } + else if (result[7]) { + // DATERANGE + const rawDaterange = result[7]; + const daterangeTags = PlaylistTagParser.parseTags(rawDaterange); + if (daterangeTags.ID) { + if (!levelDetails.daterangeTags) { + levelDetails.daterangeTags = {}; + } + levelDetails.daterangeTags[daterangeTags.ID] = daterangeTags; + } + } + else { + result = result[0].match(HlsRegex.LevelPlaylistSlow); + for (ix = 1; ix < result.length; ix++) { + if (result[ix] !== undefined) { + break; + } + } + // avoid sliced strings https://github.com/video-dev/hls.js/issues/939 + const unprocessedValue1 = PlaylistParser.replaceVariables((' ' + result[ix + 1]).slice(1), tempVariableList); + const unprocessedValue2 = PlaylistParser.replaceVariables((' ' + result[ix + 2]).slice(1), tempVariableList); + if (unprocessedValue1.error || unprocessedValue2.error) { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.LEVEL_LOAD_ERROR, true, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE.text, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE); + break; + } + const value1 = unprocessedValue1.updatedString; + const value2 = unprocessedValue2.updatedString; + switch (result[ix]) { + case '#': + frag.tagList.push(value2 ? [value1, value2] : [value1]); + break; + case 'PLAYLIST-TYPE': + levelDetails.type = value1.toUpperCase(); + if (levelDetails.type === 'VOD') { + levelDetails.liveOrEvent = false; + } + break; + case 'MEDIA-SEQUENCE': + if (levelDetails.fragments.length === 0) { + currentSN = levelDetails.startSN = parseInt(value1); + } + break; + case 'TARGETDURATION': + levelDetails.targetduration = parseFloat(value1); + break; + case 'VERSION': + levelDetails.version = parseInt(value1); + break; + case 'EXTM3U': + break; + case 'ENDLIST': + levelDetails.liveOrEvent = false; + break; + case 'DIS': + cc++; + frag.tagList.push(['DIS']); + ensureMapForDiscontinuity = true; + break; + case 'DISCONTINUITY-SEQ': + cc = parseInt(value1); + break; + case 'KEY': + // https://tools.ietf.org/html/draft-pantos-http-live-streaming-08#section-3.4.4 + const decryptparams = value1; + isEncrypted = true; + if (!isKeySystemSelected) { + try { + decryptData = PlaylistParser.parseDecryptData(decryptparams, baseurl, keySystemPreference); + } + catch (error) { + playlistParsingError = error; + } + if (decryptData) { + // Now mark that the key system has been selected. No more playing around with decryptData + isKeySystemSelected = true; + } + } + // if (!isKeySystemSelected || !decryptData) { + // logger.warn(`[Keys] Not selecting EXT-X-KEY tag : ${decryptparams}, IsKeySystemSelected: ${isKeySystemSelected}`); + // } + break; + case 'START': + const startParams = value1; + const startAttrs = PlaylistTagParser.parseTags(startParams); + const startTimeOffset = startAttrs['TIME-OFFSET']; + // TIME-OFFSET can be 0 + if (isFiniteNumber(startTimeOffset)) { + levelDetails.startTimeOffset = startTimeOffset; + } + break; + case 'I-FRAMES': + levelDetails.iframesOnly = true; + break; + case 'MAP': + const mapAttrs = PlaylistTagParser.parseTags(value1); + frag.relurl = mapAttrs.URI; + frag.rawByteRange = mapAttrs.BYTERANGE; + frag.baseurl = baseurl; + // frag.levelId = levelId; + frag.isInitSegment = true; + frag.levelkey = decryptData; // TODO: handle MAP before KEY + if (isEncrypted && !isKeySystemSelected) { + playlistParsingError = incompatibleAssetError(); + break; + } + // The decrypt data has been associated with the fragment, reset the key system selected flag. + // So that if the key changes for the future segments, we can select it. + isKeySystemSelected = false; + isEncrypted = false; + // The occurence of map indicates that it applies to all + // media fragments that follows until the next map. The + // DISCONTINUITY tag can come before or after or never + // relative to MAP tag. + // Common Scenario DISCO -> MAP -> FRAGMENT1 -> Fragment 2 + // Uncommon Scenario Map -> Disco -> FRAGMENTS (live case) + // Defer insertion into initSegments[cc] until media + // fragments are seen + prevInitSegment = frag.getMediaFragment(itemId, mediaOptionId, mediaOptionType); + ensureMapRefresh = true; + // logger.info(`creating new initSegment`); + frag = new FragmentBuilder(inheritQuery); + break; + case 'DEFINE': + const defineList = HlsRegex.VARIABLE_PLAYLIST_REGEX.exec(value1); + const name = 'NAME' === defineList[1] ? defineList[2] : defineList[4], value = 'VALUE' === defineList[1] ? defineList[2] : defineList[4], importName = defineList[5], importValue = defineList[6]; + // eslint-disable-next-line no-prototype-builtins + if (!name && !value && importName === 'IMPORT' && masterVariableList.hasOwnProperty(importValue)) { + tempVariableList[importValue] = masterVariableList[importValue]; + // eslint-disable-next-line no-prototype-builtins + } + else if (name && !importName && defineList[1] !== defineList[3] && !tempVariableList.hasOwnProperty(name)) { + tempVariableList[name] = value; + } + else { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, ErrorResponses.PlaylistErrorMissingImportReference.text, ErrorResponses.PlaylistErrorMissingImportReference); + break; + } + break; + } + } + // frag.itemId = this.itemId; + } + frag = prevFrag; + // logger.info('found ' + levelDetails.fragments.length + ' fragments'); + if (frag && !frag.relurl) { + levelDetails.fragments.pop(); + totalduration -= frag.duration; + } + if (!levelDetails.liveOrEvent && levelDetails.fragments.length > 0) { + levelDetails.fragments[levelDetails.fragments.length - 1].isLastFragment = true; + } + levelDetails.totalduration = totalduration; + levelDetails.averagetargetduration = totalduration / levelDetails.fragments.length; + levelDetails.endSN = currentSN - 1; + return { mediaOptionDetails: levelDetails, playlistParsingError }; + } + static parseRootPlaylist(queueItemId, playlist, baseurl, inheritQuery) { + var _a; + const levelArray = []; + const masterVariableList = {}; + let contentSteeringOption = null; + let result; + let updatedURI; + let updatedAttrList; + let playlistParsingError; + let scoreAvailable = true; + HlsRegex.MasterPlaylist.lastIndex = 0; + while ((result = HlsRegex.MasterPlaylist.exec(playlist)) != null) { + // result[4] -> regex capture group 4, i.e. EXT-X-DEFINE + if (result[4]) { + // result[1] -> NAME/VALUE keyword, result[2] -> value of result[1], result[3] -> NAME/VALUE keyword, + // result[4] -> value of result[3], result[5] -> IMPORT keyword, result[6] -> value of IMPORT + result = HlsRegex.VARIABLE_PLAYLIST_REGEX.exec(result[4]); + const name = result[1] === 'NAME' ? result[2] : result[4], value = result[1] === 'VALUE' ? result[2] : result[4], importName = result[5]; + // eslint-disable-next-line no-prototype-builtins + if (name && !masterVariableList.hasOwnProperty(name) && !importName && result[1] !== result[3]) { + masterVariableList[name] = value; + } + else { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE.text, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE); + break; + } + } + else if (result[5]) { + // result[5] -> regex capture group 5, i.e. EXT-X-CONTENT-STEERING + const updatedAttrList = PlaylistParser.replaceVariables(result[5], masterVariableList); + if (updatedAttrList.error) { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE.text, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE); + break; + } + const attrs = PlaylistTagParser.parseTags(updatedAttrList.updatedString); + if (typeof attrs['SERVER-URI'] !== 'string') { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, ErrorResponses.PlaylistErrorInvalidSERVERURI.text, ErrorResponses.PlaylistErrorInvalidSERVERURI); + break; + } + if (attrs['PATHWAY-ID'] != null && typeof attrs['PATHWAY-ID'] !== 'string') { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, ErrorResponses.PlaylistErrorInvalidPATHWAYID.text, ErrorResponses.PlaylistErrorInvalidPATHWAYID); + break; + } + contentSteeringOption = { + serverURI: resolve(attrs['SERVER-URI'], baseurl, false), + initPathwayID: attrs['PATHWAY-ID'] || '.', + }; + } + else { + // result[1] -> regex capture group 1, i.e. EXT-X-STREAM-INF + // otherwise, result[3] -> regex capture group 3, i.e. EXT-X-I-FRAME-STREAM-INF + updatedAttrList = PlaylistParser.replaceVariables(result[1] || result[3], masterVariableList); + const attrs = PlaylistTagParser.parseTags(updatedAttrList.updatedString); + // result[2] -> regex capture group 2, i.e. URI to be read from the new line (for EXT-X-STREAM-INF) + // otherwise, arrts.URI -> URI to be read from the attributes (for EXT-X-I-FRAME-STREAM-INF) + updatedURI = PlaylistParser.replaceVariables(result[2] || attrs.URI, masterVariableList); + if (updatedAttrList.error || updatedURI.error) { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE.text, ErrorResponses.PlaylistErrorInvalidEXTXDEFINE); + break; + } + if ((attrs.SCORE !== undefined && !isFiniteNumber(attrs.SCORE)) || attrs.SCORE < 0) { + playlistParsingError = new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, ErrorResponses.PlaylistErrorInvalidSCORE.text, ErrorResponses.PlaylistErrorInvalidSCORE); + scoreAvailable = false; + break; + // if SCORE attribute is missing in any level, default to bandwidth + } + else if (scoreAvailable && attrs.SCORE === undefined) { + // logger.warn('SCORE attribute missing in one of the levels, defaulting to bandwidth selection'); + scoreAvailable = false; + } + const bandwidth = attrs.BANDWIDTH; + const avgBandwidth = attrs['AVERAGE-BANDWIDTH']; + const bitrate = avgBandwidth || bandwidth; + const videoRange = (_a = attrs['VIDEO-RANGE']) !== null && _a !== void 0 ? _a : 'SDR'; + if (!isVideoRange(videoRange)) { + // Skip this one. + continue; + } + // Note this is different from audio persistentId; this is an arbitrarily calculated value based on bitrate and index + const mediaOptionId = `level_${(bitrate || 0) + (levelArray.length % 1000) / 1000}`; + const levelInfo = { + itemId: queueItemId, + mediaOptionId, + mediaOptionType: MediaOptionType.Variant, + attrs, + url: resolve(updatedURI.updatedString, baseurl, inheritQuery), + name: attrs.NAME, + audioGroupId: attrs.AUDIO, + subtitleGroupId: attrs.SUBTITLES, + iframes: !!result[3], + bandwidth, + avgBandwidth, + bitrate, + videoRange, + frameRate: attrs['FRAME-RATE'], + allowedCPCMap: PlaylistParser.parseAllowedCPC(attrs['ALLOWED-CPC']), + closedcaption: attrs['CLOSED-CAPTIONS'], + levelCodec: attrs.CODECS, + score: attrs.SCORE, + pathwayID: attrs['PATHWAY-ID'] || '.', + }; + const hdcpString = attrs['HDCP-LEVEL']; + if (isHdcpLevel(hdcpString)) { + levelInfo.hdcpLevel = hdcpString; + } + const resolution = attrs.RESOLUTION; + if (resolution) { + levelInfo.width = resolution.width; + levelInfo.height = resolution.height; + } + if (attrs.CODECS) { + levelInfo.videoCodecList = new Array(); + levelInfo.audioCodecList = new Array(); + const codecs = attrs.CODECS.split(/[ ,]+/); + const { length } = codecs; + for (let i = 0; i < length; i++) { + const codec = codecs[i]; + const prefix = codec.slice(0, 4); + switch (prefix) { + case 'avc1': + levelInfo.videoCodec = MediaUtil.avc1toavcoti(codec); + levelInfo.videoCodecList.push(levelInfo.videoCodec); + break; + case 'avc3': + case 'dvav': + case 'dva1': + // HEVC + case 'hev1': // eslint-disable-line + case 'hvc1': + case 'dvh1': + case 'dvhe': + case 'vp09': + levelInfo.videoCodec = codec; + levelInfo.videoCodecList.push(levelInfo.videoCodec); + break; + case 'mp4a': + case 'ec-3': + case 'ac-3': + levelInfo.audioCodec = codec; + levelInfo.audioCodecList.push(levelInfo.audioCodec); + break; + default: + // logger.warn(`Unrecognized codec ${codec}`); + levelInfo.audioCodec = codec; // Just set it to whatever, maybe it will work. + levelInfo.audioCodecList.push(levelInfo.audioCodec); + break; + } + } + if (levelInfo.audioCodecList.length > 1) { + levelInfo.audioCodec = RichestMedia.getRichestAudioCodec(levelInfo.audioCodecList); + } + if (levelInfo.videoCodecList.length > 1) { + levelInfo.videoCodec = RichestMedia.getRichestVideoCodec(levelInfo.videoCodecList); + } + } + if ((playlistParsingError = validatePathwayID(levelInfo.pathwayID)) != null) { + break; + } + levelArray.push(levelInfo); + } + } + return { variantMediaOptions: levelArray, contentSteeringOption, masterVariableList, playlistParsingError, scoreAvailable }; + } + /** + * Encryption Stuff + */ + static parseAllowedCPC(allowedCPCString) { + if (typeof allowedCPCString !== 'string') { + return null; + } + const allowedCPCMap = {}; + allowedCPCString.split(',').forEach((keyFormatToCPCListStr) => { + const splitList = keyFormatToCPCListStr.split(':'); + let keyFormat, cpcStr; + if (splitList.length === 2) { + // The keyformat + keyFormat = splitList[0].trim(); + cpcStr = splitList[1].trim(); + } + else if (splitList.length > 2) { + cpcStr = splitList[splitList.length - 1].trim(); + splitList.pop(); + keyFormat = splitList.join(':'); + } + else { + return; + } + if (keyFormat in allowedCPCMap) { + return; + } + let cpcLabels = new Array(); + if (cpcStr !== '') { + cpcLabels = cpcStr.split('/').map((cpcLabel) => cpcLabel.trim()); + } + allowedCPCMap[keyFormat] = cpcLabels; + }); + return allowedCPCMap; + } + static parseSessionKeys(playlist, baseurl, keySystemPreference) { + let result; + const sessionKeys = []; + HlsRegex.SessionData.lastIndex = 0; + while ((result = HlsRegex.SessionKeys.exec(playlist))) { + try { + const decryptData = PlaylistParser.parseDecryptData(result[1], baseurl, keySystemPreference); + if (decryptData && decryptData.isEncrypted) { + sessionKeys.push(decryptData); + } + } + catch (error) { + // PlaylistParsingError: "Invalid IV..." + } + } + return sessionKeys; + } + //#region session data + static parseSessionData(sessionDataString, baseurl) { + let result; + const sessionDataItemList = []; + const existingItems = new Set(); + HlsRegex.SessionData.lastIndex = 0; + while ((result = HlsRegex.SessionData.exec(sessionDataString)) != null) { + const attrs = PlaylistTagParser.parseTags(result[1]); + attrs.LANGUAGE = bcp47Utils.shortenLanguageCode(attrs.LANGUAGE); + const uniqueKey = attrs.LANGUAGE ? attrs['DATA-ID'] + '|' + attrs.LANGUAGE : undefined; + if (isSessionDataItem(attrs)) { + if (!uniqueKey || !existingItems.has(uniqueKey)) { + // Prevent duplicated DATA-ID & LANGUAGE pair. + // If LANGUAGE is absent, duplicated DATA-ID items may be okay. + if (attrs['DATA-ID'] === SessionDataKey.OTHER_TEXT_BADGES) { + attrs.VALUE = tryDecodeBase64Metadata(attrs.VALUE); + } + sessionDataItemList.push(attrs); + if (uniqueKey) { + existingItems.add(uniqueKey); + } + } + } + else { + const logger = getLogger(); + logger.error(`Error processing DATA-ID ${attrs['DATA-ID']} and LANGUAGE ${attrs.LANGUAGE}`); + } + } + const sessionData = { + itemList: sessionDataItemList, + baseUrl: baseurl, + }; + return sessionData; + } + } + //#endregion session data + var PlaylistParser$1 = PlaylistParser; + + const fromUrlText = (requestCtx, loadConfig, extendMaxTTFB) => { + const ctx = Object.assign(Object.assign({}, requestCtx), { method: 'GET', responseType: 'text', extendMaxTTFB: extendMaxTTFB }); + const url = ctx.url; + if (isCustomUrl(url)) { + const customUrlLoader = getCustomUrlLoader(); + return customUrlLoader.load(ctx, loadConfig).pipe(map((res) => { + const responseText = res.data.response.data.toString(); + return { + responseText, + responseURL: res.data.response.uri, + stats: res.stats, + }; + })); + } + else { + return fromXMLHttpRequest(ctx, loadConfig).pipe(map(([xhr, stats]) => ({ + responseText: xhr.responseText, + responseURL: xhr.responseURL, + stats: stats, + }))); + } + }; + + const loadMediaOptionDetails = (mediaOption, itemStartOffset, config, loadPolicy, logger, keySystemPreference, statsService, masterVariableList, extendMaxTTFB) => { + const { url, itemId, mediaOptionId, mediaOptionType, iframes = false } = mediaOption; + const loadConfig = getLoadConfig(mediaOption, loadPolicy); + return fromUrlText({ url, xhrSetup: config.xhrSetup }, loadConfig, extendMaxTTFB).pipe(map(({ responseText: rawPlaylist, responseURL: rURL, stats }) => { + logger.debug(`media playlist url: ${url}, baseUrl: ${rURL}`); + if (!rURL) { + logger.warn('Missing response url. Reusing request url as base url'); + rURL = url; + } + const t1 = performance.now(); + const parsed = PlaylistParser.parseMediaOptionPlaylist(rawPlaylist, rURL, true, keySystemPreference, masterVariableList, itemId, mediaOptionId, mediaOptionType, logger, itemStartOffset, iframes); + updatePlaylistAttributes(parsed.mediaOptionDetails); + const t2 = performance.now(); + const { mediaOptionDetails } = parsed; + const playlistSample = { + playlistLoadTimeMs: stats.tload - stats.trequest, + playlistParseTimeMs: t2 - t1, + }; + statsService.setPlaylistSample(playlistSample); + const results = { mediaOptionDetails, stats }; + return results; + }), convertToPlaylistNetworkError(mediaOptionType, mediaOptionId, false, url)); + }; + + const decryptMediaFragment = (mediaFragment, data, config, logger, crypto) => { + return of(data).pipe(switchMap((data) => { + const { keyTagInfo, isInitSegment, iframe, byteRangeOffset } = mediaFragment; + const { method } = keyTagInfo; + const { start, end } = byteRangeOffset; + if (method === 'AES-128') { + if (keyTagInfo.uri && !keyTagInfo.iv && (!keyTagInfo.format || keyTagInfo.format === 'identity')) { + keyTagInfo.iv = createInitializationVector(mediaFragment.mediaSeqNum); + } + const cipherText = data; + const key = keyTagInfo.key.buffer; + const iv = keyTagInfo.iv.buffer; + // For Iframes and Initsegments, byterange indicates the plainText length - ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6 + // For media segments, byterange indicates the length of the cipherText, and the decrypt method will remove the padding to recover the plainText length + const plainTextLength = end && (iframe || isInitSegment) ? end - start : undefined; + /* WebCrypto is the default choice. However, we use JSCrypto in the following scenarios. + 1. WebCrypto disabled via config. + 2. Due to [rdar://73772133], Iframes or Initsegment served via byte-ranges. + */ + const useJSCrypto = !config.enableWebCrypto || !!plainTextLength; + const keyCopy = key.slice(0); // Copy the Key and IV for the webworker. + const ivCopy = iv.slice(0); // Copy the Key and IV for the webworker. + const options = { useJSCrypto, plainTextLength }; + return crypto.decrypt(keyCopy, ivCopy, 'AES-CBC', cipherText, options); + } + else { + // If method is not AES-128, just return the original buffer + return of(data); + } + })); + }; + /** + * Utility method to create an initialization vector from integer + * @param ivValue 128-bit unsigned int representing initialization vector + * @returns {Uint8Array} Buffer representation of the IV + */ + function createInitializationVector(ivValue) { + const uint8View = new Uint8Array(16); + for (let i = 12; i < 16; i++) { + uint8View[i] = (ivValue >> (8 * (15 - i))) & 255; + } + return uint8View; + } + + function fragIsInDetails(details, parsedFrag) { + const fragments = details.fragments; + const fragIdx = parsedFrag.mediaSeqNum - details.startSN; + return fragIdx >= 0 && fragIdx < details.fragments.length && fragEqual(parsedFrag, fragments[fragIdx]); + } + /** + * Update fragment lookup table + */ + function updateFragPTSDTS(details, parsedFrag, startOffset, iframeMode, cpyModified = false, forceUpdateAll = false) { + if (!fragIsInDetails(details, parsedFrag)) { + return; + } + const fragIdx = parsedFrag.mediaSeqNum - details.startSN; + let fragments = details.fragments; + let frag = fragments[fragIdx]; + const { startDtsTs, startPts, endPts } = parsedFrag; + if (cpyModified) { + fragments = details.fragments = details.fragments.slice(); // shallow cpy + frag = fragments[fragIdx] = Object.assign({}, frag); + } + frag.startDtsTs = startDtsTs; + frag.startPts = startPts; + frag.endPts = endPts; + if (iframeMode || frag.isIframeStart !== undefined) { + frag.isIframeStart = iframeMode; + } + frag.start = startOffset; + frag.duration = diffSeconds(endPts, startPts); + // adjust fragment PTS/duration from seqnum-1 to frag 0 + for (let i = fragIdx, canContinue = true; i > 0 && (forceUpdateAll || canContinue); i--) { + canContinue = updatePTS(fragments, i, i - 1, iframeMode, startPts.timescale, cpyModified); + } + // adjust fragment PTS/duration from seqnum to last frag + for (let i = fragIdx, canContinue = true; i < fragments.length - 1 && (forceUpdateAll || canContinue); i++) { + canContinue = updatePTS(fragments, i, i + 1, iframeMode, startPts.timescale, cpyModified); + } + const endFrag = fragments[fragments.length - 1]; + details.totalduration = endFrag.start + endFrag.duration - fragments[0].start; + details.ptsKnown = true; + } + /** + * + * @param fragments fragment list + * @param fromIdx index inside fragments of the reference fragment + * @param toIdx index inside fragments of the fragment to modify + * @param iframeMode (optional) the iframeMode when this was called + * @param timescale (optional) use timescale for deciding if value is changed enough to update + * @param cpyModified (optional) whether we should make a copy of the fragment rather than modify in place + * @returns whether it should continue iterating + */ + function updatePTS(fragments, fromIdx, toIdx, iframeMode, timescale, cpyModified = false) { + const fragFrom = fragments[fromIdx]; + let fragTo = fragments[toIdx]; + const forceUpdateStartTime = iframeMode != null && fragTo.isIframeStart != null && fragTo.isIframeStart !== iframeMode && fragTo.discoSeqNum === fragFrom.discoSeqNum; + let newStart = fragTo.start; + // Update all frag start times in disco after iframe transition or unknown pts + if (forceUpdateStartTime || fragTo.startPts == null) { + if (toIdx > fromIdx) { + newStart = fragFrom.start + fragFrom.duration; + } + else { + newStart = Math.max(fragFrom.start - fragTo.duration, 0); + } + } + const precision = isFiniteNumber(timescale) ? 1 / timescale : Number.EPSILON; + const timeChanged = Math.abs(fragTo.start - newStart) > precision; + if (forceUpdateStartTime || timeChanged) { + // Never update duration. These are parsed values. + if (cpyModified) { + fragTo = fragments[toIdx] = Object.assign({}, fragTo); + } + if (timeChanged) { + fragTo.start = newStart; + } + if (forceUpdateStartTime) { + fragTo.isIframeStart = iframeMode; + } + return true; + } + return false; + } + function updateDateToMediaTimeMap(details) { + if (details.programDateTimeMap) { + details.dateMediaTimePairs = []; + for (const [dtStr, sn] of Object.entries(details.programDateTimeMap)) { + const dt = Number(dtStr); + const frag = details.fragments[sn - details.startSN]; + if (frag) { + const startTime = frag.start; + details.dateMediaTimePairs.push([dt, startTime]); + } + } + details.dateMediaTimePairs.sort((a, b) => { + return a[0] - b[0]; + }); + } + } + + class SimpleListFilter { + constructor(option) { + this.option = option; + } + get name() { + return this.option.name; + } + get priority() { + return this.option.priority; + } + get expiry() { + return this.option.expiry; + } + filter(originalList, options) { + const context = (this.option.initFn && this.option.initFn(originalList, options)) || (options ? Object.assign({}, options) : {}); + let filteredList = originalList; + if (this.option.firstPassFn) { + originalList.forEach((value, index) => this.option.firstPassFn(value, index, context, originalList)); + } + if (this.option.filterFn) { + filteredList = originalList.filter((value, index) => this.option.filterFn(value, index, context, originalList)); + } + if ((this.option.filterFn == null || filteredList.length === 0) && this.option.minSortingFn) { + filteredList = originalList.sort((a, b) => this.option.minSortingFn(a, b, context, originalList)); + } + if (this.option.finalFn) { + this.option.finalFn(filteredList, context, originalList); + } + return filteredList; + } + } + function applyFilters(originalList, filters, options) { + return (filters || []).reduce((list, filter) => filter.filter(list, options), Array.from(originalList)); + } + function isExpired(expiry, now) { + return now >= expiry; + } + function sortFilters(filters) { + const cpy = [...filters]; + return cpy.sort((a, b) => { + var _a, _b; + const priorityA = (_a = a.priority) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER; + const priorityB = (_b = b.priority) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER; + return priorityA - priorityB; + }); + } + + function getPreferredList(preferredHost, filteredMediaOptionList) { + return filteredMediaOptionList.filter((x) => { var _a; return hasMatchingHost(preferredHost, (_a = x.url) !== null && _a !== void 0 ? _a : null); }); + } + function newRemoveFilter() { + return new SimpleListFilter({ + name: 'Remove Filter', + priority: 0, + filterFn: (value, index, options) => { + return !options || options.removed.every((mediaOptionId) => value.mediaOptionId !== mediaOptionId); + }, + }); + } + function newPenaltyBoxFilter() { + return new SimpleListFilter({ + name: 'Penalty Box Filter', + priority: 1, + filterFn: (value, index, options) => { + const now = performance.now(); + return !options || options.penaltyBoxQueue.every((info) => isExpired(info.expiry, now) || value.mediaOptionId !== info.mediaOptionId); + }, + }); + } + function newCompatibleIdsFilter() { + return new SimpleListFilter({ + name: 'Compatible IDs Filter', + priority: 1, + filterFn: (value, index, options) => { + return !options || options.compatibleIds == null || options.compatibleIds.some((id) => id === value.mediaOptionId); + }, + }); + } + function makeCommonFilters() { + // prettier-ignore + return [ + newRemoveFilter(), + newPenaltyBoxFilter(), + newCompatibleIdsFilter(), + ]; + } + /** + * @brief Query used to get the filtered media option list for a given media option type. + */ + class MediaOptionListQuery extends QueryEntity { + constructor(store, itemId, mediaOptionType) { + super(store); + this.itemId = itemId; + this.mediaOptionType = mediaOptionType; + this.allowFilters = this._initFilters(); + } + /** + * Get the unfiltered media option list + */ + get mediaOptionList() { + var _a; + return ((_a = this.mediaOptionListInfo) === null || _a === void 0 ? void 0 : _a.mediaOptions) || null; + } + get mediaOptionList$() { + return this.mediaOptionListInfo$.pipe(map(({ mediaOptions }) => mediaOptions)); + } + mediaOptionFromId(mediaOptionId) { + var _a, _b; + const list = (_a = this.mediaOptionList) !== null && _a !== void 0 ? _a : []; + return (_b = list.find((option) => option.mediaOptionId === mediaOptionId)) !== null && _b !== void 0 ? _b : null; + } + _getFilteredList(mediaOptionListInfo) { + const mediaOptionList = mediaOptionListInfo.mediaOptions; + return applyFilters(mediaOptionList, this.allowFilters, mediaOptionListInfo); + } + /** + * Get the filtered media option list + */ + get filteredMediaOptionList() { + return this.mediaOptionListInfo ? this._getFilteredList(this.mediaOptionListInfo) : null; + } + get filteredMediaOptionList$() { + return this.mediaOptionListInfo$.pipe(switchMap((mediaOptionListInfo) => { + const fire$ = [VOID]; + const now = performance.now(); + for (const penalty of mediaOptionListInfo.penaltyBoxQueue) { + if (isFiniteNumber(penalty.expiry) && penalty.expiry > now) { + fire$.push(timer(penalty.expiry - now)); + } + } + return merge(...fire$).pipe(map(() => { + return this._getFilteredList(mediaOptionListInfo); + })); + }), distinctUntilArrayItemChanged()); + } + /** + * Get the filtered media option list that also has a hostname matching the preferred host + */ + get preferredMediaOptionList() { + return this.filteredMediaOptionList ? getPreferredList(this.preferredHost, this.filteredMediaOptionList) : []; + } + get preferredMediaOptionList$() { + return combineQueries([this.preferredHost$, this.filteredMediaOptionList$]).pipe(map(([preferredHost, filteredMediaOptionList]) => { + return getPreferredList(preferredHost, filteredMediaOptionList); + })); + } + /** + * @param fromId Media option id used as reference for the switch + * @returns The new host to switch to, or the current host if not switching + */ + getNewHost(fromId) { + const fallback = this.getFallbackVariant(fromId, false, true); + if (fallback === null || fallback === void 0 ? void 0 : fallback.url) { + return getHostName(fallback.url); + } + return this.preferredHost; + } + } + + function isHDRLevel(levelInfo) { + return levelInfo.videoRange === 'PQ' || levelInfo.videoRange === 'HLG'; + } + function isIframeLevel(option) { + return isMatchingIframeLevel(true, option); + } + function isMatchingIframeLevel(iframeMode, option) { + return option.iframes === iframeMode; + } + /** + * Sort function for variants. Ordering determines how ABR mediaOptionList is stored. + * Order will be preserved even after filtering + * + * @param variantList The list to sort + * @param hasScore Use SCORE to sort the list + * @returns Sorted list + */ + function sortVariants(variantList, hasScore) { + const cpy = [...variantList]; + if (hasScore) { + // ascending order by score, then descending order by bitrate + cpy.sort((a, b) => { + return a.score - b.score || b.bitrate - a.bitrate; + }); + } + else { + // bitrate in ascending order + cpy.sort((a, b) => { + return a.bitrate - b.bitrate; + }); + } + return cpy; + } + var Rank; + (function (Rank) { + Rank[Rank["Better"] = 1] = "Better"; + Rank[Rank["Same"] = 0] = "Same"; + Rank[Rank["Worse"] = -1] = "Worse"; + })(Rank || (Rank = {})); + /** + * @param fromVariant The variant we're switching from. We will try to choose something with similar bitrate in all cases + * @param hasScore Whether we should consider SCORE attribute when comparing candidates + * @param candidate Candidate to consider + * @param currentBest Current best candidate + * @returns Better if candidate is better than currentBest, Same if candidate is same as currentBest, else Worse + */ + function compareCandidate(fromVariant, hasScore, candidate, currentBest) { + // TODO: handle SCORE + if (!currentBest || (candidate.bitrate > currentBest.bitrate && candidate.bitrate <= fromVariant.bitrate)) { + return Rank.Better; + } + else if (candidate.bitrate === currentBest.bitrate) { + return Rank.Same; + } + return Rank.Worse; + } + function rankComparison(matchA, matchB) { + if (matchA && !matchB) { + return -1; + } + else if (!matchA && matchB) { + return 1; + } + return 0; + } + function sortFallbackVariants(variantList, fromVariant, hasScore) { + const cpy = [...variantList]; + const fromHost = getHostName(fromVariant.url); + const fromAudioGroup = fromVariant.audioGroupId; + // sort score or bitrate in descending order + // tie breaker: hostname, then audioGroup + cpy.sort((a, b) => { + let rank = 0; + const useScore = hasScore && isFiniteNumber(a.score) && isFiniteNumber(b.score); + const ABetterThanB = useScore ? a.score > b.score && a.score <= fromVariant.score : a.bitrate > b.bitrate && a.bitrate <= fromVariant.bitrate; + const AEqualB = useScore ? a.score === b.score : a.bitrate === b.bitrate; + if (ABetterThanB) { + rank = -1; + } + else if (AEqualB) { + const AmatchHost = hasMatchingHost(fromHost, a.url); + const BmatchHost = hasMatchingHost(fromHost, b.url); + rank = rankComparison(AmatchHost, BmatchHost); + if (rank === 0) { + const AmatchGroup = !fromAudioGroup || a.audioGroupId === fromAudioGroup; + const BmatchGroup = !fromAudioGroup || b.audioGroupId === fromAudioGroup; + rank = rankComparison(AmatchGroup, BmatchGroup); + } + } + else { + rank = 1; + } + return rank; + }); + return cpy; + } + function newHDRFilter() { + return new SimpleListFilter({ + name: 'HDR Filter', + priority: 1, + filterFn: (value, index, options) => { + return !options || (options.hasHdrLevels && options.preferHDR) === isHDRLevel(value); + }, + }); + } + function isSizeWithinTolerance(variant, viewportInfo) { + const TOLERANCE_FACTOR = 1.35; // Value inherited from native stack + return (variant.width < viewportInfo.width * TOLERANCE_FACTOR && + variant.height < viewportInfo.height * TOLERANCE_FACTOR && + variant.width * variant.height < viewportInfo.width * viewportInfo.height * TOLERANCE_FACTOR); + } + function newViewportFilter() { + return new SimpleListFilter({ + name: 'Viewport Filter', + priority: 1, + firstPassFn: (value, index, context) => { + if (context && value && !value.iframes && value.videoCodec) { + // Find the lowest non-iframe level with video + const lowestBitrate = !context.lowestBitrate || value.bitrate < context.lowestBitrate ? value.bitrate : context.lowestBitrate; + context.lowestBitrate = lowestBitrate; + } + }, + filterFn: (value, index, context) => { + if (!value || !context || !context.viewportInfo || !value.videoCodec || !context.lowestBitrate) { + // Don't apply this filter + return true; + } + // Allow only the sizes within tolerance or if it's the lowest bitrate + return isSizeWithinTolerance({ width: value.width, height: value.height }, context.viewportInfo) || value.bitrate === context.lowestBitrate; + }, + }); + } + function newHDCPFilter() { + return new SimpleListFilter({ + name: 'HDCP Filter', + priority: 2, + filterFn: (value, index, options) => { + return !options || !isHdcpLevel(options.maxHdcpLevel) || hdcpLevelToInt(value.hdcpLevel) < hdcpLevelToInt(options.maxHdcpLevel); + }, + }); + } + class VariantMediaOptionListQuery extends MediaOptionListQuery { + constructor(store, itemId) { + super(store, itemId, MediaOptionType.Variant); + } + static makeFilters() { + // prettier-ignore + return sortFilters(makeCommonFilters().concat([ + newHDRFilter(), + newViewportFilter(), + newHDCPFilter(), + // TODO: Fix rdar://81171922 and re-enable content steering + // newPathwayFilter(), + ])); + } + _initFilters() { + return VariantMediaOptionListQuery.kAllowFilters; + } + get preferredHost() { + var _a, _b; + return (_b = (_a = this.mediaOptionListInfo) === null || _a === void 0 ? void 0 : _a.preferredHost) !== null && _b !== void 0 ? _b : null; + } + get preferredHost$() { + return this.selectEntity(this.itemId, (entity) => { + var _a; + return (_a = entity === null || entity === void 0 ? void 0 : entity.mediaOptionListTuple[MediaOptionType.Variant].preferredHost) !== null && _a !== void 0 ? _a : null; + }); + } + get mediaOptionListInfo() { + var _a, _b; + return (_b = (_a = this.getEntity(this.itemId)) === null || _a === void 0 ? void 0 : _a.mediaOptionListTuple[MediaOptionType.Variant]) !== null && _b !== void 0 ? _b : null; + } + get mediaOptionListInfo$() { + return this.selectEntity(this.itemId, (entity) => { var _a; return (_a = entity === null || entity === void 0 ? void 0 : entity.mediaOptionListTuple) === null || _a === void 0 ? void 0 : _a[MediaOptionType.Variant]; }).pipe(filterNullOrUndefined()); + } + get hdrMode$() { + return this.mediaOptionListInfo$.pipe(map((info) => { + return info.preferHDR === true && info.hasHdrLevels; + }), distinctUntilChanged()); + } + get maxHdcpLevel$() { + return this.selectEntity(this.itemId, (entity) => { + var _a; + const info = (_a = entity === null || entity === void 0 ? void 0 : entity.mediaOptionListTuple) === null || _a === void 0 ? void 0 : _a[MediaOptionType.Variant]; + return info === null || info === void 0 ? void 0 : info.maxHdcpLevel; + }).pipe(distinctUntilChanged()); + } + // excludingOptions is useful for skipping visited variants in successive getFallbackVariant + listFallbackVariants(fromId, sdrOnly, shouldSwitchHosts, shouldDownswitch, excludingOptions = undefined) { + var _a; + const mediaOptionListInfo = this.mediaOptionListInfo; + const fromVariant = (_a = this.mediaOptionList) === null || _a === void 0 ? void 0 : _a.find((x) => x.mediaOptionId === fromId); + if (!fromVariant || !mediaOptionListInfo) { + return null; + } + const filteredList = this.makeFilteredListFromVariant(fromVariant, sdrOnly, excludingOptions); + if (!filteredList) { + return null; + } + const fromHost = getHostName(fromVariant.url); + const hasScore = mediaOptionListInfo.hasScore; + return VariantMediaOptionListQuery._listFallbackVariants(filteredList, fromVariant, fromHost, hasScore, shouldSwitchHosts, shouldDownswitch, excludingOptions); + } + // excludingOptions is useful for skipping visited variants in successive getFallbackVariant + getFallbackVariant(fromId, sdrOnly, shouldSwitchHosts, excludingOptions = undefined) { + var _a; + const mediaOptionListInfo = this.mediaOptionListInfo; + const fromVariant = (_a = this.mediaOptionList) === null || _a === void 0 ? void 0 : _a.find((x) => x.mediaOptionId === fromId); + if (!fromVariant || !mediaOptionListInfo) { + return null; + } + const filteredList = this.makeFilteredListFromVariant(fromVariant, sdrOnly, excludingOptions); + if (!filteredList) { + return null; + } + const fromHost = getHostName(fromVariant.url); + const hasScore = mediaOptionListInfo.hasScore; + return VariantMediaOptionListQuery._getFallbackVariant(filteredList, fromVariant, fromHost, hasScore, shouldSwitchHosts); + } + makeFilteredListFromVariant(fromVariant, sdrOnly, excludingOptions = undefined) { + let mediaOptionListInfo = this.mediaOptionListInfo; + if (!fromVariant || !this.mediaOptionList || !mediaOptionListInfo) { + return null; + } + mediaOptionListInfo = Object.assign(Object.assign({}, mediaOptionListInfo), { includeAllEligiblePathways: true }); + const originalList = Array.from(this.mediaOptionList); + let filteredList = sdrOnly ? applyFilters(originalList, this.allowFilters, Object.assign(Object.assign({}, mediaOptionListInfo), { preferHDR: false, compatibleIds: null })) : this._getFilteredList(mediaOptionListInfo); + if (!filteredList) { + return null; + } + if (excludingOptions && excludingOptions.length > 0) { + filteredList = filteredList.filter((option) => !excludingOptions.includes(option.mediaOptionId)); + } + return filteredList; + } + get hasIframes() { + var _a, _b; + return (_b = (_a = this.mediaOptionListInfo) === null || _a === void 0 ? void 0 : _a.hasIframeLevels) !== null && _b !== void 0 ? _b : false; + } + /** + * @returns true if fromId is an HDR level and we can switch to a SDR level + */ + canSwitchToSDR(fromId, shouldSwitchHosts, shouldDownswitch = false) { + const mediaOptionListInfo = this.mediaOptionListInfo; + if (!this.mediaOptionList || !mediaOptionListInfo) { + return false; + } + const fromVariant = this.mediaOptionFromId(fromId); + if (!fromVariant) { + return false; + } + if (!isHDRLevel(fromVariant)) { + return false; + } + const fromHost = getHostName(fromVariant.url); + // Get filtered list but override hdr preference to false + const originalList = Array.from(this.mediaOptionList); + const filteredList = applyFilters(originalList, this.allowFilters, Object.assign(Object.assign({}, mediaOptionListInfo), { preferHDR: false, compatibleIds: null })); + const hasScore = mediaOptionListInfo.hasScore; + return VariantMediaOptionListQuery._getFallbackVariant(filteredList, fromVariant, fromHost, hasScore, shouldSwitchHosts, shouldDownswitch) != null; + } + // Generic helper function for finding a fallback given a filtered list and the failing variant + static _listFallbackVariants(filteredList, fromVariant, fromHost, hasScore, shouldSwitchHosts, shouldDownswitch = false, excludingOptions = null) { + // shouldDownswitch: On timeout we want to pick variant with bitrate lower than currently being downloaded + let needFromVariant = false; + const candidateList = filteredList.filter((candidate) => { + const validCandidate = candidate.iframes === fromVariant.iframes && (!shouldSwitchHosts || !hasMatchingHost(fromHost, candidate.url)); + const lesserTier = shouldDownswitch ? candidate.bitrate < fromVariant.bitrate : candidate.bitrate <= fromVariant.bitrate; + const success = validCandidate && lesserTier; + if (fromVariant.mediaOptionId === candidate.mediaOptionId) { + needFromVariant = success; // if needed, add fromVariant to the top of candidateList later + return false; + } + return success; + }); + const result = sortFallbackVariants(candidateList, fromVariant, hasScore); + if (needFromVariant && (!excludingOptions || !excludingOptions.includes(fromVariant.mediaOptionId))) { + result.unshift(fromVariant); // put fromVariant at the top if not excluded + } + return result; + } + // Generic helper function for finding a fallback given a filtered list and the failing variant + static _getFallbackVariant(filteredList, fromVariant, fromHost, hasScore, shouldSwitchHosts, shouldDownswitch = false) { + // Choose best option between these two + let newVariant = null; + // On timeout we want to pick variant with bitrate lower than currently being downloaded + if (shouldDownswitch) { + filteredList = filteredList.filter((option) => option.bitrate < fromVariant.bitrate); + } + const candidateList = filteredList.filter((candidate) => candidate.mediaOptionId !== fromVariant.mediaOptionId && candidate.iframes === fromVariant.iframes); + if (shouldSwitchHosts && fromHost != null) { + // Choose from different host + for (const candidate of candidateList) { + if (compareCandidate(fromVariant, hasScore, candidate, newVariant) === Rank.Better && !hasMatchingHost(fromHost, candidate.url)) { + newVariant = candidate; + } + } + } + else { + // Choose best one from any host. Tie breaker favors current host + // If hosts are same between candidates, favor same audio group + for (const candidate of candidateList) { + const rank = compareCandidate(fromVariant, hasScore, candidate, newVariant); + if (rank === Rank.Better || + (rank === Rank.Same && hasMatchingHost(fromHost, candidate.url) && (!hasMatchingHost(fromHost, newVariant.url) || candidate.audioGroupId === fromVariant.audioGroupId))) { + newVariant = candidate; + } + } + } + return newVariant; + } + // Get media option matching the input mediaOption groupID + getMatchingVariant(fromId, mediaOption) { + const fromVariant = this.mediaOptionFromId(fromId); + const fromHost = getHostName(fromVariant === null || fromVariant === void 0 ? void 0 : fromVariant.url); + const whichGroup = mediaOption.mediaOptionType === MediaOptionType.AltAudio ? 'audioGroupId' : 'subtitleGroupId'; + let bestCandidate = null; + const hasScore = this.mediaOptionListInfo.hasScore; + for (const candidate of this.filteredMediaOptionList) { + if (candidate[whichGroup] !== mediaOption.groupId) { + continue; + } + if (!fromVariant) { + bestCandidate = candidate; // First mediaOption with matching groupId + break; + } + const rank = compareCandidate(fromVariant, hasScore, candidate, bestCandidate); + if (rank === Rank.Better || + (rank === Rank.Same && bestCandidate.mediaOptionId !== fromVariant.mediaOptionId && (candidate.mediaOptionId === fromVariant.mediaOptionId || hasMatchingHost(fromHost, candidate.url)))) { + bestCandidate = candidate; + } + } + return bestCandidate; + } + get currentPathwayID() { + var _a; + return (_a = this.mediaOptionListInfo) === null || _a === void 0 ? void 0 : _a.currentPathwayID; + } + } + VariantMediaOptionListQuery.kAllowFilters = VariantMediaOptionListQuery.makeFilters(); + + /** + * Error handling policies. This file handles general error handling + * + * @copyright 2018 Apple Inc. All rights reserved. + */ + /** + * @brief Common error actions + */ + var NetworkErrorAction; + (function (NetworkErrorAction) { + NetworkErrorAction[NetworkErrorAction["DoNothing"] = 0] = "DoNothing"; + NetworkErrorAction[NetworkErrorAction["SendEndCallback"] = 1] = "SendEndCallback"; + NetworkErrorAction[NetworkErrorAction["SendAlternateToPenaltyBox"] = 2] = "SendAlternateToPenaltyBox"; + NetworkErrorAction[NetworkErrorAction["RemoveAlternatePermanently"] = 3] = "RemoveAlternatePermanently"; + NetworkErrorAction[NetworkErrorAction["InsertDiscontinuity"] = 4] = "InsertDiscontinuity"; + NetworkErrorAction[NetworkErrorAction["RetryRequest"] = 5] = "RetryRequest"; + })(NetworkErrorAction || (NetworkErrorAction = {})); + /** + * PenaltyBox or Remove only. Additional flags for determining what we should do + */ + var ErrorActionFlags; + (function (ErrorActionFlags) { + ErrorActionFlags[ErrorActionFlags["MoveAllAlternatesMatchingHost"] = 1] = "MoveAllAlternatesMatchingHost"; + ErrorActionFlags[ErrorActionFlags["MoveAllAlternatesMatchingHDCP"] = 2] = "MoveAllAlternatesMatchingHDCP"; + ErrorActionFlags[ErrorActionFlags["SwitchToSDR"] = 4] = "SwitchToSDR"; + })(ErrorActionFlags || (ErrorActionFlags = {})); + /** + * Modify the error action if we have no fallbacks to switch to + * + * @param errorAction Original error action + * @param errorCode The error code + */ + function _modifyErrorActionIfLastValidVariantInternal(errorAction, errorCode) { + switch (errorAction) { + case NetworkErrorAction.SendAlternateToPenaltyBox: + errorAction = NetworkErrorAction.RetryRequest; + if (errorCode === 401 || + errorCode === 403 || + errorCode === 407 || + errorCode === ErrorResponses.CorruptStream.code || + errorCode === ErrorResponses.LivePlaylistUpdateError.code // We've already retried up to max at this point + ) { + errorAction = NetworkErrorAction.SendEndCallback; + } + break; + case NetworkErrorAction.RemoveAlternatePermanently: + errorAction = NetworkErrorAction.SendEndCallback; + break; + } + return errorAction; + } + /** + * Common code to modify if it's the last variant of its kind in the controller + * @param originalAction Original action from getActionForCommonError + * @param isPrefetch Was a prefetch (or not needed immediately for playback) + * @param errorCode The error code + * @param mediaOptionId Option id + * @param mediaOptionType The type + * @param rootQuery Root playlist query + */ + function modifyErrorActionIfCurrentLevelIsLastValidLevel(originalAction, isPrefetch, errorCode, mediaOptionId, mediaOptionType, rootQuery, rootService, isTimeout = false) { + const mediaListQuery = rootQuery.mediaOptionListQueries[mediaOptionType]; + const shouldSwitchHosts = (originalAction.errorActionFlags & ErrorActionFlags.MoveAllAlternatesMatchingHost) != 0; + const mediaOption = rootQuery.mediaOptionListQueries[mediaOptionType].mediaOptionFromId(mediaOptionId); + const fallbackMediaOptions = rootService.getFallbackMediaOptionTupleFromMediaOptionId(rootQuery, mediaOptionType, mediaOptionId, mediaOption.backingMediaOptionId, false, shouldSwitchHosts, isTimeout); + let { errorAction, errorActionFlags } = originalAction; + if (!rootQuery.isValidMediaOptionTuple(fallbackMediaOptions)) { + if (!isPrefetch) { + errorAction = _modifyErrorActionIfLastValidVariantInternal(errorAction, errorCode); + errorActionFlags = 0; + } + if (mediaListQuery instanceof VariantMediaOptionListQuery) { + const mediaOption = mediaListQuery.mediaOptionFromId(mediaOptionId); + if (mediaOption.iframes === true) { + errorAction = NetworkErrorAction.DoNothing; + errorActionFlags = 0; + rootService.logger.debug(`[modifyErrorAction] skip error handling for iframes; isPrefetch ${isPrefetch} fallback ${fallbackMediaOptions}`); + } + else if (!isPrefetch && rootService.canSwitchToSDR(rootQuery, mediaOptionId, shouldSwitchHosts, isTimeout)) { + errorAction = originalAction.errorAction; + errorActionFlags = ErrorActionFlags.SwitchToSDR; + rootService.logger.debug(`[modifyErrorAction] switchToSDR; isPrefetch ${isPrefetch} fallback ${fallbackMediaOptions} isTimeout ${isTimeout}`); + } + } + } + else if (hasMatchingHost(mediaListQuery.preferredHost, fallbackMediaOptions[mediaOptionType].url)) { + errorActionFlags &= ~ErrorActionFlags.MoveAllAlternatesMatchingHost; + rootService.logger.debug(`[modifyErrorAction] matched preferredHost ${mediaListQuery.preferredHost}; isPrefetch ${isPrefetch} fallback ${fallbackMediaOptions}`); + } + return { errorAction, errorActionFlags }; + } + // Get default error action based on error codes + function _getActionForCommonNetworkError(errorCode) { + let errorAction; + let errorActionFlags = 0; + switch (errorCode) { + case 0: + // 0 is sometimes returned as a CORS error or a "muted" error when "--disable-web-security --ignore-certificate-errors" are used in Chrome. + errorAction = NetworkErrorAction.SendAlternateToPenaltyBox; + errorActionFlags = ErrorActionFlags.MoveAllAlternatesMatchingHost; + break; + case 410: + errorAction = NetworkErrorAction.RemoveAlternatePermanently; + break; + case 500: // Internal Server error + case 502: // Bad gateway + case 503: // Service unavailable + case 504: // Gateway timeout + case 404: // NotFound + case 409: // Conflict + case 401: // Unauthorized + case 403: // Forbidden + case 407: // Proxy error + case ErrorResponses.LivePlaylistUpdateError.code: // -12888 + case ErrorResponses.PlaylistNotReceived.code: // -12884 + default: + errorAction = NetworkErrorAction.SendAlternateToPenaltyBox; + errorActionFlags = 0; + break; + } + return { errorAction, errorActionFlags }; + } + /** + * Modify the error action if we think we're going to take too long.... + * + * @param error The error + * @param originalAction The original action + * @param isPrefetch true if this is not for playback but optimistic load + * @param maxTimeouts The maximum number of consecutive timeouts allowed + * @param rootQuery The root playlist query + * @return modified error action + */ + function _modifyActionOnTimeout(error, originalAction, isPrefetch, maxTimeouts, rootQuery) { + var _a, _b; + let { errorAction, errorActionFlags } = originalAction; + if (error.isTimeout) { + const { mediaOptionType } = error; + const consecutiveTimeouts = (_b = (_a = rootQuery.getErrorInfoByType(mediaOptionType)) === null || _a === void 0 ? void 0 : _a.timeouts['load']) !== null && _b !== void 0 ? _b : 0; + if (!isPrefetch && consecutiveTimeouts >= maxTimeouts) { + // this.logger.warn(`Hit max consecutive penalty due to timeout count: ${error.details}`); + errorAction = NetworkErrorAction.DoNothing; // don't treat timeouts as fatal, if the NW conditions don't improve, low buffer will lead to end playback + errorActionFlags = 0; + } + } + return { errorAction, errorActionFlags }; + } + /** + * Get the policy for a manifest load error + * @param error The error + */ + function getActionForManifestError(error) { + let { errorAction, errorActionFlags } = _getActionForCommonNetworkError(error.response.code); + errorAction = _modifyErrorActionIfLastValidVariantInternal(errorAction, error.response.code); + errorActionFlags = 0; // cannot default to a backup CDN for manifest + // this.logger.info(`Manifest error ${errorAction}`); + return { errorAction, errorActionFlags }; + } + /** + * Get the policy for a playlist load error + * @param error The error + * @param isPrefetch true if this is not critical for playback. For instance i-frame + * @param maxTimeouts The maximum number of consecutive timeouts allowed + * @param rootQuery The root playlist query + * @returns The action to perform + */ + function getActionForPlaylistOrFragError(error, isPrefetch, maxTimeouts, rootQuery, rootService) { + const errorCode = error.response.code; + let result = _getActionForCommonNetworkError(errorCode); + const { mediaOptionId, mediaOptionType } = error; + if (isPrefetch) { + // Do not modify on last level in prefetch mode + result.errorActionFlags &= ~ErrorActionFlags.MoveAllAlternatesMatchingHost; + } + else { + result = _modifyActionOnTimeout(error, result, isPrefetch, maxTimeouts, rootQuery); + } + result = modifyErrorActionIfCurrentLevelIsLastValidLevel(result, isPrefetch, errorCode, mediaOptionId, mediaOptionType, rootQuery, rootService, error.isTimeout); + // rootService.logger.info(`[${error.type}] Got playlist error ${errorCode} ${error.message} ${JSON.stringify(result)}`); + return result; + } + /** + * Handle a network error due to crypt key failure + * @param error KeyError + * @param mediaOptionId One of the media options associated with this error + * @param mediaOptionType The media option type associated with the media option id + * @param rootQuery The root query to use + */ + function getActionForCryptKeyNetworkError(error, mediaOptionId, mediaOptionType, rootQuery, rootService) { + let action = { + errorAction: NetworkErrorAction.SendAlternateToPenaltyBox, + errorActionFlags: 0, + }; + if (error instanceof KeyRequestTimeoutError) { + action.errorAction = NetworkErrorAction.SendAlternateToPenaltyBox; + } + else { + const isOkToRetry = error.isOkToRetry; + const isHDCPError = error.keyErrorReason === KeyRequestErrorReason.OutputRestricted; + if (isHDCPError) { + action.errorAction = NetworkErrorAction.RemoveAlternatePermanently; + action.errorActionFlags |= ErrorActionFlags.MoveAllAlternatesMatchingHDCP; + } + else if (!isOkToRetry) { + action.errorAction = NetworkErrorAction.RemoveAlternatePermanently; + } + else { + action = _getActionForCommonNetworkError(error.code); + } + } + // Don't force host switch for key errors + action.errorActionFlags &= ~ErrorActionFlags.MoveAllAlternatesMatchingHost; + const enabledOptionId = rootQuery.enabledMediaOptionIdByType(mediaOptionType); + if (mediaOptionId === enabledOptionId) { + return modifyErrorActionIfCurrentLevelIsLastValidLevel(action, false, error.code, enabledOptionId, mediaOptionType, rootQuery, rootService, error.isTimeout); + } + else { + return action; + } + } + /** + * Common error action handling. use if error can't be handled automatically by handleErrorCommon. + * Note that this will modify the store multiple times so it should be wrapped in a transaction + * + * @param action Error action to handle + * @param rootQuery The root playlist query + * @param rootService The root playlist service + * @param mediaOptionType The media option type that the error originates from. Required for penalty box + * @param mediaOptionId The media option id that the error originates from. Required for penalty box + * @returns true if error was handled (we did something in reaction to it) + */ + function handleErrorAction(action, error, rootQuery, rootService, mediaOptionType, mediaOptionId, isTimeOut) { + const { errorAction, errorActionFlags } = action; + let errorHandled = true; + switch (errorAction) { + case NetworkErrorAction.RemoveAlternatePermanently: + case NetworkErrorAction.SendAlternateToPenaltyBox: { + if (mediaOptionType == null || mediaOptionId == null) { + error.handled = false; + return false; + } + const itemId = rootQuery.itemId; + let failedMediaOptionId = mediaOptionId; + let failedMediaOption = rootQuery.mediaOptionListQueries[mediaOptionType].mediaOptionFromId(mediaOptionId); + if (failedMediaOption.backingMediaOptionId) { + failedMediaOptionId = failedMediaOption.backingMediaOptionId; + failedMediaOption = rootQuery.mediaOptionListQueries[mediaOptionType].mediaOptionFromId(failedMediaOptionId); + } + const shouldSwitchHosts = (errorActionFlags & ErrorActionFlags.MoveAllAlternatesMatchingHost) != 0; + const shouldMoveMatchingHDCP = (errorActionFlags & ErrorActionFlags.MoveAllAlternatesMatchingHDCP) != 0; + const shouldSwitchToSDR = (errorActionFlags & ErrorActionFlags.SwitchToSDR) != 0; + const shouldRemove = errorAction === NetworkErrorAction.RemoveAlternatePermanently; + rootService.logger.debug(`[handleErrorAction] mediaOptionId ${mediaOptionId} shouldSwitchHosts ${shouldSwitchHosts} shouldMoveMatchingHDCP ${shouldMoveMatchingHDCP} shouldSwitchToSDR ${shouldSwitchToSDR} shouldRemove ${shouldRemove} fatal ${error.fatal}`); + if (shouldMoveMatchingHDCP && 'hdcpLevel' in failedMediaOption) { + const maxHdcpLevel = failedMediaOption.hdcpLevel; + rootService.setMaxHdcpLevel(itemId, maxHdcpLevel); + } + if (shouldSwitchToSDR) { + rootService.switchToSDROnly(itemId); + } + if (shouldSwitchHosts) { + const hostName = getHostName(failedMediaOption.url); + rootService.moveAllWithMatchingHosts(itemId, mediaOptionType, hostName, shouldRemove); + } + else { + if (shouldRemove) { + rootService.removePermanently(itemId, mediaOptionType, failedMediaOptionId); + } + else { + rootService.addToPenaltyBox(itemId, mediaOptionType, failedMediaOptionId); + } + } + // Switch enabled option only if we're the enabled option + const currentMediaOptionId = rootQuery.enabledMediaOptionIdByType(mediaOptionType); + if (currentMediaOptionId === mediaOptionId) { + let newOptions = [NoMediaOption, NoMediaOption, NoMediaOption]; + newOptions = rootService.getFallbackMediaOptionTupleFromMediaOptionId(rootQuery, mediaOptionType, mediaOptionId, null, false, shouldSwitchHosts, isTimeOut); + if (rootQuery.isValidMediaOptionTuple(newOptions)) { + rootService.setPreferredHost(itemId, getHostName(newOptions[MediaOptionType.Variant].url)); + } + else { + error.fatal = true; // Couldn't find matching variant + } + rootService.logger.debug(`[handleErrorAction] ${error.fatal ? 'rejected' : 'picked'} ${JSON.stringify(newOptions)}`); + if (error.fatal) { + newOptions = [NoMediaOption, NoMediaOption, NoMediaOption]; + } + rootService.setNextMediaOptions(rootQuery.itemId, newOptions); + } + break; + } + case NetworkErrorAction.SendEndCallback: + error.fatal = true; + break; + case NetworkErrorAction.RetryRequest: // Retry should be handled outside of this using retryWhen + case NetworkErrorAction.DoNothing: + default: + errorHandled = false; + break; + } + error.handled = errorHandled; + return errorHandled; + } + function logError(logger, error, action, retryCount, nextRetry) { + var _a, _b; + let requestID; + if (error instanceof ManifestNetworkError) { + requestID = 'manifest'; + } + else if (error instanceof PlaylistNetworkError || error instanceof FragmentNetworkError) { + requestID = `${MediaOptionNames[error.mediaOptionType]}:${error.mediaOptionId}`; + } + else if (error instanceof KeyRequestError || error instanceof KeyRequestTimeoutError) { + requestID = `key:${redactUrl(error.keyuri)}`; + } + const data = { + requestID, + type: error.type, + details: error.details, + fatal: error.fatal, + code: (_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : NaN, + errorAction: action === null || action === void 0 ? void 0 : action.errorAction, + errorActionFlags: action === null || action === void 0 ? void 0 : action.errorActionFlags, + retryCount, + nextRetry, + }; + logger.qe({ + critical: true, + name: 'internalError', + data, + }); + } + + /** + * Common helpers / operators for handling errors + */ + function handleRetryAction(error, retryCount, retryConfig, logger) { + error.handled = true; + if (retryConfig && retryCount < retryConfig.maxNumRetry && isFiniteNumber(retryConfig.retryDelayMs)) { + let timeoutMs; + switch (retryConfig.backoff) { + case 'linear': + timeoutMs = (retryCount + 1) * retryConfig.retryDelayMs; + break; + default: + // exponential + timeoutMs = Math.pow(2, retryCount) * retryConfig.retryDelayMs; + break; + } + timeoutMs = Math.min(retryConfig.maxRetryDelayMs, timeoutMs); + logError(logger, error, { errorAction: NetworkErrorAction.RetryRequest, errorActionFlags: 0 }, retryCount, timeoutMs); + return timer(timeoutMs); + } + error.fatal = true; + logError(logger, error, { errorAction: NetworkErrorAction.SendEndCallback, errorActionFlags: 0 }, retryCount); + return throwError(error); + } + /** + * For use in retryWhen. This is a generic helper just in case we don't want to go + * through getActionAndHandleError. + * + * @returns timer() if we should retry, else throws if we should stop / abort the request + */ + function handleErrorWithRetry(error, retryCount, retryConfig, action, rootQuery, rootService, mediaOptionType, mediaOptionId, isTimeOut = false) { + if ((action === null || action === void 0 ? void 0 : action.errorAction) === NetworkErrorAction.RetryRequest) { + return handleRetryAction(error, retryCount, retryConfig, rootService.logger); + } + return handleErrorActionCommon(error, retryCount, action, rootQuery, rootService, mediaOptionType, mediaOptionId, isTimeOut); + } + function handleErrorActionCommon(error, retryCount, action, rootQuery, rootService, mediaOptionType, mediaOptionId, isTimeOut = false) { + const async$ = new AsyncSubject(); + // Wrap handleErrorAction in transaction because it will update the store a few times + applyTransaction(() => { + if (action) { + logError(rootService.logger, error, action, retryCount); + handleErrorAction(action, error, rootQuery, rootService, mediaOptionType, mediaOptionId, isTimeOut); + } + async$.error(error); + }); + return async$; + } + + /** + * Handle errors coming from demuxers + */ + /** + * An operator for handling demux errors + */ + function addDemuxErrorHandlingPolicy(rootService, rootQuery, mediaOptionType, mediaOptionId) { + return (source$) => source$.pipe(catchError((error) => { + rootService.logger.error(`Got demux error ${error.message}`); + if (error instanceof FragParsingError || error instanceof RemuxAllocError) { + let errorAction = NetworkErrorAction.SendAlternateToPenaltyBox; + if (error.fatal) { + errorAction = NetworkErrorAction.SendEndCallback; + } + else if (error instanceof RemuxAllocError) { + errorAction = NetworkErrorAction.SendAlternateToPenaltyBox; + } + else { + errorAction = NetworkErrorAction.RemoveAlternatePermanently; + } + const action = { + errorAction, + errorActionFlags: 0, + }; + // No retry allowed + return handleErrorActionCommon(error, 0, action, rootQuery, rootService, mediaOptionType, mediaOptionId); + } + throw error; + })); + } + + /** + * Handle errors that occur while fetching keys or from keysystem + */ + function updateKeyTimeouts(keyUri, increment, rootQuery, rootService, ksQuery) { + var _a, _b; + const mediaOptionIds = (_b = (_a = ksQuery.getKeyInfo(keyUri)) === null || _a === void 0 ? void 0 : _a.mediaOptionIds) !== null && _b !== void 0 ? _b : []; + for (const mediaOptionId of mediaOptionIds) { + for (const query of rootQuery.mediaOptionListQueries) { + if (query.mediaOptionFromId(mediaOptionId) != null) { + rootService.updateConsecutiveTimeouts(rootQuery.itemId, query.mediaOptionType, increment, 'key'); + } + } + } + } + function addKeyErrorHandlingPolicy(keyUri, loadConfig, rootQuery, rootService, ksQuery) { + return (source) => source.pipe(withTransaction(() => { + updateKeyTimeouts(keyUri, false, rootQuery, rootService, ksQuery); + }), retryWhen((errors) => errors.pipe(mergeMap((err, retryCount) => { + if (err instanceof KeyRequestTimeoutError || err instanceof KeyRequestError) { + return handleKeyError(err, retryCount, getRetryConfig(err, loadConfig), rootService, rootQuery, ksQuery); + } + throw err; + })))); + } + function handleKeyError(error, retryCount, retryConfig, rootService, rootQuery, ksQuery) { + const logger = rootService.logger; + const enabledOptions = rootQuery.enabledMediaOptionKeys; + const mediaOptions = []; + for (const mediaOptionId of error.mediaOptionIds) { + const isEnabled = enabledOptions.some((key) => key.mediaOptionId === mediaOptionId); + const query = rootQuery.mediaOptionListQueries.find((query) => query.mediaOptionFromId(mediaOptionId) != null); + if (!query) { + logger.warn(`Couldn't find query for ${mediaOptionId}`); + continue; + } + const mediaOptionType = query.mediaOptionType; + const obj = { mediaOptionId, mediaOptionType }; + if (isEnabled) { + mediaOptions.push(obj); // Handle after all other options because of fallback handling + } + else { + mediaOptions.unshift(obj); + } + } + const async$ = new AsyncSubject(); + applyTransaction(() => { + const isTimeout = error instanceof KeyRequestTimeoutError; + updateKeyTimeouts(error.keyuri, isTimeout, rootQuery, rootService, ksQuery); + let shouldRetry = false; + let action; + for (const { mediaOptionId, mediaOptionType } of mediaOptions) { + action = getActionForCryptKeyNetworkError(error, mediaOptionId, mediaOptionType, rootQuery, rootService); + logger.error(`[Keys] handleNetworkError uri=${redactUrl(error.keyuri)} mediaOptionId=${mediaOptionId} mediaOptionType=${mediaOptionType} action=${JSON.stringify(action)}`); + if (action.errorAction === NetworkErrorAction.RetryRequest) { + // This means there's no fallback! + shouldRetry = true; + } + handleErrorAction(action, error, rootQuery, rootService, mediaOptionType, mediaOptionId); + } + if (shouldRetry) { + async$.next(); + async$.complete(); + } + else { + logError(logger, error, action, retryCount); // Log final action + async$.error(error); + } + }); + return async$.pipe(switchMap(() => { + return handleRetryAction(error, retryCount, retryConfig, rootService.logger); + })); + } + + /** + * Handle root playlist, media playlist and fragment load errors + */ + /** + * An operator for handling Playlist and Fragment load errors. It will either retry or abort the observable by throwing error + * Additional error handling may happen by putting something into penalty box + */ + function addLoadErrorHandlingPolicy(itemId, mediaOptionType, loadConfig, maxTimeouts, isPrefetch, rootQuery, rootPlaylistService, statsService) { + maxTimeouts = Math.max(0, maxTimeouts); + return (source) => source.pipe( + // Expected that the source will throw appropriate HlsError. + tap(() => { + if (mediaOptionType != null) { + rootPlaylistService.updateConsecutiveTimeouts(itemId, mediaOptionType, false, 'load'); + } + }), retryWhen((errors) => errors.pipe(mergeMap((error, retryCount) => { + return getActionAndHandleError(error, retryCount, getRetryConfig(error, loadConfig), isPrefetch, maxTimeouts, rootQuery, rootPlaylistService, statsService); + })))); + } + /** + * Meant to be used within retryWhen for an Observable + * @param retryCount How many times we have retried this observable. 0 means this was the original request + * @param retryConfig Retry config to use + * @param isPrefetch true if this is a prefetch (not needed for playback) + * @param maxTimeouts Maximum number of consecutive timeouts allowed before failing + * @param rootQuery The root playlist query + * @param rootService The root playlist service + * @returns Retry timer if retrying, else throws error + */ + function getActionAndHandleError(error, retryCount, retryConfig, isPrefetch, maxTimeouts, rootQuery, rootService, statsService) { + var _a; + if (!(error instanceof HlsError)) { + return throwError(error); + } + let mediaOptionId; + let mediaOptionType; + let action; + let isTimeout = false; + if (error instanceof ManifestNetworkError) { + action = getActionForManifestError(error); + } + else if (error instanceof PlaylistNetworkError || error instanceof FragmentNetworkError) { + ({ mediaOptionType, mediaOptionId, isTimeout } = error); + const mediaOption = (_a = rootQuery.mediaOptionListQueries[mediaOptionType]) === null || _a === void 0 ? void 0 : _a.mediaOptionFromId(mediaOptionId); + if (!isPrefetch && error.isTimeout && mediaOption != null && !('iframes' in mediaOption && mediaOption.iframes === true)) { + rootService.updateConsecutiveTimeouts(rootQuery.itemId, error.mediaOptionType, true, 'load'); + // record only for fragments + if (error instanceof FragmentNetworkError && error.stats) { + const now = performance.now(); + statsService.setBandwidthSample(Object.assign(Object.assign({}, error.stats), { tfirst: error.stats.tfirst || now, tload: error.stats.tload || now, complete: true, mediaOptionType: mediaOptionType })); + } + } + action = getActionForPlaylistOrFragError(error, isPrefetch, maxTimeouts, rootQuery, rootService); + } + // TODO: add more error types + return handleErrorWithRetry(error, retryCount, retryConfig, action, rootQuery, rootService, mediaOptionType, mediaOptionId, isTimeout); + } + + class HlsQuery extends QueryEntity { + constructor(store) { + super(store); + } + get currentConfig() { + var _a; + return (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.config; + } + get extendMaxTTFB() { + var _a; + return (_a = this.getActive()) === null || _a === void 0 ? void 0 : _a.extendMaxTTFB; + } + get config$() { + return this.selectActive((entity) => entity === null || entity === void 0 ? void 0 : entity.config); + } + get userSeek$() { + return this.selectActive((entity) => entity === null || entity === void 0 ? void 0 : entity.userSeek); + } + } + + // rdar://84941644 ([HLS JS 2.1a beta] [DoW] The plugin for 'MapSet' has not been loaded into Immer) + // hls.js uses Set and/or Map in highestVideoCodecs and various entities. + // dev-app occasionally throws "The plugin for 'MapSet' has not been loaded into Immer." error during error handling (e.g., switchToSDROnly). + // need to call enableMapSet() after and including immer 6. + // reference: https://immerjs.github.io/immer/map-set/ + enableMapSet_1(); + /** + * @brief Store for keeping track of things that are associated with Hls lifetime + */ + class HlsStore extends EntityStore { + constructor() { + super({}, { name: 'hls-store', producerFn: produce_1 }); + } + } + + /** + * @brief Service for HlsStore + */ + class HlsService { + constructor(store) { + this.store = store; + } + getQuery() { + return new HlsQuery(this.store); + } + /** + * Add and set active HlsEntity + */ + setHlsEntity(entity) { + const id = entity.id; + logAction(`hls.set.entity ${id}`); + applyTransaction(() => { + this.store.add(deepCpy(entity)); + this.store.setActive(id); + }); + } + removeEntity(id) { + logAction(`hls.remove ${id}`); + this.store.remove(id); + } + // legacy hack to get airplay to work + setStartTime(startTimeSec) { + this.store.updateActive((active) => { + active.config.startPosition = startTimeSec; + }); + } + // If we got a user seek + setUserSeek(position) { + this.store.updateActive((active) => { + active.userSeek = position; + }); + } + setExtendMaxTTFB(value) { + this.store.updateActive((active) => { + active.extendMaxTTFB = value; + }); + } + } + let service; + function globalHlsService() { + if (!service) { + service = new HlsService(new HlsStore()); + } + return service; + } + function createHlsQuery() { + return globalHlsService().getQuery(); + } + /** + * Config for active hls entity + */ + function getCurrentConfig() { + return globalHlsService().getQuery().currentConfig; + } + + const detailFields = ['mediaOptionId', 'startSN', 'endSN', 'ptsKnown']; + /** + * Used for live, merge the two playlists together + * @param oldDetails + * @param newDetails Newly parsed variant info from PlaylistParser. Assumption is that fragments[0].start === 0 + */ + function mergeDetails(oldDetails, newDetails, logger) { + var _a; + // no merging required in VOD or if not matching in iframe mode + if (oldDetails.type === 'VOD' || newDetails.type === 'VOD' || oldDetails.iframesOnly !== newDetails.iframesOnly) { + return; + } + logger.info(`[live] merging ${JSON.stringify(oldDetails, detailFields)}+${JSON.stringify(newDetails, detailFields)}`); + const matchingMediaOption = oldDetails.mediaOptionId === newDetails.mediaOptionId; + const startIdx = Math.max(oldDetails.startSN, newDetails.startSN) - newDetails.startSN; // start of overlap inside newfragments + const endIdx = Math.min(oldDetails.endSN, newDetails.endSN) - newDetails.startSN; // end of overlap inside newfragments + const idxDelta = newDetails.startSN - oldDetails.startSN; + const oldfragments = oldDetails.fragments; + const newfragments = newDetails.fragments; + let discoSeqNumOffset = 0; // oldCC - newCC + for (let i = startIdx; i <= endIdx; ++i) { + // Expect this to only be O(1) usually... + if (oldfragments[idxDelta + i] && newfragments[i]) { + discoSeqNumOffset = oldfragments[idxDelta + i].discoSeqNum - newfragments[i].discoSeqNum; + // non zero value means the content is in violation of authoring guidelines + logger.debug(`[live] merging details for mediaOptionId: ${newDetails.mediaOptionId} using discoSeqNumOffset: ${discoSeqNumOffset}`); + break; + } + } + // loop through overlapping SN and update startPTS , cc, and duration if any found + const mergedInitSegments = {}; + let lastPtsFrag = null; + for (let i = 0; i < newfragments.length; i++) { + // logger.info(`[live] merging details for media sequence number: ${newfragments[i].mediaSeqNum}`); + const oldFrag = oldfragments[idxDelta + i]; + const newFrag = newfragments[i]; + if (discoSeqNumOffset) { + // This block is to handle publisher side issue, where the + // authoring guideline below is not handled: 8.17. If + // live/linear content will ever contain an EXT-X-DISCONTINUITY + // tag, the EXT-X-DISCONTINUITY-SEQUENCE tag MUST always be + // present. + const discoSeqNum = newFrag.discoSeqNum + discoSeqNumOffset; + if (newDetails.initSegments[newFrag.discoSeqNum]) { + // logger.info(`[live] merging details offseting discoSeqNum from ${newFrag.discoSeqNum} to ${discoSeqNum}`); + newDetails.initSegments[newFrag.discoSeqNum].discoSeqNum = discoSeqNum; // update the frag details + mergedInitSegments[discoSeqNum] = newDetails.initSegments[newFrag.discoSeqNum]; // update the record + delete newDetails.initSegments[newFrag.discoSeqNum]; // delete from the old record. + } + newFrag.discoSeqNum = discoSeqNum; + } + if (matchingMediaOption && newFrag.mediaSeqNum === (oldFrag === null || oldFrag === void 0 ? void 0 : oldFrag.mediaSeqNum) && oldFrag.startPts != null) { + // logger.info(`[live] merging timestamps for media sequence number: ${newFrag.mediaSeqNum} using start PTS: ${oldFrag.startPTS}`); + newFrag.start = oldFrag.start; + newFrag.duration = oldFrag.duration; + newFrag.startDtsTs = oldFrag.startDtsTs; + newFrag.endDtsTs = oldFrag.endDtsTs; + newFrag.startPts = oldFrag.startPts; + newFrag.endPts = oldFrag.endPts; + lastPtsFrag = newFrag; + } + } + if (Object.keys(mergedInitSegments).length) { + newDetails.initSegments = mergedInitSegments; + } + if (lastPtsFrag) { + // Force update entire list to ensure correct sliding window + updateFragPTSDTS(newDetails, lastPtsFrag, lastPtsFrag.start, undefined, false, true); + } + else { + // ensure that delta is within oldfragments range + // also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61]) + // in that case we also need to adjust start offset of all fragments + if (idxDelta >= 0 && idxDelta < oldfragments.length) { + // adjust start by sliding offset + const sliding = oldfragments[idxDelta].start; + logger.info(`[live] merging details using sliding ${sliding}`); + const mergedFragments = newDetails.fragments; + for (let i = 0; i < newfragments.length; i++) { + mergedFragments[i].start += sliding; + } + } + } + // If overlapping use oldDetails.PTSKnown + newDetails.ptsKnown = newDetails.ptsKnown || (matchingMediaOption && oldDetails.ptsKnown === true && oldDetails.endSN >= newDetails.startSN); + updateDateToMediaTimeMap(newDetails); + const startPos = (_a = newDetails.fragments[0]) === null || _a === void 0 ? void 0 : _a.start; + const endPos = startPos + newDetails.totalduration; + logger.info(`[live] merged ${JSON.stringify(oldDetails, detailFields)}+${JSON.stringify(newDetails, detailFields)}=[${startPos === null || startPos === void 0 ? void 0 : startPos.toFixed(3)},${endPos === null || endPos === void 0 ? void 0 : endPos.toFixed(3)}]`); + } + + function computeLivePosition(sliding, mediaOptionDetails, config, logger) { + let targetLatency = mediaOptionDetails.targetduration; + if (isFiniteNumber(config.liveSyncDuration)) { + targetLatency = config.liveSyncDuration; + } + else if (isFiniteNumber(config.liveSyncDurationCount)) { + targetLatency = config.liveSyncDurationCount * mediaOptionDetails.targetduration; + } + const result = sliding + Math.max(0, mediaOptionDetails.totalduration - targetLatency); + logger.info(`[live] computeLivePosition: ${toFixed(result, 3)}`); + return result; + } + function sanitizeLiveSeek(seekTo, details, config, logger) { + let santizedSeek = seekTo; + const liveWindowStart = details.fragments[0].start; + const liveWindowEnd = details.fragments[details.fragments.length - 1].start + details.fragments[details.fragments.length - 1].duration; + if (seekTo < liveWindowStart) { + santizedSeek = liveWindowStart; + } + else if (seekTo > liveWindowEnd) { + santizedSeek = computeLivePosition(0, details, config, logger); + } + if (seekTo < liveWindowStart || seekTo > liveWindowEnd) { + logger.warn(`[live] sanitizeLiveSeek seekTo:${toFixed(seekTo, 3)}, sanitizedSeek:${toFixed(santizedSeek, 3)}, liveWindowStart:${toFixed(liveWindowStart, 3)}, liveWindowEnd:${toFixed(liveWindowEnd, 3)}`); + } + return santizedSeek; + } + function getMinPlayablePosition(pos, details, lastUpdateMillis, maxBufferHole, mediaQuery) { + if (!details.ptsKnown) { + return 0; + } + const targetDuration = details.targetduration; + const liveWindowStart = details.fragments[0].start; + const playlistEstimate = { avgPlaylistLoadTimeMs: 0, avgPlaylistParseTimeMs: 0 }; + const canPlayThrough = mediaQuery.canContinuePlaybackWithoutGap(details, lastUpdateMillis, playlistEstimate, maxBufferHole); + let minPosition = Math.max(0, pos - targetDuration); + if (pos < liveWindowStart && !canPlayThrough) { + minPosition = liveWindowStart; + } + return minPosition; + } + /** + * @returns An observable that will ensure playback stays within the live window on playlist refresh + * emits the seek position + */ + function ensurePlaybackWithinWindow(context) { + const { config, mediaSink, rootPlaylistQuery, mediaLibraryService } = context; + const logger = context.logger.child({ name: 'live' }); + const mediaQuery = mediaSink.mediaQuery; + return rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(filter(isEnabledMediaOption), switchMap((option) => { + const libQuery = mediaLibraryService.getQueryForOption(option); + return libQuery.mediaOptionDetailsEntity$.pipe(filter((entity) => { var _a; return ((_a = entity === null || entity === void 0 ? void 0 : entity.mediaOptionDetails) === null || _a === void 0 ? void 0 : _a.ptsKnown) && entity.mediaOptionDetails.liveOrEvent; }), distinctUntilChanged((a, b) => (a === null || a === void 0 ? void 0 : a.lastUpdateMillis) === (b === null || b === void 0 ? void 0 : b.lastUpdateMillis))); + }), map((entity) => { + const details = entity.mediaOptionDetails; + const pos = mediaQuery.currentTime; + const duration = mediaQuery.msDuration; + if (duration < entity.playlistDuration) { + logger.info(`msDuration < playlistDuration, updating ${duration}->${entity.playlistDuration}`); + mediaSink.msDuration = entity.playlistDuration; + } + else if (isFiniteNumber(mediaSink.msDuration)) { + // audio could have been behind video and stagnated, and missed out on last opportunity + // and video playlist could stagnate subsequently + // doing this will trigger the needData, giving a chance to survive low buffer stall + mediaSink.msDuration = mediaSink.msDuration + config.livePlaylistDurationNudge; + } + const minPosition = getMinPlayablePosition(pos, details, entity.lastUpdateMillis, config.maxBufferHole, mediaQuery); + let seekTo = NaN; + if (pos < minPosition) { + seekTo = computeLivePosition(details.fragments[0].start, details, config, logger); + logger.info(`${pos.toFixed(3)} too far behind window start:${minPosition} seek to live=${seekTo}`); + mediaSink.seekTo = seekTo; + } + return seekTo; + })); + } + + /* + * deals with live/event refresh related aspects + * + * + * + */ + // in milliseconds + function getLiveRefreshInterval(mediaOptionDetails) { + return 1000 * (mediaOptionDetails.averagetargetduration ? mediaOptionDetails.averagetargetduration : mediaOptionDetails.targetduration); + } + function needToRefreshLevel(mediaOptionDetails, lastUpdateMillis) { + const refreshInterval = getLiveRefreshInterval(mediaOptionDetails); + const timeSinceLastLevelRequest = performance.now() - lastUpdateMillis; + return mediaOptionDetails.liveOrEvent && timeSinceLastLevelRequest >= refreshInterval; + } + /** + * + * @param curDetails + * @param newDetails + * @param logger + * @returns Whether there has been a change between curDetails && newDetails + */ + function mediaOptionDetailsHasChanged(curDetails, newDetails) { + return curDetails == null || newDetails.endSN !== curDetails.endSN || newDetails.liveOrEvent !== curDetails.liveOrEvent; + } + function getReloadTimer(mediaOptionDetailsEntity, slowDownTimeInMillis, logger) { + // In gapless mode it is possible the mediaOptionDetailsEntity is null right after an item eviction + if (!mediaOptionDetailsEntity) { + logger.info('mediaOptionDetailsEntity is null'); + return EMPTY; + } + const { mediaOptionDetails, lastUpdateMillis, unchangedCount } = mediaOptionDetailsEntity; + if (!(mediaOptionDetails === null || mediaOptionDetails === void 0 ? void 0 : mediaOptionDetails.liveOrEvent)) { + logger.info(`End of event refresh for mediaOptionId: ${mediaOptionDetails.mediaOptionId}`); + return EMPTY; + } + if (needToRefreshLevel(mediaOptionDetails, lastUpdateMillis)) { + return timer(0).pipe(tap(() => logger.info(`[live] immediate live refresh for mediaOptionId: ${mediaOptionDetails.mediaOptionId}`))); + } + let reloadInterval = getLiveRefreshInterval(mediaOptionDetails); + if (unchangedCount > 0) { + reloadInterval /= 2; + reloadInterval = Math.max(reloadInterval, 5000); // Have a minumum 5 seconds gap + } + // decrement reloadInterval with level loading delay + const now = performance.now(); + const sinceLastUpdate = now - lastUpdateMillis; + reloadInterval -= sinceLastUpdate; + reloadInterval += slowDownTimeInMillis; + // in any case, don't reload more than every second + reloadInterval = Math.max(1000, Math.round(reloadInterval)); + return timer(reloadInterval).pipe(tap(() => logger.info(`[live] live refresh after ${reloadInterval} for mediaOptionId: ${mediaOptionDetails.mediaOptionId}`))); + } + /** + * @returns whether the live playlist is too far in the past. This means the sliding window end is too + * far behind the minimum playback position + */ + function livePlaylistExpired(details, lastUpdateMillis, maxBufferHole, mediaQuery) { + const minPosition = getMinPlayablePosition(mediaQuery.currentTime, details, lastUpdateMillis, maxBufferHole, mediaQuery); + const lastFrag = details.fragments[details.fragments.length - 1]; + const windowEnd = (lastFrag === null || lastFrag === void 0 ? void 0 : lastFrag.start) + (lastFrag === null || lastFrag === void 0 ? void 0 : lastFrag.duration); + const expired = lastFrag != null && details.liveOrEvent && details.ptsKnown && windowEnd < minPosition; + return { expired, windowEnd, minPosition }; + } + + function findFragForCriteria(details, fn, startSN = NaN) { + const fragList = details.fragments; + const startIdx = startSN > details.startSN ? startSN - details.startSN : 0; + for (let idx = startIdx; idx < fragList.length; ++idx) { + const mediaFragment = fragList[idx]; + const { start: timelineOffset } = mediaFragment; + if (fn(mediaFragment)) { + return { timelineOffset, mediaFragment }; + } + } + return null; + } + function discoSeqNumForTime(details, position) { + var _a; + const foundFrag = (_a = findFragForCriteria(details, (f) => { + const positiveDuration = f.duration > 0; + const fragEnd = f.start + f.duration; + const validPosition = fragEnd > position || (position - fragEnd < 1 && f.isLastFragment); + return positiveDuration && validPosition; + })) !== null && _a !== void 0 ? _a : null; + return foundFrag === null || foundFrag === void 0 ? void 0 : foundFrag.mediaFragment.discoSeqNum; + } + function validUnbufferedFragment(bufferedSeg, position, f) { + const positiveDuration = f.duration > 0; + const fragEnd = f.start + f.duration; + // edge case : position is after last segment, but its very close, use the last fragment. + const validPosition = position == null || fragEnd > position || (position - fragEnd < 1 && f.isLastFragment); + const fragNotAlreadyBuffered = bufferedSeg.every((seg) => !fragEqual(seg.frag, f)); + return positiveDuration && fragNotAlreadyBuffered && validPosition; + } + function findFragment(position, activeDiscoSeqNum, anchorMSN, details, bufferedSeg) { + var _a, _b, _c; + const firstUnbufferedFrag = (_a = findFragForCriteria(details, validUnbufferedFragment.bind(null, bufferedSeg, undefined), anchorMSN)) !== null && _a !== void 0 ? _a : null; + let foundFrag = null; + if (firstUnbufferedFrag) { + // Try to find fragment with valid position using previous result as hint + foundFrag = (_b = findFragForCriteria(details, validUnbufferedFragment.bind(null, bufferedSeg, position), firstUnbufferedFrag.mediaFragment.mediaSeqNum)) !== null && _b !== void 0 ? _b : null; + if (!foundFrag && details.liveOrEvent && !details.ptsKnown) { + // this is fall back for fairly rare case + foundFrag = firstUnbufferedFrag; + } + } + let nextDisco = NaN; + if (foundFrag != null && isFiniteNumber(activeDiscoSeqNum) && foundFrag.mediaFragment.discoSeqNum !== activeDiscoSeqNum) { + nextDisco = foundFrag.mediaFragment.discoSeqNum; + foundFrag = null; + } + // When switching variants and segments have the potential to drop frames, return mediaSeqNum -1 + // to retieve the start of the GOP needed to buffer the start of the segment time range. + const canDropFrames = bufferedSeg.some((seg) => seg.frag.framesWithoutIDR > 0); + if (foundFrag && canDropFrames) { + const levelSwitch = bufferedSeg[bufferedSeg.length - 1].frag.mediaOptionId !== details.mediaOptionId; + if (levelSwitch) { + foundFrag = (_c = findFragForCriteria(details, (f) => f.mediaSeqNum === foundFrag.mediaFragment.mediaSeqNum - 1)) !== null && _c !== void 0 ? _c : foundFrag; + } + } + return { foundFrag, nextDisco }; + } + function findIframeFragmentForPosition(position, details, audioDetails, rate, iframeMachine) { + const nextFragResult = iframeMachine.nextFragment(details.fragments, (audioDetails === null || audioDetails === void 0 ? void 0 : audioDetails.fragments) || [], rate, position); + if (!nextFragResult) { + return null; + } + const { frag, newMediaRootTime } = nextFragResult; + const foundFrag = { timelineOffset: frag.iframeMediaStart, mediaFragment: frag }; + return { foundFrag, nextDisco: NaN, newMediaRootTime }; + } + function calculatePlaylistEnd(details) { + const fragEnd = details.fragments[details.fragments.length - 1]; + return fragEnd ? fragEnd.start + fragEnd.duration : 0; + } + + /** + * @brief Query interface to the media library. Holds the details and init segments + */ + class MediaLibraryQuery extends QueryEntity { + constructor(mediaLibraryStore, mediaOption) { + super(mediaLibraryStore); + this.mediaOption = mediaOption; + } + get itemId() { + return this.mediaOption.itemId; + } + get mediaOptionId() { + return this.mediaOption.mediaOptionId; + } + get initSegmentEntities() { + var _a; + return (_a = this.mediaOptionDetailsEntity) === null || _a === void 0 ? void 0 : _a.initSegmentCacheEntities; + } + get mediaLibraryEntity() { + return this.getEntity(this.itemId); + } + get mediaOptionDetailsEntityRecord() { + var _a; + return (_a = this.mediaLibraryEntity) === null || _a === void 0 ? void 0 : _a.mediaOptionDetailsEntityRecord; + } + get mediaOptionDetailsEntity() { + if (!this.mediaOptionDetailsEntityRecord) + return null; + return this.mediaOptionDetailsEntityRecord[this.mediaOptionId]; + } + get mediaOptionDetails() { + var _a; + return (_a = this.mediaOptionDetailsEntity) === null || _a === void 0 ? void 0 : _a.mediaOptionDetails; + } + get playlistDuration() { + var _a; + return (_a = this.mediaOptionDetailsEntity) === null || _a === void 0 ? void 0 : _a.playlistDuration; + } + get mediaOptionDetailsEntity$() { + const { itemId, mediaOptionId } = this; + return this.selectEntity(itemId, (libraryEntity) => { + if (libraryEntity === null || libraryEntity === void 0 ? void 0 : libraryEntity.mediaOptionDetailsEntityRecord) { + return libraryEntity === null || libraryEntity === void 0 ? void 0 : libraryEntity.mediaOptionDetailsEntityRecord[mediaOptionId]; + } + }); + } + get mediaOptionDetails$() { + return this.selectEntity(this.itemId, (entity) => { var _a; return (_a = entity === null || entity === void 0 ? void 0 : entity.mediaOptionDetailsEntityRecord[this.mediaOptionId]) === null || _a === void 0 ? void 0 : _a.mediaOptionDetails; }).pipe(filterNullOrUndefined()); + } + get playlistDuration$() { + return this.mediaOptionDetailsEntity$.pipe(map((mediaOptionDetailsEntity) => mediaOptionDetailsEntity === null || mediaOptionDetailsEntity === void 0 ? void 0 : mediaOptionDetailsEntity.playlistDuration), filterNullOrUndefined(), distinctUntilChanged()); + } + get live$() { + return this.mediaOptionDetails$.pipe(map((mediaOptionDetails) => mediaOptionDetails === null || mediaOptionDetails === void 0 ? void 0 : mediaOptionDetails.liveOrEvent), distinctUntilChanged()); + } + } + + class MediaLibraryStore extends EntityStore { + constructor() { + super({}, { name: 'media-library-store', idKey: 'itemId', producerFn: produce_1 }); + } + } + + /** + * @brief Service interface to the media library. Will fetch and catch media options details and init segments, and find + * the right fragments to load. + * + * The retrieve functions are rxjs pipeable operators: + * https://rxjs.dev/guide/v6/pipeable-operators + */ + class MediaLibraryService { + constructor(store) { + this.store = store; + } + getQuery() { + return new QueryEntity(this.store); + } + getQueryForOption(mediaOption) { + return new MediaLibraryQuery(this.store, mediaOption); + } + createMediaLibraryEntity(itemId) { + const libraryEntity = { itemId, mediaOptionDetailsEntityRecord: {} }; + logAction(`library.entity.create: ${itemId}`); + this.store.add(libraryEntity); + } + setDetailsLoading(mediaOption) { + const { itemId, mediaOptionId } = mediaOption; + logAction(`library.details.loading: ${mediaOptionId}`); + this.store.update(itemId, ({ mediaOptionDetailsEntityRecord }) => { + if (!mediaOptionDetailsEntityRecord[mediaOptionId]) { + mediaOptionDetailsEntityRecord[mediaOptionId] = { initSegmentCacheEntities: {}, unchangedCount: 0 }; + } + mediaOptionDetailsEntityRecord[mediaOptionId].detailsLoading = true; + }); + } + archiveMediaOptionDetails(mediaOptionDetails, stats, changed) { + const { itemId, mediaOptionId } = mediaOptionDetails; + const lastUpdateMillis = performance.now(); + const playlistDuration = calculatePlaylistEnd(mediaOptionDetails); + logAction(`library.details.loaded: ${mediaOptionId}`); + this.store.update(itemId, (libraryEntity) => { + const detailsEntity = libraryEntity.mediaOptionDetailsEntityRecord[mediaOptionId]; + detailsEntity.detailsLoading = false; + detailsEntity.mediaOptionDetails = mediaOptionDetails; + detailsEntity.lastUpdateMillis = lastUpdateMillis; + if (changed) { + detailsEntity.unchangedCount = 0; + } + else { + ++detailsEntity.unchangedCount; + } + detailsEntity.playlistDuration = playlistDuration; + detailsEntity.stats = stats; + libraryEntity.liveOrEvent = mediaOptionDetails.liveOrEvent; + }); + } + setInitSegmentLoading(initSegment) { + const { itemId, mediaOptionId, discoSeqNum } = initSegment; + logAction(`library.initsegs.loading: ${mediaOptionId}/${discoSeqNum}`); + this.store.update(itemId, (libraryEntity) => { + libraryEntity.mediaOptionDetailsEntityRecord[mediaOptionId].initSegLoading = discoSeqNum; + }); + } + archiveInitSegmentEntity(original, generated) { + const { itemId, mediaOptionId, discoSeqNum } = original; + logAction(`library.initseg.loaded: ${mediaOptionId}/${discoSeqNum}`); + this.store.update(itemId, ({ mediaOptionDetailsEntityRecord }) => { + const detailsEntity = mediaOptionDetailsEntityRecord[mediaOptionId]; + detailsEntity.initSegmentCacheEntities[discoSeqNum] = [original, generated]; + detailsEntity.initSegLoading = null; + }); + } + updatePTSDTS(itemId, mediaOptionId, initPTSInfo, parsedFrag) { + var _a; + const origDetails = (_a = this.getQueryForOption({ itemId, mediaOptionId })) === null || _a === void 0 ? void 0 : _a.mediaOptionDetails; + if (!origDetails || !fragIsInDetails(origDetails, parsedFrag)) { + return; + } + // immer read/write is slow, modify details cpy outside of store update + const { startDtsTs } = parsedFrag; + const { variantDTS, timelineOffset, iframeMode } = initPTSInfo; + const startOffset = diffSeconds(startDtsTs, variantDTS) + timelineOffset; + const newDetails = Object.assign({}, origDetails); // shallow copy + updateFragPTSDTS(newDetails, parsedFrag, startOffset, iframeMode, true); + updateDateToMediaTimeMap(newDetails); + const newPlaylistDuration = calculatePlaylistEnd(newDetails); + this.store.update(itemId, ({ mediaOptionDetailsEntityRecord }) => { + const entity = mediaOptionDetailsEntityRecord[mediaOptionId]; + if (!(entity === null || entity === void 0 ? void 0 : entity.mediaOptionDetails)) { + return; + } + entity.mediaOptionDetails = newDetails; + entity.playlistDuration = newPlaylistDuration; + }); + } + remove(ids) { + this.store.remove(ids); + } + clear() { + this.store.remove(); + } + } + /** + * Global state store for the service + */ + let libraryService; + function mediaLibraryService() { + if (!libraryService) { + libraryService = new MediaLibraryService(new MediaLibraryStore()); + } + return libraryService; + } + /** + * Creates a new media library query from any media option info (MediaOption, MediaOptionDetails, etc) + * Uses the global store for read only query, but protects the store access + * + * @param {MediaOptionDetails} mediaOptionDetails The details to store + */ + const createMediaLibraryQuery = (mediaOption) => { + return mediaLibraryService().getQueryForOption(mediaOption); + }; + /** + * Upserts a MediaOptionDetails to the store + * + * @param {MediaOptionDetails} mediaOptionDetails The details to store + */ + const archiveMediaOptionDetails = (mediaOptionDetails, stats, changed) => { + mediaLibraryService().archiveMediaOptionDetails(mediaOptionDetails, stats, changed); + }; + /** + * Retrieve the details (a mediaplaylist.m3u8) for a media option (variant or alternate) + * Uses the global store for read only query, but protects the store access + * + * @param {MediaOption} mediaOption media option to load the details for + * @param {LoadPolicy} loadPolicy the policy determining how to load the details + * @param {number} maxTimeouts Maximum number of consecutive timeouts allowed + * @returns {Observable} retrieved (cached or loaded) details for the source media option + */ + const retrieveMediaOptionDetails = (libContext, mediaOption, isPrefetch = false, force = false) => { + if (mediaOption == null || !isEnabledMediaOption(mediaOption)) { + return of(null); + } + const { itemId } = mediaOption; + const { mediaLibraryService: libraryService } = libContext; + const libraryQuery = libraryService.getQueryForOption(mediaOption); + if (!libraryQuery.hasEntity(itemId)) { + libraryService.createMediaLibraryEntity(itemId); + } + const entity = libraryQuery.mediaOptionDetailsEntity; + const details = libraryQuery.mediaOptionDetails; + if (details != null && !force && (details.type === 'VOD' || (details.liveOrEvent && !needToRefreshLevel(details, entity.lastUpdateMillis)))) { + return of(details).pipe(tag('retrieveMediaOptionDetails.emit.cached')).pipe(take(1)); + } + libraryService.setDetailsLoading(mediaOption); + return getMediaOptionDetailsCommon(libContext, mediaOption, isPrefetch); + }; + /** + * Schedules playlist refresh if needed + */ + function refreshMediaOptionDetails(libContext, mediaOption) { + const { mediaLibraryService, logger } = libContext; + const mediaLibraryQuery = mediaLibraryService.getQueryForOption(mediaOption); + // getReloadTimer returns EMPTY if non-live so it shouldn't emit + return getReloadTimer(mediaLibraryQuery.mediaOptionDetailsEntity, 0, logger).pipe(switchMap(() => retrieveMediaOptionDetails(libContext, mediaOption, false, true)), switchMap(() => refreshMediaOptionDetails(libContext, mediaOption))); + } + // Load media option details with error handling + function getMediaOptionDetailsCommon(libContext, mediaOption, isPrefetch) { + var _a, _b; + const { logger, config, rootPlaylistQuery: rootQuery, rootPlaylistService: rootService, statsService, mediaLibraryService, mediaSink } = libContext; + const mediaQuery = mediaSink.mediaQuery; + const loadPolicy = config.playlistLoadPolicy; + const keySystemPreference = config.keySystemPreference; + const masterVariableList = rootQuery.masterVariableList; + const extendMaxTTFB = (_b = (_a = globalHlsService()) === null || _a === void 0 ? void 0 : _a.getQuery()) === null || _b === void 0 ? void 0 : _b.extendMaxTTFB; + return loadMediaOptionDetails(mediaOption, rootQuery.itemStartOffset, config, loadPolicy, logger, keySystemPreference, statsService, masterVariableList, extendMaxTTFB) + .pipe(map((loadMediaOptionDetailsResult) => { + var _a; + // Handle merging with previous level for live/event + const curLibraryQuery = mediaLibraryService.getQueryForOption(mediaOption); + const thisMediaOptionDetails = curLibraryQuery.mediaOptionDetails; + const { mediaOptionDetails: newMediaOptionDetails } = loadMediaOptionDetailsResult; + const { stats } = loadMediaOptionDetailsResult; + let changed = true; + if (newMediaOptionDetails.liveOrEvent) { + const { mediaOptionType } = newMediaOptionDetails; + changed = mediaOptionDetailsHasChanged(thisMediaOptionDetails, newMediaOptionDetails); + // Try merging with self first, then last loaded + if (thisMediaOptionDetails) { + mergeDetails(thisMediaOptionDetails, newMediaOptionDetails, logger); + } + const lastLoadedOption = rootQuery.lastLoadedMediaOptionByType(mediaOptionType); + const lastMediaOptionDetails = lastLoadedOption ? (_a = mediaLibraryService.getQueryForOption(lastLoadedOption)) === null || _a === void 0 ? void 0 : _a.mediaOptionDetails : null; + if (!newMediaOptionDetails.ptsKnown && lastMediaOptionDetails && lastMediaOptionDetails.mediaOptionId !== (thisMediaOptionDetails === null || thisMediaOptionDetails === void 0 ? void 0 : thisMediaOptionDetails.mediaOptionId)) { + mergeDetails(lastMediaOptionDetails, newMediaOptionDetails, logger); + } + } + if (newMediaOptionDetails) { + applyTransaction(() => { + mediaLibraryService.archiveMediaOptionDetails(newMediaOptionDetails, stats, changed); + rootService.setLastLoadedMediaOptionByType(rootQuery.itemId, mediaOption.mediaOptionType, mediaOption); + }); + } + const hitUnchangedMaxCount = !changed && curLibraryQuery.mediaOptionDetailsEntity.unchangedCount >= config.liveMaxUnchangedPlaylistRefresh; + const isExpiredInfo = livePlaylistExpired(newMediaOptionDetails, stats.tload, config.maxBufferHole, mediaQuery); + if (hitUnchangedMaxCount || isExpiredInfo.expired) { + let response; + if (hitUnchangedMaxCount) { + response = ErrorResponses.LivePlaylistUpdateError; + } + else { + response = { + text: `Live window too far in the past end:${isExpiredInfo.windowEnd.toFixed(3)} minPosition:${isExpiredInfo.minPosition}`, + code: 0, + }; + } + throw new PlaylistNetworkError(false, response.text, response.code, response, false, mediaOption.mediaOptionType, mediaOption.mediaOptionId, mediaOption.url); + } + return newMediaOptionDetails; + }), tag('getMediaOptionDetailsCommon.emit.loaded'), addLoadErrorHandlingPolicy(mediaOption.itemId, mediaOption.mediaOptionType, getLoadConfig(mediaOption, loadPolicy), config.maxNumAddLevelToPenaltyBox, isPrefetch, rootQuery, rootService, statsService)) + .pipe(take(1)); + } + /** + * Retrieve the corresponding init segment (#EXT-X-MAP) for a media fragment + * + * @param {MediaFragment} mediaFragment get init segment for this media fragment + * @returns {Observable} retrieved (cached or loaded) init segment + */ + const retrieveInitSegmentCacheEntity = (libContext, mediaFragment) => { + if (!mediaFragment) + return of(null); + const { logger } = libContext; + const { mediaLibraryService, mediaParser } = libContext; + const mediaLibraryQuery = mediaLibraryService.getQueryForOption(mediaFragment); + const { mediaOption, mediaOptionDetailsEntityRecord, mediaOptionDetails } = mediaLibraryQuery; + const { mediaOptionId } = mediaOption; + if (!(mediaOptionDetailsEntityRecord === null || mediaOptionDetailsEntityRecord === void 0 ? void 0 : mediaOptionDetailsEntityRecord[mediaOptionId])) + throw new Error('retrieveInitSegmentCacheEntity no details entity'); + if (!mediaOptionDetails) + throw new Error('retrieveInitSegmentCacheEntity no details'); + const { initSegmentCacheEntities } = mediaOptionDetailsEntityRecord[mediaOptionId]; + const { initSegments } = mediaOptionDetails; + const { mediaSeqNum, discoSeqNum } = mediaFragment; + if (initSegmentCacheEntities[discoSeqNum]) { + logger.debug({ mediaOptionId, mediaSeqNum, discoSeqNum }, 'found cached init segment'); + const [original, generated] = initSegmentCacheEntities[discoSeqNum]; + let entity = original; + if (generated) { + const trackSwitch = mediaParser.willBeTrackSwitch(mediaFragment); + entity = trackSwitch ? original : generated; + } + return of(entity); + } + const initFrag = initSegments[discoSeqNum]; + if (!initFrag) { + logger.debug({ mediaOptionId, mediaSeqNum, discoSeqNum }, 'no init segment entry'); + return of(null); + } + mediaLibraryService.setInitSegmentLoading(initFrag); + logger.info({ mediaSeqNum, discoSeqNum }, 'loading init segment'); + const timingObj = { + mediaOptionId, + mediaSeqNum: 'initSegment', + discoSeqNum, + name: MediaOptionNames[mediaFragment.mediaOptionType], + state: 'loading', + }; + const tlog = logger.child({ name: 'timing' }); + tlog.info(`${JSON.stringify(timingObj)}`); + return getMediaFragmentCommon(libContext, initFrag, false, false).pipe(tap(() => { + tlog.info(`${JSON.stringify(Object.assign(Object.assign({}, timingObj), { state: 'loaded' }))}`); + }), observeOn(asyncScheduler), switchMap((data) => { + tlog.info(`${JSON.stringify(Object.assign(Object.assign({}, timingObj), { state: 'parsing' }))}`); + return parseInitSegment(data, initFrag, libContext); + }), tap(() => { + tlog.info(`${JSON.stringify(Object.assign(Object.assign({}, timingObj), { state: 'parsed' }))}`); + })); + }; + function parseInitSegment(data, frag, libContext) { + var _a; + const { logger, mediaSink, rootPlaylistService, rootPlaylistQuery, mediaParser, mediaLibraryService, gaplessInstance } = libContext; + const { mediaQuery } = mediaSink; + const mediaLibraryQuery = mediaLibraryService.getQueryForOption(frag); + const { mediaOption, mediaOptionDetails } = mediaLibraryQuery; + const { itemId, mediaOptionId } = mediaOption; + const { keyTagInfo, discoSeqNum, mediaSeqNum, mediaOptionType } = frag; + const seeking = mediaQuery.seeking; + const live = mediaOptionDetails.liveOrEvent; + const ptsKnown = mediaOptionType === MediaOptionType.Variant ? mediaOptionDetails.ptsKnown : false; + let segment; + let initSegment; + if (frag.isInitSegment) { + initSegment = new Uint8Array(data); + } + else { + segment = new Uint8Array(data); + } + const parserContext = { + segment, + initSegment, + frag, + ptsKnown, + seeking, + live, + totalDuration: mediaOptionDetails.totalduration, + }; + return mediaParser.parseInitSegment(parserContext, (_a = navigator === null || navigator === void 0 ? void 0 : navigator.vendor) !== null && _a !== void 0 ? _a : '').pipe(map((parsedInitSegment) => { + const { track, moovData, mimeType } = parsedInitSegment; + const { initSegment } = track; + if (gaplessInstance.inGaplessMode && MediaUtil.isVideoCodec(track.codec)) { + logger.warn(`Video codec discovered in gapless mode codec:${track.codec}`); + gaplessInstance.dequeueSource('InvalidFormat'); + } + const initSegmentCacheEntity = { itemId, mediaOptionId, discoSeqNum, initParsedData: moovData, data: initSegment, mimeType, keyTagInfo, fragment: frag }; + mediaLibraryService.archiveInitSegmentEntity(initSegmentCacheEntity); + logger.info({ mediaOptionId, mediaSeqNum, discoSeqNum }, 'loaded init segment'); + return initSegmentCacheEntity; + }), addDemuxErrorHandlingPolicy(rootPlaylistService, rootPlaylistQuery, mediaOptionType, mediaOptionId)); + } + function parseSegment(data, defaultInitPTS, initSegmentCacheEntity, frag, timelineOffset, libContext) { + var _a, _b; + const segment = new Uint8Array(data); + const { legibleSystemAdapter, rootPlaylistService, mediaSink, mediaParser, rootPlaylistQuery, mediaLibraryService } = libContext; + const { mediaQuery } = mediaSink; + const mediaLibraryQuery = mediaLibraryService.getQueryForOption(frag); + const { mediaOption, mediaOptionDetails } = mediaLibraryQuery; + const { initSegments } = mediaOptionDetails; + const { itemId, mediaOptionId } = mediaOption; + const { discoSeqNum, mediaSeqNum, mediaOptionType, isLastFragment } = frag; + const seeking = mediaQuery.seeking; + const live = mediaOptionDetails.liveOrEvent; + const initSeg = initSegments[discoSeqNum]; + const ptsKnown = mediaOptionType === MediaOptionType.Variant ? mediaOptionDetails.ptsKnown : false; + const parserContext = { + segment, + frag, + seeking, + live, + ptsKnown, + totalDuration: mediaOptionDetails.totalduration, + defaultInitPTS, + iframeMediaStart: isIframeMediaFragment(frag) ? frag.iframeMediaStart : undefined, + iframeDuration: isIframeMediaFragment(frag) ? frag.iframeMediaDuration : undefined, + iframeOriginalStart: isIframeMediaFragment(frag) ? frag.iframeOriginalStart : undefined, + }; + let source; + if (initSegmentCacheEntity != null && ((_a = frag.keyTagInfo) === null || _a === void 0 ? void 0 : _a.uri) === ((_b = initSegmentCacheEntity.keyTagInfo) === null || _b === void 0 ? void 0 : _b.uri)) { + source = of(initSegmentCacheEntity); + } + else if (initSegmentCacheEntity != null) { + // key rotated, update cached init segment with current frag keyTagInfo, pass to demuxer for parsing + const updatedFrag = Object.assign(Object.assign({}, initSegmentCacheEntity.fragment), { keyTagInfo: frag.keyTagInfo }); + const initData = initSeg ? initSegmentCacheEntity.data : data; + source = parseInitSegment(initData, updatedFrag, libContext); + } + else { + source = parseInitSegment(data, frag, libContext); + } + return source.pipe(switchMap((initSegmentCacheEntity) => { + const parseStartTime = performance.now(); + if (initSegmentCacheEntity != null) { + const { data: is } = initSegmentCacheEntity; + const initSegment = new Uint8Array(is); + parserContext.initSegment = initSegment; + } + if (frag.mediaOptionType === MediaOptionType.Variant) { + legibleSystemAdapter === null || legibleSystemAdapter === void 0 ? void 0 : legibleSystemAdapter.setupForFrag(frag); + } + return mediaParser.parseSegment(parserContext, '').pipe(map((parsedSegment) => { + var _a; + const parseEndTime = performance.now(); + const { startPTS, startDTS: startDtsTs, endPTS, endDTS: endDtsTs, firstKeyframePts, framesWithoutIDR, dropped, data1, data2, captionData, id3Samples, parsedInitSegment } = parsedSegment; + const fragSample = { + durationSec: endPTS.baseTime / endPTS.timescale - startPTS.baseTime / startPTS.timescale, + parseTimeMs: parseEndTime - parseStartTime, + }; + libContext.statsService.setFragSample(fragSample); + // parser updated initSegment, possibly due to silent audio insertion + let generatedInitSegmentCacheEntity = Object.assign({}, initSegmentCacheEntity); + if (parsedInitSegment) { + const { track, moovData, mimeType } = parsedInitSegment; + const { initSegment } = track; + generatedInitSegmentCacheEntity = { itemId, mediaOptionId, discoSeqNum, initParsedData: moovData, data: initSegment, mimeType, keyTagInfo: frag.keyTagInfo, fragment: frag }; + mediaLibraryService.archiveInitSegmentEntity(initSegmentCacheEntity, generatedInitSegmentCacheEntity); + } + const keyTagInfo = frag.keyTagInfo; + const mediaFragmentCacheEntity = { + itemId, + mediaOptionId, + mediaSeqNum, + discoSeqNum, + startDtsTs, + endDtsTs, + timelineOffset, + firstKeyframePts, + framesWithoutIDR, + dropped, + data1, + data2, + startPts: startPTS, + endPts: endPTS, + keyTagInfo, + isLastFragment, + iframe: (_a = frag.iframe) !== null && _a !== void 0 ? _a : false, + duration: frag.duration, + iframeMediaDuration: isIframeMediaFragment(frag) ? frag.iframeMediaDuration : undefined, + iframeOriginalStart: isIframeMediaFragment(frag) ? frag.iframeOriginalStart : undefined, + captionData, + id3Samples, + }; + const appendDataTuple = [generatedInitSegmentCacheEntity, mediaFragmentCacheEntity]; + return appendDataTuple; + })); + }), addDemuxErrorHandlingPolicy(rootPlaylistService, rootPlaylistQuery, mediaOptionType, mediaOptionId)); + } + // Fragment loading with error handling + function getMediaFragmentCommon(libContext, frag, updateStats, updateRtc) { + var _a, _b, _c; + const { rootPlaylistQuery: rootQuery, rootPlaylistService: rootService, config, rtcService, statsService } = libContext; + const { itemId, mediaOptionType } = frag; + const loadPolicy = config.fragLoadPolicy; + const isMediaFragment = isFiniteNumber(frag.mediaSeqNum); + let onProgress; + if (isMediaFragment) { + const updateSample = (_url, _status, stats, _data) => { + rootService.updateInflightFrag(itemId, frag.mediaOptionType, frag, 'loading', stats); + return false; + }; + onProgress = { getData: false, cb: updateSample }; + } + let requestServerInfo = false; + if (updateRtc) { + if (rtcService.serverInfoInstance === null) { + requestServerInfo = true; + } + } + const fetchSegment$ = loadMediaFragment(frag, config, loadPolicy, onProgress, requestServerInfo, (_b = (_a = globalHlsService()) === null || _a === void 0 ? void 0 : _a.getQuery()) === null || _b === void 0 ? void 0 : _b.extendMaxTTFB).pipe(tap(([, , stats, serverInfo]) => { + libContext.logger.qe({ + critical: true, + name: 'resourceTimingMonitor', + data: { + type: MediaOptionNames[frag.mediaOptionType], + trequest: stats.trequest, + tfirst: stats.tfirst, + tload: stats.tload, + bitsDownloaded: stats.total, + mediaSeqNum: frag.mediaSeqNum, + mediaOpitonId: frag.mediaOptionId, + }, + }); + if (updateStats) { + statsService.setBandwidthSample(Object.assign(Object.assign({}, stats), { mediaOptionType: frag.mediaOptionType })); + } + if (updateRtc && requestServerInfo) { + rtcService.serverInfoInstance = serverInfo; + } + if (isMediaFragment) { + rootService.updateInflightFrag(itemId, frag.mediaOptionType, frag, 'loaded', stats); + } + }), tap(([mediaFragment, , stats]) => { + if (updateRtc) { + const { logger } = rootService; + logger.qe({ + critical: true, + name: 'fragLoaded', + data: { mediaOptionType: frag.mediaOptionType, fragLoadingProcessingMs: stats.tload - stats.tfirst, loaded: stats.loaded, duration: frag.duration, fragLoadMs: stats.tload - stats.trequest }, + }); + rtcService.handleFragLoaded(mediaFragment, stats); + } + }), addLoadErrorHandlingPolicy(itemId, mediaOptionType, getLoadConfig(frag, loadPolicy), config.maxNumAddLevelToPenaltyBox, false, rootQuery, rootService, statsService)); + // Don't need to wait for key if segment is not encrypted! + const shouldWaitForKey = ((_c = frag.keyTagInfo) === null || _c === void 0 ? void 0 : _c.method) === 'AES-128'; + if (shouldWaitForKey) { + return forkJoin([loadKey(libContext, frag.keyTagInfo, { itemId: frag.itemId, mediaOptionId: frag.mediaOptionId }), fetchSegment$]).pipe(switchMap(([keyTagInfo, fragInfo]) => { + const [mediaFragment, fragDataBuf] = fragInfo; + mediaFragment.keyTagInfo.key = keyTagInfo.key; + return decryptMediaFragment(mediaFragment, fragDataBuf, config, libContext.logger, libContext.rpcClients.crypto); + })); + } + return fetchSegment$.pipe(map((fragInfo) => fragInfo[1])); + } + /** + * Retrieve the data for a media fragment + * + * @param {MediaFragment} retrieveFragAction the media fragment to retrieve data for + * @returns {Observable} the init segment data and fragment data + */ + const retrieveSubtitleFragmentCacheEntity = (libContext, initPTS, mediaFragment) => { + const { logger } = libContext; + const { mediaOptionType, mediaOptionId, discoSeqNum, mediaSeqNum } = mediaFragment; + logger.info(`[${MediaOptionNames[mediaOptionType]}] loading media fragment ${JSON.stringify({ mediaOptionId, discoSeqNum, mediaSeqNum })}`); + return getMediaFragmentCommon(libContext, mediaFragment, false, false).pipe(map((data) => { + logger.info(`[${MediaOptionNames[mediaOptionType]}] loaded media fragment ${JSON.stringify({ mediaOptionId, discoSeqNum, mediaSeqNum })}`); + return { initPTS, data, mediaFragment }; + }), tag('retrieveSubtitleFragmentCacheEntity.emit')); + }; + /** + * Retrieve the data for a media fragment + * + * @param {MediaFragment} retrieveFragAction the media fragment to retrieve data for + * @returns {Observable} the init segment data and fragment data + */ + const retrieveMediaFragmentCacheEntity = (libContext, mediaOptionType, retrieveFragAction) => { + const { rootPlaylistService: rootService, rootPlaylistQuery: rootQuery } = libContext; + const { logger } = rootService; + const { timelineOffset, mediaFragment } = retrieveFragAction.foundFrag; + const { itemId, mediaOptionId, discoSeqNum, mediaSeqNum } = mediaFragment; + logger.info(`[${MediaOptionNames[mediaOptionType]}] loading media fragment ${JSON.stringify({ mediaOptionId, discoSeqNum, mediaSeqNum })}`); + return retrieveInitSegmentCacheEntity(libContext, mediaFragment).pipe(switchMap((initSegmentCacheEntity) => { + rootService.updateInflightFrag(itemId, mediaFragment.mediaOptionType, mediaFragment, 'loading', null); + return getMediaFragmentCommon(libContext, mediaFragment, true, true).pipe(switchMap((data) => { + var _a; + rootService.updateInflightFrag(itemId, mediaOptionType, mediaFragment, 'parsing', null); + return parseSegment(data, (_a = rootQuery.getInitPTS(discoSeqNum)) === null || _a === void 0 ? void 0 : _a.offsetTimestamp, initSegmentCacheEntity, mediaFragment, timelineOffset, libContext); + }), tap((parsedData) => { + rootService.updateInflightFrag(itemId, mediaOptionType, mediaFragment, 'parsed', null); + const { startPts, endPts, startDtsTs, endDtsTs } = parsedData[1]; + logger.info(`[${MediaOptionNames[mediaOptionType]}] ${JSON.stringify({ mediaOptionId, discoSeqNum, mediaSeqNum })} parsed: ${JSON.stringify({ startPts, endPts, startDtsTs, endDtsTs })}`); + }), tag(`retrieveMediaFragmentCacheEntity.${mediaOptionType}.emit`)); + }), take(1)); + }; + function loadKey(context, keyTagInfo, mediaOptionKey) { + const { keySystemAdapter, rootPlaylistQuery, rootPlaylistService, config } = context; + return keySystemAdapter + .getKeyFromDecryptData(keyTagInfo, mediaOptionKey) + .pipe(addKeyErrorHandlingPolicy(keyTagInfo.uri, getLoadConfig({ url: keyTagInfo.uri }, config.keyLoadPolicy), rootPlaylistQuery, rootPlaylistService, keySystemAdapter.ksQuery)); + } + function mediaLibraryRemove(ids) { + mediaLibraryService().remove(ids); + } + function mediaLibraryClear() { + mediaLibraryService().clear(); + } + + /* + * HLS Player Events + * + * + */ + /* + * @brief subscribes to hls public queries and sends out events. + */ + class HlsPlayerEvents { + constructor(hls, logger, rtcService) { + this.hls = hls; + this.destroy$ = new Subject(); + this.iframeSwitchStart = 0; + this.logger = logger.child({ name: 'hls-player-events' }); + this.rtc = rtcService; + this.subscribeAndEmit(); + } + destroy() { + this.destroy$.next(); + } + subscribeAndEmit() { + const loaderQuery$ = this.loaderQueryListener(createLoaderQuery()); + const publicQueries$ = this.hls.publicQueries$.pipe(switchMap(([rootPlaylistQuery, mediaElementQuery]) => { + return merge(this.rootPlaylistQueryListener(rootPlaylistQuery, mediaElementQuery), this.mediaElementQueryListener(mediaElementQuery, rootPlaylistQuery)); + })); + const activeItemQuery$ = this.activeItemListener(this.hls.itemQueue); + merge(loaderQuery$, publicQueries$, activeItemQuery$) + .pipe(catchError((err) => { + let errMessage = err.message; + { + errMessage = err.stack; + } + this.logger.error(`Got error in HlsPlayerEvents ${errMessage}`, err); + return EMPTY; + }), takeUntil(this.destroy$), finalize$1(() => { + this.logger.info('HlsPlayerEvents finalized'); + })) + .subscribe(); + } + activeItemListener(itemQueue) { + const manifestLoadSource$ = itemQueue.activeItemById$.pipe(filterNullOrUndefined(), switchMap((item) => { + var _a; + const url = item.url; + this.logger.debug(`Manifest loading: ${(_a = this.hls.itemQueue.activeItem) === null || _a === void 0 ? void 0 : _a.url}`); + this.hls.trigger(HlsEvent.MANIFEST_LOADING, { url }); + return EMPTY; + })); + return manifestLoadSource$; + } + rootPlaylistQueryListener(rootPlaylistQuery, mediaElementQuery) { + const variantSource$ = rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(filter((mediaOption) => !!mediaOption), switchMap((mediaOption) => { + var _a; + this.logger.debug(`Switching to level: ${mediaOption.mediaOptionId}`); + this.hls.trigger(HlsEvent.LEVEL_SWITCHING, mediaOption); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleLevelSwitching(mediaOption.url); + return EMPTY; + })); + const levelLoading$ = rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(switchMap((mediaOption) => { + const mediaLibQuery = createMediaLibraryQuery(mediaOption); + return mediaLibQuery.mediaOptionDetailsEntity$.pipe(filter((entity) => (entity === null || entity === void 0 ? void 0 : entity.detailsLoading) === true), tap((_) => { + const levelLoading = { + url: redactUrl(mediaOption === null || mediaOption === void 0 ? void 0 : mediaOption.url), + level: mediaOption.mediaOptionId, + type: MediaOptionNames[mediaOption.mediaOptionType], + }; + this.logger.qe({ critical: true, name: 'levelLoading', data: levelLoading }); + this.hls.trigger(HlsEvent.LEVEL_LOADING, levelLoading); + return EMPTY; + })); + })); + const levelLoaded$ = rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(switchMap((mediaOption) => { + const query = createMediaLibraryQuery(mediaOption); + let lastUpdate = 0; + // filter on entities that have loading set to false and have stats filled and have been updated + return query.mediaOptionDetailsEntity$.pipe(filterNullOrUndefined(), filter((entity) => { + var _a; + const retValue = entity.stats !== null && entity.detailsLoading === false && entity.lastUpdateMillis > lastUpdate; + lastUpdate = (_a = entity.lastUpdateMillis) !== null && _a !== void 0 ? _a : 0; + return retValue; + })); + }), switchMap((mediaDetailsEntity) => { + var _a; + const mediaOptionDetails = mediaDetailsEntity.mediaOptionDetails; + const stats = mediaDetailsEntity.stats; + const levelLoadedData = { + mediaOptionId: mediaOptionDetails.mediaOptionId, + details: mediaOptionDetails, + playlistType: mediaOptionDetails.type, + stats: stats, + }; + // this.logger.debug('Level loaded %o', levelLoadedData); + this.logger.qe({ + critical: true, + name: 'levelLoaded', + data: { url: redactUrl(mediaOptionDetails === null || mediaOptionDetails === void 0 ? void 0 : mediaOptionDetails.url), level: mediaOptionDetails.mediaOptionId, type: MediaOptionNames[mediaOptionDetails.mediaOptionType], adt: stats.tload - stats.trequest }, + }); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleLevelLoaded(mediaOptionDetails, levelLoadedData.stats); + this.hls.trigger(HlsEvent.LEVEL_LOADED, levelLoadedData); + if (mediaDetailsEntity.unchangedCount === 0) { + const levelUpdatedData = { + level: 0, + details: mediaOptionDetails, + }; + // This is critical for gapless. Muze uses this to set media duration + this.hls.trigger(HlsEvent.LEVEL_UPDATED, levelUpdatedData); + } + if (mediaOptionDetails === null || mediaOptionDetails === void 0 ? void 0 : mediaOptionDetails.daterangeTags) { + const dateRangeTags = { daterangeTags: mediaOptionDetails.daterangeTags }; + // this.logger.debug('Date range tags parsed: %o', dateRangeTags); + this.logger.qe({ critical: true, name: 'dateRangeTags', data: { dateRangeTags } }); + this.hls.trigger(HlsEvent.DATERANGE_UPDATED, dateRangeTags); + } + return EMPTY; + })); + const audioSource$ = rootPlaylistQuery.enableMediaOptionSwitchedForType$(MediaOptionType.AltAudio).pipe(switchMap((mediaOption) => { + const altOption = rootPlaylistQuery.alternateMediaOptionById(MediaOptionType.AltAudio, mediaOption.mediaOptionId); + if (altOption) { + this.triggerAudioSwitch(altOption); + } + return EMPTY; + })); + // The first audio switch occurs before the rootPlaylistQuery is ready. As a result, we'll monitor the + // rootPlaylistEntity to trigger the first audio switch + const firstAudioSwitch$ = rootPlaylistQuery.rootPlaylistEntity$.pipe(filter((rootEntity) => rootEntity.enabledMediaOptionKeys[MediaOptionType.AltAudio].mediaOptionId !== null), take(1), switchMap((rootEntity) => { + const mediaOptionId = rootEntity.enabledMediaOptionKeys[MediaOptionType.AltAudio].mediaOptionId; + if (mediaOptionId) { + const altOption = rootEntity.mediaOptionListTuple[MediaOptionType.AltAudio].mediaOptions.find((option) => option.mediaOptionId === mediaOptionId); + this.triggerAudioSwitch(Object.assign(Object.assign({}, altOption), { url: redactUrl(altOption === null || altOption === void 0 ? void 0 : altOption.url) })); + } + return EMPTY; + })); + // Trigger SUBTITLE_TRACK_SWITCH only when the HTML5 texttracks have been created. + // MatchPoint will call addCueChange on the enabled texttrack. + const subtitleSource$ = waitFor(mediaElementQuery.textTracksCreated$, (created) => created).pipe(switchMap(() => { + return rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Subtitle).pipe(switchMap((mediaOption) => { + const altOption = rootPlaylistQuery.alternateMediaOptionById(MediaOptionType.Subtitle, mediaOption.mediaOptionId); + if (altOption) { + const data = { + trackId: altOption.id, + mediaOptionId: altOption.mediaOptionId, + groupId: altOption.groupId, + persistentId: altOption.persistentID, + name: altOption.name, + }; + this.logger.qe({ critical: true, name: 'textTrackSwitch', data }); + this.logger.debug(`Subtitle track switch track: ${altOption.id}`); + this.hls.trigger(HlsEvent.SUBTITLE_TRACK_SWITCH, { + track: Object.assign({}, altOption), + hidden: false, + }); + } + else { + this.hls.trigger(HlsEvent.SUBTITLE_TRACK_SWITCH, { + track: undefined, + hidden: false, + }); + this.logger.qe({ critical: true, name: 'textTrackSwitch', data: { unselected: true } }); + } + return EMPTY; + })); + })); + const sessionData$ = rootPlaylistQuery.sessionData$.pipe(filter((d) => d.complete != undefined), take(1), tap((sd) => this.logger.debug('Session Data Complete: %o', sd)), map((sd) => { + this.hls.trigger(HlsEvent.SESSION_DATA_COMPLETE, sd); + })); + const prefferedLevels$ = rootPlaylistQuery.getPreferredMediaOptionsByType$(MediaOptionType.Variant).pipe(skip(1), map((prefLevels) => { + var _a; + const variantList = prefLevels; + this.logger.debug('Levels changed %o', variantList); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleLevelsChanged(variantList); + this.logger.qe({ critical: true, name: 'levelsChanged', data: { numLevels: variantList.length } }); + variantList.forEach((level) => { + const { mediaOptionId, bandwidth, bitrate, videoCodec, audioCodec, height, width, videoRange, iframes } = level; + this.logger.qe({ critical: true, name: 'manifestLevel', data: { mediaOptionId, bandwidth, bitrate, videoCodec, audioCodec, height, width, videoRange, iframes } }); + }); + this.hls.trigger(HlsEvent.LEVELS_CHANGED, { requiresReset: false, levels: variantList }); + //TODO fix require reset + })); + const altPrefferedLevels$ = rootPlaylistQuery.getPreferredMediaOptionsByType$(MediaOptionType.AltAudio).pipe(map((prefLevels) => { + const altList = prefLevels; + this.logger.debug('Audio tracks updated %o', altList); + this.hls.trigger(HlsEvent.AUDIO_TRACKS_UPDATED, { audioTracks: altList }); + //TODO fix require reset + })); + // Trigger SUBTITLE_TRACKS_UPDATED only when the HTML5 texttracks have been created. + // MatchPoint may query the available media option list and relate them to the HTML5 texttracks + const subPrefferedLevels$ = waitFor(mediaElementQuery.textTracksCreated$, (created) => created).pipe(switchMap(() => { + return rootPlaylistQuery.getPreferredMediaOptionsByType$(MediaOptionType.Subtitle).pipe(take(1), map((prefLevels) => { + const altList = prefLevels; + // Potentially large object log + // this.logger.info('Subtitle tracks updated %o', altList); + this.hls.trigger(HlsEvent.SUBTITLE_TRACKS_UPDATED, { subtitleTracks: altList }); + this.logger.info('Subtitle tracks created'); + this.hls.trigger(HlsEvent.SUBTITLE_TRACKS_CREATED); + //TODO fix require reset + })); + })); + return merge(variantSource$, audioSource$, subtitleSource$, sessionData$, prefferedLevels$, altPrefferedLevels$, subPrefferedLevels$, levelLoaded$, levelLoading$, firstAudioSwitch$); + } + mediaElementQueryListener(mediaElementQuery, rootPlaylistQuery) { + const seekSource$ = mediaElementQuery.seekTo$.pipe(map((seekTo) => { + var _a, _b; + if (seekTo && isFiniteNumber(seekTo.pos)) { + this.logger.debug(`Seeking pos:${seekTo.pos}`); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleSeek('SEEKING'); + this.hls.trigger(HlsEvent.SEEKING, { seekToPos: seekTo.pos }); + } + else if (seekTo === null) { + (_b = this.rtc) === null || _b === void 0 ? void 0 : _b.handleSeek('SEEKED'); + this.logger.debug('Seeked'); + this.hls.trigger(HlsEvent.SEEKED); + } + })); + const desiredRateSource$ = mediaElementQuery.desiredRate$.pipe(startWith(0), pairwise(), map((pair) => { + var _a; + const oldRate = pair[0]; + const newRate = pair[1]; + if (isIframeRate(newRate)) { + if (this.iframeSwitchStart == 0) { + this.iframeSwitchStart = performance.now(); + } + } + else { + this.iframeSwitchStart = 0; + } + this.logger.debug(`Rate changed oldRate: ${oldRate}, newRate: ${newRate}`); + this.hls.trigger(HlsEvent.DESIRED_RATE_CHANGED, { oldRate, newRate }); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleDesiredRateChanged(oldRate, newRate); + })); + const audioBufferSource$ = mediaElementQuery.sourceBufferEntityByType$(SourceBufferType.AltAudio).pipe(filter((buffer) => !!buffer), distinctUntilChanged((prev, cur) => prev.totalBytes === cur.totalBytes), map((buffer) => { + this.logger.trace('Audio Buffer Appended. Buffer= %o', buffer); + this.hls.trigger(HlsEvent.BUFFER_APPENDED); + })); + const variantBufferSource$ = mediaElementQuery.sourceBufferEntityByType$(SourceBufferType.Variant).pipe(filter((buffer) => !!buffer), distinctUntilChanged((prev, cur) => prev.totalBytes === cur.totalBytes), map((buffer) => { + var _a; + this.logger.trace('Variant Buffer Appended. Buffer= %o', buffer); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleVariantBufferAppended(buffer.timestampOffset, buffer.totalBytes); + this.hls.trigger(HlsEvent.BUFFER_APPENDED); + })); + const stallInfo$ = mediaElementQuery.stallInfo$.pipe(filterNullOrUndefined(), withLatestFrom(mediaElementQuery.combinedBuffer$), map(([stallInfo, buffered]) => { + var _a; + this.logger.qe({ critical: true, name: 'stall', data: Object.assign(Object.assign({}, stallInfo), { buffered }) }); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleStalled(stallInfo, mediaElementQuery.getCombinedBufferInfo(stallInfo.currentTime, 0).len); + this.hls.trigger(HlsEvent.STALLED, stallInfo); + })); + const fragChangeMonitor$ = combineLatest([ + of(rootPlaylistQuery), + combineQueries([mediaElementQuery.timeupdate$, mediaElementQuery.bufferedSegmentsByType$(SourceBufferType.Variant)]).pipe(throttleTime(1000), map(([currentTime, bufferedSegments]) => { + const playingFrag = bufferedSegments === null || bufferedSegments === void 0 ? void 0 : bufferedSegments.find((seg) => seg.startPTS <= currentTime && seg.endPTS > currentTime); + return playingFrag; + }), filter((playingFrag) => !!playingFrag), startWith(null), pairwise()), + ]).pipe(switchMap(([rootPlaylistQuery, [a, b]]) => { + var _a; + const playingFrag = b === null || b === void 0 ? void 0 : b.frag; + const previousFrag = a === null || a === void 0 ? void 0 : a.frag; + if (playingFrag && !fragEqual(previousFrag, playingFrag)) { + this.hls.trigger(HlsEvent.FRAG_CHANGED, b); + if (this.hls.inGaplessMode) { + this.checkAndTriggerReadyForNext(mediaElementQuery, b); + } + if (!previousFrag || playingFrag.mediaOptionId !== previousFrag.mediaOptionId) { + const variantOption = rootPlaylistQuery.mediaOptionListQueries[MediaOptionType.Variant].mediaOptionFromId(playingFrag.mediaOptionId); + if (!variantOption) { + // TODO investigate this.. sometimes happens in gapless mode + this.logger.warn('variantInfo is undefined in fragChangeMonitor'); + return EMPTY; + } + const oldVariant = previousFrag ? previousFrag.mediaOptionId : ''; + const newVariant = playingFrag.mediaOptionId; + const data = { + oldVariant, + newVariant, + bitrate: variantOption.bitrate, + bandwidth: variantOption.bandwidth, + avgBandwidth: variantOption.avgBandwidth, + width: variantOption.width, + height: variantOption.height, + levelCodec: variantOption.levelCodec, + frameRate: variantOption.frameRate, + }; + if (variantOption.iframes) { + const rate = mediaElementQuery.desiredRate; + const state = mediaElementQuery.isIframeRate; + const startupTime = performance.now() - this.iframeSwitchStart; + this.logger.qe({ critical: true, name: 'iframes', data: { state, rate, oldVariant, newVariant, startupTime } }); + } + this.logger.qe({ critical: true, name: 'variantSwitched', data }); + (_a = this.rtc) === null || _a === void 0 ? void 0 : _a.handleLevelSwitched({ url: variantOption.url, mediaOptionId: variantOption.mediaOptionId, oldVariant: oldVariant !== '' ? oldVariant : undefined, newVariant: newVariant }); + this.hls.trigger(HlsEvent.LEVEL_SWITCHED, variantOption); + } + } + return EMPTY; + })); + const fullyBuffered$ = mediaElementQuery.isBufferedToEnd$(this.hls.config.maxBufferHole, false).pipe(filter((isBuffered) => isBuffered === true), + // Use asyncScheduler as the READY_FOR_NEXT_ITEM event could cause an item queue change + observeOn(asyncScheduler), map((isBuffered) => { + if (isBuffered && !this.hls.itemQueue.isPreloading() && this.hls.inGaplessMode) { + const combinedBuffer = mediaElementQuery.getCombinedBufferInfo(mediaElementQuery.currentTime, 0); + let duration = 0; + if (combinedBuffer) { + duration = combinedBuffer.end; + } + else { + this.logger.info('Combined Buffer is not ready, do not trigger READY_FOR_NEXT_ITEM'); + return; + } + const mediaDuration = mediaElementQuery.mediaElementDuration; + // Only trigger READY_FOR_NEXT with less than 10 seconds to play. This is a Muze hack so that + // short songs are not skipped + if (duration > 0 && mediaDuration - mediaElementQuery.currentTime < 10) { + this.logger.info(`Trigger READY_FOR_NEXT_ITEM BufferDuration=${duration}, mediaDuration=${mediaDuration}`); + this.hls.trigger(HlsEvent.READY_FOR_NEXT_ITEM, { duration }); + } + } + })); + return merge(seekSource$, desiredRateSource$, audioBufferSource$, variantBufferSource$, stallInfo$, fragChangeMonitor$, fullyBuffered$); + } + checkAndTriggerReadyForNext(mediaElementQuery, currentFrag) { + if (!currentFrag || !currentFrag.frag) { + return; + } + this.logger.trace('currentFrag %o', currentFrag); + const pos = mediaElementQuery.currentTime; + const combinedBuffer = mediaElementQuery.getCombinedBufferInfo(pos, 0); + if (!combinedBuffer) { + this.logger.info('Combined Buffer is not ready, do not trigger READY_FOR_NEXT_ITEM'); + return; + } + const duration = combinedBuffer.end; + const mediaDuration = mediaElementQuery.mediaElementDuration; + const bufInfoMonitor = mediaElementQuery.bufferMonitorInfo; + // The closeToEndThreashold is typically half of the target duration. This differs from 2.0 that uses the full target duration. + // This leaves short time to buffer the next item. Good for audio but will not work for video. + // If we ever want to do gapless video we'll need to re-visit the using the fullyBuffered$ method above + const closeToEndThreshold = Math.max(bufInfoMonitor.almostDryWaterLevelSeconds, bufInfoMonitor.lowWaterLevelSeconds / 2); + if (mediaDuration - currentFrag.endPTS <= closeToEndThreshold || currentFrag.frag.isLastFragment) { + if (this.hls.inGaplessMode && !this.hls.isPreloading) { + this.logger.info(`Trigger READY_FOR_NEXT_ITEM BufferDuration=${duration}, mediaDuration=${mediaDuration}`); + this.hls.trigger(HlsEvent.READY_FOR_NEXT_ITEM, { duration }); + } + } + } + loaderQueryListener(loaderQuery) { + const unresolvedUriLoadingSource$ = loaderQuery.unresolvedUriLoading$.pipe(map((entities) => { + return entities.map((entity) => { + this.logger.debug('Unresolved Uri Loading, data= %o', entity); + const data = { uri: entity.uri, responseType: entity.responseType, userAgent: entity.userAgent }; + this.hls.trigger(HlsEvent.UNRESOLVED_URI_LOADING, data); + }); + })); + return merge(unresolvedUriLoadingSource$); + } + triggerAudioSwitch(altOption) { + if (altOption) { + this.logger.info(`Audio track switched id: ${altOption.id} ${altOption.mediaOptionId}`); + this.logger.qe({ critical: true, name: 'audioTrackSwitched', data: { altOption } }); + this.hls.trigger(HlsEvent.AUDIO_TRACK_SWITCHED, { id: altOption.id }); + } + } + triggerManifestLoaded(loadRootMediaOptionsResult) { + var _a; + const payload = { + levels: loadRootMediaOptionsResult.rootMediaOptionsTuple[MediaOptionType.Variant], + audioTracks: loadRootMediaOptionsResult.rootMediaOptionsTuple[MediaOptionType.AltAudio], + subtitleTracks: loadRootMediaOptionsResult.rootMediaOptionsTuple[MediaOptionType.Subtitle], + url: loadRootMediaOptionsResult.baseUrl, + audioMediaSelectionGroup: loadRootMediaOptionsResult.audioMediaSelectionGroup, + subtitleMediaSelectionGroup: loadRootMediaOptionsResult.subtitleMediaSelectionGroup, + stats: loadRootMediaOptionsResult.stats, + isMediaPlaylist: loadRootMediaOptionsResult.isMediaPlaylist, + }; + this.logger.debug('Manifest loaded'); + this.logger.qe({ critical: true, name: 'manifestLoaded', data: { numLevels: (_a = payload.levels) === null || _a === void 0 ? void 0 : _a.length } }); + this.hls.trigger(HlsEvent.MANIFEST_LOADED, payload); + } + triggerManifestParsed(rootQuery) { + var _a, _b; + // TODO Fix firstlevel, audio, video and altAudio + const manifestParsedData = { + levels: rootQuery.mediaOptionListQueries[MediaOptionType.Variant].filteredMediaOptionList, + firstLevel: 0, + audio: false, + video: true, + altAudio: false, + audioTracks: rootQuery.mediaOptionListQueries[MediaOptionType.AltAudio].filteredMediaOptionList, + audioMediaSelectionGroup: rootQuery.audioMediaSelectionGroup, + subtitleMediaSelectionGroup: rootQuery.subtitleMediaSelectionGroup, + stats: rootQuery.loadStats, + }; + this.logger.debug('Manifest parsed %o', manifestParsedData); + this.logger.qe({ critical: true, name: 'manifestParsed', data: { numLevels: (_a = manifestParsedData.levels) === null || _a === void 0 ? void 0 : _a.length } }); + (_b = this.rtc) === null || _b === void 0 ? void 0 : _b.handleManifestParsed(manifestParsedData); + this.hls.trigger(HlsEvent.MANIFEST_PARSED, manifestParsedData); + } + urlRedactedManifestLoaded(indata) { + const outdata = Object.assign({}, indata); + outdata.url = redactUrl(outdata.url); + outdata.levels = urlRedactedLevelInfo(outdata.levels); + outdata.audioTracks = urlRedactedAltMediaOption(outdata.audioTracks); + outdata.subtitleTracks = urlRedactedAltMediaOption(outdata.subtitleTracks); + return outdata; + } + urlRedactedManifestParsed(indata) { + const outdata = Object.assign({}, indata); + outdata.levels = urlRedactedLevelInfo(outdata.levels); + outdata.audioTracks = urlRedactedAltMediaOption(outdata.audioTracks); + return outdata; + } + } + + var SwitchReason; + (function (SwitchReason) { + SwitchReason["LowBandwidth"] = "LowBandwidth"; + SwitchReason["HighBandwidth"] = "HighBandwidth"; + SwitchReason["PreferredListChanged"] = "PreferredListChanged"; + SwitchReason["IframeModeChange"] = "IframeModeChange"; + SwitchReason["None"] = ""; + })(SwitchReason || (SwitchReason = {})); + + const firstMediaOptionSelectionMetrics = { + minValidBitrate: 2000000, + maxValidBitrate: 5000000, + maxPreferredBitrate: 3000000, + minValidHeight: 480, + maxValidHeight: 720, + }; + // Filter media options that are not compatible with the starting tier + // Currently we hit an issue when switching between audio codecs: ac-3 / ec-3 / mp4a.40.* + // and video codecs: dolby, hevc, avc + const isCompatible = (mediaOption1, mediaOption2) => { + let isVideoCompatible = true; + if (mediaOption1.videoCodec && mediaOption2.videoCodec) { + isVideoCompatible = MediaUtil.isCompatibleVideoCodec(mediaOption1.videoCodec, mediaOption2.videoCodec); + } + let isVideoRangeSame = false; + if (mediaOption1.videoRange && mediaOption2.videoRange) { + isVideoRangeSame = mediaOption1.videoRange == mediaOption2.videoRange; + } + else if (!mediaOption1.videoRange && !mediaOption2.videoRange) { + isVideoRangeSame = true; + } + let isAudioCompatible = true; + if (mediaOption1.audioCodec && mediaOption2.audioCodec) { + // Both have valid audio codecs, check with MediaUtil.isAudioCompatible + isAudioCompatible = MediaUtil.isCompatibleAudioCodec(mediaOption1.audioCodec, mediaOption2.audioCodec); + } + return isVideoCompatible && isVideoRangeSame && isAudioCompatible; + }; + function filterMediaOptionsBasedOnFirstMediaOptions(mediaOptions, firstMediaOptionInfo) { + // Filter out again according to starting level, and save audioGroups of filtered levels if present + return mediaOptions.reduce((prev, cur) => { + const validMediaOption = isCompatible(firstMediaOptionInfo, cur); + if (validMediaOption) { + const audioGroup = cur.audioGroupId; + if (audioGroup) { + prev.audioGroups.add(audioGroup); + } + prev.mediaOptions.add(cur); + } + const subtitleGroup = cur.subtitleGroupId; + if (subtitleGroup) { + prev.subtitleGroups.add(subtitleGroup); + } + const closedCaptionGroup = cur.closedcaption; + if (closedCaptionGroup) { + prev.closedCaptionGroups.add(closedCaptionGroup); + } + return prev; + }, { mediaOptions: new Set(), audioGroups: new Set(), subtitleGroups: new Set(), closedCaptionGroups: new Set() }); + } + function chooseFirstMediaOptionBasedOnScore(mediaOptions, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + const ranking = mediaOptions.reduce((prev, cur) => { + if (cur.iframes) { + return prev; + } + let result = prev; + const rank = getScoreRank(cur, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + if (!prev || rank.isGreaterThan(prev.bestRank) || (rank.isEqualTo(prev.bestRank) && cur.bandwidth < prev.selected.bandwidth)) { + result = { selected: cur, bestRank: rank }; + } + return result; + }, null); + return ranking.selected; + } + // Determine the highest ranking MediaOption to be used as first MediaOption (breaking ties by prioritizing the higher bitrate if two MediaOptions have the same rank) + function chooseFirstMediaOptionBasedOnRanking(mediaOptions, metrics, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + const ranking = mediaOptions.reduce((prev, cur) => { + if (cur.iframes) { + return prev; + } + let result = prev; + const rank = getMediaOptionRank(cur, metrics, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + if (!prev || rank.isGreaterThan(prev.bestRank) || (rank.isEqualTo(prev.bestRank) && cur.bitrate > prev.selected.bitrate)) { + result = { selected: cur, bestRank: rank }; + } + return result; + }, null); + return ranking.selected; + } + // A MediaOption SCORE ranking is determined by a multisort comparison of 2 properties in order of importance: + // (1) within bandwidth cap + // (2) SCORE (determined by the playlist) + function getScoreRank(mediaInfo, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + const score = mediaInfo.score; + const isWithinCap = bandwidthHistory && + adaptiveStartupConfig && + playlistEstimate && + fragEstimate && + !isWithinBandwidthCap(mediaInfo, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) + ? MatchRanking.INVALID + : MatchRanking.VALID; // If no bandwidthHistory or adaptiveStartupConfig specified, then don't mark the media option as INVALID; + return new MediaOptionRank(isWithinCap, score); + } + // A MediaOption's ranking is determined by a multisort comparison on 8 properties in order of importance: + // (1) validMetrics (between 2-5 mbps, height between 480-720p) + // (2) videoRangeRank (PQ/HLG/SDR) + // (3) videoRank (video codec rank) + // (4) audioChannelRank (if available and supported, then a 5.1 ac-3 tier takes precedence over stereo ec-3 tier) + // (5) audioCodecRank (audio codec rank) + // (6) within bandwidth cap + // (7) preferred max bitrate (less than 3 mbps) + // (8) MediaOption's height + function getMediaOptionRank(mediaInfo, firstMediaOptionSelectionMetrics, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + const validMetrics = hasValidMetrics(mediaInfo.bitrate, mediaInfo.height, firstMediaOptionSelectionMetrics) ? MatchRanking.VALID : MatchRanking.INVALID; + const videoRangeRank = getVideoRangeRanking(mediaInfo.videoRange); + const { videoCodecRank, audioCodecRank } = getAudioVideoCodecRanks(mediaInfo); + const lessThanMaxPreferredBitrate = mediaInfo.bitrate < firstMediaOptionSelectionMetrics.maxPreferredBitrate ? MatchRanking.VALID : MatchRanking.INVALID; + const DEFAULT_AUDIO_CHANNEL_COUNT = 1; + const audioChannelCount = mediaInfo.audioChannelCount || DEFAULT_AUDIO_CHANNEL_COUNT; // use the channel count for ranking; + const isWithinCap = bandwidthHistory && + adaptiveStartupConfig && + playlistEstimate && + fragEstimate && + !isWithinBandwidthCap(mediaInfo, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) + ? MatchRanking.INVALID + : MatchRanking.VALID; // If no bandwidthHistory or adaptiveStartupConfig specified, then don't mark the MediaOption as INVALID + return new MediaOptionRank(validMetrics, videoRangeRank, videoCodecRank, audioChannelCount, audioCodecRank, isWithinCap, lessThanMaxPreferredBitrate, mediaInfo.height); + } + function isWithinBandwidthCap(mediaInfo, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + const { targetDuration, targetStartupMs } = adaptiveStartupConfig; + const { avgPlaylistLoadTimeMs } = playlistEstimate; + const { avgParseTimeMs } = fragEstimate; + const { avgBufferCreateMs, avgInitFragAppendMs, avgDataFragAppendMs } = bufferEstimate; + const avgBufferTimeMs = avgInitFragAppendMs + avgDataFragAppendMs; + const { avgBandwidth, avgLatencyMs } = bandwidthHistory; + const fragCount = 1; // Math.ceil(targetDuration / maxDuration); + return (mediaInfo.bandwidth <= avgBandwidth && // has sufficient bandwidth + (((mediaInfo.avgBandwidth || mediaInfo.bandwidth) * targetDuration) / avgBandwidth) * 1000 + + avgPlaylistLoadTimeMs + + avgBufferCreateMs + + (avgLatencyMs + avgParseTimeMs + avgBufferTimeMs) * fragCount <= + targetStartupMs); // can be loaded within targetStartupMs + } + function onlyIFrames(mediaOptions) { + return mediaOptions.every((opt) => opt.iframes); + } + function hasValidMetrics(bitrate, height, metrics) { + const inRange = (input, minVal, maxVal) => (input - minVal) * (input - maxVal) <= 0; + return inRange(bitrate, metrics.minValidBitrate, metrics.maxValidBitrate) && inRange(height, metrics.minValidHeight, metrics.maxValidHeight); + } + /** + * Choose first MediaOption from MediaOption array + * + * @param mediaOptions Set of MediaOptions to choose from + * @param hasScoreAvailable If SCORE metric is available + * @param metrics Metrics to use for selection + * @param bandwidthHistory Bandwidth history + * @param adaptiveStartupConfig Override configs + */ + function chooseFirstMediaOption(mediaOptions, metrics, hasScoreAvailable, logger, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + let firstMediaOption; + if (!mediaOptions || mediaOptions.length < 1 || onlyIFrames(mediaOptions)) { + logger.warn('no non-iframe media option found'); + return; + } + if (hasScoreAvailable) { + firstMediaOption = chooseFirstMediaOptionBasedOnScore(mediaOptions, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + } + else { + firstMediaOption = chooseFirstMediaOptionBasedOnRanking(mediaOptions, metrics, bandwidthHistory, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + } + if (!firstMediaOption) { + logger.warn('no valid first media option found'); + } + return firstMediaOption; + } + function filterRegularLevelsBasedOnCapOn1080p(levels) { + // standard 1080p resolution with a slight tolerance of 1.2 + const PIXELS_CAP = 2488320; + const capedLevels = levels.filter((levelInfo) => !levelInfo.iframes && (!levelInfo.width || !levelInfo.height || levelInfo.width * levelInfo.height <= PIXELS_CAP)); + return capedLevels; + } + + /* + * simple ABR level switcher + * - compute next level based on last fragment bw heuristics + * - implement an abandon rules triggered if we have less than 2 frag buffered and if computed bw shows that we risk buffer stalling + * + * 2018 Apple Inc. All rights reserved. + */ + const abrLogName = { name: 'abr' }; + function getMaxStarvationDelaySec(fragDuration, maxBufStarvationSec) { + return isFiniteNumber(fragDuration) ? Math.min(fragDuration, maxBufStarvationSec) : maxBufStarvationSec; + } + function instantBwTooSlow(avgBw, abrStatus, bwStatus) { + const instantBw = bwStatus.instantBw; + return abrStatus.fragDownloadSlow || abrStatus.fragDownloadTooSlow || (isFiniteNumber(instantBw) && instantBw < avgBw); + } + function gotSlowMedia(abrStatus) { + return abrStatus.fragDownloadSlow || abrStatus.fragDownloadTooSlow; + } + function hasReliableBandwidthEstimate(bandwidthEstimate) { + return isFiniteNumber(bandwidthEstimate === null || bandwidthEstimate === void 0 ? void 0 : bandwidthEstimate.avgBandwidth); + } + function nextAutoMediaOption(abrConfig, rootPlaylistQuery, rootPlaylistService, mediaLibraryQuery, mediaElementQuery, statsQuery, logger) { + let defaultAutoVariantOption = rootPlaylistQuery.nextMaxAutoOptionId; + // In 2.0 arch, There was check to see if the nextMaxAutoOptionId was + // in penalty box. Don't see a possibility of that, here in 2.1 as + // the nexMaxAutoOptionId is set from the preferrdList. + if (defaultAutoVariantOption !== NoMediaOption.mediaOptionId && !hasReliableBandwidthEstimate(statsQuery.getBandwidthEstimate())) { + if (mediaElementQuery.isIframeRate) { + // no group matching for iframe mode + return { variantMediaOption: defaultAutoVariantOption, holdOffDuration: 0, lowestCandidate: null }; + } + else { + // defaultAutoVariantOption (rootPlaylistQuery.nextMaxAutoOptionId) gets set in likelyToStall. + // Even though it has matching altAudio and subtitle mediaOptions at that time. + // It might not at this moment due to penalized alternates. + // getBestMediaOptionTupleFromVariantAndPersistentId will look for a + // fallback variant that has matching alternates. + // If it comes up short, then continue to use the current variant and alternates. + const variantMediaOption = rootPlaylistQuery.variantMediaOptionById(defaultAutoVariantOption); + const subtitleAltOption = rootPlaylistQuery.enabledAlternateMediaOptionByType(MediaOptionType.Subtitle); + const audioAltOption = rootPlaylistQuery.enabledAlternateMediaOptionByType(MediaOptionType.AltAudio); + const audioPersistentId = audioAltOption === null || audioAltOption === void 0 ? void 0 : audioAltOption.persistentID; + const subtitlePersistentId = subtitleAltOption === null || subtitleAltOption === void 0 ? void 0 : subtitleAltOption.persistentID; + const sdrOnly = !rootPlaylistQuery.preferHDR; + const mediaOptionTuple = rootPlaylistService.getBestMediaOptionTupleFromVariantAndPersistentId(rootPlaylistQuery, variantMediaOption, audioPersistentId, subtitlePersistentId, undefined, [], sdrOnly, false, false); + logger.info(`capped at sdrOnly ${sdrOnly} ${JSON.stringify(defaultAutoVariantOption)} with matching alternates: ${JSON.stringify(mediaOptionTuple)}`); + if (rootPlaylistQuery.isValidMediaOptionTuple(mediaOptionTuple)) { + defaultAutoVariantOption = mediaOptionTuple[MediaOptionType.Variant].mediaOptionId; + const alternates = { + altAudio: mediaOptionTuple[MediaOptionType.AltAudio], + subtitle: mediaOptionTuple[MediaOptionType.Subtitle], + }; + return { variantMediaOption: defaultAutoVariantOption, holdOffDuration: 0, alternates, lowestCandidate: null }; + } + else { + logger.info(`No fallback variant with matching alternates for (capped) level ${defaultAutoVariantOption}: use currentVariant instead.`); + } + const currentVariant = rootPlaylistQuery.enabledMediaOptionKeys[MediaOptionType.Variant]; + return { variantMediaOption: currentVariant.mediaOptionId, holdOffDuration: 0, lowestCandidate: null }; // by using currentVariant, switch will be skipped. + } + } + return nextABRAutoMediaOption(abrConfig, rootPlaylistQuery, mediaLibraryQuery, mediaElementQuery, statsQuery, logger); + } + function nextABRAutoMediaOption(abrConfig, rootPlaylistQuery, mediaLibraryQuery, mediaElementQuery, statsQuery, logger) { + const loggerChild = logger.child({ name: 'abr' }); + const iframeMode = mediaElementQuery.isIframeRate; + const enabledVariantOptionId = rootPlaylistQuery.enabledMediaOptionIdByType(MediaOptionType.Variant); + const autoVariantOption = findNextABRAutoVariantOptionInMode(iframeMode, abrConfig, rootPlaylistQuery, mediaLibraryQuery, mediaElementQuery, statsQuery, loggerChild); + loggerChild.info(`nextABRAutoMediaOption ${enabledVariantOptionId}->${autoVariantOption.variantMediaOption}`); + return autoVariantOption; + } + function getABRPlaybackRate(mediaElementQuery) { + // playbackRate is the absolute value of the playback rate; if v.playbackRate is 0, we use 1 to load as + // if we're playing back at the normal rate. + return mediaElementQuery.playbackRate !== 0 ? Math.abs(mediaElementQuery.playbackRate) : 1; + } + // Scaled buffer ahead in seconds for video buffer + function getBufferAheadSec(mediaElementQuery, maxBufferHole) { + return mediaElementQuery.getCurrentWaterLevelByType(SourceBufferType.Variant, maxBufferHole) / getABRPlaybackRate(mediaElementQuery); + } + function findLowestValidVariantIndex(minAutoVariantIndex, availableVariantOptions, iframeMode, rootPlaylistQuery) { + if (iframeMode) { + return minAutoVariantIndex; + } + let lowestValidVariantId = -1; + if (minAutoVariantIndex < 0) { + return lowestValidVariantId; + } + for (let i = minAutoVariantIndex; i < availableVariantOptions.length; ++i) { + const variantMediaOption = availableVariantOptions[i]; + const alternates = getMatchingAlternates(variantMediaOption, rootPlaylistQuery); + if (alternates.altAudio && alternates.subtitle) { + lowestValidVariantId = i; + break; + } + } + return lowestValidVariantId; + } + function findNextABRAutoVariantOptionInMode(iframeMode, abrConfig, rootPlaylistQuery, curOptionQuery, mediaElementQuery, statsQuery, logger) { + const variantOptions = rootPlaylistQuery.preferredMediaOptions[MediaOptionType.Variant].filter((variantOption) => variantOption.iframes === iframeMode); + if (!variantOptions.length) { + return { variantMediaOption: NoMediaOption.mediaOptionId, holdOffDuration: 0, lowestCandidate: null }; + } + // Find minAutoVariant if it was set because of highBWTrigger + let minAutoVariantOption = 0; + const minAutoVariantOptionId = rootPlaylistQuery.nextMinAutoOptionId; + if (minAutoVariantOptionId !== NoMediaOption.mediaOptionId) { + const found = variantOptions.findIndex((variantOption) => variantOption.mediaOptionId === minAutoVariantOptionId); + if (found >= 0) { + minAutoVariantOption = found; + logger.info(`minAutoVariantOptionId set=${minAutoVariantOptionId}, minAutoVariantOption=${minAutoVariantOption}/${variantOptions.length}`); + } + } + // Ensure the minAutoVariant is valid + minAutoVariantOption = findLowestValidVariantIndex(minAutoVariantOption, variantOptions, iframeMode, rootPlaylistQuery); + if (minAutoVariantOption < 0) { + return { variantMediaOption: NoMediaOption.mediaOptionId, holdOffDuration: 0, lowestCandidate: null }; + } + let maxAutoVariantOption = variantOptions.length - 1; + // if forced auto level has been defined, use it to cap ABR computed quality level + const maxAutoVariantOptionId = rootPlaylistQuery.nextMaxAutoOptionId; + if (maxAutoVariantOptionId !== NoMediaOption.mediaOptionId) { + const found = variantOptions.findIndex((variantOption) => variantOption.mediaOptionId === maxAutoVariantOptionId); + if (found >= 0) { + maxAutoVariantOption = found; + logger.info(`maxAutoVariantOptionId set=${maxAutoVariantOptionId}, maxAutoVariantOption=${maxAutoVariantOption}/${variantOptions.length}`); + } + } + const currentVariant = rootPlaylistQuery.variantMediaOptionById(curOptionQuery.mediaOptionId); + const currentVariantOptionDetails = curOptionQuery.mediaOptionDetails; // Get info even if in penalty box TODO check here + const bufferedDuration = (currentVariant === null || currentVariant === void 0 ? void 0 : currentVariant.iframes) !== iframeMode ? 0 : getBufferAheadSec(mediaElementQuery, abrConfig.maxBufferHole); + let bestLevelHeuristics, currentFragDuration; + if (!iframeMode) { + currentFragDuration = currentVariantOptionDetails ? currentVariantOptionDetails.targetduration : 0; + // TODO where is the current Frag and get duration, be careful not to use init segment + } + else { + const desiredIframeFPS = abrConfig.desiredIframeFPS; + currentFragDuration = currentVariantOptionDetails ? currentVariantOptionDetails.targetduration / desiredIframeFPS : 0; + // lower limit on iframe duration - dense tracks likely have a target duration that would achieve more than 8 fps if we displayed everything + currentFragDuration = Math.max(1 / desiredIframeFPS, currentFragDuration); + } + const bwUpFactor = abrConfig.abrBandWidthUpFactor; + const bwFactor = abrConfig.abrBandWidthFactor; + // First, look to see if we can find a level matching with our avg bandwidth AND that could also guarantee no rebuffering at all + bestLevelHeuristics = findBestVariantOption(variantOptions, currentFragDuration, minAutoVariantOption, maxAutoVariantOption, bufferedDuration, iframeMode, statsQuery.getCombinedEstimate(), statsQuery.bandwidthStatus, bwFactor, bwUpFactor, abrConfig, rootPlaylistQuery, curOptionQuery, mediaElementQuery, logger, true); + if (bestLevelHeuristics.variantMediaOption === NoMediaOption.mediaOptionId) { + logger.trace('rebuffering expected to happen, lets try to find a quality level minimizing the rebuffering'); + // not possible to get rid of rebuffering ... let's try to find + // level that will guarantee less than maxStarvationDelay of + // rebuffering if no matching level found, logic will return 0 + const maxStarvationDelay = getMaxStarvationDelaySec(currentFragDuration, abrConfig.maxStarvationDelay); + bestLevelHeuristics = findBestVariantOption(variantOptions, currentFragDuration, minAutoVariantOption, maxAutoVariantOption, bufferedDuration + maxStarvationDelay, iframeMode, statsQuery.getCombinedEstimate(), statsQuery.bandwidthStatus, bwFactor, bwUpFactor, abrConfig, rootPlaylistQuery, curOptionQuery, mediaElementQuery, logger, true); + if (bestLevelHeuristics.variantMediaOption === NoMediaOption.mediaOptionId && minAutoVariantOption >= 0) { + bestLevelHeuristics.variantMediaOption = variantOptions[minAutoVariantOption].mediaOptionId; + bestLevelHeuristics.alternates = iframeMode ? null : getMatchingAlternates(variantOptions[minAutoVariantOption], rootPlaylistQuery); + } + } + logger.debug(`[ findNextABRAutoVariantOptionInMode] Returning ${JSON.stringify(bestLevelHeuristics)}`); + return bestLevelHeuristics; + } + function getMatchingAlternates(variant, rootPlaylistQuery) { + const enabledMediaOptions = rootPlaylistQuery.enabledMediaOptionKeys; + const altAudioKey = enabledMediaOptions[MediaOptionType.AltAudio]; + const altAudio = isEnabledMediaOption(altAudioKey) ? rootPlaylistQuery.mediaOptionListQueries[MediaOptionType.AltAudio].getMatchingAlternate(altAudioKey.mediaOptionId, variant) : NoMediaOption; + const subtitleKey = enabledMediaOptions[MediaOptionType.Subtitle]; + const subtitle = isEnabledMediaOption(subtitleKey) ? rootPlaylistQuery.mediaOptionListQueries[MediaOptionType.Subtitle].getMatchingAlternate(subtitleKey.mediaOptionId, variant) : NoMediaOption; + return { altAudio, subtitle }; + } + const minItemsInBandwidthAverage = 4; + const shortTermBandwidthFactor = 1.8; + /** + * @param variantOptionList The filtered list of candidate variants + */ + function findBestVariantOption(variantOptionList, currentFragDuration, minAutoVariant, maxAutoVariant, maxFetchDuration, iframeMode, estimate, bwStatus, bwFactor, bwUpFactor, abrConfig, rootPlaylistQuery, mediaLibraryQuery, mediaElementQuery, logger, dumpParams = false) { + if (abrConfig.abrBandwidthEstimator !== 'bandwidth-history-controller') { + logger.warn(`Unsupported configuration: ${abrConfig.abrBandwidthEstimator} for ABR bandwidth estimator`); + } + const bandwidthSamples = bwStatus.bandwidthSampleCount; + const abrStatus = rootPlaylistQuery.abrStatus; + const maxBufferSize = mediaElementQuery.maxBufferSize; + const minTargetDurations = abrConfig.minTargetDurations || 1; + const mediaOptionListInfo = rootPlaylistQuery.mediaOptionListQueries[MediaOptionType.Variant].mediaOptionListInfo; + const hasScore = mediaOptionListInfo.hasScore; + if (!variantOptionList.length) { + return { variantMediaOption: NoMediaOption.mediaOptionId, holdOffDuration: -1, lowestCandidate: null }; + } + const enabledVariantOptionId = rootPlaylistQuery.enabledMediaOptionIdByType(MediaOptionType.Variant); + const enabledVariantOption = rootPlaylistQuery.variantMediaOptionById(enabledVariantOptionId); + const enabledVariantOptionIsValid = variantOptionList.find((variantOption) => variantOption.mediaOptionId === enabledVariantOptionId) != null; + const isSameMode = enabledVariantOption && enabledVariantOption.iframes === iframeMode; + const currentScore = enabledVariantOption && isSameMode ? enabledVariantOption.score : undefined; + const currentFrameRate = enabledVariantOption && isSameMode ? enabledVariantOption.frameRate : undefined; + const currentHeight = enabledVariantOption && isSameMode ? enabledVariantOption.height : undefined; + const bufferedDuration = isSameMode ? getBufferAheadSec(mediaElementQuery, abrConfig.maxBufferHole) : 0; + // Sanity capping + maxAutoVariant = Math.max(0, Math.min(variantOptionList.length - 1, maxAutoVariant)); + minAutoVariant = Math.max(0, Math.min(variantOptionList.length - 1, minAutoVariant)); + if (dumpParams) { + logger.debug(`[abr] findBestLevel params=${stringifyWithPrecision({ + enabledVariantOptionId, + currentFragDuration, + estimate, + minAutoVariant, + maxAutoVariant, + bwFactor, + bwUpFactor, + maxFetchDuration, + iframeMode, + maxBufferSize, + bufferedDuration, + currentScore, + currentFrameRate, + currentHeight, + })}`); + } + const mediaOptionDetailsEntityRecord = mediaLibraryQuery.mediaOptionDetailsEntityRecord; + const adjustedBwObj = getAdjustedBW(estimate.avgBandwidth, bwUpFactor, bwFactor, bandwidthSamples, logger); + let lowestCandidate; + for (let i = maxAutoVariant; i >= minAutoVariant; i--) { + const variantOption = variantOptionList[i]; + let variantOptionId = variantOption.mediaOptionId; + const variantOptionScore = variantOption.score; + const variantOptionDetails = mediaOptionDetailsEntityRecord && mediaOptionDetailsEntityRecord[variantOptionId] ? mediaOptionDetailsEntityRecord[variantOptionId].mediaOptionDetails : undefined; + const lastUpdateMs = mediaOptionDetailsEntityRecord && mediaOptionDetailsEntityRecord[variantOptionId] ? mediaOptionDetailsEntityRecord[variantOptionId].lastUpdateMillis : null; + const avgDuration = variantOptionDetails ? variantOptionDetails.totalduration / variantOptionDetails.fragments.length : currentFragDuration; + const isUpSwitch = enabledVariantOption != null && variantOption.bitrate > enabledVariantOption.bitrate; + const isDownSwitch = enabledVariantOption != null && variantOption.bitrate < enabledVariantOption.bitrate; + // don't switch up to a lower frame rate or switch down to a higher frame rate + const validFrameRate = !(currentFrameRate != null && ((isUpSwitch && variantOption.frameRate < currentFrameRate) || (isDownSwitch && variantOption.frameRate > currentFrameRate))); + // pick only ascending levels that have greater than/equal height than the current level + const validHeight = !(isUpSwitch && currentHeight != null && currentHeight > variantOption.height); + /* + Note: AMP playlists are set up in such a way that + - fragments are served from a primary host (e.g. Apple CDN, vod-ap1-aoc.tv.apple.com) and alternate host (e.g. Akamai, vod-ak-aoc.tv.apple.com) + - for both of these, the playlists are served from a single host (e.g. play.itunes.apple.com) + - the primary and alternate hosts are identified by a bitrate difference of 1 bit (primary bitrate > alternate bitrate by 1) + */ + // Don't use same bitrate on alternate CDN for downswitch. + const validCDN = !(isDownSwitch && (variantOption.bitrate === enabledVariantOption.bitrate - 1 || variantOption.bitrate === enabledVariantOption.bitrate + 1)); + // if SCORE attribute is available, pick ascending levels that have greater/equal SCORE than the current level + // if SCORE attributes are the same, ignore levels that have higher bitrate than current selected level + const validScore = !(hasScore && + isUpSwitch && + currentScore != null && + (variantOptionScore < currentScore || (variantOptionScore === currentScore && enabledVariantOption && variantOption.bitrate >= enabledVariantOption.bitrate))); + const validMode = variantOption.iframes === iframeMode; + if (!isFiniteNumber(avgDuration) || !validMode || !validFrameRate || !validHeight || !validCDN || !validScore) { + logger.debug(`variant ${variantOptionId} ineligible ${stringifyWithPrecision({ avgDuration, validMode, validFrameRate, validHeight, validCDN, validScore })}`); + continue; + } + const { adjustedbw, bitrate, fetchDuration, rejectLevelDueToPeakBW, canFitMultipleSegments, requireAlternates, alternates } = getVariantOptionMetrics(variantOption, variantOptionDetails, bufferedDuration, minTargetDurations, isUpSwitch, estimate, adjustedBwObj, currentFragDuration, maxBufferSize, lastUpdateMs, iframeMode, rootPlaylistQuery, logger); + if (dumpParams) { + logger.debug(`getVariantOptionMetrics in=${stringifyWithPrecision({ + bufferedDuration, + minTargetDurations, + isUpSwitch, + estimate, + bwUpFactor, + bwFactor, + currentFragDuration, + maxBufferSize, + bandwidthSamples, + lastUpdateMs, + iframeMode, + })} out=${stringifyWithPrecision({ adjustedbw, bitrate, fetchDuration, rejectLevelDueToPeakBW, canFitMultipleSegments, requireAlternates })} alternates=${JSON.stringify(alternates)}`); + } + // lowestCandidate is also guaranteed to be delivering fragments from same host. + if (requireAlternates && Boolean(alternates)) { + lowestCandidate = variantOptionId; + } + // if adjusted bw is greater than level bitrate AND + if (adjustedbw > bitrate && + canFitMultipleSegments && + !rejectLevelDueToPeakBW && + (!requireAlternates || Boolean(alternates)) && + // fragment fetchDuration unknown OR fragment fetchDuration less than max allowed fetch duration, then this level matches + (iframeMode || !fetchDuration || fetchDuration < maxFetchDuration)) { + // as we are looping from highest to lowest, this will return the best achievable quality level + if (instantBwTooSlow(adjustedbw, abrStatus, bwStatus) && enabledVariantOptionIsValid && isSameMode) { + // low inst bw and a switchdown imminent, only switch up if we have enough buffer + if (bufferedDuration <= 2 * avgDuration && isUpSwitch) { + // do not switch up + logger.info(`Last fragment too slow, not switching up instantBw=${bwStatus.instantBw}, ${enabledVariantOptionId}->${variantOptionId}, ${stringifyWithPrecision({ + bufferedDuration, + avgDuration, + isUpSwitch, + })}`); + variantOptionId = enabledVariantOptionId; + } + else if (isUpSwitch && bwUpFactor * bwStatus.instantBw < bitrate) { + // instantBw might be too slow for this level, but we could upswitch to a lower level + continue; + } + } + return { variantMediaOption: variantOptionId, holdOffDuration: fetchDuration, alternates: alternates, lowestCandidate: lowestCandidate }; + } + } + // not enough time budget even with quality level 0 ... rebuffering might happen + return { variantMediaOption: NoMediaOption.mediaOptionId, holdOffDuration: -1, lowestCandidate: lowestCandidate }; + } + // Get metrics used for switching + function getVariantOptionMetrics(variantOption, variantOptionDetails, bufferedDuration, minTargetDurations, isUpSwitch, estimate, adjustedBwObj, defaultFragDuration, maxBufferSize, lastUpdateMs, iframeMode, rootPlaylistQuery, logger) { + const adjustedbw = isUpSwitch ? adjustedBwObj.bwUp : adjustedBwObj.bwDown; + const bitrate = variantOption.bitrate; + // const live = levelDetails != null && levelDetails.live; + const avgDuration = variantOptionDetails ? variantOptionDetails.totalduration / variantOptionDetails.fragments.length : defaultFragDuration; + const playlistFetchMs = isFiniteNumber(estimate.avgPlaylistLoadTimeMs) ? estimate.avgPlaylistLoadTimeMs : estimate.avgLatencyMs; + const fetchDuration = calcFetchDuration(variantOption, variantOptionDetails, defaultFragDuration, adjustedbw, playlistFetchMs, lastUpdateMs, logger); + const peakBandwidth = variantOption.bandwidth; + // have atleast 2 target-durations buffered to switch if peak exceeds measured bandwidth + const rejectLevelDueToPeakBW = adjustedbw > bitrate && adjustedbw < peakBandwidth && bufferedDuration <= 2 * avgDuration; + const peakSegSizeBits = (peakBandwidth || bitrate || 0) * ((variantOptionDetails === null || variantOptionDetails === void 0 ? void 0 : variantOptionDetails.targetduration) || avgDuration); + // can fit at least this.minTargetDurations * targetDuration seconds into the buffer + const canFitMultipleSegments = (minTargetDurations * peakSegSizeBits) / 8 <= maxBufferSize; + // must have matching alternates + let alternates = null; + const requireAlternates = !iframeMode; + if (requireAlternates) { + alternates = getMatchingAlternates(variantOption, rootPlaylistQuery); + logger.debug(`${variantOption.mediaOptionId} matched alternate audio ${JSON.stringify(alternates.altAudio)} subtitle ${JSON.stringify(alternates.subtitle)}`); + if (!alternates.altAudio || !alternates.subtitle) { + logger.info(`no matching alternates ${alternates.altAudio} or ${alternates.subtitle}, skipping ${variantOption.mediaOptionId}`); + alternates = null; + } + } + return { + adjustedbw, + bitrate, + fetchDuration, + rejectLevelDueToPeakBW, + canFitMultipleSegments, + requireAlternates, + alternates, + }; + } + function getAdjustedBW(bw, switchUpFactor, switchDownFactor, numBandwidthSamples, logger) { + let bwUp; + let bwDown; + if (numBandwidthSamples >= minItemsInBandwidthAverage) { + bwUp = bw * switchUpFactor; + bwDown = bw * switchDownFactor; + } + else { + bwUp = bwDown = bw / shortTermBandwidthFactor; + } + logger.trace(`[getAdjustedBW] numSamples: ${numBandwidthSamples}, minSamples: ${minItemsInBandwidthAverage} - returning up: ${bwUp}, down: ${bwDown}`); + return { bwUp, bwDown }; + } + function calcFetchDuration(variantOption, variantOptionDetails, defaultFragDuration, bw, playlistFetchMs, lastUpdateMs, logger) { + const bitrate = variantOption.bitrate; + const avgDuration = variantOptionDetails ? variantOptionDetails.totalduration / variantOptionDetails.fragments.length : defaultFragDuration; + const avgSegSizeBits = bitrate * avgDuration; + let fetchDuration = avgSegSizeBits / bw; + // if live and !ptsKnown or outOfDate + if ((variantOptionDetails === null || variantOptionDetails === void 0 ? void 0 : variantOptionDetails.liveOrEvent) && (!variantOptionDetails.ptsKnown || likelyOutOfDate(variantOptionDetails.totalduration, playlistFetchMs, lastUpdateMs))) { + // live fetch duration could be up to two segments if it doesn't have time info + // First segment could be the wrong segment if we don't have PTS since we choose the middle frag + logger.debug(`PTS unknown / expired, using 2x fetchDuration for ${variantOption.mediaOptionId}`); + fetchDuration *= 2; + } + // if this is first update for this option or if live + if (isFiniteNumber(playlistFetchMs) && (!isFiniteNumber(lastUpdateMs) || (variantOptionDetails === null || variantOptionDetails === void 0 ? void 0 : variantOptionDetails.liveOrEvent))) { + fetchDuration += playlistFetchMs / 1000; + } + return fetchDuration; + } + function minSwitchBufferAheadSec(from, to, toDetails, currentFragDuration, abrStatus, statsQuery, abrConfig, lastUpdateMs, logger) { + const forcedAutoOptionId = abrStatus.nextMaxAutoOptionId; + // in case next auto level has been forced, and bw not available or not reliable, return false + if (forcedAutoOptionId !== NoMediaOption.mediaOptionId && !hasReliableBandwidthEstimate(statsQuery.getBandwidthEstimate())) { + return Number.POSITIVE_INFINITY; + } + const bw = getAdjustedBW(statsQuery.getBandwidthEstimate().avgBandwidth, abrConfig.abrBandWidthUpFactor, abrConfig.abrBandWidthFactor, statsQuery.bandwidthStatus.bandwidthSampleCount, logger); + const playlistFetchMs = isFiniteNumber(statsQuery.getPlaylistEstimate().avgPlaylistLoadTimeMs) + ? statsQuery.getPlaylistEstimate().avgPlaylistLoadTimeMs + : statsQuery.getBandwidthEstimate().avgLatencyMs; + // How much buffer ahead required to switch + // duration from playhead pos that is necessary to stay at this level + const isUpSwitch = to.bitrate > from.bitrate; + const bwValue = isUpSwitch ? bw.bwUp : bw.bwDown; + if ((toDetails === null || toDetails === void 0 ? void 0 : toDetails.liveOrEvent) && (!toDetails.ptsKnown || likelyOutOfDate(toDetails.totalduration, playlistFetchMs, lastUpdateMs))) { + // Don't allow flush if we won't have overlapping window + return Number.POSITIVE_INFINITY; + } + return calcFetchDuration(to, toDetails, currentFragDuration, bwValue, playlistFetchMs, lastUpdateMs, logger); + } + function getLowestSuperiorBW(mediaOptionId, variantOptions) { + let lowestSuperiorBW = Infinity; + if (mediaOptionId === NoMediaOption.mediaOptionId) { + return lowestSuperiorBW; + } + const givenMediaOption = variantOptions.find((mediaOption) => mediaOption.mediaOptionId === mediaOptionId); + if (!givenMediaOption) { + return Infinity; + } + const iframeMode = givenMediaOption.iframes; + const bitrate = givenMediaOption.bitrate; + const frameRate = givenMediaOption.frameRate; + const nextMediaOption = variantOptions.find((mediaOption) => mediaOption.iframes === iframeMode && (frameRate === undefined || mediaOption.frameRate >= frameRate) && mediaOption.bitrate > bitrate); + if (nextMediaOption) { + lowestSuperiorBW = nextMediaOption.bitrate; + } + return lowestSuperiorBW; + } + /** + * Returns whether it's likely that the refreshed level will end up with a non-overlapping playlist (causing ptsKnown == false) + * @param totalDurationSecs Details about the level + * @param playlistFetchMs time in MS to get playlist refresh + * @param lastUpdateMillis timeStamp of the last update + */ + function likelyOutOfDate(totalDurationSecs, playlistFetchMs, lastUpdateMillis) { + playlistFetchMs = isFiniteNumber(playlistFetchMs) ? playlistFetchMs : 0; + return !isFiniteNumber(lastUpdateMillis) || performance.now() - lastUpdateMillis + playlistFetchMs > totalDurationSecs * 1000; + } + /** + * Choose option to resume at when coming out of trickplay + */ + function getTrickPlayMaxResumeOption(preIframeOptionId, config, logger, rootPlaylistQuery, statsQuery) { + const vQuery = rootPlaylistQuery.mediaOptionListQueries[MediaOptionType.Variant]; + const vOptions = vQuery.preferredMediaOptionList; + const targetStartupMs = config.targetStartupMs; + const playlistEstimate = { + // statsQuery.playlistEstimate + avgPlaylistParseTimeMs: 0, + avgPlaylistLoadTimeMs: 0, + }; // Do not use max values for this estimate + const fragEstimate = statsQuery.getFragEstimate(); + const bufferEstimate = { + avgBufferCreateMs: 0, + avgInitFragAppendMs: 0, + avgDataFragAppendMs: 0, + }; + const fragDuration = fragEstimate.maxDurationSec; + // Use 0 latency since it is already wrapped into bw estimate(See BandwidthHistoryController.record). Change back if we use tload - tfirst instead + const bw = { + avgLatencyMs: 0, + avgBandwidth: statsQuery.getBandwidthEstimate().avgBandwidth, + }; + const startConfig = { + targetDuration: fragDuration, + targetStartupMs: targetStartupMs, + metricsOverride: { + maxValidHeight: 0, + maxValidBitrate: 0, + maxPreferredBitrate: 0, + }, + }; + logger.info(`trickplay resume selection params=${stringifyWithPrecision({ startConfig, bw, playlistEstimate, fragEstimate, bufferEstimate })}`); + const regOptions = filterRegularLevelsBasedOnCapOn1080p(vOptions); + let resumeId = preIframeOptionId; + if (regOptions.length > 0) { + resumeId = regOptions[0].mediaOptionId; + } + const candidates = regOptions.filter((option) => isWithinBandwidthCap(option, bw, startConfig, playlistEstimate, fragEstimate, bufferEstimate)); + logger.debug(`Picking resume level from validLevels/regLevels/resumeLevels ${vOptions.length}/${regOptions.length}/${candidates.length}`); + if (candidates.length > 0) { + resumeId = candidates[candidates.length - 1].mediaOptionId; + } + logger.info(`trickplay start/max resume:${preIframeOptionId}/${resumeId}`); + return resumeId; + } + function fragAbrStatusDidChange(a, b) { + return (a === null || a === void 0 ? void 0 : a.fragDownloadSlow) === (b === null || b === void 0 ? void 0 : b.fragDownloadSlow) && a.fragDownloadTooSlow === (b === null || b === void 0 ? void 0 : b.fragDownloadTooSlow); + } + /** + * @returns Returns whether we should abort the fragment and also updates AbrStatus + */ + function shouldAbortFrag(context) { + // Slow fragment download: + const { mediaSink, rootPlaylistQuery, rootPlaylistService } = context; + const mediaQuery = mediaSink.mediaQuery; + const logger = context.logger.child(abrLogName); + return merge(slowFragmentCheck(rootPlaylistQuery, mediaQuery, logger), likelyToStallCheck(context)).pipe(startWith({ fragDownloadSlow: false, fragDownloadTooSlow: false }), scan((curState, newState) => { + return { + fragDownloadSlow: curState.fragDownloadSlow || newState.fragDownloadSlow, + fragDownloadTooSlow: curState.fragDownloadTooSlow || newState.fragDownloadTooSlow, + }; + }), distinctUntilChanged(fragAbrStatusDidChange), map((status) => { + logger.debug(`abrStatus update=${JSON.stringify(status)}`); + rootPlaylistService.setFragLoadSlow(rootPlaylistQuery.itemId, status); + return false; + }), catchError((err) => { + if (err instanceof FragmentAbortError) { + const wayTooSlow = { fragDownloadSlow: true, fragDownloadTooSlow: true }; + rootPlaylistService.setFragLoadSlow(rootPlaylistQuery.itemId, wayTooSlow); + return of(true); + } + return throwError(err); + })); + } + function slowFragmentCheck(rootPlaylistQuery, mediaQuery, logger) { + return combineQueries([mediaQuery.fellBelowLowWater$, rootPlaylistQuery.getInFlightFragByType$(MediaOptionType.Variant)]).pipe(switchMap((value) => { + const [, inFlight] = value; + if (!hasValidSample(inFlight)) { + return EMPTY; + } + const elapsedMs = performance.now() - inFlight.bwSample.trequest; + const flowDeadline = kFlowMeasurementPeriodMS - elapsedMs; + const durationDeadline = inFlight.duration * 1000 - elapsedMs; + const timers$ = [VOID]; + if (flowDeadline > 0) { + timers$.push(timer(flowDeadline)); + } + if (durationDeadline > 0) { + timers$.push(timer(durationDeadline)); + } + return merge(...timers$).pipe(mapTo(value)); + }), scan((curState, [fellBelowLowWater, inFlight]) => { + const newState = Object.assign({}, curState); + if (fellBelowLowWater) { + newState.fragDownloadSlow = true; + } + return gotSlowFlow(inFlight, newState, rootPlaylistQuery, logger); + }, { fragDownloadSlow: false, fragDownloadTooSlow: false }), startWith({ fragDownloadSlow: false, fragDownloadTooSlow: false }), distinctUntilChanged(fragAbrStatusDidChange)); + } + function hasValidSample(inFlight) { + var _a; + return (inFlight === null || inFlight === void 0 ? void 0 : inFlight.state) === 'loading' && isFiniteNumber((_a = inFlight.bwSample) === null || _a === void 0 ? void 0 : _a.trequest); + } + const kFlowMeasurementPeriodMS = 2000; + const kUnderflowAllowanceMS = 1000; + function gotSlowFlow(inFlight, curStatus, rootQuery, logger) { + let { fragDownloadSlow, fragDownloadTooSlow } = curStatus; + const variant = rootQuery.variantMediaOptionById(inFlight.mediaOptionId); + const bitrate = variant.bitrate; + const stats = inFlight.bwSample; + logger = logger.child(abrLogName); + const totalBytes = stats.total ? stats.total : Math.max(stats.loaded, Math.round((inFlight.duration * bitrate) / 8)), timeSpentMS = performance.now() - stats.tfirst, // time spent downloading the fragment + durationDownloadedMS = (stats.loaded * inFlight.duration * 1000) / totalBytes; + if (timeSpentMS >= kFlowMeasurementPeriodMS && timeSpentMS - durationDownloadedMS >= kUnderflowAllowanceMS) { + if (!fragDownloadSlow) { + logger.warn(`flow indicates low bandwidth, after time/duration behind real time: ${timeSpentMS}/${timeSpentMS - durationDownloadedMS}`); + } + fragDownloadSlow = true; + } + if (timeSpentMS >= inFlight.duration * 1000) { + if (!fragDownloadTooSlow) { + logger.warn(`too much time spent downloading fragment, likely to switch down ${timeSpentMS} > ${inFlight.duration * 1000}`); + } + fragDownloadTooSlow = true; + } + return { fragDownloadSlow, fragDownloadTooSlow }; + } + function likelyToStallCheck(context) { + const mediaQuery = context.mediaSink.mediaQuery; + const { rootPlaylistQuery: rootQuery, config } = context; + return mediaQuery.desiredRate$ + .pipe(switchMap((desiredRate) => { + // Don't emit if about to pause or if we are currently paused + if (desiredRate === 0) { + return EMPTY; + } + return combineQueries([ + rootQuery.getInFlightFragByType$(MediaOptionType.Variant), + rootQuery.mediaOptionListQueries[MediaOptionType.Variant].preferredMediaOptionList$.pipe(map((list) => list.filter(isMatchingIframeLevel.bind(null, isIframeRate(desiredRate))))), + ]); + }), throttleTime(100), switchMap((value) => { + const [inFlight, preferredList] = value; + // Make sure inFlight fragment in correct mode && not the lowest bitrate variant + if (!hasValidSample(inFlight) || preferredList.findIndex((o) => o.mediaOptionId === inFlight.mediaOptionId) <= 0) { + return EMPTY; + } + // Wait some min threshold for stable bitrate calculation then check every 100ms + const now = performance.now(); + const elapsedMs = now - inFlight.bwSample.trequest; + const maxStarvationDelaySec = getMaxStarvationDelaySec(inFlight.duration, config.maxStarvationDelay); + const minThresholdMs = Math.min(maxStarvationDelaySec * 1000, (inFlight.duration * 500) / mediaQuery.playbackRate); + const delayMs = Math.max(0, minThresholdMs - elapsedMs); + return timer(delayMs, 100).pipe(mapTo(value)); + })) + .pipe(scan((curStatus, [inFlight, preferredList]) => { + return likelyToStall(curStatus, inFlight, preferredList, context); + }, { fragDownloadSlow: false, fragDownloadTooSlow: false }), startWith({ fragDownloadSlow: false, fragDownloadTooSlow: false }), distinctUntilChanged(fragAbrStatusDidChange)); + } + /** + * Determine whether we are going to stall based on the remaining time to download the inflight fragment and buffer then switch fragments if needed. + * Can initiate abort of inflight fragment and switch down through limiting the nexMaxAutoOptiondId to either a level that can download in time or the lowest option. + * Alternatively, can just initiate a switch down without abort by limiting nextMaxAutoOptionId to one level down if the current fragment can download quickly enough. + */ + function likelyToStall(curStatus, inFlight, preferredList, // filtered list in the correct mode + context) { + var _a, _b; + let { fragDownloadSlow, fragDownloadTooSlow } = curStatus; + const { config, rootPlaylistService, rootPlaylistQuery: rootQuery, mediaSink, statsService, mediaLibraryService } = context; + const logger = context.logger.child(abrLogName); + const mediaQuery = mediaSink.mediaQuery; + // Prevent switch down if we are not in play state + if (mediaQuery.paused) { + return curStatus; + } + const stats = inFlight.bwSample; + // likelyToStall not required to check until download has started + if (!isFiniteNumber(stats.tfirst)) { + return curStatus; + } + const now = performance.now(); + const elapsedMs = now - stats.trequest; + const maxStarvationDelaySec = getMaxStarvationDelaySec(inFlight.duration, config.maxStarvationDelay); + const mediaOptionType = MediaOptionType.Variant; + const mediaOptionId = inFlight.mediaOptionId; + const curVariant = rootQuery.variantMediaOptionById(mediaOptionId); + const curLibQuery = mediaLibraryService.getQueryForOption(curVariant); + const variantBitrate = curVariant.bitrate; + const instantBw = Math.max(1, (stats.loaded * 8000) / elapsedMs); // instant load rate in bits per second + const totalBytes = isFiniteNumber(stats.total) ? stats.total : Math.max(stats.loaded, Math.round((inFlight.duration * variantBitrate) / 8)); // fragment size in bytes + const remainingTimeSec = ((totalBytes - stats.loaded) * 8) / instantBw; // how much longer until this fragment will be loaded in seconds + const bufferAheadSec = getBufferAheadSec(mediaQuery, config.maxBufferHole); + let maxTimeToLoadSec; // Max time to load the next fragment + if (isFiniteNumber(bufferAheadSec) && bufferAheadSec > 0 && !isFiniteNumber((_a = mediaQuery.seekTo) === null || _a === void 0 ? void 0 : _a.pos)) { + maxTimeToLoadSec = bufferAheadSec; + } + else { + // bufferAheadSec === 0 or NaN or seeking + const elapsedSec = elapsedMs / 1000; + if (elapsedSec < maxStarvationDelaySec) { + // Already starving. Try to complete load by maxStarvationDelaySec relative to current load + maxTimeToLoadSec = maxStarvationDelaySec - elapsedSec; + } + else { + // Could happen if we have high target duration. Start over with maxStarvationDelay + maxTimeToLoadSec = maxStarvationDelaySec; + } + } + const wasSlow = fragDownloadSlow; // To make logs less chatty + ({ fragDownloadSlow, fragDownloadTooSlow } = gotSlowFlow(inFlight, curStatus, rootQuery, logger)); + // consider emergency switch down only if we have less than 2 frag buffered AND + // time to finish loading current fragment is bigger than buffer starvation delay + // ie if we risk buffer starvation if bw does not increase quickly. + const minSwitchDuration = 2 * (((_b = curLibQuery.mediaOptionDetails) === null || _b === void 0 ? void 0 : _b.targetduration) || inFlight.duration); + const likelyToStall = bufferAheadSec <= minSwitchDuration && (remainingTimeSec >= maxTimeToLoadSec || fragDownloadSlow); + if (!likelyToStall) { + if (globalHlsService().getQuery().extendMaxTTFB) { + logger.info('[abr] re-enabling TTFB'); + globalHlsService().setExtendMaxTTFB(0); + } + return { fragDownloadSlow, fragDownloadTooSlow }; + } + if (!wasSlow) { + logger.warn(`likely to stall ${stringifyWithPrecision({ + maxTimeToLoadSec, + minSwitchDuration, + stats, + elapsedMs, + remainingTimeSec, + instantBw, + bufferAheadSec, + fragDownloadSlow, + })}`); + } + fragDownloadSlow = true; + if (!globalHlsService().getQuery().extendMaxTTFB) { + logger.info('[abr] temporarily disabling TTFB'); + globalHlsService().setExtendMaxTTFB(600000); // set to 10mins + } + // TODO: in native stack we only downswitch if our predictedBitrate < levelBitrate. However + // seems like we need to investigate if bandwidth estimate is reacting fast enough to bandwidth changes + let nextOptionId = undefined; + // Find something that will take less than bufferStarvationDelay (avoids rebuffering) + const itemId = inFlight.itemId; + const statsQuery = statsService.getQueryForItem(itemId); + const avgEstimate = statsQuery.getCombinedEstimate(); + const instantEstimate = Object.assign(Object.assign({}, avgEstimate), { avgBandwidth: instantBw }); + const bwStatus = statsQuery.bandwidthStatus; + const bwFactor = 1; + const bwUpFactor = 1; + const iframeMode = curVariant.iframes; + // We should probably switch down either way after this fragment, but whether we abort depends on whether we can avoid rebuffering + // Never abort in iframe mode. It kills the av-pipe when handleVariantSwitch does not switch + const shouldAbort = remainingTimeSec >= maxTimeToLoadSec && !iframeMode; + // Find lowest index with matching group or 0 if none + const minLevelIdx = findLowestValidVariantIndex(0, preferredList, iframeMode, rootQuery); + // There is no variant with audio/subtitle group matching, so there is nothing to switch to + if (minLevelIdx < 0) { + logger.info('findLowestValidVariantIndex could not find a valid level'); + return { fragDownloadSlow, fragDownloadTooSlow }; + } + // Set max level to current level or the lowest valid level, whichever is greater + const maxLevelIdx = Math.max(minLevelIdx, preferredList.findIndex((v) => v && v.mediaOptionId === curVariant.mediaOptionId)); + if (shouldAbort) { + // We will stall if we do not abort and switch down + // Check if we can find a variant that will load within maxTimeToLoadSec + let res = findBestVariantOption(preferredList, inFlight.duration, minLevelIdx, maxLevelIdx, maxTimeToLoadSec, iframeMode, instantEstimate, bwStatus, bwFactor, bwUpFactor, config, rootQuery, curLibQuery, mediaQuery, logger); + const badOptionId = NoMediaOption.mediaOptionId; + if (res.variantMediaOption !== badOptionId) { + logger.info(`buffered: ${bufferAheadSec} got option ${res.variantMediaOption} that will load in conditions ${stringifyWithPrecision({ maxTimeToLoadSec, instantBw })}`); + nextOptionId = res.variantMediaOption; + } + else if ((res = findBestVariantOption(preferredList, inFlight.duration, minLevelIdx, maxLevelIdx, remainingTimeSec, iframeMode, instantEstimate, bwStatus, bwFactor, bwUpFactor, config, rootQuery, curLibQuery, mediaQuery, logger)).variantMediaOption !== badOptionId) { + // Found variant that will load before current frag is done + nextOptionId = res.variantMediaOption; + logger.info(`buffered: ${bufferAheadSec} got option ${nextOptionId} that will load in conditions ${stringifyWithPrecision({ remainingTimeSec, instantBw })}`); + } + else { + // Waiting for current frag to finish will result in rebuffering, fall back to minimum option and abort + nextOptionId = res.lowestCandidate; + logger.info(`buffered: ${bufferAheadSec} got fallback option ${nextOptionId}, could not find variant that will load in conditions ${stringifyWithPrecision({ remainingTimeSec, instantBw })}`); + } + } + else { + // Can finish current frag download and then switch down by one level, matching alternates. + // Reverse preferredList in range [minLevelIdx, maxLevelIdx-1] inclusive then look for the lowest idx with valid variant audio/subtitle matching. + // This will return -1 on failure, maxLevelIdx-1 if iframeMode, or the offset from the tail of the highest idx below maxLevelIdx with matching + const offsetFromTail = findLowestValidVariantIndex(0, preferredList.slice(minLevelIdx, maxLevelIdx).reverse(), iframeMode, rootQuery); + const nextMatchingGroupIdx = maxLevelIdx - 1 - offsetFromTail; // maxLevelIdx-1 since slice(start, end) excludes the end idx + // Cap to next highest level with audio/subtitle group matching. If there is no lower group, stay at the currently enabled option and log it. + if (offsetFromTail >= 0 || maxLevelIdx === minLevelIdx) { + logger.info('cap to next highest level with audio/subtitle matching'); + nextOptionId = preferredList[nextMatchingGroupIdx].mediaOptionId; + } + else { + logger.info(`no lower level with matching audio/subtitle to switch to level=${curVariant.mediaOptionId}`); + } + } + if (nextOptionId != null && nextOptionId !== rootQuery.abrStatus.nextMaxAutoOptionId) { + logger.info(`capping level to ${nextOptionId} because likelyToStall`); + rootPlaylistService.setNextMaxAutoOptionId(itemId, nextOptionId); + } + // only emergency switch down if it takes less time to load new fragment at lowest level instead + // of finishing loading current one ... + if (shouldAbort) { + logger.warn(`loading too slow, abort fragment loading and switch to level ${nextOptionId}`); + logger.debug(`abort stats=${stringifyWithPrecision({ + instantBw, + loadedBytes: stats.loaded, + totalBytes, + elapsedMs, + remainingTimeSec, + maxTimeToLoadSec, + fragDownloadSlow, + })}`); + // force next load level in auto mode + // update bw estimate for this fragment before cancelling load (this will help reducing the bw) + logger.info(`[${MediaOptionNames[mediaOptionType]}] fragLoadingProcessingMs/stats.loaded: ${elapsedMs}/${stats.loaded}`); // also log when too slow + statsService.setBandwidthSample(Object.assign(Object.assign({}, stats), { tfirst: stats.tfirst || now, tload: stats.tload || now, complete: true, mediaOptionType: mediaOptionType })); + fragDownloadTooSlow = true; + // Abort current sequence + throw new FragmentAbortError({ mediaOptionType, mediaOptionId }, nextOptionId, ErrorResponses.FragmentAbortError); + } + return { fragDownloadSlow, fragDownloadTooSlow }; + } + function initializeAbrStatus(mediaOptionId, variantOptions) { + const highBWTrigger = getLowestSuperiorBW(mediaOptionId, variantOptions); + return { + fragDownloadSlow: false, + fragDownloadTooSlow: false, + nextMinAutoOptionId: NoMediaOption.mediaOptionId, + nextMaxAutoOptionId: NoMediaOption.mediaOptionId, + highBWTrigger: highBWTrigger, + }; + } + /** + * @brief Use ABR logic to switch VariantMediaOption if needed + * + * We should not switch levels unless we hit certain triggers: + * 1. Bandwidth High / Low change + * 2. Crossing low water level threshold + * 3. Hitting end of buffer + * 4. Slow fragment or level loading + * 5. iframe mode change + * 6. gapless item transition + * Exceptions are when we are at a discontinuity or seeking, when we should only switch if we have + * slow media (timeout) current level was sent to penalty box. + * When switching variant, handleVariantSwitch will ensure altAudio and subtitle mediaOptions follow + * the same groups specified by the chosen variant. + */ + function handleVariantSwitch(originalReason, config, rootQuery, mediaElementQuery, rootService) { + var _a, _b; + const logger = rootService.logger.child(abrLogName); + const iframeMode = mediaElementQuery.isIframeRate; + const optionListQuery = rootQuery.mediaOptionListQueries[MediaOptionType.Variant]; + const preferredList = optionListQuery.preferredMediaOptionList; + const curVariant = rootQuery.enabledMediaOptionKeys[MediaOptionType.Variant]; + let switchReason = originalReason; + if (switchReason === SwitchReason.None && !preferredList.some((option) => option.mediaOptionId === curVariant.mediaOptionId)) { + switchReason = SwitchReason.PreferredListChanged; + logger.info(`overriding switchReason: ${originalReason}->${switchReason}`); + } + const shouldSwitchVariant = switchReason !== SwitchReason.None; + if (!shouldSwitchVariant) { + logger.info(`Skipping variant switch as switchReason: ${switchReason}`); + return false; + } + if (iframeMode && switchReason !== SwitchReason.IframeModeChange) { + const bufferedIframes = mediaElementQuery.getBufferedSegmentsByType(SourceBufferType.Variant).filter((seg) => seg.frag.iframe); + if (bufferedIframes.length < config.minFramesBeforeSwitchingLevel) { + logger.info(`[iframes] only ${bufferedIframes.length} iframes, stay at current mediaOption ${curVariant.mediaOptionId}`); + // TODO: Force needData$. If fragment was aborted and water level is almost/dry, av-pipe will die. <@robert-walch 3/8/2022> + return false; + } + } + if (iframeMode && switchReason === SwitchReason.IframeModeChange) { + rootService.setEnabledVariantMediaOptionIdBeforeTrickplaySwitch(rootQuery.itemId, curVariant.mediaOptionId); + } + const statsQuery = createStatsQuery(rootQuery.itemId); + const mediaLibraryQuery = createMediaLibraryQuery(curVariant); + const newOptions = [NoMediaOption, NoMediaOption, NoMediaOption]; + // rdar://85517745 (Resume from trickplay level calculation needs functional parity with 2.15) + // On leaving trickplay, set the nextMaxAutioOptionId, this will in turn be used in nextAutoMediaOption + if (!iframeMode && originalReason === SwitchReason.IframeModeChange) { + const maxResumeOption = getTrickPlayMaxResumeOption(rootQuery.enabledVariantMediaOptionIdBeforeTrickplaySwitch, config, logger, rootQuery, statsQuery); + logger.info(`Capping variant selection to ${maxResumeOption} because switchReason: ${originalReason}`); + rootService.setNextMaxAutoOptionId(rootQuery.itemId, maxResumeOption); + rootService.setEnabledVariantMediaOptionIdBeforeTrickplaySwitch(rootQuery.itemId, undefined); + } + const nextVariant = nextAutoMediaOption(config, rootQuery, rootService, mediaLibraryQuery, mediaElementQuery, statsQuery, logger); + if (!iframeMode && originalReason === SwitchReason.IframeModeChange) { + // reset nextMaxAutioOptionId that was set above + rootService.setNextMaxAutoOptionId(rootQuery.itemId, NoMediaOption.mediaOptionId); + } + if (nextVariant.variantMediaOption === curVariant.mediaOptionId) { + logger.info(`Skipping variant switch as no better candidate than ${curVariant.mediaOptionId}`); + // TODO: Force needData$. If fragment was aborted and water level is almost/dry, av-pipe will die. <@robert-walch 3/8/2022> + return false; + } + logger.qe({ critical: true, name: 'shouldSwitchVariant', data: { value: shouldSwitchVariant, reason: switchReason } }); + newOptions[MediaOptionType.Variant] = { itemId: rootQuery.itemId, mediaOptionId: nextVariant.variantMediaOption }; + for (const i of [MediaOptionType.AltAudio, MediaOptionType.Subtitle]) { + const curOptionId = rootQuery.enabledMediaOptionIdByType(i); + if (curOptionId !== NoMediaOption.mediaOptionId) { + // newAlternate may be null for iframe, NoMediaOption, or reuse existing variant (no switch): reuse existing alternates + const newAlternate = i === MediaOptionType.AltAudio ? (_a = nextVariant.alternates) === null || _a === void 0 ? void 0 : _a.altAudio : (_b = nextVariant.alternates) === null || _b === void 0 ? void 0 : _b.subtitle; + newOptions[i] = newAlternate ? newAlternate : { itemId: rootQuery.itemId, mediaOptionId: curOptionId }; + } + } + rootService.setEnabledMediaOptions(rootQuery.itemId, newOptions); + logger.info(`Switching variant ${switchReason}: ${curVariant.mediaOptionId} variant/audio/subtitle ${newOptions[0].mediaOptionId}/${newOptions[1].mediaOptionId}/${newOptions[2].mediaOptionId}`); + return true; + } + /** + * @returns whether we should check for downswitch + */ + function gotLowBw(rootQuery, mediaElementQuery, rootService) { + var _a; + const logger = rootService.logger.child(abrLogName); + const abrStatus = rootQuery.abrStatus; + const slowMedia = gotSlowMedia(abrStatus); + const seeking = isFiniteNumber((_a = mediaElementQuery.seekTo) === null || _a === void 0 ? void 0 : _a.pos); + if (slowMedia && !abrStatus.fragDownloadTooSlow && seeking) { + logger.warn('could be ignoring low bandwidth due to seek'); + return false; + } + return slowMedia; + } + /** + * @returns whether we should check for upswitch + */ + function gotHighBw(config, rootQuery, rootService) { + var _a; + const logger = rootService.logger; + const statsQuery = createStatsQuery(rootQuery.itemId); + const bwe = statsQuery.getBandwidthEstimate(); + const abrStatus = rootQuery.abrStatus; + if (!hasReliableBandwidthEstimate(bwe)) { + return false; + } + const bandwidthSampleCount = ((_a = statsQuery.bandwidthStatus) === null || _a === void 0 ? void 0 : _a.bandwidthSampleCount) || 0; + const { bwUp } = getAdjustedBW(bwe.avgBandwidth, config.abrBandWidthUpFactor, config.abrBandWidthFactor, bandwidthSampleCount, logger); + if (bwUp > abrStatus.highBWTrigger) { + logger.info(`[abr] bandwidth high ${Math.round(bwe.avgBandwidth / 1000)}kbps trigger=${abrStatus.highBWTrigger / 1000}kbps factor=${config.abrBandWidthUpFactor}`); + return true; + } + return false; + } + + const loggerName$2 = { name: 'iframes' }; + var PrefetchResult; + (function (PrefetchResult) { + PrefetchResult[PrefetchResult["DISABLED"] = 0] = "DISABLED"; + PrefetchResult[PrefetchResult["ERRORED"] = 1] = "ERRORED"; + PrefetchResult[PrefetchResult["SUCCESS"] = 2] = "SUCCESS"; + })(PrefetchResult || (PrefetchResult = {})); + const checkForIframePrefetch = (context) => { + const { config, logger } = context; + if (!config.enableIFramePreloading) { + logger.info(loggerName$2, 'Iframe prefetch disabled'); + return of(PrefetchResult.DISABLED); + } + return waitTillAllowedPrefetch(context); + }; + function waitTillAllowedPrefetch(context) { + const { mediaSink, rootPlaylistQuery, mediaLibraryService, logger } = context; + const { mediaQuery } = mediaSink; + return combineQueries([mediaQuery.desiredRate$, mediaQuery.waterLevelChangedForType$(SourceBufferType.Variant)]).pipe( + // startup: don't subscribe to root playlist query until needed + switchMap(([desiredRate, waterLevel]) => { + if (isIframeRate(desiredRate) || waterLevel !== BufferWaterLevel.AboveHighWater) { + return EMPTY; + } + return rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(map((enabledVariantMediaOption) => { + var _a, _b; + const variantQuery = rootPlaylistQuery.mediaOptionListQueries[MediaOptionType.Variant]; + const hasIframes = variantQuery.hasIframes; + const libQuery = mediaLibraryService.getQuery(); + const isLiveOrEvent = (_b = (_a = libQuery.getEntity(rootPlaylistQuery.itemId)) === null || _a === void 0 ? void 0 : _a.liveOrEvent) !== null && _b !== void 0 ? _b : false; + if (!hasIframes || isLiveOrEvent) { + logger.info(loggerName$2, `Skipping iframe prefetch hasIframes=${hasIframes}, liveOrEvent=${isLiveOrEvent}`); + return PrefetchResult.DISABLED; + } + return enabledVariantMediaOption; + })); + }), take(1), exhaustMap((variantOption) => beginPrefetch(variantOption, context)), finalize$1(() => { + logger.trace(loggerName$2, 'finalizing iframe prefetch'); + })); + } + function beginPrefetch(variantOption, context) { + const { logger } = context; + if (variantOption === PrefetchResult.DISABLED) { + return of(variantOption); + } + return prefetchPlaylist(variantOption, context).pipe(exhaustMap((mediaOptionDetails) => prefetchInitSegmentAndKey(mediaOptionDetails, context)), mapTo(PrefetchResult.SUCCESS), catchError((err) => { + logger.error(loggerName$2, `got error ${err.message} in prefetch`); + return of(PrefetchResult.ERRORED); + })); + } + function prefetchPlaylist(variantOption, context) { + const { rootPlaylistQuery, logger, config, mediaSink, statsService } = context; + const { mediaQuery } = mediaSink; + const statsQuery = statsService.getQueryForItem(rootPlaylistQuery.itemId); + const mediaLibraryQuery = createMediaLibraryQuery(variantOption); + const iframeMediaChoice = findNextABRAutoVariantOptionInMode(true, config, rootPlaylistQuery, mediaLibraryQuery, mediaQuery, statsQuery, logger); + const iframeMediaOption = rootPlaylistQuery.variantMediaOptionById(iframeMediaChoice.variantMediaOption); + logger.info(loggerName$2, `prefetching variant ${iframeMediaChoice.variantMediaOption}`); + return retrieveMediaOptionDetails(context, iframeMediaOption, true); + } + function prefetchInitSegmentAndKey(mediaOptionDetails, context) { + var _a; + const { logger, mediaSink, rootPlaylistQuery } = context; + const { mediaQuery } = mediaSink; + const fragResult = findFragment(mediaQuery.currentTime, rootPlaylistQuery.discoSeqNum, 0, mediaOptionDetails, []); + if (!((_a = fragResult === null || fragResult === void 0 ? void 0 : fragResult.foundFrag) === null || _a === void 0 ? void 0 : _a.mediaFragment)) { + return throwError('Unable to find fragment for iframe prefetch'); + } + const mediaFragment = fragResult.foundFrag.mediaFragment; + const prefetchKey$ = loadKey(context, mediaFragment.keyTagInfo, { itemId: mediaFragment.itemId, mediaOptionId: mediaFragment.mediaOptionId }); + const prefetchInitSeg$ = retrieveInitSegmentCacheEntity(context, mediaFragment); + return forkJoin([prefetchKey$, prefetchInitSeg$]).pipe(tap(() => logger.info(loggerName$2, `prefetched variant ${mediaOptionDetails.mediaOptionId}`)), mapTo(PrefetchResult.SUCCESS)); + } + function checkForIframeAutoPause(context) { + const { config, logger, iframeMachine, mediaSink } = context; + const { mediaQuery } = mediaSink; + return mediaQuery.desiredRate$.pipe(switchMap((rate) => { + if (!isIframeRate(rate)) { + return EMPTY; + } + const period = Math.abs(1000 / rate); + return timer(0, period).pipe(map(() => { + let result = null; + const seekable = mediaQuery.seekable; + if (!iframeMachine.isStarted || seekable.length < 1) { + return result; + } + const iframeReferenceClockTime = iframeMachine.iframeClockTimeSeconds; + const { leftMediaTimeToAutoPause } = config; + const minTime = seekable.start(0); + const maxTime = seekable.end(seekable.length - 1); + if (rate > 1 && maxTime - iframeReferenceClockTime < leftMediaTimeToAutoPause) { + logger.info({ name: 'iframes' }, `near the end of media, pausing normal playback, maxTime ${maxTime}, ifrct ${iframeReferenceClockTime}`); + result = { newRate: 0, postFlushSeek: maxTime - leftMediaTimeToAutoPause }; + iframeMachine.pause(); + } + else if (rate < 0 && iframeReferenceClockTime - minTime < rate / -2) { + logger.info({ name: 'iframes' }, `near the start of media, resuming playback, minTime ${minTime}, ifrct: ${iframeReferenceClockTime}`); + result = { newRate: 1, postFlushSeek: minTime }; + } + return result; + }), filterNullOrUndefined(), tap(({ newRate, postFlushSeek }) => { + mediaSink.postFlushSeek = postFlushSeek; + mediaSink.desiredRate = newRate; + }), switchMapTo(EMPTY)); + })); + } + function desiredRateChange(context) { + const mediaQuery = context.mediaSink.mediaQuery; + return combineLatest([of(context), mediaQuery.desiredRate$.pipe(pairwise())]).pipe(switchMap(([context, [oldRate, newRate]]) => { + const { rootPlaylistQuery, rootPlaylistService, config, logger, mediaSink, mediaLibraryService, statsService } = context; + const mediaQuery = mediaSink.mediaQuery; + const wasIframeRate = isIframeRate(oldRate); + const iframeRate = isIframeRate(newRate); + if (wasIframeRate !== iframeRate) { + logger.qe({ critical: true, name: 'iframes', data: { state: iframeRate, prevRate: oldRate, newRate } }); + handleVariantSwitch(SwitchReason.IframeModeChange, config, rootPlaylistQuery, mediaQuery, rootPlaylistService); + } + else if (oldRate === 0 && newRate === 1) { + const canPlayWithoutGap = AVMediaOptionTypes.every((type) => { + var _a; + const enabledOption = rootPlaylistQuery.enabledMediaOptionKeys[type]; + const libQuery = mediaLibraryService.getQueryForOption(enabledOption); + const statsQuery = statsService.getQueryForItem(rootPlaylistQuery.itemId); + const entity = libQuery.mediaOptionDetailsEntity; + return (!((_a = entity === null || entity === void 0 ? void 0 : entity.mediaOptionDetails) === null || _a === void 0 ? void 0 : _a.ptsKnown) || + mediaQuery.canContinuePlaybackWithoutGap(entity.mediaOptionDetails, entity.lastUpdateMillis, statsQuery.getPlaylistEstimate(), config.maxBufferHole)); + }); + if (!canPlayWithoutGap) { + logger.info('flush due to live gap [0, Infinity]'); + mediaSink.pause(); + return mediaSink.flushAll(0, Infinity, true); + } + } + return EMPTY; + }), switchMapTo(EMPTY)); + } + function capToEnabledIframeOption(context) { + const rootQuery = context.rootPlaylistQuery; + const mediaQuery = context.mediaSink.mediaQuery; + const enabledOption$ = rootQuery.enabledMediaOptionByType$(MediaOptionType.Variant); + return combineLatest([of(context), mediaQuery.desiredRate$.pipe(pairwise())]).pipe( + // distinct until desiredRate changed + distinctUntilChanged((prev, cur) => prev[1] === cur[1]), withLatestFrom(enabledOption$), // Startup: don't subscribe to root playlist query until needed + switchMap(([[context, [oldRate, newRate]], enabledMediaOption]) => { + const wasIframeRate = isIframeRate(oldRate); + const iframeRate = isIframeRate(newRate); + // Early return if trickplay was not toggled + if (wasIframeRate === iframeRate) { + return EMPTY; + } + const { rootPlaylistService, logger } = context; + if (iframeRate) { + // Check if level uncapped + if (context.rootPlaylistQuery.nextMaxAutoOptionId === NoMediaOption.mediaOptionId) { + // Attach to rootPlaylistQuery so it lasts throughout trickplay + rootPlaylistService.setNextMaxAutoOptionId(context.rootPlaylistQuery.itemId, enabledMediaOption.mediaOptionId); + logger.info(`Capped level to ${enabledMediaOption.mediaOptionId} on entering trickplay`); + } + } + return EMPTY; + })); + } + + class QueueItemQuery extends QueryEntity { + } + const queueItemStore = new EntityStore({}, { name: 'item-queue', producerFn: produce_1, idKey: 'itemId', resettable: true }); + const queueItemQuery = new QueueItemQuery(queueItemStore); + /** + * @brief The playback queue + */ + class ItemQueue { + constructor() { + this.firstItem = true; + this.playingEntity = null; + this.loadingEntity = null; + } + static createItem(name, url, initialSeekTime = NaN, platformInfo, serviceName) { + const today = new Date(); + const createTime = `${today.getHours()}:${today.getMinutes()}:${today.getSeconds()}`; + // The MediaFragment URI start time we get from URL will take precedence over: + // hls.config.startPosition > TIME-OFFSET in playlist > initialSeekTime parameter in this function. + const logger = getLogger(); + const timeOffset = getTimeOffsetParameter(url); + logger.info(`timeOffset parsed from URL ${timeOffset}`); + if (isFiniteNumber(timeOffset)) { + initialSeekTime = timeOffset; + } + else { + const hlsConfig = getCurrentConfig(); + if (isFiniteNumber(hlsConfig === null || hlsConfig === void 0 ? void 0 : hlsConfig.startPosition)) { + // override only if finite value + initialSeekTime = hlsConfig.startPosition; + logger.info(`override initialSeekTime with startPosition ${initialSeekTime}`); + } + } + const queueItem = { + itemId: `${name}_${createTime}`, + name, + url, + serviceName, + createTime, + initialSeekTime, + itemStartOffset: 0, + platformInfo, + config: {}, + }; + return queueItem; + } + /** + * @returns obervable for whenever active item changes + */ + get activeItemById$() { + return queueItemQuery.selectActiveId().pipe(map((_) => queueItemQuery.getActive())); + } + get removedItems$() { + return queueItemQuery.selectEntityAction(EntityActions.Remove).pipe(map((ids) => ids)); + } + /** + * @returns the active item. The active item is the currently downloading item + * which could be different from the playing item. + */ + get activeItem() { + return queueItemQuery.getActive(); + } + /** + * @returns the entire play queue + */ + get queueItems$() { + return queueItemQuery.selectAll().pipe(map((queueItems) => queueItems !== null && queueItems !== void 0 ? queueItems : [])); + } + /* + * @returns whether this is the first item + */ + get isFirstItem() { + return this.firstItem; + } + get playingItem() { + return this.playingEntity; + } + get loadingItem() { + return this.loadingEntity; + } + /** + * Add item to the queue and makes it active but keeps the former active item. + * + * @param name Identifier for the item + * @param url URL for the root playlist + */ + addQueueItem(name, url, initialSeekTime, platformInfo, itemStartOffset, serviceName) { + // TODO: Kola to investigate not exposing itemStartOffset in the public API of addQueueItem + queueItemQuery.getCount(); + const queueItem = ItemQueue.createItem(name, url, initialSeekTime, platformInfo, serviceName); + if (this.playingEntity != null) { + // clear initialSeekTime if it's not the playing item + queueItem.initialSeekTime = undefined; + } + if (itemStartOffset) { + queueItem.itemStartOffset = itemStartOffset; + getLogger().debug(`itemStartOffset=${queueItem.itemStartOffset}`); + this.firstItem = false; + // set playing and loading item ids + this.playingEntity = this.activeItem; + this.loadingEntity = queueItem; + } + logAction(`queue.add.item: ${name}`); + applyTransaction(() => { + queueItemStore.add(queueItem); + queueItemStore.setActive(queueItem.itemId); + }); + } + /** + * Update the playing item id from loading item id and clear loading item id + */ + updatePlayingItemId() { + this.playingEntity = this.loadingEntity; + this.loadingEntity = null; + this.clearAllButActive(); + } + /** + * Reset loading item + */ + resetLoadingItem() { + this.removeQueueItem(this.loadingEntity.itemId); + this.loadingEntity = null; + applyTransaction(() => { + queueItemStore.setActive(this.playingEntity.itemId); + }); + } + /** + * Returns whether a track is currently preloading but not yet playing + */ + isPreloading() { + // If both loading and playing items are not undefined then a track is currently loading + return this.playingEntity !== null && this.loadingEntity !== null; + } + setQueueItem(name, url, initialSeekTime, platformInfo, serviceName) { + logAction('queue.set.item'); + this.loadingEntity = null; + applyTransaction(() => { + queueItemStore.reset(); + const queueItem = ItemQueue.createItem(name, url, initialSeekTime, platformInfo, serviceName); + queueItemStore.add(queueItem); + queueItemStore.setActive(queueItem.itemId); + }); + this.playingEntity = this.activeItem; + } + /** + * Remove an item from the queue + */ + removeQueueItem(itemId) { + queueItemStore.remove(itemId); + } + /** + * Clear the queue + */ + clearQueue() { + queueItemStore.reset(); + } + /** + * Clear all items but the active item + */ + clearAllButActive() { + var _a; + const activeId = (_a = this.activeItem) === null || _a === void 0 ? void 0 : _a.itemId; + applyTransaction(() => { + const items = queueItemQuery.getAll(); + items.forEach((item) => { + if (item.itemId !== activeId) { + queueItemStore.remove(item.itemId); + } + }); + }); + } + set earlyAudioSelection(audioPersistentId) { + queueItemStore.updateActive((activeItem) => { + if (!activeItem.earlySelection) { + activeItem.earlySelection = {}; + } + activeItem.earlySelection.audioPersistentId = audioPersistentId; + }); + } + get earlyAudioSelection() { + var _a; + return (_a = this.activeItem.earlySelection) === null || _a === void 0 ? void 0 : _a.audioPersistentId; + } + set earlySubtitleSelection(subtitlePersistentId) { + queueItemStore.updateActive((activeItem) => { + if (!activeItem.earlySelection) { + activeItem.earlySelection = {}; + } + activeItem.earlySelection.subtitlePersistentId = subtitlePersistentId; + }); + } + get earlySubtitleSelection() { + var _a; + return (_a = this.activeItem.earlySelection) === null || _a === void 0 ? void 0 : _a.subtitlePersistentId; + } + } + + /** + * Handle MSE related errors: sourcebuffer creation, appending, etc. + */ + // Append error handling + function addAppendErrorHandlingPolicy(mediaSink, sbAdapter, mediaOptionType, mediaOptionId, targetDuration, config, rootQuery, rootService, meQuery) { + return (source) => source.pipe(tap(() => { + rootService.updateConsecutiveTimeouts(rootQuery.itemId, mediaOptionType, false, 'append'); + }), retryWhen((errors) => errors.pipe(mergeMap((err, retryCount) => { + const isTimeout = err instanceof AppendBufferError && err.isTimeout; + rootService.updateConsecutiveTimeouts(rootQuery.itemId, mediaOptionType, isTimeout, 'append'); + if (isTimeout) { + return handleAppendTimeout(err, retryCount, config, mediaOptionType, mediaOptionId, meQuery, rootQuery, rootService); + } + if (err instanceof BufferFullError) { + return handleBufferFullError(err, sbAdapter, retryCount, targetDuration, config, mediaOptionType, mediaOptionId, meQuery, rootQuery, rootService); + } + if (err instanceof MediaDecodeError) { + const { mediaOptionType, mediaOptionId } = err; + return handleFormatError(err, mediaOptionType, mediaOptionId, mediaSink, rootService, rootQuery); + } + throw err; + })))); + } + function handleBufferFullError(error, sb, retryCount, targetDuration, config, mediaOptionType, mediaOptionId, meQuery, rootQuery, rootService) { + const sbType = sb.type; + const currentWaterLevel = meQuery.getCurrentWaterLevelByType(sbType, config.maxBufferHole); // Always use real position for buffer full errors + const mediaBuffered = currentWaterLevel >= config.almostDryBufferSec; + // Ejecting media from the buffer in iframe-mode will allow trick-play to recover when the forward audio buffer is full + // TODO: This should be considered for normal playback. Retries buy time, but they don't help reduce buffer usage. + // Flushing back and forward buffer is a better long-term solution for reclaiming memory. + if (mediaBuffered && !meQuery.isIframeRate) { + // this.logger.debug(`${self} bufferFullError waterLevel:${currentWaterLevel} targetDur:${this.targetDuration}`); + const retryDelayMs = targetDuration * 1000; + const action = { + errorAction: NetworkErrorAction.RetryRequest, + errorActionFlags: 0, + }; + if (currentWaterLevel * 1000 < retryDelayMs) { + if (rootService.hasFallbackMediaOptionTuple(rootQuery, mediaOptionType, mediaOptionId, false)) { + // Put into penalty box if we might run out of buffer before we can append again + action.errorAction = NetworkErrorAction.SendAlternateToPenaltyBox; + } + else { + // can only fit 1 target duration so likely to stall. Probably pointless to keep going + // this.logger.warn(`${self} buffer too small to sustain playback @${pos.toFixed(3)} buffered:${TimeRangesExt.toString(this.buffered)}`); + action.errorAction = NetworkErrorAction.SendEndCallback; + } + } + // this.logger.info(`${self} handleBufferFullError errorAction:${errorAction} ${retryDelayMs}ms`); + const retryConfig = { + retryDelayMs, + maxNumRetry: Infinity, + maxRetryDelayMs: retryDelayMs, + }; + return handleErrorWithRetry(error, retryCount, retryConfig, action, rootQuery, rootService, mediaOptionType, mediaOptionId); + } + else if (retryCount < config.appendErrorMaxRetry) { + // current position is not buffered, but browser is still complaining about buffer full error + // this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708 + // in that case flush the whole buffer to recover and retry + // this.logger.warn(`${self} buffer full and not buffered. flush everything and retry`); + return sb.remove(0, Number.POSITIVE_INFINITY); + } + else { + error.fatal = true; + } + return throwError(error); // Rethrow + } + function handleAppendTimeout(err, retryCount, config, mediaOptionType, mediaOptionId, meQuery, rootQuery, rootService) { + // Should be rare. If append timeout occurs possibly there is some platform or media issue so safer to + // reset and switch + let errorAction = { + errorAction: NetworkErrorAction.SendAlternateToPenaltyBox, + errorActionFlags: 0, + }; + const waterLevel = meQuery.getCurrentWaterLevel(config.maxBufferHole); + const bufferEmpty = waterLevel < config.almostDryBufferSec; + let retryDelayMs = NaN; + const maxAppendFails = config.appendErrorMaxRetry; + const appendTimeouts = rootQuery.rootPlaylistEntity.errorsByType[mediaOptionType].timeouts.append; + if ((bufferEmpty && appendTimeouts >= maxAppendFails) || retryCount >= maxAppendFails) { + errorAction.errorAction = NetworkErrorAction.SendEndCallback; + } + else { + retryDelayMs = waterLevel * 1000; // should only trigger on last variant + } + const retryConfig = { + retryDelayMs, + maxNumRetry: maxAppendFails, + maxRetryDelayMs: retryDelayMs, + }; + errorAction = modifyErrorActionIfCurrentLevelIsLastValidLevel(errorAction, false, err.response.code, mediaOptionId, mediaOptionType, rootQuery, rootService); + return handleErrorWithRetry(err, retryCount, retryConfig, errorAction, rootQuery, rootService, mediaOptionType, mediaOptionId) + .pipe(); + } + function handleFormatError(err, mediaOptionType, mediaOptionId, mediaSink, rootService, rootQuery) { + let action = { + errorAction: NetworkErrorAction.RemoveAlternatePermanently, + errorActionFlags: 0, + }; + action = modifyErrorActionIfCurrentLevelIsLastValidLevel(action, false, err.response.code, mediaOptionId, mediaOptionType, rootQuery, rootService); + // No retry + return handleErrorActionCommon(err, 0, action, rootQuery, rootService, mediaOptionType, mediaOptionId).pipe(catchError((err) => { + if (err.fatal === false) { + mediaSink.resetMediaSource(); + } + throw err; + })); + } + // Handle CreateSourceBufferError. For combined audio video append, handle the error here so that + // reset does not destroy the other SourceBuffer too early + function addCreateSourceBufferErrorHandlingPolicy(mediaSink, rootService, rootQuery) { + return (source$) => source$.pipe(catchError((err) => { + if (err instanceof CreateSourceBufferError) { + const { mediaOptionType, mediaOptionId } = err; + return handleFormatError(err, mediaOptionType, mediaOptionId, mediaSink, rootService, rootQuery); + } + throw err; + })); + } + + class FragmentPicker { + constructor(logger, _rootPlaylistService, _rootQuery, _mediaQuery, _iframeMachine, config) { + this.logger = logger; + this._rootPlaylistService = _rootPlaylistService; + this._rootQuery = _rootQuery; + this._mediaQuery = _mediaQuery; + this._iframeMachine = _iframeMachine; + this._anchorMSNs = [NaN, NaN]; // First fragment in current discontinuity + this._avDetails = [null, null]; // enabled AV options latest details (just the relevant info) + this.logger = logger.child({ name: 'fpicker' }); + this._discoSeqNum = NaN; + this.lookUpTolerance = Math.max(config.maxBufferHole, config.maxFragLookUpTolerance); + this.firstAudioMustOverlapVideoStart = config.firstAudioMustOverlapVideoStart; + this.lookUpToleranceAlt = config.firstAudioMustOverlapVideoStart ? 0 : config.maxFragLookUpTolerance; + this.logger.info(`new item ${this._rootQuery.itemId}`); + } + destroy() { + this._anchorMSNs = [NaN, NaN]; + this._avDetails = [null, null]; + this._rootQuery = null; + this._mediaQuery = null; + this._rootPlaylistService = null; + this._iframeMachine = null; + } + get discoSeqNum() { + return this._discoSeqNum; + } + get _discoSeqNum() { + return this._rootQuery.discoSeqNum; + } + set _discoSeqNum(cc) { + // Should we just have a separate store for fragment selection? + this._rootPlaylistService.setDiscoSeqNum(this._rootQuery.itemId, cc); + } + get anchorMSNs() { + return this._anchorMSNs; + } + _resolvePosition(position, type, newDetails) { + var _a; + let resolvedPosition = position; + const curDetails = this._avDetails[type]; + // LIVE: + // 1. try choosing position based on program date time @ the switch position + // 2. if ptsknown, we can reasonably choose @ switch position + // 3. else, choose at live offset from end + // Has END-TAG: + // Simple case. just use position. + if ((curDetails === null || curDetails === void 0 ? void 0 : curDetails.mediaOptionId) !== (newDetails === null || newDetails === void 0 ? void 0 : newDetails.mediaOptionId) && + newDetails.liveOrEvent && + newDetails.ptsKnown === false && + (!curDetails || Math.max(curDetails.startSN, newDetails.startSN) > Math.min(curDetails.endSN, newDetails.endSN)) // no overlap + ) { + // Commenting out PDT based revisal as it needs new position as opposed to old position, before rebasing to newDetails. + // if (curDetails?.dateMediaTimePairs != null && newDetails.dateMediaTimePairs) { + // const date = resolvePTSToDate(curDetails.dateMediaTimePairs, position); + // resolvedPosition = resolveDateToPTS(newDetails.dateMediaTimePairs, date); + // this.logger.info(`Use program date time ${date.toISOString()} ${position.toFixed(3)}->${resolvedPosition.toFixed(3)}`); + // } else { + const liveOffsetSec = 3 * newDetails.targetduration; // HLS native chooses 3 * targetDuration, or HOLD-BACK property + const liveEdge = ((_a = newDetails.fragments[0]) === null || _a === void 0 ? void 0 : _a.start) + newDetails.totalduration; + resolvedPosition = Math.max(0, liveEdge - liveOffsetSec); + this.logger.info(`Use live offset ${liveOffsetSec.toFixed(3)} ${position.toFixed(3)}->${resolvedPosition.toFixed(3)}`); + // } + } + return resolvedPosition; + } + getDiscoSeqNumForTime(details, position) { + if (this._mediaQuery.isIframeRate && details.iframesOnly) { + return DiscoHelper$1.discoSeqNumForTime(details.fragments, position); // from iframeMachine startClocksAndGetFirstFragment + } + else { + return discoSeqNumForTime(details, position); + } + } + /** + * After a seek, need to re-anchor using latest details + * @param position Position for re-anchor + * @param detailsTuple details + */ + _updateAnchorByPosition(position, detailsTuple) { + let newCC = NaN; + const vDetails = detailsTuple[SourceBufferType.Variant]; + let resolvedPosition = position; + if (vDetails) { + const fragments = vDetails.fragments; + resolvedPosition = this._resolvePosition(position, SourceBufferType.Variant, vDetails); + newCC = this.getDiscoSeqNumForTime(vDetails, resolvedPosition); // used resolved position to get CC + if (!isFiniteNumber(newCC)) { + const firstFrag = fragments[0]; + const lastFrag = fragments[fragments.length - 1]; + const startPTSSec = firstFrag === null || firstFrag === void 0 ? void 0 : firstFrag.start; + const endPTSSec = (lastFrag === null || lastFrag === void 0 ? void 0 : lastFrag.start) + (lastFrag === null || lastFrag === void 0 ? void 0 : lastFrag.duration); + this.logger.warn(`${position.toFixed(3)} out of range [${startPTSSec === null || startPTSSec === void 0 ? void 0 : startPTSSec.toFixed(3)},${endPTSSec === null || endPTSSec === void 0 ? void 0 : endPTSSec.toFixed(3)}]`); + if (resolvedPosition <= startPTSSec) { + // Gapless preloading + newCC = firstFrag.discoSeqNum; + } + else if (resolvedPosition >= endPTSSec) { + newCC = lastFrag.discoSeqNum; + } + else { + this.logger.warn(`Unable to determine newCC. fragFirst: ${JSON.stringify(firstFrag)} fragLast: ${JSON.stringify(lastFrag)}`); + } + if (!isFiniteNumber(newCC)) { + this.logger.warn(`Unable to determine newCC. fragFirst: ${JSON.stringify(firstFrag)} fragLast: ${JSON.stringify(lastFrag)}`); + } + } + } + else { + this.logger.warn('No variant details for anchoring'); + } + if (newCC !== this._discoSeqNum) { + this.logger.info(`Update anchor by position:${resolvedPosition.toFixed(3)} cc:${this._discoSeqNum}->${newCC}`); + } + this._updateAnchor(newCC, detailsTuple); + return resolvedPosition; + } + _updateAnchor(newCC, detailsTuple) { + const ccDidChange = newCC !== this._discoSeqNum; + if (ccDidChange) { + this.logger.info(`Update anchor cc:${this._discoSeqNum}->${newCC}`); + this._discoSeqNum = newCC; + } + AVMediaOptionTypes.forEach((type) => { + const curDetails = this._avDetails[type]; + const newDetails = detailsTuple[type]; + const detailsChanged = (curDetails === null || curDetails === void 0 ? void 0 : curDetails.mediaOptionId) !== (newDetails === null || newDetails === void 0 ? void 0 : newDetails.mediaOptionId); + if (ccDidChange || detailsChanged) { + this._updateAnchorForType(mediaOptionTypeToSourceBufferType(type), newDetails); + } + else if (newDetails) { + const { mediaOptionId, ptsKnown, dateMediaTimePairs, startSN, endSN } = newDetails; + this._avDetails[type] = { mediaOptionId, ptsKnown, dateMediaTimePairs, startSN, endSN }; + } + }); + } + /** + * Get next set of fragments to choose. + * @param pos The playback position (media.currentTime) + * @param detailsTuple The latest details for variant and alt audio + * @param usePosition if true, use position for selection. else, use buffer end + */ + getNextFragments(action, detailsTuple, logger) { + const { position, bufferInfoTuple, switchContexts } = action; + const searchPositions = bufferInfoTuple.map((bufferInfo, type) => { + return getSearchPosition(position, detailsTuple[type], switchContexts[type], bufferInfo === null || bufferInfo === void 0 ? void 0 : bufferInfo.buffered, type === MediaOptionType.AltAudio ? this.lookUpToleranceAlt : this.lookUpTolerance); + }); + let anchorPosition = searchPositions.reduce((lastMin, position) => Math.min(position, lastMin), Number.POSITIVE_INFINITY); + if (isFiniteNumber(action.discoSeqNum)) { + // if anchorTime specifies a discontinuity sequence number, find only fragments in the specified cc. + // happens right after resetting mediaSource when crossing an incompat. discontinuity + const combinedRange = detailsTuple.reduce((finalRange, details) => { + if (!details) { + return finalRange; + } + const thisRange = DiscoHelper$1.getTimeRangeForCC(details.fragments, action.discoSeqNum, logger); // adjust anchorPosition in case the anchor cc is a bit off + return [Math.max(finalRange[0], thisRange[0]), Math.min(finalRange[1], thisRange[1])]; + }, [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY]); + anchorPosition = Math.min(Math.max(anchorPosition, combinedRange[0]), combinedRange[1]); + this.logger.info(`adjusted anchorPosition ${anchorPosition} to fit in cc ${action.discoSeqNum} [${combinedRange[0]}-${combinedRange[1]}]`); + } + action.position = this._updateAnchorByPosition(anchorPosition, detailsTuple); + return this._getNextFragmentsInternal(action, detailsTuple); + } + _getNextFragmentsInternal(action, detailsTuple) { + var _a, _b; + const chosenFrags = [null, null]; + let origPosition; + detailsTuple.forEach((_, type) => { + var _a; + if (this.firstAudioMustOverlapVideoStart && type === MediaOptionType.AltAudio && this._mediaQuery.seeking) { + // this ensures the audio is not ahead of the video; + // especially, decode from iframes could further pull back the + // seek position, and we should ensure that the corresponding audio is + // also available + if ((_a = chosenFrags[MediaOptionType.Variant]) === null || _a === void 0 ? void 0 : _a.foundFrag) { + // retain original position in case of next discontinuity + origPosition = action.position; + action.position = chosenFrags[MediaOptionType.Variant].foundFrag.mediaFragment.start; + this.logger.info(`revised altAudio frag search position to ${action.position} based on variant frag start`); + } + } + chosenFrags[type] = this._getNextFragmentForType(action, detailsTuple, type); + }); + const vResult = chosenFrags[SourceBufferType.Variant]; + const aResult = chosenFrags[SourceBufferType.AltAudio]; + // One buffer is too far ahead of the other one + // 1. Could happen in i-frame mode where audio fragments are much longer + // 2. Audio switch that causes complete flush + const vFrag = (_a = vResult === null || vResult === void 0 ? void 0 : vResult.foundFrag) === null || _a === void 0 ? void 0 : _a.mediaFragment; + const aFrag = (_b = aResult === null || aResult === void 0 ? void 0 : aResult.foundFrag) === null || _b === void 0 ? void 0 : _b.mediaFragment; + if (vFrag && aFrag) { + if (aFrag.start > vFrag.start + vFrag.duration) { + // must not load audio too far ahead in iframe mode, cause unrecoverable bufferFull error in AirPlay + this.logger.warn('Audio too far ahead'); + chosenFrags[SourceBufferType.AltAudio] = FragmentPicker.noopResult; + } + else if (vFrag.start > aFrag.start + aFrag.duration && !this._mediaQuery.isIframeRate) { + this.logger.warn('Video too far ahead'); + chosenFrags[SourceBufferType.Variant] = FragmentPicker.noopResult; + } + } + // All fragments in next discontinuity. Advance and try selecting again + if (isFinite(vResult === null || vResult === void 0 ? void 0 : vResult.nextDisco) && (aResult == null || isFiniteNumber(aResult.nextDisco))) { + const newDisco = chosenFrags[SourceBufferType.Variant].nextDisco; + this.logger.info(`Advance anchor cc: ${this._discoSeqNum}->${newDisco}`); + this._updateAnchor(newDisco, detailsTuple); + if (isFiniteNumber(origPosition)) { + // reinstate the original position due to previous firstAudioMustOverlapVideoStart override + action.position = origPosition; + origPosition = NaN; + } + return this._getNextFragmentsInternal(action, detailsTuple); + } + return chosenFrags; + } + /** + * Get fragment for position for particular buffer + * @param pos position that fragment should overlap + * @param usePos if true, choose fragment overlapping pos (e.g. immediate switch w/o flush). else, use bufferEnd (default) + */ + _getNextFragmentForType(action, detailsTuple, type) { + var _a, _b, _c, _d, _e, _f, _g, _h; + const { position: pos, bufferInfoTuple, switchContexts } = action; + const newDetails = detailsTuple[type]; + const bufferInfo = (_b = (_a = bufferInfoTuple[type]) === null || _a === void 0 ? void 0 : _a.buffered) !== null && _b !== void 0 ? _b : { start: pos, end: pos, len: 0 }; + const bufferedSeg = this._mediaQuery.getBufferedSegmentsByType(type); + const willFlush = (_d = (_c = switchContexts[type]) === null || _c === void 0 ? void 0 : _c.userInitiated) !== null && _d !== void 0 ? _d : false; // Full flush of this buffer will happen + const searchPos = getSearchPosition(pos, newDetails, switchContexts[type], bufferInfo, this.lookUpTolerance); + if (!newDetails) { + return null; + } + const { highWaterLevelSeconds, lowWaterLevelSeconds } = this._mediaQuery.bufferMonitorInfo; + const bufferAhead = bufferInfo.len; // Future bufferAhead + if (!willFlush && bufferAhead >= highWaterLevelSeconds) { + this.logger.info(`[${MediaOptionNames[type]}] got high buffer @${pos.toFixed(3)} ${bufferInfo.len.toFixed(3)} > ${highWaterLevelSeconds}`); + return FragmentPicker.noopResult; + } + // Special case where audio is starving but variant is ok + const otherType = type === SourceBufferType.Variant ? SourceBufferType.AltAudio : SourceBufferType.Variant; + const otherBuffer = (_e = bufferInfoTuple[otherType]) === null || _e === void 0 ? void 0 : _e.buffered; + const otherWillFlush = (_g = (_f = switchContexts[otherType]) === null || _f === void 0 ? void 0 : _f.userInitiated) !== null && _g !== void 0 ? _g : false; + let wantToDelayVariant = false; + if (type === SourceBufferType.Variant && + bufferAhead >= lowWaterLevelSeconds && + // Yield to altaudio (but ensure audio load-n-append does not punt back to variant, causing an infinite loop): + // A) Audio buffer ends earlier than video buffer. + // If buffered audio ends later than video, audio append may abort & wait for video append to catch up in mediaSink.getMatchingInfo + this._mediaQuery.expectedSbCount > 1 && + otherBuffer != null && + otherBuffer.end < bufferInfo.end && + // B) Audio was starting from an empty buffer (true starvation after audio track switch): _total_ audio buffer < 1 target duration + // Use (otherBuffer.end - otherBuffer.start) instead of otherBuffer.len (which begins from currentTime, not start of buffer) + (otherWillFlush || otherBuffer.end - otherBuffer.start < lowWaterLevelSeconds)) { + this.logger.info(`[${MediaOptionNames[type]}] want to delay variant due to audio starvation @${pos.toFixed(3)} ${bufferInfo.len.toFixed(3)} > ${lowWaterLevelSeconds}`); + wantToDelayVariant = true; + } + let foundFrag = null; + let nextDisco = NaN; + let newMediaRootTime = undefined; + if (this._mediaQuery.isIframeRate && type === SourceBufferType.Variant && newDetails.iframesOnly) { + const result = findIframeFragmentForPosition(searchPos, newDetails, detailsTuple[SourceBufferType.AltAudio], this._mediaQuery.desiredRate, this._iframeMachine); + if (result) { + ({ foundFrag, nextDisco, newMediaRootTime } = result); + const frag = foundFrag.mediaFragment; + if (frag.discoSeqNum !== this._discoSeqNum) { + this.logger.info(`[iframes] overrride cc:${frag.discoSeqNum}`); + // OK to advance here since Variant will run before AltAudio. + this._updateAnchor(frag.discoSeqNum, detailsTuple); + } + } + } + else { + // Find eligible segment in the specified discontinuity + const anchorMSN = this._anchorMSNs[type]; + ({ foundFrag, nextDisco, newMediaRootTime } = findFragment(searchPos, this._discoSeqNum, anchorMSN, newDetails, bufferedSeg)); + } + if (wantToDelayVariant && this._rootQuery.getInitPTS(foundFrag === null || foundFrag === void 0 ? void 0 : foundFrag.mediaFragment.discoSeqNum)) { + this.logger.info(`[${MediaOptionNames[type]}] delay variant since initPTS[${foundFrag === null || foundFrag === void 0 ? void 0 : foundFrag.mediaFragment.discoSeqNum}] is available`); + return FragmentPicker.noopResult; + } + this.logger.info(`[${MediaOptionNames[type]}] getNextFragmentForType searchPos:${searchPos.toFixed(3)} pos:${pos.toFixed(3)} bufferEnd:${bufferInfo === null || bufferInfo === void 0 ? void 0 : bufferInfo.end.toFixed(3)} willFlush: ${willFlush} cc:${this._discoSeqNum} foundFrag:${fragPrint(foundFrag === null || foundFrag === void 0 ? void 0 : foundFrag.mediaFragment)} timelineOffset:${(_h = foundFrag === null || foundFrag === void 0 ? void 0 : foundFrag.timelineOffset) === null || _h === void 0 ? void 0 : _h.toFixed(3)} nextDisco:${nextDisco} newMediaRootTime:${newMediaRootTime}`); + return { foundFrag, nextDisco, newMediaRootTime }; + } + _updateAnchorForType(type, newDetails) { + var _a; + if (!newDetails) { + this._anchorMSNs[type] = NaN; + this._avDetails[type] = null; + return; + } + if (!isFiniteNumber(this._discoSeqNum)) { + this.logger.warn('Trying to anchor with non-finite discoSeqNum'); + return; + } + const cc = this._discoSeqNum; + const anchorFrag = getAnchorFrag(newDetails.fragments, cc); + const mediaSeqNum = (_a = anchorFrag === null || anchorFrag === void 0 ? void 0 : anchorFrag.mediaSeqNum) !== null && _a !== void 0 ? _a : newDetails.startSN; // No anchor, use first fragment as fallback + this._anchorMSNs[type] = mediaSeqNum; + const { mediaOptionId, ptsKnown, dateMediaTimePairs, startSN, endSN } = newDetails; + this._avDetails[type] = { mediaOptionId, ptsKnown, dateMediaTimePairs, startSN, endSN }; + this.logger.info(`[${MediaOptionNames[type]}] Anchor update id:${mediaOptionId} sn:${this._anchorMSNs[type]}->${mediaSeqNum} discoSeqNum:${this._discoSeqNum}`); + } + } + FragmentPicker.noopResult = { foundFrag: null, nextDisco: NaN }; // prevents us from skipping ahead in disco + /** + * Get first fragment in discontinuity cc + */ + function getAnchorFrag(fragments, cc) { + return fragments.find((f) => f.discoSeqNum === cc); + } + function getSearchPosition(pos, details, switchContext, bufferInfo, defaultTolerance) { + var _a; + bufferInfo = bufferInfo !== null && bufferInfo !== void 0 ? bufferInfo : { start: pos, end: pos, len: 0 }; + const willFlush = (_a = switchContext === null || switchContext === void 0 ? void 0 : switchContext.userInitiated) !== null && _a !== void 0 ? _a : false; // Full flush of this buffer will happen + const tolerance = (details === null || details === void 0 ? void 0 : details.iframesOnly) ? 0 : defaultTolerance; + return willFlush || bufferInfo.len === 0 ? pos : bufferInfo.end + tolerance; + } + + const avPipeLogName = { name: 'avpipe' }; + // AVPipe + function makeAVPipe(context) { + const { config, rootPlaylistService, rootPlaylistQuery, mediaSink, gaplessInstance } = context; + const mediaQuery = mediaSink.mediaQuery; + const mediaOptionSwitching$ = combineQueries(AVMediaOptionTypes.map((type) => { + return rootPlaylistQuery.enabledMediaOptionSwitchForType$(type).pipe(tap((switchInfo) => logger.info(`${MediaOptionNames[type]} mediaOptionSwitch: ${JSON.stringify(switchInfo)}`))); + })).pipe(switchMap((switchInfo) => { + // Teardown if no enabled option for at least main + if (!isEnabledMediaOption({ itemId: rootPlaylistQuery.itemId, mediaOptionId: switchInfo[MediaOptionType.Variant].toId })) { + throw new ExceptionError(true, `No valid variant enabled id:${switchInfo[MediaOptionType.Variant].toId}`, ErrorResponses.NoValidAlternates); + } + // Handle switch + const switchActions$ = switchInfo.map(({ fromId, toId }, mediaOptionType) => { + return pipelineHandleOptionSwitch(context, statsQuery, mediaOptionType, fromId, toId); + }); + return concat(of(true), // Emit on switch start + forkJoin(switchActions$).pipe(mapTo(false)) // Emit when we're ready to select fragments + ); + }), tag('mediaOptionSwitch.audiovideo.out')); + const statsQuery = createStatsQuery(rootPlaylistQuery.itemId); + const logger = context.logger.child(avPipeLogName); + const fragmentPicker = new FragmentPicker(logger, rootPlaylistService, rootPlaylistQuery, mediaQuery, context.iframeMachine, config); + const anchorTimeChange$ = rootPlaylistQuery.anchorTime$.pipe(tag('anchorTime.audiovideo.in')); + // Switch subscriptions when: + // 1. anchor time change + // 2. enabled option change + // Exhaust / wait for pipeline to finalize when: + // 1. Need data changes + return combineQueries([anchorTimeChange$, mediaOptionSwitching$]).pipe(switchMap(([anchorTime, handlingSwitch]) => { + logger.info(`anchorTime=${anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.pos.toFixed(3)} cc=${anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.discoSeqNum} handlingSwitch=${handlingSwitch}`); + if (handlingSwitch) { + return EMPTY; // Just cancel any loads in progress. This is to stop stuff from loading while we're flushing + } + return mediaQuery.needData$(config.maxBufferHole, gaplessInstance.inGaplessMode).pipe(map((needData) => { + const switchContexts = [ + rootPlaylistQuery.enabledMediaOptionSwitchContexts[MediaOptionType.Variant], + rootPlaylistQuery.enabledMediaOptionSwitchContexts[MediaOptionType.AltAudio], + ]; + return mediaQuery.getSourceBufferInfoAction(needData, anchorTime, switchContexts, config.maxBufferHole); + }), exhaustMap((sbAction) => { + if (!sbAction) { + return EMPTY; // Don't emit if we didn't do anything + } + logger.debug(`start hoses ${JSON.stringify(sbAction)}`); + const producerConsumer$ = of(sbAction).pipe(mediaProducerEpic(context, fragmentPicker), mediaConsumerEpic(context)); + return race(producerConsumer$, waitFor(shouldAbortFrag(context), (abort) => abort) // If this emits, we'll abort the whole chain + ).pipe(take(1), finalize$1(() => { + AVMediaOptionTypes.forEach((type) => { + rootPlaylistService.updateInflightFrag(rootPlaylistQuery.itemId, type, null, null, null); + }); + })); + })); + }), map(() => { + if (rootPlaylistQuery.getEntity(rootPlaylistQuery.itemId).manualMode) { + return; + } + // Check for automatic / lazy switch + let switchReason = SwitchReason.None; + if (checkAndUpdateViewportInfo(platformService(), mediaQuery, config, logger)) { + switchReason = SwitchReason.PreferredListChanged; + } + let cappedForLowBandwidth = false; + const enabledOption = rootPlaylistQuery.enabledVariantMediaOption; + if (gotLowBw(rootPlaylistQuery, mediaQuery, rootPlaylistService)) { + switchReason = SwitchReason.LowBandwidth; + // Only add a cap if there is not already one in place + if (rootPlaylistQuery.nextMaxAutoOptionId === NoMediaOption.mediaOptionId) { + // Should uncap automatically if we select a different variant, ensure this is released after handling switch + rootPlaylistService.setNextMaxAutoOptionId(enabledOption.itemId, enabledOption.mediaOptionId); + logger.info(`Capping variant selection to ${enabledOption.mediaOptionId} because switchReason: ${switchReason}`); + cappedForLowBandwidth = true; + } + } + else if (mediaQuery.playbackStarted && gotHighBw(config, rootPlaylistQuery, rootPlaylistService)) { + switchReason = SwitchReason.HighBandwidth; + rootPlaylistService.setNextMinAutoOptionId(enabledOption.itemId, enabledOption.mediaOptionId); + logger.info(`Capping variant selection to above ${enabledOption.mediaOptionId} because switchReason: ${switchReason}`); + } + handleVariantSwitch(switchReason, config, rootPlaylistQuery, mediaQuery, rootPlaylistService); + // Remove any max/min level caps we placed before level selection + if (cappedForLowBandwidth) { + rootPlaylistService.setNextMaxAutoOptionId(enabledOption.itemId, NoMediaOption.mediaOptionId); + } + else if (switchReason === SwitchReason.HighBandwidth) { + rootPlaylistService.setNextMinAutoOptionId(enabledOption.itemId, NoMediaOption.mediaOptionId); + } + }), finalize$1(() => { + // on (i) active item change, or (ii) after handleErrorActionCommon which will reuse fragmentPicker. + // let fragmentPicker garbage collect automatically. + logger.debug('teardown'); + })); + } + function audioMediaOptionRemoved(rootPlaylistQuery, fromId, toId) { + const fromAlternate = fromId === 'Nah' ? null : rootPlaylistQuery.alternateMediaOptionById(MediaOptionType.AltAudio, fromId); + const fromIdHasAudio = Boolean(fromAlternate && fromAlternate.url); + const toAlternate = fromId === 'Nah' ? null : rootPlaylistQuery.alternateMediaOptionById(MediaOptionType.AltAudio, toId); + const toIdHasAudio = Boolean(toAlternate && toAlternate.url); + // rename function to audioMediaOptionRemovedOrAdded if uncommenting following line. + // return fromIdHasAudio !== toIdHasAudio; + return fromIdHasAudio && !toIdHasAudio; + } + /** + * @brief Handle option switch at start of pipeline + * Called within pipeline as an action before fetch, as part of switching the enabled option + * May be called before or after destination option has actually fully loaded + */ + function pipelineHandleOptionSwitch(libContext, statsQuery, mediaOptionType, fromId, toId) { + var _a, _b; + const { rootPlaylistQuery, rootPlaylistService, mediaSink, mediaParser, logger, config, iframeMachine } = libContext; + const meQuery = mediaSink.mediaQuery; + if (!fromId || !toId || (fromId === toId && (mediaOptionType === MediaOptionType.AltAudio || !iframeMachine.isStarted))) { + // if iframeMachine.isStarted, must check for trickplay exit condition + return VOID; + } + switch (mediaOptionType) { + case MediaOptionType.Variant: + { + if (fromId !== toId) { + mediaParser.reset(MediaOptionType.Variant); + } + const sbType = mediaOptionTypeToSourceBufferType(mediaOptionType); + const fromVariant = rootPlaylistQuery.variantMediaOptionById(fromId); + const toVariant = rootPlaylistQuery.variantMediaOptionById(toId); + const itemId = rootPlaylistQuery.itemId; + if (toVariant == null || fromVariant == null) { + return VOID; + } + const resumingFromTrickPlay = !toVariant.iframes && iframeMachine.isStarted; + if (fromVariant.iframes !== toVariant.iframes || resumingFromTrickPlay) { + mediaSink.toggleTrickPlaybackMode(toVariant.iframes); + if (resumingFromTrickPlay) { + if (!isFiniteNumber(mediaSink.mediaQuery.postFlushSeek)) { + mediaSink.postFlushSeek = iframeMachine.iframeClockTimeSeconds; + } + iframeMachine.stop(); + } + logger.info(`pause & flush for iframeMode transition [0, Infinity] postFlushSeek=${mediaSink.mediaQuery.postFlushSeek} resumingFromTrickPlay=${resumingFromTrickPlay}`); + mediaSink.pause(); + // (2.1a) Flush audio and video when resuming from trickplay to avoid fpicker getting stuck with audio gaps after rewind + const postTrickPlayFlush$ = resumingFromTrickPlay ? mediaSink.flushAll(0, Infinity, true) : mediaSink.flushData(sbType, 0, Infinity, true); + return postTrickPlayFlush$.pipe(tap(() => { + const postFlushSeek = mediaSink.mediaQuery.postFlushSeek; + if (isFiniteNumber(postFlushSeek)) { + rootPlaylistService.setPendingSeek(itemId, postFlushSeek); + } + })); + } + // From stream-controller.ts attemptSafeNextLevelSwitch + if (!config.allowFastSwitchUp || toVariant.iframes) { + return VOID; + } + const fromQuery = createMediaLibraryQuery(fromVariant); + const fromDetails = fromQuery.mediaOptionDetails; + if (fromDetails != null && toVariant != null && fromVariant.bitrate < toVariant.bitrate) { + const fromTargetDuration = fromDetails.targetduration; + const mediaLibraryQuery = createMediaLibraryQuery(toVariant); + const toDetails = mediaLibraryQuery.mediaOptionDetails; + const lastUpdateMs = mediaLibraryQuery.mediaOptionDetailsEntity.lastUpdateMillis; + const currentWaterLevel = meQuery.getCurrentWaterLevelByType(sbType, config.maxBufferHole); + const minBufferAhead = minSwitchBufferAheadSec(fromVariant, toVariant, toDetails, fromTargetDuration, rootPlaylistQuery.abrStatus, statsQuery, config, lastUpdateMs, logger) + config.maxStarvationDelay; // add a safety delay of maxStarvationDelay + logger.info(`fastSwitchUp: currentWaterLevel:${currentWaterLevel} minBufferAhead:${minBufferAhead}`); + // Flush from somewhere past midpoint of first segment after minFlushStart position + const minFlushStart = meQuery.currentTime + minBufferAhead; + const segment = (_b = (_a = meQuery.sourceBufferEntityByType(sbType)) === null || _a === void 0 ? void 0 : _a.bufferedSegments) === null || _b === void 0 ? void 0 : _b.find((seg) => seg.startPTS >= minFlushStart); + // Flush position will remove half to a quarter (at least maxFragLookUpTolerance) of the buffered segment + // to avoid gaps left by appening new segments with dropped samples up to the first IDR frame + let flushStart; + if (segment) { + const duration = segment.endPTS - segment.startPTS; + flushStart = segment.startPTS + Math.min(Math.max(duration - config.maxFragLookUpTolerance, duration * 0.5), duration * 0.75); + } + if (isFiniteNumber(flushStart) && currentWaterLevel >= minBufferAhead) { + // Note: old code had special handling for live to preserve fragPrevious + logger.info(`flush for fast switchup [${flushStart.toFixed(3)}, Infinity]`); + return mediaSink.flushData(sbType, flushStart, Infinity); + } + } + } + break; + case MediaOptionType.AltAudio: + if (audioMediaOptionRemoved(rootPlaylistQuery, fromId, toId)) { + // altAudio -> muxed handling is tricky because: + // when hls switches audio, the new altAudio mediaOption (toId) has no url; audio is muxed with video. + // During switching, getDetailsAndSwitchContext(altAudio) will ignore toId because it has no mediaOptionDetails too. + // As a result, chooseAndFetchFragment will never sees toId's switchContext to trigger any audio switching logic. + // Cleaner to shortcircuit the process: reset the mediaSource now, reload and seek with only the muxed mediaOption. + logger.info(`alt audio removed/added while switching fromId ${fromId} to toId ${toId} @ ${meQuery.currentTime}`); + rootPlaylistService.setEnabledMediaOptionSwitchContextByType(rootPlaylistQuery.itemId, MediaOptionType.AltAudio, toId, undefined); + mediaSink.resetMediaSource(meQuery.currentTime); + } + mediaParser.reset(MediaOptionType.AltAudio); + break; + } + return VOID; + } + function checkAndUpdateViewportInfo(platformService, mediaQuery, config, logger) { + var _a; + const clientWidth = mediaQuery === null || mediaQuery === void 0 ? void 0 : mediaQuery.clientWidth; + const clientHeight = mediaQuery === null || mediaQuery === void 0 ? void 0 : mediaQuery.clientHeight; + const devicePixelRatio = typeof window === 'object' && window.devicePixelRatio ? window.devicePixelRatio : 1; + const newViewportInfo = clientWidth && clientHeight ? { width: clientWidth * devicePixelRatio, height: clientHeight * devicePixelRatio } : undefined; + const curViewportInfo = ((_a = platformService.getQuery()) === null || _a === void 0 ? void 0 : _a.viewportInfo) || {}; + const isViewportSizeChanged = curViewportInfo && newViewportInfo && (curViewportInfo.width !== newViewportInfo.width || curViewportInfo.height !== newViewportInfo.height); + if (config.useViewportSizeForLevelCap && isViewportSizeChanged) { + platformService.updateViewportInfo(newViewportInfo); + logger.info(`ViewportSize changed, old: ${JSON.stringify(curViewportInfo)}, new: ${JSON.stringify(newViewportInfo)}`); + return true; + } + return false; + } + // AV Producer should work as follows: + // 1. wait for details for enabled variant & alt audio + // 2. choose fragment(s) for the position if < highWaterLevelSeconds + // 3. fetch & parse candidate fragments(s) + // 4. on parse, check if we need to re-select any fragment (ptsKnown changed) + // 5. advance discontinuity if needed + // 6. fetch & parse any new candidate fragment(s) + const mediaProducerEpic = (pipelineContext, fragmentPicker) => (bufferInfoAction$) => { + const { rootPlaylistQuery: rootQuery, mediaSink } = pipelineContext; + const logger = pipelineContext.logger.child(avPipeLogName); + return bufferInfoAction$.pipe(observeOn(asyncScheduler), withLatestFrom(rootQuery.enabledMediaOptionKeys$), + // Wait for details and switch context + switchMap(([action, enabledOptionKeys]) => { + return zip(getDetailsAndSwitchContext(action, MediaOptionType.Variant, pipelineContext, enabledOptionKeys).pipe(tap((detailsAndContext) => { + var _a, _b; + const varEntity = detailsAndContext.detailsEntity; + if (!varEntity.mediaOptionDetails.liveOrEvent || varEntity.mediaOptionDetails.ptsKnown) { + const newDuration = varEntity.playlistDuration; + // When AltAudio buffer is ahead of Variant and AltAudio buffer end is slightly greater than playlistDuration + // then setting mediaSink.msDuration based on variant alone will lead to mediaSource buffer trucation to set duration. + // This behavior is seen on Chrome browser, Roku & LG + const variantBufferEnd = ((_a = action.bufferInfoTuple[0]) === null || _a === void 0 ? void 0 : _a.buffered.end) || 0; + const altAudioBufferEnd = ((_b = action.bufferInfoTuple[1]) === null || _b === void 0 ? void 0 : _b.buffered.end) || 0; + const maxBufferEnd = Math.max(variantBufferEnd, altAudioBufferEnd); + mediaSink.msDuration = isFiniteNumber(mediaSink.msDuration) ? Math.max(mediaSink.msDuration, newDuration, maxBufferEnd) : newDuration; + } + })), getDetailsAndSwitchContext(action, MediaOptionType.AltAudio, pipelineContext, enabledOptionKeys)).pipe(map((detailsAndContext) => ({ action, detailsAndContext }))); + }), + // Choose, fetch, & parse fragments: + switchMap(({ action, detailsAndContext }) => chooseAndFetchFragments(logger, fragmentPicker, pipelineContext, action, detailsAndContext)), tag('mediaProducerEpic.emit')); + }; + function playlistIsValid(mediaOptionDetails, lastUpdateMillis) { + return !mediaOptionDetails.liveOrEvent || !mediaOptionDetails.ptsKnown || !likelyOutOfDate(mediaOptionDetails === null || mediaOptionDetails === void 0 ? void 0 : mediaOptionDetails.totalduration, 0, lastUpdateMillis); + } + function getDetailsAndSwitchContext(bufferInfoAction, type, pipelineContext, enabledMediaOptionKeys) { + const { rootPlaylistQuery, mediaLibraryService, gaplessInstance, config } = pipelineContext; + // Note we don't expect enabled option to change while we're in this hose because of makeAVPipe. + const option = enabledMediaOptionKeys[type]; + const logger = pipelineContext.logger.child({ name: MediaOptionNames[type] }); + if (!option || option.mediaOptionId === 'Nah') { + return of({ detailsEntity: null, switchContext: null }); + } + const playlistQuery = mediaLibraryService.getQueryForOption(option); + return combineLatest([ + of(bufferInfoAction), + playlistQuery.mediaOptionDetailsEntity$.pipe(distinctUntilChanged((a, b) => (a === null || a === void 0 ? void 0 : a.lastUpdateMillis) === (b === null || b === void 0 ? void 0 : b.lastUpdateMillis)), filter((mediaOptionDetailsEntity) => { + const mediaOptionDetails = mediaOptionDetailsEntity === null || mediaOptionDetailsEntity === void 0 ? void 0 : mediaOptionDetailsEntity.mediaOptionDetails; + if (!mediaOptionDetails) { + return true; // audio/muxed content + } + const now = performance.now(); + const lastUpdateMillis = mediaOptionDetailsEntity.lastUpdateMillis || now; + const liveOrEvent = mediaOptionDetails.liveOrEvent; + const targetDuration = mediaOptionDetails.targetduration; + // logger.info(`playlist updated at ${lastUpdateMillis}, current time is ${now}, delta is ${(now - lastUpdateMillis) / 1000} gt/lt ${2 * targetDuration}`); + // Ensure live mediaOptionDetails is not stale from a previous use of this level. + return !liveOrEvent || now - lastUpdateMillis < config.livePlaylistUpdateStaleness * targetDuration * 1000; + })), + ]).pipe(filter(([bufferInfoAction, detailsEntity]) => { + var _a, _b; + logger.info(`details entity ${(_a = detailsEntity === null || detailsEntity === void 0 ? void 0 : detailsEntity.mediaOptionDetails) === null || _a === void 0 ? void 0 : _a.mediaOptionId} updated`); + if (type === MediaOptionType.AltAudio && !rootPlaylistQuery.altMediaOptionHasValidUrl(type, option.mediaOptionId)) { + logger.info('manifest may have unused alternate audio options'); + return true; + } + const mediaOptionDetails = detailsEntity === null || detailsEntity === void 0 ? void 0 : detailsEntity.mediaOptionDetails; + // Old code tries to save effort by blocking variant if it has already loaded the last segment. + // but altAudio may backtrack to media.currentTime when user switches audio. + // In which case, hls needs both variant and altaudio to emit getDetailsAndSwitchContext @ media.currentTime + // const bufferedSegments = bufferInfoAction.bufferInfoTuple[type]?.bufferedSegments ?? []; + return (mediaOptionDetails != null && playlistIsValid(mediaOptionDetails, (_b = detailsEntity.lastUpdateMillis) !== null && _b !== void 0 ? _b : 0) + // && (!lastFragmentBuffered(mediaOptionDetails, bufferedSegments, rootPlaylistQuery.itemStartOffset, gaplessInstance.inGaplessMode)) + ); + }), take(1), withLatestFrom(rootPlaylistQuery.enabledMediaOptionSwitchContextsByType$(type)), map(([[, detailsEntity], switchContext]) => { + var _a, _b, _c; + const details = detailsEntity === null || detailsEntity === void 0 ? void 0 : detailsEntity.mediaOptionDetails; + if (details) { + const lastFrag = details.fragments[details.fragments.length - 1]; + logger.info(`${details.mediaOptionId} got details MSNs:[${details.startSN},${details.endSN}] range=[${(_b = (_a = details.fragments[0]) === null || _a === void 0 ? void 0 : _a.start) === null || _b === void 0 ? void 0 : _b.toFixed(3)},${(_c = ((lastFrag === null || lastFrag === void 0 ? void 0 : lastFrag.start) + (lastFrag === null || lastFrag === void 0 ? void 0 : lastFrag.duration))) === null || _c === void 0 ? void 0 : _c.toFixed(3)}]`); + } + return { detailsEntity, switchContext }; + })); + } + function chooseAndFetchFragments(logger, fragmentPicker, pipelineContext, action, detailsAndContext) { + var _a, _b; + const { mediaSink, iframeMachine, rootPlaylistQuery } = pipelineContext; + const detailsTuple = [detailsAndContext[MediaOptionType.Variant].detailsEntity.mediaOptionDetails, (_b = (_a = detailsAndContext[MediaOptionType.AltAudio]) === null || _a === void 0 ? void 0 : _a.detailsEntity) === null || _b === void 0 ? void 0 : _b.mediaOptionDetails]; + let chosenFrags = fragmentPicker.getNextFragments(action, detailsTuple, logger); + logger.info(`chosen frags=${JSON.stringify(chosenFrags.map((x) => { + var _a; + return ({ + foundFrag: fragPrint((_a = x === null || x === void 0 ? void 0 : x.foundFrag) === null || _a === void 0 ? void 0 : _a.mediaFragment), + nextDisco: x === null || x === void 0 ? void 0 : x.nextDisco, + newMediaRootTime: x === null || x === void 0 ? void 0 : x.newMediaRootTime, }); - let R = e.audioMediaSelectionGroup; - const L = null == R ? void 0 : R.MediaSelectionGroupOptions; - if (L) { - const e = L.reduce((e,t)=>(P.persistentIds.has(t.MediaSelectionOptionsPersistentID) && e.push(t), - e), new Array); - R = Object.assign(Object.assign({}, R), { - MediaSelectionGroupOptions: e - }) - } - h.mediaOptions = Fy(m, T, h.mediaOptions); - const _ = h.mediaOptions.reduce((e,t)=>(O.has(t.groupId) && (e.persistentIds.add(t.persistentID), - e.filteredSubtitleMediaOptions.push(t)), - e), { - filteredSubtitleMediaOptions: [], - persistentIds: new Set - }); - let N = e.subtitleMediaSelectionGroup; - const F = null == N ? void 0 : N.MediaSelectionGroupOptions; - if (F) { - const e = F.reduce((e,t)=>(_.persistentIds.has(t.MediaSelectionOptionsPersistentID) && e.push(t), - e), new Array); - N = Object.assign(Object.assign({}, N), { - MediaSelectionGroupOptions: e - }) - } - i = [D, x, h]; - let B = new Map; - ng().useHighestVideoCodecPrivate && (B = null == D ? void 0 : D.mediaOptions.reduce((e,t)=>{ - const i = t.videoCodecList; - if (i) - for (const t of i) { - const i = Vp(t) - , r = e.get(i); - Se.isHigherCodecByFamily(r, t) && e.set(i, t) - } - return e - } - , B)), - B.size && B.forEach((e,t)=>{} - ); - t = { - fragDownloadSlow: !1, - fragDownloadTooSlow: !1, - nextMinAutoOptionId: Ol.mediaOptionId, - nextMaxAutoOptionId: Ol.mediaOptionId, - highBWTrigger: Vg(v.mediaOptionId, D.mediaOptions) - }; - return Object.assign(Object.assign({}, e), { - enabledMediaOptionKeys: [v, b, I], - mediaOptionListTuple: i, - audioMediaSelectionGroup: R, - abrStatus: t, - highestVideoCodec: B - }) - } - const Uy = (o,d,l,u,c,h,p)=>e=>e.pipe(Ql.tag("retrieveRootMediaOptions.input"), Ra(t=>{ - var e; - if (!t) - return Ti; - const {itemId: i, platformInfo: r} = t - , n = Ly(i) - , s = d["logger"]; - if (n.hasEntity(i)) - return Bi(n); - xy.setLoading(!0); - const a = performance.now(); - return function(e, t, u, c, i) { - const {itemId: h, url: p, itemStartOffset: f} = e - , r = xc(e, t); - return km({ - url: p, - onProgress: { - getData: !0, - cb: my - }, - xhrSetup: c.xhrSetup - }, r, i).pipe(ur(({responseText: e, stats: t})=>{ - var i = c["keySystemPreference"]; - if (Om.isMediaPlaylist(e)) { - const c = "media-pl-" + Jd() - , d = Om.parseMediaOptionPlaylist(e, p, !0, i, {}, h, c, ul.Variant, u, f); - Lc(d.mediaOptionDetails); - var r = { - itemId: h, - mediaOptionId: c, - mediaOptionType: ul.Variant, - url: p, - bandwidth: 0, - bitrate: 0, - iframes: d.mediaOptionDetails.iframesOnly, - pathwayID: "." - }; - return { - itemId: h, - itemStartOffset: f, - rootMediaOptionsTuple: [[r], [], []], - stats: t, - baseUrl: p, - initialDetails: d.mediaOptionDetails, - isMediaPlaylist: !0 - } - } - { - const u = Om.parseSessionData(e, p) - , c = Om.parseSessionKeys(e, p, i) - , l = Om.parseRootPlaylist(h, e, p, !0); - if (l.playlistParsingError) - throw l.playlistParsingError; - var {variantMediaOptions: n, contentSteeringOption: s, masterVariableList: a} = l - , o = Om.parseRootPlaylistAlternateMediaOptions(h, e, p, l.variantMediaOptions, !0, a); - if (o.playlistParsingError) - throw o.playlistParsingError; - var {audioAlternateOptions: r, subtitleAlternateOptions: i, audioMediaSelectionGroup: e, subtitleMediaSelectionGroup: o} = o.alternateMediaInfo; - return { - itemId: h, - itemStartOffset: f, - rootMediaOptionsTuple: [n, r, i], - stats: t, - baseUrl: p, - audioMediaSelectionGroup: e, - subtitleMediaSelectionGroup: o, - contentSteeringOption: s, - sessionData: u, - sessionKeys: c, - masterVariableList: a - } - } - } - ), e=>e.pipe(Un(e=>{ - if (e instanceof ou) - throw new ru(!1,"Timeout",0,$.ManifestTimeoutError,!0); - if (e instanceof tu) - throw new ru(!1,e.message,e.code,{ - code: e.code, - text: "Manifest network error" - },!1); - throw e - } - ))) - }(t, o, s, l, null === (e = null === (e = rg()) || void 0 === e ? void 0 : e.getQuery()) || void 0 === e ? void 0 : e.extendMaxTTFB).pipe(Ja(e=>p.triggerManifestLoaded(e)), Ja(({initialDetails: e, stats: t})=>{ - e && (e = e, - t = t, - Sg().archiveMediaOptionDetails(e, t, !0)) - } - ), So(u.displaySupportsHdr$), Ra(([e,t])=>_y(e, r, l, t, s)), ur(e=>(d.rootPlaylistEntity = function(e, t, i, r, n, s) { - const {itemId: a, initialSeekTime: o} = e - , d = Qf(a) - , l = n.enableAdaptiveStartup ? d.getBandwidthEstimate(n, e.serviceName) : void 0 - , u = n.enableAdaptiveStartup ? d.getPlaylistEstimate(n, e.serviceName) : void 0 - , c = n.enableAdaptiveStartup ? d.getFragEstimate(n, e.serviceName) : void 0 - , h = n.enableAdaptiveStartup ? d.getBufferEstimate(n, e.serviceName) : void 0 - , p = n.targetStartupMs - (performance.now() - r) - , f = n.enableAdaptiveStartup ? { - targetDuration: c.maxDurationSec || n.defaultTargetDuration, - targetStartupMs: p - } : void 0 - , m = By(t, i, s, l, f, u, c, h); - return m.pendingSeek = o, - m - }(t, e, c, a, l, s), - n)), Ym(i, null, xc(t, o), 0, !1, n, d, h), $s(()=>{ - xy.setLoading(!1) - } - )) - } - ), Ql.tag("retrieveRootMediaOptions.emit")); - function $y(t, o, d, l, u, c, h) { - return e=>e.pipe(Up(), Ra(e=>{ - return e ? Cr([Bi(e).pipe(Uy(t.manifestLoadPolicy, d, t, l, null, u, c)), (n = t, - s = o, - a = h.mux, - new Ut(e=>{ - const t = new py(n,s,a); - return e.next(t), - ()=>{ - t.destroy() - } - } - )), (i = t.trickPlaybackConfig, - r = o, - new Ut(e=>{ - var t = new ql(i,r); - return e.next(t), - ()=>{} - } - ))]).pipe(ur(([e,t,i])=>({ - rootPlaylistQuery: e, - mediaParser: t, - iframeMachine: i - }))) : Bi(null); - var i, r, n, s, a - } - )) - } - Ec; - return class Vy extends Ec { - constructor(e={}, t) { - var i; - if (super(), - this.destroy$ = new zt, - this.mediaElement$ = new gi(null), - this.encryptedMediaElement$ = new gi(null), - this.publicQueriesInternal$ = new gi(null), - this.mediaElementAdapter = null, - this.rpcService = null, - this.rpcClients = null, - this.platformService = bf(), - this.keySystemAdapter = null, - this.legibleSystemAdapter = null, - this.sessionID = Jd(), - this.statsService = (qf = qf || new Hf(jf), - qf), - this.gaplessCapable = !0, - this.teardownWorker$ = new Xf, - this.itemQueue = new Yg, - (e.liveSyncDurationCount || e.liveMaxLatencyDurationCount) && (e.liveSyncDuration || e.liveMaxLatencyDuration)) - throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration"); - const f = Object.assign(Object.assign({}, Al), e); - i = (this.hlsConfig = f).buildType, - ae = "production" === i; - const r = this.sessionID; - let n = "silent"; - e.debug && (n = f.debugLevel), - this.logger = null !== (i = this.logger) && void 0 !== i ? i : ([M,h={}] = [r, (c = { - sendLogs: e.sendLogs, - level: "log" === n ? "debug" : n, - consoleOverride: "boolean" != typeof e.debug ? e.debug : void 0, - buildType: f.buildType - }, - P = c.consoleOverride, - Object.assign({ - name: "hls", - timestamp: c.sendLogs ? Ae.stdTimeFunctions.epochTime : Ae.stdTimeFunctions.isoTime, - browser: { - asObject: !0, - serialize: !0, - transmit: { - send: (e,t)=>{} - }, - write: { - debug: Ke.bind(null, Ve(P || console, "debug"), "debug"), - info: Ke.bind(null, Ve(P || console, "info"), "info"), - warn: Ke.bind(null, Ve(P || console, "warn"), "warn"), - error: Ke.bind(null, Ve(P || console, "error"), "error"), - fatal: Ke.bind(null, Ve(P || console, "error"), "fatal") - } - } - }, c))], - Be && Be.sessionId === M ? Be.warn("Logger Singleton already setup, returning existing singleton") : (Be = Ae(Ue(h)).child({ - sessionId: M, - name: "hls" - }), - Be.qe = e=>Be.info(e), - Be.sessionId = M), - Be), - Lo = !1, - Ro && (delete window.$$stores, - delete window.$$queries), - this.hlsConfig.audioPrimingDelay = 0, - this.rootPlaylistService = (P = this.logger, - Ry = new Py(xy,P), - Ry), - this.customUrlLoader = Mc(), - this.sessionDataLoader = new _p(f,Oc,this.customUrlLoader.load,this.logger); - var s, a, o, d, l, u, c = f.liveMaxLatencyDurationCount, h = f.liveSyncDurationCount; - if (ne(c) && ne(h) && c <= h) - throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be gt "liveSyncDurationCount"'); - if (ne(f.liveMaxLatencyDuration) && (f.liveMaxLatencyDuration <= f.liveSyncDuration || !ne(f.liveSyncDuration))) - throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be gt "liveSyncDuration"'); - const p = rg(); - p.setHlsEntity({ - id: r, - config: f - }); - const m = Sg() - , g = new gf(vf) - , y = (Ph = Ph || new Dh(Mh), - Ph); - this.accessLogInstance = new Yf(this,r), - this.rtcService = new _f(this,f,this.accessLogInstance,this.logger), - this.playerEvents = new kg(this,this.logger,this.rtcService); - const v = (M = this.platformService, - u = M, - (()=>{ - if ("function" == typeof matchMedia) { - var e = matchMedia("(dynamic-range: high)") - , t = matchMedia("bad query"); - if (e.media !== t.media) - return nn(Bi(e), en(e, "change")).pipe(ur(e=>e.matches)) - } - return Bi(!0) - } - )().pipe(Ja(e=>{ - u.updateSupportsHdr(e) - } - )).pipe(Ua(Ti))) - , S = this.mediaElement$.pipe((s = f, - o = (a = this).logger, - d = this.teardownWorker$, - l = this.rtcService, - e=>e.pipe(Ql.tag("playback.mediaElementServiceEpic.in"), Ra(e=>{ - if (!e) - return Bi(null); - const t = new hf(e,mf,s,a,o,d,l); - return t.openMediaSource(new MediaSource), - nn(Bi(t), t) - } - ), Ql.tag("playback.mediaElementServiceEpic.emit"))), wa()) - , b = this.itemQueue.activeItemById$.pipe(Ra(e=>e ? Wf(f, this.statsService, e, this.logger) : Ti)); - this.rpcService = (()=>{ - let e = f.createRPCService; - return f.enableWorker && null == e && (e = Cf), - null == e && (e = Of), - e(this.logger) - } - )(), - this.rpcClients = (P = this.rpcService, - { - crypto: new Ef(P), - mux: new If(P) - }); - var T, E, I, w, A, O, k, C, D, c = Cr([this.itemQueue.activeItemById$.pipe($y(f, this.logger, this.rootPlaylistService, g, this.statsService, this.playerEvents, this.rpcClients), Ja(e=>{ - var t = null == e ? void 0 : e.rootPlaylistQuery; - this.publicQueriesInternal$.next([t, null]), - this.iframeMachine = null == e ? void 0 : e.iframeMachine, - t && this.playerEvents.triggerManifestParsed(t) - } - )), S.pipe((I = this.itemQueue.removedItems$, - w = y, - A = f, - O = g, - C = (k = this).rtcService, - D = this.logger, - e=>Cr([((n,s,a,o,d,l,u)=>e.pipe(Ql.tag("[Keys] playback.keySystemServiceEpic.in"), Ra(r=>r ? new Ut(e=>{ - let t = new kh(n,r,a,o,d,l,u); - const i = nn(Bi(t), s.pipe(Kr(e=>t.removeKeysForItems(e)), Ua(Ti))).subscribe(e); - return function() { - u.warn("[Keys] playback.keySystemServiceEpic.unsubscribe"), - i.unsubscribe(), - t.destroy().subscribe(), - t = void 0 - } - } - ) : Bi(null)), Ql.tag("[Keys] playback.keySystemServiceEpic.emit")))(w, I, A, O, k, C, D), ((t,i,r)=>e.pipe(Ql.tag("playback.legibleServiceEpic.in"), Ra(e=>e ? nn(Bi(e = new Rp(e,t,i,r)), e) : Bi(null)), Ql.tag("playback.legibleServiceEpic.emit")))(A, k, D), e]).pipe(ur(([e,t,i])=>({ - keySystemAdapter: e, - legibleSystemAdapter: t, - mediaSink: i - })))), Ja(({keySystemAdapter: e, legibleSystemAdapter: t, mediaSink: i})=>{ - this.keySystemAdapter = e, - this.legibleSystemAdapter = t, - this.mediaElementAdapter = i - } - ))]).pipe(ur(([e,t])=>{ - var {keySystemAdapter: i, legibleSystemAdapter: r, mediaSink: n} = t; - if (!(e && i && r && n)) - return null; - var {rootPlaylistQuery: s, iframeMachine: t, mediaParser: e} = e; - return { - logger: this.logger, - config: f, - platformService: this.platformService, - statsService: this.statsService, - rtcService: this.rtcService, - rpcClients: this.rpcClients, - rootPlaylistService: this.rootPlaylistService, - rootPlaylistQuery: s, - mediaLibraryService: m, - keySystemAdapter: i, - legibleSystemAdapter: r, - mediaSink: n, - mediaParser: e, - iframeMachine: t, - customUrlLoader: this.customUrlLoader, - gaplessInstance: this - } - } - ), wa()).pipe(Ra(a=>{ - if (!a) - return Ti; - const {rootPlaylistQuery: t, mediaSink: e, mediaLibraryService: i} = a; - this.publicQueriesInternal$.next([t, e.mediaQuery]); - const n = e.mediaQuery - , r = Bi(a).pipe(uy()) - , s = t.rootPlaylistEntity$.pipe(Up(), Cs(1), Ja(()=>{ - this.commitEarlySelection(a.logger) - } - )) - , o = $l(Cr([n.haveEnough$, t.sessionData$]), ([e])=>!0 === e, 1).pipe(Ra(([,e])=>this.sessionDataLoader.loadSessionData(e)), Ja(e=>{ - this.rootPlaylistService.setSessionData(t.itemId, e) - } - ), Un(e=>(this.logger.error(e.message), - Ti))) - , d = Qf(t.itemId) - , l = function(l, e, u, r, t) { - const a = u.mediaQuery - , i = Zd([a.seekTo$, a.bufferedSegmentsByType$(cl.Variant)]).pipe(ur(([e,t])=>{ - const i = ne(null == e ? void 0 : e.pos) ? e.pos : a.currentTime - , r = t.find(e=>e.startPTS <= i && e.endPTS > i) - , n = a.getBufferInfo(i, l.maxBufferHole) - , s = a.getCombinedBufferInfo(i, l.maxBufferHole); - return { - pos: i, - sbTuple: n, - combined: s, - playingFrag: null !== (t = null == r ? void 0 : r.frag) && void 0 !== t ? t : null - } - } - )) - , n = Zd([e.getInFlightFragByType$(ul.Variant), e.enabledMediaOptionByType$(ul.Variant)]).pipe(Ra(([e,t])=>{ - var i = r.getQueryForOption(t); - return bn(Bi(e), Bi(t), i.mediaOptionDetails$) - } - ), ur(([e,t,i])=>[e, { - variant: t, - details: i - }])) - , s = Zd([t.bandwidthEstimate$, t.fragEstimate$, t.bufferEstimate$]); - return Zd([a.readyState$, n, i, a.desiredRate$, s]).pipe(Hi(Zi), ur(([,e,t,i,r])=>{ - var [n,s] = e - , [a,e,r] = r; - let o = e - , d = r; - return e && (o = { - maxDurationSec: ne(e.maxDurationSec) ? e.maxDurationSec : l.defaultTargetDuration, - avgParseTimeMs: ne(e.avgParseTimeMs) ? e.avgParseTimeMs : l.statDefaults.fragParseTimeMs - }), - r && (d = { - avgBufferCreateMs: ne(r.avgBufferCreateMs) ? r.avgBufferCreateMs : l.statDefaults.fragBufferCreationDelayMs, - avgInitFragAppendMs: ne(r.avgInitFragAppendMs) ? r.avgInitFragAppendMs : l.statDefaults.initFragAppendMs, - avgDataFragAppendMs: ne(r.avgDataFragAppendMs) ? r.avgDataFragAppendMs : l.statDefaults.dataFragAppendMs - }), - a = function(e, t, i, h, p, r, n, s) { - let a = function(e, t, i) { - const {pos: r, combined: n, playingFrag: s} = h; - if (0 === n.len) - return !1; - var a = 0 != p && 1 != p - , o = t.details - , d = o.fragments - , t = fy(o) - , i = Math.max(1, t * i); - let l = a || n.len >= t || n.len >= i; - a = d[o.fragments.length - 1], - i = d[0].start + o.totalduration; - let u = !1; - if (s) { - const c = _l.search(d, e=>s.discoSeqNum - e.discoSeqNum); - u = e && s.discoSeqNum !== e.discoSeqNum || null == c || Fp(c, s) - } - return l && o.liveOrEvent ? l = r <= i - a.duration : o.liveOrEvent || (l = l || i - t <= r), - l = l || u, - l - }(t, i, e.startTargetDurationFactor); - var o = h.combined; - if (!a && 0 < o.len) { - const p = fy(i.details); - a = function(n, e, t, i, r, s, a) { - var o = null === (o = h.sbTuple[ul.Variant]) || void 0 === o ? void 0 : o.buffered; - if ((null == o ? void 0 : o.len) >= t) - return 0; - if (!o || !n || !(n.start + n.duration > o.end && (n.start - o.end <= a || n.start <= o.end))) - return 1 / 0; - o = n.state; - let d = n.tstart - , l = 0; - switch (o) { - case "loading": - l += function(e, t) { - var {bwSample: i, duration: r} = n; - return i ? (r = ne(i.total) ? 8 * i.total : Math.ceil(r * e), - e = 8 * i.loaded, - r -= e, - i = e / (performance.now() - i.tfirst) * 1e3, - t = t.avgBandwidth, - r / (ne(i) ? Math.min(t, i) : t)) : 1 / 0 - }(e, i), - d = n.tstart + 1e3 * l; - case "loaded": - case "parsing": - l += function(e, t) { - return t = ne(r.avgParseTimeMs) ? t.avgParseTimeMs : 0, - performance.now() < e ? t / 1e3 : Math.max(0, t - (performance.now() - e)) / 1e3 - }(d, r), - d = n.tstart + 1e3 * l; - case "parsed": - case "appending": - l += function(e, t) { - return t = ne(s.avgDataFragAppendMs) ? t.avgDataFragAppendMs : 0, - performance.now() < e ? t / 1e3 : Math.max(0, t - (performance.now() - e)) / 1e3 - }(d, s); - break; - case "appended": - l = 0; - break; - default: - l = 1 / 0 - } - return l - }(t, i.variant.bitrate, p, r, n, s, e.maxBufferHole) <= o.len - } - return a - }(l, n, s, t, i, a, o, d), - u.haveEnough = a - } - ), ca(), Ra(([e,t])=>e !== t ? Bi(t) : Bi(t).pipe(ss(200))), Ja(e=>{} - ), Ua(Ti)) - }(f, (this.logger, - t), e, i, d) - , u = function() { - const {config: e, mediaSink: t, rootPlaylistQuery: i, mediaLibraryService: r, gaplessInstance: n} = a - , s = t.mediaQuery; - return Zd([i.enabledAVOptions$.pipe(Ra(e=>bn(...e.map(e=>kl(e) ? r.getQueryForOption(e).mediaOptionDetails$ : Bi(null))))), s.msReadyState$, s.updating$, s.isIframeRate$, s.isBufferedToEnd$(e.maxBufferHole, !n.inGaplessMode)]).pipe(Ql.tag("checkForEndOfStream"), an(([,e,t,i,r])=>"open" === e && !1 === t && !i && r), Ja(([e])=>{ - null != e[0] && e.every(e=>null == e || !1 === e.liveOrEvent && !1 === e.iframesOnly) && !n.inGaplessMode && t.endStream() - } - ), Ua(Ti)) - }() - , c = function() { - const {config: o, iframeMachine: d, mediaSink: t} = a - , l = t.mediaQuery; - return l.desiredRate$.pipe(Ra(a=>jp(a) ? vn(0, Math.abs(1e3 / a)).pipe(ur(()=>{ - let e = null; - const t = l.seekable; - if (!d.isStarted || t.length < 1) - return e; - var i = d.iframeClockTimeSeconds - , r = o.leftMediaTimeToAutoPause - , n = t.start(0) - , s = t.end(t.length - 1); - return 1 < a && s - i < r ? e = { - newRate: 0, - autoPausedRestartTime: s - r - } : a < 0 && i - n < a / -2 && (e = { - newRate: 1, - autoPausedRestartTime: n - }), - e - } - ), Up(), Ja(e=>{ - t.desiredRate = e.newRate, - t.autoPausedRestartTime = e.autoPausedRestartTime - } - ), Ua(Ti)) : Ti)) - }() - , h = (t=>{ - const {mediaSink: e, config: i} = t - , r = e.mediaQuery; - return !0 !== i.enableIFramePreloading ? Ti : r.desiredRate$.pipe(ur(jp), Es(), Ra(e=>e ? Ti : function(r) { - const {mediaSink: e, rootPlaylistQuery: n, mediaLibraryService: s, logger: a, config: o} = r - , d = e.mediaQuery; - return d.waterLevelChangedForType$(cl.Variant).pipe(an(e=>e === kp.AboveHighWater), Ls(()=>n.enabledMediaOptionByType$(ul.Variant).pipe(Ra(e=>{ - var t = n.mediaOptionListQueries[ul.Variant].hasIframes - , i = null !== (i = null === (i = s.getQuery().getEntity(n.itemId)) || void 0 === i ? void 0 : i.liveOrEvent) && void 0 !== i && i; - return !t || i ? Ti : (i = Qf(n.itemId), - e = bg(e), - i = Ng(!0, o, n, e, d, i, a), - i = n.variantMediaOptionById(i.variantMediaOption), - Tg(r, i)) - } - ), Ra(e=>{ - var t = fg(d.currentTime, n.discoSeqNum, 0, e, []); - return null !== (e = null == t ? void 0 : t.foundFrag) && void 0 !== e && e.mediaFragment ? (t = t.foundFrag.mediaFragment, - nn(Og(r, t.keyTagInfo, { - itemId: t.itemId, - mediaOptionId: t.mediaOptionId - }), Eg(r, t))) : (a.warn(Wg, "Unable to find fragment for iframe prefetch"), - Ti) - } - ), Cs(1), Ua(Ti), Un(e=>(a.error(Wg, `got error ${e.message} in prefetch`), - Ti)), $s(()=>{} - )))) - }(t))) - } - )(a) - , p = [s, r, o, l, $l(Zd([n.gotPlaying$, n.gotLoadStart$, n.readyState$]), ([e,t,i])=>!0 === e || !0 === t || 1 <= i).pipe(Ra(()=>n.ended$), Ra(e=>vn(0, e ? void 0 : 1e3)), Ja(()=>{ - this.playbackInfo(f, n) - } - )), c, h, n.timeupdate$.pipe(ur(e=>{ - if (this.inGaplessMode && this.isPreloading && ne(this.loadingItem.itemStartOffset) && e >= this.loadingItem.itemStartOffset) { - const e = this.itemQueue.playingItem.itemId - , t = this.itemQueue.loadingItem.itemId - , i = { - prevItemId: e, - nextItemId: t, - nextStartTime: this.loadingItem.itemStartOffset, - nextDuration: n.msDuration - this.loadingItem.itemStartOffset - }; - this.itemQueue.updatePlayingItemId(), - this.trigger(x.ITEM_TRANSITIONED, i), - this.rtcService.itemTransitioned(e, t) - } - } - )), this.updateLiveSeekableRange(t, e), u]; - if (f.enablePerformanceLogging) { - const a = bn(...Ml.map(r=>t.getInFlightFragByType$(r).pipe(Up(), Es((e,t)=>e.state === t.state), So(n.bufferedRangeTuple$), Ja(([e,t])=>{ - const i = Object.assign(Object.assign({}, e), { - name: Cl[r], - buffered: void 0 - }); - "appended" === e.state && (i.buffered = t) - } - )))); - p.push(a) - } - return nn(...p) - } - )), h = this.itemQueue.removedItems$.pipe(od(e=>{ - var t; - t = e, - Sg().remove(t), - this.rootPlaylistService.removeItems(e) - } - )), M = p.getQuery().userSeek$.pipe((T = this.itemQueue, - E = this.rootPlaylistService, - e=>e.pipe(Up(), Ra(e=>Jr([Bi(e), T.activeItemById$.pipe(Up(), Ra(e=>E.getQueryForId(e.itemId).rootPlaylistEntity$), Cs(1))])), ur(([e,t])=>(E.setPendingSeek(t.itemId, e), - e))))), P = p.getQuery().selectEntityAction(To.Add).pipe(Ja(()=>{ - this.logger.warn(`new Hls instance added while old one still active sessionId:${r}`) - } - )); - nn(S.pipe(Un(()=>Ti)), nn(v, M, b, h, c, this.teardownWorker$).pipe(Un(e=>this._handleError(e)))).pipe($s(()=>{ - var e, t; - try { - this.detachMedia(), - this.trigger(x.DESTROYING), - this.playerEvents.destroy(), - null === (e = this.accessLogInstance) || void 0 === e || e.destroy(), - null === (t = this.rtcService) || void 0 === t || t.destroy(), - Sg().clear(), - this.rootPlaylistService.removeAll(), - this.itemQueue.clearQueue(), - p.removeEntity(this.sessionID) - } catch (e) { - this.logger.error(`Got error in finalize ${e.message}`) - } - } - ), $a(hn(this.destroy$, P))).subscribe() - } - get publicQueries$() { - return this.publicQueriesInternal$.pipe(an(e=>Boolean(e) && Boolean(e[0]) && Boolean(e[1]))) - } - get _activeRootQuery() { - var e = this.publicQueriesInternal$.value; - return null !== (e = null == e ? void 0 : e[0]) && void 0 !== e ? e : null - } - get _mediaElementQuery() { - var e = this.publicQueriesInternal$.value; - return null !== (e = null == e ? void 0 : e[1]) && void 0 !== e ? e : null - } - static get version() { - return "2.141.1" - } - static get Events() { - return x - } - get Events() { - return Vy.Events - } - static get DefaultConfig() { - return de(Al) - } - get DefaultConfig() { - return Vy.DefaultConfig - } - static isSupported() { - try { - const e = window.MediaSource || window.WebKitMediaSource - , t = window.SourceBuffer || window.WebKitSourceBuffer - , i = e && "function" == typeof e.isTypeSupported && e.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"') - , r = !t || t.prototype && "function" == typeof t.prototype.appendBuffer && "function" == typeof t.prototype.remove; - return !!i && !!r - } catch (e) { - return !1 - } - } - commitEarlySelection(e) { - var t = this.itemQueue.earlyAudioSelection; - ne(t) && (this.audioSelectedPersistentID = t, - this.itemQueue.earlyAudioSelection = null), - ne(t = this.itemQueue.earlySubtitleSelection) && (this.subtitleSelectedPersistentID = t, - this.itemQueue.earlySubtitleSelection = null) - } - _handleError(i) { - var r; - try { - let t, e = i.message; - if (this.logger.error(`Got unhandled or fatal error ${e}`, i), - null === (r = this.rtcService) || void 0 === r || r.handleError(i), - t = i instanceof p ? i : new V(!0,i.message,$.InternalError), - t.fatal && this.isPreloading && (this.logger.warn("Fatal error seen while preloading, calling dequeueSource"), - this.dequeueSource("FatalErrorWhileLoading")), - t.fatal) { - let e = Ul; - if (this.mediaElementAdapter) { - const r = this.mediaElementAdapter.mediaQuery - , n = r.getCombinedBufferInfo(r.currentTime, 0); - 0 < (null == n ? void 0 : n.len) && (e = $l(this.mediaElementAdapter.mediaQuery.stallInfo$, e=>null != e).pipe(ur(()=>{} - ))) - } - return e.pipe(Ra(()=>(this.trigger(x.ERROR, t), - Ti))) - } - this.trigger(x.ERROR, t) - } catch (i) { - throw this.logger.error(`Error thrown inside _handleError ${i.message}`, i), - i - } - return Ti - } - updateLiveSeekableRange(e, t) { - return e.enabledMediaOptionByType$(ul.Variant).pipe(Ra(e=>{ - const t = bg(e); - let i = 0; - return t.mediaOptionDetailsEntity$.pipe(Up(), an(e=>{ - var t = null !== e.stats && !1 === e.detailsLoading && e.lastUpdateMillis > i; - return i = null !== (e = e.lastUpdateMillis) && void 0 !== e ? e : 0, - t - } - )) - } - ), Ra(e=>(0 === e.unchangedCount && (e.mediaOptionDetails.liveOrEvent ? t.updateLiveSeekableRange(e.mediaOptionDetails) : t.clearLiveSeekableRange()), - Ti))) - } - playbackInfo(i, r) { - const n = this.mediaElement$.getValue(); - if (n) { - const s = n.readyState >= n.HAVE_FUTURE_DATA - , a = { - readyToPlay: s, - playbackLikelyToKeepUp: r.haveEnough && s, - rate: n.playbackRate, - paused: n.paused, - position: n.currentTime, - duration: n.duration, - seekableTimeRanges: zf.timeRangeToArray(n.seekable), - loadedTimeRanges: zf.timeRangeToArray(n.buffered) - }; - let e = 0 - , t = 0; - if (zf.isHtmlVideoElement(n)) { - const o = n.getVideoPlaybackQuality; - if (o && typeof o == typeof Function) { - const o = n.getVideoPlaybackQuality(); - e = a.droppedVideoFrames = o.droppedVideoFrames, - a.corruptedVideoFrames = o.corruptedVideoFrames, - a.totalVideoFrames = o.totalVideoFrames, - t = a.totalVideoFrames - e - } - } else - zf.isWebkitMediaElement(n) && (e = a.droppedVideoFrames = n.webkitDroppedFrameCount, - t = a.decodedFrameCount = n.webkitDecodedFrameCount); - i.enablePerformanceLogging && r.getCombinedMediaSourceBufferInfo(i.maxBufferHole), - null === (i = this.rtcService) || void 0 === i || i.handlePlaybackInfo(e, t) - } - } - get currentItem() { - return this.isPreloading ? this.playingItem : this.itemQueue.activeItem - } - get realCurrentTime() { - var e, t = this._mediaElementQuery; - if (this.iframeMachine && this.iframeMachine.isStarted) { - const r = t.mediaElementDuration - , e = this.iframeMachine.iframeClockTimeSeconds; - return e > r ? r : e - } - let i = null !== (e = null == t ? void 0 : t.currentTime) && void 0 !== e ? e : NaN; - return ne(i) && ne(null === (e = this.playingItem) || void 0 === e ? void 0 : e.itemStartOffset) && (i -= this.playingItem.itemStartOffset), - i - } - set realCurrentTime(e) { - var t; - ne(null === (t = this.playingItem) || void 0 === t ? void 0 : t.itemStartOffset) && (e += this.playingItem.itemStartOffset), - this.seekTo = e - } - get bufferedDuration() { - var e; - const t = this._mediaElementQuery; - return null !== (e = null == t ? void 0 : t.getBufferedDuration()) && void 0 !== e ? e : 0 - } - get sessionData() { - var e = this._activeRootQuery; - return null == e ? void 0 : e.sessionData - } - get supportedFrameRates() { - const e = this.hlsConfig.trickPlaybackConfig.enabled - , t = [0, 1] - , i = this._activeRootQuery - , r = Sg().getQuery(); - return e && i && r.getEntity(i.itemId) && !1 === r.getEntity(i.itemId).liveOrEvent && t.push(8, 24, 48, 96), - t - } - loadSource(e, i, t) { - var r; - if ("playready" === this.config.keySystemPreference && !this.config.enablePlayReadyKeySystem) - throw new V(!0,"Playready key system is not supported now",$.UnsupportedKeySystemError); - if (!e || !e.trim().length) - throw new V(!0,"Empty loadSource url",$.EmptyLoadSourceError); - e = fl.buildAbsoluteURL(window.location.href, e, { - alwaysNormalize: !0 - }), - i && Object.keys(i).filter(e=>0 <= ["itemId", "streamID"].indexOf(e)).reduce((e,t)=>t in i ? Object.assign(e, { - [t]: i[t] - }) : e, {}), - null !== (r = null == i ? void 0 : i.appData) && void 0 !== r && r.reportingAgent && (this.reportingAgent = i.appData.reportingAgent), - null != i && i.userInfo && (this.userInfo = i.userInfo), - null === (r = this.accessLogInstance) || void 0 === r || r.setupReporter(i.appData), - null != i && i.platformInfo && this.platformService.updatePlatformInfo(i.platformInfo), - this.itemQueue.setQueueItem(`item:${null !== (r = null == i ? void 0 : i.itemId) && void 0 !== r ? r : Jd()}`, e, t, null == i ? void 0 : i.platformInfo, null === (t = null == i ? void 0 : i.appData) || void 0 === t ? void 0 : t.serviceName), - rg().setStartTime(void 0) - } - queueSource(e, t, i) { - var r; - null != t && t.userInfo && (this.userInfo = t.userInfo); - var n = null === (r = this._mediaElementQuery) || void 0 === r ? void 0 : r.getCombinedBufferInfo(null === (n = this._mediaElementQuery) || void 0 === n ? void 0 : n.currentTime, 0); - let s = 0; - n && (s = n.end), - this.itemQueue.addQueueItem(`item:${null !== (n = null == t ? void 0 : t.itemId) && void 0 !== n ? n : Jd()}`, e, i, null == t ? void 0 : t.platformInfo, s, null === (t = null == t ? void 0 : t.appData) || void 0 === t ? void 0 : t.serviceName) - } - dequeueSource(e="ApplicationInitiated") { - if (!this.isPreloading && "InvalidFormat" === e && this.isFirstItem) - return this.logger.error("First item has invalid format for gapless. Probably video. Disabling gapless."), - void (this.gaplessCapable = !1); - var t, i; - this.isPreloading ? (t = this.loadingItem.url, - i = this.loadingItem.itemId, - this.mediaElementAdapter.flushData(cl.Variant, this.loadingItem.itemStartOffset, 1 / 0), - this.mediaElementAdapter.msDuration = this.loadingItem.itemStartOffset, - this.itemQueue.resetLoadingItem(), - "InvalidFormat" !== e && "FatalErrorWhileLoading" !== e || (this.gaplessCapable = !1), - this.triggerItemEvicted({ - url: t, - itemId: i - }, e)) : this.logger.warn(`Nothing to dequeue, no item is preloading dequeue reason: ${e}`) - } - triggerItemEvicted(e, t) { - null !== e ? (t = { - url: e.url, - evictedItemId: e.itemId, - reason: t - }, - Object.assign(Object.assign({}, t), { - url: oe(e.url) - }), - this.trigger(x.ITEM_EVICTED, t)) : this.logger.error("dequeueSource called with no playing or loading item") - } - endSource() { - this.gaplessCapable = !1, - this.isPreloading && (this.logger.warn("EndSource called during preloading. Loading item will be removed"), - this.mediaElementAdapter.flushData(cl.Variant, this.loadingItem.itemStartOffset, 1 / 0), - this.mediaElementAdapter.msDuration = this.loadingItem.itemStartOffset, - this.itemQueue.resetLoadingItem()) - } - get inGaplessMode() { - return this.config.gapless && this.gaplessCapable - } - get isPreloading() { - return this.itemQueue.isPreloading() - } - get isFirstItem() { - return this.itemQueue.isFirstItem - } - get loadingItem() { - return this.itemQueue.loadingItem - } - get playingItem() { - return this.itemQueue.playingItem - } - get url() { - return this.playingItem ? this.playingItem.url : this.loadingItem ? this.loadingItem.url : void 0 - } - destroy() { - var e; - return this.destroy$.next(), - null != this.rpcService && this.rpcService.teardown(), - null !== (e = this.encryptedMediaElement$.getValue()) && void 0 !== e && e.updating ? this.encryptedMediaElement$.getValue().done$.pipe(an(e=>e), Cs(2), Ra(e=>(this.encryptedMediaElement$.next(null), - this.teardownWorker$.complete(), - this.teardownWorker$))) : (this.encryptedMediaElement$.next(null), - this.teardownWorker$.complete(), - this.teardownWorker$) - } - attachMedia(e) { - this.trigger(x.MEDIA_ATTACHING, { - media: e - }), - this.mediaElement$.next(e), - this.encryptedMediaElement$.next(e), - this.trigger(x.MEDIA_ATTACHED, { - media: e - }) - } - detachMedia() { - var e; - this.mediaElement$.getValue() && (this.trigger(x.MEDIA_DETACHING), - null === (e = this.rtcService) || void 0 === e || e.detachMedia(), - this.mediaElement$.next(null), - this.trigger(x.MEDIA_DETACHED)) - } - handleResolvedUri(e, t) { - this.customUrlLoader.setCustomUrlResponse(e, { - uri: t.uri, - response: t - }) - } - get variantOptions$() { - return this.publicQueries$.pipe(Ra(e=>{ - const [t,i] = e; - return Cr([t.preferredMediaOptions$, i.desiredRate$]).pipe(ur(([e])=>{ - const t = i.isIframeRate; - return e[ul.Variant].filter(e=>(null !== (e = e.iframes) && void 0 !== e && e) === t).map(e=>e.mediaOptionId) - } - )) - } - )) - } - get altAudioOptions$() { - return this.publicQueries$.pipe(Ra(e=>{ - var [e] = e; - return Bi(e.audioMediaSelectionOptions) - } - )) - } - get subtitleOptions$() { - return this.publicQueries$.pipe(Ra(e=>{ - var [e] = e; - return Bi([{ - MediaSelectionOptionsName: "Disable subtitle", - MediaSelectionOptionsPersistentID: -1 - }].concat(e.subtitleMediaSelectionOptions)) - } - )) - } - get levels() { - var e; - return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.preferredMediaOptions[ul.Variant]) && void 0 !== e ? e : [] - } - get audioTracks() { - var e; - return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.preferredMediaOptions[ul.AltAudio]) && void 0 !== e ? e : [] - } - get audioMediaOptions() { - var e; - return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.audioMediaSelectionOptions) && void 0 !== e ? e : [] - } - get subtitleMediaOptions() { - var e; - return null !== (e = null === (e = this._activeRootQuery) || void 0 === e ? void 0 : e.subtitleMediaSelectionOptions) && void 0 !== e ? e : [] - } - get playbackLikelyToKeepUp() { - var e; - return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.playbackLikelyToKeepUp) && void 0 !== e && e - } - get duration$() { - return this.publicQueries$.pipe(Ra(e=>{ - var [,e] = e; - return e.mediaElementDuration$ - } - )) - } - get timeupdate$() { - return this.publicQueries$.pipe(Ra(e=>{ - var [,e] = e; - return e.timeupdate$ - } - )) - } - get playing$() { - return this.publicQueries$.pipe(Ra(e=>{ - var [,e] = e; - return e.gotPlaying$ - } - )) - } - get desiredRate$() { - return this.publicQueries$.pipe(Ra(e=>{ - var [,e] = e; - return e.desiredRate$ - } - )) - } - set desiredRate(e) { - null != e && this.setRate(e) - } - get desiredRate() { - var e; - return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.desiredRate) && void 0 !== e ? e : 0 - } - get effectiveRate() { - var e; - return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.effectiveRate) && void 0 !== e ? e : 0 - } - get iframeMode() { - var e; - return null !== (e = null === (e = this._mediaElementQuery) || void 0 === e ? void 0 : e.isIframeRate) && void 0 !== e && e - } - get accessLog() { - return this.accessLogInstance && this._activeRootQuery ? this.accessLogInstance.getAccessLog(this._activeRootQuery.itemId) : [] - } - get errorLog() { - return this.accessLogInstance ? this.accessLogInstance.errorLog : [] - } - setRate(e) { - const t = this.logger.child({ - name: "iframes" - }); - if (e === this.desiredRate) - return -2; - if (!this.mediaElementAdapter || isNaN(e)) - return t.warn("unable to switch to rate, missing adapter or newRate isNaN"), - -1; - e = Number(e); - const i = Math.abs(e); - if (!this.supportedFrameRates.some(e=>e === i)) - return t.warn(`unsupported rate(${e})`), - -3; - if (jp(e)) { - const e = this._activeRootQuery; - if (null == e || !e.mediaOptionListQueries[ul.Variant].hasIframes) - return t.warn("no iframe variants available"), - -1 - } - return this.mediaElementAdapter.desiredRate = e, - 0 - } - get sessionData$() { - return this.publicQueries$.pipe(Ra(([e])=>e.sessionData$)) - } - set skip(e) { - this.mediaElementAdapter.skip = e - } - gaplessSeekTo(e) { - e < this.playingItem.itemStartOffset && (this.logger.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${this.playingItem.itemStartOffset}`), - e = this.playingItem.itemStartOffset), - this.isPreloading && (e > this.loadingItem.itemStartOffset && (this.logger.warn(`[Gapless] Seeking past track boundary oldSeek=${e}, adjustedSeek=${this.loadingItem.itemStartOffset}`), - e = this.loadingItem.itemStartOffset), - e < this._mediaElementQuery.getBufferInfo(this._mediaElementQuery.currentTime, this.config.maxBufferHole)[0].buffered.start && this.dequeueSource("SeekToUnbufferedTimeRanges")), - rg().setUserSeek(e) - } - set seekTo(e) { - var t = Number(e); - ne(t) ? this.inGaplessMode ? this.gaplessSeekTo(t) : rg().setUserSeek(t) : this.logger.error(`[seek] got invalid seek value ${e}`) - } - seekToDate(e) { - rg().setUserSeek(e) - } - get availableProgramDateTime() { - return new Map(this._currentDateToMediaTimeTuple) - } - get _currentDateToMediaTimeTuple() { - if (!this._activeRootQuery) - return []; - var e = this._activeRootQuery.enabledMediaOptionKeys[ul.Variant]; - return kl(e) && null !== (e = null === (e = Sg().getQueryForOption(e).mediaOptionDetails) || void 0 === e ? void 0 : e.dateMediaTimePairs) && void 0 !== e ? e : [] - } - get playingDate() { - return ey(this._currentDateToMediaTimeTuple, this.realCurrentTime) - } - set variantId(e) {} - set audioSelectedPersistentID(e) { - var t = this._activeRootQuery; - null != t && t.preferredMediaOptions[ul.AltAudio] ? (t = t.itemId, - this.rootPlaylistService.setEnabledMediaOptionTupleWithMatchedGroups(t, ul.AltAudio, e, { - userInitiated: !0 - })) : !ne(e) || e < 0 || (this.logger.warn(`[audio] no active item, defer audio track selection: persistentId ${e}`), - this.itemQueue.earlyAudioSelection = e) - } - get audioSelectedPersistentID() { - var e; - return this._activeRootQuery ? null === (e = this._activeRootQuery.enabledAlternateMediaOptionByType(ul.AltAudio)) || void 0 === e ? void 0 : e.persistentID : this.itemQueue.earlyAudioSelection - } - set subtitleSelectedPersistentID(e) { - var t = this._activeRootQuery - , i = null == t ? void 0 : t.preferredMediaOptions[ul.Subtitle]; - i ? (t = t.itemId, - 0 === i.length && (!ne(e) || e < 0) || (ne(e) && -1 !== e ? this.rootPlaylistService.setEnabledMediaOptionTupleWithMatchedGroups(t, ul.Subtitle, e) : this.rootPlaylistService.setEnabledMediaOptionByType(t, ul.Subtitle, Ol))) : !ne(e) || e < 0 || (this.logger.warn(`[subtitle] no active item, defer subtitle track selection: persistentId ${e}`), - this.itemQueue.earlySubtitleSelection = e) - } - get subtitleSelectedPersistentID() { - var e; - return this._activeRootQuery ? null === (e = this._activeRootQuery.enabledAlternateMediaOptionByType(ul.Subtitle)) || void 0 === e ? void 0 : e.persistentID : this.itemQueue.earlySubtitleSelection - } - get selectedMediaArray() { - const e = this._activeRootQuery; - if (!e) - return []; - const t = [] - , i = e.enabledAlternateMediaOptionByType(ul.AltAudio) - , r = e.enabledAlternateMediaOptionByType(ul.Subtitle) - , n = i ? e.audioMediaSelectionOptions.find(e=>e.MediaSelectionOptionsPersistentID === i.persistentID) : void 0 - , s = r ? e.subtitleMediaSelectionOptions.find(e=>e.MediaSelectionOptionsPersistentID === r.persistentID) : void 0; - if (n) { - const e = { - MediaSelectionGroupMediaType: pl.AUDIO, - MediaSelectionOptionsPersistentID: n.MediaSelectionOptionsPersistentID - }; - t.push(e) - } - if (s) { - let e = hl.NO; - s.MediaSelectionOptionsDisplaysNonForcedSubtitles && (e = s.MediaSelectionOptionsDisplaysNonForcedSubtitles); - const i = { - MediaSelectionGroupMediaType: pl.SUBTITLE, - MediaSelectionOptionsDisplaysNonForcedSubtitles: e, - MediaSelectionOptionsPersistentID: s.MediaSelectionOptionsPersistentID - }; - t.push(i) - } - return t - } - set selectedMediaArray(e) { - this._activeRootQuery ? e.forEach(e=>{ - e.MediaSelectionGroupMediaType === pl.AUDIO || e.MediaSelectionOptionsMediaType === pl.AUDIO ? this.audioSelectedPersistentID = e.MediaSelectionOptionsPersistentID : e.MediaSelectionGroupMediaType !== pl.SUBTITLE && e.MediaSelectionOptionsMediaType !== pl.SUBTITLE && e.MediaSelectionOptionsMediaType !== pl.CLOSEDCAPTION || (this.subtitleSelectedPersistentID = e.MediaSelectionOptionsPersistentID) - } - ) : this.logger.warn("selectedMediaArray: no active item") - } - getHTMLTextTrack(e) { - return this.legibleSystemAdapter.getExistingHTMLTextTrackWithSubtitleTrackId(e) - } - get keysystems() { - return this.keySystemAdapter.availableKeySystems - } - setProtectionData(e) { - this.keySystemAdapter.initialize(e) - } - generateKeyRequest(e, t) { - this.keySystemAdapter.generateRequest(e, t), - this.rtcService.licenseChallengeReceived({ - keyuri: e - }) - } - setLicenseResponse(e, t) { - this.keySystemAdapter.setLicenseResponse(e, t) - } - get bufferInfo$() { - return this.publicQueries$.pipe(Ra(e=>{ - const [,t] = e - , i = rg().getQuery().currentConfig; - return nn(t.timeupdate$, t.bufferedRangeTuple$).pipe(so(1e3), ur(()=>{ - var e = t.currentTime; - return { - combined: t.getCombinedBufferInfo(e, i.maxBufferHole), - sbTuple: t.getBufferInfo(e, i.maxBufferHole) - } - } - )) - } - )) - } - bufferInfoByType$(t) { - return this.bufferInfo$.pipe(ur(e=>null === (e = null == e ? void 0 : e.sbTuple) || void 0 === e ? void 0 : e[t])) - } - levelWithPersistentId(e) { - this.logger.warn("levelWithPersistentId is deprecated") - } - startLoad(e) { - this.logger.warn("startLoad is deprecated"), - ne(e) && (this.logger.warn(`[seek] Seeking to ${null == e ? void 0 : e.toFixed(3)} via deprecated "startLoad" method. Use loadSource(url, options, startTime) instead.`), - this.seekTo = e) - } - stopLoad() {} - get config() { - return Object.assign(Object.assign({}, de(ng())), { - set startPosition(e) { - qe().warn(`Setting start position ${null == e ? void 0 : e.toFixed(3)} using deprecated method`), - rg().setStartTime(e) - } - }) - } - get media() { - return null != this.mediaElement$.value - } - set subtitleDisplay(e) { - this.logger.warn(`set subtitleDisplay ${e} is deprecated`) - } - } - } - , - "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || jy).Hls = t() -}(!1); -//# sourceMappingURL=hls.js.map + }))}`); + const newMediaRootTime = chosenFrags.reduce((prev, cur) => { + return Math.max(prev, isFiniteNumber(cur === null || cur === void 0 ? void 0 : cur.newMediaRootTime) ? cur.newMediaRootTime : -Infinity); + }, -Infinity); + if (isFiniteNumber(newMediaRootTime)) { + logger.info(`seek to newMediaRootTime ${newMediaRootTime}`); + mediaSink.seekTo = newMediaRootTime; + chosenFrags = [null, null]; + } + if (chosenFrags.every((f) => (f === null || f === void 0 ? void 0 : f.foundFrag) == null)) { + return of(null); // no more to produce + } + return zip(...chosenFrags.map((f, type) => { + if (!f || f.foundFrag == null) { + return of(null); + } + else { + const { mediaFragment } = f.foundFrag; + const prefetchKey$ = loadKey(pipelineContext, mediaFragment.keyTagInfo, { itemId: mediaFragment.itemId, mediaOptionId: mediaFragment.mediaOptionId }); + let fetchAndParse$ = retrieveMediaFragmentCacheEntity(pipelineContext, type, f).pipe(tap((sbDataTuple) => { + var _a; + const mediaFragmentCacheEntity = sbDataTuple[1]; + const switchContext = detailsAndContext[type].switchContext; + mediaFragmentCacheEntity.switchPosition = switchContext === null || switchContext === void 0 ? void 0 : switchContext.switchPosition; + // if user initiated or rewind rate change + const userInitiated = (_a = switchContext === null || switchContext === void 0 ? void 0 : switchContext.userInitiated) !== null && _a !== void 0 ? _a : false; + const { mediaQuery } = mediaSink; + const { desiredRate, isIframeRate } = mediaQuery; + const rewindRateChange = isIframeRate && iframeMachine.isStarted && desiredRate && desiredRate < 0 && desiredRate !== iframeMachine.iframeRate; + if (userInitiated || rewindRateChange) { + logger.info(`creating flushBeforeAppend > userInitiated=${userInitiated}, rewindRateChange=${rewindRateChange} :: iframeMachine.isStarted=${iframeMachine.isStarted}, iframeMachine.iframeRate=${iframeMachine.iframeRate}, desiredRate=${desiredRate}`); + mediaFragmentCacheEntity.flushBeforeAppend = { start: 0, end: Number.POSITIVE_INFINITY }; + } + })); + // UpdatePTSDTS is expensive on startup + // try to parallelize with key request and/or fragment request + if (type === MediaOptionType.Variant) { + fetchAndParse$ = fetchAndParse$.pipe(tap((sbData) => { + const initPTSInfo = updateInitPTS(logger, pipelineContext, sbData, fragmentPicker.discoSeqNum); + updatePTSDTS(logger, pipelineContext, sbData, initPTSInfo); + })); + } + else { + const initPTSInfo$ = waitFor(rootPlaylistQuery.initPTS$(fragmentPicker.discoSeqNum), (initPTSInfo) => { + const iframeMode = mediaSink.mediaQuery.isIframeRate; + return initPTSInfo != null && (iframeMode || !initPTSInfo.iframeMode); + }); + fetchAndParse$ = forkJoin([fetchAndParse$, initPTSInfo$]).pipe(map(([sbData, initPTSInfo]) => { + updatePTSDTS(logger, pipelineContext, sbData, initPTSInfo); + return sbData; + })); + } + return forkJoin([prefetchKey$, fetchAndParse$]).pipe(map((res) => res[1])); + } + })).pipe(map((sbDataTuple) => getConsumerInput(logger, pipelineContext, fragmentPicker.discoSeqNum, sbDataTuple)), switchMap((consumerInput) => { + if (!consumerInput) { + // Potentially dangerous (unbounded loop) if we keep selecting the same fragment + logger.info('Attempting fragment reselection because of complete overlap with updated details'); + const updatedDetailsAndContext = getUpdatedDetailsAndContext(rootPlaylistQuery, detailsAndContext, logger); + return chooseAndFetchFragments(logger, fragmentPicker, pipelineContext, action, updatedDetailsAndContext); + } + return of(consumerInput); + })); + } + function getUpdatedDetailsAndContext(rootPlaylistQuery, detailsAndContext, logger) { + const enabledMediaKeys = rootPlaylistQuery.enabledMediaOptionKeys; + const updatedDetailsAndContext = [null, null]; + const detailsInfo = [null, null]; + AVMediaOptionTypes.map((type) => { + var _a, _b; + if (isEnabledMediaOption(enabledMediaKeys[type])) { + const libraryQuery = createMediaLibraryQuery(enabledMediaKeys[type]); + const detailsEntity = libraryQuery.mediaOptionDetailsEntity; + detailsInfo[type] = (_a = detailsEntity.mediaOptionDetails) === null || _a === void 0 ? void 0 : _a.ptsKnown; + updatedDetailsAndContext[type] = { detailsEntity, switchContext: (_b = detailsAndContext[type]) === null || _b === void 0 ? void 0 : _b.switchContext }; + } + }); + logger.info(`retrieve updated details entity ${JSON.stringify(detailsInfo)}`); + return updatedDetailsAndContext; + } + /** + * Update initPTS info + * @param vTuple the parsed fragment information for the variant + */ + function updateInitPTS(logger, pipelineContext, vTuple, activeDiscoSeqNum) { + var _a, _b, _c; + if (!vTuple) { + return null; + } + const { rootPlaylistService: rootService, rootPlaylistQuery: rootQuery } = pipelineContext; + const itemId = rootQuery.itemId; + const variantData = vTuple[1]; + const fragIsIframe = variantData.iframe; + // Favor non-iframe initPTS if available + let initPTSInfo = rootQuery.getInitPTS(activeDiscoSeqNum); + if (initPTSInfo == null || (!fragIsIframe && initPTSInfo.iframeMode)) { + const variantDTS = (_a = variantData.startDtsTs) !== null && _a !== void 0 ? _a : null; + if (variantDTS == null) { + logger.warn('updateInitPTS: Variant data missing.'); + return null; + } + let timelineOffset = (_b = variantData.timelineOffset) !== null && _b !== void 0 ? _b : 0; + if (fragIsIframe) { + logger.info(`updateInitPTS: initPTS timelineOffset is appendData iframeOriginalStart ${vTuple[1].iframeOriginalStart}`); + timelineOffset = (_c = variantData.iframeOriginalStart) !== null && _c !== void 0 ? _c : 0; + } + else { + logger.info(`updateInitPTS: initPTS timelineOffset is appendData timelineOffset ${vTuple[1].timelineOffset}`); + } + if (variantDTS.timescale < 1000) { + // this scaleup is especially useful when traversing 23.976/24 fps discos + variantDTS.timescale = variantDTS.timescale * 1000; + variantDTS.baseTime = variantDTS.baseTime * 1000; + } + const playlistTS = convertSecondsToTimestamp(timelineOffset, variantDTS.timescale); + const offsetTimestamp = { baseTime: variantDTS.baseTime - playlistTS.baseTime, timescale: variantDTS.timescale }; + logger.info(`initPTS[${activeDiscoSeqNum}] ${JSON.stringify({ variantDTS, timelineOffset, offsetTimestamp, fragIsIframe })}`); + rootService.setInitPTS(itemId, activeDiscoSeqNum, variantDTS, timelineOffset, offsetTimestamp, fragIsIframe); + initPTSInfo = { variantDTS, timelineOffset, offsetTimestamp, iframeMode: fragIsIframe }; + } + return initPTSInfo; + } + function updatePTSDTS(logger, pipelineContext, sbData, initPTSInfo) { + const { mediaLibraryService, rootPlaylistQuery, mediaSink } = pipelineContext; + const itemId = rootPlaylistQuery.itemId; + if (initPTSInfo == null) { + return; + } + // Don't update if we're in normal playback and we have an i-frame initPTS + const curIframeMode = mediaSink.mediaQuery.isIframeRate; + if (!curIframeMode && initPTSInfo.iframeMode) { + logger.warn('updatePTSDTS iframeMode mismatch'); + return; + } + // Update playlist offsets. Never update for main in i-frame mode + if (sbData && !isFiniteNumber(sbData[1].iframeMediaDuration)) { + const tstart = performance.now(); + mediaLibraryService.updatePTSDTS(itemId, sbData[1].mediaOptionId, initPTSInfo, sbData[1]); + logger.info(`updatePTSDTS took ${Math.round(performance.now() - tstart)}ms`); + } + } + function getConsumerInput(logger, pipelineContext, activeDiscoSeqNum, sbDataTuple) { + const { rootPlaylistQuery: rootQuery, mediaSink, config } = pipelineContext; + const mediaQuery = mediaSink.mediaQuery; + const iframeMode = mediaQuery.isIframeRate; + const initPTSInfo = rootQuery.getInitPTS(activeDiscoSeqNum); + if (initPTSInfo == null) { + logger.warn('No initPTS info found'); + return null; + } + const variantData = sbDataTuple[MediaOptionType.Variant]; + const variantFragData = variantData === null || variantData === void 0 ? void 0 : variantData[1]; + if (variantFragData && variantFragData.iframe !== iframeMode) { + logger.warn(`frag mediaSeqNum ${variantFragData.mediaSeqNum} discoSeqNum ${variantFragData.discoSeqNum} mediaOptionId ${variantFragData.mediaOptionId} doesn't match mediaSink's iframeMode ${iframeMode}; discard`); + return null; // repick frag since the parsed one doesn't match mediaSink's iframe mode + } + // Build output + const appendDataTuple = [null, null]; + if (variantData) { + const [initSeg, dataSeg] = variantData; + let offsetTimestamp = initPTSInfo.offsetTimestamp; + if (iframeMode) { + // Always offset video + const dts = dataSeg.startDtsTs; + const timelineOffset = dataSeg.timelineOffset; + const playlistTS = convertSecondsToTimestamp(timelineOffset, dts.timescale); + offsetTimestamp = { baseTime: dts.baseTime - playlistTS.baseTime, timescale: dts.timescale }; + } + appendDataTuple[SourceBufferType.Variant] = { initSeg, dataSeg, offsetTimestamp }; + } + const audioData = sbDataTuple[MediaOptionType.AltAudio]; + if (audioData != null) { + const [initSeg, dataSeg] = audioData; + appendDataTuple[SourceBufferType.AltAudio] = { initSeg, dataSeg, offsetTimestamp: initPTSInfo.offsetTimestamp }; + } + // Update in flight fragments + const inFlightFrags = appendDataTuple.map((data, type) => { + var _a, _b; + const dataSeg = data === null || data === void 0 ? void 0 : data.dataSeg; + if (dataSeg) { + const { itemId, mediaOptionId, mediaSeqNum, discoSeqNum, startPts, endPts, duration, iframe } = dataSeg; + const { offsetTimestamp } = data; + const startPTSSec = diffSeconds(startPts, offsetTimestamp); + const endPTSSec = diffSeconds(endPts, offsetTimestamp); + const libraryQuery = createMediaLibraryQuery(dataSeg); + logger.info(`${MediaOptionNames[type]} aboutToAppend iframe:${dataSeg.iframeMediaDuration != null} ${stringifyWithPrecision({ + mediaOptionId, + mediaSeqNum, + discoSeqNum, + offsetTimestamp, + startPTSSec, + endPTSSec, + startPts, + endPts, + })} buffered:${stringifyWithPrecision(mediaQuery.getBufferedRangeByType(type))}`); + const videoSegment = appendDataTuple[0]; + const noDroppedFrames = !videoSegment || !videoSegment.dataSeg.dropped; + if (noDroppedFrames && !dataSeg.flushBeforeAppend && ((_b = (_a = mediaQuery.getBufferInfo(startPTSSec, config.maxBufferHole)[type]) === null || _a === void 0 ? void 0 : _a.buffered) === null || _b === void 0 ? void 0 : _b.len) >= endPTSSec - startPTSSec) { + logger.warn(`${MediaOptionNames[type]} Discarding append due to complete overlap with existing buffer`); + appendDataTuple[type] = null; + return null; + } + return { + start: startPTSSec, + duration: iframe ? duration : endPTSSec - startPTSSec, + itemId, + mediaOptionId, + mediaSeqNum, + discoSeqNum, + targetDuration: libraryQuery.mediaOptionDetails.targetduration, + }; + } + return null; + }); + if (inFlightFrags.every((f) => !f)) { + return null; + } + return { appendDataTuple, inFlightFrags, initPTSInfo }; + } + /** + * @brief The media consumer side + * transform consumerInput to boolean indicating whether we actually appended anything + */ + const mediaConsumerEpic = (context) => (consumerInput) => { + const { rootPlaylistQuery: rootQuery, rootPlaylistService: rootService, mediaSink, legibleSystemAdapter, statsService, rtcService } = context; + return consumerInput.pipe(tag('mediaConsumerEpic.in'), + // Do Append + switchMap((appendData) => { + if (!appendData) { + return of(false); + } + const { appendDataTuple, inFlightFrags, initPTSInfo } = appendData; + const { offsetTimestamp } = initPTSInfo; + inFlightFrags.forEach((frag, type) => { + if (frag) { + rootService.updateInflightFrag(frag.itemId, type, frag, 'appending', null); + } + }); + // Pass rootQuery.itemStartOffset into appendData. + // add samples based on captiondata + appendDataTuple.forEach((sbAppendData) => { + if (sbAppendData) { + const dataSeg = sbAppendData.dataSeg; + legibleSystemAdapter.addLegibleSamples(offsetTimestamp, dataSeg.captionData, dataSeg.id3Samples, dataSeg.endPts); + } + }); + return mediaSink + .appendData(appendDataTuple, (sbAdapter, mediaOptionType, mediaOptionId, config, meQuery) => { + var _a; + const targetDuration = (_a = inFlightFrags[mediaOptionType].targetDuration) !== null && _a !== void 0 ? _a : 10; + return addAppendErrorHandlingPolicy(mediaSink, sbAdapter, mediaOptionType, mediaOptionId, targetDuration, config, rootQuery, rootService, meQuery); + }, rootQuery.highestVideoCodec) + .pipe(map((metrics) => { + var _a, _b; + inFlightFrags.forEach((frag, type) => { + if (frag) { + rootService.updateInflightFrag(frag.itemId, type, frag, 'appended', null); + } + }); + const metric = metrics.filter((metric) => (metric === null || metric === void 0 ? void 0 : metric.fragmentType) === MediaOptionType.Variant); + if (metric.length) { + statsService.setBufferMetric(metric[0]); + rtcService === null || rtcService === void 0 ? void 0 : rtcService.handleFragBuffered(metric[0]); + } + const audioAppendData = appendDataTuple[SourceBufferType.AltAudio]; + if (((_a = audioAppendData === null || audioAppendData === void 0 ? void 0 : audioAppendData.dataSeg) === null || _a === void 0 ? void 0 : _a.flushBeforeAppend) || isFiniteNumber((_b = audioAppendData === null || audioAppendData === void 0 ? void 0 : audioAppendData.dataSeg) === null || _b === void 0 ? void 0 : _b.switchPosition)) { + const { itemId, mediaOptionId } = audioAppendData.dataSeg; + rootService.setEnabledMediaOptionSwitchContextByType(itemId, MediaOptionType.AltAudio, mediaOptionId, undefined); + } + return true; + }), addCreateSourceBufferErrorHandlingPolicy(mediaSink, rootService, rootQuery)); + })); + }; + + /** + * Convert seek to date values into media position seeks + */ + /** + * @brief Get the media time for a given date + * @param dateMediaTimeTuple DateTimeMs, mediaTimeSec pairs sorted in ascending order + * @param searchDate date to resolve + * @returns media position. 0 if earlier than beginning of playlist + */ + function resolveDateToPTS(dateMediaTimeTuple, searchDate) { + var _a; + if (!dateMediaTimeTuple || dateMediaTimeTuple.length === 0) { + return 0; + } + // Scan for the max startDateTime that is smaller than the searchDate + const descendingTuple = [...dateMediaTimeTuple].sort((a, b) => b[0] - a[0]); + const searchDt = searchDate.getTime(); + const closest = (_a = descendingTuple.find(([dt]) => searchDt >= dt)) !== null && _a !== void 0 ? _a : descendingTuple[descendingTuple.length - 1]; + const [closestDt, startPTSSec] = closest; + const resolvedTime = startPTSSec + (searchDt - closestDt) / 1000; + return Math.max(0, resolvedTime); + } + /** + * @brief Get the date for a given position in media + * @param dateMediaTimeTuple DateTimeMs, mediaTimeSec pairs sorted in ascending order + * @param ptsSeconds time in media seconds + * @returns Date associated with this time. undefined if no date available + */ + function resolvePTSToDate(dateMediaTimeTuple, ptsSeconds) { + var _a; + if (!dateMediaTimeTuple || dateMediaTimeTuple.length === 0) { + return undefined; + } + const descendingTuple = [...dateMediaTimeTuple].sort((a, b) => b[1] - a[1]); + const closest = (_a = descendingTuple.find(([_, mediaTime]) => ptsSeconds >= mediaTime)) !== null && _a !== void 0 ? _a : descendingTuple[descendingTuple.length - 1]; + const [closestDt, startPTSSec] = closest; + const resolvedDate = new Date(closestDt + (ptsSeconds - startPTSSec) * 1000); + return resolvedDate; + } + function resolveSeekToDateAsync(seekTo, rootQuery, libService) { + return rootQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(switchMap((option) => { + return libService.getQueryForOption(option).mediaOptionDetails$; + }), map((details) => resolveDateToPTS(details.dateMediaTimePairs, seekTo)), take(1)); + } + /** + * Return seek position within media + * @param seekTo + * @param rootPlaylistQuery + * @returns + */ + function resolveSeekToAsync(seekTo, isFirstSeek, config, rootPlaylistQuery, libService, logger) { + // seekTo value meanings: + // non-finite = auto seek position. LIVE: live edge, VOD: startTimeOffset if available or start of item + // 0 = if (LIVE && liveEdgeForZeroStartPositon), live edge, else 0 + // positive = position in media timeline + // negative = LIVE: live edge, VOD: position relative to end of playlist + let resolvedSeekTo$ = rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(switchMap((variant) => libService.getQueryForOption(variant).mediaOptionDetails$), filter((details) => isFiniteNumber(details === null || details === void 0 ? void 0 : details.totalduration)), take(1), map((details) => { + const hasEndTag = !details.liveOrEvent; + const totalDuration = details.totalduration; + const itemStartOffset = rootPlaylistQuery.itemStartOffset; + if (hasEndTag) { + if (!isFiniteNumber(seekTo)) { + const offset = isFiniteNumber(details.startTimeOffset) ? details.startTimeOffset : 0; + return itemStartOffset + offset; + } + else if (seekTo >= 0) { + // seekTo positive values are never pending + // seekTo 0 is pending only when liveEdgeForZeroStartPositon is opted in + return seekTo; + } + else { + // seekTo negative values + const offset = totalDuration + seekTo; + return itemStartOffset + offset; + } + } + else { + // live and event (no EXT-X-END tag) + if (!isFiniteNumber(seekTo) || seekTo < 0 || (seekTo === 0 && config.liveEdgeForZeroStartPositon)) { + // catch up to live edge + return computeLivePosition(0, details, config, logger); + } + else { + // isFinite(seekTo) && seekTo >= 0 && (seekTo !== 0 || !liveEdgeForZeroStartPosition) + // sanitize seek value + return sanitizeLiveSeek(seekTo, details, config, logger); + } + } + })); + if (isFirstSeek) { + resolvedSeekTo$ = resolvedSeekTo$.pipe(tap((seekTo) => { + logger.qe({ critical: true, name: 'initialSeekSet', data: { seekTo, source: 'rootPlaylistQuery.pendingSeek' } }); + })); + } + return resolvedSeekTo$; + } + /** + * Epic that just updates pending seek in active item from hls service. + * @param rootQuery + * @param libService + * @returns + */ + function userSeekEpic(itemQueue, rootService) { + return (userSeek$) => userSeek$.pipe(filterNullOrUndefined(), switchMap((seekTo) => forkJoin([ + of(seekTo), + itemQueue.activeItemById$.pipe(filterNullOrUndefined(), switchMap((entity) => { + return rootService.getQueryForId(entity.itemId).rootPlaylistEntity$; + }), take(1)), + ])), map(([seekTo, activeItem]) => { + rootService.setPendingSeek(activeItem.itemId, seekTo); + return seekTo; + })); + } + /** + * Epic that handles requested seeks made to the current active item and + * then updates mediaSink position. Expected to be subscribed on active item change + * + * @param config configuration for seek resolution + * @param logger logger object + * @param mediaSink MediaSink object + * @param rootQuery Query for the active item + * @param libService Media library service + * @returns + */ + function pendingSeekEpic(config, logger, mediaSink, rootService, rootQuery, libService) { + logger = logger.child({ name: 'seek' }); + return (pendingSeek$) => pendingSeek$.pipe(switchMap((pendingSeek, index) => { + if (pendingSeek == null) { + return EMPTY; + } + logger.info(`got pendingSeek=${pendingSeek}`); + const gotNewerSeek$ = mediaSink.mediaQuery.seekTo$.pipe(skip(1), // seekTo$ always emits the active seekTo value to new subscribers (which is populated while seeking, null otherwise) + filterNullOrUndefined()); + return resolveSeek(pendingSeek, index === 0, config, logger, rootQuery, libService).pipe(finalize$1(() => { + rootService.setPendingSeek(rootQuery.itemId, undefined); + }), takeUntil(gotNewerSeek$)); + }), tap((pendingSeek) => { + logger.info(`resolved pendingSeek=${pendingSeek}`); + if (isFiniteNumber(pendingSeek)) { + mediaSink.seekTo = pendingSeek; + } + })); + } + function resolveSeek(seekTo, isFirst, config, logger, rootQuery, libService) { + if (seekTo == null) { + return EMPTY; + } + if (seekTo instanceof Date) { + return resolveSeekToDateAsync(seekTo, rootQuery, libService); + } + else { + return resolveSeekToAsync(seekTo, isFirst, config, rootQuery, libService, logger); + } + } + + function updateEnabledMediaOptionsAsync(rootPlaylistService, itemId) { + return timer(0).pipe(map(() => { + rootPlaylistService.logger.debug(`[updateEnabledMediaOptions] itemId ${itemId}`); + rootPlaylistService.updateEnabledMediaOptions(itemId); + })); + } + /** + * Handle end of the pipeline error. Update the media options as needed based + * on nextMediaOptionsKeys (updated by ErrorHandlingPolicies) + * + * Should always be the last operator. + */ + function mediaPipelineHandleError(pipelineContext) { + const { logger, rootPlaylistService, rootPlaylistQuery } = pipelineContext; + const itemId = rootPlaylistQuery.itemId; + return (source) => source.pipe(retryWhen((errors) => errors.pipe(mergeMap((err) => { + logger.error(`Got error in pipeline ${err.message} fatal:${err === null || err === void 0 ? void 0 : err.fatal} handled:${err === null || err === void 0 ? void 0 : err.handled}`); + if (!(err instanceof HlsError) || err.fatal) { + throw err; + } + if (!err.handled) { + return EMPTY; // Do nothing, wait for next emit + } + // Not fatal, we can re-subscribe to source after updating media options + return updateEnabledMediaOptionsAsync(rootPlaylistService, itemId); + })))); + } + /** + * Core fetch and append epic. Listens to what details are available from the playlist service, + * and the playback and buffering state from the mediaPlaybackService. It can respond to either + * by changing downloading fragments or initiating track switching. + * + * store with these selections + * @param mediaPlaybackService + * @param config Configuration needed load and playback + */ + const mediaFragmentPipelineEpic = () => (pipelineActionSource$) => { + return pipelineActionSource$.pipe(tag('mediaFragmentPipelineEpic.in'), switchMap((pipelineContext) => { + if (!pipelineContext) { + return EMPTY; + } + const { logger, config, platformService, rootPlaylistService, rootPlaylistQuery, keySystemAdapter, mediaSink, mediaParser, gaplessInstance, mediaLibraryService } = pipelineContext; + const { itemId } = rootPlaylistQuery; + const { mediaQuery } = mediaSink; + logger.info(`mediaFragmentPipelineEpic start ${itemId}`); + const keyStatusChange$ = keySystemAdapter.keyStatusChange$.pipe(keyStatusChangeEpic(pipelineContext)); + const platformQuery = platformService.getQuery(); + const displayChange$ = platformQuery.displaySupportsHdr$.pipe(distinctUntilChanged(), switchMap((capable) => { + logger.info(`hdr display change=${capable}`); + rootPlaylistService.setHDRPreference(itemId, capable, true); + return EMPTY; + })); + const viewPortChange$ = platformQuery.viewportInfo$.pipe(distinctUntilChanged((a, b) => a && b && a.width === b.width && a.height === b.height), tap((viewportInfo) => { + logger.info(`viewport change=${JSON.stringify(viewportInfo)}, useViewportSizeForLevelCap: ${config.useViewportSizeForLevelCap}`); + if (config.useViewportSizeForLevelCap) { + rootPlaylistService.setViewportInfo(itemId, viewportInfo); + } + }), switchMapTo(EMPTY)); + const needsMediaReset$ = combineQueries([rootPlaylistQuery.hdrMode$.pipe(distinctUntilChanged()), rootPlaylistQuery.maxHdcpLevel$.pipe(distinctUntilChanged())]).pipe(switchMap(([hdrMode, maxHdcpLevel]) => { + logger.info(`hdrMode=${hdrMode} maxHdcpLevel=${maxHdcpLevel}`); + // if not in gapless mode and the current item is not offset on the timeline, reset the media source + if (!gaplessInstance.inGaplessMode && rootPlaylistQuery.itemStartOffset === 0) { + mediaSink.resetMediaSource(); + mediaParser.reset(); + } + return EMPTY; + })); + // Register this separately so errors here that may be recovered don't cause us to re-subscribe to the platform updates + const mediaPipes$ = merge( + // prettier-ignore + handleEnabledMediaOptions(pipelineContext), makeAVPipe(pipelineContext), makeSubtitlePipe(pipelineContext), keyStatusChange$).pipe( + // This updates enabled media options whenever an emit happens + mapTo(undefined), mediaPipelineHandleError(pipelineContext)); + const anchor$ = mediaQuery.seekTo$.pipe(filter((seekTo) => isFiniteNumber(seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos)), distinctUntilChanged((a, b) => Math.abs(a.pos - b.pos) < Number.EPSILON), // Can choose different threshold + switchMap((anchorTime) => { + rootPlaylistService.setAnchorTime(itemId, anchorTime); + return EMPTY; + })); + // Non-functional, Logs compatible levels after playback starts + const logCompatibleLevels$ = mediaQuery.gotPlaying$.pipe(filter((playing) => playing), tap((_) => { + const mediaOptionQuery = rootPlaylistQuery.mediaOptionListQueries[MediaOptionType.Variant]; + const compatibleMediaLevels = mediaOptionQuery.filteredMediaOptionList; + logger.qe({ critical: true, name: 'compatibleLevels', data: { numLevels: compatibleMediaLevels.length } }); + compatibleMediaLevels.forEach((level) => { + const { mediaOptionId, bandwidth, bitrate, videoCodec, audioCodec, height, width, videoRange, iframes } = level; + logger.qe({ critical: true, name: 'manifestLevel', data: { mediaOptionId, bandwidth, bitrate, videoCodec, audioCodec, height, width, videoRange, iframes } }); + }); + }), take(1), switchMapTo(EMPTY)); + return merge( + // Seeking / position adjustments + rootPlaylistQuery.pendingSeek$.pipe(pendingSeekEpic(config, logger, mediaSink, rootPlaylistService, rootPlaylistQuery, mediaLibraryService)), ensurePlaybackWithinWindow(pipelineContext), // Adjust position within live window + anchor$, + // Download pipe + mediaPipes$, + // Following observables monitor state changes that may modify enabled media options + displayChange$, viewPortChange$, needsMediaReset$, desiredRateChange(pipelineContext), capToEnabledIframeOption(pipelineContext), logCompatibleLevels$).pipe(tag('mediaFragmentPiplineEpic.emit'), mapTo(undefined)); + })); + }; + /** + * update expected SbCount and load all media playlists + */ + function handleEnabledMediaOptions(pipelineContext) { + const { logger, rootPlaylistQuery, mediaSink } = pipelineContext; + const updateExpectedSbCount$ = rootPlaylistQuery.enabledMediaOptions$.pipe(filterNullOrUndefined(), tap((enabledOptions) => { + const altAudio = enabledOptions[MediaOptionType.AltAudio]; + const expectedSbCount = isEnabledMediaOption(altAudio) && (altAudio === null || altAudio === void 0 ? void 0 : altAudio.url) != null ? 2 : 1; + mediaSink.setExpectedSbCount(expectedSbCount); + })); + const setBufferTargetDuration$ = forkJoin([ + rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(filter((option) => isEnabledMediaOption(option)), switchMap((option) => { + const query = createMediaLibraryQuery(option); + return query.mediaOptionDetails$; + }), take(1) // Just update on first load. Target duration should be consistent across variants + ), + waitFor(mediaSink.mediaQuery.updating$, (x) => x), // On startup don't need to do this immediately + ]).pipe(observeOn(asyncScheduler), tap(([details]) => { + mediaSink.bufferMonitorTargetDuration = details.targetduration; + })); + const loadMediaOptions = MediaOptionTypes.map((mediaOptionType) => { + return rootPlaylistQuery.enabledMediaOptionByType$(mediaOptionType).pipe(tag('mediaOptionRetrieve.switch'), switchMap((option) => { + if (!option || !option.url || !isEnabledMediaOption(option)) { + return EMPTY; + } + const allowRefresh$ = mediaSink.mediaQuery.desiredRate$.pipe(map((rate) => rate !== 0), distinctUntilChanged()); + // always request first copy. this will either return cached value or request from server + return retrieveMediaOptionDetails(pipelineContext, option).pipe(tag('mediaOptionRetrieve.first'), switchMapTo(allowRefresh$), switchMap((allowRefresh) => { + if (!allowRefresh) { + return EMPTY; // Don't refresh while in pause + } + // refresh + return refreshMediaOptionDetails(pipelineContext, option); + })); + })); + }); + return merge(updateExpectedSbCount$, setBufferTargetDuration$, merge(...loadMediaOptions)).pipe(switchMapTo(EMPTY)); + } + function makeSubtitlePipe(pipelineContext) { + const { rootPlaylistQuery, mediaSink } = pipelineContext; + const mediaQuery = mediaSink.mediaQuery; + return waitFor(mediaQuery.mediaElementEntity$, (entity) => entity).pipe(switchMap((_) => { + return rootPlaylistQuery.anchorTime$.pipe(tag('anchorTime.subtitle.in'), filter((anchorTime) => isFiniteNumber(anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.pos)), subtitleSelectionEpic(pipelineContext), subtitleLoadAndProcessEpic(pipelineContext)); + })); + } + function keyStatusChangeEpic(keyLoadContext) { + return (source) => source.pipe(switchMap((event) => { + const { decryptdata, status, error } = event; + const { rootPlaylistQuery } = keyLoadContext; + if (status === 'needs-renewal') { + return loadKey(keyLoadContext, decryptdata, null); + } + else if (status === 'error' && (error instanceof KeyRequestError || error instanceof KeyRequestTimeoutError) && !error.handled) { + // Don't actually retry, we're just doing penalty box stuff and updating enabled options + const { rootPlaylistService, keySystemAdapter } = keyLoadContext; + return handleKeyError(error, 0, null, rootPlaylistService, rootPlaylistQuery, keySystemAdapter.ksQuery); + } + return EMPTY; + }), switchMap(() => EMPTY)); + } + /** + * @brief subtitle selection + */ + const subtitleSelectionEpic = (pipelineContext) => (anchorTimeSource$) => { + const { rootPlaylistQuery, rootPlaylistService, legibleSystemAdapter } = pipelineContext; + // setup HTML5 texttracks + const enabledMediaOption = rootPlaylistQuery.enabledAlternateMediaOptionByType(MediaOptionType.Subtitle); + if (!legibleSystemAdapter.gotTracks) { + const availableAlternateMediaOptions = rootPlaylistQuery.preferredMediaOptions[MediaOptionType.Subtitle]; + legibleSystemAdapter.setTracks(availableAlternateMediaOptions, enabledMediaOption, rootPlaylistQuery.getDisabledMediaOption(MediaOptionType.Subtitle)); + } + else { + legibleSystemAdapter.selectedTrack = enabledMediaOption; + } + return anchorTimeSource$.pipe(tag('subtitleEpic.select.in'), switchMap(() => { + return merge(legibleSystemAdapter.nativeSubtitleTrackChange$.pipe( + // mediaOption selected via native media element video controller UI + switchMap((mediaOption) => { + if (mediaOption.mediaOptionId !== legibleSystemAdapter.selectedMediaOption.mediaOptionId) { + rootPlaylistService.setEnabledMediaOptionByType(mediaOption.itemId, MediaOptionType.Subtitle, mediaOption); + } + return EMPTY; + })), rootPlaylistQuery + .enabledMediaOptionByType$(MediaOptionType.Subtitle) + .pipe( + // mediaOption selected via hls.js API + map((option) => { + // option may be null initially + const altMediaOption = isEnabledMediaOption(option) ? rootPlaylistQuery.alternateMediaOptionById(MediaOptionType.Subtitle, option.mediaOptionId) : option; + legibleSystemAdapter.selectedMediaOption = altMediaOption; + return altMediaOption; + })) + .pipe(distinctUntilChanged((a, b) => { + return (a === null || a === void 0 ? void 0 : a.mediaOptionId) === (b === null || b === void 0 ? void 0 : b.mediaOptionId); + }))); + }), tag('subtitleEpic.select.emit')); + }; + const loadOneSubtitleFrag = (pipelineContext, initPTS, loadingFrag) => { + const { rootPlaylistQuery, legibleSystemAdapter } = pipelineContext; + return defer(() => { + return retrieveSubtitleFragmentCacheEntity(pipelineContext, initPTS, loadingFrag).pipe(map(({ initPTS, data, mediaFragment }) => { + const enabledAltMediaOption = rootPlaylistQuery.enabledAlternateMediaOptionByType(MediaOptionType.Subtitle); + const parsedCueRecord = processSubtitlePayload(enabledAltMediaOption, mediaFragment, initPTS, data, legibleSystemAdapter); + return { frag: mediaFragment, cueRange: parsedCueRecord }; + })); + }); + }; + const loadSubtitleBatch = (pipelineContext, initPTS, findFragsResult, details) => { + const legibleServiceAdapter = pipelineContext.legibleSystemAdapter; + const nextFrags = findFragsResult.foundFrags; + return from(nextFrags).pipe( + // emit next frags to load in a sequence + map((frag) => { + return loadOneSubtitleFrag(pipelineContext, initPTS, frag).pipe(delayWhen((parsedFragResult) => { + return legibleServiceAdapter.checkReadyToLoadNextSubtitleFragment$(frag, nextFrags).pipe(filter((x) => x)); + })); + }), mergeAll(pipelineContext.config.vttConcurrentLoadCount), tap((parsedFragResult) => { + if (legibleServiceAdapter.reviewParsedFrag(parsedFragResult, findFragsResult, details) !== ParsedFragQuality.CloseEnough) { + // may be too far from target frag. find another frag based on newly parsed cues + pipelineContext.legibleSystemAdapter.tryAgain$.next(true); + } + })); + }; + const loadSubtitleInDiscontinuity = (pipelineContext, details, activeSeqNum) => { + const { legibleSystemAdapter, rootPlaylistQuery } = pipelineContext; + return rootPlaylistQuery.initPTS$(activeSeqNum).pipe(switchMap((initPTS) => { + if (!initPTS || initPTS.iframeMode) { + return NEVER; + } + return legibleSystemAdapter.findFrags$(details, activeSeqNum).pipe(switchMap((findFragsResult) => { + if (!details || !(findFragsResult === null || findFragsResult === void 0 ? void 0 : findFragsResult.foundFrags)) + return VOID; + return loadSubtitleBatch(pipelineContext, initPTS.offsetTimestamp, findFragsResult, details); + })); + })); + }; + /** + * @brief subtitle loading & processing + */ + const subtitleLoadAndProcessEpic = (pipelineContext) => (bufferInfoSource$) => { + const { mediaSink, rootPlaylistQuery, legibleSystemAdapter, logger } = pipelineContext; + return bufferInfoSource$.pipe(tag('subtitleEpic.process.in'), switchMap((option) => { + if (!option || !option.url || !isEnabledMediaOption(option)) { + return of([null, null, null]); + } + const mediaLibraryQuery = createMediaLibraryQuery(option); + const details$ = mediaLibraryQuery.mediaOptionDetails$; + const activeDiscoSeqNum$ = rootPlaylistQuery.discoSeqNum$.pipe(filter((sn) => isFiniteNumber(sn))); + return combineQueries([details$, activeDiscoSeqNum$]).pipe(switchMap(([details, activeSeqNum]) => { + return loadSubtitleInDiscontinuity(pipelineContext, details, activeSeqNum); + })); + }), tag('subtitleEpic.process.emit')); + }; + function processSubtitlePayload(enabledMediaOption, mediaFragment, initPTS, data, legibleSystemAdapter) { + if (enabledMediaOption) { + return legibleSystemAdapter.processSubtitleFrag(enabledMediaOption, mediaFragment, initPTS, data); + } + return; + } + + const getMimeInfo = (initParsedData, container) => { + var _a; + let mimeType = ''; + let codec = ''; + let type; + if (initParsedData.videoCodec && initParsedData.audioCodec) { + codec = `${initParsedData.videoCodec}, ${initParsedData.audioCodec}`; + container = container !== null && container !== void 0 ? container : 'video/mp4'; + type = 'audiovideo'; + } + else if (initParsedData.videoCodec) { + codec = `${initParsedData.videoCodec}`; + container = container !== null && container !== void 0 ? container : 'video/mp4'; + type = 'video'; + } + else { + codec = `${(_a = initParsedData.audioCodec) !== null && _a !== void 0 ? _a : ''}`; + container = container !== null && container !== void 0 ? container : 'audio/mp4'; + type = 'audio'; + } + mimeType = `${container};codecs=${codec}`; + return { mimeType, codec, container, type }; + }; + + class MediaParser { + constructor(config, logger, demuxClient) { + this.config = config; + this.logger = logger; + this.demuxClient = demuxClient; + this.typeSupported = { + mp4: MediaSource.isTypeSupported('video/mp4'), + mpeg: MediaSource.isTypeSupported('audio/mpeg'), + mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'), + ac3: MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"'), + ec3: MediaSource.isTypeSupported('audio/mp4; codecs="ec-3"'), + }; + this.demuxers = []; + this.lastInitFrags = []; + this.lastFrags = []; + } + parseInitSegment(context, vendor) { + return this.getDemuxerInfo(context, this.lastInitFrags, vendor, this.demuxClient).pipe(switchMap(({ demuxer, contiguous, trackSwitch, discontinuity, accurateTimeOffset }) => { + const { frag } = context; + const { keyTagInfo, start: timeOffset, mediaOptionType } = frag; + this.lastInitFrags[mediaOptionType] = frag; + if (context.initSegment) { + const remuxedInitSegment = MP4EncryptionRemuxer.remuxInitSegment(new Uint8Array(context.initSegment), this.logger, keyTagInfo); + const initParsedData = MP4Demuxer.parseInitSegment(remuxedInitSegment); + const { mimeType, type, codec, container } = getMimeInfo(initParsedData); + return of({ moovData: initParsedData, mimeType, track: { type, codec, initSegment: remuxedInitSegment, container } }); + } + const segmentData = context.segment ? context.segment : context.initSegment; + const initSegmentData = segmentData ? context.initSegment : undefined; + const demuxerTarget = fromEventTarget(demuxer.observer); + return of(demuxerTarget.event(DemuxerEvent.FRAG_PARSING_INIT_SEGMENT).pipe(map(this.handleInitSegmentData)), demuxerTarget.event(HlsEvent$1.INTERNAL_ERROR).pipe(switchMap(this.handleError)), + // Because we're sending the same data to demuxers multiple times, we cannot transfer to worker here. + demuxer + .pushWithoutTransfer(segmentData, keyTagInfo, initSegmentData, timeOffset, discontinuity, trackSwitch, contiguous, context.totalDuration, accurateTimeOffset, undefined, // context.defaultInitPTS, + context.iframeMediaStart, context.iframeDuration) + .pipe(switchMapTo(EMPTY))).pipe(mergeAll(), take(1)); + })); + } + parseSegment(context, vendor) { + return this.getDemuxerInfo(context, this.lastFrags, vendor, this.demuxClient).pipe(switchMap(({ demuxer, contiguous, trackSwitch, discontinuity, accurateTimeOffset }) => { + const { frag, defaultInitPTS } = context; + const { keyTagInfo, start: timeOffset, duration, mediaOptionType } = frag; + this.lastFrags[mediaOptionType] = frag; + let parsedInitSegment; + const demuxerTarget = fromEventTarget(demuxer.observer); + return of(demuxerTarget.event(DemuxerEvent.FRAG_PARSING_INIT_SEGMENT).pipe(switchMap((data) => { + var _a; + if (data.track.initSegment.byteLength !== ((_a = context.initSegment) === null || _a === void 0 ? void 0 : _a.byteLength)) { + parsedInitSegment = this.handleInitSegmentData(data); + } + return EMPTY; + })), demuxerTarget.event(DemuxerEvent.FRAG_PARSING_DATA).pipe(map((parsedData) => { + const { startPTS, startDTS, firstKeyframePts, framesWithoutIDR, dropped, data1, data2, captionData, id3Samples } = parsedData; + let { endPTS, endDTS } = parsedData; + if (endPTS == null) { + this.logger.warn(`${MediaOptionNames[mediaOptionType]} ${fragPrint(frag)}: null endPTS parsed, using duration ${duration}`); + endPTS = Object.assign(Object.assign({}, startPTS), { baseTime: startPTS.baseTime + convertSecondsToTimestamp(duration, startPTS.timescale).baseTime }); + } + if (endDTS == null) { + this.logger.warn(`${MediaOptionNames[mediaOptionType]} ${fragPrint(frag)}: null endDTS parsed, using duration ${duration}`); + endDTS = Object.assign(Object.assign({}, startDTS), { baseTime: startDTS.baseTime + convertSecondsToTimestamp(duration, startDTS.timescale).baseTime }); + } + // Don't post sanity check error event for trickplay until we fix the rounding problem (due to small timescale) + if (!isFiniteNumber(context.iframeMediaStart)) { + // Just do duration check for now (accurateTimeOffset == false) + checkIfValidFragParsingData(frag, parsedData, defaultInitPTS, false, context.iframeMediaStart, this.config.audioPrimingDelay); + } + return { startPTS, endPTS, startDTS, endDTS, firstKeyframePts, framesWithoutIDR, dropped, data1, data2, captionData, id3Samples, parsedInitSegment }; + })), demuxerTarget.event(HlsEvent$1.INTERNAL_ERROR).pipe(switchMap(this.handleError)), demuxer + .push(context.segment, keyTagInfo, context.initSegment, timeOffset, discontinuity, trackSwitch, contiguous, context.totalDuration, accurateTimeOffset, defaultInitPTS, context.iframeMediaStart, context.iframeDuration) + .pipe(switchMapTo(EMPTY))).pipe(mergeAll(), take(1)); + })); + } + reset(mediaOptionType = undefined) { + if (mediaOptionType == undefined) { + this.demuxers.forEach((demuxer) => { + if (demuxer) + demuxer.destroy(); + }); + this.demuxers = []; + return; + } + const demuxer = this.demuxers[mediaOptionType]; + demuxer === null || demuxer === void 0 ? void 0 : demuxer.destroy(); + this.demuxers[mediaOptionType] = null; + } + destroy(mediaOptionType = undefined) { + if (mediaOptionType == undefined) { + this.reset(); + return; + } + this.reset(mediaOptionType); + } + willBeTrackSwitch(mediaFragment, frags) { + const { mediaOptionType, mediaOptionId } = mediaFragment; + const lastFrag = frags ? frags[mediaOptionType] : this.lastFrags[mediaOptionType]; + return !(lastFrag && lastFrag.mediaOptionId === mediaOptionId); + } + getDemuxerInfo(context, frags, vendor, demuxClient) { + const { frag, ptsKnown, seeking, live } = context; + const { discoSeqNum, mediaSeqNum, mediaOptionType } = frag; + return defer(() => { + const demuxer = this.demuxers[mediaOptionType]; + if (demuxer) { + return of(demuxer); + } + return demuxClient.init(this.typeSupported, this.config, vendor).pipe(tap((demuxer) => (this.demuxers[mediaOptionType] = demuxer))); + }).pipe(map((demuxer) => { + const lastFrag = frags[mediaOptionType]; + const trackSwitch = this.willBeTrackSwitch(frag, frags); + const discontinuity = !(lastFrag && discoSeqNum === lastFrag.discoSeqNum); + const contiguous = (lastFrag || false) && !trackSwitch && lastFrag.mediaSeqNum + 1 === mediaSeqNum; + const accurateTimeOffset = !seeking && (ptsKnown || !live); + return { demuxer, trackSwitch, discontinuity, contiguous, accurateTimeOffset }; + })); + } + handleInitSegmentData(data) { + const { track } = data; + const { initSegment } = track; + const moovData = MP4Demuxer.parseInitSegment(initSegment); + const { mimeType, type, codec, container } = getMimeInfo(moovData, track.container); + return { moovData, mimeType, track: Object.assign(Object.assign({}, track), { type, codec, initSegment, container }) }; + } + handleError(err) { + return throwError(err); + } + } + // Basic sanity check. Returns true if this is valid data, false if PTS/DTS values seem wrong + function checkIfValidFragParsingData(frag, data, initPTS, accurateTimeOffset, iframeMediaStart, audioPrimingDelay) { + let fudge = NaN; // max diff in seconds between parsed startDTS & expectedStartDTS + let expectedStartDTS = NaN; // expected value of parsed startDTS in seconds + if (isFiniteNumber(iframeMediaStart)) { + expectedStartDTS = iframeMediaStart; + // Most we should be off is one tick of the timescale due to rounding. iframe tracks can have small timescales, so allow up to 10 ms + fudge = 0.01; + if (isFinite(expectedStartDTS) && isFinite(audioPrimingDelay)) { + expectedStartDTS += audioPrimingDelay; + } + } + else if (accurateTimeOffset && initPTS) { + const timestampOffset = convertTimestampToSeconds(initPTS); + expectedStartDTS = frag.start + timestampOffset; + fudge = frag.duration; + } + const { startPTS, startDTS, endPTS, endDTS } = data; + // Technically we could have negative numbers if value > Number.MAX_SAFE_INTEGER + // but right now we would barf in LevelHelper adjustment + const success = startPTS.baseTime >= 0 && + startDTS.baseTime >= 0 && + frag.duration > 0 && + (endPTS == null || diffSeconds(endPTS, startPTS) > 0) && + (endDTS == null || diffSeconds(endDTS, startDTS) > 0) && + (!isFiniteNumber(fudge) || !isFiniteNumber(expectedStartDTS) || Math.abs(convertTimestampToSeconds(startDTS) - expectedStartDTS) <= fudge); + if (!success) { + throw new FragParsingError(false, `Failed demuxer sanity check frag=${fragPrint(frag)} parsed=${JSON.stringify({ startPTS, endPTS, startDTS, endDTS })} ${stringifyWithPrecision({ expectedStartDTS, fudge })}`, ErrorResponses.FailedDemuxerSanityCheck); + } + return success; + } + function createMediaParser(config, logger, demuxClient) { + return new Observable((subscriber) => { + const parser = new MediaParser(config, logger, demuxClient); + subscriber.next(parser); + return () => { + parser.destroy(); + }; + }); + } + + function getMinBufferAhead(config, details, bufferInfo) { + var _a, _b; + // Allow if we have a whole segment ahead + let playingFragDuration = Infinity; + if (bufferInfo.playingFrag) { + playingFragDuration = (_b = (_a = details.fragments[bufferInfo.playingFrag.mediaSeqNum - details.startSN]) === null || _a === void 0 ? void 0 : _a.duration) !== null && _b !== void 0 ? _b : Infinity; + } + const { minRequiredStartDuration, maxRequiredStartDuration, startTargetDurationFactor } = config; + const { targetduration, averagetargetduration } = details; + const requiredStartDuration = startTargetDurationFactor * Math.min(playingFragDuration, averagetargetduration, targetduration, maxRequiredStartDuration); + return Math.max(minRequiredStartDuration, requiredStartDuration); + } + /** + * @returns whether we probably have enough + */ + function probablyHaveEnough(config, fragInfo, playlistInfo, bufferInfo, desiredRate, bwEstimate, fragEstimate, bufferEstimate, logger) { + const { combined } = bufferInfo; + const minBufferAhead = getMinBufferAhead(config, playlistInfo.details, bufferInfo); + let haveEnough = haveEnoughBuffer(fragInfo, playlistInfo, bufferInfo, desiredRate, minBufferAhead); + if (!haveEnough && combined.len > 0 && (fragInfo === null || fragInfo === void 0 ? void 0 : fragInfo.state)) { + const estTimeToHaveEnough = getEstTimeToHaveEnough(fragInfo, playlistInfo.variant.bitrate, minBufferAhead, bufferInfo, bwEstimate, fragEstimate, bufferEstimate, config.maxBufferHole); + haveEnough = estTimeToHaveEnough <= combined.len; + logger === null || logger === void 0 ? void 0 : logger.info(`haveEnough (probably): ${haveEnough}, ${stringifyWithPrecision({ + bufferLen: combined.len, + pos: bufferInfo.pos, + estTimeToHaveEnough, + minBufferAhead, + state: fragInfo.state, + tstart: fragInfo.tstart, + avgParseMs: fragEstimate.avgParseTimeMs, + avgAppendMs: bufferEstimate.avgDataFragAppendMs, + })}`); + } + else if (!haveEnough && fragInfo == null) { + logger === null || logger === void 0 ? void 0 : logger.info(`haveEnough: ${haveEnough}, bufferLen: ${combined.len.toFixed(3)}`); + } + return haveEnough; + } + /** + * @returns whether we have enough buffer without using any estimation + */ + function haveEnoughBuffer(fragInfo, playlistInfo, bufferInfo, desiredRate, requiredStartDuration) { + const { pos, combined, playingFrag } = bufferInfo; + if (combined.len === 0) { + return false; + } + const iframeMode = desiredRate != 0 && desiredRate != 1; + const details = playlistInfo.details; + const fragments = details.fragments; + let haveEnough = iframeMode || combined.len >= requiredStartDuration; + const lastFrag = fragments[details.fragments.length - 1]; + const playlistStart = fragments[0].start; + const playlistEnd = playlistStart + details.totalduration; + let gotDiscontinuity = false; + if (playingFrag) { + const lastFragForCC = BinarySearch$1.search(fragments, (frag) => playingFrag.discoSeqNum - frag.discoSeqNum); + gotDiscontinuity = + (fragInfo && playingFrag.discoSeqNum !== fragInfo.discoSeqNum) || + lastFragForCC == null || // buffered cc does not appear in the refreshed playlist anymore + fragEqual(lastFragForCC, playingFrag); // buffered cc appears to end in refreshed playlist + } + // Also ensure that live is behind furthest live position + if (haveEnough && details.liveOrEvent) { + const behindLivePosition = playlistEnd - lastFrag.duration; + haveEnough = pos <= behindLivePosition; + } + else if (!details.liveOrEvent) { + // Allow play through if we're close to the end + haveEnough = haveEnough || pos >= playlistEnd - requiredStartDuration; + } + haveEnough = haveEnough || gotDiscontinuity; + return haveEnough; + } + /** + * @returns the duration relative to now when we think that the fragment will be + * buffered / complete + */ + function getEstTimeToHaveEnough(fragInfo, bitrate, minBufferAhead, bufferInfo, bwEstimate, fragEstimate, bufferEstimate, maxBufferHole) { + var _a, _b; + const mainBufferInfo = (_a = bufferInfo.sbTuple[MediaOptionType.Variant]) === null || _a === void 0 ? void 0 : _a.buffered; + const audioBufferInfo = (_b = bufferInfo.sbTuple[MediaOptionType.AltAudio]) === null || _b === void 0 ? void 0 : _b.buffered; + if ((mainBufferInfo === null || mainBufferInfo === void 0 ? void 0 : mainBufferInfo.len) >= minBufferAhead && (!audioBufferInfo || audioBufferInfo.len >= minBufferAhead)) { + // Already have enough buffered in main/audio sb. Its + // already assumed that if main suffices, audio will as well - but + // still checking for sanity + return 0; + } + else if (!mainBufferInfo || !fragInfo || !fragOverlapsEndAndSufficient(fragInfo, mainBufferInfo, maxBufferHole, minBufferAhead, bufferInfo.pos)) { + // Not enough fragment info + return Infinity; + } + const state = fragInfo.state; + let tStartOfState = fragInfo.tstart; + let timeToComplete = 0; + switch (state) { + case 'loading': + timeToComplete += getTimeToLoad(fragInfo, bitrate, bwEstimate); + tStartOfState = fragInfo.tstart + timeToComplete * 1000; + // fallthrough + case 'loaded': + case 'parsing': + timeToComplete += getTimeToParse(tStartOfState, fragEstimate); + tStartOfState = fragInfo.tstart + timeToComplete * 1000; + // fallthrough + case 'parsed': + case 'appending': + timeToComplete += getTimeToAppendBuffer(tStartOfState, bufferEstimate); + break; + case 'appended': + // 0 triggers a false positive for haveEnough; If appended, it + // should be factored in combined.len. + timeToComplete = Infinity; + break; + default: + timeToComplete = Infinity; + break; + } + return timeToComplete; + } + /** + * @returns the estimated remaining amount of time to load the fragment + */ + function getTimeToLoad(fragInfo, bitrate, bwEstimate) { + const { bwSample: fragStats, duration } = fragInfo; + if (!fragStats) { + return Infinity; + } + // Calculate based on current bw when we think the next frag will be finished + // Assume audio will take less time + const totalBits = isFiniteNumber(fragStats.total) ? fragStats.total * 8 : Math.ceil(duration * bitrate); // est bytes using bitrate & duration + const loadedBits = fragStats.loaded * 8; + const remainingBits = totalBits - loadedBits; + const instantBW = (loadedBits / (performance.now() - fragStats.tfirst)) * 1000; // bps + if (!isFiniteNumber(instantBW)) { + return Infinity; + } + const avgBW = bwEstimate.avgBandwidth; // bps + const bandwidth = Math.min(avgBW, instantBW); + return remainingBits / bandwidth; + } + /** + * @returns the estimated remaining amount of time to parse the fragment + */ + function getTimeToParse(tParseStart, fragEstimate) { + const avgParseTimeMs = isFiniteNumber(fragEstimate.avgParseTimeMs) ? fragEstimate.avgParseTimeMs : 0; + if (performance.now() < tParseStart) { + return avgParseTimeMs / 1000; + } + return Math.max(0, avgParseTimeMs - (performance.now() - tParseStart)) / 1000; + } + /** + * @returns the estimated remaining amount of time to append the fragment + */ + function getTimeToAppendBuffer(tAppendStart, bufferEstimate) { + const avgDataFragAppendMs = isFiniteNumber(bufferEstimate.avgDataFragAppendMs) ? bufferEstimate.avgDataFragAppendMs : 0; + if (performance.now() < tAppendStart) { + return avgDataFragAppendMs / 1000; + } + return Math.max(0, avgDataFragAppendMs - (performance.now() - tAppendStart)) / 1000; + } + /** + *@returns true if to frag overlaps end + */ + function fragOverlapsEndAndSufficient(fragInfo, bufferInfo, maxBufferHole, minBufferAhead, currentPosition) { + const fragend = fragInfo.start + fragInfo.duration; + return fragend > bufferInfo.end && (fragInfo.start - bufferInfo.end <= maxBufferHole || fragInfo.start <= bufferInfo.end) && fragend - currentPosition >= minBufferAhead; + } + + /** + * Observables that keep track of pipeline and media state to update playback state + */ + function checkForHaveEnough(config, logger, rootQuery, mediaSink, mediaLibraryService, statsQuery) { + const mediaQuery = mediaSink.mediaQuery; + // Startup perf: avoid subscribing to stuff on startup if we don't /need/ it + // Have enough won't ever be true until something gets buffered so don't listen to any observables until then. + return waitFor(mediaQuery.combinedBuffer$, (combinedBuffer) => (combinedBuffer === null || combinedBuffer === void 0 ? void 0 : combinedBuffer.length) > 0).pipe(switchMap(() => { + const mediaBufferInfo$ = combineQueries([mediaQuery.seekTo$, mediaQuery.bufferedSegmentsByType$(SourceBufferType.Variant)]).pipe(map(([seekTo, bufferedSeg]) => { + var _a; + const pos = isFiniteNumber(seekTo === null || seekTo === void 0 ? void 0 : seekTo.pos) ? seekTo.pos : mediaQuery.currentTime; + const playingSeg = bufferedSeg.find((seg) => seg.startPTS <= pos && seg.endPTS > pos); + const sbTuple = mediaQuery.getBufferInfo(pos, config.maxBufferHole); + const combined = mediaQuery.getCombinedBufferInfo(pos, config.maxBufferHole); + return { + pos, + sbTuple, + combined, + playingFrag: (_a = playingSeg === null || playingSeg === void 0 ? void 0 : playingSeg.frag) !== null && _a !== void 0 ? _a : null, + }; + })); + const inFlightInfo$ = combineQueries([ + rootQuery.getInFlightFragByType$(MediaOptionType.Variant), + rootQuery.enabledMediaOptionByType$(MediaOptionType.Variant), + ]).pipe(switchMap(([inFlightFrag, mediaOption]) => { + const playlistQuery = mediaLibraryService.getQueryForOption(mediaOption); + return zip(of(inFlightFrag), of(mediaOption), playlistQuery.mediaOptionDetails$); + }), map(([currentFrag, variant, details]) => { + return [currentFrag, { variant, details }]; + })); + const bwEstimates$ = combineQueries([statsQuery.bandwidthEstimate$, statsQuery.fragEstimate$, statsQuery.bufferEstimate$]); + return combineQueries([mediaQuery.readyState$, inFlightInfo$, mediaBufferInfo$, mediaQuery.desiredRate$, bwEstimates$]); + }), throttleTime(100, asyncScheduler, { leading: true, trailing: true }), map(([_readyState, inFlightInfo, bufferInfo, desiredRate, bwEstimates]) => { + const [fragInfo, playlistInfo] = inFlightInfo; + const [bwEstimate, fragEstimate, bufferEstimate] = bwEstimates; + let overrideFragEstimate = fragEstimate; + let overrideBufferEsimate = bufferEstimate; + if (fragEstimate) { + const maxDurationSec = isFiniteNumber(fragEstimate.maxDurationSec) ? fragEstimate.maxDurationSec : config.defaultTargetDuration; + const avgParseTimeMs = isFiniteNumber(fragEstimate.avgParseTimeMs) ? fragEstimate.avgParseTimeMs : config.statDefaults.fragParseTimeMs; + overrideFragEstimate = { maxDurationSec, avgParseTimeMs }; + } + if (bufferEstimate) { + const avgBufferCreateMs = isFiniteNumber(bufferEstimate.avgBufferCreateMs) ? bufferEstimate.avgBufferCreateMs : config.statDefaults.fragBufferCreationDelayMs; + const avgInitFragAppendMs = isFiniteNumber(bufferEstimate.avgInitFragAppendMs) ? bufferEstimate.avgInitFragAppendMs : config.statDefaults.initFragAppendMs; + const avgDataFragAppendMs = isFiniteNumber(bufferEstimate.avgDataFragAppendMs) ? bufferEstimate.avgDataFragAppendMs : config.statDefaults.dataFragAppendMs; + overrideBufferEsimate = { avgBufferCreateMs, avgInitFragAppendMs, avgDataFragAppendMs }; + } + const haveEnough = probablyHaveEnough(config, fragInfo, playlistInfo, bufferInfo, desiredRate, bwEstimate, overrideFragEstimate, overrideBufferEsimate, logger); + mediaSink.haveEnough = haveEnough; + return haveEnough; + }), distinctUntilChanged(), tap((haveEnough) => { + logger.info(`[seek] haveEnough=${haveEnough}`); + }), switchMapTo(EMPTY)); + } + function checkForEndOfStream(context) { + const { config, logger, mediaSink, rootPlaylistQuery: rootQuery, mediaLibraryService, gaplessInstance } = context; + const { mediaQuery } = mediaSink; + const currentEnabledDetails$ = rootQuery.enabledAVOptions$.pipe(switchMap((options) => zip(...options.map((option) => { + if (!isEnabledMediaOption(option)) { + return of(null); + } + return mediaLibraryService.getQueryForOption(option).mediaOptionDetails$; + })))); + // Startup: wait for something to be buffered before subscribe to enabledAVOptions & details + return waitFor(mediaQuery.combinedBuffer$, (combined) => { + return (combined === null || combined === void 0 ? void 0 : combined.length) > 0; + }).pipe(switchMapTo(combineQueries([ + currentEnabledDetails$, + mediaQuery.msReadyState$, + mediaQuery.updating$, + mediaQuery.isIframeRate$, + mediaQuery.isBufferedToEnd$(config.maxBufferHole, !gaplessInstance.inGaplessMode), + ])), tag('checkForEndOfStream'), filter(([_, readyState, updating, isIframeRate, bufferedToEnd]) => { + return readyState === 'open' && updating === false && !isIframeRate && bufferedToEnd; + }), tap(([details]) => { + logger.info('Reached end of stream'); + const isVOD = details[0] != null && details.every((x) => x == null || (x.liveOrEvent === false && x.iframesOnly === false)); + if (isVOD && !gaplessInstance.inGaplessMode) { + logger.info('Calling MediaSink endStream'); + mediaSink.endStream(); // May only be called when updating == false + } + }), switchMapTo(EMPTY)); + } + + function loadRootMediaOptions(item, loadPolicy, logger, config, statsService, extendMaxTTFB) { + const { itemId, url, itemStartOffset } = item; + const loadConfig = getLoadConfig(item, loadPolicy); + return fromUrlText({ + url, + onProgress: { getData: true, cb: loadProgress }, + xhrSetup: config.xhrSetup, + }, loadConfig, extendMaxTTFB).pipe(map(({ responseText: rawPlaylist, responseURL: rURL, stats }) => { + const { keySystemPreference } = config; + logger.debug(`root playlist url: ${url}, baseUrl: ${rURL}`); + if (!rURL) { + logger.warn('Missing response url. Reusing request url as base url'); + rURL = url; + } + if (PlaylistParser$1.isMediaPlaylist(rawPlaylist)) { + const mediaOptionId = 'media-pl-' + guid(); + const parsed = PlaylistParser$1.parseMediaOptionPlaylist(rawPlaylist, rURL, true, keySystemPreference, {}, itemId, mediaOptionId, MediaOptionType.Variant, logger, itemStartOffset); + updatePlaylistAttributes(parsed.mediaOptionDetails); + const variantOption = { + itemId, + mediaOptionId, + mediaOptionType: MediaOptionType.Variant, + url, + bandwidth: 0, + bitrate: 0, + iframes: parsed.mediaOptionDetails.iframesOnly, + pathwayID: '.', + }; + const rootMediaOptionsTuple = [[variantOption], [], []]; + const loadResult = { + itemId, + itemStartOffset, + rootMediaOptionsTuple, + stats, + baseUrl: rURL, + initialDetails: parsed.mediaOptionDetails, + isMediaPlaylist: true, + }; + return loadResult; + } + else { + const sessionData = PlaylistParser$1.parseSessionData(rawPlaylist, rURL); + const sessionKeys = PlaylistParser$1.parseSessionKeys(rawPlaylist, rURL, keySystemPreference); + const parsed = PlaylistParser$1.parseRootPlaylist(itemId, rawPlaylist, rURL, true); + if (parsed.playlistParsingError) { + throw parsed.playlistParsingError; + } + const { variantMediaOptions, contentSteeringOption, masterVariableList } = parsed; + const parsingResult = PlaylistParser$1.parseRootPlaylistAlternateMediaOptions(itemId, rawPlaylist, rURL, parsed.variantMediaOptions, true, masterVariableList); + if (parsingResult.playlistParsingError) { + throw parsingResult.playlistParsingError; + } + const { audioAlternateOptions, subtitleAlternateOptions, audioMediaSelectionGroup, subtitleMediaSelectionGroup } = parsingResult.alternateMediaInfo; + const rootMediaOptionsTuple = [variantMediaOptions, audioAlternateOptions, subtitleAlternateOptions]; + const loadResult = { + itemId, + itemStartOffset, + rootMediaOptionsTuple, + stats, + baseUrl: rURL, + audioMediaSelectionGroup, + subtitleMediaSelectionGroup, + contentSteeringOption, + sessionData, + sessionKeys, + masterVariableList, + }; + return loadResult; + } + }), convertToManifestNetworkError(false)); + } + function loadProgress(url, status, _stats, data) { + if (status === 200 && data && data.length > 10) { + // only look at responses which have status 200 and is at least 10 chars long + if (!PlaylistParser$1.isValidPlaylist(data)) { + const playlistParsingError = new PlaylistParsingError(ErrorTypes.NETWORK_ERROR, ErrorDetails.MANIFEST_PARSING_ERROR, true, 'response doesnt have #EXTM3U tag', ErrorResponses.PlaylistErrorMissingEXTM3U); + playlistParsingError.url = url; + throw playlistParsingError; + } + return true; + } + return false; + } + + const loggerName$1 = { name: 'pltfrm' }; + var HdrMetadataType; + (function (HdrMetadataType) { + HdrMetadataType["HDR10"] = "smpteSt2086"; + HdrMetadataType["DoVi"] = "smpteSt2094-10"; + HdrMetadataType["HDR10Plus"] = "smpteSt2094-40"; + })(HdrMetadataType || (HdrMetadataType = {})); + function isValidSecurityLevel(securityLevel, keySystemId) { + const securityLevels = KeySystemFactory$1.getKeySystemSecurityLevel(keySystemId); + return securityLevel != null && securityLevels[securityLevel] !== undefined; + } + function onlyIframes(mediaOptionList) { + return mediaOptionList.every((mediaOption) => mediaOption.iframes); + } + function isWithinCap(val, cap) { + // If there is no value or if there is no cap, then the value is vacuously within the cap + return !isFiniteNumber(val) || !isFiniteNumber(cap) || val <= cap; // TODO revert or fix <- this is not my todo, inherited from 2.0 + } + function makeVideoConfiguration(codec, mediaOption) { + const vConfig = { + contentType: `video/mp4;codecs=${codec}`, + width: mediaOption.width, + height: mediaOption.height, + bitrate: mediaOption.bandwidth || mediaOption.avgBandwidth, + framerate: mediaOption.iframes ? 8 : mediaOption.frameRate, + }; + if (mediaOption.videoRange) { + switch (mediaOption.videoRange) { + case 'PQ': + if (MediaUtil.isDolby(codec)) { + vConfig.hdrMetadataType = HdrMetadataType.DoVi; + vConfig.colorGamut = 'rec2020'; + } + else if (MediaUtil.isHEVC(codec) || MediaUtil.isVP09(codec)) { + // Assuming HDR10 + vConfig.hdrMetadataType = HdrMetadataType.HDR10; + vConfig.colorGamut = 'rec2020'; + } + vConfig.transferFunction = 'pq'; + break; + case 'HLG': + // no metadata + vConfig.colorGamut = 'rec2020'; + vConfig.transferFunction = 'hlg'; + break; + } + } + return vConfig; + } + function makeAudioConfiguration(codec, mediaOption, audioMediaOptions) { + const aConfig = { + contentType: `audio/mp4;codecs=${codec}`, + }; + // Optional fields + const channels = RichestMedia.getRichestChannelLayoutForGroupId(mediaOption.audioGroupId, audioMediaOptions); + if (channels) { + aConfig.channels = MediaUtil.getChannelCount(channels).toString(); + aConfig.spatialRendering = MediaUtil.isDolbyAtmos(codec, channels); + } + return aConfig; + } + function createHandleCodec(logger) { + // can reduce the number of calls by caching the results + const cachedDecodingInfo = new Map(); + const mediaCapabilities = navigator && navigator.mediaCapabilities; + return (mediaOption, audioMediaOptions, codec, isVideo, isTypeSupportedObservables) => { + const config = { + type: 'media-source', + }; + if (isVideo) { + config.video = makeVideoConfiguration(codec, mediaOption); + } + else { + config.audio = makeAudioConfiguration(codec, mediaOption, audioMediaOptions); + } + const configStr = JSON.stringify(config); + let decodingInfoObservable; + if (cachedDecodingInfo.has(configStr)) { + decodingInfoObservable = cachedDecodingInfo.get(configStr); + } + else { + decodingInfoObservable = from(mediaCapabilities.decodingInfo(config)).pipe(map((decodingInfo) => { + const supportedConfig = decodingInfo.configuration || decodingInfo.supportedConfiguration; + const hasRequestedFields = supportedConfig instanceof Object && + (!config.video || Object.keys(config.video).find((k) => !(k in supportedConfig.video)) == undefined) && + (!config.audio || Object.keys(config.audio).find((k) => !(k in supportedConfig.audio)) == undefined); + const isTypeSupported = decodingInfo.supported && (!isVideo || decodingInfo.powerEfficient) && hasRequestedFields; + if (!isTypeSupported) { + logger.warn(loggerName$1, `Unsupported config ${decodingInfo.supported}/${decodingInfo.powerEfficient}/${hasRequestedFields} ${JSON.stringify(config)} supportedConfig=${JSON.stringify(supportedConfig)}`); + } + return isTypeSupported; + })); + cachedDecodingInfo.set(configStr, decodingInfoObservable); + } + return [...isTypeSupportedObservables, decodingInfoObservable]; + }; + } + function createIsSupportedInternal() { + const supportedCodecs = new Set(); + const unsupportedCodecs = new Set(); + return (mediaOption) => { + const checkSupported = (type, codec) => { + let isSupported = MediaSource.isTypeSupported(`${type}/mp4;codecs=${codec}`); + if (codec === 'mp4a.40.34' && !isSupported) { + isSupported = MediaSource.isTypeSupported(`${type}/mpeg`); + } + return isSupported; + }; + const updateCachedCodecsSetsIfNecessary = (codec, isAudioCodec) => { + const type = isAudioCodec ? 'audio' : 'video'; + // Minimizes calls to chromium by caching supported/unsupported audio video codecs + if (!supportedCodecs.has(codec) && !unsupportedCodecs.has(codec)) { + if (checkSupported(type, codec)) { + supportedCodecs.add(codec); + } + else { + unsupportedCodecs.add(codec); + } + } + }; + // Update the codec support/notSupport cache based on MediaSource support. + // After that verify if that codec falls into unsupported category. + const checkUnsupportedCodec = (codec, isAudioCodec) => { + updateCachedCodecsSetsIfNecessary(codec, isAudioCodec); + return unsupportedCodecs.has(codec); + }; + let foundUnsupportedCodec = false; + if (mediaOption.audioCodecList) { + foundUnsupportedCodec = mediaOption.audioCodecList.some((codec) => checkUnsupportedCodec(codec, true)); + } + if (!foundUnsupportedCodec && mediaOption.videoCodecList) { + foundUnsupportedCodec = mediaOption.videoCodecList.some((codec) => checkUnsupportedCodec(codec, false)); + } + return !foundUnsupportedCodec; + }; + } + function useFallbackCapsIfMissing(result, fallback) { + const keys = Object.keys(fallback); + keys.forEach((key) => { + if (!result[key]) { + result[key] = fallback[key]; + } + }); + return result; + } + /** + * @param cappingInfoList Usually platformInfo.videoCodecs or platformInfo.videoDynamicRangeFormats + * @param type to use for lookup + * @returns Capping info with matching type + */ + function getCappingInfoFromType(cappingInfoList, type) { + for (const id in cappingInfoList) { + if (cappingInfoList[id].type === type) { + return cappingInfoList[id]; + } + } + return {}; + } + /** + * @param format DynamicRangeFormat + * @param compressionType CompressionType + * @param videoCodecs List of capping info [ { type: DynamicRangeFormat } ] + * @param videoDynamicRangeFormats List of capping info [ {type, CompressionType } ] + * @returns The capping information to use + */ + function getCappingInfo(vdrType, compressionType, videoCodecs, videoDynamicRangeFormats) { + if (!videoDynamicRangeFormats && !videoCodecs) { + return {}; + } + const cappingFromCompressionInfo = videoCodecs ? getCappingInfoFromType(videoCodecs, compressionType) : {}; + const cappingFromFormat = videoDynamicRangeFormats ? getCappingInfoFromType(videoDynamicRangeFormats, vdrType) : {}; + let preferredCaps; + let fallbackCaps; + switch (vdrType) { + case VideoDynamicRangeType.SDR: + // Prioritize using compressionType > dynamic range + preferredCaps = cappingFromCompressionInfo; + fallbackCaps = cappingFromFormat; + break; + default: + // Prioritize using dynamic range > compressionType + preferredCaps = cappingFromFormat; + fallbackCaps = cappingFromCompressionInfo; + } + const result = Object.assign({}, preferredCaps); + return useFallbackCapsIfMissing(result, fallbackCaps); + } + function getSupportedVideoFormats(videoDynamicRangeFormats) { + return videoDynamicRangeFormats.reduce((prev, cur) => { + switch (cur.type) { + case VideoDynamicRangeType.DolbyVision: + prev.doViSupported = true; + break; + case VideoDynamicRangeType.HDR10: + prev.hdr10Supported = true; + break; + case VideoDynamicRangeType.HLG: + prev.hlgSupported = true; + break; + } + return prev; + }, { doViSupported: false, hdr10Supported: false, hlgSupported: false }); + } + function filterMediaOptionInfoPrint(filterName, unfilteredMediaOptionInfo, filteredMediaOptionInfo, logger) { + const unfilteredMediaOptionCount = unfilteredMediaOptionInfo.length; + const filteredMediaOptionCount = filteredMediaOptionInfo.length; + const unchanged = unfilteredMediaOptionCount === filteredMediaOptionCount; + const removedMediaOptionIds = unfilteredMediaOptionInfo.filter((mediaOption) => !filteredMediaOptionInfo.includes(mediaOption)).map((mediaOption) => mediaOption.mediaOptionId); + logger.qe({ critical: true, name: 'mediaFiltering', data: { filterName, unchanged, remaining: filteredMediaOptionCount, filteredIds: removedMediaOptionIds } }); + } + function printMediaOptionInfo(mediaOptionInfo, logger) { + logger.info(loggerName$1, `Unsupported level ${JSON.stringify(mediaOptionInfo, ['avgBandwidth', 'audioCodecList', 'videoCodecList', 'videoRange', 'frameRate', 'width', 'height', 'iframes'])}`); + } + function filterMediaOptionsBasedOnHlsConfig(mediaOptions, disableVideoCodecList, disableAudioCodecList, logger) { + let filteredMediaOptions = mediaOptions.filter((mediaOption) => { + if (mediaOption.videoCodec) { + return mediaOption.videoCodecList.every((codec) => { + const videoCodecRank = getVideoCodecRanking(codec); + return !disableVideoCodecList.has(videoCodecRank); + }); + } + return true; + }); + filteredMediaOptions = filteredMediaOptions.filter((mediaOption) => { + if (!mediaOption.iframes && mediaOption.audioCodec) { + return mediaOption.audioCodecList.every((codec) => { + const audioCodecRank = getAudioCodecRanking(codec); + return !disableAudioCodecList.has(audioCodecRank); + }); + } + return true; + }); + filterMediaOptionInfoPrint('Disable Codec config', mediaOptions, filteredMediaOptions, logger); + return filteredMediaOptions; + } + function filterMediaOptionsBasedOnMaxAllowedHdcpLevel(mediaOptions, maxHdcpLevel, logger) { + const maxHdcpRanking = hdcpLevelToInt(maxHdcpLevel); + const filteredMediaOptions = mediaOptions.filter((mediaOption) => { + const curHdcpLevel = mediaOption.hdcpLevel; + return !curHdcpLevel || hdcpLevelToInt(curHdcpLevel) <= maxHdcpRanking; + }); + filterMediaOptionInfoPrint('Hdcp', mediaOptions, filteredMediaOptions, logger); + return filteredMediaOptions; + } + function filterMediaOptionsBasedOnSecurityLevel(mediaOptions, maxSecurityLevel, keySystemId, logger) { + const securityLevels = KeySystemFactory$1.getKeySystemSecurityLevel(keySystemId); + const keyFormat = KeySystemFactory$1.getKeySystemFormat(keySystemId); + const getSecurityLevelRanking = function (curSecurityLevel) { + return isValidSecurityLevel(curSecurityLevel, keySystemId) ? securityLevels[curSecurityLevel] : -1; + }; + const maxSecurityLevelRanking = getSecurityLevelRanking(maxSecurityLevel); + const filteredMediaOptions = mediaOptions.filter((mediaOption) => { + var _a, _b; + const cpcLabels = (_b = (_a = mediaOption.allowedCPCMap) === null || _a === void 0 ? void 0 : _a[keyFormat]) !== null && _b !== void 0 ? _b : []; + let selectLevel = true; + for (const currentLabelSecurityLevel of cpcLabels) { + const currentLabelSecurityLevelRanking = getSecurityLevelRanking(currentLabelSecurityLevel); + selectLevel = currentLabelSecurityLevelRanking <= maxSecurityLevelRanking; + if (!selectLevel) { + break; + } + } + return selectLevel; + }); + filterMediaOptionInfoPrint('Security Level', mediaOptions, filteredMediaOptions, logger); + return [...filteredMediaOptions]; + } + function filterMediaOptionsBasedOnMediaKeySystemAccess(mediaOptions, keySystemId, logger) { + const cachedKeySystemConfig = new Map(); + function handleKeySystem(keySystemId, levelInfo, isKeySystemSupportedPromises) { + const mediaCapabilities = keysystemutil.getCapabilities(levelInfo.videoCodecList, levelInfo.audioCodecList); + const configStr = JSON.stringify(mediaCapabilities); + let requestKeySystemPromise; + if (cachedKeySystemConfig.has(configStr)) { + requestKeySystemPromise = cachedKeySystemConfig.get(configStr); + } + else { + requestKeySystemPromise = KeySystemFactory$1.requestKeySystemAccess(keySystemId, mediaCapabilities, undefined, logger).pipe(map(() => { + return true; + }), catchError((error) => { + logger.warn(`Request key system error: ${error.message}`); + return of(false); + }), shareReplay({ bufferSize: 1, refCount: true })); + cachedKeySystemConfig.set(configStr, requestKeySystemPromise); + } + isKeySystemSupportedPromises.push(requestKeySystemPromise); + } + const isSupported = new Array(); + mediaOptions.forEach((mediaOption) => { + const isKeySystemSupportedPromises = Array(); + handleKeySystem(keySystemId, mediaOption, isKeySystemSupportedPromises); + const p = forkJoin(isKeySystemSupportedPromises).pipe(map((results) => { + // If no unsupported config found then we're good + if (results.find((supported) => supported === false) === undefined) { + return mediaOption; + } + })); + isSupported.push(p); + }); + return forkJoin(isSupported).pipe(map((results) => { + return results.filter((r) => Boolean(r)); + })); + } + /** + * Use MediaCapabilities API to determine whether we can play this. + * @param mediaOptions + * @param audioMediaOptions + */ + function filterBasedOnMediaCapabilities(mediaOptions, audioMediaOptions, logger) { + logger.debug(loggerName$1, 'Using MediaCapabilities'); + const observables = []; + const isSupportedInternal = createIsSupportedInternal(); + const handleCodec = createHandleCodec(logger); + mediaOptions.forEach((mediaOption) => { + var _a, _b; + let isTypeSupportedObservables = []; + (_a = mediaOption.videoCodecList) === null || _a === void 0 ? void 0 : _a.forEach((codec) => { + isTypeSupportedObservables = handleCodec(mediaOption, audioMediaOptions, codec, true, isTypeSupportedObservables); + }); + if (((_b = mediaOption.audioCodecList) === null || _b === void 0 ? void 0 : _b.length) > 0) { + const codec = RichestMedia.getRichestAudioCodec(mediaOption.audioCodecList); + isTypeSupportedObservables = handleCodec(mediaOption, audioMediaOptions, codec, false, isTypeSupportedObservables); + } + let o = of(mediaOption); + if (isTypeSupportedObservables.length > 0) { + o = forkJoin(isTypeSupportedObservables).pipe(map((results) => { + const supported = results.find((supported) => supported === false) == undefined; + if (!supported) { + printMediaOptionInfo(mediaOption, logger); + } + return supported ? mediaOption : null; + }), catchError((error) => { + logger.warn(loggerName$1, `decodingInfo errror: ${error.message}`); // Missing field probably + const supported = isSupportedInternal(mediaOption); + if (!supported) { + printMediaOptionInfo(mediaOption, logger); + } + return of(supported ? mediaOption : null); + })); + } + observables.push(o); + }); + return forkJoin(observables).pipe(map((list) => list.filter((item) => Boolean(item)))); + } + function filterMediaOptionsBasedOnAudioAndVideoCodecs(mediaOptions, logger) { + const isSupportedInternal = createIsSupportedInternal(); + const filteredMediaOptions = mediaOptions.filter(isSupportedInternal); + filterMediaOptionInfoPrint('Platform Supported Media Codec', mediaOptions, filteredMediaOptions, logger); + return filteredMediaOptions; + } + function filterMediaOptionsBasedOnExtendedAudioParameters(mediaOptions, audioMediaOptions, logger) { + const supportedMimeCodecs = new Set(); + const unsupportedMimeCodecs = new Set(); + /* Intentional negative tests to identify platform support for 'channels' and 'features' attributes via isTypeSupported(). + - If the platform supports 'channels' & 'features' attributes, then the below calls will return false. + - Otherwise, if we get true, that means the platform ignores the 'channels' and/or 'features' attribute and we cannot rely on this API for testing them. + */ + const shouldCheckChannels = !MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.2"; channels="-1"'); + const shouldCheckFeatures = shouldCheckChannels && !MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.2"; channels="2"; features="INVALID"'); + logger.info(loggerName$1, `Platform support for channels: ${shouldCheckChannels}; features: ${shouldCheckFeatures}`); + const checkSupported = (codec, channels) => { + const parameters = channels.split('/'); + const channelCount = parseInt(parameters[0]); + let mimeCodec; + let mimeCodecAlternate; + if (parameters.length > 1) { + const features = parameters[1].split(',')[0]; // 'features' is the first in the comma separated list. + mimeCodec = `audio/mp4;codecs="${codec}";channels="${channelCount}";features="${features}"`; + mimeCodecAlternate = `audio/mp4;codecs="${codec}";channels="8";features="${features}"`; + } + else { + mimeCodec = `audio/mp4;codecs="${codec}";channels="${channelCount}"`; + } + let isSupported = MediaSource.isTypeSupported(mimeCodec); + // LG doesn't return isTypeSupported correctly for 16ch ATMOS. This workaround uses 8ch test for ATMOS support. + // This code should be removed when LG firmware fix is in place. + if (!isSupported && mimeCodecAlternate) { + isSupported = MediaSource.isTypeSupported(mimeCodecAlternate); + logger.info(loggerName$1, `Using mimeCodecAlternate, isSupported: ${isSupported}; mimeCodecAlternate: ${mimeCodecAlternate}`); + } + return isSupported; + }; + const updateCachedMimeCodecSetsIfNecessary = (codec, channels) => { + const mimeCodec = `${codec}/${channels}`; + if (!supportedMimeCodecs.has(mimeCodec) && !unsupportedMimeCodecs.has(mimeCodec)) { + if (checkSupported(codec, channels)) { + supportedMimeCodecs.add(mimeCodec); + } + else { + unsupportedMimeCodecs.add(mimeCodec); + } + } + }; + // Update the mimeCodec support/notSupport cache based on MediaSource support. + // After that verify if that mimeCodec falls into unsupported category. + const checkUnsupportedMimeCodec = (codec, channels, logger) => { + const isAtmos = MediaUtil.isDolbyAtmos(codec, channels); + if (shouldCheckFeatures || (shouldCheckChannels && !isAtmos)) { + // check for platform support + updateCachedMimeCodecSetsIfNecessary(codec, channels); + const mimeCodec = `${codec}/${channels}`; + return unsupportedMimeCodecs.has(mimeCodec); + } + else { + // Don't allow ATMOS if we cannot reliably check support via MediaSource.isTypeSupported() + // All other cases are already handled via codec support + return isAtmos ? true : false; + } + }; + const filteredMediaOptions = mediaOptions.filter((mediaOption) => { + let foundUnsupportedMimeCodec = false; + // Extended parameters are valid only if there is an audio group + if (mediaOption.audioCodecList && mediaOption.audioGroupId) { + const channels = RichestMedia.getRichestChannelLayoutForGroupId(mediaOption.audioGroupId, audioMediaOptions); + if (mediaOption.audioCodecList.length > 0 && channels) { + // pick the highest ranking audio codec to match with the channels tag + const richestCodec = RichestMedia.getRichestAudioCodec(mediaOption.audioCodecList); + // check only if channels attribute is present, otherwise, the case is already handled through audio codecs + foundUnsupportedMimeCodec = checkUnsupportedMimeCodec(richestCodec, channels); + } + } + return !foundUnsupportedMimeCodec; + }); + filterMediaOptionInfoPrint('Richest Audio Codec Selection', mediaOptions, filteredMediaOptions, logger); + return filteredMediaOptions; + } + function getCapsForMediaOption(mediaOption, platformInfo) { + if (!platformInfo) { + return { + highestPlayableAverageBitRate: undefined, + highestPlayablePeakBitRate: undefined, + highestPlayableWidth: undefined, + highestPlayableHeight: undefined, + highestPlayableFrameRate: undefined, + }; + } + const firstMediaOptionCodec = mediaOption.videoCodec; + const firstMediaOptionVideoRange = mediaOption.videoRange; + const videoDynamicRangeFormats = platformInfo.videoDynamicRangeFormats; + const videoCodecs = platformInfo.videoCodecs; + const vdrType = MediaUtil.getDynamicRangeType(firstMediaOptionVideoRange, firstMediaOptionCodec); + const compressionType = MediaUtil.getCompressionType(firstMediaOptionCodec); + const caps = getCappingInfo(vdrType, compressionType, videoCodecs, videoDynamicRangeFormats); + // Ignore highestPlayablePeakBitRateForClearContent for all codecs and formats except VP9 + if (compressionType !== CompressionType.VP09) { + caps.highestPlayablePeakBitRateForClearContent = undefined; + } + return caps; + } + function filterMediaOptionsByCaps(mediaOptions, sessionKeys, platformInfo, logger) { + const hasSessionKeys = (sessionKeys === null || sessionKeys === void 0 ? void 0 : sessionKeys.length) > 0; + const filteredMediaOptions = mediaOptions.filter((mediaOption) => { + const caps = getCapsForMediaOption(mediaOption, platformInfo); + const { highestPlayablePeakBitRateForClearContent } = caps; + // Use highestPlayablePeakBitRate|highestPlayablePeakBitRateForClearContent based on the presence of sessionKeys or allowedCPCMap which we assume means contents are encrypted + const assumeEncryptedContent = mediaOption.allowedCPCMap || hasSessionKeys; + const isWithinSafePeekBitRate = isWithinCap(mediaOption.bandwidth, caps.highestPlayablePeakBitRate); + const isWithinPeekBitRate = assumeEncryptedContent || !highestPlayablePeakBitRateForClearContent + ? isWithinSafePeekBitRate + : isWithinSafePeekBitRate || isWithinCap(mediaOption.bandwidth, highestPlayablePeakBitRateForClearContent); + return (isWithinPeekBitRate && + isWithinCap(mediaOption.avgBandwidth, caps.highestPlayableAverageBitRate) && + isWithinCap(mediaOption.width, caps.highestPlayableWidth) && + isWithinCap(mediaOption.height, caps.highestPlayableHeight) && + isWithinCap(mediaOption.frameRate, caps.highestPlayableFrameRate)); + }); + filterMediaOptionInfoPrint('Highest Playable Platform Caps', mediaOptions, filteredMediaOptions, logger); + return filteredMediaOptions; + } + function filterIframeMediaOptionsBasedOnCapOn1080p(mediaOptions, logger) { + // standard 1080p resolution with a slight tolerance of 1.2 + const PIXELS_CAP = 2488320; + const filteredMediaOptions = mediaOptions.filter((mediaOption) => !mediaOption.iframes || !mediaOption.width || !mediaOption.height || mediaOption.width * mediaOption.height <= PIXELS_CAP); + filterMediaOptionInfoPrint('1080p iFrame', mediaOptions, filteredMediaOptions, logger); + return filteredMediaOptions; + } + function filterMediaOptionsBasedOnSupportedVideoFormats(mediaOptions, videoDynamicRangeFormats, logger) { + const supportedFormats = getSupportedVideoFormats(videoDynamicRangeFormats); + const { doViSupported, hdr10Supported, hlgSupported } = supportedFormats; + logger.info(loggerName$1, `Supported videoDynamicRangeFormats DoVi/HDR10/HLG: ${doViSupported}/${hdr10Supported}/${hlgSupported}`); + // filter based on supported videoDynamicRangeFormats + // only keep level with correct codec for video-range + const validMediaOptions = mediaOptions.reduce((prev, option) => { + var _a; + const vdr = MediaUtil.getDynamicRangeType(option.videoRange, (_a = option.videoCodec) !== null && _a !== void 0 ? _a : ''); + switch (vdr) { + case VideoDynamicRangeType.HDR: + case VideoDynamicRangeType.HDR10: + if (hdr10Supported) { + prev.hdrMediaOptions.push(option); + } + break; + case VideoDynamicRangeType.DolbyVision: + if (doViSupported) { + prev.hdrMediaOptions.push(option); + } + break; + case VideoDynamicRangeType.HLG: + if (hlgSupported) { + prev.hdrMediaOptions.push(option); + } + break; + default: + // default is SDR + if (option.videoRange === 'SDR' || option.videoRange == null) { + prev.sdrMediaOptions.push(option); + } + } + return prev; + }, { hdrMediaOptions: new Array(), sdrMediaOptions: new Array() }); + logger.debug(loggerName$1, `HDR/SDR mediaOptions: ${validMediaOptions.hdrMediaOptions.length}/${validMediaOptions.sdrMediaOptions.length}`); + return validMediaOptions; + } + /** + * Filter root playlist. Remove all media options that should not ever be used on this platform based on + * capabilities (platformInfo and MediaCapabilities) + * + * @param mediaOptions Original mediaOption list + * @param audioMediaOptions Alternate mediaOption info + * @param platformInfo Platform information for filtering out media options + * @param config HLS Config option + * @returns { hdrMediaOptions: valid hdr media options, sdrMediaOptions: valid sdr media options } + */ + function filterByPlatformCapabilities(mediaOptions, audioMediaOptions, sessionKeys, platformInfo, config, logger) { + const maxHdcpLevel = (platformInfo === null || platformInfo === void 0 ? void 0 : platformInfo.maxHdcpLevel) || undefined; + let filteredMediaOptions = [...mediaOptions]; + if (config.disableVideoCodecList.size > 0 || config.disableAudioCodecList.size > 0) { + filteredMediaOptions = filterMediaOptionsBasedOnHlsConfig(filteredMediaOptions, config.disableVideoCodecList, config.disableAudioCodecList, logger); + } + if (maxHdcpLevel && isHdcpLevel(maxHdcpLevel)) { + filteredMediaOptions = filterMediaOptionsBasedOnMaxAllowedHdcpLevel(filteredMediaOptions, maxHdcpLevel, logger); + } + // Filter based on ALLOWED-CPC + const maxSecurityLevel = platformInfo === null || platformInfo === void 0 ? void 0 : platformInfo.maxSecurityLevel; + const keySystemId = config === null || config === void 0 ? void 0 : config.keySystemPreference; + if (maxSecurityLevel && keySystemId && isValidSecurityLevel(maxSecurityLevel, keySystemId)) { + filteredMediaOptions = filterMediaOptionsBasedOnSecurityLevel(filteredMediaOptions, maxSecurityLevel, keySystemId, logger); + } + // parse and set audioChannelCount property + filteredMediaOptions = filteredMediaOptions.map((mediaOption) => { + if (mediaOption.audioCodecList && mediaOption.audioGroupId) { + const matchingTrack = audioMediaOptions.find((audio) => audio.groupId === mediaOption.audioGroupId); + const channels = matchingTrack === null || matchingTrack === void 0 ? void 0 : matchingTrack.channels; + if (channels) { + mediaOption.audioChannelCount = parseInt(channels); + } + } + return mediaOption; + }); + const useMediaKeySystemAccessFilter = (config === null || config === void 0 ? void 0 : config.useMediaKeySystemAccessFilter) || false; + const keySystemAccessEnabled = useMediaKeySystemAccessFilter && keySystemId && navigator && typeof navigator.requestMediaKeySystemAccess === 'function'; + const source = keySystemAccessEnabled ? filterMediaOptionsBasedOnMediaKeySystemAccess(filteredMediaOptions, keySystemId, logger) : of(filteredMediaOptions); + return source.pipe(switchMap((keySystemMediaOptions) => { + if (keySystemMediaOptions.length === 0 || onlyIframes(keySystemMediaOptions)) { + throw new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR, undefined, 'no media option with compatible codecs found in playlist', undefined); + } + if (keySystemAccessEnabled) { + filterMediaOptionInfoPrint('Key System Support', filteredMediaOptions, keySystemMediaOptions, logger); + } + const mediaCapabilities = navigator && navigator.mediaCapabilities; + const useMediaCapabilities = (config === null || config === void 0 ? void 0 : config.useMediaCapabilities) || false; + const mediaCapabilitiesEnabled = useMediaCapabilities && mediaCapabilities && typeof mediaCapabilities.decodingInfo === 'function'; + let source; + if (mediaCapabilitiesEnabled) { + source = filterBasedOnMediaCapabilities(keySystemMediaOptions, audioMediaOptions, logger); + } + else { + keySystemMediaOptions = filterMediaOptionsBasedOnAudioAndVideoCodecs(keySystemMediaOptions, logger); + keySystemMediaOptions = filterMediaOptionsBasedOnExtendedAudioParameters(keySystemMediaOptions, audioMediaOptions, logger); + source = of(keySystemMediaOptions); + } + return source.pipe(map((compatibleMediaOptions) => { + if (compatibleMediaOptions.length === 0 || onlyIframes(compatibleMediaOptions)) { + throw new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR, undefined, 'no media option with compatible codecs found in manifest', undefined); + } + compatibleMediaOptions = filterMediaOptionsByCaps(compatibleMediaOptions, sessionKeys, platformInfo, logger); + compatibleMediaOptions = filterIframeMediaOptionsBasedOnCapOn1080p(compatibleMediaOptions, logger); + if (compatibleMediaOptions.length === 0 || onlyIframes(compatibleMediaOptions)) { + throw new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR, undefined, 'no media option with compatible codecs found in manifest', undefined); + } + // Seperate out fallback mediaOptions if needed + let videoDynamicRangeFormats = (platformInfo === null || platformInfo === void 0 ? void 0 : platformInfo.videoDynamicRangeFormats) || []; + if (mediaCapabilitiesEnabled && videoDynamicRangeFormats.length === 0) { + // Just allow all types; MediaCapabilities API should have filtered out anything that was unsupported + videoDynamicRangeFormats = [ + { type: VideoDynamicRangeType.SDR }, + { type: VideoDynamicRangeType.HDR }, + { type: VideoDynamicRangeType.HDR10 }, + { type: VideoDynamicRangeType.DolbyVision }, + { type: VideoDynamicRangeType.HLG }, + ]; + } + const { hdrMediaOptions, sdrMediaOptions } = filterMediaOptionsBasedOnSupportedVideoFormats(compatibleMediaOptions, videoDynamicRangeFormats, logger); + if ((hdrMediaOptions.length === 0 && sdrMediaOptions.length === 0) || (onlyIframes(hdrMediaOptions) && onlyIframes(sdrMediaOptions))) { + throw new PlaylistParsingError(ErrorTypes.MEDIA_ERROR, ErrorDetails.MANIFEST_INCOMPATIBLE_VIDEO_RANGE_ERROR, undefined, 'mediaOption with compatible VIDEO-RANGE not found in manifest', undefined); + } + return { hdrMediaOptions, sdrMediaOptions }; + }), catchError((err) => { + if (err instanceof PlaylistParsingError) { + err.fatal = true; + err.response = ErrorResponses.IncompatibleAsset; + } + throw err; + })); + })); + } + + function mediaOptionToString(mediaOption) { + const MediaOptionLogAttributes = [ + 'persistentId', + 'bitrate', + 'bandwidth', + 'avg-bandwidth', + 'width', + 'height', + 'videoCodec', + 'audioCodec', + 'videoRange', + 'iframes', + 'frameRate', + 'audioGroupId', + 'score', + ]; + return JSON.stringify(mediaOption, MediaOptionLogAttributes); + } + + function isValidCandidate(fromTrack, candidate) { + // Same persistentID but different rendition group + return candidate.mediaOptionId !== fromTrack.mediaOptionId && candidate.persistentID === fromTrack.persistentID && candidate.groupId !== fromTrack.groupId; + } + class AlternateMediaOptionListQuery extends MediaOptionListQuery { + constructor(store, itemId, mediaOptionType) { + super(store, itemId, mediaOptionType); + } + static makeFilters() { + return makeCommonFilters(); + } + _initFilters() { + return AlternateMediaOptionListQuery.kAllowFilters; + } + // For convenience + get _mediaOptionType() { + return this.mediaOptionType; + } + get preferredHost() { + return null; + } + get preferredHost$() { + return of(null); + } + get mediaOptionListInfo() { + var _a, _b; + return (_b = (_a = this.getEntity(this.itemId)) === null || _a === void 0 ? void 0 : _a.mediaOptionListTuple[this._mediaOptionType]) !== null && _b !== void 0 ? _b : null; + } + get mediaOptionListInfo$() { + return this.selectEntity(this.itemId, (entity) => (entity && entity.mediaOptionListTuple ? entity.mediaOptionListTuple[this._mediaOptionType] : null)).pipe(filterNullOrUndefined()); + } + // excludingVariants for skipping variants visited in successive getFallbackVariant; not applicable to alternates + // since we are looking for a *variant* fallback + getFallbackVariant(fromId, sdrOnly, shouldSwitchHosts, excludingVariants = undefined) { + var _a, _b; + const fromTrack = (_a = this.mediaOptionList) === null || _a === void 0 ? void 0 : _a.find((track) => track.mediaOptionId === fromId); + if (!fromTrack) { + return null; + } + const filteredList = this.filteredMediaOptionList; + if (!filteredList) { + return null; + } + // If shouldSwitchHosts is true, we must switch hosts + const fromHost = getHostName(fromTrack.url); + if (shouldSwitchHosts) { + return (_b = filteredList.find((candidate) => isValidCandidate(fromTrack, candidate) && !hasMatchingHost(fromHost, candidate.url))) !== null && _b !== void 0 ? _b : null; + } + // else, allow any host but favor current if available + let newTrack = null; + for (const candidate of filteredList) { + if (isValidCandidate(fromTrack, candidate) && (!newTrack || hasMatchingHost(fromHost, candidate.url))) { + newTrack = candidate; + } + } + return newTrack; + } + // excludingOptions for skipping soon-to-be-penalized alternates + getMatchingAlternateWithPersistentId(persistentId, variant, excludingOptions) { + var _a; + return ((_a = this.preferredMediaOptionList.find((option) => { + if ((excludingOptions === null || excludingOptions === void 0 ? void 0 : excludingOptions.length) > 0 && excludingOptions.includes(option.mediaOptionId)) { + return false; + } + if (!isFiniteNumber(persistentId) || option.persistentID === persistentId) { + if (variant) { + // match group and persistent id + return this.matchGroup(option, variant.audioGroupId, variant.subtitleGroupId, variant.closedcaption); + } + else { + // match only persistent id + return true; + } + } + else { + return false; + } + })) !== null && _a !== void 0 ? _a : null); + } + matchGroup(mediaOption, audioGroup, subtitleGroup, closedCaptionGroup) { + let result = false; + switch (mediaOption.type) { + case 'CLOSED-CAPTIONS': + result = !closedCaptionGroup || mediaOption.groupId === closedCaptionGroup; + break; + case 'SUBTITLES': + result = !subtitleGroup || mediaOption.groupId === subtitleGroup; + break; + case 'AUDIO': + result = !audioGroup || mediaOption.groupId === audioGroup; + break; + } + return result; + } + getMatchingAlternate(fromId, variant) { + const fromAlternate = this.mediaOptionFromId(fromId); + return this.getMatchingAlternateWithPersistentId(fromAlternate === null || fromAlternate === void 0 ? void 0 : fromAlternate.persistentID, variant, []); + } + /** + * Package Alternate media Option + * Augment closed-captions mediaOption with the playlist URL of a supporting subtitle mediaOption. + * This allows Apple-style closed-caption track to include forced subtitles from the supporting WebVTT playlist. + * + * @param variantOption The variantMediaOption that is to be augmented. + * @param altOption The alternate media option (has to be of type closed caption) to be augmented + * @param useFilteredList boolean if true use a filtered list for packaging, hence do not include media in penalty Box + * if false use an unfiltered raw list as seen from the manifest. + * @return AlternateMediaOption A packaged alternate media option or altOption if packaging was not possible + */ + packageAlternateMediaOption(variantOption, altOption, useFilteredList) { + return altOption.mediaType === MediaTypeFourCC.CLOSEDCAPTION ? this.augmentClosedCaptionsWithForcedSubtitles(variantOption === null || variantOption === void 0 ? void 0 : variantOption.subtitleGroupId, altOption, useFilteredList) : altOption; + } + augmentClosedCaptionsWithForcedSubtitles(subtitleGroup, closedCaptionMediaOption, useFilteredList) { + const forcedMediaOption = this.pairForcedSubtitleMediaOptionWithClosedCaption(subtitleGroup, closedCaptionMediaOption, useFilteredList); + return forcedMediaOption ? Object.assign(Object.assign({}, closedCaptionMediaOption), { url: forcedMediaOption.url, backingMediaOptionId: forcedMediaOption.mediaOptionId }) : closedCaptionMediaOption; + } + pairForcedSubtitleMediaOptionWithClosedCaption(subtitleGroup, selectedMediaOption, useFilteredList) { + let supportingOption; + if (selectedMediaOption && selectedMediaOption.mediaType === MediaTypeFourCC.CLOSEDCAPTION) { + let list = this.mediaOptionList; + if (useFilteredList) { + list = this.preferredMediaOptionList; + } + supportingOption = AlternateMediaOptionListQuery.pairForcedSubtitleMediaOptionWithClosedCaptionInList(subtitleGroup, selectedMediaOption, list); + } + return supportingOption; + } + static pairForcedSubtitleMediaOptionWithClosedCaptionInList(subtitleGroup, selectedMediaOption, mediaOptionList) { + return mediaOptionList.find(function (option) { + const match = option.mediaType === MediaTypeFourCC.SUBTITLE && option.lang === selectedMediaOption.lang && option.forced && option.autoselect && (!subtitleGroup || option.groupId === subtitleGroup); + if (match) { + getLogger().debug(`[subtitle] pick side track persistent id ${option.persistentID} option id ${option.id} option mediaOptionId ${option.mediaOptionId} group id ${option.groupId} (=${subtitleGroup})`); + } + return match; + }); + } + } + AlternateMediaOptionListQuery.kAllowFilters = AlternateMediaOptionListQuery.makeFilters(); + + /** + * @brief Query interface to the root playlist store + */ + class RootPlaylistQuery extends QueryEntity { + constructor(rootPlaylistStore, itemId) { + super(rootPlaylistStore); + this.itemId = itemId; + this.mediaOptionListQueries = [ + new VariantMediaOptionListQuery(rootPlaylistStore, this.itemId), + new AlternateMediaOptionListQuery(rootPlaylistStore, this.itemId, MediaOptionType.AltAudio), + new AlternateMediaOptionListQuery(rootPlaylistStore, this.itemId, MediaOptionType.Subtitle), + ]; + } + // getters + get rootPlaylistEntity() { + return this.getEntity(this.itemId); + } + /** + * @returns the unmodified original media options without filters applied + */ + get rootMediaOptionsTuple() { + var _a; + const mediaOptionListTuple = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.mediaOptionListTuple; + if (mediaOptionListTuple) { + return [mediaOptionListTuple[0].mediaOptions, mediaOptionListTuple[1].mediaOptions, mediaOptionListTuple[2].mediaOptions]; + } + return [[], [], []]; + } + /** + * @returns the position in media corresponding to the start of this item + */ + get itemStartOffset() { + var _a, _b, _c; + if (((_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.itemStartOffset) && isFiniteNumber((_b = this.rootPlaylistEntity) === null || _b === void 0 ? void 0 : _b.itemStartOffset)) { + return (_c = this.rootPlaylistEntity) === null || _c === void 0 ? void 0 : _c.itemStartOffset; + } + return 0; + } + get highestVideoCodec() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.highestVideoCodec; + } + get baseUrl() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.baseUrl; + } + get anchorTime() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.anchorTime; + } + get discoSeqNum() { + var _a, _b; + return (_b = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.discoSeqNum) !== null && _b !== void 0 ? _b : NaN; + } + get discoSeqNum$() { + return this.selectEntity(this.itemId, 'discoSeqNum'); + } + get audioMediaSelectionGroup() { + var _a, _b; + return (_b = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.audioMediaSelectionGroup) !== null && _b !== void 0 ? _b : null; + } + get subtitleMediaSelectionGroup() { + var _a, _b; + return (_b = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.subtitleMediaSelectionGroup) !== null && _b !== void 0 ? _b : null; + } + get audioMediaSelectionOptions() { + var _a, _b, _c; + return (_c = (_b = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.audioMediaSelectionGroup) === null || _b === void 0 ? void 0 : _b.MediaSelectionGroupOptions) !== null && _c !== void 0 ? _c : []; + } + get subtitleMediaSelectionOptions() { + var _a, _b, _c; + return (_c = (_b = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.subtitleMediaSelectionGroup) === null || _b === void 0 ? void 0 : _b.MediaSelectionGroupOptions) !== null && _c !== void 0 ? _c : []; + } + get contentSteeringOption() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.contentSteeringOption; + } + get masterVariableList() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.masterVariableList; + } + get loadStats() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.loadStats; + } + get isMediaPlaylist() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.isMediaPlaylist; + } + getInitPTS(discoSeqNum) { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.initPtsRecord[discoSeqNum]; + } + get abrStatus$() { + return this.selectEntity(this.itemId, (entity) => entity === null || entity === void 0 ? void 0 : entity.abrStatus); + } + get abrStatus() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.abrStatus; + } + get nextMaxAutoOptionId() { + var _a, _b; + return (_b = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.abrStatus) === null || _b === void 0 ? void 0 : _b.nextMaxAutoOptionId; + } + get nextMinAutoOptionId() { + var _a, _b; + return (_b = (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.abrStatus) === null || _b === void 0 ? void 0 : _b.nextMinAutoOptionId; + } + initPTS$(discoSeqNum) { + return this.selectEntity(this.itemId, ({ initPtsRecord }) => initPtsRecord[discoSeqNum]); + } + // observables + get rootPlaylistEntity$() { + return this.selectEntity(this.itemId).pipe(filter((rootEntity) => Boolean(rootEntity)), map((rootEntity) => rootEntity)); + } + get rootPlaylistEntityAdded$() { + return this.selectEntityAction(EntityActions.Add).pipe(map((itemIds) => itemIds.map((itemId) => this.getEntity(itemId)))); + } + /** + * @returns the unmodified original media options without filters applied + */ + get rootMediaOptionsTuple$() { + return combineQueries([ + this.selectEntity(this.itemId, (entity) => entity.mediaOptionListTuple[0].mediaOptions), + this.selectEntity(this.itemId, (entity) => entity.mediaOptionListTuple[1].mediaOptions), + this.selectEntity(this.itemId, (entity) => entity.mediaOptionListTuple[2].mediaOptions), + ]); + } + get sessionData() { + var _a; + return (_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.sessionData; + } + get sessionData$() { + return this.selectEntity(this.itemId, ({ sessionData }) => sessionData).pipe(filterNullOrUndefined()); + } + get anchorTime$() { + return this.selectEntity(this.itemId, 'anchorTime').pipe(switchMap((anchorTime) => { + var _a, _b; + if (!isFiniteNumber(anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.pos)) { + return EMPTY; + } + if ((anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.pos) !== ((_a = this.anchorTime) === null || _a === void 0 ? void 0 : _a.pos)) { + // Kind of hacky but sometimes this happens???? + getLogger().warn(`anchorTime doesn't match stored value! ${anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.pos} !== ${(_b = this.anchorTime) === null || _b === void 0 ? void 0 : _b.pos}`); + return EMPTY; + } + return of(anchorTime); + })); + } + get pendingSeek$() { + return this.selectEntity(this.itemId, ({ pendingSeek }) => pendingSeek).pipe(distinctUntilChanged((a, b) => a === b || (typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b)))); + } + get enabledMediaOptionKeys$() { + return this.selectEntity(this.itemId, 'enabledMediaOptionKeys').pipe(filter((keys) => Boolean(keys))); + } + get enabledMediaOptionKeys() { + var _a, _b; + return (_b = (_a = this.getEntity(this.itemId)) === null || _a === void 0 ? void 0 : _a.enabledMediaOptionKeys) !== null && _b !== void 0 ? _b : [NoMediaOption, NoMediaOption, NoMediaOption]; + } + get enabledMediaOptionSwitchContexts() { + var _a, _b; + return (_b = (_a = this.getEntity(this.itemId)) === null || _a === void 0 ? void 0 : _a.mediaOptionSwitchContexts) !== null && _b !== void 0 ? _b : [null, null, null]; + } + enabledMediaOptionSwitchContextsByType$(mediaOptionType) { + return this.selectEntity(this.itemId, 'mediaOptionSwitchContexts').pipe(map((contexts) => contexts === null || contexts === void 0 ? void 0 : contexts[mediaOptionType])); + } + get enabledMediaOptions$() { + return combineQueries([ + this.enabledMediaOptionByType$(MediaOptionType.Variant), + this.enabledMediaOptionByType$(MediaOptionType.AltAudio), + this.enabledMediaOptionByType$(MediaOptionType.Subtitle), + ]); + } + // Convenience method for just A/V + get enabledAVOptions$() { + return combineQueries([this.enabledMediaOptionByType$(MediaOptionType.Variant), this.enabledMediaOptionByType$(MediaOptionType.AltAudio)]); + } + rawEnabledMediaOptionByType$(mediaOptionType) { + return this.enabledMediaOptionKeys$.pipe(map((enabledMediaOptionKeys) => { + const mediaOptionKey = enabledMediaOptionKeys[mediaOptionType]; + if (!isEnabledMediaOption(mediaOptionKey)) { + // return NoMediaOption even if mediaOptionKey may have a valid itemId. + // callers typically check for NoMediaOption only to see if a track is disabled. + return NoMediaOption; + } + const options = this.rootMediaOptionsTuple[mediaOptionType]; + const foundOption = options.find((option) => mediaOptionKeyEquals(option, mediaOptionKey)); + return foundOption ? foundOption : NoMediaOption; + })); + } + enabledMediaOptionByType$(mediaOptionType) { + return this.rawEnabledMediaOptionByType$(mediaOptionType).pipe(distinctUntilChanged((a, b) => a.mediaOptionId === b.mediaOptionId && a.url === b.url)); + } + /** + * Emits when selected option changes and returns switch information + */ + enabledMediaOptionSwitchForType$(mediaOptionType) { + // Only trigger on option change, not when context is set + // rawEnabledMediaOptionByType does not de-dupe mediaOption changes + // so it's possible to snapshot/represent a switch to the same mediaOption { fromId: sameMediaOptionId, toId: sameMediaOptionId } + // when this happens, the observer will know no switching took place and it won't trigger any change event. + // enabledMediaOptionByType will always return a stale mediaOption switch from previous activities, + // potentially causing bogus emits and event triggers. + return this.rawEnabledMediaOptionByType$(mediaOptionType).pipe(withLatestFrom(this.enabledMediaOptionSwitchContextsByType$(mediaOptionType)), startWith(null), pairwise(), map(([a, b]) => { + return { fromId: a === null || a === void 0 ? void 0 : a[0].mediaOptionId, toId: b === null || b === void 0 ? void 0 : b[0].mediaOptionId, switchContext: b === null || b === void 0 ? void 0 : b[1] }; + }), distinctUntilChanged((x, y) => x.fromId === y.fromId && x.toId === y.toId)); + } + enableMediaOptionSwitchedForType$(mediaOptionType) { + return this.enabledMediaOptionByType$(mediaOptionType).pipe(switchMap((mediaOption) => waitFor(combineLatest([of(mediaOption), this.enabledMediaOptionSwitchContextsByType$(mediaOptionType).pipe(pairwise())]), ([option, contexts]) => contexts[0] && !contexts[1])), + // drop the contexts because contexts[0] may be wrong in this sequence: + // 1. Request 1: setEnabledMediaOptions( englishMediaOption, { switchPosition: 0.0 }); + // 2. Request 2: setEnabledMediaOptions( englishMediaOption, { switchPosition: 1.0 }); + // 3. Request 2 succeeded: setEnabledMediaOptions( englishMediaOption, null); + // But this function will return [englishMediaOption, [{ switchPosition: 0.0 }, null]] + // Nonetheless, englishMediaOption did switch successfully. + map(([option]) => option)); + } + enabledMediaOptionIdByType(mediaOptionType) { + return this.getEntity(this.itemId).enabledMediaOptionKeys[mediaOptionType].mediaOptionId; + } + get enabledVariantMediaOptionIdBeforeTrickplaySwitch() { + return this.getEntity(this.itemId).enabledVariantMediaOptionIdBeforeTrickplaySwitch; + } + variantMediaOptionById(mediaOptionId) { + return this.mediaOptionListQueries[MediaOptionType.Variant].mediaOptionFromId(mediaOptionId); + } + alternateMediaOptionById(mediaOptionType, mediaOptionId) { + return this.mediaOptionListQueries[mediaOptionType].mediaOptionFromId(mediaOptionId); + } + enabledAlternateMediaOptionByType(mediaOptionType) { + const enabledOptionId = this.enabledMediaOptionIdByType(mediaOptionType); + return this.alternateMediaOptionById(mediaOptionType, enabledOptionId); + } + get enabledVariantMediaOption() { + const enabledOptionId = this.enabledMediaOptionIdByType(MediaOptionType.Variant); + return this.variantMediaOptionById(enabledOptionId); + } + lastLoadedMediaOptionByType(mediaOptionType) { + var _a; + return (_a = this.getEntity(this.itemId).lastLoadedMediaOptionKeys) === null || _a === void 0 ? void 0 : _a[mediaOptionType]; + } + /** + * Set by ABR and error handling. Next enabled media options to be used next time we are allowed to switch + */ + get nextMediaOptionsKeys$() { + return this.selectEntity(this.itemId, 'nextMediaOptionKeys'); + } + /** + * Return the filtered list with preferred host filtering + */ + get preferredMediaOptions() { + return [this.mediaOptionListQueries[0].preferredMediaOptionList, this.mediaOptionListQueries[1].preferredMediaOptionList, this.mediaOptionListQueries[2].preferredMediaOptionList]; + } + get preferredMediaOptions$() { + return combineQueries([ + this.mediaOptionListQueries[0].preferredMediaOptionList$, + this.mediaOptionListQueries[1].preferredMediaOptionList$, + this.mediaOptionListQueries[2].preferredMediaOptionList$, + ]); + } + get filteredMediaOptions() { + return [this.mediaOptionListQueries[0].filteredMediaOptionList, this.mediaOptionListQueries[1].filteredMediaOptionList, this.mediaOptionListQueries[2].filteredMediaOptionList]; + } + getDisabledMediaOption(mediaOptionType) { + return { itemId: this.itemId, mediaOptionType, mediaOptionId: 'Nah' }; + } + getEnabledMediaOptionMask() { + return this.enabledMediaOptionKeys.map((key) => isEnabledMediaOption(key)); + } + /** + * Get filtered list with preferred host filtering by type + * @param mediaOptionType The type to get info about + */ + getPreferredMediaOptionsByType$(mediaOptionType) { + return this.mediaOptionListQueries[mediaOptionType].preferredMediaOptionList$; + } + altMediaOptionHasValidUrl(mediaOptionType, mediaOptionId) { + const altOption = this.alternateMediaOptionById(mediaOptionType, mediaOptionId); + return Boolean(altOption === null || altOption === void 0 ? void 0 : altOption.url); + } + /** + * Return whether the preferred variant set is HDR + */ + get hdrMode$() { + return this.mediaOptionListQueries[MediaOptionType.Variant].hdrMode$; + } + get maxHdcpLevel$() { + return this.mediaOptionListQueries[MediaOptionType.Variant].maxHdcpLevel$; + } + get currentPathwayID() { + return this.mediaOptionListQueries[MediaOptionType.Variant].currentPathwayID; + } + get preferredHost() { + return this.mediaOptionListQueries[MediaOptionType.Variant].preferredHost; + } + /** + * Get error info by type + * @param mediaOptionType The type to get info about + */ + getErrorInfoByType(mediaOptionType) { + var _a; + if (((_a = this.rootPlaylistEntity) === null || _a === void 0 ? void 0 : _a.errorsByType) != null) { + return this.rootPlaylistEntity.errorsByType[mediaOptionType]; + } + return null; + } + getInFlightFragByType(mediaOptionType) { + var _a, _b, _c; + return (_c = (_b = (_a = this.getEntity(this.itemId)) === null || _a === void 0 ? void 0 : _a.inFlightFrags) === null || _b === void 0 ? void 0 : _b[mediaOptionType]) !== null && _c !== void 0 ? _c : null; + } + getInFlightFragByType$(mediaOptionType) { + return this.selectEntity(this.itemId, (entity) => { var _a; return (_a = entity === null || entity === void 0 ? void 0 : entity.inFlightFrags) === null || _a === void 0 ? void 0 : _a[mediaOptionType]; }); + } + matchAlternates(currentVariant, audioPersistentId, subtitlePersistentId, excludingOptions) { + const audioAltMediaOption = isFiniteNumber(audioPersistentId) + ? this.mediaOptionListQueries[MediaOptionType.AltAudio].getMatchingAlternateWithPersistentId(audioPersistentId, currentVariant, excludingOptions) + : undefined; + const subtitleAltMediaOption = isFiniteNumber(subtitlePersistentId) + ? this.mediaOptionListQueries[MediaOptionType.Subtitle].getMatchingAlternateWithPersistentId(subtitlePersistentId, currentVariant, excludingOptions) + : undefined; + return [audioAltMediaOption ? audioAltMediaOption : NoMediaOption, subtitleAltMediaOption ? subtitleAltMediaOption : NoMediaOption]; + } + getLegacyMatchingAlternateWithPersistentId(mediaOptionType, persistentId, currentVariant) { + let altMediaOption = this.mediaOptionListQueries[mediaOptionType].getMatchingAlternateWithPersistentId(persistentId, currentVariant, []); + if (!altMediaOption) { + altMediaOption = this.mediaOptionListQueries[mediaOptionType].getMatchingAlternateWithPersistentId(persistentId, undefined, []); // just match persistent id + } + return altMediaOption; + } + isValidMediaOptionTuple(tuple, mediaOptionMask = undefined) { + const expectedEnabledMediaOptionMask = mediaOptionMask ? mediaOptionMask : this.getEnabledMediaOptionMask(); + const result = [MediaOptionType.Variant, MediaOptionType.AltAudio, MediaOptionType.Subtitle].reduce((prev, cur) => { + return prev && expectedEnabledMediaOptionMask[cur] === isEnabledMediaOption(tuple[cur]); + }, true); + return result; + } + matchGroup(mediaOption, audioGroup, subtitleGroup, closedCaptionGroup) { + const mediaType = mediaOption.mediaOptionType; + const altOptionQuery = this.mediaOptionListQueries[mediaType]; + return altOptionQuery.matchGroup(mediaOption, audioGroup, subtitleGroup, closedCaptionGroup); + } + get preferHDR() { + return this.mediaOptionListQueries[MediaOptionType.Variant].mediaOptionListInfo.preferHDR; + } + } + + class RootPlaylistStore extends EntityStore { + constructor() { + super({}, { name: 'root-playlist-store', idKey: 'itemId', producerFn: produce_1 }); + } + akitaPreAddEntity(newEntity) { + if (newEntity.errorsByType == null) { + return Object.assign(Object.assign({}, newEntity), { errorsByType: [{ timeouts: { load: 0, append: 0, key: 0 } }, { timeouts: { load: 0, append: 0, key: 0 } }, { timeouts: { load: 0, append: 0, key: 0 } }] }); + } + return newEntity; + } + } + + const loggerName = { name: 'rps' }; + /** + * @brief Service for managing root playlist state. Will fetch the root playlist and manage selected media options + */ + const PENALTYBOX_TIMEOUT_MS = 120000; // 2 minutes + class RootPlaylistService { + constructor(store, logger) { + this.store = store; + this.logger = logger; + } + getQuery() { + return new QueryEntity(this.store); + } + getQueryForId(itemId) { + return new RootPlaylistQuery(this.store, itemId); + } + set rootPlaylistEntity(rootPlaylistEntity) { + logAction('root.add.rootPlaylist'); + this.store.add(rootPlaylistEntity); + } + // Remove entity by item id + removeItems(itemIds) { + logAction(`root.add.remove ${JSON.stringify(itemIds)}`); + this.store.remove(itemIds); + } + // Remove all entities + removeAll() { + logAction('root.add.clear'); + this.store.remove(); + } + setRootPlaylistEntity(itemId, rootPlaylistEntity) { + logAction('root.set.rootPlaylistEntity'); + this.store.update(itemId, (entity) => { + // Must return this so that entire entity is updated + return (rootPlaylistEntity); + }); + } + setSessionData(itemId, sessionData) { + logAction('root.set.sessionData'); + this.store.update(itemId, (rootPlaylistEntity) => { + rootPlaylistEntity.sessionData = sessionData; + }); + } + /** + * Update the position and discontinuity sequence number used for choosing fragments + * @param anchorTime The anchor position + * @param discoSeqNum The discontinuity sequence number + */ + setAnchorTime(itemId, anchorTime) { + logAction(`root.set.anchorTime: ${anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.pos} ${anchorTime === null || anchorTime === void 0 ? void 0 : anchorTime.discoSeqNum}`); + this.store.update(itemId, (rootPlaylistEntity) => { + rootPlaylistEntity.anchorTime = anchorTime; + }); + } + setDiscoSeqNum(itemId, cc) { + logAction(`root.set.discoSeqNum: ${cc}`); + this.store.update(itemId, (rootPlaylistEntity) => { + rootPlaylistEntity.discoSeqNum = cc; + }); + } + setPendingSeek(itemId, pendingSeek) { + logAction('root.set.pendingSeek'); + this.store.update(itemId, (rootPlaylistEntity) => { + rootPlaylistEntity.pendingSeek = pendingSeek; + }); + if (pendingSeek === undefined) { + globalHlsService().setUserSeek(pendingSeek); + } + } + setEnabledMediaOptionSwitchContextByType(itemId, mediaOptionType, mediaOptionId, context) { + this.logger.info(`root.set.mediaOptionSwitchContextByType: ${mediaOptionType} ${mediaOptionId} ${context === null || context === void 0 ? void 0 : context.userInitiated}`); + this.store.update(itemId, (entity) => { + var _a; + if (entity.enabledMediaOptionKeys[mediaOptionType].mediaOptionId === mediaOptionId) { + const mediaOptionContextTuple = (_a = entity.mediaOptionSwitchContexts) !== null && _a !== void 0 ? _a : [null, null, null]; + mediaOptionContextTuple[mediaOptionType] = context ? { userInitiated: context.userInitiated, switchPosition: context.switchPosition } : null; + entity.mediaOptionSwitchContexts = mediaOptionContextTuple; + } + else { + // Don't update switch context for a different mediaOption + logAction(`root.set.mediaOptionSwitchContextByType ${mediaOptionId} doesn't match existing mediaOption ${entity.enabledMediaOptionKeys[mediaOptionType].mediaOptionId}`); + } + }); + } + setEnabledVariantMediaOptionIdBeforeTrickplaySwitch(itemId, id) { + this.logger.info(`root.set.enabledVariantMediaOptionIdBeforeTrickplaySwitch: ${id}`); + this.store.update(itemId, (entity) => { + entity.enabledVariantMediaOptionIdBeforeTrickplaySwitch = id; + }); + } + setEnabledMediaOptionByType(itemId, mediaOptionType, mediaOption, replaceContext = false, context = undefined) { + if (!mediaOption) { + mediaOption = { itemId, mediaOptionType, mediaOptionId: 'Nah' }; + } + this.logger.info(`root.set.mediaOptionByType: ${mediaOptionType} ${mediaOption.mediaOptionId} replaceCtxt ${replaceContext} ctxt ${JSON.stringify(context === null || context === void 0 ? void 0 : context.userInitiated)}`); + this.store.update(itemId, (entity) => { + var _a, _b; + const mediaOptionKeyTuple = (_a = [...entity.enabledMediaOptionKeys]) !== null && _a !== void 0 ? _a : [NoMediaOption, NoMediaOption, NoMediaOption]; + mediaOptionKeyTuple[mediaOptionType] = { itemId, mediaOptionId: mediaOption.mediaOptionId }; + this._updateEnabledMediaOptionKeys(entity, mediaOptionKeyTuple); + if (replaceContext) { + // consider this sequence of events: + // (1) user switches audio mediaOption. Such an alt audio switch will include a switchContext. + // (2) While audio mediaOption is being handled, user switches subtitle mediaOption, hls.js *might* also switch the audio mediaOption to match the latest group-ids. + // The "silent" audio track switch in (2) should not override the userInitiated switchContext in (1) + // replaceContext should be true in (1) and false in (2) + const mediaOptionContextTuple = (_b = entity.mediaOptionSwitchContexts) !== null && _b !== void 0 ? _b : [null, null, null]; + mediaOptionContextTuple[mediaOptionType] = context ? { userInitiated: context.userInitiated, switchPosition: context.switchPosition } : null; + entity.mediaOptionSwitchContexts = mediaOptionContextTuple; + } + }); + } + _associateForcedSubtitleWithClosedCaption(entity, variantMediaOptionId, closedCaption, rootQuery) { + if ((closedCaption === null || closedCaption === void 0 ? void 0 : closedCaption.mediaType) === MediaTypeFourCC.CLOSEDCAPTION) { + const variantOption = rootQuery.variantMediaOptionById(variantMediaOptionId); + const newClosedCaption = rootQuery.mediaOptionListQueries[MediaOptionType.Subtitle].packageAlternateMediaOption(variantOption, closedCaption, true); + getLogger().info(`[subtitle] new closedCaption ${redactUrl(newClosedCaption.url)} vs old ${redactUrl(closedCaption.url)}`); + if (newClosedCaption.url !== closedCaption.url) { + const newMediaOptions = replaceClosedCaptionInMediaOptionListIfNecessary(variantOption, newClosedCaption, entity.mediaOptionListTuple[MediaOptionType.Subtitle].mediaOptions, getLogger()); + entity.mediaOptionListTuple[MediaOptionType.Subtitle].mediaOptions = newMediaOptions; + } + } + } + // Stuff that must be done always when setting enabledMediaOptionKeys + _updateEnabledMediaOptionKeys(entity, mediaOptionKeyTuple) { + var _a; + const enabledMediaOptionKeys = (_a = entity.enabledMediaOptionKeys) !== null && _a !== void 0 ? _a : [NoMediaOption, NoMediaOption, NoMediaOption]; + let enabledVariantKey; + for (let type = 0; type < mediaOptionKeyTuple.length; ++type) { + const newOption = mediaOptionKeyTuple[type]; + const didChange = enabledMediaOptionKeys[type].mediaOptionId !== newOption.mediaOptionId; + if (didChange) { + enabledMediaOptionKeys[type] = Object.assign({}, newOption); + } + if (type === MediaOptionType.Variant) { + // Using all mediaOptions so that mediaOptions in PenaltyBox are also considered when setting highBWTrigger + const unfilteredList = this.getQueryForId(newOption.itemId).mediaOptionListQueries[type].mediaOptionList; + if (didChange) { + entity.abrStatus = initializeAbrStatus(newOption.mediaOptionId, unfilteredList); + } + else { + // Just update highBW trigger + entity.abrStatus.highBWTrigger = getLowestSuperiorBW(newOption.mediaOptionId, unfilteredList); + } + enabledVariantKey = newOption; + } + else if (type === MediaOptionType.Subtitle && isEnabledMediaOption(newOption)) { + const rootQuery = this.getQueryForId(newOption.itemId); + const subtitleOption = rootQuery.alternateMediaOptionById(type, newOption.mediaOptionId); + this._associateForcedSubtitleWithClosedCaption(entity, enabledVariantKey.mediaOptionId, subtitleOption, rootQuery); + } + } + entity.enabledMediaOptionKeys = enabledMediaOptionKeys; + entity.nextMediaOptionKeys = undefined; + } + // Disables ABR. for development + setManualMode(itemId, manualMode) { + this.store.update(itemId, (entity) => { + entity.manualMode = manualMode; + }); + } + setEnabledMediaOptions(itemId, mediaOptions) { + this.logger.info(`root.set.enabledMediaOptions: ${JSON.stringify(mediaOptions.map((x) => x.mediaOptionId))}`); + this.store.update(itemId, (entity) => { + const mediaOptionKeyTuple = mediaOptions.map(({ mediaOptionId, itemId }) => { + const result = { mediaOptionId, itemId }; + return result; + }); + this._updateEnabledMediaOptionKeys(entity, mediaOptionKeyTuple); + }); + } + setEnabledMediaOptionsAndSwitchContexts(itemId, mediaOptions, switchContexts) { + this.logger.info(`root.set.enabledMediaOptionsAndSwitchContexts: ${JSON.stringify(mediaOptions.map((x) => x.mediaOptionId))} ctxt ${JSON.stringify(switchContexts)}`); + this.store.update(itemId, (entity) => { + const mediaOptionKeyTuple = mediaOptions.map(({ mediaOptionId, itemId }) => { + const result = { mediaOptionId, itemId }; + return result; + }); + this._updateEnabledMediaOptionKeys(entity, mediaOptionKeyTuple); + entity.mediaOptionSwitchContexts = switchContexts; + }); + } + setNextMediaOptions(itemId, mediaOptions) { + logAction(`root.set.nextMediaOptions: ${JSON.stringify(mediaOptions === null || mediaOptions === void 0 ? void 0 : mediaOptions.map((x) => x.mediaOptionId))}`); + this.store.update(itemId, (entity) => { + const keys = mediaOptions + ? mediaOptions.map(({ itemId, mediaOptionId }) => { + const result = { itemId, mediaOptionId }; + return result; + }) + : null; + entity.nextMediaOptionKeys = keys; + }); + } + // updateEnabledMediaOptions should not touch the switch context + updateEnabledMediaOptions(itemId) { + logAction('root.set.updateEnabledMediaOptions'); + this.store.update(itemId, (entity) => { + if (entity.nextMediaOptionKeys && entity.manualMode !== true) { + logAction(`root.set.updateEnabledMediaOptions ${JSON.stringify(entity.nextMediaOptionKeys)}`); + this._updateEnabledMediaOptionKeys(entity, [...entity.nextMediaOptionKeys]); + } + entity.nextMediaOptionKeys = undefined; + }); + } + setLastLoadedMediaOptionByType(itemId, mediaOptionType, mediaOption) { + if (!mediaOption) { + mediaOption = { itemId, mediaOptionType, mediaOptionId: 'Nah' }; + } + logAction(`root.set.lastLoadedMediaOptionByType: ${mediaOptionType} ${mediaOption.mediaOptionId}`); + this.store.update(itemId, (entity) => { + var _a; + const mediaOptionKeyTuple = (_a = entity.lastLoadedMediaOptionKeys) !== null && _a !== void 0 ? _a : [NoMediaOption, NoMediaOption, NoMediaOption]; + mediaOptionKeyTuple[mediaOptionType] = { itemId, mediaOptionId: mediaOption.mediaOptionId }; + entity.lastLoadedMediaOptionKeys = mediaOptionKeyTuple; + }); + } + setPreferredHost(itemId, newHost) { + logAction(`root.set.preferredHost: ${newHost}`); + this.store.update(itemId, (entity) => { + if (!entity) { + return; + } + const optionListInfo = entity.mediaOptionListTuple[MediaOptionType.Variant]; + optionListInfo.preferredHost = newHost; + }); + } + setViewportInfo(itemId, viewportInfo) { + logAction(`root.set.viewportInfo: ${JSON.stringify(viewportInfo)}`); + this.store.update(itemId, (entity) => { + if (!entity) { + return; + } + const optionListInfo = entity.mediaOptionListTuple[MediaOptionType.Variant]; + optionListInfo.viewportInfo = viewportInfo; + }); + } + static getExistingPersistentIds(entity) { + var _a, _b; + const existingSelection = {}; + const audioOptionId = (_a = entity.enabledMediaOptionKeys[MediaOptionType.AltAudio]) === null || _a === void 0 ? void 0 : _a.mediaOptionId; + if (audioOptionId !== 'Nah') { + const audioOptionListInfo = entity.mediaOptionListTuple[MediaOptionType.AltAudio]; + const filteredAudio = applyFilters(audioOptionListInfo.mediaOptions, AlternateMediaOptionListQuery.kAllowFilters, audioOptionListInfo); + const altAudioOption = filteredAudio.find((altOption) => altOption.mediaOptionId === audioOptionId); + existingSelection.audioPersistentId = altAudioOption === null || altAudioOption === void 0 ? void 0 : altAudioOption.persistentID; + } + const subtitleOptionId = (_b = entity.enabledMediaOptionKeys[MediaOptionType.Subtitle]) === null || _b === void 0 ? void 0 : _b.mediaOptionId; + if (subtitleOptionId !== 'Nah') { + const subtitleOptionListInfo = entity.mediaOptionListTuple[MediaOptionType.Subtitle]; + const filteredSubtitles = applyFilters(subtitleOptionListInfo.mediaOptions, AlternateMediaOptionListQuery.kAllowFilters, subtitleOptionListInfo); + const subtitleOption = filteredSubtitles.find((altOption) => altOption.mediaOptionId === subtitleOptionId); + existingSelection.subtitlePersistentId = subtitleOption === null || subtitleOption === void 0 ? void 0 : subtitleOption.persistentID; + } + return existingSelection; + } + static doUpdateRootHDRSwitch(entity, preferHDR, hasHdrLevels, logger) { + // immer complains if you try to modify and update the object in one go so make deep copy of mediaOptionListTuple + const mediaOptionListTuple = entity.mediaOptionListTuple.map((info) => (Object.assign({}, info))); + mediaOptionListTuple[MediaOptionType.Variant].preferHDR = preferHDR; + mediaOptionListTuple[MediaOptionType.Variant].hasHdrLevels = hasHdrLevels; + const hlsConf = getCurrentConfig(); + const curItem = queueItemQuery.getEntity(entity.itemId); + const statsQuery = createStatsQuery(entity.itemId); + const bandwidthEstimate = statsQuery.getBandwidthEstimate(hlsConf, curItem === null || curItem === void 0 ? void 0 : curItem.serviceName); + const playlistEstimate = statsQuery.getPlaylistEstimate(hlsConf, curItem === null || curItem === void 0 ? void 0 : curItem.serviceName); + const fragEstimate = statsQuery.getFragEstimate(hlsConf, curItem === null || curItem === void 0 ? void 0 : curItem.serviceName); + const bufferEstimate = statsQuery.getBufferEstimate(hlsConf, curItem === null || curItem === void 0 ? void 0 : curItem.serviceName); + const adaptiveStartupConfig = { + targetDuration: fragEstimate.maxDurationSec || (hlsConf === null || hlsConf === void 0 ? void 0 : hlsConf.defaultTargetDuration), + targetStartupMs: hlsConf === null || hlsConf === void 0 ? void 0 : hlsConf.targetStartupMs, + }; + const existingSelection = RootPlaylistService.getExistingPersistentIds(entity); + return updateRootPlaylistEntityWithEnabledMediaOptionKeys(Object.assign(Object.assign({}, entity), { mediaOptionListTuple, nextMediaOptionKeys: null }), existingSelection, logger, bandwidthEstimate, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + } + // For error handling. disable HDR playback but don't re-calculate enabled media options + switchToSDROnly(itemId) { + logAction('root.switchToSDROnly'); + this.store.update(itemId, (entity) => { + const { mediaOptionListTuple } = RootPlaylistService.doUpdateRootHDRSwitch(entity, false, false, this.logger); + entity.mediaOptionListTuple = mediaOptionListTuple; + }); + } + /** + * Update HDR preference and set enabled media options based on the preference + */ + setHDRPreference(itemId, preferHDR, updateEnabledOptions) { + logAction(`root.set.HDRPreference: ${preferHDR}`); + this.store.update(itemId, (entity) => { + const optionListInfo = entity.mediaOptionListTuple[MediaOptionType.Variant]; + if (optionListInfo.preferHDR === preferHDR || (preferHDR && !optionListInfo.hasHdrLevels)) { + return; + } + const newEntity = RootPlaylistService.doUpdateRootHDRSwitch(entity, preferHDR, optionListInfo.hasHdrLevels, this.logger); + if (!updateEnabledOptions) { + entity.mediaOptionListTuple = newEntity.mediaOptionListTuple; + } + else { + // Must return this so that entire entity is updated + return (entity = newEntity); + } + }); + } + setPathwayPriority(itemId, pathwayPriority) { + logAction(`root.set.PathwayPriority: [ ${pathwayPriority.join(', ')} ]`); + this.store.update(itemId, (entity) => { + if (!entity) { + return; + } + const optionListInfo = entity.mediaOptionListTuple[MediaOptionType.Variant]; + optionListInfo.pathwayPriority = pathwayPriority; + optionListInfo.preferredHost = null; + }); + } + setCurrentPathwayID(itemId, currentPathwayID) { + logAction(`root.set.currentPathwayID: ${currentPathwayID}`); + this.store.update(itemId, (entity) => { + if (!entity) { + return; + } + const optionListInfo = entity.mediaOptionListTuple[MediaOptionType.Variant]; + optionListInfo.currentPathwayID = currentPathwayID; + }); + } + setInitPTS(itemId, discoSeqNum, variantDTS, timelineOffset, offsetTimestamp, iframeMode) { + logAction(`root.set.initPTS: ${itemId} ${discoSeqNum} variantDTS:${JSON.stringify(variantDTS)} timelineOffset: ${timelineOffset}`); + this.store.update(itemId, (entity) => { + entity.initPtsRecord[discoSeqNum] = { variantDTS, timelineOffset, offsetTimestamp, iframeMode }; + }); + } + /** + * Modify penaltyBoxQueue to remove all expired entries in place + * @param penaltyBoxQueue + * @param now + */ + static prunePenaltyBox(penaltyBoxQueue, now) { + return penaltyBoxQueue.filter((x) => !isExpired(x.expiry, now)); + } + /** + * Add entry to penaltyBoxQueue in place + * @param penaltyBoxQueue + * @param now + * @param mediaOptionId + */ + static addToPenaltyBox(penaltyBoxQueue, now, mediaOptionId) { + return penaltyBoxQueue.push({ mediaOptionId, expiry: now + PENALTYBOX_TIMEOUT_MS }); + } + /** + * Put a media option into the penalty box. It will stay there for 2 minutes + * @param filterListId The filter list to modify + * @param mediaOptionType The media option type + * @param mediaOptionId The media option to put into penalty box + */ + addToPenaltyBox(itemId, mediaOptionType, mediaOptionId) { + logAction(`root.set.penaltyBox: ${mediaOptionType}: ${mediaOptionId}`); + this.store.update(itemId, ({ mediaOptionListTuple: mediaOptionsStates }) => { + const optionListInfo = mediaOptionsStates[mediaOptionType]; + // TODO: dedup + const now = performance.now(); + optionListInfo.penaltyBoxQueue = RootPlaylistService.prunePenaltyBox(optionListInfo.penaltyBoxQueue, now); + RootPlaylistService.addToPenaltyBox(optionListInfo.penaltyBoxQueue, now, mediaOptionId); + }); + } + /** + * Remove all expired entries from penalty box + * @param itemId The queue item id + * @param mediaOptionType which media option type to prune penalty box for. if null, prune all + */ + prunePenaltyBox(itemId, mediaOptionType = null) { + logAction(`root.set.prunePenaltyBox: ${mediaOptionType}`); + this.store.update(itemId, ({ mediaOptionListTuple }) => { + const infoList = mediaOptionType ? [mediaOptionListTuple[mediaOptionType]] : mediaOptionListTuple; + const now = performance.now(); + for (const info of infoList) { + info.penaltyBoxQueue = RootPlaylistService.prunePenaltyBox(info.penaltyBoxQueue, now); + } + }); + } + /** + * Put a media option in the remove list. It will stay there permanently. + * @param itemId The filter list to modify + * @param mediaOptionType The media option type + * @param mediaOptionId The media option to put in remove list + */ + removePermanently(itemId, mediaOptionType, mediaOptionId) { + logAction(`root.set.removePermanently: ${mediaOptionType}: ${mediaOptionId}`); + this.store.update(itemId, ({ mediaOptionListTuple: mediaOptionsStates }) => { + const optionListInfo = mediaOptionsStates[mediaOptionType]; + // dedup. uncommon to remove so this should hopefully be small + const removeSet = new Set(optionListInfo.removed); + removeSet.add(mediaOptionId); + optionListInfo.removed = Array.from(removeSet); + }); + } + /** + * + * @param itemId The filter list to modify + * @param mediaOptionType Which media option list to update + * @param hostName The hostname used for matching + * @param remove if true, remove this host permanently from valid list. if false, put into penalty box + */ + moveAllWithMatchingHosts(itemId, mediaOptionType, hostName, remove) { + logAction(`root.set.moveAllMatchingHosts: ${mediaOptionType}:${hostName} remove:${remove}`); + this.store.update(itemId, ({ mediaOptionListTuple: mediaOptionsStates }) => { + const optionListInfo = mediaOptionsStates[mediaOptionType]; + const mediaOptionIdsToModify = [...optionListInfo.mediaOptions].filter((mo) => hasMatchingHost(hostName, mo.url)).map((x) => x.mediaOptionId); + if (remove) { + const merged = new Set([...optionListInfo.removed, ...mediaOptionIdsToModify]); + optionListInfo.removed = Array.from(merged); + } + else { + const now = performance.now(); + optionListInfo.penaltyBoxQueue = RootPlaylistService.prunePenaltyBox(optionListInfo.penaltyBoxQueue, now); + for (const mediaOptionId of mediaOptionIdsToModify) { + RootPlaylistService.addToPenaltyBox(optionListInfo.penaltyBoxQueue, now, mediaOptionId); + } + } + }); + } + /** + * @param itemId the item id to modify + * @param maxHdcpLevel the maximum hdcp level allowed for this asset (exclusive). Only allow variants with hdcpLevel < maxHdcpLevel + * @param force if true, always update. if false, only update if maxHdcpLevel is < current maxHdcpLevel + */ + setMaxHdcpLevel(itemId, maxHdcpLevel, force = false) { + logAction(`root.set.maxHdcpLevel: ${maxHdcpLevel}`); + this.store.update(itemId, ({ mediaOptionListTuple: mediaOptionsStates }) => { + const optionListInfo = mediaOptionsStates[MediaOptionType.Variant]; + // Only can lower max hdcp level unless forced + if (force || hdcpLevelToInt(maxHdcpLevel) < hdcpLevelToInt(optionListInfo.maxHdcpLevel)) { + optionListInfo.maxHdcpLevel = maxHdcpLevel; + } + }); + } + /** + * @param itemId The queue item id + * @param mediaOptionType the mediaOptionType + * @param increment if true, increment else reset + * @param timeout Which type of timeout it was + */ + updateConsecutiveTimeouts(itemId, mediaOptionType, increment, type) { + this.store.update(itemId, (entity) => { + const errorHandlingInfo = entity.errorsByType || [ + { timeouts: { load: 0, append: 0, key: 0 } }, + { timeouts: { load: 0, append: 0, key: 0 } }, + { timeouts: { load: 0, append: 0, key: 0 } }, + ]; + if (increment) { + ++errorHandlingInfo[mediaOptionType].timeouts[type]; + } + else { + errorHandlingInfo[mediaOptionType].timeouts[type] = 0; + } + entity.errorsByType = errorHandlingInfo; + }); + } + // Update inflight fragment information. For now just hooking up Variant & AltAudio + updateInflightFrag(itemId, type, frag, state, sample) { + logAction('root.set.updateInflightFrag'); + this.store.update(itemId, (entity) => { + if (!entity.inFlightFrags) { + entity.inFlightFrags = [null, null]; + } + if (type === MediaOptionType.Subtitle || (frag && frag.itemId !== itemId)) { + return; + } + if (!frag) { + entity.inFlightFrags[type] = null; + return; + } + let { start, duration } = frag; + const { mediaOptionId, mediaSeqNum, discoSeqNum } = frag; + const inFlight = entity.inFlightFrags[type]; + // Update tstart if state changed + let tstart = inFlight === null || inFlight === void 0 ? void 0 : inFlight.tstart; + if (state !== (inFlight === null || inFlight === void 0 ? void 0 : inFlight.state)) { + tstart = performance.now(); + } + if (fragEqual(inFlight, frag)) { + start = inFlight.start; + duration = inFlight.duration; + } + entity.inFlightFrags[type] = { + itemId, + mediaOptionId, + mediaSeqNum, + discoSeqNum, + start, + duration, + tstart, + state, + bwSample: Object.assign({}, sample), + }; + }); + } + setNextMaxAutoOptionId(itemId, nextMaxAutoOptionId) { + logAction(`root.set.nextMaxAutoOptionId: ${nextMaxAutoOptionId}`); + this.store.update(itemId, ({ abrStatus: abrs }) => { + abrs.nextMaxAutoOptionId = nextMaxAutoOptionId; + }); + } + setNextMinAutoOptionId(itemId, nextMinAutoOptionId) { + logAction(`root.set.nextMinAutoOptionId: ${nextMinAutoOptionId}`); + this.store.update(itemId, ({ abrStatus: abrs }) => { + abrs.nextMinAutoOptionId = nextMinAutoOptionId; + }); + } + setHighBWTrigger(itemId, value) { + logAction(`root.set.setHighBWTrigger: ${value}`); + this.store.update(itemId, ({ abrStatus: abrs }) => { + abrs.highBWTrigger = value; + }); + } + setFragLoadSlow(itemId, value) { + logAction(`root.set.setFragLoadSlow ${itemId} ${JSON.stringify(value)}`); + this.store.update(itemId, ({ abrStatus: abrs }) => { + abrs.fragDownloadSlow = value.fragDownloadSlow; + abrs.fragDownloadTooSlow = value.fragDownloadTooSlow; + }); + } + pickMediaOptionTupleByPersistentId(rootQuery, mediaOptionType, persistentId, sdrOnly = false, shouldSwitchHost = false) { + const currentVariantId = rootQuery.enabledMediaOptionIdByType(MediaOptionType.Variant); + const variant = rootQuery.variantMediaOptionById(currentVariantId); + let audioPersistentId; + let subtitlePersistentId; + if (mediaOptionType === MediaOptionType.AltAudio) { + const subtitleAltOption = rootQuery.enabledAlternateMediaOptionByType(MediaOptionType.Subtitle); + subtitlePersistentId = subtitleAltOption === null || subtitleAltOption === void 0 ? void 0 : subtitleAltOption.persistentID; + audioPersistentId = persistentId; + } + else { + const audioAltOption = rootQuery.enabledAlternateMediaOptionByType(MediaOptionType.AltAudio); + audioPersistentId = audioAltOption === null || audioAltOption === void 0 ? void 0 : audioAltOption.persistentID; + subtitlePersistentId = persistentId; + } + const expectedEnabledMediaOptionMask = rootQuery.getEnabledMediaOptionMask(); + expectedEnabledMediaOptionMask[mediaOptionType] = isFiniteNumber(persistentId) && persistentId >= 0 ? true : false; + return variant + ? this.getBestMediaOptionTupleFromVariantAndPersistentId(rootQuery, variant, audioPersistentId, subtitlePersistentId, expectedEnabledMediaOptionMask, undefined, sdrOnly, shouldSwitchHost, false) + : [NoMediaOption, NoMediaOption, NoMediaOption]; + } + getFallbackMediaOptionTupleFromMediaOptionId(rootQuery, mediaOptionType, mediaOptionId, backingMediaOptionId, sdrOnly = false, shouldSwitchHosts = false, shouldDownswitch = false) { + const excludingOptions = backingMediaOptionId ? [backingMediaOptionId] : [mediaOptionId]; // always exclude mediaOptionId or backingMediaOptionId from result list since we are looking for its fallback + const currentVariantId = rootQuery.enabledMediaOptionIdByType(MediaOptionType.Variant); // getBestMediaOptionTupleFromVariantAndPersistentId will skip currentVariantId if it's mediaOptionId (excluded above) + const variant = rootQuery.variantMediaOptionById(currentVariantId); + const altAudio = mediaOptionType === MediaOptionType.AltAudio + ? rootQuery.alternateMediaOptionById(MediaOptionType.AltAudio, mediaOptionId) + : rootQuery.enabledAlternateMediaOptionByType(MediaOptionType.AltAudio); + const audioPersistentId = altAudio === null || altAudio === void 0 ? void 0 : altAudio.persistentID; + const subtitle = mediaOptionType === MediaOptionType.Subtitle + ? rootQuery.alternateMediaOptionById(MediaOptionType.Subtitle, mediaOptionId) + : rootQuery.enabledAlternateMediaOptionByType(MediaOptionType.Subtitle); + const subtitlePersistentId = subtitle === null || subtitle === void 0 ? void 0 : subtitle.persistentID; + return variant + ? this.getBestMediaOptionTupleFromVariantAndPersistentId(rootQuery, variant, audioPersistentId, subtitlePersistentId, undefined, excludingOptions, sdrOnly, shouldSwitchHosts, shouldDownswitch) + : [NoMediaOption, NoMediaOption, NoMediaOption]; + } + hasFallbackMediaOptionTuple(rootQuery, mediaOptionType, fromId, shouldSwitchHosts) { + const fromOption = rootQuery.mediaOptionListQueries[mediaOptionType].mediaOptionFromId(fromId); + return rootQuery.isValidMediaOptionTuple(this.getFallbackMediaOptionTupleFromMediaOptionId(rootQuery, mediaOptionType, fromId, fromOption.backingMediaOptionId, false, shouldSwitchHosts)); + } + setLegacyAlternateMediaOption(rootQuery, itemId, mediaOptionType, persistentId, switchContext = undefined) { + const currentVariantId = rootQuery.enabledMediaOptionIdByType(MediaOptionType.Variant); + const currentVariant = rootQuery.variantMediaOptionById(currentVariantId); + const newAltOption = rootQuery.getLegacyMatchingAlternateWithPersistentId(mediaOptionType, persistentId, currentVariant); + if (newAltOption) { + this.setEnabledMediaOptionByType(itemId, mediaOptionType, newAltOption, true, switchContext); + } + else { + this.logger.warn(`${MediaOptionNames[mediaOptionType]} can't find matching mediaOption for persistent id ${persistentId}`); + } + } + setEnabledMediaOptionTupleWithMatchedGroups(itemId, mediaOptionType, persistentId, switchContext = undefined) { + const rootQuery = createRootPlaylistQuery(itemId); + const newOptions = this.pickMediaOptionTupleByPersistentId(rootQuery, mediaOptionType, persistentId); + if (!rootQuery.isValidMediaOptionTuple(newOptions)) { + // can't find matching variant and alternates combo, + // just switch the alternate media option of mediaOptionType, potentially ignore preferred host and group + return this.setLegacyAlternateMediaOption(rootQuery, itemId, mediaOptionType, persistentId, switchContext); + } + applyTransaction(() => { + this.setEnabledMediaOptionByType(itemId, mediaOptionType, newOptions[mediaOptionType], true, switchContext); + if (newOptions[MediaOptionType.Variant].mediaOptionId !== rootQuery.enabledMediaOptionIdByType(MediaOptionType.Variant)) { + this.setPreferredHost(itemId, getHostName(newOptions[MediaOptionType.Variant].url)); + } + // always update the variant mediaOption even if it has not changed. This will allow AVPipe's enabledMediaOptionSwitchForType call + // to reflect the latest fromId->toId mediaOption switching. + this.setEnabledMediaOptionByType(itemId, MediaOptionType.Variant, newOptions[MediaOptionType.Variant]); + const otherType = mediaOptionType === MediaOptionType.AltAudio ? MediaOptionType.Subtitle : MediaOptionType.AltAudio; + if (newOptions[otherType].mediaOptionId !== rootQuery.enabledMediaOptionIdByType(otherType)) { + this.setEnabledMediaOptionByType(itemId, otherType, newOptions[otherType], false); // don't override switchContext of the other alternate + } + }); + } + canSwitchToSDR(rootQuery, mediaOptionId, shouldSwitchHosts, shouldDownswitch = false) { + const mediaOption = rootQuery.mediaOptionListQueries[MediaOptionType.Variant].mediaOptionFromId(mediaOptionId); + const newMediaOptions = this.getFallbackMediaOptionTupleFromMediaOptionId(rootQuery, MediaOptionType.Variant, mediaOptionId, mediaOption.backingMediaOptionId, true, shouldSwitchHosts, shouldDownswitch); + return rootQuery.isValidMediaOptionTuple(newMediaOptions); + } + getBestMediaOptionTupleFromVariantAndPersistentId(rootQuery, currentVariant, audioPersistentId, subtitlePersistentId, expectedEnabledMediaOptionMask, excludingOptions, sdrOnly, shouldSwitchHosts, shouldDownswitch) { + let alternates; + const fallbackVariantList = rootQuery.mediaOptionListQueries[MediaOptionType.Variant].listFallbackVariants(currentVariant.mediaOptionId, sdrOnly, shouldSwitchHosts, shouldDownswitch, excludingOptions); + let preferredFallback = [NoMediaOption, NoMediaOption, NoMediaOption]; + for (let i = 0; i < fallbackVariantList.length; ++i) { + const nextVariant = fallbackVariantList[i]; + alternates = rootQuery.matchAlternates(nextVariant, audioPersistentId, subtitlePersistentId, excludingOptions); + if (rootQuery.isValidMediaOptionTuple([nextVariant, ...alternates], expectedEnabledMediaOptionMask)) { + preferredFallback = [nextVariant, ...alternates]; + break; // found variant with valid alternates + } + } + return preferredFallback; + } + } + const rootPlaylistStore = new RootPlaylistStore(); + new QueryEntity(rootPlaylistStore); + let rootService = null; // To be instantiated in rootPlaylistService + /*********************************************** + * Static helper functions that specifically use the above singletons + */ + function createRootPlaylistQuery(itemId) { + return new RootPlaylistQuery(rootPlaylistStore, itemId); + } + /** + * @returns The global instance of RootPlaylistService that operates on global RootPlaylistStore + */ + function rootPlaylistService(logger) { + rootService = new RootPlaylistService(rootPlaylistStore, logger); + return rootService; + } + /** + * Choose the audio track given the selection group and options + * @param groupId GroupID from variant + * @param audioMediaSelectionGroup + * @param audioAlternateOptions + */ + const getAutoAudio = (persistentId, groupId, audioMediaSelectionGroup, audioAlternateOptions) => { + if (audioMediaSelectionGroup) { + let audioMediaOption; + if (isFiniteNumber(persistentId)) { + audioMediaOption = audioMediaSelectionGroup.MediaSelectionGroupOptions.find(function (mediaOption) { + return mediaOption.MediaSelectionOptionsPersistentID === persistentId; + }); + } + else { + audioMediaOption = audioMediaSelectionGroup.MediaSelectionGroupOptions.find(function (mediaOption) { + return mediaOption.MediaSelectionOptionsIsDefault; + }); + } + if (!audioMediaOption) { + audioMediaOption = audioMediaSelectionGroup.MediaSelectionGroupOptions[0]; + getLogger().info(`no default audio: pick the first persistentId ${audioMediaOption.MediaSelectionOptionsPersistentID}`); + } + const audioTrackInfo = audioAlternateOptions.find((audioTrack) => { + return (!groupId || audioTrack.groupId === groupId) && audioTrack.persistentID === (audioMediaOption === null || audioMediaOption === void 0 ? void 0 : audioMediaOption.MediaSelectionOptionsPersistentID); + }); + return audioTrackInfo; + } + }; + function logPlatformCapabilitiesFilterResults(hdrMediaOptions, sdrMediaOptions, el, config, displaySupportsHdr, logger) { + hdrMediaOptions.concat(sdrMediaOptions); + const devicePixelRatio = typeof window === 'object' && window.devicePixelRatio ? window.devicePixelRatio : 1; + const displaySize = config.useViewportSizeForLevelCap && el ? { width: el.clientWidth * devicePixelRatio, height: el.clientHeight * devicePixelRatio } : undefined; + logger.info(loggerName, `valid media options: hdr=${hdrMediaOptions.length} sdr=${sdrMediaOptions.length}, supportsHdr=${displaySupportsHdr}, displaySize=${displaySize ? JSON.stringify(displaySize) : null}`); + } + const updateBasedOnPlatformCapabilities = (loadRootMediaOptionsResult, platformInfo, config, displaySupportsHdr, logger) => { + const { rootMediaOptionsTuple, sessionKeys } = loadRootMediaOptionsResult; + const variantMediaOptions = Array.from(rootMediaOptionsTuple[MediaOptionType.Variant]); + const audioAlternateOptions = Array.from(rootMediaOptionsTuple[MediaOptionType.AltAudio]); + let videoCodecFound = false; + let audioCodecFound = false; + // regroup redundant variants together + let regroupedVariantMediaOptions = variantMediaOptions.map((mediaOption) => { + videoCodecFound = videoCodecFound || Boolean(mediaOption.videoCodec); + audioCodecFound = audioCodecFound || Boolean(mediaOption.audioCodec) || Boolean(mediaOption.audioGroupId); + return mediaOption; + }); + // remove audio-only media options if we also have media options with audio+video codecs signaled + if (videoCodecFound && audioCodecFound) { + regroupedVariantMediaOptions = regroupedVariantMediaOptions.filter(({ videoCodec }) => Boolean(videoCodec)); + } + logger.info(loggerName, `playlist has ${regroupedVariantMediaOptions.length} variantMediaOptions`); + return filterByPlatformCapabilities(variantMediaOptions, audioAlternateOptions, sessionKeys, platformInfo, config, logger).pipe(map(({ hdrMediaOptions, sdrMediaOptions }) => { + const allMediaOptions = hdrMediaOptions.concat(sdrMediaOptions); + const hasHdrMediaOptions = hdrMediaOptions.length > 0; + logPlatformCapabilitiesFilterResults(hdrMediaOptions, sdrMediaOptions, undefined, config, displaySupportsHdr, logger); + return makeRootPlaylistEntity(loadRootMediaOptionsResult, allMediaOptions, hasHdrMediaOptions, displaySupportsHdr); + })); + }; + /** + * Choose the audio track given the selection group and options + * @param subtitleMediaSelectionGroup + * @param subtitleAlternateOptions + */ + const getAutoSubtitle = (persistentId, closedCaptionGroup, subtitleGroup, subtitleMediaSelectionGroup, subtitleAlternateOptions, logger) => { + if (subtitleMediaSelectionGroup) { + let subtitleMediaOption; + if (isFiniteNumber(persistentId)) { + subtitleMediaOption = subtitleMediaSelectionGroup.MediaSelectionGroupOptions.find(function (mediaOption) { + return mediaOption.MediaSelectionOptionsPersistentID === persistentId; + }); + } + else { + subtitleMediaOption = subtitleMediaSelectionGroup.MediaSelectionGroupOptions.find(function (mediaOption) { + return mediaOption.MediaSelectionOptionsIsDefault; + }); + } + let subtitleTrackInfo; + if (subtitleMediaOption) { + subtitleTrackInfo = subtitleAlternateOptions.find((subtitleTrack) => { + if (subtitleTrack.mediaType === MediaTypeFourCC.CLOSEDCAPTION) { + return (!closedCaptionGroup || subtitleTrack.groupId === closedCaptionGroup) && subtitleTrack.persistentID === subtitleMediaOption.MediaSelectionOptionsPersistentID; + } + else if (subtitleTrack.mediaType === MediaTypeFourCC.SUBTITLE) { + return (!subtitleGroup || subtitleTrack.groupId === subtitleGroup) && subtitleTrack.persistentID === subtitleMediaOption.MediaSelectionOptionsPersistentID; + } + else { + logger.warn(loggerName, `subtitle media option has unknown type ${subtitleTrack.mediaType}`); + } + }); + } + return subtitleTrackInfo; + } + }; + function makeRootPlaylistEntity(loadRootMediaOptionsResult, variantMediaOptions, hasHdrLevels, preferHDR) { + var _a; + const { itemId, itemStartOffset, rootMediaOptionsTuple, audioMediaSelectionGroup, subtitleMediaSelectionGroup } = loadRootMediaOptionsResult; + const audioAlternateOptions = Array.from(rootMediaOptionsTuple[MediaOptionType.AltAudio]); + const subtitleAlternateOptions = Array.from(rootMediaOptionsTuple[MediaOptionType.Subtitle]); + const hasScore = variantMediaOptions.every((x) => isFiniteNumber(x.score)); + const hasIframeLevels = variantMediaOptions.some((x) => isIframeLevel(x)); + const sortedVariantMediaOptions = sortVariants(variantMediaOptions, hasScore); + const compatibleVariants = null; + const compatibleAudioAlternates = null; + const baseUrl = loadRootMediaOptionsResult.baseUrl; + const initPathwayID = (_a = loadRootMediaOptionsResult.contentSteeringOption) === null || _a === void 0 ? void 0 : _a.initPathwayID; + const sessionData = loadRootMediaOptionsResult.sessionData; + const rootPlaylistEntity = { + itemId, + baseUrl, + mediaOptionListTuple: [ + { + mediaOptions: sortedVariantMediaOptions, + hasHdrLevels, + hasIframeLevels, + hasScore, + preferHDR, + compatibleIds: compatibleVariants, + penaltyBoxQueue: [], + removed: [], + currentPathwayID: initPathwayID, + }, + { + mediaOptions: audioAlternateOptions, + compatibleIds: compatibleAudioAlternates, + penaltyBoxQueue: [], + removed: [], + }, + { + mediaOptions: subtitleAlternateOptions, + penaltyBoxQueue: [], + removed: [], + }, + ], + audioMediaSelectionGroup, + subtitleMediaSelectionGroup, + enabledMediaOptionKeys: [NoMediaOption, NoMediaOption, NoMediaOption], + mediaOptionSwitchContexts: [null, null, null], + anchorTime: { pos: 0 }, + discoSeqNum: NaN, + pendingSeek: undefined, + itemStartOffset, + initPtsRecord: {}, + contentSteeringOption: loadRootMediaOptionsResult.contentSteeringOption, + masterVariableList: loadRootMediaOptionsResult.masterVariableList, + loadStats: loadRootMediaOptionsResult.stats, + isMediaPlaylist: loadRootMediaOptionsResult.isMediaPlaylist, + abrStatus: { + fragDownloadSlow: false, + fragDownloadTooSlow: false, + nextMinAutoOptionId: NoMediaOption.mediaOptionId, + nextMaxAutoOptionId: NoMediaOption.mediaOptionId, + highBWTrigger: NaN, + }, + sessionData, + }; + return rootPlaylistEntity; + } + function selectStartingVariant(rootPlaylistEntity, logger, bandwidthEstimate, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + const mediaOptionListInfo = rootPlaylistEntity.mediaOptionListTuple[MediaOptionType.Variant]; + const filteredVariants = applyFilters(mediaOptionListInfo.mediaOptions, VariantMediaOptionListQuery.kAllowFilters, Object.assign(Object.assign({}, mediaOptionListInfo), { compatibleIds: null })); + const preferredVariants = getPreferredList(mediaOptionListInfo.preferredHost, filteredVariants); + const firstVariant = chooseFirstMediaOption(preferredVariants, firstMediaOptionSelectionMetrics, mediaOptionListInfo.hasScore, logger, bandwidthEstimate, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + return { firstVariant, filteredVariants, preferredVariants }; + } + function replaceClosedCaptionInMediaOptionListIfNecessary(variant, closedCaption, subtitleMediaOptions, logger) { + if ((closedCaption === null || closedCaption === void 0 ? void 0 : closedCaption.mediaType) === MediaTypeFourCC.CLOSEDCAPTION) { + const forcedMediaOption = AlternateMediaOptionListQuery.pairForcedSubtitleMediaOptionWithClosedCaptionInList(variant.subtitleGroupId, closedCaption, subtitleMediaOptions); + if (forcedMediaOption) { + closedCaption = Object.assign(Object.assign({}, closedCaption), { url: forcedMediaOption.url, backingMediaOptionId: forcedMediaOption.mediaOptionId }); + const newSubtitles = subtitleMediaOptions.map((option) => { + if (option.mediaOptionId === closedCaption.mediaOptionId) { + logger.info(`[subtitle] use closedCaption ${JSON.stringify(closedCaption)}`); + return closedCaption; + } + return option; + }); + return newSubtitles; + } + } + return subtitleMediaOptions; // no change + } + /** + * Modify rootPlaylistEntity (in-place), updating media options list and selecting a new set of enabled media options + */ + function updateRootPlaylistEntityWithEnabledMediaOptionKeys(rootPlaylistEntity, existingSelection, logger, bandwidthEstimate, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate) { + var _a, _b; + const itemId = rootPlaylistEntity.itemId; + const mediaOptionListInfo = rootPlaylistEntity.mediaOptionListTuple[MediaOptionType.Variant]; + const audioOptionListInfo = rootPlaylistEntity.mediaOptionListTuple[MediaOptionType.AltAudio]; + const subtitleOptionListInfo = rootPlaylistEntity.mediaOptionListTuple[MediaOptionType.Subtitle]; + const filteredAudio = applyFilters(audioOptionListInfo.mediaOptions, AlternateMediaOptionListQuery.kAllowFilters, audioOptionListInfo); + const filteredSubtitles = applyFilters(subtitleOptionListInfo.mediaOptions, AlternateMediaOptionListQuery.kAllowFilters, subtitleOptionListInfo); + let { firstVariant, filteredVariants } = selectStartingVariant(rootPlaylistEntity, logger, bandwidthEstimate, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + if (!firstVariant) { + const preferHDR = mediaOptionListInfo.preferHDR; + if (preferHDR) { + mediaOptionListInfo.preferHDR = false; + } + else { + mediaOptionListInfo.preferHDR = mediaOptionListInfo.hasHdrLevels; + } + if (mediaOptionListInfo.preferHDR !== preferHDR) { + logger.warn(`No valid first variant found, toggling hdr preference=${preferHDR}->${mediaOptionListInfo.preferHDR}`); + ({ firstVariant, filteredVariants } = selectStartingVariant(rootPlaylistEntity, logger, bandwidthEstimate, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate)); + } + } + if (!firstVariant) { + throw new ExceptionError(true, 'No valid first variant found', ErrorResponses.NoValidAlternates); + } + const preferredHost = getHostName(firstVariant.url); + logger.info(loggerName, `First level ${itemId}: ${mediaOptionToString(firstVariant)}`); + const variantId = (_a = firstVariant === null || firstVariant === void 0 ? void 0 : firstVariant.mediaOptionId) !== null && _a !== void 0 ? _a : null; + const variantKey = { itemId, mediaOptionId: variantId }; + const altAudioId = (filteredAudio === null || filteredAudio === void 0 ? void 0 : filteredAudio.length) + ? (_b = getAutoAudio(existingSelection === null || existingSelection === void 0 ? void 0 : existingSelection.audioPersistentId, firstVariant.audioGroupId, rootPlaylistEntity.audioMediaSelectionGroup, filteredAudio)) === null || _b === void 0 ? void 0 : _b.mediaOptionId + : null; + const altAudioKey = altAudioId ? { itemId, mediaOptionId: altAudioId } : NoMediaOption; + const firstSubtitle = getAutoSubtitle(existingSelection === null || existingSelection === void 0 ? void 0 : existingSelection.subtitlePersistentId, firstVariant.closedcaption, firstVariant.subtitleGroupId, rootPlaylistEntity.subtitleMediaSelectionGroup, filteredSubtitles, logger); + const subtitleId = (filteredSubtitles === null || filteredSubtitles === void 0 ? void 0 : filteredSubtitles.length) ? firstSubtitle === null || firstSubtitle === void 0 ? void 0 : firstSubtitle.mediaOptionId : null; + const subtitleKey = subtitleId ? { itemId, mediaOptionId: subtitleId, mediaOptionType: MediaOptionType.Subtitle } : NoMediaOption; + const { mediaOptions, audioGroups, subtitleGroups, closedCaptionGroups } = filterMediaOptionsBasedOnFirstMediaOptions(filteredVariants, firstVariant); + const compatibleVariants = Array.from(mediaOptions).map((mediaOption) => mediaOption.mediaOptionId); + const currentPathwayID = firstVariant.pathwayID; + const updatedMediaOptionListInfo = Object.assign(Object.assign({}, mediaOptionListInfo), { compatibleIds: compatibleVariants, preferredHost, + currentPathwayID }); + // audio + const compatibleAudioAlternates = []; + const audioMediaOptions = audioOptionListInfo.mediaOptions; + const filteredAudioResults = audioMediaOptions.reduce((prev, cur) => { + if (audioGroups.has(cur.groupId)) { + prev.persistentIds.add(cur.persistentID); + compatibleAudioAlternates.push(cur.mediaOptionId); + prev.filteredAudioMediaOptions.push(cur); + if (!prev.altAudio) { + prev.altAudio = !!cur.url; + } + } + return prev; + }, { filteredAudioMediaOptions: [], persistentIds: new Set(), altAudio: false }); + const updatedAudioOptionListInfo = Object.assign(Object.assign({}, audioOptionListInfo), { compatibleIds: compatibleAudioAlternates }); + let audioMediaSelectionGroup = rootPlaylistEntity.audioMediaSelectionGroup; + const audioMediaSelectionOptions = audioMediaSelectionGroup === null || audioMediaSelectionGroup === void 0 ? void 0 : audioMediaSelectionGroup.MediaSelectionGroupOptions; + if (audioMediaSelectionOptions) { + const filteredAudioSelectionOptions = audioMediaSelectionOptions.reduce((prev, cur) => { + if (filteredAudioResults.persistentIds.has(cur.MediaSelectionOptionsPersistentID)) { + prev.push(cur); + } + return prev; + }, new Array()); + audioMediaSelectionGroup = Object.assign(Object.assign({}, audioMediaSelectionGroup), { MediaSelectionGroupOptions: filteredAudioSelectionOptions }); + } + // subtitle + subtitleOptionListInfo.mediaOptions = replaceClosedCaptionInMediaOptionListIfNecessary(firstVariant, firstSubtitle, subtitleOptionListInfo.mediaOptions, logger); + const subtitleMediaOptions = subtitleOptionListInfo.mediaOptions; + const filteredSubtitleResults = subtitleMediaOptions.reduce((prev, cur) => { + if (subtitleGroups.has(cur.groupId)) { + // do NOT re-assign track id. They must be unique for the entire collection of subtitle and caption tracks + // cur.id = prev.filteredSubtitleMediaOptions.length; + prev.persistentIds.add(cur.persistentID); + prev.filteredSubtitleMediaOptions.push(cur); + } + return prev; + }, { filteredSubtitleMediaOptions: [], persistentIds: new Set() }); + let subtitleMediaSelectionGroup = rootPlaylistEntity.subtitleMediaSelectionGroup; + const subtitleMediaSelectionOptions = subtitleMediaSelectionGroup === null || subtitleMediaSelectionGroup === void 0 ? void 0 : subtitleMediaSelectionGroup.MediaSelectionGroupOptions; + if (subtitleMediaSelectionOptions) { + const filteredSubtitleSelectionOptions = subtitleMediaSelectionOptions.reduce((prev, cur) => { + if (filteredSubtitleResults.persistentIds.has(cur.MediaSelectionOptionsPersistentID)) { + prev.push(cur); + } + return prev; + }, new Array()); + subtitleMediaSelectionGroup = Object.assign(Object.assign({}, subtitleMediaSelectionGroup), { MediaSelectionGroupOptions: filteredSubtitleSelectionOptions }); + } + const mediaOptionListTuple = [updatedMediaOptionListInfo, updatedAudioOptionListInfo, subtitleOptionListInfo]; + // Find the highest codec string per codec family + let highestVideoCodec = new Map(); + const hlsConf = getCurrentConfig(); + if (hlsConf.useHighestVideoCodecPrivate) { + highestVideoCodec = updatedMediaOptionListInfo === null || updatedMediaOptionListInfo === void 0 ? void 0 : updatedMediaOptionListInfo.mediaOptions.reduce((codecStringMap, mediaOption) => { + const codecStringList = mediaOption.videoCodecList; + if (codecStringList) { + for (const codec of codecStringList) { + const key = getVideoCodecFamily(codec); + const currentCodec = codecStringMap.get(key); + if (MediaUtil.isHigherCodecByFamily(currentCodec, codec)) { + codecStringMap.set(key, codec); + } + } + } + return codecStringMap; + }, highestVideoCodec); + } + if (highestVideoCodec.size) { + highestVideoCodec.forEach((value, key) => logger.info(`override for ${key} family with codec ${value}`)); + } + const abrStatus = { + fragDownloadSlow: false, + fragDownloadTooSlow: false, + nextMinAutoOptionId: NoMediaOption.mediaOptionId, + nextMaxAutoOptionId: NoMediaOption.mediaOptionId, + highBWTrigger: getLowestSuperiorBW(variantKey.mediaOptionId, updatedMediaOptionListInfo.mediaOptions), + }; + return Object.assign(Object.assign({}, rootPlaylistEntity), { enabledMediaOptionKeys: [variantKey, altAudioKey, subtitleKey], mediaOptionListTuple, + audioMediaSelectionGroup, + abrStatus, + highestVideoCodec }); + } + /** + * @brief Load the root playlist + * + */ + const retrieveRootMediaOptions = (loadPolicy, rootPlaylistService, config, platformQuery, existingSelection, statsService, playerEvents) => (source) => { + return source.pipe(tag('retrieveRootMediaOptions.input'), switchMap((item) => { + var _a, _b; + if (!item) + return EMPTY; + const { itemId, platformInfo } = item; + const rootPlaylistQuery = createRootPlaylistQuery(itemId); + const { logger } = rootPlaylistService; + if (rootPlaylistQuery.hasEntity(itemId)) { + // these needs to handle failures and stuff + return of(rootPlaylistQuery); + } + rootPlaylistStore.setLoading(true); + const tManifestLoadStart = performance.now(); + return loadRootMediaOptions(item, loadPolicy, logger, config, statsService, (_b = (_a = globalHlsService()) === null || _a === void 0 ? void 0 : _a.getQuery()) === null || _b === void 0 ? void 0 : _b.extendMaxTTFB).pipe(tap((loadRootMediaOptionsResult) => playerEvents.triggerManifestLoaded(loadRootMediaOptionsResult)), tap(({ initialDetails, sessionData, stats }) => { + if (initialDetails) { + archiveMediaOptionDetails(initialDetails, stats, true); + } + }), withLatestFrom(platformQuery.displaySupportsHdr$), switchMap(([loadRootMediaOptionsResult, displaySupportsHdr]) => updateBasedOnPlatformCapabilities(loadRootMediaOptionsResult, platformInfo, config, displaySupportsHdr, logger)), map((rootPlaylistEntity) => { + rootPlaylistService.rootPlaylistEntity = initializeRootEntity(item, rootPlaylistEntity, existingSelection, tManifestLoadStart, config, logger); + return rootPlaylistQuery; + }), addLoadErrorHandlingPolicy(itemId, null, getLoadConfig(item, loadPolicy), 0, false, rootPlaylistQuery, rootPlaylistService, statsService), finalize$1(() => { + rootPlaylistStore.setLoading(false); + })); + }), tag('retrieveRootMediaOptions.emit')); + }; + /** + * @brief Choose first media options and update initial seek position + * @returns updated RootPlaylistEntity with selected media options and seek time + */ + function initializeRootEntity(item, rootPlaylistEntity, existingSelection, tManifestLoadStart, config, logger) { + const { itemId, initialSeekTime, itemStartOffset } = item; + const statsQuery = createStatsQuery(itemId); + const bandwidthEstimate = config.enableAdaptiveStartup ? statsQuery.getBandwidthEstimate(config, item.serviceName) : undefined; + const playlistEstimate = config.enableAdaptiveStartup ? statsQuery.getPlaylistEstimate(config, item.serviceName) : undefined; + const fragEstimate = config.enableAdaptiveStartup ? statsQuery.getFragEstimate(config, item.serviceName) : undefined; + const bufferEstimate = config.enableAdaptiveStartup ? statsQuery.getBufferEstimate(config, item.serviceName) : undefined; + const timeElapsed = performance.now() - tManifestLoadStart; + let targetStartupMs; + if (config.targetStartupMs > timeElapsed) { + targetStartupMs = config.targetStartupMs - timeElapsed; + } + else { + /* In some edge cases, such as network is too slow/lossy, it is seen that the manifestLoad takes longer resulting in timeElapsed go above config.targetStartupMs. + To avoid targetStartupMs being negative, fall back to config.targetStartupMs */ + targetStartupMs = config.targetStartupMs; + logger.warn(`Manifest load took ${timeElapsed}ms and exceeds targetStartupMs: ${config.targetStartupMs}; resetting targetStartupMs to ${config.targetStartupMs}`); + } + const adaptiveStartupConfig = config.enableAdaptiveStartup + ? { + targetDuration: fragEstimate.maxDurationSec || config.defaultTargetDuration, + targetStartupMs: targetStartupMs, + } + : undefined; + const updatedRootPlaylistEntity = updateRootPlaylistEntityWithEnabledMediaOptionKeys(rootPlaylistEntity, existingSelection, logger, bandwidthEstimate, adaptiveStartupConfig, playlistEstimate, fragEstimate, bufferEstimate); + // Initialize pendingSeek if this is not a preloading item. don't update anchorTime yet. + updatedRootPlaylistEntity.pendingSeek = initialSeekTime; + return updatedRootPlaylistEntity; + } + + /** + * @brief Create all adapters for hls. they will live while media is attached + */ + function makeAdapters(itemRemove$, ksService, config, platformQuery, eventEmitter, rtcService, logger) { + return (source$) => { + const keySystemAdapter = makeKeySystemService(ksService, source$, itemRemove$, config, platformQuery, eventEmitter, rtcService, logger); + const legibleSystemAdapter = makeLegibleService(source$, config, eventEmitter, logger); + return combineLatest([keySystemAdapter, legibleSystemAdapter, source$]).pipe(map(([keySystemAdapter, legibleSystemAdapter, mediaSink]) => { + return { keySystemAdapter, legibleSystemAdapter, mediaSink }; + })); + }; + } + function makeActiveItemAdapters(config, logger, rootPlaylistService, platformQuery, statsService, playerEvents, rpcClients) { + return (activeItem$) => activeItem$.pipe(filterNullOrUndefined(), switchMap((activeItem) => { + logger.info(`active item changed ${activeItem === null || activeItem === void 0 ? void 0 : activeItem.itemId}`); + if (!activeItem) { + return of(null); + } + const rootPlaylistQuery$ = of(activeItem).pipe(retrieveRootMediaOptions(config.manifestLoadPolicy, rootPlaylistService, config, platformQuery, null, statsService, playerEvents)); + return combineLatest([rootPlaylistQuery$, createMediaParser(config, logger, rpcClients.mux), createIframeMachine(config.trickPlaybackConfig, logger)]).pipe(map(([rootPlaylistQuery, mediaParser, iframeMachine]) => ({ rootPlaylistQuery, mediaParser, iframeMachine }))); + })); + } + /** + * @brief Observable for updating platform information + */ + function platformUpdater(platformService) { + return listenForHdrUpdates(platformService).pipe(switchMapTo(EMPTY)); + } + /** + * @brief Top level class that handles setup of playback for a queue of items + */ + class Hls$1 extends HlsEventEmitter { + constructor(userConfig = {}, logger) { + var _a; + super(); + this.destroy$ = new Subject(); + this.mediaElement$ = new BehaviorSubject(null); + this.publicQueriesInternal$ = new BehaviorSubject(null); + this.mediaElementAdapter = null; + this.rpcService = null; + this.rpcClients = null; + this.platformService = platformService(); + this.keySystemAdapter = null; + this.legibleSystemAdapter = null; + this.sessionID = guid(); + this.statsService = statsServiceSingleton(); + this.gaplessCapable = true; + this.teardownWG$ = new WaitGroup(); + this.itemQueue = new ItemQueue(); + // Sanitize userConfig + if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) { + throw new Error('Illegal hls.js config: don\'t mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration'); + } + const config = Object.assign(Object.assign({}, hlsDefaultConfig), userConfig); + if (config.maxRequiredStartDuration < config.minRequiredStartDuration || config.minRequiredStartDuration < 0) { + throw new Error('Illegal config: bad maxRequiredStartDuration or minRequiredStartDuration'); + } + this.hlsConfig = config; + // setup the redact url function + setupRedactUrl(config.buildType); + // set up logger + const { sessionID: sessionId } = this; + let logLevel = 'silent'; + if (userConfig.debug) { + logLevel = config.debugLevel; + } + // rdar://88106960 (HLS with buildType "production" much slower than with buildType "development") + // setting autoFreeze to true follows default behavior with immer 8.0+ + setAutoFreeze_1(true); + { + // for unit tests only + this.logger = logger; + } + this.logger = + (_a = this.logger) !== null && _a !== void 0 ? _a : setupLoggerSingleton(sessionId, 'hls', getLoggerConfig({ + sendLogs: config.sendLogs || (config.log ? LoggerExternals$1().logStore : null), + level: logLevel === 'log' ? 'debug' : logLevel, + consoleOverride: typeof userConfig.debug !== 'boolean' ? userConfig.debug : undefined, + buildType: config.buildType, + })); + this.logger.qe({ critical: true, name: 'playerVersion', data: { version: Hls$1.version } }); + { + this.logger.qe({ critical: true, name: 'playerCommit', data: { hash: '0c65bb95' } }); + this.logger.qe({ critical: true, name: 'playerBranch', data: { hash: 'release/2.162' } }); + initialize(userConfig.socketurl, userConfig.socketid); + setHls(this); + setLogger(this.logger); + } + this.hlsConfig.audioPrimingDelay = 0; + this.logger.info(`force audioPrimingDelay to ${this.hlsConfig.audioPrimingDelay}`); + this.rootPlaylistService = rootPlaylistService(this.logger); + this.customUrlLoader = getCustomUrlLoader(); + this.sessionDataLoader = new SessionDataLoader(config, fromXMLHttpRequest, this.customUrlLoader.load, this.logger); + const liveMaxLatencyDurationCount = config.liveMaxLatencyDurationCount; + const liveSyncDurationCount = config.liveSyncDurationCount; + if (isFiniteNumber(liveMaxLatencyDurationCount) && isFiniteNumber(liveSyncDurationCount) && liveMaxLatencyDurationCount <= liveSyncDurationCount) { + throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be gt "liveSyncDurationCount"'); + } + if (isFiniteNumber(config.liveMaxLatencyDuration) && (config.liveMaxLatencyDuration <= config.liveSyncDuration || !isFiniteNumber(config.liveSyncDuration))) { + throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be gt "liveSyncDuration"'); + } + const hlsService = globalHlsService(); + this.logger.info(`start Hls sessionId:${sessionId}`); + hlsService.setHlsEntity({ id: sessionId, config }); + const mediaLibService = mediaLibraryService(); + const platformQuery = createPlatformQuery(); + const ksService = keySystemService(); + this.accessLogInstance = new AccessLog(this, sessionId); + this.rtcService = new RTCService(this, config, this.accessLogInstance, this.logger); + this.playerEvents = new HlsPlayerEvents(this, this.logger, this.rtcService); + // Update platform information (display, etc) + const updatePlatformInfo$ = platformUpdater(this.platformService); + const mediaSink$ = this.mediaElement$.pipe(mediaElementServiceEpic(() => { + return new MediaSource(); + }, config, this, this.logger, this.teardownWG$, this.rtcService), share() // Prevent us from making a new MediaSink for each thing subscribing to this observable + ); + // Things that depend on active item. + const handleActiveItemChange$ = this.itemQueue.activeItemById$.pipe(switchMap((entity) => { + if (!entity) { + return EMPTY; + } + return statsProcessor(config, this.statsService, entity, this.logger); + })); + this.rpcService = (() => { + let create = null; + if (config.createRPCService != null) { + create = createRPCServiceWithFallbacks(config.createRPCService, createRPCInlineService); + } + if (hasUMDWorker() && config.enableWorker) { + if (create == null) { + create = createRPCService; + } + } + if (create == null) { + create = createRPCInlineService; + } + return create(this.logger); + })(); + this.rpcClients = createRPCClients(this.rpcService); + // Emits when we have all context available for pipeline. + // CAUTION: every time this observable emits it will cause pipelineCtxHandlers$ to + // teardown and re-subscribe (if applicable). Only emit on /changes/ to pipeline context! + const pipelineContext$ = combineLatest([ + // Emit when root playlist loaded + this.itemQueue.activeItemById$.pipe(makeActiveItemAdapters(config, this.logger, this.rootPlaylistService, platformQuery, this.statsService, this.playerEvents, this.rpcClients), tap((rootAdapters) => { + const rootPlaylistQuery = rootAdapters === null || rootAdapters === void 0 ? void 0 : rootAdapters.rootPlaylistQuery; + // prep publicQueriesInternal to serve api calls, that + // depend on rootPlaylistQuery exclusively. + this.publicQueriesInternal$.next([rootPlaylistQuery, null]); + this.iframeMachine = rootAdapters === null || rootAdapters === void 0 ? void 0 : rootAdapters.iframeMachine; + if (rootPlaylistQuery) { + // this is delayed trigger for manifest parsed, but doing it before + // setting in publicQueriesInternal will make some api such as + // sessionData non serviceable. + this.playerEvents.triggerManifestParsed(rootPlaylistQuery); + } + })), + // Emit when all adapters created / destroyed + mediaSink$.pipe(makeAdapters(this.itemQueue.removedItems$, ksService, config, platformQuery, this, this.rtcService, this.logger), tap(({ keySystemAdapter, legibleSystemAdapter, mediaSink }) => { + this.keySystemAdapter = keySystemAdapter; + this.legibleSystemAdapter = legibleSystemAdapter; + this.mediaElementAdapter = mediaSink; + })), + ]).pipe(map(([activeItemAdapters, mediaAdapters]) => { + const { keySystemAdapter, legibleSystemAdapter, mediaSink } = mediaAdapters; + if (!activeItemAdapters || !keySystemAdapter || !legibleSystemAdapter || !mediaSink) { + return null; // Stop everything depending on this + } + const { rootPlaylistQuery, iframeMachine, mediaParser } = activeItemAdapters; + return { + logger: this.logger, + config, + platformService: this.platformService, + statsService: this.statsService, + rtcService: this.rtcService, + rpcClients: this.rpcClients, + rootPlaylistService: this.rootPlaylistService, + rootPlaylistQuery, + mediaLibraryService: mediaLibService, + keySystemAdapter, + legibleSystemAdapter, + mediaSink, + mediaParser, + iframeMachine, + customUrlLoader: this.customUrlLoader, + gaplessInstance: this, + }; + }), share()); + // Things that depend on PipelineContext. This means rootPlaylist loaded && mediaSink != null + const pipelineCtxHandlers$ = pipelineContext$.pipe(switchMap((context) => { + if (!context) { + return EMPTY; + } + const { rootPlaylistQuery, mediaSink, mediaLibraryService } = context; + this.publicQueriesInternal$.next([rootPlaylistQuery, mediaSink.mediaQuery]); + const mediaQuery = mediaSink.mediaQuery; + const mediaFragmentPipeline$ = of(context).pipe(mediaFragmentPipelineEpic()); + // TODO: Fix rdar://81171922 and re-enable content steering + // const loadSteeringManifest$ = of(rootPlaylistQuery).pipe(contentSteeringEpic(context.rootPlaylistService, config, config.steeringManifestLoadPolicy, this.logger)); + // AirPlay may pick the alternates before hls.rootQuery and rootQuery.rootPlaylistEntity are ready. + // Delay these early selections when hls is instantiating. + // We should not need these early alternate selections for gapless items since + // (i) follow-up items should inherit the existing language selections. + // (ii) hls.rootQuery has been setup and rootQuery.rootPlaylistEntity lifecycle (for the next itemId) is controlled by hls.js + const earlySelection$ = rootPlaylistQuery.rootPlaylistEntity$.pipe(filterNullOrUndefined(), take(1), tap(() => { + this.commitEarlySelection(context.logger); // earliest point where this._activeRootQuery is valid + })); + const loadSessionData$ = waitFor(combineLatest([mediaQuery.haveEnough$, rootPlaylistQuery.sessionData$]), ([haveEnough]) => haveEnough === true, 1).pipe(switchMap(([, sessionData]) => { + return this.sessionDataLoader.loadSessionData(sessionData); + }), tap((sessionData) => { + this.rootPlaylistService.setSessionData(rootPlaylistQuery.itemId, sessionData); + }), catchError((err) => { + this.logger.error(err.message); + return EMPTY; + })); + // Is this a good place to put this.... + const statsQuery = createStatsQuery(rootPlaylistQuery.itemId); + const haveEnough$ = checkForHaveEnough(config, this.logger, rootPlaylistQuery, mediaSink, mediaLibraryService, statsQuery); + const ended$ = checkForEndOfStream(context); + const iframeAutoPause$ = checkForIframeAutoPause(context); + const iframePrefetch$ = checkForIframePrefetch(context); + const playbackInfo$ = waitFor(combineQueries([mediaQuery.gotPlaying$, mediaQuery.gotLoadStart$, mediaQuery.readyState$]), ([playing, loadStart, readyState]) => playing === true || loadStart === true || readyState >= 1).pipe(switchMap(() => mediaQuery.ended$), + // on ended, fire once and stop, else every 1s + switchMap((ended) => timer(0, ended ? undefined : 1000)), tap(() => { + this.playbackInfo(config, mediaQuery); + })); + const updatePlayingId$ = mediaQuery.timeupdate$.pipe(map((pos) => { + if (this.inGaplessMode && this.isPreloading) { + if (isFiniteNumber(this.loadingItem.itemStartOffset) && pos >= this.loadingItem.itemStartOffset) { + const prevItemId = this.itemQueue.playingItem.itemId; + const nextItemId = this.itemQueue.loadingItem.itemId; + const nextStartTime = this.loadingItem.itemStartOffset; + const nextDuration = mediaQuery.msDuration - this.loadingItem.itemStartOffset; + const data = { prevItemId, nextItemId, nextStartTime, nextDuration }; + this.logger.info(`[gapless] Item transitioned prevItem: ${prevItemId}, nextItem: ${nextItemId}, nextStartTime: ${nextStartTime}, nextDuration: ${nextDuration}`); + this.itemQueue.updatePlayingItemId(); + this.trigger(HlsEvent.ITEM_TRANSITIONED, data); + this.rtcService.itemTransitioned(prevItemId, nextItemId); + this.logger.qe({ critical: true, name: 'gapless', data: { transitionFrom: prevItemId, transitionTo: nextItemId } }); + } + } + })); + const liveSeekableRange$ = this.updateLiveSeekableRange(rootPlaylistQuery, mediaSink); + const observableList = [ + earlySelection$, + mediaFragmentPipeline$, + // TODO: Fix rdar://81171922 and re-enable content steering + // loadSteeringManifest$, // Load steering manifest + loadSessionData$, + haveEnough$, + playbackInfo$, + iframeAutoPause$, + iframePrefetch$, + updatePlayingId$, + liveSeekableRange$, + ended$, // Check for end of stream + ]; + if (config.enablePerformanceLogging) { + const tlog = this.logger.child({ name: 'timing' }); + // Log currently loading fragments + const inFlightFrags$ = zip(...AVMediaOptionTypes.map((type) => { + return rootPlaylistQuery.getInFlightFragByType$(type).pipe(distinctUntilChanged((a, b) => (a === null || a === void 0 ? void 0 : a.state) === (b === null || b === void 0 ? void 0 : b.state)), filterNullOrUndefined(), withLatestFrom(mediaQuery.bufferedRangeTuple$), tap(([inFlightInfo, bufferedRanges]) => { + const payload = Object.assign(Object.assign({}, inFlightInfo), { event: 'fragment', name: MediaOptionNames[type], buffered: undefined }); + if (inFlightInfo.state === 'appended') { + payload.buffered = bufferedRanges; + } + tlog.info(JSON.stringify(payload)); + }), catchError(() => EMPTY)); + })); + // Log whenever detailsLoading changes + const loadingPlaylist$ = zip(...MediaOptionTypes.map((type) => { + return rootPlaylistQuery.enabledMediaOptionByType$(type).pipe(switchMap((option) => { + if ((option === null || option === void 0 ? void 0 : option.url) == null || !isEnabledMediaOption(option)) { + return EMPTY; + } + const query = createMediaLibraryQuery(option); + return query.mediaOptionDetailsEntity$.pipe(filterNullOrUndefined(), map((entity) => ({ entity, option })), distinctUntilChanged((a, b) => (a === null || a === void 0 ? void 0 : a.entity.detailsLoading) === (b === null || b === void 0 ? void 0 : b.entity.detailsLoading)), tap(({ entity, option }) => { + if (!entity || !option) { + return; + } + const payload = { + event: 'playlist', + name: MediaOptionNames[option.mediaOptionType], + mediaOptionId: option.mediaOptionId, + state: entity.detailsLoading ? 'loading' : 'loaded', + }; + tlog.info(JSON.stringify(payload)); + })); + }), catchError(() => EMPTY)); + })); + observableList.push(inFlightFrags$, loadingPlaylist$); + } + return merge(...observableList); + })); + const handleQueueItemRemove$ = this.itemQueue.removedItems$.pipe(withTransaction((ids) => { + // Cleanup everything with lifecycle tied to QueueItem + mediaLibraryRemove(ids); + this.rootPlaylistService.removeItems(ids); + })); + const userSeek$ = hlsService.getQuery().userSeek$.pipe(userSeekEpic(this.itemQueue, this.rootPlaylistService)); + const gotNewHls$ = hlsService + .getQuery() + .selectEntityAction(EntityActions.Add) + .pipe(tap(() => { + this.logger.warn(`new Hls instance added while old one still active sessionId:${sessionId}`); + })); + merge( + // Keep mediaSink alive even if other stuff errors out just in case we need play to end of buffer handling + // PipelineContext is subscribed to by pipelineCtxHandler$ so errors should be caught in other observable. + mediaSink$.pipe(catchError(() => EMPTY)), merge(updatePlatformInfo$, userSeek$, handleActiveItemChange$, handleQueueItemRemove$, pipelineCtxHandlers$, this.teardownWG$).pipe(catchError((err) => this._handleError(err)))) + .pipe(finalize$1(() => { + var _a, _b; + try { + this.logger.info(`finalize Hls sessionId:${sessionId}`); + // Clean up everything with lifecycle tied to HLS instance: + this.detachMedia(); + this.trigger(HlsEvent.DESTROYING); + this.playerEvents.destroy(); + (_a = this.accessLogInstance) === null || _a === void 0 ? void 0 : _a.destroy(); + (_b = this.rtcService) === null || _b === void 0 ? void 0 : _b.destroy(); + mediaLibraryClear(); + this.rootPlaylistService.removeAll(); + this.itemQueue.clearQueue(); + hlsService.removeEntity(this.sessionID); + } + catch (err) { + this.logger.error(`Got error in finalize ${err.message}`); + } + }), takeUntil(race(this.destroy$, gotNewHls$))) + .subscribe(); + } + get publicQueries$() { + return this.publicQueriesInternal$.pipe(filter((queries) => Boolean(queries) && Boolean(queries[0]) && Boolean(queries[1]))); + } + get _activeRootQuery() { + var _a; + const publicQueries = this.publicQueriesInternal$.value; + return (_a = publicQueries === null || publicQueries === void 0 ? void 0 : publicQueries[0]) !== null && _a !== void 0 ? _a : null; + } + get _mediaElementQuery() { + var _a; + const publicQueries = this.publicQueriesInternal$.value; + return (_a = publicQueries === null || publicQueries === void 0 ? void 0 : publicQueries[1]) !== null && _a !== void 0 ? _a : null; + } + static get version() { + return '2.162.2'; + } + /** + * @type {HlsEvent} + */ + static get Events() { + return HlsEvent; + } + get Events() { + return Hls$1.Events; + } + /** + * @type {HlsConfig} + */ + static get DefaultConfig() { + return deepCpy(hlsDefaultConfig); + } + get DefaultConfig() { + return Hls$1.DefaultConfig; + } + /** + * @type {boolean} + */ + static isSupported() { + return isSupported(); + } + commitEarlySelection(logger) { + const audioPersistentId = this.itemQueue.earlyAudioSelection; + if (isFiniteNumber(audioPersistentId)) { + logger.info(`use early audio selection ${audioPersistentId}`); + this.audioSelectedPersistentID = audioPersistentId; + this.itemQueue.earlyAudioSelection = null; + } + const subtitlePersistentId = this.itemQueue.earlySubtitleSelection; + if (isFiniteNumber(subtitlePersistentId)) { + logger.info(`use early subtitle selection ${subtitlePersistentId}`); + this.subtitleSelectedPersistentID = subtitlePersistentId; + this.itemQueue.earlySubtitleSelection = null; + } + } + /** + * Global error handler. If we've reached here, we've exhausted all other options + * and it's likely fatal. All errors should bubble up from the observables in the pipe + */ + _handleError(err) { + var _a; + try { + let errMessage = err.message; + { + errMessage += `\n${err.stack}`; + } + this.logger.error(`Got unhandled or fatal error ${errMessage}`, err); + (_a = this.rtcService) === null || _a === void 0 ? void 0 : _a.handleError(err); + let newError; + if (err instanceof HlsError) { + newError = err; + } + else { + newError = new ExceptionError(true, err.message, ErrorResponses.InternalError); + } + if (newError.fatal && this.isPreloading) { + this.logger.warn('Fatal error seen while preloading, calling dequeueSource'); + this.dequeueSource('FatalErrorWhileLoading'); + } + const shouldEscalateError = newError.fatal; + if (shouldEscalateError) { + this.logger.qe({ critical: true, name: 'fatalError', data: { msg: newError.message, stack: newError.stack } }); + let triggerError$ = VOID; + if (this.mediaElementAdapter) { + const mediaQuery = this.mediaElementAdapter.mediaQuery; + const combinedBuffer = mediaQuery.getCombinedBufferInfo(mediaQuery.currentTime, 0); + if ((combinedBuffer === null || combinedBuffer === void 0 ? void 0 : combinedBuffer.len) > 0) { + this.logger.info(`playing to buffer end @${combinedBuffer.end}, pos=${mediaQuery.currentTime}`); + triggerError$ = waitFor(this.mediaElementAdapter.mediaQuery.stallInfo$, (stallInfo) => stallInfo != null).pipe(map(() => { })); + } + } + return triggerError$.pipe(switchMap(() => { + this.trigger(HlsEvent.ERROR, newError); + return EMPTY; + })); + } + this.trigger(HlsEvent.ERROR, newError); + } + catch (thrownError) { + this.logger.error(`Error thrown inside _handleError ${thrownError.message}`, thrownError); + throw thrownError; + } + return EMPTY; + } + updateLiveSeekableRange(rootPlaylistQuery, mediaSink) { + return rootPlaylistQuery.enabledMediaOptionByType$(MediaOptionType.Variant).pipe(switchMap((mediaOption) => { + const query = createMediaLibraryQuery(mediaOption); + let lastUpdate = 0; + // filter on entities that have loading set to false and have stats filled and have been updated + return query.mediaOptionDetailsEntity$.pipe(filterNullOrUndefined(), filter((entity) => { + var _a; + const retValue = entity.stats !== null && entity.detailsLoading === false && entity.lastUpdateMillis > lastUpdate; + lastUpdate = (_a = entity.lastUpdateMillis) !== null && _a !== void 0 ? _a : 0; + return retValue; + })); + }), switchMap((mediaDetailsEntity) => { + if (mediaDetailsEntity.unchangedCount === 0) { + if (mediaDetailsEntity.mediaOptionDetails.liveOrEvent) { + mediaSink.updateLiveSeekableRange(mediaDetailsEntity.mediaOptionDetails); + } + else { + mediaSink.clearLiveSeekableRange(); + } + } + return EMPTY; + })); + } + playbackInfo(config, mediaQuery) { + var _a; + const video = this.mediaElement$.getValue(); + if (!video) { + return; + } + const readyToPlay = video.readyState >= video.HAVE_FUTURE_DATA; + const playbackLikelyToKeepUp = mediaQuery.haveEnough && readyToPlay; + const playbackInfo = { + readyToPlay: readyToPlay, + playbackLikelyToKeepUp: playbackLikelyToKeepUp, + rate: video.playbackRate, + paused: video.paused, + position: video.currentTime, + duration: video.duration, + seekableTimeRanges: MediaElementHelper.timeRangeToArray(video.seekable), + loadedTimeRanges: MediaElementHelper.timeRangeToArray(video.buffered), + }; + let droppedVideoFrames = 0, decodedFrameCount = 0; + if (MediaElementHelper.isHtmlVideoElement(video)) { + const videoPlaybackQuality = video.getVideoPlaybackQuality; + if (videoPlaybackQuality && typeof videoPlaybackQuality === typeof Function) { + const videoQuality = video.getVideoPlaybackQuality(); + droppedVideoFrames = playbackInfo.droppedVideoFrames = videoQuality.droppedVideoFrames; + playbackInfo.corruptedVideoFrames = videoQuality.corruptedVideoFrames; + playbackInfo.totalVideoFrames = videoQuality.totalVideoFrames; + decodedFrameCount = playbackInfo.totalVideoFrames - droppedVideoFrames; + } + } + else if (MediaElementHelper.isWebkitMediaElement(video)) { + droppedVideoFrames = playbackInfo.droppedVideoFrames = video.webkitDroppedFrameCount; + decodedFrameCount = playbackInfo.decodedFrameCount = video.webkitDecodedFrameCount; + } + if (config.enablePerformanceLogging) { + this.logger.qe({ critical: true, name: 'playbackInfo', data: playbackInfo }); + const [variantBufferInfo, altAudioBufferInfo] = mediaQuery.getCombinedMediaSourceBufferInfo(config.maxBufferHole); + this.logger.qe({ critical: true, name: 'bufferInfo', data: { variant: variantBufferInfo, altAudio: altAudioBufferInfo } }); + } + (_a = this.rtcService) === null || _a === void 0 ? void 0 : _a.handlePlaybackInfo(droppedVideoFrames, decodedFrameCount); + } + get currentItem() { + if (this.isPreloading) { + this.logger.info('Currently preloading, returning playing item'); + return this.playingItem; + } + return this.itemQueue.activeItem; + } + get realCurrentTime() { + var _a, _b; + const mediaQuery = this._mediaElementQuery; + if (!mediaQuery) { + return NaN; + } + // during trick-playback + if ((_a = this.iframeMachine) === null || _a === void 0 ? void 0 : _a.isStarted) { + const duration = mediaQuery.mediaElementDuration; + const ifct = this.iframeMachine.iframeClockTimeSeconds; + return ifct > duration ? duration : ifct; + } + // After trick-play is stopped, before seek to postFlushSeek, return postFlushSeek time until postFlushSeek is set to undefined when seek complete + let currentTime = isFiniteNumber(mediaQuery.postFlushSeek) ? mediaQuery.postFlushSeek : mediaQuery.currentTime; + // if the playing item is a finite number, remove it from real current time. + // No need to check inGaplessMode mode here because there situations where inGaplessMode is false + // but itemStartOffset is finite e.g. when playing the last song in an album + if (isFiniteNumber(currentTime) && isFiniteNumber((_b = this.playingItem) === null || _b === void 0 ? void 0 : _b.itemStartOffset)) { + currentTime -= this.playingItem.itemStartOffset; + } + return currentTime; + } + set realCurrentTime(value) { + var _a; + this.logger.info(`[seek] realCurrentTime ${value}`); + // if the playing item is a finite number, add it to the value. + // No need to check inGaplessMode mode here because there situations where inGaplessMode is false + // but itemStartOffset is finite e.g. when playing the last song in an album + if (isFiniteNumber((_a = this.playingItem) === null || _a === void 0 ? void 0 : _a.itemStartOffset)) { + value += this.playingItem.itemStartOffset; + } + this.seekTo = value; + } + get bufferedDuration() { + var _a; + const mediaQuery = this._mediaElementQuery; + return (_a = mediaQuery === null || mediaQuery === void 0 ? void 0 : mediaQuery.getBufferedDuration()) !== null && _a !== void 0 ? _a : 0; + } + get sessionData() { + const rootPlaylistQuery = this._activeRootQuery; + return rootPlaylistQuery === null || rootPlaylistQuery === void 0 ? void 0 : rootPlaylistQuery.sessionData; + } + get supportedFrameRates() { + const { enabled } = this.hlsConfig.trickPlaybackConfig; + const supported = [0, 1]; + const rootQuery = this._activeRootQuery; + const libQuery = mediaLibraryService().getQuery(); + if (enabled && rootQuery && libQuery.getEntity(rootQuery.itemId)) { + const isLive = libQuery.getEntity(rootQuery.itemId).liveOrEvent; + if (isLive === false) { + supported.push(8, 24, 48, 96); + } + } + return supported; + } + loadSource(url, itemOptions, initialSeekTime) { + var _a, _b, _c, _d; + // If Playready key system is being requested and if it's not enabled for the browser, reject loading the source + if (this.config.keySystemPreference === 'playready' && !this.config.enablePlayReadyKeySystem) { + throw new ExceptionError(true, 'Playready key system is not supported now', ErrorResponses.UnsupportedKeySystemError); + } + if (!url || !url.trim().length) { + throw new ExceptionError(true, 'Empty loadSource url', ErrorResponses.EmptyLoadSourceError); + } + // inherit protocol from href + url = URLToolkit$1.buildAbsoluteURL(window.location.href, url, { alwaysNormalize: true }); + const logItemOptions = itemOptions && + Object.keys(itemOptions) + .filter((key) => ['itemId', 'streamID'].indexOf(key) >= 0) + .reduce((newObj, key) => (key in itemOptions ? Object.assign(newObj, { [key]: itemOptions[key] }) : newObj), {}); + this.logger.qe({ critical: true, name: 'loadSource', data: { url: redactUrl(url), itemOptions: logItemOptions, initialSeekTime } }); + if ((_a = itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.appData) === null || _a === void 0 ? void 0 : _a.reportingAgent) { + this.reportingAgent = itemOptions.appData.reportingAgent; + } + if (itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.userInfo) { + this.userInfo = itemOptions.userInfo; + } + (_b = this.accessLogInstance) === null || _b === void 0 ? void 0 : _b.setupReporter(itemOptions.appData); + if (itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.platformInfo) { + this.platformService.updatePlatformInfo(itemOptions.platformInfo); + } + // Append queries specific to certain hosts + if (urlNeedsUpdate(url, this.config.enableQueryParamsForITunes)) { + const queryParameters = { + language: itemOptions.language, + dsid: itemOptions.dsid, + subs: itemOptions.subs, + }; + url = updateUrlWithQueryStrings(url, itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.platformInfo, queryParameters); + itemOptions.inheritQuery = false; // don't inherit queries to subsequent requests + } + this.itemQueue.setQueueItem(`item:${(_c = itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.itemId) !== null && _c !== void 0 ? _c : guid()}`, url, initialSeekTime, itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.platformInfo, (_d = itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.appData) === null || _d === void 0 ? void 0 : _d.serviceName); + // clear this out. only makes sense for first asset + globalHlsService().setStartTime(undefined); + } + queueSource(url, itemOptions, initialSeekTime) { + var _a, _b, _c, _d; + this.logger.qe({ critical: true, name: 'queueSource', data: { url: redactUrl(url), itemOptions, initialSeekTime } }); + if (itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.userInfo) { + this.userInfo = itemOptions.userInfo; + } + const combinedBuffer = (_a = this._mediaElementQuery) === null || _a === void 0 ? void 0 : _a.getCombinedBufferInfo((_b = this._mediaElementQuery) === null || _b === void 0 ? void 0 : _b.currentTime, 0); + let duration = 0; + if (combinedBuffer) { + duration = combinedBuffer.end; + } + this.logger.info(`queueSource ${redactUrl(url)} initialSeekTime:${initialSeekTime === null || initialSeekTime === void 0 ? void 0 : initialSeekTime.toFixed(3)}`); + this.logger.qe({ critical: true, name: 'gapless', data: { itemLoadingAt: duration } }); + this.itemQueue.addQueueItem(`item:${(_c = itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.itemId) !== null && _c !== void 0 ? _c : guid()}`, url, initialSeekTime, itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.platformInfo, duration, (_d = itemOptions === null || itemOptions === void 0 ? void 0 : itemOptions.appData) === null || _d === void 0 ? void 0 : _d.serviceName); + } + dequeueSource(reason = 'ApplicationInitiated') { + // if we are not preloading and this is the first item and it's invalid format, disallow gapless + // but do not evict the item. It's probably a video + if (!this.isPreloading && reason === 'InvalidFormat' && this.isFirstItem) { + this.logger.error('First item has invalid format for gapless. Probably video. Disabling gapless.'); + this.gaplessCapable = false; + return; + } + if (!this.isPreloading) { + this.logger.warn(`Nothing to dequeue, no item is preloading dequeue reason: ${reason}`); + return; + } + this.logger.qe({ critical: true, name: 'gapless', data: { event: 'clean up current source' } }); + // Store loading item information + const itemToEvictUrl = this.loadingItem.url; + const itemToEvictId = this.loadingItem.itemId; + // flush all data from the loading item and set media sink duration + this.mediaElementAdapter.flushData(SourceBufferType.Variant, this.loadingItem.itemStartOffset, Infinity); + this.mediaElementAdapter.msDuration = this.loadingItem.itemStartOffset; + // clear loading item in queue and make playing item active. + this.itemQueue.resetLoadingItem(); + // Disallow gapless on invalidFormat and FatalErrorWhileLoading + if (reason === 'InvalidFormat' || reason === 'FatalErrorWhileLoading') { + // Disallow gapless + this.gaplessCapable = false; + } + // Send out item evicted event + this.triggerItemEvicted({ url: itemToEvictUrl, itemId: itemToEvictId }, reason); + } + triggerItemEvicted(itemToEvict, reason) { + if (itemToEvict === null) { + this.logger.error('dequeueSource called with no playing or loading item'); + return; + } + const data = { url: itemToEvict.url, evictedItemId: itemToEvict.itemId, reason }; + const loggableData = Object.assign(Object.assign({}, data), { url: redactUrl(itemToEvict.url) }); + this.logger.info('Item evicted evictedData: %o', loggableData); + this.trigger(HlsEvent.ITEM_EVICTED, data); + } + endSource() { + // When endSource is called, this hls instance is no longer gapless capable. + this.gaplessCapable = false; + this.logger.info('[gapless] end source'); + // if preloading clear buffers and remove loading item + if (this.isPreloading) { + this.logger.warn('EndSource called during preloading. Loading item will be removed'); + // flush all data from the loading item and set media sink duration + this.mediaElementAdapter.flushData(SourceBufferType.Variant, this.loadingItem.itemStartOffset, Infinity); + this.mediaElementAdapter.msDuration = this.loadingItem.itemStartOffset; + // clear loading item in queue and make playing item active. + this.itemQueue.resetLoadingItem(); + } + } + get inGaplessMode() { + //return this.config.gapless; //&& figure out who should know if gapless is allowed... item OR rootPlaylistService + // Don't call this.config because it does deepCpy and is deprecated + return getCurrentConfig().gapless && this.gaplessCapable; + } + get isPreloading() { + return this.itemQueue.isPreloading(); + } + get isFirstItem() { + return this.itemQueue.isFirstItem; + } + get loadingItem() { + return this.itemQueue.loadingItem; + } + get playingItem() { + return this.itemQueue.playingItem; + } + get url() { + if (this.playingItem) { + return this.playingItem.url; + } + if (this.loadingItem) { + return this.loadingItem.url; + } + return undefined; + } + destroy() { + const { logger } = this; + logger.info('destroy'); + // See finalize in Hls constructor for what happens on destroy$ + this.destroy$.next(); + if (this.rpcService != null) { + this.teardownWG$.add(); + this.rpcService.teardown((err) => { + if (err) { + logger.error('RPCService teardown error:', err); + } + this.teardownWG$.done(); + }); + this.rpcService = null; + } + if (this.iframeMachine != null) { + this.iframeMachine.destroy(); + this.iframeMachine = null; + } + return this.teardownWG$.toPromise(); + } + attachMedia(mediaElement) { + this.logger.info('attachMedia'); + this.trigger(HlsEvent.MEDIA_ATTACHING, { media: mediaElement }); + this.mediaElement$.next(mediaElement); + this.trigger(HlsEvent.MEDIA_ATTACHED, { media: mediaElement }); + } + detachMedia() { + var _a; + if (!this.mediaElement$.getValue()) { + this.logger.info('detachMedia called with no media element to detach'); + return; + } + this.logger.info('detachMedia'); + this.trigger(HlsEvent.MEDIA_DETACHING); + (_a = this.rtcService) === null || _a === void 0 ? void 0 : _a.detachMedia(); + if (this.iframeMachine != null) { + this.iframeMachine.stop(); + } + this.mediaElement$.next(null); + this.trigger(HlsEvent.MEDIA_DETACHED); + } + handleResolvedUri(originalURI, response) { + this.customUrlLoader.setCustomUrlResponse(originalURI, { uri: response.uri, response: response }); + } + get variantOptions$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [rootQuery, meQuery] = queries; + return combineLatest([rootQuery.preferredMediaOptions$, meQuery.desiredRate$]).pipe(map(([rootTuple]) => { + const iframeMode = meQuery.isIframeRate; + return rootTuple[MediaOptionType.Variant].filter((option) => { var _a; return ((_a = option.iframes) !== null && _a !== void 0 ? _a : false) === iframeMode; }).map((option) => option.mediaOptionId); + })); + })); + } + get altAudioOptions$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [rootQuery] = queries; + return of(rootQuery.audioMediaSelectionOptions); + })); + } + get subtitleOptions$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [rootQuery] = queries; + const disableOption = [ + { + MediaSelectionOptionsName: 'Disable subtitle', + MediaSelectionOptionsPersistentID: -1, + }, + ]; + return of(disableOption.concat(rootQuery.subtitleMediaSelectionOptions)); + })); + } + // Old public API used by webapp + get levels() { + var _a, _b; + return (_b = (_a = this._activeRootQuery) === null || _a === void 0 ? void 0 : _a.preferredMediaOptions[MediaOptionType.Variant]) !== null && _b !== void 0 ? _b : []; + } + // Old public API used by webapp + get audioTracks() { + var _a, _b; + return (_b = (_a = this._activeRootQuery) === null || _a === void 0 ? void 0 : _a.preferredMediaOptions[MediaOptionType.AltAudio]) !== null && _b !== void 0 ? _b : []; + } + get audioMediaOptions() { + var _a, _b; + return (_b = (_a = this._activeRootQuery) === null || _a === void 0 ? void 0 : _a.audioMediaSelectionOptions) !== null && _b !== void 0 ? _b : []; + } + get subtitleMediaOptions() { + var _a, _b; + return (_b = (_a = this._activeRootQuery) === null || _a === void 0 ? void 0 : _a.subtitleMediaSelectionOptions) !== null && _b !== void 0 ? _b : []; + } + /** + * @returns whether we are likely to keep up based on network and buffer + */ + get playbackLikelyToKeepUp() { + var _a, _b; + return (_b = (_a = this._mediaElementQuery) === null || _a === void 0 ? void 0 : _a.playbackLikelyToKeepUp) !== null && _b !== void 0 ? _b : false; + } + get duration$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [, mediaQuery] = queries; + return mediaQuery.mediaElementDuration$; + })); + } + get timeupdate$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [, mediaQuery] = queries; + return mediaQuery.timeupdate$; + })); + } + get playing$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [, mediaQuery] = queries; + return mediaQuery.gotPlaying$; + })); + } + get desiredRate$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [, mediaQuery] = queries; + return mediaQuery.desiredRate$; + })); + } + set desiredRate(desiredRate) { + if (desiredRate == null) { + return; + } + this.setRate(desiredRate); + } + get desiredRate() { + var _a, _b; + return (_b = (_a = this._mediaElementQuery) === null || _a === void 0 ? void 0 : _a.desiredRate) !== null && _b !== void 0 ? _b : 0; + } + get effectiveRate() { + var _a, _b; + return (_b = (_a = this._mediaElementQuery) === null || _a === void 0 ? void 0 : _a.effectiveRate) !== null && _b !== void 0 ? _b : 0; + } + get iframeMode() { + var _a, _b; + return (_b = (_a = this._mediaElementQuery) === null || _a === void 0 ? void 0 : _a.isIframeRate) !== null && _b !== void 0 ? _b : false; + } + get accessLog() { + return this.accessLogInstance && this._activeRootQuery ? this.accessLogInstance.getAccessLog(this._activeRootQuery.itemId) : []; + } + get errorLog() { + return this.accessLogInstance ? this.accessLogInstance.errorLog : []; + } + setRate(newRate) { + var _a; + const Errors = { UNABLE_TO_SWITCH: -1, ALREADY_IN_RATE: -2, UNSUPPORTED_RATE: -3 }; + const logger = this.logger.child({ name: 'iframes' }); + const oldRate = this.desiredRate; + if (newRate === oldRate) { + return Errors.ALREADY_IN_RATE; + } + logger.info(`setRate ${oldRate} -> ${newRate}`); + const mediaSink = this.mediaElementAdapter; + if (!mediaSink || isNaN(newRate)) { + logger.warn('unable to switch to rate, missing adapter or newRate isNaN'); + return Errors.UNABLE_TO_SWITCH; + } + newRate = Number(newRate); + const absRate = Math.abs(newRate); + const isSupportedRate = this.supportedFrameRates.some((rate) => rate === absRate); + if (!isSupportedRate) { + logger.warn(`unsupported rate(${newRate})`); + return Errors.UNSUPPORTED_RATE; + } + const iframeRate = isIframeRate(newRate); + const iframeMachine = this.iframeMachine; + if (iframeRate) { + const rootQuery = this._activeRootQuery; + if (!(rootQuery === null || rootQuery === void 0 ? void 0 : rootQuery.mediaOptionListQueries[MediaOptionType.Variant].hasIframes)) { + logger.warn('no iframe variants available'); + return Errors.UNABLE_TO_SWITCH; + } + mediaSink.postFlushSeek = null; + } + else if ((iframeMachine === null || iframeMachine === void 0 ? void 0 : iframeMachine.isStarted) && !isFiniteNumber((_a = mediaSink.mediaQuery) === null || _a === void 0 ? void 0 : _a.postFlushSeek)) { + iframeMachine.pause(); + logger.info(`resuming from trick-play postFlushSeek=${iframeMachine.iframeClockTimeSeconds}`); + mediaSink.postFlushSeek = iframeMachine.iframeClockTimeSeconds; + } + mediaSink.desiredRate = newRate; + return 0; + } + get sessionData$() { + return this.publicQueries$.pipe(switchMap(([rootPlaylistQuery]) => { + return rootPlaylistQuery.sessionData$; + })); + } + set skip(skip) { + this.logger.info(`skip=${skip}`); + if (this._mediaElementQuery) { + this.logger.info(`[seek] skip ${skip}`); + this.realCurrentTime = Math.max(0, this.realCurrentTime + skip); + } + } + // Helper function for seeking when in gapless mode + gaplessSeekTo(seekTo) { + // Adjust seekTo Value if needed + this.logger.debug(`seekTo before gapless adjust: ${seekTo}, startOffset: ${this.playingItem.itemStartOffset}`); + if (seekTo < this.playingItem.itemStartOffset) { + this.logger.warn(`[Gapless] Seeking past track boundary oldSeek=${seekTo}, adjustedSeek=${this.playingItem.itemStartOffset}`); + seekTo = this.playingItem.itemStartOffset; + } + if (this.isPreloading) { + if (seekTo > this.loadingItem.itemStartOffset) { + this.logger.warn(`[Gapless] Seeking past track boundary oldSeek=${seekTo}, adjustedSeek=${this.loadingItem.itemStartOffset}`); + seekTo = this.loadingItem.itemStartOffset; + } + const buf = this._mediaElementQuery.getBufferInfo(this._mediaElementQuery.currentTime, this.config.maxBufferHole); + this.logger.info('Hls seekTo during preloading currentTime:%d seekTo:%d Buf:%o', this.realCurrentTime, seekTo, buf); + if (seekTo < buf[0].buffered.start) { + this.dequeueSource('SeekToUnbufferedTimeRanges'); + } + } + globalHlsService().setUserSeek(seekTo); + } + isIframeInternalSeek(seekTo) { + var _a; + return seekTo === ((_a = this.iframeMachine) === null || _a === void 0 ? void 0 : _a.mediaRootTime); + } + set seekTo(seekValue) { + var _a; + const seekTo = Number(seekValue); + if (!isFiniteNumber(seekTo)) { + this.logger.error(`[seek] got invalid seek value ${seekValue}`); + return; + } + this.logger.info(`[seek] seekTo=${seekTo}`); + if (this.inGaplessMode) { + this.gaplessSeekTo(seekTo); + return; + } + // After trick-play is stopped, before seek to postFlushSeek, update the post flush resume time + const mediaSink = this.mediaElementAdapter; + if (mediaSink && isFiniteNumber((_a = mediaSink.mediaQuery) === null || _a === void 0 ? void 0 : _a.postFlushSeek) && (!mediaSink.mediaQuery.seekTo || this.isIframeInternalSeek(mediaSink.mediaQuery.seekTo.pos))) { + this.logger.info(`[seek] clearing seekTo ${JSON.stringify(mediaSink.mediaQuery.seekTo)} and resuming from trick-play postFlushSeek=${seekTo}`); + mediaSink.schedulePostFlushSeek(seekTo); + return; + } + // Store seek in userSeek to be processed by userSeekEpic + globalHlsService().setUserSeek(seekTo); + } + /** + * Seek to a date. Only valid for playlists with PROGRAM-DATE-TIME tags + * @param searchDate The date to seek to + */ + seekToDate(searchDate) { + // Note: Airplay allows seekToDate() to occur before loadSource() so we must store it at Hls level + this.logger.info(`[seek] seekToDate=${searchDate.toISOString()}`); + globalHlsService().setUserSeek(searchDate); + } + /** + * @returns a map of Date (ms) to time in media element (s) + */ + get availableProgramDateTime() { + return new Map(this._currentDateToMediaTimeTuple); + } + get _currentDateToMediaTimeTuple() { + var _a, _b; + if (!this._activeRootQuery) { + return []; + } + const curVariant = this._activeRootQuery.enabledMediaOptionKeys[MediaOptionType.Variant]; + if (!isEnabledMediaOption(curVariant)) { + return []; + } + const libQuery = mediaLibraryService().getQueryForOption(curVariant); + return (_b = (_a = libQuery.mediaOptionDetails) === null || _a === void 0 ? void 0 : _a.dateMediaTimePairs) !== null && _b !== void 0 ? _b : []; + } + /** + * Convert the playing time into equivalent DateTime + */ + get playingDate() { + return resolvePTSToDate(this._currentDateToMediaTimeTuple, this.realCurrentTime); + } + /** + * Manually set variantID. Only in development mode + */ + set variantId(variantId) { + { + const rootQuery = this._activeRootQuery; + if (!rootQuery) { + return; + } + this.logger.info(`variantId=${variantId}`); + const itemId = rootQuery.itemId; + const mediaOption = rootQuery.variantMediaOptionById(variantId); + this.rootPlaylistService.setManualMode(itemId, true); + this.rootPlaylistService.setEnabledMediaOptionByType(itemId, MediaOptionType.Variant, mediaOption); + } + } + set audioSelectedPersistentID(persistentID) { + const rootQuery = this._activeRootQuery; + const audioMediaOptions = rootQuery === null || rootQuery === void 0 ? void 0 : rootQuery.preferredMediaOptions[MediaOptionType.AltAudio]; + if (audioMediaOptions) { + const itemId = rootQuery.itemId; + if (persistentID === this.audioSelectedPersistentID) { + this.logger.info('skipping set audioSelectedPersistentID, id is same. PersistentID = %d', persistentID); + return; + } + this.rootPlaylistService.setEnabledMediaOptionTupleWithMatchedGroups(itemId, MediaOptionType.AltAudio, persistentID, { userInitiated: true }); + } + else { + // MatchPoint spams audioSelectedPersistentID(-1) during startup (when hls is not ready) + // hls 1.0 - 2.0 ignores them explicitly. + // Otherwise, they may override a valid selection. + if (!isFiniteNumber(persistentID) || persistentID < 0) { + this.logger.info(`ignore early invalid audio selection: ${persistentID}`); + return; + } + this.logger.warn(`[audio] no active item, defer audio track selection: persistentId ${persistentID}`); + this.itemQueue.earlyAudioSelection = persistentID; + } + } + get audioSelectedPersistentID() { + var _a; + if (this._activeRootQuery) { + return (_a = this._activeRootQuery.enabledAlternateMediaOptionByType(MediaOptionType.AltAudio)) === null || _a === void 0 ? void 0 : _a.persistentID; + } + else { + return this.itemQueue.earlyAudioSelection; + } + } + /** + * @param persistentID = the persistentId + */ + set subtitleSelectedPersistentID(persistentID) { + const rootQuery = this._activeRootQuery; + const subtitleMediaOptions = rootQuery === null || rootQuery === void 0 ? void 0 : rootQuery.preferredMediaOptions[MediaOptionType.Subtitle]; + if (subtitleMediaOptions) { + if (persistentID === this.subtitleSelectedPersistentID) { + this.logger.info('skipping set subtitleSelectedPersistentID, id is same. PersistentID = %d', persistentID); + return; + } + const itemId = rootQuery.itemId; + if (subtitleMediaOptions.length === 0 && (!isFiniteNumber(persistentID) || persistentID < 0)) { + this.logger.info(`ignore early invalid subtitle selection ${persistentID}; no subtitle media options yet`); + return; + } + this.logger.info(`subtitleSelectedPersistentID ${persistentID}`); + if (!isFiniteNumber(persistentID) || persistentID === -1) { + // Disable subtitles + this.rootPlaylistService.setEnabledMediaOptionByType(itemId, MediaOptionType.Subtitle, NoMediaOption); + } + else { + this.rootPlaylistService.setEnabledMediaOptionTupleWithMatchedGroups(itemId, MediaOptionType.Subtitle, persistentID); + } + } + else { + // MatchPoint spams subtitleSelectedPersistentID(-1) during startup (when hls is not ready) + // hls 1.0 - 2.0 ignores them explicitly. + // Otherwise, they may override a valid selection. + if (!isFiniteNumber(persistentID) || persistentID < 0) { + this.logger.info(`ignore early invalid subtitle selection ${persistentID}`); + return; + } + // cache valid selection + this.logger.warn(`[subtitle] no active item, defer subtitle track selection: persistentId ${persistentID}`); + this.itemQueue.earlySubtitleSelection = persistentID; + } + } + /** + * @returns the persistentID of the enabled subtitle + */ + get subtitleSelectedPersistentID() { + var _a; + if (this._activeRootQuery) { + return (_a = this._activeRootQuery.enabledAlternateMediaOptionByType(MediaOptionType.Subtitle)) === null || _a === void 0 ? void 0 : _a.persistentID; + } + else { + return this.itemQueue.earlySubtitleSelection; + } + } + /** + * Get array of selected tracks + */ + get selectedMediaArray() { + const rootQuery = this._activeRootQuery; + if (!rootQuery) { + return []; + } + const selectedMediaArray = []; + const audioMediaOption = rootQuery.enabledAlternateMediaOptionByType(MediaOptionType.AltAudio); + const subtitleMediaOption = rootQuery.enabledAlternateMediaOptionByType(MediaOptionType.Subtitle); + const audioSelectedMediaOption = audioMediaOption ? rootQuery.audioMediaSelectionOptions.find((option) => option.MediaSelectionOptionsPersistentID === audioMediaOption.persistentID) : undefined; + const subtitleSelectedMediaOption = subtitleMediaOption + ? rootQuery.subtitleMediaSelectionOptions.find((option) => option.MediaSelectionOptionsPersistentID === subtitleMediaOption.persistentID) + : undefined; + if (audioSelectedMediaOption) { + const selectedItem = { + MediaSelectionGroupMediaType: MediaTypeFourCC.AUDIO, + MediaSelectionOptionsPersistentID: audioSelectedMediaOption.MediaSelectionOptionsPersistentID, + }; + selectedMediaArray.push(selectedItem); + } + if (subtitleSelectedMediaOption) { + let showNonForcedSubtitles = Allowed.NO; + if (subtitleSelectedMediaOption.MediaSelectionOptionsDisplaysNonForcedSubtitles) { + showNonForcedSubtitles = subtitleSelectedMediaOption.MediaSelectionOptionsDisplaysNonForcedSubtitles; + } + const selectedItem = { + MediaSelectionGroupMediaType: MediaTypeFourCC.SUBTITLE, + MediaSelectionOptionsDisplaysNonForcedSubtitles: showNonForcedSubtitles, + MediaSelectionOptionsPersistentID: subtitleSelectedMediaOption.MediaSelectionOptionsPersistentID, + }; + selectedMediaArray.push(selectedItem); + } + this.logger.debug(`get selectedMediaArray: ${JSON.stringify(selectedMediaArray)}`); + return selectedMediaArray; + } + set selectedMediaArray(mediaArray) { + if (this._activeRootQuery) { + this.logger.debug(`selectedMediaArray=${JSON.stringify(mediaArray)}`); + mediaArray.forEach((selectedItem) => { + if (selectedItem.MediaSelectionGroupMediaType === MediaTypeFourCC.AUDIO || selectedItem.MediaSelectionOptionsMediaType === MediaTypeFourCC.AUDIO) { + this.audioSelectedPersistentID = selectedItem.MediaSelectionOptionsPersistentID; + } + else if (selectedItem.MediaSelectionGroupMediaType === MediaTypeFourCC.SUBTITLE || + selectedItem.MediaSelectionOptionsMediaType === MediaTypeFourCC.SUBTITLE || + selectedItem.MediaSelectionOptionsMediaType === MediaTypeFourCC.CLOSEDCAPTION) { + this.subtitleSelectedPersistentID = selectedItem.MediaSelectionOptionsPersistentID; + } + }); + } + else { + this.logger.warn('selectedMediaArray: no active item'); + } + } + getHTMLTextTrack(subtitleTrackId) { + return this.legibleSystemAdapter.getExistingHTMLTextTrackWithSubtitleTrackId(subtitleTrackId); + } + get keysystems() { + return this.keySystemAdapter.availableKeySystems; + } + setProtectionData(data) { + this.keySystemAdapter.initialize(data); + } + generateKeyRequest(keyuri, requestInfo) { + this.keySystemAdapter.generateRequest(keyuri, requestInfo); + this.rtcService.licenseChallengeReceived({ keyuri: keyuri }); + } + setLicenseResponse(keyuri, response) { + this.keySystemAdapter.setLicenseResponse(keyuri, response); + } + get bufferInfo$() { + return this.publicQueries$.pipe(switchMap((queries) => { + const [, mediaQuery] = queries; + const config = createHlsQuery().currentConfig; + return merge(mediaQuery.timeupdate$, mediaQuery.bufferedRangeTuple$).pipe(throttleTime(1000), map(() => { + const pos = mediaQuery.currentTime; + return { + combined: mediaQuery.getCombinedBufferInfo(pos, config.maxBufferHole), + sbTuple: mediaQuery.getBufferInfo(pos, config.maxBufferHole), + }; + })); + })); + } + bufferInfoByType$(type) { + return this.bufferInfo$.pipe(map((bufInfoTuple) => { + var _a; + return (_a = bufInfoTuple === null || bufInfoTuple === void 0 ? void 0 : bufInfoTuple.sbTuple) === null || _a === void 0 ? void 0 : _a[type]; + })); + } + /** + * DEPRECATED + */ + levelWithPersistentId(levelId) { + this.logger.warn('levelWithPersistentId is deprecated'); + } + /** + * DEPRECATED + */ + startLoad(startTimeSec) { + this.logger.warn('startLoad is deprecated'); + // Hack for Vuze. remove when they adopt initialSeekTime API. + if (isFiniteNumber(startTimeSec)) { + this.logger.warn(`[seek] Seeking to ${startTimeSec === null || startTimeSec === void 0 ? void 0 : startTimeSec.toFixed(3)} via deprecated "startLoad" method. Use loadSource(url, options, startTime) instead.`); + this.seekTo = startTimeSec; + } + } + /** + * DEPRECATED + */ + stopLoad() { } + /** + * DEPRECATED + * @returns current config + */ + get config() { + return Object.assign(Object.assign({}, deepCpy(getCurrentConfig())), { set startPosition(startTimeSec) { + // Hack for airplay. remove when they adopt initialSeekTime API + getLogger().warn(`Setting start position ${startTimeSec === null || startTimeSec === void 0 ? void 0 : startTimeSec.toFixed(3)} using deprecated method`); + globalHlsService().setStartTime(startTimeSec); + } }); + } + /** + * DEPRECATED + * @returns if media is attached + */ + get media() { + return this.mediaElement$.value != null; + } + /** + * DEPRECATED + */ + set subtitleDisplay(subtitleDisplay) { + this.logger.warn(`set subtitleDisplay ${subtitleDisplay} is deprecated`); + } + } + + var Hls = Hls$1; + + return Hls; + + })); + })(false); \ No newline at end of file diff --git a/src/renderer/assets/AppChromeBtn-Open.svg b/src/renderer/assets/AppChromeBtn-Open.svg new file mode 100644 index 00000000..fb24b33d --- /dev/null +++ b/src/renderer/assets/AppChromeBtn-Open.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/renderer/assets/AppChromeBtn.svg b/src/renderer/assets/AppChromeBtn.svg new file mode 100644 index 00000000..16985261 --- /dev/null +++ b/src/renderer/assets/AppChromeBtn.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/renderer/assets/CiderMenu.svg b/src/renderer/assets/CiderMenu.svg new file mode 100644 index 00000000..fd48fa55 --- /dev/null +++ b/src/renderer/assets/CiderMenu.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/renderer/assets/MissingArtwork.svg b/src/renderer/assets/MissingArtwork.svg new file mode 100644 index 00000000..cca3ca5b --- /dev/null +++ b/src/renderer/assets/MissingArtwork.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/renderer/assets/angles-left.svg b/src/renderer/assets/angles-left.svg new file mode 100644 index 00000000..cc38eb23 --- /dev/null +++ b/src/renderer/assets/angles-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/angles-right.svg b/src/renderer/assets/angles-right.svg new file mode 100644 index 00000000..7bc040ed --- /dev/null +++ b/src/renderer/assets/angles-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/banner.png b/src/renderer/assets/banner.png index 1edba696..1a1b099a 100644 Binary files a/src/renderer/assets/banner.png and b/src/renderer/assets/banner.png differ diff --git a/src/renderer/assets/banner2.png b/src/renderer/assets/banner2.png new file mode 100644 index 00000000..1edba696 Binary files /dev/null and b/src/renderer/assets/banner2.png differ diff --git a/src/renderer/assets/c1-c2.png b/src/renderer/assets/c1-c2.png new file mode 100644 index 00000000..1a1619f3 Binary files /dev/null and b/src/renderer/assets/c1-c2.png differ diff --git a/src/renderer/assets/check.svg b/src/renderer/assets/check.svg new file mode 100644 index 00000000..1c209899 --- /dev/null +++ b/src/renderer/assets/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/chevron-right.svg b/src/renderer/assets/chevron-right.svg new file mode 100644 index 00000000..538cc611 --- /dev/null +++ b/src/renderer/assets/chevron-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/cider-icons/backward.svg b/src/renderer/assets/cider-icons/backward.svg new file mode 100644 index 00000000..87d5ecca --- /dev/null +++ b/src/renderer/assets/cider-icons/backward.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/renderer/assets/cider-icons/forward.svg b/src/renderer/assets/cider-icons/forward.svg new file mode 100644 index 00000000..37320d60 --- /dev/null +++ b/src/renderer/assets/cider-icons/forward.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/renderer/assets/cider-icons/pause.svg b/src/renderer/assets/cider-icons/pause.svg new file mode 100644 index 00000000..39b3608c --- /dev/null +++ b/src/renderer/assets/cider-icons/pause.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/renderer/assets/cider-icons/play.svg b/src/renderer/assets/cider-icons/play.svg new file mode 100644 index 00000000..885b90cc --- /dev/null +++ b/src/renderer/assets/cider-icons/play.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/renderer/assets/cider-icons/stop.svg b/src/renderer/assets/cider-icons/stop.svg new file mode 100644 index 00000000..b7f1e3d1 --- /dev/null +++ b/src/renderer/assets/cider-icons/stop.svg @@ -0,0 +1,45 @@ + + + + diff --git a/src/renderer/assets/cider-round.svg b/src/renderer/assets/cider-round.svg new file mode 100644 index 00000000..f27dc45d --- /dev/null +++ b/src/renderer/assets/cider-round.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/discord.svg b/src/renderer/assets/discord.svg index f905d235..3b0fa57f 100644 --- a/src/renderer/assets/discord.svg +++ b/src/renderer/assets/discord.svg @@ -1,10 +1,41 @@ - - - - - - - - - + + + + + diff --git a/src/renderer/assets/feather/external-link.svg b/src/renderer/assets/feather/external-link.svg new file mode 100644 index 00000000..6236df3e --- /dev/null +++ b/src/renderer/assets/feather/external-link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/feather/hard-drive.svg b/src/renderer/assets/feather/hard-drive.svg new file mode 100644 index 00000000..30305b6c --- /dev/null +++ b/src/renderer/assets/feather/hard-drive.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/renderer/assets/feather/headphones.svg b/src/renderer/assets/feather/headphones.svg new file mode 100644 index 00000000..6c197a70 --- /dev/null +++ b/src/renderer/assets/feather/headphones.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/renderer/assets/feather/heart-fill.svg b/src/renderer/assets/feather/heart-fill.svg new file mode 100644 index 00000000..4daaa2c8 --- /dev/null +++ b/src/renderer/assets/feather/heart-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/feather/heart.svg b/src/renderer/assets/feather/heart.svg index a083b7e2..973edba4 100644 --- a/src/renderer/assets/feather/heart.svg +++ b/src/renderer/assets/feather/heart.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/renderer/assets/feather/pen-tool.svg b/src/renderer/assets/feather/pen-tool.svg new file mode 100644 index 00000000..304803a1 --- /dev/null +++ b/src/renderer/assets/feather/pen-tool.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/feather/plugins.svg b/src/renderer/assets/feather/plugins.svg new file mode 100644 index 00000000..1ad5759a --- /dev/null +++ b/src/renderer/assets/feather/plugins.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/feather/style.svg b/src/renderer/assets/feather/style.svg new file mode 100644 index 00000000..e6eae9e2 --- /dev/null +++ b/src/renderer/assets/feather/style.svg @@ -0,0 +1,41 @@ + + + + + + diff --git a/src/renderer/assets/feather/zap.svg b/src/renderer/assets/feather/zap.svg new file mode 100644 index 00000000..8e71dd07 --- /dev/null +++ b/src/renderer/assets/feather/zap.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/renderer/assets/fonts/Inter/inter.css b/src/renderer/assets/fonts/Inter/inter.css index f4500101..06a2f922 100644 --- a/src/renderer/assets/fonts/Inter/inter.css +++ b/src/renderer/assets/fonts/Inter/inter.css @@ -1,154 +1,136 @@ @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 100; font-display: swap; - src: url("Inter-Thin.woff2?v=3.19") format("woff2"), - url("Inter-Thin.woff?v=3.19") format("woff"); + src: url("Inter-Thin.woff2?v=3.19") format("woff2"), url("Inter-Thin.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 100; font-display: swap; - src: url("Inter-ThinItalic.woff2?v=3.19") format("woff2"), - url("Inter-ThinItalic.woff?v=3.19") format("woff"); + src: url("Inter-ThinItalic.woff2?v=3.19") format("woff2"), url("Inter-ThinItalic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 200; font-display: swap; - src: url("Inter-ExtraLight.woff2?v=3.19") format("woff2"), - url("Inter-ExtraLight.woff?v=3.19") format("woff"); + src: url("Inter-ExtraLight.woff2?v=3.19") format("woff2"), url("Inter-ExtraLight.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 200; font-display: swap; - src: url("Inter-ExtraLightItalic.woff2?v=3.19") format("woff2"), - url("Inter-ExtraLightItalic.woff?v=3.19") format("woff"); + src: url("Inter-ExtraLightItalic.woff2?v=3.19") format("woff2"), url("Inter-ExtraLightItalic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 300; font-display: swap; - src: url("Inter-Light.woff2?v=3.19") format("woff2"), - url("Inter-Light.woff?v=3.19") format("woff"); + src: url("Inter-Light.woff2?v=3.19") format("woff2"), url("Inter-Light.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 300; font-display: swap; - src: url("Inter-LightItalic.woff2?v=3.19") format("woff2"), - url("Inter-LightItalic.woff?v=3.19") format("woff"); + src: url("Inter-LightItalic.woff2?v=3.19") format("woff2"), url("Inter-LightItalic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 400; font-display: swap; - src: url("Inter-Regular.woff2?v=3.19") format("woff2"), - url("Inter-Regular.woff?v=3.19") format("woff"); + src: url("Inter-Regular.woff2?v=3.19") format("woff2"), url("Inter-Regular.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 400; font-display: swap; - src: url("Inter-Italic.woff2?v=3.19") format("woff2"), - url("Inter-Italic.woff?v=3.19") format("woff"); + src: url("Inter-Italic.woff2?v=3.19") format("woff2"), url("Inter-Italic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 500; font-display: swap; - src: url("Inter-Medium.woff2?v=3.19") format("woff2"), - url("Inter-Medium.woff?v=3.19") format("woff"); + src: url("Inter-Medium.woff2?v=3.19") format("woff2"), url("Inter-Medium.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 500; font-display: swap; - src: url("Inter-MediumItalic.woff2?v=3.19") format("woff2"), - url("Inter-MediumItalic.woff?v=3.19") format("woff"); + src: url("Inter-MediumItalic.woff2?v=3.19") format("woff2"), url("Inter-MediumItalic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 600; font-display: swap; - src: url("Inter-SemiBold.woff2?v=3.19") format("woff2"), - url("Inter-SemiBold.woff?v=3.19") format("woff"); + src: url("Inter-SemiBold.woff2?v=3.19") format("woff2"), url("Inter-SemiBold.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 600; font-display: swap; - src: url("Inter-SemiBoldItalic.woff2?v=3.19") format("woff2"), - url("Inter-SemiBoldItalic.woff?v=3.19") format("woff"); + src: url("Inter-SemiBoldItalic.woff2?v=3.19") format("woff2"), url("Inter-SemiBoldItalic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 700; font-display: swap; - src: url("Inter-Bold.woff2?v=3.19") format("woff2"), - url("Inter-Bold.woff?v=3.19") format("woff"); + src: url("Inter-Bold.woff2?v=3.19") format("woff2"), url("Inter-Bold.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 700; font-display: swap; - src: url("Inter-BoldItalic.woff2?v=3.19") format("woff2"), - url("Inter-BoldItalic.woff?v=3.19") format("woff"); + src: url("Inter-BoldItalic.woff2?v=3.19") format("woff2"), url("Inter-BoldItalic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 800; font-display: swap; - src: url("Inter-ExtraBold.woff2?v=3.19") format("woff2"), - url("Inter-ExtraBold.woff?v=3.19") format("woff"); + src: url("Inter-ExtraBold.woff2?v=3.19") format("woff2"), url("Inter-ExtraBold.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 800; font-display: swap; - src: url("Inter-ExtraBoldItalic.woff2?v=3.19") format("woff2"), - url("Inter-ExtraBoldItalic.woff?v=3.19") format("woff"); + src: url("Inter-ExtraBoldItalic.woff2?v=3.19") format("woff2"), url("Inter-ExtraBoldItalic.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: normal; + font-family: "Inter"; + font-style: normal; font-weight: 900; font-display: swap; - src: url("Inter-Black.woff2?v=3.19") format("woff2"), - url("Inter-Black.woff?v=3.19") format("woff"); + src: url("Inter-Black.woff2?v=3.19") format("woff2"), url("Inter-Black.woff?v=3.19") format("woff"); } @font-face { - font-family: 'Inter'; - font-style: italic; + font-family: "Inter"; + font-style: italic; font-weight: 900; font-display: swap; - src: url("Inter-BlackItalic.woff2?v=3.19") format("woff2"), - url("Inter-BlackItalic.woff?v=3.19") format("woff"); + src: url("Inter-BlackItalic.woff2?v=3.19") format("woff2"), url("Inter-BlackItalic.woff?v=3.19") format("woff"); } /* ------------------------------------------------------- @@ -161,23 +143,22 @@ Usage: } */ @font-face { - font-family: 'Inter var'; + font-family: "Inter var"; font-weight: 100 900; font-display: swap; font-style: normal; - font-named-instance: 'Regular'; + font-named-instance: "Regular"; src: url("Inter-roman.var.woff2?v=3.19") format("woff2"); } @font-face { - font-family: 'Inter var'; + font-family: "Inter var"; font-weight: 100 900; font-display: swap; font-style: italic; - font-named-instance: 'Italic'; + font-named-instance: "Italic"; src: url("Inter-italic.var.woff2?v=3.19") format("woff2"); } - /* -------------------------------------------------------------------------- [EXPERIMENTAL] Multi-axis, single variable font. @@ -192,7 +173,7 @@ explicitly, e.g. */ @font-face { - font-family: 'Inter var experimental'; + font-family: "Inter var experimental"; font-weight: 100 900; font-display: swap; font-style: oblique 0deg 10deg; diff --git a/src/renderer/assets/fonts/Pretendard/pretendardvariable.css b/src/renderer/assets/fonts/Pretendard/pretendardvariable.css new file mode 100644 index 00000000..b623b8a4 --- /dev/null +++ b/src/renderer/assets/fonts/Pretendard/pretendardvariable.css @@ -0,0 +1,16 @@ +/* +Copyright (c) 2021 Kil Hyung-jin, with Reserved Font Name Pretendard. +https://github.com/orioncactus/pretendard + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL +*/ + +@font-face { + font-family: "Pretendard Variable"; + font-weight: 45 920; + font-style: normal; + font-display: swap; + src: local("Pretendard Variable"), url("./woff2/PretendardVariable.woff2") format("woff2-variations"); +} diff --git a/src/renderer/assets/fonts/Pretendard/woff2/PretendardVariable.woff2 b/src/renderer/assets/fonts/Pretendard/woff2/PretendardVariable.woff2 new file mode 100644 index 00000000..98125beb Binary files /dev/null and b/src/renderer/assets/fonts/Pretendard/woff2/PretendardVariable.woff2 differ diff --git a/src/renderer/assets/github.svg b/src/renderer/assets/github.svg new file mode 100644 index 00000000..e84df9e7 --- /dev/null +++ b/src/renderer/assets/github.svg @@ -0,0 +1,41 @@ + + + + + + diff --git a/src/renderer/assets/hamborgar.svg b/src/renderer/assets/hamborgar.svg new file mode 100644 index 00000000..b8dbaf40 --- /dev/null +++ b/src/renderer/assets/hamborgar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/ko_fi.svg b/src/renderer/assets/ko_fi.svg index 8630f586..dcd86131 100644 --- a/src/renderer/assets/ko_fi.svg +++ b/src/renderer/assets/ko_fi.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + diff --git a/src/renderer/assets/music.svg b/src/renderer/assets/music.svg new file mode 100644 index 00000000..7bee2f7e --- /dev/null +++ b/src/renderer/assets/music.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/oobe/maverick.png b/src/renderer/assets/oobe/maverick.png new file mode 100644 index 00000000..c2238734 Binary files /dev/null and b/src/renderer/assets/oobe/maverick.png differ diff --git a/src/renderer/assets/oobe/mojave.png b/src/renderer/assets/oobe/mojave.png new file mode 100644 index 00000000..0f6a9280 Binary files /dev/null and b/src/renderer/assets/oobe/mojave.png differ diff --git a/src/renderer/assets/open_collective.svg b/src/renderer/assets/open_collective.svg index ea86a543..59e09857 100644 --- a/src/renderer/assets/open_collective.svg +++ b/src/renderer/assets/open_collective.svg @@ -1 +1,50 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/renderer/assets/ppe.svg b/src/renderer/assets/ppe.svg new file mode 100644 index 00000000..49848f52 --- /dev/null +++ b/src/renderer/assets/ppe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/private.svg b/src/renderer/assets/private.svg new file mode 100644 index 00000000..c0d61ac9 --- /dev/null +++ b/src/renderer/assets/private.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/qq.svg b/src/renderer/assets/qq.svg new file mode 100644 index 00000000..af0fff50 --- /dev/null +++ b/src/renderer/assets/qq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/search-alt.svg b/src/renderer/assets/search-alt.svg new file mode 100644 index 00000000..d21e9b73 --- /dev/null +++ b/src/renderer/assets/search-alt.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/renderer/assets/settings.svg b/src/renderer/assets/settings.svg new file mode 100644 index 00000000..41f574c0 --- /dev/null +++ b/src/renderer/assets/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/spatialization.svg b/src/renderer/assets/spatialization.svg new file mode 100644 index 00000000..97c0ef77 --- /dev/null +++ b/src/renderer/assets/spatialization.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/renderer/assets/star.svg b/src/renderer/assets/star.svg new file mode 100644 index 00000000..861e24be --- /dev/null +++ b/src/renderer/assets/star.svg @@ -0,0 +1,14 @@ + + dark blue star + + + Layer 1 + + + + + + + spear + + \ No newline at end of file diff --git a/src/renderer/assets/twitter.svg b/src/renderer/assets/twitter.svg new file mode 100644 index 00000000..ce724ef1 --- /dev/null +++ b/src/renderer/assets/twitter.svg @@ -0,0 +1,41 @@ + + + + + + diff --git a/src/renderer/audio/audio.js b/src/renderer/audio/audio.js index 56b2ad01..f09300cb 100644 --- a/src/renderer/audio/audio.js +++ b/src/renderer/audio/audio.js @@ -1,162 +1,1174 @@ -var CiderAudio = { - context : null, - source : null, - audioNodes : { - gainNode : null, - spatialNode : null, - spatialInput: null, - audioBands : null, - preampNode : null, - vibrantbassNode: null, - }, - init: function (cb = function () { }) { - //AudioOutputs.fInit = true; - searchInt = setInterval(function () { - if (document.getElementById("apple-music-player")) { - //AudioOutputs.eqReady = true; - document.getElementById("apple-music-player").crossOrigin = "anonymous"; - CiderAudio.connectContext(document.getElementById("apple-music-player"), 0); - - cb(); - clearInterval(searchInt); - } - }, 1000); - }, - off: function(){ - try{ - try{ - CiderAudio.audioNodes.gainNode.disconnect(); } catch(e){} - try{ CiderAudio.audioNodes.spatialNode.disconnect();} catch(e){} - try{ - CiderAudio.audioNodes.preampNode.disconnect(); - CiderAudio.audioNodes.vibrantbassNode.disconnect(); - CiderAudio.audioNodes.audioBands[0].disconnect(); - CiderAudio.audioNodes.audioBands[9].disconnect(); - } catch(e){} - CiderAudio.source.connect(CiderAudio.context.destination);} catch(e){} - }, - connectContext: function (mediaElem){ +const CiderAudio = { + context: null, + source: null, + audioNodes: { + gainNode: null, + spatialNode: null, + audioBands: null, + vibrantbassNode: null, + llpw: null, + recorderNode: null, + intelliGainComp: null, + atmosphereRealizer2: null, + atmosphereRealizer1: null, + opportunisticCorrection: null, + optimizedNode: null, + }, + ccON: false, + mediaRecorder: null, + init: function (cb = function () {}) { + //AudioOutputs.fInit = true; + let searchInt = setInterval(function () { + if (document.getElementById("apple-music-player")) { + //AudioOutputs.eqReady = true; + document.getElementById("apple-music-player").crossOrigin = "anonymous"; + CiderAudio.connectContext(document.getElementById("apple-music-player"), 0); - if (!CiderAudio.context){ - CiderAudio.context = new (window.AudioContext || window.webkitAudioContext); - } - if (!CiderAudio.source){ - CiderAudio.source = CiderAudio.context.createMediaElementSource(mediaElem); - } else {try{CiderAudio.source.disconnect(CiderAudio.context.destination)}catch(e){}} - CiderAudio.audioNodes.gainNode = CiderAudio.context.createGain() - CiderAudio.source.connect(CiderAudio.audioNodes.gainNode); - CiderAudio.audioNodes.gainNode.connect(CiderAudio.context.destination); - if(app.cfg.audio.normalization){ - CiderAudio.normalizerOn() - } - if (app.cfg.audio.spatial){ - CiderAudio.spatialOn() - } - CiderAudio.equalizer() - }, - normalizerOn: function (){}, - normalizerOff: function (){ - CiderAudio.audioNodes.gainNode.gain.setTargetAtTime(1, CiderAudio.context.currentTime+ 1, 0.5); - }, - spatialOn: function (){ - try{ - CiderAudio.audioNodes.gainNode.disconnect(CiderAudio.context.destination);} catch(e){} - CiderAudio.audioNodes.spatialNode = new ResonanceAudio(CiderAudio.context); - CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.context.destination); - let roomDimensions = { - width: 32, - height: 12, - depth: 32, + cb(); + clearInterval(searchInt); + } + }, 1000); + }, + off: function () { + try { + try { + CiderAudio.audioNodes = { + gainNode: null, + spatialNode: null, + audioBands: null, + vibrantbassNode: null, + llpw: null, + recorderNode: null, + intelliGainComp: null, + atmosphereRealizer2: null, + atmosphereRealizer1: null, + opportunisticCorrection: null, + optimizedNode: null, }; - let roomMaterials = { - // Room wall materials - left: 'metal', - right: 'metal', - front: 'brick-bare', - back: 'brick-bare', - down: 'acoustic-ceiling-tiles', - up: 'acoustic-ceiling-tiles', - }; - CiderAudio.audioNodes.spatialNode.setRoomProperties(roomDimensions, roomMaterials); - CiderAudio.audioNodes.spatialInput = CiderAudio.audioNodes.spatialNode.createSource(); - CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialInput.input); + } catch (e) {} + CiderAudio.source.connect(CiderAudio.context.destination); + } catch (e) {} + }, + connectContext: function (mediaElem) { + if (!CiderAudio.context) { + CiderAudio.context = new window.AudioContext({ + sampleRate: 96000, + latencyHint: "playback", + }); // Don't ever remove the sample rate arg. Ask Maikiwi. + app.lyricOffset = CiderAudio.context.baseLatency + (CiderAudio.context.outputLatency ? CiderAudio.context.outputLatency : 0); + } + if (!CiderAudio.source) { + CiderAudio.source = CiderAudio.context.createMediaElementSource(mediaElem); + } else { + try { + CiderAudio.source.disconnect(CiderAudio.context.destination); + } catch (e) {} + } + CiderAudio.audioNodes.gainNode = CiderAudio.context.createGain(); + CiderAudio.audioNodes.intelliGainComp = CiderAudio.context.createGain(); + CiderAudio.source.connect(CiderAudio.audioNodes.intelliGainComp); + CiderAudio.audioNodes.intelliGainComp.connect(CiderAudio.audioNodes.gainNode); + if (app.cfg.audio.normalization) { + CiderAudio.normalizerOn(); + } + CiderAudio.hierarchical_loading(); + }, + normalizerOn: function () { + try { + let previewURL = null; + try { + previewURL = app.mk.nowPlayingItem.previewURL; + } catch (e) {} + if (previewURL == null && (app.mk.nowPlayingItem?._songId ?? app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id) != -1) { + app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem?._songId ?? app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id}`).then((response) => { + previewURL = response.data.data[0].attributes.previews[0].url; + if (previewURL) ipcRenderer.send("getPreviewURL", previewURL); + }); + } else { + if (previewURL) ipcRenderer.send("getPreviewURL", previewURL); + } + } catch (e) { + console.debug("[Cider][MaikiwiSoundCheck] normalizer func err: " + e); + } + }, + normalizerOff: function () { + CiderAudio.audioNodes.gainNode.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.5); + }, + spatialProfiles: [ + { + id: "maikiwi", + file: "./cideraudio/impulses/CiderSpatial_Maikiwi.wav", + name: "Maikiwi", + description: "", + gainComp: "1.044", }, - spatialOff: function (){ - try{ - CiderAudio.audioNodes.spatialNode.output.disconnect(CiderAudio.context.destination); - CiderAudio.audioNodes.gainNode.disconnect(CiderAudio.audioNodes.spatialInput.input);} catch(e){} - CiderAudio.audioNodes.gainNode.connect(CiderAudio.context.destination); + { + id: "maikiwiplus", + file: "./cideraudio/impulses/CiderSpatial_MaikiwiPlus.wav", + name: "Maikiwi+", + description: "", + gainComp: "1.044", }, - sendAudio: function (){ - var options = { - mimeType : 'audio/webm; codecs=opus' - }; - var destnode = CiderAudio.context.createMediaStreamDestination(); - CiderAudio.audioNodes.gainNode.connect(destnode) - var mediaRecorder = new MediaRecorder(destnode.stream,options); - mediaRecorder.start(1); - mediaRecorder.ondataavailable = function(e) { - e.data.arrayBuffer().then(buffer => { - ipcRenderer.send('writeAudio',buffer) - } - ); - } + { + id: "71_420maikiwi", + file: "./cideraudio/impulses/CiderSpatial_v71.420_Maikiwi.wav", + name: "Soundstage", + description: "", + gainComp: "1.3963683610559376", }, - equalizer: function (){ - let BANDS = app.cfg.audio.equalizer.frequencies; - let GAIN = app.cfg.audio.equalizer.gain; - let Q = app.cfg.audio.equalizer.Q; - let VIBRANTBASSBANDS = app.cfg.audio.vibrantBass.frequencies; - let VIBRANTBASSGAIN = app.cfg.audio.vibrantBass.gain; - let VIBRANTBASSQ = app.cfg.audio.vibrantBass.Q; - CiderAudio.audioNodes.audioBands = []; CiderAudio.audioNodes.vibrantbassNode = []; + { + id: "70_422maikiwi", + file: "./cideraudio/impulses/CiderSpatial_v70.422_Maikiwi.wav", + name: "Separation", + description: "", + gainComp: "1.30767553892022", + }, + { + id: "standard", + file: "./cideraudio/impulses/CiderSpatial_Natural.wav", + name: "Minimal", + description: "", + gainComp: "1.044", + }, + { + id: "standardplus", + file: "./cideraudio/impulses/CiderSpatial_Natural+.wav", + name: "Minimal+", + description: "", + gainComp: "1.044", + }, + { + id: "diffused", + file: "./cideraudio/impulses/CiderSpatial_Diffuse.wav", + name: "Diffused", + description: "", + gainComp: "1.044", + }, + { + id: "BPLK", + file: "./cideraudio/impulses/CiderSpatial_BPLK.wav", + name: "BPLK", + description: "", + gainComp: "1.044", + }, + { + id: "HW2K", + file: "./cideraudio/impulses/CiderSpatial_HW2K.wav", + name: "HW2K", + description: "", + gainComp: "1.044", + }, + { + id: "live", + file: "./cideraudio/impulses/CiderSpatial_LIVE_2.wav", + name: "live", + description: "", + gainComp: "1.2647363474711515", + }, + ], + atmosphereRealizerProfiles: [ + { + id: "NATURAL_STANDARD", + file: "./cideraudio/impulses/AtmosphereRealizer_NaturalStandard.wav", + name: "ãģうじčŒļチãƒŧã‚ēクãƒĒãƒŧãƒžãƒ†ã‚Ŗãƒŧ", + description: "", + }, + { + id: "NATURAL_PLUS", + file: "./cideraudio/impulses/AtmosphereRealizer_Natural+.wav", + name: "įŽ„įąŗčŒļã‚ŋピã‚Ēã‚ĢミãƒĢã‚¯ãƒ†ã‚Ŗãƒŧ", + description: "", + }, + { + id: "E68_1", + file: "./cideraudio/impulses/AtmosphereRealizer_E68_1.5.wav", + name: "å˛ŠåĄŠã‚¯ãƒĒãƒŧムチãƒŧã‚ēãƒ†ã‚Ŗãƒŧ", + description: "Light", + }, + { + id: "E68_2", + file: "./cideraudio/impulses/AtmosphereRealizer_E68_2.2.wav", + name: "抚čŒļミãƒĢã‚¯ãƒ†ã‚Ŗãƒŧ", + description: "Dark", + }, + { + id: "BSCBM", + file: "./cideraudio/impulses/AtmosphereRealizer_BSCBM.wav", + name: "BSCBM", + description: "BSCBM", + }, + { + id: "CUDDLE", + file: "./cideraudio/impulses/AtmosphereRealizer_Cuddle.wav", + name: "CUDDLE", + description: "CUDDLE", + }, + { + id: "E168_1", + file: "./cideraudio/impulses/AtmosphereRealizer_E168_1.2.wav", + name: "æ˜Ĩæ¯Ģã‚¸ãƒŖã‚šãƒŸãƒŗãƒžã‚­ã‚ĸãƒŧト", + description: "Natural Air", + }, + { + id: "Z3600", + file: "./cideraudio/impulses/AtmosphereRealizer_Z3600.wav", + name: "ロイヤãƒĢミãƒĢã‚¯ãƒ†ã‚Ŗãƒŧ", + description: "3600", + }, + { + id: "Z8500A", + file: "./cideraudio/impulses/AtmosphereRealizer_Z8500_A.wav", + name: "ムãƒŧãƒŗãƒŠã‚¤ãƒˆã‚Ŋãƒ•ãƒˆã‚ąãƒŧキ", + description: "8500", + }, + { + id: "Z8500B", + file: "./cideraudio/impulses/AtmosphereRealizer_Z8500_B.wav", + name: "Clafoutis aux Cerises", + description: "8500", + }, + { + id: "Z8500C", + file: "./cideraudio/impulses/AtmosphereRealizer_Z8500_C.wav", + name: "厇æ˛ģ抚čŒļだいãĩく", + description: "8500", + }, + ], + opportunisticCorrectionProfiles: [ + { + id: "CHU", + file: "./cideraudio/impulses/MoondropCHU_Cider.wav", + name: "Moondrop CHU Specific", + description: "", + }, + ], + spatial_ninf: function () { + CiderAudio.audioNodes.spatialNode = null; + CiderAudio.audioNodes.spatialNode = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.spatialNode.normalize = false; - for (i = 0; i < BANDS.length; i++) { - CiderAudio.audioNodes.audioBands[i] = CiderAudio.context.createBiquadFilter(); - CiderAudio.audioNodes.audioBands[i].type = 'peaking'; // 'peaking'; - CiderAudio.audioNodes.audioBands[i].frequency.value = BANDS[i]; - CiderAudio.audioNodes.audioBands[i].Q.value = Q[i]; - CiderAudio.audioNodes.audioBands[i].gain.value = GAIN[i] * app.cfg.audio.equalizer.mix; - } + let spatialProfile = CiderAudio.spatialProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; + }); - CiderAudio.audioNodes.preampNode = CiderAudio.context.createBiquadFilter(); - CiderAudio.audioNodes.preampNode.type = 'highshelf'; - CiderAudio.audioNodes.preampNode.frequency.value = 0; // allow all - CiderAudio.audioNodes.preampNode.gain.value = app.cfg.audio.equalizer.preamp; + if (spatialProfile === undefined) { + spatialProfile = CiderAudio.spatialProfiles[0]; + } + fetch(spatialProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.spatialNode.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); - for (i = 0; i < VIBRANTBASSBANDS.length; i++) { - CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter(); - CiderAudio.audioNodes.vibrantbassNode[i].type = 'peaking'; // 'peaking'; - CiderAudio.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i]; - CiderAudio.audioNodes.vibrantbassNode[i].Q.value = VIBRANTBASSQ[i]; - CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * app.cfg.audio.vibrantBass.multiplier; - } - - if (app.cfg.audio.spatial) { - try{ - CiderAudio.audioNodes.spatialNode.output.disconnect(CiderAudio.context.destination); } catch(e){} - CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.preampNode); - } else { - try{ - CiderAudio.audioNodes.gainNode.disconnect(CiderAudio.context.destination);} catch(e){} - CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.preampNode); - } - - CiderAudio.audioNodes.preampNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]); - - for (i = 1; i < VIBRANTBASSBANDS.length; i ++) { - CiderAudio.audioNodes.vibrantbassNode[i-1].connect(CiderAudio.audioNodes.vibrantbassNode[i]); - } - CiderAudio.audioNodes.vibrantbassNode[VIBRANTBASSBANDS.length-1].connect(CiderAudio.audioNodes.audioBands[0]); - - for (i = 1; i < BANDS.length; i ++) { - CiderAudio.audioNodes.audioBands[i-1].connect(CiderAudio.audioNodes.audioBands[i]); - } - CiderAudio.audioNodes.audioBands[BANDS.length-1].connect(CiderAudio.context.destination); + // Always destination + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.context.destination); + }, + spatialOff: function () { + CiderAudio.hierarchical_loading(); + }, + intelliGainComp_n0_0: function () { + let filters = []; + const precisionHz = 12; + // Biquad calculation + if (CiderAudio.audioNodes.audioBands !== null) { + filters = filters.concat(CiderAudio.audioNodes.audioBands); + } + if (CiderAudio.audioNodes.vibrantbassNode !== null) { + filters = filters.concat(CiderAudio.audioNodes.vibrantbassNode); + } + if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length > 2) { + filters = filters.concat(CiderAudio.audioNodes.llpw); } -} -if (app.cfg.advanced.AudioContext){ - CiderAudio.init() - -} \ No newline at end of file + if (!filters || filters.length === 0) { + let filterlessGain = 1; + // Impulse Calculation + if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length <= 2) { + filterlessGain = filterlessGain * 1.109174815262401; + } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true) { + filterlessGain = filterlessGain * 1.096478196143185; + } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true) { + filterlessGain = filterlessGain * 1.096478196143185; + } + if (app.cfg.audio.maikiwiAudio.spatial == true) { + let spatialProfile = CiderAudio.spatialProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; + }); + if (spatialProfile === undefined) { + spatialProfile = CiderAudio.spatialProfiles[0]; + } + filterlessGain = filterlessGain * spatialProfile.gainComp; + } + filterlessGain = Math.pow(10, (-1 * (20 * Math.log10(filterlessGain))) / 20).toFixed(4); + filterlessGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(filterlessGain, CiderAudio.context.currentTime + 0.3); + console.debug(`[Cider][Audio] IntelliGainComp: ${filterlessGain > 1.0 ? 0 : (20 * Math.log10(filterlessGain)).toFixed(2)} dB (${filterlessGain > 1.0 ? 1 : filterlessGain})`); + return; + } + + filters.shift(); + let steps = Math.ceil(96000 / precisionHz); + // Generate input array for getFrequencyResponse method + let frequencies = new Float32Array(steps); + for (let i = 0; i < steps; i++) { + frequencies[i] = (i + 1) * precisionHz; + } + // Here we will store combined amplitude response + let totalAmplitudeResp = new Float32Array(steps); + for (let i = 0; i < steps; i++) { + totalAmplitudeResp[i] = 1; + } + // Temporary container for every filter response + let amplitudeResp = new Float32Array(steps), + phaseResp = new Float32Array(steps); + for (let i = filters.length - 1; i >= 0; i--) { + let filter = filters[i]; + // Get filter response and convolve it with existing response + filter.getFrequencyResponse(frequencies, amplitudeResp, phaseResp); + for (let j = 0; j < steps; j++) { + totalAmplitudeResp[j] *= amplitudeResp[j]; + } + } + // Find max gain + let maxGain = -120; + for (let i = 0; i < steps; i++) { + let gain = totalAmplitudeResp[i]; + if (gain > maxGain) maxGain = gain; + } + + // Impulse Calculation + if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length <= 2) { + maxGain = maxGain * 1.109174815262401; + } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true) { + maxGain = maxGain * 1.096478196143185; + } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true) { + maxGain = maxGain * 1.096478196143185; + } + if (app.cfg.audio.maikiwiAudio.spatial == true) { + let spatialProfile = CiderAudio.spatialProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; + }); + if (spatialProfile === undefined) { + spatialProfile = CiderAudio.spatialProfiles[0]; + } + maxGain = maxGain * spatialProfile.gainComp; + } + maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4); + maxGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudio.context.currentTime + 0.3); + console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`); + }, + sendAudio: function () { + if (!CiderAudio.ccON) { + CiderAudio.ccON = true; + let searchInt = setInterval(async function () { + if (CiderAudio.context != null && CiderAudio.audioNodes.intelliGainComp != null) { + // var options = { + // mimeType: 'audio/webm; codecs=opus' + // }; + // var destnode = CiderAudio.context.createMediaStreamDestination(); + // CiderAudio.audioNodes.intelliGainComp.connect(CiderAudio.audioNodes.gainNode); + // CiderAudio.audioNodes.gainNode.connect(destnode) + // CiderAudio.mediaRecorder = new MediaRecorder(destnode.stream, options); + // CiderAudio.mediaRecorder.start(1); + // CiderAudio.mediaRecorder.ondataavailable = function (e) { + // e.data.arrayBuffer().then(buffer => { + // ipcRenderer.send('writeAudio', buffer) + // } + // ); + // } + const worklet = `class RecorderWorkletProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return [{ + name: 'isRecording', + defaultValue: 0 + }, + { + name: 'numberOfChannels', + defaultValue: 2 + } + ]; + } + + constructor() { + super(); + this._bufferSize = 2048; + this._buffers = null; + this._initBuffer(); + } + _initBuffers(numberOfChannels) { + this._buffers = []; + for (let channel=0; channel < numberOfChannels; channel++) { + this._buffers.push(new Float32Array(this._bufferSize)); + } + } + + _initBuffer() { + this._bytesWritten = 0; + } + + _isBufferEmpty() { + return this._bytesWritten === 0; + } + + _isBufferFull() { + return this._bytesWritten === this._bufferSize; + } + _pushToBuffers(audioRawData, numberOfChannels) { + if (this._isBufferFull()) { + this._flush(); + } + let dataLength = audioRawData[0]?.length ?? 0; + for (let idx=0; idx { + if (this._bytesWritten < this._bufferSize) { + buffer = buffer.slice(0, this._bytesWritten); + } + buffers[channel] = buffer; + }); + this.port.postMessage({ + eventType: 'data', + audioBuffer: buffers, + bufferSize: this._bufferSize + }); + this._initBuffer(); + } + + _recordingStopped() { + this.port.postMessage({ + eventType: 'stop' + }); + } + + process(inputs, outputs, parameters) { + const isRecordingValues = parameters.isRecording; + const numberOfChannels = parameters.numberOfChannels[0]; + if (this._buffers === null) { + this._initBuffers(numberOfChannels); + } + + for (let dataIndex = 0; dataIndex < isRecordingValues.length; dataIndex++) + { + const shouldRecord = isRecordingValues[dataIndex] === 1; + if (!shouldRecord && !this._isBufferEmpty()) { + this._flush(); + this._recordingStopped(); + } + + if (shouldRecord) { + let audioRawData = inputs[0]; + this._pushToBuffers(audioRawData, numberOfChannels); + } + } + return true; + } + + } + + registerProcessor('recorder-worklet', RecorderWorkletProcessor);`; + let blob = new Blob([worklet], { type: "application/javascript" }); + await CiderAudio.context.audioWorklet.addModule(URL.createObjectURL(blob)).then(() => { + const channels = 2; + CiderAudio.audioNodes.recorderNode = new window.AudioWorkletNode(CiderAudio.context, "recorder-worklet", { + parameterData: { numberOfChannels: channels }, + }); + CiderAudio.audioNodes.recorderNode.port.onmessage = (e) => { + const data = e.data; + switch (data.eventType) { + case "data": + const audioData = data.audioBuffer; + const bufferSize = data.bufferSize; + if (audioData[0].some((item) => item !== 0) || audioData[0].some((item) => item !== 0)) { + ipcRenderer.send("writeWAV", audioData[0], audioData[1], bufferSize); + } + break; + case "stop": + break; + } + }; + CiderAudio.audioNodes.recorderNode.parameters.get("isRecording").setValueAtTime(1, CiderAudio.context.currentTime); + CiderAudio.audioNodes.intelliGainComp.connect(CiderAudio.audioNodes.recorderNode); + }); + clearInterval(searchInt); + } + }, 1000); + } else { + if (CiderAudio.audioNodes.recorderNode != null && CiderAudio.context != null) { + CiderAudio.audioNodes.recorderNode.parameters.get("isRecording").setValueAtTime(1, CiderAudio.context.currentTime); + // CiderAudio.audioNodes.recorderNode = null; + // CiderAudio.ccON = false; + } + } + }, + stopAudio() { + if (CiderAudio.audioNodes.recorderNode != null && CiderAudio.context != null) { + CiderAudio.audioNodes.recorderNode.parameters.get("isRecording").setValueAtTime(0, CiderAudio.context.currentTime); + // CiderAudio.audioNodes.recorderNode = null; + // CiderAudio.ccON = false; + } + }, + atmosphereRealizer2_n6: function (status, destination) { + if (status === true) { + CiderAudio.audioNodes.atmosphereRealizer2 = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.atmosphereRealizer2.normalize = false; + let atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer2_value; + }); + + if (atmosphereRealizerProfile === undefined) { + atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles[0]; + } + fetch(atmosphereRealizerProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.atmosphereRealizer2.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> destination"); + } catch (e) {} + break; + } + } + }, + atmosphereRealizer1_n5: function (status, destination) { + if (status === true) { + CiderAudio.audioNodes.atmosphereRealizer1 = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.atmosphereRealizer1.normalize = false; + let atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer1_value; + }); + + if (atmosphereRealizerProfile === undefined) { + atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles[0]; + } + fetch(atmosphereRealizerProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.atmosphereRealizer1.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> destination"); + } catch (e) {} + break; + } + } + }, + opportunisticCorrection_n2: function (status, destination) { + if (status === true) { + CiderAudio.audioNodes.opportunisticCorrection = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.opportunisticCorrection.normalize = false; + let opportunisticCorrectionProfile = CiderAudio.opportunisticCorrectionProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.opportunisticCorrection_state; + }); + + if (opportunisticCorrectionProfile === undefined) { + opportunisticCorrectionProfile = CiderAudio.opportunisticCorrectionProfiles[0]; + } + fetch(opportunisticCorrectionProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.opportunisticCorrection.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.opportunisticCorrection[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> destination"); + } catch (e) {} + break; + } + } + }, + llpw_n1: function (status, destination) { + if (status === true) { + let c_LLPW_Q = [1.25, 0.131, 10, 2.5, 2.293, 0.11, 14.14, 1.552, 28.28, 7.071, 2.847, 5, 0.625, 7.071, 3.856, 3.856, 20, 28.28, 20, 14.14, 2.102, 6.698, 3.536, 10]; + let c_LLPW_GAIN = [-0.11, 0.27, -0.8, 0.57, 1.84, -0.38, 0.47, -1.56, 0.83, 1.58, -1.79, -0.45, 0.48, 1.22, -1.58, -1.59, -2.03, 2.56, -2.2, -2.48, 4.75, 10.5, 1.43, 3.76]; + let c_LLPW_FREQUENCIES = [400.83, 5812.8, 8360, 10413, 10658, 12079, 12899, 13205, 14848, 15591, 15778, 15783, 16716, 16891, 17255, 17496, 18555, 18622, 19219, 19448, 19664, 21341, 21353, 22595]; + let LLPW_Q = [5, 1, 3.536, 1.25, 8.409, 1.25, 14.14, 7.071, 5, 0.625, 16.82, 20, 20, 20, 28.28, 28.28, 28.28, 20, 33.64, 33.64, 10, 28.28, 7.071, 3.856]; + let LLPW_GAIN = [0.38, -1.81, -0.23, -0.51, 0.4, 0.84, 0.36, -0.34, 0.27, -1.2, -0.42, -0.67, 0.81, 1.31, -0.71, 0.68, -1.04, 0.79, -0.73, -1.33, 1.17, 0.57, 0.35, 6.33]; + let LLPW_FREQUENCIES = [16.452, 24.636, 37.134, 74.483, 159.54, 308.18, 670.21, 915.81, 1200.7, 2766.4, 2930.6, 4050.6, 4409.1, 5395.2, 5901.6, 6455.5, 7164.1, 7724.1, 8449, 10573, 12368, 14198, 17910, 18916]; + CiderAudio.audioNodes.llpw = []; + + switch (app.cfg.audio.maikiwiAudio.ciderPPE_value) { + case "MAIKIWI": + try { + switch (localStorage.getItem("playingBitrate")) { + case "64": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + fetch("./cideraudio/impulses/CAP_64.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - 64kbps"); + + break; + case "256": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[1].gain.value = 2.37; // Post Gain Compensation + CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]); + fetch("./cideraudio/impulses/CAP_256_FINAL_48k.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - 256kbps"); + + break; + default: + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[0].gain.value = 1; + console.debug("[Cider][Audio] CAP Disabled (Passthrough) : Non-Lossy Bitrate."); + + break; + } + } catch (e) { + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[1].gain.value = 2.37; + CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]); + fetch("./cideraudio/impulses/CAP_256_FINAL_48k.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - (Error Fallback) 256kbps"); + } + + break; + case "MAIKIWI_LEGACY": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + fetch("./cideraudio/impulses/CAP_Maikiwi.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP - Maikiwi Signature Mode"); + break; + case "NATURAL": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + fetch("./cideraudio/impulses/CAP_Natural.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + console.debug("[Cider][Audio] CAP - Natural Mode"); + break; + + case "LEGACY": + for (let i = 0; i < LLPW_FREQUENCIES.length; i++) { + CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter(); + CiderAudio.audioNodes.llpw[i].type = "peaking"; // 'peaking'; + CiderAudio.audioNodes.llpw[i].frequency.value = LLPW_FREQUENCIES[i]; + CiderAudio.audioNodes.llpw[i].Q.value = LLPW_Q[i]; + CiderAudio.audioNodes.llpw[i].gain.value = LLPW_GAIN[i]; + } + for (let i = 1; i < LLPW_FREQUENCIES.length; i++) { + CiderAudio.audioNodes.llpw[i - 1].connect(CiderAudio.audioNodes.llpw[i]); + } + console.debug("[Cider][Audio] CAP - Legacy Mode"); + + break; + + default: + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[1].gain.value = 2.57; + CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]); + fetch("./cideraudio/impulses/CAP_256_FINAL_48k.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + app.cfg.audio.maikiwiAudio.ciderPPE_value = "MAIKIWI"; + + console.debug("[Cider][Audio] CAP - Maikiwi Adaptive Mode (Defaulted from broki config)"); + break; + } + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] llpw_n1 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] llpw_n1 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] llpw_n1 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] llpw_n1 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] llpw_n1 -> destination"); + } catch (e) {} + break; + } + } + }, + vibrantbass_n4: function (status, destination) { + if (status === true) { + let VIBRANTBASSBANDS = app.cfg.audio.maikiwiAudio.vibrantBass.frequencies; + let VIBRANTBASSGAIN = app.cfg.audio.maikiwiAudio.vibrantBass.gain; + let VIBRANTBASSQ = app.cfg.audio.maikiwiAudio.vibrantBass.Q; + CiderAudio.audioNodes.vibrantbassNode = []; + + for (let i = 0; i < VIBRANTBASSBANDS.length; i++) { + CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter(); + CiderAudio.audioNodes.vibrantbassNode[i].type = "peaking"; // 'peaking'; + CiderAudio.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i]; + CiderAudio.audioNodes.vibrantbassNode[i].Q.value = VIBRANTBASSQ[i]; + CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * (app.cfg.audio.equalizer.vibrantBass / 10); + } + + for (let i = 1; i < VIBRANTBASSBANDS.length; i++) { + CiderAudio.audioNodes.vibrantbassNode[i - 1].connect(CiderAudio.audioNodes.vibrantbassNode[i]); + } + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] vibrantbass_n4 -> Spatial"); + } catch (e) {} + break; + + case "n6": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] vibrantbass_n4 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] vibrantbass_n4 -> destination"); + } catch (e) {} + break; + } + } + }, + hierarchical_unloading: function () { + try { + CiderAudio.audioNodes.spatialNode.disconnect(); + CiderAudio.audioNodes.spatialNode = null; + } catch (e) {} + try { + CiderAudio.audioNodes.gainNode.disconnect(); + } catch (e) {} + try { + CiderAudio.audioNodes.atmosphereRealizer2.disconnect(); + CiderAudio.audioNodes.atmosphereRealizer2 = null; + } catch (e) {} + try { + CiderAudio.audioNodes.atmosphereRealizer1.disconnect(); + CiderAudio.audioNodes.atmosphereRealizer1 = null; + } catch (e) {} + try { + for (var i of CiderAudio.audioNodes.llpw) { + i.disconnect(); + } + CiderAudio.audioNodes.llpw = null; + } catch (e) {} + try { + for (var i of CiderAudio.audioNodes.vibrantbassNode) { + i.disconnect(); + } + CiderAudio.audioNodes.vibrantbassNode = null; + } catch (e) {} + try { + for (var i of CiderAudio.audioNodes.audioBands) { + i.disconnect(); + } + CiderAudio.audioNodes.vibrantbassNode = null; + } catch (e) {} + try { + CiderAudio.audioNodes.opportunisticCorrection.disconnect(); + CiderAudio.audioNodes.opportunisticCorrection = null; + } catch (e) {} + console.debug("[Cider][Audio] Finished hierarchical unloading"); + }, + hierarchical_loading: async function () { + const configMap = new Map([ + ["spatial", app.cfg.audio.maikiwiAudio.spatial === true], + ["n6", app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true], + ["n5", app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true], + ["n4", app.cfg.audio.equalizer.vibrantBass != 0], + ["n3", Math.max(...app.cfg.audio.equalizer.gain) != 0], + ["n2", app.cfg.audio.maikiwiAudio.opportunisticCorrection_state !== "OFF"], + ["n1", app.cfg.audio.maikiwiAudio.ciderPPE === true], + ]); + + CiderAudio.hierarchical_unloading(); + let lastNode = "n0"; + let index = 0; + let firstNode = "n0"; + for (let [tier, value] of configMap.entries()) { + if (value === true) { + if (index === 0) { + firstNode = tier; + } + index++; + switch (tier) { + case "spatial": + CiderAudio.spatial_ninf(); + lastNode = "spatial"; + break; + case "n6": + app.cfg.audio.normalization = true; + CiderAudio.atmosphereRealizer2_n6(true, lastNode); + lastNode = "n6"; + break; + case "n5": + app.cfg.audio.normalization = true; + CiderAudio.atmosphereRealizer1_n5(true, lastNode); + lastNode = "n5"; + break; + case "n4": + CiderAudio.vibrantbass_n4(true, lastNode); + lastNode = "n4"; + break; + case "n3": + CiderAudio.equalizer(true, lastNode); + lastNode = "n3"; + break; + case "n2": + CiderAudio.opportunisticCorrection_n2(true, lastNode); + lastNode = "n2"; + break; + case "n1": + app.cfg.audio.normalization = true; + CiderAudio.llpw_n1(true, lastNode); + lastNode = "n1"; + break; + } + } + } + + app.cfg.audio.maikiwiAudio.lastNode = lastNode; + app.cfg.audio.maikiwiAudio.firstNode = firstNode; // Sync last node & first + + switch (lastNode) { + case "spatial": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] gainNode -> Spatial"); + break; + case "n6": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] gainNode -> atmosphereRealizer2"); + break; + case "n5": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] gainNode -> atmosphereRealizer1"); + break; + case "n4": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] gainNode -> vibrantbass"); + break; + case "n3": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] gainNode -> audioBands"); + + break; + case "n2": + try { + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] gainNode -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] gainNode -> llpw"); + break; + case "n0": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] gainNode -> destination"); + break; + } + + console.debug("[Cider][Audio]\n" + [...configMap.entries()] + "\n lastNode: " + lastNode); + + CiderAudio.intelliGainComp_n0_0(); + console.debug("[Cider][Audio] Finished hierarchical loading"); + }, + + equalizer: function (status, destination) { + // n3_1 + if (status === true) { + let BANDS = app.cfg.audio.equalizer.frequencies; + let GAIN = app.cfg.audio.equalizer.gain; + let Q = app.cfg.audio.equalizer.Q; + + CiderAudio.audioNodes.audioBands = []; + for (let i = 0; i < BANDS.length; i++) { + CiderAudio.audioNodes.audioBands[i] = CiderAudio.context.createBiquadFilter(); + CiderAudio.audioNodes.audioBands[i].type = "peaking"; // 'peaking'; + CiderAudio.audioNodes.audioBands[i].frequency.value = BANDS[i]; + CiderAudio.audioNodes.audioBands[i].Q.value = Q[i]; + CiderAudio.audioNodes.audioBands[i].gain.value = GAIN[i] * app.cfg.audio.equalizer.mix; + } + + for (let i = 1; i < BANDS.length; i++) { + CiderAudio.audioNodes.audioBands[i - 1].connect(CiderAudio.audioNodes.audioBands[i]); + } + + switch (destination) { + case "spatial": + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] Equalizer -> Spatial"); + break; + case "n6": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] Equalizer -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] Equalizer -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] Equalizer -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] Equalizer -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] Equalizer -> destination"); + } catch (e) {} + break; + } + } + }, +}; +export { CiderAudio }; diff --git a/src/renderer/audio/cloud/audio.js b/src/renderer/audio/cloud/audio.js new file mode 100644 index 00000000..d47d9f92 --- /dev/null +++ b/src/renderer/audio/cloud/audio.js @@ -0,0 +1,1111 @@ +const CiderAudio = { + context: null, + source: null, + audioNodes: { + gainNode: null, + audioBands: null, + vibrantbassNode: null, + recorderNode: null, + intelliGainComp: null, + cloudProcessor: null, + }, + ccON: false, + mediaRecorder: null, + init: function (cb = function () {}) { + //AudioOutputs.fInit = true; + let searchInt = setInterval(function () { + if (document.getElementById("apple-music-player")) { + //AudioOutputs.eqReady = true; + document.getElementById("apple-music-player").crossOrigin = "anonymous"; + CiderAudio.connectContext(document.getElementById("apple-music-player"), 0); + + cb(); + clearInterval(searchInt); + } + }, 1000); + }, + off: function () { + try { + try { + CiderAudio.audioNodes = { + gainNode: null, + audioBands: null, + vibrantbassNode: null, + recorderNode: null, + intelliGainComp: null, + cloudProcessor: null, + }; + } catch (e) {} + CiderAudio.source.connect(CiderAudio.context.destination); + } catch (e) {} + }, + connectContext: function (mediaElem) { + if (!CiderAudio.context) { + CiderAudio.context = new window.AudioContext({ + sampleRate: 96000, + latencyHint: "playback", + }); // Don't ever remove the sample rate arg. Ask Maikiwi. + app.lyricOffset = CiderAudio.context.baseLatency + (CiderAudio.context.outputLatency ? CiderAudio.context.outputLatency : 0); + } + if (!CiderAudio.source) { + CiderAudio.source = CiderAudio.context.createMediaElementSource(mediaElem); + } else { + try { + CiderAudio.source.disconnect(CiderAudio.context.destination); + } catch (e) {} + } + CiderAudio.audioNodes.gainNode = CiderAudio.context.createGain(); + CiderAudio.audioNodes.intelliGainComp = CiderAudio.context.createGain(); + CiderAudio.source.connect(CiderAudio.audioNodes.intelliGainComp); + CiderAudio.audioNodes.intelliGainComp.connect(CiderAudio.audioNodes.gainNode); + if (app.cfg.audio.normalization) { + CiderAudio.normalizerOn(); + } + CiderAudio.hierarchical_loading(); + }, + normalizerOn: function () { + try { + let previewURL = null; + try { + previewURL = app.mk.nowPlayingItem.previewURL; + } catch (e) {} + if (previewURL == null && (app.mk.nowPlayingItem?._songId ?? app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id) != -1) { + app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem?._songId ?? app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id}`).then((response) => { + previewURL = response.data.data[0].attributes.previews[0].url; + if (previewURL) ipcRenderer.send("getPreviewURL", previewURL); + }); + } else { + if (previewURL) ipcRenderer.send("getPreviewURL", previewURL); + } + } catch (e) { + console.debug("[Cider][MaikiwiSoundCheck] normalizer func err: " + e); + } + }, + normalizerOff: function () { + CiderAudio.audioNodes.gainNode.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.5); + }, + spatialProfiles: [ + { + id: "maikiwi", + file: "./cideraudio/impulses/CiderSpatial_Maikiwi.wav", + name: "Maikiwi", + description: "", + gainComp: "1.044", + }, + { + id: "maikiwiplus", + file: "./cideraudio/impulses/CiderSpatial_MaikiwiPlus.wav", + name: "Maikiwi+", + description: "", + gainComp: "1.044", + }, + { + id: "71_420maikiwi", + file: "./cideraudio/impulses/CiderSpatial_v71.420_Maikiwi.wav", + name: "Soundstage", + description: "", + gainComp: "1.3963683610559376", + }, + { + id: "70_422maikiwi", + file: "./cideraudio/impulses/CiderSpatial_v70.422_Maikiwi.wav", + name: "Separation", + description: "", + gainComp: "1.30767553892022", + }, + { + id: "standard", + file: "./cideraudio/impulses/CiderSpatial_Natural.wav", + name: "Minimal", + description: "", + gainComp: "1.044", + }, + { + id: "standardplus", + file: "./cideraudio/impulses/CiderSpatial_Natural+.wav", + name: "Minimal+", + description: "", + gainComp: "1.044", + }, + { + id: "diffused", + file: "./cideraudio/impulses/CiderSpatial_Diffuse.wav", + name: "Diffused", + description: "", + gainComp: "1.044", + }, + { + id: "BPLK", + file: "./cideraudio/impulses/CiderSpatial_BPLK.wav", + name: "BPLK", + description: "", + gainComp: "1.044", + }, + { + id: "HW2K", + file: "./cideraudio/impulses/CiderSpatial_HW2K.wav", + name: "HW2K", + description: "", + gainComp: "1.044", + }, + { + id: "live", + file: "./cideraudio/impulses/CiderSpatial_LIVE_2.wav", + name: "live", + description: "", + gainComp: "1.2647363474711515", + }, + ], + atmosphereRealizerProfiles: [ + { + id: "NATURAL_STANDARD", + file: "./cideraudio/impulses/AtmosphereRealizer_NaturalStandard.wav", + name: "ãģうじčŒļチãƒŧã‚ēクãƒĒãƒŧãƒžãƒ†ã‚Ŗãƒŧ", + description: "", + }, + { + id: "NATURAL_PLUS", + file: "./cideraudio/impulses/AtmosphereRealizer_Natural+.wav", + name: "įŽ„įąŗčŒļã‚ŋピã‚Ēã‚ĢミãƒĢã‚¯ãƒ†ã‚Ŗãƒŧ", + description: "", + }, + { + id: "E68_1", + file: "./cideraudio/impulses/AtmosphereRealizer_E68_1.5.wav", + name: "å˛ŠåĄŠã‚¯ãƒĒãƒŧムチãƒŧã‚ēãƒ†ã‚Ŗãƒŧ", + description: "Light", + }, + { + id: "E68_2", + file: "./cideraudio/impulses/AtmosphereRealizer_E68_2.2.wav", + name: "抚čŒļミãƒĢã‚¯ãƒ†ã‚Ŗãƒŧ", + description: "Dark", + }, + { + id: "BSCBM", + file: "./cideraudio/impulses/AtmosphereRealizer_BSCBM.wav", + name: "BSCBM", + description: "BSCBM", + }, + { + id: "CUDDLE", + file: "./cideraudio/impulses/AtmosphereRealizer_Cuddle.wav", + name: "CUDDLE", + description: "CUDDLE", + }, + { + id: "E168_1", + file: "./cideraudio/impulses/AtmosphereRealizer_E168_1.2.wav", + name: "æ˜Ĩæ¯Ģã‚¸ãƒŖã‚šãƒŸãƒŗãƒžã‚­ã‚ĸãƒŧト", + description: "Natural Air", + }, + { + id: "Z3600", + file: "./cideraudio/impulses/AtmosphereRealizer_Z3600.wav", + name: "ロイヤãƒĢミãƒĢã‚¯ãƒ†ã‚Ŗãƒŧ", + description: "3600", + }, + { + id: "Z8500A", + file: "./cideraudio/impulses/AtmosphereRealizer_Z8500_A.wav", + name: "ムãƒŧãƒŗãƒŠã‚¤ãƒˆã‚Ŋãƒ•ãƒˆã‚ąãƒŧキ", + description: "8500", + }, + { + id: "Z8500B", + file: "./cideraudio/impulses/AtmosphereRealizer_Z8500_B.wav", + name: "Clafoutis aux Cerises", + description: "8500", + }, + { + id: "Z8500C", + file: "./cideraudio/impulses/AtmosphereRealizer_Z8500_C.wav", + name: "厇æ˛ģ抚čŒļだいãĩく", + description: "8500", + }, + ], + opportunisticCorrectionProfiles: [ + { + id: "CHU", + file: "./cideraudio/impulses/MoondropCHU_Cider.wav", + name: "Moondrop CHU Specific", + description: "", + }, + ], + cloudProcessor_ninf: function () { + CiderAudio.audioNodes.cloudProcessor = null; + CiderAudio.audioNodes.cloudProcessor = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.cloudProcessor.normalize = false; + + // Always destination + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.context.destination); + }, + spatialOff: function () { + CiderAudio.hierarchical_loading(); + }, + intelliGainComp_n0_0: function () { + let filters = []; + const precisionHz = 12; + // Biquad calculation + if (CiderAudio.audioNodes.audioBands !== null) { + filters = filters.concat(CiderAudio.audioNodes.audioBands); + } + if (CiderAudio.audioNodes.vibrantbassNode !== null) { + filters = filters.concat(CiderAudio.audioNodes.vibrantbassNode); + } + + if (!filters || filters.length === 0) { + let filterlessGain = 1; + + CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3); + console.debug(`[Cider][Audio] IntelliGainComp: 0 dB (1.0)`); + return; + } + + filters.shift(); + let steps = Math.ceil(96000 / precisionHz); + // Generate input array for getFrequencyResponse method + let frequencies = new Float32Array(steps); + for (let i = 0; i < steps; i++) { + frequencies[i] = (i + 1) * precisionHz; + } + // Here we will store combined amplitude response + let totalAmplitudeResp = new Float32Array(steps); + for (let i = 0; i < steps; i++) { + totalAmplitudeResp[i] = 1; + } + // Temporary container for every filter response + let amplitudeResp = new Float32Array(steps), + phaseResp = new Float32Array(steps); + for (let i = filters.length - 1; i >= 0; i--) { + let filter = filters[i]; + // Get filter response and convolve it with existing response + filter.getFrequencyResponse(frequencies, amplitudeResp, phaseResp); + for (let j = 0; j < steps; j++) { + totalAmplitudeResp[j] *= amplitudeResp[j]; + } + } + // Find max gain + let maxGain = -120; + for (let i = 0; i < steps; i++) { + let gain = totalAmplitudeResp[i]; + if (gain > maxGain) maxGain = gain; + } + + maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4); + maxGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudio.context.currentTime + 0.3); + console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`); + }, + sendAudio: function () { + if (!CiderAudio.ccON) { + CiderAudio.ccON = true; + let searchInt = setInterval(async function () { + if (CiderAudio.context != null && CiderAudio.audioNodes.intelliGainComp != null) { + // var options = { + // mimeType: 'audio/webm; codecs=opus' + // }; + // var destnode = CiderAudio.context.createMediaStreamDestination(); + // CiderAudio.audioNodes.intelliGainComp.connect(CiderAudio.audioNodes.gainNode); + // CiderAudio.audioNodes.gainNode.connect(destnode) + // CiderAudio.mediaRecorder = new MediaRecorder(destnode.stream, options); + // CiderAudio.mediaRecorder.start(1); + // CiderAudio.mediaRecorder.ondataavailable = function (e) { + // e.data.arrayBuffer().then(buffer => { + // ipcRenderer.send('writeAudio', buffer) + // } + // ); + // } + const worklet = `class RecorderWorkletProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return [{ + name: 'isRecording', + defaultValue: 0 + }, + { + name: 'numberOfChannels', + defaultValue: 2 + } + ]; + } + + constructor() { + super(); + this._bufferSize = 2048; + this._buffers = null; + this._initBuffer(); + } + _initBuffers(numberOfChannels) { + this._buffers = []; + for (let channel=0; channel < numberOfChannels; channel++) { + this._buffers.push(new Float32Array(this._bufferSize)); + } + } + + _initBuffer() { + this._bytesWritten = 0; + } + + _isBufferEmpty() { + return this._bytesWritten === 0; + } + + _isBufferFull() { + return this._bytesWritten === this._bufferSize; + } + _pushToBuffers(audioRawData, numberOfChannels) { + if (this._isBufferFull()) { + this._flush(); + } + let dataLength = audioRawData[0]?.length ?? 0; + for (let idx=0; idx { + if (this._bytesWritten < this._bufferSize) { + buffer = buffer.slice(0, this._bytesWritten); + } + buffers[channel] = buffer; + }); + this.port.postMessage({ + eventType: 'data', + audioBuffer: buffers, + bufferSize: this._bufferSize + }); + this._initBuffer(); + } + + _recordingStopped() { + this.port.postMessage({ + eventType: 'stop' + }); + } + + process(inputs, outputs, parameters) { + const isRecordingValues = parameters.isRecording; + const numberOfChannels = parameters.numberOfChannels[0]; + if (this._buffers === null) { + this._initBuffers(numberOfChannels); + } + + for (let dataIndex = 0; dataIndex < isRecordingValues.length; dataIndex++) + { + const shouldRecord = isRecordingValues[dataIndex] === 1; + if (!shouldRecord && !this._isBufferEmpty()) { + this._flush(); + this._recordingStopped(); + } + + if (shouldRecord) { + let audioRawData = inputs[0]; + this._pushToBuffers(audioRawData, numberOfChannels); + } + } + return true; + } + + } + + registerProcessor('recorder-worklet', RecorderWorkletProcessor);`; + let blob = new Blob([worklet], { type: "application/javascript" }); + await CiderAudio.context.audioWorklet.addModule(URL.createObjectURL(blob)).then(() => { + const channels = 2; + CiderAudio.audioNodes.recorderNode = new window.AudioWorkletNode(CiderAudio.context, "recorder-worklet", { + parameterData: { numberOfChannels: channels }, + }); + CiderAudio.audioNodes.recorderNode.port.onmessage = (e) => { + const data = e.data; + switch (data.eventType) { + case "data": + const audioData = data.audioBuffer; + const bufferSize = data.bufferSize; + if (audioData[0].some((item) => item !== 0) || audioData[0].some((item) => item !== 0)) { + ipcRenderer.send("writeWAV", audioData[0], audioData[1], bufferSize); + } + break; + case "stop": + break; + } + }; + CiderAudio.audioNodes.recorderNode.parameters.get("isRecording").setValueAtTime(1, CiderAudio.context.currentTime); + CiderAudio.audioNodes.intelliGainComp.connect(CiderAudio.audioNodes.recorderNode); + }); + clearInterval(searchInt); + } + }, 1000); + } else { + if (CiderAudio.audioNodes.recorderNode != null && CiderAudio.context != null) { + CiderAudio.audioNodes.recorderNode.parameters.get("isRecording").setValueAtTime(1, CiderAudio.context.currentTime); + // CiderAudio.audioNodes.recorderNode = null; + // CiderAudio.ccON = false; + } + } + }, + stopAudio() { + if (CiderAudio.audioNodes.recorderNode != null && CiderAudio.context != null) { + CiderAudio.audioNodes.recorderNode.parameters.get("isRecording").setValueAtTime(0, CiderAudio.context.currentTime); + // CiderAudio.audioNodes.recorderNode = null; + // CiderAudio.ccON = false; + } + }, + atmosphereRealizer2_n6: function (status, destination) { + if (status === true) { + CiderAudio.audioNodes.atmosphereRealizer2 = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.atmosphereRealizer2.normalize = false; + let atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer2_value; + }); + + if (atmosphereRealizerProfile === undefined) { + atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles[0]; + } + fetch(atmosphereRealizerProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.atmosphereRealizer2.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> destination"); + } catch (e) {} + break; + } + } + }, + atmosphereRealizer1_n5: function (status, destination) { + if (status === true) { + CiderAudio.audioNodes.atmosphereRealizer1 = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.atmosphereRealizer1.normalize = false; + let atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer1_value; + }); + + if (atmosphereRealizerProfile === undefined) { + atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles[0]; + } + fetch(atmosphereRealizerProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.atmosphereRealizer1.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> destination"); + } catch (e) {} + break; + } + } + }, + opportunisticCorrection_n2: function (status, destination) { + if (status === true) { + CiderAudio.audioNodes.opportunisticCorrection = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.opportunisticCorrection.normalize = false; + let opportunisticCorrectionProfile = CiderAudio.opportunisticCorrectionProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.opportunisticCorrection_state; + }); + + if (opportunisticCorrectionProfile === undefined) { + opportunisticCorrectionProfile = CiderAudio.opportunisticCorrectionProfiles[0]; + } + fetch(opportunisticCorrectionProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.opportunisticCorrection.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.opportunisticCorrection[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> destination"); + } catch (e) {} + break; + } + } + }, + llpw_n1: function (status, destination) { + if (status === true) { + let c_LLPW_Q = [1.25, 0.131, 10, 2.5, 2.293, 0.11, 14.14, 1.552, 28.28, 7.071, 2.847, 5, 0.625, 7.071, 3.856, 3.856, 20, 28.28, 20, 14.14, 2.102, 6.698, 3.536, 10]; + let c_LLPW_GAIN = [-0.11, 0.27, -0.8, 0.57, 1.84, -0.38, 0.47, -1.56, 0.83, 1.58, -1.79, -0.45, 0.48, 1.22, -1.58, -1.59, -2.03, 2.56, -2.2, -2.48, 4.75, 10.5, 1.43, 3.76]; + let c_LLPW_FREQUENCIES = [400.83, 5812.8, 8360, 10413, 10658, 12079, 12899, 13205, 14848, 15591, 15778, 15783, 16716, 16891, 17255, 17496, 18555, 18622, 19219, 19448, 19664, 21341, 21353, 22595]; + let LLPW_Q = [5, 1, 3.536, 1.25, 8.409, 1.25, 14.14, 7.071, 5, 0.625, 16.82, 20, 20, 20, 28.28, 28.28, 28.28, 20, 33.64, 33.64, 10, 28.28, 7.071, 3.856]; + let LLPW_GAIN = [0.38, -1.81, -0.23, -0.51, 0.4, 0.84, 0.36, -0.34, 0.27, -1.2, -0.42, -0.67, 0.81, 1.31, -0.71, 0.68, -1.04, 0.79, -0.73, -1.33, 1.17, 0.57, 0.35, 6.33]; + let LLPW_FREQUENCIES = [16.452, 24.636, 37.134, 74.483, 159.54, 308.18, 670.21, 915.81, 1200.7, 2766.4, 2930.6, 4050.6, 4409.1, 5395.2, 5901.6, 6455.5, 7164.1, 7724.1, 8449, 10573, 12368, 14198, 17910, 18916]; + CiderAudio.audioNodes.llpw = []; + + switch (app.cfg.audio.maikiwiAudio.ciderPPE_value) { + case "MAIKIWI": + try { + switch (localStorage.getItem("playingBitrate")) { + case "64": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + fetch("./cideraudio/impulses/CAP_64.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - 64kbps"); + + break; + case "256": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[1].gain.value = 2.37; // Post Gain Compensation + CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]); + fetch("./cideraudio/impulses/CAP_256_FINAL_48k.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - 256kbps"); + + break; + default: + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[0].gain.value = 1; + console.debug("[Cider][Audio] CAP Disabled (Passthrough) : Non-Lossy Bitrate."); + + break; + } + } catch (e) { + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[1].gain.value = 2.37; + CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]); + fetch("./cideraudio/impulses/CAP_256_FINAL_48k.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - (Error Fallback) 256kbps"); + } + + break; + case "MAIKIWI_LEGACY": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + fetch("./cideraudio/impulses/CAP_Maikiwi.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP - Maikiwi Signature Mode"); + break; + case "NATURAL": + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + fetch("./cideraudio/impulses/CAP_Natural.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + + console.debug("[Cider][Audio] CAP - Natural Mode"); + break; + + case "LEGACY": + for (let i = 0; i < LLPW_FREQUENCIES.length; i++) { + CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter(); + CiderAudio.audioNodes.llpw[i].type = "peaking"; // 'peaking'; + CiderAudio.audioNodes.llpw[i].frequency.value = LLPW_FREQUENCIES[i]; + CiderAudio.audioNodes.llpw[i].Q.value = LLPW_Q[i]; + CiderAudio.audioNodes.llpw[i].gain.value = LLPW_GAIN[i]; + } + for (let i = 1; i < LLPW_FREQUENCIES.length; i++) { + CiderAudio.audioNodes.llpw[i - 1].connect(CiderAudio.audioNodes.llpw[i]); + } + console.debug("[Cider][Audio] CAP - Legacy Mode"); + + break; + + default: + CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.llpw[0].normalize = false; + CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); + CiderAudio.audioNodes.llpw[1].gain.value = 2.57; + CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]); + fetch("./cideraudio/impulses/CAP_256_FINAL_48k.wav").then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); + app.cfg.audio.maikiwiAudio.ciderPPE_value = "MAIKIWI"; + + console.debug("[Cider][Audio] CAP - Maikiwi Adaptive Mode (Defaulted from broki config)"); + break; + } + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] llpw_n1 -> Spatial"); + } catch (e) {} + break; + case "n6": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] llpw_n1 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] llpw_n1 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] llpw_n1 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] llpw_n1 -> destination"); + } catch (e) {} + break; + } + } + }, + vibrantbass_n4: function (status, destination) { + if (status === true) { + let VIBRANTBASSBANDS = app.cfg.audio.maikiwiAudio.vibrantBass.frequencies; + let VIBRANTBASSGAIN = app.cfg.audio.maikiwiAudio.vibrantBass.gain; + let VIBRANTBASSQ = app.cfg.audio.maikiwiAudio.vibrantBass.Q; + CiderAudio.audioNodes.vibrantbassNode = []; + + for (let i = 0; i < VIBRANTBASSBANDS.length; i++) { + CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter(); + CiderAudio.audioNodes.vibrantbassNode[i].type = "peaking"; // 'peaking'; + CiderAudio.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i]; + CiderAudio.audioNodes.vibrantbassNode[i].Q.value = VIBRANTBASSQ[i]; + CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * (app.cfg.audio.equalizer.vibrantBass / 10); + } + + for (let i = 1; i < VIBRANTBASSBANDS.length; i++) { + CiderAudio.audioNodes.vibrantbassNode[i - 1].connect(CiderAudio.audioNodes.vibrantbassNode[i]); + } + + switch (destination) { + case "spatial": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] vibrantbass_n4 -> Spatial"); + } catch (e) {} + break; + + case "n6": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] vibrantbass_n4 -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] vibrantbass_n4 -> destination"); + } catch (e) {} + break; + } + } + }, + hierarchical_unloading: function () { + try { + CiderAudio.audioNodes.spatialNode.disconnect(); + CiderAudio.audioNodes.spatialNode = null; + } catch (e) {} + try { + CiderAudio.audioNodes.gainNode.disconnect(); + } catch (e) {} + try { + CiderAudio.audioNodes.atmosphereRealizer2.disconnect(); + CiderAudio.audioNodes.atmosphereRealizer2 = null; + } catch (e) {} + try { + CiderAudio.audioNodes.atmosphereRealizer1.disconnect(); + CiderAudio.audioNodes.atmosphereRealizer1 = null; + } catch (e) {} + try { + for (var i of CiderAudio.audioNodes.llpw) { + i.disconnect(); + } + CiderAudio.audioNodes.llpw = null; + } catch (e) {} + try { + for (var i of CiderAudio.audioNodes.vibrantbassNode) { + i.disconnect(); + } + CiderAudio.audioNodes.vibrantbassNode = null; + } catch (e) {} + try { + for (var i of CiderAudio.audioNodes.audioBands) { + i.disconnect(); + } + CiderAudio.audioNodes.vibrantbassNode = null; + } catch (e) {} + try { + CiderAudio.audioNodes.opportunisticCorrection.disconnect(); + CiderAudio.audioNodes.opportunisticCorrection = null; + } catch (e) {} + console.debug("[Cider][Audio] Finished hierarchical unloading"); + }, + hierarchical_loading: async function () { + const configMap = new Map([ + ["spatial", app.cfg.audio.maikiwiAudio.spatial === true], + ["n6", app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true], + ["n5", app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true], + ["n4", app.cfg.audio.equalizer.vibrantBass != 0], + ["n3", Math.max(...app.cfg.audio.equalizer.gain) != 0], + ["n2", app.cfg.audio.maikiwiAudio.opportunisticCorrection_state !== "OFF"], + ["n1", app.cfg.audio.maikiwiAudio.ciderPPE === true], + ]); + + CiderAudio.hierarchical_unloading(); + let lastNode = "n0"; + let index = 0; + let firstNode = "n0"; + for (let [tier, value] of configMap.entries()) { + if (value === true) { + if (index === 0) { + firstNode = tier; + } + index++; + switch (tier) { + case "spatial": + CiderAudio.spatial_ninf(); + lastNode = "spatial"; + break; + case "n6": + app.cfg.audio.normalization = true; + CiderAudio.atmosphereRealizer2_n6(true, lastNode); + lastNode = "n6"; + break; + case "n5": + app.cfg.audio.normalization = true; + CiderAudio.atmosphereRealizer1_n5(true, lastNode); + lastNode = "n5"; + break; + case "n4": + CiderAudio.vibrantbass_n4(true, lastNode); + lastNode = "n4"; + break; + case "n3": + CiderAudio.equalizer(true, lastNode); + lastNode = "n3"; + break; + case "n2": + CiderAudio.opportunisticCorrection_n2(true, lastNode); + lastNode = "n2"; + break; + case "n1": + app.cfg.audio.normalization = true; + CiderAudio.llpw_n1(true, lastNode); + lastNode = "n1"; + break; + } + } + } + + app.cfg.audio.maikiwiAudio.lastNode = lastNode; + app.cfg.audio.maikiwiAudio.firstNode = firstNode; // Sync last node & first + + switch (lastNode) { + case "spatial": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] gainNode -> Spatial"); + break; + case "n6": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] gainNode -> atmosphereRealizer2"); + break; + case "n5": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] gainNode -> atmosphereRealizer1"); + break; + case "n4": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] gainNode -> vibrantbass"); + break; + case "n3": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] gainNode -> audioBands"); + + break; + case "n2": + try { + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] gainNode -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] gainNode -> llpw"); + break; + case "n0": + CiderAudio.audioNodes.gainNode.connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] gainNode -> destination"); + break; + } + + console.debug("[Cider][Audio]\n" + [...configMap.entries()] + "\n lastNode: " + lastNode); + + CiderAudio.intelliGainComp_n0_0(); + console.debug("[Cider][Audio] Finished hierarchical loading"); + }, + + equalizer: function (status, destination) { + // n3_1 + if (status === true) { + let BANDS = app.cfg.audio.equalizer.frequencies; + let GAIN = app.cfg.audio.equalizer.gain; + let Q = app.cfg.audio.equalizer.Q; + + CiderAudio.audioNodes.audioBands = []; + for (let i = 0; i < BANDS.length; i++) { + CiderAudio.audioNodes.audioBands[i] = CiderAudio.context.createBiquadFilter(); + CiderAudio.audioNodes.audioBands[i].type = "peaking"; // 'peaking'; + CiderAudio.audioNodes.audioBands[i].frequency.value = BANDS[i]; + CiderAudio.audioNodes.audioBands[i].Q.value = Q[i]; + CiderAudio.audioNodes.audioBands[i].gain.value = GAIN[i] * app.cfg.audio.equalizer.mix; + } + + for (let i = 1; i < BANDS.length; i++) { + CiderAudio.audioNodes.audioBands[i - 1].connect(CiderAudio.audioNodes.audioBands[i]); + } + + switch (destination) { + case "spatial": + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.spatialNode); + console.debug("[Cider][Audio] Equalizer -> Spatial"); + break; + case "n6": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer2"); + } catch (e) {} + break; + case "n5": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer1"); + } catch (e) {} + break; + case "n4": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] Equalizer -> vibrantbassNode"); + } catch (e) {} + break; + case "n3": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] Equalizer -> audioBands"); + } catch (e) {} + break; + case "n2": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] Equalizer -> opportunisticCorrection"); + } catch (e) {} + break; + case "n1": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.llpw[0]); + console.debug("[Cider][Audio] Equalizer -> llpw"); + } catch (e) {} + break; + case "n0": + try { + CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.context.destination); + console.debug("[Cider][Audio] Equalizer -> destination"); + } catch (e) {} + break; + } + } + }, +}; +export { CiderAudio }; diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_BSCBM.wav b/src/renderer/audio/impulses/AtmosphereRealizer_BSCBM.wav new file mode 100644 index 00000000..4a3a6152 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_BSCBM.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_Cuddle.wav b/src/renderer/audio/impulses/AtmosphereRealizer_Cuddle.wav new file mode 100644 index 00000000..06cc8a08 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_Cuddle.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_E168_1.2.wav b/src/renderer/audio/impulses/AtmosphereRealizer_E168_1.2.wav new file mode 100644 index 00000000..354e09f6 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_E168_1.2.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_E68_1.5.wav b/src/renderer/audio/impulses/AtmosphereRealizer_E68_1.5.wav new file mode 100644 index 00000000..6ec330ec Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_E68_1.5.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_E68_2.2.wav b/src/renderer/audio/impulses/AtmosphereRealizer_E68_2.2.wav new file mode 100644 index 00000000..9ffd14f3 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_E68_2.2.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_Natural+.wav b/src/renderer/audio/impulses/AtmosphereRealizer_Natural+.wav new file mode 100644 index 00000000..18c6dec9 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_Natural+.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_NaturalStandard.wav b/src/renderer/audio/impulses/AtmosphereRealizer_NaturalStandard.wav new file mode 100644 index 00000000..970cd609 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_NaturalStandard.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_Z3600.wav b/src/renderer/audio/impulses/AtmosphereRealizer_Z3600.wav new file mode 100644 index 00000000..cc5e80c3 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_Z3600.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_A.wav b/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_A.wav new file mode 100644 index 00000000..fe68fe0c Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_A.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_B.wav b/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_B.wav new file mode 100644 index 00000000..e4dbf263 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_B.wav differ diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_C.wav b/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_C.wav new file mode 100644 index 00000000..b83bdeea Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_Z8500_C.wav differ diff --git a/src/renderer/audio/impulses/CAP_256_FINAL_48k.wav b/src/renderer/audio/impulses/CAP_256_FINAL_48k.wav new file mode 100644 index 00000000..45d80862 Binary files /dev/null and b/src/renderer/audio/impulses/CAP_256_FINAL_48k.wav differ diff --git a/src/renderer/audio/impulses/CAP_64.wav b/src/renderer/audio/impulses/CAP_64.wav new file mode 100644 index 00000000..4a5eb93a Binary files /dev/null and b/src/renderer/audio/impulses/CAP_64.wav differ diff --git a/src/renderer/audio/impulses/CAP_Maikiwi.wav b/src/renderer/audio/impulses/CAP_Maikiwi.wav new file mode 100644 index 00000000..5e9156dd Binary files /dev/null and b/src/renderer/audio/impulses/CAP_Maikiwi.wav differ diff --git a/src/renderer/audio/impulses/CAP_Natural.wav b/src/renderer/audio/impulses/CAP_Natural.wav new file mode 100644 index 00000000..8aba11a9 Binary files /dev/null and b/src/renderer/audio/impulses/CAP_Natural.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_BPLK.wav b/src/renderer/audio/impulses/CiderSpatial_BPLK.wav new file mode 100644 index 00000000..d6bc918c Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_BPLK.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_Diffuse.wav b/src/renderer/audio/impulses/CiderSpatial_Diffuse.wav new file mode 100644 index 00000000..793895e4 Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_Diffuse.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_HW2K.wav b/src/renderer/audio/impulses/CiderSpatial_HW2K.wav new file mode 100644 index 00000000..914925fd Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_HW2K.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_LIVE_2.wav b/src/renderer/audio/impulses/CiderSpatial_LIVE_2.wav new file mode 100644 index 00000000..2323b5f0 Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_LIVE_2.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_Maikiwi.wav b/src/renderer/audio/impulses/CiderSpatial_Maikiwi.wav new file mode 100644 index 00000000..849131aa Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_Maikiwi.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_MaikiwiPlus.wav b/src/renderer/audio/impulses/CiderSpatial_MaikiwiPlus.wav new file mode 100644 index 00000000..bdae8712 Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_MaikiwiPlus.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_Natural+.wav b/src/renderer/audio/impulses/CiderSpatial_Natural+.wav new file mode 100644 index 00000000..176a6b96 Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_Natural+.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_Natural.wav b/src/renderer/audio/impulses/CiderSpatial_Natural.wav new file mode 100644 index 00000000..10117b9e Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_Natural.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_v69_Standard.wav b/src/renderer/audio/impulses/CiderSpatial_v69_Standard.wav new file mode 100644 index 00000000..947d6f65 Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_v69_Standard.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_v70.422_Maikiwi.wav b/src/renderer/audio/impulses/CiderSpatial_v70.422_Maikiwi.wav new file mode 100644 index 00000000..4f2683f9 Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_v70.422_Maikiwi.wav differ diff --git a/src/renderer/audio/impulses/CiderSpatial_v71.420_Maikiwi.wav b/src/renderer/audio/impulses/CiderSpatial_v71.420_Maikiwi.wav new file mode 100644 index 00000000..23fa42ae Binary files /dev/null and b/src/renderer/audio/impulses/CiderSpatial_v71.420_Maikiwi.wav differ diff --git a/src/renderer/audio/impulses/MoondropCHU_Cider.wav b/src/renderer/audio/impulses/MoondropCHU_Cider.wav new file mode 100644 index 00000000..ab57c636 Binary files /dev/null and b/src/renderer/audio/impulses/MoondropCHU_Cider.wav differ diff --git a/src/renderer/hlscider.js b/src/renderer/hlscider.js index b2d6ce87..f7da6d23 100644 --- a/src/renderer/hlscider.js +++ b/src/renderer/hlscider.js @@ -1,6472 +1,6696 @@ typeof window !== "undefined" && -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["CiderHls"] = factory(); - else - root["CiderHls"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = "/dist/"; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = "./src/CiderHls.ts"); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ "./node_modules/eventemitter3/index.js": -/*!*********************************************!*\ + (function webpackUniversalModuleDefinition(root, factory) { + if (typeof exports === "object" && typeof module === "object") module.exports = factory(); + else if (typeof define === "function" && define.amd) define([], factory); + else if (typeof exports === "object") exports["CiderHls"] = factory(); + else root["CiderHls"] = factory(); + })(this, function () { + return /******/ (function (modules) { + // webpackBootstrap + /******/ // The module cache + /******/ var installedModules = {}; + /******/ + /******/ // The require function + /******/ function __webpack_require__(moduleId) { + /******/ + /******/ // Check if module is in cache + /******/ if (installedModules[moduleId]) { + /******/ return installedModules[moduleId].exports; + /******/ + } + /******/ // Create a new module (and put it into the cache) + /******/ var module = (installedModules[moduleId] = { + /******/ i: moduleId, + /******/ l: false, + /******/ exports: {}, + /******/ + }); + /******/ + /******/ // Execute the module function + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + /******/ + /******/ // Flag the module as loaded + /******/ module.l = true; + /******/ + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ + } + /******/ + /******/ + /******/ // expose the modules object (__webpack_modules__) + /******/ __webpack_require__.m = modules; + /******/ + /******/ // expose the module cache + /******/ __webpack_require__.c = installedModules; + /******/ + /******/ // define getter function for harmony exports + /******/ __webpack_require__.d = function (exports, name, getter) { + /******/ if (!__webpack_require__.o(exports, name)) { + /******/ Object.defineProperty(exports, name, { + enumerable: true, + get: getter, + }); + /******/ + } + /******/ + }; + /******/ + /******/ // define __esModule on exports + /******/ __webpack_require__.r = function (exports) { + /******/ if (typeof Symbol !== "undefined" && Symbol.toStringTag) { + /******/ Object.defineProperty(exports, Symbol.toStringTag, { + value: "Module", + }); + /******/ + } + /******/ Object.defineProperty(exports, "__esModule", { value: true }); + /******/ + }; + /******/ + /******/ // create a fake namespace object + /******/ // mode & 1: value is a module id, require it + /******/ // mode & 2: merge all properties of value into the ns + /******/ // mode & 4: return value when already ns object + /******/ // mode & 8|1: behave like require + /******/ __webpack_require__.t = function (value, mode) { + /******/ if (mode & 1) value = __webpack_require__(value); + /******/ if (mode & 8) return value; + /******/ if (mode & 4 && typeof value === "object" && value && value.__esModule) return value; + /******/ var ns = Object.create(null); + /******/ __webpack_require__.r(ns); + /******/ Object.defineProperty(ns, "default", { + enumerable: true, + value: value, + }); + /******/ if (mode & 2 && typeof value != "string") + for (var key in value) + __webpack_require__.d( + ns, + key, + function (key) { + return value[key]; + }.bind(null, key) + ); + /******/ return ns; + /******/ + }; + /******/ + /******/ // getDefaultExport function for compatibility with non-harmony modules + /******/ __webpack_require__.n = function (module) { + /******/ var getter = + module && module.__esModule + ? /******/ function getDefault() { + return module["default"]; + } + : /******/ function getModuleExports() { + return module; + }; + /******/ __webpack_require__.d(getter, "a", getter); + /******/ return getter; + /******/ + }; + /******/ + /******/ // Object.prototype.hasOwnProperty.call + /******/ __webpack_require__.o = function (object, property) { + return Object.prototype.hasOwnProperty.call(object, property); + }; + /******/ + /******/ // __webpack_public_path__ + /******/ __webpack_require__.p = "/dist/"; + /******/ + /******/ + /******/ // Load entry module and return exports + /******/ return __webpack_require__((__webpack_require__.s = "./src/CiderHls.ts")); + /******/ + })( + /************************************************************************/ + /******/ { + /***/ "./node_modules/eventemitter3/index.js": + /*!*********************************************!*\ !*** ./node_modules/eventemitter3/index.js ***! \*********************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { + /*! no static exports found */ + /***/ function (module, exports, __webpack_require__) { + "use strict"; -"use strict"; + var has = Object.prototype.hasOwnProperty, + prefix = "~"; + /** + * Constructor to create a storage for our `EE` objects. + * An `Events` instance is a plain object whose properties are event names. + * + * @constructor + * @private + */ + function Events() {} -var has = Object.prototype.hasOwnProperty - , prefix = '~'; + // + // We try to not inherit from `Object.prototype`. In some engines creating an + // instance in this way is faster than calling `Object.create(null)` directly. + // If `Object.create(null)` is not supported we prefix the event names with a + // character to make sure that the built-in object properties are not + // overridden or used as an attack vector. + // + if (Object.create) { + Events.prototype = Object.create(null); -/** - * Constructor to create a storage for our `EE` objects. - * An `Events` instance is a plain object whose properties are event names. - * - * @constructor - * @private - */ -function Events() {} + // + // This hack is needed because the `__proto__` property is still inherited in + // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. + // + if (!new Events().__proto__) prefix = false; + } -// -// We try to not inherit from `Object.prototype`. In some engines creating an -// instance in this way is faster than calling `Object.create(null)` directly. -// If `Object.create(null)` is not supported we prefix the event names with a -// character to make sure that the built-in object properties are not -// overridden or used as an attack vector. -// -if (Object.create) { - Events.prototype = Object.create(null); + /** + * Representation of a single event listener. + * + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} [once=false] Specify if the listener is a one-time listener. + * @constructor + * @private + */ + function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; + } - // - // This hack is needed because the `__proto__` property is still inherited in - // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. - // - if (!new Events().__proto__) prefix = false; -} + /** + * Add a listener for a given event. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} once Specify if the listener is a one-time listener. + * @returns {EventEmitter} + * @private + */ + function addListener(emitter, event, fn, context, once) { + if (typeof fn !== "function") { + throw new TypeError("The listener must be a function"); + } -/** - * Representation of a single event listener. - * - * @param {Function} fn The listener function. - * @param {*} context The context to invoke the listener with. - * @param {Boolean} [once=false] Specify if the listener is a one-time listener. - * @constructor - * @private - */ -function EE(fn, context, once) { - this.fn = fn; - this.context = context; - this.once = once || false; -} + var listener = new EE(fn, context || emitter, once), + evt = prefix ? prefix + event : event; -/** - * Add a listener for a given event. - * - * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. - * @param {(String|Symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} context The context to invoke the listener with. - * @param {Boolean} once Specify if the listener is a one-time listener. - * @returns {EventEmitter} - * @private - */ -function addListener(emitter, event, fn, context, once) { - if (typeof fn !== 'function') { - throw new TypeError('The listener must be a function'); - } + if (!emitter._events[evt]) (emitter._events[evt] = listener), emitter._eventsCount++; + else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); + else emitter._events[evt] = [emitter._events[evt], listener]; - var listener = new EE(fn, context || emitter, once) - , evt = prefix ? prefix + event : event; + return emitter; + } - if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; - else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); - else emitter._events[evt] = [emitter._events[evt], listener]; + /** + * Clear event by name. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} evt The Event name. + * @private + */ + function clearEvent(emitter, evt) { + if (--emitter._eventsCount === 0) emitter._events = new Events(); + else delete emitter._events[evt]; + } - return emitter; -} + /** + * Minimal `EventEmitter` interface that is molded against the Node.js + * `EventEmitter` interface. + * + * @constructor + * @public + */ + function EventEmitter() { + this._events = new Events(); + this._eventsCount = 0; + } -/** - * Clear event by name. - * - * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. - * @param {(String|Symbol)} evt The Event name. - * @private - */ -function clearEvent(emitter, evt) { - if (--emitter._eventsCount === 0) emitter._events = new Events(); - else delete emitter._events[evt]; -} + /** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @public + */ + EventEmitter.prototype.eventNames = function eventNames() { + var names = [], + events, + name; -/** - * Minimal `EventEmitter` interface that is molded against the Node.js - * `EventEmitter` interface. - * - * @constructor - * @public - */ -function EventEmitter() { - this._events = new Events(); - this._eventsCount = 0; -} + if (this._eventsCount === 0) return names; -/** - * Return an array listing the events for which the emitter has registered - * listeners. - * - * @returns {Array} - * @public - */ -EventEmitter.prototype.eventNames = function eventNames() { - var names = [] - , events - , name; + for (name in (events = this._events)) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } - if (this._eventsCount === 0) return names; + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } - for (name in (events = this._events)) { - if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); - } + return names; + }; - if (Object.getOwnPropertySymbols) { - return names.concat(Object.getOwnPropertySymbols(events)); - } + /** + * Return the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Array} The registered listeners. + * @public + */ + EventEmitter.prototype.listeners = function listeners(event) { + var evt = prefix ? prefix + event : event, + handlers = this._events[evt]; - return names; -}; + if (!handlers) return []; + if (handlers.fn) return [handlers.fn]; -/** - * Return the listeners registered for a given event. - * - * @param {(String|Symbol)} event The event name. - * @returns {Array} The registered listeners. - * @public - */ -EventEmitter.prototype.listeners = function listeners(event) { - var evt = prefix ? prefix + event : event - , handlers = this._events[evt]; + for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { + ee[i] = handlers[i].fn; + } - if (!handlers) return []; - if (handlers.fn) return [handlers.fn]; + return ee; + }; - for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { - ee[i] = handlers[i].fn; - } + /** + * Return the number of listeners listening to a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Number} The number of listeners. + * @public + */ + EventEmitter.prototype.listenerCount = function listenerCount(event) { + var evt = prefix ? prefix + event : event, + listeners = this._events[evt]; - return ee; -}; + if (!listeners) return 0; + if (listeners.fn) return 1; + return listeners.length; + }; -/** - * Return the number of listeners listening to a given event. - * - * @param {(String|Symbol)} event The event name. - * @returns {Number} The number of listeners. - * @public - */ -EventEmitter.prototype.listenerCount = function listenerCount(event) { - var evt = prefix ? prefix + event : event - , listeners = this._events[evt]; + /** + * Calls each of the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Boolean} `true` if the event had listeners, else `false`. + * @public + */ + EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; - if (!listeners) return 0; - if (listeners.fn) return 1; - return listeners.length; -}; + if (!this._events[evt]) return false; -/** - * Calls each of the listeners registered for a given event. - * - * @param {(String|Symbol)} event The event name. - * @returns {Boolean} `true` if the event had listeners, else `false`. - * @public - */ -EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { - var evt = prefix ? prefix + event : event; + var listeners = this._events[evt], + len = arguments.length, + args, + i; - if (!this._events[evt]) return false; + if (listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); - var listeners = this._events[evt] - , len = arguments.length - , args - , i; + switch (len) { + case 1: + return listeners.fn.call(listeners.context), true; + case 2: + return listeners.fn.call(listeners.context, a1), true; + case 3: + return listeners.fn.call(listeners.context, a1, a2), true; + case 4: + return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: + return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: + return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; + } - if (listeners.fn) { - if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); + for (i = 1, args = new Array(len - 1); i < len; i++) { + args[i - 1] = arguments[i]; + } - switch (len) { - case 1: return listeners.fn.call(listeners.context), true; - case 2: return listeners.fn.call(listeners.context, a1), true; - case 3: return listeners.fn.call(listeners.context, a1, a2), true; - case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; - case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; - case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; - } + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length, + j; - for (i = 1, args = new Array(len -1); i < len; i++) { - args[i - 1] = arguments[i]; - } + for (i = 0; i < length; i++) { + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); - listeners.fn.apply(listeners.context, args); - } else { - var length = listeners.length - , j; + switch (len) { + case 1: + listeners[i].fn.call(listeners[i].context); + break; + case 2: + listeners[i].fn.call(listeners[i].context, a1); + break; + case 3: + listeners[i].fn.call(listeners[i].context, a1, a2); + break; + case 4: + listeners[i].fn.call(listeners[i].context, a1, a2, a3); + break; + default: + if (!args) + for (j = 1, args = new Array(len - 1); j < len; j++) { + args[j - 1] = arguments[j]; + } - for (i = 0; i < length; i++) { - if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); + listeners[i].fn.apply(listeners[i].context, args); + } + } + } - switch (len) { - case 1: listeners[i].fn.call(listeners[i].context); break; - case 2: listeners[i].fn.call(listeners[i].context, a1); break; - case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; - case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; - default: - if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { - args[j - 1] = arguments[j]; - } + return true; + }; - listeners[i].fn.apply(listeners[i].context, args); - } - } - } + /** + * Add a listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.on = function on(event, fn, context) { + return addListener(this, event, fn, context, false); + }; - return true; -}; + /** + * Add a one-time listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.once = function once(event, fn, context) { + return addListener(this, event, fn, context, true); + }; -/** - * Add a listener for a given event. - * - * @param {(String|Symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - * @public - */ -EventEmitter.prototype.on = function on(event, fn, context) { - return addListener(this, event, fn, context, false); -}; + /** + * Remove the listeners of a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {Boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; -/** - * Add a one-time listener for a given event. - * - * @param {(String|Symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - * @public - */ -EventEmitter.prototype.once = function once(event, fn, context) { - return addListener(this, event, fn, context, true); -}; + if (!this._events[evt]) return this; + if (!fn) { + clearEvent(this, evt); + return this; + } -/** - * Remove the listeners of a given event. - * - * @param {(String|Symbol)} event The event name. - * @param {Function} fn Only remove the listeners that match this function. - * @param {*} context Only remove the listeners that have this context. - * @param {Boolean} once Only remove one-time listeners. - * @returns {EventEmitter} `this`. - * @public - */ -EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { - var evt = prefix ? prefix + event : event; + var listeners = this._events[evt]; - if (!this._events[evt]) return this; - if (!fn) { - clearEvent(this, evt); - return this; - } + if (listeners.fn) { + if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) { + clearEvent(this, evt); + } + } else { + for (var i = 0, events = [], length = listeners.length; i < length; i++) { + if (listeners[i].fn !== fn || (once && !listeners[i].once) || (context && listeners[i].context !== context)) { + events.push(listeners[i]); + } + } - var listeners = this._events[evt]; + // + // Reset the array, or remove it completely if we have no more listeners. + // + if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; + else clearEvent(this, evt); + } - if (listeners.fn) { - if ( - listeners.fn === fn && - (!once || listeners.once) && - (!context || listeners.context === context) - ) { - clearEvent(this, evt); - } - } else { - for (var i = 0, events = [], length = listeners.length; i < length; i++) { - if ( - listeners[i].fn !== fn || - (once && !listeners[i].once) || - (context && listeners[i].context !== context) - ) { - events.push(listeners[i]); - } - } + return this; + }; - // - // Reset the array, or remove it completely if we have no more listeners. - // - if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; - else clearEvent(this, evt); - } + /** + * Remove all listeners, or those of the specified event. + * + * @param {(String|Symbol)} [event] The event name. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { + var evt; - return this; -}; + if (event) { + evt = prefix ? prefix + event : event; + if (this._events[evt]) clearEvent(this, evt); + } else { + this._events = new Events(); + this._eventsCount = 0; + } -/** - * Remove all listeners, or those of the specified event. - * - * @param {(String|Symbol)} [event] The event name. - * @returns {EventEmitter} `this`. - * @public - */ -EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { - var evt; + return this; + }; - if (event) { - evt = prefix ? prefix + event : event; - if (this._events[evt]) clearEvent(this, evt); - } else { - this._events = new Events(); - this._eventsCount = 0; - } + // + // Alias methods names because people roll like that. + // + EventEmitter.prototype.off = EventEmitter.prototype.removeListener; + EventEmitter.prototype.addListener = EventEmitter.prototype.on; - return this; -}; + // + // Expose the prefix. + // + EventEmitter.prefixed = prefix; -// -// Alias methods names because people roll like that. -// -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; -EventEmitter.prototype.addListener = EventEmitter.prototype.on; + // + // Allow `EventEmitter` to be imported as module namespace. + // + EventEmitter.EventEmitter = EventEmitter; -// -// Expose the prefix. -// -EventEmitter.prefixed = prefix; + // + // Expose the module. + // + if (true) { + module.exports = EventEmitter; + } -// -// Allow `EventEmitter` to be imported as module namespace. -// -EventEmitter.EventEmitter = EventEmitter; + /***/ + }, -// -// Expose the module. -// -if (true) { - module.exports = EventEmitter; -} - - -/***/ }), - -/***/ "./node_modules/url-toolkit/src/url-toolkit.js": -/*!*****************************************************!*\ + /***/ "./node_modules/url-toolkit/src/url-toolkit.js": + /*!*****************************************************!*\ !*** ./node_modules/url-toolkit/src/url-toolkit.js ***! \*****************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { + /*! no static exports found */ + /***/ function (module, exports, __webpack_require__) { + // see https://tools.ietf.org/html/rfc1808 -// see https://tools.ietf.org/html/rfc1808 + (function (root) { + var URL_REGEX = /^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/?#]*\/)*[^;?#]*)?(;[^?#]*)?(\?[^#]*)?(#[^]*)?$/; + var FIRST_SEGMENT_REGEX = /^([^\/?#]*)([^]*)$/; + var SLASH_DOT_REGEX = /(?:\/|^)\.(?=\/)/g; + var SLASH_DOT_DOT_REGEX = /(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g; -(function (root) { - var URL_REGEX = - /^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/?#]*\/)*[^;?#]*)?(;[^?#]*)?(\?[^#]*)?(#[^]*)?$/; - var FIRST_SEGMENT_REGEX = /^([^\/?#]*)([^]*)$/; - var SLASH_DOT_REGEX = /(?:\/|^)\.(?=\/)/g; - var SLASH_DOT_DOT_REGEX = /(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g; + var URLToolkit = { + // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or // + // E.g + // With opts.alwaysNormalize = false (default, spec compliant) + // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g + // With opts.alwaysNormalize = true (not spec compliant) + // http://a.com/b/cd + /e/f/../g => http://a.com/e/g + buildAbsoluteURL: function (baseURL, relativeURL, opts) { + opts = opts || {}; + // remove any remaining space and CRLF + baseURL = baseURL.trim(); + relativeURL = relativeURL.trim(); + if (!relativeURL) { + // 2a) If the embedded URL is entirely empty, it inherits the + // entire base URL (i.e., is set equal to the base URL) + // and we are done. + if (!opts.alwaysNormalize) { + return baseURL; + } + var basePartsForNormalise = URLToolkit.parseURL(baseURL); + if (!basePartsForNormalise) { + throw new Error("Error trying to parse base URL."); + } + basePartsForNormalise.path = URLToolkit.normalizePath(basePartsForNormalise.path); + return URLToolkit.buildURLFromParts(basePartsForNormalise); + } + var relativeParts = URLToolkit.parseURL(relativeURL); + if (!relativeParts) { + throw new Error("Error trying to parse relative URL."); + } + if (relativeParts.scheme) { + // 2b) If the embedded URL starts with a scheme name, it is + // interpreted as an absolute URL and we are done. + if (!opts.alwaysNormalize) { + return relativeURL; + } + relativeParts.path = URLToolkit.normalizePath(relativeParts.path); + return URLToolkit.buildURLFromParts(relativeParts); + } + var baseParts = URLToolkit.parseURL(baseURL); + if (!baseParts) { + throw new Error("Error trying to parse base URL."); + } + if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== "/") { + // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc + // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a' + var pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path); + baseParts.netLoc = pathParts[1]; + baseParts.path = pathParts[2]; + } + if (baseParts.netLoc && !baseParts.path) { + baseParts.path = "/"; + } + var builtParts = { + // 2c) Otherwise, the embedded URL inherits the scheme of + // the base URL. + scheme: baseParts.scheme, + netLoc: relativeParts.netLoc, + path: null, + params: relativeParts.params, + query: relativeParts.query, + fragment: relativeParts.fragment, + }; + if (!relativeParts.netLoc) { + // 3) If the embedded URL's is non-empty, we skip to + // Step 7. Otherwise, the embedded URL inherits the + // (if any) of the base URL. + builtParts.netLoc = baseParts.netLoc; + // 4) If the embedded URL path is preceded by a slash "/", the + // path is not relative and we skip to Step 7. + if (relativeParts.path[0] !== "/") { + if (!relativeParts.path) { + // 5) If the embedded URL path is empty (and not preceded by a + // slash), then the embedded URL inherits the base URL path + builtParts.path = baseParts.path; + // 5a) if the embedded URL's is non-empty, we skip to + // step 7; otherwise, it inherits the of the base + // URL (if any) and + if (!relativeParts.params) { + builtParts.params = baseParts.params; + // 5b) if the embedded URL's is non-empty, we skip to + // step 7; otherwise, it inherits the of the base + // URL (if any) and we skip to step 7. + if (!relativeParts.query) { + builtParts.query = baseParts.query; + } + } + } else { + // 6) The last segment of the base URL's path (anything + // following the rightmost slash "/", or the entire path if no + // slash is present) is removed and the embedded URL's path is + // appended in its place. + var baseURLPath = baseParts.path; + var newPath = baseURLPath.substring(0, baseURLPath.lastIndexOf("/") + 1) + relativeParts.path; + builtParts.path = URLToolkit.normalizePath(newPath); + } + } + } + if (builtParts.path === null) { + builtParts.path = opts.alwaysNormalize ? URLToolkit.normalizePath(relativeParts.path) : relativeParts.path; + } + return URLToolkit.buildURLFromParts(builtParts); + }, + parseURL: function (url) { + var parts = URL_REGEX.exec(url); + if (!parts) { + return null; + } + return { + scheme: parts[1] || "", + netLoc: parts[2] || "", + path: parts[3] || "", + params: parts[4] || "", + query: parts[5] || "", + fragment: parts[6] || "", + }; + }, + normalizePath: function (path) { + // The following operations are + // then applied, in order, to the new path: + // 6a) All occurrences of "./", where "." is a complete path + // segment, are removed. + // 6b) If the path ends with "." as a complete path segment, + // that "." is removed. + path = path.split("").reverse().join("").replace(SLASH_DOT_REGEX, ""); + // 6c) All occurrences of "/../", where is a + // complete path segment not equal to "..", are removed. + // Removal of these path segments is performed iteratively, + // removing the leftmost matching pattern on each iteration, + // until no matching pattern remains. + // 6d) If the path ends with "/..", where is a + // complete path segment not equal to "..", that + // "/.." is removed. + while (path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, "")).length) {} + return path.split("").reverse().join(""); + }, + buildURLFromParts: function (parts) { + return parts.scheme + parts.netLoc + parts.path + parts.params + parts.query + parts.fragment; + }, + }; - var URLToolkit = { - // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or // - // E.g - // With opts.alwaysNormalize = false (default, spec compliant) - // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g - // With opts.alwaysNormalize = true (not spec compliant) - // http://a.com/b/cd + /e/f/../g => http://a.com/e/g - buildAbsoluteURL: function (baseURL, relativeURL, opts) { - opts = opts || {}; - // remove any remaining space and CRLF - baseURL = baseURL.trim(); - relativeURL = relativeURL.trim(); - if (!relativeURL) { - // 2a) If the embedded URL is entirely empty, it inherits the - // entire base URL (i.e., is set equal to the base URL) - // and we are done. - if (!opts.alwaysNormalize) { - return baseURL; - } - var basePartsForNormalise = URLToolkit.parseURL(baseURL); - if (!basePartsForNormalise) { - throw new Error('Error trying to parse base URL.'); - } - basePartsForNormalise.path = URLToolkit.normalizePath( - basePartsForNormalise.path - ); - return URLToolkit.buildURLFromParts(basePartsForNormalise); - } - var relativeParts = URLToolkit.parseURL(relativeURL); - if (!relativeParts) { - throw new Error('Error trying to parse relative URL.'); - } - if (relativeParts.scheme) { - // 2b) If the embedded URL starts with a scheme name, it is - // interpreted as an absolute URL and we are done. - if (!opts.alwaysNormalize) { - return relativeURL; - } - relativeParts.path = URLToolkit.normalizePath(relativeParts.path); - return URLToolkit.buildURLFromParts(relativeParts); - } - var baseParts = URLToolkit.parseURL(baseURL); - if (!baseParts) { - throw new Error('Error trying to parse base URL.'); - } - if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== '/') { - // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc - // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a' - var pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path); - baseParts.netLoc = pathParts[1]; - baseParts.path = pathParts[2]; - } - if (baseParts.netLoc && !baseParts.path) { - baseParts.path = '/'; - } - var builtParts = { - // 2c) Otherwise, the embedded URL inherits the scheme of - // the base URL. - scheme: baseParts.scheme, - netLoc: relativeParts.netLoc, - path: null, - params: relativeParts.params, - query: relativeParts.query, - fragment: relativeParts.fragment, - }; - if (!relativeParts.netLoc) { - // 3) If the embedded URL's is non-empty, we skip to - // Step 7. Otherwise, the embedded URL inherits the - // (if any) of the base URL. - builtParts.netLoc = baseParts.netLoc; - // 4) If the embedded URL path is preceded by a slash "/", the - // path is not relative and we skip to Step 7. - if (relativeParts.path[0] !== '/') { - if (!relativeParts.path) { - // 5) If the embedded URL path is empty (and not preceded by a - // slash), then the embedded URL inherits the base URL path - builtParts.path = baseParts.path; - // 5a) if the embedded URL's is non-empty, we skip to - // step 7; otherwise, it inherits the of the base - // URL (if any) and - if (!relativeParts.params) { - builtParts.params = baseParts.params; - // 5b) if the embedded URL's is non-empty, we skip to - // step 7; otherwise, it inherits the of the base - // URL (if any) and we skip to step 7. - if (!relativeParts.query) { - builtParts.query = baseParts.query; + if (true) module.exports = URLToolkit; + else { } - } - } else { - // 6) The last segment of the base URL's path (anything - // following the rightmost slash "/", or the entire path if no - // slash is present) is removed and the embedded URL's path is - // appended in its place. - var baseURLPath = baseParts.path; - var newPath = - baseURLPath.substring(0, baseURLPath.lastIndexOf('/') + 1) + - relativeParts.path; - builtParts.path = URLToolkit.normalizePath(newPath); - } - } - } - if (builtParts.path === null) { - builtParts.path = opts.alwaysNormalize - ? URLToolkit.normalizePath(relativeParts.path) - : relativeParts.path; - } - return URLToolkit.buildURLFromParts(builtParts); - }, - parseURL: function (url) { - var parts = URL_REGEX.exec(url); - if (!parts) { - return null; - } - return { - scheme: parts[1] || '', - netLoc: parts[2] || '', - path: parts[3] || '', - params: parts[4] || '', - query: parts[5] || '', - fragment: parts[6] || '', - }; - }, - normalizePath: function (path) { - // The following operations are - // then applied, in order, to the new path: - // 6a) All occurrences of "./", where "." is a complete path - // segment, are removed. - // 6b) If the path ends with "." as a complete path segment, - // that "." is removed. - path = path.split('').reverse().join('').replace(SLASH_DOT_REGEX, ''); - // 6c) All occurrences of "/../", where is a - // complete path segment not equal to "..", are removed. - // Removal of these path segments is performed iteratively, - // removing the leftmost matching pattern on each iteration, - // until no matching pattern remains. - // 6d) If the path ends with "/..", where is a - // complete path segment not equal to "..", that - // "/.." is removed. - while ( - path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, '')).length - ) {} - return path.split('').reverse().join(''); - }, - buildURLFromParts: function (parts) { - return ( - parts.scheme + - parts.netLoc + - parts.path + - parts.params + - parts.query + - parts.fragment - ); - }, - }; + })(this); - if (true) - module.exports = URLToolkit; - else {} -})(this); + /***/ + }, - -/***/ }), - -/***/ "./node_modules/webworkify-webpack/index.js": -/*!**************************************************!*\ + /***/ "./node_modules/webworkify-webpack/index.js": + /*!**************************************************!*\ !*** ./node_modules/webworkify-webpack/index.js ***! \**************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { + /*! no static exports found */ + /***/ function (module, exports, __webpack_require__) { + function webpackBootstrapFunc(modules) { + /******/ // The module cache + /******/ var installedModules = {}; -function webpackBootstrapFunc (modules) { -/******/ // The module cache -/******/ var installedModules = {}; + /******/ // The require function + /******/ function __webpack_require__(moduleId) { + /******/ // Check if module is in cache + /******/ if (installedModules[moduleId]) /******/ return installedModules[moduleId].exports; -/******/ // The require function -/******/ function __webpack_require__(moduleId) { + /******/ // Create a new module (and put it into the cache) + /******/ var module = (installedModules[moduleId] = { + /******/ i: moduleId, + /******/ l: false, + /******/ exports: {}, + /******/ + }); -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; + /******/ // Execute the module function + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; + /******/ // Flag the module as loaded + /******/ module.l = true; -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ + } -/******/ // Flag the module as loaded -/******/ module.l = true; + /******/ // expose the modules object (__webpack_modules__) + /******/ __webpack_require__.m = modules; -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } + /******/ // expose the module cache + /******/ __webpack_require__.c = installedModules; -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; + /******/ // identity function for calling harmony imports with the correct context + /******/ __webpack_require__.i = function (value) { + return value; + }; -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; + /******/ // define getter function for harmony exports + /******/ __webpack_require__.d = function (exports, name, getter) { + /******/ if (!__webpack_require__.o(exports, name)) { + /******/ Object.defineProperty(exports, name, { + /******/ configurable: false, + /******/ enumerable: true, + /******/ get: getter, + /******/ + }); + /******/ + } + /******/ + }; -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; + /******/ // define __esModule on exports + /******/ __webpack_require__.r = function (exports) { + /******/ Object.defineProperty(exports, "__esModule", { + value: true, + }); + /******/ + }; -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; + /******/ // getDefaultExport function for compatibility with non-harmony modules + /******/ __webpack_require__.n = function (module) { + /******/ var getter = + module && module.__esModule + ? /******/ function getDefault() { + return module["default"]; + } + : /******/ function getModuleExports() { + return module; + }; + /******/ __webpack_require__.d(getter, "a", getter); + /******/ return getter; + /******/ + }; -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; + /******/ // Object.prototype.hasOwnProperty.call + /******/ __webpack_require__.o = function (object, property) { + return Object.prototype.hasOwnProperty.call(object, property); + }; -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; + /******/ // __webpack_public_path__ + /******/ __webpack_require__.p = "/"; -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + /******/ // on error function for async loading + /******/ __webpack_require__.oe = function (err) { + console.error(err); + throw err; + }; -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = "/"; + var f = __webpack_require__((__webpack_require__.s = ENTRY_MODULE)); + return f.default || f; // try to call default if defined to also support babel esmodule exports + } -/******/ // on error function for async loading -/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; + var moduleNameReqExp = "[\\.|\\-|\\+|\\w|/|@]+"; + var dependencyRegExp = "\\(\\s*(/\\*.*?\\*/)?\\s*.*?(" + moduleNameReqExp + ").*?\\)"; // additional chars when output.pathinfo is true - var f = __webpack_require__(__webpack_require__.s = ENTRY_MODULE) - return f.default || f // try to call default if defined to also support babel esmodule exports -} + // http://stackoverflow.com/a/2593661/130442 + function quoteRegExp(str) { + return (str + "").replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); + } -var moduleNameReqExp = '[\\.|\\-|\\+|\\w|\/|@]+' -var dependencyRegExp = '\\(\\s*(\/\\*.*?\\*\/)?\\s*.*?(' + moduleNameReqExp + ').*?\\)' // additional chars when output.pathinfo is true + function isNumeric(n) { + return !isNaN(1 * n); // 1 * n converts integers, integers as string ("123"), 1e3 and "1e3" to integers and strings to NaN + } -// http://stackoverflow.com/a/2593661/130442 -function quoteRegExp (str) { - return (str + '').replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&') -} + function getModuleDependencies(sources, module, queueName) { + var retval = {}; + retval[queueName] = []; -function isNumeric(n) { - return !isNaN(1 * n); // 1 * n converts integers, integers as string ("123"), 1e3 and "1e3" to integers and strings to NaN -} + var fnString = module.toString(); + var wrapperSignature = fnString.match(/^function\s?\w*\(\w+,\s*\w+,\s*(\w+)\)/); + if (!wrapperSignature) return retval; + var webpackRequireName = wrapperSignature[1]; -function getModuleDependencies (sources, module, queueName) { - var retval = {} - retval[queueName] = [] + // main bundle deps + var re = new RegExp("(\\\\n|\\W)" + quoteRegExp(webpackRequireName) + dependencyRegExp, "g"); + var match; + while ((match = re.exec(fnString))) { + if (match[3] === "dll-reference") continue; + retval[queueName].push(match[3]); + } - var fnString = module.toString() - var wrapperSignature = fnString.match(/^function\s?\w*\(\w+,\s*\w+,\s*(\w+)\)/) - if (!wrapperSignature) return retval - var webpackRequireName = wrapperSignature[1] + // dll deps + re = new RegExp("\\(" + quoteRegExp(webpackRequireName) + '\\("(dll-reference\\s(' + moduleNameReqExp + '))"\\)\\)' + dependencyRegExp, "g"); + while ((match = re.exec(fnString))) { + if (!sources[match[2]]) { + retval[queueName].push(match[1]); + sources[match[2]] = __webpack_require__(match[1]).m; + } + retval[match[2]] = retval[match[2]] || []; + retval[match[2]].push(match[4]); + } - // main bundle deps - var re = new RegExp('(\\\\n|\\W)' + quoteRegExp(webpackRequireName) + dependencyRegExp, 'g') - var match - while ((match = re.exec(fnString))) { - if (match[3] === 'dll-reference') continue - retval[queueName].push(match[3]) - } + // convert 1e3 back to 1000 - this can be important after uglify-js converted 1000 to 1e3 + var keys = Object.keys(retval); + for (var i = 0; i < keys.length; i++) { + for (var j = 0; j < retval[keys[i]].length; j++) { + if (isNumeric(retval[keys[i]][j])) { + retval[keys[i]][j] = 1 * retval[keys[i]][j]; + } + } + } - // dll deps - re = new RegExp('\\(' + quoteRegExp(webpackRequireName) + '\\("(dll-reference\\s(' + moduleNameReqExp + '))"\\)\\)' + dependencyRegExp, 'g') - while ((match = re.exec(fnString))) { - if (!sources[match[2]]) { - retval[queueName].push(match[1]) - sources[match[2]] = __webpack_require__(match[1]).m - } - retval[match[2]] = retval[match[2]] || [] - retval[match[2]].push(match[4]) - } + return retval; + } - // convert 1e3 back to 1000 - this can be important after uglify-js converted 1000 to 1e3 - var keys = Object.keys(retval); - for (var i = 0; i < keys.length; i++) { - for (var j = 0; j < retval[keys[i]].length; j++) { - if (isNumeric(retval[keys[i]][j])) { - retval[keys[i]][j] = 1 * retval[keys[i]][j]; - } - } - } + function hasValuesInQueues(queues) { + var keys = Object.keys(queues); + return keys.reduce(function (hasValues, key) { + return hasValues || queues[key].length > 0; + }, false); + } - return retval -} + function getRequiredModules(sources, moduleId) { + var modulesQueue = { + main: [moduleId], + }; + var requiredModules = { + main: [], + }; + var seenModules = { + main: {}, + }; -function hasValuesInQueues (queues) { - var keys = Object.keys(queues) - return keys.reduce(function (hasValues, key) { - return hasValues || queues[key].length > 0 - }, false) -} + while (hasValuesInQueues(modulesQueue)) { + var queues = Object.keys(modulesQueue); + for (var i = 0; i < queues.length; i++) { + var queueName = queues[i]; + var queue = modulesQueue[queueName]; + var moduleToCheck = queue.pop(); + seenModules[queueName] = seenModules[queueName] || {}; + if (seenModules[queueName][moduleToCheck] || !sources[queueName][moduleToCheck]) continue; + seenModules[queueName][moduleToCheck] = true; + requiredModules[queueName] = requiredModules[queueName] || []; + requiredModules[queueName].push(moduleToCheck); + var newModules = getModuleDependencies(sources, sources[queueName][moduleToCheck], queueName); + var newModulesKeys = Object.keys(newModules); + for (var j = 0; j < newModulesKeys.length; j++) { + modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]] || []; + modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]]); + } + } + } -function getRequiredModules (sources, moduleId) { - var modulesQueue = { - main: [moduleId] - } - var requiredModules = { - main: [] - } - var seenModules = { - main: {} - } + return requiredModules; + } - while (hasValuesInQueues(modulesQueue)) { - var queues = Object.keys(modulesQueue) - for (var i = 0; i < queues.length; i++) { - var queueName = queues[i] - var queue = modulesQueue[queueName] - var moduleToCheck = queue.pop() - seenModules[queueName] = seenModules[queueName] || {} - if (seenModules[queueName][moduleToCheck] || !sources[queueName][moduleToCheck]) continue - seenModules[queueName][moduleToCheck] = true - requiredModules[queueName] = requiredModules[queueName] || [] - requiredModules[queueName].push(moduleToCheck) - var newModules = getModuleDependencies(sources, sources[queueName][moduleToCheck], queueName) - var newModulesKeys = Object.keys(newModules) - for (var j = 0; j < newModulesKeys.length; j++) { - modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]] || [] - modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]]) - } - } - } + module.exports = function (moduleId, options) { + options = options || {}; + var sources = { + main: __webpack_require__.m, + }; - return requiredModules -} + var requiredModules = options.all ? { main: Object.keys(sources.main) } : getRequiredModules(sources, moduleId); -module.exports = function (moduleId, options) { - options = options || {} - var sources = { - main: __webpack_require__.m - } + var src = ""; - var requiredModules = options.all ? { main: Object.keys(sources.main) } : getRequiredModules(sources, moduleId) + Object.keys(requiredModules) + .filter(function (m) { + return m !== "main"; + }) + .forEach(function (module) { + var entryModule = 0; + while (requiredModules[module][entryModule]) { + entryModule++; + } + requiredModules[module].push(entryModule); + sources[module][entryModule] = "(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })"; + src = + src + + "var " + + module + + " = (" + + webpackBootstrapFunc.toString().replace("ENTRY_MODULE", JSON.stringify(entryModule)) + + ")({" + + requiredModules[module] + .map(function (id) { + return "" + JSON.stringify(id) + ": " + sources[module][id].toString(); + }) + .join(",") + + "});\n"; + }); - var src = '' + src = + src + + "new ((" + + webpackBootstrapFunc.toString().replace("ENTRY_MODULE", JSON.stringify(moduleId)) + + ")({" + + requiredModules.main + .map(function (id) { + return "" + JSON.stringify(id) + ": " + sources.main[id].toString(); + }) + .join(",") + + "}))(self);"; - Object.keys(requiredModules).filter(function (m) { return m !== 'main' }).forEach(function (module) { - var entryModule = 0 - while (requiredModules[module][entryModule]) { - entryModule++ - } - requiredModules[module].push(entryModule) - sources[module][entryModule] = '(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })' - src = src + 'var ' + module + ' = (' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(entryModule)) + ')({' + requiredModules[module].map(function (id) { return '' + JSON.stringify(id) + ': ' + sources[module][id].toString() }).join(',') + '});\n' - }) + var blob = new window.Blob([src], { type: "text/javascript" }); + if (options.bare) { + return blob; + } - src = src + 'new ((' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(moduleId)) + ')({' + requiredModules.main.map(function (id) { return '' + JSON.stringify(id) + ': ' + sources.main[id].toString() }).join(',') + '}))(self);' + var URL = window.URL || window.webkitURL || window.mozURL || window.msURL; - var blob = new window.Blob([src], { type: 'text/javascript' }) - if (options.bare) { return blob } + var workerUrl = URL.createObjectURL(blob); + var worker = new window.Worker(workerUrl); + worker.objectURL = workerUrl; - var URL = window.URL || window.webkitURL || window.mozURL || window.msURL + return worker; + }; - var workerUrl = URL.createObjectURL(blob) - var worker = new window.Worker(workerUrl) - worker.objectURL = workerUrl + /***/ + }, - return worker -} - - -/***/ }), - -/***/ "./src/config.ts": -/*!***********************!*\ + /***/ "./src/config.ts": + /*!***********************!*\ !*** ./src/config.ts ***! \***********************/ -/*! exports provided: CiderHlsDefaultConfig, mergeConfig, enableStreamingMode */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: CiderHlsDefaultConfig, mergeConfig, enableStreamingMode */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CiderHlsDefaultConfig", function () { + return CiderHlsDefaultConfig; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeConfig", function () { + return mergeConfig; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableStreamingMode", function () { + return enableStreamingMode; + }); + /* harmony import */ var _controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./controller/abr-controller */ "./src/controller/abr-controller.ts"); + /* harmony import */ var _controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controller/audio-stream-controller */ "./src/controller/audio-stream-controller.ts"); + /* harmony import */ var _controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controller/audio-track-controller */ "./src/controller/audio-track-controller.ts"); + /* harmony import */ var _controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controller/subtitle-stream-controller */ "./src/controller/subtitle-stream-controller.ts"); + /* harmony import */ var _controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controller/subtitle-track-controller */ "./src/controller/subtitle-track-controller.ts"); + /* harmony import */ var _controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./controller/buffer-controller */ "./src/controller/buffer-controller.ts"); + /* harmony import */ var _controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./controller/timeline-controller */ "./src/controller/timeline-controller.ts"); + /* harmony import */ var _controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./controller/cap-level-controller */ "./src/controller/cap-level-controller.ts"); + /* harmony import */ var _controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./controller/fps-controller */ "./src/controller/fps-controller.ts"); + /* harmony import */ var _controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./controller/eme-controller */ "./src/controller/eme-controller.ts"); + /* harmony import */ var _controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./controller/cmcd-controller */ "./src/controller/cmcd-controller.ts"); + /* harmony import */ var _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils/xhr-loader */ "./src/utils/xhr-loader.ts"); + /* harmony import */ var _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./utils/fetch-loader */ "./src/utils/fetch-loader.ts"); + /* harmony import */ var _utils_cues__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./utils/cues */ "./src/utils/cues.ts"); + /* harmony import */ var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./utils/mediakeys-helper */ "./src/utils/mediakeys-helper.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./utils/logger */ "./src/utils/logger.ts"); + function _extends() { + _extends = + Object.assign || + function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CiderHlsDefaultConfig", function() { return CiderHlsDefaultConfig; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeConfig", function() { return mergeConfig; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableStreamingMode", function() { return enableStreamingMode; }); -/* harmony import */ var _controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./controller/abr-controller */ "./src/controller/abr-controller.ts"); -/* harmony import */ var _controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controller/audio-stream-controller */ "./src/controller/audio-stream-controller.ts"); -/* harmony import */ var _controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controller/audio-track-controller */ "./src/controller/audio-track-controller.ts"); -/* harmony import */ var _controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controller/subtitle-stream-controller */ "./src/controller/subtitle-stream-controller.ts"); -/* harmony import */ var _controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controller/subtitle-track-controller */ "./src/controller/subtitle-track-controller.ts"); -/* harmony import */ var _controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./controller/buffer-controller */ "./src/controller/buffer-controller.ts"); -/* harmony import */ var _controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./controller/timeline-controller */ "./src/controller/timeline-controller.ts"); -/* harmony import */ var _controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./controller/cap-level-controller */ "./src/controller/cap-level-controller.ts"); -/* harmony import */ var _controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./controller/fps-controller */ "./src/controller/fps-controller.ts"); -/* harmony import */ var _controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./controller/eme-controller */ "./src/controller/eme-controller.ts"); -/* harmony import */ var _controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./controller/cmcd-controller */ "./src/controller/cmcd-controller.ts"); -/* harmony import */ var _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils/xhr-loader */ "./src/utils/xhr-loader.ts"); -/* harmony import */ var _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./utils/fetch-loader */ "./src/utils/fetch-loader.ts"); -/* harmony import */ var _utils_cues__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./utils/cues */ "./src/utils/cues.ts"); -/* harmony import */ var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./utils/mediakeys-helper */ "./src/utils/mediakeys-helper.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./utils/logger */ "./src/utils/logger.ts"); -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + if (enumerableOnly) { + symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + } + keys.push.apply(keys, symbols); + } + return keys; + } -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + if (i % 2) { + ownKeys(Object(source), true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + return target; + } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true, + }); + } else { + obj[key] = value; + } + return obj; + } -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + // If possible, keep CiderHlsDefaultConfig shallow + // It is cloned whenever a new CiderHls instance is created, by keeping the config + // shallow the properties are cloned, and we don't end up manipulating the default + var CiderHlsDefaultConfig = _objectSpread( + _objectSpread( + { + autoStartLoad: true, + // used by stream-controller + startPosition: -1, + // used by stream-controller + defaultAudioCodec: undefined, + // used by stream-controller + debug: false, + // used by logger + capLevelOnFPSDrop: false, + // used by fps-controller + capLevelToPlayerSize: false, + // used by cap-level-controller + initialLiveManifestSize: 1, + // used by stream-controller + maxBufferLength: 30, + // used by stream-controller + backBufferLength: Infinity, + // used by buffer-controller + maxBufferSize: 60 * 1000 * 1000, + // used by stream-controller + maxBufferHole: 0.1, + // used by stream-controller + highBufferWatchdogPeriod: 2, + // used by stream-controller + nudgeOffset: 0.1, + // used by stream-controller + nudgeMaxRetry: 3, + // used by stream-controller + maxFragLookUpTolerance: 0.25, + // used by stream-controller + liveSyncDurationCount: 3, + // used by latency-controller + liveMaxLatencyDurationCount: Infinity, + // used by latency-controller + liveSyncDuration: undefined, + // used by latency-controller + liveMaxLatencyDuration: undefined, + // used by latency-controller + maxLiveSyncPlaybackRate: 1, + // used by latency-controller + liveDurationInfinity: false, + // used by buffer-controller + liveBackBufferLength: null, + // used by buffer-controller + maxMaxBufferLength: 600, + // used by stream-controller + enableWorker: true, + // used by demuxer + enableSoftwareAES: true, + // used by decrypter + manifestLoadingTimeOut: 10000, + // used by playlist-loader + manifestLoadingMaxRetry: 1, + // used by playlist-loader + manifestLoadingRetryDelay: 1000, + // used by playlist-loader + manifestLoadingMaxRetryTimeout: 64000, + // used by playlist-loader + startLevel: undefined, + // used by level-controller + levelLoadingTimeOut: 10000, + // used by playlist-loader + levelLoadingMaxRetry: 4, + // used by playlist-loader + levelLoadingRetryDelay: 1000, + // used by playlist-loader + levelLoadingMaxRetryTimeout: 64000, + // used by playlist-loader + fragLoadingTimeOut: 20000, + // used by fragment-loader + fragLoadingMaxRetry: 6, + // used by fragment-loader + fragLoadingRetryDelay: 1000, + // used by fragment-loader + fragLoadingMaxRetryTimeout: 64000, + // used by fragment-loader + startFragPrefetch: false, + // used by stream-controller + fpsDroppedMonitoringPeriod: 5000, + // used by fps-controller + fpsDroppedMonitoringThreshold: 0.2, + // used by fps-controller + appendErrorMaxRetry: 3, + // used by buffer-controller + loader: _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"], + // loader: FetchLoader, + fLoader: undefined, + // used by fragment-loader + pLoader: undefined, + // used by playlist-loader + xhrSetup: undefined, + // used by xhr-loader + licenseXhrSetup: undefined, + // used by eme-controller + licenseResponseCallback: undefined, + // used by eme-controller + abrController: _controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__["default"], + bufferController: _controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__["default"], + capLevelController: _controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__["default"], + fpsController: _controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__["default"], + stretchShortVideoTrack: false, + // used by mp4-remuxer + maxAudioFramesDrift: 1, + // used by mp4-remuxer + forceKeyFrameOnDiscontinuity: true, + // used by ts-demuxer + abrEwmaFastLive: 3, + // used by abr-controller + abrEwmaSlowLive: 9, + // used by abr-controller + abrEwmaFastVoD: 3, + // used by abr-controller + abrEwmaSlowVoD: 9, + // used by abr-controller + abrEwmaDefaultEstimate: 5e5, + // 500 kbps // used by abr-controller + abrBandWidthFactor: 0.95, + // used by abr-controller + abrBandWidthUpFactor: 0.7, + // used by abr-controller + abrMaxWithRealBitrate: false, + // used by abr-controller + maxStarvationDelay: 4, + // used by abr-controller + maxLoadingDelay: 4, + // used by abr-controller + minAutoBitrate: 0, + // used by CiderHls + emeEnabled: false, + // used by eme-controller + widevineLicenseUrl: undefined, + // used by eme-controller + drmSystemOptions: {}, + // used by eme-controller + requestMediaKeySystemAccessFunc: _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__["requestMediaKeySystemAccess"], + // used by eme-controller + testBandwidth: true, + progressive: false, + lowLatencyMode: true, + cmcd: undefined, + }, + timelineConfig() + ), + {}, + { + subtitleStreamController: true ? _controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__["SubtitleStreamController"] : undefined, + subtitleTrackController: true ? _controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__["default"] : undefined, + timelineController: true ? _controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__["TimelineController"] : undefined, + audioStreamController: true ? _controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"] : undefined, + audioTrackController: true ? _controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__["default"] : undefined, + emeController: true ? _controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__["default"] : undefined, + cmcdController: true ? _controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__["default"] : undefined, + } + ); + function timelineConfig() { + return { + cueHandler: _utils_cues__WEBPACK_IMPORTED_MODULE_13__["default"], + // used by timeline-controller + enableCEA708Captions: true, + // used by timeline-controller + enableWebVTT: true, + // used by timeline-controller + enableIMSC1: true, + // used by timeline-controller + captionsTextTrack1Label: "English", + // used by timeline-controller + captionsTextTrack1LanguageCode: "en", + // used by timeline-controller + captionsTextTrack2Label: "Spanish", + // used by timeline-controller + captionsTextTrack2LanguageCode: "es", + // used by timeline-controller + captionsTextTrack3Label: "Unknown CC", + // used by timeline-controller + captionsTextTrack3LanguageCode: "", + // used by timeline-controller + captionsTextTrack4Label: "Unknown CC", + // used by timeline-controller + captionsTextTrack4LanguageCode: "", + // used by timeline-controller + renderTextTracksNatively: true, + }; + } + function mergeConfig(defaultConfig, userConfig) { + if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) { + throw new Error("Illegal CiderHls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration"); + } + if (userConfig.liveMaxLatencyDurationCount !== undefined && (userConfig.liveSyncDurationCount === undefined || userConfig.liveMaxLatencyDurationCount <= userConfig.liveSyncDurationCount)) { + throw new Error('Illegal CiderHls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"'); + } + if (userConfig.liveMaxLatencyDuration !== undefined && (userConfig.liveSyncDuration === undefined || userConfig.liveMaxLatencyDuration <= userConfig.liveSyncDuration)) { + throw new Error('Illegal CiderHls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"'); + } + return _extends({}, defaultConfig, userConfig); + } + function enableStreamingMode(config) { + var currentLoader = config.loader; + if (currentLoader !== _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"] && currentLoader !== _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"]) { + // If a developer has configured their own loader, respect that choice + _utils_logger__WEBPACK_IMPORTED_MODULE_15__["logger"].log("[config]: Custom loader detected, cannot enable progressive streaming"); + config.progressive = false; + } else { + var canStreamProgressively = Object(_utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["fetchSupported"])(); + if (canStreamProgressively) { + config.loader = _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"]; + config.progressive = true; + config.enableSoftwareAES = true; + _utils_logger__WEBPACK_IMPORTED_MODULE_15__["logger"].log("[config]: Progressive streaming enabled, using FetchLoader"); + } + } + } + /***/ + }, - - - - - - - - -// If possible, keep CiderHlsDefaultConfig shallow -// It is cloned whenever a new CiderHls instance is created, by keeping the config -// shallow the properties are cloned, and we don't end up manipulating the default -var CiderHlsDefaultConfig = _objectSpread(_objectSpread({ - autoStartLoad: true, - // used by stream-controller - startPosition: -1, - // used by stream-controller - defaultAudioCodec: undefined, - // used by stream-controller - debug: false, - // used by logger - capLevelOnFPSDrop: false, - // used by fps-controller - capLevelToPlayerSize: false, - // used by cap-level-controller - initialLiveManifestSize: 1, - // used by stream-controller - maxBufferLength: 30, - // used by stream-controller - backBufferLength: Infinity, - // used by buffer-controller - maxBufferSize: 60 * 1000 * 1000, - // used by stream-controller - maxBufferHole: 0.1, - // used by stream-controller - highBufferWatchdogPeriod: 2, - // used by stream-controller - nudgeOffset: 0.1, - // used by stream-controller - nudgeMaxRetry: 3, - // used by stream-controller - maxFragLookUpTolerance: 0.25, - // used by stream-controller - liveSyncDurationCount: 3, - // used by latency-controller - liveMaxLatencyDurationCount: Infinity, - // used by latency-controller - liveSyncDuration: undefined, - // used by latency-controller - liveMaxLatencyDuration: undefined, - // used by latency-controller - maxLiveSyncPlaybackRate: 1, - // used by latency-controller - liveDurationInfinity: false, - // used by buffer-controller - liveBackBufferLength: null, - // used by buffer-controller - maxMaxBufferLength: 600, - // used by stream-controller - enableWorker: true, - // used by demuxer - enableSoftwareAES: true, - // used by decrypter - manifestLoadingTimeOut: 10000, - // used by playlist-loader - manifestLoadingMaxRetry: 1, - // used by playlist-loader - manifestLoadingRetryDelay: 1000, - // used by playlist-loader - manifestLoadingMaxRetryTimeout: 64000, - // used by playlist-loader - startLevel: undefined, - // used by level-controller - levelLoadingTimeOut: 10000, - // used by playlist-loader - levelLoadingMaxRetry: 4, - // used by playlist-loader - levelLoadingRetryDelay: 1000, - // used by playlist-loader - levelLoadingMaxRetryTimeout: 64000, - // used by playlist-loader - fragLoadingTimeOut: 20000, - // used by fragment-loader - fragLoadingMaxRetry: 6, - // used by fragment-loader - fragLoadingRetryDelay: 1000, - // used by fragment-loader - fragLoadingMaxRetryTimeout: 64000, - // used by fragment-loader - startFragPrefetch: false, - // used by stream-controller - fpsDroppedMonitoringPeriod: 5000, - // used by fps-controller - fpsDroppedMonitoringThreshold: 0.2, - // used by fps-controller - appendErrorMaxRetry: 3, - // used by buffer-controller - loader: _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"], - // loader: FetchLoader, - fLoader: undefined, - // used by fragment-loader - pLoader: undefined, - // used by playlist-loader - xhrSetup: undefined, - // used by xhr-loader - licenseXhrSetup: undefined, - // used by eme-controller - licenseResponseCallback: undefined, - // used by eme-controller - abrController: _controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__["default"], - bufferController: _controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__["default"], - capLevelController: _controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__["default"], - fpsController: _controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__["default"], - stretchShortVideoTrack: false, - // used by mp4-remuxer - maxAudioFramesDrift: 1, - // used by mp4-remuxer - forceKeyFrameOnDiscontinuity: true, - // used by ts-demuxer - abrEwmaFastLive: 3, - // used by abr-controller - abrEwmaSlowLive: 9, - // used by abr-controller - abrEwmaFastVoD: 3, - // used by abr-controller - abrEwmaSlowVoD: 9, - // used by abr-controller - abrEwmaDefaultEstimate: 5e5, - // 500 kbps // used by abr-controller - abrBandWidthFactor: 0.95, - // used by abr-controller - abrBandWidthUpFactor: 0.7, - // used by abr-controller - abrMaxWithRealBitrate: false, - // used by abr-controller - maxStarvationDelay: 4, - // used by abr-controller - maxLoadingDelay: 4, - // used by abr-controller - minAutoBitrate: 0, - // used by CiderHls - emeEnabled: false, - // used by eme-controller - widevineLicenseUrl: undefined, - // used by eme-controller - drmSystemOptions: {}, - // used by eme-controller - requestMediaKeySystemAccessFunc: _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__["requestMediaKeySystemAccess"], - // used by eme-controller - testBandwidth: true, - progressive: false, - lowLatencyMode: true, - cmcd: undefined -}, timelineConfig()), {}, { - subtitleStreamController: true ? _controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__["SubtitleStreamController"] : undefined, - subtitleTrackController: true ? _controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__["default"] : undefined, - timelineController: true ? _controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__["TimelineController"] : undefined, - audioStreamController: true ? _controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"] : undefined, - audioTrackController: true ? _controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__["default"] : undefined, - emeController: true ? _controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__["default"] : undefined, - cmcdController: true ? _controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__["default"] : undefined -}); - -function timelineConfig() { - return { - cueHandler: _utils_cues__WEBPACK_IMPORTED_MODULE_13__["default"], - // used by timeline-controller - enableCEA708Captions: true, - // used by timeline-controller - enableWebVTT: true, - // used by timeline-controller - enableIMSC1: true, - // used by timeline-controller - captionsTextTrack1Label: 'English', - // used by timeline-controller - captionsTextTrack1LanguageCode: 'en', - // used by timeline-controller - captionsTextTrack2Label: 'Spanish', - // used by timeline-controller - captionsTextTrack2LanguageCode: 'es', - // used by timeline-controller - captionsTextTrack3Label: 'Unknown CC', - // used by timeline-controller - captionsTextTrack3LanguageCode: '', - // used by timeline-controller - captionsTextTrack4Label: 'Unknown CC', - // used by timeline-controller - captionsTextTrack4LanguageCode: '', - // used by timeline-controller - renderTextTracksNatively: true - }; -} - -function mergeConfig(defaultConfig, userConfig) { - if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) { - throw new Error("Illegal CiderHls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration"); - } - - if (userConfig.liveMaxLatencyDurationCount !== undefined && (userConfig.liveSyncDurationCount === undefined || userConfig.liveMaxLatencyDurationCount <= userConfig.liveSyncDurationCount)) { - throw new Error('Illegal CiderHls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"'); - } - - if (userConfig.liveMaxLatencyDuration !== undefined && (userConfig.liveSyncDuration === undefined || userConfig.liveMaxLatencyDuration <= userConfig.liveSyncDuration)) { - throw new Error('Illegal CiderHls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"'); - } - - return _extends({}, defaultConfig, userConfig); -} -function enableStreamingMode(config) { - var currentLoader = config.loader; - - if (currentLoader !== _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"] && currentLoader !== _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"]) { - // If a developer has configured their own loader, respect that choice - _utils_logger__WEBPACK_IMPORTED_MODULE_15__["logger"].log('[config]: Custom loader detected, cannot enable progressive streaming'); - config.progressive = false; - } else { - var canStreamProgressively = Object(_utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["fetchSupported"])(); - - if (canStreamProgressively) { - config.loader = _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"]; - config.progressive = true; - config.enableSoftwareAES = true; - _utils_logger__WEBPACK_IMPORTED_MODULE_15__["logger"].log('[config]: Progressive streaming enabled, using FetchLoader'); - } - } -} - -/***/ }), - -/***/ "./src/controller/abr-controller.ts": -/*!******************************************!*\ + /***/ "./src/controller/abr-controller.ts": + /*!******************************************!*\ !*** ./src/controller/abr-controller.ts ***! \******************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/ewma-bandwidth-estimator */ "./src/utils/ewma-bandwidth-estimator.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/ewma-bandwidth-estimator */ "./src/utils/ewma-bandwidth-estimator.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + var AbrController = /*#__PURE__*/ (function () { + function AbrController(CiderHls) { + this.CiderHls = void 0; + this.lastLoadedFragLevel = 0; + this._nextAutoLevel = -1; + this.timer = void 0; + this.onCheck = this._abandonRulesCheck.bind(this); + this.fragCurrent = null; + this.partCurrent = null; + this.bitrateTestDelay = 0; + this.bwEstimator = void 0; + this.CiderHls = CiderHls; + var config = CiderHls.config; + this.bwEstimator = new _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__["default"](config.abrEwmaSlowVoD, config.abrEwmaFastVoD, config.abrEwmaDefaultEstimate); + this.registerListeners(); + } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + var _proto = AbrController.prototype; -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + _proto.registerListeners = function registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADING, this.onFragLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADED, this.onFragLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); + }; + _proto.unregisterListeners = function unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADING, this.onFragLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADED, this.onFragLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); + }; + _proto.destroy = function destroy() { + this.unregisterListeners(); + this.clearTimer(); // @ts-ignore + this.CiderHls = this.onCheck = null; + this.fragCurrent = this.partCurrent = null; + }; + _proto.onFragLoading = function onFragLoading(event, data) { + var frag = data.frag; + if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__["PlaylistLevelType"].MAIN) { + if (!this.timer) { + var _data$part; + this.fragCurrent = frag; + this.partCurrent = (_data$part = data.part) != null ? _data$part : null; + this.timer = self.setInterval(this.onCheck, 100); + } + } + }; + _proto.onLevelLoaded = function onLevelLoaded(event, data) { + var config = this.CiderHls.config; -var AbrController = /*#__PURE__*/function () { - function AbrController(CiderHls) { - this.CiderHls = void 0; - this.lastLoadedFragLevel = 0; - this._nextAutoLevel = -1; - this.timer = void 0; - this.onCheck = this._abandonRulesCheck.bind(this); - this.fragCurrent = null; - this.partCurrent = null; - this.bitrateTestDelay = 0; - this.bwEstimator = void 0; - this.CiderHls = CiderHls; - var config = CiderHls.config; - this.bwEstimator = new _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__["default"](config.abrEwmaSlowVoD, config.abrEwmaFastVoD, config.abrEwmaDefaultEstimate); - this.registerListeners(); - } - - var _proto = AbrController.prototype; - - _proto.registerListeners = function registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADING, this.onFragLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADED, this.onFragLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); - }; - - _proto.unregisterListeners = function unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADING, this.onFragLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOADED, this.onFragLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); - }; - - _proto.destroy = function destroy() { - this.unregisterListeners(); - this.clearTimer(); // @ts-ignore - - this.CiderHls = this.onCheck = null; - this.fragCurrent = this.partCurrent = null; - }; - - _proto.onFragLoading = function onFragLoading(event, data) { - var frag = data.frag; - - if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__["PlaylistLevelType"].MAIN) { - if (!this.timer) { - var _data$part; - - this.fragCurrent = frag; - this.partCurrent = (_data$part = data.part) != null ? _data$part : null; - this.timer = self.setInterval(this.onCheck, 100); - } - } - }; - - _proto.onLevelLoaded = function onLevelLoaded(event, data) { - var config = this.CiderHls.config; - - if (data.details.live) { - this.bwEstimator.update(config.abrEwmaSlowLive, config.abrEwmaFastLive); - } else { - this.bwEstimator.update(config.abrEwmaSlowVoD, config.abrEwmaFastVoD); - } - } - /* + if (data.details.live) { + this.bwEstimator.update(config.abrEwmaSlowLive, config.abrEwmaFastLive); + } else { + this.bwEstimator.update(config.abrEwmaSlowVoD, config.abrEwmaFastVoD); + } + }; + /* This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load quickly enough to prevent underbuffering */ - ; - _proto._abandonRulesCheck = function _abandonRulesCheck() { - var frag = this.fragCurrent, - part = this.partCurrent, - CiderHls = this.CiderHls; - var autoLevelEnabled = CiderHls.autoLevelEnabled, - config = CiderHls.config, - media = CiderHls.media; - - if (!frag || !media) { - return; - } - - var stats = part ? part.stats : frag.stats; - var duration = part ? part.duration : frag.duration; // If loading has been aborted and not in lowLatencyMode, stop timer and return - - if (stats.aborted) { - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn('frag loader destroy or aborted, disarm abandonRules'); - this.clearTimer(); // reset forced auto level value so that next level will be selected - - this._nextAutoLevel = -1; - return; - } // This check only runs if we're in ABR mode and actually playing - - - if (!autoLevelEnabled || media.paused || !media.playbackRate || !media.readyState) { - return; - } - - var requestDelay = performance.now() - stats.loading.start; - var playbackRate = Math.abs(media.playbackRate); // In order to work with a stable bandwidth, only begin monitoring bandwidth after half of the fragment has been loaded - - if (requestDelay <= 500 * duration / playbackRate) { - return; - } - - var levels = CiderHls.levels, - minAutoLevel = CiderHls.minAutoLevel; - var level = levels[frag.level]; - var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.maxBitrate / 8)); - var loadRate = Math.max(1, stats.bwEstimate ? stats.bwEstimate / 8 : stats.loaded * 1000 / requestDelay); // fragLoadDelay is an estimate of the time (in seconds) it will take to buffer the entire fragment - - var fragLoadedDelay = (expectedLen - stats.loaded) / loadRate; - var pos = media.currentTime; // bufferStarvationDelay is an estimate of the amount time (in seconds) it will take to exhaust the buffer - - var bufferStarvationDelay = (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(media, pos, config.maxBufferHole).end - pos) / playbackRate; // Attempt an emergency downswitch only if less than 2 fragment lengths are buffered, and the time to finish loading - // the current fragment is greater than the amount of buffer we have left - - if (bufferStarvationDelay >= 2 * duration / playbackRate || fragLoadedDelay <= bufferStarvationDelay) { - return; - } - - var fragLevelNextLoadedDelay = Number.POSITIVE_INFINITY; - var nextLoadLevel; // Iterate through lower level and try to find the largest one that avoids rebuffering - - for (nextLoadLevel = frag.level - 1; nextLoadLevel > minAutoLevel; nextLoadLevel--) { - // compute time to load next fragment at lower level - // 0.8 : consider only 80% of current bw to be conservative - // 8 = bits per byte (bps/Bps) - var levelNextBitrate = levels[nextLoadLevel].maxBitrate; - fragLevelNextLoadedDelay = duration * levelNextBitrate / (8 * 0.8 * loadRate); - - if (fragLevelNextLoadedDelay < bufferStarvationDelay) { - break; - } - } // Only emergency switch down if it takes less time to load a new fragment at lowest level instead of continuing - // to load the current one - - - if (fragLevelNextLoadedDelay >= fragLoadedDelay) { - return; - } - - var bwEstimate = this.bwEstimator.getEstimate(); - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " is loading too slowly and will cause an underbuffer; aborting and switching to level " + nextLoadLevel + "\n Current BW estimate: " + (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(bwEstimate) ? (bwEstimate / 1024).toFixed(3) : 'Unknown') + " Kb/s\n Estimated load time for current fragment: " + fragLoadedDelay.toFixed(3) + " s\n Estimated load time for the next fragment: " + fragLevelNextLoadedDelay.toFixed(3) + " s\n Time to underbuffer: " + bufferStarvationDelay.toFixed(3) + " s"); - CiderHls.nextLoadLevel = nextLoadLevel; - this.bwEstimator.sample(requestDelay, stats.loaded); - this.clearTimer(); - - if (frag.loader) { - this.fragCurrent = this.partCurrent = null; - frag.loader.abort(); - } - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOAD_EMERGENCY_ABORTED, { - frag: frag, - part: part, - stats: stats - }); - }; - - _proto.onFragLoaded = function onFragLoaded(event, _ref) { - var frag = _ref.frag, - part = _ref.part; - - if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__["PlaylistLevelType"].MAIN && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.sn)) { - var stats = part ? part.stats : frag.stats; - var duration = part ? part.duration : frag.duration; // stop monitoring bw once frag loaded - - this.clearTimer(); // store level id after successful fragment load - - this.lastLoadedFragLevel = frag.level; // reset forced auto level value so that next level will be selected - - this._nextAutoLevel = -1; // compute level average bitrate - - if (this.CiderHls.config.abrMaxWithRealBitrate) { - var level = this.CiderHls.levels[frag.level]; - var loadedBytes = (level.loaded ? level.loaded.bytes : 0) + stats.loaded; - var loadedDuration = (level.loaded ? level.loaded.duration : 0) + duration; - level.loaded = { - bytes: loadedBytes, - duration: loadedDuration - }; - level.realBitrate = Math.round(8 * loadedBytes / loadedDuration); - } - - if (frag.bitrateTest) { - var fragBufferedData = { - stats: stats, - frag: frag, - part: part, - id: frag.type - }; - this.onFragBuffered(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, fragBufferedData); - frag.bitrateTest = false; - } - } - }; - - _proto.onFragBuffered = function onFragBuffered(event, data) { - var frag = data.frag, - part = data.part; - var stats = part ? part.stats : frag.stats; - - if (stats.aborted) { - return; - } // Only count non-alt-audio frags which were actually buffered in our BW calculations - - - if (frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_5__["PlaylistLevelType"].MAIN || frag.sn === 'initSegment') { - return; - } // Use the difference between parsing and request instead of buffering and request to compute fragLoadingProcessing; - // rationale is that buffer appending only happens once media is attached. This can happen when config.startFragPrefetch - // is used. If we used buffering in that case, our BW estimate sample will be very large. - - - var processingMs = stats.parsing.end - stats.loading.start; - this.bwEstimator.sample(processingMs, stats.loaded); - stats.bwEstimate = this.bwEstimator.getEstimate(); - - if (frag.bitrateTest) { - this.bitrateTestDelay = processingMs / 1000; - } else { - this.bitrateTestDelay = 0; - } - }; - - _proto.onError = function onError(event, data) { - // stop timer in case of frag loading error - switch (data.details) { - case _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].FRAG_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].FRAG_LOAD_TIMEOUT: - this.clearTimer(); - break; - - default: - break; - } - }; - - _proto.clearTimer = function clearTimer() { - self.clearInterval(this.timer); - this.timer = undefined; - } // return next auto level - ; - - _proto.getNextABRAutoLevel = function getNextABRAutoLevel() { - var fragCurrent = this.fragCurrent, - partCurrent = this.partCurrent, - CiderHls = this.CiderHls; - var maxAutoLevel = CiderHls.maxAutoLevel, - config = CiderHls.config, - minAutoLevel = CiderHls.minAutoLevel, - media = CiderHls.media; - var currentFragDuration = partCurrent ? partCurrent.duration : fragCurrent ? fragCurrent.duration : 0; - var pos = media ? media.currentTime : 0; // playbackRate is the absolute value of the playback rate; if media.playbackRate is 0, we use 1 to load as - // if we're playing back at the normal rate. - - var playbackRate = media && media.playbackRate !== 0 ? Math.abs(media.playbackRate) : 1.0; - var avgbw = this.bwEstimator ? this.bwEstimator.getEstimate() : config.abrEwmaDefaultEstimate; // bufferStarvationDelay is the wall-clock time left until the playback buffer is exhausted. - - var bufferStarvationDelay = (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(media, pos, config.maxBufferHole).end - pos) / playbackRate; // First, look to see if we can find a level matching with our avg bandwidth AND that could also guarantee no rebuffering at all - - var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, config.abrBandWidthFactor, config.abrBandWidthUpFactor); - - if (bestLevel >= 0) { - return bestLevel; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace((bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", finding optimal quality level"); // not possible to get rid of rebuffering ... let's try to find level that will guarantee less than maxStarvationDelay of rebuffering - // if no matching level found, logic will return 0 - - var maxStarvationDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxStarvationDelay) : config.maxStarvationDelay; - var bwFactor = config.abrBandWidthFactor; - var bwUpFactor = config.abrBandWidthUpFactor; - - if (!bufferStarvationDelay) { - // in case buffer is empty, let's check if previous fragment was loaded to perform a bitrate test - var bitrateTestDelay = this.bitrateTestDelay; - - if (bitrateTestDelay) { - // if it is the case, then we need to adjust our max starvation delay using maxLoadingDelay config value - // max video loading delay used in automatic start level selection : - // in that mode ABR controller will ensure that video loading time (ie the time to fetch the first fragment at lowest quality level + - // the time to fetch the fragment at the appropriate quality level is less than ```maxLoadingDelay``` ) - // cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration - var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay; - maxStarvationDelay = maxLoadingDelay - bitrateTestDelay; - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace("bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms"); // don't use conservative factor on bitrate test - - bwFactor = bwUpFactor = 1; - } - } - - bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay + maxStarvationDelay, bwFactor, bwUpFactor); - return Math.max(bestLevel, 0); - }; - - _proto.findBestLevel = function findBestLevel(currentBw, minAutoLevel, maxAutoLevel, maxFetchDuration, bwFactor, bwUpFactor) { - var _level$details; - - var fragCurrent = this.fragCurrent, - partCurrent = this.partCurrent, - currentLevel = this.lastLoadedFragLevel; - var levels = this.CiderHls.levels; - var level = levels[currentLevel]; - var live = !!(level !== null && level !== void 0 && (_level$details = level.details) !== null && _level$details !== void 0 && _level$details.live); - var currentCodecSet = level === null || level === void 0 ? void 0 : level.codecSet; - var currentFragDuration = partCurrent ? partCurrent.duration : fragCurrent ? fragCurrent.duration : 0; - - for (var i = maxAutoLevel; i >= minAutoLevel; i--) { - var levelInfo = levels[i]; - - if (!levelInfo || currentCodecSet && levelInfo.codecSet !== currentCodecSet) { - continue; - } - - var levelDetails = levelInfo.details; - var avgDuration = (partCurrent ? levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.partTarget : levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.averagetargetduration) || currentFragDuration; - var adjustedbw = void 0; // follow algorithm captured from stagefright : - // https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp - // Pick the highest bandwidth stream below or equal to estimated bandwidth. - // consider only 80% of the available bandwidth, but if we are switching up, - // be even more conservative (70%) to avoid overestimating and immediately - // switching back. - - if (i <= currentLevel) { - adjustedbw = bwFactor * currentBw; - } else { - adjustedbw = bwUpFactor * currentBw; - } - - var bitrate = levels[i].maxBitrate; - var fetchDuration = bitrate * avgDuration / adjustedbw; - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace("level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: " + i + "/" + Math.round(adjustedbw) + "/" + bitrate + "/" + avgDuration + "/" + maxFetchDuration + "/" + fetchDuration); // if adjusted bw is greater than level bitrate AND - - if (adjustedbw > bitrate && ( // fragment fetchDuration unknown OR live stream OR fragment fetchDuration less than max allowed fetch duration, then this level matches - // we don't account for max Fetch Duration for live streams, this is to avoid switching down when near the edge of live sliding window ... - // special case to support startLevel = -1 (bitrateTest) on live streams : in that case we should not exit loop so that findBestLevel will return -1 - !fetchDuration || live && !this.bitrateTestDelay || fetchDuration < maxFetchDuration)) { - // as we are looping from highest to lowest, this will return the best achievable quality level - return i; - } - } // not enough time budget even with quality level 0 ... rebuffering might happen - - - return -1; - }; - - _createClass(AbrController, [{ - key: "nextAutoLevel", - get: function get() { - var forcedAutoLevel = this._nextAutoLevel; - var bwEstimator = this.bwEstimator; // in case next auto level has been forced, and bw not available or not reliable, return forced value - - if (forcedAutoLevel !== -1 && (!bwEstimator || !bwEstimator.canEstimate())) { - return forcedAutoLevel; - } // compute next level using ABR logic - - - var nextABRAutoLevel = this.getNextABRAutoLevel(); // if forced auto level has been defined, use it to cap ABR computed quality level - - if (forcedAutoLevel !== -1) { - nextABRAutoLevel = Math.min(forcedAutoLevel, nextABRAutoLevel); - } - - return nextABRAutoLevel; - }, - set: function set(nextLevel) { - this._nextAutoLevel = nextLevel; - } - }]); - - return AbrController; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (AbrController); - -/***/ }), - -/***/ "./src/controller/audio-stream-controller.ts": -/*!***************************************************!*\ - !*** ./src/controller/audio-stream-controller.ts ***! - \***************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); -/* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -/* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); -/* harmony import */ var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../demux/chunk-cache */ "./src/demux/chunk-cache.ts"); -/* harmony import */ var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../demux/transmuxer-interface */ "./src/demux/transmuxer-interface.ts"); -/* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts"); -/* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts"); -/* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - - - - - - - - - - - - - - - -var TICK_INTERVAL = 100; // how often to tick in ms - -var AudioStreamController = /*#__PURE__*/function (_BaseStreamController) { - _inheritsLoose(AudioStreamController, _BaseStreamController); - - function AudioStreamController(CiderHls, fragmentTracker) { - var _this; - - _this = _BaseStreamController.call(this, CiderHls, fragmentTracker, '[audio-stream-controller]') || this; - _this.videoBuffer = null; - _this.videoTrackCC = -1; - _this.waitingVideoCC = -1; - _this.audioSwitch = false; - _this.trackId = -1; - _this.waitingData = null; - _this.mainDetails = null; - _this.bufferFlushed = false; - - _this._registerListeners(); - - return _this; - } - - var _proto = AudioStreamController.prototype; - - _proto.onHandlerDestroying = function onHandlerDestroying() { - this._unregisterListeners(); - - this.mainDetails = null; - }; - - _proto._registerListeners = function _registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_RESET, this.onBufferReset, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_CREATED, this.onBufferCreated, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - }; - - _proto._unregisterListeners = function _unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_RESET, this.onBufferReset, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_CREATED, this.onBufferCreated, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - } // INIT_PTS_FOUND is triggered when the video track parsed in the stream-controller has a new PTS value - ; - - _proto.onInitPtsFound = function onInitPtsFound(event, _ref) { - var frag = _ref.frag, - id = _ref.id, - initPTS = _ref.initPTS; - - // Always update the new INIT PTS - // Can change due level switch - if (id === 'main') { - var cc = frag.cc; - this.initPTS[frag.cc] = initPTS; - this.log("InitPTS for cc: " + cc + " found from main: " + initPTS); - this.videoTrackCC = cc; // If we are waiting, tick immediately to unblock audio fragment transmuxing - - if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS) { - this.tick(); - } - } - }; - - _proto.startLoad = function startLoad(startPosition) { - if (!this.levels) { - this.startPosition = startPosition; - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED; - return; - } - - var lastCurrentTime = this.lastCurrentTime; - this.stopLoad(); - this.setInterval(TICK_INTERVAL); - this.fragLoadError = 0; - - if (lastCurrentTime > 0 && startPosition === -1) { - this.log("Override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3)); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } else { - this.loadedmetadata = false; - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK; - } - - this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition; - this.tick(); - }; - - _proto.doTick = function doTick() { - switch (this.state) { - case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE: - this.doTickIdle(); - break; - - case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK: - { - var _levels$trackId; - - var levels = this.levels, - trackId = this.trackId; - var details = levels === null || levels === void 0 ? void 0 : (_levels$trackId = levels[trackId]) === null || _levels$trackId === void 0 ? void 0 : _levels$trackId.details; - - if (details) { - if (this.waitForCdnTuneIn(details)) { - break; - } - - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS; - } - - break; - } - - case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING_WAITING_RETRY: - { - var _this$media; - - var now = performance.now(); - var retryDate = this.retryDate; // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading - - if (!retryDate || now >= retryDate || (_this$media = this.media) !== null && _this$media !== void 0 && _this$media.seeking) { - this.log('RetryDate reached, switch back to IDLE state'); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - - break; - } - - case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS: - { - // Ensure we don't get stuck in the WAITING_INIT_PTS state if the waiting frag CC doesn't match any initPTS - var waitingData = this.waitingData; - - if (waitingData) { - var frag = waitingData.frag, - part = waitingData.part, - cache = waitingData.cache, - complete = waitingData.complete; - - if (this.initPTS[frag.cc] !== undefined) { - this.waitingData = null; - this.waitingVideoCC = -1; - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING; - var payload = cache.flush(); - var data = { - frag: frag, - part: part, - payload: payload, - networkDetails: null + _proto._abandonRulesCheck = function _abandonRulesCheck() { + var frag = this.fragCurrent, + part = this.partCurrent, + CiderHls = this.CiderHls; + var autoLevelEnabled = CiderHls.autoLevelEnabled, + config = CiderHls.config, + media = CiderHls.media; + + if (!frag || !media) { + return; + } + + var stats = part ? part.stats : frag.stats; + var duration = part ? part.duration : frag.duration; // If loading has been aborted and not in lowLatencyMode, stop timer and return + + if (stats.aborted) { + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("frag loader destroy or aborted, disarm abandonRules"); + this.clearTimer(); // reset forced auto level value so that next level will be selected + + this._nextAutoLevel = -1; + return; + } // This check only runs if we're in ABR mode and actually playing + + if (!autoLevelEnabled || media.paused || !media.playbackRate || !media.readyState) { + return; + } + + var requestDelay = performance.now() - stats.loading.start; + var playbackRate = Math.abs(media.playbackRate); // In order to work with a stable bandwidth, only begin monitoring bandwidth after half of the fragment has been loaded + + if (requestDelay <= (500 * duration) / playbackRate) { + return; + } + + var levels = CiderHls.levels, + minAutoLevel = CiderHls.minAutoLevel; + var level = levels[frag.level]; + var expectedLen = stats.total || Math.max(stats.loaded, Math.round((duration * level.maxBitrate) / 8)); + var loadRate = Math.max(1, stats.bwEstimate ? stats.bwEstimate / 8 : (stats.loaded * 1000) / requestDelay); // fragLoadDelay is an estimate of the time (in seconds) it will take to buffer the entire fragment + + var fragLoadedDelay = (expectedLen - stats.loaded) / loadRate; + var pos = media.currentTime; // bufferStarvationDelay is an estimate of the amount time (in seconds) it will take to exhaust the buffer + + var bufferStarvationDelay = (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(media, pos, config.maxBufferHole).end - pos) / playbackRate; // Attempt an emergency downswitch only if less than 2 fragment lengths are buffered, and the time to finish loading + // the current fragment is greater than the amount of buffer we have left + + if (bufferStarvationDelay >= (2 * duration) / playbackRate || fragLoadedDelay <= bufferStarvationDelay) { + return; + } + + var fragLevelNextLoadedDelay = Number.POSITIVE_INFINITY; + var nextLoadLevel; // Iterate through lower level and try to find the largest one that avoids rebuffering + + for (nextLoadLevel = frag.level - 1; nextLoadLevel > minAutoLevel; nextLoadLevel--) { + // compute time to load next fragment at lower level + // 0.8 : consider only 80% of current bw to be conservative + // 8 = bits per byte (bps/Bps) + var levelNextBitrate = levels[nextLoadLevel].maxBitrate; + fragLevelNextLoadedDelay = (duration * levelNextBitrate) / (8 * 0.8 * loadRate); + + if (fragLevelNextLoadedDelay < bufferStarvationDelay) { + break; + } + } // Only emergency switch down if it takes less time to load a new fragment at lowest level instead of continuing + // to load the current one + + if (fragLevelNextLoadedDelay >= fragLoadedDelay) { + return; + } + + var bwEstimate = this.bwEstimator.getEstimate(); + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn( + "Fragment " + + frag.sn + + (part ? " part " + part.index : "") + + " of level " + + frag.level + + " is loading too slowly and will cause an underbuffer; aborting and switching to level " + + nextLoadLevel + + "\n Current BW estimate: " + + (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(bwEstimate) ? (bwEstimate / 1024).toFixed(3) : "Unknown") + + " Kb/s\n Estimated load time for current fragment: " + + fragLoadedDelay.toFixed(3) + + " s\n Estimated load time for the next fragment: " + + fragLevelNextLoadedDelay.toFixed(3) + + " s\n Time to underbuffer: " + + bufferStarvationDelay.toFixed(3) + + " s" + ); + CiderHls.nextLoadLevel = nextLoadLevel; + this.bwEstimator.sample(requestDelay, stats.loaded); + this.clearTimer(); + + if (frag.loader) { + this.fragCurrent = this.partCurrent = null; + frag.loader.abort(); + } + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_LOAD_EMERGENCY_ABORTED, { + frag: frag, + part: part, + stats: stats, + }); }; - this._handleFragmentLoadProgress(data); + _proto.onFragLoaded = function onFragLoaded(event, _ref) { + var frag = _ref.frag, + part = _ref.part; - if (complete) { - _BaseStreamController.prototype._handleFragmentLoadComplete.call(this, data); - } - } else if (this.videoTrackCC !== this.waitingVideoCC) { - // Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found - _utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log("Waiting fragment cc (" + frag.cc + ") cancelled because video is at cc " + this.videoTrackCC); - this.clearWaitingFragment(); - } else { - // Drop waiting fragment if an earlier fragment is needed - var pos = this.getLoadPosition(); - var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(this.mediaBuffer, pos, this.config.maxBufferHole); - var waitingFragmentAtPosition = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_11__["fragmentWithinToleranceTest"])(bufferInfo.end, this.config.maxFragLookUpTolerance, frag); + if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__["PlaylistLevelType"].MAIN && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.sn)) { + var stats = part ? part.stats : frag.stats; + var duration = part ? part.duration : frag.duration; // stop monitoring bw once frag loaded - if (waitingFragmentAtPosition < 0) { - _utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log("Waiting fragment cc (" + frag.cc + ") @ " + frag.start + " cancelled because another fragment at " + bufferInfo.end + " is needed"); - this.clearWaitingFragment(); - } + this.clearTimer(); // store level id after successful fragment load + + this.lastLoadedFragLevel = frag.level; // reset forced auto level value so that next level will be selected + + this._nextAutoLevel = -1; // compute level average bitrate + + if (this.CiderHls.config.abrMaxWithRealBitrate) { + var level = this.CiderHls.levels[frag.level]; + var loadedBytes = (level.loaded ? level.loaded.bytes : 0) + stats.loaded; + var loadedDuration = (level.loaded ? level.loaded.duration : 0) + duration; + level.loaded = { + bytes: loadedBytes, + duration: loadedDuration, + }; + level.realBitrate = Math.round((8 * loadedBytes) / loadedDuration); + } + + if (frag.bitrateTest) { + var fragBufferedData = { + stats: stats, + frag: frag, + part: part, + id: frag.type, + }; + this.onFragBuffered(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, fragBufferedData); + frag.bitrateTest = false; + } + } + }; + + _proto.onFragBuffered = function onFragBuffered(event, data) { + var frag = data.frag, + part = data.part; + var stats = part ? part.stats : frag.stats; + + if (stats.aborted) { + return; + } // Only count non-alt-audio frags which were actually buffered in our BW calculations + + if (frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_5__["PlaylistLevelType"].MAIN || frag.sn === "initSegment") { + return; + } // Use the difference between parsing and request instead of buffering and request to compute fragLoadingProcessing; + // rationale is that buffer appending only happens once media is attached. This can happen when config.startFragPrefetch + // is used. If we used buffering in that case, our BW estimate sample will be very large. + + var processingMs = stats.parsing.end - stats.loading.start; + this.bwEstimator.sample(processingMs, stats.loaded); + stats.bwEstimate = this.bwEstimator.getEstimate(); + + if (frag.bitrateTest) { + this.bitrateTestDelay = processingMs / 1000; + } else { + this.bitrateTestDelay = 0; + } + }; + + _proto.onError = function onError(event, data) { + // stop timer in case of frag loading error + switch (data.details) { + case _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].FRAG_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].FRAG_LOAD_TIMEOUT: + this.clearTimer(); + break; + + default: + break; + } + }; + + _proto.clearTimer = function clearTimer() { + self.clearInterval(this.timer); + this.timer = undefined; + }; // return next auto level + + _proto.getNextABRAutoLevel = function getNextABRAutoLevel() { + var fragCurrent = this.fragCurrent, + partCurrent = this.partCurrent, + CiderHls = this.CiderHls; + var maxAutoLevel = CiderHls.maxAutoLevel, + config = CiderHls.config, + minAutoLevel = CiderHls.minAutoLevel, + media = CiderHls.media; + var currentFragDuration = partCurrent ? partCurrent.duration : fragCurrent ? fragCurrent.duration : 0; + var pos = media ? media.currentTime : 0; // playbackRate is the absolute value of the playback rate; if media.playbackRate is 0, we use 1 to load as + // if we're playing back at the normal rate. + + var playbackRate = media && media.playbackRate !== 0 ? Math.abs(media.playbackRate) : 1.0; + var avgbw = this.bwEstimator ? this.bwEstimator.getEstimate() : config.abrEwmaDefaultEstimate; // bufferStarvationDelay is the wall-clock time left until the playback buffer is exhausted. + + var bufferStarvationDelay = (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(media, pos, config.maxBufferHole).end - pos) / playbackRate; // First, look to see if we can find a level matching with our avg bandwidth AND that could also guarantee no rebuffering at all + + var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, config.abrBandWidthFactor, config.abrBandWidthUpFactor); + + if (bestLevel >= 0) { + return bestLevel; + } + + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace((bufferStarvationDelay ? "rebuffering expected" : "buffer is empty") + ", finding optimal quality level"); // not possible to get rid of rebuffering ... let's try to find level that will guarantee less than maxStarvationDelay of rebuffering + // if no matching level found, logic will return 0 + + var maxStarvationDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxStarvationDelay) : config.maxStarvationDelay; + var bwFactor = config.abrBandWidthFactor; + var bwUpFactor = config.abrBandWidthUpFactor; + + if (!bufferStarvationDelay) { + // in case buffer is empty, let's check if previous fragment was loaded to perform a bitrate test + var bitrateTestDelay = this.bitrateTestDelay; + + if (bitrateTestDelay) { + // if it is the case, then we need to adjust our max starvation delay using maxLoadingDelay config value + // max video loading delay used in automatic start level selection : + // in that mode ABR controller will ensure that video loading time (ie the time to fetch the first fragment at lowest quality level + + // the time to fetch the fragment at the appropriate quality level is less than ```maxLoadingDelay``` ) + // cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration + var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay; + maxStarvationDelay = maxLoadingDelay - bitrateTestDelay; + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace("bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms"); // don't use conservative factor on bitrate test + + bwFactor = bwUpFactor = 1; + } + } + + bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay + maxStarvationDelay, bwFactor, bwUpFactor); + return Math.max(bestLevel, 0); + }; + + _proto.findBestLevel = function findBestLevel(currentBw, minAutoLevel, maxAutoLevel, maxFetchDuration, bwFactor, bwUpFactor) { + var _level$details; + + var fragCurrent = this.fragCurrent, + partCurrent = this.partCurrent, + currentLevel = this.lastLoadedFragLevel; + var levels = this.CiderHls.levels; + var level = levels[currentLevel]; + var live = !!(level !== null && level !== void 0 && (_level$details = level.details) !== null && _level$details !== void 0 && _level$details.live); + var currentCodecSet = level === null || level === void 0 ? void 0 : level.codecSet; + var currentFragDuration = partCurrent ? partCurrent.duration : fragCurrent ? fragCurrent.duration : 0; + + for (var i = maxAutoLevel; i >= minAutoLevel; i--) { + var levelInfo = levels[i]; + + if (!levelInfo || (currentCodecSet && levelInfo.codecSet !== currentCodecSet)) { + continue; + } + + var levelDetails = levelInfo.details; + var avgDuration = (partCurrent ? (levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.partTarget) : levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.averagetargetduration) || currentFragDuration; + var adjustedbw = void 0; // follow algorithm captured from stagefright : + // https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp + // Pick the highest bandwidth stream below or equal to estimated bandwidth. + // consider only 80% of the available bandwidth, but if we are switching up, + // be even more conservative (70%) to avoid overestimating and immediately + // switching back. + + if (i <= currentLevel) { + adjustedbw = bwFactor * currentBw; + } else { + adjustedbw = bwUpFactor * currentBw; + } + + var bitrate = levels[i].maxBitrate; + var fetchDuration = (bitrate * avgDuration) / adjustedbw; + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace("level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: " + i + "/" + Math.round(adjustedbw) + "/" + bitrate + "/" + avgDuration + "/" + maxFetchDuration + "/" + fetchDuration); // if adjusted bw is greater than level bitrate AND + + if ( + adjustedbw > bitrate && // fragment fetchDuration unknown OR live stream OR fragment fetchDuration less than max allowed fetch duration, then this level matches + // we don't account for max Fetch Duration for live streams, this is to avoid switching down when near the edge of live sliding window ... + // special case to support startLevel = -1 (bitrateTest) on live streams : in that case we should not exit loop so that findBestLevel will return -1 + (!fetchDuration || (live && !this.bitrateTestDelay) || fetchDuration < maxFetchDuration) + ) { + // as we are looping from highest to lowest, this will return the best achievable quality level + return i; + } + } // not enough time budget even with quality level 0 ... rebuffering might happen + + return -1; + }; + + _createClass(AbrController, [ + { + key: "nextAutoLevel", + get: function get() { + var forcedAutoLevel = this._nextAutoLevel; + var bwEstimator = this.bwEstimator; // in case next auto level has been forced, and bw not available or not reliable, return forced value + + if (forcedAutoLevel !== -1 && (!bwEstimator || !bwEstimator.canEstimate())) { + return forcedAutoLevel; + } // compute next level using ABR logic + + var nextABRAutoLevel = this.getNextABRAutoLevel(); // if forced auto level has been defined, use it to cap ABR computed quality level + + if (forcedAutoLevel !== -1) { + nextABRAutoLevel = Math.min(forcedAutoLevel, nextABRAutoLevel); + } + + return nextABRAutoLevel; + }, + set: function set(nextLevel) { + this._nextAutoLevel = nextLevel; + }, + }, + ]); + + return AbrController; + })(); + + /* harmony default export */ __webpack_exports__["default"] = AbrController; + + /***/ + }, + + /***/ "./src/controller/audio-stream-controller.ts": + /*!***************************************************!*\ + !*** ./src/controller/audio-stream-controller.ts ***! + \***************************************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); + /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); + /* harmony import */ var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../demux/chunk-cache */ "./src/demux/chunk-cache.ts"); + /* harmony import */ var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../demux/transmuxer-interface */ "./src/demux/transmuxer-interface.ts"); + /* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts"); + /* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts"); + /* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + + function _extends() { + _extends = + Object.assign || + function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); } - } else { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - } - } - - this.onTickEnd(); - }; - - _proto.clearWaitingFragment = function clearWaitingFragment() { - var waitingData = this.waitingData; - - if (waitingData) { - this.fragmentTracker.removeFragment(waitingData.frag); - this.waitingData = null; - this.waitingVideoCC = -1; - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - }; - - _proto.onTickEnd = function onTickEnd() { - var media = this.media; - - if (!media || !media.readyState) { - // Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0) - return; - } - - var mediaBuffer = this.mediaBuffer ? this.mediaBuffer : media; - var buffered = mediaBuffer.buffered; - - if (!this.loadedmetadata && buffered.length) { - this.loadedmetadata = true; - } - - this.lastCurrentTime = media.currentTime; - }; - - _proto.doTickIdle = function doTickIdle() { - var _frag$decryptdata, _frag$decryptdata2; - - var CiderHls = this.CiderHls, - levels = this.levels, - media = this.media, - trackId = this.trackId; - var config = CiderHls.config; - - if (!levels || !levels[trackId]) { - return; - } // if video not attached AND - // start fragment already requested OR start frag prefetch not enabled - // exit loop - // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop - - - if (!media && (this.startFragRequested || !config.startFragPrefetch)) { - return; - } - - var levelInfo = levels[trackId]; - var trackDetails = levelInfo.details; - - if (!trackDetails || trackDetails.live && this.levelLastLoaded !== trackId || this.waitForCdnTuneIn(trackDetails)) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK; - return; - } - - if (this.bufferFlushed) { - this.bufferFlushed = false; - this.afterBufferFlushed(this.mediaBuffer ? this.mediaBuffer : this.media, _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO); - } - - var bufferInfo = this.getFwdBufferInfo(this.mediaBuffer ? this.mediaBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO); - - if (bufferInfo === null) { - return; - } - - var bufferLen = bufferInfo.len; - var maxBufLen = this.getMaxBufferLength(); - var audioSwitch = this.audioSwitch; // if buffer length is less than maxBufLen try to load a new fragment - - if (bufferLen >= maxBufLen && !audioSwitch) { - return; - } - - if (!audioSwitch && this._streamEnded(bufferInfo, trackDetails)) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_EOS, { - type: 'audio' - }); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ENDED; - return; - } - - var fragments = trackDetails.fragments; - var start = fragments[0].start; - var targetBufferTime = bufferInfo.end; - - if (audioSwitch) { - var pos = this.getLoadPosition(); - targetBufferTime = pos; // if currentTime (pos) is less than alt audio playlist start time, it means that alt audio is ahead of currentTime - - if (trackDetails.PTSKnown && pos < start) { - // if everything is buffered from pos to start or if audio buffer upfront, let's seek to start - if (bufferInfo.end > start || bufferInfo.nextStart) { - this.log('Alt audio track ahead of main track, seek to start of alt audio track'); - media.currentTime = start + 0.05; - } - } - } - - var frag = this.getNextFragment(targetBufferTime, trackDetails); - - if (!frag) { - this.bufferFlushed = true; - return; - } - - if (((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === 'identity' && !((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)) { - this.loadKey(frag, trackDetails); - } else { - this.loadFragment(frag, trackDetails, targetBufferTime); - } - }; - - _proto.getMaxBufferLength = function getMaxBufferLength() { - var maxConfigBuffer = _BaseStreamController.prototype.getMaxBufferLength.call(this); - - var mainBufferInfo = this.getFwdBufferInfo(this.videoBuffer ? this.videoBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); - - if (mainBufferInfo === null) { - return maxConfigBuffer; - } - - return Math.max(maxConfigBuffer, mainBufferInfo.len); - }; - - _proto.onMediaDetaching = function onMediaDetaching() { - this.videoBuffer = null; - - _BaseStreamController.prototype.onMediaDetaching.call(this); - }; - - _proto.onAudioTracksUpdated = function onAudioTracksUpdated(event, _ref2) { - var audioTracks = _ref2.audioTracks; - this.resetTransmuxer(); - this.levels = audioTracks.map(function (mediaPlaylist) { - return new _types_level__WEBPACK_IMPORTED_MODULE_5__["Level"](mediaPlaylist); - }); - }; - - _proto.onAudioTrackSwitching = function onAudioTrackSwitching(event, data) { - // if any URL found on new audio track, it is an alternate audio track - var altAudio = !!data.url; - this.trackId = data.id; - var fragCurrent = this.fragCurrent; - - if (fragCurrent !== null && fragCurrent !== void 0 && fragCurrent.loader) { - fragCurrent.loader.abort(); - } - - this.fragCurrent = null; - this.clearWaitingFragment(); // destroy useless transmuxer when switching audio to main - - if (!altAudio) { - this.resetTransmuxer(); - } else { - // switching to audio track, start timer if not already started - this.setInterval(TICK_INTERVAL); - } // should we switch tracks ? - - - if (altAudio) { - this.audioSwitch = true; // main audio track are handled by stream-controller, just do something if switching to alt audio track - - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } else { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED; - } - - this.tick(); - }; - - _proto.onManifestLoading = function onManifestLoading() { - this.mainDetails = null; - this.fragmentTracker.removeAllFragments(); - this.startPosition = this.lastCurrentTime = 0; - this.bufferFlushed = false; - }; - - _proto.onLevelLoaded = function onLevelLoaded(event, data) { - this.mainDetails = data.details; - }; - - _proto.onAudioTrackLoaded = function onAudioTrackLoaded(event, data) { - var _track$details; - - var levels = this.levels; - var newDetails = data.details, - trackId = data.id; - - if (!levels) { - this.warn("Audio tracks were reset while loading level " + trackId); - return; - } - - this.log("Track " + trackId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "],duration:" + newDetails.totalduration); - var track = levels[trackId]; - var sliding = 0; - - if (newDetails.live || (_track$details = track.details) !== null && _track$details !== void 0 && _track$details.live) { - var mainDetails = this.mainDetails; - - if (!newDetails.fragments[0]) { - newDetails.deltaUpdateFailed = true; - } - - if (newDetails.deltaUpdateFailed || !mainDetails) { - return; - } - - if (!track.details && newDetails.hasProgramDateTime && mainDetails.hasProgramDateTime) { - // Make sure our audio rendition is aligned with the "main" rendition, using - // pdt as our reference times. - Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__["alignMediaPlaylistByPDT"])(newDetails, mainDetails); - sliding = newDetails.fragments[0].start; - } else { - sliding = this.alignPlaylists(newDetails, track.details); - } - } - - track.details = newDetails; - this.levelLastLoaded = trackId; // compute start position if we are aligned with the main playlist - - if (!this.startFragRequested && (this.mainDetails || !newDetails.live)) { - this.setStartPosition(track.details, sliding); - } // only switch back to IDLE state if we were waiting for track to start downloading a new fragment - - - if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK && !this.waitForCdnTuneIn(newDetails)) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } // trigger handler right now - - - this.tick(); - }; - - _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(data) { - var _frag$initSegment; - - var frag = data.frag, - part = data.part, - payload = data.payload; - var config = this.config, - trackId = this.trackId, - levels = this.levels; - - if (!levels) { - this.warn("Audio tracks were reset while fragment load was in progress. Fragment " + frag.sn + " of level " + frag.level + " will not be buffered"); - return; - } - - var track = levels[trackId]; - console.assert(track, 'Audio track is defined on fragment load progress'); - var details = track.details; - console.assert(details, 'Audio track details are defined on fragment load progress'); - var audioCodec = config.defaultAudioCodec || track.audioCodec || 'mp4a.40.2'; - var transmuxer = this.transmuxer; - - if (!transmuxer) { - transmuxer = this.transmuxer = new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__["default"](this.CiderHls, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this)); - } // Check if we have video initPTS - // If not we need to wait for it - - - var initPTS = this.initPTS[frag.cc]; - var initSegmentData = (_frag$initSegment = frag.initSegment) === null || _frag$initSegment === void 0 ? void 0 : _frag$initSegment.data; - - if (initPTS !== undefined) { - // this.log(`Transmuxing ${sn} of [${details.startSN} ,${details.endSN}],track ${trackId}`); - // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live) - var accurateTimeOffset = false; // details.PTSKnown || !details.live; - - var partIndex = part ? part.index : -1; - var partial = partIndex !== -1; - var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial); - transmuxer.push(payload, initSegmentData, audioCodec, '', frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS); - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log("Unknown video PTS for cc " + frag.cc + ", waiting for video PTS before demuxing audio frag " + frag.sn + " of [" + details.startSN + " ," + details.endSN + "],track " + trackId); - - var _this$waitingData = this.waitingData = this.waitingData || { - frag: frag, - part: part, - cache: new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__["default"](), - complete: false - }, - cache = _this$waitingData.cache; - - cache.push(new Uint8Array(payload)); - this.waitingVideoCC = this.videoTrackCC; - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS; - } - }; - - _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedData) { - if (this.waitingData) { - this.waitingData.complete = true; - return; - } - - _BaseStreamController.prototype._handleFragmentLoadComplete.call(this, fragLoadedData); - }; - - _proto.onBufferReset = function - /* event: Events.BUFFER_RESET */ - onBufferReset() { - // reset reference to sourcebuffers - this.mediaBuffer = this.videoBuffer = null; - this.loadedmetadata = false; - }; - - _proto.onBufferCreated = function onBufferCreated(event, data) { - var audioTrack = data.tracks.audio; - - if (audioTrack) { - this.mediaBuffer = audioTrack.buffer; - } - - if (data.tracks.video) { - this.videoBuffer = data.tracks.video.buffer; - } - }; - - _proto.onFragBuffered = function onFragBuffered(event, data) { - var frag = data.frag, - part = data.part; - - if (frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO) { - return; - } - - if (this.fragContextChanged(frag)) { - // If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion - // Avoid setting state back to IDLE or concluding the audio switch; otherwise, the switched-to track will not buffer - this.warn("Fragment " + frag.sn + (part ? ' p: ' + part.index : '') + " of level " + frag.level + " finished buffering, but was aborted. state: " + this.state + ", audioSwitch: " + this.audioSwitch); - return; - } - - if (frag.sn !== 'initSegment') { - this.fragPrevious = frag; - - if (this.audioSwitch) { - this.audioSwitch = false; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHED, { - id: this.trackId - }); - } - } - - this.fragBufferedComplete(frag, part); - }; - - _proto.onError = function onError(event, data) { - switch (data.details) { - case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].FRAG_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].FRAG_LOAD_TIMEOUT: - case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].KEY_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].KEY_LOAD_TIMEOUT: - // TODO: Skip fragments that do not belong to this.fragCurrent audio-group id - this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO, data); - break; - - case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].AUDIO_TRACK_LOAD_TIMEOUT: - // when in ERROR state, don't switch back to IDLE state in case a non-fatal error is received - if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR && this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED) { - // if fatal error, stop processing, otherwise move to IDLE to retry loading - this.state = data.fatal ? _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR : _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - this.warn(data.details + " while loading frag, switching to " + this.state + " state"); - } - - break; - - case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].BUFFER_FULL_ERROR: - // if in appending state - if (data.parent === 'audio' && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSED)) { - var flushBuffer = true; - var bufferedInfo = this.getFwdBufferInfo(this.mediaBuffer, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO); // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end - // reduce max buf len if current position is buffered - - if (bufferedInfo && bufferedInfo.len > 0.5) { - flushBuffer = !this.reduceMaxBufferLength(bufferedInfo.len); - } - - if (flushBuffer) { - // current position is not buffered, but browser is still complaining about buffer full error - // this happens on IE/Edge, refer to https://github.com/video-dev/CiderHls.js/pull/708 - // in that case flush the whole audio buffer to recover - this.warn('Buffer full error also media.currentTime is not buffered, flush audio buffer'); - this.fragCurrent = null; - - _BaseStreamController.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, 'audio'); - } - - this.resetLoadingState(); - } - - break; - - default: - break; - } - }; - - _proto.onBufferFlushed = function onBufferFlushed(event, _ref3) { - var type = _ref3.type; - - if (type === _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO) { - this.bufferFlushed = true; - } - }; - - _proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) { - var _id3$samples; - - var id = 'audio'; - var CiderHls = this.CiderHls; - var remuxResult = transmuxResult.remuxResult, - chunkMeta = transmuxResult.chunkMeta; - var context = this.getCurrentContext(chunkMeta); - - if (!context) { - this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered."); - this.resetLiveStartWhenNotLoaded(chunkMeta.level); - return; - } - - var frag = context.frag, - part = context.part; - var audio = remuxResult.audio, - text = remuxResult.text, - id3 = remuxResult.id3, - initSegment = remuxResult.initSegment; // Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level. - // If we are, subsequently check if the currently loading fragment (fragCurrent) has changed. - - if (this.fragContextChanged(frag)) { - return; - } - - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING; - - if (this.audioSwitch && audio) { - this.completeAudioSwitch(); - } - - if (initSegment !== null && initSegment !== void 0 && initSegment.tracks) { - this._bufferInitSegment(initSegment.tracks, frag, chunkMeta); - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_PARSING_INIT_SEGMENT, { - frag: frag, - id: id, - tracks: initSegment.tracks - }); // Only flush audio from old audio tracks when PTS is known on new audio track - } - - if (audio) { - var startPTS = audio.startPTS, - endPTS = audio.endPTS, - startDTS = audio.startDTS, - endDTS = audio.endDTS; - - if (part) { - part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO] = { - startPTS: startPTS, - endPTS: endPTS, - startDTS: startDTS, - endDTS: endDTS - }; - } - - frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO, startPTS, endPTS, startDTS, endDTS); - this.bufferFragmentData(audio, frag, part, chunkMeta); - } - - if (id3 !== null && id3 !== void 0 && (_id3$samples = id3.samples) !== null && _id3$samples !== void 0 && _id3$samples.length) { - var emittedID3 = _extends({ - frag: frag, - id: id - }, id3); - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_PARSING_METADATA, emittedID3); - } - - if (text) { - var emittedText = _extends({ - frag: frag, - id: id - }, text); - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_PARSING_USERDATA, emittedText); - } - }; - - _proto._bufferInitSegment = function _bufferInitSegment(tracks, frag, chunkMeta) { - if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING) { - return; - } // delete any video track found on audio transmuxer - - - if (tracks.video) { - delete tracks.video; - } // include levelCodec in audio and video tracks - - - var track = tracks.audio; - - if (!track) { - return; - } - - track.levelCodec = track.codec; - track.id = 'audio'; - this.log("Init audio buffer, container:" + track.container + ", codecs[parsed]=[" + track.codec + "]"); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_CODECS, tracks); - var initSegment = track.initSegment; - - if (initSegment !== null && initSegment !== void 0 && initSegment.byteLength) { - var segment = { - type: 'audio', - frag: frag, - part: null, - chunkMeta: chunkMeta, - parent: frag.type, - data: initSegment - }; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_APPENDING, segment); - } // trigger handler right now - - - this.tick(); - }; - - _proto.loadFragment = function loadFragment(frag, trackDetails, targetBufferTime) { - // only load if fragment is not loaded or if in audio switch - var fragState = this.fragmentTracker.getState(frag); - this.fragCurrent = frag; // we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch - - if (this.audioSwitch || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__["FragmentState"].NOT_LOADED || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__["FragmentState"].PARTIAL) { - if (frag.sn === 'initSegment') { - this._loadInitSegment(frag); - } else if (trackDetails.live && !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.initPTS[frag.cc])) { - this.log("Waiting for video PTS in continuity counter " + frag.cc + " of live stream before loading audio fragment " + frag.sn + " of level " + this.trackId); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS; - } else { - this.startFragRequested = true; - - _BaseStreamController.prototype.loadFragment.call(this, frag, trackDetails, targetBufferTime); - } - } - }; - - _proto.completeAudioSwitch = function completeAudioSwitch() { - var CiderHls = this.CiderHls, - media = this.media, - trackId = this.trackId; - - if (media) { - this.log('Switching audio track : flushing all audio'); - - _BaseStreamController.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, 'audio'); - } - - this.audioSwitch = false; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHED, { - id: trackId - }); - }; - - return AudioStreamController; -}(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]); - -/* harmony default export */ __webpack_exports__["default"] = (AudioStreamController); - -/***/ }), - -/***/ "./src/controller/audio-track-controller.ts": -/*!**************************************************!*\ + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } + + var TICK_INTERVAL = 100; // how often to tick in ms + + var AudioStreamController = /*#__PURE__*/ (function (_BaseStreamController) { + _inheritsLoose(AudioStreamController, _BaseStreamController); + + function AudioStreamController(CiderHls, fragmentTracker) { + var _this; + + _this = _BaseStreamController.call(this, CiderHls, fragmentTracker, "[audio-stream-controller]") || this; + _this.videoBuffer = null; + _this.videoTrackCC = -1; + _this.waitingVideoCC = -1; + _this.audioSwitch = false; + _this.trackId = -1; + _this.waitingData = null; + _this.mainDetails = null; + _this.bufferFlushed = false; + + _this._registerListeners(); + + return _this; + } + + var _proto = AudioStreamController.prototype; + + _proto.onHandlerDestroying = function onHandlerDestroying() { + this._unregisterListeners(); + + this.mainDetails = null; + }; + + _proto._registerListeners = function _registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_RESET, this.onBufferReset, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_CREATED, this.onBufferCreated, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + }; + + _proto._unregisterListeners = function _unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, this.onError, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_RESET, this.onBufferReset, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_CREATED, this.onBufferCreated, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + }; // INIT_PTS_FOUND is triggered when the video track parsed in the stream-controller has a new PTS value + + _proto.onInitPtsFound = function onInitPtsFound(event, _ref) { + var frag = _ref.frag, + id = _ref.id, + initPTS = _ref.initPTS; + + // Always update the new INIT PTS + // Can change due level switch + if (id === "main") { + var cc = frag.cc; + this.initPTS[frag.cc] = initPTS; + this.log("InitPTS for cc: " + cc + " found from main: " + initPTS); + this.videoTrackCC = cc; // If we are waiting, tick immediately to unblock audio fragment transmuxing + + if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS) { + this.tick(); + } + } + }; + + _proto.startLoad = function startLoad(startPosition) { + if (!this.levels) { + this.startPosition = startPosition; + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED; + return; + } + + var lastCurrentTime = this.lastCurrentTime; + this.stopLoad(); + this.setInterval(TICK_INTERVAL); + this.fragLoadError = 0; + + if (lastCurrentTime > 0 && startPosition === -1) { + this.log("Override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3)); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } else { + this.loadedmetadata = false; + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK; + } + + this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition; + this.tick(); + }; + + _proto.doTick = function doTick() { + switch (this.state) { + case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE: + this.doTickIdle(); + break; + + case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK: { + var _levels$trackId; + + var levels = this.levels, + trackId = this.trackId; + var details = levels === null || levels === void 0 ? void 0 : (_levels$trackId = levels[trackId]) === null || _levels$trackId === void 0 ? void 0 : _levels$trackId.details; + + if (details) { + if (this.waitForCdnTuneIn(details)) { + break; + } + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS; + } + + break; + } + + case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING_WAITING_RETRY: { + var _this$media; + + var now = performance.now(); + var retryDate = this.retryDate; // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading + + if (!retryDate || now >= retryDate || ((_this$media = this.media) !== null && _this$media !== void 0 && _this$media.seeking)) { + this.log("RetryDate reached, switch back to IDLE state"); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + + break; + } + + case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS: { + // Ensure we don't get stuck in the WAITING_INIT_PTS state if the waiting frag CC doesn't match any initPTS + var waitingData = this.waitingData; + + if (waitingData) { + var frag = waitingData.frag, + part = waitingData.part, + cache = waitingData.cache, + complete = waitingData.complete; + + if (this.initPTS[frag.cc] !== undefined) { + this.waitingData = null; + this.waitingVideoCC = -1; + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING; + var payload = cache.flush(); + var data = { + frag: frag, + part: part, + payload: payload, + networkDetails: null, + }; + + this._handleFragmentLoadProgress(data); + + if (complete) { + _BaseStreamController.prototype._handleFragmentLoadComplete.call(this, data); + } + } else if (this.videoTrackCC !== this.waitingVideoCC) { + // Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found + _utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log("Waiting fragment cc (" + frag.cc + ") cancelled because video is at cc " + this.videoTrackCC); + this.clearWaitingFragment(); + } else { + // Drop waiting fragment if an earlier fragment is needed + var pos = this.getLoadPosition(); + var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(this.mediaBuffer, pos, this.config.maxBufferHole); + var waitingFragmentAtPosition = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_11__["fragmentWithinToleranceTest"])(bufferInfo.end, this.config.maxFragLookUpTolerance, frag); + + if (waitingFragmentAtPosition < 0) { + _utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log("Waiting fragment cc (" + frag.cc + ") @ " + frag.start + " cancelled because another fragment at " + bufferInfo.end + " is needed"); + this.clearWaitingFragment(); + } + } + } else { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + } + } + + this.onTickEnd(); + }; + + _proto.clearWaitingFragment = function clearWaitingFragment() { + var waitingData = this.waitingData; + + if (waitingData) { + this.fragmentTracker.removeFragment(waitingData.frag); + this.waitingData = null; + this.waitingVideoCC = -1; + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + }; + + _proto.onTickEnd = function onTickEnd() { + var media = this.media; + + if (!media || !media.readyState) { + // Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0) + return; + } + + var mediaBuffer = this.mediaBuffer ? this.mediaBuffer : media; + var buffered = mediaBuffer.buffered; + + if (!this.loadedmetadata && buffered.length) { + this.loadedmetadata = true; + } + + this.lastCurrentTime = media.currentTime; + }; + + _proto.doTickIdle = function doTickIdle() { + var _frag$decryptdata, _frag$decryptdata2; + + var CiderHls = this.CiderHls, + levels = this.levels, + media = this.media, + trackId = this.trackId; + var config = CiderHls.config; + + if (!levels || !levels[trackId]) { + return; + } // if video not attached AND + // start fragment already requested OR start frag prefetch not enabled + // exit loop + // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop + + if (!media && (this.startFragRequested || !config.startFragPrefetch)) { + return; + } + + var levelInfo = levels[trackId]; + var trackDetails = levelInfo.details; + + if (!trackDetails || (trackDetails.live && this.levelLastLoaded !== trackId) || this.waitForCdnTuneIn(trackDetails)) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK; + return; + } + + if (this.bufferFlushed) { + this.bufferFlushed = false; + this.afterBufferFlushed(this.mediaBuffer ? this.mediaBuffer : this.media, _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO); + } + + var bufferInfo = this.getFwdBufferInfo(this.mediaBuffer ? this.mediaBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO); + + if (bufferInfo === null) { + return; + } + + var bufferLen = bufferInfo.len; + var maxBufLen = this.getMaxBufferLength(); + var audioSwitch = this.audioSwitch; // if buffer length is less than maxBufLen try to load a new fragment + + if (bufferLen >= maxBufLen && !audioSwitch) { + return; + } + + if (!audioSwitch && this._streamEnded(bufferInfo, trackDetails)) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_EOS, { + type: "audio", + }); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ENDED; + return; + } + + var fragments = trackDetails.fragments; + var start = fragments[0].start; + var targetBufferTime = bufferInfo.end; + + if (audioSwitch) { + var pos = this.getLoadPosition(); + targetBufferTime = pos; // if currentTime (pos) is less than alt audio playlist start time, it means that alt audio is ahead of currentTime + + if (trackDetails.PTSKnown && pos < start) { + // if everything is buffered from pos to start or if audio buffer upfront, let's seek to start + if (bufferInfo.end > start || bufferInfo.nextStart) { + this.log("Alt audio track ahead of main track, seek to start of alt audio track"); + media.currentTime = start + 0.05; + } + } + } + + var frag = this.getNextFragment(targetBufferTime, trackDetails); + + if (!frag) { + this.bufferFlushed = true; + return; + } + + if (((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === "identity" && !((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)) { + this.loadKey(frag, trackDetails); + } else { + this.loadFragment(frag, trackDetails, targetBufferTime); + } + }; + + _proto.getMaxBufferLength = function getMaxBufferLength() { + var maxConfigBuffer = _BaseStreamController.prototype.getMaxBufferLength.call(this); + + var mainBufferInfo = this.getFwdBufferInfo(this.videoBuffer ? this.videoBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + + if (mainBufferInfo === null) { + return maxConfigBuffer; + } + + return Math.max(maxConfigBuffer, mainBufferInfo.len); + }; + + _proto.onMediaDetaching = function onMediaDetaching() { + this.videoBuffer = null; + + _BaseStreamController.prototype.onMediaDetaching.call(this); + }; + + _proto.onAudioTracksUpdated = function onAudioTracksUpdated(event, _ref2) { + var audioTracks = _ref2.audioTracks; + this.resetTransmuxer(); + this.levels = audioTracks.map(function (mediaPlaylist) { + return new _types_level__WEBPACK_IMPORTED_MODULE_5__["Level"](mediaPlaylist); + }); + }; + + _proto.onAudioTrackSwitching = function onAudioTrackSwitching(event, data) { + // if any URL found on new audio track, it is an alternate audio track + var altAudio = !!data.url; + this.trackId = data.id; + var fragCurrent = this.fragCurrent; + + if (fragCurrent !== null && fragCurrent !== void 0 && fragCurrent.loader) { + fragCurrent.loader.abort(); + } + + this.fragCurrent = null; + this.clearWaitingFragment(); // destroy useless transmuxer when switching audio to main + + if (!altAudio) { + this.resetTransmuxer(); + } else { + // switching to audio track, start timer if not already started + this.setInterval(TICK_INTERVAL); + } // should we switch tracks ? + + if (altAudio) { + this.audioSwitch = true; // main audio track are handled by stream-controller, just do something if switching to alt audio track + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } else { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED; + } + + this.tick(); + }; + + _proto.onManifestLoading = function onManifestLoading() { + this.mainDetails = null; + this.fragmentTracker.removeAllFragments(); + this.startPosition = this.lastCurrentTime = 0; + this.bufferFlushed = false; + }; + + _proto.onLevelLoaded = function onLevelLoaded(event, data) { + this.mainDetails = data.details; + }; + + _proto.onAudioTrackLoaded = function onAudioTrackLoaded(event, data) { + var _track$details; + + var levels = this.levels; + var newDetails = data.details, + trackId = data.id; + + if (!levels) { + this.warn("Audio tracks were reset while loading level " + trackId); + return; + } + + this.log("Track " + trackId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "],duration:" + newDetails.totalduration); + var track = levels[trackId]; + var sliding = 0; + + if (newDetails.live || ((_track$details = track.details) !== null && _track$details !== void 0 && _track$details.live)) { + var mainDetails = this.mainDetails; + + if (!newDetails.fragments[0]) { + newDetails.deltaUpdateFailed = true; + } + + if (newDetails.deltaUpdateFailed || !mainDetails) { + return; + } + + if (!track.details && newDetails.hasProgramDateTime && mainDetails.hasProgramDateTime) { + // Make sure our audio rendition is aligned with the "main" rendition, using + // pdt as our reference times. + Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__["alignMediaPlaylistByPDT"])(newDetails, mainDetails); + sliding = newDetails.fragments[0].start; + } else { + sliding = this.alignPlaylists(newDetails, track.details); + } + } + + track.details = newDetails; + this.levelLastLoaded = trackId; // compute start position if we are aligned with the main playlist + + if (!this.startFragRequested && (this.mainDetails || !newDetails.live)) { + this.setStartPosition(track.details, sliding); + } // only switch back to IDLE state if we were waiting for track to start downloading a new fragment + + if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_TRACK && !this.waitForCdnTuneIn(newDetails)) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } // trigger handler right now + + this.tick(); + }; + + _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(data) { + var _frag$initSegment; + + var frag = data.frag, + part = data.part, + payload = data.payload; + var config = this.config, + trackId = this.trackId, + levels = this.levels; + + if (!levels) { + this.warn("Audio tracks were reset while fragment load was in progress. Fragment " + frag.sn + " of level " + frag.level + " will not be buffered"); + return; + } + + var track = levels[trackId]; + console.assert(track, "Audio track is defined on fragment load progress"); + var details = track.details; + console.assert(details, "Audio track details are defined on fragment load progress"); + var audioCodec = config.defaultAudioCodec || track.audioCodec || "mp4a.40.2"; + var transmuxer = this.transmuxer; + + if (!transmuxer) { + transmuxer = this.transmuxer = new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__["default"](this.CiderHls, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this)); + } // Check if we have video initPTS + // If not we need to wait for it + + var initPTS = this.initPTS[frag.cc]; + var initSegmentData = (_frag$initSegment = frag.initSegment) === null || _frag$initSegment === void 0 ? void 0 : _frag$initSegment.data; + + if (initPTS !== undefined) { + // this.log(`Transmuxing ${sn} of [${details.startSN} ,${details.endSN}],track ${trackId}`); + // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live) + var accurateTimeOffset = false; // details.PTSKnown || !details.live; + + var partIndex = part ? part.index : -1; + var partial = partIndex !== -1; + var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial); + transmuxer.push(payload, initSegmentData, audioCodec, "", frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS); + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log("Unknown video PTS for cc " + frag.cc + ", waiting for video PTS before demuxing audio frag " + frag.sn + " of [" + details.startSN + " ," + details.endSN + "],track " + trackId); + + var _this$waitingData = (this.waitingData = this.waitingData || { + frag: frag, + part: part, + cache: new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__["default"](), + complete: false, + }), + cache = _this$waitingData.cache; + + cache.push(new Uint8Array(payload)); + this.waitingVideoCC = this.videoTrackCC; + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS; + } + }; + + _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedData) { + if (this.waitingData) { + this.waitingData.complete = true; + return; + } + + _BaseStreamController.prototype._handleFragmentLoadComplete.call(this, fragLoadedData); + }; + + _proto.onBufferReset = function /* event: Events.BUFFER_RESET */ + onBufferReset() { + // reset reference to sourcebuffers + this.mediaBuffer = this.videoBuffer = null; + this.loadedmetadata = false; + }; + + _proto.onBufferCreated = function onBufferCreated(event, data) { + var audioTrack = data.tracks.audio; + + if (audioTrack) { + this.mediaBuffer = audioTrack.buffer; + } + + if (data.tracks.video) { + this.videoBuffer = data.tracks.video.buffer; + } + }; + + _proto.onFragBuffered = function onFragBuffered(event, data) { + var frag = data.frag, + part = data.part; + + if (frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO) { + return; + } + + if (this.fragContextChanged(frag)) { + // If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion + // Avoid setting state back to IDLE or concluding the audio switch; otherwise, the switched-to track will not buffer + this.warn("Fragment " + frag.sn + (part ? " p: " + part.index : "") + " of level " + frag.level + " finished buffering, but was aborted. state: " + this.state + ", audioSwitch: " + this.audioSwitch); + return; + } + + if (frag.sn !== "initSegment") { + this.fragPrevious = frag; + + if (this.audioSwitch) { + this.audioSwitch = false; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHED, { + id: this.trackId, + }); + } + } + + this.fragBufferedComplete(frag, part); + }; + + _proto.onError = function onError(event, data) { + switch (data.details) { + case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].FRAG_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].FRAG_LOAD_TIMEOUT: + case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].KEY_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].KEY_LOAD_TIMEOUT: + // TODO: Skip fragments that do not belong to this.fragCurrent audio-group id + this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO, data); + break; + + case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].AUDIO_TRACK_LOAD_TIMEOUT: + // when in ERROR state, don't switch back to IDLE state in case a non-fatal error is received + if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR && this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED) { + // if fatal error, stop processing, otherwise move to IDLE to retry loading + this.state = data.fatal ? _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR : _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + this.warn(data.details + " while loading frag, switching to " + this.state + " state"); + } + + break; + + case _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].BUFFER_FULL_ERROR: + // if in appending state + if (data.parent === "audio" && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSED)) { + var flushBuffer = true; + var bufferedInfo = this.getFwdBufferInfo(this.mediaBuffer, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO); // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end + // reduce max buf len if current position is buffered + + if (bufferedInfo && bufferedInfo.len > 0.5) { + flushBuffer = !this.reduceMaxBufferLength(bufferedInfo.len); + } + + if (flushBuffer) { + // current position is not buffered, but browser is still complaining about buffer full error + // this happens on IE/Edge, refer to https://github.com/video-dev/CiderHls.js/pull/708 + // in that case flush the whole audio buffer to recover + this.warn("Buffer full error also media.currentTime is not buffered, flush audio buffer"); + this.fragCurrent = null; + + _BaseStreamController.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, "audio"); + } + + this.resetLoadingState(); + } + + break; + + default: + break; + } + }; + + _proto.onBufferFlushed = function onBufferFlushed(event, _ref3) { + var type = _ref3.type; + + if (type === _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO) { + this.bufferFlushed = true; + } + }; + + _proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) { + var _id3$samples; + + var id = "audio"; + var CiderHls = this.CiderHls; + var remuxResult = transmuxResult.remuxResult, + chunkMeta = transmuxResult.chunkMeta; + var context = this.getCurrentContext(chunkMeta); + + if (!context) { + this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered."); + this.resetLiveStartWhenNotLoaded(chunkMeta.level); + return; + } + + var frag = context.frag, + part = context.part; + var audio = remuxResult.audio, + text = remuxResult.text, + id3 = remuxResult.id3, + initSegment = remuxResult.initSegment; // Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level. + // If we are, subsequently check if the currently loading fragment (fragCurrent) has changed. + + if (this.fragContextChanged(frag)) { + return; + } + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING; + + if (this.audioSwitch && audio) { + this.completeAudioSwitch(); + } + + if (initSegment !== null && initSegment !== void 0 && initSegment.tracks) { + this._bufferInitSegment(initSegment.tracks, frag, chunkMeta); + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_PARSING_INIT_SEGMENT, { + frag: frag, + id: id, + tracks: initSegment.tracks, + }); // Only flush audio from old audio tracks when PTS is known on new audio track + } + + if (audio) { + var startPTS = audio.startPTS, + endPTS = audio.endPTS, + startDTS = audio.startDTS, + endDTS = audio.endDTS; + + if (part) { + part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO] = { + startPTS: startPTS, + endPTS: endPTS, + startDTS: startDTS, + endDTS: endDTS, + }; + } + + frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO, startPTS, endPTS, startDTS, endDTS); + this.bufferFragmentData(audio, frag, part, chunkMeta); + } + + if (id3 !== null && id3 !== void 0 && (_id3$samples = id3.samples) !== null && _id3$samples !== void 0 && _id3$samples.length) { + var emittedID3 = _extends( + { + frag: frag, + id: id, + }, + id3 + ); + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_PARSING_METADATA, emittedID3); + } + + if (text) { + var emittedText = _extends( + { + frag: frag, + id: id, + }, + text + ); + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].FRAG_PARSING_USERDATA, emittedText); + } + }; + + _proto._bufferInitSegment = function _bufferInitSegment(tracks, frag, chunkMeta) { + if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING) { + return; + } // delete any video track found on audio transmuxer + + if (tracks.video) { + delete tracks.video; + } // include levelCodec in audio and video tracks + + var track = tracks.audio; + + if (!track) { + return; + } + + track.levelCodec = track.codec; + track.id = "audio"; + this.log("Init audio buffer, container:" + track.container + ", codecs[parsed]=[" + track.codec + "]"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_CODECS, tracks); + var initSegment = track.initSegment; + + if (initSegment !== null && initSegment !== void 0 && initSegment.byteLength) { + var segment = { + type: "audio", + frag: frag, + part: null, + chunkMeta: chunkMeta, + parent: frag.type, + data: initSegment, + }; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].BUFFER_APPENDING, segment); + } // trigger handler right now + + this.tick(); + }; + + _proto.loadFragment = function loadFragment(frag, trackDetails, targetBufferTime) { + // only load if fragment is not loaded or if in audio switch + var fragState = this.fragmentTracker.getState(frag); + this.fragCurrent = frag; // we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch + + if (this.audioSwitch || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__["FragmentState"].NOT_LOADED || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__["FragmentState"].PARTIAL) { + if (frag.sn === "initSegment") { + this._loadInitSegment(frag); + } else if (trackDetails.live && !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.initPTS[frag.cc])) { + this.log("Waiting for video PTS in continuity counter " + frag.cc + " of live stream before loading audio fragment " + frag.sn + " of level " + this.trackId); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_INIT_PTS; + } else { + this.startFragRequested = true; + + _BaseStreamController.prototype.loadFragment.call(this, frag, trackDetails, targetBufferTime); + } + } + }; + + _proto.completeAudioSwitch = function completeAudioSwitch() { + var CiderHls = this.CiderHls, + media = this.media, + trackId = this.trackId; + + if (media) { + this.log("Switching audio track : flushing all audio"); + + _BaseStreamController.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, "audio"); + } + + this.audioSwitch = false; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].AUDIO_TRACK_SWITCHED, { + id: trackId, + }); + }; + + return AudioStreamController; + })(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]); + + /* harmony default export */ __webpack_exports__["default"] = AudioStreamController; + + /***/ + }, + + /***/ "./src/controller/audio-track-controller.ts": + /*!**************************************************!*\ !*** ./src/controller/audio-track-controller.ts ***! \**************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + var AudioTrackController = /*#__PURE__*/ (function (_BasePlaylistControll) { + _inheritsLoose(AudioTrackController, _BasePlaylistControll); + function AudioTrackController(CiderHls) { + var _this; + _this = _BasePlaylistControll.call(this, CiderHls, "[audio-track-controller]") || this; + _this.tracks = []; + _this.groupId = null; + _this.tracksInGroup = []; + _this.trackId = -1; + _this.trackName = ""; + _this.selectDefaultTrack = true; + _this.registerListeners(); + return _this; + } + var _proto = AudioTrackController.prototype; -var AudioTrackController = /*#__PURE__*/function (_BasePlaylistControll) { - _inheritsLoose(AudioTrackController, _BasePlaylistControll); + _proto.registerListeners = function registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); + }; - function AudioTrackController(CiderHls) { - var _this; + _proto.unregisterListeners = function unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); + }; - _this = _BasePlaylistControll.call(this, CiderHls, '[audio-track-controller]') || this; - _this.tracks = []; - _this.groupId = null; - _this.tracksInGroup = []; - _this.trackId = -1; - _this.trackName = ''; - _this.selectDefaultTrack = true; + _proto.destroy = function destroy() { + this.unregisterListeners(); + this.tracks.length = 0; + this.tracksInGroup.length = 0; - _this.registerListeners(); + _BasePlaylistControll.prototype.destroy.call(this); + }; - return _this; - } + _proto.onManifestLoading = function onManifestLoading() { + this.tracks = []; + this.groupId = null; + this.tracksInGroup = []; + this.trackId = -1; + this.trackName = ""; + this.selectDefaultTrack = true; + }; - var _proto = AudioTrackController.prototype; + _proto.onManifestParsed = function onManifestParsed(event, data) { + this.tracks = data.audioTracks || []; + }; - _proto.registerListeners = function registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); - }; + _proto.onAudioTrackLoaded = function onAudioTrackLoaded(event, data) { + var id = data.id, + details = data.details; + var currentTrack = this.tracksInGroup[id]; - _proto.unregisterListeners = function unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); - }; + if (!currentTrack) { + this.warn("Invalid audio track id " + id); + return; + } - _proto.destroy = function destroy() { - this.unregisterListeners(); - this.tracks.length = 0; - this.tracksInGroup.length = 0; + var curDetails = currentTrack.details; + currentTrack.details = data.details; + this.log("audioTrack " + id + " loaded [" + details.startSN + "-" + details.endSN + "]"); - _BasePlaylistControll.prototype.destroy.call(this); - }; + if (id === this.trackId) { + this.retryCount = 0; + this.playlistLoaded(id, data, curDetails); + } + }; - _proto.onManifestLoading = function onManifestLoading() { - this.tracks = []; - this.groupId = null; - this.tracksInGroup = []; - this.trackId = -1; - this.trackName = ''; - this.selectDefaultTrack = true; - }; + _proto.onLevelLoading = function onLevelLoading(event, data) { + this.switchLevel(data.level); + }; - _proto.onManifestParsed = function onManifestParsed(event, data) { - this.tracks = data.audioTracks || []; - }; + _proto.onLevelSwitching = function onLevelSwitching(event, data) { + this.switchLevel(data.level); + }; - _proto.onAudioTrackLoaded = function onAudioTrackLoaded(event, data) { - var id = data.id, - details = data.details; - var currentTrack = this.tracksInGroup[id]; + _proto.switchLevel = function switchLevel(levelIndex) { + var levelInfo = this.CiderHls.levels[levelIndex]; - if (!currentTrack) { - this.warn("Invalid audio track id " + id); - return; - } + if (!(levelInfo !== null && levelInfo !== void 0 && levelInfo.audioGroupIds)) { + return; + } - var curDetails = currentTrack.details; - currentTrack.details = data.details; - this.log("audioTrack " + id + " loaded [" + details.startSN + "-" + details.endSN + "]"); + var audioGroupId = levelInfo.audioGroupIds[levelInfo.urlId]; - if (id === this.trackId) { - this.retryCount = 0; - this.playlistLoaded(id, data, curDetails); - } - }; + if (this.groupId !== audioGroupId) { + this.groupId = audioGroupId; + var audioTracks = this.tracks.filter(function (track) { + return !audioGroupId || track.groupId === audioGroupId; + }); // Disable selectDefaultTrack if there are no default tracks - _proto.onLevelLoading = function onLevelLoading(event, data) { - this.switchLevel(data.level); - }; + if ( + this.selectDefaultTrack && + !audioTracks.some(function (track) { + return track.default; + }) + ) { + this.selectDefaultTrack = false; + } - _proto.onLevelSwitching = function onLevelSwitching(event, data) { - this.switchLevel(data.level); - }; + this.tracksInGroup = audioTracks; + var audioTracksUpdated = { + audioTracks: audioTracks, + }; + this.log("Updating audio tracks, " + audioTracks.length + ' track(s) found in "' + audioGroupId + '" group-id'); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACKS_UPDATED, audioTracksUpdated); + this.selectInitialTrack(); + } + }; - _proto.switchLevel = function switchLevel(levelIndex) { - var levelInfo = this.CiderHls.levels[levelIndex]; + _proto.onError = function onError(event, data) { + _BasePlaylistControll.prototype.onError.call(this, event, data); - if (!(levelInfo !== null && levelInfo !== void 0 && levelInfo.audioGroupIds)) { - return; - } + if (data.fatal || !data.context) { + return; + } - var audioGroupId = levelInfo.audioGroupIds[levelInfo.urlId]; + if (data.context.type === _types_loader__WEBPACK_IMPORTED_MODULE_3__["PlaylistContextType"].AUDIO_TRACK && data.context.id === this.trackId && data.context.groupId === this.groupId) { + this.retryLoadingOrFail(data); + } + }; - if (this.groupId !== audioGroupId) { - this.groupId = audioGroupId; - var audioTracks = this.tracks.filter(function (track) { - return !audioGroupId || track.groupId === audioGroupId; - }); // Disable selectDefaultTrack if there are no default tracks + _proto.setAudioTrack = function setAudioTrack(newId) { + var tracks = this.tracksInGroup; // check if level idx is valid - if (this.selectDefaultTrack && !audioTracks.some(function (track) { - return track.default; - })) { - this.selectDefaultTrack = false; - } + if (newId < 0 || newId >= tracks.length) { + this.warn("Invalid id passed to audio-track controller"); + return; + } // stopping live reloading timer if any - this.tracksInGroup = audioTracks; - var audioTracksUpdated = { - audioTracks: audioTracks - }; - this.log("Updating audio tracks, " + audioTracks.length + " track(s) found in \"" + audioGroupId + "\" group-id"); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACKS_UPDATED, audioTracksUpdated); - this.selectInitialTrack(); - } - }; + this.clearTimer(); + var lastTrack = tracks[this.trackId]; + this.log("Now switching to audio-track index " + newId); + var track = tracks[newId]; + var id = track.id, + _track$groupId = track.groupId, + groupId = _track$groupId === void 0 ? "" : _track$groupId, + name = track.name, + type = track.type, + url = track.url; + this.trackId = newId; + this.trackName = name; + this.selectDefaultTrack = false; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_SWITCHING, { + id: id, + groupId: groupId, + name: name, + type: type, + url: url, + }); // Do not reload track unless live - _proto.onError = function onError(event, data) { - _BasePlaylistControll.prototype.onError.call(this, event, data); + if (track.details && !track.details.live) { + return; + } - if (data.fatal || !data.context) { - return; - } + var CiderHlsUrlParameters = this.switchParams(track.url, lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.details); + this.loadPlaylist(CiderHlsUrlParameters); + }; - if (data.context.type === _types_loader__WEBPACK_IMPORTED_MODULE_3__["PlaylistContextType"].AUDIO_TRACK && data.context.id === this.trackId && data.context.groupId === this.groupId) { - this.retryLoadingOrFail(data); - } - }; + _proto.selectInitialTrack = function selectInitialTrack() { + var audioTracks = this.tracksInGroup; + console.assert(audioTracks.length, "Initial audio track should be selected when tracks are known"); + var currentAudioTrackName = this.trackName; + var trackId = this.findTrackId(currentAudioTrackName) || this.findTrackId(); - _proto.setAudioTrack = function setAudioTrack(newId) { - var tracks = this.tracksInGroup; // check if level idx is valid + if (trackId !== -1) { + this.setAudioTrack(trackId); + } else { + this.warn("No track found for running audio group-ID: " + this.groupId); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR, + fatal: true, + }); + } + }; - if (newId < 0 || newId >= tracks.length) { - this.warn('Invalid id passed to audio-track controller'); - return; - } // stopping live reloading timer if any + _proto.findTrackId = function findTrackId(name) { + var audioTracks = this.tracksInGroup; + for (var i = 0; i < audioTracks.length; i++) { + var track = audioTracks[i]; - this.clearTimer(); - var lastTrack = tracks[this.trackId]; - this.log("Now switching to audio-track index " + newId); - var track = tracks[newId]; - var id = track.id, - _track$groupId = track.groupId, - groupId = _track$groupId === void 0 ? '' : _track$groupId, - name = track.name, - type = track.type, - url = track.url; - this.trackId = newId; - this.trackName = name; - this.selectDefaultTrack = false; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_SWITCHING, { - id: id, - groupId: groupId, - name: name, - type: type, - url: url - }); // Do not reload track unless live + if (!this.selectDefaultTrack || track.default) { + if (!name || name === track.name) { + return track.id; + } + } + } - if (track.details && !track.details.live) { - return; - } + return -1; + }; - var CiderHlsUrlParameters = this.switchParams(track.url, lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.details); - this.loadPlaylist(CiderHlsUrlParameters); - }; + _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) { + var audioTrack = this.tracksInGroup[this.trackId]; - _proto.selectInitialTrack = function selectInitialTrack() { - var audioTracks = this.tracksInGroup; - console.assert(audioTracks.length, 'Initial audio track should be selected when tracks are known'); - var currentAudioTrackName = this.trackName; - var trackId = this.findTrackId(currentAudioTrackName) || this.findTrackId(); + if (this.shouldLoadTrack(audioTrack)) { + var id = audioTrack.id; + var groupId = audioTrack.groupId; + var url = audioTrack.url; - if (trackId !== -1) { - this.setAudioTrack(trackId); - } else { - this.warn("No track found for running audio group-ID: " + this.groupId); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR, - fatal: true - }); - } - }; + if (CiderHlsUrlParameters) { + try { + url = CiderHlsUrlParameters.addDirectives(url); + } catch (error) { + this.warn("Could not construct new URL with CiderHls Delivery Directives: " + error); + } + } // track not retrieved yet, or live playlist we need to (re)load it - _proto.findTrackId = function findTrackId(name) { - var audioTracks = this.tracksInGroup; + this.log("loading audio-track playlist for id: " + id); + this.clearTimer(); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_LOADING, { + url: url, + id: id, + groupId: groupId, + deliveryDirectives: CiderHlsUrlParameters || null, + }); + } + }; - for (var i = 0; i < audioTracks.length; i++) { - var track = audioTracks[i]; + _createClass(AudioTrackController, [ + { + key: "audioTracks", + get: function get() { + return this.tracksInGroup; + }, + }, + { + key: "audioTrack", + get: function get() { + return this.trackId; + }, + set: function set(newId) { + // If audio track is selected from API then don't choose from the manifest default track + this.selectDefaultTrack = false; + this.setAudioTrack(newId); + }, + }, + ]); - if (!this.selectDefaultTrack || track.default) { - if (!name || name === track.name) { - return track.id; - } - } - } + return AudioTrackController; + })(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]); - return -1; - }; + /* harmony default export */ __webpack_exports__["default"] = AudioTrackController; - _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) { - var audioTrack = this.tracksInGroup[this.trackId]; + /***/ + }, - if (this.shouldLoadTrack(audioTrack)) { - var id = audioTrack.id; - var groupId = audioTrack.groupId; - var url = audioTrack.url; - - if (CiderHlsUrlParameters) { - try { - url = CiderHlsUrlParameters.addDirectives(url); - } catch (error) { - this.warn("Could not construct new URL with CiderHls Delivery Directives: " + error); - } - } // track not retrieved yet, or live playlist we need to (re)load it - - - this.log("loading audio-track playlist for id: " + id); - this.clearTimer(); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].AUDIO_TRACK_LOADING, { - url: url, - id: id, - groupId: groupId, - deliveryDirectives: CiderHlsUrlParameters || null - }); - } - }; - - _createClass(AudioTrackController, [{ - key: "audioTracks", - get: function get() { - return this.tracksInGroup; - } - }, { - key: "audioTrack", - get: function get() { - return this.trackId; - }, - set: function set(newId) { - // If audio track is selected from API then don't choose from the manifest default track - this.selectDefaultTrack = false; - this.setAudioTrack(newId); - } - }]); - - return AudioTrackController; -}(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]); - -/* harmony default export */ __webpack_exports__["default"] = (AudioTrackController); - -/***/ }), - -/***/ "./src/controller/base-playlist-controller.ts": -/*!****************************************************!*\ + /***/ "./src/controller/base-playlist-controller.ts": + /*!****************************************************!*\ !*** ./src/controller/base-playlist-controller.ts ***! \****************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return BasePlaylistController; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); + /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BasePlaylistController; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); -/* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + var BasePlaylistController = /*#__PURE__*/ (function () { + function BasePlaylistController(CiderHls, logPrefix) { + this.CiderHls = void 0; + this.timer = -1; + this.canLoad = false; + this.retryCount = 0; + this.log = void 0; + this.warn = void 0; + this.log = _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"], logPrefix + ":"); + this.warn = _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"], logPrefix + ":"); + this.CiderHls = CiderHls; + } + var _proto = BasePlaylistController.prototype; + _proto.destroy = function destroy() { + this.clearTimer(); // @ts-ignore + this.CiderHls = this.log = this.warn = null; + }; + _proto.onError = function onError(event, data) { + if (data.fatal && data.type === _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].NETWORK_ERROR) { + this.clearTimer(); + } + }; + _proto.clearTimer = function clearTimer() { + clearTimeout(this.timer); + this.timer = -1; + }; + _proto.startLoad = function startLoad() { + this.canLoad = true; + this.retryCount = 0; + this.loadPlaylist(); + }; -var BasePlaylistController = /*#__PURE__*/function () { - function BasePlaylistController(CiderHls, logPrefix) { - this.CiderHls = void 0; - this.timer = -1; - this.canLoad = false; - this.retryCount = 0; - this.log = void 0; - this.warn = void 0; - this.log = _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"], logPrefix + ":"); - this.warn = _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"], logPrefix + ":"); - this.CiderHls = CiderHls; - } + _proto.stopLoad = function stopLoad() { + this.canLoad = false; + this.clearTimer(); + }; - var _proto = BasePlaylistController.prototype; + _proto.switchParams = function switchParams(playlistUri, previous) { + var renditionReports = previous === null || previous === void 0 ? void 0 : previous.renditionReports; - _proto.destroy = function destroy() { - this.clearTimer(); // @ts-ignore + if (renditionReports) { + for (var i = 0; i < renditionReports.length; i++) { + var attr = renditionReports[i]; + var uri = "" + attr.URI; - this.CiderHls = this.log = this.warn = null; - }; + if (uri === playlistUri.substr(-uri.length)) { + var msn = parseInt(attr["LAST-MSN"]); + var part = parseInt(attr["LAST-PART"]); - _proto.onError = function onError(event, data) { - if (data.fatal && data.type === _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].NETWORK_ERROR) { - this.clearTimer(); - } - }; + if (previous && this.CiderHls.config.lowLatencyMode) { + var currentGoal = Math.min(previous.age - previous.partTarget, previous.targetduration); - _proto.clearTimer = function clearTimer() { - clearTimeout(this.timer); - this.timer = -1; - }; + if (part !== undefined && currentGoal > previous.partTarget) { + part += 1; + } + } - _proto.startLoad = function startLoad() { - this.canLoad = true; - this.retryCount = 0; - this.loadPlaylist(); - }; + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(msn)) { + return new _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsUrlParameters"]( + msn, + Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(part) ? part : undefined, + _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsSkip"].No + ); + } + } + } + } + }; - _proto.stopLoad = function stopLoad() { - this.canLoad = false; - this.clearTimer(); - }; + _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) {}; - _proto.switchParams = function switchParams(playlistUri, previous) { - var renditionReports = previous === null || previous === void 0 ? void 0 : previous.renditionReports; + _proto.shouldLoadTrack = function shouldLoadTrack(track) { + return this.canLoad && track && !!track.url && (!track.details || track.details.live); + }; - if (renditionReports) { - for (var i = 0; i < renditionReports.length; i++) { - var attr = renditionReports[i]; - var uri = '' + attr.URI; + _proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) { + var _this = this; - if (uri === playlistUri.substr(-uri.length)) { - var msn = parseInt(attr['LAST-MSN']); - var part = parseInt(attr['LAST-PART']); + var details = data.details, + stats = data.stats; // Set last updated date-time - if (previous && this.CiderHls.config.lowLatencyMode) { - var currentGoal = Math.min(previous.age - previous.partTarget, previous.targetduration); + var elapsed = stats.loading.end ? Math.max(0, self.performance.now() - stats.loading.end) : 0; + details.advancedDateTime = Date.now() - elapsed; // if current playlist is a live playlist, arm a timer to reload it - if (part !== undefined && currentGoal > previous.partTarget) { - part += 1; - } - } + if (details.live || (previousDetails !== null && previousDetails !== void 0 && previousDetails.live)) { + details.reloaded(previousDetails); - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(msn)) { - return new _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsUrlParameters"](msn, Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(part) ? part : undefined, _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsSkip"].No); - } - } - } - } - }; + if (previousDetails) { + this.log("live playlist " + index + " " + (details.advanced ? "REFRESHED " + details.lastPartSn + "-" + details.lastPartIndex : "MISSED")); + } // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments - _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) {}; + if (previousDetails && details.fragments.length > 0) { + Object(_level_helper__WEBPACK_IMPORTED_MODULE_2__["mergeDetails"])(previousDetails, details); + } - _proto.shouldLoadTrack = function shouldLoadTrack(track) { - return this.canLoad && track && !!track.url && (!track.details || track.details.live); - }; + if (!this.canLoad || !details.live) { + return; + } - _proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) { - var _this = this; + var deliveryDirectives; + var msn = undefined; + var part = undefined; - var details = data.details, - stats = data.stats; // Set last updated date-time + if (details.canBlockReload && details.endSN && details.advanced) { + // Load level with LL-CiderHls delivery directives + var lowLatencyMode = this.CiderHls.config.lowLatencyMode; + var lastPartSn = details.lastPartSn; + var endSn = details.endSN; + var lastPartIndex = details.lastPartIndex; + var hasParts = lastPartIndex !== -1; + var lastPart = lastPartSn === endSn; // When low latency mode is disabled, we'll skip part requests once the last part index is found - var elapsed = stats.loading.end ? Math.max(0, self.performance.now() - stats.loading.end) : 0; - details.advancedDateTime = Date.now() - elapsed; // if current playlist is a live playlist, arm a timer to reload it + var nextSnStartIndex = lowLatencyMode ? 0 : lastPartIndex; - if (details.live || previousDetails !== null && previousDetails !== void 0 && previousDetails.live) { - details.reloaded(previousDetails); + if (hasParts) { + msn = lastPart ? endSn + 1 : lastPartSn; + part = lastPart ? nextSnStartIndex : lastPartIndex + 1; + } else { + msn = endSn + 1; + } // Low-Latency CDN Tune-in: "age" header and time since load indicates we're behind by more than one part + // Update directives to obtain the Playlist that has the estimated additional duration of media - if (previousDetails) { - this.log("live playlist " + index + " " + (details.advanced ? 'REFRESHED ' + details.lastPartSn + '-' + details.lastPartIndex : 'MISSED')); - } // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments + var lastAdvanced = details.age; + var cdnAge = lastAdvanced + details.ageHeader; + var currentGoal = Math.min(cdnAge - details.partTarget, details.targetduration * 1.5); + if (currentGoal > 0) { + if (previousDetails && currentGoal > previousDetails.tuneInGoal) { + // If we attempted to get the next or latest playlist update, but currentGoal increased, + // then we either can't catchup, or the "age" header cannot be trusted. + this.warn("CDN Tune-in goal increased from: " + previousDetails.tuneInGoal + " to: " + currentGoal + " with playlist age: " + details.age); + currentGoal = 0; + } else { + var segments = Math.floor(currentGoal / details.targetduration); + msn += segments; - if (previousDetails && details.fragments.length > 0) { - Object(_level_helper__WEBPACK_IMPORTED_MODULE_2__["mergeDetails"])(previousDetails, details); - } + if (part !== undefined) { + var parts = Math.round((currentGoal % details.targetduration) / details.partTarget); + part += parts; + } - if (!this.canLoad || !details.live) { - return; - } + this.log("CDN Tune-in age: " + details.ageHeader + "s last advanced " + lastAdvanced.toFixed(2) + "s goal: " + currentGoal + " skip sn " + segments + " to part " + part); + } - var deliveryDirectives; - var msn = undefined; - var part = undefined; + details.tuneInGoal = currentGoal; + } - if (details.canBlockReload && details.endSN && details.advanced) { - // Load level with LL-CiderHls delivery directives - var lowLatencyMode = this.CiderHls.config.lowLatencyMode; - var lastPartSn = details.lastPartSn; - var endSn = details.endSN; - var lastPartIndex = details.lastPartIndex; - var hasParts = lastPartIndex !== -1; - var lastPart = lastPartSn === endSn; // When low latency mode is disabled, we'll skip part requests once the last part index is found + deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part); - var nextSnStartIndex = lowLatencyMode ? 0 : lastPartIndex; + if (lowLatencyMode || !lastPart) { + this.loadPlaylist(deliveryDirectives); + return; + } + } else { + deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part); + } - if (hasParts) { - msn = lastPart ? endSn + 1 : lastPartSn; - part = lastPart ? nextSnStartIndex : lastPartIndex + 1; - } else { - msn = endSn + 1; - } // Low-Latency CDN Tune-in: "age" header and time since load indicates we're behind by more than one part - // Update directives to obtain the Playlist that has the estimated additional duration of media + var reloadInterval = Object(_level_helper__WEBPACK_IMPORTED_MODULE_2__["computeReloadInterval"])(details, stats); + if (msn !== undefined && details.canBlockReload) { + reloadInterval -= details.partTarget || 1; + } - var lastAdvanced = details.age; - var cdnAge = lastAdvanced + details.ageHeader; - var currentGoal = Math.min(cdnAge - details.partTarget, details.targetduration * 1.5); + this.log("reload live playlist " + index + " in " + Math.round(reloadInterval) + " ms"); + this.timer = self.setTimeout(function () { + return _this.loadPlaylist(deliveryDirectives); + }, reloadInterval); + } else { + this.clearTimer(); + } + }; - if (currentGoal > 0) { - if (previousDetails && currentGoal > previousDetails.tuneInGoal) { - // If we attempted to get the next or latest playlist update, but currentGoal increased, - // then we either can't catchup, or the "age" header cannot be trusted. - this.warn("CDN Tune-in goal increased from: " + previousDetails.tuneInGoal + " to: " + currentGoal + " with playlist age: " + details.age); - currentGoal = 0; - } else { - var segments = Math.floor(currentGoal / details.targetduration); - msn += segments; + _proto.getDeliveryDirectives = function getDeliveryDirectives(details, previousDeliveryDirectives, msn, part) { + var skip = Object(_types_level__WEBPACK_IMPORTED_MODULE_1__["getSkipValue"])(details, msn); - if (part !== undefined) { - var parts = Math.round(currentGoal % details.targetduration / details.partTarget); - part += parts; - } + if (previousDeliveryDirectives !== null && previousDeliveryDirectives !== void 0 && previousDeliveryDirectives.skip && details.deltaUpdateFailed) { + msn = previousDeliveryDirectives.msn; + part = previousDeliveryDirectives.part; + skip = _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsSkip"].No; + } - this.log("CDN Tune-in age: " + details.ageHeader + "s last advanced " + lastAdvanced.toFixed(2) + "s goal: " + currentGoal + " skip sn " + segments + " to part " + part); - } + return new _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsUrlParameters"](msn, part, skip); + }; - details.tuneInGoal = currentGoal; - } + _proto.retryLoadingOrFail = function retryLoadingOrFail(errorEvent) { + var _this2 = this; - deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part); + var config = this.CiderHls.config; + var retry = this.retryCount < config.levelLoadingMaxRetry; - if (lowLatencyMode || !lastPart) { - this.loadPlaylist(deliveryDirectives); - return; - } - } else { - deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part); - } + if (retry) { + var _errorEvent$context; - var reloadInterval = Object(_level_helper__WEBPACK_IMPORTED_MODULE_2__["computeReloadInterval"])(details, stats); + this.retryCount++; - if (msn !== undefined && details.canBlockReload) { - reloadInterval -= details.partTarget || 1; - } + if (errorEvent.details.indexOf("LoadTimeOut") > -1 && (_errorEvent$context = errorEvent.context) !== null && _errorEvent$context !== void 0 && _errorEvent$context.deliveryDirectives) { + // The LL-CiderHls request already timed out so retry immediately + this.warn("retry playlist loading #" + this.retryCount + ' after "' + errorEvent.details + '"'); + this.loadPlaylist(); + } else { + // exponential backoff capped to max retry timeout + var delay = Math.min(Math.pow(2, this.retryCount) * config.levelLoadingRetryDelay, config.levelLoadingMaxRetryTimeout); // Schedule level/track reload - this.log("reload live playlist " + index + " in " + Math.round(reloadInterval) + " ms"); - this.timer = self.setTimeout(function () { - return _this.loadPlaylist(deliveryDirectives); - }, reloadInterval); - } else { - this.clearTimer(); - } - }; + this.timer = self.setTimeout(function () { + return _this2.loadPlaylist(); + }, delay); + this.warn("retry playlist loading #" + this.retryCount + " in " + delay + ' ms after "' + errorEvent.details + '"'); + } + } else { + this.warn('cannot recover from error "' + errorEvent.details + '"'); // stopping live reloading timer if any - _proto.getDeliveryDirectives = function getDeliveryDirectives(details, previousDeliveryDirectives, msn, part) { - var skip = Object(_types_level__WEBPACK_IMPORTED_MODULE_1__["getSkipValue"])(details, msn); + this.clearTimer(); // switch error to fatal - if (previousDeliveryDirectives !== null && previousDeliveryDirectives !== void 0 && previousDeliveryDirectives.skip && details.deltaUpdateFailed) { - msn = previousDeliveryDirectives.msn; - part = previousDeliveryDirectives.part; - skip = _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsSkip"].No; - } + errorEvent.fatal = true; + } - return new _types_level__WEBPACK_IMPORTED_MODULE_1__["CiderHlsUrlParameters"](msn, part, skip); - }; + return retry; + }; - _proto.retryLoadingOrFail = function retryLoadingOrFail(errorEvent) { - var _this2 = this; + return BasePlaylistController; + })(); - var config = this.CiderHls.config; - var retry = this.retryCount < config.levelLoadingMaxRetry; + /***/ + }, - if (retry) { - var _errorEvent$context; - - this.retryCount++; - - if (errorEvent.details.indexOf('LoadTimeOut') > -1 && (_errorEvent$context = errorEvent.context) !== null && _errorEvent$context !== void 0 && _errorEvent$context.deliveryDirectives) { - // The LL-CiderHls request already timed out so retry immediately - this.warn("retry playlist loading #" + this.retryCount + " after \"" + errorEvent.details + "\""); - this.loadPlaylist(); - } else { - // exponential backoff capped to max retry timeout - var delay = Math.min(Math.pow(2, this.retryCount) * config.levelLoadingRetryDelay, config.levelLoadingMaxRetryTimeout); // Schedule level/track reload - - this.timer = self.setTimeout(function () { - return _this2.loadPlaylist(); - }, delay); - this.warn("retry playlist loading #" + this.retryCount + " in " + delay + " ms after \"" + errorEvent.details + "\""); - } - } else { - this.warn("cannot recover from error \"" + errorEvent.details + "\""); // stopping live reloading timer if any - - this.clearTimer(); // switch error to fatal - - errorEvent.fatal = true; - } - - return retry; - }; - - return BasePlaylistController; -}(); - - - -/***/ }), - -/***/ "./src/controller/base-stream-controller.ts": -/*!**************************************************!*\ + /***/ "./src/controller/base-stream-controller.ts": + /*!**************************************************!*\ !*** ./src/controller/base-stream-controller.ts ***! \**************************************************/ -/*! exports provided: State, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "State", function() { return State; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BaseStreamController; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _task_loop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../task-loop */ "./src/task-loop.ts"); -/* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts"); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts"); -/* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts"); -/* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); -/* harmony import */ var _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../loader/fragment-loader */ "./src/loader/fragment-loader.ts"); -/* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts"); -/* harmony import */ var _utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/time-ranges */ "./src/utils/time-ranges.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); - - - - - - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - - - - - - - - - - - - - - - - -var State = { - STOPPED: 'STOPPED', - IDLE: 'IDLE', - KEY_LOADING: 'KEY_LOADING', - FRAG_LOADING: 'FRAG_LOADING', - FRAG_LOADING_WAITING_RETRY: 'FRAG_LOADING_WAITING_RETRY', - WAITING_TRACK: 'WAITING_TRACK', - PARSING: 'PARSING', - PARSED: 'PARSED', - BACKTRACKING: 'BACKTRACKING', - ENDED: 'ENDED', - ERROR: 'ERROR', - WAITING_INIT_PTS: 'WAITING_INIT_PTS', - WAITING_LEVEL: 'WAITING_LEVEL' -}; - -var BaseStreamController = /*#__PURE__*/function (_TaskLoop) { - _inheritsLoose(BaseStreamController, _TaskLoop); - - function BaseStreamController(CiderHls, fragmentTracker, logPrefix) { - var _this; - - _this = _TaskLoop.call(this) || this; - _this.CiderHls = void 0; - _this.fragPrevious = null; - _this.fragCurrent = null; - _this.fragmentTracker = void 0; - _this.transmuxer = null; - _this._state = State.STOPPED; - _this.media = void 0; - _this.mediaBuffer = void 0; - _this.config = void 0; - _this.bitrateTest = false; - _this.lastCurrentTime = 0; - _this.nextLoadPosition = 0; - _this.startPosition = 0; - _this.loadedmetadata = false; - _this.fragLoadError = 0; - _this.retryDate = 0; - _this.levels = null; - _this.fragmentLoader = void 0; - _this.levelLastLoaded = null; - _this.startFragRequested = false; - _this.decrypter = void 0; - _this.initPTS = []; - _this.onvseeking = null; - _this.onvended = null; - _this.logPrefix = ''; - _this.log = void 0; - _this.warn = void 0; - _this.logPrefix = logPrefix; - _this.log = _utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"].log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"], logPrefix + ":"); - _this.warn = _utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"].warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"], logPrefix + ":"); - _this.CiderHls = CiderHls; - _this.fragmentLoader = new _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__["default"](CiderHls.config); - _this.fragmentTracker = fragmentTracker; - _this.config = CiderHls.config; - _this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__["default"](CiderHls, CiderHls.config); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].KEY_LOADED, _this.onKeyLoaded, _assertThisInitialized(_this)); - return _this; - } - - var _proto = BaseStreamController.prototype; - - _proto.doTick = function doTick() { - this.onTickEnd(); - }; - - _proto.onTickEnd = function onTickEnd() {} // eslint-disable-next-line @typescript-eslint/no-unused-vars - ; - - _proto.startLoad = function startLoad(startPosition) {}; - - _proto.stopLoad = function stopLoad() { - this.fragmentLoader.abort(); - var frag = this.fragCurrent; - - if (frag) { - this.fragmentTracker.removeFragment(frag); - } - - this.resetTransmuxer(); - this.fragCurrent = null; - this.fragPrevious = null; - this.clearInterval(); - this.clearNextTick(); - this.state = State.STOPPED; - }; - - _proto._streamEnded = function _streamEnded(bufferInfo, levelDetails) { - var fragCurrent = this.fragCurrent, - fragmentTracker = this.fragmentTracker; // we just got done loading the final fragment and there is no other buffered range after ... - // rationale is that in case there are any buffered ranges after, it means that there are unbuffered portion in between - // so we should not switch to ENDED in that case, to be able to buffer them - - if (!levelDetails.live && fragCurrent && fragCurrent.sn === levelDetails.endSN && !bufferInfo.nextStart) { - var fragState = fragmentTracker.getState(fragCurrent); - return fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].PARTIAL || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].OK; - } - - return false; - }; - - _proto.onMediaAttached = function onMediaAttached(event, data) { - var media = this.media = this.mediaBuffer = data.media; - this.onvseeking = this.onMediaSeeking.bind(this); - this.onvended = this.onMediaEnded.bind(this); - media.addEventListener('seeking', this.onvseeking); - media.addEventListener('ended', this.onvended); - var config = this.config; - - if (this.levels && config.autoStartLoad && this.state === State.STOPPED) { - this.startLoad(config.startPosition); - } - }; - - _proto.onMediaDetaching = function onMediaDetaching() { - var media = this.media; - - if (media !== null && media !== void 0 && media.ended) { - this.log('MSE detaching and video ended, reset startPosition'); - this.startPosition = this.lastCurrentTime = 0; - } // remove video listeners - - - if (media) { - media.removeEventListener('seeking', this.onvseeking); - media.removeEventListener('ended', this.onvended); - this.onvseeking = this.onvended = null; - } - - this.media = this.mediaBuffer = null; - this.loadedmetadata = false; - this.fragmentTracker.removeAllFragments(); - this.stopLoad(); - }; - - _proto.onMediaSeeking = function onMediaSeeking() { - var config = this.config, - fragCurrent = this.fragCurrent, - media = this.media, - mediaBuffer = this.mediaBuffer, - state = this.state; - var currentTime = media ? media.currentTime : 0; - var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(mediaBuffer || media, currentTime, config.maxBufferHole); - this.log("media seeking to " + (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state); - - if (state === State.ENDED) { - this.resetLoadingState(); - } else if (fragCurrent && !bufferInfo.len) { - // check if we are seeking to a unbuffered area AND if frag loading is in progress - var tolerance = config.maxFragLookUpTolerance; - var fragStartOffset = fragCurrent.start - tolerance; - var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance; - var pastFragment = currentTime > fragEndOffset; // check if the seek position is past current fragment, and if so abort loading - - if (currentTime < fragStartOffset || pastFragment) { - if (pastFragment && fragCurrent.loader) { - this.log('seeking outside of buffer while fragment load in progress, cancel fragment load'); - fragCurrent.loader.abort(); - } - - this.resetLoadingState(); - } - } - - if (media) { - this.lastCurrentTime = currentTime; - } // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target - - - if (!this.loadedmetadata && !bufferInfo.len) { - this.nextLoadPosition = this.startPosition = currentTime; - } // Async tick to speed up processing - - - this.tickImmediate(); - }; - - _proto.onMediaEnded = function onMediaEnded() { - // reset startPosition and lastCurrentTime to restart playback @ stream beginning - this.startPosition = this.lastCurrentTime = 0; - }; - - _proto.onKeyLoaded = function onKeyLoaded(event, data) { - if (this.state !== State.KEY_LOADING || data.frag !== this.fragCurrent || !this.levels) { - return; - } - - this.state = State.IDLE; - var levelDetails = this.levels[data.frag.level].details; - - if (levelDetails) { - this.loadFragment(data.frag, levelDetails, data.frag.start); - } - }; - - _proto.onHandlerDestroying = function onHandlerDestroying() { - this.stopLoad(); - - _TaskLoop.prototype.onHandlerDestroying.call(this); - }; - - _proto.onHandlerDestroyed = function onHandlerDestroyed() { - this.state = State.STOPPED; - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].KEY_LOADED, this.onKeyLoaded, this); - - if (this.fragmentLoader) { - this.fragmentLoader.destroy(); - } - - if (this.decrypter) { - this.decrypter.destroy(); - } - - this.CiderHls = this.log = this.warn = this.decrypter = this.fragmentLoader = this.fragmentTracker = null; - - _TaskLoop.prototype.onHandlerDestroyed.call(this); - }; - - _proto.loadKey = function loadKey(frag, details) { - this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level); - this.state = State.KEY_LOADING; - this.fragCurrent = frag; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].KEY_LOADING, { - frag: frag - }); - }; - - _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) { - this._loadFragForPlayback(frag, levelDetails, targetBufferTime); - }; - - _proto._loadFragForPlayback = function _loadFragForPlayback(frag, levelDetails, targetBufferTime) { - var _this2 = this; - - var progressCallback = function progressCallback(data) { - if (_this2.fragContextChanged(frag)) { - _this2.warn("Fragment " + frag.sn + (data.part ? ' p: ' + data.part.index : '') + " of level " + frag.level + " was dropped during download."); - - _this2.fragmentTracker.removeFragment(frag); - - return; - } - - frag.stats.chunkCount++; - - _this2._handleFragmentLoadProgress(data); - }; - - this._doFragLoad(frag, levelDetails, targetBufferTime, progressCallback).then(function (data) { - if (!data) { - // if we're here we probably needed to backtrack or are waiting for more parts - return; - } - - _this2.fragLoadError = 0; - var state = _this2.state; - - if (_this2.fragContextChanged(frag)) { - if (state === State.FRAG_LOADING || state === State.BACKTRACKING || !_this2.fragCurrent && state === State.PARSING) { - _this2.fragmentTracker.removeFragment(frag); - - _this2.state = State.IDLE; - } - - return; - } - - if ('payload' in data) { - _this2.log("Loaded fragment " + frag.sn + " of level " + frag.level); - - _this2.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADED, data); // Tracker backtrack must be called after onFragLoaded to update the fragment entity state to BACKTRACKED - // This happens after handleTransmuxComplete when the worker or progressive is disabled - - - if (_this2.state === State.BACKTRACKING) { - _this2.fragmentTracker.backtrack(frag, data); - - _this2.resetFragmentLoading(frag); - - return; - } - } // Pass through the whole payload; controllers not implementing progressive loading receive data from this callback - - - _this2._handleFragmentLoadComplete(data); - }).catch(function (reason) { - _this2.warn(reason); - - _this2.resetFragmentLoading(frag); - }); - }; - - _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset, type) { - if (type === void 0) { - type = null; - } - - if (!(startOffset - endOffset)) { - return; - } // When alternate audio is playing, the audio-stream-controller is responsible for the audio buffer. Otherwise, - // passing a null type flushes both buffers - - - var flushScope = { - startOffset: startOffset, - endOffset: endOffset, - type: type - }; // Reset load errors on flush - - this.fragLoadError = 0; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].BUFFER_FLUSHING, flushScope); - }; - - _proto._loadInitSegment = function _loadInitSegment(frag) { - var _this3 = this; - - this._doFragLoad(frag).then(function (data) { - if (!data || _this3.fragContextChanged(frag) || !_this3.levels) { - throw new Error('init load aborted'); - } - - return data; - }).then(function (data) { - var CiderHls = _this3.CiderHls; - var payload = data.payload; - var decryptData = frag.decryptdata; // check to see if the payload needs to be decrypted - - if (payload && payload.byteLength > 0 && decryptData && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') { - var startTime = self.performance.now(); // decrypt the subtitles - - return _this3.decrypter.webCryptoDecrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).then(function (decryptedData) { - var endTime = self.performance.now(); - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_DECRYPTED, { - frag: frag, - payload: decryptedData, - stats: { - tstart: startTime, - tdecrypt: endTime - } - }); - data.payload = decryptedData; - return data; - }); - } - - return data; - }).then(function (data) { - var fragCurrent = _this3.fragCurrent, - CiderHls = _this3.CiderHls, - levels = _this3.levels; - - if (!levels) { - throw new Error('init load aborted, missing levels'); - } - - var details = levels[frag.level].details; - console.assert(details, 'Level details are defined when init segment is loaded'); - var stats = frag.stats; - _this3.state = State.IDLE; - _this3.fragLoadError = 0; - frag.data = new Uint8Array(data.payload); - stats.parsing.start = stats.buffering.start = self.performance.now(); - stats.parsing.end = stats.buffering.end = self.performance.now(); // Silence FRAG_BUFFERED event if fragCurrent is null - - if (data.frag === fragCurrent) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_BUFFERED, { - stats: stats, - frag: fragCurrent, - part: null, - id: frag.type - }); - } - - _this3.tick(); - }).catch(function (reason) { - _this3.warn(reason); - - _this3.resetFragmentLoading(frag); - }); - }; - - _proto.fragContextChanged = function fragContextChanged(frag) { - var fragCurrent = this.fragCurrent; - return !frag || !fragCurrent || frag.level !== fragCurrent.level || frag.sn !== fragCurrent.sn || frag.urlId !== fragCurrent.urlId; - }; - - _proto.fragBufferedComplete = function fragBufferedComplete(frag, part) { - var media = this.mediaBuffer ? this.mediaBuffer : this.media; - this.log("Buffered " + frag.type + " sn: " + frag.sn + (part ? ' part: ' + part.index : '') + " of " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level + " " + _utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__["default"].toString(_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].getBuffered(media))); - this.state = State.IDLE; - this.tick(); - }; - - _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedEndData) { - var transmuxer = this.transmuxer; - - if (!transmuxer) { - return; - } - - var frag = fragLoadedEndData.frag, - part = fragLoadedEndData.part, - partsLoaded = fragLoadedEndData.partsLoaded; // If we did not load parts, or loaded all parts, we have complete (not partial) fragment data - - var complete = !partsLoaded || partsLoaded.length === 0 || partsLoaded.some(function (fragLoaded) { - return !fragLoaded; - }); - var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount + 1, 0, part ? part.index : -1, !complete); - transmuxer.flush(chunkMeta); - } // eslint-disable-next-line @typescript-eslint/no-unused-vars - ; - - _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(frag) {}; - - _proto._doFragLoad = function _doFragLoad(frag, details, targetBufferTime, progressCallback) { - var _this4 = this; - - if (targetBufferTime === void 0) { - targetBufferTime = null; - } - - if (!this.levels) { - throw new Error('frag load aborted, missing levels'); - } - - targetBufferTime = Math.max(frag.start, targetBufferTime || 0); - - if (this.config.lowLatencyMode && details) { - var partList = details.partList; - - if (partList && progressCallback) { - if (targetBufferTime > frag.end && details.fragmentHint) { - frag = details.fragmentHint; - } - - var partIndex = this.getNextPart(partList, frag, targetBufferTime); - - if (partIndex > -1) { - var part = partList[partIndex]; - this.log("Loading part sn: " + frag.sn + " p: " + part.index + " cc: " + frag.cc + " of playlist [" + details.startSN + "-" + details.endSN + "] parts [0-" + partIndex + "-" + (partList.length - 1) + "] " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3))); - this.nextLoadPosition = part.start + part.duration; - this.state = State.FRAG_LOADING; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADING, { - frag: frag, - part: partList[partIndex], - targetBufferTime: targetBufferTime - }); - return this.doFragPartsLoad(frag, partList, partIndex, progressCallback).catch(function (error) { - return _this4.handleFragLoadError(error); - }); - } else if (!frag.url || this.loadedEndOfParts(partList, targetBufferTime)) { - // Fragment hint has no parts - return Promise.resolve(null); - } - } - } - - this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : '') + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3))); // Don't update nextLoadPosition for fragments which are not buffered - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.sn) && !this.bitrateTest) { - this.nextLoadPosition = frag.start + frag.duration; - } - - this.state = State.FRAG_LOADING; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADING, { - frag: frag, - targetBufferTime: targetBufferTime - }); - return this.fragmentLoader.load(frag, progressCallback).catch(function (error) { - return _this4.handleFragLoadError(error); - }); - }; - - _proto.doFragPartsLoad = function doFragPartsLoad(frag, partList, partIndex, progressCallback) { - var _this5 = this; - - return new Promise(function (resolve, reject) { - var partsLoaded = []; - - var loadPartIndex = function loadPartIndex(index) { - var part = partList[index]; - - _this5.fragmentLoader.loadPart(frag, part, progressCallback).then(function (partLoadedData) { - partsLoaded[part.index] = partLoadedData; - var loadedPart = partLoadedData.part; - - _this5.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADED, partLoadedData); - - var nextPart = partList[index + 1]; - - if (nextPart && nextPart.fragment === frag) { - loadPartIndex(index + 1); - } else { - return resolve({ - frag: frag, - part: loadedPart, - partsLoaded: partsLoaded + /*! exports provided: State, default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "State", function () { + return State; }); - } - }).catch(reject); - }; + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return BaseStreamController; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _task_loop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../task-loop */ "./src/task-loop.ts"); + /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts"); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts"); + /* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts"); + /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); + /* harmony import */ var _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../loader/fragment-loader */ "./src/loader/fragment-loader.ts"); + /* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts"); + /* harmony import */ var _utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/time-ranges */ "./src/utils/time-ranges.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); - loadPartIndex(partIndex); - }); - }; + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - _proto.handleFragLoadError = function handleFragLoadError(_ref) { - var data = _ref.data; + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } - if (data && data.details === _errors__WEBPACK_IMPORTED_MODULE_6__["ErrorDetails"].INTERNAL_ABORTED) { - this.handleFragLoadAborted(data.frag, data.part); - } else { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, data); - } + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + return self; + } - return null; - }; + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } - _proto._handleTransmuxerFlush = function _handleTransmuxerFlush(chunkMeta) { - var context = this.getCurrentContext(chunkMeta); + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } - if (!context || this.state !== State.PARSING) { - if (!this.fragCurrent) { - this.state = State.IDLE; - } + var State = { + STOPPED: "STOPPED", + IDLE: "IDLE", + KEY_LOADING: "KEY_LOADING", + FRAG_LOADING: "FRAG_LOADING", + FRAG_LOADING_WAITING_RETRY: "FRAG_LOADING_WAITING_RETRY", + WAITING_TRACK: "WAITING_TRACK", + PARSING: "PARSING", + PARSED: "PARSED", + BACKTRACKING: "BACKTRACKING", + ENDED: "ENDED", + ERROR: "ERROR", + WAITING_INIT_PTS: "WAITING_INIT_PTS", + WAITING_LEVEL: "WAITING_LEVEL", + }; - return; - } + var BaseStreamController = /*#__PURE__*/ (function (_TaskLoop) { + _inheritsLoose(BaseStreamController, _TaskLoop); - var frag = context.frag, - part = context.part, - level = context.level; - var now = self.performance.now(); - frag.stats.parsing.end = now; + function BaseStreamController(CiderHls, fragmentTracker, logPrefix) { + var _this; - if (part) { - part.stats.parsing.end = now; - } + _this = _TaskLoop.call(this) || this; + _this.CiderHls = void 0; + _this.fragPrevious = null; + _this.fragCurrent = null; + _this.fragmentTracker = void 0; + _this.transmuxer = null; + _this._state = State.STOPPED; + _this.media = void 0; + _this.mediaBuffer = void 0; + _this.config = void 0; + _this.bitrateTest = false; + _this.lastCurrentTime = 0; + _this.nextLoadPosition = 0; + _this.startPosition = 0; + _this.loadedmetadata = false; + _this.fragLoadError = 0; + _this.retryDate = 0; + _this.levels = null; + _this.fragmentLoader = void 0; + _this.levelLastLoaded = null; + _this.startFragRequested = false; + _this.decrypter = void 0; + _this.initPTS = []; + _this.onvseeking = null; + _this.onvended = null; + _this.logPrefix = ""; + _this.log = void 0; + _this.warn = void 0; + _this.logPrefix = logPrefix; + _this.log = _utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"].log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"], logPrefix + ":"); + _this.warn = _utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"].warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"], logPrefix + ":"); + _this.CiderHls = CiderHls; + _this.fragmentLoader = new _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__["default"](CiderHls.config); + _this.fragmentTracker = fragmentTracker; + _this.config = CiderHls.config; + _this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__["default"](CiderHls, CiderHls.config); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].KEY_LOADED, _this.onKeyLoaded, _assertThisInitialized(_this)); + return _this; + } - this.updateLevelTiming(frag, part, level, chunkMeta.partial); - }; + var _proto = BaseStreamController.prototype; - _proto.getCurrentContext = function getCurrentContext(chunkMeta) { - var levels = this.levels; - var levelIndex = chunkMeta.level, - sn = chunkMeta.sn, - partIndex = chunkMeta.part; + _proto.doTick = function doTick() { + this.onTickEnd(); + }; - if (!levels || !levels[levelIndex]) { - this.warn("Levels object was unset while buffering fragment " + sn + " of level " + levelIndex + ". The current chunk will not be buffered."); - return null; - } + _proto.onTickEnd = function onTickEnd() {}; // eslint-disable-next-line @typescript-eslint/no-unused-vars - var level = levels[levelIndex]; - var part = partIndex > -1 ? Object(_level_helper__WEBPACK_IMPORTED_MODULE_11__["getPartWith"])(level, sn, partIndex) : null; - var frag = part ? part.fragment : Object(_level_helper__WEBPACK_IMPORTED_MODULE_11__["getFragmentWithSN"])(level, sn, this.fragCurrent); + _proto.startLoad = function startLoad(startPosition) {}; - if (!frag) { - return null; - } + _proto.stopLoad = function stopLoad() { + this.fragmentLoader.abort(); + var frag = this.fragCurrent; - return { - frag: frag, - part: part, - level: level - }; - }; + if (frag) { + this.fragmentTracker.removeFragment(frag); + } - _proto.bufferFragmentData = function bufferFragmentData(data, frag, part, chunkMeta) { - if (!data || this.state !== State.PARSING) { - return; - } + this.resetTransmuxer(); + this.fragCurrent = null; + this.fragPrevious = null; + this.clearInterval(); + this.clearNextTick(); + this.state = State.STOPPED; + }; - var data1 = data.data1, - data2 = data.data2; - var buffer = data1; + _proto._streamEnded = function _streamEnded(bufferInfo, levelDetails) { + var fragCurrent = this.fragCurrent, + fragmentTracker = this.fragmentTracker; // we just got done loading the final fragment and there is no other buffered range after ... + // rationale is that in case there are any buffered ranges after, it means that there are unbuffered portion in between + // so we should not switch to ENDED in that case, to be able to buffer them - if (data1 && data2) { - // Combine the moof + mdat so that we buffer with a single append - buffer = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__["appendUint8Array"])(data1, data2); - } + if (!levelDetails.live && fragCurrent && fragCurrent.sn === levelDetails.endSN && !bufferInfo.nextStart) { + var fragState = fragmentTracker.getState(fragCurrent); + return fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].PARTIAL || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].OK; + } - if (!buffer || !buffer.length) { - return; - } + return false; + }; - var segment = { - type: data.type, - frag: frag, - part: part, - chunkMeta: chunkMeta, - parent: frag.type, - data: buffer - }; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].BUFFER_APPENDING, segment); + _proto.onMediaAttached = function onMediaAttached(event, data) { + var media = (this.media = this.mediaBuffer = data.media); + this.onvseeking = this.onMediaSeeking.bind(this); + this.onvended = this.onMediaEnded.bind(this); + media.addEventListener("seeking", this.onvseeking); + media.addEventListener("ended", this.onvended); + var config = this.config; - if (data.dropped && data.independent && !part) { - // Clear buffer so that we reload previous segments sequentially if required - this.flushBufferGap(frag); - } - }; + if (this.levels && config.autoStartLoad && this.state === State.STOPPED) { + this.startLoad(config.startPosition); + } + }; - _proto.flushBufferGap = function flushBufferGap(frag) { - var media = this.media; + _proto.onMediaDetaching = function onMediaDetaching() { + var media = this.media; - if (!media) { - return; - } // If currentTime is not buffered, clear the back buffer so that we can backtrack as much as needed + if (media !== null && media !== void 0 && media.ended) { + this.log("MSE detaching and video ended, reset startPosition"); + this.startPosition = this.lastCurrentTime = 0; + } // remove video listeners + if (media) { + media.removeEventListener("seeking", this.onvseeking); + media.removeEventListener("ended", this.onvended); + this.onvseeking = this.onvended = null; + } - if (!_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].isBuffered(media, media.currentTime)) { - this.flushMainBuffer(0, frag.start); - return; - } // Remove back-buffer without interrupting playback to allow back tracking + this.media = this.mediaBuffer = null; + this.loadedmetadata = false; + this.fragmentTracker.removeAllFragments(); + this.stopLoad(); + }; + _proto.onMediaSeeking = function onMediaSeeking() { + var config = this.config, + fragCurrent = this.fragCurrent, + media = this.media, + mediaBuffer = this.mediaBuffer, + state = this.state; + var currentTime = media ? media.currentTime : 0; + var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(mediaBuffer || media, currentTime, config.maxBufferHole); + this.log("media seeking to " + (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state); - var currentTime = media.currentTime; - var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(media, currentTime, 0); - var fragDuration = frag.duration; - var segmentFraction = Math.min(this.config.maxFragLookUpTolerance * 2, fragDuration * 0.25); - var start = Math.max(Math.min(frag.start - segmentFraction, bufferInfo.end - segmentFraction), currentTime + segmentFraction); + if (state === State.ENDED) { + this.resetLoadingState(); + } else if (fragCurrent && !bufferInfo.len) { + // check if we are seeking to a unbuffered area AND if frag loading is in progress + var tolerance = config.maxFragLookUpTolerance; + var fragStartOffset = fragCurrent.start - tolerance; + var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance; + var pastFragment = currentTime > fragEndOffset; // check if the seek position is past current fragment, and if so abort loading - if (frag.start - start > segmentFraction) { - this.flushMainBuffer(start, frag.start); - } - }; + if (currentTime < fragStartOffset || pastFragment) { + if (pastFragment && fragCurrent.loader) { + this.log("seeking outside of buffer while fragment load in progress, cancel fragment load"); + fragCurrent.loader.abort(); + } - _proto.getFwdBufferInfo = function getFwdBufferInfo(bufferable, type) { - var config = this.config; - var pos = this.getLoadPosition(); + this.resetLoadingState(); + } + } - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(pos)) { - return null; - } + if (media) { + this.lastCurrentTime = currentTime; + } // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target - var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(bufferable, pos, config.maxBufferHole); // Workaround flaw in getting forward buffer when maxBufferHole is smaller than gap at current pos + if (!this.loadedmetadata && !bufferInfo.len) { + this.nextLoadPosition = this.startPosition = currentTime; + } // Async tick to speed up processing - if (bufferInfo.len === 0 && bufferInfo.nextStart !== undefined) { - var bufferedFragAtPos = this.fragmentTracker.getBufferedFrag(pos, type); + this.tickImmediate(); + }; - if (bufferedFragAtPos && bufferInfo.nextStart < bufferedFragAtPos.end) { - return _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(bufferable, pos, Math.max(bufferInfo.nextStart, config.maxBufferHole)); - } - } + _proto.onMediaEnded = function onMediaEnded() { + // reset startPosition and lastCurrentTime to restart playback @ stream beginning + this.startPosition = this.lastCurrentTime = 0; + }; - return bufferInfo; - }; + _proto.onKeyLoaded = function onKeyLoaded(event, data) { + if (this.state !== State.KEY_LOADING || data.frag !== this.fragCurrent || !this.levels) { + return; + } - _proto.getMaxBufferLength = function getMaxBufferLength(levelBitrate) { - var config = this.config; - var maxBufLen; + this.state = State.IDLE; + var levelDetails = this.levels[data.frag.level].details; - if (levelBitrate) { - maxBufLen = Math.max(8 * config.maxBufferSize / levelBitrate, config.maxBufferLength); - } else { - maxBufLen = config.maxBufferLength; - } + if (levelDetails) { + this.loadFragment(data.frag, levelDetails, data.frag.start); + } + }; - return Math.min(maxBufLen, config.maxMaxBufferLength); - }; + _proto.onHandlerDestroying = function onHandlerDestroying() { + this.stopLoad(); - _proto.reduceMaxBufferLength = function reduceMaxBufferLength(threshold) { - var config = this.config; - var minLength = threshold || config.maxBufferLength; + _TaskLoop.prototype.onHandlerDestroying.call(this); + }; - if (config.maxMaxBufferLength >= minLength) { - // reduce max buffer length as it might be too high. we do this to avoid loop flushing ... - config.maxMaxBufferLength /= 2; - this.warn("Reduce max buffer length to " + config.maxMaxBufferLength + "s"); - return true; - } + _proto.onHandlerDestroyed = function onHandlerDestroyed() { + this.state = State.STOPPED; + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].KEY_LOADED, this.onKeyLoaded, this); - return false; - }; + if (this.fragmentLoader) { + this.fragmentLoader.destroy(); + } - _proto.getNextFragment = function getNextFragment(pos, levelDetails) { - var _frag, _frag2; + if (this.decrypter) { + this.decrypter.destroy(); + } - var fragments = levelDetails.fragments; - var fragLen = fragments.length; + this.CiderHls = this.log = this.warn = this.decrypter = this.fragmentLoader = this.fragmentTracker = null; - if (!fragLen) { - return null; - } // find fragment index, contiguous with end of buffer position + _TaskLoop.prototype.onHandlerDestroyed.call(this); + }; + _proto.loadKey = function loadKey(frag, details) { + this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.logPrefix === "[stream-controller]" ? "level" : "track") + " " + frag.level); + this.state = State.KEY_LOADING; + this.fragCurrent = frag; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].KEY_LOADING, { + frag: frag, + }); + }; - var config = this.config; - var start = fragments[0].start; - var frag; + _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) { + this._loadFragForPlayback(frag, levelDetails, targetBufferTime); + }; - if (levelDetails.live) { - var initialLiveManifestSize = config.initialLiveManifestSize; + _proto._loadFragForPlayback = function _loadFragForPlayback(frag, levelDetails, targetBufferTime) { + var _this2 = this; - if (fragLen < initialLiveManifestSize) { - this.warn("Not enough fragments to start playback (have: " + fragLen + ", need: " + initialLiveManifestSize + ")"); - return null; - } // The real fragment start times for a live stream are only known after the PTS range for that level is known. - // In order to discover the range, we load the best matching fragment for that level and demux it. - // Do not load using live logic if the starting frag is requested - we want to use getFragmentAtPosition() so that - // we get the fragment matching that start time + var progressCallback = function progressCallback(data) { + if (_this2.fragContextChanged(frag)) { + _this2.warn("Fragment " + frag.sn + (data.part ? " p: " + data.part.index : "") + " of level " + frag.level + " was dropped during download."); + _this2.fragmentTracker.removeFragment(frag); - if (!levelDetails.PTSKnown && !this.startFragRequested && this.startPosition === -1) { - frag = this.getInitialLiveFragment(levelDetails, fragments); - this.startPosition = frag ? this.CiderHls.liveSyncPosition || frag.start : pos; - } - } else if (pos <= start) { - // VoD playlist: if loadPosition before start of playlist, load first fragment - frag = fragments[0]; - } // If we haven't run into any special cases already, just load the fragment most closely matching the requested position + return; + } + frag.stats.chunkCount++; - if (!frag) { - var end = config.lowLatencyMode ? levelDetails.partEnd : levelDetails.fragmentEnd; - frag = this.getFragmentAtPosition(pos, end, levelDetails); - } // If an initSegment is present, it must be buffered first + _this2._handleFragmentLoadProgress(data); + }; + this._doFragLoad(frag, levelDetails, targetBufferTime, progressCallback) + .then(function (data) { + if (!data) { + // if we're here we probably needed to backtrack or are waiting for more parts + return; + } - if ((_frag = frag) !== null && _frag !== void 0 && _frag.initSegment && !((_frag2 = frag) !== null && _frag2 !== void 0 && _frag2.initSegment.data) && !this.bitrateTest) { - frag = frag.initSegment; - } + _this2.fragLoadError = 0; + var state = _this2.state; - return frag; - }; + if (_this2.fragContextChanged(frag)) { + if (state === State.FRAG_LOADING || state === State.BACKTRACKING || (!_this2.fragCurrent && state === State.PARSING)) { + _this2.fragmentTracker.removeFragment(frag); - _proto.getNextPart = function getNextPart(partList, frag, targetBufferTime) { - var nextPart = -1; - var contiguous = false; - var independentAttrOmitted = true; + _this2.state = State.IDLE; + } - for (var i = 0, len = partList.length; i < len; i++) { - var part = partList[i]; - independentAttrOmitted = independentAttrOmitted && !part.independent; + return; + } - if (nextPart > -1 && targetBufferTime < part.start) { - break; - } + if ("payload" in data) { + _this2.log("Loaded fragment " + frag.sn + " of level " + frag.level); - var loaded = part.loaded; + _this2.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADED, data); // Tracker backtrack must be called after onFragLoaded to update the fragment entity state to BACKTRACKED + // This happens after handleTransmuxComplete when the worker or progressive is disabled - if (!loaded && (contiguous || part.independent || independentAttrOmitted) && part.fragment === frag) { - nextPart = i; - } + if (_this2.state === State.BACKTRACKING) { + _this2.fragmentTracker.backtrack(frag, data); - contiguous = loaded; - } + _this2.resetFragmentLoading(frag); - return nextPart; - }; + return; + } + } // Pass through the whole payload; controllers not implementing progressive loading receive data from this callback - _proto.loadedEndOfParts = function loadedEndOfParts(partList, targetBufferTime) { - var lastPart = partList[partList.length - 1]; - return lastPart && targetBufferTime > lastPart.start && lastPart.loaded; - } - /* + _this2._handleFragmentLoadComplete(data); + }) + .catch(function (reason) { + _this2.warn(reason); + + _this2.resetFragmentLoading(frag); + }); + }; + + _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset, type) { + if (type === void 0) { + type = null; + } + + if (!(startOffset - endOffset)) { + return; + } // When alternate audio is playing, the audio-stream-controller is responsible for the audio buffer. Otherwise, + // passing a null type flushes both buffers + + var flushScope = { + startOffset: startOffset, + endOffset: endOffset, + type: type, + }; // Reset load errors on flush + + this.fragLoadError = 0; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].BUFFER_FLUSHING, flushScope); + }; + + _proto._loadInitSegment = function _loadInitSegment(frag) { + var _this3 = this; + + this._doFragLoad(frag) + .then(function (data) { + if (!data || _this3.fragContextChanged(frag) || !_this3.levels) { + throw new Error("init load aborted"); + } + + return data; + }) + .then(function (data) { + var CiderHls = _this3.CiderHls; + var payload = data.payload; + var decryptData = frag.decryptdata; // check to see if the payload needs to be decrypted + + if (payload && payload.byteLength > 0 && decryptData && decryptData.key && decryptData.iv && decryptData.method === "AES-128") { + var startTime = self.performance.now(); // decrypt the subtitles + + return _this3.decrypter.webCryptoDecrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).then(function (decryptedData) { + var endTime = self.performance.now(); + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_DECRYPTED, { + frag: frag, + payload: decryptedData, + stats: { + tstart: startTime, + tdecrypt: endTime, + }, + }); + data.payload = decryptedData; + return data; + }); + } + + return data; + }) + .then(function (data) { + var fragCurrent = _this3.fragCurrent, + CiderHls = _this3.CiderHls, + levels = _this3.levels; + + if (!levels) { + throw new Error("init load aborted, missing levels"); + } + + var details = levels[frag.level].details; + console.assert(details, "Level details are defined when init segment is loaded"); + var stats = frag.stats; + _this3.state = State.IDLE; + _this3.fragLoadError = 0; + frag.data = new Uint8Array(data.payload); + stats.parsing.start = stats.buffering.start = self.performance.now(); + stats.parsing.end = stats.buffering.end = self.performance.now(); // Silence FRAG_BUFFERED event if fragCurrent is null + + if (data.frag === fragCurrent) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_BUFFERED, { + stats: stats, + frag: fragCurrent, + part: null, + id: frag.type, + }); + } + + _this3.tick(); + }) + .catch(function (reason) { + _this3.warn(reason); + + _this3.resetFragmentLoading(frag); + }); + }; + + _proto.fragContextChanged = function fragContextChanged(frag) { + var fragCurrent = this.fragCurrent; + return !frag || !fragCurrent || frag.level !== fragCurrent.level || frag.sn !== fragCurrent.sn || frag.urlId !== fragCurrent.urlId; + }; + + _proto.fragBufferedComplete = function fragBufferedComplete(frag, part) { + var media = this.mediaBuffer ? this.mediaBuffer : this.media; + this.log( + "Buffered " + + frag.type + + " sn: " + + frag.sn + + (part ? " part: " + part.index : "") + + " of " + + (this.logPrefix === "[stream-controller]" ? "level" : "track") + + " " + + frag.level + + " " + + _utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__["default"].toString(_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].getBuffered(media)) + ); + this.state = State.IDLE; + this.tick(); + }; + + _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedEndData) { + var transmuxer = this.transmuxer; + + if (!transmuxer) { + return; + } + + var frag = fragLoadedEndData.frag, + part = fragLoadedEndData.part, + partsLoaded = fragLoadedEndData.partsLoaded; // If we did not load parts, or loaded all parts, we have complete (not partial) fragment data + + var complete = + !partsLoaded || + partsLoaded.length === 0 || + partsLoaded.some(function (fragLoaded) { + return !fragLoaded; + }); + var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount + 1, 0, part ? part.index : -1, !complete); + transmuxer.flush(chunkMeta); + }; // eslint-disable-next-line @typescript-eslint/no-unused-vars + + _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(frag) {}; + + _proto._doFragLoad = function _doFragLoad(frag, details, targetBufferTime, progressCallback) { + var _this4 = this; + + if (targetBufferTime === void 0) { + targetBufferTime = null; + } + + if (!this.levels) { + throw new Error("frag load aborted, missing levels"); + } + + targetBufferTime = Math.max(frag.start, targetBufferTime || 0); + + if (this.config.lowLatencyMode && details) { + var partList = details.partList; + + if (partList && progressCallback) { + if (targetBufferTime > frag.end && details.fragmentHint) { + frag = details.fragmentHint; + } + + var partIndex = this.getNextPart(partList, frag, targetBufferTime); + + if (partIndex > -1) { + var part = partList[partIndex]; + this.log( + "Loading part sn: " + + frag.sn + + " p: " + + part.index + + " cc: " + + frag.cc + + " of playlist [" + + details.startSN + + "-" + + details.endSN + + "] parts [0-" + + partIndex + + "-" + + (partList.length - 1) + + "] " + + (this.logPrefix === "[stream-controller]" ? "level" : "track") + + ": " + + frag.level + + ", target: " + + parseFloat(targetBufferTime.toFixed(3)) + ); + this.nextLoadPosition = part.start + part.duration; + this.state = State.FRAG_LOADING; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADING, { + frag: frag, + part: partList[partIndex], + targetBufferTime: targetBufferTime, + }); + return this.doFragPartsLoad(frag, partList, partIndex, progressCallback).catch(function (error) { + return _this4.handleFragLoadError(error); + }); + } else if (!frag.url || this.loadedEndOfParts(partList, targetBufferTime)) { + // Fragment hint has no parts + return Promise.resolve(null); + } + } + } + + this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? "of [" + details.startSN + "-" + details.endSN + "] " : "") + (this.logPrefix === "[stream-controller]" ? "level" : "track") + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3))); // Don't update nextLoadPosition for fragments which are not buffered + + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.sn) && !this.bitrateTest) { + this.nextLoadPosition = frag.start + frag.duration; + } + + this.state = State.FRAG_LOADING; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADING, { + frag: frag, + targetBufferTime: targetBufferTime, + }); + return this.fragmentLoader.load(frag, progressCallback).catch(function (error) { + return _this4.handleFragLoadError(error); + }); + }; + + _proto.doFragPartsLoad = function doFragPartsLoad(frag, partList, partIndex, progressCallback) { + var _this5 = this; + + return new Promise(function (resolve, reject) { + var partsLoaded = []; + + var loadPartIndex = function loadPartIndex(index) { + var part = partList[index]; + + _this5.fragmentLoader + .loadPart(frag, part, progressCallback) + .then(function (partLoadedData) { + partsLoaded[part.index] = partLoadedData; + var loadedPart = partLoadedData.part; + + _this5.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_LOADED, partLoadedData); + + var nextPart = partList[index + 1]; + + if (nextPart && nextPart.fragment === frag) { + loadPartIndex(index + 1); + } else { + return resolve({ + frag: frag, + part: loadedPart, + partsLoaded: partsLoaded, + }); + } + }) + .catch(reject); + }; + + loadPartIndex(partIndex); + }); + }; + + _proto.handleFragLoadError = function handleFragLoadError(_ref) { + var data = _ref.data; + + if (data && data.details === _errors__WEBPACK_IMPORTED_MODULE_6__["ErrorDetails"].INTERNAL_ABORTED) { + this.handleFragLoadAborted(data.frag, data.part); + } else { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, data); + } + + return null; + }; + + _proto._handleTransmuxerFlush = function _handleTransmuxerFlush(chunkMeta) { + var context = this.getCurrentContext(chunkMeta); + + if (!context || this.state !== State.PARSING) { + if (!this.fragCurrent) { + this.state = State.IDLE; + } + + return; + } + + var frag = context.frag, + part = context.part, + level = context.level; + var now = self.performance.now(); + frag.stats.parsing.end = now; + + if (part) { + part.stats.parsing.end = now; + } + + this.updateLevelTiming(frag, part, level, chunkMeta.partial); + }; + + _proto.getCurrentContext = function getCurrentContext(chunkMeta) { + var levels = this.levels; + var levelIndex = chunkMeta.level, + sn = chunkMeta.sn, + partIndex = chunkMeta.part; + + if (!levels || !levels[levelIndex]) { + this.warn("Levels object was unset while buffering fragment " + sn + " of level " + levelIndex + ". The current chunk will not be buffered."); + return null; + } + + var level = levels[levelIndex]; + var part = partIndex > -1 ? Object(_level_helper__WEBPACK_IMPORTED_MODULE_11__["getPartWith"])(level, sn, partIndex) : null; + var frag = part ? part.fragment : Object(_level_helper__WEBPACK_IMPORTED_MODULE_11__["getFragmentWithSN"])(level, sn, this.fragCurrent); + + if (!frag) { + return null; + } + + return { + frag: frag, + part: part, + level: level, + }; + }; + + _proto.bufferFragmentData = function bufferFragmentData(data, frag, part, chunkMeta) { + if (!data || this.state !== State.PARSING) { + return; + } + + var data1 = data.data1, + data2 = data.data2; + var buffer = data1; + + if (data1 && data2) { + // Combine the moof + mdat so that we buffer with a single append + buffer = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__["appendUint8Array"])(data1, data2); + } + + if (!buffer || !buffer.length) { + return; + } + + var segment = { + type: data.type, + frag: frag, + part: part, + chunkMeta: chunkMeta, + parent: frag.type, + data: buffer, + }; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].BUFFER_APPENDING, segment); + + if (data.dropped && data.independent && !part) { + // Clear buffer so that we reload previous segments sequentially if required + this.flushBufferGap(frag); + } + }; + + _proto.flushBufferGap = function flushBufferGap(frag) { + var media = this.media; + + if (!media) { + return; + } // If currentTime is not buffered, clear the back buffer so that we can backtrack as much as needed + + if (!_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].isBuffered(media, media.currentTime)) { + this.flushMainBuffer(0, frag.start); + return; + } // Remove back-buffer without interrupting playback to allow back tracking + + var currentTime = media.currentTime; + var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(media, currentTime, 0); + var fragDuration = frag.duration; + var segmentFraction = Math.min(this.config.maxFragLookUpTolerance * 2, fragDuration * 0.25); + var start = Math.max(Math.min(frag.start - segmentFraction, bufferInfo.end - segmentFraction), currentTime + segmentFraction); + + if (frag.start - start > segmentFraction) { + this.flushMainBuffer(start, frag.start); + } + }; + + _proto.getFwdBufferInfo = function getFwdBufferInfo(bufferable, type) { + var config = this.config; + var pos = this.getLoadPosition(); + + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(pos)) { + return null; + } + + var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(bufferable, pos, config.maxBufferHole); // Workaround flaw in getting forward buffer when maxBufferHole is smaller than gap at current pos + + if (bufferInfo.len === 0 && bufferInfo.nextStart !== undefined) { + var bufferedFragAtPos = this.fragmentTracker.getBufferedFrag(pos, type); + + if (bufferedFragAtPos && bufferInfo.nextStart < bufferedFragAtPos.end) { + return _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(bufferable, pos, Math.max(bufferInfo.nextStart, config.maxBufferHole)); + } + } + + return bufferInfo; + }; + + _proto.getMaxBufferLength = function getMaxBufferLength(levelBitrate) { + var config = this.config; + var maxBufLen; + + if (levelBitrate) { + maxBufLen = Math.max((8 * config.maxBufferSize) / levelBitrate, config.maxBufferLength); + } else { + maxBufLen = config.maxBufferLength; + } + + return Math.min(maxBufLen, config.maxMaxBufferLength); + }; + + _proto.reduceMaxBufferLength = function reduceMaxBufferLength(threshold) { + var config = this.config; + var minLength = threshold || config.maxBufferLength; + + if (config.maxMaxBufferLength >= minLength) { + // reduce max buffer length as it might be too high. we do this to avoid loop flushing ... + config.maxMaxBufferLength /= 2; + this.warn("Reduce max buffer length to " + config.maxMaxBufferLength + "s"); + return true; + } + + return false; + }; + + _proto.getNextFragment = function getNextFragment(pos, levelDetails) { + var _frag, _frag2; + + var fragments = levelDetails.fragments; + var fragLen = fragments.length; + + if (!fragLen) { + return null; + } // find fragment index, contiguous with end of buffer position + + var config = this.config; + var start = fragments[0].start; + var frag; + + if (levelDetails.live) { + var initialLiveManifestSize = config.initialLiveManifestSize; + + if (fragLen < initialLiveManifestSize) { + this.warn("Not enough fragments to start playback (have: " + fragLen + ", need: " + initialLiveManifestSize + ")"); + return null; + } // The real fragment start times for a live stream are only known after the PTS range for that level is known. + // In order to discover the range, we load the best matching fragment for that level and demux it. + // Do not load using live logic if the starting frag is requested - we want to use getFragmentAtPosition() so that + // we get the fragment matching that start time + + if (!levelDetails.PTSKnown && !this.startFragRequested && this.startPosition === -1) { + frag = this.getInitialLiveFragment(levelDetails, fragments); + this.startPosition = frag ? this.CiderHls.liveSyncPosition || frag.start : pos; + } + } else if (pos <= start) { + // VoD playlist: if loadPosition before start of playlist, load first fragment + frag = fragments[0]; + } // If we haven't run into any special cases already, just load the fragment most closely matching the requested position + + if (!frag) { + var end = config.lowLatencyMode ? levelDetails.partEnd : levelDetails.fragmentEnd; + frag = this.getFragmentAtPosition(pos, end, levelDetails); + } // If an initSegment is present, it must be buffered first + + if ((_frag = frag) !== null && _frag !== void 0 && _frag.initSegment && !((_frag2 = frag) !== null && _frag2 !== void 0 && _frag2.initSegment.data) && !this.bitrateTest) { + frag = frag.initSegment; + } + + return frag; + }; + + _proto.getNextPart = function getNextPart(partList, frag, targetBufferTime) { + var nextPart = -1; + var contiguous = false; + var independentAttrOmitted = true; + + for (var i = 0, len = partList.length; i < len; i++) { + var part = partList[i]; + independentAttrOmitted = independentAttrOmitted && !part.independent; + + if (nextPart > -1 && targetBufferTime < part.start) { + break; + } + + var loaded = part.loaded; + + if (!loaded && (contiguous || part.independent || independentAttrOmitted) && part.fragment === frag) { + nextPart = i; + } + + contiguous = loaded; + } + + return nextPart; + }; + + _proto.loadedEndOfParts = function loadedEndOfParts(partList, targetBufferTime) { + var lastPart = partList[partList.length - 1]; + return lastPart && targetBufferTime > lastPart.start && lastPart.loaded; + }; + /* This method is used find the best matching first fragment for a live playlist. This fragment is used to calculate the "sliding" of the playlist, which is its offset from the start of playback. After sliding we can compute the real start and end times for each fragment in the playlist (after which this method will not need to be called). */ - ; - _proto.getInitialLiveFragment = function getInitialLiveFragment(levelDetails, fragments) { - var fragPrevious = this.fragPrevious; - var frag = null; + _proto.getInitialLiveFragment = function getInitialLiveFragment(levelDetails, fragments) { + var fragPrevious = this.fragPrevious; + var frag = null; - if (fragPrevious) { - if (levelDetails.hasProgramDateTime) { - // Prefer using PDT, because it can be accurate enough to choose the correct fragment without knowing the level sliding - this.log("Live playlist, switching playlist, load frag with same PDT: " + fragPrevious.programDateTime); - frag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_10__["findFragmentByPDT"])(fragments, fragPrevious.endProgramDateTime, this.config.maxFragLookUpTolerance); - } + if (fragPrevious) { + if (levelDetails.hasProgramDateTime) { + // Prefer using PDT, because it can be accurate enough to choose the correct fragment without knowing the level sliding + this.log("Live playlist, switching playlist, load frag with same PDT: " + fragPrevious.programDateTime); + frag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_10__["findFragmentByPDT"])(fragments, fragPrevious.endProgramDateTime, this.config.maxFragLookUpTolerance); + } - if (!frag) { - // SN does not need to be accurate between renditions, but depending on the packaging it may be so. - var targetSN = fragPrevious.sn + 1; + if (!frag) { + // SN does not need to be accurate between renditions, but depending on the packaging it may be so. + var targetSN = fragPrevious.sn + 1; - if (targetSN >= levelDetails.startSN && targetSN <= levelDetails.endSN) { - var fragNext = fragments[targetSN - levelDetails.startSN]; // Ensure that we're staying within the continuity range, since PTS resets upon a new range + if (targetSN >= levelDetails.startSN && targetSN <= levelDetails.endSN) { + var fragNext = fragments[targetSN - levelDetails.startSN]; // Ensure that we're staying within the continuity range, since PTS resets upon a new range - if (fragPrevious.cc === fragNext.cc) { - frag = fragNext; - this.log("Live playlist, switching playlist, load frag with next SN: " + frag.sn); - } - } // It's important to stay within the continuity range if available; otherwise the fragments in the playlist - // will have the wrong start times + if (fragPrevious.cc === fragNext.cc) { + frag = fragNext; + this.log("Live playlist, switching playlist, load frag with next SN: " + frag.sn); + } + } // It's important to stay within the continuity range if available; otherwise the fragments in the playlist + // will have the wrong start times + if (!frag) { + frag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_10__["findFragWithCC"])(fragments, fragPrevious.cc); - if (!frag) { - frag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_10__["findFragWithCC"])(fragments, fragPrevious.cc); + if (frag) { + this.log("Live playlist, switching playlist, load frag with same CC: " + frag.sn); + } + } + } + } else { + // Find a new start fragment when fragPrevious is null + var liveStart = this.CiderHls.liveSyncPosition; - if (frag) { - this.log("Live playlist, switching playlist, load frag with same CC: " + frag.sn); - } - } - } - } else { - // Find a new start fragment when fragPrevious is null - var liveStart = this.CiderHls.liveSyncPosition; + if (liveStart !== null) { + frag = this.getFragmentAtPosition(liveStart, this.bitrateTest ? levelDetails.fragmentEnd : levelDetails.edge, levelDetails); + } + } - if (liveStart !== null) { - frag = this.getFragmentAtPosition(liveStart, this.bitrateTest ? levelDetails.fragmentEnd : levelDetails.edge, levelDetails); - } - } - - return frag; - } - /* + return frag; + }; + /* This method finds the best matching fragment given the provided position. */ - ; - - _proto.getFragmentAtPosition = function getFragmentAtPosition(bufferEnd, end, levelDetails) { - var config = this.config, - fragPrevious = this.fragPrevious; - var fragments = levelDetails.fragments, - endSN = levelDetails.endSN; - var fragmentHint = levelDetails.fragmentHint; - var tolerance = config.maxFragLookUpTolerance; - var loadingParts = !!(config.lowLatencyMode && levelDetails.partList && fragmentHint); - - if (loadingParts && fragmentHint && !this.bitrateTest) { - // Include incomplete fragment with parts at end - fragments = fragments.concat(fragmentHint); - endSN = fragmentHint.sn; - } - - var frag; - - if (bufferEnd < end) { - var lookupTolerance = bufferEnd > end - tolerance ? 0 : tolerance; // Remove the tolerance if it would put the bufferEnd past the actual end of stream - // Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE) - - frag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_10__["findFragmentByPTS"])(fragPrevious, fragments, bufferEnd, lookupTolerance); - } else { - // reach end of playlist - frag = fragments[fragments.length - 1]; - } - - if (frag) { - var curSNIdx = frag.sn - levelDetails.startSN; - var sameLevel = fragPrevious && frag.level === fragPrevious.level; - var nextFrag = fragments[curSNIdx + 1]; - var fragState = this.fragmentTracker.getState(frag); - - if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].BACKTRACKED) { - frag = null; - var i = curSNIdx; - - while (fragments[i] && this.fragmentTracker.getState(fragments[i]) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].BACKTRACKED) { - // When fragPrevious is null, backtrack to first the first fragment is not BACKTRACKED for loading - // When fragPrevious is set, we want the first BACKTRACKED fragment for parsing and buffering - if (!fragPrevious) { - frag = fragments[--i]; - } else { - frag = fragments[i--]; - } - } - - if (!frag) { - frag = nextFrag; - } - } else if (fragPrevious && frag.sn === fragPrevious.sn && !loadingParts) { - // Force the next fragment to load if the previous one was already selected. This can occasionally happen with - // non-uniform fragment durations - if (sameLevel) { - if (frag.sn < endSN && this.fragmentTracker.getState(nextFrag) !== _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].OK) { - this.log("SN " + frag.sn + " just loaded, load next one: " + nextFrag.sn); - frag = nextFrag; - } else { - frag = null; - } - } - } - } - - return frag; - }; - - _proto.synchronizeToLiveEdge = function synchronizeToLiveEdge(levelDetails) { - var config = this.config, - media = this.media; - - if (!media) { - return; - } - - var liveSyncPosition = this.CiderHls.liveSyncPosition; - var currentTime = media.currentTime; - var start = levelDetails.fragments[0].start; - var end = levelDetails.edge; - var withinSlidingWindow = currentTime >= start - config.maxFragLookUpTolerance && currentTime <= end; // Continue if we can seek forward to sync position or if current time is outside of sliding window - - if (liveSyncPosition !== null && media.duration > liveSyncPosition && (currentTime < liveSyncPosition || !withinSlidingWindow)) { - // Continue if buffer is starving or if current time is behind max latency - var maxLatency = config.liveMaxLatencyDuration !== undefined ? config.liveMaxLatencyDuration : config.liveMaxLatencyDurationCount * levelDetails.targetduration; - - if (!withinSlidingWindow && media.readyState < 4 || currentTime < end - maxLatency) { - if (!this.loadedmetadata) { - this.nextLoadPosition = liveSyncPosition; - } // Only seek if ready and there is not a significant forward buffer available for playback - - - if (media.readyState) { - this.warn("Playback: " + currentTime.toFixed(3) + " is located too far from the end of live sliding playlist: " + end + ", reset currentTime to : " + liveSyncPosition.toFixed(3)); - media.currentTime = liveSyncPosition; - } - } - } - }; - - _proto.alignPlaylists = function alignPlaylists(details, previousDetails) { - var levels = this.levels, - levelLastLoaded = this.levelLastLoaded, - fragPrevious = this.fragPrevious; - var lastLevel = levelLastLoaded !== null ? levels[levelLastLoaded] : null; // FIXME: If not for `shouldAlignOnDiscontinuities` requiring fragPrevious.cc, - // this could all go in level-helper mergeDetails() - - var length = details.fragments.length; - - if (!length) { - this.warn("No fragments in live playlist"); - return 0; - } - - var slidingStart = details.fragments[0].start; - var firstLevelLoad = !previousDetails; - - var aligned = details.alignedSliding && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(slidingStart); - - if (firstLevelLoad || !aligned && !slidingStart) { - Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__["alignStream"])(fragPrevious, lastLevel, details); - var alignedSlidingStart = details.fragments[0].start; - this.log("Live playlist sliding: " + alignedSlidingStart.toFixed(2) + " start-sn: " + (previousDetails ? previousDetails.startSN : 'na') + "->" + details.startSN + " prev-sn: " + (fragPrevious ? fragPrevious.sn : 'na') + " fragments: " + length); - return alignedSlidingStart; - } - - return slidingStart; - }; - - _proto.waitForCdnTuneIn = function waitForCdnTuneIn(details) { - // Wait for Low-Latency CDN Tune-in to get an updated playlist - var advancePartLimit = 3; - return details.live && details.canBlockReload && details.tuneInGoal > Math.max(details.partHoldBack, details.partTarget * advancePartLimit); - }; - - _proto.setStartPosition = function setStartPosition(details, sliding) { - // compute start position if set to -1. use it straight away if value is defined - var startPosition = this.startPosition; - - if (startPosition < sliding) { - startPosition = -1; - } - - if (startPosition === -1 || this.lastCurrentTime === -1) { - // first, check if start time offset has been set in playlist, if yes, use this value - var startTimeOffset = details.startTimeOffset; - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(startTimeOffset)) { - startPosition = sliding + startTimeOffset; - - if (startTimeOffset < 0) { - startPosition += details.totalduration; - } - - startPosition = Math.min(Math.max(sliding, startPosition), sliding + details.totalduration); - this.log("Start time offset " + startTimeOffset + " found in playlist, adjust startPosition to " + startPosition); - this.startPosition = startPosition; - } else if (details.live) { - // Leave this.startPosition at -1, so that we can use `getInitialLiveFragment` logic when startPosition has - // not been specified via the config or an as an argument to startLoad (#3736). - startPosition = this.CiderHls.liveSyncPosition || sliding; - } else { - this.startPosition = startPosition = 0; - } - - this.lastCurrentTime = startPosition; - } - - this.nextLoadPosition = startPosition; - }; - - _proto.getLoadPosition = function getLoadPosition() { - var media = this.media; // if we have not yet loaded any fragment, start loading from start position - - var pos = 0; - - if (this.loadedmetadata && media) { - pos = media.currentTime; - } else if (this.nextLoadPosition) { - pos = this.nextLoadPosition; - } - - return pos; - }; - - _proto.handleFragLoadAborted = function handleFragLoadAborted(frag, part) { - if (this.transmuxer && frag.sn !== 'initSegment' && frag.stats.aborted) { - this.warn("Fragment " + frag.sn + (part ? ' part' + part.index : '') + " of level " + frag.level + " was aborted"); - this.resetFragmentLoading(frag); - } - }; - - _proto.resetFragmentLoading = function resetFragmentLoading(frag) { - if (!this.fragCurrent || !this.fragContextChanged(frag)) { - this.state = State.IDLE; - } - }; - - _proto.onFragmentOrKeyLoadError = function onFragmentOrKeyLoadError(filterType, data) { - if (data.fatal) { - return; - } - - var frag = data.frag; // Handle frag error related to caller's filterType - - if (!frag || frag.type !== filterType) { - return; - } - - var fragCurrent = this.fragCurrent; - console.assert(fragCurrent && frag.sn === fragCurrent.sn && frag.level === fragCurrent.level && frag.urlId === fragCurrent.urlId, 'Frag load error must match current frag to retry'); - var config = this.config; // keep retrying until the limit will be reached - - if (this.fragLoadError + 1 <= config.fragLoadingMaxRetry) { - if (this.resetLiveStartWhenNotLoaded(frag.level)) { - return; - } // exponential backoff capped to config.fragLoadingMaxRetryTimeout - - - var delay = Math.min(Math.pow(2, this.fragLoadError) * config.fragLoadingRetryDelay, config.fragLoadingMaxRetryTimeout); - this.warn("Fragment " + frag.sn + " of " + filterType + " " + frag.level + " failed to load, retrying in " + delay + "ms"); - this.retryDate = self.performance.now() + delay; - this.fragLoadError++; - this.state = State.FRAG_LOADING_WAITING_RETRY; - } else if (data.levelRetry) { - if (filterType === _types_loader__WEBPACK_IMPORTED_MODULE_15__["PlaylistLevelType"].AUDIO) { - // Reset current fragment since audio track audio is essential and may not have a fail-over track - this.fragCurrent = null; - } // Fragment errors that result in a level switch or redundant fail-over - // should reset the stream controller state to idle - - - this.fragLoadError = 0; - this.state = State.IDLE; - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"].error(data.details + " reaches max retry, redispatch as fatal ..."); // switch error to fatal - - data.fatal = true; - this.CiderHls.stopLoad(); - this.state = State.ERROR; - } - }; - - _proto.afterBufferFlushed = function afterBufferFlushed(media, bufferType, playlistType) { - if (!media) { - return; - } // After successful buffer flushing, filter flushed fragments from bufferedFrags use mediaBuffered instead of media - // (so that we will check against video.buffered ranges in case of alt audio track) - - - var bufferedTimeRanges = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].getBuffered(media); - this.fragmentTracker.detectEvictedFragments(bufferType, bufferedTimeRanges, playlistType); - - if (this.state === State.ENDED) { - this.resetLoadingState(); - } - }; - - _proto.resetLoadingState = function resetLoadingState() { - this.fragCurrent = null; - this.fragPrevious = null; - this.state = State.IDLE; - }; - - _proto.resetLiveStartWhenNotLoaded = function resetLiveStartWhenNotLoaded(level) { - // if loadedmetadata is not set, it means that we are emergency switch down on first frag - // in that case, reset startFragRequested flag - if (!this.loadedmetadata) { - this.startFragRequested = false; - var details = this.levels ? this.levels[level].details : null; - - if (details !== null && details !== void 0 && details.live) { - // We can't afford to retry after a delay in a live scenario. Update the start position and return to IDLE. - this.startPosition = -1; - this.setStartPosition(details, 0); - this.resetLoadingState(); - return true; - } - - this.nextLoadPosition = this.startPosition; - } - - return false; - }; - - _proto.updateLevelTiming = function updateLevelTiming(frag, part, level, partial) { - var _this6 = this; - - var details = level.details; - console.assert(!!details, 'level.details must be defined'); - var parsed = Object.keys(frag.elementaryStreams).reduce(function (result, type) { - var info = frag.elementaryStreams[type]; - - if (info) { - var parsedDuration = info.endPTS - info.startPTS; - - if (parsedDuration <= 0) { - // Destroy the transmuxer after it's next time offset failed to advance because duration was <= 0. - // The new transmuxer will be configured with a time offset matching the next fragment start, - // preventing the timeline from shifting. - _this6.warn("Could not parse fragment " + frag.sn + " " + type + " duration reliably (" + parsedDuration + ") resetting transmuxer to fallback to playlist timing"); - - _this6.resetTransmuxer(); - - return result || false; - } - - var drift = partial ? 0 : Object(_level_helper__WEBPACK_IMPORTED_MODULE_11__["updateFragPTSDTS"])(details, frag, info.startPTS, info.endPTS, info.startDTS, info.endDTS); - - _this6.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].LEVEL_PTS_UPDATED, { - details: details, - level: level, - drift: drift, - type: type, - frag: frag, - start: info.startPTS, - end: info.endPTS - }); - - return true; - } - - return result; - }, false); - - if (parsed) { - this.state = State.PARSED; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_PARSED, { - frag: frag, - part: part - }); - } else { - this.resetLoadingState(); - } - }; - - _proto.resetTransmuxer = function resetTransmuxer() { - if (this.transmuxer) { - this.transmuxer.destroy(); - this.transmuxer = null; - } - }; - - _createClass(BaseStreamController, [{ - key: "state", - get: function get() { - return this._state; - }, - set: function set(nextState) { - var previousState = this._state; - - if (previousState !== nextState) { - this._state = nextState; - this.log(previousState + "->" + nextState); - } - } - }]); - - return BaseStreamController; -}(_task_loop__WEBPACK_IMPORTED_MODULE_1__["default"]); - - - -/***/ }), - -/***/ "./src/controller/buffer-controller.ts": -/*!*********************************************!*\ + + _proto.getFragmentAtPosition = function getFragmentAtPosition(bufferEnd, end, levelDetails) { + var config = this.config, + fragPrevious = this.fragPrevious; + var fragments = levelDetails.fragments, + endSN = levelDetails.endSN; + var fragmentHint = levelDetails.fragmentHint; + var tolerance = config.maxFragLookUpTolerance; + var loadingParts = !!(config.lowLatencyMode && levelDetails.partList && fragmentHint); + + if (loadingParts && fragmentHint && !this.bitrateTest) { + // Include incomplete fragment with parts at end + fragments = fragments.concat(fragmentHint); + endSN = fragmentHint.sn; + } + + var frag; + + if (bufferEnd < end) { + var lookupTolerance = bufferEnd > end - tolerance ? 0 : tolerance; // Remove the tolerance if it would put the bufferEnd past the actual end of stream + // Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE) + + frag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_10__["findFragmentByPTS"])(fragPrevious, fragments, bufferEnd, lookupTolerance); + } else { + // reach end of playlist + frag = fragments[fragments.length - 1]; + } + + if (frag) { + var curSNIdx = frag.sn - levelDetails.startSN; + var sameLevel = fragPrevious && frag.level === fragPrevious.level; + var nextFrag = fragments[curSNIdx + 1]; + var fragState = this.fragmentTracker.getState(frag); + + if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].BACKTRACKED) { + frag = null; + var i = curSNIdx; + + while (fragments[i] && this.fragmentTracker.getState(fragments[i]) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].BACKTRACKED) { + // When fragPrevious is null, backtrack to first the first fragment is not BACKTRACKED for loading + // When fragPrevious is set, we want the first BACKTRACKED fragment for parsing and buffering + if (!fragPrevious) { + frag = fragments[--i]; + } else { + frag = fragments[i--]; + } + } + + if (!frag) { + frag = nextFrag; + } + } else if (fragPrevious && frag.sn === fragPrevious.sn && !loadingParts) { + // Force the next fragment to load if the previous one was already selected. This can occasionally happen with + // non-uniform fragment durations + if (sameLevel) { + if (frag.sn < endSN && this.fragmentTracker.getState(nextFrag) !== _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__["FragmentState"].OK) { + this.log("SN " + frag.sn + " just loaded, load next one: " + nextFrag.sn); + frag = nextFrag; + } else { + frag = null; + } + } + } + } + + return frag; + }; + + _proto.synchronizeToLiveEdge = function synchronizeToLiveEdge(levelDetails) { + var config = this.config, + media = this.media; + + if (!media) { + return; + } + + var liveSyncPosition = this.CiderHls.liveSyncPosition; + var currentTime = media.currentTime; + var start = levelDetails.fragments[0].start; + var end = levelDetails.edge; + var withinSlidingWindow = currentTime >= start - config.maxFragLookUpTolerance && currentTime <= end; // Continue if we can seek forward to sync position or if current time is outside of sliding window + + if (liveSyncPosition !== null && media.duration > liveSyncPosition && (currentTime < liveSyncPosition || !withinSlidingWindow)) { + // Continue if buffer is starving or if current time is behind max latency + var maxLatency = config.liveMaxLatencyDuration !== undefined ? config.liveMaxLatencyDuration : config.liveMaxLatencyDurationCount * levelDetails.targetduration; + + if ((!withinSlidingWindow && media.readyState < 4) || currentTime < end - maxLatency) { + if (!this.loadedmetadata) { + this.nextLoadPosition = liveSyncPosition; + } // Only seek if ready and there is not a significant forward buffer available for playback + + if (media.readyState) { + this.warn("Playback: " + currentTime.toFixed(3) + " is located too far from the end of live sliding playlist: " + end + ", reset currentTime to : " + liveSyncPosition.toFixed(3)); + media.currentTime = liveSyncPosition; + } + } + } + }; + + _proto.alignPlaylists = function alignPlaylists(details, previousDetails) { + var levels = this.levels, + levelLastLoaded = this.levelLastLoaded, + fragPrevious = this.fragPrevious; + var lastLevel = levelLastLoaded !== null ? levels[levelLastLoaded] : null; // FIXME: If not for `shouldAlignOnDiscontinuities` requiring fragPrevious.cc, + // this could all go in level-helper mergeDetails() + + var length = details.fragments.length; + + if (!length) { + this.warn("No fragments in live playlist"); + return 0; + } + + var slidingStart = details.fragments[0].start; + var firstLevelLoad = !previousDetails; + + var aligned = details.alignedSliding && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(slidingStart); + + if (firstLevelLoad || (!aligned && !slidingStart)) { + Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__["alignStream"])(fragPrevious, lastLevel, details); + var alignedSlidingStart = details.fragments[0].start; + this.log("Live playlist sliding: " + alignedSlidingStart.toFixed(2) + " start-sn: " + (previousDetails ? previousDetails.startSN : "na") + "->" + details.startSN + " prev-sn: " + (fragPrevious ? fragPrevious.sn : "na") + " fragments: " + length); + return alignedSlidingStart; + } + + return slidingStart; + }; + + _proto.waitForCdnTuneIn = function waitForCdnTuneIn(details) { + // Wait for Low-Latency CDN Tune-in to get an updated playlist + var advancePartLimit = 3; + return details.live && details.canBlockReload && details.tuneInGoal > Math.max(details.partHoldBack, details.partTarget * advancePartLimit); + }; + + _proto.setStartPosition = function setStartPosition(details, sliding) { + // compute start position if set to -1. use it straight away if value is defined + var startPosition = this.startPosition; + + if (startPosition < sliding) { + startPosition = -1; + } + + if (startPosition === -1 || this.lastCurrentTime === -1) { + // first, check if start time offset has been set in playlist, if yes, use this value + var startTimeOffset = details.startTimeOffset; + + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(startTimeOffset)) { + startPosition = sliding + startTimeOffset; + + if (startTimeOffset < 0) { + startPosition += details.totalduration; + } + + startPosition = Math.min(Math.max(sliding, startPosition), sliding + details.totalduration); + this.log("Start time offset " + startTimeOffset + " found in playlist, adjust startPosition to " + startPosition); + this.startPosition = startPosition; + } else if (details.live) { + // Leave this.startPosition at -1, so that we can use `getInitialLiveFragment` logic when startPosition has + // not been specified via the config or an as an argument to startLoad (#3736). + startPosition = this.CiderHls.liveSyncPosition || sliding; + } else { + this.startPosition = startPosition = 0; + } + + this.lastCurrentTime = startPosition; + } + + this.nextLoadPosition = startPosition; + }; + + _proto.getLoadPosition = function getLoadPosition() { + var media = this.media; // if we have not yet loaded any fragment, start loading from start position + + var pos = 0; + + if (this.loadedmetadata && media) { + pos = media.currentTime; + } else if (this.nextLoadPosition) { + pos = this.nextLoadPosition; + } + + return pos; + }; + + _proto.handleFragLoadAborted = function handleFragLoadAborted(frag, part) { + if (this.transmuxer && frag.sn !== "initSegment" && frag.stats.aborted) { + this.warn("Fragment " + frag.sn + (part ? " part" + part.index : "") + " of level " + frag.level + " was aborted"); + this.resetFragmentLoading(frag); + } + }; + + _proto.resetFragmentLoading = function resetFragmentLoading(frag) { + if (!this.fragCurrent || !this.fragContextChanged(frag)) { + this.state = State.IDLE; + } + }; + + _proto.onFragmentOrKeyLoadError = function onFragmentOrKeyLoadError(filterType, data) { + if (data.fatal) { + return; + } + + var frag = data.frag; // Handle frag error related to caller's filterType + + if (!frag || frag.type !== filterType) { + return; + } + + var fragCurrent = this.fragCurrent; + console.assert(fragCurrent && frag.sn === fragCurrent.sn && frag.level === fragCurrent.level && frag.urlId === fragCurrent.urlId, "Frag load error must match current frag to retry"); + var config = this.config; // keep retrying until the limit will be reached + + if (this.fragLoadError + 1 <= config.fragLoadingMaxRetry) { + if (this.resetLiveStartWhenNotLoaded(frag.level)) { + return; + } // exponential backoff capped to config.fragLoadingMaxRetryTimeout + + var delay = Math.min(Math.pow(2, this.fragLoadError) * config.fragLoadingRetryDelay, config.fragLoadingMaxRetryTimeout); + this.warn("Fragment " + frag.sn + " of " + filterType + " " + frag.level + " failed to load, retrying in " + delay + "ms"); + this.retryDate = self.performance.now() + delay; + this.fragLoadError++; + this.state = State.FRAG_LOADING_WAITING_RETRY; + } else if (data.levelRetry) { + if (filterType === _types_loader__WEBPACK_IMPORTED_MODULE_15__["PlaylistLevelType"].AUDIO) { + // Reset current fragment since audio track audio is essential and may not have a fail-over track + this.fragCurrent = null; + } // Fragment errors that result in a level switch or redundant fail-over + // should reset the stream controller state to idle + + this.fragLoadError = 0; + this.state = State.IDLE; + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_4__["logger"].error(data.details + " reaches max retry, redispatch as fatal ..."); // switch error to fatal + + data.fatal = true; + this.CiderHls.stopLoad(); + this.state = State.ERROR; + } + }; + + _proto.afterBufferFlushed = function afterBufferFlushed(media, bufferType, playlistType) { + if (!media) { + return; + } // After successful buffer flushing, filter flushed fragments from bufferedFrags use mediaBuffered instead of media + // (so that we will check against video.buffered ranges in case of alt audio track) + + var bufferedTimeRanges = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].getBuffered(media); + this.fragmentTracker.detectEvictedFragments(bufferType, bufferedTimeRanges, playlistType); + + if (this.state === State.ENDED) { + this.resetLoadingState(); + } + }; + + _proto.resetLoadingState = function resetLoadingState() { + this.fragCurrent = null; + this.fragPrevious = null; + this.state = State.IDLE; + }; + + _proto.resetLiveStartWhenNotLoaded = function resetLiveStartWhenNotLoaded(level) { + // if loadedmetadata is not set, it means that we are emergency switch down on first frag + // in that case, reset startFragRequested flag + if (!this.loadedmetadata) { + this.startFragRequested = false; + var details = this.levels ? this.levels[level].details : null; + + if (details !== null && details !== void 0 && details.live) { + // We can't afford to retry after a delay in a live scenario. Update the start position and return to IDLE. + this.startPosition = -1; + this.setStartPosition(details, 0); + this.resetLoadingState(); + return true; + } + + this.nextLoadPosition = this.startPosition; + } + + return false; + }; + + _proto.updateLevelTiming = function updateLevelTiming(frag, part, level, partial) { + var _this6 = this; + + var details = level.details; + console.assert(!!details, "level.details must be defined"); + var parsed = Object.keys(frag.elementaryStreams).reduce(function (result, type) { + var info = frag.elementaryStreams[type]; + + if (info) { + var parsedDuration = info.endPTS - info.startPTS; + + if (parsedDuration <= 0) { + // Destroy the transmuxer after it's next time offset failed to advance because duration was <= 0. + // The new transmuxer will be configured with a time offset matching the next fragment start, + // preventing the timeline from shifting. + _this6.warn("Could not parse fragment " + frag.sn + " " + type + " duration reliably (" + parsedDuration + ") resetting transmuxer to fallback to playlist timing"); + + _this6.resetTransmuxer(); + + return result || false; + } + + var drift = partial ? 0 : Object(_level_helper__WEBPACK_IMPORTED_MODULE_11__["updateFragPTSDTS"])(details, frag, info.startPTS, info.endPTS, info.startDTS, info.endDTS); + + _this6.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].LEVEL_PTS_UPDATED, { + details: details, + level: level, + drift: drift, + type: type, + frag: frag, + start: info.startPTS, + end: info.endPTS, + }); + + return true; + } + + return result; + }, false); + + if (parsed) { + this.state = State.PARSED; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].FRAG_PARSED, { + frag: frag, + part: part, + }); + } else { + this.resetLoadingState(); + } + }; + + _proto.resetTransmuxer = function resetTransmuxer() { + if (this.transmuxer) { + this.transmuxer.destroy(); + this.transmuxer = null; + } + }; + + _createClass(BaseStreamController, [ + { + key: "state", + get: function get() { + return this._state; + }, + set: function set(nextState) { + var previousState = this._state; + + if (previousState !== nextState) { + this._state = nextState; + this.log(previousState + "->" + nextState); + } + }, + }, + ]); + + return BaseStreamController; + })(_task_loop__WEBPACK_IMPORTED_MODULE_1__["default"]); + + /***/ + }, + + /***/ "./src/controller/buffer-controller.ts": + /*!*********************************************!*\ !*** ./src/controller/buffer-controller.ts ***! \*********************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BufferController; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/mediasource-helper */ "./src/utils/mediasource-helper.ts"); -/* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); -/* harmony import */ var _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./buffer-operation-queue */ "./src/controller/buffer-operation-queue.ts"); - - - - - - - - - - - - -var MediaSource = Object(_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__["getMediaSource"])(); -var VIDEO_CODEC_PROFILE_REPACE = /([ha]vc.)(?:\.[^.,]+)+/; - -var BufferController = /*#__PURE__*/function () { - // The level details used to determine duration, target-duration and live - // cache the self generated object url to detect hijack of video tag - // A queue of buffer operations which require the SourceBuffer to not be updating upon execution - // References to event listeners for each SourceBuffer, so that they can be referenced for event removal - // The number of BUFFER_CODEC events received before any sourceBuffers are created - // The total number of BUFFER_CODEC events received - // A reference to the attached media element - // A reference to the active media source - // counters - function BufferController(_CiderHls) { - var _this = this; - - this.details = null; - this._objectUrl = null; - this.operationQueue = void 0; - this.listeners = void 0; - this.CiderHls = void 0; - this.bufferCodecEventsExpected = 0; - this._bufferCodecEventsTotal = 0; - this.media = null; - this.mediaSource = null; - this.appendError = 0; - this.tracks = {}; - this.pendingTracks = {}; - this.sourceBuffer = void 0; - - this._onMediaSourceOpen = function () { - var CiderHls = _this.CiderHls, - media = _this.media, - mediaSource = _this.mediaSource; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('[buffer-controller]: Media source opened'); - - if (media) { - _this.updateMediaElementDuration(); - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHED, { - media: media - }); - } - - if (mediaSource) { - // once received, don't listen anymore to sourceopen event - mediaSource.removeEventListener('sourceopen', _this._onMediaSourceOpen); - } - - _this.checkPendingTracks(); - }; - - this._onMediaSourceClose = function () { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('[buffer-controller]: Media source closed'); - }; - - this._onMediaSourceEnded = function () { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('[buffer-controller]: Media source ended'); - }; - - this.CiderHls = _CiderHls; - - this._initSourceBuffer(); - - this.registerListeners(); - } - - var _proto = BufferController.prototype; - - _proto.hasSourceTypes = function hasSourceTypes() { - return this.getSourceBufferTypes().length > 0 || Object.keys(this.pendingTracks).length > 0; - }; - - _proto.destroy = function destroy() { - this.unregisterListeners(); - this.details = null; - }; - - _proto.registerListeners = function registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_RESET, this.onBufferReset, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_APPENDING, this.onBufferAppending, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_EOS, this.onBufferEos, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSED, this.onFragParsed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_CHANGED, this.onFragChanged, this); - }; - - _proto.unregisterListeners = function unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_RESET, this.onBufferReset, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_APPENDING, this.onBufferAppending, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_EOS, this.onBufferEos, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSED, this.onFragParsed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_CHANGED, this.onFragChanged, this); - }; - - _proto._initSourceBuffer = function _initSourceBuffer() { - this.sourceBuffer = {}; - this.operationQueue = new _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__["default"](this.sourceBuffer); - this.listeners = { - audio: [], - video: [], - audiovideo: [] - }; - }; - - _proto.onManifestParsed = function onManifestParsed(event, data) { - // in case of alt audio 2 BUFFER_CODECS events will be triggered, one per stream controller - // sourcebuffers will be created all at once when the expected nb of tracks will be reached - // in case alt audio is not used, only one BUFFER_CODEC event will be fired from main stream controller - // it will contain the expected nb of source buffers, no need to compute it - var codecEvents = 2; - - if (data.audio && !data.video || !data.altAudio) { - codecEvents = 1; - } - - this.bufferCodecEventsExpected = this._bufferCodecEventsTotal = codecEvents; - this.details = null; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log(this.bufferCodecEventsExpected + " bufferCodec event(s) expected"); - }; - - _proto.onMediaAttaching = function onMediaAttaching(event, data) { - var media = this.media = data.media; - - if (media && MediaSource) { - var ms = this.mediaSource = new MediaSource(); // MediaSource listeners are arrow functions with a lexical scope, and do not need to be bound - - ms.addEventListener('sourceopen', this._onMediaSourceOpen); - ms.addEventListener('sourceended', this._onMediaSourceEnded); - ms.addEventListener('sourceclose', this._onMediaSourceClose); // link video and media Source - - media.src = self.URL.createObjectURL(ms); // cache the locally generated object url - - this._objectUrl = media.src; - } - }; - - _proto.onMediaDetaching = function onMediaDetaching() { - var media = this.media, - mediaSource = this.mediaSource, - _objectUrl = this._objectUrl; - - if (mediaSource) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('[buffer-controller]: media source detaching'); - - if (mediaSource.readyState === 'open') { - try { - // endOfStream could trigger exception if any sourcebuffer is in updating state - // we don't really care about checking sourcebuffer state here, - // as we are anyway detaching the MediaSource - // let's just avoid this exception to propagate - mediaSource.endOfStream(); - } catch (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: onMediaDetaching: " + err.message + " while calling endOfStream"); - } - } // Clean up the SourceBuffers by invoking onBufferReset - - - this.onBufferReset(); - mediaSource.removeEventListener('sourceopen', this._onMediaSourceOpen); - mediaSource.removeEventListener('sourceended', this._onMediaSourceEnded); - mediaSource.removeEventListener('sourceclose', this._onMediaSourceClose); // Detach properly the MediaSource from the HTMLMediaElement as - // suggested in https://github.com/w3c/media-source/issues/53. - - if (media) { - if (_objectUrl) { - self.URL.revokeObjectURL(_objectUrl); - } // clean up video tag src only if it's our own url. some external libraries might - // hijack the video tag and change its 'src' without destroying the CiderHls instance first - - - if (media.src === _objectUrl) { - media.removeAttribute('src'); - media.load(); - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn('[buffer-controller]: media.src was changed by a third party - skip cleanup'); - } - } - - this.mediaSource = null; - this.media = null; - this._objectUrl = null; - this.bufferCodecEventsExpected = this._bufferCodecEventsTotal; - this.pendingTracks = {}; - this.tracks = {}; - } - - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHED, undefined); - }; - - _proto.onBufferReset = function onBufferReset() { - var _this2 = this; - - this.getSourceBufferTypes().forEach(function (type) { - var sb = _this2.sourceBuffer[type]; - - try { - if (sb) { - _this2.removeBufferListeners(type); - - if (_this2.mediaSource) { - _this2.mediaSource.removeSourceBuffer(sb); - } // Synchronously remove the SB from the map before the next call in order to prevent an async function from - // accessing it - - - _this2.sourceBuffer[type] = undefined; - } - } catch (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Failed to reset the " + type + " buffer", err); - } - }); - - this._initSourceBuffer(); - }; - - _proto.onBufferCodecs = function onBufferCodecs(event, data) { - var _this3 = this; - - var sourceBufferCount = this.getSourceBufferTypes().length; - Object.keys(data).forEach(function (trackName) { - if (sourceBufferCount) { - // check if SourceBuffer codec needs to change - var track = _this3.tracks[trackName]; - - if (track && typeof track.buffer.changeType === 'function') { - var _data$trackName = data[trackName], - codec = _data$trackName.codec, - levelCodec = _data$trackName.levelCodec, - container = _data$trackName.container; - var currentCodec = (track.levelCodec || track.codec).replace(VIDEO_CODEC_PROFILE_REPACE, '$1'); - var nextCodec = (levelCodec || codec).replace(VIDEO_CODEC_PROFILE_REPACE, '$1'); - - if (currentCodec !== nextCodec) { - var mimeType = container + ";codecs=" + (levelCodec || codec); - - _this3.appendChangeType(trackName, mimeType); - } - } - } else { - // if source buffer(s) not created yet, appended buffer tracks in this.pendingTracks - _this3.pendingTracks[trackName] = data[trackName]; - } - }); // if sourcebuffers already created, do nothing ... - - if (sourceBufferCount) { - return; - } - - this.bufferCodecEventsExpected = Math.max(this.bufferCodecEventsExpected - 1, 0); - - if (this.mediaSource && this.mediaSource.readyState === 'open') { - this.checkPendingTracks(); - } - }; - - _proto.appendChangeType = function appendChangeType(type, mimeType) { - var _this4 = this; - - var operationQueue = this.operationQueue; - var operation = { - execute: function execute() { - var sb = _this4.sourceBuffer[type]; - - if (sb) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: changing " + type + " sourceBuffer type to " + mimeType); - sb.changeType(mimeType); - } - - operationQueue.shiftAndExecuteNext(type); - }, - onStart: function onStart() {}, - onComplete: function onComplete() {}, - onError: function onError(e) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Failed to change " + type + " SourceBuffer type", e); - } - }; - operationQueue.append(operation, type); - }; - - _proto.onBufferAppending = function onBufferAppending(event, eventData) { - var _this5 = this; - - var CiderHls = this.CiderHls, - operationQueue = this.operationQueue, - tracks = this.tracks; - var data = eventData.data, - type = eventData.type, - frag = eventData.frag, - part = eventData.part, - chunkMeta = eventData.chunkMeta; - var chunkStats = chunkMeta.buffering[type]; - var bufferAppendingStart = self.performance.now(); - chunkStats.start = bufferAppendingStart; - var fragBuffering = frag.stats.buffering; - var partBuffering = part ? part.stats.buffering : null; - - if (fragBuffering.start === 0) { - fragBuffering.start = bufferAppendingStart; - } - - if (partBuffering && partBuffering.start === 0) { - partBuffering.start = bufferAppendingStart; - } // TODO: Only update timestampOffset when audio/mpeg fragment or part is not contiguous with previously appended - // Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended) - // in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset` - // is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos). - // More info here: https://github.com/video-dev/CiderHls.js/issues/332#issuecomment-257986486 - - - var audioTrack = tracks.audio; - var checkTimestampOffset = type === 'audio' && chunkMeta.id === 1 && (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.container) === 'audio/mpeg'; - var operation = { - execute: function execute() { - chunkStats.executeStart = self.performance.now(); - - if (checkTimestampOffset) { - var sb = _this5.sourceBuffer[type]; - - if (sb) { - var delta = frag.start - sb.timestampOffset; - - if (Math.abs(delta) >= 0.1) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Updating audio SourceBuffer timestampOffset to " + frag.start + " (delta: " + delta + ") sn: " + frag.sn + ")"); - sb.timestampOffset = frag.start; - } - } - } - - _this5.appendExecutor(data, type); - }, - onStart: function onStart() {// logger.debug(`[buffer-controller]: ${type} SourceBuffer updatestart`); - }, - onComplete: function onComplete() { - // logger.debug(`[buffer-controller]: ${type} SourceBuffer updateend`); - var end = self.performance.now(); - chunkStats.executeEnd = chunkStats.end = end; - - if (fragBuffering.first === 0) { - fragBuffering.first = end; - } - - if (partBuffering && partBuffering.first === 0) { - partBuffering.first = end; - } - - var sourceBuffer = _this5.sourceBuffer; - var timeRanges = {}; - - for (var _type in sourceBuffer) { - timeRanges[_type] = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(sourceBuffer[_type]); - } - - _this5.appendError = 0; - - _this5.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_APPENDED, { - type: type, - frag: frag, - part: part, - chunkMeta: chunkMeta, - parent: frag.type, - timeRanges: timeRanges - }); - }, - onError: function onError(err) { - // in case any error occured while appending, put back segment in segments table - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: Error encountered while trying to append to the " + type + " SourceBuffer", err); - var event = { - type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, - parent: frag.type, - details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_APPEND_ERROR, - err: err, - fatal: false - }; - - if (err.code === DOMException.QUOTA_EXCEEDED_ERR) { - // QuotaExceededError: http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror - // let's stop appending any segments, and report BUFFER_FULL_ERROR error - event.details = _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_FULL_ERROR; - } else { - _this5.appendError++; - event.details = _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_APPEND_ERROR; - /* with UHD content, we could get loop of quota exceeded error until + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return BufferController; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/mediasource-helper */ "./src/utils/mediasource-helper.ts"); + /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); + /* harmony import */ var _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./buffer-operation-queue */ "./src/controller/buffer-operation-queue.ts"); + + var MediaSource = Object(_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__["getMediaSource"])(); + var VIDEO_CODEC_PROFILE_REPACE = /([ha]vc.)(?:\.[^.,]+)+/; + + var BufferController = /*#__PURE__*/ (function () { + // The level details used to determine duration, target-duration and live + // cache the self generated object url to detect hijack of video tag + // A queue of buffer operations which require the SourceBuffer to not be updating upon execution + // References to event listeners for each SourceBuffer, so that they can be referenced for event removal + // The number of BUFFER_CODEC events received before any sourceBuffers are created + // The total number of BUFFER_CODEC events received + // A reference to the attached media element + // A reference to the active media source + // counters + function BufferController(_CiderHls) { + var _this = this; + + this.details = null; + this._objectUrl = null; + this.operationQueue = void 0; + this.listeners = void 0; + this.CiderHls = void 0; + this.bufferCodecEventsExpected = 0; + this._bufferCodecEventsTotal = 0; + this.media = null; + this.mediaSource = null; + this.appendError = 0; + this.tracks = {}; + this.pendingTracks = {}; + this.sourceBuffer = void 0; + + this._onMediaSourceOpen = function () { + var CiderHls = _this.CiderHls, + media = _this.media, + mediaSource = _this.mediaSource; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Media source opened"); + + if (media) { + _this.updateMediaElementDuration(); + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHED, { + media: media, + }); + } + + if (mediaSource) { + // once received, don't listen anymore to sourceopen event + mediaSource.removeEventListener("sourceopen", _this._onMediaSourceOpen); + } + + _this.checkPendingTracks(); + }; + + this._onMediaSourceClose = function () { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Media source closed"); + }; + + this._onMediaSourceEnded = function () { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Media source ended"); + }; + + this.CiderHls = _CiderHls; + + this._initSourceBuffer(); + + this.registerListeners(); + } + + var _proto = BufferController.prototype; + + _proto.hasSourceTypes = function hasSourceTypes() { + return this.getSourceBufferTypes().length > 0 || Object.keys(this.pendingTracks).length > 0; + }; + + _proto.destroy = function destroy() { + this.unregisterListeners(); + this.details = null; + }; + + _proto.registerListeners = function registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_RESET, this.onBufferReset, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_APPENDING, this.onBufferAppending, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_EOS, this.onBufferEos, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSED, this.onFragParsed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_CHANGED, this.onFragChanged, this); + }; + + _proto.unregisterListeners = function unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_RESET, this.onBufferReset, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_APPENDING, this.onBufferAppending, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_EOS, this.onBufferEos, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSED, this.onFragParsed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_CHANGED, this.onFragChanged, this); + }; + + _proto._initSourceBuffer = function _initSourceBuffer() { + this.sourceBuffer = {}; + this.operationQueue = new _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__["default"](this.sourceBuffer); + this.listeners = { + audio: [], + video: [], + audiovideo: [], + }; + }; + + _proto.onManifestParsed = function onManifestParsed(event, data) { + // in case of alt audio 2 BUFFER_CODECS events will be triggered, one per stream controller + // sourcebuffers will be created all at once when the expected nb of tracks will be reached + // in case alt audio is not used, only one BUFFER_CODEC event will be fired from main stream controller + // it will contain the expected nb of source buffers, no need to compute it + var codecEvents = 2; + + if ((data.audio && !data.video) || !data.altAudio) { + codecEvents = 1; + } + + this.bufferCodecEventsExpected = this._bufferCodecEventsTotal = codecEvents; + this.details = null; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log(this.bufferCodecEventsExpected + " bufferCodec event(s) expected"); + }; + + _proto.onMediaAttaching = function onMediaAttaching(event, data) { + var media = (this.media = data.media); + + if (media && MediaSource) { + var ms = (this.mediaSource = new MediaSource()); // MediaSource listeners are arrow functions with a lexical scope, and do not need to be bound + + ms.addEventListener("sourceopen", this._onMediaSourceOpen); + ms.addEventListener("sourceended", this._onMediaSourceEnded); + ms.addEventListener("sourceclose", this._onMediaSourceClose); // link video and media Source + + media.src = self.URL.createObjectURL(ms); // cache the locally generated object url + + this._objectUrl = media.src; + } + }; + + _proto.onMediaDetaching = function onMediaDetaching() { + var media = this.media, + mediaSource = this.mediaSource, + _objectUrl = this._objectUrl; + + if (mediaSource) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: media source detaching"); + + if (mediaSource.readyState === "open") { + try { + // endOfStream could trigger exception if any sourcebuffer is in updating state + // we don't really care about checking sourcebuffer state here, + // as we are anyway detaching the MediaSource + // let's just avoid this exception to propagate + mediaSource.endOfStream(); + } catch (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: onMediaDetaching: " + err.message + " while calling endOfStream"); + } + } // Clean up the SourceBuffers by invoking onBufferReset + + this.onBufferReset(); + mediaSource.removeEventListener("sourceopen", this._onMediaSourceOpen); + mediaSource.removeEventListener("sourceended", this._onMediaSourceEnded); + mediaSource.removeEventListener("sourceclose", this._onMediaSourceClose); // Detach properly the MediaSource from the HTMLMediaElement as + // suggested in https://github.com/w3c/media-source/issues/53. + + if (media) { + if (_objectUrl) { + self.URL.revokeObjectURL(_objectUrl); + } // clean up video tag src only if it's our own url. some external libraries might + // hijack the video tag and change its 'src' without destroying the CiderHls instance first + + if (media.src === _objectUrl) { + media.removeAttribute("src"); + media.load(); + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: media.src was changed by a third party - skip cleanup"); + } + } + + this.mediaSource = null; + this.media = null; + this._objectUrl = null; + this.bufferCodecEventsExpected = this._bufferCodecEventsTotal; + this.pendingTracks = {}; + this.tracks = {}; + } + + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHED, undefined); + }; + + _proto.onBufferReset = function onBufferReset() { + var _this2 = this; + + this.getSourceBufferTypes().forEach(function (type) { + var sb = _this2.sourceBuffer[type]; + + try { + if (sb) { + _this2.removeBufferListeners(type); + + if (_this2.mediaSource) { + _this2.mediaSource.removeSourceBuffer(sb); + } // Synchronously remove the SB from the map before the next call in order to prevent an async function from + // accessing it + + _this2.sourceBuffer[type] = undefined; + } + } catch (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Failed to reset the " + type + " buffer", err); + } + }); + + this._initSourceBuffer(); + }; + + _proto.onBufferCodecs = function onBufferCodecs(event, data) { + var _this3 = this; + + var sourceBufferCount = this.getSourceBufferTypes().length; + Object.keys(data).forEach(function (trackName) { + if (sourceBufferCount) { + // check if SourceBuffer codec needs to change + var track = _this3.tracks[trackName]; + + if (track && typeof track.buffer.changeType === "function") { + var _data$trackName = data[trackName], + codec = _data$trackName.codec, + levelCodec = _data$trackName.levelCodec, + container = _data$trackName.container; + var currentCodec = (track.levelCodec || track.codec).replace(VIDEO_CODEC_PROFILE_REPACE, "$1"); + var nextCodec = (levelCodec || codec).replace(VIDEO_CODEC_PROFILE_REPACE, "$1"); + + if (currentCodec !== nextCodec) { + var mimeType = container + ";codecs=" + (levelCodec || codec); + + _this3.appendChangeType(trackName, mimeType); + } + } + } else { + // if source buffer(s) not created yet, appended buffer tracks in this.pendingTracks + _this3.pendingTracks[trackName] = data[trackName]; + } + }); // if sourcebuffers already created, do nothing ... + + if (sourceBufferCount) { + return; + } + + this.bufferCodecEventsExpected = Math.max(this.bufferCodecEventsExpected - 1, 0); + + if (this.mediaSource && this.mediaSource.readyState === "open") { + this.checkPendingTracks(); + } + }; + + _proto.appendChangeType = function appendChangeType(type, mimeType) { + var _this4 = this; + + var operationQueue = this.operationQueue; + var operation = { + execute: function execute() { + var sb = _this4.sourceBuffer[type]; + + if (sb) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: changing " + type + " sourceBuffer type to " + mimeType); + sb.changeType(mimeType); + } + + operationQueue.shiftAndExecuteNext(type); + }, + onStart: function onStart() {}, + onComplete: function onComplete() {}, + onError: function onError(e) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Failed to change " + type + " SourceBuffer type", e); + }, + }; + operationQueue.append(operation, type); + }; + + _proto.onBufferAppending = function onBufferAppending(event, eventData) { + var _this5 = this; + + var CiderHls = this.CiderHls, + operationQueue = this.operationQueue, + tracks = this.tracks; + var data = eventData.data, + type = eventData.type, + frag = eventData.frag, + part = eventData.part, + chunkMeta = eventData.chunkMeta; + var chunkStats = chunkMeta.buffering[type]; + var bufferAppendingStart = self.performance.now(); + chunkStats.start = bufferAppendingStart; + var fragBuffering = frag.stats.buffering; + var partBuffering = part ? part.stats.buffering : null; + + if (fragBuffering.start === 0) { + fragBuffering.start = bufferAppendingStart; + } + + if (partBuffering && partBuffering.start === 0) { + partBuffering.start = bufferAppendingStart; + } // TODO: Only update timestampOffset when audio/mpeg fragment or part is not contiguous with previously appended + // Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended) + // in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset` + // is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos). + // More info here: https://github.com/video-dev/CiderHls.js/issues/332#issuecomment-257986486 + + var audioTrack = tracks.audio; + var checkTimestampOffset = type === "audio" && chunkMeta.id === 1 && (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.container) === "audio/mpeg"; + var operation = { + execute: function execute() { + chunkStats.executeStart = self.performance.now(); + + if (checkTimestampOffset) { + var sb = _this5.sourceBuffer[type]; + + if (sb) { + var delta = frag.start - sb.timestampOffset; + + if (Math.abs(delta) >= 0.1) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Updating audio SourceBuffer timestampOffset to " + frag.start + " (delta: " + delta + ") sn: " + frag.sn + ")"); + sb.timestampOffset = frag.start; + } + } + } + + _this5.appendExecutor(data, type); + }, + onStart: function onStart() { + // logger.debug(`[buffer-controller]: ${type} SourceBuffer updatestart`); + }, + onComplete: function onComplete() { + // logger.debug(`[buffer-controller]: ${type} SourceBuffer updateend`); + var end = self.performance.now(); + chunkStats.executeEnd = chunkStats.end = end; + + if (fragBuffering.first === 0) { + fragBuffering.first = end; + } + + if (partBuffering && partBuffering.first === 0) { + partBuffering.first = end; + } + + var sourceBuffer = _this5.sourceBuffer; + var timeRanges = {}; + + for (var _type in sourceBuffer) { + timeRanges[_type] = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(sourceBuffer[_type]); + } + + _this5.appendError = 0; + + _this5.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_APPENDED, { + type: type, + frag: frag, + part: part, + chunkMeta: chunkMeta, + parent: frag.type, + timeRanges: timeRanges, + }); + }, + onError: function onError(err) { + // in case any error occured while appending, put back segment in segments table + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: Error encountered while trying to append to the " + type + " SourceBuffer", err); + var event = { + type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, + parent: frag.type, + details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_APPEND_ERROR, + err: err, + fatal: false, + }; + + if (err.code === DOMException.QUOTA_EXCEEDED_ERR) { + // QuotaExceededError: http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror + // let's stop appending any segments, and report BUFFER_FULL_ERROR error + event.details = _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_FULL_ERROR; + } else { + _this5.appendError++; + event.details = _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_APPEND_ERROR; + /* with UHD content, we could get loop of quota exceeded error until browser is able to evict some data from sourcebuffer. Retrying can help recover. */ - if (_this5.appendError > CiderHls.config.appendErrorMaxRetry) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: Failed " + CiderHls.config.appendErrorMaxRetry + " times to append segment in sourceBuffer"); - event.fatal = true; - } - } - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, event); - } - }; - operationQueue.append(operation, type); - }; - - _proto.onBufferFlushing = function onBufferFlushing(event, data) { - var _this6 = this; - - var operationQueue = this.operationQueue; - - var flushOperation = function flushOperation(type) { - return { - execute: _this6.removeExecutor.bind(_this6, type, data.startOffset, data.endOffset), - onStart: function onStart() {// logger.debug(`[buffer-controller]: Started flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`); - }, - onComplete: function onComplete() { - // logger.debug(`[buffer-controller]: Finished flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`); - _this6.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHED, { - type: type - }); - }, - onError: function onError(e) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Failed to remove from " + type + " SourceBuffer", e); - } - }; - }; - - if (data.type) { - operationQueue.append(flushOperation(data.type), data.type); - } else { - this.getSourceBufferTypes().forEach(function (type) { - operationQueue.append(flushOperation(type), type); - }); - } - }; - - _proto.onFragParsed = function onFragParsed(event, data) { - var _this7 = this; - - var frag = data.frag, - part = data.part; - var buffersAppendedTo = []; - var elementaryStreams = part ? part.elementaryStreams : frag.elementaryStreams; - - if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__["ElementaryStreamTypes"].AUDIOVIDEO]) { - buffersAppendedTo.push('audiovideo'); - } else { - if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__["ElementaryStreamTypes"].AUDIO]) { - buffersAppendedTo.push('audio'); - } - - if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__["ElementaryStreamTypes"].VIDEO]) { - buffersAppendedTo.push('video'); - } - } - - var onUnblocked = function onUnblocked() { - var now = self.performance.now(); - frag.stats.buffering.end = now; - - if (part) { - part.stats.buffering.end = now; - } - - var stats = part ? part.stats : frag.stats; - - _this7.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_BUFFERED, { - frag: frag, - part: part, - stats: stats, - id: frag.type - }); - }; - - if (buffersAppendedTo.length === 0) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("Fragments must have at least one ElementaryStreamType set. type: " + frag.type + " level: " + frag.level + " sn: " + frag.sn); - } - - this.blockBuffers(onUnblocked, buffersAppendedTo); - }; - - _proto.onFragChanged = function onFragChanged(event, data) { - this.flushBackBuffer(); - } // on BUFFER_EOS mark matching sourcebuffer(s) as ended and trigger checkEos() - // an undefined data.type will mark all buffers as EOS. - ; - - _proto.onBufferEos = function onBufferEos(event, data) { - var _this8 = this; - - var ended = this.getSourceBufferTypes().reduce(function (acc, type) { - var sb = _this8.sourceBuffer[type]; - - if (!data.type || data.type === type) { - if (sb && !sb.ended) { - sb.ended = true; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: " + type + " sourceBuffer now EOS"); - } - } - - return acc && !!(!sb || sb.ended); - }, true); - - if (ended) { - this.blockBuffers(function () { - var mediaSource = _this8.mediaSource; - - if (!mediaSource || mediaSource.readyState !== 'open') { - return; - } // Allow this to throw and be caught by the enqueueing function - - - mediaSource.endOfStream(); - }); - } - }; - - _proto.onLevelUpdated = function onLevelUpdated(event, _ref) { - var details = _ref.details; - - if (!details.fragments.length) { - return; - } - - this.details = details; - - if (this.getSourceBufferTypes().length) { - this.blockBuffers(this.updateMediaElementDuration.bind(this)); - } else { - this.updateMediaElementDuration(); - } - }; - - _proto.flushBackBuffer = function flushBackBuffer() { - var CiderHls = this.CiderHls, - details = this.details, - media = this.media, - sourceBuffer = this.sourceBuffer; - - if (!media || details === null) { - return; - } - - var sourceBufferTypes = this.getSourceBufferTypes(); - - if (!sourceBufferTypes.length) { - return; - } // Support for deprecated liveBackBufferLength - - - var backBufferLength = details.live && CiderHls.config.liveBackBufferLength !== null ? CiderHls.config.liveBackBufferLength : CiderHls.config.backBufferLength; - - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(backBufferLength) || backBufferLength < 0) { - return; - } - - var currentTime = media.currentTime; - var targetDuration = details.levelTargetDuration; - var maxBackBufferLength = Math.max(backBufferLength, targetDuration); - var targetBackBufferPosition = Math.floor(currentTime / targetDuration) * targetDuration - maxBackBufferLength; - sourceBufferTypes.forEach(function (type) { - var sb = sourceBuffer[type]; - - if (sb) { - var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(sb); // when target buffer start exceeds actual buffer start - - if (buffered.length > 0 && targetBackBufferPosition > buffered.start(0)) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BACK_BUFFER_REACHED, { - bufferEnd: targetBackBufferPosition - }); // Support for deprecated event: - - if (details.live) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LIVE_BACK_BUFFER_REACHED, { - bufferEnd: targetBackBufferPosition - }); - } - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, { - startOffset: 0, - endOffset: targetBackBufferPosition, - type: type - }); - } - } - }); - } - /** - * Update Media Source duration to current level duration or override to Infinity if configuration parameter - * 'liveDurationInfinity` is set to `true` - * More details: https://github.com/video-dev/CiderHls.js/issues/355 - */ - ; - - _proto.updateMediaElementDuration = function updateMediaElementDuration() { - if (!this.details || !this.media || !this.mediaSource || this.mediaSource.readyState !== 'open') { - return; - } - - var details = this.details, - CiderHls = this.CiderHls, - media = this.media, - mediaSource = this.mediaSource; - var levelDuration = details.fragments[0].start + details.totalduration; - var mediaDuration = media.duration; - var msDuration = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mediaSource.duration) ? mediaSource.duration : 0; - - if (details.live && CiderHls.config.liveDurationInfinity) { - // Override duration to Infinity - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('[buffer-controller]: Media Source duration is set to Infinity'); - mediaSource.duration = Infinity; - this.updateSeekableRange(details); - } else if (levelDuration > msDuration && levelDuration > mediaDuration || !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mediaDuration)) { - // levelDuration was the last value we set. - // not using mediaSource.duration as the browser may tweak this value - // only update Media Source duration if its value increase, this is to avoid - // flushing already buffered portion when switching between quality level - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Updating Media Source duration to " + levelDuration.toFixed(3)); - mediaSource.duration = levelDuration; - } - }; - - _proto.updateSeekableRange = function updateSeekableRange(levelDetails) { - var mediaSource = this.mediaSource; - var fragments = levelDetails.fragments; - var len = fragments.length; - - if (len && levelDetails.live && mediaSource !== null && mediaSource !== void 0 && mediaSource.setLiveSeekableRange) { - var start = Math.max(0, fragments[0].start); - var end = Math.max(start, start + levelDetails.totalduration); - mediaSource.setLiveSeekableRange(start, end); - } - }; - - _proto.checkPendingTracks = function checkPendingTracks() { - var bufferCodecEventsExpected = this.bufferCodecEventsExpected, - operationQueue = this.operationQueue, - pendingTracks = this.pendingTracks; // Check if we've received all of the expected bufferCodec events. When none remain, create all the sourceBuffers at once. - // This is important because the MSE spec allows implementations to throw QuotaExceededErrors if creating new sourceBuffers after - // data has been appended to existing ones. - // 2 tracks is the max (one for audio, one for video). If we've reach this max go ahead and create the buffers. - - var pendingTracksCount = Object.keys(pendingTracks).length; - - if (pendingTracksCount && !bufferCodecEventsExpected || pendingTracksCount === 2) { - // ok, let's create them now ! - this.createSourceBuffers(pendingTracks); - this.pendingTracks = {}; // append any pending segments now ! - - var buffers = this.getSourceBufferTypes(); - - if (buffers.length === 0) { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_INCOMPATIBLE_CODECS_ERROR, - fatal: true, - reason: 'could not create source buffer for media codec(s)' - }); - return; - } - - buffers.forEach(function (type) { - operationQueue.executeNext(type); - }); - } - }; - - _proto.createSourceBuffers = function createSourceBuffers(tracks) { - var sourceBuffer = this.sourceBuffer, - mediaSource = this.mediaSource; - - if (!mediaSource) { - throw Error('createSourceBuffers called when mediaSource was null'); - } - - var tracksCreated = 0; - - for (var trackName in tracks) { - if (!sourceBuffer[trackName]) { - var track = tracks[trackName]; - - if (!track) { - throw Error("source buffer exists for track " + trackName + ", however track does not"); - } // use levelCodec as first priority - - - var codec = track.levelCodec || track.codec; - var mimeType = track.container + ";codecs=" + codec; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: creating sourceBuffer(" + mimeType + ")"); - - try { - var sb = sourceBuffer[trackName] = mediaSource.addSourceBuffer(mimeType); - var sbName = trackName; - this.addBufferListener(sbName, 'updatestart', this._onSBUpdateStart); - this.addBufferListener(sbName, 'updateend', this._onSBUpdateEnd); - this.addBufferListener(sbName, 'error', this._onSBUpdateError); - this.tracks[trackName] = { - buffer: sb, - codec: codec, - container: track.container, - levelCodec: track.levelCodec, - id: track.id - }; - tracksCreated++; - } catch (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: error while trying to add sourceBuffer: " + err.message); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_ADD_CODEC_ERROR, - fatal: false, - error: err, - mimeType: mimeType - }); - } - } - } - - if (tracksCreated) { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_CREATED, { - tracks: this.tracks - }); - } - } // Keep as arrow functions so that we can directly reference these functions directly as event listeners - ; - - _proto._onSBUpdateStart = function _onSBUpdateStart(type) { - var operationQueue = this.operationQueue; - var operation = operationQueue.current(type); - operation.onStart(); - }; - - _proto._onSBUpdateEnd = function _onSBUpdateEnd(type) { - var operationQueue = this.operationQueue; - var operation = operationQueue.current(type); - operation.onComplete(); - operationQueue.shiftAndExecuteNext(type); - }; - - _proto._onSBUpdateError = function _onSBUpdateError(type, event) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: " + type + " SourceBuffer error", event); // according to http://www.w3.org/TR/media-source/#sourcebuffer-append-error - // SourceBuffer errors are not necessarily fatal; if so, the HTMLMediaElement will fire an error event - - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_APPENDING_ERROR, - fatal: false - }); // updateend is always fired after error, so we'll allow that to shift the current operation off of the queue - - var operation = this.operationQueue.current(type); - - if (operation) { - operation.onError(event); - } - } // This method must result in an updateend event; if remove is not called, _onSBUpdateEnd must be called manually - ; - - _proto.removeExecutor = function removeExecutor(type, startOffset, endOffset) { - var media = this.media, - mediaSource = this.mediaSource, - operationQueue = this.operationQueue, - sourceBuffer = this.sourceBuffer; - var sb = sourceBuffer[type]; - - if (!media || !mediaSource || !sb) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Attempting to remove from the " + type + " SourceBuffer, but it does not exist"); - operationQueue.shiftAndExecuteNext(type); - return; - } - - var mediaDuration = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(media.duration) ? media.duration : Infinity; - var msDuration = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mediaSource.duration) ? mediaSource.duration : Infinity; - var removeStart = Math.max(0, startOffset); - var removeEnd = Math.min(endOffset, mediaDuration, msDuration); - - if (removeEnd > removeStart) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Removing [" + removeStart + "," + removeEnd + "] from the " + type + " SourceBuffer"); - console.assert(!sb.updating, type + " sourceBuffer must not be updating"); - sb.remove(removeStart, removeEnd); - } else { - // Cycle the queue - operationQueue.shiftAndExecuteNext(type); - } - } // This method must result in an updateend event; if append is not called, _onSBUpdateEnd must be called manually - ; - - _proto.appendExecutor = function appendExecutor(data, type) { - var operationQueue = this.operationQueue, - sourceBuffer = this.sourceBuffer; - var sb = sourceBuffer[type]; - - if (!sb) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Attempting to append to the " + type + " SourceBuffer, but it does not exist"); - operationQueue.shiftAndExecuteNext(type); - return; - } - - sb.ended = false; - console.assert(!sb.updating, type + " sourceBuffer must not be updating"); - sb.appendBuffer(data); - } // Enqueues an operation to each SourceBuffer queue which, upon execution, resolves a promise. When all promises - // resolve, the onUnblocked function is executed. Functions calling this method do not need to unblock the queue - // upon completion, since we already do it here - ; - - _proto.blockBuffers = function blockBuffers(onUnblocked, buffers) { - var _this9 = this; - - if (buffers === void 0) { - buffers = this.getSourceBufferTypes(); - } - - if (!buffers.length) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('[buffer-controller]: Blocking operation requested, but no SourceBuffers exist'); - Promise.resolve(onUnblocked); - return; - } - - var operationQueue = this.operationQueue; // logger.debug(`[buffer-controller]: Blocking ${buffers} SourceBuffer`); - - var blockingOperations = buffers.map(function (type) { - return operationQueue.appendBlocker(type); - }); - Promise.all(blockingOperations).then(function () { - // logger.debug(`[buffer-controller]: Blocking operation resolved; unblocking ${buffers} SourceBuffer`); - onUnblocked(); - buffers.forEach(function (type) { - var sb = _this9.sourceBuffer[type]; // Only cycle the queue if the SB is not updating. There's a bug in Chrome which sets the SB updating flag to - // true when changing the MediaSource duration (https://bugs.chromium.org/p/chromium/issues/detail?id=959359&can=2&q=mediasource%20duration) - // While this is a workaround, it's probably useful to have around - - if (!sb || !sb.updating) { - operationQueue.shiftAndExecuteNext(type); - } - }); - }); - }; - - _proto.getSourceBufferTypes = function getSourceBufferTypes() { - return Object.keys(this.sourceBuffer); - }; - - _proto.addBufferListener = function addBufferListener(type, event, fn) { - var buffer = this.sourceBuffer[type]; - - if (!buffer) { - return; - } - - var listener = fn.bind(this, type); - this.listeners[type].push({ - event: event, - listener: listener - }); - buffer.addEventListener(event, listener); - }; - - _proto.removeBufferListeners = function removeBufferListeners(type) { - var buffer = this.sourceBuffer[type]; - - if (!buffer) { - return; - } - - this.listeners[type].forEach(function (l) { - buffer.removeEventListener(l.event, l.listener); - }); - }; - - return BufferController; -}(); - - - -/***/ }), - -/***/ "./src/controller/buffer-operation-queue.ts": -/*!**************************************************!*\ + if (_this5.appendError > CiderHls.config.appendErrorMaxRetry) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: Failed " + CiderHls.config.appendErrorMaxRetry + " times to append segment in sourceBuffer"); + event.fatal = true; + } + } + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, event); + }, + }; + operationQueue.append(operation, type); + }; + + _proto.onBufferFlushing = function onBufferFlushing(event, data) { + var _this6 = this; + + var operationQueue = this.operationQueue; + + var flushOperation = function flushOperation(type) { + return { + execute: _this6.removeExecutor.bind(_this6, type, data.startOffset, data.endOffset), + onStart: function onStart() { + // logger.debug(`[buffer-controller]: Started flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`); + }, + onComplete: function onComplete() { + // logger.debug(`[buffer-controller]: Finished flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`); + _this6.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHED, { + type: type, + }); + }, + onError: function onError(e) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Failed to remove from " + type + " SourceBuffer", e); + }, + }; + }; + + if (data.type) { + operationQueue.append(flushOperation(data.type), data.type); + } else { + this.getSourceBufferTypes().forEach(function (type) { + operationQueue.append(flushOperation(type), type); + }); + } + }; + + _proto.onFragParsed = function onFragParsed(event, data) { + var _this7 = this; + + var frag = data.frag, + part = data.part; + var buffersAppendedTo = []; + var elementaryStreams = part ? part.elementaryStreams : frag.elementaryStreams; + + if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__["ElementaryStreamTypes"].AUDIOVIDEO]) { + buffersAppendedTo.push("audiovideo"); + } else { + if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__["ElementaryStreamTypes"].AUDIO]) { + buffersAppendedTo.push("audio"); + } + + if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__["ElementaryStreamTypes"].VIDEO]) { + buffersAppendedTo.push("video"); + } + } + + var onUnblocked = function onUnblocked() { + var now = self.performance.now(); + frag.stats.buffering.end = now; + + if (part) { + part.stats.buffering.end = now; + } + + var stats = part ? part.stats : frag.stats; + + _this7.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_BUFFERED, { + frag: frag, + part: part, + stats: stats, + id: frag.type, + }); + }; + + if (buffersAppendedTo.length === 0) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("Fragments must have at least one ElementaryStreamType set. type: " + frag.type + " level: " + frag.level + " sn: " + frag.sn); + } + + this.blockBuffers(onUnblocked, buffersAppendedTo); + }; + + _proto.onFragChanged = function onFragChanged(event, data) { + this.flushBackBuffer(); + }; // on BUFFER_EOS mark matching sourcebuffer(s) as ended and trigger checkEos() + // an undefined data.type will mark all buffers as EOS. + + _proto.onBufferEos = function onBufferEos(event, data) { + var _this8 = this; + + var ended = this.getSourceBufferTypes().reduce(function (acc, type) { + var sb = _this8.sourceBuffer[type]; + + if (!data.type || data.type === type) { + if (sb && !sb.ended) { + sb.ended = true; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: " + type + " sourceBuffer now EOS"); + } + } + + return acc && !!(!sb || sb.ended); + }, true); + + if (ended) { + this.blockBuffers(function () { + var mediaSource = _this8.mediaSource; + + if (!mediaSource || mediaSource.readyState !== "open") { + return; + } // Allow this to throw and be caught by the enqueueing function + + mediaSource.endOfStream(); + }); + } + }; + + _proto.onLevelUpdated = function onLevelUpdated(event, _ref) { + var details = _ref.details; + + if (!details.fragments.length) { + return; + } + + this.details = details; + + if (this.getSourceBufferTypes().length) { + this.blockBuffers(this.updateMediaElementDuration.bind(this)); + } else { + this.updateMediaElementDuration(); + } + }; + + _proto.flushBackBuffer = function flushBackBuffer() { + var CiderHls = this.CiderHls, + details = this.details, + media = this.media, + sourceBuffer = this.sourceBuffer; + + if (!media || details === null) { + return; + } + + var sourceBufferTypes = this.getSourceBufferTypes(); + + if (!sourceBufferTypes.length) { + return; + } // Support for deprecated liveBackBufferLength + + var backBufferLength = details.live && CiderHls.config.liveBackBufferLength !== null ? CiderHls.config.liveBackBufferLength : CiderHls.config.backBufferLength; + + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(backBufferLength) || backBufferLength < 0) { + return; + } + + var currentTime = media.currentTime; + var targetDuration = details.levelTargetDuration; + var maxBackBufferLength = Math.max(backBufferLength, targetDuration); + var targetBackBufferPosition = Math.floor(currentTime / targetDuration) * targetDuration - maxBackBufferLength; + sourceBufferTypes.forEach(function (type) { + var sb = sourceBuffer[type]; + + if (sb) { + var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(sb); // when target buffer start exceeds actual buffer start + + if (buffered.length > 0 && targetBackBufferPosition > buffered.start(0)) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BACK_BUFFER_REACHED, { + bufferEnd: targetBackBufferPosition, + }); // Support for deprecated event: + + if (details.live) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LIVE_BACK_BUFFER_REACHED, { + bufferEnd: targetBackBufferPosition, + }); + } + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, { + startOffset: 0, + endOffset: targetBackBufferPosition, + type: type, + }); + } + } + }); + }; + /** + * Update Media Source duration to current level duration or override to Infinity if configuration parameter + * 'liveDurationInfinity` is set to `true` + * More details: https://github.com/video-dev/CiderHls.js/issues/355 + */ + + _proto.updateMediaElementDuration = function updateMediaElementDuration() { + if (!this.details || !this.media || !this.mediaSource || this.mediaSource.readyState !== "open") { + return; + } + + var details = this.details, + CiderHls = this.CiderHls, + media = this.media, + mediaSource = this.mediaSource; + var levelDuration = details.fragments[0].start + details.totalduration; + var mediaDuration = media.duration; + var msDuration = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mediaSource.duration) ? mediaSource.duration : 0; + + if (details.live && CiderHls.config.liveDurationInfinity) { + // Override duration to Infinity + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Media Source duration is set to Infinity"); + mediaSource.duration = Infinity; + this.updateSeekableRange(details); + } else if ((levelDuration > msDuration && levelDuration > mediaDuration) || !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mediaDuration)) { + // levelDuration was the last value we set. + // not using mediaSource.duration as the browser may tweak this value + // only update Media Source duration if its value increase, this is to avoid + // flushing already buffered portion when switching between quality level + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Updating Media Source duration to " + levelDuration.toFixed(3)); + mediaSource.duration = levelDuration; + } + }; + + _proto.updateSeekableRange = function updateSeekableRange(levelDetails) { + var mediaSource = this.mediaSource; + var fragments = levelDetails.fragments; + var len = fragments.length; + + if (len && levelDetails.live && mediaSource !== null && mediaSource !== void 0 && mediaSource.setLiveSeekableRange) { + var start = Math.max(0, fragments[0].start); + var end = Math.max(start, start + levelDetails.totalduration); + mediaSource.setLiveSeekableRange(start, end); + } + }; + + _proto.checkPendingTracks = function checkPendingTracks() { + var bufferCodecEventsExpected = this.bufferCodecEventsExpected, + operationQueue = this.operationQueue, + pendingTracks = this.pendingTracks; // Check if we've received all of the expected bufferCodec events. When none remain, create all the sourceBuffers at once. + // This is important because the MSE spec allows implementations to throw QuotaExceededErrors if creating new sourceBuffers after + // data has been appended to existing ones. + // 2 tracks is the max (one for audio, one for video). If we've reach this max go ahead and create the buffers. + + var pendingTracksCount = Object.keys(pendingTracks).length; + + if ((pendingTracksCount && !bufferCodecEventsExpected) || pendingTracksCount === 2) { + // ok, let's create them now ! + this.createSourceBuffers(pendingTracks); + this.pendingTracks = {}; // append any pending segments now ! + + var buffers = this.getSourceBufferTypes(); + + if (buffers.length === 0) { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_INCOMPATIBLE_CODECS_ERROR, + fatal: true, + reason: "could not create source buffer for media codec(s)", + }); + return; + } + + buffers.forEach(function (type) { + operationQueue.executeNext(type); + }); + } + }; + + _proto.createSourceBuffers = function createSourceBuffers(tracks) { + var sourceBuffer = this.sourceBuffer, + mediaSource = this.mediaSource; + + if (!mediaSource) { + throw Error("createSourceBuffers called when mediaSource was null"); + } + + var tracksCreated = 0; + + for (var trackName in tracks) { + if (!sourceBuffer[trackName]) { + var track = tracks[trackName]; + + if (!track) { + throw Error("source buffer exists for track " + trackName + ", however track does not"); + } // use levelCodec as first priority + + var codec = track.levelCodec || track.codec; + var mimeType = track.container + ";codecs=" + codec; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: creating sourceBuffer(" + mimeType + ")"); + + try { + var sb = (sourceBuffer[trackName] = mediaSource.addSourceBuffer(mimeType)); + var sbName = trackName; + this.addBufferListener(sbName, "updatestart", this._onSBUpdateStart); + this.addBufferListener(sbName, "updateend", this._onSBUpdateEnd); + this.addBufferListener(sbName, "error", this._onSBUpdateError); + this.tracks[trackName] = { + buffer: sb, + codec: codec, + container: track.container, + levelCodec: track.levelCodec, + id: track.id, + }; + tracksCreated++; + } catch (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: error while trying to add sourceBuffer: " + err.message); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_ADD_CODEC_ERROR, + fatal: false, + error: err, + mimeType: mimeType, + }); + } + } + } + + if (tracksCreated) { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_CREATED, { + tracks: this.tracks, + }); + } + }; // Keep as arrow functions so that we can directly reference these functions directly as event listeners + + _proto._onSBUpdateStart = function _onSBUpdateStart(type) { + var operationQueue = this.operationQueue; + var operation = operationQueue.current(type); + operation.onStart(); + }; + + _proto._onSBUpdateEnd = function _onSBUpdateEnd(type) { + var operationQueue = this.operationQueue; + var operation = operationQueue.current(type); + operation.onComplete(); + operationQueue.shiftAndExecuteNext(type); + }; + + _proto._onSBUpdateError = function _onSBUpdateError(type, event) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("[buffer-controller]: " + type + " SourceBuffer error", event); // according to http://www.w3.org/TR/media-source/#sourcebuffer-append-error + // SourceBuffer errors are not necessarily fatal; if so, the HTMLMediaElement will fire an error event + + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_3__["ErrorDetails"].BUFFER_APPENDING_ERROR, + fatal: false, + }); // updateend is always fired after error, so we'll allow that to shift the current operation off of the queue + + var operation = this.operationQueue.current(type); + + if (operation) { + operation.onError(event); + } + }; // This method must result in an updateend event; if remove is not called, _onSBUpdateEnd must be called manually + + _proto.removeExecutor = function removeExecutor(type, startOffset, endOffset) { + var media = this.media, + mediaSource = this.mediaSource, + operationQueue = this.operationQueue, + sourceBuffer = this.sourceBuffer; + var sb = sourceBuffer[type]; + + if (!media || !mediaSource || !sb) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Attempting to remove from the " + type + " SourceBuffer, but it does not exist"); + operationQueue.shiftAndExecuteNext(type); + return; + } + + var mediaDuration = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(media.duration) ? media.duration : Infinity; + var msDuration = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mediaSource.duration) ? mediaSource.duration : Infinity; + var removeStart = Math.max(0, startOffset); + var removeEnd = Math.min(endOffset, mediaDuration, msDuration); + + if (removeEnd > removeStart) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Removing [" + removeStart + "," + removeEnd + "] from the " + type + " SourceBuffer"); + console.assert(!sb.updating, type + " sourceBuffer must not be updating"); + sb.remove(removeStart, removeEnd); + } else { + // Cycle the queue + operationQueue.shiftAndExecuteNext(type); + } + }; // This method must result in an updateend event; if append is not called, _onSBUpdateEnd must be called manually + + _proto.appendExecutor = function appendExecutor(data, type) { + var operationQueue = this.operationQueue, + sourceBuffer = this.sourceBuffer; + var sb = sourceBuffer[type]; + + if (!sb) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[buffer-controller]: Attempting to append to the " + type + " SourceBuffer, but it does not exist"); + operationQueue.shiftAndExecuteNext(type); + return; + } + + sb.ended = false; + console.assert(!sb.updating, type + " sourceBuffer must not be updating"); + sb.appendBuffer(data); + }; // Enqueues an operation to each SourceBuffer queue which, upon execution, resolves a promise. When all promises + // resolve, the onUnblocked function is executed. Functions calling this method do not need to unblock the queue + // upon completion, since we already do it here + + _proto.blockBuffers = function blockBuffers(onUnblocked, buffers) { + var _this9 = this; + + if (buffers === void 0) { + buffers = this.getSourceBufferTypes(); + } + + if (!buffers.length) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("[buffer-controller]: Blocking operation requested, but no SourceBuffers exist"); + Promise.resolve(onUnblocked); + return; + } + + var operationQueue = this.operationQueue; // logger.debug(`[buffer-controller]: Blocking ${buffers} SourceBuffer`); + + var blockingOperations = buffers.map(function (type) { + return operationQueue.appendBlocker(type); + }); + Promise.all(blockingOperations).then(function () { + // logger.debug(`[buffer-controller]: Blocking operation resolved; unblocking ${buffers} SourceBuffer`); + onUnblocked(); + buffers.forEach(function (type) { + var sb = _this9.sourceBuffer[type]; // Only cycle the queue if the SB is not updating. There's a bug in Chrome which sets the SB updating flag to + // true when changing the MediaSource duration (https://bugs.chromium.org/p/chromium/issues/detail?id=959359&can=2&q=mediasource%20duration) + // While this is a workaround, it's probably useful to have around + + if (!sb || !sb.updating) { + operationQueue.shiftAndExecuteNext(type); + } + }); + }); + }; + + _proto.getSourceBufferTypes = function getSourceBufferTypes() { + return Object.keys(this.sourceBuffer); + }; + + _proto.addBufferListener = function addBufferListener(type, event, fn) { + var buffer = this.sourceBuffer[type]; + + if (!buffer) { + return; + } + + var listener = fn.bind(this, type); + this.listeners[type].push({ + event: event, + listener: listener, + }); + buffer.addEventListener(event, listener); + }; + + _proto.removeBufferListeners = function removeBufferListeners(type) { + var buffer = this.sourceBuffer[type]; + + if (!buffer) { + return; + } + + this.listeners[type].forEach(function (l) { + buffer.removeEventListener(l.event, l.listener); + }); + }; + + return BufferController; + })(); + + /***/ + }, + + /***/ "./src/controller/buffer-operation-queue.ts": + /*!**************************************************!*\ !*** ./src/controller/buffer-operation-queue.ts ***! \**************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return BufferOperationQueue; + }); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BufferOperationQueue; }); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + var BufferOperationQueue = /*#__PURE__*/ (function () { + function BufferOperationQueue(sourceBufferReference) { + this.buffers = void 0; + this.queues = { + video: [], + audio: [], + audiovideo: [], + }; + this.buffers = sourceBufferReference; + } + var _proto = BufferOperationQueue.prototype; -var BufferOperationQueue = /*#__PURE__*/function () { - function BufferOperationQueue(sourceBufferReference) { - this.buffers = void 0; - this.queues = { - video: [], - audio: [], - audiovideo: [] - }; - this.buffers = sourceBufferReference; - } + _proto.append = function append(operation, type) { + var queue = this.queues[type]; + queue.push(operation); - var _proto = BufferOperationQueue.prototype; + if (queue.length === 1 && this.buffers[type]) { + this.executeNext(type); + } + }; - _proto.append = function append(operation, type) { - var queue = this.queues[type]; - queue.push(operation); + _proto.insertAbort = function insertAbort(operation, type) { + var queue = this.queues[type]; + queue.unshift(operation); + this.executeNext(type); + }; - if (queue.length === 1 && this.buffers[type]) { - this.executeNext(type); - } - }; + _proto.appendBlocker = function appendBlocker(type) { + var execute; + var promise = new Promise(function (resolve) { + execute = resolve; + }); + var operation = { + execute: execute, + onStart: function onStart() {}, + onComplete: function onComplete() {}, + onError: function onError() {}, + }; + this.append(operation, type); + return promise; + }; - _proto.insertAbort = function insertAbort(operation, type) { - var queue = this.queues[type]; - queue.unshift(operation); - this.executeNext(type); - }; + _proto.executeNext = function executeNext(type) { + var buffers = this.buffers, + queues = this.queues; + var sb = buffers[type]; + var queue = queues[type]; - _proto.appendBlocker = function appendBlocker(type) { - var execute; - var promise = new Promise(function (resolve) { - execute = resolve; - }); - var operation = { - execute: execute, - onStart: function onStart() {}, - onComplete: function onComplete() {}, - onError: function onError() {} - }; - this.append(operation, type); - return promise; - }; + if (queue.length) { + var operation = queue[0]; - _proto.executeNext = function executeNext(type) { - var buffers = this.buffers, - queues = this.queues; - var sb = buffers[type]; - var queue = queues[type]; + try { + // Operations are expected to result in an 'updateend' event being fired. If not, the queue will lock. Operations + // which do not end with this event must call _onSBUpdateEnd manually + operation.execute(); + } catch (e) { + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].warn("[buffer-operation-queue]: Unhandled exception executing the current operation"); + operation.onError(e); // Only shift the current operation off, otherwise the updateend handler will do this for us - if (queue.length) { - var operation = queue[0]; + if (!sb || !sb.updating) { + queue.shift(); + this.executeNext(type); + } + } + } + }; - try { - // Operations are expected to result in an 'updateend' event being fired. If not, the queue will lock. Operations - // which do not end with this event must call _onSBUpdateEnd manually - operation.execute(); - } catch (e) { - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].warn('[buffer-operation-queue]: Unhandled exception executing the current operation'); - operation.onError(e); // Only shift the current operation off, otherwise the updateend handler will do this for us + _proto.shiftAndExecuteNext = function shiftAndExecuteNext(type) { + this.queues[type].shift(); + this.executeNext(type); + }; - if (!sb || !sb.updating) { - queue.shift(); - this.executeNext(type); - } - } - } - }; + _proto.current = function current(type) { + return this.queues[type][0]; + }; - _proto.shiftAndExecuteNext = function shiftAndExecuteNext(type) { - this.queues[type].shift(); - this.executeNext(type); - }; + return BufferOperationQueue; + })(); - _proto.current = function current(type) { - return this.queues[type][0]; - }; + /***/ + }, - return BufferOperationQueue; -}(); - - - -/***/ }), - -/***/ "./src/controller/cap-level-controller.ts": -/*!************************************************!*\ + /***/ "./src/controller/cap-level-controller.ts": + /*!************************************************!*\ !*** ./src/controller/cap-level-controller.ts ***! \************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + /* + * cap stream level to media size dimension controller + */ -/* - * cap stream level to media size dimension controller - */ + var CapLevelController = /*#__PURE__*/ (function () { + function CapLevelController(CiderHls) { + this.autoLevelCapping = void 0; + this.firstLevel = void 0; + this.media = void 0; + this.restrictedLevels = void 0; + this.timer = void 0; + this.CiderHls = void 0; + this.streamController = void 0; + this.clientRect = void 0; + this.CiderHls = CiderHls; + this.autoLevelCapping = Number.POSITIVE_INFINITY; + this.firstLevel = -1; + this.media = null; + this.restrictedLevels = []; + this.timer = undefined; + this.clientRect = null; + this.registerListeners(); + } + var _proto = CapLevelController.prototype; -var CapLevelController = /*#__PURE__*/function () { - function CapLevelController(CiderHls) { - this.autoLevelCapping = void 0; - this.firstLevel = void 0; - this.media = void 0; - this.restrictedLevels = void 0; - this.timer = void 0; - this.CiderHls = void 0; - this.streamController = void 0; - this.clientRect = void 0; - this.CiderHls = CiderHls; - this.autoLevelCapping = Number.POSITIVE_INFINITY; - this.firstLevel = -1; - this.media = null; - this.restrictedLevels = []; - this.timer = undefined; - this.clientRect = null; - this.registerListeners(); - } + _proto.setStreamController = function setStreamController(streamController) { + this.streamController = streamController; + }; - var _proto = CapLevelController.prototype; + _proto.destroy = function destroy() { + this.unregisterListener(); - _proto.setStreamController = function setStreamController(streamController) { - this.streamController = streamController; - }; + if (this.CiderHls.config.capLevelToPlayerSize) { + this.stopCapping(); + } - _proto.destroy = function destroy() { - this.unregisterListener(); + this.media = null; + this.clientRect = null; // @ts-ignore - if (this.CiderHls.config.capLevelToPlayerSize) { - this.stopCapping(); - } + this.CiderHls = this.streamController = null; + }; - this.media = null; - this.clientRect = null; // @ts-ignore + _proto.registerListeners = function registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + }; - this.CiderHls = this.streamController = null; - }; + _proto.unregisterListener = function unregisterListener() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + }; - _proto.registerListeners = function registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - }; + _proto.onFpsDropLevelCapping = function onFpsDropLevelCapping(event, data) { + // Don't add a restricted level more than once + if (CapLevelController.isLevelAllowed(data.droppedLevel, this.restrictedLevels)) { + this.restrictedLevels.push(data.droppedLevel); + } + }; - _proto.unregisterListener = function unregisterListener() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CODECS, this.onBufferCodecs, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - }; + _proto.onMediaAttaching = function onMediaAttaching(event, data) { + this.media = data.media instanceof HTMLVideoElement ? data.media : null; + }; - _proto.onFpsDropLevelCapping = function onFpsDropLevelCapping(event, data) { - // Don't add a restricted level more than once - if (CapLevelController.isLevelAllowed(data.droppedLevel, this.restrictedLevels)) { - this.restrictedLevels.push(data.droppedLevel); - } - }; + _proto.onManifestParsed = function onManifestParsed(event, data) { + var CiderHls = this.CiderHls; + this.restrictedLevels = []; + this.firstLevel = data.firstLevel; - _proto.onMediaAttaching = function onMediaAttaching(event, data) { - this.media = data.media instanceof HTMLVideoElement ? data.media : null; - }; + if (CiderHls.config.capLevelToPlayerSize && data.video) { + // Start capping immediately if the manifest has signaled video codecs + this.startCapping(); + } + }; // Only activate capping when playing a video stream; otherwise, multi-bitrate audio-only streams will be restricted + // to the first level - _proto.onManifestParsed = function onManifestParsed(event, data) { - var CiderHls = this.CiderHls; - this.restrictedLevels = []; - this.firstLevel = data.firstLevel; + _proto.onBufferCodecs = function onBufferCodecs(event, data) { + var CiderHls = this.CiderHls; - if (CiderHls.config.capLevelToPlayerSize && data.video) { - // Start capping immediately if the manifest has signaled video codecs - this.startCapping(); - } - } // Only activate capping when playing a video stream; otherwise, multi-bitrate audio-only streams will be restricted - // to the first level - ; + if (CiderHls.config.capLevelToPlayerSize && data.video) { + // If the manifest did not signal a video codec capping has been deferred until we're certain video is present + this.startCapping(); + } + }; - _proto.onBufferCodecs = function onBufferCodecs(event, data) { - var CiderHls = this.CiderHls; + _proto.onMediaDetaching = function onMediaDetaching() { + this.stopCapping(); + }; - if (CiderHls.config.capLevelToPlayerSize && data.video) { - // If the manifest did not signal a video codec capping has been deferred until we're certain video is present - this.startCapping(); - } - }; + _proto.detectPlayerSize = function detectPlayerSize() { + if (this.media && this.mediaHeight > 0 && this.mediaWidth > 0) { + var levels = this.CiderHls.levels; - _proto.onMediaDetaching = function onMediaDetaching() { - this.stopCapping(); - }; + if (levels.length) { + var CiderHls = this.CiderHls; + CiderHls.autoLevelCapping = this.getMaxLevel(levels.length - 1); - _proto.detectPlayerSize = function detectPlayerSize() { - if (this.media && this.mediaHeight > 0 && this.mediaWidth > 0) { - var levels = this.CiderHls.levels; + if (CiderHls.autoLevelCapping > this.autoLevelCapping && this.streamController) { + // if auto level capping has a higher value for the previous one, flush the buffer using nextLevelSwitch + // usually happen when the user go to the fullscreen mode. + this.streamController.nextLevelSwitch(); + } - if (levels.length) { - var CiderHls = this.CiderHls; - CiderHls.autoLevelCapping = this.getMaxLevel(levels.length - 1); + this.autoLevelCapping = CiderHls.autoLevelCapping; + } + } + }; + /* + * returns level should be the one with the dimensions equal or greater than the media (player) dimensions (so the video will be downscaled) + */ - if (CiderHls.autoLevelCapping > this.autoLevelCapping && this.streamController) { - // if auto level capping has a higher value for the previous one, flush the buffer using nextLevelSwitch - // usually happen when the user go to the fullscreen mode. - this.streamController.nextLevelSwitch(); - } + _proto.getMaxLevel = function getMaxLevel(capLevelIndex) { + var _this = this; - this.autoLevelCapping = CiderHls.autoLevelCapping; - } - } - } - /* - * returns level should be the one with the dimensions equal or greater than the media (player) dimensions (so the video will be downscaled) - */ - ; + var levels = this.CiderHls.levels; - _proto.getMaxLevel = function getMaxLevel(capLevelIndex) { - var _this = this; + if (!levels.length) { + return -1; + } - var levels = this.CiderHls.levels; + var validLevels = levels.filter(function (level, index) { + return CapLevelController.isLevelAllowed(index, _this.restrictedLevels) && index <= capLevelIndex; + }); + this.clientRect = null; + return CapLevelController.getMaxLevelByMediaSize(validLevels, this.mediaWidth, this.mediaHeight); + }; - if (!levels.length) { - return -1; - } + _proto.startCapping = function startCapping() { + if (this.timer) { + // Don't reset capping if started twice; this can happen if the manifest signals a video codec + return; + } - var validLevels = levels.filter(function (level, index) { - return CapLevelController.isLevelAllowed(index, _this.restrictedLevels) && index <= capLevelIndex; - }); - this.clientRect = null; - return CapLevelController.getMaxLevelByMediaSize(validLevels, this.mediaWidth, this.mediaHeight); - }; + this.autoLevelCapping = Number.POSITIVE_INFINITY; + this.CiderHls.firstLevel = this.getMaxLevel(this.firstLevel); + self.clearInterval(this.timer); + this.timer = self.setInterval(this.detectPlayerSize.bind(this), 1000); + this.detectPlayerSize(); + }; - _proto.startCapping = function startCapping() { - if (this.timer) { - // Don't reset capping if started twice; this can happen if the manifest signals a video codec - return; - } + _proto.stopCapping = function stopCapping() { + this.restrictedLevels = []; + this.firstLevel = -1; + this.autoLevelCapping = Number.POSITIVE_INFINITY; - this.autoLevelCapping = Number.POSITIVE_INFINITY; - this.CiderHls.firstLevel = this.getMaxLevel(this.firstLevel); - self.clearInterval(this.timer); - this.timer = self.setInterval(this.detectPlayerSize.bind(this), 1000); - this.detectPlayerSize(); - }; + if (this.timer) { + self.clearInterval(this.timer); + this.timer = undefined; + } + }; - _proto.stopCapping = function stopCapping() { - this.restrictedLevels = []; - this.firstLevel = -1; - this.autoLevelCapping = Number.POSITIVE_INFINITY; + _proto.getDimensions = function getDimensions() { + if (this.clientRect) { + return this.clientRect; + } - if (this.timer) { - self.clearInterval(this.timer); - this.timer = undefined; - } - }; + var media = this.media; + var boundsRect = { + width: 0, + height: 0, + }; - _proto.getDimensions = function getDimensions() { - if (this.clientRect) { - return this.clientRect; - } + if (media) { + var clientRect = media.getBoundingClientRect(); + boundsRect.width = clientRect.width; + boundsRect.height = clientRect.height; - var media = this.media; - var boundsRect = { - width: 0, - height: 0 - }; + if (!boundsRect.width && !boundsRect.height) { + // When the media element has no width or height (equivalent to not being in the DOM), + // then use its width and height attributes (media.width, media.height) + boundsRect.width = clientRect.right - clientRect.left || media.width || 0; + boundsRect.height = clientRect.bottom - clientRect.top || media.height || 0; + } + } - if (media) { - var clientRect = media.getBoundingClientRect(); - boundsRect.width = clientRect.width; - boundsRect.height = clientRect.height; + this.clientRect = boundsRect; + return boundsRect; + }; - if (!boundsRect.width && !boundsRect.height) { - // When the media element has no width or height (equivalent to not being in the DOM), - // then use its width and height attributes (media.width, media.height) - boundsRect.width = clientRect.right - clientRect.left || media.width || 0; - boundsRect.height = clientRect.bottom - clientRect.top || media.height || 0; - } - } + CapLevelController.isLevelAllowed = function isLevelAllowed(level, restrictedLevels) { + if (restrictedLevels === void 0) { + restrictedLevels = []; + } - this.clientRect = boundsRect; - return boundsRect; - }; + return restrictedLevels.indexOf(level) === -1; + }; - CapLevelController.isLevelAllowed = function isLevelAllowed(level, restrictedLevels) { - if (restrictedLevels === void 0) { - restrictedLevels = []; - } + CapLevelController.getMaxLevelByMediaSize = function getMaxLevelByMediaSize(levels, width, height) { + if (!levels || !levels.length) { + return -1; + } // Levels can have the same dimensions but differing bandwidths - since levels are ordered, we can look to the next + // to determine whether we've chosen the greatest bandwidth for the media's dimensions - return restrictedLevels.indexOf(level) === -1; - }; + var atGreatestBandiwdth = function atGreatestBandiwdth(curLevel, nextLevel) { + if (!nextLevel) { + return true; + } - CapLevelController.getMaxLevelByMediaSize = function getMaxLevelByMediaSize(levels, width, height) { - if (!levels || !levels.length) { - return -1; - } // Levels can have the same dimensions but differing bandwidths - since levels are ordered, we can look to the next - // to determine whether we've chosen the greatest bandwidth for the media's dimensions + return curLevel.width !== nextLevel.width || curLevel.height !== nextLevel.height; + }; // If we run through the loop without breaking, the media's dimensions are greater than every level, so default to + // the max level + var maxLevelIndex = levels.length - 1; - var atGreatestBandiwdth = function atGreatestBandiwdth(curLevel, nextLevel) { - if (!nextLevel) { - return true; - } + for (var i = 0; i < levels.length; i += 1) { + var level = levels[i]; - return curLevel.width !== nextLevel.width || curLevel.height !== nextLevel.height; - }; // If we run through the loop without breaking, the media's dimensions are greater than every level, so default to - // the max level + if ((level.width >= width || level.height >= height) && atGreatestBandiwdth(level, levels[i + 1])) { + maxLevelIndex = i; + break; + } + } + return maxLevelIndex; + }; - var maxLevelIndex = levels.length - 1; + _createClass( + CapLevelController, + [ + { + key: "mediaWidth", + get: function get() { + return this.getDimensions().width * CapLevelController.contentScaleFactor; + }, + }, + { + key: "mediaHeight", + get: function get() { + return this.getDimensions().height * CapLevelController.contentScaleFactor; + }, + }, + ], + [ + { + key: "contentScaleFactor", + get: function get() { + var pixelRatio = 1; - for (var i = 0; i < levels.length; i += 1) { - var level = levels[i]; + try { + pixelRatio = self.devicePixelRatio; + } catch (e) { + /* no-op */ + } - if ((level.width >= width || level.height >= height) && atGreatestBandiwdth(level, levels[i + 1])) { - maxLevelIndex = i; - break; - } - } + return pixelRatio; + }, + }, + ] + ); - return maxLevelIndex; - }; + return CapLevelController; + })(); - _createClass(CapLevelController, [{ - key: "mediaWidth", - get: function get() { - return this.getDimensions().width * CapLevelController.contentScaleFactor; - } - }, { - key: "mediaHeight", - get: function get() { - return this.getDimensions().height * CapLevelController.contentScaleFactor; - } - }], [{ - key: "contentScaleFactor", - get: function get() { - var pixelRatio = 1; + /* harmony default export */ __webpack_exports__["default"] = CapLevelController; - try { - pixelRatio = self.devicePixelRatio; - } catch (e) { - /* no-op */ - } + /***/ + }, - return pixelRatio; - } - }]); - - return CapLevelController; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (CapLevelController); - -/***/ }), - -/***/ "./src/controller/cmcd-controller.ts": -/*!*******************************************!*\ + /***/ "./src/controller/cmcd-controller.ts": + /*!*******************************************!*\ !*** ./src/controller/cmcd-controller.ts ***! \*******************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CMCDController; }); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _types_cmcd__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/cmcd */ "./src/types/cmcd.ts"); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - - - - - -/** - * Controller to deal with Common Media Client Data (CMCD) - * @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf - */ - -var CMCDController = /*#__PURE__*/function () { - // eslint-disable-line no-restricted-globals - // eslint-disable-line no-restricted-globals - function CMCDController(CiderHls) { - var _this = this; - - this.CiderHls = void 0; - this.config = void 0; - this.media = void 0; - this.sid = void 0; - this.cid = void 0; - this.useHeaders = false; - this.initialized = false; - this.starved = false; - this.buffering = true; - this.audioBuffer = void 0; - this.videoBuffer = void 0; - - this.onWaiting = function () { - if (_this.initialized) { - _this.starved = true; - } - - _this.buffering = true; - }; - - this.onPlaying = function () { - if (!_this.initialized) { - _this.initialized = true; - } - - _this.buffering = false; - }; - - this.applyPlaylistData = function (context) { - try { - _this.apply(context, { - ot: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MANIFEST, - su: !_this.initialized - }); - } catch (error) { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('Could not generate manifest CMCD data.', error); - } - }; - - this.applyFragmentData = function (context) { - try { - var fragment = context.frag; - var level = _this.CiderHls.levels[fragment.level]; - - var ot = _this.getObjectType(fragment); - - var data = { - d: fragment.duration * 1000, - ot: ot - }; - - if (ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO || ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO || ot == _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED) { - data.br = level.bitrate / 1000; - data.tb = _this.getTopBandwidth(ot); - data.bl = _this.getBufferLength(ot); - } - - _this.apply(context, data); - } catch (error) { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('Could not generate segment CMCD data.', error); - } - }; - - this.CiderHls = CiderHls; - var config = this.config = CiderHls.config; - var cmcd = config.cmcd; - - if (cmcd != null) { - config.pLoader = this.createPlaylistLoader(); - config.fLoader = this.createFragmentLoader(); - this.sid = cmcd.sessionId || CMCDController.uuid(); - this.cid = cmcd.contentId; - this.useHeaders = cmcd.useHeaders === true; - this.registerListeners(); - } - } - - var _proto = CMCDController.prototype; - - _proto.registerListeners = function registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CREATED, this.onBufferCreated, this); - }; - - _proto.unregisterListeners = function unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CREATED, this.onBufferCreated, this); - this.onMediaDetached(); - }; - - _proto.destroy = function destroy() { - this.unregisterListeners(); // @ts-ignore - - this.CiderHls = this.config = this.audioBuffer = this.videoBuffer = null; - }; - - _proto.onMediaAttached = function onMediaAttached(event, data) { - this.media = data.media; - this.media.addEventListener('waiting', this.onWaiting); - this.media.addEventListener('playing', this.onPlaying); - }; - - _proto.onMediaDetached = function onMediaDetached() { - if (!this.media) { - return; - } - - this.media.removeEventListener('waiting', this.onWaiting); - this.media.removeEventListener('playing', this.onPlaying); // @ts-ignore - - this.media = null; - }; - - _proto.onBufferCreated = function onBufferCreated(event, data) { - var _data$tracks$audio, _data$tracks$video; - - this.audioBuffer = (_data$tracks$audio = data.tracks.audio) === null || _data$tracks$audio === void 0 ? void 0 : _data$tracks$audio.buffer; - this.videoBuffer = (_data$tracks$video = data.tracks.video) === null || _data$tracks$video === void 0 ? void 0 : _data$tracks$video.buffer; - }; - - /** - * Create baseline CMCD data - */ - _proto.createData = function createData() { - var _this$media; - - return { - v: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDVersion"], - sf: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDStreamingFormat"].CiderHls, - sid: this.sid, - cid: this.cid, - pr: (_this$media = this.media) === null || _this$media === void 0 ? void 0 : _this$media.playbackRate, - mtp: this.CiderHls.bandwidthEstimate / 1000 - }; - } - /** - * Apply CMCD data to a request. - */ - ; - - _proto.apply = function apply(context, data) { - if (data === void 0) { - data = {}; - } - - // apply baseline data - _extends(data, this.createData()); - - var isVideo = data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].INIT || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED; - - if (this.starved && isVideo) { - data.bs = true; - data.su = true; - this.starved = false; - } - - if (data.su == null) { - data.su = this.buffering; - } // TODO: Implement rtp, nrr, nor, dl - - - if (this.useHeaders) { - var headers = CMCDController.toHeaders(data); - - if (!Object.keys(headers).length) { - return; - } - - if (!context.headers) { - context.headers = {}; - } - - _extends(context.headers, headers); - } else { - var query = CMCDController.toQuery(data); - - if (!query) { - return; - } - - context.url = CMCDController.appendQueryToUri(context.url, query); - } - } - /** - * Apply CMCD data to a manifest request. - */ - ; - - /** - * The CMCD object type. - */ - _proto.getObjectType = function getObjectType(fragment) { - var type = fragment.type; - - if (type === 'subtitle') { - return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].TIMED_TEXT; - } - - if (fragment.sn === 'initSegment') { - return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].INIT; - } - - if (type === 'audio') { - return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO; - } - - if (type === 'main') { - if (!this.CiderHls.audioTracks.length) { - return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED; - } - - return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO; - } - - return undefined; - } - /** - * Get the highest bitrate. - */ - ; - - _proto.getTopBandwidth = function getTopBandwidth(type) { - var bitrate = 0; - var levels = type === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO ? this.CiderHls.audioTracks : this.CiderHls.levels; - - for (var _iterator = _createForOfIteratorHelperLoose(levels), _step; !(_step = _iterator()).done;) { - var level = _step.value; - - if (level.bitrate > bitrate) { - bitrate = level.bitrate; - } - } - - return bitrate > 0 ? bitrate : NaN; - } - /** - * Get the buffer length for a media type in milliseconds - */ - ; - - _proto.getBufferLength = function getBufferLength(type) { - var media = this.CiderHls.media; - var buffer = type === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO ? this.audioBuffer : this.videoBuffer; - - if (!buffer || !media) { - return NaN; - } - - var info = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__["BufferHelper"].bufferInfo(buffer, media.currentTime, this.config.maxBufferHole); - return info.len * 1000; - } - /** - * Create a playlist loader - */ - ; - - _proto.createPlaylistLoader = function createPlaylistLoader() { - var pLoader = this.config.pLoader; - var apply = this.applyPlaylistData; - var Ctor = pLoader || this.config.loader; - return /*#__PURE__*/function () { - function CmcdPlaylistLoader(config) { - this.loader = void 0; - this.loader = new Ctor(config); - } - - var _proto2 = CmcdPlaylistLoader.prototype; - - _proto2.destroy = function destroy() { - this.loader.destroy(); - }; - - _proto2.abort = function abort() { - this.loader.abort(); - }; - - _proto2.load = function load(context, config, callbacks) { - apply(context); - this.loader.load(context, config, callbacks); - }; - - _createClass(CmcdPlaylistLoader, [{ - key: "stats", - get: function get() { - return this.loader.stats; - } - }, { - key: "context", - get: function get() { - return this.loader.context; - } - }]); - - return CmcdPlaylistLoader; - }(); - } - /** - * Create a playlist loader - */ - ; - - _proto.createFragmentLoader = function createFragmentLoader() { - var fLoader = this.config.fLoader; - var apply = this.applyFragmentData; - var Ctor = fLoader || this.config.loader; - return /*#__PURE__*/function () { - function CmcdFragmentLoader(config) { - this.loader = void 0; - this.loader = new Ctor(config); - } - - var _proto3 = CmcdFragmentLoader.prototype; - - _proto3.destroy = function destroy() { - this.loader.destroy(); - }; - - _proto3.abort = function abort() { - this.loader.abort(); - }; - - _proto3.load = function load(context, config, callbacks) { - apply(context); - this.loader.load(context, config, callbacks); - }; - - _createClass(CmcdFragmentLoader, [{ - key: "stats", - get: function get() { - return this.loader.stats; - } - }, { - key: "context", - get: function get() { - return this.loader.context; - } - }]); - - return CmcdFragmentLoader; - }(); - } - /** - * Generate a random v4 UUI - * - * @returns {string} - */ - ; - - CMCDController.uuid = function uuid() { - var url = URL.createObjectURL(new Blob()); - var uuid = url.toString(); - URL.revokeObjectURL(url); - return uuid.substr(uuid.lastIndexOf('/') + 1); - } - /** - * Serialize a CMCD data object according to the rules defined in the - * section 3.2 of - * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). - */ - ; - - CMCDController.serialize = function serialize(data) { - var results = []; - - var isValid = function isValid(value) { - return !Number.isNaN(value) && value != null && value !== '' && value !== false; - }; - - var toRounded = function toRounded(value) { - return Math.round(value); - }; - - var toHundred = function toHundred(value) { - return toRounded(value / 100) * 100; - }; - - var toUrlSafe = function toUrlSafe(value) { - return encodeURIComponent(value); - }; - - var formatters = { - br: toRounded, - d: toRounded, - bl: toHundred, - dl: toHundred, - mtp: toHundred, - nor: toUrlSafe, - rtp: toHundred, - tb: toRounded - }; - var keys = Object.keys(data || {}).sort(); - - for (var _iterator2 = _createForOfIteratorHelperLoose(keys), _step2; !(_step2 = _iterator2()).done;) { - var key = _step2.value; - var value = data[key]; // ignore invalid values - - if (!isValid(value)) { - continue; - } // Version should only be reported if not equal to 1. - - - if (key === 'v' && value === 1) { - continue; - } // Playback rate should only be sent if not equal to 1. - - - if (key == 'pr' && value === 1) { - continue; - } // Certain values require special formatting - - - var formatter = formatters[key]; - - if (formatter) { - value = formatter(value); - } // Serialize the key/value pair - - - var type = typeof value; - var result = void 0; - - if (key === 'ot' || key === 'sf' || key === 'st') { - result = key + "=" + value; - } else if (type === 'boolean') { - result = key; - } else if (type === 'number') { - result = key + "=" + value; - } else { - result = key + "=" + JSON.stringify(value); - } - - results.push(result); - } - - return results.join(','); - } - /** - * Convert a CMCD data object to request headers according to the rules - * defined in the section 2.1 and 3.2 of - * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). - */ - ; - - CMCDController.toHeaders = function toHeaders(data) { - var keys = Object.keys(data); - var headers = {}; - var headerNames = ['Object', 'Request', 'Session', 'Status']; - var headerGroups = [{}, {}, {}, {}]; - var headerMap = { - br: 0, - d: 0, - ot: 0, - tb: 0, - bl: 1, - dl: 1, - mtp: 1, - nor: 1, - nrr: 1, - su: 1, - cid: 2, - pr: 2, - sf: 2, - sid: 2, - st: 2, - v: 2, - bs: 3, - rtp: 3 - }; - - for (var _i = 0, _keys = keys; _i < _keys.length; _i++) { - var key = _keys[_i]; - // Unmapped fields are mapped to the Request header - var index = headerMap[key] != null ? headerMap[key] : 1; - headerGroups[index][key] = data[key]; - } - - for (var i = 0; i < headerGroups.length; i++) { - var value = CMCDController.serialize(headerGroups[i]); - - if (value) { - headers["CMCD-" + headerNames[i]] = value; - } - } - - return headers; - } - /** - * Convert a CMCD data object to query args according to the rules - * defined in the section 2.2 and 3.2 of - * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). - */ - ; - - CMCDController.toQuery = function toQuery(data) { - return "CMCD=" + encodeURIComponent(CMCDController.serialize(data)); - } - /** - * Append query args to a uri. - */ - ; - - CMCDController.appendQueryToUri = function appendQueryToUri(uri, query) { - if (!query) { - return uri; - } - - var separator = uri.includes('?') ? '&' : '?'; - return "" + uri + separator + query; - }; - - return CMCDController; -}(); - - - -/***/ }), - -/***/ "./src/controller/eme-controller.ts": -/*!******************************************!*\ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return CMCDController; + }); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _types_cmcd__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/cmcd */ "./src/types/cmcd.ts"); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _createForOfIteratorHelperLoose(o, allowArrayLike) { + var it = (typeof Symbol !== "undefined" && o[Symbol.iterator]) || o["@@iterator"]; + if (it) return (it = it.call(o)).next.bind(it); + if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || (allowArrayLike && o && typeof o.length === "number")) { + if (it) o = it; + var i = 0; + return function () { + if (i >= o.length) return { done: true }; + return { done: false, value: o[i++] }; + }; + } + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) { + arr2[i] = arr[i]; + } + return arr2; + } + + function _extends() { + _extends = + Object.assign || + function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); + } + + /** + * Controller to deal with Common Media Client Data (CMCD) + * @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf + */ + + var CMCDController = /*#__PURE__*/ (function () { + // eslint-disable-line no-restricted-globals + // eslint-disable-line no-restricted-globals + function CMCDController(CiderHls) { + var _this = this; + + this.CiderHls = void 0; + this.config = void 0; + this.media = void 0; + this.sid = void 0; + this.cid = void 0; + this.useHeaders = false; + this.initialized = false; + this.starved = false; + this.buffering = true; + this.audioBuffer = void 0; + this.videoBuffer = void 0; + + this.onWaiting = function () { + if (_this.initialized) { + _this.starved = true; + } + + _this.buffering = true; + }; + + this.onPlaying = function () { + if (!_this.initialized) { + _this.initialized = true; + } + + _this.buffering = false; + }; + + this.applyPlaylistData = function (context) { + try { + _this.apply(context, { + ot: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MANIFEST, + su: !_this.initialized, + }); + } catch (error) { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Could not generate manifest CMCD data.", error); + } + }; + + this.applyFragmentData = function (context) { + try { + var fragment = context.frag; + var level = _this.CiderHls.levels[fragment.level]; + + var ot = _this.getObjectType(fragment); + + var data = { + d: fragment.duration * 1000, + ot: ot, + }; + + if (ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO || ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO || ot == _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED) { + data.br = level.bitrate / 1000; + data.tb = _this.getTopBandwidth(ot); + data.bl = _this.getBufferLength(ot); + } + + _this.apply(context, data); + } catch (error) { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Could not generate segment CMCD data.", error); + } + }; + + this.CiderHls = CiderHls; + var config = (this.config = CiderHls.config); + var cmcd = config.cmcd; + + if (cmcd != null) { + config.pLoader = this.createPlaylistLoader(); + config.fLoader = this.createFragmentLoader(); + this.sid = cmcd.sessionId || CMCDController.uuid(); + this.cid = cmcd.contentId; + this.useHeaders = cmcd.useHeaders === true; + this.registerListeners(); + } + } + + var _proto = CMCDController.prototype; + + _proto.registerListeners = function registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CREATED, this.onBufferCreated, this); + }; + + _proto.unregisterListeners = function unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_CREATED, this.onBufferCreated, this); + this.onMediaDetached(); + }; + + _proto.destroy = function destroy() { + this.unregisterListeners(); // @ts-ignore + + this.CiderHls = this.config = this.audioBuffer = this.videoBuffer = null; + }; + + _proto.onMediaAttached = function onMediaAttached(event, data) { + this.media = data.media; + this.media.addEventListener("waiting", this.onWaiting); + this.media.addEventListener("playing", this.onPlaying); + }; + + _proto.onMediaDetached = function onMediaDetached() { + if (!this.media) { + return; + } + + this.media.removeEventListener("waiting", this.onWaiting); + this.media.removeEventListener("playing", this.onPlaying); // @ts-ignore + + this.media = null; + }; + + _proto.onBufferCreated = function onBufferCreated(event, data) { + var _data$tracks$audio, _data$tracks$video; + + this.audioBuffer = (_data$tracks$audio = data.tracks.audio) === null || _data$tracks$audio === void 0 ? void 0 : _data$tracks$audio.buffer; + this.videoBuffer = (_data$tracks$video = data.tracks.video) === null || _data$tracks$video === void 0 ? void 0 : _data$tracks$video.buffer; + }; + + /** + * Create baseline CMCD data + */ + _proto.createData = function createData() { + var _this$media; + + return { + v: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDVersion"], + sf: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDStreamingFormat"].CiderHls, + sid: this.sid, + cid: this.cid, + pr: (_this$media = this.media) === null || _this$media === void 0 ? void 0 : _this$media.playbackRate, + mtp: this.CiderHls.bandwidthEstimate / 1000, + }; + }; + /** + * Apply CMCD data to a request. + */ + + _proto.apply = function apply(context, data) { + if (data === void 0) { + data = {}; + } + + // apply baseline data + _extends(data, this.createData()); + + var isVideo = data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].INIT || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED; + + if (this.starved && isVideo) { + data.bs = true; + data.su = true; + this.starved = false; + } + + if (data.su == null) { + data.su = this.buffering; + } // TODO: Implement rtp, nrr, nor, dl + + if (this.useHeaders) { + var headers = CMCDController.toHeaders(data); + + if (!Object.keys(headers).length) { + return; + } + + if (!context.headers) { + context.headers = {}; + } + + _extends(context.headers, headers); + } else { + var query = CMCDController.toQuery(data); + + if (!query) { + return; + } + + context.url = CMCDController.appendQueryToUri(context.url, query); + } + }; + /** + * Apply CMCD data to a manifest request. + */ + + /** + * The CMCD object type. + */ + _proto.getObjectType = function getObjectType(fragment) { + var type = fragment.type; + + if (type === "subtitle") { + return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].TIMED_TEXT; + } + + if (fragment.sn === "initSegment") { + return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].INIT; + } + + if (type === "audio") { + return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO; + } + + if (type === "main") { + if (!this.CiderHls.audioTracks.length) { + return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED; + } + + return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO; + } + + return undefined; + }; + /** + * Get the highest bitrate. + */ + + _proto.getTopBandwidth = function getTopBandwidth(type) { + var bitrate = 0; + var levels = type === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO ? this.CiderHls.audioTracks : this.CiderHls.levels; + + for (var _iterator = _createForOfIteratorHelperLoose(levels), _step; !(_step = _iterator()).done; ) { + var level = _step.value; + + if (level.bitrate > bitrate) { + bitrate = level.bitrate; + } + } + + return bitrate > 0 ? bitrate : NaN; + }; + /** + * Get the buffer length for a media type in milliseconds + */ + + _proto.getBufferLength = function getBufferLength(type) { + var media = this.CiderHls.media; + var buffer = type === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO ? this.audioBuffer : this.videoBuffer; + + if (!buffer || !media) { + return NaN; + } + + var info = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__["BufferHelper"].bufferInfo(buffer, media.currentTime, this.config.maxBufferHole); + return info.len * 1000; + }; + /** + * Create a playlist loader + */ + + _proto.createPlaylistLoader = function createPlaylistLoader() { + var pLoader = this.config.pLoader; + var apply = this.applyPlaylistData; + var Ctor = pLoader || this.config.loader; + return /*#__PURE__*/ (function () { + function CmcdPlaylistLoader(config) { + this.loader = void 0; + this.loader = new Ctor(config); + } + + var _proto2 = CmcdPlaylistLoader.prototype; + + _proto2.destroy = function destroy() { + this.loader.destroy(); + }; + + _proto2.abort = function abort() { + this.loader.abort(); + }; + + _proto2.load = function load(context, config, callbacks) { + apply(context); + this.loader.load(context, config, callbacks); + }; + + _createClass(CmcdPlaylistLoader, [ + { + key: "stats", + get: function get() { + return this.loader.stats; + }, + }, + { + key: "context", + get: function get() { + return this.loader.context; + }, + }, + ]); + + return CmcdPlaylistLoader; + })(); + }; + /** + * Create a playlist loader + */ + + _proto.createFragmentLoader = function createFragmentLoader() { + var fLoader = this.config.fLoader; + var apply = this.applyFragmentData; + var Ctor = fLoader || this.config.loader; + return /*#__PURE__*/ (function () { + function CmcdFragmentLoader(config) { + this.loader = void 0; + this.loader = new Ctor(config); + } + + var _proto3 = CmcdFragmentLoader.prototype; + + _proto3.destroy = function destroy() { + this.loader.destroy(); + }; + + _proto3.abort = function abort() { + this.loader.abort(); + }; + + _proto3.load = function load(context, config, callbacks) { + apply(context); + this.loader.load(context, config, callbacks); + }; + + _createClass(CmcdFragmentLoader, [ + { + key: "stats", + get: function get() { + return this.loader.stats; + }, + }, + { + key: "context", + get: function get() { + return this.loader.context; + }, + }, + ]); + + return CmcdFragmentLoader; + })(); + }; + /** + * Generate a random v4 UUI + * + * @returns {string} + */ + + CMCDController.uuid = function uuid() { + var url = URL.createObjectURL(new Blob()); + var uuid = url.toString(); + URL.revokeObjectURL(url); + return uuid.substr(uuid.lastIndexOf("/") + 1); + }; + /** + * Serialize a CMCD data object according to the rules defined in the + * section 3.2 of + * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). + */ + + CMCDController.serialize = function serialize(data) { + var results = []; + + var isValid = function isValid(value) { + return !Number.isNaN(value) && value != null && value !== "" && value !== false; + }; + + var toRounded = function toRounded(value) { + return Math.round(value); + }; + + var toHundred = function toHundred(value) { + return toRounded(value / 100) * 100; + }; + + var toUrlSafe = function toUrlSafe(value) { + return encodeURIComponent(value); + }; + + var formatters = { + br: toRounded, + d: toRounded, + bl: toHundred, + dl: toHundred, + mtp: toHundred, + nor: toUrlSafe, + rtp: toHundred, + tb: toRounded, + }; + var keys = Object.keys(data || {}).sort(); + + for (var _iterator2 = _createForOfIteratorHelperLoose(keys), _step2; !(_step2 = _iterator2()).done; ) { + var key = _step2.value; + var value = data[key]; // ignore invalid values + + if (!isValid(value)) { + continue; + } // Version should only be reported if not equal to 1. + + if (key === "v" && value === 1) { + continue; + } // Playback rate should only be sent if not equal to 1. + + if (key == "pr" && value === 1) { + continue; + } // Certain values require special formatting + + var formatter = formatters[key]; + + if (formatter) { + value = formatter(value); + } // Serialize the key/value pair + + var type = typeof value; + var result = void 0; + + if (key === "ot" || key === "sf" || key === "st") { + result = key + "=" + value; + } else if (type === "boolean") { + result = key; + } else if (type === "number") { + result = key + "=" + value; + } else { + result = key + "=" + JSON.stringify(value); + } + + results.push(result); + } + + return results.join(","); + }; + /** + * Convert a CMCD data object to request headers according to the rules + * defined in the section 2.1 and 3.2 of + * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). + */ + + CMCDController.toHeaders = function toHeaders(data) { + var keys = Object.keys(data); + var headers = {}; + var headerNames = ["Object", "Request", "Session", "Status"]; + var headerGroups = [{}, {}, {}, {}]; + var headerMap = { + br: 0, + d: 0, + ot: 0, + tb: 0, + bl: 1, + dl: 1, + mtp: 1, + nor: 1, + nrr: 1, + su: 1, + cid: 2, + pr: 2, + sf: 2, + sid: 2, + st: 2, + v: 2, + bs: 3, + rtp: 3, + }; + + for (var _i = 0, _keys = keys; _i < _keys.length; _i++) { + var key = _keys[_i]; + // Unmapped fields are mapped to the Request header + var index = headerMap[key] != null ? headerMap[key] : 1; + headerGroups[index][key] = data[key]; + } + + for (var i = 0; i < headerGroups.length; i++) { + var value = CMCDController.serialize(headerGroups[i]); + + if (value) { + headers["CMCD-" + headerNames[i]] = value; + } + } + + return headers; + }; + /** + * Convert a CMCD data object to query args according to the rules + * defined in the section 2.2 and 3.2 of + * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). + */ + + CMCDController.toQuery = function toQuery(data) { + return "CMCD=" + encodeURIComponent(CMCDController.serialize(data)); + }; + /** + * Append query args to a uri. + */ + + CMCDController.appendQueryToUri = function appendQueryToUri(uri, query) { + if (!query) { + return uri; + } + + var separator = uri.includes("?") ? "&" : "?"; + return "" + uri + separator + query; + }; + + return CMCDController; + })(); + + /***/ + }, + + /***/ "./src/controller/eme-controller.ts": + /*!******************************************!*\ !*** ./src/controller/eme-controller.ts ***! \******************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/mediakeys-helper */ "./src/utils/mediakeys-helper.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -/** - * @author Stephan Hesse | - * - * DRM support for CiderHls.js - */ - - - - -var MAX_LICENSE_REQUEST_FAILURES = 3; -/** - * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemConfiguration - * @param {Array} audioCodecs List of required audio codecs to support - * @param {Array} videoCodecs List of required video codecs to support - * @param {object} drmSystemOptions Optional parameters/requirements for the key-system - * @returns {Array} An array of supported configurations - */ - -var createWidevineMediaKeySystemConfigurations = function createWidevineMediaKeySystemConfigurations(audioCodecs, videoCodecs, drmSystemOptions) { - /* jshint ignore:line */ - var baseConfig = { - // initDataTypes: ['keyids', 'mp4'], - // label: "", - // persistentState: "not-allowed", // or "required" ? - // distinctiveIdentifier: "not-allowed", // or "required" ? - // sessionTypes: ['temporary'], - audioCapabilities: [], - // { contentType: 'audio/mp4; codecs="mp4a.40.2"' } - videoCapabilities: [] // { contentType: 'video/mp4; codecs="avc1.42E01E"' } - - }; - audioCodecs.forEach(function (codec) { - baseConfig.audioCapabilities.push({ - contentType: "audio/mp4; codecs=\"" + codec + "\"", - robustness: drmSystemOptions.audioRobustness || '' - }); - }); - videoCodecs.forEach(function (codec) { - baseConfig.videoCapabilities.push({ - contentType: "video/mp4; codecs=\"" + codec + "\"", - robustness: drmSystemOptions.videoRobustness || '' - }); - }); - return [baseConfig]; -}; -/** - * The idea here is to handle key-system (and their respective platforms) specific configuration differences - * in order to work with the local requestMediaKeySystemAccess method. - * - * We can also rule-out platform-related key-system support at this point by throwing an error. - * - * @param {string} keySystem Identifier for the key-system, see `KeySystems` enum - * @param {Array} audioCodecs List of required audio codecs to support - * @param {Array} videoCodecs List of required video codecs to support - * @throws will throw an error if a unknown key system is passed - * @returns {Array} A non-empty Array of MediaKeySystemConfiguration objects - */ - - -var getSupportedMediaKeySystemConfigurations = function getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, drmSystemOptions) { - switch (keySystem) { - case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE: - return createWidevineMediaKeySystemConfigurations(audioCodecs, videoCodecs, drmSystemOptions); - - default: - throw new Error("Unknown key-system: " + keySystem); - } -}; - -/** - * Controller to deal with encrypted media extensions (EME) - * @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API - * - * @class - * @constructor - */ -var EMEController = /*#__PURE__*/function () { - /** - * @constructs - * @param {CiderHls} CiderHls Our CiderHls.js instance - */ - function EMEController(CiderHls) { - this.CiderHls = void 0; - this._widevineLicenseUrl = void 0; - this._licenseXhrSetup = void 0; - this._licenseResponseCallback = void 0; - this._emeEnabled = void 0; - this._requestMediaKeySystemAccess = void 0; - this._drmSystemOptions = void 0; - this._config = void 0; - this._mediaKeysList = []; - this._media = null; - this._hasSetMediaKeys = false; - this._requestLicenseFailureCount = 0; - this.mediaKeysPromise = null; - this._onMediaEncrypted = this.onMediaEncrypted.bind(this); - this.CiderHls = CiderHls; - this._config = CiderHls.config; - this._widevineLicenseUrl = this._config.widevineLicenseUrl; - this._licenseXhrSetup = this._config.licenseXhrSetup; - this._licenseResponseCallback = this._config.licenseResponseCallback; - this._emeEnabled = this._config.emeEnabled; - this._requestMediaKeySystemAccess = this._config.requestMediaKeySystemAccessFunc; - this._drmSystemOptions = this._config.drmSystemOptions; - - this._registerListeners(); - } - - var _proto = EMEController.prototype; - - _proto.destroy = function destroy() { - this._unregisterListeners(); // @ts-ignore - - - this.CiderHls = this._onMediaEncrypted = null; - this._requestMediaKeySystemAccess = null; - }; - - _proto._registerListeners = function _registerListeners() { - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - }; - - _proto._unregisterListeners = function _unregisterListeners() { - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - } - /** - * @param {string} keySystem Identifier for the key-system, see `KeySystems` enum - * @returns {string} License server URL for key-system (if any configured, otherwise causes error) - * @throws if a unsupported keysystem is passed - */ - ; - - _proto.getLicenseServerUrl = function getLicenseServerUrl(keySystem) { - switch (keySystem) { - case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE: - if (!this._widevineLicenseUrl) { - break; - } - - return this._widevineLicenseUrl; - } - - throw new Error("no license server URL configured for key-system \"" + keySystem + "\""); - } - /** - * Requests access object and adds it to our list upon success - * @private - * @param {string} keySystem System ID (see `KeySystems`) - * @param {Array} audioCodecs List of required audio codecs to support - * @param {Array} videoCodecs List of required video codecs to support - * @throws When a unsupported KeySystem is passed - */ - ; - - _proto._attemptKeySystemAccess = function _attemptKeySystemAccess(keySystem, audioCodecs, videoCodecs) { - var _this = this; - - // This can throw, but is caught in event handler callpath - var mediaKeySystemConfigs = getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, this._drmSystemOptions); - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Requesting encrypted media key-system access'); // expecting interface like window.navigator.requestMediaKeySystemAccess - - var keySystemAccessPromise = this.requestMediaKeySystemAccess(keySystem, mediaKeySystemConfigs); - this.mediaKeysPromise = keySystemAccessPromise.then(function (mediaKeySystemAccess) { - return _this._onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess); - }); - keySystemAccessPromise.catch(function (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Failed to obtain key-system \"" + keySystem + "\" access:", err); - }); - }; - - /** - * Handles obtaining access to a key-system - * @private - * @param {string} keySystem - * @param {MediaKeySystemAccess} mediaKeySystemAccess https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemAccess - */ - _proto._onMediaKeySystemAccessObtained = function _onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess) { - var _this2 = this; - - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Access for key-system \"" + keySystem + "\" obtained"); - var mediaKeysListItem = { - mediaKeysSessionInitialized: false, - mediaKeySystemAccess: mediaKeySystemAccess, - mediaKeySystemDomain: keySystem - }; - - this._mediaKeysList.push(mediaKeysListItem); - - var mediaKeysPromise = Promise.resolve().then(function () { - return mediaKeySystemAccess.createMediaKeys(); - }).then(function (mediaKeys) { - mediaKeysListItem.mediaKeys = mediaKeys; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Media-keys created for key-system \"" + keySystem + "\""); - - _this2._onMediaKeysCreated(); - - return mediaKeys; - }); - mediaKeysPromise.catch(function (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Failed to create media-keys:', err); - }); - return mediaKeysPromise; - } - /** - * Handles key-creation (represents access to CDM). We are going to create key-sessions upon this - * for all existing keys where no session exists yet. - * - * @private - */ - ; - - _proto._onMediaKeysCreated = function _onMediaKeysCreated() { - var _this3 = this; - - // check for all key-list items if a session exists, otherwise, create one - this._mediaKeysList.forEach(function (mediaKeysListItem) { - if (!mediaKeysListItem.mediaKeysSession) { - // mediaKeys is definitely initialized here - mediaKeysListItem.mediaKeysSession = mediaKeysListItem.mediaKeys.createSession(); - - _this3._onNewMediaKeySession(mediaKeysListItem.mediaKeysSession); - } - }); - } - /** - * @private - * @param {*} keySession - */ - ; - - _proto._onNewMediaKeySession = function _onNewMediaKeySession(keySession) { - var _this4 = this; - - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("New key-system session " + keySession.sessionId); - keySession.addEventListener('message', function (event) { - _this4._onKeySessionMessage(keySession, event.message); - }, false); - } - /** - * @private - * @param {MediaKeySession} keySession - * @param {ArrayBuffer} message - */ - ; - - _proto._onKeySessionMessage = function _onKeySessionMessage(keySession, message) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Got EME message event, creating license request'); - - this._requestLicense(message, function (data) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Received license data (length: " + (data ? data.byteLength : data) + "), updating key-session"); - keySession.update(data); - }); - } - /** - * @private - * @param e {MediaEncryptedEvent} - */ - ; - - _proto.onMediaEncrypted = function onMediaEncrypted(e) { - var _this5 = this; - - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Media is encrypted using \"" + e.initDataType + "\" init data type"); - - if (!this.mediaKeysPromise) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Fatal: Media is encrypted but no CDM access or no keys have been requested'); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_KEYS, - fatal: true - }); - return; - } - - var finallySetKeyAndStartSession = function finallySetKeyAndStartSession(mediaKeys) { - if (!_this5._media) { - return; - } - - _this5._attemptSetMediaKeys(mediaKeys); - - _this5._generateRequestWithPreferredKeySession(e.initDataType, e.initData); - }; // Could use `Promise.finally` but some Promise polyfills are missing it - - - this.mediaKeysPromise.then(finallySetKeyAndStartSession).catch(finallySetKeyAndStartSession); - } - /** - * @private - */ - ; - - _proto._attemptSetMediaKeys = function _attemptSetMediaKeys(mediaKeys) { - if (!this._media) { - throw new Error('Attempted to set mediaKeys without first attaching a media element'); - } - - if (!this._hasSetMediaKeys) { - // FIXME: see if we can/want/need-to really to deal with several potential key-sessions? - var keysListItem = this._mediaKeysList[0]; - - if (!keysListItem || !keysListItem.mediaKeys) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Fatal: Media is encrypted but no CDM access or no keys have been obtained yet'); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_KEYS, - fatal: true - }); - return; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Setting keys for encrypted media'); - - this._media.setMediaKeys(keysListItem.mediaKeys); - - this._hasSetMediaKeys = true; - } - } - /** - * @private - */ - ; - - _proto._generateRequestWithPreferredKeySession = function _generateRequestWithPreferredKeySession(initDataType, initData) { - var _this6 = this; - - // FIXME: see if we can/want/need-to really to deal with several potential key-sessions? - var keysListItem = this._mediaKeysList[0]; - - if (!keysListItem) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Fatal: Media is encrypted but not any key-system access has been obtained yet'); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_ACCESS, - fatal: true - }); - return; - } - - if (keysListItem.mediaKeysSessionInitialized) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn('Key-Session already initialized but requested again'); - return; - } - - var keySession = keysListItem.mediaKeysSession; - - if (!keySession) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Fatal: Media is encrypted but no key-session existing'); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_SESSION, - fatal: true - }); - return; - } // initData is null if the media is not CORS-same-origin - - - if (!initData) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn('Fatal: initData required for generating a key session is null'); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_INIT_DATA, - fatal: true - }); - return; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Generating key-session request for \"" + initDataType + "\" init data type"); - keysListItem.mediaKeysSessionInitialized = true; - keySession.generateRequest(initDataType, initData).then(function () { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].debug('Key-session generation succeeded'); - }).catch(function (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Error generating key-session request:', err); - - _this6.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_SESSION, - fatal: false - }); - }); - } - /** - * @private - * @param {string} url License server URL - * @param {ArrayBuffer} keyMessage Message data issued by key-system - * @param {function} callback Called when XHR has succeeded - * @returns {XMLHttpRequest} Unsent (but opened state) XHR object - * @throws if XMLHttpRequest construction failed - */ - ; - - _proto._createLicenseXhr = function _createLicenseXhr(url, keyMessage, callback) { - var xhr = new XMLHttpRequest(); - xhr.responseType = 'arraybuffer'; - xhr.onreadystatechange = this._onLicenseRequestReadyStageChange.bind(this, xhr, url, keyMessage, callback); - var licenseXhrSetup = this._licenseXhrSetup; - - if (licenseXhrSetup) { - try { - licenseXhrSetup.call(this.CiderHls, xhr, url); - licenseXhrSetup = undefined; - } catch (e) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error(e); - } - } - - try { - // if licenseXhrSetup did not yet call open, let's do it now - if (!xhr.readyState) { - xhr.open('POST', url, true); - } - - if (licenseXhrSetup) { - licenseXhrSetup.call(this.CiderHls, xhr, url); - } - } catch (e) { - // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS - throw new Error("issue setting up KeySystem license XHR " + e); - } - - return xhr; - } - /** - * @private - * @param {XMLHttpRequest} xhr - * @param {string} url License server URL - * @param {ArrayBuffer} keyMessage Message data issued by key-system - * @param {function} callback Called when XHR has succeeded - */ - ; - - _proto._onLicenseRequestReadyStageChange = function _onLicenseRequestReadyStageChange(xhr, url, keyMessage, callback) { - switch (xhr.readyState) { - case 4: - if (xhr.status === 200) { - this._requestLicenseFailureCount = 0; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('License request succeeded'); - var _data = xhr.response; - var licenseResponseCallback = this._licenseResponseCallback; - - if (licenseResponseCallback) { - try { - _data = licenseResponseCallback.call(this.CiderHls, xhr, url); - } catch (e) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error(e); + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/mediakeys-helper */ "./src/utils/mediakeys-helper.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } } - } - callback(_data); - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("License Request XHR failed (" + url + "). Status: " + xhr.status + " (" + xhr.statusText + ")"); - this._requestLicenseFailureCount++; + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } - if (this._requestLicenseFailureCount > MAX_LICENSE_REQUEST_FAILURES) { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_LICENSE_REQUEST_FAILED, - fatal: true - }); - return; - } + /** + * @author Stephan Hesse | + * + * DRM support for CiderHls.js + */ - var attemptsLeft = MAX_LICENSE_REQUEST_FAILURES - this._requestLicenseFailureCount + 1; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("Retrying license request, " + attemptsLeft + " attempts left"); + var MAX_LICENSE_REQUEST_FAILURES = 3; + /** + * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemConfiguration + * @param {Array} audioCodecs List of required audio codecs to support + * @param {Array} videoCodecs List of required video codecs to support + * @param {object} drmSystemOptions Optional parameters/requirements for the key-system + * @returns {Array} An array of supported configurations + */ - this._requestLicense(keyMessage, callback); - } + var createWidevineMediaKeySystemConfigurations = function createWidevineMediaKeySystemConfigurations(audioCodecs, videoCodecs, drmSystemOptions) { + /* jshint ignore:line */ + var baseConfig = { + // initDataTypes: ['keyids', 'mp4'], + // label: "", + // persistentState: "not-allowed", // or "required" ? + // distinctiveIdentifier: "not-allowed", // or "required" ? + // sessionTypes: ['temporary'], + audioCapabilities: [], + // { contentType: 'audio/mp4; codecs="mp4a.40.2"' } + videoCapabilities: [], // { contentType: 'video/mp4; codecs="avc1.42E01E"' } + }; + audioCodecs.forEach(function (codec) { + baseConfig.audioCapabilities.push({ + contentType: 'audio/mp4; codecs="' + codec + '"', + robustness: drmSystemOptions.audioRobustness || "", + }); + }); + videoCodecs.forEach(function (codec) { + baseConfig.videoCapabilities.push({ + contentType: 'video/mp4; codecs="' + codec + '"', + robustness: drmSystemOptions.videoRobustness || "", + }); + }); + return [baseConfig]; + }; + /** + * The idea here is to handle key-system (and their respective platforms) specific configuration differences + * in order to work with the local requestMediaKeySystemAccess method. + * + * We can also rule-out platform-related key-system support at this point by throwing an error. + * + * @param {string} keySystem Identifier for the key-system, see `KeySystems` enum + * @param {Array} audioCodecs List of required audio codecs to support + * @param {Array} videoCodecs List of required video codecs to support + * @throws will throw an error if a unknown key system is passed + * @returns {Array} A non-empty Array of MediaKeySystemConfiguration objects + */ - break; - } - } - /** - * @private - * @param {MediaKeysListItem} keysListItem - * @param {ArrayBuffer} keyMessage - * @returns {ArrayBuffer} Challenge data posted to license server - * @throws if KeySystem is unsupported - */ - ; + var getSupportedMediaKeySystemConfigurations = function getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, drmSystemOptions) { + switch (keySystem) { + case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE: + return createWidevineMediaKeySystemConfigurations(audioCodecs, videoCodecs, drmSystemOptions); - _proto._generateLicenseRequestChallenge = function _generateLicenseRequestChallenge(keysListItem, keyMessage) { - switch (keysListItem.mediaKeySystemDomain) { - // case KeySystems.PLAYREADY: - // from https://github.com/MicrosoftEdge/Demos/blob/master/eme/scripts/demo.js + default: + throw new Error("Unknown key-system: " + keySystem); + } + }; - /* + /** + * Controller to deal with encrypted media extensions (EME) + * @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API + * + * @class + * @constructor + */ + var EMEController = /*#__PURE__*/ (function () { + /** + * @constructs + * @param {CiderHls} CiderHls Our CiderHls.js instance + */ + function EMEController(CiderHls) { + this.CiderHls = void 0; + this._widevineLicenseUrl = void 0; + this._licenseXhrSetup = void 0; + this._licenseResponseCallback = void 0; + this._emeEnabled = void 0; + this._requestMediaKeySystemAccess = void 0; + this._drmSystemOptions = void 0; + this._config = void 0; + this._mediaKeysList = []; + this._media = null; + this._hasSetMediaKeys = false; + this._requestLicenseFailureCount = 0; + this.mediaKeysPromise = null; + this._onMediaEncrypted = this.onMediaEncrypted.bind(this); + this.CiderHls = CiderHls; + this._config = CiderHls.config; + this._widevineLicenseUrl = this._config.widevineLicenseUrl; + this._licenseXhrSetup = this._config.licenseXhrSetup; + this._licenseResponseCallback = this._config.licenseResponseCallback; + this._emeEnabled = this._config.emeEnabled; + this._requestMediaKeySystemAccess = this._config.requestMediaKeySystemAccessFunc; + this._drmSystemOptions = this._config.drmSystemOptions; + + this._registerListeners(); + } + + var _proto = EMEController.prototype; + + _proto.destroy = function destroy() { + this._unregisterListeners(); // @ts-ignore + + this.CiderHls = this._onMediaEncrypted = null; + this._requestMediaKeySystemAccess = null; + }; + + _proto._registerListeners = function _registerListeners() { + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + }; + + _proto._unregisterListeners = function _unregisterListeners() { + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHED, this.onMediaDetached, this); + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + }; + /** + * @param {string} keySystem Identifier for the key-system, see `KeySystems` enum + * @returns {string} License server URL for key-system (if any configured, otherwise causes error) + * @throws if a unsupported keysystem is passed + */ + + _proto.getLicenseServerUrl = function getLicenseServerUrl(keySystem) { + switch (keySystem) { + case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE: + if (!this._widevineLicenseUrl) { + break; + } + + return this._widevineLicenseUrl; + } + + throw new Error('no license server URL configured for key-system "' + keySystem + '"'); + }; + /** + * Requests access object and adds it to our list upon success + * @private + * @param {string} keySystem System ID (see `KeySystems`) + * @param {Array} audioCodecs List of required audio codecs to support + * @param {Array} videoCodecs List of required video codecs to support + * @throws When a unsupported KeySystem is passed + */ + + _proto._attemptKeySystemAccess = function _attemptKeySystemAccess(keySystem, audioCodecs, videoCodecs) { + var _this = this; + + // This can throw, but is caught in event handler callpath + var mediaKeySystemConfigs = getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, this._drmSystemOptions); + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Requesting encrypted media key-system access"); // expecting interface like window.navigator.requestMediaKeySystemAccess + + var keySystemAccessPromise = this.requestMediaKeySystemAccess(keySystem, mediaKeySystemConfigs); + this.mediaKeysPromise = keySystemAccessPromise.then(function (mediaKeySystemAccess) { + return _this._onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess); + }); + keySystemAccessPromise.catch(function (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Failed to obtain key-system "' + keySystem + '" access:', err); + }); + }; + + /** + * Handles obtaining access to a key-system + * @private + * @param {string} keySystem + * @param {MediaKeySystemAccess} mediaKeySystemAccess https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemAccess + */ + _proto._onMediaKeySystemAccessObtained = function _onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess) { + var _this2 = this; + + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Access for key-system "' + keySystem + '" obtained'); + var mediaKeysListItem = { + mediaKeysSessionInitialized: false, + mediaKeySystemAccess: mediaKeySystemAccess, + mediaKeySystemDomain: keySystem, + }; + + this._mediaKeysList.push(mediaKeysListItem); + + var mediaKeysPromise = Promise.resolve() + .then(function () { + return mediaKeySystemAccess.createMediaKeys(); + }) + .then(function (mediaKeys) { + mediaKeysListItem.mediaKeys = mediaKeys; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Media-keys created for key-system "' + keySystem + '"'); + + _this2._onMediaKeysCreated(); + + return mediaKeys; + }); + mediaKeysPromise.catch(function (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Failed to create media-keys:", err); + }); + return mediaKeysPromise; + }; + /** + * Handles key-creation (represents access to CDM). We are going to create key-sessions upon this + * for all existing keys where no session exists yet. + * + * @private + */ + + _proto._onMediaKeysCreated = function _onMediaKeysCreated() { + var _this3 = this; + + // check for all key-list items if a session exists, otherwise, create one + this._mediaKeysList.forEach(function (mediaKeysListItem) { + if (!mediaKeysListItem.mediaKeysSession) { + // mediaKeys is definitely initialized here + mediaKeysListItem.mediaKeysSession = mediaKeysListItem.mediaKeys.createSession(); + + _this3._onNewMediaKeySession(mediaKeysListItem.mediaKeysSession); + } + }); + }; + /** + * @private + * @param {*} keySession + */ + + _proto._onNewMediaKeySession = function _onNewMediaKeySession(keySession) { + var _this4 = this; + + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("New key-system session " + keySession.sessionId); + keySession.addEventListener( + "message", + function (event) { + _this4._onKeySessionMessage(keySession, event.message); + }, + false + ); + }; + /** + * @private + * @param {MediaKeySession} keySession + * @param {ArrayBuffer} message + */ + + _proto._onKeySessionMessage = function _onKeySessionMessage(keySession, message) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Got EME message event, creating license request"); + + this._requestLicense(message, function (data) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Received license data (length: " + (data ? data.byteLength : data) + "), updating key-session"); + keySession.update(data); + }); + }; + /** + * @private + * @param e {MediaEncryptedEvent} + */ + + _proto.onMediaEncrypted = function onMediaEncrypted(e) { + var _this5 = this; + + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Media is encrypted using "' + e.initDataType + '" init data type'); + + if (!this.mediaKeysPromise) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Fatal: Media is encrypted but no CDM access or no keys have been requested"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_KEYS, + fatal: true, + }); + return; + } + + var finallySetKeyAndStartSession = function finallySetKeyAndStartSession(mediaKeys) { + if (!_this5._media) { + return; + } + + _this5._attemptSetMediaKeys(mediaKeys); + + _this5._generateRequestWithPreferredKeySession(e.initDataType, e.initData); + }; // Could use `Promise.finally` but some Promise polyfills are missing it + + this.mediaKeysPromise.then(finallySetKeyAndStartSession).catch(finallySetKeyAndStartSession); + }; + /** + * @private + */ + + _proto._attemptSetMediaKeys = function _attemptSetMediaKeys(mediaKeys) { + if (!this._media) { + throw new Error("Attempted to set mediaKeys without first attaching a media element"); + } + + if (!this._hasSetMediaKeys) { + // FIXME: see if we can/want/need-to really to deal with several potential key-sessions? + var keysListItem = this._mediaKeysList[0]; + + if (!keysListItem || !keysListItem.mediaKeys) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Fatal: Media is encrypted but no CDM access or no keys have been obtained yet"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_KEYS, + fatal: true, + }); + return; + } + + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Setting keys for encrypted media"); + + this._media.setMediaKeys(keysListItem.mediaKeys); + + this._hasSetMediaKeys = true; + } + }; + /** + * @private + */ + + _proto._generateRequestWithPreferredKeySession = function _generateRequestWithPreferredKeySession(initDataType, initData) { + var _this6 = this; + + // FIXME: see if we can/want/need-to really to deal with several potential key-sessions? + var keysListItem = this._mediaKeysList[0]; + + if (!keysListItem) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Fatal: Media is encrypted but not any key-system access has been obtained yet"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_ACCESS, + fatal: true, + }); + return; + } + + if (keysListItem.mediaKeysSessionInitialized) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("Key-Session already initialized but requested again"); + return; + } + + var keySession = keysListItem.mediaKeysSession; + + if (!keySession) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Fatal: Media is encrypted but no key-session existing"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_SESSION, + fatal: true, + }); + return; + } // initData is null if the media is not CORS-same-origin + + if (!initData) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("Fatal: initData required for generating a key session is null"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_INIT_DATA, + fatal: true, + }); + return; + } + + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Generating key-session request for "' + initDataType + '" init data type'); + keysListItem.mediaKeysSessionInitialized = true; + keySession + .generateRequest(initDataType, initData) + .then(function () { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].debug("Key-session generation succeeded"); + }) + .catch(function (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Error generating key-session request:", err); + + _this6.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_SESSION, + fatal: false, + }); + }); + }; + /** + * @private + * @param {string} url License server URL + * @param {ArrayBuffer} keyMessage Message data issued by key-system + * @param {function} callback Called when XHR has succeeded + * @returns {XMLHttpRequest} Unsent (but opened state) XHR object + * @throws if XMLHttpRequest construction failed + */ + + _proto._createLicenseXhr = function _createLicenseXhr(url, keyMessage, callback) { + var xhr = new XMLHttpRequest(); + xhr.responseType = "arraybuffer"; + xhr.onreadystatechange = this._onLicenseRequestReadyStageChange.bind(this, xhr, url, keyMessage, callback); + var licenseXhrSetup = this._licenseXhrSetup; + + if (licenseXhrSetup) { + try { + licenseXhrSetup.call(this.CiderHls, xhr, url); + licenseXhrSetup = undefined; + } catch (e) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error(e); + } + } + + try { + // if licenseXhrSetup did not yet call open, let's do it now + if (!xhr.readyState) { + xhr.open("POST", url, true); + } + + if (licenseXhrSetup) { + licenseXhrSetup.call(this.CiderHls, xhr, url); + } + } catch (e) { + // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS + throw new Error("issue setting up KeySystem license XHR " + e); + } + + return xhr; + }; + /** + * @private + * @param {XMLHttpRequest} xhr + * @param {string} url License server URL + * @param {ArrayBuffer} keyMessage Message data issued by key-system + * @param {function} callback Called when XHR has succeeded + */ + + _proto._onLicenseRequestReadyStageChange = function _onLicenseRequestReadyStageChange(xhr, url, keyMessage, callback) { + switch (xhr.readyState) { + case 4: + if (xhr.status === 200) { + this._requestLicenseFailureCount = 0; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("License request succeeded"); + var _data = xhr.response; + var licenseResponseCallback = this._licenseResponseCallback; + + if (licenseResponseCallback) { + try { + _data = licenseResponseCallback.call(this.CiderHls, xhr, url); + } catch (e) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error(e); + } + } + + callback(_data); + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("License Request XHR failed (" + url + "). Status: " + xhr.status + " (" + xhr.statusText + ")"); + this._requestLicenseFailureCount++; + + if (this._requestLicenseFailureCount > MAX_LICENSE_REQUEST_FAILURES) { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_LICENSE_REQUEST_FAILED, + fatal: true, + }); + return; + } + + var attemptsLeft = MAX_LICENSE_REQUEST_FAILURES - this._requestLicenseFailureCount + 1; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("Retrying license request, " + attemptsLeft + " attempts left"); + + this._requestLicense(keyMessage, callback); + } + + break; + } + }; + /** + * @private + * @param {MediaKeysListItem} keysListItem + * @param {ArrayBuffer} keyMessage + * @returns {ArrayBuffer} Challenge data posted to license server + * @throws if KeySystem is unsupported + */ + + _proto._generateLicenseRequestChallenge = function _generateLicenseRequestChallenge(keysListItem, keyMessage) { + switch (keysListItem.mediaKeySystemDomain) { + // case KeySystems.PLAYREADY: + // from https://github.com/MicrosoftEdge/Demos/blob/master/eme/scripts/demo.js + + /* if (this.licenseType !== this.LICENSE_TYPE_WIDEVINE) { // For PlayReady CDMs, we need to dig the Challenge out of the XML. var keyMessageXml = new DOMParser().parseFromString(String.fromCharCode.apply(null, new Uint16Array(keyMessage)), 'application/xml'); @@ -6486,6405 +6710,6528 @@ var EMEController = /*#__PURE__*/function () { } break; */ - case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE: - // For Widevine CDMs, the challenge is the keyMessage. - return keyMessage; - } + case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE: + // For Widevine CDMs, the challenge is the keyMessage. + return keyMessage; + } - throw new Error("unsupported key-system: " + keysListItem.mediaKeySystemDomain); - } - /** - * @private - * @param keyMessage - * @param callback - */ - ; + throw new Error("unsupported key-system: " + keysListItem.mediaKeySystemDomain); + }; + /** + * @private + * @param keyMessage + * @param callback + */ - _proto._requestLicense = function _requestLicense(keyMessage, callback) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('Requesting content license for key-system'); - var keysListItem = this._mediaKeysList[0]; + _proto._requestLicense = function _requestLicense(keyMessage, callback) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Requesting content license for key-system"); + var keysListItem = this._mediaKeysList[0]; - if (!keysListItem) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('Fatal error: Media is encrypted but no key-system access has been obtained yet'); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_ACCESS, - fatal: true - }); - return; - } + if (!keysListItem) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Fatal error: Media is encrypted but no key-system access has been obtained yet"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_NO_ACCESS, + fatal: true, + }); + return; + } - try { - var _url = this.getLicenseServerUrl(keysListItem.mediaKeySystemDomain); + try { + var _url = this.getLicenseServerUrl(keysListItem.mediaKeySystemDomain); - var _xhr = this._createLicenseXhr(_url, keyMessage, callback); + var _xhr = this._createLicenseXhr(_url, keyMessage, callback); - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Sending license request to URL: " + _url); + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("Sending license request to URL: " + _url); - var challenge = this._generateLicenseRequestChallenge(keysListItem, keyMessage); + var challenge = this._generateLicenseRequestChallenge(keysListItem, keyMessage); - _xhr.send(challenge); - } catch (e) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Failure requesting DRM license: " + e); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_LICENSE_REQUEST_FAILED, - fatal: true - }); - } - }; + _xhr.send(challenge); + } catch (e) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("Failure requesting DRM license: " + e); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].KEY_SYSTEM_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_SYSTEM_LICENSE_REQUEST_FAILED, + fatal: true, + }); + } + }; - _proto.onMediaAttached = function onMediaAttached(event, data) { - if (!this._emeEnabled) { - return; - } + _proto.onMediaAttached = function onMediaAttached(event, data) { + if (!this._emeEnabled) { + return; + } - var media = data.media; // keep reference of media + var media = data.media; // keep reference of media - this._media = media; - media.addEventListener('encrypted', this._onMediaEncrypted); - }; + this._media = media; + media.addEventListener("encrypted", this._onMediaEncrypted); + }; - _proto.onMediaDetached = function onMediaDetached() { - var media = this._media; - var mediaKeysList = this._mediaKeysList; + _proto.onMediaDetached = function onMediaDetached() { + var media = this._media; + var mediaKeysList = this._mediaKeysList; - if (!media) { - return; - } + if (!media) { + return; + } - media.removeEventListener('encrypted', this._onMediaEncrypted); - this._media = null; - this._mediaKeysList = []; // Close all sessions and remove media keys from the video element. + media.removeEventListener("encrypted", this._onMediaEncrypted); + this._media = null; + this._mediaKeysList = []; // Close all sessions and remove media keys from the video element. - Promise.all(mediaKeysList.map(function (mediaKeysListItem) { - if (mediaKeysListItem.mediaKeysSession) { - return mediaKeysListItem.mediaKeysSession.close().catch(function () {// Ignore errors when closing the sessions. Closing a session that - // generated no key requests will throw an error. - }); - } - })).then(function () { - return media.setMediaKeys(null); - }).catch(function () {// Ignore any failures while removing media keys from the video element. - }); - }; + Promise.all( + mediaKeysList.map(function (mediaKeysListItem) { + if (mediaKeysListItem.mediaKeysSession) { + return mediaKeysListItem.mediaKeysSession.close().catch(function () { + // Ignore errors when closing the sessions. Closing a session that + // generated no key requests will throw an error. + }); + } + }) + ) + .then(function () { + return media.setMediaKeys(null); + }) + .catch(function () { + // Ignore any failures while removing media keys from the video element. + }); + }; - _proto.onManifestParsed = function onManifestParsed(event, data) { - if (!this._emeEnabled) { - return; - } + _proto.onManifestParsed = function onManifestParsed(event, data) { + if (!this._emeEnabled) { + return; + } - var audioCodecs = data.levels.map(function (level) { - return level.audioCodec; - }).filter(function (audioCodec) { - return !!audioCodec; - }); - var videoCodecs = data.levels.map(function (level) { - return level.videoCodec; - }).filter(function (videoCodec) { - return !!videoCodec; - }); + var audioCodecs = data.levels + .map(function (level) { + return level.audioCodec; + }) + .filter(function (audioCodec) { + return !!audioCodec; + }); + var videoCodecs = data.levels + .map(function (level) { + return level.videoCodec; + }) + .filter(function (videoCodec) { + return !!videoCodec; + }); - this._attemptKeySystemAccess(_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE, audioCodecs, videoCodecs); - }; + this._attemptKeySystemAccess(_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__["KeySystems"].WIDEVINE, audioCodecs, videoCodecs); + }; - _createClass(EMEController, [{ - key: "requestMediaKeySystemAccess", - get: function get() { - if (!this._requestMediaKeySystemAccess) { - throw new Error('No requestMediaKeySystemAccess function configured'); - } + _createClass(EMEController, [ + { + key: "requestMediaKeySystemAccess", + get: function get() { + if (!this._requestMediaKeySystemAccess) { + throw new Error("No requestMediaKeySystemAccess function configured"); + } - return this._requestMediaKeySystemAccess; - } - }]); + return this._requestMediaKeySystemAccess; + }, + }, + ]); - return EMEController; -}(); + return EMEController; + })(); -/* harmony default export */ __webpack_exports__["default"] = (EMEController); + /* harmony default export */ __webpack_exports__["default"] = EMEController; -/***/ }), + /***/ + }, -/***/ "./src/controller/fps-controller.ts": -/*!******************************************!*\ + /***/ "./src/controller/fps-controller.ts": + /*!******************************************!*\ !*** ./src/controller/fps-controller.ts ***! \******************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + var FPSController = /*#__PURE__*/ (function () { + // stream controller must be provided as a dependency! + function FPSController(CiderHls) { + this.CiderHls = void 0; + this.isVideoPlaybackQualityAvailable = false; + this.timer = void 0; + this.media = null; + this.lastTime = void 0; + this.lastDroppedFrames = 0; + this.lastDecodedFrames = 0; + this.streamController = void 0; + this.CiderHls = CiderHls; + this.registerListeners(); + } + var _proto = FPSController.prototype; + _proto.setStreamController = function setStreamController(streamController) { + this.streamController = streamController; + }; -var FPSController = /*#__PURE__*/function () { - // stream controller must be provided as a dependency! - function FPSController(CiderHls) { - this.CiderHls = void 0; - this.isVideoPlaybackQualityAvailable = false; - this.timer = void 0; - this.media = null; - this.lastTime = void 0; - this.lastDroppedFrames = 0; - this.lastDecodedFrames = 0; - this.streamController = void 0; - this.CiderHls = CiderHls; - this.registerListeners(); - } + _proto.registerListeners = function registerListeners() { + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); + }; - var _proto = FPSController.prototype; + _proto.unregisterListeners = function unregisterListeners() { + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching); + }; - _proto.setStreamController = function setStreamController(streamController) { - this.streamController = streamController; - }; + _proto.destroy = function destroy() { + if (this.timer) { + clearInterval(this.timer); + } - _proto.registerListeners = function registerListeners() { - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); - }; + this.unregisterListeners(); + this.isVideoPlaybackQualityAvailable = false; + this.media = null; + }; - _proto.unregisterListeners = function unregisterListeners() { - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHING, this.onMediaAttaching); - }; + _proto.onMediaAttaching = function onMediaAttaching(event, data) { + var config = this.CiderHls.config; - _proto.destroy = function destroy() { - if (this.timer) { - clearInterval(this.timer); - } + if (config.capLevelOnFPSDrop) { + var media = data.media instanceof self.HTMLVideoElement ? data.media : null; + this.media = media; - this.unregisterListeners(); - this.isVideoPlaybackQualityAvailable = false; - this.media = null; - }; + if (media && typeof media.getVideoPlaybackQuality === "function") { + this.isVideoPlaybackQualityAvailable = true; + } - _proto.onMediaAttaching = function onMediaAttaching(event, data) { - var config = this.CiderHls.config; + self.clearInterval(this.timer); + this.timer = self.setInterval(this.checkFPSInterval.bind(this), config.fpsDroppedMonitoringPeriod); + } + }; - if (config.capLevelOnFPSDrop) { - var media = data.media instanceof self.HTMLVideoElement ? data.media : null; - this.media = media; + _proto.checkFPS = function checkFPS(video, decodedFrames, droppedFrames) { + var currentTime = performance.now(); - if (media && typeof media.getVideoPlaybackQuality === 'function') { - this.isVideoPlaybackQualityAvailable = true; - } + if (decodedFrames) { + if (this.lastTime) { + var currentPeriod = currentTime - this.lastTime; + var currentDropped = droppedFrames - this.lastDroppedFrames; + var currentDecoded = decodedFrames - this.lastDecodedFrames; + var droppedFPS = (1000 * currentDropped) / currentPeriod; + var CiderHls = this.CiderHls; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP, { + currentDropped: currentDropped, + currentDecoded: currentDecoded, + totalDroppedFrames: droppedFrames, + }); - self.clearInterval(this.timer); - this.timer = self.setInterval(this.checkFPSInterval.bind(this), config.fpsDroppedMonitoringPeriod); - } - }; + if (droppedFPS > 0) { + // logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod)); + if (currentDropped > CiderHls.config.fpsDroppedMonitoringThreshold * currentDecoded) { + var currentLevel = CiderHls.currentLevel; + _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn("drop FPS ratio greater than max allowed value for currentLevel: " + currentLevel); - _proto.checkFPS = function checkFPS(video, decodedFrames, droppedFrames) { - var currentTime = performance.now(); + if (currentLevel > 0 && (CiderHls.autoLevelCapping === -1 || CiderHls.autoLevelCapping >= currentLevel)) { + currentLevel = currentLevel - 1; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP_LEVEL_CAPPING, { + level: currentLevel, + droppedLevel: CiderHls.currentLevel, + }); + CiderHls.autoLevelCapping = currentLevel; + this.streamController.nextLevelSwitch(); + } + } + } + } - if (decodedFrames) { - if (this.lastTime) { - var currentPeriod = currentTime - this.lastTime; - var currentDropped = droppedFrames - this.lastDroppedFrames; - var currentDecoded = decodedFrames - this.lastDecodedFrames; - var droppedFPS = 1000 * currentDropped / currentPeriod; - var CiderHls = this.CiderHls; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP, { - currentDropped: currentDropped, - currentDecoded: currentDecoded, - totalDroppedFrames: droppedFrames - }); + this.lastTime = currentTime; + this.lastDroppedFrames = droppedFrames; + this.lastDecodedFrames = decodedFrames; + } + }; - if (droppedFPS > 0) { - // logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod)); - if (currentDropped > CiderHls.config.fpsDroppedMonitoringThreshold * currentDecoded) { - var currentLevel = CiderHls.currentLevel; - _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel); + _proto.checkFPSInterval = function checkFPSInterval() { + var video = this.media; - if (currentLevel > 0 && (CiderHls.autoLevelCapping === -1 || CiderHls.autoLevelCapping >= currentLevel)) { - currentLevel = currentLevel - 1; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FPS_DROP_LEVEL_CAPPING, { - level: currentLevel, - droppedLevel: CiderHls.currentLevel - }); - CiderHls.autoLevelCapping = currentLevel; - this.streamController.nextLevelSwitch(); - } - } - } - } + if (video) { + if (this.isVideoPlaybackQualityAvailable) { + var videoPlaybackQuality = video.getVideoPlaybackQuality(); + this.checkFPS(video, videoPlaybackQuality.totalVideoFrames, videoPlaybackQuality.droppedVideoFrames); + } else { + // HTMLVideoElement doesn't include the webkit types + this.checkFPS(video, video.webkitDecodedFrameCount, video.webkitDroppedFrameCount); + } + } + }; - this.lastTime = currentTime; - this.lastDroppedFrames = droppedFrames; - this.lastDecodedFrames = decodedFrames; - } - }; + return FPSController; + })(); - _proto.checkFPSInterval = function checkFPSInterval() { - var video = this.media; + /* harmony default export */ __webpack_exports__["default"] = FPSController; - if (video) { - if (this.isVideoPlaybackQualityAvailable) { - var videoPlaybackQuality = video.getVideoPlaybackQuality(); - this.checkFPS(video, videoPlaybackQuality.totalVideoFrames, videoPlaybackQuality.droppedVideoFrames); - } else { - // HTMLVideoElement doesn't include the webkit types - this.checkFPS(video, video.webkitDecodedFrameCount, video.webkitDroppedFrameCount); - } - } - }; + /***/ + }, - return FPSController; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (FPSController); - -/***/ }), - -/***/ "./src/controller/fragment-finders.ts": -/*!********************************************!*\ + /***/ "./src/controller/fragment-finders.ts": + /*!********************************************!*\ !*** ./src/controller/fragment-finders.ts ***! \********************************************/ -/*! exports provided: findFragmentByPDT, findFragmentByPTS, fragmentWithinToleranceTest, pdtWithinToleranceTest, findFragWithCC */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: findFragmentByPDT, findFragmentByPTS, fragmentWithinToleranceTest, pdtWithinToleranceTest, findFragWithCC */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFragmentByPDT", function () { + return findFragmentByPDT; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFragmentByPTS", function () { + return findFragmentByPTS; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fragmentWithinToleranceTest", function () { + return fragmentWithinToleranceTest; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pdtWithinToleranceTest", function () { + return pdtWithinToleranceTest; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFragWithCC", function () { + return findFragWithCC; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/binary-search */ "./src/utils/binary-search.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFragmentByPDT", function() { return findFragmentByPDT; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFragmentByPTS", function() { return findFragmentByPTS; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fragmentWithinToleranceTest", function() { return fragmentWithinToleranceTest; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pdtWithinToleranceTest", function() { return pdtWithinToleranceTest; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFragWithCC", function() { return findFragWithCC; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/binary-search */ "./src/utils/binary-search.ts"); + /** + * Returns first fragment whose endPdt value exceeds the given PDT. + * @param {Array} fragments - The array of candidate fragments + * @param {number|null} [PDTValue = null] - The PDT value which must be exceeded + * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start/end can be within in order to be considered contiguous + * @returns {*|null} fragment - The best matching fragment + */ + function findFragmentByPDT(fragments, PDTValue, maxFragLookUpTolerance) { + if (PDTValue === null || !Array.isArray(fragments) || !fragments.length || !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(PDTValue)) { + return null; + } // if less than start + var startPDT = fragments[0].programDateTime; + if (PDTValue < (startPDT || 0)) { + return null; + } -/** - * Returns first fragment whose endPdt value exceeds the given PDT. - * @param {Array} fragments - The array of candidate fragments - * @param {number|null} [PDTValue = null] - The PDT value which must be exceeded - * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start/end can be within in order to be considered contiguous - * @returns {*|null} fragment - The best matching fragment - */ -function findFragmentByPDT(fragments, PDTValue, maxFragLookUpTolerance) { - if (PDTValue === null || !Array.isArray(fragments) || !fragments.length || !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(PDTValue)) { - return null; - } // if less than start + var endPDT = fragments[fragments.length - 1].endProgramDateTime; + if (PDTValue >= (endPDT || 0)) { + return null; + } - var startPDT = fragments[0].programDateTime; + maxFragLookUpTolerance = maxFragLookUpTolerance || 0; - if (PDTValue < (startPDT || 0)) { - return null; - } + for (var seg = 0; seg < fragments.length; ++seg) { + var frag = fragments[seg]; - var endPDT = fragments[fragments.length - 1].endProgramDateTime; + if (pdtWithinToleranceTest(PDTValue, maxFragLookUpTolerance, frag)) { + return frag; + } + } - if (PDTValue >= (endPDT || 0)) { - return null; - } + return null; + } + /** + * Finds a fragment based on the SN of the previous fragment; or based on the needs of the current buffer. + * This method compensates for small buffer gaps by applying a tolerance to the start of any candidate fragment, thus + * breaking any traps which would cause the same fragment to be continuously selected within a small range. + * @param {*} fragPrevious - The last frag successfully appended + * @param {Array} fragments - The array of candidate fragments + * @param {number} [bufferEnd = 0] - The end of the contiguous buffered range the playhead is currently within + * @param {number} maxFragLookUpTolerance - The amount of time that a fragment's start/end can be within in order to be considered contiguous + * @returns {*} foundFrag - The best matching fragment + */ - maxFragLookUpTolerance = maxFragLookUpTolerance || 0; + function findFragmentByPTS(fragPrevious, fragments, bufferEnd, maxFragLookUpTolerance) { + if (bufferEnd === void 0) { + bufferEnd = 0; + } - for (var seg = 0; seg < fragments.length; ++seg) { - var frag = fragments[seg]; + if (maxFragLookUpTolerance === void 0) { + maxFragLookUpTolerance = 0; + } - if (pdtWithinToleranceTest(PDTValue, maxFragLookUpTolerance, frag)) { - return frag; - } - } + var fragNext = null; - return null; -} -/** - * Finds a fragment based on the SN of the previous fragment; or based on the needs of the current buffer. - * This method compensates for small buffer gaps by applying a tolerance to the start of any candidate fragment, thus - * breaking any traps which would cause the same fragment to be continuously selected within a small range. - * @param {*} fragPrevious - The last frag successfully appended - * @param {Array} fragments - The array of candidate fragments - * @param {number} [bufferEnd = 0] - The end of the contiguous buffered range the playhead is currently within - * @param {number} maxFragLookUpTolerance - The amount of time that a fragment's start/end can be within in order to be considered contiguous - * @returns {*} foundFrag - The best matching fragment - */ + if (fragPrevious) { + fragNext = fragments[fragPrevious.sn - fragments[0].sn + 1] || null; + } else if (bufferEnd === 0 && fragments[0].start === 0) { + fragNext = fragments[0]; + } // Prefer the next fragment if it's within tolerance -function findFragmentByPTS(fragPrevious, fragments, bufferEnd, maxFragLookUpTolerance) { - if (bufferEnd === void 0) { - bufferEnd = 0; - } + if (fragNext && fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext) === 0) { + return fragNext; + } // We might be seeking past the tolerance so find the best match - if (maxFragLookUpTolerance === void 0) { - maxFragLookUpTolerance = 0; - } + var foundFragment = _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments, fragmentWithinToleranceTest.bind(null, bufferEnd, maxFragLookUpTolerance)); - var fragNext = null; + if (foundFragment) { + return foundFragment; + } // If no match was found return the next fragment after fragPrevious, or null - if (fragPrevious) { - fragNext = fragments[fragPrevious.sn - fragments[0].sn + 1] || null; - } else if (bufferEnd === 0 && fragments[0].start === 0) { - fragNext = fragments[0]; - } // Prefer the next fragment if it's within tolerance + return fragNext; + } + /** + * The test function used by the findFragmentBySn's BinarySearch to look for the best match to the current buffer conditions. + * @param {*} candidate - The fragment to test + * @param {number} [bufferEnd = 0] - The end of the current buffered range the playhead is currently within + * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous + * @returns {number} - 0 if it matches, 1 if too low, -1 if too high + */ + function fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, candidate) { + if (bufferEnd === void 0) { + bufferEnd = 0; + } - if (fragNext && fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext) === 0) { - return fragNext; - } // We might be seeking past the tolerance so find the best match + if (maxFragLookUpTolerance === void 0) { + maxFragLookUpTolerance = 0; + } + // offset should be within fragment boundary - config.maxFragLookUpTolerance + // this is to cope with situations like + // bufferEnd = 9.991 + // frag[Ø] : [0,10] + // frag[1] : [10,20] + // bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here + // frag start frag start+duration + // |-----------------------------| + // <---> <---> + // ...--------><-----------------------------><---------.... + // previous frag matching fragment next frag + // return -1 return 0 return 1 + // logger.log(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`); + // Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments + var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)); - var foundFragment = _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments, fragmentWithinToleranceTest.bind(null, bufferEnd, maxFragLookUpTolerance)); + if (candidate.start + candidate.duration - candidateLookupTolerance <= bufferEnd) { + return 1; + } else if (candidate.start - candidateLookupTolerance > bufferEnd && candidate.start) { + // if maxFragLookUpTolerance will have negative value then don't return -1 for first element + return -1; + } - if (foundFragment) { - return foundFragment; - } // If no match was found return the next fragment after fragPrevious, or null + return 0; + } + /** + * The test function used by the findFragmentByPdt's BinarySearch to look for the best match to the current buffer conditions. + * This function tests the candidate's program date time values, as represented in Unix time + * @param {*} candidate - The fragment to test + * @param {number} [pdtBufferEnd = 0] - The Unix time representing the end of the current buffered range + * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous + * @returns {boolean} True if contiguous, false otherwise + */ + function pdtWithinToleranceTest(pdtBufferEnd, maxFragLookUpTolerance, candidate) { + var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)) * 1000; // endProgramDateTime can be null, default to zero - return fragNext; -} -/** - * The test function used by the findFragmentBySn's BinarySearch to look for the best match to the current buffer conditions. - * @param {*} candidate - The fragment to test - * @param {number} [bufferEnd = 0] - The end of the current buffered range the playhead is currently within - * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous - * @returns {number} - 0 if it matches, 1 if too low, -1 if too high - */ + var endProgramDateTime = candidate.endProgramDateTime || 0; + return endProgramDateTime - candidateLookupTolerance > pdtBufferEnd; + } + function findFragWithCC(fragments, cc) { + return _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments, function (candidate) { + if (candidate.cc < cc) { + return 1; + } else if (candidate.cc > cc) { + return -1; + } else { + return 0; + } + }); + } -function fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, candidate) { - if (bufferEnd === void 0) { - bufferEnd = 0; - } + /***/ + }, - if (maxFragLookUpTolerance === void 0) { - maxFragLookUpTolerance = 0; - } - - // offset should be within fragment boundary - config.maxFragLookUpTolerance - // this is to cope with situations like - // bufferEnd = 9.991 - // frag[Ø] : [0,10] - // frag[1] : [10,20] - // bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here - // frag start frag start+duration - // |-----------------------------| - // <---> <---> - // ...--------><-----------------------------><---------.... - // previous frag matching fragment next frag - // return -1 return 0 return 1 - // logger.log(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`); - // Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments - var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)); - - if (candidate.start + candidate.duration - candidateLookupTolerance <= bufferEnd) { - return 1; - } else if (candidate.start - candidateLookupTolerance > bufferEnd && candidate.start) { - // if maxFragLookUpTolerance will have negative value then don't return -1 for first element - return -1; - } - - return 0; -} -/** - * The test function used by the findFragmentByPdt's BinarySearch to look for the best match to the current buffer conditions. - * This function tests the candidate's program date time values, as represented in Unix time - * @param {*} candidate - The fragment to test - * @param {number} [pdtBufferEnd = 0] - The Unix time representing the end of the current buffered range - * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous - * @returns {boolean} True if contiguous, false otherwise - */ - -function pdtWithinToleranceTest(pdtBufferEnd, maxFragLookUpTolerance, candidate) { - var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)) * 1000; // endProgramDateTime can be null, default to zero - - var endProgramDateTime = candidate.endProgramDateTime || 0; - return endProgramDateTime - candidateLookupTolerance > pdtBufferEnd; -} -function findFragWithCC(fragments, cc) { - return _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments, function (candidate) { - if (candidate.cc < cc) { - return 1; - } else if (candidate.cc > cc) { - return -1; - } else { - return 0; - } - }); -} - -/***/ }), - -/***/ "./src/controller/fragment-tracker.ts": -/*!********************************************!*\ + /***/ "./src/controller/fragment-tracker.ts": + /*!********************************************!*\ !*** ./src/controller/fragment-tracker.ts ***! \********************************************/ -/*! exports provided: FragmentState, FragmentTracker */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: FragmentState, FragmentTracker */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FragmentState", function () { + return FragmentState; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FragmentTracker", function () { + return FragmentTracker; + }); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FragmentState", function() { return FragmentState; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FragmentTracker", function() { return FragmentTracker; }); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + var FragmentState; + (function (FragmentState) { + FragmentState["NOT_LOADED"] = "NOT_LOADED"; + FragmentState["BACKTRACKED"] = "BACKTRACKED"; + FragmentState["APPENDING"] = "APPENDING"; + FragmentState["PARTIAL"] = "PARTIAL"; + FragmentState["OK"] = "OK"; + })(FragmentState || (FragmentState = {})); -var FragmentState; + var FragmentTracker = /*#__PURE__*/ (function () { + function FragmentTracker(CiderHls) { + this.activeFragment = null; + this.activeParts = null; + this.fragments = Object.create(null); + this.timeRanges = Object.create(null); + this.bufferPadding = 0.2; + this.CiderHls = void 0; + this.CiderHls = CiderHls; -(function (FragmentState) { - FragmentState["NOT_LOADED"] = "NOT_LOADED"; - FragmentState["BACKTRACKED"] = "BACKTRACKED"; - FragmentState["APPENDING"] = "APPENDING"; - FragmentState["PARTIAL"] = "PARTIAL"; - FragmentState["OK"] = "OK"; -})(FragmentState || (FragmentState = {})); + this._registerListeners(); + } -var FragmentTracker = /*#__PURE__*/function () { - function FragmentTracker(CiderHls) { - this.activeFragment = null; - this.activeParts = null; - this.fragments = Object.create(null); - this.timeRanges = Object.create(null); - this.bufferPadding = 0.2; - this.CiderHls = void 0; - this.CiderHls = CiderHls; + var _proto = FragmentTracker.prototype; - this._registerListeners(); - } + _proto._registerListeners = function _registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_APPENDED, this.onBufferAppended, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_LOADED, this.onFragLoaded, this); + }; - var _proto = FragmentTracker.prototype; + _proto._unregisterListeners = function _unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_APPENDED, this.onBufferAppended, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_LOADED, this.onFragLoaded, this); + }; - _proto._registerListeners = function _registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_APPENDED, this.onBufferAppended, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_LOADED, this.onFragLoaded, this); - }; + _proto.destroy = function destroy() { + this._unregisterListeners(); // @ts-ignore - _proto._unregisterListeners = function _unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_APPENDED, this.onBufferAppended, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_LOADED, this.onFragLoaded, this); - }; + this.fragments = this.timeRanges = null; + }; + /** + * Return a Fragment with an appended range that matches the position and levelType. + * If not found any Fragment, return null + */ - _proto.destroy = function destroy() { - this._unregisterListeners(); // @ts-ignore + _proto.getAppendedFrag = function getAppendedFrag(position, levelType) { + if (levelType === _types_loader__WEBPACK_IMPORTED_MODULE_1__["PlaylistLevelType"].MAIN) { + var activeFragment = this.activeFragment, + activeParts = this.activeParts; + if (!activeFragment) { + return null; + } - this.fragments = this.timeRanges = null; - } - /** - * Return a Fragment with an appended range that matches the position and levelType. - * If not found any Fragment, return null - */ - ; + if (activeParts) { + for (var i = activeParts.length; i--; ) { + var activePart = activeParts[i]; + var appendedPTS = activePart ? activePart.end : activeFragment.appendedPTS; - _proto.getAppendedFrag = function getAppendedFrag(position, levelType) { - if (levelType === _types_loader__WEBPACK_IMPORTED_MODULE_1__["PlaylistLevelType"].MAIN) { - var activeFragment = this.activeFragment, - activeParts = this.activeParts; + if (activePart.start <= position && appendedPTS !== undefined && position <= appendedPTS) { + // 9 is a magic number. remove parts from lookup after a match but keep some short seeks back. + if (i > 9) { + this.activeParts = activeParts.slice(i - 9); + } - if (!activeFragment) { - return null; - } + return activePart; + } + } + } else if (activeFragment.start <= position && activeFragment.appendedPTS !== undefined && position <= activeFragment.appendedPTS) { + return activeFragment; + } + } - if (activeParts) { - for (var i = activeParts.length; i--;) { - var activePart = activeParts[i]; - var appendedPTS = activePart ? activePart.end : activeFragment.appendedPTS; + return this.getBufferedFrag(position, levelType); + }; + /** + * Return a buffered Fragment that matches the position and levelType. + * A buffered Fragment is one whose loading, parsing and appending is done (completed or "partial" meaning aborted). + * If not found any Fragment, return null + */ - if (activePart.start <= position && appendedPTS !== undefined && position <= appendedPTS) { - // 9 is a magic number. remove parts from lookup after a match but keep some short seeks back. - if (i > 9) { - this.activeParts = activeParts.slice(i - 9); + _proto.getBufferedFrag = function getBufferedFrag(position, levelType) { + var fragments = this.fragments; + var keys = Object.keys(fragments); + + for (var i = keys.length; i--; ) { + var fragmentEntity = fragments[keys[i]]; + + if ((fragmentEntity === null || fragmentEntity === void 0 ? void 0 : fragmentEntity.body.type) === levelType && fragmentEntity.buffered) { + var frag = fragmentEntity.body; + + if (frag.start <= position && position <= frag.end) { + return frag; + } + } + } + + return null; + }; + /** + * Partial fragments effected by coded frame eviction will be removed + * The browser will unload parts of the buffer to free up memory for new buffer data + * Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable) + */ + + _proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange, playlistType) { + var _this = this; + + // Check if any flagged fragments have been unloaded + Object.keys(this.fragments).forEach(function (key) { + var fragmentEntity = _this.fragments[key]; + + if (!fragmentEntity) { + return; + } + + if (!fragmentEntity.buffered) { + if (fragmentEntity.body.type === playlistType) { + _this.removeFragment(fragmentEntity.body); + } + + return; + } + + var esData = fragmentEntity.range[elementaryStream]; + + if (!esData) { + return; + } + + esData.time.some(function (time) { + var isNotBuffered = !_this.isTimeBuffered(time.startPTS, time.endPTS, timeRange); + + if (isNotBuffered) { + // Unregister partial fragment as it needs to load again to be reused + _this.removeFragment(fragmentEntity.body); + } + + return isNotBuffered; + }); + }); + }; + /** + * Checks if the fragment passed in is loaded in the buffer properly + * Partially loaded fragments will be registered as a partial fragment + */ + + _proto.detectPartialFragments = function detectPartialFragments(data) { + var _this2 = this; + + var timeRanges = this.timeRanges; + var frag = data.frag, + part = data.part; + + if (!timeRanges || frag.sn === "initSegment") { + return; + } + + var fragKey = getFragmentKey(frag); + var fragmentEntity = this.fragments[fragKey]; + + if (!fragmentEntity) { + return; + } + + Object.keys(timeRanges).forEach(function (elementaryStream) { + var streamInfo = frag.elementaryStreams[elementaryStream]; + + if (!streamInfo) { + return; + } + + var timeRange = timeRanges[elementaryStream]; + var partial = part !== null || streamInfo.partial === true; + fragmentEntity.range[elementaryStream] = _this2.getBufferedTimes(frag, part, partial, timeRange); + }); + fragmentEntity.backtrack = fragmentEntity.loaded = null; + + if (Object.keys(fragmentEntity.range).length) { + fragmentEntity.buffered = true; + } else { + // remove fragment if nothing was appended + this.removeFragment(fragmentEntity.body); + } + }; + + _proto.fragBuffered = function fragBuffered(frag) { + var fragKey = getFragmentKey(frag); + var fragmentEntity = this.fragments[fragKey]; + + if (fragmentEntity) { + fragmentEntity.backtrack = fragmentEntity.loaded = null; + fragmentEntity.buffered = true; + } + }; + + _proto.getBufferedTimes = function getBufferedTimes(fragment, part, partial, timeRange) { + var buffered = { + time: [], + partial: partial, + }; + var startPTS = part ? part.start : fragment.start; + var endPTS = part ? part.end : fragment.end; + var minEndPTS = fragment.minEndPTS || endPTS; + var maxStartPTS = fragment.maxStartPTS || startPTS; + + for (var i = 0; i < timeRange.length; i++) { + var startTime = timeRange.start(i) - this.bufferPadding; + var endTime = timeRange.end(i) + this.bufferPadding; + + if (maxStartPTS >= startTime && minEndPTS <= endTime) { + // Fragment is entirely contained in buffer + // No need to check the other timeRange times since it's completely playable + buffered.time.push({ + startPTS: Math.max(startPTS, timeRange.start(i)), + endPTS: Math.min(endPTS, timeRange.end(i)), + }); + break; + } else if (startPTS < endTime && endPTS > startTime) { + buffered.partial = true; // Check for intersection with buffer + // Get playable sections of the fragment + + buffered.time.push({ + startPTS: Math.max(startPTS, timeRange.start(i)), + endPTS: Math.min(endPTS, timeRange.end(i)), + }); + } else if (endPTS <= startTime) { + // No need to check the rest of the timeRange as it is in order + break; + } + } + + return buffered; + }; + /** + * Gets the partial fragment for a certain time + */ + + _proto.getPartialFragment = function getPartialFragment(time) { + var bestFragment = null; + var timePadding; + var startTime; + var endTime; + var bestOverlap = 0; + var bufferPadding = this.bufferPadding, + fragments = this.fragments; + Object.keys(fragments).forEach(function (key) { + var fragmentEntity = fragments[key]; + + if (!fragmentEntity) { + return; + } + + if (isPartial(fragmentEntity)) { + startTime = fragmentEntity.body.start - bufferPadding; + endTime = fragmentEntity.body.end + bufferPadding; + + if (time >= startTime && time <= endTime) { + // Use the fragment that has the most padding from start and end time + timePadding = Math.min(time - startTime, endTime - time); + + if (bestOverlap <= timePadding) { + bestFragment = fragmentEntity.body; + bestOverlap = timePadding; + } + } + } + }); + return bestFragment; + }; + + _proto.getState = function getState(fragment) { + var fragKey = getFragmentKey(fragment); + var fragmentEntity = this.fragments[fragKey]; + + if (fragmentEntity) { + if (!fragmentEntity.buffered) { + if (fragmentEntity.backtrack) { + return FragmentState.BACKTRACKED; + } + + return FragmentState.APPENDING; + } else if (isPartial(fragmentEntity)) { + return FragmentState.PARTIAL; + } else { + return FragmentState.OK; + } + } + + return FragmentState.NOT_LOADED; + }; + + _proto.backtrack = function backtrack(frag, data) { + var fragKey = getFragmentKey(frag); + var fragmentEntity = this.fragments[fragKey]; + + if (!fragmentEntity || fragmentEntity.backtrack) { + return null; + } + + var backtrack = (fragmentEntity.backtrack = data ? data : fragmentEntity.loaded); + fragmentEntity.loaded = null; + return backtrack; + }; + + _proto.getBacktrackData = function getBacktrackData(fragment) { + var fragKey = getFragmentKey(fragment); + var fragmentEntity = this.fragments[fragKey]; + + if (fragmentEntity) { + var _backtrack$payload; + + var backtrack = fragmentEntity.backtrack; // If data was already sent to Worker it is detached no longer available + + if (backtrack !== null && backtrack !== void 0 && (_backtrack$payload = backtrack.payload) !== null && _backtrack$payload !== void 0 && _backtrack$payload.byteLength) { + return backtrack; + } else { + this.removeFragment(fragment); + } + } + + return null; + }; + + _proto.isTimeBuffered = function isTimeBuffered(startPTS, endPTS, timeRange) { + var startTime; + var endTime; + + for (var i = 0; i < timeRange.length; i++) { + startTime = timeRange.start(i) - this.bufferPadding; + endTime = timeRange.end(i) + this.bufferPadding; + + if (startPTS >= startTime && endPTS <= endTime) { + return true; + } + + if (endPTS <= startTime) { + // No need to check the rest of the timeRange as it is in order + return false; + } + } + + return false; + }; + + _proto.onFragLoaded = function onFragLoaded(event, data) { + var frag = data.frag, + part = data.part; // don't track initsegment (for which sn is not a number) + // don't track frags used for bitrateTest, they're irrelevant. + // don't track parts for memory efficiency + + if (frag.sn === "initSegment" || frag.bitrateTest || part) { + return; + } + + var fragKey = getFragmentKey(frag); + this.fragments[fragKey] = { + body: frag, + loaded: data, + backtrack: null, + buffered: false, + range: Object.create(null), + }; + }; + + _proto.onBufferAppended = function onBufferAppended(event, data) { + var _this3 = this; + + var frag = data.frag, + part = data.part, + timeRanges = data.timeRanges; + + if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_1__["PlaylistLevelType"].MAIN) { + this.activeFragment = frag; + + if (part) { + var activeParts = this.activeParts; + + if (!activeParts) { + this.activeParts = activeParts = []; + } + + activeParts.push(part); + } else { + this.activeParts = null; + } + } // Store the latest timeRanges loaded in the buffer + + this.timeRanges = timeRanges; + Object.keys(timeRanges).forEach(function (elementaryStream) { + var timeRange = timeRanges[elementaryStream]; + + _this3.detectEvictedFragments(elementaryStream, timeRange); + + if (!part) { + for (var i = 0; i < timeRange.length; i++) { + frag.appendedPTS = Math.max(timeRange.end(i), frag.appendedPTS || 0); + } + } + }); + }; + + _proto.onFragBuffered = function onFragBuffered(event, data) { + this.detectPartialFragments(data); + }; + + _proto.hasFragment = function hasFragment(fragment) { + var fragKey = getFragmentKey(fragment); + return !!this.fragments[fragKey]; + }; + + _proto.removeFragmentsInRange = function removeFragmentsInRange(start, end, playlistType) { + var _this4 = this; + + Object.keys(this.fragments).forEach(function (key) { + var fragmentEntity = _this4.fragments[key]; + + if (!fragmentEntity) { + return; + } + + if (fragmentEntity.buffered) { + var frag = fragmentEntity.body; + + if (frag.type === playlistType && frag.start < end && frag.end > start) { + _this4.removeFragment(frag); + } + } + }); + }; + + _proto.removeFragment = function removeFragment(fragment) { + var fragKey = getFragmentKey(fragment); + fragment.stats.loaded = 0; + fragment.clearElementaryStreamInfo(); + delete this.fragments[fragKey]; + }; + + _proto.removeAllFragments = function removeAllFragments() { + this.fragments = Object.create(null); + this.activeFragment = null; + this.activeParts = null; + }; + + return FragmentTracker; + })(); + + function isPartial(fragmentEntity) { + var _fragmentEntity$range, _fragmentEntity$range2; + + return ( + fragmentEntity.buffered && + (((_fragmentEntity$range = fragmentEntity.range.video) === null || _fragmentEntity$range === void 0 ? void 0 : _fragmentEntity$range.partial) || + ((_fragmentEntity$range2 = fragmentEntity.range.audio) === null || _fragmentEntity$range2 === void 0 ? void 0 : _fragmentEntity$range2.partial)) + ); } - return activePart; - } - } - } else if (activeFragment.start <= position && activeFragment.appendedPTS !== undefined && position <= activeFragment.appendedPTS) { - return activeFragment; - } - } + function getFragmentKey(fragment) { + return fragment.type + "_" + fragment.level + "_" + fragment.urlId + "_" + fragment.sn; + } - return this.getBufferedFrag(position, levelType); - } - /** - * Return a buffered Fragment that matches the position and levelType. - * A buffered Fragment is one whose loading, parsing and appending is done (completed or "partial" meaning aborted). - * If not found any Fragment, return null - */ - ; + /***/ + }, - _proto.getBufferedFrag = function getBufferedFrag(position, levelType) { - var fragments = this.fragments; - var keys = Object.keys(fragments); - - for (var i = keys.length; i--;) { - var fragmentEntity = fragments[keys[i]]; - - if ((fragmentEntity === null || fragmentEntity === void 0 ? void 0 : fragmentEntity.body.type) === levelType && fragmentEntity.buffered) { - var frag = fragmentEntity.body; - - if (frag.start <= position && position <= frag.end) { - return frag; - } - } - } - - return null; - } - /** - * Partial fragments effected by coded frame eviction will be removed - * The browser will unload parts of the buffer to free up memory for new buffer data - * Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable) - */ - ; - - _proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange, playlistType) { - var _this = this; - - // Check if any flagged fragments have been unloaded - Object.keys(this.fragments).forEach(function (key) { - var fragmentEntity = _this.fragments[key]; - - if (!fragmentEntity) { - return; - } - - if (!fragmentEntity.buffered) { - if (fragmentEntity.body.type === playlistType) { - _this.removeFragment(fragmentEntity.body); - } - - return; - } - - var esData = fragmentEntity.range[elementaryStream]; - - if (!esData) { - return; - } - - esData.time.some(function (time) { - var isNotBuffered = !_this.isTimeBuffered(time.startPTS, time.endPTS, timeRange); - - if (isNotBuffered) { - // Unregister partial fragment as it needs to load again to be reused - _this.removeFragment(fragmentEntity.body); - } - - return isNotBuffered; - }); - }); - } - /** - * Checks if the fragment passed in is loaded in the buffer properly - * Partially loaded fragments will be registered as a partial fragment - */ - ; - - _proto.detectPartialFragments = function detectPartialFragments(data) { - var _this2 = this; - - var timeRanges = this.timeRanges; - var frag = data.frag, - part = data.part; - - if (!timeRanges || frag.sn === 'initSegment') { - return; - } - - var fragKey = getFragmentKey(frag); - var fragmentEntity = this.fragments[fragKey]; - - if (!fragmentEntity) { - return; - } - - Object.keys(timeRanges).forEach(function (elementaryStream) { - var streamInfo = frag.elementaryStreams[elementaryStream]; - - if (!streamInfo) { - return; - } - - var timeRange = timeRanges[elementaryStream]; - var partial = part !== null || streamInfo.partial === true; - fragmentEntity.range[elementaryStream] = _this2.getBufferedTimes(frag, part, partial, timeRange); - }); - fragmentEntity.backtrack = fragmentEntity.loaded = null; - - if (Object.keys(fragmentEntity.range).length) { - fragmentEntity.buffered = true; - } else { - // remove fragment if nothing was appended - this.removeFragment(fragmentEntity.body); - } - }; - - _proto.fragBuffered = function fragBuffered(frag) { - var fragKey = getFragmentKey(frag); - var fragmentEntity = this.fragments[fragKey]; - - if (fragmentEntity) { - fragmentEntity.backtrack = fragmentEntity.loaded = null; - fragmentEntity.buffered = true; - } - }; - - _proto.getBufferedTimes = function getBufferedTimes(fragment, part, partial, timeRange) { - var buffered = { - time: [], - partial: partial - }; - var startPTS = part ? part.start : fragment.start; - var endPTS = part ? part.end : fragment.end; - var minEndPTS = fragment.minEndPTS || endPTS; - var maxStartPTS = fragment.maxStartPTS || startPTS; - - for (var i = 0; i < timeRange.length; i++) { - var startTime = timeRange.start(i) - this.bufferPadding; - var endTime = timeRange.end(i) + this.bufferPadding; - - if (maxStartPTS >= startTime && minEndPTS <= endTime) { - // Fragment is entirely contained in buffer - // No need to check the other timeRange times since it's completely playable - buffered.time.push({ - startPTS: Math.max(startPTS, timeRange.start(i)), - endPTS: Math.min(endPTS, timeRange.end(i)) - }); - break; - } else if (startPTS < endTime && endPTS > startTime) { - buffered.partial = true; // Check for intersection with buffer - // Get playable sections of the fragment - - buffered.time.push({ - startPTS: Math.max(startPTS, timeRange.start(i)), - endPTS: Math.min(endPTS, timeRange.end(i)) - }); - } else if (endPTS <= startTime) { - // No need to check the rest of the timeRange as it is in order - break; - } - } - - return buffered; - } - /** - * Gets the partial fragment for a certain time - */ - ; - - _proto.getPartialFragment = function getPartialFragment(time) { - var bestFragment = null; - var timePadding; - var startTime; - var endTime; - var bestOverlap = 0; - var bufferPadding = this.bufferPadding, - fragments = this.fragments; - Object.keys(fragments).forEach(function (key) { - var fragmentEntity = fragments[key]; - - if (!fragmentEntity) { - return; - } - - if (isPartial(fragmentEntity)) { - startTime = fragmentEntity.body.start - bufferPadding; - endTime = fragmentEntity.body.end + bufferPadding; - - if (time >= startTime && time <= endTime) { - // Use the fragment that has the most padding from start and end time - timePadding = Math.min(time - startTime, endTime - time); - - if (bestOverlap <= timePadding) { - bestFragment = fragmentEntity.body; - bestOverlap = timePadding; - } - } - } - }); - return bestFragment; - }; - - _proto.getState = function getState(fragment) { - var fragKey = getFragmentKey(fragment); - var fragmentEntity = this.fragments[fragKey]; - - if (fragmentEntity) { - if (!fragmentEntity.buffered) { - if (fragmentEntity.backtrack) { - return FragmentState.BACKTRACKED; - } - - return FragmentState.APPENDING; - } else if (isPartial(fragmentEntity)) { - return FragmentState.PARTIAL; - } else { - return FragmentState.OK; - } - } - - return FragmentState.NOT_LOADED; - }; - - _proto.backtrack = function backtrack(frag, data) { - var fragKey = getFragmentKey(frag); - var fragmentEntity = this.fragments[fragKey]; - - if (!fragmentEntity || fragmentEntity.backtrack) { - return null; - } - - var backtrack = fragmentEntity.backtrack = data ? data : fragmentEntity.loaded; - fragmentEntity.loaded = null; - return backtrack; - }; - - _proto.getBacktrackData = function getBacktrackData(fragment) { - var fragKey = getFragmentKey(fragment); - var fragmentEntity = this.fragments[fragKey]; - - if (fragmentEntity) { - var _backtrack$payload; - - var backtrack = fragmentEntity.backtrack; // If data was already sent to Worker it is detached no longer available - - if (backtrack !== null && backtrack !== void 0 && (_backtrack$payload = backtrack.payload) !== null && _backtrack$payload !== void 0 && _backtrack$payload.byteLength) { - return backtrack; - } else { - this.removeFragment(fragment); - } - } - - return null; - }; - - _proto.isTimeBuffered = function isTimeBuffered(startPTS, endPTS, timeRange) { - var startTime; - var endTime; - - for (var i = 0; i < timeRange.length; i++) { - startTime = timeRange.start(i) - this.bufferPadding; - endTime = timeRange.end(i) + this.bufferPadding; - - if (startPTS >= startTime && endPTS <= endTime) { - return true; - } - - if (endPTS <= startTime) { - // No need to check the rest of the timeRange as it is in order - return false; - } - } - - return false; - }; - - _proto.onFragLoaded = function onFragLoaded(event, data) { - var frag = data.frag, - part = data.part; // don't track initsegment (for which sn is not a number) - // don't track frags used for bitrateTest, they're irrelevant. - // don't track parts for memory efficiency - - if (frag.sn === 'initSegment' || frag.bitrateTest || part) { - return; - } - - var fragKey = getFragmentKey(frag); - this.fragments[fragKey] = { - body: frag, - loaded: data, - backtrack: null, - buffered: false, - range: Object.create(null) - }; - }; - - _proto.onBufferAppended = function onBufferAppended(event, data) { - var _this3 = this; - - var frag = data.frag, - part = data.part, - timeRanges = data.timeRanges; - - if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_1__["PlaylistLevelType"].MAIN) { - this.activeFragment = frag; - - if (part) { - var activeParts = this.activeParts; - - if (!activeParts) { - this.activeParts = activeParts = []; - } - - activeParts.push(part); - } else { - this.activeParts = null; - } - } // Store the latest timeRanges loaded in the buffer - - - this.timeRanges = timeRanges; - Object.keys(timeRanges).forEach(function (elementaryStream) { - var timeRange = timeRanges[elementaryStream]; - - _this3.detectEvictedFragments(elementaryStream, timeRange); - - if (!part) { - for (var i = 0; i < timeRange.length; i++) { - frag.appendedPTS = Math.max(timeRange.end(i), frag.appendedPTS || 0); - } - } - }); - }; - - _proto.onFragBuffered = function onFragBuffered(event, data) { - this.detectPartialFragments(data); - }; - - _proto.hasFragment = function hasFragment(fragment) { - var fragKey = getFragmentKey(fragment); - return !!this.fragments[fragKey]; - }; - - _proto.removeFragmentsInRange = function removeFragmentsInRange(start, end, playlistType) { - var _this4 = this; - - Object.keys(this.fragments).forEach(function (key) { - var fragmentEntity = _this4.fragments[key]; - - if (!fragmentEntity) { - return; - } - - if (fragmentEntity.buffered) { - var frag = fragmentEntity.body; - - if (frag.type === playlistType && frag.start < end && frag.end > start) { - _this4.removeFragment(frag); - } - } - }); - }; - - _proto.removeFragment = function removeFragment(fragment) { - var fragKey = getFragmentKey(fragment); - fragment.stats.loaded = 0; - fragment.clearElementaryStreamInfo(); - delete this.fragments[fragKey]; - }; - - _proto.removeAllFragments = function removeAllFragments() { - this.fragments = Object.create(null); - this.activeFragment = null; - this.activeParts = null; - }; - - return FragmentTracker; -}(); - -function isPartial(fragmentEntity) { - var _fragmentEntity$range, _fragmentEntity$range2; - - return fragmentEntity.buffered && (((_fragmentEntity$range = fragmentEntity.range.video) === null || _fragmentEntity$range === void 0 ? void 0 : _fragmentEntity$range.partial) || ((_fragmentEntity$range2 = fragmentEntity.range.audio) === null || _fragmentEntity$range2 === void 0 ? void 0 : _fragmentEntity$range2.partial)); -} - -function getFragmentKey(fragment) { - return fragment.type + "_" + fragment.level + "_" + fragment.urlId + "_" + fragment.sn; -} - -/***/ }), - -/***/ "./src/controller/gap-controller.ts": -/*!******************************************!*\ + /***/ "./src/controller/gap-controller.ts": + /*!******************************************!*\ !*** ./src/controller/gap-controller.ts ***! \******************************************/ -/*! exports provided: STALL_MINIMUM_DURATION_MS, MAX_START_GAP_JUMP, SKIP_BUFFER_HOLE_STEP_SECONDS, SKIP_BUFFER_RANGE_START, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: STALL_MINIMUM_DURATION_MS, MAX_START_GAP_JUMP, SKIP_BUFFER_HOLE_STEP_SECONDS, SKIP_BUFFER_RANGE_START, default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "STALL_MINIMUM_DURATION_MS", function () { + return STALL_MINIMUM_DURATION_MS; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MAX_START_GAP_JUMP", function () { + return MAX_START_GAP_JUMP; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SKIP_BUFFER_HOLE_STEP_SECONDS", function () { + return SKIP_BUFFER_HOLE_STEP_SECONDS; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SKIP_BUFFER_RANGE_START", function () { + return SKIP_BUFFER_RANGE_START; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return GapController; + }); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "STALL_MINIMUM_DURATION_MS", function() { return STALL_MINIMUM_DURATION_MS; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MAX_START_GAP_JUMP", function() { return MAX_START_GAP_JUMP; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SKIP_BUFFER_HOLE_STEP_SECONDS", function() { return SKIP_BUFFER_HOLE_STEP_SECONDS; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SKIP_BUFFER_RANGE_START", function() { return SKIP_BUFFER_RANGE_START; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return GapController; }); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + var STALL_MINIMUM_DURATION_MS = 250; + var MAX_START_GAP_JUMP = 2.0; + var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1; + var SKIP_BUFFER_RANGE_START = 0.05; + var GapController = /*#__PURE__*/ (function () { + function GapController(config, media, fragmentTracker, CiderHls) { + this.config = void 0; + this.media = void 0; + this.fragmentTracker = void 0; + this.CiderHls = void 0; + this.nudgeRetry = 0; + this.stallReported = false; + this.stalled = null; + this.moved = false; + this.seeking = false; + this.config = config; + this.media = media; + this.fragmentTracker = fragmentTracker; + this.CiderHls = CiderHls; + } + var _proto = GapController.prototype; + _proto.destroy = function destroy() { + // @ts-ignore + this.CiderHls = this.fragmentTracker = this.media = null; + }; + /** + * Checks if the playhead is stuck within a gap, and if so, attempts to free it. + * A gap is an unbuffered range between two buffered ranges (or the start and the first buffered range). + * + * @param {number} lastCurrentTime Previously read playhead position + */ -var STALL_MINIMUM_DURATION_MS = 250; -var MAX_START_GAP_JUMP = 2.0; -var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1; -var SKIP_BUFFER_RANGE_START = 0.05; + _proto.poll = function poll(lastCurrentTime) { + var config = this.config, + media = this.media, + stalled = this.stalled; + var currentTime = media.currentTime, + seeking = media.seeking; + var seeked = this.seeking && !seeking; + var beginSeek = !this.seeking && seeking; + this.seeking = seeking; // The playhead is moving, no-op -var GapController = /*#__PURE__*/function () { - function GapController(config, media, fragmentTracker, CiderHls) { - this.config = void 0; - this.media = void 0; - this.fragmentTracker = void 0; - this.CiderHls = void 0; - this.nudgeRetry = 0; - this.stallReported = false; - this.stalled = null; - this.moved = false; - this.seeking = false; - this.config = config; - this.media = media; - this.fragmentTracker = fragmentTracker; - this.CiderHls = CiderHls; - } + if (currentTime !== lastCurrentTime) { + this.moved = true; - var _proto = GapController.prototype; + if (stalled !== null) { + // The playhead is now moving, but was previously stalled + if (this.stallReported) { + var _stalledDuration = self.performance.now() - stalled; - _proto.destroy = function destroy() { - // @ts-ignore - this.CiderHls = this.fragmentTracker = this.media = null; - } - /** - * Checks if the playhead is stuck within a gap, and if so, attempts to free it. - * A gap is an unbuffered range between two buffered ranges (or the start and the first buffered range). - * - * @param {number} lastCurrentTime Previously read playhead position - */ - ; + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms"); + this.stallReported = false; + } - _proto.poll = function poll(lastCurrentTime) { - var config = this.config, - media = this.media, - stalled = this.stalled; - var currentTime = media.currentTime, - seeking = media.seeking; - var seeked = this.seeking && !seeking; - var beginSeek = !this.seeking && seeking; - this.seeking = seeking; // The playhead is moving, no-op + this.stalled = null; + this.nudgeRetry = 0; + } - if (currentTime !== lastCurrentTime) { - this.moved = true; + return; + } // Clear stalled state when beginning or finishing seeking so that we don't report stalls coming out of a seek - if (stalled !== null) { - // The playhead is now moving, but was previously stalled - if (this.stallReported) { - var _stalledDuration = self.performance.now() - stalled; + if (beginSeek || seeked) { + this.stalled = null; + } // The playhead should not be moving - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms"); - this.stallReported = false; - } + if (media.paused || media.ended || media.playbackRate === 0 || !_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].getBuffered(media).length) { + return; + } - this.stalled = null; - this.nudgeRetry = 0; - } + var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].bufferInfo(media, currentTime, 0); + var isBuffered = bufferInfo.len > 0; + var nextStart = bufferInfo.nextStart || 0; // There is no playable buffer (seeked, waiting for buffer) - return; - } // Clear stalled state when beginning or finishing seeking so that we don't report stalls coming out of a seek + if (!isBuffered && !nextStart) { + return; + } + if (seeking) { + // Waiting for seeking in a buffered range to complete + var hasEnoughBuffer = bufferInfo.len > MAX_START_GAP_JUMP; // Next buffered range is too far ahead to jump to while still seeking - if (beginSeek || seeked) { - this.stalled = null; - } // The playhead should not be moving + var noBufferGap = !nextStart || (nextStart - currentTime > MAX_START_GAP_JUMP && !this.fragmentTracker.getPartialFragment(currentTime)); + if (hasEnoughBuffer || noBufferGap) { + return; + } // Reset moved state when seeking to a point in or before a gap - if (media.paused || media.ended || media.playbackRate === 0 || !_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].getBuffered(media).length) { - return; - } + this.moved = false; + } // Skip start gaps if we haven't played, but the last poll detected the start of a stall + // The addition poll gives the browser a chance to jump the gap for us - var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].bufferInfo(media, currentTime, 0); - var isBuffered = bufferInfo.len > 0; - var nextStart = bufferInfo.nextStart || 0; // There is no playable buffer (seeked, waiting for buffer) + if (!this.moved && this.stalled !== null) { + var _level$details; - if (!isBuffered && !nextStart) { - return; - } + // Jump start gaps within jump threshold + var startJump = Math.max(nextStart, bufferInfo.start || 0) - currentTime; // When joining a live stream with audio tracks, account for live playlist window sliding by allowing + // a larger jump over start gaps caused by the audio-stream-controller buffering a start fragment + // that begins over 1 target duration after the video start position. - if (seeking) { - // Waiting for seeking in a buffered range to complete - var hasEnoughBuffer = bufferInfo.len > MAX_START_GAP_JUMP; // Next buffered range is too far ahead to jump to while still seeking + var level = this.CiderHls.levels ? this.CiderHls.levels[this.CiderHls.currentLevel] : null; + var isLive = level === null || level === void 0 ? void 0 : (_level$details = level.details) === null || _level$details === void 0 ? void 0 : _level$details.live; + var maxStartGapJump = isLive ? level.details.targetduration * 2 : MAX_START_GAP_JUMP; - var noBufferGap = !nextStart || nextStart - currentTime > MAX_START_GAP_JUMP && !this.fragmentTracker.getPartialFragment(currentTime); + if (startJump > 0 && startJump <= maxStartGapJump) { + this._trySkipBufferHole(null); - if (hasEnoughBuffer || noBufferGap) { - return; - } // Reset moved state when seeking to a point in or before a gap + return; + } + } // Start tracking stall time + var tnow = self.performance.now(); - this.moved = false; - } // Skip start gaps if we haven't played, but the last poll detected the start of a stall - // The addition poll gives the browser a chance to jump the gap for us + if (stalled === null) { + this.stalled = tnow; + return; + } + var stalledDuration = tnow - stalled; - if (!this.moved && this.stalled !== null) { - var _level$details; + if (!seeking && stalledDuration >= STALL_MINIMUM_DURATION_MS) { + // Report stalling after trying to fix + this._reportStall(bufferInfo.len); + } - // Jump start gaps within jump threshold - var startJump = Math.max(nextStart, bufferInfo.start || 0) - currentTime; // When joining a live stream with audio tracks, account for live playlist window sliding by allowing - // a larger jump over start gaps caused by the audio-stream-controller buffering a start fragment - // that begins over 1 target duration after the video start position. + var bufferedWithHoles = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].bufferInfo(media, currentTime, config.maxBufferHole); - var level = this.CiderHls.levels ? this.CiderHls.levels[this.CiderHls.currentLevel] : null; - var isLive = level === null || level === void 0 ? void 0 : (_level$details = level.details) === null || _level$details === void 0 ? void 0 : _level$details.live; - var maxStartGapJump = isLive ? level.details.targetduration * 2 : MAX_START_GAP_JUMP; + this._tryFixBufferStall(bufferedWithHoles, stalledDuration); + }; + /** + * Detects and attempts to fix known buffer stalling issues. + * @param bufferInfo - The properties of the current buffer. + * @param stalledDurationMs - The amount of time CiderHls.js has been stalling for. + * @private + */ - if (startJump > 0 && startJump <= maxStartGapJump) { - this._trySkipBufferHole(null); + _proto._tryFixBufferStall = function _tryFixBufferStall(bufferInfo, stalledDurationMs) { + var config = this.config, + fragmentTracker = this.fragmentTracker, + media = this.media; + var currentTime = media.currentTime; + var partial = fragmentTracker.getPartialFragment(currentTime); - return; - } - } // Start tracking stall time + if (partial) { + // Try to skip over the buffer hole caused by a partial fragment + // This method isn't limited by the size of the gap between buffered ranges + var targetTime = this._trySkipBufferHole(partial); // we return here in this case, meaning + // the branch below only executes when we don't handle a partial fragment + if (targetTime) { + return; + } + } // if we haven't had to skip over a buffer hole of a partial fragment + // we may just have to "nudge" the playlist as the browser decoding/rendering engine + // needs to cross some sort of threshold covering all source-buffers content + // to start playing properly. - var tnow = self.performance.now(); + if (bufferInfo.len > config.maxBufferHole && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Trying to nudge playhead over buffer-hole"); // Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds + // We only try to jump the hole if it's under the configured size + // Reset stalled so to rearm watchdog timer - if (stalled === null) { - this.stalled = tnow; - return; - } + this.stalled = null; - var stalledDuration = tnow - stalled; + this._tryNudgeBuffer(); + } + }; + /** + * Triggers a BUFFER_STALLED_ERROR event, but only once per stall period. + * @param bufferLen - The playhead distance from the end of the current buffer segment. + * @private + */ - if (!seeking && stalledDuration >= STALL_MINIMUM_DURATION_MS) { - // Report stalling after trying to fix - this._reportStall(bufferInfo.len); - } + _proto._reportStall = function _reportStall(bufferLen) { + var CiderHls = this.CiderHls, + media = this.media, + stallReported = this.stallReported; - var bufferedWithHoles = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].bufferInfo(media, currentTime, config.maxBufferHole); + if (!stallReported) { + // Report stalled error once + this.stallReported = true; + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Playback stalling at @" + media.currentTime + " due to low buffer (buffer=" + bufferLen + ")"); + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_STALLED_ERROR, + fatal: false, + buffer: bufferLen, + }); + } + }; + /** + * Attempts to fix buffer stalls by jumping over known gaps caused by partial fragments + * @param partial - The partial fragment found at the current time (where playback is stalling). + * @private + */ - this._tryFixBufferStall(bufferedWithHoles, stalledDuration); - } - /** - * Detects and attempts to fix known buffer stalling issues. - * @param bufferInfo - The properties of the current buffer. - * @param stalledDurationMs - The amount of time CiderHls.js has been stalling for. - * @private - */ - ; + _proto._trySkipBufferHole = function _trySkipBufferHole(partial) { + var config = this.config, + CiderHls = this.CiderHls, + media = this.media; + var currentTime = media.currentTime; + var lastEndTime = 0; // Check if currentTime is between unbuffered regions of partial fragments - _proto._tryFixBufferStall = function _tryFixBufferStall(bufferInfo, stalledDurationMs) { - var config = this.config, - fragmentTracker = this.fragmentTracker, - media = this.media; - var currentTime = media.currentTime; - var partial = fragmentTracker.getPartialFragment(currentTime); + var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].getBuffered(media); - if (partial) { - // Try to skip over the buffer hole caused by a partial fragment - // This method isn't limited by the size of the gap between buffered ranges - var targetTime = this._trySkipBufferHole(partial); // we return here in this case, meaning - // the branch below only executes when we don't handle a partial fragment + for (var i = 0; i < buffered.length; i++) { + var startTime = buffered.start(i); + if (currentTime + config.maxBufferHole >= lastEndTime && currentTime < startTime) { + var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, media.currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS); + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime); + this.moved = true; + this.stalled = null; + media.currentTime = targetTime; - if (targetTime) { - return; - } - } // if we haven't had to skip over a buffer hole of a partial fragment - // we may just have to "nudge" the playlist as the browser decoding/rendering engine - // needs to cross some sort of threshold covering all source-buffers content - // to start playing properly. + if (partial) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_SEEK_OVER_HOLE, + fatal: false, + reason: "fragment loaded with buffer holes, seeking from " + currentTime + " to " + targetTime, + frag: partial, + }); + } + return targetTime; + } - if (bufferInfo.len > config.maxBufferHole && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('Trying to nudge playhead over buffer-hole'); // Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds - // We only try to jump the hole if it's under the configured size - // Reset stalled so to rearm watchdog timer + lastEndTime = buffered.end(i); + } - this.stalled = null; + return 0; + }; + /** + * Attempts to fix buffer stalls by advancing the mediaElement's current time by a small amount. + * @private + */ - this._tryNudgeBuffer(); - } - } - /** - * Triggers a BUFFER_STALLED_ERROR event, but only once per stall period. - * @param bufferLen - The playhead distance from the end of the current buffer segment. - * @private - */ - ; + _proto._tryNudgeBuffer = function _tryNudgeBuffer() { + var config = this.config, + CiderHls = this.CiderHls, + media = this.media; + var currentTime = media.currentTime; + var nudgeRetry = (this.nudgeRetry || 0) + 1; + this.nudgeRetry = nudgeRetry; - _proto._reportStall = function _reportStall(bufferLen) { - var CiderHls = this.CiderHls, - media = this.media, - stallReported = this.stallReported; + if (nudgeRetry < config.nudgeMaxRetry) { + var targetTime = currentTime + nudgeRetry * config.nudgeOffset; // playback stalled in buffered area ... let's nudge currentTime to try to overcome this - if (!stallReported) { - // Report stalled error once - this.stallReported = true; - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Playback stalling at @" + media.currentTime + " due to low buffer (buffer=" + bufferLen + ")"); - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_STALLED_ERROR, - fatal: false, - buffer: bufferLen - }); - } - } - /** - * Attempts to fix buffer stalls by jumping over known gaps caused by partial fragments - * @param partial - The partial fragment found at the current time (where playback is stalling). - * @private - */ - ; + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Nudging 'currentTime' from " + currentTime + " to " + targetTime); + media.currentTime = targetTime; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_NUDGE_ON_STALL, + fatal: false, + }); + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges"); + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_STALLED_ERROR, + fatal: true, + }); + } + }; - _proto._trySkipBufferHole = function _trySkipBufferHole(partial) { - var config = this.config, - CiderHls = this.CiderHls, - media = this.media; - var currentTime = media.currentTime; - var lastEndTime = 0; // Check if currentTime is between unbuffered regions of partial fragments + return GapController; + })(); - var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__["BufferHelper"].getBuffered(media); + /***/ + }, - for (var i = 0; i < buffered.length; i++) { - var startTime = buffered.start(i); - - if (currentTime + config.maxBufferHole >= lastEndTime && currentTime < startTime) { - var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, media.currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS); - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime); - this.moved = true; - this.stalled = null; - media.currentTime = targetTime; - - if (partial) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_SEEK_OVER_HOLE, - fatal: false, - reason: "fragment loaded with buffer holes, seeking from " + currentTime + " to " + targetTime, - frag: partial - }); - } - - return targetTime; - } - - lastEndTime = buffered.end(i); - } - - return 0; - } - /** - * Attempts to fix buffer stalls by advancing the mediaElement's current time by a small amount. - * @private - */ - ; - - _proto._tryNudgeBuffer = function _tryNudgeBuffer() { - var config = this.config, - CiderHls = this.CiderHls, - media = this.media; - var currentTime = media.currentTime; - var nudgeRetry = (this.nudgeRetry || 0) + 1; - this.nudgeRetry = nudgeRetry; - - if (nudgeRetry < config.nudgeMaxRetry) { - var targetTime = currentTime + nudgeRetry * config.nudgeOffset; // playback stalled in buffered area ... let's nudge currentTime to try to overcome this - - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Nudging 'currentTime' from " + currentTime + " to " + targetTime); - media.currentTime = targetTime; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_NUDGE_ON_STALL, - fatal: false - }); - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges"); - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].BUFFER_STALLED_ERROR, - fatal: true - }); - } - }; - - return GapController; -}(); - - - -/***/ }), - -/***/ "./src/controller/id3-track-controller.ts": -/*!************************************************!*\ + /***/ "./src/controller/id3-track-controller.ts": + /*!************************************************!*\ !*** ./src/controller/id3-track-controller.ts ***! \************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts"); + /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts"); -/* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); + var MIN_CUE_DURATION = 0.25; + var ID3TrackController = /*#__PURE__*/ (function () { + function ID3TrackController(CiderHls) { + this.CiderHls = void 0; + this.id3Track = null; + this.media = null; + this.CiderHls = CiderHls; + this._registerListeners(); + } -var MIN_CUE_DURATION = 0.25; + var _proto = ID3TrackController.prototype; -var ID3TrackController = /*#__PURE__*/function () { - function ID3TrackController(CiderHls) { - this.CiderHls = void 0; - this.id3Track = null; - this.media = null; - this.CiderHls = CiderHls; + _proto.destroy = function destroy() { + this._unregisterListeners(); + }; - this._registerListeners(); - } + _proto._registerListeners = function _registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_PARSING_METADATA, this.onFragParsingMetadata, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); + }; - var _proto = ID3TrackController.prototype; + _proto._unregisterListeners = function _unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_PARSING_METADATA, this.onFragParsingMetadata, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); + }; // Add ID3 metatadata text track. - _proto.destroy = function destroy() { - this._unregisterListeners(); - }; + _proto.onMediaAttached = function onMediaAttached(event, data) { + this.media = data.media; + }; - _proto._registerListeners = function _registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_PARSING_METADATA, this.onFragParsingMetadata, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); - }; + _proto.onMediaDetaching = function onMediaDetaching() { + if (!this.id3Track) { + return; + } - _proto._unregisterListeners = function _unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_PARSING_METADATA, this.onFragParsingMetadata, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); - } // Add ID3 metatadata text track. - ; + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["clearCurrentCues"])(this.id3Track); + this.id3Track = null; + this.media = null; + }; - _proto.onMediaAttached = function onMediaAttached(event, data) { - this.media = data.media; - }; + _proto.getID3Track = function getID3Track(textTracks) { + if (!this.media) { + return; + } - _proto.onMediaDetaching = function onMediaDetaching() { - if (!this.id3Track) { - return; - } + for (var i = 0; i < textTracks.length; i++) { + var textTrack = textTracks[i]; - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["clearCurrentCues"])(this.id3Track); - this.id3Track = null; - this.media = null; - }; + if (textTrack.kind === "metadata" && textTrack.label === "id3") { + // send 'addtrack' when reusing the textTrack for metadata, + // same as what we do for captions + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["sendAddTrackEvent"])(textTrack, this.media); + return textTrack; + } + } - _proto.getID3Track = function getID3Track(textTracks) { - if (!this.media) { - return; - } + return this.media.addTextTrack("metadata", "id3"); + }; - for (var i = 0; i < textTracks.length; i++) { - var textTrack = textTracks[i]; + _proto.onFragParsingMetadata = function onFragParsingMetadata(event, data) { + if (!this.media) { + return; + } - if (textTrack.kind === 'metadata' && textTrack.label === 'id3') { - // send 'addtrack' when reusing the textTrack for metadata, - // same as what we do for captions - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["sendAddTrackEvent"])(textTrack, this.media); - return textTrack; - } - } + var fragment = data.frag; + var samples = data.samples; // create track dynamically - return this.media.addTextTrack('metadata', 'id3'); - }; + if (!this.id3Track) { + this.id3Track = this.getID3Track(this.media.textTracks); + this.id3Track.mode = "hidden"; + } // Attempt to recreate Safari functionality by creating + // WebKitDataCue objects when available and store the decoded + // ID3 data in the value property of the cue - _proto.onFragParsingMetadata = function onFragParsingMetadata(event, data) { - if (!this.media) { - return; - } + var Cue = self.WebKitDataCue || self.VTTCue || self.TextTrackCue; - var fragment = data.frag; - var samples = data.samples; // create track dynamically + for (var i = 0; i < samples.length; i++) { + var frames = _demux_id3__WEBPACK_IMPORTED_MODULE_2__["getID3Frames"](samples[i].data); - if (!this.id3Track) { - this.id3Track = this.getID3Track(this.media.textTracks); - this.id3Track.mode = 'hidden'; - } // Attempt to recreate Safari functionality by creating - // WebKitDataCue objects when available and store the decoded - // ID3 data in the value property of the cue + if (frames) { + var startTime = samples[i].pts; + var endTime = i < samples.length - 1 ? samples[i + 1].pts : fragment.end; + var timeDiff = endTime - startTime; + if (timeDiff <= 0) { + endTime = startTime + MIN_CUE_DURATION; + } - var Cue = self.WebKitDataCue || self.VTTCue || self.TextTrackCue; + for (var j = 0; j < frames.length; j++) { + var frame = frames[j]; // Safari doesn't put the timestamp frame in the TextTrack - for (var i = 0; i < samples.length; i++) { - var frames = _demux_id3__WEBPACK_IMPORTED_MODULE_2__["getID3Frames"](samples[i].data); + if (!_demux_id3__WEBPACK_IMPORTED_MODULE_2__["isTimeStampFrame"](frame)) { + var cue = new Cue(startTime, endTime, ""); + cue.value = frame; + this.id3Track.addCue(cue); + } + } + } + } + }; - if (frames) { - var startTime = samples[i].pts; - var endTime = i < samples.length - 1 ? samples[i + 1].pts : fragment.end; - var timeDiff = endTime - startTime; + _proto.onBufferFlushing = function onBufferFlushing(event, _ref) { + var startOffset = _ref.startOffset, + endOffset = _ref.endOffset, + type = _ref.type; - if (timeDiff <= 0) { - endTime = startTime + MIN_CUE_DURATION; - } + if (!type || type === "audio") { + // id3 cues come from parsed audio only remove cues when audio buffer is cleared + var id3Track = this.id3Track; - for (var j = 0; j < frames.length; j++) { - var frame = frames[j]; // Safari doesn't put the timestamp frame in the TextTrack + if (id3Track) { + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["removeCuesInRange"])(id3Track, startOffset, endOffset); + } + } + }; - if (!_demux_id3__WEBPACK_IMPORTED_MODULE_2__["isTimeStampFrame"](frame)) { - var cue = new Cue(startTime, endTime, ''); - cue.value = frame; - this.id3Track.addCue(cue); - } - } - } - } - }; + return ID3TrackController; + })(); - _proto.onBufferFlushing = function onBufferFlushing(event, _ref) { - var startOffset = _ref.startOffset, - endOffset = _ref.endOffset, - type = _ref.type; + /* harmony default export */ __webpack_exports__["default"] = ID3TrackController; - if (!type || type === 'audio') { - // id3 cues come from parsed audio only remove cues when audio buffer is cleared - var id3Track = this.id3Track; + /***/ + }, - if (id3Track) { - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["removeCuesInRange"])(id3Track, startOffset, endOffset); - } - } - }; - - return ID3TrackController; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (ID3TrackController); - -/***/ }), - -/***/ "./src/controller/latency-controller.ts": -/*!**********************************************!*\ + /***/ "./src/controller/latency-controller.ts": + /*!**********************************************!*\ !*** ./src/controller/latency-controller.ts ***! \**********************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return LatencyController; + }); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return LatencyController; }); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + var LatencyController = /*#__PURE__*/ (function () { + function LatencyController(CiderHls) { + var _this = this; + this.CiderHls = void 0; + this.config = void 0; + this.media = null; + this.levelDetails = null; + this.currentTime = 0; + this.stallCount = 0; + this._latency = null; + this.timeupdateHandler = function () { + return _this.timeupdate(); + }; + this.CiderHls = CiderHls; + this.config = CiderHls.config; + this.registerListeners(); + } + var _proto = LatencyController.prototype; -var LatencyController = /*#__PURE__*/function () { - function LatencyController(CiderHls) { - var _this = this; + _proto.destroy = function destroy() { + this.unregisterListeners(); + this.onMediaDetaching(); + this.levelDetails = null; // @ts-ignore - this.CiderHls = void 0; - this.config = void 0; - this.media = null; - this.levelDetails = null; - this.currentTime = 0; - this.stallCount = 0; - this._latency = null; + this.CiderHls = this.timeupdateHandler = null; + }; - this.timeupdateHandler = function () { - return _this.timeupdate(); - }; + _proto.registerListeners = function registerListeners() { + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated, this); + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError, this); + }; - this.CiderHls = CiderHls; - this.config = CiderHls.config; - this.registerListeners(); - } + _proto.unregisterListeners = function unregisterListeners() { + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHED, this.onMediaAttached); + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching); + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading); + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated); + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError); + }; - var _proto = LatencyController.prototype; + _proto.onMediaAttached = function onMediaAttached(event, data) { + this.media = data.media; + this.media.addEventListener("timeupdate", this.timeupdateHandler); + }; - _proto.destroy = function destroy() { - this.unregisterListeners(); - this.onMediaDetaching(); - this.levelDetails = null; // @ts-ignore + _proto.onMediaDetaching = function onMediaDetaching() { + if (this.media) { + this.media.removeEventListener("timeupdate", this.timeupdateHandler); + this.media = null; + } + }; - this.CiderHls = this.timeupdateHandler = null; - }; + _proto.onManifestLoading = function onManifestLoading() { + this.levelDetails = null; + this._latency = null; + this.stallCount = 0; + }; - _proto.registerListeners = function registerListeners() { - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated, this); - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError, this); - }; + _proto.onLevelUpdated = function onLevelUpdated(event, _ref) { + var details = _ref.details; + this.levelDetails = details; - _proto.unregisterListeners = function unregisterListeners() { - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHED, this.onMediaAttached); - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching); - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading); - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_UPDATED, this.onLevelUpdated); - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError); - }; + if (details.advanced) { + this.timeupdate(); + } - _proto.onMediaAttached = function onMediaAttached(event, data) { - this.media = data.media; - this.media.addEventListener('timeupdate', this.timeupdateHandler); - }; + if (!details.live && this.media) { + this.media.removeEventListener("timeupdate", this.timeupdateHandler); + } + }; - _proto.onMediaDetaching = function onMediaDetaching() { - if (this.media) { - this.media.removeEventListener('timeupdate', this.timeupdateHandler); - this.media = null; - } - }; + _proto.onError = function onError(event, data) { + if (data.details !== _errors__WEBPACK_IMPORTED_MODULE_0__["ErrorDetails"].BUFFER_STALLED_ERROR) { + return; + } - _proto.onManifestLoading = function onManifestLoading() { - this.levelDetails = null; - this._latency = null; - this.stallCount = 0; - }; + this.stallCount++; + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("[playback-rate-controller]: Stall detected, adjusting target latency"); + }; - _proto.onLevelUpdated = function onLevelUpdated(event, _ref) { - var details = _ref.details; - this.levelDetails = details; + _proto.timeupdate = function timeupdate() { + var media = this.media, + levelDetails = this.levelDetails; - if (details.advanced) { - this.timeupdate(); - } + if (!media || !levelDetails) { + return; + } - if (!details.live && this.media) { - this.media.removeEventListener('timeupdate', this.timeupdateHandler); - } - }; + this.currentTime = media.currentTime; + var latency = this.computeLatency(); - _proto.onError = function onError(event, data) { - if (data.details !== _errors__WEBPACK_IMPORTED_MODULE_0__["ErrorDetails"].BUFFER_STALLED_ERROR) { - return; - } + if (latency === null) { + return; + } - this.stallCount++; - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn('[playback-rate-controller]: Stall detected, adjusting target latency'); - }; + this._latency = latency; // Adapt playbackRate to meet target latency in low-latency mode - _proto.timeupdate = function timeupdate() { - var media = this.media, - levelDetails = this.levelDetails; + var _this$config = this.config, + lowLatencyMode = _this$config.lowLatencyMode, + maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate; - if (!media || !levelDetails) { - return; - } + if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1) { + return; + } - this.currentTime = media.currentTime; - var latency = this.computeLatency(); + var targetLatency = this.targetLatency; - if (latency === null) { - return; - } + if (targetLatency === null) { + return; + } - this._latency = latency; // Adapt playbackRate to meet target latency in low-latency mode + var distanceFromTarget = latency - targetLatency; // Only adjust playbackRate when within one target duration of targetLatency + // and more than one second from under-buffering. + // Playback further than one target duration from target can be considered DVR playback. - var _this$config = this.config, - lowLatencyMode = _this$config.lowLatencyMode, - maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate; + var liveMinLatencyDuration = Math.min(this.maxLatency, targetLatency + levelDetails.targetduration); + var inLiveRange = distanceFromTarget < liveMinLatencyDuration; - if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1) { - return; - } + if (levelDetails.live && inLiveRange && distanceFromTarget > 0.05 && this.forwardBufferLength > 1) { + var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate)); + var rate = Math.round((2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled))) * 20) / 20; + media.playbackRate = Math.min(max, Math.max(1, rate)); + } else if (media.playbackRate !== 1 && media.playbackRate !== 0) { + media.playbackRate = 1; + } + }; - var targetLatency = this.targetLatency; + _proto.estimateLiveEdge = function estimateLiveEdge() { + var levelDetails = this.levelDetails; - if (targetLatency === null) { - return; - } + if (levelDetails === null) { + return null; + } - var distanceFromTarget = latency - targetLatency; // Only adjust playbackRate when within one target duration of targetLatency - // and more than one second from under-buffering. - // Playback further than one target duration from target can be considered DVR playback. + return levelDetails.edge + levelDetails.age; + }; - var liveMinLatencyDuration = Math.min(this.maxLatency, targetLatency + levelDetails.targetduration); - var inLiveRange = distanceFromTarget < liveMinLatencyDuration; + _proto.computeLatency = function computeLatency() { + var liveEdge = this.estimateLiveEdge(); - if (levelDetails.live && inLiveRange && distanceFromTarget > 0.05 && this.forwardBufferLength > 1) { - var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate)); - var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled)) * 20) / 20; - media.playbackRate = Math.min(max, Math.max(1, rate)); - } else if (media.playbackRate !== 1 && media.playbackRate !== 0) { - media.playbackRate = 1; - } - }; + if (liveEdge === null) { + return null; + } - _proto.estimateLiveEdge = function estimateLiveEdge() { - var levelDetails = this.levelDetails; + return liveEdge - this.currentTime; + }; - if (levelDetails === null) { - return null; - } + _createClass(LatencyController, [ + { + key: "latency", + get: function get() { + return this._latency || 0; + }, + }, + { + key: "maxLatency", + get: function get() { + var config = this.config, + levelDetails = this.levelDetails; - return levelDetails.edge + levelDetails.age; - }; + if (config.liveMaxLatencyDuration !== undefined) { + return config.liveMaxLatencyDuration; + } - _proto.computeLatency = function computeLatency() { - var liveEdge = this.estimateLiveEdge(); + return levelDetails ? config.liveMaxLatencyDurationCount * levelDetails.targetduration : 0; + }, + }, + { + key: "targetLatency", + get: function get() { + var levelDetails = this.levelDetails; - if (liveEdge === null) { - return null; - } + if (levelDetails === null) { + return null; + } - return liveEdge - this.currentTime; - }; + var holdBack = levelDetails.holdBack, + partHoldBack = levelDetails.partHoldBack, + targetduration = levelDetails.targetduration; + var _this$config2 = this.config, + liveSyncDuration = _this$config2.liveSyncDuration, + liveSyncDurationCount = _this$config2.liveSyncDurationCount, + lowLatencyMode = _this$config2.lowLatencyMode; + var userConfig = this.CiderHls.userConfig; + var targetLatency = lowLatencyMode ? partHoldBack || holdBack : holdBack; - _createClass(LatencyController, [{ - key: "latency", - get: function get() { - return this._latency || 0; - } - }, { - key: "maxLatency", - get: function get() { - var config = this.config, - levelDetails = this.levelDetails; + if (userConfig.liveSyncDuration || userConfig.liveSyncDurationCount || targetLatency === 0) { + targetLatency = liveSyncDuration !== undefined ? liveSyncDuration : liveSyncDurationCount * targetduration; + } - if (config.liveMaxLatencyDuration !== undefined) { - return config.liveMaxLatencyDuration; - } + var maxLiveSyncOnStallIncrease = targetduration; + var liveSyncOnStallIncrease = 1.0; + return targetLatency + Math.min(this.stallCount * liveSyncOnStallIncrease, maxLiveSyncOnStallIncrease); + }, + }, + { + key: "liveSyncPosition", + get: function get() { + var liveEdge = this.estimateLiveEdge(); + var targetLatency = this.targetLatency; + var levelDetails = this.levelDetails; - return levelDetails ? config.liveMaxLatencyDurationCount * levelDetails.targetduration : 0; - } - }, { - key: "targetLatency", - get: function get() { - var levelDetails = this.levelDetails; + if (liveEdge === null || targetLatency === null || levelDetails === null) { + return null; + } - if (levelDetails === null) { - return null; - } + var edge = levelDetails.edge; + var syncPosition = liveEdge - targetLatency - this.edgeStalled; + var min = edge - levelDetails.totalduration; + var max = edge - ((this.config.lowLatencyMode && levelDetails.partTarget) || levelDetails.targetduration); + return Math.min(Math.max(min, syncPosition), max); + }, + }, + { + key: "drift", + get: function get() { + var levelDetails = this.levelDetails; - var holdBack = levelDetails.holdBack, - partHoldBack = levelDetails.partHoldBack, - targetduration = levelDetails.targetduration; - var _this$config2 = this.config, - liveSyncDuration = _this$config2.liveSyncDuration, - liveSyncDurationCount = _this$config2.liveSyncDurationCount, - lowLatencyMode = _this$config2.lowLatencyMode; - var userConfig = this.CiderHls.userConfig; - var targetLatency = lowLatencyMode ? partHoldBack || holdBack : holdBack; + if (levelDetails === null) { + return 1; + } - if (userConfig.liveSyncDuration || userConfig.liveSyncDurationCount || targetLatency === 0) { - targetLatency = liveSyncDuration !== undefined ? liveSyncDuration : liveSyncDurationCount * targetduration; - } + return levelDetails.drift; + }, + }, + { + key: "edgeStalled", + get: function get() { + var levelDetails = this.levelDetails; - var maxLiveSyncOnStallIncrease = targetduration; - var liveSyncOnStallIncrease = 1.0; - return targetLatency + Math.min(this.stallCount * liveSyncOnStallIncrease, maxLiveSyncOnStallIncrease); - } - }, { - key: "liveSyncPosition", - get: function get() { - var liveEdge = this.estimateLiveEdge(); - var targetLatency = this.targetLatency; - var levelDetails = this.levelDetails; + if (levelDetails === null) { + return 0; + } - if (liveEdge === null || targetLatency === null || levelDetails === null) { - return null; - } + var maxLevelUpdateAge = ((this.config.lowLatencyMode && levelDetails.partTarget) || levelDetails.targetduration) * 3; + return Math.max(levelDetails.age - maxLevelUpdateAge, 0); + }, + }, + { + key: "forwardBufferLength", + get: function get() { + var media = this.media, + levelDetails = this.levelDetails; - var edge = levelDetails.edge; - var syncPosition = liveEdge - targetLatency - this.edgeStalled; - var min = edge - levelDetails.totalduration; - var max = edge - (this.config.lowLatencyMode && levelDetails.partTarget || levelDetails.targetduration); - return Math.min(Math.max(min, syncPosition), max); - } - }, { - key: "drift", - get: function get() { - var levelDetails = this.levelDetails; + if (!media || !levelDetails) { + return 0; + } - if (levelDetails === null) { - return 1; - } + var bufferedRanges = media.buffered.length; + return bufferedRanges ? media.buffered.end(bufferedRanges - 1) : levelDetails.edge - this.currentTime; + }, + }, + ]); - return levelDetails.drift; - } - }, { - key: "edgeStalled", - get: function get() { - var levelDetails = this.levelDetails; + return LatencyController; + })(); - if (levelDetails === null) { - return 0; - } + /***/ + }, - var maxLevelUpdateAge = (this.config.lowLatencyMode && levelDetails.partTarget || levelDetails.targetduration) * 3; - return Math.max(levelDetails.age - maxLevelUpdateAge, 0); - } - }, { - key: "forwardBufferLength", - get: function get() { - var media = this.media, - levelDetails = this.levelDetails; - - if (!media || !levelDetails) { - return 0; - } - - var bufferedRanges = media.buffered.length; - return bufferedRanges ? media.buffered.end(bufferedRanges - 1) : levelDetails.edge - this.currentTime; - } - }]); - - return LatencyController; -}(); - - - -/***/ }), - -/***/ "./src/controller/level-controller.ts": -/*!********************************************!*\ + /***/ "./src/controller/level-controller.ts": + /*!********************************************!*\ !*** ./src/controller/level-controller.ts ***! \********************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return LevelController; }); -/* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_codecs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/codecs */ "./src/utils/codecs.ts"); -/* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); -/* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -/* - * Level Controller - */ - - - - - - - -var chromeOrFirefox = /chrome|firefox/.test(navigator.userAgent.toLowerCase()); - -var LevelController = /*#__PURE__*/function (_BasePlaylistControll) { - _inheritsLoose(LevelController, _BasePlaylistControll); - - function LevelController(CiderHls) { - var _this; - - _this = _BasePlaylistControll.call(this, CiderHls, '[level-controller]') || this; - _this._levels = []; - _this._firstLevel = -1; - _this._startLevel = void 0; - _this.currentLevelIndex = -1; - _this.manualLevelIndex = -1; - _this.onParsedComplete = void 0; - - _this._registerListeners(); - - return _this; - } - - var _proto = LevelController.prototype; - - _proto._registerListeners = function _registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError, this); - }; - - _proto._unregisterListeners = function _unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError, this); - }; - - _proto.destroy = function destroy() { - this._unregisterListeners(); - - this.manualLevelIndex = -1; - this._levels.length = 0; - - _BasePlaylistControll.prototype.destroy.call(this); - }; - - _proto.startLoad = function startLoad() { - var levels = this._levels; // clean up live level details to force reload them, and reset load errors - - levels.forEach(function (level) { - level.loadError = 0; - }); - - _BasePlaylistControll.prototype.startLoad.call(this); - }; - - _proto.onManifestLoaded = function onManifestLoaded(event, data) { - var levels = []; - var audioTracks = []; - var subtitleTracks = []; - var bitrateStart; - var levelSet = {}; - var levelFromSet; - var resolutionFound = false; - var videoCodecFound = false; - var audioCodecFound = false; // regroup redundant levels together - - data.levels.forEach(function (levelParsed) { - var attributes = levelParsed.attrs; - resolutionFound = resolutionFound || !!(levelParsed.width && levelParsed.height); - videoCodecFound = videoCodecFound || !!levelParsed.videoCodec; - audioCodecFound = audioCodecFound || !!levelParsed.audioCodec; // erase audio codec info if browser does not support mp4a.40.34. - // demuxer will autodetect codec and fallback to mpeg/audio - - if (chromeOrFirefox && levelParsed.audioCodec && levelParsed.audioCodec.indexOf('mp4a.40.34') !== -1) { - levelParsed.audioCodec = undefined; - } - - var levelKey = levelParsed.bitrate + "-" + levelParsed.attrs.RESOLUTION + "-" + levelParsed.attrs.CODECS; - levelFromSet = levelSet[levelKey]; - - if (!levelFromSet) { - levelFromSet = new _types_level__WEBPACK_IMPORTED_MODULE_0__["Level"](levelParsed); - levelSet[levelKey] = levelFromSet; - levels.push(levelFromSet); - } else { - levelFromSet.url.push(levelParsed.url); - } - - if (attributes) { - if (attributes.AUDIO) { - Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["addGroupId"])(levelFromSet, 'audio', attributes.AUDIO); - } - - if (attributes.SUBTITLES) { - Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["addGroupId"])(levelFromSet, 'text', attributes.SUBTITLES); - } - } - }); // remove audio-only level if we also have levels with video codecs or RESOLUTION signalled - - if ((resolutionFound || videoCodecFound) && audioCodecFound) { - levels = levels.filter(function (_ref) { - var videoCodec = _ref.videoCodec, - width = _ref.width, - height = _ref.height; - return !!videoCodec || !!(width && height); - }); - } // only keep levels with supported audio/video codecs - - - levels = levels.filter(function (_ref2) { - var audioCodec = _ref2.audioCodec, - videoCodec = _ref2.videoCodec; - return (!audioCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(audioCodec, 'audio')) && (!videoCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(videoCodec, 'video')); - }); - - if (data.audioTracks) { - audioTracks = data.audioTracks.filter(function (track) { - return !track.audioCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(track.audioCodec, 'audio'); - }); // Assign ids after filtering as array indices by group-id - - Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["assignTrackIdsByGroup"])(audioTracks); - } - - if (data.subtitles) { - subtitleTracks = data.subtitles; - Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["assignTrackIdsByGroup"])(subtitleTracks); - } - - if (levels.length > 0) { - // start bitrate is the first bitrate of the manifest - bitrateStart = levels[0].bitrate; // sort level on bitrate - - levels.sort(function (a, b) { - return a.bitrate - b.bitrate; - }); - this._levels = levels; // find index of first level in sorted levels - - for (var i = 0; i < levels.length; i++) { - if (levels[i].bitrate === bitrateStart) { - this._firstLevel = i; - this.log("manifest loaded, " + levels.length + " level(s) found, first bitrate: " + bitrateStart); - break; - } - } // Audio is only alternate if manifest include a URI along with the audio group tag, - // and this is not an audio-only stream where levels contain audio-only - - - var audioOnly = audioCodecFound && !videoCodecFound; - var edata = { - levels: levels, - audioTracks: audioTracks, - subtitleTracks: subtitleTracks, - firstLevel: this._firstLevel, - stats: data.stats, - audio: audioCodecFound, - video: videoCodecFound, - altAudio: !audioOnly && audioTracks.some(function (t) { - return !!t.url; - }) - }; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_PARSED, edata); // Initiate loading after all controllers have received MANIFEST_PARSED - - if (this.CiderHls.config.autoStartLoad || this.CiderHls.forceStartLoad) { - this.CiderHls.startLoad(this.CiderHls.config.startPosition); - } - } else { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_INCOMPATIBLE_CODECS_ERROR, - fatal: true, - url: data.url, - reason: 'no level with compatible codecs found in manifest' - }); - } - }; - - _proto.onError = function onError(event, data) { - _BasePlaylistControll.prototype.onError.call(this, event, data); - - if (data.fatal) { - return; - } // Switch to redundant level when track fails to load - - - var context = data.context; - var level = this._levels[this.currentLevelIndex]; - - if (context && (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK && level.audioGroupIds && context.groupId === level.audioGroupIds[level.urlId] || context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK && level.textGroupIds && context.groupId === level.textGroupIds[level.urlId])) { - this.redundantFailover(this.currentLevelIndex); - return; - } - - var levelError = false; - var levelSwitch = true; - var levelIndex; // try to recover not fatal errors - - switch (data.details) { - case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].FRAG_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].FRAG_LOAD_TIMEOUT: - case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].KEY_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].KEY_LOAD_TIMEOUT: - if (data.frag) { - var _level = this._levels[data.frag.level]; // Set levelIndex when we're out of fragment retries - - if (_level) { - _level.fragmentError++; - - if (_level.fragmentError > this.CiderHls.config.fragLoadingMaxRetry) { - levelIndex = data.frag.level; + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return LevelController; + }); + /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_codecs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/codecs */ "./src/utils/codecs.ts"); + /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); + /* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + function _extends() { + _extends = + Object.assign || + function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); } - } else { - levelIndex = data.frag.level; - } - } - - break; - - case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_TIMEOUT: - // Do not perform level switch if an error occurred using delivery directives - // Attempt to reload level without directives first - if (context) { - if (context.deliveryDirectives) { - levelSwitch = false; - } - - levelIndex = context.level; - } - - levelError = true; - break; - - case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].REMUX_ALLOC_ERROR: - levelIndex = data.level; - levelError = true; - break; - } - - if (levelIndex !== undefined) { - this.recoverLevel(data, levelIndex, levelError, levelSwitch); - } - } - /** - * Switch to a redundant stream if any available. - * If redundant stream is not available, emergency switch down if ABR mode is enabled. - */ - ; - - _proto.recoverLevel = function recoverLevel(errorEvent, levelIndex, levelError, levelSwitch) { - var errorDetails = errorEvent.details; - var level = this._levels[levelIndex]; - level.loadError++; - - if (levelError) { - var retrying = this.retryLoadingOrFail(errorEvent); - - if (retrying) { - // boolean used to inform stream controller not to switch back to IDLE on non fatal error - errorEvent.levelRetry = true; - } else { - this.currentLevelIndex = -1; - return; - } - } - - if (levelSwitch) { - var redundantLevels = level.url.length; // Try redundant fail-over until level.loadError reaches redundantLevels - - if (redundantLevels > 1 && level.loadError < redundantLevels) { - errorEvent.levelRetry = true; - this.redundantFailover(levelIndex); - } else if (this.manualLevelIndex === -1) { - // Search for available level in auto level selection mode, cycling from highest to lowest bitrate - var nextLevel = levelIndex === 0 ? this._levels.length - 1 : levelIndex - 1; - - if (this.currentLevelIndex !== nextLevel && this._levels[nextLevel].loadError === 0) { - this.warn(errorDetails + ": switch to " + nextLevel); - errorEvent.levelRetry = true; - this.CiderHls.nextAutoLevel = nextLevel; - } - } - } - }; - - _proto.redundantFailover = function redundantFailover(levelIndex) { - var level = this._levels[levelIndex]; - var redundantLevels = level.url.length; - - if (redundantLevels > 1) { - // Update the url id of all levels so that we stay on the same set of variants when level switching - var newUrlId = (level.urlId + 1) % redundantLevels; - this.warn("Switching to redundant URL-id " + newUrlId); - - this._levels.forEach(function (level) { - level.urlId = newUrlId; - }); - - this.level = levelIndex; - } - } // reset errors on the successful load of a fragment - ; - - _proto.onFragLoaded = function onFragLoaded(event, _ref3) { - var frag = _ref3.frag; - - if (frag !== undefined && frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN) { - var level = this._levels[frag.level]; - - if (level !== undefined) { - level.fragmentError = 0; - level.loadError = 0; - } - } - }; - - _proto.onLevelLoaded = function onLevelLoaded(event, data) { - var _data$deliveryDirecti2; - - var level = data.level, - details = data.details; - var curLevel = this._levels[level]; - - if (!curLevel) { - var _data$deliveryDirecti; - - this.warn("Invalid level index " + level); - - if ((_data$deliveryDirecti = data.deliveryDirectives) !== null && _data$deliveryDirecti !== void 0 && _data$deliveryDirecti.skip) { - details.deltaUpdateFailed = true; - } - - return; - } // only process level loaded events matching with expected level - - - if (level === this.currentLevelIndex) { - // reset level load error counter on successful level loaded only if there is no issues with fragments - if (curLevel.fragmentError === 0) { - curLevel.loadError = 0; - this.retryCount = 0; - } - - this.playlistLoaded(level, data, curLevel.details); - } else if ((_data$deliveryDirecti2 = data.deliveryDirectives) !== null && _data$deliveryDirecti2 !== void 0 && _data$deliveryDirecti2.skip) { - // received a delta playlist update that cannot be merged - details.deltaUpdateFailed = true; - } - }; - - _proto.onAudioTrackSwitched = function onAudioTrackSwitched(event, data) { - var currentLevel = this.CiderHls.levels[this.currentLevelIndex]; - - if (!currentLevel) { - return; - } - - if (currentLevel.audioGroupIds) { - var urlId = -1; - var audioGroupId = this.CiderHls.audioTracks[data.id].groupId; - - for (var i = 0; i < currentLevel.audioGroupIds.length; i++) { - if (currentLevel.audioGroupIds[i] === audioGroupId) { - urlId = i; - break; - } - } - - if (urlId !== currentLevel.urlId) { - currentLevel.urlId = urlId; - this.startLoad(); - } - } - }; - - _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) { - var level = this.currentLevelIndex; - var currentLevel = this._levels[level]; - - if (this.canLoad && currentLevel && currentLevel.url.length > 0) { - var id = currentLevel.urlId; - var url = currentLevel.url[id]; - - if (CiderHlsUrlParameters) { - try { - url = CiderHlsUrlParameters.addDirectives(url); - } catch (error) { - this.warn("Could not construct new URL with CiderHls Delivery Directives: " + error); - } - } - - this.log("Attempt loading level index " + level + (CiderHlsUrlParameters ? ' at sn ' + CiderHlsUrlParameters.msn + ' part ' + CiderHlsUrlParameters.part : '') + " with URL-id " + id + " " + url); // console.log('Current audio track group ID:', this.CiderHls.audioTracks[this.CiderHls.audioTrack].groupId); - // console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level); - - this.clearTimer(); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADING, { - url: url, - level: level, - id: id, - deliveryDirectives: CiderHlsUrlParameters || null - }); - } - }; - - _proto.removeLevel = function removeLevel(levelIndex, urlId) { - var filterLevelAndGroupByIdIndex = function filterLevelAndGroupByIdIndex(url, id) { - return id !== urlId; - }; - - var levels = this._levels.filter(function (level, index) { - if (index !== levelIndex) { - return true; - } - - if (level.url.length > 1 && urlId !== undefined) { - level.url = level.url.filter(filterLevelAndGroupByIdIndex); - - if (level.audioGroupIds) { - level.audioGroupIds = level.audioGroupIds.filter(filterLevelAndGroupByIdIndex); - } - - if (level.textGroupIds) { - level.textGroupIds = level.textGroupIds.filter(filterLevelAndGroupByIdIndex); - } - - level.urlId = 0; - return true; - } - - return false; - }).map(function (level, index) { - var details = level.details; - - if (details !== null && details !== void 0 && details.fragments) { - details.fragments.forEach(function (fragment) { - fragment.level = index; - }); - } - - return level; - }); - - this._levels = levels; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVELS_UPDATED, { - levels: levels - }); - }; - - _createClass(LevelController, [{ - key: "levels", - get: function get() { - if (this._levels.length === 0) { - return null; - } - - return this._levels; - } - }, { - key: "level", - get: function get() { - return this.currentLevelIndex; - }, - set: function set(newLevel) { - var _levels$newLevel; - - var levels = this._levels; - - if (levels.length === 0) { - return; - } - - if (this.currentLevelIndex === newLevel && (_levels$newLevel = levels[newLevel]) !== null && _levels$newLevel !== void 0 && _levels$newLevel.details) { - return; - } // check if level idx is valid - - - if (newLevel < 0 || newLevel >= levels.length) { - // invalid level id given, trigger error - var fatal = newLevel < 0; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].OTHER_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_SWITCH_ERROR, - level: newLevel, - fatal: fatal, - reason: 'invalid level idx' - }); - - if (fatal) { - return; - } - - newLevel = Math.min(newLevel, levels.length - 1); - } // stopping live reloading timer if any - - - this.clearTimer(); - var lastLevelIndex = this.currentLevelIndex; - var lastLevel = levels[lastLevelIndex]; - var level = levels[newLevel]; - this.log("switching to level " + newLevel + " from " + lastLevelIndex); - this.currentLevelIndex = newLevel; - - var levelSwitchingData = _extends({}, level, { - level: newLevel, - maxBitrate: level.maxBitrate, - uri: level.uri, - urlId: level.urlId - }); // @ts-ignore - - - delete levelSwitchingData._urlId; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_SWITCHING, levelSwitchingData); // check if we need to load playlist for this level - - var levelDetails = level.details; - - if (!levelDetails || levelDetails.live) { - // level not retrieved yet, or live playlist we need to (re)load it - var CiderHlsUrlParameters = this.switchParams(level.uri, lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.details); - this.loadPlaylist(CiderHlsUrlParameters); - } - } - }, { - key: "manualLevel", - get: function get() { - return this.manualLevelIndex; - }, - set: function set(newLevel) { - this.manualLevelIndex = newLevel; - - if (this._startLevel === undefined) { - this._startLevel = newLevel; - } - - if (newLevel !== -1) { - this.level = newLevel; - } - } - }, { - key: "firstLevel", - get: function get() { - return this._firstLevel; - }, - set: function set(newLevel) { - this._firstLevel = newLevel; - } - }, { - key: "startLevel", - get: function get() { - // CiderHls.startLevel takes precedence over config.startLevel - // if none of these values are defined, fallback on this._firstLevel (first quality level appearing in variant manifest) - if (this._startLevel === undefined) { - var configStartLevel = this.CiderHls.config.startLevel; - - if (configStartLevel !== undefined) { - return configStartLevel; - } else { - return this._firstLevel; - } - } else { - return this._startLevel; - } - }, - set: function set(newLevel) { - this._startLevel = newLevel; - } - }, { - key: "nextLoadLevel", - get: function get() { - if (this.manualLevelIndex !== -1) { - return this.manualLevelIndex; - } else { - return this.CiderHls.nextAutoLevel; - } - }, - set: function set(nextLevel) { - this.level = nextLevel; - - if (this.manualLevelIndex === -1) { - this.CiderHls.nextAutoLevel = nextLevel; - } - } - }]); - - return LevelController; -}(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__["default"]); - - - -/***/ }), - -/***/ "./src/controller/level-helper.ts": -/*!****************************************!*\ + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } + + /* + * Level Controller + */ + + var chromeOrFirefox = /chrome|firefox/.test(navigator.userAgent.toLowerCase()); + + var LevelController = /*#__PURE__*/ (function (_BasePlaylistControll) { + _inheritsLoose(LevelController, _BasePlaylistControll); + + function LevelController(CiderHls) { + var _this; + + _this = _BasePlaylistControll.call(this, CiderHls, "[level-controller]") || this; + _this._levels = []; + _this._firstLevel = -1; + _this._startLevel = void 0; + _this.currentLevelIndex = -1; + _this.manualLevelIndex = -1; + _this.onParsedComplete = void 0; + + _this._registerListeners(); + + return _this; + } + + var _proto = LevelController.prototype; + + _proto._registerListeners = function _registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError, this); + }; + + _proto._unregisterListeners = function _unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, this.onError, this); + }; + + _proto.destroy = function destroy() { + this._unregisterListeners(); + + this.manualLevelIndex = -1; + this._levels.length = 0; + + _BasePlaylistControll.prototype.destroy.call(this); + }; + + _proto.startLoad = function startLoad() { + var levels = this._levels; // clean up live level details to force reload them, and reset load errors + + levels.forEach(function (level) { + level.loadError = 0; + }); + + _BasePlaylistControll.prototype.startLoad.call(this); + }; + + _proto.onManifestLoaded = function onManifestLoaded(event, data) { + var levels = []; + var audioTracks = []; + var subtitleTracks = []; + var bitrateStart; + var levelSet = {}; + var levelFromSet; + var resolutionFound = false; + var videoCodecFound = false; + var audioCodecFound = false; // regroup redundant levels together + + data.levels.forEach(function (levelParsed) { + var attributes = levelParsed.attrs; + resolutionFound = resolutionFound || !!(levelParsed.width && levelParsed.height); + videoCodecFound = videoCodecFound || !!levelParsed.videoCodec; + audioCodecFound = audioCodecFound || !!levelParsed.audioCodec; // erase audio codec info if browser does not support mp4a.40.34. + // demuxer will autodetect codec and fallback to mpeg/audio + + if (chromeOrFirefox && levelParsed.audioCodec && levelParsed.audioCodec.indexOf("mp4a.40.34") !== -1) { + levelParsed.audioCodec = undefined; + } + + var levelKey = levelParsed.bitrate + "-" + levelParsed.attrs.RESOLUTION + "-" + levelParsed.attrs.CODECS; + levelFromSet = levelSet[levelKey]; + + if (!levelFromSet) { + levelFromSet = new _types_level__WEBPACK_IMPORTED_MODULE_0__["Level"](levelParsed); + levelSet[levelKey] = levelFromSet; + levels.push(levelFromSet); + } else { + levelFromSet.url.push(levelParsed.url); + } + + if (attributes) { + if (attributes.AUDIO) { + Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["addGroupId"])(levelFromSet, "audio", attributes.AUDIO); + } + + if (attributes.SUBTITLES) { + Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["addGroupId"])(levelFromSet, "text", attributes.SUBTITLES); + } + } + }); // remove audio-only level if we also have levels with video codecs or RESOLUTION signalled + + if ((resolutionFound || videoCodecFound) && audioCodecFound) { + levels = levels.filter(function (_ref) { + var videoCodec = _ref.videoCodec, + width = _ref.width, + height = _ref.height; + return !!videoCodec || !!(width && height); + }); + } // only keep levels with supported audio/video codecs + + levels = levels.filter(function (_ref2) { + var audioCodec = _ref2.audioCodec, + videoCodec = _ref2.videoCodec; + return (!audioCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(audioCodec, "audio")) && (!videoCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(videoCodec, "video")); + }); + + if (data.audioTracks) { + audioTracks = data.audioTracks.filter(function (track) { + return !track.audioCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(track.audioCodec, "audio"); + }); // Assign ids after filtering as array indices by group-id + + Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["assignTrackIdsByGroup"])(audioTracks); + } + + if (data.subtitles) { + subtitleTracks = data.subtitles; + Object(_level_helper__WEBPACK_IMPORTED_MODULE_4__["assignTrackIdsByGroup"])(subtitleTracks); + } + + if (levels.length > 0) { + // start bitrate is the first bitrate of the manifest + bitrateStart = levels[0].bitrate; // sort level on bitrate + + levels.sort(function (a, b) { + return a.bitrate - b.bitrate; + }); + this._levels = levels; // find index of first level in sorted levels + + for (var i = 0; i < levels.length; i++) { + if (levels[i].bitrate === bitrateStart) { + this._firstLevel = i; + this.log("manifest loaded, " + levels.length + " level(s) found, first bitrate: " + bitrateStart); + break; + } + } // Audio is only alternate if manifest include a URI along with the audio group tag, + // and this is not an audio-only stream where levels contain audio-only + + var audioOnly = audioCodecFound && !videoCodecFound; + var edata = { + levels: levels, + audioTracks: audioTracks, + subtitleTracks: subtitleTracks, + firstLevel: this._firstLevel, + stats: data.stats, + audio: audioCodecFound, + video: videoCodecFound, + altAudio: + !audioOnly && + audioTracks.some(function (t) { + return !!t.url; + }), + }; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_PARSED, edata); // Initiate loading after all controllers have received MANIFEST_PARSED + + if (this.CiderHls.config.autoStartLoad || this.CiderHls.forceStartLoad) { + this.CiderHls.startLoad(this.CiderHls.config.startPosition); + } + } else { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_INCOMPATIBLE_CODECS_ERROR, + fatal: true, + url: data.url, + reason: "no level with compatible codecs found in manifest", + }); + } + }; + + _proto.onError = function onError(event, data) { + _BasePlaylistControll.prototype.onError.call(this, event, data); + + if (data.fatal) { + return; + } // Switch to redundant level when track fails to load + + var context = data.context; + var level = this._levels[this.currentLevelIndex]; + + if ( + context && + ((context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK && level.audioGroupIds && context.groupId === level.audioGroupIds[level.urlId]) || + (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK && level.textGroupIds && context.groupId === level.textGroupIds[level.urlId])) + ) { + this.redundantFailover(this.currentLevelIndex); + return; + } + + var levelError = false; + var levelSwitch = true; + var levelIndex; // try to recover not fatal errors + + switch (data.details) { + case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].FRAG_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].FRAG_LOAD_TIMEOUT: + case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].KEY_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].KEY_LOAD_TIMEOUT: + if (data.frag) { + var _level = this._levels[data.frag.level]; // Set levelIndex when we're out of fragment retries + + if (_level) { + _level.fragmentError++; + + if (_level.fragmentError > this.CiderHls.config.fragLoadingMaxRetry) { + levelIndex = data.frag.level; + } + } else { + levelIndex = data.frag.level; + } + } + + break; + + case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_TIMEOUT: + // Do not perform level switch if an error occurred using delivery directives + // Attempt to reload level without directives first + if (context) { + if (context.deliveryDirectives) { + levelSwitch = false; + } + + levelIndex = context.level; + } + + levelError = true; + break; + + case _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].REMUX_ALLOC_ERROR: + levelIndex = data.level; + levelError = true; + break; + } + + if (levelIndex !== undefined) { + this.recoverLevel(data, levelIndex, levelError, levelSwitch); + } + }; + /** + * Switch to a redundant stream if any available. + * If redundant stream is not available, emergency switch down if ABR mode is enabled. + */ + + _proto.recoverLevel = function recoverLevel(errorEvent, levelIndex, levelError, levelSwitch) { + var errorDetails = errorEvent.details; + var level = this._levels[levelIndex]; + level.loadError++; + + if (levelError) { + var retrying = this.retryLoadingOrFail(errorEvent); + + if (retrying) { + // boolean used to inform stream controller not to switch back to IDLE on non fatal error + errorEvent.levelRetry = true; + } else { + this.currentLevelIndex = -1; + return; + } + } + + if (levelSwitch) { + var redundantLevels = level.url.length; // Try redundant fail-over until level.loadError reaches redundantLevels + + if (redundantLevels > 1 && level.loadError < redundantLevels) { + errorEvent.levelRetry = true; + this.redundantFailover(levelIndex); + } else if (this.manualLevelIndex === -1) { + // Search for available level in auto level selection mode, cycling from highest to lowest bitrate + var nextLevel = levelIndex === 0 ? this._levels.length - 1 : levelIndex - 1; + + if (this.currentLevelIndex !== nextLevel && this._levels[nextLevel].loadError === 0) { + this.warn(errorDetails + ": switch to " + nextLevel); + errorEvent.levelRetry = true; + this.CiderHls.nextAutoLevel = nextLevel; + } + } + } + }; + + _proto.redundantFailover = function redundantFailover(levelIndex) { + var level = this._levels[levelIndex]; + var redundantLevels = level.url.length; + + if (redundantLevels > 1) { + // Update the url id of all levels so that we stay on the same set of variants when level switching + var newUrlId = (level.urlId + 1) % redundantLevels; + this.warn("Switching to redundant URL-id " + newUrlId); + + this._levels.forEach(function (level) { + level.urlId = newUrlId; + }); + + this.level = levelIndex; + } + }; // reset errors on the successful load of a fragment + + _proto.onFragLoaded = function onFragLoaded(event, _ref3) { + var frag = _ref3.frag; + + if (frag !== undefined && frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN) { + var level = this._levels[frag.level]; + + if (level !== undefined) { + level.fragmentError = 0; + level.loadError = 0; + } + } + }; + + _proto.onLevelLoaded = function onLevelLoaded(event, data) { + var _data$deliveryDirecti2; + + var level = data.level, + details = data.details; + var curLevel = this._levels[level]; + + if (!curLevel) { + var _data$deliveryDirecti; + + this.warn("Invalid level index " + level); + + if ((_data$deliveryDirecti = data.deliveryDirectives) !== null && _data$deliveryDirecti !== void 0 && _data$deliveryDirecti.skip) { + details.deltaUpdateFailed = true; + } + + return; + } // only process level loaded events matching with expected level + + if (level === this.currentLevelIndex) { + // reset level load error counter on successful level loaded only if there is no issues with fragments + if (curLevel.fragmentError === 0) { + curLevel.loadError = 0; + this.retryCount = 0; + } + + this.playlistLoaded(level, data, curLevel.details); + } else if ((_data$deliveryDirecti2 = data.deliveryDirectives) !== null && _data$deliveryDirecti2 !== void 0 && _data$deliveryDirecti2.skip) { + // received a delta playlist update that cannot be merged + details.deltaUpdateFailed = true; + } + }; + + _proto.onAudioTrackSwitched = function onAudioTrackSwitched(event, data) { + var currentLevel = this.CiderHls.levels[this.currentLevelIndex]; + + if (!currentLevel) { + return; + } + + if (currentLevel.audioGroupIds) { + var urlId = -1; + var audioGroupId = this.CiderHls.audioTracks[data.id].groupId; + + for (var i = 0; i < currentLevel.audioGroupIds.length; i++) { + if (currentLevel.audioGroupIds[i] === audioGroupId) { + urlId = i; + break; + } + } + + if (urlId !== currentLevel.urlId) { + currentLevel.urlId = urlId; + this.startLoad(); + } + } + }; + + _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) { + var level = this.currentLevelIndex; + var currentLevel = this._levels[level]; + + if (this.canLoad && currentLevel && currentLevel.url.length > 0) { + var id = currentLevel.urlId; + var url = currentLevel.url[id]; + + if (CiderHlsUrlParameters) { + try { + url = CiderHlsUrlParameters.addDirectives(url); + } catch (error) { + this.warn("Could not construct new URL with CiderHls Delivery Directives: " + error); + } + } + + this.log("Attempt loading level index " + level + (CiderHlsUrlParameters ? " at sn " + CiderHlsUrlParameters.msn + " part " + CiderHlsUrlParameters.part : "") + " with URL-id " + id + " " + url); // console.log('Current audio track group ID:', this.CiderHls.audioTracks[this.CiderHls.audioTrack].groupId); + // console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level); + + this.clearTimer(); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADING, { + url: url, + level: level, + id: id, + deliveryDirectives: CiderHlsUrlParameters || null, + }); + } + }; + + _proto.removeLevel = function removeLevel(levelIndex, urlId) { + var filterLevelAndGroupByIdIndex = function filterLevelAndGroupByIdIndex(url, id) { + return id !== urlId; + }; + + var levels = this._levels + .filter(function (level, index) { + if (index !== levelIndex) { + return true; + } + + if (level.url.length > 1 && urlId !== undefined) { + level.url = level.url.filter(filterLevelAndGroupByIdIndex); + + if (level.audioGroupIds) { + level.audioGroupIds = level.audioGroupIds.filter(filterLevelAndGroupByIdIndex); + } + + if (level.textGroupIds) { + level.textGroupIds = level.textGroupIds.filter(filterLevelAndGroupByIdIndex); + } + + level.urlId = 0; + return true; + } + + return false; + }) + .map(function (level, index) { + var details = level.details; + + if (details !== null && details !== void 0 && details.fragments) { + details.fragments.forEach(function (fragment) { + fragment.level = index; + }); + } + + return level; + }); + + this._levels = levels; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVELS_UPDATED, { + levels: levels, + }); + }; + + _createClass(LevelController, [ + { + key: "levels", + get: function get() { + if (this._levels.length === 0) { + return null; + } + + return this._levels; + }, + }, + { + key: "level", + get: function get() { + return this.currentLevelIndex; + }, + set: function set(newLevel) { + var _levels$newLevel; + + var levels = this._levels; + + if (levels.length === 0) { + return; + } + + if (this.currentLevelIndex === newLevel && (_levels$newLevel = levels[newLevel]) !== null && _levels$newLevel !== void 0 && _levels$newLevel.details) { + return; + } // check if level idx is valid + + if (newLevel < 0 || newLevel >= levels.length) { + // invalid level id given, trigger error + var fatal = newLevel < 0; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].OTHER_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_SWITCH_ERROR, + level: newLevel, + fatal: fatal, + reason: "invalid level idx", + }); + + if (fatal) { + return; + } + + newLevel = Math.min(newLevel, levels.length - 1); + } // stopping live reloading timer if any + + this.clearTimer(); + var lastLevelIndex = this.currentLevelIndex; + var lastLevel = levels[lastLevelIndex]; + var level = levels[newLevel]; + this.log("switching to level " + newLevel + " from " + lastLevelIndex); + this.currentLevelIndex = newLevel; + + var levelSwitchingData = _extends({}, level, { + level: newLevel, + maxBitrate: level.maxBitrate, + uri: level.uri, + urlId: level.urlId, + }); // @ts-ignore + + delete levelSwitchingData._urlId; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_SWITCHING, levelSwitchingData); // check if we need to load playlist for this level + + var levelDetails = level.details; + + if (!levelDetails || levelDetails.live) { + // level not retrieved yet, or live playlist we need to (re)load it + var CiderHlsUrlParameters = this.switchParams(level.uri, lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.details); + this.loadPlaylist(CiderHlsUrlParameters); + } + }, + }, + { + key: "manualLevel", + get: function get() { + return this.manualLevelIndex; + }, + set: function set(newLevel) { + this.manualLevelIndex = newLevel; + + if (this._startLevel === undefined) { + this._startLevel = newLevel; + } + + if (newLevel !== -1) { + this.level = newLevel; + } + }, + }, + { + key: "firstLevel", + get: function get() { + return this._firstLevel; + }, + set: function set(newLevel) { + this._firstLevel = newLevel; + }, + }, + { + key: "startLevel", + get: function get() { + // CiderHls.startLevel takes precedence over config.startLevel + // if none of these values are defined, fallback on this._firstLevel (first quality level appearing in variant manifest) + if (this._startLevel === undefined) { + var configStartLevel = this.CiderHls.config.startLevel; + + if (configStartLevel !== undefined) { + return configStartLevel; + } else { + return this._firstLevel; + } + } else { + return this._startLevel; + } + }, + set: function set(newLevel) { + this._startLevel = newLevel; + }, + }, + { + key: "nextLoadLevel", + get: function get() { + if (this.manualLevelIndex !== -1) { + return this.manualLevelIndex; + } else { + return this.CiderHls.nextAutoLevel; + } + }, + set: function set(nextLevel) { + this.level = nextLevel; + + if (this.manualLevelIndex === -1) { + this.CiderHls.nextAutoLevel = nextLevel; + } + }, + }, + ]); + + return LevelController; + })(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__["default"]); + + /***/ + }, + + /***/ "./src/controller/level-helper.ts": + /*!****************************************!*\ !*** ./src/controller/level-helper.ts ***! \****************************************/ -/*! exports provided: addGroupId, assignTrackIdsByGroup, updatePTS, updateFragPTSDTS, mergeDetails, mapPartIntersection, mapFragmentIntersection, adjustSliding, addSliding, computeReloadInterval, getFragmentWithSN, getPartWith */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addGroupId", function() { return addGroupId; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "assignTrackIdsByGroup", function() { return assignTrackIdsByGroup; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updatePTS", function() { return updatePTS; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateFragPTSDTS", function() { return updateFragPTSDTS; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeDetails", function() { return mergeDetails; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapPartIntersection", function() { return mapPartIntersection; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapFragmentIntersection", function() { return mapFragmentIntersection; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "adjustSliding", function() { return adjustSliding; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addSliding", function() { return addSliding; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "computeReloadInterval", function() { return computeReloadInterval; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getFragmentWithSN", function() { return getFragmentWithSN; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPartWith", function() { return getPartWith; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - - - - - - -/** - * @module LevelHelper - * Providing methods dealing with playlist sliding and drift - * */ - -function addGroupId(level, type, id) { - switch (type) { - case 'audio': - if (!level.audioGroupIds) { - level.audioGroupIds = []; - } - - level.audioGroupIds.push(id); - break; - - case 'text': - if (!level.textGroupIds) { - level.textGroupIds = []; - } - - level.textGroupIds.push(id); - break; - } -} -function assignTrackIdsByGroup(tracks) { - var groups = {}; - tracks.forEach(function (track) { - var groupId = track.groupId || ''; - track.id = groups[groupId] = groups[groupId] || 0; - groups[groupId]++; - }); -} -function updatePTS(fragments, fromIdx, toIdx) { - var fragFrom = fragments[fromIdx]; - var fragTo = fragments[toIdx]; - updateFromToPTS(fragFrom, fragTo); -} - -function updateFromToPTS(fragFrom, fragTo) { - var fragToPTS = fragTo.startPTS; // if we know startPTS[toIdx] - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(fragToPTS)) { - // update fragment duration. - // it helps to fix drifts between playlist reported duration and fragment real duration - var duration = 0; - var frag; - - if (fragTo.sn > fragFrom.sn) { - duration = fragToPTS - fragFrom.start; - frag = fragFrom; - } else { - duration = fragFrom.start - fragToPTS; - frag = fragTo; - } // TODO? Drift can go either way, or the playlist could be completely accurate - // console.assert(duration > 0, - // `duration of ${duration} computed for frag ${frag.sn}, level ${frag.level}, there should be some duration drift between playlist and fragment!`); - - - if (frag.duration !== duration) { - frag.duration = duration; - } // we dont know startPTS[toIdx] - - } else if (fragTo.sn > fragFrom.sn) { - var contiguous = fragFrom.cc === fragTo.cc; // TODO: With part-loading end/durations we need to confirm the whole fragment is loaded before using (or setting) minEndPTS - - if (contiguous && fragFrom.minEndPTS) { - fragTo.start = fragFrom.start + (fragFrom.minEndPTS - fragFrom.start); - } else { - fragTo.start = fragFrom.start + fragFrom.duration; - } - } else { - fragTo.start = Math.max(fragFrom.start - fragTo.duration, 0); - } -} - -function updateFragPTSDTS(details, frag, startPTS, endPTS, startDTS, endDTS) { - var parsedMediaDuration = endPTS - startPTS; - - if (parsedMediaDuration <= 0) { - _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn('Fragment should have a positive duration', frag); - endPTS = startPTS + frag.duration; - endDTS = startDTS + frag.duration; - } - - var maxStartPTS = startPTS; - var minEndPTS = endPTS; - var fragStartPts = frag.startPTS; - var fragEndPts = frag.endPTS; - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(fragStartPts)) { - // delta PTS between audio and video - var deltaPTS = Math.abs(fragStartPts - startPTS); - - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.deltaPTS)) { - frag.deltaPTS = deltaPTS; - } else { - frag.deltaPTS = Math.max(deltaPTS, frag.deltaPTS); - } - - maxStartPTS = Math.max(startPTS, fragStartPts); - startPTS = Math.min(startPTS, fragStartPts); - startDTS = Math.min(startDTS, frag.startDTS); - minEndPTS = Math.min(endPTS, fragEndPts); - endPTS = Math.max(endPTS, fragEndPts); - endDTS = Math.max(endDTS, frag.endDTS); - } - - frag.duration = endPTS - startPTS; - var drift = startPTS - frag.start; - frag.appendedPTS = endPTS; - frag.start = frag.startPTS = startPTS; - frag.maxStartPTS = maxStartPTS; - frag.startDTS = startDTS; - frag.endPTS = endPTS; - frag.minEndPTS = minEndPTS; - frag.endDTS = endDTS; - var sn = frag.sn; // 'initSegment' - // exit if sn out of range - - if (!details || sn < details.startSN || sn > details.endSN) { - return 0; - } - - var i; - var fragIdx = sn - details.startSN; - var fragments = details.fragments; // update frag reference in fragments array - // rationale is that fragments array might not contain this frag object. - // this will happen if playlist has been refreshed between frag loading and call to updateFragPTSDTS() - // if we don't update frag, we won't be able to propagate PTS info on the playlist - // resulting in invalid sliding computation - - fragments[fragIdx] = frag; // adjust fragment PTS/duration from seqnum-1 to frag 0 - - for (i = fragIdx; i > 0; i--) { - updateFromToPTS(fragments[i], fragments[i - 1]); - } // adjust fragment PTS/duration from seqnum to last frag - - - for (i = fragIdx; i < fragments.length - 1; i++) { - updateFromToPTS(fragments[i], fragments[i + 1]); - } - - if (details.fragmentHint) { - updateFromToPTS(fragments[fragments.length - 1], details.fragmentHint); - } - - details.PTSKnown = details.alignedSliding = true; - return drift; -} -function mergeDetails(oldDetails, newDetails) { - // Track the last initSegment processed. Initialize it to the last one on the timeline. - var currentInitSegment = null; - var oldFragments = oldDetails.fragments; - - for (var i = oldFragments.length - 1; i >= 0; i--) { - var oldInit = oldFragments[i].initSegment; - - if (oldInit) { - currentInitSegment = oldInit; - break; - } - } - - if (oldDetails.fragmentHint) { - // prevent PTS and duration from being adjusted on the next hint - delete oldDetails.fragmentHint.endPTS; - } // check if old/new playlists have fragments in common - // loop through overlapping SN and update startPTS , cc, and duration if any found - - - var ccOffset = 0; - var PTSFrag; - mapFragmentIntersection(oldDetails, newDetails, function (oldFrag, newFrag) { - if (oldFrag.relurl) { - // Do not compare CC if the old fragment has no url. This is a level.fragmentHint used by LL-CiderHls parts. - // It maybe be off by 1 if it was created before any parts or discontinuity tags were appended to the end - // of the playlist. - ccOffset = oldFrag.cc - newFrag.cc; - } - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.startPTS) && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.endPTS)) { - newFrag.start = newFrag.startPTS = oldFrag.startPTS; - newFrag.startDTS = oldFrag.startDTS; - newFrag.appendedPTS = oldFrag.appendedPTS; - newFrag.maxStartPTS = oldFrag.maxStartPTS; - newFrag.endPTS = oldFrag.endPTS; - newFrag.endDTS = oldFrag.endDTS; - newFrag.minEndPTS = oldFrag.minEndPTS; - newFrag.duration = oldFrag.endPTS - oldFrag.startPTS; - - if (newFrag.duration) { - PTSFrag = newFrag; - } // PTS is known when any segment has startPTS and endPTS - - - newDetails.PTSKnown = newDetails.alignedSliding = true; - } - - newFrag.elementaryStreams = oldFrag.elementaryStreams; - newFrag.loader = oldFrag.loader; - newFrag.stats = oldFrag.stats; - newFrag.urlId = oldFrag.urlId; - - if (oldFrag.initSegment) { - newFrag.initSegment = oldFrag.initSegment; - currentInitSegment = oldFrag.initSegment; - } - }); - - if (currentInitSegment) { - var fragmentsToCheck = newDetails.fragmentHint ? newDetails.fragments.concat(newDetails.fragmentHint) : newDetails.fragments; - fragmentsToCheck.forEach(function (frag) { - var _currentInitSegment; - - if (!frag.initSegment || frag.initSegment.relurl === ((_currentInitSegment = currentInitSegment) === null || _currentInitSegment === void 0 ? void 0 : _currentInitSegment.relurl)) { - frag.initSegment = currentInitSegment; - } - }); - } - - if (newDetails.skippedSegments) { - newDetails.deltaUpdateFailed = newDetails.fragments.some(function (frag) { - return !frag; - }); - - if (newDetails.deltaUpdateFailed) { - _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn('[level-helper] Previous playlist missing segments skipped in delta playlist'); - - for (var _i = newDetails.skippedSegments; _i--;) { - newDetails.fragments.shift(); - } - - newDetails.startSN = newDetails.fragments[0].sn; - newDetails.startCC = newDetails.fragments[0].cc; - } - } - - var newFragments = newDetails.fragments; - - if (ccOffset) { - _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn('discontinuity sliding from playlist, take drift into account'); - - for (var _i2 = 0; _i2 < newFragments.length; _i2++) { - newFragments[_i2].cc += ccOffset; - } - } - - if (newDetails.skippedSegments) { - newDetails.startCC = newDetails.fragments[0].cc; - } // Merge parts - - - mapPartIntersection(oldDetails.partList, newDetails.partList, function (oldPart, newPart) { - newPart.elementaryStreams = oldPart.elementaryStreams; - newPart.stats = oldPart.stats; - }); // if at least one fragment contains PTS info, recompute PTS information for all fragments - - if (PTSFrag) { - updateFragPTSDTS(newDetails, PTSFrag, PTSFrag.startPTS, PTSFrag.endPTS, PTSFrag.startDTS, PTSFrag.endDTS); - } else { - // ensure that delta is within oldFragments range - // also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61]) - // in that case we also need to adjust start offset of all fragments - adjustSliding(oldDetails, newDetails); - } - - if (newFragments.length) { - newDetails.totalduration = newDetails.edge - newFragments[0].start; - } - - newDetails.driftStartTime = oldDetails.driftStartTime; - newDetails.driftStart = oldDetails.driftStart; - var advancedDateTime = newDetails.advancedDateTime; - - if (newDetails.advanced && advancedDateTime) { - var edge = newDetails.edge; - - if (!newDetails.driftStart) { - newDetails.driftStartTime = advancedDateTime; - newDetails.driftStart = edge; - } - - newDetails.driftEndTime = advancedDateTime; - newDetails.driftEnd = edge; - } else { - newDetails.driftEndTime = oldDetails.driftEndTime; - newDetails.driftEnd = oldDetails.driftEnd; - newDetails.advancedDateTime = oldDetails.advancedDateTime; - } -} -function mapPartIntersection(oldParts, newParts, intersectionFn) { - if (oldParts && newParts) { - var delta = 0; - - for (var i = 0, len = oldParts.length; i <= len; i++) { - var _oldPart = oldParts[i]; - var _newPart = newParts[i + delta]; - - if (_oldPart && _newPart && _oldPart.index === _newPart.index && _oldPart.fragment.sn === _newPart.fragment.sn) { - intersectionFn(_oldPart, _newPart); - } else { - delta--; - } - } - } -} -function mapFragmentIntersection(oldDetails, newDetails, intersectionFn) { - var skippedSegments = newDetails.skippedSegments; - var start = Math.max(oldDetails.startSN, newDetails.startSN) - newDetails.startSN; - var end = (oldDetails.fragmentHint ? 1 : 0) + (skippedSegments ? newDetails.endSN : Math.min(oldDetails.endSN, newDetails.endSN)) - newDetails.startSN; - var delta = newDetails.startSN - oldDetails.startSN; - var newFrags = newDetails.fragmentHint ? newDetails.fragments.concat(newDetails.fragmentHint) : newDetails.fragments; - var oldFrags = oldDetails.fragmentHint ? oldDetails.fragments.concat(oldDetails.fragmentHint) : oldDetails.fragments; - - for (var i = start; i <= end; i++) { - var _oldFrag = oldFrags[delta + i]; - var _newFrag = newFrags[i]; - - if (skippedSegments && !_newFrag && i < skippedSegments) { - // Fill in skipped segments in delta playlist - _newFrag = newDetails.fragments[i] = _oldFrag; - } - - if (_oldFrag && _newFrag) { - intersectionFn(_oldFrag, _newFrag); - } - } -} -function adjustSliding(oldDetails, newDetails) { - var delta = newDetails.startSN + newDetails.skippedSegments - oldDetails.startSN; - var oldFragments = oldDetails.fragments; - - if (delta < 0 || delta >= oldFragments.length) { - return; - } - - addSliding(newDetails, oldFragments[delta].start); -} -function addSliding(details, start) { - if (start) { - var fragments = details.fragments; - - for (var i = details.skippedSegments; i < fragments.length; i++) { - fragments[i].start += start; - } - - if (details.fragmentHint) { - details.fragmentHint.start += start; - } - } -} -function computeReloadInterval(newDetails, stats) { - var reloadInterval = 1000 * newDetails.levelTargetDuration; - var reloadIntervalAfterMiss = reloadInterval / 2; - var timeSinceLastModified = newDetails.age; - var useLastModified = timeSinceLastModified > 0 && timeSinceLastModified < reloadInterval * 3; - var roundTrip = stats.loading.end - stats.loading.start; - var estimatedTimeUntilUpdate; - var availabilityDelay = newDetails.availabilityDelay; // let estimate = 'average'; - - if (newDetails.updated === false) { - if (useLastModified) { - // estimate = 'miss round trip'; - // We should have had a hit so try again in the time it takes to get a response, - // but no less than 1/3 second. - var minRetry = 333 * newDetails.misses; - estimatedTimeUntilUpdate = Math.max(Math.min(reloadIntervalAfterMiss, roundTrip * 2), minRetry); - newDetails.availabilityDelay = (newDetails.availabilityDelay || 0) + estimatedTimeUntilUpdate; - } else { - // estimate = 'miss half average'; - // follow CiderHls Spec, If the client reloads a Playlist file and finds that it has not - // changed then it MUST wait for a period of one-half the target - // duration before retrying. - estimatedTimeUntilUpdate = reloadIntervalAfterMiss; - } - } else if (useLastModified) { - // estimate = 'next modified date'; - // Get the closest we've been to timeSinceLastModified on update - availabilityDelay = Math.min(availabilityDelay || reloadInterval / 2, timeSinceLastModified); - newDetails.availabilityDelay = availabilityDelay; - estimatedTimeUntilUpdate = availabilityDelay + reloadInterval - timeSinceLastModified; - } else { - estimatedTimeUntilUpdate = reloadInterval - roundTrip; - } // console.log(`[computeReloadInterval] live reload ${newDetails.updated ? 'REFRESHED' : 'MISSED'}`, - // '\n method', estimate, - // '\n estimated time until update =>', estimatedTimeUntilUpdate, - // '\n average target duration', reloadInterval, - // '\n time since modified', timeSinceLastModified, - // '\n time round trip', roundTrip, - // '\n availability delay', availabilityDelay); - - - return Math.round(estimatedTimeUntilUpdate); -} -function getFragmentWithSN(level, sn, fragCurrent) { - if (!level || !level.details) { - return null; - } - - var levelDetails = level.details; - var fragment = levelDetails.fragments[sn - levelDetails.startSN]; - - if (fragment) { - return fragment; - } - - fragment = levelDetails.fragmentHint; - - if (fragment && fragment.sn === sn) { - return fragment; - } - - if (sn < levelDetails.startSN && fragCurrent && fragCurrent.sn === sn) { - return fragCurrent; - } - - return null; -} -function getPartWith(level, sn, partIndex) { - if (!level || !level.details) { - return null; - } - - var partList = level.details.partList; - - if (partList) { - for (var i = partList.length; i--;) { - var part = partList[i]; - - if (part.index === partIndex && part.fragment.sn === sn) { - return part; - } - } - } - - return null; -} - -/***/ }), - -/***/ "./src/controller/stream-controller.ts": -/*!*********************************************!*\ - !*** ./src/controller/stream-controller.ts ***! - \*********************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return StreamController; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts"); -/* harmony import */ var _is_supported__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../is-supported */ "./src/is-supported.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -/* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); -/* harmony import */ var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../demux/transmuxer-interface */ "./src/demux/transmuxer-interface.ts"); -/* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts"); -/* harmony import */ var _gap_controller__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./gap-controller */ "./src/controller/gap-controller.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - - - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - - - - - - - - - - - - - -var TICK_INTERVAL = 100; // how often to tick in ms - -var StreamController = /*#__PURE__*/function (_BaseStreamController) { - _inheritsLoose(StreamController, _BaseStreamController); - - function StreamController(CiderHls, fragmentTracker) { - var _this; - - _this = _BaseStreamController.call(this, CiderHls, fragmentTracker, '[stream-controller]') || this; - _this.audioCodecSwap = false; - _this.gapController = null; - _this.level = -1; - _this._forceStartLoad = false; - _this.altAudio = false; - _this.audioOnly = false; - _this.fragPlaying = null; - _this.onvplaying = null; - _this.onvseeked = null; - _this.fragLastKbps = 0; - _this.stalled = false; - _this.couldBacktrack = false; - _this.audioCodecSwitch = false; - _this.videoBuffer = null; - - _this._registerListeners(); - - return _this; - } - - var _proto = StreamController.prototype; - - _proto._registerListeners = function _registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_LOADING, this.onLevelLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, this.onError, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_CREATED, this.onBufferCreated, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVELS_UPDATED, this.onLevelsUpdated, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - }; - - _proto._unregisterListeners = function _unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, this.onError, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_CREATED, this.onBufferCreated, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVELS_UPDATED, this.onLevelsUpdated, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); - }; - - _proto.onHandlerDestroying = function onHandlerDestroying() { - this._unregisterListeners(); - - this.onMediaDetaching(); - }; - - _proto.startLoad = function startLoad(startPosition) { - if (this.levels) { - var lastCurrentTime = this.lastCurrentTime, - CiderHls = this.CiderHls; - this.stopLoad(); - this.setInterval(TICK_INTERVAL); - this.level = -1; - this.fragLoadError = 0; - - if (!this.startFragRequested) { - // determine load level - var startLevel = CiderHls.startLevel; - - if (startLevel === -1) { - if (CiderHls.config.testBandwidth) { - // -1 : guess start Level by doing a bitrate test by loading first fragment of lowest quality level - startLevel = 0; - this.bitrateTest = true; - } else { - startLevel = CiderHls.nextAutoLevel; - } - } // set new level to playlist loader : this will trigger start level load - // CiderHls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded - - - this.level = CiderHls.nextLoadLevel = startLevel; - this.loadedmetadata = false; - } // if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime - - - if (lastCurrentTime > 0 && startPosition === -1) { - this.log("Override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3)); - startPosition = lastCurrentTime; - } - - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition; - this.tick(); - } else { - this._forceStartLoad = true; - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED; - } - }; - - _proto.stopLoad = function stopLoad() { - this._forceStartLoad = false; - - _BaseStreamController.prototype.stopLoad.call(this); - }; - - _proto.doTick = function doTick() { - switch (this.state) { - case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE: - this.doTickIdle(); - break; - - case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL: - { - var _levels$level; - - var levels = this.levels, - level = this.level; - var details = levels === null || levels === void 0 ? void 0 : (_levels$level = levels[level]) === null || _levels$level === void 0 ? void 0 : _levels$level.details; - - if (details && (!details.live || this.levelLastLoaded === this.level)) { - if (this.waitForCdnTuneIn(details)) { - break; + /*! exports provided: addGroupId, assignTrackIdsByGroup, updatePTS, updateFragPTSDTS, mergeDetails, mapPartIntersection, mapFragmentIntersection, adjustSliding, addSliding, computeReloadInterval, getFragmentWithSN, getPartWith */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addGroupId", function () { + return addGroupId; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "assignTrackIdsByGroup", function () { + return assignTrackIdsByGroup; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updatePTS", function () { + return updatePTS; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateFragPTSDTS", function () { + return updateFragPTSDTS; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeDetails", function () { + return mergeDetails; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapPartIntersection", function () { + return mapPartIntersection; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapFragmentIntersection", function () { + return mapFragmentIntersection; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "adjustSliding", function () { + return adjustSliding; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addSliding", function () { + return addSliding; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "computeReloadInterval", function () { + return computeReloadInterval; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getFragmentWithSN", function () { + return getFragmentWithSN; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPartWith", function () { + return getPartWith; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + + /** + * @module LevelHelper + * Providing methods dealing with playlist sliding and drift + * */ + + function addGroupId(level, type, id) { + switch (type) { + case "audio": + if (!level.audioGroupIds) { + level.audioGroupIds = []; + } + + level.audioGroupIds.push(id); + break; + + case "text": + if (!level.textGroupIds) { + level.textGroupIds = []; + } + + level.textGroupIds.push(id); + break; + } + } + function assignTrackIdsByGroup(tracks) { + var groups = {}; + tracks.forEach(function (track) { + var groupId = track.groupId || ""; + track.id = groups[groupId] = groups[groupId] || 0; + groups[groupId]++; + }); + } + function updatePTS(fragments, fromIdx, toIdx) { + var fragFrom = fragments[fromIdx]; + var fragTo = fragments[toIdx]; + updateFromToPTS(fragFrom, fragTo); } - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - break; - } + function updateFromToPTS(fragFrom, fragTo) { + var fragToPTS = fragTo.startPTS; // if we know startPTS[toIdx] - break; - } + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(fragToPTS)) { + // update fragment duration. + // it helps to fix drifts between playlist reported duration and fragment real duration + var duration = 0; + var frag; - case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING_WAITING_RETRY: - { - var _this$media; + if (fragTo.sn > fragFrom.sn) { + duration = fragToPTS - fragFrom.start; + frag = fragFrom; + } else { + duration = fragFrom.start - fragToPTS; + frag = fragTo; + } // TODO? Drift can go either way, or the playlist could be completely accurate + // console.assert(duration > 0, + // `duration of ${duration} computed for frag ${frag.sn}, level ${frag.level}, there should be some duration drift between playlist and fragment!`); - var now = self.performance.now(); - var retryDate = this.retryDate; // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading + if (frag.duration !== duration) { + frag.duration = duration; + } // we dont know startPTS[toIdx] + } else if (fragTo.sn > fragFrom.sn) { + var contiguous = fragFrom.cc === fragTo.cc; // TODO: With part-loading end/durations we need to confirm the whole fragment is loaded before using (or setting) minEndPTS - if (!retryDate || now >= retryDate || (_this$media = this.media) !== null && _this$media !== void 0 && _this$media.seeking) { - this.log('retryDate reached, switch back to IDLE state'); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - } - break; + if (contiguous && fragFrom.minEndPTS) { + fragTo.start = fragFrom.start + (fragFrom.minEndPTS - fragFrom.start); + } else { + fragTo.start = fragFrom.start + fragFrom.duration; + } + } else { + fragTo.start = Math.max(fragFrom.start - fragTo.duration, 0); + } + } - default: - break; - } // check buffer - // check/update current fragment + function updateFragPTSDTS(details, frag, startPTS, endPTS, startDTS, endDTS) { + var parsedMediaDuration = endPTS - startPTS; + if (parsedMediaDuration <= 0) { + _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn("Fragment should have a positive duration", frag); + endPTS = startPTS + frag.duration; + endDTS = startDTS + frag.duration; + } - this.onTickEnd(); - }; + var maxStartPTS = startPTS; + var minEndPTS = endPTS; + var fragStartPts = frag.startPTS; + var fragEndPts = frag.endPTS; - _proto.onTickEnd = function onTickEnd() { - _BaseStreamController.prototype.onTickEnd.call(this); + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(fragStartPts)) { + // delta PTS between audio and video + var deltaPTS = Math.abs(fragStartPts - startPTS); - this.checkBuffer(); - this.checkFragmentChanged(); - }; + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.deltaPTS)) { + frag.deltaPTS = deltaPTS; + } else { + frag.deltaPTS = Math.max(deltaPTS, frag.deltaPTS); + } - _proto.doTickIdle = function doTickIdle() { - var _frag$decryptdata, _frag$decryptdata2; + maxStartPTS = Math.max(startPTS, fragStartPts); + startPTS = Math.min(startPTS, fragStartPts); + startDTS = Math.min(startDTS, frag.startDTS); + minEndPTS = Math.min(endPTS, fragEndPts); + endPTS = Math.max(endPTS, fragEndPts); + endDTS = Math.max(endDTS, frag.endDTS); + } - var CiderHls = this.CiderHls, - levelLastLoaded = this.levelLastLoaded, - levels = this.levels, - media = this.media; - var config = CiderHls.config, - level = CiderHls.nextLoadLevel; // if start level not parsed yet OR - // if video not attached AND start fragment already requested OR start frag prefetch not enabled - // exit loop, as we either need more info (level not parsed) or we need media to be attached to load new fragment + frag.duration = endPTS - startPTS; + var drift = startPTS - frag.start; + frag.appendedPTS = endPTS; + frag.start = frag.startPTS = startPTS; + frag.maxStartPTS = maxStartPTS; + frag.startDTS = startDTS; + frag.endPTS = endPTS; + frag.minEndPTS = minEndPTS; + frag.endDTS = endDTS; + var sn = frag.sn; // 'initSegment' + // exit if sn out of range - if (levelLastLoaded === null || !media && (this.startFragRequested || !config.startFragPrefetch)) { - return; - } // If the "main" level is audio-only but we are loading an alternate track in the same group, do not load anything + if (!details || sn < details.startSN || sn > details.endSN) { + return 0; + } + var i; + var fragIdx = sn - details.startSN; + var fragments = details.fragments; // update frag reference in fragments array + // rationale is that fragments array might not contain this frag object. + // this will happen if playlist has been refreshed between frag loading and call to updateFragPTSDTS() + // if we don't update frag, we won't be able to propagate PTS info on the playlist + // resulting in invalid sliding computation - if (this.altAudio && this.audioOnly) { - return; - } + fragments[fragIdx] = frag; // adjust fragment PTS/duration from seqnum-1 to frag 0 - if (!levels || !levels[level]) { - return; - } + for (i = fragIdx; i > 0; i--) { + updateFromToPTS(fragments[i], fragments[i - 1]); + } // adjust fragment PTS/duration from seqnum to last frag - var levelInfo = levels[level]; // if buffer length is less than maxBufLen try to load a new fragment - // set next load level : this will trigger a playlist load if needed + for (i = fragIdx; i < fragments.length - 1; i++) { + updateFromToPTS(fragments[i], fragments[i + 1]); + } - this.level = CiderHls.nextLoadLevel = level; - var levelDetails = levelInfo.details; // if level info not retrieved yet, switch state and wait for level retrieval - // if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load - // a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist) + if (details.fragmentHint) { + updateFromToPTS(fragments[fragments.length - 1], details.fragmentHint); + } - if (!levelDetails || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL || levelDetails.live && this.levelLastLoaded !== level) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL; - return; - } + details.PTSKnown = details.alignedSliding = true; + return drift; + } + function mergeDetails(oldDetails, newDetails) { + // Track the last initSegment processed. Initialize it to the last one on the timeline. + var currentInitSegment = null; + var oldFragments = oldDetails.fragments; - var bufferInfo = this.getFwdBufferInfo(this.mediaBuffer ? this.mediaBuffer : media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + for (var i = oldFragments.length - 1; i >= 0; i--) { + var oldInit = oldFragments[i].initSegment; - if (bufferInfo === null) { - return; - } + if (oldInit) { + currentInitSegment = oldInit; + break; + } + } - var bufferLen = bufferInfo.len; // compute max Buffer Length that we could get from this load level, based on level bitrate. don't buffer more than 60 MB and more than 30s + if (oldDetails.fragmentHint) { + // prevent PTS and duration from being adjusted on the next hint + delete oldDetails.fragmentHint.endPTS; + } // check if old/new playlists have fragments in common + // loop through overlapping SN and update startPTS , cc, and duration if any found - var maxBufLen = this.getMaxBufferLength(levelInfo.maxBitrate); // Stay idle if we are still with buffer margins + var ccOffset = 0; + var PTSFrag; + mapFragmentIntersection(oldDetails, newDetails, function (oldFrag, newFrag) { + if (oldFrag.relurl) { + // Do not compare CC if the old fragment has no url. This is a level.fragmentHint used by LL-CiderHls parts. + // It maybe be off by 1 if it was created before any parts or discontinuity tags were appended to the end + // of the playlist. + ccOffset = oldFrag.cc - newFrag.cc; + } - if (bufferLen >= maxBufLen) { - return; - } + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.startPTS) && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.endPTS)) { + newFrag.start = newFrag.startPTS = oldFrag.startPTS; + newFrag.startDTS = oldFrag.startDTS; + newFrag.appendedPTS = oldFrag.appendedPTS; + newFrag.maxStartPTS = oldFrag.maxStartPTS; + newFrag.endPTS = oldFrag.endPTS; + newFrag.endDTS = oldFrag.endDTS; + newFrag.minEndPTS = oldFrag.minEndPTS; + newFrag.duration = oldFrag.endPTS - oldFrag.startPTS; - if (this._streamEnded(bufferInfo, levelDetails)) { - var data = {}; + if (newFrag.duration) { + PTSFrag = newFrag; + } // PTS is known when any segment has startPTS and endPTS - if (this.altAudio) { - data.type = 'video'; - } + newDetails.PTSKnown = newDetails.alignedSliding = true; + } - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_EOS, data); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ENDED; - return; - } + newFrag.elementaryStreams = oldFrag.elementaryStreams; + newFrag.loader = oldFrag.loader; + newFrag.stats = oldFrag.stats; + newFrag.urlId = oldFrag.urlId; - var targetBufferTime = bufferInfo.end; - var frag = this.getNextFragment(targetBufferTime, levelDetails); // Avoid backtracking after seeking or switching by loading an earlier segment in streams that could backtrack + if (oldFrag.initSegment) { + newFrag.initSegment = oldFrag.initSegment; + currentInitSegment = oldFrag.initSegment; + } + }); - if (this.couldBacktrack && !this.fragPrevious && frag && frag.sn !== 'initSegment') { - var fragIdx = frag.sn - levelDetails.startSN; + if (currentInitSegment) { + var fragmentsToCheck = newDetails.fragmentHint ? newDetails.fragments.concat(newDetails.fragmentHint) : newDetails.fragments; + fragmentsToCheck.forEach(function (frag) { + var _currentInitSegment; - if (fragIdx > 1) { - frag = levelDetails.fragments[fragIdx - 1]; - this.fragmentTracker.removeFragment(frag); - } - } // Avoid loop loading by using nextLoadPosition set for backtracking + if (!frag.initSegment || frag.initSegment.relurl === ((_currentInitSegment = currentInitSegment) === null || _currentInitSegment === void 0 ? void 0 : _currentInitSegment.relurl)) { + frag.initSegment = currentInitSegment; + } + }); + } + if (newDetails.skippedSegments) { + newDetails.deltaUpdateFailed = newDetails.fragments.some(function (frag) { + return !frag; + }); - if (frag && this.fragmentTracker.getState(frag) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].OK && this.nextLoadPosition > targetBufferTime) { - // Cleanup the fragment tracker before trying to find the next unbuffered fragment - var type = this.audioOnly && !this.altAudio ? _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO : _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].VIDEO; - this.afterBufferFlushed(media, type, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); - frag = this.getNextFragment(this.nextLoadPosition, levelDetails); - } + if (newDetails.deltaUpdateFailed) { + _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn("[level-helper] Previous playlist missing segments skipped in delta playlist"); - if (!frag) { - return; - } + for (var _i = newDetails.skippedSegments; _i--; ) { + newDetails.fragments.shift(); + } - if (frag.initSegment && !frag.initSegment.data && !this.bitrateTest) { - frag = frag.initSegment; - } // We want to load the key if we're dealing with an identity key, because we will decrypt - // this content using the key we fetch. Other keys will be handled by the DRM CDM via EME. + newDetails.startSN = newDetails.fragments[0].sn; + newDetails.startCC = newDetails.fragments[0].cc; + } + } + var newFragments = newDetails.fragments; - if (((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === 'identity' && !((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)) { - this.loadKey(frag, levelDetails); - } else { - this.loadFragment(frag, levelDetails, targetBufferTime); - } - }; + if (ccOffset) { + _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].warn("discontinuity sliding from playlist, take drift into account"); - _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) { - var _this$media2; + for (var _i2 = 0; _i2 < newFragments.length; _i2++) { + newFragments[_i2].cc += ccOffset; + } + } - // Check if fragment is not loaded - var fragState = this.fragmentTracker.getState(frag); - this.fragCurrent = frag; // Use data from loaded backtracked fragment if available + if (newDetails.skippedSegments) { + newDetails.startCC = newDetails.fragments[0].cc; + } // Merge parts - if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].BACKTRACKED) { - var data = this.fragmentTracker.getBacktrackData(frag); + mapPartIntersection(oldDetails.partList, newDetails.partList, function (oldPart, newPart) { + newPart.elementaryStreams = oldPart.elementaryStreams; + newPart.stats = oldPart.stats; + }); // if at least one fragment contains PTS info, recompute PTS information for all fragments - if (data) { - this._handleFragmentLoadProgress(data); + if (PTSFrag) { + updateFragPTSDTS(newDetails, PTSFrag, PTSFrag.startPTS, PTSFrag.endPTS, PTSFrag.startDTS, PTSFrag.endDTS); + } else { + // ensure that delta is within oldFragments range + // also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61]) + // in that case we also need to adjust start offset of all fragments + adjustSliding(oldDetails, newDetails); + } - this._handleFragmentLoadComplete(data); + if (newFragments.length) { + newDetails.totalduration = newDetails.edge - newFragments[0].start; + } - return; - } else { - fragState = _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].NOT_LOADED; - } - } + newDetails.driftStartTime = oldDetails.driftStartTime; + newDetails.driftStart = oldDetails.driftStart; + var advancedDateTime = newDetails.advancedDateTime; - if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].NOT_LOADED || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].PARTIAL) { - if (frag.sn === 'initSegment') { - this._loadInitSegment(frag); - } else if (this.bitrateTest) { - frag.bitrateTest = true; - this.log("Fragment " + frag.sn + " of level " + frag.level + " is being downloaded to test bitrate and will not be buffered"); + if (newDetails.advanced && advancedDateTime) { + var edge = newDetails.edge; - this._loadBitrateTestFrag(frag); - } else { - this.startFragRequested = true; + if (!newDetails.driftStart) { + newDetails.driftStartTime = advancedDateTime; + newDetails.driftStart = edge; + } - _BaseStreamController.prototype.loadFragment.call(this, frag, levelDetails, targetBufferTime); - } - } else if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].APPENDING) { - // Lower the buffer size and try again - if (this.reduceMaxBufferLength(frag.duration)) { - this.fragmentTracker.removeFragment(frag); - } - } else if (((_this$media2 = this.media) === null || _this$media2 === void 0 ? void 0 : _this$media2.buffered.length) === 0) { - // Stop gap for bad tracker / buffer flush behavior - this.fragmentTracker.removeAllFragments(); - } - }; + newDetails.driftEndTime = advancedDateTime; + newDetails.driftEnd = edge; + } else { + newDetails.driftEndTime = oldDetails.driftEndTime; + newDetails.driftEnd = oldDetails.driftEnd; + newDetails.advancedDateTime = oldDetails.advancedDateTime; + } + } + function mapPartIntersection(oldParts, newParts, intersectionFn) { + if (oldParts && newParts) { + var delta = 0; - _proto.getAppendedFrag = function getAppendedFrag(position) { - var fragOrPart = this.fragmentTracker.getAppendedFrag(position, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + for (var i = 0, len = oldParts.length; i <= len; i++) { + var _oldPart = oldParts[i]; + var _newPart = newParts[i + delta]; - if (fragOrPart && 'fragment' in fragOrPart) { - return fragOrPart.fragment; - } + if (_oldPart && _newPart && _oldPart.index === _newPart.index && _oldPart.fragment.sn === _newPart.fragment.sn) { + intersectionFn(_oldPart, _newPart); + } else { + delta--; + } + } + } + } + function mapFragmentIntersection(oldDetails, newDetails, intersectionFn) { + var skippedSegments = newDetails.skippedSegments; + var start = Math.max(oldDetails.startSN, newDetails.startSN) - newDetails.startSN; + var end = (oldDetails.fragmentHint ? 1 : 0) + (skippedSegments ? newDetails.endSN : Math.min(oldDetails.endSN, newDetails.endSN)) - newDetails.startSN; + var delta = newDetails.startSN - oldDetails.startSN; + var newFrags = newDetails.fragmentHint ? newDetails.fragments.concat(newDetails.fragmentHint) : newDetails.fragments; + var oldFrags = oldDetails.fragmentHint ? oldDetails.fragments.concat(oldDetails.fragmentHint) : oldDetails.fragments; - return fragOrPart; - }; + for (var i = start; i <= end; i++) { + var _oldFrag = oldFrags[delta + i]; + var _newFrag = newFrags[i]; - _proto.getBufferedFrag = function getBufferedFrag(position) { - return this.fragmentTracker.getBufferedFrag(position, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); - }; + if (skippedSegments && !_newFrag && i < skippedSegments) { + // Fill in skipped segments in delta playlist + _newFrag = newDetails.fragments[i] = _oldFrag; + } - _proto.followingBufferedFrag = function followingBufferedFrag(frag) { - if (frag) { - // try to get range of next fragment (500ms after this range) - return this.getBufferedFrag(frag.end + 0.5); - } + if (_oldFrag && _newFrag) { + intersectionFn(_oldFrag, _newFrag); + } + } + } + function adjustSliding(oldDetails, newDetails) { + var delta = newDetails.startSN + newDetails.skippedSegments - oldDetails.startSN; + var oldFragments = oldDetails.fragments; - return null; - } - /* + if (delta < 0 || delta >= oldFragments.length) { + return; + } + + addSliding(newDetails, oldFragments[delta].start); + } + function addSliding(details, start) { + if (start) { + var fragments = details.fragments; + + for (var i = details.skippedSegments; i < fragments.length; i++) { + fragments[i].start += start; + } + + if (details.fragmentHint) { + details.fragmentHint.start += start; + } + } + } + function computeReloadInterval(newDetails, stats) { + var reloadInterval = 1000 * newDetails.levelTargetDuration; + var reloadIntervalAfterMiss = reloadInterval / 2; + var timeSinceLastModified = newDetails.age; + var useLastModified = timeSinceLastModified > 0 && timeSinceLastModified < reloadInterval * 3; + var roundTrip = stats.loading.end - stats.loading.start; + var estimatedTimeUntilUpdate; + var availabilityDelay = newDetails.availabilityDelay; // let estimate = 'average'; + + if (newDetails.updated === false) { + if (useLastModified) { + // estimate = 'miss round trip'; + // We should have had a hit so try again in the time it takes to get a response, + // but no less than 1/3 second. + var minRetry = 333 * newDetails.misses; + estimatedTimeUntilUpdate = Math.max(Math.min(reloadIntervalAfterMiss, roundTrip * 2), minRetry); + newDetails.availabilityDelay = (newDetails.availabilityDelay || 0) + estimatedTimeUntilUpdate; + } else { + // estimate = 'miss half average'; + // follow CiderHls Spec, If the client reloads a Playlist file and finds that it has not + // changed then it MUST wait for a period of one-half the target + // duration before retrying. + estimatedTimeUntilUpdate = reloadIntervalAfterMiss; + } + } else if (useLastModified) { + // estimate = 'next modified date'; + // Get the closest we've been to timeSinceLastModified on update + availabilityDelay = Math.min(availabilityDelay || reloadInterval / 2, timeSinceLastModified); + newDetails.availabilityDelay = availabilityDelay; + estimatedTimeUntilUpdate = availabilityDelay + reloadInterval - timeSinceLastModified; + } else { + estimatedTimeUntilUpdate = reloadInterval - roundTrip; + } // console.log(`[computeReloadInterval] live reload ${newDetails.updated ? 'REFRESHED' : 'MISSED'}`, + // '\n method', estimate, + // '\n estimated time until update =>', estimatedTimeUntilUpdate, + // '\n average target duration', reloadInterval, + // '\n time since modified', timeSinceLastModified, + // '\n time round trip', roundTrip, + // '\n availability delay', availabilityDelay); + + return Math.round(estimatedTimeUntilUpdate); + } + function getFragmentWithSN(level, sn, fragCurrent) { + if (!level || !level.details) { + return null; + } + + var levelDetails = level.details; + var fragment = levelDetails.fragments[sn - levelDetails.startSN]; + + if (fragment) { + return fragment; + } + + fragment = levelDetails.fragmentHint; + + if (fragment && fragment.sn === sn) { + return fragment; + } + + if (sn < levelDetails.startSN && fragCurrent && fragCurrent.sn === sn) { + return fragCurrent; + } + + return null; + } + function getPartWith(level, sn, partIndex) { + if (!level || !level.details) { + return null; + } + + var partList = level.details.partList; + + if (partList) { + for (var i = partList.length; i--; ) { + var part = partList[i]; + + if (part.index === partIndex && part.fragment.sn === sn) { + return part; + } + } + } + + return null; + } + + /***/ + }, + + /***/ "./src/controller/stream-controller.ts": + /*!*********************************************!*\ + !*** ./src/controller/stream-controller.ts ***! + \*********************************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return StreamController; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts"); + /* harmony import */ var _is_supported__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../is-supported */ "./src/is-supported.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); + /* harmony import */ var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../demux/transmuxer-interface */ "./src/demux/transmuxer-interface.ts"); + /* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts"); + /* harmony import */ var _gap_controller__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./gap-controller */ "./src/controller/gap-controller.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } + + var TICK_INTERVAL = 100; // how often to tick in ms + + var StreamController = /*#__PURE__*/ (function (_BaseStreamController) { + _inheritsLoose(StreamController, _BaseStreamController); + + function StreamController(CiderHls, fragmentTracker) { + var _this; + + _this = _BaseStreamController.call(this, CiderHls, fragmentTracker, "[stream-controller]") || this; + _this.audioCodecSwap = false; + _this.gapController = null; + _this.level = -1; + _this._forceStartLoad = false; + _this.altAudio = false; + _this.audioOnly = false; + _this.fragPlaying = null; + _this.onvplaying = null; + _this.onvseeked = null; + _this.fragLastKbps = 0; + _this.stalled = false; + _this.couldBacktrack = false; + _this.audioCodecSwitch = false; + _this.videoBuffer = null; + + _this._registerListeners(); + + return _this; + } + + var _proto = StreamController.prototype; + + _proto._registerListeners = function _registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_LOADING, this.onLevelLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, this.onError, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_CREATED, this.onBufferCreated, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVELS_UPDATED, this.onLevelsUpdated, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + }; + + _proto._unregisterListeners = function _unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, this.onError, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_CREATED, this.onBufferCreated, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_FLUSHED, this.onBufferFlushed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVELS_UPDATED, this.onLevelsUpdated, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_BUFFERED, this.onFragBuffered, this); + }; + + _proto.onHandlerDestroying = function onHandlerDestroying() { + this._unregisterListeners(); + + this.onMediaDetaching(); + }; + + _proto.startLoad = function startLoad(startPosition) { + if (this.levels) { + var lastCurrentTime = this.lastCurrentTime, + CiderHls = this.CiderHls; + this.stopLoad(); + this.setInterval(TICK_INTERVAL); + this.level = -1; + this.fragLoadError = 0; + + if (!this.startFragRequested) { + // determine load level + var startLevel = CiderHls.startLevel; + + if (startLevel === -1) { + if (CiderHls.config.testBandwidth) { + // -1 : guess start Level by doing a bitrate test by loading first fragment of lowest quality level + startLevel = 0; + this.bitrateTest = true; + } else { + startLevel = CiderHls.nextAutoLevel; + } + } // set new level to playlist loader : this will trigger start level load + // CiderHls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded + + this.level = CiderHls.nextLoadLevel = startLevel; + this.loadedmetadata = false; + } // if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime + + if (lastCurrentTime > 0 && startPosition === -1) { + this.log("Override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3)); + startPosition = lastCurrentTime; + } + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition; + this.tick(); + } else { + this._forceStartLoad = true; + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].STOPPED; + } + }; + + _proto.stopLoad = function stopLoad() { + this._forceStartLoad = false; + + _BaseStreamController.prototype.stopLoad.call(this); + }; + + _proto.doTick = function doTick() { + switch (this.state) { + case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE: + this.doTickIdle(); + break; + + case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL: { + var _levels$level; + + var levels = this.levels, + level = this.level; + var details = levels === null || levels === void 0 ? void 0 : (_levels$level = levels[level]) === null || _levels$level === void 0 ? void 0 : _levels$level.details; + + if (details && (!details.live || this.levelLastLoaded === this.level)) { + if (this.waitForCdnTuneIn(details)) { + break; + } + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + break; + } + + break; + } + + case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING_WAITING_RETRY: + { + var _this$media; + + var now = self.performance.now(); + var retryDate = this.retryDate; // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading + + if (!retryDate || now >= retryDate || ((_this$media = this.media) !== null && _this$media !== void 0 && _this$media.seeking)) { + this.log("retryDate reached, switch back to IDLE state"); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + } + break; + + default: + break; + } // check buffer + // check/update current fragment + + this.onTickEnd(); + }; + + _proto.onTickEnd = function onTickEnd() { + _BaseStreamController.prototype.onTickEnd.call(this); + + this.checkBuffer(); + this.checkFragmentChanged(); + }; + + _proto.doTickIdle = function doTickIdle() { + var _frag$decryptdata, _frag$decryptdata2; + + var CiderHls = this.CiderHls, + levelLastLoaded = this.levelLastLoaded, + levels = this.levels, + media = this.media; + var config = CiderHls.config, + level = CiderHls.nextLoadLevel; // if start level not parsed yet OR + // if video not attached AND start fragment already requested OR start frag prefetch not enabled + // exit loop, as we either need more info (level not parsed) or we need media to be attached to load new fragment + + if (levelLastLoaded === null || (!media && (this.startFragRequested || !config.startFragPrefetch))) { + return; + } // If the "main" level is audio-only but we are loading an alternate track in the same group, do not load anything + + if (this.altAudio && this.audioOnly) { + return; + } + + if (!levels || !levels[level]) { + return; + } + + var levelInfo = levels[level]; // if buffer length is less than maxBufLen try to load a new fragment + // set next load level : this will trigger a playlist load if needed + + this.level = CiderHls.nextLoadLevel = level; + var levelDetails = levelInfo.details; // if level info not retrieved yet, switch state and wait for level retrieval + // if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load + // a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist) + + if (!levelDetails || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL || (levelDetails.live && this.levelLastLoaded !== level)) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL; + return; + } + + var bufferInfo = this.getFwdBufferInfo(this.mediaBuffer ? this.mediaBuffer : media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + + if (bufferInfo === null) { + return; + } + + var bufferLen = bufferInfo.len; // compute max Buffer Length that we could get from this load level, based on level bitrate. don't buffer more than 60 MB and more than 30s + + var maxBufLen = this.getMaxBufferLength(levelInfo.maxBitrate); // Stay idle if we are still with buffer margins + + if (bufferLen >= maxBufLen) { + return; + } + + if (this._streamEnded(bufferInfo, levelDetails)) { + var data = {}; + + if (this.altAudio) { + data.type = "video"; + } + + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_EOS, data); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ENDED; + return; + } + + var targetBufferTime = bufferInfo.end; + var frag = this.getNextFragment(targetBufferTime, levelDetails); // Avoid backtracking after seeking or switching by loading an earlier segment in streams that could backtrack + + if (this.couldBacktrack && !this.fragPrevious && frag && frag.sn !== "initSegment") { + var fragIdx = frag.sn - levelDetails.startSN; + + if (fragIdx > 1) { + frag = levelDetails.fragments[fragIdx - 1]; + this.fragmentTracker.removeFragment(frag); + } + } // Avoid loop loading by using nextLoadPosition set for backtracking + + if (frag && this.fragmentTracker.getState(frag) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].OK && this.nextLoadPosition > targetBufferTime) { + // Cleanup the fragment tracker before trying to find the next unbuffered fragment + var type = this.audioOnly && !this.altAudio ? _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO : _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].VIDEO; + this.afterBufferFlushed(media, type, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + frag = this.getNextFragment(this.nextLoadPosition, levelDetails); + } + + if (!frag) { + return; + } + + if (frag.initSegment && !frag.initSegment.data && !this.bitrateTest) { + frag = frag.initSegment; + } // We want to load the key if we're dealing with an identity key, because we will decrypt + // this content using the key we fetch. Other keys will be handled by the DRM CDM via EME. + + if (((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === "identity" && !((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)) { + this.loadKey(frag, levelDetails); + } else { + this.loadFragment(frag, levelDetails, targetBufferTime); + } + }; + + _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) { + var _this$media2; + + // Check if fragment is not loaded + var fragState = this.fragmentTracker.getState(frag); + this.fragCurrent = frag; // Use data from loaded backtracked fragment if available + + if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].BACKTRACKED) { + var data = this.fragmentTracker.getBacktrackData(frag); + + if (data) { + this._handleFragmentLoadProgress(data); + + this._handleFragmentLoadComplete(data); + + return; + } else { + fragState = _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].NOT_LOADED; + } + } + + if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].NOT_LOADED || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].PARTIAL) { + if (frag.sn === "initSegment") { + this._loadInitSegment(frag); + } else if (this.bitrateTest) { + frag.bitrateTest = true; + this.log("Fragment " + frag.sn + " of level " + frag.level + " is being downloaded to test bitrate and will not be buffered"); + + this._loadBitrateTestFrag(frag); + } else { + this.startFragRequested = true; + + _BaseStreamController.prototype.loadFragment.call(this, frag, levelDetails, targetBufferTime); + } + } else if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__["FragmentState"].APPENDING) { + // Lower the buffer size and try again + if (this.reduceMaxBufferLength(frag.duration)) { + this.fragmentTracker.removeFragment(frag); + } + } else if (((_this$media2 = this.media) === null || _this$media2 === void 0 ? void 0 : _this$media2.buffered.length) === 0) { + // Stop gap for bad tracker / buffer flush behavior + this.fragmentTracker.removeAllFragments(); + } + }; + + _proto.getAppendedFrag = function getAppendedFrag(position) { + var fragOrPart = this.fragmentTracker.getAppendedFrag(position, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + + if (fragOrPart && "fragment" in fragOrPart) { + return fragOrPart.fragment; + } + + return fragOrPart; + }; + + _proto.getBufferedFrag = function getBufferedFrag(position) { + return this.fragmentTracker.getBufferedFrag(position, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + }; + + _proto.followingBufferedFrag = function followingBufferedFrag(frag) { + if (frag) { + // try to get range of next fragment (500ms after this range) + return this.getBufferedFrag(frag.end + 0.5); + } + + return null; + }; + /* on immediate level switch : - pause playback if playing - cancel any pending load request - and trigger a buffer flush */ - ; - - _proto.immediateLevelSwitch = function immediateLevelSwitch() { - this.abortCurrentFrag(); - this.flushMainBuffer(0, Number.POSITIVE_INFINITY); - } - /** - * try to switch ASAP without breaking video playback: - * in order to ensure smooth but quick level switching, - * we need to find the next flushable buffer range - * we should take into account new segment fetch time - */ - ; - - _proto.nextLevelSwitch = function nextLevelSwitch() { - var levels = this.levels, - media = this.media; // ensure that media is defined and that metadata are available (to retrieve currentTime) - - if (media !== null && media !== void 0 && media.readyState) { - var fetchdelay; - var fragPlayingCurrent = this.getAppendedFrag(media.currentTime); - - if (fragPlayingCurrent && fragPlayingCurrent.start > 1) { - // flush buffer preceding current fragment (flush until current fragment start offset) - // minus 1s to avoid video freezing, that could happen if we flush keyframe of current video ... - this.flushMainBuffer(0, fragPlayingCurrent.start - 1); - } - - if (!media.paused && levels) { - // add a safety delay of 1s - var nextLevelId = this.CiderHls.nextLoadLevel; - var nextLevel = levels[nextLevelId]; - var fragLastKbps = this.fragLastKbps; - - if (fragLastKbps && this.fragCurrent) { - fetchdelay = this.fragCurrent.duration * nextLevel.maxBitrate / (1000 * fragLastKbps) + 1; - } else { - fetchdelay = 0; - } - } else { - fetchdelay = 0; - } // this.log('fetchdelay:'+fetchdelay); - // find buffer range that will be reached once new fragment will be fetched - - - var bufferedFrag = this.getBufferedFrag(media.currentTime + fetchdelay); - - if (bufferedFrag) { - // we can flush buffer range following this one without stalling playback - var nextBufferedFrag = this.followingBufferedFrag(bufferedFrag); - - if (nextBufferedFrag) { - // if we are here, we can also cancel any loading/demuxing in progress, as they are useless - this.abortCurrentFrag(); // start flush position is in next buffered frag. Leave some padding for non-independent segments and smoother playback. - - var maxStart = nextBufferedFrag.maxStartPTS ? nextBufferedFrag.maxStartPTS : nextBufferedFrag.start; - var fragDuration = nextBufferedFrag.duration; - var startPts = Math.max(bufferedFrag.end, maxStart + Math.min(Math.max(fragDuration - this.config.maxFragLookUpTolerance, fragDuration * 0.5), fragDuration * 0.75)); - this.flushMainBuffer(startPts, Number.POSITIVE_INFINITY); - } - } - } - }; - - _proto.abortCurrentFrag = function abortCurrentFrag() { - var fragCurrent = this.fragCurrent; - this.fragCurrent = null; - - if (fragCurrent !== null && fragCurrent !== void 0 && fragCurrent.loader) { - fragCurrent.loader.abort(); - } - - if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].KEY_LOADING) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - - this.nextLoadPosition = this.getLoadPosition(); - }; - - _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset) { - _BaseStreamController.prototype.flushMainBuffer.call(this, startOffset, endOffset, this.altAudio ? 'video' : null); - }; - - _proto.onMediaAttached = function onMediaAttached(event, data) { - _BaseStreamController.prototype.onMediaAttached.call(this, event, data); - - var media = data.media; - this.onvplaying = this.onMediaPlaying.bind(this); - this.onvseeked = this.onMediaSeeked.bind(this); - media.addEventListener('playing', this.onvplaying); - media.addEventListener('seeked', this.onvseeked); - this.gapController = new _gap_controller__WEBPACK_IMPORTED_MODULE_10__["default"](this.config, media, this.fragmentTracker, this.CiderHls); - }; - - _proto.onMediaDetaching = function onMediaDetaching() { - var media = this.media; - - if (media) { - media.removeEventListener('playing', this.onvplaying); - media.removeEventListener('seeked', this.onvseeked); - this.onvplaying = this.onvseeked = null; - this.videoBuffer = null; - } - - this.fragPlaying = null; - - if (this.gapController) { - this.gapController.destroy(); - this.gapController = null; - } - - _BaseStreamController.prototype.onMediaDetaching.call(this); - }; - - _proto.onMediaPlaying = function onMediaPlaying() { - // tick to speed up FRAG_CHANGED triggering - this.tick(); - }; - - _proto.onMediaSeeked = function onMediaSeeked() { - var media = this.media; - var currentTime = media ? media.currentTime : null; - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(currentTime)) { - this.log("Media seeked to " + currentTime.toFixed(3)); - } // tick to speed up FRAG_CHANGED triggering - - - this.tick(); - }; - - _proto.onManifestLoading = function onManifestLoading() { - // reset buffer on manifest loading - this.log('Trigger BUFFER_RESET'); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_RESET, undefined); - this.fragmentTracker.removeAllFragments(); - this.couldBacktrack = this.stalled = false; - this.startPosition = this.lastCurrentTime = 0; - this.fragPlaying = null; - }; - - _proto.onManifestParsed = function onManifestParsed(event, data) { - var aac = false; - var heaac = false; - var codec; - data.levels.forEach(function (level) { - // detect if we have different kind of audio codecs used amongst playlists - codec = level.audioCodec; - - if (codec) { - if (codec.indexOf('mp4a.40.2') !== -1) { - aac = true; - } - - if (codec.indexOf('mp4a.40.5') !== -1) { - heaac = true; - } - } - }); - this.audioCodecSwitch = aac && heaac && !Object(_is_supported__WEBPACK_IMPORTED_MODULE_2__["changeTypeSupported"])(); - - if (this.audioCodecSwitch) { - this.log('Both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC'); - } - - this.levels = data.levels; - this.startFragRequested = false; - }; - - _proto.onLevelLoading = function onLevelLoading(event, data) { - var levels = this.levels; - - if (!levels || this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE) { - return; - } - - var level = levels[data.level]; - - if (!level.details || level.details.live && this.levelLastLoaded !== data.level || this.waitForCdnTuneIn(level.details)) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL; - } - }; - - _proto.onLevelLoaded = function onLevelLoaded(event, data) { - var _curLevel$details; - - var levels = this.levels; - var newLevelId = data.level; - var newDetails = data.details; - var duration = newDetails.totalduration; - - if (!levels) { - this.warn("Levels were reset while loading level " + newLevelId); - return; - } - - this.log("Level " + newLevelId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "], cc [" + newDetails.startCC + ", " + newDetails.endCC + "] duration:" + duration); - var fragCurrent = this.fragCurrent; - - if (fragCurrent && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING_WAITING_RETRY)) { - if (fragCurrent.level !== data.level && fragCurrent.loader) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - fragCurrent.loader.abort(); - } - } - - var curLevel = levels[newLevelId]; - var sliding = 0; - - if (newDetails.live || (_curLevel$details = curLevel.details) !== null && _curLevel$details !== void 0 && _curLevel$details.live) { - if (!newDetails.fragments[0]) { - newDetails.deltaUpdateFailed = true; - } - - if (newDetails.deltaUpdateFailed) { - return; - } - - sliding = this.alignPlaylists(newDetails, curLevel.details); - } // override level info - - - curLevel.details = newDetails; - this.levelLastLoaded = newLevelId; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_UPDATED, { - details: newDetails, - level: newLevelId - }); // only switch back to IDLE state if we were waiting for level to start downloading a new fragment - - if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL) { - if (this.waitForCdnTuneIn(newDetails)) { - // Wait for Low-Latency CDN Tune-in - return; - } - - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - - if (!this.startFragRequested) { - this.setStartPosition(newDetails, sliding); - } else if (newDetails.live) { - this.synchronizeToLiveEdge(newDetails); - } // trigger handler right now - - - this.tick(); - }; - - _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(data) { - var _frag$initSegment; - - var frag = data.frag, - part = data.part, - payload = data.payload; - var levels = this.levels; - - if (!levels) { - this.warn("Levels were reset while fragment load was in progress. Fragment " + frag.sn + " of level " + frag.level + " will not be buffered"); - return; - } - - var currentLevel = levels[frag.level]; - var details = currentLevel.details; - - if (!details) { - this.warn("Dropping fragment " + frag.sn + " of level " + frag.level + " after level details were reset"); - return; - } - - var videoCodec = currentLevel.videoCodec; // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live) - - var accurateTimeOffset = details.PTSKnown || !details.live; - var initSegmentData = (_frag$initSegment = frag.initSegment) === null || _frag$initSegment === void 0 ? void 0 : _frag$initSegment.data; - - var audioCodec = this._getAudioCodec(currentLevel); // transmux the MPEG-TS data to ISO-BMFF segments - // this.log(`Transmuxing ${frag.sn} of [${details.startSN} ,${details.endSN}],level ${frag.level}, cc ${frag.cc}`); - - - var transmuxer = this.transmuxer = this.transmuxer || new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__["default"](this.CiderHls, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this)); - var partIndex = part ? part.index : -1; - var partial = partIndex !== -1; - var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial); - var initPTS = this.initPTS[frag.cc]; - transmuxer.push(payload, initSegmentData, audioCodec, videoCodec, frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS); - }; - - _proto.onAudioTrackSwitching = function onAudioTrackSwitching(event, data) { - // if any URL found on new audio track, it is an alternate audio track - var fromAltAudio = this.altAudio; - var altAudio = !!data.url; - var trackId = data.id; // if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered - // don't do anything if we switch to alt audio: audio stream controller is handling it. - // we will just have to change buffer scheduling on audioTrackSwitched - - if (!altAudio) { - if (this.mediaBuffer !== this.media) { - this.log('Switching on main audio, use media.buffered to schedule main fragment loading'); - this.mediaBuffer = this.media; - var fragCurrent = this.fragCurrent; // we need to refill audio buffer from main: cancel any frag loading to speed up audio switch - - if (fragCurrent !== null && fragCurrent !== void 0 && fragCurrent.loader) { - this.log('Switching to main audio track, cancel main fragment load'); - fragCurrent.loader.abort(); - } // destroy transmuxer to force init segment generation (following audio switch) - - - this.resetTransmuxer(); // switch to IDLE state to load new fragment - - this.resetLoadingState(); - } else if (this.audioOnly) { - // Reset audio transmuxer so when switching back to main audio we're not still appending where we left off - this.resetTransmuxer(); - } - - var CiderHls = this.CiderHls; // If switching from alt to main audio, flush all audio and trigger track switched - - if (fromAltAudio) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_FLUSHING, { - startOffset: 0, - endOffset: Number.POSITIVE_INFINITY, - type: 'audio' - }); - } - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHED, { - id: trackId - }); - } - }; - - _proto.onAudioTrackSwitched = function onAudioTrackSwitched(event, data) { - var trackId = data.id; - var altAudio = !!this.CiderHls.audioTracks[trackId].url; - - if (altAudio) { - var videoBuffer = this.videoBuffer; // if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered - - if (videoBuffer && this.mediaBuffer !== videoBuffer) { - this.log('Switching on alternate audio, use video.buffered to schedule main fragment loading'); - this.mediaBuffer = videoBuffer; - } - } - - this.altAudio = altAudio; - this.tick(); - }; - - _proto.onBufferCreated = function onBufferCreated(event, data) { - var tracks = data.tracks; - var mediaTrack; - var name; - var alternate = false; - - for (var type in tracks) { - var track = tracks[type]; - - if (track.id === 'main') { - name = type; - mediaTrack = track; // keep video source buffer reference - - if (type === 'video') { - var videoTrack = tracks[type]; - - if (videoTrack) { - this.videoBuffer = videoTrack.buffer; - } - } - } else { - alternate = true; - } - } - - if (alternate && mediaTrack) { - this.log("Alternate track found, use " + name + ".buffered to schedule main fragment loading"); - this.mediaBuffer = mediaTrack.buffer; - } else { - this.mediaBuffer = this.media; - } - }; - - _proto.onFragBuffered = function onFragBuffered(event, data) { - var frag = data.frag, - part = data.part; - - if (frag && frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN) { - return; - } - - if (this.fragContextChanged(frag)) { - // If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion - // Avoid setting state back to IDLE, since that will interfere with a level switch - this.warn("Fragment " + frag.sn + (part ? ' p: ' + part.index : '') + " of level " + frag.level + " finished buffering, but was aborted. state: " + this.state); - - if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSED) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - - return; - } - - var stats = part ? part.stats : frag.stats; - this.fragLastKbps = Math.round(8 * stats.total / (stats.buffering.end - stats.loading.first)); - - if (frag.sn !== 'initSegment') { - this.fragPrevious = frag; - } - - this.fragBufferedComplete(frag, part); - }; - - _proto.onError = function onError(event, data) { - switch (data.details) { - case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].FRAG_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].FRAG_LOAD_TIMEOUT: - case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].KEY_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].KEY_LOAD_TIMEOUT: - this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN, data); - break; - - case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].LEVEL_LOAD_ERROR: - case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].LEVEL_LOAD_TIMEOUT: - if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR) { - if (data.fatal) { - // if fatal error, stop processing - this.warn("" + data.details); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR; - } else { - // in case of non fatal error while loading level, if level controller is not retrying to load level , switch back to IDLE - if (!data.levelRetry && this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - } - } - } - - break; - - case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].BUFFER_FULL_ERROR: - // if in appending state - if (data.parent === 'main' && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSED)) { - var flushBuffer = true; - var bufferedInfo = this.getFwdBufferInfo(this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end - // reduce max buf len if current position is buffered - - if (bufferedInfo && bufferedInfo.len > 0.5) { - flushBuffer = !this.reduceMaxBufferLength(bufferedInfo.len); - } - - if (flushBuffer) { - // current position is not buffered, but browser is still complaining about buffer full error - // this happens on IE/Edge, refer to https://github.com/video-dev/CiderHls.js/pull/708 - // in that case flush the whole buffer to recover - this.warn('buffer full error also media.currentTime is not buffered, flush main'); // flush main buffer - - this.immediateLevelSwitch(); - } - - this.resetLoadingState(); - } - - break; - - default: - break; - } - } // Checks the health of the buffer and attempts to resolve playback stalls. - ; - - _proto.checkBuffer = function checkBuffer() { - var media = this.media, - gapController = this.gapController; - - if (!media || !gapController || !media.readyState) { - // Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0) - return; - } // Check combined buffer - - - var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(media); - - if (!this.loadedmetadata && buffered.length) { - this.loadedmetadata = true; - this.seekToStartPos(); - } else { - // Resolve gaps using the main buffer, whose ranges are the intersections of the A/V sourcebuffers - gapController.poll(this.lastCurrentTime); - } - - this.lastCurrentTime = media.currentTime; - }; - - _proto.onFragLoadEmergencyAborted = function onFragLoadEmergencyAborted() { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; // if loadedmetadata is not set, it means that we are emergency switch down on first frag - // in that case, reset startFragRequested flag - - if (!this.loadedmetadata) { - this.startFragRequested = false; - this.nextLoadPosition = this.startPosition; - } - - this.tickImmediate(); - }; - - _proto.onBufferFlushed = function onBufferFlushed(event, _ref) { - var type = _ref.type; - - if (type !== _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO || this.audioOnly && !this.altAudio) { - var media = (type === _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].VIDEO ? this.videoBuffer : this.mediaBuffer) || this.media; - this.afterBufferFlushed(media, type, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); - } - }; - - _proto.onLevelsUpdated = function onLevelsUpdated(event, data) { - this.levels = data.levels; - }; - - _proto.swapAudioCodec = function swapAudioCodec() { - this.audioCodecSwap = !this.audioCodecSwap; - } - /** - * Seeks to the set startPosition if not equal to the mediaElement's current time. - * @private - */ - ; - - _proto.seekToStartPos = function seekToStartPos() { - var media = this.media; - var currentTime = media.currentTime; - var startPosition = this.startPosition; // only adjust currentTime if different from startPosition or if startPosition not buffered - // at that stage, there should be only one buffered range, as we reach that code after first fragment has been buffered - - if (startPosition >= 0 && currentTime < startPosition) { - if (media.seeking) { - _utils_logger__WEBPACK_IMPORTED_MODULE_12__["logger"].log("could not seek to " + startPosition + ", already seeking at " + currentTime); - return; - } - - var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(media); - var bufferStart = buffered.length ? buffered.start(0) : 0; - var delta = bufferStart - startPosition; - - if (delta > 0 && (delta < this.config.maxBufferHole || delta < this.config.maxFragLookUpTolerance)) { - _utils_logger__WEBPACK_IMPORTED_MODULE_12__["logger"].log("adjusting start position by " + delta + " to match buffer start"); - startPosition += delta; - this.startPosition = startPosition; - } - - this.log("seek to target start position " + startPosition + " from current time " + currentTime); - media.currentTime = startPosition; - } - }; - - _proto._getAudioCodec = function _getAudioCodec(currentLevel) { - var audioCodec = this.config.defaultAudioCodec || currentLevel.audioCodec; - - if (this.audioCodecSwap && audioCodec) { - this.log('Swapping audio codec'); - - if (audioCodec.indexOf('mp4a.40.5') !== -1) { - audioCodec = 'mp4a.40.2'; - } else { - audioCodec = 'mp4a.40.5'; - } - } - - return audioCodec; - }; - - _proto._loadBitrateTestFrag = function _loadBitrateTestFrag(frag) { - var _this2 = this; - - this._doFragLoad(frag).then(function (data) { - var CiderHls = _this2.CiderHls; - - if (!data || CiderHls.nextLoadLevel || _this2.fragContextChanged(frag)) { - return; - } - - _this2.fragLoadError = 0; - _this2.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; - _this2.startFragRequested = false; - _this2.bitrateTest = false; - var stats = frag.stats; // Bitrate tests fragments are neither parsed nor buffered - - stats.parsing.start = stats.parsing.end = stats.buffering.start = stats.buffering.end = self.performance.now(); - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_LOADED, data); - }); - }; - - _proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) { - var _id3$samples; - - var id = 'main'; - var CiderHls = this.CiderHls; - var remuxResult = transmuxResult.remuxResult, - chunkMeta = transmuxResult.chunkMeta; - var context = this.getCurrentContext(chunkMeta); - - if (!context) { - this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered."); - this.resetLiveStartWhenNotLoaded(chunkMeta.level); - return; - } - - var frag = context.frag, - part = context.part, - level = context.level; - var video = remuxResult.video, - text = remuxResult.text, - id3 = remuxResult.id3, - initSegment = remuxResult.initSegment; // The audio-stream-controller handles audio buffering if CiderHls.js is playing an alternate audio track - - var audio = this.altAudio ? undefined : remuxResult.audio; // Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level. - // If we are, subsequently check if the currently loading fragment (fragCurrent) has changed. - - if (this.fragContextChanged(frag)) { - return; - } - - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING; - - if (initSegment) { - if (initSegment.tracks) { - this._bufferInitSegment(level, initSegment.tracks, frag, chunkMeta); - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_PARSING_INIT_SEGMENT, { - frag: frag, - id: id, - tracks: initSegment.tracks - }); - } // This would be nice if Number.isFinite acted as a typeguard, but it doesn't. See: https://github.com/Microsoft/TypeScript/issues/10038 - - - var initPTS = initSegment.initPTS; - var timescale = initSegment.timescale; - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(initPTS)) { - this.initPTS[frag.cc] = initPTS; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].INIT_PTS_FOUND, { - frag: frag, - id: id, - initPTS: initPTS, - timescale: timescale - }); - } - } // Avoid buffering if backtracking this fragment - - - if (video && remuxResult.independent !== false) { - if (level.details) { - var startPTS = video.startPTS, - endPTS = video.endPTS, - startDTS = video.startDTS, - endDTS = video.endDTS; - - if (part) { - part.elementaryStreams[video.type] = { - startPTS: startPTS, - endPTS: endPTS, - startDTS: startDTS, - endDTS: endDTS - }; - } else { - if (video.firstKeyFrame && video.independent) { - this.couldBacktrack = true; - } - - if (video.dropped && video.independent) { - // Backtrack if dropped frames create a gap after currentTime - var pos = this.getLoadPosition() + this.config.maxBufferHole; - - if (pos < startPTS) { - this.backtrack(frag); - return; - } // Set video stream start to fragment start so that truncated samples do not distort the timeline, and mark it partial - - - frag.setElementaryStreamInfo(video.type, frag.start, endPTS, frag.start, endDTS, true); - } - } - - frag.setElementaryStreamInfo(video.type, startPTS, endPTS, startDTS, endDTS); - this.bufferFragmentData(video, frag, part, chunkMeta); - } - } else if (remuxResult.independent === false) { - this.backtrack(frag); - return; - } - - if (audio) { - var _startPTS = audio.startPTS, - _endPTS = audio.endPTS, - _startDTS = audio.startDTS, - _endDTS = audio.endDTS; - - if (part) { - part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO] = { - startPTS: _startPTS, - endPTS: _endPTS, - startDTS: _startDTS, - endDTS: _endDTS - }; - } - - frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO, _startPTS, _endPTS, _startDTS, _endDTS); - this.bufferFragmentData(audio, frag, part, chunkMeta); - } - - if (id3 !== null && id3 !== void 0 && (_id3$samples = id3.samples) !== null && _id3$samples !== void 0 && _id3$samples.length) { - var emittedID3 = { - frag: frag, - id: id, - samples: id3.samples - }; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_PARSING_METADATA, emittedID3); - } - - if (text) { - var emittedText = { - frag: frag, - id: id, - samples: text.samples - }; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_PARSING_USERDATA, emittedText); - } - }; - - _proto._bufferInitSegment = function _bufferInitSegment(currentLevel, tracks, frag, chunkMeta) { - var _this3 = this; - - if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING) { - return; - } - - this.audioOnly = !!tracks.audio && !tracks.video; // if audio track is expected to come from audio stream controller, discard any coming from main - - if (this.altAudio && !this.audioOnly) { - delete tracks.audio; - } // include levelCodec in audio and video tracks - - - var audio = tracks.audio, - video = tracks.video, - audiovideo = tracks.audiovideo; - - if (audio) { - var audioCodec = currentLevel.audioCodec; - var ua = navigator.userAgent.toLowerCase(); - - if (this.audioCodecSwitch) { - if (audioCodec) { - if (audioCodec.indexOf('mp4a.40.5') !== -1) { - audioCodec = 'mp4a.40.2'; - } else { - audioCodec = 'mp4a.40.5'; - } - } // In the case that AAC and HE-AAC audio codecs are signalled in manifest, - // force HE-AAC, as it seems that most browsers prefers it. - // don't force HE-AAC if mono stream, or in Firefox - - - if (audio.metadata.channelCount !== 1 && ua.indexOf('firefox') === -1) { - audioCodec = 'mp4a.40.5'; - } - } // HE-AAC is broken on Android, always signal audio codec as AAC even if variant manifest states otherwise - - - if (ua.indexOf('android') !== -1 && audio.container !== 'audio/mpeg') { - // Exclude mpeg audio - audioCodec = 'mp4a.40.2'; - this.log("Android: force audio codec to " + audioCodec); - } - - if (currentLevel.audioCodec && currentLevel.audioCodec !== audioCodec) { - this.log("Swapping manifest audio codec \"" + currentLevel.audioCodec + "\" for \"" + audioCodec + "\""); - } - - audio.levelCodec = audioCodec; - audio.id = 'main'; - this.log("Init audio buffer, container:" + audio.container + ", codecs[selected/level/parsed]=[" + (audioCodec || '') + "/" + (currentLevel.audioCodec || '') + "/" + audio.codec + "]"); - } - - if (video) { - video.levelCodec = currentLevel.videoCodec; - video.id = 'main'; - this.log("Init video buffer, container:" + video.container + ", codecs[level/parsed]=[" + (currentLevel.videoCodec || '') + "/" + video.codec + "]"); - } - - if (audiovideo) { - this.log("Init audiovideo buffer, container:" + audiovideo.container + ", codecs[level/parsed]=[" + (currentLevel.attrs.CODECS || '') + "/" + audiovideo.codec + "]"); - } - - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_CODECS, tracks); // loop through tracks that are going to be provided to bufferController - - Object.keys(tracks).forEach(function (trackName) { - var track = tracks[trackName]; - var initSegment = track.initSegment; - - if (initSegment !== null && initSegment !== void 0 && initSegment.byteLength) { - _this3.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_APPENDING, { - type: trackName, - data: initSegment, - frag: frag, - part: null, - chunkMeta: chunkMeta, - parent: frag.type - }); - } - }); // trigger handler right now - - this.tick(); - }; - - _proto.backtrack = function backtrack(frag) { - this.couldBacktrack = true; // Causes findFragments to backtrack through fragments to find the keyframe - - this.resetTransmuxer(); - this.flushBufferGap(frag); - var data = this.fragmentTracker.backtrack(frag); - this.fragPrevious = null; - this.nextLoadPosition = frag.start; - - if (data) { - this.resetFragmentLoading(frag); - } else { - // Change state to BACKTRACKING so that fragmentEntity.backtrack data can be added after _doFragLoad - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].BACKTRACKING; - } - }; - - _proto.checkFragmentChanged = function checkFragmentChanged() { - var video = this.media; - var fragPlayingCurrent = null; - - if (video && video.readyState > 1 && video.seeking === false) { - var currentTime = video.currentTime; - /* if video element is in seeked state, currentTime can only increase. + + _proto.immediateLevelSwitch = function immediateLevelSwitch() { + this.abortCurrentFrag(); + this.flushMainBuffer(0, Number.POSITIVE_INFINITY); + }; + /** + * try to switch ASAP without breaking video playback: + * in order to ensure smooth but quick level switching, + * we need to find the next flushable buffer range + * we should take into account new segment fetch time + */ + + _proto.nextLevelSwitch = function nextLevelSwitch() { + var levels = this.levels, + media = this.media; // ensure that media is defined and that metadata are available (to retrieve currentTime) + + if (media !== null && media !== void 0 && media.readyState) { + var fetchdelay; + var fragPlayingCurrent = this.getAppendedFrag(media.currentTime); + + if (fragPlayingCurrent && fragPlayingCurrent.start > 1) { + // flush buffer preceding current fragment (flush until current fragment start offset) + // minus 1s to avoid video freezing, that could happen if we flush keyframe of current video ... + this.flushMainBuffer(0, fragPlayingCurrent.start - 1); + } + + if (!media.paused && levels) { + // add a safety delay of 1s + var nextLevelId = this.CiderHls.nextLoadLevel; + var nextLevel = levels[nextLevelId]; + var fragLastKbps = this.fragLastKbps; + + if (fragLastKbps && this.fragCurrent) { + fetchdelay = (this.fragCurrent.duration * nextLevel.maxBitrate) / (1000 * fragLastKbps) + 1; + } else { + fetchdelay = 0; + } + } else { + fetchdelay = 0; + } // this.log('fetchdelay:'+fetchdelay); + // find buffer range that will be reached once new fragment will be fetched + + var bufferedFrag = this.getBufferedFrag(media.currentTime + fetchdelay); + + if (bufferedFrag) { + // we can flush buffer range following this one without stalling playback + var nextBufferedFrag = this.followingBufferedFrag(bufferedFrag); + + if (nextBufferedFrag) { + // if we are here, we can also cancel any loading/demuxing in progress, as they are useless + this.abortCurrentFrag(); // start flush position is in next buffered frag. Leave some padding for non-independent segments and smoother playback. + + var maxStart = nextBufferedFrag.maxStartPTS ? nextBufferedFrag.maxStartPTS : nextBufferedFrag.start; + var fragDuration = nextBufferedFrag.duration; + var startPts = Math.max(bufferedFrag.end, maxStart + Math.min(Math.max(fragDuration - this.config.maxFragLookUpTolerance, fragDuration * 0.5), fragDuration * 0.75)); + this.flushMainBuffer(startPts, Number.POSITIVE_INFINITY); + } + } + } + }; + + _proto.abortCurrentFrag = function abortCurrentFrag() { + var fragCurrent = this.fragCurrent; + this.fragCurrent = null; + + if (fragCurrent !== null && fragCurrent !== void 0 && fragCurrent.loader) { + fragCurrent.loader.abort(); + } + + if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].KEY_LOADING) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + + this.nextLoadPosition = this.getLoadPosition(); + }; + + _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset) { + _BaseStreamController.prototype.flushMainBuffer.call(this, startOffset, endOffset, this.altAudio ? "video" : null); + }; + + _proto.onMediaAttached = function onMediaAttached(event, data) { + _BaseStreamController.prototype.onMediaAttached.call(this, event, data); + + var media = data.media; + this.onvplaying = this.onMediaPlaying.bind(this); + this.onvseeked = this.onMediaSeeked.bind(this); + media.addEventListener("playing", this.onvplaying); + media.addEventListener("seeked", this.onvseeked); + this.gapController = new _gap_controller__WEBPACK_IMPORTED_MODULE_10__["default"](this.config, media, this.fragmentTracker, this.CiderHls); + }; + + _proto.onMediaDetaching = function onMediaDetaching() { + var media = this.media; + + if (media) { + media.removeEventListener("playing", this.onvplaying); + media.removeEventListener("seeked", this.onvseeked); + this.onvplaying = this.onvseeked = null; + this.videoBuffer = null; + } + + this.fragPlaying = null; + + if (this.gapController) { + this.gapController.destroy(); + this.gapController = null; + } + + _BaseStreamController.prototype.onMediaDetaching.call(this); + }; + + _proto.onMediaPlaying = function onMediaPlaying() { + // tick to speed up FRAG_CHANGED triggering + this.tick(); + }; + + _proto.onMediaSeeked = function onMediaSeeked() { + var media = this.media; + var currentTime = media ? media.currentTime : null; + + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(currentTime)) { + this.log("Media seeked to " + currentTime.toFixed(3)); + } // tick to speed up FRAG_CHANGED triggering + + this.tick(); + }; + + _proto.onManifestLoading = function onManifestLoading() { + // reset buffer on manifest loading + this.log("Trigger BUFFER_RESET"); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_RESET, undefined); + this.fragmentTracker.removeAllFragments(); + this.couldBacktrack = this.stalled = false; + this.startPosition = this.lastCurrentTime = 0; + this.fragPlaying = null; + }; + + _proto.onManifestParsed = function onManifestParsed(event, data) { + var aac = false; + var heaac = false; + var codec; + data.levels.forEach(function (level) { + // detect if we have different kind of audio codecs used amongst playlists + codec = level.audioCodec; + + if (codec) { + if (codec.indexOf("mp4a.40.2") !== -1) { + aac = true; + } + + if (codec.indexOf("mp4a.40.5") !== -1) { + heaac = true; + } + } + }); + this.audioCodecSwitch = aac && heaac && !Object(_is_supported__WEBPACK_IMPORTED_MODULE_2__["changeTypeSupported"])(); + + if (this.audioCodecSwitch) { + this.log("Both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC"); + } + + this.levels = data.levels; + this.startFragRequested = false; + }; + + _proto.onLevelLoading = function onLevelLoading(event, data) { + var levels = this.levels; + + if (!levels || this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE) { + return; + } + + var level = levels[data.level]; + + if (!level.details || (level.details.live && this.levelLastLoaded !== data.level) || this.waitForCdnTuneIn(level.details)) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL; + } + }; + + _proto.onLevelLoaded = function onLevelLoaded(event, data) { + var _curLevel$details; + + var levels = this.levels; + var newLevelId = data.level; + var newDetails = data.details; + var duration = newDetails.totalduration; + + if (!levels) { + this.warn("Levels were reset while loading level " + newLevelId); + return; + } + + this.log("Level " + newLevelId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "], cc [" + newDetails.startCC + ", " + newDetails.endCC + "] duration:" + duration); + var fragCurrent = this.fragCurrent; + + if (fragCurrent && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].FRAG_LOADING_WAITING_RETRY)) { + if (fragCurrent.level !== data.level && fragCurrent.loader) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + fragCurrent.loader.abort(); + } + } + + var curLevel = levels[newLevelId]; + var sliding = 0; + + if (newDetails.live || ((_curLevel$details = curLevel.details) !== null && _curLevel$details !== void 0 && _curLevel$details.live)) { + if (!newDetails.fragments[0]) { + newDetails.deltaUpdateFailed = true; + } + + if (newDetails.deltaUpdateFailed) { + return; + } + + sliding = this.alignPlaylists(newDetails, curLevel.details); + } // override level info + + curLevel.details = newDetails; + this.levelLastLoaded = newLevelId; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_UPDATED, { + details: newDetails, + level: newLevelId, + }); // only switch back to IDLE state if we were waiting for level to start downloading a new fragment + + if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL) { + if (this.waitForCdnTuneIn(newDetails)) { + // Wait for Low-Latency CDN Tune-in + return; + } + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + + if (!this.startFragRequested) { + this.setStartPosition(newDetails, sliding); + } else if (newDetails.live) { + this.synchronizeToLiveEdge(newDetails); + } // trigger handler right now + + this.tick(); + }; + + _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(data) { + var _frag$initSegment; + + var frag = data.frag, + part = data.part, + payload = data.payload; + var levels = this.levels; + + if (!levels) { + this.warn("Levels were reset while fragment load was in progress. Fragment " + frag.sn + " of level " + frag.level + " will not be buffered"); + return; + } + + var currentLevel = levels[frag.level]; + var details = currentLevel.details; + + if (!details) { + this.warn("Dropping fragment " + frag.sn + " of level " + frag.level + " after level details were reset"); + return; + } + + var videoCodec = currentLevel.videoCodec; // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live) + + var accurateTimeOffset = details.PTSKnown || !details.live; + var initSegmentData = (_frag$initSegment = frag.initSegment) === null || _frag$initSegment === void 0 ? void 0 : _frag$initSegment.data; + + var audioCodec = this._getAudioCodec(currentLevel); // transmux the MPEG-TS data to ISO-BMFF segments + // this.log(`Transmuxing ${frag.sn} of [${details.startSN} ,${details.endSN}],level ${frag.level}, cc ${frag.cc}`); + + var transmuxer = (this.transmuxer = + this.transmuxer || new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__["default"](this.CiderHls, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this))); + var partIndex = part ? part.index : -1; + var partial = partIndex !== -1; + var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial); + var initPTS = this.initPTS[frag.cc]; + transmuxer.push(payload, initSegmentData, audioCodec, videoCodec, frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS); + }; + + _proto.onAudioTrackSwitching = function onAudioTrackSwitching(event, data) { + // if any URL found on new audio track, it is an alternate audio track + var fromAltAudio = this.altAudio; + var altAudio = !!data.url; + var trackId = data.id; // if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered + // don't do anything if we switch to alt audio: audio stream controller is handling it. + // we will just have to change buffer scheduling on audioTrackSwitched + + if (!altAudio) { + if (this.mediaBuffer !== this.media) { + this.log("Switching on main audio, use media.buffered to schedule main fragment loading"); + this.mediaBuffer = this.media; + var fragCurrent = this.fragCurrent; // we need to refill audio buffer from main: cancel any frag loading to speed up audio switch + + if (fragCurrent !== null && fragCurrent !== void 0 && fragCurrent.loader) { + this.log("Switching to main audio track, cancel main fragment load"); + fragCurrent.loader.abort(); + } // destroy transmuxer to force init segment generation (following audio switch) + + this.resetTransmuxer(); // switch to IDLE state to load new fragment + + this.resetLoadingState(); + } else if (this.audioOnly) { + // Reset audio transmuxer so when switching back to main audio we're not still appending where we left off + this.resetTransmuxer(); + } + + var CiderHls = this.CiderHls; // If switching from alt to main audio, flush all audio and trigger track switched + + if (fromAltAudio) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_FLUSHING, { + startOffset: 0, + endOffset: Number.POSITIVE_INFINITY, + type: "audio", + }); + } + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].AUDIO_TRACK_SWITCHED, { + id: trackId, + }); + } + }; + + _proto.onAudioTrackSwitched = function onAudioTrackSwitched(event, data) { + var trackId = data.id; + var altAudio = !!this.CiderHls.audioTracks[trackId].url; + + if (altAudio) { + var videoBuffer = this.videoBuffer; // if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered + + if (videoBuffer && this.mediaBuffer !== videoBuffer) { + this.log("Switching on alternate audio, use video.buffered to schedule main fragment loading"); + this.mediaBuffer = videoBuffer; + } + } + + this.altAudio = altAudio; + this.tick(); + }; + + _proto.onBufferCreated = function onBufferCreated(event, data) { + var tracks = data.tracks; + var mediaTrack; + var name; + var alternate = false; + + for (var type in tracks) { + var track = tracks[type]; + + if (track.id === "main") { + name = type; + mediaTrack = track; // keep video source buffer reference + + if (type === "video") { + var videoTrack = tracks[type]; + + if (videoTrack) { + this.videoBuffer = videoTrack.buffer; + } + } + } else { + alternate = true; + } + } + + if (alternate && mediaTrack) { + this.log("Alternate track found, use " + name + ".buffered to schedule main fragment loading"); + this.mediaBuffer = mediaTrack.buffer; + } else { + this.mediaBuffer = this.media; + } + }; + + _proto.onFragBuffered = function onFragBuffered(event, data) { + var frag = data.frag, + part = data.part; + + if (frag && frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN) { + return; + } + + if (this.fragContextChanged(frag)) { + // If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion + // Avoid setting state back to IDLE, since that will interfere with a level switch + this.warn("Fragment " + frag.sn + (part ? " p: " + part.index : "") + " of level " + frag.level + " finished buffering, but was aborted. state: " + this.state); + + if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSED) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + + return; + } + + var stats = part ? part.stats : frag.stats; + this.fragLastKbps = Math.round((8 * stats.total) / (stats.buffering.end - stats.loading.first)); + + if (frag.sn !== "initSegment") { + this.fragPrevious = frag; + } + + this.fragBufferedComplete(frag, part); + }; + + _proto.onError = function onError(event, data) { + switch (data.details) { + case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].FRAG_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].FRAG_LOAD_TIMEOUT: + case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].KEY_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].KEY_LOAD_TIMEOUT: + this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN, data); + break; + + case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].LEVEL_LOAD_ERROR: + case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].LEVEL_LOAD_TIMEOUT: + if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR) { + if (data.fatal) { + // if fatal error, stop processing + this.warn("" + data.details); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].ERROR; + } else { + // in case of non fatal error while loading level, if level controller is not retrying to load level , switch back to IDLE + if (!data.levelRetry && this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].WAITING_LEVEL) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + } + } + } + + break; + + case _errors__WEBPACK_IMPORTED_MODULE_11__["ErrorDetails"].BUFFER_FULL_ERROR: + // if in appending state + if (data.parent === "main" && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSED)) { + var flushBuffer = true; + var bufferedInfo = this.getFwdBufferInfo(this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end + // reduce max buf len if current position is buffered + + if (bufferedInfo && bufferedInfo.len > 0.5) { + flushBuffer = !this.reduceMaxBufferLength(bufferedInfo.len); + } + + if (flushBuffer) { + // current position is not buffered, but browser is still complaining about buffer full error + // this happens on IE/Edge, refer to https://github.com/video-dev/CiderHls.js/pull/708 + // in that case flush the whole buffer to recover + this.warn("buffer full error also media.currentTime is not buffered, flush main"); // flush main buffer + + this.immediateLevelSwitch(); + } + + this.resetLoadingState(); + } + + break; + + default: + break; + } + }; // Checks the health of the buffer and attempts to resolve playback stalls. + + _proto.checkBuffer = function checkBuffer() { + var media = this.media, + gapController = this.gapController; + + if (!media || !gapController || !media.readyState) { + // Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0) + return; + } // Check combined buffer + + var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(media); + + if (!this.loadedmetadata && buffered.length) { + this.loadedmetadata = true; + this.seekToStartPos(); + } else { + // Resolve gaps using the main buffer, whose ranges are the intersections of the A/V sourcebuffers + gapController.poll(this.lastCurrentTime); + } + + this.lastCurrentTime = media.currentTime; + }; + + _proto.onFragLoadEmergencyAborted = function onFragLoadEmergencyAborted() { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; // if loadedmetadata is not set, it means that we are emergency switch down on first frag + // in that case, reset startFragRequested flag + + if (!this.loadedmetadata) { + this.startFragRequested = false; + this.nextLoadPosition = this.startPosition; + } + + this.tickImmediate(); + }; + + _proto.onBufferFlushed = function onBufferFlushed(event, _ref) { + var type = _ref.type; + + if (type !== _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO || (this.audioOnly && !this.altAudio)) { + var media = (type === _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].VIDEO ? this.videoBuffer : this.mediaBuffer) || this.media; + this.afterBufferFlushed(media, type, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN); + } + }; + + _proto.onLevelsUpdated = function onLevelsUpdated(event, data) { + this.levels = data.levels; + }; + + _proto.swapAudioCodec = function swapAudioCodec() { + this.audioCodecSwap = !this.audioCodecSwap; + }; + /** + * Seeks to the set startPosition if not equal to the mediaElement's current time. + * @private + */ + + _proto.seekToStartPos = function seekToStartPos() { + var media = this.media; + var currentTime = media.currentTime; + var startPosition = this.startPosition; // only adjust currentTime if different from startPosition or if startPosition not buffered + // at that stage, there should be only one buffered range, as we reach that code after first fragment has been buffered + + if (startPosition >= 0 && currentTime < startPosition) { + if (media.seeking) { + _utils_logger__WEBPACK_IMPORTED_MODULE_12__["logger"].log("could not seek to " + startPosition + ", already seeking at " + currentTime); + return; + } + + var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].getBuffered(media); + var bufferStart = buffered.length ? buffered.start(0) : 0; + var delta = bufferStart - startPosition; + + if (delta > 0 && (delta < this.config.maxBufferHole || delta < this.config.maxFragLookUpTolerance)) { + _utils_logger__WEBPACK_IMPORTED_MODULE_12__["logger"].log("adjusting start position by " + delta + " to match buffer start"); + startPosition += delta; + this.startPosition = startPosition; + } + + this.log("seek to target start position " + startPosition + " from current time " + currentTime); + media.currentTime = startPosition; + } + }; + + _proto._getAudioCodec = function _getAudioCodec(currentLevel) { + var audioCodec = this.config.defaultAudioCodec || currentLevel.audioCodec; + + if (this.audioCodecSwap && audioCodec) { + this.log("Swapping audio codec"); + + if (audioCodec.indexOf("mp4a.40.5") !== -1) { + audioCodec = "mp4a.40.2"; + } else { + audioCodec = "mp4a.40.5"; + } + } + + return audioCodec; + }; + + _proto._loadBitrateTestFrag = function _loadBitrateTestFrag(frag) { + var _this2 = this; + + this._doFragLoad(frag).then(function (data) { + var CiderHls = _this2.CiderHls; + + if (!data || CiderHls.nextLoadLevel || _this2.fragContextChanged(frag)) { + return; + } + + _this2.fragLoadError = 0; + _this2.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].IDLE; + _this2.startFragRequested = false; + _this2.bitrateTest = false; + var stats = frag.stats; // Bitrate tests fragments are neither parsed nor buffered + + stats.parsing.start = stats.parsing.end = stats.buffering.start = stats.buffering.end = self.performance.now(); + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_LOADED, data); + }); + }; + + _proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) { + var _id3$samples; + + var id = "main"; + var CiderHls = this.CiderHls; + var remuxResult = transmuxResult.remuxResult, + chunkMeta = transmuxResult.chunkMeta; + var context = this.getCurrentContext(chunkMeta); + + if (!context) { + this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered."); + this.resetLiveStartWhenNotLoaded(chunkMeta.level); + return; + } + + var frag = context.frag, + part = context.part, + level = context.level; + var video = remuxResult.video, + text = remuxResult.text, + id3 = remuxResult.id3, + initSegment = remuxResult.initSegment; // The audio-stream-controller handles audio buffering if CiderHls.js is playing an alternate audio track + + var audio = this.altAudio ? undefined : remuxResult.audio; // Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level. + // If we are, subsequently check if the currently loading fragment (fragCurrent) has changed. + + if (this.fragContextChanged(frag)) { + return; + } + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING; + + if (initSegment) { + if (initSegment.tracks) { + this._bufferInitSegment(level, initSegment.tracks, frag, chunkMeta); + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_PARSING_INIT_SEGMENT, { + frag: frag, + id: id, + tracks: initSegment.tracks, + }); + } // This would be nice if Number.isFinite acted as a typeguard, but it doesn't. See: https://github.com/Microsoft/TypeScript/issues/10038 + + var initPTS = initSegment.initPTS; + var timescale = initSegment.timescale; + + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(initPTS)) { + this.initPTS[frag.cc] = initPTS; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].INIT_PTS_FOUND, { + frag: frag, + id: id, + initPTS: initPTS, + timescale: timescale, + }); + } + } // Avoid buffering if backtracking this fragment + + if (video && remuxResult.independent !== false) { + if (level.details) { + var startPTS = video.startPTS, + endPTS = video.endPTS, + startDTS = video.startDTS, + endDTS = video.endDTS; + + if (part) { + part.elementaryStreams[video.type] = { + startPTS: startPTS, + endPTS: endPTS, + startDTS: startDTS, + endDTS: endDTS, + }; + } else { + if (video.firstKeyFrame && video.independent) { + this.couldBacktrack = true; + } + + if (video.dropped && video.independent) { + // Backtrack if dropped frames create a gap after currentTime + var pos = this.getLoadPosition() + this.config.maxBufferHole; + + if (pos < startPTS) { + this.backtrack(frag); + return; + } // Set video stream start to fragment start so that truncated samples do not distort the timeline, and mark it partial + + frag.setElementaryStreamInfo(video.type, frag.start, endPTS, frag.start, endDTS, true); + } + } + + frag.setElementaryStreamInfo(video.type, startPTS, endPTS, startDTS, endDTS); + this.bufferFragmentData(video, frag, part, chunkMeta); + } + } else if (remuxResult.independent === false) { + this.backtrack(frag); + return; + } + + if (audio) { + var _startPTS = audio.startPTS, + _endPTS = audio.endPTS, + _startDTS = audio.startDTS, + _endDTS = audio.endDTS; + + if (part) { + part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO] = { + startPTS: _startPTS, + endPTS: _endPTS, + startDTS: _startDTS, + endDTS: _endDTS, + }; + } + + frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO, _startPTS, _endPTS, _startDTS, _endDTS); + this.bufferFragmentData(audio, frag, part, chunkMeta); + } + + if (id3 !== null && id3 !== void 0 && (_id3$samples = id3.samples) !== null && _id3$samples !== void 0 && _id3$samples.length) { + var emittedID3 = { + frag: frag, + id: id, + samples: id3.samples, + }; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_PARSING_METADATA, emittedID3); + } + + if (text) { + var emittedText = { + frag: frag, + id: id, + samples: text.samples, + }; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_PARSING_USERDATA, emittedText); + } + }; + + _proto._bufferInitSegment = function _bufferInitSegment(currentLevel, tracks, frag, chunkMeta) { + var _this3 = this; + + if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].PARSING) { + return; + } + + this.audioOnly = !!tracks.audio && !tracks.video; // if audio track is expected to come from audio stream controller, discard any coming from main + + if (this.altAudio && !this.audioOnly) { + delete tracks.audio; + } // include levelCodec in audio and video tracks + + var audio = tracks.audio, + video = tracks.video, + audiovideo = tracks.audiovideo; + + if (audio) { + var audioCodec = currentLevel.audioCodec; + var ua = navigator.userAgent.toLowerCase(); + + if (this.audioCodecSwitch) { + if (audioCodec) { + if (audioCodec.indexOf("mp4a.40.5") !== -1) { + audioCodec = "mp4a.40.2"; + } else { + audioCodec = "mp4a.40.5"; + } + } // In the case that AAC and HE-AAC audio codecs are signalled in manifest, + // force HE-AAC, as it seems that most browsers prefers it. + // don't force HE-AAC if mono stream, or in Firefox + + if (audio.metadata.channelCount !== 1 && ua.indexOf("firefox") === -1) { + audioCodec = "mp4a.40.5"; + } + } // HE-AAC is broken on Android, always signal audio codec as AAC even if variant manifest states otherwise + + if (ua.indexOf("android") !== -1 && audio.container !== "audio/mpeg") { + // Exclude mpeg audio + audioCodec = "mp4a.40.2"; + this.log("Android: force audio codec to " + audioCodec); + } + + if (currentLevel.audioCodec && currentLevel.audioCodec !== audioCodec) { + this.log('Swapping manifest audio codec "' + currentLevel.audioCodec + '" for "' + audioCodec + '"'); + } + + audio.levelCodec = audioCodec; + audio.id = "main"; + this.log("Init audio buffer, container:" + audio.container + ", codecs[selected/level/parsed]=[" + (audioCodec || "") + "/" + (currentLevel.audioCodec || "") + "/" + audio.codec + "]"); + } + + if (video) { + video.levelCodec = currentLevel.videoCodec; + video.id = "main"; + this.log("Init video buffer, container:" + video.container + ", codecs[level/parsed]=[" + (currentLevel.videoCodec || "") + "/" + video.codec + "]"); + } + + if (audiovideo) { + this.log("Init audiovideo buffer, container:" + audiovideo.container + ", codecs[level/parsed]=[" + (currentLevel.attrs.CODECS || "") + "/" + audiovideo.codec + "]"); + } + + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_CODECS, tracks); // loop through tracks that are going to be provided to bufferController + + Object.keys(tracks).forEach(function (trackName) { + var track = tracks[trackName]; + var initSegment = track.initSegment; + + if (initSegment !== null && initSegment !== void 0 && initSegment.byteLength) { + _this3.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].BUFFER_APPENDING, { + type: trackName, + data: initSegment, + frag: frag, + part: null, + chunkMeta: chunkMeta, + parent: frag.type, + }); + } + }); // trigger handler right now + + this.tick(); + }; + + _proto.backtrack = function backtrack(frag) { + this.couldBacktrack = true; // Causes findFragments to backtrack through fragments to find the keyframe + + this.resetTransmuxer(); + this.flushBufferGap(frag); + var data = this.fragmentTracker.backtrack(frag); + this.fragPrevious = null; + this.nextLoadPosition = frag.start; + + if (data) { + this.resetFragmentLoading(frag); + } else { + // Change state to BACKTRACKING so that fragmentEntity.backtrack data can be added after _doFragLoad + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["State"].BACKTRACKING; + } + }; + + _proto.checkFragmentChanged = function checkFragmentChanged() { + var video = this.media; + var fragPlayingCurrent = null; + + if (video && video.readyState > 1 && video.seeking === false) { + var currentTime = video.currentTime; + /* if video element is in seeked state, currentTime can only increase. (assuming that playback rate is positive ...) As sometimes currentTime jumps back to zero after a media decode error, check this, to avoid seeking back to wrong position after a media decode error */ - if (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].isBuffered(video, currentTime)) { - fragPlayingCurrent = this.getAppendedFrag(currentTime); - } else if (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].isBuffered(video, currentTime + 0.1)) { - /* ensure that FRAG_CHANGED event is triggered at startup, + if (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].isBuffered(video, currentTime)) { + fragPlayingCurrent = this.getAppendedFrag(currentTime); + } else if (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__["BufferHelper"].isBuffered(video, currentTime + 0.1)) { + /* ensure that FRAG_CHANGED event is triggered at startup, when first video frame is displayed and playback is paused. add a tolerance of 100ms, in case current position is not buffered, check if current pos+100ms is buffered and use that buffer range for FRAG_CHANGED event reporting */ - fragPlayingCurrent = this.getAppendedFrag(currentTime + 0.1); - } + fragPlayingCurrent = this.getAppendedFrag(currentTime + 0.1); + } - if (fragPlayingCurrent) { - var fragPlaying = this.fragPlaying; - var fragCurrentLevel = fragPlayingCurrent.level; + if (fragPlayingCurrent) { + var fragPlaying = this.fragPlaying; + var fragCurrentLevel = fragPlayingCurrent.level; - if (!fragPlaying || fragPlayingCurrent.sn !== fragPlaying.sn || fragPlaying.level !== fragCurrentLevel || fragPlayingCurrent.urlId !== fragPlaying.urlId) { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_CHANGED, { - frag: fragPlayingCurrent - }); + if (!fragPlaying || fragPlayingCurrent.sn !== fragPlaying.sn || fragPlaying.level !== fragCurrentLevel || fragPlayingCurrent.urlId !== fragPlaying.urlId) { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].FRAG_CHANGED, { + frag: fragPlayingCurrent, + }); - if (!fragPlaying || fragPlaying.level !== fragCurrentLevel) { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_SWITCHED, { - level: fragCurrentLevel - }); - } + if (!fragPlaying || fragPlaying.level !== fragCurrentLevel) { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].LEVEL_SWITCHED, { + level: fragCurrentLevel, + }); + } - this.fragPlaying = fragPlayingCurrent; - } - } - } - }; + this.fragPlaying = fragPlayingCurrent; + } + } + } + }; - _createClass(StreamController, [{ - key: "nextLevel", - get: function get() { - var frag = this.nextBufferedFrag; + _createClass(StreamController, [ + { + key: "nextLevel", + get: function get() { + var frag = this.nextBufferedFrag; - if (frag) { - return frag.level; - } else { - return -1; - } - } - }, { - key: "currentLevel", - get: function get() { - var media = this.media; + if (frag) { + return frag.level; + } else { + return -1; + } + }, + }, + { + key: "currentLevel", + get: function get() { + var media = this.media; - if (media) { - var fragPlayingCurrent = this.getAppendedFrag(media.currentTime); + if (media) { + var fragPlayingCurrent = this.getAppendedFrag(media.currentTime); - if (fragPlayingCurrent) { - return fragPlayingCurrent.level; - } - } + if (fragPlayingCurrent) { + return fragPlayingCurrent.level; + } + } - return -1; - } - }, { - key: "nextBufferedFrag", - get: function get() { - var media = this.media; + return -1; + }, + }, + { + key: "nextBufferedFrag", + get: function get() { + var media = this.media; - if (media) { - // first get end range of current fragment - var fragPlayingCurrent = this.getAppendedFrag(media.currentTime); - return this.followingBufferedFrag(fragPlayingCurrent); - } else { - return null; - } - } - }, { - key: "forceStartLoad", - get: function get() { - return this._forceStartLoad; - } - }]); + if (media) { + // first get end range of current fragment + var fragPlayingCurrent = this.getAppendedFrag(media.currentTime); + return this.followingBufferedFrag(fragPlayingCurrent); + } else { + return null; + } + }, + }, + { + key: "forceStartLoad", + get: function get() { + return this._forceStartLoad; + }, + }, + ]); - return StreamController; -}(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]); + return StreamController; + })(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]); + /***/ + }, - -/***/ }), - -/***/ "./src/controller/subtitle-stream-controller.ts": -/*!******************************************************!*\ + /***/ "./src/controller/subtitle-stream-controller.ts": + /*!******************************************************!*\ !*** ./src/controller/subtitle-stream-controller.ts ***! \******************************************************/ -/*! exports provided: SubtitleStreamController */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubtitleStreamController", function() { return SubtitleStreamController; }); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); -/* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts"); -/* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts"); -/* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); -/* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); -/* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -/* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - - - - - - - - - - - -var TICK_INTERVAL = 500; // how often to tick in ms - -var SubtitleStreamController = /*#__PURE__*/function (_BaseStreamController) { - _inheritsLoose(SubtitleStreamController, _BaseStreamController); - - function SubtitleStreamController(CiderHls, fragmentTracker) { - var _this; - - _this = _BaseStreamController.call(this, CiderHls, fragmentTracker, '[subtitle-stream-controller]') || this; - _this.levels = []; - _this.currentTrackId = -1; - _this.tracksBuffered = []; - _this.mainDetails = null; - - _this._registerListeners(); - - return _this; - } - - var _proto = SubtitleStreamController.prototype; - - _proto.onHandlerDestroying = function onHandlerDestroying() { - this._unregisterListeners(); - - this.mainDetails = null; - }; - - _proto._registerListeners = function _registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); - }; - - _proto._unregisterListeners = function _unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); - }; - - _proto.startLoad = function startLoad() { - this.stopLoad(); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; - this.setInterval(TICK_INTERVAL); - this.tick(); - }; - - _proto.onManifestLoading = function onManifestLoading() { - this.mainDetails = null; - this.fragmentTracker.removeAllFragments(); - }; - - _proto.onLevelLoaded = function onLevelLoaded(event, data) { - this.mainDetails = data.details; - }; - - _proto.onSubtitleFragProcessed = function onSubtitleFragProcessed(event, data) { - var frag = data.frag, - success = data.success; - this.fragPrevious = frag; - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; - - if (!success) { - return; - } - - var buffered = this.tracksBuffered[this.currentTrackId]; - - if (!buffered) { - return; - } // Create/update a buffered array matching the interface used by BufferHelper.bufferedInfo - // so we can re-use the logic used to detect how much has been buffered - - - var timeRange; - var fragStart = frag.start; - - for (var i = 0; i < buffered.length; i++) { - if (fragStart >= buffered[i].start && fragStart <= buffered[i].end) { - timeRange = buffered[i]; - break; - } - } - - var fragEnd = frag.start + frag.duration; - - if (timeRange) { - timeRange.end = fragEnd; - } else { - timeRange = { - start: fragStart, - end: fragEnd - }; - buffered.push(timeRange); - } - - this.fragmentTracker.fragBuffered(frag); - }; - - _proto.onBufferFlushing = function onBufferFlushing(event, data) { - var startOffset = data.startOffset, - endOffset = data.endOffset; - - if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) { - var currentTrackId = this.currentTrackId, - levels = this.levels; - - if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) { - return; - } - - var trackDetails = levels[currentTrackId].details; - var targetDuration = trackDetails.targetduration; - var endOffsetSubtitles = endOffset - targetDuration; - - if (endOffsetSubtitles <= 0) { - return; - } - - data.endOffsetSubtitles = Math.max(0, endOffsetSubtitles); - this.tracksBuffered.forEach(function (buffered) { - for (var i = 0; i < buffered.length;) { - if (buffered[i].end <= endOffsetSubtitles) { - buffered.shift(); - continue; - } else if (buffered[i].start < endOffsetSubtitles) { - buffered[i].start = endOffsetSubtitles; - } else { - break; - } - - i++; - } - }); - this.fragmentTracker.removeFragmentsInRange(startOffset, endOffsetSubtitles, _types_loader__WEBPACK_IMPORTED_MODULE_8__["PlaylistLevelType"].SUBTITLE); - } - } // If something goes wrong, proceed to next frag, if we were processing one. - ; - - _proto.onError = function onError(event, data) { - var _this$fragCurrent; - - var frag = data.frag; // don't handle error not related to subtitle fragment - - if (!frag || frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_8__["PlaylistLevelType"].SUBTITLE) { - return; - } - - if ((_this$fragCurrent = this.fragCurrent) !== null && _this$fragCurrent !== void 0 && _this$fragCurrent.loader) { - this.fragCurrent.loader.abort(); - } - - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; - } // Got all new subtitle levels. - ; - - _proto.onSubtitleTracksUpdated = function onSubtitleTracksUpdated(event, _ref) { - var _this2 = this; - - var subtitleTracks = _ref.subtitleTracks; - this.tracksBuffered = []; - this.levels = subtitleTracks.map(function (mediaPlaylist) { - return new _types_level__WEBPACK_IMPORTED_MODULE_9__["Level"](mediaPlaylist); - }); - this.fragmentTracker.removeAllFragments(); - this.fragPrevious = null; - this.levels.forEach(function (level) { - _this2.tracksBuffered[level.id] = []; - }); - this.mediaBuffer = null; - }; - - _proto.onSubtitleTrackSwitch = function onSubtitleTrackSwitch(event, data) { - this.currentTrackId = data.id; - - if (!this.levels.length || this.currentTrackId === -1) { - this.clearInterval(); - return; - } // Check if track has the necessary details to load fragments - - - var currentTrack = this.levels[this.currentTrackId]; - - if (currentTrack !== null && currentTrack !== void 0 && currentTrack.details) { - this.mediaBuffer = this.mediaBufferTimeRanges; - } else { - this.mediaBuffer = null; - } - - if (currentTrack) { - this.setInterval(TICK_INTERVAL); - } - } // Got a new set of subtitle fragments. - ; - - _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(event, data) { - var _track$details; - - var newDetails = data.details, - trackId = data.id; - var currentTrackId = this.currentTrackId, - levels = this.levels; - - if (!levels.length) { - return; - } - - var track = levels[currentTrackId]; - - if (trackId >= levels.length || trackId !== currentTrackId || !track) { - return; - } - - this.mediaBuffer = this.mediaBufferTimeRanges; - - if (newDetails.live || (_track$details = track.details) !== null && _track$details !== void 0 && _track$details.live) { - var mainDetails = this.mainDetails; - - if (newDetails.deltaUpdateFailed || !mainDetails) { - return; - } - - var mainSlidingStartFragment = mainDetails.fragments[0]; - - if (!track.details) { - if (newDetails.hasProgramDateTime && mainDetails.hasProgramDateTime) { - Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_4__["alignMediaPlaylistByPDT"])(newDetails, mainDetails); - } else if (mainSlidingStartFragment) { - // line up live playlist with main so that fragments in range are loaded - Object(_level_helper__WEBPACK_IMPORTED_MODULE_5__["addSliding"])(newDetails, mainSlidingStartFragment.start); - } - } else { - var sliding = this.alignPlaylists(newDetails, track.details); - - if (sliding === 0 && mainSlidingStartFragment) { - // realign with main when there is no overlap with last refresh - Object(_level_helper__WEBPACK_IMPORTED_MODULE_5__["addSliding"])(newDetails, mainSlidingStartFragment.start); - } - } - } - - track.details = newDetails; - this.levelLastLoaded = trackId; // trigger handler right now - - this.tick(); // If playlist is misaligned because of bad PDT or drift, delete details to resync with main on reload - - if (newDetails.live && !this.fragCurrent && this.media && this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE) { - var foundFrag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_3__["findFragmentByPTS"])(null, newDetails.fragments, this.media.currentTime, 0); - - if (!foundFrag) { - this.warn('Subtitle playlist not aligned with playback'); - track.details = undefined; - } - } - }; - - _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedData) { - var frag = fragLoadedData.frag, - payload = fragLoadedData.payload; - var decryptData = frag.decryptdata; - var CiderHls = this.CiderHls; - - if (this.fragContextChanged(frag)) { - return; - } // check to see if the payload needs to be decrypted - - - if (payload && payload.byteLength > 0 && decryptData && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') { - var startTime = performance.now(); // decrypt the subtitles - - this.decrypter.webCryptoDecrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).then(function (decryptedData) { - var endTime = performance.now(); - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_DECRYPTED, { - frag: frag, - payload: decryptedData, - stats: { - tstart: startTime, - tdecrypt: endTime - } - }); - }); - } - }; - - _proto.doTick = function doTick() { - if (!this.media) { - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; - return; - } - - if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE) { - var _foundFrag; - - var currentTrackId = this.currentTrackId, - levels = this.levels; - - if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) { - return; - } // Expand range of subs loaded by one target-duration in either direction to make up for misaligned playlists - - - var trackDetails = levels[currentTrackId].details; - var targetDuration = trackDetails.targetduration; - var config = this.config, - media = this.media; - var bufferedInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__["BufferHelper"].bufferedInfo(this.mediaBufferTimeRanges, media.currentTime - targetDuration, config.maxBufferHole); - var targetBufferTime = bufferedInfo.end, - bufferLen = bufferedInfo.len; - var maxBufLen = this.getMaxBufferLength() + targetDuration; - - if (bufferLen > maxBufLen) { - return; - } - - console.assert(trackDetails, 'Subtitle track details are defined on idle subtitle stream controller tick'); - var fragments = trackDetails.fragments; - var fragLen = fragments.length; - var end = trackDetails.edge; - var foundFrag; - var fragPrevious = this.fragPrevious; - - if (targetBufferTime < end) { - var maxFragLookUpTolerance = config.maxFragLookUpTolerance; - - if (fragPrevious && trackDetails.hasProgramDateTime) { - foundFrag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_3__["findFragmentByPDT"])(fragments, fragPrevious.endProgramDateTime, maxFragLookUpTolerance); - } - - if (!foundFrag) { - foundFrag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_3__["findFragmentByPTS"])(fragPrevious, fragments, targetBufferTime, maxFragLookUpTolerance); - - if (!foundFrag && fragPrevious && fragPrevious.start < fragments[0].start) { - foundFrag = fragments[0]; - } - } - } else { - foundFrag = fragments[fragLen - 1]; - } - - if ((_foundFrag = foundFrag) !== null && _foundFrag !== void 0 && _foundFrag.encrypted) { - _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("Loading key for " + foundFrag.sn); - this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].KEY_LOADING; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADING, { - frag: foundFrag - }); - } else if (foundFrag && this.fragmentTracker.getState(foundFrag) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_6__["FragmentState"].NOT_LOADED) { - // only load if fragment is not loaded - this.loadFragment(foundFrag, trackDetails, targetBufferTime); - } - } - }; - - _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) { - this.fragCurrent = frag; - - _BaseStreamController.prototype.loadFragment.call(this, frag, levelDetails, targetBufferTime); - }; - - _createClass(SubtitleStreamController, [{ - key: "mediaBufferTimeRanges", - get: function get() { - return this.tracksBuffered[this.currentTrackId] || []; - } - }]); - - return SubtitleStreamController; -}(_base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["default"]); - -/***/ }), - -/***/ "./src/controller/subtitle-track-controller.ts": -/*!*****************************************************!*\ + /*! exports provided: SubtitleStreamController */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubtitleStreamController", function () { + return SubtitleStreamController; + }); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts"); + /* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts"); + /* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts"); + /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts"); + /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts"); + /* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } + + var TICK_INTERVAL = 500; // how often to tick in ms + + var SubtitleStreamController = /*#__PURE__*/ (function (_BaseStreamController) { + _inheritsLoose(SubtitleStreamController, _BaseStreamController); + + function SubtitleStreamController(CiderHls, fragmentTracker) { + var _this; + + _this = _BaseStreamController.call(this, CiderHls, fragmentTracker, "[subtitle-stream-controller]") || this; + _this.levels = []; + _this.currentTrackId = -1; + _this.tracksBuffered = []; + _this.mainDetails = null; + + _this._registerListeners(); + + return _this; + } + + var _proto = SubtitleStreamController.prototype; + + _proto.onHandlerDestroying = function onHandlerDestroying() { + this._unregisterListeners(); + + this.mainDetails = null; + }; + + _proto._registerListeners = function _registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); + }; + + _proto._unregisterListeners = function _unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADED, this.onLevelLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); + }; + + _proto.startLoad = function startLoad() { + this.stopLoad(); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; + this.setInterval(TICK_INTERVAL); + this.tick(); + }; + + _proto.onManifestLoading = function onManifestLoading() { + this.mainDetails = null; + this.fragmentTracker.removeAllFragments(); + }; + + _proto.onLevelLoaded = function onLevelLoaded(event, data) { + this.mainDetails = data.details; + }; + + _proto.onSubtitleFragProcessed = function onSubtitleFragProcessed(event, data) { + var frag = data.frag, + success = data.success; + this.fragPrevious = frag; + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; + + if (!success) { + return; + } + + var buffered = this.tracksBuffered[this.currentTrackId]; + + if (!buffered) { + return; + } // Create/update a buffered array matching the interface used by BufferHelper.bufferedInfo + // so we can re-use the logic used to detect how much has been buffered + + var timeRange; + var fragStart = frag.start; + + for (var i = 0; i < buffered.length; i++) { + if (fragStart >= buffered[i].start && fragStart <= buffered[i].end) { + timeRange = buffered[i]; + break; + } + } + + var fragEnd = frag.start + frag.duration; + + if (timeRange) { + timeRange.end = fragEnd; + } else { + timeRange = { + start: fragStart, + end: fragEnd, + }; + buffered.push(timeRange); + } + + this.fragmentTracker.fragBuffered(frag); + }; + + _proto.onBufferFlushing = function onBufferFlushing(event, data) { + var startOffset = data.startOffset, + endOffset = data.endOffset; + + if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) { + var currentTrackId = this.currentTrackId, + levels = this.levels; + + if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) { + return; + } + + var trackDetails = levels[currentTrackId].details; + var targetDuration = trackDetails.targetduration; + var endOffsetSubtitles = endOffset - targetDuration; + + if (endOffsetSubtitles <= 0) { + return; + } + + data.endOffsetSubtitles = Math.max(0, endOffsetSubtitles); + this.tracksBuffered.forEach(function (buffered) { + for (var i = 0; i < buffered.length; ) { + if (buffered[i].end <= endOffsetSubtitles) { + buffered.shift(); + continue; + } else if (buffered[i].start < endOffsetSubtitles) { + buffered[i].start = endOffsetSubtitles; + } else { + break; + } + + i++; + } + }); + this.fragmentTracker.removeFragmentsInRange(startOffset, endOffsetSubtitles, _types_loader__WEBPACK_IMPORTED_MODULE_8__["PlaylistLevelType"].SUBTITLE); + } + }; // If something goes wrong, proceed to next frag, if we were processing one. + + _proto.onError = function onError(event, data) { + var _this$fragCurrent; + + var frag = data.frag; // don't handle error not related to subtitle fragment + + if (!frag || frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_8__["PlaylistLevelType"].SUBTITLE) { + return; + } + + if ((_this$fragCurrent = this.fragCurrent) !== null && _this$fragCurrent !== void 0 && _this$fragCurrent.loader) { + this.fragCurrent.loader.abort(); + } + + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; + }; // Got all new subtitle levels. + + _proto.onSubtitleTracksUpdated = function onSubtitleTracksUpdated(event, _ref) { + var _this2 = this; + + var subtitleTracks = _ref.subtitleTracks; + this.tracksBuffered = []; + this.levels = subtitleTracks.map(function (mediaPlaylist) { + return new _types_level__WEBPACK_IMPORTED_MODULE_9__["Level"](mediaPlaylist); + }); + this.fragmentTracker.removeAllFragments(); + this.fragPrevious = null; + this.levels.forEach(function (level) { + _this2.tracksBuffered[level.id] = []; + }); + this.mediaBuffer = null; + }; + + _proto.onSubtitleTrackSwitch = function onSubtitleTrackSwitch(event, data) { + this.currentTrackId = data.id; + + if (!this.levels.length || this.currentTrackId === -1) { + this.clearInterval(); + return; + } // Check if track has the necessary details to load fragments + + var currentTrack = this.levels[this.currentTrackId]; + + if (currentTrack !== null && currentTrack !== void 0 && currentTrack.details) { + this.mediaBuffer = this.mediaBufferTimeRanges; + } else { + this.mediaBuffer = null; + } + + if (currentTrack) { + this.setInterval(TICK_INTERVAL); + } + }; // Got a new set of subtitle fragments. + + _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(event, data) { + var _track$details; + + var newDetails = data.details, + trackId = data.id; + var currentTrackId = this.currentTrackId, + levels = this.levels; + + if (!levels.length) { + return; + } + + var track = levels[currentTrackId]; + + if (trackId >= levels.length || trackId !== currentTrackId || !track) { + return; + } + + this.mediaBuffer = this.mediaBufferTimeRanges; + + if (newDetails.live || ((_track$details = track.details) !== null && _track$details !== void 0 && _track$details.live)) { + var mainDetails = this.mainDetails; + + if (newDetails.deltaUpdateFailed || !mainDetails) { + return; + } + + var mainSlidingStartFragment = mainDetails.fragments[0]; + + if (!track.details) { + if (newDetails.hasProgramDateTime && mainDetails.hasProgramDateTime) { + Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_4__["alignMediaPlaylistByPDT"])(newDetails, mainDetails); + } else if (mainSlidingStartFragment) { + // line up live playlist with main so that fragments in range are loaded + Object(_level_helper__WEBPACK_IMPORTED_MODULE_5__["addSliding"])(newDetails, mainSlidingStartFragment.start); + } + } else { + var sliding = this.alignPlaylists(newDetails, track.details); + + if (sliding === 0 && mainSlidingStartFragment) { + // realign with main when there is no overlap with last refresh + Object(_level_helper__WEBPACK_IMPORTED_MODULE_5__["addSliding"])(newDetails, mainSlidingStartFragment.start); + } + } + } + + track.details = newDetails; + this.levelLastLoaded = trackId; // trigger handler right now + + this.tick(); // If playlist is misaligned because of bad PDT or drift, delete details to resync with main on reload + + if (newDetails.live && !this.fragCurrent && this.media && this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE) { + var foundFrag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_3__["findFragmentByPTS"])(null, newDetails.fragments, this.media.currentTime, 0); + + if (!foundFrag) { + this.warn("Subtitle playlist not aligned with playback"); + track.details = undefined; + } + } + }; + + _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedData) { + var frag = fragLoadedData.frag, + payload = fragLoadedData.payload; + var decryptData = frag.decryptdata; + var CiderHls = this.CiderHls; + + if (this.fragContextChanged(frag)) { + return; + } // check to see if the payload needs to be decrypted + + if (payload && payload.byteLength > 0 && decryptData && decryptData.key && decryptData.iv && decryptData.method === "AES-128") { + var startTime = performance.now(); // decrypt the subtitles + + this.decrypter.webCryptoDecrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).then(function (decryptedData) { + var endTime = performance.now(); + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].FRAG_DECRYPTED, { + frag: frag, + payload: decryptedData, + stats: { + tstart: startTime, + tdecrypt: endTime, + }, + }); + }); + } + }; + + _proto.doTick = function doTick() { + if (!this.media) { + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE; + return; + } + + if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].IDLE) { + var _foundFrag; + + var currentTrackId = this.currentTrackId, + levels = this.levels; + + if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) { + return; + } // Expand range of subs loaded by one target-duration in either direction to make up for misaligned playlists + + var trackDetails = levels[currentTrackId].details; + var targetDuration = trackDetails.targetduration; + var config = this.config, + media = this.media; + var bufferedInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__["BufferHelper"].bufferedInfo(this.mediaBufferTimeRanges, media.currentTime - targetDuration, config.maxBufferHole); + var targetBufferTime = bufferedInfo.end, + bufferLen = bufferedInfo.len; + var maxBufLen = this.getMaxBufferLength() + targetDuration; + + if (bufferLen > maxBufLen) { + return; + } + + console.assert(trackDetails, "Subtitle track details are defined on idle subtitle stream controller tick"); + var fragments = trackDetails.fragments; + var fragLen = fragments.length; + var end = trackDetails.edge; + var foundFrag; + var fragPrevious = this.fragPrevious; + + if (targetBufferTime < end) { + var maxFragLookUpTolerance = config.maxFragLookUpTolerance; + + if (fragPrevious && trackDetails.hasProgramDateTime) { + foundFrag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_3__["findFragmentByPDT"])(fragments, fragPrevious.endProgramDateTime, maxFragLookUpTolerance); + } + + if (!foundFrag) { + foundFrag = Object(_fragment_finders__WEBPACK_IMPORTED_MODULE_3__["findFragmentByPTS"])(fragPrevious, fragments, targetBufferTime, maxFragLookUpTolerance); + + if (!foundFrag && fragPrevious && fragPrevious.start < fragments[0].start) { + foundFrag = fragments[0]; + } + } + } else { + foundFrag = fragments[fragLen - 1]; + } + + if ((_foundFrag = foundFrag) !== null && _foundFrag !== void 0 && _foundFrag.encrypted) { + _utils_logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("Loading key for " + foundFrag.sn); + this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["State"].KEY_LOADING; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADING, { + frag: foundFrag, + }); + } else if (foundFrag && this.fragmentTracker.getState(foundFrag) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_6__["FragmentState"].NOT_LOADED) { + // only load if fragment is not loaded + this.loadFragment(foundFrag, trackDetails, targetBufferTime); + } + } + }; + + _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) { + this.fragCurrent = frag; + + _BaseStreamController.prototype.loadFragment.call(this, frag, levelDetails, targetBufferTime); + }; + + _createClass(SubtitleStreamController, [ + { + key: "mediaBufferTimeRanges", + get: function get() { + return this.tracksBuffered[this.currentTrackId] || []; + }, + }, + ]); + + return SubtitleStreamController; + })(_base_stream_controller__WEBPACK_IMPORTED_MODULE_7__["default"]); + + /***/ + }, + + /***/ "./src/controller/subtitle-track-controller.ts": + /*!*****************************************************!*\ !*** ./src/controller/subtitle-track-controller.ts ***! \*****************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts"); -/* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - - - - - - -var SubtitleTrackController = /*#__PURE__*/function (_BasePlaylistControll) { - _inheritsLoose(SubtitleTrackController, _BasePlaylistControll); - - // Enable/disable subtitle display rendering - function SubtitleTrackController(CiderHls) { - var _this; - - _this = _BasePlaylistControll.call(this, CiderHls, '[subtitle-track-controller]') || this; - _this.media = null; - _this.tracks = []; - _this.groupId = null; - _this.tracksInGroup = []; - _this.trackId = -1; - _this.selectDefaultTrack = true; - _this.queuedDefaultTrack = -1; - - _this.trackChangeListener = function () { - return _this.onTextTracksChanged(); - }; - - _this.asyncPollTrackChange = function () { - return _this.pollTrackChange(0); - }; - - _this.useTextTrackPolling = false; - _this.subtitlePollingInterval = -1; - _this.subtitleDisplay = true; - - _this.registerListeners(); - - return _this; - } - - var _proto = SubtitleTrackController.prototype; - - _proto.destroy = function destroy() { - this.unregisterListeners(); - this.tracks.length = 0; - this.tracksInGroup.length = 0; - this.trackChangeListener = this.asyncPollTrackChange = null; - - _BasePlaylistControll.prototype.destroy.call(this); - }; - - _proto.registerListeners = function registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); - }; - - _proto.unregisterListeners = function unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); - } // Listen for subtitle track change, then extract the current track ID. - ; - - _proto.onMediaAttached = function onMediaAttached(event, data) { - this.media = data.media; - - if (!this.media) { - return; - } - - if (this.queuedDefaultTrack > -1) { - this.subtitleTrack = this.queuedDefaultTrack; - this.queuedDefaultTrack = -1; - } - - this.useTextTrackPolling = !(this.media.textTracks && 'onchange' in this.media.textTracks); - - if (this.useTextTrackPolling) { - this.pollTrackChange(500); - } else { - this.media.textTracks.addEventListener('change', this.asyncPollTrackChange); - } - }; - - _proto.pollTrackChange = function pollTrackChange(timeout) { - self.clearInterval(this.subtitlePollingInterval); - this.subtitlePollingInterval = self.setInterval(this.trackChangeListener, timeout); - }; - - _proto.onMediaDetaching = function onMediaDetaching() { - if (!this.media) { - return; - } - - self.clearInterval(this.subtitlePollingInterval); - - if (!this.useTextTrackPolling) { - this.media.textTracks.removeEventListener('change', this.asyncPollTrackChange); - } - - if (this.trackId > -1) { - this.queuedDefaultTrack = this.trackId; - } - - var textTracks = filterSubtitleTracks(this.media.textTracks); // Clear loaded cues on media detachment from tracks - - textTracks.forEach(function (track) { - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["clearCurrentCues"])(track); - }); // Disable all subtitle tracks before detachment so when reattached only tracks in that content are enabled. - - this.subtitleTrack = -1; - this.media = null; - }; - - _proto.onManifestLoading = function onManifestLoading() { - this.tracks = []; - this.groupId = null; - this.tracksInGroup = []; - this.trackId = -1; - this.selectDefaultTrack = true; - } // Fired whenever a new manifest is loaded. - ; - - _proto.onManifestParsed = function onManifestParsed(event, data) { - this.tracks = data.subtitleTracks; - }; - - _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(event, data) { - var id = data.id, - details = data.details; - var trackId = this.trackId; - var currentTrack = this.tracksInGroup[trackId]; - - if (!currentTrack) { - this.warn("Invalid subtitle track id " + id); - return; - } - - var curDetails = currentTrack.details; - currentTrack.details = data.details; - this.log("subtitle track " + id + " loaded [" + details.startSN + "-" + details.endSN + "]"); - - if (id === this.trackId) { - this.retryCount = 0; - this.playlistLoaded(id, data, curDetails); - } - }; - - _proto.onLevelLoading = function onLevelLoading(event, data) { - this.switchLevel(data.level); - }; - - _proto.onLevelSwitching = function onLevelSwitching(event, data) { - this.switchLevel(data.level); - }; - - _proto.switchLevel = function switchLevel(levelIndex) { - var levelInfo = this.CiderHls.levels[levelIndex]; - - if (!(levelInfo !== null && levelInfo !== void 0 && levelInfo.textGroupIds)) { - return; - } - - var textGroupId = levelInfo.textGroupIds[levelInfo.urlId]; - - if (this.groupId !== textGroupId) { - var lastTrack = this.tracksInGroup ? this.tracksInGroup[this.trackId] : undefined; - var subtitleTracks = this.tracks.filter(function (track) { - return !textGroupId || track.groupId === textGroupId; - }); - this.tracksInGroup = subtitleTracks; - var initialTrackId = this.findTrackId(lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.name) || this.findTrackId(); - this.groupId = textGroupId; - var subtitleTracksUpdated = { - subtitleTracks: subtitleTracks - }; - this.log("Updating subtitle tracks, " + subtitleTracks.length + " track(s) found in \"" + textGroupId + "\" group-id"); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACKS_UPDATED, subtitleTracksUpdated); - - if (initialTrackId !== -1) { - this.setSubtitleTrack(initialTrackId, lastTrack); - } - } - }; - - _proto.findTrackId = function findTrackId(name) { - var textTracks = this.tracksInGroup; - - for (var i = 0; i < textTracks.length; i++) { - var track = textTracks[i]; - - if (!this.selectDefaultTrack || track.default) { - if (!name || name === track.name) { - return track.id; - } - } - } - - return -1; - }; - - _proto.onError = function onError(event, data) { - _BasePlaylistControll.prototype.onError.call(this, event, data); - - if (data.fatal || !data.context) { - return; - } - - if (data.context.type === _types_loader__WEBPACK_IMPORTED_MODULE_3__["PlaylistContextType"].SUBTITLE_TRACK && data.context.id === this.trackId && data.context.groupId === this.groupId) { - this.retryLoadingOrFail(data); - } - } - /** get alternate subtitle tracks list from playlist **/ - ; - - _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) { - var currentTrack = this.tracksInGroup[this.trackId]; - - if (this.shouldLoadTrack(currentTrack)) { - var id = currentTrack.id; - var groupId = currentTrack.groupId; - var url = currentTrack.url; - - if (CiderHlsUrlParameters) { - try { - url = CiderHlsUrlParameters.addDirectives(url); - } catch (error) { - this.warn("Could not construct new URL with CiderHls Delivery Directives: " + error); - } - } - - this.log("Loading subtitle playlist for id " + id); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADING, { - url: url, - id: id, - groupId: groupId, - deliveryDirectives: CiderHlsUrlParameters || null - }); - } - } - /** - * Disables the old subtitleTrack and sets current mode on the next subtitleTrack. - * This operates on the DOM textTracks. - * A value of -1 will disable all subtitle tracks. - */ - ; - - _proto.toggleTrackModes = function toggleTrackModes(newId) { - var _this2 = this; - - var media = this.media, - subtitleDisplay = this.subtitleDisplay, - trackId = this.trackId; - - if (!media) { - return; - } - - var textTracks = filterSubtitleTracks(media.textTracks); - var groupTracks = textTracks.filter(function (track) { - return track.groupId === _this2.groupId; - }); - - if (newId === -1) { - [].slice.call(textTracks).forEach(function (track) { - track.mode = 'disabled'; - }); - } else { - var oldTrack = groupTracks[trackId]; - - if (oldTrack) { - oldTrack.mode = 'disabled'; - } - } - - var nextTrack = groupTracks[newId]; - - if (nextTrack) { - nextTrack.mode = subtitleDisplay ? 'showing' : 'hidden'; - } - } - /** - * This method is responsible for validating the subtitle index and periodically reloading if live. - * Dispatches the SUBTITLE_TRACK_SWITCH event, which instructs the subtitle-stream-controller to load the selected track. - */ - ; - - _proto.setSubtitleTrack = function setSubtitleTrack(newId, lastTrack) { - var _tracks$newId; - - var tracks = this.tracksInGroup; // setting this.subtitleTrack will trigger internal logic - // if media has not been attached yet, it will fail - // we keep a reference to the default track id - // and we'll set subtitleTrack when onMediaAttached is triggered - - if (!this.media) { - this.queuedDefaultTrack = newId; - return; - } - - if (this.trackId !== newId) { - this.toggleTrackModes(newId); - } // exit if track id as already set or invalid - - - if (this.trackId === newId && (newId === -1 || (_tracks$newId = tracks[newId]) !== null && _tracks$newId !== void 0 && _tracks$newId.details) || newId < -1 || newId >= tracks.length) { - return; - } // stopping live reloading timer if any - - - this.clearTimer(); - var track = tracks[newId]; - this.log("Switching to subtitle track " + newId); - this.trackId = newId; - - if (track) { - var id = track.id, - _track$groupId = track.groupId, - groupId = _track$groupId === void 0 ? '' : _track$groupId, - name = track.name, - type = track.type, - url = track.url; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, { - id: id, - groupId: groupId, - name: name, - type: type, - url: url - }); - var CiderHlsUrlParameters = this.switchParams(track.url, lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.details); - this.loadPlaylist(CiderHlsUrlParameters); - } else { - // switch to -1 - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, { - id: newId - }); - } - }; - - _proto.onTextTracksChanged = function onTextTracksChanged() { - if (!this.useTextTrackPolling) { - self.clearInterval(this.subtitlePollingInterval); - } // Media is undefined when switching streams via loadSource() - - - if (!this.media || !this.CiderHls.config.renderTextTracksNatively) { - return; - } - - var trackId = -1; - var tracks = filterSubtitleTracks(this.media.textTracks); - - for (var id = 0; id < tracks.length; id++) { - if (tracks[id].mode === 'hidden') { - // Do not break in case there is a following track with showing. - trackId = id; - } else if (tracks[id].mode === 'showing') { - trackId = id; - break; - } - } // Setting current subtitleTrack will invoke code. - - - if (this.subtitleTrack !== trackId) { - this.subtitleTrack = trackId; - } - }; - - _createClass(SubtitleTrackController, [{ - key: "subtitleTracks", - get: function get() { - return this.tracksInGroup; - } - /** get/set index of the selected subtitle track (based on index in subtitle track lists) **/ - - }, { - key: "subtitleTrack", - get: function get() { - return this.trackId; - }, - set: function set(newId) { - this.selectDefaultTrack = false; - var lastTrack = this.tracksInGroup ? this.tracksInGroup[this.trackId] : undefined; - this.setSubtitleTrack(newId, lastTrack); - } - }]); - - return SubtitleTrackController; -}(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]); - -function filterSubtitleTracks(textTrackList) { - var tracks = []; - - for (var i = 0; i < textTrackList.length; i++) { - var track = textTrackList[i]; // Edge adds a track without a label; we don't want to use it - - if (track.kind === 'subtitles' && track.label) { - tracks.push(textTrackList[i]); - } - } - - return tracks; -} - -/* harmony default export */ __webpack_exports__["default"] = (SubtitleTrackController); - -/***/ }), - -/***/ "./src/controller/timeline-controller.ts": -/*!***********************************************!*\ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts"); + /* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } + + var SubtitleTrackController = /*#__PURE__*/ (function (_BasePlaylistControll) { + _inheritsLoose(SubtitleTrackController, _BasePlaylistControll); + + // Enable/disable subtitle display rendering + function SubtitleTrackController(CiderHls) { + var _this; + + _this = _BasePlaylistControll.call(this, CiderHls, "[subtitle-track-controller]") || this; + _this.media = null; + _this.tracks = []; + _this.groupId = null; + _this.tracksInGroup = []; + _this.trackId = -1; + _this.selectDefaultTrack = true; + _this.queuedDefaultTrack = -1; + + _this.trackChangeListener = function () { + return _this.onTextTracksChanged(); + }; + + _this.asyncPollTrackChange = function () { + return _this.pollTrackChange(0); + }; + + _this.useTextTrackPolling = false; + _this.subtitlePollingInterval = -1; + _this.subtitleDisplay = true; + + _this.registerListeners(); + + return _this; + } + + var _proto = SubtitleTrackController.prototype; + + _proto.destroy = function destroy() { + this.unregisterListeners(); + this.tracks.length = 0; + this.tracksInGroup.length = 0; + this.trackChangeListener = this.asyncPollTrackChange = null; + + _BasePlaylistControll.prototype.destroy.call(this); + }; + + _proto.registerListeners = function registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); + }; + + _proto.unregisterListeners = function unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_ATTACHED, this.onMediaAttached, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].MANIFEST_PARSED, this.onManifestParsed, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_LOADING, this.onLevelLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].LEVEL_SWITCHING, this.onLevelSwitching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, this.onError, this); + }; // Listen for subtitle track change, then extract the current track ID. + + _proto.onMediaAttached = function onMediaAttached(event, data) { + this.media = data.media; + + if (!this.media) { + return; + } + + if (this.queuedDefaultTrack > -1) { + this.subtitleTrack = this.queuedDefaultTrack; + this.queuedDefaultTrack = -1; + } + + this.useTextTrackPolling = !(this.media.textTracks && "onchange" in this.media.textTracks); + + if (this.useTextTrackPolling) { + this.pollTrackChange(500); + } else { + this.media.textTracks.addEventListener("change", this.asyncPollTrackChange); + } + }; + + _proto.pollTrackChange = function pollTrackChange(timeout) { + self.clearInterval(this.subtitlePollingInterval); + this.subtitlePollingInterval = self.setInterval(this.trackChangeListener, timeout); + }; + + _proto.onMediaDetaching = function onMediaDetaching() { + if (!this.media) { + return; + } + + self.clearInterval(this.subtitlePollingInterval); + + if (!this.useTextTrackPolling) { + this.media.textTracks.removeEventListener("change", this.asyncPollTrackChange); + } + + if (this.trackId > -1) { + this.queuedDefaultTrack = this.trackId; + } + + var textTracks = filterSubtitleTracks(this.media.textTracks); // Clear loaded cues on media detachment from tracks + + textTracks.forEach(function (track) { + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__["clearCurrentCues"])(track); + }); // Disable all subtitle tracks before detachment so when reattached only tracks in that content are enabled. + + this.subtitleTrack = -1; + this.media = null; + }; + + _proto.onManifestLoading = function onManifestLoading() { + this.tracks = []; + this.groupId = null; + this.tracksInGroup = []; + this.trackId = -1; + this.selectDefaultTrack = true; + }; // Fired whenever a new manifest is loaded. + + _proto.onManifestParsed = function onManifestParsed(event, data) { + this.tracks = data.subtitleTracks; + }; + + _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(event, data) { + var id = data.id, + details = data.details; + var trackId = this.trackId; + var currentTrack = this.tracksInGroup[trackId]; + + if (!currentTrack) { + this.warn("Invalid subtitle track id " + id); + return; + } + + var curDetails = currentTrack.details; + currentTrack.details = data.details; + this.log("subtitle track " + id + " loaded [" + details.startSN + "-" + details.endSN + "]"); + + if (id === this.trackId) { + this.retryCount = 0; + this.playlistLoaded(id, data, curDetails); + } + }; + + _proto.onLevelLoading = function onLevelLoading(event, data) { + this.switchLevel(data.level); + }; + + _proto.onLevelSwitching = function onLevelSwitching(event, data) { + this.switchLevel(data.level); + }; + + _proto.switchLevel = function switchLevel(levelIndex) { + var levelInfo = this.CiderHls.levels[levelIndex]; + + if (!(levelInfo !== null && levelInfo !== void 0 && levelInfo.textGroupIds)) { + return; + } + + var textGroupId = levelInfo.textGroupIds[levelInfo.urlId]; + + if (this.groupId !== textGroupId) { + var lastTrack = this.tracksInGroup ? this.tracksInGroup[this.trackId] : undefined; + var subtitleTracks = this.tracks.filter(function (track) { + return !textGroupId || track.groupId === textGroupId; + }); + this.tracksInGroup = subtitleTracks; + var initialTrackId = this.findTrackId(lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.name) || this.findTrackId(); + this.groupId = textGroupId; + var subtitleTracksUpdated = { + subtitleTracks: subtitleTracks, + }; + this.log("Updating subtitle tracks, " + subtitleTracks.length + ' track(s) found in "' + textGroupId + '" group-id'); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACKS_UPDATED, subtitleTracksUpdated); + + if (initialTrackId !== -1) { + this.setSubtitleTrack(initialTrackId, lastTrack); + } + } + }; + + _proto.findTrackId = function findTrackId(name) { + var textTracks = this.tracksInGroup; + + for (var i = 0; i < textTracks.length; i++) { + var track = textTracks[i]; + + if (!this.selectDefaultTrack || track.default) { + if (!name || name === track.name) { + return track.id; + } + } + } + + return -1; + }; + + _proto.onError = function onError(event, data) { + _BasePlaylistControll.prototype.onError.call(this, event, data); + + if (data.fatal || !data.context) { + return; + } + + if (data.context.type === _types_loader__WEBPACK_IMPORTED_MODULE_3__["PlaylistContextType"].SUBTITLE_TRACK && data.context.id === this.trackId && data.context.groupId === this.groupId) { + this.retryLoadingOrFail(data); + } + }; + /** get alternate subtitle tracks list from playlist **/ + + _proto.loadPlaylist = function loadPlaylist(CiderHlsUrlParameters) { + var currentTrack = this.tracksInGroup[this.trackId]; + + if (this.shouldLoadTrack(currentTrack)) { + var id = currentTrack.id; + var groupId = currentTrack.groupId; + var url = currentTrack.url; + + if (CiderHlsUrlParameters) { + try { + url = CiderHlsUrlParameters.addDirectives(url); + } catch (error) { + this.warn("Could not construct new URL with CiderHls Delivery Directives: " + error); + } + } + + this.log("Loading subtitle playlist for id " + id); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_LOADING, { + url: url, + id: id, + groupId: groupId, + deliveryDirectives: CiderHlsUrlParameters || null, + }); + } + }; + /** + * Disables the old subtitleTrack and sets current mode on the next subtitleTrack. + * This operates on the DOM textTracks. + * A value of -1 will disable all subtitle tracks. + */ + + _proto.toggleTrackModes = function toggleTrackModes(newId) { + var _this2 = this; + + var media = this.media, + subtitleDisplay = this.subtitleDisplay, + trackId = this.trackId; + + if (!media) { + return; + } + + var textTracks = filterSubtitleTracks(media.textTracks); + var groupTracks = textTracks.filter(function (track) { + return track.groupId === _this2.groupId; + }); + + if (newId === -1) { + [].slice.call(textTracks).forEach(function (track) { + track.mode = "disabled"; + }); + } else { + var oldTrack = groupTracks[trackId]; + + if (oldTrack) { + oldTrack.mode = "disabled"; + } + } + + var nextTrack = groupTracks[newId]; + + if (nextTrack) { + nextTrack.mode = subtitleDisplay ? "showing" : "hidden"; + } + }; + /** + * This method is responsible for validating the subtitle index and periodically reloading if live. + * Dispatches the SUBTITLE_TRACK_SWITCH event, which instructs the subtitle-stream-controller to load the selected track. + */ + + _proto.setSubtitleTrack = function setSubtitleTrack(newId, lastTrack) { + var _tracks$newId; + + var tracks = this.tracksInGroup; // setting this.subtitleTrack will trigger internal logic + // if media has not been attached yet, it will fail + // we keep a reference to the default track id + // and we'll set subtitleTrack when onMediaAttached is triggered + + if (!this.media) { + this.queuedDefaultTrack = newId; + return; + } + + if (this.trackId !== newId) { + this.toggleTrackModes(newId); + } // exit if track id as already set or invalid + + if ((this.trackId === newId && (newId === -1 || ((_tracks$newId = tracks[newId]) !== null && _tracks$newId !== void 0 && _tracks$newId.details))) || newId < -1 || newId >= tracks.length) { + return; + } // stopping live reloading timer if any + + this.clearTimer(); + var track = tracks[newId]; + this.log("Switching to subtitle track " + newId); + this.trackId = newId; + + if (track) { + var id = track.id, + _track$groupId = track.groupId, + groupId = _track$groupId === void 0 ? "" : _track$groupId, + name = track.name, + type = track.type, + url = track.url; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, { + id: id, + groupId: groupId, + name: name, + type: type, + url: url, + }); + var CiderHlsUrlParameters = this.switchParams(track.url, lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.details); + this.loadPlaylist(CiderHlsUrlParameters); + } else { + // switch to -1 + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].SUBTITLE_TRACK_SWITCH, { + id: newId, + }); + } + }; + + _proto.onTextTracksChanged = function onTextTracksChanged() { + if (!this.useTextTrackPolling) { + self.clearInterval(this.subtitlePollingInterval); + } // Media is undefined when switching streams via loadSource() + + if (!this.media || !this.CiderHls.config.renderTextTracksNatively) { + return; + } + + var trackId = -1; + var tracks = filterSubtitleTracks(this.media.textTracks); + + for (var id = 0; id < tracks.length; id++) { + if (tracks[id].mode === "hidden") { + // Do not break in case there is a following track with showing. + trackId = id; + } else if (tracks[id].mode === "showing") { + trackId = id; + break; + } + } // Setting current subtitleTrack will invoke code. + + if (this.subtitleTrack !== trackId) { + this.subtitleTrack = trackId; + } + }; + + _createClass(SubtitleTrackController, [ + { + key: "subtitleTracks", + get: function get() { + return this.tracksInGroup; + }, + /** get/set index of the selected subtitle track (based on index in subtitle track lists) **/ + }, + { + key: "subtitleTrack", + get: function get() { + return this.trackId; + }, + set: function set(newId) { + this.selectDefaultTrack = false; + var lastTrack = this.tracksInGroup ? this.tracksInGroup[this.trackId] : undefined; + this.setSubtitleTrack(newId, lastTrack); + }, + }, + ]); + + return SubtitleTrackController; + })(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]); + + function filterSubtitleTracks(textTrackList) { + var tracks = []; + + for (var i = 0; i < textTrackList.length; i++) { + var track = textTrackList[i]; // Edge adds a track without a label; we don't want to use it + + if (track.kind === "subtitles" && track.label) { + tracks.push(textTrackList[i]); + } + } + + return tracks; + } + + /* harmony default export */ __webpack_exports__["default"] = SubtitleTrackController; + + /***/ + }, + + /***/ "./src/controller/timeline-controller.ts": + /*!***********************************************!*\ !*** ./src/controller/timeline-controller.ts ***! \***********************************************/ -/*! exports provided: TimelineController */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimelineController", function() { return TimelineController; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/cea-608-parser */ "./src/utils/cea-608-parser.ts"); -/* harmony import */ var _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/output-filter */ "./src/utils/output-filter.ts"); -/* harmony import */ var _utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/webvtt-parser */ "./src/utils/webvtt-parser.ts"); -/* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts"); -/* harmony import */ var _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/imsc1-ttml-parser */ "./src/utils/imsc1-ttml-parser.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - - - - - - - - - - -var TimelineController = /*#__PURE__*/function () { - function TimelineController(CiderHls) { - this.CiderHls = void 0; - this.media = null; - this.config = void 0; - this.enabled = true; - this.Cues = void 0; - this.textTracks = []; - this.tracks = []; - this.initPTS = []; - this.timescale = []; - this.unparsedVttFrags = []; - this.captionsTracks = {}; - this.nonNativeCaptionsTracks = {}; - this.cea608Parser1 = void 0; - this.cea608Parser2 = void 0; - this.lastSn = -1; - this.lastPartIndex = -1; - this.prevCC = -1; - this.vttCCs = newVTTCCs(); - this.captionsProperties = void 0; - this.CiderHls = CiderHls; - this.config = CiderHls.config; - this.Cues = CiderHls.config.cueHandler; - this.captionsProperties = { - textTrack1: { - label: this.config.captionsTextTrack1Label, - languageCode: this.config.captionsTextTrack1LanguageCode - }, - textTrack2: { - label: this.config.captionsTextTrack2Label, - languageCode: this.config.captionsTextTrack2LanguageCode - }, - textTrack3: { - label: this.config.captionsTextTrack3Label, - languageCode: this.config.captionsTextTrack3LanguageCode - }, - textTrack4: { - label: this.config.captionsTextTrack4Label, - languageCode: this.config.captionsTextTrack4LanguageCode - } - }; - - if (this.config.enableCEA708Captions) { - var channel1 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack1'); - var channel2 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack2'); - var channel3 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack3'); - var channel4 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack4'); - this.cea608Parser1 = new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](1, channel1, channel2); - this.cea608Parser2 = new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](3, channel3, channel4); - } - - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADING, this.onFragLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, this.onFragDecrypted, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); - } - - var _proto = TimelineController.prototype; - - _proto.destroy = function destroy() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADING, this.onFragLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, this.onFragDecrypted, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); // @ts-ignore - - this.CiderHls = this.config = this.cea608Parser1 = this.cea608Parser2 = null; - }; - - _proto.addCues = function addCues(trackName, startTime, endTime, screen, cueRanges) { - // skip cues which overlap more than 50% with previously parsed time ranges - var merged = false; - - for (var i = cueRanges.length; i--;) { - var cueRange = cueRanges[i]; - var overlap = intersection(cueRange[0], cueRange[1], startTime, endTime); - - if (overlap >= 0) { - cueRange[0] = Math.min(cueRange[0], startTime); - cueRange[1] = Math.max(cueRange[1], endTime); - merged = true; - - if (overlap / (endTime - startTime) > 0.5) { - return; - } - } - } - - if (!merged) { - cueRanges.push([startTime, endTime]); - } - - if (this.config.renderTextTracksNatively) { - var track = this.captionsTracks[trackName]; - this.Cues.newCue(track, startTime, endTime, screen); - } else { - var cues = this.Cues.newCue(null, startTime, endTime, screen); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].CUES_PARSED, { - type: 'captions', - cues: cues, - track: trackName - }); - } - } // Triggered when an initial PTS is found; used for synchronisation of WebVTT. - ; - - _proto.onInitPtsFound = function onInitPtsFound(event, _ref) { - var _this = this; - - var frag = _ref.frag, - id = _ref.id, - initPTS = _ref.initPTS, - timescale = _ref.timescale; - var unparsedVttFrags = this.unparsedVttFrags; - - if (id === 'main') { - this.initPTS[frag.cc] = initPTS; - this.timescale[frag.cc] = timescale; - } // Due to asynchronous processing, initial PTS may arrive later than the first VTT fragments are loaded. - // Parse any unparsed fragments upon receiving the initial PTS. - - - if (unparsedVttFrags.length) { - this.unparsedVttFrags = []; - unparsedVttFrags.forEach(function (frag) { - _this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, frag); - }); - } - }; - - _proto.getExistingTrack = function getExistingTrack(trackName) { - var media = this.media; - - if (media) { - for (var i = 0; i < media.textTracks.length; i++) { - var textTrack = media.textTracks[i]; - - if (textTrack[trackName]) { - return textTrack; - } - } - } - - return null; - }; - - _proto.createCaptionsTrack = function createCaptionsTrack(trackName) { - if (this.config.renderTextTracksNatively) { - this.createNativeTrack(trackName); - } else { - this.createNonNativeTrack(trackName); - } - }; - - _proto.createNativeTrack = function createNativeTrack(trackName) { - if (this.captionsTracks[trackName]) { - return; - } - - var captionsProperties = this.captionsProperties, - captionsTracks = this.captionsTracks, - media = this.media; - var _captionsProperties$t = captionsProperties[trackName], - label = _captionsProperties$t.label, - languageCode = _captionsProperties$t.languageCode; // Enable reuse of existing text track. - - var existingTrack = this.getExistingTrack(trackName); - - if (!existingTrack) { - var textTrack = this.createTextTrack('captions', label, languageCode); - - if (textTrack) { - // Set a special property on the track so we know it's managed by CiderHls.js - textTrack[trackName] = true; - captionsTracks[trackName] = textTrack; - } - } else { - captionsTracks[trackName] = existingTrack; - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(captionsTracks[trackName]); - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["sendAddTrackEvent"])(captionsTracks[trackName], media); - } - }; - - _proto.createNonNativeTrack = function createNonNativeTrack(trackName) { - if (this.nonNativeCaptionsTracks[trackName]) { - return; - } // Create a list of a single track for the provider to consume - - - var trackProperties = this.captionsProperties[trackName]; - - if (!trackProperties) { - return; - } - - var label = trackProperties.label; - var track = { - _id: trackName, - label: label, - kind: 'captions', - default: trackProperties.media ? !!trackProperties.media.default : false, - closedCaptions: trackProperties.media - }; - this.nonNativeCaptionsTracks[trackName] = track; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].NON_NATIVE_TEXT_TRACKS_FOUND, { - tracks: [track] - }); - }; - - _proto.createTextTrack = function createTextTrack(kind, label, lang) { - var media = this.media; - - if (!media) { - return; - } - - return media.addTextTrack(kind, label, lang); - }; - - _proto.onMediaAttaching = function onMediaAttaching(event, data) { - this.media = data.media; - - this._cleanTracks(); - }; - - _proto.onMediaDetaching = function onMediaDetaching() { - var captionsTracks = this.captionsTracks; - Object.keys(captionsTracks).forEach(function (trackName) { - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(captionsTracks[trackName]); - delete captionsTracks[trackName]; - }); - this.nonNativeCaptionsTracks = {}; - }; - - _proto.onManifestLoading = function onManifestLoading() { - this.lastSn = -1; // Detect discontinuity in fragment parsing - - this.lastPartIndex = -1; - this.prevCC = -1; - this.vttCCs = newVTTCCs(); // Detect discontinuity in subtitle manifests - - this._cleanTracks(); - - this.tracks = []; - this.captionsTracks = {}; - this.nonNativeCaptionsTracks = {}; - this.textTracks = []; - this.unparsedVttFrags = this.unparsedVttFrags || []; - this.initPTS = []; - this.timescale = []; - - if (this.cea608Parser1 && this.cea608Parser2) { - this.cea608Parser1.reset(); - this.cea608Parser2.reset(); - } - }; - - _proto._cleanTracks = function _cleanTracks() { - // clear outdated subtitles - var media = this.media; - - if (!media) { - return; - } - - var textTracks = media.textTracks; - - if (textTracks) { - for (var i = 0; i < textTracks.length; i++) { - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(textTracks[i]); - } - } - }; - - _proto.onSubtitleTracksUpdated = function onSubtitleTracksUpdated(event, data) { - var _this2 = this; - - this.textTracks = []; - var tracks = data.subtitleTracks || []; - var hasIMSC1 = tracks.some(function (track) { - return track.textCodec === _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["IMSC1_CODEC"]; - }); - - if (this.config.enableWebVTT || hasIMSC1 && this.config.enableIMSC1) { - var sameTracks = this.tracks && tracks && this.tracks.length === tracks.length; - this.tracks = tracks || []; - - if (this.config.renderTextTracksNatively) { - var inUseTracks = this.media ? this.media.textTracks : []; - this.tracks.forEach(function (track, index) { - var textTrack; - - if (index < inUseTracks.length) { - var inUseTrack = null; - - for (var i = 0; i < inUseTracks.length; i++) { - if (canReuseVttTextTrack(inUseTracks[i], track)) { - inUseTrack = inUseTracks[i]; - break; - } - } // Reuse tracks with the same label, but do not reuse 608/708 tracks - - - if (inUseTrack) { - textTrack = inUseTrack; - } - } - - if (textTrack) { - Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(textTrack); - } else { - textTrack = _this2.createTextTrack('subtitles', track.name, track.lang); - - if (textTrack) { - textTrack.mode = 'disabled'; - } - } - - if (textTrack) { - textTrack.groupId = track.groupId; - - _this2.textTracks.push(textTrack); - } - }); - } else if (!sameTracks && this.tracks && this.tracks.length) { - // Create a list of tracks for the provider to consume - var tracksList = this.tracks.map(function (track) { - return { - label: track.name, - kind: track.type.toLowerCase(), - default: track.default, - subtitleTrack: track - }; - }); - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].NON_NATIVE_TEXT_TRACKS_FOUND, { - tracks: tracksList - }); - } - } - }; - - _proto.onManifestLoaded = function onManifestLoaded(event, data) { - var _this3 = this; - - if (this.config.enableCEA708Captions && data.captions) { - data.captions.forEach(function (captionsTrack) { - var instreamIdMatch = /(?:CC|SERVICE)([1-4])/.exec(captionsTrack.instreamId); - - if (!instreamIdMatch) { - return; - } - - var trackName = "textTrack" + instreamIdMatch[1]; - var trackProperties = _this3.captionsProperties[trackName]; - - if (!trackProperties) { - return; - } - - trackProperties.label = captionsTrack.name; - - if (captionsTrack.lang) { - // optional attribute - trackProperties.languageCode = captionsTrack.lang; - } - - trackProperties.media = captionsTrack; - }); - } - }; - - _proto.onFragLoading = function onFragLoading(event, data) { - var cea608Parser1 = this.cea608Parser1, - cea608Parser2 = this.cea608Parser2, - lastSn = this.lastSn, - lastPartIndex = this.lastPartIndex; - - if (!this.enabled || !(cea608Parser1 && cea608Parser2)) { - return; - } // if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack - - - if (data.frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_7__["PlaylistLevelType"].MAIN) { - var _data$part$index, _data$part; - - var sn = data.frag.sn; - var partIndex = (_data$part$index = data === null || data === void 0 ? void 0 : (_data$part = data.part) === null || _data$part === void 0 ? void 0 : _data$part.index) != null ? _data$part$index : -1; - - if (!(sn === lastSn + 1 || sn === lastSn && partIndex === lastPartIndex + 1)) { - cea608Parser1.reset(); - cea608Parser2.reset(); - } - - this.lastSn = sn; - this.lastPartIndex = partIndex; - } - }; - - _proto.onFragLoaded = function onFragLoaded(event, data) { - var frag = data.frag, - payload = data.payload; - var initPTS = this.initPTS, - unparsedVttFrags = this.unparsedVttFrags; - - if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_7__["PlaylistLevelType"].SUBTITLE) { - // If fragment is subtitle type, parse as WebVTT. - if (payload.byteLength) { - // We need an initial synchronisation PTS. Store fragments as long as none has arrived. - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(initPTS[frag.cc])) { - unparsedVttFrags.push(data); - - if (initPTS.length) { - // finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags. - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { - success: false, - frag: frag, - error: new Error('Missing initial subtitle PTS') + /*! exports provided: TimelineController */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimelineController", function () { + return TimelineController; }); - } + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/cea-608-parser */ "./src/utils/cea-608-parser.ts"); + /* harmony import */ var _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/output-filter */ "./src/utils/output-filter.ts"); + /* harmony import */ var _utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/webvtt-parser */ "./src/utils/webvtt-parser.ts"); + /* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts"); + /* harmony import */ var _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/imsc1-ttml-parser */ "./src/utils/imsc1-ttml-parser.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - return; - } + var TimelineController = /*#__PURE__*/ (function () { + function TimelineController(CiderHls) { + this.CiderHls = void 0; + this.media = null; + this.config = void 0; + this.enabled = true; + this.Cues = void 0; + this.textTracks = []; + this.tracks = []; + this.initPTS = []; + this.timescale = []; + this.unparsedVttFrags = []; + this.captionsTracks = {}; + this.nonNativeCaptionsTracks = {}; + this.cea608Parser1 = void 0; + this.cea608Parser2 = void 0; + this.lastSn = -1; + this.lastPartIndex = -1; + this.prevCC = -1; + this.vttCCs = newVTTCCs(); + this.captionsProperties = void 0; + this.CiderHls = CiderHls; + this.config = CiderHls.config; + this.Cues = CiderHls.config.cueHandler; + this.captionsProperties = { + textTrack1: { + label: this.config.captionsTextTrack1Label, + languageCode: this.config.captionsTextTrack1LanguageCode, + }, + textTrack2: { + label: this.config.captionsTextTrack2Label, + languageCode: this.config.captionsTextTrack2LanguageCode, + }, + textTrack3: { + label: this.config.captionsTextTrack3Label, + languageCode: this.config.captionsTextTrack3LanguageCode, + }, + textTrack4: { + label: this.config.captionsTextTrack4Label, + languageCode: this.config.captionsTextTrack4LanguageCode, + }, + }; - var decryptData = frag.decryptdata; // If the subtitles are not encrypted, parse VTTs now. Otherwise, we need to wait. + if (this.config.enableCEA708Captions) { + var channel1 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, "textTrack1"); + var channel2 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, "textTrack2"); + var channel3 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, "textTrack3"); + var channel4 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, "textTrack4"); + this.cea608Parser1 = new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](1, channel1, channel2); + this.cea608Parser2 = new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](3, channel3, channel4); + } - if (decryptData == null || decryptData.key == null || decryptData.method !== 'AES-128') { - var trackPlaylistMedia = this.tracks[frag.level]; - var vttCCs = this.vttCCs; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADING, this.onFragLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, this.onFragDecrypted, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); + } - if (!vttCCs[frag.cc]) { - vttCCs[frag.cc] = { - start: frag.start, - prevCC: this.prevCC, - new: true - }; - this.prevCC = frag.cc; - } + var _proto = TimelineController.prototype; - if (trackPlaylistMedia && trackPlaylistMedia.textCodec === _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["IMSC1_CODEC"]) { - this._parseIMSC1(frag, payload); - } else { - this._parseVTTs(frag, payload, vttCCs); - } - } - } else { - // In case there is no payload, finish unsuccessfully. - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { - success: false, - frag: frag, - error: new Error('Empty subtitle payload') - }); - } - } - }; + _proto.destroy = function destroy() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_ATTACHING, this.onMediaAttaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MEDIA_DETACHING, this.onMediaDetaching, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, this.onManifestLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADING, this.onFragLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, this.onFragLoaded, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, this.onFragDecrypted, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].INIT_PTS_FOUND, this.onInitPtsFound, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].BUFFER_FLUSHING, this.onBufferFlushing, this); // @ts-ignore - _proto._parseIMSC1 = function _parseIMSC1(frag, payload) { - var _this4 = this; + this.CiderHls = this.config = this.cea608Parser1 = this.cea608Parser2 = null; + }; - var CiderHls = this.CiderHls; - Object(_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["parseIMSC1"])(payload, this.initPTS[frag.cc], this.timescale[frag.cc], function (cues) { - _this4._appendCues(cues, frag.level); + _proto.addCues = function addCues(trackName, startTime, endTime, screen, cueRanges) { + // skip cues which overlap more than 50% with previously parsed time ranges + var merged = false; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { - success: true, - frag: frag - }); - }, function (error) { - _utils_logger__WEBPACK_IMPORTED_MODULE_8__["logger"].log("Failed to parse IMSC1: " + error); - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { - success: false, - frag: frag, - error: error - }); - }); - }; + for (var i = cueRanges.length; i--; ) { + var cueRange = cueRanges[i]; + var overlap = intersection(cueRange[0], cueRange[1], startTime, endTime); - _proto._parseVTTs = function _parseVTTs(frag, payload, vttCCs) { - var _this5 = this; + if (overlap >= 0) { + cueRange[0] = Math.min(cueRange[0], startTime); + cueRange[1] = Math.max(cueRange[1], endTime); + merged = true; - var CiderHls = this.CiderHls; // Parse the WebVTT file contents. + if (overlap / (endTime - startTime) > 0.5) { + return; + } + } + } - Object(_utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__["parseWebVTT"])(payload, this.initPTS[frag.cc], this.timescale[frag.cc], vttCCs, frag.cc, frag.start, function (cues) { - _this5._appendCues(cues, frag.level); + if (!merged) { + cueRanges.push([startTime, endTime]); + } - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { - success: true, - frag: frag - }); - }, function (error) { - _this5._fallbackToIMSC1(frag, payload); // Something went wrong while parsing. Trigger event with success false. + if (this.config.renderTextTracksNatively) { + var track = this.captionsTracks[trackName]; + this.Cues.newCue(track, startTime, endTime, screen); + } else { + var cues = this.Cues.newCue(null, startTime, endTime, screen); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].CUES_PARSED, { + type: "captions", + cues: cues, + track: trackName, + }); + } + }; // Triggered when an initial PTS is found; used for synchronisation of WebVTT. + _proto.onInitPtsFound = function onInitPtsFound(event, _ref) { + var _this = this; - _utils_logger__WEBPACK_IMPORTED_MODULE_8__["logger"].log("Failed to parse VTT cue: " + error); - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { - success: false, - frag: frag, - error: error - }); - }); - }; + var frag = _ref.frag, + id = _ref.id, + initPTS = _ref.initPTS, + timescale = _ref.timescale; + var unparsedVttFrags = this.unparsedVttFrags; - _proto._fallbackToIMSC1 = function _fallbackToIMSC1(frag, payload) { - var _this6 = this; + if (id === "main") { + this.initPTS[frag.cc] = initPTS; + this.timescale[frag.cc] = timescale; + } // Due to asynchronous processing, initial PTS may arrive later than the first VTT fragments are loaded. + // Parse any unparsed fragments upon receiving the initial PTS. - // If textCodec is unknown, try parsing as IMSC1. Set textCodec based on the result - var trackPlaylistMedia = this.tracks[frag.level]; + if (unparsedVttFrags.length) { + this.unparsedVttFrags = []; + unparsedVttFrags.forEach(function (frag) { + _this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, frag); + }); + } + }; - if (!trackPlaylistMedia.textCodec) { - Object(_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["parseIMSC1"])(payload, this.initPTS[frag.cc], this.timescale[frag.cc], function () { - trackPlaylistMedia.textCodec = _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["IMSC1_CODEC"]; + _proto.getExistingTrack = function getExistingTrack(trackName) { + var media = this.media; - _this6._parseIMSC1(frag, payload); - }, function () { - trackPlaylistMedia.textCodec = 'wvtt'; - }); - } - }; + if (media) { + for (var i = 0; i < media.textTracks.length; i++) { + var textTrack = media.textTracks[i]; - _proto._appendCues = function _appendCues(cues, fragLevel) { - var CiderHls = this.CiderHls; + if (textTrack[trackName]) { + return textTrack; + } + } + } - if (this.config.renderTextTracksNatively) { - var textTrack = this.textTracks[fragLevel]; // WebVTTParser.parse is an async method and if the currently selected text track mode is set to "disabled" - // before parsing is done then don't try to access currentTrack.cues.getCueById as cues will be null - // and trying to access getCueById method of cues will throw an exception - // Because we check if the mode is disabled, we can force check `cues` below. They can't be null. + return null; + }; - if (textTrack.mode === 'disabled') { - return; - } + _proto.createCaptionsTrack = function createCaptionsTrack(trackName) { + if (this.config.renderTextTracksNatively) { + this.createNativeTrack(trackName); + } else { + this.createNonNativeTrack(trackName); + } + }; - cues.forEach(function (cue) { - return Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["addCueToTrack"])(textTrack, cue); - }); - } else { - var currentTrack = this.tracks[fragLevel]; - var track = currentTrack.default ? 'default' : 'subtitles' + fragLevel; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].CUES_PARSED, { - type: 'subtitles', - cues: cues, - track: track - }); - } - }; + _proto.createNativeTrack = function createNativeTrack(trackName) { + if (this.captionsTracks[trackName]) { + return; + } - _proto.onFragDecrypted = function onFragDecrypted(event, data) { - var frag = data.frag; + var captionsProperties = this.captionsProperties, + captionsTracks = this.captionsTracks, + media = this.media; + var _captionsProperties$t = captionsProperties[trackName], + label = _captionsProperties$t.label, + languageCode = _captionsProperties$t.languageCode; // Enable reuse of existing text track. - if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_7__["PlaylistLevelType"].SUBTITLE) { - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.initPTS[frag.cc])) { - this.unparsedVttFrags.push(data); - return; - } + var existingTrack = this.getExistingTrack(trackName); - this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, data); - } - }; + if (!existingTrack) { + var textTrack = this.createTextTrack("captions", label, languageCode); - _proto.onSubtitleTracksCleared = function onSubtitleTracksCleared() { - this.tracks = []; - this.captionsTracks = {}; - }; + if (textTrack) { + // Set a special property on the track so we know it's managed by CiderHls.js + textTrack[trackName] = true; + captionsTracks[trackName] = textTrack; + } + } else { + captionsTracks[trackName] = existingTrack; + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(captionsTracks[trackName]); + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["sendAddTrackEvent"])(captionsTracks[trackName], media); + } + }; - _proto.onFragParsingUserdata = function onFragParsingUserdata(event, data) { - var cea608Parser1 = this.cea608Parser1, - cea608Parser2 = this.cea608Parser2; + _proto.createNonNativeTrack = function createNonNativeTrack(trackName) { + if (this.nonNativeCaptionsTracks[trackName]) { + return; + } // Create a list of a single track for the provider to consume - if (!this.enabled || !(cea608Parser1 && cea608Parser2)) { - return; - } // If the event contains captions (found in the bytes property), push all bytes into the parser immediately - // It will create the proper timestamps based on the PTS value + var trackProperties = this.captionsProperties[trackName]; + if (!trackProperties) { + return; + } - for (var i = 0; i < data.samples.length; i++) { - var ccBytes = data.samples[i].bytes; + var label = trackProperties.label; + var track = { + _id: trackName, + label: label, + kind: "captions", + default: trackProperties.media ? !!trackProperties.media.default : false, + closedCaptions: trackProperties.media, + }; + this.nonNativeCaptionsTracks[trackName] = track; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].NON_NATIVE_TEXT_TRACKS_FOUND, { + tracks: [track], + }); + }; - if (ccBytes) { - var ccdatas = this.extractCea608Data(ccBytes); - cea608Parser1.addData(data.samples[i].pts, ccdatas[0]); - cea608Parser2.addData(data.samples[i].pts, ccdatas[1]); - } - } - }; + _proto.createTextTrack = function createTextTrack(kind, label, lang) { + var media = this.media; - _proto.onBufferFlushing = function onBufferFlushing(event, _ref2) { - var startOffset = _ref2.startOffset, - endOffset = _ref2.endOffset, - endOffsetSubtitles = _ref2.endOffsetSubtitles, - type = _ref2.type; - var media = this.media; + if (!media) { + return; + } - if (!media || media.currentTime < endOffset) { - return; - } // Clear 608 caption cues from the captions TextTracks when the video back buffer is flushed - // Forward cues are never removed because we can loose streamed 608 content from recent fragments + return media.addTextTrack(kind, label, lang); + }; + _proto.onMediaAttaching = function onMediaAttaching(event, data) { + this.media = data.media; - if (!type || type === 'video') { - var captionsTracks = this.captionsTracks; - Object.keys(captionsTracks).forEach(function (trackName) { - return Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["removeCuesInRange"])(captionsTracks[trackName], startOffset, endOffset); - }); - } + this._cleanTracks(); + }; - if (this.config.renderTextTracksNatively) { - // Clear VTT/IMSC1 subtitle cues from the subtitle TextTracks when the back buffer is flushed - if (startOffset === 0 && endOffsetSubtitles !== undefined) { - var textTracks = this.textTracks; - Object.keys(textTracks).forEach(function (trackName) { - return Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["removeCuesInRange"])(textTracks[trackName], startOffset, endOffsetSubtitles); - }); - } - } - }; + _proto.onMediaDetaching = function onMediaDetaching() { + var captionsTracks = this.captionsTracks; + Object.keys(captionsTracks).forEach(function (trackName) { + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(captionsTracks[trackName]); + delete captionsTracks[trackName]; + }); + this.nonNativeCaptionsTracks = {}; + }; - _proto.extractCea608Data = function extractCea608Data(byteArray) { - var count = byteArray[0] & 31; - var position = 2; - var actualCCBytes = [[], []]; + _proto.onManifestLoading = function onManifestLoading() { + this.lastSn = -1; // Detect discontinuity in fragment parsing - for (var j = 0; j < count; j++) { - var tmpByte = byteArray[position++]; - var ccbyte1 = 0x7f & byteArray[position++]; - var ccbyte2 = 0x7f & byteArray[position++]; - var ccValid = (4 & tmpByte) !== 0; - var ccType = 3 & tmpByte; + this.lastPartIndex = -1; + this.prevCC = -1; + this.vttCCs = newVTTCCs(); // Detect discontinuity in subtitle manifests - if (ccbyte1 === 0 && ccbyte2 === 0) { - continue; - } + this._cleanTracks(); - if (ccValid) { - if (ccType === 0 || ccType === 1) { - actualCCBytes[ccType].push(ccbyte1); - actualCCBytes[ccType].push(ccbyte2); - } - } - } + this.tracks = []; + this.captionsTracks = {}; + this.nonNativeCaptionsTracks = {}; + this.textTracks = []; + this.unparsedVttFrags = this.unparsedVttFrags || []; + this.initPTS = []; + this.timescale = []; - return actualCCBytes; - }; + if (this.cea608Parser1 && this.cea608Parser2) { + this.cea608Parser1.reset(); + this.cea608Parser2.reset(); + } + }; - return TimelineController; -}(); + _proto._cleanTracks = function _cleanTracks() { + // clear outdated subtitles + var media = this.media; -function canReuseVttTextTrack(inUseTrack, manifestTrack) { - return inUseTrack && inUseTrack.label === manifestTrack.name && !(inUseTrack.textTrack1 || inUseTrack.textTrack2); -} + if (!media) { + return; + } -function intersection(x1, x2, y1, y2) { - return Math.min(x2, y2) - Math.max(x1, y1); -} + var textTracks = media.textTracks; -function newVTTCCs() { - return { - ccOffset: 0, - presentationOffset: 0, - 0: { - start: 0, - prevCC: -1, - new: false - } - }; -} + if (textTracks) { + for (var i = 0; i < textTracks.length; i++) { + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(textTracks[i]); + } + } + }; -/***/ }), + _proto.onSubtitleTracksUpdated = function onSubtitleTracksUpdated(event, data) { + var _this2 = this; -/***/ "./src/crypt/aes-crypto.ts": -/*!*********************************!*\ + this.textTracks = []; + var tracks = data.subtitleTracks || []; + var hasIMSC1 = tracks.some(function (track) { + return track.textCodec === _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["IMSC1_CODEC"]; + }); + + if (this.config.enableWebVTT || (hasIMSC1 && this.config.enableIMSC1)) { + var sameTracks = this.tracks && tracks && this.tracks.length === tracks.length; + this.tracks = tracks || []; + + if (this.config.renderTextTracksNatively) { + var inUseTracks = this.media ? this.media.textTracks : []; + this.tracks.forEach(function (track, index) { + var textTrack; + + if (index < inUseTracks.length) { + var inUseTrack = null; + + for (var i = 0; i < inUseTracks.length; i++) { + if (canReuseVttTextTrack(inUseTracks[i], track)) { + inUseTrack = inUseTracks[i]; + break; + } + } // Reuse tracks with the same label, but do not reuse 608/708 tracks + + if (inUseTrack) { + textTrack = inUseTrack; + } + } + + if (textTrack) { + Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["clearCurrentCues"])(textTrack); + } else { + textTrack = _this2.createTextTrack("subtitles", track.name, track.lang); + + if (textTrack) { + textTrack.mode = "disabled"; + } + } + + if (textTrack) { + textTrack.groupId = track.groupId; + + _this2.textTracks.push(textTrack); + } + }); + } else if (!sameTracks && this.tracks && this.tracks.length) { + // Create a list of tracks for the provider to consume + var tracksList = this.tracks.map(function (track) { + return { + label: track.name, + kind: track.type.toLowerCase(), + default: track.default, + subtitleTrack: track, + }; + }); + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].NON_NATIVE_TEXT_TRACKS_FOUND, { + tracks: tracksList, + }); + } + } + }; + + _proto.onManifestLoaded = function onManifestLoaded(event, data) { + var _this3 = this; + + if (this.config.enableCEA708Captions && data.captions) { + data.captions.forEach(function (captionsTrack) { + var instreamIdMatch = /(?:CC|SERVICE)([1-4])/.exec(captionsTrack.instreamId); + + if (!instreamIdMatch) { + return; + } + + var trackName = "textTrack" + instreamIdMatch[1]; + var trackProperties = _this3.captionsProperties[trackName]; + + if (!trackProperties) { + return; + } + + trackProperties.label = captionsTrack.name; + + if (captionsTrack.lang) { + // optional attribute + trackProperties.languageCode = captionsTrack.lang; + } + + trackProperties.media = captionsTrack; + }); + } + }; + + _proto.onFragLoading = function onFragLoading(event, data) { + var cea608Parser1 = this.cea608Parser1, + cea608Parser2 = this.cea608Parser2, + lastSn = this.lastSn, + lastPartIndex = this.lastPartIndex; + + if (!this.enabled || !(cea608Parser1 && cea608Parser2)) { + return; + } // if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack + + if (data.frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_7__["PlaylistLevelType"].MAIN) { + var _data$part$index, _data$part; + + var sn = data.frag.sn; + var partIndex = (_data$part$index = data === null || data === void 0 ? void 0 : (_data$part = data.part) === null || _data$part === void 0 ? void 0 : _data$part.index) != null ? _data$part$index : -1; + + if (!(sn === lastSn + 1 || (sn === lastSn && partIndex === lastPartIndex + 1))) { + cea608Parser1.reset(); + cea608Parser2.reset(); + } + + this.lastSn = sn; + this.lastPartIndex = partIndex; + } + }; + + _proto.onFragLoaded = function onFragLoaded(event, data) { + var frag = data.frag, + payload = data.payload; + var initPTS = this.initPTS, + unparsedVttFrags = this.unparsedVttFrags; + + if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_7__["PlaylistLevelType"].SUBTITLE) { + // If fragment is subtitle type, parse as WebVTT. + if (payload.byteLength) { + // We need an initial synchronisation PTS. Store fragments as long as none has arrived. + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(initPTS[frag.cc])) { + unparsedVttFrags.push(data); + + if (initPTS.length) { + // finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags. + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { + success: false, + frag: frag, + error: new Error("Missing initial subtitle PTS"), + }); + } + + return; + } + + var decryptData = frag.decryptdata; // If the subtitles are not encrypted, parse VTTs now. Otherwise, we need to wait. + + if (decryptData == null || decryptData.key == null || decryptData.method !== "AES-128") { + var trackPlaylistMedia = this.tracks[frag.level]; + var vttCCs = this.vttCCs; + + if (!vttCCs[frag.cc]) { + vttCCs[frag.cc] = { + start: frag.start, + prevCC: this.prevCC, + new: true, + }; + this.prevCC = frag.cc; + } + + if (trackPlaylistMedia && trackPlaylistMedia.textCodec === _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["IMSC1_CODEC"]) { + this._parseIMSC1(frag, payload); + } else { + this._parseVTTs(frag, payload, vttCCs); + } + } + } else { + // In case there is no payload, finish unsuccessfully. + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { + success: false, + frag: frag, + error: new Error("Empty subtitle payload"), + }); + } + } + }; + + _proto._parseIMSC1 = function _parseIMSC1(frag, payload) { + var _this4 = this; + + var CiderHls = this.CiderHls; + Object(_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["parseIMSC1"])( + payload, + this.initPTS[frag.cc], + this.timescale[frag.cc], + function (cues) { + _this4._appendCues(cues, frag.level); + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { + success: true, + frag: frag, + }); + }, + function (error) { + _utils_logger__WEBPACK_IMPORTED_MODULE_8__["logger"].log("Failed to parse IMSC1: " + error); + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { + success: false, + frag: frag, + error: error, + }); + } + ); + }; + + _proto._parseVTTs = function _parseVTTs(frag, payload, vttCCs) { + var _this5 = this; + + var CiderHls = this.CiderHls; // Parse the WebVTT file contents. + + Object(_utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__["parseWebVTT"])( + payload, + this.initPTS[frag.cc], + this.timescale[frag.cc], + vttCCs, + frag.cc, + frag.start, + function (cues) { + _this5._appendCues(cues, frag.level); + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { + success: true, + frag: frag, + }); + }, + function (error) { + _this5._fallbackToIMSC1(frag, payload); // Something went wrong while parsing. Trigger event with success false. + + _utils_logger__WEBPACK_IMPORTED_MODULE_8__["logger"].log("Failed to parse VTT cue: " + error); + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_FRAG_PROCESSED, { + success: false, + frag: frag, + error: error, + }); + } + ); + }; + + _proto._fallbackToIMSC1 = function _fallbackToIMSC1(frag, payload) { + var _this6 = this; + + // If textCodec is unknown, try parsing as IMSC1. Set textCodec based on the result + var trackPlaylistMedia = this.tracks[frag.level]; + + if (!trackPlaylistMedia.textCodec) { + Object(_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["parseIMSC1"])( + payload, + this.initPTS[frag.cc], + this.timescale[frag.cc], + function () { + trackPlaylistMedia.textCodec = _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__["IMSC1_CODEC"]; + + _this6._parseIMSC1(frag, payload); + }, + function () { + trackPlaylistMedia.textCodec = "wvtt"; + } + ); + } + }; + + _proto._appendCues = function _appendCues(cues, fragLevel) { + var CiderHls = this.CiderHls; + + if (this.config.renderTextTracksNatively) { + var textTrack = this.textTracks[fragLevel]; // WebVTTParser.parse is an async method and if the currently selected text track mode is set to "disabled" + // before parsing is done then don't try to access currentTrack.cues.getCueById as cues will be null + // and trying to access getCueById method of cues will throw an exception + // Because we check if the mode is disabled, we can force check `cues` below. They can't be null. + + if (textTrack.mode === "disabled") { + return; + } + + cues.forEach(function (cue) { + return Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["addCueToTrack"])(textTrack, cue); + }); + } else { + var currentTrack = this.tracks[fragLevel]; + var track = currentTrack.default ? "default" : "subtitles" + fragLevel; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].CUES_PARSED, { + type: "subtitles", + cues: cues, + track: track, + }); + } + }; + + _proto.onFragDecrypted = function onFragDecrypted(event, data) { + var frag = data.frag; + + if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_7__["PlaylistLevelType"].SUBTITLE) { + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.initPTS[frag.cc])) { + this.unparsedVttFrags.push(data); + return; + } + + this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_LOADED, data); + } + }; + + _proto.onSubtitleTracksCleared = function onSubtitleTracksCleared() { + this.tracks = []; + this.captionsTracks = {}; + }; + + _proto.onFragParsingUserdata = function onFragParsingUserdata(event, data) { + var cea608Parser1 = this.cea608Parser1, + cea608Parser2 = this.cea608Parser2; + + if (!this.enabled || !(cea608Parser1 && cea608Parser2)) { + return; + } // If the event contains captions (found in the bytes property), push all bytes into the parser immediately + // It will create the proper timestamps based on the PTS value + + for (var i = 0; i < data.samples.length; i++) { + var ccBytes = data.samples[i].bytes; + + if (ccBytes) { + var ccdatas = this.extractCea608Data(ccBytes); + cea608Parser1.addData(data.samples[i].pts, ccdatas[0]); + cea608Parser2.addData(data.samples[i].pts, ccdatas[1]); + } + } + }; + + _proto.onBufferFlushing = function onBufferFlushing(event, _ref2) { + var startOffset = _ref2.startOffset, + endOffset = _ref2.endOffset, + endOffsetSubtitles = _ref2.endOffsetSubtitles, + type = _ref2.type; + var media = this.media; + + if (!media || media.currentTime < endOffset) { + return; + } // Clear 608 caption cues from the captions TextTracks when the video back buffer is flushed + // Forward cues are never removed because we can loose streamed 608 content from recent fragments + + if (!type || type === "video") { + var captionsTracks = this.captionsTracks; + Object.keys(captionsTracks).forEach(function (trackName) { + return Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["removeCuesInRange"])(captionsTracks[trackName], startOffset, endOffset); + }); + } + + if (this.config.renderTextTracksNatively) { + // Clear VTT/IMSC1 subtitle cues from the subtitle TextTracks when the back buffer is flushed + if (startOffset === 0 && endOffsetSubtitles !== undefined) { + var textTracks = this.textTracks; + Object.keys(textTracks).forEach(function (trackName) { + return Object(_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__["removeCuesInRange"])(textTracks[trackName], startOffset, endOffsetSubtitles); + }); + } + } + }; + + _proto.extractCea608Data = function extractCea608Data(byteArray) { + var count = byteArray[0] & 31; + var position = 2; + var actualCCBytes = [[], []]; + + for (var j = 0; j < count; j++) { + var tmpByte = byteArray[position++]; + var ccbyte1 = 0x7f & byteArray[position++]; + var ccbyte2 = 0x7f & byteArray[position++]; + var ccValid = (4 & tmpByte) !== 0; + var ccType = 3 & tmpByte; + + if (ccbyte1 === 0 && ccbyte2 === 0) { + continue; + } + + if (ccValid) { + if (ccType === 0 || ccType === 1) { + actualCCBytes[ccType].push(ccbyte1); + actualCCBytes[ccType].push(ccbyte2); + } + } + } + + return actualCCBytes; + }; + + return TimelineController; + })(); + + function canReuseVttTextTrack(inUseTrack, manifestTrack) { + return inUseTrack && inUseTrack.label === manifestTrack.name && !(inUseTrack.textTrack1 || inUseTrack.textTrack2); + } + + function intersection(x1, x2, y1, y2) { + return Math.min(x2, y2) - Math.max(x1, y1); + } + + function newVTTCCs() { + return { + ccOffset: 0, + presentationOffset: 0, + 0: { + start: 0, + prevCC: -1, + new: false, + }, + }; + } + + /***/ + }, + + /***/ "./src/crypt/aes-crypto.ts": + /*!*********************************!*\ !*** ./src/crypt/aes-crypto.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return AESCrypto; + }); + var AESCrypto = /*#__PURE__*/ (function () { + function AESCrypto(subtle, iv) { + this.subtle = void 0; + this.aesIV = void 0; + this.subtle = subtle; + this.aesIV = iv; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AESCrypto; }); -var AESCrypto = /*#__PURE__*/function () { - function AESCrypto(subtle, iv) { - this.subtle = void 0; - this.aesIV = void 0; - this.subtle = subtle; - this.aesIV = iv; - } + var _proto = AESCrypto.prototype; - var _proto = AESCrypto.prototype; + _proto.decrypt = function decrypt(data, key) { + return this.subtle.decrypt( + { + name: "AES-CBC", + iv: this.aesIV, + }, + key, + data + ); + }; - _proto.decrypt = function decrypt(data, key) { - return this.subtle.decrypt({ - name: 'AES-CBC', - iv: this.aesIV - }, key, data); - }; + return AESCrypto; + })(); - return AESCrypto; -}(); + /***/ + }, - - -/***/ }), - -/***/ "./src/crypt/aes-decryptor.ts": -/*!************************************!*\ + /***/ "./src/crypt/aes-decryptor.ts": + /*!************************************!*\ !*** ./src/crypt/aes-decryptor.ts ***! \************************************/ -/*! exports provided: removePadding, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: removePadding, default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removePadding", function () { + return removePadding; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return AESDecryptor; + }); + /* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts"); + // PKCS7 -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removePadding", function() { return removePadding; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AESDecryptor; }); -/* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts"); - // PKCS7 + function removePadding(array) { + var outputBytes = array.byteLength; + var paddingBytes = outputBytes && new DataView(array.buffer).getUint8(outputBytes - 1); -function removePadding(array) { - var outputBytes = array.byteLength; - var paddingBytes = outputBytes && new DataView(array.buffer).getUint8(outputBytes - 1); + if (paddingBytes) { + return Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_0__["sliceUint8"])(array, 0, outputBytes - paddingBytes); + } - if (paddingBytes) { - return Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_0__["sliceUint8"])(array, 0, outputBytes - paddingBytes); - } + return array; + } - return array; -} + var AESDecryptor = /*#__PURE__*/ (function () { + function AESDecryptor() { + this.rcon = [0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]; + this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]; + this.sBox = new Uint32Array(256); + this.invSBox = new Uint32Array(256); + this.key = new Uint32Array(0); + this.ksRows = 0; + this.keySize = 0; + this.keySchedule = void 0; + this.invKeySchedule = void 0; + this.initTable(); + } // Using view.getUint32() also swaps the byte order. -var AESDecryptor = /*#__PURE__*/function () { - function AESDecryptor() { - this.rcon = [0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; - this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]; - this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]; - this.sBox = new Uint32Array(256); - this.invSBox = new Uint32Array(256); - this.key = new Uint32Array(0); - this.ksRows = 0; - this.keySize = 0; - this.keySchedule = void 0; - this.invKeySchedule = void 0; - this.initTable(); - } // Using view.getUint32() also swaps the byte order. + var _proto = AESDecryptor.prototype; + _proto.uint8ArrayToUint32Array_ = function uint8ArrayToUint32Array_(arrayBuffer) { + var view = new DataView(arrayBuffer); + var newArray = new Uint32Array(4); - var _proto = AESDecryptor.prototype; + for (var i = 0; i < 4; i++) { + newArray[i] = view.getUint32(i * 4); + } - _proto.uint8ArrayToUint32Array_ = function uint8ArrayToUint32Array_(arrayBuffer) { - var view = new DataView(arrayBuffer); - var newArray = new Uint32Array(4); + return newArray; + }; - for (var i = 0; i < 4; i++) { - newArray[i] = view.getUint32(i * 4); - } + _proto.initTable = function initTable() { + var sBox = this.sBox; + var invSBox = this.invSBox; + var subMix = this.subMix; + var subMix0 = subMix[0]; + var subMix1 = subMix[1]; + var subMix2 = subMix[2]; + var subMix3 = subMix[3]; + var invSubMix = this.invSubMix; + var invSubMix0 = invSubMix[0]; + var invSubMix1 = invSubMix[1]; + var invSubMix2 = invSubMix[2]; + var invSubMix3 = invSubMix[3]; + var d = new Uint32Array(256); + var x = 0; + var xi = 0; + var i = 0; - return newArray; - }; + for (i = 0; i < 256; i++) { + if (i < 128) { + d[i] = i << 1; + } else { + d[i] = (i << 1) ^ 0x11b; + } + } - _proto.initTable = function initTable() { - var sBox = this.sBox; - var invSBox = this.invSBox; - var subMix = this.subMix; - var subMix0 = subMix[0]; - var subMix1 = subMix[1]; - var subMix2 = subMix[2]; - var subMix3 = subMix[3]; - var invSubMix = this.invSubMix; - var invSubMix0 = invSubMix[0]; - var invSubMix1 = invSubMix[1]; - var invSubMix2 = invSubMix[2]; - var invSubMix3 = invSubMix[3]; - var d = new Uint32Array(256); - var x = 0; - var xi = 0; - var i = 0; + for (i = 0; i < 256; i++) { + var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); + sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; + sBox[x] = sx; + invSBox[sx] = x; // Compute multiplication - for (i = 0; i < 256; i++) { - if (i < 128) { - d[i] = i << 1; - } else { - d[i] = i << 1 ^ 0x11b; - } - } + var x2 = d[x]; + var x4 = d[x2]; + var x8 = d[x4]; // Compute sub/invSub bytes, mix columns tables - for (i = 0; i < 256; i++) { - var sx = xi ^ xi << 1 ^ xi << 2 ^ xi << 3 ^ xi << 4; - sx = sx >>> 8 ^ sx & 0xff ^ 0x63; - sBox[x] = sx; - invSBox[sx] = x; // Compute multiplication + var t = (d[sx] * 0x101) ^ (sx * 0x1010100); + subMix0[x] = (t << 24) | (t >>> 8); + subMix1[x] = (t << 16) | (t >>> 16); + subMix2[x] = (t << 8) | (t >>> 24); + subMix3[x] = t; // Compute inv sub bytes, inv mix columns tables - var x2 = d[x]; - var x4 = d[x2]; - var x8 = d[x4]; // Compute sub/invSub bytes, mix columns tables + t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); + invSubMix0[sx] = (t << 24) | (t >>> 8); + invSubMix1[sx] = (t << 16) | (t >>> 16); + invSubMix2[sx] = (t << 8) | (t >>> 24); + invSubMix3[sx] = t; // Compute next counter - var t = d[sx] * 0x101 ^ sx * 0x1010100; - subMix0[x] = t << 24 | t >>> 8; - subMix1[x] = t << 16 | t >>> 16; - subMix2[x] = t << 8 | t >>> 24; - subMix3[x] = t; // Compute inv sub bytes, inv mix columns tables + if (!x) { + x = xi = 1; + } else { + x = x2 ^ d[d[d[x8 ^ x2]]]; + xi ^= d[d[xi]]; + } + } + }; - t = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100; - invSubMix0[sx] = t << 24 | t >>> 8; - invSubMix1[sx] = t << 16 | t >>> 16; - invSubMix2[sx] = t << 8 | t >>> 24; - invSubMix3[sx] = t; // Compute next counter + _proto.expandKey = function expandKey(keyBuffer) { + // convert keyBuffer to Uint32Array + var key = this.uint8ArrayToUint32Array_(keyBuffer); + var sameKey = true; + var offset = 0; - if (!x) { - x = xi = 1; - } else { - x = x2 ^ d[d[d[x8 ^ x2]]]; - xi ^= d[d[xi]]; - } - } - }; + while (offset < key.length && sameKey) { + sameKey = key[offset] === this.key[offset]; + offset++; + } - _proto.expandKey = function expandKey(keyBuffer) { - // convert keyBuffer to Uint32Array - var key = this.uint8ArrayToUint32Array_(keyBuffer); - var sameKey = true; - var offset = 0; + if (sameKey) { + return; + } - while (offset < key.length && sameKey) { - sameKey = key[offset] === this.key[offset]; - offset++; - } + this.key = key; + var keySize = (this.keySize = key.length); - if (sameKey) { - return; - } + if (keySize !== 4 && keySize !== 6 && keySize !== 8) { + throw new Error("Invalid aes key size=" + keySize); + } - this.key = key; - var keySize = this.keySize = key.length; + var ksRows = (this.ksRows = (keySize + 6 + 1) * 4); + var ksRow; + var invKsRow; + var keySchedule = (this.keySchedule = new Uint32Array(ksRows)); + var invKeySchedule = (this.invKeySchedule = new Uint32Array(ksRows)); + var sbox = this.sBox; + var rcon = this.rcon; + var invSubMix = this.invSubMix; + var invSubMix0 = invSubMix[0]; + var invSubMix1 = invSubMix[1]; + var invSubMix2 = invSubMix[2]; + var invSubMix3 = invSubMix[3]; + var prev; + var t; - if (keySize !== 4 && keySize !== 6 && keySize !== 8) { - throw new Error('Invalid aes key size=' + keySize); - } + for (ksRow = 0; ksRow < ksRows; ksRow++) { + if (ksRow < keySize) { + prev = keySchedule[ksRow] = key[ksRow]; + continue; + } - var ksRows = this.ksRows = (keySize + 6 + 1) * 4; - var ksRow; - var invKsRow; - var keySchedule = this.keySchedule = new Uint32Array(ksRows); - var invKeySchedule = this.invKeySchedule = new Uint32Array(ksRows); - var sbox = this.sBox; - var rcon = this.rcon; - var invSubMix = this.invSubMix; - var invSubMix0 = invSubMix[0]; - var invSubMix1 = invSubMix[1]; - var invSubMix2 = invSubMix[2]; - var invSubMix3 = invSubMix[3]; - var prev; - var t; + t = prev; - for (ksRow = 0; ksRow < ksRows; ksRow++) { - if (ksRow < keySize) { - prev = keySchedule[ksRow] = key[ksRow]; - continue; - } + if (ksRow % keySize === 0) { + // Rot word + t = (t << 8) | (t >>> 24); // Sub word - t = prev; + t = (sbox[t >>> 24] << 24) | (sbox[(t >>> 16) & 0xff] << 16) | (sbox[(t >>> 8) & 0xff] << 8) | sbox[t & 0xff]; // Mix Rcon - if (ksRow % keySize === 0) { - // Rot word - t = t << 8 | t >>> 24; // Sub word + t ^= rcon[(ksRow / keySize) | 0] << 24; + } else if (keySize > 6 && ksRow % keySize === 4) { + // Sub word + t = (sbox[t >>> 24] << 24) | (sbox[(t >>> 16) & 0xff] << 16) | (sbox[(t >>> 8) & 0xff] << 8) | sbox[t & 0xff]; + } - t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 0xff] << 16 | sbox[t >>> 8 & 0xff] << 8 | sbox[t & 0xff]; // Mix Rcon + keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0; + } - t ^= rcon[ksRow / keySize | 0] << 24; - } else if (keySize > 6 && ksRow % keySize === 4) { - // Sub word - t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 0xff] << 16 | sbox[t >>> 8 & 0xff] << 8 | sbox[t & 0xff]; - } + for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { + ksRow = ksRows - invKsRow; - keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0; - } + if (invKsRow & 3) { + t = keySchedule[ksRow]; + } else { + t = keySchedule[ksRow - 4]; + } - for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { - ksRow = ksRows - invKsRow; + if (invKsRow < 4 || ksRow <= 4) { + invKeySchedule[invKsRow] = t; + } else { + invKeySchedule[invKsRow] = invSubMix0[sbox[t >>> 24]] ^ invSubMix1[sbox[(t >>> 16) & 0xff]] ^ invSubMix2[sbox[(t >>> 8) & 0xff]] ^ invSubMix3[sbox[t & 0xff]]; + } - if (invKsRow & 3) { - t = keySchedule[ksRow]; - } else { - t = keySchedule[ksRow - 4]; - } + invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0; + } + }; // Adding this as a method greatly improves performance. - if (invKsRow < 4 || ksRow <= 4) { - invKeySchedule[invKsRow] = t; - } else { - invKeySchedule[invKsRow] = invSubMix0[sbox[t >>> 24]] ^ invSubMix1[sbox[t >>> 16 & 0xff]] ^ invSubMix2[sbox[t >>> 8 & 0xff]] ^ invSubMix3[sbox[t & 0xff]]; - } + _proto.networkToHostOrderSwap = function networkToHostOrderSwap(word) { + return (word << 24) | ((word & 0xff00) << 8) | ((word & 0xff0000) >> 8) | (word >>> 24); + }; - invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0; - } - } // Adding this as a method greatly improves performance. - ; + _proto.decrypt = function decrypt(inputArrayBuffer, offset, aesIV) { + var nRounds = this.keySize + 6; + var invKeySchedule = this.invKeySchedule; + var invSBOX = this.invSBox; + var invSubMix = this.invSubMix; + var invSubMix0 = invSubMix[0]; + var invSubMix1 = invSubMix[1]; + var invSubMix2 = invSubMix[2]; + var invSubMix3 = invSubMix[3]; + var initVector = this.uint8ArrayToUint32Array_(aesIV); + var initVector0 = initVector[0]; + var initVector1 = initVector[1]; + var initVector2 = initVector[2]; + var initVector3 = initVector[3]; + var inputInt32 = new Int32Array(inputArrayBuffer); + var outputInt32 = new Int32Array(inputInt32.length); + var t0, t1, t2, t3; + var s0, s1, s2, s3; + var inputWords0, inputWords1, inputWords2, inputWords3; + var ksRow, i; + var swapWord = this.networkToHostOrderSwap; - _proto.networkToHostOrderSwap = function networkToHostOrderSwap(word) { - return word << 24 | (word & 0xff00) << 8 | (word & 0xff0000) >> 8 | word >>> 24; - }; + while (offset < inputInt32.length) { + inputWords0 = swapWord(inputInt32[offset]); + inputWords1 = swapWord(inputInt32[offset + 1]); + inputWords2 = swapWord(inputInt32[offset + 2]); + inputWords3 = swapWord(inputInt32[offset + 3]); + s0 = inputWords0 ^ invKeySchedule[0]; + s1 = inputWords3 ^ invKeySchedule[1]; + s2 = inputWords2 ^ invKeySchedule[2]; + s3 = inputWords1 ^ invKeySchedule[3]; + ksRow = 4; // Iterate through the rounds of decryption - _proto.decrypt = function decrypt(inputArrayBuffer, offset, aesIV) { - var nRounds = this.keySize + 6; - var invKeySchedule = this.invKeySchedule; - var invSBOX = this.invSBox; - var invSubMix = this.invSubMix; - var invSubMix0 = invSubMix[0]; - var invSubMix1 = invSubMix[1]; - var invSubMix2 = invSubMix[2]; - var invSubMix3 = invSubMix[3]; - var initVector = this.uint8ArrayToUint32Array_(aesIV); - var initVector0 = initVector[0]; - var initVector1 = initVector[1]; - var initVector2 = initVector[2]; - var initVector3 = initVector[3]; - var inputInt32 = new Int32Array(inputArrayBuffer); - var outputInt32 = new Int32Array(inputInt32.length); - var t0, t1, t2, t3; - var s0, s1, s2, s3; - var inputWords0, inputWords1, inputWords2, inputWords3; - var ksRow, i; - var swapWord = this.networkToHostOrderSwap; + for (i = 1; i < nRounds; i++) { + t0 = invSubMix0[s0 >>> 24] ^ invSubMix1[(s1 >> 16) & 0xff] ^ invSubMix2[(s2 >> 8) & 0xff] ^ invSubMix3[s3 & 0xff] ^ invKeySchedule[ksRow]; + t1 = invSubMix0[s1 >>> 24] ^ invSubMix1[(s2 >> 16) & 0xff] ^ invSubMix2[(s3 >> 8) & 0xff] ^ invSubMix3[s0 & 0xff] ^ invKeySchedule[ksRow + 1]; + t2 = invSubMix0[s2 >>> 24] ^ invSubMix1[(s3 >> 16) & 0xff] ^ invSubMix2[(s0 >> 8) & 0xff] ^ invSubMix3[s1 & 0xff] ^ invKeySchedule[ksRow + 2]; + t3 = invSubMix0[s3 >>> 24] ^ invSubMix1[(s0 >> 16) & 0xff] ^ invSubMix2[(s1 >> 8) & 0xff] ^ invSubMix3[s2 & 0xff] ^ invKeySchedule[ksRow + 3]; // Update state - while (offset < inputInt32.length) { - inputWords0 = swapWord(inputInt32[offset]); - inputWords1 = swapWord(inputInt32[offset + 1]); - inputWords2 = swapWord(inputInt32[offset + 2]); - inputWords3 = swapWord(inputInt32[offset + 3]); - s0 = inputWords0 ^ invKeySchedule[0]; - s1 = inputWords3 ^ invKeySchedule[1]; - s2 = inputWords2 ^ invKeySchedule[2]; - s3 = inputWords1 ^ invKeySchedule[3]; - ksRow = 4; // Iterate through the rounds of decryption + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + ksRow = ksRow + 4; + } // Shift rows, sub bytes, add round key - for (i = 1; i < nRounds; i++) { - t0 = invSubMix0[s0 >>> 24] ^ invSubMix1[s1 >> 16 & 0xff] ^ invSubMix2[s2 >> 8 & 0xff] ^ invSubMix3[s3 & 0xff] ^ invKeySchedule[ksRow]; - t1 = invSubMix0[s1 >>> 24] ^ invSubMix1[s2 >> 16 & 0xff] ^ invSubMix2[s3 >> 8 & 0xff] ^ invSubMix3[s0 & 0xff] ^ invKeySchedule[ksRow + 1]; - t2 = invSubMix0[s2 >>> 24] ^ invSubMix1[s3 >> 16 & 0xff] ^ invSubMix2[s0 >> 8 & 0xff] ^ invSubMix3[s1 & 0xff] ^ invKeySchedule[ksRow + 2]; - t3 = invSubMix0[s3 >>> 24] ^ invSubMix1[s0 >> 16 & 0xff] ^ invSubMix2[s1 >> 8 & 0xff] ^ invSubMix3[s2 & 0xff] ^ invKeySchedule[ksRow + 3]; // Update state + t0 = (invSBOX[s0 >>> 24] << 24) ^ (invSBOX[(s1 >> 16) & 0xff] << 16) ^ (invSBOX[(s2 >> 8) & 0xff] << 8) ^ invSBOX[s3 & 0xff] ^ invKeySchedule[ksRow]; + t1 = (invSBOX[s1 >>> 24] << 24) ^ (invSBOX[(s2 >> 16) & 0xff] << 16) ^ (invSBOX[(s3 >> 8) & 0xff] << 8) ^ invSBOX[s0 & 0xff] ^ invKeySchedule[ksRow + 1]; + t2 = (invSBOX[s2 >>> 24] << 24) ^ (invSBOX[(s3 >> 16) & 0xff] << 16) ^ (invSBOX[(s0 >> 8) & 0xff] << 8) ^ invSBOX[s1 & 0xff] ^ invKeySchedule[ksRow + 2]; + t3 = (invSBOX[s3 >>> 24] << 24) ^ (invSBOX[(s0 >> 16) & 0xff] << 16) ^ (invSBOX[(s1 >> 8) & 0xff] << 8) ^ invSBOX[s2 & 0xff] ^ invKeySchedule[ksRow + 3]; // Write - s0 = t0; - s1 = t1; - s2 = t2; - s3 = t3; - ksRow = ksRow + 4; - } // Shift rows, sub bytes, add round key + outputInt32[offset] = swapWord(t0 ^ initVector0); + outputInt32[offset + 1] = swapWord(t3 ^ initVector1); + outputInt32[offset + 2] = swapWord(t2 ^ initVector2); + outputInt32[offset + 3] = swapWord(t1 ^ initVector3); // reset initVector to last 4 unsigned int + initVector0 = inputWords0; + initVector1 = inputWords1; + initVector2 = inputWords2; + initVector3 = inputWords3; + offset = offset + 4; + } - t0 = invSBOX[s0 >>> 24] << 24 ^ invSBOX[s1 >> 16 & 0xff] << 16 ^ invSBOX[s2 >> 8 & 0xff] << 8 ^ invSBOX[s3 & 0xff] ^ invKeySchedule[ksRow]; - t1 = invSBOX[s1 >>> 24] << 24 ^ invSBOX[s2 >> 16 & 0xff] << 16 ^ invSBOX[s3 >> 8 & 0xff] << 8 ^ invSBOX[s0 & 0xff] ^ invKeySchedule[ksRow + 1]; - t2 = invSBOX[s2 >>> 24] << 24 ^ invSBOX[s3 >> 16 & 0xff] << 16 ^ invSBOX[s0 >> 8 & 0xff] << 8 ^ invSBOX[s1 & 0xff] ^ invKeySchedule[ksRow + 2]; - t3 = invSBOX[s3 >>> 24] << 24 ^ invSBOX[s0 >> 16 & 0xff] << 16 ^ invSBOX[s1 >> 8 & 0xff] << 8 ^ invSBOX[s2 & 0xff] ^ invKeySchedule[ksRow + 3]; // Write + return outputInt32.buffer; + }; - outputInt32[offset] = swapWord(t0 ^ initVector0); - outputInt32[offset + 1] = swapWord(t3 ^ initVector1); - outputInt32[offset + 2] = swapWord(t2 ^ initVector2); - outputInt32[offset + 3] = swapWord(t1 ^ initVector3); // reset initVector to last 4 unsigned int + return AESDecryptor; + })(); - initVector0 = inputWords0; - initVector1 = inputWords1; - initVector2 = inputWords2; - initVector3 = inputWords3; - offset = offset + 4; - } + /***/ + }, - return outputInt32.buffer; - }; - - return AESDecryptor; -}(); - - - -/***/ }), - -/***/ "./src/crypt/decrypter.ts": -/*!********************************!*\ + /***/ "./src/crypt/decrypter.ts": + /*!********************************!*\ !*** ./src/crypt/decrypter.ts ***! \********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return Decrypter; + }); + /* harmony import */ var _aes_crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./aes-crypto */ "./src/crypt/aes-crypto.ts"); + /* harmony import */ var _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./fast-aes-key */ "./src/crypt/fast-aes-key.ts"); + /* harmony import */ var _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./aes-decryptor */ "./src/crypt/aes-decryptor.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Decrypter; }); -/* harmony import */ var _aes_crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./aes-crypto */ "./src/crypt/aes-crypto.ts"); -/* harmony import */ var _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./fast-aes-key */ "./src/crypt/fast-aes-key.ts"); -/* harmony import */ var _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./aes-decryptor */ "./src/crypt/aes-decryptor.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts"); + var CHUNK_SIZE = 16; // 16 bytes, 128 bits + var Decrypter = /*#__PURE__*/ (function () { + function Decrypter(observer, config, _temp) { + var _ref = _temp === void 0 ? {} : _temp, + _ref$removePKCS7Paddi = _ref.removePKCS7Padding, + removePKCS7Padding = _ref$removePKCS7Paddi === void 0 ? true : _ref$removePKCS7Paddi; + this.logEnabled = true; + this.observer = void 0; + this.config = void 0; + this.removePKCS7Padding = void 0; + this.subtle = null; + this.softwareDecrypter = null; + this.key = null; + this.fastAesKey = null; + this.remainderData = null; + this.currentIV = null; + this.currentResult = null; + this.observer = observer; + this.config = config; + this.removePKCS7Padding = removePKCS7Padding; // built in decryptor expects PKCS7 padding + if (removePKCS7Padding) { + try { + var browserCrypto = self.crypto; + if (browserCrypto) { + this.subtle = browserCrypto.subtle || browserCrypto.webkitSubtle; + } + } catch (e) { + /* no-op */ + } + } + if (this.subtle === null) { + this.config.enableSoftwareAES = true; + } + } -var CHUNK_SIZE = 16; // 16 bytes, 128 bits + var _proto = Decrypter.prototype; -var Decrypter = /*#__PURE__*/function () { - function Decrypter(observer, config, _temp) { - var _ref = _temp === void 0 ? {} : _temp, - _ref$removePKCS7Paddi = _ref.removePKCS7Padding, - removePKCS7Padding = _ref$removePKCS7Paddi === void 0 ? true : _ref$removePKCS7Paddi; + _proto.destroy = function destroy() { + // @ts-ignore + this.observer = null; + }; - this.logEnabled = true; - this.observer = void 0; - this.config = void 0; - this.removePKCS7Padding = void 0; - this.subtle = null; - this.softwareDecrypter = null; - this.key = null; - this.fastAesKey = null; - this.remainderData = null; - this.currentIV = null; - this.currentResult = null; - this.observer = observer; - this.config = config; - this.removePKCS7Padding = removePKCS7Padding; // built in decryptor expects PKCS7 padding + _proto.isSync = function isSync() { + return this.config.enableSoftwareAES; + }; - if (removePKCS7Padding) { - try { - var browserCrypto = self.crypto; + _proto.flush = function flush() { + var currentResult = this.currentResult; - if (browserCrypto) { - this.subtle = browserCrypto.subtle || browserCrypto.webkitSubtle; - } - } catch (e) { - /* no-op */ - } - } + if (!currentResult) { + this.reset(); + return; + } - if (this.subtle === null) { - this.config.enableSoftwareAES = true; - } - } + var data = new Uint8Array(currentResult); + this.reset(); - var _proto = Decrypter.prototype; + if (this.removePKCS7Padding) { + return Object(_aes_decryptor__WEBPACK_IMPORTED_MODULE_2__["removePadding"])(data); + } - _proto.destroy = function destroy() { - // @ts-ignore - this.observer = null; - }; + return data; + }; - _proto.isSync = function isSync() { - return this.config.enableSoftwareAES; - }; + _proto.reset = function reset() { + this.currentResult = null; + this.currentIV = null; + this.remainderData = null; - _proto.flush = function flush() { - var currentResult = this.currentResult; + if (this.softwareDecrypter) { + this.softwareDecrypter = null; + } + }; - if (!currentResult) { - this.reset(); - return; - } + _proto.decrypt = function decrypt(data, key, iv, callback) { + if (this.config.enableSoftwareAES) { + this.softwareDecrypt(new Uint8Array(data), key, iv); + var decryptResult = this.flush(); - var data = new Uint8Array(currentResult); - this.reset(); + if (decryptResult) { + callback(decryptResult.buffer); + } + } else { + this.webCryptoDecrypt(new Uint8Array(data), key, iv).then(callback); + } + }; - if (this.removePKCS7Padding) { - return Object(_aes_decryptor__WEBPACK_IMPORTED_MODULE_2__["removePadding"])(data); - } + _proto.softwareDecrypt = function softwareDecrypt(data, key, iv) { + var currentIV = this.currentIV, + currentResult = this.currentResult, + remainderData = this.remainderData; + this.logOnce("JS AES decrypt"); // The output is staggered during progressive parsing - the current result is cached, and emitted on the next call + // This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached + // the end on flush(), but by that time we have already received all bytes for the segment. + // Progressive decryption does not work with WebCrypto - return data; - }; + if (remainderData) { + data = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__["appendUint8Array"])(remainderData, data); + this.remainderData = null; + } // Byte length must be a multiple of 16 (AES-128 = 128 bit blocks = 16 bytes) - _proto.reset = function reset() { - this.currentResult = null; - this.currentIV = null; - this.remainderData = null; + var currentChunk = this.getValidChunk(data); - if (this.softwareDecrypter) { - this.softwareDecrypter = null; - } - }; + if (!currentChunk.length) { + return null; + } - _proto.decrypt = function decrypt(data, key, iv, callback) { - if (this.config.enableSoftwareAES) { - this.softwareDecrypt(new Uint8Array(data), key, iv); - var decryptResult = this.flush(); + if (currentIV) { + iv = currentIV; + } - if (decryptResult) { - callback(decryptResult.buffer); - } - } else { - this.webCryptoDecrypt(new Uint8Array(data), key, iv).then(callback); - } - }; + var softwareDecrypter = this.softwareDecrypter; - _proto.softwareDecrypt = function softwareDecrypt(data, key, iv) { - var currentIV = this.currentIV, - currentResult = this.currentResult, - remainderData = this.remainderData; - this.logOnce('JS AES decrypt'); // The output is staggered during progressive parsing - the current result is cached, and emitted on the next call - // This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached - // the end on flush(), but by that time we have already received all bytes for the segment. - // Progressive decryption does not work with WebCrypto + if (!softwareDecrypter) { + softwareDecrypter = this.softwareDecrypter = new _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__["default"](); + } - if (remainderData) { - data = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__["appendUint8Array"])(remainderData, data); - this.remainderData = null; - } // Byte length must be a multiple of 16 (AES-128 = 128 bit blocks = 16 bytes) + softwareDecrypter.expandKey(key); + var result = currentResult; + this.currentResult = softwareDecrypter.decrypt(currentChunk.buffer, 0, iv); + this.currentIV = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__["sliceUint8"])(currentChunk, -16).buffer; + if (!result) { + return null; + } - var currentChunk = this.getValidChunk(data); + return result; + }; - if (!currentChunk.length) { - return null; - } + _proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) { + var _this = this; - if (currentIV) { - iv = currentIV; - } + var subtle = this.subtle; - var softwareDecrypter = this.softwareDecrypter; + if (this.key !== key || !this.fastAesKey) { + this.key = key; + this.fastAesKey = new _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__["default"](subtle, key); + } - if (!softwareDecrypter) { - softwareDecrypter = this.softwareDecrypter = new _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__["default"](); - } + return this.fastAesKey + .expandKey() + .then(function (aesKey) { + // decrypt using web crypto + if (!subtle) { + return Promise.reject(new Error("web crypto not initialized")); + } - softwareDecrypter.expandKey(key); - var result = currentResult; - this.currentResult = softwareDecrypter.decrypt(currentChunk.buffer, 0, iv); - this.currentIV = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__["sliceUint8"])(currentChunk, -16).buffer; + var crypto = new _aes_crypto__WEBPACK_IMPORTED_MODULE_0__["default"](subtle, iv); + return crypto.decrypt(data.buffer, aesKey); + }) + .catch(function (err) { + return _this.onWebCryptoError(err, data, key, iv); + }); + }; - if (!result) { - return null; - } + _proto.onWebCryptoError = function onWebCryptoError(err, data, key, iv) { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("[decrypter.ts]: WebCrypto Error, disable WebCrypto API:", err); + this.config.enableSoftwareAES = true; + this.logEnabled = true; + return this.softwareDecrypt(data, key, iv); + }; - return result; - }; + _proto.getValidChunk = function getValidChunk(data) { + var currentChunk = data; + var splitPoint = data.length - (data.length % CHUNK_SIZE); - _proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) { - var _this = this; + if (splitPoint !== data.length) { + currentChunk = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__["sliceUint8"])(data, 0, splitPoint); + this.remainderData = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__["sliceUint8"])(data, splitPoint); + } - var subtle = this.subtle; + return currentChunk; + }; - if (this.key !== key || !this.fastAesKey) { - this.key = key; - this.fastAesKey = new _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__["default"](subtle, key); - } + _proto.logOnce = function logOnce(msg) { + if (!this.logEnabled) { + return; + } - return this.fastAesKey.expandKey().then(function (aesKey) { - // decrypt using web crypto - if (!subtle) { - return Promise.reject(new Error('web crypto not initialized')); - } + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log("[decrypter.ts]: " + msg); + this.logEnabled = false; + }; - var crypto = new _aes_crypto__WEBPACK_IMPORTED_MODULE_0__["default"](subtle, iv); - return crypto.decrypt(data.buffer, aesKey); - }).catch(function (err) { - return _this.onWebCryptoError(err, data, key, iv); - }); - }; + return Decrypter; + })(); - _proto.onWebCryptoError = function onWebCryptoError(err, data, key, iv) { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('[decrypter.ts]: WebCrypto Error, disable WebCrypto API:', err); - this.config.enableSoftwareAES = true; - this.logEnabled = true; - return this.softwareDecrypt(data, key, iv); - }; + /***/ + }, - _proto.getValidChunk = function getValidChunk(data) { - var currentChunk = data; - var splitPoint = data.length - data.length % CHUNK_SIZE; - - if (splitPoint !== data.length) { - currentChunk = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__["sliceUint8"])(data, 0, splitPoint); - this.remainderData = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__["sliceUint8"])(data, splitPoint); - } - - return currentChunk; - }; - - _proto.logOnce = function logOnce(msg) { - if (!this.logEnabled) { - return; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log("[decrypter.ts]: " + msg); - this.logEnabled = false; - }; - - return Decrypter; -}(); - - - -/***/ }), - -/***/ "./src/crypt/fast-aes-key.ts": -/*!***********************************!*\ + /***/ "./src/crypt/fast-aes-key.ts": + /*!***********************************!*\ !*** ./src/crypt/fast-aes-key.ts ***! \***********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return FastAESKey; + }); + var FastAESKey = /*#__PURE__*/ (function () { + function FastAESKey(subtle, key) { + this.subtle = void 0; + this.key = void 0; + this.subtle = subtle; + this.key = key; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return FastAESKey; }); -var FastAESKey = /*#__PURE__*/function () { - function FastAESKey(subtle, key) { - this.subtle = void 0; - this.key = void 0; - this.subtle = subtle; - this.key = key; - } + var _proto = FastAESKey.prototype; - var _proto = FastAESKey.prototype; + _proto.expandKey = function expandKey() { + return this.subtle.importKey( + "raw", + this.key, + { + name: "AES-CBC", + }, + false, + ["encrypt", "decrypt"] + ); + }; - _proto.expandKey = function expandKey() { - return this.subtle.importKey('raw', this.key, { - name: 'AES-CBC' - }, false, ['encrypt', 'decrypt']); - }; + return FastAESKey; + })(); - return FastAESKey; -}(); + /***/ + }, - - -/***/ }), - -/***/ "./src/demux/aacdemuxer.ts": -/*!*********************************!*\ + /***/ "./src/demux/aacdemuxer.ts": + /*!*********************************!*\ !*** ./src/demux/aacdemuxer.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-audio-demuxer */ "./src/demux/base-audio-demuxer.ts"); + /* harmony import */ var _adts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./adts */ "./src/demux/adts.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-audio-demuxer */ "./src/demux/base-audio-demuxer.ts"); -/* harmony import */ var _adts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./adts */ "./src/demux/adts.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + /** + * AAC demuxer + */ -/** - * AAC demuxer - */ + var AACDemuxer = /*#__PURE__*/ (function (_BaseAudioDemuxer) { + _inheritsLoose(AACDemuxer, _BaseAudioDemuxer); + function AACDemuxer(observer, config) { + var _this; + _this = _BaseAudioDemuxer.call(this) || this; + _this.observer = void 0; + _this.config = void 0; + _this.observer = observer; + _this.config = config; + return _this; + } + var _proto = AACDemuxer.prototype; + _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { + _BaseAudioDemuxer.prototype.resetInitSegment.call(this, audioCodec, videoCodec, duration); -var AACDemuxer = /*#__PURE__*/function (_BaseAudioDemuxer) { - _inheritsLoose(AACDemuxer, _BaseAudioDemuxer); + this._audioTrack = { + container: "audio/adts", + type: "audio", + id: 2, + pid: -1, + sequenceNumber: 0, + isAAC: true, + samples: [], + manifestCodec: audioCodec, + duration: duration, + inputTimeScale: 90000, + dropped: 0, + }; + }; // Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS - function AACDemuxer(observer, config) { - var _this; + AACDemuxer.probe = function probe(data) { + if (!data) { + return false; + } // Check for the ADTS sync word + // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1 + // Layer bits (position 14 and 15) in header should be always 0 for ADTS + // More info https://wiki.multimedia.cx/index.php?title=ADTS - _this = _BaseAudioDemuxer.call(this) || this; - _this.observer = void 0; - _this.config = void 0; - _this.observer = observer; - _this.config = config; - return _this; - } + var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_3__["getID3Data"](data, 0) || []; + var offset = id3Data.length; - var _proto = AACDemuxer.prototype; + for (var length = data.length; offset < length; offset++) { + if (_adts__WEBPACK_IMPORTED_MODULE_1__["probe"](data, offset)) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("ADTS sync word found !"); + return true; + } + } - _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { - _BaseAudioDemuxer.prototype.resetInitSegment.call(this, audioCodec, videoCodec, duration); + return false; + }; - this._audioTrack = { - container: 'audio/adts', - type: 'audio', - id: 2, - pid: -1, - sequenceNumber: 0, - isAAC: true, - samples: [], - manifestCodec: audioCodec, - duration: duration, - inputTimeScale: 90000, - dropped: 0 - }; - } // Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS - ; + _proto.canParse = function canParse(data, offset) { + return _adts__WEBPACK_IMPORTED_MODULE_1__["canParse"](data, offset); + }; - AACDemuxer.probe = function probe(data) { - if (!data) { - return false; - } // Check for the ADTS sync word - // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1 - // Layer bits (position 14 and 15) in header should be always 0 for ADTS - // More info https://wiki.multimedia.cx/index.php?title=ADTS + _proto.appendFrame = function appendFrame(track, data, offset) { + _adts__WEBPACK_IMPORTED_MODULE_1__["initTrackConfig"](track, this.observer, data, offset, track.manifestCodec); + var frame = _adts__WEBPACK_IMPORTED_MODULE_1__["appendFrame"](track, data, offset, this.initPTS, this.frameIndex); + if (frame && frame.missing === 0) { + return frame; + } + }; - var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_3__["getID3Data"](data, 0) || []; - var offset = id3Data.length; + return AACDemuxer; + })(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]); - for (var length = data.length; offset < length; offset++) { - if (_adts__WEBPACK_IMPORTED_MODULE_1__["probe"](data, offset)) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('ADTS sync word found !'); - return true; - } - } + AACDemuxer.minProbeByteLength = 9; + /* harmony default export */ __webpack_exports__["default"] = AACDemuxer; - return false; - }; + /***/ + }, - _proto.canParse = function canParse(data, offset) { - return _adts__WEBPACK_IMPORTED_MODULE_1__["canParse"](data, offset); - }; - - _proto.appendFrame = function appendFrame(track, data, offset) { - _adts__WEBPACK_IMPORTED_MODULE_1__["initTrackConfig"](track, this.observer, data, offset, track.manifestCodec); - var frame = _adts__WEBPACK_IMPORTED_MODULE_1__["appendFrame"](track, data, offset, this.initPTS, this.frameIndex); - - if (frame && frame.missing === 0) { - return frame; - } - }; - - return AACDemuxer; -}(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]); - -AACDemuxer.minProbeByteLength = 9; -/* harmony default export */ __webpack_exports__["default"] = (AACDemuxer); - -/***/ }), - -/***/ "./src/demux/adts.ts": -/*!***************************!*\ + /***/ "./src/demux/adts.ts": + /*!***************************!*\ !*** ./src/demux/adts.ts ***! \***************************/ -/*! exports provided: getAudioConfig, isHeaderPattern, getHeaderLength, getFullFrameLength, canGetFrameLength, isHeader, canParse, probe, initTrackConfig, getFrameDuration, parseFrameHeader, appendFrame */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: getAudioConfig, isHeaderPattern, getHeaderLength, getFullFrameLength, canGetFrameLength, isHeader, canParse, probe, initTrackConfig, getFrameDuration, parseFrameHeader, appendFrame */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAudioConfig", function () { + return getAudioConfig; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeaderPattern", function () { + return isHeaderPattern; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHeaderLength", function () { + return getHeaderLength; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getFullFrameLength", function () { + return getFullFrameLength; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canGetFrameLength", function () { + return canGetFrameLength; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeader", function () { + return isHeader; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canParse", function () { + return canParse; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "probe", function () { + return probe; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initTrackConfig", function () { + return initTrackConfig; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getFrameDuration", function () { + return getFrameDuration; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseFrameHeader", function () { + return parseFrameHeader; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "appendFrame", function () { + return appendFrame; + }); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /** + * ADTS parser helper + * @link https://wiki.multimedia.cx/index.php?title=ADTS + */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAudioConfig", function() { return getAudioConfig; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeaderPattern", function() { return isHeaderPattern; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHeaderLength", function() { return getHeaderLength; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getFullFrameLength", function() { return getFullFrameLength; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canGetFrameLength", function() { return canGetFrameLength; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeader", function() { return isHeader; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canParse", function() { return canParse; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "probe", function() { return probe; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initTrackConfig", function() { return initTrackConfig; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getFrameDuration", function() { return getFrameDuration; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseFrameHeader", function() { return parseFrameHeader; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "appendFrame", function() { return appendFrame; }); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/** - * ADTS parser helper - * @link https://wiki.multimedia.cx/index.php?title=ADTS - */ + function getAudioConfig(observer, data, offset, audioCodec) { + var adtsObjectType; + var adtsExtensionSamplingIndex; + var adtsChanelConfig; + var config; + var userAgent = navigator.userAgent.toLowerCase(); + var manifestCodec = audioCodec; + var adtsSampleingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350]; // byte 2 + adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1; + var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2; + if (adtsSamplingIndex > adtsSampleingRates.length - 1) { + observer.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_PARSING_ERROR, + fatal: true, + reason: "invalid ADTS sampling index:" + adtsSamplingIndex, + }); + return; + } -function getAudioConfig(observer, data, offset, audioCodec) { - var adtsObjectType; - var adtsExtensionSamplingIndex; - var adtsChanelConfig; - var config; - var userAgent = navigator.userAgent.toLowerCase(); - var manifestCodec = audioCodec; - var adtsSampleingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350]; // byte 2 + adtsChanelConfig = (data[offset + 2] & 0x01) << 2; // byte 3 - adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1; - var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2; + adtsChanelConfig |= (data[offset + 3] & 0xc0) >>> 6; + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex); // firefox: freq less than 24kHz = AAC SBR (HE-AAC) - if (adtsSamplingIndex > adtsSampleingRates.length - 1) { - observer.trigger(_events__WEBPACK_IMPORTED_MODULE_2__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_PARSING_ERROR, - fatal: true, - reason: "invalid ADTS sampling index:" + adtsSamplingIndex - }); - return; - } + if (/firefox/i.test(userAgent)) { + if (adtsSamplingIndex >= 6) { + adtsObjectType = 5; + config = new Array(4); // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies + // there is a factor 2 between frame sample rate and output sample rate + // multiply frequency by 2 (see table below, equivalent to substract 3) - adtsChanelConfig = (data[offset + 2] & 0x01) << 2; // byte 3 - - adtsChanelConfig |= (data[offset + 3] & 0xc0) >>> 6; - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex); // firefox: freq less than 24kHz = AAC SBR (HE-AAC) - - if (/firefox/i.test(userAgent)) { - if (adtsSamplingIndex >= 6) { - adtsObjectType = 5; - config = new Array(4); // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies - // there is a factor 2 between frame sample rate and output sample rate - // multiply frequency by 2 (see table below, equivalent to substract 3) - - adtsExtensionSamplingIndex = adtsSamplingIndex - 3; - } else { - adtsObjectType = 2; - config = new Array(2); - adtsExtensionSamplingIndex = adtsSamplingIndex; - } // Android : always use AAC - - } else if (userAgent.indexOf('android') !== -1) { - adtsObjectType = 2; - config = new Array(2); - adtsExtensionSamplingIndex = adtsSamplingIndex; - } else { - /* for other browsers (Chrome/Vivaldi/Opera ...) + adtsExtensionSamplingIndex = adtsSamplingIndex - 3; + } else { + adtsObjectType = 2; + config = new Array(2); + adtsExtensionSamplingIndex = adtsSamplingIndex; + } // Android : always use AAC + } else if (userAgent.indexOf("android") !== -1) { + adtsObjectType = 2; + config = new Array(2); + adtsExtensionSamplingIndex = adtsSamplingIndex; + } else { + /* for other browsers (Chrome/Vivaldi/Opera ...) always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...) */ - adtsObjectType = 5; - config = new Array(4); // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz) + adtsObjectType = 5; + config = new Array(4); // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz) - if (audioCodec && (audioCodec.indexOf('mp4a.40.29') !== -1 || audioCodec.indexOf('mp4a.40.5') !== -1) || !audioCodec && adtsSamplingIndex >= 6) { - // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies - // there is a factor 2 between frame sample rate and output sample rate - // multiply frequency by 2 (see table below, equivalent to substract 3) - adtsExtensionSamplingIndex = adtsSamplingIndex - 3; - } else { - // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio) - // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo. - if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && (adtsSamplingIndex >= 6 && adtsChanelConfig === 1 || /vivaldi/i.test(userAgent)) || !audioCodec && adtsChanelConfig === 1) { - adtsObjectType = 2; - config = new Array(2); - } + if ((audioCodec && (audioCodec.indexOf("mp4a.40.29") !== -1 || audioCodec.indexOf("mp4a.40.5") !== -1)) || (!audioCodec && adtsSamplingIndex >= 6)) { + // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies + // there is a factor 2 between frame sample rate and output sample rate + // multiply frequency by 2 (see table below, equivalent to substract 3) + adtsExtensionSamplingIndex = adtsSamplingIndex - 3; + } else { + // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio) + // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo. + if ((audioCodec && audioCodec.indexOf("mp4a.40.2") !== -1 && ((adtsSamplingIndex >= 6 && adtsChanelConfig === 1) || /vivaldi/i.test(userAgent))) || (!audioCodec && adtsChanelConfig === 1)) { + adtsObjectType = 2; + config = new Array(2); + } - adtsExtensionSamplingIndex = adtsSamplingIndex; - } - } - /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config + adtsExtensionSamplingIndex = adtsSamplingIndex; + } + } + /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config ISO 14496-3 (AAC).pdf - Table 1.13 — Syntax of AudioSpecificConfig() Audio Profile / Audio Object Type 0: Null @@ -12917,5629 +13264,5734 @@ function getAudioConfig(observer, data, offset, audioCodec) { 1: 1 channel: front-center 2: 2 channels: front-left, front-right */ - // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1 + // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1 + config[0] = adtsObjectType << 3; // samplingFrequencyIndex - config[0] = adtsObjectType << 3; // samplingFrequencyIndex + config[0] |= (adtsSamplingIndex & 0x0e) >> 1; + config[1] |= (adtsSamplingIndex & 0x01) << 7; // channelConfiguration - config[0] |= (adtsSamplingIndex & 0x0e) >> 1; - config[1] |= (adtsSamplingIndex & 0x01) << 7; // channelConfiguration + config[1] |= adtsChanelConfig << 3; - config[1] |= adtsChanelConfig << 3; + if (adtsObjectType === 5) { + // adtsExtensionSampleingIndex + config[1] |= (adtsExtensionSamplingIndex & 0x0e) >> 1; + config[2] = (adtsExtensionSamplingIndex & 0x01) << 7; // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ??? + // https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc - if (adtsObjectType === 5) { - // adtsExtensionSampleingIndex - config[1] |= (adtsExtensionSamplingIndex & 0x0e) >> 1; - config[2] = (adtsExtensionSamplingIndex & 0x01) << 7; // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ??? - // https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc + config[2] |= 2 << 2; + config[3] = 0; + } - config[2] |= 2 << 2; - config[3] = 0; - } + return { + config: config, + samplerate: adtsSampleingRates[adtsSamplingIndex], + channelCount: adtsChanelConfig, + codec: "mp4a.40." + adtsObjectType, + manifestCodec: manifestCodec, + }; + } + function isHeaderPattern(data, offset) { + return data[offset] === 0xff && (data[offset + 1] & 0xf6) === 0xf0; + } + function getHeaderLength(data, offset) { + return data[offset + 1] & 0x01 ? 7 : 9; + } + function getFullFrameLength(data, offset) { + return ((data[offset + 3] & 0x03) << 11) | (data[offset + 4] << 3) | ((data[offset + 5] & 0xe0) >>> 5); + } + function canGetFrameLength(data, offset) { + return offset + 5 < data.length; + } + function isHeader(data, offset) { + // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1 + // Layer bits (position 14 and 15) in header should be always 0 for ADTS + // More info https://wiki.multimedia.cx/index.php?title=ADTS + return offset + 1 < data.length && isHeaderPattern(data, offset); + } + function canParse(data, offset) { + return canGetFrameLength(data, offset) && isHeaderPattern(data, offset) && getFullFrameLength(data, offset) <= data.length - offset; + } + function probe(data, offset) { + // same as isHeader but we also check that ADTS frame follows last ADTS frame + // or end of data is reached + if (isHeader(data, offset)) { + // ADTS header Length + var headerLength = getHeaderLength(data, offset); - return { - config: config, - samplerate: adtsSampleingRates[adtsSamplingIndex], - channelCount: adtsChanelConfig, - codec: 'mp4a.40.' + adtsObjectType, - manifestCodec: manifestCodec - }; -} -function isHeaderPattern(data, offset) { - return data[offset] === 0xff && (data[offset + 1] & 0xf6) === 0xf0; -} -function getHeaderLength(data, offset) { - return data[offset + 1] & 0x01 ? 7 : 9; -} -function getFullFrameLength(data, offset) { - return (data[offset + 3] & 0x03) << 11 | data[offset + 4] << 3 | (data[offset + 5] & 0xe0) >>> 5; -} -function canGetFrameLength(data, offset) { - return offset + 5 < data.length; -} -function isHeader(data, offset) { - // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1 - // Layer bits (position 14 and 15) in header should be always 0 for ADTS - // More info https://wiki.multimedia.cx/index.php?title=ADTS - return offset + 1 < data.length && isHeaderPattern(data, offset); -} -function canParse(data, offset) { - return canGetFrameLength(data, offset) && isHeaderPattern(data, offset) && getFullFrameLength(data, offset) <= data.length - offset; -} -function probe(data, offset) { - // same as isHeader but we also check that ADTS frame follows last ADTS frame - // or end of data is reached - if (isHeader(data, offset)) { - // ADTS header Length - var headerLength = getHeaderLength(data, offset); + if (offset + headerLength >= data.length) { + return false; + } // ADTS frame Length - if (offset + headerLength >= data.length) { - return false; - } // ADTS frame Length + var frameLength = getFullFrameLength(data, offset); + if (frameLength <= headerLength) { + return false; + } - var frameLength = getFullFrameLength(data, offset); + var newOffset = offset + frameLength; + return newOffset === data.length || isHeader(data, newOffset); + } - if (frameLength <= headerLength) { - return false; - } + return false; + } + function initTrackConfig(track, observer, data, offset, audioCodec) { + if (!track.samplerate) { + var config = getAudioConfig(observer, data, offset, audioCodec); - var newOffset = offset + frameLength; - return newOffset === data.length || isHeader(data, newOffset); - } + if (!config) { + return; + } - return false; -} -function initTrackConfig(track, observer, data, offset, audioCodec) { - if (!track.samplerate) { - var config = getAudioConfig(observer, data, offset, audioCodec); + track.config = config.config; + track.samplerate = config.samplerate; + track.channelCount = config.channelCount; + track.codec = config.codec; + track.manifestCodec = config.manifestCodec; + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log("parsed codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount); + } + } + function getFrameDuration(samplerate) { + return (1024 * 90000) / samplerate; + } + function parseFrameHeader(data, offset, pts, frameIndex, frameDuration) { + // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header + var headerLength = getHeaderLength(data, offset); // retrieve frame size - if (!config) { - return; - } + var frameLength = getFullFrameLength(data, offset); + frameLength -= headerLength; - track.config = config.config; - track.samplerate = config.samplerate; - track.channelCount = config.channelCount; - track.codec = config.codec; - track.manifestCodec = config.manifestCodec; - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log("parsed codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount); - } -} -function getFrameDuration(samplerate) { - return 1024 * 90000 / samplerate; -} -function parseFrameHeader(data, offset, pts, frameIndex, frameDuration) { - // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header - var headerLength = getHeaderLength(data, offset); // retrieve frame size + if (frameLength > 0) { + var stamp = pts + frameIndex * frameDuration; // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`); - var frameLength = getFullFrameLength(data, offset); - frameLength -= headerLength; + return { + headerLength: headerLength, + frameLength: frameLength, + stamp: stamp, + }; + } + } + function appendFrame(track, data, offset, pts, frameIndex) { + var frameDuration = getFrameDuration(track.samplerate); + var header = parseFrameHeader(data, offset, pts, frameIndex, frameDuration); - if (frameLength > 0) { - var stamp = pts + frameIndex * frameDuration; // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`); + if (header) { + var frameLength = header.frameLength, + headerLength = header.headerLength, + stamp = header.stamp; + var length = headerLength + frameLength; + var missing = Math.max(0, offset + length - data.length); // logger.log(`AAC frame ${frameIndex}, pts:${stamp} length@offset/total: ${frameLength}@${offset+headerLength}/${data.byteLength} missing: ${missing}`); - return { - headerLength: headerLength, - frameLength: frameLength, - stamp: stamp - }; - } -} -function appendFrame(track, data, offset, pts, frameIndex) { - var frameDuration = getFrameDuration(track.samplerate); - var header = parseFrameHeader(data, offset, pts, frameIndex, frameDuration); + var unit; - if (header) { - var frameLength = header.frameLength, - headerLength = header.headerLength, - stamp = header.stamp; - var length = headerLength + frameLength; - var missing = Math.max(0, offset + length - data.length); // logger.log(`AAC frame ${frameIndex}, pts:${stamp} length@offset/total: ${frameLength}@${offset+headerLength}/${data.byteLength} missing: ${missing}`); + if (missing) { + unit = new Uint8Array(length - headerLength); + unit.set(data.subarray(offset + headerLength, data.length), 0); + } else { + unit = data.subarray(offset + headerLength, offset + length); + } - var unit; + var sample = { + unit: unit, + pts: stamp, + }; - if (missing) { - unit = new Uint8Array(length - headerLength); - unit.set(data.subarray(offset + headerLength, data.length), 0); - } else { - unit = data.subarray(offset + headerLength, offset + length); - } + if (!missing) { + track.samples.push(sample); + } - var sample = { - unit: unit, - pts: stamp - }; + return { + sample: sample, + length: length, + missing: missing, + }; + } + } - if (!missing) { - track.samples.push(sample); - } + /***/ + }, - return { - sample: sample, - length: length, - missing: missing - }; - } -} - -/***/ }), - -/***/ "./src/demux/base-audio-demuxer.ts": -/*!*****************************************!*\ + /***/ "./src/demux/base-audio-demuxer.ts": + /*!*****************************************!*\ !*** ./src/demux/base-audio-demuxer.ts ***! \*****************************************/ -/*! exports provided: initPTSFn, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: initPTSFn, default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initPTSFn", function () { + return initPTSFn; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); + /* harmony import */ var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dummy-demuxed-track */ "./src/demux/dummy-demuxed-track.ts"); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initPTSFn", function() { return initPTSFn; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); -/* harmony import */ var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dummy-demuxed-track */ "./src/demux/dummy-demuxed-track.ts"); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts"); + var BaseAudioDemuxer = /*#__PURE__*/ (function () { + function BaseAudioDemuxer() { + this._audioTrack = void 0; + this._id3Track = void 0; + this.frameIndex = 0; + this.cachedData = null; + this.initPTS = null; + } + var _proto = BaseAudioDemuxer.prototype; + _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { + this._id3Track = { + type: "id3", + id: 3, + pid: -1, + inputTimeScale: 90000, + sequenceNumber: 0, + samples: [], + dropped: 0, + }; + }; + _proto.resetTimeStamp = function resetTimeStamp() {}; + _proto.resetContiguity = function resetContiguity() {}; + _proto.canParse = function canParse(data, offset) { + return false; + }; -var BaseAudioDemuxer = /*#__PURE__*/function () { - function BaseAudioDemuxer() { - this._audioTrack = void 0; - this._id3Track = void 0; - this.frameIndex = 0; - this.cachedData = null; - this.initPTS = null; - } + _proto.appendFrame = function appendFrame(track, data, offset) {}; // feed incoming data to the front of the parsing pipeline - var _proto = BaseAudioDemuxer.prototype; + _proto.demux = function demux(data, timeOffset) { + if (this.cachedData) { + data = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_3__["appendUint8Array"])(this.cachedData, data); + this.cachedData = null; + } - _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { - this._id3Track = { - type: 'id3', - id: 3, - pid: -1, - inputTimeScale: 90000, - sequenceNumber: 0, - samples: [], - dropped: 0 - }; - }; + var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getID3Data"](data, 0); + var offset = id3Data ? id3Data.length : 0; + var lastDataIndex; + var pts; + var track = this._audioTrack; + var id3Track = this._id3Track; + var timestamp = id3Data ? _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getTimeStamp"](id3Data) : undefined; + var length = data.length; - _proto.resetTimeStamp = function resetTimeStamp() {}; + if (this.frameIndex === 0 || this.initPTS === null) { + this.initPTS = initPTSFn(timestamp, timeOffset); + } // more expressive than alternative: id3Data?.length - _proto.resetContiguity = function resetContiguity() {}; + if (id3Data && id3Data.length > 0) { + id3Track.samples.push({ + pts: this.initPTS, + dts: this.initPTS, + data: id3Data, + }); + } - _proto.canParse = function canParse(data, offset) { - return false; - }; + pts = this.initPTS; - _proto.appendFrame = function appendFrame(track, data, offset) {} // feed incoming data to the front of the parsing pipeline - ; + while (offset < length) { + if (this.canParse(data, offset)) { + var frame = this.appendFrame(track, data, offset); - _proto.demux = function demux(data, timeOffset) { - if (this.cachedData) { - data = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_3__["appendUint8Array"])(this.cachedData, data); - this.cachedData = null; - } + if (frame) { + this.frameIndex++; + pts = frame.sample.pts; + offset += frame.length; + lastDataIndex = offset; + } else { + offset = length; + } + } else if (_demux_id3__WEBPACK_IMPORTED_MODULE_1__["canParse"](data, offset)) { + // after a ID3.canParse, a call to ID3.getID3Data *should* always returns some data + id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getID3Data"](data, offset); + id3Track.samples.push({ + pts: pts, + dts: pts, + data: id3Data, + }); + offset += id3Data.length; + lastDataIndex = offset; + } else { + offset++; + } - var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getID3Data"](data, 0); - var offset = id3Data ? id3Data.length : 0; - var lastDataIndex; - var pts; - var track = this._audioTrack; - var id3Track = this._id3Track; - var timestamp = id3Data ? _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getTimeStamp"](id3Data) : undefined; - var length = data.length; + if (offset === length && lastDataIndex !== length) { + var partialData = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_4__["sliceUint8"])(data, lastDataIndex); - if (this.frameIndex === 0 || this.initPTS === null) { - this.initPTS = initPTSFn(timestamp, timeOffset); - } // more expressive than alternative: id3Data?.length + if (this.cachedData) { + this.cachedData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_3__["appendUint8Array"])(this.cachedData, partialData); + } else { + this.cachedData = partialData; + } + } + } + return { + audioTrack: track, + avcTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])(), + id3Track: id3Track, + textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])(), + }; + }; - if (id3Data && id3Data.length > 0) { - id3Track.samples.push({ - pts: this.initPTS, - dts: this.initPTS, - data: id3Data - }); - } + _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) { + return Promise.reject(new Error("[" + this + "] This demuxer does not support Sample-AES decryption")); + }; - pts = this.initPTS; + _proto.flush = function flush(timeOffset) { + // Parse cache in case of remaining frames. + var cachedData = this.cachedData; - while (offset < length) { - if (this.canParse(data, offset)) { - var frame = this.appendFrame(track, data, offset); + if (cachedData) { + this.cachedData = null; + this.demux(cachedData, 0); + } - if (frame) { - this.frameIndex++; - pts = frame.sample.pts; - offset += frame.length; - lastDataIndex = offset; - } else { - offset = length; - } - } else if (_demux_id3__WEBPACK_IMPORTED_MODULE_1__["canParse"](data, offset)) { - // after a ID3.canParse, a call to ID3.getID3Data *should* always returns some data - id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getID3Data"](data, offset); - id3Track.samples.push({ - pts: pts, - dts: pts, - data: id3Data - }); - offset += id3Data.length; - lastDataIndex = offset; - } else { - offset++; - } + this.frameIndex = 0; + return { + audioTrack: this._audioTrack, + avcTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])(), + id3Track: this._id3Track, + textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])(), + }; + }; - if (offset === length && lastDataIndex !== length) { - var partialData = Object(_utils_typed_array__WEBPACK_IMPORTED_MODULE_4__["sliceUint8"])(data, lastDataIndex); + _proto.destroy = function destroy() {}; - if (this.cachedData) { - this.cachedData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_3__["appendUint8Array"])(this.cachedData, partialData); - } else { - this.cachedData = partialData; - } - } - } + return BaseAudioDemuxer; + })(); + /** + * Initialize PTS + *

+ * use timestamp unless it is undefined, NaN or Infinity + *

+ */ - return { - audioTrack: track, - avcTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])(), - id3Track: id3Track, - textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])() - }; - }; + var initPTSFn = function initPTSFn(timestamp, timeOffset) { + return Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(timestamp) ? timestamp * 90 : timeOffset * 90000; + }; + /* harmony default export */ __webpack_exports__["default"] = BaseAudioDemuxer; - _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) { - return Promise.reject(new Error("[" + this + "] This demuxer does not support Sample-AES decryption")); - }; + /***/ + }, - _proto.flush = function flush(timeOffset) { - // Parse cache in case of remaining frames. - var cachedData = this.cachedData; - - if (cachedData) { - this.cachedData = null; - this.demux(cachedData, 0); - } - - this.frameIndex = 0; - return { - audioTrack: this._audioTrack, - avcTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])(), - id3Track: this._id3Track, - textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_2__["dummyTrack"])() - }; - }; - - _proto.destroy = function destroy() {}; - - return BaseAudioDemuxer; -}(); -/** - * Initialize PTS - *

- * use timestamp unless it is undefined, NaN or Infinity - *

- */ - - -var initPTSFn = function initPTSFn(timestamp, timeOffset) { - return Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(timestamp) ? timestamp * 90 : timeOffset * 90000; -}; -/* harmony default export */ __webpack_exports__["default"] = (BaseAudioDemuxer); - -/***/ }), - -/***/ "./src/demux/chunk-cache.ts": -/*!**********************************!*\ + /***/ "./src/demux/chunk-cache.ts": + /*!**********************************!*\ !*** ./src/demux/chunk-cache.ts ***! \**********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return ChunkCache; + }); + var ChunkCache = /*#__PURE__*/ (function () { + function ChunkCache() { + this.chunks = []; + this.dataLength = 0; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ChunkCache; }); -var ChunkCache = /*#__PURE__*/function () { - function ChunkCache() { - this.chunks = []; - this.dataLength = 0; - } + var _proto = ChunkCache.prototype; - var _proto = ChunkCache.prototype; + _proto.push = function push(chunk) { + this.chunks.push(chunk); + this.dataLength += chunk.length; + }; - _proto.push = function push(chunk) { - this.chunks.push(chunk); - this.dataLength += chunk.length; - }; + _proto.flush = function flush() { + var chunks = this.chunks, + dataLength = this.dataLength; + var result; - _proto.flush = function flush() { - var chunks = this.chunks, - dataLength = this.dataLength; - var result; + if (!chunks.length) { + return new Uint8Array(0); + } else if (chunks.length === 1) { + result = chunks[0]; + } else { + result = concatUint8Arrays(chunks, dataLength); + } - if (!chunks.length) { - return new Uint8Array(0); - } else if (chunks.length === 1) { - result = chunks[0]; - } else { - result = concatUint8Arrays(chunks, dataLength); - } + this.reset(); + return result; + }; - this.reset(); - return result; - }; + _proto.reset = function reset() { + this.chunks.length = 0; + this.dataLength = 0; + }; - _proto.reset = function reset() { - this.chunks.length = 0; - this.dataLength = 0; - }; + return ChunkCache; + })(); - return ChunkCache; -}(); + function concatUint8Arrays(chunks, dataLength) { + var result = new Uint8Array(dataLength); + var offset = 0; + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + result.set(chunk, offset); + offset += chunk.length; + } + return result; + } -function concatUint8Arrays(chunks, dataLength) { - var result = new Uint8Array(dataLength); - var offset = 0; + /***/ + }, - for (var i = 0; i < chunks.length; i++) { - var chunk = chunks[i]; - result.set(chunk, offset); - offset += chunk.length; - } - - return result; -} - -/***/ }), - -/***/ "./src/demux/dummy-demuxed-track.ts": -/*!******************************************!*\ + /***/ "./src/demux/dummy-demuxed-track.ts": + /*!******************************************!*\ !*** ./src/demux/dummy-demuxed-track.ts ***! \******************************************/ -/*! exports provided: dummyTrack */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: dummyTrack */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dummyTrack", function () { + return dummyTrack; + }); + function dummyTrack() { + return { + type: "", + id: -1, + pid: -1, + inputTimeScale: 90000, + sequenceNumber: -1, + samples: [], + dropped: 0, + }; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dummyTrack", function() { return dummyTrack; }); -function dummyTrack() { - return { - type: '', - id: -1, - pid: -1, - inputTimeScale: 90000, - sequenceNumber: -1, - samples: [], - dropped: 0 - }; -} + /***/ + }, -/***/ }), - -/***/ "./src/demux/exp-golomb.ts": -/*!*********************************!*\ + /***/ "./src/demux/exp-golomb.ts": + /*!*********************************!*\ !*** ./src/demux/exp-golomb.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/** - * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264. - */ - - -var ExpGolomb = /*#__PURE__*/function () { - function ExpGolomb(data) { - this.data = void 0; - this.bytesAvailable = void 0; - this.word = void 0; - this.bitsAvailable = void 0; - this.data = data; // the number of bytes left to examine in this.data - - this.bytesAvailable = data.byteLength; // the current word being examined - - this.word = 0; // :uint - // the number of bits left to examine in the current word - - this.bitsAvailable = 0; // :uint - } // ():void - - - var _proto = ExpGolomb.prototype; - - _proto.loadWord = function loadWord() { - var data = this.data; - var bytesAvailable = this.bytesAvailable; - var position = data.byteLength - bytesAvailable; - var workingBytes = new Uint8Array(4); - var availableBytes = Math.min(4, bytesAvailable); - - if (availableBytes === 0) { - throw new Error('no bytes available'); - } - - workingBytes.set(data.subarray(position, position + availableBytes)); - this.word = new DataView(workingBytes.buffer).getUint32(0); // track the amount of this.data that has been processed - - this.bitsAvailable = availableBytes * 8; - this.bytesAvailable -= availableBytes; - } // (count:int):void - ; - - _proto.skipBits = function skipBits(count) { - var skipBytes; // :int - - if (this.bitsAvailable > count) { - this.word <<= count; - this.bitsAvailable -= count; - } else { - count -= this.bitsAvailable; - skipBytes = count >> 3; - count -= skipBytes >> 3; - this.bytesAvailable -= skipBytes; - this.loadWord(); - this.word <<= count; - this.bitsAvailable -= count; - } - } // (size:int):uint - ; - - _proto.readBits = function readBits(size) { - var bits = Math.min(this.bitsAvailable, size); // :uint - - var valu = this.word >>> 32 - bits; // :uint - - if (size > 32) { - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].error('Cannot read more than 32 bits at a time'); - } - - this.bitsAvailable -= bits; - - if (this.bitsAvailable > 0) { - this.word <<= bits; - } else if (this.bytesAvailable > 0) { - this.loadWord(); - } - - bits = size - bits; - - if (bits > 0 && this.bitsAvailable) { - return valu << bits | this.readBits(bits); - } else { - return valu; - } - } // ():uint - ; - - _proto.skipLZ = function skipLZ() { - var leadingZeroCount; // :uint - - for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) { - if ((this.word & 0x80000000 >>> leadingZeroCount) !== 0) { - // the first bit of working word is 1 - this.word <<= leadingZeroCount; - this.bitsAvailable -= leadingZeroCount; - return leadingZeroCount; - } - } // we exhausted word and still have not found a 1 - - - this.loadWord(); - return leadingZeroCount + this.skipLZ(); - } // ():void - ; - - _proto.skipUEG = function skipUEG() { - this.skipBits(1 + this.skipLZ()); - } // ():void - ; - - _proto.skipEG = function skipEG() { - this.skipBits(1 + this.skipLZ()); - } // ():uint - ; - - _proto.readUEG = function readUEG() { - var clz = this.skipLZ(); // :uint - - return this.readBits(clz + 1) - 1; - } // ():int - ; - - _proto.readEG = function readEG() { - var valu = this.readUEG(); // :int - - if (0x01 & valu) { - // the number is odd if the low order bit is set - return 1 + valu >>> 1; // add 1 to make it even, and divide by 2 - } else { - return -1 * (valu >>> 1); // divide by two then make it negative - } - } // Some convenience functions - // :Boolean - ; - - _proto.readBoolean = function readBoolean() { - return this.readBits(1) === 1; - } // ():int - ; - - _proto.readUByte = function readUByte() { - return this.readBits(8); - } // ():int - ; - - _proto.readUShort = function readUShort() { - return this.readBits(16); - } // ():int - ; - - _proto.readUInt = function readUInt() { - return this.readBits(32); - } - /** - * Advance the ExpGolomb decoder past a scaling list. The scaling - * list is optionally transmitted as part of a sequence parameter - * set and is not relevant to transmuxing. - * @param count the number of entries in this scaling list - * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1 - */ - ; - - _proto.skipScalingList = function skipScalingList(count) { - var lastScale = 8; - var nextScale = 8; - var deltaScale; - - for (var j = 0; j < count; j++) { - if (nextScale !== 0) { - deltaScale = this.readEG(); - nextScale = (lastScale + deltaScale + 256) % 256; - } - - lastScale = nextScale === 0 ? lastScale : nextScale; - } - } - /** - * Read a sequence parameter set and return some interesting video - * properties. A sequence parameter set is the H264 metadata that - * describes the properties of upcoming video frames. - * @param data {Uint8Array} the bytes of a sequence parameter set - * @return {object} an object with configuration parsed from the - * sequence parameter set, including the dimensions of the - * associated video frames. - */ - ; - - _proto.readSPS = function readSPS() { - var frameCropLeftOffset = 0; - var frameCropRightOffset = 0; - var frameCropTopOffset = 0; - var frameCropBottomOffset = 0; - var numRefFramesInPicOrderCntCycle; - var scalingListCount; - var i; - var readUByte = this.readUByte.bind(this); - var readBits = this.readBits.bind(this); - var readUEG = this.readUEG.bind(this); - var readBoolean = this.readBoolean.bind(this); - var skipBits = this.skipBits.bind(this); - var skipEG = this.skipEG.bind(this); - var skipUEG = this.skipUEG.bind(this); - var skipScalingList = this.skipScalingList.bind(this); - readUByte(); - var profileIdc = readUByte(); // profile_idc - - readBits(5); // profileCompat constraint_set[0-4]_flag, u(5) - - skipBits(3); // reserved_zero_3bits u(3), - - readUByte(); // level_idc u(8) - - skipUEG(); // seq_parameter_set_id - // some profiles have more optional data we don't need - - if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) { - var chromaFormatIdc = readUEG(); - - if (chromaFormatIdc === 3) { - skipBits(1); - } // separate_colour_plane_flag - - - skipUEG(); // bit_depth_luma_minus8 - - skipUEG(); // bit_depth_chroma_minus8 - - skipBits(1); // qpprime_y_zero_transform_bypass_flag - - if (readBoolean()) { - // seq_scaling_matrix_present_flag - scalingListCount = chromaFormatIdc !== 3 ? 8 : 12; - - for (i = 0; i < scalingListCount; i++) { - if (readBoolean()) { - // seq_scaling_list_present_flag[ i ] - if (i < 6) { - skipScalingList(16); - } else { - skipScalingList(64); - } - } - } - } - } - - skipUEG(); // log2_max_frame_num_minus4 - - var picOrderCntType = readUEG(); - - if (picOrderCntType === 0) { - readUEG(); // log2_max_pic_order_cnt_lsb_minus4 - } else if (picOrderCntType === 1) { - skipBits(1); // delta_pic_order_always_zero_flag - - skipEG(); // offset_for_non_ref_pic - - skipEG(); // offset_for_top_to_bottom_field - - numRefFramesInPicOrderCntCycle = readUEG(); - - for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) { - skipEG(); - } // offset_for_ref_frame[ i ] - - } - - skipUEG(); // max_num_ref_frames - - skipBits(1); // gaps_in_frame_num_value_allowed_flag - - var picWidthInMbsMinus1 = readUEG(); - var picHeightInMapUnitsMinus1 = readUEG(); - var frameMbsOnlyFlag = readBits(1); - - if (frameMbsOnlyFlag === 0) { - skipBits(1); - } // mb_adaptive_frame_field_flag - - - skipBits(1); // direct_8x8_inference_flag - - if (readBoolean()) { - // frame_cropping_flag - frameCropLeftOffset = readUEG(); - frameCropRightOffset = readUEG(); - frameCropTopOffset = readUEG(); - frameCropBottomOffset = readUEG(); - } + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /** + * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264. + */ + + var ExpGolomb = /*#__PURE__*/ (function () { + function ExpGolomb(data) { + this.data = void 0; + this.bytesAvailable = void 0; + this.word = void 0; + this.bitsAvailable = void 0; + this.data = data; // the number of bytes left to examine in this.data + + this.bytesAvailable = data.byteLength; // the current word being examined + + this.word = 0; // :uint + // the number of bits left to examine in the current word + + this.bitsAvailable = 0; // :uint + } // ():void + + var _proto = ExpGolomb.prototype; + + _proto.loadWord = function loadWord() { + var data = this.data; + var bytesAvailable = this.bytesAvailable; + var position = data.byteLength - bytesAvailable; + var workingBytes = new Uint8Array(4); + var availableBytes = Math.min(4, bytesAvailable); + + if (availableBytes === 0) { + throw new Error("no bytes available"); + } + + workingBytes.set(data.subarray(position, position + availableBytes)); + this.word = new DataView(workingBytes.buffer).getUint32(0); // track the amount of this.data that has been processed + + this.bitsAvailable = availableBytes * 8; + this.bytesAvailable -= availableBytes; + }; // (count:int):void + + _proto.skipBits = function skipBits(count) { + var skipBytes; // :int + + if (this.bitsAvailable > count) { + this.word <<= count; + this.bitsAvailable -= count; + } else { + count -= this.bitsAvailable; + skipBytes = count >> 3; + count -= skipBytes >> 3; + this.bytesAvailable -= skipBytes; + this.loadWord(); + this.word <<= count; + this.bitsAvailable -= count; + } + }; // (size:int):uint + + _proto.readBits = function readBits(size) { + var bits = Math.min(this.bitsAvailable, size); // :uint + + var valu = this.word >>> (32 - bits); // :uint + + if (size > 32) { + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].error("Cannot read more than 32 bits at a time"); + } + + this.bitsAvailable -= bits; + + if (this.bitsAvailable > 0) { + this.word <<= bits; + } else if (this.bytesAvailable > 0) { + this.loadWord(); + } + + bits = size - bits; + + if (bits > 0 && this.bitsAvailable) { + return (valu << bits) | this.readBits(bits); + } else { + return valu; + } + }; // ():uint + + _proto.skipLZ = function skipLZ() { + var leadingZeroCount; // :uint + + for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) { + if ((this.word & (0x80000000 >>> leadingZeroCount)) !== 0) { + // the first bit of working word is 1 + this.word <<= leadingZeroCount; + this.bitsAvailable -= leadingZeroCount; + return leadingZeroCount; + } + } // we exhausted word and still have not found a 1 + + this.loadWord(); + return leadingZeroCount + this.skipLZ(); + }; // ():void + + _proto.skipUEG = function skipUEG() { + this.skipBits(1 + this.skipLZ()); + }; // ():void + + _proto.skipEG = function skipEG() { + this.skipBits(1 + this.skipLZ()); + }; // ():uint + + _proto.readUEG = function readUEG() { + var clz = this.skipLZ(); // :uint + + return this.readBits(clz + 1) - 1; + }; // ():int + + _proto.readEG = function readEG() { + var valu = this.readUEG(); // :int + + if (0x01 & valu) { + // the number is odd if the low order bit is set + return (1 + valu) >>> 1; // add 1 to make it even, and divide by 2 + } else { + return -1 * (valu >>> 1); // divide by two then make it negative + } + }; // Some convenience functions + // :Boolean + + _proto.readBoolean = function readBoolean() { + return this.readBits(1) === 1; + }; // ():int + + _proto.readUByte = function readUByte() { + return this.readBits(8); + }; // ():int + + _proto.readUShort = function readUShort() { + return this.readBits(16); + }; // ():int + + _proto.readUInt = function readUInt() { + return this.readBits(32); + }; + /** + * Advance the ExpGolomb decoder past a scaling list. The scaling + * list is optionally transmitted as part of a sequence parameter + * set and is not relevant to transmuxing. + * @param count the number of entries in this scaling list + * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1 + */ + + _proto.skipScalingList = function skipScalingList(count) { + var lastScale = 8; + var nextScale = 8; + var deltaScale; + + for (var j = 0; j < count; j++) { + if (nextScale !== 0) { + deltaScale = this.readEG(); + nextScale = (lastScale + deltaScale + 256) % 256; + } + + lastScale = nextScale === 0 ? lastScale : nextScale; + } + }; + /** + * Read a sequence parameter set and return some interesting video + * properties. A sequence parameter set is the H264 metadata that + * describes the properties of upcoming video frames. + * @param data {Uint8Array} the bytes of a sequence parameter set + * @return {object} an object with configuration parsed from the + * sequence parameter set, including the dimensions of the + * associated video frames. + */ + + _proto.readSPS = function readSPS() { + var frameCropLeftOffset = 0; + var frameCropRightOffset = 0; + var frameCropTopOffset = 0; + var frameCropBottomOffset = 0; + var numRefFramesInPicOrderCntCycle; + var scalingListCount; + var i; + var readUByte = this.readUByte.bind(this); + var readBits = this.readBits.bind(this); + var readUEG = this.readUEG.bind(this); + var readBoolean = this.readBoolean.bind(this); + var skipBits = this.skipBits.bind(this); + var skipEG = this.skipEG.bind(this); + var skipUEG = this.skipUEG.bind(this); + var skipScalingList = this.skipScalingList.bind(this); + readUByte(); + var profileIdc = readUByte(); // profile_idc + + readBits(5); // profileCompat constraint_set[0-4]_flag, u(5) + + skipBits(3); // reserved_zero_3bits u(3), + + readUByte(); // level_idc u(8) + + skipUEG(); // seq_parameter_set_id + // some profiles have more optional data we don't need + + if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) { + var chromaFormatIdc = readUEG(); + + if (chromaFormatIdc === 3) { + skipBits(1); + } // separate_colour_plane_flag + + skipUEG(); // bit_depth_luma_minus8 + + skipUEG(); // bit_depth_chroma_minus8 + + skipBits(1); // qpprime_y_zero_transform_bypass_flag + + if (readBoolean()) { + // seq_scaling_matrix_present_flag + scalingListCount = chromaFormatIdc !== 3 ? 8 : 12; + + for (i = 0; i < scalingListCount; i++) { + if (readBoolean()) { + // seq_scaling_list_present_flag[ i ] + if (i < 6) { + skipScalingList(16); + } else { + skipScalingList(64); + } + } + } + } + } + + skipUEG(); // log2_max_frame_num_minus4 + + var picOrderCntType = readUEG(); + + if (picOrderCntType === 0) { + readUEG(); // log2_max_pic_order_cnt_lsb_minus4 + } else if (picOrderCntType === 1) { + skipBits(1); // delta_pic_order_always_zero_flag + + skipEG(); // offset_for_non_ref_pic + + skipEG(); // offset_for_top_to_bottom_field + + numRefFramesInPicOrderCntCycle = readUEG(); + + for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) { + skipEG(); + } // offset_for_ref_frame[ i ] + } + + skipUEG(); // max_num_ref_frames + + skipBits(1); // gaps_in_frame_num_value_allowed_flag + + var picWidthInMbsMinus1 = readUEG(); + var picHeightInMapUnitsMinus1 = readUEG(); + var frameMbsOnlyFlag = readBits(1); + + if (frameMbsOnlyFlag === 0) { + skipBits(1); + } // mb_adaptive_frame_field_flag + + skipBits(1); // direct_8x8_inference_flag + + if (readBoolean()) { + // frame_cropping_flag + frameCropLeftOffset = readUEG(); + frameCropRightOffset = readUEG(); + frameCropTopOffset = readUEG(); + frameCropBottomOffset = readUEG(); + } - var pixelRatio = [1, 1]; + var pixelRatio = [1, 1]; - if (readBoolean()) { - // vui_parameters_present_flag - if (readBoolean()) { - // aspect_ratio_info_present_flag - var aspectRatioIdc = readUByte(); + if (readBoolean()) { + // vui_parameters_present_flag + if (readBoolean()) { + // aspect_ratio_info_present_flag + var aspectRatioIdc = readUByte(); - switch (aspectRatioIdc) { - case 1: - pixelRatio = [1, 1]; - break; + switch (aspectRatioIdc) { + case 1: + pixelRatio = [1, 1]; + break; - case 2: - pixelRatio = [12, 11]; - break; + case 2: + pixelRatio = [12, 11]; + break; - case 3: - pixelRatio = [10, 11]; - break; + case 3: + pixelRatio = [10, 11]; + break; - case 4: - pixelRatio = [16, 11]; - break; + case 4: + pixelRatio = [16, 11]; + break; - case 5: - pixelRatio = [40, 33]; - break; + case 5: + pixelRatio = [40, 33]; + break; - case 6: - pixelRatio = [24, 11]; - break; + case 6: + pixelRatio = [24, 11]; + break; - case 7: - pixelRatio = [20, 11]; - break; + case 7: + pixelRatio = [20, 11]; + break; - case 8: - pixelRatio = [32, 11]; - break; + case 8: + pixelRatio = [32, 11]; + break; - case 9: - pixelRatio = [80, 33]; - break; + case 9: + pixelRatio = [80, 33]; + break; - case 10: - pixelRatio = [18, 11]; - break; + case 10: + pixelRatio = [18, 11]; + break; - case 11: - pixelRatio = [15, 11]; - break; + case 11: + pixelRatio = [15, 11]; + break; - case 12: - pixelRatio = [64, 33]; - break; + case 12: + pixelRatio = [64, 33]; + break; - case 13: - pixelRatio = [160, 99]; - break; + case 13: + pixelRatio = [160, 99]; + break; - case 14: - pixelRatio = [4, 3]; - break; + case 14: + pixelRatio = [4, 3]; + break; - case 15: - pixelRatio = [3, 2]; - break; + case 15: + pixelRatio = [3, 2]; + break; - case 16: - pixelRatio = [2, 1]; - break; + case 16: + pixelRatio = [2, 1]; + break; - case 255: - { - pixelRatio = [readUByte() << 8 | readUByte(), readUByte() << 8 | readUByte()]; - break; - } - } - } - } + case 255: { + pixelRatio = [(readUByte() << 8) | readUByte(), (readUByte() << 8) | readUByte()]; + break; + } + } + } + } - return { - width: Math.ceil((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2), - height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset), - pixelRatio: pixelRatio - }; - }; + return { + width: Math.ceil((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2), + height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset), + pixelRatio: pixelRatio, + }; + }; + + _proto.readSliceType = function readSliceType() { + // skip NALu type + this.readUByte(); // discard first_mb_in_slice + + this.readUEG(); // return slice_type + + return this.readUEG(); + }; - _proto.readSliceType = function readSliceType() { - // skip NALu type - this.readUByte(); // discard first_mb_in_slice - - this.readUEG(); // return slice_type - - return this.readUEG(); - }; + return ExpGolomb; + })(); - return ExpGolomb; -}(); + /* harmony default export */ __webpack_exports__["default"] = ExpGolomb; -/* harmony default export */ __webpack_exports__["default"] = (ExpGolomb); - -/***/ }), + /***/ + }, -/***/ "./src/demux/id3.ts": -/*!**************************!*\ + /***/ "./src/demux/id3.ts": + /*!**************************!*\ !*** ./src/demux/id3.ts ***! \**************************/ -/*! exports provided: isHeader, isFooter, getID3Data, canParse, getTimeStamp, isTimeStampFrame, getID3Frames, decodeFrame, utf8ArrayToStr, testables */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: isHeader, isFooter, getID3Data, canParse, getTimeStamp, isTimeStampFrame, getID3Frames, decodeFrame, utf8ArrayToStr, testables */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeader", function () { + return isHeader; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFooter", function () { + return isFooter; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getID3Data", function () { + return getID3Data; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canParse", function () { + return canParse; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getTimeStamp", function () { + return getTimeStamp; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isTimeStampFrame", function () { + return isTimeStampFrame; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getID3Frames", function () { + return getID3Frames; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decodeFrame", function () { + return decodeFrame; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "utf8ArrayToStr", function () { + return utf8ArrayToStr; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "testables", function () { + return testables; + }); + // breaking up those two types in order to clarify what is happening in the decoding path. -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeader", function() { return isHeader; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFooter", function() { return isFooter; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getID3Data", function() { return getID3Data; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canParse", function() { return canParse; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getTimeStamp", function() { return getTimeStamp; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isTimeStampFrame", function() { return isTimeStampFrame; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getID3Frames", function() { return getID3Frames; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decodeFrame", function() { return decodeFrame; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "utf8ArrayToStr", function() { return utf8ArrayToStr; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "testables", function() { return testables; }); -// breaking up those two types in order to clarify what is happening in the decoding path. + /** + * Returns true if an ID3 header can be found at offset in data + * @param {Uint8Array} data - The data to search in + * @param {number} offset - The offset at which to start searching + * @return {boolean} - True if an ID3 header is found + */ + var isHeader = function isHeader(data, offset) { + /* + * http://id3.org/id3v2.3.0 + * [0] = 'I' + * [1] = 'D' + * [2] = '3' + * [3,4] = {Version} + * [5] = {Flags} + * [6-9] = {ID3 Size} + * + * An ID3v2 tag can be detected with the following pattern: + * $49 44 33 yy yy xx zz zz zz zz + * Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80 + */ + if (offset + 10 <= data.length) { + // look for 'ID3' identifier + if (data[offset] === 0x49 && data[offset + 1] === 0x44 && data[offset + 2] === 0x33) { + // check version is within range + if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) { + // check size is within range + if (data[offset + 6] < 0x80 && data[offset + 7] < 0x80 && data[offset + 8] < 0x80 && data[offset + 9] < 0x80) { + return true; + } + } + } + } -/** - * Returns true if an ID3 header can be found at offset in data - * @param {Uint8Array} data - The data to search in - * @param {number} offset - The offset at which to start searching - * @return {boolean} - True if an ID3 header is found - */ -var isHeader = function isHeader(data, offset) { - /* - * http://id3.org/id3v2.3.0 - * [0] = 'I' - * [1] = 'D' - * [2] = '3' - * [3,4] = {Version} - * [5] = {Flags} - * [6-9] = {ID3 Size} - * - * An ID3v2 tag can be detected with the following pattern: - * $49 44 33 yy yy xx zz zz zz zz - * Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80 - */ - if (offset + 10 <= data.length) { - // look for 'ID3' identifier - if (data[offset] === 0x49 && data[offset + 1] === 0x44 && data[offset + 2] === 0x33) { - // check version is within range - if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) { - // check size is within range - if (data[offset + 6] < 0x80 && data[offset + 7] < 0x80 && data[offset + 8] < 0x80 && data[offset + 9] < 0x80) { - return true; - } - } - } - } + return false; + }; + /** + * Returns true if an ID3 footer can be found at offset in data + * @param {Uint8Array} data - The data to search in + * @param {number} offset - The offset at which to start searching + * @return {boolean} - True if an ID3 footer is found + */ - return false; -}; -/** - * Returns true if an ID3 footer can be found at offset in data - * @param {Uint8Array} data - The data to search in - * @param {number} offset - The offset at which to start searching - * @return {boolean} - True if an ID3 footer is found - */ + var isFooter = function isFooter(data, offset) { + /* + * The footer is a copy of the header, but with a different identifier + */ + if (offset + 10 <= data.length) { + // look for '3DI' identifier + if (data[offset] === 0x33 && data[offset + 1] === 0x44 && data[offset + 2] === 0x49) { + // check version is within range + if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) { + // check size is within range + if (data[offset + 6] < 0x80 && data[offset + 7] < 0x80 && data[offset + 8] < 0x80 && data[offset + 9] < 0x80) { + return true; + } + } + } + } -var isFooter = function isFooter(data, offset) { - /* - * The footer is a copy of the header, but with a different identifier - */ - if (offset + 10 <= data.length) { - // look for '3DI' identifier - if (data[offset] === 0x33 && data[offset + 1] === 0x44 && data[offset + 2] === 0x49) { - // check version is within range - if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) { - // check size is within range - if (data[offset + 6] < 0x80 && data[offset + 7] < 0x80 && data[offset + 8] < 0x80 && data[offset + 9] < 0x80) { - return true; - } - } - } - } + return false; + }; + /** + * Returns any adjacent ID3 tags found in data starting at offset, as one block of data + * @param {Uint8Array} data - The data to search in + * @param {number} offset - The offset at which to start searching + * @return {Uint8Array | undefined} - The block of data containing any ID3 tags found + * or *undefined* if no header is found at the starting offset + */ - return false; -}; -/** - * Returns any adjacent ID3 tags found in data starting at offset, as one block of data - * @param {Uint8Array} data - The data to search in - * @param {number} offset - The offset at which to start searching - * @return {Uint8Array | undefined} - The block of data containing any ID3 tags found - * or *undefined* if no header is found at the starting offset - */ + var getID3Data = function getID3Data(data, offset) { + var front = offset; + var length = 0; -var getID3Data = function getID3Data(data, offset) { - var front = offset; - var length = 0; + while (isHeader(data, offset)) { + // ID3 header is 10 bytes + length += 10; + var size = readSize(data, offset + 6); + length += size; - while (isHeader(data, offset)) { - // ID3 header is 10 bytes - length += 10; - var size = readSize(data, offset + 6); - length += size; + if (isFooter(data, offset + 10)) { + // ID3 footer is 10 bytes + length += 10; + } - if (isFooter(data, offset + 10)) { - // ID3 footer is 10 bytes - length += 10; - } + offset += length; + } - offset += length; - } + if (length > 0) { + return data.subarray(front, front + length); + } - if (length > 0) { - return data.subarray(front, front + length); - } + return undefined; + }; - return undefined; -}; + var readSize = function readSize(data, offset) { + var size = 0; + size = (data[offset] & 0x7f) << 21; + size |= (data[offset + 1] & 0x7f) << 14; + size |= (data[offset + 2] & 0x7f) << 7; + size |= data[offset + 3] & 0x7f; + return size; + }; -var readSize = function readSize(data, offset) { - var size = 0; - size = (data[offset] & 0x7f) << 21; - size |= (data[offset + 1] & 0x7f) << 14; - size |= (data[offset + 2] & 0x7f) << 7; - size |= data[offset + 3] & 0x7f; - return size; -}; + var canParse = function canParse(data, offset) { + return isHeader(data, offset) && readSize(data, offset + 6) + 10 <= data.length - offset; + }; + /** + * Searches for the Elementary Stream timestamp found in the ID3 data chunk + * @param {Uint8Array} data - Block of data containing one or more ID3 tags + * @return {number | undefined} - The timestamp + */ -var canParse = function canParse(data, offset) { - return isHeader(data, offset) && readSize(data, offset + 6) + 10 <= data.length - offset; -}; -/** - * Searches for the Elementary Stream timestamp found in the ID3 data chunk - * @param {Uint8Array} data - Block of data containing one or more ID3 tags - * @return {number | undefined} - The timestamp - */ + var getTimeStamp = function getTimeStamp(data) { + var frames = getID3Frames(data); -var getTimeStamp = function getTimeStamp(data) { - var frames = getID3Frames(data); + for (var i = 0; i < frames.length; i++) { + var frame = frames[i]; - for (var i = 0; i < frames.length; i++) { - var frame = frames[i]; + if (isTimeStampFrame(frame)) { + return readTimeStamp(frame); + } + } - if (isTimeStampFrame(frame)) { - return readTimeStamp(frame); - } - } + return undefined; + }; + /** + * Returns true if the ID3 frame is an Elementary Stream timestamp frame + * @param {ID3 frame} frame + */ - return undefined; -}; -/** - * Returns true if the ID3 frame is an Elementary Stream timestamp frame - * @param {ID3 frame} frame - */ + var isTimeStampFrame = function isTimeStampFrame(frame) { + return frame && frame.key === "PRIV" && frame.info === "com.apple.streaming.transportStreamTimestamp"; + }; -var isTimeStampFrame = function isTimeStampFrame(frame) { - return frame && frame.key === 'PRIV' && frame.info === 'com.apple.streaming.transportStreamTimestamp'; -}; - -var getFrameData = function getFrameData(data) { - /* + var getFrameData = function getFrameData(data) { + /* Frame ID $xx xx xx xx (four characters) Size $xx xx xx xx Flags $xx xx */ - var type = String.fromCharCode(data[0], data[1], data[2], data[3]); - var size = readSize(data, 4); // skip frame id, size, and flags + var type = String.fromCharCode(data[0], data[1], data[2], data[3]); + var size = readSize(data, 4); // skip frame id, size, and flags - var offset = 10; - return { - type: type, - size: size, - data: data.subarray(offset, offset + size) - }; -}; -/** - * Returns an array of ID3 frames found in all the ID3 tags in the id3Data - * @param {Uint8Array} id3Data - The ID3 data containing one or more ID3 tags - * @return {ID3.Frame[]} - Array of ID3 frame objects - */ + var offset = 10; + return { + type: type, + size: size, + data: data.subarray(offset, offset + size), + }; + }; + /** + * Returns an array of ID3 frames found in all the ID3 tags in the id3Data + * @param {Uint8Array} id3Data - The ID3 data containing one or more ID3 tags + * @return {ID3.Frame[]} - Array of ID3 frame objects + */ + var getID3Frames = function getID3Frames(id3Data) { + var offset = 0; + var frames = []; -var getID3Frames = function getID3Frames(id3Data) { - var offset = 0; - var frames = []; + while (isHeader(id3Data, offset)) { + var size = readSize(id3Data, offset + 6); // skip past ID3 header - while (isHeader(id3Data, offset)) { - var size = readSize(id3Data, offset + 6); // skip past ID3 header + offset += 10; + var end = offset + size; // loop through frames in the ID3 tag - offset += 10; - var end = offset + size; // loop through frames in the ID3 tag + while (offset + 8 < end) { + var frameData = getFrameData(id3Data.subarray(offset)); + var frame = decodeFrame(frameData); - while (offset + 8 < end) { - var frameData = getFrameData(id3Data.subarray(offset)); - var frame = decodeFrame(frameData); + if (frame) { + frames.push(frame); + } // skip frame header and frame data - if (frame) { - frames.push(frame); - } // skip frame header and frame data + offset += frameData.size + 10; + } + if (isFooter(id3Data, offset)) { + offset += 10; + } + } - offset += frameData.size + 10; - } + return frames; + }; + var decodeFrame = function decodeFrame(frame) { + if (frame.type === "PRIV") { + return decodePrivFrame(frame); + } else if (frame.type[0] === "W") { + return decodeURLFrame(frame); + } - if (isFooter(id3Data, offset)) { - offset += 10; - } - } + return decodeTextFrame(frame); + }; - return frames; -}; -var decodeFrame = function decodeFrame(frame) { - if (frame.type === 'PRIV') { - return decodePrivFrame(frame); - } else if (frame.type[0] === 'W') { - return decodeURLFrame(frame); - } - - return decodeTextFrame(frame); -}; - -var decodePrivFrame = function decodePrivFrame(frame) { - /* + var decodePrivFrame = function decodePrivFrame(frame) { + /* Format: \0 */ - if (frame.size < 2) { - return undefined; - } + if (frame.size < 2) { + return undefined; + } - var owner = utf8ArrayToStr(frame.data, true); - var privateData = new Uint8Array(frame.data.subarray(owner.length + 1)); - return { - key: frame.type, - info: owner, - data: privateData.buffer - }; -}; + var owner = utf8ArrayToStr(frame.data, true); + var privateData = new Uint8Array(frame.data.subarray(owner.length + 1)); + return { + key: frame.type, + info: owner, + data: privateData.buffer, + }; + }; -var decodeTextFrame = function decodeTextFrame(frame) { - if (frame.size < 2) { - return undefined; - } + var decodeTextFrame = function decodeTextFrame(frame) { + if (frame.size < 2) { + return undefined; + } - if (frame.type === 'TXXX') { - /* + if (frame.type === "TXXX") { + /* Format: [0] = {Text Encoding} [1-?] = {Description}\0{Value} */ - var index = 1; - var description = utf8ArrayToStr(frame.data.subarray(index), true); - index += description.length + 1; - var value = utf8ArrayToStr(frame.data.subarray(index)); - return { - key: frame.type, - info: description, - data: value - }; - } - /* + var index = 1; + var description = utf8ArrayToStr(frame.data.subarray(index), true); + index += description.length + 1; + var value = utf8ArrayToStr(frame.data.subarray(index)); + return { + key: frame.type, + info: description, + data: value, + }; + } + /* Format: [0] = {Text Encoding} [1-?] = {Value} */ + var text = utf8ArrayToStr(frame.data.subarray(1)); + return { + key: frame.type, + data: text, + }; + }; - var text = utf8ArrayToStr(frame.data.subarray(1)); - return { - key: frame.type, - data: text - }; -}; - -var decodeURLFrame = function decodeURLFrame(frame) { - if (frame.type === 'WXXX') { - /* + var decodeURLFrame = function decodeURLFrame(frame) { + if (frame.type === "WXXX") { + /* Format: [0] = {Text Encoding} [1-?] = {Description}\0{URL} */ - if (frame.size < 2) { - return undefined; - } + if (frame.size < 2) { + return undefined; + } - var index = 1; - var description = utf8ArrayToStr(frame.data.subarray(index), true); - index += description.length + 1; - var value = utf8ArrayToStr(frame.data.subarray(index)); - return { - key: frame.type, - info: description, - data: value - }; - } - /* + var index = 1; + var description = utf8ArrayToStr(frame.data.subarray(index), true); + index += description.length + 1; + var value = utf8ArrayToStr(frame.data.subarray(index)); + return { + key: frame.type, + info: description, + data: value, + }; + } + /* Format: [0-?] = {URL} */ + var url = utf8ArrayToStr(frame.data); + return { + key: frame.type, + data: url, + }; + }; - var url = utf8ArrayToStr(frame.data); - return { - key: frame.type, - data: url - }; -}; + var readTimeStamp = function readTimeStamp(timeStampFrame) { + if (timeStampFrame.data.byteLength === 8) { + var data = new Uint8Array(timeStampFrame.data); // timestamp is 33 bit expressed as a big-endian eight-octet number, + // with the upper 31 bits set to zero. -var readTimeStamp = function readTimeStamp(timeStampFrame) { - if (timeStampFrame.data.byteLength === 8) { - var data = new Uint8Array(timeStampFrame.data); // timestamp is 33 bit expressed as a big-endian eight-octet number, - // with the upper 31 bits set to zero. + var pts33Bit = data[3] & 0x1; + var timestamp = (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7]; + timestamp /= 45; - var pts33Bit = data[3] & 0x1; - var timestamp = (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7]; - timestamp /= 45; + if (pts33Bit) { + timestamp += 47721858.84; + } // 2^32 / 90 - if (pts33Bit) { - timestamp += 47721858.84; - } // 2^32 / 90 + return Math.round(timestamp); + } + return undefined; + }; // http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197 + // http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt - return Math.round(timestamp); - } + /* utf.js - UTF-8 <=> UTF-16 convertion + * + * Copyright (C) 1999 Masanao Izumo + * Version: 1.0 + * LastModified: Dec 25 1999 + * This library is free. You can redistribute it and/or modify it. + */ - return undefined; -}; // http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197 -// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt + var utf8ArrayToStr = function utf8ArrayToStr(array, exitOnNull) { + if (exitOnNull === void 0) { + exitOnNull = false; + } -/* utf.js - UTF-8 <=> UTF-16 convertion - * - * Copyright (C) 1999 Masanao Izumo - * Version: 1.0 - * LastModified: Dec 25 1999 - * This library is free. You can redistribute it and/or modify it. - */ + var decoder = getTextDecoder(); + if (decoder) { + var decoded = decoder.decode(array); -var utf8ArrayToStr = function utf8ArrayToStr(array, exitOnNull) { - if (exitOnNull === void 0) { - exitOnNull = false; - } + if (exitOnNull) { + // grab up to the first null + var idx = decoded.indexOf("\0"); + return idx !== -1 ? decoded.substring(0, idx) : decoded; + } // remove any null characters - var decoder = getTextDecoder(); + return decoded.replace(/\0/g, ""); + } - if (decoder) { - var decoded = decoder.decode(array); + var len = array.length; + var c; + var char2; + var char3; + var out = ""; + var i = 0; - if (exitOnNull) { - // grab up to the first null - var idx = decoded.indexOf('\0'); - return idx !== -1 ? decoded.substring(0, idx) : decoded; - } // remove any null characters + while (i < len) { + c = array[i++]; + if (c === 0x00 && exitOnNull) { + return out; + } else if (c === 0x00 || c === 0x03) { + // If the character is 3 (END_OF_TEXT) or 0 (NULL) then skip it + continue; + } - return decoded.replace(/\0/g, ''); - } + switch (c >> 4) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + // 0xxxxxxx + out += String.fromCharCode(c); + break; - var len = array.length; - var c; - var char2; - var char3; - var out = ''; - var i = 0; + case 12: + case 13: + // 110x xxxx 10xx xxxx + char2 = array[i++]; + out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f)); + break; - while (i < len) { - c = array[i++]; + case 14: + // 1110 xxxx 10xx xxxx 10xx xxxx + char2 = array[i++]; + char3 = array[i++]; + out += String.fromCharCode(((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)); + break; - if (c === 0x00 && exitOnNull) { - return out; - } else if (c === 0x00 || c === 0x03) { - // If the character is 3 (END_OF_TEXT) or 0 (NULL) then skip it - continue; - } + default: + } + } - switch (c >> 4) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - // 0xxxxxxx - out += String.fromCharCode(c); - break; + return out; + }; + var testables = { + decodeTextFrame: decodeTextFrame, + }; + var decoder; - case 12: - case 13: - // 110x xxxx 10xx xxxx - char2 = array[i++]; - out += String.fromCharCode((c & 0x1f) << 6 | char2 & 0x3f); - break; + function getTextDecoder() { + if (!decoder && typeof self.TextDecoder !== "undefined") { + decoder = new self.TextDecoder("utf-8"); + } - case 14: - // 1110 xxxx 10xx xxxx 10xx xxxx - char2 = array[i++]; - char3 = array[i++]; - out += String.fromCharCode((c & 0x0f) << 12 | (char2 & 0x3f) << 6 | (char3 & 0x3f) << 0); - break; + return decoder; + } - default: - } - } + /***/ + }, - return out; -}; -var testables = { - decodeTextFrame: decodeTextFrame -}; -var decoder; - -function getTextDecoder() { - if (!decoder && typeof self.TextDecoder !== 'undefined') { - decoder = new self.TextDecoder('utf-8'); - } - - return decoder; -} - -/***/ }), - -/***/ "./src/demux/mp3demuxer.ts": -/*!*********************************!*\ + /***/ "./src/demux/mp3demuxer.ts": + /*!*********************************!*\ !*** ./src/demux/mp3demuxer.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-audio-demuxer */ "./src/demux/base-audio-demuxer.ts"); + /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _mpegaudio__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mpegaudio */ "./src/demux/mpegaudio.ts"); + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-audio-demuxer */ "./src/demux/base-audio-demuxer.ts"); -/* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _mpegaudio__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mpegaudio */ "./src/demux/mpegaudio.ts"); -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + /** + * MP3 demuxer + */ -/** - * MP3 demuxer - */ + var MP3Demuxer = /*#__PURE__*/ (function (_BaseAudioDemuxer) { + _inheritsLoose(MP3Demuxer, _BaseAudioDemuxer); + function MP3Demuxer() { + return _BaseAudioDemuxer.apply(this, arguments) || this; + } + var _proto = MP3Demuxer.prototype; + _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { + _BaseAudioDemuxer.prototype.resetInitSegment.call(this, audioCodec, videoCodec, duration); + this._audioTrack = { + container: "audio/mpeg", + type: "audio", + id: 2, + pid: -1, + sequenceNumber: 0, + isAAC: false, + samples: [], + manifestCodec: audioCodec, + duration: duration, + inputTimeScale: 90000, + dropped: 0, + }; + }; -var MP3Demuxer = /*#__PURE__*/function (_BaseAudioDemuxer) { - _inheritsLoose(MP3Demuxer, _BaseAudioDemuxer); + MP3Demuxer.probe = function probe(data) { + if (!data) { + return false; + } // check if data contains ID3 timestamp and MPEG sync word + // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1 + // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III) + // More info http://www.mp3-tech.org/programmer/frame_header.html - function MP3Demuxer() { - return _BaseAudioDemuxer.apply(this, arguments) || this; - } + var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getID3Data"](data, 0) || []; + var offset = id3Data.length; - var _proto = MP3Demuxer.prototype; + for (var length = data.length; offset < length; offset++) { + if (_mpegaudio__WEBPACK_IMPORTED_MODULE_3__["probe"](data, offset)) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log("MPEG Audio sync word found !"); + return true; + } + } - _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { - _BaseAudioDemuxer.prototype.resetInitSegment.call(this, audioCodec, videoCodec, duration); + return false; + }; - this._audioTrack = { - container: 'audio/mpeg', - type: 'audio', - id: 2, - pid: -1, - sequenceNumber: 0, - isAAC: false, - samples: [], - manifestCodec: audioCodec, - duration: duration, - inputTimeScale: 90000, - dropped: 0 - }; - }; + _proto.canParse = function canParse(data, offset) { + return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__["canParse"](data, offset); + }; - MP3Demuxer.probe = function probe(data) { - if (!data) { - return false; - } // check if data contains ID3 timestamp and MPEG sync word - // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1 - // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III) - // More info http://www.mp3-tech.org/programmer/frame_header.html + _proto.appendFrame = function appendFrame(track, data, offset) { + if (this.initPTS === null) { + return; + } + return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__["appendFrame"](track, data, offset, this.initPTS, this.frameIndex); + }; - var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__["getID3Data"](data, 0) || []; - var offset = id3Data.length; + return MP3Demuxer; + })(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]); - for (var length = data.length; offset < length; offset++) { - if (_mpegaudio__WEBPACK_IMPORTED_MODULE_3__["probe"](data, offset)) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].log('MPEG Audio sync word found !'); - return true; - } - } + MP3Demuxer.minProbeByteLength = 4; + /* harmony default export */ __webpack_exports__["default"] = MP3Demuxer; - return false; - }; + /***/ + }, - _proto.canParse = function canParse(data, offset) { - return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__["canParse"](data, offset); - }; - - _proto.appendFrame = function appendFrame(track, data, offset) { - if (this.initPTS === null) { - return; - } - - return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__["appendFrame"](track, data, offset, this.initPTS, this.frameIndex); - }; - - return MP3Demuxer; -}(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]); - -MP3Demuxer.minProbeByteLength = 4; -/* harmony default export */ __webpack_exports__["default"] = (MP3Demuxer); - -/***/ }), - -/***/ "./src/demux/mp4demuxer.ts": -/*!*********************************!*\ + /***/ "./src/demux/mp4demuxer.ts": + /*!*********************************!*\ !*** ./src/demux/mp4demuxer.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dummy-demuxed-track */ "./src/demux/dummy-demuxed-track.ts"); + /** + * MP4 demuxer + */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dummy-demuxed-track */ "./src/demux/dummy-demuxed-track.ts"); -/** - * MP4 demuxer - */ + var MP4Demuxer = /*#__PURE__*/ (function () { + function MP4Demuxer(observer, config) { + this.remainderData = null; + this.config = void 0; + this.config = config; + } + var _proto = MP4Demuxer.prototype; + _proto.resetTimeStamp = function resetTimeStamp() {}; -var MP4Demuxer = /*#__PURE__*/function () { - function MP4Demuxer(observer, config) { - this.remainderData = null; - this.config = void 0; - this.config = config; - } + _proto.resetInitSegment = function resetInitSegment() {}; - var _proto = MP4Demuxer.prototype; + _proto.resetContiguity = function resetContiguity() {}; - _proto.resetTimeStamp = function resetTimeStamp() {}; + MP4Demuxer.probe = function probe(data) { + // ensure we find a moof box in the first 16 kB + return ( + Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["findBox"])( + { + data: data, + start: 0, + end: Math.min(data.length, 16384), + }, + ["moof"] + ).length > 0 + ); + }; - _proto.resetInitSegment = function resetInitSegment() {}; + _proto.demux = function demux(data) { + // Load all data into the avc track. The CMAF remuxer will look for the data in the samples object; the rest of the fields do not matter + var avcSamples = data; + var avcTrack = Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(); - _proto.resetContiguity = function resetContiguity() {}; + if (this.config.progressive) { + // Split the bytestream into two ranges: one encompassing all data up until the start of the last moof, and everything else. + // This is done to guarantee that we're sending valid data to MSE - when demuxing progressively, we have no guarantee + // that the fetch loader gives us flush moof+mdat pairs. If we push jagged data to MSE, it will throw an exception. + if (this.remainderData) { + avcSamples = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["appendUint8Array"])(this.remainderData, data); + } - MP4Demuxer.probe = function probe(data) { - // ensure we find a moof box in the first 16 kB - return Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["findBox"])({ - data: data, - start: 0, - end: Math.min(data.length, 16384) - }, ['moof']).length > 0; - }; + var segmentedData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["segmentValidRange"])(avcSamples); + this.remainderData = segmentedData.remainder; + avcTrack.samples = segmentedData.valid || new Uint8Array(); + } else { + avcTrack.samples = avcSamples; + } - _proto.demux = function demux(data) { - // Load all data into the avc track. The CMAF remuxer will look for the data in the samples object; the rest of the fields do not matter - var avcSamples = data; - var avcTrack = Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(); + return { + audioTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), + avcTrack: avcTrack, + id3Track: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), + textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), + }; + }; - if (this.config.progressive) { - // Split the bytestream into two ranges: one encompassing all data up until the start of the last moof, and everything else. - // This is done to guarantee that we're sending valid data to MSE - when demuxing progressively, we have no guarantee - // that the fetch loader gives us flush moof+mdat pairs. If we push jagged data to MSE, it will throw an exception. - if (this.remainderData) { - avcSamples = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["appendUint8Array"])(this.remainderData, data); - } + _proto.flush = function flush() { + var avcTrack = Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(); + avcTrack.samples = this.remainderData || new Uint8Array(); + this.remainderData = null; + return { + audioTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), + avcTrack: avcTrack, + id3Track: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), + textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), + }; + }; - var segmentedData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["segmentValidRange"])(avcSamples); - this.remainderData = segmentedData.remainder; - avcTrack.samples = segmentedData.valid || new Uint8Array(); - } else { - avcTrack.samples = avcSamples; - } + _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) { + return Promise.reject(new Error("The MP4 demuxer does not support SAMPLE-AES decryption")); + }; - return { - audioTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), - avcTrack: avcTrack, - id3Track: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), - textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])() - }; - }; + _proto.destroy = function destroy() {}; - _proto.flush = function flush() { - var avcTrack = Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(); - avcTrack.samples = this.remainderData || new Uint8Array(); - this.remainderData = null; - return { - audioTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), - avcTrack: avcTrack, - id3Track: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])(), - textTrack: Object(_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_1__["dummyTrack"])() - }; - }; + return MP4Demuxer; + })(); - _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) { - return Promise.reject(new Error('The MP4 demuxer does not support SAMPLE-AES decryption')); - }; + MP4Demuxer.minProbeByteLength = 1024; + /* harmony default export */ __webpack_exports__["default"] = MP4Demuxer; - _proto.destroy = function destroy() {}; + /***/ + }, - return MP4Demuxer; -}(); - -MP4Demuxer.minProbeByteLength = 1024; -/* harmony default export */ __webpack_exports__["default"] = (MP4Demuxer); - -/***/ }), - -/***/ "./src/demux/mpegaudio.ts": -/*!********************************!*\ + /***/ "./src/demux/mpegaudio.ts": + /*!********************************!*\ !*** ./src/demux/mpegaudio.ts ***! \********************************/ -/*! exports provided: appendFrame, parseHeader, isHeaderPattern, isHeader, canParse, probe */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: appendFrame, parseHeader, isHeaderPattern, isHeader, canParse, probe */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "appendFrame", function () { + return appendFrame; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseHeader", function () { + return parseHeader; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeaderPattern", function () { + return isHeaderPattern; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeader", function () { + return isHeader; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canParse", function () { + return canParse; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "probe", function () { + return probe; + }); + /** + * MPEG parser helper + */ + var chromeVersion = null; + var BitratesMap = [ + 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 144, 160, + ]; + var SamplingRateMap = [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000]; + var SamplesCoefficients = [ + // MPEG 2.5 + [ + 0, // Reserved + 72, // Layer3 + 144, // Layer2 + 12, // Layer1 + ], // Reserved + [ + 0, // Reserved + 0, // Layer3 + 0, // Layer2 + 0, // Layer1 + ], // MPEG 2 + [ + 0, // Reserved + 72, // Layer3 + 144, // Layer2 + 12, // Layer1 + ], // MPEG 1 + [ + 0, // Reserved + 144, // Layer3 + 144, // Layer2 + 12, // Layer1 + ], + ]; + var BytesInSlot = [ + 0, // Reserved + 1, // Layer3 + 1, // Layer2 + 4, // Layer1 + ]; + function appendFrame(track, data, offset, pts, frameIndex) { + // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference + if (offset + 24 > data.length) { + return; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "appendFrame", function() { return appendFrame; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseHeader", function() { return parseHeader; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeaderPattern", function() { return isHeaderPattern; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeader", function() { return isHeader; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canParse", function() { return canParse; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "probe", function() { return probe; }); -/** - * MPEG parser helper - */ -var chromeVersion = null; -var BitratesMap = [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160]; -var SamplingRateMap = [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000]; -var SamplesCoefficients = [// MPEG 2.5 -[0, // Reserved -72, // Layer3 -144, // Layer2 -12 // Layer1 -], // Reserved -[0, // Reserved -0, // Layer3 -0, // Layer2 -0 // Layer1 -], // MPEG 2 -[0, // Reserved -72, // Layer3 -144, // Layer2 -12 // Layer1 -], // MPEG 1 -[0, // Reserved -144, // Layer3 -144, // Layer2 -12 // Layer1 -]]; -var BytesInSlot = [0, // Reserved -1, // Layer3 -1, // Layer2 -4 // Layer1 -]; -function appendFrame(track, data, offset, pts, frameIndex) { - // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference - if (offset + 24 > data.length) { - return; - } + var header = parseHeader(data, offset); - var header = parseHeader(data, offset); + if (header && offset + header.frameLength <= data.length) { + var frameDuration = (header.samplesPerFrame * 90000) / header.sampleRate; + var stamp = pts + frameIndex * frameDuration; + var sample = { + unit: data.subarray(offset, offset + header.frameLength), + pts: stamp, + dts: stamp, + }; + track.config = []; + track.channelCount = header.channelCount; + track.samplerate = header.sampleRate; + track.samples.push(sample); + return { + sample: sample, + length: header.frameLength, + missing: 0, + }; + } + } + function parseHeader(data, offset) { + var mpegVersion = (data[offset + 1] >> 3) & 3; + var mpegLayer = (data[offset + 1] >> 1) & 3; + var bitRateIndex = (data[offset + 2] >> 4) & 15; + var sampleRateIndex = (data[offset + 2] >> 2) & 3; - if (header && offset + header.frameLength <= data.length) { - var frameDuration = header.samplesPerFrame * 90000 / header.sampleRate; - var stamp = pts + frameIndex * frameDuration; - var sample = { - unit: data.subarray(offset, offset + header.frameLength), - pts: stamp, - dts: stamp - }; - track.config = []; - track.channelCount = header.channelCount; - track.samplerate = header.sampleRate; - track.samples.push(sample); - return { - sample: sample, - length: header.frameLength, - missing: 0 - }; - } -} -function parseHeader(data, offset) { - var mpegVersion = data[offset + 1] >> 3 & 3; - var mpegLayer = data[offset + 1] >> 1 & 3; - var bitRateIndex = data[offset + 2] >> 4 & 15; - var sampleRateIndex = data[offset + 2] >> 2 & 3; + if (mpegVersion !== 1 && bitRateIndex !== 0 && bitRateIndex !== 15 && sampleRateIndex !== 3) { + var paddingBit = (data[offset + 2] >> 1) & 1; + var channelMode = data[offset + 3] >> 6; + var columnInBitrates = mpegVersion === 3 ? 3 - mpegLayer : mpegLayer === 3 ? 3 : 4; + var bitRate = BitratesMap[columnInBitrates * 14 + bitRateIndex - 1] * 1000; + var columnInSampleRates = mpegVersion === 3 ? 0 : mpegVersion === 2 ? 1 : 2; + var sampleRate = SamplingRateMap[columnInSampleRates * 3 + sampleRateIndex]; + var channelCount = channelMode === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono) - if (mpegVersion !== 1 && bitRateIndex !== 0 && bitRateIndex !== 15 && sampleRateIndex !== 3) { - var paddingBit = data[offset + 2] >> 1 & 1; - var channelMode = data[offset + 3] >> 6; - var columnInBitrates = mpegVersion === 3 ? 3 - mpegLayer : mpegLayer === 3 ? 3 : 4; - var bitRate = BitratesMap[columnInBitrates * 14 + bitRateIndex - 1] * 1000; - var columnInSampleRates = mpegVersion === 3 ? 0 : mpegVersion === 2 ? 1 : 2; - var sampleRate = SamplingRateMap[columnInSampleRates * 3 + sampleRateIndex]; - var channelCount = channelMode === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono) + var sampleCoefficient = SamplesCoefficients[mpegVersion][mpegLayer]; + var bytesInSlot = BytesInSlot[mpegLayer]; + var samplesPerFrame = sampleCoefficient * 8 * bytesInSlot; + var frameLength = Math.floor((sampleCoefficient * bitRate) / sampleRate + paddingBit) * bytesInSlot; - var sampleCoefficient = SamplesCoefficients[mpegVersion][mpegLayer]; - var bytesInSlot = BytesInSlot[mpegLayer]; - var samplesPerFrame = sampleCoefficient * 8 * bytesInSlot; - var frameLength = Math.floor(sampleCoefficient * bitRate / sampleRate + paddingBit) * bytesInSlot; + if (chromeVersion === null) { + var userAgent = navigator.userAgent || ""; + var result = userAgent.match(/Chrome\/(\d+)/i); + chromeVersion = result ? parseInt(result[1]) : 0; + } - if (chromeVersion === null) { - var userAgent = navigator.userAgent || ''; - var result = userAgent.match(/Chrome\/(\d+)/i); - chromeVersion = result ? parseInt(result[1]) : 0; - } + var needChromeFix = !!chromeVersion && chromeVersion <= 87; - var needChromeFix = !!chromeVersion && chromeVersion <= 87; + if (needChromeFix && mpegLayer === 2 && bitRate >= 224000 && channelMode === 0) { + // Work around bug in Chromium by setting channelMode to dual-channel (01) instead of stereo (00) + data[offset + 3] = data[offset + 3] | 0x80; + } - if (needChromeFix && mpegLayer === 2 && bitRate >= 224000 && channelMode === 0) { - // Work around bug in Chromium by setting channelMode to dual-channel (01) instead of stereo (00) - data[offset + 3] = data[offset + 3] | 0x80; - } + return { + sampleRate: sampleRate, + channelCount: channelCount, + frameLength: frameLength, + samplesPerFrame: samplesPerFrame, + }; + } + } + function isHeaderPattern(data, offset) { + return data[offset] === 0xff && (data[offset + 1] & 0xe0) === 0xe0 && (data[offset + 1] & 0x06) !== 0x00; + } + function isHeader(data, offset) { + // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1 + // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III) + // More info http://www.mp3-tech.org/programmer/frame_header.html + return offset + 1 < data.length && isHeaderPattern(data, offset); + } + function canParse(data, offset) { + var headerSize = 4; + return isHeaderPattern(data, offset) && headerSize <= data.length - offset; + } + function probe(data, offset) { + // same as isHeader but we also check that MPEG frame follows last MPEG frame + // or end of data is reached + if (offset + 1 < data.length && isHeaderPattern(data, offset)) { + // MPEG header Length + var headerLength = 4; // MPEG frame Length - return { - sampleRate: sampleRate, - channelCount: channelCount, - frameLength: frameLength, - samplesPerFrame: samplesPerFrame - }; - } -} -function isHeaderPattern(data, offset) { - return data[offset] === 0xff && (data[offset + 1] & 0xe0) === 0xe0 && (data[offset + 1] & 0x06) !== 0x00; -} -function isHeader(data, offset) { - // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1 - // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III) - // More info http://www.mp3-tech.org/programmer/frame_header.html - return offset + 1 < data.length && isHeaderPattern(data, offset); -} -function canParse(data, offset) { - var headerSize = 4; - return isHeaderPattern(data, offset) && headerSize <= data.length - offset; -} -function probe(data, offset) { - // same as isHeader but we also check that MPEG frame follows last MPEG frame - // or end of data is reached - if (offset + 1 < data.length && isHeaderPattern(data, offset)) { - // MPEG header Length - var headerLength = 4; // MPEG frame Length + var header = parseHeader(data, offset); + var frameLength = headerLength; - var header = parseHeader(data, offset); - var frameLength = headerLength; + if (header !== null && header !== void 0 && header.frameLength) { + frameLength = header.frameLength; + } - if (header !== null && header !== void 0 && header.frameLength) { - frameLength = header.frameLength; - } + var newOffset = offset + frameLength; + return newOffset === data.length || isHeader(data, newOffset); + } - var newOffset = offset + frameLength; - return newOffset === data.length || isHeader(data, newOffset); - } + return false; + } - return false; -} + /***/ + }, -/***/ }), - -/***/ "./src/demux/sample-aes.ts": -/*!*********************************!*\ + /***/ "./src/demux/sample-aes.ts": + /*!*********************************!*\ !*** ./src/demux/sample-aes.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts"); + /* harmony import */ var _tsdemuxer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tsdemuxer */ "./src/demux/tsdemuxer.ts"); + /** + * SAMPLE-AES decrypter + */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts"); -/* harmony import */ var _tsdemuxer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tsdemuxer */ "./src/demux/tsdemuxer.ts"); -/** - * SAMPLE-AES decrypter - */ + var SampleAesDecrypter = /*#__PURE__*/ (function () { + function SampleAesDecrypter(observer, config, keyData) { + this.keyData = void 0; + this.decrypter = void 0; + this.keyData = keyData; + this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__["default"](observer, config, { + removePKCS7Padding: false, + }); + } + var _proto = SampleAesDecrypter.prototype; + _proto.decryptBuffer = function decryptBuffer(encryptedData, callback) { + this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer, callback); + }; // AAC - encrypt all full 16 bytes blocks starting from offset 16 -var SampleAesDecrypter = /*#__PURE__*/function () { - function SampleAesDecrypter(observer, config, keyData) { - this.keyData = void 0; - this.decrypter = void 0; - this.keyData = keyData; - this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__["default"](observer, config, { - removePKCS7Padding: false - }); - } + _proto.decryptAacSample = function decryptAacSample(samples, sampleIndex, callback, sync) { + var curUnit = samples[sampleIndex].unit; + var encryptedData = curUnit.subarray(16, curUnit.length - (curUnit.length % 16)); + var encryptedBuffer = encryptedData.buffer.slice(encryptedData.byteOffset, encryptedData.byteOffset + encryptedData.length); + var localthis = this; + this.decryptBuffer(encryptedBuffer, function (decryptedBuffer) { + var decryptedData = new Uint8Array(decryptedBuffer); + curUnit.set(decryptedData, 16); - var _proto = SampleAesDecrypter.prototype; + if (!sync) { + localthis.decryptAacSamples(samples, sampleIndex + 1, callback); + } + }); + }; - _proto.decryptBuffer = function decryptBuffer(encryptedData, callback) { - this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer, callback); - } // AAC - encrypt all full 16 bytes blocks starting from offset 16 - ; + _proto.decryptAacSamples = function decryptAacSamples(samples, sampleIndex, callback) { + for (; ; sampleIndex++) { + if (sampleIndex >= samples.length) { + callback(); + return; + } - _proto.decryptAacSample = function decryptAacSample(samples, sampleIndex, callback, sync) { - var curUnit = samples[sampleIndex].unit; - var encryptedData = curUnit.subarray(16, curUnit.length - curUnit.length % 16); - var encryptedBuffer = encryptedData.buffer.slice(encryptedData.byteOffset, encryptedData.byteOffset + encryptedData.length); - var localthis = this; - this.decryptBuffer(encryptedBuffer, function (decryptedBuffer) { - var decryptedData = new Uint8Array(decryptedBuffer); - curUnit.set(decryptedData, 16); + if (samples[sampleIndex].unit.length < 32) { + continue; + } - if (!sync) { - localthis.decryptAacSamples(samples, sampleIndex + 1, callback); - } - }); - }; + var sync = this.decrypter.isSync(); + this.decryptAacSample(samples, sampleIndex, callback, sync); - _proto.decryptAacSamples = function decryptAacSamples(samples, sampleIndex, callback) { - for (;; sampleIndex++) { - if (sampleIndex >= samples.length) { - callback(); - return; - } + if (!sync) { + return; + } + } + }; // AVC - encrypt one 16 bytes block out of ten, starting from offset 32 - if (samples[sampleIndex].unit.length < 32) { - continue; - } + _proto.getAvcEncryptedData = function getAvcEncryptedData(decodedData) { + var encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16; + var encryptedData = new Int8Array(encryptedDataLen); + var outputPos = 0; - var sync = this.decrypter.isSync(); - this.decryptAacSample(samples, sampleIndex, callback, sync); + for (var inputPos = 32; inputPos <= decodedData.length - 16; inputPos += 160, outputPos += 16) { + encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos); + } - if (!sync) { - return; - } - } - } // AVC - encrypt one 16 bytes block out of ten, starting from offset 32 - ; + return encryptedData; + }; - _proto.getAvcEncryptedData = function getAvcEncryptedData(decodedData) { - var encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16; - var encryptedData = new Int8Array(encryptedDataLen); - var outputPos = 0; + _proto.getAvcDecryptedUnit = function getAvcDecryptedUnit(decodedData, decryptedData) { + var uint8DecryptedData = new Uint8Array(decryptedData); + var inputPos = 0; - for (var inputPos = 32; inputPos <= decodedData.length - 16; inputPos += 160, outputPos += 16) { - encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos); - } + for (var outputPos = 32; outputPos <= decodedData.length - 16; outputPos += 160, inputPos += 16) { + decodedData.set(uint8DecryptedData.subarray(inputPos, inputPos + 16), outputPos); + } - return encryptedData; - }; + return decodedData; + }; - _proto.getAvcDecryptedUnit = function getAvcDecryptedUnit(decodedData, decryptedData) { - var uint8DecryptedData = new Uint8Array(decryptedData); - var inputPos = 0; + _proto.decryptAvcSample = function decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync) { + var decodedData = Object(_tsdemuxer__WEBPACK_IMPORTED_MODULE_1__["discardEPB"])(curUnit.data); + var encryptedData = this.getAvcEncryptedData(decodedData); + var localthis = this; + this.decryptBuffer(encryptedData.buffer, function (decryptedBuffer) { + curUnit.data = localthis.getAvcDecryptedUnit(decodedData, decryptedBuffer); - for (var outputPos = 32; outputPos <= decodedData.length - 16; outputPos += 160, inputPos += 16) { - decodedData.set(uint8DecryptedData.subarray(inputPos, inputPos + 16), outputPos); - } + if (!sync) { + localthis.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback); + } + }); + }; - return decodedData; - }; + _proto.decryptAvcSamples = function decryptAvcSamples(samples, sampleIndex, unitIndex, callback) { + if (samples instanceof Uint8Array) { + throw new Error("Cannot decrypt samples of type Uint8Array"); + } - _proto.decryptAvcSample = function decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync) { - var decodedData = Object(_tsdemuxer__WEBPACK_IMPORTED_MODULE_1__["discardEPB"])(curUnit.data); - var encryptedData = this.getAvcEncryptedData(decodedData); - var localthis = this; - this.decryptBuffer(encryptedData.buffer, function (decryptedBuffer) { - curUnit.data = localthis.getAvcDecryptedUnit(decodedData, decryptedBuffer); + for (; ; sampleIndex++, unitIndex = 0) { + if (sampleIndex >= samples.length) { + callback(); + return; + } - if (!sync) { - localthis.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback); - } - }); - }; + var curUnits = samples[sampleIndex].units; - _proto.decryptAvcSamples = function decryptAvcSamples(samples, sampleIndex, unitIndex, callback) { - if (samples instanceof Uint8Array) { - throw new Error('Cannot decrypt samples of type Uint8Array'); - } + for (; ; unitIndex++) { + if (unitIndex >= curUnits.length) { + break; + } - for (;; sampleIndex++, unitIndex = 0) { - if (sampleIndex >= samples.length) { - callback(); - return; - } + var curUnit = curUnits[unitIndex]; - var curUnits = samples[sampleIndex].units; + if (curUnit.data.length <= 48 || (curUnit.type !== 1 && curUnit.type !== 5)) { + continue; + } - for (;; unitIndex++) { - if (unitIndex >= curUnits.length) { - break; - } + var sync = this.decrypter.isSync(); + this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync); - var curUnit = curUnits[unitIndex]; + if (!sync) { + return; + } + } + } + }; - if (curUnit.data.length <= 48 || curUnit.type !== 1 && curUnit.type !== 5) { - continue; - } + return SampleAesDecrypter; + })(); - var sync = this.decrypter.isSync(); - this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync); + /* harmony default export */ __webpack_exports__["default"] = SampleAesDecrypter; - if (!sync) { - return; - } - } - } - }; + /***/ + }, - return SampleAesDecrypter; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (SampleAesDecrypter); - -/***/ }), - -/***/ "./src/demux/transmuxer-interface.ts": -/*!*******************************************!*\ + /***/ "./src/demux/transmuxer-interface.ts": + /*!*******************************************!*\ !*** ./src/demux/transmuxer-interface.ts ***! \*******************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return TransmuxerInterface; + }); + /* harmony import */ var webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webworkify-webpack */ "./node_modules/webworkify-webpack/index.js"); + /* harmony import */ var webworkify_webpack__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/transmuxer */ "./src/demux/transmuxer.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/mediasource-helper */ "./src/utils/mediasource-helper.ts"); + /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js"); + /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/ __webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_6__); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TransmuxerInterface; }); -/* harmony import */ var webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webworkify-webpack */ "./node_modules/webworkify-webpack/index.js"); -/* harmony import */ var webworkify_webpack__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/transmuxer */ "./src/demux/transmuxer.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/mediasource-helper */ "./src/utils/mediasource-helper.ts"); -/* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js"); -/* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_6__); + var MediaSource = Object(_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__["getMediaSource"])() || { + isTypeSupported: function isTypeSupported() { + return false; + }, + }; + var TransmuxerInterface = /*#__PURE__*/ (function () { + function TransmuxerInterface(CiderHls, id, onTransmuxComplete, onFlush) { + var _this = this; + this.CiderHls = void 0; + this.id = void 0; + this.observer = void 0; + this.frag = null; + this.part = null; + this.worker = void 0; + this.onwmsg = void 0; + this.transmuxer = null; + this.onTransmuxComplete = void 0; + this.onFlush = void 0; + this.CiderHls = CiderHls; + this.id = id; + this.onTransmuxComplete = onTransmuxComplete; + this.onFlush = onFlush; + var config = CiderHls.config; + var forwardMessage = function forwardMessage(ev, data) { + data = data || {}; + data.frag = _this.frag; + data.id = _this.id; + CiderHls.trigger(ev, data); + }; // forward events to main thread + this.observer = new eventemitter3__WEBPACK_IMPORTED_MODULE_6__["EventEmitter"](); + this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, forwardMessage); + this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, forwardMessage); + var typeSupported = { + mp4: MediaSource.isTypeSupported("video/mp4"), + mpeg: MediaSource.isTypeSupported("audio/mpeg"), + mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'), + }; // navigator.vendor is not always available in Web Worker + // refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator + var vendor = navigator.vendor; + if (config.enableWorker && typeof Worker !== "undefined") { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log("demuxing in webworker"); + var worker; -var MediaSource = Object(_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__["getMediaSource"])() || { - isTypeSupported: function isTypeSupported() { - return false; - } -}; + try { + worker = this.worker = webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__(/*require.resolve*/ /*! ../demux/transmuxer-worker.ts */ "./src/demux/transmuxer-worker.ts"); + this.onwmsg = this.onWorkerMessage.bind(this); + worker.addEventListener("message", this.onwmsg); -var TransmuxerInterface = /*#__PURE__*/function () { - function TransmuxerInterface(CiderHls, id, onTransmuxComplete, onFlush) { - var _this = this; + worker.onerror = function (event) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].OTHER_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].INTERNAL_EXCEPTION, + fatal: true, + event: "demuxerWorker", + error: new Error(event.message + " (" + event.filename + ":" + event.lineno + ")"), + }); + }; - this.CiderHls = void 0; - this.id = void 0; - this.observer = void 0; - this.frag = null; - this.part = null; - this.worker = void 0; - this.onwmsg = void 0; - this.transmuxer = null; - this.onTransmuxComplete = void 0; - this.onFlush = void 0; - this.CiderHls = CiderHls; - this.id = id; - this.onTransmuxComplete = onTransmuxComplete; - this.onFlush = onFlush; - var config = CiderHls.config; + worker.postMessage({ + cmd: "init", + typeSupported: typeSupported, + vendor: vendor, + id: id, + config: JSON.stringify(config), + }); + } catch (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Error in worker:", err); + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].error("Error while initializing DemuxerWorker, fallback to inline"); - var forwardMessage = function forwardMessage(ev, data) { - data = data || {}; - data.frag = _this.frag; - data.id = _this.id; - CiderHls.trigger(ev, data); - }; // forward events to main thread + if (worker) { + // revoke the Object URL that was used to create transmuxer worker, so as not to leak it + self.URL.revokeObjectURL(worker.objectURL); + } + this.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, typeSupported, config, vendor, id); + this.worker = null; + } + } else { + this.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, typeSupported, config, vendor, id); + } + } - this.observer = new eventemitter3__WEBPACK_IMPORTED_MODULE_6__["EventEmitter"](); - this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, forwardMessage); - this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, forwardMessage); - var typeSupported = { - mp4: MediaSource.isTypeSupported('video/mp4'), - mpeg: MediaSource.isTypeSupported('audio/mpeg'), - mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"') - }; // navigator.vendor is not always available in Web Worker - // refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator + var _proto = TransmuxerInterface.prototype; - var vendor = navigator.vendor; + _proto.destroy = function destroy() { + var w = this.worker; - if (config.enableWorker && typeof Worker !== 'undefined') { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log('demuxing in webworker'); - var worker; + if (w) { + w.removeEventListener("message", this.onwmsg); + w.terminate(); + this.worker = null; + } else { + var transmuxer = this.transmuxer; - try { - worker = this.worker = webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__(/*require.resolve*/(/*! ../demux/transmuxer-worker.ts */ "./src/demux/transmuxer-worker.ts")); - this.onwmsg = this.onWorkerMessage.bind(this); - worker.addEventListener('message', this.onwmsg); + if (transmuxer) { + transmuxer.destroy(); + this.transmuxer = null; + } + } - worker.onerror = function (event) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].OTHER_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].INTERNAL_EXCEPTION, - fatal: true, - event: 'demuxerWorker', - error: new Error(event.message + " (" + event.filename + ":" + event.lineno + ")") - }); - }; + var observer = this.observer; - worker.postMessage({ - cmd: 'init', - typeSupported: typeSupported, - vendor: vendor, - id: id, - config: JSON.stringify(config) - }); - } catch (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('Error in worker:', err); - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].error('Error while initializing DemuxerWorker, fallback to inline'); + if (observer) { + observer.removeAllListeners(); + } // @ts-ignore - if (worker) { - // revoke the Object URL that was used to create transmuxer worker, so as not to leak it - self.URL.revokeObjectURL(worker.objectURL); - } + this.observer = null; + }; - this.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, typeSupported, config, vendor, id); - this.worker = null; - } - } else { - this.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, typeSupported, config, vendor, id); - } - } + _proto.push = function push(data, initSegmentData, audioCodec, videoCodec, frag, part, duration, accurateTimeOffset, chunkMeta, defaultInitPTS) { + var _this2 = this; - var _proto = TransmuxerInterface.prototype; + chunkMeta.transmuxing.start = self.performance.now(); + var transmuxer = this.transmuxer, + worker = this.worker; + var timeOffset = part ? part.start : frag.start; + var decryptdata = frag.decryptdata; + var lastFrag = this.frag; + var discontinuity = !(lastFrag && frag.cc === lastFrag.cc); + var trackSwitch = !(lastFrag && chunkMeta.level === lastFrag.level); + var snDiff = lastFrag ? chunkMeta.sn - lastFrag.sn : -1; + var partDiff = this.part ? chunkMeta.part - this.part.index : 1; + var contiguous = !trackSwitch && (snDiff === 1 || (snDiff === 0 && partDiff === 1)); + var now = self.performance.now(); - _proto.destroy = function destroy() { - var w = this.worker; + if (trackSwitch || snDiff || frag.stats.parsing.start === 0) { + frag.stats.parsing.start = now; + } - if (w) { - w.removeEventListener('message', this.onwmsg); - w.terminate(); - this.worker = null; - } else { - var transmuxer = this.transmuxer; + if (part && (partDiff || !contiguous)) { + part.stats.parsing.start = now; + } - if (transmuxer) { - transmuxer.destroy(); - this.transmuxer = null; - } - } + var state = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["TransmuxState"](discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset); - var observer = this.observer; + if (!contiguous || discontinuity) { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log( + "[transmuxer-interface, " + + frag.type + + "]: Starting new transmux session for sn: " + + chunkMeta.sn + + " p: " + + chunkMeta.part + + " level: " + + chunkMeta.level + + " id: " + + chunkMeta.id + + "\n discontinuity: " + + discontinuity + + "\n trackSwitch: " + + trackSwitch + + "\n contiguous: " + + contiguous + + "\n accurateTimeOffset: " + + accurateTimeOffset + + "\n timeOffset: " + + timeOffset + ); + var config = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["TransmuxConfig"](audioCodec, videoCodec, initSegmentData, duration, defaultInitPTS); + this.configureTransmuxer(config); + } - if (observer) { - observer.removeAllListeners(); - } // @ts-ignore + this.frag = frag; + this.part = part; // Frags with sn of 'initSegment' are not transmuxed + if (worker) { + // post fragment payload as transferable objects for ArrayBuffer (no copy) + worker.postMessage( + { + cmd: "demux", + data: data, + decryptdata: decryptdata, + chunkMeta: chunkMeta, + state: state, + }, + data instanceof ArrayBuffer ? [data] : [] + ); + } else if (transmuxer) { + var _transmuxResult = transmuxer.push(data, decryptdata, chunkMeta, state); - this.observer = null; - }; + if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["isPromise"])(_transmuxResult)) { + _transmuxResult.then(function (data) { + _this2.handleTransmuxComplete(data); + }); + } else { + this.handleTransmuxComplete(_transmuxResult); + } + } + }; - _proto.push = function push(data, initSegmentData, audioCodec, videoCodec, frag, part, duration, accurateTimeOffset, chunkMeta, defaultInitPTS) { - var _this2 = this; + _proto.flush = function flush(chunkMeta) { + var _this3 = this; - chunkMeta.transmuxing.start = self.performance.now(); - var transmuxer = this.transmuxer, - worker = this.worker; - var timeOffset = part ? part.start : frag.start; - var decryptdata = frag.decryptdata; - var lastFrag = this.frag; - var discontinuity = !(lastFrag && frag.cc === lastFrag.cc); - var trackSwitch = !(lastFrag && chunkMeta.level === lastFrag.level); - var snDiff = lastFrag ? chunkMeta.sn - lastFrag.sn : -1; - var partDiff = this.part ? chunkMeta.part - this.part.index : 1; - var contiguous = !trackSwitch && (snDiff === 1 || snDiff === 0 && partDiff === 1); - var now = self.performance.now(); + chunkMeta.transmuxing.start = self.performance.now(); + var transmuxer = this.transmuxer, + worker = this.worker; - if (trackSwitch || snDiff || frag.stats.parsing.start === 0) { - frag.stats.parsing.start = now; - } + if (worker) { + worker.postMessage({ + cmd: "flush", + chunkMeta: chunkMeta, + }); + } else if (transmuxer) { + var _transmuxResult2 = transmuxer.flush(chunkMeta); - if (part && (partDiff || !contiguous)) { - part.stats.parsing.start = now; - } + if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["isPromise"])(_transmuxResult2)) { + _transmuxResult2.then(function (data) { + _this3.handleFlushResult(data, chunkMeta); + }); + } else { + this.handleFlushResult(_transmuxResult2, chunkMeta); + } + } + }; - var state = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["TransmuxState"](discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset); + _proto.handleFlushResult = function handleFlushResult(results, chunkMeta) { + var _this4 = this; - if (!contiguous || discontinuity) { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log("[transmuxer-interface, " + frag.type + "]: Starting new transmux session for sn: " + chunkMeta.sn + " p: " + chunkMeta.part + " level: " + chunkMeta.level + " id: " + chunkMeta.id + "\n discontinuity: " + discontinuity + "\n trackSwitch: " + trackSwitch + "\n contiguous: " + contiguous + "\n accurateTimeOffset: " + accurateTimeOffset + "\n timeOffset: " + timeOffset); - var config = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["TransmuxConfig"](audioCodec, videoCodec, initSegmentData, duration, defaultInitPTS); - this.configureTransmuxer(config); - } + results.forEach(function (result) { + _this4.handleTransmuxComplete(result); + }); + this.onFlush(chunkMeta); + }; - this.frag = frag; - this.part = part; // Frags with sn of 'initSegment' are not transmuxed + _proto.onWorkerMessage = function onWorkerMessage(ev) { + var data = ev.data; + var CiderHls = this.CiderHls; - if (worker) { - // post fragment payload as transferable objects for ArrayBuffer (no copy) - worker.postMessage({ - cmd: 'demux', - data: data, - decryptdata: decryptdata, - chunkMeta: chunkMeta, - state: state - }, data instanceof ArrayBuffer ? [data] : []); - } else if (transmuxer) { - var _transmuxResult = transmuxer.push(data, decryptdata, chunkMeta, state); + switch (data.event) { + case "init": { + // revoke the Object URL that was used to create transmuxer worker, so as not to leak it + self.URL.revokeObjectURL(this.worker.objectURL); + break; + } - if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["isPromise"])(_transmuxResult)) { - _transmuxResult.then(function (data) { - _this2.handleTransmuxComplete(data); - }); - } else { - this.handleTransmuxComplete(_transmuxResult); - } - } - }; + case "transmuxComplete": { + this.handleTransmuxComplete(data.data); + break; + } - _proto.flush = function flush(chunkMeta) { - var _this3 = this; + case "flush": { + this.onFlush(data.data); + break; + } - chunkMeta.transmuxing.start = self.performance.now(); - var transmuxer = this.transmuxer, - worker = this.worker; + /* falls through */ - if (worker) { - worker.postMessage({ - cmd: 'flush', - chunkMeta: chunkMeta - }); - } else if (transmuxer) { - var _transmuxResult2 = transmuxer.flush(chunkMeta); + default: { + data.data = data.data || {}; + data.data.frag = this.frag; + data.data.id = this.id; + CiderHls.trigger(data.event, data.data); + break; + } + } + }; - if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["isPromise"])(_transmuxResult2)) { - _transmuxResult2.then(function (data) { - _this3.handleFlushResult(data, chunkMeta); - }); - } else { - this.handleFlushResult(_transmuxResult2, chunkMeta); - } - } - }; + _proto.configureTransmuxer = function configureTransmuxer(config) { + var worker = this.worker, + transmuxer = this.transmuxer; - _proto.handleFlushResult = function handleFlushResult(results, chunkMeta) { - var _this4 = this; + if (worker) { + worker.postMessage({ + cmd: "configure", + config: config, + }); + } else if (transmuxer) { + transmuxer.configure(config); + } + }; - results.forEach(function (result) { - _this4.handleTransmuxComplete(result); - }); - this.onFlush(chunkMeta); - }; + _proto.handleTransmuxComplete = function handleTransmuxComplete(result) { + result.chunkMeta.transmuxing.end = self.performance.now(); + this.onTransmuxComplete(result); + }; - _proto.onWorkerMessage = function onWorkerMessage(ev) { - var data = ev.data; - var CiderHls = this.CiderHls; + return TransmuxerInterface; + })(); - switch (data.event) { - case 'init': - { - // revoke the Object URL that was used to create transmuxer worker, so as not to leak it - self.URL.revokeObjectURL(this.worker.objectURL); - break; - } + /***/ + }, - case 'transmuxComplete': - { - this.handleTransmuxComplete(data.data); - break; - } - - case 'flush': - { - this.onFlush(data.data); - break; - } - - /* falls through */ - - default: - { - data.data = data.data || {}; - data.data.frag = this.frag; - data.data.id = this.id; - CiderHls.trigger(data.event, data.data); - break; - } - } - }; - - _proto.configureTransmuxer = function configureTransmuxer(config) { - var worker = this.worker, - transmuxer = this.transmuxer; - - if (worker) { - worker.postMessage({ - cmd: 'configure', - config: config - }); - } else if (transmuxer) { - transmuxer.configure(config); - } - }; - - _proto.handleTransmuxComplete = function handleTransmuxComplete(result) { - result.chunkMeta.transmuxing.end = self.performance.now(); - this.onTransmuxComplete(result); - }; - - return TransmuxerInterface; -}(); - - - -/***/ }), - -/***/ "./src/demux/transmuxer-worker.ts": -/*!****************************************!*\ + /***/ "./src/demux/transmuxer-worker.ts": + /*!****************************************!*\ !*** ./src/demux/transmuxer-worker.ts ***! \****************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TransmuxerWorker; }); -/* harmony import */ var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../demux/transmuxer */ "./src/demux/transmuxer.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js"); -/* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_3__); - - - - -function TransmuxerWorker(self) { - var observer = new eventemitter3__WEBPACK_IMPORTED_MODULE_3__["EventEmitter"](); - - var forwardMessage = function forwardMessage(ev, data) { - self.postMessage({ - event: ev, - data: data - }); - }; // forward events to main thread - - - observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, forwardMessage); - observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, forwardMessage); - self.addEventListener('message', function (ev) { - var data = ev.data; - - switch (data.cmd) { - case 'init': - { - var config = JSON.parse(data.config); - self.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["default"](observer, data.typeSupported, config, data.vendor, data.id); - Object(_utils_logger__WEBPACK_IMPORTED_MODULE_2__["enableLogs"])(config.debug); - forwardMessage('init', null); - break; - } - - case 'configure': - { - self.transmuxer.configure(data.config); - break; - } - - case 'demux': - { - var transmuxResult = self.transmuxer.push(data.data, data.decryptdata, data.chunkMeta, data.state); - - if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["isPromise"])(transmuxResult)) { - transmuxResult.then(function (data) { - emitTransmuxComplete(self, data); + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return TransmuxerWorker; }); - } else { - emitTransmuxComplete(self, transmuxResult); - } + /* harmony import */ var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../demux/transmuxer */ "./src/demux/transmuxer.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js"); + /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/ __webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_3__); - break; - } + function TransmuxerWorker(self) { + var observer = new eventemitter3__WEBPACK_IMPORTED_MODULE_3__["EventEmitter"](); - case 'flush': - { - var id = data.chunkMeta; + var forwardMessage = function forwardMessage(ev, data) { + self.postMessage({ + event: ev, + data: data, + }); + }; // forward events to main thread - var _transmuxResult = self.transmuxer.flush(id); + observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].FRAG_DECRYPTED, forwardMessage); + observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, forwardMessage); + self.addEventListener("message", function (ev) { + var data = ev.data; - if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["isPromise"])(_transmuxResult)) { - _transmuxResult.then(function (results) { - handleFlushResult(self, results, id); - }); - } else { - handleFlushResult(self, _transmuxResult, id); - } + switch (data.cmd) { + case "init": { + var config = JSON.parse(data.config); + self.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["default"](observer, data.typeSupported, config, data.vendor, data.id); + Object(_utils_logger__WEBPACK_IMPORTED_MODULE_2__["enableLogs"])(config.debug); + forwardMessage("init", null); + break; + } - break; - } + case "configure": { + self.transmuxer.configure(data.config); + break; + } - default: - break; - } - }); -} + case "demux": { + var transmuxResult = self.transmuxer.push(data.data, data.decryptdata, data.chunkMeta, data.state); -function emitTransmuxComplete(self, transmuxResult) { - if (isEmptyResult(transmuxResult.remuxResult)) { - return; - } + if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["isPromise"])(transmuxResult)) { + transmuxResult.then(function (data) { + emitTransmuxComplete(self, data); + }); + } else { + emitTransmuxComplete(self, transmuxResult); + } - var transferable = []; - var _transmuxResult$remux = transmuxResult.remuxResult, - audio = _transmuxResult$remux.audio, - video = _transmuxResult$remux.video; + break; + } - if (audio) { - addToTransferable(transferable, audio); - } + case "flush": { + var id = data.chunkMeta; - if (video) { - addToTransferable(transferable, video); - } + var _transmuxResult = self.transmuxer.flush(id); - self.postMessage({ - event: 'transmuxComplete', - data: transmuxResult - }, transferable); -} // Converts data to a transferable object https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) -// in order to minimize message passing overhead + if (Object(_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["isPromise"])(_transmuxResult)) { + _transmuxResult.then(function (results) { + handleFlushResult(self, results, id); + }); + } else { + handleFlushResult(self, _transmuxResult, id); + } + break; + } -function addToTransferable(transferable, track) { - if (track.data1) { - transferable.push(track.data1.buffer); - } + default: + break; + } + }); + } - if (track.data2) { - transferable.push(track.data2.buffer); - } -} + function emitTransmuxComplete(self, transmuxResult) { + if (isEmptyResult(transmuxResult.remuxResult)) { + return; + } -function handleFlushResult(self, results, chunkMeta) { - results.forEach(function (result) { - emitTransmuxComplete(self, result); - }); - self.postMessage({ - event: 'flush', - data: chunkMeta - }); -} + var transferable = []; + var _transmuxResult$remux = transmuxResult.remuxResult, + audio = _transmuxResult$remux.audio, + video = _transmuxResult$remux.video; -function isEmptyResult(remuxResult) { - return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment; -} + if (audio) { + addToTransferable(transferable, audio); + } -/***/ }), + if (video) { + addToTransferable(transferable, video); + } -/***/ "./src/demux/transmuxer.ts": -/*!*********************************!*\ + self.postMessage( + { + event: "transmuxComplete", + data: transmuxResult, + }, + transferable + ); + } // Converts data to a transferable object https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) + // in order to minimize message passing overhead + + function addToTransferable(transferable, track) { + if (track.data1) { + transferable.push(track.data1.buffer); + } + + if (track.data2) { + transferable.push(track.data2.buffer); + } + } + + function handleFlushResult(self, results, chunkMeta) { + results.forEach(function (result) { + emitTransmuxComplete(self, result); + }); + self.postMessage({ + event: "flush", + data: chunkMeta, + }); + } + + function isEmptyResult(remuxResult) { + return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment; + } + + /***/ + }, + + /***/ "./src/demux/transmuxer.ts": + /*!*********************************!*\ !*** ./src/demux/transmuxer.ts ***! \*********************************/ -/*! exports provided: default, isPromise, TransmuxConfig, TransmuxState */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Transmuxer; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isPromise", function() { return isPromise; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TransmuxConfig", function() { return TransmuxConfig; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TransmuxState", function() { return TransmuxState; }); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts"); -/* harmony import */ var _demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/aacdemuxer */ "./src/demux/aacdemuxer.ts"); -/* harmony import */ var _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../demux/mp4demuxer */ "./src/demux/mp4demuxer.ts"); -/* harmony import */ var _demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../demux/tsdemuxer */ "./src/demux/tsdemuxer.ts"); -/* harmony import */ var _demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../demux/mp3demuxer */ "./src/demux/mp3demuxer.ts"); -/* harmony import */ var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../remux/mp4-remuxer */ "./src/remux/mp4-remuxer.ts"); -/* harmony import */ var _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../remux/passthrough-remuxer */ "./src/remux/passthrough-remuxer.ts"); -/* harmony import */ var _chunk_cache__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./chunk-cache */ "./src/demux/chunk-cache.ts"); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - - - - - - - - - - - - -var now; // performance.now() not available on WebWorker, at least on Safari Desktop - -try { - now = self.performance.now.bind(self.performance); -} catch (err) { - _utils_logger__WEBPACK_IMPORTED_MODULE_11__["logger"].debug('Unable to use Performance API on this environment'); - now = self.Date.now; -} - -var muxConfig = [{ - demux: _demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__["default"], - remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"] -}, { - demux: _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"], - remux: _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"] -}, { - demux: _demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__["default"], - remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"] -}, { - demux: _demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__["default"], - remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"] -}]; -var minProbeByteLength = 1024; -muxConfig.forEach(function (_ref) { - var demux = _ref.demux; - minProbeByteLength = Math.max(minProbeByteLength, demux.minProbeByteLength); -}); - -var Transmuxer = /*#__PURE__*/function () { - function Transmuxer(observer, typeSupported, config, vendor, id) { - this.observer = void 0; - this.typeSupported = void 0; - this.config = void 0; - this.vendor = void 0; - this.id = void 0; - this.demuxer = void 0; - this.remuxer = void 0; - this.decrypter = void 0; - this.probe = void 0; - this.decryptionPromise = null; - this.transmuxConfig = void 0; - this.currentTransmuxState = void 0; - this.cache = new _chunk_cache__WEBPACK_IMPORTED_MODULE_9__["default"](); - this.observer = observer; - this.typeSupported = typeSupported; - this.config = config; - this.vendor = vendor; - this.id = id; - } - - var _proto = Transmuxer.prototype; - - _proto.configure = function configure(transmuxConfig) { - this.transmuxConfig = transmuxConfig; - - if (this.decrypter) { - this.decrypter.reset(); - } - }; - - _proto.push = function push(data, decryptdata, chunkMeta, state) { - var _this = this; - - var stats = chunkMeta.transmuxing; - stats.executeStart = now(); - var uintData = new Uint8Array(data); - var cache = this.cache, - config = this.config, - currentTransmuxState = this.currentTransmuxState, - transmuxConfig = this.transmuxConfig; - - if (state) { - this.currentTransmuxState = state; - } - - var keyData = getEncryptionType(uintData, decryptdata); - - if (keyData && keyData.method === 'AES-128') { - var decrypter = this.getDecrypter(); // Software decryption is synchronous; webCrypto is not - - if (config.enableSoftwareAES) { - // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached - // data is handled in the flush() call - var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer); - - if (!decryptedData) { - stats.executeEnd = now(); - return emptyResult(chunkMeta); - } - - uintData = new Uint8Array(decryptedData); - } else { - this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer).then(function (decryptedData) { - // Calling push here is important; if flush() is called while this is still resolving, this ensures that - // the decrypted data has been transmuxed - var result = _this.push(decryptedData, null, chunkMeta); - - _this.decryptionPromise = null; - return result; - }); - return this.decryptionPromise; - } - } - - var _ref2 = state || currentTransmuxState, - contiguous = _ref2.contiguous, - discontinuity = _ref2.discontinuity, - trackSwitch = _ref2.trackSwitch, - accurateTimeOffset = _ref2.accurateTimeOffset, - timeOffset = _ref2.timeOffset; - - var audioCodec = transmuxConfig.audioCodec, - videoCodec = transmuxConfig.videoCodec, - defaultInitPts = transmuxConfig.defaultInitPts, - duration = transmuxConfig.duration, - initSegmentData = transmuxConfig.initSegmentData; // Reset muxers before probing to ensure that their state is clean, even if flushing occurs before a successful probe - - if (discontinuity || trackSwitch) { - this.resetInitSegment(initSegmentData, audioCodec, videoCodec, duration); - } - - if (discontinuity) { - this.resetInitialTimestamp(defaultInitPts); - } - - if (!contiguous) { - this.resetContiguity(); - } - - if (this.needsProbing(uintData, discontinuity, trackSwitch)) { - if (cache.dataLength) { - var cachedData = cache.flush(); - uintData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_10__["appendUint8Array"])(cachedData, uintData); - } - - this.configureTransmuxer(uintData, transmuxConfig); - } - - var result = this.transmux(uintData, keyData, timeOffset, accurateTimeOffset, chunkMeta); - var currentState = this.currentTransmuxState; - currentState.contiguous = true; - currentState.discontinuity = false; - currentState.trackSwitch = false; - stats.executeEnd = now(); - return result; - } // Due to data caching, flush calls can produce more than one TransmuxerResult (hence the Array type) - ; - - _proto.flush = function flush(chunkMeta) { - var _this2 = this; - - var stats = chunkMeta.transmuxing; - stats.executeStart = now(); - var decrypter = this.decrypter, - cache = this.cache, - currentTransmuxState = this.currentTransmuxState, - decryptionPromise = this.decryptionPromise; - - if (decryptionPromise) { - // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore - // only flushing is required for async decryption - return decryptionPromise.then(function () { - return _this2.flush(chunkMeta); - }); - } - - var transmuxResults = []; - var timeOffset = currentTransmuxState.timeOffset; - - if (decrypter) { - // The decrypter may have data cached, which needs to be demuxed. In this case we'll have two TransmuxResults - // This happens in the case that we receive only 1 push call for a segment (either for non-progressive downloads, - // or for progressive downloads with small segments) - var decryptedData = decrypter.flush(); - - if (decryptedData) { - // Push always returns a TransmuxerResult if decryptdata is null - transmuxResults.push(this.push(decryptedData, null, chunkMeta)); - } - } - - var bytesSeen = cache.dataLength; - cache.reset(); - var demuxer = this.demuxer, - remuxer = this.remuxer; - - if (!demuxer || !remuxer) { - // If probing failed, and each demuxer saw enough bytes to be able to probe, then CiderHls.js has been given content its not able to handle - if (bytesSeen >= minProbeByteLength) { - this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_PARSING_ERROR, - fatal: true, - reason: 'no demux matching with content found' - }); - } - - stats.executeEnd = now(); - return [emptyResult(chunkMeta)]; - } - - var demuxResultOrPromise = demuxer.flush(timeOffset); - - if (isPromise(demuxResultOrPromise)) { - // Decrypt final SAMPLE-AES samples - return demuxResultOrPromise.then(function (demuxResult) { - _this2.flushRemux(transmuxResults, demuxResult, chunkMeta); - - return transmuxResults; - }); - } - - this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta); - return transmuxResults; - }; - - _proto.flushRemux = function flushRemux(transmuxResults, demuxResult, chunkMeta) { - var audioTrack = demuxResult.audioTrack, - avcTrack = demuxResult.avcTrack, - id3Track = demuxResult.id3Track, - textTrack = demuxResult.textTrack; - var _this$currentTransmux = this.currentTransmuxState, - accurateTimeOffset = _this$currentTransmux.accurateTimeOffset, - timeOffset = _this$currentTransmux.timeOffset; - _utils_logger__WEBPACK_IMPORTED_MODULE_11__["logger"].log("[transmuxer.ts]: Flushed fragment " + chunkMeta.sn + (chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : '') + " of level " + chunkMeta.level); - var remuxResult = this.remuxer.remux(audioTrack, avcTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id); - transmuxResults.push({ - remuxResult: remuxResult, - chunkMeta: chunkMeta - }); - chunkMeta.transmuxing.executeEnd = now(); - }; - - _proto.resetInitialTimestamp = function resetInitialTimestamp(defaultInitPts) { - var demuxer = this.demuxer, - remuxer = this.remuxer; - - if (!demuxer || !remuxer) { - return; - } - - demuxer.resetTimeStamp(defaultInitPts); - remuxer.resetTimeStamp(defaultInitPts); - }; - - _proto.resetContiguity = function resetContiguity() { - var demuxer = this.demuxer, - remuxer = this.remuxer; - - if (!demuxer || !remuxer) { - return; - } - - demuxer.resetContiguity(); - remuxer.resetNextTimestamp(); - }; - - _proto.resetInitSegment = function resetInitSegment(initSegmentData, audioCodec, videoCodec, duration) { - var demuxer = this.demuxer, - remuxer = this.remuxer; - - if (!demuxer || !remuxer) { - return; - } - - demuxer.resetInitSegment(audioCodec, videoCodec, duration); - remuxer.resetInitSegment(initSegmentData, audioCodec, videoCodec); - }; - - _proto.destroy = function destroy() { - if (this.demuxer) { - this.demuxer.destroy(); - this.demuxer = undefined; - } - - if (this.remuxer) { - this.remuxer.destroy(); - this.remuxer = undefined; - } - }; - - _proto.transmux = function transmux(data, keyData, timeOffset, accurateTimeOffset, chunkMeta) { - var result; - - if (keyData && keyData.method === 'SAMPLE-AES') { - result = this.transmuxSampleAes(data, keyData, timeOffset, accurateTimeOffset, chunkMeta); - } else { - result = this.transmuxUnencrypted(data, timeOffset, accurateTimeOffset, chunkMeta); - } - - return result; - }; - - _proto.transmuxUnencrypted = function transmuxUnencrypted(data, timeOffset, accurateTimeOffset, chunkMeta) { - var _demux = this.demuxer.demux(data, timeOffset, false, !this.config.progressive), - audioTrack = _demux.audioTrack, - avcTrack = _demux.avcTrack, - id3Track = _demux.id3Track, - textTrack = _demux.textTrack; - - var remuxResult = this.remuxer.remux(audioTrack, avcTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, false, this.id); - return { - remuxResult: remuxResult, - chunkMeta: chunkMeta - }; - }; - - _proto.transmuxSampleAes = function transmuxSampleAes(data, decryptData, timeOffset, accurateTimeOffset, chunkMeta) { - var _this3 = this; - - return this.demuxer.demuxSampleAes(data, decryptData, timeOffset).then(function (demuxResult) { - var remuxResult = _this3.remuxer.remux(demuxResult.audioTrack, demuxResult.avcTrack, demuxResult.id3Track, demuxResult.textTrack, timeOffset, accurateTimeOffset, false, _this3.id); - - return { - remuxResult: remuxResult, - chunkMeta: chunkMeta - }; - }); - }; - - _proto.configureTransmuxer = function configureTransmuxer(data, transmuxConfig) { - var config = this.config, - observer = this.observer, - typeSupported = this.typeSupported, - vendor = this.vendor; - var audioCodec = transmuxConfig.audioCodec, - defaultInitPts = transmuxConfig.defaultInitPts, - duration = transmuxConfig.duration, - initSegmentData = transmuxConfig.initSegmentData, - videoCodec = transmuxConfig.videoCodec; // probe for content type - - var mux; - - for (var i = 0, len = muxConfig.length; i < len; i++) { - if (muxConfig[i].demux.probe(data)) { - mux = muxConfig[i]; - break; - } - } - - if (!mux) { - // If probing previous configs fail, use mp4 passthrough - _utils_logger__WEBPACK_IMPORTED_MODULE_11__["logger"].warn('Failed to find demuxer by probing frag, treating as mp4 passthrough'); - mux = { - demux: _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"], - remux: _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"] - }; - } // so let's check that current remuxer and demuxer are still valid - - - var demuxer = this.demuxer; - var remuxer = this.remuxer; - var Remuxer = mux.remux; - var Demuxer = mux.demux; - - if (!remuxer || !(remuxer instanceof Remuxer)) { - this.remuxer = new Remuxer(observer, config, typeSupported, vendor); - } - - if (!demuxer || !(demuxer instanceof Demuxer)) { - this.demuxer = new Demuxer(observer, config, typeSupported); - this.probe = Demuxer.probe; - } // Ensure that muxers are always initialized with an initSegment - - - this.resetInitSegment(initSegmentData, audioCodec, videoCodec, duration); - this.resetInitialTimestamp(defaultInitPts); - }; - - _proto.needsProbing = function needsProbing(data, discontinuity, trackSwitch) { - // in case of continuity change, or track switch - // we might switch from content type (AAC container to TS container, or TS to fmp4 for example) - return !this.demuxer || !this.remuxer || discontinuity || trackSwitch; - }; - - _proto.getDecrypter = function getDecrypter() { - var decrypter = this.decrypter; - - if (!decrypter) { - decrypter = this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, this.config); - } - - return decrypter; - }; - - return Transmuxer; -}(); - - - -function getEncryptionType(data, decryptData) { - var encryptionType = null; - - if (data.byteLength > 0 && decryptData != null && decryptData.key != null && decryptData.iv !== null && decryptData.method != null) { - encryptionType = decryptData; - } - - return encryptionType; -} - -var emptyResult = function emptyResult(chunkMeta) { - return { - remuxResult: {}, - chunkMeta: chunkMeta - }; -}; - -function isPromise(p) { - return 'then' in p && p.then instanceof Function; -} -var TransmuxConfig = function TransmuxConfig(audioCodec, videoCodec, initSegmentData, duration, defaultInitPts) { - this.audioCodec = void 0; - this.videoCodec = void 0; - this.initSegmentData = void 0; - this.duration = void 0; - this.defaultInitPts = void 0; - this.audioCodec = audioCodec; - this.videoCodec = videoCodec; - this.initSegmentData = initSegmentData; - this.duration = duration; - this.defaultInitPts = defaultInitPts; -}; -var TransmuxState = function TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset) { - this.discontinuity = void 0; - this.contiguous = void 0; - this.accurateTimeOffset = void 0; - this.trackSwitch = void 0; - this.timeOffset = void 0; - this.discontinuity = discontinuity; - this.contiguous = contiguous; - this.accurateTimeOffset = accurateTimeOffset; - this.trackSwitch = trackSwitch; - this.timeOffset = timeOffset; -}; - -/***/ }), - -/***/ "./src/demux/tsdemuxer.ts": -/*!********************************!*\ - !*** ./src/demux/tsdemuxer.ts ***! - \********************************/ -/*! exports provided: discardEPB, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "discardEPB", function() { return discardEPB; }); -/* harmony import */ var _adts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./adts */ "./src/demux/adts.ts"); -/* harmony import */ var _mpegaudio__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mpegaudio */ "./src/demux/mpegaudio.ts"); -/* harmony import */ var _exp_golomb__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./exp-golomb */ "./src/demux/exp-golomb.ts"); -/* harmony import */ var _id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./id3 */ "./src/demux/id3.ts"); -/* harmony import */ var _sample_aes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./sample-aes */ "./src/demux/sample-aes.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/** - * highly optimized TS demuxer: - * parse PAT, PMT - * extract PES packet from audio and video PIDs - * extract AVC/H264 NAL units and AAC/ADTS samples from PES packet - * trigger the remuxer upon parsing completion - * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource. - * it also controls the remuxing process : - * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state. - */ - - - - - - - - - -// We are using fixed track IDs for driving the MP4 remuxer -// instead of following the TS PIDs. -// There is no reason not to do this and some browsers/SourceBuffer-demuxers -// may not like if there are TrackID "switches" -// See https://github.com/video-dev/CiderHls.js/issues/1331 -// Here we are mapping our internal track types to constant MP4 track IDs -// With MSE currently one can only have one track of each, and we are muxing -// whatever video/audio rendition in them. -var RemuxerTrackIdConfig = { - video: 1, - audio: 2, - id3: 3, - text: 4 -}; - -var TSDemuxer = /*#__PURE__*/function () { - function TSDemuxer(observer, config, typeSupported) { - this.observer = void 0; - this.config = void 0; - this.typeSupported = void 0; - this.sampleAes = null; - this.pmtParsed = false; - this.audioCodec = void 0; - this.videoCodec = void 0; - this._duration = 0; - this.aacLastPTS = null; - this._initPTS = null; - this._initDTS = null; - this._pmtId = -1; - this._avcTrack = void 0; - this._audioTrack = void 0; - this._id3Track = void 0; - this._txtTrack = void 0; - this.aacOverFlow = null; - this.avcSample = null; - this.remainderData = null; - this.observer = observer; - this.config = config; - this.typeSupported = typeSupported; - } - - TSDemuxer.probe = function probe(data) { - var syncOffset = TSDemuxer.syncOffset(data); - - if (syncOffset < 0) { - return false; - } else { - if (syncOffset) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("MPEG2-TS detected but first sync word found @ offset " + syncOffset + ", junk ahead ?"); - } - - return true; - } - }; - - TSDemuxer.syncOffset = function syncOffset(data) { - // scan 1000 first bytes - var scanwindow = Math.min(1000, data.length - 3 * 188); - var i = 0; - - while (i < scanwindow) { - // a TS fragment should contain at least 3 TS packets, a PAT, a PMT, and one PID, each starting with 0x47 - if (data[i] === 0x47 && data[i + 188] === 0x47 && data[i + 2 * 188] === 0x47) { - return i; - } else { - i++; - } - } - - return -1; - } - /** - * Creates a track model internal to demuxer used to drive remuxing input - * - * @param type 'audio' | 'video' | 'id3' | 'text' - * @param duration - * @return TSDemuxer's internal track model - */ - ; - - TSDemuxer.createTrack = function createTrack(type, duration) { - return { - container: type === 'video' || type === 'audio' ? 'video/mp2t' : undefined, - type: type, - id: RemuxerTrackIdConfig[type], - pid: -1, - inputTimeScale: 90000, - sequenceNumber: 0, - samples: [], - dropped: 0, - duration: type === 'audio' ? duration : undefined - }; - } - /** - * Initializes a new init segment on the demuxer/remuxer interface. Needed for discontinuities/track-switches (or at stream start) - * Resets all internal track instances of the demuxer. - */ - ; - - var _proto = TSDemuxer.prototype; - - _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { - this.pmtParsed = false; - this._pmtId = -1; - this._avcTrack = TSDemuxer.createTrack('video', duration); - this._audioTrack = TSDemuxer.createTrack('audio', duration); - this._id3Track = TSDemuxer.createTrack('id3', duration); - this._txtTrack = TSDemuxer.createTrack('text', duration); - this._audioTrack.isAAC = true; // flush any partial content - - this.aacOverFlow = null; - this.aacLastPTS = null; - this.avcSample = null; - this.audioCodec = audioCodec; - this.videoCodec = videoCodec; - this._duration = duration; - }; - - _proto.resetTimeStamp = function resetTimeStamp() {}; - - _proto.resetContiguity = function resetContiguity() { - var _audioTrack = this._audioTrack, - _avcTrack = this._avcTrack, - _id3Track = this._id3Track; - - if (_audioTrack) { - _audioTrack.pesData = null; - } - - if (_avcTrack) { - _avcTrack.pesData = null; - } - - if (_id3Track) { - _id3Track.pesData = null; - } - - this.aacOverFlow = null; - this.aacLastPTS = null; - }; - - _proto.demux = function demux(data, timeOffset, isSampleAes, flush) { - if (isSampleAes === void 0) { - isSampleAes = false; - } - - if (flush === void 0) { - flush = false; - } - - if (!isSampleAes) { - this.sampleAes = null; - } - - var pes; - var avcTrack = this._avcTrack; - var audioTrack = this._audioTrack; - var id3Track = this._id3Track; - var avcId = avcTrack.pid; - var avcData = avcTrack.pesData; - var audioId = audioTrack.pid; - var id3Id = id3Track.pid; - var audioData = audioTrack.pesData; - var id3Data = id3Track.pesData; - var unknownPIDs = false; - var pmtParsed = this.pmtParsed; - var pmtId = this._pmtId; - var len = data.length; - - if (this.remainderData) { - data = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_6__["appendUint8Array"])(this.remainderData, data); - len = data.length; - this.remainderData = null; - } - - if (len < 188 && !flush) { - this.remainderData = data; - return { - audioTrack: audioTrack, - avcTrack: avcTrack, - id3Track: id3Track, - textTrack: this._txtTrack - }; - } - - var syncOffset = Math.max(0, TSDemuxer.syncOffset(data)); - len -= (len + syncOffset) % 188; - - if (len < data.byteLength && !flush) { - this.remainderData = new Uint8Array(data.buffer, len, data.buffer.byteLength - len); - } // loop through TS packets - - - for (var start = syncOffset; start < len; start += 188) { - if (data[start] === 0x47) { - var stt = !!(data[start + 1] & 0x40); // pid is a 13-bit field starting at the last bit of TS[1] - - var pid = ((data[start + 1] & 0x1f) << 8) + data[start + 2]; - var atf = (data[start + 3] & 0x30) >> 4; // if an adaption field is present, its length is specified by the fifth byte of the TS packet header. - - var offset = void 0; - - if (atf > 1) { - offset = start + 5 + data[start + 4]; // continue if there is only adaptation field - - if (offset === start + 188) { - continue; - } - } else { - offset = start + 4; - } - - switch (pid) { - case avcId: - if (stt) { - if (avcData && (pes = parsePES(avcData))) { - this.parseAVCPES(pes, false); - } - - avcData = { - data: [], - size: 0 - }; - } - - if (avcData) { - avcData.data.push(data.subarray(offset, start + 188)); - avcData.size += start + 188 - offset; - } - - break; - - case audioId: - if (stt) { - if (audioData && (pes = parsePES(audioData))) { - if (audioTrack.isAAC) { - this.parseAACPES(pes); - } else { - this.parseMPEGPES(pes); - } - } - - audioData = { - data: [], - size: 0 - }; - } - - if (audioData) { - audioData.data.push(data.subarray(offset, start + 188)); - audioData.size += start + 188 - offset; - } - - break; - - case id3Id: - if (stt) { - if (id3Data && (pes = parsePES(id3Data))) { - this.parseID3PES(pes); - } - - id3Data = { - data: [], - size: 0 - }; - } - - if (id3Data) { - id3Data.data.push(data.subarray(offset, start + 188)); - id3Data.size += start + 188 - offset; - } - - break; - - case 0: - if (stt) { - offset += data[offset] + 1; - } - - pmtId = this._pmtId = parsePAT(data, offset); - break; - - case pmtId: - { - if (stt) { - offset += data[offset] + 1; - } - - var parsedPIDs = parsePMT(data, offset, this.typeSupported.mpeg === true || this.typeSupported.mp3 === true, isSampleAes); // only update track id if track PID found while parsing PMT - // this is to avoid resetting the PID to -1 in case - // track PID transiently disappears from the stream - // this could happen in case of transient missing audio samples for example - // NOTE this is only the PID of the track as found in TS, - // but we are not using this for MP4 track IDs. - - avcId = parsedPIDs.avc; - - if (avcId > 0) { - avcTrack.pid = avcId; - } - - audioId = parsedPIDs.audio; - - if (audioId > 0) { - audioTrack.pid = audioId; - audioTrack.isAAC = parsedPIDs.isAAC; - } - - id3Id = parsedPIDs.id3; - - if (id3Id > 0) { - id3Track.pid = id3Id; - } - - if (unknownPIDs && !pmtParsed) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log('reparse from beginning'); - unknownPIDs = false; // we set it to -188, the += 188 in the for loop will reset start to 0 - - start = syncOffset - 188; - } - - pmtParsed = this.pmtParsed = true; - break; - } - - case 17: - case 0x1fff: - break; - - default: - unknownPIDs = true; - break; - } - } else { - this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorDetails"].FRAG_PARSING_ERROR, - fatal: false, - reason: 'TS packet did not start with 0x47' - }); - } - } - - avcTrack.pesData = avcData; - audioTrack.pesData = audioData; - id3Track.pesData = id3Data; - var demuxResult = { - audioTrack: audioTrack, - avcTrack: avcTrack, - id3Track: id3Track, - textTrack: this._txtTrack - }; - - if (flush) { - this.extractRemainingSamples(demuxResult); - } - - return demuxResult; - }; - - _proto.flush = function flush() { - var remainderData = this.remainderData; - this.remainderData = null; - var result; - - if (remainderData) { - result = this.demux(remainderData, -1, false, true); - } else { - result = { - audioTrack: this._audioTrack, - avcTrack: this._avcTrack, - textTrack: this._txtTrack, - id3Track: this._id3Track - }; - } - - this.extractRemainingSamples(result); - - if (this.sampleAes) { - return this.decrypt(result, this.sampleAes); - } - - return result; - }; - - _proto.extractRemainingSamples = function extractRemainingSamples(demuxResult) { - var audioTrack = demuxResult.audioTrack, - avcTrack = demuxResult.avcTrack, - id3Track = demuxResult.id3Track; - var avcData = avcTrack.pesData; - var audioData = audioTrack.pesData; - var id3Data = id3Track.pesData; // try to parse last PES packets - - var pes; - - if (avcData && (pes = parsePES(avcData))) { - this.parseAVCPES(pes, true); - avcTrack.pesData = null; - } else { - // either avcData null or PES truncated, keep it for next frag parsing - avcTrack.pesData = avcData; - } - - if (audioData && (pes = parsePES(audioData))) { - if (audioTrack.isAAC) { - this.parseAACPES(pes); - } else { - this.parseMPEGPES(pes); - } - - audioTrack.pesData = null; - } else { - if (audioData !== null && audioData !== void 0 && audioData.size) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log('last AAC PES packet truncated,might overlap between fragments'); - } // either audioData null or PES truncated, keep it for next frag parsing - - - audioTrack.pesData = audioData; - } - - if (id3Data && (pes = parsePES(id3Data))) { - this.parseID3PES(pes); - id3Track.pesData = null; - } else { - // either id3Data null or PES truncated, keep it for next frag parsing - id3Track.pesData = id3Data; - } - }; - - _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) { - var demuxResult = this.demux(data, timeOffset, true, !this.config.progressive); - var sampleAes = this.sampleAes = new _sample_aes__WEBPACK_IMPORTED_MODULE_4__["default"](this.observer, this.config, keyData); - return this.decrypt(demuxResult, sampleAes); - }; - - _proto.decrypt = function decrypt(demuxResult, sampleAes) { - return new Promise(function (resolve) { - var audioTrack = demuxResult.audioTrack, - avcTrack = demuxResult.avcTrack; - - if (audioTrack.samples && audioTrack.isAAC) { - sampleAes.decryptAacSamples(audioTrack.samples, 0, function () { - if (avcTrack.samples) { - sampleAes.decryptAvcSamples(avcTrack.samples, 0, 0, function () { - resolve(demuxResult); + /*! exports provided: default, isPromise, TransmuxConfig, TransmuxState */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return Transmuxer; }); - } else { - resolve(demuxResult); - } - }); - } else if (avcTrack.samples) { - sampleAes.decryptAvcSamples(avcTrack.samples, 0, 0, function () { - resolve(demuxResult); - }); - } - }); - }; + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isPromise", function () { + return isPromise; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TransmuxConfig", function () { + return TransmuxConfig; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TransmuxState", function () { + return TransmuxState; + }); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts"); + /* harmony import */ var _demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/aacdemuxer */ "./src/demux/aacdemuxer.ts"); + /* harmony import */ var _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../demux/mp4demuxer */ "./src/demux/mp4demuxer.ts"); + /* harmony import */ var _demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../demux/tsdemuxer */ "./src/demux/tsdemuxer.ts"); + /* harmony import */ var _demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../demux/mp3demuxer */ "./src/demux/mp3demuxer.ts"); + /* harmony import */ var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../remux/mp4-remuxer */ "./src/remux/mp4-remuxer.ts"); + /* harmony import */ var _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../remux/passthrough-remuxer */ "./src/remux/passthrough-remuxer.ts"); + /* harmony import */ var _chunk_cache__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./chunk-cache */ "./src/demux/chunk-cache.ts"); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - _proto.destroy = function destroy() { - this._initPTS = this._initDTS = null; - this._duration = 0; - }; + var now; // performance.now() not available on WebWorker, at least on Safari Desktop - _proto.parseAVCPES = function parseAVCPES(pes, last) { - var _this = this; - - var track = this._avcTrack; - var units = this.parseAVCNALu(pes.data); - var debug = false; - var avcSample = this.avcSample; - var push; - var spsfound = false; // free pes.data to save up some memory - - pes.data = null; // if new NAL units found and last sample still there, let's push ... - // this helps parsing streams with missing AUD (only do this if AUD never found) - - if (avcSample && units.length && !track.audFound) { - pushAccessUnit(avcSample, track); - avcSample = this.avcSample = createAVCSample(false, pes.pts, pes.dts, ''); - } - - units.forEach(function (unit) { - switch (unit.type) { - // NDR - case 1: - { - push = true; - - if (!avcSample) { - avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, ''); + try { + now = self.performance.now.bind(self.performance); + } catch (err) { + _utils_logger__WEBPACK_IMPORTED_MODULE_11__["logger"].debug("Unable to use Performance API on this environment"); + now = self.Date.now; } - if (debug) { - avcSample.debug += 'NDR '; - } + var muxConfig = [ + { + demux: _demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__["default"], + remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"], + }, + { + demux: _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"], + remux: _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"], + }, + { + demux: _demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__["default"], + remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"], + }, + { + demux: _demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__["default"], + remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"], + }, + ]; + var minProbeByteLength = 1024; + muxConfig.forEach(function (_ref) { + var demux = _ref.demux; + minProbeByteLength = Math.max(minProbeByteLength, demux.minProbeByteLength); + }); - avcSample.frame = true; - var data = unit.data; // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...) - - if (spsfound && data.length > 4) { - // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR - var sliceType = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](data).readSliceType(); // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice - // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples. - // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice. - // I slice: A slice that is not an SI slice that is decoded using intra prediction only. - // if (sliceType === 2 || sliceType === 7) { - - if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) { - avcSample.key = true; + var Transmuxer = /*#__PURE__*/ (function () { + function Transmuxer(observer, typeSupported, config, vendor, id) { + this.observer = void 0; + this.typeSupported = void 0; + this.config = void 0; + this.vendor = void 0; + this.id = void 0; + this.demuxer = void 0; + this.remuxer = void 0; + this.decrypter = void 0; + this.probe = void 0; + this.decryptionPromise = null; + this.transmuxConfig = void 0; + this.currentTransmuxState = void 0; + this.cache = new _chunk_cache__WEBPACK_IMPORTED_MODULE_9__["default"](); + this.observer = observer; + this.typeSupported = typeSupported; + this.config = config; + this.vendor = vendor; + this.id = id; } - } - break; // IDR - } + var _proto = Transmuxer.prototype; - case 5: - push = true; // handle PES not starting with AUD + _proto.configure = function configure(transmuxConfig) { + this.transmuxConfig = transmuxConfig; - if (!avcSample) { - avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, ''); - } + if (this.decrypter) { + this.decrypter.reset(); + } + }; - if (debug) { - avcSample.debug += 'IDR '; - } + _proto.push = function push(data, decryptdata, chunkMeta, state) { + var _this = this; - avcSample.key = true; - avcSample.frame = true; - break; - // SEI + var stats = chunkMeta.transmuxing; + stats.executeStart = now(); + var uintData = new Uint8Array(data); + var cache = this.cache, + config = this.config, + currentTransmuxState = this.currentTransmuxState, + transmuxConfig = this.transmuxConfig; - case 6: - { - push = true; + if (state) { + this.currentTransmuxState = state; + } - if (debug && avcSample) { - avcSample.debug += 'SEI '; - } + var keyData = getEncryptionType(uintData, decryptdata); - var expGolombDecoder = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](discardEPB(unit.data)); // skip frameType + if (keyData && keyData.method === "AES-128") { + var decrypter = this.getDecrypter(); // Software decryption is synchronous; webCrypto is not - expGolombDecoder.readUByte(); - var payloadType = 0; - var payloadSize = 0; - var endOfCaptions = false; - var b = 0; + if (config.enableSoftwareAES) { + // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached + // data is handled in the flush() call + var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer); - while (!endOfCaptions && expGolombDecoder.bytesAvailable > 1) { - payloadType = 0; - - do { - b = expGolombDecoder.readUByte(); - payloadType += b; - } while (b === 0xff); // Parse payload size. - - - payloadSize = 0; - - do { - b = expGolombDecoder.readUByte(); - payloadSize += b; - } while (b === 0xff); // TODO: there can be more than one payload in an SEI packet... - // TODO: need to read type and size in a while loop to get them all - - - if (payloadType === 4 && expGolombDecoder.bytesAvailable !== 0) { - endOfCaptions = true; - var countryCode = expGolombDecoder.readUByte(); - - if (countryCode === 181) { - var providerCode = expGolombDecoder.readUShort(); - - if (providerCode === 49) { - var userStructure = expGolombDecoder.readUInt(); - - if (userStructure === 0x47413934) { - var userDataType = expGolombDecoder.readUByte(); // Raw CEA-608 bytes wrapped in CEA-708 packet - - if (userDataType === 3) { - var firstByte = expGolombDecoder.readUByte(); - var secondByte = expGolombDecoder.readUByte(); - var totalCCs = 31 & firstByte; - var byteArray = [firstByte, secondByte]; - - for (var i = 0; i < totalCCs; i++) { - // 3 bytes per CC - byteArray.push(expGolombDecoder.readUByte()); - byteArray.push(expGolombDecoder.readUByte()); - byteArray.push(expGolombDecoder.readUByte()); - } - - insertSampleInOrder(_this._txtTrack.samples, { - type: 3, - pts: pes.pts, - bytes: byteArray - }); - } + if (!decryptedData) { + stats.executeEnd = now(); + return emptyResult(chunkMeta); } + + uintData = new Uint8Array(decryptedData); + } else { + this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer).then(function (decryptedData) { + // Calling push here is important; if flush() is called while this is still resolving, this ensures that + // the decrypted data has been transmuxed + var result = _this.push(decryptedData, null, chunkMeta); + + _this.decryptionPromise = null; + return result; + }); + return this.decryptionPromise; } } - } else if (payloadType === 5 && expGolombDecoder.bytesAvailable !== 0) { - endOfCaptions = true; - if (payloadSize > 16) { - var uuidStrArray = []; + var _ref2 = state || currentTransmuxState, + contiguous = _ref2.contiguous, + discontinuity = _ref2.discontinuity, + trackSwitch = _ref2.trackSwitch, + accurateTimeOffset = _ref2.accurateTimeOffset, + timeOffset = _ref2.timeOffset; - for (var _i = 0; _i < 16; _i++) { - uuidStrArray.push(expGolombDecoder.readUByte().toString(16)); + var audioCodec = transmuxConfig.audioCodec, + videoCodec = transmuxConfig.videoCodec, + defaultInitPts = transmuxConfig.defaultInitPts, + duration = transmuxConfig.duration, + initSegmentData = transmuxConfig.initSegmentData; // Reset muxers before probing to ensure that their state is clean, even if flushing occurs before a successful probe - if (_i === 3 || _i === 5 || _i === 7 || _i === 9) { - uuidStrArray.push('-'); - } + if (discontinuity || trackSwitch) { + this.resetInitSegment(initSegmentData, audioCodec, videoCodec, duration); + } + + if (discontinuity) { + this.resetInitialTimestamp(defaultInitPts); + } + + if (!contiguous) { + this.resetContiguity(); + } + + if (this.needsProbing(uintData, discontinuity, trackSwitch)) { + if (cache.dataLength) { + var cachedData = cache.flush(); + uintData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_10__["appendUint8Array"])(cachedData, uintData); } - var length = payloadSize - 16; - var userDataPayloadBytes = new Uint8Array(length); + this.configureTransmuxer(uintData, transmuxConfig); + } - for (var _i2 = 0; _i2 < length; _i2++) { - userDataPayloadBytes[_i2] = expGolombDecoder.readUByte(); - } + var result = this.transmux(uintData, keyData, timeOffset, accurateTimeOffset, chunkMeta); + var currentState = this.currentTransmuxState; + currentState.contiguous = true; + currentState.discontinuity = false; + currentState.trackSwitch = false; + stats.executeEnd = now(); + return result; + }; // Due to data caching, flush calls can produce more than one TransmuxerResult (hence the Array type) - insertSampleInOrder(_this._txtTrack.samples, { - pts: pes.pts, - payloadType: payloadType, - uuid: uuidStrArray.join(''), - userData: Object(_id3__WEBPACK_IMPORTED_MODULE_3__["utf8ArrayToStr"])(userDataPayloadBytes), - userDataBytes: userDataPayloadBytes + _proto.flush = function flush(chunkMeta) { + var _this2 = this; + + var stats = chunkMeta.transmuxing; + stats.executeStart = now(); + var decrypter = this.decrypter, + cache = this.cache, + currentTransmuxState = this.currentTransmuxState, + decryptionPromise = this.decryptionPromise; + + if (decryptionPromise) { + // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore + // only flushing is required for async decryption + return decryptionPromise.then(function () { + return _this2.flush(chunkMeta); }); } - } else if (payloadSize < expGolombDecoder.bytesAvailable) { - for (var _i3 = 0; _i3 < payloadSize; _i3++) { - expGolombDecoder.readUByte(); + + var transmuxResults = []; + var timeOffset = currentTransmuxState.timeOffset; + + if (decrypter) { + // The decrypter may have data cached, which needs to be demuxed. In this case we'll have two TransmuxResults + // This happens in the case that we receive only 1 push call for a segment (either for non-progressive downloads, + // or for progressive downloads with small segments) + var decryptedData = decrypter.flush(); + + if (decryptedData) { + // Push always returns a TransmuxerResult if decryptdata is null + transmuxResults.push(this.push(decryptedData, null, chunkMeta)); + } } - } - } - break; // SPS - } + var bytesSeen = cache.dataLength; + cache.reset(); + var demuxer = this.demuxer, + remuxer = this.remuxer; - case 7: - push = true; - spsfound = true; + if (!demuxer || !remuxer) { + // If probing failed, and each demuxer saw enough bytes to be able to probe, then CiderHls.js has been given content its not able to handle + if (bytesSeen >= minProbeByteLength) { + this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_PARSING_ERROR, + fatal: true, + reason: "no demux matching with content found", + }); + } - if (debug && avcSample) { - avcSample.debug += 'SPS '; - } + stats.executeEnd = now(); + return [emptyResult(chunkMeta)]; + } - if (!track.sps) { - var _expGolombDecoder = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](unit.data); + var demuxResultOrPromise = demuxer.flush(timeOffset); - var config = _expGolombDecoder.readSPS(); + if (isPromise(demuxResultOrPromise)) { + // Decrypt final SAMPLE-AES samples + return demuxResultOrPromise.then(function (demuxResult) { + _this2.flushRemux(transmuxResults, demuxResult, chunkMeta); - track.width = config.width; - track.height = config.height; - track.pixelRatio = config.pixelRatio; // TODO: `track.sps` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`. + return transmuxResults; + }); + } - track.sps = [unit.data]; - track.duration = _this._duration; - var codecarray = unit.data.subarray(1, 4); - var codecstring = 'avc1.'; + this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta); + return transmuxResults; + }; - for (var _i4 = 0; _i4 < 3; _i4++) { - var h = codecarray[_i4].toString(16); + _proto.flushRemux = function flushRemux(transmuxResults, demuxResult, chunkMeta) { + var audioTrack = demuxResult.audioTrack, + avcTrack = demuxResult.avcTrack, + id3Track = demuxResult.id3Track, + textTrack = demuxResult.textTrack; + var _this$currentTransmux = this.currentTransmuxState, + accurateTimeOffset = _this$currentTransmux.accurateTimeOffset, + timeOffset = _this$currentTransmux.timeOffset; + _utils_logger__WEBPACK_IMPORTED_MODULE_11__["logger"].log("[transmuxer.ts]: Flushed fragment " + chunkMeta.sn + (chunkMeta.part > -1 ? " p: " + chunkMeta.part : "") + " of level " + chunkMeta.level); + var remuxResult = this.remuxer.remux(audioTrack, avcTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id); + transmuxResults.push({ + remuxResult: remuxResult, + chunkMeta: chunkMeta, + }); + chunkMeta.transmuxing.executeEnd = now(); + }; - if (h.length < 2) { - h = '0' + h; + _proto.resetInitialTimestamp = function resetInitialTimestamp(defaultInitPts) { + var demuxer = this.demuxer, + remuxer = this.remuxer; + + if (!demuxer || !remuxer) { + return; + } + + demuxer.resetTimeStamp(defaultInitPts); + remuxer.resetTimeStamp(defaultInitPts); + }; + + _proto.resetContiguity = function resetContiguity() { + var demuxer = this.demuxer, + remuxer = this.remuxer; + + if (!demuxer || !remuxer) { + return; + } + + demuxer.resetContiguity(); + remuxer.resetNextTimestamp(); + }; + + _proto.resetInitSegment = function resetInitSegment(initSegmentData, audioCodec, videoCodec, duration) { + var demuxer = this.demuxer, + remuxer = this.remuxer; + + if (!demuxer || !remuxer) { + return; + } + + demuxer.resetInitSegment(audioCodec, videoCodec, duration); + remuxer.resetInitSegment(initSegmentData, audioCodec, videoCodec); + }; + + _proto.destroy = function destroy() { + if (this.demuxer) { + this.demuxer.destroy(); + this.demuxer = undefined; + } + + if (this.remuxer) { + this.remuxer.destroy(); + this.remuxer = undefined; + } + }; + + _proto.transmux = function transmux(data, keyData, timeOffset, accurateTimeOffset, chunkMeta) { + var result; + + if (keyData && keyData.method === "SAMPLE-AES") { + result = this.transmuxSampleAes(data, keyData, timeOffset, accurateTimeOffset, chunkMeta); + } else { + result = this.transmuxUnencrypted(data, timeOffset, accurateTimeOffset, chunkMeta); + } + + return result; + }; + + _proto.transmuxUnencrypted = function transmuxUnencrypted(data, timeOffset, accurateTimeOffset, chunkMeta) { + var _demux = this.demuxer.demux(data, timeOffset, false, !this.config.progressive), + audioTrack = _demux.audioTrack, + avcTrack = _demux.avcTrack, + id3Track = _demux.id3Track, + textTrack = _demux.textTrack; + + var remuxResult = this.remuxer.remux(audioTrack, avcTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, false, this.id); + return { + remuxResult: remuxResult, + chunkMeta: chunkMeta, + }; + }; + + _proto.transmuxSampleAes = function transmuxSampleAes(data, decryptData, timeOffset, accurateTimeOffset, chunkMeta) { + var _this3 = this; + + return this.demuxer.demuxSampleAes(data, decryptData, timeOffset).then(function (demuxResult) { + var remuxResult = _this3.remuxer.remux(demuxResult.audioTrack, demuxResult.avcTrack, demuxResult.id3Track, demuxResult.textTrack, timeOffset, accurateTimeOffset, false, _this3.id); + + return { + remuxResult: remuxResult, + chunkMeta: chunkMeta, + }; + }); + }; + + _proto.configureTransmuxer = function configureTransmuxer(data, transmuxConfig) { + var config = this.config, + observer = this.observer, + typeSupported = this.typeSupported, + vendor = this.vendor; + var audioCodec = transmuxConfig.audioCodec, + defaultInitPts = transmuxConfig.defaultInitPts, + duration = transmuxConfig.duration, + initSegmentData = transmuxConfig.initSegmentData, + videoCodec = transmuxConfig.videoCodec; // probe for content type + + var mux; + + for (var i = 0, len = muxConfig.length; i < len; i++) { + if (muxConfig[i].demux.probe(data)) { + mux = muxConfig[i]; + break; + } + } + + if (!mux) { + // If probing previous configs fail, use mp4 passthrough + _utils_logger__WEBPACK_IMPORTED_MODULE_11__["logger"].warn("Failed to find demuxer by probing frag, treating as mp4 passthrough"); + mux = { + demux: _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"], + remux: _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"], + }; + } // so let's check that current remuxer and demuxer are still valid + + var demuxer = this.demuxer; + var remuxer = this.remuxer; + var Remuxer = mux.remux; + var Demuxer = mux.demux; + + if (!remuxer || !(remuxer instanceof Remuxer)) { + this.remuxer = new Remuxer(observer, config, typeSupported, vendor); + } + + if (!demuxer || !(demuxer instanceof Demuxer)) { + this.demuxer = new Demuxer(observer, config, typeSupported); + this.probe = Demuxer.probe; + } // Ensure that muxers are always initialized with an initSegment + + this.resetInitSegment(initSegmentData, audioCodec, videoCodec, duration); + this.resetInitialTimestamp(defaultInitPts); + }; + + _proto.needsProbing = function needsProbing(data, discontinuity, trackSwitch) { + // in case of continuity change, or track switch + // we might switch from content type (AAC container to TS container, or TS to fmp4 for example) + return !this.demuxer || !this.remuxer || discontinuity || trackSwitch; + }; + + _proto.getDecrypter = function getDecrypter() { + var decrypter = this.decrypter; + + if (!decrypter) { + decrypter = this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, this.config); + } + + return decrypter; + }; + + return Transmuxer; + })(); + + function getEncryptionType(data, decryptData) { + var encryptionType = null; + + if (data.byteLength > 0 && decryptData != null && decryptData.key != null && decryptData.iv !== null && decryptData.method != null) { + encryptionType = decryptData; } - codecstring += h; + return encryptionType; } - track.codec = codecstring; - } + var emptyResult = function emptyResult(chunkMeta) { + return { + remuxResult: {}, + chunkMeta: chunkMeta, + }; + }; - break; - // PPS + function isPromise(p) { + return "then" in p && p.then instanceof Function; + } + var TransmuxConfig = function TransmuxConfig(audioCodec, videoCodec, initSegmentData, duration, defaultInitPts) { + this.audioCodec = void 0; + this.videoCodec = void 0; + this.initSegmentData = void 0; + this.duration = void 0; + this.defaultInitPts = void 0; + this.audioCodec = audioCodec; + this.videoCodec = videoCodec; + this.initSegmentData = initSegmentData; + this.duration = duration; + this.defaultInitPts = defaultInitPts; + }; + var TransmuxState = function TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset) { + this.discontinuity = void 0; + this.contiguous = void 0; + this.accurateTimeOffset = void 0; + this.trackSwitch = void 0; + this.timeOffset = void 0; + this.discontinuity = discontinuity; + this.contiguous = contiguous; + this.accurateTimeOffset = accurateTimeOffset; + this.trackSwitch = trackSwitch; + this.timeOffset = timeOffset; + }; - case 8: - push = true; + /***/ + }, - if (debug && avcSample) { - avcSample.debug += 'PPS '; - } + /***/ "./src/demux/tsdemuxer.ts": + /*!********************************!*\ + !*** ./src/demux/tsdemuxer.ts ***! + \********************************/ + /*! exports provided: discardEPB, default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "discardEPB", function () { + return discardEPB; + }); + /* harmony import */ var _adts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./adts */ "./src/demux/adts.ts"); + /* harmony import */ var _mpegaudio__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mpegaudio */ "./src/demux/mpegaudio.ts"); + /* harmony import */ var _exp_golomb__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./exp-golomb */ "./src/demux/exp-golomb.ts"); + /* harmony import */ var _id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./id3 */ "./src/demux/id3.ts"); + /* harmony import */ var _sample_aes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./sample-aes */ "./src/demux/sample-aes.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /** + * highly optimized TS demuxer: + * parse PAT, PMT + * extract PES packet from audio and video PIDs + * extract AVC/H264 NAL units and AAC/ADTS samples from PES packet + * trigger the remuxer upon parsing completion + * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource. + * it also controls the remuxing process : + * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state. + */ - if (!track.pps) { - // TODO: `track.pss` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`. - track.pps = [unit.data]; - } + // We are using fixed track IDs for driving the MP4 remuxer + // instead of following the TS PIDs. + // There is no reason not to do this and some browsers/SourceBuffer-demuxers + // may not like if there are TrackID "switches" + // See https://github.com/video-dev/CiderHls.js/issues/1331 + // Here we are mapping our internal track types to constant MP4 track IDs + // With MSE currently one can only have one track of each, and we are muxing + // whatever video/audio rendition in them. + var RemuxerTrackIdConfig = { + video: 1, + audio: 2, + id3: 3, + text: 4, + }; - break; - // AUD - - case 9: - push = false; - track.audFound = true; - - if (avcSample) { - pushAccessUnit(avcSample, track); - } - - avcSample = _this.avcSample = createAVCSample(false, pes.pts, pes.dts, debug ? 'AUD ' : ''); - break; - // Filler Data - - case 12: - push = false; - break; - - default: - push = false; - - if (avcSample) { - avcSample.debug += 'unknown NAL ' + unit.type + ' '; - } - - break; - } - - if (avcSample && push) { - var _units = avcSample.units; - - _units.push(unit); - } - }); // if last PES packet, push samples - - if (last && avcSample) { - pushAccessUnit(avcSample, track); - this.avcSample = null; - } - }; - - _proto.getLastNalUnit = function getLastNalUnit() { - var _avcSample; - - var avcSample = this.avcSample; - var lastUnit; // try to fallback to previous sample if current one is empty - - if (!avcSample || avcSample.units.length === 0) { - var samples = this._avcTrack.samples; - avcSample = samples[samples.length - 1]; - } - - if ((_avcSample = avcSample) !== null && _avcSample !== void 0 && _avcSample.units) { - var units = avcSample.units; - lastUnit = units[units.length - 1]; - } - - return lastUnit; - }; - - _proto.parseAVCNALu = function parseAVCNALu(array) { - var len = array.byteLength; - var track = this._avcTrack; - var state = track.naluState || 0; - var lastState = state; - var units = []; - var i = 0; - var value; - var overflow; - var unitType; - var lastUnitStart = -1; - var lastUnitType = 0; // logger.log('PES:' + Hex.hexDump(array)); - - if (state === -1) { - // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet - lastUnitStart = 0; // NALu type is value read from offset 0 - - lastUnitType = array[0] & 0x1f; - state = 0; - i = 1; - } - - while (i < len) { - value = array[i++]; // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case - - if (!state) { - state = value ? 0 : 1; - continue; - } - - if (state === 1) { - state = value ? 0 : 2; - continue; - } // here we have state either equal to 2 or 3 - - - if (!value) { - state = 3; - } else if (value === 1) { - if (lastUnitStart >= 0) { - var unit = { - data: array.subarray(lastUnitStart, i - state - 1), - type: lastUnitType - }; // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength); - - units.push(unit); - } else { - // lastUnitStart is undefined => this is the first start code found in this PES packet - // first check if start code delimiter is overlapping between 2 PES packets, - // ie it started in last packet (lastState not zero) - // and ended at the beginning of this PES packet (i <= 4 - lastState) - var lastUnit = this.getLastNalUnit(); - - if (lastUnit) { - if (lastState && i <= 4 - lastState) { - // start delimiter overlapping between PES packets - // strip start delimiter bytes from the end of last NAL unit - // check if lastUnit had a state different from zero - if (lastUnit.state) { - // strip last bytes - lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState); + var TSDemuxer = /*#__PURE__*/ (function () { + function TSDemuxer(observer, config, typeSupported) { + this.observer = void 0; + this.config = void 0; + this.typeSupported = void 0; + this.sampleAes = null; + this.pmtParsed = false; + this.audioCodec = void 0; + this.videoCodec = void 0; + this._duration = 0; + this.aacLastPTS = null; + this._initPTS = null; + this._initDTS = null; + this._pmtId = -1; + this._avcTrack = void 0; + this._audioTrack = void 0; + this._id3Track = void 0; + this._txtTrack = void 0; + this.aacOverFlow = null; + this.avcSample = null; + this.remainderData = null; + this.observer = observer; + this.config = config; + this.typeSupported = typeSupported; } - } // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit. + TSDemuxer.probe = function probe(data) { + var syncOffset = TSDemuxer.syncOffset(data); - overflow = i - state - 1; + if (syncOffset < 0) { + return false; + } else { + if (syncOffset) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("MPEG2-TS detected but first sync word found @ offset " + syncOffset + ", junk ahead ?"); + } - if (overflow > 0) { - // logger.log('first NALU found with overflow:' + overflow); - var tmp = new Uint8Array(lastUnit.data.byteLength + overflow); - tmp.set(lastUnit.data, 0); - tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength); - lastUnit.data = tmp; - lastUnit.state = 0; + return true; + } + }; + + TSDemuxer.syncOffset = function syncOffset(data) { + // scan 1000 first bytes + var scanwindow = Math.min(1000, data.length - 3 * 188); + var i = 0; + + while (i < scanwindow) { + // a TS fragment should contain at least 3 TS packets, a PAT, a PMT, and one PID, each starting with 0x47 + if (data[i] === 0x47 && data[i + 188] === 0x47 && data[i + 2 * 188] === 0x47) { + return i; + } else { + i++; + } + } + + return -1; + }; + /** + * Creates a track model internal to demuxer used to drive remuxing input + * + * @param type 'audio' | 'video' | 'id3' | 'text' + * @param duration + * @return TSDemuxer's internal track model + */ + + TSDemuxer.createTrack = function createTrack(type, duration) { + return { + container: type === "video" || type === "audio" ? "video/mp2t" : undefined, + type: type, + id: RemuxerTrackIdConfig[type], + pid: -1, + inputTimeScale: 90000, + sequenceNumber: 0, + samples: [], + dropped: 0, + duration: type === "audio" ? duration : undefined, + }; + }; + /** + * Initializes a new init segment on the demuxer/remuxer interface. Needed for discontinuities/track-switches (or at stream start) + * Resets all internal track instances of the demuxer. + */ + + var _proto = TSDemuxer.prototype; + + _proto.resetInitSegment = function resetInitSegment(audioCodec, videoCodec, duration) { + this.pmtParsed = false; + this._pmtId = -1; + this._avcTrack = TSDemuxer.createTrack("video", duration); + this._audioTrack = TSDemuxer.createTrack("audio", duration); + this._id3Track = TSDemuxer.createTrack("id3", duration); + this._txtTrack = TSDemuxer.createTrack("text", duration); + this._audioTrack.isAAC = true; // flush any partial content + + this.aacOverFlow = null; + this.aacLastPTS = null; + this.avcSample = null; + this.audioCodec = audioCodec; + this.videoCodec = videoCodec; + this._duration = duration; + }; + + _proto.resetTimeStamp = function resetTimeStamp() {}; + + _proto.resetContiguity = function resetContiguity() { + var _audioTrack = this._audioTrack, + _avcTrack = this._avcTrack, + _id3Track = this._id3Track; + + if (_audioTrack) { + _audioTrack.pesData = null; + } + + if (_avcTrack) { + _avcTrack.pesData = null; + } + + if (_id3Track) { + _id3Track.pesData = null; + } + + this.aacOverFlow = null; + this.aacLastPTS = null; + }; + + _proto.demux = function demux(data, timeOffset, isSampleAes, flush) { + if (isSampleAes === void 0) { + isSampleAes = false; + } + + if (flush === void 0) { + flush = false; + } + + if (!isSampleAes) { + this.sampleAes = null; + } + + var pes; + var avcTrack = this._avcTrack; + var audioTrack = this._audioTrack; + var id3Track = this._id3Track; + var avcId = avcTrack.pid; + var avcData = avcTrack.pesData; + var audioId = audioTrack.pid; + var id3Id = id3Track.pid; + var audioData = audioTrack.pesData; + var id3Data = id3Track.pesData; + var unknownPIDs = false; + var pmtParsed = this.pmtParsed; + var pmtId = this._pmtId; + var len = data.length; + + if (this.remainderData) { + data = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_6__["appendUint8Array"])(this.remainderData, data); + len = data.length; + this.remainderData = null; + } + + if (len < 188 && !flush) { + this.remainderData = data; + return { + audioTrack: audioTrack, + avcTrack: avcTrack, + id3Track: id3Track, + textTrack: this._txtTrack, + }; + } + + var syncOffset = Math.max(0, TSDemuxer.syncOffset(data)); + len -= (len + syncOffset) % 188; + + if (len < data.byteLength && !flush) { + this.remainderData = new Uint8Array(data.buffer, len, data.buffer.byteLength - len); + } // loop through TS packets + + for (var start = syncOffset; start < len; start += 188) { + if (data[start] === 0x47) { + var stt = !!(data[start + 1] & 0x40); // pid is a 13-bit field starting at the last bit of TS[1] + + var pid = ((data[start + 1] & 0x1f) << 8) + data[start + 2]; + var atf = (data[start + 3] & 0x30) >> 4; // if an adaption field is present, its length is specified by the fifth byte of the TS packet header. + + var offset = void 0; + + if (atf > 1) { + offset = start + 5 + data[start + 4]; // continue if there is only adaptation field + + if (offset === start + 188) { + continue; + } + } else { + offset = start + 4; + } + + switch (pid) { + case avcId: + if (stt) { + if (avcData && (pes = parsePES(avcData))) { + this.parseAVCPES(pes, false); + } + + avcData = { + data: [], + size: 0, + }; + } + + if (avcData) { + avcData.data.push(data.subarray(offset, start + 188)); + avcData.size += start + 188 - offset; + } + + break; + + case audioId: + if (stt) { + if (audioData && (pes = parsePES(audioData))) { + if (audioTrack.isAAC) { + this.parseAACPES(pes); + } else { + this.parseMPEGPES(pes); + } + } + + audioData = { + data: [], + size: 0, + }; + } + + if (audioData) { + audioData.data.push(data.subarray(offset, start + 188)); + audioData.size += start + 188 - offset; + } + + break; + + case id3Id: + if (stt) { + if (id3Data && (pes = parsePES(id3Data))) { + this.parseID3PES(pes); + } + + id3Data = { + data: [], + size: 0, + }; + } + + if (id3Data) { + id3Data.data.push(data.subarray(offset, start + 188)); + id3Data.size += start + 188 - offset; + } + + break; + + case 0: + if (stt) { + offset += data[offset] + 1; + } + + pmtId = this._pmtId = parsePAT(data, offset); + break; + + case pmtId: { + if (stt) { + offset += data[offset] + 1; + } + + var parsedPIDs = parsePMT(data, offset, this.typeSupported.mpeg === true || this.typeSupported.mp3 === true, isSampleAes); // only update track id if track PID found while parsing PMT + // this is to avoid resetting the PID to -1 in case + // track PID transiently disappears from the stream + // this could happen in case of transient missing audio samples for example + // NOTE this is only the PID of the track as found in TS, + // but we are not using this for MP4 track IDs. + + avcId = parsedPIDs.avc; + + if (avcId > 0) { + avcTrack.pid = avcId; + } + + audioId = parsedPIDs.audio; + + if (audioId > 0) { + audioTrack.pid = audioId; + audioTrack.isAAC = parsedPIDs.isAAC; + } + + id3Id = parsedPIDs.id3; + + if (id3Id > 0) { + id3Track.pid = id3Id; + } + + if (unknownPIDs && !pmtParsed) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log("reparse from beginning"); + unknownPIDs = false; // we set it to -188, the += 188 in the for loop will reset start to 0 + + start = syncOffset - 188; + } + + pmtParsed = this.pmtParsed = true; + break; + } + + case 17: + case 0x1fff: + break; + + default: + unknownPIDs = true; + break; + } + } else { + this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorDetails"].FRAG_PARSING_ERROR, + fatal: false, + reason: "TS packet did not start with 0x47", + }); + } + } + + avcTrack.pesData = avcData; + audioTrack.pesData = audioData; + id3Track.pesData = id3Data; + var demuxResult = { + audioTrack: audioTrack, + avcTrack: avcTrack, + id3Track: id3Track, + textTrack: this._txtTrack, + }; + + if (flush) { + this.extractRemainingSamples(demuxResult); + } + + return demuxResult; + }; + + _proto.flush = function flush() { + var remainderData = this.remainderData; + this.remainderData = null; + var result; + + if (remainderData) { + result = this.demux(remainderData, -1, false, true); + } else { + result = { + audioTrack: this._audioTrack, + avcTrack: this._avcTrack, + textTrack: this._txtTrack, + id3Track: this._id3Track, + }; + } + + this.extractRemainingSamples(result); + + if (this.sampleAes) { + return this.decrypt(result, this.sampleAes); + } + + return result; + }; + + _proto.extractRemainingSamples = function extractRemainingSamples(demuxResult) { + var audioTrack = demuxResult.audioTrack, + avcTrack = demuxResult.avcTrack, + id3Track = demuxResult.id3Track; + var avcData = avcTrack.pesData; + var audioData = audioTrack.pesData; + var id3Data = id3Track.pesData; // try to parse last PES packets + + var pes; + + if (avcData && (pes = parsePES(avcData))) { + this.parseAVCPES(pes, true); + avcTrack.pesData = null; + } else { + // either avcData null or PES truncated, keep it for next frag parsing + avcTrack.pesData = avcData; + } + + if (audioData && (pes = parsePES(audioData))) { + if (audioTrack.isAAC) { + this.parseAACPES(pes); + } else { + this.parseMPEGPES(pes); + } + + audioTrack.pesData = null; + } else { + if (audioData !== null && audioData !== void 0 && audioData.size) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log("last AAC PES packet truncated,might overlap between fragments"); + } // either audioData null or PES truncated, keep it for next frag parsing + + audioTrack.pesData = audioData; + } + + if (id3Data && (pes = parsePES(id3Data))) { + this.parseID3PES(pes); + id3Track.pesData = null; + } else { + // either id3Data null or PES truncated, keep it for next frag parsing + id3Track.pesData = id3Data; + } + }; + + _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) { + var demuxResult = this.demux(data, timeOffset, true, !this.config.progressive); + var sampleAes = (this.sampleAes = new _sample_aes__WEBPACK_IMPORTED_MODULE_4__["default"](this.observer, this.config, keyData)); + return this.decrypt(demuxResult, sampleAes); + }; + + _proto.decrypt = function decrypt(demuxResult, sampleAes) { + return new Promise(function (resolve) { + var audioTrack = demuxResult.audioTrack, + avcTrack = demuxResult.avcTrack; + + if (audioTrack.samples && audioTrack.isAAC) { + sampleAes.decryptAacSamples(audioTrack.samples, 0, function () { + if (avcTrack.samples) { + sampleAes.decryptAvcSamples(avcTrack.samples, 0, 0, function () { + resolve(demuxResult); + }); + } else { + resolve(demuxResult); + } + }); + } else if (avcTrack.samples) { + sampleAes.decryptAvcSamples(avcTrack.samples, 0, 0, function () { + resolve(demuxResult); + }); + } + }); + }; + + _proto.destroy = function destroy() { + this._initPTS = this._initDTS = null; + this._duration = 0; + }; + + _proto.parseAVCPES = function parseAVCPES(pes, last) { + var _this = this; + + var track = this._avcTrack; + var units = this.parseAVCNALu(pes.data); + var debug = false; + var avcSample = this.avcSample; + var push; + var spsfound = false; // free pes.data to save up some memory + + pes.data = null; // if new NAL units found and last sample still there, let's push ... + // this helps parsing streams with missing AUD (only do this if AUD never found) + + if (avcSample && units.length && !track.audFound) { + pushAccessUnit(avcSample, track); + avcSample = this.avcSample = createAVCSample(false, pes.pts, pes.dts, ""); + } + + units.forEach(function (unit) { + switch (unit.type) { + // NDR + case 1: { + push = true; + + if (!avcSample) { + avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, ""); + } + + if (debug) { + avcSample.debug += "NDR "; + } + + avcSample.frame = true; + var data = unit.data; // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...) + + if (spsfound && data.length > 4) { + // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR + var sliceType = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](data).readSliceType(); // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice + // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples. + // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice. + // I slice: A slice that is not an SI slice that is decoded using intra prediction only. + // if (sliceType === 2 || sliceType === 7) { + + if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) { + avcSample.key = true; + } + } + + break; // IDR + } + + case 5: + push = true; // handle PES not starting with AUD + + if (!avcSample) { + avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, ""); + } + + if (debug) { + avcSample.debug += "IDR "; + } + + avcSample.key = true; + avcSample.frame = true; + break; + // SEI + + case 6: { + push = true; + + if (debug && avcSample) { + avcSample.debug += "SEI "; + } + + var expGolombDecoder = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](discardEPB(unit.data)); // skip frameType + + expGolombDecoder.readUByte(); + var payloadType = 0; + var payloadSize = 0; + var endOfCaptions = false; + var b = 0; + + while (!endOfCaptions && expGolombDecoder.bytesAvailable > 1) { + payloadType = 0; + + do { + b = expGolombDecoder.readUByte(); + payloadType += b; + } while (b === 0xff); // Parse payload size. + + payloadSize = 0; + + do { + b = expGolombDecoder.readUByte(); + payloadSize += b; + } while (b === 0xff); // TODO: there can be more than one payload in an SEI packet... + // TODO: need to read type and size in a while loop to get them all + + if (payloadType === 4 && expGolombDecoder.bytesAvailable !== 0) { + endOfCaptions = true; + var countryCode = expGolombDecoder.readUByte(); + + if (countryCode === 181) { + var providerCode = expGolombDecoder.readUShort(); + + if (providerCode === 49) { + var userStructure = expGolombDecoder.readUInt(); + + if (userStructure === 0x47413934) { + var userDataType = expGolombDecoder.readUByte(); // Raw CEA-608 bytes wrapped in CEA-708 packet + + if (userDataType === 3) { + var firstByte = expGolombDecoder.readUByte(); + var secondByte = expGolombDecoder.readUByte(); + var totalCCs = 31 & firstByte; + var byteArray = [firstByte, secondByte]; + + for (var i = 0; i < totalCCs; i++) { + // 3 bytes per CC + byteArray.push(expGolombDecoder.readUByte()); + byteArray.push(expGolombDecoder.readUByte()); + byteArray.push(expGolombDecoder.readUByte()); + } + + insertSampleInOrder(_this._txtTrack.samples, { + type: 3, + pts: pes.pts, + bytes: byteArray, + }); + } + } + } + } + } else if (payloadType === 5 && expGolombDecoder.bytesAvailable !== 0) { + endOfCaptions = true; + + if (payloadSize > 16) { + var uuidStrArray = []; + + for (var _i = 0; _i < 16; _i++) { + uuidStrArray.push(expGolombDecoder.readUByte().toString(16)); + + if (_i === 3 || _i === 5 || _i === 7 || _i === 9) { + uuidStrArray.push("-"); + } + } + + var length = payloadSize - 16; + var userDataPayloadBytes = new Uint8Array(length); + + for (var _i2 = 0; _i2 < length; _i2++) { + userDataPayloadBytes[_i2] = expGolombDecoder.readUByte(); + } + + insertSampleInOrder(_this._txtTrack.samples, { + pts: pes.pts, + payloadType: payloadType, + uuid: uuidStrArray.join(""), + userData: Object(_id3__WEBPACK_IMPORTED_MODULE_3__["utf8ArrayToStr"])(userDataPayloadBytes), + userDataBytes: userDataPayloadBytes, + }); + } + } else if (payloadSize < expGolombDecoder.bytesAvailable) { + for (var _i3 = 0; _i3 < payloadSize; _i3++) { + expGolombDecoder.readUByte(); + } + } + } + + break; // SPS + } + + case 7: + push = true; + spsfound = true; + + if (debug && avcSample) { + avcSample.debug += "SPS "; + } + + if (!track.sps) { + var _expGolombDecoder = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](unit.data); + + var config = _expGolombDecoder.readSPS(); + + track.width = config.width; + track.height = config.height; + track.pixelRatio = config.pixelRatio; // TODO: `track.sps` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`. + + track.sps = [unit.data]; + track.duration = _this._duration; + var codecarray = unit.data.subarray(1, 4); + var codecstring = "avc1."; + + for (var _i4 = 0; _i4 < 3; _i4++) { + var h = codecarray[_i4].toString(16); + + if (h.length < 2) { + h = "0" + h; + } + + codecstring += h; + } + + track.codec = codecstring; + } + + break; + // PPS + + case 8: + push = true; + + if (debug && avcSample) { + avcSample.debug += "PPS "; + } + + if (!track.pps) { + // TODO: `track.pss` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`. + track.pps = [unit.data]; + } + + break; + // AUD + + case 9: + push = false; + track.audFound = true; + + if (avcSample) { + pushAccessUnit(avcSample, track); + } + + avcSample = _this.avcSample = createAVCSample(false, pes.pts, pes.dts, debug ? "AUD " : ""); + break; + // Filler Data + + case 12: + push = false; + break; + + default: + push = false; + + if (avcSample) { + avcSample.debug += "unknown NAL " + unit.type + " "; + } + + break; + } + + if (avcSample && push) { + var _units = avcSample.units; + + _units.push(unit); + } + }); // if last PES packet, push samples + + if (last && avcSample) { + pushAccessUnit(avcSample, track); + this.avcSample = null; + } + }; + + _proto.getLastNalUnit = function getLastNalUnit() { + var _avcSample; + + var avcSample = this.avcSample; + var lastUnit; // try to fallback to previous sample if current one is empty + + if (!avcSample || avcSample.units.length === 0) { + var samples = this._avcTrack.samples; + avcSample = samples[samples.length - 1]; + } + + if ((_avcSample = avcSample) !== null && _avcSample !== void 0 && _avcSample.units) { + var units = avcSample.units; + lastUnit = units[units.length - 1]; + } + + return lastUnit; + }; + + _proto.parseAVCNALu = function parseAVCNALu(array) { + var len = array.byteLength; + var track = this._avcTrack; + var state = track.naluState || 0; + var lastState = state; + var units = []; + var i = 0; + var value; + var overflow; + var unitType; + var lastUnitStart = -1; + var lastUnitType = 0; // logger.log('PES:' + Hex.hexDump(array)); + + if (state === -1) { + // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet + lastUnitStart = 0; // NALu type is value read from offset 0 + + lastUnitType = array[0] & 0x1f; + state = 0; + i = 1; + } + + while (i < len) { + value = array[i++]; // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case + + if (!state) { + state = value ? 0 : 1; + continue; + } + + if (state === 1) { + state = value ? 0 : 2; + continue; + } // here we have state either equal to 2 or 3 + + if (!value) { + state = 3; + } else if (value === 1) { + if (lastUnitStart >= 0) { + var unit = { + data: array.subarray(lastUnitStart, i - state - 1), + type: lastUnitType, + }; // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength); + + units.push(unit); + } else { + // lastUnitStart is undefined => this is the first start code found in this PES packet + // first check if start code delimiter is overlapping between 2 PES packets, + // ie it started in last packet (lastState not zero) + // and ended at the beginning of this PES packet (i <= 4 - lastState) + var lastUnit = this.getLastNalUnit(); + + if (lastUnit) { + if (lastState && i <= 4 - lastState) { + // start delimiter overlapping between PES packets + // strip start delimiter bytes from the end of last NAL unit + // check if lastUnit had a state different from zero + if (lastUnit.state) { + // strip last bytes + lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState); + } + } // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit. + + overflow = i - state - 1; + + if (overflow > 0) { + // logger.log('first NALU found with overflow:' + overflow); + var tmp = new Uint8Array(lastUnit.data.byteLength + overflow); + tmp.set(lastUnit.data, 0); + tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength); + lastUnit.data = tmp; + lastUnit.state = 0; + } + } + } // check if we can read unit type + + if (i < len) { + unitType = array[i] & 0x1f; // logger.log('find NALU @ offset:' + i + ',type:' + unitType); + + lastUnitStart = i; + lastUnitType = unitType; + state = 0; + } else { + // not enough byte to read unit type. let's read it on next PES parsing + state = -1; + } + } else { + state = 0; + } + } + + if (lastUnitStart >= 0 && state >= 0) { + var _unit = { + data: array.subarray(lastUnitStart, len), + type: lastUnitType, + state: state, + }; + units.push(_unit); // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state); + } // no NALu found + + if (units.length === 0) { + // append pes.data to previous NAL unit + var _lastUnit = this.getLastNalUnit(); + + if (_lastUnit) { + var _tmp = new Uint8Array(_lastUnit.data.byteLength + array.byteLength); + + _tmp.set(_lastUnit.data, 0); + + _tmp.set(array, _lastUnit.data.byteLength); + + _lastUnit.data = _tmp; + } + } + + track.naluState = state; + return units; + }; + + _proto.parseAACPES = function parseAACPES(pes) { + var startOffset = 0; + var track = this._audioTrack; + var aacOverFlow = this.aacOverFlow; + var data = pes.data; + + if (aacOverFlow) { + this.aacOverFlow = null; + var sampleLength = aacOverFlow.sample.unit.byteLength; + var frameMissingBytes = Math.min(aacOverFlow.missing, sampleLength); + var frameOverflowBytes = sampleLength - frameMissingBytes; + aacOverFlow.sample.unit.set(data.subarray(0, frameMissingBytes), frameOverflowBytes); + track.samples.push(aacOverFlow.sample); // logger.log(`AAC: append overflowing ${frameOverflowBytes} bytes to beginning of new PES`); + + startOffset = aacOverFlow.missing; + } // look for ADTS header (0xFFFx) + + var offset; + var len; + + for (offset = startOffset, len = data.length; offset < len - 1; offset++) { + if (_adts__WEBPACK_IMPORTED_MODULE_0__["isHeader"](data, offset)) { + break; + } + } // if ADTS header does not start straight from the beginning of the PES payload, raise an error + + if (offset !== startOffset) { + var reason; + var fatal; + + if (offset < len - 1) { + reason = "AAC PES did not start with ADTS header,offset:" + offset; + fatal = false; + } else { + reason = "no ADTS header found in AAC PES"; + fatal = true; + } + + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("parsing error:" + reason); + this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorTypes"].MEDIA_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorDetails"].FRAG_PARSING_ERROR, + fatal: fatal, + reason: reason, + }); + + if (fatal) { + return; + } + } + + _adts__WEBPACK_IMPORTED_MODULE_0__["initTrackConfig"](track, this.observer, data, offset, this.audioCodec); + var pts; + + if (pes.pts !== undefined) { + pts = pes.pts; + } else if (aacOverFlow) { + // if last AAC frame is overflowing, we should ensure timestamps are contiguous: + // first sample PTS should be equal to last sample PTS + frameDuration + var frameDuration = _adts__WEBPACK_IMPORTED_MODULE_0__["getFrameDuration"](track.samplerate); + pts = aacOverFlow.sample.pts + frameDuration; + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("[tsdemuxer]: AAC PES unknown PTS"); + return; + } // scan for aac samples + + var frameIndex = 0; + + while (offset < len) { + if (_adts__WEBPACK_IMPORTED_MODULE_0__["isHeader"](data, offset)) { + if (offset + 5 < len) { + var frame = _adts__WEBPACK_IMPORTED_MODULE_0__["appendFrame"](track, data, offset, pts, frameIndex); + + if (frame) { + if (frame.missing) { + this.aacOverFlow = frame; + } else { + offset += frame.length; + frameIndex++; + continue; + } + } + } // We are at an ADTS header, but do not have enough data for a frame + // Remaining data will be added to aacOverFlow + + break; + } else { + // nothing found, keep looking + offset++; + } + } + }; + + _proto.parseMPEGPES = function parseMPEGPES(pes) { + var data = pes.data; + var length = data.length; + var frameIndex = 0; + var offset = 0; + var pts = pes.pts; + + if (pts === undefined) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("[tsdemuxer]: MPEG PES unknown PTS"); + return; + } + + while (offset < length) { + if (_mpegaudio__WEBPACK_IMPORTED_MODULE_1__["isHeader"](data, offset)) { + var frame = _mpegaudio__WEBPACK_IMPORTED_MODULE_1__["appendFrame"](this._audioTrack, data, offset, pts, frameIndex); + + if (frame) { + offset += frame.length; + frameIndex++; + } else { + // logger.log('Unable to parse Mpeg audio frame'); + break; + } + } else { + // nothing found, keep looking + offset++; + } + } + }; + + _proto.parseID3PES = function parseID3PES(pes) { + if (pes.pts === undefined) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("[tsdemuxer]: ID3 PES unknown PTS"); + return; + } + + this._id3Track.samples.push(pes); + }; + + return TSDemuxer; + })(); + + TSDemuxer.minProbeByteLength = 188; + + function createAVCSample(key, pts, dts, debug) { + return { + key: key, + frame: false, + pts: pts, + dts: dts, + units: [], + debug: debug, + length: 0, + }; } - } - } // check if we can read unit type - - if (i < len) { - unitType = array[i] & 0x1f; // logger.log('find NALU @ offset:' + i + ',type:' + unitType); - - lastUnitStart = i; - lastUnitType = unitType; - state = 0; - } else { - // not enough byte to read unit type. let's read it on next PES parsing - state = -1; - } - } else { - state = 0; - } - } - - if (lastUnitStart >= 0 && state >= 0) { - var _unit = { - data: array.subarray(lastUnitStart, len), - type: lastUnitType, - state: state - }; - units.push(_unit); // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state); - } // no NALu found - - - if (units.length === 0) { - // append pes.data to previous NAL unit - var _lastUnit = this.getLastNalUnit(); - - if (_lastUnit) { - var _tmp = new Uint8Array(_lastUnit.data.byteLength + array.byteLength); - - _tmp.set(_lastUnit.data, 0); - - _tmp.set(array, _lastUnit.data.byteLength); - - _lastUnit.data = _tmp; - } - } - - track.naluState = state; - return units; - }; - - _proto.parseAACPES = function parseAACPES(pes) { - var startOffset = 0; - var track = this._audioTrack; - var aacOverFlow = this.aacOverFlow; - var data = pes.data; - - if (aacOverFlow) { - this.aacOverFlow = null; - var sampleLength = aacOverFlow.sample.unit.byteLength; - var frameMissingBytes = Math.min(aacOverFlow.missing, sampleLength); - var frameOverflowBytes = sampleLength - frameMissingBytes; - aacOverFlow.sample.unit.set(data.subarray(0, frameMissingBytes), frameOverflowBytes); - track.samples.push(aacOverFlow.sample); // logger.log(`AAC: append overflowing ${frameOverflowBytes} bytes to beginning of new PES`); - - startOffset = aacOverFlow.missing; - } // look for ADTS header (0xFFFx) - - - var offset; - var len; - - for (offset = startOffset, len = data.length; offset < len - 1; offset++) { - if (_adts__WEBPACK_IMPORTED_MODULE_0__["isHeader"](data, offset)) { - break; - } - } // if ADTS header does not start straight from the beginning of the PES payload, raise an error - - - if (offset !== startOffset) { - var reason; - var fatal; - - if (offset < len - 1) { - reason = "AAC PES did not start with ADTS header,offset:" + offset; - fatal = false; - } else { - reason = 'no ADTS header found in AAC PES'; - fatal = true; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("parsing error:" + reason); - this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_5__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorTypes"].MEDIA_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_8__["ErrorDetails"].FRAG_PARSING_ERROR, - fatal: fatal, - reason: reason - }); - - if (fatal) { - return; - } - } - - _adts__WEBPACK_IMPORTED_MODULE_0__["initTrackConfig"](track, this.observer, data, offset, this.audioCodec); - var pts; - - if (pes.pts !== undefined) { - pts = pes.pts; - } else if (aacOverFlow) { - // if last AAC frame is overflowing, we should ensure timestamps are contiguous: - // first sample PTS should be equal to last sample PTS + frameDuration - var frameDuration = _adts__WEBPACK_IMPORTED_MODULE_0__["getFrameDuration"](track.samplerate); - pts = aacOverFlow.sample.pts + frameDuration; - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn('[tsdemuxer]: AAC PES unknown PTS'); - return; - } // scan for aac samples - - - var frameIndex = 0; - - while (offset < len) { - if (_adts__WEBPACK_IMPORTED_MODULE_0__["isHeader"](data, offset)) { - if (offset + 5 < len) { - var frame = _adts__WEBPACK_IMPORTED_MODULE_0__["appendFrame"](track, data, offset, pts, frameIndex); - - if (frame) { - if (frame.missing) { - this.aacOverFlow = frame; - } else { - offset += frame.length; - frameIndex++; - continue; + function parsePAT(data, offset) { + // skip the PSI header and parse the first PMT entry + return ((data[offset + 10] & 0x1f) << 8) | data[offset + 11]; // logger.log('PMT PID:' + this._pmtId); } - } - } // We are at an ADTS header, but do not have enough data for a frame - // Remaining data will be added to aacOverFlow + function parsePMT(data, offset, mpegSupported, isSampleAes) { + var result = { + audio: -1, + avc: -1, + id3: -1, + isAAC: true, + }; + var sectionLength = ((data[offset + 1] & 0x0f) << 8) | data[offset + 2]; + var tableEnd = offset + 3 + sectionLength - 4; // to determine where the table is, we have to figure out how + // long the program info descriptors are - break; - } else { - // nothing found, keep looking - offset++; - } - } - }; + var programInfoLength = ((data[offset + 10] & 0x0f) << 8) | data[offset + 11]; // advance the offset to the first entry in the mapping table - _proto.parseMPEGPES = function parseMPEGPES(pes) { - var data = pes.data; - var length = data.length; - var frameIndex = 0; - var offset = 0; - var pts = pes.pts; + offset += 12 + programInfoLength; - if (pts === undefined) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn('[tsdemuxer]: MPEG PES unknown PTS'); - return; - } + while (offset < tableEnd) { + var pid = ((data[offset + 1] & 0x1f) << 8) | data[offset + 2]; - while (offset < length) { - if (_mpegaudio__WEBPACK_IMPORTED_MODULE_1__["isHeader"](data, offset)) { - var frame = _mpegaudio__WEBPACK_IMPORTED_MODULE_1__["appendFrame"](this._audioTrack, data, offset, pts, frameIndex); + switch (data[offset]) { + case 0xcf: + // SAMPLE-AES AAC + if (!isSampleAes) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log("ADTS AAC with AES-128-CBC frame encryption found in unencrypted stream"); + break; + } - if (frame) { - offset += frame.length; - frameIndex++; - } else { - // logger.log('Unable to parse Mpeg audio frame'); - break; - } - } else { - // nothing found, keep looking - offset++; - } - } - }; + /* falls through */ - _proto.parseID3PES = function parseID3PES(pes) { - if (pes.pts === undefined) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn('[tsdemuxer]: ID3 PES unknown PTS'); - return; - } + case 0x0f: + // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio) + // logger.log('AAC PID:' + pid); + if (result.audio === -1) { + result.audio = pid; + } - this._id3Track.samples.push(pes); - }; + break; + // Packetized metadata (ID3) - return TSDemuxer; -}(); + case 0x15: + // logger.log('ID3 PID:' + pid); + if (result.id3 === -1) { + result.id3 = pid; + } -TSDemuxer.minProbeByteLength = 188; + break; -function createAVCSample(key, pts, dts, debug) { - return { - key: key, - frame: false, - pts: pts, - dts: dts, - units: [], - debug: debug, - length: 0 - }; -} + case 0xdb: + // SAMPLE-AES AVC + if (!isSampleAes) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log("H.264 with AES-128-CBC slice encryption found in unencrypted stream"); + break; + } -function parsePAT(data, offset) { - // skip the PSI header and parse the first PMT entry - return (data[offset + 10] & 0x1f) << 8 | data[offset + 11]; // logger.log('PMT PID:' + this._pmtId); -} + /* falls through */ -function parsePMT(data, offset, mpegSupported, isSampleAes) { - var result = { - audio: -1, - avc: -1, - id3: -1, - isAAC: true - }; - var sectionLength = (data[offset + 1] & 0x0f) << 8 | data[offset + 2]; - var tableEnd = offset + 3 + sectionLength - 4; // to determine where the table is, we have to figure out how - // long the program info descriptors are + case 0x1b: + // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video) + // logger.log('AVC PID:' + pid); + if (result.avc === -1) { + result.avc = pid; + } - var programInfoLength = (data[offset + 10] & 0x0f) << 8 | data[offset + 11]; // advance the offset to the first entry in the mapping table + break; + // ISO/IEC 11172-3 (MPEG-1 audio) + // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio) - offset += 12 + programInfoLength; + case 0x03: + case 0x04: + // logger.log('MPEG PID:' + pid); + if (!mpegSupported) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log("MPEG audio found, not supported in this browser"); + } else if (result.audio === -1) { + result.audio = pid; + result.isAAC = false; + } - while (offset < tableEnd) { - var pid = (data[offset + 1] & 0x1f) << 8 | data[offset + 2]; + break; - switch (data[offset]) { - case 0xcf: - // SAMPLE-AES AAC - if (!isSampleAes) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log('ADTS AAC with AES-128-CBC frame encryption found in unencrypted stream'); - break; - } + case 0x24: + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn("Unsupported HEVC stream type found"); + break; - /* falls through */ + default: + // logger.log('unknown stream type:' + data[offset]); + break; + } // move to the next table entry + // skip past the elementary stream descriptors, if present - case 0x0f: - // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio) - // logger.log('AAC PID:' + pid); - if (result.audio === -1) { - result.audio = pid; - } + offset += (((data[offset + 3] & 0x0f) << 8) | data[offset + 4]) + 5; + } - break; - // Packetized metadata (ID3) + return result; + } - case 0x15: - // logger.log('ID3 PID:' + pid); - if (result.id3 === -1) { - result.id3 = pid; - } + function parsePES(stream) { + var i = 0; + var frag; + var pesLen; + var pesHdrLen; + var pesPts; + var pesDts; + var data = stream.data; // safety check - break; + if (!stream || stream.size === 0) { + return null; + } // we might need up to 19 bytes to read PES header + // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes + // usually only one merge is needed (and this is rare ...) - case 0xdb: - // SAMPLE-AES AVC - if (!isSampleAes) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log('H.264 with AES-128-CBC slice encryption found in unencrypted stream'); - break; - } + while (data[0].length < 19 && data.length > 1) { + var newData = new Uint8Array(data[0].length + data[1].length); + newData.set(data[0]); + newData.set(data[1], data[0].length); + data[0] = newData; + data.splice(1, 1); + } // retrieve PTS/DTS from first fragment - /* falls through */ + frag = data[0]; + var pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2]; - case 0x1b: - // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video) - // logger.log('AVC PID:' + pid); - if (result.avc === -1) { - result.avc = pid; - } + if (pesPrefix === 1) { + pesLen = (frag[4] << 8) + frag[5]; // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated + // minus 6 : PES header size - break; - // ISO/IEC 11172-3 (MPEG-1 audio) - // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio) + if (pesLen && pesLen > stream.size - 6) { + return null; + } - case 0x03: - case 0x04: - // logger.log('MPEG PID:' + pid); - if (!mpegSupported) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log('MPEG audio found, not supported in this browser'); - } else if (result.audio === -1) { - result.audio = pid; - result.isAAC = false; - } + var pesFlags = frag[7]; - break; - - case 0x24: - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn('Unsupported HEVC stream type found'); - break; - - default: - // logger.log('unknown stream type:' + data[offset]); - break; - } // move to the next table entry - // skip past the elementary stream descriptors, if present - - - offset += ((data[offset + 3] & 0x0f) << 8 | data[offset + 4]) + 5; - } - - return result; -} - -function parsePES(stream) { - var i = 0; - var frag; - var pesLen; - var pesHdrLen; - var pesPts; - var pesDts; - var data = stream.data; // safety check - - if (!stream || stream.size === 0) { - return null; - } // we might need up to 19 bytes to read PES header - // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes - // usually only one merge is needed (and this is rare ...) - - - while (data[0].length < 19 && data.length > 1) { - var newData = new Uint8Array(data[0].length + data[1].length); - newData.set(data[0]); - newData.set(data[1], data[0].length); - data[0] = newData; - data.splice(1, 1); - } // retrieve PTS/DTS from first fragment - - - frag = data[0]; - var pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2]; - - if (pesPrefix === 1) { - pesLen = (frag[4] << 8) + frag[5]; // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated - // minus 6 : PES header size - - if (pesLen && pesLen > stream.size - 6) { - return null; - } - - var pesFlags = frag[7]; - - if (pesFlags & 0xc0) { - /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html + if (pesFlags & 0xc0) { + /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html as PTS / DTS is 33 bit we cannot use bitwise operator in JS, as Bitwise operators treat their operands as a sequence of 32 bits */ - pesPts = (frag[9] & 0x0e) * 536870912 + // 1 << 29 - (frag[10] & 0xff) * 4194304 + // 1 << 22 - (frag[11] & 0xfe) * 16384 + // 1 << 14 - (frag[12] & 0xff) * 128 + // 1 << 7 - (frag[13] & 0xfe) / 2; + pesPts = + (frag[9] & 0x0e) * 536870912 + // 1 << 29 + (frag[10] & 0xff) * 4194304 + // 1 << 22 + (frag[11] & 0xfe) * 16384 + // 1 << 14 + (frag[12] & 0xff) * 128 + // 1 << 7 + (frag[13] & 0xfe) / 2; - if (pesFlags & 0x40) { - pesDts = (frag[14] & 0x0e) * 536870912 + // 1 << 29 - (frag[15] & 0xff) * 4194304 + // 1 << 22 - (frag[16] & 0xfe) * 16384 + // 1 << 14 - (frag[17] & 0xff) * 128 + // 1 << 7 - (frag[18] & 0xfe) / 2; + if (pesFlags & 0x40) { + pesDts = + (frag[14] & 0x0e) * 536870912 + // 1 << 29 + (frag[15] & 0xff) * 4194304 + // 1 << 22 + (frag[16] & 0xfe) * 16384 + // 1 << 14 + (frag[17] & 0xff) * 128 + // 1 << 7 + (frag[18] & 0xfe) / 2; - if (pesPts - pesDts > 60 * 90000) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn(Math.round((pesPts - pesDts) / 90000) + "s delta between PTS and DTS, align them"); - pesPts = pesDts; - } - } else { - pesDts = pesPts; - } - } + if (pesPts - pesDts > 60 * 90000) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].warn(Math.round((pesPts - pesDts) / 90000) + "s delta between PTS and DTS, align them"); + pesPts = pesDts; + } + } else { + pesDts = pesPts; + } + } - pesHdrLen = frag[8]; // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension + pesHdrLen = frag[8]; // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension - var payloadStartOffset = pesHdrLen + 9; + var payloadStartOffset = pesHdrLen + 9; - if (stream.size <= payloadStartOffset) { - return null; - } + if (stream.size <= payloadStartOffset) { + return null; + } - stream.size -= payloadStartOffset; // reassemble PES packet + stream.size -= payloadStartOffset; // reassemble PES packet - var pesData = new Uint8Array(stream.size); + var pesData = new Uint8Array(stream.size); - for (var j = 0, dataLen = data.length; j < dataLen; j++) { - frag = data[j]; - var len = frag.byteLength; + for (var j = 0, dataLen = data.length; j < dataLen; j++) { + frag = data[j]; + var len = frag.byteLength; - if (payloadStartOffset) { - if (payloadStartOffset > len) { - // trim full frag if PES header bigger than frag - payloadStartOffset -= len; - continue; - } else { - // trim partial frag if PES header smaller than frag - frag = frag.subarray(payloadStartOffset); - len -= payloadStartOffset; - payloadStartOffset = 0; - } - } + if (payloadStartOffset) { + if (payloadStartOffset > len) { + // trim full frag if PES header bigger than frag + payloadStartOffset -= len; + continue; + } else { + // trim partial frag if PES header smaller than frag + frag = frag.subarray(payloadStartOffset); + len -= payloadStartOffset; + payloadStartOffset = 0; + } + } - pesData.set(frag, i); - i += len; - } + pesData.set(frag, i); + i += len; + } - if (pesLen) { - // payload size : remove PES header + PES extension - pesLen -= pesHdrLen + 3; - } + if (pesLen) { + // payload size : remove PES header + PES extension + pesLen -= pesHdrLen + 3; + } - return { - data: pesData, - pts: pesPts, - dts: pesDts, - len: pesLen - }; - } + return { + data: pesData, + pts: pesPts, + dts: pesDts, + len: pesLen, + }; + } - return null; -} + return null; + } -function pushAccessUnit(avcSample, avcTrack) { - if (avcSample.units.length && avcSample.frame) { - // if sample does not have PTS/DTS, patch with last sample PTS/DTS - if (avcSample.pts === undefined) { - var samples = avcTrack.samples; - var nbSamples = samples.length; + function pushAccessUnit(avcSample, avcTrack) { + if (avcSample.units.length && avcSample.frame) { + // if sample does not have PTS/DTS, patch with last sample PTS/DTS + if (avcSample.pts === undefined) { + var samples = avcTrack.samples; + var nbSamples = samples.length; - if (nbSamples) { - var lastSample = samples[nbSamples - 1]; - avcSample.pts = lastSample.pts; - avcSample.dts = lastSample.dts; - } else { - // dropping samples, no timestamp found - avcTrack.dropped++; - return; - } - } + if (nbSamples) { + var lastSample = samples[nbSamples - 1]; + avcSample.pts = lastSample.pts; + avcSample.dts = lastSample.dts; + } else { + // dropping samples, no timestamp found + avcTrack.dropped++; + return; + } + } - avcTrack.samples.push(avcSample); - } + avcTrack.samples.push(avcSample); + } - if (avcSample.debug.length) { - _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log(avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug); - } -} + if (avcSample.debug.length) { + _utils_logger__WEBPACK_IMPORTED_MODULE_7__["logger"].log(avcSample.pts + "/" + avcSample.dts + ":" + avcSample.debug); + } + } -function insertSampleInOrder(arr, data) { - var len = arr.length; + function insertSampleInOrder(arr, data) { + var len = arr.length; - if (len > 0) { - if (data.pts >= arr[len - 1].pts) { - arr.push(data); - } else { - for (var pos = len - 1; pos >= 0; pos--) { - if (data.pts < arr[pos].pts) { - arr.splice(pos, 0, data); - break; - } - } - } - } else { - arr.push(data); - } -} -/** - * remove Emulation Prevention bytes from a RBSP - */ + if (len > 0) { + if (data.pts >= arr[len - 1].pts) { + arr.push(data); + } else { + for (var pos = len - 1; pos >= 0; pos--) { + if (data.pts < arr[pos].pts) { + arr.splice(pos, 0, data); + break; + } + } + } + } else { + arr.push(data); + } + } + /** + * remove Emulation Prevention bytes from a RBSP + */ + function discardEPB(data) { + var length = data.byteLength; + var EPBPositions = []; + var i = 1; // Find all `Emulation Prevention Bytes` -function discardEPB(data) { - var length = data.byteLength; - var EPBPositions = []; - var i = 1; // Find all `Emulation Prevention Bytes` + while (i < length - 2) { + if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) { + EPBPositions.push(i + 2); + i += 2; + } else { + i++; + } + } // If no Emulation Prevention Bytes were found just return the original + // array - while (i < length - 2) { - if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) { - EPBPositions.push(i + 2); - i += 2; - } else { - i++; - } - } // If no Emulation Prevention Bytes were found just return the original - // array + if (EPBPositions.length === 0) { + return data; + } // Create a new array to hold the NAL unit data + var newLength = length - EPBPositions.length; + var newData = new Uint8Array(newLength); + var sourceIndex = 0; - if (EPBPositions.length === 0) { - return data; - } // Create a new array to hold the NAL unit data + for (i = 0; i < newLength; sourceIndex++, i++) { + if (sourceIndex === EPBPositions[0]) { + // Skip this byte + sourceIndex++; // Remove this position index + EPBPositions.shift(); + } - var newLength = length - EPBPositions.length; - var newData = new Uint8Array(newLength); - var sourceIndex = 0; + newData[i] = data[sourceIndex]; + } - for (i = 0; i < newLength; sourceIndex++, i++) { - if (sourceIndex === EPBPositions[0]) { - // Skip this byte - sourceIndex++; // Remove this position index + return newData; + } + /* harmony default export */ __webpack_exports__["default"] = TSDemuxer; - EPBPositions.shift(); - } + /***/ + }, - newData[i] = data[sourceIndex]; - } - - return newData; -} -/* harmony default export */ __webpack_exports__["default"] = (TSDemuxer); - -/***/ }), - -/***/ "./src/errors.ts": -/*!***********************!*\ + /***/ "./src/errors.ts": + /*!***********************!*\ !*** ./src/errors.ts ***! \***********************/ -/*! exports provided: ErrorTypes, ErrorDetails */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: ErrorTypes, ErrorDetails */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorTypes", function () { + return ErrorTypes; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorDetails", function () { + return ErrorDetails; + }); + var ErrorTypes; + /** + * @enum {ErrorDetails} + * @typedef {string} ErrorDetail + */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorTypes", function() { return ErrorTypes; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorDetails", function() { return ErrorDetails; }); -var ErrorTypes; -/** - * @enum {ErrorDetails} - * @typedef {string} ErrorDetail - */ + (function (ErrorTypes) { + ErrorTypes["NETWORK_ERROR"] = "networkError"; + ErrorTypes["MEDIA_ERROR"] = "mediaError"; + ErrorTypes["KEY_SYSTEM_ERROR"] = "keySystemError"; + ErrorTypes["MUX_ERROR"] = "muxError"; + ErrorTypes["OTHER_ERROR"] = "otherError"; + })(ErrorTypes || (ErrorTypes = {})); -(function (ErrorTypes) { - ErrorTypes["NETWORK_ERROR"] = "networkError"; - ErrorTypes["MEDIA_ERROR"] = "mediaError"; - ErrorTypes["KEY_SYSTEM_ERROR"] = "keySystemError"; - ErrorTypes["MUX_ERROR"] = "muxError"; - ErrorTypes["OTHER_ERROR"] = "otherError"; -})(ErrorTypes || (ErrorTypes = {})); + var ErrorDetails; -var ErrorDetails; + (function (ErrorDetails) { + ErrorDetails["KEY_SYSTEM_NO_KEYS"] = "keySystemNoKeys"; + ErrorDetails["KEY_SYSTEM_NO_ACCESS"] = "keySystemNoAccess"; + ErrorDetails["KEY_SYSTEM_NO_SESSION"] = "keySystemNoSession"; + ErrorDetails["KEY_SYSTEM_LICENSE_REQUEST_FAILED"] = "keySystemLicenseRequestFailed"; + ErrorDetails["KEY_SYSTEM_NO_INIT_DATA"] = "keySystemNoInitData"; + ErrorDetails["MANIFEST_LOAD_ERROR"] = "manifestLoadError"; + ErrorDetails["MANIFEST_LOAD_TIMEOUT"] = "manifestLoadTimeOut"; + ErrorDetails["MANIFEST_PARSING_ERROR"] = "manifestParsingError"; + ErrorDetails["MANIFEST_INCOMPATIBLE_CODECS_ERROR"] = "manifestIncompatibleCodecsError"; + ErrorDetails["LEVEL_EMPTY_ERROR"] = "levelEmptyError"; + ErrorDetails["LEVEL_LOAD_ERROR"] = "levelLoadError"; + ErrorDetails["LEVEL_LOAD_TIMEOUT"] = "levelLoadTimeOut"; + ErrorDetails["LEVEL_SWITCH_ERROR"] = "levelSwitchError"; + ErrorDetails["AUDIO_TRACK_LOAD_ERROR"] = "audioTrackLoadError"; + ErrorDetails["AUDIO_TRACK_LOAD_TIMEOUT"] = "audioTrackLoadTimeOut"; + ErrorDetails["SUBTITLE_LOAD_ERROR"] = "subtitleTrackLoadError"; + ErrorDetails["SUBTITLE_TRACK_LOAD_TIMEOUT"] = "subtitleTrackLoadTimeOut"; + ErrorDetails["FRAG_LOAD_ERROR"] = "fragLoadError"; + ErrorDetails["FRAG_LOAD_TIMEOUT"] = "fragLoadTimeOut"; + ErrorDetails["FRAG_DECRYPT_ERROR"] = "fragDecryptError"; + ErrorDetails["FRAG_PARSING_ERROR"] = "fragParsingError"; + ErrorDetails["REMUX_ALLOC_ERROR"] = "remuxAllocError"; + ErrorDetails["KEY_LOAD_ERROR"] = "keyLoadError"; + ErrorDetails["KEY_LOAD_TIMEOUT"] = "keyLoadTimeOut"; + ErrorDetails["BUFFER_ADD_CODEC_ERROR"] = "bufferAddCodecError"; + ErrorDetails["BUFFER_INCOMPATIBLE_CODECS_ERROR"] = "bufferIncompatibleCodecsError"; + ErrorDetails["BUFFER_APPEND_ERROR"] = "bufferAppendError"; + ErrorDetails["BUFFER_APPENDING_ERROR"] = "bufferAppendingError"; + ErrorDetails["BUFFER_STALLED_ERROR"] = "bufferStalledError"; + ErrorDetails["BUFFER_FULL_ERROR"] = "bufferFullError"; + ErrorDetails["BUFFER_SEEK_OVER_HOLE"] = "bufferSeekOverHole"; + ErrorDetails["BUFFER_NUDGE_ON_STALL"] = "bufferNudgeOnStall"; + ErrorDetails["INTERNAL_EXCEPTION"] = "internalException"; + ErrorDetails["INTERNAL_ABORTED"] = "aborted"; + ErrorDetails["UNKNOWN"] = "unknown"; + })(ErrorDetails || (ErrorDetails = {})); -(function (ErrorDetails) { - ErrorDetails["KEY_SYSTEM_NO_KEYS"] = "keySystemNoKeys"; - ErrorDetails["KEY_SYSTEM_NO_ACCESS"] = "keySystemNoAccess"; - ErrorDetails["KEY_SYSTEM_NO_SESSION"] = "keySystemNoSession"; - ErrorDetails["KEY_SYSTEM_LICENSE_REQUEST_FAILED"] = "keySystemLicenseRequestFailed"; - ErrorDetails["KEY_SYSTEM_NO_INIT_DATA"] = "keySystemNoInitData"; - ErrorDetails["MANIFEST_LOAD_ERROR"] = "manifestLoadError"; - ErrorDetails["MANIFEST_LOAD_TIMEOUT"] = "manifestLoadTimeOut"; - ErrorDetails["MANIFEST_PARSING_ERROR"] = "manifestParsingError"; - ErrorDetails["MANIFEST_INCOMPATIBLE_CODECS_ERROR"] = "manifestIncompatibleCodecsError"; - ErrorDetails["LEVEL_EMPTY_ERROR"] = "levelEmptyError"; - ErrorDetails["LEVEL_LOAD_ERROR"] = "levelLoadError"; - ErrorDetails["LEVEL_LOAD_TIMEOUT"] = "levelLoadTimeOut"; - ErrorDetails["LEVEL_SWITCH_ERROR"] = "levelSwitchError"; - ErrorDetails["AUDIO_TRACK_LOAD_ERROR"] = "audioTrackLoadError"; - ErrorDetails["AUDIO_TRACK_LOAD_TIMEOUT"] = "audioTrackLoadTimeOut"; - ErrorDetails["SUBTITLE_LOAD_ERROR"] = "subtitleTrackLoadError"; - ErrorDetails["SUBTITLE_TRACK_LOAD_TIMEOUT"] = "subtitleTrackLoadTimeOut"; - ErrorDetails["FRAG_LOAD_ERROR"] = "fragLoadError"; - ErrorDetails["FRAG_LOAD_TIMEOUT"] = "fragLoadTimeOut"; - ErrorDetails["FRAG_DECRYPT_ERROR"] = "fragDecryptError"; - ErrorDetails["FRAG_PARSING_ERROR"] = "fragParsingError"; - ErrorDetails["REMUX_ALLOC_ERROR"] = "remuxAllocError"; - ErrorDetails["KEY_LOAD_ERROR"] = "keyLoadError"; - ErrorDetails["KEY_LOAD_TIMEOUT"] = "keyLoadTimeOut"; - ErrorDetails["BUFFER_ADD_CODEC_ERROR"] = "bufferAddCodecError"; - ErrorDetails["BUFFER_INCOMPATIBLE_CODECS_ERROR"] = "bufferIncompatibleCodecsError"; - ErrorDetails["BUFFER_APPEND_ERROR"] = "bufferAppendError"; - ErrorDetails["BUFFER_APPENDING_ERROR"] = "bufferAppendingError"; - ErrorDetails["BUFFER_STALLED_ERROR"] = "bufferStalledError"; - ErrorDetails["BUFFER_FULL_ERROR"] = "bufferFullError"; - ErrorDetails["BUFFER_SEEK_OVER_HOLE"] = "bufferSeekOverHole"; - ErrorDetails["BUFFER_NUDGE_ON_STALL"] = "bufferNudgeOnStall"; - ErrorDetails["INTERNAL_EXCEPTION"] = "internalException"; - ErrorDetails["INTERNAL_ABORTED"] = "aborted"; - ErrorDetails["UNKNOWN"] = "unknown"; -})(ErrorDetails || (ErrorDetails = {})); + /***/ + }, -/***/ }), - -/***/ "./src/events.ts": -/*!***********************!*\ + /***/ "./src/events.ts": + /*!***********************!*\ !*** ./src/events.ts ***! \***********************/ -/*! exports provided: Events */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: Events */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Events", function () { + return Events; + }); + /** + * @readonly + * @enum {string} + */ + var Events; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Events", function() { return Events; }); -/** - * @readonly - * @enum {string} - */ -var Events; + (function (Events) { + Events["MEDIA_ATTACHING"] = "CiderHlsMediaAttaching"; + Events["MEDIA_ATTACHED"] = "CiderHlsMediaAttached"; + Events["MEDIA_DETACHING"] = "CiderHlsMediaDetaching"; + Events["MEDIA_DETACHED"] = "CiderHlsMediaDetached"; + Events["BUFFER_RESET"] = "CiderHlsBufferReset"; + Events["BUFFER_CODECS"] = "CiderHlsBufferCodecs"; + Events["BUFFER_CREATED"] = "CiderHlsBufferCreated"; + Events["BUFFER_APPENDING"] = "CiderHlsBufferAppending"; + Events["BUFFER_APPENDED"] = "CiderHlsBufferAppended"; + Events["BUFFER_EOS"] = "CiderHlsBufferEos"; + Events["BUFFER_FLUSHING"] = "CiderHlsBufferFlushing"; + Events["BUFFER_FLUSHED"] = "CiderHlsBufferFlushed"; + Events["MANIFEST_LOADING"] = "CiderHlsManifestLoading"; + Events["MANIFEST_LOADED"] = "CiderHlsManifestLoaded"; + Events["MANIFEST_PARSED"] = "CiderHlsManifestParsed"; + Events["LEVEL_SWITCHING"] = "CiderHlsLevelSwitching"; + Events["LEVEL_SWITCHED"] = "CiderHlsLevelSwitched"; + Events["LEVEL_LOADING"] = "CiderHlsLevelLoading"; + Events["LEVEL_LOADED"] = "CiderHlsLevelLoaded"; + Events["LEVEL_UPDATED"] = "CiderHlsLevelUpdated"; + Events["LEVEL_PTS_UPDATED"] = "CiderHlsLevelPtsUpdated"; + Events["LEVELS_UPDATED"] = "CiderHlsLevelsUpdated"; + Events["AUDIO_TRACKS_UPDATED"] = "CiderHlsAudioTracksUpdated"; + Events["AUDIO_TRACK_SWITCHING"] = "CiderHlsAudioTrackSwitching"; + Events["AUDIO_TRACK_SWITCHED"] = "CiderHlsAudioTrackSwitched"; + Events["AUDIO_TRACK_LOADING"] = "CiderHlsAudioTrackLoading"; + Events["AUDIO_TRACK_LOADED"] = "CiderHlsAudioTrackLoaded"; + Events["SUBTITLE_TRACKS_UPDATED"] = "CiderHlsSubtitleTracksUpdated"; + Events["SUBTITLE_TRACKS_CLEARED"] = "CiderHlsSubtitleTracksCleared"; + Events["SUBTITLE_TRACK_SWITCH"] = "CiderHlsSubtitleTrackSwitch"; + Events["SUBTITLE_TRACK_LOADING"] = "CiderHlsSubtitleTrackLoading"; + Events["SUBTITLE_TRACK_LOADED"] = "CiderHlsSubtitleTrackLoaded"; + Events["SUBTITLE_FRAG_PROCESSED"] = "CiderHlsSubtitleFragProcessed"; + Events["CUES_PARSED"] = "CiderHlsCuesParsed"; + Events["NON_NATIVE_TEXT_TRACKS_FOUND"] = "CiderHlsNonNativeTextTracksFound"; + Events["INIT_PTS_FOUND"] = "CiderHlsInitPtsFound"; + Events["FRAG_LOADING"] = "CiderHlsFragLoading"; + Events["FRAG_LOAD_EMERGENCY_ABORTED"] = "CiderHlsFragLoadEmergencyAborted"; + Events["FRAG_LOADED"] = "CiderHlsFragLoaded"; + Events["FRAG_DECRYPTED"] = "CiderHlsFragDecrypted"; + Events["FRAG_PARSING_INIT_SEGMENT"] = "CiderHlsFragParsingInitSegment"; + Events["FRAG_PARSING_USERDATA"] = "CiderHlsFragParsingUserdata"; + Events["FRAG_PARSING_METADATA"] = "CiderHlsFragParsingMetadata"; + Events["FRAG_PARSED"] = "CiderHlsFragParsed"; + Events["FRAG_BUFFERED"] = "CiderHlsFragBuffered"; + Events["FRAG_CHANGED"] = "CiderHlsFragChanged"; + Events["FPS_DROP"] = "CiderHlsFpsDrop"; + Events["FPS_DROP_LEVEL_CAPPING"] = "CiderHlsFpsDropLevelCapping"; + Events["ERROR"] = "CiderHlsError"; + Events["DESTROYING"] = "CiderHlsDestroying"; + Events["KEY_LOADING"] = "CiderHlsKeyLoading"; + Events["KEY_LOADED"] = "CiderHlsKeyLoaded"; + Events["LIVE_BACK_BUFFER_REACHED"] = "CiderHlsLiveBackBufferReached"; + Events["BACK_BUFFER_REACHED"] = "CiderHlsBackBufferReached"; + })(Events || (Events = {})); -(function (Events) { - Events["MEDIA_ATTACHING"] = "CiderHlsMediaAttaching"; - Events["MEDIA_ATTACHED"] = "CiderHlsMediaAttached"; - Events["MEDIA_DETACHING"] = "CiderHlsMediaDetaching"; - Events["MEDIA_DETACHED"] = "CiderHlsMediaDetached"; - Events["BUFFER_RESET"] = "CiderHlsBufferReset"; - Events["BUFFER_CODECS"] = "CiderHlsBufferCodecs"; - Events["BUFFER_CREATED"] = "CiderHlsBufferCreated"; - Events["BUFFER_APPENDING"] = "CiderHlsBufferAppending"; - Events["BUFFER_APPENDED"] = "CiderHlsBufferAppended"; - Events["BUFFER_EOS"] = "CiderHlsBufferEos"; - Events["BUFFER_FLUSHING"] = "CiderHlsBufferFlushing"; - Events["BUFFER_FLUSHED"] = "CiderHlsBufferFlushed"; - Events["MANIFEST_LOADING"] = "CiderHlsManifestLoading"; - Events["MANIFEST_LOADED"] = "CiderHlsManifestLoaded"; - Events["MANIFEST_PARSED"] = "CiderHlsManifestParsed"; - Events["LEVEL_SWITCHING"] = "CiderHlsLevelSwitching"; - Events["LEVEL_SWITCHED"] = "CiderHlsLevelSwitched"; - Events["LEVEL_LOADING"] = "CiderHlsLevelLoading"; - Events["LEVEL_LOADED"] = "CiderHlsLevelLoaded"; - Events["LEVEL_UPDATED"] = "CiderHlsLevelUpdated"; - Events["LEVEL_PTS_UPDATED"] = "CiderHlsLevelPtsUpdated"; - Events["LEVELS_UPDATED"] = "CiderHlsLevelsUpdated"; - Events["AUDIO_TRACKS_UPDATED"] = "CiderHlsAudioTracksUpdated"; - Events["AUDIO_TRACK_SWITCHING"] = "CiderHlsAudioTrackSwitching"; - Events["AUDIO_TRACK_SWITCHED"] = "CiderHlsAudioTrackSwitched"; - Events["AUDIO_TRACK_LOADING"] = "CiderHlsAudioTrackLoading"; - Events["AUDIO_TRACK_LOADED"] = "CiderHlsAudioTrackLoaded"; - Events["SUBTITLE_TRACKS_UPDATED"] = "CiderHlsSubtitleTracksUpdated"; - Events["SUBTITLE_TRACKS_CLEARED"] = "CiderHlsSubtitleTracksCleared"; - Events["SUBTITLE_TRACK_SWITCH"] = "CiderHlsSubtitleTrackSwitch"; - Events["SUBTITLE_TRACK_LOADING"] = "CiderHlsSubtitleTrackLoading"; - Events["SUBTITLE_TRACK_LOADED"] = "CiderHlsSubtitleTrackLoaded"; - Events["SUBTITLE_FRAG_PROCESSED"] = "CiderHlsSubtitleFragProcessed"; - Events["CUES_PARSED"] = "CiderHlsCuesParsed"; - Events["NON_NATIVE_TEXT_TRACKS_FOUND"] = "CiderHlsNonNativeTextTracksFound"; - Events["INIT_PTS_FOUND"] = "CiderHlsInitPtsFound"; - Events["FRAG_LOADING"] = "CiderHlsFragLoading"; - Events["FRAG_LOAD_EMERGENCY_ABORTED"] = "CiderHlsFragLoadEmergencyAborted"; - Events["FRAG_LOADED"] = "CiderHlsFragLoaded"; - Events["FRAG_DECRYPTED"] = "CiderHlsFragDecrypted"; - Events["FRAG_PARSING_INIT_SEGMENT"] = "CiderHlsFragParsingInitSegment"; - Events["FRAG_PARSING_USERDATA"] = "CiderHlsFragParsingUserdata"; - Events["FRAG_PARSING_METADATA"] = "CiderHlsFragParsingMetadata"; - Events["FRAG_PARSED"] = "CiderHlsFragParsed"; - Events["FRAG_BUFFERED"] = "CiderHlsFragBuffered"; - Events["FRAG_CHANGED"] = "CiderHlsFragChanged"; - Events["FPS_DROP"] = "CiderHlsFpsDrop"; - Events["FPS_DROP_LEVEL_CAPPING"] = "CiderHlsFpsDropLevelCapping"; - Events["ERROR"] = "CiderHlsError"; - Events["DESTROYING"] = "CiderHlsDestroying"; - Events["KEY_LOADING"] = "CiderHlsKeyLoading"; - Events["KEY_LOADED"] = "CiderHlsKeyLoaded"; - Events["LIVE_BACK_BUFFER_REACHED"] = "CiderHlsLiveBackBufferReached"; - Events["BACK_BUFFER_REACHED"] = "CiderHlsBackBufferReached"; -})(Events || (Events = {})); + /***/ + }, -/***/ }), - -/***/ "./src/CiderHls.ts": -/*!********************!*\ + /***/ "./src/CiderHls.ts": + /*!********************!*\ !*** ./src/CiderHls.ts ***! \********************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CiderHls; }); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./loader/playlist-loader */ "./src/loader/playlist-loader.ts"); -/* harmony import */ var _loader_key_loader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./loader/key-loader */ "./src/loader/key-loader.ts"); -/* harmony import */ var _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controller/id3-track-controller */ "./src/controller/id3-track-controller.ts"); -/* harmony import */ var _controller_latency_controller__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controller/latency-controller */ "./src/controller/latency-controller.ts"); -/* harmony import */ var _controller_level_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./controller/level-controller */ "./src/controller/level-controller.ts"); -/* harmony import */ var _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./controller/fragment-tracker */ "./src/controller/fragment-tracker.ts"); -/* harmony import */ var _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./controller/stream-controller */ "./src/controller/stream-controller.ts"); -/* harmony import */ var _is_supported__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./is-supported */ "./src/is-supported.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./config */ "./src/config.ts"); -/* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js"); -/* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_11__); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./errors */ "./src/errors.ts"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - - - - - - - - - - - - - - - - -/** - * @module CiderHls - * @class - * @constructor - */ -var CiderHls = /*#__PURE__*/function () { - CiderHls.isSupported = function isSupported() { - return Object(_is_supported__WEBPACK_IMPORTED_MODULE_8__["isSupported"])(); - }; - - /** - * Creates an instance of an CiderHls client that can attach to exactly one `HTMLMediaElement`. - * - * @constructs CiderHls - * @param {CiderHlsConfig} config - */ - function CiderHls(userConfig) { - if (userConfig === void 0) { - userConfig = {}; - } - - this.config = void 0; - this.userConfig = void 0; - this.coreComponents = void 0; - this.networkControllers = void 0; - this._emitter = new eventemitter3__WEBPACK_IMPORTED_MODULE_11__["EventEmitter"](); - this._autoLevelCapping = void 0; - this.abrController = void 0; - this.bufferController = void 0; - this.capLevelController = void 0; - this.latencyController = void 0; - this.levelController = void 0; - this.streamController = void 0; - this.audioTrackController = void 0; - this.subtitleTrackController = void 0; - this.emeController = void 0; - this.cmcdController = void 0; - this._media = null; - this.url = null; - var config = this.config = Object(_config__WEBPACK_IMPORTED_MODULE_10__["mergeConfig"])(CiderHls.DefaultConfig, userConfig); - this.userConfig = userConfig; - Object(_utils_logger__WEBPACK_IMPORTED_MODULE_9__["enableLogs"])(config.debug); - this._autoLevelCapping = -1; - - if (config.progressive) { - Object(_config__WEBPACK_IMPORTED_MODULE_10__["enableStreamingMode"])(config); - } // core controllers and network loaders - - - var ConfigAbrController = config.abrController, - ConfigBufferController = config.bufferController, - ConfigCapLevelController = config.capLevelController, - ConfigFpsController = config.fpsController; - var abrController = this.abrController = new ConfigAbrController(this); - var bufferController = this.bufferController = new ConfigBufferController(this); - var capLevelController = this.capLevelController = new ConfigCapLevelController(this); - var fpsController = new ConfigFpsController(this); - var playListLoader = new _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__["default"](this); - var keyLoader = new _loader_key_loader__WEBPACK_IMPORTED_MODULE_2__["default"](this); - var id3TrackController = new _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_3__["default"](this); // network controllers - - var levelController = this.levelController = new _controller_level_controller__WEBPACK_IMPORTED_MODULE_5__["default"](this); // FragmentTracker must be defined before StreamController because the order of event handling is important - - var fragmentTracker = new _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_6__["FragmentTracker"](this); - var streamController = this.streamController = new _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__["default"](this, fragmentTracker); // Cap level controller uses streamController to flush the buffer - - capLevelController.setStreamController(streamController); // fpsController uses streamController to switch when frames are being dropped - - fpsController.setStreamController(streamController); - var networkControllers = [levelController, streamController]; - this.networkControllers = networkControllers; - var coreComponents = [playListLoader, keyLoader, abrController, bufferController, capLevelController, fpsController, id3TrackController, fragmentTracker]; - this.audioTrackController = this.createController(config.audioTrackController, null, networkControllers); - this.createController(config.audioStreamController, fragmentTracker, networkControllers); // subtitleTrackController must be defined before because the order of event handling is important - - this.subtitleTrackController = this.createController(config.subtitleTrackController, null, networkControllers); - this.createController(config.subtitleStreamController, fragmentTracker, networkControllers); - this.createController(config.timelineController, null, coreComponents); - this.emeController = this.createController(config.emeController, null, coreComponents); - this.cmcdController = this.createController(config.cmcdController, null, coreComponents); - this.latencyController = this.createController(_controller_latency_controller__WEBPACK_IMPORTED_MODULE_4__["default"], null, coreComponents); - this.coreComponents = coreComponents; - } - - var _proto = CiderHls.prototype; - - _proto.createController = function createController(ControllerClass, fragmentTracker, components) { - if (ControllerClass) { - var controllerInstance = fragmentTracker ? new ControllerClass(this, fragmentTracker) : new ControllerClass(this); - - if (components) { - components.push(controllerInstance); - } - - return controllerInstance; - } - - return null; - } // Delegate the EventEmitter through the public API of CiderHls.js - ; - - _proto.on = function on(event, listener, context) { - if (context === void 0) { - context = this; - } - - this._emitter.on(event, listener, context); - }; - - _proto.once = function once(event, listener, context) { - if (context === void 0) { - context = this; - } - - this._emitter.once(event, listener, context); - }; - - _proto.removeAllListeners = function removeAllListeners(event) { - this._emitter.removeAllListeners(event); - }; - - _proto.off = function off(event, listener, context, once) { - if (context === void 0) { - context = this; - } - - this._emitter.off(event, listener, context, once); - }; - - _proto.listeners = function listeners(event) { - return this._emitter.listeners(event); - }; - - _proto.emit = function emit(event, name, eventObject) { - return this._emitter.emit(event, name, eventObject); - }; - - _proto.trigger = function trigger(event, eventObject) { - if (this.config.debug) { - return this.emit(event, event, eventObject); - } else { - try { - return this.emit(event, event, eventObject); - } catch (e) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].error('An internal error happened while handling event ' + event + '. Error message: "' + e.message + '". Here is a stacktrace:', e); - this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorTypes"].OTHER_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].INTERNAL_EXCEPTION, - fatal: false, - event: event, - error: e - }); - } - } - - return false; - }; - - _proto.listenerCount = function listenerCount(event) { - return this._emitter.listenerCount(event); - } - /** - * Dispose of the instance - */ - ; - - _proto.destroy = function destroy() { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log('destroy'); - this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].DESTROYING, undefined); - this.detachMedia(); - this.removeAllListeners(); - this._autoLevelCapping = -1; - this.url = null; - this.networkControllers.forEach(function (component) { - return component.destroy(); - }); - this.networkControllers.length = 0; - this.coreComponents.forEach(function (component) { - return component.destroy(); - }); - this.coreComponents.length = 0; - } - /** - * Attaches CiderHls.js to a media element - * @param {HTMLMediaElement} media - */ - ; - - _proto.attachMedia = function attachMedia(media) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log('attachMedia'); - this._media = media; - this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].MEDIA_ATTACHING, { - media: media - }); - } - /** - * Detach CiderHls.js from the media - */ - ; - - _proto.detachMedia = function detachMedia() { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log('detachMedia'); - this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].MEDIA_DETACHING, undefined); - this._media = null; - } - /** - * Set the source URL. Can be relative or absolute. - * @param {string} url - */ - ; - - _proto.loadSource = function loadSource(url) { - this.stopLoad(); - var media = this.media; - var loadedSource = this.url; - var loadingSource = this.url = url_toolkit__WEBPACK_IMPORTED_MODULE_0__["buildAbsoluteURL"](self.location.href, url, { - alwaysNormalize: true - }); - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("loadSource:" + loadingSource); - - if (media && loadedSource && loadedSource !== loadingSource && this.bufferController.hasSourceTypes()) { - this.detachMedia(); - this.attachMedia(media); - } // when attaching to a source URL, trigger a playlist load - - - this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].MANIFEST_LOADING, { - url: url - }); - } - /** - * Start loading data from the stream source. - * Depending on default config, client starts loading automatically when a source is set. - * - * @param {number} startPosition Set the start position to stream from - * @default -1 None (from earliest point) - */ - ; - - _proto.startLoad = function startLoad(startPosition) { - if (startPosition === void 0) { - startPosition = -1; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("startLoad(" + startPosition + ")"); - this.networkControllers.forEach(function (controller) { - controller.startLoad(startPosition); - }); - } - /** - * Stop loading of any stream data. - */ - ; - - _proto.stopLoad = function stopLoad() { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log('stopLoad'); - this.networkControllers.forEach(function (controller) { - controller.stopLoad(); - }); - } - /** - * Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1) - */ - ; - - _proto.swapAudioCodec = function swapAudioCodec() { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log('swapAudioCodec'); - this.streamController.swapAudioCodec(); - } - /** - * When the media-element fails, this allows to detach and then re-attach it - * as one call (convenience method). - * - * Automatic recovery of media-errors by this process is configurable. - */ - ; - - _proto.recoverMediaError = function recoverMediaError() { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log('recoverMediaError'); - var media = this._media; - this.detachMedia(); - - if (media) { - this.attachMedia(media); - } - }; - - _proto.removeLevel = function removeLevel(levelIndex, urlId) { - if (urlId === void 0) { - urlId = 0; - } - - this.levelController.removeLevel(levelIndex, urlId); - } - /** - * @type {Level[]} - */ - ; - - _createClass(CiderHls, [{ - key: "levels", - get: function get() { - var levels = this.levelController.levels; - return levels ? levels : []; - } - /** - * Index of quality level currently played - * @type {number} - */ - - }, { - key: "currentLevel", - get: function get() { - return this.streamController.currentLevel; - } - /** - * Set quality level index immediately . - * This will flush the current buffer to replace the quality asap. - * That means playback will interrupt at least shortly to re-buffer and re-sync eventually. - * @type {number} -1 for automatic level selection - */ - , - set: function set(newLevel) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set currentLevel:" + newLevel); - this.loadLevel = newLevel; - this.abrController.clearTimer(); - this.streamController.immediateLevelSwitch(); - } - /** - * Index of next quality level loaded as scheduled by stream controller. - * @type {number} - */ - - }, { - key: "nextLevel", - get: function get() { - return this.streamController.nextLevel; - } - /** - * Set quality level index for next loaded data. - * This will switch the video quality asap, without interrupting playback. - * May abort current loading of data, and flush parts of buffer (outside currently played fragment region). - * @type {number} -1 for automatic level selection - */ - , - set: function set(newLevel) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set nextLevel:" + newLevel); - this.levelController.manualLevel = newLevel; - this.streamController.nextLevelSwitch(); - } - /** - * Return the quality level of the currently or last (of none is loaded currently) segment - * @type {number} - */ - - }, { - key: "loadLevel", - get: function get() { - return this.levelController.level; - } - /** - * Set quality level index for next loaded data in a conservative way. - * This will switch the quality without flushing, but interrupt current loading. - * Thus the moment when the quality switch will appear in effect will only be after the already existing buffer. - * @type {number} newLevel -1 for automatic level selection - */ - , - set: function set(newLevel) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set loadLevel:" + newLevel); - this.levelController.manualLevel = newLevel; - } - /** - * get next quality level loaded - * @type {number} - */ - - }, { - key: "nextLoadLevel", - get: function get() { - return this.levelController.nextLoadLevel; - } - /** - * Set quality level of next loaded segment in a fully "non-destructive" way. - * Same as `loadLevel` but will wait for next switch (until current loading is done). - * @type {number} level - */ - , - set: function set(level) { - this.levelController.nextLoadLevel = level; - } - /** - * Return "first level": like a default level, if not set, - * falls back to index of first level referenced in manifest - * @type {number} - */ - - }, { - key: "firstLevel", - get: function get() { - return Math.max(this.levelController.firstLevel, this.minAutoLevel); - } - /** - * Sets "first-level", see getter. - * @type {number} - */ - , - set: function set(newLevel) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set firstLevel:" + newLevel); - this.levelController.firstLevel = newLevel; - } - /** - * Return start level (level of first fragment that will be played back) - * if not overrided by user, first level appearing in manifest will be used as start level - * if -1 : automatic start level selection, playback will start from level matching download bandwidth - * (determined from download of first segment) - * @type {number} - */ - - }, { - key: "startLevel", - get: function get() { - return this.levelController.startLevel; - } - /** - * set start level (level of first fragment that will be played back) - * if not overrided by user, first level appearing in manifest will be used as start level - * if -1 : automatic start level selection, playback will start from level matching download bandwidth - * (determined from download of first segment) - * @type {number} newLevel - */ - , - set: function set(newLevel) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set startLevel:" + newLevel); // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel - - if (newLevel !== -1) { - newLevel = Math.max(newLevel, this.minAutoLevel); - } - - this.levelController.startLevel = newLevel; - } - /** - * Get the current setting for capLevelToPlayerSize - * - * @type {boolean} - */ - - }, { - key: "capLevelToPlayerSize", - get: function get() { - return this.config.capLevelToPlayerSize; - } - /** - * set dynamically set capLevelToPlayerSize against (`CapLevelController`) - * - * @type {boolean} - */ - , - set: function set(shouldStartCapping) { - var newCapLevelToPlayerSize = !!shouldStartCapping; - - if (newCapLevelToPlayerSize !== this.config.capLevelToPlayerSize) { - if (newCapLevelToPlayerSize) { - this.capLevelController.startCapping(); // If capping occurs, nextLevelSwitch will happen based on size. - } else { - this.capLevelController.stopCapping(); - this.autoLevelCapping = -1; - this.streamController.nextLevelSwitch(); // Now we're uncapped, get the next level asap. - } - - this.config.capLevelToPlayerSize = newCapLevelToPlayerSize; - } - } - /** - * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`) - * @type {number} - */ - - }, { - key: "autoLevelCapping", - get: function get() { - return this._autoLevelCapping; - } - /** - * get bandwidth estimate - * @type {number} - */ - , - set: - /** - * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`) - * @type {number} - */ - function set(newLevel) { - if (this._autoLevelCapping !== newLevel) { - _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set autoLevelCapping:" + newLevel); - this._autoLevelCapping = newLevel; - } - } - /** - * True when automatic level selection enabled - * @type {boolean} - */ - - }, { - key: "bandwidthEstimate", - get: function get() { - var bwEstimator = this.abrController.bwEstimator; - - if (!bwEstimator) { - return NaN; - } - - return bwEstimator.getEstimate(); - } - }, { - key: "autoLevelEnabled", - get: function get() { - return this.levelController.manualLevel === -1; - } - /** - * Level set manually (if any) - * @type {number} - */ - - }, { - key: "manualLevel", - get: function get() { - return this.levelController.manualLevel; - } - /** - * min level selectable in auto mode according to config.minAutoBitrate - * @type {number} - */ - - }, { - key: "minAutoLevel", - get: function get() { - var levels = this.levels, - minAutoBitrate = this.config.minAutoBitrate; - if (!levels) return 0; - var len = levels.length; - - for (var i = 0; i < len; i++) { - if (levels[i].maxBitrate > minAutoBitrate) { - return i; - } - } - - return 0; - } - /** - * max level selectable in auto mode according to autoLevelCapping - * @type {number} - */ - - }, { - key: "maxAutoLevel", - get: function get() { - var levels = this.levels, - autoLevelCapping = this.autoLevelCapping; - var maxAutoLevel; - - if (autoLevelCapping === -1 && levels && levels.length) { - maxAutoLevel = levels.length - 1; - } else { - maxAutoLevel = autoLevelCapping; - } - - return maxAutoLevel; - } - /** - * next automatically selected quality level - * @type {number} - */ - - }, { - key: "nextAutoLevel", - get: function get() { - // ensure next auto level is between min and max auto level - return Math.min(Math.max(this.abrController.nextAutoLevel, this.minAutoLevel), this.maxAutoLevel); - } - /** - * this setter is used to force next auto level. - * this is useful to force a switch down in auto mode: - * in case of load error on level N, CiderHls.js can set nextAutoLevel to N-1 for example) - * forced value is valid for one fragment. upon succesful frag loading at forced level, - * this value will be resetted to -1 by ABR controller. - * @type {number} - */ - , - set: function set(nextLevel) { - this.abrController.nextAutoLevel = Math.max(this.minAutoLevel, nextLevel); - } - /** - * @type {AudioTrack[]} - */ - - }, { - key: "audioTracks", - get: function get() { - var audioTrackController = this.audioTrackController; - return audioTrackController ? audioTrackController.audioTracks : []; - } - /** - * index of the selected audio track (index in audio track lists) - * @type {number} - */ - - }, { - key: "audioTrack", - get: function get() { - var audioTrackController = this.audioTrackController; - return audioTrackController ? audioTrackController.audioTrack : -1; - } - /** - * selects an audio track, based on its index in audio track lists - * @type {number} - */ - , - set: function set(audioTrackId) { - var audioTrackController = this.audioTrackController; - - if (audioTrackController) { - audioTrackController.audioTrack = audioTrackId; - } - } - /** - * get alternate subtitle tracks list from playlist - * @type {MediaPlaylist[]} - */ - - }, { - key: "subtitleTracks", - get: function get() { - var subtitleTrackController = this.subtitleTrackController; - return subtitleTrackController ? subtitleTrackController.subtitleTracks : []; - } - /** - * index of the selected subtitle track (index in subtitle track lists) - * @type {number} - */ - - }, { - key: "subtitleTrack", - get: function get() { - var subtitleTrackController = this.subtitleTrackController; - return subtitleTrackController ? subtitleTrackController.subtitleTrack : -1; - }, - set: - /** - * select an subtitle track, based on its index in subtitle track lists - * @type {number} - */ - function set(subtitleTrackId) { - var subtitleTrackController = this.subtitleTrackController; - - if (subtitleTrackController) { - subtitleTrackController.subtitleTrack = subtitleTrackId; - } - } - /** - * @type {boolean} - */ - - }, { - key: "media", - get: function get() { - return this._media; - } - }, { - key: "subtitleDisplay", - get: function get() { - var subtitleTrackController = this.subtitleTrackController; - return subtitleTrackController ? subtitleTrackController.subtitleDisplay : false; - } - /** - * Enable/disable subtitle display rendering - * @type {boolean} - */ - , - set: function set(value) { - var subtitleTrackController = this.subtitleTrackController; - - if (subtitleTrackController) { - subtitleTrackController.subtitleDisplay = value; - } - } - /** - * get mode for Low-Latency CiderHls loading - * @type {boolean} - */ - - }, { - key: "lowLatencyMode", - get: function get() { - return this.config.lowLatencyMode; - } - /** - * Enable/disable Low-Latency CiderHls part playlist and segment loading, and start live streams at playlist PART-HOLD-BACK rather than HOLD-BACK. - * @type {boolean} - */ - , - set: function set(mode) { - this.config.lowLatencyMode = mode; - } - /** - * position (in seconds) of live sync point (ie edge of live position minus safety delay defined by ```CiderHls.config.liveSyncDuration```) - * @type {number} - */ - - }, { - key: "liveSyncPosition", - get: function get() { - return this.latencyController.liveSyncPosition; - } - /** - * estimated position (in seconds) of live edge (ie edge of live playlist plus time sync playlist advanced) - * returns 0 before first playlist is loaded - * @type {number} - */ - - }, { - key: "latency", - get: function get() { - return this.latencyController.latency; - } - /** - * maximum distance from the edge before the player seeks forward to ```CiderHls.liveSyncPosition``` - * configured using ```liveMaxLatencyDurationCount``` (multiple of target duration) or ```liveMaxLatencyDuration``` - * returns 0 before first playlist is loaded - * @type {number} - */ - - }, { - key: "maxLatency", - get: function get() { - return this.latencyController.maxLatency; - } - /** - * target distance from the edge as calculated by the latency controller - * @type {number} - */ - - }, { - key: "targetLatency", - get: function get() { - return this.latencyController.targetLatency; - } - /** - * the rate at which the edge of the current live playlist is advancing or 1 if there is none - * @type {number} - */ - - }, { - key: "drift", - get: function get() { - return this.latencyController.drift; - } - /** - * set to true when startLoad is called before MANIFEST_PARSED event - * @type {boolean} - */ - - }, { - key: "forceStartLoad", - get: function get() { - return this.streamController.forceStartLoad; - } - }], [{ - key: "version", - get: function get() { - return "1.1.2"; - } - }, { - key: "Events", - get: function get() { - return _events__WEBPACK_IMPORTED_MODULE_12__["Events"]; - } - }, { - key: "ErrorTypes", - get: function get() { - return _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorTypes"]; - } - }, { - key: "ErrorDetails", - get: function get() { - return _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"]; - } - }, { - key: "DefaultConfig", - get: function get() { - if (!CiderHls.defaultConfig) { - return _config__WEBPACK_IMPORTED_MODULE_10__["CiderHlsDefaultConfig"]; - } - - return CiderHls.defaultConfig; - } - /** - * @type {CiderHlsConfig} - */ - , - set: function set(defaultConfig) { - CiderHls.defaultConfig = defaultConfig; - } - }]); - - return CiderHls; -}(); - -CiderHls.defaultConfig = void 0; - - -/***/ }), - -/***/ "./src/is-supported.ts": -/*!*****************************!*\ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return CiderHls; + }); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_0__); + /* harmony import */ var _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./loader/playlist-loader */ "./src/loader/playlist-loader.ts"); + /* harmony import */ var _loader_key_loader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./loader/key-loader */ "./src/loader/key-loader.ts"); + /* harmony import */ var _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controller/id3-track-controller */ "./src/controller/id3-track-controller.ts"); + /* harmony import */ var _controller_latency_controller__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controller/latency-controller */ "./src/controller/latency-controller.ts"); + /* harmony import */ var _controller_level_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./controller/level-controller */ "./src/controller/level-controller.ts"); + /* harmony import */ var _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./controller/fragment-tracker */ "./src/controller/fragment-tracker.ts"); + /* harmony import */ var _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./controller/stream-controller */ "./src/controller/stream-controller.ts"); + /* harmony import */ var _is_supported__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./is-supported */ "./src/is-supported.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./config */ "./src/config.ts"); + /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js"); + /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/ __webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_11__); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./errors */ "./src/errors.ts"); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + /** + * @module CiderHls + * @class + * @constructor + */ + var CiderHls = /*#__PURE__*/ (function () { + CiderHls.isSupported = function isSupported() { + return Object(_is_supported__WEBPACK_IMPORTED_MODULE_8__["isSupported"])(); + }; + + /** + * Creates an instance of an CiderHls client that can attach to exactly one `HTMLMediaElement`. + * + * @constructs CiderHls + * @param {CiderHlsConfig} config + */ + function CiderHls(userConfig) { + if (userConfig === void 0) { + userConfig = {}; + } + + this.config = void 0; + this.userConfig = void 0; + this.coreComponents = void 0; + this.networkControllers = void 0; + this._emitter = new eventemitter3__WEBPACK_IMPORTED_MODULE_11__["EventEmitter"](); + this._autoLevelCapping = void 0; + this.abrController = void 0; + this.bufferController = void 0; + this.capLevelController = void 0; + this.latencyController = void 0; + this.levelController = void 0; + this.streamController = void 0; + this.audioTrackController = void 0; + this.subtitleTrackController = void 0; + this.emeController = void 0; + this.cmcdController = void 0; + this._media = null; + this.url = null; + var config = (this.config = Object(_config__WEBPACK_IMPORTED_MODULE_10__["mergeConfig"])(CiderHls.DefaultConfig, userConfig)); + this.userConfig = userConfig; + Object(_utils_logger__WEBPACK_IMPORTED_MODULE_9__["enableLogs"])(config.debug); + this._autoLevelCapping = -1; + + if (config.progressive) { + Object(_config__WEBPACK_IMPORTED_MODULE_10__["enableStreamingMode"])(config); + } // core controllers and network loaders + + var ConfigAbrController = config.abrController, + ConfigBufferController = config.bufferController, + ConfigCapLevelController = config.capLevelController, + ConfigFpsController = config.fpsController; + var abrController = (this.abrController = new ConfigAbrController(this)); + var bufferController = (this.bufferController = new ConfigBufferController(this)); + var capLevelController = (this.capLevelController = new ConfigCapLevelController(this)); + var fpsController = new ConfigFpsController(this); + var playListLoader = new _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__["default"](this); + var keyLoader = new _loader_key_loader__WEBPACK_IMPORTED_MODULE_2__["default"](this); + var id3TrackController = new _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_3__["default"](this); // network controllers + + var levelController = (this.levelController = new _controller_level_controller__WEBPACK_IMPORTED_MODULE_5__["default"](this)); // FragmentTracker must be defined before StreamController because the order of event handling is important + + var fragmentTracker = new _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_6__["FragmentTracker"](this); + var streamController = (this.streamController = new _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__["default"](this, fragmentTracker)); // Cap level controller uses streamController to flush the buffer + + capLevelController.setStreamController(streamController); // fpsController uses streamController to switch when frames are being dropped + + fpsController.setStreamController(streamController); + var networkControllers = [levelController, streamController]; + this.networkControllers = networkControllers; + var coreComponents = [playListLoader, keyLoader, abrController, bufferController, capLevelController, fpsController, id3TrackController, fragmentTracker]; + this.audioTrackController = this.createController(config.audioTrackController, null, networkControllers); + this.createController(config.audioStreamController, fragmentTracker, networkControllers); // subtitleTrackController must be defined before because the order of event handling is important + + this.subtitleTrackController = this.createController(config.subtitleTrackController, null, networkControllers); + this.createController(config.subtitleStreamController, fragmentTracker, networkControllers); + this.createController(config.timelineController, null, coreComponents); + this.emeController = this.createController(config.emeController, null, coreComponents); + this.cmcdController = this.createController(config.cmcdController, null, coreComponents); + this.latencyController = this.createController(_controller_latency_controller__WEBPACK_IMPORTED_MODULE_4__["default"], null, coreComponents); + this.coreComponents = coreComponents; + } + + var _proto = CiderHls.prototype; + + _proto.createController = function createController(ControllerClass, fragmentTracker, components) { + if (ControllerClass) { + var controllerInstance = fragmentTracker ? new ControllerClass(this, fragmentTracker) : new ControllerClass(this); + + if (components) { + components.push(controllerInstance); + } + + return controllerInstance; + } + + return null; + }; // Delegate the EventEmitter through the public API of CiderHls.js + + _proto.on = function on(event, listener, context) { + if (context === void 0) { + context = this; + } + + this._emitter.on(event, listener, context); + }; + + _proto.once = function once(event, listener, context) { + if (context === void 0) { + context = this; + } + + this._emitter.once(event, listener, context); + }; + + _proto.removeAllListeners = function removeAllListeners(event) { + this._emitter.removeAllListeners(event); + }; + + _proto.off = function off(event, listener, context, once) { + if (context === void 0) { + context = this; + } + + this._emitter.off(event, listener, context, once); + }; + + _proto.listeners = function listeners(event) { + return this._emitter.listeners(event); + }; + + _proto.emit = function emit(event, name, eventObject) { + return this._emitter.emit(event, name, eventObject); + }; + + _proto.trigger = function trigger(event, eventObject) { + if (this.config.debug) { + return this.emit(event, event, eventObject); + } else { + try { + return this.emit(event, event, eventObject); + } catch (e) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].error("An internal error happened while handling event " + event + '. Error message: "' + e.message + '". Here is a stacktrace:', e); + this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorTypes"].OTHER_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"].INTERNAL_EXCEPTION, + fatal: false, + event: event, + error: e, + }); + } + } + + return false; + }; + + _proto.listenerCount = function listenerCount(event) { + return this._emitter.listenerCount(event); + }; + /** + * Dispose of the instance + */ + + _proto.destroy = function destroy() { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("destroy"); + this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].DESTROYING, undefined); + this.detachMedia(); + this.removeAllListeners(); + this._autoLevelCapping = -1; + this.url = null; + this.networkControllers.forEach(function (component) { + return component.destroy(); + }); + this.networkControllers.length = 0; + this.coreComponents.forEach(function (component) { + return component.destroy(); + }); + this.coreComponents.length = 0; + }; + /** + * Attaches CiderHls.js to a media element + * @param {HTMLMediaElement} media + */ + + _proto.attachMedia = function attachMedia(media) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("attachMedia"); + this._media = media; + this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].MEDIA_ATTACHING, { + media: media, + }); + }; + /** + * Detach CiderHls.js from the media + */ + + _proto.detachMedia = function detachMedia() { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("detachMedia"); + this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].MEDIA_DETACHING, undefined); + this._media = null; + }; + /** + * Set the source URL. Can be relative or absolute. + * @param {string} url + */ + + _proto.loadSource = function loadSource(url) { + this.stopLoad(); + var media = this.media; + var loadedSource = this.url; + var loadingSource = (this.url = url_toolkit__WEBPACK_IMPORTED_MODULE_0__["buildAbsoluteURL"](self.location.href, url, { + alwaysNormalize: true, + })); + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("loadSource:" + loadingSource); + + if (media && loadedSource && loadedSource !== loadingSource && this.bufferController.hasSourceTypes()) { + this.detachMedia(); + this.attachMedia(media); + } // when attaching to a source URL, trigger a playlist load + + this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__["Events"].MANIFEST_LOADING, { + url: url, + }); + }; + /** + * Start loading data from the stream source. + * Depending on default config, client starts loading automatically when a source is set. + * + * @param {number} startPosition Set the start position to stream from + * @default -1 None (from earliest point) + */ + + _proto.startLoad = function startLoad(startPosition) { + if (startPosition === void 0) { + startPosition = -1; + } + + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("startLoad(" + startPosition + ")"); + this.networkControllers.forEach(function (controller) { + controller.startLoad(startPosition); + }); + }; + /** + * Stop loading of any stream data. + */ + + _proto.stopLoad = function stopLoad() { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("stopLoad"); + this.networkControllers.forEach(function (controller) { + controller.stopLoad(); + }); + }; + /** + * Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1) + */ + + _proto.swapAudioCodec = function swapAudioCodec() { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("swapAudioCodec"); + this.streamController.swapAudioCodec(); + }; + /** + * When the media-element fails, this allows to detach and then re-attach it + * as one call (convenience method). + * + * Automatic recovery of media-errors by this process is configurable. + */ + + _proto.recoverMediaError = function recoverMediaError() { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("recoverMediaError"); + var media = this._media; + this.detachMedia(); + + if (media) { + this.attachMedia(media); + } + }; + + _proto.removeLevel = function removeLevel(levelIndex, urlId) { + if (urlId === void 0) { + urlId = 0; + } + + this.levelController.removeLevel(levelIndex, urlId); + }; + /** + * @type {Level[]} + */ + + _createClass( + CiderHls, + [ + { + key: "levels", + get: function get() { + var levels = this.levelController.levels; + return levels ? levels : []; + }, + /** + * Index of quality level currently played + * @type {number} + */ + }, + { + key: "currentLevel", + get: function get() { + return this.streamController.currentLevel; + }, + /** + * Set quality level index immediately . + * This will flush the current buffer to replace the quality asap. + * That means playback will interrupt at least shortly to re-buffer and re-sync eventually. + * @type {number} -1 for automatic level selection + */ + set: function set(newLevel) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set currentLevel:" + newLevel); + this.loadLevel = newLevel; + this.abrController.clearTimer(); + this.streamController.immediateLevelSwitch(); + }, + /** + * Index of next quality level loaded as scheduled by stream controller. + * @type {number} + */ + }, + { + key: "nextLevel", + get: function get() { + return this.streamController.nextLevel; + }, + /** + * Set quality level index for next loaded data. + * This will switch the video quality asap, without interrupting playback. + * May abort current loading of data, and flush parts of buffer (outside currently played fragment region). + * @type {number} -1 for automatic level selection + */ + set: function set(newLevel) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set nextLevel:" + newLevel); + this.levelController.manualLevel = newLevel; + this.streamController.nextLevelSwitch(); + }, + /** + * Return the quality level of the currently or last (of none is loaded currently) segment + * @type {number} + */ + }, + { + key: "loadLevel", + get: function get() { + return this.levelController.level; + }, + /** + * Set quality level index for next loaded data in a conservative way. + * This will switch the quality without flushing, but interrupt current loading. + * Thus the moment when the quality switch will appear in effect will only be after the already existing buffer. + * @type {number} newLevel -1 for automatic level selection + */ + set: function set(newLevel) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set loadLevel:" + newLevel); + this.levelController.manualLevel = newLevel; + }, + /** + * get next quality level loaded + * @type {number} + */ + }, + { + key: "nextLoadLevel", + get: function get() { + return this.levelController.nextLoadLevel; + }, + /** + * Set quality level of next loaded segment in a fully "non-destructive" way. + * Same as `loadLevel` but will wait for next switch (until current loading is done). + * @type {number} level + */ + set: function set(level) { + this.levelController.nextLoadLevel = level; + }, + /** + * Return "first level": like a default level, if not set, + * falls back to index of first level referenced in manifest + * @type {number} + */ + }, + { + key: "firstLevel", + get: function get() { + return Math.max(this.levelController.firstLevel, this.minAutoLevel); + }, + /** + * Sets "first-level", see getter. + * @type {number} + */ + set: function set(newLevel) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set firstLevel:" + newLevel); + this.levelController.firstLevel = newLevel; + }, + /** + * Return start level (level of first fragment that will be played back) + * if not overrided by user, first level appearing in manifest will be used as start level + * if -1 : automatic start level selection, playback will start from level matching download bandwidth + * (determined from download of first segment) + * @type {number} + */ + }, + { + key: "startLevel", + get: function get() { + return this.levelController.startLevel; + }, + /** + * set start level (level of first fragment that will be played back) + * if not overrided by user, first level appearing in manifest will be used as start level + * if -1 : automatic start level selection, playback will start from level matching download bandwidth + * (determined from download of first segment) + * @type {number} newLevel + */ + set: function set(newLevel) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set startLevel:" + newLevel); // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel + + if (newLevel !== -1) { + newLevel = Math.max(newLevel, this.minAutoLevel); + } + + this.levelController.startLevel = newLevel; + }, + /** + * Get the current setting for capLevelToPlayerSize + * + * @type {boolean} + */ + }, + { + key: "capLevelToPlayerSize", + get: function get() { + return this.config.capLevelToPlayerSize; + }, + /** + * set dynamically set capLevelToPlayerSize against (`CapLevelController`) + * + * @type {boolean} + */ + set: function set(shouldStartCapping) { + var newCapLevelToPlayerSize = !!shouldStartCapping; + + if (newCapLevelToPlayerSize !== this.config.capLevelToPlayerSize) { + if (newCapLevelToPlayerSize) { + this.capLevelController.startCapping(); // If capping occurs, nextLevelSwitch will happen based on size. + } else { + this.capLevelController.stopCapping(); + this.autoLevelCapping = -1; + this.streamController.nextLevelSwitch(); // Now we're uncapped, get the next level asap. + } + + this.config.capLevelToPlayerSize = newCapLevelToPlayerSize; + } + }, + /** + * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`) + * @type {number} + */ + }, + { + key: "autoLevelCapping", + get: function get() { + return this._autoLevelCapping; + }, + /** + * get bandwidth estimate + * @type {number} + */ + set: + /** + * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`) + * @type {number} + */ + function set(newLevel) { + if (this._autoLevelCapping !== newLevel) { + _utils_logger__WEBPACK_IMPORTED_MODULE_9__["logger"].log("set autoLevelCapping:" + newLevel); + this._autoLevelCapping = newLevel; + } + }, + /** + * True when automatic level selection enabled + * @type {boolean} + */ + }, + { + key: "bandwidthEstimate", + get: function get() { + var bwEstimator = this.abrController.bwEstimator; + + if (!bwEstimator) { + return NaN; + } + + return bwEstimator.getEstimate(); + }, + }, + { + key: "autoLevelEnabled", + get: function get() { + return this.levelController.manualLevel === -1; + }, + /** + * Level set manually (if any) + * @type {number} + */ + }, + { + key: "manualLevel", + get: function get() { + return this.levelController.manualLevel; + }, + /** + * min level selectable in auto mode according to config.minAutoBitrate + * @type {number} + */ + }, + { + key: "minAutoLevel", + get: function get() { + var levels = this.levels, + minAutoBitrate = this.config.minAutoBitrate; + if (!levels) return 0; + var len = levels.length; + + for (var i = 0; i < len; i++) { + if (levels[i].maxBitrate > minAutoBitrate) { + return i; + } + } + + return 0; + }, + /** + * max level selectable in auto mode according to autoLevelCapping + * @type {number} + */ + }, + { + key: "maxAutoLevel", + get: function get() { + var levels = this.levels, + autoLevelCapping = this.autoLevelCapping; + var maxAutoLevel; + + if (autoLevelCapping === -1 && levels && levels.length) { + maxAutoLevel = levels.length - 1; + } else { + maxAutoLevel = autoLevelCapping; + } + + return maxAutoLevel; + }, + /** + * next automatically selected quality level + * @type {number} + */ + }, + { + key: "nextAutoLevel", + get: function get() { + // ensure next auto level is between min and max auto level + return Math.min(Math.max(this.abrController.nextAutoLevel, this.minAutoLevel), this.maxAutoLevel); + }, + /** + * this setter is used to force next auto level. + * this is useful to force a switch down in auto mode: + * in case of load error on level N, CiderHls.js can set nextAutoLevel to N-1 for example) + * forced value is valid for one fragment. upon succesful frag loading at forced level, + * this value will be resetted to -1 by ABR controller. + * @type {number} + */ + set: function set(nextLevel) { + this.abrController.nextAutoLevel = Math.max(this.minAutoLevel, nextLevel); + }, + /** + * @type {AudioTrack[]} + */ + }, + { + key: "audioTracks", + get: function get() { + var audioTrackController = this.audioTrackController; + return audioTrackController ? audioTrackController.audioTracks : []; + }, + /** + * index of the selected audio track (index in audio track lists) + * @type {number} + */ + }, + { + key: "audioTrack", + get: function get() { + var audioTrackController = this.audioTrackController; + return audioTrackController ? audioTrackController.audioTrack : -1; + }, + /** + * selects an audio track, based on its index in audio track lists + * @type {number} + */ + set: function set(audioTrackId) { + var audioTrackController = this.audioTrackController; + + if (audioTrackController) { + audioTrackController.audioTrack = audioTrackId; + } + }, + /** + * get alternate subtitle tracks list from playlist + * @type {MediaPlaylist[]} + */ + }, + { + key: "subtitleTracks", + get: function get() { + var subtitleTrackController = this.subtitleTrackController; + return subtitleTrackController ? subtitleTrackController.subtitleTracks : []; + }, + /** + * index of the selected subtitle track (index in subtitle track lists) + * @type {number} + */ + }, + { + key: "subtitleTrack", + get: function get() { + var subtitleTrackController = this.subtitleTrackController; + return subtitleTrackController ? subtitleTrackController.subtitleTrack : -1; + }, + set: + /** + * select an subtitle track, based on its index in subtitle track lists + * @type {number} + */ + function set(subtitleTrackId) { + var subtitleTrackController = this.subtitleTrackController; + + if (subtitleTrackController) { + subtitleTrackController.subtitleTrack = subtitleTrackId; + } + }, + /** + * @type {boolean} + */ + }, + { + key: "media", + get: function get() { + return this._media; + }, + }, + { + key: "subtitleDisplay", + get: function get() { + var subtitleTrackController = this.subtitleTrackController; + return subtitleTrackController ? subtitleTrackController.subtitleDisplay : false; + }, + /** + * Enable/disable subtitle display rendering + * @type {boolean} + */ + set: function set(value) { + var subtitleTrackController = this.subtitleTrackController; + + if (subtitleTrackController) { + subtitleTrackController.subtitleDisplay = value; + } + }, + /** + * get mode for Low-Latency CiderHls loading + * @type {boolean} + */ + }, + { + key: "lowLatencyMode", + get: function get() { + return this.config.lowLatencyMode; + }, + /** + * Enable/disable Low-Latency CiderHls part playlist and segment loading, and start live streams at playlist PART-HOLD-BACK rather than HOLD-BACK. + * @type {boolean} + */ + set: function set(mode) { + this.config.lowLatencyMode = mode; + }, + /** + * position (in seconds) of live sync point (ie edge of live position minus safety delay defined by ```CiderHls.config.liveSyncDuration```) + * @type {number} + */ + }, + { + key: "liveSyncPosition", + get: function get() { + return this.latencyController.liveSyncPosition; + }, + /** + * estimated position (in seconds) of live edge (ie edge of live playlist plus time sync playlist advanced) + * returns 0 before first playlist is loaded + * @type {number} + */ + }, + { + key: "latency", + get: function get() { + return this.latencyController.latency; + }, + /** + * maximum distance from the edge before the player seeks forward to ```CiderHls.liveSyncPosition``` + * configured using ```liveMaxLatencyDurationCount``` (multiple of target duration) or ```liveMaxLatencyDuration``` + * returns 0 before first playlist is loaded + * @type {number} + */ + }, + { + key: "maxLatency", + get: function get() { + return this.latencyController.maxLatency; + }, + /** + * target distance from the edge as calculated by the latency controller + * @type {number} + */ + }, + { + key: "targetLatency", + get: function get() { + return this.latencyController.targetLatency; + }, + /** + * the rate at which the edge of the current live playlist is advancing or 1 if there is none + * @type {number} + */ + }, + { + key: "drift", + get: function get() { + return this.latencyController.drift; + }, + /** + * set to true when startLoad is called before MANIFEST_PARSED event + * @type {boolean} + */ + }, + { + key: "forceStartLoad", + get: function get() { + return this.streamController.forceStartLoad; + }, + }, + ], + [ + { + key: "version", + get: function get() { + return "1.1.2"; + }, + }, + { + key: "Events", + get: function get() { + return _events__WEBPACK_IMPORTED_MODULE_12__["Events"]; + }, + }, + { + key: "ErrorTypes", + get: function get() { + return _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorTypes"]; + }, + }, + { + key: "ErrorDetails", + get: function get() { + return _errors__WEBPACK_IMPORTED_MODULE_13__["ErrorDetails"]; + }, + }, + { + key: "DefaultConfig", + get: function get() { + if (!CiderHls.defaultConfig) { + return _config__WEBPACK_IMPORTED_MODULE_10__["CiderHlsDefaultConfig"]; + } + + return CiderHls.defaultConfig; + }, + /** + * @type {CiderHlsConfig} + */ + set: function set(defaultConfig) { + CiderHls.defaultConfig = defaultConfig; + }, + }, + ] + ); + + return CiderHls; + })(); + + CiderHls.defaultConfig = void 0; + + /***/ + }, + + /***/ "./src/is-supported.ts": + /*!*****************************!*\ !*** ./src/is-supported.ts ***! \*****************************/ -/*! exports provided: isSupported, changeTypeSupported */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: isSupported, changeTypeSupported */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isSupported", function () { + return isSupported; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "changeTypeSupported", function () { + return changeTypeSupported; + }); + /* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/mediasource-helper */ "./src/utils/mediasource-helper.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isSupported", function() { return isSupported; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "changeTypeSupported", function() { return changeTypeSupported; }); -/* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/mediasource-helper */ "./src/utils/mediasource-helper.ts"); + function getSourceBuffer() { + return self.SourceBuffer || self.WebKitSourceBuffer; + } + function isSupported() { + var mediaSource = Object(_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__["getMediaSource"])(); -function getSourceBuffer() { - return self.SourceBuffer || self.WebKitSourceBuffer; -} + if (!mediaSource) { + return false; + } -function isSupported() { - var mediaSource = Object(_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__["getMediaSource"])(); + var sourceBuffer = getSourceBuffer(); + var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === "function" && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'); // if SourceBuffer is exposed ensure its API is valid + // safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible - if (!mediaSource) { - return false; - } + var sourceBufferValidAPI = !sourceBuffer || (sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === "function" && typeof sourceBuffer.prototype.remove === "function"); + return !!isTypeSupported && !!sourceBufferValidAPI; + } + function changeTypeSupported() { + var _sourceBuffer$prototy; - var sourceBuffer = getSourceBuffer(); - var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'); // if SourceBuffer is exposed ensure its API is valid - // safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible + var sourceBuffer = getSourceBuffer(); + return typeof (sourceBuffer === null || sourceBuffer === void 0 ? void 0 : (_sourceBuffer$prototy = sourceBuffer.prototype) === null || _sourceBuffer$prototy === void 0 ? void 0 : _sourceBuffer$prototy.changeType) === "function"; + } - var sourceBufferValidAPI = !sourceBuffer || sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === 'function' && typeof sourceBuffer.prototype.remove === 'function'; - return !!isTypeSupported && !!sourceBufferValidAPI; -} -function changeTypeSupported() { - var _sourceBuffer$prototy; + /***/ + }, - var sourceBuffer = getSourceBuffer(); - return typeof (sourceBuffer === null || sourceBuffer === void 0 ? void 0 : (_sourceBuffer$prototy = sourceBuffer.prototype) === null || _sourceBuffer$prototy === void 0 ? void 0 : _sourceBuffer$prototy.changeType) === 'function'; -} - -/***/ }), - -/***/ "./src/loader/fragment-loader.ts": -/*!***************************************!*\ + /***/ "./src/loader/fragment-loader.ts": + /*!***************************************!*\ !*** ./src/loader/fragment-loader.ts ***! \***************************************/ -/*! exports provided: default, LoadError */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return FragmentLoader; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoadError", function() { return LoadError; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); - - - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } - -function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - - -var MIN_CHUNK_SIZE = Math.pow(2, 17); // 128kb - -var FragmentLoader = /*#__PURE__*/function () { - function FragmentLoader(config) { - this.config = void 0; - this.loader = null; - this.partLoadTimeout = -1; - this.config = config; - } - - var _proto = FragmentLoader.prototype; - - _proto.destroy = function destroy() { - if (this.loader) { - this.loader.destroy(); - this.loader = null; - } - }; - - _proto.abort = function abort() { - if (this.loader) { - // Abort the loader for current fragment. Only one may load at any given time - this.loader.abort(); - } - }; - - _proto.load = function load(frag, _onProgress) { - var _this = this; - - var url = frag.url; - - if (!url) { - return Promise.reject(new LoadError({ - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_ERROR, - fatal: false, - frag: frag, - networkDetails: null - }, "Fragment does not have a " + (url ? 'part list' : 'url'))); - } - - this.abort(); - var config = this.config; - var FragmentILoader = config.fLoader; - var DefaultILoader = config.loader; - return new Promise(function (resolve, reject) { - if (_this.loader) { - _this.loader.destroy(); - } - - var loader = _this.loader = frag.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config); - var loaderContext = createLoaderContext(frag); - var loaderConfig = { - timeout: config.fragLoadingTimeOut, - maxRetry: 0, - retryDelay: 0, - maxRetryDelay: config.fragLoadingMaxRetryTimeout, - highWaterMark: MIN_CHUNK_SIZE - }; // Assign frag stats to the loader's stats reference - - frag.stats = loader.stats; - loader.load(loaderContext, loaderConfig, { - onSuccess: function onSuccess(response, stats, context, networkDetails) { - _this.resetLoader(frag, loader); - - resolve({ - frag: frag, - part: null, - payload: response.data, - networkDetails: networkDetails - }); - }, - onError: function onError(response, context, networkDetails) { - _this.resetLoader(frag, loader); - - reject(new LoadError({ - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_ERROR, - fatal: false, - frag: frag, - response: response, - networkDetails: networkDetails - })); - }, - onAbort: function onAbort(stats, context, networkDetails) { - _this.resetLoader(frag, loader); - - reject(new LoadError({ - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].INTERNAL_ABORTED, - fatal: false, - frag: frag, - networkDetails: networkDetails - })); - }, - onTimeout: function onTimeout(response, context, networkDetails) { - _this.resetLoader(frag, loader); - - reject(new LoadError({ - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_TIMEOUT, - fatal: false, - frag: frag, - networkDetails: networkDetails - })); - }, - onProgress: function onProgress(stats, context, data, networkDetails) { - if (_onProgress) { - _onProgress({ - frag: frag, - part: null, - payload: data, - networkDetails: networkDetails + /*! exports provided: default, LoadError */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return FragmentLoader; }); - } - } - }); - }); - }; + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoadError", function () { + return LoadError; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); - _proto.loadPart = function loadPart(frag, part, onProgress) { - var _this2 = this; + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } - this.abort(); - var config = this.config; - var FragmentILoader = config.fLoader; - var DefaultILoader = config.loader; - return new Promise(function (resolve, reject) { - if (_this2.loader) { - _this2.loader.destroy(); - } + function _wrapNativeSuper(Class) { + var _cache = typeof Map === "function" ? new Map() : undefined; + _wrapNativeSuper = function _wrapNativeSuper(Class) { + if (Class === null || !_isNativeFunction(Class)) return Class; + if (typeof Class !== "function") { + throw new TypeError("Super expression must either be null or a function"); + } + if (typeof _cache !== "undefined") { + if (_cache.has(Class)) return _cache.get(Class); + _cache.set(Class, Wrapper); + } + function Wrapper() { + return _construct(Class, arguments, _getPrototypeOf(this).constructor); + } + Wrapper.prototype = Object.create(Class.prototype, { + constructor: { + value: Wrapper, + enumerable: false, + writable: true, + configurable: true, + }, + }); + return _setPrototypeOf(Wrapper, Class); + }; + return _wrapNativeSuper(Class); + } - var loader = _this2.loader = frag.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config); - var loaderContext = createLoaderContext(frag, part); - var loaderConfig = { - timeout: config.fragLoadingTimeOut, - maxRetry: 0, - retryDelay: 0, - maxRetryDelay: config.fragLoadingMaxRetryTimeout, - highWaterMark: MIN_CHUNK_SIZE - }; // Assign part stats to the loader's stats reference + function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; + } else { + _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) _setPrototypeOf(instance, Class.prototype); + return instance; + }; + } + return _construct.apply(null, arguments); + } - part.stats = loader.stats; - loader.load(loaderContext, loaderConfig, { - onSuccess: function onSuccess(response, stats, context, networkDetails) { - _this2.resetLoader(frag, loader); + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + return true; + } catch (e) { + return false; + } + } - _this2.updateStatsFromPart(frag, part); + function _isNativeFunction(fn) { + return Function.toString.call(fn).indexOf("[native code]") !== -1; + } - var partLoadedData = { - frag: frag, - part: part, - payload: response.data, - networkDetails: networkDetails - }; - onProgress(partLoadedData); - resolve(partLoadedData); - }, - onError: function onError(response, context, networkDetails) { - _this2.resetLoader(frag, loader); + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } - reject(new LoadError({ - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_ERROR, - fatal: false, - frag: frag, - part: part, - response: response, - networkDetails: networkDetails - })); - }, - onAbort: function onAbort(stats, context, networkDetails) { - frag.stats.aborted = part.stats.aborted; + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf + ? Object.getPrototypeOf + : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } - _this2.resetLoader(frag, loader); + var MIN_CHUNK_SIZE = Math.pow(2, 17); // 128kb - reject(new LoadError({ - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].INTERNAL_ABORTED, - fatal: false, - frag: frag, - part: part, - networkDetails: networkDetails - })); - }, - onTimeout: function onTimeout(response, context, networkDetails) { - _this2.resetLoader(frag, loader); + var FragmentLoader = /*#__PURE__*/ (function () { + function FragmentLoader(config) { + this.config = void 0; + this.loader = null; + this.partLoadTimeout = -1; + this.config = config; + } - reject(new LoadError({ - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_TIMEOUT, - fatal: false, - frag: frag, - part: part, - networkDetails: networkDetails - })); - } - }); - }); - }; + var _proto = FragmentLoader.prototype; - _proto.updateStatsFromPart = function updateStatsFromPart(frag, part) { - var fragStats = frag.stats; - var partStats = part.stats; - var partTotal = partStats.total; - fragStats.loaded += partStats.loaded; + _proto.destroy = function destroy() { + if (this.loader) { + this.loader.destroy(); + this.loader = null; + } + }; - if (partTotal) { - var estTotalParts = Math.round(frag.duration / part.duration); - var estLoadedParts = Math.min(Math.round(fragStats.loaded / partTotal), estTotalParts); - var estRemainingParts = estTotalParts - estLoadedParts; - var estRemainingBytes = estRemainingParts * Math.round(fragStats.loaded / estLoadedParts); - fragStats.total = fragStats.loaded + estRemainingBytes; - } else { - fragStats.total = Math.max(fragStats.loaded, fragStats.total); - } + _proto.abort = function abort() { + if (this.loader) { + // Abort the loader for current fragment. Only one may load at any given time + this.loader.abort(); + } + }; - var fragLoading = fragStats.loading; - var partLoading = partStats.loading; + _proto.load = function load(frag, _onProgress) { + var _this = this; - if (fragLoading.start) { - // add to fragment loader latency - fragLoading.first += partLoading.first - partLoading.start; - } else { - fragLoading.start = partLoading.start; - fragLoading.first = partLoading.first; - } + var url = frag.url; - fragLoading.end = partLoading.end; - }; + if (!url) { + return Promise.reject( + new LoadError( + { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_ERROR, + fatal: false, + frag: frag, + networkDetails: null, + }, + "Fragment does not have a " + (url ? "part list" : "url") + ) + ); + } - _proto.resetLoader = function resetLoader(frag, loader) { - frag.loader = null; + this.abort(); + var config = this.config; + var FragmentILoader = config.fLoader; + var DefaultILoader = config.loader; + return new Promise(function (resolve, reject) { + if (_this.loader) { + _this.loader.destroy(); + } - if (this.loader === loader) { - self.clearTimeout(this.partLoadTimeout); - this.loader = null; - } + var loader = (_this.loader = frag.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config)); + var loaderContext = createLoaderContext(frag); + var loaderConfig = { + timeout: config.fragLoadingTimeOut, + maxRetry: 0, + retryDelay: 0, + maxRetryDelay: config.fragLoadingMaxRetryTimeout, + highWaterMark: MIN_CHUNK_SIZE, + }; // Assign frag stats to the loader's stats reference - loader.destroy(); - }; + frag.stats = loader.stats; + loader.load(loaderContext, loaderConfig, { + onSuccess: function onSuccess(response, stats, context, networkDetails) { + _this.resetLoader(frag, loader); - return FragmentLoader; -}(); + resolve({ + frag: frag, + part: null, + payload: response.data, + networkDetails: networkDetails, + }); + }, + onError: function onError(response, context, networkDetails) { + _this.resetLoader(frag, loader); + reject( + new LoadError({ + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_ERROR, + fatal: false, + frag: frag, + response: response, + networkDetails: networkDetails, + }) + ); + }, + onAbort: function onAbort(stats, context, networkDetails) { + _this.resetLoader(frag, loader); + reject( + new LoadError({ + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].INTERNAL_ABORTED, + fatal: false, + frag: frag, + networkDetails: networkDetails, + }) + ); + }, + onTimeout: function onTimeout(response, context, networkDetails) { + _this.resetLoader(frag, loader); -function createLoaderContext(frag, part) { - if (part === void 0) { - part = null; - } + reject( + new LoadError({ + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_TIMEOUT, + fatal: false, + frag: frag, + networkDetails: networkDetails, + }) + ); + }, + onProgress: function onProgress(stats, context, data, networkDetails) { + if (_onProgress) { + _onProgress({ + frag: frag, + part: null, + payload: data, + networkDetails: networkDetails, + }); + } + }, + }); + }); + }; - var segment = part || frag; - var loaderContext = { - frag: frag, - part: part, - responseType: 'arraybuffer', - url: segment.url, - headers: {}, - rangeStart: 0, - rangeEnd: 0 - }; - var start = segment.byteRangeStartOffset; - var end = segment.byteRangeEndOffset; + _proto.loadPart = function loadPart(frag, part, onProgress) { + var _this2 = this; - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(start) && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(end)) { - loaderContext.rangeStart = start; - loaderContext.rangeEnd = end; - } + this.abort(); + var config = this.config; + var FragmentILoader = config.fLoader; + var DefaultILoader = config.loader; + return new Promise(function (resolve, reject) { + if (_this2.loader) { + _this2.loader.destroy(); + } - return loaderContext; -} + var loader = (_this2.loader = frag.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config)); + var loaderContext = createLoaderContext(frag, part); + var loaderConfig = { + timeout: config.fragLoadingTimeOut, + maxRetry: 0, + retryDelay: 0, + maxRetryDelay: config.fragLoadingMaxRetryTimeout, + highWaterMark: MIN_CHUNK_SIZE, + }; // Assign part stats to the loader's stats reference -var LoadError = /*#__PURE__*/function (_Error) { - _inheritsLoose(LoadError, _Error); + part.stats = loader.stats; + loader.load(loaderContext, loaderConfig, { + onSuccess: function onSuccess(response, stats, context, networkDetails) { + _this2.resetLoader(frag, loader); - function LoadError(data) { - var _this3; + _this2.updateStatsFromPart(frag, part); - for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - params[_key - 1] = arguments[_key]; - } + var partLoadedData = { + frag: frag, + part: part, + payload: response.data, + networkDetails: networkDetails, + }; + onProgress(partLoadedData); + resolve(partLoadedData); + }, + onError: function onError(response, context, networkDetails) { + _this2.resetLoader(frag, loader); - _this3 = _Error.call.apply(_Error, [this].concat(params)) || this; - _this3.data = void 0; - _this3.data = data; - return _this3; - } + reject( + new LoadError({ + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_ERROR, + fatal: false, + frag: frag, + part: part, + response: response, + networkDetails: networkDetails, + }) + ); + }, + onAbort: function onAbort(stats, context, networkDetails) { + frag.stats.aborted = part.stats.aborted; - return LoadError; -}( /*#__PURE__*/_wrapNativeSuper(Error)); + _this2.resetLoader(frag, loader); -/***/ }), + reject( + new LoadError({ + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].INTERNAL_ABORTED, + fatal: false, + frag: frag, + part: part, + networkDetails: networkDetails, + }) + ); + }, + onTimeout: function onTimeout(response, context, networkDetails) { + _this2.resetLoader(frag, loader); -/***/ "./src/loader/fragment.ts": -/*!********************************!*\ + reject( + new LoadError({ + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].FRAG_LOAD_TIMEOUT, + fatal: false, + frag: frag, + part: part, + networkDetails: networkDetails, + }) + ); + }, + }); + }); + }; + + _proto.updateStatsFromPart = function updateStatsFromPart(frag, part) { + var fragStats = frag.stats; + var partStats = part.stats; + var partTotal = partStats.total; + fragStats.loaded += partStats.loaded; + + if (partTotal) { + var estTotalParts = Math.round(frag.duration / part.duration); + var estLoadedParts = Math.min(Math.round(fragStats.loaded / partTotal), estTotalParts); + var estRemainingParts = estTotalParts - estLoadedParts; + var estRemainingBytes = estRemainingParts * Math.round(fragStats.loaded / estLoadedParts); + fragStats.total = fragStats.loaded + estRemainingBytes; + } else { + fragStats.total = Math.max(fragStats.loaded, fragStats.total); + } + + var fragLoading = fragStats.loading; + var partLoading = partStats.loading; + + if (fragLoading.start) { + // add to fragment loader latency + fragLoading.first += partLoading.first - partLoading.start; + } else { + fragLoading.start = partLoading.start; + fragLoading.first = partLoading.first; + } + + fragLoading.end = partLoading.end; + }; + + _proto.resetLoader = function resetLoader(frag, loader) { + frag.loader = null; + + if (this.loader === loader) { + self.clearTimeout(this.partLoadTimeout); + this.loader = null; + } + + loader.destroy(); + }; + + return FragmentLoader; + })(); + + function createLoaderContext(frag, part) { + if (part === void 0) { + part = null; + } + + var segment = part || frag; + var loaderContext = { + frag: frag, + part: part, + responseType: "arraybuffer", + url: segment.url, + headers: {}, + rangeStart: 0, + rangeEnd: 0, + }; + var start = segment.byteRangeStartOffset; + var end = segment.byteRangeEndOffset; + + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(start) && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(end)) { + loaderContext.rangeStart = start; + loaderContext.rangeEnd = end; + } + + return loaderContext; + } + + var LoadError = /*#__PURE__*/ (function (_Error) { + _inheritsLoose(LoadError, _Error); + + function LoadError(data) { + var _this3; + + for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + params[_key - 1] = arguments[_key]; + } + + _this3 = _Error.call.apply(_Error, [this].concat(params)) || this; + _this3.data = void 0; + _this3.data = data; + return _this3; + } + + return LoadError; + })(/*#__PURE__*/ _wrapNativeSuper(Error)); + + /***/ + }, + + /***/ "./src/loader/fragment.ts": + /*!********************************!*\ !*** ./src/loader/fragment.ts ***! \********************************/ -/*! exports provided: ElementaryStreamTypes, BaseSegment, Fragment, Part */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: ElementaryStreamTypes, BaseSegment, Fragment, Part */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ElementaryStreamTypes", function () { + return ElementaryStreamTypes; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSegment", function () { + return BaseSegment; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Fragment", function () { + return Fragment; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Part", function () { + return Part; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _level_key__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./level-key */ "./src/loader/level-key.ts"); + /* harmony import */ var _load_stats__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./load-stats */ "./src/loader/load-stats.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ElementaryStreamTypes", function() { return ElementaryStreamTypes; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSegment", function() { return BaseSegment; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Fragment", function() { return Fragment; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Part", function() { return Part; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _level_key__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./level-key */ "./src/loader/level-key.ts"); -/* harmony import */ var _load_stats__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./load-stats */ "./src/loader/load-stats.ts"); + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + var ElementaryStreamTypes; -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + (function (ElementaryStreamTypes) { + ElementaryStreamTypes["AUDIO"] = "audio"; + ElementaryStreamTypes["VIDEO"] = "video"; + ElementaryStreamTypes["AUDIOVIDEO"] = "audiovideo"; + })(ElementaryStreamTypes || (ElementaryStreamTypes = {})); -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + var BaseSegment = /*#__PURE__*/ (function () { + // baseurl is the URL to the playlist + // relurl is the portion of the URL that comes from inside the playlist. + // Holds the types of data this fragment supports + function BaseSegment(baseurl) { + var _this$elementaryStrea; + this._byteRange = null; + this._url = null; + this.baseurl = void 0; + this.relurl = void 0; + this.elementaryStreams = ((_this$elementaryStrea = {}), (_this$elementaryStrea[ElementaryStreamTypes.AUDIO] = null), (_this$elementaryStrea[ElementaryStreamTypes.VIDEO] = null), (_this$elementaryStrea[ElementaryStreamTypes.AUDIOVIDEO] = null), _this$elementaryStrea); + this.baseurl = baseurl; + } // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array + var _proto = BaseSegment.prototype; + _proto.setByteRange = function setByteRange(value, previous) { + var params = value.split("@", 2); + var byteRange = []; + if (params.length === 1) { + byteRange[0] = previous ? previous.byteRangeEndOffset : 0; + } else { + byteRange[0] = parseInt(params[1]); + } -var ElementaryStreamTypes; + byteRange[1] = parseInt(params[0]) + byteRange[0]; + this._byteRange = byteRange; + }; -(function (ElementaryStreamTypes) { - ElementaryStreamTypes["AUDIO"] = "audio"; - ElementaryStreamTypes["VIDEO"] = "video"; - ElementaryStreamTypes["AUDIOVIDEO"] = "audiovideo"; -})(ElementaryStreamTypes || (ElementaryStreamTypes = {})); + _createClass(BaseSegment, [ + { + key: "byteRange", + get: function get() { + if (!this._byteRange) { + return []; + } -var BaseSegment = /*#__PURE__*/function () { - // baseurl is the URL to the playlist - // relurl is the portion of the URL that comes from inside the playlist. - // Holds the types of data this fragment supports - function BaseSegment(baseurl) { - var _this$elementaryStrea; + return this._byteRange; + }, + }, + { + key: "byteRangeStartOffset", + get: function get() { + return this.byteRange[0]; + }, + }, + { + key: "byteRangeEndOffset", + get: function get() { + return this.byteRange[1]; + }, + }, + { + key: "url", + get: function get() { + if (!this._url && this.baseurl && this.relurl) { + this._url = Object(url_toolkit__WEBPACK_IMPORTED_MODULE_1__["buildAbsoluteURL"])(this.baseurl, this.relurl, { + alwaysNormalize: true, + }); + } - this._byteRange = null; - this._url = null; - this.baseurl = void 0; - this.relurl = void 0; - this.elementaryStreams = (_this$elementaryStrea = {}, _this$elementaryStrea[ElementaryStreamTypes.AUDIO] = null, _this$elementaryStrea[ElementaryStreamTypes.VIDEO] = null, _this$elementaryStrea[ElementaryStreamTypes.AUDIOVIDEO] = null, _this$elementaryStrea); - this.baseurl = baseurl; - } // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array + return this._url || ""; + }, + set: function set(value) { + this._url = value; + }, + }, + ]); + return BaseSegment; + })(); + var Fragment = /*#__PURE__*/ (function (_BaseSegment) { + _inheritsLoose(Fragment, _BaseSegment); - var _proto = BaseSegment.prototype; + // EXTINF has to be present for a m38 to be considered valid + // sn notates the sequence number for a segment, and if set to a string can be 'initSegment' + // levelkey is the EXT-X-KEY that applies to this segment for decryption + // core difference from the private field _decryptdata is the lack of the initialized IV + // _decryptdata will set the IV for this segment based on the segment number in the fragment + // A string representing the fragment type + // A reference to the loader. Set while the fragment is loading, and removed afterwards. Used to abort fragment loading + // The level/track index to which the fragment belongs + // The continuity counter of the fragment + // The starting Presentation Time Stamp (PTS) of the fragment. Set after transmux complete. + // The ending Presentation Time Stamp (PTS) of the fragment. Set after transmux complete. + // The latest Presentation Time Stamp (PTS) appended to the buffer. + // The starting Decode Time Stamp (DTS) of the fragment. Set after transmux complete. + // The ending Decode Time Stamp (DTS) of the fragment. Set after transmux complete. + // The start time of the fragment, as listed in the manifest. Updated after transmux complete. + // Set by `updateFragPTSDTS` in level-helper + // The maximum starting Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete. + // The minimum ending Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete. + // Load/parse timing information + // A flag indicating whether the segment was downloaded in order to test bitrate, and was not buffered + // #EXTINF segment title + // The Media Initialization Section for this segment + function Fragment(type, baseurl) { + var _this; - _proto.setByteRange = function setByteRange(value, previous) { - var params = value.split('@', 2); - var byteRange = []; + _this = _BaseSegment.call(this, baseurl) || this; + _this._decryptdata = null; + _this.rawProgramDateTime = null; + _this.programDateTime = null; + _this.tagList = []; + _this.duration = 0; + _this.sn = 0; + _this.levelkey = void 0; + _this.type = void 0; + _this.loader = null; + _this.level = -1; + _this.cc = 0; + _this.startPTS = void 0; + _this.endPTS = void 0; + _this.appendedPTS = void 0; + _this.startDTS = void 0; + _this.endDTS = void 0; + _this.start = 0; + _this.deltaPTS = void 0; + _this.maxStartPTS = void 0; + _this.minEndPTS = void 0; + _this.stats = new _load_stats__WEBPACK_IMPORTED_MODULE_4__["LoadStats"](); + _this.urlId = 0; + _this.data = void 0; + _this.bitrateTest = false; + _this.title = null; + _this.initSegment = null; + _this.type = type; + return _this; + } - if (params.length === 1) { - byteRange[0] = previous ? previous.byteRangeEndOffset : 0; - } else { - byteRange[0] = parseInt(params[1]); - } + var _proto2 = Fragment.prototype; - byteRange[1] = parseInt(params[0]) + byteRange[0]; - this._byteRange = byteRange; - }; + /** + * Utility method for parseLevelPlaylist to create an initialization vector for a given segment + * @param {number} segmentNumber - segment number to generate IV with + * @returns {Uint8Array} + */ + _proto2.createInitializationVector = function createInitializationVector(segmentNumber) { + var uint8View = new Uint8Array(16); - _createClass(BaseSegment, [{ - key: "byteRange", - get: function get() { - if (!this._byteRange) { - return []; - } + for (var i = 12; i < 16; i++) { + uint8View[i] = (segmentNumber >> (8 * (15 - i))) & 0xff; + } - return this._byteRange; - } - }, { - key: "byteRangeStartOffset", - get: function get() { - return this.byteRange[0]; - } - }, { - key: "byteRangeEndOffset", - get: function get() { - return this.byteRange[1]; - } - }, { - key: "url", - get: function get() { - if (!this._url && this.baseurl && this.relurl) { - this._url = Object(url_toolkit__WEBPACK_IMPORTED_MODULE_1__["buildAbsoluteURL"])(this.baseurl, this.relurl, { - alwaysNormalize: true - }); - } + return uint8View; + }; + /** + * Utility method for parseLevelPlaylist to get a fragment's decryption data from the currently parsed encryption key data + * @param levelkey - a playlist's encryption info + * @param segmentNumber - the fragment's segment number + * @returns {LevelKey} - an object to be applied as a fragment's decryptdata + */ - return this._url || ''; - }, - set: function set(value) { - this._url = value; - } - }]); + _proto2.setDecryptDataFromLevelKey = function setDecryptDataFromLevelKey(levelkey, segmentNumber) { + var decryptdata = levelkey; - return BaseSegment; -}(); -var Fragment = /*#__PURE__*/function (_BaseSegment) { - _inheritsLoose(Fragment, _BaseSegment); + if ((levelkey === null || levelkey === void 0 ? void 0 : levelkey.method) === "AES-128" && levelkey.uri && !levelkey.iv) { + decryptdata = _level_key__WEBPACK_IMPORTED_MODULE_3__["LevelKey"].fromURI(levelkey.uri); + decryptdata.method = levelkey.method; + decryptdata.iv = this.createInitializationVector(segmentNumber); + decryptdata.keyFormat = "identity"; + } - // EXTINF has to be present for a m38 to be considered valid - // sn notates the sequence number for a segment, and if set to a string can be 'initSegment' - // levelkey is the EXT-X-KEY that applies to this segment for decryption - // core difference from the private field _decryptdata is the lack of the initialized IV - // _decryptdata will set the IV for this segment based on the segment number in the fragment - // A string representing the fragment type - // A reference to the loader. Set while the fragment is loading, and removed afterwards. Used to abort fragment loading - // The level/track index to which the fragment belongs - // The continuity counter of the fragment - // The starting Presentation Time Stamp (PTS) of the fragment. Set after transmux complete. - // The ending Presentation Time Stamp (PTS) of the fragment. Set after transmux complete. - // The latest Presentation Time Stamp (PTS) appended to the buffer. - // The starting Decode Time Stamp (DTS) of the fragment. Set after transmux complete. - // The ending Decode Time Stamp (DTS) of the fragment. Set after transmux complete. - // The start time of the fragment, as listed in the manifest. Updated after transmux complete. - // Set by `updateFragPTSDTS` in level-helper - // The maximum starting Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete. - // The minimum ending Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete. - // Load/parse timing information - // A flag indicating whether the segment was downloaded in order to test bitrate, and was not buffered - // #EXTINF segment title - // The Media Initialization Section for this segment - function Fragment(type, baseurl) { - var _this; + return decryptdata; + }; - _this = _BaseSegment.call(this, baseurl) || this; - _this._decryptdata = null; - _this.rawProgramDateTime = null; - _this.programDateTime = null; - _this.tagList = []; - _this.duration = 0; - _this.sn = 0; - _this.levelkey = void 0; - _this.type = void 0; - _this.loader = null; - _this.level = -1; - _this.cc = 0; - _this.startPTS = void 0; - _this.endPTS = void 0; - _this.appendedPTS = void 0; - _this.startDTS = void 0; - _this.endDTS = void 0; - _this.start = 0; - _this.deltaPTS = void 0; - _this.maxStartPTS = void 0; - _this.minEndPTS = void 0; - _this.stats = new _load_stats__WEBPACK_IMPORTED_MODULE_4__["LoadStats"](); - _this.urlId = 0; - _this.data = void 0; - _this.bitrateTest = false; - _this.title = null; - _this.initSegment = null; - _this.type = type; - return _this; - } + _proto2.setElementaryStreamInfo = function setElementaryStreamInfo(type, startPTS, endPTS, startDTS, endDTS, partial) { + if (partial === void 0) { + partial = false; + } - var _proto2 = Fragment.prototype; + var elementaryStreams = this.elementaryStreams; + var info = elementaryStreams[type]; - /** - * Utility method for parseLevelPlaylist to create an initialization vector for a given segment - * @param {number} segmentNumber - segment number to generate IV with - * @returns {Uint8Array} - */ - _proto2.createInitializationVector = function createInitializationVector(segmentNumber) { - var uint8View = new Uint8Array(16); + if (!info) { + elementaryStreams[type] = { + startPTS: startPTS, + endPTS: endPTS, + startDTS: startDTS, + endDTS: endDTS, + partial: partial, + }; + return; + } - for (var i = 12; i < 16; i++) { - uint8View[i] = segmentNumber >> 8 * (15 - i) & 0xff; - } + info.startPTS = Math.min(info.startPTS, startPTS); + info.endPTS = Math.max(info.endPTS, endPTS); + info.startDTS = Math.min(info.startDTS, startDTS); + info.endDTS = Math.max(info.endDTS, endDTS); + }; - return uint8View; - } - /** - * Utility method for parseLevelPlaylist to get a fragment's decryption data from the currently parsed encryption key data - * @param levelkey - a playlist's encryption info - * @param segmentNumber - the fragment's segment number - * @returns {LevelKey} - an object to be applied as a fragment's decryptdata - */ - ; + _proto2.clearElementaryStreamInfo = function clearElementaryStreamInfo() { + var elementaryStreams = this.elementaryStreams; + elementaryStreams[ElementaryStreamTypes.AUDIO] = null; + elementaryStreams[ElementaryStreamTypes.VIDEO] = null; + elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null; + }; - _proto2.setDecryptDataFromLevelKey = function setDecryptDataFromLevelKey(levelkey, segmentNumber) { - var decryptdata = levelkey; + _createClass(Fragment, [ + { + key: "decryptdata", + get: function get() { + if (!this.levelkey && !this._decryptdata) { + return null; + } - if ((levelkey === null || levelkey === void 0 ? void 0 : levelkey.method) === 'AES-128' && levelkey.uri && !levelkey.iv) { - decryptdata = _level_key__WEBPACK_IMPORTED_MODULE_3__["LevelKey"].fromURI(levelkey.uri); - decryptdata.method = levelkey.method; - decryptdata.iv = this.createInitializationVector(segmentNumber); - decryptdata.keyFormat = 'identity'; - } + if (!this._decryptdata && this.levelkey) { + var sn = this.sn; - return decryptdata; - }; - - _proto2.setElementaryStreamInfo = function setElementaryStreamInfo(type, startPTS, endPTS, startDTS, endDTS, partial) { - if (partial === void 0) { - partial = false; - } - - var elementaryStreams = this.elementaryStreams; - var info = elementaryStreams[type]; - - if (!info) { - elementaryStreams[type] = { - startPTS: startPTS, - endPTS: endPTS, - startDTS: startDTS, - endDTS: endDTS, - partial: partial - }; - return; - } - - info.startPTS = Math.min(info.startPTS, startPTS); - info.endPTS = Math.max(info.endPTS, endPTS); - info.startDTS = Math.min(info.startDTS, startDTS); - info.endDTS = Math.max(info.endDTS, endDTS); - }; - - _proto2.clearElementaryStreamInfo = function clearElementaryStreamInfo() { - var elementaryStreams = this.elementaryStreams; - elementaryStreams[ElementaryStreamTypes.AUDIO] = null; - elementaryStreams[ElementaryStreamTypes.VIDEO] = null; - elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null; - }; - - _createClass(Fragment, [{ - key: "decryptdata", - get: function get() { - if (!this.levelkey && !this._decryptdata) { - return null; - } - - if (!this._decryptdata && this.levelkey) { - var sn = this.sn; - - if (typeof sn !== 'number') { - // We are fetching decryption data for a initialization segment - // If the segment was encrypted with AES-128 - // It must have an IV defined. We cannot substitute the Segment Number in. - if (this.levelkey && this.levelkey.method === 'AES-128' && !this.levelkey.iv) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("missing IV for initialization segment with method=\"" + this.levelkey.method + "\" - compliance issue"); - } - /* + if (typeof sn !== "number") { + // We are fetching decryption data for a initialization segment + // If the segment was encrypted with AES-128 + // It must have an IV defined. We cannot substitute the Segment Number in. + if (this.levelkey && this.levelkey.method === "AES-128" && !this.levelkey.iv) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn('missing IV for initialization segment with method="' + this.levelkey.method + '" - compliance issue'); + } + /* Be converted to a Number. 'initSegment' will become NaN. NaN, which when converted through ToInt32() -> +0. @@ -18547,7445 +18999,8293 @@ var Fragment = /*#__PURE__*/function (_BaseSegment) { Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation. */ + sn = 0; + } - sn = 0; - } + this._decryptdata = this.setDecryptDataFromLevelKey(this.levelkey, sn); + } - this._decryptdata = this.setDecryptDataFromLevelKey(this.levelkey, sn); - } + return this._decryptdata; + }, + }, + { + key: "end", + get: function get() { + return this.start + this.duration; + }, + }, + { + key: "endProgramDateTime", + get: function get() { + if (this.programDateTime === null) { + return null; + } - return this._decryptdata; - } - }, { - key: "end", - get: function get() { - return this.start + this.duration; - } - }, { - key: "endProgramDateTime", - get: function get() { - if (this.programDateTime === null) { - return null; - } + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.programDateTime)) { + return null; + } - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.programDateTime)) { - return null; - } + var duration = !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.duration) ? 0 : this.duration; + return this.programDateTime + duration * 1000; + }, + }, + { + key: "encrypted", + get: function get() { + var _this$decryptdata; - var duration = !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.duration) ? 0 : this.duration; - return this.programDateTime + duration * 1000; - } - }, { - key: "encrypted", - get: function get() { - var _this$decryptdata; + // At the m3u8-parser level we need to add support for manifest signalled keyformats + // when we want the fragment to start reporting that it is encrypted. + // Currently, keyFormat will only be set for identity keys + if ((_this$decryptdata = this.decryptdata) !== null && _this$decryptdata !== void 0 && _this$decryptdata.keyFormat && this.decryptdata.uri) { + return true; + } - // At the m3u8-parser level we need to add support for manifest signalled keyformats - // when we want the fragment to start reporting that it is encrypted. - // Currently, keyFormat will only be set for identity keys - if ((_this$decryptdata = this.decryptdata) !== null && _this$decryptdata !== void 0 && _this$decryptdata.keyFormat && this.decryptdata.uri) { - return true; - } + return false; + }, + }, + ]); - return false; - } - }]); + return Fragment; + })(BaseSegment); + var Part = /*#__PURE__*/ (function (_BaseSegment2) { + _inheritsLoose(Part, _BaseSegment2); - return Fragment; -}(BaseSegment); -var Part = /*#__PURE__*/function (_BaseSegment2) { - _inheritsLoose(Part, _BaseSegment2); + function Part(partAttrs, frag, baseurl, index, previous) { + var _this2; - function Part(partAttrs, frag, baseurl, index, previous) { - var _this2; + _this2 = _BaseSegment2.call(this, baseurl) || this; + _this2.fragOffset = 0; + _this2.duration = 0; + _this2.gap = false; + _this2.independent = false; + _this2.relurl = void 0; + _this2.fragment = void 0; + _this2.index = void 0; + _this2.stats = new _load_stats__WEBPACK_IMPORTED_MODULE_4__["LoadStats"](); + _this2.duration = partAttrs.decimalFloatingPoint("DURATION"); + _this2.gap = partAttrs.bool("GAP"); + _this2.independent = partAttrs.bool("INDEPENDENT"); + _this2.relurl = partAttrs.enumeratedString("URI"); + _this2.fragment = frag; + _this2.index = index; + var byteRange = partAttrs.enumeratedString("BYTERANGE"); - _this2 = _BaseSegment2.call(this, baseurl) || this; - _this2.fragOffset = 0; - _this2.duration = 0; - _this2.gap = false; - _this2.independent = false; - _this2.relurl = void 0; - _this2.fragment = void 0; - _this2.index = void 0; - _this2.stats = new _load_stats__WEBPACK_IMPORTED_MODULE_4__["LoadStats"](); - _this2.duration = partAttrs.decimalFloatingPoint('DURATION'); - _this2.gap = partAttrs.bool('GAP'); - _this2.independent = partAttrs.bool('INDEPENDENT'); - _this2.relurl = partAttrs.enumeratedString('URI'); - _this2.fragment = frag; - _this2.index = index; - var byteRange = partAttrs.enumeratedString('BYTERANGE'); + if (byteRange) { + _this2.setByteRange(byteRange, previous); + } - if (byteRange) { - _this2.setByteRange(byteRange, previous); - } + if (previous) { + _this2.fragOffset = previous.fragOffset + previous.duration; + } - if (previous) { - _this2.fragOffset = previous.fragOffset + previous.duration; - } + return _this2; + } - return _this2; - } + _createClass(Part, [ + { + key: "start", + get: function get() { + return this.fragment.start + this.fragOffset; + }, + }, + { + key: "end", + get: function get() { + return this.start + this.duration; + }, + }, + { + key: "loaded", + get: function get() { + var elementaryStreams = this.elementaryStreams; + return !!(elementaryStreams.audio || elementaryStreams.video || elementaryStreams.audiovideo); + }, + }, + ]); - _createClass(Part, [{ - key: "start", - get: function get() { - return this.fragment.start + this.fragOffset; - } - }, { - key: "end", - get: function get() { - return this.start + this.duration; - } - }, { - key: "loaded", - get: function get() { - var elementaryStreams = this.elementaryStreams; - return !!(elementaryStreams.audio || elementaryStreams.video || elementaryStreams.audiovideo); - } - }]); + return Part; + })(BaseSegment); - return Part; -}(BaseSegment); + /***/ + }, -/***/ }), - -/***/ "./src/loader/key-loader.ts": -/*!**********************************!*\ + /***/ "./src/loader/key-loader.ts": + /*!**********************************!*\ !*** ./src/loader/key-loader.ts ***! \**********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return KeyLoader; }); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* - * Decrypt key Loader - */ - - - - -var KeyLoader = /*#__PURE__*/function () { - function KeyLoader(CiderHls) { - this.CiderHls = void 0; - this.loaders = {}; - this.decryptkey = null; - this.decrypturl = null; - this.CiderHls = CiderHls; - - this._registerListeners(); - } - - var _proto = KeyLoader.prototype; - - _proto._registerListeners = function _registerListeners() { - this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADING, this.onKeyLoading, this); - }; - - _proto._unregisterListeners = function _unregisterListeners() { - this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADING, this.onKeyLoading); - }; - - _proto.destroy = function destroy() { - this._unregisterListeners(); - - for (var loaderName in this.loaders) { - var loader = this.loaders[loaderName]; - - if (loader) { - loader.destroy(); - } - } - - this.loaders = {}; - }; - - _proto.onKeyLoading = function onKeyLoading(event, data) { - var frag = data.frag; - var type = frag.type; - var loader = this.loaders[type]; - - if (!frag.decryptdata) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn('Missing decryption data on fragment in onKeyLoading'); - return; - } // Load the key if the uri is different from previous one, or if the decrypt key has not yet been retrieved - - - var uri = frag.decryptdata.uri; - - if (uri !== this.decrypturl || this.decryptkey === null) { - var config = this.CiderHls.config; - - if (loader) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("abort previous key loader for type:" + type); - loader.abort(); - } - - if (!uri) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn('key uri is falsy'); - return; - } - - var Loader = config.loader; - var fragLoader = frag.loader = this.loaders[type] = new Loader(config); - this.decrypturl = uri; - this.decryptkey = null; - var loaderContext = { - url: uri, - frag: frag, - responseType: 'arraybuffer' - }; // maxRetry is 0 so that instead of retrying the same key on the same variant multiple times, - // key-loader will trigger an error and rely on stream-controller to handle retry logic. - // this will also align retry logic with fragment-loader - - var loaderConfig = { - timeout: config.fragLoadingTimeOut, - maxRetry: 0, - retryDelay: config.fragLoadingRetryDelay, - maxRetryDelay: config.fragLoadingMaxRetryTimeout, - highWaterMark: 0 - }; - var loaderCallbacks = { - onSuccess: this.loadsuccess.bind(this), - onError: this.loaderror.bind(this), - onTimeout: this.loadtimeout.bind(this) - }; - fragLoader.load(loaderContext, loaderConfig, loaderCallbacks); - } else if (this.decryptkey) { - // Return the key if it's already been loaded - frag.decryptdata.key = this.decryptkey; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADED, { - frag: frag - }); - } - }; - - _proto.loadsuccess = function loadsuccess(response, stats, context) { - var frag = context.frag; - - if (!frag.decryptdata) { - _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error('after key load, decryptdata unset'); - return; - } - - this.decryptkey = frag.decryptdata.key = new Uint8Array(response.data); // detach fragment loader on load success - - frag.loader = null; - delete this.loaders[frag.type]; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADED, { - frag: frag - }); - }; - - _proto.loaderror = function loaderror(response, context) { - var frag = context.frag; - var loader = frag.loader; - - if (loader) { - loader.abort(); - } - - delete this.loaders[frag.type]; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_LOAD_ERROR, - fatal: false, - frag: frag, - response: response - }); - }; - - _proto.loadtimeout = function loadtimeout(stats, context) { - var frag = context.frag; - var loader = frag.loader; - - if (loader) { - loader.abort(); - } - - delete this.loaders[frag.type]; - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_LOAD_TIMEOUT, - fatal: false, - frag: frag - }); - }; - - return KeyLoader; -}(); - - - -/***/ }), - -/***/ "./src/loader/level-details.ts": -/*!*************************************!*\ - !*** ./src/loader/level-details.ts ***! - \*************************************/ -/*! exports provided: LevelDetails */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LevelDetails", function() { return LevelDetails; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); - - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -var DEFAULT_TARGET_DURATION = 10; -var LevelDetails = /*#__PURE__*/function () { - // Manifest reload synchronization - function LevelDetails(baseUrl) { - this.PTSKnown = false; - this.alignedSliding = false; - this.averagetargetduration = void 0; - this.endCC = 0; - this.endSN = 0; - this.fragments = void 0; - this.fragmentHint = void 0; - this.partList = null; - this.live = true; - this.ageHeader = 0; - this.advancedDateTime = void 0; - this.updated = true; - this.advanced = true; - this.availabilityDelay = void 0; - this.misses = 0; - this.needSidxRanges = false; - this.startCC = 0; - this.startSN = 0; - this.startTimeOffset = null; - this.targetduration = 0; - this.totalduration = 0; - this.type = null; - this.url = void 0; - this.m3u8 = ''; - this.version = null; - this.canBlockReload = false; - this.canSkipUntil = 0; - this.canSkipDateRanges = false; - this.skippedSegments = 0; - this.recentlyRemovedDateranges = void 0; - this.partHoldBack = 0; - this.holdBack = 0; - this.partTarget = 0; - this.preloadHint = void 0; - this.renditionReports = void 0; - this.tuneInGoal = 0; - this.deltaUpdateFailed = void 0; - this.driftStartTime = 0; - this.driftEndTime = 0; - this.driftStart = 0; - this.driftEnd = 0; - this.fragments = []; - this.url = baseUrl; - } - - var _proto = LevelDetails.prototype; - - _proto.reloaded = function reloaded(previous) { - if (!previous) { - this.advanced = true; - this.updated = true; - return; - } - - var partSnDiff = this.lastPartSn - previous.lastPartSn; - var partIndexDiff = this.lastPartIndex - previous.lastPartIndex; - this.updated = this.endSN !== previous.endSN || !!partIndexDiff || !!partSnDiff; - this.advanced = this.endSN > previous.endSN || partSnDiff > 0 || partSnDiff === 0 && partIndexDiff > 0; - - if (this.updated || this.advanced) { - this.misses = Math.floor(previous.misses * 0.6); - } else { - this.misses = previous.misses + 1; - } - - this.availabilityDelay = previous.availabilityDelay; - }; - - _createClass(LevelDetails, [{ - key: "hasProgramDateTime", - get: function get() { - if (this.fragments.length) { - return Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.fragments[this.fragments.length - 1].programDateTime); - } - - return false; - } - }, { - key: "levelTargetDuration", - get: function get() { - return this.averagetargetduration || this.targetduration || DEFAULT_TARGET_DURATION; - } - }, { - key: "drift", - get: function get() { - var runTime = this.driftEndTime - this.driftStartTime; - - if (runTime > 0) { - var runDuration = this.driftEnd - this.driftStart; - return runDuration * 1000 / runTime; - } - - return 1; - } - }, { - key: "edge", - get: function get() { - return this.partEnd || this.fragmentEnd; - } - }, { - key: "partEnd", - get: function get() { - var _this$partList; - - if ((_this$partList = this.partList) !== null && _this$partList !== void 0 && _this$partList.length) { - return this.partList[this.partList.length - 1].end; - } - - return this.fragmentEnd; - } - }, { - key: "fragmentEnd", - get: function get() { - var _this$fragments; - - if ((_this$fragments = this.fragments) !== null && _this$fragments !== void 0 && _this$fragments.length) { - return this.fragments[this.fragments.length - 1].end; - } - - return 0; - } - }, { - key: "age", - get: function get() { - if (this.advancedDateTime) { - return Math.max(Date.now() - this.advancedDateTime, 0) / 1000; - } - - return 0; - } - }, { - key: "lastPartIndex", - get: function get() { - var _this$partList2; - - if ((_this$partList2 = this.partList) !== null && _this$partList2 !== void 0 && _this$partList2.length) { - return this.partList[this.partList.length - 1].index; - } - - return -1; - } - }, { - key: "lastPartSn", - get: function get() { - var _this$partList3; - - if ((_this$partList3 = this.partList) !== null && _this$partList3 !== void 0 && _this$partList3.length) { - return this.partList[this.partList.length - 1].fragment.sn; - } - - return this.endSN; - } - }]); - - return LevelDetails; -}(); - -/***/ }), - -/***/ "./src/loader/level-key.ts": -/*!*********************************!*\ - !*** ./src/loader/level-key.ts ***! - \*********************************/ -/*! exports provided: LevelKey */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LevelKey", function() { return LevelKey; }); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_0__); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - - -var LevelKey = /*#__PURE__*/function () { - LevelKey.fromURL = function fromURL(baseUrl, relativeUrl) { - return new LevelKey(baseUrl, relativeUrl); - }; - - LevelKey.fromURI = function fromURI(uri) { - return new LevelKey(uri); - }; - - function LevelKey(absoluteOrBaseURI, relativeURL) { - this._uri = null; - this.method = null; - this.keyFormat = null; - this.keyFormatVersions = null; - this.keyID = null; - this.key = null; - this.iv = null; - - if (relativeURL) { - this._uri = Object(url_toolkit__WEBPACK_IMPORTED_MODULE_0__["buildAbsoluteURL"])(absoluteOrBaseURI, relativeURL, { - alwaysNormalize: true - }); - } else { - this._uri = absoluteOrBaseURI; - } - } - - _createClass(LevelKey, [{ - key: "uri", - get: function get() { - return this._uri; - } - }]); - - return LevelKey; -}(); - -/***/ }), - -/***/ "./src/loader/load-stats.ts": -/*!**********************************!*\ - !*** ./src/loader/load-stats.ts ***! - \**********************************/ -/*! exports provided: LoadStats */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoadStats", function() { return LoadStats; }); -var LoadStats = function LoadStats() { - this.aborted = false; - this.loaded = 0; - this.retry = 0; - this.total = 0; - this.chunkCount = 0; - this.bwEstimate = 0; - this.loading = { - start: 0, - first: 0, - end: 0 - }; - this.parsing = { - start: 0, - end: 0 - }; - this.buffering = { - start: 0, - first: 0, - end: 0 - }; -}; - -/***/ }), - -/***/ "./src/loader/m3u8-parser.ts": -/*!***********************************!*\ - !*** ./src/loader/m3u8-parser.ts ***! - \***********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return M3U8Parser; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); -/* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fragment */ "./src/loader/fragment.ts"); -/* harmony import */ var _level_details__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./level-details */ "./src/loader/level-details.ts"); -/* harmony import */ var _level_key__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./level-key */ "./src/loader/level-key.ts"); -/* harmony import */ var _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/attr-list */ "./src/utils/attr-list.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _utils_codecs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/codecs */ "./src/utils/codecs.ts"); - - - - - - - - - - - -// https://regex101.com is your friend -var MASTER_PLAYLIST_REGEX = /#EXT-X-STREAM-INF:([^\r\n]*)(?:[\r\n](?:#[^\r\n]*)?)*([^\r\n]+)|#EXT-X-SESSION-DATA:([^\r\n]*)[\r\n]+/g; -var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g; -var LEVEL_PLAYLIST_REGEX_FAST = new RegExp([/#EXTINF:\s*(\d*(?:\.\d+)?)(?:,(.*)\s+)?/.source, // duration (#EXTINF:,), group 1 => duration, group 2 => title -/(?!#) *(\S[\S ]*)/.source, // segment URI, group 3 => the URI (note newline is not eaten) -/#EXT-X-BYTERANGE:*(.+)/.source, // next segment's byterange, group 4 => range spec (x@y) -/#EXT-X-PROGRAM-DATE-TIME:(.+)/.source, // next segment's program date/time group 5 => the datetime spec -/#.*/.source // All other non-segment oriented tags will match with all groups empty -].join('|'), 'g'); -var LEVEL_PLAYLIST_REGEX_SLOW = new RegExp([/#(EXTM3U)/.source, /#EXT-X-(PLAYLIST-TYPE):(.+)/.source, /#EXT-X-(MEDIA-SEQUENCE): *(\d+)/.source, /#EXT-X-(SKIP):(.+)/.source, /#EXT-X-(TARGETDURATION): *(\d+)/.source, /#EXT-X-(KEY):(.+)/.source, /#EXT-X-(START):(.+)/.source, /#EXT-X-(ENDLIST)/.source, /#EXT-X-(DISCONTINUITY-SEQ)UENCE: *(\d+)/.source, /#EXT-X-(DIS)CONTINUITY/.source, /#EXT-X-(VERSION):(\d+)/.source, /#EXT-X-(MAP):(.+)/.source, /#EXT-X-(SERVER-CONTROL):(.+)/.source, /#EXT-X-(PART-INF):(.+)/.source, /#EXT-X-(GAP)/.source, /#EXT-X-(BITRATE):\s*(\d+)/.source, /#EXT-X-(PART):(.+)/.source, /#EXT-X-(PRELOAD-HINT):(.+)/.source, /#EXT-X-(RENDITION-REPORT):(.+)/.source, /(#)([^:]*):(.*)/.source, /(#)(.*)(?:.*)\r?\n?/.source].join('|')); -var MP4_REGEX_SUFFIX = /\.(mp4|m4s|m4v|m4a)$/i; - -function isMP4Url(url) { - var _URLToolkit$parseURL$, _URLToolkit$parseURL; - - return MP4_REGEX_SUFFIX.test((_URLToolkit$parseURL$ = (_URLToolkit$parseURL = url_toolkit__WEBPACK_IMPORTED_MODULE_1__["parseURL"](url)) === null || _URLToolkit$parseURL === void 0 ? void 0 : _URLToolkit$parseURL.path) != null ? _URLToolkit$parseURL$ : ''); -} - -var M3U8Parser = /*#__PURE__*/function () { - function M3U8Parser() {} - - M3U8Parser.findGroup = function findGroup(groups, mediaGroupId) { - for (var i = 0; i < groups.length; i++) { - var group = groups[i]; - - if (group.id === mediaGroupId) { - return group; - } - } - }; - - M3U8Parser.convertAVC1ToAVCOTI = function convertAVC1ToAVCOTI(codec) { - // Convert avc1 codec string from RFC-4281 to RFC-6381 for MediaSource.isTypeSupported - var avcdata = codec.split('.'); - - if (avcdata.length > 2) { - var result = avcdata.shift() + '.'; - result += parseInt(avcdata.shift()).toString(16); - result += ('000' + parseInt(avcdata.shift()).toString(16)).substr(-4); - return result; - } - - return codec; - }; - - M3U8Parser.resolve = function resolve(url, baseUrl) { - return url_toolkit__WEBPACK_IMPORTED_MODULE_1__["buildAbsoluteURL"](baseUrl, url, { - alwaysNormalize: true - }); - }; - - M3U8Parser.parseMasterPlaylist = function parseMasterPlaylist(string, baseurl) { - var levels = []; - var sessionData = {}; - var hasSessionData = false; - MASTER_PLAYLIST_REGEX.lastIndex = 0; - var result; - - while ((result = MASTER_PLAYLIST_REGEX.exec(string)) != null) { - if (result[1]) { - // '#EXT-X-STREAM-INF' is found, parse level tag in group 1 - var attrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](result[1]); - var level = { - attrs: attrs, - bitrate: attrs.decimalInteger('AVERAGE-BANDWIDTH') || attrs.decimalInteger('BANDWIDTH'), - name: attrs.NAME, - url: M3U8Parser.resolve(result[2], baseurl) - }; - var resolution = attrs.decimalResolution('RESOLUTION'); - - if (resolution) { - level.width = resolution.width; - level.height = resolution.height; - } - - setCodecs((attrs.CODECS || '').split(/[ ,]+/).filter(function (c) { - return c; - }), level); - - if (level.videoCodec && level.videoCodec.indexOf('avc1') !== -1) { - level.videoCodec = M3U8Parser.convertAVC1ToAVCOTI(level.videoCodec); - } - - levels.push(level); - } else if (result[3]) { - // '#EXT-X-SESSION-DATA' is found, parse session data in group 3 - var sessionAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](result[3]); - - if (sessionAttrs['DATA-ID']) { - hasSessionData = true; - sessionData[sessionAttrs['DATA-ID']] = sessionAttrs; - } - } - } - if (levels && levels.length > 0) { - levels = levels.sort(function (a, b) { - return a.bitrate - b.bitrate; - }); - } - return { - levels: levels, - sessionData: hasSessionData ? sessionData : null - }; - }; - - M3U8Parser.parseMasterPlaylistMedia = function parseMasterPlaylistMedia(string, baseurl, type, groups) { - if (groups === void 0) { - groups = []; - } - - var result; - var medias = []; - var id = 0; - MASTER_PLAYLIST_MEDIA_REGEX.lastIndex = 0; - - while ((result = MASTER_PLAYLIST_MEDIA_REGEX.exec(string)) !== null) { - var attrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](result[1]); - - if (attrs.TYPE === type) { - var media = { - attrs: attrs, - bitrate: 0, - id: id++, - groupId: attrs['GROUP-ID'], - instreamId: attrs['INSTREAM-ID'], - name: attrs.NAME || attrs.LANGUAGE || '', - type: type, - default: attrs.bool('DEFAULT'), - autoselect: attrs.bool('AUTOSELECT'), - forced: attrs.bool('FORCED'), - lang: attrs.LANGUAGE, - url: attrs.URI ? M3U8Parser.resolve(attrs.URI, baseurl) : '' - }; - - if (groups.length) { - // If there are audio or text groups signalled in the manifest, let's look for a matching codec string for this track - // If we don't find the track signalled, lets use the first audio groups codec we have - // Acting as a best guess - var groupCodec = M3U8Parser.findGroup(groups, media.groupId) || groups[0]; - assignCodec(media, groupCodec, 'audioCodec'); - assignCodec(media, groupCodec, 'textCodec'); - } - - medias.push(media); - } - } - - return medias; - }; - - M3U8Parser.parseLevelPlaylist = function parseLevelPlaylist(string, baseurl, id, type, levelUrlId) { - var level = new _level_details__WEBPACK_IMPORTED_MODULE_3__["LevelDetails"](baseurl); - var fragments = level.fragments; // The most recent init segment seen (applies to all subsequent segments) - - var currentInitSegment = null; - var currentSN = 0; - var currentPart = 0; - var totalduration = 0; - var discontinuityCounter = 0; - var prevFrag = null; - var frag = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Fragment"](type, baseurl); - var result; - var i; - var levelkey; - var firstPdtIndex = -1; - var createNextFrag = false; - LEVEL_PLAYLIST_REGEX_FAST.lastIndex = 0; - level.m3u8 = string; - - while ((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null) { - if (createNextFrag) { - createNextFrag = false; - frag = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Fragment"](type, baseurl); // setup the next fragment for part loading - - frag.start = totalduration; - frag.sn = currentSN; - frag.cc = discontinuityCounter; - frag.level = id; - - if (currentInitSegment) { - frag.initSegment = currentInitSegment; - frag.rawProgramDateTime = currentInitSegment.rawProgramDateTime; - } - } - - var duration = result[1]; - - if (duration) { - // INF - frag.duration = parseFloat(duration); // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 - - var title = (' ' + result[2]).slice(1); - frag.title = title || null; - frag.tagList.push(title ? ['INF', duration, title] : ['INF', duration]); - } else if (result[3]) { - // url - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.duration)) { - frag.start = totalduration; - - if (levelkey) { - frag.levelkey = levelkey; - } - - frag.sn = currentSN; - frag.level = id; - frag.cc = discontinuityCounter; - frag.urlId = levelUrlId; - fragments.push(frag); // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 - - frag.relurl = (' ' + result[3]).slice(1); - assignProgramDateTime(frag, prevFrag); - prevFrag = frag; - totalduration += frag.duration; - currentSN++; - currentPart = 0; - createNextFrag = true; - } - } else if (result[4]) { - // X-BYTERANGE - var data = (' ' + result[4]).slice(1); - - if (prevFrag) { - frag.setByteRange(data, prevFrag); - } else { - frag.setByteRange(data); - } - } else if (result[5]) { - // PROGRAM-DATE-TIME - // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 - frag.rawProgramDateTime = (' ' + result[5]).slice(1); - frag.tagList.push(['PROGRAM-DATE-TIME', frag.rawProgramDateTime]); - - if (firstPdtIndex === -1) { - firstPdtIndex = fragments.length; - } - } else { - result = result[0].match(LEVEL_PLAYLIST_REGEX_SLOW); - - if (!result) { - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn('No matches on slow regex match for level playlist!'); - continue; - } - - for (i = 1; i < result.length; i++) { - if (typeof result[i] !== 'undefined') { - break; - } - } // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 - - - var tag = (' ' + result[i]).slice(1); - var value1 = (' ' + result[i + 1]).slice(1); - var value2 = result[i + 2] ? (' ' + result[i + 2]).slice(1) : ''; - - switch (tag) { - case 'PLAYLIST-TYPE': - level.type = value1.toUpperCase(); - break; - - case 'MEDIA-SEQUENCE': - currentSN = level.startSN = parseInt(value1); - break; - - case 'SKIP': - { - var skipAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - var skippedSegments = skipAttrs.decimalInteger('SKIPPED-SEGMENTS'); - - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(skippedSegments)) { - level.skippedSegments = skippedSegments; // This will result in fragments[] containing undefined values, which we will fill in with `mergeDetails` - - for (var _i = skippedSegments; _i--;) { - fragments.unshift(null); + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return KeyLoader; + }); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* + * Decrypt key Loader + */ + + var KeyLoader = /*#__PURE__*/ (function () { + function KeyLoader(CiderHls) { + this.CiderHls = void 0; + this.loaders = {}; + this.decryptkey = null; + this.decrypturl = null; + this.CiderHls = CiderHls; + + this._registerListeners(); + } + + var _proto = KeyLoader.prototype; + + _proto._registerListeners = function _registerListeners() { + this.CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADING, this.onKeyLoading, this); + }; + + _proto._unregisterListeners = function _unregisterListeners() { + this.CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADING, this.onKeyLoading); + }; + + _proto.destroy = function destroy() { + this._unregisterListeners(); + + for (var loaderName in this.loaders) { + var loader = this.loaders[loaderName]; + + if (loader) { + loader.destroy(); + } } - currentSN += skippedSegments; - } + this.loaders = {}; + }; - var recentlyRemovedDateranges = skipAttrs.enumeratedString('RECENTLY-REMOVED-DATERANGES'); + _proto.onKeyLoading = function onKeyLoading(event, data) { + var frag = data.frag; + var type = frag.type; + var loader = this.loaders[type]; - if (recentlyRemovedDateranges) { - level.recentlyRemovedDateranges = recentlyRemovedDateranges.split('\t'); - } + if (!frag.decryptdata) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("Missing decryption data on fragment in onKeyLoading"); + return; + } // Load the key if the uri is different from previous one, or if the decrypt key has not yet been retrieved - break; - } + var uri = frag.decryptdata.uri; - case 'TARGETDURATION': - level.targetduration = parseFloat(value1); - break; + if (uri !== this.decrypturl || this.decryptkey === null) { + var config = this.CiderHls.config; - case 'VERSION': - level.version = parseInt(value1); - break; - - case 'EXTM3U': - break; - - case 'ENDLIST': - level.live = false; - break; - - case '#': - if (value1 || value2) { - frag.tagList.push(value2 ? [value1, value2] : [value1]); - } - - break; - - case 'DIS': - discontinuityCounter++; - - /* falls through */ - - case 'GAP': - frag.tagList.push([tag]); - break; - - case 'BITRATE': - frag.tagList.push([tag, value1]); - break; - - case 'DISCONTINUITY-SEQ': - discontinuityCounter = parseInt(value1); - break; - - case 'KEY': - { - var _keyAttrs$enumeratedS; - - // https://tools.ietf.org/html/rfc8216#section-4.3.2.4 - var keyAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - var decryptmethod = keyAttrs.enumeratedString('METHOD'); - var decrypturi = keyAttrs.URI; - var decryptiv = keyAttrs.hexadecimalInteger('IV'); - var decryptkeyformatversions = keyAttrs.enumeratedString('KEYFORMATVERSIONS'); - var decryptkeyid = keyAttrs.enumeratedString('KEYID'); // From RFC: This attribute is OPTIONAL; its absence indicates an implicit value of "identity". - - var decryptkeyformat = (_keyAttrs$enumeratedS = keyAttrs.enumeratedString('KEYFORMAT')) != null ? _keyAttrs$enumeratedS : 'identity'; - var unsupportedKnownKeyformatsInManifest = ['com.apple.streamingkeydelivery', 'com.microsoft.playready', 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed', // widevine (v2) - 'com.widevine' // earlier widevine (v1) - ]; - - if (unsupportedKnownKeyformatsInManifest.indexOf(decryptkeyformat) > -1) { - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("Keyformat " + decryptkeyformat + " is not supported from the manifest"); - continue; - } else if (decryptkeyformat !== 'identity') { - // We are supposed to skip keys we don't understand. - // As we currently only officially support identity keys - // from the manifest we shouldn't save any other key. - continue; - } // TODO: multiple keys can be defined on a fragment, and we need to support this - // for clients that support both playready and widevine - - - if (decryptmethod) { - // TODO: need to determine if the level key is actually a relative URL - // if it isn't, then we should instead construct the LevelKey using fromURI. - levelkey = _level_key__WEBPACK_IMPORTED_MODULE_4__["LevelKey"].fromURL(baseurl, decrypturi); - - if (decrypturi && ['AES-128', 'SAMPLE-AES', 'SAMPLE-AES-CENC'].indexOf(decryptmethod) >= 0) { - levelkey.method = decryptmethod; - levelkey.keyFormat = decryptkeyformat; - - if (decryptkeyid) { - levelkey.keyID = decryptkeyid; + if (loader) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("abort previous key loader for type:" + type); + loader.abort(); } - if (decryptkeyformatversions) { - levelkey.keyFormatVersions = decryptkeyformatversions; - } // Initialization Vector (IV) + if (!uri) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].warn("key uri is falsy"); + return; + } + var Loader = config.loader; + var fragLoader = (frag.loader = this.loaders[type] = new Loader(config)); + this.decrypturl = uri; + this.decryptkey = null; + var loaderContext = { + url: uri, + frag: frag, + responseType: "arraybuffer", + }; // maxRetry is 0 so that instead of retrying the same key on the same variant multiple times, + // key-loader will trigger an error and rely on stream-controller to handle retry logic. + // this will also align retry logic with fragment-loader - levelkey.iv = decryptiv; + var loaderConfig = { + timeout: config.fragLoadingTimeOut, + maxRetry: 0, + retryDelay: config.fragLoadingRetryDelay, + maxRetryDelay: config.fragLoadingMaxRetryTimeout, + highWaterMark: 0, + }; + var loaderCallbacks = { + onSuccess: this.loadsuccess.bind(this), + onError: this.loaderror.bind(this), + onTimeout: this.loadtimeout.bind(this), + }; + fragLoader.load(loaderContext, loaderConfig, loaderCallbacks); + } else if (this.decryptkey) { + // Return the key if it's already been loaded + frag.decryptdata.key = this.decryptkey; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADED, { + frag: frag, + }); + } + }; + + _proto.loadsuccess = function loadsuccess(response, stats, context) { + var frag = context.frag; + + if (!frag.decryptdata) { + _utils_logger__WEBPACK_IMPORTED_MODULE_2__["logger"].error("after key load, decryptdata unset"); + return; + } + + this.decryptkey = frag.decryptdata.key = new Uint8Array(response.data); // detach fragment loader on load success + + frag.loader = null; + delete this.loaders[frag.type]; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].KEY_LOADED, { + frag: frag, + }); + }; + + _proto.loaderror = function loaderror(response, context) { + var frag = context.frag; + var loader = frag.loader; + + if (loader) { + loader.abort(); + } + + delete this.loaders[frag.type]; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_LOAD_ERROR, + fatal: false, + frag: frag, + response: response, + }); + }; + + _proto.loadtimeout = function loadtimeout(stats, context) { + var frag = context.frag; + var loader = frag.loader; + + if (loader) { + loader.abort(); + } + + delete this.loaders[frag.type]; + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_1__["ErrorDetails"].KEY_LOAD_TIMEOUT, + fatal: false, + frag: frag, + }); + }; + + return KeyLoader; + })(); + + /***/ + }, + + /***/ "./src/loader/level-details.ts": + /*!*************************************!*\ + !*** ./src/loader/level-details.ts ***! + \*************************************/ + /*! exports provided: LevelDetails */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LevelDetails", function () { + return LevelDetails; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + var DEFAULT_TARGET_DURATION = 10; + var LevelDetails = /*#__PURE__*/ (function () { + // Manifest reload synchronization + function LevelDetails(baseUrl) { + this.PTSKnown = false; + this.alignedSliding = false; + this.averagetargetduration = void 0; + this.endCC = 0; + this.endSN = 0; + this.fragments = void 0; + this.fragmentHint = void 0; + this.partList = null; + this.live = true; + this.ageHeader = 0; + this.advancedDateTime = void 0; + this.updated = true; + this.advanced = true; + this.availabilityDelay = void 0; + this.misses = 0; + this.needSidxRanges = false; + this.startCC = 0; + this.startSN = 0; + this.startTimeOffset = null; + this.targetduration = 0; + this.totalduration = 0; + this.type = null; + this.url = void 0; + this.m3u8 = ""; + this.version = null; + this.canBlockReload = false; + this.canSkipUntil = 0; + this.canSkipDateRanges = false; + this.skippedSegments = 0; + this.recentlyRemovedDateranges = void 0; + this.partHoldBack = 0; + this.holdBack = 0; + this.partTarget = 0; + this.preloadHint = void 0; + this.renditionReports = void 0; + this.tuneInGoal = 0; + this.deltaUpdateFailed = void 0; + this.driftStartTime = 0; + this.driftEndTime = 0; + this.driftStart = 0; + this.driftEnd = 0; + this.fragments = []; + this.url = baseUrl; + } + + var _proto = LevelDetails.prototype; + + _proto.reloaded = function reloaded(previous) { + if (!previous) { + this.advanced = true; + this.updated = true; + return; + } + + var partSnDiff = this.lastPartSn - previous.lastPartSn; + var partIndexDiff = this.lastPartIndex - previous.lastPartIndex; + this.updated = this.endSN !== previous.endSN || !!partIndexDiff || !!partSnDiff; + this.advanced = this.endSN > previous.endSN || partSnDiff > 0 || (partSnDiff === 0 && partIndexDiff > 0); + + if (this.updated || this.advanced) { + this.misses = Math.floor(previous.misses * 0.6); + } else { + this.misses = previous.misses + 1; + } + + this.availabilityDelay = previous.availabilityDelay; + }; + + _createClass(LevelDetails, [ + { + key: "hasProgramDateTime", + get: function get() { + if (this.fragments.length) { + return Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this.fragments[this.fragments.length - 1].programDateTime); + } + + return false; + }, + }, + { + key: "levelTargetDuration", + get: function get() { + return this.averagetargetduration || this.targetduration || DEFAULT_TARGET_DURATION; + }, + }, + { + key: "drift", + get: function get() { + var runTime = this.driftEndTime - this.driftStartTime; + + if (runTime > 0) { + var runDuration = this.driftEnd - this.driftStart; + return (runDuration * 1000) / runTime; + } + + return 1; + }, + }, + { + key: "edge", + get: function get() { + return this.partEnd || this.fragmentEnd; + }, + }, + { + key: "partEnd", + get: function get() { + var _this$partList; + + if ((_this$partList = this.partList) !== null && _this$partList !== void 0 && _this$partList.length) { + return this.partList[this.partList.length - 1].end; + } + + return this.fragmentEnd; + }, + }, + { + key: "fragmentEnd", + get: function get() { + var _this$fragments; + + if ((_this$fragments = this.fragments) !== null && _this$fragments !== void 0 && _this$fragments.length) { + return this.fragments[this.fragments.length - 1].end; + } + + return 0; + }, + }, + { + key: "age", + get: function get() { + if (this.advancedDateTime) { + return Math.max(Date.now() - this.advancedDateTime, 0) / 1000; + } + + return 0; + }, + }, + { + key: "lastPartIndex", + get: function get() { + var _this$partList2; + + if ((_this$partList2 = this.partList) !== null && _this$partList2 !== void 0 && _this$partList2.length) { + return this.partList[this.partList.length - 1].index; + } + + return -1; + }, + }, + { + key: "lastPartSn", + get: function get() { + var _this$partList3; + + if ((_this$partList3 = this.partList) !== null && _this$partList3 !== void 0 && _this$partList3.length) { + return this.partList[this.partList.length - 1].fragment.sn; + } + + return this.endSN; + }, + }, + ]); + + return LevelDetails; + })(); + + /***/ + }, + + /***/ "./src/loader/level-key.ts": + /*!*********************************!*\ + !*** ./src/loader/level-key.ts ***! + \*********************************/ + /*! exports provided: LevelKey */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LevelKey", function () { + return LevelKey; + }); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_0__); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + var LevelKey = /*#__PURE__*/ (function () { + LevelKey.fromURL = function fromURL(baseUrl, relativeUrl) { + return new LevelKey(baseUrl, relativeUrl); + }; + + LevelKey.fromURI = function fromURI(uri) { + return new LevelKey(uri); + }; + + function LevelKey(absoluteOrBaseURI, relativeURL) { + this._uri = null; + this.method = null; + this.keyFormat = null; + this.keyFormatVersions = null; + this.keyID = null; + this.key = null; + this.iv = null; + + if (relativeURL) { + this._uri = Object(url_toolkit__WEBPACK_IMPORTED_MODULE_0__["buildAbsoluteURL"])(absoluteOrBaseURI, relativeURL, { + alwaysNormalize: true, + }); + } else { + this._uri = absoluteOrBaseURI; } } - break; + _createClass(LevelKey, [ + { + key: "uri", + get: function get() { + return this._uri; + }, + }, + ]); + + return LevelKey; + })(); + + /***/ + }, + + /***/ "./src/loader/load-stats.ts": + /*!**********************************!*\ + !*** ./src/loader/load-stats.ts ***! + \**********************************/ + /*! exports provided: LoadStats */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoadStats", function () { + return LoadStats; + }); + var LoadStats = function LoadStats() { + this.aborted = false; + this.loaded = 0; + this.retry = 0; + this.total = 0; + this.chunkCount = 0; + this.bwEstimate = 0; + this.loading = { + start: 0, + first: 0, + end: 0, + }; + this.parsing = { + start: 0, + end: 0, + }; + this.buffering = { + start: 0, + first: 0, + end: 0, + }; + }; + + /***/ + }, + + /***/ "./src/loader/m3u8-parser.ts": + /*!***********************************!*\ + !*** ./src/loader/m3u8-parser.ts ***! + \***********************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return M3U8Parser; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js"); + /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__); + /* harmony import */ var _fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fragment */ "./src/loader/fragment.ts"); + /* harmony import */ var _level_details__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./level-details */ "./src/loader/level-details.ts"); + /* harmony import */ var _level_key__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./level-key */ "./src/loader/level-key.ts"); + /* harmony import */ var _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/attr-list */ "./src/utils/attr-list.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _utils_codecs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/codecs */ "./src/utils/codecs.ts"); + + // https://regex101.com is your friend + var MASTER_PLAYLIST_REGEX = /#EXT-X-STREAM-INF:([^\r\n]*)(?:[\r\n](?:#[^\r\n]*)?)*([^\r\n]+)|#EXT-X-SESSION-DATA:([^\r\n]*)[\r\n]+/g; + var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g; + var LEVEL_PLAYLIST_REGEX_FAST = new RegExp( + [ + /#EXTINF:\s*(\d*(?:\.\d+)?)(?:,(.*)\s+)?/.source, // duration (#EXTINF:<duration>,<title>), group 1 => duration, group 2 => title + /(?!#) *(\S[\S ]*)/.source, // segment URI, group 3 => the URI (note newline is not eaten) + /#EXT-X-BYTERANGE:*(.+)/.source, // next segment's byterange, group 4 => range spec (x@y) + /#EXT-X-PROGRAM-DATE-TIME:(.+)/.source, // next segment's program date/time group 5 => the datetime spec + /#.*/.source, // All other non-segment oriented tags will match with all groups empty + ].join("|"), + "g" + ); + var LEVEL_PLAYLIST_REGEX_SLOW = new RegExp( + [ + /#(EXTM3U)/.source, + /#EXT-X-(PLAYLIST-TYPE):(.+)/.source, + /#EXT-X-(MEDIA-SEQUENCE): *(\d+)/.source, + /#EXT-X-(SKIP):(.+)/.source, + /#EXT-X-(TARGETDURATION): *(\d+)/.source, + /#EXT-X-(KEY):(.+)/.source, + /#EXT-X-(START):(.+)/.source, + /#EXT-X-(ENDLIST)/.source, + /#EXT-X-(DISCONTINUITY-SEQ)UENCE: *(\d+)/.source, + /#EXT-X-(DIS)CONTINUITY/.source, + /#EXT-X-(VERSION):(\d+)/.source, + /#EXT-X-(MAP):(.+)/.source, + /#EXT-X-(SERVER-CONTROL):(.+)/.source, + /#EXT-X-(PART-INF):(.+)/.source, + /#EXT-X-(GAP)/.source, + /#EXT-X-(BITRATE):\s*(\d+)/.source, + /#EXT-X-(PART):(.+)/.source, + /#EXT-X-(PRELOAD-HINT):(.+)/.source, + /#EXT-X-(RENDITION-REPORT):(.+)/.source, + /(#)([^:]*):(.*)/.source, + /(#)(.*)(?:.*)\r?\n?/.source, + ].join("|") + ); + var MP4_REGEX_SUFFIX = /\.(mp4|m4s|m4v|m4a)$/i; + + function isMP4Url(url) { + var _URLToolkit$parseURL$, _URLToolkit$parseURL; + + return MP4_REGEX_SUFFIX.test((_URLToolkit$parseURL$ = (_URLToolkit$parseURL = url_toolkit__WEBPACK_IMPORTED_MODULE_1__["parseURL"](url)) === null || _URLToolkit$parseURL === void 0 ? void 0 : _URLToolkit$parseURL.path) != null ? _URLToolkit$parseURL$ : ""); } - case 'START': - { - var startAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - var startTimeOffset = startAttrs.decimalFloatingPoint('TIME-OFFSET'); // TIME-OFFSET can be 0 + var M3U8Parser = /*#__PURE__*/ (function () { + function M3U8Parser() {} - if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(startTimeOffset)) { - level.startTimeOffset = startTimeOffset; + M3U8Parser.findGroup = function findGroup(groups, mediaGroupId) { + for (var i = 0; i < groups.length; i++) { + var group = groups[i]; + + if (group.id === mediaGroupId) { + return group; + } + } + }; + + M3U8Parser.convertAVC1ToAVCOTI = function convertAVC1ToAVCOTI(codec) { + // Convert avc1 codec string from RFC-4281 to RFC-6381 for MediaSource.isTypeSupported + var avcdata = codec.split("."); + + if (avcdata.length > 2) { + var result = avcdata.shift() + "."; + result += parseInt(avcdata.shift()).toString(16); + result += ("000" + parseInt(avcdata.shift()).toString(16)).substr(-4); + return result; + } + + return codec; + }; + + M3U8Parser.resolve = function resolve(url, baseUrl) { + return url_toolkit__WEBPACK_IMPORTED_MODULE_1__["buildAbsoluteURL"](baseUrl, url, { + alwaysNormalize: true, + }); + }; + + M3U8Parser.parseMasterPlaylist = function parseMasterPlaylist(string, baseurl) { + var levels = []; + var sessionData = {}; + var hasSessionData = false; + MASTER_PLAYLIST_REGEX.lastIndex = 0; + var result; + + while ((result = MASTER_PLAYLIST_REGEX.exec(string)) != null) { + if (result[1]) { + // '#EXT-X-STREAM-INF' is found, parse level tag in group 1 + var attrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](result[1]); + var level = { + attrs: attrs, + bitrate: attrs.decimalInteger("AVERAGE-BANDWIDTH") || attrs.decimalInteger("BANDWIDTH"), + name: attrs.NAME, + url: M3U8Parser.resolve(result[2], baseurl), + }; + var resolution = attrs.decimalResolution("RESOLUTION"); + + if (resolution) { + level.width = resolution.width; + level.height = resolution.height; + } + + setCodecs( + (attrs.CODECS || "").split(/[ ,]+/).filter(function (c) { + return c; + }), + level + ); + + if (level.videoCodec && level.videoCodec.indexOf("avc1") !== -1) { + level.videoCodec = M3U8Parser.convertAVC1ToAVCOTI(level.videoCodec); + } + + levels.push(level); + } else if (result[3]) { + // '#EXT-X-SESSION-DATA' is found, parse session data in group 3 + var sessionAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](result[3]); + + if (sessionAttrs["DATA-ID"]) { + hasSessionData = true; + sessionData[sessionAttrs["DATA-ID"]] = sessionAttrs; + } + } + } + if (levels && levels.length > 0) { + levels = levels.sort(function (a, b) { + return a.bitrate - b.bitrate; + }); + } + return { + levels: levels, + sessionData: hasSessionData ? sessionData : null, + }; + }; + + M3U8Parser.parseMasterPlaylistMedia = function parseMasterPlaylistMedia(string, baseurl, type, groups) { + if (groups === void 0) { + groups = []; + } + + var result; + var medias = []; + var id = 0; + MASTER_PLAYLIST_MEDIA_REGEX.lastIndex = 0; + + while ((result = MASTER_PLAYLIST_MEDIA_REGEX.exec(string)) !== null) { + var attrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](result[1]); + + if (attrs.TYPE === type) { + var media = { + attrs: attrs, + bitrate: 0, + id: id++, + groupId: attrs["GROUP-ID"], + instreamId: attrs["INSTREAM-ID"], + name: attrs.NAME || attrs.LANGUAGE || "", + type: type, + default: attrs.bool("DEFAULT"), + autoselect: attrs.bool("AUTOSELECT"), + forced: attrs.bool("FORCED"), + lang: attrs.LANGUAGE, + url: attrs.URI ? M3U8Parser.resolve(attrs.URI, baseurl) : "", + }; + + if (groups.length) { + // If there are audio or text groups signalled in the manifest, let's look for a matching codec string for this track + // If we don't find the track signalled, lets use the first audio groups codec we have + // Acting as a best guess + var groupCodec = M3U8Parser.findGroup(groups, media.groupId) || groups[0]; + assignCodec(media, groupCodec, "audioCodec"); + assignCodec(media, groupCodec, "textCodec"); + } + + medias.push(media); + } + } + + return medias; + }; + + M3U8Parser.parseLevelPlaylist = function parseLevelPlaylist(string, baseurl, id, type, levelUrlId) { + var level = new _level_details__WEBPACK_IMPORTED_MODULE_3__["LevelDetails"](baseurl); + var fragments = level.fragments; // The most recent init segment seen (applies to all subsequent segments) + + var currentInitSegment = null; + var currentSN = 0; + var currentPart = 0; + var totalduration = 0; + var discontinuityCounter = 0; + var prevFrag = null; + var frag = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Fragment"](type, baseurl); + var result; + var i; + var levelkey; + var firstPdtIndex = -1; + var createNextFrag = false; + LEVEL_PLAYLIST_REGEX_FAST.lastIndex = 0; + level.m3u8 = string; + + while ((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null) { + if (createNextFrag) { + createNextFrag = false; + frag = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Fragment"](type, baseurl); // setup the next fragment for part loading + + frag.start = totalduration; + frag.sn = currentSN; + frag.cc = discontinuityCounter; + frag.level = id; + + if (currentInitSegment) { + frag.initSegment = currentInitSegment; + frag.rawProgramDateTime = currentInitSegment.rawProgramDateTime; + } + } + + var duration = result[1]; + + if (duration) { + // INF + frag.duration = parseFloat(duration); // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 + + var title = (" " + result[2]).slice(1); + frag.title = title || null; + frag.tagList.push(title ? ["INF", duration, title] : ["INF", duration]); + } else if (result[3]) { + // url + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.duration)) { + frag.start = totalduration; + + if (levelkey) { + frag.levelkey = levelkey; + } + + frag.sn = currentSN; + frag.level = id; + frag.cc = discontinuityCounter; + frag.urlId = levelUrlId; + fragments.push(frag); // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 + + frag.relurl = (" " + result[3]).slice(1); + assignProgramDateTime(frag, prevFrag); + prevFrag = frag; + totalduration += frag.duration; + currentSN++; + currentPart = 0; + createNextFrag = true; + } + } else if (result[4]) { + // X-BYTERANGE + var data = (" " + result[4]).slice(1); + + if (prevFrag) { + frag.setByteRange(data, prevFrag); + } else { + frag.setByteRange(data); + } + } else if (result[5]) { + // PROGRAM-DATE-TIME + // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 + frag.rawProgramDateTime = (" " + result[5]).slice(1); + frag.tagList.push(["PROGRAM-DATE-TIME", frag.rawProgramDateTime]); + + if (firstPdtIndex === -1) { + firstPdtIndex = fragments.length; + } + } else { + result = result[0].match(LEVEL_PLAYLIST_REGEX_SLOW); + + if (!result) { + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("No matches on slow regex match for level playlist!"); + continue; + } + + for (i = 1; i < result.length; i++) { + if (typeof result[i] !== "undefined") { + break; + } + } // avoid sliced strings https://github.com/video-dev/CiderHls.js/issues/939 + + var tag = (" " + result[i]).slice(1); + var value1 = (" " + result[i + 1]).slice(1); + var value2 = result[i + 2] ? (" " + result[i + 2]).slice(1) : ""; + + switch (tag) { + case "PLAYLIST-TYPE": + level.type = value1.toUpperCase(); + break; + + case "MEDIA-SEQUENCE": + currentSN = level.startSN = parseInt(value1); + break; + + case "SKIP": { + var skipAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + var skippedSegments = skipAttrs.decimalInteger("SKIPPED-SEGMENTS"); + + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(skippedSegments)) { + level.skippedSegments = skippedSegments; // This will result in fragments[] containing undefined values, which we will fill in with `mergeDetails` + + for (var _i = skippedSegments; _i--; ) { + fragments.unshift(null); + } + + currentSN += skippedSegments; + } + + var recentlyRemovedDateranges = skipAttrs.enumeratedString("RECENTLY-REMOVED-DATERANGES"); + + if (recentlyRemovedDateranges) { + level.recentlyRemovedDateranges = recentlyRemovedDateranges.split("\t"); + } + + break; + } + + case "TARGETDURATION": + level.targetduration = parseFloat(value1); + break; + + case "VERSION": + level.version = parseInt(value1); + break; + + case "EXTM3U": + break; + + case "ENDLIST": + level.live = false; + break; + + case "#": + if (value1 || value2) { + frag.tagList.push(value2 ? [value1, value2] : [value1]); + } + + break; + + case "DIS": + discontinuityCounter++; + + /* falls through */ + + case "GAP": + frag.tagList.push([tag]); + break; + + case "BITRATE": + frag.tagList.push([tag, value1]); + break; + + case "DISCONTINUITY-SEQ": + discontinuityCounter = parseInt(value1); + break; + + case "KEY": { + var _keyAttrs$enumeratedS; + + // https://tools.ietf.org/html/rfc8216#section-4.3.2.4 + var keyAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + var decryptmethod = keyAttrs.enumeratedString("METHOD"); + var decrypturi = keyAttrs.URI; + var decryptiv = keyAttrs.hexadecimalInteger("IV"); + var decryptkeyformatversions = keyAttrs.enumeratedString("KEYFORMATVERSIONS"); + var decryptkeyid = keyAttrs.enumeratedString("KEYID"); // From RFC: This attribute is OPTIONAL; its absence indicates an implicit value of "identity". + + var decryptkeyformat = (_keyAttrs$enumeratedS = keyAttrs.enumeratedString("KEYFORMAT")) != null ? _keyAttrs$enumeratedS : "identity"; + var unsupportedKnownKeyformatsInManifest = [ + "com.apple.streamingkeydelivery", + "com.microsoft.playready", + "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed", // widevine (v2) + "com.widevine", // earlier widevine (v1) + ]; + + if (unsupportedKnownKeyformatsInManifest.indexOf(decryptkeyformat) > -1) { + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("Keyformat " + decryptkeyformat + " is not supported from the manifest"); + continue; + } else if (decryptkeyformat !== "identity") { + // We are supposed to skip keys we don't understand. + // As we currently only officially support identity keys + // from the manifest we shouldn't save any other key. + continue; + } // TODO: multiple keys can be defined on a fragment, and we need to support this + // for clients that support both playready and widevine + + if (decryptmethod) { + // TODO: need to determine if the level key is actually a relative URL + // if it isn't, then we should instead construct the LevelKey using fromURI. + levelkey = _level_key__WEBPACK_IMPORTED_MODULE_4__["LevelKey"].fromURL(baseurl, decrypturi); + + if (decrypturi && ["AES-128", "SAMPLE-AES", "SAMPLE-AES-CENC"].indexOf(decryptmethod) >= 0) { + levelkey.method = decryptmethod; + levelkey.keyFormat = decryptkeyformat; + + if (decryptkeyid) { + levelkey.keyID = decryptkeyid; + } + + if (decryptkeyformatversions) { + levelkey.keyFormatVersions = decryptkeyformatversions; + } // Initialization Vector (IV) + + levelkey.iv = decryptiv; + } + } + + break; + } + + case "START": { + var startAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + var startTimeOffset = startAttrs.decimalFloatingPoint("TIME-OFFSET"); // TIME-OFFSET can be 0 + + if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(startTimeOffset)) { + level.startTimeOffset = startTimeOffset; + } + + break; + } + + case "MAP": { + var mapAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + frag.relurl = mapAttrs.URI; + + if (mapAttrs.BYTERANGE) { + frag.setByteRange(mapAttrs.BYTERANGE); + } + + frag.level = id; + frag.sn = "initSegment"; + + if (levelkey) { + frag.levelkey = levelkey; + } + + frag.initSegment = null; + currentInitSegment = frag; + createNextFrag = true; + break; + } + + case "SERVER-CONTROL": { + var serverControlAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + level.canBlockReload = serverControlAttrs.bool("CAN-BLOCK-RELOAD"); + level.canSkipUntil = serverControlAttrs.optionalFloat("CAN-SKIP-UNTIL", 0); + level.canSkipDateRanges = level.canSkipUntil > 0 && serverControlAttrs.bool("CAN-SKIP-DATERANGES"); + level.partHoldBack = serverControlAttrs.optionalFloat("PART-HOLD-BACK", 0); + level.holdBack = serverControlAttrs.optionalFloat("HOLD-BACK", 0); + break; + } + + case "PART-INF": { + var partInfAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + level.partTarget = partInfAttrs.decimalFloatingPoint("PART-TARGET"); + break; + } + + case "PART": { + var partList = level.partList; + + if (!partList) { + partList = level.partList = []; + } + + var previousFragmentPart = currentPart > 0 ? partList[partList.length - 1] : undefined; + var index = currentPart++; + var part = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Part"](new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1), frag, baseurl, index, previousFragmentPart); + partList.push(part); + frag.duration += part.duration; + break; + } + + case "PRELOAD-HINT": { + var preloadHintAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + level.preloadHint = preloadHintAttrs; + break; + } + + case "RENDITION-REPORT": { + var renditionReportAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); + level.renditionReports = level.renditionReports || []; + level.renditionReports.push(renditionReportAttrs); + break; + } + + default: + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("line parsed but not handled: " + result); + break; + } + } + } + + if (prevFrag && !prevFrag.relurl) { + fragments.pop(); + totalduration -= prevFrag.duration; + + if (level.partList) { + level.fragmentHint = prevFrag; + } + } else if (level.partList) { + assignProgramDateTime(frag, prevFrag); + frag.cc = discontinuityCounter; + level.fragmentHint = frag; + } + + var fragmentLength = fragments.length; + var firstFragment = fragments[0]; + var lastFragment = fragments[fragmentLength - 1]; + totalduration += level.skippedSegments * level.targetduration; + + if (totalduration > 0 && fragmentLength && lastFragment) { + level.averagetargetduration = totalduration / fragmentLength; + var lastSn = lastFragment.sn; + level.endSN = lastSn !== "initSegment" ? lastSn : 0; + + if (firstFragment) { + level.startCC = firstFragment.cc; + + if (!firstFragment.initSegment) { + // this is a bit lurky but CiderHls really has no other way to tell us + // if the fragments are TS or MP4, except if we download them :/ + // but this is to be able to handle SIDX. + if ( + level.fragments.every(function (frag) { + return frag.relurl && isMP4Url(frag.relurl); + }) + ) { + _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("MP4 fragments found but no init segment (probably no MAP, incomplete M3U8), trying to fetch SIDX"); + frag = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Fragment"](type, baseurl); + frag.relurl = lastFragment.relurl; + frag.level = id; + frag.sn = "initSegment"; + firstFragment.initSegment = frag; + level.needSidxRanges = true; + } + } + } + } else { + level.endSN = 0; + level.startCC = 0; + } + + if (level.fragmentHint) { + totalduration += level.fragmentHint.duration; + } + + level.totalduration = totalduration; + level.endCC = discontinuityCounter; + /** + * Backfill any missing PDT values + * "If the first EXT-X-PROGRAM-DATE-TIME tag in a Playlist appears after + * one or more Media Segment URIs, the client SHOULD extrapolate + * backward from that tag (using EXTINF durations and/or media + * timestamps) to associate dates with those segments." + * We have already extrapolated forward, but all fragments up to the first instance of PDT do not have their PDTs + * computed. + */ + + if (firstPdtIndex > 0) { + backfillProgramDateTimes(fragments, firstPdtIndex); + } + + return level; + }; + + return M3U8Parser; + })(); + + function setCodecs(codecs, level) { + ["video", "audio", "text"].forEach(function (type) { + var filtered = codecs.filter(function (codec) { + return Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_7__["isCodecType"])(codec, type); + }); + + if (filtered.length) { + var preferred = filtered.filter(function (codec) { + return codec.lastIndexOf("avc1", 0) === 0 || codec.lastIndexOf("mp4a", 0) === 0; + }); + level[type + "Codec"] = preferred.length > 0 ? preferred[0] : filtered[0]; // remove from list + + codecs = codecs.filter(function (codec) { + return filtered.indexOf(codec) === -1; + }); + } + }); + level.unknownCodecs = codecs; + } + + function assignCodec(media, groupItem, codecProperty) { + var codecValue = groupItem[codecProperty]; + + if (codecValue) { + media[codecProperty] = codecValue; + } + } + + function backfillProgramDateTimes(fragments, firstPdtIndex) { + var fragPrev = fragments[firstPdtIndex]; + + for (var i = firstPdtIndex; i--; ) { + var frag = fragments[i]; // Exit on delta-playlist skipped segments + + if (!frag) { + return; + } + + frag.programDateTime = fragPrev.programDateTime - frag.duration * 1000; + fragPrev = frag; + } + } + + function assignProgramDateTime(frag, prevFrag) { + if (frag.rawProgramDateTime) { + frag.programDateTime = Date.parse(frag.rawProgramDateTime); + } else if (prevFrag !== null && prevFrag !== void 0 && prevFrag.programDateTime) { + frag.programDateTime = prevFrag.endProgramDateTime; } - break; - } - - case 'MAP': - { - var mapAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - frag.relurl = mapAttrs.URI; - - if (mapAttrs.BYTERANGE) { - frag.setByteRange(mapAttrs.BYTERANGE); + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.programDateTime)) { + frag.programDateTime = null; + frag.rawProgramDateTime = null; } - - frag.level = id; - frag.sn = 'initSegment'; - - if (levelkey) { - frag.levelkey = levelkey; - } - - frag.initSegment = null; - currentInitSegment = frag; - createNextFrag = true; - break; } - case 'SERVER-CONTROL': - { - var serverControlAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - level.canBlockReload = serverControlAttrs.bool('CAN-BLOCK-RELOAD'); - level.canSkipUntil = serverControlAttrs.optionalFloat('CAN-SKIP-UNTIL', 0); - level.canSkipDateRanges = level.canSkipUntil > 0 && serverControlAttrs.bool('CAN-SKIP-DATERANGES'); - level.partHoldBack = serverControlAttrs.optionalFloat('PART-HOLD-BACK', 0); - level.holdBack = serverControlAttrs.optionalFloat('HOLD-BACK', 0); - break; - } + /***/ + }, - case 'PART-INF': - { - var partInfAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - level.partTarget = partInfAttrs.decimalFloatingPoint('PART-TARGET'); - break; - } - - case 'PART': - { - var partList = level.partList; - - if (!partList) { - partList = level.partList = []; - } - - var previousFragmentPart = currentPart > 0 ? partList[partList.length - 1] : undefined; - var index = currentPart++; - var part = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Part"](new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1), frag, baseurl, index, previousFragmentPart); - partList.push(part); - frag.duration += part.duration; - break; - } - - case 'PRELOAD-HINT': - { - var preloadHintAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - level.preloadHint = preloadHintAttrs; - break; - } - - case 'RENDITION-REPORT': - { - var renditionReportAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_5__["AttrList"](value1); - level.renditionReports = level.renditionReports || []; - level.renditionReports.push(renditionReportAttrs); - break; - } - - default: - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn("line parsed but not handled: " + result); - break; - } - } - } - - if (prevFrag && !prevFrag.relurl) { - fragments.pop(); - totalduration -= prevFrag.duration; - - if (level.partList) { - level.fragmentHint = prevFrag; - } - } else if (level.partList) { - assignProgramDateTime(frag, prevFrag); - frag.cc = discontinuityCounter; - level.fragmentHint = frag; - } - - var fragmentLength = fragments.length; - var firstFragment = fragments[0]; - var lastFragment = fragments[fragmentLength - 1]; - totalduration += level.skippedSegments * level.targetduration; - - if (totalduration > 0 && fragmentLength && lastFragment) { - level.averagetargetduration = totalduration / fragmentLength; - var lastSn = lastFragment.sn; - level.endSN = lastSn !== 'initSegment' ? lastSn : 0; - - if (firstFragment) { - level.startCC = firstFragment.cc; - - if (!firstFragment.initSegment) { - // this is a bit lurky but CiderHls really has no other way to tell us - // if the fragments are TS or MP4, except if we download them :/ - // but this is to be able to handle SIDX. - if (level.fragments.every(function (frag) { - return frag.relurl && isMP4Url(frag.relurl); - })) { - _utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].warn('MP4 fragments found but no init segment (probably no MAP, incomplete M3U8), trying to fetch SIDX'); - frag = new _fragment__WEBPACK_IMPORTED_MODULE_2__["Fragment"](type, baseurl); - frag.relurl = lastFragment.relurl; - frag.level = id; - frag.sn = 'initSegment'; - firstFragment.initSegment = frag; - level.needSidxRanges = true; - } - } - } - } else { - level.endSN = 0; - level.startCC = 0; - } - - if (level.fragmentHint) { - totalduration += level.fragmentHint.duration; - } - - level.totalduration = totalduration; - level.endCC = discontinuityCounter; - /** - * Backfill any missing PDT values - * "If the first EXT-X-PROGRAM-DATE-TIME tag in a Playlist appears after - * one or more Media Segment URIs, the client SHOULD extrapolate - * backward from that tag (using EXTINF durations and/or media - * timestamps) to associate dates with those segments." - * We have already extrapolated forward, but all fragments up to the first instance of PDT do not have their PDTs - * computed. - */ - - if (firstPdtIndex > 0) { - backfillProgramDateTimes(fragments, firstPdtIndex); - } - - return level; - }; - - return M3U8Parser; -}(); - - - -function setCodecs(codecs, level) { - ['video', 'audio', 'text'].forEach(function (type) { - var filtered = codecs.filter(function (codec) { - return Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_7__["isCodecType"])(codec, type); - }); - - if (filtered.length) { - var preferred = filtered.filter(function (codec) { - return codec.lastIndexOf('avc1', 0) === 0 || codec.lastIndexOf('mp4a', 0) === 0; - }); - level[type + "Codec"] = preferred.length > 0 ? preferred[0] : filtered[0]; // remove from list - - codecs = codecs.filter(function (codec) { - return filtered.indexOf(codec) === -1; - }); - } - }); - level.unknownCodecs = codecs; -} - -function assignCodec(media, groupItem, codecProperty) { - var codecValue = groupItem[codecProperty]; - - if (codecValue) { - media[codecProperty] = codecValue; - } -} - -function backfillProgramDateTimes(fragments, firstPdtIndex) { - var fragPrev = fragments[firstPdtIndex]; - - for (var i = firstPdtIndex; i--;) { - var frag = fragments[i]; // Exit on delta-playlist skipped segments - - if (!frag) { - return; - } - - frag.programDateTime = fragPrev.programDateTime - frag.duration * 1000; - fragPrev = frag; - } -} - -function assignProgramDateTime(frag, prevFrag) { - if (frag.rawProgramDateTime) { - frag.programDateTime = Date.parse(frag.rawProgramDateTime); - } else if (prevFrag !== null && prevFrag !== void 0 && prevFrag.programDateTime) { - frag.programDateTime = prevFrag.endProgramDateTime; - } - - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.programDateTime)) { - frag.programDateTime = null; - frag.rawProgramDateTime = null; - } -} - -/***/ }), - -/***/ "./src/loader/playlist-loader.ts": -/*!***************************************!*\ + /***/ "./src/loader/playlist-loader.ts": + /*!***************************************!*\ !*** ./src/loader/playlist-loader.ts ***! \***************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./m3u8-parser */ "./src/loader/m3u8-parser.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -/* harmony import */ var _utils_attr_list__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/attr-list */ "./src/utils/attr-list.ts"); - - - -/** - * PlaylistLoader - delegate for media manifest/playlist loading tasks. Takes care of parsing media to internal data-models. - * - * Once loaded, dispatches events with parsed data-models of manifest/levels/audio/subtitle tracks. - * - * Uses loader(s) set in config to do actual internal loading of resource tasks. - * - * @module - * - */ - - - - - - - - -function mapContextToLevelType(context) { - var type = context.type; - - switch (type) { - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: - return _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO; - - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: - return _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].SUBTITLE; - - default: - return _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN; - } -} - -function getResponseUrl(response, context) { - var url = response.url; // responseURL not supported on some browsers (it is used to detect URL redirection) - // data-uri mode also not supported (but no need to detect redirection) - - if (url === undefined || url.indexOf('data:') === 0) { - // fallback to initial URL - url = context.url; - } - - return url; -} - -var PlaylistLoader = /*#__PURE__*/function () { - function PlaylistLoader(CiderHls) { - this.CiderHls = void 0; - this.loaders = Object.create(null); - this.CiderHls = CiderHls; - this.registerListeners(); - } - - var _proto = PlaylistLoader.prototype; - - _proto.registerListeners = function registerListeners() { - var CiderHls = this.CiderHls; - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADING, this.onLevelLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this); - CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this); - }; - - _proto.unregisterListeners = function unregisterListeners() { - var CiderHls = this.CiderHls; - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADING, this.onLevelLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this); - CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this); - } - /** - * Returns defaults or configured loader-type overloads (pLoader and loader config params) - */ - ; - - _proto.createInternalLoader = function createInternalLoader(context) { - var config = this.CiderHls.config; - var PLoader = config.pLoader; - var Loader = config.loader; - var InternalLoader = PLoader || Loader; - var loader = new InternalLoader(config); - context.loader = loader; - this.loaders[context.type] = loader; - return loader; - }; - - _proto.getInternalLoader = function getInternalLoader(context) { - return this.loaders[context.type]; - }; - - _proto.resetInternalLoader = function resetInternalLoader(contextType) { - if (this.loaders[contextType]) { - delete this.loaders[contextType]; - } - } - /** - * Call `destroy` on all internal loader instances mapped (one per context type) - */ - ; - - _proto.destroyInternalLoaders = function destroyInternalLoaders() { - for (var contextType in this.loaders) { - var loader = this.loaders[contextType]; - - if (loader) { - loader.destroy(); - } - - this.resetInternalLoader(contextType); - } - }; - - _proto.destroy = function destroy() { - this.unregisterListeners(); - this.destroyInternalLoaders(); - }; - - _proto.onManifestLoading = function onManifestLoading(event, data) { - var url = data.url; - this.load({ - id: null, - groupId: null, - level: 0, - responseType: 'text', - type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST, - url: url, - deliveryDirectives: null - }); - }; - - _proto.onLevelLoading = function onLevelLoading(event, data) { - var id = data.id, - level = data.level, - url = data.url, - deliveryDirectives = data.deliveryDirectives; - this.load({ - id: id, - groupId: null, - level: level, - responseType: 'text', - type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL, - url: url, - deliveryDirectives: deliveryDirectives - }); - }; - - _proto.onAudioTrackLoading = function onAudioTrackLoading(event, data) { - var id = data.id, - groupId = data.groupId, - url = data.url, - deliveryDirectives = data.deliveryDirectives; - this.load({ - id: id, - groupId: groupId, - level: null, - responseType: 'text', - type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK, - url: url, - deliveryDirectives: deliveryDirectives - }); - }; - - _proto.onSubtitleTrackLoading = function onSubtitleTrackLoading(event, data) { - var id = data.id, - groupId = data.groupId, - url = data.url, - deliveryDirectives = data.deliveryDirectives; - this.load({ - id: id, - groupId: groupId, - level: null, - responseType: 'text', - type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK, - url: url, - deliveryDirectives: deliveryDirectives - }); - }; - - _proto.load = function load(context) { - var _context$deliveryDire; - - var config = this.CiderHls.config; // logger.debug(`[playlist-loader]: Loading playlist of type ${context.type}, level: ${context.level}, id: ${context.id}`); - // Check if a loader for this context already exists - - var loader = this.getInternalLoader(context); - - if (loader) { - var loaderContext = loader.context; - - if (loaderContext && loaderContext.url === context.url) { - // same URL can't overlap - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].trace('[playlist-loader]: playlist request ongoing'); - return; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log("[playlist-loader]: aborting previous loader for type: " + context.type); - loader.abort(); - } - - var maxRetry; - var timeout; - var retryDelay; - var maxRetryDelay; // apply different configs for retries depending on - // context (manifest, level, audio/subs playlist) - - switch (context.type) { - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST: - maxRetry = config.manifestLoadingMaxRetry; - timeout = config.manifestLoadingTimeOut; - retryDelay = config.manifestLoadingRetryDelay; - maxRetryDelay = config.manifestLoadingMaxRetryTimeout; - break; - - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL: - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: - // Manage retries in Level/Track Controller - maxRetry = 0; - timeout = config.levelLoadingTimeOut; - break; - - default: - maxRetry = config.levelLoadingMaxRetry; - timeout = config.levelLoadingTimeOut; - retryDelay = config.levelLoadingRetryDelay; - maxRetryDelay = config.levelLoadingMaxRetryTimeout; - break; - } - - loader = this.createInternalLoader(context); // Override level/track timeout for LL-CiderHls requests - // (the default of 10000ms is counter productive to blocking playlist reload requests) - - if ((_context$deliveryDire = context.deliveryDirectives) !== null && _context$deliveryDire !== void 0 && _context$deliveryDire.part) { - var levelDetails; - - if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL && context.level !== null) { - levelDetails = this.CiderHls.levels[context.level].details; - } else if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK && context.id !== null) { - levelDetails = this.CiderHls.audioTracks[context.id].details; - } else if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK && context.id !== null) { - levelDetails = this.CiderHls.subtitleTracks[context.id].details; - } - - if (levelDetails) { - var partTarget = levelDetails.partTarget; - var targetDuration = levelDetails.targetduration; - - if (partTarget && targetDuration) { - timeout = Math.min(Math.max(partTarget * 3, targetDuration * 0.8) * 1000, timeout); - } - } - } - - var loaderConfig = { - timeout: timeout, - maxRetry: maxRetry, - retryDelay: retryDelay, - maxRetryDelay: maxRetryDelay, - highWaterMark: 0 - }; - var loaderCallbacks = { - onSuccess: this.loadsuccess.bind(this), - onError: this.loaderror.bind(this), - onTimeout: this.loadtimeout.bind(this) - }; // logger.debug(`[playlist-loader]: Calling internal loader delegate for URL: ${context.url}`); - - loader.load(context, loaderConfig, loaderCallbacks); - }; - - _proto.loadsuccess = function loadsuccess(response, stats, context, networkDetails) { - if (networkDetails === void 0) { - networkDetails = null; - } - - if (context.isSidxRequest) { - this.handleSidxRequest(response, context); - this.handlePlaylistLoaded(response, stats, context, networkDetails); - return; - } - - this.resetInternalLoader(context.type); - var string = response.data; // Validate if it is an M3U8 at all - - if (string.indexOf('#EXTM3U') !== 0) { - this.handleManifestParsingError(response, context, 'no EXTM3U delimiter', networkDetails); - return; - } - - stats.parsing.start = performance.now(); // Check if chunk-list or master. handle empty chunk list case (first EXTINF not signaled, but TARGETDURATION present) - - if (string.indexOf('#EXTINF:') > 0 || string.indexOf('#EXT-X-TARGETDURATION:') > 0) { - this.handleTrackOrLevelPlaylist(response, stats, context, networkDetails); - } else { - this.handleMasterPlaylist(response, stats, context, networkDetails); - } - }; - - _proto.loaderror = function loaderror(response, context, networkDetails) { - if (networkDetails === void 0) { - networkDetails = null; - } - - this.handleNetworkError(context, networkDetails, false, response); - }; - - _proto.loadtimeout = function loadtimeout(stats, context, networkDetails) { - if (networkDetails === void 0) { - networkDetails = null; - } - - this.handleNetworkError(context, networkDetails, true); - }; - - _proto.handleMasterPlaylist = function handleMasterPlaylist(response, stats, context, networkDetails) { - var CiderHls = this.CiderHls; - var string = response.data; - var url = getResponseUrl(response, context); - - var _M3U8Parser$parseMast = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylist(string, url), - levels = _M3U8Parser$parseMast.levels, - sessionData = _M3U8Parser$parseMast.sessionData; - - if (!levels.length) { - this.handleManifestParsingError(response, context, 'no level found in manifest', networkDetails); - return; - } // multi level playlist, parse level info - - - var audioGroups = levels.map(function (level) { - return { - id: level.attrs.AUDIO, - audioCodec: level.audioCodec - }; - }); - var subtitleGroups = levels.map(function (level) { - return { - id: level.attrs.SUBTITLES, - textCodec: level.textCodec - }; - }); - var audioTracks = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylistMedia(string, url, 'AUDIO', audioGroups); - var subtitles = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylistMedia(string, url, 'SUBTITLES', subtitleGroups); - var captions = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylistMedia(string, url, 'CLOSED-CAPTIONS'); - - if (audioTracks.length) { - // check if we have found an audio track embedded in main playlist (audio track without URI attribute) - var embeddedAudioFound = audioTracks.some(function (audioTrack) { - return !audioTrack.url; - }); // if no embedded audio track defined, but audio codec signaled in quality level, - // we need to signal this main audio track this could happen with playlists with - // alt audio rendition in which quality levels (main) - // contains both audio+video. but with mixed audio track not signaled - - if (!embeddedAudioFound && levels[0].audioCodec && !levels[0].attrs.AUDIO) { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log('[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one'); - audioTracks.unshift({ - type: 'main', - name: 'main', - default: false, - autoselect: false, - forced: false, - id: -1, - attrs: new _utils_attr_list__WEBPACK_IMPORTED_MODULE_7__["AttrList"]({}), - bitrate: 0, - url: '' - }); - } - } - - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, { - levels: levels, - audioTracks: audioTracks, - subtitles: subtitles, - captions: captions, - url: url, - stats: stats, - networkDetails: networkDetails, - sessionData: sessionData - }); - }; - - _proto.handleTrackOrLevelPlaylist = function handleTrackOrLevelPlaylist(response, stats, context, networkDetails) { - var CiderHls = this.CiderHls; - var id = context.id, - level = context.level, - type = context.type; - var url = getResponseUrl(response, context); - var levelUrlId = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(id) ? id : 0; - var levelId = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(level) ? level : levelUrlId; - var levelType = mapContextToLevelType(context); - var levelDetails = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseLevelPlaylist(response.data, url, levelId, levelType, levelUrlId); - - if (!levelDetails.fragments.length) { - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_EMPTY_ERROR, - fatal: false, - url: url, - reason: 'no fragments found in level', - level: typeof context.level === 'number' ? context.level : undefined - }); - return; - } // We have done our first request (Manifest-type) and receive - // not a master playlist but a chunk-list (track/level) - // We fire the manifest-loaded event anyway with the parsed level-details - // by creating a single-level structure for it. - - - if (type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST) { - var singleLevel = { - attrs: new _utils_attr_list__WEBPACK_IMPORTED_MODULE_7__["AttrList"]({}), - bitrate: 0, - details: levelDetails, - name: '', - url: url - }; - CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, { - levels: [singleLevel], - audioTracks: [], - url: url, - stats: stats, - networkDetails: networkDetails, - sessionData: null - }); - } // save parsing time - - - stats.parsing.end = performance.now(); // in case we need SIDX ranges - // return early after calling load for - // the SIDX box. - - if (levelDetails.needSidxRanges) { - var _levelDetails$fragmen; - - var sidxUrl = (_levelDetails$fragmen = levelDetails.fragments[0].initSegment) === null || _levelDetails$fragmen === void 0 ? void 0 : _levelDetails$fragmen.url; - this.load({ - url: sidxUrl, - isSidxRequest: true, - type: type, - level: level, - levelDetails: levelDetails, - id: id, - groupId: null, - rangeStart: 0, - rangeEnd: 2048, - responseType: 'arraybuffer', - deliveryDirectives: null - }); - return; - } // extend the context with the new levelDetails property - - - context.levelDetails = levelDetails; - this.handlePlaylistLoaded(response, stats, context, networkDetails); - }; - - _proto.handleSidxRequest = function handleSidxRequest(response, context) { - var sidxInfo = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__["parseSegmentIndex"])(new Uint8Array(response.data)); // if provided fragment does not contain sidx, early return - - if (!sidxInfo) { - return; - } - - var sidxReferences = sidxInfo.references; - var levelDetails = context.levelDetails; - sidxReferences.forEach(function (segmentRef, index) { - var segRefInfo = segmentRef.info; - var frag = levelDetails.fragments[index]; - - if (frag.byteRange.length === 0) { - frag.setByteRange(String(1 + segRefInfo.end - segRefInfo.start) + '@' + String(segRefInfo.start)); - } - - if (frag.initSegment) { - frag.initSegment.setByteRange(String(sidxInfo.moovEndOffset) + '@0'); - } - }); - }; - - _proto.handleManifestParsingError = function handleManifestParsingError(response, context, reason, networkDetails) { - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].NETWORK_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_PARSING_ERROR, - fatal: context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST, - url: response.url, - reason: reason, - response: response, - context: context, - networkDetails: networkDetails - }); - }; - - _proto.handleNetworkError = function handleNetworkError(context, networkDetails, timeout, response) { - if (timeout === void 0) { - timeout = false; - } - - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("[playlist-loader]: A network " + (timeout ? 'timeout' : 'error') + " occurred while loading " + context.type + " level: " + context.level + " id: " + context.id + " group-id: \"" + context.groupId + "\""); - var details = _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].UNKNOWN; - var fatal = false; - var loader = this.getInternalLoader(context); - - switch (context.type) { - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST: - details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_LOAD_ERROR; - fatal = true; - break; - - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL: - details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_ERROR; - fatal = false; - break; - - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: - details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].AUDIO_TRACK_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR; - fatal = false; - break; - - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: - details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].SUBTITLE_TRACK_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].SUBTITLE_LOAD_ERROR; - fatal = false; - break; - } - - if (loader) { - this.resetInternalLoader(context.type); - } - - var errorData = { - type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].NETWORK_ERROR, - details: details, - fatal: fatal, - url: context.url, - loader: loader, - context: context, - networkDetails: networkDetails - }; - - if (response) { - errorData.response = response; - } - - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, errorData); - }; - - _proto.handlePlaylistLoaded = function handlePlaylistLoaded(response, stats, context, networkDetails) { - var type = context.type, - level = context.level, - id = context.id, - groupId = context.groupId, - loader = context.loader, - levelDetails = context.levelDetails, - deliveryDirectives = context.deliveryDirectives; - - if (!(levelDetails !== null && levelDetails !== void 0 && levelDetails.targetduration)) { - this.handleManifestParsingError(response, context, 'invalid target duration', networkDetails); - return; - } - - if (!loader) { - return; - } - - if (levelDetails.live) { - if (loader.getCacheAge) { - levelDetails.ageHeader = loader.getCacheAge() || 0; - } - - if (!loader.getCacheAge || isNaN(levelDetails.ageHeader)) { - levelDetails.ageHeader = 0; - } - } - - switch (type) { - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST: - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL: - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADED, { - details: levelDetails, - level: level || 0, - id: id || 0, - stats: stats, - networkDetails: networkDetails, - deliveryDirectives: deliveryDirectives - }); - break; - - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_LOADED, { - details: levelDetails, - id: id || 0, - groupId: groupId || '', - stats: stats, - networkDetails: networkDetails, - deliveryDirectives: deliveryDirectives - }); - break; - - case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: - this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACK_LOADED, { - details: levelDetails, - id: id || 0, - groupId: groupId || '', - stats: stats, - networkDetails: networkDetails, - deliveryDirectives: deliveryDirectives - }); - break; - } - }; - - return PlaylistLoader; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (PlaylistLoader); - -/***/ }), - -/***/ "./src/polyfills/number.ts": -/*!*********************************!*\ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./m3u8-parser */ "./src/loader/m3u8-parser.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + /* harmony import */ var _utils_attr_list__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/attr-list */ "./src/utils/attr-list.ts"); + + /** + * PlaylistLoader - delegate for media manifest/playlist loading tasks. Takes care of parsing media to internal data-models. + * + * Once loaded, dispatches events with parsed data-models of manifest/levels/audio/subtitle tracks. + * + * Uses loader(s) set in config to do actual internal loading of resource tasks. + * + * @module + * + */ + + function mapContextToLevelType(context) { + var type = context.type; + + switch (type) { + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: + return _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO; + + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: + return _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].SUBTITLE; + + default: + return _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN; + } + } + + function getResponseUrl(response, context) { + var url = response.url; // responseURL not supported on some browsers (it is used to detect URL redirection) + // data-uri mode also not supported (but no need to detect redirection) + + if (url === undefined || url.indexOf("data:") === 0) { + // fallback to initial URL + url = context.url; + } + + return url; + } + + var PlaylistLoader = /*#__PURE__*/ (function () { + function PlaylistLoader(CiderHls) { + this.CiderHls = void 0; + this.loaders = Object.create(null); + this.CiderHls = CiderHls; + this.registerListeners(); + } + + var _proto = PlaylistLoader.prototype; + + _proto.registerListeners = function registerListeners() { + var CiderHls = this.CiderHls; + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADING, this.onLevelLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this); + CiderHls.on(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this); + }; + + _proto.unregisterListeners = function unregisterListeners() { + var CiderHls = this.CiderHls; + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADING, this.onManifestLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADING, this.onLevelLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this); + CiderHls.off(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this); + }; + /** + * Returns defaults or configured loader-type overloads (pLoader and loader config params) + */ + + _proto.createInternalLoader = function createInternalLoader(context) { + var config = this.CiderHls.config; + var PLoader = config.pLoader; + var Loader = config.loader; + var InternalLoader = PLoader || Loader; + var loader = new InternalLoader(config); + context.loader = loader; + this.loaders[context.type] = loader; + return loader; + }; + + _proto.getInternalLoader = function getInternalLoader(context) { + return this.loaders[context.type]; + }; + + _proto.resetInternalLoader = function resetInternalLoader(contextType) { + if (this.loaders[contextType]) { + delete this.loaders[contextType]; + } + }; + /** + * Call `destroy` on all internal loader instances mapped (one per context type) + */ + + _proto.destroyInternalLoaders = function destroyInternalLoaders() { + for (var contextType in this.loaders) { + var loader = this.loaders[contextType]; + + if (loader) { + loader.destroy(); + } + + this.resetInternalLoader(contextType); + } + }; + + _proto.destroy = function destroy() { + this.unregisterListeners(); + this.destroyInternalLoaders(); + }; + + _proto.onManifestLoading = function onManifestLoading(event, data) { + var url = data.url; + this.load({ + id: null, + groupId: null, + level: 0, + responseType: "text", + type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST, + url: url, + deliveryDirectives: null, + }); + }; + + _proto.onLevelLoading = function onLevelLoading(event, data) { + var id = data.id, + level = data.level, + url = data.url, + deliveryDirectives = data.deliveryDirectives; + this.load({ + id: id, + groupId: null, + level: level, + responseType: "text", + type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL, + url: url, + deliveryDirectives: deliveryDirectives, + }); + }; + + _proto.onAudioTrackLoading = function onAudioTrackLoading(event, data) { + var id = data.id, + groupId = data.groupId, + url = data.url, + deliveryDirectives = data.deliveryDirectives; + this.load({ + id: id, + groupId: groupId, + level: null, + responseType: "text", + type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK, + url: url, + deliveryDirectives: deliveryDirectives, + }); + }; + + _proto.onSubtitleTrackLoading = function onSubtitleTrackLoading(event, data) { + var id = data.id, + groupId = data.groupId, + url = data.url, + deliveryDirectives = data.deliveryDirectives; + this.load({ + id: id, + groupId: groupId, + level: null, + responseType: "text", + type: _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK, + url: url, + deliveryDirectives: deliveryDirectives, + }); + }; + + _proto.load = function load(context) { + var _context$deliveryDire; + + var config = this.CiderHls.config; // logger.debug(`[playlist-loader]: Loading playlist of type ${context.type}, level: ${context.level}, id: ${context.id}`); + // Check if a loader for this context already exists + + var loader = this.getInternalLoader(context); + + if (loader) { + var loaderContext = loader.context; + + if (loaderContext && loaderContext.url === context.url) { + // same URL can't overlap + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].trace("[playlist-loader]: playlist request ongoing"); + return; + } + + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log("[playlist-loader]: aborting previous loader for type: " + context.type); + loader.abort(); + } + + var maxRetry; + var timeout; + var retryDelay; + var maxRetryDelay; // apply different configs for retries depending on + // context (manifest, level, audio/subs playlist) + + switch (context.type) { + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST: + maxRetry = config.manifestLoadingMaxRetry; + timeout = config.manifestLoadingTimeOut; + retryDelay = config.manifestLoadingRetryDelay; + maxRetryDelay = config.manifestLoadingMaxRetryTimeout; + break; + + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL: + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: + // Manage retries in Level/Track Controller + maxRetry = 0; + timeout = config.levelLoadingTimeOut; + break; + + default: + maxRetry = config.levelLoadingMaxRetry; + timeout = config.levelLoadingTimeOut; + retryDelay = config.levelLoadingRetryDelay; + maxRetryDelay = config.levelLoadingMaxRetryTimeout; + break; + } + + loader = this.createInternalLoader(context); // Override level/track timeout for LL-CiderHls requests + // (the default of 10000ms is counter productive to blocking playlist reload requests) + + if ((_context$deliveryDire = context.deliveryDirectives) !== null && _context$deliveryDire !== void 0 && _context$deliveryDire.part) { + var levelDetails; + + if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL && context.level !== null) { + levelDetails = this.CiderHls.levels[context.level].details; + } else if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK && context.id !== null) { + levelDetails = this.CiderHls.audioTracks[context.id].details; + } else if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK && context.id !== null) { + levelDetails = this.CiderHls.subtitleTracks[context.id].details; + } + + if (levelDetails) { + var partTarget = levelDetails.partTarget; + var targetDuration = levelDetails.targetduration; + + if (partTarget && targetDuration) { + timeout = Math.min(Math.max(partTarget * 3, targetDuration * 0.8) * 1000, timeout); + } + } + } + + var loaderConfig = { + timeout: timeout, + maxRetry: maxRetry, + retryDelay: retryDelay, + maxRetryDelay: maxRetryDelay, + highWaterMark: 0, + }; + var loaderCallbacks = { + onSuccess: this.loadsuccess.bind(this), + onError: this.loaderror.bind(this), + onTimeout: this.loadtimeout.bind(this), + }; // logger.debug(`[playlist-loader]: Calling internal loader delegate for URL: ${context.url}`); + + loader.load(context, loaderConfig, loaderCallbacks); + }; + + _proto.loadsuccess = function loadsuccess(response, stats, context, networkDetails) { + if (networkDetails === void 0) { + networkDetails = null; + } + + if (context.isSidxRequest) { + this.handleSidxRequest(response, context); + this.handlePlaylistLoaded(response, stats, context, networkDetails); + return; + } + + this.resetInternalLoader(context.type); + var string = response.data; // Validate if it is an M3U8 at all + + if (string.indexOf("#EXTM3U") !== 0) { + this.handleManifestParsingError(response, context, "no EXTM3U delimiter", networkDetails); + return; + } + + stats.parsing.start = performance.now(); // Check if chunk-list or master. handle empty chunk list case (first EXTINF not signaled, but TARGETDURATION present) + + if (string.indexOf("#EXTINF:") > 0 || string.indexOf("#EXT-X-TARGETDURATION:") > 0) { + this.handleTrackOrLevelPlaylist(response, stats, context, networkDetails); + } else { + this.handleMasterPlaylist(response, stats, context, networkDetails); + } + }; + + _proto.loaderror = function loaderror(response, context, networkDetails) { + if (networkDetails === void 0) { + networkDetails = null; + } + + this.handleNetworkError(context, networkDetails, false, response); + }; + + _proto.loadtimeout = function loadtimeout(stats, context, networkDetails) { + if (networkDetails === void 0) { + networkDetails = null; + } + + this.handleNetworkError(context, networkDetails, true); + }; + + _proto.handleMasterPlaylist = function handleMasterPlaylist(response, stats, context, networkDetails) { + var CiderHls = this.CiderHls; + var string = response.data; + var url = getResponseUrl(response, context); + + var _M3U8Parser$parseMast = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylist(string, url), + levels = _M3U8Parser$parseMast.levels, + sessionData = _M3U8Parser$parseMast.sessionData; + + if (!levels.length) { + this.handleManifestParsingError(response, context, "no level found in manifest", networkDetails); + return; + } // multi level playlist, parse level info + + var audioGroups = levels.map(function (level) { + return { + id: level.attrs.AUDIO, + audioCodec: level.audioCodec, + }; + }); + var subtitleGroups = levels.map(function (level) { + return { + id: level.attrs.SUBTITLES, + textCodec: level.textCodec, + }; + }); + var audioTracks = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylistMedia(string, url, "AUDIO", audioGroups); + var subtitles = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylistMedia(string, url, "SUBTITLES", subtitleGroups); + var captions = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseMasterPlaylistMedia(string, url, "CLOSED-CAPTIONS"); + + if (audioTracks.length) { + // check if we have found an audio track embedded in main playlist (audio track without URI attribute) + var embeddedAudioFound = audioTracks.some(function (audioTrack) { + return !audioTrack.url; + }); // if no embedded audio track defined, but audio codec signaled in quality level, + // we need to signal this main audio track this could happen with playlists with + // alt audio rendition in which quality levels (main) + // contains both audio+video. but with mixed audio track not signaled + + if (!embeddedAudioFound && levels[0].audioCodec && !levels[0].attrs.AUDIO) { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].log("[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one"); + audioTracks.unshift({ + type: "main", + name: "main", + default: false, + autoselect: false, + forced: false, + id: -1, + attrs: new _utils_attr_list__WEBPACK_IMPORTED_MODULE_7__["AttrList"]({}), + bitrate: 0, + url: "", + }); + } + } + + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, { + levels: levels, + audioTracks: audioTracks, + subtitles: subtitles, + captions: captions, + url: url, + stats: stats, + networkDetails: networkDetails, + sessionData: sessionData, + }); + }; + + _proto.handleTrackOrLevelPlaylist = function handleTrackOrLevelPlaylist(response, stats, context, networkDetails) { + var CiderHls = this.CiderHls; + var id = context.id, + level = context.level, + type = context.type; + var url = getResponseUrl(response, context); + var levelUrlId = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(id) ? id : 0; + var levelId = Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(level) ? level : levelUrlId; + var levelType = mapContextToLevelType(context); + var levelDetails = _m3u8_parser__WEBPACK_IMPORTED_MODULE_5__["default"].parseLevelPlaylist(response.data, url, levelId, levelType, levelUrlId); + + if (!levelDetails.fragments.length) { + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_EMPTY_ERROR, + fatal: false, + url: url, + reason: "no fragments found in level", + level: typeof context.level === "number" ? context.level : undefined, + }); + return; + } // We have done our first request (Manifest-type) and receive + // not a master playlist but a chunk-list (track/level) + // We fire the manifest-loaded event anyway with the parsed level-details + // by creating a single-level structure for it. + + if (type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST) { + var singleLevel = { + attrs: new _utils_attr_list__WEBPACK_IMPORTED_MODULE_7__["AttrList"]({}), + bitrate: 0, + details: levelDetails, + name: "", + url: url, + }; + CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].MANIFEST_LOADED, { + levels: [singleLevel], + audioTracks: [], + url: url, + stats: stats, + networkDetails: networkDetails, + sessionData: null, + }); + } // save parsing time + + stats.parsing.end = performance.now(); // in case we need SIDX ranges + // return early after calling load for + // the SIDX box. + + if (levelDetails.needSidxRanges) { + var _levelDetails$fragmen; + + var sidxUrl = (_levelDetails$fragmen = levelDetails.fragments[0].initSegment) === null || _levelDetails$fragmen === void 0 ? void 0 : _levelDetails$fragmen.url; + this.load({ + url: sidxUrl, + isSidxRequest: true, + type: type, + level: level, + levelDetails: levelDetails, + id: id, + groupId: null, + rangeStart: 0, + rangeEnd: 2048, + responseType: "arraybuffer", + deliveryDirectives: null, + }); + return; + } // extend the context with the new levelDetails property + + context.levelDetails = levelDetails; + this.handlePlaylistLoaded(response, stats, context, networkDetails); + }; + + _proto.handleSidxRequest = function handleSidxRequest(response, context) { + var sidxInfo = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__["parseSegmentIndex"])(new Uint8Array(response.data)); // if provided fragment does not contain sidx, early return + + if (!sidxInfo) { + return; + } + + var sidxReferences = sidxInfo.references; + var levelDetails = context.levelDetails; + sidxReferences.forEach(function (segmentRef, index) { + var segRefInfo = segmentRef.info; + var frag = levelDetails.fragments[index]; + + if (frag.byteRange.length === 0) { + frag.setByteRange(String(1 + segRefInfo.end - segRefInfo.start) + "@" + String(segRefInfo.start)); + } + + if (frag.initSegment) { + frag.initSegment.setByteRange(String(sidxInfo.moovEndOffset) + "@0"); + } + }); + }; + + _proto.handleManifestParsingError = function handleManifestParsingError(response, context, reason, networkDetails) { + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].NETWORK_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_PARSING_ERROR, + fatal: context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST, + url: response.url, + reason: reason, + response: response, + context: context, + networkDetails: networkDetails, + }); + }; + + _proto.handleNetworkError = function handleNetworkError(context, networkDetails, timeout, response) { + if (timeout === void 0) { + timeout = false; + } + + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("[playlist-loader]: A network " + (timeout ? "timeout" : "error") + " occurred while loading " + context.type + " level: " + context.level + " id: " + context.id + ' group-id: "' + context.groupId + '"'); + var details = _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].UNKNOWN; + var fatal = false; + var loader = this.getInternalLoader(context); + + switch (context.type) { + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST: + details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].MANIFEST_LOAD_ERROR; + fatal = true; + break; + + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL: + details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].LEVEL_LOAD_ERROR; + fatal = false; + break; + + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: + details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].AUDIO_TRACK_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR; + fatal = false; + break; + + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: + details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].SUBTITLE_TRACK_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].SUBTITLE_LOAD_ERROR; + fatal = false; + break; + } + + if (loader) { + this.resetInternalLoader(context.type); + } + + var errorData = { + type: _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorTypes"].NETWORK_ERROR, + details: details, + fatal: fatal, + url: context.url, + loader: loader, + context: context, + networkDetails: networkDetails, + }; + + if (response) { + errorData.response = response; + } + + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].ERROR, errorData); + }; + + _proto.handlePlaylistLoaded = function handlePlaylistLoaded(response, stats, context, networkDetails) { + var type = context.type, + level = context.level, + id = context.id, + groupId = context.groupId, + loader = context.loader, + levelDetails = context.levelDetails, + deliveryDirectives = context.deliveryDirectives; + + if (!(levelDetails !== null && levelDetails !== void 0 && levelDetails.targetduration)) { + this.handleManifestParsingError(response, context, "invalid target duration", networkDetails); + return; + } + + if (!loader) { + return; + } + + if (levelDetails.live) { + if (loader.getCacheAge) { + levelDetails.ageHeader = loader.getCacheAge() || 0; + } + + if (!loader.getCacheAge || isNaN(levelDetails.ageHeader)) { + levelDetails.ageHeader = 0; + } + } + + switch (type) { + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].MANIFEST: + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].LEVEL: + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].LEVEL_LOADED, { + details: levelDetails, + level: level || 0, + id: id || 0, + stats: stats, + networkDetails: networkDetails, + deliveryDirectives: deliveryDirectives, + }); + break; + + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].AUDIO_TRACK: + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].AUDIO_TRACK_LOADED, { + details: levelDetails, + id: id || 0, + groupId: groupId || "", + stats: stats, + networkDetails: networkDetails, + deliveryDirectives: deliveryDirectives, + }); + break; + + case _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistContextType"].SUBTITLE_TRACK: + this.CiderHls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["Events"].SUBTITLE_TRACK_LOADED, { + details: levelDetails, + id: id || 0, + groupId: groupId || "", + stats: stats, + networkDetails: networkDetails, + deliveryDirectives: deliveryDirectives, + }); + break; + } + }; + + return PlaylistLoader; + })(); + + /* harmony default export */ __webpack_exports__["default"] = PlaylistLoader; + + /***/ + }, + + /***/ "./src/polyfills/number.ts": + /*!*********************************!*\ !*** ./src/polyfills/number.ts ***! \*********************************/ -/*! exports provided: isFiniteNumber, MAX_SAFE_INTEGER */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: isFiniteNumber, MAX_SAFE_INTEGER */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFiniteNumber", function () { + return isFiniteNumber; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MAX_SAFE_INTEGER", function () { + return MAX_SAFE_INTEGER; + }); + var isFiniteNumber = + Number.isFinite || + function (value) { + return typeof value === "number" && isFinite(value); + }; + var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFiniteNumber", function() { return isFiniteNumber; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MAX_SAFE_INTEGER", function() { return MAX_SAFE_INTEGER; }); -var isFiniteNumber = Number.isFinite || function (value) { - return typeof value === 'number' && isFinite(value); -}; -var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + /***/ + }, -/***/ }), - -/***/ "./src/remux/aac-helper.ts": -/*!*********************************!*\ + /***/ "./src/remux/aac-helper.ts": + /*!*********************************!*\ !*** ./src/remux/aac-helper.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /** + * AAC helper + */ + var AAC = /*#__PURE__*/ (function () { + function AAC() {} -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * AAC helper - */ -var AAC = /*#__PURE__*/function () { - function AAC() {} + AAC.getSilentFrame = function getSilentFrame(codec, channelCount) { + switch (codec) { + case "mp4a.40.2": + if (channelCount === 1) { + return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]); + } else if (channelCount === 2) { + return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]); + } else if (channelCount === 3) { + return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]); + } else if (channelCount === 4) { + return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]); + } else if (channelCount === 5) { + return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]); + } else if (channelCount === 6) { + return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]); + } - AAC.getSilentFrame = function getSilentFrame(codec, channelCount) { - switch (codec) { - case 'mp4a.40.2': - if (channelCount === 1) { - return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]); - } else if (channelCount === 2) { - return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]); - } else if (channelCount === 3) { - return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]); - } else if (channelCount === 4) { - return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]); - } else if (channelCount === 5) { - return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]); - } else if (channelCount === 6) { - return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]); - } + break; + // handle HE-AAC below (mp4a.40.5 / mp4a.40.29) - break; - // handle HE-AAC below (mp4a.40.5 / mp4a.40.29) + default: + if (channelCount === 1) { + // ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac + return new Uint8Array([ + 0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e, + ]); + } else if (channelCount === 2) { + // ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac + return new Uint8Array([ + 0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e, + ]); + } else if (channelCount === 3) { + // ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac + return new Uint8Array([ + 0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e, + ]); + } - default: - if (channelCount === 1) { - // ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac - return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]); - } else if (channelCount === 2) { - // ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac - return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]); - } else if (channelCount === 3) { - // ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac - return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]); - } + break; + } - break; - } + return undefined; + }; - return undefined; - }; + return AAC; + })(); - return AAC; -}(); + /* harmony default export */ __webpack_exports__["default"] = AAC; -/* harmony default export */ __webpack_exports__["default"] = (AAC); + /***/ + }, -/***/ }), - -/***/ "./src/remux/mp4-generator.ts": -/*!************************************!*\ + /***/ "./src/remux/mp4-generator.ts": + /*!************************************!*\ !*** ./src/remux/mp4-generator.ts ***! \************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /** + * Generate MP4 Box + */ + var UINT32_MAX = Math.pow(2, 32) - 1; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * Generate MP4 Box - */ -var UINT32_MAX = Math.pow(2, 32) - 1; + var MP4 = /*#__PURE__*/ (function () { + function MP4() {} -var MP4 = /*#__PURE__*/function () { - function MP4() {} + MP4.init = function init() { + MP4.types = { + avc1: [], + // codingname + avcC: [], + btrt: [], + dinf: [], + dref: [], + esds: [], + ftyp: [], + hdlr: [], + mdat: [], + mdhd: [], + mdia: [], + mfhd: [], + minf: [], + moof: [], + moov: [], + mp4a: [], + ".mp3": [], + mvex: [], + mvhd: [], + pasp: [], + sdtp: [], + stbl: [], + stco: [], + stsc: [], + stsd: [], + stsz: [], + stts: [], + tfdt: [], + tfhd: [], + traf: [], + trak: [], + trun: [], + trex: [], + tkhd: [], + vmhd: [], + smhd: [], + }; + var i; - MP4.init = function init() { - MP4.types = { - avc1: [], - // codingname - avcC: [], - btrt: [], - dinf: [], - dref: [], - esds: [], - ftyp: [], - hdlr: [], - mdat: [], - mdhd: [], - mdia: [], - mfhd: [], - minf: [], - moof: [], - moov: [], - mp4a: [], - '.mp3': [], - mvex: [], - mvhd: [], - pasp: [], - sdtp: [], - stbl: [], - stco: [], - stsc: [], - stsd: [], - stsz: [], - stts: [], - tfdt: [], - tfhd: [], - traf: [], - trak: [], - trun: [], - trex: [], - tkhd: [], - vmhd: [], - smhd: [] - }; - var i; + for (i in MP4.types) { + if (MP4.types.hasOwnProperty(i)) { + MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)]; + } + } - for (i in MP4.types) { - if (MP4.types.hasOwnProperty(i)) { - MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)]; - } - } + var videoHdlr = new Uint8Array([ + 0x00, // version 0 + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x00, // pre_defined + 0x76, + 0x69, + 0x64, + 0x65, // handler_type: 'vide' + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x56, + 0x69, + 0x64, + 0x65, + 0x6f, + 0x48, + 0x61, + 0x6e, + 0x64, + 0x6c, + 0x65, + 0x72, + 0x00, // name: 'VideoHandler' + ]); + var audioHdlr = new Uint8Array([ + 0x00, // version 0 + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x00, // pre_defined + 0x73, + 0x6f, + 0x75, + 0x6e, // handler_type: 'soun' + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x53, + 0x6f, + 0x75, + 0x6e, + 0x64, + 0x48, + 0x61, + 0x6e, + 0x64, + 0x6c, + 0x65, + 0x72, + 0x00, // name: 'SoundHandler' + ]); + MP4.HDLR_TYPES = { + video: videoHdlr, + audio: audioHdlr, + }; + var dref = new Uint8Array([ + 0x00, // version 0 + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x01, // entry_count + 0x00, + 0x00, + 0x00, + 0x0c, // entry_size + 0x75, + 0x72, + 0x6c, + 0x20, // 'url' type + 0x00, // version 0 + 0x00, + 0x00, + 0x01, // entry_flags + ]); + var stco = new Uint8Array([ + 0x00, // version + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x00, // entry_count + ]); + MP4.STTS = MP4.STSC = MP4.STCO = stco; + MP4.STSZ = new Uint8Array([ + 0x00, // version + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x00, // sample_size + 0x00, + 0x00, + 0x00, + 0x00, // sample_count + ]); + MP4.VMHD = new Uint8Array([ + 0x00, // version + 0x00, + 0x00, + 0x01, // flags + 0x00, + 0x00, // graphicsmode + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // opcolor + ]); + MP4.SMHD = new Uint8Array([ + 0x00, // version + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, // balance + 0x00, + 0x00, // reserved + ]); + MP4.STSD = new Uint8Array([ + 0x00, // version 0 + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x01, + ]); // entry_count - var videoHdlr = new Uint8Array([0x00, // version 0 - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x00, // pre_defined - 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide' - 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, 0x00, // reserved - 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'VideoHandler' - ]); - var audioHdlr = new Uint8Array([0x00, // version 0 - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x00, // pre_defined - 0x73, 0x6f, 0x75, 0x6e, // handler_type: 'soun' - 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, 0x00, // reserved - 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'SoundHandler' - ]); - MP4.HDLR_TYPES = { - video: videoHdlr, - audio: audioHdlr - }; - var dref = new Uint8Array([0x00, // version 0 - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x01, // entry_count - 0x00, 0x00, 0x00, 0x0c, // entry_size - 0x75, 0x72, 0x6c, 0x20, // 'url' type - 0x00, // version 0 - 0x00, 0x00, 0x01 // entry_flags - ]); - var stco = new Uint8Array([0x00, // version - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x00 // entry_count - ]); - MP4.STTS = MP4.STSC = MP4.STCO = stco; - MP4.STSZ = new Uint8Array([0x00, // version - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x00, // sample_size - 0x00, 0x00, 0x00, 0x00 // sample_count - ]); - MP4.VMHD = new Uint8Array([0x00, // version - 0x00, 0x00, 0x01, // flags - 0x00, 0x00, // graphicsmode - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // opcolor - ]); - MP4.SMHD = new Uint8Array([0x00, // version - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, // balance - 0x00, 0x00 // reserved - ]); - MP4.STSD = new Uint8Array([0x00, // version 0 - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x01]); // entry_count + var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom - var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom + var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1 - var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1 + var minorVersion = new Uint8Array([0, 0, 0, 1]); + MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand); + MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref)); + }; - var minorVersion = new Uint8Array([0, 0, 0, 1]); - MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand); - MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref)); - }; + MP4.box = function box(type) { + var size = 8; - MP4.box = function box(type) { - var size = 8; + for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + payload[_key - 1] = arguments[_key]; + } - for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - payload[_key - 1] = arguments[_key]; - } + var i = payload.length; + var len = i; // calculate the total size we need to allocate - var i = payload.length; - var len = i; // calculate the total size we need to allocate + while (i--) { + size += payload[i].byteLength; + } - while (i--) { - size += payload[i].byteLength; - } + var result = new Uint8Array(size); + result[0] = (size >> 24) & 0xff; + result[1] = (size >> 16) & 0xff; + result[2] = (size >> 8) & 0xff; + result[3] = size & 0xff; + result.set(type, 4); // copy the payload into the result - var result = new Uint8Array(size); - result[0] = size >> 24 & 0xff; - result[1] = size >> 16 & 0xff; - result[2] = size >> 8 & 0xff; - result[3] = size & 0xff; - result.set(type, 4); // copy the payload into the result + for (i = 0, size = 8; i < len; i++) { + // copy payload[i] array @ offset size + result.set(payload[i], size); + size += payload[i].byteLength; + } - for (i = 0, size = 8; i < len; i++) { - // copy payload[i] array @ offset size - result.set(payload[i], size); - size += payload[i].byteLength; - } + return result; + }; - return result; - }; + MP4.hdlr = function hdlr(type) { + return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]); + }; - MP4.hdlr = function hdlr(type) { - return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]); - }; + MP4.mdat = function mdat(data) { + return MP4.box(MP4.types.mdat, data); + }; - MP4.mdat = function mdat(data) { - return MP4.box(MP4.types.mdat, data); - }; + MP4.mdhd = function mdhd(timescale, duration) { + duration *= timescale; + var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); + var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); + return MP4.box( + MP4.types.mdhd, + new Uint8Array([ + 0x01, // version 1 + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x02, // creation_time + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, // modification_time + (timescale >> 24) & 0xff, + (timescale >> 16) & 0xff, + (timescale >> 8) & 0xff, + timescale & 0xff, // timescale + upperWordDuration >> 24, + (upperWordDuration >> 16) & 0xff, + (upperWordDuration >> 8) & 0xff, + upperWordDuration & 0xff, + lowerWordDuration >> 24, + (lowerWordDuration >> 16) & 0xff, + (lowerWordDuration >> 8) & 0xff, + lowerWordDuration & 0xff, + 0x55, + 0xc4, // 'und' language (undetermined) + 0x00, + 0x00, + ]) + ); + }; - MP4.mdhd = function mdhd(timescale, duration) { - duration *= timescale; - var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); - var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); - return MP4.box(MP4.types.mdhd, new Uint8Array([0x01, // version 1 - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // creation_time - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // modification_time - timescale >> 24 & 0xff, timescale >> 16 & 0xff, timescale >> 8 & 0xff, timescale & 0xff, // timescale - upperWordDuration >> 24, upperWordDuration >> 16 & 0xff, upperWordDuration >> 8 & 0xff, upperWordDuration & 0xff, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xff, lowerWordDuration >> 8 & 0xff, lowerWordDuration & 0xff, 0x55, 0xc4, // 'und' language (undetermined) - 0x00, 0x00])); - }; + MP4.mdia = function mdia(track) { + return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track)); + }; - MP4.mdia = function mdia(track) { - return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track)); - }; + MP4.mfhd = function mfhd(sequenceNumber) { + return MP4.box( + MP4.types.mfhd, + new Uint8Array([ + 0x00, + 0x00, + 0x00, + 0x00, // flags + sequenceNumber >> 24, + (sequenceNumber >> 16) & 0xff, + (sequenceNumber >> 8) & 0xff, + sequenceNumber & 0xff, // sequence_number + ]) + ); + }; - MP4.mfhd = function mfhd(sequenceNumber) { - return MP4.box(MP4.types.mfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // flags - sequenceNumber >> 24, sequenceNumber >> 16 & 0xff, sequenceNumber >> 8 & 0xff, sequenceNumber & 0xff // sequence_number - ])); - }; + MP4.minf = function minf(track) { + if (track.type === "audio") { + return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track)); + } else { + return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track)); + } + }; - MP4.minf = function minf(track) { - if (track.type === 'audio') { - return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track)); - } else { - return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track)); - } - }; + MP4.moof = function moof(sn, baseMediaDecodeTime, track) { + return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime)); + }; + /** + * @param tracks... (optional) {array} the tracks associated with this movie + */ - MP4.moof = function moof(sn, baseMediaDecodeTime, track) { - return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime)); - } - /** - * @param tracks... (optional) {array} the tracks associated with this movie - */ - ; + MP4.moov = function moov(tracks) { + var i = tracks.length; + var boxes = []; - MP4.moov = function moov(tracks) { - var i = tracks.length; - var boxes = []; + while (i--) { + boxes[i] = MP4.trak(tracks[i]); + } - while (i--) { - boxes[i] = MP4.trak(tracks[i]); - } + return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks))); + }; - return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks))); - }; + MP4.mvex = function mvex(tracks) { + var i = tracks.length; + var boxes = []; - MP4.mvex = function mvex(tracks) { - var i = tracks.length; - var boxes = []; + while (i--) { + boxes[i] = MP4.trex(tracks[i]); + } - while (i--) { - boxes[i] = MP4.trex(tracks[i]); - } + return MP4.box.apply(null, [MP4.types.mvex].concat(boxes)); + }; - return MP4.box.apply(null, [MP4.types.mvex].concat(boxes)); - }; + MP4.mvhd = function mvhd(timescale, duration) { + duration *= timescale; + var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); + var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); + var bytes = new Uint8Array([ + 0x01, // version 1 + 0x00, + 0x00, + 0x00, // flags + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x02, // creation_time + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, // modification_time + (timescale >> 24) & 0xff, + (timescale >> 16) & 0xff, + (timescale >> 8) & 0xff, + timescale & 0xff, // timescale + upperWordDuration >> 24, + (upperWordDuration >> 16) & 0xff, + (upperWordDuration >> 8) & 0xff, + upperWordDuration & 0xff, + lowerWordDuration >> 24, + (lowerWordDuration >> 16) & 0xff, + (lowerWordDuration >> 8) & 0xff, + lowerWordDuration & 0xff, + 0x00, + 0x01, + 0x00, + 0x00, // 1.0 rate + 0x01, + 0x00, // 1.0 volume + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, + 0x00, // transformation: unity matrix + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // pre_defined + 0xff, + 0xff, + 0xff, + 0xff, // next_track_ID + ]); + return MP4.box(MP4.types.mvhd, bytes); + }; - MP4.mvhd = function mvhd(timescale, duration) { - duration *= timescale; - var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); - var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); - var bytes = new Uint8Array([0x01, // version 1 - 0x00, 0x00, 0x00, // flags - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // creation_time - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // modification_time - timescale >> 24 & 0xff, timescale >> 16 & 0xff, timescale >> 8 & 0xff, timescale & 0xff, // timescale - upperWordDuration >> 24, upperWordDuration >> 16 & 0xff, upperWordDuration >> 8 & 0xff, upperWordDuration & 0xff, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xff, lowerWordDuration >> 8 & 0xff, lowerWordDuration & 0xff, 0x00, 0x01, 0x00, 0x00, // 1.0 rate - 0x01, 0x00, // 1.0 volume - 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined - 0xff, 0xff, 0xff, 0xff // next_track_ID - ]); - return MP4.box(MP4.types.mvhd, bytes); - }; + MP4.sdtp = function sdtp(track) { + var samples = track.samples || []; + var bytes = new Uint8Array(4 + samples.length); + var i; + var flags; // leave the full box header (4 bytes) all zero + // write the sample table - MP4.sdtp = function sdtp(track) { - var samples = track.samples || []; - var bytes = new Uint8Array(4 + samples.length); - var i; - var flags; // leave the full box header (4 bytes) all zero - // write the sample table + for (i = 0; i < samples.length; i++) { + flags = samples[i].flags; + bytes[i + 4] = (flags.dependsOn << 4) | (flags.isDependedOn << 2) | flags.hasRedundancy; + } - for (i = 0; i < samples.length; i++) { - flags = samples[i].flags; - bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy; - } + return MP4.box(MP4.types.sdtp, bytes); + }; - return MP4.box(MP4.types.sdtp, bytes); - }; + MP4.stbl = function stbl(track) { + return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO)); + }; - MP4.stbl = function stbl(track) { - return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO)); - }; + MP4.avc1 = function avc1(track) { + var sps = []; + var pps = []; + var i; + var data; + var len; // assemble the SPSs - MP4.avc1 = function avc1(track) { - var sps = []; - var pps = []; - var i; - var data; - var len; // assemble the SPSs + for (i = 0; i < track.sps.length; i++) { + data = track.sps[i]; + len = data.byteLength; + sps.push((len >>> 8) & 0xff); + sps.push(len & 0xff); // SPS - for (i = 0; i < track.sps.length; i++) { - data = track.sps[i]; - len = data.byteLength; - sps.push(len >>> 8 & 0xff); - sps.push(len & 0xff); // SPS + sps = sps.concat(Array.prototype.slice.call(data)); + } // assemble the PPSs - sps = sps.concat(Array.prototype.slice.call(data)); - } // assemble the PPSs + for (i = 0; i < track.pps.length; i++) { + data = track.pps[i]; + len = data.byteLength; + pps.push((len >>> 8) & 0xff); + pps.push(len & 0xff); + pps = pps.concat(Array.prototype.slice.call(data)); + } + var avcc = MP4.box( + MP4.types.avcC, + new Uint8Array( + [ + 0x01, // version + sps[3], // profile + sps[4], // profile compat + sps[5], // level + 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes + 0xe0 | track.sps.length, // 3bit reserved (111) + numOfSequenceParameterSets + ] + .concat(sps) + .concat([ + track.pps.length, // numOfPictureParameterSets + ]) + .concat(pps) + ) + ); // "PPS" - for (i = 0; i < track.pps.length; i++) { - data = track.pps[i]; - len = data.byteLength; - pps.push(len >>> 8 & 0xff); - pps.push(len & 0xff); - pps = pps.concat(Array.prototype.slice.call(data)); - } + var width = track.width; + var height = track.height; + var hSpacing = track.pixelRatio[0]; + var vSpacing = track.pixelRatio[1]; + return MP4.box( + MP4.types.avc1, + new Uint8Array([ + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x01, // data_reference_index + 0x00, + 0x00, // pre_defined + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // pre_defined + (width >> 8) & 0xff, + width & 0xff, // width + (height >> 8) & 0xff, + height & 0xff, // height + 0x00, + 0x48, + 0x00, + 0x00, // horizresolution + 0x00, + 0x48, + 0x00, + 0x00, // vertresolution + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x01, // frame_count + 0x12, + 0x64, + 0x61, + 0x69, + 0x6c, // dailymotion/CiderHls.js + 0x79, + 0x6d, + 0x6f, + 0x74, + 0x69, + 0x6f, + 0x6e, + 0x2f, + 0x68, + 0x6c, + 0x73, + 0x2e, + 0x6a, + 0x73, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // compressorname + 0x00, + 0x18, // depth = 24 + 0x11, + 0x11, + ]), // pre_defined = -1 + avcc, + MP4.box( + MP4.types.btrt, + new Uint8Array([ + 0x00, + 0x1c, + 0x9c, + 0x80, // bufferSizeDB + 0x00, + 0x2d, + 0xc6, + 0xc0, // maxBitrate + 0x00, + 0x2d, + 0xc6, + 0xc0, + ]) + ), // avgBitrate + MP4.box( + MP4.types.pasp, + new Uint8Array([ + hSpacing >> 24, // hSpacing + (hSpacing >> 16) & 0xff, + (hSpacing >> 8) & 0xff, + hSpacing & 0xff, + vSpacing >> 24, // vSpacing + (vSpacing >> 16) & 0xff, + (vSpacing >> 8) & 0xff, + vSpacing & 0xff, + ]) + ) + ); + }; - var avcc = MP4.box(MP4.types.avcC, new Uint8Array([0x01, // version - sps[3], // profile - sps[4], // profile compat - sps[5], // level - 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes - 0xe0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets - ].concat(sps).concat([track.pps.length // numOfPictureParameterSets - ]).concat(pps))); // "PPS" + MP4.esds = function esds(track) { + var configlen = track.config.length; + return new Uint8Array( + [ + 0x00, // version 0 + 0x00, + 0x00, + 0x00, // flags + 0x03, // descriptor_type + 0x17 + configlen, // length + 0x00, + 0x01, // es_id + 0x00, // stream_priority + 0x04, // descriptor_type + 0x0f + configlen, // length + 0x40, // codec : mpeg4_audio + 0x15, // stream_type + 0x00, + 0x00, + 0x00, // buffer_size + 0x00, + 0x00, + 0x00, + 0x00, // maxBitrate + 0x00, + 0x00, + 0x00, + 0x00, // avgBitrate + 0x05, // descriptor_type + ] + .concat([configlen]) + .concat(track.config) + .concat([0x06, 0x01, 0x02]) + ); // GASpecificConfig)); // length + audio config descriptor + }; - var width = track.width; - var height = track.height; - var hSpacing = track.pixelRatio[0]; - var vSpacing = track.pixelRatio[1]; - return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, // reserved - 0x00, 0x01, // data_reference_index - 0x00, 0x00, // pre_defined - 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined - width >> 8 & 0xff, width & 0xff, // width - height >> 8 & 0xff, height & 0xff, // height - 0x00, 0x48, 0x00, 0x00, // horizresolution - 0x00, 0x48, 0x00, 0x00, // vertresolution - 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x01, // frame_count - 0x12, 0x64, 0x61, 0x69, 0x6c, // dailymotion/CiderHls.js - 0x79, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x68, 0x6c, 0x73, 0x2e, 0x6a, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // compressorname - 0x00, 0x18, // depth = 24 - 0x11, 0x11]), // pre_defined = -1 - avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80, // bufferSizeDB - 0x00, 0x2d, 0xc6, 0xc0, // maxBitrate - 0x00, 0x2d, 0xc6, 0xc0])), // avgBitrate - MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24, // hSpacing - hSpacing >> 16 & 0xff, hSpacing >> 8 & 0xff, hSpacing & 0xff, vSpacing >> 24, // vSpacing - vSpacing >> 16 & 0xff, vSpacing >> 8 & 0xff, vSpacing & 0xff]))); - }; + MP4.mp4a = function mp4a(track) { + var samplerate = track.samplerate; + return MP4.box( + MP4.types.mp4a, + new Uint8Array([ + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x01, // data_reference_index + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + track.channelCount, // channelcount + 0x00, + 0x10, // sampleSize:16bits + 0x00, + 0x00, + 0x00, + 0x00, // reserved2 + (samplerate >> 8) & 0xff, + samplerate & 0xff, // + 0x00, + 0x00, + ]), + MP4.box(MP4.types.esds, MP4.esds(track)) + ); + }; - MP4.esds = function esds(track) { - var configlen = track.config.length; - return new Uint8Array([0x00, // version 0 - 0x00, 0x00, 0x00, // flags - 0x03, // descriptor_type - 0x17 + configlen, // length - 0x00, 0x01, // es_id - 0x00, // stream_priority - 0x04, // descriptor_type - 0x0f + configlen, // length - 0x40, // codec : mpeg4_audio - 0x15, // stream_type - 0x00, 0x00, 0x00, // buffer_size - 0x00, 0x00, 0x00, 0x00, // maxBitrate - 0x00, 0x00, 0x00, 0x00, // avgBitrate - 0x05 // descriptor_type - ].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor - }; + MP4.mp3 = function mp3(track) { + var samplerate = track.samplerate; + return MP4.box( + MP4.types[".mp3"], + new Uint8Array([ + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x01, // data_reference_index + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + track.channelCount, // channelcount + 0x00, + 0x10, // sampleSize:16bits + 0x00, + 0x00, + 0x00, + 0x00, // reserved2 + (samplerate >> 8) & 0xff, + samplerate & 0xff, // + 0x00, + 0x00, + ]) + ); + }; - MP4.mp4a = function mp4a(track) { - var samplerate = track.samplerate; - return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, // reserved - 0x00, 0x01, // data_reference_index - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, track.channelCount, // channelcount - 0x00, 0x10, // sampleSize:16bits - 0x00, 0x00, 0x00, 0x00, // reserved2 - samplerate >> 8 & 0xff, samplerate & 0xff, // - 0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track))); - }; + MP4.stsd = function stsd(track) { + if (track.type === "audio") { + if (!track.isAAC && track.codec === "mp3") { + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track)); + } - MP4.mp3 = function mp3(track) { - var samplerate = track.samplerate; - return MP4.box(MP4.types['.mp3'], new Uint8Array([0x00, 0x00, 0x00, // reserved - 0x00, 0x00, 0x00, // reserved - 0x00, 0x01, // data_reference_index - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, track.channelCount, // channelcount - 0x00, 0x10, // sampleSize:16bits - 0x00, 0x00, 0x00, 0x00, // reserved2 - samplerate >> 8 & 0xff, samplerate & 0xff, // - 0x00, 0x00])); - }; + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track)); + } else { + return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track)); + } + }; - MP4.stsd = function stsd(track) { - if (track.type === 'audio') { - if (!track.isAAC && track.codec === 'mp3') { - return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track)); - } + MP4.tkhd = function tkhd(track) { + var id = track.id; + var duration = track.duration * track.timescale; + var width = track.width; + var height = track.height; + var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); + var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); + return MP4.box( + MP4.types.tkhd, + new Uint8Array([ + 0x01, // version 1 + 0x00, + 0x00, + 0x07, // flags + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x02, // creation_time + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, // modification_time + (id >> 24) & 0xff, + (id >> 16) & 0xff, + (id >> 8) & 0xff, + id & 0xff, // track_ID + 0x00, + 0x00, + 0x00, + 0x00, // reserved + upperWordDuration >> 24, + (upperWordDuration >> 16) & 0xff, + (upperWordDuration >> 8) & 0xff, + upperWordDuration & 0xff, + lowerWordDuration >> 24, + (lowerWordDuration >> 16) & 0xff, + (lowerWordDuration >> 8) & 0xff, + lowerWordDuration & 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // reserved + 0x00, + 0x00, // layer + 0x00, + 0x00, // alternate_group + 0x00, + 0x00, // non-audio track volume + 0x00, + 0x00, // reserved + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, + 0x00, // transformation: unity matrix + (width >> 8) & 0xff, + width & 0xff, + 0x00, + 0x00, // width + (height >> 8) & 0xff, + height & 0xff, + 0x00, + 0x00, // height + ]) + ); + }; - return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track)); - } else { - return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track)); - } - }; + MP4.traf = function traf(track, baseMediaDecodeTime) { + var sampleDependencyTable = MP4.sdtp(track); + var id = track.id; + var upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)); + var lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1)); + return MP4.box( + MP4.types.traf, + MP4.box( + MP4.types.tfhd, + new Uint8Array([ + 0x00, // version 0 + 0x00, + 0x00, + 0x00, // flags + id >> 24, + (id >> 16) & 0xff, + (id >> 8) & 0xff, + id & 0xff, // track_ID + ]) + ), + MP4.box( + MP4.types.tfdt, + new Uint8Array([ + 0x01, // version 1 + 0x00, + 0x00, + 0x00, // flags + upperWordBaseMediaDecodeTime >> 24, + (upperWordBaseMediaDecodeTime >> 16) & 0xff, + (upperWordBaseMediaDecodeTime >> 8) & 0xff, + upperWordBaseMediaDecodeTime & 0xff, + lowerWordBaseMediaDecodeTime >> 24, + (lowerWordBaseMediaDecodeTime >> 16) & 0xff, + (lowerWordBaseMediaDecodeTime >> 8) & 0xff, + lowerWordBaseMediaDecodeTime & 0xff, + ]) + ), + MP4.trun( + track, + sampleDependencyTable.length + + 16 + // tfhd + 20 + // tfdt + 8 + // traf header + 16 + // mfhd + 8 + // moof header + 8 + ), // mdat header + sampleDependencyTable + ); + }; + /** + * Generate a track box. + * @param track {object} a track definition + * @return {Uint8Array} the track box + */ - MP4.tkhd = function tkhd(track) { - var id = track.id; - var duration = track.duration * track.timescale; - var width = track.width; - var height = track.height; - var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); - var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); - return MP4.box(MP4.types.tkhd, new Uint8Array([0x01, // version 1 - 0x00, 0x00, 0x07, // flags - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // creation_time - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // modification_time - id >> 24 & 0xff, id >> 16 & 0xff, id >> 8 & 0xff, id & 0xff, // track_ID - 0x00, 0x00, 0x00, 0x00, // reserved - upperWordDuration >> 24, upperWordDuration >> 16 & 0xff, upperWordDuration >> 8 & 0xff, upperWordDuration & 0xff, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xff, lowerWordDuration >> 8 & 0xff, lowerWordDuration & 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, 0x00, // layer - 0x00, 0x00, // alternate_group - 0x00, 0x00, // non-audio track volume - 0x00, 0x00, // reserved - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix - width >> 8 & 0xff, width & 0xff, 0x00, 0x00, // width - height >> 8 & 0xff, height & 0xff, 0x00, 0x00 // height - ])); - }; + MP4.trak = function trak(track) { + track.duration = track.duration || 0xffffffff; + return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track)); + }; - MP4.traf = function traf(track, baseMediaDecodeTime) { - var sampleDependencyTable = MP4.sdtp(track); - var id = track.id; - var upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)); - var lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1)); - return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00, // version 0 - 0x00, 0x00, 0x00, // flags - id >> 24, id >> 16 & 0xff, id >> 8 & 0xff, id & 0xff // track_ID - ])), MP4.box(MP4.types.tfdt, new Uint8Array([0x01, // version 1 - 0x00, 0x00, 0x00, // flags - upperWordBaseMediaDecodeTime >> 24, upperWordBaseMediaDecodeTime >> 16 & 0xff, upperWordBaseMediaDecodeTime >> 8 & 0xff, upperWordBaseMediaDecodeTime & 0xff, lowerWordBaseMediaDecodeTime >> 24, lowerWordBaseMediaDecodeTime >> 16 & 0xff, lowerWordBaseMediaDecodeTime >> 8 & 0xff, lowerWordBaseMediaDecodeTime & 0xff])), MP4.trun(track, sampleDependencyTable.length + 16 + // tfhd - 20 + // tfdt - 8 + // traf header - 16 + // mfhd - 8 + // moof header - 8), // mdat header - sampleDependencyTable); - } - /** - * Generate a track box. - * @param track {object} a track definition - * @return {Uint8Array} the track box - */ - ; + MP4.trex = function trex(track) { + var id = track.id; + return MP4.box( + MP4.types.trex, + new Uint8Array([ + 0x00, // version 0 + 0x00, + 0x00, + 0x00, // flags + id >> 24, + (id >> 16) & 0xff, + (id >> 8) & 0xff, + id & 0xff, // track_ID + 0x00, + 0x00, + 0x00, + 0x01, // default_sample_description_index + 0x00, + 0x00, + 0x00, + 0x00, // default_sample_duration + 0x00, + 0x00, + 0x00, + 0x00, // default_sample_size + 0x00, + 0x01, + 0x00, + 0x01, // default_sample_flags + ]) + ); + }; - MP4.trak = function trak(track) { - track.duration = track.duration || 0xffffffff; - return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track)); - }; + MP4.trun = function trun(track, offset) { + var samples = track.samples || []; + var len = samples.length; + var arraylen = 12 + 16 * len; + var array = new Uint8Array(arraylen); + var i; + var sample; + var duration; + var size; + var flags; + var cts; + offset += 8 + arraylen; + array.set( + [ + 0x00, // version 0 + 0x00, + 0x0f, + 0x01, // flags + (len >>> 24) & 0xff, + (len >>> 16) & 0xff, + (len >>> 8) & 0xff, + len & 0xff, // sample_count + (offset >>> 24) & 0xff, + (offset >>> 16) & 0xff, + (offset >>> 8) & 0xff, + offset & 0xff, // data_offset + ], + 0 + ); - MP4.trex = function trex(track) { - var id = track.id; - return MP4.box(MP4.types.trex, new Uint8Array([0x00, // version 0 - 0x00, 0x00, 0x00, // flags - id >> 24, id >> 16 & 0xff, id >> 8 & 0xff, id & 0xff, // track_ID - 0x00, 0x00, 0x00, 0x01, // default_sample_description_index - 0x00, 0x00, 0x00, 0x00, // default_sample_duration - 0x00, 0x00, 0x00, 0x00, // default_sample_size - 0x00, 0x01, 0x00, 0x01 // default_sample_flags - ])); - }; + for (i = 0; i < len; i++) { + sample = samples[i]; + duration = sample.duration; + size = sample.size; + flags = sample.flags; + cts = sample.cts; + array.set( + [ + (duration >>> 24) & 0xff, + (duration >>> 16) & 0xff, + (duration >>> 8) & 0xff, + duration & 0xff, // sample_duration + (size >>> 24) & 0xff, + (size >>> 16) & 0xff, + (size >>> 8) & 0xff, + size & 0xff, // sample_size + (flags.isLeading << 2) | flags.dependsOn, + (flags.isDependedOn << 6) | (flags.hasRedundancy << 4) | (flags.paddingValue << 1) | flags.isNonSync, + flags.degradPrio & (0xf0 << 8), + flags.degradPrio & 0x0f, // sample_flags + (cts >>> 24) & 0xff, + (cts >>> 16) & 0xff, + (cts >>> 8) & 0xff, + cts & 0xff, // sample_composition_time_offset + ], + 12 + 16 * i + ); + } - MP4.trun = function trun(track, offset) { - var samples = track.samples || []; - var len = samples.length; - var arraylen = 12 + 16 * len; - var array = new Uint8Array(arraylen); - var i; - var sample; - var duration; - var size; - var flags; - var cts; - offset += 8 + arraylen; - array.set([0x00, // version 0 - 0x00, 0x0f, 0x01, // flags - len >>> 24 & 0xff, len >>> 16 & 0xff, len >>> 8 & 0xff, len & 0xff, // sample_count - offset >>> 24 & 0xff, offset >>> 16 & 0xff, offset >>> 8 & 0xff, offset & 0xff // data_offset - ], 0); + return MP4.box(MP4.types.trun, array); + }; - for (i = 0; i < len; i++) { - sample = samples[i]; - duration = sample.duration; - size = sample.size; - flags = sample.flags; - cts = sample.cts; - array.set([duration >>> 24 & 0xff, duration >>> 16 & 0xff, duration >>> 8 & 0xff, duration & 0xff, // sample_duration - size >>> 24 & 0xff, size >>> 16 & 0xff, size >>> 8 & 0xff, size & 0xff, // sample_size - flags.isLeading << 2 | flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xf0 << 8, flags.degradPrio & 0x0f, // sample_flags - cts >>> 24 & 0xff, cts >>> 16 & 0xff, cts >>> 8 & 0xff, cts & 0xff // sample_composition_time_offset - ], 12 + 16 * i); - } + MP4.initSegment = function initSegment(tracks) { + if (!MP4.types) { + MP4.init(); + } - return MP4.box(MP4.types.trun, array); - }; + var movie = MP4.moov(tracks); + var result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength); + result.set(MP4.FTYP); + result.set(movie, MP4.FTYP.byteLength); + return result; + }; - MP4.initSegment = function initSegment(tracks) { - if (!MP4.types) { - MP4.init(); - } + return MP4; + })(); - var movie = MP4.moov(tracks); - var result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength); - result.set(MP4.FTYP); - result.set(movie, MP4.FTYP.byteLength); - return result; - }; + MP4.types = void 0; + MP4.HDLR_TYPES = void 0; + MP4.STTS = void 0; + MP4.STSC = void 0; + MP4.STCO = void 0; + MP4.STSZ = void 0; + MP4.VMHD = void 0; + MP4.SMHD = void 0; + MP4.STSD = void 0; + MP4.FTYP = void 0; + MP4.DINF = void 0; + /* harmony default export */ __webpack_exports__["default"] = MP4; - return MP4; -}(); + /***/ + }, -MP4.types = void 0; -MP4.HDLR_TYPES = void 0; -MP4.STTS = void 0; -MP4.STSC = void 0; -MP4.STCO = void 0; -MP4.STSZ = void 0; -MP4.VMHD = void 0; -MP4.SMHD = void 0; -MP4.STSD = void 0; -MP4.FTYP = void 0; -MP4.DINF = void 0; -/* harmony default export */ __webpack_exports__["default"] = (MP4); - -/***/ }), - -/***/ "./src/remux/mp4-remuxer.ts": -/*!**********************************!*\ + /***/ "./src/remux/mp4-remuxer.ts": + /*!**********************************!*\ !*** ./src/remux/mp4-remuxer.ts ***! \**********************************/ -/*! exports provided: default, normalizePts */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default, normalizePts */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return MP4Remuxer; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalizePts", function () { + return normalizePts; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _aac_helper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./aac-helper */ "./src/remux/aac-helper.ts"); + /* harmony import */ var _mp4_generator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mp4-generator */ "./src/remux/mp4-generator.ts"); + /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../events */ "./src/events.ts"); + /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); + /* harmony import */ var _utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/timescale-conversion */ "./src/utils/timescale-conversion.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return MP4Remuxer; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalizePts", function() { return normalizePts; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _aac_helper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./aac-helper */ "./src/remux/aac-helper.ts"); -/* harmony import */ var _mp4_generator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mp4-generator */ "./src/remux/mp4-generator.ts"); -/* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../events */ "./src/events.ts"); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts"); -/* harmony import */ var _utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/timescale-conversion */ "./src/utils/timescale-conversion.ts"); - - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - - - - - - - - -var MAX_SILENT_FRAME_DURATION = 10 * 1000; // 10 seconds - -var AAC_SAMPLES_PER_FRAME = 1024; -var MPEG_AUDIO_SAMPLE_PER_FRAME = 1152; -var chromeVersion = null; -var safariWebkitVersion = null; -var requiresPositiveDts = false; - -var MP4Remuxer = /*#__PURE__*/function () { - function MP4Remuxer(observer, config, typeSupported, vendor) { - if (vendor === void 0) { - vendor = ''; - } - - this.observer = void 0; - this.config = void 0; - this.typeSupported = void 0; - this.ISGenerated = false; - this._initPTS = void 0; - this._initDTS = void 0; - this.nextAvcDts = null; - this.nextAudioPts = null; - this.isAudioContiguous = false; - this.isVideoContiguous = false; - this.observer = observer; - this.config = config; - this.typeSupported = typeSupported; - this.ISGenerated = false; - - if (chromeVersion === null) { - var userAgent = navigator.userAgent || ''; - var result = userAgent.match(/Chrome\/(\d+)/i); - chromeVersion = result ? parseInt(result[1]) : 0; - } - - if (safariWebkitVersion === null) { - var _result = navigator.userAgent.match(/Safari\/(\d+)/i); - - safariWebkitVersion = _result ? parseInt(_result[1]) : 0; - } - - requiresPositiveDts = !!chromeVersion && chromeVersion < 75 || !!safariWebkitVersion && safariWebkitVersion < 600; - } - - var _proto = MP4Remuxer.prototype; - - _proto.destroy = function destroy() {}; - - _proto.resetTimeStamp = function resetTimeStamp(defaultTimeStamp) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log('[mp4-remuxer]: initPTS & initDTS reset'); - this._initPTS = this._initDTS = defaultTimeStamp; - }; - - _proto.resetNextTimestamp = function resetNextTimestamp() { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log('[mp4-remuxer]: reset next timestamp'); - this.isVideoContiguous = false; - this.isAudioContiguous = false; - }; - - _proto.resetInitSegment = function resetInitSegment() { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log('[mp4-remuxer]: ISGenerated flag reset'); - this.ISGenerated = false; - }; - - _proto.getVideoStartPts = function getVideoStartPts(videoSamples) { - var rolloverDetected = false; - var startPTS = videoSamples.reduce(function (minPTS, sample) { - var delta = sample.pts - minPTS; - - if (delta < -4294967296) { - // 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation - rolloverDetected = true; - return normalizePts(minPTS, sample.pts); - } else if (delta > 0) { - return minPTS; - } else { - return sample.pts; - } - }, videoSamples[0].pts); - - if (rolloverDetected) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].debug('PTS rollover detected'); - } - - return startPTS; - }; - - _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, flush, playlistType) { - var video; - var audio; - var initSegment; - var text; - var id3; - var independent; - var audioTimeOffset = timeOffset; - var videoTimeOffset = timeOffset; // If we're remuxing audio and video progressively, wait until we've received enough samples for each track before proceeding. - // This is done to synchronize the audio and video streams. We know if the current segment will have samples if the "pid" - // parameter is greater than -1. The pid is set when the PMT is parsed, which contains the tracks list. - // However, if the initSegment has already been generated, or we've reached the end of a segment (flush), - // then we can remux one track without waiting for the other. - - var hasAudio = audioTrack.pid > -1; - var hasVideo = videoTrack.pid > -1; - var length = videoTrack.samples.length; - var enoughAudioSamples = audioTrack.samples.length > 0; - var enoughVideoSamples = length > 1; - var canRemuxAvc = (!hasAudio || enoughAudioSamples) && (!hasVideo || enoughVideoSamples) || this.ISGenerated || flush; - - if (canRemuxAvc) { - if (!this.ISGenerated) { - initSegment = this.generateIS(audioTrack, videoTrack, timeOffset); - } - - var isVideoContiguous = this.isVideoContiguous; - var firstKeyFrameIndex = -1; - - if (enoughVideoSamples) { - firstKeyFrameIndex = findKeyframeIndex(videoTrack.samples); - - if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) { - independent = true; - - if (firstKeyFrameIndex > 0) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: Dropped " + firstKeyFrameIndex + " out of " + length + " video samples due to a missing keyframe"); - var startPTS = this.getVideoStartPts(videoTrack.samples); - videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex); - videoTrack.dropped += firstKeyFrameIndex; - videoTimeOffset += (videoTrack.samples[0].pts - startPTS) / (videoTrack.timescale || 90000); - } else if (firstKeyFrameIndex === -1) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: No keyframe found out of " + length + " video samples"); - independent = false; - } - } - } - - if (this.ISGenerated) { - if (enoughAudioSamples && enoughVideoSamples) { - // timeOffset is expected to be the offset of the first timestamp of this fragment (first DTS) - // if first audio DTS is not aligned with first video DTS then we need to take that into account - // when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small - // drift between audio and video streams - var _startPTS = this.getVideoStartPts(videoTrack.samples); - - var tsDelta = normalizePts(audioTrack.samples[0].pts, _startPTS) - _startPTS; - - var audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale; - audioTimeOffset += Math.max(0, audiovideoTimestampDelta); - videoTimeOffset += Math.max(0, -audiovideoTimestampDelta); - } // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is calculated in remuxAudio. - - - if (enoughAudioSamples) { - // if initSegment was generated without audio samples, regenerate it again - if (!audioTrack.samplerate) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn('[mp4-remuxer]: regenerate InitSegment as audio detected'); - initSegment = this.generateIS(audioTrack, videoTrack, timeOffset); - } - - audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO ? videoTimeOffset : undefined); - - if (enoughVideoSamples) { - var audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0; // if initSegment was generated without video samples, regenerate it again - - if (!videoTrack.inputTimeScale) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn('[mp4-remuxer]: regenerate InitSegment as video detected'); - initSegment = this.generateIS(audioTrack, videoTrack, timeOffset); + function _extends() { + _extends = + Object.assign || + function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); } - video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, audioTrackLength); - } - } else if (enoughVideoSamples) { - video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, 0); - } + var MAX_SILENT_FRAME_DURATION = 10 * 1000; // 10 seconds - if (video) { - video.firstKeyFrame = firstKeyFrameIndex; - video.independent = firstKeyFrameIndex !== -1; - } - } - } // Allow ID3 and text to remux, even if more audio/video samples are required + var AAC_SAMPLES_PER_FRAME = 1024; + var MPEG_AUDIO_SAMPLE_PER_FRAME = 1152; + var chromeVersion = null; + var safariWebkitVersion = null; + var requiresPositiveDts = false; + var MP4Remuxer = /*#__PURE__*/ (function () { + function MP4Remuxer(observer, config, typeSupported, vendor) { + if (vendor === void 0) { + vendor = ""; + } - if (this.ISGenerated) { - if (id3Track.samples.length) { - id3 = this.remuxID3(id3Track, timeOffset); - } + this.observer = void 0; + this.config = void 0; + this.typeSupported = void 0; + this.ISGenerated = false; + this._initPTS = void 0; + this._initDTS = void 0; + this.nextAvcDts = null; + this.nextAudioPts = null; + this.isAudioContiguous = false; + this.isVideoContiguous = false; + this.observer = observer; + this.config = config; + this.typeSupported = typeSupported; + this.ISGenerated = false; - if (textTrack.samples.length) { - text = this.remuxText(textTrack, timeOffset); - } - } + if (chromeVersion === null) { + var userAgent = navigator.userAgent || ""; + var result = userAgent.match(/Chrome\/(\d+)/i); + chromeVersion = result ? parseInt(result[1]) : 0; + } - return { - audio: audio, - video: video, - initSegment: initSegment, - independent: independent, - text: text, - id3: id3 - }; - }; + if (safariWebkitVersion === null) { + var _result = navigator.userAgent.match(/Safari\/(\d+)/i); - _proto.generateIS = function generateIS(audioTrack, videoTrack, timeOffset) { - var audioSamples = audioTrack.samples; - var videoSamples = videoTrack.samples; - var typeSupported = this.typeSupported; - var tracks = {}; - var computePTSDTS = !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this._initPTS); - var container = 'audio/mp4'; - var initPTS; - var initDTS; - var timescale; + safariWebkitVersion = _result ? parseInt(_result[1]) : 0; + } - if (computePTSDTS) { - initPTS = initDTS = Infinity; - } + requiresPositiveDts = (!!chromeVersion && chromeVersion < 75) || (!!safariWebkitVersion && safariWebkitVersion < 600); + } - if (audioTrack.config && audioSamples.length) { - // let's use audio sampling rate as MP4 time scale. - // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC) - // using audio sampling rate here helps having an integer MP4 frame duration - // this avoids potential rounding issue and AV sync issue - audioTrack.timescale = audioTrack.samplerate; + var _proto = MP4Remuxer.prototype; - if (!audioTrack.isAAC) { - if (typeSupported.mpeg) { - // Chrome and Safari - container = 'audio/mpeg'; - audioTrack.codec = ''; - } else if (typeSupported.mp3) { - // Firefox - audioTrack.codec = 'mp3'; - } - } + _proto.destroy = function destroy() {}; - tracks.audio = { - id: 'audio', - container: container, - codec: audioTrack.codec, - initSegment: !audioTrack.isAAC && typeSupported.mpeg ? new Uint8Array(0) : _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([audioTrack]), - metadata: { - channelCount: audioTrack.channelCount - } - }; + _proto.resetTimeStamp = function resetTimeStamp(defaultTimeStamp) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("[mp4-remuxer]: initPTS & initDTS reset"); + this._initPTS = this._initDTS = defaultTimeStamp; + }; - if (computePTSDTS) { - timescale = audioTrack.inputTimeScale; // remember first PTS of this demuxing context. for audio, PTS = DTS + _proto.resetNextTimestamp = function resetNextTimestamp() { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("[mp4-remuxer]: reset next timestamp"); + this.isVideoContiguous = false; + this.isAudioContiguous = false; + }; - initPTS = initDTS = audioSamples[0].pts - Math.round(timescale * timeOffset); - } - } + _proto.resetInitSegment = function resetInitSegment() { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("[mp4-remuxer]: ISGenerated flag reset"); + this.ISGenerated = false; + }; - if (videoTrack.sps && videoTrack.pps && videoSamples.length) { - // let's use input time scale as MP4 video timescale - // we use input time scale straight away to avoid rounding issues on frame duration / cts computation - videoTrack.timescale = videoTrack.inputTimeScale; - tracks.video = { - id: 'main', - container: 'video/mp4', - codec: videoTrack.codec, - initSegment: _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([videoTrack]), - metadata: { - width: videoTrack.width, - height: videoTrack.height - } - }; + _proto.getVideoStartPts = function getVideoStartPts(videoSamples) { + var rolloverDetected = false; + var startPTS = videoSamples.reduce(function (minPTS, sample) { + var delta = sample.pts - minPTS; - if (computePTSDTS) { - timescale = videoTrack.inputTimeScale; - var startPTS = this.getVideoStartPts(videoSamples); - var startOffset = Math.round(timescale * timeOffset); - initDTS = Math.min(initDTS, normalizePts(videoSamples[0].dts, startPTS) - startOffset); - initPTS = Math.min(initPTS, startPTS - startOffset); - } - } + if (delta < -4294967296) { + // 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation + rolloverDetected = true; + return normalizePts(minPTS, sample.pts); + } else if (delta > 0) { + return minPTS; + } else { + return sample.pts; + } + }, videoSamples[0].pts); - if (Object.keys(tracks).length) { - this.ISGenerated = true; + if (rolloverDetected) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].debug("PTS rollover detected"); + } - if (computePTSDTS) { - this._initPTS = initPTS; - this._initDTS = initDTS; - } + return startPTS; + }; - return { - tracks: tracks, - initPTS: initPTS, - timescale: timescale - }; - } - }; + _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, flush, playlistType) { + var video; + var audio; + var initSegment; + var text; + var id3; + var independent; + var audioTimeOffset = timeOffset; + var videoTimeOffset = timeOffset; // If we're remuxing audio and video progressively, wait until we've received enough samples for each track before proceeding. + // This is done to synchronize the audio and video streams. We know if the current segment will have samples if the "pid" + // parameter is greater than -1. The pid is set when the PMT is parsed, which contains the tracks list. + // However, if the initSegment has already been generated, or we've reached the end of a segment (flush), + // then we can remux one track without waiting for the other. - _proto.remuxVideo = function remuxVideo(track, timeOffset, contiguous, audioTrackLength) { - var timeScale = track.inputTimeScale; - var inputSamples = track.samples; - var outputSamples = []; - var nbSamples = inputSamples.length; - var initPTS = this._initPTS; - var nextAvcDts = this.nextAvcDts; - var offset = 8; - var mp4SampleDuration; - var firstDTS; - var lastDTS; - var minPTS = Number.POSITIVE_INFINITY; - var maxPTS = Number.NEGATIVE_INFINITY; - var ptsDtsShift = 0; - var sortSamples = false; // if parsed fragment is contiguous with last one, let's use last DTS value as reference + var hasAudio = audioTrack.pid > -1; + var hasVideo = videoTrack.pid > -1; + var length = videoTrack.samples.length; + var enoughAudioSamples = audioTrack.samples.length > 0; + var enoughVideoSamples = length > 1; + var canRemuxAvc = ((!hasAudio || enoughAudioSamples) && (!hasVideo || enoughVideoSamples)) || this.ISGenerated || flush; - if (!contiguous || nextAvcDts === null) { - var pts = timeOffset * timeScale; - var cts = inputSamples[0].pts - normalizePts(inputSamples[0].dts, inputSamples[0].pts); // if not contiguous, let's use target timeOffset + if (canRemuxAvc) { + if (!this.ISGenerated) { + initSegment = this.generateIS(audioTrack, videoTrack, timeOffset); + } - nextAvcDts = pts - cts; - } // PTS is coded on 33bits, and can loop from -2^32 to 2^32 - // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value + var isVideoContiguous = this.isVideoContiguous; + var firstKeyFrameIndex = -1; + if (enoughVideoSamples) { + firstKeyFrameIndex = findKeyframeIndex(videoTrack.samples); - for (var i = 0; i < nbSamples; i++) { - var sample = inputSamples[i]; - sample.pts = normalizePts(sample.pts - initPTS, nextAvcDts); - sample.dts = normalizePts(sample.dts - initPTS, nextAvcDts); + if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) { + independent = true; - if (sample.dts > sample.pts) { - var PTS_DTS_SHIFT_TOLERANCE_90KHZ = 90000 * 0.2; - ptsDtsShift = Math.max(Math.min(ptsDtsShift, sample.pts - sample.dts), -1 * PTS_DTS_SHIFT_TOLERANCE_90KHZ); - } + if (firstKeyFrameIndex > 0) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: Dropped " + firstKeyFrameIndex + " out of " + length + " video samples due to a missing keyframe"); + var startPTS = this.getVideoStartPts(videoTrack.samples); + videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex); + videoTrack.dropped += firstKeyFrameIndex; + videoTimeOffset += (videoTrack.samples[0].pts - startPTS) / (videoTrack.timescale || 90000); + } else if (firstKeyFrameIndex === -1) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: No keyframe found out of " + length + " video samples"); + independent = false; + } + } + } - if (sample.dts < inputSamples[i > 0 ? i - 1 : i].dts) { - sortSamples = true; - } - } // sort video samples by DTS then PTS then demux id order + if (this.ISGenerated) { + if (enoughAudioSamples && enoughVideoSamples) { + // timeOffset is expected to be the offset of the first timestamp of this fragment (first DTS) + // if first audio DTS is not aligned with first video DTS then we need to take that into account + // when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small + // drift between audio and video streams + var _startPTS = this.getVideoStartPts(videoTrack.samples); + var tsDelta = normalizePts(audioTrack.samples[0].pts, _startPTS) - _startPTS; - if (sortSamples) { - inputSamples.sort(function (a, b) { - var deltadts = a.dts - b.dts; - var deltapts = a.pts - b.pts; - return deltadts || deltapts; - }); - } // Get first/last DTS + var audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale; + audioTimeOffset += Math.max(0, audiovideoTimestampDelta); + videoTimeOffset += Math.max(0, -audiovideoTimestampDelta); + } // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is calculated in remuxAudio. + if (enoughAudioSamples) { + // if initSegment was generated without audio samples, regenerate it again + if (!audioTrack.samplerate) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: regenerate InitSegment as audio detected"); + initSegment = this.generateIS(audioTrack, videoTrack, timeOffset); + } - firstDTS = inputSamples[0].dts; - lastDTS = inputSamples[inputSamples.length - 1].dts; // on Safari let's signal the same sample duration for all samples - // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS - // set this constant duration as being the avg delta between consecutive DTS. + audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO ? videoTimeOffset : undefined); - var averageSampleDuration = Math.round((lastDTS - firstDTS) / (nbSamples - 1)); // handle broken streams with PTS < DTS, tolerance up 0.2 seconds + if (enoughVideoSamples) { + var audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0; // if initSegment was generated without video samples, regenerate it again - if (ptsDtsShift < 0) { - if (ptsDtsShift < averageSampleDuration * -2) { - // Fix for "CNN special report, with CC" in test-streams (including Safari browser) - // With large PTS < DTS errors such as this, we want to correct CTS while maintaining increasing DTS values - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("PTS < DTS detected in video samples, offsetting DTS from PTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-averageSampleDuration, true) + " ms"); - var lastDts = ptsDtsShift; + if (!videoTrack.inputTimeScale) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: regenerate InitSegment as video detected"); + initSegment = this.generateIS(audioTrack, videoTrack, timeOffset); + } - for (var _i = 0; _i < nbSamples; _i++) { - inputSamples[_i].dts = lastDts = Math.max(lastDts, inputSamples[_i].pts - averageSampleDuration); - inputSamples[_i].pts = Math.max(lastDts, inputSamples[_i].pts); - } - } else { - // Fix for "Custom IV with bad PTS DTS" in test-streams - // With smaller PTS < DTS errors we can simply move all DTS back. This increases CTS without causing buffer gaps or decode errors in Safari - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("PTS < DTS detected in video samples, shifting DTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(ptsDtsShift, true) + " ms to overcome this issue"); + video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, audioTrackLength); + } + } else if (enoughVideoSamples) { + video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, 0); + } - for (var _i2 = 0; _i2 < nbSamples; _i2++) { - inputSamples[_i2].dts = inputSamples[_i2].dts + ptsDtsShift; - } - } + if (video) { + video.firstKeyFrame = firstKeyFrameIndex; + video.independent = firstKeyFrameIndex !== -1; + } + } + } // Allow ID3 and text to remux, even if more audio/video samples are required - firstDTS = inputSamples[0].dts; - } // if fragment are contiguous, detect hole/overlapping between fragments + if (this.ISGenerated) { + if (id3Track.samples.length) { + id3 = this.remuxID3(id3Track, timeOffset); + } + if (textTrack.samples.length) { + text = this.remuxText(textTrack, timeOffset); + } + } - if (contiguous) { - // check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole) - var delta = firstDTS - nextAvcDts; - var foundHole = delta > averageSampleDuration; - var foundOverlap = delta < -1; + return { + audio: audio, + video: video, + initSegment: initSegment, + independent: independent, + text: text, + id3: id3, + }; + }; - if (foundHole || foundOverlap) { - if (foundHole) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(delta, true) + " ms (" + delta + "dts) hole between fragments detected, filling it"); - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected"); - } + _proto.generateIS = function generateIS(audioTrack, videoTrack, timeOffset) { + var audioSamples = audioTrack.samples; + var videoSamples = videoTrack.samples; + var typeSupported = this.typeSupported; + var tracks = {}; + var computePTSDTS = !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(this._initPTS); + var container = "audio/mp4"; + var initPTS; + var initDTS; + var timescale; - firstDTS = nextAvcDts; - var firstPTS = inputSamples[0].pts - delta; - inputSamples[0].dts = firstDTS; - inputSamples[0].pts = firstPTS; - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("Video: First PTS/DTS adjusted: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(firstPTS, true) + "/" + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(firstDTS, true) + ", delta: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(delta, true) + " ms"); - } - } + if (computePTSDTS) { + initPTS = initDTS = Infinity; + } - if (requiresPositiveDts) { - firstDTS = Math.max(0, firstDTS); - } + if (audioTrack.config && audioSamples.length) { + // let's use audio sampling rate as MP4 time scale. + // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC) + // using audio sampling rate here helps having an integer MP4 frame duration + // this avoids potential rounding issue and AV sync issue + audioTrack.timescale = audioTrack.samplerate; - var nbNalu = 0; - var naluLen = 0; + if (!audioTrack.isAAC) { + if (typeSupported.mpeg) { + // Chrome and Safari + container = "audio/mpeg"; + audioTrack.codec = ""; + } else if (typeSupported.mp3) { + // Firefox + audioTrack.codec = "mp3"; + } + } - for (var _i3 = 0; _i3 < nbSamples; _i3++) { - // compute total/avc sample length and nb of NAL units - var _sample = inputSamples[_i3]; - var units = _sample.units; - var nbUnits = units.length; - var sampleLen = 0; + tracks.audio = { + id: "audio", + container: container, + codec: audioTrack.codec, + initSegment: !audioTrack.isAAC && typeSupported.mpeg ? new Uint8Array(0) : _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([audioTrack]), + metadata: { + channelCount: audioTrack.channelCount, + }, + }; - for (var j = 0; j < nbUnits; j++) { - sampleLen += units[j].data.length; - } + if (computePTSDTS) { + timescale = audioTrack.inputTimeScale; // remember first PTS of this demuxing context. for audio, PTS = DTS - naluLen += sampleLen; - nbNalu += nbUnits; - _sample.length = sampleLen; // normalize PTS/DTS - // ensure sample monotonic DTS + initPTS = initDTS = audioSamples[0].pts - Math.round(timescale * timeOffset); + } + } - _sample.dts = Math.max(_sample.dts, firstDTS); // ensure that computed value is greater or equal than sample DTS + if (videoTrack.sps && videoTrack.pps && videoSamples.length) { + // let's use input time scale as MP4 video timescale + // we use input time scale straight away to avoid rounding issues on frame duration / cts computation + videoTrack.timescale = videoTrack.inputTimeScale; + tracks.video = { + id: "main", + container: "video/mp4", + codec: videoTrack.codec, + initSegment: _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([videoTrack]), + metadata: { + width: videoTrack.width, + height: videoTrack.height, + }, + }; - _sample.pts = Math.max(_sample.pts, _sample.dts, 0); - minPTS = Math.min(_sample.pts, minPTS); - maxPTS = Math.max(_sample.pts, maxPTS); - } + if (computePTSDTS) { + timescale = videoTrack.inputTimeScale; + var startPTS = this.getVideoStartPts(videoSamples); + var startOffset = Math.round(timescale * timeOffset); + initDTS = Math.min(initDTS, normalizePts(videoSamples[0].dts, startPTS) - startOffset); + initPTS = Math.min(initPTS, startPTS - startOffset); + } + } - lastDTS = inputSamples[nbSamples - 1].dts; - /* concatenate the video data and construct the mdat in place + if (Object.keys(tracks).length) { + this.ISGenerated = true; + + if (computePTSDTS) { + this._initPTS = initPTS; + this._initDTS = initDTS; + } + + return { + tracks: tracks, + initPTS: initPTS, + timescale: timescale, + }; + } + }; + + _proto.remuxVideo = function remuxVideo(track, timeOffset, contiguous, audioTrackLength) { + var timeScale = track.inputTimeScale; + var inputSamples = track.samples; + var outputSamples = []; + var nbSamples = inputSamples.length; + var initPTS = this._initPTS; + var nextAvcDts = this.nextAvcDts; + var offset = 8; + var mp4SampleDuration; + var firstDTS; + var lastDTS; + var minPTS = Number.POSITIVE_INFINITY; + var maxPTS = Number.NEGATIVE_INFINITY; + var ptsDtsShift = 0; + var sortSamples = false; // if parsed fragment is contiguous with last one, let's use last DTS value as reference + + if (!contiguous || nextAvcDts === null) { + var pts = timeOffset * timeScale; + var cts = inputSamples[0].pts - normalizePts(inputSamples[0].dts, inputSamples[0].pts); // if not contiguous, let's use target timeOffset + + nextAvcDts = pts - cts; + } // PTS is coded on 33bits, and can loop from -2^32 to 2^32 + // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value + + for (var i = 0; i < nbSamples; i++) { + var sample = inputSamples[i]; + sample.pts = normalizePts(sample.pts - initPTS, nextAvcDts); + sample.dts = normalizePts(sample.dts - initPTS, nextAvcDts); + + if (sample.dts > sample.pts) { + var PTS_DTS_SHIFT_TOLERANCE_90KHZ = 90000 * 0.2; + ptsDtsShift = Math.max(Math.min(ptsDtsShift, sample.pts - sample.dts), -1 * PTS_DTS_SHIFT_TOLERANCE_90KHZ); + } + + if (sample.dts < inputSamples[i > 0 ? i - 1 : i].dts) { + sortSamples = true; + } + } // sort video samples by DTS then PTS then demux id order + + if (sortSamples) { + inputSamples.sort(function (a, b) { + var deltadts = a.dts - b.dts; + var deltapts = a.pts - b.pts; + return deltadts || deltapts; + }); + } // Get first/last DTS + + firstDTS = inputSamples[0].dts; + lastDTS = inputSamples[inputSamples.length - 1].dts; // on Safari let's signal the same sample duration for all samples + // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS + // set this constant duration as being the avg delta between consecutive DTS. + + var averageSampleDuration = Math.round((lastDTS - firstDTS) / (nbSamples - 1)); // handle broken streams with PTS < DTS, tolerance up 0.2 seconds + + if (ptsDtsShift < 0) { + if (ptsDtsShift < averageSampleDuration * -2) { + // Fix for "CNN special report, with CC" in test-streams (including Safari browser) + // With large PTS < DTS errors such as this, we want to correct CTS while maintaining increasing DTS values + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("PTS < DTS detected in video samples, offsetting DTS from PTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-averageSampleDuration, true) + " ms"); + var lastDts = ptsDtsShift; + + for (var _i = 0; _i < nbSamples; _i++) { + inputSamples[_i].dts = lastDts = Math.max(lastDts, inputSamples[_i].pts - averageSampleDuration); + inputSamples[_i].pts = Math.max(lastDts, inputSamples[_i].pts); + } + } else { + // Fix for "Custom IV with bad PTS DTS" in test-streams + // With smaller PTS < DTS errors we can simply move all DTS back. This increases CTS without causing buffer gaps or decode errors in Safari + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("PTS < DTS detected in video samples, shifting DTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(ptsDtsShift, true) + " ms to overcome this issue"); + + for (var _i2 = 0; _i2 < nbSamples; _i2++) { + inputSamples[_i2].dts = inputSamples[_i2].dts + ptsDtsShift; + } + } + + firstDTS = inputSamples[0].dts; + } // if fragment are contiguous, detect hole/overlapping between fragments + + if (contiguous) { + // check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole) + var delta = firstDTS - nextAvcDts; + var foundHole = delta > averageSampleDuration; + var foundOverlap = delta < -1; + + if (foundHole || foundOverlap) { + if (foundHole) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(delta, true) + " ms (" + delta + "dts) hole between fragments detected, filling it"); + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected"); + } + + firstDTS = nextAvcDts; + var firstPTS = inputSamples[0].pts - delta; + inputSamples[0].dts = firstDTS; + inputSamples[0].pts = firstPTS; + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log( + "Video: First PTS/DTS adjusted: " + + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(firstPTS, true) + + "/" + + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(firstDTS, true) + + ", delta: " + + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(delta, true) + + " ms" + ); + } + } + + if (requiresPositiveDts) { + firstDTS = Math.max(0, firstDTS); + } + + var nbNalu = 0; + var naluLen = 0; + + for (var _i3 = 0; _i3 < nbSamples; _i3++) { + // compute total/avc sample length and nb of NAL units + var _sample = inputSamples[_i3]; + var units = _sample.units; + var nbUnits = units.length; + var sampleLen = 0; + + for (var j = 0; j < nbUnits; j++) { + sampleLen += units[j].data.length; + } + + naluLen += sampleLen; + nbNalu += nbUnits; + _sample.length = sampleLen; // normalize PTS/DTS + // ensure sample monotonic DTS + + _sample.dts = Math.max(_sample.dts, firstDTS); // ensure that computed value is greater or equal than sample DTS + + _sample.pts = Math.max(_sample.pts, _sample.dts, 0); + minPTS = Math.min(_sample.pts, minPTS); + maxPTS = Math.max(_sample.pts, maxPTS); + } + + lastDTS = inputSamples[nbSamples - 1].dts; + /* concatenate the video data and construct the mdat in place (need 8 more bytes to fill length and mpdat type) */ - var mdatSize = naluLen + 4 * nbNalu + 8; - var mdat; + var mdatSize = naluLen + 4 * nbNalu + 8; + var mdat; - try { - mdat = new Uint8Array(mdatSize); - } catch (err) { - this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].MUX_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].REMUX_ALLOC_ERROR, - fatal: false, - bytes: mdatSize, - reason: "fail allocating video mdat " + mdatSize - }); - return; - } + try { + mdat = new Uint8Array(mdatSize); + } catch (err) { + this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].MUX_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].REMUX_ALLOC_ERROR, + fatal: false, + bytes: mdatSize, + reason: "fail allocating video mdat " + mdatSize, + }); + return; + } - var view = new DataView(mdat.buffer); - view.setUint32(0, mdatSize); - mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat, 4); + var view = new DataView(mdat.buffer); + view.setUint32(0, mdatSize); + mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat, 4); - for (var _i4 = 0; _i4 < nbSamples; _i4++) { - var avcSample = inputSamples[_i4]; - var avcSampleUnits = avcSample.units; - var mp4SampleLength = 0; // convert NALU bitstream to MP4 format (prepend NALU with size field) + for (var _i4 = 0; _i4 < nbSamples; _i4++) { + var avcSample = inputSamples[_i4]; + var avcSampleUnits = avcSample.units; + var mp4SampleLength = 0; // convert NALU bitstream to MP4 format (prepend NALU with size field) - for (var _j = 0, _nbUnits = avcSampleUnits.length; _j < _nbUnits; _j++) { - var unit = avcSampleUnits[_j]; - var unitData = unit.data; - var unitDataLen = unit.data.byteLength; - view.setUint32(offset, unitDataLen); - offset += 4; - mdat.set(unitData, offset); - offset += unitDataLen; - mp4SampleLength += 4 + unitDataLen; - } // expected sample duration is the Decoding Timestamp diff of consecutive samples + for (var _j = 0, _nbUnits = avcSampleUnits.length; _j < _nbUnits; _j++) { + var unit = avcSampleUnits[_j]; + var unitData = unit.data; + var unitDataLen = unit.data.byteLength; + view.setUint32(offset, unitDataLen); + offset += 4; + mdat.set(unitData, offset); + offset += unitDataLen; + mp4SampleLength += 4 + unitDataLen; + } // expected sample duration is the Decoding Timestamp diff of consecutive samples + if (_i4 < nbSamples - 1) { + mp4SampleDuration = inputSamples[_i4 + 1].dts - avcSample.dts; + } else { + var config = this.config; + var lastFrameDuration = avcSample.dts - inputSamples[_i4 > 0 ? _i4 - 1 : _i4].dts; - if (_i4 < nbSamples - 1) { - mp4SampleDuration = inputSamples[_i4 + 1].dts - avcSample.dts; - } else { - var config = this.config; - var lastFrameDuration = avcSample.dts - inputSamples[_i4 > 0 ? _i4 - 1 : _i4].dts; + if (config.stretchShortVideoTrack && this.nextAudioPts !== null) { + // In some cases, a segment's audio track duration may exceed the video track duration. + // Since we've already remuxed audio, and we know how long the audio track is, we look to + // see if the delta to the next segment is longer than maxBufferHole. + // If so, playback would potentially get stuck, so we artificially inflate + // the duration of the last frame to minimize any potential gap between segments. + var gapTolerance = Math.floor(config.maxBufferHole * timeScale); + var deltaToFrameEnd = (audioTrackLength ? minPTS + audioTrackLength * timeScale : this.nextAudioPts) - avcSample.pts; - if (config.stretchShortVideoTrack && this.nextAudioPts !== null) { - // In some cases, a segment's audio track duration may exceed the video track duration. - // Since we've already remuxed audio, and we know how long the audio track is, we look to - // see if the delta to the next segment is longer than maxBufferHole. - // If so, playback would potentially get stuck, so we artificially inflate - // the duration of the last frame to minimize any potential gap between segments. - var gapTolerance = Math.floor(config.maxBufferHole * timeScale); - var deltaToFrameEnd = (audioTrackLength ? minPTS + audioTrackLength * timeScale : this.nextAudioPts) - avcSample.pts; + if (deltaToFrameEnd > gapTolerance) { + // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video + // frame overlap. maxBufferHole should be >> lastFrameDuration anyway. + mp4SampleDuration = deltaToFrameEnd - lastFrameDuration; - if (deltaToFrameEnd > gapTolerance) { - // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video - // frame overlap. maxBufferHole should be >> lastFrameDuration anyway. - mp4SampleDuration = deltaToFrameEnd - lastFrameDuration; + if (mp4SampleDuration < 0) { + mp4SampleDuration = lastFrameDuration; + } - if (mp4SampleDuration < 0) { - mp4SampleDuration = lastFrameDuration; - } + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("[mp4-remuxer]: It is approximately " + deltaToFrameEnd / 90 + " ms to the next segment; using duration " + mp4SampleDuration / 90 + " ms for the last video frame."); + } else { + mp4SampleDuration = lastFrameDuration; + } + } else { + mp4SampleDuration = lastFrameDuration; + } + } - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("[mp4-remuxer]: It is approximately " + deltaToFrameEnd / 90 + " ms to the next segment; using duration " + mp4SampleDuration / 90 + " ms for the last video frame."); - } else { - mp4SampleDuration = lastFrameDuration; - } - } else { - mp4SampleDuration = lastFrameDuration; - } - } + var compositionTimeOffset = Math.round(avcSample.pts - avcSample.dts); + outputSamples.push(new Mp4Sample(avcSample.key, mp4SampleDuration, mp4SampleLength, compositionTimeOffset)); + } - var compositionTimeOffset = Math.round(avcSample.pts - avcSample.dts); - outputSamples.push(new Mp4Sample(avcSample.key, mp4SampleDuration, mp4SampleLength, compositionTimeOffset)); - } + if (outputSamples.length && chromeVersion && chromeVersion < 70) { + // Chrome workaround, mark first sample as being a Random Access Point (keyframe) to avoid sourcebuffer append issue + // https://code.google.com/p/chromium/issues/detail?id=229412 + var flags = outputSamples[0].flags; + flags.dependsOn = 2; + flags.isNonSync = 0; + } - if (outputSamples.length && chromeVersion && chromeVersion < 70) { - // Chrome workaround, mark first sample as being a Random Access Point (keyframe) to avoid sourcebuffer append issue - // https://code.google.com/p/chromium/issues/detail?id=229412 - var flags = outputSamples[0].flags; - flags.dependsOn = 2; - flags.isNonSync = 0; - } + console.assert(mp4SampleDuration !== undefined, "mp4SampleDuration must be computed"); // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale) - console.assert(mp4SampleDuration !== undefined, 'mp4SampleDuration must be computed'); // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale) + this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration; + this.isVideoContiguous = true; + var moof = _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof( + track.sequenceNumber++, + firstDTS, + _extends({}, track, { + samples: outputSamples, + }) + ); + var type = "video"; + var data = { + data1: moof, + data2: mdat, + startPTS: minPTS / timeScale, + endPTS: (maxPTS + mp4SampleDuration) / timeScale, + startDTS: firstDTS / timeScale, + endDTS: nextAvcDts / timeScale, + type: type, + hasAudio: false, + hasVideo: true, + nb: outputSamples.length, + dropped: track.dropped, + }; + track.samples = []; + track.dropped = 0; + console.assert(mdat.length, "MDAT length must not be zero"); + return data; + }; - this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration; - this.isVideoContiguous = true; - var moof = _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof(track.sequenceNumber++, firstDTS, _extends({}, track, { - samples: outputSamples - })); - var type = 'video'; - var data = { - data1: moof, - data2: mdat, - startPTS: minPTS / timeScale, - endPTS: (maxPTS + mp4SampleDuration) / timeScale, - startDTS: firstDTS / timeScale, - endDTS: nextAvcDts / timeScale, - type: type, - hasAudio: false, - hasVideo: true, - nb: outputSamples.length, - dropped: track.dropped - }; - track.samples = []; - track.dropped = 0; - console.assert(mdat.length, 'MDAT length must not be zero'); - return data; - }; + _proto.remuxAudio = function remuxAudio(track, timeOffset, contiguous, accurateTimeOffset, videoTimeOffset) { + var inputTimeScale = track.inputTimeScale; + var mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale; + var scaleFactor = inputTimeScale / mp4timeScale; + var mp4SampleDuration = track.isAAC ? AAC_SAMPLES_PER_FRAME : MPEG_AUDIO_SAMPLE_PER_FRAME; + var inputSampleDuration = mp4SampleDuration * scaleFactor; + var initPTS = this._initPTS; + var rawMPEG = !track.isAAC && this.typeSupported.mpeg; + var outputSamples = []; + var inputSamples = track.samples; + var offset = rawMPEG ? 0 : 8; + var nextAudioPts = this.nextAudioPts || -1; // window.audioSamples ? window.audioSamples.push(inputSamples.map(s => s.pts)) : (window.audioSamples = [inputSamples.map(s => s.pts)]); + // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs), + // for sake of clarity: + // consecutive fragments are frags with + // - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR + // - less than 20 audio frames distance + // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1) + // this helps ensuring audio continuity + // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame - _proto.remuxAudio = function remuxAudio(track, timeOffset, contiguous, accurateTimeOffset, videoTimeOffset) { - var inputTimeScale = track.inputTimeScale; - var mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale; - var scaleFactor = inputTimeScale / mp4timeScale; - var mp4SampleDuration = track.isAAC ? AAC_SAMPLES_PER_FRAME : MPEG_AUDIO_SAMPLE_PER_FRAME; - var inputSampleDuration = mp4SampleDuration * scaleFactor; - var initPTS = this._initPTS; - var rawMPEG = !track.isAAC && this.typeSupported.mpeg; - var outputSamples = []; - var inputSamples = track.samples; - var offset = rawMPEG ? 0 : 8; - var nextAudioPts = this.nextAudioPts || -1; // window.audioSamples ? window.audioSamples.push(inputSamples.map(s => s.pts)) : (window.audioSamples = [inputSamples.map(s => s.pts)]); - // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs), - // for sake of clarity: - // consecutive fragments are frags with - // - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR - // - less than 20 audio frames distance - // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1) - // this helps ensuring audio continuity - // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame + var timeOffsetMpegTS = timeOffset * inputTimeScale; + this.isAudioContiguous = contiguous = + contiguous || (inputSamples.length && nextAudioPts > 0 && ((accurateTimeOffset && Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000) || Math.abs(normalizePts(inputSamples[0].pts - initPTS, timeOffsetMpegTS) - nextAudioPts) < 20 * inputSampleDuration)); // compute normalized PTS - var timeOffsetMpegTS = timeOffset * inputTimeScale; - this.isAudioContiguous = contiguous = contiguous || inputSamples.length && nextAudioPts > 0 && (accurateTimeOffset && Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000 || Math.abs(normalizePts(inputSamples[0].pts - initPTS, timeOffsetMpegTS) - nextAudioPts) < 20 * inputSampleDuration); // compute normalized PTS + inputSamples.forEach(function (sample) { + sample.pts = normalizePts(sample.pts - initPTS, timeOffsetMpegTS); + }); - inputSamples.forEach(function (sample) { - sample.pts = normalizePts(sample.pts - initPTS, timeOffsetMpegTS); - }); + if (!contiguous || nextAudioPts < 0) { + // filter out sample with negative PTS that are not playable anyway + // if we don't remove these negative samples, they will shift all audio samples forward. + // leading to audio overlap between current / next fragment + inputSamples = inputSamples.filter(function (sample) { + return sample.pts >= 0; + }); // in case all samples have negative PTS, and have been filtered out, return now - if (!contiguous || nextAudioPts < 0) { - // filter out sample with negative PTS that are not playable anyway - // if we don't remove these negative samples, they will shift all audio samples forward. - // leading to audio overlap between current / next fragment - inputSamples = inputSamples.filter(function (sample) { - return sample.pts >= 0; - }); // in case all samples have negative PTS, and have been filtered out, return now + if (!inputSamples.length) { + return; + } - if (!inputSamples.length) { - return; - } + if (videoTimeOffset === 0) { + // Set the start to 0 to match video so that start gaps larger than inputSampleDuration are filled with silence + nextAudioPts = 0; + } else if (accurateTimeOffset) { + // When not seeking, not live, and LevelDetails.PTSKnown, use fragment start as predicted next audio PTS + nextAudioPts = Math.max(0, timeOffsetMpegTS); + } else { + // if frags are not contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS + nextAudioPts = inputSamples[0].pts; + } + } // If the audio track is missing samples, the frames seem to get "left-shifted" within the + // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment. + // In an effort to prevent this from happening, we inject frames here where there are gaps. + // When possible, we inject a silent frame; when that's not possible, we duplicate the last + // frame. - if (videoTimeOffset === 0) { - // Set the start to 0 to match video so that start gaps larger than inputSampleDuration are filled with silence - nextAudioPts = 0; - } else if (accurateTimeOffset) { - // When not seeking, not live, and LevelDetails.PTSKnown, use fragment start as predicted next audio PTS - nextAudioPts = Math.max(0, timeOffsetMpegTS); - } else { - // if frags are not contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS - nextAudioPts = inputSamples[0].pts; - } - } // If the audio track is missing samples, the frames seem to get "left-shifted" within the - // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment. - // In an effort to prevent this from happening, we inject frames here where there are gaps. - // When possible, we inject a silent frame; when that's not possible, we duplicate the last - // frame. + if (track.isAAC) { + var alignedWithVideo = videoTimeOffset !== undefined; + var maxAudioFramesDrift = this.config.maxAudioFramesDrift; + for (var i = 0, nextPts = nextAudioPts; i < inputSamples.length; i++) { + // First, let's see how far off this frame is from where we expect it to be + var sample = inputSamples[i]; + var pts = sample.pts; + var delta = pts - nextPts; + var duration = Math.abs((1000 * delta) / inputTimeScale); // When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync - if (track.isAAC) { - var alignedWithVideo = videoTimeOffset !== undefined; - var maxAudioFramesDrift = this.config.maxAudioFramesDrift; + if (delta <= -maxAudioFramesDrift * inputSampleDuration && alignedWithVideo) { + if (i === 0) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("Audio frame @ " + (pts / inputTimeScale).toFixed(3) + "s overlaps nextAudioPts by " + Math.round((1000 * delta) / inputTimeScale) + " ms."); + this.nextAudioPts = nextAudioPts = nextPts = pts; + } + } // eslint-disable-line brace-style + // Insert missing frames if: + // 1: We're more than maxAudioFramesDrift frame away + // 2: Not more than MAX_SILENT_FRAME_DURATION away + // 3: currentTime (aka nextPtsNorm) is not 0 + // 4: remuxing with video (videoTimeOffset !== undefined) + else if (delta >= maxAudioFramesDrift * inputSampleDuration && duration < MAX_SILENT_FRAME_DURATION && alignedWithVideo) { + var missing = Math.round(delta / inputSampleDuration); // Adjust nextPts so that silent samples are aligned with media pts. This will prevent media samples from + // later being shifted if nextPts is based on timeOffset and delta is not a multiple of inputSampleDuration. - for (var i = 0, nextPts = nextAudioPts; i < inputSamples.length; i++) { - // First, let's see how far off this frame is from where we expect it to be - var sample = inputSamples[i]; - var pts = sample.pts; - var delta = pts - nextPts; - var duration = Math.abs(1000 * delta / inputTimeScale); // When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync + nextPts = pts - missing * inputSampleDuration; - if (delta <= -maxAudioFramesDrift * inputSampleDuration && alignedWithVideo) { - if (i === 0) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("Audio frame @ " + (pts / inputTimeScale).toFixed(3) + "s overlaps nextAudioPts by " + Math.round(1000 * delta / inputTimeScale) + " ms."); - this.nextAudioPts = nextAudioPts = nextPts = pts; - } - } // eslint-disable-line brace-style - // Insert missing frames if: - // 1: We're more than maxAudioFramesDrift frame away - // 2: Not more than MAX_SILENT_FRAME_DURATION away - // 3: currentTime (aka nextPtsNorm) is not 0 - // 4: remuxing with video (videoTimeOffset !== undefined) - else if (delta >= maxAudioFramesDrift * inputSampleDuration && duration < MAX_SILENT_FRAME_DURATION && alignedWithVideo) { - var missing = Math.round(delta / inputSampleDuration); // Adjust nextPts so that silent samples are aligned with media pts. This will prevent media samples from - // later being shifted if nextPts is based on timeOffset and delta is not a multiple of inputSampleDuration. + if (nextPts < 0) { + missing--; + nextPts += inputSampleDuration; + } - nextPts = pts - missing * inputSampleDuration; + if (i === 0) { + this.nextAudioPts = nextAudioPts = nextPts; + } - if (nextPts < 0) { - missing--; - nextPts += inputSampleDuration; - } + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round((1000 * delta) / inputTimeScale) + " ms gap."); - if (i === 0) { - this.nextAudioPts = nextAudioPts = nextPts; - } + for (var j = 0; j < missing; j++) { + var newStamp = Math.max(nextPts, 0); + var fillFrame = _aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec || track.codec, track.channelCount); - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round(1000 * delta / inputTimeScale) + " ms gap."); + if (!fillFrame) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead."); + fillFrame = sample.unit.subarray(); + } - for (var j = 0; j < missing; j++) { - var newStamp = Math.max(nextPts, 0); - var fillFrame = _aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec || track.codec, track.channelCount); + inputSamples.splice(i, 0, { + unit: fillFrame, + pts: newStamp, + }); + nextPts += inputSampleDuration; + i++; + } + } - if (!fillFrame) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.'); - fillFrame = sample.unit.subarray(); - } + sample.pts = nextPts; + nextPts += inputSampleDuration; + } + } - inputSamples.splice(i, 0, { - unit: fillFrame, - pts: newStamp - }); - nextPts += inputSampleDuration; - i++; - } - } + var firstPTS = null; + var lastPTS = null; + var mdat; + var mdatSize = 0; + var sampleLength = inputSamples.length; - sample.pts = nextPts; - nextPts += inputSampleDuration; - } - } + while (sampleLength--) { + mdatSize += inputSamples[sampleLength].unit.byteLength; + } - var firstPTS = null; - var lastPTS = null; - var mdat; - var mdatSize = 0; - var sampleLength = inputSamples.length; + for (var _j2 = 0, _nbSamples = inputSamples.length; _j2 < _nbSamples; _j2++) { + var audioSample = inputSamples[_j2]; + var unit = audioSample.unit; + var _pts = audioSample.pts; - while (sampleLength--) { - mdatSize += inputSamples[sampleLength].unit.byteLength; - } + if (lastPTS !== null) { + // If we have more than one sample, set the duration of the sample to the "real" duration; the PTS diff with + // the previous sample + var prevSample = outputSamples[_j2 - 1]; + prevSample.duration = Math.round((_pts - lastPTS) / scaleFactor); + } else { + if (contiguous && track.isAAC) { + // set PTS/DTS to expected PTS/DTS + _pts = nextAudioPts; + } // remember first PTS of our audioSamples - for (var _j2 = 0, _nbSamples = inputSamples.length; _j2 < _nbSamples; _j2++) { - var audioSample = inputSamples[_j2]; - var unit = audioSample.unit; - var _pts = audioSample.pts; + firstPTS = _pts; - if (lastPTS !== null) { - // If we have more than one sample, set the duration of the sample to the "real" duration; the PTS diff with - // the previous sample - var prevSample = outputSamples[_j2 - 1]; - prevSample.duration = Math.round((_pts - lastPTS) / scaleFactor); - } else { - if (contiguous && track.isAAC) { - // set PTS/DTS to expected PTS/DTS - _pts = nextAudioPts; - } // remember first PTS of our audioSamples - - - firstPTS = _pts; - - if (mdatSize > 0) { - /* concatenate the audio data and construct the mdat in place + if (mdatSize > 0) { + /* concatenate the audio data and construct the mdat in place (need 8 more bytes to fill length and mdat type) */ - mdatSize += offset; + mdatSize += offset; - try { - mdat = new Uint8Array(mdatSize); - } catch (err) { - this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, { - type: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].MUX_ERROR, - details: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].REMUX_ALLOC_ERROR, - fatal: false, - bytes: mdatSize, - reason: "fail allocating audio mdat " + mdatSize - }); - return; - } + try { + mdat = new Uint8Array(mdatSize); + } catch (err) { + this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, _events__WEBPACK_IMPORTED_MODULE_3__["Events"].ERROR, { + type: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorTypes"].MUX_ERROR, + details: _errors__WEBPACK_IMPORTED_MODULE_4__["ErrorDetails"].REMUX_ALLOC_ERROR, + fatal: false, + bytes: mdatSize, + reason: "fail allocating audio mdat " + mdatSize, + }); + return; + } - if (!rawMPEG) { - var view = new DataView(mdat.buffer); - view.setUint32(0, mdatSize); - mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat, 4); - } - } else { - // no audio samples - return; - } - } + if (!rawMPEG) { + var view = new DataView(mdat.buffer); + view.setUint32(0, mdatSize); + mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat, 4); + } + } else { + // no audio samples + return; + } + } - mdat.set(unit, offset); - var unitLen = unit.byteLength; - offset += unitLen; // Default the sample's duration to the computed mp4SampleDuration, which will either be 1024 for AAC or 1152 for MPEG - // In the case that we have 1 sample, this will be the duration. If we have more than one sample, the duration - // becomes the PTS diff with the previous sample + mdat.set(unit, offset); + var unitLen = unit.byteLength; + offset += unitLen; // Default the sample's duration to the computed mp4SampleDuration, which will either be 1024 for AAC or 1152 for MPEG + // In the case that we have 1 sample, this will be the duration. If we have more than one sample, the duration + // becomes the PTS diff with the previous sample - outputSamples.push(new Mp4Sample(true, mp4SampleDuration, unitLen, 0)); - lastPTS = _pts; - } // We could end up with no audio samples if all input samples were overlapping with the previously remuxed ones + outputSamples.push(new Mp4Sample(true, mp4SampleDuration, unitLen, 0)); + lastPTS = _pts; + } // We could end up with no audio samples if all input samples were overlapping with the previously remuxed ones + var nbSamples = outputSamples.length; - var nbSamples = outputSamples.length; + if (!nbSamples) { + return; + } // The next audio sample PTS should be equal to last sample PTS + duration - if (!nbSamples) { - return; - } // The next audio sample PTS should be equal to last sample PTS + duration + var lastSample = outputSamples[outputSamples.length - 1]; + this.nextAudioPts = nextAudioPts = lastPTS + scaleFactor * lastSample.duration; // Set the track samples from inputSamples to outputSamples before remuxing + var moof = rawMPEG + ? new Uint8Array(0) + : _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof( + track.sequenceNumber++, + firstPTS / scaleFactor, + _extends({}, track, { + samples: outputSamples, + }) + ); // Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared - var lastSample = outputSamples[outputSamples.length - 1]; - this.nextAudioPts = nextAudioPts = lastPTS + scaleFactor * lastSample.duration; // Set the track samples from inputSamples to outputSamples before remuxing + track.samples = []; + var start = firstPTS / inputTimeScale; + var end = nextAudioPts / inputTimeScale; + var type = "audio"; + var audioData = { + data1: moof, + data2: mdat, + startPTS: start, + endPTS: end, + startDTS: start, + endDTS: end, + type: type, + hasAudio: true, + hasVideo: false, + nb: nbSamples, + }; + this.isAudioContiguous = true; + console.assert(mdat.length, "MDAT length must not be zero"); + return audioData; + }; - var moof = rawMPEG ? new Uint8Array(0) : _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof(track.sequenceNumber++, firstPTS / scaleFactor, _extends({}, track, { - samples: outputSamples - })); // Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared + _proto.remuxEmptyAudio = function remuxEmptyAudio(track, timeOffset, contiguous, videoData) { + var inputTimeScale = track.inputTimeScale; + var mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale; + var scaleFactor = inputTimeScale / mp4timeScale; + var nextAudioPts = this.nextAudioPts; // sync with video's timestamp - track.samples = []; - var start = firstPTS / inputTimeScale; - var end = nextAudioPts / inputTimeScale; - var type = 'audio'; - var audioData = { - data1: moof, - data2: mdat, - startPTS: start, - endPTS: end, - startDTS: start, - endDTS: end, - type: type, - hasAudio: true, - hasVideo: false, - nb: nbSamples - }; - this.isAudioContiguous = true; - console.assert(mdat.length, 'MDAT length must not be zero'); - return audioData; - }; + var startDTS = (nextAudioPts !== null ? nextAudioPts : videoData.startDTS * inputTimeScale) + this._initDTS; + var endDTS = videoData.endDTS * inputTimeScale + this._initDTS; // one sample's duration value - _proto.remuxEmptyAudio = function remuxEmptyAudio(track, timeOffset, contiguous, videoData) { - var inputTimeScale = track.inputTimeScale; - var mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale; - var scaleFactor = inputTimeScale / mp4timeScale; - var nextAudioPts = this.nextAudioPts; // sync with video's timestamp + var frameDuration = scaleFactor * AAC_SAMPLES_PER_FRAME; // samples count of this segment's duration - var startDTS = (nextAudioPts !== null ? nextAudioPts : videoData.startDTS * inputTimeScale) + this._initDTS; - var endDTS = videoData.endDTS * inputTimeScale + this._initDTS; // one sample's duration value + var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration); // silent frame - var frameDuration = scaleFactor * AAC_SAMPLES_PER_FRAME; // samples count of this segment's duration + var silentFrame = _aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec || track.codec, track.channelCount); + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: remux empty Audio"); // Can't remux if we can't generate a silent frame... - var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration); // silent frame + if (!silentFrame) { + _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].trace("[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec"); + return; + } - var silentFrame = _aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec || track.codec, track.channelCount); - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn('[mp4-remuxer]: remux empty Audio'); // Can't remux if we can't generate a silent frame... + var samples = []; - if (!silentFrame) { - _utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].trace('[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec'); - return; - } + for (var i = 0; i < nbSamples; i++) { + var stamp = startDTS + i * frameDuration; + samples.push({ + unit: silentFrame, + pts: stamp, + dts: stamp, + }); + } - var samples = []; + track.samples = samples; + return this.remuxAudio(track, timeOffset, contiguous, false); + }; - for (var i = 0; i < nbSamples; i++) { - var stamp = startDTS + i * frameDuration; - samples.push({ - unit: silentFrame, - pts: stamp, - dts: stamp - }); - } + _proto.remuxID3 = function remuxID3(track, timeOffset) { + var length = track.samples.length; - track.samples = samples; - return this.remuxAudio(track, timeOffset, contiguous, false); - }; + if (!length) { + return; + } - _proto.remuxID3 = function remuxID3(track, timeOffset) { - var length = track.samples.length; + var inputTimeScale = track.inputTimeScale; + var initPTS = this._initPTS; + var initDTS = this._initDTS; - if (!length) { - return; - } + for (var index = 0; index < length; index++) { + var sample = track.samples[index]; // setting id3 pts, dts to relative time + // using this._initPTS and this._initDTS to calculate relative time - var inputTimeScale = track.inputTimeScale; - var initPTS = this._initPTS; - var initDTS = this._initDTS; + sample.pts = normalizePts(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale; + sample.dts = normalizePts(sample.dts - initDTS, timeOffset * inputTimeScale) / inputTimeScale; + } - for (var index = 0; index < length; index++) { - var sample = track.samples[index]; // setting id3 pts, dts to relative time - // using this._initPTS and this._initDTS to calculate relative time + var samples = track.samples; + track.samples = []; + return { + samples: samples, + }; + }; - sample.pts = normalizePts(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale; - sample.dts = normalizePts(sample.dts - initDTS, timeOffset * inputTimeScale) / inputTimeScale; - } + _proto.remuxText = function remuxText(track, timeOffset) { + var length = track.samples.length; - var samples = track.samples; - track.samples = []; - return { - samples: samples - }; - }; + if (!length) { + return; + } - _proto.remuxText = function remuxText(track, timeOffset) { - var length = track.samples.length; + var inputTimeScale = track.inputTimeScale; + var initPTS = this._initPTS; - if (!length) { - return; - } + for (var index = 0; index < length; index++) { + var sample = track.samples[index]; // setting text pts, dts to relative time + // using this._initPTS and this._initDTS to calculate relative time - var inputTimeScale = track.inputTimeScale; - var initPTS = this._initPTS; + sample.pts = normalizePts(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale; + } - for (var index = 0; index < length; index++) { - var sample = track.samples[index]; // setting text pts, dts to relative time - // using this._initPTS and this._initDTS to calculate relative time + track.samples.sort(function (a, b) { + return a.pts - b.pts; + }); + var samples = track.samples; + track.samples = []; + return { + samples: samples, + }; + }; - sample.pts = normalizePts(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale; - } + return MP4Remuxer; + })(); - track.samples.sort(function (a, b) { - return a.pts - b.pts; - }); - var samples = track.samples; - track.samples = []; - return { - samples: samples - }; - }; + function normalizePts(value, reference) { + var offset; - return MP4Remuxer; -}(); + if (reference === null) { + return value; + } - -function normalizePts(value, reference) { - var offset; - - if (reference === null) { - return value; - } - - if (reference < value) { - // - 2^33 - offset = -8589934592; - } else { - // + 2^33 - offset = 8589934592; - } - /* PTS is 33bit (from 0 to 2^33 -1) + if (reference < value) { + // - 2^33 + offset = -8589934592; + } else { + // + 2^33 + offset = 8589934592; + } + /* PTS is 33bit (from 0 to 2^33 -1) if diff between value and reference is bigger than half of the amplitude (2^32) then it means that PTS looping occured. fill the gap */ + while (Math.abs(value - reference) > 4294967296) { + value += offset; + } - while (Math.abs(value - reference) > 4294967296) { - value += offset; - } + return value; + } - return value; -} + function findKeyframeIndex(samples) { + for (var i = 0; i < samples.length; i++) { + if (samples[i].key) { + return i; + } + } -function findKeyframeIndex(samples) { - for (var i = 0; i < samples.length; i++) { - if (samples[i].key) { - return i; - } - } + return -1; + } - return -1; -} + var Mp4Sample = function Mp4Sample(isKeyframe, duration, size, cts) { + this.size = void 0; + this.duration = void 0; + this.cts = void 0; + this.flags = void 0; + this.duration = duration; + this.size = size; + this.cts = cts; + this.flags = new Mp4SampleFlags(isKeyframe); + }; -var Mp4Sample = function Mp4Sample(isKeyframe, duration, size, cts) { - this.size = void 0; - this.duration = void 0; - this.cts = void 0; - this.flags = void 0; - this.duration = duration; - this.size = size; - this.cts = cts; - this.flags = new Mp4SampleFlags(isKeyframe); -}; + var Mp4SampleFlags = function Mp4SampleFlags(isKeyframe) { + this.isLeading = 0; + this.isDependedOn = 0; + this.hasRedundancy = 0; + this.degradPrio = 0; + this.dependsOn = 1; + this.isNonSync = 1; + this.dependsOn = isKeyframe ? 2 : 1; + this.isNonSync = isKeyframe ? 0 : 1; + }; -var Mp4SampleFlags = function Mp4SampleFlags(isKeyframe) { - this.isLeading = 0; - this.isDependedOn = 0; - this.hasRedundancy = 0; - this.degradPrio = 0; - this.dependsOn = 1; - this.isNonSync = 1; - this.dependsOn = isKeyframe ? 2 : 1; - this.isNonSync = isKeyframe ? 0 : 1; -}; + /***/ + }, -/***/ }), - -/***/ "./src/remux/passthrough-remuxer.ts": -/*!******************************************!*\ + /***/ "./src/remux/passthrough-remuxer.ts": + /*!******************************************!*\ !*** ./src/remux/passthrough-remuxer.ts ***! \******************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + var PassThroughRemuxer = /*#__PURE__*/ (function () { + function PassThroughRemuxer() { + this.emitInitSegment = false; + this.audioCodec = void 0; + this.videoCodec = void 0; + this.initData = void 0; + this.initPTS = void 0; + this.initTracks = void 0; + this.lastEndDTS = null; + } + var _proto = PassThroughRemuxer.prototype; + _proto.destroy = function destroy() {}; + _proto.resetTimeStamp = function resetTimeStamp(defaultInitPTS) { + this.initPTS = defaultInitPTS; + this.lastEndDTS = null; + }; + _proto.resetNextTimestamp = function resetNextTimestamp() { + this.lastEndDTS = null; + }; + _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec) { + this.audioCodec = audioCodec; + this.videoCodec = videoCodec; + this.generateInitSegment(initSegment); + this.emitInitSegment = true; + }; -var PassThroughRemuxer = /*#__PURE__*/function () { - function PassThroughRemuxer() { - this.emitInitSegment = false; - this.audioCodec = void 0; - this.videoCodec = void 0; - this.initData = void 0; - this.initPTS = void 0; - this.initTracks = void 0; - this.lastEndDTS = null; - } + _proto.generateInitSegment = function generateInitSegment(initSegment) { + var audioCodec = this.audioCodec, + videoCodec = this.videoCodec; - var _proto = PassThroughRemuxer.prototype; + if (!initSegment || !initSegment.byteLength) { + this.initTracks = undefined; + this.initData = undefined; + return; + } - _proto.destroy = function destroy() {}; + var initData = (this.initData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["parseInitSegment"])(initSegment)); // Get codec from initSegment or fallback to default - _proto.resetTimeStamp = function resetTimeStamp(defaultInitPTS) { - this.initPTS = defaultInitPTS; - this.lastEndDTS = null; - }; + if (!audioCodec) { + audioCodec = getParsedTrackCodec(initData.audio, _loader_fragment__WEBPACK_IMPORTED_MODULE_2__["ElementaryStreamTypes"].AUDIO); + } - _proto.resetNextTimestamp = function resetNextTimestamp() { - this.lastEndDTS = null; - }; + if (!videoCodec) { + videoCodec = getParsedTrackCodec(initData.video, _loader_fragment__WEBPACK_IMPORTED_MODULE_2__["ElementaryStreamTypes"].VIDEO); + } - _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec) { - this.audioCodec = audioCodec; - this.videoCodec = videoCodec; - this.generateInitSegment(initSegment); - this.emitInitSegment = true; - }; + var tracks = {}; - _proto.generateInitSegment = function generateInitSegment(initSegment) { - var audioCodec = this.audioCodec, - videoCodec = this.videoCodec; + if (initData.audio && initData.video) { + tracks.audiovideo = { + container: "video/mp4", + codec: audioCodec + "," + videoCodec, + initSegment: initSegment, + id: "main", + }; + } else if (initData.audio) { + tracks.audio = { + container: "audio/mp4", + codec: audioCodec, + initSegment: initSegment, + id: "audio", + }; + } else if (initData.video) { + tracks.video = { + container: "video/mp4", + codec: videoCodec, + initSegment: initSegment, + id: "main", + }; + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes."); + } - if (!initSegment || !initSegment.byteLength) { - this.initTracks = undefined; - this.initData = undefined; - return; - } + this.initTracks = tracks; + }; - var initData = this.initData = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["parseInitSegment"])(initSegment); // Get codec from initSegment or fallback to default + _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset) { + var initPTS = this.initPTS, + lastEndDTS = this.lastEndDTS; + var result = { + audio: undefined, + video: undefined, + text: textTrack, + id3: id3Track, + initSegment: undefined, + }; // If we haven't yet set a lastEndDTS, or it was reset, set it to the provided timeOffset. We want to use the + // lastEndDTS over timeOffset whenever possible; during progressive playback, the media source will not update + // the media duration (which is what timeOffset is provided as) before we need to process the next chunk. - if (!audioCodec) { - audioCodec = getParsedTrackCodec(initData.audio, _loader_fragment__WEBPACK_IMPORTED_MODULE_2__["ElementaryStreamTypes"].AUDIO); - } + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(lastEndDTS)) { + lastEndDTS = this.lastEndDTS = timeOffset || 0; + } // The binary segment data is added to the videoTrack in the mp4demuxer. We don't check to see if the data is only + // audio or video (or both); adding it to video was an arbitrary choice. - if (!videoCodec) { - videoCodec = getParsedTrackCodec(initData.video, _loader_fragment__WEBPACK_IMPORTED_MODULE_2__["ElementaryStreamTypes"].VIDEO); - } + var data = videoTrack.samples; - var tracks = {}; + if (!data || !data.length) { + return result; + } - if (initData.audio && initData.video) { - tracks.audiovideo = { - container: 'video/mp4', - codec: audioCodec + ',' + videoCodec, - initSegment: initSegment, - id: 'main' - }; - } else if (initData.audio) { - tracks.audio = { - container: 'audio/mp4', - codec: audioCodec, - initSegment: initSegment, - id: 'audio' - }; - } else if (initData.video) { - tracks.video = { - container: 'video/mp4', - codec: videoCodec, - initSegment: initSegment, - id: 'main' - }; - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.'); - } + var initSegment = { + initPTS: undefined, + timescale: 1, + }; + var initData = this.initData; - this.initTracks = tracks; - }; + if (!initData || !initData.length) { + this.generateInitSegment(data); + initData = this.initData; + } - _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset) { - var initPTS = this.initPTS, - lastEndDTS = this.lastEndDTS; - var result = { - audio: undefined, - video: undefined, - text: textTrack, - id3: id3Track, - initSegment: undefined - }; // If we haven't yet set a lastEndDTS, or it was reset, set it to the provided timeOffset. We want to use the - // lastEndDTS over timeOffset whenever possible; during progressive playback, the media source will not update - // the media duration (which is what timeOffset is provided as) before we need to process the next chunk. + if (!initData || !initData.length) { + // We can't remux if the initSegment could not be generated + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("[passthrough-remuxer.ts]: Failed to generate initSegment."); + return result; + } - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(lastEndDTS)) { - lastEndDTS = this.lastEndDTS = timeOffset || 0; - } // The binary segment data is added to the videoTrack in the mp4demuxer. We don't check to see if the data is only - // audio or video (or both); adding it to video was an arbitrary choice. + if (this.emitInitSegment) { + initSegment.tracks = this.initTracks; + this.emitInitSegment = false; + } + if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(initPTS)) { + this.initPTS = initSegment.initPTS = initPTS = computeInitPTS(initData, data, lastEndDTS); + } - var data = videoTrack.samples; + var duration = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["getDuration"])(data, initData); + var startDTS = lastEndDTS; + var endDTS = duration + startDTS; + Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["offsetStartDTS"])(initData, data, initPTS); - if (!data || !data.length) { - return result; - } + if (duration > 0) { + this.lastEndDTS = endDTS; + } else { + _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("Duration parsed from mp4 should be greater than zero"); + this.resetNextTimestamp(); + } - var initSegment = { - initPTS: undefined, - timescale: 1 - }; - var initData = this.initData; + var hasAudio = !!initData.audio; + var hasVideo = !!initData.video; + var type = ""; - if (!initData || !initData.length) { - this.generateInitSegment(data); - initData = this.initData; - } + if (hasAudio) { + type += "audio"; + } - if (!initData || !initData.length) { - // We can't remux if the initSegment could not be generated - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('[passthrough-remuxer.ts]: Failed to generate initSegment.'); - return result; - } + if (hasVideo) { + type += "video"; + } - if (this.emitInitSegment) { - initSegment.tracks = this.initTracks; - this.emitInitSegment = false; - } + var track = { + data1: data, + startPTS: startDTS, + startDTS: startDTS, + endPTS: endDTS, + endDTS: endDTS, + type: type, + hasAudio: hasAudio, + hasVideo: hasVideo, + nb: 1, + dropped: 0, + }; + result.audio = track.type === "audio" ? track : undefined; + result.video = track.type !== "audio" ? track : undefined; + result.text = textTrack; + result.id3 = id3Track; + result.initSegment = initSegment; + return result; + }; - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(initPTS)) { - this.initPTS = initSegment.initPTS = initPTS = computeInitPTS(initData, data, lastEndDTS); - } + return PassThroughRemuxer; + })(); - var duration = Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["getDuration"])(data, initData); - var startDTS = lastEndDTS; - var endDTS = duration + startDTS; - Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["offsetStartDTS"])(initData, data, initPTS); + var computeInitPTS = function computeInitPTS(initData, data, timeOffset) { + return Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["getStartDTS"])(initData, data) - timeOffset; + }; - if (duration > 0) { - this.lastEndDTS = endDTS; - } else { - _utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn('Duration parsed from mp4 should be greater than zero'); - this.resetNextTimestamp(); - } + function getParsedTrackCodec(track, type) { + var parsedCodec = track === null || track === void 0 ? void 0 : track.codec; - var hasAudio = !!initData.audio; - var hasVideo = !!initData.video; - var type = ''; + if (parsedCodec && parsedCodec.length > 4) { + return parsedCodec; + } // Since mp4-tools cannot parse full codec string (see 'TODO: Parse codec details'... in mp4-tools) + // Provide defaults based on codec type + // This allows for some playback of some fmp4 playlists without CODECS defined in manifest - if (hasAudio) { - type += 'audio'; - } + if (parsedCodec === "hvc1") { + return "hvc1.1.c.L120.90"; + } - if (hasVideo) { - type += 'video'; - } + if (parsedCodec === "av01") { + return "av01.0.04M.08"; + } - var track = { - data1: data, - startPTS: startDTS, - startDTS: startDTS, - endPTS: endDTS, - endDTS: endDTS, - type: type, - hasAudio: hasAudio, - hasVideo: hasVideo, - nb: 1, - dropped: 0 - }; - result.audio = track.type === 'audio' ? track : undefined; - result.video = track.type !== 'audio' ? track : undefined; - result.text = textTrack; - result.id3 = id3Track; - result.initSegment = initSegment; - return result; - }; + if (parsedCodec === "avc1" || type === _loader_fragment__WEBPACK_IMPORTED_MODULE_2__["ElementaryStreamTypes"].VIDEO) { + return "avc1.42e01e"; + } - return PassThroughRemuxer; -}(); + return "mp4a.40.5"; + } -var computeInitPTS = function computeInitPTS(initData, data, timeOffset) { - return Object(_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__["getStartDTS"])(initData, data) - timeOffset; -}; + /* harmony default export */ __webpack_exports__["default"] = PassThroughRemuxer; -function getParsedTrackCodec(track, type) { - var parsedCodec = track === null || track === void 0 ? void 0 : track.codec; + /***/ + }, - if (parsedCodec && parsedCodec.length > 4) { - return parsedCodec; - } // Since mp4-tools cannot parse full codec string (see 'TODO: Parse codec details'... in mp4-tools) - // Provide defaults based on codec type - // This allows for some playback of some fmp4 playlists without CODECS defined in manifest - - - if (parsedCodec === 'hvc1') { - return 'hvc1.1.c.L120.90'; - } - - if (parsedCodec === 'av01') { - return 'av01.0.04M.08'; - } - - if (parsedCodec === 'avc1' || type === _loader_fragment__WEBPACK_IMPORTED_MODULE_2__["ElementaryStreamTypes"].VIDEO) { - return 'avc1.42e01e'; - } - - return 'mp4a.40.5'; -} - -/* harmony default export */ __webpack_exports__["default"] = (PassThroughRemuxer); - -/***/ }), - -/***/ "./src/task-loop.ts": -/*!**************************!*\ + /***/ "./src/task-loop.ts": + /*!**************************!*\ !*** ./src/task-loop.ts ***! \**************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return TaskLoop; + }); + /** + * Sub-class specialization of EventHandler base class. + * + * TaskLoop allows to schedule a task function being called (optionnaly repeatedly) on the main loop, + * scheduled asynchroneously, avoiding recursive calls in the same tick. + * + * The task itself is implemented in `doTick`. It can be requested and called for single execution + * using the `tick` method. + * + * It will be assured that the task execution method (`tick`) only gets called once per main loop "tick", + * no matter how often it gets requested for execution. Execution in further ticks will be scheduled accordingly. + * + * If further execution requests have already been scheduled on the next tick, it can be checked with `hasNextTick`, + * and cancelled with `clearNextTick`. + * + * The task can be scheduled as an interval repeatedly with a period as parameter (see `setInterval`, `clearInterval`). + * + * Sub-classes need to implement the `doTick` method which will effectively have the task execution routine. + * + * Further explanations: + * + * The baseclass has a `tick` method that will schedule the doTick call. It may be called synchroneously + * only for a stack-depth of one. On re-entrant calls, sub-sequent calls are scheduled for next main loop ticks. + * + * When the task execution (`tick` method) is called in re-entrant way this is detected and + * we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further + * task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo). + */ + var TaskLoop = /*#__PURE__*/ (function () { + function TaskLoop() { + this._boundTick = void 0; + this._tickTimer = null; + this._tickInterval = null; + this._tickCallCount = 0; + this._boundTick = this.tick.bind(this); + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TaskLoop; }); -/** - * Sub-class specialization of EventHandler base class. - * - * TaskLoop allows to schedule a task function being called (optionnaly repeatedly) on the main loop, - * scheduled asynchroneously, avoiding recursive calls in the same tick. - * - * The task itself is implemented in `doTick`. It can be requested and called for single execution - * using the `tick` method. - * - * It will be assured that the task execution method (`tick`) only gets called once per main loop "tick", - * no matter how often it gets requested for execution. Execution in further ticks will be scheduled accordingly. - * - * If further execution requests have already been scheduled on the next tick, it can be checked with `hasNextTick`, - * and cancelled with `clearNextTick`. - * - * The task can be scheduled as an interval repeatedly with a period as parameter (see `setInterval`, `clearInterval`). - * - * Sub-classes need to implement the `doTick` method which will effectively have the task execution routine. - * - * Further explanations: - * - * The baseclass has a `tick` method that will schedule the doTick call. It may be called synchroneously - * only for a stack-depth of one. On re-entrant calls, sub-sequent calls are scheduled for next main loop ticks. - * - * When the task execution (`tick` method) is called in re-entrant way this is detected and - * we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further - * task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo). - */ -var TaskLoop = /*#__PURE__*/function () { - function TaskLoop() { - this._boundTick = void 0; - this._tickTimer = null; - this._tickInterval = null; - this._tickCallCount = 0; - this._boundTick = this.tick.bind(this); - } + var _proto = TaskLoop.prototype; - var _proto = TaskLoop.prototype; + _proto.destroy = function destroy() { + this.onHandlerDestroying(); + this.onHandlerDestroyed(); + }; - _proto.destroy = function destroy() { - this.onHandlerDestroying(); - this.onHandlerDestroyed(); - }; + _proto.onHandlerDestroying = function onHandlerDestroying() { + // clear all timers before unregistering from event bus + this.clearNextTick(); + this.clearInterval(); + }; - _proto.onHandlerDestroying = function onHandlerDestroying() { - // clear all timers before unregistering from event bus - this.clearNextTick(); - this.clearInterval(); - }; + _proto.onHandlerDestroyed = function onHandlerDestroyed() {}; + /** + * @returns {boolean} + */ - _proto.onHandlerDestroyed = function onHandlerDestroyed() {} - /** - * @returns {boolean} - */ - ; + _proto.hasInterval = function hasInterval() { + return !!this._tickInterval; + }; + /** + * @returns {boolean} + */ - _proto.hasInterval = function hasInterval() { - return !!this._tickInterval; - } - /** - * @returns {boolean} - */ - ; + _proto.hasNextTick = function hasNextTick() { + return !!this._tickTimer; + }; + /** + * @param {number} millis Interval time (ms) + * @returns {boolean} True when interval has been scheduled, false when already scheduled (no effect) + */ - _proto.hasNextTick = function hasNextTick() { - return !!this._tickTimer; - } - /** - * @param {number} millis Interval time (ms) - * @returns {boolean} True when interval has been scheduled, false when already scheduled (no effect) - */ - ; + _proto.setInterval = function setInterval(millis) { + if (!this._tickInterval) { + this._tickInterval = self.setInterval(this._boundTick, millis); + return true; + } - _proto.setInterval = function setInterval(millis) { - if (!this._tickInterval) { - this._tickInterval = self.setInterval(this._boundTick, millis); - return true; - } + return false; + }; + /** + * @returns {boolean} True when interval was cleared, false when none was set (no effect) + */ - return false; - } - /** - * @returns {boolean} True when interval was cleared, false when none was set (no effect) - */ - ; + _proto.clearInterval = function clearInterval() { + if (this._tickInterval) { + self.clearInterval(this._tickInterval); + this._tickInterval = null; + return true; + } - _proto.clearInterval = function clearInterval() { - if (this._tickInterval) { - self.clearInterval(this._tickInterval); - this._tickInterval = null; - return true; - } + return false; + }; + /** + * @returns {boolean} True when timeout was cleared, false when none was set (no effect) + */ - return false; - } - /** - * @returns {boolean} True when timeout was cleared, false when none was set (no effect) - */ - ; + _proto.clearNextTick = function clearNextTick() { + if (this._tickTimer) { + self.clearTimeout(this._tickTimer); + this._tickTimer = null; + return true; + } - _proto.clearNextTick = function clearNextTick() { - if (this._tickTimer) { - self.clearTimeout(this._tickTimer); - this._tickTimer = null; - return true; - } + return false; + }; + /** + * Will call the subclass doTick implementation in this main loop tick + * or in the next one (via setTimeout(,0)) in case it has already been called + * in this tick (in case this is a re-entrant call). + */ - return false; - } - /** - * Will call the subclass doTick implementation in this main loop tick - * or in the next one (via setTimeout(,0)) in case it has already been called - * in this tick (in case this is a re-entrant call). - */ - ; + _proto.tick = function tick() { + this._tickCallCount++; - _proto.tick = function tick() { - this._tickCallCount++; + if (this._tickCallCount === 1) { + this.doTick(); // re-entrant call to tick from previous doTick call stack + // -> schedule a call on the next main loop iteration to process this task processing request - if (this._tickCallCount === 1) { - this.doTick(); // re-entrant call to tick from previous doTick call stack - // -> schedule a call on the next main loop iteration to process this task processing request + if (this._tickCallCount > 1) { + // make sure only one timer exists at any time at max + this.tickImmediate(); + } - if (this._tickCallCount > 1) { - // make sure only one timer exists at any time at max - this.tickImmediate(); - } + this._tickCallCount = 0; + } + }; - this._tickCallCount = 0; - } - }; + _proto.tickImmediate = function tickImmediate() { + this.clearNextTick(); + this._tickTimer = self.setTimeout(this._boundTick, 0); + }; + /** + * For subclass to implement task logic + * @abstract + */ - _proto.tickImmediate = function tickImmediate() { - this.clearNextTick(); - this._tickTimer = self.setTimeout(this._boundTick, 0); - } - /** - * For subclass to implement task logic - * @abstract - */ - ; + _proto.doTick = function doTick() {}; - _proto.doTick = function doTick() {}; + return TaskLoop; + })(); - return TaskLoop; -}(); + /***/ + }, - - -/***/ }), - -/***/ "./src/types/cmcd.ts": -/*!***************************!*\ + /***/ "./src/types/cmcd.ts": + /*!***************************!*\ !*** ./src/types/cmcd.ts ***! \***************************/ -/*! exports provided: CMCDVersion, CMCDObjectType, CMCDStreamingFormat, CMCDStreamType */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: CMCDVersion, CMCDObjectType, CMCDStreamingFormat, CMCDStreamType */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDVersion", function () { + return CMCDVersion; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDObjectType", function () { + return CMCDObjectType; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDStreamingFormat", function () { + return CMCDStreamingFormat; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDStreamType", function () { + return CMCDStreamType; + }); + /** + * CMCD spec version + */ + var CMCDVersion = 1; + /** + * CMCD Object Type + */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDVersion", function() { return CMCDVersion; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDObjectType", function() { return CMCDObjectType; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDStreamingFormat", function() { return CMCDStreamingFormat; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CMCDStreamType", function() { return CMCDStreamType; }); -/** - * CMCD spec version - */ -var CMCDVersion = 1; -/** - * CMCD Object Type - */ + var CMCDObjectType; + /** + * CMCD Streaming Format + */ -var CMCDObjectType; -/** - * CMCD Streaming Format - */ + (function (CMCDObjectType) { + CMCDObjectType["MANIFEST"] = "m"; + CMCDObjectType["AUDIO"] = "a"; + CMCDObjectType["VIDEO"] = "v"; + CMCDObjectType["MUXED"] = "av"; + CMCDObjectType["INIT"] = "i"; + CMCDObjectType["CAPTION"] = "c"; + CMCDObjectType["TIMED_TEXT"] = "tt"; + CMCDObjectType["KEY"] = "k"; + CMCDObjectType["OTHER"] = "o"; + })(CMCDObjectType || (CMCDObjectType = {})); -(function (CMCDObjectType) { - CMCDObjectType["MANIFEST"] = "m"; - CMCDObjectType["AUDIO"] = "a"; - CMCDObjectType["VIDEO"] = "v"; - CMCDObjectType["MUXED"] = "av"; - CMCDObjectType["INIT"] = "i"; - CMCDObjectType["CAPTION"] = "c"; - CMCDObjectType["TIMED_TEXT"] = "tt"; - CMCDObjectType["KEY"] = "k"; - CMCDObjectType["OTHER"] = "o"; -})(CMCDObjectType || (CMCDObjectType = {})); + var CMCDStreamingFormat; + /** + * CMCD Streaming Type + */ -var CMCDStreamingFormat; -/** - * CMCD Streaming Type - */ + (function (CMCDStreamingFormat) { + CMCDStreamingFormat["DASH"] = "d"; + CMCDStreamingFormat["CiderHls"] = "h"; + CMCDStreamingFormat["SMOOTH"] = "s"; + CMCDStreamingFormat["OTHER"] = "o"; + })(CMCDStreamingFormat || (CMCDStreamingFormat = {})); -(function (CMCDStreamingFormat) { - CMCDStreamingFormat["DASH"] = "d"; - CMCDStreamingFormat["CiderHls"] = "h"; - CMCDStreamingFormat["SMOOTH"] = "s"; - CMCDStreamingFormat["OTHER"] = "o"; -})(CMCDStreamingFormat || (CMCDStreamingFormat = {})); + var CMCDStreamType; + /** + * CMCD Headers + */ -var CMCDStreamType; -/** - * CMCD Headers - */ + (function (CMCDStreamType) { + CMCDStreamType["VOD"] = "v"; + CMCDStreamType["LIVE"] = "l"; + })(CMCDStreamType || (CMCDStreamType = {})); -(function (CMCDStreamType) { - CMCDStreamType["VOD"] = "v"; - CMCDStreamType["LIVE"] = "l"; -})(CMCDStreamType || (CMCDStreamType = {})); + /***/ + }, -/***/ }), - -/***/ "./src/types/level.ts": -/*!****************************!*\ + /***/ "./src/types/level.ts": + /*!****************************!*\ !*** ./src/types/level.ts ***! \****************************/ -/*! exports provided: CiderHlsSkip, getSkipValue, CiderHlsUrlParameters, Level */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: CiderHlsSkip, getSkipValue, CiderHlsUrlParameters, Level */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CiderHlsSkip", function () { + return CiderHlsSkip; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSkipValue", function () { + return getSkipValue; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CiderHlsUrlParameters", function () { + return CiderHlsUrlParameters; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Level", function () { + return Level; + }); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CiderHlsSkip", function() { return CiderHlsSkip; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSkipValue", function() { return getSkipValue; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CiderHlsUrlParameters", function() { return CiderHlsUrlParameters; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Level", function() { return Level; }); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + var CiderHlsSkip; -var CiderHlsSkip; + (function (CiderHlsSkip) { + CiderHlsSkip["No"] = ""; + CiderHlsSkip["Yes"] = "YES"; + CiderHlsSkip["v2"] = "v2"; + })(CiderHlsSkip || (CiderHlsSkip = {})); -(function (CiderHlsSkip) { - CiderHlsSkip["No"] = ""; - CiderHlsSkip["Yes"] = "YES"; - CiderHlsSkip["v2"] = "v2"; -})(CiderHlsSkip || (CiderHlsSkip = {})); + function getSkipValue(details, msn) { + var canSkipUntil = details.canSkipUntil, + canSkipDateRanges = details.canSkipDateRanges, + endSN = details.endSN; + var snChangeGoal = msn !== undefined ? msn - endSN : 0; -function getSkipValue(details, msn) { - var canSkipUntil = details.canSkipUntil, - canSkipDateRanges = details.canSkipDateRanges, - endSN = details.endSN; - var snChangeGoal = msn !== undefined ? msn - endSN : 0; + if (canSkipUntil && snChangeGoal < canSkipUntil) { + if (canSkipDateRanges) { + return CiderHlsSkip.v2; + } - if (canSkipUntil && snChangeGoal < canSkipUntil) { - if (canSkipDateRanges) { - return CiderHlsSkip.v2; - } + return CiderHlsSkip.Yes; + } - return CiderHlsSkip.Yes; - } + return CiderHlsSkip.No; + } + var CiderHlsUrlParameters = /*#__PURE__*/ (function () { + function CiderHlsUrlParameters(msn, part, skip) { + this.msn = void 0; + this.part = void 0; + this.skip = void 0; + this.msn = msn; + this.part = part; + this.skip = skip; + } - return CiderHlsSkip.No; -} -var CiderHlsUrlParameters = /*#__PURE__*/function () { - function CiderHlsUrlParameters(msn, part, skip) { - this.msn = void 0; - this.part = void 0; - this.skip = void 0; - this.msn = msn; - this.part = part; - this.skip = skip; - } + var _proto = CiderHlsUrlParameters.prototype; - var _proto = CiderHlsUrlParameters.prototype; + _proto.addDirectives = function addDirectives(uri) { + var url = new self.URL(uri); - _proto.addDirectives = function addDirectives(uri) { - var url = new self.URL(uri); + if (this.msn !== undefined) { + url.searchParams.set("_CiderHls_msn", this.msn.toString()); + } - if (this.msn !== undefined) { - url.searchParams.set('_CiderHls_msn', this.msn.toString()); - } + if (this.part !== undefined) { + url.searchParams.set("_CiderHls_part", this.part.toString()); + } - if (this.part !== undefined) { - url.searchParams.set('_CiderHls_part', this.part.toString()); - } + if (this.skip) { + url.searchParams.set("_CiderHls_skip", this.skip); + } - if (this.skip) { - url.searchParams.set('_CiderHls_skip', this.skip); - } + return url.toString(); + }; - return url.toString(); - }; + return CiderHlsUrlParameters; + })(); + var Level = /*#__PURE__*/ (function () { + function Level(data) { + this.attrs = void 0; + this.audioCodec = void 0; + this.bitrate = void 0; + this.codecSet = void 0; + this.height = void 0; + this.id = void 0; + this.name = void 0; + this.videoCodec = void 0; + this.width = void 0; + this.unknownCodecs = void 0; + this.audioGroupIds = void 0; + this.details = void 0; + this.fragmentError = 0; + this.loadError = 0; + this.loaded = void 0; + this.realBitrate = 0; + this.textGroupIds = void 0; + this.url = void 0; + this._urlId = 0; + this.url = [data.url]; + this.attrs = data.attrs; + this.bitrate = data.bitrate; - return CiderHlsUrlParameters; -}(); -var Level = /*#__PURE__*/function () { - function Level(data) { - this.attrs = void 0; - this.audioCodec = void 0; - this.bitrate = void 0; - this.codecSet = void 0; - this.height = void 0; - this.id = void 0; - this.name = void 0; - this.videoCodec = void 0; - this.width = void 0; - this.unknownCodecs = void 0; - this.audioGroupIds = void 0; - this.details = void 0; - this.fragmentError = 0; - this.loadError = 0; - this.loaded = void 0; - this.realBitrate = 0; - this.textGroupIds = void 0; - this.url = void 0; - this._urlId = 0; - this.url = [data.url]; - this.attrs = data.attrs; - this.bitrate = data.bitrate; + if (data.details) { + this.details = data.details; + } - if (data.details) { - this.details = data.details; - } + this.id = data.id || 0; + this.name = data.name; + this.width = data.width || 0; + this.height = data.height || 0; + this.audioCodec = data.audioCodec; + this.videoCodec = data.videoCodec; + this.unknownCodecs = data.unknownCodecs; + this.codecSet = [data.videoCodec, data.audioCodec] + .filter(function (c) { + return c; + }) + .join(",") + .replace(/\.[^.,]+/g, ""); + } - this.id = data.id || 0; - this.name = data.name; - this.width = data.width || 0; - this.height = data.height || 0; - this.audioCodec = data.audioCodec; - this.videoCodec = data.videoCodec; - this.unknownCodecs = data.unknownCodecs; - this.codecSet = [data.videoCodec, data.audioCodec].filter(function (c) { - return c; - }).join(',').replace(/\.[^.,]+/g, ''); - } + _createClass(Level, [ + { + key: "maxBitrate", + get: function get() { + return Math.max(this.realBitrate, this.bitrate); + }, + }, + { + key: "uri", + get: function get() { + return this.url[this._urlId] || ""; + }, + }, + { + key: "urlId", + get: function get() { + return this._urlId; + }, + set: function set(value) { + var newValue = value % this.url.length; - _createClass(Level, [{ - key: "maxBitrate", - get: function get() { - return Math.max(this.realBitrate, this.bitrate); - } - }, { - key: "uri", - get: function get() { - return this.url[this._urlId] || ''; - } - }, { - key: "urlId", - get: function get() { - return this._urlId; - }, - set: function set(value) { - var newValue = value % this.url.length; + if (this._urlId !== newValue) { + this.details = undefined; + this._urlId = newValue; + } + }, + }, + ]); - if (this._urlId !== newValue) { - this.details = undefined; - this._urlId = newValue; - } - } - }]); + return Level; + })(); - return Level; -}(); + /***/ + }, -/***/ }), - -/***/ "./src/types/loader.ts": -/*!*****************************!*\ + /***/ "./src/types/loader.ts": + /*!*****************************!*\ !*** ./src/types/loader.ts ***! \*****************************/ -/*! exports provided: PlaylistContextType, PlaylistLevelType */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: PlaylistContextType, PlaylistLevelType */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaylistContextType", function () { + return PlaylistContextType; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaylistLevelType", function () { + return PlaylistLevelType; + }); + var PlaylistContextType; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaylistContextType", function() { return PlaylistContextType; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaylistLevelType", function() { return PlaylistLevelType; }); -var PlaylistContextType; + (function (PlaylistContextType) { + PlaylistContextType["MANIFEST"] = "manifest"; + PlaylistContextType["LEVEL"] = "level"; + PlaylistContextType["AUDIO_TRACK"] = "audioTrack"; + PlaylistContextType["SUBTITLE_TRACK"] = "subtitleTrack"; + })(PlaylistContextType || (PlaylistContextType = {})); -(function (PlaylistContextType) { - PlaylistContextType["MANIFEST"] = "manifest"; - PlaylistContextType["LEVEL"] = "level"; - PlaylistContextType["AUDIO_TRACK"] = "audioTrack"; - PlaylistContextType["SUBTITLE_TRACK"] = "subtitleTrack"; -})(PlaylistContextType || (PlaylistContextType = {})); + var PlaylistLevelType; -var PlaylistLevelType; + (function (PlaylistLevelType) { + PlaylistLevelType["MAIN"] = "main"; + PlaylistLevelType["AUDIO"] = "audio"; + PlaylistLevelType["SUBTITLE"] = "subtitle"; + })(PlaylistLevelType || (PlaylistLevelType = {})); -(function (PlaylistLevelType) { - PlaylistLevelType["MAIN"] = "main"; - PlaylistLevelType["AUDIO"] = "audio"; - PlaylistLevelType["SUBTITLE"] = "subtitle"; -})(PlaylistLevelType || (PlaylistLevelType = {})); + /***/ + }, -/***/ }), - -/***/ "./src/types/transmuxer.ts": -/*!*********************************!*\ + /***/ "./src/types/transmuxer.ts": + /*!*********************************!*\ !*** ./src/types/transmuxer.ts ***! \*********************************/ -/*! exports provided: ChunkMetadata */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: ChunkMetadata */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ChunkMetadata", function () { + return ChunkMetadata; + }); + var ChunkMetadata = function ChunkMetadata(level, sn, id, size, part, partial) { + if (size === void 0) { + size = 0; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ChunkMetadata", function() { return ChunkMetadata; }); -var ChunkMetadata = function ChunkMetadata(level, sn, id, size, part, partial) { - if (size === void 0) { - size = 0; - } + if (part === void 0) { + part = -1; + } - if (part === void 0) { - part = -1; - } + if (partial === void 0) { + partial = false; + } - if (partial === void 0) { - partial = false; - } + this.level = void 0; + this.sn = void 0; + this.part = void 0; + this.id = void 0; + this.size = void 0; + this.partial = void 0; + this.transmuxing = getNewPerformanceTiming(); + this.buffering = { + audio: getNewPerformanceTiming(), + video: getNewPerformanceTiming(), + audiovideo: getNewPerformanceTiming(), + }; + this.level = level; + this.sn = sn; + this.id = id; + this.size = size; + this.part = part; + this.partial = partial; + }; - this.level = void 0; - this.sn = void 0; - this.part = void 0; - this.id = void 0; - this.size = void 0; - this.partial = void 0; - this.transmuxing = getNewPerformanceTiming(); - this.buffering = { - audio: getNewPerformanceTiming(), - video: getNewPerformanceTiming(), - audiovideo: getNewPerformanceTiming() - }; - this.level = level; - this.sn = sn; - this.id = id; - this.size = size; - this.part = part; - this.partial = partial; -}; + function getNewPerformanceTiming() { + return { + start: 0, + executeStart: 0, + executeEnd: 0, + end: 0, + }; + } -function getNewPerformanceTiming() { - return { - start: 0, - executeStart: 0, - executeEnd: 0, - end: 0 - }; -} + /***/ + }, -/***/ }), - -/***/ "./src/utils/attr-list.ts": -/*!********************************!*\ + /***/ "./src/utils/attr-list.ts": + /*!********************************!*\ !*** ./src/utils/attr-list.ts ***! \********************************/ -/*! exports provided: AttrList */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: AttrList */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttrList", function () { + return AttrList; + }); + var DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/; // eslint-disable-line no-useless-escape -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttrList", function() { return AttrList; }); -var DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/; // eslint-disable-line no-useless-escape + var ATTR_LIST_REGEX = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; // eslint-disable-line no-useless-escape + // adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js -var ATTR_LIST_REGEX = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; // eslint-disable-line no-useless-escape -// adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js + var AttrList = /*#__PURE__*/ (function () { + function AttrList(attrs) { + if (typeof attrs === "string") { + attrs = AttrList.parseAttrList(attrs); + } -var AttrList = /*#__PURE__*/function () { - function AttrList(attrs) { - if (typeof attrs === 'string') { - attrs = AttrList.parseAttrList(attrs); - } + for (var attr in attrs) { + if (attrs.hasOwnProperty(attr)) { + this[attr] = attrs[attr]; + } + } + } - for (var attr in attrs) { - if (attrs.hasOwnProperty(attr)) { - this[attr] = attrs[attr]; - } - } - } + var _proto = AttrList.prototype; - var _proto = AttrList.prototype; + _proto.decimalInteger = function decimalInteger(attrName) { + var intValue = parseInt(this[attrName], 10); - _proto.decimalInteger = function decimalInteger(attrName) { - var intValue = parseInt(this[attrName], 10); + if (intValue > Number.MAX_SAFE_INTEGER) { + return Infinity; + } - if (intValue > Number.MAX_SAFE_INTEGER) { - return Infinity; - } + return intValue; + }; - return intValue; - }; + _proto.hexadecimalInteger = function hexadecimalInteger(attrName) { + if (this[attrName]) { + var stringValue = (this[attrName] || "0x").slice(2); + stringValue = (stringValue.length & 1 ? "0" : "") + stringValue; + var value = new Uint8Array(stringValue.length / 2); - _proto.hexadecimalInteger = function hexadecimalInteger(attrName) { - if (this[attrName]) { - var stringValue = (this[attrName] || '0x').slice(2); - stringValue = (stringValue.length & 1 ? '0' : '') + stringValue; - var value = new Uint8Array(stringValue.length / 2); + for (var i = 0; i < stringValue.length / 2; i++) { + value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16); + } - for (var i = 0; i < stringValue.length / 2; i++) { - value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16); - } + return value; + } else { + return null; + } + }; - return value; - } else { - return null; - } - }; + _proto.hexadecimalIntegerAsNumber = function hexadecimalIntegerAsNumber(attrName) { + var intValue = parseInt(this[attrName], 16); - _proto.hexadecimalIntegerAsNumber = function hexadecimalIntegerAsNumber(attrName) { - var intValue = parseInt(this[attrName], 16); + if (intValue > Number.MAX_SAFE_INTEGER) { + return Infinity; + } - if (intValue > Number.MAX_SAFE_INTEGER) { - return Infinity; - } + return intValue; + }; - return intValue; - }; + _proto.decimalFloatingPoint = function decimalFloatingPoint(attrName) { + return parseFloat(this[attrName]); + }; - _proto.decimalFloatingPoint = function decimalFloatingPoint(attrName) { - return parseFloat(this[attrName]); - }; + _proto.optionalFloat = function optionalFloat(attrName, defaultValue) { + var value = this[attrName]; + return value ? parseFloat(value) : defaultValue; + }; - _proto.optionalFloat = function optionalFloat(attrName, defaultValue) { - var value = this[attrName]; - return value ? parseFloat(value) : defaultValue; - }; + _proto.enumeratedString = function enumeratedString(attrName) { + return this[attrName]; + }; - _proto.enumeratedString = function enumeratedString(attrName) { - return this[attrName]; - }; + _proto.bool = function bool(attrName) { + return this[attrName] === "YES"; + }; - _proto.bool = function bool(attrName) { - return this[attrName] === 'YES'; - }; + _proto.decimalResolution = function decimalResolution(attrName) { + var res = DECIMAL_RESOLUTION_REGEX.exec(this[attrName]); - _proto.decimalResolution = function decimalResolution(attrName) { - var res = DECIMAL_RESOLUTION_REGEX.exec(this[attrName]); + if (res === null) { + return undefined; + } - if (res === null) { - return undefined; - } + return { + width: parseInt(res[1], 10), + height: parseInt(res[2], 10), + }; + }; - return { - width: parseInt(res[1], 10), - height: parseInt(res[2], 10) - }; - }; + AttrList.parseAttrList = function parseAttrList(input) { + var match; + var attrs = {}; + var quote = '"'; + ATTR_LIST_REGEX.lastIndex = 0; - AttrList.parseAttrList = function parseAttrList(input) { - var match; - var attrs = {}; - var quote = '"'; - ATTR_LIST_REGEX.lastIndex = 0; + while ((match = ATTR_LIST_REGEX.exec(input)) !== null) { + var value = match[2]; - while ((match = ATTR_LIST_REGEX.exec(input)) !== null) { - var value = match[2]; + if (value.indexOf(quote) === 0 && value.lastIndexOf(quote) === value.length - 1) { + value = value.slice(1, -1); + } - if (value.indexOf(quote) === 0 && value.lastIndexOf(quote) === value.length - 1) { - value = value.slice(1, -1); - } + attrs[match[1]] = value; + } - attrs[match[1]] = value; - } + return attrs; + }; - return attrs; - }; + return AttrList; + })(); - return AttrList; -}(); + /***/ + }, -/***/ }), - -/***/ "./src/utils/binary-search.ts": -/*!************************************!*\ + /***/ "./src/utils/binary-search.ts": + /*!************************************!*\ !*** ./src/utils/binary-search.ts ***! \************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + var BinarySearch = { + /** + * Searches for an item in an array which matches a certain condition. + * This requires the condition to only match one item in the array, + * and for the array to be ordered. + * + * @param {Array<T>} list The array to search. + * @param {BinarySearchComparison<T>} comparisonFn + * Called and provided a candidate item as the first argument. + * Should return: + * > -1 if the item should be located at a lower index than the provided item. + * > 1 if the item should be located at a higher index than the provided item. + * > 0 if the item is the item you're looking for. + * + * @return {T | null} The object if it is found or null otherwise. + */ + search: function search(list, comparisonFn) { + var minIndex = 0; + var maxIndex = list.length - 1; + var currentIndex = null; + var currentElement = null; -"use strict"; -__webpack_require__.r(__webpack_exports__); -var BinarySearch = { - /** - * Searches for an item in an array which matches a certain condition. - * This requires the condition to only match one item in the array, - * and for the array to be ordered. - * - * @param {Array<T>} list The array to search. - * @param {BinarySearchComparison<T>} comparisonFn - * Called and provided a candidate item as the first argument. - * Should return: - * > -1 if the item should be located at a lower index than the provided item. - * > 1 if the item should be located at a higher index than the provided item. - * > 0 if the item is the item you're looking for. - * - * @return {T | null} The object if it is found or null otherwise. - */ - search: function search(list, comparisonFn) { - var minIndex = 0; - var maxIndex = list.length - 1; - var currentIndex = null; - var currentElement = null; + while (minIndex <= maxIndex) { + currentIndex = ((minIndex + maxIndex) / 2) | 0; + currentElement = list[currentIndex]; + var comparisonResult = comparisonFn(currentElement); - while (minIndex <= maxIndex) { - currentIndex = (minIndex + maxIndex) / 2 | 0; - currentElement = list[currentIndex]; - var comparisonResult = comparisonFn(currentElement); + if (comparisonResult > 0) { + minIndex = currentIndex + 1; + } else if (comparisonResult < 0) { + maxIndex = currentIndex - 1; + } else { + return currentElement; + } + } - if (comparisonResult > 0) { - minIndex = currentIndex + 1; - } else if (comparisonResult < 0) { - maxIndex = currentIndex - 1; - } else { - return currentElement; - } - } + return null; + }, + }; + /* harmony default export */ __webpack_exports__["default"] = BinarySearch; - return null; - } -}; -/* harmony default export */ __webpack_exports__["default"] = (BinarySearch); + /***/ + }, -/***/ }), - -/***/ "./src/utils/buffer-helper.ts": -/*!************************************!*\ + /***/ "./src/utils/buffer-helper.ts": + /*!************************************!*\ !*** ./src/utils/buffer-helper.ts ***! \************************************/ -/*! exports provided: BufferHelper */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: BufferHelper */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BufferHelper", function () { + return BufferHelper; + }); + /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts"); + /** + * @module BufferHelper + * + * Providing methods dealing with buffer length retrieval for example. + * + * In general, a helper around HTML5 MediaElement TimeRanges gathered from `buffered` property. + * + * Also @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered + */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BufferHelper", function() { return BufferHelper; }); -/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts"); -/** - * @module BufferHelper - * - * Providing methods dealing with buffer length retrieval for example. - * - * In general, a helper around HTML5 MediaElement TimeRanges gathered from `buffered` property. - * - * Also @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered - */ + var noopBuffered = { + length: 0, + start: function start() { + return 0; + }, + end: function end() { + return 0; + }, + }; + var BufferHelper = /*#__PURE__*/ (function () { + function BufferHelper() {} -var noopBuffered = { - length: 0, - start: function start() { - return 0; - }, - end: function end() { - return 0; - } -}; -var BufferHelper = /*#__PURE__*/function () { - function BufferHelper() {} + /** + * Return true if `media`'s buffered include `position` + * @param {Bufferable} media + * @param {number} position + * @returns {boolean} + */ + BufferHelper.isBuffered = function isBuffered(media, position) { + try { + if (media) { + var buffered = BufferHelper.getBuffered(media); - /** - * Return true if `media`'s buffered include `position` - * @param {Bufferable} media - * @param {number} position - * @returns {boolean} - */ - BufferHelper.isBuffered = function isBuffered(media, position) { - try { - if (media) { - var buffered = BufferHelper.getBuffered(media); + for (var i = 0; i < buffered.length; i++) { + if (position >= buffered.start(i) && position <= buffered.end(i)) { + return true; + } + } + } + } catch (error) { + // this is to catch + // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer': + // This SourceBuffer has been removed from the parent media source + } - for (var i = 0; i < buffered.length; i++) { - if (position >= buffered.start(i) && position <= buffered.end(i)) { - return true; - } - } - } - } catch (error) {// this is to catch - // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer': - // This SourceBuffer has been removed from the parent media source - } + return false; + }; - return false; - }; + BufferHelper.bufferInfo = function bufferInfo(media, pos, maxHoleDuration) { + try { + if (media) { + var vbuffered = BufferHelper.getBuffered(media); + var buffered = []; + var i; - BufferHelper.bufferInfo = function bufferInfo(media, pos, maxHoleDuration) { - try { - if (media) { - var vbuffered = BufferHelper.getBuffered(media); - var buffered = []; - var i; + for (i = 0; i < vbuffered.length; i++) { + buffered.push({ + start: vbuffered.start(i), + end: vbuffered.end(i), + }); + } - for (i = 0; i < vbuffered.length; i++) { - buffered.push({ - start: vbuffered.start(i), - end: vbuffered.end(i) - }); - } + return this.bufferedInfo(buffered, pos, maxHoleDuration); + } + } catch (error) { + // this is to catch + // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer': + // This SourceBuffer has been removed from the parent media source + } - return this.bufferedInfo(buffered, pos, maxHoleDuration); - } - } catch (error) {// this is to catch - // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer': - // This SourceBuffer has been removed from the parent media source - } + return { + len: 0, + start: pos, + end: pos, + nextStart: undefined, + }; + }; - return { - len: 0, - start: pos, - end: pos, - nextStart: undefined - }; - }; + BufferHelper.bufferedInfo = function bufferedInfo(buffered, pos, maxHoleDuration) { + pos = Math.max(0, pos); // sort on buffer.start/smaller end (IE does not always return sorted buffered range) - BufferHelper.bufferedInfo = function bufferedInfo(buffered, pos, maxHoleDuration) { - pos = Math.max(0, pos); // sort on buffer.start/smaller end (IE does not always return sorted buffered range) + buffered.sort(function (a, b) { + var diff = a.start - b.start; - buffered.sort(function (a, b) { - var diff = a.start - b.start; + if (diff) { + return diff; + } else { + return b.end - a.end; + } + }); + var buffered2 = []; - if (diff) { - return diff; - } else { - return b.end - a.end; - } - }); - var buffered2 = []; + if (maxHoleDuration) { + // there might be some small holes between buffer time range + // consider that holes smaller than maxHoleDuration are irrelevant and build another + // buffer time range representations that discards those holes + for (var i = 0; i < buffered.length; i++) { + var buf2len = buffered2.length; - if (maxHoleDuration) { - // there might be some small holes between buffer time range - // consider that holes smaller than maxHoleDuration are irrelevant and build another - // buffer time range representations that discards those holes - for (var i = 0; i < buffered.length; i++) { - var buf2len = buffered2.length; + if (buf2len) { + var buf2end = buffered2[buf2len - 1].end; // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative) - if (buf2len) { - var buf2end = buffered2[buf2len - 1].end; // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative) + if (buffered[i].start - buf2end < maxHoleDuration) { + // merge overlapping time ranges + // update lastRange.end only if smaller than item.end + // e.g. [ 1, 15] with [ 2,8] => [ 1,15] (no need to modify lastRange.end) + // whereas [ 1, 8] with [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15]) + if (buffered[i].end > buf2end) { + buffered2[buf2len - 1].end = buffered[i].end; + } + } else { + // big hole + buffered2.push(buffered[i]); + } + } else { + // first value + buffered2.push(buffered[i]); + } + } + } else { + buffered2 = buffered; + } - if (buffered[i].start - buf2end < maxHoleDuration) { - // merge overlapping time ranges - // update lastRange.end only if smaller than item.end - // e.g. [ 1, 15] with [ 2,8] => [ 1,15] (no need to modify lastRange.end) - // whereas [ 1, 8] with [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15]) - if (buffered[i].end > buf2end) { - buffered2[buf2len - 1].end = buffered[i].end; - } - } else { - // big hole - buffered2.push(buffered[i]); - } - } else { - // first value - buffered2.push(buffered[i]); - } - } - } else { - buffered2 = buffered; - } + var bufferLen = 0; // bufferStartNext can possibly be undefined based on the conditional logic below - var bufferLen = 0; // bufferStartNext can possibly be undefined based on the conditional logic below + var bufferStartNext; // bufferStart and bufferEnd are buffer boundaries around current video position - var bufferStartNext; // bufferStart and bufferEnd are buffer boundaries around current video position + var bufferStart = pos; + var bufferEnd = pos; - var bufferStart = pos; - var bufferEnd = pos; + for (var _i = 0; _i < buffered2.length; _i++) { + var start = buffered2[_i].start; + var end = buffered2[_i].end; // logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i)); - for (var _i = 0; _i < buffered2.length; _i++) { - var start = buffered2[_i].start; - var end = buffered2[_i].end; // logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i)); + if (pos + maxHoleDuration >= start && pos < end) { + // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length + bufferStart = start; + bufferEnd = end; + bufferLen = bufferEnd - pos; + } else if (pos + maxHoleDuration < start) { + bufferStartNext = start; + break; + } + } - if (pos + maxHoleDuration >= start && pos < end) { - // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length - bufferStart = start; - bufferEnd = end; - bufferLen = bufferEnd - pos; - } else if (pos + maxHoleDuration < start) { - bufferStartNext = start; - break; - } - } + return { + len: bufferLen, + start: bufferStart || 0, + end: bufferEnd || 0, + nextStart: bufferStartNext, + }; + }; + /** + * Safe method to get buffered property. + * SourceBuffer.buffered may throw if SourceBuffer is removed from it's MediaSource + */ - return { - len: bufferLen, - start: bufferStart || 0, - end: bufferEnd || 0, - nextStart: bufferStartNext - }; - } - /** - * Safe method to get buffered property. - * SourceBuffer.buffered may throw if SourceBuffer is removed from it's MediaSource - */ - ; + BufferHelper.getBuffered = function getBuffered(media) { + try { + return media.buffered; + } catch (e) { + _logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log("failed to get media.buffered", e); + return noopBuffered; + } + }; - BufferHelper.getBuffered = function getBuffered(media) { - try { - return media.buffered; - } catch (e) { - _logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log('failed to get media.buffered', e); - return noopBuffered; - } - }; + return BufferHelper; + })(); - return BufferHelper; -}(); + /***/ + }, -/***/ }), - -/***/ "./src/utils/cea-608-parser.ts": -/*!*************************************!*\ + /***/ "./src/utils/cea-608-parser.ts": + /*!*************************************!*\ !*** ./src/utils/cea-608-parser.ts ***! \*************************************/ -/*! exports provided: Row, CaptionScreen, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Row", function() { return Row; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CaptionScreen", function() { return CaptionScreen; }); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); - -/** - * - * This code was ported from the dash.js project at: - * https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js - * https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2 - * - * The original copyright appears below: - * - * The copyright in this software is being made available under the BSD License, - * included below. This software may be subject to other third party and contributor - * rights, including patent rights, and no such rights are granted under this license. - * - * Copyright (c) 2015-2016, DASH Industry Forum. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * 2. Neither the name of Dash Industry Forum nor the names of its - * contributors may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes - */ - -var specialCea608CharsCodes = { - 0x2a: 0xe1, - // lowercase a, acute accent - 0x5c: 0xe9, - // lowercase e, acute accent - 0x5e: 0xed, - // lowercase i, acute accent - 0x5f: 0xf3, - // lowercase o, acute accent - 0x60: 0xfa, - // lowercase u, acute accent - 0x7b: 0xe7, - // lowercase c with cedilla - 0x7c: 0xf7, - // division symbol - 0x7d: 0xd1, - // uppercase N tilde - 0x7e: 0xf1, - // lowercase n tilde - 0x7f: 0x2588, - // Full block - // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS - // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F - // THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES - 0x80: 0xae, - // Registered symbol (R) - 0x81: 0xb0, - // degree sign - 0x82: 0xbd, - // 1/2 symbol - 0x83: 0xbf, - // Inverted (open) question mark - 0x84: 0x2122, - // Trademark symbol (TM) - 0x85: 0xa2, - // Cents symbol - 0x86: 0xa3, - // Pounds sterling - 0x87: 0x266a, - // Music 8'th note - 0x88: 0xe0, - // lowercase a, grave accent - 0x89: 0x20, - // transparent space (regular) - 0x8a: 0xe8, - // lowercase e, grave accent - 0x8b: 0xe2, - // lowercase a, circumflex accent - 0x8c: 0xea, - // lowercase e, circumflex accent - 0x8d: 0xee, - // lowercase i, circumflex accent - 0x8e: 0xf4, - // lowercase o, circumflex accent - 0x8f: 0xfb, - // lowercase u, circumflex accent - // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS - // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F - 0x90: 0xc1, - // capital letter A with acute - 0x91: 0xc9, - // capital letter E with acute - 0x92: 0xd3, - // capital letter O with acute - 0x93: 0xda, - // capital letter U with acute - 0x94: 0xdc, - // capital letter U with diaresis - 0x95: 0xfc, - // lowercase letter U with diaeresis - 0x96: 0x2018, - // opening single quote - 0x97: 0xa1, - // inverted exclamation mark - 0x98: 0x2a, - // asterisk - 0x99: 0x2019, - // closing single quote - 0x9a: 0x2501, - // box drawings heavy horizontal - 0x9b: 0xa9, - // copyright sign - 0x9c: 0x2120, - // Service mark - 0x9d: 0x2022, - // (round) bullet - 0x9e: 0x201c, - // Left double quotation mark - 0x9f: 0x201d, - // Right double quotation mark - 0xa0: 0xc0, - // uppercase A, grave accent - 0xa1: 0xc2, - // uppercase A, circumflex - 0xa2: 0xc7, - // uppercase C with cedilla - 0xa3: 0xc8, - // uppercase E, grave accent - 0xa4: 0xca, - // uppercase E, circumflex - 0xa5: 0xcb, - // capital letter E with diaresis - 0xa6: 0xeb, - // lowercase letter e with diaresis - 0xa7: 0xce, - // uppercase I, circumflex - 0xa8: 0xcf, - // uppercase I, with diaresis - 0xa9: 0xef, - // lowercase i, with diaresis - 0xaa: 0xd4, - // uppercase O, circumflex - 0xab: 0xd9, - // uppercase U, grave accent - 0xac: 0xf9, - // lowercase u, grave accent - 0xad: 0xdb, - // uppercase U, circumflex - 0xae: 0xab, - // left-pointing double angle quotation mark - 0xaf: 0xbb, - // right-pointing double angle quotation mark - // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS - // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F - 0xb0: 0xc3, - // Uppercase A, tilde - 0xb1: 0xe3, - // Lowercase a, tilde - 0xb2: 0xcd, - // Uppercase I, acute accent - 0xb3: 0xcc, - // Uppercase I, grave accent - 0xb4: 0xec, - // Lowercase i, grave accent - 0xb5: 0xd2, - // Uppercase O, grave accent - 0xb6: 0xf2, - // Lowercase o, grave accent - 0xb7: 0xd5, - // Uppercase O, tilde - 0xb8: 0xf5, - // Lowercase o, tilde - 0xb9: 0x7b, - // Open curly brace - 0xba: 0x7d, - // Closing curly brace - 0xbb: 0x5c, - // Backslash - 0xbc: 0x5e, - // Caret - 0xbd: 0x5f, - // Underscore - 0xbe: 0x7c, - // Pipe (vertical line) - 0xbf: 0x223c, - // Tilde operator - 0xc0: 0xc4, - // Uppercase A, umlaut - 0xc1: 0xe4, - // Lowercase A, umlaut - 0xc2: 0xd6, - // Uppercase O, umlaut - 0xc3: 0xf6, - // Lowercase o, umlaut - 0xc4: 0xdf, - // Esszett (sharp S) - 0xc5: 0xa5, - // Yen symbol - 0xc6: 0xa4, - // Generic currency sign - 0xc7: 0x2503, - // Box drawings heavy vertical - 0xc8: 0xc5, - // Uppercase A, ring - 0xc9: 0xe5, - // Lowercase A, ring - 0xca: 0xd8, - // Uppercase O, stroke - 0xcb: 0xf8, - // Lowercase o, strok - 0xcc: 0x250f, - // Box drawings heavy down and right - 0xcd: 0x2513, - // Box drawings heavy down and left - 0xce: 0x2517, - // Box drawings heavy up and right - 0xcf: 0x251b // Box drawings heavy up and left - -}; -/** - * Utils - */ - -var getCharForByte = function getCharForByte(_byte) { - var charCode = _byte; - - if (specialCea608CharsCodes.hasOwnProperty(_byte)) { - charCode = specialCea608CharsCodes[_byte]; - } - - return String.fromCharCode(charCode); -}; - -var NR_ROWS = 15; -var NR_COLS = 100; // Tables to look up row from PAC data - -var rowsLowCh1 = { - 0x11: 1, - 0x12: 3, - 0x15: 5, - 0x16: 7, - 0x17: 9, - 0x10: 11, - 0x13: 12, - 0x14: 14 -}; -var rowsHighCh1 = { - 0x11: 2, - 0x12: 4, - 0x15: 6, - 0x16: 8, - 0x17: 10, - 0x13: 13, - 0x14: 15 -}; -var rowsLowCh2 = { - 0x19: 1, - 0x1a: 3, - 0x1d: 5, - 0x1e: 7, - 0x1f: 9, - 0x18: 11, - 0x1b: 12, - 0x1c: 14 -}; -var rowsHighCh2 = { - 0x19: 2, - 0x1a: 4, - 0x1d: 6, - 0x1e: 8, - 0x1f: 10, - 0x1b: 13, - 0x1c: 15 -}; -var backgroundColors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'black', 'transparent']; -var VerboseLevel; - -(function (VerboseLevel) { - VerboseLevel[VerboseLevel["ERROR"] = 0] = "ERROR"; - VerboseLevel[VerboseLevel["TEXT"] = 1] = "TEXT"; - VerboseLevel[VerboseLevel["WARNING"] = 2] = "WARNING"; - VerboseLevel[VerboseLevel["INFO"] = 2] = "INFO"; - VerboseLevel[VerboseLevel["DEBUG"] = 3] = "DEBUG"; - VerboseLevel[VerboseLevel["DATA"] = 3] = "DATA"; -})(VerboseLevel || (VerboseLevel = {})); - -var CaptionsLogger = /*#__PURE__*/function () { - function CaptionsLogger() { - this.time = null; - this.verboseLevel = VerboseLevel.ERROR; - } - - var _proto = CaptionsLogger.prototype; - - _proto.log = function log(severity, msg) { - if (this.verboseLevel >= severity) { - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log(this.time + " [" + severity + "] " + msg); - } - }; - - return CaptionsLogger; -}(); - -var numArrayToHexArray = function numArrayToHexArray(numArray) { - var hexArray = []; - - for (var j = 0; j < numArray.length; j++) { - hexArray.push(numArray[j].toString(16)); - } - - return hexArray; -}; - -var PenState = /*#__PURE__*/function () { - function PenState(foreground, underline, italics, background, flash) { - this.foreground = void 0; - this.underline = void 0; - this.italics = void 0; - this.background = void 0; - this.flash = void 0; - this.foreground = foreground || 'white'; - this.underline = underline || false; - this.italics = italics || false; - this.background = background || 'black'; - this.flash = flash || false; - } - - var _proto2 = PenState.prototype; - - _proto2.reset = function reset() { - this.foreground = 'white'; - this.underline = false; - this.italics = false; - this.background = 'black'; - this.flash = false; - }; - - _proto2.setStyles = function setStyles(styles) { - var attribs = ['foreground', 'underline', 'italics', 'background', 'flash']; - - for (var i = 0; i < attribs.length; i++) { - var style = attribs[i]; - - if (styles.hasOwnProperty(style)) { - this[style] = styles[style]; - } - } - }; - - _proto2.isDefault = function isDefault() { - return this.foreground === 'white' && !this.underline && !this.italics && this.background === 'black' && !this.flash; - }; - - _proto2.equals = function equals(other) { - return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash; - }; - - _proto2.copy = function copy(newPenState) { - this.foreground = newPenState.foreground; - this.underline = newPenState.underline; - this.italics = newPenState.italics; - this.background = newPenState.background; - this.flash = newPenState.flash; - }; - - _proto2.toString = function toString() { - return 'color=' + this.foreground + ', underline=' + this.underline + ', italics=' + this.italics + ', background=' + this.background + ', flash=' + this.flash; - }; - - return PenState; -}(); -/** - * Unicode character with styling and background. - * @constructor - */ - - -var StyledUnicodeChar = /*#__PURE__*/function () { - function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) { - this.uchar = void 0; - this.penState = void 0; - this.uchar = uchar || ' '; // unicode character - - this.penState = new PenState(foreground, underline, italics, background, flash); - } - - var _proto3 = StyledUnicodeChar.prototype; - - _proto3.reset = function reset() { - this.uchar = ' '; - this.penState.reset(); - }; - - _proto3.setChar = function setChar(uchar, newPenState) { - this.uchar = uchar; - this.penState.copy(newPenState); - }; - - _proto3.setPenState = function setPenState(newPenState) { - this.penState.copy(newPenState); - }; - - _proto3.equals = function equals(other) { - return this.uchar === other.uchar && this.penState.equals(other.penState); - }; - - _proto3.copy = function copy(newChar) { - this.uchar = newChar.uchar; - this.penState.copy(newChar.penState); - }; - - _proto3.isEmpty = function isEmpty() { - return this.uchar === ' ' && this.penState.isDefault(); - }; - - return StyledUnicodeChar; -}(); -/** - * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar. - * @constructor - */ - - -var Row = /*#__PURE__*/function () { - function Row(logger) { - this.chars = void 0; - this.pos = void 0; - this.currPenState = void 0; - this.cueStartTime = void 0; - this.logger = void 0; - this.chars = []; - - for (var i = 0; i < NR_COLS; i++) { - this.chars.push(new StyledUnicodeChar()); - } - - this.logger = logger; - this.pos = 0; - this.currPenState = new PenState(); - } - - var _proto4 = Row.prototype; - - _proto4.equals = function equals(other) { - var equal = true; - - for (var i = 0; i < NR_COLS; i++) { - if (!this.chars[i].equals(other.chars[i])) { - equal = false; - break; - } - } - - return equal; - }; - - _proto4.copy = function copy(other) { - for (var i = 0; i < NR_COLS; i++) { - this.chars[i].copy(other.chars[i]); - } - }; - - _proto4.isEmpty = function isEmpty() { - var empty = true; - - for (var i = 0; i < NR_COLS; i++) { - if (!this.chars[i].isEmpty()) { - empty = false; - break; - } - } - - return empty; - } - /** - * Set the cursor to a valid column. - */ - ; - - _proto4.setCursor = function setCursor(absPos) { - if (this.pos !== absPos) { - this.pos = absPos; - } - - if (this.pos < 0) { - this.logger.log(VerboseLevel.DEBUG, 'Negative cursor position ' + this.pos); - this.pos = 0; - } else if (this.pos > NR_COLS) { - this.logger.log(VerboseLevel.DEBUG, 'Too large cursor position ' + this.pos); - this.pos = NR_COLS; - } - } - /** - * Move the cursor relative to current position. - */ - ; - - _proto4.moveCursor = function moveCursor(relPos) { - var newPos = this.pos + relPos; - - if (relPos > 1) { - for (var i = this.pos + 1; i < newPos + 1; i++) { - this.chars[i].setPenState(this.currPenState); - } - } - - this.setCursor(newPos); - } - /** - * Backspace, move one step back and clear character. - */ - ; - - _proto4.backSpace = function backSpace() { - this.moveCursor(-1); - this.chars[this.pos].setChar(' ', this.currPenState); - }; - - _proto4.insertChar = function insertChar(_byte2) { - if (_byte2 >= 0x90) { - // Extended char - this.backSpace(); - } - - var _char = getCharForByte(_byte2); - - if (this.pos >= NR_COLS) { - this.logger.log(VerboseLevel.ERROR, 'Cannot insert ' + _byte2.toString(16) + ' (' + _char + ') at position ' + this.pos + '. Skipping it!'); - return; - } - - this.chars[this.pos].setChar(_char, this.currPenState); - this.moveCursor(1); - }; - - _proto4.clearFromPos = function clearFromPos(startPos) { - var i; - - for (i = startPos; i < NR_COLS; i++) { - this.chars[i].reset(); - } - }; - - _proto4.clear = function clear() { - this.clearFromPos(0); - this.pos = 0; - this.currPenState.reset(); - }; - - _proto4.clearToEndOfRow = function clearToEndOfRow() { - this.clearFromPos(this.pos); - }; - - _proto4.getTextString = function getTextString() { - var chars = []; - var empty = true; - - for (var i = 0; i < NR_COLS; i++) { - var _char2 = this.chars[i].uchar; - - if (_char2 !== ' ') { - empty = false; - } - - chars.push(_char2); - } - - if (empty) { - return ''; - } else { - return chars.join(''); - } - }; - - _proto4.setPenStyles = function setPenStyles(styles) { - this.currPenState.setStyles(styles); - var currChar = this.chars[this.pos]; - currChar.setPenState(this.currPenState); - }; - - return Row; -}(); -/** - * Keep a CEA-608 screen of 32x15 styled characters - * @constructor - */ - -var CaptionScreen = /*#__PURE__*/function () { - function CaptionScreen(logger) { - this.rows = void 0; - this.currRow = void 0; - this.nrRollUpRows = void 0; - this.lastOutputScreen = void 0; - this.logger = void 0; - this.rows = []; - - for (var i = 0; i < NR_ROWS; i++) { - this.rows.push(new Row(logger)); - } // Note that we use zero-based numbering (0-14) - - - this.logger = logger; - this.currRow = NR_ROWS - 1; - this.nrRollUpRows = null; - this.lastOutputScreen = null; - this.reset(); - } - - var _proto5 = CaptionScreen.prototype; - - _proto5.reset = function reset() { - for (var i = 0; i < NR_ROWS; i++) { - this.rows[i].clear(); - } - - this.currRow = NR_ROWS - 1; - }; - - _proto5.equals = function equals(other) { - var equal = true; - - for (var i = 0; i < NR_ROWS; i++) { - if (!this.rows[i].equals(other.rows[i])) { - equal = false; - break; - } - } - - return equal; - }; - - _proto5.copy = function copy(other) { - for (var i = 0; i < NR_ROWS; i++) { - this.rows[i].copy(other.rows[i]); - } - }; - - _proto5.isEmpty = function isEmpty() { - var empty = true; - - for (var i = 0; i < NR_ROWS; i++) { - if (!this.rows[i].isEmpty()) { - empty = false; - break; - } - } - - return empty; - }; - - _proto5.backSpace = function backSpace() { - var row = this.rows[this.currRow]; - row.backSpace(); - }; - - _proto5.clearToEndOfRow = function clearToEndOfRow() { - var row = this.rows[this.currRow]; - row.clearToEndOfRow(); - } - /** - * Insert a character (without styling) in the current row. - */ - ; - - _proto5.insertChar = function insertChar(_char3) { - var row = this.rows[this.currRow]; - row.insertChar(_char3); - }; - - _proto5.setPen = function setPen(styles) { - var row = this.rows[this.currRow]; - row.setPenStyles(styles); - }; - - _proto5.moveCursor = function moveCursor(relPos) { - var row = this.rows[this.currRow]; - row.moveCursor(relPos); - }; - - _proto5.setCursor = function setCursor(absPos) { - this.logger.log(VerboseLevel.INFO, 'setCursor: ' + absPos); - var row = this.rows[this.currRow]; - row.setCursor(absPos); - }; - - _proto5.setPAC = function setPAC(pacData) { - this.logger.log(VerboseLevel.INFO, 'pacData = ' + JSON.stringify(pacData)); - var newRow = pacData.row - 1; - - if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) { - newRow = this.nrRollUpRows - 1; - } // Make sure this only affects Roll-up Captions by checking this.nrRollUpRows - - - if (this.nrRollUpRows && this.currRow !== newRow) { - // clear all rows first - for (var i = 0; i < NR_ROWS; i++) { - this.rows[i].clear(); - } // Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location - // topRowIndex - the start of rows to copy (inclusive index) - - - var topRowIndex = this.currRow + 1 - this.nrRollUpRows; // We only copy if the last position was already shown. - // We use the cueStartTime value to check this. - - var lastOutputScreen = this.lastOutputScreen; - - if (lastOutputScreen) { - var prevLineTime = lastOutputScreen.rows[topRowIndex].cueStartTime; - var time = this.logger.time; - - if (prevLineTime && time !== null && prevLineTime < time) { - for (var _i = 0; _i < this.nrRollUpRows; _i++) { - this.rows[newRow - this.nrRollUpRows + _i + 1].copy(lastOutputScreen.rows[topRowIndex + _i]); - } - } - } - } - - this.currRow = newRow; - var row = this.rows[this.currRow]; - - if (pacData.indent !== null) { - var indent = pacData.indent; - var prevPos = Math.max(indent - 1, 0); - row.setCursor(pacData.indent); - pacData.color = row.chars[prevPos].penState.foreground; - } - - var styles = { - foreground: pacData.color, - underline: pacData.underline, - italics: pacData.italics, - background: 'black', - flash: false - }; - this.setPen(styles); - } - /** - * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility). - */ - ; - - _proto5.setBkgData = function setBkgData(bkgData) { - this.logger.log(VerboseLevel.INFO, 'bkgData = ' + JSON.stringify(bkgData)); - this.backSpace(); - this.setPen(bkgData); - this.insertChar(0x20); // Space - }; - - _proto5.setRollUpRows = function setRollUpRows(nrRows) { - this.nrRollUpRows = nrRows; - }; - - _proto5.rollUp = function rollUp() { - if (this.nrRollUpRows === null) { - this.logger.log(VerboseLevel.DEBUG, 'roll_up but nrRollUpRows not set yet'); - return; // Not properly setup - } - - this.logger.log(VerboseLevel.TEXT, this.getDisplayText()); - var topRowIndex = this.currRow + 1 - this.nrRollUpRows; - var topRow = this.rows.splice(topRowIndex, 1)[0]; - topRow.clear(); - this.rows.splice(this.currRow, 0, topRow); - this.logger.log(VerboseLevel.INFO, 'Rolling up'); // this.logger.log(VerboseLevel.TEXT, this.get_display_text()) - } - /** - * Get all non-empty rows with as unicode text. - */ - ; - - _proto5.getDisplayText = function getDisplayText(asOneRow) { - asOneRow = asOneRow || false; - var displayText = []; - var text = ''; - var rowNr = -1; - - for (var i = 0; i < NR_ROWS; i++) { - var rowText = this.rows[i].getTextString(); - - if (rowText) { - rowNr = i + 1; - - if (asOneRow) { - displayText.push('Row ' + rowNr + ": '" + rowText + "'"); - } else { - displayText.push(rowText.trim()); - } - } - } - - if (displayText.length > 0) { - if (asOneRow) { - text = '[' + displayText.join(' | ') + ']'; - } else { - text = displayText.join('\n'); - } - } - - return text; - }; - - _proto5.getTextAndFormat = function getTextAndFormat() { - return this.rows; - }; - - return CaptionScreen; -}(); // var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT']; - -var Cea608Channel = /*#__PURE__*/function () { - function Cea608Channel(channelNumber, outputFilter, logger) { - this.chNr = void 0; - this.outputFilter = void 0; - this.mode = void 0; - this.verbose = void 0; - this.displayedMemory = void 0; - this.nonDisplayedMemory = void 0; - this.lastOutputScreen = void 0; - this.currRollUpRow = void 0; - this.writeScreen = void 0; - this.cueStartTime = void 0; - this.logger = void 0; - this.chNr = channelNumber; - this.outputFilter = outputFilter; - this.mode = null; - this.verbose = 0; - this.displayedMemory = new CaptionScreen(logger); - this.nonDisplayedMemory = new CaptionScreen(logger); - this.lastOutputScreen = new CaptionScreen(logger); - this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; - this.writeScreen = this.displayedMemory; - this.mode = null; - this.cueStartTime = null; // Keeps track of where a cue started. - - this.logger = logger; - } - - var _proto6 = Cea608Channel.prototype; - - _proto6.reset = function reset() { - this.mode = null; - this.displayedMemory.reset(); - this.nonDisplayedMemory.reset(); - this.lastOutputScreen.reset(); - this.outputFilter.reset(); - this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; - this.writeScreen = this.displayedMemory; - this.mode = null; - this.cueStartTime = null; - }; - - _proto6.getHandler = function getHandler() { - return this.outputFilter; - }; - - _proto6.setHandler = function setHandler(newHandler) { - this.outputFilter = newHandler; - }; - - _proto6.setPAC = function setPAC(pacData) { - this.writeScreen.setPAC(pacData); - }; - - _proto6.setBkgData = function setBkgData(bkgData) { - this.writeScreen.setBkgData(bkgData); - }; - - _proto6.setMode = function setMode(newMode) { - if (newMode === this.mode) { - return; - } - - this.mode = newMode; - this.logger.log(VerboseLevel.INFO, 'MODE=' + newMode); - - if (this.mode === 'MODE_POP-ON') { - this.writeScreen = this.nonDisplayedMemory; - } else { - this.writeScreen = this.displayedMemory; - this.writeScreen.reset(); - } - - if (this.mode !== 'MODE_ROLL-UP') { - this.displayedMemory.nrRollUpRows = null; - this.nonDisplayedMemory.nrRollUpRows = null; - } - - this.mode = newMode; - }; - - _proto6.insertChars = function insertChars(chars) { - for (var i = 0; i < chars.length; i++) { - this.writeScreen.insertChar(chars[i]); - } - - var screen = this.writeScreen === this.displayedMemory ? 'DISP' : 'NON_DISP'; - this.logger.log(VerboseLevel.INFO, screen + ': ' + this.writeScreen.getDisplayText(true)); - - if (this.mode === 'MODE_PAINT-ON' || this.mode === 'MODE_ROLL-UP') { - this.logger.log(VerboseLevel.TEXT, 'DISPLAYED: ' + this.displayedMemory.getDisplayText(true)); - this.outputDataUpdate(); - } - }; - - _proto6.ccRCL = function ccRCL() { - // Resume Caption Loading (switch mode to Pop On) - this.logger.log(VerboseLevel.INFO, 'RCL - Resume Caption Loading'); - this.setMode('MODE_POP-ON'); - }; - - _proto6.ccBS = function ccBS() { - // BackSpace - this.logger.log(VerboseLevel.INFO, 'BS - BackSpace'); - - if (this.mode === 'MODE_TEXT') { - return; - } - - this.writeScreen.backSpace(); - - if (this.writeScreen === this.displayedMemory) { - this.outputDataUpdate(); - } - }; - - _proto6.ccAOF = function ccAOF() {// Reserved (formerly Alarm Off) - }; - - _proto6.ccAON = function ccAON() {// Reserved (formerly Alarm On) - }; - - _proto6.ccDER = function ccDER() { - // Delete to End of Row - this.logger.log(VerboseLevel.INFO, 'DER- Delete to End of Row'); - this.writeScreen.clearToEndOfRow(); - this.outputDataUpdate(); - }; - - _proto6.ccRU = function ccRU(nrRows) { - // Roll-Up Captions-2,3,or 4 Rows - this.logger.log(VerboseLevel.INFO, 'RU(' + nrRows + ') - Roll Up'); - this.writeScreen = this.displayedMemory; - this.setMode('MODE_ROLL-UP'); - this.writeScreen.setRollUpRows(nrRows); - }; - - _proto6.ccFON = function ccFON() { - // Flash On - this.logger.log(VerboseLevel.INFO, 'FON - Flash On'); - this.writeScreen.setPen({ - flash: true - }); - }; - - _proto6.ccRDC = function ccRDC() { - // Resume Direct Captioning (switch mode to PaintOn) - this.logger.log(VerboseLevel.INFO, 'RDC - Resume Direct Captioning'); - this.setMode('MODE_PAINT-ON'); - }; - - _proto6.ccTR = function ccTR() { - // Text Restart in text mode (not supported, however) - this.logger.log(VerboseLevel.INFO, 'TR'); - this.setMode('MODE_TEXT'); - }; - - _proto6.ccRTD = function ccRTD() { - // Resume Text Display in Text mode (not supported, however) - this.logger.log(VerboseLevel.INFO, 'RTD'); - this.setMode('MODE_TEXT'); - }; - - _proto6.ccEDM = function ccEDM() { - // Erase Displayed Memory - this.logger.log(VerboseLevel.INFO, 'EDM - Erase Displayed Memory'); - this.displayedMemory.reset(); - this.outputDataUpdate(true); - }; - - _proto6.ccCR = function ccCR() { - // Carriage Return - this.logger.log(VerboseLevel.INFO, 'CR - Carriage Return'); - this.writeScreen.rollUp(); - this.outputDataUpdate(true); - }; - - _proto6.ccENM = function ccENM() { - // Erase Non-Displayed Memory - this.logger.log(VerboseLevel.INFO, 'ENM - Erase Non-displayed Memory'); - this.nonDisplayedMemory.reset(); - }; - - _proto6.ccEOC = function ccEOC() { - // End of Caption (Flip Memories) - this.logger.log(VerboseLevel.INFO, 'EOC - End Of Caption'); - - if (this.mode === 'MODE_POP-ON') { - var tmp = this.displayedMemory; - this.displayedMemory = this.nonDisplayedMemory; - this.nonDisplayedMemory = tmp; - this.writeScreen = this.nonDisplayedMemory; - this.logger.log(VerboseLevel.TEXT, 'DISP: ' + this.displayedMemory.getDisplayText()); - } - - this.outputDataUpdate(true); - }; - - _proto6.ccTO = function ccTO(nrCols) { - // Tab Offset 1,2, or 3 columns - this.logger.log(VerboseLevel.INFO, 'TO(' + nrCols + ') - Tab Offset'); - this.writeScreen.moveCursor(nrCols); - }; - - _proto6.ccMIDROW = function ccMIDROW(secondByte) { - // Parse MIDROW command - var styles = { - flash: false - }; - styles.underline = secondByte % 2 === 1; - styles.italics = secondByte >= 0x2e; - - if (!styles.italics) { - var colorIndex = Math.floor(secondByte / 2) - 0x10; - var colors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta']; - styles.foreground = colors[colorIndex]; - } else { - styles.foreground = 'white'; - } - - this.logger.log(VerboseLevel.INFO, 'MIDROW: ' + JSON.stringify(styles)); - this.writeScreen.setPen(styles); - }; - - _proto6.outputDataUpdate = function outputDataUpdate(dispatch) { - if (dispatch === void 0) { - dispatch = false; - } - - var time = this.logger.time; - - if (time === null) { - return; - } - - if (this.outputFilter) { - if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) { - // Start of a new cue - this.cueStartTime = time; - } else { - if (!this.displayedMemory.equals(this.lastOutputScreen)) { - this.outputFilter.newCue(this.cueStartTime, time, this.lastOutputScreen); - - if (dispatch && this.outputFilter.dispatchCue) { - this.outputFilter.dispatchCue(); - } - - this.cueStartTime = this.displayedMemory.isEmpty() ? null : time; - } - } - - this.lastOutputScreen.copy(this.displayedMemory); - } - }; - - _proto6.cueSplitAtTime = function cueSplitAtTime(t) { - if (this.outputFilter) { - if (!this.displayedMemory.isEmpty()) { - if (this.outputFilter.newCue) { - this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory); - } - - this.cueStartTime = t; - } - } - }; - - return Cea608Channel; -}(); - -var Cea608Parser = /*#__PURE__*/function () { - function Cea608Parser(field, out1, out2) { - this.channels = void 0; - this.currentChannel = 0; - this.cmdHistory = void 0; - this.logger = void 0; - var logger = new CaptionsLogger(); - this.channels = [null, new Cea608Channel(field, out1, logger), new Cea608Channel(field + 1, out2, logger)]; - this.cmdHistory = createCmdHistory(); - this.logger = logger; - } - - var _proto7 = Cea608Parser.prototype; - - _proto7.getHandler = function getHandler(channel) { - return this.channels[channel].getHandler(); - }; - - _proto7.setHandler = function setHandler(channel, newHandler) { - this.channels[channel].setHandler(newHandler); - } - /** - * Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs. - */ - ; - - _proto7.addData = function addData(time, byteList) { - var cmdFound; - var a; - var b; - var charsFound = false; - this.logger.time = time; - - for (var i = 0; i < byteList.length; i += 2) { - a = byteList[i] & 0x7f; - b = byteList[i + 1] & 0x7f; - - if (a === 0 && b === 0) { - continue; - } else { - this.logger.log(VerboseLevel.DATA, '[' + numArrayToHexArray([byteList[i], byteList[i + 1]]) + '] -> (' + numArrayToHexArray([a, b]) + ')'); - } - - cmdFound = this.parseCmd(a, b); - - if (!cmdFound) { - cmdFound = this.parseMidrow(a, b); - } - - if (!cmdFound) { - cmdFound = this.parsePAC(a, b); - } - - if (!cmdFound) { - cmdFound = this.parseBackgroundAttributes(a, b); - } - - if (!cmdFound) { - charsFound = this.parseChars(a, b); - - if (charsFound) { - var currChNr = this.currentChannel; - - if (currChNr && currChNr > 0) { - var channel = this.channels[currChNr]; - channel.insertChars(charsFound); - } else { - this.logger.log(VerboseLevel.WARNING, 'No channel found yet. TEXT-MODE?'); - } - } - } - - if (!cmdFound && !charsFound) { - this.logger.log(VerboseLevel.WARNING, "Couldn't parse cleaned data " + numArrayToHexArray([a, b]) + ' orig: ' + numArrayToHexArray([byteList[i], byteList[i + 1]])); - } - } - } - /** - * Parse Command. - * @returns {Boolean} Tells if a command was found - */ - ; - - _proto7.parseCmd = function parseCmd(a, b) { - var cmdHistory = this.cmdHistory; - var cond1 = (a === 0x14 || a === 0x1c || a === 0x15 || a === 0x1d) && b >= 0x20 && b <= 0x2f; - var cond2 = (a === 0x17 || a === 0x1f) && b >= 0x21 && b <= 0x23; - - if (!(cond1 || cond2)) { - return false; - } - - if (hasCmdRepeated(a, b, cmdHistory)) { - setLastCmd(null, null, cmdHistory); - this.logger.log(VerboseLevel.DEBUG, 'Repeated command (' + numArrayToHexArray([a, b]) + ') is dropped'); - return true; - } - - var chNr = a === 0x14 || a === 0x15 || a === 0x17 ? 1 : 2; - var channel = this.channels[chNr]; - - if (a === 0x14 || a === 0x15 || a === 0x1c || a === 0x1d) { - if (b === 0x20) { - channel.ccRCL(); - } else if (b === 0x21) { - channel.ccBS(); - } else if (b === 0x22) { - channel.ccAOF(); - } else if (b === 0x23) { - channel.ccAON(); - } else if (b === 0x24) { - channel.ccDER(); - } else if (b === 0x25) { - channel.ccRU(2); - } else if (b === 0x26) { - channel.ccRU(3); - } else if (b === 0x27) { - channel.ccRU(4); - } else if (b === 0x28) { - channel.ccFON(); - } else if (b === 0x29) { - channel.ccRDC(); - } else if (b === 0x2a) { - channel.ccTR(); - } else if (b === 0x2b) { - channel.ccRTD(); - } else if (b === 0x2c) { - channel.ccEDM(); - } else if (b === 0x2d) { - channel.ccCR(); - } else if (b === 0x2e) { - channel.ccENM(); - } else if (b === 0x2f) { - channel.ccEOC(); - } - } else { - // a == 0x17 || a == 0x1F - channel.ccTO(b - 0x20); - } - - setLastCmd(a, b, cmdHistory); - this.currentChannel = chNr; - return true; - } - /** - * Parse midrow styling command - * @returns {Boolean} - */ - ; - - _proto7.parseMidrow = function parseMidrow(a, b) { - var chNr = 0; - - if ((a === 0x11 || a === 0x19) && b >= 0x20 && b <= 0x2f) { - if (a === 0x11) { - chNr = 1; - } else { - chNr = 2; - } - - if (chNr !== this.currentChannel) { - this.logger.log(VerboseLevel.ERROR, 'Mismatch channel in midrow parsing'); - return false; - } - - var channel = this.channels[chNr]; - - if (!channel) { - return false; - } - - channel.ccMIDROW(b); - this.logger.log(VerboseLevel.DEBUG, 'MIDROW (' + numArrayToHexArray([a, b]) + ')'); - return true; - } - - return false; - } - /** - * Parse Preable Access Codes (Table 53). - * @returns {Boolean} Tells if PAC found - */ - ; - - _proto7.parsePAC = function parsePAC(a, b) { - var row; - var cmdHistory = this.cmdHistory; - var case1 = (a >= 0x11 && a <= 0x17 || a >= 0x19 && a <= 0x1f) && b >= 0x40 && b <= 0x7f; - var case2 = (a === 0x10 || a === 0x18) && b >= 0x40 && b <= 0x5f; - - if (!(case1 || case2)) { - return false; - } - - if (hasCmdRepeated(a, b, cmdHistory)) { - setLastCmd(null, null, cmdHistory); - return true; // Repeated commands are dropped (once) - } - - var chNr = a <= 0x17 ? 1 : 2; - - if (b >= 0x40 && b <= 0x5f) { - row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a]; - } else { - // 0x60 <= b <= 0x7F - row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a]; - } - - var channel = this.channels[chNr]; - - if (!channel) { - return false; - } - - channel.setPAC(this.interpretPAC(row, b)); - setLastCmd(a, b, cmdHistory); - this.currentChannel = chNr; - return true; - } - /** - * Interpret the second byte of the pac, and return the information. - * @returns {Object} pacData with style parameters. - */ - ; - - _proto7.interpretPAC = function interpretPAC(row, _byte3) { - var pacIndex; - var pacData = { - color: null, - italics: false, - indent: null, - underline: false, - row: row - }; - - if (_byte3 > 0x5f) { - pacIndex = _byte3 - 0x60; - } else { - pacIndex = _byte3 - 0x40; - } - - pacData.underline = (pacIndex & 1) === 1; - - if (pacIndex <= 0xd) { - pacData.color = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'white'][Math.floor(pacIndex / 2)]; - } else if (pacIndex <= 0xf) { - pacData.italics = true; - pacData.color = 'white'; - } else { - pacData.indent = Math.floor((pacIndex - 0x10) / 2) * 4; - } - - return pacData; // Note that row has zero offset. The spec uses 1. - } - /** - * Parse characters. - * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise. - */ - ; - - _proto7.parseChars = function parseChars(a, b) { - var channelNr; - var charCodes = null; - var charCode1 = null; - - if (a >= 0x19) { - channelNr = 2; - charCode1 = a - 8; - } else { - channelNr = 1; - charCode1 = a; - } - - if (charCode1 >= 0x11 && charCode1 <= 0x13) { - // Special character - var oneCode; - - if (charCode1 === 0x11) { - oneCode = b + 0x50; - } else if (charCode1 === 0x12) { - oneCode = b + 0x70; - } else { - oneCode = b + 0x90; - } - - this.logger.log(VerboseLevel.INFO, "Special char '" + getCharForByte(oneCode) + "' in channel " + channelNr); - charCodes = [oneCode]; - } else if (a >= 0x20 && a <= 0x7f) { - charCodes = b === 0 ? [a] : [a, b]; - } - - if (charCodes) { - var hexCodes = numArrayToHexArray(charCodes); - this.logger.log(VerboseLevel.DEBUG, 'Char codes = ' + hexCodes.join(',')); - setLastCmd(a, b, this.cmdHistory); - } - - return charCodes; - } - /** - * Parse extended background attributes as well as new foreground color black. - * @returns {Boolean} Tells if background attributes are found - */ - ; - - _proto7.parseBackgroundAttributes = function parseBackgroundAttributes(a, b) { - var case1 = (a === 0x10 || a === 0x18) && b >= 0x20 && b <= 0x2f; - var case2 = (a === 0x17 || a === 0x1f) && b >= 0x2d && b <= 0x2f; - - if (!(case1 || case2)) { - return false; - } - - var index; - var bkgData = {}; - - if (a === 0x10 || a === 0x18) { - index = Math.floor((b - 0x20) / 2); - bkgData.background = backgroundColors[index]; - - if (b % 2 === 1) { - bkgData.background = bkgData.background + '_semi'; - } - } else if (b === 0x2d) { - bkgData.background = 'transparent'; - } else { - bkgData.foreground = 'black'; - - if (b === 0x2f) { - bkgData.underline = true; - } - } - - var chNr = a <= 0x17 ? 1 : 2; - var channel = this.channels[chNr]; - channel.setBkgData(bkgData); - setLastCmd(a, b, this.cmdHistory); - return true; - } - /** - * Reset state of parser and its channels. - */ - ; - - _proto7.reset = function reset() { - for (var i = 0; i < Object.keys(this.channels).length; i++) { - var channel = this.channels[i]; - - if (channel) { - channel.reset(); - } - } - - this.cmdHistory = createCmdHistory(); - } - /** - * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty. - */ - ; - - _proto7.cueSplitAtTime = function cueSplitAtTime(t) { - for (var i = 0; i < this.channels.length; i++) { - var channel = this.channels[i]; - - if (channel) { - channel.cueSplitAtTime(t); - } - } - }; - - return Cea608Parser; -}(); - -function setLastCmd(a, b, cmdHistory) { - cmdHistory.a = a; - cmdHistory.b = b; -} - -function hasCmdRepeated(a, b, cmdHistory) { - return cmdHistory.a === a && cmdHistory.b === b; -} - -function createCmdHistory() { - return { - a: null, - b: null - }; -} - -/* harmony default export */ __webpack_exports__["default"] = (Cea608Parser); - -/***/ }), - -/***/ "./src/utils/codecs.ts": -/*!*****************************!*\ - !*** ./src/utils/codecs.ts ***! - \*****************************/ -/*! exports provided: isCodecType, isCodecSupportedInMp4 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isCodecType", function() { return isCodecType; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isCodecSupportedInMp4", function() { return isCodecSupportedInMp4; }); -// from http://mp4ra.org/codecs.html -var sampleEntryCodesISO = { - audio: { - a3ds: true, - 'ac-3': true, - 'ac-4': true, - alac: true, - alaw: true, - dra1: true, - 'dts+': true, - 'dts-': true, - dtsc: true, - dtse: true, - dtsh: true, - 'ec-3': true, - enca: true, - g719: true, - g726: true, - m4ae: true, - mha1: true, - mha2: true, - mhm1: true, - mhm2: true, - mlpa: true, - mp4a: true, - 'raw ': true, - Opus: true, - samr: true, - sawb: true, - sawp: true, - sevc: true, - sqcp: true, - ssmv: true, - twos: true, - ulaw: true - }, - video: { - avc1: true, - avc2: true, - avc3: true, - avc4: true, - avcp: true, - av01: true, - drac: true, - dvav: true, - dvhe: true, - encv: true, - hev1: true, - hvc1: true, - mjp2: true, - mp4v: true, - mvc1: true, - mvc2: true, - mvc3: true, - mvc4: true, - resv: true, - rv60: true, - s263: true, - svc1: true, - svc2: true, - 'vc-1': true, - vp08: true, - vp09: true - }, - text: { - stpp: true, - wvtt: true - } -}; -function isCodecType(codec, type) { - var typeCodes = sampleEntryCodesISO[type]; - return !!typeCodes && typeCodes[codec.slice(0, 4)] === true; -} -function isCodecSupportedInMp4(codec, type) { - return MediaSource.isTypeSupported((type || 'video') + "/mp4;codecs=\"" + codec + "\""); -} - -/***/ }), - -/***/ "./src/utils/cues.ts": -/*!***************************!*\ - !*** ./src/utils/cues.ts ***! - \***************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts"); -/* harmony import */ var _webvtt_parser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./webvtt-parser */ "./src/utils/webvtt-parser.ts"); -/* harmony import */ var _texttrack_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./texttrack-utils */ "./src/utils/texttrack-utils.ts"); - - - -var WHITESPACE_CHAR = /\s/; -var Cues = { - newCue: function newCue(track, startTime, endTime, captionScreen) { - var result = []; - var row; // the type data states this is VTTCue, but it can potentially be a TextTrackCue on old browsers - - var cue; - var indenting; - var indent; - var text; - var Cue = self.VTTCue || self.TextTrackCue; - - for (var r = 0; r < captionScreen.rows.length; r++) { - row = captionScreen.rows[r]; - indenting = true; - indent = 0; - text = ''; - - if (!row.isEmpty()) { - for (var c = 0; c < row.chars.length; c++) { - if (WHITESPACE_CHAR.test(row.chars[c].uchar) && indenting) { - indent++; - } else { - text += row.chars[c].uchar; - indenting = false; - } - } // To be used for cleaning-up orphaned roll-up captions - - - row.cueStartTime = startTime; // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE - - if (startTime === endTime) { - endTime += 0.0001; - } - - if (indent >= 16) { - indent--; - } else { - indent++; - } - - var cueText = Object(_vttparser__WEBPACK_IMPORTED_MODULE_0__["fixLineBreaks"])(text.trim()); - var id = Object(_webvtt_parser__WEBPACK_IMPORTED_MODULE_1__["generateCueId"])(startTime, endTime, cueText); // If this cue already exists in the track do not push it - - if (!track || !track.cues || !track.cues.getCueById(id)) { - cue = new Cue(startTime, endTime, cueText); - cue.id = id; - cue.line = r + 1; - cue.align = 'left'; // Clamp the position between 10 and 80 percent (CEA-608 PAC indent code) - // https://dvcs.w3.org/hg/text-tracks/raw-file/default/608toVTT/608toVTT.html#positioning-in-cea-608 - // Firefox throws an exception and captions break with out of bounds 0-100 values - - cue.position = 10 + Math.min(80, Math.floor(indent * 8 / 32) * 10); - result.push(cue); - } - } - } - - if (track && result.length) { - // Sort bottom cues in reverse order so that they render in line order when overlapping in Chrome - result.sort(function (cueA, cueB) { - if (cueA.line === 'auto' || cueB.line === 'auto') { - return 0; - } - - if (cueA.line > 8 && cueB.line > 8) { - return cueB.line - cueA.line; - } - - return cueA.line - cueB.line; - }); - result.forEach(function (cue) { - return Object(_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__["addCueToTrack"])(track, cue); - }); - } - - return result; - } -}; -/* harmony default export */ __webpack_exports__["default"] = (Cues); - -/***/ }), - -/***/ "./src/utils/discontinuities.ts": -/*!**************************************!*\ - !*** ./src/utils/discontinuities.ts ***! - \**************************************/ -/*! exports provided: findFirstFragWithCC, shouldAlignOnDiscontinuities, findDiscontinuousReferenceFrag, adjustSlidingStart, alignStream, alignPDT, alignFragmentByPDTDelta, alignMediaPlaylistByPDT */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFirstFragWithCC", function() { return findFirstFragWithCC; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shouldAlignOnDiscontinuities", function() { return shouldAlignOnDiscontinuities; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findDiscontinuousReferenceFrag", function() { return findDiscontinuousReferenceFrag; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "adjustSlidingStart", function() { return adjustSlidingStart; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignStream", function() { return alignStream; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignPDT", function() { return alignPDT; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignFragmentByPDTDelta", function() { return alignFragmentByPDTDelta; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignMediaPlaylistByPDT", function() { return alignMediaPlaylistByPDT; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts"); -/* harmony import */ var _controller_level_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../controller/level-helper */ "./src/controller/level-helper.ts"); - - - - -function findFirstFragWithCC(fragments, cc) { - var firstFrag = null; - - for (var i = 0, len = fragments.length; i < len; i++) { - var currentFrag = fragments[i]; - - if (currentFrag && currentFrag.cc === cc) { - firstFrag = currentFrag; - break; - } - } - - return firstFrag; -} -function shouldAlignOnDiscontinuities(lastFrag, lastLevel, details) { - if (lastLevel.details) { - if (details.endCC > details.startCC || lastFrag && lastFrag.cc < details.startCC) { - return true; - } - } - - return false; -} // Find the first frag in the previous level which matches the CC of the first frag of the new level - -function findDiscontinuousReferenceFrag(prevDetails, curDetails) { - var prevFrags = prevDetails.fragments; - var curFrags = curDetails.fragments; - - if (!curFrags.length || !prevFrags.length) { - _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log('No fragments to align'); - return; - } - - var prevStartFrag = findFirstFragWithCC(prevFrags, curFrags[0].cc); - - if (!prevStartFrag || prevStartFrag && !prevStartFrag.startPTS) { - _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log('No frag in previous level to align on'); - return; - } - - return prevStartFrag; -} - -function adjustFragmentStart(frag, sliding) { - if (frag) { - var start = frag.start + sliding; - frag.start = frag.startPTS = start; - frag.endPTS = start + frag.duration; - } -} - -function adjustSlidingStart(sliding, details) { - // Update segments - var fragments = details.fragments; - - for (var i = 0, len = fragments.length; i < len; i++) { - adjustFragmentStart(fragments[i], sliding); - } // Update LL-CiderHls parts at the end of the playlist - - - if (details.fragmentHint) { - adjustFragmentStart(details.fragmentHint, sliding); - } - - details.alignedSliding = true; -} -/** - * Using the parameters of the last level, this function computes PTS' of the new fragments so that they form a - * contiguous stream with the last fragments. - * The PTS of a fragment lets CiderHls.js know where it fits into a stream - by knowing every PTS, we know which fragment to - * download at any given time. PTS is normally computed when the fragment is demuxed, so taking this step saves us time - * and an extra download. - * @param lastFrag - * @param lastLevel - * @param details - */ - -function alignStream(lastFrag, lastLevel, details) { - if (!lastLevel) { - return; - } - - alignDiscontinuities(lastFrag, details, lastLevel); - - if (!details.alignedSliding && lastLevel.details) { - // If the PTS wasn't figured out via discontinuity sequence that means there was no CC increase within the level. - // Aligning via Program Date Time should therefore be reliable, since PDT should be the same within the same - // discontinuity sequence. - alignPDT(details, lastLevel.details); - } - - if (!details.alignedSliding && lastLevel.details && !details.skippedSegments) { - // Try to align on sn so that we pick a better start fragment. - // Do not perform this on playlists with delta updates as this is only to align levels on switch - // and adjustSliding only adjusts fragments after skippedSegments. - Object(_controller_level_helper__WEBPACK_IMPORTED_MODULE_2__["adjustSliding"])(lastLevel.details, details); - } -} -/** - * Computes the PTS if a new level's fragments using the PTS of a fragment in the last level which shares the same - * discontinuity sequence. - * @param lastFrag - The last Fragment which shares the same discontinuity sequence - * @param lastLevel - The details of the last loaded level - * @param details - The details of the new level - */ - -function alignDiscontinuities(lastFrag, details, lastLevel) { - if (shouldAlignOnDiscontinuities(lastFrag, lastLevel, details)) { - var referenceFrag = findDiscontinuousReferenceFrag(lastLevel.details, details); - - if (referenceFrag && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(referenceFrag.start)) { - _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("Adjusting PTS using last level due to CC increase within current level " + details.url); - adjustSlidingStart(referenceFrag.start, details); - } - } -} -/** - * Computes the PTS of a new level's fragments using the difference in Program Date Time from the last level. - * @param details - The details of the new level - * @param lastDetails - The details of the last loaded level - */ - - -function alignPDT(details, lastDetails) { - // This check protects the unsafe "!" usage below for null program date time access. - if (!lastDetails.fragments.length || !details.hasProgramDateTime || !lastDetails.hasProgramDateTime) { - return; - } // if last level sliding is 1000 and its first frag PROGRAM-DATE-TIME is 2017-08-20 1:10:00 AM - // and if new details first frag PROGRAM DATE-TIME is 2017-08-20 1:10:08 AM - // then we can deduce that playlist B sliding is 1000+8 = 1008s - - - var lastPDT = lastDetails.fragments[0].programDateTime; // hasProgramDateTime check above makes this safe. - - var newPDT = details.fragments[0].programDateTime; // date diff is in ms. frag.start is in seconds - - var sliding = (newPDT - lastPDT) / 1000 + lastDetails.fragments[0].start; - - if (sliding && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(sliding)) { - _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("Adjusting PTS using programDateTime delta " + (newPDT - lastPDT) + "ms, sliding:" + sliding.toFixed(3) + " " + details.url + " "); - adjustSlidingStart(sliding, details); - } -} -function alignFragmentByPDTDelta(frag, delta) { - var programDateTime = frag.programDateTime; - if (!programDateTime) return; - var start = (programDateTime - delta) / 1000; - frag.start = frag.startPTS = start; - frag.endPTS = start + frag.duration; -} -/** - * Ensures appropriate time-alignment between renditions based on PDT. Unlike `alignPDT`, which adjusts - * the timeline based on the delta between PDTs of the 0th fragment of two playlists/`LevelDetails`, - * this function assumes the timelines represented in `refDetails` are accurate, including the PDTs, - * and uses the "wallclock"/PDT timeline as a cross-reference to `details`, adjusting the presentation - * times/timelines of `details` accordingly. - * Given the asynchronous nature of fetches and initial loads of live `main` and audio/subtitle tracks, - * the primary purpose of this function is to ensure the "local timelines" of audio/subtitle tracks - * are aligned to the main/video timeline, using PDT as the cross-reference/"anchor" that should - * be consistent across playlists, per the CiderHls spec. - * @param details - The details of the rendition you'd like to time-align (e.g. an audio rendition). - * @param refDetails - The details of the reference rendition with start and PDT times for alignment. - */ - -function alignMediaPlaylistByPDT(details, refDetails) { - // This check protects the unsafe "!" usage below for null program date time access. - if (!refDetails.fragments.length || !details.hasProgramDateTime || !refDetails.hasProgramDateTime) { - return; - } - - var refPDT = refDetails.fragments[0].programDateTime; // hasProgramDateTime check above makes this safe. - - var refStart = refDetails.fragments[0].start; // Use the delta between the reference details' presentation timeline's start time and its PDT - // to align the other rendtion's timeline. - - var delta = refPDT - refStart * 1000; // Per spec: "If any Media Playlist in a Master Playlist contains an EXT-X-PROGRAM-DATE-TIME tag, then all - // Media Playlists in that Master Playlist MUST contain EXT-X-PROGRAM-DATE-TIME tags with consistent mappings - // of date and time to media timestamps." - // So we should be able to use each rendition's PDT as a reference time and use the delta to compute our relevant - // start and end times. - // NOTE: This code assumes each level/details timelines have already been made "internally consistent" - - details.fragments.forEach(function (frag) { - alignFragmentByPDTDelta(frag, delta); - }); - - if (details.fragmentHint) { - alignFragmentByPDTDelta(details.fragmentHint, delta); - } - - details.alignedSliding = true; -} - -/***/ }), - -/***/ "./src/utils/ewma-bandwidth-estimator.ts": -/*!***********************************************!*\ - !*** ./src/utils/ewma-bandwidth-estimator.ts ***! - \***********************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _utils_ewma__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/ewma */ "./src/utils/ewma.ts"); -/* - * EWMA Bandwidth Estimator - * - heavily inspired from shaka-player - * Tracks bandwidth samples and estimates available bandwidth. - * Based on the minimum of two exponentially-weighted moving averages with - * different half-lives. - */ - - -var EwmaBandWidthEstimator = /*#__PURE__*/function () { - function EwmaBandWidthEstimator(slow, fast, defaultEstimate) { - this.defaultEstimate_ = void 0; - this.minWeight_ = void 0; - this.minDelayMs_ = void 0; - this.slow_ = void 0; - this.fast_ = void 0; - this.defaultEstimate_ = defaultEstimate; - this.minWeight_ = 0.001; - this.minDelayMs_ = 50; - this.slow_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow); - this.fast_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast); - } - - var _proto = EwmaBandWidthEstimator.prototype; - - _proto.update = function update(slow, fast) { - var slow_ = this.slow_, - fast_ = this.fast_; - - if (this.slow_.halfLife !== slow) { - this.slow_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow, slow_.getEstimate(), slow_.getTotalWeight()); - } - - if (this.fast_.halfLife !== fast) { - this.fast_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast, fast_.getEstimate(), fast_.getTotalWeight()); - } - }; - - _proto.sample = function sample(durationMs, numBytes) { - durationMs = Math.max(durationMs, this.minDelayMs_); - var numBits = 8 * numBytes; // weight is duration in seconds - - var durationS = durationMs / 1000; // value is bandwidth in bits/s - - var bandwidthInBps = numBits / durationS; - this.fast_.sample(durationS, bandwidthInBps); - this.slow_.sample(durationS, bandwidthInBps); - }; - - _proto.canEstimate = function canEstimate() { - var fast = this.fast_; - return fast && fast.getTotalWeight() >= this.minWeight_; - }; - - _proto.getEstimate = function getEstimate() { - if (this.canEstimate()) { - // console.log('slow estimate:'+ Math.round(this.slow_.getEstimate())); - // console.log('fast estimate:'+ Math.round(this.fast_.getEstimate())); - // Take the minimum of these two estimates. This should have the effect of - // adapting down quickly, but up more slowly. - return Math.min(this.fast_.getEstimate(), this.slow_.getEstimate()); - } else { - return this.defaultEstimate_; - } - }; - - _proto.destroy = function destroy() {}; - - return EwmaBandWidthEstimator; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (EwmaBandWidthEstimator); - -/***/ }), - -/***/ "./src/utils/ewma.ts": -/*!***************************!*\ - !*** ./src/utils/ewma.ts ***! - \***************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * compute an Exponential Weighted moving average - * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average - * - heavily inspired from shaka-player - */ -var EWMA = /*#__PURE__*/function () { - // About half of the estimated value will be from the last |halfLife| samples by weight. - function EWMA(halfLife, estimate, weight) { - if (estimate === void 0) { - estimate = 0; - } - - if (weight === void 0) { - weight = 0; - } - - this.halfLife = void 0; - this.alpha_ = void 0; - this.estimate_ = void 0; - this.totalWeight_ = void 0; - this.halfLife = halfLife; // Larger values of alpha expire historical data more slowly. - - this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0; - this.estimate_ = estimate; - this.totalWeight_ = weight; - } - - var _proto = EWMA.prototype; - - _proto.sample = function sample(weight, value) { - var adjAlpha = Math.pow(this.alpha_, weight); - this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_; - this.totalWeight_ += weight; - }; - - _proto.getTotalWeight = function getTotalWeight() { - return this.totalWeight_; - }; - - _proto.getEstimate = function getEstimate() { - if (this.alpha_) { - var zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_); - - if (zeroFactor) { - return this.estimate_ / zeroFactor; - } - } - - return this.estimate_; - }; - - return EWMA; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (EWMA); - -/***/ }), - -/***/ "./src/utils/fetch-loader.ts": -/*!***********************************!*\ - !*** ./src/utils/fetch-loader.ts ***! - \***********************************/ -/*! exports provided: fetchSupported, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fetchSupported", function() { return fetchSupported; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/load-stats */ "./src/loader/load-stats.ts"); -/* harmony import */ var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/chunk-cache */ "./src/demux/chunk-cache.ts"); - - - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } - -function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - - - -function fetchSupported() { - if ( // @ts-ignore - self.fetch && self.AbortController && self.ReadableStream && self.Request) { - try { - new self.ReadableStream({}); // eslint-disable-line no-new - - return true; - } catch (e) { - /* noop */ - } - } - - return false; -} - -var FetchLoader = /*#__PURE__*/function () { - function FetchLoader(config - /* CiderHlsConfig */ - ) { - this.fetchSetup = void 0; - this.requestTimeout = void 0; - this.request = void 0; - this.response = void 0; - this.controller = void 0; - this.context = void 0; - this.config = null; - this.callbacks = null; - this.stats = void 0; - this.loader = null; - this.fetchSetup = config.fetchSetup || getRequest; - this.controller = new self.AbortController(); - this.stats = new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__["LoadStats"](); - } - - var _proto = FetchLoader.prototype; - - _proto.destroy = function destroy() { - this.loader = this.callbacks = null; - this.abortInternal(); - }; - - _proto.abortInternal = function abortInternal() { - var response = this.response; - - if (!response || !response.ok) { - this.stats.aborted = true; - this.controller.abort(); - } - }; - - _proto.abort = function abort() { - var _this$callbacks; - - this.abortInternal(); - - if ((_this$callbacks = this.callbacks) !== null && _this$callbacks !== void 0 && _this$callbacks.onAbort) { - this.callbacks.onAbort(this.stats, this.context, this.response); - } - }; - - _proto.load = function load(context, config, callbacks) { - var _this = this; - - var stats = this.stats; - - if (stats.loading.start) { - throw new Error('Loader can only be used once.'); - } - - stats.loading.start = self.performance.now(); - var initParams = getRequestParameters(context, this.controller.signal); - var onProgress = callbacks.onProgress; - var isArrayBuffer = context.responseType === 'arraybuffer'; - var LENGTH = isArrayBuffer ? 'byteLength' : 'length'; - this.context = context; - this.config = config; - this.callbacks = callbacks; - this.request = this.fetchSetup(context, initParams); - self.clearTimeout(this.requestTimeout); - this.requestTimeout = self.setTimeout(function () { - _this.abortInternal(); - - callbacks.onTimeout(stats, context, _this.response); - }, config.timeout); - self.fetch(this.request).then(function (response) { - _this.response = _this.loader = response; - - if (!response.ok) { - var status = response.status, - statusText = response.statusText; - throw new FetchError(statusText || 'fetch, bad network response', status, response); - } - - stats.loading.first = Math.max(self.performance.now(), stats.loading.start); - stats.total = parseInt(response.headers.get('Content-Length') || '0'); - - if (onProgress && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(config.highWaterMark)) { - return _this.loadProgressively(response, stats, context, config.highWaterMark, onProgress); - } - - if (isArrayBuffer) { - return response.arrayBuffer(); - } - - return response.text(); - }).then(function (responseData) { - var response = _this.response; - self.clearTimeout(_this.requestTimeout); - stats.loading.end = Math.max(self.performance.now(), stats.loading.first); - stats.loaded = stats.total = responseData[LENGTH]; - var loaderResponse = { - url: response.url, - data: responseData - }; - - if (onProgress && !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(config.highWaterMark)) { - onProgress(stats, context, responseData, response); - } - - callbacks.onSuccess(loaderResponse, stats, context, response); - }).catch(function (error) { - self.clearTimeout(_this.requestTimeout); - - if (stats.aborted) { - return; - } // CORS errors result in an undefined code. Set it to 0 here to align with XHR's behavior - - - var code = error.code || 0; - callbacks.onError({ - code: code, - text: error.message - }, context, error.details); - }); - }; - - _proto.getCacheAge = function getCacheAge() { - var result = null; - - if (this.response) { - var ageHeader = this.response.headers.get('age'); - result = ageHeader ? parseFloat(ageHeader) : null; - } - - return result; - }; - - _proto.loadProgressively = function loadProgressively(response, stats, context, highWaterMark, onProgress) { - if (highWaterMark === void 0) { - highWaterMark = 0; - } - - var chunkCache = new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__["default"](); - var reader = response.body.getReader(); - - var pump = function pump() { - return reader.read().then(function (data) { - if (data.done) { - if (chunkCache.dataLength) { - onProgress(stats, context, chunkCache.flush(), response); - } - - return Promise.resolve(new ArrayBuffer(0)); - } - - var chunk = data.value; - var len = chunk.length; - stats.loaded += len; - - if (len < highWaterMark || chunkCache.dataLength) { - // The current chunk is too small to to be emitted or the cache already has data - // Push it to the cache - chunkCache.push(chunk); - - if (chunkCache.dataLength >= highWaterMark) { - // flush in order to join the typed arrays - onProgress(stats, context, chunkCache.flush(), response); - } - } else { - // If there's nothing cached already, and the chache is large enough - // just emit the progress event - onProgress(stats, context, chunk, response); - } - - return pump(); - }).catch(function () { - /* aborted */ - return Promise.reject(); - }); - }; - - return pump(); - }; - - return FetchLoader; -}(); - -function getRequestParameters(context, signal) { - var initParams = { - method: 'GET', - mode: 'cors', - credentials: 'same-origin', - signal: signal, - headers: new self.Headers(_extends({}, context.headers)) - }; - - if (context.rangeEnd) { - initParams.headers.set('Range', 'bytes=' + context.rangeStart + '-' + String(context.rangeEnd - 1)); - } - - return initParams; -} - -function getRequest(context, initParams) { - return new self.Request(context.url, initParams); -} - -var FetchError = /*#__PURE__*/function (_Error) { - _inheritsLoose(FetchError, _Error); - - function FetchError(message, code, details) { - var _this2; - - _this2 = _Error.call(this, message) || this; - _this2.code = void 0; - _this2.details = void 0; - _this2.code = code; - _this2.details = details; - return _this2; - } - - return FetchError; -}( /*#__PURE__*/_wrapNativeSuper(Error)); - -/* harmony default export */ __webpack_exports__["default"] = (FetchLoader); - -/***/ }), - -/***/ "./src/utils/imsc1-ttml-parser.ts": -/*!****************************************!*\ - !*** ./src/utils/imsc1-ttml-parser.ts ***! - \****************************************/ -/*! exports provided: IMSC1_CODEC, parseIMSC1 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IMSC1_CODEC", function() { return IMSC1_CODEC; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseIMSC1", function() { return parseIMSC1; }); -/* harmony import */ var _mp4_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mp4-tools */ "./src/utils/mp4-tools.ts"); -/* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts"); -/* harmony import */ var _vttcue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./vttcue */ "./src/utils/vttcue.ts"); -/* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); -/* harmony import */ var _timescale_conversion__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./timescale-conversion */ "./src/utils/timescale-conversion.ts"); -/* harmony import */ var _webvtt_parser__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./webvtt-parser */ "./src/utils/webvtt-parser.ts"); -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - - - - - - - -var IMSC1_CODEC = 'stpp.ttml.im1t'; // Time format: h:m:s:frames(.subframes) - -var HMSF_REGEX = /^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/; // Time format: hours, minutes, seconds, milliseconds, frames, ticks - -var TIME_UNIT_REGEX = /^(\d*(?:\.\d*)?)(h|m|s|ms|f|t)$/; -var textAlignToLineAlign = { - left: 'start', - center: 'center', - right: 'end', - start: 'start', - end: 'end' -}; -function parseIMSC1(payload, initPTS, timescale, callBack, errorCallBack) { - var results = Object(_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["findBox"])(new Uint8Array(payload), ['mdat']); - - if (results.length === 0) { - errorCallBack(new Error('Could not parse IMSC1 mdat')); - return; - } - - var mdat = results[0]; - var ttml = Object(_demux_id3__WEBPACK_IMPORTED_MODULE_3__["utf8ArrayToStr"])(new Uint8Array(payload, mdat.start, mdat.end - mdat.start)); - var syncTime = Object(_timescale_conversion__WEBPACK_IMPORTED_MODULE_4__["toTimescaleFromScale"])(initPTS, 1, timescale); - - try { - callBack(parseTTML(ttml, syncTime)); - } catch (error) { - errorCallBack(error); - } -} - -function parseTTML(ttml, syncTime) { - var parser = new DOMParser(); - var xmlDoc = parser.parseFromString(ttml, 'text/xml'); - var tt = xmlDoc.getElementsByTagName('tt')[0]; - - if (!tt) { - throw new Error('Invalid ttml'); - } - - var defaultRateInfo = { - frameRate: 30, - subFrameRate: 1, - frameRateMultiplier: 0, - tickRate: 0 - }; - var rateInfo = Object.keys(defaultRateInfo).reduce(function (result, key) { - result[key] = tt.getAttribute("ttp:" + key) || defaultRateInfo[key]; - return result; - }, {}); - var trim = tt.getAttribute('xml:space') !== 'preserve'; - var styleElements = collectionToDictionary(getElementCollection(tt, 'styling', 'style')); - var regionElements = collectionToDictionary(getElementCollection(tt, 'layout', 'region')); - var cueElements = getElementCollection(tt, 'body', '[begin]'); - return [].map.call(cueElements, function (cueElement) { - var cueText = getTextContent(cueElement, trim); - - if (!cueText || !cueElement.hasAttribute('begin')) { - return null; - } - - var startTime = parseTtmlTime(cueElement.getAttribute('begin'), rateInfo); - var duration = parseTtmlTime(cueElement.getAttribute('dur'), rateInfo); - var endTime = parseTtmlTime(cueElement.getAttribute('end'), rateInfo); - - if (startTime === null) { - throw timestampParsingError(cueElement); - } - - if (endTime === null) { - if (duration === null) { - throw timestampParsingError(cueElement); - } - - endTime = startTime + duration; - } - - var cue = new _vttcue__WEBPACK_IMPORTED_MODULE_2__["default"](startTime - syncTime, endTime - syncTime, cueText); - cue.id = Object(_webvtt_parser__WEBPACK_IMPORTED_MODULE_5__["generateCueId"])(cue.startTime, cue.endTime, cue.text); - var region = regionElements[cueElement.getAttribute('region')]; - var style = styleElements[cueElement.getAttribute('style')]; // TODO: Add regions to track and cue (origin and extend) - // These values are hard-coded (for now) to simulate region settings in the demo - - cue.position = 10; - cue.size = 80; // Apply styles to cue - - var styles = getTtmlStyles(region, style); - var textAlign = styles.textAlign; - - if (textAlign) { - // cue.positionAlign not settable in FF~2016 - var lineAlign = textAlignToLineAlign[textAlign]; - - if (lineAlign) { - cue.lineAlign = lineAlign; - } - - cue.align = textAlign; - } - - _extends(cue, styles); - - return cue; - }).filter(function (cue) { - return cue !== null; - }); -} - -function getElementCollection(fromElement, parentName, childName) { - var parent = fromElement.getElementsByTagName(parentName)[0]; - - if (parent) { - return [].slice.call(parent.querySelectorAll(childName)); - } - - return []; -} - -function collectionToDictionary(elementsWithId) { - return elementsWithId.reduce(function (dict, element) { - var id = element.getAttribute('xml:id'); - - if (id) { - dict[id] = element; - } - - return dict; - }, {}); -} - -function getTextContent(element, trim) { - return [].slice.call(element.childNodes).reduce(function (str, node, i) { - var _node$childNodes; - - if (node.nodeName === 'br' && i) { - return str + '\n'; - } - - if ((_node$childNodes = node.childNodes) !== null && _node$childNodes !== void 0 && _node$childNodes.length) { - return getTextContent(node, trim); - } else if (trim) { - return str + node.textContent.trim().replace(/\s+/g, ' '); - } - - return str + node.textContent; - }, ''); -} - -function getTtmlStyles(region, style) { - var ttsNs = 'http://www.w3.org/ns/ttml#styling'; - var styleAttributes = ['displayAlign', 'textAlign', 'color', 'backgroundColor', 'fontSize', 'fontFamily' // 'fontWeight', - // 'lineHeight', - // 'wrapOption', - // 'fontStyle', - // 'direction', - // 'writingMode' - ]; - return styleAttributes.reduce(function (styles, name) { - var value = getAttributeNS(style, ttsNs, name) || getAttributeNS(region, ttsNs, name); - - if (value) { - styles[name] = value; - } - - return styles; - }, {}); -} - -function getAttributeNS(element, ns, name) { - return element.hasAttributeNS(ns, name) ? element.getAttributeNS(ns, name) : null; -} - -function timestampParsingError(node) { - return new Error("Could not parse ttml timestamp " + node); -} - -function parseTtmlTime(timeAttributeValue, rateInfo) { - if (!timeAttributeValue) { - return null; - } - - var seconds = Object(_vttparser__WEBPACK_IMPORTED_MODULE_1__["parseTimeStamp"])(timeAttributeValue); - - if (seconds === null) { - if (HMSF_REGEX.test(timeAttributeValue)) { - seconds = parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo); - } else if (TIME_UNIT_REGEX.test(timeAttributeValue)) { - seconds = parseTimeUnits(timeAttributeValue, rateInfo); - } - } - - return seconds; -} - -function parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo) { - var m = HMSF_REGEX.exec(timeAttributeValue); - var frames = (m[4] | 0) + (m[5] | 0) / rateInfo.subFrameRate; - return (m[1] | 0) * 3600 + (m[2] | 0) * 60 + (m[3] | 0) + frames / rateInfo.frameRate; -} - -function parseTimeUnits(timeAttributeValue, rateInfo) { - var m = TIME_UNIT_REGEX.exec(timeAttributeValue); - var value = Number(m[1]); - var unit = m[2]; - - switch (unit) { - case 'h': - return value * 3600; - - case 'm': - return value * 60; - - case 'ms': - return value * 1000; - - case 'f': - return value / rateInfo.frameRate; - - case 't': - return value / rateInfo.tickRate; - } - - return value; -} - -/***/ }), - -/***/ "./src/utils/logger.ts": -/*!*****************************!*\ - !*** ./src/utils/logger.ts ***! - \*****************************/ -/*! exports provided: enableLogs, logger */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableLogs", function() { return enableLogs; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logger", function() { return logger; }); -var noop = function noop() {}; - -var fakeLogger = { - trace: noop, - debug: noop, - log: noop, - warn: noop, - info: noop, - error: noop -}; -var exportedLogger = fakeLogger; // let lastCallTime; -// function formatMsgWithTimeInfo(type, msg) { -// const now = Date.now(); -// const diff = lastCallTime ? '+' + (now - lastCallTime) : '0'; -// lastCallTime = now; -// msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )'; -// return msg; -// } - -function consolePrintFn(type) { - var func = self.console[type]; - - if (func) { - return func.bind(self.console, "[" + type + "] >"); - } - - return noop; -} - -function exportLoggerFunctions(debugConfig) { - for (var _len = arguments.length, functions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - functions[_key - 1] = arguments[_key]; - } - - functions.forEach(function (type) { - exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type); - }); -} - -function enableLogs(debugConfig) { - // check that console is available - if (self.console && debugConfig === true || typeof debugConfig === 'object') { - exportLoggerFunctions(debugConfig, // Remove out from list here to hard-disable a log-level - // 'trace', - 'debug', 'log', 'info', 'warn', 'error'); // Some browsers don't allow to use bind on console object anyway - // fallback to default if needed - - try { - exportedLogger.log(); - } catch (e) { - exportedLogger = fakeLogger; - } - } else { - exportedLogger = fakeLogger; - } -} -var logger = exportedLogger; - -/***/ }), - -/***/ "./src/utils/mediakeys-helper.ts": -/*!***************************************!*\ - !*** ./src/utils/mediakeys-helper.ts ***! - \***************************************/ -/*! exports provided: KeySystems, requestMediaKeySystemAccess */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeySystems", function() { return KeySystems; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "requestMediaKeySystemAccess", function() { return requestMediaKeySystemAccess; }); -/** - * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess - */ -var KeySystems; - -(function (KeySystems) { - KeySystems["WIDEVINE"] = "com.widevine.alpha"; - KeySystems["PLAYREADY"] = "com.microsoft.playready"; -})(KeySystems || (KeySystems = {})); - -var requestMediaKeySystemAccess = function () { - if (typeof self !== 'undefined' && self.navigator && self.navigator.requestMediaKeySystemAccess) { - return self.navigator.requestMediaKeySystemAccess.bind(self.navigator); - } else { - return null; - } -}(); - - - -/***/ }), - -/***/ "./src/utils/mediasource-helper.ts": -/*!*****************************************!*\ - !*** ./src/utils/mediasource-helper.ts ***! - \*****************************************/ -/*! exports provided: getMediaSource */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getMediaSource", function() { return getMediaSource; }); -/** - * MediaSource helper - */ -function getMediaSource() { - return self.MediaSource || self.WebKitMediaSource; -} - -/***/ }), - -/***/ "./src/utils/mp4-tools.ts": -/*!********************************!*\ - !*** ./src/utils/mp4-tools.ts ***! - \********************************/ -/*! exports provided: bin2str, readUint16, readUint32, writeUint32, findBox, parseSegmentIndex, parseInitSegment, getStartDTS, getDuration, computeRawDurationFromSamples, offsetStartDTS, segmentValidRange, appendUint8Array */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bin2str", function() { return bin2str; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readUint16", function() { return readUint16; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readUint32", function() { return readUint32; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writeUint32", function() { return writeUint32; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findBox", function() { return findBox; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseSegmentIndex", function() { return parseSegmentIndex; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseInitSegment", function() { return parseInitSegment; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getStartDTS", function() { return getStartDTS; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDuration", function() { return getDuration; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "computeRawDurationFromSamples", function() { return computeRawDurationFromSamples; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "offsetStartDTS", function() { return offsetStartDTS; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "segmentValidRange", function() { return segmentValidRange; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "appendUint8Array", function() { return appendUint8Array; }); -/* harmony import */ var _typed_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./typed-array */ "./src/utils/typed-array.ts"); -/* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); - - -var UINT32_MAX = Math.pow(2, 32) - 1; -var push = [].push; -function bin2str(data) { - return String.fromCharCode.apply(null, data); -} -function readUint16(buffer, offset) { - if ('data' in buffer) { - offset += buffer.start; - buffer = buffer.data; - } - - var val = buffer[offset] << 8 | buffer[offset + 1]; - return val < 0 ? 65536 + val : val; -} -function readUint32(buffer, offset) { - if ('data' in buffer) { - offset += buffer.start; - buffer = buffer.data; - } - - var val = buffer[offset] << 24 | buffer[offset + 1] << 16 | buffer[offset + 2] << 8 | buffer[offset + 3]; - return val < 0 ? 4294967296 + val : val; -} -function writeUint32(buffer, offset, value) { - if ('data' in buffer) { - offset += buffer.start; - buffer = buffer.data; - } - - buffer[offset] = value >> 24; - buffer[offset + 1] = value >> 16 & 0xff; - buffer[offset + 2] = value >> 8 & 0xff; - buffer[offset + 3] = value & 0xff; -} // Find the data for a box specified by its path - -function findBox(input, path) { - var results = []; - - if (!path.length) { - // short-circuit the search for empty paths - return results; - } - - var data; - var start; - var end; - - if ('data' in input) { - data = input.data; - start = input.start; - end = input.end; - } else { - data = input; - start = 0; - end = data.byteLength; - } - - for (var i = start; i < end;) { - var size = readUint32(data, i); - var type = bin2str(data.subarray(i + 4, i + 8)); - var endbox = size > 1 ? i + size : end; - - if (type === path[0]) { - if (path.length === 1) { - // this is the end of the path and we've found the box we were - // looking for - results.push({ - data: data, - start: i + 8, - end: endbox - }); - } else { - // recursively search for the next box along the path - var subresults = findBox({ - data: data, - start: i + 8, - end: endbox - }, path.slice(1)); - - if (subresults.length) { - push.apply(results, subresults); - } - } - } - - i = endbox; - } // we've finished searching all of data - - - return results; -} -function parseSegmentIndex(initSegment) { - var moovBox = findBox(initSegment, ['moov']); - var moov = moovBox[0]; - var moovEndOffset = moov ? moov.end : null; // we need this in case we need to chop of garbage of the end of current data - - var sidxBox = findBox(initSegment, ['sidx']); - - if (!sidxBox || !sidxBox[0]) { - return null; - } - - var references = []; - var sidx = sidxBox[0]; - var version = sidx.data[0]; // set initial offset, we skip the reference ID (not needed) - - var index = version === 0 ? 8 : 16; - var timescale = readUint32(sidx, index); - index += 4; // TODO: parse earliestPresentationTime and firstOffset - // usually zero in our case - - var earliestPresentationTime = 0; - var firstOffset = 0; - - if (version === 0) { - index += 8; - } else { - index += 16; - } // skip reserved - - - index += 2; - var startByte = sidx.end + firstOffset; - var referencesCount = readUint16(sidx, index); - index += 2; - - for (var i = 0; i < referencesCount; i++) { - var referenceIndex = index; - var referenceInfo = readUint32(sidx, referenceIndex); - referenceIndex += 4; - var referenceSize = referenceInfo & 0x7fffffff; - var referenceType = (referenceInfo & 0x80000000) >>> 31; - - if (referenceType === 1) { - // eslint-disable-next-line no-console - console.warn('SIDX has hierarchical references (not supported)'); - return null; - } - - var subsegmentDuration = readUint32(sidx, referenceIndex); - referenceIndex += 4; - references.push({ - referenceSize: referenceSize, - subsegmentDuration: subsegmentDuration, - // unscaled - info: { - duration: subsegmentDuration / timescale, - start: startByte, - end: startByte + referenceSize - 1 - } - }); - startByte += referenceSize; // Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits - // for |sapDelta|. - - referenceIndex += 4; // skip to next ref - - index = referenceIndex; - } - - return { - earliestPresentationTime: earliestPresentationTime, - timescale: timescale, - version: version, - referencesCount: referencesCount, - references: references, - moovEndOffset: moovEndOffset - }; -} -/** - * Parses an MP4 initialization segment and extracts stream type and - * timescale values for any declared tracks. Timescale values indicate the - * number of clock ticks per second to assume for time-based values - * elsewhere in the MP4. - * - * To determine the start time of an MP4, you need two pieces of - * information: the timescale unit and the earliest base media decode - * time. Multiple timescales can be specified within an MP4 but the - * base media decode time is always expressed in the timescale from - * the media header box for the track: - * ``` - * moov > trak > mdia > mdhd.timescale - * moov > trak > mdia > hdlr - * ``` - * @param initSegment {Uint8Array} the bytes of the init segment - * @return {InitData} a hash of track type to timescale values or null if - * the init segment is malformed. - */ - -function parseInitSegment(initSegment) { - var result = []; - var traks = findBox(initSegment, ['moov', 'trak']); - - for (var i = 0; i < traks.length; i++) { - var trak = traks[i]; - var tkhd = findBox(trak, ['tkhd'])[0]; - - if (tkhd) { - var version = tkhd.data[tkhd.start]; - - var _index = version === 0 ? 12 : 20; - - var trackId = readUint32(tkhd, _index); - var mdhd = findBox(trak, ['mdia', 'mdhd'])[0]; - - if (mdhd) { - version = mdhd.data[mdhd.start]; - _index = version === 0 ? 12 : 20; - var timescale = readUint32(mdhd, _index); - var hdlr = findBox(trak, ['mdia', 'hdlr'])[0]; - - if (hdlr) { - var hdlrType = bin2str(hdlr.data.subarray(hdlr.start + 8, hdlr.start + 12)); - var type = { - soun: _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].AUDIO, - vide: _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].VIDEO - }[hdlrType]; - - if (type) { - // Parse codec details - var stsd = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0]; - var codec = void 0; - - if (stsd) { - codec = bin2str(stsd.data.subarray(stsd.start + 12, stsd.start + 16)); // TODO: Parse codec details to be able to build MIME type. - // stsd.start += 8; - // const codecBox = findBox(stsd, [codec])[0]; - // if (codecBox) { - // TODO: Codec parsing support for avc1, mp4a, hevc, av01... - // } + /*! exports provided: Row, CaptionScreen, default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Row", function () { + return Row; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CaptionScreen", function () { + return CaptionScreen; + }); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + + /** + * + * This code was ported from the dash.js project at: + * https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js + * https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2 + * + * The original copyright appears below: + * + * The copyright in this software is being made available under the BSD License, + * included below. This software may be subject to other third party and contributor + * rights, including patent rights, and no such rights are granted under this license. + * + * Copyright (c) 2015-2016, DASH Industry Forum. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * 2. Neither the name of Dash Industry Forum nor the names of its + * contributors may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + /** + * Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes + */ + + var specialCea608CharsCodes = { + 0x2a: 0xe1, + // lowercase a, acute accent + 0x5c: 0xe9, + // lowercase e, acute accent + 0x5e: 0xed, + // lowercase i, acute accent + 0x5f: 0xf3, + // lowercase o, acute accent + 0x60: 0xfa, + // lowercase u, acute accent + 0x7b: 0xe7, + // lowercase c with cedilla + 0x7c: 0xf7, + // division symbol + 0x7d: 0xd1, + // uppercase N tilde + 0x7e: 0xf1, + // lowercase n tilde + 0x7f: 0x2588, + // Full block + // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS + // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F + // THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES + 0x80: 0xae, + // Registered symbol (R) + 0x81: 0xb0, + // degree sign + 0x82: 0xbd, + // 1/2 symbol + 0x83: 0xbf, + // Inverted (open) question mark + 0x84: 0x2122, + // Trademark symbol (TM) + 0x85: 0xa2, + // Cents symbol + 0x86: 0xa3, + // Pounds sterling + 0x87: 0x266a, + // Music 8'th note + 0x88: 0xe0, + // lowercase a, grave accent + 0x89: 0x20, + // transparent space (regular) + 0x8a: 0xe8, + // lowercase e, grave accent + 0x8b: 0xe2, + // lowercase a, circumflex accent + 0x8c: 0xea, + // lowercase e, circumflex accent + 0x8d: 0xee, + // lowercase i, circumflex accent + 0x8e: 0xf4, + // lowercase o, circumflex accent + 0x8f: 0xfb, + // lowercase u, circumflex accent + // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS + // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F + 0x90: 0xc1, + // capital letter A with acute + 0x91: 0xc9, + // capital letter E with acute + 0x92: 0xd3, + // capital letter O with acute + 0x93: 0xda, + // capital letter U with acute + 0x94: 0xdc, + // capital letter U with diaresis + 0x95: 0xfc, + // lowercase letter U with diaeresis + 0x96: 0x2018, + // opening single quote + 0x97: 0xa1, + // inverted exclamation mark + 0x98: 0x2a, + // asterisk + 0x99: 0x2019, + // closing single quote + 0x9a: 0x2501, + // box drawings heavy horizontal + 0x9b: 0xa9, + // copyright sign + 0x9c: 0x2120, + // Service mark + 0x9d: 0x2022, + // (round) bullet + 0x9e: 0x201c, + // Left double quotation mark + 0x9f: 0x201d, + // Right double quotation mark + 0xa0: 0xc0, + // uppercase A, grave accent + 0xa1: 0xc2, + // uppercase A, circumflex + 0xa2: 0xc7, + // uppercase C with cedilla + 0xa3: 0xc8, + // uppercase E, grave accent + 0xa4: 0xca, + // uppercase E, circumflex + 0xa5: 0xcb, + // capital letter E with diaresis + 0xa6: 0xeb, + // lowercase letter e with diaresis + 0xa7: 0xce, + // uppercase I, circumflex + 0xa8: 0xcf, + // uppercase I, with diaresis + 0xa9: 0xef, + // lowercase i, with diaresis + 0xaa: 0xd4, + // uppercase O, circumflex + 0xab: 0xd9, + // uppercase U, grave accent + 0xac: 0xf9, + // lowercase u, grave accent + 0xad: 0xdb, + // uppercase U, circumflex + 0xae: 0xab, + // left-pointing double angle quotation mark + 0xaf: 0xbb, + // right-pointing double angle quotation mark + // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS + // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F + 0xb0: 0xc3, + // Uppercase A, tilde + 0xb1: 0xe3, + // Lowercase a, tilde + 0xb2: 0xcd, + // Uppercase I, acute accent + 0xb3: 0xcc, + // Uppercase I, grave accent + 0xb4: 0xec, + // Lowercase i, grave accent + 0xb5: 0xd2, + // Uppercase O, grave accent + 0xb6: 0xf2, + // Lowercase o, grave accent + 0xb7: 0xd5, + // Uppercase O, tilde + 0xb8: 0xf5, + // Lowercase o, tilde + 0xb9: 0x7b, + // Open curly brace + 0xba: 0x7d, + // Closing curly brace + 0xbb: 0x5c, + // Backslash + 0xbc: 0x5e, + // Caret + 0xbd: 0x5f, + // Underscore + 0xbe: 0x7c, + // Pipe (vertical line) + 0xbf: 0x223c, + // Tilde operator + 0xc0: 0xc4, + // Uppercase A, umlaut + 0xc1: 0xe4, + // Lowercase A, umlaut + 0xc2: 0xd6, + // Uppercase O, umlaut + 0xc3: 0xf6, + // Lowercase o, umlaut + 0xc4: 0xdf, + // Esszett (sharp S) + 0xc5: 0xa5, + // Yen symbol + 0xc6: 0xa4, + // Generic currency sign + 0xc7: 0x2503, + // Box drawings heavy vertical + 0xc8: 0xc5, + // Uppercase A, ring + 0xc9: 0xe5, + // Lowercase A, ring + 0xca: 0xd8, + // Uppercase O, stroke + 0xcb: 0xf8, + // Lowercase o, strok + 0xcc: 0x250f, + // Box drawings heavy down and right + 0xcd: 0x2513, + // Box drawings heavy down and left + 0xce: 0x2517, + // Box drawings heavy up and right + 0xcf: 0x251b, // Box drawings heavy up and left + }; + /** + * Utils + */ + + var getCharForByte = function getCharForByte(_byte) { + var charCode = _byte; + + if (specialCea608CharsCodes.hasOwnProperty(_byte)) { + charCode = specialCea608CharsCodes[_byte]; + } + + return String.fromCharCode(charCode); + }; + + var NR_ROWS = 15; + var NR_COLS = 100; // Tables to look up row from PAC data + + var rowsLowCh1 = { + 0x11: 1, + 0x12: 3, + 0x15: 5, + 0x16: 7, + 0x17: 9, + 0x10: 11, + 0x13: 12, + 0x14: 14, + }; + var rowsHighCh1 = { + 0x11: 2, + 0x12: 4, + 0x15: 6, + 0x16: 8, + 0x17: 10, + 0x13: 13, + 0x14: 15, + }; + var rowsLowCh2 = { + 0x19: 1, + 0x1a: 3, + 0x1d: 5, + 0x1e: 7, + 0x1f: 9, + 0x18: 11, + 0x1b: 12, + 0x1c: 14, + }; + var rowsHighCh2 = { + 0x19: 2, + 0x1a: 4, + 0x1d: 6, + 0x1e: 8, + 0x1f: 10, + 0x1b: 13, + 0x1c: 15, + }; + var backgroundColors = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "black", "transparent"]; + var VerboseLevel; + + (function (VerboseLevel) { + VerboseLevel[(VerboseLevel["ERROR"] = 0)] = "ERROR"; + VerboseLevel[(VerboseLevel["TEXT"] = 1)] = "TEXT"; + VerboseLevel[(VerboseLevel["WARNING"] = 2)] = "WARNING"; + VerboseLevel[(VerboseLevel["INFO"] = 2)] = "INFO"; + VerboseLevel[(VerboseLevel["DEBUG"] = 3)] = "DEBUG"; + VerboseLevel[(VerboseLevel["DATA"] = 3)] = "DATA"; + })(VerboseLevel || (VerboseLevel = {})); + + var CaptionsLogger = /*#__PURE__*/ (function () { + function CaptionsLogger() { + this.time = null; + this.verboseLevel = VerboseLevel.ERROR; + } + + var _proto = CaptionsLogger.prototype; + + _proto.log = function log(severity, msg) { + if (this.verboseLevel >= severity) { + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log(this.time + " [" + severity + "] " + msg); + } + }; + + return CaptionsLogger; + })(); + + var numArrayToHexArray = function numArrayToHexArray(numArray) { + var hexArray = []; + + for (var j = 0; j < numArray.length; j++) { + hexArray.push(numArray[j].toString(16)); + } + + return hexArray; + }; + + var PenState = /*#__PURE__*/ (function () { + function PenState(foreground, underline, italics, background, flash) { + this.foreground = void 0; + this.underline = void 0; + this.italics = void 0; + this.background = void 0; + this.flash = void 0; + this.foreground = foreground || "white"; + this.underline = underline || false; + this.italics = italics || false; + this.background = background || "black"; + this.flash = flash || false; + } + + var _proto2 = PenState.prototype; + + _proto2.reset = function reset() { + this.foreground = "white"; + this.underline = false; + this.italics = false; + this.background = "black"; + this.flash = false; + }; + + _proto2.setStyles = function setStyles(styles) { + var attribs = ["foreground", "underline", "italics", "background", "flash"]; + + for (var i = 0; i < attribs.length; i++) { + var style = attribs[i]; + + if (styles.hasOwnProperty(style)) { + this[style] = styles[style]; + } + } + }; + + _proto2.isDefault = function isDefault() { + return this.foreground === "white" && !this.underline && !this.italics && this.background === "black" && !this.flash; + }; + + _proto2.equals = function equals(other) { + return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash; + }; + + _proto2.copy = function copy(newPenState) { + this.foreground = newPenState.foreground; + this.underline = newPenState.underline; + this.italics = newPenState.italics; + this.background = newPenState.background; + this.flash = newPenState.flash; + }; + + _proto2.toString = function toString() { + return "color=" + this.foreground + ", underline=" + this.underline + ", italics=" + this.italics + ", background=" + this.background + ", flash=" + this.flash; + }; + + return PenState; + })(); + /** + * Unicode character with styling and background. + * @constructor + */ + + var StyledUnicodeChar = /*#__PURE__*/ (function () { + function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) { + this.uchar = void 0; + this.penState = void 0; + this.uchar = uchar || " "; // unicode character + + this.penState = new PenState(foreground, underline, italics, background, flash); + } + + var _proto3 = StyledUnicodeChar.prototype; + + _proto3.reset = function reset() { + this.uchar = " "; + this.penState.reset(); + }; + + _proto3.setChar = function setChar(uchar, newPenState) { + this.uchar = uchar; + this.penState.copy(newPenState); + }; + + _proto3.setPenState = function setPenState(newPenState) { + this.penState.copy(newPenState); + }; + + _proto3.equals = function equals(other) { + return this.uchar === other.uchar && this.penState.equals(other.penState); + }; + + _proto3.copy = function copy(newChar) { + this.uchar = newChar.uchar; + this.penState.copy(newChar.penState); + }; + + _proto3.isEmpty = function isEmpty() { + return this.uchar === " " && this.penState.isDefault(); + }; + + return StyledUnicodeChar; + })(); + /** + * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar. + * @constructor + */ + + var Row = /*#__PURE__*/ (function () { + function Row(logger) { + this.chars = void 0; + this.pos = void 0; + this.currPenState = void 0; + this.cueStartTime = void 0; + this.logger = void 0; + this.chars = []; + + for (var i = 0; i < NR_COLS; i++) { + this.chars.push(new StyledUnicodeChar()); + } + + this.logger = logger; + this.pos = 0; + this.currPenState = new PenState(); + } + + var _proto4 = Row.prototype; + + _proto4.equals = function equals(other) { + var equal = true; + + for (var i = 0; i < NR_COLS; i++) { + if (!this.chars[i].equals(other.chars[i])) { + equal = false; + break; + } + } + + return equal; + }; + + _proto4.copy = function copy(other) { + for (var i = 0; i < NR_COLS; i++) { + this.chars[i].copy(other.chars[i]); + } + }; + + _proto4.isEmpty = function isEmpty() { + var empty = true; + + for (var i = 0; i < NR_COLS; i++) { + if (!this.chars[i].isEmpty()) { + empty = false; + break; + } + } + + return empty; + }; + /** + * Set the cursor to a valid column. + */ + + _proto4.setCursor = function setCursor(absPos) { + if (this.pos !== absPos) { + this.pos = absPos; + } + + if (this.pos < 0) { + this.logger.log(VerboseLevel.DEBUG, "Negative cursor position " + this.pos); + this.pos = 0; + } else if (this.pos > NR_COLS) { + this.logger.log(VerboseLevel.DEBUG, "Too large cursor position " + this.pos); + this.pos = NR_COLS; + } + }; + /** + * Move the cursor relative to current position. + */ + + _proto4.moveCursor = function moveCursor(relPos) { + var newPos = this.pos + relPos; + + if (relPos > 1) { + for (var i = this.pos + 1; i < newPos + 1; i++) { + this.chars[i].setPenState(this.currPenState); + } + } + + this.setCursor(newPos); + }; + /** + * Backspace, move one step back and clear character. + */ + + _proto4.backSpace = function backSpace() { + this.moveCursor(-1); + this.chars[this.pos].setChar(" ", this.currPenState); + }; + + _proto4.insertChar = function insertChar(_byte2) { + if (_byte2 >= 0x90) { + // Extended char + this.backSpace(); + } + + var _char = getCharForByte(_byte2); + + if (this.pos >= NR_COLS) { + this.logger.log(VerboseLevel.ERROR, "Cannot insert " + _byte2.toString(16) + " (" + _char + ") at position " + this.pos + ". Skipping it!"); + return; + } + + this.chars[this.pos].setChar(_char, this.currPenState); + this.moveCursor(1); + }; + + _proto4.clearFromPos = function clearFromPos(startPos) { + var i; + + for (i = startPos; i < NR_COLS; i++) { + this.chars[i].reset(); + } + }; + + _proto4.clear = function clear() { + this.clearFromPos(0); + this.pos = 0; + this.currPenState.reset(); + }; + + _proto4.clearToEndOfRow = function clearToEndOfRow() { + this.clearFromPos(this.pos); + }; + + _proto4.getTextString = function getTextString() { + var chars = []; + var empty = true; + + for (var i = 0; i < NR_COLS; i++) { + var _char2 = this.chars[i].uchar; + + if (_char2 !== " ") { + empty = false; + } + + chars.push(_char2); + } + + if (empty) { + return ""; + } else { + return chars.join(""); + } + }; + + _proto4.setPenStyles = function setPenStyles(styles) { + this.currPenState.setStyles(styles); + var currChar = this.chars[this.pos]; + currChar.setPenState(this.currPenState); + }; + + return Row; + })(); + /** + * Keep a CEA-608 screen of 32x15 styled characters + * @constructor + */ + + var CaptionScreen = /*#__PURE__*/ (function () { + function CaptionScreen(logger) { + this.rows = void 0; + this.currRow = void 0; + this.nrRollUpRows = void 0; + this.lastOutputScreen = void 0; + this.logger = void 0; + this.rows = []; + + for (var i = 0; i < NR_ROWS; i++) { + this.rows.push(new Row(logger)); + } // Note that we use zero-based numbering (0-14) + + this.logger = logger; + this.currRow = NR_ROWS - 1; + this.nrRollUpRows = null; + this.lastOutputScreen = null; + this.reset(); + } + + var _proto5 = CaptionScreen.prototype; + + _proto5.reset = function reset() { + for (var i = 0; i < NR_ROWS; i++) { + this.rows[i].clear(); + } + + this.currRow = NR_ROWS - 1; + }; + + _proto5.equals = function equals(other) { + var equal = true; + + for (var i = 0; i < NR_ROWS; i++) { + if (!this.rows[i].equals(other.rows[i])) { + equal = false; + break; + } + } + + return equal; + }; + + _proto5.copy = function copy(other) { + for (var i = 0; i < NR_ROWS; i++) { + this.rows[i].copy(other.rows[i]); + } + }; + + _proto5.isEmpty = function isEmpty() { + var empty = true; + + for (var i = 0; i < NR_ROWS; i++) { + if (!this.rows[i].isEmpty()) { + empty = false; + break; + } + } + + return empty; + }; + + _proto5.backSpace = function backSpace() { + var row = this.rows[this.currRow]; + row.backSpace(); + }; + + _proto5.clearToEndOfRow = function clearToEndOfRow() { + var row = this.rows[this.currRow]; + row.clearToEndOfRow(); + }; + /** + * Insert a character (without styling) in the current row. + */ + + _proto5.insertChar = function insertChar(_char3) { + var row = this.rows[this.currRow]; + row.insertChar(_char3); + }; + + _proto5.setPen = function setPen(styles) { + var row = this.rows[this.currRow]; + row.setPenStyles(styles); + }; + + _proto5.moveCursor = function moveCursor(relPos) { + var row = this.rows[this.currRow]; + row.moveCursor(relPos); + }; + + _proto5.setCursor = function setCursor(absPos) { + this.logger.log(VerboseLevel.INFO, "setCursor: " + absPos); + var row = this.rows[this.currRow]; + row.setCursor(absPos); + }; + + _proto5.setPAC = function setPAC(pacData) { + this.logger.log(VerboseLevel.INFO, "pacData = " + JSON.stringify(pacData)); + var newRow = pacData.row - 1; + + if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) { + newRow = this.nrRollUpRows - 1; + } // Make sure this only affects Roll-up Captions by checking this.nrRollUpRows + + if (this.nrRollUpRows && this.currRow !== newRow) { + // clear all rows first + for (var i = 0; i < NR_ROWS; i++) { + this.rows[i].clear(); + } // Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location + // topRowIndex - the start of rows to copy (inclusive index) + + var topRowIndex = this.currRow + 1 - this.nrRollUpRows; // We only copy if the last position was already shown. + // We use the cueStartTime value to check this. + + var lastOutputScreen = this.lastOutputScreen; + + if (lastOutputScreen) { + var prevLineTime = lastOutputScreen.rows[topRowIndex].cueStartTime; + var time = this.logger.time; + + if (prevLineTime && time !== null && prevLineTime < time) { + for (var _i = 0; _i < this.nrRollUpRows; _i++) { + this.rows[newRow - this.nrRollUpRows + _i + 1].copy(lastOutputScreen.rows[topRowIndex + _i]); + } + } + } + } + + this.currRow = newRow; + var row = this.rows[this.currRow]; + + if (pacData.indent !== null) { + var indent = pacData.indent; + var prevPos = Math.max(indent - 1, 0); + row.setCursor(pacData.indent); + pacData.color = row.chars[prevPos].penState.foreground; + } + + var styles = { + foreground: pacData.color, + underline: pacData.underline, + italics: pacData.italics, + background: "black", + flash: false, + }; + this.setPen(styles); + }; + /** + * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility). + */ + + _proto5.setBkgData = function setBkgData(bkgData) { + this.logger.log(VerboseLevel.INFO, "bkgData = " + JSON.stringify(bkgData)); + this.backSpace(); + this.setPen(bkgData); + this.insertChar(0x20); // Space + }; + + _proto5.setRollUpRows = function setRollUpRows(nrRows) { + this.nrRollUpRows = nrRows; + }; + + _proto5.rollUp = function rollUp() { + if (this.nrRollUpRows === null) { + this.logger.log(VerboseLevel.DEBUG, "roll_up but nrRollUpRows not set yet"); + return; // Not properly setup + } + + this.logger.log(VerboseLevel.TEXT, this.getDisplayText()); + var topRowIndex = this.currRow + 1 - this.nrRollUpRows; + var topRow = this.rows.splice(topRowIndex, 1)[0]; + topRow.clear(); + this.rows.splice(this.currRow, 0, topRow); + this.logger.log(VerboseLevel.INFO, "Rolling up"); // this.logger.log(VerboseLevel.TEXT, this.get_display_text()) + }; + /** + * Get all non-empty rows with as unicode text. + */ + + _proto5.getDisplayText = function getDisplayText(asOneRow) { + asOneRow = asOneRow || false; + var displayText = []; + var text = ""; + var rowNr = -1; + + for (var i = 0; i < NR_ROWS; i++) { + var rowText = this.rows[i].getTextString(); + + if (rowText) { + rowNr = i + 1; + + if (asOneRow) { + displayText.push("Row " + rowNr + ": '" + rowText + "'"); + } else { + displayText.push(rowText.trim()); + } + } + } + + if (displayText.length > 0) { + if (asOneRow) { + text = "[" + displayText.join(" | ") + "]"; + } else { + text = displayText.join("\n"); + } + } + + return text; + }; + + _proto5.getTextAndFormat = function getTextAndFormat() { + return this.rows; + }; + + return CaptionScreen; + })(); // var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT']; + + var Cea608Channel = /*#__PURE__*/ (function () { + function Cea608Channel(channelNumber, outputFilter, logger) { + this.chNr = void 0; + this.outputFilter = void 0; + this.mode = void 0; + this.verbose = void 0; + this.displayedMemory = void 0; + this.nonDisplayedMemory = void 0; + this.lastOutputScreen = void 0; + this.currRollUpRow = void 0; + this.writeScreen = void 0; + this.cueStartTime = void 0; + this.logger = void 0; + this.chNr = channelNumber; + this.outputFilter = outputFilter; + this.mode = null; + this.verbose = 0; + this.displayedMemory = new CaptionScreen(logger); + this.nonDisplayedMemory = new CaptionScreen(logger); + this.lastOutputScreen = new CaptionScreen(logger); + this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; + this.writeScreen = this.displayedMemory; + this.mode = null; + this.cueStartTime = null; // Keeps track of where a cue started. + + this.logger = logger; + } + + var _proto6 = Cea608Channel.prototype; + + _proto6.reset = function reset() { + this.mode = null; + this.displayedMemory.reset(); + this.nonDisplayedMemory.reset(); + this.lastOutputScreen.reset(); + this.outputFilter.reset(); + this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; + this.writeScreen = this.displayedMemory; + this.mode = null; + this.cueStartTime = null; + }; + + _proto6.getHandler = function getHandler() { + return this.outputFilter; + }; + + _proto6.setHandler = function setHandler(newHandler) { + this.outputFilter = newHandler; + }; + + _proto6.setPAC = function setPAC(pacData) { + this.writeScreen.setPAC(pacData); + }; + + _proto6.setBkgData = function setBkgData(bkgData) { + this.writeScreen.setBkgData(bkgData); + }; + + _proto6.setMode = function setMode(newMode) { + if (newMode === this.mode) { + return; + } + + this.mode = newMode; + this.logger.log(VerboseLevel.INFO, "MODE=" + newMode); + + if (this.mode === "MODE_POP-ON") { + this.writeScreen = this.nonDisplayedMemory; + } else { + this.writeScreen = this.displayedMemory; + this.writeScreen.reset(); + } + + if (this.mode !== "MODE_ROLL-UP") { + this.displayedMemory.nrRollUpRows = null; + this.nonDisplayedMemory.nrRollUpRows = null; + } + + this.mode = newMode; + }; + + _proto6.insertChars = function insertChars(chars) { + for (var i = 0; i < chars.length; i++) { + this.writeScreen.insertChar(chars[i]); + } + + var screen = this.writeScreen === this.displayedMemory ? "DISP" : "NON_DISP"; + this.logger.log(VerboseLevel.INFO, screen + ": " + this.writeScreen.getDisplayText(true)); + + if (this.mode === "MODE_PAINT-ON" || this.mode === "MODE_ROLL-UP") { + this.logger.log(VerboseLevel.TEXT, "DISPLAYED: " + this.displayedMemory.getDisplayText(true)); + this.outputDataUpdate(); + } + }; + + _proto6.ccRCL = function ccRCL() { + // Resume Caption Loading (switch mode to Pop On) + this.logger.log(VerboseLevel.INFO, "RCL - Resume Caption Loading"); + this.setMode("MODE_POP-ON"); + }; + + _proto6.ccBS = function ccBS() { + // BackSpace + this.logger.log(VerboseLevel.INFO, "BS - BackSpace"); + + if (this.mode === "MODE_TEXT") { + return; + } + + this.writeScreen.backSpace(); + + if (this.writeScreen === this.displayedMemory) { + this.outputDataUpdate(); + } + }; + + _proto6.ccAOF = function ccAOF() { + // Reserved (formerly Alarm Off) + }; + + _proto6.ccAON = function ccAON() { + // Reserved (formerly Alarm On) + }; + + _proto6.ccDER = function ccDER() { + // Delete to End of Row + this.logger.log(VerboseLevel.INFO, "DER- Delete to End of Row"); + this.writeScreen.clearToEndOfRow(); + this.outputDataUpdate(); + }; + + _proto6.ccRU = function ccRU(nrRows) { + // Roll-Up Captions-2,3,or 4 Rows + this.logger.log(VerboseLevel.INFO, "RU(" + nrRows + ") - Roll Up"); + this.writeScreen = this.displayedMemory; + this.setMode("MODE_ROLL-UP"); + this.writeScreen.setRollUpRows(nrRows); + }; + + _proto6.ccFON = function ccFON() { + // Flash On + this.logger.log(VerboseLevel.INFO, "FON - Flash On"); + this.writeScreen.setPen({ + flash: true, + }); + }; + + _proto6.ccRDC = function ccRDC() { + // Resume Direct Captioning (switch mode to PaintOn) + this.logger.log(VerboseLevel.INFO, "RDC - Resume Direct Captioning"); + this.setMode("MODE_PAINT-ON"); + }; + + _proto6.ccTR = function ccTR() { + // Text Restart in text mode (not supported, however) + this.logger.log(VerboseLevel.INFO, "TR"); + this.setMode("MODE_TEXT"); + }; + + _proto6.ccRTD = function ccRTD() { + // Resume Text Display in Text mode (not supported, however) + this.logger.log(VerboseLevel.INFO, "RTD"); + this.setMode("MODE_TEXT"); + }; + + _proto6.ccEDM = function ccEDM() { + // Erase Displayed Memory + this.logger.log(VerboseLevel.INFO, "EDM - Erase Displayed Memory"); + this.displayedMemory.reset(); + this.outputDataUpdate(true); + }; + + _proto6.ccCR = function ccCR() { + // Carriage Return + this.logger.log(VerboseLevel.INFO, "CR - Carriage Return"); + this.writeScreen.rollUp(); + this.outputDataUpdate(true); + }; + + _proto6.ccENM = function ccENM() { + // Erase Non-Displayed Memory + this.logger.log(VerboseLevel.INFO, "ENM - Erase Non-displayed Memory"); + this.nonDisplayedMemory.reset(); + }; + + _proto6.ccEOC = function ccEOC() { + // End of Caption (Flip Memories) + this.logger.log(VerboseLevel.INFO, "EOC - End Of Caption"); + + if (this.mode === "MODE_POP-ON") { + var tmp = this.displayedMemory; + this.displayedMemory = this.nonDisplayedMemory; + this.nonDisplayedMemory = tmp; + this.writeScreen = this.nonDisplayedMemory; + this.logger.log(VerboseLevel.TEXT, "DISP: " + this.displayedMemory.getDisplayText()); + } + + this.outputDataUpdate(true); + }; + + _proto6.ccTO = function ccTO(nrCols) { + // Tab Offset 1,2, or 3 columns + this.logger.log(VerboseLevel.INFO, "TO(" + nrCols + ") - Tab Offset"); + this.writeScreen.moveCursor(nrCols); + }; + + _proto6.ccMIDROW = function ccMIDROW(secondByte) { + // Parse MIDROW command + var styles = { + flash: false, + }; + styles.underline = secondByte % 2 === 1; + styles.italics = secondByte >= 0x2e; + + if (!styles.italics) { + var colorIndex = Math.floor(secondByte / 2) - 0x10; + var colors = ["white", "green", "blue", "cyan", "red", "yellow", "magenta"]; + styles.foreground = colors[colorIndex]; + } else { + styles.foreground = "white"; + } + + this.logger.log(VerboseLevel.INFO, "MIDROW: " + JSON.stringify(styles)); + this.writeScreen.setPen(styles); + }; + + _proto6.outputDataUpdate = function outputDataUpdate(dispatch) { + if (dispatch === void 0) { + dispatch = false; + } + + var time = this.logger.time; + + if (time === null) { + return; + } + + if (this.outputFilter) { + if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) { + // Start of a new cue + this.cueStartTime = time; + } else { + if (!this.displayedMemory.equals(this.lastOutputScreen)) { + this.outputFilter.newCue(this.cueStartTime, time, this.lastOutputScreen); + + if (dispatch && this.outputFilter.dispatchCue) { + this.outputFilter.dispatchCue(); + } + + this.cueStartTime = this.displayedMemory.isEmpty() ? null : time; + } + } + + this.lastOutputScreen.copy(this.displayedMemory); + } + }; + + _proto6.cueSplitAtTime = function cueSplitAtTime(t) { + if (this.outputFilter) { + if (!this.displayedMemory.isEmpty()) { + if (this.outputFilter.newCue) { + this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory); + } + + this.cueStartTime = t; + } + } + }; + + return Cea608Channel; + })(); + + var Cea608Parser = /*#__PURE__*/ (function () { + function Cea608Parser(field, out1, out2) { + this.channels = void 0; + this.currentChannel = 0; + this.cmdHistory = void 0; + this.logger = void 0; + var logger = new CaptionsLogger(); + this.channels = [null, new Cea608Channel(field, out1, logger), new Cea608Channel(field + 1, out2, logger)]; + this.cmdHistory = createCmdHistory(); + this.logger = logger; + } + + var _proto7 = Cea608Parser.prototype; + + _proto7.getHandler = function getHandler(channel) { + return this.channels[channel].getHandler(); + }; + + _proto7.setHandler = function setHandler(channel, newHandler) { + this.channels[channel].setHandler(newHandler); + }; + /** + * Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs. + */ + + _proto7.addData = function addData(time, byteList) { + var cmdFound; + var a; + var b; + var charsFound = false; + this.logger.time = time; + + for (var i = 0; i < byteList.length; i += 2) { + a = byteList[i] & 0x7f; + b = byteList[i + 1] & 0x7f; + + if (a === 0 && b === 0) { + continue; + } else { + this.logger.log(VerboseLevel.DATA, "[" + numArrayToHexArray([byteList[i], byteList[i + 1]]) + "] -> (" + numArrayToHexArray([a, b]) + ")"); + } + + cmdFound = this.parseCmd(a, b); + + if (!cmdFound) { + cmdFound = this.parseMidrow(a, b); + } + + if (!cmdFound) { + cmdFound = this.parsePAC(a, b); + } + + if (!cmdFound) { + cmdFound = this.parseBackgroundAttributes(a, b); + } + + if (!cmdFound) { + charsFound = this.parseChars(a, b); + + if (charsFound) { + var currChNr = this.currentChannel; + + if (currChNr && currChNr > 0) { + var channel = this.channels[currChNr]; + channel.insertChars(charsFound); + } else { + this.logger.log(VerboseLevel.WARNING, "No channel found yet. TEXT-MODE?"); + } + } + } + + if (!cmdFound && !charsFound) { + this.logger.log(VerboseLevel.WARNING, "Couldn't parse cleaned data " + numArrayToHexArray([a, b]) + " orig: " + numArrayToHexArray([byteList[i], byteList[i + 1]])); + } + } + }; + /** + * Parse Command. + * @returns {Boolean} Tells if a command was found + */ + + _proto7.parseCmd = function parseCmd(a, b) { + var cmdHistory = this.cmdHistory; + var cond1 = (a === 0x14 || a === 0x1c || a === 0x15 || a === 0x1d) && b >= 0x20 && b <= 0x2f; + var cond2 = (a === 0x17 || a === 0x1f) && b >= 0x21 && b <= 0x23; + + if (!(cond1 || cond2)) { + return false; + } + + if (hasCmdRepeated(a, b, cmdHistory)) { + setLastCmd(null, null, cmdHistory); + this.logger.log(VerboseLevel.DEBUG, "Repeated command (" + numArrayToHexArray([a, b]) + ") is dropped"); + return true; + } + + var chNr = a === 0x14 || a === 0x15 || a === 0x17 ? 1 : 2; + var channel = this.channels[chNr]; + + if (a === 0x14 || a === 0x15 || a === 0x1c || a === 0x1d) { + if (b === 0x20) { + channel.ccRCL(); + } else if (b === 0x21) { + channel.ccBS(); + } else if (b === 0x22) { + channel.ccAOF(); + } else if (b === 0x23) { + channel.ccAON(); + } else if (b === 0x24) { + channel.ccDER(); + } else if (b === 0x25) { + channel.ccRU(2); + } else if (b === 0x26) { + channel.ccRU(3); + } else if (b === 0x27) { + channel.ccRU(4); + } else if (b === 0x28) { + channel.ccFON(); + } else if (b === 0x29) { + channel.ccRDC(); + } else if (b === 0x2a) { + channel.ccTR(); + } else if (b === 0x2b) { + channel.ccRTD(); + } else if (b === 0x2c) { + channel.ccEDM(); + } else if (b === 0x2d) { + channel.ccCR(); + } else if (b === 0x2e) { + channel.ccENM(); + } else if (b === 0x2f) { + channel.ccEOC(); + } + } else { + // a == 0x17 || a == 0x1F + channel.ccTO(b - 0x20); + } + + setLastCmd(a, b, cmdHistory); + this.currentChannel = chNr; + return true; + }; + /** + * Parse midrow styling command + * @returns {Boolean} + */ + + _proto7.parseMidrow = function parseMidrow(a, b) { + var chNr = 0; + + if ((a === 0x11 || a === 0x19) && b >= 0x20 && b <= 0x2f) { + if (a === 0x11) { + chNr = 1; + } else { + chNr = 2; + } + + if (chNr !== this.currentChannel) { + this.logger.log(VerboseLevel.ERROR, "Mismatch channel in midrow parsing"); + return false; + } + + var channel = this.channels[chNr]; + + if (!channel) { + return false; + } + + channel.ccMIDROW(b); + this.logger.log(VerboseLevel.DEBUG, "MIDROW (" + numArrayToHexArray([a, b]) + ")"); + return true; + } + + return false; + }; + /** + * Parse Preable Access Codes (Table 53). + * @returns {Boolean} Tells if PAC found + */ + + _proto7.parsePAC = function parsePAC(a, b) { + var row; + var cmdHistory = this.cmdHistory; + var case1 = ((a >= 0x11 && a <= 0x17) || (a >= 0x19 && a <= 0x1f)) && b >= 0x40 && b <= 0x7f; + var case2 = (a === 0x10 || a === 0x18) && b >= 0x40 && b <= 0x5f; + + if (!(case1 || case2)) { + return false; + } + + if (hasCmdRepeated(a, b, cmdHistory)) { + setLastCmd(null, null, cmdHistory); + return true; // Repeated commands are dropped (once) + } + + var chNr = a <= 0x17 ? 1 : 2; + + if (b >= 0x40 && b <= 0x5f) { + row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a]; + } else { + // 0x60 <= b <= 0x7F + row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a]; + } + + var channel = this.channels[chNr]; + + if (!channel) { + return false; + } + + channel.setPAC(this.interpretPAC(row, b)); + setLastCmd(a, b, cmdHistory); + this.currentChannel = chNr; + return true; + }; + /** + * Interpret the second byte of the pac, and return the information. + * @returns {Object} pacData with style parameters. + */ + + _proto7.interpretPAC = function interpretPAC(row, _byte3) { + var pacIndex; + var pacData = { + color: null, + italics: false, + indent: null, + underline: false, + row: row, + }; + + if (_byte3 > 0x5f) { + pacIndex = _byte3 - 0x60; + } else { + pacIndex = _byte3 - 0x40; + } + + pacData.underline = (pacIndex & 1) === 1; + + if (pacIndex <= 0xd) { + pacData.color = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "white"][Math.floor(pacIndex / 2)]; + } else if (pacIndex <= 0xf) { + pacData.italics = true; + pacData.color = "white"; + } else { + pacData.indent = Math.floor((pacIndex - 0x10) / 2) * 4; + } + + return pacData; // Note that row has zero offset. The spec uses 1. + }; + /** + * Parse characters. + * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise. + */ + + _proto7.parseChars = function parseChars(a, b) { + var channelNr; + var charCodes = null; + var charCode1 = null; + + if (a >= 0x19) { + channelNr = 2; + charCode1 = a - 8; + } else { + channelNr = 1; + charCode1 = a; + } + + if (charCode1 >= 0x11 && charCode1 <= 0x13) { + // Special character + var oneCode; + + if (charCode1 === 0x11) { + oneCode = b + 0x50; + } else if (charCode1 === 0x12) { + oneCode = b + 0x70; + } else { + oneCode = b + 0x90; + } + + this.logger.log(VerboseLevel.INFO, "Special char '" + getCharForByte(oneCode) + "' in channel " + channelNr); + charCodes = [oneCode]; + } else if (a >= 0x20 && a <= 0x7f) { + charCodes = b === 0 ? [a] : [a, b]; + } + + if (charCodes) { + var hexCodes = numArrayToHexArray(charCodes); + this.logger.log(VerboseLevel.DEBUG, "Char codes = " + hexCodes.join(",")); + setLastCmd(a, b, this.cmdHistory); + } + + return charCodes; + }; + /** + * Parse extended background attributes as well as new foreground color black. + * @returns {Boolean} Tells if background attributes are found + */ + + _proto7.parseBackgroundAttributes = function parseBackgroundAttributes(a, b) { + var case1 = (a === 0x10 || a === 0x18) && b >= 0x20 && b <= 0x2f; + var case2 = (a === 0x17 || a === 0x1f) && b >= 0x2d && b <= 0x2f; + + if (!(case1 || case2)) { + return false; + } + + var index; + var bkgData = {}; + + if (a === 0x10 || a === 0x18) { + index = Math.floor((b - 0x20) / 2); + bkgData.background = backgroundColors[index]; + + if (b % 2 === 1) { + bkgData.background = bkgData.background + "_semi"; + } + } else if (b === 0x2d) { + bkgData.background = "transparent"; + } else { + bkgData.foreground = "black"; + + if (b === 0x2f) { + bkgData.underline = true; + } + } + + var chNr = a <= 0x17 ? 1 : 2; + var channel = this.channels[chNr]; + channel.setBkgData(bkgData); + setLastCmd(a, b, this.cmdHistory); + return true; + }; + /** + * Reset state of parser and its channels. + */ + + _proto7.reset = function reset() { + for (var i = 0; i < Object.keys(this.channels).length; i++) { + var channel = this.channels[i]; + + if (channel) { + channel.reset(); + } + } + + this.cmdHistory = createCmdHistory(); + }; + /** + * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty. + */ + + _proto7.cueSplitAtTime = function cueSplitAtTime(t) { + for (var i = 0; i < this.channels.length; i++) { + var channel = this.channels[i]; + + if (channel) { + channel.cueSplitAtTime(t); + } + } + }; + + return Cea608Parser; + })(); + + function setLastCmd(a, b, cmdHistory) { + cmdHistory.a = a; + cmdHistory.b = b; } - result[trackId] = { - timescale: timescale, - type: type + function hasCmdRepeated(a, b, cmdHistory) { + return cmdHistory.a === a && cmdHistory.b === b; + } + + function createCmdHistory() { + return { + a: null, + b: null, + }; + } + + /* harmony default export */ __webpack_exports__["default"] = Cea608Parser; + + /***/ + }, + + /***/ "./src/utils/codecs.ts": + /*!*****************************!*\ + !*** ./src/utils/codecs.ts ***! + \*****************************/ + /*! exports provided: isCodecType, isCodecSupportedInMp4 */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isCodecType", function () { + return isCodecType; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isCodecSupportedInMp4", function () { + return isCodecSupportedInMp4; + }); + // from http://mp4ra.org/codecs.html + var sampleEntryCodesISO = { + audio: { + a3ds: true, + "ac-3": true, + "ac-4": true, + alac: true, + alaw: true, + dra1: true, + "dts+": true, + "dts-": true, + dtsc: true, + dtse: true, + dtsh: true, + "ec-3": true, + enca: true, + g719: true, + g726: true, + m4ae: true, + mha1: true, + mha2: true, + mhm1: true, + mhm2: true, + mlpa: true, + mp4a: true, + "raw ": true, + Opus: true, + samr: true, + sawb: true, + sawp: true, + sevc: true, + sqcp: true, + ssmv: true, + twos: true, + ulaw: true, + }, + video: { + avc1: true, + avc2: true, + avc3: true, + avc4: true, + avcp: true, + av01: true, + drac: true, + dvav: true, + dvhe: true, + encv: true, + hev1: true, + hvc1: true, + mjp2: true, + mp4v: true, + mvc1: true, + mvc2: true, + mvc3: true, + mvc4: true, + resv: true, + rv60: true, + s263: true, + svc1: true, + svc2: true, + "vc-1": true, + vp08: true, + vp09: true, + }, + text: { + stpp: true, + wvtt: true, + }, }; - result[type] = { - timescale: timescale, - id: trackId, - codec: codec + function isCodecType(codec, type) { + var typeCodes = sampleEntryCodesISO[type]; + return !!typeCodes && typeCodes[codec.slice(0, 4)] === true; + } + function isCodecSupportedInMp4(codec, type) { + return MediaSource.isTypeSupported((type || "video") + '/mp4;codecs="' + codec + '"'); + } + + /***/ + }, + + /***/ "./src/utils/cues.ts": + /*!***************************!*\ + !*** ./src/utils/cues.ts ***! + \***************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts"); + /* harmony import */ var _webvtt_parser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./webvtt-parser */ "./src/utils/webvtt-parser.ts"); + /* harmony import */ var _texttrack_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./texttrack-utils */ "./src/utils/texttrack-utils.ts"); + + var WHITESPACE_CHAR = /\s/; + var Cues = { + newCue: function newCue(track, startTime, endTime, captionScreen) { + var result = []; + var row; // the type data states this is VTTCue, but it can potentially be a TextTrackCue on old browsers + + var cue; + var indenting; + var indent; + var text; + var Cue = self.VTTCue || self.TextTrackCue; + + for (var r = 0; r < captionScreen.rows.length; r++) { + row = captionScreen.rows[r]; + indenting = true; + indent = 0; + text = ""; + + if (!row.isEmpty()) { + for (var c = 0; c < row.chars.length; c++) { + if (WHITESPACE_CHAR.test(row.chars[c].uchar) && indenting) { + indent++; + } else { + text += row.chars[c].uchar; + indenting = false; + } + } // To be used for cleaning-up orphaned roll-up captions + + row.cueStartTime = startTime; // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE + + if (startTime === endTime) { + endTime += 0.0001; + } + + if (indent >= 16) { + indent--; + } else { + indent++; + } + + var cueText = Object(_vttparser__WEBPACK_IMPORTED_MODULE_0__["fixLineBreaks"])(text.trim()); + var id = Object(_webvtt_parser__WEBPACK_IMPORTED_MODULE_1__["generateCueId"])(startTime, endTime, cueText); // If this cue already exists in the track do not push it + + if (!track || !track.cues || !track.cues.getCueById(id)) { + cue = new Cue(startTime, endTime, cueText); + cue.id = id; + cue.line = r + 1; + cue.align = "left"; // Clamp the position between 10 and 80 percent (CEA-608 PAC indent code) + // https://dvcs.w3.org/hg/text-tracks/raw-file/default/608toVTT/608toVTT.html#positioning-in-cea-608 + // Firefox throws an exception and captions break with out of bounds 0-100 values + + cue.position = 10 + Math.min(80, Math.floor((indent * 8) / 32) * 10); + result.push(cue); + } + } + } + + if (track && result.length) { + // Sort bottom cues in reverse order so that they render in line order when overlapping in Chrome + result.sort(function (cueA, cueB) { + if (cueA.line === "auto" || cueB.line === "auto") { + return 0; + } + + if (cueA.line > 8 && cueB.line > 8) { + return cueB.line - cueA.line; + } + + return cueA.line - cueB.line; + }); + result.forEach(function (cue) { + return Object(_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__["addCueToTrack"])(track, cue); + }); + } + + return result; + }, }; - } - } - } - } - } + /* harmony default export */ __webpack_exports__["default"] = Cues; - var trex = findBox(initSegment, ['moov', 'mvex', 'trex']); - trex.forEach(function (trex) { - var trackId = readUint32(trex, 4); - var track = result[trackId]; + /***/ + }, - if (track) { - track.default = { - duration: readUint32(trex, 12), - flags: readUint32(trex, 20) - }; - } - }); - return result; -} -/** - * Determine the base media decode start time, in seconds, for an MP4 - * fragment. If multiple fragments are specified, the earliest time is - * returned. - * - * The base media decode time can be parsed from track fragment - * metadata: - * ``` - * moof > traf > tfdt.baseMediaDecodeTime - * ``` - * It requires the timescale value from the mdhd to interpret. - * - * @param initData {InitData} a hash of track type to timescale values - * @param fmp4 {Uint8Array} the bytes of the mp4 fragment - * @return {number} the earliest base media decode start time for the - * fragment, in seconds - */ + /***/ "./src/utils/discontinuities.ts": + /*!**************************************!*\ + !*** ./src/utils/discontinuities.ts ***! + \**************************************/ + /*! exports provided: findFirstFragWithCC, shouldAlignOnDiscontinuities, findDiscontinuousReferenceFrag, adjustSlidingStart, alignStream, alignPDT, alignFragmentByPDTDelta, alignMediaPlaylistByPDT */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findFirstFragWithCC", function () { + return findFirstFragWithCC; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shouldAlignOnDiscontinuities", function () { + return shouldAlignOnDiscontinuities; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findDiscontinuousReferenceFrag", function () { + return findDiscontinuousReferenceFrag; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "adjustSlidingStart", function () { + return adjustSlidingStart; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignStream", function () { + return alignStream; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignPDT", function () { + return alignPDT; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignFragmentByPDTDelta", function () { + return alignFragmentByPDTDelta; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "alignMediaPlaylistByPDT", function () { + return alignMediaPlaylistByPDT; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts"); + /* harmony import */ var _controller_level_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../controller/level-helper */ "./src/controller/level-helper.ts"); -function getStartDTS(initData, fmp4) { - // we need info from two children of each track fragment box - return findBox(fmp4, ['moof', 'traf']).reduce(function (result, traf) { - var tfdt = findBox(traf, ['tfdt'])[0]; - var version = tfdt.data[tfdt.start]; - var start = findBox(traf, ['tfhd']).reduce(function (result, tfhd) { - // get the track id from the tfhd - var id = readUint32(tfhd, 4); - var track = initData[id]; + function findFirstFragWithCC(fragments, cc) { + var firstFrag = null; - if (track) { - var baseTime = readUint32(tfdt, 4); + for (var i = 0, len = fragments.length; i < len; i++) { + var currentFrag = fragments[i]; - if (version === 1) { - baseTime *= Math.pow(2, 32); - baseTime += readUint32(tfdt, 8); - } // assume a 90kHz clock if no timescale was specified + if (currentFrag && currentFrag.cc === cc) { + firstFrag = currentFrag; + break; + } + } + return firstFrag; + } + function shouldAlignOnDiscontinuities(lastFrag, lastLevel, details) { + if (lastLevel.details) { + if (details.endCC > details.startCC || (lastFrag && lastFrag.cc < details.startCC)) { + return true; + } + } - var scale = track.timescale || 90e3; // convert base time to seconds + return false; + } // Find the first frag in the previous level which matches the CC of the first frag of the new level - var startTime = baseTime / scale; + function findDiscontinuousReferenceFrag(prevDetails, curDetails) { + var prevFrags = prevDetails.fragments; + var curFrags = curDetails.fragments; - if (isFinite(startTime) && (result === null || startTime < result)) { - return startTime; - } - } + if (!curFrags.length || !prevFrags.length) { + _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("No fragments to align"); + return; + } - return result; - }, null); + var prevStartFrag = findFirstFragWithCC(prevFrags, curFrags[0].cc); - if (start !== null && isFinite(start) && (result === null || start < result)) { - return start; - } + if (!prevStartFrag || (prevStartFrag && !prevStartFrag.startPTS)) { + _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("No frag in previous level to align on"); + return; + } - return result; - }, null) || 0; -} -/* + return prevStartFrag; + } + + function adjustFragmentStart(frag, sliding) { + if (frag) { + var start = frag.start + sliding; + frag.start = frag.startPTS = start; + frag.endPTS = start + frag.duration; + } + } + + function adjustSlidingStart(sliding, details) { + // Update segments + var fragments = details.fragments; + + for (var i = 0, len = fragments.length; i < len; i++) { + adjustFragmentStart(fragments[i], sliding); + } // Update LL-CiderHls parts at the end of the playlist + + if (details.fragmentHint) { + adjustFragmentStart(details.fragmentHint, sliding); + } + + details.alignedSliding = true; + } + /** + * Using the parameters of the last level, this function computes PTS' of the new fragments so that they form a + * contiguous stream with the last fragments. + * The PTS of a fragment lets CiderHls.js know where it fits into a stream - by knowing every PTS, we know which fragment to + * download at any given time. PTS is normally computed when the fragment is demuxed, so taking this step saves us time + * and an extra download. + * @param lastFrag + * @param lastLevel + * @param details + */ + + function alignStream(lastFrag, lastLevel, details) { + if (!lastLevel) { + return; + } + + alignDiscontinuities(lastFrag, details, lastLevel); + + if (!details.alignedSliding && lastLevel.details) { + // If the PTS wasn't figured out via discontinuity sequence that means there was no CC increase within the level. + // Aligning via Program Date Time should therefore be reliable, since PDT should be the same within the same + // discontinuity sequence. + alignPDT(details, lastLevel.details); + } + + if (!details.alignedSliding && lastLevel.details && !details.skippedSegments) { + // Try to align on sn so that we pick a better start fragment. + // Do not perform this on playlists with delta updates as this is only to align levels on switch + // and adjustSliding only adjusts fragments after skippedSegments. + Object(_controller_level_helper__WEBPACK_IMPORTED_MODULE_2__["adjustSliding"])(lastLevel.details, details); + } + } + /** + * Computes the PTS if a new level's fragments using the PTS of a fragment in the last level which shares the same + * discontinuity sequence. + * @param lastFrag - The last Fragment which shares the same discontinuity sequence + * @param lastLevel - The details of the last loaded level + * @param details - The details of the new level + */ + + function alignDiscontinuities(lastFrag, details, lastLevel) { + if (shouldAlignOnDiscontinuities(lastFrag, lastLevel, details)) { + var referenceFrag = findDiscontinuousReferenceFrag(lastLevel.details, details); + + if (referenceFrag && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(referenceFrag.start)) { + _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("Adjusting PTS using last level due to CC increase within current level " + details.url); + adjustSlidingStart(referenceFrag.start, details); + } + } + } + /** + * Computes the PTS of a new level's fragments using the difference in Program Date Time from the last level. + * @param details - The details of the new level + * @param lastDetails - The details of the last loaded level + */ + + function alignPDT(details, lastDetails) { + // This check protects the unsafe "!" usage below for null program date time access. + if (!lastDetails.fragments.length || !details.hasProgramDateTime || !lastDetails.hasProgramDateTime) { + return; + } // if last level sliding is 1000 and its first frag PROGRAM-DATE-TIME is 2017-08-20 1:10:00 AM + // and if new details first frag PROGRAM DATE-TIME is 2017-08-20 1:10:08 AM + // then we can deduce that playlist B sliding is 1000+8 = 1008s + + var lastPDT = lastDetails.fragments[0].programDateTime; // hasProgramDateTime check above makes this safe. + + var newPDT = details.fragments[0].programDateTime; // date diff is in ms. frag.start is in seconds + + var sliding = (newPDT - lastPDT) / 1000 + lastDetails.fragments[0].start; + + if (sliding && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(sliding)) { + _logger__WEBPACK_IMPORTED_MODULE_1__["logger"].log("Adjusting PTS using programDateTime delta " + (newPDT - lastPDT) + "ms, sliding:" + sliding.toFixed(3) + " " + details.url + " "); + adjustSlidingStart(sliding, details); + } + } + function alignFragmentByPDTDelta(frag, delta) { + var programDateTime = frag.programDateTime; + if (!programDateTime) return; + var start = (programDateTime - delta) / 1000; + frag.start = frag.startPTS = start; + frag.endPTS = start + frag.duration; + } + /** + * Ensures appropriate time-alignment between renditions based on PDT. Unlike `alignPDT`, which adjusts + * the timeline based on the delta between PDTs of the 0th fragment of two playlists/`LevelDetails`, + * this function assumes the timelines represented in `refDetails` are accurate, including the PDTs, + * and uses the "wallclock"/PDT timeline as a cross-reference to `details`, adjusting the presentation + * times/timelines of `details` accordingly. + * Given the asynchronous nature of fetches and initial loads of live `main` and audio/subtitle tracks, + * the primary purpose of this function is to ensure the "local timelines" of audio/subtitle tracks + * are aligned to the main/video timeline, using PDT as the cross-reference/"anchor" that should + * be consistent across playlists, per the CiderHls spec. + * @param details - The details of the rendition you'd like to time-align (e.g. an audio rendition). + * @param refDetails - The details of the reference rendition with start and PDT times for alignment. + */ + + function alignMediaPlaylistByPDT(details, refDetails) { + // This check protects the unsafe "!" usage below for null program date time access. + if (!refDetails.fragments.length || !details.hasProgramDateTime || !refDetails.hasProgramDateTime) { + return; + } + + var refPDT = refDetails.fragments[0].programDateTime; // hasProgramDateTime check above makes this safe. + + var refStart = refDetails.fragments[0].start; // Use the delta between the reference details' presentation timeline's start time and its PDT + // to align the other rendtion's timeline. + + var delta = refPDT - refStart * 1000; // Per spec: "If any Media Playlist in a Master Playlist contains an EXT-X-PROGRAM-DATE-TIME tag, then all + // Media Playlists in that Master Playlist MUST contain EXT-X-PROGRAM-DATE-TIME tags with consistent mappings + // of date and time to media timestamps." + // So we should be able to use each rendition's PDT as a reference time and use the delta to compute our relevant + // start and end times. + // NOTE: This code assumes each level/details timelines have already been made "internally consistent" + + details.fragments.forEach(function (frag) { + alignFragmentByPDTDelta(frag, delta); + }); + + if (details.fragmentHint) { + alignFragmentByPDTDelta(details.fragmentHint, delta); + } + + details.alignedSliding = true; + } + + /***/ + }, + + /***/ "./src/utils/ewma-bandwidth-estimator.ts": + /*!***********************************************!*\ + !*** ./src/utils/ewma-bandwidth-estimator.ts ***! + \***********************************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _utils_ewma__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/ewma */ "./src/utils/ewma.ts"); + /* + * EWMA Bandwidth Estimator + * - heavily inspired from shaka-player + * Tracks bandwidth samples and estimates available bandwidth. + * Based on the minimum of two exponentially-weighted moving averages with + * different half-lives. + */ + + var EwmaBandWidthEstimator = /*#__PURE__*/ (function () { + function EwmaBandWidthEstimator(slow, fast, defaultEstimate) { + this.defaultEstimate_ = void 0; + this.minWeight_ = void 0; + this.minDelayMs_ = void 0; + this.slow_ = void 0; + this.fast_ = void 0; + this.defaultEstimate_ = defaultEstimate; + this.minWeight_ = 0.001; + this.minDelayMs_ = 50; + this.slow_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow); + this.fast_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast); + } + + var _proto = EwmaBandWidthEstimator.prototype; + + _proto.update = function update(slow, fast) { + var slow_ = this.slow_, + fast_ = this.fast_; + + if (this.slow_.halfLife !== slow) { + this.slow_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow, slow_.getEstimate(), slow_.getTotalWeight()); + } + + if (this.fast_.halfLife !== fast) { + this.fast_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast, fast_.getEstimate(), fast_.getTotalWeight()); + } + }; + + _proto.sample = function sample(durationMs, numBytes) { + durationMs = Math.max(durationMs, this.minDelayMs_); + var numBits = 8 * numBytes; // weight is duration in seconds + + var durationS = durationMs / 1000; // value is bandwidth in bits/s + + var bandwidthInBps = numBits / durationS; + this.fast_.sample(durationS, bandwidthInBps); + this.slow_.sample(durationS, bandwidthInBps); + }; + + _proto.canEstimate = function canEstimate() { + var fast = this.fast_; + return fast && fast.getTotalWeight() >= this.minWeight_; + }; + + _proto.getEstimate = function getEstimate() { + if (this.canEstimate()) { + // console.log('slow estimate:'+ Math.round(this.slow_.getEstimate())); + // console.log('fast estimate:'+ Math.round(this.fast_.getEstimate())); + // Take the minimum of these two estimates. This should have the effect of + // adapting down quickly, but up more slowly. + return Math.min(this.fast_.getEstimate(), this.slow_.getEstimate()); + } else { + return this.defaultEstimate_; + } + }; + + _proto.destroy = function destroy() {}; + + return EwmaBandWidthEstimator; + })(); + + /* harmony default export */ __webpack_exports__["default"] = EwmaBandWidthEstimator; + + /***/ + }, + + /***/ "./src/utils/ewma.ts": + /*!***************************!*\ + !*** ./src/utils/ewma.ts ***! + \***************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* + * compute an Exponential Weighted moving average + * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + * - heavily inspired from shaka-player + */ + var EWMA = /*#__PURE__*/ (function () { + // About half of the estimated value will be from the last |halfLife| samples by weight. + function EWMA(halfLife, estimate, weight) { + if (estimate === void 0) { + estimate = 0; + } + + if (weight === void 0) { + weight = 0; + } + + this.halfLife = void 0; + this.alpha_ = void 0; + this.estimate_ = void 0; + this.totalWeight_ = void 0; + this.halfLife = halfLife; // Larger values of alpha expire historical data more slowly. + + this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0; + this.estimate_ = estimate; + this.totalWeight_ = weight; + } + + var _proto = EWMA.prototype; + + _proto.sample = function sample(weight, value) { + var adjAlpha = Math.pow(this.alpha_, weight); + this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_; + this.totalWeight_ += weight; + }; + + _proto.getTotalWeight = function getTotalWeight() { + return this.totalWeight_; + }; + + _proto.getEstimate = function getEstimate() { + if (this.alpha_) { + var zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_); + + if (zeroFactor) { + return this.estimate_ / zeroFactor; + } + } + + return this.estimate_; + }; + + return EWMA; + })(); + + /* harmony default export */ __webpack_exports__["default"] = EWMA; + + /***/ + }, + + /***/ "./src/utils/fetch-loader.ts": + /*!***********************************!*\ + !*** ./src/utils/fetch-loader.ts ***! + \***********************************/ + /*! exports provided: fetchSupported, default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fetchSupported", function () { + return fetchSupported; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/load-stats */ "./src/loader/load-stats.ts"); + /* harmony import */ var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/chunk-cache */ "./src/demux/chunk-cache.ts"); + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + _setPrototypeOf(subClass, superClass); + } + + function _wrapNativeSuper(Class) { + var _cache = typeof Map === "function" ? new Map() : undefined; + _wrapNativeSuper = function _wrapNativeSuper(Class) { + if (Class === null || !_isNativeFunction(Class)) return Class; + if (typeof Class !== "function") { + throw new TypeError("Super expression must either be null or a function"); + } + if (typeof _cache !== "undefined") { + if (_cache.has(Class)) return _cache.get(Class); + _cache.set(Class, Wrapper); + } + function Wrapper() { + return _construct(Class, arguments, _getPrototypeOf(this).constructor); + } + Wrapper.prototype = Object.create(Class.prototype, { + constructor: { + value: Wrapper, + enumerable: false, + writable: true, + configurable: true, + }, + }); + return _setPrototypeOf(Wrapper, Class); + }; + return _wrapNativeSuper(Class); + } + + function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; + } else { + _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) _setPrototypeOf(instance, Class.prototype); + return instance; + }; + } + return _construct.apply(null, arguments); + } + + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + return true; + } catch (e) { + return false; + } + } + + function _isNativeFunction(fn) { + return Function.toString.call(fn).indexOf("[native code]") !== -1; + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + return _setPrototypeOf(o, p); + } + + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf + ? Object.getPrototypeOf + : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } + + function _extends() { + _extends = + Object.assign || + function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); + } + + function fetchSupported() { + if ( + // @ts-ignore + self.fetch && + self.AbortController && + self.ReadableStream && + self.Request + ) { + try { + new self.ReadableStream({}); // eslint-disable-line no-new + + return true; + } catch (e) { + /* noop */ + } + } + + return false; + } + + var FetchLoader = /*#__PURE__*/ (function () { + function FetchLoader( + config + /* CiderHlsConfig */ + ) { + this.fetchSetup = void 0; + this.requestTimeout = void 0; + this.request = void 0; + this.response = void 0; + this.controller = void 0; + this.context = void 0; + this.config = null; + this.callbacks = null; + this.stats = void 0; + this.loader = null; + this.fetchSetup = config.fetchSetup || getRequest; + this.controller = new self.AbortController(); + this.stats = new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__["LoadStats"](); + } + + var _proto = FetchLoader.prototype; + + _proto.destroy = function destroy() { + this.loader = this.callbacks = null; + this.abortInternal(); + }; + + _proto.abortInternal = function abortInternal() { + var response = this.response; + + if (!response || !response.ok) { + this.stats.aborted = true; + this.controller.abort(); + } + }; + + _proto.abort = function abort() { + var _this$callbacks; + + this.abortInternal(); + + if ((_this$callbacks = this.callbacks) !== null && _this$callbacks !== void 0 && _this$callbacks.onAbort) { + this.callbacks.onAbort(this.stats, this.context, this.response); + } + }; + + _proto.load = function load(context, config, callbacks) { + var _this = this; + + var stats = this.stats; + + if (stats.loading.start) { + throw new Error("Loader can only be used once."); + } + + stats.loading.start = self.performance.now(); + var initParams = getRequestParameters(context, this.controller.signal); + var onProgress = callbacks.onProgress; + var isArrayBuffer = context.responseType === "arraybuffer"; + var LENGTH = isArrayBuffer ? "byteLength" : "length"; + this.context = context; + this.config = config; + this.callbacks = callbacks; + this.request = this.fetchSetup(context, initParams); + self.clearTimeout(this.requestTimeout); + this.requestTimeout = self.setTimeout(function () { + _this.abortInternal(); + + callbacks.onTimeout(stats, context, _this.response); + }, config.timeout); + self + .fetch(this.request) + .then(function (response) { + _this.response = _this.loader = response; + + if (!response.ok) { + var status = response.status, + statusText = response.statusText; + throw new FetchError(statusText || "fetch, bad network response", status, response); + } + + stats.loading.first = Math.max(self.performance.now(), stats.loading.start); + stats.total = parseInt(response.headers.get("Content-Length") || "0"); + + if (onProgress && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(config.highWaterMark)) { + return _this.loadProgressively(response, stats, context, config.highWaterMark, onProgress); + } + + if (isArrayBuffer) { + return response.arrayBuffer(); + } + + return response.text(); + }) + .then(function (responseData) { + var response = _this.response; + self.clearTimeout(_this.requestTimeout); + stats.loading.end = Math.max(self.performance.now(), stats.loading.first); + stats.loaded = stats.total = responseData[LENGTH]; + var loaderResponse = { + url: response.url, + data: responseData, + }; + + if (onProgress && !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(config.highWaterMark)) { + onProgress(stats, context, responseData, response); + } + + callbacks.onSuccess(loaderResponse, stats, context, response); + }) + .catch(function (error) { + self.clearTimeout(_this.requestTimeout); + + if (stats.aborted) { + return; + } // CORS errors result in an undefined code. Set it to 0 here to align with XHR's behavior + + var code = error.code || 0; + callbacks.onError( + { + code: code, + text: error.message, + }, + context, + error.details + ); + }); + }; + + _proto.getCacheAge = function getCacheAge() { + var result = null; + + if (this.response) { + var ageHeader = this.response.headers.get("age"); + result = ageHeader ? parseFloat(ageHeader) : null; + } + + return result; + }; + + _proto.loadProgressively = function loadProgressively(response, stats, context, highWaterMark, onProgress) { + if (highWaterMark === void 0) { + highWaterMark = 0; + } + + var chunkCache = new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__["default"](); + var reader = response.body.getReader(); + + var pump = function pump() { + return reader + .read() + .then(function (data) { + if (data.done) { + if (chunkCache.dataLength) { + onProgress(stats, context, chunkCache.flush(), response); + } + + return Promise.resolve(new ArrayBuffer(0)); + } + + var chunk = data.value; + var len = chunk.length; + stats.loaded += len; + + if (len < highWaterMark || chunkCache.dataLength) { + // The current chunk is too small to to be emitted or the cache already has data + // Push it to the cache + chunkCache.push(chunk); + + if (chunkCache.dataLength >= highWaterMark) { + // flush in order to join the typed arrays + onProgress(stats, context, chunkCache.flush(), response); + } + } else { + // If there's nothing cached already, and the chache is large enough + // just emit the progress event + onProgress(stats, context, chunk, response); + } + + return pump(); + }) + .catch(function () { + /* aborted */ + return Promise.reject(); + }); + }; + + return pump(); + }; + + return FetchLoader; + })(); + + function getRequestParameters(context, signal) { + var initParams = { + method: "GET", + mode: "cors", + credentials: "same-origin", + signal: signal, + headers: new self.Headers(_extends({}, context.headers)), + }; + + if (context.rangeEnd) { + initParams.headers.set("Range", "bytes=" + context.rangeStart + "-" + String(context.rangeEnd - 1)); + } + + return initParams; + } + + function getRequest(context, initParams) { + return new self.Request(context.url, initParams); + } + + var FetchError = /*#__PURE__*/ (function (_Error) { + _inheritsLoose(FetchError, _Error); + + function FetchError(message, code, details) { + var _this2; + + _this2 = _Error.call(this, message) || this; + _this2.code = void 0; + _this2.details = void 0; + _this2.code = code; + _this2.details = details; + return _this2; + } + + return FetchError; + })(/*#__PURE__*/ _wrapNativeSuper(Error)); + + /* harmony default export */ __webpack_exports__["default"] = FetchLoader; + + /***/ + }, + + /***/ "./src/utils/imsc1-ttml-parser.ts": + /*!****************************************!*\ + !*** ./src/utils/imsc1-ttml-parser.ts ***! + \****************************************/ + /*! exports provided: IMSC1_CODEC, parseIMSC1 */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IMSC1_CODEC", function () { + return IMSC1_CODEC; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseIMSC1", function () { + return parseIMSC1; + }); + /* harmony import */ var _mp4_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mp4-tools */ "./src/utils/mp4-tools.ts"); + /* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts"); + /* harmony import */ var _vttcue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./vttcue */ "./src/utils/vttcue.ts"); + /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); + /* harmony import */ var _timescale_conversion__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./timescale-conversion */ "./src/utils/timescale-conversion.ts"); + /* harmony import */ var _webvtt_parser__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./webvtt-parser */ "./src/utils/webvtt-parser.ts"); + function _extends() { + _extends = + Object.assign || + function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); + } + + var IMSC1_CODEC = "stpp.ttml.im1t"; // Time format: h:m:s:frames(.subframes) + + var HMSF_REGEX = /^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/; // Time format: hours, minutes, seconds, milliseconds, frames, ticks + + var TIME_UNIT_REGEX = /^(\d*(?:\.\d*)?)(h|m|s|ms|f|t)$/; + var textAlignToLineAlign = { + left: "start", + center: "center", + right: "end", + start: "start", + end: "end", + }; + function parseIMSC1(payload, initPTS, timescale, callBack, errorCallBack) { + var results = Object(_mp4_tools__WEBPACK_IMPORTED_MODULE_0__["findBox"])(new Uint8Array(payload), ["mdat"]); + + if (results.length === 0) { + errorCallBack(new Error("Could not parse IMSC1 mdat")); + return; + } + + var mdat = results[0]; + var ttml = Object(_demux_id3__WEBPACK_IMPORTED_MODULE_3__["utf8ArrayToStr"])(new Uint8Array(payload, mdat.start, mdat.end - mdat.start)); + var syncTime = Object(_timescale_conversion__WEBPACK_IMPORTED_MODULE_4__["toTimescaleFromScale"])(initPTS, 1, timescale); + + try { + callBack(parseTTML(ttml, syncTime)); + } catch (error) { + errorCallBack(error); + } + } + + function parseTTML(ttml, syncTime) { + var parser = new DOMParser(); + var xmlDoc = parser.parseFromString(ttml, "text/xml"); + var tt = xmlDoc.getElementsByTagName("tt")[0]; + + if (!tt) { + throw new Error("Invalid ttml"); + } + + var defaultRateInfo = { + frameRate: 30, + subFrameRate: 1, + frameRateMultiplier: 0, + tickRate: 0, + }; + var rateInfo = Object.keys(defaultRateInfo).reduce(function (result, key) { + result[key] = tt.getAttribute("ttp:" + key) || defaultRateInfo[key]; + return result; + }, {}); + var trim = tt.getAttribute("xml:space") !== "preserve"; + var styleElements = collectionToDictionary(getElementCollection(tt, "styling", "style")); + var regionElements = collectionToDictionary(getElementCollection(tt, "layout", "region")); + var cueElements = getElementCollection(tt, "body", "[begin]"); + return [].map + .call(cueElements, function (cueElement) { + var cueText = getTextContent(cueElement, trim); + + if (!cueText || !cueElement.hasAttribute("begin")) { + return null; + } + + var startTime = parseTtmlTime(cueElement.getAttribute("begin"), rateInfo); + var duration = parseTtmlTime(cueElement.getAttribute("dur"), rateInfo); + var endTime = parseTtmlTime(cueElement.getAttribute("end"), rateInfo); + + if (startTime === null) { + throw timestampParsingError(cueElement); + } + + if (endTime === null) { + if (duration === null) { + throw timestampParsingError(cueElement); + } + + endTime = startTime + duration; + } + + var cue = new _vttcue__WEBPACK_IMPORTED_MODULE_2__["default"](startTime - syncTime, endTime - syncTime, cueText); + cue.id = Object(_webvtt_parser__WEBPACK_IMPORTED_MODULE_5__["generateCueId"])(cue.startTime, cue.endTime, cue.text); + var region = regionElements[cueElement.getAttribute("region")]; + var style = styleElements[cueElement.getAttribute("style")]; // TODO: Add regions to track and cue (origin and extend) + // These values are hard-coded (for now) to simulate region settings in the demo + + cue.position = 10; + cue.size = 80; // Apply styles to cue + + var styles = getTtmlStyles(region, style); + var textAlign = styles.textAlign; + + if (textAlign) { + // cue.positionAlign not settable in FF~2016 + var lineAlign = textAlignToLineAlign[textAlign]; + + if (lineAlign) { + cue.lineAlign = lineAlign; + } + + cue.align = textAlign; + } + + _extends(cue, styles); + + return cue; + }) + .filter(function (cue) { + return cue !== null; + }); + } + + function getElementCollection(fromElement, parentName, childName) { + var parent = fromElement.getElementsByTagName(parentName)[0]; + + if (parent) { + return [].slice.call(parent.querySelectorAll(childName)); + } + + return []; + } + + function collectionToDictionary(elementsWithId) { + return elementsWithId.reduce(function (dict, element) { + var id = element.getAttribute("xml:id"); + + if (id) { + dict[id] = element; + } + + return dict; + }, {}); + } + + function getTextContent(element, trim) { + return [].slice.call(element.childNodes).reduce(function (str, node, i) { + var _node$childNodes; + + if (node.nodeName === "br" && i) { + return str + "\n"; + } + + if ((_node$childNodes = node.childNodes) !== null && _node$childNodes !== void 0 && _node$childNodes.length) { + return getTextContent(node, trim); + } else if (trim) { + return str + node.textContent.trim().replace(/\s+/g, " "); + } + + return str + node.textContent; + }, ""); + } + + function getTtmlStyles(region, style) { + var ttsNs = "http://www.w3.org/ns/ttml#styling"; + var styleAttributes = [ + "displayAlign", + "textAlign", + "color", + "backgroundColor", + "fontSize", + "fontFamily", // 'fontWeight', + // 'lineHeight', + // 'wrapOption', + // 'fontStyle', + // 'direction', + // 'writingMode' + ]; + return styleAttributes.reduce(function (styles, name) { + var value = getAttributeNS(style, ttsNs, name) || getAttributeNS(region, ttsNs, name); + + if (value) { + styles[name] = value; + } + + return styles; + }, {}); + } + + function getAttributeNS(element, ns, name) { + return element.hasAttributeNS(ns, name) ? element.getAttributeNS(ns, name) : null; + } + + function timestampParsingError(node) { + return new Error("Could not parse ttml timestamp " + node); + } + + function parseTtmlTime(timeAttributeValue, rateInfo) { + if (!timeAttributeValue) { + return null; + } + + var seconds = Object(_vttparser__WEBPACK_IMPORTED_MODULE_1__["parseTimeStamp"])(timeAttributeValue); + + if (seconds === null) { + if (HMSF_REGEX.test(timeAttributeValue)) { + seconds = parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo); + } else if (TIME_UNIT_REGEX.test(timeAttributeValue)) { + seconds = parseTimeUnits(timeAttributeValue, rateInfo); + } + } + + return seconds; + } + + function parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo) { + var m = HMSF_REGEX.exec(timeAttributeValue); + var frames = (m[4] | 0) + (m[5] | 0) / rateInfo.subFrameRate; + return (m[1] | 0) * 3600 + (m[2] | 0) * 60 + (m[3] | 0) + frames / rateInfo.frameRate; + } + + function parseTimeUnits(timeAttributeValue, rateInfo) { + var m = TIME_UNIT_REGEX.exec(timeAttributeValue); + var value = Number(m[1]); + var unit = m[2]; + + switch (unit) { + case "h": + return value * 3600; + + case "m": + return value * 60; + + case "ms": + return value * 1000; + + case "f": + return value / rateInfo.frameRate; + + case "t": + return value / rateInfo.tickRate; + } + + return value; + } + + /***/ + }, + + /***/ "./src/utils/logger.ts": + /*!*****************************!*\ + !*** ./src/utils/logger.ts ***! + \*****************************/ + /*! exports provided: enableLogs, logger */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableLogs", function () { + return enableLogs; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logger", function () { + return logger; + }); + var noop = function noop() {}; + + var fakeLogger = { + trace: noop, + debug: noop, + log: noop, + warn: noop, + info: noop, + error: noop, + }; + var exportedLogger = fakeLogger; // let lastCallTime; + // function formatMsgWithTimeInfo(type, msg) { + // const now = Date.now(); + // const diff = lastCallTime ? '+' + (now - lastCallTime) : '0'; + // lastCallTime = now; + // msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )'; + // return msg; + // } + + function consolePrintFn(type) { + var func = self.console[type]; + + if (func) { + return func.bind(self.console, "[" + type + "] >"); + } + + return noop; + } + + function exportLoggerFunctions(debugConfig) { + for (var _len = arguments.length, functions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + functions[_key - 1] = arguments[_key]; + } + + functions.forEach(function (type) { + exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type); + }); + } + + function enableLogs(debugConfig) { + // check that console is available + if ((self.console && debugConfig === true) || typeof debugConfig === "object") { + exportLoggerFunctions( + debugConfig, // Remove out from list here to hard-disable a log-level + // 'trace', + "debug", + "log", + "info", + "warn", + "error" + ); // Some browsers don't allow to use bind on console object anyway + // fallback to default if needed + + try { + exportedLogger.log(); + } catch (e) { + exportedLogger = fakeLogger; + } + } else { + exportedLogger = fakeLogger; + } + } + var logger = exportedLogger; + + /***/ + }, + + /***/ "./src/utils/mediakeys-helper.ts": + /*!***************************************!*\ + !*** ./src/utils/mediakeys-helper.ts ***! + \***************************************/ + /*! exports provided: KeySystems, requestMediaKeySystemAccess */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeySystems", function () { + return KeySystems; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "requestMediaKeySystemAccess", function () { + return requestMediaKeySystemAccess; + }); + /** + * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess + */ + var KeySystems; + + (function (KeySystems) { + KeySystems["WIDEVINE"] = "com.widevine.alpha"; + KeySystems["PLAYREADY"] = "com.microsoft.playready"; + })(KeySystems || (KeySystems = {})); + + var requestMediaKeySystemAccess = (function () { + if (typeof self !== "undefined" && self.navigator && self.navigator.requestMediaKeySystemAccess) { + return self.navigator.requestMediaKeySystemAccess.bind(self.navigator); + } else { + return null; + } + })(); + + /***/ + }, + + /***/ "./src/utils/mediasource-helper.ts": + /*!*****************************************!*\ + !*** ./src/utils/mediasource-helper.ts ***! + \*****************************************/ + /*! exports provided: getMediaSource */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getMediaSource", function () { + return getMediaSource; + }); + /** + * MediaSource helper + */ + function getMediaSource() { + return self.MediaSource || self.WebKitMediaSource; + } + + /***/ + }, + + /***/ "./src/utils/mp4-tools.ts": + /*!********************************!*\ + !*** ./src/utils/mp4-tools.ts ***! + \********************************/ + /*! exports provided: bin2str, readUint16, readUint32, writeUint32, findBox, parseSegmentIndex, parseInitSegment, getStartDTS, getDuration, computeRawDurationFromSamples, offsetStartDTS, segmentValidRange, appendUint8Array */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bin2str", function () { + return bin2str; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readUint16", function () { + return readUint16; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readUint32", function () { + return readUint32; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writeUint32", function () { + return writeUint32; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findBox", function () { + return findBox; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseSegmentIndex", function () { + return parseSegmentIndex; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseInitSegment", function () { + return parseInitSegment; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getStartDTS", function () { + return getStartDTS; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDuration", function () { + return getDuration; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "computeRawDurationFromSamples", function () { + return computeRawDurationFromSamples; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "offsetStartDTS", function () { + return offsetStartDTS; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "segmentValidRange", function () { + return segmentValidRange; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "appendUint8Array", function () { + return appendUint8Array; + }); + /* harmony import */ var _typed_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./typed-array */ "./src/utils/typed-array.ts"); + /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts"); + + var UINT32_MAX = Math.pow(2, 32) - 1; + var push = [].push; + function bin2str(data) { + return String.fromCharCode.apply(null, data); + } + function readUint16(buffer, offset) { + if ("data" in buffer) { + offset += buffer.start; + buffer = buffer.data; + } + + var val = (buffer[offset] << 8) | buffer[offset + 1]; + return val < 0 ? 65536 + val : val; + } + function readUint32(buffer, offset) { + if ("data" in buffer) { + offset += buffer.start; + buffer = buffer.data; + } + + var val = (buffer[offset] << 24) | (buffer[offset + 1] << 16) | (buffer[offset + 2] << 8) | buffer[offset + 3]; + return val < 0 ? 4294967296 + val : val; + } + function writeUint32(buffer, offset, value) { + if ("data" in buffer) { + offset += buffer.start; + buffer = buffer.data; + } + + buffer[offset] = value >> 24; + buffer[offset + 1] = (value >> 16) & 0xff; + buffer[offset + 2] = (value >> 8) & 0xff; + buffer[offset + 3] = value & 0xff; + } // Find the data for a box specified by its path + + function findBox(input, path) { + var results = []; + + if (!path.length) { + // short-circuit the search for empty paths + return results; + } + + var data; + var start; + var end; + + if ("data" in input) { + data = input.data; + start = input.start; + end = input.end; + } else { + data = input; + start = 0; + end = data.byteLength; + } + + for (var i = start; i < end; ) { + var size = readUint32(data, i); + var type = bin2str(data.subarray(i + 4, i + 8)); + var endbox = size > 1 ? i + size : end; + + if (type === path[0]) { + if (path.length === 1) { + // this is the end of the path and we've found the box we were + // looking for + results.push({ + data: data, + start: i + 8, + end: endbox, + }); + } else { + // recursively search for the next box along the path + var subresults = findBox( + { + data: data, + start: i + 8, + end: endbox, + }, + path.slice(1) + ); + + if (subresults.length) { + push.apply(results, subresults); + } + } + } + + i = endbox; + } // we've finished searching all of data + + return results; + } + function parseSegmentIndex(initSegment) { + var moovBox = findBox(initSegment, ["moov"]); + var moov = moovBox[0]; + var moovEndOffset = moov ? moov.end : null; // we need this in case we need to chop of garbage of the end of current data + + var sidxBox = findBox(initSegment, ["sidx"]); + + if (!sidxBox || !sidxBox[0]) { + return null; + } + + var references = []; + var sidx = sidxBox[0]; + var version = sidx.data[0]; // set initial offset, we skip the reference ID (not needed) + + var index = version === 0 ? 8 : 16; + var timescale = readUint32(sidx, index); + index += 4; // TODO: parse earliestPresentationTime and firstOffset + // usually zero in our case + + var earliestPresentationTime = 0; + var firstOffset = 0; + + if (version === 0) { + index += 8; + } else { + index += 16; + } // skip reserved + + index += 2; + var startByte = sidx.end + firstOffset; + var referencesCount = readUint16(sidx, index); + index += 2; + + for (var i = 0; i < referencesCount; i++) { + var referenceIndex = index; + var referenceInfo = readUint32(sidx, referenceIndex); + referenceIndex += 4; + var referenceSize = referenceInfo & 0x7fffffff; + var referenceType = (referenceInfo & 0x80000000) >>> 31; + + if (referenceType === 1) { + // eslint-disable-next-line no-console + console.warn("SIDX has hierarchical references (not supported)"); + return null; + } + + var subsegmentDuration = readUint32(sidx, referenceIndex); + referenceIndex += 4; + references.push({ + referenceSize: referenceSize, + subsegmentDuration: subsegmentDuration, + // unscaled + info: { + duration: subsegmentDuration / timescale, + start: startByte, + end: startByte + referenceSize - 1, + }, + }); + startByte += referenceSize; // Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits + // for |sapDelta|. + + referenceIndex += 4; // skip to next ref + + index = referenceIndex; + } + + return { + earliestPresentationTime: earliestPresentationTime, + timescale: timescale, + version: version, + referencesCount: referencesCount, + references: references, + moovEndOffset: moovEndOffset, + }; + } + /** + * Parses an MP4 initialization segment and extracts stream type and + * timescale values for any declared tracks. Timescale values indicate the + * number of clock ticks per second to assume for time-based values + * elsewhere in the MP4. + * + * To determine the start time of an MP4, you need two pieces of + * information: the timescale unit and the earliest base media decode + * time. Multiple timescales can be specified within an MP4 but the + * base media decode time is always expressed in the timescale from + * the media header box for the track: + * ``` + * moov > trak > mdia > mdhd.timescale + * moov > trak > mdia > hdlr + * ``` + * @param initSegment {Uint8Array} the bytes of the init segment + * @return {InitData} a hash of track type to timescale values or null if + * the init segment is malformed. + */ + + function parseInitSegment(initSegment) { + var result = []; + var traks = findBox(initSegment, ["moov", "trak"]); + + for (var i = 0; i < traks.length; i++) { + var trak = traks[i]; + var tkhd = findBox(trak, ["tkhd"])[0]; + + if (tkhd) { + var version = tkhd.data[tkhd.start]; + + var _index = version === 0 ? 12 : 20; + + var trackId = readUint32(tkhd, _index); + var mdhd = findBox(trak, ["mdia", "mdhd"])[0]; + + if (mdhd) { + version = mdhd.data[mdhd.start]; + _index = version === 0 ? 12 : 20; + var timescale = readUint32(mdhd, _index); + var hdlr = findBox(trak, ["mdia", "hdlr"])[0]; + + if (hdlr) { + var hdlrType = bin2str(hdlr.data.subarray(hdlr.start + 8, hdlr.start + 12)); + var type = { + soun: _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].AUDIO, + vide: _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].VIDEO, + }[hdlrType]; + + if (type) { + // Parse codec details + var stsd = findBox(trak, ["mdia", "minf", "stbl", "stsd"])[0]; + var codec = void 0; + + if (stsd) { + codec = bin2str(stsd.data.subarray(stsd.start + 12, stsd.start + 16)); // TODO: Parse codec details to be able to build MIME type. + // stsd.start += 8; + // const codecBox = findBox(stsd, [codec])[0]; + // if (codecBox) { + // TODO: Codec parsing support for avc1, mp4a, hevc, av01... + // } + } + + result[trackId] = { + timescale: timescale, + type: type, + }; + result[type] = { + timescale: timescale, + id: trackId, + codec: codec, + }; + } + } + } + } + } + + var trex = findBox(initSegment, ["moov", "mvex", "trex"]); + trex.forEach(function (trex) { + var trackId = readUint32(trex, 4); + var track = result[trackId]; + + if (track) { + track.default = { + duration: readUint32(trex, 12), + flags: readUint32(trex, 20), + }; + } + }); + return result; + } + /** + * Determine the base media decode start time, in seconds, for an MP4 + * fragment. If multiple fragments are specified, the earliest time is + * returned. + * + * The base media decode time can be parsed from track fragment + * metadata: + * ``` + * moof > traf > tfdt.baseMediaDecodeTime + * ``` + * It requires the timescale value from the mdhd to interpret. + * + * @param initData {InitData} a hash of track type to timescale values + * @param fmp4 {Uint8Array} the bytes of the mp4 fragment + * @return {number} the earliest base media decode start time for the + * fragment, in seconds + */ + + function getStartDTS(initData, fmp4) { + // we need info from two children of each track fragment box + return ( + findBox(fmp4, ["moof", "traf"]).reduce(function (result, traf) { + var tfdt = findBox(traf, ["tfdt"])[0]; + var version = tfdt.data[tfdt.start]; + var start = findBox(traf, ["tfhd"]).reduce(function (result, tfhd) { + // get the track id from the tfhd + var id = readUint32(tfhd, 4); + var track = initData[id]; + + if (track) { + var baseTime = readUint32(tfdt, 4); + + if (version === 1) { + baseTime *= Math.pow(2, 32); + baseTime += readUint32(tfdt, 8); + } // assume a 90kHz clock if no timescale was specified + + var scale = track.timescale || 90e3; // convert base time to seconds + + var startTime = baseTime / scale; + + if (isFinite(startTime) && (result === null || startTime < result)) { + return startTime; + } + } + + return result; + }, null); + + if (start !== null && isFinite(start) && (result === null || start < result)) { + return start; + } + + return result; + }, null) || 0 + ); + } + /* For Reference: aligned(8) class TrackFragmentHeaderBox extends FullBox(‘tfhd’, 0, tf_flags){ @@ -25999,81 +27299,80 @@ function getStartDTS(initData, fmp4) { } */ -function getDuration(data, initData) { - var rawDuration = 0; - var videoDuration = 0; - var audioDuration = 0; - var trafs = findBox(data, ['moof', 'traf']); + function getDuration(data, initData) { + var rawDuration = 0; + var videoDuration = 0; + var audioDuration = 0; + var trafs = findBox(data, ["moof", "traf"]); - for (var i = 0; i < trafs.length; i++) { - var traf = trafs[i]; // There is only one tfhd & trun per traf - // This is true for CMAF style content, and we should perhaps check the ftyp - // and only look for a single trun then, but for ISOBMFF we should check - // for multiple track runs. + for (var i = 0; i < trafs.length; i++) { + var traf = trafs[i]; // There is only one tfhd & trun per traf + // This is true for CMAF style content, and we should perhaps check the ftyp + // and only look for a single trun then, but for ISOBMFF we should check + // for multiple track runs. - var tfhd = findBox(traf, ['tfhd'])[0]; // get the track id from the tfhd + var tfhd = findBox(traf, ["tfhd"])[0]; // get the track id from the tfhd - var id = readUint32(tfhd, 4); - var track = initData[id]; + var id = readUint32(tfhd, 4); + var track = initData[id]; - if (!track) { - continue; - } + if (!track) { + continue; + } - var trackDefault = track.default; - var tfhdFlags = readUint32(tfhd, 0) | (trackDefault === null || trackDefault === void 0 ? void 0 : trackDefault.flags); - var sampleDuration = trackDefault === null || trackDefault === void 0 ? void 0 : trackDefault.duration; + var trackDefault = track.default; + var tfhdFlags = readUint32(tfhd, 0) | (trackDefault === null || trackDefault === void 0 ? void 0 : trackDefault.flags); + var sampleDuration = trackDefault === null || trackDefault === void 0 ? void 0 : trackDefault.duration; - if (tfhdFlags & 0x000008) { - // 0x000008 indicates the presence of the default_sample_duration field - if (tfhdFlags & 0x000002) { - // 0x000002 indicates the presence of the sample_description_index field, which precedes default_sample_duration - // If present, the default_sample_duration exists at byte offset 12 - sampleDuration = readUint32(tfhd, 12); - } else { - // Otherwise, the duration is at byte offset 8 - sampleDuration = readUint32(tfhd, 8); - } - } // assume a 90kHz clock if no timescale was specified + if (tfhdFlags & 0x000008) { + // 0x000008 indicates the presence of the default_sample_duration field + if (tfhdFlags & 0x000002) { + // 0x000002 indicates the presence of the sample_description_index field, which precedes default_sample_duration + // If present, the default_sample_duration exists at byte offset 12 + sampleDuration = readUint32(tfhd, 12); + } else { + // Otherwise, the duration is at byte offset 8 + sampleDuration = readUint32(tfhd, 8); + } + } // assume a 90kHz clock if no timescale was specified + var timescale = track.timescale || 90e3; + var truns = findBox(traf, ["trun"]); - var timescale = track.timescale || 90e3; - var truns = findBox(traf, ['trun']); + for (var j = 0; j < truns.length; j++) { + if (sampleDuration) { + var sampleCount = readUint32(truns[j], 4); + rawDuration = sampleDuration * sampleCount; + } else { + rawDuration = computeRawDurationFromSamples(truns[j]); + } - for (var j = 0; j < truns.length; j++) { - if (sampleDuration) { - var sampleCount = readUint32(truns[j], 4); - rawDuration = sampleDuration * sampleCount; - } else { - rawDuration = computeRawDurationFromSamples(truns[j]); - } + if (track.type === _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].VIDEO) { + videoDuration += rawDuration / timescale; + } else if (track.type === _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].AUDIO) { + audioDuration += rawDuration / timescale; + } + } + } - if (track.type === _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].VIDEO) { - videoDuration += rawDuration / timescale; - } else if (track.type === _loader_fragment__WEBPACK_IMPORTED_MODULE_1__["ElementaryStreamTypes"].AUDIO) { - audioDuration += rawDuration / timescale; - } - } - } + if (videoDuration === 0 && audioDuration === 0) { + // If duration samples are not available in the traf use sidx subsegment_duration + var sidx = parseSegmentIndex(data); - if (videoDuration === 0 && audioDuration === 0) { - // If duration samples are not available in the traf use sidx subsegment_duration - var sidx = parseSegmentIndex(data); + if (sidx !== null && sidx !== void 0 && sidx.references) { + return sidx.references.reduce(function (dur, ref) { + return dur + ref.info.duration || 0; + }, 0); + } + } - if (sidx !== null && sidx !== void 0 && sidx.references) { - return sidx.references.reduce(function (dur, ref) { - return dur + ref.info.duration || 0; - }, 0); - } - } + if (videoDuration) { + return videoDuration; + } - if (videoDuration) { - return videoDuration; - } - - return audioDuration; -} -/* + return audioDuration; + } + /* For Reference: aligned(8) class TrackRunBox extends FullBox(‘trun’, version, tr_flags) { @@ -26094,1733 +27393,1804 @@ function getDuration(data, initData) { } */ -function computeRawDurationFromSamples(trun) { - var flags = readUint32(trun, 0); // Flags are at offset 0, non-optional sample_count is at offset 4. Therefore we start 8 bytes in. - // Each field is an int32, which is 4 bytes + function computeRawDurationFromSamples(trun) { + var flags = readUint32(trun, 0); // Flags are at offset 0, non-optional sample_count is at offset 4. Therefore we start 8 bytes in. + // Each field is an int32, which is 4 bytes - var offset = 8; // data-offset-present flag + var offset = 8; // data-offset-present flag - if (flags & 0x000001) { - offset += 4; - } // first-sample-flags-present flag + if (flags & 0x000001) { + offset += 4; + } // first-sample-flags-present flag + if (flags & 0x000004) { + offset += 4; + } - if (flags & 0x000004) { - offset += 4; - } + var duration = 0; + var sampleCount = readUint32(trun, 4); - var duration = 0; - var sampleCount = readUint32(trun, 4); + for (var i = 0; i < sampleCount; i++) { + // sample-duration-present flag + if (flags & 0x000100) { + var sampleDuration = readUint32(trun, offset); + duration += sampleDuration; + offset += 4; + } // sample-size-present flag - for (var i = 0; i < sampleCount; i++) { - // sample-duration-present flag - if (flags & 0x000100) { - var sampleDuration = readUint32(trun, offset); - duration += sampleDuration; - offset += 4; - } // sample-size-present flag + if (flags & 0x000200) { + offset += 4; + } // sample-flags-present flag + if (flags & 0x000400) { + offset += 4; + } // sample-composition-time-offsets-present flag - if (flags & 0x000200) { - offset += 4; - } // sample-flags-present flag + if (flags & 0x000800) { + offset += 4; + } + } + return duration; + } + function offsetStartDTS(initData, fmp4, timeOffset) { + findBox(fmp4, ["moof", "traf"]).forEach(function (traf) { + findBox(traf, ["tfhd"]).forEach(function (tfhd) { + // get the track id from the tfhd + var id = readUint32(tfhd, 4); + var track = initData[id]; - if (flags & 0x000400) { - offset += 4; - } // sample-composition-time-offsets-present flag + if (!track) { + return; + } // assume a 90kHz clock if no timescale was specified + var timescale = track.timescale || 90e3; // get the base media decode time from the tfdt - if (flags & 0x000800) { - offset += 4; - } - } + findBox(traf, ["tfdt"]).forEach(function (tfdt) { + var version = tfdt.data[tfdt.start]; + var baseMediaDecodeTime = readUint32(tfdt, 4); - return duration; -} -function offsetStartDTS(initData, fmp4, timeOffset) { - findBox(fmp4, ['moof', 'traf']).forEach(function (traf) { - findBox(traf, ['tfhd']).forEach(function (tfhd) { - // get the track id from the tfhd - var id = readUint32(tfhd, 4); - var track = initData[id]; + if (version === 0) { + writeUint32(tfdt, 4, baseMediaDecodeTime - timeOffset * timescale); + } else { + baseMediaDecodeTime *= Math.pow(2, 32); + baseMediaDecodeTime += readUint32(tfdt, 8); + baseMediaDecodeTime -= timeOffset * timescale; + baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0); + var upper = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)); + var lower = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1)); + writeUint32(tfdt, 4, upper); + writeUint32(tfdt, 8, lower); + } + }); + }); + }); + } // TODO: Check if the last moof+mdat pair is part of the valid range - if (!track) { - return; - } // assume a 90kHz clock if no timescale was specified + function segmentValidRange(data) { + var segmentedRange = { + valid: null, + remainder: null, + }; + var moofs = findBox(data, ["moof"]); + if (!moofs) { + return segmentedRange; + } else if (moofs.length < 2) { + segmentedRange.remainder = data; + return segmentedRange; + } - var timescale = track.timescale || 90e3; // get the base media decode time from the tfdt + var last = moofs[moofs.length - 1]; // Offset by 8 bytes; findBox offsets the start by as much - findBox(traf, ['tfdt']).forEach(function (tfdt) { - var version = tfdt.data[tfdt.start]; - var baseMediaDecodeTime = readUint32(tfdt, 4); + segmentedRange.valid = Object(_typed_array__WEBPACK_IMPORTED_MODULE_0__["sliceUint8"])(data, 0, last.start - 8); + segmentedRange.remainder = Object(_typed_array__WEBPACK_IMPORTED_MODULE_0__["sliceUint8"])(data, last.start - 8); + return segmentedRange; + } + function appendUint8Array(data1, data2) { + var temp = new Uint8Array(data1.length + data2.length); + temp.set(data1); + temp.set(data2, data1.length); + return temp; + } - if (version === 0) { - writeUint32(tfdt, 4, baseMediaDecodeTime - timeOffset * timescale); - } else { - baseMediaDecodeTime *= Math.pow(2, 32); - baseMediaDecodeTime += readUint32(tfdt, 8); - baseMediaDecodeTime -= timeOffset * timescale; - baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0); - var upper = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)); - var lower = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1)); - writeUint32(tfdt, 4, upper); - writeUint32(tfdt, 8, lower); - } - }); - }); - }); -} // TODO: Check if the last moof+mdat pair is part of the valid range + /***/ + }, -function segmentValidRange(data) { - var segmentedRange = { - valid: null, - remainder: null - }; - var moofs = findBox(data, ['moof']); - - if (!moofs) { - return segmentedRange; - } else if (moofs.length < 2) { - segmentedRange.remainder = data; - return segmentedRange; - } - - var last = moofs[moofs.length - 1]; // Offset by 8 bytes; findBox offsets the start by as much - - segmentedRange.valid = Object(_typed_array__WEBPACK_IMPORTED_MODULE_0__["sliceUint8"])(data, 0, last.start - 8); - segmentedRange.remainder = Object(_typed_array__WEBPACK_IMPORTED_MODULE_0__["sliceUint8"])(data, last.start - 8); - return segmentedRange; -} -function appendUint8Array(data1, data2) { - var temp = new Uint8Array(data1.length + data2.length); - temp.set(data1); - temp.set(data2, data1.length); - return temp; -} - -/***/ }), - -/***/ "./src/utils/output-filter.ts": -/*!************************************!*\ + /***/ "./src/utils/output-filter.ts": + /*!************************************!*\ !*** ./src/utils/output-filter.ts ***! \************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return OutputFilter; }); -var OutputFilter = /*#__PURE__*/function () { - function OutputFilter(timelineController, trackName) { - this.timelineController = void 0; - this.cueRanges = []; - this.trackName = void 0; - this.startTime = null; - this.endTime = null; - this.screen = null; - this.timelineController = timelineController; - this.trackName = trackName; - } - - var _proto = OutputFilter.prototype; - - _proto.dispatchCue = function dispatchCue() { - if (this.startTime === null) { - return; - } - - this.timelineController.addCues(this.trackName, this.startTime, this.endTime, this.screen, this.cueRanges); - this.startTime = null; - }; - - _proto.newCue = function newCue(startTime, endTime, screen) { - if (this.startTime === null || this.startTime > startTime) { - this.startTime = startTime; - } - - this.endTime = endTime; - this.screen = screen; - this.timelineController.createCaptionsTrack(this.trackName); - }; - - _proto.reset = function reset() { - this.cueRanges = []; - }; - - return OutputFilter; -}(); - - - -/***/ }), - -/***/ "./src/utils/texttrack-utils.ts": -/*!**************************************!*\ - !*** ./src/utils/texttrack-utils.ts ***! - \**************************************/ -/*! exports provided: sendAddTrackEvent, addCueToTrack, clearCurrentCues, removeCuesInRange, getCuesInRange */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sendAddTrackEvent", function() { return sendAddTrackEvent; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addCueToTrack", function() { return addCueToTrack; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clearCurrentCues", function() { return clearCurrentCues; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeCuesInRange", function() { return removeCuesInRange; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCuesInRange", function() { return getCuesInRange; }); -/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts"); - -function sendAddTrackEvent(track, videoEl) { - var event; - - try { - event = new Event('addtrack'); - } catch (err) { - // for IE11 - event = document.createEvent('Event'); - event.initEvent('addtrack', false, false); - } - - event.track = track; - videoEl.dispatchEvent(event); -} -function addCueToTrack(track, cue) { - // Sometimes there are cue overlaps on segmented vtts so the same - // cue can appear more than once in different vtt files. - // This avoid showing duplicated cues with same timecode and text. - var mode = track.mode; - - if (mode === 'disabled') { - track.mode = 'hidden'; - } - - if (track.cues && !track.cues.getCueById(cue.id)) { - try { - track.addCue(cue); - - if (!track.cues.getCueById(cue.id)) { - throw new Error("addCue is failed for: " + cue); - } - } catch (err) { - _logger__WEBPACK_IMPORTED_MODULE_0__["logger"].debug("[texttrack-utils]: " + err); - var textTrackCue = new self.TextTrackCue(cue.startTime, cue.endTime, cue.text); - textTrackCue.id = cue.id; - track.addCue(textTrackCue); - } - } - - if (mode === 'disabled') { - track.mode = mode; - } -} -function clearCurrentCues(track) { - // When track.mode is disabled, track.cues will be null. - // To guarantee the removal of cues, we need to temporarily - // change the mode to hidden - var mode = track.mode; - - if (mode === 'disabled') { - track.mode = 'hidden'; - } - - if (track.cues) { - for (var i = track.cues.length; i--;) { - track.removeCue(track.cues[i]); - } - } - - if (mode === 'disabled') { - track.mode = mode; - } -} -function removeCuesInRange(track, start, end) { - var mode = track.mode; - - if (mode === 'disabled') { - track.mode = 'hidden'; - } - - if (track.cues && track.cues.length > 0) { - var cues = getCuesInRange(track.cues, start, end); - - for (var i = 0; i < cues.length; i++) { - track.removeCue(cues[i]); - } - } - - if (mode === 'disabled') { - track.mode = mode; - } -} // Find first cue starting after given time. -// Modified version of binary search O(log(n)). - -function getFirstCueIndexAfterTime(cues, time) { - // If first cue starts after time, start there - if (time < cues[0].startTime) { - return 0; - } // If the last cue ends before time there is no overlap - - - var len = cues.length - 1; - - if (time > cues[len].endTime) { - return -1; - } - - var left = 0; - var right = len; - - while (left <= right) { - var mid = Math.floor((right + left) / 2); - - if (time < cues[mid].startTime) { - right = mid - 1; - } else if (time > cues[mid].startTime && left < len) { - left = mid + 1; - } else { - // If it's not lower or higher, it must be equal. - return mid; - } - } // At this point, left and right have swapped. - // No direct match was found, left or right element must be the closest. Check which one has the smallest diff. - - - return cues[left].startTime - time < time - cues[right].startTime ? left : right; -} - -function getCuesInRange(cues, start, end) { - var cuesFound = []; - var firstCueInRange = getFirstCueIndexAfterTime(cues, start); - - if (firstCueInRange > -1) { - for (var i = firstCueInRange, len = cues.length; i < len; i++) { - var cue = cues[i]; - - if (cue.startTime >= start && cue.endTime <= end) { - cuesFound.push(cue); - } else if (cue.startTime > end) { - return cuesFound; - } - } - } - - return cuesFound; -} - -/***/ }), - -/***/ "./src/utils/time-ranges.ts": -/*!**********************************!*\ - !*** ./src/utils/time-ranges.ts ***! - \**********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * TimeRanges to string helper - */ -var TimeRanges = { - toString: function toString(r) { - var log = ''; - var len = r.length; - - for (var i = 0; i < len; i++) { - log += '[' + r.start(i).toFixed(3) + ',' + r.end(i).toFixed(3) + ']'; - } - - return log; - } -}; -/* harmony default export */ __webpack_exports__["default"] = (TimeRanges); - -/***/ }), - -/***/ "./src/utils/timescale-conversion.ts": -/*!*******************************************!*\ - !*** ./src/utils/timescale-conversion.ts ***! - \*******************************************/ -/*! exports provided: toTimescaleFromBase, toTimescaleFromScale, toMsFromMpegTsClock, toMpegTsClockFromTimescale */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toTimescaleFromBase", function() { return toTimescaleFromBase; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toTimescaleFromScale", function() { return toTimescaleFromScale; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toMsFromMpegTsClock", function() { return toMsFromMpegTsClock; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toMpegTsClockFromTimescale", function() { return toMpegTsClockFromTimescale; }); -var MPEG_TS_CLOCK_FREQ_HZ = 90000; -function toTimescaleFromBase(value, destScale, srcBase, round) { - if (srcBase === void 0) { - srcBase = 1; - } - - if (round === void 0) { - round = false; - } - - var result = value * destScale * srcBase; // equivalent to `(value * scale) / (1 / base)` - - return round ? Math.round(result) : result; -} -function toTimescaleFromScale(value, destScale, srcScale, round) { - if (srcScale === void 0) { - srcScale = 1; - } - - if (round === void 0) { - round = false; - } - - return toTimescaleFromBase(value, destScale, 1 / srcScale, round); -} -function toMsFromMpegTsClock(value, round) { - if (round === void 0) { - round = false; - } - - return toTimescaleFromBase(value, 1000, 1 / MPEG_TS_CLOCK_FREQ_HZ, round); -} -function toMpegTsClockFromTimescale(value, srcScale) { - if (srcScale === void 0) { - srcScale = 1; - } - - return toTimescaleFromBase(value, MPEG_TS_CLOCK_FREQ_HZ, 1 / srcScale); -} - -/***/ }), - -/***/ "./src/utils/typed-array.ts": -/*!**********************************!*\ - !*** ./src/utils/typed-array.ts ***! - \**********************************/ -/*! exports provided: sliceUint8 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sliceUint8", function() { return sliceUint8; }); -function sliceUint8(array, start, end) { - // @ts-expect-error This polyfills IE11 usage of Uint8Array slice. - // It always exists in the TypeScript definition so fails, but it fails at runtime on IE11. - return Uint8Array.prototype.slice ? array.slice(start, end) : new Uint8Array(Array.prototype.slice.call(array, start, end)); -} - -/***/ }), - -/***/ "./src/utils/vttcue.ts": -/*!*****************************!*\ - !*** ./src/utils/vttcue.ts ***! - \*****************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * Copyright 2013 vtt.js Contributors - * - * Licensed under the Apache License, Version 2.0 (the 'License'); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* harmony default export */ __webpack_exports__["default"] = ((function () { - if (typeof self !== 'undefined' && self.VTTCue) { - return self.VTTCue; - } - - var AllowedDirections = ['', 'lr', 'rl']; - var AllowedAlignments = ['start', 'middle', 'end', 'left', 'right']; - - function isAllowedValue(allowed, value) { - if (typeof value !== 'string') { - return false; - } // necessary for assuring the generic conforms to the Array interface - - - if (!Array.isArray(allowed)) { - return false; - } // reset the type so that the next narrowing works well - - - var lcValue = value.toLowerCase(); // use the allow list to narrow the type to a specific subset of strings - - if (~allowed.indexOf(lcValue)) { - return lcValue; - } - - return false; - } - - function findDirectionSetting(value) { - return isAllowedValue(AllowedDirections, value); - } - - function findAlignSetting(value) { - return isAllowedValue(AllowedAlignments, value); - } - - function extend(obj) { - for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - rest[_key - 1] = arguments[_key]; - } - - var i = 1; - - for (; i < arguments.length; i++) { - var cobj = arguments[i]; - - for (var p in cobj) { - obj[p] = cobj[p]; - } - } - - return obj; - } - - function VTTCue(startTime, endTime, text) { - var cue = this; - var baseObj = { - enumerable: true - }; - /** - * Shim implementation specific properties. These properties are not in - * the spec. - */ - // Lets us know when the VTTCue's data has changed in such a way that we need - // to recompute its display state. This lets us compute its display state - // lazily. - - cue.hasBeenReset = false; - /** - * VTTCue and TextTrackCue properties - * http://dev.w3.org/html5/webvtt/#vttcue-interface - */ - - var _id = ''; - var _pauseOnExit = false; - var _startTime = startTime; - var _endTime = endTime; - var _text = text; - var _region = null; - var _vertical = ''; - var _snapToLines = true; - var _line = 'auto'; - var _lineAlign = 'start'; - var _position = 50; - var _positionAlign = 'middle'; - var _size = 50; - var _align = 'middle'; - Object.defineProperty(cue, 'id', extend({}, baseObj, { - get: function get() { - return _id; - }, - set: function set(value) { - _id = '' + value; - } - })); - Object.defineProperty(cue, 'pauseOnExit', extend({}, baseObj, { - get: function get() { - return _pauseOnExit; - }, - set: function set(value) { - _pauseOnExit = !!value; - } - })); - Object.defineProperty(cue, 'startTime', extend({}, baseObj, { - get: function get() { - return _startTime; - }, - set: function set(value) { - if (typeof value !== 'number') { - throw new TypeError('Start time must be set to a number.'); - } - - _startTime = value; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'endTime', extend({}, baseObj, { - get: function get() { - return _endTime; - }, - set: function set(value) { - if (typeof value !== 'number') { - throw new TypeError('End time must be set to a number.'); - } - - _endTime = value; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'text', extend({}, baseObj, { - get: function get() { - return _text; - }, - set: function set(value) { - _text = '' + value; - this.hasBeenReset = true; - } - })); // todo: implement VTTRegion polyfill? - - Object.defineProperty(cue, 'region', extend({}, baseObj, { - get: function get() { - return _region; - }, - set: function set(value) { - _region = value; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'vertical', extend({}, baseObj, { - get: function get() { - return _vertical; - }, - set: function set(value) { - var setting = findDirectionSetting(value); // Have to check for false because the setting an be an empty string. - - if (setting === false) { - throw new SyntaxError('An invalid or illegal string was specified.'); - } - - _vertical = setting; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'snapToLines', extend({}, baseObj, { - get: function get() { - return _snapToLines; - }, - set: function set(value) { - _snapToLines = !!value; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'line', extend({}, baseObj, { - get: function get() { - return _line; - }, - set: function set(value) { - if (typeof value !== 'number' && value !== 'auto') { - throw new SyntaxError('An invalid number or illegal string was specified.'); - } - - _line = value; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'lineAlign', extend({}, baseObj, { - get: function get() { - return _lineAlign; - }, - set: function set(value) { - var setting = findAlignSetting(value); - - if (!setting) { - throw new SyntaxError('An invalid or illegal string was specified.'); - } - - _lineAlign = setting; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'position', extend({}, baseObj, { - get: function get() { - return _position; - }, - set: function set(value) { - if (value < 0 || value > 100) { - throw new Error('Position must be between 0 and 100.'); - } - - _position = value; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'positionAlign', extend({}, baseObj, { - get: function get() { - return _positionAlign; - }, - set: function set(value) { - var setting = findAlignSetting(value); - - if (!setting) { - throw new SyntaxError('An invalid or illegal string was specified.'); - } - - _positionAlign = setting; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'size', extend({}, baseObj, { - get: function get() { - return _size; - }, - set: function set(value) { - if (value < 0 || value > 100) { - throw new Error('Size must be between 0 and 100.'); - } - - _size = value; - this.hasBeenReset = true; - } - })); - Object.defineProperty(cue, 'align', extend({}, baseObj, { - get: function get() { - return _align; - }, - set: function set(value) { - var setting = findAlignSetting(value); - - if (!setting) { - throw new SyntaxError('An invalid or illegal string was specified.'); - } - - _align = setting; - this.hasBeenReset = true; - } - })); - /** - * Other <track> spec defined properties - */ - // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state - - cue.displayState = undefined; - } - /** - * VTTCue methods - */ - - - VTTCue.prototype.getCueAsHTML = function () { - // Assume WebVTT.convertCueToDOMTree is on the global. - var WebVTT = self.WebVTT; - return WebVTT.convertCueToDOMTree(self, this.text); - }; // this is a polyfill hack - - - return VTTCue; -})()); - -/***/ }), - -/***/ "./src/utils/vttparser.ts": -/*!********************************!*\ - !*** ./src/utils/vttparser.ts ***! - \********************************/ -/*! exports provided: parseTimeStamp, fixLineBreaks, VTTParser */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseTimeStamp", function() { return parseTimeStamp; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fixLineBreaks", function() { return fixLineBreaks; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VTTParser", function() { return VTTParser; }); -/* harmony import */ var _vttcue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vttcue */ "./src/utils/vttcue.ts"); -/* - * Source: https://github.com/mozilla/vtt.js/blob/master/dist/vtt.js - */ - - -var StringDecoder = /*#__PURE__*/function () { - function StringDecoder() {} - - var _proto = StringDecoder.prototype; - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _proto.decode = function decode(data, options) { - if (!data) { - return ''; - } - - if (typeof data !== 'string') { - throw new Error('Error - expected string data.'); - } - - return decodeURIComponent(encodeURIComponent(data)); - }; - - return StringDecoder; -}(); // Try to parse input as a time stamp. - - -function parseTimeStamp(input) { - function computeSeconds(h, m, s, f) { - return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + parseFloat(f || 0); - } - - var m = input.match(/^(?:(\d+):)?(\d{2}):(\d{2})(\.\d+)?/); - - if (!m) { - return null; - } - - if (parseFloat(m[2]) > 59) { - // Timestamp takes the form of [hours]:[minutes].[milliseconds] - // First position is hours as it's over 59. - return computeSeconds(m[2], m[3], 0, m[4]); - } // Timestamp takes the form of [hours (optional)]:[minutes]:[seconds].[milliseconds] - - - return computeSeconds(m[1], m[2], m[3], m[4]); -} // A settings object holds key/value pairs and will ignore anything but the first -// assignment to a specific key. - -var Settings = /*#__PURE__*/function () { - function Settings() { - this.values = Object.create(null); - } - - var _proto2 = Settings.prototype; - - // Only accept the first assignment to any key. - _proto2.set = function set(k, v) { - if (!this.get(k) && v !== '') { - this.values[k] = v; - } - } // Return the value for a key, or a default value. - // If 'defaultKey' is passed then 'dflt' is assumed to be an object with - // a number of possible default values as properties where 'defaultKey' is - // the key of the property that will be chosen; otherwise it's assumed to be - // a single value. - ; - - _proto2.get = function get(k, dflt, defaultKey) { - if (defaultKey) { - return this.has(k) ? this.values[k] : dflt[defaultKey]; - } - - return this.has(k) ? this.values[k] : dflt; - } // Check whether we have a value for a key. - ; - - _proto2.has = function has(k) { - return k in this.values; - } // Accept a setting if its one of the given alternatives. - ; - - _proto2.alt = function alt(k, v, a) { - for (var n = 0; n < a.length; ++n) { - if (v === a[n]) { - this.set(k, v); - break; - } - } - } // Accept a setting if its a valid (signed) integer. - ; - - _proto2.integer = function integer(k, v) { - if (/^-?\d+$/.test(v)) { - // integer - this.set(k, parseInt(v, 10)); - } - } // Accept a setting if its a valid percentage. - ; - - _proto2.percent = function percent(k, v) { - if (/^([\d]{1,3})(\.[\d]*)?%$/.test(v)) { - var percent = parseFloat(v); - - if (percent >= 0 && percent <= 100) { - this.set(k, percent); - return true; - } - } - - return false; - }; - - return Settings; -}(); // Helper function to parse input into groups separated by 'groupDelim', and -// interpret each group as a key/value pair separated by 'keyValueDelim'. - - -function parseOptions(input, callback, keyValueDelim, groupDelim) { - var groups = groupDelim ? input.split(groupDelim) : [input]; - - for (var i in groups) { - if (typeof groups[i] !== 'string') { - continue; - } - - var kv = groups[i].split(keyValueDelim); - - if (kv.length !== 2) { - continue; - } - - var _k = kv[0]; - var _v = kv[1]; - callback(_k, _v); - } -} - -var defaults = new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0, 0, ''); // 'middle' was changed to 'center' in the spec: https://github.com/w3c/webvtt/pull/244 -// Safari doesn't yet support this change, but FF and Chrome do. - -var center = defaults.align === 'middle' ? 'middle' : 'center'; - -function parseCue(input, cue, regionList) { - // Remember the original input if we need to throw an error. - var oInput = input; // 4.1 WebVTT timestamp - - function consumeTimeStamp() { - var ts = parseTimeStamp(input); - - if (ts === null) { - throw new Error('Malformed timestamp: ' + oInput); - } // Remove time stamp from input. - - - input = input.replace(/^[^\sa-zA-Z-]+/, ''); - return ts; - } // 4.4.2 WebVTT cue settings - - - function consumeCueSettings(input, cue) { - var settings = new Settings(); - parseOptions(input, function (k, v) { - var vals; - - switch (k) { - case 'region': - // Find the last region we parsed with the same region id. - for (var i = regionList.length - 1; i >= 0; i--) { - if (regionList[i].id === v) { - settings.set(k, regionList[i].region); - break; - } - } - - break; - - case 'vertical': - settings.alt(k, v, ['rl', 'lr']); - break; - - case 'line': - vals = v.split(','); - settings.integer(k, vals[0]); - - if (settings.percent(k, vals[0])) { - settings.set('snapToLines', false); - } - - settings.alt(k, vals[0], ['auto']); - - if (vals.length === 2) { - settings.alt('lineAlign', vals[1], ['start', center, 'end']); - } - - break; - - case 'position': - vals = v.split(','); - settings.percent(k, vals[0]); - - if (vals.length === 2) { - settings.alt('positionAlign', vals[1], ['start', center, 'end', 'line-left', 'line-right', 'auto']); - } - - break; - - case 'size': - settings.percent(k, v); - break; - - case 'align': - settings.alt(k, v, ['start', center, 'end', 'left', 'right']); - break; - } - }, /:/, /\s/); // Apply default values for any missing fields. - - cue.region = settings.get('region', null); - cue.vertical = settings.get('vertical', ''); - var line = settings.get('line', 'auto'); - - if (line === 'auto' && defaults.line === -1) { - // set numeric line number for Safari - line = -1; - } - - cue.line = line; - cue.lineAlign = settings.get('lineAlign', 'start'); - cue.snapToLines = settings.get('snapToLines', true); - cue.size = settings.get('size', 100); - cue.align = settings.get('align', center); - var position = settings.get('position', 'auto'); - - if (position === 'auto' && defaults.position === 50) { - // set numeric position for Safari - position = cue.align === 'start' || cue.align === 'left' ? 0 : cue.align === 'end' || cue.align === 'right' ? 100 : 50; - } - - cue.position = position; - } - - function skipWhitespace() { - input = input.replace(/^\s+/, ''); - } // 4.1 WebVTT cue timings. - - - skipWhitespace(); - cue.startTime = consumeTimeStamp(); // (1) collect cue start time - - skipWhitespace(); - - if (input.substr(0, 3) !== '-->') { - // (3) next characters must match '-->' - throw new Error("Malformed time stamp (time stamps must be separated by '-->'): " + oInput); - } - - input = input.substr(3); - skipWhitespace(); - cue.endTime = consumeTimeStamp(); // (5) collect cue end time - // 4.1 WebVTT cue settings list. - - skipWhitespace(); - consumeCueSettings(input, cue); -} - -function fixLineBreaks(input) { - return input.replace(/<br(?: \/)?>/gi, '\n'); -} -var VTTParser = /*#__PURE__*/function () { - function VTTParser() { - this.state = 'INITIAL'; - this.buffer = ''; - this.decoder = new StringDecoder(); - this.regionList = []; - this.cue = null; - this.oncue = void 0; - this.onparsingerror = void 0; - this.onflush = void 0; - } - - var _proto3 = VTTParser.prototype; - - _proto3.parse = function parse(data) { - var _this = this; // If there is no data then we won't decode it, but will just try to parse - // whatever is in buffer already. This may occur in circumstances, for - // example when flush() is called. - - - if (data) { - // Try to decode the data that we received. - _this.buffer += _this.decoder.decode(data, { - stream: true - }); - } - - function collectNextLine() { - var buffer = _this.buffer; - var pos = 0; - buffer = fixLineBreaks(buffer); - - while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { - ++pos; - } - - var line = buffer.substr(0, pos); // Advance the buffer early in case we fail below. - - if (buffer[pos] === '\r') { - ++pos; - } - - if (buffer[pos] === '\n') { - ++pos; - } - - _this.buffer = buffer.substr(pos); - return line; - } // 3.2 WebVTT metadata header syntax - - - function parseHeader(input) { - parseOptions(input, function (k, v) {// switch (k) { - // case 'region': - // 3.3 WebVTT region metadata header syntax - // console.log('parse region', v); - // parseRegion(v); - // break; - // } - }, /:/); - } // 5.1 WebVTT file parsing. - - - try { - var line = ''; - - if (_this.state === 'INITIAL') { - // We can't start parsing until we have the first line. - if (!/\r\n|\n/.test(_this.buffer)) { - return this; - } - - line = collectNextLine(); // strip of UTF-8 BOM if any - // https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 - - var m = line.match(/^(ïÂģÂŋ)?WEBVTT([ \t].*)?$/); - - if (!m || !m[0]) { - throw new Error('Malformed WebVTT signature.'); - } - - _this.state = 'HEADER'; - } - - var alreadyCollectedLine = false; - - while (_this.buffer) { - // We can't parse a line until we have the full line. - if (!/\r\n|\n/.test(_this.buffer)) { - return this; - } - - if (!alreadyCollectedLine) { - line = collectNextLine(); - } else { - alreadyCollectedLine = false; - } - - switch (_this.state) { - case 'HEADER': - // 13-18 - Allow a header (metadata) under the WEBVTT line. - if (/:/.test(line)) { - parseHeader(line); - } else if (!line) { - // An empty line terminates the header and starts the body (cues). - _this.state = 'ID'; - } - - continue; - - case 'NOTE': - // Ignore NOTE blocks. - if (!line) { - _this.state = 'ID'; - } - - continue; - - case 'ID': - // Check for the start of NOTE blocks. - if (/^NOTE($|[ \t])/.test(line)) { - _this.state = 'NOTE'; - break; - } // 19-29 - Allow any number of line terminators, then initialize new cue values. - - - if (!line) { - continue; - } - - _this.cue = new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0, 0, ''); - _this.state = 'CUE'; // 30-39 - Check if self line contains an optional identifier or timing data. - - if (line.indexOf('-->') === -1) { - _this.cue.id = line; - continue; - } - - // Process line as start of a cue. - - /* falls through */ - - case 'CUE': - // 40 - Collect cue timings and settings. - if (!_this.cue) { - _this.state = 'BADCUE'; - continue; - } - - try { - parseCue(line, _this.cue, _this.regionList); - } catch (e) { - // In case of an error ignore rest of the cue. - _this.cue = null; - _this.state = 'BADCUE'; - continue; - } - - _this.state = 'CUETEXT'; - continue; - - case 'CUETEXT': - { - var hasSubstring = line.indexOf('-->') !== -1; // 34 - If we have an empty line then report the cue. - // 35 - If we have the special substring '-->' then report the cue, - // but do not collect the line as we need to process the current - // one as a new cue. - - if (!line || hasSubstring && (alreadyCollectedLine = true)) { - // We are done parsing self cue. - if (_this.oncue && _this.cue) { - _this.oncue(_this.cue); + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { + return OutputFilter; + }); + var OutputFilter = /*#__PURE__*/ (function () { + function OutputFilter(timelineController, trackName) { + this.timelineController = void 0; + this.cueRanges = []; + this.trackName = void 0; + this.startTime = null; + this.endTime = null; + this.screen = null; + this.timelineController = timelineController; + this.trackName = trackName; + } + + var _proto = OutputFilter.prototype; + + _proto.dispatchCue = function dispatchCue() { + if (this.startTime === null) { + return; } - _this.cue = null; - _this.state = 'ID'; - continue; + this.timelineController.addCues(this.trackName, this.startTime, this.endTime, this.screen, this.cueRanges); + this.startTime = null; + }; + + _proto.newCue = function newCue(startTime, endTime, screen) { + if (this.startTime === null || this.startTime > startTime) { + this.startTime = startTime; + } + + this.endTime = endTime; + this.screen = screen; + this.timelineController.createCaptionsTrack(this.trackName); + }; + + _proto.reset = function reset() { + this.cueRanges = []; + }; + + return OutputFilter; + })(); + + /***/ + }, + + /***/ "./src/utils/texttrack-utils.ts": + /*!**************************************!*\ + !*** ./src/utils/texttrack-utils.ts ***! + \**************************************/ + /*! exports provided: sendAddTrackEvent, addCueToTrack, clearCurrentCues, removeCuesInRange, getCuesInRange */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sendAddTrackEvent", function () { + return sendAddTrackEvent; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addCueToTrack", function () { + return addCueToTrack; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clearCurrentCues", function () { + return clearCurrentCues; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeCuesInRange", function () { + return removeCuesInRange; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCuesInRange", function () { + return getCuesInRange; + }); + /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts"); + + function sendAddTrackEvent(track, videoEl) { + var event; + + try { + event = new Event("addtrack"); + } catch (err) { + // for IE11 + event = document.createEvent("Event"); + event.initEvent("addtrack", false, false); } - if (_this.cue === null) { - continue; - } - - if (_this.cue.text) { - _this.cue.text += '\n'; - } - - _this.cue.text += line; + event.track = track; + videoEl.dispatchEvent(event); } - continue; + function addCueToTrack(track, cue) { + // Sometimes there are cue overlaps on segmented vtts so the same + // cue can appear more than once in different vtt files. + // This avoid showing duplicated cues with same timecode and text. + var mode = track.mode; - case 'BADCUE': - // 54-62 - Collect and discard the remaining cue. - if (!line) { - _this.state = 'ID'; + if (mode === "disabled") { + track.mode = "hidden"; + } + + if (track.cues && !track.cues.getCueById(cue.id)) { + try { + track.addCue(cue); + + if (!track.cues.getCueById(cue.id)) { + throw new Error("addCue is failed for: " + cue); + } + } catch (err) { + _logger__WEBPACK_IMPORTED_MODULE_0__["logger"].debug("[texttrack-utils]: " + err); + var textTrackCue = new self.TextTrackCue(cue.startTime, cue.endTime, cue.text); + textTrackCue.id = cue.id; + track.addCue(textTrackCue); + } + } + + if (mode === "disabled") { + track.mode = mode; + } + } + function clearCurrentCues(track) { + // When track.mode is disabled, track.cues will be null. + // To guarantee the removal of cues, we need to temporarily + // change the mode to hidden + var mode = track.mode; + + if (mode === "disabled") { + track.mode = "hidden"; + } + + if (track.cues) { + for (var i = track.cues.length; i--; ) { + track.removeCue(track.cues[i]); + } + } + + if (mode === "disabled") { + track.mode = mode; + } + } + function removeCuesInRange(track, start, end) { + var mode = track.mode; + + if (mode === "disabled") { + track.mode = "hidden"; + } + + if (track.cues && track.cues.length > 0) { + var cues = getCuesInRange(track.cues, start, end); + + for (var i = 0; i < cues.length; i++) { + track.removeCue(cues[i]); + } + } + + if (mode === "disabled") { + track.mode = mode; + } + } // Find first cue starting after given time. + // Modified version of binary search O(log(n)). + + function getFirstCueIndexAfterTime(cues, time) { + // If first cue starts after time, start there + if (time < cues[0].startTime) { + return 0; + } // If the last cue ends before time there is no overlap + + var len = cues.length - 1; + + if (time > cues[len].endTime) { + return -1; + } + + var left = 0; + var right = len; + + while (left <= right) { + var mid = Math.floor((right + left) / 2); + + if (time < cues[mid].startTime) { + right = mid - 1; + } else if (time > cues[mid].startTime && left < len) { + left = mid + 1; + } else { + // If it's not lower or higher, it must be equal. + return mid; + } + } // At this point, left and right have swapped. + // No direct match was found, left or right element must be the closest. Check which one has the smallest diff. + + return cues[left].startTime - time < time - cues[right].startTime ? left : right; } - } - } - } catch (e) { - // If we are currently parsing a cue, report what we have. - if (_this.state === 'CUETEXT' && _this.cue && _this.oncue) { - _this.oncue(_this.cue); - } + function getCuesInRange(cues, start, end) { + var cuesFound = []; + var firstCueInRange = getFirstCueIndexAfterTime(cues, start); - _this.cue = null; // Enter BADWEBVTT state if header was not parsed correctly otherwise - // another exception occurred so enter BADCUE state. + if (firstCueInRange > -1) { + for (var i = firstCueInRange, len = cues.length; i < len; i++) { + var cue = cues[i]; - _this.state = _this.state === 'INITIAL' ? 'BADWEBVTT' : 'BADCUE'; - } + if (cue.startTime >= start && cue.endTime <= end) { + cuesFound.push(cue); + } else if (cue.startTime > end) { + return cuesFound; + } + } + } - return this; - }; + return cuesFound; + } - _proto3.flush = function flush() { - var _this = this; + /***/ + }, - try { - // Finish decoding the stream. - // _this.buffer += _this.decoder.decode(); - // Synthesize the end of the current cue or region. - if (_this.cue || _this.state === 'HEADER') { - _this.buffer += '\n\n'; + /***/ "./src/utils/time-ranges.ts": + /*!**********************************!*\ + !*** ./src/utils/time-ranges.ts ***! + \**********************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /** + * TimeRanges to string helper + */ + var TimeRanges = { + toString: function toString(r) { + var log = ""; + var len = r.length; - _this.parse(); - } // If we've flushed, parsed, and we're still on the INITIAL state then - // that means we don't have enough of the stream to parse the first - // line. + for (var i = 0; i < len; i++) { + log += "[" + r.start(i).toFixed(3) + "," + r.end(i).toFixed(3) + "]"; + } + return log; + }, + }; + /* harmony default export */ __webpack_exports__["default"] = TimeRanges; - if (_this.state === 'INITIAL' || _this.state === 'BADWEBVTT') { - throw new Error('Malformed WebVTT signature.'); - } - } catch (e) { - if (_this.onparsingerror) { - _this.onparsingerror(e); - } - } + /***/ + }, - if (_this.onflush) { - _this.onflush(); - } + /***/ "./src/utils/timescale-conversion.ts": + /*!*******************************************!*\ + !*** ./src/utils/timescale-conversion.ts ***! + \*******************************************/ + /*! exports provided: toTimescaleFromBase, toTimescaleFromScale, toMsFromMpegTsClock, toMpegTsClockFromTimescale */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toTimescaleFromBase", function () { + return toTimescaleFromBase; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toTimescaleFromScale", function () { + return toTimescaleFromScale; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toMsFromMpegTsClock", function () { + return toMsFromMpegTsClock; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toMpegTsClockFromTimescale", function () { + return toMpegTsClockFromTimescale; + }); + var MPEG_TS_CLOCK_FREQ_HZ = 90000; + function toTimescaleFromBase(value, destScale, srcBase, round) { + if (srcBase === void 0) { + srcBase = 1; + } - return this; - }; + if (round === void 0) { + round = false; + } - return VTTParser; -}(); + var result = value * destScale * srcBase; // equivalent to `(value * scale) / (1 / base)` -/***/ }), + return round ? Math.round(result) : result; + } + function toTimescaleFromScale(value, destScale, srcScale, round) { + if (srcScale === void 0) { + srcScale = 1; + } -/***/ "./src/utils/webvtt-parser.ts": -/*!************************************!*\ + if (round === void 0) { + round = false; + } + + return toTimescaleFromBase(value, destScale, 1 / srcScale, round); + } + function toMsFromMpegTsClock(value, round) { + if (round === void 0) { + round = false; + } + + return toTimescaleFromBase(value, 1000, 1 / MPEG_TS_CLOCK_FREQ_HZ, round); + } + function toMpegTsClockFromTimescale(value, srcScale) { + if (srcScale === void 0) { + srcScale = 1; + } + + return toTimescaleFromBase(value, MPEG_TS_CLOCK_FREQ_HZ, 1 / srcScale); + } + + /***/ + }, + + /***/ "./src/utils/typed-array.ts": + /*!**********************************!*\ + !*** ./src/utils/typed-array.ts ***! + \**********************************/ + /*! exports provided: sliceUint8 */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sliceUint8", function () { + return sliceUint8; + }); + function sliceUint8(array, start, end) { + // @ts-expect-error This polyfills IE11 usage of Uint8Array slice. + // It always exists in the TypeScript definition so fails, but it fails at runtime on IE11. + return Uint8Array.prototype.slice ? array.slice(start, end) : new Uint8Array(Array.prototype.slice.call(array, start, end)); + } + + /***/ + }, + + /***/ "./src/utils/vttcue.ts": + /*!*****************************!*\ + !*** ./src/utils/vttcue.ts ***! + \*****************************/ + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* harmony default export */ __webpack_exports__["default"] = (function () { + if (typeof self !== "undefined" && self.VTTCue) { + return self.VTTCue; + } + + var AllowedDirections = ["", "lr", "rl"]; + var AllowedAlignments = ["start", "middle", "end", "left", "right"]; + + function isAllowedValue(allowed, value) { + if (typeof value !== "string") { + return false; + } // necessary for assuring the generic conforms to the Array interface + + if (!Array.isArray(allowed)) { + return false; + } // reset the type so that the next narrowing works well + + var lcValue = value.toLowerCase(); // use the allow list to narrow the type to a specific subset of strings + + if (~allowed.indexOf(lcValue)) { + return lcValue; + } + + return false; + } + + function findDirectionSetting(value) { + return isAllowedValue(AllowedDirections, value); + } + + function findAlignSetting(value) { + return isAllowedValue(AllowedAlignments, value); + } + + function extend(obj) { + for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + rest[_key - 1] = arguments[_key]; + } + + var i = 1; + + for (; i < arguments.length; i++) { + var cobj = arguments[i]; + + for (var p in cobj) { + obj[p] = cobj[p]; + } + } + + return obj; + } + + function VTTCue(startTime, endTime, text) { + var cue = this; + var baseObj = { + enumerable: true, + }; + /** + * Shim implementation specific properties. These properties are not in + * the spec. + */ + // Lets us know when the VTTCue's data has changed in such a way that we need + // to recompute its display state. This lets us compute its display state + // lazily. + + cue.hasBeenReset = false; + /** + * VTTCue and TextTrackCue properties + * http://dev.w3.org/html5/webvtt/#vttcue-interface + */ + + var _id = ""; + var _pauseOnExit = false; + var _startTime = startTime; + var _endTime = endTime; + var _text = text; + var _region = null; + var _vertical = ""; + var _snapToLines = true; + var _line = "auto"; + var _lineAlign = "start"; + var _position = 50; + var _positionAlign = "middle"; + var _size = 50; + var _align = "middle"; + Object.defineProperty( + cue, + "id", + extend({}, baseObj, { + get: function get() { + return _id; + }, + set: function set(value) { + _id = "" + value; + }, + }) + ); + Object.defineProperty( + cue, + "pauseOnExit", + extend({}, baseObj, { + get: function get() { + return _pauseOnExit; + }, + set: function set(value) { + _pauseOnExit = !!value; + }, + }) + ); + Object.defineProperty( + cue, + "startTime", + extend({}, baseObj, { + get: function get() { + return _startTime; + }, + set: function set(value) { + if (typeof value !== "number") { + throw new TypeError("Start time must be set to a number."); + } + + _startTime = value; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "endTime", + extend({}, baseObj, { + get: function get() { + return _endTime; + }, + set: function set(value) { + if (typeof value !== "number") { + throw new TypeError("End time must be set to a number."); + } + + _endTime = value; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "text", + extend({}, baseObj, { + get: function get() { + return _text; + }, + set: function set(value) { + _text = "" + value; + this.hasBeenReset = true; + }, + }) + ); // todo: implement VTTRegion polyfill? + + Object.defineProperty( + cue, + "region", + extend({}, baseObj, { + get: function get() { + return _region; + }, + set: function set(value) { + _region = value; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "vertical", + extend({}, baseObj, { + get: function get() { + return _vertical; + }, + set: function set(value) { + var setting = findDirectionSetting(value); // Have to check for false because the setting an be an empty string. + + if (setting === false) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + + _vertical = setting; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "snapToLines", + extend({}, baseObj, { + get: function get() { + return _snapToLines; + }, + set: function set(value) { + _snapToLines = !!value; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "line", + extend({}, baseObj, { + get: function get() { + return _line; + }, + set: function set(value) { + if (typeof value !== "number" && value !== "auto") { + throw new SyntaxError("An invalid number or illegal string was specified."); + } + + _line = value; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "lineAlign", + extend({}, baseObj, { + get: function get() { + return _lineAlign; + }, + set: function set(value) { + var setting = findAlignSetting(value); + + if (!setting) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + + _lineAlign = setting; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "position", + extend({}, baseObj, { + get: function get() { + return _position; + }, + set: function set(value) { + if (value < 0 || value > 100) { + throw new Error("Position must be between 0 and 100."); + } + + _position = value; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "positionAlign", + extend({}, baseObj, { + get: function get() { + return _positionAlign; + }, + set: function set(value) { + var setting = findAlignSetting(value); + + if (!setting) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + + _positionAlign = setting; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "size", + extend({}, baseObj, { + get: function get() { + return _size; + }, + set: function set(value) { + if (value < 0 || value > 100) { + throw new Error("Size must be between 0 and 100."); + } + + _size = value; + this.hasBeenReset = true; + }, + }) + ); + Object.defineProperty( + cue, + "align", + extend({}, baseObj, { + get: function get() { + return _align; + }, + set: function set(value) { + var setting = findAlignSetting(value); + + if (!setting) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + + _align = setting; + this.hasBeenReset = true; + }, + }) + ); + /** + * Other <track> spec defined properties + */ + // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state + + cue.displayState = undefined; + } + /** + * VTTCue methods + */ + + VTTCue.prototype.getCueAsHTML = function () { + // Assume WebVTT.convertCueToDOMTree is on the global. + var WebVTT = self.WebVTT; + return WebVTT.convertCueToDOMTree(self, this.text); + }; // this is a polyfill hack + + return VTTCue; + })(); + + /***/ + }, + + /***/ "./src/utils/vttparser.ts": + /*!********************************!*\ + !*** ./src/utils/vttparser.ts ***! + \********************************/ + /*! exports provided: parseTimeStamp, fixLineBreaks, VTTParser */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseTimeStamp", function () { + return parseTimeStamp; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fixLineBreaks", function () { + return fixLineBreaks; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VTTParser", function () { + return VTTParser; + }); + /* harmony import */ var _vttcue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vttcue */ "./src/utils/vttcue.ts"); + /* + * Source: https://github.com/mozilla/vtt.js/blob/master/dist/vtt.js + */ + + var StringDecoder = /*#__PURE__*/ (function () { + function StringDecoder() {} + + var _proto = StringDecoder.prototype; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _proto.decode = function decode(data, options) { + if (!data) { + return ""; + } + + if (typeof data !== "string") { + throw new Error("Error - expected string data."); + } + + return decodeURIComponent(encodeURIComponent(data)); + }; + + return StringDecoder; + })(); // Try to parse input as a time stamp. + + function parseTimeStamp(input) { + function computeSeconds(h, m, s, f) { + return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + parseFloat(f || 0); + } + + var m = input.match(/^(?:(\d+):)?(\d{2}):(\d{2})(\.\d+)?/); + + if (!m) { + return null; + } + + if (parseFloat(m[2]) > 59) { + // Timestamp takes the form of [hours]:[minutes].[milliseconds] + // First position is hours as it's over 59. + return computeSeconds(m[2], m[3], 0, m[4]); + } // Timestamp takes the form of [hours (optional)]:[minutes]:[seconds].[milliseconds] + + return computeSeconds(m[1], m[2], m[3], m[4]); + } // A settings object holds key/value pairs and will ignore anything but the first + // assignment to a specific key. + + var Settings = /*#__PURE__*/ (function () { + function Settings() { + this.values = Object.create(null); + } + + var _proto2 = Settings.prototype; + + // Only accept the first assignment to any key. + _proto2.set = function set(k, v) { + if (!this.get(k) && v !== "") { + this.values[k] = v; + } + }; // Return the value for a key, or a default value. + // If 'defaultKey' is passed then 'dflt' is assumed to be an object with + // a number of possible default values as properties where 'defaultKey' is + // the key of the property that will be chosen; otherwise it's assumed to be + // a single value. + + _proto2.get = function get(k, dflt, defaultKey) { + if (defaultKey) { + return this.has(k) ? this.values[k] : dflt[defaultKey]; + } + + return this.has(k) ? this.values[k] : dflt; + }; // Check whether we have a value for a key. + + _proto2.has = function has(k) { + return k in this.values; + }; // Accept a setting if its one of the given alternatives. + + _proto2.alt = function alt(k, v, a) { + for (var n = 0; n < a.length; ++n) { + if (v === a[n]) { + this.set(k, v); + break; + } + } + }; // Accept a setting if its a valid (signed) integer. + + _proto2.integer = function integer(k, v) { + if (/^-?\d+$/.test(v)) { + // integer + this.set(k, parseInt(v, 10)); + } + }; // Accept a setting if its a valid percentage. + + _proto2.percent = function percent(k, v) { + if (/^([\d]{1,3})(\.[\d]*)?%$/.test(v)) { + var percent = parseFloat(v); + + if (percent >= 0 && percent <= 100) { + this.set(k, percent); + return true; + } + } + + return false; + }; + + return Settings; + })(); // Helper function to parse input into groups separated by 'groupDelim', and + // interpret each group as a key/value pair separated by 'keyValueDelim'. + + function parseOptions(input, callback, keyValueDelim, groupDelim) { + var groups = groupDelim ? input.split(groupDelim) : [input]; + + for (var i in groups) { + if (typeof groups[i] !== "string") { + continue; + } + + var kv = groups[i].split(keyValueDelim); + + if (kv.length !== 2) { + continue; + } + + var _k = kv[0]; + var _v = kv[1]; + callback(_k, _v); + } + } + + var defaults = new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0, 0, ""); // 'middle' was changed to 'center' in the spec: https://github.com/w3c/webvtt/pull/244 + // Safari doesn't yet support this change, but FF and Chrome do. + + var center = defaults.align === "middle" ? "middle" : "center"; + + function parseCue(input, cue, regionList) { + // Remember the original input if we need to throw an error. + var oInput = input; // 4.1 WebVTT timestamp + + function consumeTimeStamp() { + var ts = parseTimeStamp(input); + + if (ts === null) { + throw new Error("Malformed timestamp: " + oInput); + } // Remove time stamp from input. + + input = input.replace(/^[^\sa-zA-Z-]+/, ""); + return ts; + } // 4.4.2 WebVTT cue settings + + function consumeCueSettings(input, cue) { + var settings = new Settings(); + parseOptions( + input, + function (k, v) { + var vals; + + switch (k) { + case "region": + // Find the last region we parsed with the same region id. + for (var i = regionList.length - 1; i >= 0; i--) { + if (regionList[i].id === v) { + settings.set(k, regionList[i].region); + break; + } + } + + break; + + case "vertical": + settings.alt(k, v, ["rl", "lr"]); + break; + + case "line": + vals = v.split(","); + settings.integer(k, vals[0]); + + if (settings.percent(k, vals[0])) { + settings.set("snapToLines", false); + } + + settings.alt(k, vals[0], ["auto"]); + + if (vals.length === 2) { + settings.alt("lineAlign", vals[1], ["start", center, "end"]); + } + + break; + + case "position": + vals = v.split(","); + settings.percent(k, vals[0]); + + if (vals.length === 2) { + settings.alt("positionAlign", vals[1], ["start", center, "end", "line-left", "line-right", "auto"]); + } + + break; + + case "size": + settings.percent(k, v); + break; + + case "align": + settings.alt(k, v, ["start", center, "end", "left", "right"]); + break; + } + }, + /:/, + /\s/ + ); // Apply default values for any missing fields. + + cue.region = settings.get("region", null); + cue.vertical = settings.get("vertical", ""); + var line = settings.get("line", "auto"); + + if (line === "auto" && defaults.line === -1) { + // set numeric line number for Safari + line = -1; + } + + cue.line = line; + cue.lineAlign = settings.get("lineAlign", "start"); + cue.snapToLines = settings.get("snapToLines", true); + cue.size = settings.get("size", 100); + cue.align = settings.get("align", center); + var position = settings.get("position", "auto"); + + if (position === "auto" && defaults.position === 50) { + // set numeric position for Safari + position = cue.align === "start" || cue.align === "left" ? 0 : cue.align === "end" || cue.align === "right" ? 100 : 50; + } + + cue.position = position; + } + + function skipWhitespace() { + input = input.replace(/^\s+/, ""); + } // 4.1 WebVTT cue timings. + + skipWhitespace(); + cue.startTime = consumeTimeStamp(); // (1) collect cue start time + + skipWhitespace(); + + if (input.substr(0, 3) !== "-->") { + // (3) next characters must match '-->' + throw new Error("Malformed time stamp (time stamps must be separated by '-->'): " + oInput); + } + + input = input.substr(3); + skipWhitespace(); + cue.endTime = consumeTimeStamp(); // (5) collect cue end time + // 4.1 WebVTT cue settings list. + + skipWhitespace(); + consumeCueSettings(input, cue); + } + + function fixLineBreaks(input) { + return input.replace(/<br(?: \/)?>/gi, "\n"); + } + var VTTParser = /*#__PURE__*/ (function () { + function VTTParser() { + this.state = "INITIAL"; + this.buffer = ""; + this.decoder = new StringDecoder(); + this.regionList = []; + this.cue = null; + this.oncue = void 0; + this.onparsingerror = void 0; + this.onflush = void 0; + } + + var _proto3 = VTTParser.prototype; + + _proto3.parse = function parse(data) { + var _this = this; // If there is no data then we won't decode it, but will just try to parse + // whatever is in buffer already. This may occur in circumstances, for + // example when flush() is called. + + if (data) { + // Try to decode the data that we received. + _this.buffer += _this.decoder.decode(data, { + stream: true, + }); + } + + function collectNextLine() { + var buffer = _this.buffer; + var pos = 0; + buffer = fixLineBreaks(buffer); + + while (pos < buffer.length && buffer[pos] !== "\r" && buffer[pos] !== "\n") { + ++pos; + } + + var line = buffer.substr(0, pos); // Advance the buffer early in case we fail below. + + if (buffer[pos] === "\r") { + ++pos; + } + + if (buffer[pos] === "\n") { + ++pos; + } + + _this.buffer = buffer.substr(pos); + return line; + } // 3.2 WebVTT metadata header syntax + + function parseHeader(input) { + parseOptions( + input, + function (k, v) { + // switch (k) { + // case 'region': + // 3.3 WebVTT region metadata header syntax + // console.log('parse region', v); + // parseRegion(v); + // break; + // } + }, + /:/ + ); + } // 5.1 WebVTT file parsing. + + try { + var line = ""; + + if (_this.state === "INITIAL") { + // We can't start parsing until we have the first line. + if (!/\r\n|\n/.test(_this.buffer)) { + return this; + } + + line = collectNextLine(); // strip of UTF-8 BOM if any + // https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 + + var m = line.match(/^(ïÂģÂŋ)?WEBVTT([ \t].*)?$/); + + if (!m || !m[0]) { + throw new Error("Malformed WebVTT signature."); + } + + _this.state = "HEADER"; + } + + var alreadyCollectedLine = false; + + while (_this.buffer) { + // We can't parse a line until we have the full line. + if (!/\r\n|\n/.test(_this.buffer)) { + return this; + } + + if (!alreadyCollectedLine) { + line = collectNextLine(); + } else { + alreadyCollectedLine = false; + } + + switch (_this.state) { + case "HEADER": + // 13-18 - Allow a header (metadata) under the WEBVTT line. + if (/:/.test(line)) { + parseHeader(line); + } else if (!line) { + // An empty line terminates the header and starts the body (cues). + _this.state = "ID"; + } + + continue; + + case "NOTE": + // Ignore NOTE blocks. + if (!line) { + _this.state = "ID"; + } + + continue; + + case "ID": + // Check for the start of NOTE blocks. + if (/^NOTE($|[ \t])/.test(line)) { + _this.state = "NOTE"; + break; + } // 19-29 - Allow any number of line terminators, then initialize new cue values. + + if (!line) { + continue; + } + + _this.cue = new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0, 0, ""); + _this.state = "CUE"; // 30-39 - Check if self line contains an optional identifier or timing data. + + if (line.indexOf("-->") === -1) { + _this.cue.id = line; + continue; + } + + // Process line as start of a cue. + + /* falls through */ + + case "CUE": + // 40 - Collect cue timings and settings. + if (!_this.cue) { + _this.state = "BADCUE"; + continue; + } + + try { + parseCue(line, _this.cue, _this.regionList); + } catch (e) { + // In case of an error ignore rest of the cue. + _this.cue = null; + _this.state = "BADCUE"; + continue; + } + + _this.state = "CUETEXT"; + continue; + + case "CUETEXT": + { + var hasSubstring = line.indexOf("-->") !== -1; // 34 - If we have an empty line then report the cue. + // 35 - If we have the special substring '-->' then report the cue, + // but do not collect the line as we need to process the current + // one as a new cue. + + if (!line || (hasSubstring && (alreadyCollectedLine = true))) { + // We are done parsing self cue. + if (_this.oncue && _this.cue) { + _this.oncue(_this.cue); + } + + _this.cue = null; + _this.state = "ID"; + continue; + } + + if (_this.cue === null) { + continue; + } + + if (_this.cue.text) { + _this.cue.text += "\n"; + } + + _this.cue.text += line; + } + continue; + + case "BADCUE": + // 54-62 - Collect and discard the remaining cue. + if (!line) { + _this.state = "ID"; + } + } + } + } catch (e) { + // If we are currently parsing a cue, report what we have. + if (_this.state === "CUETEXT" && _this.cue && _this.oncue) { + _this.oncue(_this.cue); + } + + _this.cue = null; // Enter BADWEBVTT state if header was not parsed correctly otherwise + // another exception occurred so enter BADCUE state. + + _this.state = _this.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; + } + + return this; + }; + + _proto3.flush = function flush() { + var _this = this; + + try { + // Finish decoding the stream. + // _this.buffer += _this.decoder.decode(); + // Synthesize the end of the current cue or region. + if (_this.cue || _this.state === "HEADER") { + _this.buffer += "\n\n"; + + _this.parse(); + } // If we've flushed, parsed, and we're still on the INITIAL state then + // that means we don't have enough of the stream to parse the first + // line. + + if (_this.state === "INITIAL" || _this.state === "BADWEBVTT") { + throw new Error("Malformed WebVTT signature."); + } + } catch (e) { + if (_this.onparsingerror) { + _this.onparsingerror(e); + } + } + + if (_this.onflush) { + _this.onflush(); + } + + return this; + }; + + return VTTParser; + })(); + + /***/ + }, + + /***/ "./src/utils/webvtt-parser.ts": + /*!************************************!*\ !*** ./src/utils/webvtt-parser.ts ***! \************************************/ -/*! exports provided: generateCueId, parseWebVTT */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: generateCueId, parseWebVTT */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateCueId", function () { + return generateCueId; + }); + /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseWebVTT", function () { + return parseWebVTT; + }); + /* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); + /* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts"); + /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); + /* harmony import */ var _timescale_conversion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./timescale-conversion */ "./src/utils/timescale-conversion.ts"); + /* harmony import */ var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../remux/mp4-remuxer */ "./src/remux/mp4-remuxer.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateCueId", function() { return generateCueId; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseWebVTT", function() { return parseWebVTT; }); -/* harmony import */ var _home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts"); -/* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts"); -/* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts"); -/* harmony import */ var _timescale_conversion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./timescale-conversion */ "./src/utils/timescale-conversion.ts"); -/* harmony import */ var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../remux/mp4-remuxer */ "./src/remux/mp4-remuxer.ts"); + var LINEBREAKS = /\r\n|\n\r|\n|\r/g; // String.prototype.startsWith is not supported in IE11 + var startsWith = function startsWith(inputString, searchString, position) { + if (position === void 0) { + position = 0; + } + return inputString.substr(position, searchString.length) === searchString; + }; + var cueString2millis = function cueString2millis(timeString) { + var ts = parseInt(timeString.substr(-3)); + var secs = parseInt(timeString.substr(-6, 2)); + var mins = parseInt(timeString.substr(-9, 2)); + var hours = timeString.length > 9 ? parseInt(timeString.substr(0, timeString.indexOf(":"))) : 0; + if ( + !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(ts) || + !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(secs) || + !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mins) || + !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(hours) + ) { + throw Error("Malformed X-TIMESTAMP-MAP: Local:" + timeString); + } + ts += 1000 * secs; + ts += 60 * 1000 * mins; + ts += 60 * 60 * 1000 * hours; + return ts; + }; // From https://github.com/darkskyapp/string-hash + var hash = function hash(text) { + var hash = 5381; + var i = text.length; + while (i) { + hash = (hash * 33) ^ text.charCodeAt(--i); + } -var LINEBREAKS = /\r\n|\n\r|\n|\r/g; // String.prototype.startsWith is not supported in IE11 + return (hash >>> 0).toString(); + }; // Create a unique hash id for a cue based on start/end times and text. + // This helps timeline-controller to avoid showing repeated captions. -var startsWith = function startsWith(inputString, searchString, position) { - if (position === void 0) { - position = 0; - } + function generateCueId(startTime, endTime, text) { + return hash(startTime.toString()) + hash(endTime.toString()) + hash(text); + } - return inputString.substr(position, searchString.length) === searchString; -}; + var calculateOffset = function calculateOffset(vttCCs, cc, presentationTime) { + var currCC = vttCCs[cc]; + var prevCC = vttCCs[currCC.prevCC]; // This is the first discontinuity or cues have been processed since the last discontinuity + // Offset = current discontinuity time -var cueString2millis = function cueString2millis(timeString) { - var ts = parseInt(timeString.substr(-3)); - var secs = parseInt(timeString.substr(-6, 2)); - var mins = parseInt(timeString.substr(-9, 2)); - var hours = timeString.length > 9 ? parseInt(timeString.substr(0, timeString.indexOf(':'))) : 0; + if (!prevCC || (!prevCC.new && currCC.new)) { + vttCCs.ccOffset = vttCCs.presentationOffset = currCC.start; + currCC.new = false; + return; + } // There have been discontinuities since cues were last parsed. + // Offset = time elapsed - if (!Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(ts) || !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(secs) || !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(mins) || !Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(hours)) { - throw Error("Malformed X-TIMESTAMP-MAP: Local:" + timeString); - } + while ((_prevCC = prevCC) !== null && _prevCC !== void 0 && _prevCC.new) { + var _prevCC; - ts += 1000 * secs; - ts += 60 * 1000 * mins; - ts += 60 * 60 * 1000 * hours; - return ts; -}; // From https://github.com/darkskyapp/string-hash + vttCCs.ccOffset += currCC.start - prevCC.start; + currCC.new = false; + currCC = prevCC; + prevCC = vttCCs[currCC.prevCC]; + } + vttCCs.presentationOffset = presentationTime; + }; -var hash = function hash(text) { - var hash = 5381; - var i = text.length; + function parseWebVTT(vttByteArray, initPTS, timescale, vttCCs, cc, timeOffset, callBack, errorCallBack) { + var parser = new _vttparser__WEBPACK_IMPORTED_MODULE_1__["VTTParser"](); // Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character. + // Uint8Array.prototype.reduce is not implemented in IE11 - while (i) { - hash = hash * 33 ^ text.charCodeAt(--i); - } + var vttLines = Object(_demux_id3__WEBPACK_IMPORTED_MODULE_2__["utf8ArrayToStr"])(new Uint8Array(vttByteArray)).trim().replace(LINEBREAKS, "\n").split("\n"); + var cues = []; + var initPTS90Hz = Object(_timescale_conversion__WEBPACK_IMPORTED_MODULE_3__["toMpegTsClockFromTimescale"])(initPTS, timescale); + var cueTime = "00:00.000"; + var timestampMapMPEGTS = 0; + var timestampMapLOCAL = 0; + var parsingError; + var inHeader = true; + var timestampMap = false; - return (hash >>> 0).toString(); -}; // Create a unique hash id for a cue based on start/end times and text. -// This helps timeline-controller to avoid showing repeated captions. + parser.oncue = function (cue) { + // Adjust cue timing; clamp cues to start no earlier than - and drop cues that don't end after - 0 on timeline. + var currCC = vttCCs[cc]; + var cueOffset = vttCCs.ccOffset; // Calculate subtitle PTS offset + var webVttMpegTsMapOffset = (timestampMapMPEGTS - initPTS90Hz) / 90000; // Update offsets for new discontinuities -function generateCueId(startTime, endTime, text) { - return hash(startTime.toString()) + hash(endTime.toString()) + hash(text); -} + if (currCC !== null && currCC !== void 0 && currCC.new) { + if (timestampMapLOCAL !== undefined) { + // When local time is provided, offset = discontinuity start time - local time + cueOffset = vttCCs.ccOffset = currCC.start; + } else { + calculateOffset(vttCCs, cc, webVttMpegTsMapOffset); + } + } -var calculateOffset = function calculateOffset(vttCCs, cc, presentationTime) { - var currCC = vttCCs[cc]; - var prevCC = vttCCs[currCC.prevCC]; // This is the first discontinuity or cues have been processed since the last discontinuity - // Offset = current discontinuity time + if (webVttMpegTsMapOffset) { + // If we have MPEGTS, offset = presentation time + discontinuity offset + cueOffset = webVttMpegTsMapOffset - vttCCs.presentationOffset; + } - if (!prevCC || !prevCC.new && currCC.new) { - vttCCs.ccOffset = vttCCs.presentationOffset = currCC.start; - currCC.new = false; - return; - } // There have been discontinuities since cues were last parsed. - // Offset = time elapsed + if (timestampMap) { + var duration = cue.endTime - cue.startTime; + var startTime = Object(_remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__["normalizePts"])((cue.startTime + cueOffset - timestampMapLOCAL) * 90000, timeOffset * 90000) / 90000; + cue.startTime = startTime; + cue.endTime = startTime + duration; + } //trim trailing webvtt block whitespaces + var text = cue.text.trim(); // Fix encoding of special characters - while ((_prevCC = prevCC) !== null && _prevCC !== void 0 && _prevCC.new) { - var _prevCC; + cue.text = decodeURIComponent(encodeURIComponent(text)); // If the cue was not assigned an id from the VTT file (line above the content), create one. - vttCCs.ccOffset += currCC.start - prevCC.start; - currCC.new = false; - currCC = prevCC; - prevCC = vttCCs[currCC.prevCC]; - } + if (!cue.id) { + cue.id = generateCueId(cue.startTime, cue.endTime, text); + } - vttCCs.presentationOffset = presentationTime; -}; + if (cue.endTime > 0) { + cues.push(cue); + } + }; -function parseWebVTT(vttByteArray, initPTS, timescale, vttCCs, cc, timeOffset, callBack, errorCallBack) { - var parser = new _vttparser__WEBPACK_IMPORTED_MODULE_1__["VTTParser"](); // Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character. - // Uint8Array.prototype.reduce is not implemented in IE11 + parser.onparsingerror = function (error) { + parsingError = error; + }; - var vttLines = Object(_demux_id3__WEBPACK_IMPORTED_MODULE_2__["utf8ArrayToStr"])(new Uint8Array(vttByteArray)).trim().replace(LINEBREAKS, '\n').split('\n'); - var cues = []; - var initPTS90Hz = Object(_timescale_conversion__WEBPACK_IMPORTED_MODULE_3__["toMpegTsClockFromTimescale"])(initPTS, timescale); - var cueTime = '00:00.000'; - var timestampMapMPEGTS = 0; - var timestampMapLOCAL = 0; - var parsingError; - var inHeader = true; - var timestampMap = false; + parser.onflush = function () { + if (parsingError) { + errorCallBack(parsingError); + return; + } - parser.oncue = function (cue) { - // Adjust cue timing; clamp cues to start no earlier than - and drop cues that don't end after - 0 on timeline. - var currCC = vttCCs[cc]; - var cueOffset = vttCCs.ccOffset; // Calculate subtitle PTS offset + callBack(cues); + }; // Go through contents line by line. - var webVttMpegTsMapOffset = (timestampMapMPEGTS - initPTS90Hz) / 90000; // Update offsets for new discontinuities + vttLines.forEach(function (line) { + if (inHeader) { + // Look for X-TIMESTAMP-MAP in header. + if (startsWith(line, "X-TIMESTAMP-MAP=")) { + // Once found, no more are allowed anyway, so stop searching. + inHeader = false; + timestampMap = true; // Extract LOCAL and MPEGTS. - if (currCC !== null && currCC !== void 0 && currCC.new) { - if (timestampMapLOCAL !== undefined) { - // When local time is provided, offset = discontinuity start time - local time - cueOffset = vttCCs.ccOffset = currCC.start; - } else { - calculateOffset(vttCCs, cc, webVttMpegTsMapOffset); - } - } + line + .substr(16) + .split(",") + .forEach(function (timestamp) { + if (startsWith(timestamp, "LOCAL:")) { + cueTime = timestamp.substr(6); + } else if (startsWith(timestamp, "MPEGTS:")) { + timestampMapMPEGTS = parseInt(timestamp.substr(7)); + } + }); - if (webVttMpegTsMapOffset) { - // If we have MPEGTS, offset = presentation time + discontinuity offset - cueOffset = webVttMpegTsMapOffset - vttCCs.presentationOffset; - } + try { + // Convert cue time to seconds + timestampMapLOCAL = cueString2millis(cueTime) / 1000; + } catch (error) { + timestampMap = false; + parsingError = error; + } // Return without parsing X-TIMESTAMP-MAP line. - if (timestampMap) { - var duration = cue.endTime - cue.startTime; - var startTime = Object(_remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__["normalizePts"])((cue.startTime + cueOffset - timestampMapLOCAL) * 90000, timeOffset * 90000) / 90000; - cue.startTime = startTime; - cue.endTime = startTime + duration; - } //trim trailing webvtt block whitespaces + return; + } else if (line === "") { + inHeader = false; + } + } // Parse line by default. + parser.parse(line + "\n"); + }); + parser.flush(); + } - var text = cue.text.trim(); // Fix encoding of special characters + /***/ + }, - cue.text = decodeURIComponent(encodeURIComponent(text)); // If the cue was not assigned an id from the VTT file (line above the content), create one. - - if (!cue.id) { - cue.id = generateCueId(cue.startTime, cue.endTime, text); - } - - if (cue.endTime > 0) { - cues.push(cue); - } - }; - - parser.onparsingerror = function (error) { - parsingError = error; - }; - - parser.onflush = function () { - if (parsingError) { - errorCallBack(parsingError); - return; - } - - callBack(cues); - }; // Go through contents line by line. - - - vttLines.forEach(function (line) { - if (inHeader) { - // Look for X-TIMESTAMP-MAP in header. - if (startsWith(line, 'X-TIMESTAMP-MAP=')) { - // Once found, no more are allowed anyway, so stop searching. - inHeader = false; - timestampMap = true; // Extract LOCAL and MPEGTS. - - line.substr(16).split(',').forEach(function (timestamp) { - if (startsWith(timestamp, 'LOCAL:')) { - cueTime = timestamp.substr(6); - } else if (startsWith(timestamp, 'MPEGTS:')) { - timestampMapMPEGTS = parseInt(timestamp.substr(7)); - } - }); - - try { - // Convert cue time to seconds - timestampMapLOCAL = cueString2millis(cueTime) / 1000; - } catch (error) { - timestampMap = false; - parsingError = error; - } // Return without parsing X-TIMESTAMP-MAP line. - - - return; - } else if (line === '') { - inHeader = false; - } - } // Parse line by default. - - - parser.parse(line + '\n'); - }); - parser.flush(); -} - -/***/ }), - -/***/ "./src/utils/xhr-loader.ts": -/*!*********************************!*\ + /***/ "./src/utils/xhr-loader.ts": + /*!*********************************!*\ !*** ./src/utils/xhr-loader.ts ***! \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + /*! exports provided: default */ + /***/ function (module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__); + /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); + /* harmony import */ var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/load-stats */ "./src/loader/load-stats.ts"); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts"); -/* harmony import */ var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/load-stats */ "./src/loader/load-stats.ts"); + var AGE_HEADER_LINE_REGEX = /^age:\s*[\d.]+\s*$/m; + var XhrLoader = /*#__PURE__*/ (function () { + function XhrLoader( + config + /* CiderHlsConfig */ + ) { + this.xhrSetup = void 0; + this.requestTimeout = void 0; + this.retryTimeout = void 0; + this.retryDelay = void 0; + this.config = null; + this.callbacks = null; + this.context = void 0; + this.loader = null; + this.stats = void 0; + this.xhrSetup = config ? config.xhrSetup : null; + this.stats = new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__["LoadStats"](); + this.retryDelay = 0; + } -var AGE_HEADER_LINE_REGEX = /^age:\s*[\d.]+\s*$/m; + var _proto = XhrLoader.prototype; -var XhrLoader = /*#__PURE__*/function () { - function XhrLoader(config - /* CiderHlsConfig */ - ) { - this.xhrSetup = void 0; - this.requestTimeout = void 0; - this.retryTimeout = void 0; - this.retryDelay = void 0; - this.config = null; - this.callbacks = null; - this.context = void 0; - this.loader = null; - this.stats = void 0; - this.xhrSetup = config ? config.xhrSetup : null; - this.stats = new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__["LoadStats"](); - this.retryDelay = 0; - } + _proto.destroy = function destroy() { + this.callbacks = null; + this.abortInternal(); + this.loader = null; + this.config = null; + }; - var _proto = XhrLoader.prototype; + _proto.abortInternal = function abortInternal() { + var loader = this.loader; + self.clearTimeout(this.requestTimeout); + self.clearTimeout(this.retryTimeout); - _proto.destroy = function destroy() { - this.callbacks = null; - this.abortInternal(); - this.loader = null; - this.config = null; - }; + if (loader) { + loader.onreadystatechange = null; + loader.onprogress = null; - _proto.abortInternal = function abortInternal() { - var loader = this.loader; - self.clearTimeout(this.requestTimeout); - self.clearTimeout(this.retryTimeout); + if (loader.readyState !== 4) { + this.stats.aborted = true; + loader.abort(); + } + } + }; - if (loader) { - loader.onreadystatechange = null; - loader.onprogress = null; + _proto.abort = function abort() { + var _this$callbacks; - if (loader.readyState !== 4) { - this.stats.aborted = true; - loader.abort(); + this.abortInternal(); + + if ((_this$callbacks = this.callbacks) !== null && _this$callbacks !== void 0 && _this$callbacks.onAbort) { + this.callbacks.onAbort(this.stats, this.context, this.loader); + } + }; + + _proto.load = function load(context, config, callbacks) { + if (this.stats.loading.start) { + throw new Error("Loader can only be used once."); + } + + this.stats.loading.start = self.performance.now(); + this.context = context; + this.config = config; + this.callbacks = callbacks; + this.retryDelay = config.retryDelay; + this.loadInternal(); + }; + + _proto.loadInternal = function loadInternal() { + var config = this.config, + context = this.context; + + if (!config) { + return; + } + + var xhr = (this.loader = new self.XMLHttpRequest()); + var stats = this.stats; + stats.loading.first = 0; + stats.loaded = 0; + var xhrSetup = this.xhrSetup; + + try { + if (xhrSetup) { + try { + xhrSetup(xhr, context.url); + } catch (e) { + // fix xhrSetup: (xhr, url) => {xhr.setRequestHeader("Content-Language", "test");} + // not working, as xhr.setRequestHeader expects xhr.readyState === OPEN + xhr.open("GET", context.url, true); + xhrSetup(xhr, context.url); + } + } + + if (!xhr.readyState) { + xhr.open("GET", context.url, true); + } + + var headers = this.context.headers; + + if (headers) { + for (var header in headers) { + xhr.setRequestHeader(header, headers[header]); + } + } + } catch (e) { + // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS + this.callbacks.onError( + { + code: xhr.status, + text: e.message, + }, + context, + xhr + ); + return; + } + + if (context.rangeEnd) { + xhr.setRequestHeader("Range", "bytes=" + context.rangeStart + "-" + (context.rangeEnd - 1)); + } + + xhr.onreadystatechange = this.readystatechange.bind(this); + xhr.onprogress = this.loadprogress.bind(this); + xhr.responseType = context.responseType; // setup timeout before we perform request + + self.clearTimeout(this.requestTimeout); + this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), config.timeout); + xhr.send(); + }; + + _proto.readystatechange = function readystatechange() { + var context = this.context, + xhr = this.loader, + stats = this.stats; + + if (!context || !xhr) { + return; + } + + var readyState = xhr.readyState; + var config = this.config; // don't proceed if xhr has been aborted + + if (stats.aborted) { + return; + } // >= HEADERS_RECEIVED + + if (readyState >= 2) { + // clear xhr timeout and rearm it if readyState less than 4 + self.clearTimeout(this.requestTimeout); + + if (stats.loading.first === 0) { + stats.loading.first = Math.max(self.performance.now(), stats.loading.start); + } + + if (readyState === 4) { + xhr.onreadystatechange = null; + xhr.onprogress = null; + var status = xhr.status; // http status between 200 to 299 are all successful + + if (status >= 200 && status < 300) { + stats.loading.end = Math.max(self.performance.now(), stats.loading.first); + var data; + var len; + + if (context.responseType === "arraybuffer") { + data = xhr.response; + len = data.byteLength; + } else { + data = xhr.responseText; + len = data.length; + } + + stats.loaded = stats.total = len; + + if (!this.callbacks) { + return; + } + + var onProgress = this.callbacks.onProgress; + + if (onProgress) { + onProgress(stats, context, data, xhr); + } + + if (!this.callbacks) { + return; + } + + var response = { + url: xhr.responseURL, + data: data, + }; + this.callbacks.onSuccess(response, stats, context, xhr); + } else { + // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error + if (stats.retry >= config.maxRetry || (status >= 400 && status < 499)) { + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].error(status + " while loading " + context.url); + this.callbacks.onError( + { + code: status, + text: xhr.statusText, + }, + context, + xhr + ); + } else { + // retry + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].warn(status + " while loading " + context.url + ", retrying in " + this.retryDelay + "..."); // abort and reset internal state + + this.abortInternal(); + this.loader = null; // schedule retry + + self.clearTimeout(this.retryTimeout); + this.retryTimeout = self.setTimeout(this.loadInternal.bind(this), this.retryDelay); // set exponential backoff + + this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay); + stats.retry++; + } + } + } else { + // readyState >= 2 AND readyState !==4 (readyState = HEADERS_RECEIVED || LOADING) rearm timeout as xhr not finished yet + self.clearTimeout(this.requestTimeout); + this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), config.timeout); + } + } + }; + + _proto.loadtimeout = function loadtimeout() { + _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].warn("timeout while loading " + this.context.url); + var callbacks = this.callbacks; + + if (callbacks) { + this.abortInternal(); + callbacks.onTimeout(this.stats, this.context, this.loader); + } + }; + + _proto.loadprogress = function loadprogress(event) { + var stats = this.stats; + stats.loaded = event.loaded; + + if (event.lengthComputable) { + stats.total = event.total; + } + }; + + _proto.getCacheAge = function getCacheAge() { + var result = null; + + if (this.loader && AGE_HEADER_LINE_REGEX.test(this.loader.getAllResponseHeaders())) { + var ageHeader = this.loader.getResponseHeader("age"); + result = ageHeader ? parseFloat(ageHeader) : null; + } + + return result; + }; + + return XhrLoader; + })(); + + /* harmony default export */ __webpack_exports__["default"] = XhrLoader; + + /***/ + }, + + /******/ } - } - }; - - _proto.abort = function abort() { - var _this$callbacks; - - this.abortInternal(); - - if ((_this$callbacks = this.callbacks) !== null && _this$callbacks !== void 0 && _this$callbacks.onAbort) { - this.callbacks.onAbort(this.stats, this.context, this.loader); - } - }; - - _proto.load = function load(context, config, callbacks) { - if (this.stats.loading.start) { - throw new Error('Loader can only be used once.'); - } - - this.stats.loading.start = self.performance.now(); - this.context = context; - this.config = config; - this.callbacks = callbacks; - this.retryDelay = config.retryDelay; - this.loadInternal(); - }; - - _proto.loadInternal = function loadInternal() { - var config = this.config, - context = this.context; - - if (!config) { - return; - } - - var xhr = this.loader = new self.XMLHttpRequest(); - var stats = this.stats; - stats.loading.first = 0; - stats.loaded = 0; - var xhrSetup = this.xhrSetup; - - try { - if (xhrSetup) { - try { - xhrSetup(xhr, context.url); - } catch (e) { - // fix xhrSetup: (xhr, url) => {xhr.setRequestHeader("Content-Language", "test");} - // not working, as xhr.setRequestHeader expects xhr.readyState === OPEN - xhr.open('GET', context.url, true); - xhrSetup(xhr, context.url); - } - } - - if (!xhr.readyState) { - xhr.open('GET', context.url, true); - } - - var headers = this.context.headers; - - if (headers) { - for (var header in headers) { - xhr.setRequestHeader(header, headers[header]); - } - } - } catch (e) { - // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS - this.callbacks.onError({ - code: xhr.status, - text: e.message - }, context, xhr); - return; - } - - if (context.rangeEnd) { - xhr.setRequestHeader('Range', 'bytes=' + context.rangeStart + '-' + (context.rangeEnd - 1)); - } - - xhr.onreadystatechange = this.readystatechange.bind(this); - xhr.onprogress = this.loadprogress.bind(this); - xhr.responseType = context.responseType; // setup timeout before we perform request - - self.clearTimeout(this.requestTimeout); - this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), config.timeout); - xhr.send(); - }; - - _proto.readystatechange = function readystatechange() { - var context = this.context, - xhr = this.loader, - stats = this.stats; - - if (!context || !xhr) { - return; - } - - var readyState = xhr.readyState; - var config = this.config; // don't proceed if xhr has been aborted - - if (stats.aborted) { - return; - } // >= HEADERS_RECEIVED - - - if (readyState >= 2) { - // clear xhr timeout and rearm it if readyState less than 4 - self.clearTimeout(this.requestTimeout); - - if (stats.loading.first === 0) { - stats.loading.first = Math.max(self.performance.now(), stats.loading.start); - } - - if (readyState === 4) { - xhr.onreadystatechange = null; - xhr.onprogress = null; - var status = xhr.status; // http status between 200 to 299 are all successful - - if (status >= 200 && status < 300) { - stats.loading.end = Math.max(self.performance.now(), stats.loading.first); - var data; - var len; - - if (context.responseType === 'arraybuffer') { - data = xhr.response; - len = data.byteLength; - } else { - data = xhr.responseText; - len = data.length; - } - - stats.loaded = stats.total = len; - - if (!this.callbacks) { - return; - } - - var onProgress = this.callbacks.onProgress; - - if (onProgress) { - onProgress(stats, context, data, xhr); - } - - if (!this.callbacks) { - return; - } - - var response = { - url: xhr.responseURL, - data: data - }; - this.callbacks.onSuccess(response, stats, context, xhr); - } else { - // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error - if (stats.retry >= config.maxRetry || status >= 400 && status < 499) { - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].error(status + " while loading " + context.url); - this.callbacks.onError({ - code: status, - text: xhr.statusText - }, context, xhr); - } else { - // retry - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].warn(status + " while loading " + context.url + ", retrying in " + this.retryDelay + "..."); // abort and reset internal state - - this.abortInternal(); - this.loader = null; // schedule retry - - self.clearTimeout(this.retryTimeout); - this.retryTimeout = self.setTimeout(this.loadInternal.bind(this), this.retryDelay); // set exponential backoff - - this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay); - stats.retry++; - } - } - } else { - // readyState >= 2 AND readyState !==4 (readyState = HEADERS_RECEIVED || LOADING) rearm timeout as xhr not finished yet - self.clearTimeout(this.requestTimeout); - this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), config.timeout); - } - } - }; - - _proto.loadtimeout = function loadtimeout() { - _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].warn("timeout while loading " + this.context.url); - var callbacks = this.callbacks; - - if (callbacks) { - this.abortInternal(); - callbacks.onTimeout(this.stats, this.context, this.loader); - } - }; - - _proto.loadprogress = function loadprogress(event) { - var stats = this.stats; - stats.loaded = event.loaded; - - if (event.lengthComputable) { - stats.total = event.total; - } - }; - - _proto.getCacheAge = function getCacheAge() { - var result = null; - - if (this.loader && AGE_HEADER_LINE_REGEX.test(this.loader.getAllResponseHeaders())) { - var ageHeader = this.loader.getResponseHeader('age'); - result = ageHeader ? parseFloat(ageHeader) : null; - } - - return result; - }; - - return XhrLoader; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (XhrLoader); - -/***/ }) - -/******/ })["default"]; -}); -//# sourceMappingURL=CiderHls.js.map \ No newline at end of file + )["default"]; + }); +//# sourceMappingURL=CiderHls.js.map diff --git a/src/renderer/index.js b/src/renderer/index.js index a7075497..9f735a55 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -1,3839 +1,296 @@ -Vue.use(VueObserveVisibility); var notyf = new Notyf(); -// This is going to suck to code -var CiderContextMenu = { - Menu: function(event) { - this.items = [] - }, - async Create(event, menudata) { - var menuBackground = document.createElement("div"); - var menu = document.createElement("div"); - menu.classList.add("context-menu-body"); - menu.classList.add("context-menu-open"); - menuBackground.classList.add("context-menu"); - menu.style.left = 0 + "px"; - menu.style.top = 0 + "px"; - menu.style.position = "absolute"; - menu.style.zIndex = "99909"; - menu.addEventListener("animationend", function() { - menu.classList.remove("context-menu-open"); - }, { once: true }); - function close() { - menuBackground.style.pointerEvents = "none"; - menu.classList.add("context-menu-close"); - menu.addEventListener("animationend", function() { - menuBackground.remove(); - menu.remove(); - }, { once: true }); - } - - // when menubackground is clicked, remove it - menuBackground.addEventListener("click", close); - menuBackground.addEventListener("contextmenu", close); - - // add menu to menuBackground - menuBackground.appendChild(menu); - - document.body.appendChild(menuBackground); - - if (typeof menudata.items == "object") { - menudata.items = Object.values(menudata.items); - } - - console.log(menudata); - - // for each item in menudata create a menu item - for (var i = 0; i < menudata.items.length; i++) { - let item = document.createElement("button") - - if (menudata.items[i]["disabled"] === true) { - continue - } - item.tabIndex = 0 - item.classList.add("context-menu-item") - if (menudata.items[i]["icon"]) { - item.innerHTML += `<div class="sidebar-icon">${await app.getSvgIcon(menudata.items[i]["icon"])}</div>` - } - item.innerHTML += menudata.items[i].name - item.onclick = menudata.items[i].action - menu.appendChild(item) - } - menu.style.width = (menu.offsetWidth + 10) + "px"; - menu.style.left = event.clientX + "px"; - menu.style.top = event.clientY + "px"; - // if menu would be off the screen, move it into view, but preserve the width - if (menu.offsetLeft + menu.offsetWidth > window.innerWidth) { - menu.style.left = (window.innerWidth - menu.offsetWidth) + "px"; - } - if (menu.offsetTop + menu.offsetHeight > window.innerHeight) { - menu.style.top = (window.innerHeight - menu.offsetHeight) + "px"; - } - - return menuBackground; - } +function clamp(num, min, max) { + return Math.min(Math.max(num, min), max); } const MusicKitObjects = { - LibraryPlaylist: function() { - this.id = "" - this.type = "library-playlist-folders" - this.href = "" - this.attributes = { - dateAdded: "", - name: "" - } - this.playlists = [] - } -} - -const MusicKitTools = { - getHeader() { - return new Headers({ - Authorization: 'Bearer ' + MusicKit.getInstance().developerToken, - Accept: 'application/json', - 'Content-Type': 'application/json', - 'Music-User-Token': '' + MusicKit.getInstance().musicUserToken - }); - } -} - -// limit an array to a certain number of items -Array.prototype.limit = function(n) { - return this.slice(0, n); + LibraryPlaylist: function () { + this.id = ""; + this.type = "library-playlist-folders"; + this.href = ""; + this.attributes = { + dateAdded: "", + name: "", + }; + this.playlists = []; + }, }; -const store = new Vuex.Store({ - state: { - library: { - songs: ipcRenderer.sendSync("get-library-songs"), - albums: ipcRenderer.sendSync("get-library-albums"), - recentlyAdded: ipcRenderer.sendSync("get-library-recentlyAdded"), - playlists: ipcRenderer.sendSync("get-library-playlists") - }, - artwork: { - playerLCD: "" - } - }, - mutations: { - setLCDArtwork(state, artwork) { - state.artwork.playerLCD = artwork - } - } -}) - -const app = new Vue({ - el: "#app", - store: store, - data: { - appMode: "player", - ipcRenderer: ipcRenderer, - cfg: ipcRenderer.sendSync("getStore"), - isDev: ipcRenderer.sendSync("is-dev"), - drawertest: false, - platform: "", - mk: {}, - quickPlayQuery: "", - lz: ipcRenderer.sendSync("get-i18n", "en_US"), - lzListing: ipcRenderer.sendSync("get-i18n-listing"), - search: { - term: "", - hints: [], - showHints: false, - results: {}, - resultsSocial: {}, - limit: 10 - }, - fullscreenLyrics: false, - playerLCD: { - playbackDuration: 0, - desiredDuration: 0, - userInteraction: false - }, - drawer: { - open: false, - panel: "" - }, - browsepage: [], - listennow: [], - madeforyou: [], - radio: { - personal: [] - }, - webview: { - url: "", - title: "", - loading: false - }, - showingPlaylist: [], - appleCurator: [], - artistPage: { - data: {}, - }, - library: { - backgroundNotification: { - show: false, - message: "", - total: 0, - progress: 0 - }, - songs: { - sortingOptions: { - "albumName": "0", - "artistName": "0", - "name": "0", - "genre": "0", - "releaseDate": "0", - "durationInMillis": "0" - }, - sorting: "name", - sortOrder: "asc", - listing: [], - meta: { total: 0, progress: 0 }, - search: "", - displayListing: [], - downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library - }, - albums: { - sortingOptions: { - "albumName": "0", - "artistName": "0", - "name": "0", - "genre": "0" - }, - viewAs: 'covers', - sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page - sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page - listing: [], - meta: { total: 0, progress: 0 }, - search: "", - displayListing: [], - downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library - }, - artists: { - sortingOptions: { - "artistName": "0", - "name": "0", - "genre": "0", - "releaseDate": "0" - }, - viewAs: 'covers', - sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page - sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page - listing: [], - meta: { total: 0, progress: 0 }, - search: "", - displayListing: [], - downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library - }, - }, - playlists: { - listing: [], - details: {}, - loadingState: 0, // 0 loading, 1 loaded, 2 error - id: "" - }, - webremoteurl : "", - webremoteqr: "", - mxmtoken: "", - mkIsReady: false, - playerReady: false, - animateBackground: false, - currentArtUrl: '', - lyricon: false, - currentTrackID: '', - currentTrackIDBG: '', - lyrics: [], - currentLyricsLine: 0, - lyriccurrenttime: 0, - richlyrics: [], - lyricsMediaItem: {}, - lyricsDebug: { - current: 0, - start: 0, - end: 0 - }, - v3: { - requestBody: { - platform: "web" - } - }, - tmpHeight : '', - tmpWidth : '', - tmpVar: [], - notification: false, - chrome: { - hideUserInfo: ipcRenderer.sendSync("is-dev") || false, - artworkReady: false, - userinfo: { - "id": "", - "attributes": { - "name": "Cider User", - "handle": "CiderUser", - "artwork": { "url": "./assets/logocut.png" } - } - }, - menuOpened: false, - maximized: false, - drawerOpened: false, - drawerState: "queue", - topChromeVisible: true, - progresshover: false, - windowControlPosition: "right" - }, - collectionList: { - response: {}, - title: "", - type: "" - }, - prevButtonBackIndicator: false, - currentSongInfo: {}, - page: "", - pageHistory: [], - songstest: false, - hangtimer: null, - selectedMediaItems: [], - routes: ["browse", "listen_now", "radio"], - musicBaseUrl: "https://api.music.apple.com/", - modals: { - addToPlaylist: false, - spatialProperties: false, - qrcode: false, - equalizer: false, - audioSettings: false, - }, - socialBadges: { - badgeMap: {}, - version: "", - mediaItems: [], - mediaItemDLState: 0 // 0 = not started, 1 = in progress, 2 = complete - }, - menuPanel: { - visible: false, - event: null, - content: { - name: "", - items: {}, - headerItems: {} - } - } - }, - watch: { - cfg: { - handler: function(val, oldVal) { - console.log(`cfg changed from ${oldVal} to ${val}`); - ipcRenderer.send("setStore", val); - }, - deep: true - }, - page: () => { - document.getElementById("app-content").scrollTo(0, 0); - app.resetState() - }, - showingPlaylist: () => { - document.getElementById("app-content").scrollTo(0, 0); - app.resetState() - }, - artistPage: () => { - document.getElementById("app-content").scrollTo(0, 0); - app.resetState() - }, - }, - methods: { - stringTemplateParser(expression, valueObj) { - const templateMatcher = /{{\s?([^{}\s]*)\s?}}/g; - let text = expression.replace(templateMatcher, (substring, value, index) => { - value = valueObj[value]; - return value; - }); - return text - // stringTemplateParser('my name is {{name}} and age is {{age}}', {name: 'Tom', age:100}) - }, - setLz(lang) { - if(lang == "") { - lang = this.cfg.general.language - } - this.lz = ipcRenderer.sendSync("get-i18n", lang) - }, - getLz(message) { - if(this.lz[message]) { - return this.lz[message] - }else{ - return message - } - }, - setLzManual() { - app.$data.library.songs.sortingOptions = { - "albumName": app.getLz('term.sortBy.album'), - "artistName": app.getLz('term.sortBy.artist'), - "name": app.getLz('term.sortBy.name'), - "genre": app.getLz('term.sortBy.genre'), - "releaseDate": app.getLz('term.sortBy.releaseDate'), - "durationInMillis": app.getLz('term.sortBy.duration') - } - - app.$data.library.albums.sortingOptions = { - "albumName": app.getLz('term.sortBy.album'), - "artistName": app.getLz('term.sortBy.artist'), - "name": app.getLz('term.sortBy.name'), - "genre": app.getLz('term.sortBy.genre') - } - - app.$data.library.artists.sortingOptions = { - "artistName": app.getLz('term.sortBy.artist'), - "name": app.getLz('term.sortBy.name'), - "genre": app.getLz('term.sortBy.genre'), - "releaseDate": app.getLz('term.sortBy.releaseDate') - } - }, - async showSocialListeningTo() { - let contentIds = Object.keys(app.socialBadges.badgeMap) - app.showCollection({ data: this.socialBadges.mediaItems }, "Friends Listening To", "albums") - if (this.socialBadges.mediaItemDLState == 1 || this.socialBadges.mediaItemDLState == 2) { - return - } - this.socialBadges.mediaItemDLState = 2 - await asyncForEach(contentIds, async(item) => { - try { - let type = "albums" - if (item.includes("pl.")) { - type = "playlists" - } - if (item.includes("ra.")) { - type = "stations" - } - let found = await app.mk.api.v3.music(`/v1/catalog/us/${type}/${item}`) - this.socialBadges.mediaItems.push(found.data.data[0]) - } catch (e) { - - } - }) - }, - async openAppleMusicURL(url) { - let properties = MusicKit.formattedMediaURL(url) - let item = { - id: properties.contentId, - attributes: { - playParams: { - id: properties.contentId, - kind: properties.kind, - } - }, - type: properties.kind, - kind: properties.kind - } - app.routeView(item) - }, - async showMenuPanel(data, event) { - app.menuPanel.visible = true; - app.menuPanel.content.name = data.name ?? ""; - app.menuPanel.content.items = data.items ?? {}; - app.menuPanel.content.headerItems = data.headerItems ?? {}; - if (event) { - app.menuPanel.event = event; - } - }, - async getSvgIcon(url) { - let response = await fetch(url); - let data = await response.text(); - return data; - }, - getSocialBadges(cb = () => {}) { - let self = this - try { - app.mk.api.v3.music("/v1/social/badging-map").then(data => { - self.socialBadges.badgeMap = data.data.results.badgingMap - cb(data.data.results.badgingMap) - }) - } catch (ex) { - this.socialBadges.badgeMap = {} - } - }, - addFavorite(id, type) { - this.cfg.home.favoriteItems.push({ - id: id, - type: type - }); - }, - modularUITest(val = false) { - this.fullscreenLyrics = val; - if (val) { - document.querySelector("#app-main").classList.add("modular-fs") - } else { - document.querySelector("#app-main").classList.remove("modular-fs") - } - }, - navigateBack() { - history.back() - }, - navigateForward() { - history.forward() - }, - getHTMLStyle() { - document.querySelector("html").style.background = "#222"; - document.querySelector("body").classList.add("notransparency") - }, - resetState() { - this.menuPanel.visible = false; - app.selectedMediaItems = []; - for (let key in app.modals) { - app.modals[key] = false; - } - }, - promptAddToPlaylist() { - app.modals.addToPlaylist = true; - }, - async addSelectedToNewPlaylist() { - let self = this - let pl_items = [] - for (let i = 0; i < self.selectedMediaItems.length; i++) { - if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") { - self.selectedMediaItems[i].kind = "songs" - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) { - self.selectedMediaItems[i].kind = "albums" - let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function (i) { - return {id: i.id, type: i.type} - }) - pl_items = pl_items.concat(ids) - } else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") { - self.selectedMediaItems[i].kind = "library-songs" - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } else if ((self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums") || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) { - self.selectedMediaItems[i].kind = "library-albums" - let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function (i) { - return {id: i.id, type: i.type} - }) - pl_items = pl_items.concat(ids) - } else { - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } - } - this.modals.addToPlaylist = false - app.newPlaylist(app.getLz('term.newPlaylist'), pl_items) - }, - async addSelectedToPlaylist(playlist_id) { - let self = this - let pl_items = [] - for (let i = 0; i < self.selectedMediaItems.length; i++) { - if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") { - self.selectedMediaItems[i].kind = "songs" - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) { - self.selectedMediaItems[i].kind = "albums" - let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function(i) { - return { id: i.id, type: i.type } - }) - pl_items = pl_items.concat(ids) - } else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") { - self.selectedMediaItems[i].kind = "library-songs" - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } else if ((self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums") || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) { - self.selectedMediaItems[i].kind = "library-albums" - let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function(i) { - return { id: i.id, type: i.type } - }) - pl_items = pl_items.concat(ids) - } else { - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } - - } - this.modals.addToPlaylist = false - await app.mk.api.v3.music( - `/v1/me/library/playlists/${playlist_id}/tracks`, {}, { - fetchOptions: { - method: "POST", - body: JSON.stringify({ - data: pl_items - }) - } - } - ).then(() => { - if (this.page == 'playlist_' + this.showingPlaylist.id) { - this.getPlaylistFromID(this.showingPlaylist.id) - } - }) - }, - async init() { - let self = this - this.setLz(this.cfg.general.language) - this.setLzManual() - clearTimeout(this.hangtimer) - this.mk = MusicKit.getInstance() - let needsReload = (typeof localStorage["music.ampwebplay.media-user-token"] == "undefined") - this.mk.authorize().then(() => { - self.mkIsReady = true - if(needsReload) { - document.location.reload() - } - }) - this.$forceUpdate() - if (this.isDev) { - this.mk.privateEnabled = true - // Hide UserInfo if Dev mode - this.chrome.hideUserInfo = true - } else { - // Get Hide User from Settings - this.chrome.hideUserInfo = !this.cfg.visual.showuserinfo - } - if (this.cfg.visual.hw_acceleration == "disabled") { - document.body.classList.add("no-gpu") - } - this.mk._services.timing.mode = 0 - this.platform = ipcRenderer.sendSync('cider-platform'); - - try { - // Set profile name - this.chrome.userinfo = (await app.mk.api.v3.music(`/v1/me/social-profile`)).data.data[0] - } catch (err) {} - - // API Fallback - if (!this.chrome.userinfo) { - this.chrome.userinfo = { - "id": "", - "attributes": { - "name": "Cider User", - "handle": "CiderUser", - "artwork": { "url": "./assets/logocut.png" } - } - } - } - MusicKitInterop.init() - // Set the volume - - // Check the value of this.cfg.audio.muted - if( !this.cfg.audio.muted ) - { - // Set the mk.volume to the last stored volume data - this.mk.volume = this.cfg.audio.volume - } else if( this.cfg.audio.muted ) { - // Set mk.volume to -1 (setting to 0 wont work, so temp solution setting to -1) - this.mk.volume = -1; - } - // ipcRenderer.invoke('getStoreValue', 'audio.volume').then((value) => { - // self.mk.volume = value - // }) - - // load cached library - if (localStorage.getItem("librarySongs") != null) { - this.library.songs.listing = JSON.parse(localStorage.getItem("librarySongs")) - this.library.songs.displayListing = this.library.songs.listing - } - if (localStorage.getItem("libraryAlbums") != null) { - this.library.albums.listing = JSON.parse(localStorage.getItem("libraryAlbums")) - this.library.albums.displayListing = this.library.albums.listing - } - - window.onbeforeunload = function(e) { - window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem)) - window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime)) - window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue.items)) - }; - - // Load saved quality - switch (app.cfg.audio.quality) { - /** case "extreme": - app.mk.bitrate = app.cfg.audio.quality = 990 - break; **/ - case "high": - app.mk.bitrate = app.cfg.audio.quality = 256 - break; - case "low": - app.mk.bitrate = app.cfg.audio.quality = 64 - break; - default: - // app.mk.bitrate = app.cfg.audio.quality - break; - } - - - // load last played track - try { - let lastItem = window.localStorage.getItem("currentTrack") - let time = window.localStorage.getItem("currentTime") - let queue = window.localStorage.getItem("currentQueue") - if (lastItem != null) { - lastItem = JSON.parse(lastItem) - let kind = lastItem.attributes.playParams.kind; - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - app.mk.setQueue({ - [truekind]: [lastItem.attributes.playParams.id] - }) - app.mk.mute() - setTimeout(() => { - app.mk.play().then(() => { - app.mk.pause().then(() => { - if (time != null) { - app.mk.seekToTime(time) - } - app.mk.unmute() - if (queue != null) { - queue = JSON.parse(queue) - if (queue && queue.length > 0) { - let ids = queue.map(e => (e.playParams ? e.playParams.id : (e.attributes.playParams ? e.attributes.playParams.id : ''))) - let i = 0; - if (ids.length > 0) { - for (id of ids) { - if (!(i == 0 && ids[0] == lastItem.attributes.playParams.id)) { - try { - app.mk.playLater({ songs: [id] }) - } catch (err) {} - } - i++; - } - } - } - } - - }) - - }) - }, 1500) - - } - - } catch (e) { - console.log(e) - } - - MusicKit.getInstance().videoContainerElement = document.getElementById("apple-music-video-player") - - ipcRenderer.on('SoundCheckTag', (event, tag) => { - let replaygain = self.parseSCTagToRG(tag) - try { - CiderAudio.audioNodes.gainNode.gain.value = (Math.min(Math.pow(10, (replaygain.gain / 20)), (1 / replaygain.peak))) - } catch (e) { - - } - }) - - ipcRenderer.on('play', function(_event, mode, id) { - if (mode !== 'url'){ - self.mk.setQueue({[mode]: id}).then(() => { - app.mk.play() - }) - } else { - app.openAppleMusicURL(id) - } - }); - - this.mk.addEventListener(MusicKit.Events.playbackStateDidChange, ()=>{ - ipcRenderer.send('wsapi-updatePlaybackState', wsapi.getAttributes()); - }) - - this.mk.addEventListener(MusicKit.Events.playbackTimeDidChange, (a) => { - self.lyriccurrenttime = self.mk.currentPlaybackTime - this.currentSongInfo = a - self.playerLCD.playbackDuration = (self.mk.currentPlaybackTime) - // wsapi - ipcRenderer.send('wsapi-updatePlaybackState', wsapi.getAttributes()); - }) - - this.mk.addEventListener(MusicKit.Events.nowPlayingItemDidChange, (a) => { - if (self.$refs.queue) { - self.$refs.queue.updateQueue(); - } - this.currentSongInfo = a - - - if (app.cfg.audio.normalization) { - // get unencrypted audio previews to get SoundCheck's normalization tag - try { - let previewURL = null - try { - previewURL = app.mk.nowPlayingItem.previewURL - } catch (e) {} - if (!previewURL) { - app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id}`).then((response) => { - previewURL = response.data.data[0].attributes.previews[0].url - if (previewURL) - ipcRenderer.send('getPreviewURL', previewURL) - }) - } else { - if (previewURL) - ipcRenderer.send('getPreviewURL', previewURL) - } - - } catch (e) {} - } - - try { - a = a.item.attributes; - } catch (_) {} - let type = (self.mk.nowPlayingItem != null) ? self.mk.nowPlayingItem["type"] ?? '' : ''; - - if (type.includes("musicVideo") || type.includes("uploadedVideo") || type.includes("music-movie")) { - document.getElementById("apple-music-video-container").style.display = "block"; - // app.chrome.topChromeVisible = false - } else { - document.getElementById("apple-music-video-container").style.display = "none"; - // app.chrome.topChromeVisible = true - } - self.chrome.artworkReady = false - self.lyrics = [] - self.richlyrics = [] - app.getCurrentArtURL(); - // app.getNowPlayingArtwork(42); - app.getNowPlayingArtworkBG(32); - app.loadLyrics(); - - // Playback Notifications - if (this.cfg.general.playbackNotifications && !document.hasFocus() && a.artistName && a.artwork && a.name) { - if (this.notification) { - this.notification.close() - } - this.notification = new Notification(a.name, { - body: a.artistName, - icon: a.artwork.url.replace('/{w}x{h}bb', '/512x512bb').replace('/2000x2000bb', '/35x35bb'), - silent: true, - }); - } - - }) - - - this.mk.addEventListener(MusicKit.Events.playbackVolumeDidChange, (_a) => { - this.cfg.audio.volume = this.mk.volume - }) - - this.refreshPlaylists() - document.body.removeAttribute("loading") - if (window.location.hash != "") { - this.appRoute(window.location.hash) - } else { - this.page = "home" - } - - setTimeout(() => { - this.getSocialBadges() - this.getBrowsePage(); - this.$forceUpdate() - }, 500) - }, - unauthorize() { - this.mk.unauthorize() - document.location.reload() - }, - getAppClasses() { - let classes = {} - if (this.cfg.advanced.experiments.includes('compactui')) { - classes.compact = true - } - if(this.cfg.visual.window_background_style == "none") { - classes.simplebg = true - } - return classes - }, - invokeDrawer(panel) { - if (this.drawer.panel == panel && this.drawer.open) { - if (panel == "lyrics") { - this.lyricon = false - } - this.drawer.panel = "" - this.drawer.open = false - } else { - if (panel == "lyrics") { - this.lyricon = true - } else { - this.lyricon = false - } - this.drawer.open = true - this.drawer.panel = panel - } - }, - select_removeMediaItem(id) { - this.selectedMediaItems.filter(item => item.guid == id).forEach(item => { - this.selectedMediaItems.splice(this.selectedMediaItems.indexOf(item), 1) - }) - }, - select_hasMediaItem(id) { - let found = this.selectedMediaItems.find(item => item.guid == id) - if (found) { - return true - } else { - return false - } - }, - select_selectMediaItem(id, kind, index, guid, library) { - if (!this.select_hasMediaItem(guid)) { - this.selectedMediaItems.push({ - id: id, - kind: kind, - index: index, - guid: guid, - isLibrary: library - }) - } - }, - getPlaylistFolderChildren(id) { - return this.playlists.listing.filter(playlist => { - if (playlist.parent == id) { - return playlist - } - }) - }, - async refreshPlaylists() { - let self = this - this.apiCall('https://api.music.apple.com/v1/me/library/playlist-folders/p.playlistsroot/children/', res => { - self.playlists.listing = res.data - self.playlists.listing.forEach(playlist => { - playlist.parent = "p.playlistsroot" - }) - self.sortPlaylists() - }) - }, - sortPlaylists() { - this.playlists.listing.sort((a, b) => { - if (a.type === "library-playlist-folders" && b.type !== "library-playlist-folders") { - return -1 - } else if (a.type !== "library-playlist-folders" && b.type === "library-playlist-folders") { - return 1 - } else { - return 0 - } - }) - }, - playlistHeaderContextMenu(event) { - let menu = { - items: [{ - name: app.getLz('term.createNewPlaylist'), - action: () => { - this.newPlaylist() - } - }, - { - name: app.getLz('term.createNewPlaylistFolder'), - action: () => { - this.newPlaylistFolder() - } - } - ] - } - this.showMenuPanel(menu, event) - }, - async editPlaylistFolder(id, name = app.getLz('term.newPlaylist')) { - let self = this - this.mk.api.v3.music( - `/v1/me/library/playlist-folders/${id}`, {}, { - fetchOptions: { - method: "PATCH", - body: JSON.stringify({ - attributes: { name: name } - }) - } - } - ).then(res => { - self.refreshPlaylists() - }) - }, - async editPlaylist(id, name = app.getLz('term.newPlaylist')) { - let self = this - this.mk.api.v3.music( - `/v1/me/library/playlists/${id}`, {}, { - fetchOptions: { - method: "PATCH", - body: JSON.stringify({ - attributes: { name: name } - }) - } - } - ).then(res => { - self.refreshPlaylists() - }) - }, - copyToClipboard(str) { - navigator.clipboard.writeText(str) - }, - newPlaylist(name = app.getLz('term.newPlaylist'), tracks = []) { - let self = this - let request = { - name: name - } - if (tracks.length > 0) { - request.tracks = tracks - } - app.mk.api.v3.music(`/v1/me/library/playlists`, {}, { - fetchOptions: { - method: "POST", - body: JSON.stringify({ - "attributes": { "name": name }, - "relationships": { - "tracks": { "data": tracks }, - } - }) - } - }).then(res => { - res = res.data.data[0] - console.log(res) - self.appRoute(`playlist_` + res.id); - self.showingPlaylist = []; - self.getPlaylistFromID(app.page.substring(9)) - self.playlists.listing.push({ - id: res.id, - attributes: { - name: name - }, - parent: "p.playlistsroot" - }) - self.sortPlaylists() - setTimeout(() => { - app.refreshPlaylists() - }, 8000) - }) - }, - deletePlaylist(id) { - let self = this - if (confirm(app.getLz('term.deletePlaylist'))) { - app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, {}, { - fetchOptions: { - method: "DELETE" - } - }).then(res => { - // remove this playlist from playlists.listing if it exists - let found = self.playlists.listing.find(item => item.id == id) - if (found) { - self.playlists.listing.splice(self.playlists.listing.indexOf(found), 1) - } - }) - } - }, - async showCollection(response, title, type, requestBody = {}) { - let self = this - console.log(response) - this.collectionList.requestBody = {} - this.collectionList.response = response - this.collectionList.title = title - this.collectionList.type = type - this.collectionList.requestBody = requestBody - app.appRoute("collection-list") - }, - async showArtistView(artist, title, view) { - let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artist}/view/${view}`,{}, {includeResponseMeta: !0})).data - console.log(response) - await this.showCollection(response, title, "artists") - }, - async showRecordLabelView(label, title, view) { - let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/record-labels/${label}/view/${view}`)).data - await this.showCollection(response, title, "record-labels") - }, - async showSearchView(term, group, title) { - - let requestBody = { - platform: "web", - groups: group, - types: "activities,albums,apple-curators,artists,curators,editorial-items,music-movies,music-videos,playlists,songs,stations,tv-episodes,uploaded-videos,record-labels", - limit: 25, - relate: { - editorialItems: ["contents"] - }, - include: { - albums: ["artists"], - songs: ["artists"], - "music-videos": ["artists"] - }, - extend: "artistUrl", - fields: { - artists: "url,name,artwork,hero", - albums: "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url" - }, - with: "serverBubbles,lyricHighlights", - art: { - "url": "cf" - }, - omit: { - resource: ["autos"] - }, - groups: group - } - let response = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${term}`, requestBody , { - includeResponseMeta: !0 - }) - - console.log('searchres', response) - let responseFormat = { - data: response.data.results[group].data, - next: response.data.results[group].next, - groups: group - } - await this.showCollection(responseFormat, title, "search", requestBody) - }, - async getPlaylistContinuous(response, transient = false) { - response = response.data.data[0] - let self = this - let playlistId = response.id - if (!transient) this.playlists.loadingState = 0 - this.showingPlaylist = response - if (!response.relationships.tracks.next) { - this.playlists.loadingState = 1 - return - } - - function getPlaylistTracks(next) { - app.apiCall(app.musicBaseUrl + next, res => { - if (self.showingPlaylist.id != playlistId) { - return - } - self.showingPlaylist.relationships.tracks.data = self.showingPlaylist.relationships.tracks.data.concat(res.data) - if (res.next) { - getPlaylistTracks(res.next) - } else { - self.playlists.loadingState = 1 - } - }) - } - - getPlaylistTracks(response.relationships.tracks.next) - - }, - async getPlaylistFromID(id, transient = false) { - let self = this - const params = { - include: "tracks", - platform: "web", - "include[library-playlists]": "catalog,tracks", - "fields[playlists]": "curatorName,playlistType,name,artwork,url,playParams", - "include[library-songs]": "catalog,artists,albums,playParams,name,artwork,url", - "fields[catalog]": "artistUrl,albumUrl,url", - "fields[songs]": "artistUrl,albumUrl,playParams,name,artwork,url,artistName,albumName,durationInMillis" - } - if (!transient) { - this.playlists.loadingState = 0; - } - app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, params).then(res => { - self.getPlaylistContinuous(res, transient) - }).catch((e) => { - console.log(e); - try { - app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`, params).then(res => { - self.getPlaylistContinuous(res, transient) - }) - } catch (err) { - console.log(err) - } - }) - - }, - async getArtistFromID(id) { - this.page = "" - const artistData = await this.mkapi("artists", false, id, { - "views": "featured-release,full-albums,appears-on-albums,featured-albums,featured-on-albums,singles,compilation-albums,live-albums,latest-release,top-music-videos,similar-artists,top-songs,playlists,more-to-hear,more-to-see", - "extend": "artistBio,bornOrFormed,editorialArtwork,editorialVideo,isGroup,origin,hero", - "extend[playlists]": "trackCount", - "include[songs]": "albums", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount", - "limit[artists:top-songs]": 20, - "art[url]": "f" - }, { includeResponseMeta: !0 }) - console.log(artistData.data.data[0]) - this.artistPage.data = artistData.data.data[0] - this.page = "artist-page" - }, - progressBarStyle() { - let val = this.playerLCD.playbackDuration - if (this.playerLCD.desiredDuration > 0) { - val = this.playerLCD.desiredDuration - } - let min = 0 - let max = this.mk.currentPlaybackDuration - let value = (val - min) / (max - min) * 100 - return { - 'background': ('linear-gradient(to right, var(--keyColor) 0%, var(--keyColor) ' + value + '%, #333 ' + value + '%, #333 100%)') - } - }, - async getRecursive(response) { - // if response has a .next() property run it and keep running until .next is null or undefined - // and then return the response concatenated with the results of the next() call - function executeRequest() { - if (response.next) { - return response.next().then(executeRequest) - } else { - return response - } - } - - return executeRequest() - }, - async getRecursive2(response, sendTo) { - let returnData = { - "data": [], - "meta": {} - } - if (response.next) { - console.log("has next") - returnData.data.concat(response.data) - returnData.meta = response.meta - return await this.getRecursive(await response.next()) - } else { - console.log("no next") - returnData.data.concat(response.data) - return returnData - } - }, - async getSearchHints() { - if (this.search.term == "") { - this.search.hints = [] - return - } - let hints = await (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search/hints?term=${this.search.term}`)).data.results - this.search.hints = hints ? hints.terms : [] - }, - getSongProgress() { - if (this.playerLCD.userInteraction) { - return this.playerLCD.desiredDuration - } else { - return this.playerLCD.playbackDuration - } - }, - convertToMins(time) { - let mins = Math.floor(time / 60) - let seconds = (Math.floor(time % 60) / 100).toFixed(2) - return `${mins}:${seconds.replace("0.", "")}` - }, - hashCode(str) { - let hash = 0, - i, chr; - if (str.length === 0) return hash; - for (i = 0; i < str.length; i++) { - chr = str.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; // Convert to 32bit integer - } - return hash; - }, - appRoute(route) { - console.log(route) - if (route == "" || route == "#" || route == "/") { - return; - } - route = route.replace(/#/g, "") - // if the route contains does not include a / then route to the page directly - if (route.indexOf("/") == -1) { - this.page = route - window.location.hash = this.page - return - } - let hash = route.split("/") - let page = hash[0] - let id = hash[1] - let isLibrary = hash[2] ?? false - console.log(`page: ${page} id: ${id} isLibrary: ${isLibrary}`) - this.routeView({ - kind: page, - id: id, - attributes: { - playParams: { kind: page, id: id, isLibrary: isLibrary } - } - }) - }, - routeView(item) { - let kind = (item.attributes.playParams ? (item.attributes.playParams.kind ?? (item.type ?? '')) : (item.type ?? '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id ?? (item.id ?? '')) : (item.id ?? ''));; - let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary ?? false) : false; - console.log(kind, id, isLibrary) - - if (true) { - if (kind.includes("playlist") || kind.includes("album")) { - app.showingPlaylist = []; - } - if (kind.toString().includes("apple-curator")) { - kind = "appleCurator" - app.getTypeFromID("appleCurator", (id), false, { - platform: "web", - include: "grouping,playlists", - extend: "editorialArtwork", - "art[url]": "f" - }); - window.location.hash = `${kind}/${id}` - document.querySelector("#app-content").scrollTop = 0 - } else if (kind.toString().includes("artist")) { - app.getArtistInfo(id, isLibrary) - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - document.querySelector("#app-content").scrollTop = 0 - - } else if (kind.toString().includes("record-label") || kind.toString().includes("curator")) { - if (kind.toString().includes("record-label")) { - kind = "recordLabel" - } else { - kind = "curator" - } - app.page = (kind) + "_" + (id); - app.getTypeFromID((kind), (id), (isLibrary), { - extend: "editorialVideo", - include: 'grouping,playlists', - views: 'top-releases,latest-releases,top-artists' - }); - window.location.hash = `${kind}/${id}` - document.querySelector("#app-content").scrollTop = 0 - } else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) { - let params = { - extend: "offers,editorialVideo", - "views": "appears-on,more-by-artist,related-videos,other-versions,you-might-also-like,video-extras,audio-extras", - } - app.page = (kind) + "_" + (id); - app.getTypeFromID((kind), (id), (isLibrary), params); - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - document.querySelector("#app-content").scrollTop = 0 - } else { - app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '') - } - - } - - }, - prevButton() { - if (!app.prevButtonBackIndicator && app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) { - app.prevButtonBackIndicator = true; - app.mk.seekToTime(0); - } else { - app.prevButtonBackIndicator = false; - app.mk.skipToPreviousItem() - } - }, - async getNowPlayingItemDetailed(target) { - let u = await app.mkapi(app.mk.nowPlayingItem.playParams.kind, (app.mk.nowPlayingItem.songId == -1), (app.mk.nowPlayingItem.songId != -1) ? app.mk.nowPlayingItem.songId : app.mk.nowPlayingItem["id"], { "include[songs]": "albums,artists" }); - app.searchAndNavigate(u.data.data[0], target) - }, - async searchAndNavigate(item, target) { - let self = this - app.tmpVar = item; - switch (target) { - case "artist": - let artistId = ''; - try { - if (item.relationships.artists && item.relationships.artists.data.length > 0 && !item.relationships.artists.data[0].type.includes("library")) { - if (item.relationships.artists.data[0].type === "artist" || item.relationships.artists.data[0].type === "artists") { - artistId = item.relationships.artists.data[0].id - } - } - if (artistId == '') { - const url = (item.relationships.catalog.data[0].attributes.artistUrl); - artistId = (url).substring(url.lastIndexOf('/') + 1) - if (artistId.includes('viewCollaboration')) { - artistId = artistId.substring(artistId.lastIndexOf('ids=') + 4, artistId.lastIndexOf('-')) - } - } - } catch (_) {} - - if (artistId == "") { - let artistQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.artistName}`, { - limit: 1, - types: 'artists' - })).data.results; - try { - if (artistQuery.artists.data.length > 0) { - artistId = artistQuery.artists.data[0].id; - console.log(artistId) - } - } catch (e) {} - } - console.log(artistId); - if (artistId != "") - self.appRoute(`artist/${artistId}`) - break; - case "album": - let albumId = ''; - try { - if (item.relationships.albums && item.relationships.albums.data.length > 0 && !item.relationships.albums.data[0].type.includes("library")) { - if (item.relationships.albums.data[0].type === "album" || item.relationships.albums.data[0].type === "albums") { - albumId = item.relationships.albums.data[0].id - } - } - if (albumId == '') { - const url = (item.relationships.catalog.data[0].attributes.url); - albumId = (url).substring(url.lastIndexOf('/') + 1) - if (albumId.includes("?i=")) { - albumId = albumId.substring(0, albumId.indexOf("?i=")) - } - } - } catch (_) {} - - if (albumId == "") { - try { - let albumQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.albumName + " " + (item.attributes.artistName ?? "")}`, { - limit: 1, - types: 'albums' - })).data.results; - if (albumQuery.albums.data.length > 0) { - albumId = albumQuery.albums.data[0].id; - console.log(albumId) - } - } catch (e) {} - } - if (albumId != "") { - self.appRoute(`album/${albumId}`) - } - break; - case "recordLabel": - let labelId = ''; - try { - labelId = item.relationships['record-labels'].data[0].id - } catch (_) {} - - if (labelId == "") { - try { - let labelQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.recordLabel}`, { - limit: 1, - types: 'record-labels' - })).data.results; - if (labelQuery["record-labels"].data.length > 0) { - labelId = labelQuery["record-labels"].data[0].id; - console.log(labelId) - } - } catch (e) {} - } - if (labelId != "") { - app.showingPlaylist = [] - await app.getTypeFromID("recordLabel", labelId, false, { views: 'top-releases,latest-releases,top-artists' }); - app.page = "recordLabel_" + labelId; - } - - break; - } - }, - exitMV() { - MusicKit.getInstance().stop() - document.getElementById("apple-music-video-container").style.display = "none"; - }, - getArtistInfo(id, isLibrary) { - this.getArtistFromID(id) - //this.getTypeFromID("artist",id,isLibrary,query) - }, - playMediaItem(item) { - let kind = (item.attributes.playParams ? (item.attributes.playParams.kind ?? (item.type ?? '')) : (item.type ?? '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id ?? (item.id ?? '')) : (item.id ?? ''));; - let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary ?? false) : false; - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(kind, id, isLibrary) - app.mk.stop().then(() => { - if (kind.includes("artist")) { - app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { - app.mk.play() - }) - } - // else if (kind.includes("playlist") && (id.startsWith("p.") || id.startsWith("pl."))){ - // /* Randomize array in-place using Durstenfeld shuffle algorithm */ - // function shuffleArray(array) { - // for (var i = array.length - 1; i > 0; i--) { - // var j = Math.floor(Math.random() * (i + 1)); - // var temp = array[i]; - // array[i] = array[j]; - // array[j] = temp; - // } - // } - // app.mk.clearQueue().then(function () { { - // app.mk.setQueue({[truekind]: [item.attributes.playParams.id ?? item.id]}).then(function () { - // app.mk.play().then(function (){ - // app.mk.clearQueue().then(function (){ - // var playlistId = id - // const params = { - // include: "tracks", - // platform: "web", - // "include[library-playlists]": "catalog,tracks", - // "fields[playlists]": "curatorName,playlistType,name,artwork,url", - // "include[library-songs]": "catalog,artists,albums", - // "fields[catalog]": "artistUrl,albumUrl", - // "fields[songs]": "artistUrl,albumUrl" - // } - // var playlistId = '' - - // try { - // function getPlaylist(id, params, isLibrary){ - // if (isLibrary){ - // return app.mk.api.library.playlist(id, params) - // } else { return app.mk.api.playlist(id, params)} - // } - // getPlaylist(id, params, isLibrary).then(res => { - // let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} - // app.mk.queue.append(query) - // if (!res.relationships.tracks.next) { - // return - // } else { - // getPlaylistTracks(res.relationships.tracks.next) - // } - - // function getPlaylistTracks(next) { - // app.apiCall(app.musicBaseUrl + next, res => { - // if (res.id != playlistId) { - // return - // } - // let query = res.data.map(item => new MusicKit.MediaItem(item)) - // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} - // app.mk.queue.append(query) - - // if (res.next) { - // getPlaylistTracks(res.next) - // } - // }) - // } - // }) - // } catch (e) {} - - - // }) - // }) - // }) - // } - // }) - // } - else { - app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '') - } - }) - }, - async getTypeFromID(kind, id, isLibrary = false, params = {}, params2 = {}) { - let a; - if (kind == "album" | kind == "albums") { - params["include"] = "tracks,artists,record-labels,catalog"; - } - try { - a = await this.mkapi(kind.toString(), isLibrary, id.toString(), params, params2); - } catch (e) { - console.log(e); - try { - a = await this.mkapi(kind.toString(), !isLibrary, id.toString(), params, params2); - } catch (err) { - console.log(err); - a = [] - } finally { - if (kind == "appleCurator") { - app.appleCurator = a.data.data[0] - } else { - this.getPlaylistContinuous(a) - } - } - } finally { - if (kind == "appleCurator") { - app.appleCurator = a.data.data[0] - } else { - this.getPlaylistContinuous(a) - } - }; - }, - searchLibrarySongs() { - let self = this - let prefs = this.cfg.libraryPrefs.songs - - function sortSongs() { - // sort this.library.songs.displayListing by song.attributes[self.library.songs.sorting] in descending or ascending order based on alphabetical order and numeric order - // check if song.attributes[self.library.songs.sorting] is a number and if so, sort by number if not, sort by alphabetical order ignoring case - self.library.songs.displayListing.sort((a, b) => { - let aa = a.attributes[prefs.sort] - let bb = b.attributes[prefs.sort] - if (self.library.songs.sorting == "genre") { - aa = a.attributes.genreNames[0] - bb = b.attributes.genreNames[0] - } - if (aa == null) { - aa = "" - } - if (bb == null) { - bb = "" - } - if (prefs.sortOrder == "asc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return aa - bb - } else { - return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()) - } - } else if (prefs.sortOrder == "desc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return bb - aa - } else { - return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()) - } - } - }) - } - - if (this.library.songs.search == "") { - this.library.songs.displayListing = this.library.songs.listing - sortSongs() - } else { - this.library.songs.displayListing = this.library.songs.listing.filter(item => { - let itemName = item.attributes.name.toLowerCase() - let searchTerm = this.library.songs.search.toLowerCase() - let artistName = "" - let albumName = "" - if (item.attributes.artistName != null) { - artistName = item.attributes.artistName.toLowerCase() - } - if (item.attributes.albumName != null) { - albumName = item.attributes.albumName.toLowerCase() - } - - // remove any non-alphanumeric characters and spaces from search term and item name - searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "") - itemName = itemName.replace(/[^a-z0-9 ]/gi, "") - artistName = artistName.replace(/[^a-z0-9 ]/gi, "") - albumName = albumName.replace(/[^a-z0-9 ]/gi, "") - - if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { - return item - } - }) - sortSongs() - } - }, - // make a copy of searchLibrarySongs except use Albums instead of Songs - searchLibraryAlbums(index) { - let self = this - - function sortAlbums() { - // sort this.library.albums.displayListing by album.attributes[self.library.albums.sorting[index]] in descending or ascending order based on alphabetical order and numeric order - // check if album.attributes[self.library.albums.sorting[index]] is a number and if so, sort by number if not, sort by alphabetical order ignoring case - self.library.albums.displayListing.sort((a, b) => { - let aa = a.attributes[self.library.albums.sorting[index]] - let bb = b.attributes[self.library.albums.sorting[index]] - if (self.library.albums.sorting[index] == "genre") { - aa = a.attributes.genreNames[0] - bb = b.attributes.genreNames[0] - } - if (aa == null) { - aa = "" - } - if (bb == null) { - bb = "" - } - if (self.library.albums.sortOrder[index] == "asc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return aa - bb - } else { - return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()) - } - } else if (self.library.albums.sortOrder[index] == "desc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return bb - aa - } else { - return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()) - } - } - }) - } - - if (this.library.albums.search == "") { - this.library.albums.displayListing = this.library.albums.listing - sortAlbums() - } else { - this.library.albums.displayListing = this.library.albums.listing.filter(item => { - let itemName = item.attributes.name.toLowerCase() - let searchTerm = this.library.albums.search.toLowerCase() - let artistName = "" - let albumName = "" - if (item.attributes.artistName != null) { - artistName = item.attributes.artistName.toLowerCase() - } - if (item.attributes.albumName != null) { - albumName = item.attributes.albumName.toLowerCase() - } - - // remove any non-alphanumeric characters and spaces from search term and item name - searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "") - itemName = itemName.replace(/[^a-z0-9 ]/gi, "") - artistName = artistName.replace(/[^a-z0-9 ]/gi, "") - albumName = albumName.replace(/[^a-z0-9 ]/gi, "") - - if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { - return item - } - }) - sortAlbums() - } - }, - // make a copy of searchLibrarySongs except use Albums instead of Songs - searchLibraryArtists(index) { - let self = this - - function sortArtists() { - // sort this.library.albums.displayListing by album.attributes[self.library.albums.sorting[index]] in descending or ascending order based on alphabetical order and numeric order - // check if album.attributes[self.library.albums.sorting[index]] is a number and if so, sort by number if not, sort by alphabetical order ignoring case - self.library.artists.displayListing.sort((a, b) => { - let aa = a.attributes[self.library.artists.sorting[index]] - let bb = b.attributes[self.library.artists.sorting[index]] - if (self.library.artists.sorting[index] == "genre") { - aa = a.attributes.genreNames[0] - bb = b.attributes.genreNames[0] - } - if (aa == null) { - aa = "" - } - if (bb == null) { - bb = "" - } - if (self.library.artists.sortOrder[index] == "asc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return aa - bb - } else { - return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()) - } - } else if (self.library.artists.sortOrder[index] == "desc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return bb - aa - } else { - return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()) - } - } - }) - } - - if (this.library.artists.search == "") { - this.library.artists.displayListing = this.library.artists.listing - sortArtists() - } else { - this.library.artists.displayListing = this.library.artists.listing.filter(item => { - let itemName = item.attributes.name.toLowerCase() - let searchTerm = this.library.artists.search.toLowerCase() - let artistName = "" - let albumName = "" - // if (item.attributes.artistName != null) { - // artistName = item.attributes.artistName.toLowerCase() - // } - // if (item.attributes.albumName != null) { - // albumName = item.attributes.albumName.toLowerCase() - // } - - // remove any non-alphanumeric characters and spaces from search term and item name - searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "") - itemName = itemName.replace(/[^a-z0-9 ]/gi, "") - - - if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { - return item - } - }) - sortArtists() - } - }, - getSidebarItemClass(page) { - if (this.page == page) { - return ["active"] - } else { - return [] - } - }, - async mkapi(method, library = false, term, params = {}, params2 = {}, attempts = 0) { - if (method.includes(`recordLabel`)) { method = `record-labels` } - if (method.includes(`appleCurator`)) { method = `apple-curators` } - if (attempts > 3) { - return - } - let truemethod = (!method.endsWith("s")) ? (method + "s") : method; - try { - if (library) { - return await this.mk.api.v3.music(`v1/me/library/${truemethod}/${term.toString()}`, params, params2) - } else { - return await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2) - } - } catch (e) { - console.log(e) - return await this.mkapi(method, library, term, params, params2, attempts + 1) - } - }, - getLibraryGenres() { - let genres = [] - genres = [] - this.library.songs.listing.forEach((item) => { - item.attributes.genreNames.forEach((genre) => { - if (!genres.includes(genre)) { - genres.push(genre) - } - }) - }) - return genres - }, - async getLibrarySongsFull(force = false) { - let self = this - let library = [] - let downloaded = null; - if ((this.library.songs.downloadState == 2) && !force) { - return - } - if (this.library.songs.downloadState == 1) { - return - } - if (localStorage.getItem("librarySongs") != null) { - this.library.songs.listing = JSON.parse(localStorage.getItem("librarySongs")) - this.searchLibrarySongs() - } - if (this.songstest) { - return - } - this.library.songs.downloadState = 1 - this.library.backgroundNotification.show = true - this.library.backgroundNotification.message = app.getLz('notification.updatingLibrarySongs') - - function downloadChunk() { - const params = { - "include[library-songs]": "catalog,artists,albums", - "fields[artists]": "name,url,id", - "fields[albums]": "name,url,id", - platform: "web", - "fields[catalog]": "artistUrl,albumUrl", - "fields[songs]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - limit: 100, - } - const safeparams = { - "platform": "web", - "limit": 80, - } - self.library.songs.downloadState = 1 - if (downloaded == null) { - app.mk.api.v3.music(`/v1/me/library/songs/`, params).then((response) => { - processChunk(response.data) - }).catch((error) => { - console.log('safe loading'); - app.mk.api.v3.music(`/v1/me/library/songs/`, safeparams).then((response) => { - processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.songs.downloadState = 2 - app.library.backgroundNotification.show = false}) - }) - } else { - if (downloaded.next != null) { - app.mk.api.v3.music(downloaded.next, params).then((response) => { - processChunk(response.data) - }).catch((error) => { - console.log('safe loading'); - app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { - processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.songs.downloadState = 2 - app.library.backgroundNotification.show = false}) - }) - } else { - console.log("Download next", downloaded.next) - } - } - } - - function processChunk(response) { - downloaded = response - library = library.concat(downloaded.data) - self.library.backgroundNotification.show = true - self.library.backgroundNotification.message = app.getLz('notification.updatingLibrarySongs') - self.library.backgroundNotification.total = downloaded.meta.total - self.library.backgroundNotification.progress = library.length - - if (downloaded.meta.total == 0) { - self.library.songs.downloadState = 3 - return - } - if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") - self.library.songs.listing = library - self.library.songs.downloadState = 2 - self.library.backgroundNotification.show = false - self.searchLibrarySongs() - localStorage.setItem("librarySongs", JSON.stringify(library)) - } - if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length} songs so far`) - downloadChunk() - } else { - self.library.songs.listing = library - self.library.songs.downloadState = 2 - self.library.backgroundNotification.show = false - self.searchLibrarySongs() - localStorage.setItem("librarySongs", JSON.stringify(library)) - console.log(library) - } - } - - downloadChunk() - }, - // copy the getLibrarySongsFull function except change Songs to Albums - async getLibraryAlbumsFull(force = false, index) { - let self = this - let library = [] - let downloaded = null; - if ((this.library.albums.downloadState == 2 || this.library.albums.downloadState == 1) && !force) { - return - } - if (localStorage.getItem("libraryAlbums") != null) { - this.library.albums.listing = JSON.parse(localStorage.getItem("libraryAlbums")) - this.searchLibraryAlbums(index) - } - if (this.songstest) { - return - } - this.library.albums.downloadState = 1 - this.library.backgroundNotification.show = true - this.library.backgroundNotification.message = app.getLz('notification.updatingLibraryAlbums') - - function downloadChunk() { - self.library.albums.downloadState = 1 - const params = { - "include[library-albums]": "catalog,artists,albums", - "fields[artists]": "name,url,id", - "fields[albums]": "name,url,id", - platform: "web", - "fields[catalog]": "artistUrl,albumUrl", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - limit: 100, - } - const safeparams = { - platform: "web", - limit: "60", - "include[library-albums]": "artists", - "include[library-artists]": "catalog", - "include[albums]": "artists", - "fields[artists]": "name,url", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - "includeOnly": "catalog,artists" - } - if (downloaded == null) { - app.mk.api.v3.music(`/v1/me/library/albums/`, params).then((response) => { - processChunk(response.data) - }).catch((error) => { - console.log('safe loading'); - app.mk.api.v3.music(`/v1/me/library/albums/`, safeparams).then((response) => { - processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.albums.downloadState = 2 - app.library.backgroundNotification.show = false}) - }) - } else { - if (downloaded.next != null) { - app.mk.api.v3.music(downloaded.next, params).then((response) => { - processChunk(response.data) - }).catch((error) => { - console.log('safe loading'); - app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { - processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error); - app.library.albums.downloadState = 2 - app.library.backgroundNotification.show = false}) - }) - } else { - console.log("Download next", downloaded.next) - } - } - } - - function processChunk(response) { - downloaded = response - library = library.concat(downloaded.data) - self.library.backgroundNotification.show = true - self.library.backgroundNotification.message = app.getLz('notification.updatingLibraryAlbums') - self.library.backgroundNotification.total = downloaded.meta.total - self.library.backgroundNotification.progress = library.length - if (downloaded.meta.total == 0) { - self.library.albums.downloadState = 3 - return - } - if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") - self.library.albums.listing = library - self.library.albums.downloadState = 2 - self.library.backgroundNotification.show = false - localStorage.setItem("libraryAlbums", JSON.stringify(library)) - self.searchLibraryAlbums(index) - } - if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length - } albums so far`) - downloadChunk() - } else { - self.library.albums.listing = library - self.library.albums.downloadState = 2 - self.library.backgroundNotification.show = false - localStorage.setItem("libraryAlbums", JSON.stringify(library)) - self.searchLibraryAlbums(index) - console.log(library) - } - } - - downloadChunk() - }, - // copy the getLibrarySongsFull function except change Songs to Albums - async getLibraryArtistsFull(force = false, index) { - let self = this - let library = [] - let downloaded = null; - if ((this.library.artists.downloadState == 2 || this.library.artists.downloadState == 1) && !force) { - return - } - if (localStorage.getItem("libraryArtists") != null) { - this.library.artists.listing = JSON.parse(localStorage.getItem("libraryArtists")) - this.searchLibraryArtists(index) - } - if (this.songstest) { - return - } - this.library.artists.downloadState = 1 - this.library.backgroundNotification.show = true - this.library.backgroundNotification.message = app.getLz('notification.updatingLibraryArtists') - - function downloadChunk() { - self.library.artists.downloadState = 1 - const params = { - include: "catalog", - // "include[library-artists]": "catalog,artists,albums", - // "fields[artists]": "name,url,id", - // "fields[albums]": "name,url,id", - platform: "web", - // "fields[catalog]": "artistUrl,albumUrl", - // "fields[artists]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - limit: 100, - } - const safeparams = { - include: "catalog", - platform: "web", - limit: 50, - } - if (downloaded == null) { - app.mk.api.v3.music(`/v1/me/library/artists/`, params).then((response) => { - processChunk(response.data) - }).catch((error) => { - console.log('safe loading'); - app.mk.api.v3.music(`/v1/me/library/artists/`, safeparams).then((response) => { - processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.artists.downloadState = 2 - app.library.backgroundNotification.show = false}) - }) - - } else { - if (downloaded.next != null) { - app.mk.api.v3.music(downloaded.next, params).then((response) => { - processChunk(response.data) - }).catch((error) => { - console.log('safe loading'); - app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { - processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.artists.downloadState = 2 - app.library.backgroundNotification.show = false}) - }) - } else { - console.log("Download next", downloaded.next) - } - - } - } - - function processChunk(response) { - downloaded = response - library = library.concat(downloaded.data) - self.library.backgroundNotification.show = true - self.library.backgroundNotification.message = app.getLz('notification.updatingLibraryArtists') - self.library.backgroundNotification.total = downloaded.meta.total - self.library.backgroundNotification.progress = library.length - if (downloaded.meta.total == 0) { - self.library.albums.downloadState = 3 - return - } - if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") - self.library.artists.listing = library - self.library.artists.downloadState = 2 - self.library.artists.show = false - localStorage.setItem("libraryArtists", JSON.stringify(library)) - self.searchLibraryArtists(index) - } - if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length - } artists so far`) - downloadChunk() - } else { - self.library.artists.listing = library - self.library.artists.downloadState = 2 - self.library.backgroundNotification.show = false - localStorage.setItem("libraryArtists", JSON.stringify(library)) - self.searchLibraryArtists(index) - console.log(library) - } - } - - downloadChunk() - }, - getTotalTime() { - try { - if (app.showingPlaylist.relationships.tracks.data.length > 0) { - let time = Math.round([].concat(...app.showingPlaylist.relationships.tracks.data).reduce((a, { attributes: { durationInMillis } }) => a + durationInMillis, 0) / 1000); - let hours = Math.floor(time / 3600) - let mins = Math.floor(time / 60) % 60 - let secs = time % 60 - return app.showingPlaylist.relationships.tracks.data.length + " " + app.getLz('term.tracks') +", " + ((hours > 0) ? (hours + (" " + ((hours > 1) ? app.getLz('term.time.hours') + ", " : app.getLz('term.time.hour') +", "))) : "") + ((mins > 0) ? (mins + ((mins > 1) ? " " + app.getLz('term.time.minutes') + ", " : " " + app.getLz('term.time.minute') + ", ")) : "") + secs + ((secs > 1) ? " " + app.getLz('term.time.seconds') + "." : " " + app.getLz('term.time.second') + "."); - } else return "" - } catch (err) { - return "" - } - }, - async getLibrarySongs() { - let response = await this.mkapi("songs", true, "", { limit: 100 }, { includeResponseMeta: !0 }) - this.library.songs.listing = response.data.data - this.library.songs.meta = response.data.meta - }, - async getLibraryAlbums() { - let response = await this.mkapi("albums", true, "", { limit: 100 }, { includeResponseMeta: !0 }) - this.library.albums.listing = response.data.data - this.library.albums.meta = response.data.meta - }, - async getListenNow(attempt = 0) { - if (this.listennow.timestamp > Date.now() - 120000) { - return - } - - if (attempt > 3) { - return - } - try { - this.listennow = (await this.mk.api.v3.music(`v1/me/recommendations?timezone=${encodeURIComponent(this.formatTimezoneOffset())}`, { - name: "listen-now", - with: "friendsMix,library,social", - "art[social-profiles:url]": "c", - "art[url]": "c,f", - "omit[resource]": "autos", - "relate[editorial-items]": "contents", - extend: ["editorialCard", "editorialVideo"], - "extend[albums]": ["artistUrl"], - "extend[library-albums]": ["artistUrl", "editorialVideo"], - "extend[playlists]": ["artistNames", "editorialArtwork", "editorialVideo"], - "extend[library-playlists]": ["artistNames", "editorialArtwork", "editorialVideo"], - "extend[social-profiles]": "topGenreNames", - "include[albums]": "artists", - "include[songs]": "artists", - "include[music-videos]": "artists", - "fields[albums]": ["artistName", "artistUrl", "artwork", "contentRating", "editorialArtwork", "editorialVideo", "name", "playParams", "releaseDate", "url"], - "fields[artists]": ["name", "url"], - "extend[stations]": ["airDate", "supportsAirTimeUpdates"], - "meta[stations]": "inflectionPoints", - types: "artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-upsells", - platform: "web" - }, { - includeResponseMeta: !0, - reload: !0 - })).data; - this.listennow.timestamp = Date.now() - console.log(this.listennow) - } catch (e) { - console.log(e) - this.getListenNow(attempt + 1) - } - }, - async getBrowsePage(attempt = 0) { - if (this.browsepage.timestamp > Date.now() - 120000) { - return - } - if (attempt > 3) { - return - } - try { - let browse = await app.mk.api.v3.music(`/v1/editorial/${app.mk.storefrontId}/groupings`, { - platform: "web", - name: "music", - "omit[resource:artists]": "relationships", - "include[albums]": "artists", - "include[songs]": "artists", - "include[music-videos]": "artists", - extend: "editorialArtwork,artistUrl", - "fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes", - "art[url]": "f" - }); - this.browsepage = browse.data.data[0]; - this.browsepage.timestamp = Date.now() - console.log(this.browsepage) - } catch (e) { - console.log(e) - this.getBrowsePage(attempt + 1) - } - }, - async getRadioStations(attempt = 0) { - if (attempt > 3) { - return - } - try { - this.radio.personal = (await app.mk.api.v3.music(`/v1/me/recent/radio-stations`, { - "platform": "web", - "art[url]": "f" - })).data.data; - } catch (e) { - console.log(e) - this.getRadioStations(attempt + 1) - } - }, - async getMadeForYou(attempt = 0) { - if (attempt > 3) { - return - } - try { - mfu = await app.mk.api.v3.music("/v1/me/library/playlists?platform=web&extend=editorialVideo&fields%5Bplaylists%5D=lastModifiedDate&filter%5Bfeatured%5D=made-for-you&include%5Blibrary-playlists%5D=catalog&fields%5Blibrary-playlists%5D=artwork%2Cname%2CplayParams%2CdateAdded") - this.madeforyou = mfu.data - } catch (e) { - console.log(e) - this.getMadeForYou(attempt + 1) - } - }, - newPlaylistFolder(name = app.getLz('term.newPlaylistFolder')) { - let self = this - this.mk.api.v3.music( - "/v1/me/library/playlist-folders/", {}, { - fetchOptions: { - method: "POST", - body: JSON.stringify({ - attributes: { name: name } - }) - } - } - ).then((res) => { - let playlist = (res.data.data[0]) - self.playlists.listing.push({ - id: playlist.id, - attributes: { - name: playlist.attributes.name - }, - type: "library-playlist-folders", - parent: "p.playlistsroot" - }) - self.sortPlaylists() - setTimeout(() => { - app.refreshPlaylists() - }, 13000) - }) - }, - unauthorize() { - this.mk.unauthorize() - }, - showSearch() { - this.page = "search" - }, - loadLyrics() { - const musicType = (MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem["type"] ?? '' : ''; - console.log("mt", musicType) - if (musicType === "musicVideo") { - this.loadYTLyrics(); - } else { - if (app.cfg.lyrics.enable_mxm) { - this.loadMXM(); - } else { - this.loadAMLyrics(); - } - } - }, - loadAMLyrics() { - const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] ?? -1 : -1; - // this.getMXM( trackName, artistName, 'en', duration); - if (songID != -1) { - MusicKit.getInstance().api.lyric(songID) - .then((response) => { - this.lyricsMediaItem = response.attributes["ttml"] - this.parseTTML() - }) - } - }, - addToLibrary(id) { - let self = this - this.mk.addToLibrary(id).then((data) => { - self.getLibrarySongsFull(true) - }) - }, - removeFromLibrary(kind, id) { - let self = this - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - app.mk.api.v3.music(`v1/me/library/${truekind}/${id.toString()}`, {}, { - fetchOptions: { - method: "DELETE" - } - }).then((data) => { - self.getLibrarySongsFull(true) - }) - }, - async loadYTLyrics() { - const track = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : ''; - const artist = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : ''; - const time = (this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1; - ipcRenderer.invoke('getYTLyrics', track, artist).then((result) => { - if (result.length > 0) { - let ytid = result[0]['id']['videoId']; - if (app.cfg.lyrics.enable_yt) { - loadYT(ytid, app.cfg.lyrics.mxm_language ?? "en") - } else { - app.loadMXM() - } - } else { - app.loadMXM() - } - - function loadYT(id, lang) { - let req = new XMLHttpRequest(); - let url = `https://www.youtube.com/watch?&v=${id}`; - req.open('GET', url, true); - req.onerror = function(e) { - this.loadMXM(); - } - req.onload = function() { - // console.log(this.responseText); - res = this.responseText; - let captionurl1 = res.substring(res.indexOf(`{"playerCaptionsRenderer":{"baseUrl":"`) + (`{"playerCaptionsRenderer":{"baseUrl":"`).length); - let captionurl = captionurl1.substring(0, captionurl1.indexOf(`"`)); - if (captionurl.includes("timedtext")) { - let json = JSON.parse(`{"url": "${captionurl}"}`); - let newurl = json.url + `&lang=${lang}&format=ttml` - - let req2 = new XMLHttpRequest(); - - req2.open('GET', newurl, true); - req2.onerror = function(e) { - app.loadMXM(); - } - req2.onload = function() { - try { - const ttmlLyrics = this.responseText; - if (ttmlLyrics) { - this.lyricsMediaItem = ttmlLyrics - this.parseTTML() - } - } catch (e) { - app.loadMXM(); - } - - } - req2.send(); - } else { - - app.loadMXM(); - - } - } - req.send(); - } - - }) - - }, - loadMXM() { - let attempt = 0; - const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : ''); - const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : ''); - const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1); - const id = encodeURIComponent((this.mk.nowPlayingItem != null) ? app.mk.nowPlayingItem._songId ?? '' : ''); - let lrcfile = ""; - let richsync = []; - const lang = app.cfg.lyrics.mxm_language // translation language - function revisedRandId() { - return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); - } - - /* get token */ - function getToken(mode, track, artist, songid, lang, time, id) { - if (attempt > 2) { - app.loadAMLyrics(); - } else { - attempt = attempt + 1; - let url = "https://apic-desktop.musixmatch.com/ws/1.1/token.get?app_id=web-desktop-app-v1.0&t=" + revisedRandId(); - let req = new XMLHttpRequest(); - req.overrideMimeType("application/json"); - req.open('GET', url, true); - req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req.onload = function() { - let jsonResponse = JSON.parse(this.responseText); - let status2 = jsonResponse["message"]["header"]["status_code"]; - if (status2 == 200) { - let token = jsonResponse["message"]["body"]["user_token"] ?? ''; - if (token != "" && token != "UpgradeOnlyUpgradeOnlyUpgradeOnlyUpgradeOnly") { - console.log('200 token', mode); - // token good - app.mxmtoken = token; - - if (mode == 1) { - getMXMSubs(track, artist, app.mxmtoken, lang, time, id); - } else { - getMXMTrans(songid, lang, app.mxmtoken); - } - } else { - console.log('fake 200 token'); - getToken(mode, track, artist, songid, lang, time) - } - } else { - console.log('token 4xx'); - getToken(mode, track, artist, songid, lang, time) - } - - }; - req.onerror = function() { - console.log('error'); - app.loadAMLyrics(); - }; - req.send(); - } - } - - function getMXMSubs(track, artist, token, lang, time, id) { - let usertoken = encodeURIComponent(token); - let richsyncQuery = (app.cfg.lyrics.mxm_karaoke) ? "&optional_calls=track.richsync" : "" - let timecustom = (!time || (time && time < 0)) ? '' : `&f_subtitle_length=${time}&q_duration=${time}&f_subtitle_length_max_deviation=40`; - let itunesid = (id && id != "") ? `&track_itunes_id=${id}` : ''; - let url = "https://apic-desktop.musixmatch.com/ws/1.1/macro.subtitles.get?format=json&namespace=lyrics_richsynched" + richsyncQuery + "&subtitle_format=lrc&q_artist=" + artist + "&q_track=" + track + itunesid + "&usertoken=" + usertoken + timecustom + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId(); - let req = new XMLHttpRequest(); - req.overrideMimeType("application/json"); - req.open('GET', url, true); - req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req.onload = function() { - let jsonResponse = JSON.parse(this.responseText); - console.log(jsonResponse); - let status1 = jsonResponse["message"]["header"]["status_code"]; - - if (status1 == 200) { - let id = ''; - try { - if (jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["header"]["status_code"] == 200 && jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["header"]["status_code"] == 200) { - id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["track_id"] ?? ''; - lrcfile = jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["body"]["subtitle_list"][0]["subtitle"]["subtitle_body"]; - - try { - lrcrich = jsonResponse["message"]["body"]["macro_calls"]["track.richsync.get"]["message"]["body"]["richsync"]["richsync_body"]; - richsync = JSON.parse(lrcrich); - app.richlyrics = richsync; - } catch (_) {} - } - - if (lrcfile == "") { - app.loadAMLyrics() - } else { - if (richsync == [] || richsync.length == 0) { - console.log("ok"); - // process lrcfile to json here - app.lyricsMediaItem = lrcfile - let u = app.lyricsMediaItem.split(/[\r\n]/); - let preLrc = [] - for (var i = u.length - 1; i >= 0; i--) { - let xline = (/(\[[0-9.:\[\]]*\])+(.*)/).exec(u[i]) - let end = (preLrc.length > 0) ? ((preLrc[preLrc.length - 1].startTime) ?? 99999) : 99999 - preLrc.push({ - startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, - endTime: end, - line: xline[2], - translation: '' - }) - } - if (preLrc.length > 0) - preLrc.push({ - startTime: 0, - endTime: preLrc[preLrc.length - 1].startTime, - line: "lrcInstrumental", - translation: '' - }); - app.lyrics = preLrc.reverse(); - } else { - preLrc = richsync.map(function(item) { - return { - startTime: item.ts, - endTime: item.te, - line: item.x, - translation: '' - } - }) - if (preLrc.length > 0) - preLrc.unshift({ - startTime: 0, - endTime: preLrc[0].startTime, - line: "lrcInstrumental", - translation: '' - }); - app.lyrics = preLrc; - } - if (lrcfile != null && lrcfile != '' && lang != "disabled") { - // load translation - getMXMTrans(id, lang, token); - } else { - app.loadAMLyrics() - } - } - } catch (e) { - console.log(e); - app.loadAMLyrics() - } - } else { //4xx rejected - getToken(1, track, artist, '', lang, time); - } - } - req.send(); - } - - function getMXMTrans(id, lang, token) { - if (lang != "disabled" && id != '') { - let usertoken = encodeURIComponent(token); - let url2 = "https://apic-desktop.musixmatch.com/ws/1.1/crowd.track.translations.get?translation_fields_set=minimal&selected_language=" + lang + "&track_id=" + id + "&comment_format=text&part=user&format=json&usertoken=" + usertoken + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId(); - let req2 = new XMLHttpRequest(); - req2.overrideMimeType("application/json"); - req2.open('GET', url2, true); - req2.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req2.onload = function() { - let jsonResponse2 = JSON.parse(this.responseText); - console.log(jsonResponse2); - let status2 = jsonResponse2["message"]["header"]["status_code"]; - if (status2 == 200) { - try { - let preTrans = [] - let u = app.lyrics; - let translation_list = jsonResponse2["message"]["body"]["translations_list"]; - if (translation_list.length > 0) { - for (var i = 0; i < u.length - 1; i++) { - preTrans[i] = "" - for (var trans_line of translation_list) { - if (u[i].line == " " + trans_line["translation"]["matched_line"] || u[i].line == trans_line["translation"]["matched_line"]) { - u[i].translation = trans_line["translation"]["description"]; - break; - } - } - } - app.lyrics = u; - } - } catch (e) { - /// not found trans -> ignore - } - } else { //4xx rejected - getToken(2, '', '', id, lang, ''); - } - } - req2.send(); - } - - } - - if (track != "" & track != "No Title Found") { - if (app.mxmtoken != null && app.mxmtoken != '') { - getMXMSubs(track, artist, app.mxmtoken, lang, time, id) - } else { - getToken(1, track, artist, '', lang, time); - } - } - }, - toMS(str) { - let rawTime = str.match(/(\d+:)?(\d+:)?(\d+)(\.\d+)?/); - let hours = (rawTime[2] != null) ? (rawTime[1].replace(":", "")) : 0; - let minutes = (rawTime[2] != null) ? (hours * 60 + rawTime[2].replace(":", "") * 1) : ((rawTime[1] != null) ? rawTime[1].replace(":", "") : 0); - let seconds = (rawTime[3] != null) ? (rawTime[3]) : 0; - let milliseconds = (rawTime[4] != null) ? (rawTime[4].replace(".", "")) : 0 - return parseFloat(`${minutes * 60 + seconds * 1}.${milliseconds * 1}`); - }, - parseTTML() { - this.lyrics = []; - let preLrc = []; - let xml = this.stringToXml(this.lyricsMediaItem); - let lyricsLines = xml.getElementsByTagName('p'); - let synced = true; - let endTimes = []; - if (xml.getElementsByTagName('tt')[0].getAttribute("itunes:timing") === "None") { - synced = false; - } - endTimes.push(0); - if (synced) { - for (element of lyricsLines) { - start = this.toMS(element.getAttribute('begin')) - end = this.toMS(element.getAttribute('end')) - if (start - endTimes[endTimes.length - 1] > 5 && endTimes[endTimes.length - 1] != 0) { - preLrc.push({ - startTime: endTimes[endTimes.length - 1], - endTime: start, - line: "lrcInstrumental" - }); - } - preLrc.push({ startTime: start, endTime: end, line: element.textContent }); - endTimes.push(end); - } - // first line dot - if (preLrc.length > 0) - preLrc.unshift({ startTime: 0, endTime: preLrc[0].startTime, line: "lrcInstrumental" }); - } else { - for (element of lyricsLines) { - preLrc.push({ startTime: 9999999, endTime: 9999999, line: element.textContent }); - } - } - this.lyrics = preLrc; - - }, - parseLyrics() { - let xml = this.stringToXml(this.lyricsMediaItem) - let json = xmlToJson(xml); - this.lyrics = json - }, - stringToXml(st) { - // string to xml - let xml = (new DOMParser()).parseFromString(st, "text/xml"); - return xml; - - }, - getCurrentTime() { - return parseFloat(this.hmsToSecondsOnly(this.parseTime(this.mk.nowPlayingItem.attributes.durationInMillis - app.mk.currentPlaybackTimeRemaining * 1000))); - }, - seekTo(time) { - this.mk.seekToTime(time); - }, - parseTime(value) { - let minutes = Math.floor(value / 60000); - let seconds = ((value % 60000) / 1000).toFixed(0); - return minutes + ":" + (seconds < 10 ? '0' : '') + seconds; - }, - parseTimeDecimal(value) { - let minutes = Math.floor(value / 60000); - let seconds = ((value % 60000) / 1000).toFixed(0); - return minutes + "." + (seconds < 10 ? '0' : '') + seconds; - }, - hmsToSecondsOnly(str) { - let p = str.split(':'), - s = 0, - m = 1; - - while (p.length > 0) { - s += m * parseInt(p.pop(), 10); - m *= 60; - } - - return s; - }, - getLyricBGStyle(start, end) { - let currentTime = this.getCurrentTime(); - // let duration = this.mk.nowPlayingItem.attributes.durationInMillis - let start2 = this.hmsToSecondsOnly(start) - let end2 = this.hmsToSecondsOnly(end) - // let currentProgress = ((100 * (currentTime)) / (end2)) - // check if currenttime is between start and end - this.player.lyricsDebug.start = start2 - this.player.lyricsDebug.end = end2 - this.player.lyricsDebug.current = currentTime - if (currentTime >= start2 && currentTime <= end2) { - return { - "--bgSpeed": `${(end2 - start2)}s` - } - } else { - return {} - } - }, - playMediaItemById(id, kind, isLibrary, raurl = "") { - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(id, truekind, isLibrary) - try { - if (truekind.includes("artist")) { - app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { - app.mk.play() - }) - } else if (truekind == "radioStations") { - this.mk.setStationQueue({ url: raurl }).then(function(queue) { - MusicKit.getInstance().play() - }); - } else { - this.mk.setQueue({ - [truekind]: [id] - }).then(function(queue) { - MusicKit.getInstance().play() - }) - } - } catch (err) { - console.log(err) - this.playMediaItemById(id, kind, isLibrary, raurl) - } - }, - queueParentandplayChild(parent, childIndex, item) { - - /* Randomize array in-place using Durstenfeld shuffle algorithm */ - function shuffleArray(array) { - for (var i = array.length - 1; i > 0; i--) { - var j = Math.floor(Math.random() * (i + 1)); - var temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } - } - - let kind = parent.substring(0, parent.indexOf(":")) - let id = parent.substring(parent.indexOf(":") + 1, parent.length) - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(truekind, id) - - try { - if (app.library.songs.displayListing.length > childIndex && parent == "librarysongs") { - console.log(item) - if (item && ((app.library.songs.displayListing[childIndex].id != item.id))) { - childIndex = app.library.songs.displayListing.indexOf(item) - } - - let query = app.library.songs.displayListing.map(item => new MusicKit.MediaItem(item)); - - - app.mk.stop().then(() => { - if (item) { - app.mk.setQueue({ - [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id - }).then(function () { - app.mk.play().then(() => { - if (app.mk.shuffleMode == 1) { - shuffleArray(query) - } else { - for (let i = 0; i < query.length; i++) { - if (query[i].id == item.id) {query.splice(0, i+1); - break;} - } - } - app.mk.queue.append(query) - }) - }) - } else { - this.mk.clearQueue().then(function (_) { - if (app.mk.shuffleMode == 1) { - shuffleArray(query) - } - app.mk.queue.append(query) - if (childIndex != -1) { - app.mk.changeToMediaAtIndex(childIndex) - } else { - app.mk.play() - } - }) - } - }) - } else { - app.mk.stop().then(() => { - if (truekind == "playlists" && (id.startsWith("p.") || id.startsWith("pl.u"))) { - app.mk.setQueue({ - [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1).then(function() { - if ((app.showingPlaylist && app.showingPlaylist.id == id)) { - let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - let u = query; - if (app.mk.shuffleMode == 1) { - shuffleArray(u) - } else { - for (let i = 0; i < app.showingPlaylist.relationships.tracks.data.length; i++) { - if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) {u.splice(0, i+1); break;} - } - } - app.mk.queue.append(u) - } else { - app.getPlaylistFromID(id, true).then(function() { - let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - let u = query; - if (app.mk.shuffleMode == 1) { - shuffleArray(u) - } else { - for (let i = 0; i < app.showingPlaylist.relationships.tracks.data.length; i++) { - if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) {u.splice(0, i+1); break;} - } - } - app.mk.queue.append(u) - }) - } - }) - - }) - } else { - this.mk.setQueue({ - [truekind]: [id] - }).then(function(queue) { - if (item && ((queue._itemIDs[childIndex] != item.id))) { - childIndex = queue._itemIDs.indexOf(item.id) - } - if (childIndex != -1) { - app.mk.changeToMediaAtIndex(childIndex) - } else if (item) { - app.mk.playNext({ - [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1) - app.mk.play() - }) - } else { - app.mk.play() - } - }) - } - }) - } - } catch (err) { - console.log(err) - try { - app.mk.stop() - } catch (e) {} - this.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url) - } - - }, - friendlyTypes(type) { - // use switch statement to return friendly name for media types "songs,artists,albums,playlists,music-videos,stations,apple-curators,curators" - switch (type) { - case "song": - return "Songs" - break; - case "artist": - return "Artists" - break; - case "album": - return "Albums" - break; - case "playlist": - return "Playlists" - break; - case "music_video": - return "Music Videos" - break; - case "station": - return "Stations" - break; - case "apple-curator": - return "Apple Curators" - break; - case "radio_show": - return "Radio Shows" - break; - case "record_label": - return "Record Labels" - break; - case "radio_episode": - return "Episodes" - break; - case "video_extra": - return "Video Extras" - break; - case "curator": - return "Curators" - break; - case "top": - return "Top" - break; - default: - return type - break; - } - }, - async searchQuery(term = this.search.term) { - let self = this - if (term == "") { - return - } - //this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${this.search.term}` - this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${this.search.term}`, { - types: "activities,albums,apple-curators,artists,curators,editorial-items,music-movies,music-videos,playlists,songs,stations,tv-episodes,uploaded-videos,record-labels", - "relate[editorial-items]": "contents", - "include[editorial-items]": "contents", - "include[albums]": "artists", - "include[artists]": "artists", - "include[songs]": "artists,albums", - "include[music-videos]": "artists", - "extend": "artistUrl", - "fields[artists]": "url,name,artwork,hero", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - "with": "serverBubbles,lyricHighlights", - "art[url]": "c,f", - "omit[resource]": "autos", - "platform": "web", - limit: 25 - }).then(function(results) { - results.data.results["meta"] = results.data.meta - self.search.results = results.data.results - }) - - await app.mk.api.v3.music(`v1/social/${app.mk.storefrontId}/search?term=${app.search.term}`, { - types: ["playlists", "social-profiles"], - limit: 25, - with: ["serverBubbles", "lyricSnippet"], - "art[url]": "f", - "art[social-profiles:url]": "c" - }, { includeResponseMeta: !0 }).then(function(results) { - results.data.results["meta"] = results.data.meta - self.search.resultsSocial = results.data.results - }) - }, - async inLibrary(items = []) { - let types = [] - - for (let item of items) { - let type = item.type - if (type.slice(-1) != "s") { - type += "s" - } - type = type.replace("library-", "") - let id = item.attributes.playParams.catalogId ?? item.id - - let index = types.findIndex(function(type) { - return type.type == this - }, type) - if (index == -1) { - types.push({ type: type, id: [id] }) - } else { - types[index].id.push(id) - } - } - types2 = types.map(function(item) { - return { - [`ids[${item.type}]`]: [item.id] - } - }) - types2 = types2.reduce(function(result, item) { - var key = Object.keys(item)[0]; //first property: a, b, c - result[key] = item[key]; - return result; - }, {}); - return (await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}`, {... { - "omit[resource]": "autos", - relate: "library", - fields: "inLibrary" - }, - ...types2 - })).data.data - }, - isInLibrary(playParams) { - let self = this - let id = "" - // ugly code to check if current playback item is in library - if (typeof playParams == "undefined") { - return true - } - if (playParams["isLibrary"]) { - return true - } else if (playParams["catalogId"]) { - id = playParams["catalogId"] - } else if (playParams["id"]) { - id = playParams["id"] - } - let found = this.library.songs.listing.filter((item) => { - if (item["attributes"]) { - if (item["attributes"]["playParams"] && (item["attributes"]["playParams"]["catalogId"] == id)) { - return item; - } - } - }) - if (found.length != 0) { - return true - } else { - return false - } - }, - mkReady() { - if (this.mk["nowPlayingItem"]) { - return true - } else { - return false - } - }, - getMediaItemArtwork(url, height = 64, width) { - if (typeof url == "undefined" || url == "") { - return "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg" - } - let newurl = `${url.replace('{w}', width ?? height).replace('{h}', height).replace('{f}', "webp").replace('{c}', ((width === 900) ? "sr" : "cc"))}`; - - if (newurl.includes("900x516")) { - newurl = newurl.replace("900x516cc", "900x516sr").replace("900x516bb", "900x516sr"); - } - return newurl - }, - _rgbToRgb(rgb = [0, 0, 0]) { - // if rgb - return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})` - }, - getNowPlayingArtworkBG(size = 32, force = false) { - let self = this - if (typeof this.mk.nowPlayingItem === "undefined") return; - let bginterval = setInterval(() => { - if (!this.mkReady()) { - return "" - } - - try { - if ((this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] != this.currentTrackID && document.querySelector('.bg-artwork')) || force) { - if (document.querySelector('.bg-artwork')) { - clearInterval(bginterval); - } - this.currentTrackID = this.mk.nowPlayingItem["id"]; - document.querySelector('.bg-artwork').src = ""; - if (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"]) { - getBase64FromUrl(this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"].replace('{w}', size).replace('{h}', size)).then(img => { - document.querySelectorAll('.bg-artwork').forEach(artwork => { - artwork.src = img; - }) - self.$store.commit("setLCDArtwork", img) - }) - - // Vibrant.from(this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"].replace('{w}', size).replace('{h}', size)).getPalette().then(palette=>{ - // let angle = "140deg" - // let gradient = "" - // let colors = Object.values(palette).filter(color=>color!=null) - // if(colors.length > 0){ - // let stops = [] - // colors.forEach(color=>{ - // stops.push(`${self._rgbToRgb(color._rgb)} 0%`) - // }) - // stops.push(`${self._rgbToRgb(colors[0]._rgb)} 100%`) - // gradient = `linear-gradient(${angle}, ${stops.join(", ")}` - // } - // - // document.querySelector("#app").style.setProperty("--bgColor", gradient) - // }).setQuantizer(Vibrant.Quantizer.WebWorker) - - try { - clearInterval(bginterval); - } catch (err) {} - } else { - this.setLibraryArtBG() - } - } else if (this.mk.nowPlayingItem["id"] == this.currentTrackID) { - try { - clearInterval(bginterval); - } catch (err) {} - } - } catch (e) { - if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] && document.querySelector('.bg-artwork')) { - this.setLibraryArtBG() - try { - clearInterval(bginterval); - } catch (err) {} - } - } - }, 200) - }, - - // getNowPlayingArtwork(size = 600) { - // if (typeof this.mk.nowPlayingItem === "undefined") return; - // let interval = setInterval(() => { - - // try { - // if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] != this.currentTrackIDBG && document.querySelector('.app-playback-controls .artwork')) { - // this.currentTrackIDBG = this.mk.nowPlayingItem["id"]; - // if (document.querySelector('.app-playback-controls .artwork') != null) { - // clearInterval(interval); - // } - // if (app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url!= '' ) { - // document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${decodeURI((this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"])).replace('{w}', size).replace('{h}', size)}")`); - // try { - // clearInterval(interval); - // } catch (err) { - // } - // } else { - // this.setLibraryArt() - // } - // } else if (this.mk.nowPlayingItem["id"] == this.currentTrackID) { - // try { - // clearInterval(interval); - // } catch (err) { - // } - // } - // } catch (e) { - // if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] && document.querySelector('.app-playback-controls .artwork')) { - // this.setLibraryArt() - // try { - // clearInterval(interval); - // } catch (err) { - // } - - // } - - // } - // }, 200) - - - // }, - async getCurrentArtURL() { - try { - this.currentArtUrl = ''; - if (app.mk.nowPlayingItem != null && app.mk.nowPlayingItem.attributes != null && app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url != '') { - this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50); - try { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} - } else { - let data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); - data = data.data.data[0]; - if (data != null && data !== "" && data.attributes != null && data.attributes.artwork != null) { - this.currentArtUrl = (data["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50); - // if (this.currentArtUrl != ""){ - // let attr = MusicKitInterop.getAttributes(); - // attr.artwork.url = this.currentArtUrl; - // ipcRenderer.send('forceUpdateRPC',attr) - // } - try { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} - } else { - this.currentArtUrl = ''; - try { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} - } - } - } catch (e) { - - } - }, - async setLibraryArt() { - if (typeof this.mk.nowPlayingItem === "undefined") return; - try { - const data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); - data = data.data.data[0]; - - if (data != null && data !== "") { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', 'url("' + (data["attributes"]["artwork"]["url"]).toString() + '")'); - } else { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("")`); - } - } catch (e) {} - }, - async setLibraryArtBG() { - if (typeof this.mk.nowPlayingItem === "undefined") return; - try { - const data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); - data = data.data.data[0]; - - if (data != null && data !== "") { - getBase64FromUrl((data["attributes"]["artwork"]["url"]).toString()).then(img => { - document.querySelector('.bg-artwork').forEach(artwork => { - artwork.src = img; - }) - self.$store.commit("setLCDArtwork", img) - }) - } - } catch (e) {} - - }, - quickPlay(query) { - let self = this - MusicKit.getInstance().api.search(query, { limit: 2, types: 'songs' }).then(function(data) { - MusicKit.getInstance().setQueue({ song: data["songs"]['data'][0]["id"] }).then(function(queue) { - MusicKit.getInstance().play() - setTimeout(() => { - self.$forceUpdate() - }, 1000) - }) - }) - }, - async getRating(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - let response = await this.mk.api.v3.music(`/v1/me/ratings/${type}?platform=web&ids=${type.includes('library') ? item.id : id}`) - if (response.data.data.length != 0) { - let value = response.data.data[0].attributes.value - return value - } else { - return 0 - } - }, - love(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - this.mk.api.v3.music(`/v1/me/ratings/${type}/${id}`, {}, { - fetchOptions: { - method: "PUT", - body: JSON.stringify({ - "type": "rating", - "attributes": { - "value": 1 - } - }) - } - }) - }, - dislike(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - this.mk.api.v3.music(`/v1/me/ratings/${type}/${id}`, {}, { - fetchOptions: { - method: "PUT", - body: JSON.stringify({ - "type": "rating", - "attributes": { - "value": -1 - } - }) - } - }) - }, - unlove(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - this.mk.api.v3.music(`/v1/me/ratings/${type}/${id}`, {}, { - fetchOptions: { - method: "DELETE", - } - }) - }, - volumeWheel(event) { - if (this.cfg.audio.maxVolume < 1.0 && this.cfg.audio.maxVolume > 0.01) { - this.cfg.audio.volumePrecision = 0.01 - this.cfg.audio.volumeRoundMax = this.cfg.audio.maxVolume - 0.01 - this.cfg.audio.volumeRoundMin = 0.01 - } - if (event.deltaY < 0) { - if (this.mk.volume < this.cfg.audio.maxVolume) { - if (this.mk.volume <= this.cfg.audio.volumeRoundMax) { - this.mk.volume += this.cfg.audio.volumePrecision - } else { - this.mk.volume = this.cfg.audio.maxVolume - } - } - } else if (event.deltaY > 0) { - if (this.mk.volume > 0) { - if (this.mk.volume >= this.cfg.audio.volumeRoundMin) { - this.mk.volume -= this.cfg.audio.volumePrecision - } else { - this.mk.volume = 0 - } - } - } - }, - muteButtonPressed() { - if( this.cfg.audio.muted ) { - this.mk.volume = this.cfg.audio.lastVolume; - this.cfg.audio.muted = false; - } else { - this.cfg.audio.lastVolume = this.cfg.audio.volume; - this.mk.volume = 0; - this.cfg.audio.muted = true; - } - }, - checkMuteChange() { - if( this.cfg.audio.muted ) { - this.cfg.audio.muted = false; - } - }, - async apiCall(url, callback) { - const xmlHttp = new XMLHttpRequest(); - - xmlHttp.onreadystatechange = (e) => { - if (xmlHttp.readyState !== 4) { - return; - } - - if (xmlHttp.status === 200) { - // console.log('SUCCESS', xmlHttp.responseText); - callback(JSON.parse(xmlHttp.responseText)); - } else { - console.warn('request_error'); - } - }; - - xmlHttp.open("GET", url); - xmlHttp.setRequestHeader("Authorization", "Bearer " + MusicKit.getInstance().developerToken); - xmlHttp.setRequestHeader("Music-User-Token", "" + MusicKit.getInstance().musicUserToken); - xmlHttp.setRequestHeader("Accept", "application/json"); - xmlHttp.setRequestHeader("Content-Type", "application/json"); - xmlHttp.responseType = "text"; - xmlHttp.send(); - }, - fetchPlaylist(id, callback) { - // id can be found in playlist.attributes.playParams.globalId - // this.mk.api. - this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`).then(res => { - callback(res.data.data[0]) - }) - - // tracks are found in relationship.data - }, - windowFocus(val) { - if (val) { - document.querySelectorAll(".animated-artwork-video").forEach(el => { - el.play() - }) - this.animateBackground = true - } else { - document.querySelectorAll(".animated-artwork-video").forEach(el => { - el.pause() - }) - this.animateBackground = false - } - }, - async nowPlayingContextMenu(event) { - // function revisedRandId() { - // return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); - // } - let self = this - let data_type = this.mk.nowPlayingItem.playParams.kind - let item_id = this.mk.nowPlayingItem.attributes.playParams.id ?? this.mk.nowPlayingItem.id - let isLibrary = this.mk.nowPlayingItem.attributes.playParams.isLibrary ?? false - let params = { "fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library", "t": "1" } - // let res = await app.mkapi(data_type, isLibrary , item_id, params); - // if (res && res.relationships && res.relationships.library && res.relationships.library.data && res.relationships.library.data.length > 0) { - // item_id = res.relationships.library.data[0].id - // } - app.selectedMediaItems = [] - app.select_selectMediaItem(item_id, data_type, 0, '12344', isLibrary) - let useMenu = "normal" - let menus = { - multiple: { - items: [] - }, - normal: { - headerItems: [{ - "icon": "./assets/feather/heart.svg", - "id": "love", - "name": app.getLz('action.love'), - "hidden": false, - "disabled": true, - "action": function() { - app.love(app.mk.nowPlayingItem) - } - }, - { - "icon": "./assets/feather/heart.svg", - "id": "unlove", - "active": true, - "name": app.getLz('action.unlove'), - "hidden": true, - "action": function() { - app.unlove(app.mk.nowPlayingItem) - } - }, - { - "icon": "./assets/feather/thumbs-down.svg", - "id": "dislike", - "name": app.getLz('action.dislike'), - "hidden": false, - "disabled": true, - "action": function() { - app.dislike(app.mk.nowPlayingItem) - } - }, - { - "icon": "./assets/feather/thumbs-down.svg", - "id": "undo_dislike", - "name": app.getLz('action.undoDislike'), - "active": true, - "hidden": true, - "action": function() { - app.unlove(app.mk.nowPlayingItem) - } - }, - ], - items: [{ - "icon": "./assets/feather/list.svg", - "name": app.getLz('action.addToPlaylist')+" ...", - "action": function() { - app.promptAddToPlaylist() - } - }, - { - "icon": "./assets/feather/plus.svg", - "id": "addToLibrary", - "name": app.getLz('action.addToLibrary')+" ...", - "disabled": false, - "action": function() { - app.addToLibrary(app.mk.nowPlayingItem.id); - // if (!isLibrary) {app.addToLibrary(item_id); this.mk.nowPlayingItem.attributes.playParams["isLibrary"] = true} else { app.removeFromLibrary(data_type,item_id); this.mk.nowPlayingItem.attributes.playParams["isLibrary"] = false}; - } - }, - { - "icon": "./assets/feather/radio.svg", - "name": app.getLz('action.startRadio'), - "action": function() { - app.mk.setStationQueue({ song: app.mk.nowPlayingItem.id }).then(() => { - app.mk.play() - app.selectedMediaItems = [] - }) - } - }, - ] - } - } - if (this.contextExt) { - // if this.context-ext.normal is true append all options to the 'normal' menu which is a kvp of arrays - if (this.contextExt.normal) { - menus.normal.items = menus.normal.items.concat(this.contextExt.normal) - } - } - - // isLibrary = await app.inLibrary([this.mk.nowPlayingItem]) - // console.warn(isLibrary) - // if(isLibrary.length != 0) { - // if (isLibrary[0].attributes.inLibrary) { - // menus.normal.items.find(x => x.id == "addToLibrary").disabled = true - // } - // }else{ - // menus.normal.items.find(x => x.id == "addToLibrary").disabled = true - // } - this.showMenuPanel(menus[useMenu], event) - - try { - let rating = await app.getRating(app.mk.nowPlayingItem) - if (rating == 0) { - menus.normal.headerItems.find(x => x.id == 'love').disabled = false - menus.normal.headerItems.find(x => x.id == 'dislike').disabled = false - } else if (rating == 1) { - menus.normal.headerItems.find(x => x.id == 'unlove').hidden = false - menus.normal.headerItems.find(x => x.id == 'love').hidden = true - } else if (rating == -1) { - menus.normal.headerItems.find(x => x.id == 'undo_dislike').hidden = false - menus.normal.headerItems.find(x => x.id == 'dislike').hidden = true - } - } catch (err) { - - } - }, - LastFMDeauthorize() { - ipcRenderer.invoke('setStoreValue', 'lastfm.enabled', false).catch((e) => console.error(e)); - ipcRenderer.invoke('setStoreValue', 'lastfm.auth_token', '').catch((e) => console.error(e)); - app.cfg.lastfm.auth_token = ""; - app.cfg.lastfm.enabled = false; - const element = document.getElementById('lfmConnect'); - element.innerHTML = getLz('term.connect'); - element.onclick = app.LastFMAuthenticate; - }, - LastFMAuthenticate() { - console.log("[LastFM] Received LastFM authentication callback") - const element = document.getElementById('lfmConnect'); - // new key : f9986d12aab5a0fe66193c559435ede3 - window.open('https://www.last.fm/api/auth?api_key=f9986d12aab5a0fe66193c559435ede3&cb=cider://auth/lastfm'); - element.innerText = app.getLz('term.connecting') + '...'; - - /* Just a timeout for the button */ - setTimeout(() => { - if (element.innerText === app.getLz('term.connecting') +'...') { - element.innerText = app.getLz('term.connect'); - console.warn('[LastFM] Attempted connection timed out.'); - } - }, 20000); - - ipcRenderer.on('LastfmAuthenticated', function(_event, lfmAuthKey) { - app.cfg.lastfm.auth_token = lfmAuthKey; - app.cfg.lastfm.enabled = true; - element.innerHTML = `${app.getLz('term.disconnect')}\n<p style="font-size: 8px"><i>(${app.getLz('term.authed')}: ${lfmAuthKey})</i></p>`; - element.onclick = app.LastFMDeauthorize; - }); - }, - parseSCTagToRG: function(tag) { - let soundcheck = tag.split(" ") - let numbers = [] - for (item of soundcheck) { - numbers.push(parseInt(item, 16)) - - } - numbers.shift() - let gain = Math.log10((Math.max(numbers[0], numbers[1]) ?? 1000) / 1000.0) * -10 - let peak = Math.max(numbers[6], numbers[7]) / 32768.0 - return { - gain: gain, - peak: peak - } - }, - fullscreen(flag) { - if (flag) { - ipcRenderer.send('setFullScreen', true); - if (app.mk.nowPlayingItem.type && app.mk.nowPlayingItem.type.toLowerCase().includes("video")) { - document.querySelector('video#apple-music-video-player').requestFullscreen() - } else { - app.appMode = 'fullscreen'; - } - document.addEventListener('keydown', event => { - if (event.key === 'Escape' && app.appMode === 'fullscreen') { - this.fullscreen(false); - } - }); - } else { - ipcRenderer.send('setFullScreen', false); - app.appMode = 'player'; - } - }, - miniPlayer(flag) { - if (flag) { - this.tmpWidth = window.innerWidth; - this.tmpHeight = window.innerHeight; - ipcRenderer.send('unmaximize'); - ipcRenderer.send('windowmin', 250, 250) - ipcRenderer.send('windowresize', 300, 300, false) - app.appMode = 'mini'; - } else { - ipcRenderer.send('windowmin', 844, 410) - ipcRenderer.send('windowresize', this.tmpWidth, this.tmpHeight, false) - ipcRenderer.send('windowontop', false) - this.cfg.visual.miniplayer_top_toggle = true; - app.appMode = 'player'; - } - }, - pinMiniPlayer() { - if (this.cfg.visual.miniplayer_top_toggle) { - ipcRenderer.send('windowontop', true) - this.cfg.visual.miniplayer_top_toggle = false - } else { - ipcRenderer.send('windowontop', false) - this.cfg.visual.miniplayer_top_toggle = true; - } - }, - formatTimezoneOffset: (e = new Date) => { - let leadingZeros = (e, s = 2) => { - let n = "" + e; - for (; n.length < s;) - n = "0" + n; - return n - } - - const s = e.getTimezoneOffset(), - n = Math.floor(Math.abs(s) / 60), - d = Math.round(Math.abs(s) % 60); - let h = "+"; - return 0 !== s && (h = s > 0 ? "-" : "+"), - `${h}${leadingZeros(n, 2)}:${leadingZeros(d, 2)}` - }, - toggleHideUserInfo() { - if(this.chrome.hideUserInfo) { - this.cfg.visual.showuserinfo = true - this.chrome.hideUserInfo = false - } else { - this.cfg.visual.showuserinfo = false - this.chrome.hideUserInfo = true - } - }, - isElementOverflowing(selector) { - try{ - let element = document.querySelector(selector); - var overflowX = element.offsetWidth < element.scrollWidth, - overflowY = element.offsetHeight < element.scrollHeight; - element.setAttribute('data-value', '\xa0\xa0\xa0\xa0' + element.textContent); - - return (overflowX || overflowY); } catch (e) { return false} - }, - async showWebRemoteQR(){ - //this.webremoteqr = await ipcRenderer.invoke('setRemoteQR','') - this.webremoteurl = await ipcRenderer.invoke('showQR','') - //this.modals.qrcode = true; - }, - checkMarquee() { - if(isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-artist') == true) { - document.getElementsByClassName('song-artist')[0].classList.add('marquee'); - document.getElementsByClassName('song-artist')[1].classList.add('marquee-after'); - } - if(isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') == true) { - document.getElementsByClassName('song-name')[0].classList.add('marquee'); - document.getElementsByClassName('song-name')[1].classList.add('marquee-after'); - } - }, - closeWindow(){ - ipcRenderer.send('close'); - }, - checkForUpdate(){ - ipcRenderer.send('check-for-update') - } - } -}) - -Vue.component('animated-number', { - - template: "<div style='display: inline-block;'>{{ displayNumber }}</div>", - props: { 'number': { default: 0 } }, - - data() { - return { - displayNumber: 0, - interval: false - } - }, - - ready() { - this.displayNumber = this.number ? this.number : 0; - }, - - watch: { - number() { - clearInterval(this.interval); - - if (this.number == this.displayNumber) { - return; - } - - this.interval = window.setInterval(() => { - if (this.displayNumber != this.number) { - var change = (this.number - this.displayNumber) / 10; - change = change >= 0 ? Math.ceil(change) : Math.floor(change); - this.displayNumber = this.displayNumber + change; - } - }, 20); - } - } -}) - -Vue.component('sidebar-library-item', { - template: '#sidebar-library-item', - props: { - name: { - type: String, - required: true - }, - page: { - type: String, - required: true - }, - svgIcon: { - type: String, - required: false, - default: '' - }, - cdClick: { - type: Function, - required: false - } - }, - data: function() { - return { - app: app, - svgIconData: "" - } - }, - async mounted() { - if (this.svgIcon) { - this.svgIconData = await this.app.getSvgIcon(this.svgIcon) - } - }, - methods: {} -}); - -// Key binds -document.addEventListener('keydown', function(e) { - if (e.keyCode === 70 && e.ctrlKey) { - app.$refs.searchInput.focus() - app.$refs.searchInput.select() - } -}); - -// Hang Timer -app.hangtimer = setTimeout(() => { - if (confirm("Cider is not responding. Reload the app?")) { - window.location.reload() - } -}, 10000) - -// add event listener for when window.location.hash changes -window.addEventListener("hashchange", function() { - app.appRoute(window.location.hash) -}); - - -function fallbackinitMusicKit() { - const request = new XMLHttpRequest(); - - function loadAlternateKey() { - let parsedJson = JSON.parse(this.responseText) - MusicKit.configure({ - developerToken: parsedJson.developerToken, - app: { - name: 'Apple Music', - build: '1978.4.1', - version: "1.0" - }, - sourceType: 24, - suppressErrorDialog: true - }); - setTimeout(() => { - app.init() - }, 1000) - } - - request.addEventListener("load", loadAlternateKey); - request.open("GET", "https://raw.githubusercontent.com/lujjjh/LitoMusic/main/token.json"); - request.send(); -} - -document.addEventListener('musickitloaded', function() { - // MusicKit global is now defined - function initMusicKit() { - let parsedJson = JSON.parse(this.responseText) - MusicKit.configure({ - developerToken: parsedJson.Key, - app: { - name: 'Apple Music', - build: '1978.4.1', - version: "1.0" - }, - sourceType: 24, - suppressErrorDialog: true - }); - setTimeout(() => { - app.init() - }, 1000) - } - - - const request = new XMLHttpRequest(); - request.timeout = 5000; - request.addEventListener("load", initMusicKit); - request.onreadystatechange = function(aEvt) { - if (request.readyState == 4) { - if (request.status != 200) - fallbackinitMusicKit() - } +// limit an array to a certain number of items +Array.prototype.limit = function (n) { + return this.slice(0, n); +}; + +Vue.component("animated-number", { + template: "<div style='display: inline-block;'>{{ displayNumber }}</div>", + props: { number: { default: 0 } }, + + data() { + return { + displayNumber: 0, + interval: false, }; - request.open("GET", "https://api.cider.sh/"); - request.send(); + }, - // check for widevine failure and reconfigure the instance. - window.addEventListener("drmUnsupported", function() { - initMusicKit() - }); + ready() { + this.displayNumber = this.number ? this.number : 0; + }, + + watch: { + number() { + clearInterval(this.interval); + + if (this.number == this.displayNumber) { + return; + } + + this.interval = window.setInterval(() => { + if (this.displayNumber != this.number) { + var change = (this.number - this.displayNumber) / 10; + change = change >= 0 ? Math.ceil(change) : Math.floor(change); + this.displayNumber = this.displayNumber + change; + } + }, 20); + }, + }, }); -if ('serviceWorker' in navigator) { - // Use the window load event to keep the page load performant - window.addEventListener('load', () => { - navigator.serviceWorker.register('sw.js?v=1'); +function initMusicKit() { + if (!this.responseText) { + console.log("Using stored token"); + this.responseText = JSON.stringify({ + token: localStorage.getItem("lastToken"), }); -} - -const getBase64FromUrl = async(url) => { - const data = await fetch(url); - const blob = await data.blob(); - return new Promise((resolve) => { - const reader = new FileReader(); - reader.readAsDataURL(blob); - reader.onloadend = () => { - const base64data = reader.result; - resolve(base64data); + } + let parsedJson = JSON.parse(this.responseText); + localStorage.setItem("lastToken", parsedJson.token); + MusicKit.configure({ + developerToken: parsedJson.token, + app: { + name: "Apple Music", + build: "1978.4.1", + version: "1.0", + }, + sourceType: 24, + suppressErrorDialog: true, + }).then(() => { + function waitForApp() { + if (typeof app.init !== "undefined") { + app.init(); + if (app.cfg.visual.window_background_style == "mica" && !app.isDev) { + app.spawnMica(); } - }); + } else { + setTimeout(waitForApp, 250); + } + } + waitForApp(); + }); } -function Clone (obj) { - return JSON.parse(JSON.stringify(obj)); +function capiInit() { + const request = new XMLHttpRequest(); + request.timeout = 5000; + request.addEventListener("load", initMusicKit); + request.onreadystatechange = function (aEvt) { + if (request.readyState == 4 && request.status != 200) { + if (localStorage.getItem("lastToken") != null) { + initMusicKit(); + } else { + console.error(`Failed to load capi, cannot get token [${request.status}]`); + } + } + }; + request.open("GET", "https://api.cider.sh/v1/"); + request.send(); +} + +document.addEventListener("musickitloaded", function () { + if (showOobe()) return; + console.log("MusicKit loaded"); + // MusicKit global is now defined + capiInit(); +}); +window.addEventListener("drmUnsupported", function () { + initMusicKit(); +}); +if ("serviceWorker" in navigator) { + // Use the window load event to keep the page load performant + window.addEventListener("load", () => { + navigator.serviceWorker.register("sw.js?v=1"); + }); +} + +const getBase64FromUrl = async (url) => { + const data = await fetch(url); + const blob = await data.blob(); + return new Promise((resolve) => { + const reader = new FileReader(); + reader.readAsDataURL(blob); + reader.onloadend = () => { + const base64data = reader.result; + resolve(base64data); + }; + }); +}; + +function Clone(obj) { + return JSON.parse(JSON.stringify(obj)); } function uuidv4() { - return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => - (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) - ); + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)); } -function refreshFocus() { - if (document.hasFocus() == false) { - app.windowFocus(false) - } else { - app.windowFocus(true) - } - setTimeout(refreshFocus, 200); -} - -app.getHTMLStyle() - -refreshFocus(); - function xmlToJson(xml) { + // Create the return object + let obj = {}; - // Create the return object - let obj = {}; - - if (xml.nodeType == 1) { // element - // do attributes - if (xml.attributes.length > 0) { - obj["@attributes"] = {}; - for (var j = 0; j < xml.attributes.length; j++) { - let attribute = xml.attributes.item(j); - obj["@attributes"][attribute.nodeName] = attribute.nodeValue; - } - } - } else if (xml.nodeType == 3) { // text - obj = xml.nodeValue; + if (xml.nodeType == 1) { + // element + // do attributes + if (xml.attributes.length > 0) { + obj["@attributes"] = {}; + for (var j = 0; j < xml.attributes.length; j++) { + let attribute = xml.attributes.item(j); + obj["@attributes"][attribute.nodeName] = attribute.nodeValue; + } } + } else if (xml.nodeType == 3) { + // text + obj = xml.nodeValue; + } - // do children - if (xml.hasChildNodes()) { - for (var i = 0; i < xml.childNodes.length; i++) { - var item = xml.childNodes.item(i); - var nodeName = item.nodeName; - if (typeof(obj[nodeName]) == "undefined") { - obj[nodeName] = xmlToJson(item); - } else { - if (typeof(obj[nodeName].push) == "undefined") { - var old = obj[nodeName]; - obj[nodeName] = []; - obj[nodeName].push(old); - } - obj[nodeName].push(xmlToJson(item)); - } + // do children + if (xml.hasChildNodes()) { + for (var i = 0; i < xml.childNodes.length; i++) { + var item = xml.childNodes.item(i); + var nodeName = item.nodeName; + if (typeof obj[nodeName] == "undefined") { + obj[nodeName] = xmlToJson(item); + } else { + if (typeof obj[nodeName].push == "undefined") { + var old = obj[nodeName]; + obj[nodeName] = []; + obj[nodeName].push(old); } + obj[nodeName].push(xmlToJson(item)); + } } - console.log(obj); - return obj; -}; + } + console.log(obj); + return obj; +} async function asyncForEach(array, callback) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array); - } + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array); + } } var checkIfScrollIsStatic = setInterval(() => { - try { - if (position === document.getElementsByClassName('lyric-body')[0].scrollTop) { - clearInterval(checkIfScrollIsStatic) - // do something - } - position = document.getElementsByClassName('lyric-body')[0].scrollTop - } catch (e) {} - + try { + if (position === document.getElementsByClassName("lyric-body")[0].scrollTop) { + clearInterval(checkIfScrollIsStatic); + // do something + } + position = document.getElementsByClassName("lyric-body")[0].scrollTop; + } catch (e) {} }, 50); // WebGPU Console Notification async function webGPU() { - try { - const currentGPU = await navigator.gpu.requestAdapter() - console.log("WebGPU enabled on", currentGPU.name, "with feature ID", currentGPU.features.size) - } catch (e) { - console.log("WebGPU disabled / WebGPU initialization failed") - } + try { + const currentGPU = await navigator.gpu.requestAdapter(); + console.log("WebGPU enabled on", currentGPU.name, "with feature ID", currentGPU.features.size); + } catch (e) { + console.log("WebGPU disabled / WebGPU initialization failed"); + } } -webGPU().then() +function isJson(item) { + item = typeof item !== "string" ? JSON.stringify(item) : item; + + try { + item = JSON.parse(item); + } catch (e) { + return false; + } + + if (typeof item === "object" && item !== null) { + return true; + } + + return false; +} + +webGPU().then(); + +function showOobe() { + if (localStorage.getItem("music.ampwebplay.media-user-token") && localStorage.getItem("seenOOBE")) { + return false; + } else { + function waitForApp() { + if (typeof app.init !== "undefined") { + app.oobeInit(); + } else { + setTimeout(waitForApp, 250); + } + } + waitForApp(); + return true; + } +} let screenWidth = screen.width; let screenHeight = screen.height; -// Key bind to unjam MusicKit in case it fails: CTRL+F10 -document.addEventListener('keydown', function(event) { - if (event.ctrlKey && event.keyCode == 121) { - try { - app.mk._services.mediaItemPlayback._currentPlayer.stop() - } catch (e) { } - try { - app.mk._services.mediaItemPlayback._currentPlayer.destroy() - } catch (e) { } - } +document.addEventListener("DOMContentLoaded", async function () { + // app.oobeInit() }); -document.addEventListener('keydown', function(event) { - if (event.ctrlKey && event.keyCode == 122) { - try { - ipcRenderer.send('detachDT','') - } catch (e) { } +document.addEventListener( + "contextmenu", + function (e) { + if (e.target.tagName.toLowerCase() == "textarea" || (e.target.tagName.toLowerCase() == "input" && e.target.type != "checkbox" && e.target.type != "radio" && e.target.disabled == false)) { + e.preventDefault(); + const menuPanel = { + items: { + cut: { + name: app.getLz("action.cut"), + action: function () { + document.execCommand("cut"); + }, + }, + copy: { + name: app.getLz("action.copy"), + action: function () { + document.execCommand("copy"); + }, + }, + paste: { + name: app.getLz("action.paste"), + action: function () { + document.execCommand("paste"); + }, + }, + delete: { + name: app.getLz("action.delete"), + action: function () { + document.execCommand("delete"); + }, + }, + selectAll: { + name: app.getLz("action.selectAll"), + action: function () { + document.execCommand("selectAll"); + }, + }, + }, + }; + app.showMenuPanel(menuPanel, e); } -}); + }, + false, +); diff --git a/src/renderer/js/WSAPI_Interop.js b/src/renderer/js/WSAPI_Interop.js deleted file mode 100644 index e86327be..00000000 --- a/src/renderer/js/WSAPI_Interop.js +++ /dev/null @@ -1,108 +0,0 @@ -const wsapi = { - cache: {playParams: {id: 0}, status: null, remainingTime: 0}, - playbackCache: {status: null, time: Date.now()}, - search(term, limit) { - MusicKit.getInstance().api.search(term, {limit: limit, types: 'songs,artists,albums,playlists'}).then((results)=>{ - ipcRenderer.send('wsapi-returnSearch', JSON.stringify(results)) - }) - }, - searchLibrary(term, limit) { - MusicKit.getInstance().api.library.search(term, {limit: limit, types: 'library-songs,library-artists,library-albums,library-playlists'}).then((results)=>{ - ipcRenderer.send('wsapi-returnSearchLibrary', JSON.stringify(results)) - }) - }, - getAttributes: function () { - const mk = MusicKit.getInstance(); - const nowPlayingItem = mk.nowPlayingItem; - const isPlayingExport = mk.isPlaying; - const remainingTimeExport = mk.currentPlaybackTimeRemaining; - const attributes = (nowPlayingItem != null ? nowPlayingItem.attributes : {}); - - attributes.status = isPlayingExport ? isPlayingExport : false; - attributes.name = attributes.name ? attributes.name : 'No Title Found'; - attributes.artwork = attributes.artwork ? attributes.artwork : {url: ''}; - attributes.artwork.url = attributes.artwork.url ? attributes.artwork.url : ''; - attributes.playParams = attributes.playParams ? attributes.playParams : {id: 'no-id-found'}; - attributes.playParams.id = attributes.playParams.id ? attributes.playParams.id : 'no-id-found'; - attributes.albumName = attributes.albumName ? attributes.albumName : ''; - attributes.artistName = attributes.artistName ? attributes.artistName : ''; - attributes.genreNames = attributes.genreNames ? attributes.genreNames : []; - attributes.remainingTime = remainingTimeExport ? (remainingTimeExport * 1000) : 0; - attributes.durationInMillis = attributes.durationInMillis ? attributes.durationInMillis : 0; - attributes.startTime = Date.now(); - attributes.endTime = attributes.endTime ? attributes.endTime : Date.now(); - attributes.volume = mk.volume; - attributes.shuffleMode = mk.shuffleMode; - attributes.repeatMode = mk.repeatMode; - attributes.autoplayEnabled = mk.autoplayEnabled; - return attributes - }, - moveQueueItem(oldPosition, newPosition) { - MusicKit.getInstance().queue._queueItems.splice(newPosition,0,MusicKit.getInstance().queue._queueItems.splice(oldPosition,1)[0]) - MusicKit.getInstance().queue._reindex() - }, - setAutoplay(value) { - MusicKit.getInstance().autoplayEnabled = value - }, - returnDynamic(data, type) { - ipcRenderer.send('wsapi-returnDynamic', JSON.stringify(data), type) - }, - musickitApi(method, id, params, library = false) { - if (library) { - MusicKit.getInstance().api.library[method](id, params).then((results)=>{ - ipcRenderer.send('wsapi-returnMusicKitApi', JSON.stringify(results), method) - }) - } else { - MusicKit.getInstance().api[method](id, params).then((results)=>{ - ipcRenderer.send('wsapi-returnMusicKitApi', JSON.stringify(results), method) - }) - } - }, - getPlaybackState () { - ipcRenderer.send('wsapi-updatePlaybackState', MusicKitInterop.getAttributes()); - }, - getLyrics() { - ipcRenderer.send('wsapi-returnLyrics',JSON.stringify(app.lyrics)); - }, - getQueue() { - ipcRenderer.send('wsapi-returnQueue', JSON.stringify(MusicKit.getInstance().queue)) - }, - playNext(type, id) { - var request = {} - request[type] = id - MusicKit.getInstance().playNext(request) - }, - playLater(type, id) { - var request = {} - request[type] = id - MusicKit.getInstance().playLater(request) - }, - love() { - - }, - playTrackById(id, kind = "song") { - MusicKit.getInstance().setQueue({ [kind]: id }).then(function (queue) { - MusicKit.getInstance().play() - }) - }, - quickPlay(term) { - // Quick play by song name - MusicKit.getInstance().api.search(term, { limit: 2, types: 'songs' }).then(function (data) { - MusicKit.getInstance().setQueue({ song: data["songs"][0]["id"] }).then(function (queue) { - MusicKit.getInstance().play() - }) - }) - }, - toggleShuffle() { - MusicKit.getInstance().shuffleMode = MusicKit.getInstance().shuffleMode === 0 ? 1 : 0 - }, - toggleRepeat() { - if(MusicKit.getInstance().repeatMode == 0) { - MusicKit.getInstance().repeatMode = 1 - }else if(MusicKit.getInstance().repeatMode == 1){ - MusicKit.getInstance().repeatMode = 2 - }else{ - MusicKit.getInstance().repeatMode = 0 - } - } -} \ No newline at end of file diff --git a/src/renderer/less/ameframework.less b/src/renderer/less/ameframework.less new file mode 100644 index 00000000..4e1f770a --- /dev/null +++ b/src/renderer/less/ameframework.less @@ -0,0 +1,1017 @@ +:root { + --appleEase: cubic-bezier(0.42, 0, 0.58, 1); + --appleTransition: 0.2s var(--appleEase); +} + +/* Simple CSS framework for Apple Music Electron */ + +.md-labeltext { + font-size: 14px; + text-transform: uppercase; + opacity: 0.75; + font-weight: 500; +} + +.md-option-container { + /* border-radius: 10px; */ + overflow: hidden; +} + +.md-option-line { + display: flex; + width: 100%; + padding: 14px; + background: var(--opaquePageBGColor); + font-size: 0.85em; + + &.child { + background: rgb(0 0 0 / 15%); + } +} + +.md-option-segment.md-option-segment_auto { + width: auto; + white-space: nowrap; +} + +.md-option-container .md-option-line:not(:last-child) { + border-bottom: 1px solid rgb(0 0 0 / 15%); +} + +input[type="range"].md-slider { + -webkit-appearance: none; + height: 7px; + background: rgba(255, 255, 255, 0.6); + border-radius: 5px; + background-size: 70% 100%; + background-repeat: no-repeat; +} + +input[type="range"].md-slider::-webkit-slider-thumb { + -webkit-appearance: none; + height: 20px; + width: 20px; + border-radius: 50%; + background: rgb(255 255 255); + cursor: ew-resize; + box-shadow: 0 0 2px 0 #555; +} + +input[type="range"].md-slider::-webkit-slider-runnable-track { + -webkit-appearance: none; + box-shadow: none; + border: none; + background: transparent; +} + +.md-option-header { + padding: 10px; + border-bottom: 1px solid rgb(200 200 200 / 25%); + font-weight: 500; + font-size: 0.9em; + background: rgb(255 255 255 / 10%); +} + +.md-option-segment { + width: 100%; + display: flex; + justify-content: center; + flex-direction: column; +} + +.md-h1 { + font-size: 3em; + text-align: center; +} + +.md-header { + padding: 16px; +} + +.md-header-title { + padding: 18px; + font-weight: 600; + font-size: 16px; + height: 55px; + background: var(--opaquePageBGColor); + border-bottom: 1px solid rgb(0 0 0 / 15%); +} + +.md-footer { + padding: 16px; + text-align: center; +} + +.md-transparent { + background: transparent; +} + +.md-container { + display: flex; + flex-direction: column; + height: 100%; + position: absolute; + top: 0px; + left: 0px; + width: 100%; + padding: 32px; +} + +.md-container_panel { + padding: 0px; +} + +.md-body { + height: 100%; + padding: 16px; + font-size: 1.25em; +} + +@media (prefers-color-scheme: light) { + .md-btn { + box-shadow: + rgb(0 0 0 / 10%) 0px 0px 1px, + rgb(0 0 0 / 20%) 0px 1px 1px; + border: 1px solid rgb(0 0 0 / 15%); + } + + .md-close-btn { + background-color: #000; + } +} + +/* Vue transitions */ +.fade_simple-enter-active, +.fade_simple-leave-active { + transition: all 0.5s; +} + +.fade_simple-enter, +.fade_simple-leave-to { + opacity: 0; +} + +.fade-enter-active, +.fade-leave-active { + transition: all 0.5s; +} + +.fade-enter, +.fade-leave-to { + opacity: 0; + transform: scale(0.95); +} + +/* CSS Grids */ + +.container, +.container-fluid, +.container-xxl, +.container-xl, +.container-lg, +.container-md, +.container-sm { + width: 100%; + padding-right: var(--bs-gutter-x, 0.75rem); + padding-left: var(--bs-gutter-x, 0.75rem); + margin-right: auto; + margin-left: auto; +} + +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + /*margin-top: calc(-1 * var(--bs-gutter-y));*/ + /*margin-right: calc(-0.5 * var(--bs-gutter-x));*/ + /*margin-left: calc(-0.5 * var(--bs-gutter-x));*/ +} + +.row > * { + box-sizing: border-box; + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); + margin-top: var(--bs-gutter-y); +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +@media only screen and (min-width: 1133px) and (max-width: 1233px) { + .about-page { + .row .col-auto { + display: none !important; + } + } +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-left: 8.33333333%; +} + +.offset-2 { + margin-left: 16.66666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.33333333%; +} + +.offset-5 { + margin-left: 41.66666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.33333333%; +} + +.offset-8 { + margin-left: 66.66666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.33333333%; +} + +.offset-11 { + margin-left: 91.66666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.mx-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; +} + +.mx-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-right: 0 !important; +} + +.me-1 { + margin-right: 0.25rem !important; +} + +.me-2 { + margin-right: 0.5rem !important; +} + +.me-3 { + margin-right: 1rem !important; +} + +.me-4 { + margin-right: 1.5rem !important; +} + +.me-5 { + margin-right: 3rem !important; +} + +.me-auto { + margin-right: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-left: 0 !important; +} + +.ms-1 { + margin-left: 0.25rem !important; +} + +.ms-2 { + margin-left: 0.5rem !important; +} + +.ms-3 { + margin-left: 1rem !important; +} + +.ms-4 { + margin-left: 1.5rem !important; +} + +.ms-5 { + margin-left: 3rem !important; +} + +.ms-auto { + margin-left: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.px-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; +} + +.px-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-right: 0 !important; +} + +.pe-1 { + padding-right: 0.25rem !important; +} + +.pe-2 { + padding-right: 0.5rem !important; +} + +.pe-3 { + padding-right: 1rem !important; +} + +.pe-4 { + padding-right: 1.5rem !important; +} + +.pe-5 { + padding-right: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-left: 0 !important; +} + +.ps-1 { + padding-left: 0.25rem !important; +} + +.ps-2 { + padding-left: 0.5rem !important; +} + +.ps-3 { + padding-left: 1rem !important; +} + +.ps-4 { + padding-left: 1.5rem !important; +} + +.ps-5 { + padding-left: 3rem !important; +} diff --git a/src/renderer/less/appvars.less b/src/renderer/less/appvars.less new file mode 100644 index 00000000..e6b1af26 --- /dev/null +++ b/src/renderer/less/appvars.less @@ -0,0 +1,21 @@ +@colorMixRate: 1%; +@transparencyRate: 50%; + +@keyColor: #fc3c44; +@ciderColor: #ff2654; +@baseColor: #1e1e1e; +@baseColorMix: mix(@baseColor, transparent, @transparencyRate); +@sidebarColor: #2e2e2e; +@sidebarColorMix: mix(@sidebarColor, transparent, @transparencyRate); +@appOpacity: 0.15; + +:root { + --baseColor: @baseColor; + --baseColorMix: @baseColorMix; + --sidebarColor: @sidebarColor; + --sidebarColorMix: @sidebarColorMix; + --ciderColor: @ciderColor; + --appOpacity: @appOpacity; + --transparencyRate: @transparencyRate; + --macOSChromeColor: rgb(14 14 14 / 32%); +} diff --git a/src/renderer/less/bootstrap-vue.min.less b/src/renderer/less/bootstrap-vue.min.less new file mode 100644 index 00000000..8fac0f5e --- /dev/null +++ b/src/renderer/less/bootstrap-vue.min.less @@ -0,0 +1,2638 @@ +@charset "UTF-8"; +/*! + * BootstrapVue Custom CSS (https://bootstrap-vue.org) + */ +.bv-no-focus-ring:focus { + outline: none; +} + +@media (max-width: 575.98px) { + .bv-d-xs-down-none { + display: none !important; + } +} +@media (max-width: 767.98px) { + .bv-d-sm-down-none { + display: none !important; + } +} +@media (max-width: 991.98px) { + .bv-d-md-down-none { + display: none !important; + } +} +@media (max-width: 1199.98px) { + .bv-d-lg-down-none { + display: none !important; + } +} +.bv-d-xl-down-none { + display: none !important; +} + +.form-control.focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.form-control.focus.is-valid { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.form-control.focus.is-invalid { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.b-avatar { + display: inline-flex; + align-items: center; + justify-content: center; + vertical-align: middle; + flex-shrink: 0; + width: 2.5rem; + height: 2.5rem; + font-size: inherit; + font-weight: 400; + line-height: 1; + max-width: 100%; + max-height: auto; + text-align: center; + overflow: visible; + position: relative; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +.b-avatar:focus { + outline: 0; +} +.b-avatar.btn, .b-avatar[href] { + padding: 0; + border: 0; +} +.b-avatar.btn .b-avatar-img img, .b-avatar[href] .b-avatar-img img { + transition: -webkit-transform 0.15s ease-in-out; + transition: transform 0.15s ease-in-out; + transition: transform 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out; +} +.b-avatar.btn:not(:disabled):not(.disabled), .b-avatar[href]:not(:disabled):not(.disabled) { + cursor: pointer; +} +.b-avatar.btn:not(:disabled):not(.disabled):hover .b-avatar-img img, .b-avatar[href]:not(:disabled):not(.disabled):hover .b-avatar-img img { + -webkit-transform: scale(1.15); + transform: scale(1.15); +} +.b-avatar.disabled, .b-avatar:disabled, .b-avatar[disabled] { + opacity: 0.65; + pointer-events: none; +} +.b-avatar .b-avatar-custom, +.b-avatar .b-avatar-text, +.b-avatar .b-avatar-img { + border-radius: inherit; + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + -webkit-mask-image: radial-gradient(white, black); + mask-image: radial-gradient(white, black); +} +.b-avatar .b-avatar-text { + text-transform: uppercase; + white-space: nowrap; +} +.b-avatar[href] { + text-decoration: none; +} +.b-avatar > .b-icon { + width: 60%; + height: auto; + max-width: 100%; +} +.b-avatar .b-avatar-img img { + width: 100%; + height: 100%; + max-height: auto; + border-radius: inherit; + -o-object-fit: cover; + object-fit: cover; +} +.b-avatar .b-avatar-badge { + position: absolute; + min-height: 1.5em; + min-width: 1.5em; + padding: 0.25em; + line-height: 1; + border-radius: 10em; + font-size: 70%; + font-weight: 700; + z-index: 1; +} + +.b-avatar-sm { + width: 1.5rem; + height: 1.5rem; +} +.b-avatar-sm .b-avatar-text { + font-size: calc(0.6rem); +} +.b-avatar-sm .b-avatar-badge { + font-size: calc(0.42rem); +} + +.b-avatar-lg { + width: 3.5rem; + height: 3.5rem; +} +.b-avatar-lg .b-avatar-text { + font-size: calc(1.4rem); +} +.b-avatar-lg .b-avatar-badge { + font-size: calc(0.98rem); +} + +.b-avatar-group .b-avatar-group-inner { + display: flex; + flex-wrap: wrap; +} +.b-avatar-group .b-avatar { + border: 1px solid #dee2e6; +} +.b-avatar-group a.b-avatar:hover:not(.disabled):not(disabled), +.b-avatar-group .btn.b-avatar:hover:not(.disabled):not(disabled) { + z-index: 1; +} + +.b-calendar { + display: inline-flex; +} +.b-calendar .b-calendar-inner { + min-width: 250px; +} +.b-calendar .b-calendar-header, +.b-calendar .b-calendar-nav { + margin-bottom: 0.25rem; +} +.b-calendar .b-calendar-nav .btn { + padding: 0.25rem; +} +.b-calendar output { + padding: 0.25rem; + font-size: 80%; +} +.b-calendar output.readonly { + background-color: #e9ecef; + opacity: 1; +} +.b-calendar .b-calendar-footer { + margin-top: 0.5rem; +} +.b-calendar .b-calendar-grid { + padding: 0; + margin: 0; + overflow: hidden; +} +.b-calendar .b-calendar-grid .row { + flex-wrap: nowrap; +} +.b-calendar .b-calendar-grid-caption { + padding: 0.25rem; +} +.b-calendar .b-calendar-grid-body .col[data-date] .btn { + width: 32px; + height: 32px; + font-size: 14px; + line-height: 1; + margin: 3px auto; + padding: 9px 0; +} +.b-calendar .btn:disabled, .b-calendar .btn.disabled, .b-calendar .btn[aria-disabled=true] { + cursor: default; + pointer-events: none; +} + +.card-img-left { + border-top-left-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-img-right { + border-top-right-radius: calc(0.25rem - 1px); + border-bottom-right-radius: calc(0.25rem - 1px); +} + +.dropdown:not(.dropleft) .dropdown-toggle.dropdown-toggle-no-caret::after { + display: none !important; +} +.dropdown.dropleft .dropdown-toggle.dropdown-toggle-no-caret::before { + display: none !important; +} +.dropdown .dropdown-menu:focus { + outline: none; +} + +.b-dropdown-form { + display: inline-block; + padding: 0.25rem 1.5rem; + width: 100%; + clear: both; + font-weight: 400; +} +.b-dropdown-form:focus { + outline: 1px dotted !important; + outline: 5px auto -webkit-focus-ring-color !important; +} +.b-dropdown-form.disabled, .b-dropdown-form:disabled { + outline: 0 !important; + color: #6c757d; + pointer-events: none; +} + +.b-dropdown-text { + display: inline-block; + padding: 0.25rem 1.5rem; + margin-bottom: 0; + width: 100%; + clear: both; + font-weight: lighter; +} + +.custom-checkbox.b-custom-control-lg, +.input-group-lg .custom-checkbox { + font-size: 1.25rem; + line-height: 1.5; + padding-left: 1.875rem; +} +.custom-checkbox.b-custom-control-lg .custom-control-label::before, +.input-group-lg .custom-checkbox .custom-control-label::before { + top: 0.3125rem; + left: -1.875rem; + width: 1.25rem; + height: 1.25rem; + border-radius: 0.3rem; +} +.custom-checkbox.b-custom-control-lg .custom-control-label::after, +.input-group-lg .custom-checkbox .custom-control-label::after { + top: 0.3125rem; + left: -1.875rem; + width: 1.25rem; + height: 1.25rem; + background-size: 50% 50%; +} + +.custom-checkbox.b-custom-control-sm, +.input-group-sm .custom-checkbox { + font-size: 0.875rem; + line-height: 1.5; + padding-left: 1.3125rem; +} +.custom-checkbox.b-custom-control-sm .custom-control-label::before, +.input-group-sm .custom-checkbox .custom-control-label::before { + top: 0.21875rem; + left: -1.3125rem; + width: 0.875rem; + height: 0.875rem; + border-radius: 0.2rem; +} +.custom-checkbox.b-custom-control-sm .custom-control-label::after, +.input-group-sm .custom-checkbox .custom-control-label::after { + top: 0.21875rem; + left: -1.3125rem; + width: 0.875rem; + height: 0.875rem; + background-size: 50% 50%; +} + +.custom-switch.b-custom-control-lg, +.input-group-lg .custom-switch { + padding-left: 2.8125rem; +} +.custom-switch.b-custom-control-lg .custom-control-label, +.input-group-lg .custom-switch .custom-control-label { + font-size: 1.25rem; + line-height: 1.5; +} +.custom-switch.b-custom-control-lg .custom-control-label::before, +.input-group-lg .custom-switch .custom-control-label::before { + top: 0.3125rem; + height: 1.25rem; + left: -2.8125rem; + width: 2.1875rem; + border-radius: 0.625rem; +} +.custom-switch.b-custom-control-lg .custom-control-label::after, +.input-group-lg .custom-switch .custom-control-label::after { + top: calc( 0.3125rem + 2px ); + left: calc( -2.8125rem + 2px ); + width: calc( 1.25rem - 4px ); + height: calc( 1.25rem - 4px ); + border-radius: 0.625rem; + background-size: 50% 50%; +} +.custom-switch.b-custom-control-lg .custom-control-input:checked ~ .custom-control-label::after, +.input-group-lg .custom-switch .custom-control-input:checked ~ .custom-control-label::after { + -webkit-transform: translateX(0.9375rem); + transform: translateX(0.9375rem); +} + +.custom-switch.b-custom-control-sm, +.input-group-sm .custom-switch { + padding-left: 1.96875rem; +} +.custom-switch.b-custom-control-sm .custom-control-label, +.input-group-sm .custom-switch .custom-control-label { + font-size: 0.875rem; + line-height: 1.5; +} +.custom-switch.b-custom-control-sm .custom-control-label::before, +.input-group-sm .custom-switch .custom-control-label::before { + top: 0.21875rem; + left: -1.96875rem; + width: 1.53125rem; + height: 0.875rem; + border-radius: 0.4375rem; +} +.custom-switch.b-custom-control-sm .custom-control-label::after, +.input-group-sm .custom-switch .custom-control-label::after { + top: calc( 0.21875rem + 2px ); + left: calc( -1.96875rem + 2px ); + width: calc( 0.875rem - 4px ); + height: calc( 0.875rem - 4px ); + border-radius: 0.4375rem; + background-size: 50% 50%; +} +.custom-switch.b-custom-control-sm .custom-control-input:checked ~ .custom-control-label::after, +.input-group-sm .custom-switch .custom-control-input:checked ~ .custom-control-label::after { + -webkit-transform: translateX(0.65625rem); + transform: translateX(0.65625rem); +} + +.input-group > .input-group-prepend > .btn-group > .btn, +.input-group > .input-group-append:not(:last-child) > .btn-group > .btn, +.input-group > .input-group-append:last-child > .btn-group:not(:last-child):not(.dropdown-toggle) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .input-group-append > .btn-group > .btn, +.input-group > .input-group-prepend:not(:first-child) > .btn-group > .btn, +.input-group > .input-group-prepend:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.b-form-btn-label-control.form-control { + display: flex; + align-items: stretch; + height: auto; + padding: 0; + background-image: none; +} +.input-group .b-form-btn-label-control.form-control { + padding: 0; +} + +[dir=rtl] .b-form-btn-label-control.form-control, .b-form-btn-label-control.form-control[dir=rtl] { + flex-direction: row-reverse; +} +[dir=rtl] .b-form-btn-label-control.form-control > label, .b-form-btn-label-control.form-control[dir=rtl] > label { + text-align: right; +} + +.b-form-btn-label-control.form-control > .btn { + line-height: 1; + font-size: inherit; + box-shadow: none !important; + border: 0; +} +.b-form-btn-label-control.form-control > .btn:disabled { + pointer-events: none; +} +.b-form-btn-label-control.form-control.is-valid > .btn { + color: #28a745; +} +.b-form-btn-label-control.form-control.is-invalid > .btn { + color: #dc3545; +} +.b-form-btn-label-control.form-control > .dropdown-menu { + padding: 0.5rem; +} +.b-form-btn-label-control.form-control > .form-control { + height: auto; + min-height: calc(calc(1.5em + 0.75rem + 2px) - 2px); + padding-left: 0.25rem; + margin: 0; + border: 0; + outline: 0; + background: transparent; + word-break: break-word; + font-size: inherit; + white-space: normal; + cursor: pointer; +} +.b-form-btn-label-control.form-control > .form-control.form-control-sm { + min-height: calc(calc(1.5em + 0.5rem + 2px) - 2px); +} +.b-form-btn-label-control.form-control > .form-control.form-control-lg { + min-height: calc(calc(1.5em + 1rem + 2px) - 2px); +} +.input-group.input-group-sm .b-form-btn-label-control.form-control > .form-control { + min-height: calc(calc(1.5em + 0.5rem + 2px) - 2px); + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.input-group.input-group-lg .b-form-btn-label-control.form-control > .form-control { + min-height: calc(calc(1.5em + 1rem + 2px) - 2px); + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.b-form-btn-label-control.form-control[aria-disabled=true], .b-form-btn-label-control.form-control[aria-readonly=true] { + background-color: #e9ecef; + opacity: 1; +} +.b-form-btn-label-control.form-control[aria-disabled=true] { + pointer-events: none; +} +.b-form-btn-label-control.form-control[aria-disabled=true] > label { + cursor: default; +} + +.b-form-btn-label-control.btn-group > .dropdown-menu { + padding: 0.5rem; +} + +.custom-file-label { + white-space: nowrap; + overflow-x: hidden; +} + +.b-custom-control-lg.custom-file, +.b-custom-control-lg .custom-file-input, +.b-custom-control-lg .custom-file-label, +.input-group-lg.custom-file, +.input-group-lg .custom-file-input, +.input-group-lg .custom-file-label { + font-size: 1.25rem; + height: calc(1.5em + 1rem + 2px); +} +.b-custom-control-lg .custom-file-label, +.b-custom-control-lg .custom-file-label:after, +.input-group-lg .custom-file-label, +.input-group-lg .custom-file-label:after { + padding: 0.5rem 1rem; + line-height: 1.5; +} +.b-custom-control-lg .custom-file-label, +.input-group-lg .custom-file-label { + border-radius: 0.3rem; +} +.b-custom-control-lg .custom-file-label::after, +.input-group-lg .custom-file-label::after { + font-size: inherit; + height: calc( 1.5em + 1rem ); + border-radius: 0 0.3rem 0.3rem 0; +} + +.b-custom-control-sm.custom-file, +.b-custom-control-sm .custom-file-input, +.b-custom-control-sm .custom-file-label, +.input-group-sm.custom-file, +.input-group-sm .custom-file-input, +.input-group-sm .custom-file-label { + font-size: 0.875rem; + height: calc(1.5em + 0.5rem + 2px); +} +.b-custom-control-sm .custom-file-label, +.b-custom-control-sm .custom-file-label:after, +.input-group-sm .custom-file-label, +.input-group-sm .custom-file-label:after { + padding: 0.25rem 0.5rem; + line-height: 1.5; +} +.b-custom-control-sm .custom-file-label, +.input-group-sm .custom-file-label { + border-radius: 0.2rem; +} +.b-custom-control-sm .custom-file-label::after, +.input-group-sm .custom-file-label::after { + font-size: inherit; + height: calc( 1.5em + 0.5rem ); + border-radius: 0 0.2rem 0.2rem 0; +} + +.was-validated .form-control:invalid, .was-validated .form-control:valid, .form-control.is-invalid, .form-control.is-valid { + background-position: right calc(0.375em + 0.1875rem) center; +} + +input[type=color].form-control { + height: calc(1.5em + 0.75rem + 2px); + padding: 0.125rem 0.25rem; +} + +input[type=color].form-control.form-control-sm, +.input-group-sm input[type=color].form-control { + height: calc(1.5em + 0.5rem + 2px); + padding: 0.125rem 0.25rem; +} + +input[type=color].form-control.form-control-lg, +.input-group-lg input[type=color].form-control { + height: calc(1.5em + 1rem + 2px); + padding: 0.125rem 0.25rem; +} + +input[type=color].form-control:disabled { + background-color: #adb5bd; + opacity: 0.65; +} + +.input-group > .custom-range { + position: relative; + flex: 1 1 auto; + width: 1%; + margin-bottom: 0; +} +.input-group > .custom-range + .form-control, +.input-group > .custom-range + .form-control-plaintext, +.input-group > .custom-range + .custom-select, +.input-group > .custom-range + .custom-range, +.input-group > .custom-range + .custom-file { + margin-left: -1px; +} +.input-group > .form-control + .custom-range, +.input-group > .form-control-plaintext + .custom-range, +.input-group > .custom-select + .custom-range, +.input-group > .custom-range + .custom-range, +.input-group > .custom-file + .custom-range { + margin-left: -1px; +} +.input-group > .custom-range:focus { + z-index: 3; +} +.input-group > .custom-range:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .custom-range:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group > .custom-range { + height: calc(1.5em + 0.75rem + 2px); + padding: 0 0.75rem; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + height: calc(1.5em + 0.75rem + 2px); + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .input-group > .custom-range { + transition: none; + } +} +.input-group > .custom-range:focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.input-group > .custom-range:disabled, .input-group > .custom-range[readonly] { + background-color: #e9ecef; +} + +.input-group-lg > .custom-range { + height: calc(1.5em + 1rem + 2px); + padding: 0 1rem; + border-radius: 0.3rem; +} + +.input-group-sm > .custom-range { + height: calc(1.5em + 0.5rem + 2px); + padding: 0 0.5rem; + border-radius: 0.2rem; +} + +.was-validated .input-group .custom-range:valid, .input-group .custom-range.is-valid { + border-color: #28a745; +} +.was-validated .input-group .custom-range:valid:focus, .input-group .custom-range.is-valid:focus { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.was-validated .custom-range:valid:focus::-webkit-slider-thumb, .custom-range.is-valid:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem #9be7ac; +} +.was-validated .custom-range:valid:focus::-moz-range-thumb, .custom-range.is-valid:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem #9be7ac; +} +.was-validated .custom-range:valid:focus::-ms-thumb, .custom-range.is-valid:focus::-ms-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem #9be7ac; +} +.was-validated .custom-range:valid::-webkit-slider-thumb, .custom-range.is-valid::-webkit-slider-thumb { + background-color: #28a745; + background-image: none; +} +.was-validated .custom-range:valid::-webkit-slider-thumb:active, .custom-range.is-valid::-webkit-slider-thumb:active { + background-color: #9be7ac; + background-image: none; +} +.was-validated .custom-range:valid::-webkit-slider-runnable-track, .custom-range.is-valid::-webkit-slider-runnable-track { + background-color: rgba(40, 167, 69, 0.35); +} +.was-validated .custom-range:valid::-moz-range-thumb, .custom-range.is-valid::-moz-range-thumb { + background-color: #28a745; + background-image: none; +} +.was-validated .custom-range:valid::-moz-range-thumb:active, .custom-range.is-valid::-moz-range-thumb:active { + background-color: #9be7ac; + background-image: none; +} +.was-validated .custom-range:valid::-moz-range-track, .custom-range.is-valid::-moz-range-track { + background: rgba(40, 167, 69, 0.35); +} +.was-validated .custom-range:valid ~ .valid-feedback, +.was-validated .custom-range:valid ~ .valid-tooltip, .custom-range.is-valid ~ .valid-feedback, +.custom-range.is-valid ~ .valid-tooltip { + display: block; +} +.was-validated .custom-range:valid::-ms-thumb, .custom-range.is-valid::-ms-thumb { + background-color: #28a745; + background-image: none; +} +.was-validated .custom-range:valid::-ms-thumb:active, .custom-range.is-valid::-ms-thumb:active { + background-color: #9be7ac; + background-image: none; +} +.was-validated .custom-range:valid::-ms-track-lower, .custom-range.is-valid::-ms-track-lower { + background: rgba(40, 167, 69, 0.35); +} +.was-validated .custom-range:valid::-ms-track-upper, .custom-range.is-valid::-ms-track-upper { + background: rgba(40, 167, 69, 0.35); +} + +.was-validated .input-group .custom-range:invalid, .input-group .custom-range.is-invalid { + border-color: #dc3545; +} +.was-validated .input-group .custom-range:invalid:focus, .input-group .custom-range.is-invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.was-validated .custom-range:invalid:focus::-webkit-slider-thumb, .custom-range.is-invalid:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem #f6cdd1; +} +.was-validated .custom-range:invalid:focus::-moz-range-thumb, .custom-range.is-invalid:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem #f6cdd1; +} +.was-validated .custom-range:invalid:focus::-ms-thumb, .custom-range.is-invalid:focus::-ms-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem #f6cdd1; +} +.was-validated .custom-range:invalid::-webkit-slider-thumb, .custom-range.is-invalid::-webkit-slider-thumb { + background-color: #dc3545; + background-image: none; +} +.was-validated .custom-range:invalid::-webkit-slider-thumb:active, .custom-range.is-invalid::-webkit-slider-thumb:active { + background-color: #f6cdd1; + background-image: none; +} +.was-validated .custom-range:invalid::-webkit-slider-runnable-track, .custom-range.is-invalid::-webkit-slider-runnable-track { + background-color: rgba(220, 53, 69, 0.35); +} +.was-validated .custom-range:invalid::-moz-range-thumb, .custom-range.is-invalid::-moz-range-thumb { + background-color: #dc3545; + background-image: none; +} +.was-validated .custom-range:invalid::-moz-range-thumb:active, .custom-range.is-invalid::-moz-range-thumb:active { + background-color: #f6cdd1; + background-image: none; +} +.was-validated .custom-range:invalid::-moz-range-track, .custom-range.is-invalid::-moz-range-track { + background: rgba(220, 53, 69, 0.35); +} +.was-validated .custom-range:invalid ~ .invalid-feedback, +.was-validated .custom-range:invalid ~ .invalid-tooltip, .custom-range.is-invalid ~ .invalid-feedback, +.custom-range.is-invalid ~ .invalid-tooltip { + display: block; +} +.was-validated .custom-range:invalid::-ms-thumb, .custom-range.is-invalid::-ms-thumb { + background-color: #dc3545; + background-image: none; +} +.was-validated .custom-range:invalid::-ms-thumb:active, .custom-range.is-invalid::-ms-thumb:active { + background-color: #f6cdd1; + background-image: none; +} +.was-validated .custom-range:invalid::-ms-track-lower, .custom-range.is-invalid::-ms-track-lower { + background: rgba(220, 53, 69, 0.35); +} +.was-validated .custom-range:invalid::-ms-track-upper, .custom-range.is-invalid::-ms-track-upper { + background: rgba(220, 53, 69, 0.35); +} + +.custom-radio.b-custom-control-lg, +.input-group-lg .custom-radio { + font-size: 1.25rem; + line-height: 1.5; + padding-left: 1.875rem; +} +.custom-radio.b-custom-control-lg .custom-control-label::before, +.input-group-lg .custom-radio .custom-control-label::before { + top: 0.3125rem; + left: -1.875rem; + width: 1.25rem; + height: 1.25rem; + border-radius: 50%; +} +.custom-radio.b-custom-control-lg .custom-control-label::after, +.input-group-lg .custom-radio .custom-control-label::after { + top: 0.3125rem; + left: -1.875rem; + width: 1.25rem; + height: 1.25rem; + background: no-repeat 50%/50% 50%; +} + +.custom-radio.b-custom-control-sm, +.input-group-sm .custom-radio { + font-size: 0.875rem; + line-height: 1.5; + padding-left: 1.3125rem; +} +.custom-radio.b-custom-control-sm .custom-control-label::before, +.input-group-sm .custom-radio .custom-control-label::before { + top: 0.21875rem; + left: -1.3125rem; + width: 0.875rem; + height: 0.875rem; + border-radius: 50%; +} +.custom-radio.b-custom-control-sm .custom-control-label::after, +.input-group-sm .custom-radio .custom-control-label::after { + top: 0.21875rem; + left: -1.3125rem; + width: 0.875rem; + height: 0.875rem; + background: no-repeat 50%/50% 50%; +} + +.b-rating { + text-align: center; +} +.b-rating.d-inline-flex { + width: auto; +} +.b-rating .b-rating-star, +.b-rating .b-rating-value { + padding: 0 0.25em; +} +.b-rating .b-rating-value { + min-width: 2.5em; +} +.b-rating .b-rating-star { + display: inline-flex; + justify-content: center; + outline: 0; +} +.b-rating .b-rating-star .b-rating-icon { + display: inline-flex; + transition: all 0.15s ease-in-out; +} +.b-rating.disabled, .b-rating:disabled { + background-color: #e9ecef; + color: #6c757d; +} +.b-rating:not(.disabled):not(.readonly) .b-rating-star { + cursor: pointer; +} +.b-rating:not(.disabled):not(.readonly):focus:not(:hover) .b-rating-star.focused .b-rating-icon, +.b-rating:not(.disabled):not(.readonly) .b-rating-star:hover .b-rating-icon { + -webkit-transform: scale(1.5); + transform: scale(1.5); +} +.b-rating[dir=rtl] .b-rating-star-half { + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); +} + +.b-form-spinbutton { + text-align: center; + overflow: hidden; + background-image: none; + padding: 0; +} +[dir=rtl] .b-form-spinbutton:not(.flex-column), .b-form-spinbutton[dir=rtl]:not(.flex-column) { + flex-direction: row-reverse; +} + +.b-form-spinbutton output { + font-size: inherit; + outline: 0; + border: 0; + background-color: transparent; + width: auto; + margin: 0; + padding: 0 0.25rem; +} +.b-form-spinbutton output > div, +.b-form-spinbutton output > bdi { + display: block; + min-width: 2.25em; + height: 1.5em; +} +.b-form-spinbutton.flex-column { + height: auto; + width: auto; +} +.b-form-spinbutton.flex-column output { + margin: 0 0.25rem; + padding: 0.25rem 0; +} +.b-form-spinbutton:not(.d-inline-flex):not(.flex-column) { + output-width: 100%; +} +.b-form-spinbutton.d-inline-flex:not(.flex-column) { + width: auto; +} +.b-form-spinbutton .btn { + line-height: 1; + box-shadow: none !important; +} +.b-form-spinbutton .btn:disabled { + pointer-events: none; +} +.b-form-spinbutton .btn:hover:not(:disabled) > div > .b-icon { + -webkit-transform: scale(1.25); + transform: scale(1.25); +} +.b-form-spinbutton.disabled, .b-form-spinbutton.readonly { + background-color: #e9ecef; +} +.b-form-spinbutton.disabled { + pointer-events: none; +} + +.b-form-tags .b-form-tags-list { + margin-top: -0.25rem; +} +.b-form-tags .b-form-tags-list .b-from-tags-field, +.b-form-tags .b-form-tags-list .b-form-tag { + margin-top: 0.25rem; +} +.b-form-tags.focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.b-form-tags.focus.is-valid { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.b-form-tags.focus.is-invalid { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} +.b-form-tags.disabled { + background-color: #e9ecef; +} + +.b-form-tag { + font-size: 75%; + font-weight: normal; + line-height: 1.5; + margin-right: 0.25rem; +} +.b-form-tag.disabled { + opacity: 0.75; +} +.b-form-tag > button.b-form-tag-remove { + color: inherit; + font-size: 125%; + line-height: 1; + float: none; + margin-left: 0.25rem; +} + +.form-control-sm .b-form-tag { + line-height: 1.5; +} + +.form-control-lg .b-form-tag { + line-height: 1.5; +} + +.media-aside { + display: flex; + margin-right: 1rem; +} + +.media-aside-right { + margin-right: 0; + margin-left: 1rem; +} + +.modal-backdrop { + opacity: 0.5; +} + +.b-pagination-pills .page-item .page-link { + border-radius: 50rem !important; + margin-left: 0.25rem; + line-height: 1; +} +.b-pagination-pills .page-item:first-child .page-link { + margin-left: 0; +} + +.popover.b-popover { + display: block; + opacity: 1; + outline: 0; +} +.popover.b-popover.fade:not(.show) { + opacity: 0; +} +.popover.b-popover.show { + opacity: 1; +} + +.b-popover-primary.popover { + background-color: #cce5ff; + border-color: #b8daff; +} +.b-popover-primary.bs-popover-top > .arrow::before, .b-popover-primary.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #b8daff; +} +.b-popover-primary.bs-popover-top > .arrow::after, .b-popover-primary.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #cce5ff; +} +.b-popover-primary.bs-popover-right > .arrow::before, .b-popover-primary.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #b8daff; +} +.b-popover-primary.bs-popover-right > .arrow::after, .b-popover-primary.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #cce5ff; +} +.b-popover-primary.bs-popover-bottom > .arrow::before, .b-popover-primary.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #b8daff; +} +.b-popover-primary.bs-popover-bottom > .arrow::after, .b-popover-primary.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #bdddff; +} +.b-popover-primary.bs-popover-bottom .popover-header::before, .b-popover-primary.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #bdddff; +} +.b-popover-primary.bs-popover-left > .arrow::before, .b-popover-primary.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #b8daff; +} +.b-popover-primary.bs-popover-left > .arrow::after, .b-popover-primary.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #cce5ff; +} +.b-popover-primary .popover-header { + color: #212529; + background-color: #bdddff; + border-bottom-color: #a3d0ff; +} +.b-popover-primary .popover-body { + color: #004085; +} + +.b-popover-secondary.popover { + background-color: #e2e3e5; + border-color: #d6d8db; +} +.b-popover-secondary.bs-popover-top > .arrow::before, .b-popover-secondary.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #d6d8db; +} +.b-popover-secondary.bs-popover-top > .arrow::after, .b-popover-secondary.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #e2e3e5; +} +.b-popover-secondary.bs-popover-right > .arrow::before, .b-popover-secondary.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #d6d8db; +} +.b-popover-secondary.bs-popover-right > .arrow::after, .b-popover-secondary.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #e2e3e5; +} +.b-popover-secondary.bs-popover-bottom > .arrow::before, .b-popover-secondary.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #d6d8db; +} +.b-popover-secondary.bs-popover-bottom > .arrow::after, .b-popover-secondary.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #dadbde; +} +.b-popover-secondary.bs-popover-bottom .popover-header::before, .b-popover-secondary.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #dadbde; +} +.b-popover-secondary.bs-popover-left > .arrow::before, .b-popover-secondary.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #d6d8db; +} +.b-popover-secondary.bs-popover-left > .arrow::after, .b-popover-secondary.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #e2e3e5; +} +.b-popover-secondary .popover-header { + color: #212529; + background-color: #dadbde; + border-bottom-color: #ccced2; +} +.b-popover-secondary .popover-body { + color: #383d41; +} + +.b-popover-success.popover { + background-color: #d4edda; + border-color: #c3e6cb; +} +.b-popover-success.bs-popover-top > .arrow::before, .b-popover-success.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #c3e6cb; +} +.b-popover-success.bs-popover-top > .arrow::after, .b-popover-success.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #d4edda; +} +.b-popover-success.bs-popover-right > .arrow::before, .b-popover-success.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #c3e6cb; +} +.b-popover-success.bs-popover-right > .arrow::after, .b-popover-success.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #d4edda; +} +.b-popover-success.bs-popover-bottom > .arrow::before, .b-popover-success.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #c3e6cb; +} +.b-popover-success.bs-popover-bottom > .arrow::after, .b-popover-success.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #c9e8d1; +} +.b-popover-success.bs-popover-bottom .popover-header::before, .b-popover-success.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #c9e8d1; +} +.b-popover-success.bs-popover-left > .arrow::before, .b-popover-success.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #c3e6cb; +} +.b-popover-success.bs-popover-left > .arrow::after, .b-popover-success.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #d4edda; +} +.b-popover-success .popover-header { + color: #212529; + background-color: #c9e8d1; + border-bottom-color: #b7e1c1; +} +.b-popover-success .popover-body { + color: #155724; +} + +.b-popover-info.popover { + background-color: #d1ecf1; + border-color: #bee5eb; +} +.b-popover-info.bs-popover-top > .arrow::before, .b-popover-info.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #bee5eb; +} +.b-popover-info.bs-popover-top > .arrow::after, .b-popover-info.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #d1ecf1; +} +.b-popover-info.bs-popover-right > .arrow::before, .b-popover-info.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #bee5eb; +} +.b-popover-info.bs-popover-right > .arrow::after, .b-popover-info.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #d1ecf1; +} +.b-popover-info.bs-popover-bottom > .arrow::before, .b-popover-info.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #bee5eb; +} +.b-popover-info.bs-popover-bottom > .arrow::after, .b-popover-info.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #c5e7ed; +} +.b-popover-info.bs-popover-bottom .popover-header::before, .b-popover-info.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #c5e7ed; +} +.b-popover-info.bs-popover-left > .arrow::before, .b-popover-info.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #bee5eb; +} +.b-popover-info.bs-popover-left > .arrow::after, .b-popover-info.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #d1ecf1; +} +.b-popover-info .popover-header { + color: #212529; + background-color: #c5e7ed; + border-bottom-color: #b2dfe7; +} +.b-popover-info .popover-body { + color: #0c5460; +} + +.b-popover-warning.popover { + background-color: #fff3cd; + border-color: #ffeeba; +} +.b-popover-warning.bs-popover-top > .arrow::before, .b-popover-warning.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #ffeeba; +} +.b-popover-warning.bs-popover-top > .arrow::after, .b-popover-warning.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #fff3cd; +} +.b-popover-warning.bs-popover-right > .arrow::before, .b-popover-warning.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #ffeeba; +} +.b-popover-warning.bs-popover-right > .arrow::after, .b-popover-warning.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #fff3cd; +} +.b-popover-warning.bs-popover-bottom > .arrow::before, .b-popover-warning.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #ffeeba; +} +.b-popover-warning.bs-popover-bottom > .arrow::after, .b-popover-warning.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #ffefbe; +} +.b-popover-warning.bs-popover-bottom .popover-header::before, .b-popover-warning.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #ffefbe; +} +.b-popover-warning.bs-popover-left > .arrow::before, .b-popover-warning.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #ffeeba; +} +.b-popover-warning.bs-popover-left > .arrow::after, .b-popover-warning.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #fff3cd; +} +.b-popover-warning .popover-header { + color: #212529; + background-color: #ffefbe; + border-bottom-color: #ffe9a4; +} +.b-popover-warning .popover-body { + color: #856404; +} + +.b-popover-danger.popover { + background-color: #f8d7da; + border-color: #f5c6cb; +} +.b-popover-danger.bs-popover-top > .arrow::before, .b-popover-danger.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #f5c6cb; +} +.b-popover-danger.bs-popover-top > .arrow::after, .b-popover-danger.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #f8d7da; +} +.b-popover-danger.bs-popover-right > .arrow::before, .b-popover-danger.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #f5c6cb; +} +.b-popover-danger.bs-popover-right > .arrow::after, .b-popover-danger.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #f8d7da; +} +.b-popover-danger.bs-popover-bottom > .arrow::before, .b-popover-danger.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #f5c6cb; +} +.b-popover-danger.bs-popover-bottom > .arrow::after, .b-popover-danger.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #f6cace; +} +.b-popover-danger.bs-popover-bottom .popover-header::before, .b-popover-danger.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #f6cace; +} +.b-popover-danger.bs-popover-left > .arrow::before, .b-popover-danger.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #f5c6cb; +} +.b-popover-danger.bs-popover-left > .arrow::after, .b-popover-danger.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #f8d7da; +} +.b-popover-danger .popover-header { + color: #212529; + background-color: #f6cace; + border-bottom-color: #f2b4ba; +} +.b-popover-danger .popover-body { + color: #721c24; +} + +.b-popover-light.popover { + background-color: #fefefe; + border-color: #fdfdfe; +} +.b-popover-light.bs-popover-top > .arrow::before, .b-popover-light.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #fdfdfe; +} +.b-popover-light.bs-popover-top > .arrow::after, .b-popover-light.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #fefefe; +} +.b-popover-light.bs-popover-right > .arrow::before, .b-popover-light.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #fdfdfe; +} +.b-popover-light.bs-popover-right > .arrow::after, .b-popover-light.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #fefefe; +} +.b-popover-light.bs-popover-bottom > .arrow::before, .b-popover-light.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #fdfdfe; +} +.b-popover-light.bs-popover-bottom > .arrow::after, .b-popover-light.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #f6f6f6; +} +.b-popover-light.bs-popover-bottom .popover-header::before, .b-popover-light.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #f6f6f6; +} +.b-popover-light.bs-popover-left > .arrow::before, .b-popover-light.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #fdfdfe; +} +.b-popover-light.bs-popover-left > .arrow::after, .b-popover-light.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #fefefe; +} +.b-popover-light .popover-header { + color: #212529; + background-color: #f6f6f6; + border-bottom-color: #eaeaea; +} +.b-popover-light .popover-body { + color: #818182; +} + +.b-popover-dark.popover { + background-color: #d6d8d9; + border-color: #c6c8ca; +} +.b-popover-dark.bs-popover-top > .arrow::before, .b-popover-dark.bs-popover-auto[x-placement^=top] > .arrow::before { + border-top-color: #c6c8ca; +} +.b-popover-dark.bs-popover-top > .arrow::after, .b-popover-dark.bs-popover-auto[x-placement^=top] > .arrow::after { + border-top-color: #d6d8d9; +} +.b-popover-dark.bs-popover-right > .arrow::before, .b-popover-dark.bs-popover-auto[x-placement^=right] > .arrow::before { + border-right-color: #c6c8ca; +} +.b-popover-dark.bs-popover-right > .arrow::after, .b-popover-dark.bs-popover-auto[x-placement^=right] > .arrow::after { + border-right-color: #d6d8d9; +} +.b-popover-dark.bs-popover-bottom > .arrow::before, .b-popover-dark.bs-popover-auto[x-placement^=bottom] > .arrow::before { + border-bottom-color: #c6c8ca; +} +.b-popover-dark.bs-popover-bottom > .arrow::after, .b-popover-dark.bs-popover-auto[x-placement^=bottom] > .arrow::after { + border-bottom-color: #ced0d2; +} +.b-popover-dark.bs-popover-bottom .popover-header::before, .b-popover-dark.bs-popover-auto[x-placement^=bottom] .popover-header::before { + border-bottom-color: #ced0d2; +} +.b-popover-dark.bs-popover-left > .arrow::before, .b-popover-dark.bs-popover-auto[x-placement^=left] > .arrow::before { + border-left-color: #c6c8ca; +} +.b-popover-dark.bs-popover-left > .arrow::after, .b-popover-dark.bs-popover-auto[x-placement^=left] > .arrow::after { + border-left-color: #d6d8d9; +} +.b-popover-dark .popover-header { + color: #212529; + background-color: #ced0d2; + border-bottom-color: #c1c4c5; +} +.b-popover-dark .popover-body { + color: #1b1e21; +} + +.b-sidebar-outer { + position: fixed; + top: 0; + left: 0; + right: 0; + height: 0; + overflow: visible; + z-index: calc(1030 + 5); +} + +.b-sidebar-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: -1; + width: 100vw; + height: 100vh; + opacity: 0.6; +} + +.b-sidebar { + display: flex; + flex-direction: column; + position: fixed; + top: 0; + width: 320px; + max-width: 100%; + height: 100vh; + max-height: 100%; + margin: 0; + outline: 0; + -webkit-transform: translateX(0); + transform: translateX(0); +} +.b-sidebar.slide { + transition: -webkit-transform 0.3s ease-in-out; + transition: transform 0.3s ease-in-out; + transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .b-sidebar.slide { + transition: none; + } +} +.b-sidebar:not(.b-sidebar-right) { + left: 0; + right: auto; +} +.b-sidebar:not(.b-sidebar-right).slide:not(.show) { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} +.b-sidebar:not(.b-sidebar-right) > .b-sidebar-header .close { + margin-left: auto; +} +.b-sidebar.b-sidebar-right { + left: auto; + right: 0; +} +.b-sidebar.b-sidebar-right.slide:not(.show) { + -webkit-transform: translateX(100%); + transform: translateX(100%); +} +.b-sidebar.b-sidebar-right > .b-sidebar-header .close { + margin-right: auto; +} +.b-sidebar > .b-sidebar-header { + font-size: 1.5rem; + padding: 0.5rem 1rem; + display: flex; + flex-direction: row; + flex-grow: 0; + align-items: center; +} +[dir=rtl] .b-sidebar > .b-sidebar-header { + flex-direction: row-reverse; +} + +.b-sidebar > .b-sidebar-header .close { + float: none; + font-size: 1.5rem; +} +.b-sidebar > .b-sidebar-body { + flex-grow: 1; + height: 100%; + overflow-y: auto; +} +.b-sidebar > .b-sidebar-footer { + flex-grow: 0; +} + +.b-skeleton-wrapper { + cursor: wait; +} + +.b-skeleton { + position: relative; + overflow: hidden; + background-color: rgba(0, 0, 0, 0.12); + cursor: wait; + -webkit-mask-image: radial-gradient(white, black); + mask-image: radial-gradient(white, black); +} +.b-skeleton::before { + content: " "; +} + +.b-skeleton-text { + height: 1rem; + margin-bottom: 0.25rem; + border-radius: 0.25rem; +} + +.b-skeleton-button { + width: 75px; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: 0.25rem; +} + +.b-skeleton-avatar { + width: 2.5em; + height: 2.5em; + border-radius: 50%; +} + +.b-skeleton-input { + height: calc(1.5em + 0.75rem + 2px); + padding: 0.375rem 0.75rem; + line-height: 1.5; + border: #ced4da solid 1px; + border-radius: 0.25rem; +} + +.b-skeleton-icon-wrapper svg { + color: rgba(0, 0, 0, 0.12); +} + +.b-skeleton-img { + height: 100%; + width: 100%; +} + +.b-skeleton-animate-wave::after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 0; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent); + -webkit-animation: b-skeleton-animate-wave 1.75s linear infinite; + animation: b-skeleton-animate-wave 1.75s linear infinite; +} +@media (prefers-reduced-motion: reduce) { + .b-skeleton-animate-wave::after { + background: none; + -webkit-animation: none; + animation: none; + } +} + +@-webkit-keyframes b-skeleton-animate-wave { + from { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + } + to { + -webkit-transform: translateX(100%); + transform: translateX(100%); + } +} + +@keyframes b-skeleton-animate-wave { + from { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + } + to { + -webkit-transform: translateX(100%); + transform: translateX(100%); + } +} +.b-skeleton-animate-fade { + -webkit-animation: b-skeleton-animate-fade 0.875s ease-in-out alternate infinite; + animation: b-skeleton-animate-fade 0.875s ease-in-out alternate infinite; +} +@media (prefers-reduced-motion: reduce) { + .b-skeleton-animate-fade { + -webkit-animation: none; + animation: none; + } +} + +@-webkit-keyframes b-skeleton-animate-fade { + 0% { + opacity: 1; + } + 100% { + opacity: 0.4; + } +} + +@keyframes b-skeleton-animate-fade { + 0% { + opacity: 1; + } + 100% { + opacity: 0.4; + } +} +.b-skeleton-animate-throb { + -webkit-animation: b-skeleton-animate-throb 0.875s ease-in alternate infinite; + animation: b-skeleton-animate-throb 0.875s ease-in alternate infinite; +} +@media (prefers-reduced-motion: reduce) { + .b-skeleton-animate-throb { + -webkit-animation: none; + animation: none; + } +} + +@-webkit-keyframes b-skeleton-animate-throb { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0.975); + transform: scale(0.975); + } +} + +@keyframes b-skeleton-animate-throb { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0.975); + transform: scale(0.975); + } +} +.table.b-table.b-table-fixed { + table-layout: fixed; +} +.table.b-table.b-table-no-border-collapse { + border-collapse: separate; + border-spacing: 0; +} +.table.b-table[aria-busy=true] { + opacity: 0.55; +} +.table.b-table > tbody > tr.b-table-details > td { + border-top: none !important; +} +.table.b-table > caption { + caption-side: bottom; +} +.table.b-table.b-table-caption-top > caption { + caption-side: top !important; +} +.table.b-table > tbody > .table-active, +.table.b-table > tbody > .table-active > th, +.table.b-table > tbody > .table-active > td { + background-color: rgba(0, 0, 0, 0.075); +} +.table.b-table.table-hover > tbody > tr.table-active:hover td, +.table.b-table.table-hover > tbody > tr.table-active:hover th { + color: #212529; + background-image: linear-gradient(rgba(0, 0, 0, 0.075), rgba(0, 0, 0, 0.075)); + background-repeat: no-repeat; +} +.table.b-table > tbody > .bg-active, +.table.b-table > tbody > .bg-active > th, +.table.b-table > tbody > .bg-active > td { + background-color: rgba(255, 255, 255, 0.075) !important; +} +.table.b-table.table-hover.table-dark > tbody > tr.bg-active:hover td, +.table.b-table.table-hover.table-dark > tbody > tr.bg-active:hover th { + color: #fff; + background-image: linear-gradient(rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.075)); + background-repeat: no-repeat; +} + +.b-table-sticky-header, +.table-responsive, +[class*=table-responsive-] { + margin-bottom: 1rem; +} +.b-table-sticky-header > .table, +.table-responsive > .table, +[class*=table-responsive-] > .table { + margin-bottom: 0; +} + +.b-table-sticky-header { + overflow-y: auto; + max-height: 300px; +} + +@media print { + .b-table-sticky-header { + overflow-y: visible !important; + max-height: none !important; + } +} +@supports ((position: -webkit-sticky) or (position: sticky)) { + .b-table-sticky-header > .table.b-table > thead > tr > th { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 2; + } + + .b-table-sticky-header > .table.b-table > thead > tr > .b-table-sticky-column, +.b-table-sticky-header > .table.b-table > tbody > tr > .b-table-sticky-column, +.b-table-sticky-header > .table.b-table > tfoot > tr > .b-table-sticky-column, +.table-responsive > .table.b-table > thead > tr > .b-table-sticky-column, +.table-responsive > .table.b-table > tbody > tr > .b-table-sticky-column, +.table-responsive > .table.b-table > tfoot > tr > .b-table-sticky-column, +[class*=table-responsive-] > .table.b-table > thead > tr > .b-table-sticky-column, +[class*=table-responsive-] > .table.b-table > tbody > tr > .b-table-sticky-column, +[class*=table-responsive-] > .table.b-table > tfoot > tr > .b-table-sticky-column { + position: -webkit-sticky; + position: sticky; + left: 0; + } + .b-table-sticky-header > .table.b-table > thead > tr > .b-table-sticky-column, +.table-responsive > .table.b-table > thead > tr > .b-table-sticky-column, +[class*=table-responsive-] > .table.b-table > thead > tr > .b-table-sticky-column { + z-index: 5; + } + .b-table-sticky-header > .table.b-table > tbody > tr > .b-table-sticky-column, +.b-table-sticky-header > .table.b-table > tfoot > tr > .b-table-sticky-column, +.table-responsive > .table.b-table > tbody > tr > .b-table-sticky-column, +.table-responsive > .table.b-table > tfoot > tr > .b-table-sticky-column, +[class*=table-responsive-] > .table.b-table > tbody > tr > .b-table-sticky-column, +[class*=table-responsive-] > .table.b-table > tfoot > tr > .b-table-sticky-column { + z-index: 2; + } + + .table.b-table > thead > tr > .table-b-table-default, +.table.b-table > tbody > tr > .table-b-table-default, +.table.b-table > tfoot > tr > .table-b-table-default { + color: #212529; + background-color: #fff; + } + .table.b-table.table-dark > thead > tr > .bg-b-table-default, +.table.b-table.table-dark > tbody > tr > .bg-b-table-default, +.table.b-table.table-dark > tfoot > tr > .bg-b-table-default { + color: #fff; + background-color: #343a40; + } + .table.b-table.table-striped > tbody > tr:nth-of-type(odd) > .table-b-table-default { + background-image: linear-gradient(rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)); + background-repeat: no-repeat; + } + .table.b-table.table-striped.table-dark > tbody > tr:nth-of-type(odd) > .bg-b-table-default { + background-image: linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05)); + background-repeat: no-repeat; + } + .table.b-table.table-hover > tbody > tr:hover > .table-b-table-default { + color: #212529; + background-image: linear-gradient(rgba(0, 0, 0, 0.075), rgba(0, 0, 0, 0.075)); + background-repeat: no-repeat; + } + .table.b-table.table-hover.table-dark > tbody > tr:hover > .bg-b-table-default { + color: #fff; + background-image: linear-gradient(rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.075)); + background-repeat: no-repeat; + } +} +.table.b-table > thead > tr > [aria-sort], +.table.b-table > tfoot > tr > [aria-sort] { + cursor: pointer; + background-image: none; + background-repeat: no-repeat; + background-size: 0.65em 1em; +} +.table.b-table > thead > tr > [aria-sort]:not(.b-table-sort-icon-left), +.table.b-table > tfoot > tr > [aria-sort]:not(.b-table-sort-icon-left) { + background-position: right calc(0.75rem / 2) center; + padding-right: calc(0.75rem + 0.65em); +} +.table.b-table > thead > tr > [aria-sort].b-table-sort-icon-left, +.table.b-table > tfoot > tr > [aria-sort].b-table-sort-icon-left { + background-position: left calc(0.75rem / 2) center; + padding-left: calc(0.75rem + 0.65em); +} +.table.b-table > thead > tr > [aria-sort=none], +.table.b-table > tfoot > tr > [aria-sort=none] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='black' opacity='.3' d='M51 1l25 23 24 22H1l25-22zM51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table > thead > tr > [aria-sort=ascending], +.table.b-table > tfoot > tr > [aria-sort=ascending] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='black' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='black' opacity='.3' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table > thead > tr > [aria-sort=descending], +.table.b-table > tfoot > tr > [aria-sort=descending] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='black' opacity='.3' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='black' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table.table-dark > thead > tr > [aria-sort=none], .table.b-table.table-dark > tfoot > tr > [aria-sort=none], +.table.b-table > .thead-dark > tr > [aria-sort=none] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='white' opacity='.3' d='M51 1l25 23 24 22H1l25-22zM51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table.table-dark > thead > tr > [aria-sort=ascending], .table.b-table.table-dark > tfoot > tr > [aria-sort=ascending], +.table.b-table > .thead-dark > tr > [aria-sort=ascending] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='white' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='white' opacity='.3' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table.table-dark > thead > tr > [aria-sort=descending], .table.b-table.table-dark > tfoot > tr > [aria-sort=descending], +.table.b-table > .thead-dark > tr > [aria-sort=descending] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='white' opacity='.3' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='white' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table > thead > tr > .table-dark[aria-sort=none], +.table.b-table > tfoot > tr > .table-dark[aria-sort=none] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='white' opacity='.3' d='M51 1l25 23 24 22H1l25-22zM51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table > thead > tr > .table-dark[aria-sort=ascending], +.table.b-table > tfoot > tr > .table-dark[aria-sort=ascending] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='white' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='white' opacity='.3' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table > thead > tr > .table-dark[aria-sort=descending], +.table.b-table > tfoot > tr > .table-dark[aria-sort=descending] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='white' opacity='.3' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='white' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e"); +} +.table.b-table.table-sm > thead > tr > [aria-sort]:not(.b-table-sort-icon-left), +.table.b-table.table-sm > tfoot > tr > [aria-sort]:not(.b-table-sort-icon-left) { + background-position: right calc(0.3rem / 2) center; + padding-right: calc(0.3rem + 0.65em); +} +.table.b-table.table-sm > thead > tr > [aria-sort].b-table-sort-icon-left, +.table.b-table.table-sm > tfoot > tr > [aria-sort].b-table-sort-icon-left { + background-position: left calc(0.3rem / 2) center; + padding-left: calc(0.3rem + 0.65em); +} + +.table.b-table.b-table-selectable:not(.b-table-selectable-no-click) > tbody > tr { + cursor: pointer; +} +.table.b-table.b-table-selectable:not(.b-table-selectable-no-click).b-table-selecting.b-table-select-range > tbody > tr { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +@media (max-width: 575.98px) { + .table.b-table.b-table-stacked-sm { + display: block; + width: 100%; + } + .table.b-table.b-table-stacked-sm > caption, +.table.b-table.b-table-stacked-sm > tbody, +.table.b-table.b-table-stacked-sm > tbody > tr, +.table.b-table.b-table-stacked-sm > tbody > tr > td, +.table.b-table.b-table-stacked-sm > tbody > tr > th { + display: block; + } + .table.b-table.b-table-stacked-sm > thead, +.table.b-table.b-table-stacked-sm > tfoot { + display: none; + } + .table.b-table.b-table-stacked-sm > thead > tr.b-table-top-row, +.table.b-table.b-table-stacked-sm > thead > tr.b-table-bottom-row, +.table.b-table.b-table-stacked-sm > tfoot > tr.b-table-top-row, +.table.b-table.b-table-stacked-sm > tfoot > tr.b-table-bottom-row { + display: none; + } + .table.b-table.b-table-stacked-sm > caption { + caption-side: top !important; + } + .table.b-table.b-table-stacked-sm > tbody > tr > [data-label]::before { + content: attr(data-label); + width: 40%; + float: left; + text-align: right; + overflow-wrap: break-word; + font-weight: bold; + font-style: normal; + padding: 0 calc(1rem / 2) 0 0; + margin: 0; + } + .table.b-table.b-table-stacked-sm > tbody > tr > [data-label]::after { + display: block; + clear: both; + content: ""; + } + .table.b-table.b-table-stacked-sm > tbody > tr > [data-label] > div { + display: inline-block; + width: calc(100% - 40%); + padding: 0 0 0 calc(1rem / 2); + margin: 0; + } + .table.b-table.b-table-stacked-sm > tbody > tr.top-row, .table.b-table.b-table-stacked-sm > tbody > tr.bottom-row { + display: none; + } + .table.b-table.b-table-stacked-sm > tbody > tr > :first-child { + border-top-width: 3px; + } + .table.b-table.b-table-stacked-sm > tbody > tr > [rowspan] + td, +.table.b-table.b-table-stacked-sm > tbody > tr > [rowspan] + th { + border-top-width: 3px; + } +} +@media (max-width: 767.98px) { + .table.b-table.b-table-stacked-md { + display: block; + width: 100%; + } + .table.b-table.b-table-stacked-md > caption, +.table.b-table.b-table-stacked-md > tbody, +.table.b-table.b-table-stacked-md > tbody > tr, +.table.b-table.b-table-stacked-md > tbody > tr > td, +.table.b-table.b-table-stacked-md > tbody > tr > th { + display: block; + } + .table.b-table.b-table-stacked-md > thead, +.table.b-table.b-table-stacked-md > tfoot { + display: none; + } + .table.b-table.b-table-stacked-md > thead > tr.b-table-top-row, +.table.b-table.b-table-stacked-md > thead > tr.b-table-bottom-row, +.table.b-table.b-table-stacked-md > tfoot > tr.b-table-top-row, +.table.b-table.b-table-stacked-md > tfoot > tr.b-table-bottom-row { + display: none; + } + .table.b-table.b-table-stacked-md > caption { + caption-side: top !important; + } + .table.b-table.b-table-stacked-md > tbody > tr > [data-label]::before { + content: attr(data-label); + width: 40%; + float: left; + text-align: right; + overflow-wrap: break-word; + font-weight: bold; + font-style: normal; + padding: 0 calc(1rem / 2) 0 0; + margin: 0; + } + .table.b-table.b-table-stacked-md > tbody > tr > [data-label]::after { + display: block; + clear: both; + content: ""; + } + .table.b-table.b-table-stacked-md > tbody > tr > [data-label] > div { + display: inline-block; + width: calc(100% - 40%); + padding: 0 0 0 calc(1rem / 2); + margin: 0; + } + .table.b-table.b-table-stacked-md > tbody > tr.top-row, .table.b-table.b-table-stacked-md > tbody > tr.bottom-row { + display: none; + } + .table.b-table.b-table-stacked-md > tbody > tr > :first-child { + border-top-width: 3px; + } + .table.b-table.b-table-stacked-md > tbody > tr > [rowspan] + td, +.table.b-table.b-table-stacked-md > tbody > tr > [rowspan] + th { + border-top-width: 3px; + } +} +@media (max-width: 991.98px) { + .table.b-table.b-table-stacked-lg { + display: block; + width: 100%; + } + .table.b-table.b-table-stacked-lg > caption, +.table.b-table.b-table-stacked-lg > tbody, +.table.b-table.b-table-stacked-lg > tbody > tr, +.table.b-table.b-table-stacked-lg > tbody > tr > td, +.table.b-table.b-table-stacked-lg > tbody > tr > th { + display: block; + } + .table.b-table.b-table-stacked-lg > thead, +.table.b-table.b-table-stacked-lg > tfoot { + display: none; + } + .table.b-table.b-table-stacked-lg > thead > tr.b-table-top-row, +.table.b-table.b-table-stacked-lg > thead > tr.b-table-bottom-row, +.table.b-table.b-table-stacked-lg > tfoot > tr.b-table-top-row, +.table.b-table.b-table-stacked-lg > tfoot > tr.b-table-bottom-row { + display: none; + } + .table.b-table.b-table-stacked-lg > caption { + caption-side: top !important; + } + .table.b-table.b-table-stacked-lg > tbody > tr > [data-label]::before { + content: attr(data-label); + width: 40%; + float: left; + text-align: right; + overflow-wrap: break-word; + font-weight: bold; + font-style: normal; + padding: 0 calc(1rem / 2) 0 0; + margin: 0; + } + .table.b-table.b-table-stacked-lg > tbody > tr > [data-label]::after { + display: block; + clear: both; + content: ""; + } + .table.b-table.b-table-stacked-lg > tbody > tr > [data-label] > div { + display: inline-block; + width: calc(100% - 40%); + padding: 0 0 0 calc(1rem / 2); + margin: 0; + } + .table.b-table.b-table-stacked-lg > tbody > tr.top-row, .table.b-table.b-table-stacked-lg > tbody > tr.bottom-row { + display: none; + } + .table.b-table.b-table-stacked-lg > tbody > tr > :first-child { + border-top-width: 3px; + } + .table.b-table.b-table-stacked-lg > tbody > tr > [rowspan] + td, +.table.b-table.b-table-stacked-lg > tbody > tr > [rowspan] + th { + border-top-width: 3px; + } +} +@media (max-width: 1199.98px) { + .table.b-table.b-table-stacked-xl { + display: block; + width: 100%; + } + .table.b-table.b-table-stacked-xl > caption, +.table.b-table.b-table-stacked-xl > tbody, +.table.b-table.b-table-stacked-xl > tbody > tr, +.table.b-table.b-table-stacked-xl > tbody > tr > td, +.table.b-table.b-table-stacked-xl > tbody > tr > th { + display: block; + } + .table.b-table.b-table-stacked-xl > thead, +.table.b-table.b-table-stacked-xl > tfoot { + display: none; + } + .table.b-table.b-table-stacked-xl > thead > tr.b-table-top-row, +.table.b-table.b-table-stacked-xl > thead > tr.b-table-bottom-row, +.table.b-table.b-table-stacked-xl > tfoot > tr.b-table-top-row, +.table.b-table.b-table-stacked-xl > tfoot > tr.b-table-bottom-row { + display: none; + } + .table.b-table.b-table-stacked-xl > caption { + caption-side: top !important; + } + .table.b-table.b-table-stacked-xl > tbody > tr > [data-label]::before { + content: attr(data-label); + width: 40%; + float: left; + text-align: right; + overflow-wrap: break-word; + font-weight: bold; + font-style: normal; + padding: 0 calc(1rem / 2) 0 0; + margin: 0; + } + .table.b-table.b-table-stacked-xl > tbody > tr > [data-label]::after { + display: block; + clear: both; + content: ""; + } + .table.b-table.b-table-stacked-xl > tbody > tr > [data-label] > div { + display: inline-block; + width: calc(100% - 40%); + padding: 0 0 0 calc(1rem / 2); + margin: 0; + } + .table.b-table.b-table-stacked-xl > tbody > tr.top-row, .table.b-table.b-table-stacked-xl > tbody > tr.bottom-row { + display: none; + } + .table.b-table.b-table-stacked-xl > tbody > tr > :first-child { + border-top-width: 3px; + } + .table.b-table.b-table-stacked-xl > tbody > tr > [rowspan] + td, +.table.b-table.b-table-stacked-xl > tbody > tr > [rowspan] + th { + border-top-width: 3px; + } +} +.table.b-table.b-table-stacked { + display: block; + width: 100%; +} +.table.b-table.b-table-stacked > caption, +.table.b-table.b-table-stacked > tbody, +.table.b-table.b-table-stacked > tbody > tr, +.table.b-table.b-table-stacked > tbody > tr > td, +.table.b-table.b-table-stacked > tbody > tr > th { + display: block; +} +.table.b-table.b-table-stacked > thead, +.table.b-table.b-table-stacked > tfoot { + display: none; +} +.table.b-table.b-table-stacked > thead > tr.b-table-top-row, +.table.b-table.b-table-stacked > thead > tr.b-table-bottom-row, +.table.b-table.b-table-stacked > tfoot > tr.b-table-top-row, +.table.b-table.b-table-stacked > tfoot > tr.b-table-bottom-row { + display: none; +} +.table.b-table.b-table-stacked > caption { + caption-side: top !important; +} +.table.b-table.b-table-stacked > tbody > tr > [data-label]::before { + content: attr(data-label); + width: 40%; + float: left; + text-align: right; + overflow-wrap: break-word; + font-weight: bold; + font-style: normal; + padding: 0 calc(1rem / 2) 0 0; + margin: 0; +} +.table.b-table.b-table-stacked > tbody > tr > [data-label]::after { + display: block; + clear: both; + content: ""; +} +.table.b-table.b-table-stacked > tbody > tr > [data-label] > div { + display: inline-block; + width: calc(100% - 40%); + padding: 0 0 0 calc(1rem / 2); + margin: 0; +} +.table.b-table.b-table-stacked > tbody > tr.top-row, .table.b-table.b-table-stacked > tbody > tr.bottom-row { + display: none; +} +.table.b-table.b-table-stacked > tbody > tr > :first-child { + border-top-width: 3px; +} +.table.b-table.b-table-stacked > tbody > tr > [rowspan] + td, +.table.b-table.b-table-stacked > tbody > tr > [rowspan] + th { + border-top-width: 3px; +} + +.b-time { + min-width: 150px; +} +.b-time[aria-disabled=true] output, .b-time[aria-readonly=true] output, +.b-time output.disabled { + background-color: #e9ecef; + opacity: 1; +} +.b-time[aria-disabled=true] output { + pointer-events: none; +} +[dir=rtl] .b-time > .d-flex:not(.flex-column) { + flex-direction: row-reverse; +} + +.b-time .b-time-header { + margin-bottom: 0.5rem; +} +.b-time .b-time-header output { + padding: 0.25rem; + font-size: 80%; +} +.b-time .b-time-footer { + margin-top: 0.5rem; +} +.b-time .b-time-ampm { + margin-left: 0.5rem; +} + +.b-toast { + display: block; + position: relative; + max-width: 350px; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + background-clip: padding-box; + z-index: 1; + border-radius: 0.25rem; +} +.b-toast .toast { + background-color: rgba(255, 255, 255, 0.85); +} +.b-toast:not(:last-child) { + margin-bottom: 0.75rem; +} +.b-toast.b-toast-solid .toast { + background-color: white; +} +.b-toast .toast { + opacity: 1; +} +.b-toast .toast.fade:not(.show) { + opacity: 0; +} +.b-toast .toast .toast-body { + display: block; +} + +.b-toast-primary .toast { + background-color: rgba(230, 242, 255, 0.85); + border-color: rgba(184, 218, 255, 0.85); + color: #004085; +} +.b-toast-primary .toast .toast-header { + color: #004085; + background-color: rgba(204, 229, 255, 0.85); + border-bottom-color: rgba(184, 218, 255, 0.85); +} +.b-toast-primary.b-toast-solid .toast { + background-color: #e6f2ff; +} + +.b-toast-secondary .toast { + background-color: rgba(239, 240, 241, 0.85); + border-color: rgba(214, 216, 219, 0.85); + color: #383d41; +} +.b-toast-secondary .toast .toast-header { + color: #383d41; + background-color: rgba(226, 227, 229, 0.85); + border-bottom-color: rgba(214, 216, 219, 0.85); +} +.b-toast-secondary.b-toast-solid .toast { + background-color: #eff0f1; +} + +.b-toast-success .toast { + background-color: rgba(230, 245, 233, 0.85); + border-color: rgba(195, 230, 203, 0.85); + color: #155724; +} +.b-toast-success .toast .toast-header { + color: #155724; + background-color: rgba(212, 237, 218, 0.85); + border-bottom-color: rgba(195, 230, 203, 0.85); +} +.b-toast-success.b-toast-solid .toast { + background-color: #e6f5e9; +} + +.b-toast-info .toast { + background-color: rgba(229, 244, 247, 0.85); + border-color: rgba(190, 229, 235, 0.85); + color: #0c5460; +} +.b-toast-info .toast .toast-header { + color: #0c5460; + background-color: rgba(209, 236, 241, 0.85); + border-bottom-color: rgba(190, 229, 235, 0.85); +} +.b-toast-info.b-toast-solid .toast { + background-color: #e5f4f7; +} + +.b-toast-warning .toast { + background-color: rgba(255, 249, 231, 0.85); + border-color: rgba(255, 238, 186, 0.85); + color: #856404; +} +.b-toast-warning .toast .toast-header { + color: #856404; + background-color: rgba(255, 243, 205, 0.85); + border-bottom-color: rgba(255, 238, 186, 0.85); +} +.b-toast-warning.b-toast-solid .toast { + background-color: #fff9e7; +} + +.b-toast-danger .toast { + background-color: rgba(252, 237, 238, 0.85); + border-color: rgba(245, 198, 203, 0.85); + color: #721c24; +} +.b-toast-danger .toast .toast-header { + color: #721c24; + background-color: rgba(248, 215, 218, 0.85); + border-bottom-color: rgba(245, 198, 203, 0.85); +} +.b-toast-danger.b-toast-solid .toast { + background-color: #fcedee; +} + +.b-toast-light .toast { + background-color: rgba(255, 255, 255, 0.85); + border-color: rgba(253, 253, 254, 0.85); + color: #818182; +} +.b-toast-light .toast .toast-header { + color: #818182; + background-color: rgba(254, 254, 254, 0.85); + border-bottom-color: rgba(253, 253, 254, 0.85); +} +.b-toast-light.b-toast-solid .toast { + background-color: white; +} + +.b-toast-dark .toast { + background-color: rgba(227, 229, 229, 0.85); + border-color: rgba(198, 200, 202, 0.85); + color: #1b1e21; +} +.b-toast-dark .toast .toast-header { + color: #1b1e21; + background-color: rgba(214, 216, 217, 0.85); + border-bottom-color: rgba(198, 200, 202, 0.85); +} +.b-toast-dark.b-toast-solid .toast { + background-color: #e3e5e5; +} + +.b-toaster { + z-index: 1100; +} +.b-toaster .b-toaster-slot { + position: relative; + display: block; +} +.b-toaster .b-toaster-slot:empty { + display: none !important; +} + +.b-toaster.b-toaster-top-right, .b-toaster.b-toaster-top-left, .b-toaster.b-toaster-top-center, .b-toaster.b-toaster-top-full, .b-toaster.b-toaster-bottom-right, .b-toaster.b-toaster-bottom-left, .b-toaster.b-toaster-bottom-center, .b-toaster.b-toaster-bottom-full { + position: fixed; + left: 0.5rem; + right: 0.5rem; + margin: 0; + padding: 0; + height: 0; + overflow: visible; +} +.b-toaster.b-toaster-top-right .b-toaster-slot, .b-toaster.b-toaster-top-left .b-toaster-slot, .b-toaster.b-toaster-top-center .b-toaster-slot, .b-toaster.b-toaster-top-full .b-toaster-slot, .b-toaster.b-toaster-bottom-right .b-toaster-slot, .b-toaster.b-toaster-bottom-left .b-toaster-slot, .b-toaster.b-toaster-bottom-center .b-toaster-slot, .b-toaster.b-toaster-bottom-full .b-toaster-slot { + position: absolute; + max-width: 350px; + width: 100%; + /* IE 11 fix */ + left: 0; + right: 0; + padding: 0; + margin: 0; +} +.b-toaster.b-toaster-top-full .b-toaster-slot, .b-toaster.b-toaster-bottom-full .b-toaster-slot { + width: 100%; + max-width: 100%; +} +.b-toaster.b-toaster-top-full .b-toaster-slot .b-toast, +.b-toaster.b-toaster-top-full .b-toaster-slot .toast, .b-toaster.b-toaster-bottom-full .b-toaster-slot .b-toast, +.b-toaster.b-toaster-bottom-full .b-toaster-slot .toast { + width: 100%; + max-width: 100%; +} +.b-toaster.b-toaster-top-right, .b-toaster.b-toaster-top-left, .b-toaster.b-toaster-top-center, .b-toaster.b-toaster-top-full { + top: 0; +} +.b-toaster.b-toaster-top-right .b-toaster-slot, .b-toaster.b-toaster-top-left .b-toaster-slot, .b-toaster.b-toaster-top-center .b-toaster-slot, .b-toaster.b-toaster-top-full .b-toaster-slot { + top: 0.5rem; +} +.b-toaster.b-toaster-bottom-right, .b-toaster.b-toaster-bottom-left, .b-toaster.b-toaster-bottom-center, .b-toaster.b-toaster-bottom-full { + bottom: 0; +} +.b-toaster.b-toaster-bottom-right .b-toaster-slot, .b-toaster.b-toaster-bottom-left .b-toaster-slot, .b-toaster.b-toaster-bottom-center .b-toaster-slot, .b-toaster.b-toaster-bottom-full .b-toaster-slot { + bottom: 0.5rem; +} +.b-toaster.b-toaster-top-right .b-toaster-slot, .b-toaster.b-toaster-bottom-right .b-toaster-slot, .b-toaster.b-toaster-top-center .b-toaster-slot, .b-toaster.b-toaster-bottom-center .b-toaster-slot { + margin-left: auto; +} +.b-toaster.b-toaster-top-left .b-toaster-slot, .b-toaster.b-toaster-bottom-left .b-toaster-slot, .b-toaster.b-toaster-top-center .b-toaster-slot, .b-toaster.b-toaster-bottom-center .b-toaster-slot { + margin-right: auto; +} + +.b-toaster.b-toaster-top-right .b-toast.b-toaster-enter-active, .b-toaster.b-toaster-top-right .b-toast.b-toaster-leave-active, .b-toaster.b-toaster-top-right .b-toast.b-toaster-move, .b-toaster.b-toaster-top-left .b-toast.b-toaster-enter-active, .b-toaster.b-toaster-top-left .b-toast.b-toaster-leave-active, .b-toaster.b-toaster-top-left .b-toast.b-toaster-move, .b-toaster.b-toaster-bottom-right .b-toast.b-toaster-enter-active, .b-toaster.b-toaster-bottom-right .b-toast.b-toaster-leave-active, .b-toaster.b-toaster-bottom-right .b-toast.b-toaster-move, .b-toaster.b-toaster-bottom-left .b-toast.b-toaster-enter-active, .b-toaster.b-toaster-bottom-left .b-toast.b-toaster-leave-active, .b-toaster.b-toaster-bottom-left .b-toast.b-toaster-move { + transition: -webkit-transform 0.175s; + transition: transform 0.175s; + transition: transform 0.175s, -webkit-transform 0.175s; +} +.b-toaster.b-toaster-top-right .b-toast.b-toaster-enter-to .toast.fade, .b-toaster.b-toaster-top-right .b-toast.b-toaster-enter-active .toast.fade, .b-toaster.b-toaster-top-left .b-toast.b-toaster-enter-to .toast.fade, .b-toaster.b-toaster-top-left .b-toast.b-toaster-enter-active .toast.fade, .b-toaster.b-toaster-bottom-right .b-toast.b-toaster-enter-to .toast.fade, .b-toaster.b-toaster-bottom-right .b-toast.b-toaster-enter-active .toast.fade, .b-toaster.b-toaster-bottom-left .b-toast.b-toaster-enter-to .toast.fade, .b-toaster.b-toaster-bottom-left .b-toast.b-toaster-enter-active .toast.fade { + transition-delay: 0.175s; +} +.b-toaster.b-toaster-top-right .b-toast.b-toaster-leave-active, .b-toaster.b-toaster-top-left .b-toast.b-toaster-leave-active, .b-toaster.b-toaster-bottom-right .b-toast.b-toaster-leave-active, .b-toaster.b-toaster-bottom-left .b-toast.b-toaster-leave-active { + position: absolute; + transition-delay: 0.175s; +} +.b-toaster.b-toaster-top-right .b-toast.b-toaster-leave-active .toast.fade, .b-toaster.b-toaster-top-left .b-toast.b-toaster-leave-active .toast.fade, .b-toaster.b-toaster-bottom-right .b-toast.b-toaster-leave-active .toast.fade, .b-toaster.b-toaster-bottom-left .b-toast.b-toaster-leave-active .toast.fade { + transition-delay: 0s; +} +.tooltip.b-tooltip { + display: block; + opacity: 1; + outline: 0; + transition: opacity 0.1s var(--appleEase); +} +.tooltip.b-tooltip.fade:not(.show) { + opacity: 0; +} +.tooltip.b-tooltip.show { + opacity: 0.9; +} +.tooltip.b-tooltip.noninteractive { + pointer-events: none; +} +.tooltip.b-tooltip .arrow { + margin: 0 0.25rem; +} +.tooltip.b-tooltip.bs-tooltip-right .arrow, .tooltip.b-tooltip.b-tooltip-dark.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.b-tooltip-light.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.b-tooltip-danger.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.b-tooltip-warning.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.b-tooltip-info.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.b-tooltip-success.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.b-tooltip-secondary.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.b-tooltip-primary.bs-tooltip-auto[x-placement^=right] .arrow, .tooltip.b-tooltip.bs-tooltip-left .arrow, .tooltip.b-tooltip.b-tooltip-dark.bs-tooltip-auto[x-placement^=left] .arrow, .tooltip.b-tooltip.b-tooltip-light.bs-tooltip-auto[x-placement^=left] .arrow, .tooltip.b-tooltip.b-tooltip-danger.bs-tooltip-auto[x-placement^=left] .arrow, .tooltip.b-tooltip.b-tooltip-warning.bs-tooltip-auto[x-placement^=left] .arrow, .tooltip.b-tooltip.b-tooltip-info.bs-tooltip-auto[x-placement^=left] .arrow, .tooltip.b-tooltip.b-tooltip-success.bs-tooltip-auto[x-placement^=left] .arrow, .tooltip.b-tooltip.b-tooltip-secondary.bs-tooltip-auto[x-placement^=left] .arrow, .tooltip.b-tooltip.b-tooltip-primary.bs-tooltip-auto[x-placement^=left] .arrow { + margin: 0.25rem 0; +} + +.tooltip.b-tooltip-primary.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-primary.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #007bff; +} +.tooltip.b-tooltip-primary.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-primary.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #007bff; +} +.tooltip.b-tooltip-primary.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-primary.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #007bff; +} +.tooltip.b-tooltip-primary.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-primary.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #007bff; +} +.tooltip.b-tooltip-primary .tooltip-inner { + color: #fff; + background-color: #007bff; +} + +.tooltip.b-tooltip-secondary.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-secondary.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #6c757d; +} +.tooltip.b-tooltip-secondary.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-secondary.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #6c757d; +} +.tooltip.b-tooltip-secondary.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-secondary.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #6c757d; +} +.tooltip.b-tooltip-secondary.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-secondary.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #6c757d; +} +.tooltip.b-tooltip-secondary .tooltip-inner { + color: #fff; + background-color: #6c757d; +} + +.tooltip.b-tooltip-success.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-success.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #28a745; +} +.tooltip.b-tooltip-success.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-success.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #28a745; +} +.tooltip.b-tooltip-success.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-success.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #28a745; +} +.tooltip.b-tooltip-success.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-success.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #28a745; +} +.tooltip.b-tooltip-success .tooltip-inner { + color: #fff; + background-color: #28a745; +} + +.tooltip.b-tooltip-info.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-info.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #17a2b8; +} +.tooltip.b-tooltip-info.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-info.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #17a2b8; +} +.tooltip.b-tooltip-info.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-info.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #17a2b8; +} +.tooltip.b-tooltip-info.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-info.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #17a2b8; +} +.tooltip.b-tooltip-info .tooltip-inner { + color: #fff; + background-color: #17a2b8; +} + +.tooltip.b-tooltip-warning.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-warning.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #ffc107; +} +.tooltip.b-tooltip-warning.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-warning.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #ffc107; +} +.tooltip.b-tooltip-warning.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-warning.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #ffc107; +} +.tooltip.b-tooltip-warning.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-warning.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #ffc107; +} +.tooltip.b-tooltip-warning .tooltip-inner { + color: #212529; + background-color: #ffc107; +} + +.tooltip.b-tooltip-danger.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-danger.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #dc3545; +} +.tooltip.b-tooltip-danger.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-danger.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #dc3545; +} +.tooltip.b-tooltip-danger.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-danger.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #dc3545; +} +.tooltip.b-tooltip-danger.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-danger.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #dc3545; +} +.tooltip.b-tooltip-danger .tooltip-inner { + color: #fff; + background-color: #dc3545; +} + +.tooltip.b-tooltip-light.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-light.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #f8f9fa; +} +.tooltip.b-tooltip-light.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-light.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #f8f9fa; +} +.tooltip.b-tooltip-light.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-light.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #f8f9fa; +} +.tooltip.b-tooltip-light.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-light.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #f8f9fa; +} +.tooltip.b-tooltip-light .tooltip-inner { + color: #212529; + background-color: #f8f9fa; +} + +.tooltip.b-tooltip-dark.bs-tooltip-top .arrow::before, .tooltip.b-tooltip-dark.bs-tooltip-auto[x-placement^=top] .arrow::before { + border-top-color: #343a40; +} +.tooltip.b-tooltip-dark.bs-tooltip-right .arrow::before, .tooltip.b-tooltip-dark.bs-tooltip-auto[x-placement^=right] .arrow::before { + border-right-color: #343a40; +} +.tooltip.b-tooltip-dark.bs-tooltip-bottom .arrow::before, .tooltip.b-tooltip-dark.bs-tooltip-auto[x-placement^=bottom] .arrow::before { + border-bottom-color: #343a40; +} +.tooltip.b-tooltip-dark.bs-tooltip-left .arrow::before, .tooltip.b-tooltip-dark.bs-tooltip-auto[x-placement^=left] .arrow::before { + border-left-color: #343a40; +} +.tooltip.b-tooltip-dark .tooltip-inner { + color: #fff; + background-color: #343a40; +} + +.b-icon.bi { + display: inline-block; + overflow: visible; + vertical-align: -0.15em; +} +.b-icon.b-icon-animation-cylon, .b-icon.b-iconstack .b-icon-animation-cylon > g { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-animation: 0.75s infinite ease-in-out alternate b-icon-animation-cylon; + animation: 0.75s infinite ease-in-out alternate b-icon-animation-cylon; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-cylon, .b-icon.b-iconstack .b-icon-animation-cylon > g { + -webkit-animation: none; + animation: none; + } +} +.b-icon.b-icon-animation-cylon-vertical, .b-icon.b-iconstack .b-icon-animation-cylon-vertical > g { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-animation: 0.75s infinite ease-in-out alternate b-icon-animation-cylon-vertical; + animation: 0.75s infinite ease-in-out alternate b-icon-animation-cylon-vertical; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-cylon-vertical, .b-icon.b-iconstack .b-icon-animation-cylon-vertical > g { + -webkit-animation: none; + animation: none; + } +} +.b-icon.b-icon-animation-fade, .b-icon.b-iconstack .b-icon-animation-fade > g { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-animation: 0.75s infinite ease-in-out alternate b-icon-animation-fade; + animation: 0.75s infinite ease-in-out alternate b-icon-animation-fade; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-fade, .b-icon.b-iconstack .b-icon-animation-fade > g { + -webkit-animation: none; + animation: none; + } +} +.b-icon.b-icon-animation-spin, .b-icon.b-iconstack .b-icon-animation-spin > g { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-animation: 2s infinite linear normal b-icon-animation-spin; + animation: 2s infinite linear normal b-icon-animation-spin; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-spin, .b-icon.b-iconstack .b-icon-animation-spin > g { + -webkit-animation: none; + animation: none; + } +} +.b-icon.b-icon-animation-spin-reverse, .b-icon.b-iconstack .b-icon-animation-spin-reverse > g { + -webkit-transform-origin: center; + transform-origin: center; + animation: 2s infinite linear reverse b-icon-animation-spin; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-spin-reverse, .b-icon.b-iconstack .b-icon-animation-spin-reverse > g { + -webkit-animation: none; + animation: none; + } +} +.b-icon.b-icon-animation-spin-pulse, .b-icon.b-iconstack .b-icon-animation-spin-pulse > g { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-animation: 1s infinite steps(8) normal b-icon-animation-spin; + animation: 1s infinite steps(8) normal b-icon-animation-spin; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-spin-pulse, .b-icon.b-iconstack .b-icon-animation-spin-pulse > g { + -webkit-animation: none; + animation: none; + } +} +.b-icon.b-icon-animation-spin-reverse-pulse, .b-icon.b-iconstack .b-icon-animation-spin-reverse-pulse > g { + -webkit-transform-origin: center; + transform-origin: center; + animation: 1s infinite steps(8) reverse b-icon-animation-spin; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-spin-reverse-pulse, .b-icon.b-iconstack .b-icon-animation-spin-reverse-pulse > g { + -webkit-animation: none; + animation: none; + } +} +.b-icon.b-icon-animation-throb, .b-icon.b-iconstack .b-icon-animation-throb > g { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-animation: 0.75s infinite ease-in-out alternate b-icon-animation-throb; + animation: 0.75s infinite ease-in-out alternate b-icon-animation-throb; +} +@media (prefers-reduced-motion: reduce) { + .b-icon.b-icon-animation-throb, .b-icon.b-iconstack .b-icon-animation-throb > g { + -webkit-animation: none; + animation: none; + } +} + +@-webkit-keyframes b-icon-animation-cylon { + 0% { + -webkit-transform: translateX(-25%); + transform: translateX(-25%); + } + 100% { + -webkit-transform: translateX(25%); + transform: translateX(25%); + } +} + +@keyframes b-icon-animation-cylon { + 0% { + -webkit-transform: translateX(-25%); + transform: translateX(-25%); + } + 100% { + -webkit-transform: translateX(25%); + transform: translateX(25%); + } +} +@-webkit-keyframes b-icon-animation-cylon-vertical { + 0% { + -webkit-transform: translateY(25%); + transform: translateY(25%); + } + 100% { + -webkit-transform: translateY(-25%); + transform: translateY(-25%); + } +} +@keyframes b-icon-animation-cylon-vertical { + 0% { + -webkit-transform: translateY(25%); + transform: translateY(25%); + } + 100% { + -webkit-transform: translateY(-25%); + transform: translateY(-25%); + } +} +@-webkit-keyframes b-icon-animation-fade { + 0% { + opacity: 0.1; + } + 100% { + opacity: 1; + } +} +@keyframes b-icon-animation-fade { + 0% { + opacity: 0.1; + } + 100% { + opacity: 1; + } +} +@-webkit-keyframes b-icon-animation-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes b-icon-animation-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-webkit-keyframes b-icon-animation-throb { + 0% { + opacity: 0.5; + -webkit-transform: scale(0.5); + transform: scale(0.5); + } + 100% { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } +} +@keyframes b-icon-animation-throb { + 0% { + opacity: 0.5; + -webkit-transform: scale(0.5); + transform: scale(0.5); + } + 100% { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } +} +.btn .b-icon.bi, +.nav-link .b-icon.bi, +.dropdown-toggle .b-icon.bi, +.dropdown-item .b-icon.bi, +.input-group-text .b-icon.bi { + font-size: 125%; + vertical-align: text-bottom; +} + +/*# sourceMappingURL=bootstrap-vue.css.map */ \ No newline at end of file diff --git a/src/renderer/less/bootstrap.less b/src/renderer/less/bootstrap.less index 6dfc7821..4aea1cf8 100644 --- a/src/renderer/less/bootstrap.less +++ b/src/renderer/less/bootstrap.less @@ -1,1107 +1,8036 @@ -.modal { - position: fixed; - top: 0; - left: 0; - z-index: 1055; - display: none; - width: 100%; - height: 100%; - overflow-x: hidden; - overflow-y: auto; - outline: 0; - user-select: none; +// Dropdown - - .close { - width: 50px; - height: 42px; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; - - &:hover { - background-color: rgb(196, 43, 28) - } - } +.dropup, +.dropend, +.dropdown, +.dropstart { + position: relative; } -.modal-dialog { - position: relative; - width: auto; - margin: 0.5rem; - pointer-events: none; - color: var(--textColor); +.dropdown-toggle { + white-space: nowrap; +} +.dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; } -.modal.fade .modal-dialog { - transition: transform 0.1s var(--appleEase), opacity 0.1s var(--appleEase); - transform: scale(0.9); - opacity: 0; +.dropdown-menu { + position: absolute; + z-index: 1000; + display: none; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: var(--color1); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; + box-shadow: var(--mediaItemShadow), var(--mediaItemShadow-ShadowSubtle); + backdrop-filter: var(--glassFilter); +} +.dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: 0.125rem; } -@media (prefers-reduced-motion: reduce) { - .modal.fade .modal-dialog { - transition: none; - } +.dropdown-menu-start { + --bs-position: start; +} +.dropdown-menu-start[data-bs-popper] { + right: auto; + left: 0; } -.modal.show .modal-dialog { - transform: none; - opacity: 1; +.dropdown-menu-end { + --bs-position: end; } - -.modal.modal-static .modal-dialog { - transform: scale(1.02); -} - -.modal-dialog-scrollable { - height: calc(100% - 1rem); -} - -.modal-dialog-scrollable .modal-content { - max-height: 100%; - overflow: hidden; -} - -.modal-dialog-scrollable .modal-body { - overflow-y: auto; -} - -.modal-dialog-centered { - display: flex; - align-items: center; - min-height: calc(100% - 1rem); -} - -.modal-content { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - pointer-events: auto; - background-color: var(--modalBackground); - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; - outline: 0; - box-shadow: var(--ciderShadow-Generic); - overflow: hidden; -} - -.modal-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: 1050; - width: 100vw; - height: 100vh; - background-color: #000; -} - -.modal-backdrop.fade { - opacity: 0; -} - -.modal-backdrop.show { - opacity: 0.5; -} - -.modal-header { - display: flex; - flex-shrink: 0; - align-items: center; - justify-content: space-between; - padding: 1rem 1rem; - border-top-left-radius: calc(0.3rem - 1px); - border-top-right-radius: calc(0.3rem - 1px); -} - -.modal-header .btn-close { - padding: 0.5rem 0.5rem; - margin: -0.5rem -0.5rem -0.5rem auto; -} - -.modal-title { - line-height: 1.5; - margin: 0; -} - -.modal-body { - position: relative; - flex: 1 1 auto; - padding: 3rem 1rem 1rem 1rem; - font-size: 0.9em -} - -.modal-footer { - display: flex; - flex-wrap: wrap; - flex-shrink: 0; - align-items: center; - justify-content: flex-end; - padding: 0.75rem; - border-bottom-right-radius: calc(0.3rem - 1px); - border-bottom-left-radius: calc(0.3rem - 1px); -} - -.modal-footer>* { - margin: 0.25rem; +.dropdown-menu-end[data-bs-popper] { + right: 0; + left: auto; } @media (min-width: 576px) { - .modal-dialog { - max-width: 500px; - margin: 1.75rem auto; - } + .dropdown-menu-sm-start { + --bs-position: start; + } + .dropdown-menu-sm-start[data-bs-popper] { + right: auto; + left: 0; + } - .modal-dialog-scrollable { - height: calc(100% - 3.5rem); - } + .dropdown-menu-sm-end { + --bs-position: end; + } + .dropdown-menu-sm-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 768px) { + .dropdown-menu-md-start { + --bs-position: start; + } + .dropdown-menu-md-start[data-bs-popper] { + right: auto; + left: 0; + } - .modal-dialog-centered { - min-height: calc(100% - 3.5rem); - } + .dropdown-menu-md-end { + --bs-position: end; + } + .dropdown-menu-md-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 992px) { + .dropdown-menu-lg-start { + --bs-position: start; + } + .dropdown-menu-lg-start[data-bs-popper] { + right: auto; + left: 0; + } - .modal-sm { - max-width: 300px; - } + .dropdown-menu-lg-end { + --bs-position: end; + } + .dropdown-menu-lg-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1200px) { + .dropdown-menu-xl-start { + --bs-position: start; + } + .dropdown-menu-xl-start[data-bs-popper] { + right: auto; + left: 0; + } + + .dropdown-menu-xl-end { + --bs-position: end; + } + .dropdown-menu-xl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1400px) { + .dropdown-menu-xxl-start { + --bs-position: start; + } + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto; + left: 0; + } + + .dropdown-menu-xxl-end { + --bs-position: end; + } + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: 0.125rem; +} +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: 0.125rem; +} +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropend .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropend .dropdown-toggle::after { + vertical-align: 0; +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: 0.125rem; +} +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} +.dropstart .dropdown-toggle::after { + display: none; +} +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropstart .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropstart .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid rgba(0, 0, 0, 0.15); +} + +.dropdown-item { + display: block; + width: 100%; + padding: 0.25rem 1rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.dropdown-item:hover, +.dropdown-item:focus { + color: #1e2125; + background-color: #e9ecef; +} +.dropdown-item.active, +.dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #0d6efd; +} +.dropdown-item.disabled, +.dropdown-item:disabled { + color: #adb5bd; + pointer-events: none; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: 0.5rem 1rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} + +.dropdown-item-text { + display: block; + padding: 0.25rem 1rem; + color: #212529; +} + +.dropdown-menu-dark { + color: #dee2e6; + background-color: #343a40; + border-color: rgba(0, 0, 0, 0.15); +} +.dropdown-menu-dark .dropdown-item { + color: #dee2e6; +} +.dropdown-menu-dark .dropdown-item:hover, +.dropdown-menu-dark .dropdown-item:focus { + color: #fff; + background-color: rgba(255, 255, 255, 0.15); +} +.dropdown-menu-dark .dropdown-item.active, +.dropdown-menu-dark .dropdown-item:active { + color: #fff; + background-color: #0d6efd; +} +.dropdown-menu-dark .dropdown-item.disabled, +.dropdown-menu-dark .dropdown-item:disabled { + color: #adb5bd; +} +.dropdown-menu-dark .dropdown-divider { + border-color: rgba(0, 0, 0, 0.15); +} +.dropdown-menu-dark .dropdown-item-text { + color: #dee2e6; +} +.dropdown-menu-dark .dropdown-header { + color: #adb5bd; +} + +// List Group +.list-group { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: 0.25rem; +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section; +} + +.list-group-numbered > li::before { + content: counters(section, ".") ". "; + counter-increment: section; +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} + +.list-group-item-action:hover, +.list-group-item-action:focus { + z-index: 1; + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} + +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} + +.list-group-item { + position: relative; + display: block; + padding: 0.5rem 1rem; + color: #212529; + text-decoration: none; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} + +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} + +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit; +} + +.list-group-item.disabled, +.list-group-item:disabled { + color: #6c757d; + pointer-events: none; + background-color: #fff; +} + +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} + +.list-group-item + .list-group-item { + border-top-width: 0; +} + +.list-group-item + .list-group-item.active { + margin-top: -1px; + border-top-width: 1px; +} + +.list-group-horizontal { + flex-direction: row; +} + +.list-group-horizontal > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; +} + +.list-group-horizontal > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; +} + +.list-group-horizontal > .list-group-item.active { + margin-top: 0; +} + +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; +} + +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; +} + +@media (min-width: 576px) { + .list-group-horizontal-sm { + flex-direction: row; + } + + .list-group-horizontal-sm > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + + .list-group-horizontal-sm > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0; + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} + +@media (min-width: 768px) { + .list-group-horizontal-md { + flex-direction: row; + } + + .list-group-horizontal-md > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + + .list-group-horizontal-md > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0; + } + + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } } @media (min-width: 992px) { + .list-group-horizontal-lg { + flex-direction: row; + } - .modal-lg, - .modal-xl { - max-width: 800px; - } + .list-group-horizontal-lg > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + + .list-group-horizontal-lg > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0; + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } } @media (min-width: 1200px) { - .modal-xl { - max-width: 1140px; + .list-group-horizontal-xl { + flex-direction: row; + } + + .list-group-horizontal-xl > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + + .list-group-horizontal-xl > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0; + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} + +@media (min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction: row; + } + + .list-group-horizontal-xxl > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + + .list-group-horizontal-xxl > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0; + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} + +.list-group-flush { + border-radius: 0; +} + +.list-group-flush > .list-group-item { + border-width: 0 0 1px; +} + +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0; +} + +.list-group-item-primary { + color: #084298; + background-color: #cfe2ff; +} + +.list-group-item-primary.list-group-item-action:hover, +.list-group-item-primary.list-group-item-action:focus { + color: #084298; + background-color: #bacbe6; +} + +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #084298; + border-color: #084298; +} + +.list-group-item-secondary { + color: #41464b; + background-color: #e2e3e5; +} + +.list-group-item-secondary.list-group-item-action:hover, +.list-group-item-secondary.list-group-item-action:focus { + color: #41464b; + background-color: #cbccce; +} + +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #41464b; + border-color: #41464b; +} + +.list-group-item-success { + color: #0f5132; + background-color: #d1e7dd; +} + +.list-group-item-success.list-group-item-action:hover, +.list-group-item-success.list-group-item-action:focus { + color: #0f5132; + background-color: #bcd0c7; +} + +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #0f5132; + border-color: #0f5132; +} + +.list-group-item-info { + color: #055160; + background-color: #cff4fc; +} + +.list-group-item-info.list-group-item-action:hover, +.list-group-item-info.list-group-item-action:focus { + color: #055160; + background-color: #badce3; +} + +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #055160; + border-color: #055160; +} + +.list-group-item-warning { + color: #664d03; + background-color: #fff3cd; +} + +.list-group-item-warning.list-group-item-action:hover, +.list-group-item-warning.list-group-item-action:focus { + color: #664d03; + background-color: #e6dbb9; +} + +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #664d03; + border-color: #664d03; +} + +.list-group-item-danger { + color: #842029; + background-color: #f8d7da; +} + +.list-group-item-danger.list-group-item-action:hover, +.list-group-item-danger.list-group-item-action:focus { + color: #842029; + background-color: #dfc2c4; +} + +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #842029; + border-color: #842029; +} + +.list-group-item-light { + color: #636464; + background-color: #fefefe; +} + +.list-group-item-light.list-group-item-action:hover, +.list-group-item-light.list-group-item-action:focus { + color: #636464; + background-color: #e5e5e5; +} + +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #636464; + border-color: #636464; +} + +.list-group-item-dark { + color: var(--textColor); + background-color: #333; +} + +.list-group-item-dark.list-group-item-action:hover, +.list-group-item-dark.list-group-item-action:focus { + color: #141619; + background-color: #bebebf; +} + +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #141619; + border-color: #141619; +} + +// Toasts + +.toast { + width: 350px; + max-width: 100%; + font-size: 0.875rem; + pointer-events: auto; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} +.toast.showing { + opacity: 0; +} +.toast:not(.show) { + display: none; +} + +.toast-container { + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none; +} +.toast-container > :not(:last-child) { + margin-bottom: 0.75rem; +} + +.toast-header { + display: flex; + align-items: center; + padding: 0.5rem 0.75rem; + color: #6c757d; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.toast-header .btn-close { + margin-right: -0.375rem; + margin-left: 0.75rem; +} + +.toast-body { + padding: 0.75rem; + word-wrap: break-word; +} + +// Card +.card { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #333; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} + +.card > hr { + margin-right: 0; + margin-left: 0; +} + +.card > .list-group { + border-top: inherit; + border-bottom: inherit; +} + +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card > .card-header + .list-group, +.card > .list-group + .card-footer { + border-top: 0; +} + +.card-body { + flex: 1 1 auto; + padding: 1rem 1rem; +} + +.card-title { + margin-bottom: 0.5rem; +} + +.card-subtitle { + margin-top: -0.25rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link + .card-link { + margin-left: 1rem; +} + +.card-header { + padding: 0.5rem 1rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} + +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} + +.card-footer { + padding: 0.5rem 1rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); + text-align: center; +} + +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-header-tabs { + margin-right: -0.5rem; + margin-bottom: -0.5rem; + margin-left: -0.5rem; + border-bottom: 0; +} + +.card-header-pills { + margin-right: -0.5rem; + margin-left: -0.5rem; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1rem; + border-radius: calc(0.25rem - 1px); +} + +.card-img, +.card-img-top, +.card-img-bottom { + width: 100%; +} + +.card-img, +.card-img-top { + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card-img, +.card-img-bottom { + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-group > .card { + margin-bottom: 0.75rem; +} + +@media (min-width: 576px) { + .card-group { + display: flex; + flex-flow: row wrap; + } + + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0; + } + + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .card-group > .card:not(:last-child) .card-img-top, + .card-group > .card:not(:last-child) .card-header { + border-top-right-radius: 0; + } + + .card-group > .card:not(:last-child) .card-img-bottom, + .card-group > .card:not(:last-child) .card-footer { + border-bottom-right-radius: 0; + } + + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .card-group > .card:not(:first-child) .card-img-top, + .card-group > .card:not(:first-child) .card-header { + border-top-left-radius: 0; + } + + .card-group > .card:not(:first-child) .card-img-bottom, + .card-group > .card:not(:first-child) .card-footer { + border-bottom-left-radius: 0; + } +} + +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1055; + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0; + user-select: none; + + .close { + width: 50px; + height: 42px; + background-image: var(--gfx-closeBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 0; + right: 0; + + &:hover { + background-color: rgb(196, 43, 28); } + } +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; + color: var(--textColor); +} + +.modal.fade .modal-dialog { + transition: + transform 0.1s var(--appleEase), + opacity 0.1s var(--appleEase); + transform: scale(0.9); + opacity: 0; +} + +.fade { + transition: opacity 0.15s var(--appleEase); +} +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none; + } +} +.fade:not(.show) { + opacity: 0; +} + +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none; + } +} + +.modal.show .modal-dialog { + transform: none; + opacity: 1; +} + +.modal.modal-static .modal-dialog { + transform: scale(1.02); +} + +.modal-dialog-scrollable { + height: calc(100% - 1rem); +} + +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden; +} + +.modal-dialog-scrollable .modal-body { + overflow-y: auto; +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - 1rem); +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: var(--modalBackground); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: var(--panelRadius); + outline: 0; + box-shadow: var(--ciderShadow-Generic); + overflow: hidden; +} + +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1050; + width: 100vw; + height: 100vh; + background-color: #000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} + +.modal-header .btn-close { + padding: 0.5rem 0.5rem; + margin: -0.5rem -0.5rem -0.5rem auto; +} + +.modal-title { + line-height: 1.5; + margin: 0; + font-size: 1em; +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: 3rem 1rem 1rem 1rem; + //font-size: 0.9em +} + +.modal-footer { + display: flex; + flex-wrap: wrap; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; + padding: 0.75rem; + border-bottom-right-radius: calc(0.3rem - 1px); + border-bottom-left-radius: calc(0.3rem - 1px); +} + +.modal-footer > * { + margin: 0.25rem; +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + + .modal-dialog-scrollable { + height: calc(100% - 3.5rem); + } + + .modal-dialog-centered { + min-height: calc(100% - 3.5rem); + } + + .modal-sm { + max-width: 300px; + } +} + +@media (min-width: 992px) { + .modal-lg, + .modal-xl { + max-width: 800px; + } +} + +@media (min-width: 1200px) { + .modal-xl { + max-width: 1140px; + } } .modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; +} + +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0; +} + +.modal-fullscreen .modal-header { + border-radius: 0; +} + +.modal-fullscreen .modal-body { + overflow-y: auto; +} + +.modal-fullscreen .modal-footer { + border-radius: 0; +} + +@media (max-width: 575.98px) { + .modal-fullscreen-sm-down { width: 100vw; max-width: none; height: 100%; margin: 0; -} + } -.modal-fullscreen .modal-content { + .modal-fullscreen-sm-down .modal-content { height: 100%; border: 0; border-radius: 0; -} + } -.modal-fullscreen .modal-header { + .modal-fullscreen-sm-down .modal-header { border-radius: 0; -} + } -.modal-fullscreen .modal-body { + .modal-fullscreen-sm-down .modal-body { overflow-y: auto; -} + } -.modal-fullscreen .modal-footer { + .modal-fullscreen-sm-down .modal-footer { border-radius: 0; -} - -@media (max-width: 575.98px) { - .modal-fullscreen-sm-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } - - .modal-fullscreen-sm-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } - - .modal-fullscreen-sm-down .modal-header { - border-radius: 0; - } - - .modal-fullscreen-sm-down .modal-body { - overflow-y: auto; - } - - .modal-fullscreen-sm-down .modal-footer { - border-radius: 0; - } + } } @media (max-width: 767.98px) { - .modal-fullscreen-md-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } - .modal-fullscreen-md-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } - .modal-fullscreen-md-down .modal-header { - border-radius: 0; - } + .modal-fullscreen-md-down .modal-header { + border-radius: 0; + } - .modal-fullscreen-md-down .modal-body { - overflow-y: auto; - } + .modal-fullscreen-md-down .modal-body { + overflow-y: auto; + } - .modal-fullscreen-md-down .modal-footer { - border-radius: 0; - } + .modal-fullscreen-md-down .modal-footer { + border-radius: 0; + } } @media (max-width: 991.98px) { - .modal-fullscreen-lg-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } - .modal-fullscreen-lg-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } - .modal-fullscreen-lg-down .modal-header { - border-radius: 0; - } + .modal-fullscreen-lg-down .modal-header { + border-radius: 0; + } - .modal-fullscreen-lg-down .modal-body { - overflow-y: auto; - } + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto; + } - .modal-fullscreen-lg-down .modal-footer { - border-radius: 0; - } + .modal-fullscreen-lg-down .modal-footer { + border-radius: 0; + } } @media (max-width: 1199.98px) { - .modal-fullscreen-xl-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } - .modal-fullscreen-xl-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } - .modal-fullscreen-xl-down .modal-header { - border-radius: 0; - } + .modal-fullscreen-xl-down .modal-header { + border-radius: 0; + } - .modal-fullscreen-xl-down .modal-body { - overflow-y: auto; - } + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto; + } - .modal-fullscreen-xl-down .modal-footer { - border-radius: 0; - } + .modal-fullscreen-xl-down .modal-footer { + border-radius: 0; + } } @media (max-width: 1399.98px) { - .modal-fullscreen-xxl-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } - .modal-fullscreen-xxl-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } - .modal-fullscreen-xxl-down .modal-header { - border-radius: 0; - } + .modal-fullscreen-xxl-down .modal-header { + border-radius: 0; + } - .modal-fullscreen-xxl-down .modal-body { - overflow-y: auto; - } + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto; + } - .modal-fullscreen-xxl-down .modal-footer { - border-radius: 0; - } + .modal-fullscreen-xxl-down .modal-footer { + border-radius: 0; + } } - .btn { - display: inline-block; - font-weight: 400; - line-height: 1.5; - color: #212529; - text-align: center; - text-decoration: none; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - background-color: transparent; - border: 1px solid transparent; - padding: 0.375rem 0.75rem; - font-size: 1rem; - border-radius: 0.25rem; - font-family: inherit; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + display: inline-block; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + border-radius: 0.25rem; + font-family: inherit; + transition: + color 0.15s ease-in-out, + background-color 0.15s ease-in-out, + border-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out; + border: 1px solid rgba(100, 100, 100, 0.35); + border-top: 1px solid rgba(100, 100, 100, 0.5); + border-radius: 6px; + font-size: 14px; } @media (prefers-reduced-motion: reduce) { - .btn { - transition: none; - } + .btn { + transition: none; + } } .btn:hover { - color: #212529; + color: #212529; } -.btn-check:focus+.btn, +.btn-check:focus + .btn, .btn:focus { - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); } .btn:disabled, .btn.disabled, fieldset:disabled .btn { - pointer-events: none; - opacity: 0.65; + pointer-events: none; + opacity: 0.65; } .btn-primary { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; + color: #fff; + background-color: var(--keyColor-primary); + //border-color : #0d6efd; } .btn-primary:hover { - color: #fff; - background-color: #0b5ed7; - border-color: #0a58ca; + color: #fff; + //background-color: #0b5ed7; + //border-color : #0a58ca; } -.btn-check:focus+.btn-primary, +.btn-check:focus + .btn-primary, .btn-primary:focus { - color: #fff; - background-color: #0b5ed7; - border-color: #0a58ca; - box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); + color: #fff; + //background-color: #0b5ed7; + //border-color : #0a58ca; + //box-shadow : 0 0 0 0.25rem rgba(49, 132, 253, 0.5); } -.btn-check:checked+.btn-primary, -.btn-check:active+.btn-primary, +.btn-check:checked + .btn-primary, +.btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, -.show>.btn-primary.dropdown-toggle { - color: #fff; - background-color: #0a58ca; - border-color: #0a53be; +.show > .btn-primary.dropdown-toggle { + color: #fff; + //background-color: #0a58ca; + //border-color : #0a53be; } -.btn-check:checked+.btn-primary:focus, -.btn-check:active+.btn-primary:focus, +.btn-check:checked + .btn-primary:focus, +.btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, -.show>.btn-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); +.show > .btn-primary.dropdown-toggle:focus { + //box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); } .btn-primary:disabled, .btn-primary.disabled { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; } .btn-secondary { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; + color: #fff; + border-color: 1px solid rgba(100, 100, 100, 0.35); + background-color: rgba(100, 100, 100, 0.25); + border-top-color: 1px solid rgba(100, 100, 100, 0.5); } .btn-secondary:hover { - color: #fff; - background-color: #5c636a; - border-color: #565e64; + color: #fff; + // background-color: #5c636a; + // border-color : #565e64; } -.btn-check:focus+.btn-secondary, -.btn-secondary:focus { - color: #fff; - background-color: #5c636a; - border-color: #565e64; - box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); -} +// .btn-check:focus+.btn-secondary, +// .btn-secondary:focus { +// color : #fff; +// background-color: #5c636a; +// border-color : #565e64; +// box-shadow : 0 0 0 0.25rem rgba(130, 138, 145, 0.5); +// } -.btn-check:checked+.btn-secondary, -.btn-check:active+.btn-secondary, +.btn-check:checked + .btn-secondary, +.btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, -.show>.btn-secondary.dropdown-toggle { - color: #fff; - background-color: #565e64; - border-color: #51585e; +.show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #565e64; + border-color: #51585e; } -.btn-check:checked+.btn-secondary:focus, -.btn-check:active+.btn-secondary:focus, +.btn-check:checked + .btn-secondary:focus, +.btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, -.show>.btn-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); +.show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); } .btn-secondary:disabled, .btn-secondary.disabled { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; + color: #fff; + background-color: #6c757d; + border-color: #6c757d; } .btn-success { - color: #fff; - background-color: #198754; - border-color: #198754; + color: #fff; + background-color: #198754; + border-color: #198754; } .btn-success:hover { - color: #fff; - background-color: #157347; - border-color: #146c43; + color: #fff; + background-color: #157347; + border-color: #146c43; } -.btn-check:focus+.btn-success, +.btn-check:focus + .btn-success, .btn-success:focus { - color: #fff; - background-color: #157347; - border-color: #146c43; - box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); + color: #fff; + background-color: #157347; + border-color: #146c43; + box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); } -.btn-check:checked+.btn-success, -.btn-check:active+.btn-success, +.btn-check:checked + .btn-success, +.btn-check:active + .btn-success, .btn-success:active, .btn-success.active, -.show>.btn-success.dropdown-toggle { - color: #fff; - background-color: #146c43; - border-color: #13653f; +.show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #146c43; + border-color: #13653f; } -.btn-check:checked+.btn-success:focus, -.btn-check:active+.btn-success:focus, +.btn-check:checked + .btn-success:focus, +.btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, -.show>.btn-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); +.show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); } .btn-success:disabled, .btn-success.disabled { - color: #fff; - background-color: #198754; - border-color: #198754; + color: #fff; + background-color: #198754; + border-color: #198754; } .btn-info { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; } .btn-info:hover { - color: #000; - background-color: #31d2f2; - border-color: #25cff2; + color: #000; + background-color: #31d2f2; + border-color: #25cff2; } -.btn-check:focus+.btn-info, +.btn-check:focus + .btn-info, .btn-info:focus { - color: #000; - background-color: #31d2f2; - border-color: #25cff2; - box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); + color: #000; + background-color: #31d2f2; + border-color: #25cff2; + box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); } -.btn-check:checked+.btn-info, -.btn-check:active+.btn-info, +.btn-check:checked + .btn-info, +.btn-check:active + .btn-info, .btn-info:active, .btn-info.active, -.show>.btn-info.dropdown-toggle { - color: #000; - background-color: #3dd5f3; - border-color: #25cff2; +.show > .btn-info.dropdown-toggle { + color: #000; + background-color: #3dd5f3; + border-color: #25cff2; } -.btn-check:checked+.btn-info:focus, -.btn-check:active+.btn-info:focus, +.btn-check:checked + .btn-info:focus, +.btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, -.show>.btn-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); +.show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); } .btn-info:disabled, .btn-info.disabled { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; } .btn-warning { - color: #000; - background-color: #ffc107; - border-color: #ffc107; + color: #000; + background-color: #ffc107; + border-color: #ffc107; } .btn-warning:hover { - color: #000; - background-color: #ffca2c; - border-color: #ffc720; + color: #000; + background-color: #ffca2c; + border-color: #ffc720; } -.btn-check:focus+.btn-warning, +.btn-check:focus + .btn-warning, .btn-warning:focus { - color: #000; - background-color: #ffca2c; - border-color: #ffc720; - box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); + color: #000; + background-color: #ffca2c; + border-color: #ffc720; + box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); } -.btn-check:checked+.btn-warning, -.btn-check:active+.btn-warning, +.btn-check:checked + .btn-warning, +.btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, -.show>.btn-warning.dropdown-toggle { - color: #000; - background-color: #ffcd39; - border-color: #ffc720; +.show > .btn-warning.dropdown-toggle { + color: #000; + background-color: #ffcd39; + border-color: #ffc720; } -.btn-check:checked+.btn-warning:focus, -.btn-check:active+.btn-warning:focus, +.btn-check:checked + .btn-warning:focus, +.btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, -.show>.btn-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); +.show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); } .btn-warning:disabled, .btn-warning.disabled { - color: #000; - background-color: #ffc107; - border-color: #ffc107; + color: #000; + background-color: #ffc107; + border-color: #ffc107; } .btn-danger { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; + color: #fff; + background-color: #dc3545; + border-color: #dc3545; } .btn-danger:hover { - color: #fff; - background-color: #bb2d3b; - border-color: #b02a37; + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; } -.btn-check:focus+.btn-danger, +.btn-check:focus + .btn-danger, .btn-danger:focus { - color: #fff; - background-color: #bb2d3b; - border-color: #b02a37; - box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; + box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); } -.btn-check:checked+.btn-danger, -.btn-check:active+.btn-danger, +.btn-check:checked + .btn-danger, +.btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, -.show>.btn-danger.dropdown-toggle { - color: #fff; - background-color: #b02a37; - border-color: #a52834; +.show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #b02a37; + border-color: #a52834; } -.btn-check:checked+.btn-danger:focus, -.btn-check:active+.btn-danger:focus, +.btn-check:checked + .btn-danger:focus, +.btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, -.show>.btn-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); +.show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); } .btn-danger:disabled, .btn-danger.disabled { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; + color: #fff; + background-color: #dc3545; + border-color: #dc3545; } .btn-light { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; } .btn-light:hover { - color: #000; - background-color: #f9fafb; - border-color: #f9fafb; + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; } -.btn-check:focus+.btn-light, +.btn-check:focus + .btn-light, .btn-light:focus { - color: #000; - background-color: #f9fafb; - border-color: #f9fafb; - box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; + box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); } -.btn-check:checked+.btn-light, -.btn-check:active+.btn-light, +.btn-check:checked + .btn-light, +.btn-check:active + .btn-light, .btn-light:active, .btn-light.active, -.show>.btn-light.dropdown-toggle { - color: #000; - background-color: #f9fafb; - border-color: #f9fafb; +.show > .btn-light.dropdown-toggle { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; } -.btn-check:checked+.btn-light:focus, -.btn-check:active+.btn-light:focus, +.btn-check:checked + .btn-light:focus, +.btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, -.show>.btn-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); +.show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); } .btn-light:disabled, .btn-light.disabled { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; } .btn-dark { - color: #fff; - background-color: #212529; - border-color: #212529; + color: #fff; + background-color: #212529; + border-color: #212529; } .btn-dark:hover { - color: #fff; - background-color: #1c1f23; - border-color: #1a1e21; + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; } -.btn-check:focus+.btn-dark, +.btn-check:focus + .btn-dark, .btn-dark:focus { - color: #fff; - background-color: #1c1f23; - border-color: #1a1e21; - box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); } -.btn-check:checked+.btn-dark, -.btn-check:active+.btn-dark, +.btn-check:checked + .btn-dark, +.btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, -.show>.btn-dark.dropdown-toggle { - color: #fff; - background-color: #1a1e21; - border-color: #191c1f; +.show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1a1e21; + border-color: #191c1f; } -.btn-check:checked+.btn-dark:focus, -.btn-check:active+.btn-dark:focus, +.btn-check:checked + .btn-dark:focus, +.btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, -.show>.btn-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); +.show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); } .btn-dark:disabled, .btn-dark.disabled { - color: #fff; - background-color: #212529; - border-color: #212529; + color: #fff; + background-color: #212529; + border-color: #212529; } .btn-outline-primary { - color: #0d6efd; - border-color: #0d6efd; + color: #0d6efd; + border-color: #0d6efd; } .btn-outline-primary:hover { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; } -.btn-check:focus+.btn-outline-primary, +.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); } -.btn-check:checked+.btn-outline-primary, -.btn-check:active+.btn-outline-primary, +.btn-check:checked + .btn-outline-primary, +.btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; } -.btn-check:checked+.btn-outline-primary:focus, -.btn-check:active+.btn-outline-primary:focus, +.btn-check:checked + .btn-outline-primary:focus, +.btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); } .btn-outline-primary:disabled, .btn-outline-primary.disabled { - color: #0d6efd; - background-color: transparent; + color: #0d6efd; + background-color: transparent; } .btn-outline-secondary { - color: #6c757d; - border-color: #6c757d; + color: #6c757d; + border-color: #6c757d; } .btn-outline-secondary:hover { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; + color: #fff; + background-color: #6c757d; + border-color: #6c757d; } -.btn-check:focus+.btn-outline-secondary, +.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { - box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); } -.btn-check:checked+.btn-outline-secondary, -.btn-check:active+.btn-outline-secondary, +.btn-check:checked + .btn-outline-secondary, +.btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; + color: #fff; + background-color: #6c757d; + border-color: #6c757d; } -.btn-check:checked+.btn-outline-secondary:focus, -.btn-check:active+.btn-outline-secondary:focus, +.btn-check:checked + .btn-outline-secondary:focus, +.btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); } .btn-outline-secondary:disabled, .btn-outline-secondary.disabled { - color: #6c757d; - background-color: transparent; + color: #6c757d; + background-color: transparent; } .btn-outline-success { - color: #198754; - border-color: #198754; + color: #198754; + border-color: #198754; } .btn-outline-success:hover { - color: #fff; - background-color: #198754; - border-color: #198754; + color: #fff; + background-color: #198754; + border-color: #198754; } -.btn-check:focus+.btn-outline-success, +.btn-check:focus + .btn-outline-success, .btn-outline-success:focus { - box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); } -.btn-check:checked+.btn-outline-success, -.btn-check:active+.btn-outline-success, +.btn-check:checked + .btn-outline-success, +.btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { - color: #fff; - background-color: #198754; - border-color: #198754; + color: #fff; + background-color: #198754; + border-color: #198754; } -.btn-check:checked+.btn-outline-success:focus, -.btn-check:active+.btn-outline-success:focus, +.btn-check:checked + .btn-outline-success:focus, +.btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); } .btn-outline-success:disabled, .btn-outline-success.disabled { - color: #198754; - background-color: transparent; + color: #198754; + background-color: transparent; } .btn-outline-info { - color: #0dcaf0; - border-color: #0dcaf0; + color: #0dcaf0; + border-color: #0dcaf0; } .btn-outline-info:hover { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; } -.btn-check:focus+.btn-outline-info, +.btn-check:focus + .btn-outline-info, .btn-outline-info:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); } -.btn-check:checked+.btn-outline-info, -.btn-check:active+.btn-outline-info, +.btn-check:checked + .btn-outline-info, +.btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; } -.btn-check:checked+.btn-outline-info:focus, -.btn-check:active+.btn-outline-info:focus, +.btn-check:checked + .btn-outline-info:focus, +.btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); } .btn-outline-info:disabled, .btn-outline-info.disabled { - color: #0dcaf0; - background-color: transparent; + color: #0dcaf0; + background-color: transparent; } .btn-outline-warning { - color: #ffc107; - border-color: #ffc107; + color: #ffc107; + border-color: #ffc107; } .btn-outline-warning:hover { - color: #000; - background-color: #ffc107; - border-color: #ffc107; + color: #000; + background-color: #ffc107; + border-color: #ffc107; } -.btn-check:focus+.btn-outline-warning, +.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); } -.btn-check:checked+.btn-outline-warning, -.btn-check:active+.btn-outline-warning, +.btn-check:checked + .btn-outline-warning, +.btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { - color: #000; - background-color: #ffc107; - border-color: #ffc107; + color: #000; + background-color: #ffc107; + border-color: #ffc107; } -.btn-check:checked+.btn-outline-warning:focus, -.btn-check:active+.btn-outline-warning:focus, +.btn-check:checked + .btn-outline-warning:focus, +.btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); } .btn-outline-warning:disabled, .btn-outline-warning.disabled { - color: #ffc107; - background-color: transparent; + color: #ffc107; + background-color: transparent; } .btn-outline-danger { - color: #dc3545; - border-color: #dc3545; + color: #dc3545; + border-color: #dc3545; } .btn-outline-danger:hover { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; + color: #fff; + background-color: #dc3545; + border-color: #dc3545; } -.btn-check:focus+.btn-outline-danger, +.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { - box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); } -.btn-check:checked+.btn-outline-danger, -.btn-check:active+.btn-outline-danger, +.btn-check:checked + .btn-outline-danger, +.btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; + color: #fff; + background-color: #dc3545; + border-color: #dc3545; } -.btn-check:checked+.btn-outline-danger:focus, -.btn-check:active+.btn-outline-danger:focus, +.btn-check:checked + .btn-outline-danger:focus, +.btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); } .btn-outline-danger:disabled, .btn-outline-danger.disabled { - color: #dc3545; - background-color: transparent; + color: #dc3545; + background-color: transparent; } .btn-outline-light { - color: #f8f9fa; - border-color: #f8f9fa; + color: #f8f9fa; + border-color: #f8f9fa; } .btn-outline-light:hover { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; } -.btn-check:focus+.btn-outline-light, +.btn-check:focus + .btn-outline-light, .btn-outline-light:focus { - box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); } -.btn-check:checked+.btn-outline-light, -.btn-check:active+.btn-outline-light, +.btn-check:checked + .btn-outline-light, +.btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; } -.btn-check:checked+.btn-outline-light:focus, -.btn-check:active+.btn-outline-light:focus, +.btn-check:checked + .btn-outline-light:focus, +.btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); } .btn-outline-light:disabled, .btn-outline-light.disabled { - color: #f8f9fa; - background-color: transparent; + color: #f8f9fa; + background-color: transparent; } .btn-outline-dark { - color: #212529; - border-color: #212529; + color: #212529; + border-color: #212529; } .btn-outline-dark:hover { - color: #fff; - background-color: #212529; - border-color: #212529; + color: #fff; + background-color: #212529; + border-color: #212529; } -.btn-check:focus+.btn-outline-dark, +.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { - box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); } -.btn-check:checked+.btn-outline-dark, -.btn-check:active+.btn-outline-dark, +.btn-check:checked + .btn-outline-dark, +.btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { - color: #fff; - background-color: #212529; - border-color: #212529; + color: #fff; + background-color: #212529; + border-color: #212529; } -.btn-check:checked+.btn-outline-dark:focus, -.btn-check:active+.btn-outline-dark:focus, +.btn-check:checked + .btn-outline-dark:focus, +.btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); } .btn-outline-dark:disabled, .btn-outline-dark.disabled { - color: #212529; - background-color: transparent; + color: #212529; + background-color: transparent; } .btn-link { - font-weight: 400; - color: #0d6efd; - text-decoration: underline; + font-weight: 400; + color: #0d6efd; + text-decoration: underline; } .btn-link:hover { - color: #0a58ca; + color: #0a58ca; } .btn-link:disabled, .btn-link.disabled { - color: #6c757d; + color: #6c757d; } .btn-lg, -.btn-group-lg>.btn { - padding: 0.5rem 1rem; - font-size: 1.25rem; - border-radius: 0.3rem; +.btn-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.3rem; } .btn-sm, -.btn-group-sm>.btn { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; +.btn-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; } .form-control { - width:100%; -} \ No newline at end of file + width: 100%; +} + +// Button Group + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + flex: 1 1 auto; +} +.btn-group > .btn-check:checked + .btn, +.btn-group > .btn-check:focus + .btn, +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn-check:checked + .btn, +.btn-group-vertical > .btn-check:focus + .btn, +.btn-group-vertical > .btn:hover, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} + +.btn-group > .btn:not(:first-child), +.btn-group > .btn-group:not(:first-child) { + margin-left: -1px; +} +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:nth-child(n + 3), +.btn-group > :not(.btn-check) + .btn, +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} +.dropdown-toggle-split::after, +.dropup .dropdown-toggle-split::after, +.dropend .dropdown-toggle-split::after { + margin-left: 0; +} +.dropstart .dropdown-toggle-split::before { + margin-right: 0; +} + +.btn-sm + .dropdown-toggle-split, +.btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, +.btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + width: 100%; +} +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) { + margin-top: -1px; +} +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn ~ .btn, +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +// Table +.table { + --bs-table-bg: transparent; + --bs-table-accent-bg: transparent; + --bs-table-striped-color: #212529; + --bs-table-striped-bg: rgba(0, 0, 0, 0.05); + --bs-table-active-color: #212529; + --bs-table-active-bg: rgba(0, 0, 0, 0.1); + --bs-table-hover-color: #212529; + --bs-table-hover-bg: rgba(0, 0, 0, 0.075); + width: 100%; + margin-bottom: 1rem; + color: #212529; + vertical-align: top; + border-color: #dee2e6; +} +.table > :not(caption) > * > * { + padding: 0.5rem 0.5rem; + background-color: var(--bs-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg); +} +.table > tbody { + vertical-align: inherit; +} +.table > thead { + vertical-align: bottom; +} +.table > :not(:first-child) { + border-top: 2px solid currentColor; +} + +.caption-top { + caption-side: top; +} + +.table-sm > :not(caption) > * > * { + padding: 0.25rem 0.25rem; +} + +.table-bordered > :not(caption) > * { + border-width: 1px 0; +} +.table-bordered > :not(caption) > * > * { + border-width: 0 1px; +} + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0; +} +.table-borderless > :not(:first-child) { + border-top-width: 0; +} + +.table-striped > tbody > tr:nth-of-type(odd) > * { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color); +} + +.table-active { + --bs-table-accent-bg: var(--bs-table-active-bg); + color: var(--bs-table-active-color); +} + +.table-hover > tbody > tr:hover > * { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--bs-table-hover-color); +} + +.table-primary { + --bs-table-bg: #cfe2ff; + --bs-table-striped-bg: #c5d7f2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bacbe6; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfd1ec; + --bs-table-hover-color: #000; + color: #000; + border-color: #bacbe6; +} + +.table-secondary { + --bs-table-bg: #e2e3e5; + --bs-table-striped-bg: #d7d8da; + --bs-table-striped-color: #000; + --bs-table-active-bg: #cbccce; + --bs-table-active-color: #000; + --bs-table-hover-bg: #d1d2d4; + --bs-table-hover-color: #000; + color: #000; + border-color: #cbccce; +} + +.table-success { + --bs-table-bg: #d1e7dd; + --bs-table-striped-bg: #c7dbd2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bcd0c7; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c1d6cc; + --bs-table-hover-color: #000; + color: #000; + border-color: #bcd0c7; +} + +.table-info { + --bs-table-bg: #cff4fc; + --bs-table-striped-bg: #c5e8ef; + --bs-table-striped-color: #000; + --bs-table-active-bg: #badce3; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfe2e9; + --bs-table-hover-color: #000; + color: #000; + border-color: #badce3; +} + +.table-warning { + --bs-table-bg: #fff3cd; + --bs-table-striped-bg: #f2e7c3; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e6dbb9; + --bs-table-active-color: #000; + --bs-table-hover-bg: #ece1be; + --bs-table-hover-color: #000; + color: #000; + border-color: #e6dbb9; +} + +.table-danger { + --bs-table-bg: #f8d7da; + --bs-table-striped-bg: #eccccf; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfc2c4; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5c7ca; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfc2c4; +} + +.table-light { + --bs-table-bg: #f8f9fa; + --bs-table-striped-bg: #ecedee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfe0e1; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5e6e7; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfe0e1; +} + +.table-dark { + --bs-table-bg: #212529; + --bs-table-striped-bg: #2c3034; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #373b3e; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #323539; + --bs-table-hover-color: #fff; + color: #fff; + border-color: #373b3e; +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} + +// Tabs + +.nav { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; + text-decoration: none; +} + +.nav-link:hover, +.nav-link:focus { + text-decoration: none; +} + +.nav-link.disabled { + color: #6c757d; + pointer-events: none; + cursor: default; +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} +.nav-tabs .nav-link { + margin-bottom: -1px; + background: none; + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.nav-tabs .nav-link:hover, +.nav-tabs .nav-link:focus { + border-color: #e9ecef #e9ecef #dee2e6; + isolation: isolate; +} +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills .nav-link { + background-color: transparent; + border: 0; + border-radius: 6px; + color: #eee; + -webkit-user-drag: none; + font-weight: 500; + margin: 0px 4px; + &:hover { + // transition: transform .35s var(--appleEase), background-color 0s var(--appleEase); + background-color: var(--hover); + } +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: var(--selected); + // outline:2px solid var(--keyColor); +} + +.nav-fill > .nav-link, +.nav-fill .nav-item { + flex: 1 1 auto; + text-align: center; +} + +.nav-justified > .nav-link, +.nav-justified .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center; +} + +.nav-fill .nav-item .nav-link, +.nav-justified .nav-item .nav-link { + width: 100%; +} + +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} + +/*! + * Bootstrap Grid v5.1.1 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +:root { + --bs-blue: #0d6efd; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #dc3545; + --bs-orange: #fd7e14; + --bs-yellow: #ffc107; + --bs-green: #198754; + --bs-teal: #20c997; + --bs-cyan: #0dcaf0; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #e9ecef; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #6c757d; + --bs-gray-700: #495057; + --bs-gray-800: #343a40; + --bs-gray-900: #212529; + --bs-primary: #0d6efd; + --bs-secondary: #6c757d; + --bs-success: #198754; + --bs-info: #0dcaf0; + --bs-warning: #ffc107; + --bs-danger: #dc3545; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-primary-rgb: 13, 110, 253; + --bs-secondary-rgb: 108, 117, 125; + --bs-success-rgb: 25, 135, 84; + --bs-info-rgb: 13, 202, 240; + --bs-warning-rgb: 255, 193, 7; + --bs-danger-rgb: 220, 53, 69; + --bs-light-rgb: 248, 249, 250; + --bs-dark-rgb: 33, 37, 41; + --bs-white-rgb: 255, 255, 255; + --bs-black-rgb: 0, 0, 0; + --bs-body-color-rgb: 33, 37, 41; + --bs-body-bg-rgb: 255, 255, 255; + --bs-font-sans-serif: inherit; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: inherit; + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #212529; + --bs-body-bg: #fff; +} + +.container, +.container-fluid, +.container-xxl, +.container-xl, +.container-lg, +.container-md, +.container-sm { + width: 100%; + padding-right: var(--bs-gutter-x, 0.75rem); + padding-left: var(--bs-gutter-x, 0.75rem); + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container-sm, + .container { + max-width: 540px; + } +} + +@media (min-width: 768px) { + .container-md, + .container-sm, + .container { + max-width: 720px; + } +} + +@media (min-width: 992px) { + .container-lg, + .container-md, + .container-sm, + .container { + max-width: 960px; + } +} + +@media (min-width: 1200px) { + .container-xl, + .container-lg, + .container-md, + .container-sm, + .container { + max-width: 1140px; + } +} + +@media (min-width: 1400px) { + .container-xxl, + .container-xl, + .container-lg, + .container-md, + .container-sm, + .container { + max-width: 1320px; + } +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +@media only screen and (min-width: 1133px) and (max-width: 1233px) { + .about-page { + .row .col-auto { + display: none !important; + } + } +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-left: 8.33333333%; +} + +.offset-2 { + margin-left: 16.66666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.33333333%; +} + +.offset-5 { + margin-left: 41.66666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.33333333%; +} + +.offset-8 { + margin-left: 66.66666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.33333333%; +} + +.offset-11 { + margin-left: 91.66666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-sm-auto { + flex: 0 0 auto; + width: auto; + } + + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-sm-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-sm-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-sm-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-sm-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-sm-0 { + margin-left: 0; + } + + .offset-sm-1 { + margin-left: 8.33333333%; + } + + .offset-sm-2 { + margin-left: 16.66666667%; + } + + .offset-sm-3 { + margin-left: 25%; + } + + .offset-sm-4 { + margin-left: 33.33333333%; + } + + .offset-sm-5 { + margin-left: 41.66666667%; + } + + .offset-sm-6 { + margin-left: 50%; + } + + .offset-sm-7 { + margin-left: 58.33333333%; + } + + .offset-sm-8 { + margin-left: 66.66666667%; + } + + .offset-sm-9 { + margin-left: 75%; + } + + .offset-sm-10 { + margin-left: 83.33333333%; + } + + .offset-sm-11 { + margin-left: 91.66666667%; + } + + .g-sm-0, + .gx-sm-0 { + --bs-gutter-x: 0; + } + + .g-sm-0, + .gy-sm-0 { + --bs-gutter-y: 0; + } + + .g-sm-1, + .gx-sm-1 { + --bs-gutter-x: 0.25rem; + } + + .g-sm-1, + .gy-sm-1 { + --bs-gutter-y: 0.25rem; + } + + .g-sm-2, + .gx-sm-2 { + --bs-gutter-x: 0.5rem; + } + + .g-sm-2, + .gy-sm-2 { + --bs-gutter-y: 0.5rem; + } + + .g-sm-3, + .gx-sm-3 { + --bs-gutter-x: 1rem; + } + + .g-sm-3, + .gy-sm-3 { + --bs-gutter-y: 1rem; + } + + .g-sm-4, + .gx-sm-4 { + --bs-gutter-x: 1.5rem; + } + + .g-sm-4, + .gy-sm-4 { + --bs-gutter-y: 1.5rem; + } + + .g-sm-5, + .gx-sm-5 { + --bs-gutter-x: 3rem; + } + + .g-sm-5, + .gy-sm-5 { + --bs-gutter-y: 3rem; + } +} + +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-md-auto { + flex: 0 0 auto; + width: auto; + } + + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-md-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-md-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-md-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-md-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-md-0 { + margin-left: 0; + } + + .offset-md-1 { + margin-left: 8.33333333%; + } + + .offset-md-2 { + margin-left: 16.66666667%; + } + + .offset-md-3 { + margin-left: 25%; + } + + .offset-md-4 { + margin-left: 33.33333333%; + } + + .offset-md-5 { + margin-left: 41.66666667%; + } + + .offset-md-6 { + margin-left: 50%; + } + + .offset-md-7 { + margin-left: 58.33333333%; + } + + .offset-md-8 { + margin-left: 66.66666667%; + } + + .offset-md-9 { + margin-left: 75%; + } + + .offset-md-10 { + margin-left: 83.33333333%; + } + + .offset-md-11 { + margin-left: 91.66666667%; + } + + .g-md-0, + .gx-md-0 { + --bs-gutter-x: 0; + } + + .g-md-0, + .gy-md-0 { + --bs-gutter-y: 0; + } + + .g-md-1, + .gx-md-1 { + --bs-gutter-x: 0.25rem; + } + + .g-md-1, + .gy-md-1 { + --bs-gutter-y: 0.25rem; + } + + .g-md-2, + .gx-md-2 { + --bs-gutter-x: 0.5rem; + } + + .g-md-2, + .gy-md-2 { + --bs-gutter-y: 0.5rem; + } + + .g-md-3, + .gx-md-3 { + --bs-gutter-x: 1rem; + } + + .g-md-3, + .gy-md-3 { + --bs-gutter-y: 1rem; + } + + .g-md-4, + .gx-md-4 { + --bs-gutter-x: 1.5rem; + } + + .g-md-4, + .gy-md-4 { + --bs-gutter-y: 1.5rem; + } + + .g-md-5, + .gx-md-5 { + --bs-gutter-x: 3rem; + } + + .g-md-5, + .gy-md-5 { + --bs-gutter-y: 3rem; + } +} + +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-lg-auto { + flex: 0 0 auto; + width: auto; + } + + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-lg-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-lg-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-lg-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-lg-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-lg-0 { + margin-left: 0; + } + + .offset-lg-1 { + margin-left: 8.33333333%; + } + + .offset-lg-2 { + margin-left: 16.66666667%; + } + + .offset-lg-3 { + margin-left: 25%; + } + + .offset-lg-4 { + margin-left: 33.33333333%; + } + + .offset-lg-5 { + margin-left: 41.66666667%; + } + + .offset-lg-6 { + margin-left: 50%; + } + + .offset-lg-7 { + margin-left: 58.33333333%; + } + + .offset-lg-8 { + margin-left: 66.66666667%; + } + + .offset-lg-9 { + margin-left: 75%; + } + + .offset-lg-10 { + margin-left: 83.33333333%; + } + + .offset-lg-11 { + margin-left: 91.66666667%; + } + + .g-lg-0, + .gx-lg-0 { + --bs-gutter-x: 0; + } + + .g-lg-0, + .gy-lg-0 { + --bs-gutter-y: 0; + } + + .g-lg-1, + .gx-lg-1 { + --bs-gutter-x: 0.25rem; + } + + .g-lg-1, + .gy-lg-1 { + --bs-gutter-y: 0.25rem; + } + + .g-lg-2, + .gx-lg-2 { + --bs-gutter-x: 0.5rem; + } + + .g-lg-2, + .gy-lg-2 { + --bs-gutter-y: 0.5rem; + } + + .g-lg-3, + .gx-lg-3 { + --bs-gutter-x: 1rem; + } + + .g-lg-3, + .gy-lg-3 { + --bs-gutter-y: 1rem; + } + + .g-lg-4, + .gx-lg-4 { + --bs-gutter-x: 1.5rem; + } + + .g-lg-4, + .gy-lg-4 { + --bs-gutter-y: 1.5rem; + } + + .g-lg-5, + .gx-lg-5 { + --bs-gutter-x: 3rem; + } + + .g-lg-5, + .gy-lg-5 { + --bs-gutter-y: 3rem; + } +} + +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xl-auto { + flex: 0 0 auto; + width: auto; + } + + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-xl-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-xl-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-xl-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-xl-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-xl-0 { + margin-left: 0; + } + + .offset-xl-1 { + margin-left: 8.33333333%; + } + + .offset-xl-2 { + margin-left: 16.66666667%; + } + + .offset-xl-3 { + margin-left: 25%; + } + + .offset-xl-4 { + margin-left: 33.33333333%; + } + + .offset-xl-5 { + margin-left: 41.66666667%; + } + + .offset-xl-6 { + margin-left: 50%; + } + + .offset-xl-7 { + margin-left: 58.33333333%; + } + + .offset-xl-8 { + margin-left: 66.66666667%; + } + + .offset-xl-9 { + margin-left: 75%; + } + + .offset-xl-10 { + margin-left: 83.33333333%; + } + + .offset-xl-11 { + margin-left: 91.66666667%; + } + + .g-xl-0, + .gx-xl-0 { + --bs-gutter-x: 0; + } + + .g-xl-0, + .gy-xl-0 { + --bs-gutter-y: 0; + } + + .g-xl-1, + .gx-xl-1 { + --bs-gutter-x: 0.25rem; + } + + .g-xl-1, + .gy-xl-1 { + --bs-gutter-y: 0.25rem; + } + + .g-xl-2, + .gx-xl-2 { + --bs-gutter-x: 0.5rem; + } + + .g-xl-2, + .gy-xl-2 { + --bs-gutter-y: 0.5rem; + } + + .g-xl-3, + .gx-xl-3 { + --bs-gutter-x: 1rem; + } + + .g-xl-3, + .gy-xl-3 { + --bs-gutter-y: 1rem; + } + + .g-xl-4, + .gx-xl-4 { + --bs-gutter-x: 1.5rem; + } + + .g-xl-4, + .gy-xl-4 { + --bs-gutter-y: 1.5rem; + } + + .g-xl-5, + .gx-xl-5 { + --bs-gutter-x: 3rem; + } + + .g-xl-5, + .gy-xl-5 { + --bs-gutter-y: 3rem; + } +} + +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xxl-auto { + flex: 0 0 auto; + width: auto; + } + + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-xxl-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-xxl-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-xxl-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-xxl-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-xxl-0 { + margin-left: 0; + } + + .offset-xxl-1 { + margin-left: 8.33333333%; + } + + .offset-xxl-2 { + margin-left: 16.66666667%; + } + + .offset-xxl-3 { + margin-left: 25%; + } + + .offset-xxl-4 { + margin-left: 33.33333333%; + } + + .offset-xxl-5 { + margin-left: 41.66666667%; + } + + .offset-xxl-6 { + margin-left: 50%; + } + + .offset-xxl-7 { + margin-left: 58.33333333%; + } + + .offset-xxl-8 { + margin-left: 66.66666667%; + } + + .offset-xxl-9 { + margin-left: 75%; + } + + .offset-xxl-10 { + margin-left: 83.33333333%; + } + + .offset-xxl-11 { + margin-left: 91.66666667%; + } + + .g-xxl-0, + .gx-xxl-0 { + --bs-gutter-x: 0; + } + + .g-xxl-0, + .gy-xxl-0 { + --bs-gutter-y: 0; + } + + .g-xxl-1, + .gx-xxl-1 { + --bs-gutter-x: 0.25rem; + } + + .g-xxl-1, + .gy-xxl-1 { + --bs-gutter-y: 0.25rem; + } + + .g-xxl-2, + .gx-xxl-2 { + --bs-gutter-x: 0.5rem; + } + + .g-xxl-2, + .gy-xxl-2 { + --bs-gutter-y: 0.5rem; + } + + .g-xxl-3, + .gx-xxl-3 { + --bs-gutter-x: 1rem; + } + + .g-xxl-3, + .gy-xxl-3 { + --bs-gutter-y: 1rem; + } + + .g-xxl-4, + .gx-xxl-4 { + --bs-gutter-x: 1.5rem; + } + + .g-xxl-4, + .gy-xxl-4 { + --bs-gutter-y: 1.5rem; + } + + .g-xxl-5, + .gx-xxl-5 { + --bs-gutter-x: 3rem; + } + + .g-xxl-5, + .gy-xxl-5 { + --bs-gutter-y: 3rem; + } +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.mx-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; +} + +.mx-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-right: 0 !important; +} + +.me-1 { + margin-right: 0.25rem !important; +} + +.me-2 { + margin-right: 0.5rem !important; +} + +.me-3 { + margin-right: 1rem !important; +} + +.me-4 { + margin-right: 1.5rem !important; +} + +.me-5 { + margin-right: 3rem !important; +} + +.me-auto { + margin-right: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-left: 0 !important; +} + +.ms-1 { + margin-left: 0.25rem !important; +} + +.ms-2 { + margin-left: 0.5rem !important; +} + +.ms-3 { + margin-left: 1rem !important; +} + +.ms-4 { + margin-left: 1.5rem !important; +} + +.ms-5 { + margin-left: 3rem !important; +} + +.ms-auto { + margin-left: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.px-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; +} + +.px-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-right: 0 !important; +} + +.pe-1 { + padding-right: 0.25rem !important; +} + +.pe-2 { + padding-right: 0.5rem !important; +} + +.pe-3 { + padding-right: 1rem !important; +} + +.pe-4 { + padding-right: 1.5rem !important; +} + +.pe-5 { + padding-right: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-left: 0 !important; +} + +.ps-1 { + padding-left: 0.25rem !important; +} + +.ps-2 { + padding-left: 0.5rem !important; +} + +.ps-3 { + padding-left: 1rem !important; +} + +.ps-4 { + padding-left: 1.5rem !important; +} + +.ps-5 { + padding-left: 3rem !important; +} + +@media (min-width: 576px) { + .d-sm-inline { + display: inline !important; + } + + .d-sm-inline-block { + display: inline-block !important; + } + + .d-sm-block { + display: block !important; + } + + .d-sm-grid { + display: grid !important; + } + + .d-sm-table { + display: table !important; + } + + .d-sm-table-row { + display: table-row !important; + } + + .d-sm-table-cell { + display: table-cell !important; + } + + .d-sm-flex { + display: flex !important; + } + + .d-sm-inline-flex { + display: inline-flex !important; + } + + .d-sm-none { + display: none !important; + } + + .flex-sm-fill { + flex: 1 1 auto !important; + } + + .flex-sm-row { + flex-direction: row !important; + } + + .flex-sm-column { + flex-direction: column !important; + } + + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-sm-wrap { + flex-wrap: wrap !important; + } + + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-content-sm-start { + justify-content: flex-start !important; + } + + .justify-content-sm-end { + justify-content: flex-end !important; + } + + .justify-content-sm-center { + justify-content: center !important; + } + + .justify-content-sm-between { + justify-content: space-between !important; + } + + .justify-content-sm-around { + justify-content: space-around !important; + } + + .justify-content-sm-evenly { + justify-content: space-evenly !important; + } + + .align-items-sm-start { + align-items: flex-start !important; + } + + .align-items-sm-end { + align-items: flex-end !important; + } + + .align-items-sm-center { + align-items: center !important; + } + + .align-items-sm-baseline { + align-items: baseline !important; + } + + .align-items-sm-stretch { + align-items: stretch !important; + } + + .align-content-sm-start { + align-content: flex-start !important; + } + + .align-content-sm-end { + align-content: flex-end !important; + } + + .align-content-sm-center { + align-content: center !important; + } + + .align-content-sm-between { + align-content: space-between !important; + } + + .align-content-sm-around { + align-content: space-around !important; + } + + .align-content-sm-stretch { + align-content: stretch !important; + } + + .align-self-sm-auto { + align-self: auto !important; + } + + .align-self-sm-start { + align-self: flex-start !important; + } + + .align-self-sm-end { + align-self: flex-end !important; + } + + .align-self-sm-center { + align-self: center !important; + } + + .align-self-sm-baseline { + align-self: baseline !important; + } + + .align-self-sm-stretch { + align-self: stretch !important; + } + + .order-sm-first { + order: -1 !important; + } + + .order-sm-0 { + order: 0 !important; + } + + .order-sm-1 { + order: 1 !important; + } + + .order-sm-2 { + order: 2 !important; + } + + .order-sm-3 { + order: 3 !important; + } + + .order-sm-4 { + order: 4 !important; + } + + .order-sm-5 { + order: 5 !important; + } + + .order-sm-last { + order: 6 !important; + } + + .m-sm-0 { + margin: 0 !important; + } + + .m-sm-1 { + margin: 0.25rem !important; + } + + .m-sm-2 { + margin: 0.5rem !important; + } + + .m-sm-3 { + margin: 1rem !important; + } + + .m-sm-4 { + margin: 1.5rem !important; + } + + .m-sm-5 { + margin: 3rem !important; + } + + .m-sm-auto { + margin: auto !important; + } + + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-sm-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-sm-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-sm-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-sm-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-sm-0 { + margin-top: 0 !important; + } + + .mt-sm-1 { + margin-top: 0.25rem !important; + } + + .mt-sm-2 { + margin-top: 0.5rem !important; + } + + .mt-sm-3 { + margin-top: 1rem !important; + } + + .mt-sm-4 { + margin-top: 1.5rem !important; + } + + .mt-sm-5 { + margin-top: 3rem !important; + } + + .mt-sm-auto { + margin-top: auto !important; + } + + .me-sm-0 { + margin-right: 0 !important; + } + + .me-sm-1 { + margin-right: 0.25rem !important; + } + + .me-sm-2 { + margin-right: 0.5rem !important; + } + + .me-sm-3 { + margin-right: 1rem !important; + } + + .me-sm-4 { + margin-right: 1.5rem !important; + } + + .me-sm-5 { + margin-right: 3rem !important; + } + + .me-sm-auto { + margin-right: auto !important; + } + + .mb-sm-0 { + margin-bottom: 0 !important; + } + + .mb-sm-1 { + margin-bottom: 0.25rem !important; + } + + .mb-sm-2 { + margin-bottom: 0.5rem !important; + } + + .mb-sm-3 { + margin-bottom: 1rem !important; + } + + .mb-sm-4 { + margin-bottom: 1.5rem !important; + } + + .mb-sm-5 { + margin-bottom: 3rem !important; + } + + .mb-sm-auto { + margin-bottom: auto !important; + } + + .ms-sm-0 { + margin-left: 0 !important; + } + + .ms-sm-1 { + margin-left: 0.25rem !important; + } + + .ms-sm-2 { + margin-left: 0.5rem !important; + } + + .ms-sm-3 { + margin-left: 1rem !important; + } + + .ms-sm-4 { + margin-left: 1.5rem !important; + } + + .ms-sm-5 { + margin-left: 3rem !important; + } + + .ms-sm-auto { + margin-left: auto !important; + } + + .p-sm-0 { + padding: 0 !important; + } + + .p-sm-1 { + padding: 0.25rem !important; + } + + .p-sm-2 { + padding: 0.5rem !important; + } + + .p-sm-3 { + padding: 1rem !important; + } + + .p-sm-4 { + padding: 1.5rem !important; + } + + .p-sm-5 { + padding: 3rem !important; + } + + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-sm-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-sm-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-sm-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-sm-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-sm-0 { + padding-top: 0 !important; + } + + .pt-sm-1 { + padding-top: 0.25rem !important; + } + + .pt-sm-2 { + padding-top: 0.5rem !important; + } + + .pt-sm-3 { + padding-top: 1rem !important; + } + + .pt-sm-4 { + padding-top: 1.5rem !important; + } + + .pt-sm-5 { + padding-top: 3rem !important; + } + + .pe-sm-0 { + padding-right: 0 !important; + } + + .pe-sm-1 { + padding-right: 0.25rem !important; + } + + .pe-sm-2 { + padding-right: 0.5rem !important; + } + + .pe-sm-3 { + padding-right: 1rem !important; + } + + .pe-sm-4 { + padding-right: 1.5rem !important; + } + + .pe-sm-5 { + padding-right: 3rem !important; + } + + .pb-sm-0 { + padding-bottom: 0 !important; + } + + .pb-sm-1 { + padding-bottom: 0.25rem !important; + } + + .pb-sm-2 { + padding-bottom: 0.5rem !important; + } + + .pb-sm-3 { + padding-bottom: 1rem !important; + } + + .pb-sm-4 { + padding-bottom: 1.5rem !important; + } + + .pb-sm-5 { + padding-bottom: 3rem !important; + } + + .ps-sm-0 { + padding-left: 0 !important; + } + + .ps-sm-1 { + padding-left: 0.25rem !important; + } + + .ps-sm-2 { + padding-left: 0.5rem !important; + } + + .ps-sm-3 { + padding-left: 1rem !important; + } + + .ps-sm-4 { + padding-left: 1.5rem !important; + } + + .ps-sm-5 { + padding-left: 3rem !important; + } +} + +@media (min-width: 768px) { + .d-md-inline { + display: inline !important; + } + + .d-md-inline-block { + display: inline-block !important; + } + + .d-md-block { + display: block !important; + } + + .d-md-grid { + display: grid !important; + } + + .d-md-table { + display: table !important; + } + + .d-md-table-row { + display: table-row !important; + } + + .d-md-table-cell { + display: table-cell !important; + } + + .d-md-flex { + display: flex !important; + } + + .d-md-inline-flex { + display: inline-flex !important; + } + + .d-md-none { + display: none !important; + } + + .flex-md-fill { + flex: 1 1 auto !important; + } + + .flex-md-row { + flex-direction: row !important; + } + + .flex-md-column { + flex-direction: column !important; + } + + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-md-grow-0 { + flex-grow: 0 !important; + } + + .flex-md-grow-1 { + flex-grow: 1 !important; + } + + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-md-wrap { + flex-wrap: wrap !important; + } + + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-content-md-start { + justify-content: flex-start !important; + } + + .justify-content-md-end { + justify-content: flex-end !important; + } + + .justify-content-md-center { + justify-content: center !important; + } + + .justify-content-md-between { + justify-content: space-between !important; + } + + .justify-content-md-around { + justify-content: space-around !important; + } + + .justify-content-md-evenly { + justify-content: space-evenly !important; + } + + .align-items-md-start { + align-items: flex-start !important; + } + + .align-items-md-end { + align-items: flex-end !important; + } + + .align-items-md-center { + align-items: center !important; + } + + .align-items-md-baseline { + align-items: baseline !important; + } + + .align-items-md-stretch { + align-items: stretch !important; + } + + .align-content-md-start { + align-content: flex-start !important; + } + + .align-content-md-end { + align-content: flex-end !important; + } + + .align-content-md-center { + align-content: center !important; + } + + .align-content-md-between { + align-content: space-between !important; + } + + .align-content-md-around { + align-content: space-around !important; + } + + .align-content-md-stretch { + align-content: stretch !important; + } + + .align-self-md-auto { + align-self: auto !important; + } + + .align-self-md-start { + align-self: flex-start !important; + } + + .align-self-md-end { + align-self: flex-end !important; + } + + .align-self-md-center { + align-self: center !important; + } + + .align-self-md-baseline { + align-self: baseline !important; + } + + .align-self-md-stretch { + align-self: stretch !important; + } + + .order-md-first { + order: -1 !important; + } + + .order-md-0 { + order: 0 !important; + } + + .order-md-1 { + order: 1 !important; + } + + .order-md-2 { + order: 2 !important; + } + + .order-md-3 { + order: 3 !important; + } + + .order-md-4 { + order: 4 !important; + } + + .order-md-5 { + order: 5 !important; + } + + .order-md-last { + order: 6 !important; + } + + .m-md-0 { + margin: 0 !important; + } + + .m-md-1 { + margin: 0.25rem !important; + } + + .m-md-2 { + margin: 0.5rem !important; + } + + .m-md-3 { + margin: 1rem !important; + } + + .m-md-4 { + margin: 1.5rem !important; + } + + .m-md-5 { + margin: 3rem !important; + } + + .m-md-auto { + margin: auto !important; + } + + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-md-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-md-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-md-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-md-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-md-0 { + margin-top: 0 !important; + } + + .mt-md-1 { + margin-top: 0.25rem !important; + } + + .mt-md-2 { + margin-top: 0.5rem !important; + } + + .mt-md-3 { + margin-top: 1rem !important; + } + + .mt-md-4 { + margin-top: 1.5rem !important; + } + + .mt-md-5 { + margin-top: 3rem !important; + } + + .mt-md-auto { + margin-top: auto !important; + } + + .me-md-0 { + margin-right: 0 !important; + } + + .me-md-1 { + margin-right: 0.25rem !important; + } + + .me-md-2 { + margin-right: 0.5rem !important; + } + + .me-md-3 { + margin-right: 1rem !important; + } + + .me-md-4 { + margin-right: 1.5rem !important; + } + + .me-md-5 { + margin-right: 3rem !important; + } + + .me-md-auto { + margin-right: auto !important; + } + + .mb-md-0 { + margin-bottom: 0 !important; + } + + .mb-md-1 { + margin-bottom: 0.25rem !important; + } + + .mb-md-2 { + margin-bottom: 0.5rem !important; + } + + .mb-md-3 { + margin-bottom: 1rem !important; + } + + .mb-md-4 { + margin-bottom: 1.5rem !important; + } + + .mb-md-5 { + margin-bottom: 3rem !important; + } + + .mb-md-auto { + margin-bottom: auto !important; + } + + .ms-md-0 { + margin-left: 0 !important; + } + + .ms-md-1 { + margin-left: 0.25rem !important; + } + + .ms-md-2 { + margin-left: 0.5rem !important; + } + + .ms-md-3 { + margin-left: 1rem !important; + } + + .ms-md-4 { + margin-left: 1.5rem !important; + } + + .ms-md-5 { + margin-left: 3rem !important; + } + + .ms-md-auto { + margin-left: auto !important; + } + + .p-md-0 { + padding: 0 !important; + } + + .p-md-1 { + padding: 0.25rem !important; + } + + .p-md-2 { + padding: 0.5rem !important; + } + + .p-md-3 { + padding: 1rem !important; + } + + .p-md-4 { + padding: 1.5rem !important; + } + + .p-md-5 { + padding: 3rem !important; + } + + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-md-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-md-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-md-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-md-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-md-0 { + padding-top: 0 !important; + } + + .pt-md-1 { + padding-top: 0.25rem !important; + } + + .pt-md-2 { + padding-top: 0.5rem !important; + } + + .pt-md-3 { + padding-top: 1rem !important; + } + + .pt-md-4 { + padding-top: 1.5rem !important; + } + + .pt-md-5 { + padding-top: 3rem !important; + } + + .pe-md-0 { + padding-right: 0 !important; + } + + .pe-md-1 { + padding-right: 0.25rem !important; + } + + .pe-md-2 { + padding-right: 0.5rem !important; + } + + .pe-md-3 { + padding-right: 1rem !important; + } + + .pe-md-4 { + padding-right: 1.5rem !important; + } + + .pe-md-5 { + padding-right: 3rem !important; + } + + .pb-md-0 { + padding-bottom: 0 !important; + } + + .pb-md-1 { + padding-bottom: 0.25rem !important; + } + + .pb-md-2 { + padding-bottom: 0.5rem !important; + } + + .pb-md-3 { + padding-bottom: 1rem !important; + } + + .pb-md-4 { + padding-bottom: 1.5rem !important; + } + + .pb-md-5 { + padding-bottom: 3rem !important; + } + + .ps-md-0 { + padding-left: 0 !important; + } + + .ps-md-1 { + padding-left: 0.25rem !important; + } + + .ps-md-2 { + padding-left: 0.5rem !important; + } + + .ps-md-3 { + padding-left: 1rem !important; + } + + .ps-md-4 { + padding-left: 1.5rem !important; + } + + .ps-md-5 { + padding-left: 3rem !important; + } +} + +@media (min-width: 992px) { + .d-lg-inline { + display: inline !important; + } + + .d-lg-inline-block { + display: inline-block !important; + } + + .d-lg-block { + display: block !important; + } + + .d-lg-grid { + display: grid !important; + } + + .d-lg-table { + display: table !important; + } + + .d-lg-table-row { + display: table-row !important; + } + + .d-lg-table-cell { + display: table-cell !important; + } + + .d-lg-flex { + display: flex !important; + } + + .d-lg-inline-flex { + display: inline-flex !important; + } + + .d-lg-none { + display: none !important; + } + + .flex-lg-fill { + flex: 1 1 auto !important; + } + + .flex-lg-row { + flex-direction: row !important; + } + + .flex-lg-column { + flex-direction: column !important; + } + + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-lg-wrap { + flex-wrap: wrap !important; + } + + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-content-lg-start { + justify-content: flex-start !important; + } + + .justify-content-lg-end { + justify-content: flex-end !important; + } + + .justify-content-lg-center { + justify-content: center !important; + } + + .justify-content-lg-between { + justify-content: space-between !important; + } + + .justify-content-lg-around { + justify-content: space-around !important; + } + + .justify-content-lg-evenly { + justify-content: space-evenly !important; + } + + .align-items-lg-start { + align-items: flex-start !important; + } + + .align-items-lg-end { + align-items: flex-end !important; + } + + .align-items-lg-center { + align-items: center !important; + } + + .align-items-lg-baseline { + align-items: baseline !important; + } + + .align-items-lg-stretch { + align-items: stretch !important; + } + + .align-content-lg-start { + align-content: flex-start !important; + } + + .align-content-lg-end { + align-content: flex-end !important; + } + + .align-content-lg-center { + align-content: center !important; + } + + .align-content-lg-between { + align-content: space-between !important; + } + + .align-content-lg-around { + align-content: space-around !important; + } + + .align-content-lg-stretch { + align-content: stretch !important; + } + + .align-self-lg-auto { + align-self: auto !important; + } + + .align-self-lg-start { + align-self: flex-start !important; + } + + .align-self-lg-end { + align-self: flex-end !important; + } + + .align-self-lg-center { + align-self: center !important; + } + + .align-self-lg-baseline { + align-self: baseline !important; + } + + .align-self-lg-stretch { + align-self: stretch !important; + } + + .order-lg-first { + order: -1 !important; + } + + .order-lg-0 { + order: 0 !important; + } + + .order-lg-1 { + order: 1 !important; + } + + .order-lg-2 { + order: 2 !important; + } + + .order-lg-3 { + order: 3 !important; + } + + .order-lg-4 { + order: 4 !important; + } + + .order-lg-5 { + order: 5 !important; + } + + .order-lg-last { + order: 6 !important; + } + + .m-lg-0 { + margin: 0 !important; + } + + .m-lg-1 { + margin: 0.25rem !important; + } + + .m-lg-2 { + margin: 0.5rem !important; + } + + .m-lg-3 { + margin: 1rem !important; + } + + .m-lg-4 { + margin: 1.5rem !important; + } + + .m-lg-5 { + margin: 3rem !important; + } + + .m-lg-auto { + margin: auto !important; + } + + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-lg-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-lg-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-lg-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-lg-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-lg-0 { + margin-top: 0 !important; + } + + .mt-lg-1 { + margin-top: 0.25rem !important; + } + + .mt-lg-2 { + margin-top: 0.5rem !important; + } + + .mt-lg-3 { + margin-top: 1rem !important; + } + + .mt-lg-4 { + margin-top: 1.5rem !important; + } + + .mt-lg-5 { + margin-top: 3rem !important; + } + + .mt-lg-auto { + margin-top: auto !important; + } + + .me-lg-0 { + margin-right: 0 !important; + } + + .me-lg-1 { + margin-right: 0.25rem !important; + } + + .me-lg-2 { + margin-right: 0.5rem !important; + } + + .me-lg-3 { + margin-right: 1rem !important; + } + + .me-lg-4 { + margin-right: 1.5rem !important; + } + + .me-lg-5 { + margin-right: 3rem !important; + } + + .me-lg-auto { + margin-right: auto !important; + } + + .mb-lg-0 { + margin-bottom: 0 !important; + } + + .mb-lg-1 { + margin-bottom: 0.25rem !important; + } + + .mb-lg-2 { + margin-bottom: 0.5rem !important; + } + + .mb-lg-3 { + margin-bottom: 1rem !important; + } + + .mb-lg-4 { + margin-bottom: 1.5rem !important; + } + + .mb-lg-5 { + margin-bottom: 3rem !important; + } + + .mb-lg-auto { + margin-bottom: auto !important; + } + + .ms-lg-0 { + margin-left: 0 !important; + } + + .ms-lg-1 { + margin-left: 0.25rem !important; + } + + .ms-lg-2 { + margin-left: 0.5rem !important; + } + + .ms-lg-3 { + margin-left: 1rem !important; + } + + .ms-lg-4 { + margin-left: 1.5rem !important; + } + + .ms-lg-5 { + margin-left: 3rem !important; + } + + .ms-lg-auto { + margin-left: auto !important; + } + + .p-lg-0 { + padding: 0 !important; + } + + .p-lg-1 { + padding: 0.25rem !important; + } + + .p-lg-2 { + padding: 0.5rem !important; + } + + .p-lg-3 { + padding: 1rem !important; + } + + .p-lg-4 { + padding: 1.5rem !important; + } + + .p-lg-5 { + padding: 3rem !important; + } + + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-lg-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-lg-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-lg-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-lg-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-lg-0 { + padding-top: 0 !important; + } + + .pt-lg-1 { + padding-top: 0.25rem !important; + } + + .pt-lg-2 { + padding-top: 0.5rem !important; + } + + .pt-lg-3 { + padding-top: 1rem !important; + } + + .pt-lg-4 { + padding-top: 1.5rem !important; + } + + .pt-lg-5 { + padding-top: 3rem !important; + } + + .pe-lg-0 { + padding-right: 0 !important; + } + + .pe-lg-1 { + padding-right: 0.25rem !important; + } + + .pe-lg-2 { + padding-right: 0.5rem !important; + } + + .pe-lg-3 { + padding-right: 1rem !important; + } + + .pe-lg-4 { + padding-right: 1.5rem !important; + } + + .pe-lg-5 { + padding-right: 3rem !important; + } + + .pb-lg-0 { + padding-bottom: 0 !important; + } + + .pb-lg-1 { + padding-bottom: 0.25rem !important; + } + + .pb-lg-2 { + padding-bottom: 0.5rem !important; + } + + .pb-lg-3 { + padding-bottom: 1rem !important; + } + + .pb-lg-4 { + padding-bottom: 1.5rem !important; + } + + .pb-lg-5 { + padding-bottom: 3rem !important; + } + + .ps-lg-0 { + padding-left: 0 !important; + } + + .ps-lg-1 { + padding-left: 0.25rem !important; + } + + .ps-lg-2 { + padding-left: 0.5rem !important; + } + + .ps-lg-3 { + padding-left: 1rem !important; + } + + .ps-lg-4 { + padding-left: 1.5rem !important; + } + + .ps-lg-5 { + padding-left: 3rem !important; + } +} + +@media (min-width: 1200px) { + .d-xl-inline { + display: inline !important; + } + + .d-xl-inline-block { + display: inline-block !important; + } + + .d-xl-block { + display: block !important; + } + + .d-xl-grid { + display: grid !important; + } + + .d-xl-table { + display: table !important; + } + + .d-xl-table-row { + display: table-row !important; + } + + .d-xl-table-cell { + display: table-cell !important; + } + + .d-xl-flex { + display: flex !important; + } + + .d-xl-inline-flex { + display: inline-flex !important; + } + + .d-xl-none { + display: none !important; + } + + .flex-xl-fill { + flex: 1 1 auto !important; + } + + .flex-xl-row { + flex-direction: row !important; + } + + .flex-xl-column { + flex-direction: column !important; + } + + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xl-wrap { + flex-wrap: wrap !important; + } + + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-content-xl-start { + justify-content: flex-start !important; + } + + .justify-content-xl-end { + justify-content: flex-end !important; + } + + .justify-content-xl-center { + justify-content: center !important; + } + + .justify-content-xl-between { + justify-content: space-between !important; + } + + .justify-content-xl-around { + justify-content: space-around !important; + } + + .justify-content-xl-evenly { + justify-content: space-evenly !important; + } + + .align-items-xl-start { + align-items: flex-start !important; + } + + .align-items-xl-end { + align-items: flex-end !important; + } + + .align-items-xl-center { + align-items: center !important; + } + + .align-items-xl-baseline { + align-items: baseline !important; + } + + .align-items-xl-stretch { + align-items: stretch !important; + } + + .align-content-xl-start { + align-content: flex-start !important; + } + + .align-content-xl-end { + align-content: flex-end !important; + } + + .align-content-xl-center { + align-content: center !important; + } + + .align-content-xl-between { + align-content: space-between !important; + } + + .align-content-xl-around { + align-content: space-around !important; + } + + .align-content-xl-stretch { + align-content: stretch !important; + } + + .align-self-xl-auto { + align-self: auto !important; + } + + .align-self-xl-start { + align-self: flex-start !important; + } + + .align-self-xl-end { + align-self: flex-end !important; + } + + .align-self-xl-center { + align-self: center !important; + } + + .align-self-xl-baseline { + align-self: baseline !important; + } + + .align-self-xl-stretch { + align-self: stretch !important; + } + + .order-xl-first { + order: -1 !important; + } + + .order-xl-0 { + order: 0 !important; + } + + .order-xl-1 { + order: 1 !important; + } + + .order-xl-2 { + order: 2 !important; + } + + .order-xl-3 { + order: 3 !important; + } + + .order-xl-4 { + order: 4 !important; + } + + .order-xl-5 { + order: 5 !important; + } + + .order-xl-last { + order: 6 !important; + } + + .m-xl-0 { + margin: 0 !important; + } + + .m-xl-1 { + margin: 0.25rem !important; + } + + .m-xl-2 { + margin: 0.5rem !important; + } + + .m-xl-3 { + margin: 1rem !important; + } + + .m-xl-4 { + margin: 1.5rem !important; + } + + .m-xl-5 { + margin: 3rem !important; + } + + .m-xl-auto { + margin: auto !important; + } + + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-xl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-xl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-xl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-xl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-xl-0 { + margin-top: 0 !important; + } + + .mt-xl-1 { + margin-top: 0.25rem !important; + } + + .mt-xl-2 { + margin-top: 0.5rem !important; + } + + .mt-xl-3 { + margin-top: 1rem !important; + } + + .mt-xl-4 { + margin-top: 1.5rem !important; + } + + .mt-xl-5 { + margin-top: 3rem !important; + } + + .mt-xl-auto { + margin-top: auto !important; + } + + .me-xl-0 { + margin-right: 0 !important; + } + + .me-xl-1 { + margin-right: 0.25rem !important; + } + + .me-xl-2 { + margin-right: 0.5rem !important; + } + + .me-xl-3 { + margin-right: 1rem !important; + } + + .me-xl-4 { + margin-right: 1.5rem !important; + } + + .me-xl-5 { + margin-right: 3rem !important; + } + + .me-xl-auto { + margin-right: auto !important; + } + + .mb-xl-0 { + margin-bottom: 0 !important; + } + + .mb-xl-1 { + margin-bottom: 0.25rem !important; + } + + .mb-xl-2 { + margin-bottom: 0.5rem !important; + } + + .mb-xl-3 { + margin-bottom: 1rem !important; + } + + .mb-xl-4 { + margin-bottom: 1.5rem !important; + } + + .mb-xl-5 { + margin-bottom: 3rem !important; + } + + .mb-xl-auto { + margin-bottom: auto !important; + } + + .ms-xl-0 { + margin-left: 0 !important; + } + + .ms-xl-1 { + margin-left: 0.25rem !important; + } + + .ms-xl-2 { + margin-left: 0.5rem !important; + } + + .ms-xl-3 { + margin-left: 1rem !important; + } + + .ms-xl-4 { + margin-left: 1.5rem !important; + } + + .ms-xl-5 { + margin-left: 3rem !important; + } + + .ms-xl-auto { + margin-left: auto !important; + } + + .p-xl-0 { + padding: 0 !important; + } + + .p-xl-1 { + padding: 0.25rem !important; + } + + .p-xl-2 { + padding: 0.5rem !important; + } + + .p-xl-3 { + padding: 1rem !important; + } + + .p-xl-4 { + padding: 1.5rem !important; + } + + .p-xl-5 { + padding: 3rem !important; + } + + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-xl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-xl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-xl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-xl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-xl-0 { + padding-top: 0 !important; + } + + .pt-xl-1 { + padding-top: 0.25rem !important; + } + + .pt-xl-2 { + padding-top: 0.5rem !important; + } + + .pt-xl-3 { + padding-top: 1rem !important; + } + + .pt-xl-4 { + padding-top: 1.5rem !important; + } + + .pt-xl-5 { + padding-top: 3rem !important; + } + + .pe-xl-0 { + padding-right: 0 !important; + } + + .pe-xl-1 { + padding-right: 0.25rem !important; + } + + .pe-xl-2 { + padding-right: 0.5rem !important; + } + + .pe-xl-3 { + padding-right: 1rem !important; + } + + .pe-xl-4 { + padding-right: 1.5rem !important; + } + + .pe-xl-5 { + padding-right: 3rem !important; + } + + .pb-xl-0 { + padding-bottom: 0 !important; + } + + .pb-xl-1 { + padding-bottom: 0.25rem !important; + } + + .pb-xl-2 { + padding-bottom: 0.5rem !important; + } + + .pb-xl-3 { + padding-bottom: 1rem !important; + } + + .pb-xl-4 { + padding-bottom: 1.5rem !important; + } + + .pb-xl-5 { + padding-bottom: 3rem !important; + } + + .ps-xl-0 { + padding-left: 0 !important; + } + + .ps-xl-1 { + padding-left: 0.25rem !important; + } + + .ps-xl-2 { + padding-left: 0.5rem !important; + } + + .ps-xl-3 { + padding-left: 1rem !important; + } + + .ps-xl-4 { + padding-left: 1.5rem !important; + } + + .ps-xl-5 { + padding-left: 3rem !important; + } +} + +@media (min-width: 1400px) { + .d-xxl-inline { + display: inline !important; + } + + .d-xxl-inline-block { + display: inline-block !important; + } + + .d-xxl-block { + display: block !important; + } + + .d-xxl-grid { + display: grid !important; + } + + .d-xxl-table { + display: table !important; + } + + .d-xxl-table-row { + display: table-row !important; + } + + .d-xxl-table-cell { + display: table-cell !important; + } + + .d-xxl-flex { + display: flex !important; + } + + .d-xxl-inline-flex { + display: inline-flex !important; + } + + .d-xxl-none { + display: none !important; + } + + .flex-xxl-fill { + flex: 1 1 auto !important; + } + + .flex-xxl-row { + flex-direction: row !important; + } + + .flex-xxl-column { + flex-direction: column !important; + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-content-xxl-start { + justify-content: flex-start !important; + } + + .justify-content-xxl-end { + justify-content: flex-end !important; + } + + .justify-content-xxl-center { + justify-content: center !important; + } + + .justify-content-xxl-between { + justify-content: space-between !important; + } + + .justify-content-xxl-around { + justify-content: space-around !important; + } + + .justify-content-xxl-evenly { + justify-content: space-evenly !important; + } + + .align-items-xxl-start { + align-items: flex-start !important; + } + + .align-items-xxl-end { + align-items: flex-end !important; + } + + .align-items-xxl-center { + align-items: center !important; + } + + .align-items-xxl-baseline { + align-items: baseline !important; + } + + .align-items-xxl-stretch { + align-items: stretch !important; + } + + .align-content-xxl-start { + align-content: flex-start !important; + } + + .align-content-xxl-end { + align-content: flex-end !important; + } + + .align-content-xxl-center { + align-content: center !important; + } + + .align-content-xxl-between { + align-content: space-between !important; + } + + .align-content-xxl-around { + align-content: space-around !important; + } + + .align-content-xxl-stretch { + align-content: stretch !important; + } + + .align-self-xxl-auto { + align-self: auto !important; + } + + .align-self-xxl-start { + align-self: flex-start !important; + } + + .align-self-xxl-end { + align-self: flex-end !important; + } + + .align-self-xxl-center { + align-self: center !important; + } + + .align-self-xxl-baseline { + align-self: baseline !important; + } + + .align-self-xxl-stretch { + align-self: stretch !important; + } + + .order-xxl-first { + order: -1 !important; + } + + .order-xxl-0 { + order: 0 !important; + } + + .order-xxl-1 { + order: 1 !important; + } + + .order-xxl-2 { + order: 2 !important; + } + + .order-xxl-3 { + order: 3 !important; + } + + .order-xxl-4 { + order: 4 !important; + } + + .order-xxl-5 { + order: 5 !important; + } + + .order-xxl-last { + order: 6 !important; + } + + .m-xxl-0 { + margin: 0 !important; + } + + .m-xxl-1 { + margin: 0.25rem !important; + } + + .m-xxl-2 { + margin: 0.5rem !important; + } + + .m-xxl-3 { + margin: 1rem !important; + } + + .m-xxl-4 { + margin: 1.5rem !important; + } + + .m-xxl-5 { + margin: 3rem !important; + } + + .m-xxl-auto { + margin: auto !important; + } + + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-xxl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-xxl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-xxl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-xxl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-xxl-0 { + margin-top: 0 !important; + } + + .mt-xxl-1 { + margin-top: 0.25rem !important; + } + + .mt-xxl-2 { + margin-top: 0.5rem !important; + } + + .mt-xxl-3 { + margin-top: 1rem !important; + } + + .mt-xxl-4 { + margin-top: 1.5rem !important; + } + + .mt-xxl-5 { + margin-top: 3rem !important; + } + + .mt-xxl-auto { + margin-top: auto !important; + } + + .me-xxl-0 { + margin-right: 0 !important; + } + + .me-xxl-1 { + margin-right: 0.25rem !important; + } + + .me-xxl-2 { + margin-right: 0.5rem !important; + } + + .me-xxl-3 { + margin-right: 1rem !important; + } + + .me-xxl-4 { + margin-right: 1.5rem !important; + } + + .me-xxl-5 { + margin-right: 3rem !important; + } + + .me-xxl-auto { + margin-right: auto !important; + } + + .mb-xxl-0 { + margin-bottom: 0 !important; + } + + .mb-xxl-1 { + margin-bottom: 0.25rem !important; + } + + .mb-xxl-2 { + margin-bottom: 0.5rem !important; + } + + .mb-xxl-3 { + margin-bottom: 1rem !important; + } + + .mb-xxl-4 { + margin-bottom: 1.5rem !important; + } + + .mb-xxl-5 { + margin-bottom: 3rem !important; + } + + .mb-xxl-auto { + margin-bottom: auto !important; + } + + .ms-xxl-0 { + margin-left: 0 !important; + } + + .ms-xxl-1 { + margin-left: 0.25rem !important; + } + + .ms-xxl-2 { + margin-left: 0.5rem !important; + } + + .ms-xxl-3 { + margin-left: 1rem !important; + } + + .ms-xxl-4 { + margin-left: 1.5rem !important; + } + + .ms-xxl-5 { + margin-left: 3rem !important; + } + + .ms-xxl-auto { + margin-left: auto !important; + } + + .p-xxl-0 { + padding: 0 !important; + } + + .p-xxl-1 { + padding: 0.25rem !important; + } + + .p-xxl-2 { + padding: 0.5rem !important; + } + + .p-xxl-3 { + padding: 1rem !important; + } + + .p-xxl-4 { + padding: 1.5rem !important; + } + + .p-xxl-5 { + padding: 3rem !important; + } + + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-xxl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-xxl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-xxl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-xxl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-xxl-0 { + padding-top: 0 !important; + } + + .pt-xxl-1 { + padding-top: 0.25rem !important; + } + + .pt-xxl-2 { + padding-top: 0.5rem !important; + } + + .pt-xxl-3 { + padding-top: 1rem !important; + } + + .pt-xxl-4 { + padding-top: 1.5rem !important; + } + + .pt-xxl-5 { + padding-top: 3rem !important; + } + + .pe-xxl-0 { + padding-right: 0 !important; + } + + .pe-xxl-1 { + padding-right: 0.25rem !important; + } + + .pe-xxl-2 { + padding-right: 0.5rem !important; + } + + .pe-xxl-3 { + padding-right: 1rem !important; + } + + .pe-xxl-4 { + padding-right: 1.5rem !important; + } + + .pe-xxl-5 { + padding-right: 3rem !important; + } + + .pb-xxl-0 { + padding-bottom: 0 !important; + } + + .pb-xxl-1 { + padding-bottom: 0.25rem !important; + } + + .pb-xxl-2 { + padding-bottom: 0.5rem !important; + } + + .pb-xxl-3 { + padding-bottom: 1rem !important; + } + + .pb-xxl-4 { + padding-bottom: 1.5rem !important; + } + + .pb-xxl-5 { + padding-bottom: 3rem !important; + } + + .ps-xxl-0 { + padding-left: 0 !important; + } + + .ps-xxl-1 { + padding-left: 0.25rem !important; + } + + .ps-xxl-2 { + padding-left: 0.5rem !important; + } + + .ps-xxl-3 { + padding-left: 1rem !important; + } + + .ps-xxl-4 { + padding-left: 1.5rem !important; + } + + .ps-xxl-5 { + padding-left: 3rem !important; + } +} + +@media print { + .d-print-inline { + display: inline !important; + } + + .d-print-inline-block { + display: inline-block !important; + } + + .d-print-block { + display: block !important; + } + + .d-print-grid { + display: grid !important; + } + + .d-print-table { + display: table !important; + } + + .d-print-table-row { + display: table-row !important; + } + + .d-print-table-cell { + display: table-cell !important; + } + + .d-print-flex { + display: flex !important; + } + + .d-print-inline-flex { + display: inline-flex !important; + } + + .d-print-none { + display: none !important; + } +} + +// Tooltips +.tooltip { + position: absolute; + z-index: 999999; + display: block; + margin: 0; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; + pointer-events: none; +} + +.tooltip.show { + opacity: 0.9; +} + +.tooltip .tooltip-arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} + +.tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top, +.bs-tooltip-auto[data-popper-placement^="top"] { + padding: 0.4rem 0; +} + +.bs-tooltip-top .tooltip-arrow, +.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow { + bottom: 0; +} + +.bs-tooltip-top .tooltip-arrow::before, +.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before { + top: -1px; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} + +.bs-tooltip-end, +.bs-tooltip-auto[data-popper-placement^="right"] { + padding: 0 0.4rem; +} + +.bs-tooltip-end .tooltip-arrow, +.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} + +.bs-tooltip-end .tooltip-arrow::before, +.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before { + right: -1px; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} + +.bs-tooltip-bottom, +.bs-tooltip-auto[data-popper-placement^="bottom"] { + padding: 0.4rem 0; +} + +.bs-tooltip-bottom .tooltip-arrow, +.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow { + top: 0; +} + +.bs-tooltip-bottom .tooltip-arrow::before, +.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before { + bottom: -1px; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} + +.bs-tooltip-start, +.bs-tooltip-auto[data-popper-placement^="left"] { + padding: 0 0.4rem; +} + +.bs-tooltip-start .tooltip-arrow, +.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} + +.bs-tooltip-start .tooltip-arrow::before, +.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before { + left: -1px; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; + -webkit-user-select: none; + user-select: none; + pointer-events: none; +} + +.popover { + position: absolute; + top: 0; + left: 0 /* rtl:ignore */; + z-index: 1070; + display: block; + max-width: 276px; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: var(--modalBackground); + background-clip: padding-box; + box-shadow: var(--mediaItemShadow), var(--mediaItemShadow-Shadow); + border-radius: var(--mediaItemRadius); +} +.popover .popover-arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; +} +.popover .popover-arrow::before, +.popover .popover-arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-popover-top > .popover-arrow, +.bs-popover-auto[data-popper-placement^="top"] > .popover-arrow { + bottom: calc(-0.5rem - 1px); +} +.bs-popover-top > .popover-arrow::before, +.bs-popover-auto[data-popper-placement^="top"] > .popover-arrow::before { + bottom: 0; + border-width: 0.5rem 0.5rem 0; + border-top-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-top > .popover-arrow::after, +.bs-popover-auto[data-popper-placement^="top"] > .popover-arrow::after { + bottom: 1px; + border-width: 0.5rem 0.5rem 0; + border-top-color: #fff; +} + +.bs-popover-end > .popover-arrow, +.bs-popover-auto[data-popper-placement^="right"] > .popover-arrow { + left: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; +} +.bs-popover-end > .popover-arrow::before, +.bs-popover-auto[data-popper-placement^="right"] > .popover-arrow::before { + left: 0; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-end > .popover-arrow::after, +.bs-popover-auto[data-popper-placement^="right"] > .popover-arrow::after { + left: 1px; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: #fff; +} + +.bs-popover-bottom > .popover-arrow, +.bs-popover-auto[data-popper-placement^="bottom"] > .popover-arrow { + top: calc(-0.5rem - 1px); +} +.bs-popover-bottom > .popover-arrow::before, +.bs-popover-auto[data-popper-placement^="bottom"] > .popover-arrow::before { + top: 0; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-bottom > .popover-arrow::after, +.bs-popover-auto[data-popper-placement^="bottom"] > .popover-arrow::after { + top: 1px; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: #fff; +} +.bs-popover-bottom .popover-header::before, +.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ""; + border-bottom: 1px solid #f0f0f0; +} + +.bs-popover-start > .popover-arrow, +.bs-popover-auto[data-popper-placement^="left"] > .popover-arrow { + right: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; +} +.bs-popover-start > .popover-arrow::before, +.bs-popover-auto[data-popper-placement^="left"] > .popover-arrow::before { + right: 0; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-start > .popover-arrow::after, +.bs-popover-auto[data-popper-placement^="left"] > .popover-arrow::after { + right: 1px; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: #fff; +} + +.popover-header { + padding: 0.5rem 1rem; + margin-bottom: 0; + font-size: 1rem; + background-color: #f0f0f0; + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.popover-header:empty { + display: none; +} + +.popover-body { + padding: 1rem 1rem; + color: var(--textColor); +} + +// carousel +.carousel { + position: relative; +} + +.carousel.pointer-event { + -ms-touch-action: pan-y; + touch-action: pan-y; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner::after { + display: block; + clear: both; + content: ""; +} + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: -webkit-transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out; + transition: + transform 0.6s ease-in-out, + -webkit-transform 0.6s ease-in-out; +} + +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none; + } +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +.carousel-item-next:not(.carousel-item-left), +.active.carousel-item-right { + -webkit-transform: translateX(100%); + transform: translateX(100%); +} + +.carousel-item-prev:not(.carousel-item-right), +.active.carousel-item-left { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} + +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + -webkit-transform: none; + transform: none; +} + +.carousel-fade .carousel-item.active, +.carousel-fade .carousel-item-next.carousel-item-left, +.carousel-fade .carousel-item-prev.carousel-item-right { + z-index: 1; + opacity: 1; +} + +.carousel-fade .active.carousel-item-left, +.carousel-fade .active.carousel-item-right { + z-index: 0; + opacity: 0; + transition: opacity 0s 0.6s; +} + +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-left, + .carousel-fade .active.carousel-item-right { + transition: none; + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: none; + border: 0; + opacity: 0.5; + transition: opacity 0.15s ease; +} + +@media (prefers-reduced-motion: reduce) { + .carousel-control-prev, + .carousel-control-next { + transition: none; + } +} + +.carousel-control-prev:hover, +.carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: 0.9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 20px; + height: 20px; + background: 50% / 100% 100% no-repeat; +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 15; + display: -ms-flexbox; + display: flex; + -ms-flex-pack: center; + justify-content: center; + padding-left: 0; + margin-right: 15%; + margin-left: 15%; + list-style: none; +} + +.carousel-indicators li { + box-sizing: content-box; + -ms-flex: 0 1 auto; + flex: 0 1 auto; + width: 30px; + height: 3px; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: 0.5; + transition: opacity 0.6s ease; +} + +@media (prefers-reduced-motion: reduce) { + .carousel-indicators li { + transition: none; + } +} + +.carousel-indicators .active { + opacity: 1; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; +} diff --git a/src/renderer/less/codicon.css b/src/renderer/less/codicon.css new file mode 100644 index 00000000..0b10c7fa --- /dev/null +++ b/src/renderer/less/codicon.css @@ -0,0 +1,1565 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +@font-face { + font-family: "codicon"; + font-display: block; + src: url("./codicon.ttf?f06865699f1720ee6ca6e0a4aa084d76") format("truetype"); +} + +.codicon[class*="codicon-"] { + font: normal normal normal 16px/1 codicon; + display: inline-block; + text-decoration: none; + text-rendering: auto; + text-align: center; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + user-select: none; + -webkit-user-select: none; + -ms-user-select: none; +} + +/*--------------------- + * Modifiers + *-------------------*/ + +@keyframes codicon-spin { + 100% { + transform: rotate(360deg); + } +} + +.codicon-sync.codicon-modifier-spin, +.codicon-loading.codicon-modifier-spin, +.codicon-gear.codicon-modifier-spin { + /* Use steps to throttle FPS to reduce CPU usage */ + animation: codicon-spin 1.5s steps(30) infinite; +} + +.codicon-modifier-disabled { + opacity: 0.5; +} + +.codicon-modifier-hidden { + opacity: 0; +} + +/* custom speed & easing for loading icon */ +.codicon-loading { + animation-duration: 1s !important; + animation-timing-function: cubic-bezier(0.53, 0.21, 0.29, 0.67) !important; +} + +/*--------------------- + * Icons + *-------------------*/ + +.codicon-add:before { + content: "\ea60"; +} +.codicon-plus:before { + content: "\ea60"; +} +.codicon-gist-new:before { + content: "\ea60"; +} +.codicon-repo-create:before { + content: "\ea60"; +} +.codicon-lightbulb:before { + content: "\ea61"; +} +.codicon-light-bulb:before { + content: "\ea61"; +} +.codicon-repo:before { + content: "\ea62"; +} +.codicon-repo-delete:before { + content: "\ea62"; +} +.codicon-gist-fork:before { + content: "\ea63"; +} +.codicon-repo-forked:before { + content: "\ea63"; +} +.codicon-git-pull-request:before { + content: "\ea64"; +} +.codicon-git-pull-request-abandoned:before { + content: "\ea64"; +} +.codicon-record-keys:before { + content: "\ea65"; +} +.codicon-keyboard:before { + content: "\ea65"; +} +.codicon-tag:before { + content: "\ea66"; +} +.codicon-tag-add:before { + content: "\ea66"; +} +.codicon-tag-remove:before { + content: "\ea66"; +} +.codicon-person:before { + content: "\ea67"; +} +.codicon-person-follow:before { + content: "\ea67"; +} +.codicon-person-outline:before { + content: "\ea67"; +} +.codicon-person-filled:before { + content: "\ea67"; +} +.codicon-git-branch:before { + content: "\ea68"; +} +.codicon-git-branch-create:before { + content: "\ea68"; +} +.codicon-git-branch-delete:before { + content: "\ea68"; +} +.codicon-source-control:before { + content: "\ea68"; +} +.codicon-mirror:before { + content: "\ea69"; +} +.codicon-mirror-public:before { + content: "\ea69"; +} +.codicon-star:before { + content: "\ea6a"; +} +.codicon-star-add:before { + content: "\ea6a"; +} +.codicon-star-delete:before { + content: "\ea6a"; +} +.codicon-star-empty:before { + content: "\ea6a"; +} +.codicon-comment:before { + content: "\ea6b"; +} +.codicon-comment-add:before { + content: "\ea6b"; +} +.codicon-alert:before { + content: "\ea6c"; +} +.codicon-warning:before { + content: "\ea6c"; +} +.codicon-search:before { + content: "\ea6d"; +} +.codicon-search-save:before { + content: "\ea6d"; +} +.codicon-log-out:before { + content: "\ea6e"; +} +.codicon-sign-out:before { + content: "\ea6e"; +} +.codicon-log-in:before { + content: "\ea6f"; +} +.codicon-sign-in:before { + content: "\ea6f"; +} +.codicon-eye:before { + content: "\ea70"; +} +.codicon-eye-unwatch:before { + content: "\ea70"; +} +.codicon-eye-watch:before { + content: "\ea70"; +} +.codicon-circle-filled:before { + content: "\ea71"; +} +.codicon-primitive-dot:before { + content: "\ea71"; +} +.codicon-close-dirty:before { + content: "\ea71"; +} +.codicon-debug-breakpoint:before { + content: "\ea71"; +} +.codicon-debug-breakpoint-disabled:before { + content: "\ea71"; +} +.codicon-debug-hint:before { + content: "\ea71"; +} +.codicon-primitive-square:before { + content: "\ea72"; +} +.codicon-edit:before { + content: "\ea73"; +} +.codicon-pencil:before { + content: "\ea73"; +} +.codicon-info:before { + content: "\ea74"; +} +.codicon-issue-opened:before { + content: "\ea74"; +} +.codicon-gist-private:before { + content: "\ea75"; +} +.codicon-git-fork-private:before { + content: "\ea75"; +} +.codicon-lock:before { + content: "\ea75"; +} +.codicon-mirror-private:before { + content: "\ea75"; +} +.codicon-close:before { + content: "\ea76"; +} +.codicon-remove-close:before { + content: "\ea76"; +} +.codicon-x:before { + content: "\ea76"; +} +.codicon-repo-sync:before { + content: "\ea77"; +} +.codicon-sync:before { + content: "\ea77"; +} +.codicon-clone:before { + content: "\ea78"; +} +.codicon-desktop-download:before { + content: "\ea78"; +} +.codicon-beaker:before { + content: "\ea79"; +} +.codicon-microscope:before { + content: "\ea79"; +} +.codicon-vm:before { + content: "\ea7a"; +} +.codicon-device-desktop:before { + content: "\ea7a"; +} +.codicon-file:before { + content: "\ea7b"; +} +.codicon-file-text:before { + content: "\ea7b"; +} +.codicon-more:before { + content: "\ea7c"; +} +.codicon-ellipsis:before { + content: "\ea7c"; +} +.codicon-kebab-horizontal:before { + content: "\ea7c"; +} +.codicon-mail-reply:before { + content: "\ea7d"; +} +.codicon-reply:before { + content: "\ea7d"; +} +.codicon-organization:before { + content: "\ea7e"; +} +.codicon-organization-filled:before { + content: "\ea7e"; +} +.codicon-organization-outline:before { + content: "\ea7e"; +} +.codicon-new-file:before { + content: "\ea7f"; +} +.codicon-file-add:before { + content: "\ea7f"; +} +.codicon-new-folder:before { + content: "\ea80"; +} +.codicon-file-directory-create:before { + content: "\ea80"; +} +.codicon-trash:before { + content: "\ea81"; +} +.codicon-trashcan:before { + content: "\ea81"; +} +.codicon-history:before { + content: "\ea82"; +} +.codicon-clock:before { + content: "\ea82"; +} +.codicon-folder:before { + content: "\ea83"; +} +.codicon-file-directory:before { + content: "\ea83"; +} +.codicon-symbol-folder:before { + content: "\ea83"; +} +.codicon-logo-github:before { + content: "\ea84"; +} +.codicon-mark-github:before { + content: "\ea84"; +} +.codicon-github:before { + content: "\ea84"; +} +.codicon-terminal:before { + content: "\ea85"; +} +.codicon-console:before { + content: "\ea85"; +} +.codicon-repl:before { + content: "\ea85"; +} +.codicon-zap:before { + content: "\ea86"; +} +.codicon-symbol-event:before { + content: "\ea86"; +} +.codicon-error:before { + content: "\ea87"; +} +.codicon-stop:before { + content: "\ea87"; +} +.codicon-variable:before { + content: "\ea88"; +} +.codicon-symbol-variable:before { + content: "\ea88"; +} +.codicon-array:before { + content: "\ea8a"; +} +.codicon-symbol-array:before { + content: "\ea8a"; +} +.codicon-symbol-module:before { + content: "\ea8b"; +} +.codicon-symbol-package:before { + content: "\ea8b"; +} +.codicon-symbol-namespace:before { + content: "\ea8b"; +} +.codicon-symbol-object:before { + content: "\ea8b"; +} +.codicon-symbol-method:before { + content: "\ea8c"; +} +.codicon-symbol-function:before { + content: "\ea8c"; +} +.codicon-symbol-constructor:before { + content: "\ea8c"; +} +.codicon-symbol-boolean:before { + content: "\ea8f"; +} +.codicon-symbol-null:before { + content: "\ea8f"; +} +.codicon-symbol-numeric:before { + content: "\ea90"; +} +.codicon-symbol-number:before { + content: "\ea90"; +} +.codicon-symbol-structure:before { + content: "\ea91"; +} +.codicon-symbol-struct:before { + content: "\ea91"; +} +.codicon-symbol-parameter:before { + content: "\ea92"; +} +.codicon-symbol-type-parameter:before { + content: "\ea92"; +} +.codicon-symbol-key:before { + content: "\ea93"; +} +.codicon-symbol-text:before { + content: "\ea93"; +} +.codicon-symbol-reference:before { + content: "\ea94"; +} +.codicon-go-to-file:before { + content: "\ea94"; +} +.codicon-symbol-enum:before { + content: "\ea95"; +} +.codicon-symbol-value:before { + content: "\ea95"; +} +.codicon-symbol-ruler:before { + content: "\ea96"; +} +.codicon-symbol-unit:before { + content: "\ea96"; +} +.codicon-activate-breakpoints:before { + content: "\ea97"; +} +.codicon-archive:before { + content: "\ea98"; +} +.codicon-arrow-both:before { + content: "\ea99"; +} +.codicon-arrow-down:before { + content: "\ea9a"; +} +.codicon-arrow-left:before { + content: "\ea9b"; +} +.codicon-arrow-right:before { + content: "\ea9c"; +} +.codicon-arrow-small-down:before { + content: "\ea9d"; +} +.codicon-arrow-small-left:before { + content: "\ea9e"; +} +.codicon-arrow-small-right:before { + content: "\ea9f"; +} +.codicon-arrow-small-up:before { + content: "\eaa0"; +} +.codicon-arrow-up:before { + content: "\eaa1"; +} +.codicon-bell:before { + content: "\eaa2"; +} +.codicon-bold:before { + content: "\eaa3"; +} +.codicon-book:before { + content: "\eaa4"; +} +.codicon-bookmark:before { + content: "\eaa5"; +} +.codicon-debug-breakpoint-conditional-unverified:before { + content: "\eaa6"; +} +.codicon-debug-breakpoint-conditional:before { + content: "\eaa7"; +} +.codicon-debug-breakpoint-conditional-disabled:before { + content: "\eaa7"; +} +.codicon-debug-breakpoint-data-unverified:before { + content: "\eaa8"; +} +.codicon-debug-breakpoint-data:before { + content: "\eaa9"; +} +.codicon-debug-breakpoint-data-disabled:before { + content: "\eaa9"; +} +.codicon-debug-breakpoint-log-unverified:before { + content: "\eaaa"; +} +.codicon-debug-breakpoint-log:before { + content: "\eaab"; +} +.codicon-debug-breakpoint-log-disabled:before { + content: "\eaab"; +} +.codicon-briefcase:before { + content: "\eaac"; +} +.codicon-broadcast:before { + content: "\eaad"; +} +.codicon-browser:before { + content: "\eaae"; +} +.codicon-bug:before { + content: "\eaaf"; +} +.codicon-calendar:before { + content: "\eab0"; +} +.codicon-case-sensitive:before { + content: "\eab1"; +} +.codicon-check:before { + content: "\eab2"; +} +.codicon-checklist:before { + content: "\eab3"; +} +.codicon-chevron-down:before { + content: "\eab4"; +} +.codicon-chevron-left:before { + content: "\eab5"; +} +.codicon-chevron-right:before { + content: "\eab6"; +} +.codicon-chevron-up:before { + content: "\eab7"; +} +.codicon-chrome-close:before { + content: "\eab8"; +} +.codicon-chrome-maximize:before { + content: "\eab9"; +} +.codicon-chrome-minimize:before { + content: "\eaba"; +} +.codicon-chrome-restore:before { + content: "\eabb"; +} +.codicon-circle-outline:before { + content: "\eabc"; +} +.codicon-debug-breakpoint-unverified:before { + content: "\eabc"; +} +.codicon-circle-slash:before { + content: "\eabd"; +} +.codicon-circuit-board:before { + content: "\eabe"; +} +.codicon-clear-all:before { + content: "\eabf"; +} +.codicon-clippy:before { + content: "\eac0"; +} +.codicon-close-all:before { + content: "\eac1"; +} +.codicon-cloud-download:before { + content: "\eac2"; +} +.codicon-cloud-upload:before { + content: "\eac3"; +} +.codicon-code:before { + content: "\eac4"; +} +.codicon-collapse-all:before { + content: "\eac5"; +} +.codicon-color-mode:before { + content: "\eac6"; +} +.codicon-comment-discussion:before { + content: "\eac7"; +} +.codicon-credit-card:before { + content: "\eac9"; +} +.codicon-dash:before { + content: "\eacc"; +} +.codicon-dashboard:before { + content: "\eacd"; +} +.codicon-database:before { + content: "\eace"; +} +.codicon-debug-continue:before { + content: "\eacf"; +} +.codicon-debug-disconnect:before { + content: "\ead0"; +} +.codicon-debug-pause:before { + content: "\ead1"; +} +.codicon-debug-restart:before { + content: "\ead2"; +} +.codicon-debug-start:before { + content: "\ead3"; +} +.codicon-debug-step-into:before { + content: "\ead4"; +} +.codicon-debug-step-out:before { + content: "\ead5"; +} +.codicon-debug-step-over:before { + content: "\ead6"; +} +.codicon-debug-stop:before { + content: "\ead7"; +} +.codicon-debug:before { + content: "\ead8"; +} +.codicon-device-camera-video:before { + content: "\ead9"; +} +.codicon-device-camera:before { + content: "\eada"; +} +.codicon-device-mobile:before { + content: "\eadb"; +} +.codicon-diff-added:before { + content: "\eadc"; +} +.codicon-diff-ignored:before { + content: "\eadd"; +} +.codicon-diff-modified:before { + content: "\eade"; +} +.codicon-diff-removed:before { + content: "\eadf"; +} +.codicon-diff-renamed:before { + content: "\eae0"; +} +.codicon-diff:before { + content: "\eae1"; +} +.codicon-discard:before { + content: "\eae2"; +} +.codicon-editor-layout:before { + content: "\eae3"; +} +.codicon-empty-window:before { + content: "\eae4"; +} +.codicon-exclude:before { + content: "\eae5"; +} +.codicon-extensions:before { + content: "\eae6"; +} +.codicon-eye-closed:before { + content: "\eae7"; +} +.codicon-file-binary:before { + content: "\eae8"; +} +.codicon-file-code:before { + content: "\eae9"; +} +.codicon-file-media:before { + content: "\eaea"; +} +.codicon-file-pdf:before { + content: "\eaeb"; +} +.codicon-file-submodule:before { + content: "\eaec"; +} +.codicon-file-symlink-directory:before { + content: "\eaed"; +} +.codicon-file-symlink-file:before { + content: "\eaee"; +} +.codicon-file-zip:before { + content: "\eaef"; +} +.codicon-files:before { + content: "\eaf0"; +} +.codicon-filter:before { + content: "\eaf1"; +} +.codicon-flame:before { + content: "\eaf2"; +} +.codicon-fold-down:before { + content: "\eaf3"; +} +.codicon-fold-up:before { + content: "\eaf4"; +} +.codicon-fold:before { + content: "\eaf5"; +} +.codicon-folder-active:before { + content: "\eaf6"; +} +.codicon-folder-opened:before { + content: "\eaf7"; +} +.codicon-gear:before { + content: "\eaf8"; +} +.codicon-gift:before { + content: "\eaf9"; +} +.codicon-gist-secret:before { + content: "\eafa"; +} +.codicon-gist:before { + content: "\eafb"; +} +.codicon-git-commit:before { + content: "\eafc"; +} +.codicon-git-compare:before { + content: "\eafd"; +} +.codicon-compare-changes:before { + content: "\eafd"; +} +.codicon-git-merge:before { + content: "\eafe"; +} +.codicon-github-action:before { + content: "\eaff"; +} +.codicon-github-alt:before { + content: "\eb00"; +} +.codicon-globe:before { + content: "\eb01"; +} +.codicon-grabber:before { + content: "\eb02"; +} +.codicon-graph:before { + content: "\eb03"; +} +.codicon-gripper:before { + content: "\eb04"; +} +.codicon-heart:before { + content: "\eb05"; +} +.codicon-home:before { + content: "\eb06"; +} +.codicon-horizontal-rule:before { + content: "\eb07"; +} +.codicon-hubot:before { + content: "\eb08"; +} +.codicon-inbox:before { + content: "\eb09"; +} +.codicon-issue-reopened:before { + content: "\eb0b"; +} +.codicon-issues:before { + content: "\eb0c"; +} +.codicon-italic:before { + content: "\eb0d"; +} +.codicon-jersey:before { + content: "\eb0e"; +} +.codicon-json:before { + content: "\eb0f"; +} +.codicon-kebab-vertical:before { + content: "\eb10"; +} +.codicon-key:before { + content: "\eb11"; +} +.codicon-law:before { + content: "\eb12"; +} +.codicon-lightbulb-autofix:before { + content: "\eb13"; +} +.codicon-link-external:before { + content: "\eb14"; +} +.codicon-link:before { + content: "\eb15"; +} +.codicon-list-ordered:before { + content: "\eb16"; +} +.codicon-list-unordered:before { + content: "\eb17"; +} +.codicon-live-share:before { + content: "\eb18"; +} +.codicon-loading:before { + content: "\eb19"; +} +.codicon-location:before { + content: "\eb1a"; +} +.codicon-mail-read:before { + content: "\eb1b"; +} +.codicon-mail:before { + content: "\eb1c"; +} +.codicon-markdown:before { + content: "\eb1d"; +} +.codicon-megaphone:before { + content: "\eb1e"; +} +.codicon-mention:before { + content: "\eb1f"; +} +.codicon-milestone:before { + content: "\eb20"; +} +.codicon-mortar-board:before { + content: "\eb21"; +} +.codicon-move:before { + content: "\eb22"; +} +.codicon-multiple-windows:before { + content: "\eb23"; +} +.codicon-mute:before { + content: "\eb24"; +} +.codicon-no-newline:before { + content: "\eb25"; +} +.codicon-note:before { + content: "\eb26"; +} +.codicon-octoface:before { + content: "\eb27"; +} +.codicon-open-preview:before { + content: "\eb28"; +} +.codicon-package:before { + content: "\eb29"; +} +.codicon-paintcan:before { + content: "\eb2a"; +} +.codicon-pin:before { + content: "\eb2b"; +} +.codicon-play:before { + content: "\eb2c"; +} +.codicon-run:before { + content: "\eb2c"; +} +.codicon-plug:before { + content: "\eb2d"; +} +.codicon-preserve-case:before { + content: "\eb2e"; +} +.codicon-preview:before { + content: "\eb2f"; +} +.codicon-project:before { + content: "\eb30"; +} +.codicon-pulse:before { + content: "\eb31"; +} +.codicon-question:before { + content: "\eb32"; +} +.codicon-quote:before { + content: "\eb33"; +} +.codicon-radio-tower:before { + content: "\eb34"; +} +.codicon-reactions:before { + content: "\eb35"; +} +.codicon-references:before { + content: "\eb36"; +} +.codicon-refresh:before { + content: "\eb37"; +} +.codicon-regex:before { + content: "\eb38"; +} +.codicon-remote-explorer:before { + content: "\eb39"; +} +.codicon-remote:before { + content: "\eb3a"; +} +.codicon-remove:before { + content: "\eb3b"; +} +.codicon-replace-all:before { + content: "\eb3c"; +} +.codicon-replace:before { + content: "\eb3d"; +} +.codicon-repo-clone:before { + content: "\eb3e"; +} +.codicon-repo-force-push:before { + content: "\eb3f"; +} +.codicon-repo-pull:before { + content: "\eb40"; +} +.codicon-repo-push:before { + content: "\eb41"; +} +.codicon-report:before { + content: "\eb42"; +} +.codicon-request-changes:before { + content: "\eb43"; +} +.codicon-rocket:before { + content: "\eb44"; +} +.codicon-root-folder-opened:before { + content: "\eb45"; +} +.codicon-root-folder:before { + content: "\eb46"; +} +.codicon-rss:before { + content: "\eb47"; +} +.codicon-ruby:before { + content: "\eb48"; +} +.codicon-save-all:before { + content: "\eb49"; +} +.codicon-save-as:before { + content: "\eb4a"; +} +.codicon-save:before { + content: "\eb4b"; +} +.codicon-screen-full:before { + content: "\eb4c"; +} +.codicon-screen-normal:before { + content: "\eb4d"; +} +.codicon-search-stop:before { + content: "\eb4e"; +} +.codicon-server:before { + content: "\eb50"; +} +.codicon-settings-gear:before { + content: "\eb51"; +} +.codicon-settings:before { + content: "\eb52"; +} +.codicon-shield:before { + content: "\eb53"; +} +.codicon-smiley:before { + content: "\eb54"; +} +.codicon-sort-precedence:before { + content: "\eb55"; +} +.codicon-split-horizontal:before { + content: "\eb56"; +} +.codicon-split-vertical:before { + content: "\eb57"; +} +.codicon-squirrel:before { + content: "\eb58"; +} +.codicon-star-full:before { + content: "\eb59"; +} +.codicon-star-half:before { + content: "\eb5a"; +} +.codicon-symbol-class:before { + content: "\eb5b"; +} +.codicon-symbol-color:before { + content: "\eb5c"; +} +.codicon-symbol-constant:before { + content: "\eb5d"; +} +.codicon-symbol-enum-member:before { + content: "\eb5e"; +} +.codicon-symbol-field:before { + content: "\eb5f"; +} +.codicon-symbol-file:before { + content: "\eb60"; +} +.codicon-symbol-interface:before { + content: "\eb61"; +} +.codicon-symbol-keyword:before { + content: "\eb62"; +} +.codicon-symbol-misc:before { + content: "\eb63"; +} +.codicon-symbol-operator:before { + content: "\eb64"; +} +.codicon-symbol-property:before { + content: "\eb65"; +} +.codicon-wrench:before { + content: "\eb65"; +} +.codicon-wrench-subaction:before { + content: "\eb65"; +} +.codicon-symbol-snippet:before { + content: "\eb66"; +} +.codicon-tasklist:before { + content: "\eb67"; +} +.codicon-telescope:before { + content: "\eb68"; +} +.codicon-text-size:before { + content: "\eb69"; +} +.codicon-three-bars:before { + content: "\eb6a"; +} +.codicon-thumbsdown:before { + content: "\eb6b"; +} +.codicon-thumbsup:before { + content: "\eb6c"; +} +.codicon-tools:before { + content: "\eb6d"; +} +.codicon-triangle-down:before { + content: "\eb6e"; +} +.codicon-triangle-left:before { + content: "\eb6f"; +} +.codicon-triangle-right:before { + content: "\eb70"; +} +.codicon-triangle-up:before { + content: "\eb71"; +} +.codicon-twitter:before { + content: "\eb72"; +} +.codicon-unfold:before { + content: "\eb73"; +} +.codicon-unlock:before { + content: "\eb74"; +} +.codicon-unmute:before { + content: "\eb75"; +} +.codicon-unverified:before { + content: "\eb76"; +} +.codicon-verified:before { + content: "\eb77"; +} +.codicon-versions:before { + content: "\eb78"; +} +.codicon-vm-active:before { + content: "\eb79"; +} +.codicon-vm-outline:before { + content: "\eb7a"; +} +.codicon-vm-running:before { + content: "\eb7b"; +} +.codicon-watch:before { + content: "\eb7c"; +} +.codicon-whitespace:before { + content: "\eb7d"; +} +.codicon-whole-word:before { + content: "\eb7e"; +} +.codicon-window:before { + content: "\eb7f"; +} +.codicon-word-wrap:before { + content: "\eb80"; +} +.codicon-zoom-in:before { + content: "\eb81"; +} +.codicon-zoom-out:before { + content: "\eb82"; +} +.codicon-list-filter:before { + content: "\eb83"; +} +.codicon-list-flat:before { + content: "\eb84"; +} +.codicon-list-selection:before { + content: "\eb85"; +} +.codicon-selection:before { + content: "\eb85"; +} +.codicon-list-tree:before { + content: "\eb86"; +} +.codicon-debug-breakpoint-function-unverified:before { + content: "\eb87"; +} +.codicon-debug-breakpoint-function:before { + content: "\eb88"; +} +.codicon-debug-breakpoint-function-disabled:before { + content: "\eb88"; +} +.codicon-debug-stackframe-active:before { + content: "\eb89"; +} +.codicon-debug-stackframe-dot:before { + content: "\eb8a"; +} +.codicon-debug-stackframe:before { + content: "\eb8b"; +} +.codicon-debug-stackframe-focused:before { + content: "\eb8b"; +} +.codicon-debug-breakpoint-unsupported:before { + content: "\eb8c"; +} +.codicon-symbol-string:before { + content: "\eb8d"; +} +.codicon-debug-reverse-continue:before { + content: "\eb8e"; +} +.codicon-debug-step-back:before { + content: "\eb8f"; +} +.codicon-debug-restart-frame:before { + content: "\eb90"; +} +.codicon-debug-alt:before { + content: "\eb91"; +} +.codicon-call-incoming:before { + content: "\eb92"; +} +.codicon-call-outgoing:before { + content: "\eb93"; +} +.codicon-menu:before { + content: "\eb94"; +} +.codicon-expand-all:before { + content: "\eb95"; +} +.codicon-feedback:before { + content: "\eb96"; +} +.codicon-group-by-ref-type:before { + content: "\eb97"; +} +.codicon-ungroup-by-ref-type:before { + content: "\eb98"; +} +.codicon-account:before { + content: "\eb99"; +} +.codicon-bell-dot:before { + content: "\eb9a"; +} +.codicon-debug-console:before { + content: "\eb9b"; +} +.codicon-library:before { + content: "\eb9c"; +} +.codicon-output:before { + content: "\eb9d"; +} +.codicon-run-all:before { + content: "\eb9e"; +} +.codicon-sync-ignored:before { + content: "\eb9f"; +} +.codicon-pinned:before { + content: "\eba0"; +} +.codicon-github-inverted:before { + content: "\eba1"; +} +.codicon-server-process:before { + content: "\eba2"; +} +.codicon-server-environment:before { + content: "\eba3"; +} +.codicon-pass:before { + content: "\eba4"; +} +.codicon-issue-closed:before { + content: "\eba4"; +} +.codicon-stop-circle:before { + content: "\eba5"; +} +.codicon-play-circle:before { + content: "\eba6"; +} +.codicon-record:before { + content: "\eba7"; +} +.codicon-debug-alt-small:before { + content: "\eba8"; +} +.codicon-vm-connect:before { + content: "\eba9"; +} +.codicon-cloud:before { + content: "\ebaa"; +} +.codicon-merge:before { + content: "\ebab"; +} +.codicon-export:before { + content: "\ebac"; +} +.codicon-graph-left:before { + content: "\ebad"; +} +.codicon-magnet:before { + content: "\ebae"; +} +.codicon-notebook:before { + content: "\ebaf"; +} +.codicon-redo:before { + content: "\ebb0"; +} +.codicon-check-all:before { + content: "\ebb1"; +} +.codicon-pinned-dirty:before { + content: "\ebb2"; +} +.codicon-pass-filled:before { + content: "\ebb3"; +} +.codicon-circle-large-filled:before { + content: "\ebb4"; +} +.codicon-circle-large-outline:before { + content: "\ebb5"; +} +.codicon-combine:before { + content: "\ebb6"; +} +.codicon-gather:before { + content: "\ebb6"; +} +.codicon-table:before { + content: "\ebb7"; +} +.codicon-variable-group:before { + content: "\ebb8"; +} +.codicon-type-hierarchy:before { + content: "\ebb9"; +} +.codicon-type-hierarchy-sub:before { + content: "\ebba"; +} +.codicon-type-hierarchy-super:before { + content: "\ebbb"; +} +.codicon-git-pull-request-create:before { + content: "\ebbc"; +} +.codicon-run-above:before { + content: "\ebbd"; +} +.codicon-run-below:before { + content: "\ebbe"; +} +.codicon-notebook-template:before { + content: "\ebbf"; +} +.codicon-debug-rerun:before { + content: "\ebc0"; +} +.codicon-workspace-trusted:before { + content: "\ebc1"; +} +.codicon-workspace-untrusted:before { + content: "\ebc2"; +} +.codicon-workspace-unknown:before { + content: "\ebc3"; +} +.codicon-terminal-cmd:before { + content: "\ebc4"; +} +.codicon-terminal-debian:before { + content: "\ebc5"; +} +.codicon-terminal-linux:before { + content: "\ebc6"; +} +.codicon-terminal-powershell:before { + content: "\ebc7"; +} +.codicon-terminal-tmux:before { + content: "\ebc8"; +} +.codicon-terminal-ubuntu:before { + content: "\ebc9"; +} +.codicon-terminal-bash:before { + content: "\ebca"; +} +.codicon-arrow-swap:before { + content: "\ebcb"; +} +.codicon-copy:before { + content: "\ebcc"; +} +.codicon-person-add:before { + content: "\ebcd"; +} +.codicon-filter-filled:before { + content: "\ebce"; +} +.codicon-wand:before { + content: "\ebcf"; +} +.codicon-debug-line-by-line:before { + content: "\ebd0"; +} +.codicon-inspect:before { + content: "\ebd1"; +} +.codicon-layers:before { + content: "\ebd2"; +} +.codicon-layers-dot:before { + content: "\ebd3"; +} +.codicon-layers-active:before { + content: "\ebd4"; +} +.codicon-compass:before { + content: "\ebd5"; +} +.codicon-compass-dot:before { + content: "\ebd6"; +} +.codicon-compass-active:before { + content: "\ebd7"; +} +.codicon-azure:before { + content: "\ebd8"; +} +.codicon-issue-draft:before { + content: "\ebd9"; +} +.codicon-git-pull-request-closed:before { + content: "\ebda"; +} +.codicon-git-pull-request-draft:before { + content: "\ebdb"; +} +.codicon-debug-all:before { + content: "\ebdc"; +} +.codicon-debug-coverage:before { + content: "\ebdd"; +} +.codicon-run-errors:before { + content: "\ebde"; +} +.codicon-folder-library:before { + content: "\ebdf"; +} +.codicon-debug-continue-small:before { + content: "\ebe0"; +} +.codicon-beaker-stop:before { + content: "\ebe1"; +} +.codicon-graph-line:before { + content: "\ebe2"; +} +.codicon-graph-scatter:before { + content: "\ebe3"; +} +.codicon-pie-chart:before { + content: "\ebe4"; +} +.codicon-bracket:before { + content: "\eb0f"; +} +.codicon-bracket-dot:before { + content: "\ebe5"; +} +.codicon-bracket-error:before { + content: "\ebe6"; +} +.codicon-lock-small:before { + content: "\ebe7"; +} +.codicon-azure-devops:before { + content: "\ebe8"; +} +.codicon-verified-filled:before { + content: "\ebe9"; +} +.codicon-newline:before { + content: "\ebea"; +} +.codicon-layout:before { + content: "\ebeb"; +} +.codicon-layout-activitybar-left:before { + content: "\ebec"; +} +.codicon-layout-activitybar-right:before { + content: "\ebed"; +} +.codicon-layout-panel-left:before { + content: "\ebee"; +} +.codicon-layout-panel-center:before { + content: "\ebef"; +} +.codicon-layout-panel-justify:before { + content: "\ebf0"; +} +.codicon-layout-panel-right:before { + content: "\ebf1"; +} +.codicon-layout-panel:before { + content: "\ebf2"; +} +.codicon-layout-sidebar-left:before { + content: "\ebf3"; +} +.codicon-layout-sidebar-right:before { + content: "\ebf4"; +} +.codicon-layout-statusbar:before { + content: "\ebf5"; +} +.codicon-layout-menubar:before { + content: "\ebf6"; +} +.codicon-layout-centered:before { + content: "\ebf7"; +} +.codicon-target:before { + content: "\ebf8"; +} +.codicon-indent:before { + content: "\ebf9"; +} +.codicon-record-small:before { + content: "\ebfa"; +} +.codicon-error-small:before { + content: "\ebfb"; +} +.codicon-arrow-circle-down:before { + content: "\ebfc"; +} +.codicon-arrow-circle-left:before { + content: "\ebfd"; +} +.codicon-arrow-circle-right:before { + content: "\ebfe"; +} +.codicon-arrow-circle-up:before { + content: "\ebff"; +} +.codicon-layout-sidebar-right-off:before { + content: "\ec00"; +} +.codicon-layout-panel-off:before { + content: "\ec01"; +} +.codicon-layout-sidebar-left-off:before { + content: "\ec02"; +} +.codicon-blank:before { + content: "\ec03"; +} diff --git a/src/renderer/less/codicon.svg b/src/renderer/less/codicon.svg new file mode 100644 index 00000000..c0bb5a8d --- /dev/null +++ b/src/renderer/less/codicon.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol fill="currentColor" viewBox="0 0 16 16" id="account" xmlns="http://www.w3.org/2000/svg"><path d="M16 7.992C16 3.58 12.416 0 8 0S0 3.58 0 7.992c0 2.43 1.104 4.62 2.832 6.09.016.016.032.016.032.032.144.112.288.224.448.336.08.048.144.111.224.175A7.98 7.98 0 008.016 16a7.98 7.98 0 004.48-1.375c.08-.048.144-.111.224-.16.144-.111.304-.223.448-.335.016-.016.032-.016.032-.032 1.696-1.487 2.8-3.676 2.8-6.106zm-8 7.001c-1.504 0-2.88-.48-4.016-1.279.016-.128.048-.255.08-.383a4.17 4.17 0 01.416-.991c.176-.304.384-.576.64-.816.24-.24.528-.463.816-.639.304-.176.624-.304.976-.4A4.15 4.15 0 018 10.342a4.185 4.185 0 012.928 1.166c.368.368.656.8.864 1.295.112.288.192.592.24.911A7.03 7.03 0 018 14.993zm-2.448-7.4a2.49 2.49 0 01-.208-1.024c0-.351.064-.703.208-1.023.144-.32.336-.607.576-.847.24-.24.528-.431.848-.575.32-.144.672-.208 1.024-.208.368 0 .704.064 1.024.208.32.144.608.336.848.575.24.24.432.528.576.847.144.32.208.672.208 1.023 0 .368-.064.704-.208 1.023a2.84 2.84 0 01-.576.848 2.84 2.84 0 01-.848.575 2.715 2.715 0 01-2.064 0 2.84 2.84 0 01-.848-.575 2.526 2.526 0 01-.56-.848zm7.424 5.306c0-.032-.016-.048-.016-.08a5.22 5.22 0 00-.688-1.406 4.883 4.883 0 00-1.088-1.135 5.207 5.207 0 00-1.04-.608 2.82 2.82 0 00.464-.383 4.2 4.2 0 00.624-.784 3.624 3.624 0 00.528-1.934 3.71 3.71 0 00-.288-1.47 3.799 3.799 0 00-.816-1.199 3.845 3.845 0 00-1.2-.8 3.72 3.72 0 00-1.472-.287 3.72 3.72 0 00-1.472.288 3.631 3.631 0 00-1.2.815 3.84 3.84 0 00-.8 1.199 3.71 3.71 0 00-.288 1.47c0 .352.048.688.144 1.007.096.336.224.64.4.927.16.288.384.544.624.784.144.144.304.271.48.383a5.12 5.12 0 00-1.04.624c-.416.32-.784.703-1.088 1.119a4.999 4.999 0 00-.688 1.406c-.016.032-.016.064-.016.08C1.776 11.636.992 9.91.992 7.992.992 4.14 4.144.991 8 .991s7.008 3.149 7.008 7.001a6.96 6.96 0 01-2.032 4.907z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="activate-breakpoints" xmlns="http://www.w3.org/2000/svg"><path d="M15 5.5a4.394 4.394 0 01-4 4.5 2.955 2.955 0 00-.2-1A3.565 3.565 0 0014 5.5a3.507 3.507 0 00-7-.3A3.552 3.552 0 006 5a4.622 4.622 0 014.5-4A4.481 4.481 0 0115 5.5zM5.5 6a4.5 4.5 0 100 9.001 4.5 4.5 0 000-9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="add" xmlns="http://www.w3.org/2000/svg"><path d="M14 7v1H8v6H7V8H1V7h6V1h1v6h6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="alert" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.56 1h.88l6.54 12.26-.44.74H1.44L1 13.26 7.56 1zM8 2.28L2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="archive" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 1h-13l-.5.5v3l.5.5H2v8.5l.5.5h11l.5-.5V5h.5l.5-.5v-3l-.5-.5zm-1 3H2V2h12v2h-.5zM3 13V5h10v8H3zm8-6H5v1h6V7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="array" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2l-.5.5v11l.5.5H4v-1H2V3h2V2H1.5zm13 12l.5-.5v-11l-.5-.5H12v1h2v10h-2v1h2.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-both" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 9l2.146 2.146-.707.708-3-3v-.708l3-3 .707.708L3 8h10l-2.146-2.146.707-.708 3 3v.708l-3 3-.707-.707L13 9H3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-circle-down" xmlns="http://www.w3.org/2000/svg"><path d="M5.369 8.08l2.14 2.14V4.468h1v5.68l2.066-2.067.707.707-2.957 2.956h-.707L4.662 8.788l.707-.707z"/><path d="M14 8A6 6 0 102 8a6 6 0 0012 0zm-1 0A5 5 0 113 8a5 5 0 0110 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-circle-left" xmlns="http://www.w3.org/2000/svg"><path d="M7.92 10.631l-2.14-2.14h5.752v-1h-5.68L7.92 5.426l-.707-.707-2.956 2.957v.707l2.956 2.956.707-.707z"/><path d="M8 2a6 6 0 110 12A6 6 0 018 2zm0 1a5 5 0 100 10A5 5 0 008 3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-circle-right" xmlns="http://www.w3.org/2000/svg"><path d="M8.08 5.369l2.14 2.14H4.468v1h5.68L8.08 10.574l.707.707 2.956-2.957v-.707L8.788 4.662l-.707.707z"/><path d="M8 14A6 6 0 118 2a6 6 0 010 12zm0-1A5 5 0 108 3a5 5 0 000 10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-circle-up" xmlns="http://www.w3.org/2000/svg"><path d="M5.369 7.92l2.14-2.14v5.752h1v-5.68l2.066 2.067.707-.707-2.957-2.956h-.707L4.662 7.212l.707.707z"/><path d="M14 8A6 6 0 112 8a6 6 0 0112 0zm-1 0A5 5 0 103 8a5 5 0 0010 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-down" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.147 9l5 5h.707l5-5-.707-.707L9 12.439V2H8v10.44L3.854 8.292 3.147 9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-left" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 3.093l-5 5V8.8l5 5 .707-.707-4.146-4.147H14v-1H3.56L7.708 3.8 7 3.093z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-right" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9 13.887l5-5V8.18l-5-5-.707.707 4.146 4.147H2v1h10.44L8.292 13.18l.707.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-small-down" xmlns="http://www.w3.org/2000/svg"><path d="M10.7 8.64l-2.5 2.5h-.7L5 8.64l.7-.71 1.65 1.64V4h1v5.57L10 7.92l.7.72z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-small-left" xmlns="http://www.w3.org/2000/svg"><path d="M6.5 10.7L4 8.2v-.7L6.5 5l.71.7-1.64 1.65h5.57v1H5.57L7.22 10l-.72.7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-small-right" xmlns="http://www.w3.org/2000/svg"><path d="M8.64 5l2.5 2.5v.7l-2.5 2.5-.71-.7 1.64-1.65H4v-1h5.57L7.92 5.7l.72-.7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-small-up" xmlns="http://www.w3.org/2000/svg"><path d="M5 6.5L7.5 4h.7l2.5 2.5-.7.71-1.65-1.64v5.57h-1V5.57L5.7 7.22 5 6.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-swap" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.207 15.061L1 11.854v-.707L4.207 7.94l.707.707-2.353 2.354H15v1H2.56l2.354 2.353-.707.707zm7.586-7L15 4.854v-.707L11.793.94l-.707.707L13.439 4H1v1h12.44l-2.354 2.354.707.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="arrow-up" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.854 7l-5-5h-.707l-5 5 .707.707L8 3.561V14h1V3.56l4.146 4.147.708-.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="azure" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.37 13.68l-4-12a1 1 0 00-1-.68H5.63a1 1 0 00-.95.68l-4.05 12a1 1 0 001 1.32h2.93a1 1 0 00.94-.68l.61-1.78 3 2.27a1 1 0 00.6.19h4.68a1 1 0 00.98-1.32zm-5.62.66a.32.32 0 01-.2-.07L3.9 10.08l-.09-.07h3l.08-.21 1-2.53 2.24 6.63a.34.34 0 01-.38.44zm4.67 0H10.7a1 1 0 000-.66l-4.05-12h3.72a.34.34 0 01.32.23l4.05 12a.34.34 0 01-.32.43z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="azure-devops" xmlns="http://www.w3.org/2000/svg"><path d="M15 3.622v8.512L11.5 15l-5.425-1.975v1.957l-3.071-4.01 8.951.698V4.006L15 3.622zm-2.984.428L6.994 1v2.001L2.383 4.356 1 6.13v4.029l1.978.873V5.869l9.038-1.818z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="beaker" xmlns="http://www.w3.org/2000/svg"><path d="M13.893 13.558L10 6.006v-4h1v-1H9.994V1l-.456.005H5V2h1v3.952l-3.894 7.609A1 1 0 003 15.006h10a1 1 0 00.893-1.448zm-7-7.15L7 6.193V2.036l2-.024v4.237l.11.215 1.827 3.542H5.049l1.844-3.598zM3 14.017l1.54-3.011h6.916l1.547 3L3 14.017z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="beaker-stop" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 15.006h5.007a5.03 5.03 0 01-.998-.993L3 14.017l1.542-3.011H6V11c0-.34.034-.673.099-.994h-1.05l1.844-3.598L7 6.193V2.036l2-.024v4.237l.07.137c.31-.13.636-.23.974-.295L10 6.006v-4h1v-1H9.994V1l-.456.005H5V2h1v3.952l-3.894 7.609A1 1 0 003 15.006zm5.778-7.332a4 4 0 114.444 6.652 4 4 0 01-4.444-6.652zm.1 5.447A3 3 0 0011 14a3 3 0 001.74-.55L8.55 9.26A3 3 0 008 11a3 3 0 00.879 2.121zm.382-4.57l4.19 4.189A3 3 0 0014 11a3 3 0 00-3-3 3 3 0 00-1.74.55z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bell" xmlns="http://www.w3.org/2000/svg"><path d="M13.377 10.573a7.63 7.63 0 01-.383-2.38V6.195a5.115 5.115 0 00-1.268-3.446 5.138 5.138 0 00-3.242-1.722c-.694-.072-1.4 0-2.07.227-.67.215-1.28.574-1.794 1.053a4.923 4.923 0 00-1.208 1.675 5.067 5.067 0 00-.431 2.022v2.2a7.61 7.61 0 01-.383 2.37L2 12.343l.479.658h3.505c0 .526.215 1.04.586 1.412.37.37.885.586 1.412.586.526 0 1.04-.215 1.411-.586s.587-.886.587-1.412h3.505l.478-.658-.586-1.77zm-4.69 3.147a.997.997 0 01-.705.299.997.997 0 01-.706-.3.997.997 0 01-.3-.705h1.999a.939.939 0 01-.287.706zm-5.515-1.71l.371-1.114a8.633 8.633 0 00.443-2.691V6.004c0-.563.12-1.113.347-1.616.227-.514.55-.969.969-1.34.419-.382.91-.67 1.436-.837.538-.18 1.1-.24 1.65-.18a4.147 4.147 0 012.597 1.4 4.133 4.133 0 011.004 2.776v2.01c0 .909.144 1.818.443 2.691l.371 1.113h-9.63v-.012z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bell-dot" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13 8.9c.1.6.2 1.1.4 1.7l.6 1.7-.5.7H10c0 .5-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.5 0-1.1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4H2.5l-.5-.7.6-1.7c.2-.8.4-1.6.4-2.4V6c0-.7.1-1.4.4-2 .3-.7.7-1.2 1.2-1.7s1.1-.8 1.8-1C6.9 1.1 7.5 1 8 1c-.2.3-.4.7-.6 1.1-.2 0-.4 0-.7.2-.5.1-1 .4-1.4.8-.4.3-.8.8-1 1.3-.2.5-.3 1-.3 1.6v2.2c0 .9-.2 1.8-.4 2.7L3.2 12h9.6l-.4-1.1c-.175-.526-.274-1.13-.363-1.674L12 9c.4 0 .7 0 1-.1zM8 14c.2 0 .5-.1.7-.3.2-.2.3-.4.3-.7H7c0 .3.1.5.3.7.2.2.5.3.7.3zm7-10a3 3 0 11-6 0 3 3 0 016 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bold" xmlns="http://www.w3.org/2000/svg"><path d="M5 13V3h3.362c1.116 0 1.954.224 2.515.673.565.449.848 1.113.848 1.992 0 .467-.137.881-.41 1.243-.273.357-.645.634-1.116.831.556.151.993.44 1.314.865.325.422.487.925.487 1.511 0 .898-.299 1.603-.897 2.116-.598.513-1.443.769-2.536.769H5zm1.356-4.677v3.599h2.24c.63 0 1.127-.158 1.49-.474.367-.32.55-.76.55-1.319 0-1.204-.673-1.806-2.02-1.806h-2.26zm0-1.058h2.049c.593 0 1.066-.144 1.42-.433.357-.288.536-.68.536-1.174 0-.55-.165-.948-.494-1.195-.33-.252-.831-.378-1.505-.378H6.356v3.18z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="book" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 2H9l-.35.15-.65.64-.65-.64L7 2H1.5l-.5.5v10l.5.5h5.29l.86.85h.7l.86-.85h5.29l.5-.5v-10l-.5-.5zm-7 10.32l-.18-.17L7 12H2V3h4.79l.74.74-.03 8.58zM14 12H9l-.35.15-.14.13V3.7l.7-.7H14v9zM6 5H3v1h3V5zm0 4H3v1h3V9zM3 7h3v1H3V7zm10-2h-3v1h3V5zm-3 2h3v1h-3V7zm0 2h3v1h-3V9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bookmark" xmlns="http://www.w3.org/2000/svg"><path d="M12.5 1h-9l-.5.5v13l.872.335L8 10.247l4.128 4.588L13 14.5v-13l-.5-.5zM12 13.2L8.372 9.165h-.744L4 13.2V2h8v11.2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bracket" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.984V2h-.09c-.313 0-.616.062-.909.185a2.33 2.33 0 00-.775.53 2.23 2.23 0 00-.493.753v.001a3.542 3.542 0 00-.198.83v.002a6.08 6.08 0 00-.024.863c.012.29.018.58.018.869 0 .203-.04.393-.117.572v.001a1.504 1.504 0 01-.765.787 1.376 1.376 0 01-.558.115H2v.984h.09c.195 0 .38.04.556.121l.001.001c.178.078.329.184.455.318l.002.002c.13.13.233.285.307.465l.001.002c.078.18.117.368.117.566 0 .29-.006.58-.018.869-.012.296-.004.585.024.87v.001c.033.283.099.558.197.824v.001c.106.273.271.524.494.753.223.23.482.407.775.53.293.123.596.185.91.185H6v-.984h-.09c-.2 0-.387-.038-.563-.115a1.613 1.613 0 01-.457-.32 1.659 1.659 0 01-.309-.467c-.074-.18-.11-.37-.11-.573 0-.228.003-.453.011-.672.008-.228.008-.45 0-.665a4.639 4.639 0 00-.055-.64 2.682 2.682 0 00-.168-.609A2.284 2.284 0 003.522 8a2.284 2.284 0 00.738-.955c.08-.192.135-.393.168-.602.033-.21.051-.423.055-.64.008-.22.008-.442 0-.666-.008-.224-.012-.45-.012-.678a1.47 1.47 0 01.877-1.354 1.33 1.33 0 01.563-.121H6zm4 10.032V14h.09c.313 0 .616-.062.909-.185.293-.123.552-.3.775-.53.223-.23.388-.48.493-.753v-.001c.1-.266.165-.543.198-.83v-.002c.028-.28.036-.567.024-.863-.012-.29-.018-.58-.018-.869 0-.203.04-.393.117-.572v-.001a1.502 1.502 0 01.765-.787 1.38 1.38 0 01.558-.115H14v-.984h-.09c-.196 0-.381-.04-.557-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.415 1.415 0 01-.307-.465v-.002a1.405 1.405 0 01-.118-.566c0-.29.006-.58.018-.869a6.174 6.174 0 00-.024-.87v-.001a3.537 3.537 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.331 2.331 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .387.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.285 2.285 0 00.738.955 2.285 2.285 0 00-.738.955 2.689 2.689 0 00-.168.602c-.033.21-.051.423-.055.64a9.15 9.15 0 000 .666c.008.224.012.45.012.678a1.471 1.471 0 01-.877 1.354 1.33 1.33 0 01-.563.121H10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bracket-dot" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.972v.012h-.09c-.199 0-.386.04-.562.121a1.468 1.468 0 00-.457.32 1.47 1.47 0 00-.42 1.035c0 .227.004.453.012.677.008.224.008.446 0 .665a4.751 4.751 0 01-.055.64c-.033.21-.089.41-.168.603A2.284 2.284 0 013.522 8a2.284 2.284 0 01.738.955c.08.193.135.395.168.608.033.206.051.42.055.64.008.216.008.438 0 .666-.008.22-.012.444-.012.672 0 .203.037.394.111.573.079.177.182.333.309.468.13.13.283.237.457.319.175.077.363.115.563.115H6V14h-.09c-.313 0-.616-.062-.909-.185a2.33 2.33 0 01-.775-.53 2.23 2.23 0 01-.493-.753v-.001a3.54 3.54 0 01-.198-.824v-.002a6.186 6.186 0 01-.024-.87c.012-.289.018-.578.018-.868 0-.198-.04-.387-.117-.566V9.4a1.414 1.414 0 00-.308-.465l-.002-.002a1.377 1.377 0 00-.455-.318h-.001a1.316 1.316 0 00-.557-.122H2v-.984h.09c.195 0 .38-.038.557-.115a1.504 1.504 0 00.765-.786v-.002c.078-.18.117-.37.117-.572 0-.29-.006-.58-.018-.869a6.08 6.08 0 01.024-.863v-.002c.033-.287.099-.564.197-.83v-.001a2.23 2.23 0 01.494-.753A2.33 2.33 0 015 2.185c.293-.123.596-.185.91-.185H6v.972zm7.923 5.52H14v-.984h-.09c-.195 0-.38-.04-.556-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.414 1.414 0 01-.307-.465l-.001-.002a1.405 1.405 0 01-.117-.566c0-.29.006-.58.018-.869a6.19 6.19 0 00-.024-.87v-.001a3.542 3.542 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.33 2.33 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .386.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.282 2.282 0 00.738.955l-.032.025c.53.058 1.03.221 1.477.467z"/><path d="M12 9a3 3 0 100 6 3 3 0 000-6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bracket-error" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.972v.012h-.09c-.199 0-.386.04-.562.121a1.468 1.468 0 00-.457.32 1.47 1.47 0 00-.42 1.035c0 .227.004.453.012.677.008.224.008.446 0 .665a4.751 4.751 0 01-.055.64c-.033.21-.089.41-.168.603A2.284 2.284 0 013.522 8a2.284 2.284 0 01.738.955c.08.193.135.395.168.608.033.206.051.42.055.64.008.216.008.438 0 .666-.008.22-.012.444-.012.672 0 .203.037.394.111.573.079.177.182.333.309.468.13.13.283.237.457.319.175.077.363.115.563.115H6V14h-.09c-.313 0-.616-.062-.909-.185a2.33 2.33 0 01-.775-.53 2.23 2.23 0 01-.493-.753v-.001a3.54 3.54 0 01-.198-.824v-.002a6.186 6.186 0 01-.024-.87c.012-.289.018-.578.018-.868 0-.198-.04-.387-.117-.566V9.4a1.414 1.414 0 00-.308-.465l-.002-.002a1.377 1.377 0 00-.455-.318h-.001a1.316 1.316 0 00-.557-.122H2v-.984h.09c.195 0 .38-.038.557-.115a1.504 1.504 0 00.765-.786v-.002c.078-.18.117-.37.117-.572 0-.29-.006-.58-.018-.869a6.08 6.08 0 01.024-.863v-.002c.033-.287.099-.564.197-.83v-.001a2.23 2.23 0 01.494-.753A2.33 2.33 0 015 2.185c.293-.123.596-.185.91-.185H6v.972zm7.923 5.52H14v-.984h-.09c-.195 0-.38-.04-.556-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.414 1.414 0 01-.307-.465l-.001-.002a1.405 1.405 0 01-.117-.566c0-.29.006-.58.018-.869a6.19 6.19 0 00-.024-.87v-.001a3.542 3.542 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.33 2.33 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .386.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.282 2.282 0 00.738.955l-.032.025c.53.058 1.03.221 1.477.467zM10.333 9.506a3 3 0 113.334 4.988 3 3 0 01-3.334-4.988zm2.813.64L12 11.293l-1.146-1.147-.707.707L11.293 12l-1.147 1.146.708.708L12 12.707l1.146 1.146.708-.707L12.707 12l1.147-1.146-.708-.708z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="briefcase" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 4H11V2.5l-.5-.5h-5l-.5.5V4H1.5l-.5.5v8l.5.5h13l.5-.5v-8l-.5-.5zM6 3h4v1H6V3zm8 2v.76L10 8v-.5L9.51 7h-3L6 7.5V8L2 5.71V5h12zM9 8v1H7V8h2zm-7 4V6.86l4 2.29v.35l.5.5h3l.5-.5v-.31l4-2.28V12H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="broadcast" xmlns="http://www.w3.org/2000/svg"><path d="M4.667 2.011A6 6 0 018 1a6.007 6.007 0 016 6 6 6 0 01-3.996 5.655v-.044c.016-.014.031-.03.046-.045a1.48 1.48 0 00.434-1.046v-.137A5.042 5.042 0 0012.19 4.2a5.04 5.04 0 10-6.69 7.176v.144a1.48 1.48 0 00.48 1.09v.04A5.999 5.999 0 014.667 2.01z"/><path d="M9.343 11.86a.48.48 0 01-.34.14v2.52a.48.48 0 01-.48.48H7.46c.011 0-.004-.004-.034-.012-.075-.02-.241-.064-.305-.129a.48.48 0 01-.141-.34V12a.48.48 0 01-.48-.48V9.5a1 1 0 011-1h.984a1 1 0 011 1v2.02a.48.48 0 01-.137.335l-.004.004z"/><path d="M10.64 7c0 .525-.157 1.034-.445 1.465.183.302.289.656.289 1.035v.106a3.596 3.596 0 00.06-5.15A3.6 3.6 0 105.5 9.59V9.5c0-.384.108-.743.296-1.047A2.64 2.64 0 1110.64 7z"/><path d="M9 7a1 1 0 11-2 0 1 1 0 012 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="browser" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h13l.5.5v12l-.5.5h-13l-.5-.5v-12l.5-.5zM2 5v8h12V5H2zm0-1h12V2H2v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="bug" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.877 4.5v-.582a2.918 2.918 0 10-5.836 0V4.5h-.833L2.545 2.829l-.593.59 1.611 1.619-.019.049a8.03 8.03 0 00-.503 2.831c0 .196.007.39.02.58l.003.045H1v.836h2.169l.006.034c.172.941.504 1.802.954 2.531l.034.055L2.2 13.962l.592.592 1.871-1.872.058.066c.868.992 2.002 1.589 3.238 1.589 1.218 0 2.336-.579 3.199-1.544l.057-.064 1.91 1.92.593-.591-1.996-2.006.035-.056c.467-.74.81-1.619.986-2.583l.006-.034h2.171v-.836h-2.065l.003-.044a8.43 8.43 0 00.02-.58 8.02 8.02 0 00-.517-2.866l-.019-.05 1.57-1.57-.592-.59L11.662 4.5h-.785zm-5 0v-.582a2.082 2.082 0 114.164 0V4.5H5.878zm5.697.837l.02.053c.283.753.447 1.61.447 2.528 0 1.61-.503 3.034-1.274 4.037-.77 1.001-1.771 1.545-2.808 1.545-1.036 0-2.037-.544-2.807-1.545-.772-1.003-1.275-2.427-1.275-4.037 0-.918.164-1.775.448-2.528l.02-.053h7.229z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="calendar" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 2H13V1h-1v1H4V1H3v1H1.5l-.5.5v12l.5.5h13l.5-.5v-12l-.5-.5zM14 14H2V5h12v9zm0-10H2V3h12v1zM4 8H3v1h1V8zm-1 2h1v1H3v-1zm1 2H3v1h1v-1zm2-4h1v1H6V8zm1 2H6v1h1v-1zm-1 2h1v1H6v-1zm1-6H6v1h1V6zm2 2h1v1H9V8zm1 2H9v1h1v-1zm-1 2h1v1H9v-1zm1-6H9v1h1V6zm2 2h1v1h-1V8zm1 2h-1v1h1v-1zm-1-4h1v1h-1V6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="call-incoming" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.547 9.328a1.567 1.567 0 00-.594-.117 1.202 1.202 0 00-.555.101 2.762 2.762 0 00-.43.258 2.166 2.166 0 00-.359.328c-.104.12-.205.23-.304.329a2.409 2.409 0 01-.29.25.534.534 0 01-.695-.063 32.17 32.17 0 01-.328-.312c-.14-.136-.312-.3-.515-.493A61.776 61.776 0 017.844 9l-.68-.664a25.847 25.847 0 01-1.21-1.266 5.312 5.312 0 01-.391-.484c-.094-.135-.141-.234-.141-.297a.46.46 0 01.101-.312c.073-.094.16-.19.258-.29.1-.098.209-.203.328-.312.12-.11.23-.227.329-.352.098-.125.182-.268.25-.43.067-.16.101-.343.101-.546a1.567 1.567 0 00-.453-1.102 7.604 7.604 0 01-.531-.578 6.487 6.487 0 00-.617-.64 4.207 4.207 0 00-.696-.516A1.46 1.46 0 003.742 1a1.567 1.567 0 00-1.101.453c-.271.271-.508.513-.711.727a4.006 4.006 0 00-.516.664 2.63 2.63 0 00-.312.765A4.39 4.39 0 001 4.625c0 .552.089 1.125.266 1.719.177.593.416 1.185.718 1.773.302.589.67 1.167 1.102 1.735.432.567.901 1.106 1.406 1.617.505.51 1.042.982 1.61 1.414.567.432 1.148.805 1.742 1.117.593.313 1.19.557 1.789.734a6.157 6.157 0 001.75.266 4.696 4.696 0 001.008-.11 2.59 2.59 0 00.773-.312c.23-.14.45-.312.664-.515.214-.204.453-.438.719-.704A1.568 1.568 0 0015 12.257a2.009 2.009 0 00-.102-.515 1.674 1.674 0 00-.257-.484 7.24 7.24 0 00-.368-.445 5.381 5.381 0 00-.421-.422 91.549 91.549 0 00-.43-.383 8.277 8.277 0 01-.367-.344 1.516 1.516 0 00-.508-.336zm-.367 4.586a3.13 3.13 0 01-.797.086 5.526 5.526 0 01-1.516-.242 8.362 8.362 0 01-1.586-.664 13.205 13.205 0 01-3.047-2.297 17.15 17.15 0 01-1.289-1.461 10.502 10.502 0 01-1.03-1.578 9.12 9.12 0 01-.673-1.61A5.308 5.308 0 012 4.602a3.34 3.34 0 01.094-.79c.057-.218.143-.414.258-.585.114-.172.255-.339.421-.5.167-.162.357-.35.57-.563a.542.542 0 01.4-.164c.062-.005.158.036.288.125.13.089.271.195.422.32a7.058 7.058 0 01.899.899c.125.15.229.289.312.414.083.125.125.221.125.289a.429.429 0 01-.101.312c-.073.084-.16.18-.258.29-.1.109-.209.213-.328.312-.12.099-.23.216-.329.351a2.266 2.266 0 00-.25.438 1.345 1.345 0 00-.101.54c.005.213.047.413.125.6.078.188.19.355.336.5l3.726 3.727a1.527 1.527 0 001.102.46 1.2 1.2 0 00.547-.1 2.414 2.414 0 00.789-.586c.11-.12.21-.23.305-.329.093-.098.19-.182.289-.25a.545.545 0 01.312-.101c.073 0 .172.042.297.125.125.083.263.19.414.32.151.13.307.274.469.43.161.156.305.312.43.469.124.156.229.297.312.422.083.125.125.22.125.289a.533.533 0 01-.164.39c-.224.219-.414.41-.57.57a3.159 3.159 0 01-.5.422 1.93 1.93 0 01-.586.266zM15 1.704l-4.64 4.648h3.288v1h-5v-5h1V5.64L14.297 1l.703.703z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="call-outgoing" xmlns="http://www.w3.org/2000/svg"><path d="M8.648 6.648L13.29 2H10V1h5v5h-1V2.71L9.352 7.353l-.704-.704zm3.305 2.563a1.567 1.567 0 011.102.453c.11.11.232.224.367.344l.43.383c.15.135.291.276.421.421.13.146.253.295.368.446.114.15.2.312.257.484.058.172.092.344.102.516a1.568 1.568 0 01-.453 1.101c-.266.266-.505.5-.719.704a4.006 4.006 0 01-.664.515c-.23.14-.487.245-.773.313a4.696 4.696 0 01-1.008.109 6.157 6.157 0 01-1.75-.266A9.819 9.819 0 017.843 14a12.445 12.445 0 01-1.741-1.117 15.329 15.329 0 01-1.61-1.414c-.505-.51-.974-1.05-1.406-1.617a11.64 11.64 0 01-1.102-1.735 10.38 10.38 0 01-.718-1.773A6.005 6.005 0 011 4.625c0-.396.034-.734.102-1.016a2.63 2.63 0 01.312-.765c.14-.23.313-.45.516-.664.203-.214.44-.456.71-.727A1.567 1.567 0 013.743 1c.26 0 .51.07.75.21.24.142.472.313.696.517.223.203.43.416.617.64.187.224.364.417.53.578a1.567 1.567 0 01.453 1.102 1.4 1.4 0 01-.1.547 1.824 1.824 0 01-.25.43 2.983 2.983 0 01-.329.351c-.12.11-.229.214-.328.313a3.128 3.128 0 00-.258.289.46.46 0 00-.101.312c0 .063.047.162.14.297a5.3 5.3 0 00.391.484 24.386 24.386 0 001.211 1.266c.234.23.461.45.68.664.218.214.43.417.633.61.203.192.375.356.515.492.14.135.25.24.328.312a.534.534 0 00.696.063c.093-.068.19-.152.289-.25.099-.1.2-.209.304-.329.104-.12.224-.229.36-.328.135-.099.278-.185.43-.258a1.21 1.21 0 01.554-.101zM11.383 14c.318 0 .583-.029.797-.086a1.93 1.93 0 00.586-.266c.177-.12.343-.26.5-.421.156-.162.346-.352.57-.57.11-.11.164-.24.164-.391 0-.068-.042-.164-.125-.29a6.122 6.122 0 00-.313-.421 5.01 5.01 0 00-.43-.47c-.16-.155-.317-.299-.468-.429a4.322 4.322 0 00-.414-.32c-.125-.083-.224-.125-.297-.125a.545.545 0 00-.312.101 1.801 1.801 0 00-.29.25c-.093.1-.195.209-.304.329-.11.12-.23.229-.36.328-.13.099-.273.185-.43.258a1.208 1.208 0 01-.546.101 1.527 1.527 0 01-1.102-.46L4.883 7.39a1.537 1.537 0 01-.336-.5 1.655 1.655 0 01-.125-.602c0-.203.034-.383.101-.539.068-.156.151-.302.25-.438.1-.135.209-.252.329-.351.12-.099.229-.203.328-.313.099-.109.185-.205.258-.289a.429.429 0 00.101-.312c0-.068-.042-.164-.125-.29a5.085 5.085 0 00-.312-.413 6.791 6.791 0 00-.43-.469 6.787 6.787 0 00-.469-.43 5.674 5.674 0 00-.422-.32c-.13-.089-.226-.13-.289-.125a.542.542 0 00-.398.164 65.24 65.24 0 01-.57.563 3.073 3.073 0 00-.422.5 1.9 1.9 0 00-.258.586A3.377 3.377 0 002 4.601c0 .5.08 1.015.242 1.546a9.12 9.12 0 00.672 1.61c.287.541.63 1.068 1.031 1.578.401.51.831.997 1.29 1.46a13.205 13.205 0 003.046 2.298 8.37 8.37 0 001.586.664 5.526 5.526 0 001.516.242z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="case-sensitive" xmlns="http://www.w3.org/2000/svg"><path d="M8.854 11.702h-1l-.816-2.159H3.772l-.768 2.16H2L4.954 4h.935l2.965 7.702zm-2.111-2.97L5.534 5.45a3.142 3.142 0 01-.118-.515h-.021c-.036.218-.077.39-.124.515L4.073 8.732h2.67zM13.756 11.702h-.88v-.86h-.022c-.383.66-.947.99-1.692.99-.548 0-.978-.146-1.29-.436-.307-.29-.461-.675-.461-1.155 0-1.027.605-1.625 1.815-1.794l1.65-.23c0-.935-.379-1.403-1.134-1.403-.663 0-1.26.226-1.794.677V6.59c.54-.344 1.164-.516 1.87-.516 1.292 0 1.938.684 1.938 2.052v3.577zm-.88-2.782l-1.327.183c-.409.057-.717.159-.924.306-.208.143-.312.399-.312.768 0 .268.095.489.285.66.193.169.45.253.768.253a1.41 1.41 0 001.08-.457c.286-.308.43-.696.43-1.165V8.92z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="check" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.431 3.323l-8.47 10-.79-.036-3.35-4.77.818-.574 2.978 4.24 8.051-9.506.764.646z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="check-all" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.62 3.596L7.815 12.81l-.728-.033L4 8.382l.754-.53 2.744 3.907L14.917 3l.703.596z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.234 8.774l4.386-5.178L10.917 3l-4.23 4.994.547.78zm-1.55.403l.548.78-.547-.78zm-1.617 1.91l.547.78-.799.943-.728-.033L0 8.382l.754-.53 2.744 3.907.57-.672z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="checklist" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 4.48h-.71L2 3.43l.71-.7.69.68L4.81 2l.71.71-1.77 1.77zM6.99 3h8v1h-8V3zm0 3h8v1h-8V6zm8 3h-8v1h8V9zm-8 3h8v1h-8v-1zM3.04 7.48h.71l1.77-1.77-.71-.7L3.4 6.42l-.69-.69-.71.71 1.04 1.04zm.71 3.01h-.71L2 9.45l.71-.71.69.69 1.41-1.42.71.71-1.77 1.77zm-.71 3.01h.71l1.77-1.77-.71-.71-1.41 1.42-.69-.69-.71.7 1.04 1.05z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chevron-down" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.976 10.072l4.357-4.357.62.618L8.284 11h-.618L3 6.333l.619-.618 4.357 4.357z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chevron-left" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.928 7.976l4.357 4.357-.618.62L5 8.284v-.618L9.667 3l.618.619-4.357 4.357z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chevron-right" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.072 8.024L5.715 3.667l.618-.62L11 7.716v.618L6.333 13l-.618-.619 4.357-4.357z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chevron-up" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.024 5.928l-4.357 4.357-.62-.618L7.716 5h.618L13 9.667l-.619.618-4.357-4.357z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chrome-close" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.116 8l-4.558 4.558.884.884L8 8.884l4.558 4.558.884-.884L8.884 8l4.558-4.558-.884-.884L8 7.116 3.442 2.558l-.884.884L7.116 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chrome-maximize" xmlns="http://www.w3.org/2000/svg"><path d="M3 3v10h10V3H3zm9 9H4V4h8v8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chrome-minimize" xmlns="http://www.w3.org/2000/svg"><path d="M14 8v1H3V8h11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="chrome-restore" xmlns="http://www.w3.org/2000/svg"><path d="M3 5v9h9V5H3zm8 8H4V6h7v7z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 5h1V4h7v7h-1v1h2V3H5v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="circle-filled" xmlns="http://www.w3.org/2000/svg"><path d="M8 4c.367 0 .721.048 1.063.145a3.943 3.943 0 011.762 1.031 3.944 3.944 0 011.03 1.762c.097.34.145.695.145 1.062 0 .367-.048.721-.145 1.063a3.94 3.94 0 01-1.03 1.765 4.017 4.017 0 01-1.762 1.031C8.72 11.953 8.367 12 8 12s-.721-.047-1.063-.14a4.056 4.056 0 01-1.765-1.032A4.055 4.055 0 014.14 9.062 3.992 3.992 0 014 8c0-.367.047-.721.14-1.063a4.02 4.02 0 01.407-.953A4.089 4.089 0 015.98 4.546a3.94 3.94 0 01.957-.401A3.89 3.89 0 018 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="circle-large-filled" xmlns="http://www.w3.org/2000/svg"><path d="M8 1a6.8 6.8 0 011.86.253 6.899 6.899 0 013.083 1.805 6.903 6.903 0 011.804 3.083C14.916 6.738 15 7.357 15 8s-.084 1.262-.253 1.86a6.9 6.9 0 01-.704 1.674 7.157 7.157 0 01-2.516 2.509 6.966 6.966 0 01-1.668.71A6.984 6.984 0 018 15a6.984 6.984 0 01-1.86-.246 7.098 7.098 0 01-1.674-.711 7.3 7.3 0 01-1.415-1.094 7.295 7.295 0 01-1.094-1.415 7.098 7.098 0 01-.71-1.675A6.985 6.985 0 011 8c0-.643.082-1.262.246-1.86a6.968 6.968 0 01.711-1.667 7.156 7.156 0 012.509-2.516 6.895 6.895 0 011.675-.704A6.808 6.808 0 018 1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="circle-large-outline" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.588 2.215A5.808 5.808 0 008 2c-.554 0-1.082.073-1.588.215l-.006.002c-.514.141-.99.342-1.432.601A6.156 6.156 0 002.82 4.98l-.002.004A5.967 5.967 0 002.21 6.41 5.986 5.986 0 002 8c0 .555.07 1.085.21 1.591a6.05 6.05 0 001.548 2.651c.37.365.774.677 1.216.94a6.1 6.1 0 001.435.609A6.02 6.02 0 008 14c.555 0 1.085-.07 1.591-.21.515-.145.99-.348 1.426-.607l.004-.002a6.16 6.16 0 002.161-2.155 5.85 5.85 0 00.6-1.432l.003-.006A5.807 5.807 0 0014 8c0-.554-.072-1.082-.215-1.588l-.002-.006a5.772 5.772 0 00-.6-1.423l-.002-.004a5.9 5.9 0 00-.942-1.21l-.008-.008a5.902 5.902 0 00-1.21-.942l-.004-.002a5.772 5.772 0 00-1.423-.6l-.006-.002zm4.455 9.32a7.157 7.157 0 01-2.516 2.508 6.966 6.966 0 01-1.668.71A6.984 6.984 0 018 15a6.984 6.984 0 01-1.86-.246 7.098 7.098 0 01-1.674-.711 7.3 7.3 0 01-1.415-1.094 7.295 7.295 0 01-1.094-1.415 7.098 7.098 0 01-.71-1.675A6.985 6.985 0 011 8c0-.643.082-1.262.246-1.86a6.968 6.968 0 01.711-1.667 7.156 7.156 0 012.509-2.516 6.895 6.895 0 011.675-.704A6.808 6.808 0 018 1a6.8 6.8 0 011.86.253 6.899 6.899 0 013.083 1.805 6.903 6.903 0 011.804 3.083C14.916 6.738 15 7.357 15 8s-.084 1.262-.253 1.86a6.9 6.9 0 01-.704 1.674z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="circle-outline" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 12a4 4 0 100-8 4 4 0 000 8zm2.61-4a2.61 2.61 0 11-5.22 0 2.61 2.61 0 015.22 0zM8 5.246z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="circle-slash" xmlns="http://www.w3.org/2000/svg"><path d="M8 1a7 7 0 11-7 7 7.008 7.008 0 017-7zM2 8c0 1.418.504 2.79 1.423 3.87l8.447-8.447A5.993 5.993 0 002 8zm12 0c0-1.418-.504-2.79-1.423-3.87L4.13 12.577A5.993 5.993 0 0014 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="circuit-board" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 1h-13l-.5.5v13l.5.5h13l.5-.5v-13l-.5-.5zM14 14H5v-2h2.3c.3.6 1 1 1.7 1 1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2H4v3H2V2h2v2.3c-.6.3-1 1-1 1.7 0 1.1.9 2 2 2s2-.9 2-2h2c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2c-.7 0-1.4.4-1.7 1H6.7c-.3-.6-1-1-1.7-1V2h9v12zm-6-3c0-.6.4-1 1-1s1 .4 1 1-.4 1-1 1-1-.4-1-1zM5 5c.6 0 1 .4 1 1s-.4 1-1 1-1-.4-1-1 .4-1 1-1zm6 0c.6 0 1 .4 1 1s-.4 1-1 1-1-.4-1-1 .4-1 1-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="clear-all" xmlns="http://www.w3.org/2000/svg"><path d="M10 12.6l.7.7 1.6-1.6 1.6 1.6.8-.7L13 11l1.7-1.6-.8-.8-1.6 1.7-1.6-1.7-.7.8 1.6 1.6-1.6 1.6zM1 4h14V3H1v1zm0 3h14V6H1v1zm8 2.5V9H1v1h8v-.5zM9 13v-1H1v1h8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="clippy" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 13.992H4v-9h8v2h1v-2.5l-.5-.5H11v-1h-1a2 2 0 00-4 0H4.94v1H3.5l-.5.5v10l.5.5H7v-1zm0-11.2a1 1 0 01.8-.8 1 1 0 01.58.06.94.94 0 01.45.36 1 1 0 11-1.75.94 1 1 0 01-.08-.56zm7.08 9.46L13 13.342v-5.35h-1v5.34l-1.08-1.08-.71.71 1.94 1.93h.71l1.93-1.93-.71-.71zm-5.92-4.16h.71l1.93 1.93-.71.71-1.08-1.08v5.34h-1v-5.35l-1.08 1.09-.71-.71 1.94-1.93z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="clock" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.507 12.324a7 7 0 00.065-8.56A7 7 0 002 4.393V2H1v3.5l.5.5H5V5H2.811a6.008 6.008 0 11-.135 5.77l-.887.462a7 7 0 0011.718 1.092zm-3.361-.97l.708-.707L8 7.792V4H7v4l.146.354 3 3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="clone" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 15v-1c2 0 2-.6 2-1H1.5l-.5-.5v-10l.5-.5h13l.5.5v9.24l-1-1V3H2v9h5.73l-.5.5 2.5 2.5H4zm7.86 0l2.5-2.5-.71-.7L12 13.45V7h-1v6.44l-1.64-1.65-.71.71 2.5 2.5h.71z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="close" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.707l3.646 3.647.708-.707L8.707 8l3.647-3.646-.707-.708L8 7.293 4.354 3.646l-.707.708L7.293 8l-3.646 3.646.707.708L8 8.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="close-all" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.621 8.086l-.707-.707L6.5 8.793 5.086 7.379l-.707.707L5.793 9.5l-1.414 1.414.707.707L6.5 10.207l1.414 1.414.707-.707L7.207 9.5l1.414-1.414z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 3l1-1h7l1 1v7l-1 1h-2v2l-1 1H3l-1-1V6l1-1h2V3zm1 2h4l1 1v4h2V3H6v2zm4 1H3v7h7V6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="close-dirty" xmlns="http://www.w3.org/2000/svg"><path d="M8 4c.367 0 .721.048 1.063.145a3.943 3.943 0 011.762 1.031 3.944 3.944 0 011.03 1.762c.097.34.145.695.145 1.062 0 .367-.048.721-.145 1.063a3.94 3.94 0 01-1.03 1.765 4.017 4.017 0 01-1.762 1.031C8.72 11.953 8.367 12 8 12s-.721-.047-1.063-.14a4.056 4.056 0 01-1.765-1.032A4.055 4.055 0 014.14 9.062 3.992 3.992 0 014 8c0-.367.047-.721.14-1.063a4.02 4.02 0 01.407-.953A4.089 4.089 0 015.98 4.546a3.94 3.94 0 01.957-.401A3.89 3.89 0 018 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="cloud" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.957 6h.05a2.99 2.99 0 012.116.879 3.003 3.003 0 010 4.242 2.99 2.99 0 01-2.117.879v-.013L12 12H4.523a3.486 3.486 0 01-2.628-1.16 3.502 3.502 0 011.958-5.78 3.462 3.462 0 011.468.04 3.486 3.486 0 013.657-2.06A3.479 3.479 0 0111.957 6zM5 11h7.01a1.994 1.994 0 001.992-2 2.002 2.002 0 00-1.996-2h-.914l-.123-.857a2.49 2.49 0 00-2.126-2.122A2.478 2.478 0 006.231 5.5l-.333.762-.809-.189A2.49 2.49 0 004.523 6c-.662 0-1.297.263-1.764.732A2.503 2.503 0 004.523 11H5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="cloud-download" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.957 6h.05a2.99 2.99 0 012.116.879 3.003 3.003 0 010 4.242 2.99 2.99 0 01-2.117.879v-1a2.002 2.002 0 000-4h-.914l-.123-.857a2.49 2.49 0 00-2.126-2.122A2.478 2.478 0 006.231 5.5l-.333.762-.809-.189A2.49 2.49 0 004.523 6c-.662 0-1.297.263-1.764.732A2.503 2.503 0 004.523 11h.498v1h-.498a3.486 3.486 0 01-2.628-1.16 3.502 3.502 0 011.958-5.78 3.462 3.462 0 011.468.04 3.486 3.486 0 013.657-2.06A3.479 3.479 0 0111.957 6zm-5.25 5.121l1.314 1.314V7h.994v5.4l1.278-1.279.707.707-2.146 2.147h-.708L6 11.829l.707-.708z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="cloud-upload" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.956 6h.05a2.99 2.99 0 012.117.879 3.003 3.003 0 010 4.242 2.99 2.99 0 01-2.117.879h-1.995v-1h1.995a2.002 2.002 0 000-4h-.914l-.123-.857a2.49 2.49 0 00-2.126-2.122A2.478 2.478 0 006.23 5.5l-.333.762-.809-.189A2.49 2.49 0 004.523 6c-.662 0-1.297.263-1.764.732A2.503 2.503 0 004.523 11h2.494v1H4.523a3.486 3.486 0 01-2.628-1.16 3.502 3.502 0 01-.4-4.137A3.497 3.497 0 013.853 5.06c.486-.09.987-.077 1.468.041a3.486 3.486 0 013.657-2.06A3.479 3.479 0 0111.956 6zm-1.663 3.853L8.979 8.54v5.436h-.994v-5.4L6.707 9.854 6 9.146 8.146 7h.708L11 9.146l-.707.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="code" xmlns="http://www.w3.org/2000/svg"><path d="M4.708 5.578L2.061 8.224l2.647 2.646-.708.708-3-3V7.87l3-3 .708.708zm7-.708L11 5.578l2.647 2.646L11 10.87l.708.708 3-3V7.87l-3-3zM4.908 13l.894.448 5-10L9.908 3l-5 10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="collapse-all" xmlns="http://www.w3.org/2000/svg"><path d="M9 9H4v1h5V9z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 3l1-1h7l1 1v7l-1 1h-2v2l-1 1H3l-1-1V6l1-1h2V3zm1 2h4l1 1v4h2V3H6v2zm4 1H3v7h7V6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="color-mode" xmlns="http://www.w3.org/2000/svg"><path d="M8 1a7 7 0 100 14A7 7 0 008 1zm0 13V2a6 6 0 110 12z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="combine" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1l-.5.5v3l.5.5h3l.5-.5v-3L4.5 1h-3zM2 4V2h2v2H2zm-.5 2l-.5.5v3l.5.5h3l.5-.5v-3L4.5 6h-3zM2 9V7h2v2H2zm-1 2.5l.5-.5h3l.5.5v3l-.5.5h-3l-.5-.5v-3zm1 .5v2h2v-2H2zm10.5-7l-.5.5v6l.5.5h3l.5-.5v-6l-.5-.5h-3zM15 8h-2V6h2v2zm0 3h-2V9h2v2zM9.1 8H6v1h3.1l-1 1 .7.6 1.8-1.8v-.7L8.8 6.3l-.7.7 1 1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="comment" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 2h-13l-.5.5v9l.5.5H4v2.5l.854.354L7.707 12H14.5l.5-.5v-9l-.5-.5zm-.5 9H7.5l-.354.146L5 13.293V11.5l-.5-.5H2V3h12v8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="comment-add" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 2h-13l-.5.5v9l.5.5H4v2.5l.854.354L7.707 12H14.5l.5-.5v-9l-.5-.5zm-.5 9H7.5l-.354.146L5 13.293V11.5l-.5-.5H2V3h12v8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="comment-discussion" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 11.29l1-1v1.42l-1.15 1.14L3 12.5V10H1.5L1 9.5v-8l.5-.5h12l.5.5V6h-1V2H2v7h1.5l.5.5v1.79zM10.29 13l1.86 1.85.85-.35V13h1.5l.5-.5v-5l-.5-.5h-8l-.5.5v5l.5.5h3.79zm.21-1H7V8h7v4h-1.5l-.5.5v.79l-1.15-1.14-.35-.15z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="compare-changes" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.389 12.99l-1.27-1.27.67-.7 2.13 2.13v.7l-2.13 2.13-.71-.71L7.349 14h-1.85a2.49 2.49 0 01-2.5-2.5V5.95a2.59 2.59 0 01-1.27-.68 2.52 2.52 0 01-.54-2.73A2.5 2.5 0 013.499 1a2.45 2.45 0 011 .19 2.48 2.48 0 011.35 1.35c.133.317.197.658.19 1a2.5 2.5 0 01-2 2.45v5.5a1.5 1.5 0 001.5 1.5h1.85zm-4.68-8.25a1.5 1.5 0 002.08-2.08 1.55 1.55 0 00-.68-.56 1.49 1.49 0 00-.86-.08 1.49 1.49 0 00-1.18 1.18 1.49 1.49 0 00.08.86c.117.277.311.513.56.68zm10.33 6.3c.48.098.922.335 1.27.68a2.51 2.51 0 01.31 3.159 2.5 2.5 0 11-3.47-3.468c.269-.182.571-.308.89-.37V5.49a1.5 1.5 0 00-1.5-1.5h-1.85l1.27 1.27-.71.71-2.13-2.13v-.7l2.13-2.13.71.71-1.27 1.27h1.85a2.49 2.49 0 012.5 2.5v5.55zm-.351 3.943a1.5 1.5 0 001.1-2.322 1.55 1.55 0 00-.68-.56 1.49 1.49 0 00-.859-.08 1.49 1.49 0 00-1.18 1.18 1.49 1.49 0 00.08.86 1.5 1.5 0 001.539.922z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="compass" xmlns="http://www.w3.org/2000/svg"><path d="M9.009 6.991l2.024 4.042L6.991 9.01 4.967 4.967 9.009 6.99zm.426 2.444L8.481 7.52l-1.916-.955.954 1.917 1.916.954z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M13.98 8.5a6.002 6.002 0 01-5.48 5.48V13h-1v.98a6.001 6.001 0 01-5.482-5.518H3v-1h-.976A6.001 6.001 0 017.5 2.02V3h1v-.98a6.001 6.001 0 015.48 5.48H13v1h.98zM8 15A7 7 0 108 1a7 7 0 000 14z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="compass-active" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.101 13.9a6.004 6.004 0 01-.601.08V13h-1v.98a6.001 6.001 0 01-5.482-5.518H3v-1h-.976A6.001 6.001 0 017.5 2.02V3h1v-.98a6.001 6.001 0 015.48 5.48H13v1h.98a6.004 6.004 0 01-.08.601c.334.077.652.196.95.351a7 7 0 10-5.397 5.397 3.973 3.973 0 01-.352-.95zm.803-3.433L6.99 9.01 4.967 4.967 9.009 6.99l1.459 2.913a4.02 4.02 0 00-.564.563zm-.469-1.032L8.481 7.52l-1.916-.955.954 1.917 1.916.954z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M11.333 10.506a3 3 0 113.333 4.987 3 3 0 01-3.333-4.987zm1.698 3.817l1.79-2.387-.8-.6-1.48 1.974-.876-.7-.624.78 1.278 1.023.712-.09z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="compass-dot" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.101 13.9a6.004 6.004 0 01-.601.08V13h-1v.98a6.001 6.001 0 01-5.482-5.518H3v-1h-.976A6.001 6.001 0 017.5 2.02V3h1v-.98a6.001 6.001 0 015.48 5.48H13v1h.98a6.004 6.004 0 01-.08.601c.334.077.652.196.95.351a7 7 0 10-5.397 5.397 3.973 3.973 0 01-.352-.95zm.803-3.433L6.99 9.01 4.967 4.967 9.009 6.99l1.459 2.913a4.02 4.02 0 00-.564.563zm-.469-1.032L8.481 7.52l-1.916-.955.954 1.917 1.916.954z"/><circle cx="13" cy="13" r="3"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="console" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 1.5L1.5 3v18L3 22.5h18l1.5-1.5V3L21 1.5H3zM3 21V3h18v18H3zm5.656-4.01l1.038 1.061 5.26-5.243v-.912l-5.26-5.26-1.035 1.06 4.59 4.702-4.593 4.592z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="copy" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 4l1-1h5.414L14 6.586V14l-1 1H5l-1-1V4zm9 3l-3-3H5v10h8V7z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M3 1L2 2v10l1 1V2h6.414l-1-1H3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="credit-card" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 5v1H2V5h12zM2 7h12v5H2V7zm12-3H2a1 1 0 00-1 1v7a1 1 0 001 1h12a1 1 0 001-1V5a1 1 0 00-1-1zm-3 6h2v1h-2v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="dash" xmlns="http://www.w3.org/2000/svg"><path d="M5 8h6v1H5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="dashboard" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.889 2.095a6.5 6.5 0 117.222 10.81A6.5 6.5 0 013.89 2.094zm.555 9.978A5.5 5.5 0 007.5 13 5.506 5.506 0 0013 7.5a5.5 5.5 0 10-8.556 4.573zM10.294 4l.706.707-2.15 2.15a1.514 1.514 0 11-.707-.707L10.293 4zM7.221 7.916a.5.5 0 10.556-.832.5.5 0 00-.556.832zm4.286-2.449l-.763.763c.166.403.253.834.255 1.27a3.463 3.463 0 01-.5 1.777l.735.735a4.477 4.477 0 00.274-4.545h-.001zM8.733 4.242A3.373 3.373 0 007.5 4 3.5 3.5 0 004 7.5a3.46 3.46 0 00.5 1.777l-.734.735A4.5 4.5 0 019.5 3.473l-.767.769z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="database" xmlns="http://www.w3.org/2000/svg"><path d="M13 3.5C13 2.119 10.761 1 8 1S3 2.119 3 3.5c0 .04.02.077.024.117H3v8.872l.056.357C3.336 14.056 5.429 15 8 15c2.571 0 4.664-.944 4.944-2.154l.056-.357V3.617h-.024c.004-.04.024-.077.024-.117zM8 2.032c2.442 0 4 .964 4 1.468s-1.558 1.468-4 1.468S4 4 4 3.5s1.558-1.468 4-1.468zm4 10.458l-.03.131C11.855 13.116 10.431 14 8 14s-3.855-.884-3.97-1.379L4 12.49v-7.5A7.414 7.414 0 008 6a7.414 7.414 0 004-1.014v7.504z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="debug" xmlns="http://www.w3.org/2000/svg"><path d="M3.463 12.86l-.005-.07.005.07zm7.264.69l-3.034-3.049 1.014-1.014 3.209 3.225 3.163-3.163 1.014 1.014-3.034 3.034 3.034 3.05-1.014 1.014-3.209-3.225L8.707 17.6l-1.014-1.014 3.034-3.034z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M16.933 5.003V6h1.345l2.843-2.842 1.014 1.014-2.692 2.691.033.085a13.75 13.75 0 01.885 4.912c0 .335-.011.667-.034.995l-.005.075h3.54v1.434h-3.72l-.01.058c-.303 1.653-.891 3.16-1.692 4.429l-.06.094 3.423 3.44-1.017 1.012-3.274-3.29-.099.11c-1.479 1.654-3.395 2.646-5.483 2.646-2.12 0-4.063-1.023-5.552-2.723l-.098-.113-3.209 3.208-1.014-1.014 3.366-3.365-.059-.095c-.772-1.25-1.34-2.725-1.636-4.34l-.01-.057H0V12.93h3.538l-.005-.075a14.23 14.23 0 01-.034-.995c0-1.743.31-3.39.863-4.854l.032-.084-2.762-2.776L2.65 3.135 5.5 6h1.427v-.997a5.003 5.003 0 0110.006 0zm-8.572 0V6H15.5v-.997a3.569 3.569 0 00-7.138 0zm9.8 2.522l-.034-.09H5.733l-.034.09a12.328 12.328 0 00-.766 4.335c0 2.76.862 5.201 2.184 6.92 1.32 1.716 3.036 2.649 4.813 2.649 1.777 0 3.492-.933 4.813-2.65 1.322-1.718 2.184-4.16 2.184-6.919 0-1.574-.28-3.044-.766-4.335z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-all" xmlns="http://www.w3.org/2000/svg"><path d="M7.293 9.006l-.88.88A2.484 2.484 0 004 8a2.488 2.488 0 00-2.413 1.886l-.88-.88L0 9.712l1.147 1.146-.147.146v1H0v.999h1v.053c.051.326.143.643.273.946L0 15.294.707 16l1.1-1.099A2.873 2.873 0 004 16a2.875 2.875 0 002.193-1.099L7.293 16 8 15.294l-1.273-1.292A3.92 3.92 0 007 13.036v-.067h1v-.965H7v-1l-.147-.146L8 9.712l-.707-.706zM4 9.006a1.5 1.5 0 011.5 1.499h-3A1.498 1.498 0 014 9.006zm2 3.997A2.217 2.217 0 014 15a2.22 2.22 0 01-2-1.998v-1.499h4v1.499z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M3.78 2L3 2.41V7h1V3.35l7.6 5.07L9 10.15v1.2l3.78-2.52V8l-9-6zM9 13.35v-1.202l5.6-3.728L7 3.35V2.147L15.78 8v.83L9 13.35z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="debug-alt" xmlns="http://www.w3.org/2000/svg"><path d="M10.94 13.5l-1.32 1.32a3.73 3.73 0 00-7.24 0L1.06 13.5 0 14.56l1.72 1.72-.22.22V18H0v1.5h1.5v.08c.077.489.214.966.41 1.42L0 22.94 1.06 24l1.65-1.65A4.308 4.308 0 006 24a4.31 4.31 0 003.29-1.65L10.94 24 12 22.94 10.09 21c.198-.464.336-.951.41-1.45v-.1H12V18h-1.5v-1.5l-.22-.22L12 14.56l-1.06-1.06zM6 13.5a2.25 2.25 0 012.25 2.25h-4.5A2.25 2.25 0 016 13.5zm3 6a3.33 3.33 0 01-3 3 3.33 3.33 0 01-3-3v-2.25h6v2.25zm14.76-9.9v1.26L13.5 17.37V15.6l8.5-5.37L9 2v9.46a5.07 5.07 0 00-1.5-.72V.63L8.64 0l15.12 9.6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-alt-small" xmlns="http://www.w3.org/2000/svg"><path d="M7.293 9.006l-.88.88A2.484 2.484 0 004 8a2.488 2.488 0 00-2.413 1.886l-.88-.88L0 9.712l1.147 1.146-.147.146v1H0v.999h1v.053c.051.326.143.643.273.946L0 15.294.707 16l1.1-1.099A2.873 2.873 0 004 16a2.875 2.875 0 002.193-1.099L7.293 16 8 15.294l-1.273-1.292A3.92 3.92 0 007 13.036v-.067h1v-.965H7v-1l-.147-.146L8 9.712l-.707-.706zM4 9.006a1.5 1.5 0 011.5 1.499h-3A1.498 1.498 0 014 9.006zm2 3.997A2.217 2.217 0 014 15a2.22 2.22 0 01-2-1.998v-1.499h4v1.499z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 2.41L5.78 2l9 6v.83L9 12.683v-1.2l4.6-3.063L6 3.35V7H5V2.41z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint" xmlns="http://www.w3.org/2000/svg"><path d="M8 4c.367 0 .721.048 1.063.145a3.943 3.943 0 011.762 1.031 3.944 3.944 0 011.03 1.762c.097.34.145.695.145 1.062 0 .367-.048.721-.145 1.063a3.94 3.94 0 01-1.03 1.765 4.017 4.017 0 01-1.762 1.031C8.72 11.953 8.367 12 8 12s-.721-.047-1.063-.14a4.056 4.056 0 01-1.765-1.032A4.055 4.055 0 014.14 9.062 3.992 3.992 0 014 8c0-.367.047-.721.14-1.063a4.02 4.02 0 01.407-.953A4.089 4.089 0 015.98 4.546a3.94 3.94 0 01.957-.401A3.89 3.89 0 018 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-conditional" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zm2 5v1H6V9h4zm0-3v1H6V6h4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-conditional-disabled" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zm2 5v1H6V9h4zm0-3v1H6V6h4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-conditional-unverified" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.778 4.674a4 4 0 114.444 6.652 4 4 0 01-4.444-6.652zm.694 5.612a2.75 2.75 0 103.056-4.572 2.75 2.75 0 00-3.056 4.572zM9.5 6.5h-3v1h3v-1zm0 2h-3v1h3v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-data" xmlns="http://www.w3.org/2000/svg"><path d="M12.238 8l-2.31 4H5.31L3 8l2.31-4h4.618l2.31 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-data-disabled" xmlns="http://www.w3.org/2000/svg"><path d="M12.238 8l-2.31 4H5.31L3 8l2.31-4h4.618l2.31 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-data-unverified" xmlns="http://www.w3.org/2000/svg"><path d="M9.931 4h-4.62l-2.31 4 2.31 4h4.62l2.31-4-2.31-4zm-.75 6.7h-3.12L4.501 8l1.56-2.7h3.12l1.56 2.7-1.56 2.7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-disabled" xmlns="http://www.w3.org/2000/svg"><path d="M8 4c.367 0 .721.048 1.063.145a3.943 3.943 0 011.762 1.031 3.944 3.944 0 011.03 1.762c.097.34.145.695.145 1.062 0 .367-.048.721-.145 1.063a3.94 3.94 0 01-1.03 1.765 4.017 4.017 0 01-1.762 1.031C8.72 11.953 8.367 12 8 12s-.721-.047-1.063-.14a4.056 4.056 0 01-1.765-1.032A4.055 4.055 0 014.14 9.062 3.992 3.992 0 014 8c0-.367.047-.721.14-1.063a4.02 4.02 0 01.407-.953A4.089 4.089 0 015.98 4.546a3.94 3.94 0 01.957-.401A3.89 3.89 0 018 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-function" xmlns="http://www.w3.org/2000/svg"><path d="M8 4l4 6.905H4L8 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-function-disabled" xmlns="http://www.w3.org/2000/svg"><path d="M8 4l4 6.905H4L8 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-function-unverified" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 11h8L8 4l-4 7zm2.154-1.25h3.692L8 6.52 6.154 9.75z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-log" xmlns="http://www.w3.org/2000/svg"><path d="M8 3l5 5-5 5-5-5 5-5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-log-disabled" xmlns="http://www.w3.org/2000/svg"><path d="M8 3l5 5-5 5-5-5 5-5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-log-unverified" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.02 7.98L8 3l4.98 4.98L8 12.96 3.02 7.98zM8 10.77l2.79-2.79L8 5.19 5.21 7.98 8 10.77z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-unsupported" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.326 10.222a4 4 0 10-6.653-4.444 4 4 0 006.653 4.444zM8.65 10H7.4v1h1.25v-1zM7.4 9V5h1.25v4H7.4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-breakpoint-unverified" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 12a4 4 0 100-8 4 4 0 000 8zm2.61-4a2.61 2.61 0 11-5.22 0 2.61 2.61 0 015.22 0zM8 5.246z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="debug-console" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.04 1.361l.139-.057H21.32l.14.057 1.178 1.179.057.139V16.82l-.057.14-1.179 1.178-.139.057H14V18a1.99 1.99 0 00-.548-1.375h7.673V2.875H7.375v7.282a5.73 5.73 0 00-1.571-.164V2.679l.057-.14L7.04 1.362zm9.531 9.452l-2.809 2.8a2 2 0 00-.348-.467l-.419-.42 2.236-2.235-3.606-3.694.813-.833 4.133 4.133v.716zM9.62 14.82l1.32-1.32L12 14.56l-1.72 1.72.22.22V18H12v1.45h-1.5v.1a5.888 5.888 0 01-.41 1.45L12 22.94 10.94 24l-1.65-1.65A4.308 4.308 0 016 24a4.31 4.31 0 01-3.29-1.65L1.06 24 0 22.94 1.91 21a5.889 5.889 0 01-.41-1.42v-.08H0V18h1.5v-1.5l.22-.22L0 14.56l1.06-1.06 1.32 1.32a3.73 3.73 0 017.24 0zm-2.029-.661A2.25 2.25 0 003.75 15.75h4.5a2.25 2.25 0 00-.659-1.591zm.449 7.38A3.33 3.33 0 009 19.5v-2.25H3v2.25a3.33 3.33 0 003 3 3.33 3.33 0 002.04-.96z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-continue" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 2H4v12H2.5V2zm4.936.39L6.25 3v10l1.186.61 7-5V7.39l-7-5zM12.71 8l-4.96 3.543V4.457L12.71 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-continue-small" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 2H3v12h1V2zm3.29.593L6.5 3v10l.79.407 7-5v-.814l-7-5zM13.14 8L7.5 12.028V3.972L13.14 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-coverage" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 2.41L5.78 2l9 6v.83L9 12.683v-1.2l4.6-3.063L6 3.35V7H5V2.41z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6.13 12.124c-.182.18-.322.379-.42.6-.097.219-.145.457-.145.715v.862a.685.685 0 01-.205.495.703.703 0 01-.496.204h-.865a.691.691 0 01-.497-.204.701.701 0 01-.205-.495v-.862c0-.258-.049-.496-.147-.716a1.913 1.913 0 00-.418-.6 2.525 2.525 0 01-.542-.773 2.255 2.255 0 01-.19-.927A2.386 2.386 0 012.332 9.2a2.404 2.404 0 01.87-.87A2.473 2.473 0 014.432 8a2.41 2.41 0 011.225.33 2.41 2.41 0 011.205 2.093c0 .332-.063.641-.19.927a2.525 2.525 0 01-.542.774zm-1.103.991H3.835v1.186c0 .043.016.08.049.114.033.033.07.048.115.048h.865a.156.156 0 00.114-.048.154.154 0 00.049-.114v-1.186z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-disconnect" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.617 3.844a2.87 2.87 0 00-.451-.868l1.354-1.36L13.904 1l-1.36 1.354a2.877 2.877 0 00-.868-.452 3.073 3.073 0 00-2.14.075 3.03 3.03 0 00-.991.664L7 4.192l4.327 4.328 1.552-1.545c.287-.287.508-.618.663-.992a3.074 3.074 0 00.075-2.14zm-.889 1.804a2.15 2.15 0 01-.471.705l-.93.93-3.09-3.09.93-.93a2.15 2.15 0 01.704-.472 2.134 2.134 0 011.689.007c.264.114.494.271.69.472.2.195.358.426.472.69a2.134 2.134 0 01.007 1.688zm-4.824 4.994l1.484-1.545-.616-.622-1.49 1.551-1.86-1.859 1.491-1.552L6.291 6 4.808 7.545l-.616-.615-1.551 1.545a3 3 0 00-.663.998 3.023 3.023 0 00-.233 1.169c0 .332.05.656.15.97.105.31.258.597.459.862L1 13.834l.615.615 1.36-1.353c.265.2.552.353.862.458.314.1.638.15.97.15.406 0 .796-.077 1.17-.232.378-.155.71-.376.998-.663l1.545-1.552-.616-.615zm-2.262 2.023a2.16 2.16 0 01-.834.164c-.301 0-.586-.057-.855-.17a2.278 2.278 0 01-.697-.466 2.28 2.28 0 01-.465-.697 2.167 2.167 0 01-.17-.854 2.16 2.16 0 01.642-1.545l.93-.93 3.09 3.09-.93.93a2.22 2.22 0 01-.711.478z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-hint" xmlns="http://www.w3.org/2000/svg"><path d="M8 4c.367 0 .721.048 1.063.145a3.943 3.943 0 011.762 1.031 3.944 3.944 0 011.03 1.762c.097.34.145.695.145 1.062 0 .367-.048.721-.145 1.063a3.94 3.94 0 01-1.03 1.765 4.017 4.017 0 01-1.762 1.031C8.72 11.953 8.367 12 8 12s-.721-.047-1.063-.14a4.056 4.056 0 01-1.765-1.032A4.055 4.055 0 014.14 9.062 3.992 3.992 0 014 8c0-.367.047-.721.14-1.063a4.02 4.02 0 01.407-.953A4.089 4.089 0 015.98 4.546a3.94 3.94 0 01.957-.401A3.89 3.89 0 018 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-line-by-line" xmlns="http://www.w3.org/2000/svg"><path d="M6 10V9h9v1H6zm4-4h5v1h-5V6zm5-3v1H6V3h9zm-9 9v1h9v-1H6z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M1 2.795l.783-.419 5.371 3.581v.838l-5.371 3.581L1 9.957V2.795zm1.007.94v5.281l3.96-2.64-3.96-2.64z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-pause" xmlns="http://www.w3.org/2000/svg"><path d="M4.5 3H6v10H4.5V3zm7 0v10H10V3h1.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-rerun" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.167 12a3 3 0 01-5.74 1.223l-.928.376A4.001 4.001 0 101 9.556V8.333H0V11l.5.5h2.333v-1H1.568A3 3 0 017.167 12z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 2.41L5.78 2l9 6v.83L10 12.017v-1.2l3.6-2.397L6 3.35V7H5V2.41z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-restart" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.75 8a4.5 4.5 0 01-8.61 1.834l-1.391.565A6.001 6.001 0 0014.25 8 6 6 0 003.5 4.334V2.5H2v4l.75.75h3.5v-1.5H4.352A4.5 4.5 0 0112.75 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-restart-frame" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 10V9h5.207a5.48 5.48 0 00-.185 1H1zm6.257-3a5.54 5.54 0 011.08-1H1v1h6.257zM6.6 13a5.465 5.465 0 01-.393-1H1v1h5.6zM15 3v1H1V3h14zm-3.36 10.031a2.531 2.531 0 10-2.192-3.797h1.068v.844h-1.97l-.421-.422v-2.25h.844v1.032a3.375 3.375 0 11-.423 3.412l.782-.318a2.532 2.532 0 002.313 1.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-reverse-continue" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 2H12v12h1.5V2zm-4.936.39L9.75 3v10l-1.186.61-7-5V7.39l7-5zM3.29 8l4.96 3.543V4.457L3.29 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-stackframe" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 7.15l-4.26-4.74L9.31 2H4.25L3 3.25v9.48l1.25 1.25h5.06l.93-.42 4.26-4.74V7.15zm-5.19 5.58H4.25V3.25h5.06l4.26 4.73-4.26 4.75z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-stackframe-active" xmlns="http://www.w3.org/2000/svg"><path d="M10 8a2 2 0 11-4 0 2 2 0 014 0z"/><path d="M14.5 7.15l-4.26-4.74L9.31 2H4.25L3 3.25v9.48l1.25 1.25h5.06l.93-.42 4.26-4.74V7.15zm-5.19 5.58H4.25V3.25h5.06l4.26 4.73-4.26 4.75z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-stackframe-dot" xmlns="http://www.w3.org/2000/svg"><path d="M10 8a2 2 0 11-4 0 2 2 0 014 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-stackframe-focused" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 7.15l-4.26-4.74L9.31 2H4.25L3 3.25v9.48l1.25 1.25h5.06l.93-.42 4.26-4.74V7.15zm-5.19 5.58H4.25V3.25h5.06l4.26 4.73-4.26 4.75z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-start" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.25 3l1.166-.624 8 5.333v1.248l-8 5.334-1.166-.624V3zm1.5 1.401v7.864l5.898-3.932L5.75 4.401z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-step-back" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.75 5.75v-4h1.5v2.542c1.145-1.359 2.911-2.209 4.84-2.209 3.177 0 5.92 2.307 6.16 5.398l.02.269h-1.5l-.022-.226c-.212-2.195-2.202-3.94-4.656-3.94-1.736 0-3.244.875-4.05 2.166h2.83v1.5H2.707l-.961-.975V5.75h.003zM8 14a2 2 0 110-4 2 2 0 010 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-step-into" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 9.532h.542l3.905-3.905-1.061-1.06-2.637 2.61V1H7.251v6.177l-2.637-2.61-1.061 1.06 3.905 3.905H8zm1.956 3.481a2 2 0 11-4 0 2 2 0 014 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-step-out" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 1h-.542L3.553 4.905l1.061 1.06 2.637-2.61v6.177h1.498V3.355l2.637 2.61 1.061-1.06L8.542 1H8zm1.956 12.013a2 2 0 11-4 0 2 2 0 014 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-step-over" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.25 5.75v-4h-1.5v2.542c-1.145-1.359-2.911-2.209-4.84-2.209-3.177 0-5.92 2.307-6.16 5.398l-.02.269h1.501l.022-.226c.212-2.195 2.202-3.94 4.656-3.94 1.736 0 3.244.875 4.05 2.166h-2.83v1.5h4.163l.962-.975V5.75h-.004zM8 14a2 2 0 100-4 2 2 0 000 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="debug-stop" xmlns="http://www.w3.org/2000/svg"><path d="M2 2v12h12V2H2zm10.75 10.75h-9.5v-9.5h9.5v9.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="desktop-download" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 15v-1c2 0 2-.6 2-1H1.5l-.5-.5v-10l.5-.5h13l.5.5v9.24l-1-1V3H2v9h5.73l-.5.5 2.5 2.5H4zm7.86 0l2.5-2.5-.71-.7L12 13.45V7h-1v6.44l-1.64-1.65-.71.71 2.5 2.5h.71z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="device-camera" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.707 3H14.5l.5.5v9l-.5.5h-13l-.5-.5v-9l.5-.5h3.793l.853-.854L6.5 2h3l.354.146.853.854zM2 12h12V4h-3.5l-.354-.146L9.293 3H6.707l-.853.854L5.5 4H2v8zm1.5-7a.5.5 0 100 1 .5.5 0 000-1zM8 6a2 2 0 110 4 2 2 0 010-4zm0-1a3 3 0 100 6 3 3 0 000-6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="device-camera-video" xmlns="http://www.w3.org/2000/svg"><path d="M14.25 4.74L11 6.62V4.5l-.5-.5h-9l-.5.5v7l.5.5h9l.5-.5v-2l3.25 1.87.75-.47V5.18l-.75-.44zM10 11H2V5h8v6zm4-1l-3-1.7v-.52L14 6v4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="device-desktop" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 2h-13l-.5.5v10l.5.5H7v1H4v1h8v-1H9v-1h5.5l.5-.5v-10l-.5-.5zM14 12H2V3h12v9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="device-mobile" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 1h8l.5.5v13l-.5.5h-8l-.5-.5v-13l.5-.5zM5 14h7V2H5v12zm2.5-2h2v1h-2v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="diff" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 3.5l.5-.5h5l.5.5v9l-.5.5h-5l-.5-.5v-9zM3 12h4V6H3v6zm0-7h4V4H3v1zm6.5-2h5l.5.5v9l-.5.5h-5l-.5-.5v-9l.5-.5zm.5 9h4v-2h-4v2zm0-4h4V4h-4v4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="diff-added" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h12l.5.5v12l-.5.5h-12l-.5-.5v-12l.5-.5zM2 13h11V2H2v11z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8 4H7v3H4v1h3v3h1V8h3V7H8V4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="diff-ignored" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h13l.5.5v13l-.5.5h-13l-.5-.5v-13l.5-.5zM2 14h12V2H2v12zm8-10h2v2l-6 6H4v-2l6-6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="diff-modified" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h13l.5.5v13l-.5.5h-13l-.5-.5v-13l.5-.5zM2 2v12h12V2H2zm6 9a3 3 0 100-6 3 3 0 000 6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="diff-removed" xmlns="http://www.w3.org/2000/svg"><path d="M10 7v1H5V7h5z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h12l.5.5v12l-.5.5h-12l-.5-.5v-12l.5-.5zM2 13h11V2H2v11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="diff-renamed" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h13l.5.5v13l-.5.5h-13l-.5-.5v-13l.5-.5zM2 14h12V2H2v12zm2-5h3v3l5-4-5-4v3H4v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="discard" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 2v3.5L4 6h3.5V5H4.979l.941-.941a3.552 3.552 0 115.023 5.023L5.746 14.28l.72.72 5.198-5.198A4.57 4.57 0 005.2 3.339l-.7.7V2h-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="edit" xmlns="http://www.w3.org/2000/svg"><path d="M13.23 1h-1.46L3.52 9.25l-.16.22L1 13.59 2.41 15l4.12-2.36.22-.16L15 4.23V2.77L13.23 1zM2.41 13.59l1.51-3 1.45 1.45-2.96 1.55zm3.83-2.06L4.47 9.76l8-8 1.77 1.77-8 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="editor-layout" xmlns="http://www.w3.org/2000/svg"><path d="M15 6.5l-.47-.5H7V1.47L6.53 1H1.47L1 1.47v8.06l.47.47H4v4.53l.47.47h10.06l.47-.47V6.5zM2 9V3h4v6H2zm12 5H5v-4h1.53L7 9.53V8.013h7V14z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="ellipsis" xmlns="http://www.w3.org/2000/svg"><path d="M4 8a1 1 0 11-2 0 1 1 0 012 0zm5 0a1 1 0 11-2 0 1 1 0 012 0zm5 0a1 1 0 11-2 0 1 1 0 012 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="empty-window" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 4h3v1H4v3H3V5H0V4h3V1h1v3zM1 14.5V9h1v5h12V7H8V6h6V4H8V3h6.5l.5.5v11l-.5.5h-13l-.5-.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="error" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6zM7.9 7.5L10.3 5l.7.7-2.4 2.5 2.4 2.5-.7.7-2.4-2.5-2.4 2.5-.7-.7 2.4-2.5-2.4-2.5.7-.7 2.4 2.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="error-small" xmlns="http://www.w3.org/2000/svg"><path d="M9.177 10.105L8 8.928l-1.177 1.177-.928-.928L7.072 8 5.895 6.823l.928-.928L8 7.072l1.177-1.177.928.928L8.928 8l1.177 1.177-.928.928z"/><path d="M12 8a4 4 0 11-8 0 4 4 0 018 0zm-1 0a3 3 0 10-6 0 3 3 0 006 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="exclude" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.412 1H6.588l-.484 2.423-2.056-1.37-1.996 1.995 1.37 2.056L1 6.588v2.824l2.423.484-1.37 2.056 1.995 1.996 2.056-1.37L6.588 15h2.083a4.526 4.526 0 01-.917-1.005h-.342l-.288-1.441a4.473 4.473 0 01-.067-.334l-.116-.583-.764-.316-2 1.334-.832-.831L4.68 9.823l-.316-.764-2.358-.471V7.412l2.358-.471.316-.764-1.334-2 .831-.832 2 1.335.764-.316.471-2.358h1.176l.471 2.358.764.316 2-1.334.832.831-1.334 2.001.316.764.582.116c.113.018.225.04.335.067l1.441.288v.342c.38.254.719.563 1.005.917V6.588l-2.422-.484 1.37-2.056-1.996-1.996-2.056 1.37L9.412 1zM8 6a2 2 0 011.875 1.302 4.46 4.46 0 00-.9.473 1 1 0 10-1.2 1.2 4.46 4.46 0 00-.473.9A2 2 0 018 6zm1.28 2.795a3.5 3.5 0 114.44 5.41 3.5 3.5 0 01-4.44-5.41zM9 11v1h5v-1H9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="expand-all" xmlns="http://www.w3.org/2000/svg"><path d="M9 9H4v1h5V9z"/><path d="M7 12V7H6v5h1z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 3l1-1h7l1 1v7l-1 1h-2v2l-1 1H3l-1-1V6l1-1h2V3zm1 2h4l1 1v4h2V3H6v2zm4 1H3v7h7V6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="export" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.086 7l-2.39-2.398.702-.704L15 7.5l-3.602 3.602-.703-.704 2.383-2.382V8H3V7h10.086zM1 4h1v7H1V4z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="extensions" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 1.5L15 0h7.5L24 1.5V9l-1.5 1.5H15L13.5 9V1.5zm1.5 0V9h7.5V1.5H15zM0 15V6l1.5-1.5H9L10.5 6v7.5H18l1.5 1.5v7.5L18 24H1.5L0 22.5V15zm9-1.5V6H1.5v7.5H9zM9 15H1.5v7.5H9V15zm1.5 7.5H18V15h-7.5v7.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="eye" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 10c0-3.9 3.1-7 7-7s7 3.1 7 7h-1c0-3.3-2.7-6-6-6s-6 2.7-6 6H1zm4 0c0-1.7 1.3-3 3-3s3 1.3 3 3-1.3 3-3 3-3-1.3-3-3zm1 0c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="eye-closed" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 2c-1.5 0-2.8.4-3.9 1.2l.8.7C5.8 3.3 6.8 3 8 3c3.3 0 6 2.7 6 6h1c0-3.9-3.1-7-7-7zM1 3l1.6 1.5C1.6 5.7 1 7.3 1 9h1c0-1.5.5-2.8 1.4-3.8l2.2 2C5.2 7.7 5 8.3 5 9c0 1.7 1.3 3 3 3 .8 0 1.5-.3 2-.8l3 2.8.7-.7-12-11L1 3zm5.3 4.9l2.9 2.7c-.3.2-.7.4-1.2.4-1.1 0-2-.9-2-2 0-.4.1-.8.3-1.1zM11 9.5l-1-.9c-.2-.8-.9-1.5-1.8-1.6l-1-.9c.3-.1.5-.1.8-.1 1.7 0 3 1.3 3 3v.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="eye-unwatch" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 10c0-3.9 3.1-7 7-7s7 3.1 7 7h-1c0-3.3-2.7-6-6-6s-6 2.7-6 6H1zm4 0c0-1.7 1.3-3 3-3s3 1.3 3 3-1.3 3-3 3-3-1.3-3-3zm1 0c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="eye-watch" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 10c0-3.9 3.1-7 7-7s7 3.1 7 7h-1c0-3.3-2.7-6-6-6s-6 2.7-6 6H1zm4 0c0-1.7 1.3-3 3-3s3 1.3 3 3-1.3 3-3 3-3-1.3-3-3zm1 0c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="feedback" xmlns="http://www.w3.org/2000/svg"><path d="M7.549 10.078c.46.182.88.424 1.258.725.378.3.701.65.97 1.046a4.829 4.829 0 01.848 2.714V15H9.75v-.438a3.894 3.894 0 00-1.155-2.782 4.054 4.054 0 00-1.251-.84 3.898 3.898 0 00-1.532-.315A3.894 3.894 0 003.03 11.78a4.06 4.06 0 00-.84 1.251c-.206.474-.31.985-.315 1.531V15H1v-.438a4.724 4.724 0 01.848-2.713 4.918 4.918 0 012.229-1.77 2.994 2.994 0 01-.555-.493 3.156 3.156 0 01-.417-.602 2.942 2.942 0 01-.26-.683 3.345 3.345 0 01-.095-.739c0-.423.08-.82.24-1.189a3.095 3.095 0 011.626-1.627 3.067 3.067 0 012.386-.007 3.095 3.095 0 011.627 1.627 3.067 3.067 0 01.157 1.928c-.06.237-.148.465-.266.684a3.506 3.506 0 01-.417.608c-.16.187-.345.35-.554.492zM5.812 9.75c.301 0 .584-.057.848-.17a2.194 2.194 0 001.162-1.163c.119-.269.178-.554.178-.854a2.138 2.138 0 00-.643-1.538 2.383 2.383 0 00-.697-.472 2.048 2.048 0 00-.848-.178c-.3 0-.583.057-.847.17a2.218 2.218 0 00-1.17 1.17c-.113.264-.17.547-.17.848 0 .3.057.583.17.847.115.264.27.497.466.697a2.168 2.168 0 001.552.643zM15 1v7h-1.75l-2.625 2.625V8H9.75v-.875h1.75v1.388l1.388-1.388h1.237v-5.25h-8.75v1.572a7.255 7.255 0 00-.438.069 2.62 2.62 0 00-.437.123V1H15z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.71 4.29l-3-3L10 1H4L3 2v12l1 1h9l1-1V5l-.29-.71zM13 14H4V2h5v4h4v8zm-3-9V2l3 3h-3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-add" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.5 1.1l3.4 3.5.1.4v2h-1V6H8V2H3v11h4v1H2.5l-.5-.5v-12l.5-.5h6.7l.3.1zM9 2v3h2.9L9 2zm4 14h-1v-3H9v-1h3V9h1v3h3v1h-3v3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-binary" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.57 1.14l3.28 3.3.15.36v9.7l-.5.5h-11l-.5-.5v-13l.5-.5h7.72l.35.14zM3 2v12h10V5l-3-3H3zm1.46 4.052c0 1.287.458 1.93 1.374 1.93.457 0 .807-.173 1.05-.52.246-.348.368-.847.368-1.499C7.252 4.654 6.805 4 5.91 4c-.471 0-.831.175-1.08.526-.247.35-.37.858-.37 1.526zm.862-.022c0-.922.183-1.383.55-1.383.344 0 .516.448.516 1.343s-.176 1.343-.527 1.343c-.36 0-.54-.434-.54-1.303zm3.187 1.886h2.435v-.672h-.792V4l-1.665.336v.687l.82-.177v2.398h-.798v.672zm-1.337 5H4.736v-.672h.798V9.846l-.82.177v-.687L6.38 9v3.244h.792v.671zm1.035-1.931c0 1.287.458 1.93 1.375 1.93.457 0 .807-.173 1.05-.52.245-.348.368-.847.368-1.499 0-1.309-.448-1.963-1.343-1.963-.47 0-.83.175-1.08.526-.246.35-.37.858-.37 1.526zm.862-.022c0-.922.184-1.383.55-1.383.344 0 .516.448.516 1.343s-.175 1.343-.526 1.343c-.36 0-.54-.434-.54-1.303z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-code" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.57 1.14l3.28 3.3.15.36v9.7l-.5.5h-11l-.5-.5v-13l.5-.5h7.72l.35.14zM10 5h3l-3-3v3zM3 2v12h10V6H9.5L9 5.5V2H3zm2.062 7.533l1.817-1.828L6.17 7 4 9.179v.707l2.171 2.174.707-.707-1.816-1.82zM8.8 7.714l.7-.709 2.189 2.175v.709L9.5 12.062l-.705-.709 1.831-1.82L8.8 7.714z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-directory" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 3H7.71l-.85-.85L6.51 2h-5l-.5.5v11l.5.5h13l.5-.5v-10L14.5 3zm-.51 8.49V13h-12V7h4.49l.35-.15.86-.86H14v1.5l-.01 4zm0-6.49h-6.5l-.35.15-.86.86H2v-3h4.29l.85.85.36.15H14l-.01.99z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-directory-create" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 2H7.71l-.85-.85L6.51 1h-5l-.5.5v11l.5.5H7v-1H1.99V6h4.49l.35-.15.86-.86H14v1.5l-.001.51h1.011V2.5L14.5 2zm-.51 2h-6.5l-.35.15-.86.86H2v-3h4.29l.85.85.36.15H14l-.01.99zM13 16h-1v-3H9v-1h3V9h1v3h3v1h-3v3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-media" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 2h6v3.5l.5.5H12v1h1V4.8l-.15-.36-3.28-3.3L9.22 1H1.5l-.5.5v13l.5.5H5v-1H2V2zm7 0l3 3H9V2zm5.5 6h-8l-.5.5v6l.5.5h8l.5-.5v-6l-.5-.5zM14 9v4l-1.63-1.6h-.71l-1.16 1.17-2.13-2.13h-.71L7 11.1V9h7zm-2.8 4.27l.81-.81L13.55 14h-1.62l-.73-.73zM7 14v-1.49l1-1L10.52 14H7zm5.5-3.5a.5.5 0 100-1 .5.5 0 000 1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-pdf" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.85 4.44l-3.28-3.3-.35-.14H2.5l-.5.5V7h1V2h6v3.5l.5.5H13v1h1V4.8l-.15-.36zM10 5V2l3 3h-3zM2.5 8l-.5.5v6l.5.5h11l.5-.5v-6l-.5-.5h-11zM13 13v1H3V9h10v4zm-8-1h-.32v1H4v-3h1.06c.75 0 1.13.36 1.13 1a.94.94 0 01-.32.72A1.33 1.33 0 015 12zm-.06-1.45h-.26v.93h.26c.36 0 .54-.16.54-.47 0-.31-.18-.46-.54-.46zM9 12.58a1.48 1.48 0 00.44-1.12c0-1-.53-1.46-1.6-1.46H6.78v3h1.06A1.6 1.6 0 009 12.58zm-1.55-.13v-1.9h.33a.94.94 0 01.7.25.91.91 0 01.25.67 1 1 0 01-.25.72.94.94 0 01-.69.26h-.34zm4.45-.61h-.97V13h-.68v-3h1.74v.55h-1.06v.74h.97v.55z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-submodule" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 11h1V6.99H2V11zm1-5.01V5.5l.5-.5h4.43l.43.25.43.75h5.71l.5.5v8l-.5.5h-11l-.5-.5V12H1.5l-.5-.5v-9l.5-.5h4.42l.44.25.43.75h5.71l.5.5V6l-1-.03V4H6.5l-.43-.25L5.64 3H2v2.99h1zm5.07.76L7.64 6H4v3h3.15l.41-.74L8 8h6V7H8.5l-.43-.25zM7.45 10H4v4h10V9H8.3l-.41.74-.44.26z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-symlink-directory" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.71 3h6.79l.51.5v10l-.5.5h-13l-.5-.5v-11l.5-.5h5l.35.15.85.85zm6.28 10v-1.51l.01-4v-1.5H7.7l-.86.86-.35.15H2v6h11.99zm-6.5-8h6.5l.01-.99H7.5l-.36-.15-.85-.85H2v3h4.28l.86-.86.35-.15zm2.29 4.07L8.42 7.7l.74-.69 2.22 2.22v.71l-2.29 2.21-.7-.72 1.4-1.35H8.42a2 2 0 00-1.35.61A1.8 1.8 0 006.54 12h-1a2.76 2.76 0 01.81-2 3 3 0 012-.93h1.43z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-symlink-file" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.57 1.14l3.28 3.3.15.36v9.7l-.5.5H10v-1h3V6H9.5L9 5.5V2H3v4H2V1.5l.5-.5h7.72l.35.14zM10 5h3l-3-3v3zM8.5 7h-7l-.5.5v7l.5.5h7l.5-.5v-7L8.5 7zM8 14H2V8h6v6zM7 9.5v3H6v-1.793l-2.646 2.647-.708-.708L5.293 10H3.53V9H6.5l.5.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-text" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.71 4.29l-3-3L10 1H4L3 2v12l1 1h9l1-1V5l-.29-.71zM13 14H4V2h5v4h4v8zm-3-9V2l3 3h-3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="file-zip" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 1h11l.5.5v5l-.15.35-.85.86v6.79l-.5.5h-10l-.5-.5v-13l.5-.5zM6 2H5v2h1V2zm0 12h4V7.68l-.85-.85L9 6.47V2H7v2.5l-.5.5H6v1H5V5h-.5L4 4.5V2H3v12h2v-1h1v1zm0-2v1h1v-1H6zm0-1v1H5v-1h1zm0-1h1v1H6v-1zm0-1v1H5V9h1zm0-1h1v1H6V8zm0-1v1H5V7h1zm0 0h1V6H6v1zm6.15.15l.85-.86V2h-3v4.27l.85.85.15.35V14h1V7.5l.15-.35z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="files" xmlns="http://www.w3.org/2000/svg"><path d="M17.5 0h-9L7 1.5V6H2.5L1 7.5v15.07L2.5 24h12.07L16 22.57V18h4.7l1.3-1.43V4.5L17.5 0zm0 2.12l2.38 2.38H17.5V2.12zm-3 20.38h-12v-15H7v9.07L8.5 18h6v4.5zm6-6h-12v-15H16V6h4.5v10.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="filter" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15 2v1.67l-5 4.759V14H6V8.429l-5-4.76V2h14zM7 8v5h2V8l5-4.76V3H2v.24L7 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="filter-filled" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15 2v1.67l-5 4.759V14H6V8.429l-5-4.76V2h14z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="flame" xmlns="http://www.w3.org/2000/svg"><path d="M9.13 15l-.53-.77a1.85 1.85 0 00-.28-2.54 3.51 3.51 0 01-1.19-2c-1.56 2.23-.75 3.46 0 4.55l-.55.76A4.4 4.4 0 013 10.46S2.79 8.3 5.28 6.19c0 0 2.82-2.61 1.84-4.54L7.83 1a6.57 6.57 0 012.61 6.94 2.57 2.57 0 00.56-.81l.87-.07c.07.12 1.84 2.93.89 5.3A4.72 4.72 0 019.13 15zm-2-6.95l.87.39a3 3 0 00.92 2.48 2.64 2.64 0 011 2.8A3.241 3.241 0 0011.8 12a4.87 4.87 0 00-.41-3.63 1.85 1.85 0 01-1.84.86l-.35-.68a5.31 5.31 0 00-.89-5.8C8.17 4.87 6 6.83 5.93 6.94 3.86 8.7 4 10.33 4 10.4a3.47 3.47 0 001.59 3.14C5 12.14 5 10.46 7.16 8.05h-.03z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="fold" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.952 2.381L7.976 6.357 4 2.381 3.38 3l4.286 4.285h.619L12.57 3l-.618-.619zM3.904 14l4.072-4.072L12.047 14l.62-.619L8.284 9h-.619l-4.381 4.381.619.619z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="fold-down" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.207 1.707L13.5 1l-6 6-6-6-.707.707 6.353 6.354h.708l6.353-6.354zm0 6L13.5 7l-6 6-6-6-.707.707 6.353 6.354h.708l6.353-6.354z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="fold-up" xmlns="http://www.w3.org/2000/svg"><path d="M1 7.4l.7.7 6-6 6 6 .7-.7L8.1 1h-.7L1 7.4zm0 6l.7.7 6-6 6 6 .7-.7L8.1 7h-.7L1 13.4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="folder" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 3H7.71l-.85-.85L6.51 2h-5l-.5.5v11l.5.5h13l.5-.5v-10L14.5 3zm-.51 8.49V13h-12V7h4.49l.35-.15.86-.86H14v1.5l-.01 4zm0-6.49h-6.5l-.35.15-.86.86H2v-3h4.29l.85.85.36.15H14l-.01.99z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="folder-active" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.71 3h6.79l.51.5v4.507A4.997 4.997 0 0014 7.416V5.99H7.69l-.86.86-.35.15H1.99v6H7.1c.07.348.177.682.316 1H1.51l-.5-.5v-11l.5-.5h5l.35.15.85.85zm-.22 2h6.5l.01-.99H7.5l-.36-.15-.85-.85H2v3h4.28l.86-.86.35-.15z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9.778 8.674a4 4 0 114.444 6.652 4 4 0 01-4.444-6.652zm2.13 4.99l2.387-3.182-.8-.6-2.077 2.769-1.301-1.041-.625.78 1.704 1.364.713-.09z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="folder-library" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.71 3h6.79l.51.5V7H14V5.99H7.69l-.86.86-.35.15H1.99v6H7v1H1.51l-.5-.5v-11l.5-.5h5l.35.15.85.85zm-.22 2h6.5l.01-.99H7.5l-.36-.15-.85-.85H2v3h4.28l.86-.86.35-.15z"/><path d="M8 8h1v6H8zM10 8h1v6h-1zM12.004 8.352l.94-.342 2.052 5.638-.94.342z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="folder-opened" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 14h11l.48-.37 2.63-7-.48-.63H14V3.5l-.5-.5H7.71l-.86-.85L6.5 2h-5l-.5.5v11l.5.5zM2 3h4.29l.86.85.35.15H13v2H8.5l-.35.15-.86.85H3.5l-.47.34-1 3.08L2 3zm10.13 10H2.19l1.67-5H7.5l.35-.15.86-.85h5.79l-2.37 6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gather" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1l-.5.5v3l.5.5h3l.5-.5v-3L4.5 1h-3zM2 4V2h2v2H2zm-.5 2l-.5.5v3l.5.5h3l.5-.5v-3L4.5 6h-3zM2 9V7h2v2H2zm-1 2.5l.5-.5h3l.5.5v3l-.5.5h-3l-.5-.5v-3zm1 .5v2h2v-2H2zm10.5-7l-.5.5v6l.5.5h3l.5-.5v-6l-.5-.5h-3zM15 8h-2V6h2v2zm0 3h-2V9h2v2zM9.1 8H6v1h3.1l-1 1 .7.6 1.8-1.8v-.7L8.8 6.3l-.7.7 1 1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gear" xmlns="http://www.w3.org/2000/svg"><path d="M9.1 4.4L8.6 2H7.4l-.5 2.4-.7.3-2-1.3-.9.8 1.3 2-.2.7-2.4.5v1.2l2.4.5.3.8-1.3 2 .8.8 2-1.3.8.3.4 2.3h1.2l.5-2.4.8-.3 2 1.3.8-.8-1.3-2 .3-.8 2.3-.4V7.4l-2.4-.5-.3-.8 1.3-2-.8-.8-2 1.3-.7-.2zM9.4 1l.5 2.4L12 2.1l2 2-1.4 2.1 2.4.4v2.8l-2.4.5L14 12l-2 2-2.1-1.4-.5 2.4H6.6l-.5-2.4L4 13.9l-2-2 1.4-2.1L1 9.4V6.6l2.4-.5L2.1 4l2-2 2.1 1.4.4-2.4h2.8zm.6 7c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM8 9c.6 0 1-.4 1-1s-.4-1-1-1-1 .4-1 1 .4 1 1 1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gift" xmlns="http://www.w3.org/2000/svg"><path d="M13.5 4h-1.6c.1-.4.1-.8.1-1.2-.1-.3-.2-.6-.4-.9-.2-.3-.4-.5-.7-.6-.3-.1-.6-.3-.9-.3-.3 0-.6 0-.9.2-.7.2-1.2.7-1.6 1.3-.4-.6-.9-1.1-1.6-1.3-.3-.1-.6-.2-.9-.2-.3 0-.6.1-.9.3-.3.1-.5.3-.7.6-.2.2-.3.6-.4.9 0 .4 0 .8.1 1.2H1.5l-.5.5v9l.5.5h12l.5-.5v-9l-.5-.5zM7 13H2V5h5v8zm0-9H4v-.2c-.1-.3-.1-.5-.1-.8.1-.2.1-.4.3-.5.1-.2.3-.3.5-.4.1-.1.3-.1.5-.1s.4 0 .6.1c.3.1.6.3.8.6.2.3.4.6.4 1V4zm1-.3c0-.4.2-.7.4-1 .2-.3.5-.5.8-.6.2-.1.4-.1.6-.1.2 0 .4 0 .6.1.2.1.3.2.5.4.1.1.1.3.2.5 0 .3 0 .5-.1.8 0 .1 0 .1-.1.2H8v-.3zm5 9.3H8V5h5v8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gist" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.57 1.14l3.28 3.3.15.36v9.7l-.5.5h-11l-.5-.5v-13l.5-.5h7.72l.35.14zM10 5h3l-3-3v3zM3 2v12h10V6H9.5L9 5.5V2H3zm2.062 7.533l1.817-1.828L6.17 7 4 9.179v.707l2.171 2.174.707-.707-1.816-1.82zM8.8 7.714l.7-.709 2.189 2.175v.709L9.5 12.062l-.705-.709 1.831-1.82L8.8 7.714z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gist-fork" xmlns="http://www.w3.org/2000/svg"><path d="M14 4a2 2 0 10-2.47 1.94V7a.48.48 0 01-.27.44L8.49 8.88l-2.76-1.4A.49.49 0 015.46 7V5.94a2 2 0 10-1 0V7a1.51 1.51 0 00.82 1.34L8 9.74v1.32a2 2 0 101 0V9.74l2.7-1.36A1.49 1.49 0 0012.52 7V5.92A2 2 0 0014 4zM4 4a1 1 0 112 0 1 1 0 01-2 0zm5.47 9a1 1 0 11-2 0 1 1 0 012 0zM12 5a1 1 0 110-2 1 1 0 010 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gist-new" xmlns="http://www.w3.org/2000/svg"><path d="M14 7v1H8v6H7V8H1V7h6V1h1v6h6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gist-private" xmlns="http://www.w3.org/2000/svg"><path d="M13 7h-1V5a4 4 0 10-8 0v2H3L2 8v6l1 1h10l1-1V8l-1-1zM5 5a3 3 0 116 0v2H5V5zm8 9H3V8h10v6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gist-secret" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 14h4v.91l.09.09H2.5l-.5-.5v-13l.5-.5h7.72l.35.14 3.28 3.3.15.36v2.54a3.1 3.1 0 00-1-.94V6H9.5L9 5.5V2H3v12zm10-9l-3-3v3h3zm.5 4v1h1l.5.5v4l-.5.5h-6l-.5-.5v-4l.5-.5h1V9a2 2 0 014 0zm-2.707-.707A1 1 0 0010.5 9v1h2V9a1 1 0 00-1.707-.707zM9 11v3h5v-3H9z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="git-branch" xmlns="http://www.w3.org/2000/svg"><path d="M21.007 8.222A3.738 3.738 0 0015.045 5.2a3.737 3.737 0 001.156 6.583 2.988 2.988 0 01-2.668 1.67h-2.99a4.456 4.456 0 00-2.989 1.165V7.4a3.737 3.737 0 10-1.494 0v9.117a3.776 3.776 0 101.816.099 2.99 2.99 0 012.668-1.667h2.99a4.484 4.484 0 004.223-3.039 3.736 3.736 0 003.25-3.687zM4.565 3.738a2.242 2.242 0 114.484 0 2.242 2.242 0 01-4.484 0zm4.484 16.441a2.242 2.242 0 11-4.484 0 2.242 2.242 0 014.484 0zm8.221-9.715a2.242 2.242 0 110-4.485 2.242 2.242 0 010 4.485z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="git-branch-create" xmlns="http://www.w3.org/2000/svg"><path d="M21.007 8.222A3.738 3.738 0 0015.045 5.2a3.737 3.737 0 001.156 6.583 2.988 2.988 0 01-2.668 1.67h-2.99a4.456 4.456 0 00-2.989 1.165V7.4a3.737 3.737 0 10-1.494 0v9.117a3.776 3.776 0 101.816.099 2.99 2.99 0 012.668-1.667h2.99a4.484 4.484 0 004.223-3.039 3.736 3.736 0 003.25-3.687zM4.565 3.738a2.242 2.242 0 114.484 0 2.242 2.242 0 01-4.484 0zm4.484 16.441a2.242 2.242 0 11-4.484 0 2.242 2.242 0 014.484 0zm8.221-9.715a2.242 2.242 0 110-4.485 2.242 2.242 0 010 4.485z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="git-branch-delete" xmlns="http://www.w3.org/2000/svg"><path d="M21.007 8.222A3.738 3.738 0 0015.045 5.2a3.737 3.737 0 001.156 6.583 2.988 2.988 0 01-2.668 1.67h-2.99a4.456 4.456 0 00-2.989 1.165V7.4a3.737 3.737 0 10-1.494 0v9.117a3.776 3.776 0 101.816.099 2.99 2.99 0 012.668-1.667h2.99a4.484 4.484 0 004.223-3.039 3.736 3.736 0 003.25-3.687zM4.565 3.738a2.242 2.242 0 114.484 0 2.242 2.242 0 01-4.484 0zm4.484 16.441a2.242 2.242 0 11-4.484 0 2.242 2.242 0 014.484 0zm8.221-9.715a2.242 2.242 0 110-4.485 2.242 2.242 0 010 4.485z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-commit" xmlns="http://www.w3.org/2000/svg"><path d="M10.979 5a3.42 3.42 0 00-2-1V0h-1v4a3.5 3.5 0 00-.18 6.89h.18v4h1v-4a3.08 3.08 0 00.84-.23 3.42 3.42 0 001.57-1.29 3.46 3.46 0 00-.41-4.37zm-.7 4.24a2.51 2.51 0 01-3.159.31 2.5 2.5 0 01-.92-1.12 2.49 2.49 0 011.82-3.41 2.72 2.72 0 01.49 0 2.5 2.5 0 012.54 2.5 2.51 2.51 0 01-.8 1.75l.03-.03z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-compare" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.389 12.99l-1.27-1.27.67-.7 2.13 2.13v.7l-2.13 2.13-.71-.71L7.349 14h-1.85a2.49 2.49 0 01-2.5-2.5V5.95a2.59 2.59 0 01-1.27-.68 2.52 2.52 0 01-.54-2.73A2.5 2.5 0 013.499 1a2.45 2.45 0 011 .19 2.48 2.48 0 011.35 1.35c.133.317.197.658.19 1a2.5 2.5 0 01-2 2.45v5.5a1.5 1.5 0 001.5 1.5h1.85zm-4.68-8.25a1.5 1.5 0 002.08-2.08 1.55 1.55 0 00-.68-.56 1.49 1.49 0 00-.86-.08 1.49 1.49 0 00-1.18 1.18 1.49 1.49 0 00.08.86c.117.277.311.513.56.68zm10.33 6.3c.48.098.922.335 1.27.68a2.51 2.51 0 01.31 3.159 2.5 2.5 0 11-3.47-3.468c.269-.182.571-.308.89-.37V5.49a1.5 1.5 0 00-1.5-1.5h-1.85l1.27 1.27-.71.71-2.13-2.13v-.7l2.13-2.13.71.71-1.27 1.27h1.85a2.49 2.49 0 012.5 2.5v5.55zm-.351 3.943a1.5 1.5 0 001.1-2.322 1.55 1.55 0 00-.68-.56 1.49 1.49 0 00-.859-.08 1.49 1.49 0 00-1.18 1.18 1.49 1.49 0 00.08.86 1.5 1.5 0 001.539.922z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-fork-private" xmlns="http://www.w3.org/2000/svg"><path d="M13 7h-1V5a4 4 0 10-8 0v2H3L2 8v6l1 1h10l1-1V8l-1-1zM5 5a3 3 0 116 0v2H5V5zm8 9H3V8h10v6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-merge" xmlns="http://www.w3.org/2000/svg"><path d="M13.273 7.73a2.51 2.51 0 00-3.159-.31 2.5 2.5 0 00-.921 1.12 2.23 2.23 0 00-.13.44 4.52 4.52 0 01-4-4 2.23 2.23 0 00.44-.13 2.5 2.5 0 001.54-2.31 2.45 2.45 0 00-.19-1A2.48 2.48 0 005.503.19a2.45 2.45 0 00-1-.19 2.5 2.5 0 00-2.31 1.54 2.52 2.52 0 00.54 2.73c.35.343.79.579 1.27.68v5.1a2.411 2.411 0 00-.89.37 2.5 2.5 0 103.47 3.468 2.5 2.5 0 00.42-1.387 2.45 2.45 0 00-.19-1 2.48 2.48 0 00-1.81-1.49v-2.4a5.52 5.52 0 002 1.73 5.65 5.65 0 002.09.6 2.5 2.5 0 004.95-.49 2.51 2.51 0 00-.77-1.72zm-8.2 3.38c.276.117.512.312.68.56a1.5 1.5 0 01-2.08 2.08 1.55 1.55 0 01-.56-.68 1.49 1.49 0 01-.08-.86 1.49 1.49 0 011.18-1.18 1.49 1.49 0 01.86.08zM4.503 4a1.5 1.5 0 01-1.39-.93 1.49 1.49 0 01-.08-.86 1.49 1.49 0 011.18-1.18 1.49 1.49 0 01.86.08A1.5 1.5 0 014.503 4zm8.06 6.56a1.5 1.5 0 01-2.45-.49 1.49 1.49 0 01-.08-.86 1.49 1.49 0 011.18-1.18 1.49 1.49 0 01.86.08 1.499 1.499 0 01.49 2.45z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-pull-request" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.616 4.928a2.487 2.487 0 01-1.119.922c-.148.06-.458.138-.458.138v5.008a2.51 2.51 0 011.579 1.062c.273.412.419.895.419 1.388.008.343-.057.684-.19 1A2.485 2.485 0 013.5 15.984a2.482 2.482 0 01-1.388-.419A2.487 2.487 0 011.05 13c.095-.486.331-.932.68-1.283.349-.343.79-.579 1.269-.68V5.949a2.6 2.6 0 01-1.269-.68 2.503 2.503 0 01-.68-1.283 2.487 2.487 0 011.06-2.565A2.49 2.49 0 013.5 1a2.504 2.504 0 011.807.729 2.493 2.493 0 01.729 1.81c.002.494-.144.978-.42 1.389zm-.756 7.861a1.5 1.5 0 00-.552-.579 1.45 1.45 0 00-.77-.21 1.495 1.495 0 00-1.47 1.79 1.493 1.493 0 001.18 1.179c.288.058.586.03.86-.08.276-.117.512-.312.68-.56.15-.226.235-.49.249-.76a1.51 1.51 0 00-.177-.78zM2.708 4.741c.247.161.536.25.83.25.271 0 .538-.075.77-.211a1.514 1.514 0 00.729-1.359 1.513 1.513 0 00-.25-.76 1.551 1.551 0 00-.68-.56 1.49 1.49 0 00-.86-.08 1.494 1.494 0 00-1.179 1.18c-.058.288-.03.586.08.86.117.276.312.512.56.68zm10.329 6.296c.48.097.922.335 1.269.68.466.47.729 1.107.725 1.766.002.493-.144.977-.42 1.388a2.499 2.499 0 01-4.532-.899 2.5 2.5 0 011.067-2.565c.267-.183.571-.308.889-.37V5.489a1.5 1.5 0 00-1.5-1.499H8.687l1.269 1.27-.71.709L7.117 3.84v-.7l2.13-2.13.71.711-1.269 1.27h1.85a2.484 2.484 0 012.312 1.541c.125.302.189.628.187.957v5.548zm.557 3.509a1.493 1.493 0 00.191-1.89 1.552 1.552 0 00-.68-.559 1.49 1.49 0 00-.86-.08 1.493 1.493 0 00-1.179 1.18 1.49 1.49 0 00.08.86 1.496 1.496 0 002.448.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-pull-request-abandoned" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.616 4.928a2.487 2.487 0 01-1.119.922c-.148.06-.458.138-.458.138v5.008a2.51 2.51 0 011.579 1.062c.273.412.419.895.419 1.388.008.343-.057.684-.19 1A2.485 2.485 0 013.5 15.984a2.482 2.482 0 01-1.388-.419A2.487 2.487 0 011.05 13c.095-.486.331-.932.68-1.283.349-.343.79-.579 1.269-.68V5.949a2.6 2.6 0 01-1.269-.68 2.503 2.503 0 01-.68-1.283 2.487 2.487 0 011.06-2.565A2.49 2.49 0 013.5 1a2.504 2.504 0 011.807.729 2.493 2.493 0 01.729 1.81c.002.494-.144.978-.42 1.389zm-.756 7.861a1.5 1.5 0 00-.552-.579 1.45 1.45 0 00-.77-.21 1.495 1.495 0 00-1.47 1.79 1.493 1.493 0 001.18 1.179c.288.058.586.03.86-.08.276-.117.512-.312.68-.56.15-.226.235-.49.249-.76a1.51 1.51 0 00-.177-.78zM2.708 4.741c.247.161.536.25.83.25.271 0 .538-.075.77-.211a1.514 1.514 0 00.729-1.359 1.513 1.513 0 00-.25-.76 1.551 1.551 0 00-.68-.56 1.49 1.49 0 00-.86-.08 1.494 1.494 0 00-1.179 1.18c-.058.288-.03.586.08.86.117.276.312.512.56.68zm10.329 6.296c.48.097.922.335 1.269.68.466.47.729 1.107.725 1.766.002.493-.144.977-.42 1.388a2.499 2.499 0 01-4.532-.899 2.5 2.5 0 011.067-2.565c.267-.183.571-.308.889-.37V5.489a1.5 1.5 0 00-1.5-1.499H8.687l1.269 1.27-.71.709L7.117 3.84v-.7l2.13-2.13.71.711-1.269 1.27h1.85a2.484 2.484 0 012.312 1.541c.125.302.189.628.187.957v5.548zm.557 3.509a1.493 1.493 0 00.191-1.89 1.552 1.552 0 00-.68-.559 1.49 1.49 0 00-.86-.08 1.493 1.493 0 00-1.179 1.18 1.49 1.49 0 00.08.86 1.496 1.496 0 002.448.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-pull-request-closed" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.616 4.928a2.487 2.487 0 01-1.119.922c-.148.06-.458.138-.458.138v5.008a2.51 2.51 0 011.579 1.062c.273.412.419.895.419 1.388.008.343-.057.684-.19 1A2.485 2.485 0 013.5 15.984a2.48 2.48 0 01-1.388-.42A2.486 2.486 0 011.05 13c.095-.486.331-.932.68-1.283.349-.343.79-.579 1.269-.68V5.949a2.6 2.6 0 01-1.269-.68 2.503 2.503 0 01-.68-1.283A2.487 2.487 0 012.11 1.421 2.49 2.49 0 013.5 1a2.504 2.504 0 011.807.729 2.493 2.493 0 01.729 1.81c.002.494-.144.977-.42 1.389zm-.756 7.861a1.5 1.5 0 00-.552-.579 1.45 1.45 0 00-.77-.21 1.495 1.495 0 00-1.47 1.79 1.493 1.493 0 001.18 1.179c.288.058.586.03.86-.08.276-.117.512-.312.68-.56.15-.226.235-.49.249-.76a1.51 1.51 0 00-.177-.78zM2.708 4.741c.247.161.536.25.83.25.271 0 .538-.075.77-.211a1.514 1.514 0 00.729-1.36 1.513 1.513 0 00-.25-.76 1.551 1.551 0 00-.68-.559 1.49 1.49 0 00-.86-.08 1.494 1.494 0 00-1.179 1.18c-.058.288-.03.586.08.86.117.276.312.512.56.68zm10.329 6.296c.48.097.922.335 1.269.68.466.47.729 1.107.725 1.766.002.493-.144.977-.42 1.388a2.5 2.5 0 01-3.848.384 2.5 2.5 0 01.382-3.848c.268-.183.572-.308.89-.37V7.489h1.002v3.548zm.557 3.508a1.493 1.493 0 00.191-1.888 1.551 1.551 0 00-.68-.56 1.49 1.49 0 00-.86-.08 1.493 1.493 0 00-1.179 1.18 1.49 1.49 0 00.08.86 1.497 1.497 0 002.448.49zM11.688 3.4L10 5.088l.707.707 1.688-1.688 1.687 1.688.707-.707L13.103 3.4l1.688-1.687-.708-.707-1.687 1.687-1.688-1.687-.707.707L11.688 3.4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-pull-request-create" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.616 4.928a2.487 2.487 0 01-1.119.922c-.148.06-.458.138-.458.138v5.008a2.51 2.51 0 011.579 1.062c.273.412.419.895.419 1.388.008.343-.057.684-.19 1A2.485 2.485 0 013.5 15.984a2.482 2.482 0 01-1.388-.419A2.487 2.487 0 011.05 13c.095-.486.331-.932.68-1.283.349-.343.79-.579 1.269-.68V5.949a2.6 2.6 0 01-1.269-.68 2.503 2.503 0 01-.68-1.283 2.487 2.487 0 011.06-2.565A2.49 2.49 0 013.5 1a2.504 2.504 0 011.807.729 2.493 2.493 0 01.729 1.81c.002.494-.144.978-.42 1.389zm-.756 7.861a1.5 1.5 0 00-.552-.579 1.45 1.45 0 00-.77-.21 1.495 1.495 0 00-1.47 1.79 1.493 1.493 0 001.18 1.179c.288.058.586.03.86-.08.276-.117.512-.312.68-.56.15-.226.235-.49.249-.76a1.51 1.51 0 00-.177-.78zM2.708 4.741c.247.161.536.25.83.25.271 0 .538-.075.77-.211a1.514 1.514 0 00.729-1.359 1.513 1.513 0 00-.25-.76 1.551 1.551 0 00-.68-.56 1.49 1.49 0 00-.86-.08 1.494 1.494 0 00-1.179 1.18c-.058.288-.03.586.08.86.117.276.312.512.56.68zM13.037 7h-1.002V5.49a1.5 1.5 0 00-1.5-1.5H8.687l1.269 1.27-.71.709L7.117 3.84v-.7l2.13-2.13.71.711-1.269 1.27h1.85a2.484 2.484 0 012.312 1.541c.125.302.189.628.187.957V7zM13 16h-1v-3H9v-1h3V9h1v3h3v1h-3v3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="git-pull-request-draft" xmlns="http://www.w3.org/2000/svg"><path d="M4.497 5.85c.456-.19.846-.511 1.119-.922.275-.412.421-.895.419-1.388a2.493 2.493 0 00-1.538-2.35 2.504 2.504 0 00-.998-.19 2.49 2.49 0 00-1.388.42A2.487 2.487 0 001.05 3.987c.095.486.331.932.68 1.283a2.6 2.6 0 001.269.68v5.088c-.48.101-.92.337-1.269.68-.349.35-.585.797-.68 1.283a2.486 2.486 0 001.062 2.565 2.48 2.48 0 001.388.419 2.44 2.44 0 001-.19 2.485 2.485 0 001.538-2.349 2.51 2.51 0 00-1.998-2.45V5.989s.31-.078.458-.138zm-.189 6.36a1.5 1.5 0 01.48 2.12 1.551 1.551 0 01-.68.559 1.492 1.492 0 01-.86.08 1.487 1.487 0 01-1.18-1.18 1.49 1.49 0 01.08-.86c.117-.276.312-.512.56-.68.245-.164.534-.25.83-.25.271-.003.538.07.77.211zm-.77-7.22a1.52 1.52 0 01-.83-.25 1.551 1.551 0 01-.56-.68 1.491 1.491 0 01-.08-.86 1.486 1.486 0 011.18-1.179 1.49 1.49 0 01.86.08c.276.117.512.312.68.56A1.49 1.49 0 014.86 4.2c-.129.24-.32.438-.552.579-.232.136-.499.21-.77.21z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15.054 13.5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm-2.5 1.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"/><circle cx="12.554" cy="7.751" r="1"/><circle cx="12.554" cy="3.501" r="1"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="github" xmlns="http://www.w3.org/2000/svg"><path d="M12 0a12 12 0 100 24 12 12 0 000-24zm3.163 21.783h-.093a.513.513 0 01-.382-.14.513.513 0 01-.14-.372v-1.406c.006-.467.01-.94.01-1.416a3.693 3.693 0 00-.151-1.028 1.832 1.832 0 00-.542-.875 8.014 8.014 0 002.038-.471 4.051 4.051 0 001.466-.964c.407-.427.71-.943.885-1.506a6.77 6.77 0 00.3-2.13 4.138 4.138 0 00-.26-1.476 3.892 3.892 0 00-.795-1.284 2.81 2.81 0 00.162-.582c.033-.2.05-.402.05-.604 0-.26-.03-.52-.09-.773a5.309 5.309 0 00-.221-.763.293.293 0 00-.111-.02h-.11c-.23.002-.456.04-.674.111a5.34 5.34 0 00-.703.26 6.503 6.503 0 00-.661.343c-.215.127-.405.249-.573.362a9.578 9.578 0 00-5.143 0 13.507 13.507 0 00-.572-.362 6.022 6.022 0 00-.672-.342 4.516 4.516 0 00-.705-.261 2.203 2.203 0 00-.662-.111h-.11a.29.29 0 00-.11.02 5.844 5.844 0 00-.23.763c-.054.254-.08.513-.081.773 0 .202.017.404.051.604.033.199.086.394.16.582A3.888 3.888 0 005.702 10a4.142 4.142 0 00-.263 1.476 6.871 6.871 0 00.292 2.12c.181.563.483 1.08.884 1.516.415.422.915.75 1.466.964.653.25 1.337.41 2.033.476a1.828 1.828 0 00-.452.633 2.99 2.99 0 00-.2.744 2.754 2.754 0 01-1.175.27 1.788 1.788 0 01-1.065-.3 2.904 2.904 0 01-.752-.824 3.1 3.1 0 00-.292-.382 2.693 2.693 0 00-.372-.343 1.841 1.841 0 00-.432-.24 1.2 1.2 0 00-.481-.101c-.04.001-.08.005-.12.01a.649.649 0 00-.162.02.408.408 0 00-.13.06.116.116 0 00-.06.1.33.33 0 00.14.242c.093.074.17.131.232.171l.03.021c.133.103.261.214.382.333.112.098.213.209.3.33.09.119.168.246.231.381.073.134.15.288.231.463.188.474.522.875.954 1.145.453.243.961.364 1.476.351.174 0 .349-.01.522-.03.172-.028.343-.057.515-.091v1.743a.5.5 0 01-.533.521h-.062a10.286 10.286 0 116.324 0v.005z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="github-action" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.04 10h2.58l.65 1H2.54l-.5-.5v-9l.5-.5h12l.5.5v4.77l-1-1.75V2h-11v8zm5.54 1l-1.41 3.47h2.2L15 8.7 14.27 7h-1.63l.82-1.46L12.63 4H9.76l-.92.59-2.28 5L7.47 11h1.11zm1.18-6h2.87l-1.87 3h3.51l-5.76 5.84L10.2 10H7.47l2.29-5zM6.95 7H4.04V6H7.4l-.45 1zm-.9 2H4.04V8H6.5l-.45 1z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="github-alt" xmlns="http://www.w3.org/2000/svg"><path d="M21.035 5.257c.91 1.092 1.364 2.366 1.364 3.822 0 5.277-3.002 6.824-5.823 7.279.364.637.455 1.365.455 2.093v3.73c0 .455-.273.728-.637.728a.718.718 0 01-.728-.728v-3.73a2.497 2.497 0 00-.728-2.093l.455-1.183c2.821-.364 5.733-1.274 5.733-6.187 0-1.183-.455-2.275-1.274-3.185l-.182-.727a4.04 4.04 0 00.09-2.73c-.454.09-1.364.273-2.91 1.365l-.547.09a13.307 13.307 0 00-6.55 0l-.547-.09C7.57 2.71 6.66 2.437 6.204 2.437c-.273.91-.273 1.91.09 2.73l-.181.727c-.91.91-1.365 2.093-1.365 3.185 0 4.822 2.73 5.823 5.732 6.187l.364 1.183c-.546.546-.819 1.274-.728 2.002v3.821a.718.718 0 01-.728.728.718.718 0 01-.728-.728V20.18c-3.002.637-4.185-.91-5.095-2.092-.455-.546-.819-1.001-1.274-1.092-.09-.091-.364-.455-.273-.819.091-.364.455-.637.82-.455.91.182 1.455.91 2 1.547.82 1.092 1.639 2.092 4.095 1.547v-.364c-.09-.728.091-1.456.455-2.093-2.73-.546-5.914-2.093-5.914-7.279 0-1.456.455-2.73 1.365-3.822-.273-1.273-.182-2.638.273-3.73l.455-.364C5.749 1.073 7.023.8 9.66 2.437a13.673 13.673 0 016.642 0C18.851.708 20.216.98 20.398 1.072l.455.364c.455 1.274.546 2.548.182 3.821z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="github-inverted" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.976 0A7.977 7.977 0 000 7.976c0 3.522 2.3 6.507 5.431 7.584.392.049.538-.196.538-.392v-1.37c-2.201.49-2.69-1.076-2.69-1.076-.343-.93-.881-1.175-.881-1.175-.734-.489.048-.489.048-.489.783.049 1.224.832 1.224.832.734 1.223 1.859.88 2.3.685.048-.538.293-.88.489-1.076-1.762-.196-3.621-.881-3.621-3.964 0-.88.293-1.566.832-2.153-.05-.147-.343-.978.098-2.055 0 0 .685-.196 2.201.832.636-.196 1.322-.245 2.007-.245s1.37.098 2.006.245c1.517-1.027 2.202-.832 2.202-.832.44 1.077.146 1.908.097 2.104a3.16 3.16 0 01.832 2.153c0 3.083-1.86 3.719-3.62 3.915.293.244.538.733.538 1.467v2.202c0 .196.146.44.538.392A7.984 7.984 0 0016 7.976C15.951 3.572 12.38 0 7.976 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="globe" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.5 1a6.5 6.5 0 110 13 6.5 6.5 0 010-13zm4.894 4a5.527 5.527 0 00-3.053-2.676c.444.84.765 1.74.953 2.676h2.1zm.582 2.995A5.11 5.11 0 0014 7.5a5.464 5.464 0 00-.213-1.5h-2.342c.032.331.055.664.055 1a10.114 10.114 0 01-.206 2h2.493c.095-.329.158-.665.19-1.005zm-3.535 0l.006-.051A9.04 9.04 0 0010.5 7a8.994 8.994 0 00-.076-1H6.576A8.82 8.82 0 006.5 7a8.98 8.98 0 00.233 2h3.534c.077-.332.135-.667.174-1.005zM10.249 5a8.974 8.974 0 00-1.255-2.97C8.83 2.016 8.666 2 8.5 2a3.62 3.62 0 00-.312.015l-.182.015L8 2.04A8.97 8.97 0 006.751 5h3.498zM5.706 5a9.959 9.959 0 01.966-2.681A5.527 5.527 0 003.606 5h2.1zM3.213 6A5.48 5.48 0 003 7.5 5.48 5.48 0 003.213 9h2.493A10.016 10.016 0 015.5 7c0-.336.023-.669.055-1H3.213zm2.754 4h-2.36a5.515 5.515 0 003.819 2.893A10.023 10.023 0 015.967 10zM8.5 12.644A8.942 8.942 0 009.978 10H7.022A8.943 8.943 0 008.5 12.644zM11.033 10a10.024 10.024 0 01-1.459 2.893A5.517 5.517 0 0013.393 10h-2.36z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="go-to-file" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 5.914l2.06-2.06v-.708L5.915 1l-.707.707.043.043.25.25 1 1h-3a2.5 2.5 0 000 5H4V7h-.5a1.5 1.5 0 110-3h3L5.207 5.293 5.914 6 6 5.914zM11 2H8.328l-1-1H12l.71.29 3 3L16 5v9l-1 1H6l-1-1V6.5l1 .847V14h9V6h-4V2zm1 0v3h3l-3-3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="grabber" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15 6H1v1h14V6zm0 3H1v1h14V9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="graph" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 14H15v-1H2V0H1v13.5l.5.5zM3 11.5v-8l.5-.5h2l.5.5v8l-.5.5h-2l-.5-.5zm2-.5V4H4v7h1zm6-9.5v10l.5.5h2l.5-.5v-10l-.5-.5h-2l-.5.5zm2 .5v9h-1V2h1zm-6 9.5v-6l.5-.5h2l.5.5v6l-.5.5h-2l-.5-.5zm2-.5V6H8v5h1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="graph-left" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.119 4L3 4.881l-.619.619L.715 3.833v-.618L2.38 1.548l.62.619L2.167 3H15v1H2.119zM4 14.546V5.455L4.5 5h2l.5.455v9.09L6.5 15h-2l-.5-.454zm2-.455V5.909H5v8.182h1zm2-1.535V5.444L8.5 5h2l.5.444v7.112l-.5.444h-2l-.5-.444zm2-.445V5.89H9v6.222h1zm2-6.682v5.143l.5.428h2l.5-.428V5.429L14.5 5h-2l-.5.429zm2 .428v4.286h-1V5.857h1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="graph-line" xmlns="http://www.w3.org/2000/svg"><path d="M15 13v1H1.5l-.5-.5V0h1v13h13z"/><path d="M13 3.207L7.854 8.354h-.708L5.5 6.707l-3.646 3.647-.708-.708 4-4h.708L7.5 7.293l5.146-5.147h.707l2 2-.707.708L13 3.207z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="graph-scatter" xmlns="http://www.w3.org/2000/svg"><path d="M15 13v1H1.5l-.5-.5V0h1v13h13z"/><path d="M5 2h2v2H5zM12 1h2v2h-2zM8 5h2v2H8zM5 9h2v2H5zM12 8h2v2h-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="gripper" xmlns="http://www.w3.org/2000/svg"><path d="M5 3h2v2H5zm0 4h2v2H5zm0 4h2v2H5zm4-8h2v2H9zm0 4h2v2H9zm0 4h2v2H9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="group-by-ref-type" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h2v1H2v12h1.5v1h-2l-.5-.5v-13l.5-.5zm6 6h-2L5 6.5v-2l.5-.5h2l.5.5v2l-.5.5zM6 6h1V5H6v1zm7.5 1h-3l-.5-.5v-3l.5-.5h3l.5.5v3l-.5.5zM11 6h2V4h-2v2zm-3.5 6h-2l-.5-.5v-2l.5-.5h2l.5.5v2l-.5.5zM6 11h1v-1H6v1zm7.5 2h-3l-.5-.5v-3l.5-.5h3l.5.5v3l-.5.5zM11 12h2v-2h-2v2zm-1-2H8v1h2v-1zm0-5H8v1h2V5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="heart" xmlns="http://www.w3.org/2000/svg"><path d="M14.88 4.78a3.489 3.489 0 00-.37-.9 3.24 3.24 0 00-.6-.79 3.78 3.78 0 00-1.21-.81 3.74 3.74 0 00-2.84 0 4 4 0 00-1.16.75l-.05.06-.65.65-.65-.65-.05-.06a4 4 0 00-1.16-.75 3.74 3.74 0 00-2.84 0 3.78 3.78 0 00-1.21.81 3.55 3.55 0 00-.97 1.69 3.75 3.75 0 00-.12 1c0 .317.04.633.12.94a4 4 0 00.36.89 3.8 3.8 0 00.61.79L8 14.31l5.91-5.91c.237-.233.44-.5.6-.79A3.578 3.578 0 0015 5.78a3.747 3.747 0 00-.12-1zm-1 1.63a2.69 2.69 0 01-.69 1.21l-5.21 5.2-5.21-5.2a2.9 2.9 0 01-.44-.57 3 3 0 01-.27-.65 3.25 3.25 0 01-.08-.69A3.36 3.36 0 012.06 5a2.8 2.8 0 01.27-.65c.12-.21.268-.4.44-.57a2.91 2.91 0 01.89-.6 2.8 2.8 0 012.08 0c.33.137.628.338.88.59l1.36 1.37 1.36-1.37a2.72 2.72 0 01.88-.59 2.8 2.8 0 012.08 0c.331.143.633.347.89.6.174.165.32.357.43.57a2.69 2.69 0 01.35 1.34 2.6 2.6 0 01-.06.72h-.03z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="history" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.507 12.324a7 7 0 00.065-8.56A7 7 0 002 4.393V2H1v3.5l.5.5H5V5H2.811a6.008 6.008 0 11-.135 5.77l-.887.462a7 7 0 0011.718 1.092zm-3.361-.97l.708-.707L8 7.792V4H7v4l.146.354 3 3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="home" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.36 1.37l6.36 5.8-.71.71L13 6.964v6.526l-.5.5h-3l-.5-.5v-3.5H7v3.5l-.5.5h-3l-.5-.5V6.972L2 7.88l-.71-.71 6.35-5.8h.72zM4 6.063v6.927h2v-3.5l.5-.5h3l.5.5v3.5h2V6.057L8 2.43 4 6.063z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="horizontal-rule" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.432 10h.823V4h-.823v2.61h-2.61V4H3v6h.823V7.394h2.61V10zm5.668 0h.9l-1.28-2.63c.131-.058.26-.134.389-.23a1.666 1.666 0 00.585-.797c.064-.171.096-.364.096-.58a1.77 1.77 0 00-.082-.557 1.644 1.644 0 00-.22-.446 1.504 1.504 0 00-.31-.341 1.864 1.864 0 00-.737-.373A1.446 1.446 0 0011.1 4H8.64v6h.824V7.518h1.467L12.1 10zm-.681-3.32a.874.874 0 01-.293.055H9.463V4.787h1.663a.87.87 0 01.576.24.956.956 0 01.306.737c0 .168-.029.314-.087.437a.91.91 0 01-.503.479zM13 12H3v1h10v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="hubot" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.48 4h4l.5.5v2.03h.52l.5.5V8l-.5.5h-.52v3l-.5.5H9.36l-2.5 2.76L6 14.4V12H3.5l-.5-.64V8.5h-.5L2 8v-.97l.5-.5H3V4.36L3.53 4h4V2.86A1 1 0 017 2a1 1 0 012 0 1 1 0 01-.52.83V4zM12 8V5H4v5.86l2.5.14H7v2.19l1.8-2.04.35-.15H12V8zm-2.12.51a2.71 2.71 0 01-1.37.74v-.01a2.71 2.71 0 01-2.42-.74l-.7.71c.34.34.745.608 1.19.79.45.188.932.286 1.42.29a3.7 3.7 0 002.58-1.07l-.7-.71zM6.49 6.5h-1v1h1v-1zm3 0h1v1h-1v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="inbox" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 14h13l.5-.5V9l-2.77-7.66-.47-.34H4.27l-.47.33L1 8.74v4.76l.5.5zM14 13H2v-2.98h2.55l.74 1.25.43.24h4.57l.44-.26.69-1.23H14V13zm-.022-3.98H11.12l-.43.26-.69 1.23H6.01l-.75-1.25-.43-.24H2V9l2.62-7h6.78l2.578 7.02z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="indent" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 5v1.984a.5.5 0 00.5.5h6.882L9.749 5.851l.707-.707 2.121 2.121.423.423v.568L10.456 10.8l-.707-.707 1.61-1.609H4.5a1.5 1.5 0 01-1.5-1.5V5h1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="info" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.568 1.031A6.8 6.8 0 0112.76 3.05a7.06 7.06 0 01.46 9.39 6.85 6.85 0 01-8.58 1.74 7 7 0 01-3.12-3.5 7.12 7.12 0 01-.23-4.71 7 7 0 012.77-3.79 6.8 6.8 0 014.508-1.149zM9.04 13.88a5.89 5.89 0 003.41-2.07 6.07 6.07 0 00-.4-8.06 5.82 5.82 0 00-7.43-.74 6.06 6.06 0 00.5 10.29 5.81 5.81 0 003.92.58zM7.375 6h1.25V5h-1.25v1zm1.25 1v4h-1.25V7h1.25z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="inspect" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 3l1-1h12l1 1v6h-1V3H2v8h5v1H2l-1-1V3zm14.707 9.707L9 6v9.414l2.707-2.707h4zM10 13V8.414l3.293 3.293h-2L10 13z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="issue-closed" xmlns="http://www.w3.org/2000/svg"><path d="M6.27 10.87h.71l4.56-4.56-.71-.71-4.2 4.21-1.92-1.92L4 8.6l2.27 2.27z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="issue-draft" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.732 9.2l.952.31A6.494 6.494 0 0014 7.5c0-.701-.111-1.377-.316-2.01l-.952.31c.174.534.268 1.105.268 1.7s-.094 1.166-.268 1.7zm-.33-4.197l.89-.455a6.529 6.529 0 00-2.84-2.84l-.455.89a5.528 5.528 0 012.405 2.405zM9.2 2.268l.31-.951A6.495 6.495 0 007.5 1c-.701 0-1.377.111-2.01.317l.31.95A5.495 5.495 0 017.5 2c.595 0 1.166.094 1.7.268zm-4.197.33l-.455-.89a6.528 6.528 0 00-2.84 2.84l.89.455a5.528 5.528 0 012.405-2.405zM1 7.5c0-.701.111-1.377.317-2.01l.95.31A5.495 5.495 0 002 7.5c0 .595.094 1.166.268 1.7l-.951.31A6.495 6.495 0 011 7.5zm1.598 2.497l-.89.455a6.529 6.529 0 002.84 2.84l.455-.89a5.528 5.528 0 01-2.405-2.405zM5.8 12.732l-.31.952A6.494 6.494 0 007.5 14c.701 0 1.377-.111 2.01-.316l-.31-.952A5.497 5.497 0 017.5 13a5.497 5.497 0 01-1.7-.268zm4.197-.33l.455.89a6.53 6.53 0 002.84-2.84l-.89-.455a5.528 5.528 0 01-2.405 2.405zM7.5 8.5a1 1 0 100-2 1 1 0 000 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="issue-opened" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.568 1.031A6.8 6.8 0 0112.76 3.05a7.06 7.06 0 01.46 9.39 6.85 6.85 0 01-8.58 1.74 7 7 0 01-3.12-3.5 7.12 7.12 0 01-.23-4.71 7 7 0 012.77-3.79 6.8 6.8 0 014.508-1.149zM9.04 13.88a5.89 5.89 0 003.41-2.07 6.07 6.07 0 00-.4-8.06 5.82 5.82 0 00-7.43-.74 6.06 6.06 0 00.5 10.29 5.81 5.81 0 003.92.58zM7.375 6h1.25V5h-1.25v1zm1.25 1v4h-1.25V7h1.25z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="issue-reopened" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.28 5.656L2 7.006l-.66-.26L0 3.506l.92-.38.81 1.95a6.48 6.48 0 0112.48 1.93h-1a5.48 5.48 0 00-10.64-1.28l2.32-1 .39.93zm8.86 2.68l1.34 3.23-.92.44-.82-2a6.49 6.49 0 01-12.5-2h1v-.5a5.49 5.49 0 0010.64 1.89l-2.25.93-.39-.92 3.25-1.35.65.28z"/><circle cx="7.74" cy="7.54" r="1"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="issues" xmlns="http://www.w3.org/2000/svg"><path d="M7.5 1a6.5 6.5 0 100 13 6.5 6.5 0 000-13zm0 12a5.5 5.5 0 110-11 5.5 5.5 0 010 11z"/><circle cx="7.5" cy="7.5" r="1"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="italic" xmlns="http://www.w3.org/2000/svg"><path d="M9.001 13.593l-.097.325H4l.123-.325c.492-.012.817-.053.976-.123.257-.1.448-.238.57-.413.194-.276.394-.768.599-1.477l2.074-7.19c.176-.597.263-1.048.263-1.353a.643.643 0 00-.114-.387.683.683 0 00-.351-.237c-.153-.059-.454-.088-.906-.088L7.34 2h4.605l-.096.325c-.375-.006-.654.035-.835.123a1.358 1.358 0 00-.607.501c-.134.217-.31.697-.527 1.442l-2.066 7.19c-.187.661-.28 1.083-.28 1.265 0 .146.034.272.105.378.076.1.193.178.351.237.164.053.501.097 1.011.132z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="jersey" xmlns="http://www.w3.org/2000/svg"><path d="M11.91 14.22H4.06l-.5-.5V7.06H2.15l-.48-.38L1 4l.33-.6L5.59 2l.64.32a2.7 2.7 0 00.21.44c.071.103.152.2.24.29.168.169.369.302.59.39a1.82 1.82 0 001.43 0 1.74 1.74 0 00.59-.39c.09-.095.173-.195.25-.3l.15-.29a1.21 1.21 0 00.05-.14l.64-.32 4.26 1.42L15 4l-.66 2.66-.49.38h-1.44v6.66l-.5.52zm-7.35-1h6.85V6.56l.5-.5h1.52l.46-1.83-3.4-1.14a1.132 1.132 0 01-.12.21c-.11.161-.233.312-.37.45a2.75 2.75 0 01-.91.61 2.85 2.85 0 01-2.22 0A2.92 2.92 0 016 3.75a2.17 2.17 0 01-.36-.44l-.13-.22-3.43 1.14.46 1.83h1.52l.5.5v6.66z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="json" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.984V2h-.09c-.313 0-.616.062-.909.185a2.33 2.33 0 00-.775.53 2.23 2.23 0 00-.493.753v.001a3.542 3.542 0 00-.198.83v.002a6.08 6.08 0 00-.024.863c.012.29.018.58.018.869 0 .203-.04.393-.117.572v.001a1.504 1.504 0 01-.765.787 1.376 1.376 0 01-.558.115H2v.984h.09c.195 0 .38.04.556.121l.001.001c.178.078.329.184.455.318l.002.002c.13.13.233.285.307.465l.001.002c.078.18.117.368.117.566 0 .29-.006.58-.018.869-.012.296-.004.585.024.87v.001c.033.283.099.558.197.824v.001c.106.273.271.524.494.753.223.23.482.407.775.53.293.123.596.185.91.185H6v-.984h-.09c-.2 0-.387-.038-.563-.115a1.613 1.613 0 01-.457-.32 1.659 1.659 0 01-.309-.467c-.074-.18-.11-.37-.11-.573 0-.228.003-.453.011-.672.008-.228.008-.45 0-.665a4.639 4.639 0 00-.055-.64 2.682 2.682 0 00-.168-.609A2.284 2.284 0 003.522 8a2.284 2.284 0 00.738-.955c.08-.192.135-.393.168-.602.033-.21.051-.423.055-.64.008-.22.008-.442 0-.666-.008-.224-.012-.45-.012-.678a1.47 1.47 0 01.877-1.354 1.33 1.33 0 01.563-.121H6zm4 10.032V14h.09c.313 0 .616-.062.909-.185.293-.123.552-.3.775-.53.223-.23.388-.48.493-.753v-.001c.1-.266.165-.543.198-.83v-.002c.028-.28.036-.567.024-.863-.012-.29-.018-.58-.018-.869 0-.203.04-.393.117-.572v-.001a1.502 1.502 0 01.765-.787 1.38 1.38 0 01.558-.115H14v-.984h-.09c-.196 0-.381-.04-.557-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.415 1.415 0 01-.307-.465v-.002a1.405 1.405 0 01-.118-.566c0-.29.006-.58.018-.869a6.174 6.174 0 00-.024-.87v-.001a3.537 3.537 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.331 2.331 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .387.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.285 2.285 0 00.738.955 2.285 2.285 0 00-.738.955 2.689 2.689 0 00-.168.602c-.033.21-.051.423-.055.64a9.15 9.15 0 000 .666c.008.224.012.45.012.678a1.471 1.471 0 01-.877 1.354 1.33 1.33 0 01-.563.121H10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="kebab-horizontal" xmlns="http://www.w3.org/2000/svg"><path d="M4 8a1 1 0 11-2 0 1 1 0 012 0zm5 0a1 1 0 11-2 0 1 1 0 012 0zm5 0a1 1 0 11-2 0 1 1 0 012 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="kebab-vertical" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.444 13.832a1 1 0 101.111-1.663 1 1 0 00-1.11 1.662zM8 9a1 1 0 110-2 1 1 0 010 2zm0-5a1 1 0 110-2 1 1 0 010 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="key" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.351 1.091a4.528 4.528 0 013.44 3.16c.215.724.247 1.49.093 2.23a4.583 4.583 0 01-4.437 3.6c-.438 0-.874-.063-1.293-.19l-.8.938-.379.175H7v1.5l-.5.5H5v1.5l-.5.5h-3l-.5-.5v-2.307l.146-.353L6.12 6.87a4.464 4.464 0 01-.2-1.405 4.528 4.528 0 015.431-4.375zm1.318 7.2a3.568 3.568 0 001.239-2.005l.004.005A3.543 3.543 0 009.72 2.08a3.576 3.576 0 00-2.8 3.4c-.01.456.07.908.239 1.33l-.11.543L2 12.404v1.6h2v-1.5l.5-.5H6v-1.5l.5-.5h1.245l.876-1.016.561-.14a3.47 3.47 0 001.269.238 3.568 3.568 0 002.218-.795zm-.838-2.732a1 1 0 10-1.662-1.11 1 1 0 001.662 1.11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="keyboard" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 3H3a1 1 0 00-1 1v7a1 1 0 001 1h11a1 1 0 001-1V4a1 1 0 00-1-1zm0 8H3V4h11v7zm-3-6h-1v1h1V5zm-1 2H9v1h1V7zm2-2h1v1h-1V5zm1 4h-1v1h1V9zM6 9h5v1H6V9zm7-2h-2v1h2V7zM8 5h1v1H8V5zm0 2H7v1h1V7zM4 9h1v1H4V9zm0-4h1v1H4V5zm3 0H6v1h1V5zM4 7h2v1H4V7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="law" xmlns="http://www.w3.org/2000/svg"><path d="M14.63 7L13 3h1V2H9V1H8v1H3v1h1L2.38 7H2v1h.15c.156.498.473.93.9 1.23a2.47 2.47 0 002.9 0A2.44 2.44 0 006.86 8H7V7h-.45L4.88 3H8v8H6l-.39.18-2 2.51.39.81h9l.39-.81-2-2.51L11 11H9V3h3.13l-1.67 4H10v1h.15a2.48 2.48 0 004.71 0H15V7h-.37zM5.22 8.51a1.52 1.52 0 01-.72.19 1.45 1.45 0 01-.71-.19A1.47 1.47 0 013.25 8h2.5a1.52 1.52 0 01-.53.51zM5.47 7h-2l1-2.4 1 2.4zm5.29 5L12 13.5H5L6.24 12h4.52zm1.78-7.38l1 2.4h-2l1-2.4zm.68 3.91a1.41 1.41 0 01-.72.19 1.35 1.35 0 01-.71-.19 1.55 1.55 0 01-.54-.53h2.5a1.37 1.37 0 01-.53.53z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layers" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.627 1.087l.558-.004 6.091 4.037-.003.836L8.182 9.92l-.551-.004-5.91-3.963-.003-.828 5.91-4.037zm.286 1.016l-5.021 3.43 5.021 3.368 5.176-3.368-5.176-3.43zM1.793 8.5l5.838 3.915.55.004L14.206 8.5h-1.833l-4.459 2.9-4.325-2.9H1.793zm5.838 6.415L1.793 11h1.795l4.325 2.9 4.459-2.9h1.833l-6.023 3.92-.551-.005z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layers-active" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.185 1.083l-.558.004-5.909 4.037.004.828L7.63 9.915l.55.004 6.092-3.963.003-.836-6.09-4.037zm-5.293 4.45l5.021-3.43 5.176 3.43-5.176 3.368-5.021-3.368zm4.739 6.882L1.793 8.5h1.795l4.325 2.9 4.459-2.9h1.833l-.8.52a4.002 4.002 0 00-4.21 2.739l-1.013.66-.551-.004zm1.373.776l-1.09.71L3.587 11H1.793l5.838 3.915.55.004 1.02-.663a3.988 3.988 0 01-.197-1.065zM11.333 10.506a3 3 0 113.333 4.987 3 3 0 01-3.333-4.987zm1.698 3.817l1.79-2.387-.8-.6-1.48 1.974-.876-.7-.624.78 1.278 1.023.712-.09z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layers-dot" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.185 1.083l-.558.004-5.909 4.037.004.828L7.63 9.915l.55.004 6.092-3.963.003-.836-6.09-4.037zm-5.293 4.45l5.021-3.43 5.176 3.43-5.176 3.368-5.021-3.368zm4.739 6.882L1.793 8.5h1.795l4.325 2.9 4.459-2.9h1.833l-.8.52a4.002 4.002 0 00-4.21 2.739l-1.013.66-.551-.004zm1.373.776l-1.09.71L3.587 11H1.793l5.838 3.915.55.004 1.02-.663a3.988 3.988 0 01-.197-1.065z"/><circle cx="13" cy="13" r="3"/></symbol><symbol fill="currentColor" viewBox="0 0 13 13" id="layout" xmlns="http://www.w3.org/2000/svg"><path d="M1 0L0 1v11l1 1h4l1-1V1L5 0H1zm0 12V1h4v11H1zM7 1l1-1h4l1 1v4l-1 1H8L7 5V1zm1 0v4h4V1H8zM7 8l1-1h4l1 1v4l-1 1H8l-1-1V8zm1 0v4h4V8H8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-activitybar-left" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm12 13H4V2h10v12z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-activitybar-right" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 13V2h10v12H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-centered" xmlns="http://www.w3.org/2000/svg"><path d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 13V2h4v12H2zm8 0V2h4v12h-4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-menubar" xmlns="http://www.w3.org/2000/svg"><path d="M6 3H3v1h3V3zM3 5h3v1H3V5zM6 7H3v1h3V7z"/><path d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 13V2h12v12H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-panel" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 9V2h12v8H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-panel-center" xmlns="http://www.w3.org/2000/svg"><path d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 13V2h2v12H2zm3-4V2h6v8H5zm7-8h2v12h-2V2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-panel-justify" xmlns="http://www.w3.org/2000/svg"><path d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 9V2h2v8H2zm3 0V2h6v8H5zm7 0V2h2v8h-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-panel-left" xmlns="http://www.w3.org/2000/svg"><path d="M1 2l1-1h12l1 1v12l-1 1H2l-1-1V2zm1 0v8h8V2H2zm9 0v12h3V2h-3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-panel-right" xmlns="http://www.w3.org/2000/svg"><path d="M1 2l1-1h12l1 1v12l-1 1H2l-1-1V2zm1 0v12h3V2H2zm4 0v8h8V2H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-sidebar-left" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm12 13H7V2h7v12z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-sidebar-right" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 13V2h7v12H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="layout-statusbar" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 11V2h12v10H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="library" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 2.5l.5-.5h2l.5.5v11l-.5.5h-2l-.5-.5v-11zM6 3v10h1V3H6zm3.171.345l.299-.641 1.88-.684.64.299 3.762 10.336-.299.641-1.879.684-.64-.299L9.17 3.345zm1.11.128l3.42 9.396.94-.341-3.42-9.397-.94.342zM1 2.5l.5-.5h2l.5.5v11l-.5.5h-2l-.5-.5v-11zM2 3v10h1V3H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="light-bulb" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.67 8.658a3.661 3.661 0 00-.781 1.114 3.28 3.28 0 00-.268 1.329v1.6a1.304 1.304 0 01-.794 1.197 1.282 1.282 0 01-.509.102H7.712a1.285 1.285 0 01-.922-.379 1.303 1.303 0 01-.38-.92v-1.6c0-.479-.092-.921-.274-1.329a3.556 3.556 0 00-.776-1.114 4.689 4.689 0 01-1.006-1.437A4.187 4.187 0 014 5.5a4.432 4.432 0 01.616-2.27c.197-.336.432-.64.705-.914a4.6 4.6 0 01.911-.702c.338-.196.7-.348 1.084-.454a4.45 4.45 0 011.2-.16 4.476 4.476 0 012.276.614 4.475 4.475 0 011.622 1.616 4.438 4.438 0 01.616 2.27c0 .617-.117 1.191-.353 1.721a4.69 4.69 0 01-1.006 1.437zM9.623 10.5H7.409v2.201c0 .081.028.15.09.212a.29.29 0 00.213.09h1.606a.289.289 0 00.213-.09.286.286 0 00.09-.212V10.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="lightbulb" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.67 8.658a3.661 3.661 0 00-.781 1.114 3.28 3.28 0 00-.268 1.329v1.6a1.304 1.304 0 01-.794 1.197 1.282 1.282 0 01-.509.102H7.712a1.285 1.285 0 01-.922-.379 1.303 1.303 0 01-.38-.92v-1.6c0-.479-.092-.921-.274-1.329a3.556 3.556 0 00-.776-1.114 4.689 4.689 0 01-1.006-1.437A4.187 4.187 0 014 5.5a4.432 4.432 0 01.616-2.27c.197-.336.432-.64.705-.914a4.6 4.6 0 01.911-.702c.338-.196.7-.348 1.084-.454a4.45 4.45 0 011.2-.16 4.476 4.476 0 012.276.614 4.475 4.475 0 011.622 1.616 4.438 4.438 0 01.616 2.27c0 .617-.117 1.191-.353 1.721a4.69 4.69 0 01-1.006 1.437zM9.623 10.5H7.409v2.201c0 .081.028.15.09.212a.29.29 0 00.213.09h1.606a.289.289 0 00.213-.09.286.286 0 00.09-.212V10.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="lightbulb-autofix" xmlns="http://www.w3.org/2000/svg"><path d="M12 9a3 3 0 100 6 3 3 0 000-6zm1.31 5L12 13l-1.3 1 .5-1.53-1.2-.83h1.47L12 10l.54 1.64H14l-1.2.83.51 1.53z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M11.17 8.085A3.979 3.979 0 008.288 10.5H6.409v2.201c0 .081.028.15.09.212a.29.29 0 00.213.09h1.413c.089.348.223.678.396.982-.066.01-.134.015-.203.015H6.712a1.285 1.285 0 01-.922-.379 1.303 1.303 0 01-.38-.92v-1.6c0-.479-.092-.921-.274-1.329a3.556 3.556 0 00-.776-1.114 4.689 4.689 0 01-1.006-1.437A4.187 4.187 0 013 5.5a4.432 4.432 0 01.616-2.27c.197-.336.432-.64.705-.914a4.6 4.6 0 01.911-.702c.338-.196.7-.348 1.084-.454a4.45 4.45 0 011.2-.16 4.476 4.476 0 012.276.614 4.475 4.475 0 011.622 1.616 4.438 4.438 0 01.616 2.27c0 .617-.117 1.191-.353 1.721a4.537 4.537 0 01-.506.864z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="link" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.4 3h3.085a3.4 3.4 0 013.4 3.4v.205A3.4 3.4 0 017.485 10H7V9h.485A2.4 2.4 0 009.88 6.61V6.4A2.4 2.4 0 007.49 4H4.4A2.4 2.4 0 002 6.4v.205A2.394 2.394 0 004 8.96v1a3.4 3.4 0 01-3-3.35V6.4A3.405 3.405 0 014.4 3zM12 7.04v-1a3.4 3.4 0 013 3.36v.205A3.405 3.405 0 0111.605 13h-3.09A3.4 3.4 0 015.12 9.61V9.4A3.4 3.4 0 018.515 6H9v1h-.485A2.4 2.4 0 006.12 9.4v.205A2.4 2.4 0 008.515 12h3.09A2.4 2.4 0 0014 9.61V9.4a2.394 2.394 0 00-2-2.36z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="link-external" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 1H6v1H2v12h12v-4h1v4.5l-.5.5h-13l-.5-.5v-13l.5-.5z"/><path d="M15 1.5V8h-1V2.707L7.243 9.465l-.707-.708L13.293 2H8V1h6.5l.5.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="list-filter" xmlns="http://www.w3.org/2000/svg"><path d="M6 12v-1h4v1H6zM4 7h8v1H4V7zm10-4v1H2V3h12z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="list-flat" xmlns="http://www.w3.org/2000/svg"><path d="M2 10V9h12v1H2zm0-4h12v1H2V6zm12-3v1H2V3h12zM2 12v1h12v-1H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="list-ordered" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.287 2.326L2.692 2h.677v3h-.708V2.792l-.374.281v-.747zM5 3h10v1H5V3zm0 4h10v1H5V7zm10 4H5v1h10v-1zM3.742 7.626l.029-.039.065-.09a.84.84 0 00.156-.507c0-.12-.02-.24-.057-.354a.848.848 0 00-.492-.529 1.123 1.123 0 00-.452-.082 1.094 1.094 0 00-.458.087.867.867 0 00-.479.522A1.038 1.038 0 002 6.957v.05h.81v-.05a.3.3 0 01.046-.157.174.174 0 01.057-.054.19.19 0 01.172 0 .188.188 0 01.056.06.24.24 0 01.031.081.445.445 0 01-.036.29 1.309 1.309 0 01-.12.182l-1 1.138-.012.013v.54h1.988v-.7h-.9l.65-.724zm-.037 3.817c.046.032.086.07.12.114a.841.841 0 01.167.55c0 .107-.017.213-.05.314a.792.792 0 01-.487.5 1.288 1.288 0 01-.48.079c-.115 0-.23-.016-.341-.049a.94.94 0 01-.258-.123.751.751 0 01-.182-.177 1.063 1.063 0 01-.116-.2A1.038 1.038 0 012 12.078v-.049h.814v.049c0 .027.003.055.009.082a.207.207 0 00.03.074.14.14 0 00.053.052.2.2 0 00.157.008.159.159 0 00.056-.039.22.22 0 00.042-.075.417.417 0 00.017-.126.483.483 0 00-.022-.163.2.2 0 00-.051-.08.138.138 0 00-.06-.029.537.537 0 00-.077-.007h-.161v-.645h.168a.241.241 0 00.069-.011.164.164 0 00.065-.034.175.175 0 00.048-.067.286.286 0 00.021-.121.28.28 0 00-.016-.1.166.166 0 00-.097-.099.2.2 0 00-.156.007.164.164 0 00-.055.053.344.344 0 00-.04.156v.049H2v-.049a.987.987 0 01.18-.544.8.8 0 01.179-.186.87.87 0 01.262-.133c.114-.036.234-.053.354-.051.116-.001.231.01.344.036.092.021.18.055.263.1a.757.757 0 01.32.318.73.73 0 01.09.347.81.81 0 01-.167.528.562.562 0 01-.12.114z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="list-selection" xmlns="http://www.w3.org/2000/svg"><path d="M1 12v-1h9v1H1zm0-5h14v1H1V7zm11-4v1H1V3h11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="list-tree" xmlns="http://www.w3.org/2000/svg"><path d="M14 3v1H2V3h12zm-1 3v1H6V6h7zm0 3v1H5V9h8zm0 3v1H5v-1h8z"/><path d="M5 4h1v9H5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="list-unordered" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 3H1v1h1V3zm0 3H1v1h1V6zM1 9h1v1H1V9zm1 3H1v1h1v-1zm2-9h11v1H4V3zm11 3H4v1h11V6zM4 9h11v1H4V9zm11 3H4v1h11v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="live-share" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.735 1.694L15.178 1l8.029 6.328v1.388l-8.029 6.072-1.443-.694v-2.776h-.59c-4.06-.02-6.71.104-10.61 5.163l-1.534-.493a8.23 8.23 0 01.271-2.255 11.026 11.026 0 013.92-6.793 11.339 11.339 0 017.502-2.547h1.04v-2.7zm1.804 7.917v2.776l5.676-4.281-5.648-4.545v2.664h-2.86A9.299 9.299 0 005.77 8.848a10.444 10.444 0 00-2.401 4.122c3.351-3.213 6.19-3.359 9.798-3.359h2.373zm-7.647 5.896a4.31 4.31 0 114.788 7.166 4.31 4.31 0 01-4.788-7.166zm.955 5.728a2.588 2.588 0 102.878-4.302 2.588 2.588 0 00-2.878 4.302z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="loading" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.917 7A6.002 6.002 0 002.083 7H1.071a7.002 7.002 0 0113.858 0h-1.012z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="location" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.832 2.688A4.056 4.056 0 008.02 1.5h-.04a4.056 4.056 0 00-4 4c-.013.75.198 1.487.606 2.117L7.734 14h.533l3.147-6.383c.409-.63.62-1.367.606-2.117a4.056 4.056 0 00-1.188-2.812zM7.925 2.5l.082.01.074-.01a3.075 3.075 0 012.941 3.037 2.74 2.74 0 01-.467 1.568l-.02.034-.017.035L8 12.279l-2.517-5.1-.017-.039-.02-.034a2.74 2.74 0 01-.467-1.568A3.074 3.074 0 017.924 2.5zm.612 2.169a1 1 0 10-1.112 1.663 1 1 0 001.112-1.663zM6.87 3.837a2 2 0 112.22 3.326 2 2 0 01-2.22-3.326z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="lock" xmlns="http://www.w3.org/2000/svg"><path d="M13 7h-1V5a4 4 0 10-8 0v2H3L2 8v6l1 1h10l1-1V8l-1-1zM5 5a3 3 0 116 0v2H5V5zm8 9H3V8h10v6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="lock-small" xmlns="http://www.w3.org/2000/svg"><path d="M3 8l1-1h8l1 1v5l-1 1H4l-1-1V8zm1 0v5h8V8H4zM11 7V5a3 3 0 00-6 0v2h1V5a2 2 0 114 0v2h1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="log-in" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.02 3.77l.01-.01.99.99V2.5l-.5-.5h-9l-.51.5v.493L2 3v10.29l.36.46 5 1.72L8 15v-1h3.52l.5-.5v-2.25l-1 1V13H8V4.71l-.33-.46L4.036 3h6.984v.77zM7 14.28l-4-1.34V3.72l4 1.34v9.22zm3.09-6.75h4.97v1h-4.93l1.59 1.6-.71.7-2.47-2.46v-.71l2.49-2.48.7.7-1.64 1.65z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="log-out" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.02 3.77v1.56l1-.99V2.5l-.5-.5h-9l-.5.5v.486L2 3v10.29l.36.46 5 1.72L8 15v-1h3.52l.5-.5v-1.81l-1-1V13H8V4.71l-.33-.46L4.036 3h6.984v.77zM7 14.28l-4-1.34V3.72l4 1.34v9.22zm6.52-5.8H8.55v-1h4.93l-1.6-1.6.71-.7 2.47 2.46v.71l-2.49 2.48-.7-.7 1.65-1.65z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="logo-github" xmlns="http://www.w3.org/2000/svg"><path d="M12 0a12 12 0 100 24 12 12 0 000-24zm3.163 21.783h-.093a.513.513 0 01-.382-.14.513.513 0 01-.14-.372v-1.406c.006-.467.01-.94.01-1.416a3.693 3.693 0 00-.151-1.028 1.832 1.832 0 00-.542-.875 8.014 8.014 0 002.038-.471 4.051 4.051 0 001.466-.964c.407-.427.71-.943.885-1.506a6.77 6.77 0 00.3-2.13 4.138 4.138 0 00-.26-1.476 3.892 3.892 0 00-.795-1.284 2.81 2.81 0 00.162-.582c.033-.2.05-.402.05-.604 0-.26-.03-.52-.09-.773a5.309 5.309 0 00-.221-.763.293.293 0 00-.111-.02h-.11c-.23.002-.456.04-.674.111a5.34 5.34 0 00-.703.26 6.503 6.503 0 00-.661.343c-.215.127-.405.249-.573.362a9.578 9.578 0 00-5.143 0 13.507 13.507 0 00-.572-.362 6.022 6.022 0 00-.672-.342 4.516 4.516 0 00-.705-.261 2.203 2.203 0 00-.662-.111h-.11a.29.29 0 00-.11.02 5.844 5.844 0 00-.23.763c-.054.254-.08.513-.081.773 0 .202.017.404.051.604.033.199.086.394.16.582A3.888 3.888 0 005.702 10a4.142 4.142 0 00-.263 1.476 6.871 6.871 0 00.292 2.12c.181.563.483 1.08.884 1.516.415.422.915.75 1.466.964.653.25 1.337.41 2.033.476a1.828 1.828 0 00-.452.633 2.99 2.99 0 00-.2.744 2.754 2.754 0 01-1.175.27 1.788 1.788 0 01-1.065-.3 2.904 2.904 0 01-.752-.824 3.1 3.1 0 00-.292-.382 2.693 2.693 0 00-.372-.343 1.841 1.841 0 00-.432-.24 1.2 1.2 0 00-.481-.101c-.04.001-.08.005-.12.01a.649.649 0 00-.162.02.408.408 0 00-.13.06.116.116 0 00-.06.1.33.33 0 00.14.242c.093.074.17.131.232.171l.03.021c.133.103.261.214.382.333.112.098.213.209.3.33.09.119.168.246.231.381.073.134.15.288.231.463.188.474.522.875.954 1.145.453.243.961.364 1.476.351.174 0 .349-.01.522-.03.172-.028.343-.057.515-.091v1.743a.5.5 0 01-.533.521h-.062a10.286 10.286 0 116.324 0v.005z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="magnet" xmlns="http://www.w3.org/2000/svg"><path d="M8 1.5c-3.9 0-7 3.1-7 7v5l1 1h3l1-1v-5c0-1.1.9-2 2-2s2 .9 2 2v5l1 1h3l1-1v-5c0-3.9-3.1-7-7-7zm-3 12H2v-3h3v3zm9 0h-3v-3h3v3zm-3-4v-1c0-1.7-1.3-3-3-3-1.6 0-2.9 1.3-3 2.8v1.2H2v-1c0-3.3 2.7-6 6-6s6 2.7 6 6v1h-3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mail" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 3.5l.5-.5h13l.5.5v9l-.5.5h-13l-.5-.5v-9zm1 1.035V12h12V4.536L8.31 8.9H7.7L2 4.535zM13.03 4H2.97L8 7.869 13.03 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mail-read" xmlns="http://www.w3.org/2000/svg"><path d="M8.25 1.57h-.51L1 5.56v7.94l.5.5h13l.5-.5V5.56L8.25 1.57zM8 2.58l5.63 3.32-1.37 1.59H3.74L2.43 5.9 8 2.58zM14 13H2V6.92L3.11 8.3l.39.19h9l.39-.19L14 6.92V13z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mail-reply" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.306 2.146l-4.02 4.02v.708l4.02 4.02.708-.707L3.807 6.98H5.69c2.813 0 4.605.605 5.705 1.729 1.102 1.125 1.615 2.877 1.615 5.421v.35h1v-.35c0-2.646-.527-4.72-1.9-6.121C10.735 6.605 8.617 5.98 5.69 5.98H3.887l3.127-3.126-.708-.708z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="mark-github" xmlns="http://www.w3.org/2000/svg"><path d="M12 0a12 12 0 100 24 12 12 0 000-24zm3.163 21.783h-.093a.513.513 0 01-.382-.14.513.513 0 01-.14-.372v-1.406c.006-.467.01-.94.01-1.416a3.693 3.693 0 00-.151-1.028 1.832 1.832 0 00-.542-.875 8.014 8.014 0 002.038-.471 4.051 4.051 0 001.466-.964c.407-.427.71-.943.885-1.506a6.77 6.77 0 00.3-2.13 4.138 4.138 0 00-.26-1.476 3.892 3.892 0 00-.795-1.284 2.81 2.81 0 00.162-.582c.033-.2.05-.402.05-.604 0-.26-.03-.52-.09-.773a5.309 5.309 0 00-.221-.763.293.293 0 00-.111-.02h-.11c-.23.002-.456.04-.674.111a5.34 5.34 0 00-.703.26 6.503 6.503 0 00-.661.343c-.215.127-.405.249-.573.362a9.578 9.578 0 00-5.143 0 13.507 13.507 0 00-.572-.362 6.022 6.022 0 00-.672-.342 4.516 4.516 0 00-.705-.261 2.203 2.203 0 00-.662-.111h-.11a.29.29 0 00-.11.02 5.844 5.844 0 00-.23.763c-.054.254-.08.513-.081.773 0 .202.017.404.051.604.033.199.086.394.16.582A3.888 3.888 0 005.702 10a4.142 4.142 0 00-.263 1.476 6.871 6.871 0 00.292 2.12c.181.563.483 1.08.884 1.516.415.422.915.75 1.466.964.653.25 1.337.41 2.033.476a1.828 1.828 0 00-.452.633 2.99 2.99 0 00-.2.744 2.754 2.754 0 01-1.175.27 1.788 1.788 0 01-1.065-.3 2.904 2.904 0 01-.752-.824 3.1 3.1 0 00-.292-.382 2.693 2.693 0 00-.372-.343 1.841 1.841 0 00-.432-.24 1.2 1.2 0 00-.481-.101c-.04.001-.08.005-.12.01a.649.649 0 00-.162.02.408.408 0 00-.13.06.116.116 0 00-.06.1.33.33 0 00.14.242c.093.074.17.131.232.171l.03.021c.133.103.261.214.382.333.112.098.213.209.3.33.09.119.168.246.231.381.073.134.15.288.231.463.188.474.522.875.954 1.145.453.243.961.364 1.476.351.174 0 .349-.01.522-.03.172-.028.343-.057.515-.091v1.743a.5.5 0 01-.533.521h-.062a10.286 10.286 0 116.324 0v.005z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="markdown" xmlns="http://www.w3.org/2000/svg"><path d="M6.345 5h2.1v6.533H6.993l.055-5.31-1.774 5.31H4.072l-1.805-5.31c.04.644.06 5.31.06 5.31H1V5h2.156s1.528 4.493 1.577 4.807L6.345 5zm6.71 3.617v-3.5H11.11v3.5H9.166l2.917 2.916L15 8.617h-1.945z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="megaphone" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 6.77l12.33-3.43.67.53v8.6l-.67.53-6.089-1.595a2.16 2.16 0 11-4.178-1.095L2 9.77l-.42-.53V7.3L2 6.77zm3.006 3.787a1.13 1.13 0 00-.04.242 1.17 1.17 0 002.288.347l-2.248-.589zM2.58 8.82L14 11.83V4.5L2.58 7.72v1.1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mention" xmlns="http://www.w3.org/2000/svg"><path d="M10.465 12.36a5.516 5.516 0 01-3.053.736 4.262 4.262 0 01-4.57-4.543 5.381 5.381 0 015.391-5.571c2.377 0 4.413 1.375 4.413 4.006 0 2.182-1.292 3.66-2.9 3.66-.676 0-1.1-.274-1.126-.917a2.012 2.012 0 01-1.756.913c-.969 0-1.629-.645-1.629-1.923 0-1.763 1.148-3.4 2.62-3.4a1.314 1.314 0 011.427.93l.211-.809h.9L9.6 8.646c-.226.916-.13 1.215.342 1.215.984 0 1.833-1.21 1.833-2.825 0-2.068-1.445-3.265-3.61-3.265-2.643 0-4.374 2.132-4.382 4.786a3.443 3.443 0 003.686 3.717c.973.04 1.94-.179 2.8-.634l.196.72zM6.217 8.639c0 .788.307 1.206.913 1.206.758 0 1.38-.6 1.683-1.831C9.136 6.746 8.85 6.1 7.94 6.1c-1.04 0-1.723 1.339-1.723 2.539z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="menu" xmlns="http://www.w3.org/2000/svg"><path d="M16 5H0V4h16v1zm0 8H0v-1h16v1zm0-4.008H0V8h16v.992z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="merge" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 4.646L8.354 2.5h-.707L5.5 4.646l.707.707L7.3 4.261V5.28h-.02v.456l.025.001.006.319c.004.187.02.379.05.574.03.195.069.39.117.586.048.195.114.404.2.627.155.379.343.722.565 1.031.221.309.46.598.715.867.255.27.508.535.76.797.25.262.478.541.681.838.203.297.368.621.494.973.125.351.188.755.188 1.213v.884H12.5v-.884a5.991 5.991 0 00-.166-1.39 4.638 4.638 0 00-.427-1.1 5.875 5.875 0 00-.604-.897c-.222-.27-.453-.527-.693-.774-.24-.246-.471-.492-.693-.738a6.39 6.39 0 01-.604-.785 3.794 3.794 0 01-.433-.914 3.676 3.676 0 01-.16-1.13V5.28h-.001v-1l1.074 1.074.707-.708zM7.042 9.741a8.19 8.19 0 00.329-.369 6.06 6.06 0 01-.62-1.15L6.744 8.2a7.26 7.26 0 01-.095-.263c-.17.256-.359.498-.565.726-.222.246-.453.492-.693.738-.24.247-.47.504-.693.774-.221.27-.423.568-.604.896a4.643 4.643 0 00-.427 1.102 5.995 5.995 0 00-.166 1.389v.884h1.42v-.884c0-.457.062-.862.188-1.213.125-.352.29-.676.493-.973.203-.297.43-.576.682-.838.251-.262.504-.527.76-.797z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="microscope" xmlns="http://www.w3.org/2000/svg"><path d="M13.893 13.558L10 6.006v-4h1v-1H9.994V1l-.456.005H5V2h1v3.952l-3.894 7.609A1 1 0 003 15.006h10a1 1 0 00.893-1.448zm-7-7.15L7 6.193V2.036l2-.024v4.237l.11.215 1.827 3.542H5.049l1.844-3.598zM3 14.017l1.54-3.011h6.916l1.547 3L3 14.017z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="milestone" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 1H7v2H1.5l-.5.5v4l.5.5H7v7h1V8h4.49l.34-.13 2.18-2v-.74l-2.18-2L12.5 3H8V1zm4.29 6H2V4h10.29l1.63 1.5L12.29 7zM5 5h5v1H5V5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mirror" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.57 1l6.2 4 .23.38v9.2l-.76.42L8 11l-6.24 4-.76-.42v-9.2L1.23 5l6.2-4h1.14zm-.06 9.13L14 13.67V5.65l-5.49-3.5V5h-1V2.13L2 5.67v8l5.51-3.56v.02h1zm.9-4.78l.71-.7 2.47 2.48v.71l-2.46 2.46-.7-.7L11.02 8h-6L6.6 9.6l-.7.7-2.46-2.46v-.71l2.48-2.48.7.7L4.98 7h6.08L9.41 5.35z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mirror-private" xmlns="http://www.w3.org/2000/svg"><path d="M13 7h-1V5a4 4 0 10-8 0v2H3L2 8v6l1 1h10l1-1V8l-1-1zM5 5a3 3 0 116 0v2H5V5zm8 9H3V8h10v6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mirror-public" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.57 1l6.2 4 .23.38v9.2l-.76.42L8 11l-6.24 4-.76-.42v-9.2L1.23 5l6.2-4h1.14zm-.06 9.13L14 13.67V5.65l-5.49-3.5V5h-1V2.13L2 5.67v8l5.51-3.56v.02h1zm.9-4.78l.71-.7 2.47 2.48v.71l-2.46 2.46-.7-.7L11.02 8h-6L6.6 9.6l-.7.7-2.46-2.46v-.71l2.48-2.48.7.7L4.98 7h6.08L9.41 5.35z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="more" xmlns="http://www.w3.org/2000/svg"><path d="M4 8a1 1 0 11-2 0 1 1 0 012 0zm5 0a1 1 0 11-2 0 1 1 0 012 0zm5 0a1 1 0 11-2 0 1 1 0 012 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mortar-board" xmlns="http://www.w3.org/2000/svg"><path d="M15 5.66L8.18 3h-.36L1 5.66V12h1V7l2.31.9a4.35 4.35 0 00-.79 2.48c-.01.11-.01.22 0 .33v.11l.28.4L7.78 13h.41l3.94-1.81.28-.4v-.44a4.39 4.39 0 00-.78-2.47L15 6.57v-.91zm-3.52 4.68v.07L8 12l-3.5-1.6a.13.13 0 010-.06 3.44 3.44 0 01.75-2.12l2.58 1h.36l2.56-1a3.4 3.4 0 01.73 2.12zM8 8.25L2.52 6.12 8 4l5.48 2.14L8 8.25z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="move" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.232 10.707L8.5 12.44V9h-1v3.44l-1.732-1.733-.707.707L7.646 14h.708l2.585-2.586-.707-.707zM5.061 3.586l.707.707L7.5 2.56V6h1V2.56l1.732 1.733.707-.707L8.354 1h-.708L5.061 3.586zm-.268 1.682L3.06 7H6.5v1H3.06l1.733 1.732-.707.707L1.5 7.854v-.708l2.586-2.585.707.707zM9.5 7h3.44l-1.733-1.732.707-.707L14.5 7.146v.708l-2.586 2.585-.707-.707L12.94 8H9.5V7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="multiple-windows" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 1.5l.5-.5h8l.5.5v7l-.5.5H12V8h2V4H7v1H6V1.5zM7 2v1h7V2H7zM1.5 7l-.5.5v7l.5.5h8l.5-.5v-7L9.5 7h-8zM2 9V8h7v1H2zm0 1h7v4H2v-4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="mute" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 5h2.79l3.86-3.83.85.35v13l-.85.33L4.29 11H1.5l-.5-.5v-5l.5-.5zm3.35 5.17L8 13.31V2.73L4.85 5.85 4.5 6H2v4h2.5l.35.17zm9.381-4.108l.707.707L13.207 8.5l1.731 1.732-.707.707L12.5 9.207l-1.732 1.732-.707-.707L11.793 8.5 10.06 6.77l.707-.707 1.733 1.73 1.731-1.731z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="new-file" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.5 1.1l3.4 3.5.1.4v2h-1V6H8V2H3v11h4v1H2.5l-.5-.5v-12l.5-.5h6.7l.3.1zM9 2v3h2.9L9 2zm4 14h-1v-3H9v-1h3V9h1v3h3v1h-3v3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="new-folder" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 2H7.71l-.85-.85L6.51 1h-5l-.5.5v11l.5.5H7v-1H1.99V6h4.49l.35-.15.86-.86H14v1.5l-.001.51h1.011V2.5L14.5 2zm-.51 2h-6.5l-.35.15-.86.86H2v-3h4.29l.85.85.36.15H14l-.01.99zM13 16h-1v-3H9v-1h3V9h1v3h3v1h-3v3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="newline" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 5.5v1.984a.5.5 0 01-.5.5H4.618l1.633-1.633-.707-.707-2.121 2.121L3 8.188v.568L5.544 11.3l.707-.707-1.61-1.609H11.5a1.5 1.5 0 001.5-1.5V5.5h-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="no-newline" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.333 5.506a3 3 0 113.334 4.989 3 3 0 01-3.334-4.99zm2.677.777A1.986 1.986 0 002 8.009c.004.353.102.698.283 1.001L5.01 6.283zM2.99 9.717A1.986 1.986 0 006 7.991a1.988 1.988 0 00-.283-1.001L2.99 9.717zM14 5v1.984a.5.5 0 01-.5.5H9.367L11 5.851l-.707-.707-2.121 2.121-.423.423v.568l2.544 2.544.707-.707-1.61-1.609h4.11a1.5 1.5 0 001.5-1.5V5h-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="note" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2h13l.5.5v10l-.5.5h-13l-.5-.5v-10l.5-.5zM2 3v9h12V3H2zm2 2h8v1H4V5zm6 2H4v1h6V7zM4 9h4v1H4V9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="notebook" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 2l1-1h9l1 1v12l-1 1H3l-1-1V2zm1 0v12h9V2H3zm1 2l1-1h5l1 1v1l-1 1H5L4 5V4zm1 0v1h5V4H5zm10 1h-1v2h1V5zm-1 3h1v2h-1V8zm1 3h-1v2h1v-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="notebook-template" xmlns="http://www.w3.org/2000/svg"><path d="M1 5H0V4h1v1zm0 2H0V6h1v1zm0 2H0V8h1v1zm0 2H0v-1h1v1zm0 2H0v-1h1v1zm0 1v1H0v-1h1zm0 1h1v1H1v-1zm2 0h1v1H3v-1zM1 1H0V0h1v1zm2 0H2V0h1v1zm1-1h1v1H4V0zm3 1H6V0h1v1zm2 0H8V0h1v1zm2 0h-1V0h1v1zm0 1V1h1v1h-1zm1 2h-1V3h1v1zM1 3H0V2h1v1z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 6l1-1h7l1 1v9l-1 1H6l-1-1V6zm1 0v9h7V6H6z"/><path d="M15 7h1v2h-1V7zm0 3h1v2h-1v-2zm0 3h1v2h-1v-2zM7 8h5v1H7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="octoface" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.863 5.673c.113-.28.48-1.392-.114-2.897 0 0-.919-.288-3.01 1.138-.875-.245-1.812-.28-2.739-.28-.928 0-1.864.035-2.739.28-2.091-1.435-3.01-1.138-3.01-1.138-.595 1.505-.227 2.617-.113 2.897C1.428 6.433 1 7.413 1 8.603c0 4.507 2.914 5.522 6.982 5.522 4.07 0 7.018-1.015 7.018-5.521 0-1.19-.429-2.17-1.137-2.931zM8 13.268c-2.888 0-5.232-.132-5.232-2.932 0-.665.332-1.295.892-1.811.936-.857 2.537-.402 4.34-.402 1.811 0 3.395-.455 4.34.402.569.516.893 1.138.893 1.811 0 2.791-2.346 2.931-5.233 2.931zM5.804 8.883c-.578 0-1.05.7-1.05 1.557 0 .858.472 1.566 1.05 1.566.577 0 1.05-.7 1.05-1.566 0-.866-.473-1.557-1.05-1.557zm4.392 0c-.577 0-1.05.691-1.05 1.557s.473 1.566 1.05 1.566c.578 0 1.05-.7 1.05-1.566 0-.866-.463-1.557-1.05-1.557z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="open-preview" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 1h11l1 1v5.3a3.21 3.21 0 00-1-.3V2H9v10.88L7.88 14H3l-1-1V2l1-1zm0 12h5V2H3v11zm10.379-4.998a2.53 2.53 0 00-1.19.348h-.03a2.51 2.51 0 00-.799 3.53L9 14.23l.71.71 2.35-2.36c.325.22.7.358 1.09.4a2.47 2.47 0 001.14-.13 2.51 2.51 0 001-.63 2.46 2.46 0 00.58-1 2.63 2.63 0 00.07-1.15 2.53 2.53 0 00-1.35-1.81 2.53 2.53 0 00-1.211-.258zm.24 3.992a1.5 1.5 0 01-.979-.244 1.55 1.55 0 01-.56-.68 1.49 1.49 0 01-.08-.86 1.49 1.49 0 011.18-1.18 1.49 1.49 0 01.86.08c.276.117.512.311.68.56a1.5 1.5 0 01-1.1 2.324z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="organization" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.111 4.663A2 2 0 116.89 1.337a2 2 0 012.222 3.326zm-.555-2.494A1 1 0 107.444 3.83a1 1 0 001.112-1.66zm2.61.03a1.494 1.494 0 011.895.188 1.513 1.513 0 01-.487 2.46 1.492 1.492 0 01-1.635-.326 1.512 1.512 0 01.228-2.321zm.48 1.61a.499.499 0 10.705-.708.509.509 0 00-.351-.15.499.499 0 00-.5.503.51.51 0 00.146.356zM3.19 12.487H5v1.005H3.19a1.197 1.197 0 01-.842-.357 1.21 1.21 0 01-.348-.85v-1.81a.997.997 0 01-.71-.332A1.007 1.007 0 011 9.408V7.226c.003-.472.19-.923.52-1.258.329-.331.774-.52 1.24-.523H4.6a2.912 2.912 0 00-.55 1.006H2.76a.798.798 0 00-.54.232.777.777 0 00-.22.543v2.232h1v2.826a.202.202 0 00.05.151.24.24 0 00.14.05zm7.3-6.518a1.765 1.765 0 00-1.25-.523H6.76a1.765 1.765 0 00-1.24.523c-.33.335-.517.786-.52 1.258v3.178a1.06 1.06 0 00.29.734 1 1 0 00.71.332v2.323a1.202 1.202 0 00.35.855c.18.168.407.277.65.312h2a1.15 1.15 0 001-1.167V11.47a.997.997 0 00.71-.332 1.006 1.006 0 00.29-.734V7.226a1.8 1.8 0 00-.51-1.258zM10 10.454H9v3.34a.202.202 0 01-.06.14.17.17 0 01-.14.06H7.19a.21.21 0 01-.2-.2v-3.34H6V7.226c0-.203.079-.398.22-.543a.798.798 0 01.54-.232h2.48a.778.778 0 01.705.48.748.748 0 01.055.295v3.228zm2.81 3.037H11v-1.005h1.8a.24.24 0 00.14-.05.2.2 0 00.06-.152V9.458h1V7.226a.777.777 0 00-.22-.543.798.798 0 00-.54-.232h-1.29a2.91 2.91 0 00-.55-1.006h1.84a1.77 1.77 0 011.24.523c.33.335.517.786.52 1.258v2.182c0 .273-.103.535-.289.733-.186.199-.44.318-.711.333v1.81c0 .319-.125.624-.348.85a1.197 1.197 0 01-.842.357zM4 1.945a1.494 1.494 0 00-1.386.932A1.517 1.517 0 002.94 4.52 1.497 1.497 0 005.5 3.454c0-.4-.158-.784-.44-1.067A1.496 1.496 0 004 1.945zm0 2.012a.499.499 0 01-.5-.503.504.504 0 01.5-.503.509.509 0 01.5.503.504.504 0 01-.5.503z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="organization-filled" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.111 4.663A2 2 0 116.89 1.337a2 2 0 012.222 3.326zm-.555-2.494A1 1 0 107.444 3.83a1 1 0 001.112-1.66zm2.61.03a1.494 1.494 0 011.895.188 1.513 1.513 0 01-.487 2.46 1.492 1.492 0 01-1.635-.326 1.512 1.512 0 01.228-2.321zm.48 1.61a.499.499 0 10.705-.708.509.509 0 00-.351-.15.499.499 0 00-.5.503.51.51 0 00.146.356zM3.19 12.487H5v1.005H3.19a1.197 1.197 0 01-.842-.357 1.21 1.21 0 01-.348-.85v-1.81a.997.997 0 01-.71-.332A1.007 1.007 0 011 9.408V7.226c.003-.472.19-.923.52-1.258.329-.331.774-.52 1.24-.523H4.6a2.912 2.912 0 00-.55 1.006H2.76a.798.798 0 00-.54.232.777.777 0 00-.22.543v2.232h1v2.826a.202.202 0 00.05.151.24.24 0 00.14.05zm7.3-6.518a1.765 1.765 0 00-1.25-.523H6.76a1.765 1.765 0 00-1.24.523c-.33.335-.517.786-.52 1.258v3.178a1.06 1.06 0 00.29.734 1 1 0 00.71.332v2.323a1.202 1.202 0 00.35.855c.18.168.407.277.65.312h2a1.15 1.15 0 001-1.167V11.47a.997.997 0 00.71-.332 1.006 1.006 0 00.29-.734V7.226a1.8 1.8 0 00-.51-1.258zM10 10.454H9v3.34a.202.202 0 01-.06.14.17.17 0 01-.14.06H7.19a.21.21 0 01-.2-.2v-3.34H6V7.226c0-.203.079-.398.22-.543a.798.798 0 01.54-.232h2.48a.778.778 0 01.705.48.748.748 0 01.055.295v3.228zm2.81 3.037H11v-1.005h1.8a.24.24 0 00.14-.05.2.2 0 00.06-.152V9.458h1V7.226a.777.777 0 00-.22-.543.798.798 0 00-.54-.232h-1.29a2.91 2.91 0 00-.55-1.006h1.84a1.77 1.77 0 011.24.523c.33.335.517.786.52 1.258v2.182c0 .273-.103.535-.289.733-.186.199-.44.318-.711.333v1.81c0 .319-.125.624-.348.85a1.197 1.197 0 01-.842.357zM4 1.945a1.494 1.494 0 00-1.386.932A1.517 1.517 0 002.94 4.52 1.497 1.497 0 005.5 3.454c0-.4-.158-.784-.44-1.067A1.496 1.496 0 004 1.945zm0 2.012a.499.499 0 01-.5-.503.504.504 0 01.5-.503.509.509 0 01.5.503.504.504 0 01-.5.503z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="organization-outline" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.111 4.663A2 2 0 116.89 1.337a2 2 0 012.222 3.326zm-.555-2.494A1 1 0 107.444 3.83a1 1 0 001.112-1.66zm2.61.03a1.494 1.494 0 011.895.188 1.513 1.513 0 01-.487 2.46 1.492 1.492 0 01-1.635-.326 1.512 1.512 0 01.228-2.321zm.48 1.61a.499.499 0 10.705-.708.509.509 0 00-.351-.15.499.499 0 00-.5.503.51.51 0 00.146.356zM3.19 12.487H5v1.005H3.19a1.197 1.197 0 01-.842-.357 1.21 1.21 0 01-.348-.85v-1.81a.997.997 0 01-.71-.332A1.007 1.007 0 011 9.408V7.226c.003-.472.19-.923.52-1.258.329-.331.774-.52 1.24-.523H4.6a2.912 2.912 0 00-.55 1.006H2.76a.798.798 0 00-.54.232.777.777 0 00-.22.543v2.232h1v2.826a.202.202 0 00.05.151.24.24 0 00.14.05zm7.3-6.518a1.765 1.765 0 00-1.25-.523H6.76a1.765 1.765 0 00-1.24.523c-.33.335-.517.786-.52 1.258v3.178a1.06 1.06 0 00.29.734 1 1 0 00.71.332v2.323a1.202 1.202 0 00.35.855c.18.168.407.277.65.312h2a1.15 1.15 0 001-1.167V11.47a.997.997 0 00.71-.332 1.006 1.006 0 00.29-.734V7.226a1.8 1.8 0 00-.51-1.258zM10 10.454H9v3.34a.202.202 0 01-.06.14.17.17 0 01-.14.06H7.19a.21.21 0 01-.2-.2v-3.34H6V7.226c0-.203.079-.398.22-.543a.798.798 0 01.54-.232h2.48a.778.778 0 01.705.48.748.748 0 01.055.295v3.228zm2.81 3.037H11v-1.005h1.8a.24.24 0 00.14-.05.2.2 0 00.06-.152V9.458h1V7.226a.777.777 0 00-.22-.543.798.798 0 00-.54-.232h-1.29a2.91 2.91 0 00-.55-1.006h1.84a1.77 1.77 0 011.24.523c.33.335.517.786.52 1.258v2.182c0 .273-.103.535-.289.733-.186.199-.44.318-.711.333v1.81c0 .319-.125.624-.348.85a1.197 1.197 0 01-.842.357zM4 1.945a1.494 1.494 0 00-1.386.932A1.517 1.517 0 002.94 4.52 1.497 1.497 0 005.5 3.454c0-.4-.158-.784-.44-1.067A1.496 1.496 0 004 1.945zm0 2.012a.499.499 0 01-.5-.503.504.504 0 01.5-.503.509.509 0 01.5.503.504.504 0 01-.5.503z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="output" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M19.5 0v1.5L21 3v19.5L19.5 24h-15L3 22.5V3l1.5-1.5V0H6v1.5h3V0h1.5v1.5h3V0H15v1.5h3V0h1.5zm-15 22.5h15V3h-15v19.5zM7.5 6h9v1.5h-9V6zm9 6h-9v1.5h9V12zm-9 6h9v1.5h-9V18z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="package" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.61 3l5.74 1.53L15 5v6.74l-.37.48-6.13 1.69-6.14-1.69-.36-.48V5l.61-.47L8.34 3h.27zm-.09 1l-4 1 .55.2 3.43.9 3-.81.95-.29-3.93-1zM3 11.36l5 1.37V7L3 5.66v5.7zM9 7v5.73l5-1.37V5.63l-2.02.553V8.75l-1 .26V6.457L9 7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="paintcan" xmlns="http://www.w3.org/2000/svg"><path d="M14.54 11.811l-1.14-3.12v-.06l-4.91-4.91v-1.24a1.66 1.66 0 00-.11-.58 1.48 1.48 0 00-.83-.8 1.42 1.42 0 00-.58-.1 1.47 1.47 0 00-1.48 1.48v3.26l-3.06 3a1.52 1.52 0 000 2.12l3.63 3.63c.14.141.307.253.49.33a1.53 1.53 0 001.14 0 1.51 1.51 0 00.49-.33l4.93-4.92-.66 2.2a1.19 1.19 0 000 .46c.033.152.098.296.19.42.098.121.216.223.35.3.14.07.294.11.45.12a1 1 0 00.48-.09 1.14 1.14 0 00.39-.29.98.98 0 00.22-.44c.032-.145.035-.294.01-.44zm-8-9.33a.46.46 0 010-.2.52.52 0 01.12-.17.64.64 0 01.18-.1.5.5 0 01.21 0 .5.5 0 01.32.15.5.5 0 01.12.33v1.26l-1 1 .05-2.27zm1 11.35a.36.36 0 01-.16.11.47.47 0 01-.38 0 .361.361 0 01-.16-.11l-3.63-3.62a.5.5 0 010-.71l4.35-4.35v2.85a.74.74 0 00-.24.55.75.75 0 101.17-.55v-2.83l3.85 3.87-4.8 4.79z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pass" xmlns="http://www.w3.org/2000/svg"><path d="M6.27 10.87h.71l4.56-4.56-.71-.71-4.2 4.21-1.92-1.92L4 8.6l2.27 2.27z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pass-filled" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm-1.02-4.13h-.71L4 8.6l.71-.71 1.92 1.92 4.2-4.21.71.71-4.56 4.56z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pencil" xmlns="http://www.w3.org/2000/svg"><path d="M13.23 1h-1.46L3.52 9.25l-.16.22L1 13.59 2.41 15l4.12-2.36.22-.16L15 4.23V2.77L13.23 1zM2.41 13.59l1.51-3 1.45 1.45-2.96 1.55zm3.83-2.06L4.47 9.76l8-8 1.77 1.77-8 8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="person" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a1 1 0 110 2 1 1 0 010-2zm0-1a2 2 0 100 4 2 2 0 000-4zm1.23 4.49H6.77A1.77 1.77 0 005 7.26V9.9A1.06 1.06 0 006 11v2.33a1.2 1.2 0 001.2 1.2h1.6a1.2 1.2 0 001.2-1.24V11a1.06 1.06 0 001-1.1V7.26a1.77 1.77 0 00-1.77-1.77zM6 10V7.26a.76.76 0 01.77-.77h2.46a.76.76 0 01.77.77V10H9v3.31a.2.2 0 01-.2.2H7.2a.2.2 0 01-.2-.2V10H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="person-add" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13 10h-1v2h-2v1h2v2h1v-2h2v-1h-2v-2zM8.556 2.169a1 1 0 10-1.112 1.663 1 1 0 001.112-1.663zm-1.667-.832A2 2 0 119.11 4.663a2 2 0 01-2.22-3.326zM6.77 5.49h2.46A1.77 1.77 0 0111 7.26V8h-1v-.74a.76.76 0 00-.77-.77H6.77a.76.76 0 00-.77.77V10h1v3.31a.2.2 0 00.2.2H8v1.02h-.8a1.2 1.2 0 01-1.2-1.2V11a1.06 1.06 0 01-1-1.1V7.26a1.77 1.77 0 011.77-1.77z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="person-filled" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a1 1 0 110 2 1 1 0 010-2zm0-1a2 2 0 100 4 2 2 0 000-4zm1.23 4.49H6.77A1.77 1.77 0 005 7.26V9.9A1.06 1.06 0 006 11v2.33a1.2 1.2 0 001.2 1.2h1.6a1.2 1.2 0 001.2-1.24V11a1.06 1.06 0 001-1.1V7.26a1.77 1.77 0 00-1.77-1.77zM6 10V7.26a.76.76 0 01.77-.77h2.46a.76.76 0 01.77.77V10H9v3.31a.2.2 0 01-.2.2H7.2a.2.2 0 01-.2-.2V10H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="person-follow" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a1 1 0 110 2 1 1 0 010-2zm0-1a2 2 0 100 4 2 2 0 000-4zm1.23 4.49H6.77A1.77 1.77 0 005 7.26V9.9A1.06 1.06 0 006 11v2.33a1.2 1.2 0 001.2 1.2h1.6a1.2 1.2 0 001.2-1.24V11a1.06 1.06 0 001-1.1V7.26a1.77 1.77 0 00-1.77-1.77zM6 10V7.26a.76.76 0 01.77-.77h2.46a.76.76 0 01.77.77V10H9v3.31a.2.2 0 01-.2.2H7.2a.2.2 0 01-.2-.2V10H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="person-outline" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a1 1 0 110 2 1 1 0 010-2zm0-1a2 2 0 100 4 2 2 0 000-4zm1.23 4.49H6.77A1.77 1.77 0 005 7.26V9.9A1.06 1.06 0 006 11v2.33a1.2 1.2 0 001.2 1.2h1.6a1.2 1.2 0 001.2-1.24V11a1.06 1.06 0 001-1.1V7.26a1.77 1.77 0 00-1.77-1.77zM6 10V7.26a.76.76 0 01.77-.77h2.46a.76.76 0 01.77.77V10H9v3.31a.2.2 0 01-.2.2H7.2a.2.2 0 01-.2-.2V10H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pie-chart" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10 6h3.9A5.006 5.006 0 0010 2.1V6zm0-4.917A6.005 6.005 0 0115 7H9V1c.34 0 .675.028 1 .083zM7 8l1 1h4.9A5.002 5.002 0 013 8a5.002 5.002 0 014-4.9V8zm1 6a6.002 6.002 0 006-6H8V2a6.002 6.002 0 000 12z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pin" xmlns="http://www.w3.org/2000/svg"><path d="M14 5v7h-.278c-.406 0-.778-.086-1.117-.258A2.528 2.528 0 0111.73 11H8.87a3.463 3.463 0 01-.546.828 3.685 3.685 0 01-.735.633c-.27.177-.565.31-.882.398a3.875 3.875 0 01-.985.141h-.5V9H2l-1-.5L2 8h3.222V4h.5c.339 0 .664.047.977.14.312.094.607.227.883.4A3.404 3.404 0 018.87 6h2.859a2.56 2.56 0 01.875-.734c.338-.172.71-.26 1.117-.266H14zm-.778 1.086a1.222 1.222 0 00-.32.156 1.491 1.491 0 00-.43.461L12.285 7H8.183l-.117-.336a2.457 2.457 0 00-.711-1.047C7.027 5.331 6.427 5.09 6 5v7c.427-.088 1.027-.33 1.355-.617.328-.287.565-.636.71-1.047L8.184 10h4.102l.18.297c.057.094.122.177.195.25.073.073.153.143.242.21.088.069.195.12.32.157V6.086z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pinned" xmlns="http://www.w3.org/2000/svg"><path d="M4 2h7v.278c0 .406-.086.778-.258 1.117-.172.339-.42.63-.742.875v2.86c.307.145.583.328.828.546.245.219.456.464.633.735.177.27.31.565.398.882.089.318.136.646.141.985v.5H8V14l-.5 1-.5-1v-3.222H3v-.5c0-.339.047-.664.14-.977.094-.312.227-.607.4-.883A3.404 3.404 0 015 7.13V4.27a2.561 2.561 0 01-.734-.875A2.505 2.505 0 014 2.278V2zm1.086.778c.042.125.094.232.156.32a1.494 1.494 0 00.461.43L6 3.715v4.102l-.336.117c-.411.146-.76.383-1.047.711C4.331 8.973 4.09 9.573 4 10h7c-.088-.427-.33-1.027-.617-1.355a2.456 2.456 0 00-1.047-.71L9 7.816V3.715l.297-.18c.094-.057.177-.122.25-.195a2.28 2.28 0 00.21-.242.968.968 0 00.157-.32H5.086z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pinned-dirty" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 2h7v.278c0 .406-.086.778-.258 1.117-.172.339-.42.63-.742.875v2.86c.307.145.583.328.828.546a3.7 3.7 0 01.54.598 4.92 4.92 0 00-.896.412l-.007.004-.03.018a2.456 2.456 0 00-1.099-.774L9 7.817V3.715l.297-.18c.094-.057.177-.122.25-.195a2.28 2.28 0 00.21-.242.968.968 0 00.157-.32H5.086c.042.125.094.232.156.32a1.494 1.494 0 00.461.43L6 3.715v4.102l-.336.117c-.411.146-.76.383-1.047.711C4.331 8.973 4.09 9.573 4 10h5.002a5.025 5.025 0 00-.481.778H8V14l-.5 1-.5-1v-3.222H3v-.5c0-.339.047-.664.14-.977.094-.312.227-.607.4-.883A3.404 3.404 0 015 7.13V4.27a2.561 2.561 0 01-.734-.875A2.505 2.505 0 014 2.278V2zm7.485 8.41a2.924 2.924 0 01.718-.302c.256-.072.522-.108.797-.108s.541.036.797.108a2.956 2.956 0 011.321.773 2.956 2.956 0 01.774 1.322c.072.256.108.522.108.797s-.036.541-.108.797a2.953 2.953 0 01-.774 1.324 3.013 3.013 0 01-1.321.774c-.256.07-.522.105-.797.105s-.541-.035-.797-.105a3.037 3.037 0 01-1.324-.774 3.037 3.037 0 01-.773-1.324A2.994 2.994 0 0110 13c0-.275.035-.541.105-.797a3.013 3.013 0 01.883-1.425c.154-.14.32-.262.497-.368z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="play" xmlns="http://www.w3.org/2000/svg"><path d="M3.78 2L3 2.41v12l.78.42 9-6V8l-9-6zM4 13.48V3.35l7.6 5.07L4 13.48z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="play-circle" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 5l.777-.416 4.5 3v.832l-4.5 3L6 11V5zm1 .934v4.132L10.099 8 7 5.934z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="plug" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H6v3H4.5l-.5.5V8a4 4 0 003.5 3.969V15h1v-3.031A4 4 0 0012 8V4.5l-.5-.5H10V1H9v3H7V1zm3.121 9.121A3 3 0 015 8V5h6v3a3 3 0 01-.879 2.121z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="plus" xmlns="http://www.w3.org/2000/svg"><path d="M14 7v1H8v6H7V8H1V7h6V1h1v6h6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="preserve-case" xmlns="http://www.w3.org/2000/svg"><path d="M8.514 11h-1l-.816-2.16H3.433L2.664 11H1.66l2.954-7.702h.935L8.514 11zM6.403 8.03L5.194 4.748a3.144 3.144 0 01-.118-.516h-.021c-.036.219-.077.39-.124.516L3.733 8.03h2.67zM9.597 11V3.298h2.192c.666 0 1.194.163 1.584.489.39.325.586.75.586 1.273 0 .436-.119.816-.355 1.138a1.911 1.911 0 01-.977.688v.021c.519.061.934.258 1.246.591.311.33.467.76.467 1.29 0 .658-.236 1.191-.71 1.6-.472.408-1.068.612-1.788.612H9.597zm.903-6.886v2.487h.923c.495 0 .883-.118 1.166-.354.283-.24.424-.577.424-1.01 0-.749-.492-1.123-1.477-1.123H10.5zm0 3.298v2.772h1.224c.53 0 .94-.126 1.23-.376.294-.251.44-.595.44-1.032 0-.91-.619-1.364-1.858-1.364H10.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="preview" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 2h12l1 1v10l-1 1H2l-1-1V3l1-1zm0 11h12V3H2v10zm11-9H3v3h10V4zm-1 2H4V5h8v1zm-3 6h4V8H9v4zm1-3h2v2h-2V9zM7 8H3v1h4V8zm-4 3h4v1H3v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="primitive-dot" xmlns="http://www.w3.org/2000/svg"><path d="M8 4c.367 0 .721.048 1.063.145a3.943 3.943 0 011.762 1.031 3.944 3.944 0 011.03 1.762c.097.34.145.695.145 1.062 0 .367-.048.721-.145 1.063a3.94 3.94 0 01-1.03 1.765 4.017 4.017 0 01-1.762 1.031C8.72 11.953 8.367 12 8 12s-.721-.047-1.063-.14a4.056 4.056 0 01-1.765-1.032A4.055 4.055 0 014.14 9.062 3.992 3.992 0 014 8c0-.367.047-.721.14-1.063a4.02 4.02 0 01.407-.953A4.089 4.089 0 015.98 4.546a3.94 3.94 0 01.957-.401A3.89 3.89 0 018 4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="primitive-square" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 4l.5-.5h8l.5.5v8l-.5.5H4l-.5-.5V4zm1 .5v7h7v-7h-7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="project" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h13l.5.5v13l-.5.5h-13l-.5-.5v-13l.5-.5zM2 14h12V2H2v12zM3 3h2v10H3V3zm6 0H7v6h2V3zm2 0h2v8h-2V3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="pulse" xmlns="http://www.w3.org/2000/svg"><path d="M11.8 9L10 3H9L7.158 9.64 5.99 4.69h-.97L3.85 9H1v.99h3.23l.49-.37.74-2.7L6.59 12h1.03l1.87-7.04 1.46 4.68.48.36H15V9h-3.2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="question" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 1a6.5 6.5 0 100 13 6.5 6.5 0 000-13zm0 12a5.5 5.5 0 110-11 5.5 5.5 0 010 11zm1.55-8.42a1.84 1.84 0 00-.61-.42A2.25 2.25 0 007.53 4a2.16 2.16 0 00-.88.17c-.239.1-.45.254-.62.45a1.89 1.89 0 00-.38.62 3 3 0 00-.15.72h1.23a.84.84 0 01.506-.741.72.72 0 01.304-.049.86.86 0 01.27 0 .64.64 0 01.22.14.6.6 0 01.16.22.73.73 0 01.06.3c0 .173-.037.343-.11.5a2.4 2.4 0 01-.27.46l-.35.42c-.12.13-.24.27-.35.41a2.33 2.33 0 00-.27.45 1.18 1.18 0 00-.1.5v.66H8v-.49a.94.94 0 01.11-.42 3.09 3.09 0 01.28-.41l.36-.44a4.29 4.29 0 00.36-.48 2.59 2.59 0 00.28-.55 1.91 1.91 0 00.11-.64 2.18 2.18 0 00-.1-.67 1.52 1.52 0 00-.35-.55zM6.8 9.83h1.17V11H6.8V9.83z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="quote" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.16 3.5C4.73 5.06 3.55 6.67 3.55 9.36c.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.9 0-2.99-1.52-2.99-4.25 0-3.8 1.75-6.53 5.02-8.42L7.16 3.5zm7 0c-2.43 1.56-3.61 3.17-3.61 5.86.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.89 0-2.98-1.52-2.98-4.25 0-3.8 1.75-6.53 5.02-8.42l1.14 1.84h-.01z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="radio-tower" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.998 5.58a5.55 5.55 0 011.62-3.88l-.71-.7a6.45 6.45 0 000 9.16l.71-.7a5.55 5.55 0 01-1.62-3.88zm1.06 0a4.42 4.42 0 001.32 3.17l.71-.71a3.27 3.27 0 01-.76-1.12 3.45 3.45 0 010-2.67 3.22 3.22 0 01.76-1.13l-.71-.71a4.46 4.46 0 00-1.32 3.17zm7.65 3.21l-.71-.71c.33-.32.59-.704.76-1.13a3.449 3.449 0 000-2.67 3.22 3.22 0 00-.76-1.13l.71-.7a4.468 4.468 0 010 6.34zM13.068 1l-.71.71a5.43 5.43 0 010 7.74l.71.71a6.45 6.45 0 000-9.16zM9.993 5.43a1.5 1.5 0 01-.245.98 2 2 0 01-.27.23l3.44 7.73-.92.4-.77-1.73h-5.54l-.77 1.73-.92-.4 3.44-7.73a1.52 1.52 0 01-.33-1.63 1.55 1.55 0 01.56-.68 1.5 1.5 0 012.325 1.1zm-1.595-.34a.52.52 0 00-.25.14.52.52 0 00-.11.22.48.48 0 000 .29c.04.09.102.17.18.23a.54.54 0 00.28.08.51.51 0 00.5-.5.54.54 0 00-.08-.28.58.58 0 00-.23-.18.48.48 0 00-.29 0zm.23 2.05h-.27l-.87 1.94h2l-.86-1.94zm2.2 4.94l-.89-2h-2.88l-.89 2h4.66z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="reactions" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 7.5c0 .169-.01.336-.027.5h1.005A5.5 5.5 0 108 12.978v-1.005A4.5 4.5 0 1112 7.5zM5.5 7a1 1 0 100-2 1 1 0 000 2zm2 2.5c.712 0 1.355-.298 1.81-.776l.707.708A3.49 3.49 0 017.5 10.5a3.49 3.49 0 01-2.555-1.108l.707-.708A2.494 2.494 0 007.5 9.5zm2-2.5a1 1 0 100-2 1 1 0 000 2zm2.5 3h1v2h2v1h-2v2h-1v-2h-2v-1h2v-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="record" xmlns="http://www.w3.org/2000/svg"><path d="M8 10a2 2 0 100-4 2 2 0 000 4z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="record-keys" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 3H3a1 1 0 00-1 1v7a1 1 0 001 1h11a1 1 0 001-1V4a1 1 0 00-1-1zm0 8H3V4h11v7zm-3-6h-1v1h1V5zm-1 2H9v1h1V7zm2-2h1v1h-1V5zm1 4h-1v1h1V9zM6 9h5v1H6V9zm7-2h-2v1h2V7zM8 5h1v1H8V5zm0 2H7v1h1V7zM4 9h1v1H4V9zm0-4h1v1H4V5zm3 0H6v1h1V5zM4 7h2v1H4V7z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="record-small" xmlns="http://www.w3.org/2000/svg"><path d="M8 9a1 1 0 100-2 1 1 0 000 2z"/><path d="M12 8a4 4 0 11-8 0 4 4 0 018 0zm-1 0a3 3 0 10-6 0 3 3 0 006 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="redo" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.5 2v3.5L12 6H8.5V5h2.521l-.941-.941a3.552 3.552 0 10-5.023 5.023l5.197 5.198-.72.72-5.198-5.198A4.57 4.57 0 0110.8 3.339l.7.7V2h1z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="references" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.105 4.561l-3.43 3.427-1.134-1.12 2.07-2.08h-4.8a2.4 2.4 0 100 4.8h.89v1.6h-.88a4 4 0 010-7.991h4.8L6.54 1.13 7.675 0l3.43 3.432v1.13zM16.62 24h-9.6l-.8-.8V10.412l.8-.8h9.6l.8.8V23.2l-.8.8zm-8.8-1.6h8V11.212h-8V22.4zm5.6-20.798h9.6l.8.8v12.786l-.8.8h-4v-1.6h3.2V3.2h-8v4.787h-1.6V2.401l.8-.8zm.8 11.186h-4.8v1.6h4.8v-1.6zm-4.8 3.2h4.8v1.6h-4.8v-1.6zm4.8 3.2h-4.8v1.6h4.8v-1.6zm1.6-14.4h4.8v1.6h-4.8v-1.6zm4.8 6.4h-1.6v1.6h1.6v-1.6zm-3.338-3.176v-.024h3.338v1.6h-1.762l-1.576-1.576z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="refresh" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.681 3H2V2h3.5l.5.5V6H5V4a5 5 0 104.53-.761l.302-.954A6 6 0 114.681 3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="regex" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.012 2h.976v3.113l2.56-1.557.486.885L11.47 6l2.564 1.559-.485.885-2.561-1.557V10h-.976V6.887l-2.56 1.557-.486-.885L9.53 6 6.966 4.441l.485-.885 2.561 1.557V2zM2 10h4v4H2v-4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="remote" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.904 9.57L8.928 5.596l3.976-3.976-.619-.62L8 5.286v.619l4.285 4.285.62-.618zM3 5.62l4.072 4.07L3 13.763l.619.618L8 10v-.619L3.619 5 3 5.619z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="remote-explorer" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.344 2.125h20.312l.782.781v8.599a7.825 7.825 0 00-1.563-.912V3.688H2.125V17.75h7.813a7.813 7.813 0 001.562 4.688H5.25v-1.563h4.688v-1.563H1.344l-.782-.78V2.905l.782-.781zM17.75 11.5a6.25 6.25 0 100 12.5 6.25 6.25 0 000-12.5zm0 10.938a4.688 4.688 0 110-9.377 4.688 4.688 0 010 9.377zm2.603-3.132L18.2 17.153 20.353 15l.647.646-1.506 1.507L21 18.659l-.647.647zM15 17.246l1.506 1.507L15 20.259l.647.647 2.153-2.153-2.153-2.153-.647.646z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="remove" xmlns="http://www.w3.org/2000/svg"><path d="M15 8H1V7h14v1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="remove-close" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.707l3.646 3.647.708-.707L8.707 8l3.647-3.646-.707-.708L8 7.293 4.354 3.646l-.707.708L7.293 8l-3.646 3.646.707.708L8 8.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="repl" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 1.5L1.5 3v18L3 22.5h18l1.5-1.5V3L21 1.5H3zM3 21V3h18v18H3zm5.656-4.01l1.038 1.061 5.26-5.243v-.912l-5.26-5.26-1.035 1.06 4.59 4.702-4.593 4.592z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="replace" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.221 3.739l2.261 2.269L7.7 3.784l-.7-.7-1.012 1.007-.008-1.6a.523.523 0 01.5-.526H8V1H6.48A1.482 1.482 0 005 2.489V4.1L3.927 3.033l-.706.706zm6.67 1.794h.01c.183.311.451.467.806.467.393 0 .706-.168.94-.503.236-.335.353-.78.353-1.333 0-.511-.1-.913-.301-1.207-.201-.295-.488-.442-.86-.442-.405 0-.718.194-.938.581h-.01V1H9v4.919h.89v-.386zm-.015-1.061v-.34c0-.248.058-.448.175-.601a.54.54 0 01.445-.23.49.49 0 01.436.233c.104.154.155.368.155.643 0 .33-.056.587-.169.768a.524.524 0 01-.47.27.495.495 0 01-.411-.211.853.853 0 01-.16-.532zM9 12.769c-.256.154-.625.231-1.108.231-.563 0-1.02-.178-1.369-.533-.349-.355-.523-.813-.523-1.374 0-.648.186-1.158.56-1.53.374-.376.875-.563 1.5-.563.433 0 .746.06.94.179v.998a1.26 1.26 0 00-.792-.276c-.325 0-.583.1-.774.298-.19.196-.283.468-.283.816 0 .338.09.603.272.797.182.191.431.287.749.287.282 0 .558-.092.828-.276v.946zM4 7L3 8v6l1 1h7l1-1V8l-1-1H4zm0 1h7v6H4V8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="replace-all" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.6 2.677c.147-.31.356-.465.626-.465.248 0 .44.118.573.353.134.236.201.557.201.966 0 .443-.078.798-.235 1.067-.156.268-.365.402-.627.402-.237 0-.416-.125-.537-.374h-.008v.31H11V1h.593v1.677h.008zm-.016 1.1a.78.78 0 00.107.426c.071.113.163.169.274.169.136 0 .24-.072.314-.216.075-.145.113-.35.113-.615 0-.22-.035-.39-.104-.514-.067-.124-.164-.187-.29-.187-.12 0-.219.062-.297.185a.886.886 0 00-.117.48v.272zM4.12 7.695L2 5.568l.662-.662 1.006 1v-1.51A1.39 1.39 0 015.055 3H7.4v.905H5.055a.49.49 0 00-.468.493l.007 1.5.949-.944.656.656-2.08 2.085zM9.356 4.93H10V3.22C10 2.408 9.685 2 9.056 2c-.135 0-.285.024-.45.073a1.444 1.444 0 00-.388.167v.665c.237-.203.487-.304.75-.304.261 0 .392.156.392.469l-.6.103c-.506.086-.76.406-.76.961 0 .263.061.473.183.631A.61.61 0 008.69 5c.29 0 .509-.16.657-.48h.009v.41zm.004-1.355v.193a.75.75 0 01-.12.436.368.368 0 01-.313.17.276.276 0 01-.22-.095.38.38 0 01-.08-.248c0-.222.11-.351.332-.389l.4-.067zM7 12.93h-.644v-.41h-.009c-.148.32-.367.48-.657.48a.61.61 0 01-.507-.235c-.122-.158-.183-.368-.183-.63 0-.556.254-.876.76-.962l.6-.103c0-.313-.13-.47-.392-.47-.263 0-.513.102-.75.305v-.665c.095-.063.224-.119.388-.167.165-.049.315-.073.45-.073.63 0 .944.407.944 1.22v1.71zm-.64-1.162v-.193l-.4.068c-.222.037-.333.166-.333.388 0 .1.027.183.08.248a.276.276 0 00.22.095.368.368 0 00.312-.17c.08-.116.12-.26.12-.436zM9.262 13c.321 0 .568-.058.738-.173v-.71a.9.9 0 01-.552.207.619.619 0 01-.5-.215c-.12-.145-.181-.345-.181-.598 0-.26.063-.464.189-.612a.644.644 0 01.516-.223c.194 0 .37.069.528.207v-.749c-.129-.09-.338-.134-.626-.134-.417 0-.751.14-1.001.422-.249.28-.373.662-.373 1.148 0 .42.116.764.349 1.03.232.267.537.4.913.4zM2 9l1-1h9l1 1v5l-1 1H3l-1-1V9zm1 0v5h9V9H3zm3-2l1-1h7l1 1v5l-1 1V7H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="reply" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.306 2.146l-4.02 4.02v.708l4.02 4.02.708-.707L3.807 6.98H5.69c2.813 0 4.605.605 5.705 1.729 1.102 1.125 1.615 2.877 1.615 5.421v.35h1v-.35c0-2.646-.527-4.72-1.9-6.121C10.735 6.605 8.617 5.98 5.69 5.98H3.887l3.127-3.126-.708-.708z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 10V1.5l-.5-.5H3.74a1.9 1.9 0 00-.67.13 1.77 1.77 0 00-.94 1 1.7 1.7 0 00-.13.62v9.5a1.7 1.7 0 00.13.67c.177.427.515.768.94.95a1.9 1.9 0 00.67.13H4v-1h-.26a.72.72 0 01-.29-.06.74.74 0 01-.4-.4.93.93 0 01-.05-.29v-.5a.93.93 0 01.05-.29.74.74 0 01.4-.4.72.72 0 01.286-.06H13v2H9v1h4.5l.5-.5V10zM4 10V2h9v8H4zm1-7h1v1H5V3zm0 2h1v1H5V5zm1 2H5v1h1V7zm.5 6.49L5.28 15H5v-3h3v3h-.28L6.5 13.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-clone" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13 10H4V2h4V1H3.74a1.9 1.9 0 00-.67.13 1.66 1.66 0 00-.57.41 1.73 1.73 0 00-.37.59 1.68 1.68 0 00-.13.62v9.5a1.75 1.75 0 001.07 1.62 1.9 1.9 0 00.67.13H4v-1h-.26a.72.72 0 01-.29-.06.78.78 0 01-.4-.4.93.93 0 010-.29v-.5a.93.93 0 010-.29.78.78 0 01.4-.4.72.72 0 01.29-.06H13v2H9v1h4.5l.5-.5V9h-1v1zM6 3H5v1h1V3zM5 5h1v1H5V5zm0 2h1v1H5V7zm.28 8H5v-3h3v3h-.28L6.5 13.49 5.28 15zM10 1h4.5l.5.5v6l-.5.5H12v1h-1V8h-1a1 1 0 01-1-1V2a1 1 0 011-1zm.5 6h.5V6h-.5a.5.5 0 000 1zM12 7h2V6h-2v1zm-1-2h3V2h-3v3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-create" xmlns="http://www.w3.org/2000/svg"><path d="M14 7v1H8v6H7V8H1V7h6V1h1v6h6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-delete" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 10V1.5l-.5-.5H3.74a1.9 1.9 0 00-.67.13 1.77 1.77 0 00-.94 1 1.7 1.7 0 00-.13.62v9.5a1.7 1.7 0 00.13.67c.177.427.515.768.94.95a1.9 1.9 0 00.67.13H4v-1h-.26a.72.72 0 01-.29-.06.74.74 0 01-.4-.4.93.93 0 01-.05-.29v-.5a.93.93 0 01.05-.29.74.74 0 01.4-.4.72.72 0 01.286-.06H13v2H9v1h4.5l.5-.5V10zM4 10V2h9v8H4zm1-7h1v1H5V3zm0 2h1v1H5V5zm1 2H5v1h1V7zm.5 6.49L5.28 15H5v-3h3v3h-.28L6.5 13.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-force-push" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.74 1h9.76l.5.5v12l-.5.5H10v-1h3v-2h-3v-1h3V2H4v8h3v1H3.74a.74.74 0 00-.74.75v.5a.74.74 0 00.74.75H7v1H3.74A1.74 1.74 0 012 12.25v-9.5A1.74 1.74 0 013.74 1zm1.6 4.83l.71.7L8 4.58v1.45L5.38 8.65l.71.7 1.92-1.92V15h1V7.328l2.03 2.022.7-.7L9 5.9V4.538l2 1.992.7-.7L8.88 3h-.71L5.34 5.83z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-forked" xmlns="http://www.w3.org/2000/svg"><path d="M14 4a2 2 0 10-2.47 1.94V7a.48.48 0 01-.27.44L8.49 8.88l-2.76-1.4A.49.49 0 015.46 7V5.94a2 2 0 10-1 0V7a1.51 1.51 0 00.82 1.34L8 9.74v1.32a2 2 0 101 0V9.74l2.7-1.36A1.49 1.49 0 0012.52 7V5.92A2 2 0 0014 4zM4 4a1 1 0 112 0 1 1 0 01-2 0zm5.47 9a1 1 0 11-2 0 1 1 0 012 0zM12 5a1 1 0 110-2 1 1 0 010 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-pull" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13 1.5V3h-1V2H3v8h10v3.5l-.5.5H8v-1h4v-2H2.735a.72.72 0 00-.285.06.74.74 0 00-.4.4.93.93 0 00-.05.29v.5a.93.93 0 00.05.29.74.74 0 00.4.4c.091.04.19.06.29.06H3v1h-.26a1.9 1.9 0 01-.67-.13 1.77 1.77 0 01-.94-.95 1.7 1.7 0 01-.13-.67v-9.5a1.7 1.7 0 01.13-.62 1.77 1.77 0 01.94-1A1.9 1.9 0 012.74 1h9.76l.5.5zM2 10.17V2.748v7.422zM5 3H4v1h1V3zm0 2H4v1h1V5zM4 7h1v1H4V7zm8.07-3.61l-.7.71 1.92 1.92H7v1h6.39l-2.02 2.03.7.7 2.83-2.82v-.71l-2.83-2.83zM5.5 13.49L4.28 15H4v-3h3v3h-.28L5.5 13.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-push" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 1H3.74A1.74 1.74 0 002 2.75v9.5A1.74 1.74 0 003.74 14H7v-1H3.74a.74.74 0 01-.74-.75v-.5a.74.74 0 01.74-.75H7v-1H4V2h9v8h-3v1h3v2h-3v1h3.5l.5-.5v-12l-.5-.5zM3 2.73a.75.75 0 000 .02v7.42-7.44zM6 3H5v1h1V3zm-.62 5.65l.71.7 1.92-1.92V15h1V7.328l2.03 2.022.7-.7-2.82-2.83h-.71L5.38 8.65zM5 5h1v1H5V5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="repo-sync" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.006 8.267L.78 9.5 0 8.73l2.09-2.07.76.01 2.09 2.12-.76.76-1.167-1.18a5 5 0 009.4 1.983l.813.597a6 6 0 01-11.22-2.683zm10.99-.466L11.76 6.55l-.76.76 2.09 2.11.76.01 2.09-2.07-.75-.76-1.194 1.18a6 6 0 00-11.11-2.92l.81.594a5 5 0 019.3 2.346z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="report" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1h13l.5.5v10l-.5.5H7.707l-2.853 2.854L4 14.5V12H1.5l-.5-.5v-10l.5-.5zm6 10H14V2H2v9h2.5l.5.5v1.793l2.146-2.147L7.5 11zm0-8h1v5h-1V3zm0 7h1V9h-1v1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="request-changes" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 1h-13l-.5.5v10l.5.5H4v2.5l.854.354L7.707 12H14.5l.5-.5v-10l-.5-.5zM14 11H7.5l-.354.146L5 13.293V11.5l-.5-.5H2V2h12v9zm-4-1H6V8.979h4V10zM7.5 3h1v2h2v1h-2v2h-1V6h-2V5h2V3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="rocket" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.491 1c-3.598.004-6.654 1.983-8.835 4H1.5l-.5.5v3l.147.354.991.991.001.009 4 4 .009.001.999.999L7.5 15h3l.5-.5v-4.154c2.019-2.178 3.996-5.233 3.992-8.846l-.501-.5zM2 6h2.643a23.828 23.828 0 00-2.225 2.71L2 8.294V6zm5.7 8l-.42-.423a23.59 23.59 0 002.715-2.216V14H7.7zm-1.143-1.144L3.136 9.437C4.128 8 8.379 2.355 13.978 2.016c-.326 5.612-5.987 9.853-7.421 10.84zM4 15v-1H2v-2H1v3h3zm6.748-7.667a1.5 1.5 0 10-2.496-1.666 1.5 1.5 0 002.495 1.666z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="root-folder" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.71 3h6.79l.51.5v10l-.5.5H8.743a5.48 5.48 0 00.657-1h4.59v-1.51l.01-4v-1.5H7.69l-.017.017a5.494 5.494 0 00-.881-.508l.348-.349.35-.15h6.5l.01-.99H7.5l-.36-.15-.85-.85H2V5.6a5.45 5.45 0 00-.99.649V2.5l.5-.5h5l.35.15.85.85z"/><path d="M6 10.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8 10.5a3.5 3.5 0 11-7 0 3.5 3.5 0 017 0zM4.5 13a2.5 2.5 0 100-5 2.5 2.5 0 000 5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="root-folder-opened" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 6.257V2.5l.5-.5h5l.35.15.86.85h5.79l.5.5V6h1.13l.48.63-2.63 7-.48.37H8.743a5.48 5.48 0 00.657-1h2.73l2.37-6H8.743a5.534 5.534 0 00-.72-.724l.127-.126L8.5 6H13V4H7.5l-.35-.15L6.29 3H2l.01 2.594c-.361.184-.7.407-1.01.663z"/><path d="M6 10.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8 10.5a3.5 3.5 0 11-7 0 3.5 3.5 0 017 0zM4.5 13a2.5 2.5 0 100-5 2.5 2.5 0 000 5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="rss" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 13H3v-2c1.11 0 2 .89 2 2zM3 3v1a9 9 0 019 9h1C13 7.48 8.52 3 3 3zm0 4v1c2.75 0 5 2.25 5 5h1c0-3.31-2.69-6-6-6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="ruby" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 7.19l6.64 6.64h.72L15 7.19v-.72l-3.32-3.32-.36-.15H4.68l-.36.15L1 6.47v.72zm7 5.56L2.08 6.83 4.89 4h6.22l2.81 2.83L8 12.75zm0-7.73h2.69l1.81 1.81-4.5 4.4V5.02z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="run" xmlns="http://www.w3.org/2000/svg"><path d="M3.78 2L3 2.41v12l.78.42 9-6V8l-9-6zM4 13.48V3.35l7.6 5.07L4 13.48z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="run-above" xmlns="http://www.w3.org/2000/svg"><path d="M1.77 1.01L1 1.42v12l.78.42 9-6v-.83l-9.01-6zM2 12.49V2.36l7.6 5.07L2 12.49zM12.15 8h.71l2.5 2.5-.71.71L13 9.56V15h-1V9.55l-1.65 1.65-.7-.7 2.5-2.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="run-all" xmlns="http://www.w3.org/2000/svg"><path d="M2.78 2L2 2.41v12l.78.42 9-6V8l-9-6zM3 13.48V3.35l7.6 5.07L3 13.48z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 14.683l8.78-5.853V8L6 2.147V3.35l7.6 5.07L6 13.48v1.203z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="run-below" xmlns="http://www.w3.org/2000/svg"><path d="M1.8 1.01l-.78.41v12l.78.42 9-6v-.83l-9-6zm.22 11.48V2.36l7.6 5.07-7.6 5.06zM12.85 15h-.71l-2.5-2.5.71-.71L12 13.44V8h1v5.45l1.65-1.65.71.71L12.85 15z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="run-errors" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 2.41L5.78 2l9 6v.83L9 12.683v-1.2l4.6-3.063L6 3.35V7H5V2.41z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M4.872 7.808c-.85-.053-1.705.159-2.403.641-.753.485-1.233 1.184-1.499 2.03-.269.81-.213 1.72.106 2.518a3.774 3.774 0 001.658 1.873c.756.432 1.616.537 2.467.378.861-.162 1.61-.645 2.143-1.285l.005-.006c.529-.687.852-1.489.852-2.352a3.882 3.882 0 00-1.066-2.72l-.006-.005c-.585-.585-1.388-1.018-2.257-1.072zM2.951 9.183c.512-.373 1.172-.517 1.792-.47h.001c.656.048 1.22.328 1.697.804.516.516.803 1.274.803 2.038v.014c.047.649-.183 1.26-.566 1.789-.426.518-.993.85-1.61.991-.61.141-1.266.047-1.83-.282-.572-.333-1-.808-1.288-1.43-.28-.607-.282-1.265-.091-1.885v-.004a2.865 2.865 0 011.092-1.565zm1.554 1.83L3.292 9.748l-.638.637 1.22 1.27-1.22 1.27.638.637L4.505 12.3l1.213 1.264.638-.637-1.219-1.27 1.219-1.27-.638-.637-1.213 1.263z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="save" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.353 1.146l1.5 1.5L15 3v11.5l-.5.5h-13l-.5-.5v-13l.5-.5H13l.353.146zM2 2v12h12V3.208L12.793 2H11v4H4V2H2zm6 0v3h2V2H8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="save-all" xmlns="http://www.w3.org/2000/svg"><path d="M14.85 2.65l-1.5-1.5L13 1H4.48l-.5.5V4H1.5l-.5.5v10l.5.5h10l.5-.5V12h2.5l.5-.5V3l-.15-.35zM11 14H2V5h1v3.07h6V5h.79L11 6.21V14zM6 7V5h2v2H6zm8 4h-2V6l-.15-.35-1.5-1.5L10 4H5V2h7.81l1.21 1.21L14 11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="save-as" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.04 1.33L12.71 3l.29.71v.33h-.5l-.5.5v-.83l-1.67-1.67H10v4H4v-4H2v10h3l-.5 1H2l-1-1v-10l1-1h8.33l.71.29zM7 5h2V2H7v3zm6.5 0L15 6.5l-.02.69-5.5 5.5-.13.12-.37.37-.1.09-3 1.5-.67-.67 1.5-3 .09-.1.37-.37.12-.13 5.5-5.5h.71zm-6.22 7.24l-.52 1 1.04-.48-.52-.52zm.69-1.03l.79.79 5.15-5.15-.79-.79-5.15 5.15z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="screen-full" xmlns="http://www.w3.org/2000/svg"><path d="M3 12h10V4H3v8zm2-6h6v4H5V6zM2 6H1V2.5l.5-.5H5v1H2v3zm13-3.5V6h-1V3h-3V2h3.5l.5.5zM14 10h1v3.5l-.5.5H11v-1h3v-3zM2 13h3v1H1.5l-.5-.5V10h1v3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="screen-normal" xmlns="http://www.w3.org/2000/svg"><path d="M3.5 4H1V3h2V1h1v2.5l-.5.5zM13 3V1h-1v2.5l.5.5H15V3h-2zm-1 9.5V15h1v-2h2v-1h-2.5l-.5.5zM1 12v1h2v2h1v-2.5l-.5-.5H1zm11-1.5l-.5.5h-7l-.5-.5v-5l.5-.5h7l.5.5v5zM10 7H6v2h4V7z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="search" xmlns="http://www.w3.org/2000/svg"><path d="M15.25 0a8.25 8.25 0 00-6.18 13.72L1 22.88l1.12 1 8.05-9.12A8.251 8.251 0 1015.25.01V0zm0 15a6.75 6.75 0 110-13.5 6.75 6.75 0 010 13.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="search-save" xmlns="http://www.w3.org/2000/svg"><path d="M15.25 0a8.25 8.25 0 00-6.18 13.72L1 22.88l1.12 1 8.05-9.12A8.251 8.251 0 1015.25.01V0zm0 15a6.75 6.75 0 110-13.5 6.75 6.75 0 010 13.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="search-stop" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.738 3.318a4.5 4.5 0 00-.877 5.123A4.48 4.48 0 006.1 10a4.62 4.62 0 00-.1 1v.17c-.16-.11-.32-.22-.47-.34L1.75 14.5 1 13.84l3.8-3.69a5.5 5.5 0 119.62-3.65c0 .268-.02.535-.06.8a5.232 5.232 0 00-.94-.68V6.5a4.5 4.5 0 00-7.682-3.182zm3.04 4.356a4 4 0 114.444 6.652 4 4 0 01-4.444-6.652zm.1 5.447A3 3 0 0011 14a3 3 0 001.74-.55L8.55 9.26A3 3 0 008 11a3 3 0 00.879 2.121zm.382-4.57l4.19 4.189A3 3 0 0014 11a3 3 0 00-3-3 3 3 0 00-1.74.55z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="selection" xmlns="http://www.w3.org/2000/svg"><path d="M1 12v-1h9v1H1zm0-5h14v1H1V7zm11-4v1H1V3h11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="server" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 5L2 4.5v-3l.5-.5h11l.5.5v3l-.5.5h-11zM10 2H9v1H8V2H7v1H6V2H5v1H4V2H3v2h10V2h-2v1h-1V2zm-7.5 8L2 9.5v-3l.5-.5h11l.5.5v3l-.5.5h-11zM6 7H5v1H4V7H3v2h10V7h-2v1h-1V7H9v1H8V7H7v1H6V7zm7.5 8l.5-.5v-3l-.5-.5h-11l-.5.5v3l.5.5h11zM3 14v-2h1v1h1v-1h1v1h1v-1h1v1h1v-1h1v1h1v-1h2v2H3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="server-environment" xmlns="http://www.w3.org/2000/svg"><path d="M6 3h4v1H6V3zm0 6h4v1H6V9zm0 2h4v1H6v-1zm9.14 5H.86l1.25-5H4V2a.95.95 0 01.078-.383c.052-.12.123-.226.211-.32a.922.922 0 01.32-.219A1.01 1.01 0 015 1h6a.95.95 0 01.383.078c.12.052.226.123.32.211a.922.922 0 01.219.32c.052.125.078.256.078.391v9h1.89l1.25 5zM5 13h6V2H5v11zm8.86 2l-.75-3H12v2H4v-2H2.89l-.75 3h11.72z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="server-process" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2h13l.5.5V9h-1V6H2v7h7v1H1.5l-.5-.5v-11l.5-.5zM2 5h12V3H2v2zm5 7v-1.094a1.633 1.633 0 01-.469-.265l-.945.539-.5-.86.937-.547a1.57 1.57 0 010-.547l-.937-.546.5-.86.945.54c.151-.12.308-.209.469-.266V7h1v1.094a1.48 1.48 0 01.469.265l.945-.539.5.86-.937.547a1.57 1.57 0 010 .546l.937.547-.5.86-.945-.54a1.807 1.807 0 01-.469.266V12H7zm-.25-2.5c0 .208.073.385.219.531a.723.723 0 00.531.219.723.723 0 00.531-.219.723.723 0 00.219-.531.723.723 0 00-.219-.531.723.723 0 00-.531-.219.723.723 0 00-.531.219.723.723 0 00-.219.531zm5.334 5.5v-1.094a1.634 1.634 0 01-.469-.265l-.945.539-.5-.86.938-.547a1.572 1.572 0 010-.547l-.938-.546.5-.86.945.54c.151-.12.308-.209.47-.266V10h1v1.094a1.486 1.486 0 01.468.265l.945-.539.5.86-.937.547a1.562 1.562 0 010 .546l.937.547-.5.86-.945-.54a1.806 1.806 0 01-.469.266V15h-1zm-.25-2.5c0 .208.073.385.219.531a.723.723 0 00.531.219.723.723 0 00.531-.219.723.723 0 00.22-.531.723.723 0 00-.22-.531.723.723 0 00-.53-.219.723.723 0 00-.532.219.723.723 0 00-.219.531z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="settings" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 2h-1v5h1V2zm6.1 5H6.4L6 6.45v-1L6.4 5h3.2l.4.5v1l-.4.5zm-5 3H1.4L1 9.5v-1l.4-.5h3.2l.4.5v1l-.4.5zm3.9-8h-1v2h1V2zm-1 6h1v6h-1V8zm-4 3h-1v3h1v-3zm7.9 0h3.19l.4-.5v-.95l-.4-.5H11.4l-.4.5v.95l.4.5zm2.1-9h-1v6h1V2zm-1 10h1v2h-1v-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="settings-gear" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M19.85 8.75l4.15.83v4.84l-4.15.83 2.35 3.52-3.43 3.43-3.52-2.35-.83 4.15H9.58l-.83-4.15-3.52 2.35-3.43-3.43 2.35-3.52L0 14.42V9.58l4.15-.83L1.8 5.23 5.23 1.8l3.52 2.35L9.58 0h4.84l.83 4.15 3.52-2.35 3.43 3.43-2.35 3.52zm-1.57 5.07l4-.81v-2l-4-.81-.54-1.3 2.29-3.43-1.43-1.43-3.43 2.29-1.3-.54-.81-4h-2l-.81 4-1.3.54-3.43-2.29-1.43 1.43L6.38 8.9l-.54 1.3-4 .81v2l4 .81.54 1.3-2.29 3.43 1.43 1.43 3.43-2.29 1.3.54.81 4h2l.81-4 1.3-.54 3.43 2.29 1.43-1.43-2.29-3.43.54-1.3zm-8.186-4.672A3.43 3.43 0 0112 8.57 3.44 3.44 0 0115.43 12a3.43 3.43 0 11-5.336-2.852zm.956 4.274c.281.188.612.288.95.288A1.7 1.7 0 0013.71 12a1.71 1.71 0 10-2.66 1.422z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="shield" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.246 14.713a27.792 27.792 0 01-1.505-.953c-.501-.34-.983-.707-1.444-1.1-.458-.395-.888-.82-1.288-1.274-.4-.455-.753-.95-1.05-1.478a7.8 7.8 0 01-.7-1.69A7.041 7.041 0 012 6.3V3.1l.5-.5c.333 0 .656-.011.97-.036.296-.023.591-.066.882-.128.284-.062.562-.148.832-.256.284-.118.557-.261.816-.427a4.83 4.83 0 011.184-.565 4.8 4.8 0 012-.142 4.018 4.018 0 011.237.383c.199.097.392.204.58.322.26.167.535.31.821.428.27.109.547.194.831.256.291.062.587.106.884.129.311.024.634.035.967.035l.5.5v3.2a7.043 7.043 0 01-.256 1.919 7.804 7.804 0 01-.7 1.69 8.751 8.751 0 01-1.05 1.478c-.4.452-.829.877-1.286 1.27a15.94 15.94 0 01-1.448 1.1 28.71 28.71 0 01-1.51.956h-.508zM3 3.59V6.3c-.004.555.07 1.11.22 1.645a6.7 6.7 0 00.61 1.473c.263.467.575.905.93 1.308.37.417.766.81 1.188 1.174.432.368.883.712 1.352 1.03.4.267.8.523 1.2.769.4-.242.8-.498 1.2-.768.47-.319.923-.663 1.355-1.031.421-.364.817-.756 1.186-1.172a7.8 7.8 0 00.93-1.308c.261-.465.466-.96.61-1.473.15-.537.223-1.09.22-1.647V3.59c-.159 0-.313-.012-.465-.023l-.079-.006a7.95 7.95 0 01-1.018-.147 6.112 6.112 0 01-1.976-.814 5.166 5.166 0 00-.482-.27 3.123 3.123 0 00-.943-.29 3.686 3.686 0 00-1.558.106c-.332.108-.649.26-.94.452-.312.2-.64.372-.983.513a6.4 6.4 0 01-1 .307c-.335.07-.675.12-1.017.146-.174.01-.355.02-.54.026zm6.065 4.3a1.5 1.5 0 10-1.13 0L7.5 10.5h2l-.435-2.61z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="sign-in" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.02 3.77l.01-.01.99.99V2.5l-.5-.5h-9l-.51.5v.493L2 3v10.29l.36.46 5 1.72L8 15v-1h3.52l.5-.5v-2.25l-1 1V13H8V4.71l-.33-.46L4.036 3h6.984v.77zM7 14.28l-4-1.34V3.72l4 1.34v9.22zm3.09-6.75h4.97v1h-4.93l1.59 1.6-.71.7-2.47-2.46v-.71l2.49-2.48.7.7-1.64 1.65z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="sign-out" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.02 3.77v1.56l1-.99V2.5l-.5-.5h-9l-.5.5v.486L2 3v10.29l.36.46 5 1.72L8 15v-1h3.52l.5-.5v-1.81l-1-1V13H8V4.71l-.33-.46L4.036 3h6.984v.77zM7 14.28l-4-1.34V3.72l4 1.34v9.22zm6.52-5.8H8.55v-1h4.93l-1.6-1.6.71-.7 2.47 2.46v.71l-2.49 2.48-.7-.7 1.65-1.65z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="smiley" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.111 2.18a7 7 0 117.778 11.64A7 7 0 014.11 2.18zm.556 10.809a6 6 0 106.666-9.978 6 6 0 00-6.666 9.978zM6.5 7a1 1 0 11-2 0 1 1 0 012 0zm5 0a1 1 0 11-2 0 1 1 0 012 0zM8 11a3 3 0 01-2.65-1.58l-.87.48a4 4 0 007.12-.16l-.9-.43A3 3 0 018 11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="sort-precedence" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 2L6 3v3h1V3h7v2.453l.207-.16.793.793V3l-1-1H7zm1 2h2v2H8V4zM5 9H3v2h2V9zM2 7L1 8v5l1 1h7l1-1V8L9 7H2zm0 6V8h7v5H2zm6-3H6v2h2v-2zm5-6h-1v3.864l-1.182-1.182-.707.707 2.035 2.036h.708l2.035-2.036-.707-.707L13 7.864V4z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="source-control" xmlns="http://www.w3.org/2000/svg"><path d="M21.007 8.222A3.738 3.738 0 0015.045 5.2a3.737 3.737 0 001.156 6.583 2.988 2.988 0 01-2.668 1.67h-2.99a4.456 4.456 0 00-2.989 1.165V7.4a3.737 3.737 0 10-1.494 0v9.117a3.776 3.776 0 101.816.099 2.99 2.99 0 012.668-1.667h2.99a4.484 4.484 0 004.223-3.039 3.736 3.736 0 003.25-3.687zM4.565 3.738a2.242 2.242 0 114.484 0 2.242 2.242 0 01-4.484 0zm4.484 16.441a2.242 2.242 0 11-4.484 0 2.242 2.242 0 014.484 0zm8.221-9.715a2.242 2.242 0 110-4.485 2.242 2.242 0 010 4.485z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="split-horizontal" xmlns="http://www.w3.org/2000/svg"><path d="M14 1H3L2 2v11l1 1h11l1-1V2l-1-1zM8 13H3V2h5v11zm6 0H9V2h5v11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="split-vertical" xmlns="http://www.w3.org/2000/svg"><path d="M14 1H3L2 2v11l1 1h11l1-1V2l-1-1zm0 12H3V8h11v5zm0-6H3V2h11v5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="squirrel" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.558 2.642a3.698 3.698 0 00-.123-.01A1.47 1.47 0 003.999 1.52v1.307a4.898 4.898 0 00-2.993 3.587v.39c.459.836 1.906 1.13 2.154 1.18.027.006.04.009.035.009-2.419.32-2.19 2.249-2.19 2.249a1 1 0 001 .93c.272-.019.538-.08.79-.18h2.06a3 3 0 00-.36 1h-.32a2.55 2.55 0 00-2.17 2.528.42.42 0 00.39.48h6.677a3.76 3.76 0 003.929-4.158 3.649 3.649 0 00-.75-2.09l-.11-.14c-.43-.55-.68-.909-.55-1.289.13-.38.365-.4.365-.4s.185-.03.455.09c.22.128.46.22.71.27a1.58 1.58 0 001.736-.905c.095-.208.143-.435.143-.664.006-.718-.33-1.455-.725-2.088a4.998 4.998 0 00-1.554-1.57 3.998 3.998 0 00-2.639-.4 3.049 3.049 0 00-1.67.89 3.56 3.56 0 00-.779 1.359 4.358 4.358 0 00-.636-.747v-.159A1.47 1.47 0 005.558 1.52v1.122zm5.304 8.739c.111.741.22 1.821-.867 2.442-.296.103-.608.16-.923.167H3.215a1 1 0 01.92-1h1.279v-.499a1.79 1.79 0 011.653-1.825l-.626-.887c-.236.067-.463.153-.577.233H2.655a.754.754 0 00-.264.07c-.138.055-.274.109-.396.03-.2-.13.11-1.12 1.01-1.12h1c.49 0 .57-.54.57-.54l.28-1.129a3.389 3.389 0 01-2.85-.93 3.389 3.389 0 013.14-2.658l.083.002c.26.008.435.014.776.168.93.42 2.149 2.469 2.149 2.469l.06.09h.17v-.07c-.06-.443-.02-1.464.116-1.89.137-.424.367-.814.673-1.14a2.349 2.349 0 011.3-.659 2.639 2.639 0 011.86.29c.46.284.85.67 1.139 1.127.289.457.476.836.535 1.374-.001.02 0 .047.002.081.007.143.02.39-.128.547-.127.135-.448.23-.67.18a1.57 1.57 0 01-.45-.18 1.33 1.33 0 00-1.139-.13 1.42 1.42 0 00-.94 1 2.318 2.318 0 00.64 2.238l.11.14c.347.434.546.966.57 1.52a2.999 2.999 0 01-.306 1.425 2.708 2.708 0 00-.464-1.304l-.37.368zM4.24 5a.5.5 0 100 1 .5.5 0 000-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="star" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.595 6.252L8 1 6.405 6.252H1l4.373 3.4L3.75 15 8 11.695 12.25 15l-1.623-5.348L15 6.252H9.595zm-7.247.47H6.72L8 2.507 6.72 6.722H2.348zm3.537 2.75l-1.307 4.305 1.307-4.305zm7.767-2.75H9.28h4.372zm-8.75.9h2.366L8 5.214l.732 2.41h2.367l-1.915 1.49.731 2.409L8 10.032l-1.915 1.49.731-2.41-1.915-1.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="star-add" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.595 6.252L8 1 6.405 6.252H1l4.373 3.4L3.75 15 8 11.695 12.25 15l-1.623-5.348L15 6.252H9.595zm-7.247.47H6.72L8 2.507 6.72 6.722H2.348zm3.537 2.75l-1.307 4.305 1.307-4.305zm7.767-2.75H9.28h4.372zm-8.75.9h2.366L8 5.214l.732 2.41h2.367l-1.915 1.49.731 2.409L8 10.032l-1.915 1.49.731-2.41-1.915-1.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="star-delete" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.595 6.252L8 1 6.405 6.252H1l4.373 3.4L3.75 15 8 11.695 12.25 15l-1.623-5.348L15 6.252H9.595zm-7.247.47H6.72L8 2.507 6.72 6.722H2.348zm3.537 2.75l-1.307 4.305 1.307-4.305zm7.767-2.75H9.28h4.372zm-8.75.9h2.366L8 5.214l.732 2.41h2.367l-1.915 1.49.731 2.409L8 10.032l-1.915 1.49.731-2.41-1.915-1.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="star-empty" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.595 6.252L8 1 6.405 6.252H1l4.373 3.4L3.75 15 8 11.695 12.25 15l-1.623-5.348L15 6.252H9.595zm-7.247.47H6.72L8 2.507 6.72 6.722H2.348zm3.537 2.75l-1.307 4.305 1.307-4.305zm7.767-2.75H9.28h4.372zm-8.75.9h2.366L8 5.214l.732 2.41h2.367l-1.915 1.49.731 2.409L8 10.032l-1.915 1.49.731-2.41-1.915-1.49z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="star-full" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.595 6.252L8 1 6.405 6.252H1l4.373 3.4L3.75 15 8 11.695 12.25 15l-1.623-5.348L15 6.252H9.595z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="star-half" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.405 6.252L8 1l1.595 5.252H15l-4.373 3.4L12.25 15 8 11.695 3.75 15l1.623-5.348L1 6.252h5.405zM8 10.032l1.915 1.49-.731-2.41 1.915-1.49H8.732L8 5.214v4.82zm0-7.525zm5.652 4.215H9.28h4.372z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="stop" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6zM7.9 7.5L10.3 5l.7.7-2.4 2.5 2.4 2.5-.7.7-2.4-2.5-2.4 2.5-.7-.7 2.4-2.5-2.4-2.5.7-.7 2.4 2.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="stop-circle" xmlns="http://www.w3.org/2000/svg"><path d="M6 6h4v4H6z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-array" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2l-.5.5v11l.5.5H4v-1H2V3h2V2H1.5zm13 12l.5-.5v-11l-.5-.5H12v1h2v10h-2v1h2.5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-boolean" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 3.5l.5-.5h13l.5.5v9l-.5.5h-13l-.5-.5v-9zM14 4H8v3.493h-.5l-3.574-.005 2.09-2.09-.707-.707-2.955 2.955v.708l2.955 2.955.707-.707-2.114-2.114 3.996.005H8v-.986l3.907.005-2.114-2.114.707-.707 2.956 2.955v.708L10.5 11.309l-.707-.707 2.09-2.09L8 8.507V12h6V4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-class" xmlns="http://www.w3.org/2000/svg"><path d="M11.34 9.71h.71l2.67-2.67v-.71L13.38 5h-.7l-1.82 1.81h-5V5.56l1.86-1.85V3l-2-2H5L1 5v.71l2 2h.71l1.14-1.15v5.79l.5.5H10v.52l1.33 1.34h.71l2.67-2.67v-.71L13.37 10h-.7l-1.86 1.85h-5v-4H10v.48l1.34 1.38zm1.69-3.65l.63.63-2 2-.63-.63 2-2zm0 5l.63.63-2 2-.63-.63 2-2zM3.35 6.65l-1.29-1.3 3.29-3.29 1.3 1.29-3.3 3.3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-color" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 1.003a7 7 0 00-7 7v.43c.09 1.51 1.91 1.79 3 .7a1.87 1.87 0 012.64 2.64c-1.1 1.16-.79 3.07.8 3.2h.6a7 7 0 100-14l-.04.03zm0 13h-.52a.58.58 0 01-.36-.14.56.56 0 01-.15-.3 1.24 1.24 0 01.35-1.08 2.87 2.87 0 000-4 2.87 2.87 0 00-4.06 0 1 1 0 01-.9.34.41.41 0 01-.22-.12.42.42 0 01-.1-.29v-.37a6 6 0 116 6l-.04-.04zM9 3.997a1 1 0 11-2 0 1 1 0 012 0zm3 7.007a1 1 0 11-2 0 1 1 0 012 0zm-7-5a1 1 0 100-2 1 1 0 000 2zm7-1a1 1 0 11-2 0 1 1 0 012 0zM13 8a1 1 0 11-2 0 1 1 0 012 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-constant" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 6h8v1H4V6zm8 3H4v1h8V9z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M1 4l1-1h12l1 1v8l-1 1H2l-1-1V4zm1 0v8h12V4H2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-constructor" xmlns="http://www.w3.org/2000/svg"><path d="M13.51 4l-5-3h-1l-5 3-.49.86v6l.49.85 5 3h1l5-3 .49-.85v-6L13.51 4zm-6 9.56l-4.5-2.7V5.7l4.5 2.45v5.41zM3.27 4.7l4.74-2.84 4.74 2.84-4.74 2.59L3.27 4.7zm9.74 6.16l-4.5 2.7V8.15l4.5-2.45v5.16z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-enum" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 2H8L7 3v3h1V3h6v5h-4v1h4l1-1V3l-1-1zM9 6h4v1H9.41L9 6.59V6zM7 7H2L1 8v5l1 1h6l1-1V8L8 7H7zm1 6H2V8h6v5zM3 9h4v1H3V9zm0 2h4v1H3v-1zm6-7h4v1H9V4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-enum-member" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 3l1-1h6l1 1v5l-1 1h-4V8h4V3H8v3H7V3zm2 6V8L8 7H2L1 8v5l1 1h6l1-1V9zM8 8v5H2V8h6zm1.414-1L9 6.586V6h4v1H9.414zM9 4h4v1H9V4zm-2 6H3v1h4v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-event" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.414 1.56L8.312 1h3.294l.818 1.575L10.236 6h1.781l.72 1.695L5.618 15l-1.602-1.163L6.119 10H4.898L4 8.56l3.414-7zM7.78 9L4.9 14.305 12.018 7H8.312l3.294-5H8.312L4.898 9H7.78z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-field" xmlns="http://www.w3.org/2000/svg"><path d="M14.45 4.5l-5-2.5h-.9l-7 3.5-.55.89v4.5l.55.9 5 2.5h.9l7-3.5.55-.9v-4.5l-.55-.89zm-8 8.64l-4.5-2.25V7.17l4.5 2v3.97zm.5-4.8L2.29 6.23l6.66-3.34 4.67 2.34-6.67 3.11zm7 1.55l-6.5 3.25V9.21l6.5-3v3.68z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-file" xmlns="http://www.w3.org/2000/svg"><path d="M13.85 4.44l-3.28-3.3-.35-.14H2.5l-.5.5v13l.5.5h11l.5-.5V4.8l-.15-.36zM13 5h-3V2l3 3zM3 14V2h6v3.5l.5.5H13v8H3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-folder" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 3H7.71l-.85-.85L6.51 2h-5l-.5.5v11l.5.5h13l.5-.5v-10L14.5 3zm-.51 8.49V13h-12V7h4.49l.35-.15.86-.86H14v1.5l-.01 4zm0-6.49h-6.5l-.35.15-.86.86H2v-3h4.29l.85.85.36.15H14l-.01.99z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-function" xmlns="http://www.w3.org/2000/svg"><path d="M13.51 4l-5-3h-1l-5 3-.49.86v6l.49.85 5 3h1l5-3 .49-.85v-6L13.51 4zm-6 9.56l-4.5-2.7V5.7l4.5 2.45v5.41zM3.27 4.7l4.74-2.84 4.74 2.84-4.74 2.59L3.27 4.7zm9.74 6.16l-4.5 2.7V8.15l4.5-2.45v5.16z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-interface" xmlns="http://www.w3.org/2000/svg"><path d="M11.496 4a3.49 3.49 0 00-3.46 3h-3.1a2 2 0 100 1h3.1a3.5 3.5 0 103.46-4zm0 6a2.5 2.5 0 110-5 2.5 2.5 0 010 5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-key" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.223 10.933c.326.192.699.29 1.077.282a2.159 2.159 0 001.754-.842 3.291 3.291 0 00.654-2.113 2.886 2.886 0 00-.576-1.877 1.99 1.99 0 00-1.634-.733 2.294 2.294 0 00-1.523.567V3.475h-.991V11.1h.995v-.344c.076.066.158.125.244.177zM7.85 6.7c.186-.079.388-.113.59-.1a1.08 1.08 0 01.896.428c.257.363.382.802.357 1.245a2.485 2.485 0 01-.4 1.484 1.133 1.133 0 01-.96.508 1.224 1.224 0 01-.976-.417A1.522 1.522 0 016.975 8.8v-.6a1.722 1.722 0 01.393-1.145c.13-.154.296-.276.482-.355zM3.289 5.675a3.03 3.03 0 00-.937.162 2.59 2.59 0 00-.8.4l-.1.077v1.2l.423-.359a2.1 2.1 0 011.366-.572.758.758 0 01.661.282c.15.232.23.503.231.779L2.9 7.825a2.6 2.6 0 00-1.378.575 1.65 1.65 0 00-.022 2.336 1.737 1.737 0 001.253.454 1.96 1.96 0 001.107-.332c.102-.068.197-.145.286-.229v.444h.941V7.715a2.193 2.193 0 00-.469-1.5 1.687 1.687 0 00-1.329-.54zm.857 3.041c.02.418-.12.829-.391 1.148a1.221 1.221 0 01-.955.422.832.832 0 01-.608-.2.833.833 0 010-1.091c.281-.174.6-.277.93-.3l1.02-.148.004.169zm8.313 2.317c.307.13.64.193.973.182.495.012.983-.114 1.41-.365l.123-.075.013-.007V9.615l-.446.32c-.316.224-.696.34-1.084.329A1.3 1.3 0 0112.4 9.8a1.975 1.975 0 01-.4-1.312 2.01 2.01 0 01.453-1.381A1.432 1.432 0 0113.6 6.6a1.8 1.8 0 01.971.279l.43.265V5.97l-.17-.073a2.9 2.9 0 00-1.17-.247 2.52 2.52 0 00-1.929.817 2.9 2.9 0 00-.747 2.049c-.028.707.21 1.4.67 1.939.222.249.497.446.804.578z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-keyword" xmlns="http://www.w3.org/2000/svg"><path d="M15 4h-5V3h5v1zm-1 3h-2v1h2V7zm-4 0H1v1h9V7zm2 6H1v1h11v-1zm-5-3H1v1h6v-1zm8 0h-5v1h5v-1zM8 2v3H1V2h7zM7 3H2v1h5V3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-method" xmlns="http://www.w3.org/2000/svg"><path d="M13.51 4l-5-3h-1l-5 3-.49.86v6l.49.85 5 3h1l5-3 .49-.85v-6L13.51 4zm-6 9.56l-4.5-2.7V5.7l4.5 2.45v5.41zM3.27 4.7l4.74-2.84 4.74 2.84-4.74 2.59L3.27 4.7zm9.74 6.16l-4.5 2.7V8.15l4.5-2.45v5.16z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-misc" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 2h8v4c.341.035.677.112 1 .23V1H3v8.48l1-1.75V2zm2.14 8L5 8 4 9.75 3.29 11 1 15h8l-2.29-4-.57-1zm-3.42 4l1.72-3L5 10l.56 1 1.72 3H2.72zm6.836-6.41a3.5 3.5 0 113.888 5.82 3.5 3.5 0 01-3.888-5.82zm.555 4.989a2.5 2.5 0 102.778-4.157 2.5 2.5 0 00-2.778 4.157z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-module" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.984V2h-.09c-.313 0-.616.062-.909.185a2.33 2.33 0 00-.775.53 2.23 2.23 0 00-.493.753v.001a3.542 3.542 0 00-.198.83v.002a6.08 6.08 0 00-.024.863c.012.29.018.58.018.869 0 .203-.04.393-.117.572v.001a1.504 1.504 0 01-.765.787 1.376 1.376 0 01-.558.115H2v.984h.09c.195 0 .38.04.556.121l.001.001c.178.078.329.184.455.318l.002.002c.13.13.233.285.307.465l.001.002c.078.18.117.368.117.566 0 .29-.006.58-.018.869-.012.296-.004.585.024.87v.001c.033.283.099.558.197.824v.001c.106.273.271.524.494.753.223.23.482.407.775.53.293.123.596.185.91.185H6v-.984h-.09c-.199 0-.387-.038-.562-.115a1.613 1.613 0 01-.457-.32 1.659 1.659 0 01-.309-.467c-.074-.18-.11-.37-.11-.573 0-.228.003-.453.011-.672.008-.228.008-.45 0-.665a4.639 4.639 0 00-.055-.64 2.682 2.682 0 00-.168-.609A2.284 2.284 0 003.522 8a2.284 2.284 0 00.738-.955c.08-.192.135-.393.168-.602.033-.21.051-.423.055-.64.008-.22.008-.442 0-.666-.008-.224-.012-.45-.012-.678a1.47 1.47 0 01.877-1.354 1.33 1.33 0 01.563-.121H6zm4 10.032V14h.09c.313 0 .616-.062.909-.185.293-.123.552-.3.775-.53.223-.23.388-.48.493-.753v-.001c.1-.266.165-.543.198-.83v-.002c.028-.28.036-.567.024-.863-.012-.29-.018-.58-.018-.869 0-.203.04-.393.117-.572v-.001a1.504 1.504 0 01.765-.787c.176-.077.362-.115.558-.115H14v-.984h-.09c-.195 0-.38-.04-.556-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.414 1.414 0 01-.307-.465l-.001-.002a1.405 1.405 0 01-.117-.566c0-.29.006-.58.018-.869a6.19 6.19 0 00-.024-.87v-.001a3.542 3.542 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.33 2.33 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .386.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.282 2.282 0 00.738.955 2.282 2.282 0 00-.738.955 2.7 2.7 0 00-.168.602c-.033.21-.051.423-.055.64-.008.22-.008.442 0 .666.008.224.012.45.012.678a1.47 1.47 0 01-.42 1.035 1.466 1.466 0 01-.457.319 1.33 1.33 0 01-.563.121H10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-namespace" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.984V2h-.09c-.313 0-.616.062-.909.185a2.33 2.33 0 00-.775.53 2.23 2.23 0 00-.493.753v.001a3.542 3.542 0 00-.198.83v.002a6.08 6.08 0 00-.024.863c.012.29.018.58.018.869 0 .203-.04.393-.117.572v.001a1.504 1.504 0 01-.765.787 1.376 1.376 0 01-.558.115H2v.984h.09c.195 0 .38.04.556.121l.001.001c.178.078.329.184.455.318l.002.002c.13.13.233.285.307.465l.001.002c.078.18.117.368.117.566 0 .29-.006.58-.018.869-.012.296-.004.585.024.87v.001c.033.283.099.558.197.824v.001c.106.273.271.524.494.753.223.23.482.407.775.53.293.123.596.185.91.185H6v-.984h-.09c-.199 0-.387-.038-.562-.115a1.613 1.613 0 01-.457-.32 1.659 1.659 0 01-.309-.467c-.074-.18-.11-.37-.11-.573 0-.228.003-.453.011-.672.008-.228.008-.45 0-.665a4.639 4.639 0 00-.055-.64 2.682 2.682 0 00-.168-.609A2.284 2.284 0 003.522 8a2.284 2.284 0 00.738-.955c.08-.192.135-.393.168-.602.033-.21.051-.423.055-.64.008-.22.008-.442 0-.666-.008-.224-.012-.45-.012-.678a1.47 1.47 0 01.877-1.354 1.33 1.33 0 01.563-.121H6zm4 10.032V14h.09c.313 0 .616-.062.909-.185.293-.123.552-.3.775-.53.223-.23.388-.48.493-.753v-.001c.1-.266.165-.543.198-.83v-.002c.028-.28.036-.567.024-.863-.012-.29-.018-.58-.018-.869 0-.203.04-.393.117-.572v-.001a1.504 1.504 0 01.765-.787c.176-.077.362-.115.558-.115H14v-.984h-.09c-.195 0-.38-.04-.556-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.414 1.414 0 01-.307-.465l-.001-.002a1.405 1.405 0 01-.117-.566c0-.29.006-.58.018-.869a6.19 6.19 0 00-.024-.87v-.001a3.542 3.542 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.33 2.33 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .386.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.282 2.282 0 00.738.955 2.282 2.282 0 00-.738.955 2.7 2.7 0 00-.168.602c-.033.21-.051.423-.055.64-.008.22-.008.442 0 .666.008.224.012.45.012.678a1.47 1.47 0 01-.42 1.035 1.466 1.466 0 01-.457.319 1.33 1.33 0 01-.563.121H10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-null" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 3.5l.5-.5h13l.5.5v9l-.5.5h-13l-.5-.5v-9zM14 4H8v3.493h-.5l-3.574-.005 2.09-2.09-.707-.707-2.955 2.955v.708l2.955 2.955.707-.707-2.114-2.114 3.996.005H8v-.986l3.907.005-2.114-2.114.707-.707 2.956 2.955v.708L10.5 11.309l-.707-.707 2.09-2.09L8 8.507V12h6V4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-number" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11 1v4h4v1h-4v4h4v1h-4v4h-1v-4H6v4H5v-4H1v-1h4V6H1V5h4V1h1v4h4V1h1zM6 6v4h4V6H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-numeric" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11 1v4h4v1h-4v4h4v1h-4v4h-1v-4H6v4H5v-4H1v-1h4V6H1V5h4V1h1v4h4V1h1zM6 6v4h4V6H6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-object" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.984V2h-.09c-.313 0-.616.062-.909.185a2.33 2.33 0 00-.775.53 2.23 2.23 0 00-.493.753v.001a3.542 3.542 0 00-.198.83v.002a6.08 6.08 0 00-.024.863c.012.29.018.58.018.869 0 .203-.04.393-.117.572v.001a1.504 1.504 0 01-.765.787 1.376 1.376 0 01-.558.115H2v.984h.09c.195 0 .38.04.556.121l.001.001c.178.078.329.184.455.318l.002.002c.13.13.233.285.307.465l.001.002c.078.18.117.368.117.566 0 .29-.006.58-.018.869-.012.296-.004.585.024.87v.001c.033.283.099.558.197.824v.001c.106.273.271.524.494.753.223.23.482.407.775.53.293.123.596.185.91.185H6v-.984h-.09c-.199 0-.387-.038-.562-.115a1.613 1.613 0 01-.457-.32 1.659 1.659 0 01-.309-.467c-.074-.18-.11-.37-.11-.573 0-.228.003-.453.011-.672.008-.228.008-.45 0-.665a4.639 4.639 0 00-.055-.64 2.682 2.682 0 00-.168-.609A2.284 2.284 0 003.522 8a2.284 2.284 0 00.738-.955c.08-.192.135-.393.168-.602.033-.21.051-.423.055-.64.008-.22.008-.442 0-.666-.008-.224-.012-.45-.012-.678a1.47 1.47 0 01.877-1.354 1.33 1.33 0 01.563-.121H6zm4 10.032V14h.09c.313 0 .616-.062.909-.185.293-.123.552-.3.775-.53.223-.23.388-.48.493-.753v-.001c.1-.266.165-.543.198-.83v-.002c.028-.28.036-.567.024-.863-.012-.29-.018-.58-.018-.869 0-.203.04-.393.117-.572v-.001a1.504 1.504 0 01.765-.787c.176-.077.362-.115.558-.115H14v-.984h-.09c-.195 0-.38-.04-.556-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.414 1.414 0 01-.307-.465l-.001-.002a1.405 1.405 0 01-.117-.566c0-.29.006-.58.018-.869a6.19 6.19 0 00-.024-.87v-.001a3.542 3.542 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.33 2.33 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .386.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.282 2.282 0 00.738.955 2.282 2.282 0 00-.738.955 2.7 2.7 0 00-.168.602c-.033.21-.051.423-.055.64-.008.22-.008.442 0 .666.008.224.012.45.012.678a1.47 1.47 0 01-.42 1.035 1.466 1.466 0 01-.457.319 1.33 1.33 0 01-.563.121H10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-operator" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.873 1.1c.335.136.602.398.745.73.072.17.109.352.107.537a1.34 1.34 0 01-.61 1.135 1.359 1.359 0 01-.753.223A1.355 1.355 0 011 2.362a1.355 1.355 0 01.83-1.256A1.37 1.37 0 012.873 1.1zm-.298 1.765a.551.551 0 00.332-.5.548.548 0 10-.332.5zM6.43 1.109L1.11 6.43l.686.687 5.32-5.32-.686-.687zM11.5 9h1v2.5H15v1h-2.5V15h-1v-2.5H9v-1h2.5V9zm-5.732.525l.707.707L4.707 12l1.768 1.768-.707.707L4 12.707l-1.768 1.768-.707-.707L3.293 12l-1.768-1.768.707-.707L4 11.293l1.768-1.768zm1.35-4.195a1.353 1.353 0 00-1.256-.83 1.355 1.355 0 00-1.256.83 1.362 1.362 0 001.257 1.895A1.358 1.358 0 007.118 5.33zm-.753.745a.553.553 0 01-.289.29.547.547 0 01-.599-.117.529.529 0 01-.117-.173.544.544 0 01.716-.715.565.565 0 01.173.116.549.549 0 01.116.599zM14 3h-4v1h4V3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-package" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.984V2h-.09c-.313 0-.616.062-.909.185a2.33 2.33 0 00-.775.53 2.23 2.23 0 00-.493.753v.001a3.542 3.542 0 00-.198.83v.002a6.08 6.08 0 00-.024.863c.012.29.018.58.018.869 0 .203-.04.393-.117.572v.001a1.504 1.504 0 01-.765.787 1.376 1.376 0 01-.558.115H2v.984h.09c.195 0 .38.04.556.121l.001.001c.178.078.329.184.455.318l.002.002c.13.13.233.285.307.465l.001.002c.078.18.117.368.117.566 0 .29-.006.58-.018.869-.012.296-.004.585.024.87v.001c.033.283.099.558.197.824v.001c.106.273.271.524.494.753.223.23.482.407.775.53.293.123.596.185.91.185H6v-.984h-.09c-.199 0-.387-.038-.562-.115a1.613 1.613 0 01-.457-.32 1.659 1.659 0 01-.309-.467c-.074-.18-.11-.37-.11-.573 0-.228.003-.453.011-.672.008-.228.008-.45 0-.665a4.639 4.639 0 00-.055-.64 2.682 2.682 0 00-.168-.609A2.284 2.284 0 003.522 8a2.284 2.284 0 00.738-.955c.08-.192.135-.393.168-.602.033-.21.051-.423.055-.64.008-.22.008-.442 0-.666-.008-.224-.012-.45-.012-.678a1.47 1.47 0 01.877-1.354 1.33 1.33 0 01.563-.121H6zm4 10.032V14h.09c.313 0 .616-.062.909-.185.293-.123.552-.3.775-.53.223-.23.388-.48.493-.753v-.001c.1-.266.165-.543.198-.83v-.002c.028-.28.036-.567.024-.863-.012-.29-.018-.58-.018-.869 0-.203.04-.393.117-.572v-.001a1.504 1.504 0 01.765-.787c.176-.077.362-.115.558-.115H14v-.984h-.09c-.195 0-.38-.04-.556-.121l-.001-.001a1.376 1.376 0 01-.455-.318l-.002-.002a1.414 1.414 0 01-.307-.465l-.001-.002a1.405 1.405 0 01-.117-.566c0-.29.006-.58.018-.869a6.19 6.19 0 00-.024-.87v-.001a3.542 3.542 0 00-.197-.824v-.001a2.23 2.23 0 00-.494-.753 2.33 2.33 0 00-.775-.53 2.325 2.325 0 00-.91-.185H10v.984h.09c.2 0 .386.038.562.115.174.082.326.188.457.32.127.134.23.29.309.467.074.18.11.37.11.573 0 .228-.003.452-.011.672-.008.228-.008.45 0 .665.004.222.022.435.055.64.033.214.089.416.168.609a2.282 2.282 0 00.738.955 2.282 2.282 0 00-.738.955 2.7 2.7 0 00-.168.602c-.033.21-.051.423-.055.64-.008.22-.008.442 0 .666.008.224.012.45.012.678a1.47 1.47 0 01-.42 1.035 1.466 1.466 0 01-.457.319 1.33 1.33 0 01-.563.121H10z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-parameter" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11 6h-1v-.5a.5.5 0 00-.5-.5H8.479v5.5a.5.5 0 00.5.5h.5v1h-3v-1h.5a.5.5 0 00.5-.5V5H6.5a.5.5 0 00-.5.5V6H5V4h6v2zm2.914 2.048l-1.462-1.462.707-.707 1.816 1.816v.707l-1.768 1.767-.707-.707 1.414-1.414zM3.548 9.462L2.086 8 3.5 6.586l-.707-.707-1.768 1.767v.708l1.816 1.815.707-.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-property" xmlns="http://www.w3.org/2000/svg"><path d="M2.807 14.975a1.75 1.75 0 01-1.255-.556 1.684 1.684 0 01-.544-1.1A1.72 1.72 0 011.36 12.1c1.208-1.27 3.587-3.65 5.318-5.345a4.257 4.257 0 01.048-3.078 4.095 4.095 0 011.665-1.969 4.259 4.259 0 014.04-.36l.617.268-2.866 2.951 1.255 1.259 2.944-2.877.267.619a4.295 4.295 0 01.04 3.311 4.198 4.198 0 01-.923 1.392 4.27 4.27 0 01-.743.581 4.217 4.217 0 01-3.812.446c-1.098 1.112-3.84 3.872-5.32 5.254a1.63 1.63 0 01-1.084.423zm7.938-13.047a3.32 3.32 0 00-1.849.557c-.213.13-.412.284-.591.458a3.321 3.321 0 00-.657 3.733l.135.297-.233.227c-1.738 1.697-4.269 4.22-5.485 5.504a.805.805 0 00.132 1.05.911.911 0 00.298.22c.1.044.209.069.319.072a.694.694 0 00.45-.181c1.573-1.469 4.612-4.539 5.504-5.44l.23-.232.294.135a3.286 3.286 0 003.225-.254 3.33 3.33 0 00.591-.464 3.28 3.28 0 00.964-2.358c0-.215-.021-.43-.064-.642L11.43 7.125 8.879 4.578l2.515-2.59a3.286 3.286 0 00-.65-.06z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-reference" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 5.914l2.06-2.06v-.708L5.915 1l-.707.707.043.043.25.25 1 1h-3a2.5 2.5 0 000 5H4V7h-.5a1.5 1.5 0 110-3h3L5.207 5.293 5.914 6 6 5.914zM11 2H8.328l-1-1H12l.71.29 3 3L16 5v9l-1 1H6l-1-1V6.5l1 .847V14h9V6h-4V2zm1 0v3h3l-3-3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-ruler" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 1L3 2v12l1 1h8l1-1V2l-1-1H4zm0 2V2h8v12H4v-1h2v-1H4v-2h4V9H4V7h2V6H4V4h4V3H4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-snippet" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 1l-.5.5V13h1V2h11v11h1V1.5l-.5-.5h-12zM2 15v-1h1v1H2zm3-1H4v1h1v-1zm1 0h1v1H6v-1zm3 0H8v1h1v-1zm1 0h1v1h-1v-1zm5 1v-1h-1v1h1zm-3-1h1v1h-1v-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-string" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 2L1 3v9l1 1h12l1-1V3l-1-1H2zm0 10V3h12v9H2zm3.356-3.07H6V7.22C6 6.408 5.685 6 5.056 6c-.135 0-.285.024-.45.073a1.444 1.444 0 00-.388.167v.665c.237-.203.487-.304.75-.304.261 0 .392.156.392.469l-.6.103c-.506.086-.76.406-.76.961 0 .263.061.473.183.631A.61.61 0 004.69 9c.29 0 .509-.16.657-.48h.009v.41zm.004-1.355v.193a.75.75 0 01-.12.436.368.368 0 01-.313.17.276.276 0 01-.22-.095.38.38 0 01-.08-.248c0-.222.11-.351.332-.389l.4-.067zM7.6 8.626h-.007v.31H7V5h.593v1.677h.008c.146-.31.355-.465.625-.465.248 0 .44.118.573.353.134.236.201.557.201.966 0 .443-.078.798-.235 1.067C8.61 8.866 8.4 9 8.138 9c-.237 0-.416-.125-.537-.374zm-.016-1.121v.272a.78.78 0 00.107.426c.071.113.163.169.274.169.135 0 .24-.072.314-.216.075-.145.113-.35.113-.615 0-.22-.035-.39-.104-.514-.067-.124-.164-.187-.29-.187-.12 0-.219.062-.298.185a.887.887 0 00-.116.48zM11.262 9c.321 0 .567-.058.738-.173v-.71a.9.9 0 01-.552.207.619.619 0 01-.5-.215c-.12-.145-.181-.345-.181-.598 0-.26.063-.464.189-.612a.644.644 0 01.516-.223c.194 0 .37.069.528.207v-.749c-.129-.09-.338-.134-.626-.134-.417 0-.751.14-1.001.422-.249.28-.373.662-.373 1.148 0 .42.116.764.349 1.03.232.267.537.4.913.4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-struct" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 2L1 3v3l1 1h12l1-1V3l-1-1H2zm0 1h12v3H2V3zm-1 7l1-1h3l1 1v3l-1 1H2l-1-1v-3zm2 0H2v3h3v-3H3zm7 0l1-1h3l1 1v3l-1 1h-3l-1-1v-3zm2 0h-1v3h3v-3h-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-structure" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 2L1 3v3l1 1h12l1-1V3l-1-1H2zm0 1h12v3H2V3zm-1 7l1-1h3l1 1v3l-1 1H2l-1-1v-3zm2 0H2v3h3v-3H3zm7 0l1-1h3l1 1v3l-1 1h-3l-1-1v-3zm2 0h-1v3h3v-3h-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-text" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.223 10.933c.326.192.699.29 1.077.282a2.159 2.159 0 001.754-.842 3.291 3.291 0 00.654-2.113 2.886 2.886 0 00-.576-1.877 1.99 1.99 0 00-1.634-.733 2.294 2.294 0 00-1.523.567V3.475h-.991V11.1h.995v-.344c.076.066.158.125.244.177zM7.85 6.7c.186-.079.388-.113.59-.1a1.08 1.08 0 01.896.428c.257.363.382.802.357 1.245a2.485 2.485 0 01-.4 1.484 1.133 1.133 0 01-.96.508 1.224 1.224 0 01-.976-.417A1.522 1.522 0 016.975 8.8v-.6a1.722 1.722 0 01.393-1.145c.13-.154.296-.276.482-.355zM3.289 5.675a3.03 3.03 0 00-.937.162 2.59 2.59 0 00-.8.4l-.1.077v1.2l.423-.359a2.1 2.1 0 011.366-.572.758.758 0 01.661.282c.15.232.23.503.231.779L2.9 7.825a2.6 2.6 0 00-1.378.575 1.65 1.65 0 00-.022 2.336 1.737 1.737 0 001.253.454 1.96 1.96 0 001.107-.332c.102-.068.197-.145.286-.229v.444h.941V7.715a2.193 2.193 0 00-.469-1.5 1.687 1.687 0 00-1.329-.54zm.857 3.041c.02.418-.12.829-.391 1.148a1.221 1.221 0 01-.955.422.832.832 0 01-.608-.2.833.833 0 010-1.091c.281-.174.6-.277.93-.3l1.02-.148.004.169zm8.313 2.317c.307.13.64.193.973.182.495.012.983-.114 1.41-.365l.123-.075.013-.007V9.615l-.446.32c-.316.224-.696.34-1.084.329A1.3 1.3 0 0112.4 9.8a1.975 1.975 0 01-.4-1.312 2.01 2.01 0 01.453-1.381A1.432 1.432 0 0113.6 6.6a1.8 1.8 0 01.971.279l.43.265V5.97l-.17-.073a2.9 2.9 0 00-1.17-.247 2.52 2.52 0 00-1.929.817 2.9 2.9 0 00-.747 2.049c-.028.707.21 1.4.67 1.939.222.249.497.446.804.578z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-type-parameter" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11 6h-1v-.5a.5.5 0 00-.5-.5H8.479v5.5a.5.5 0 00.5.5h.5v1h-3v-1h.5a.5.5 0 00.5-.5V5H6.5a.5.5 0 00-.5.5V6H5V4h6v2zm2.914 2.048l-1.462-1.462.707-.707 1.816 1.816v.707l-1.768 1.767-.707-.707 1.414-1.414zM3.548 9.462L2.086 8 3.5 6.586l-.707-.707-1.768 1.767v.708l1.816 1.815.707-.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-unit" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 1L3 2v12l1 1h8l1-1V2l-1-1H4zm0 2V2h8v12H4v-1h2v-1H4v-2h4V9H4V7h2V6H4V4h4V3H4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-value" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 2H8L7 3v3h1V3h6v5h-4v1h4l1-1V3l-1-1zM9 6h4v1H9.41L9 6.59V6zM7 7H2L1 8v5l1 1h6l1-1V8L8 7H7zm1 6H2V8h6v5zM3 9h4v1H3V9zm0 2h4v1H3v-1zm6-7h4v1H9V4z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="symbol-variable" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 5h2V4H1.5l-.5.5v8l.5.5H4v-1H2V5zm12.5-1H12v1h2v7h-2v1h2.5l.5-.5v-8l-.5-.5zm-2.74 2.57L12 7v2.51l-.3.45-4.5 2h-.46l-2.5-1.5-.24-.43v-2.5l.3-.46 4.5-2h.46l2.5 1.5zM5 9.71l1.5.9V9.28L5 8.38v1.33zm.58-2.15l1.45.87 3.39-1.5-1.45-.87-3.39 1.5zm1.95 3.17l3.5-1.56v-1.4l-3.5 1.55v1.41z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="sync" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.006 8.267L.78 9.5 0 8.73l2.09-2.07.76.01 2.09 2.12-.76.76-1.167-1.18a5 5 0 009.4 1.983l.813.597a6 6 0 01-11.22-2.683zm10.99-.466L11.76 6.55l-.76.76 2.09 2.11.76.01 2.09-2.07-.75-.76-1.194 1.18a6 6 0 00-11.11-2.92l.81.594a5 5 0 019.3 2.346z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="sync-ignored" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.468 3.687l-.757-.706a6 6 0 019.285 4.799L15.19 6.6l.75.76-2.09 2.07-.76-.01L11 7.31l.76-.76 1.236 1.25a5 5 0 00-7.528-4.113zm4.55 8.889l.784.73a6 6 0 01-8.796-5.04L.78 9.5 0 8.73l2.09-2.07.76.01 2.09 2.12-.76.76-1.167-1.18a5 5 0 007.005 4.206z"/><path d="M1.123 2.949l.682-.732L13.72 13.328l-.682.732z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="table" xmlns="http://www.w3.org/2000/svg"><path d="M13.5 2h-12l-.5.5v11l.5.5h12l.5-.5v-11l-.5-.5zM2 3h11v1H2V3zm7 4H6V5h3v2zm0 1v2H6V8h3zM2 5h3v2H2V5zm0 3h3v2H2V8zm0 5v-2h3v2H2zm4 0v-2h3v2H6zm7 0h-3v-2h3v2zm0-3h-3V8h3v2zm-3-3V5h3v2h-3z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="tag" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.2 2H8.017l-.353.146L1 8.81v.707L6.183 14.7h.707l2.215-2.215A4.48 4.48 0 0015.65 9c.027-.166.044-.332.051-.5a4.505 4.505 0 00-2-3.74V2.5l-.5-.5zm-.5 2.259A4.504 4.504 0 0011.2 4a.5.5 0 100 1 3.5 3.5 0 011.5.338v2.138L8.775 11.4a.506.506 0 00-.217.217l-2.022 2.022-4.475-4.476L8.224 3H12.7v1.259zm1 1.792a3.5 3.5 0 011 2.449 3.438 3.438 0 01-.051.5 3.487 3.487 0 01-4.793 2.735l3.698-3.698.146-.354V6.051z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="tag-add" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.2 2H8.017l-.353.146L1 8.81v.707L6.183 14.7h.707l2.215-2.215A4.48 4.48 0 0015.65 9c.027-.166.044-.332.051-.5a4.505 4.505 0 00-2-3.74V2.5l-.5-.5zm-.5 2.259A4.504 4.504 0 0011.2 4a.5.5 0 100 1 3.5 3.5 0 011.5.338v2.138L8.775 11.4a.506.506 0 00-.217.217l-2.022 2.022-4.475-4.476L8.224 3H12.7v1.259zm1 1.792a3.5 3.5 0 011 2.449 3.438 3.438 0 01-.051.5 3.487 3.487 0 01-4.793 2.735l3.698-3.698.146-.354V6.051z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="tag-remove" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.2 2H8.017l-.353.146L1 8.81v.707L6.183 14.7h.707l2.215-2.215A4.48 4.48 0 0015.65 9c.027-.166.044-.332.051-.5a4.505 4.505 0 00-2-3.74V2.5l-.5-.5zm-.5 2.259A4.504 4.504 0 0011.2 4a.5.5 0 100 1 3.5 3.5 0 011.5.338v2.138L8.775 11.4a.506.506 0 00-.217.217l-2.022 2.022-4.475-4.476L8.224 3H12.7v1.259zm1 1.792a3.5 3.5 0 011 2.449 3.438 3.438 0 01-.051.5 3.487 3.487 0 01-4.793 2.735l3.698-3.698.146-.354V6.051z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="target" xmlns="http://www.w3.org/2000/svg"><path d="M8 9a1 1 0 100-2 1 1 0 000 2z"/><path d="M12 8a4 4 0 11-8 0 4 4 0 018 0zm-4 3a3 3 0 100-6 3 3 0 000 6z"/><path d="M15 8A7 7 0 111 8a7 7 0 0114 0zm-7 6A6 6 0 108 2a6 6 0 000 12z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="tasklist" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.57 6.699l5.693-4.936L8.585 1 3.273 5.596l-1.51-1.832L1 4.442l1.85 2.214.72.043zM15 5H6.824l2.307-2H15v2zM6 7h9v2H6V7zm9 4H6v2h9v-2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="telescope" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.24 1l.59.24 2.11 4.93-.23.59-3.29 1.41-.59-.24-.17-.41L6.1 9l-.58-.19-.16-.38L2.8 9.49l-.58-.24-.72-1.67.28-.59 2.5-1.06-.18-.41.24-.58L7.9 3.41 7.72 3 8 2.42 11.24 1zM2.5 7.64l.35.85 2.22-.91-.37-.85-2.2.91zm2.74-2.12l1.11 2.45 3-1.28-1.11-2.44-3 1.27zM8.79 3l1.86 4.11 2.29-1.01L11.18 2 8.72 3h.07zM8.5 9.1l3.02 4.9h-1.17l-1.88-3.03v4h-1V9.82L5.58 14h-1.1l1.7-3.9 2.32-1z"/></symbol><symbol fill="currentColor" viewBox="0 0 24 24" id="terminal" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 1.5L1.5 3v18L3 22.5h18l1.5-1.5V3L21 1.5H3zM3 21V3h18v18H3zm5.656-4.01l1.038 1.061 5.26-5.243v-.912l-5.26-5.26-1.035 1.06 4.59 4.702-4.593 4.592z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="terminal-bash" xmlns="http://www.w3.org/2000/svg"><path d="M13.655 3.56L8.918.75a1.785 1.785 0 00-1.82 0L2.363 3.56a1.889 1.889 0 00-.921 1.628v5.624a1.889 1.889 0 00.913 1.627l4.736 2.812a1.785 1.785 0 001.82 0l4.736-2.812a1.888 1.888 0 00.913-1.627V5.188a1.889 1.889 0 00-.904-1.627zm-3.669 8.781v.404a.149.149 0 01-.07.124l-.239.137c-.038.02-.07 0-.07-.053v-.396a.78.78 0 01-.545.053.073.073 0 01-.027-.09l.086-.365a.153.153 0 01.071-.096.048.048 0 01.038 0 .662.662 0 00.497-.063.662.662 0 00.37-.567c0-.206-.112-.292-.384-.293-.344 0-.661-.066-.67-.574A1.47 1.47 0 019.6 9.437V9.03a.147.147 0 01.07-.126l.231-.147c.038-.02.07 0 .07.054v.409a.754.754 0 01.453-.055.073.073 0 01.03.095l-.081.362a.156.156 0 01-.065.09.055.055 0 01-.035 0 .6.6 0 00-.436.072.549.549 0 00-.331.486c0 .185.098.242.425.248.438 0 .627.199.632.639a1.568 1.568 0 01-.576 1.185zm2.481-.68a.094.094 0 01-.036.092l-1.198.727a.034.034 0 01-.04.003.035.035 0 01-.016-.037v-.31a.086.086 0 01.055-.076l1.179-.706a.035.035 0 01.056.035v.273zm.827-6.914L8.812 7.515c-.559.331-.97.693-.97 1.367v5.52c0 .404.165.662.413.741a1.465 1.465 0 01-.248.025c-.264 0-.522-.072-.748-.207L2.522 12.15a1.558 1.558 0 01-.75-1.338V5.188a1.558 1.558 0 01.75-1.34l4.738-2.81a1.46 1.46 0 011.489 0l4.736 2.812a1.548 1.548 0 01.728 1.083c-.154-.334-.508-.427-.92-.185h.002z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="terminal-cmd" xmlns="http://www.w3.org/2000/svg"><path d="M10.875 7l2.008 5h-.711l-2.008-5h.711zm-5.125.594c-.276 0-.526.041-.75.125a1.542 1.542 0 00-.578.375c-.162.166-.287.37-.375.61a2.364 2.364 0 00-.133.827c0 .287.04.547.117.781.078.235.196.433.352.594.156.162.346.29.57.383.224.094.48.138.766.133a2.63 2.63 0 00.992-.195l.125.484a1.998 1.998 0 01-.492.148 4.381 4.381 0 01-.75.07 2.61 2.61 0 01-.914-.156 2.207 2.207 0 01-.742-.453 1.878 1.878 0 01-.485-.742 3.204 3.204 0 01-.18-1.023c0-.365.06-.698.18-1 .12-.302.287-.563.5-.782.214-.218.471-.388.774-.507a2.69 2.69 0 011-.18c.296 0 .536.023.718.07.183.047.315.094.399.14l-.149.493a1.85 1.85 0 00-.406-.14 2.386 2.386 0 00-.539-.055zM8 8h1v1H8V8zm0 2h1v1H8v-1z"/><path d="M15.5 1H.5l-.5.5v13l.5.5h15l.5-.5v-13l-.5-.5zM15 14H1V5h14v9zm0-10H1V2h14v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="terminal-debian" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.084.029a1.276 1.276 0 00-.355.05L6.622.065a9.46 9.46 0 01.514-.048c.075-.005.15-.01.224-.017a1.67 1.67 0 01-.276.029zm4.127 7.646c.094-.238.172-.436.16-.762l-.133.282c.135-.41.123-.847.112-1.262-.005-.187-.01-.37-.002-.543l-.054-.015c-.048-1.411-1.268-2.911-2.354-3.419-.936-.432-2.376-.506-3.042-.18a.657.657 0 01.212-.085c.107-.031.197-.058.135-.093-.6.06-.778.171-.973.294a1.92 1.92 0 01-.635.273c-.11.106.051.063.181.029.129-.035.226-.06-.004.076a1.7 1.7 0 01-.303.05c-.26.025-.492.048-.96.532.026.041.11-.009.168-.044.072-.043.106-.063-.054.137C3.07 2.871 1.78 4.31 1.507 4.787l.143.025c-.1.25-.213.461-.313.649-.136.254-.249.464-.273.667a16.97 16.97 0 01-.062.635C.907 7.619.79 8.679 1.12 9.06l-.04.406.052.11c.036.079.071.157.12.23l-.093.008c.22.692.338.704.473.717.137.013.291.028.585.757-.084-.028-.17-.06-.293-.226-.015.127.18.508.41.806l-.097.112a.89.89 0 00.27.311c.023.019.045.036.066.055-.372-.203.1.428.371.79.078.104.14.186.159.218l.073-.132c-.01.19.136.433.41.772l.229-.009c.094.186.438.522.647.538l-.139.181c.254.08.321.135.397.195.08.064.17.136.502.253l-.13-.23c.108.095.192.186.273.272.162.176.31.335.62.481.352.123.536.152.74.184.168.026.35.055.649.14a33.82 33.82 0 00-.217-.005c-.506-.012-1.056-.025-1.443-.163-3.016-.817-5.776-4.356-5.574-8-.02-.311-.01-.655 0-.961.012-.422.022-.776-.049-.882l.032-.105c.166-.54.365-1.191.742-1.957L.861 3.92v-.002.001c.012.012.106.107.275-.18.04-.09.079-.182.117-.276.08-.19.16-.383.264-.56l.08-.02c.054-.315.533-.744.93-1.1.19-.171.362-.326.46-.443l.02.138C3.541.977 4.414.611 5.074.334c.152-.063.291-.122.414-.176-.107.118.067.082.311.032.15-.03.325-.067.478-.076-.04.023-.082.044-.122.065-.085.045-.17.088-.25.145.26-.062.373-.044.499-.024.109.018.227.036.456.006-.174.025-.384.094-.35.12.245.029.398-.002.537-.03.174-.034.327-.065.61.03L7.625.275c.235.085.409.137.564.183.313.094.55.165 1.067.439a.58.58 0 00.23-.037c.112-.035.218-.069.477.037.014.025.022.046.03.066.03.08.054.143.456.383.056-.022-.097-.162-.22-.274l-.003-.004c1.01.54 2.108 1.692 2.443 2.924-.188-.347-.162-.171-.134.015.018.124.037.253-.006.235.14.377.255.766.325 1.168l-.023-.085c-.102-.368-.3-1.081-.626-1.555-.012.137-.092.122-.165.108-.105-.019-.196-.036-.058.393.081.119.096.074.109.034.015-.047.027-.086.147.164.002.133.034.266.07.414.022.094.046.195.065.306-.034-.006-.07-.07-.106-.13-.045-.076-.087-.147-.117-.101.076.358.201.545.25.572-.009.02-.021.02-.034.021-.027.002-.056.003-.059.167.022.428.102.39.166.361.02-.009.037-.017.051-.01a1.724 1.724 0 01-.083.245c-.086.221-.188.48-.106.816a2.356 2.356 0 00-.106-.295 5.896 5.896 0 01-.046-.117c-.018.151-.01.256-.003.355.013.166.023.312-.094.62.135-.442.12-.841-.007-.649.03.343-.12.642-.254.908-.111.222-.211.42-.184.602l-.161-.222c-.238.344-.22.417-.202.489.015.06.03.12-.105.339.051-.09.041-.112.031-.133-.01-.024-.021-.046.053-.158-.05.003-.17.12-.316.265-.123.121-.265.261-.402.368-1.172.94-2.571 1.062-3.926.556.006-.031-.006-.066-.097-.128-1.148-.88-1.827-1.628-1.591-3.36.068-.051.117-.193.175-.362.09-.263.203-.59.448-.745.245-.541.979-1.04 1.764-1.052.8-.044 1.476.427 1.816.872-.618-.576-1.63-.751-2.493-.324-.882.396-1.405 1.368-1.329 2.336.01-.016.021-.023.03-.03.02-.015.037-.027.048-.108-.027 1.88 2.026 3.258 3.504 2.563l.018.039c.397-.109.497-.205.633-.335.07-.067.148-.142.28-.233a.441.441 0 01-.075.085c-.068.067-.143.14-.05.142.166-.043.634-.465.947-.746l.133-.119c.062-.134.051-.177.04-.221-.012-.052-.025-.104.076-.3l.229-.114c.03-.088.062-.168.092-.243zM6.612 10.06a.018.018 0 00-.005.016.114.114 0 00.005-.016zm-.005.016c.008.069.269.268.465.369.516.19 1.1.198 1.559.181-.993.415-2.889-.422-3.509-1.532.057.012.168.14.303.297.204.234.462.532.678.605-.213-.17-.377-.387-.53-.61.288.33.637.6 1.019.779a.102.102 0 01.01-.077l.005-.012zM6.752.219a6.612 6.612 0 01-.075-.013c.472.014.437.045.283.08.018-.029-.09-.047-.208-.067zM9.63 6.732c.032-.477-.094-.326-.136-.144.019.01.036.059.052.107.028.08.054.158.084.037zm-.211.664a1.68 1.68 0 01-.314.703c.006-.061-.038-.074-.083-.086-.092-.026-.183-.052.176-.504a1.113 1.113 0 01-.126.242c-.112.184-.21.344.126.133l.033-.06a1.43 1.43 0 00.188-.428zm-1.34 1.247c-.347-.053-.662-.186-.397-.19.221.02.44.02.656-.033a3.544 3.544 0 01-.26.223zM6.958.285l-.1.02.094-.008.006-.012zM4.79 8.818l-.038.186c.047.064.092.13.136.195.12.175.237.348.4.483a4.73 4.73 0 00-.214-.368c-.08-.13-.169-.272-.285-.496zm.226-.319c.052.108.104.213.185.302l.082.24-.038-.063c-.1-.166-.2-.333-.252-.524l.023.045zm7.474-1.282l-.039.098a4.717 4.717 0 01-.462 1.474c.261-.49.43-1.028.501-1.572zM.436 3.426zm.002.022c.008.037.043.028.075.02.06-.015.114-.03-.004.236-.074.052-.119.087-.144.106l-.027.02a.05.05 0 01.008-.017.597.597 0 00.092-.365zM.118 4.76a2.92 2.92 0 01-.106.436.588.588 0 00-.005-.154c-.013-.105-.025-.197.135-.402a4.009 4.009 0 00-.023.12z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="terminal-linux" xmlns="http://www.w3.org/2000/svg"><path d="M13.281 11.156a.84.84 0 01.375.297c.084.125.143.276.18.453.02.104.044.2.07.29a1.772 1.772 0 00.219.476c.047.073.11.153.188.242.067.073.127.167.18.281a.793.793 0 01.077.328.49.49 0 01-.093.305.944.944 0 01-.235.219c-.12.083-.245.156-.375.219-.13.062-.26.127-.39.195a3.624 3.624 0 00-.555.328c-.156.115-.313.26-.469.438a2.815 2.815 0 01-.625.523 1.471 1.471 0 01-.383.172c-.13.036-.26.06-.39.07-.302 0-.552-.052-.75-.156-.198-.104-.37-.294-.516-.57-.042-.079-.083-.128-.125-.149a.774.774 0 00-.203-.055L8.67 15c-.26-.02-.525-.031-.796-.031a4.28 4.28 0 00-.672.054c-.229.037-.456.081-.68.133-.046.01-.093.05-.14.117a1.7 1.7 0 01-.196.227 1.106 1.106 0 01-.335.219 1.475 1.475 0 01-.555.101c-.172 0-.357-.018-.555-.054a1.82 1.82 0 01-.531-.18 3.578 3.578 0 00-.953-.328c-.313-.057-.643-.11-.992-.156a3.392 3.392 0 01-.344-.063.774.774 0 01-.29-.133.705.705 0 01-.194-.219.78.78 0 01-.079-.351c0-.162.021-.318.063-.469.042-.15.065-.31.07-.476 0-.115-.008-.227-.023-.336a3.53 3.53 0 01-.032-.352c0-.265.063-.46.188-.586.125-.125.307-.224.547-.297a.99.99 0 00.297-.148 2.27 2.27 0 00.234-.203 1.86 1.86 0 00.203-.242c.063-.089.133-.178.211-.266a.114.114 0 00.024-.07c0-.063-.003-.123-.008-.18l-.016-.188c0-.354.055-.71.164-1.07.11-.36.253-.71.43-1.055a9.08 9.08 0 01.594-.992c.218-.317.435-.612.648-.883a4.35 4.35 0 00.68-1.203c.15-.416.229-.87.234-1.36 0-.207-.01-.413-.031-.616a6.122 6.122 0 01-.031-.625c0-.417.047-.792.14-1.125.094-.334.24-.62.438-.86s.456-.419.773-.539C7.474.075 7.854.01 8.296 0c.527 0 .946.104 1.259.313.312.208.552.481.718.82.167.338.274.716.32 1.133.048.416.074.838.079 1.265v.133c0 .214.002.404.008.57a2.527 2.527 0 00.226.977c.073.161.182.336.328.523.25.329.506.66.766.993.26.333.497.677.71 1.03.214.355.389.725.524 1.11.136.386.206.802.211 1.25a3.3 3.3 0 01-.164 1.04zm-6.554-8.14c.072 0 .132.018.18.054a.357.357 0 01.109.149.85.85 0 01.054.187c.01.063.016.128.016.196a.282.282 0 01-.024.125.27.27 0 01-.07.086l-.094.078a.796.796 0 00-.093.093.428.428 0 01-.149.141 2.129 2.129 0 00-.18.117 1.31 1.31 0 00-.156.133.264.264 0 00-.07.195c0 .047.023.086.07.117a.704.704 0 01.266.305c.052.12.11.237.172.352.062.114.143.21.242.289.099.078.253.117.46.117h.048c.208-.01.406-.065.594-.164.187-.099.375-.203.562-.313a.633.633 0 01.102-.046.37.37 0 00.101-.055l.57-.445a.926.926 0 00.024-.102 2.75 2.75 0 00.016-.11.236.236 0 00-.04-.14.4.4 0 00-.093-.094.34.34 0 00-.133-.054.909.909 0 01-.14-.04 1.083 1.083 0 01-.352-.14 1.457 1.457 0 00-.344-.156c-.02-.006-.036-.021-.047-.047a.983.983 0 01-.031-.094.23.23 0 01-.008-.102.126.126 0 00-.008-.078c0-.062.005-.127.016-.195a.551.551 0 01.07-.195.417.417 0 01.125-.14.411.411 0 01.203-.056c.162 0 .279.06.352.18.073.12.112.25.117.39a.397.397 0 01-.039.18.379.379 0 00-.04.172c0 .042.014.07.04.086a.26.26 0 00.102.031c.12 0 .197-.028.234-.085a.533.533 0 00.062-.258c0-.12-.01-.253-.03-.399a1.32 1.32 0 00-.126-.406.969.969 0 00-.242-.313.574.574 0 00-.383-.124c-.27 0-.466.067-.586.203-.12.135-.182.338-.187.609 0 .078.005.156.015.234.01.079.016.157.016.235 0 .026-.003.039-.008.039a.218.218 0 01-.047-.016 4.263 4.263 0 01-.093-.039.774.774 0 00-.118-.039.514.514 0 00-.203-.008 1.007 1.007 0 01-.125.008c-.073 0-.11-.013-.11-.039 0-.078-.004-.177-.015-.297-.01-.12-.036-.24-.078-.36a.995.995 0 00-.156-.296c-.063-.078-.156-.12-.281-.125a.323.323 0 00-.227.086.905.905 0 00-.164.203.64.64 0 00-.086.266 5.4 5.4 0 01-.031.25 1.459 1.459 0 00.07.406c.026.083.055.156.086.219.031.062.068.093.11.093.025 0 .06-.018.101-.054.042-.037.063-.07.063-.102 0-.016-.008-.026-.024-.031a.147.147 0 00-.047-.008c-.036 0-.068-.018-.094-.055a.468.468 0 01-.062-.125 5.144 5.144 0 01-.047-.148.564.564 0 01.055-.398c.047-.084.133-.128.258-.133zM5.023 15.18c.125 0 .248-.01.368-.032a.97.97 0 00.336-.125.614.614 0 00.234-.242.943.943 0 00.094-.375.816.816 0 00-.047-.273.963.963 0 00-.133-.25 2.763 2.763 0 00-.203-.281 2.763 2.763 0 01-.203-.282 62.93 62.93 0 01-.29-.43c-.093-.14-.187-.288-.28-.445a8.124 8.124 0 01-.235-.406 2.646 2.646 0 00-.266-.398 1.203 1.203 0 00-.218-.211.469.469 0 00-.29-.094.436.436 0 00-.296.11 2.26 2.26 0 00-.258.265 3.241 3.241 0 01-.297.305c-.11.099-.25.177-.422.234a.744.744 0 00-.312.172c-.073.073-.11.185-.11.336 0 .104.008.208.024.312.015.104.026.209.031.313 0 .14-.02.273-.063.398a1.157 1.157 0 00-.062.367c0 .141.05.24.148.297.1.058.211.097.336.117.157.027.305.047.446.063.14.016.278.04.414.07.135.032.27.065.406.102.135.036.279.094.43.172.03.015.078.034.14.054l.211.07c.078.027.151.048.219.063a.741.741 0 00.148.024zm2.86-.938c.146 0 .302-.015.469-.047a3.54 3.54 0 00.976-.336 2.59 2.59 0 00.406-.257.222.222 0 00.032-.047.305.305 0 00.023-.063v-.008c.031-.114.057-.24.078-.375a8.63 8.63 0 00.055-.414 8.98 8.98 0 01.055-.414c.02-.135.039-.268.054-.398.021-.14.047-.276.078-.406.032-.13.073-.253.125-.368a1.03 1.03 0 01.211-.304 1.54 1.54 0 01.344-.25v-.016l-.008-.023a.29.29 0 01.047-.149 1.4 1.4 0 01.117-.164.582.582 0 01.149-.133.946.946 0 01.164-.078 9.837 9.837 0 00-.102-.375 4.938 4.938 0 01-.094-.375 7.126 7.126 0 00-.093-.476 2.954 2.954 0 00-.11-.36 1.317 1.317 0 00-.18-.32c-.077-.104-.174-.23-.288-.375a1.189 1.189 0 01-.118-.156.555.555 0 01-.046-.196 2.206 2.206 0 00-.047-.203 9.48 9.48 0 00-.242-.75 2.91 2.91 0 00-.172-.383 3.87 3.87 0 00-.172-.289c-.052-.078-.107-.117-.164-.117-.125 0-.274.05-.446.149-.171.099-.354.208-.546.328-.193.12-.38.232-.563.336-.182.104-.346.153-.492.148a.7.7 0 01-.43-.148 2.236 2.236 0 01-.36-.344c-.109-.13-.2-.242-.273-.336-.073-.094-.127-.146-.164-.156-.041 0-.065.031-.07.093a2.56 2.56 0 00-.008.211v.133c0 .032-.005.052-.016.063-.057.12-.12.237-.187.351-.068.115-.135.232-.203.352a1.611 1.611 0 00-.219.758c0 .078.005.156.016.234.01.078.036.154.078.227l-.016.03a1.31 1.31 0 01-.133.157 1.072 1.072 0 00-.132.164 2.796 2.796 0 00-.407.93c-.078.333-.12.672-.125 1.015 0 .089.006.178.016.266.01.089.016.177.016.266a.526.526 0 01-.008.086.525.525 0 00-.008.086.75.75 0 01.313.109c.12.068.25.154.39.258.14.104.274.224.399.36.125.135.244.267.359.398.115.13.198.26.25.39.052.13.086.237.101.32a.444.444 0 01-.125.329.955.955 0 01-.312.203c.089.156.198.289.328.398.13.11.271.198.422.266.151.068.315.117.492.148.177.032.35.047.516.047zm3.133 1.11c.109 0 .216-.016.32-.047a1.65 1.65 0 00.445-.203c.136-.089.26-.198.375-.329a3.07 3.07 0 01.977-.75l.258-.117a2.18 2.18 0 00.257-.133.962.962 0 00.165-.132.256.256 0 00.078-.188.295.295 0 00-.024-.117.58.58 0 00-.07-.117 5.136 5.136 0 01-.203-.305 1.978 1.978 0 01-.149-.297l-.125-.312a2.558 2.558 0 01-.11-.352.28.28 0 00-.054-.101.53.53 0 00-.46-.235.533.533 0 00-.266.07l-.266.149a7.335 7.335 0 01-.281.148.656.656 0 01-.297.07.411.411 0 01-.258-.077.636.636 0 01-.172-.211 2.218 2.218 0 01-.117-.258l-.094-.258a1.26 1.26 0 01-.14.188.666.666 0 00-.125.203c-.068.156-.11.33-.125.523-.026.302-.06.596-.102.883a4.7 4.7 0 01-.21.86 1.914 1.914 0 00-.063.273 2.88 2.88 0 00-.032.289c0 .255.079.466.235.633.156.166.367.25.633.25z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="terminal-powershell" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 1.007l12.999.17.43.501-1.82 12.872-.57.489-13-.17-.43-.502L1.93 1.495l.57-.488zM1.18 13.885l11.998.157 1.68-11.882L2.86 2.003 1.18 13.885zm5.791-3.49l-.14.991 5 .066.14-.99-5-.066zm1.71-2.457l-3.663-2.93-.692.796 2.636 2.112L3.739 9.95l.465.812L8.68 7.938z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="terminal-tmux" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 1h-12l-.5.5v13l.5.5h12l.5-.5v-13l-.5-.5zM7 7.5V13H2V2h5v5.5zm6 5.5H8V8h5v5zm0-6H8V2h5v5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="terminal-ubuntu" xmlns="http://www.w3.org/2000/svg"><path d="M3.26 8A1.37 1.37 0 11.52 8a1.37 1.37 0 012.74 0zm7.79 6.66a1.37 1.37 0 102.374-1.37 1.37 1.37 0 00-2.374 1.37zm2.37-11.95a1.37 1.37 0 10-2.37-1.373 1.37 1.37 0 002.37 1.373zM8.79 4.1a3.9 3.9 0 013.89 3.55h2a5.93 5.93 0 00-1.73-3.8 1.91 1.91 0 01-1.66-.12 2.001 2.001 0 01-.94-1.38 6 6 0 00-1.54-.2 5.83 5.83 0 00-2.61.61l1 1.73a3.94 3.94 0 011.59-.39zM4.88 8a3.93 3.93 0 011.66-3.2l-1-1.7A5.93 5.93 0 003.1 6.5a1.92 1.92 0 010 3 5.93 5.93 0 002.42 3.4l1-1.7A3.93 3.93 0 014.88 8zm3.91 3.91a4 4 0 01-1.65-.37l-1 1.73c.81.403 1.704.612 2.61.61.52 0 1.038-.067 1.54-.2a2 2 0 01.94-1.38 1.911 1.911 0 011.66-.12 5.93 5.93 0 001.73-3.8h-2a3.91 3.91 0 01-3.83 3.53z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="text-size" xmlns="http://www.w3.org/2000/svg"><path d="M3.36 7L1 13h1.34l.51-1.47h2.26L5.64 13H7L4.65 7H3.36zm-.15 3.53l.78-2.14.78 2.14H3.21zM11.82 4h-1.6L7 13h1.56l.75-2.29h3.36l.77 2.29H15l-3.18-9zM9.67 9.5l1.18-3.59c.059-.185.1-.376.12-.57.027.192.064.382.11.57l1.25 3.59H9.67z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="three-bars" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 5H2V3h12v2zm0 4H2V7h12v2zM2 13h12v-2H2v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="thumbsdown" xmlns="http://www.w3.org/2000/svg"><path d="M5.46 14.11a1.46 1.46 0 01-.81-.25 1.38 1.38 0 01-.45-1.69L5.17 10H2.38a1.36 1.36 0 01-1.16-.61 1.35 1.35 0 01-.09-1.32C1.8 6.62 3 4 3.4 2.9A1.38 1.38 0 014.69 2h8.93A1.4 1.4 0 0115 3.4v3.51a1.38 1.38 0 01-1.38 1.38h-1.38L6.4 13.75a1.41 1.41 0 01-.94.36zM4.69 3a.39.39 0 00-.36.25C3.93 4.34 2.86 6.7 2 8.49a.39.39 0 000 .36.37.37 0 00.38.15h3.3l.52.68v.46l-1.09 2.44a.37.37 0 00.13.46.38.38 0 00.48 0l6.06-5.59.47-.13h1.37a.38.38 0 00.38-.41V3.4a.4.4 0 00-.38-.4H4.69z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="thumbsup" xmlns="http://www.w3.org/2000/svg"><path d="M10.54 2c.289.001.57.088.81.25a1.38 1.38 0 01.45 1.69l-.97 2.17h2.79a1.36 1.36 0 011.16.61 1.35 1.35 0 01.09 1.32c-.67 1.45-1.87 4.07-2.27 5.17a1.38 1.38 0 01-1.29.9H2.38A1.4 1.4 0 011 12.71V9.2a1.38 1.38 0 011.38-1.38h1.38L9.6 2.36a1.41 1.41 0 01.94-.36zm.77 11.11a.39.39 0 00.36-.25c.4-1.09 1.47-3.45 2.33-5.24a.39.39 0 000-.36.37.37 0 00-.38-.15h-3.3l-.52-.68v-.46l1.09-2.44a.37.37 0 00-.13-.46.38.38 0 00-.48 0L4.22 8.66l-.47.13H2.38A.38.38 0 002 9.2v3.51a.4.4 0 00.38.4h8.93z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="tools" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.773 3.485l-.78-.184-2.108 2.096-1.194-1.216 2.056-2.157-.18-.792a4.42 4.42 0 00-1.347-.228 3.64 3.64 0 00-1.457.28 3.824 3.824 0 00-1.186.84 3.736 3.736 0 00-.875 1.265 3.938 3.938 0 000 2.966 335.341 335.341 0 00-6.173 6.234c-.21.275-.31.618-.284.963a1.403 1.403 0 00.464.967c.124.135.272.247.437.328.17.075.353.118.538.127.316-.006.619-.126.854-.337 1.548-1.457 4.514-4.45 6.199-6.204.457.194.948.294 1.444.293a3.736 3.736 0 002.677-1.133 3.885 3.885 0 001.111-2.73 4.211 4.211 0 00-.196-1.378zM2.933 13.928a.31.31 0 01-.135.07.437.437 0 01-.149 0 .346.346 0 01-.144-.057.336.336 0 01-.114-.11c-.14-.143-.271-.415-.14-.568 1.37-1.457 4.191-4.305 5.955-6.046.1.132.21.258.328.376.118.123.245.237.38.341-1.706 1.75-4.488 4.564-5.98 5.994zm11.118-9.065c.002.765-.296 1.5-.832 2.048a2.861 2.861 0 01-4.007 0 2.992 2.992 0 01-.635-3.137A2.748 2.748 0 0110.14 2.18a2.76 2.76 0 011.072-.214h.254L9.649 3.839v.696l1.895 1.886h.66l1.847-1.816v.258zM3.24 6.688h1.531l.705.717.678-.674-.665-.678V6.01l.057-1.649-.22-.437-2.86-1.882-.591.066-.831.849-.066.599 1.838 2.918.424.215zm-.945-3.632L4.609 4.58 4.57 5.703H3.494L2.002 3.341l.293-.285zm7.105 6.96l.674-.673 3.106 3.185a1.479 1.479 0 010 2.039 1.404 1.404 0 01-1.549.315 1.31 1.31 0 01-.437-.315l-3.142-3.203.679-.678 3.132 3.194a.402.402 0 00.153.105.477.477 0 00.359 0 .403.403 0 00.153-.105.436.436 0 00.1-.153.525.525 0 00.036-.184.547.547 0 00-.035-.184.436.436 0 00-.1-.153L9.4 10.016z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="trash" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10 3h3v1h-1v9l-1 1H4l-1-1V4H2V3h3V2a1 1 0 011-1h3a1 1 0 011 1v1zM9 2H6v1h3V2zM4 13h7V4H4v9zm2-8H5v7h1V5zm1 0h1v7H7V5zm2 0h1v7H9V5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="trashcan" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10 3h3v1h-1v9l-1 1H4l-1-1V4H2V3h3V2a1 1 0 011-1h3a1 1 0 011 1v1zM9 2H6v1h3V2zM4 13h7V4H4v9zm2-8H5v7h1V5zm1 0h1v7H7V5zm2 0h1v7H9V5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="triangle-down" xmlns="http://www.w3.org/2000/svg"><path d="M2 5.56L2.413 5h11.194l.393.54L8.373 11h-.827L2 5.56z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="triangle-left" xmlns="http://www.w3.org/2000/svg"><path d="M10.44 2l.56.413v11.194l-.54.393L5 8.373v-.827L10.44 2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="triangle-right" xmlns="http://www.w3.org/2000/svg"><path d="M5.56 14L5 13.587V2.393L5.54 2 11 7.627v.827L5.56 14z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="triangle-up" xmlns="http://www.w3.org/2000/svg"><path d="M14 10.44l-.413.56H2.393L2 10.46 7.627 5h.827L14 10.44z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="twitter" xmlns="http://www.w3.org/2000/svg"><path d="M15 3.784a5.63 5.63 0 01-.65.803 6.058 6.058 0 01-.786.68 5.442 5.442 0 01.014.377c0 .574-.061 1.141-.184 1.702a8.467 8.467 0 01-.534 1.627 8.444 8.444 0 01-1.264 2.04 7.768 7.768 0 01-1.72 1.521 7.835 7.835 0 01-2.095.95 8.524 8.524 0 01-2.379.329 8.178 8.178 0 01-2.293-.325A7.921 7.921 0 011 12.52a5.762 5.762 0 004.252-1.19 2.842 2.842 0 01-2.273-1.19 2.878 2.878 0 01-.407-.8c.091.014.181.026.27.035a2.797 2.797 0 001.022-.089 2.808 2.808 0 01-.926-.362 2.942 2.942 0 01-.728-.633 2.839 2.839 0 01-.65-1.822v-.033c.402.227.837.348 1.306.362a2.943 2.943 0 01-.936-1.04 2.955 2.955 0 01-.253-.649 2.945 2.945 0 01.007-1.453c.063-.243.161-.474.294-.693.364.451.77.856 1.216 1.213a8.215 8.215 0 003.008 1.525 7.965 7.965 0 001.695.263 2.15 2.15 0 01-.058-.325 3.265 3.265 0 01-.017-.331c0-.397.075-.77.226-1.118a2.892 2.892 0 011.528-1.528 2.79 2.79 0 011.117-.225 2.846 2.846 0 012.099.909 5.7 5.7 0 001.818-.698 2.815 2.815 0 01-1.258 1.586A5.704 5.704 0 0015 3.785z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="type-hierarchy" xmlns="http://www.w3.org/2000/svg"><path d="M13.5 12h-1.793L10 10.293V6.5L9.5 6H8V4h.5l.5-.5v-2L8.5 1h-2l-.5.5v2l.5.5H7v2H5.5l-.5.5v3.793L3.293 12H1.5l-.5.5v2l.5.5h2l.5-.5v-1.793L5.707 11h3.586L11 12.707V14.5l.5.5h2l.5-.5v-2l-.5-.5zM7 2h1v1H7V2zM6 7h3v3H6V7zm-3 7H2v-1h1v1zm10 0h-1v-1h1v1z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="type-hierarchy-sub" xmlns="http://www.w3.org/2000/svg"><path d="M13.5 11h-1.729L8.438 6H9.5l.5-.5v-4L9.5 1h-4l-.5.5v4l.5.5h1.062l-3.333 5H1.5l-.5.5v3l.5.5h3l.5-.5v-3l-.5-.5h-.068L7.5 6.4l3.068 4.6H10.5l-.5.5v3l.5.5h3l.5-.5v-3l-.5-.5zM6 5V2h3v3H6zm-2 7v2H2v-2h2zm9 2h-2v-2h2v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="type-hierarchy-super" xmlns="http://www.w3.org/2000/svg"><path d="M13.5 1h-3l-.5.5v3l.5.5h.068L7.5 9.6 4.432 5H4.5l.5-.5v-3L4.5 1h-3l-.5.5v3l.5.5h1.729l3.333 5H5.5l-.5.5v4l.5.5h4l.5-.5v-4l-.5-.5H8.438l3.333-5H13.5l.5-.5v-3l-.5-.5zM2 4V2h2v2H2zm7 7v3H6v-3h3zm4-7h-2V2h2v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="unfold" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.53 6.51v-4l-1 1-.71-.71L7.65 1h.71l1.84 1.83-.71.7-1-1v3.98h-.96zm0 2.98v4l-1-1-.71.71L7.65 15h.71l1.84-1.83-.71-.7-1 1V9.49h-.96zM13.73 4L14 5.02l-3.68 2.93L14 10.98 13.73 12h-4.2v-1h3L9.55 8.57H6.54L3.45 11h3.08v1H2.27L2 10.98l3.68-2.92L2 5.02 2.27 4h4.26v1H3.45l3 2.42h3.01L12.53 5h-3V4h4.2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="ungroup-by-ref-type" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.9 1L5 3.1l-.8.7L3 2.6V7H2V2.5L.8 3.8l-.7-.7L2.2 1h.7zM3 13.4V9H2v4.4L.8 12.2l-.7.7L2.2 15h.7L5 12.9l-.7-.7L3 13.4zM8.5 7h-2L6 6.5v-2l.5-.5h2l.5.5v2l-.5.5zM7 6h1V5H7v1zm7.5 1h-3l-.5-.5v-3l.5-.5h3l.5.5v3l-.5.5zM12 6h2V4h-2v2zm-3.5 6h-2l-.5-.5v-2l.5-.5h2l.5.5v2l-.5.5zM7 11h1v-1H7v1zm7.5 2h-3l-.5-.5v-3l.5-.5h3l.5.5v3l-.5.5zM12 12h2v-2h-2v2zm-1-2H9v1h2v-1zm0-5H9v1h2V5z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="unlock" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 7V5a3 3 0 015.83-1h1.044A4.002 4.002 0 004 5v2H3L2 8v6l1 1h10l1-1V8l-1-1H5zm6 1h2v6H3V8h8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="unmute" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 4.83h2.79L8.15 1l.85.35v13l-.85.33-3.86-3.85H1.5l-.5-.5v-5l.5-.5zM4.85 10L8 13.14V2.56L4.85 5.68l-.35.15H2v4h2.5l.35.17zM15 7.83a6.97 6.97 0 01-1.578 4.428l-.712-.71A5.975 5.975 0 0014 7.83c0-1.4-.48-2.689-1.284-3.71l.712-.71A6.971 6.971 0 0115 7.83zm-2 0a4.978 4.978 0 01-1.002 3.004l-.716-.716A3.982 3.982 0 0012 7.83a3.98 3.98 0 00-.713-2.28l.716-.716c.626.835.997 1.872.997 2.996zm-2 0c0 .574-.16 1.11-.44 1.566l-.739-.738a1.993 1.993 0 00.005-1.647l.739-.739c.276.454.435.988.435 1.558z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="unverified" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.67 14.72h.71L10.1 13h2.4l.5-.5v-2.42l1.74-1.72v-.71l-1.71-1.72V3.49l-.5-.49H10.1L8.38 1.29h-.71L6 3H3.53L3 3.5v2.43L1.31 7.65v.71L3 10.08v2.42l.53.5H6l1.67 1.72zM6.16 12H4V9.87l-.12-.35L2.37 8l1.48-1.51.15-.35V4h2.16l.36-.14L8 2.35l1.54 1.51.35.14H12v2.14l.17.35L13.69 8l-1.55 1.52-.14.35V12H9.89l-.38.15L8 13.66l-1.48-1.52-.36-.14zm1.443-5.859a.962.962 0 00-.128.291c-.03.109-.05.215-.062.317l-.005.043h-.895l.003-.051c.018-.326.089-.615.212-.864.052-.108.117-.214.193-.318.081-.106.18-.2.294-.28.119-.084.255-.15.409-.2A1.71 1.71 0 018.165 5c.28 0 .523.046.726.14.2.089.366.21.494.363.127.152.22.326.279.52.058.194.087.394.087.599 0 .191-.032.371-.098.54-.064.164-.143.32-.238.466-.094.143-.197.28-.31.41-.11.129-.211.252-.304.372a2.47 2.47 0 00-.23.34.653.653 0 00-.088.318v.48h-.888v-.539c0-.168.031-.323.094-.464a2.15 2.15 0 01.24-.401c.096-.127.2-.25.308-.368a4.74 4.74 0 00.299-.356c.093-.12.17-.246.228-.377a.984.984 0 00.09-.421 1.04 1.04 0 00-.047-.318v-.001a.638.638 0 00-.13-.243.558.558 0 00-.216-.158H8.46a.689.689 0 00-.294-.059.643.643 0 00-.339.083.742.742 0 00-.223.215zM8.5 11h-.888v-.888H8.5V11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="variable" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 5h2V4H1.5l-.5.5v8l.5.5H4v-1H2V5zm12.5-1H12v1h2v7h-2v1h2.5l.5-.5v-8l-.5-.5zm-2.74 2.57L12 7v2.51l-.3.45-4.5 2h-.46l-2.5-1.5-.24-.43v-2.5l.3-.46 4.5-2h.46l2.5 1.5zM5 9.71l1.5.9V9.28L5 8.38v1.33zm.58-2.15l1.45.87 3.39-1.5-1.45-.87-3.39 1.5zm1.95 3.17l3.5-1.56v-1.4l-3.5 1.55v1.41z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="variable-group" xmlns="http://www.w3.org/2000/svg"><path d="M5.387 11.523a.402.402 0 01.593-.367c.058.031.11.065.157.102.047.036.088.07.125.101a.177.177 0 00.117.047c.052 0 .12-.04.203-.117.083-.078.175-.182.273-.313.1-.13.201-.268.305-.414.104-.146.2-.294.29-.445l.226-.39c.062-.11.107-.199.133-.266a15.33 15.33 0 00-.133-.524 15.384 15.384 0 01-.133-.523 3.72 3.72 0 00-.133-.422 1.04 1.04 0 00-.187-.313.656.656 0 00-.266-.187 1.374 1.374 0 00-.375-.07 1.628 1.628 0 00-.328.031v-.195L7.69 7a2.345 2.345 0 01.461.734c.052.13.097.263.133.399.037.135.076.283.117.445.078-.115.175-.26.29-.438a4.49 4.49 0 01.398-.523c.15-.172.31-.315.476-.43A1.02 1.02 0 0110.089 7c.13 0 .247.034.351.101.105.068.157.175.157.32 0 .282-.141.423-.422.423a.608.608 0 01-.29-.07.608.608 0 00-.288-.071c-.1 0-.203.05-.313.148a2.3 2.3 0 00-.312.352 9.5 9.5 0 00-.485.734l.446 1.852a1.56 1.56 0 00.093.344.669.669 0 00.094.171.184.184 0 00.125.079.37.37 0 00.211-.086 2.14 2.14 0 00.43-.47c.052-.077.093-.15.125-.218l.187.094a2.025 2.025 0 01-.219.367 3.775 3.775 0 01-.351.422 3.38 3.38 0 01-.406.36c-.141.104-.269.153-.383.148a.397.397 0 01-.281-.102 1.491 1.491 0 01-.204-.234 1.599 1.599 0 01-.132-.36 8.263 8.263 0 01-.118-.507 34.16 34.16 0 01-.101-.532 2.212 2.212 0 00-.11-.414l-.203.375a4.489 4.489 0 01-.28.453c-.11.157-.222.316-.337.477a2.46 2.46 0 01-.375.422c-.135.12-.265.221-.39.305A.66.66 0 015.91 12a.539.539 0 01-.36-.133.454.454 0 01-.163-.344zm6.11.477c.28-.36.496-.748.648-1.164a3.87 3.87 0 00.226-1.32c0-.47-.075-.912-.226-1.329A4.57 4.57 0 0011.495 7h.734a3.77 3.77 0 01.922 2.515c0 .474-.073.917-.218 1.329-.146.411-.38.796-.704 1.156h-.734zM3.77 12a3.373 3.373 0 01-.704-1.149 3.97 3.97 0 01-.218-1.336c0-.953.307-1.791.922-2.515h.726a4.132 4.132 0 00-.64 1.18 4.205 4.205 0 00-.227 1.335A3.929 3.929 0 004.496 12H3.77z"/><path d="M15.5 1H.5l-.5.5v13l.5.5h15l.5-.5v-13l-.5-.5zM15 14H1V5h14v9zm0-10H1V2h14v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="verified" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.67 14.72h.71L10.1 13h2.4l.5-.5v-2.42l1.74-1.72v-.71l-1.71-1.72V3.49l-.5-.49H10.1L8.38 1.29h-.71L6 3H3.53L3 3.5v2.43L1.31 7.65v.71L3 10.08v2.42l.53.5H6l1.67 1.72zM6.16 12H4V9.87l-.12-.35L2.37 8l1.48-1.51.15-.35V4h2.16l.36-.14L8 2.35l1.54 1.51.35.14H12v2.14l.17.35L13.69 8l-1.55 1.52-.14.35V12H9.89l-.38.15L8 13.66l-1.48-1.52-.36-.14zm.57-1.52h.71l3.77-3.77L10.5 6 7.09 9.42 5.71 8.04 5 8.75l1.73 1.73z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="verified-filled" xmlns="http://www.w3.org/2000/svg"><path d="M8.38 14.72h-.71L6 13H3.53L3 12.5v-2.42L1.31 8.36v-.71L3 5.93V3.5l.53-.5H6l1.67-1.71h.71L10.1 3h2.43l.5.49v2.44l1.71 1.72v.71L13 10.08v2.42l-.5.5h-2.4l-1.72 1.72zm-1.65-4.24h.71l3.77-3.77L10.5 6 7.09 9.42 5.71 8.04 5 8.75l1.73 1.73z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="versions" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3L7 4v8l1 1h6l1-1V4l-1-1H8zm6 9H8V4h6v8zM5 9V5h1V4H4.5l-.5.5v7l.5.5H6v-1H5V9zM2 8V6h1V5H1.5l-.5.5v5l.5.5H3v-1H2V8z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="vm" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5 2h-13l-.5.5v10l.5.5H7v1H4v1h8v-1H9v-1h5.5l.5-.5v-10l-.5-.5zM14 12H2V3h12v9z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="vm-active" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2h13l.5.5v5.503a5.006 5.006 0 00-1-.583V3H2v9h5a5 5 0 001 3H4v-1h3v-1H1.5l-.5-.5v-10l.5-.5z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9.778 8.674a4 4 0 114.444 6.652 4 4 0 01-4.444-6.652zm2.13 4.99l2.387-3.182-.8-.6-2.077 2.769-1.301-1.041-.625.78 1.704 1.364.713-.09z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="vm-connect" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2h13l.5.5v5.503a5.006 5.006 0 00-1-.583V3H2v9h5a5 5 0 001 3H4v-1h3v-1H1.5l-.5-.5v-10l.5-.5z"/><path d="M12 8a4 4 0 100 8 4 4 0 000-8zm0 7a3 3 0 110-6.001A3 3 0 0112 15z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M12.133 11.435l1.436 1.436.431-.431-1.004-1.005L14 10.431l-.431-.43-1.436 1.434zm-1.129 1.067L10 11.498l.431-.431 1.436 1.435-1.436 1.436-.431-.431 1.004-1.005z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="vm-outline" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2h13l.5.5v5.503a5.006 5.006 0 00-1-.583V3H2v9h5a5 5 0 001 3H4v-1h3v-1H1.5l-.5-.5v-10l.5-.5z"/><path d="M12 8a4 4 0 100 8 4 4 0 000-8zm0 7a3 3 0 110-6.001A3 3 0 0112 15z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="vm-running" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2h13l.5.5v5.503a5.006 5.006 0 00-1-.583V3H2v9h5a5 5 0 001 3H4v-1h3v-1H1.5l-.5-.5v-10l.5-.5z"/><path d="M12 8c.367 0 .721.047 1.063.14.34.094.658.23.953.407.294.177.563.385.808.625.245.24.455.509.63.808a4.03 4.03 0 01.405 3.082c-.093.342-.229.66-.406.954a4.382 4.382 0 01-.625.808c-.24.245-.509.455-.808.63a4.029 4.029 0 01-3.082.405 3.784 3.784 0 01-.954-.406 4.382 4.382 0 01-.808-.625 3.808 3.808 0 01-.63-.808 4.027 4.027 0 01-.405-3.082c.093-.342.229-.66.406-.954.177-.294.385-.563.625-.808.24-.245.509-.455.808-.63A4.028 4.028 0 0112 8zm2 3.988L11 10v4l3-2.012z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="wand" xmlns="http://www.w3.org/2000/svg"><path d="M4.38 5h1V4h1V3h-1V2h-1v1h-1v1h1v1zm8 4h-1v1h-1v1h1v1h1v-1h1v-1h-1V9zM14 2V1h-1v1h-1v1h1v1h1V3h1V2h-1zm-2.947 2.442a1.49 1.49 0 00-2.12 0l-7.49 7.49a1.49 1.49 0 000 2.12c.59.59 1.54.59 2.12 0l7.49-7.49c.58-.58.58-1.53 0-2.12zm-8.2 8.9c-.2.2-.51.2-.71 0-.2-.2-.2-.51 0-.71l6.46-6.46.71.71-6.46 6.46zm7.49-7.49l-.32.32-.71-.71.32-.32c.2-.2.51-.2.71 0 .19.2.19.52 0 .71z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="warning" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.56 1h.88l6.54 12.26-.44.74H1.44L1 13.26 7.56 1zM8 2.28L2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="watch" xmlns="http://www.w3.org/2000/svg"><path d="M7.5 9h2V8H8V5.5H7v3l.5.5z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 3.669A4.998 4.998 0 003 8a4.998 4.998 0 002.5 4.331V14.5l.5.5h4l.5-.5v-2.169A4.998 4.998 0 0013 8a4.998 4.998 0 00-2.5-4.331V1.5L10 1H6l-.5.5v2.169zM12 8a4 4 0 11-8 0 4 4 0 018 0z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="whitespace" xmlns="http://www.w3.org/2000/svg"><path d="M12 2V1H6.5a3.5 3.5 0 000 7H8v5H7v1h5v-1h-1V2h1zM8 7H6.5a2.5 2.5 0 110-5H8v5zm2 6H9V2h1v11z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="whole-word" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 11h1v2h14v-2h1v3H0v-3z"/><path d="M6.84 11h-.88v-.86h-.022c-.383.66-.947.989-1.692.989-.548 0-.977-.145-1.289-.435-.308-.29-.462-.675-.462-1.155 0-1.028.605-1.626 1.816-1.794l1.649-.23c0-.935-.378-1.403-1.134-1.403-.662 0-1.26.226-1.794.677v-.902c.541-.344 1.164-.516 1.87-.516 1.292 0 1.938.684 1.938 2.052V11zm-.88-2.782L4.633 8.4c-.408.058-.716.16-.924.307-.208.143-.311.399-.311.768 0 .268.095.488.284.66.194.168.45.253.768.253a1.41 1.41 0 001.08-.457c.286-.308.43-.696.43-1.165v-.548zM9.348 10.205h-.022V11h-.88V2.857h.88v3.61h.021c.434-.73 1.068-1.096 1.902-1.096.705 0 1.257.247 1.654.741.401.49.602 1.15.602 1.977 0 .92-.224 1.658-.672 2.213-.447.551-1.06.827-1.837.827-.726 0-1.276-.308-1.649-.924zm-.022-2.218v.768c0 .455.147.841.44 1.16.298.315.674.473 1.128.473.534 0 .951-.204 1.252-.613.304-.408.456-.975.456-1.702 0-.613-.141-1.092-.424-1.44-.283-.347-.666-.52-1.15-.52-.511 0-.923.178-1.235.536-.311.355-.467.8-.467 1.338z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="window" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 2h-13l-.5.5v11l.5.5h13l.5-.5v-11l-.5-.5zM14 13H2V6h12v7zm0-8H2V3h12v2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="word-wrap" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.868 3.449a1.21 1.21 0 00-.473-.329c-.274-.111-.623-.15-1.055-.076a3.5 3.5 0 00-.71.208c-.082.035-.16.077-.235.125l-.043.03v1.056l.168-.139c.15-.124.326-.225.527-.303.196-.074.4-.113.604-.113.188 0 .33.051.431.157.087.095.137.248.147.456l-.962.144c-.219.03-.41.086-.57.166a1.245 1.245 0 00-.398.311c-.103.125-.181.27-.229.426-.097.33-.093.68.011 1.008a1.096 1.096 0 00.638.67c.155.063.328.093.528.093a1.25 1.25 0 00.978-.441v.345h1.007V4.65c0-.255-.03-.484-.089-.681a1.423 1.423 0 00-.275-.52zm-.636 1.896v.236c0 .119-.018.231-.055.341a.745.745 0 01-.377.447.694.694 0 01-.512.027.454.454 0 01-.156-.094.389.389 0 01-.094-.139.474.474 0 01-.035-.186c0-.077.01-.147.024-.212a.33.33 0 01.078-.141.436.436 0 01.161-.109 1.3 1.3 0 01.305-.073l.661-.097zm5.051-1.067a2.253 2.253 0 00-.244-.656 1.354 1.354 0 00-.436-.459 1.165 1.165 0 00-.642-.173 1.136 1.136 0 00-.69.223 1.33 1.33 0 00-.264.266V1H5.09v6.224h.918v-.281c.123.152.287.266.472.328.098.032.208.047.33.047.255 0 .483-.06.677-.177.192-.115.355-.278.486-.486a2.29 2.29 0 00.293-.718 3.87 3.87 0 00.096-.886 3.714 3.714 0 00-.078-.773zm-.86.758c0 .232-.02.439-.06.613-.036.172-.09.315-.159.424a.639.639 0 01-.233.237.582.582 0 01-.565.014.683.683 0 01-.21-.183.925.925 0 01-.142-.283A1.187 1.187 0 016 5.5v-.517c0-.164.02-.314.06-.447.036-.132.087-.242.156-.336a.668.668 0 01.228-.208.584.584 0 01.29-.071.554.554 0 01.496.279c.063.099.108.214.143.354.031.143.05.306.05.482zM2.407 9.9a.913.913 0 01.316-.239c.218-.1.547-.105.766-.018.104.042.204.1.32.184l.33.26V8.945l-.097-.062a1.932 1.932 0 00-.905-.215c-.308 0-.593.057-.846.168-.25.11-.467.27-.647.475-.18.21-.318.453-.403.717-.09.272-.137.57-.137.895 0 .289.043.561.13.808.086.249.211.471.373.652.161.185.361.333.597.441.232.104.493.155.778.155.233 0 .434-.028.613-.084.165-.05.322-.123.466-.217l.078-.061v-.889l-.2.095a.4.4 0 01-.076.026c-.05.017-.099.035-.128.049-.036.023-.227.09-.227.09-.06.024-.14.043-.218.059a.977.977 0 01-.599-.057.827.827 0 01-.306-.225 1.088 1.088 0 01-.205-.376 1.728 1.728 0 01-.076-.529c0-.21.028-.399.083-.56.054-.158.13-.294.22-.4zM14 6h-4V5h4.5l.5.5v6l-.5.5H7.879l2.07 2.071-.706.707-2.89-2.889v-.707l2.89-2.89L9.95 9l-2 2H14V6z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="workspace-trusted" xmlns="http://www.w3.org/2000/svg"><path d="M8.069 0c.262 0 .52.017.76.057a4.1 4.1 0 01.697.154c.228.069.451.155.674.263.217.103.44.229.663.366.377.24.748.434 1.126.589a7.537 7.537 0 002.331.525c.406.029.823.046 1.257.046v4c0 .76-.097 1.48-.291 2.166a8.996 8.996 0 01-.789 1.943 10.312 10.312 0 01-1.188 1.725 15.091 15.091 0 01-1.492 1.532 17.57 17.57 0 01-1.703 1.325c-.594.412-1.194.795-1.794 1.143l-.24.143-.24-.143a27.093 27.093 0 01-1.806-1.143 15.58 15.58 0 01-1.703-1.325 15.082 15.082 0 01-1.491-1.532 10.947 10.947 0 01-1.194-1.725 9.753 9.753 0 01-.789-1.943A7.897 7.897 0 01.571 6V2c.435 0 .852-.017 1.258-.046a8.16 8.16 0 001.188-.171c.383-.086.766-.2 1.143-.354A6.563 6.563 0 005.28.846C5.72.56 6.166.349 6.606.21A4.79 4.79 0 018.069 0zm6.502 2.983a9.566 9.566 0 01-2.234-.377 7.96 7.96 0 01-2.046-.943A4.263 4.263 0 009.23 1.16 3.885 3.885 0 008.074.994a3.99 3.99 0 00-1.165.166 3.946 3.946 0 00-1.058.503A7.926 7.926 0 013.8 2.61c-.709.206-1.451.332-2.229.378v3.017c0 .663.086 1.297.258 1.908a8.58 8.58 0 00.72 1.743 9.604 9.604 0 001.08 1.572c.417.491.862.948 1.342 1.382.48.435.983.835 1.509 1.206.531.372 1.063.709 1.594 1.017a22.397 22.397 0 001.589-1.017 15.389 15.389 0 001.514-1.206c.48-.434.926-.891 1.343-1.382a9.596 9.596 0 001.08-1.572 8.258 8.258 0 00.709-1.743 6.814 6.814 0 00.262-1.908V2.983z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M11.797 4.709l-.44-.378-.406.035-4.36 5.148-1.485-2.12-.4-.068-.463.331-.069.4 1.909 2.726.217.12.457.028.234-.102 4.835-5.715-.029-.405z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="workspace-unknown" xmlns="http://www.w3.org/2000/svg"><path d="M8.067 0c.263 0 .52.017.76.057a4.1 4.1 0 01.697.154c.229.069.452.155.675.263.217.103.44.229.662.366a7.2 7.2 0 001.126.589 7.534 7.534 0 002.332.525c.405.029.822.046 1.257.046v4c0 .76-.097 1.48-.292 2.166a8.996 8.996 0 01-.788 1.943 10.306 10.306 0 01-1.189 1.725 15.082 15.082 0 01-1.491 1.532 17.57 17.57 0 01-1.703 1.325c-.594.412-1.194.795-1.794 1.143l-.24.143-.24-.143a27.088 27.088 0 01-1.806-1.143 15.579 15.579 0 01-1.703-1.325 15.08 15.08 0 01-1.491-1.532 10.948 10.948 0 01-1.195-1.725 9.753 9.753 0 01-.788-1.943A7.897 7.897 0 01.57 6V2c.434 0 .851-.017 1.257-.046a8.16 8.16 0 001.189-.171c.383-.086.765-.2 1.143-.354a6.563 6.563 0 001.12-.583C5.719.56 6.164.349 6.604.21A4.79 4.79 0 018.067 0zm6.503 2.983a9.567 9.567 0 01-2.234-.377 7.96 7.96 0 01-2.046-.943 4.264 4.264 0 00-1.063-.503A3.885 3.885 0 008.073.994a3.99 3.99 0 00-1.166.166 3.946 3.946 0 00-1.057.503 7.927 7.927 0 01-2.051.948c-.709.206-1.452.332-2.229.378v3.017c0 .663.086 1.297.257 1.908a8.58 8.58 0 00.72 1.743 9.604 9.604 0 001.08 1.572c.417.491.863.948 1.343 1.382.48.435.983.835 1.509 1.206.531.372 1.062.709 1.594 1.017a22.4 22.4 0 001.588-1.017 15.384 15.384 0 001.515-1.206c.48-.434.925-.891 1.343-1.382a9.609 9.609 0 001.08-1.572 8.269 8.269 0 00.708-1.743 6.814 6.814 0 00.263-1.908V2.983z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9.433 4.72c.171.171.314.377.411.606.103.228.155.48.149.754a1.6 1.6 0 01-.114.64 2.24 2.24 0 01-.292.48 2.787 2.787 0 01-.354.383 4.52 4.52 0 00-.337.32 1.421 1.421 0 00-.24.32.7.7 0 00-.086.348v.36l-.131.138h-.715l-.143-.143V8.57c0-.24.04-.45.12-.634.075-.177.166-.343.28-.486a3.42 3.42 0 01.366-.382c.12-.109.229-.212.332-.32.097-.103.182-.212.245-.326a.707.707 0 00.086-.354.966.966 0 00-.074-.36.972.972 0 00-.2-.298.94.94 0 00-1.32 0 .88.88 0 00-.2.298.829.829 0 00-.075.36L7 6.21h-.715l-.131-.137c0-.263.046-.514.148-.748.103-.229.24-.435.412-.606.177-.177.383-.32.611-.417a1.883 1.883 0 011.503 0c.229.103.434.24.606.417zM7.57 9.646l.143-.143h.714l.143.143v.714l-.143.143h-.714l-.143-.143v-.714z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="workspace-untrusted" xmlns="http://www.w3.org/2000/svg"><path d="M8.067 0c.263 0 .52.017.76.057a4.1 4.1 0 01.697.154c.229.069.452.155.675.263.217.103.44.229.662.366a7.2 7.2 0 001.126.589 7.534 7.534 0 002.332.525c.405.029.822.046 1.257.046v4c0 .76-.097 1.48-.292 2.166a8.996 8.996 0 01-.788 1.943 10.306 10.306 0 01-1.189 1.725 15.082 15.082 0 01-1.491 1.532 17.57 17.57 0 01-1.703 1.325c-.594.412-1.194.795-1.794 1.143l-.24.143-.24-.143a27.088 27.088 0 01-1.806-1.143 15.579 15.579 0 01-1.703-1.325 15.08 15.08 0 01-1.491-1.532 10.948 10.948 0 01-1.195-1.725 9.753 9.753 0 01-.788-1.943A7.897 7.897 0 01.57 6V2c.434 0 .851-.017 1.257-.046a8.16 8.16 0 001.189-.171c.383-.086.765-.2 1.143-.354a6.563 6.563 0 001.12-.583C5.719.56 6.164.349 6.604.21A4.79 4.79 0 018.067 0zm6.503 2.983a9.567 9.567 0 01-2.234-.377 7.96 7.96 0 01-2.046-.943 4.264 4.264 0 00-1.063-.503A3.885 3.885 0 008.073.994a3.99 3.99 0 00-1.166.166 3.946 3.946 0 00-1.057.503 7.927 7.927 0 01-2.051.948c-.709.206-1.452.332-2.229.378v3.017c0 .663.086 1.297.257 1.908a8.58 8.58 0 00.72 1.743 9.604 9.604 0 001.08 1.572c.417.491.863.948 1.343 1.382.48.435.983.835 1.509 1.206.531.372 1.062.709 1.594 1.017a22.4 22.4 0 001.588-1.017 15.384 15.384 0 001.515-1.206c.48-.434.925-.891 1.343-1.382a9.609 9.609 0 001.08-1.572 8.269 8.269 0 00.708-1.743 6.814 6.814 0 00.263-1.908V2.983z"/><path d="M10.787 5.446l-.4-.406h-.206L8.2 7.023 6.216 5.04h-.2l-.406.406v.2l1.983 1.983L5.61 9.61v.206l.406.4h.2l1.983-1.983 1.982 1.983h.206l.4-.4V9.61L8.804 7.63l1.983-1.983v-.2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="wrench" xmlns="http://www.w3.org/2000/svg"><path d="M2.807 14.975a1.75 1.75 0 01-1.255-.556 1.684 1.684 0 01-.544-1.1A1.72 1.72 0 011.36 12.1c1.208-1.27 3.587-3.65 5.318-5.345a4.257 4.257 0 01.048-3.078 4.095 4.095 0 011.665-1.969 4.259 4.259 0 014.04-.36l.617.268-2.866 2.951 1.255 1.259 2.944-2.877.267.619a4.295 4.295 0 01.04 3.311 4.198 4.198 0 01-.923 1.392 4.27 4.27 0 01-.743.581 4.217 4.217 0 01-3.812.446c-1.098 1.112-3.84 3.872-5.32 5.254a1.63 1.63 0 01-1.084.423zm7.938-13.047a3.32 3.32 0 00-1.849.557c-.213.13-.412.284-.591.458a3.321 3.321 0 00-.657 3.733l.135.297-.233.227c-1.738 1.697-4.269 4.22-5.485 5.504a.805.805 0 00.132 1.05.911.911 0 00.298.22c.1.044.209.069.319.072a.694.694 0 00.45-.181c1.573-1.469 4.612-4.539 5.504-5.44l.23-.232.294.135a3.286 3.286 0 003.225-.254 3.33 3.33 0 00.591-.464 3.28 3.28 0 00.964-2.358c0-.215-.021-.43-.064-.642L11.43 7.125 8.879 4.578l2.515-2.59a3.286 3.286 0 00-.65-.06z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="wrench-subaction" xmlns="http://www.w3.org/2000/svg"><path d="M2.807 14.975a1.75 1.75 0 01-1.255-.556 1.684 1.684 0 01-.544-1.1A1.72 1.72 0 011.36 12.1c1.208-1.27 3.587-3.65 5.318-5.345a4.257 4.257 0 01.048-3.078 4.095 4.095 0 011.665-1.969 4.259 4.259 0 014.04-.36l.617.268-2.866 2.951 1.255 1.259 2.944-2.877.267.619a4.295 4.295 0 01.04 3.311 4.198 4.198 0 01-.923 1.392 4.27 4.27 0 01-.743.581 4.217 4.217 0 01-3.812.446c-1.098 1.112-3.84 3.872-5.32 5.254a1.63 1.63 0 01-1.084.423zm7.938-13.047a3.32 3.32 0 00-1.849.557c-.213.13-.412.284-.591.458a3.321 3.321 0 00-.657 3.733l.135.297-.233.227c-1.738 1.697-4.269 4.22-5.485 5.504a.805.805 0 00.132 1.05.911.911 0 00.298.22c.1.044.209.069.319.072a.694.694 0 00.45-.181c1.573-1.469 4.612-4.539 5.504-5.44l.23-.232.294.135a3.286 3.286 0 003.225-.254 3.33 3.33 0 00.591-.464 3.28 3.28 0 00.964-2.358c0-.215-.021-.43-.064-.642L11.43 7.125 8.879 4.578l2.515-2.59a3.286 3.286 0 00-.65-.06z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="x" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.707l3.646 3.647.708-.707L8.707 8l3.647-3.646-.707-.708L8 7.293 4.354 3.646l-.707.708L7.293 8l-3.646 3.646.707.708L8 8.707z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="zap" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.414 1.56L8.312 1h3.294l.818 1.575L10.236 6h1.781l.72 1.695L5.618 15l-1.602-1.163L6.119 10H4.898L4 8.56l3.414-7zM7.78 9L4.9 14.305 12.018 7H8.312l3.294-5H8.312L4.898 9H7.78z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="zoom-in" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.027 6.149a5.52 5.52 0 01-1.27 3.908l4.26 4.26-.7.71-4.26-4.27a5.52 5.52 0 111.97-4.608zm-5.45 4.888a4.51 4.51 0 003.18-1.32l-.04.02a4.51 4.51 0 001.36-3.2 4.5 4.5 0 10-4.5 4.5zm2.44-4v-1h-2v-2h-1v2h-2v1h2v2h1v-2h2z"/></symbol><symbol fill="currentColor" viewBox="0 0 16 16" id="zoom-out" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.027 6.149a5.52 5.52 0 01-1.27 3.908l4.26 4.26-.7.71-4.26-4.27a5.52 5.52 0 111.97-4.608zm-5.45 4.888a4.51 4.51 0 003.18-1.32l-.04.02a4.51 4.51 0 001.36-3.2 4.5 4.5 0 10-4.5 4.5zm-2.54-4.98h5v1h-5v-1z"/></symbol></svg> \ No newline at end of file diff --git a/src/renderer/less/codicon.ttf b/src/renderer/less/codicon.ttf new file mode 100644 index 00000000..3cc92070 Binary files /dev/null and b/src/renderer/less/codicon.ttf differ diff --git a/src/renderer/less/compact.less b/src/renderer/less/compact.less index e29673c9..e546fbfe 100644 --- a/src/renderer/less/compact.less +++ b/src/renderer/less/compact.less @@ -3,7 +3,7 @@ zoom: 0.95; } .app-sidebar-content { - padding:0px; + padding: 0px; .app-sidebar-header-text { padding: 6px 10px; @@ -46,7 +46,7 @@ @media (max-width: 951px) { #app-content { - zoom: 0.8; + // zoom: 0.8; } } } @@ -54,6 +54,6 @@ // if page width is less than 951px @media (max-width: 951px) { #app-content { - zoom: 0.8; + // zoom: 0.8; } -} \ No newline at end of file +} diff --git a/src/renderer/less/directives.less b/src/renderer/less/directives.less new file mode 100644 index 00000000..3d07d63c --- /dev/null +++ b/src/renderer/less/directives.less @@ -0,0 +1,375 @@ +#app.navbar { + --navigationBarHeight: 38px; +} + +#app.twopanel { + --chromeHeight1: 46px; + --chromeHeight2: 90px; + --chromeHeight: calc(var(--chromeHeight1) + var(--chromeHeight2)); + + .modular-fs .app-drawer .lyric-footer { + bottom: var(--chromeHeight2); + } + + .app-chrome { + &:not(.chrome-bottom) { + .app-chrome--center { + flex: 1; + + .top-nav-group { + background: #1e1e1e99; + border: 1px solid lighten(@baseColor, 8); + border-radius: 12px; + display: flex; + height: 32px; + + .app-sidebar-item { + background-color: #1e1e1e00; + border-radius: 10px !important; + border: 0px; + min-width: 120px; + padding: 6px; + justify-content: center; + align-items: center; + margin: 0px; + height: 100%; + position: relative; + white-space: nowrap; + + ._svg-icon { + flex: 0 0 auto; + } + + &:before { + --dist: 1px; + content: ""; + position: absolute; + top: var(--dist); + left: var(--dist); + right: var(--dist); + bottom: var(--dist); + background-color: #fff; + opacity: 0; + border-radius: 10px; + transform: scale(0.5); + transition: + transform 0.2s ease-in-out, + opacity 0.2s ease-in-out; + } + + &:after { + display: none; + } + + &:hover { + background-color: transparent; + + &:before { + transition: + transform 0.1s ease-in-out, + opacity 0.1s ease-in-out; + opacity: 0.1; + transform: scale(1); + } + } + + &.active { + background-color: transparent; + + &:before { + opacity: 0.2; + transform: scale(1); + } + } + + &.md-btn-primary { + box-shadow: 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8); + background-color: lighten(@baseColor, @colorMixRate * 5); + z-index: 1; + } + } + } + } + } + + .app-mainmenu { + width: 30px; + height: 30px; + } + + .search-input { + width: 180px; + } + + height: var(--chromeHeight1); + + &.chrome-bottom { + background: var(--color2); + -webkit-app-region: no-drag; + height: var(--chromeHeight2); + box-shadow: + 0px -2px 6px rgb(20 20 20 / 12%), + 0px -1px 0px 0px rgb(200 200 200 / 12%); + z-index: 4; + + .app-chrome-playback-duration-bottom { + width: 100%; + + .col { + display: flex; + } + + .col-sm-auto { + width: 4em; + display: flex; + justify-content: center; + align-items: center; + font-size: 0.8em; + } + + input[type="range"] { + appearance: none; + width: 100%; + height: 5px; + background-color: rgb(200 200 200 / 10%); + border-radius: 6px; + box-shadow: 0px 0px 0px 1px rgba(0 0 0 / 10%); + align-self: center; + + &::-webkit-slider-thumb { + opacity: 0; + transform: scale(1); + -webkit-appearance: none; + appearance: none; + width: 16px; + height: 16px; + border-radius: 100%; + background: var(--keyColor); + cursor: default; + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); + } + + &:hover { + &::-webkit-slider-thumb { + opacity: 1; + } + } + } + } + } + } + + .app-sidebar-footer--controls { + display: none !important; + } + + .app-chrome.chrome-bottom { + .app-playback-controls .actions { + align-self: center; + } + + -webkit-app-region: no-drag; + + .playback-button.play, + .playback-button.pause, + .playback-button.stop { + width: 42px; + height: 42px; + border-radius: 50%; + margin: 6px; + } + + .app-chrome--center { + display: flex; + flex-direction: column; + + .app-chrome-playback-controls { + display: flex; + z-index: 1; + // margin-bottom: 12px; + } + + .app-chrome-playback-duration { + position: relative; + width: 80%; + -webkit-app-region: no-drag; + height: 16px; + + .song-progress { + @bgColor: transparent; + height: 16px; + position: absolute; + bottom: 4px; + left: 0px; + right: 4px; + background: @bgColor; + z-index: 0; + + .song-duration { + display: flex; + } + + .song-duration p { + font-weight: 400; + font-size: 10px; + height: 1.2em; + line-height: 1.3em; + overflow: hidden; + margin: 0 0 0 0.25em; + } + + &:hover { + > input[type="range"] { + &::-webkit-slider-thumb { + opacity: 1; + transform: scale(1); + z-index: 1; + } + } + } + + input[type="range"] { + appearance: none; + width: 100%; + height: 4px; + background-color: rgb(200 200 200 / 10%); + border-radius: 2px; + + &::-webkit-slider-thumb { + opacity: 0; + transform: scale(0.5); + -webkit-appearance: none; + appearance: none; + width: 12px; + height: 12px; + border-radius: 100%; + background: var(--keyColor); + cursor: default; + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); + } + } + } + } + } + + .app-chrome--left { + width: 30%; + justify-content: flex-start; + align-items: flex-start; + -webkit-app-region: no-drag !important; + + .playback-controls { + -webkit-app-region: no-drag !important; + + .artwork { + --offset: 20px; + --marginOffset: 2; + --size: calc(var(--chromeHeight2) - var(--offset)); + width: var(--size); + height: var(--size); + margin: 0 calc(var(--offset) / var(--marginOffset)) 0 calc(var(--offset) / var(--marginOffset)); + + .mediaitem-artwork, + img { + border-radius: calc(var(--mediaItemRadius) / 2); + } + } + + .playback-info { + align-items: flex-start; + margin: 8px; + + .song-name { + text-align: left; + font-size: 0.8em; + font-weight: 500; + width: 100%; + -webkit-mask-image: linear-gradient(-90deg, transparent 0%, transparent 10%, black 20%); + } + + .song-artist, + .song-album { + font-size: 0.75em; + opacity: 0.8; + cursor: pointer; + white-space: nowrap; + max-width: 360px; + -webkit-mask-image: linear-gradient(-90deg, transparent 0%, transparent 10%, black 20%); + width: 100%; + + &:hover { + text-decoration: underline; + } + } + + .audio-type { + margin: 0px; + } + + .song-artist-album-content { + text-align: left; + font-size: 12px; + } + } + + width: 100%; + height: 100%; + max-width: 100%; + border: 0px; + } + + flex: 0 0 auto; + } + + .app-chrome--right { + width: 30%; + flex: 0 0 auto; + padding-right: 8px; + } + } + + .collection-page { + .top-fab { + bottom: 96px; + } + } +} + +// screen width is less than 768px +@media (max-width: 1100px) { + #app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center { + flex: unset; + } + + #app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center .top-nav-group .app-sidebar-item { + min-width: 110px; + .sidebar-item-text { + display: none; + } + + .sidebar-icon { + margin: 0px; + } + } +} + +@media (max-width: 1000px) { + #app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center { + flex: unset; + } + + #app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center .top-nav-group .app-sidebar-item { + min-width: 60px; + .sidebar-item-text { + display: none; + } + + .sidebar-icon { + margin: 0px; + } + } +} diff --git a/src/renderer/less/elements.less b/src/renderer/less/elements.less new file mode 100644 index 00000000..89a0679f --- /dev/null +++ b/src/renderer/less/elements.less @@ -0,0 +1,2458 @@ +// Form + +.md-select { + padding: 6px; + border-radius: 6px; + border: 1px solid rgba(200, 200, 200, 0.1); + border-top: 1px solid rgba(100, 100, 100, 0.5); + font-family: inherit; + font-size: 14px; + background: rgba(100, 100, 100, 0.25); + color: #eee; + + option { + font-size: 1em; + font-family: inherit; + padding: 8px 16px; + background: #404040; + } + + optgroup { + background: #2c2c2c; + } + + &:focus { + outline: solid 1px var(--selected); + } +} + +// Buttons +.md-btn { + font-family: inherit; + background: rgb(100 100 100 / 25%); + padding: 8px 14px; + border-radius: 6px; + font-size: 14px; + border: 1px solid rgba(100, 100, 100, 0.35); + border-top: 1px solid rgba(100, 100, 100, 0.5); + color: #eee; + white-space: nowrap; + transition: + transform 0.2s var(--appleEase), + box-shadow 0.2s var(--appleEase); + + &.md-btn-block { + display: block; + width: 100%; + } + + &.md-btn-glyph { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + } + + &.md-btn-primary { + background: #ff2b52a6; + color: white; + border: 1px solid rgb(220 53 69 / 25%); + border-top: 1px solid rgb(220 53 69 / 50%); + } + + &.md-btn-small { + padding: 6px 8px; + font-size: 13px; + } + + &:hover { + filter: brightness(125%); + } + + &:active { + filter: brightness(75%); + transform: scale(0.98); + transition: + transform 0s var(--appleEase), + box-shadow 0.2s var(--appleEase); + } + + &.md-btn-icon { + display: inline-flex; + vertical-align: middle; + justify-content: center; + + > img { + margin: 0px 16px 0px 0px; + pointer-events: none; + } + + > .md-btn-text { + margin: 0px; + } + } +} + +.btn-group { + display: inline-flex; + justify-content: center; + align-items: center; + + > .md-btn { + border-radius: 0px; + width: 100%; + } + + > .md-btn:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + } + + > .md-btn:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + } + + > .md-btn:not(:first-child):not(:last-child) { + border-radius: 0px; + } +} + +.md-close-btn { + -webkit-mask-image: url("ameres://icons/webui/close.svg"); + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + background-color: white; + opacity: 0.75; + -webkit-mask-size: contain; + height: 18px; + width: 18px; +} + +.md-ico-play { + content: url("./assets/play.svg"); + width: 10px; + height: 12px; + margin-right: 1px; + align-self: center; +} + +.md-ico-shuffle { + content: url("./assets/shuffle.svg"); + width: 1em; + height: 1em; + margin-right: 1px; + margin-bottom: -2px; + align-self: center; +} + +.md-ico-remove { + content: url("./assets/feather/x-circle-white.svg"); + width: 16px; + height: 16px; + margin-right: 1px; + margin-bottom: -1.5px; + align-self: center; +} + +.md-ico-add { + content: url("./assets/feather/plus-circle-white.svg"); + width: 1em; + height: 1em; + margin-right: 1px; + margin-bottom: -1.5px; + align-self: center; +} + +.page-btn { + align-self: center; + height: 32px; + width: max-content; +} + +.page-btn img { + height: 100%; + align-self: center; +} + +.md-ico-first { + content: url("./assets/angles-left.svg"); +} + +.md-ico-prev { + content: url("./assets/chevron-left.svg"); +} + +.md-ico-next { + content: url("./assets/chevron-right.svg"); +} + +.md-ico-last { + content: url("./assets/angles-right.svg"); +} + +.reload-btn { + background: rgb(86 86 86 / 52%); + border-radius: 100%; + width: 32px; + height: 32px; + border: 0px; + appearance: none; + display: flex; + justify-content: center; + align-items: center; +} + +.reload-btn:hover { + background: rgb(86 86 86 / 80%); + cursor: pointer; +} + +.reload-btn > svg { + height: 50%; + color: #eee; +} + +.wr-btn { + font-family: inherit; + appearance: none; + border: 0px; + border-radius: 6px; + padding: 8px; + font-weight: 600; + background: rgb(80 80 80 / 70%); + color: white; +} + +.cd-btn-seeall { + background: transparent; + border: 0px; + color: var(--keyColor); + font-family: inherit; + font-weight: 500; + font-size: 16px; + border-radius: 4px; + padding: 6px; + + &:hover { + cursor: pointer; + background: rgb(200 200 200 / 10%); + } +} + +// Media Item Elements + +.mediaitem-artwork { + border-radius: var(--mediaItemRadius); + overflow: hidden; + flex: 0 0 auto; + position: relative; + width: 100%; + height: 100%; + + .animatedartwork-view-box { + position: absolute; + top: 0px; + width: 100%; + height: 100%; + + .animated { + position: absolute; + top: 0px; + width: 100%; + height: 100%; + + video { + width: 100%; + height: 100%; + } + } + } + + &.rounded { + border-radius: 100%; + + &::after { + border-radius: 100%; + } + } + + &::after { + content: ""; + box-shadow: var(--mediaItemShadow); + z-index: 1; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + border-radius: inherit; + } + + img { + width: 100%; + height: 100%; + object-fit: cover; + image-rendering: -webkit-optimize-contrast; + pointer-events: none; + background-image: url("./assets/MissingArtwork.svg"); + background-size: cover; + background-position: center; + } + + &.no-shadow { + box-shadow: none; + + &::after { + display: none; + } + } + + &.subtle-shadow { + box-shadow: var(--mediaItemShadow-ShadowSubtle); + } + + &.shadow { + box-shadow: var(--mediaItemShadow-Shadow); + } +} + +#artworkLCD img { + image-rendering: auto; +} + +/* queue item */ +.cd-queue-item { + border-bottom: 0px solid rgb(200 200 200 / 10%); + padding: 1px; + padding-bottom: 9px; + padding-top: 9px; + + .row, + .col { + padding: 0px; + margin: 0px; + } + + .artwork { + width: 42px; + height: 42px; + flex: 0 0 auto; + &.circle { + border-radius: 50%; + .mediaitem-artwork { + border-radius: 50%; + } + img { + border-radius: 50%; + } + } + } + + &:hover { + background: var(--selected); + } + + &.selected { + background: var(--selected); + } + + &:active { + background: var(--selected-click); + color: #eee; + } + + &.hintactive { + background: var(--keyColor); + border-radius: 6px; + } + + .queue-info { + justify-content: center; + display: flex; + flex-direction: column; + flex-grow: 1; + + .queue-title { + font-size: 14px; + } + + .queue-subtitle { + font-size: 0.7em; + opacity: 0.7; + } + } + + .queue-duration-info { + display: flex; + flex-grow: 0; + } + + .queue-duration { + font-size: 14px; + justify-content: center; + min-width: 60px; + height: 100%; + } + + .queue-explicit-icon { + display: flex; + width: 24px; + padding: 0px; + } + + .explicit-icon { + background-image: url("./assets/explicit.svg"); + height: 12px; + width: 36px; + filter: contrast(0); + background-repeat: no-repeat; + } +} + +.search-hints .cd-queue-item { + &:hover { + background: var(--selected); + border-radius: 6px; + + .circular-play-button { + opacity: 1; + } + } + &:active { + background: var(--selected-click); + color: #eee; + border-radius: 6px; + } +} + +/* Circle Play Button */ +.circular-play-button { + position: relative; + opacity: 0; + top: -34px; + z-index: 5; + left: 8px; + align-items: center; + background: rgba(100, 100, 100, 0.5); + border: none; + cursor: pointer; + border-radius: 100%; + height: 26px; + box-shadow: var(--ciderShadow-Generic); +} + +/* horizontal media scroller */ +.cd-hmedia-scroller { + &::-webkit-scrollbar-thumb { + box-shadow: none; + } + + &:hover::-webkit-scrollbar-thumb { + box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); + } + + &.hmedia-scroller-card { + .mediaitem-card { + margin: 16px; + } + } +} + +/* mediaitem-list-item */ +.cd-mediaitem-list-item { + width: 100%; + height: 60px; + display: flex; + flex: 0 0 auto; + flex-direction: row; + font-size: 14px; + justify-content: center-between; + align-items: center; + border-radius: var(--mediaItemRadius); + position: relative; + + .listitem-content { + width: 100%; + height: 60px; + display: flex; + flex: 0 0 auto; + flex-direction: row; + font-size: 14px; + justify-content: center-between; + align-items: center; + border-radius: var(--mediaItemRadius); + position: relative; + } + + &:hover { + .heart-icon { + display: none; + } + } + + .popular { + background-image: url(assets/star.svg); + background-repeat: no-repeat; + background-size: 10px; + width: 10px; + height: 10px; + position: absolute; + left: 3px; + } + + .artwork { + height: 42px; + width: 42px; + object-fit: cover; + object-position: center; + flex: 0 0 auto; + background-repeat: no-repeat; + margin: 12px; + border: 0px; + outline: none; + position: relative; + overflow: hidden; + border-radius: var(--mediaItemRadiusSmall); + + .mediaitem-artwork { + border-radius: var(--mediaItemRadiusSmall); + } + + .overlay-play { + background: rgba(0, 0, 0, 0.5); + opacity: 0; + appearance: none; + border: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 0px; + z-index: 5; + cursor: pointer; + + &:hover { + opacity: 1; + } + + &:active { + background: var(--selected-click); + } + } + } + + .artwork.round { + border-radius: var(--mediaItemRadiusRound); + } + + .info-rect { + height: 100%; + display: flex; + flex-flow: column; + justify-content: center; + flex-grow: 1; + } + + .title { + width: 100%; + } + + .subtitle { + width: 90%; + font-size: 0.8em; + opacity: 0.7; + } + + .duration { + min-width: 60px; + text-align: center; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + + .metainfo { + min-width: 145px; + text-align: center; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + + .heart-unfilled { + -webkit-mask-image: url("assets/feather/heart.svg"); + height: 12px; + width: 12px; + background-repeat: no-repeat; + background-color: #999; + } + + .heart-filled { + -webkit-mask-image: url("assets/feather/heart-fill.svg"); + height: 12px; + width: 12px; + background-repeat: no-repeat; + background-color: #999; + } + + .explicit-icon { + background-image: url("./assets/explicit.svg"); + height: 12px; + width: 36px; + filter: contrast(0); + background-repeat: no-repeat; + } + + .heart-icon { + display: flex; + position: absolute; + left: 20px; + } + + /* CSS.gg + */ + @keyframes load-bar { + 10% { + box-shadow: inset 0 -4px 0; + } + + 20% { + box-shadow: inset 0 -10px 0; + } + + 30% { + box-shadow: inset 0 -12px 0; + } + + 40% { + box-shadow: inset 0 -8px 0; + } + + 50% { + box-shadow: inset 0 -4px 0; + } + + 60% { + box-shadow: inset 0 -6px 0; + } + + 80% { + box-shadow: inset 0 -12px 0; + } + + 90% { + box-shadow: inset 0 -6px 0; + } + + to { + box-shadow: inset 0 -2px 0; + } + } + + .loadbar-sound, + .loadbar-sound::after, + .loadbar-sound::before { + animation: load-bar 1.3s ease infinite alternate; + box-sizing: border-box; + width: 3px; + height: 28px; + box-shadow: inset 0 -12px 0; + } + + .loadbar-sound { + margin-left: 22px; + margin-top: -16px; + position: relative; + transform: scale(var(--load-bar, 1)); + color: var(--keyColor); + display: block; + } + + .loadbar-sound::after, + .loadbar-sound::before { + content: ""; + position: absolute; + bottom: 0; + } + + .loadbar-sound::before { + left: -4.5px; + animation-delay: -2.4s; + } + + .loadbar-sound::after { + right: -4.2px; + animation-delay: -3.7s; + } + + .isLibrary { + flex: 0 0 auto; + width: 40px; + text-align: center; + + button { + appearance: none; + border: 0px; + background: transparent; + cursor: pointer; + filter: contrast(0.8); + } + } + + &:hover { + background: rgb(200 200 200 / 10%); + box-shadow: var(--mediaItemShadow); + + .overlay-play { + opacity: 1; + } + } + + &.mediaitem-selected { + background: var(--selected); + box-shadow: var(--mediaItemShadow); + } + + &:active { + background: var(--selected-click); + box-shadow: var(--mediaItemShadow); + color: #eee; + } + + &.disabled { + opacity: 0.5; + pointer-events: none; + } + + // list item compact + &.compact { + height: 40px; + font-size: 13px; + + .artwork { + display: none; + } + + .info-rect { + padding-left: 1em; + } + } +} + +/* mediaitem-hrect */ +.cd-mediaitem-hrect { + background: rgb(255 255 255 / 18%); + width: 264px; + height: 100px; + display: inline-flex; + flex: 0 0 auto; + flex-direction: row; + font-size: 14px; + justify-content: center; + align-items: center; + border-radius: 6px; + cursor: pointer; + + .artwork { + height: 70px; + width: 70px; + background: blue; + border-radius: var(--mediaItemRadius); + background: var(--artwork); + background-size: contain; + flex: 0 0 auto; + background-repeat: no-repeat; + margin: 18px; + } + + .artwork.round { + border-radius: var(--mediaItemRadiusRound); + } + + .info-rect { + width: 100%; + } + + .title { + width: 100%; + text-align: center; + } + + .subtitle { + width: 100%; + text-align: center; + font-size: 12px; + } +} + +/* mediaitem-square-sp */ +.cd-mediaitem-square-sp { + --spcolor: var(""); + width: 190px; + height: 245px; + display: inline-flex; + flex: 0 0 auto; + flex-direction: column; + font-size: 14px; + justify-content: flex-start; + align-items: center; + border-radius: 6px; + margin-left: 10px; + cursor: pointer; + background-color: var(--spcolor); + + .artwork { + height: 190px; + width: 190px; + background: blue; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + background: var(--artwork); + background-size: cover; + flex: 0 0 auto; + margin: 6px; + margin-top: 0px; + + &.round { + border-radius: var(--mediaItemRadiusRound); + } + + &:hover { + box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; + } + } + + .title { + width: 90%; + text-align: center; + } + + .subtitle { + width: 100%; + text-align: center; + font-size: 12px; + } + + > .cd-mediaitem-square-large-overlay { + z-index: 3; + + &:hover { + opacity: 1; + } + } + + + .cd-mediaitem-square-large-overlay { + pointer-events: none; + } + + &:hover + .cd-mediaitem-square-large-overlay { + opacity: 1; + } + + &:hover { + box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; + } +} + +/* mediaitem-square-large */ +.cd-mediaitem-square-large { + width: 190px; + height: 250px; + display: inline-flex; + flex: 0 0 auto; + flex-direction: column; + font-size: 14px; + justify-content: flex-start; + align-items: center; + border-radius: 6px; + margin-left: 10px; + cursor: pointer; + + > * { + z-index: inherit; + } +} + +.cd-mediaitem-square-large .artwork { + height: 190px; + width: 190px; + background: blue; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + background: var(--artwork); + background-size: cover; + flex: 0 0 auto; + margin: 6px; + margin-top: 0px; +} + +.cd-mediaitem-square-large-overlay { + position: absolute; + width: 190px; + float: right; + height: 250px; + top: 0px; + margin: 10px; + margin-top: 0px; + opacity: 0; +} + +.cd-mediaitem-square-large-overlay > * { + pointer-events: auto; +} + +.cd-mediaitem-square-large > .cd-mediaitem-square-large-overlay { + z-index: 3; +} + +.cd-mediaitem-square-large > .cd-mediaitem-square-large-overlay:hover { + opacity: 1; +} + +.cd-mediaitem-square-large + .cd-mediaitem-square-large-overlay { + pointer-events: none; +} + +.cd-mediaitem-square-large:hover + .cd-mediaitem-square-large-overlay { + opacity: 1; +} + +.cd-mediaitem-square-large .artwork.round { + border-radius: var(--mediaItemRadiusRound); +} + +.cd-mediaitem-square-large .title { + width: 90%; + text-align: center; +} + +.cd-mediaitem-square-large .subtitle { + width: 100%; + text-align: center; + font-size: 12px; +} + +/* mediaitem-mvview */ + +/* mediaitem-mvview */ +.cd-mediaitem-mvview { + width: 300px; + height: 250px; + display: inline-flex; + flex: 0 0 auto; + flex-direction: column; + font-size: 14px; + justify-content: flex-start; + align-items: center; + border-radius: 6px; + margin-left: 10px; + cursor: pointer; + + > * { + z-index: inherit; + } +} + +.cd-mediaitem-mvview .artwork { + height: auto; + width: 300px; + background: blue; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + background: var(--artwork); + background-size: cover; + flex: 0 0 auto; + margin: 6px; + margin-top: 0px; + aspect-ratio: 1.7435897435897436; +} + +.cd-mediaitem-mvview-overlay { + position: absolute; + width: 300px; + float: right; + height: 250px; + top: 0px; + margin: 10px; + margin-top: 0px; + opacity: 0; +} + +.cd-mediaitem-mvview-overlay > * { + pointer-events: auto; +} + +.cd-mediaitem-mvview > .cd-mediaitem-mvview-overlay { + z-index: 3; +} + +.cd-mediaitem-mvview > .cd-mediaitem-mvview-overlay:hover { + opacity: 1; +} + +.cd-mediaitem-mvview + .cd-mediaitem-mvview-overlay { + pointer-events: none; +} + +.cd-mediaitem-mvview:hover + .cd-mediaitem-mvview-overlay { + opacity: 1; +} + +.cd-mediaitem-mvview .artwork.round { + border-radius: var(--mediaItemRadiusRound); +} + +.cd-mediaitem-mvview .title { + width: 90%; + text-align: center; +} + +.cd-mediaitem-mvview .subtitle { + width: 100%; + text-align: center; + font-size: 12px; +} + +/* mediaitem-square */ +.cd-mediaitem-square { + --transitionDuration: 0.5s; + --scaleRate: 1.25; + --scaleRateArtwork: 1; + width: calc(160px * var(--windowRelativeScale)); + height: calc(200px * var(--windowRelativeScale)); + display: inline-flex; + flex: 0 0 auto; + flex-direction: column; + font-size: 14px; + justify-content: center; + align-items: center; + border-radius: 6px; + + .artwork-container { + position: relative; + + .artwork { + height: calc(140px * var(--windowRelativeScale)); + width: calc(140px * var(--windowRelativeScale)); + background: blue; + border-radius: var(--mediaItemRadius); + background: var(--artwork); + background-size: cover; + flex: 0 0 auto; + margin: 6px; + cursor: pointer; + + .mediaitem-artwork { + box-shadow: unset; + } + + &.round { + border-radius: var(--mediaItemRadiusRound); + } + } + + .badge-container { + transition: opacity 0.1s var(--appleEase); + opacity: 1; + + .socialBadge { + width: 32px; + height: 32px; + position: absolute; + right: 14px; + bottom: 14px; + border-radius: 100%; + overflow: hidden; + z-index: 2; + pointer-events: none; + } + } + + > .play-btn, + > .menu-btn { + opacity: 0; + appearance: none; + padding: 0px; + border: 0px; + width: 30px; + height: 30px; + border-radius: 50%; + background: rgba(50, 50, 50, 0.7); + cursor: pointer; + transition: opacity 0.1s var(--appleEase); + + :hover { + border-radius: 50%; + background: rgba(250, 0, 0, 0.7); + } + } + + > .play-btn { + position: absolute; + bottom: 14px; + left: 14px; + z-index: 2; + } + + > .menu-btn { + position: absolute; + bottom: 14px; + right: 14px; + z-index: 2; + } + + &:hover { + > .badge-container { + opacity: 0; + } + + > .play-btn, + > .menu-btn { + opacity: 1; + } + } + } + + // &:not(.mediaitem-card):not(.mediaitem-brick):not(.mediaitem-video):not(.noscale) { + // @media (min-width: 1460px) { + // --scaleRate: 1.1; + // --scaleRateArtwork: 0.9; + // width: calc(200px * var(--scaleRate)); + // height: calc(200px * var(--scaleRate)); + + // .artwork-container > .artwork { + // width: calc(190px * var(--scaleRateArtwork)); + // height: calc(190px * var(--scaleRateArtwork)); + // } + // } + + // @media (min-width: 1550px) { + // --scaleRate: 1.25; + // --scaleRateArtwork: 1; + // width: calc(200px * var(--scaleRate)); + // height: calc(200px * var(--scaleRate)); + + // .artwork-container > .artwork { + // width: calc(190px * var(--scaleRateArtwork)); + // height: calc(190px * var(--scaleRateArtwork)); + // } + // } + // } + + .info-rect { + width: 90%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + } + + .title { + width: 100%; + text-align: center; + display: flex; + align-content: center; + justify-content: center; + } + + .subtitle { + width: 100%; + text-align: center; + font-size: 12px; + } + + .unavailable-overlay { + position: absolute; + top: 0px; + left: 0px; + bottom: 0; + right: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 2; + pointer-events: none; + background: rgb(0 0 0 / 40%); + margin: 2em; + border-radius: 10px; + + > .codicon { + font-size: 4em; + font-weight: bold; + opacity: 0.5; + } + } + + &.mediaitem-video { + height: 200px; + width: 240px; + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear; + + .artwork { + height: 120px; + width: 212px; + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear; + } + + &:not(.noscale) { + @media (min-width: 1460px) { + --scaleRate: 1.1; + --scaleRateArtwork: 1.1; + width: calc(240px * var(--scaleRate)); + height: calc(200px * var(--scaleRate)); + + .artwork-container > .artwork { + width: calc(220px * var(--scaleRateArtwork)); + height: calc(123px * var(--scaleRateArtwork)); + } + } + + @media (min-width: 1550px) { + --scaleRate: 1.25; + --scaleRateArtwork: 1.25; + width: calc(240px * var(--scaleRate)); + height: calc(200px * var(--scaleRate)); + + .artwork-container > .artwork { + width: calc(220px * var(--scaleRateArtwork)); + height: calc(123px * var(--scaleRateArtwork)); + } + } + } + } + + &.mediaitem-brick { + height: 200px; + width: 240px; + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear; + + .artwork { + height: 123px; + width: 220px; + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear; + } + + &:not(.noscale) { + @media (min-width: 1460px) { + --scaleRate: 1.1; + --scaleRateArtwork: 1.1; + width: calc(240px * var(--scaleRate)); + height: calc(200px * var(--scaleRate)); + + .artwork-container > .artwork { + width: calc(220px * var(--scaleRateArtwork)); + height: calc(123px * var(--scaleRateArtwork)); + } + } + + @media (min-width: 1550px) { + --scaleRate: 1.25; + --scaleRateArtwork: 1.25; + width: calc(240px * var(--scaleRate)); + height: calc(200px * var(--scaleRate)); + + .artwork-container > .artwork { + width: calc(220px * var(--scaleRateArtwork)); + height: calc(123px * var(--scaleRateArtwork)); + } + } + } + } + + &.mediaitem-small { + width: calc(140px, var(--windowRelativeScale)); + height: calc(180px, var(--windowRelativeScale)); + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear; + + .artwork { + height: calc(128px, var(--windowRelativeScale)); + width: calc(128px, var(--windowRelativeScale)); + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear; + } + } + + &.mediaitem-card { + background: #ccc; + background: var(--spcolor); + height: 302px; + width: 230px; + overflow: hidden; + position: relative; + border-radius: calc(var(--mediaItemRadius) * 2); + box-shadow: var(--mediaItemShadow-ShadowSubtle); + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear; + + .artwork { + width: 230px; + height: 230px; + overflow: hidden; + border-radius: 0px; + margin: 0; + transition: + width var(--transitionDuration) linear, + height var(--transitionDuration) linear, + filter 0.2s ease-in-out; + .mediaitem-artwork { + border-radius: 0px; + + &::after { + box-shadow: unset; + } + } + } + + .info-rect-card { + padding: 10px 10px 14px; + position: relative; + width: 100%; + display: grid; + align-content: center; + + &::before { + background: var(--bgartwork); + content: ""; + top: 0; + left: 0; + bottom: 0; + right: 0; + position: absolute; + background-size: cover; + background-position: bottom; + z-index: 0; + opacity: 1; + filter: brightness(0.5) blur(50px) saturate(180%); + transition: filter 0.2s ease-in-out; + } + } + + .title { + height: 100%; + display: flex; + justify-content: center; + align-items: center; + font-size: 0.9em; + font-weight: 500; + z-index: 1; + + & + .subtitle { + max-height: none !important; + // margin-top: -0.5em; + } + } + + .subtitle { + height: 100%; + justify-content: center; + align-items: center; + font-size: 0.75em; + width: 100%; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + max-height: 4.8em; + z-index: 1; + } + + &::after { + box-shadow: var(--mediaItemShadow); + content: ""; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + pointer-events: none; + border-radius: inherit; + } + + &:hover { + .artwork { + filter: brightness(0.8); + } + .info-rect-card::before { + filter: brightness(0.3) blur(50px) saturate(180%); + } + } + + &:not(.noscale) { + @media (min-width: 1200px) { + width: calc(230px * 1.1); + height: calc(298px * 1.1); + .artwork-container > .artwork { + width: calc(230px * 1.1); + height: calc(230px * 1.1); + } + } + + @media (min-width: 1400px) { + width: calc(230px * 1.25); + height: calc(298px * 1.25); + .artwork-container > .artwork { + width: calc(230px * 1.25); + height: calc(230px * 1.25); + } + } + } + } +} + +/* mediaitem-square */ +.albums-square-containeru > * > .cd-mediaitem-square { + --frame: max(220px, 15vw); + width: var(--frame); + height: calc(var(--frame) * 13 / 11); + display: inline-flex; + flex: 0 0 auto; + flex-direction: column; + font-size: calc(var(--frame) / 220 * 14); + justify-content: center; + align-items: center; + border-radius: calc(var(--frame) / 220 * 6); + + .artwork-container { + position: relative; + + .artwork { + height: calc(var(--frame) * 19 / 22); + width: calc(var(--frame) * 19 / 22); + background: blue; + border-radius: var(--mediaItemRadius); + background: var(--artwork); + background-size: cover; + flex: 0 0 auto; + margin: calc(var(--frame) / 220 * 6); + cursor: pointer; + + &.round { + border-radius: var(--mediaItemRadiusRound); + } + } + + > .play-btn, + > .menu-btn { + opacity: 0; + appearance: none; + padding: 0px; + border: 0px; + width: calc(var(--frame) / 220 * 30); + height: calc(var(--frame) / 220 * 30); + border-radius: 50%; + background: rgba(50, 50, 50, 0.7); + cursor: pointer; + backdrop-filter: blur(32px) saturate(180%); + transition: opacity 0.1s var(--appleEase); + } + + > .play-btn { + position: absolute; + bottom: calc(var(--frame) / 220 * 14); + left: calc(var(--frame) / 220 * 14); + z-index: 2; + } + + > .menu-btn { + position: absolute; + bottom: calc(var(--frame) / 220 * 14); + right: calc(var(--frame) / 220 * 14); + z-index: 2; + } + + &:hover { + > .play-btn, + > .menu-btn { + opacity: 1; + } + } + } + + .title { + width: 90%; + text-align: center; + } + + .subtitle { + width: 100%; + text-align: center; + font-size: calc(var(--frame) / 220 * 12); + } + + &.mediaitem-video { + height: calc(var(--frame) / 220 * 200); + width: calc(var(--frame) / 220 * 240); + + .artwork { + height: calc(var(--frame) / 220 * 120); + width: calc(var(--frame) / 220 * 212); + } + } + + &.mediaitem-brick { + height: calc(var(--frame) / 220 * 200); + width: calc(var(--frame) / 220 * 240); + + .artwork { + height: calc(var(--frame) / 220 * 123); + width: calc(var(--frame)); + } + } +} + +.listitem-horizontal { + .cd-mediaitem-list-item { + width: 350px; + height: 60px; + } +} + +.mediaitem-list-item__grid { + background: rgba(200, 200, 200, 0.05); + border-radius: 10px; + padding: var(--contentInnerPadding); + box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 0px 1px; + width: 100%; + + .cd-mediaitem-list-item { + width: 350px; + height: 60px; + } + + &::-webkit-scrollbar { + display: none; + } + + &:hover::-webkit-scrollbar { + display: initial; + } +} + +// Graphics + +// sidebar icon +.svg-icon { + --color: #aaa; + --url: url("./assets/feather/share.svg"); + -webkit-mask-image: var(--url); + -webkit-mask-size: cover; + height: 18px; + width: 18px; + background: var(--color); + + &.inline { + display: inline-block; + } +} + +.sidebar-icon { + width: 18px; + height: 18px; + margin-right: 8px; + + > .svg-icon { + width: 100%; + height: 100%; + --color: #aaa; + } + + > svg { + width: 100%; + height: 100%; + color: #aaa; + } +} + +/* Switch Checkbox */ +input[type="checkbox"][switch] { + width: 38px; + appearance: none; + border-radius: 32px; + height: 24px; + zoom: 1; + top: 0; + cursor: pointer; + left: 0; + position: relative; + transform: scale(1); + background: rgb(142 142 147 / 100%); + padding: 0; + margin: 0; +} + +input[type="checkbox"][switch]:focus, +input[type="checkbox"][switch]:active { + outline: none; +} + +input[type="checkbox"][switch]:checked { + background: var(--keyColor); + border: 0 solid var(--keyColor); + mix-blend-mode: unset; + + &:hover { + background: var(--keyColor-rollover); + } + + &:active { + background: var(--keyColor-pressed); + } +} + +input[type="checkbox"][switch]::before { + background: white; + width: 26px; + height: 26px; + top: -1px; + left: -1px; + position: absolute; + content: " "; + border-radius: 32px; + transition: 0.1s left var(--appleEase); + transform: scale(0.75); +} + +input[type="checkbox"][switch]:checked::before { + background: white; + top: -1px; + left: 13px; + transition: 0.1s left var(--appleEase); + transform: scale(0.75); +} + +input[type="checkbox"][switch]:disabled::before { + opacity: 0.5; +} + +input[type="checkbox"][switch]:active::before { + left: 13px; +} + +input[type="checkbox"][switch]:checked:active::before { + left: -1px; +} + +/* End Switch Checkbox */ + +.header-text { + margin: 0px; +} + +.media-item--small { + background: rgb(0 0 0 / 25%); + height: 162px; + width: 132px; + display: inline-flex; + flex-direction: column; + justify-content: center; + align-items: center; + border-radius: 10px; +} + +.media-item--small .artwork { + background: red; + margin: 6px; + border-radius: 100%; + width: 90px; + height: 90px; + box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 30%); +} + +.playlist-artwork { + height: 190px; + width: 190px; + background: blue; + border-radius: 6px; + background: var(--artwork); + background-size: cover; + box-shadow: var(--mediaItemShadow); + flex: 0 0 auto; + margin: 6px; + margin-top: 0px; +} + +.media-item--small .text { + font-weight: 600; + font-size: 0.9em; +} + +.media-item--small .subtext { + font-size: 0.75em; +} + +.player-duration-time { + opacity: 0.5; +} + +.player-artwork-container { + display: flex; + align-items: center; + justify-content: center; +} + +.player-duration-container { + font-size: 0.85em; + font-weight: 500; +} + +.media-artwork { + --artwork: url(""); + width: 80vw; + height: 80vw; + max-height: 500px; + max-width: 500px; + background: black; + background-image: var(--artwork); + background-size: cover; + background-position: center; + background-repeat: no-repeat; + border-radius: 8px; + box-shadow: + inset 0px 0px 0px 1px rgb(200 200 200 / 16%), + 0 8px 40px rgb(0 0 0 / 0.55); + transition: transform 0.1s var(--appleEase); +} + +.media-artwork.paused { + transition: transform 0.35s var(--appleEase); + transform: scale(0.85); +} + +.playback-slider { + width: 90%; +} + +.volume-slider { + width: 100%; +} + +.volume-slider-container { + width: 90%; + margin: 0 auto; + padding: 0px; +} + +.volume-slider-container .col-auto, +.volume-slider-container .col { + display: flex; + align-items: center; + justify-self: center; + padding: 0px; + margin: 0px; +} + +.playback-button { + font-size: 2em; + width: 40px; + height: 36px; + padding: 0px; + background: transparent; + border: 0px; + border-radius: 0px; + box-shadow: unset; + background-size: 12px; + background-position: center; + background-repeat: no-repeat; + opacity: 0.7; + border-radius: 6px; + position: relative; + + &:before { + content: ""; + display: block; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: var(--selected); + border-radius: inherit; + position: absolute; + opacity: 0; + z-index: -1; + transform: scale(0.5); + pointer-events: none; + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); + } + + &:hover { + &:before { + transform: scale(1); + opacity: 1; + } + } +} + +.playback-button--small { + border-radius: 6px; + font-size: 1em; + color: inherit; + background-size: 0.98em; + background-repeat: no-repeat; + background-position: center; + background-color: transparent; + width: 40px; + height: 32px; + border: 0px; + box-shadow: unset; + opacity: 0.7; + position: relative; + + &:before { + content: ""; + display: block; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: var(--selected); + border-radius: inherit; + position: absolute; + opacity: 0; + z-index: -1; + transform: scale(0.5); + pointer-events: none; + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); + } + + &:hover { + &:before { + transform: scale(1); + opacity: 1; + } + } +} + +.playback-button--small.active { + background-color: rgb(200 200 200 / 25%); +} + +.playback-button:hover, +.playback-button--small:hover { + // background-color: var(--selected); +} + +.playback-button:active, +.playback-button--small:active { + background-color: var(--selected-click); +} + +.playback-button--small.search { + background-image: url("./assets/search.svg"); +} + +.playback-button--small.cast { + background-image: url("./assets/cast_white.svg"); + background-size: 1.25em; +} + +.playback-button--small.miniplayer { + background-image: url("./assets/pip.svg"); +} + +.playback-button--small.queue { + background-image: url("./assets/list.svg"); +} + +.playback-button--small.lyrics { + background-image: url("./assets/quote-right.svg"); +} + +.playback-button--small.shuffle { + background-image: url("./assets/shuffle.svg"); +} + +.playback-button--small.repeat { + background-image: url("./assets/repeat.svg"); +} + +.playback-button--small.repeat.repeatOne { + background-color: rgb(200 200 200 / 25%); + background-image: url("./assets/repeatOne.svg"); +} + +.playback-button.stop { + background-image: url("./assets/cider-icons/stop.svg"); + background-size: 38px; + background-position: center; +} + +.playback-button.collapseLibrary { + font-family: "codicon"; + font-size: 1em; + color: var(--textColor); + display: grid; + place-items: center; + + span { + position: absolute; + } +} + +.playback-button.pause { + background-image: url("./assets/cider-icons/pause.svg"); + background-size: 38px; + background-position: center; +} + +.playback-button.stop { + background-image: url("./assets/cider-icons/stop.svg"); + background-size: 38px; + background-position: center; +} + +.playback-button.play { + background-image: url("./assets/cider-icons/play.svg"); + background-size: 38px; + background-position: center; +} + +.playback-button.next { + background-image: url("./assets/cider-icons/forward.svg"); + background-size: 60%; + background-position: center; +} + +.playback-button.previous { + background-image: url("./assets/cider-icons/backward.svg"); + background-size: 60%; + background-position: center; +} + +.playback-button.disabled, +.playback-button--small.disabled { + opacity: 0.25 !important; + pointer-events: none; + transform: none !important; + + &:hover { + background-color: transparent !important; + transform: none !important; + } +} + +.playback-button { + &.navigation { + display: flex; + justify-content: center; + align-items: center; + color: white; + + > ._svg-icon { + height: 16px; + width: 16px; + pointer-events: none; + } + } +} + +.playback-buttons { + display: flex; + align-items: center; + justify-content: center; +} + +.player-volume-glyph { + width: 32px; + height: 16px; + background-repeat: no-repeat; + background-size: contain; + background-position: center; +} + +.player-volume-glyph.decrease { + background-image: url("./assets/volume.svg"); + opacity: 0.5; +} + +.player-volume-glyph.increase { + background-image: url("./assets/volume-2.svg"); + opacity: 0.5; +} + +.player-track-info { + width: 90%; + margin: 0 auto; +} + +.player-song-title { + font-size: 1.25em; + text-align: left; + margin: 0 auto; + font-weight: 500; +} + +.player-song-artist { + font-size: 1em; + text-align: left; + margin: 0 auto; + color: var(--keyColor); + font-weight: 400; +} + +.player-song-artist:hover { + cursor: pointer; + text-decoration: underline; +} + +.player-more-container { + display: flex; + align-items: center; + justify-content: center; +} + +.player-more-button { + appearance: none; + width: 32px; + height: 32px; + border-radius: 50%; + border: 0px; + background: var(--keyColor); + cursor: pointer; + box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%); + color: white; + font-weight: bold; + padding: 0px; + font-size: 16px; +} + +.back-button { + width: 40px; + height: 40px; + background-color: transparent; + background-size: 16px; + background-position: center; + background-repeat: no-repeat; + background-image: url("./assets/arrow-left.svg"); + border: 0px; + border-radius: 0px; +} + +.header-text { + height: 40px; + display: flex; + align-items: center; +} + +.list-entry-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px; + font-size: 1em; + font-family: inherit; +} + +.list-entry { + display: flex; + align-items: center; + /* justify-content: space-between; */ + padding: 12px; + font-size: 1em; + font-family: inherit; + border-bottom: 1px solid rgba(255 255 255 / 0.1); + cursor: pointer; +} + +.list-entry-image { + --artwork: url(""); + width: 64px; + height: 64px; + background: var(--artwork); + background-size: cover; + background-position: center; + background-repeat: no-repeat; + border-radius: 8px; + box-shadow: + inset 0px 0px 0px 1px rgb(200 200 200 / 16%), + 0 8px 40px rgb(0 0 0 / 0.55); +} + +.list-entry-image.artist { + border-radius: 50%; +} + +.list-entry-body { + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + margin-left: 12px; +} + +.list-entry-name { + font-size: 14px; + font-weight: 500; + overflow: hidden; + width: 100%; +} + +.list-entry-artist { + font-size: 12px; + overflow: hidden; + width: 100%; +} + +.list-entry .handle { + height: 100%; + width: 28px; + background: var(--keyColor); + display: flex; + justify-content: center; + align-items: center; +} + +.artist-chip { + display: inline-flex; + align-items: center; + justify-content: center; + margin: 12px 12px 12px 0px; + border-radius: 4px; + color: white; + font-size: 1em; + font-weight: 500; + cursor: pointer; + + .artist-chip__follow { + appearance: none; + border: 0; + height: 32px; + width: 32px; + background: #ffffff0f; + margin: 0px 0px 0px 10px; + font-weight: bold; + color: white; + border-radius: 100%; + display: flex; + justify-content: center; + align-items: center; + font-size: 12px; + cursor: pointer; + flex: 0 0 32px; + box-shadow: var(--ciderShadow-Generic); + + &:hover { + background: var(--selected); + } + } + + .artist-chip__image { + width: 32px; + height: 32px; + background-size: contain; + background-position: center; + background-repeat: no-repeat; + border-radius: 100%; + overflow: hidden; + margin: 0px 12px 0px 0px; + pointer-events: none; + flex: 0 0 32px; + + .mediaitem-artwork { + border-radius: inherit; + } + } + + .artist-chip__name { + pointer-events: none; + } +} + +.search-panel { + background: rgb(0 0 0 / 50%); +} + +.search-header { + position: absolute; + width: 100%; + z-index: 1; + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border-bottom: 1px solid rgb(200 200 200 / 8%); +} + +.connection-error-panel { + background: rgb(0 0 0 / 50%); +} + +.search-type-container { + display: flex; +} + +.search-type-button { + background: rgb(20 20 20 / 0.85); + border-radius: 50px; + color: white; + border: 0px; + box-shadow: unset; + font-family: inherit; + padding: 8px 16px; + font-size: 14px; + font-weight: 500; + margin: 8px; + margin-top: 0px; + margin-bottom: 0px; +} + +.search-type-button.active { + background: var(--keyColor); +} + +.search-tab-container { + overflow: auto; + white-space: nowrap; + overflow-y: hidden; +} + +.search-body-container { + position: relative; + width: 100%; + height: 100%; +} + +.search-body { + position: absolute; + width: 100%; + height: 100%; + padding-top: 220px; +} + +.search-tab { + background: rgb(20 20 20 / 0.85); + border-radius: 50px; + color: white; + border: 0px; + box-shadow: unset; + font-family: inherit; + padding: 8px 16px; + font-size: 14px; + font-weight: 500; +} + +.search-tab.active { + background: var(--keyColor); +} + +// fancy pills +.fancy-pills { + .nav-pills { + position: relative; + + .nav-link { + transition: transform 0.3s var(--appleEase); + position: relative; + background-color: transparent; + border: 0; + border-radius: 50px; + color: #eee; + -webkit-user-drag: none; + font-weight: 500; + margin: 0px 4px; + + &:after { + --dist: 1px; + content: ""; + position: absolute; + top: var(--dist); + bottom: var(--dist); + left: var(--dist); + right: var(--dist); + // width : 100%; + // height : 100%; + background-color: transparent; + border-radius: 50px; + z-index: -1; + opacity: 0; + transition: + background-color 0.5s var(--appleEase), + opacity 0.25s var(--appleEase), + border-radius 0.32s var(--appleEase); + } + + &:hover { + outline: none; + transform: scale(1.1); + // background: #eee; + background: transparent; + color: #333; + + &:after { + opacity: 1; + background-color: #eee; + transition: + background-color 0.25s var(--appleEase), + border-radius 0.25s var(--appleEase), + color 0s var(--appleEase), + opacity 0s var(--appleEase); + } + } + + &.active { + outline: none; + transform: scale(1.1); + // background: #eee; + background: transparent; + color: #333; + font-weight: 600; + + &:after { + opacity: 1; + background-color: #eee; + } + } + } + + &:hover { + .nav-link.active { + outline: none; + transform: scale(1); + background: transparent; + color: #eee; + transform: scale(1); + + &:after { + background: rgb(200 200 200 / 15%); + opacity: 1; + transition: color 0s; + // border-radius: 5px; + --dist: 4px; + } + + &:hover { + transform: scale(1.1); + z-index: 1; + color: #333; + + &:after { + background: #eee; + border-radius: inherit; + --dist: 1px; + } + } + } + } + + &:after { + content: ""; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + background: rgb(200 200 200 / 10%); + border-radius: 50px; + z-index: 0; + pointer-events: none; + } + } +} + +.grouping-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + + .grouping-btn { + padding: 16px; + appearance: none; + border: 0px; + border-radius: 10px; + background: var(--color1); + color: var(--keyColor); + width: 100%; + text-align: left; + font-family: inherit; + cursor: pointer; + flex: 1 0 21%; + position: relative; + + &:after { + content: "îĒļ"; + position: absolute; + top: 0; + right: 0; + bottom: 0; + font-family: "codicon"; + display: flex; + align-items: center; + width: 28px; + font-weight: bold; + font-size: 1.2em; + pointer-events: none; + } + } +} + +.app-sidebar-header .search-input-container .search-hints-container { + top: 38px; + padding: 3px; +} + +.content-inner { + &.library-page { + .heart-icon { + left: 7px; + } + + .cd-mediaitem-list-item { + padding-left: 25px; + } + } + + &.library-artists-page { + .inner-container .list-container .podcasts-list { + background: rgba(27, 27, 27); + padding-top: 14px; + width: 272px; + + .cd-mediaitem-list-item { + margin-left: 10px; + } + + .cd-mediaitem-list-item:hover { + width: 96%; + } + } + } +} + +.listennow-chip.circle { + border-radius: 50%; + div { + border-radius: 50%; + } + img { + border-radius: 50%; + } +} + +.pagination-container { + display: flex; + justify-content: center; + align-items: center; + gap: 0.5rem; + margin-bottom: 16px; + .md-input-number { + min-width: 12em; + } +} diff --git a/src/renderer/less/fullscreen.less b/src/renderer/less/fullscreen.less new file mode 100644 index 00000000..115bc0a9 --- /dev/null +++ b/src/renderer/less/fullscreen.less @@ -0,0 +1,601 @@ +.fullscreen-view-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: black; + z-index: 99; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; +} + +.fullscreen-view { + width: 100%; + height: 100%; + background: black; + display: flex; + justify-content: center; + align-items: center; + --chromeHeight1: 70px; + + .app-content-container { + width: 100%; + height: 100%; + #app-content { + width: 100%; + height: 100%; + + .fs-search { + .search-input--icon { + width: 4em; + background-size: 40%; + background-position: center; + } + input { + padding-left: 2em; + font-size: 2em; + border-radius: var(--mediaItemRadius); + } + } + } + } + + .fs-header { + position: fixed; + top: 0; + left: 0; + right: 0; + height: var(--chromeHeight1); + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; + + .top-nav-group { + background: #1e1e1e99; + border: 1px solid lighten(@baseColor, 8); + border-radius: 12px; + display: flex; + height: 55px; + width: 90%; + backdrop-filter: var(--glassFilter); + + .app-sidebar-item { + background-color: #1e1e1e00; + border-radius: 10px !important; + border: 0px; + min-width: 120px; + padding: 6px; + justify-content: center; + align-items: center; + margin: 0px; + height: 100%; + position: relative; + font-size: 1.1em; + font-weight: 500; + + &:before { + --dist: 1px; + content: ""; + position: absolute; + top: var(--dist); + left: var(--dist); + right: var(--dist); + bottom: var(--dist); + background-color: #fff; + opacity: 0; + border-radius: 10px; + transform: scale(0.5); + transition: + transform 0.2s ease-in-out, + opacity 0.2s ease-in-out; + } + + &:after { + display: none; + } + + &:hover { + background-color: transparent; + + &:before { + transition: + transform 0.1s ease-in-out, + opacity 0.1s ease-in-out; + opacity: 0.1; + transform: scale(1); + } + } + + &.active { + background-color: transparent; + + &:before { + opacity: 0.2; + transform: scale(1); + } + } + + &.md-btn-primary { + box-shadow: 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8); + background-color: lighten(@baseColor, @colorMixRate * 5); + z-index: 1; + } + } + } + } + + .fs-row { + flex-grow: 0.5; + } + + .playback-button--small.active { + background-color: rgb(200 200 200 / 25%); + } + + .playback-button--small { + opacity: 0.7; + } + + .right-col { + height: 50vh; + } + + .bg-artwork-container { + display: block !important; + } + + @media only screen and (max-width: 1121px) { + .display--large { + display: flex !important; + } + } + + .display--large { + display: flex; + + .slider { + width: 100%; + z-index: 1; + } + + .input-container { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + } + + .volume-button--small { + border-radius: 6px; + color: inherit; + background-size: 16px; + background-repeat: no-repeat; + background-position: center; + background-color: transparent; + height: 15px; + width: 30px; + border: 0px; + box-shadow: unset; + opacity: 0.7; + background-image: url("./assets/feather/volume-2.svg"); + } + + .volume-button--small:active { + transform: scale(0.9); + } + + .volume-button--small.active { + background-image: url("./assets/feather/volume.svg"); + } + + input[type="range"] { + -webkit-appearance: none; + height: 4px; + background: rgba(255, 255, 255, 0.4); + border-radius: 5px; + background-size: 70% 100%; + background-repeat: no-repeat; + + &::-webkit-slider-thumb { + -webkit-appearance: none; + height: 14px; + width: 14px; + border-radius: 50%; + background: rgb(50 50 50); + cursor: default; + box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); + transition: all var(--appleTransition); + } + + &::-webkit-slider-thumb:hover { + background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px); + transform: scale(1.2); + } + + &::-webkit-slider-thumb:active { + background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px); + transform: scale(1); + } + + &::-webkit-slider-runnable-track { + -webkit-appearance: none; + box-shadow: none; + border: none; + background: transparent; + } + } + } + + .background { + position: absolute; + background-size: cover; + width: 100%; + height: 100%; + + .bgArtworkMaterial { + position: absolute; + width: 100%; + height: 100%; + + .bg-artwork-container { + z-index: unset; + } + + .bg-artwork-container .bg-artwork { + filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9); + } + } + } + + .lyrics-col { + height: 62vh; + display: flex; + justify-content: center; + align-content: center; + width: 80%; + + ::-webkit-scrollbar-thumb { + box-shadow: unset; + } + + &:hover ::-webkit-scrollbar-thumb { + box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); + } + + .no-lyrics { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + } + + .lyric-line { + font-size: 35px; + } + } + + .queue-col { + width: 60vh; + height: 62vh; + + .queue-title { + opacity: 0.6; + } + + .queue-panel > * { + z-index: 3; + } + + ::-webkit-scrollbar-thumb { + box-shadow: unset; + } + + &:hover ::-webkit-scrollbar-thumb { + box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); + } + } + + .tab-toggles { + display: flex; + position: absolute; + bottom: 0; + right: 0; + width: 15vh; + height: 5vh; + justify-content: space-evenly; + + .volume { + background-image: url("./assets/feathers/volume.svg"); + padding: 0.5vh; + width: 2vh; + height: 2vh; + background-origin: content-box; + background-repeat: no-repeat; + } + + .queue { + background-image: url("./assets/list.svg"); + padding: 0.5vh; + width: 2.5vh; + height: 2.5vh; + background-origin: content-box; + background-repeat: no-repeat; + } + + .lyrics { + background-image: url("./assets/quote-right.svg"); + padding: 0.5vh; + width: 2.5vh; + height: 2.5vh; + background-origin: content-box; + background-repeat: no-repeat; + } + + .active { + background-color: rgba(200, 200, 200, 0.7); + border-radius: 3px; + } + } + + .artwork-col { + justify-content: center; + align-items: center; + display: flex; + flex-direction: column; + + .artwork { + width: 50vh; + height: 50vh; + } + + .controls-parents { + width: 50vh; + } + + .app-playback-controls { + .song-artist, + .song-name { + font-weight: 600; + text-align: center; + font-size: 0.9em; + height: 1.2em; + line-height: 0.9em; + overflow: hidden; + text-overflow: ellipsis; + max-width: 360px; + + .song-name-normal { + height: inherit; + } + + &.song-artist-marquee { + > marquee { + //margin-bottom: -3px; + } + } + } + + .song-artist { + font-size: 0.875em; + font-weight: 400; + } + + .song-name { + width: unset !important; + margin-top: 0.15vh; + display: -webkit-box; + line-height: 1.2; + text-overflow: ellipsis; + text-align: center; + } + } + + .app-playback-controls .playback-info { + margin-top: 0.5vh; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + position: relative; + + input[type="range"] { + width: 100%; + } + + > div { + width: 100%; + text-align: center; + } + } + + .app-playback-controls .song-progress { + @bgColor: transparent; + //height: 16px; + position: absolute; + bottom: -1.5vh; + left: 0px; + background: @bgColor; + + .song-duration p { + font-weight: 400; + font-size: 10px; + height: 1.2em; + line-height: 1.3em; + overflow: hidden; + margin: 0 0 0 0.25em; + } + + &:hover { + > input[type="range"] { + &::-webkit-slider-thumb { + opacity: 1; + transform: scale(1); + z-index: 1; + } + } + } + + input[type="range"] { + appearance: none; + width: 100%; + height: 4px; + background-color: rgb(200 200 200 / 10%); + border-radius: 2px; + + &::-webkit-slider-thumb { + opacity: 0; + transform: scale(0.5); + -webkit-appearance: none; + appearance: none; + width: 12px; + height: 12px; + border-radius: 100%; + background: var(--songProgressColor); + cursor: default; + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); + } + + &::-moz-range-thumb { + width: 8px; + height: 8px; + border-radius: 100%; + background: var(--songProgressColor); + cursor: default; + } + } + } + + .control-buttons { + margin-top: 2vh; + display: inline-flex; + width: 100%; + justify-content: center; + align-items: center; + } + } + + .cd-mediaitem-square { + font-size: 17px; + font-weight: 500; + } + + .cd-mediaitem-square .artwork-container .artwork { + box-shadow: var(--mediaItemShadow-Shadow); + } + + .cd-mediaitem-list-item { + height: 80px; + } + + .cd-mediaitem-list-item .title { + font-size: 1.2em; + font-weight: 450; + } + + .cd-mediaitem-list-item .subtitle { + font-size: 1.1em; + font-weight: 380; + } + + .cd-mediaitem-list-item .duration { + font-size: 1.2em; + } + + .cd-mediaitem-list-item .artwork { + width: 50px; + height: 50px; + } + + .cd-btn-seeall { + font-size: 1.2em; + } + + h1 { + font-size: 3em; + } + + h3 { + font-size: 1.5rem; + } + + .home-page .well.artistfeed-well { + height: 512px; + } + + .header-text { + font-size: 3em; + height: 3em; + padding-left: 0.2em; + } + + .grouping-container .grouping-btn { + font-size: 1.3em; + color: var(--textColor); + background-color: var(--sidebarColor); + font-weight: 600; + padding: 32px; + //box-shadow: var(--ciderShadow-Generic); + } + + .content-inner.playlist-page { + display: flex; + flex-direction: row; + } + + .playlist-page .playlist-display { + width: 100%; + max-width: 500px; + flex: 1; + text-align: center; + + .playlistInfo { + > .row { + justify-content: center; + } + } + + .playlist-controls { + div { + width: 100%; + } + } + } + .playlist-page .mediaContainer { + width: 30vh; + height: 30vh; + aspect-ratio: 1; + } + .playlist-page .playlist-display .playlistInfo .playlist-info { + gap: 16px; + margin-top: 40px; + } + + .playlist-page .playlist-display .playlistInfo .playlist-hero { + transform: unset; + } + + .artist-page .artist-header { + min-height: 60vh; + } + + .artist-page .artist-image { + width: 20vh; + height: 20vh; + aspect-ratio: 1; + } + + .artist-page.animated .artist-header { + min-height: 80vh; + } + + .playlist-page .playlist-body { + flex: 1; + } +} diff --git a/src/renderer/less/helpers.css b/src/renderer/less/helpers.css new file mode 100644 index 00000000..396c6433 --- /dev/null +++ b/src/renderer/less/helpers.css @@ -0,0 +1,481 @@ +.notyf__toast { + -webkit-app-region: no-drag; + cursor: pointer; +} +.notyf-info { + background: var(--keyColor); +} +.tooltip-inner { + background: #2f2f2f; + opacity: 1; + border: 1px solid rgba(0, 0, 0, 0.35); + transition: all 0.3s ease-in-out; + box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25); +} +.modal-fullscreen { + display: flex; + justify-content: center; + align-items: center; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.3); + z-index: 1000; +} +.modal-fullscreen .modal-window { + background: #333; + border-radius: 10px; + box-shadow: var(--mediaItemShadow-Shadow); + display: flex; + flex-flow: column; + max-height: 500px; + max-width: 360px; + background: #121212; + width: 100%; + position: relative; +} +.modal-fullscreen .modal-window:after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + box-shadow: var(--mediaItemShadow); + z-index: 1; + border-radius: inherit; +} +.modal-fullscreen .modal-window .modal-header { + width: 100%; + padding: 6px; +} +.modal-fullscreen .modal-window .modal-content { + width: 100%; + height: 100%; + overflow: hidden; + overflow-y: overlay; +} +.spatialproperties-panel .modal-window { + overflow: hidden; +} +.spatialproperties-panel .modal-window:not(.airplay-modal) { + height: 700px; + max-height: 700px; + width: 800px; + max-width: 800px; +} +.spatialproperties-panel .modal-window .info-header { + padding-left: 12px; +} +.spatialproperties-panel .modal-window .visual-container { + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; +} +.spatialproperties-panel .modal-window .visual { + position: relative; + height: 250px; + width: 300px; + display: inline-flex; + align-items: flex-end; + justify-content: center; + filter: drop-shadow(2px 12px 6px rgba(0, 0, 0, 0.25)); + margin: 0 auto; +} +.spatialproperties-panel .modal-window .visual .face { + position: absolute; + width: calc(12px * 6); + height: calc(12px * 6); + border-radius: 6px; + transform: rotateX(60deg) rotateZ(-45deg); + transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; +} +.spatialproperties-panel .modal-window .visual .listener { + position: absolute; + width: 32px; + height: 32px; + border-radius: 6px; + transform: rotateX(60deg) rotateZ(-45deg); + transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; + background: white; + color: black; + z-index: 2; +} +.spatialproperties-panel .modal-window .visual .audiosource { + position: absolute; + width: 32px; + height: 32px; + border-radius: 6px; + transform: rotateX(60deg) rotateZ(-45deg); + transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; + background: yellow; + z-index: 2; +} +.spatialproperties-panel .modal-window .visual .face:nth-of-type(1) { + background: linear-gradient(45deg, #28223a, #1f2038); + z-index: 1; +} +.spatialproperties-panel .modal-window .visual .face:nth-of-type(2) { + background: linear-gradient(45deg, #7d53ad, #5763ff); + transform: rotateX(60deg) rotateZ(-45deg) translateZ(30px); + opacity: 0.7; + z-index: 3; +} +.spatialproperties-panel .modal-window .modal-header { + padding: 16px; + position: relative; + overflow: hidden; +} +.spatialproperties-panel .modal-window .modal-header .modal-title { + text-align: center; +} +.spatialproperties-panel .modal-window .modal-header .close-btn { + width: 36px; + height: 36px; + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 10px; + right: 10px; + border-radius: 50px; + display: grid; + align-content: center; +} +.spatialproperties-panel .modal-window .modal-header .close-btn:before { + content: "îŠļ"; + font-family: "codicon"; + color: var(--textColor); + font-size: 20px; +} +.spatialproperties-panel .modal-window .modal-header .close-btn:hover { + background-color: #c42b1c; +} +.addtoplaylist-panel .modal-window { + max-height: 600px; + max-width: 400px; + background: rgba(18, 18, 18, 0.9); + overflow: hidden; + backdrop-filter: blur(16px) saturate(180%); +} +.addtoplaylist-panel .modal-window .modal-header { + padding: 16px; + position: relative; +} +.addtoplaylist-panel .modal-window .modal-header .modal-title { + text-align: center; +} +.addtoplaylist-panel .modal-window .modal-header .close-btn { + width: 36px; + height: 36px; + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 10px; + right: 10px; + border-radius: 50px; + display: grid; + align-content: center; +} +.addtoplaylist-panel .modal-window .modal-header .close-btn:before { + content: "îŠļ"; + font-family: "codicon"; + color: var(--textColor); + font-size: 20px; +} +.addtoplaylist-panel .modal-window .modal-header .close-btn:hover { + background-color: #c42b1c; +} +.addtoplaylist-panel .modal-window .modal-search { + width: 100%; + padding: 0px 16px; + position: relative; +} +.addtoplaylist-panel .modal-window .playlist-item { + appearance: none; + border: 0px; + text-align: left; + width: 100%; + margin: 0; + display: flex; + background: rgba(32, 32, 32, 0.46); + color: #eee; + font-family: inherit; + font-size: 0.98em; + padding: 6px 12px; + align-items: center; + flex-flow: row; +} +.addtoplaylist-panel .modal-window .playlist-item .icon { + pointer-events: none; + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + margin-right: 6px; +} +.addtoplaylist-panel .modal-window .playlist-item .name { + position: relative; +} +.addtoplaylist-panel .modal-window .playlist-item:hover { + background: var(--selected); +} +.addtoplaylist-panel .modal-window .playlist-item:active { + background: var(--selected-click); +} +.addtoplaylist-panel .modal-window .playlist-item.focused { + background: var(--keyColor); +} +.addtoplaylist-panel .modal-window .playlist-item:last-child { + border-bottom: 0px; +} +.menu-panel { + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + z-index: 100001; + display: flex; + justify-content: center; + align-items: center; + -webkit-app-region: no-drag; +} +.menu-panel .menu-header-body { + padding: 6px; + display: flex; + background: rgba(200, 200, 200, 0.1); +} +.menu-panel .menu-header-body .menu-option-header { + width: 40px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; + border-radius: var(--mediaItemRadius); + appearance: none; + border: 0; + background: transparent; +} +.menu-panel .menu-header-body .menu-option-header.active .sidebar-icon > .svg-icon { + --color: var(--keyColor); +} +.menu-panel .menu-header-body .menu-option-header:hover { + background: var(--selected); +} +.menu-panel .menu-header-body .menu-option-header:active { + background: var(--selected-click); +} +.menu-panel .menu-panel-body { + display: flex; + flex-flow: column; + background: rgba(30, 30, 30, 0.45); + backdrop-filter: blur(32px) saturate(180%); + position: relative; + min-width: 200px; + box-shadow: var(--ciderShadow-Generic); + border-radius: var(--panelRadius); + overflow: hidden; + font-size: 13px; +} +.menu-panel .menu-panel-body .menu-option { + text-align: left; + display: flex; + appearance: none; + border: 0px; + font: inherit; + background: transparent; + color: inherit; + margin: 0 auto; + position: relative; + width: 100%; + padding: 9px 14px; + align-items: center; +} +.menu-panel .menu-panel-body .menu-option::before { + background: var(--hover); + border-radius: 6px; + content: ""; + --sizeY: 3px; + --sizeX: 4px; + top: var(--sizeY); + left: var(--sizeX); + bottom: var(--sizeY); + right: var(--sizeX); + position: absolute; + opacity: 0; + transform: scale(0.98); + z-index: -1; + transition: transform 0.25s ease-out, opacity 0.25s ease-out; +} +.menu-panel .menu-panel-body .menu-option:hover::before { + transition: transform 0s ease-in, opacity 0s ease-in; + opacity: 1; + transform: scale(1); +} +.menu-panel .menu-panel-body .menu-option:active::before { + transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out; + opacity: 1; + transform: scale(0.98); + background: var(--selected-click); +} +.menu-panel .menu-header-text { + margin: 18px 6px; +} +.menu-panel .menu-header-text .close-btn { + width: 36px; + height: 36px; + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 10px; + right: 10px; + border-radius: 50px; + display: grid; + align-content: center; +} +.menu-panel .menu-header-text .close-btn:before { + content: "îŠļ"; + font-family: "codicon"; + color: var(--textColor); + font-size: 20px; +} +.menu-panel .menu-header-text .close-btn:hover { + background-color: #c42b1c; +} +.menu-panel .menu-body { + overflow: overlay; + height: 100%; + display: flex; + flex-flow: column; + gap: 0px; + padding: 0px; + position: relative; +} +.menu-panel .menu-footer { + width: 100%; + padding: 12px; +} +.queue-panel { + height: 100%; + width: 100%; + display: flex; + flex-flow: column; +} +.queue-panel .queue-header-text { + margin: 18px 6px; +} +.queue-panel .queue-body { + overflow: overlay; + height: 100%; +} +.queue-panel .queue-footer { + width: 100%; + padding: 12px; +} +.queue-panel .autoplay { + background: rgba(200, 200, 200, 0.15); + display: flex; + justify-content: center; + appearance: none; + border: 0; + border-radius: 6px; + height: 32px; + width: 32px; +} +.queue-panel .infinity { + content: url("assets/infinity.svg"); + margin: auto; +} +.moreinfo-modal .modal-window { + height: 70%; + max-height: 100%; + width: 45%; + max-width: 100%; + overflow: hidden; + line-height: 1.25; +} +.moreinfo-modal .modal-content { + padding: 1em; + font-size: 0.8rem; +} +.moreinfo-modal .modal-content br { + display: block; + /* makes it have a width */ + content: ""; + /* clears default height */ + margin: 2em; + margin-bottom: -0.6rem; +} +.moreinfo-modal .modal-header { + flex-direction: column; +} +.moreinfo-modal .modal-header .modal-title { + text-align: unset !important; + width: 100%; +} +.moreinfo-modal .modal-header .modal-title:not(.modal-subtitle) { + font-size: 25px; +} +.mediainfo-popover { + user-select: none; + background-color: #000000; + overflow: hidden; +} +.mediainfo-popover .content .shadow-artwork { + height: 100%; + width: 100%; + position: absolute; + top: 0; + left: 0; + z-index: -1; + filter: blur(32px) brightness(50%) saturate(280%); +} +.mediainfo-popover .content .popover-artwork { + width: 200px; + height: 200px; + margin: 0 auto; + margin-bottom: 20px; +} +.mediainfo-popover .content .song-name { + font-weight: 600; +} +.mediainfo-popover .content .song-artist, +.mediainfo-popover .content .song-album { + opacity: 0.75; + cursor: pointer; +} +.mediainfo-popover .content .song-artist:hover, +.mediainfo-popover .content .song-album:hover { + text-decoration: underline; +} +._svg-icon { + --icon: url("assets/chevron-left.svg"); + --size: 1em; + width: var(--size); + height: var(--size); + -webkit-mask-image: var(--icon); + -webkit-mask-position: center; + -webkit-mask-size: contain; + background: rgba(255, 255, 255, 0.76); + -webkit-mask-repeat: no-repeat; +} +._svg-icon.svg-md { + --size: 1.2em; +} diff --git a/src/renderer/less/helpers.less b/src/renderer/less/helpers.less new file mode 100644 index 00000000..07018ef9 --- /dev/null +++ b/src/renderer/less/helpers.less @@ -0,0 +1,537 @@ +.notyf__toast { + -webkit-app-region: no-drag; + cursor: pointer; +} + +.notyf-info { + background: var(--keyColor); +} + +.tooltip-inner { + background: #2f2f2f; + opacity: 1; + border: 1px solid rgb(0 0 0 / 35%); + transition: all 0.3s ease-in-out; + box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25); +} + +.modal-fullscreen { + display: flex; + justify-content: center; + align-items: center; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.3); + z-index: 1000; + + .modal-window { + background: #333; + border-radius: 10px; + box-shadow: var(--mediaItemShadow-Shadow); + display: flex; + flex-flow: column; + max-height: 500px; + max-width: 360px; + background: #121212; + width: 100%; + position: relative; + + &:after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + box-shadow: var(--mediaItemShadow); + z-index: 1; + border-radius: inherit; + } + + .modal-header { + width: 100%; + padding: 6px; + } + + .modal-content { + width: 100%; + height: 100%; + overflow: hidden; + overflow-y: overlay; + } + + .modal-footer { + } + } +} + +.spatialproperties-panel { + .modal-window { + &:not(.airplay-modal) { + height: 700px; + max-height: 700px; + width: 800px; + max-width: 800px; + } + + overflow: hidden; + + .info-header { + padding-left: 12px; + } + + .visual-container { + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; + } + + .visual { + position: relative; + height: 250px; + width: 300px; + display: inline-flex; + align-items: flex-end; + justify-content: center; + filter: drop-shadow(2px 12px 6px rgb(0 0 0 / 25%)); + margin: 0 auto; + + .face { + position: absolute; + width: calc(12px * 6); + height: calc(12px * 6); + border-radius: 6px; + transform: rotateX(60deg) rotateZ(-45deg); + transition: + transform 0.2s linear, + width 0.2s linear, + height 0.2s linear; + } + + .listener { + position: absolute; + width: 32px; + height: 32px; + border-radius: 6px; + transform: rotateX(60deg) rotateZ(-45deg); + transition: + transform 0.2s linear, + width 0.2s linear, + height 0.2s linear; + background: white; + color: black; + z-index: 2; + } + + .audiosource { + position: absolute; + width: 32px; + height: 32px; + border-radius: 6px; + transform: rotateX(60deg) rotateZ(-45deg); + transition: + transform 0.2s linear, + width 0.2s linear, + height 0.2s linear; + background: yellow; + z-index: 2; + } + + .face:nth-of-type(1) { + background: linear-gradient(45deg, #28223a, #1f2038); + z-index: 1; + } + + .face:nth-of-type(2) { + background: linear-gradient(45deg, #7d53ad, #5763ff); + transform: rotateX(60deg) rotateZ(-45deg) translateZ(30px); + opacity: 0.7; + z-index: 3; + } + } + + .modal-header { + padding: 16px; + position: relative; + overflow: hidden; + + .modal-title { + text-align: center; + } + + .close-btn { + .menu-panel.menu-header-text.close-btn; + } + } + } +} + +.addtoplaylist-panel { + .modal-window { + max-height: 600px; + max-width: 400px; + background: rgb(18 18 18 / 90%); + overflow: hidden; + backdrop-filter: blur(16px) saturate(180%); + + .modal-header { + padding: 16px; + position: relative; + + .modal-title { + text-align: center; + } + + .close-btn { + .menu-panel.menu-header-text.close-btn; + } + } + + .modal-search { + width: 100%; + padding: 0px 16px; + position: relative; + } + + .playlist-item { + appearance: none; + border: 0px; + text-align: left; + width: 100%; + margin: 0; + display: flex; + background: rgba(32, 32, 32, 0.46); + color: #eee; + font-family: inherit; + font-size: 0.98em; + padding: 6px 12px; + align-items: center; + flex-flow: row; + + .icon { + pointer-events: none; + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + margin-right: 6px; + } + + .name { + position: relative; + } + + &:hover { + background: var(--selected); + } + + &:active { + background: var(--selected-click); + } + + &.focused { + background: var(--keyColor); + } + } + + .playlist-item:last-child { + border-bottom: 0px; + } + } +} + +.menu-panel { + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + z-index: 100001; + display: flex; + justify-content: center; + align-items: center; + -webkit-app-region: no-drag; + + .menu-header-body { + padding: 6px; + display: flex; + background: rgb(200 200 200 / 10%); + + .menu-option-header { + width: 40px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; + border-radius: var(--mediaItemRadius); + appearance: none; + border: 0; + background: transparent; + + &.active { + .sidebar-icon > .svg-icon { + --color: var(--keyColor); + } + } + + &:hover { + background: var(--selected); + } + + &:active { + background: var(--selected-click); + } + } + } + + .menu-panel-body { + display: flex; + flex-flow: column; + background: rgb(30 30 30 / 45%); + backdrop-filter: blur(32px) saturate(180%); + position: relative; + min-width: 200px; + box-shadow: var(--ciderShadow-Generic); + border-radius: var(--panelRadius); + overflow: hidden; + font-size: 13px; + + .menu-option { + text-align: left; + display: flex; + appearance: none; + border: 0px; + font: inherit; + background: transparent; + color: inherit; + margin: 0 auto; + position: relative; + width: 100%; + padding: 9px 14px; + align-items: center; + + &::before { + background: var(--hover); + border-radius: 6px; + content: ""; + --sizeY: 3px; + --sizeX: 4px; + top: var(--sizeY); + left: var(--sizeX); + bottom: var(--sizeY); + right: var(--sizeX); + position: absolute; + opacity: 0; + transform: scale(0.98); + z-index: -1; + transition: + transform 0.25s ease-out, + opacity 0.25s ease-out; + } + + &:hover { + &::before { + transition: + transform 0s ease-in, + opacity 0s ease-in; + opacity: 1; + transform: scale(1); + } + } + + &:active { + &::before { + transition: + transform 0.1s ease-in-out, + opacity 0.1s ease-in-out; + opacity: 1; + transform: scale(0.98); + background: var(--selected-click); + } + } + } + } + + .menu-header-text { + margin: 18px 6px; + + .close-btn { + width: 36px; + height: 36px; + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 10px; + right: 10px; + border-radius: 50px; + display: grid; + align-content: center; + + &:before { + content: "îŠļ"; + font-family: "codicon"; + color: var(--textColor); + font-size: 20px; + } + + &:hover { + background-color: rgb(196, 43, 28); + } + } + } + + .menu-body { + overflow: overlay; + height: 100%; + display: flex; + flex-flow: column; + gap: 0px; + padding: 0px; + position: relative; + } + + .menu-footer { + width: 100%; + padding: 12px; + } +} + +.queue-panel { + height: 100%; + width: 100%; + display: flex; + flex-flow: column; + + .queue-header-text { + margin: 18px 6px; + } + + .queue-body { + overflow: overlay; + height: 100%; + } + + .queue-footer { + width: 100%; + padding: 12px; + } + + .autoplay { + background: rgb(200 200 200 / 15%); + display: flex; + justify-content: center; + appearance: none; + border: 0; + border-radius: 6px; + height: 32px; + width: 32px; + } + + .infinity { + content: url("./assets/infinity.svg"); + margin: auto; + } +} + +.moreinfo-modal { + .modal-window { + height: 70%; + max-height: 100%; + width: 45%; + max-width: 100%; + overflow: hidden; + line-height: 1.25; + } + + .modal-content { + padding: 1em; + font-size: 0.8rem; + + br { + display: block; + /* makes it have a width */ + content: ""; + /* clears default height */ + margin: 2em; + margin-bottom: -0.6rem; + } + } + + .modal-header { + flex-direction: column; + + .modal-title { + text-align: unset !important; + width: 100%; + + &:not(.modal-subtitle) { + font-size: 25px; + } + } + } +} + +.mediainfo-popover { + user-select: none; + background-color: rgb(0 0 0 / 100%); + overflow: hidden; + + .content { + .shadow-artwork { + height: 100%; + width: 100%; + position: absolute; + top: 0; + left: 0; + z-index: -1; + filter: blur(32px) brightness(50%) saturate(280%); + } + + .popover-artwork { + width: 200px; + height: 200px; + margin: 0 auto; + margin-bottom: 20px; + } + + .song-name { + font-weight: 600; + } + + .song-artist, + .song-album { + opacity: 0.75; + cursor: pointer; + + &:hover { + text-decoration: underline; + } + } + } +} + +._svg-icon { + --icon: url("./assets/chevron-left.svg"); + --size: 1em; + width: var(--size); + height: var(--size); + -webkit-mask-image: var(--icon); + -webkit-mask-position: center; + -webkit-mask-size: contain; + background: rgb(255 255 255 / 76%); + -webkit-mask-repeat: no-repeat; + + &.svg-md { + --size: 1.2em; + } +} diff --git a/src/renderer/less/linux.less b/src/renderer/less/linux.less new file mode 100644 index 00000000..a701f625 --- /dev/null +++ b/src/renderer/less/linux.less @@ -0,0 +1,59 @@ +// Linux +body[platform="linux"] { + #window-controls-container { + //display: none; + } + + .window-controls { + justify-content: flex-end; + align-items: center; + padding-right: 6px; + + > div { + --iconSize: 16px; + + &.close, + &.minmax, + &.minimize, + &.minmax.restore { + background-image: unset !important; + position: relative; + display: grid; + align-content: center; + text-align: center; + height: 36px !important; + width: 36px !important; + border-radius: 50px; + transition: background-color 0.1s ease-in-out; + + &:hover { + background: rgb(200 200 200 / 10%) !important; + } + } + + &.close::before { + font-family: "codicon"; + font-size: var(--iconSize); + content: "îǏ"; + } + + &.minmax::before { + font-family: "codicon"; + font-size: var(--iconSize); + content: "îĒš"; + } + + &.minimize::before { + font-family: "codicon"; + font-size: var(--iconSize); + content: "îĒē"; + } + + &.restore::before { + font-family: "codicon"; + font-size: var(--iconSize); + content: "îĒģ"; + } + } + } +} diff --git a/src/renderer/less/macos.less b/src/renderer/less/macos.less new file mode 100644 index 00000000..d254b449 --- /dev/null +++ b/src/renderer/less/macos.less @@ -0,0 +1,79 @@ +body[platform="darwin"] { + html { + background: transparent !important; + } + + &.notransparency::before { + display: none; + } + + #app { + &.simplebg { + background: transparent; + } + + &::before { + display: none; + } + + .app-chrome { + background-color: var(--macOSChromeColor); + } + + &.twopanel { + --chromeHeight1: 55px; + --chromeHeight: calc(var(--chromeHeight1) + var(--chromeHeight2)); + + .app-chrome .app-chrome-item.search { + margin-right: 12px; + } + + .app-chrome .app-mainmenu { + width: 46px; + } + + .app-chrome.chrome-bottom { + background-color: var(--macOSChromeColor); + } + } + + &[window-state="normal"] { + &::after { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + box-shadow: inset 0px 0px 0.5px 1px rgb(200 200 200 / 40%); + border-radius: 10px; + content: " "; + z-index: 999999; + pointer-events: none; + } + } + } + + #app-main { + background-color: transparent; + + .app-navigation { + background: transparent; + } + + #app-content { + background-color: #1e1e1e6b; + } + } + + .settings-window.maxed { + .tabs > .col-auto { + transition: padding-top 0.3s linear; + padding-top: var(--chromeHeight1); + } + } + + #apple-music-video-player-controls #player-exit { + margin-top: 18px; + left: 70px; + } +} diff --git a/src/renderer/less/macosemu.less b/src/renderer/less/macosemu.less new file mode 100644 index 00000000..d0569415 --- /dev/null +++ b/src/renderer/less/macosemu.less @@ -0,0 +1,46 @@ +#app.macosemu { + .app-chrome .app-chrome-item > .window-controls-macos { + @controlSize: 12px; + display: flex; + justify-content: center; + align-items: center; + width: 96px; + @closeClr: rgb(255, 92, 92); + @minmaxClr: rgb(77, 202, 77); + @minClr: rgb(255, 189, 76); + @borderDarken: 55%; + + div { + margin: 4px; + background-color: red; + border-radius: 100%; + flex: 0 0 auto; + background-image: unset !important; + //border: 1px solid white; + &.close { + box-shadow: 0px 0px 0px 1px darken(@closeClr, @borderDarken); + background-color: @closeClr; + width: @controlSize; + height: @controlSize; + } + + &.minimize { + box-shadow: 0px 0px 0px 1px darken(@minClr, @borderDarken); + background-color: @minClr; + width: @controlSize; + height: @controlSize; + } + + &.minmax { + box-shadow: 0px 0px 0px 1px darken(@minmaxClr, 45%); + background-color: @minmaxClr; + width: @controlSize; + height: @controlSize; + } + } + } + .usermenu-body { + left: calc(100vw - 260px); + position: relative; + } +} diff --git a/src/renderer/less/miniplayer.less b/src/renderer/less/miniplayer.less new file mode 100644 index 00000000..8d38f9cb --- /dev/null +++ b/src/renderer/less/miniplayer.less @@ -0,0 +1,404 @@ +.mini-view { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + + .fs-row { + flex-grow: 1; + } + + .playback-button--small.active { + background-color: rgb(200 200 200 / 25%); + } + + .player-exit { + z-index: 3; + position: absolute; + top: 5px; + right: 5px; + -webkit-app-region: no-drag; + } + + .player-pin { + z-index: 3; + position: absolute; + min-width: 20px; + min-height: 20px; + top: 5px; + right: 30px; + -webkit-app-region: no-drag; + } + + #mini-pin { + display: none; + } + + .player-pin:hover #mini-pin { + display: block; + } + + .playback-button--small { + opacity: 0.7; + } + + .right-col { + height: 50vh; + } + + @media only screen and (max-width: 1121px) { + .display--large { + display: flex !important; + } + } + + .display--large { + display: flex; + + .slider { + width: 100%; + z-index: 1; + } + + .input-container { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + } + + .volume-button--small { + border-radius: 6px; + color: inherit; + background-size: 16px; + background-repeat: no-repeat; + background-position: center; + background-color: transparent; + height: 15px; + width: 30px; + border: 0px; + box-shadow: unset; + opacity: 0.7; + background-image: url("./assets/feather/volume-2.svg"); + } + + .volume-button--small:active { + transform: scale(0.9); + } + + .volume-button--small.active { + background-image: url("./assets/feather/volume.svg"); + } + + input[type="range"] { + -webkit-appearance: none; + height: 4px; + background: rgba(255, 255, 255, 0.4); + border-radius: 5px; + background-size: 70% 100%; + background-repeat: no-repeat; + + &::-webkit-slider-thumb { + -webkit-appearance: none; + height: 14px; + width: 14px; + border-radius: 50%; + background: rgb(50 50 50); + cursor: default; + box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); + transition: all var(--appleTransition); + } + + &::-webkit-slider-thumb:hover { + background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px); + transform: scale(1.2); + } + + &::-webkit-slider-thumb:active { + background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px); + transform: scale(1); + } + + &::-webkit-slider-runnable-track { + -webkit-appearance: none; + box-shadow: none; + border: none; + background: transparent; + } + } + } + + .background { + position: absolute; + background-size: cover; + width: 100%; + height: 100%; + -webkit-user-select: none; + -webkit-app-region: drag; + + .bgArtworkMaterial { + position: absolute; + width: 100%; + height: 100%; + + .bg-artwork-container { + z-index: unset; + } + + .bg-artwork-container .bg-artwork { + filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9); + } + + .no-animation { + animation: unset; + } + } + } + + .lyrics-col { + height: 62vh; + display: flex; + justify-content: center; + align-content: center; + width: 80%; + + ::-webkit-scrollbar-thumb { + box-shadow: unset; + } + + &:hover ::-webkit-scrollbar-thumb { + box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); + } + + .no-lyrics { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + } + + .lyric-line { + font-size: 35px; + } + } + + .queue-col { + width: 60vh; + height: 50vh; + + .queue-title { + opacity: 0.6; + } + + .queue-panel > * { + z-index: 3; + } + + ::-webkit-scrollbar-thumb { + box-shadow: unset; + } + + &:hover ::-webkit-scrollbar-thumb { + box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); + } + } + + .tab-toggles { + display: flex; + position: absolute; + bottom: 0; + right: 0; + width: 15vh; + height: 5vh; + justify-content: space-evenly; + + .volume { + background-image: url("./assets/feathers/volume.svg"); + padding: 0.5vh; + width: 2vh; + height: 2vh; + background-origin: content-box; + background-repeat: no-repeat; + } + + .queue { + background-image: url("./assets/list.svg"); + padding: 0.5vh; + width: 2.5vh; + height: 2.5vh; + background-origin: content-box; + background-repeat: no-repeat; + } + + .lyrics { + background-image: url("./assets/quote-right.svg"); + padding: 0.5vh; + width: 2.5vh; + height: 2.5vh; + background-origin: content-box; + background-repeat: no-repeat; + } + + .active { + background-color: rgba(200, 200, 200, 0.7); + border-radius: 3px; + } + } + + .artwork-col { + justify-content: center; + align-items: center; + display: flex; + flex-direction: column; + + .artwork { + width: 100%; + height: 100%; + + .mediaitem-artwork { + border-radius: unset; + } + } + + .controls-parents { + width: 100%; + position: absolute; + background: #0000009e; + backdrop-filter: blur(10px); + bottom: 0px; + z-index: 3; + opacity: 0; + padding: 3%; + + &:hover { + opacity: 1; + } + } + + .app-playback-controls { + -webkit-app-region: no-drag; + + .song-artist, + .song-name { + font-weight: 600; + text-align: center; + font-size: 0.9em; + height: 1.2em; + line-height: 0.9em; + overflow: hidden; + text-overflow: ellipsis; + max-width: 360px; + + .song-name-normal { + height: inherit; + } + + &.song-artist-marquee { + > marquee { + //margin-bottom: -3px; + } + } + } + + .song-artist { + font-size: 0.875em; + font-weight: 400; + } + + .song-name { + width: unset !important; + margin-top: 0.15vh; + display: -webkit-box; + line-height: 1.2; + text-overflow: ellipsis; + text-align: center; + } + } + + .app-playback-controls .playback-info { + margin-top: 0.5vh; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + position: relative; + + input[type="range"] { + width: 100%; + } + + > div { + width: 100%; + text-align: center; + } + } + + .app-playback-controls .song-progress { + @bgColor: transparent; + //height: 16px; + position: absolute; + bottom: -3.5vh; + left: 0px; + background: @bgColor; + + .song-duration p { + font-weight: 400; + font-size: 10px; + height: 1.2em; + line-height: 1.3em; + overflow: hidden; + margin: 0 0 0 0.25em; + } + + &:hover { + > input[type="range"] { + &::-webkit-slider-thumb { + opacity: 1; + transform: scale(1); + z-index: 1; + } + } + } + + input[type="range"] { + appearance: none; + width: 100%; + height: 4px; + background-color: rgb(200 200 200 / 10%); + border-radius: 2px; + + &::-webkit-slider-thumb { + opacity: 0; + transform: scale(0.5); + -webkit-appearance: none; + appearance: none; + width: 12px; + height: 12px; + border-radius: 100%; + background: var(--songProgressColor); + cursor: default; + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); + } + + &::-moz-range-thumb { + width: 8px; + height: 8px; + border-radius: 100%; + background: var(--songProgressColor); + cursor: default; + } + } + } + + .control-buttons { + margin-top: 3.5vh; + display: inline-flex; + width: 100%; + justify-content: center; + } + } +} diff --git a/src/renderer/less/notyf.less b/src/renderer/less/notyf.less index 3131210d..d4ec8d0d 100644 --- a/src/renderer/less/notyf.less +++ b/src/renderer/less/notyf.less @@ -1,370 +1,372 @@ @-webkit-keyframes notyf-fadeinup { - 0% { - opacity: 0; - transform: translateY(25%) - } + 0% { + opacity: 0; + transform: translateY(25%); + } - to { - opacity: 1; - transform: translateY(0) - } + to { + opacity: 1; + transform: translateY(0); + } } @keyframes notyf-fadeinup { - 0% { - opacity: 0; - transform: translateY(25%) - } + 0% { + opacity: 0; + transform: translateY(25%); + } - to { - opacity: 1; - transform: translateY(0) - } + to { + opacity: 1; + transform: translateY(0); + } } @-webkit-keyframes notyf-fadeinleft { - 0% { - opacity: 0; - transform: translateX(25%) - } + 0% { + opacity: 0; + transform: translateX(25%); + } - to { - opacity: 1; - transform: translateX(0) - } + to { + opacity: 1; + transform: translateX(0); + } } @keyframes notyf-fadeinleft { - 0% { - opacity: 0; - transform: translateX(25%) - } + 0% { + opacity: 0; + transform: translateX(25%); + } - to { - opacity: 1; - transform: translateX(0) - } + to { + opacity: 1; + transform: translateX(0); + } } @-webkit-keyframes notyf-fadeoutright { - 0% { - opacity: 1; - transform: translateX(0) - } + 0% { + opacity: 1; + transform: translateX(0); + } - to { - opacity: 0; - transform: translateX(25%) - } + to { + opacity: 0; + transform: translateX(25%); + } } @keyframes notyf-fadeoutright { - 0% { - opacity: 1; - transform: translateX(0) - } + 0% { + opacity: 1; + transform: translateX(0); + } - to { - opacity: 0; - transform: translateX(25%) - } + to { + opacity: 0; + transform: translateX(25%); + } } @-webkit-keyframes notyf-fadeoutdown { - 0% { - opacity: 1; - transform: translateY(0) - } + 0% { + opacity: 1; + transform: translateY(0); + } - to { - opacity: 0; - transform: translateY(25%) - } + to { + opacity: 0; + transform: translateY(25%); + } } @keyframes notyf-fadeoutdown { - 0% { - opacity: 1; - transform: translateY(0) - } + 0% { + opacity: 1; + transform: translateY(0); + } - to { - opacity: 0; - transform: translateY(25%) - } + to { + opacity: 0; + transform: translateY(25%); + } } @-webkit-keyframes ripple { - 0% { - transform: scale(0) translateY(-45%) translateX(13%) - } + 0% { + transform: scale(0) translateY(-45%) translateX(13%); + } - to { - transform: scale(1) translateY(-45%) translateX(13%) - } + to { + transform: scale(1) translateY(-45%) translateX(13%); + } } @keyframes ripple { - 0% { - transform: scale(0) translateY(-45%) translateX(13%) - } + 0% { + transform: scale(0) translateY(-45%) translateX(13%); + } - to { - transform: scale(1) translateY(-45%) translateX(13%) - } + to { + transform: scale(1) translateY(-45%) translateX(13%); + } } .notyf { - position: fixed; - top: 0; - left: 0; - height: 100%; - width: 100%; - color: #fff; - z-index: 9999; - display: flex; - flex-direction: column; - align-items: flex-end; - justify-content: flex-end; - pointer-events: none; - box-sizing: border-box; - padding: 20px + position: fixed; + top: 0; + left: 0; + height: 100%; + width: 100%; + color: #fff; + z-index: 9999; + display: flex; + flex-direction: column; + align-items: flex-end; + justify-content: flex-end; + pointer-events: none; + box-sizing: border-box; + padding: 20px; } .notyf__icon--error, .notyf__icon--success { - height: 21px; - width: 21px; - background: #fff; - border-radius: 50%; - display: block; - margin: 0 auto; - position: relative + height: 21px; + width: 21px; + background: #fff; + border-radius: 50%; + display: block; + margin: 0 auto; + position: relative; } .notyf__icon--error:after, .notyf__icon--error:before { - content: ""; - background: currentColor; - display: block; - position: absolute; - width: 3px; - border-radius: 3px; - left: 9px; - height: 12px; - top: 5px + content: ""; + background: currentColor; + display: block; + position: absolute; + width: 3px; + border-radius: 3px; + left: 9px; + height: 12px; + top: 5px; } .notyf__icon--error:after { - transform: rotate(-45deg) + transform: rotate(-45deg); } .notyf__icon--error:before { - transform: rotate(45deg) + transform: rotate(45deg); } .notyf__icon--success:after, .notyf__icon--success:before { - content: ""; - background: currentColor; - display: block; - position: absolute; - width: 3px; - border-radius: 3px + content: ""; + background: currentColor; + display: block; + position: absolute; + width: 3px; + border-radius: 3px; } .notyf__icon--success:after { - height: 6px; - transform: rotate(-45deg); - top: 9px; - left: 6px + height: 6px; + transform: rotate(-45deg); + top: 9px; + left: 6px; } .notyf__icon--success:before { - height: 11px; - transform: rotate(45deg); - top: 5px; - left: 10px + height: 11px; + transform: rotate(45deg); + top: 5px; + left: 10px; } .notyf__toast { - display: block; - overflow: hidden; - pointer-events: auto; - -webkit-animation: notyf-fadeinup .3s ease-in forwards; - animation: notyf-fadeinup .3s ease-in forwards; - box-shadow: 0 3px 7px 0 rgba(0, 0, 0, .25); - position: relative; - padding: 0 15px; - border-radius: 2px; - max-width: 300px; - transform: translateY(25%); - box-sizing: border-box; - flex-shrink: 0 + display: block; + overflow: hidden; + pointer-events: auto; + -webkit-animation: notyf-fadeinup 0.3s ease-in forwards; + animation: notyf-fadeinup 0.3s ease-in forwards; + box-shadow: 0 3px 7px 0 rgba(0, 0, 0, 0.25); + position: relative; + padding: 0 15px; + border-radius: 2px; + max-width: 300px; + transform: translateY(25%); + box-sizing: border-box; + flex-shrink: 0; } .notyf__toast--disappear { - transform: translateY(0); - -webkit-animation: notyf-fadeoutdown .3s forwards; - animation: notyf-fadeoutdown .3s forwards; - -webkit-animation-delay: .25s; - animation-delay: .25s + transform: translateY(0); + -webkit-animation: notyf-fadeoutdown 0.3s forwards; + animation: notyf-fadeoutdown 0.3s forwards; + -webkit-animation-delay: 0.25s; + animation-delay: 0.25s; } .notyf__toast--disappear .notyf__icon, .notyf__toast--disappear .notyf__message { - -webkit-animation: notyf-fadeoutdown .3s forwards; - animation: notyf-fadeoutdown .3s forwards; - opacity: 1; - transform: translateY(0) + -webkit-animation: notyf-fadeoutdown 0.3s forwards; + animation: notyf-fadeoutdown 0.3s forwards; + opacity: 1; + transform: translateY(0); } .notyf__toast--disappear .notyf__dismiss { - -webkit-animation: notyf-fadeoutright .3s forwards; - animation: notyf-fadeoutright .3s forwards; - opacity: 1; - transform: translateX(0) + -webkit-animation: notyf-fadeoutright 0.3s forwards; + animation: notyf-fadeoutright 0.3s forwards; + opacity: 1; + transform: translateX(0); } .notyf__toast--disappear .notyf__message { - -webkit-animation-delay: .05s; - animation-delay: .05s + -webkit-animation-delay: 0.05s; + animation-delay: 0.05s; } .notyf__toast--upper { - margin-bottom: 20px + margin-bottom: 20px; } .notyf__toast--lower { - margin-top: 20px + margin-top: 20px; } .notyf__toast--dismissible .notyf__wrapper { - padding-right: 30px + padding-right: 30px; } .notyf__ripple { - height: 400px; - width: 400px; - position: absolute; - transform-origin: bottom right; - right: 0; - top: 0; - border-radius: 50%; - transform: scale(0) translateY(-51%) translateX(13%); - z-index: 5; - -webkit-animation: ripple .4s ease-out forwards; - animation: ripple .4s ease-out forwards + height: 400px; + width: 400px; + position: absolute; + transform-origin: bottom right; + right: 0; + top: 0; + border-radius: 50%; + transform: scale(0) translateY(-51%) translateX(13%); + z-index: 5; + -webkit-animation: ripple 0.4s ease-out forwards; + animation: ripple 0.4s ease-out forwards; } .notyf__wrapper { - display: flex; - align-items: center; - padding-top: 17px; - padding-bottom: 17px; - padding-right: 15px; - border-radius: 3px; - position: relative; - z-index: 10 + display: flex; + align-items: center; + padding-top: 17px; + padding-bottom: 17px; + padding-right: 15px; + border-radius: 3px; + position: relative; + z-index: 10; } .notyf__icon { - width: 22px; - text-align: center; - font-size: 1.3em; - opacity: 0; - -webkit-animation: notyf-fadeinup .3s forwards; - animation: notyf-fadeinup .3s forwards; - -webkit-animation-delay: .3s; - animation-delay: .3s; - margin-right: 13px + width: 22px; + text-align: center; + font-size: 1.3em; + opacity: 0; + -webkit-animation: notyf-fadeinup 0.3s forwards; + animation: notyf-fadeinup 0.3s forwards; + -webkit-animation-delay: 0.3s; + animation-delay: 0.3s; + margin-right: 13px; } .notyf__dismiss { - position: absolute; - top: 0; - right: 0; - height: 100%; - width: 26px; - margin-right: -15px; - -webkit-animation: notyf-fadeinleft .3s forwards; - animation: notyf-fadeinleft .3s forwards; - -webkit-animation-delay: .35s; - animation-delay: .35s; - opacity: 0 + position: absolute; + top: 0; + right: 0; + height: 100%; + width: 26px; + margin-right: -15px; + -webkit-animation: notyf-fadeinleft 0.3s forwards; + animation: notyf-fadeinleft 0.3s forwards; + -webkit-animation-delay: 0.35s; + animation-delay: 0.35s; + opacity: 0; } .notyf__dismiss-btn { - background-color: rgba(0, 0, 0, .25); - border: none; - cursor: pointer; - transition: opacity .2s ease, background-color .2s ease; - outline: none; - opacity: .35; - height: 100%; - width: 100% + background-color: rgba(0, 0, 0, 0.25); + border: none; + cursor: pointer; + transition: + opacity 0.2s ease, + background-color 0.2s ease; + outline: none; + opacity: 0.35; + height: 100%; + width: 100%; } .notyf__dismiss-btn:after, .notyf__dismiss-btn:before { - content: ""; - background: #fff; - height: 12px; - width: 2px; - border-radius: 3px; - position: absolute; - left: calc(50% - 1px); - top: calc(50% - 5px) + content: ""; + background: #fff; + height: 12px; + width: 2px; + border-radius: 3px; + position: absolute; + left: calc(50% - 1px); + top: calc(50% - 5px); } .notyf__dismiss-btn:after { - transform: rotate(-45deg) + transform: rotate(-45deg); } .notyf__dismiss-btn:before { - transform: rotate(45deg) + transform: rotate(45deg); } .notyf__dismiss-btn:hover { - opacity: .7; - background-color: rgba(0, 0, 0, .15) + opacity: 0.7; + background-color: rgba(0, 0, 0, 0.15); } .notyf__dismiss-btn:active { - opacity: .8 + opacity: 0.8; } .notyf__message { - vertical-align: middle; - position: relative; - opacity: 0; - -webkit-animation: notyf-fadeinup .3s forwards; - animation: notyf-fadeinup .3s forwards; - -webkit-animation-delay: .25s; - animation-delay: .25s; - line-height: 1.5em + vertical-align: middle; + position: relative; + opacity: 0; + -webkit-animation: notyf-fadeinup 0.3s forwards; + animation: notyf-fadeinup 0.3s forwards; + -webkit-animation-delay: 0.25s; + animation-delay: 0.25s; + line-height: 1.5em; } -@media only screen and (max-width:480px) { - .notyf { - padding: 0 - } +@media only screen and (max-width: 480px) { + .notyf { + padding: 0; + } - .notyf__ripple { - height: 600px; - width: 600px; - -webkit-animation-duration: .5s; - animation-duration: .5s - } + .notyf__ripple { + height: 600px; + width: 600px; + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + } - .notyf__toast { - max-width: none; - border-radius: 0; - box-shadow: 0 -2px 7px 0 rgba(0, 0, 0, .13); - width: 100% - } + .notyf__toast { + max-width: none; + border-radius: 0; + box-shadow: 0 -2px 7px 0 rgba(0, 0, 0, 0.13); + width: 100%; + } - .notyf__dismiss { - width: 56px - } -} \ No newline at end of file + .notyf__dismiss { + width: 56px; + } +} diff --git a/src/renderer/less/pages.css b/src/renderer/less/pages.css new file mode 100644 index 00000000..0d594a2b --- /dev/null +++ b/src/renderer/less/pages.css @@ -0,0 +1,1906 @@ +.content-inner { + position: absolute; + top: var(--navigationBarHeight); + left: 0; + padding: 32px; + width: 100%; + transition: zoom 1s; + zoom: 1; + max-width: 1680px; + right: 0; + margin: 0 auto; +} +.content-inner.centered { + height: 100%; + display: flex; + flex-flow: column; + justify-content: center; + align-items: center; +} +.github-themes-page { + display: flex; + flex-direction: column; + height: 100%; +} +.github-themes-page .github-avatar { + height: 42px; + width: 42px; + margin: 6px; + border-radius: 32px; +} +.github-themes-page .repo-name { + margin: 0px; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + white-space: break-spaces; +} +.github-themes-page .repo-url { + color: var(--textColor); + font-size: 0.8em; +} +.github-themes-page .repo-preview-name { + margin: 0px; +} +.github-themes-page .repos-list { + height: 100%; + width: 320px; + font-size: 14px; + overflow: overlay; + padding-bottom: 16px; + flex: 0 0 auto; +} +.github-themes-page .repos-list > .list-group { + margin: 0px; +} +.github-themes-page .repos-list .list-group-item { + padding: 12px 6px; +} +.github-themes-page .repos-list .list-group-item:hover { + filter: brightness(1.2); +} +.github-themes-page .repos-list .list-group-item:active { + filter: brightness(0.8); +} +.github-themes-page .github-preview { + height: 100%; + flex: 1; + padding: 16px 32px; + overflow: auto; + padding-bottom: 16px; +} +.github-themes-page .gh-content { + display: flex; + flex-direction: row; + flex: 1; + overflow: hidden; +} +.github-themes-page .gh-header { + padding: 16px; + height: 64px; + display: grid; + align-content: center; + flex: 0 0 auto; +} +.github-themes-page .gh-header .header-text { + position: initial !important; + justify-content: left !important; +} +.github-themes-page .installed-themes-page .style-editor-container { + height: 100%; + flex: 1; + background: var(--color2); + padding: 0px; + overflow-y: overlay; +} +.github-themes-page .installed-themes-page .style-editor-container .list-group-item { + border-radius: 0px; +} +.installed-themes-page { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +} +.installed-themes-page .themeContextMenu { + background: transparent; + color: var(--keyColor); + border: 0px; +} +.installed-themes-page .list-group-item.addon { + background: rgba(86, 86, 86, 0.2); +} +.installed-themes-page .list-group-item.applied { + background: var(--keyColor-disabled); + pointer-events: none; +} +.installed-themes-page .repo-header { + font-size: 16px; + position: sticky; + top: 0; + left: 0; + right: 0; + width: 100%; + height: 50px; + z-index: 1; + background: rgba(36, 36, 36, 0.5); + display: flex; + justify-content: center; + align-items: center; + backdrop-filter: var(--glassFilter); + overflow: hidden; + border-bottom: 1px solid rgba(0, 0, 0, 0.18); + border-top: 1px solid rgba(135, 135, 135, 0.18); +} +.installed-themes-page .gh-header { + z-index: 5; + padding: 16px; + flex: 0 0 auto; + height: 64px; + display: grid; + align-content: center; +} +.installed-themes-page .gh-header .header-text { + position: initial !important; + justify-content: left !important; +} +.installed-themes-page .gh-content { + display: flex; + flex-direction: row; + padding: 0px; + height: 100%; + flex: 0 0 auto; +} +.installed-themes-page .gh-content .repos-list { + width: 320px; + overflow: overlay; + height: 90%; + font-size: 14px; + white-space: nowrap; +} +.installed-themes-page .gh-content .repos-list > .list-group { + margin: 0px; + padding-bottom: 16px; +} +.installed-themes-page .gh-content .repos-list .list-group-item { + padding: 12px 6px; +} +.installed-themes-page .gh-content .repos-list .list-group-item:hover { + filter: brightness(1.2); +} +.installed-themes-page .gh-content .repos-list .list-group-item:active { + filter: brightness(0.8); +} +.installed-themes-page .gh-content .style-editor-container { + height: 100%; + flex: 1; + padding: 0px; + width: 100%; + overflow: hidden; +} +.installed-themes-page .gh-content .style-editor-container .stylestack-editor { + padding-bottom: 16px; +} +.installed-themes-page .gh-content .style-editor-container .list-group-item { + border-radius: 0px; +} +.installed-themes-page .stylestack-editor { + width: 100%; +} +.installed-themes-page .stylestack-editor .btn, +.installed-themes-page .stylestack-editor .btn-group { + width: 100%; +} +.installed-themes-page .stylestack-editor .themeLabel { + display: flex; + align-items: center; +} +.installed-themes-page .stylestack-editor .handle { + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} +.installed-themes-page .stylestack-editor .list-group-item:hover { + cursor: grab; +} +.installed-themes-page .stylestack-editor .list-group-item:active { + cursor: grabbing; +} +.installed-themes-page .stylestack-editor .removeItem { + border: 0px; + background: transparent; + height: 32px; + font-weight: bold; + color: var(--textColor); + cursor: pointer; +} +.installed-themes-page .stylestack-editor .stylesDropdown > .dropdown-menu { + height: 300px; + overflow-y: overlay; +} +.library-page { + padding: 0px; +} +.library-page .library-header { + position: sticky; + top: 0; + left: 0; + border-bottom: 1px solid rgba(200, 200, 200, 0.05); + z-index: 6; + background: black; + padding: 0px 2em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); +} +.library-page .well { + margin: 2em; +} +.search-page .searchToggle { + float: right; +} +.search-page .searchToggle > button { + min-width: 120px; +} +.search-page .cd-mediaitem-square.mediaitem-brick { + width: 530px !important; +} +.search-page .cd-mediaitem-square.mediaitem-brick .artwork-container .artwork { + height: 168px !important; + width: 507px !important; + z-index: 1; +} +.search-page .cd-mediaitem-square.mediaitem-brick .title { + font-weight: bold; + justify-content: left; + font-size: 18px; + margin-top: -40px; + z-index: 5; + pointer-events: none; +} +.content-inner.podcasts-page { + display: flex; + height: calc(100% - var(--navigationBarHeight)); + padding: 0px; +} +.content-inner.podcasts-page .list-flat { + border-radius: 0px; +} +.content-inner.podcasts-page .podcast-artwork { + width: 200px; + margin: 16px auto; + height: 200px; +} +.content-inner.podcasts-page .podcasts-list { + height: 100%; + width: 280px; + background: rgba(200, 200, 200, 0.1); + overflow-y: overlay; + border-right: 1px solid var(--color2); + flex: none; + overflow-x: hidden; +} +.content-inner.podcasts-page .podcasts-list .podcast-list-header { + border-bottom: 1px solid var(--color2); + font-size: 0.7em; + padding: 6px; + background: #ffffff17; + text-transform: uppercase; + font-weight: 600; + opacity: 0.5; +} +.content-inner.podcasts-page .podcasts-list .podcasts-search { + padding: 10px; + position: sticky; + top: 0; + left: 0; + width: 100%; + border-bottom: 1px solid var(--color2); + z-index: 2; + background: #303030; +} +.content-inner.podcasts-page .episodes-list { + height: 100%; + width: 100%; + background: rgba(200, 200, 200, 0.06); + overflow-y: overlay; + overflow-x: hidden; +} +.content-inner.podcasts-page .episodes-list .episodes-inline-info { + padding: 14px 14px 0px 14px; +} +.content-inner.podcasts-page .episodes-list .episodes-inline-info .podcast-show-info { + display: flex; + justify-content: center; + flex-direction: column; +} +.content-inner.podcasts-page .episodes-list .episodes-inline-info .podcast-show-description { + margin: 32px 6px; + font-size: 0.8rem; + white-space: pre-wrap; + display: block; +} +.content-inner.podcasts-page .episodes-list .episodes-inline-info .podcast-artwork { + width: 120px; + margin: 0px auto; + height: 120px; +} +.content-inner.podcasts-page .episodes-list .podcast-no-search-results { + text-align: center; + margin-top: 40px; +} +.content-inner.podcasts-page .podcasts-details { + width: 300px; + flex: none; + background: rgba(255, 255, 255, 0.05); + overflow-y: overlay; + overflow-x: hidden; + top: 2%; + z-index: 2; + border-left: 1px solid var(--color2); + padding-bottom: 1em; +} +.content-inner.podcasts-page .podcasts-details .meta-btn { + font-size: 0.75em; +} +.content-inner.podcasts-page .podcasts-details .podcasts-details-header { + display: flex; + justify-content: end; + align-items: center; + position: sticky; + top: 0; + z-index: 2; +} +.content-inner.podcasts-page .podcasts-details .close-btn { + width: 50px; + height: 42px; + background-image: var(--gfx-closeBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 0; + right: 0; +} +.content-inner.podcasts-page .podcasts-details .close-btn:hover { + background-color: #c42b1c; +} +.content-inner.podcasts-page .podcasts-details .podcast-genre { + text-align: center; + margin: 6px; + font-size: 0.8em; + font-weight: 500; + opacity: 0.8; +} +.content-inner.podcasts-page .podcasts-details .podcast-metainfo { + text-align: center; + font-size: 0.7em; + opacity: 0.8; +} +.content-inner.podcasts-page .podcasts-details .podcast-header { + text-align: center; + padding: 0 1rem; +} +.content-inner.podcasts-page .podcasts-details .podcast-play-btn { + width: 50%; + display: block; + margin: 0 auto; +} +.content-inner.podcasts-page .podcasts-details .podcast-description { + margin: 12px; + font-size: 0.75em; + white-space: pre-wrap; + display: block; + line-break: anywhere; +} +.content-inner.library-artists-page { + height: calc(100% - 60px - var(--navigationBarHeight)); + padding: 0px; +} +.content-inner.library-artists-page .inner-container { + display: flex; + height: calc(100% - var(--navigationBarHeight)); + padding: 0px; + height: 100%; +} +.content-inner.library-artists-page .inner-container .list-flat { + border-radius: 0px; +} +.content-inner.library-artists-page .inner-container .podcast-artwork { + width: 200px; + margin: 16px auto; + height: 200px; +} +.content-inner.library-artists-page .inner-container .podcasts-list { + height: 100%; + width: 280px; + background: rgba(200, 200, 200, 0.1); + overflow-y: overlay; + border-right: 1px solid var(--color2); + flex: none; + overflow-x: hidden; +} +.content-inner.library-artists-page .inner-container .podcasts-list .podcast-list-header { + border-bottom: 1px solid var(--color2); + font-size: 0.7em; + padding: 6px; + background: #ffffff17; + text-transform: uppercase; + font-weight: 600; + opacity: 0.5; +} +.content-inner.library-artists-page .inner-container .podcasts-list .podcasts-search { + padding: 10px; + position: sticky; + top: 0; + left: 0; + width: 100%; + border-bottom: 1px solid var(--color2); + z-index: 2; + background: #303030; +} +.content-inner.library-artists-page .inner-container .episodes-list { + height: calc(100% + 60px); + width: 100%; + background: rgba(200, 200, 200, 0.06); + overflow-y: overlay; + overflow-x: hidden; +} +.content-inner.library-artists-page .inner-container .episodes-list .episodes-inline-info { + padding: 14px 14px 0px 14px; +} +.content-inner.library-artists-page .inner-container .episodes-list .episodes-inline-info .podcast-show-info { + display: flex; + justify-content: center; + flex-direction: column; +} +.content-inner.library-artists-page .inner-container .episodes-list .episodes-inline-info .podcast-show-description { + margin: 32px 6px; + font-size: 0.8rem; + white-space: pre-wrap; + display: block; +} +.content-inner.library-artists-page .inner-container .episodes-list .episodes-inline-info .podcast-artwork { + width: 120px; + margin: 0px auto; + height: 120px; +} +.content-inner.library-artists-page .inner-container .episodes-list .podcast-no-search-results { + text-align: center; + margin-top: 40px; +} +.content-inner.library-artists-page .inner-container .podcasts-details { + width: 300px; + flex: none; + background: rgba(255, 255, 255, 0.05); + overflow-y: overlay; + overflow-x: hidden; + top: 2%; + z-index: 2; + border-left: 1px solid var(--color2); + padding-bottom: 1em; +} +.content-inner.library-artists-page .inner-container .podcasts-details .meta-btn { + font-size: 0.75em; +} +.content-inner.library-artists-page .inner-container .podcasts-details .podcasts-details-header { + display: flex; + justify-content: end; + align-items: center; + position: sticky; + top: 0; + z-index: 2; +} +.content-inner.library-artists-page .inner-container .podcasts-details .close-btn { + width: 50px; + height: 42px; + background-image: var(--gfx-closeBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 0; + right: 0; +} +.content-inner.library-artists-page .inner-container .podcasts-details .close-btn:hover { + background-color: #c42b1c; +} +.content-inner.library-artists-page .inner-container .podcasts-details .podcast-genre { + text-align: center; + margin: 6px; + font-size: 0.8em; + font-weight: 500; + opacity: 0.8; +} +.content-inner.library-artists-page .inner-container .podcasts-details .podcast-metainfo { + text-align: center; + font-size: 0.7em; + opacity: 0.8; +} +.content-inner.library-artists-page .inner-container .podcasts-details .podcast-header { + text-align: center; +} +.content-inner.library-artists-page .inner-container .podcasts-details .podcast-play-btn { + width: 50%; + display: block; + margin: 0 auto; +} +.content-inner.library-artists-page .inner-container .podcasts-details .podcast-description { + margin: 12px; + font-size: 0.75em; + white-space: pre-wrap; + display: block; + line-break: anywhere; +} +@media only screen and (max-width: 1230px) { + .content-inner.library-artists-page .content-inner.podcasts-page .podcasts-details { + height: 96%; + width: 300px; + flex: none; + background: rgba(20, 20, 20, 0.97); + overflow-y: overlay; + overflow-x: hidden; + position: absolute; + right: 2%; + top: 2%; + border-radius: 10px; + box-shadow: var(--ciderShadow-Generic); + z-index: 2; + } +} +@media only screen and (max-width: 1230px) { + .content-inner.podcasts-page .podcasts-details { + height: 96%; + width: 300px; + flex: none; + background: rgba(20, 20, 20, 0.97); + overflow-y: overlay; + overflow-x: hidden; + position: absolute; + right: 2%; + top: 2%; + border-radius: 10px; + box-shadow: var(--ciderShadow-Generic); + z-index: 2; + } +} +/* Album / Playlist Page */ +.album-header { + position: sticky; + left: 0; + z-index: 6; + padding: 0px 2em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); + --bs-gutter-x: 4rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-right: calc(-0.5 * var(--bs-gutter-x)); + margin-left: calc(-0.5 * var(--bs-gutter-x)); + border-bottom: 1px solid rgba(200, 200, 200, 0.05); +} +.playlist-page { + --bgColor: transparent; + padding: 0px; + top: 0; + padding-top: var(--navigationBarHeight); + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +} +.playlist-page .cd-mediaitem-list-item:hover .heart-icon { + display: flex; +} +.playlist-page .cd-mediaitem-list-item .heart-icon { + left: -25px; +} +.playlist-page .editTracksBtn { + position: absolute; + top: 20px; + right: 20px; + z-index: 1; +} +.playlist-page .editTracksBtn > span { + display: flex; + gap: 8px; +} +.playlist-page .mediaContainer { + transition: width 0.5s ease-in-out, height 0.5s ease-in-out; + width: 260px; + height: 260px; +} +.playlist-page .playlist-body { + padding: 32px; + overflow-y: overlay; + height: 100%; + padding: 0px; + background-color: var(--color3); +} +.playlist-page .playlist-body.scrollbody .tabs { + display: flex; + flex-flow: column; + height: 100%; +} +.playlist-page .playlist-body.scrollbody .tabs .nav-link { + text-transform: capitalize; +} +.playlist-page .playlist-body.scrollbody .tabs .tab-content { + height: 100%; + overflow: hidden; + margin: 0px; +} +.playlist-page .playlist-body.scrollbody .tabs .tab-content .tab-pane { + height: 100%; + overflow-y: overlay; + overflow-x: hidden; + padding: var(--contentInnerPadding); + padding-inline: 40px; + -webkit-mask-image: linear-gradient(180deg, transparent, white 20px); +} +.playlist-page .playlist-body.scrollbody .tabs .tab-content .tab-pane .well { + margin: 0px; +} +.playlist-page .playlist-body .search-input-container { + height: 2.5rem; + margin: 1rem; + margin-top: 0; + scroll-margin-top: 1rem; +} +.playlist-page .playlist-body .search-input-container .search-input { + width: 100%; + height: 100%; +} +.playlist-page .floating-header { + position: sticky; + top: 0; + left: 0; + border-bottom: 1px solid rgba(200, 200, 200, 0.05); + z-index: 6; + padding: 0px 1em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); + transition: opacity 0.1s var(--appleEase); + display: none; +} +.playlist-page .playlist-display { + padding: var(--contentInnerPadding); + min-height: 300px; + position: relative; + box-shadow: 0px 4px 6px 3px rgba(0, 0, 0, 0.1); + transition: min-height 0.5s ease-in-out; +} +.playlist-page .playlist-display .artworkContainer { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: 0; + margin-top: calc(var(--navigationBarHeight) * -1); + margin-bottom: -10px; + padding: 0; + -webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, #c8c8c8, transparent 98%); + opacity: 0.7; + animation: playlistArtworkFadeIn 1s var(--appleEase); +} +.playlist-page .playlist-display .artworkContainer .artworkMaterial img { + filter: brightness(100%) blur(80px) saturate(100%) contrast(1); + object-position: center; + object-fit: cover; + width: 100%; + height: 100%; + transform: unset; +} +.playlist-page .playlist-display .playlistInfo { + z-index: 1; + position: absolute; + bottom: 0; + left: 0; + right: 0; + top: 0; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; +} +.playlist-page .playlist-display .playlistInfo .playlist-hero { + width: 100%; + transform: translateX(25%); + position: absolute; + z-index: -1; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +.playlist-page .playlist-display .playlistInfo .playlist-hero .mediaitem-artwork { + -webkit-mask-image: -webkit-radial-gradient(center, circle cover, #000000 50%, rgba(0, 0, 0, 0) 75%); + border-radius: 0px; +} +.playlist-page .playlist-display .playlistInfo .playlist-hero .hero-tint { + position: absolute; + top: 0; + opacity: 0.6; + width: 100%; + height: 100%; +} +.playlist-page .playlist-display .playlistInfo > .row { + width: calc(100% - 32px); +} +.playlist-page .playlist-display .playlistInfo .playlist-info { + flex-shrink: unset; + display: flex; + flex-flow: column; + justify-content: flex-end; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .playlist-name { + font-weight: 700; + font-size: 1.6rem; + margin-right: 6px; + margin-bottom: 6px; + flex-shrink: unset; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .search-input::placeholder { + color: var(--heroplaceholdercolor); +} +.playlist-page .playlist-display .playlistInfo .playlist-info .nameEdit { + font-weight: 700; + font-size: 1.6rem; + flex-shrink: unset; + background: transparent; + border: 0px; + color: inherit; + font-family: inherit; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .descriptionEdit { + font-size: 14px; + flex-shrink: unset; + background: transparent; + border: 0px; + color: inherit; + font-family: inherit; + width: 60vw; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .descriptionEdit { + font-size: 14px; + flex-shrink: unset; + background: transparent; + border: 0px; + color: inherit; + font-family: inherit; + width: 60vw; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .playlist-artist { + font-size: 20px; + margin-bottom: 6px; + margin-right: 6px; + flex-shrink: unset; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .playlist-desc { + transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out; + box-sizing: border-box; + font-size: 14px; + flex-shrink: unset; + margin-right: 5px; + max-height: 100px; + position: relative; + height: 4vh; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .playlist-desc .content { + height: 4vh; + -webkit-mask-image: -webkit-gradient(linear, left 50%, left 90%, from(#000000), to(rgba(0, 0, 0, 0))); +} +.playlist-page .playlist-display .playlistInfo .playlist-info .playlist-desc .more-btn { + appearance: none; + position: absolute; + right: 0; + bottom: 0; + padding: 0 5px; + font-size: 14px; + color: var(--keyColor); + background-color: transparent; + border: 0px; + cursor: pointer; + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + justify-content: flex-end; + align-items: flex-end; + font-weight: 600; + font-family: inherit; + text-transform: uppercase; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .playlist-desc-expanded { + box-sizing: border-box; + font-size: 14px; + position: relative; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .playlist-desc-expanded .more-btn { + appearance: none; + position: absolute; + right: 0; + bottom: 0; + padding: 0 5px; + font-size: 14px; + color: var(--keyColor); + background-color: transparent; + border: 0px; + cursor: pointer; + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + justify-content: flex-end; + align-items: flex-end; + font-weight: 600; + font-family: inherit; + text-transform: uppercase; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .search-btn { + display: flex; + width: 32px; + align-items: center; + margin-right: 1rem; + background: rgba(100, 100, 100, 0.5); + border: none; + cursor: pointer; + border-radius: 100vmax; + box-shadow: var(--ciderShadow-Generic); +} +.playlist-page .playlist-display .playlistInfo .playlist-info .search-btn > ._svg-icon { + width: 18px; + height: 18px; + margin: auto; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .search-btn.active { + animation: enlarge 0.5s ease-in-out; +} +.playlist-page .playlist-display .playlistInfo .playlist-info .search-btn:hover { + filter: brightness(125%); +} +@keyframes enlarge { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } + 100% { + transform: scale(1); + } +} +.playlist-page .friends-info { + display: flex; + flex-flow: column; +} +.playlist-page .friends-info .badge-container { + display: flex; + flex-flow: wrap; +} +.playlist-page .friends-info .badge-container .socialBadge { + width: 40px; + height: 40px; + border-radius: 100%; + overflow: hidden; + box-shadow: var(--mediaItemShadow-ShadowSubtle); + transition: transform 0.2s var(--appleEase); + margin: 6px; +} +.playlist-page .friends-info .badge-container .socialBadge:hover { + transform: scale(1.2); +} +.playlist-page .friends-info .friends-name { + text-align: center; + font-size: 0.9em; + margin: 8px; +} +.playlist-page .playlist-time { + font-size: 0.9em; + margin: 6px; + opacity: 0.7; + transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out; + height: 0.9em; +} +.playlist-page.inline-playlist { + overflow: hidden; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 10; + position: sticky; + margin-top: calc(var(--navigationBarHeight) * -1); +} +.playlist-page.inline-playlist .floating-header { + opacity: 1; + top: 0px; + z-index: 6; + padding: 1em; + backdrop-filter: unset; + background: black; +} +.playlist-page.inline-playlist .floating-header h3 { + display: none; +} +.playlist-page.inline-playlist .playlist-inner { + background: black; + width: 80%; + height: 100%; + overflow: overlay; + box-shadow: var(--ciderShadow-Generic); + border-radius: var(--mediaItemRadius) var(--mediaItemRadius) 0px 0px; +} +.playlist-page.inline-playlist .playlist-inner .close-btn { + position: sticky; + top: 16px; + left: 16px; + margin-left: 16px; + z-index: 7; +} +.playlist-page .pilldim .nav-pills { + width: max-content; + margin: 0 auto; + margin-top: 16px; +} +.playlist-page.plmin .playlist-display { + transition: min-height 0.5s ease-in-out; + min-height: 200px; +} +.playlist-page.plmin .playlist-display .mediaContainer { + transition: width 0.5s ease-in-out, height 0.5s ease-in-out; + width: 128px !important; + height: 128px !important; +} +.playlist-page.plmin .playlist-display .playlist-time { + transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out; + height: 0px; + opacity: 0; +} +.playlist-page.plmin .playlist-display .playlist-desc { + transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out; + height: 0px !important; + opacity: 0; +} +@keyframes playlistArtworkFadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 0.7; + } +} +.collection-page { + padding-bottom: 128px; +} +.collection-page .top-fab { + height: 52px; + width: 52px; + position: fixed; + bottom: 32px; + right: 32px; + border-radius: 100%; + background: #3c3c3c; + border: 0px; + appearance: none; + box-shadow: var(--ciderShadow-Generic); +} +.collection-page .top-fab > svg { + height: 50%; + color: #eee; + pointer-events: none; +} +.collection-page .top-fab:hover { + background: #646464; +} +.collection-page .top-fab:active { + background: var(--keyColor); +} +.collection-page .header-text { + margin-bottom: 32px; +} +/* Artist Page */ +.artist-page { + padding: 0px; + top: 0; +} +.artist-page .floating-header { + position: sticky; + top: 0; + left: 0; + border-bottom: 1px solid rgba(200, 200, 200, 0.05); + z-index: 6; + padding: 0px 1em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); + transition: opacity 0.1s var(--appleEase); +} +.artist-page.animated .artist-header .more-btn-round { + position: absolute; + bottom: 22px !important; + right: 28px; +} +.artist-page.animated .artist-header { + min-height: 80vh; +} +.artist-page .artist-header { + color: white; + display: flex; + align-items: center; + justify-content: space-between; + min-height: 400px; + position: relative; + pointer-events: none; +} +.artist-page .artist-header .header-content { + z-index: 1; +} +.artist-page .artist-header .artist-hero { + height: 100%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +.artist-page .artist-header .artist-hero .mediaitem-artwork { + border-radius: 0px; +} +.artist-page .artist-header .artworkContainer { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: 0; + padding: 0; + -webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, #c8c8c8, transparent 98%); + opacity: 0.7; + animation: playlistArtworkFadeIn 1s var(--appleEase); +} +.artist-page .artist-header .artworkContainer .artworkMaterial img { + filter: brightness(100%) blur(80px) saturate(100%) contrast(1); + object-position: center; + object-fit: cover; + width: 100%; + height: 100%; + transform: unset; +} +.artist-page .artist-header .more-btn-round { + position: absolute; + bottom: 82px; + right: 28px; +} +.artist-page .artist-header .social-btn { + border-radius: 100%; + background: transparent; + height: 17px; + border: 0px; + cursor: pointer; + z-index: 69; + display: flex; + justify-content: center; + align-items: center; + float: right; +} +@media only screen and (min-width: 1133px) and (max-width: 1277px) { + .artist-page .artist-header .about-page .social-btn { + display: none !important; + } +} +.artist-page .artist-header .animated { + width: 100%; + height: 100%; + align-self: center; + position: absolute; + overflow: hidden; + box-shadow: rgba(0, 0, 0, 0.5) 0 0 0 1000000px inset; + z-index: 1; +} +.artist-page .artist-header .animated video { + overflow: hidden; + height: 100%; + width: 100%; + min-height: 56.25vw; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + object-fit: cover; +} +.artist-page .artist-header .row .col.cider-flex-center { + z-index: 4; +} +.artist-page .artist-image { + width: 200px; + height: 200px; + margin: 32px; + position: relative; +} +.artist-page .artist-image .overlay-play { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + background: rgba(0, 0, 0, 0.5); + transition: opacity 0.1s var(--appleEase); + border-radius: 100%; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + appearance: none; + border: 0px; + padding: 0px; +} +.artist-page .artist-image .overlay-play:hover { + opacity: 1; +} +.artist-page .artist-image .overlay-play:active { + background: var(--selected-click); +} +.artist-page .artist-image .overlay-play > svg { + width: 70%; +} +.artist-page .artist-play { + width: 32px; + height: 32px; + background: rgba(100, 100, 100, 0.5); + box-shadow: var(--ciderShadow-Generic); + border-radius: 100%; + box-shadow: var(--mediaItemShadow); + display: none; + cursor: pointer; + appearance: none; + border: 0px; + padding: 0px; +} +.artist-page .artist-play:hover { + filter: brightness(125%); +} +.artist-page .artist-play:active { + filter: brightness(75%); + transform: scale(0.98); + transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase); +} +.artist-page .artist-title .artist-play { + transform: translateY(3px); + margin: 14px; +} +.artist-page .artist-title.artist-animation-on { + width: 100%; + flex: unset; + margin-left: 0.5em; + color: whitesmoke; + position: absolute; + bottom: 0; +} +.artist-page .artist-title.artist-animation-on .artist-play { + display: block; +} +.artist-page .artist-body { + padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); + margin: -64px 20px; +} +.artist-page .artist-body .arow { + display: flex; + overflow: hidden; + padding: 16px 32px; +} +.artist-page .artist-body .arow > .latestRelease { + width: 250px; +} +.artist-page .artist-body .arow > .topSongs { + width: calc(100% - 250px); +} +.artist-page .artist-body .arow.arowb > .topSongs { + width: 100%; +} +.artist-page.animated > .artist-body { + padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); + margin-top: -57px; +} +.artist-page .showmoreless { + font-family: inherit; + font-size: 16px; + font-weight: 500; + background: transparent; + border: 0px; + border-radius: 6px; + appearance: none; + color: var(--keyColor); + padding: 8px 12px; + cursor: pointer; + margin-top: 12px; + float: right; +} +.artist-page .showmoreless:hover { + background: rgba(200, 200, 200, 0.1); +} +/* Artist Page End */ +.settings-page { + padding: 0px; +} +.settings-page .nav { + width: 90%; + margin: 16px auto 0px; +} +.audiolabs-page { + padding: 0px; +} +.audiolabs-page .md-option-header { + padding: 1.25em 1.25em; + border-bottom: unset; + border-top: unset; + font-weight: 600; + font-size: 1em; + background: rgba(255, 255, 255, 0.03); +} +.audiolabs-page .carousel-item > img { + object-fit: cover; + width: 100%; +} +.audiolabs-page .spprofile-line { + height: 300px; + width: 100%; + max-width: 1024px; + padding: 16px; + margin: 0 auto; +} +.audiolabs-page .spprofile-line .spprofile-viewport { + height: 100%; + position: relative; + border-radius: var(--mediaItemRadius); + overflow: hidden; + box-shadow: var(--mediaItemShadow-Shadow); + background: black; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spprev, +.audiolabs-page .spprofile-line .spprofile-viewport .nextprev { + position: absolute; + height: 100%; + width: 64px; + top: 0; + background: rgba(0, 0, 0, 0.2); + z-index: 1; + border: 0px; + transition: background 0.2s var(--appleEase), transform 0.2s var(--appleEase); +} +.audiolabs-page .spprofile-line .spprofile-viewport .spprev:hover, +.audiolabs-page .spprofile-line .spprofile-viewport .nextprev:hover { + background: var(--selected); + transform: scale(1.1); +} +.audiolabs-page .spprofile-line .spprofile-viewport .spprev:active, +.audiolabs-page .spprofile-line .spprofile-viewport .nextprev:active { + transition: background 0s var(--appleEase); + background: var(--selected-click); +} +.audiolabs-page .spprofile-line .spprofile-viewport .spprev:before, +.audiolabs-page .spprofile-line .spprofile-viewport .nextprev:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #eee; + opacity: 1; + -webkit-mask-position: center; + -webkit-mask-repeat: no-repeat; + -webkit-mask-size: 1em; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spprev { + left: 0; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spprev:before { + -webkit-mask-image: url("views/svg/chevron-left.svg"); +} +.audiolabs-page .spprofile-line .spprofile-viewport .nextprev { + right: 0; +} +.audiolabs-page .spprofile-line .spprofile-viewport .nextprev:before { + -webkit-mask-image: url("views/svg/chevron-right.svg"); +} +.audiolabs-page .spprofile-line .spprofile-viewport .spslide { + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + background: black; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spslide > img { + width: 100%; + height: 100%; + object-fit: cover; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spslide .sptitle { + position: absolute; + bottom: 0px; + left: 0; + width: 100%; + text-align: center; + font-size: 18px; + text-shadow: 0px 2px 4px #00000033; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spfade-enter-active, +.audiolabs-page .spprofile-line .spprofile-viewport .spfade-leave-active { + --transitionTime: 0.2s; + transition: opacity var(--transitionTime) var(--appleEase), transform var(--transitionTime) var(--appleEase); + will-change: opacity, transform; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spfade-enter { + opacity: 0; + transform: scale(1.2) translate3d(0, 0, 0); + will-change: opacity, transform; +} +.audiolabs-page .spprofile-line .spprofile-viewport .spfade-leave-to { + opacity: 1; + transform: scale(1) translate3d(0, 0, 0); + will-change: opacity, transform; +} +.audiolabs-page .settings-option-body { + margin: 16px; +} +@keyframes gradient-animation { + 0% { + background-position: 0% 0%; + } + 50% { + background-position: 100% 0%; + } + 100% { + background-position: 0% 0%; + } +} +.home-page .md-btn-replay { + background-image: linear-gradient(-45deg, #2e2173, #925042); + animation: gradient-animation 5s ease-in-out infinite; + background-size: 400% 400%; + border: 0px; + box-shadow: inset 0px 0px 0px 1px rgba(200, 200, 200, 0.2); + text-transform: uppercase; + font-weight: bold; +} +.home-page .md-btn-replay--hero { + font-size: 1em; + padding: 16px; + background-image: linear-gradient(-45deg, #2e2173, #925042); + animation: gradient-animation 5s ease-in-out infinite; + background-size: 400% 400%; + border: 0px; + box-shadow: inset 0px 0px 0px 1px rgba(200, 200, 200, 0.2); + margin-top: 1em; + font-size: 0.9em; + text-transform: uppercase; + font-weight: bold; +} +.home-page .artist-feed-card { + position: absolute; + bottom: 0; + left: 10%; + z-index: 1; + background: black; + width: 80%; + height: 96%; + overflow: scroll; + border-radius: 10px; +} +.home-page .col.madeforyou-col { + width: 420px; + min-width: 0px; + max-width: 420px; +} +.home-page .well.artistfeed-well { + margin-top: 0px; + height: 392px; + align-content: flex-start; +} +.home-page .hint-text { + font-size: 0.9rem; + color: rgba(200, 200, 200, 0.7); +} +.home-page .user-icon { + border-radius: 100%; + width: 128px; + height: 128px; + overflow: hidden; + box-shadow: var(--mediaItemShadow-Shadow); + margin: 16px; +} +.home-page .well.profile-well { + flex-direction: column; + justify-content: center; + align-items: center; +} +.home-page .well.profile-well .name { + margin: 4px; + font-weight: 500; +} +.home-page .well.profile-well .handle { + margin: 4px; + opacity: 0.7; + font-weight: 500; +} +.replay-page { + --replayTextShadow: 0px 3px 2px #6f3f52; +} +.replay-page .replay-period { + height: 200px; + width: 200px; + margin: 6px; + border-radius: var(--mediaItemRadius); + overflow: hidden; + cursor: pointer; + transition: transform 0.2s var(--appleEase); + transition-delay: 0.1s; + align-self: center; +} +.replay-page .replay-period:hover { + transform: translateY(-6px); + transition-delay: 0s; +} +.replay-page .replay-period .artwork-container { + height: 200px; + width: 200px; +} +.replay-page .replay-playlist-container .cd-mediaitem-square { + height: 230px; + width: 230px; +} +.replay-page .replay-playlist-container .cd-mediaitem-square .info-rect { + display: none; +} +.replay-page .replay-video { + max-height: 300px; + max-width: 800px; + margin: 0 auto; +} +.replay-page .replay-video .mediaitem-artwork { + max-height: 300px; + max-width: 800px; +} +.replay-page .replay-video .mediaitem-artwork .animatedartwork-view-box .animated video { + object-fit: cover; +} +.replay-page .top-genres-container .genre-name { + font-size: 0.9em; + margin: 6px 0px; + font-weight: 500; +} +.replay-page .top-genres-container .genre-count { + width: 100%; + height: 32px; + background: #ffffff14; + border-radius: 10px; + overflow: hidden; +} +.replay-page .top-genres-container .genre-count .genre-count-bar { + height: 100%; + width: 0%; + background: var(--keyColor); + display: flex; + justify-content: center; + align-items: center; + min-width: 32px; + font-size: 0.9em; + font-weight: 500; +} +.replay-page .cd-mediaitem-square { + transition: transform 0.2s var(--appleEase); + transition-delay: 0.1s; +} +.replay-page .cd-mediaitem-square .mediaitem-artwork { + animation: replayFadeIn 0.5s var(--appleEase); +} +.replay-page .cd-mediaitem-square:hover { + transform: scale(1.1); + transition-delay: 0s; +} +@keyframes replayFadeIn { + 0% { + transform: translateY(10px) scale(0.9); + opacity: 0; + } + 100% { + transform: scale(1); + opacity: 1; + } +} +.replay-page .replay-viewport { + background-image: linear-gradient(-45deg, #2e2173, #925042); + animation: gradient-animation 5s ease-in-out infinite; + background-size: 400% 400%; + padding: 16px 40px; + border-radius: 10px; + box-shadow: var(--mediaItemShadow), var(--mediaItemShadow-Shadow); + color: rgba(238, 238, 238, 0.86); +} +.replay-page .replay-viewport .replay-header { + text-align: center; + font-size: 3em; + text-shadow: var(--replayTextShadow); +} +.replay-page .replay-card { + background: transparent; + border: 0px; +} +.content-inner.oobe { + position: absolute; + overflow: hidden; + top: 0; + left: 0; + bottom: 0; + right: 0; + display: grid; + place-items: center; + width: 100%; + background: #1e1e1e; +} +.content-inner.oobe .oobe-view { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 32px; + max-width: 1280px; + max-height: 720px; + align-self: center; + justify-self: center; + height: 100%; + width: 100%; +} +.content-inner.oobe .oobe-view .oobe-header { + font-size: 3em; + text-shadow: var(--replayTextShadow); + font-weight: 600; +} +.content-inner.oobe .oobe-view .oobe-body { + flex: 1; + width: 100%; + background: #ffffff0d; + border-radius: 20px; + padding: 3em; + overflow-y: scroll; + overflow-x: hidden; +} +@media screen and (max-width: 1161px) { + .content-inner.oobe .oobe-view .oobe-body { + font-size: 13px; + } +} +.content-inner.oobe .oobe-view .oobe-body.text { + white-space: pre-wrap; +} +.content-inner.oobe .oobe-view .oobe-body .blurb { + white-space: pre-wrap; + margin: 16px; + line-height: 1.5em; +} +.content-inner.oobe .oobe-view .oobe-body.visual { + padding: 1em; +} +.content-inner.oobe .oobe-view .oobe-body.visual .stylePicker { + border-radius: 10px; + overflow: hidden; + cursor: pointer; + transition: 0.25s all; + box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25); + width: 450px; + margin: 0 auto; +} +.content-inner.oobe .oobe-view .oobe-body.visual .stylePicker .visualPreview { + pointer-events: none; + transition: 0.25s all; + width: 100%; +} +.content-inner.oobe .oobe-view .oobe-body.visual .stylePicker .card-body { + padding: 0; + display: flex; + justify-content: center; + align-items: center; +} +.content-inner.oobe .oobe-view .oobe-body.visual .stylePicker .card-footer { + font-size: 1.25em; + font-weight: 500; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + border: 0px; + text-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25); + font-weight: bold; +} +.content-inner.oobe .oobe-view .oobe-body.visual .stylePicker.style-active { + outline: 4px solid var(--keyColor); +} +.content-inner.oobe .oobe-view .oobe-body.visual .stylePicker:hover { + transform: scale(1.1) translateZ(-1px) translateY(10px); + z-index: 1; + box-shadow: 0px 12px 16px rgba(0, 0, 0, 0.25); +} +@media screen and (max-height: 688px) { + .content-inner.oobe .oobe-view .oobe-body.visual .stylePicker { + width: 270px; + } +} +.content-inner.oobe .oobe-view .oobe-footer { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 16px; +} +.content-inner.oobe .oobe-view .oobe-footer .md-btn { + font-size: 18px; + min-width: 128px; + text-align: center; +} +.content-inner.oobe .oobe-titlebar { + position: absolute; + top: 0; + left: 0; + height: 46px; + width: 100%; + align-items: center; + justify-content: right; + display: flex; + -webkit-app-region: drag; +} +.content-inner.oobe .oobe-titlebar .button-group { + -webkit-app-region: no-drag; + display: flex; + flex-direction: row; + width: 100px; + height: 100%; + justify-content: center; + align-items: center; + gap: 16px; +} +.content-inner.oobe .oobe-titlebar .button-group > button { + height: 32px; + width: 32px; + font-size: 16px; + border-radius: 0px; + border: 0; + appearance: none; + position: relative; + display: flex; + justify-content: center; + align-items: center; + border-radius: 100%; +} +.content-inner.oobe .oobe-titlebar .button-group > button.close { + background-color: #fc3c44aa; +} +.content-inner.oobe .oobe-titlebar .button-group > button.close:hover { + background-color: #fc3c44; +} +.content-inner.oobe .oobe-titlebar .button-group > button.min { + background-color: rgba(200, 200, 200, 0.05); +} +.content-inner.oobe .oobe-titlebar .button-group > button.min:hover { + background-color: rgba(200, 200, 200, 0.1); +} +.content-inner.oobe .oobe-titlebar .button-group > button.close::before { + font-family: "codicon"; + content: "îǏ"; + color: white; +} +.content-inner.oobe .oobe-titlebar .button-group > button.min::before { + font-family: "codicon"; + content: "îĒē"; + color: white; +} +.content-inner.cider-multiroom { + padding: 0px; +} +.content-inner.cider-multiroom .detail { + padding: 32px; +} +.content-inner.cider-multiroom .header-desc { + font-size: 1em; + font-weight: 400; +} +.content-inner.cider-multiroom .artworkContainer { + height: 300px; + width: 100%; +} +.content-inner.cider-multiroom .artworkContainer img { + height: 100%; + width: 100%; + overflow: hidden; + object-fit: cover; + filter: unset; +} +.content-inner.cider-multiroom .artworkContainer img:last-child { + transform: unset; +} +.settings-panel { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0); + display: flex; + justify-content: center; + align-items: center; + z-index: 16; +} +.settings-panel .settings-window { + background: var(--baseColorMix); + max-width: 90%; + max-height: 90%; + width: 100%; + height: 100%; + border-radius: 10px; + box-shadow: var(--ciderShadow-Generic); + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + position: relative; + flex: 1; + backdrop-filter: var(--glassFilterHeavy); + transition: width 0.25s ease-in-out, height 0.25s ease-in-out, max-width 0.25s ease-in-out, max-height 0.25s ease-in-out; +} +.settings-panel .settings-window .header-text { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + opacity: 0.9; +} +.settings-panel .settings-window .nav-pills { + gap: 6px; +} +.settings-panel .settings-window .nav-pills .nav-link { + display: flex; + gap: 10px; + align-items: center; + height: 35px; +} +.settings-panel .settings-window .nav-pills .nav-link :nth-child(2) { + white-space: nowrap; +} +.settings-panel .settings-window .md-option-header { + padding: 0px 26px; + border-bottom: unset; + border-top: unset; + font-weight: 600; + background: rgba(255, 255, 255, 0); + font-size: 2em; +} +.settings-panel .settings-window .settings-option-body-webview { + height: 100%; + width: 100%; +} +.settings-panel .settings-window .settings-option-body { + margin: 16px; +} +.settings-panel .settings-window.maxed { + width: 100%; + height: 100%; + max-height: 100%; + max-width: 100%; + border-radius: 0px; + box-shadow: unset; +} +.settings-panel .settings-window .close-btn { + width: 36px; + height: 36px; + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 10px; + right: 10px; + border-radius: 50px; + display: grid; + align-content: center; + z-index: 9; +} +.settings-panel .settings-window .close-btn:before { + content: "îŠļ"; + font-family: "codicon"; + color: var(--textColor); + font-size: 20px; +} +.settings-panel .settings-window .close-btn:hover { + background-color: #c42b1c; +} +.settings-panel .settings-window .close-btn.back-btn { + left: 10px; + right: unset; +} +.settings-panel .settings-window .close-btn.minmax-btn { + right: 52px; +} +.settings-panel .settings-window .close-btn.minmax-btn:before { + content: ""; +} +.settings-panel .settings-window .close-btn.minmax-btn.min:before { + content: ""; +} +.settings-panel .settings-window .close-btn.minmax-btn:hover { + background-color: var(--selected); +} +.settings-panel .settings-window .tabs { + height: 100%; + width: 100%; + margin: 0; + padding: 0; +} +.settings-panel .settings-window .tabs > .col-auto { + width: 230px; + overflow-x: hidden; + overflow-y: overlay; + transition: width 0.25s ease-in-out; +} +.settings-panel .settings-window .tabs .tab-content { + margin: 0 !important; +} +.settings-panel .settings-window .tab-content { + overflow-y: overlay; + height: 100%; + background-color: var(--panelColor2); + padding: 0px; + padding-top: 48px; + border-left: 1px solid var(--borderColor); +} +.settings-panel .settings-window .github-themes-page .header-text, +.settings-panel .settings-window .installed-themes-page .header-text { + font-size: 1.25em; +} +.settings-panel .settings-window .tab-pane { + height: 100%; +} +.settings-panel .settings-window .settings-tab-content { + height: 100%; +} +.settings-panel .settings-window.no-sidebar .gh-header > .row:last-child { + padding-right: 90px; +} +.settings-panel .settings-window.no-sidebar .tab-content { + padding-top: 0px; +} +.settings-panel .settings-window.no-sidebar .tabs .nav-pills .nav-link { + width: 50px; +} +.settings-panel .settings-window.no-sidebar .tabs .nav-pills .nav-link :nth-child(2) { + opacity: 0; +} +.settings-panel .settings-window.no-sidebar .tabs > .col-auto { + width: 80px; +} +#hid___BV_tab_button__ { + display: none; +} diff --git a/src/renderer/less/pages.less b/src/renderer/less/pages.less new file mode 100644 index 00000000..ecf29ada --- /dev/null +++ b/src/renderer/less/pages.less @@ -0,0 +1,2326 @@ +// Helpers +.content-inner { + position: absolute; + top: var(--navigationBarHeight); + left: 0; + padding: 32px; + width: 100%; + transition: zoom 1s; + zoom: 1; +} + +.content-inner.centered { + height: 100%; + display: flex; + flex-flow: column; + justify-content: center; + align-items: center; +} + +// End Helpers + +// GitHub Themes +.github-themes-page { + display: flex; + flex-direction: column; + height: 100%; + + .github-avatar { + height: 42px; + width: 42px; + margin: 6px; + border-radius: 32px; + } + + .repo-name { + margin: 0px; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + white-space: break-spaces; + } + + .repo-url { + color: var(--textColor); + font-size: 0.8em; + } + + .repo-preview-name { + margin: 0px; + } + + .repos-list { + height: 100%; + width: 320px; + font-size: 14px; + overflow: overlay; + padding-bottom: 16px; + flex: 0 0 auto; + + > .list-group { + margin: 0px; + } + + .list-group-item { + padding: 12px 6px; + + &:hover { + filter: brightness(1.2); + } + + &:active { + filter: brightness(0.8); + } + } + } + + .github-preview { + height: 100%; + flex: 1; + padding: 16px 32px; + overflow: auto; + padding-bottom: 16px; + } + + .gh-content { + display: flex; + flex-direction: row; + flex: 1; + overflow: hidden; + } + + .gh-header { + padding: 16px; + height: 64px; + display: grid; + align-content: center; + flex: 0 0 auto; + + .header-text { + position: initial !important; + justify-content: left !important; + } + } + + .installed-themes-page { + .style-editor-container { + height: 100%; + flex: 1; + background: var(--color2); + padding: 0px; + overflow-y: overlay; + + .list-group-item { + border-radius: 0px; + } + } + } +} + +//Styles Page +.installed-themes-page { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + .themeContextMenu { + background: transparent; + color: var(--keyColor); + border: 0px; + } + + .list-group-item { + &.addon { + background: rgb(86 86 86 / 20%); + } + + &.applied { + background: var(--keyColor-disabled); + pointer-events: none; + } + } + + .repo-header { + font-size: 16px; + position: sticky; + top: 0; + left: 0; + right: 0; + width: 100%; + height: 50px; + z-index: 1; + background: rgba(36, 36, 36, 0.5); + display: flex; + justify-content: center; + align-items: center; + backdrop-filter: var(--glassFilter); + overflow: hidden; + border-bottom: 1px solid rgb(0 0 0 / 18%); + border-top: 1px solid rgb(135 135 135 / 18%); + } + + .gh-header { + z-index: 5; + padding: 16px; + flex: 0 0 auto; + height: 64px; + display: grid; + align-content: center; + .header-text { + position: initial !important; + justify-content: left !important; + } + } + + .gh-content { + display: flex; + flex-direction: row; + padding: 0px; + height: 100%; + flex: 0 0 auto; + + .repos-list { + width: 320px; + overflow: overlay; + height: 90%; + font-size: 14px; + white-space: nowrap; + + > .list-group { + margin: 0px; + padding-bottom: 16px; + } + + .list-group-item { + padding: 12px 6px; + + &:hover { + filter: brightness(1.2); + } + + &:active { + filter: brightness(0.8); + } + } + } + + .style-editor-container { + height: 100%; + flex: 1; + padding: 0px; + width: 100%; + overflow: hidden; + + .stylestack-editor { + padding-bottom: 16px; + } + + .list-group-item { + border-radius: 0px; + } + } + } + + .stylestack-editor { + width: 100%; + + .btn, + .btn-group { + width: 100%; + } + + .themeLabel { + display: flex; + align-items: center; + } + + .handle { + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + .list-group-item { + &:hover { + cursor: grab; + } + + &:active { + cursor: grabbing; + } + } + + .removeItem { + border: 0px; + background: transparent; + height: 32px; + font-weight: bold; + color: var(--textColor); + cursor: pointer; + } + + .stylesDropdown { + > .dropdown-menu { + height: 300px; + overflow-y: overlay; + } + } + } +} + +// Library - Songs page +.library-page { + padding: 0px; + + .library-header { + position: sticky; + top: 0; + left: 0; + border-bottom: 1px solid rgba(200, 200, 200, 0.05); + z-index: 6; + background: black; + padding: 0px 2em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); + } + + .well { + margin: 2em; + } +} + +// Search Page +&.search-page { + .searchToggle { + float: right; + + > button { + min-width: 120px; + } + } + .categories { + display: grid; + grid-template-columns: repeat(3, minmax(200px, 1fr)); + gap: 1rem; + } + .cd-mediaitem-square.mediaitem-brick { + width: 100% !important; + height: 168px; + padding-block: 0.5rem; + .artwork-container .artwork { + height: 168px !important; + width: 100% !important; + z-index: 1; + } + .info-rect { + height: max-content; + } + .title { + font-weight: bold; + justify-content: left; + font-size: 18px; + margin-top: -40px; + z-index: 5; + pointer-events: none; + } + } +} + +// Podcast Page +.content-inner.podcasts-page { + display: flex; + height: calc(100% - var(--navigationBarHeight)); + padding: 0px; + + .list-flat { + border-radius: 0px; + } + + .podcast-artwork { + width: 200px; + margin: 16px auto; + height: 200px; + } + + .podcasts-list { + height: 100%; + width: 280px; + background: rgb(200 200 200 / 10%); + overflow-y: overlay; + border-right: 1px solid var(--color2); + flex: none; + overflow-x: hidden; + + .podcast-list-header { + border-bottom: 1px solid var(--color2); + font-size: 0.7em; + padding: 6px; + background: #ffffff17; + text-transform: uppercase; + font-weight: 600; + opacity: 0.5; + } + + .podcasts-search { + padding: 10px; + position: sticky; + top: 0; + left: 0; + width: 100%; + border-bottom: 1px solid var(--color2); + z-index: 2; + background: #303030; + } + } + + .episodes-list { + height: 100%; + width: 100%; + background: rgb(200 200 200 / 6%); + overflow-y: overlay; + overflow-x: hidden; + + .episodes-inline-info { + padding: 14px 14px 0px 14px; + + .podcast-show-info { + display: flex; + justify-content: center; + flex-direction: column; + } + + .podcast-show-description { + margin: 32px 6px; + font-size: 0.8rem; + white-space: pre-wrap; + display: block; + } + + .podcast-artwork { + width: 120px; + margin: 0px auto; + height: 120px; + } + } + + .podcast-no-search-results { + text-align: center; + margin-top: 40px; + } + } + + .podcasts-details { + width: 300px; + flex: none; + background: rgb(255 255 255 / 5%); + overflow-y: overlay; + overflow-x: hidden; + top: 2%; + z-index: 2; + border-left: 1px solid var(--color2); + padding-bottom: 1em; + + .meta-btn { + font-size: 0.75em; + } + + .podcasts-details-header { + display: flex; + justify-content: end; + align-items: center; + position: sticky; + top: 0; + z-index: 2; + } + + .close-btn { + width: 50px; + height: 42px; + background-image: var(--gfx-closeBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 0; + right: 0; + + &:hover { + background-color: rgb(196, 43, 28); + } + } + + .podcast-genre { + text-align: center; + margin: 6px; + font-size: 0.8em; + font-weight: 500; + opacity: 0.8; + } + + .podcast-metainfo { + text-align: center; + font-size: 0.7em; + opacity: 0.8; + } + + .podcast-header { + text-align: center; + padding: 0 1rem; + } + + .podcast-play-btn { + width: 50%; + display: block; + margin: 0 auto; + } + + .podcast-description { + margin: 12px; + font-size: 0.75em; + white-space: pre-wrap; + display: block; + line-break: anywhere; + } + } +} + +// Podcast Page +.content-inner.library-artists-page { + // top: 0; + height: calc(100% - 60px - var(--navigationBarHeight)); + padding: 0px; + + .inner-container { + display: flex; + height: calc(100% - var(--navigationBarHeight)); + padding: 0px; + height: 100%; + + .list-flat { + border-radius: 0px; + } + + .podcast-artwork { + width: 200px; + margin: 16px auto; + height: 200px; + } + + .podcasts-list { + height: 100%; + width: 280px; + background: rgb(200 200 200 / 10%); + overflow-y: overlay; + border-right: 1px solid var(--color2); + flex: none; + overflow-x: hidden; + + .podcast-list-header { + border-bottom: 1px solid var(--color2); + font-size: 0.7em; + padding: 6px; + background: #ffffff17; + text-transform: uppercase; + font-weight: 600; + opacity: 0.5; + } + + .podcasts-search { + padding: 10px; + position: sticky; + top: 0; + left: 0; + width: 100%; + border-bottom: 1px solid var(--color2); + z-index: 2; + background: #303030; + } + } + + .episodes-list { + height: calc(100% + 60px); + width: 100%; + background: rgb(200 200 200 / 6%); + overflow-y: overlay; + overflow-x: hidden; + + .episodes-inline-info { + padding: 14px 14px 0px 14px; + + .podcast-show-info { + display: flex; + justify-content: center; + flex-direction: column; + } + + .podcast-show-description { + margin: 32px 6px; + font-size: 0.8rem; + white-space: pre-wrap; + display: block; + } + + .podcast-artwork { + width: 120px; + margin: 0px auto; + height: 120px; + } + } + + .podcast-no-search-results { + text-align: center; + margin-top: 40px; + } + } + + .podcasts-details { + width: 300px; + flex: none; + background: rgb(255 255 255 / 5%); + overflow-y: overlay; + overflow-x: hidden; + top: 2%; + z-index: 2; + border-left: 1px solid var(--color2); + padding-bottom: 1em; + + .meta-btn { + font-size: 0.75em; + } + + .podcasts-details-header { + display: flex; + justify-content: end; + align-items: center; + position: sticky; + top: 0; + z-index: 2; + } + + .close-btn { + width: 50px; + height: 42px; + background-image: var(--gfx-closeBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 0; + right: 0; + + &:hover { + background-color: rgb(196, 43, 28); + } + } + + .podcast-genre { + text-align: center; + margin: 6px; + font-size: 0.8em; + font-weight: 500; + opacity: 0.8; + } + + .podcast-metainfo { + text-align: center; + font-size: 0.7em; + opacity: 0.8; + } + + .podcast-header { + text-align: center; + } + + .podcast-play-btn { + width: 50%; + display: block; + margin: 0 auto; + } + + .podcast-description { + margin: 12px; + font-size: 0.75em; + white-space: pre-wrap; + display: block; + line-break: anywhere; + } + } + } + + @media only screen and (max-width: 1230px) { + .content-inner.podcasts-page { + .podcasts-details { + height: 96%; + width: 300px; + flex: none; + background: rgb(20 20 20 / 97%); + overflow-y: overlay; + overflow-x: hidden; + position: absolute; + right: 2%; + top: 2%; + border-radius: 10px; + box-shadow: var(--ciderShadow-Generic); + z-index: 2; + } + } + } +} + +@media only screen and (max-width: 1230px) { + .content-inner.podcasts-page { + .podcasts-details { + height: 96%; + width: 300px; + flex: none; + background: rgb(20 20 20 / 97%); + overflow-y: overlay; + overflow-x: hidden; + position: absolute; + right: 2%; + top: 2%; + border-radius: 10px; + box-shadow: var(--ciderShadow-Generic); + z-index: 2; + } + } +} + +/* Album / Playlist Page */ +.album-header { + position: sticky; + left: 0; + z-index: 6; + padding: 0px 2em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); + --bs-gutter-x: 4rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-right: calc(-0.5 * var(--bs-gutter-x)); + margin-left: calc(-0.5 * var(--bs-gutter-x)); + border-bottom: 1px solid rgba(200, 200, 200, 0.05); +} +.playlist-page { + --bgColor: transparent; + padding: 0px; + //background: linear-gradient(180deg, var(--bgColor) 32px, var(--bgColor) 18px, transparent 60px, transparent 100%); + top: 0; + padding-top: var(--navigationBarHeight); + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + + .cd-mediaitem-list-item { + &:hover { + .heart-icon { + display: flex; + } + } + + .heart-icon { + left: -25px; + } + } + + .editTracksBtn { + position: absolute; + top: 20px; + right: 20px; + z-index: 1; + + > span { + display: flex; + gap: 8px; + } + } + + .mediaContainer { + transition: + width 0.5s ease-in-out, + height 0.5s ease-in-out; + width: 260px; + height: 260px; + } + + .playlist-body { + padding: 32px; + // margin-top: -75px; + overflow-y: overlay; + height: 100%; + padding: 0px; + background-color: var(--color3); + + &.scrollbody { + .tabs { + display: flex; + flex-flow: column; + height: 100%; + + .nav-link { + text-transform: capitalize; + } + + .tab-content { + height: 100%; + overflow: hidden; + margin: 0px; + + .tab-pane { + height: 100%; + overflow-y: overlay; + overflow-x: hidden; + padding: var(--contentInnerPadding); + padding-inline: 40px; + -webkit-mask-image: linear-gradient(180deg, transparent, white 20px); + + .well { + margin: 0px; + } + } + } + } + } + + .search-input-container { + height: 2.5rem; + margin: 1rem; + margin-top: 0; + scroll-margin-top: 1rem; + + .search-input { + width: 100%; + height: 100%; + } + } + } + + .floating-header { + position: sticky; + top: 0; + left: 0; + border-bottom: 1px solid rgba(200, 200, 200, 0.05); + z-index: 6; + padding: 0px 1em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); + transition: opacity 0.1s var(--appleEase); + display: none; + } + + .playlist-display { + padding: var(--contentInnerPadding); + min-height: 300px; + position: relative; + box-shadow: 0px 4px 6px 3px rgb(0 0 0 / 10%); + transition: min-height 0.5s ease-in-out; + + .artworkContainer { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: 0; + margin-top: calc(var(--navigationBarHeight) * -1); + margin-bottom: -10px; + padding: 0; + -webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%); + opacity: 0.7; + animation: playlistArtworkFadeIn 1s var(--appleEase); + + .artworkMaterial img { + filter: brightness(100%) blur(80px) saturate(100%) contrast(1); + object-position: center; + object-fit: cover; + width: 100%; + height: 100%; + transform: unset; + } + } + + .playlistInfo { + z-index: 1; + position: absolute; + bottom: 0; + left: 0; + right: 0; + top: 0; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + + .playlist-hero { + width: 100%; + transform: translateX(+25%); + position: absolute; + z-index: -1; + top: 0; + left: 0; + right: 0; + bottom: 0; + + .mediaitem-artwork { + -webkit-mask-image: -webkit-radial-gradient(center, circle cover, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0) 75%); + border-radius: 0px; + } + + .hero-tint { + position: absolute; + top: 0; + opacity: 0.6; + width: 100%; + height: 100%; + } + } + + > .row { + width: calc(100% - 32px); + } + + .playlist-info { + flex-shrink: unset; + display: flex; + flex-flow: column; + justify-content: flex-end; + + .playlist-name { + font-weight: 700; + font-size: 1.6rem; + //margin-bottom: 6px; + margin-right: 6px; + margin-bottom: 6px; + flex-shrink: unset; + } + + .search-input::placeholder { + color: var(--heroplaceholdercolor); + } + + .nameEdit { + font-weight: 700; + font-size: 1.6rem; + flex-shrink: unset; + background: transparent; + border: 0px; + color: inherit; + font-family: inherit; + } + + .descriptionEdit { + font-size: 14px; + flex-shrink: unset; + background: transparent; + border: 0px; + color: inherit; + font-family: inherit; + width: 60vw; + } + + .descriptionEdit { + font-size: 14px; + flex-shrink: unset; + background: transparent; + border: 0px; + color: inherit; + font-family: inherit; + width: 60vw; + } + + .playlist-artist { + font-size: 20px; + margin-bottom: 6px; + margin-right: 6px; + flex-shrink: unset; + } + + .playlist-desc { + transition: + height 0.2s ease-in-out, + opacity 0.2s ease-in-out; + box-sizing: border-box; + font-size: 14px; + flex-shrink: unset; + margin-right: 5px; + max-height: 100px; + position: relative; + height: 4vh; + + .content { + height: 4vh; + -webkit-mask-image: -webkit-gradient(linear, left 50%, left 90%, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0))); + } + + .more-btn { + appearance: none; + position: absolute; + right: 0; + bottom: 0; + padding: 0 5px; + font-size: 14px; + color: var(--keyColor); + background-color: transparent; + border: 0px; + cursor: pointer; + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + justify-content: flex-end; + align-items: flex-end; + font-weight: 600; + font-family: inherit; + text-transform: uppercase; + } + } + + .playlist-desc-expanded { + box-sizing: border-box; + font-size: 14px; + position: relative; + + .more-btn { + appearance: none; + position: absolute; + right: 0; + bottom: 0; + padding: 0 5px; + font-size: 14px; + color: var(--keyColor); + background-color: transparent; + border: 0px; + cursor: pointer; + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + justify-content: flex-end; + align-items: flex-end; + font-weight: 600; + font-family: inherit; + text-transform: uppercase; + } + } + + .search-btn { + display: flex; + width: 32px; + align-items: center; + margin-right: 1rem; + background: rgba(100, 100, 100, 0.5); + border: none; + cursor: pointer; + border-radius: 100vmax; + box-shadow: var(--ciderShadow-Generic); + + > ._svg-icon { + width: 18px; + height: 18px; + margin: auto; + } + } + + .search-btn.active { + animation: enlarge 0.5s ease-in-out; + } + + .search-btn:hover { + filter: brightness(125%); + } + + @keyframes enlarge { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } + 100% { + transform: scale(1); + } + } + } + } + } + + .friends-info { + display: flex; + flex-flow: column; + + .badge-container { + display: flex; + flex-flow: wrap; + + .socialBadge { + width: 40px; + height: 40px; + border-radius: 100%; + overflow: hidden; + box-shadow: var(--mediaItemShadow-ShadowSubtle); + transition: transform 0.2s var(--appleEase); + margin: 6px; + + &:hover { + transform: scale(1.2); + } + } + } + + .friends-name { + text-align: center; + font-size: 0.9em; + margin: 8px; + } + } + + .playlist-time { + font-size: 0.9em; + margin: 6px; + opacity: 0.7; + transition: + height 0.2s ease-in-out, + opacity 0.2s ease-in-out; + height: 0.9em; + } + + &.inline-playlist { + overflow: hidden; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 10; + position: sticky; + margin-top: calc(var(--navigationBarHeight) * -1); + + .floating-header { + opacity: 1; + top: 0px; + z-index: 6; + padding: 1em; + backdrop-filter: unset; + background: black; + + h3 { + display: none; + } + } + + .playlist-inner { + background: black; + width: 80%; + height: 100%; + overflow: overlay; + box-shadow: var(--ciderShadow-Generic); + border-radius: var(--mediaItemRadius) var(--mediaItemRadius) 0px 0px; + + .close-btn { + position: sticky; + top: 16px; + left: 16px; + margin-left: 16px; + z-index: 7; + } + } + } + + .pilldim { + .nav-pills { + width: max-content; + margin: 0 auto; + margin-top: 16px; + } + } + + &.plmin { + .playlist-display { + transition: min-height 0.5s ease-in-out; + min-height: 200px; + + .playlistInfo { + } + + .mediaContainer { + transition: + width 0.5s ease-in-out, + height 0.5s ease-in-out; + width: 128px !important; + height: 128px !important; + } + + .playlist-time { + transition: + height 0.2s ease-in-out, + opacity 0.2s ease-in-out; + height: 0px; + opacity: 0; + } + + .playlist-desc { + transition: + height 0.2s ease-in-out, + opacity 0.2s ease-in-out; + height: 0px !important; + opacity: 0; + } + } + } +} + +@keyframes playlistArtworkFadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 0.7; + } +} + +// Collection Page +.collection-page { + padding-bottom: 128px; + + .top-fab { + height: 52px; + width: 52px; + position: fixed; + bottom: 32px; + right: 32px; + border-radius: 100%; + background: rgb(60 60 60); + border: 0px; + appearance: none; + box-shadow: var(--ciderShadow-Generic); + + > svg { + height: 50%; + color: #eee; + pointer-events: none; + } + + &:hover { + background: rgb(100 100 100); + } + + &:active { + background: var(--keyColor); + } + } + + .header-text { + margin-bottom: 32px; + } +} + +/* Artist Page */ + +.artist-page { + padding: 0px; + top: 0; + + .floating-header { + position: sticky; + top: 0; + left: 0; + border-bottom: 1px solid rgba(200, 200, 200, 0.05); + z-index: 6; + padding: 0px 1em; + backdrop-filter: blur(32px); + background: rgba(0, 0, 0, 0.25); + top: var(--navigationBarHeight); + transition: opacity 0.1s var(--appleEase); + } + + &.animated .artist-header .more-btn-round { + position: absolute; + bottom: 22px !important; + right: 28px; + } + + &.animated .artist-header { + min-height: 80vh; + } + + &.animated .artist-header-compact { + min-height: 40vh; + } + + .artist-header { + //background: linear-gradient(45deg, var(--keyColor), #0e0e0e); + color: white; + display: flex; + align-items: center; + justify-content: space-between; + min-height: 400px; + position: relative; + pointer-events: none; + + .header-content { + z-index: 1; + // margin-top: -16px; + } + + .artist-hero { + height: 100%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + + .mediaitem-artwork { + border-radius: 0px; + } + } + + .artworkContainer { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: 0; + padding: 0; + -webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%); + opacity: 0.7; + animation: playlistArtworkFadeIn 1s var(--appleEase); + + .artworkMaterial img { + filter: brightness(100%) blur(80px) saturate(100%) contrast(1); + object-position: center; + object-fit: cover; + width: 100%; + height: 100%; + transform: unset; + } + } + + .more-btn-round { + position: absolute; + bottom: 82px; + right: 28px; + } + + .social-btn { + border-radius: 100%; + background: transparent; + height: 17px; + border: 0px; + cursor: pointer; + z-index: 69; + display: flex; + justify-content: center; + align-items: center; + float: right; + } + @media only screen and (min-width: 1133px) and (max-width: 1277px) { + .about-page { + .social-btn { + display: none !important; + } + } + } + + .animated { + width: 100%; + height: 100%; + align-self: center; + position: absolute; + overflow: hidden; + box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; + z-index: 1; + + video { + overflow: hidden; + height: 100%; + width: 100%; + min-height: 56.25vw; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + object-fit: cover; + } + } + + .row .col.cider-flex-center { + z-index: 4; + } + } + + .artist-image { + width: 200px; + height: 200px; + margin: 32px; + position: relative; + + .overlay-play { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + background: rgb(0 0 0 / 50%); + transition: opacity 0.1s var(--appleEase); + border-radius: 100%; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + appearance: none; + border: 0px; + padding: 0px; + + &:hover { + opacity: 1; + } + + &:active { + background: var(--selected-click); + } + + > svg { + width: 70%; + } + } + } + + .artist-play { + width: 32px; + height: 32px; + background: rgba(100, 100, 100, 0.5); + box-shadow: var(--ciderShadow-Generic); + border-radius: 100%; + box-shadow: var(--mediaItemShadow); + display: none; + cursor: pointer; + appearance: none; + border: 0px; + padding: 0px; + + &:hover { + filter: brightness(125%); + } + + &:active { + filter: brightness(75%); + transform: scale(0.98); + transition: + transform 0s var(--appleEase), + box-shadow 0.2s var(--appleEase); + } + } + + .artist-title { + .artist-play { + transform: translateY(3px); + margin: 14px; + } + + &.artist-animation-on { + width: 100%; + flex: unset; + margin-left: 0.5em; + color: whitesmoke; + position: absolute; + bottom: 0; + + .artist-play { + display: block; + } + } + } + + .artist-body { + padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); + margin: -64px 20px; + + .arow { + display: flex; + overflow: hidden; + padding: 16px 32px; + + > .latestRelease { + width: 250px; + } + + > .topSongs { + width: calc(100% - 250px); + } + + &.arowb > .topSongs { + width: 100%; + } + } + } + + &.animated > .artist-body { + padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); + margin-top: -57px; + } + + .showmoreless { + font-family: inherit; + font-size: 16px; + font-weight: 500; + background: transparent; + border: 0px; + border-radius: 6px; + appearance: none; + color: var(--keyColor); + padding: 8px 12px; + cursor: pointer; + margin-top: 12px; + float: right; + } + + .showmoreless:hover { + background: rgb(200 200 200 / 10%); + } +} + +/* Artist Page End */ + +// Settings page +.settings-page { + padding: 0px; + + .nav { + width: 90%; + margin: 16px auto 0px; + } +} + +.i18n-page { + textarea { + background: black; + color: #eee; + font-weight: bold; + font-size: 1em; + font-family: system-ui, "Pretendard Variable"; + padding: 0.5em; + } + + .selectCol { + display: flex; + align-items: center; + } +} + +// AudioLabs page +.audiolabs-page { + padding: 0px; + + .md-option-header { + padding: 1.25em 1.25em; + border-bottom: unset; + border-top: unset; + font-weight: 600; + font-size: 1em; + background: rgb(255 255 255 / 3%); + } + + .carousel-item > img { + object-fit: cover; + width: 100%; + } + + .spprofile-line { + height: 300px; + width: 100%; + max-width: 1024px; + padding: 16px; + margin: 0 auto; + + .spprofile-viewport { + height: 100%; + position: relative; + border-radius: var(--mediaItemRadius); + overflow: hidden; + box-shadow: var(--mediaItemShadow-Shadow); + background: black; + + .spprev, + .nextprev { + position: absolute; + height: 100%; + width: 64px; + top: 0; + background: rgb(0 0 0 / 20%); + z-index: 1; + border: 0px; + transition: + background 0.2s var(--appleEase), + transform 0.2s var(--appleEase); + + &:hover { + background: var(--selected); + transform: scale(1.1); + } + + &:active { + transition: background 0s var(--appleEase); + background: var(--selected-click); + } + + &:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #eee; + opacity: 1; + -webkit-mask-position: center; + -webkit-mask-repeat: no-repeat; + -webkit-mask-size: 1em; + } + } + + .spprev { + left: 0; + + &:before { + -webkit-mask-image: url("./views/svg/chevron-left.svg"); + } + } + + .nextprev { + right: 0; + + &:before { + -webkit-mask-image: url("./views/svg/chevron-right.svg"); + } + } + + .spslide { + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + background: black; + + > img { + width: 100%; + height: 100%; + object-fit: cover; + } + + .sptitle { + position: absolute; + bottom: 0px; + left: 0; + width: 100%; + text-align: center; + font-size: 18px; + text-shadow: 0px 2px 4px #00000033; + } + } + + .spfade-enter-active, + .spfade-leave-active { + --transitionTime: 0.2s; + transition: + opacity var(--transitionTime) var(--appleEase), + transform var(--transitionTime) var(--appleEase); + will-change: opacity, transform; + } + + .spfade-enter { + opacity: 0; + transform: scale(1.2) translate3d(0, 0, 0); + will-change: opacity, transform; + } + + .spfade-leave-to { + opacity: 1; + transform: scale(1) translate3d(0, 0, 0); + will-change: opacity, transform; + } + } + } + + .settings-option-body { + margin: 16px; + } +} + +@keyframes gradient-animation { + 0% { + background-position: 0% 0%; + } + + 50% { + background-position: 100% 0%; + } + + 100% { + background-position: 0% 0%; + } +} + +//Home +.home-page { + .md-btn-replay { + background-image: linear-gradient(-45deg, #2e2173, #925042); + animation: gradient-animation 5s ease-in-out infinite; + background-size: 400% 400%; + border: 0px; + box-shadow: inset 0px 0px 0px 1px rgba(200, 200, 200, 0.2); + text-transform: uppercase; + font-weight: bold; + } + + .md-btn-replay--hero { + font-size: 1em; + padding: 16px; + background-image: linear-gradient(-45deg, #2e2173, #925042); + animation: gradient-animation 5s ease-in-out infinite; + background-size: 400% 400%; + border: 0px; + box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 20%); + margin-top: 1em; + font-size: 0.9em; + text-transform: uppercase; + font-weight: bold; + } + + .artist-feed-card { + position: absolute; + bottom: 0; + left: 10%; + z-index: 1; + background: black; + width: 80%; + height: 96%; + overflow: scroll; + border-radius: 10px; + } + + .col.madeforyou-col { + width: 420px; + min-width: 0px; + max-width: 420px; + } + + .well.artistfeed-well { + margin-top: 0px; + height: 392px; + align-content: flex-start; + } + + .hint-text { + font-size: 0.9rem; + color: rgb(200 200 200 / 70%); + } + + .user-icon { + border-radius: 100%; + width: 128px; + height: 128px; + overflow: hidden; + box-shadow: var(--mediaItemShadow-Shadow); + margin: 16px; + } + + .well.profile-well { + flex-direction: column; + justify-content: center; + align-items: center; + + .name { + margin: 4px; + font-weight: 500; + } + + .handle { + margin: 4px; + opacity: 0.7; + font-weight: 500; + } + } +} + +// Replay +.replay-page { + --replayTextShadow: 0px 3px 2px #6f3f52; + + .replay-period { + height: 200px; + width: 200px; + margin: 6px; + border-radius: var(--mediaItemRadius); + overflow: hidden; + cursor: pointer; + transition: transform 0.2s var(--appleEase); + transition-delay: 0.1s; + align-self: center; + + &:hover { + transform: translateY(-6px); + transition-delay: 0s; + } + + .artwork-container { + height: 200px; + width: 200px; + } + } + + .replay-playlist-container { + .cd-mediaitem-square { + height: 230px; + width: 230px; + + .info-rect { + display: none; + } + } + } + + .replay-video { + max-height: 300px; + max-width: 800px; + margin: 0 auto; + + .mediaitem-artwork { + max-height: 300px; + max-width: 800px; + } + + .mediaitem-artwork .animatedartwork-view-box .animated video { + object-fit: cover; + } + } + + .top-genres-container { + .genre-name { + font-size: 0.9em; + margin: 6px 0px; + font-weight: 500; + } + + .genre-count { + width: 100%; + height: 32px; + background: #ffffff14; + border-radius: 10px; + overflow: hidden; + + .genre-count-bar { + height: 100%; + width: 0%; + background: var(--keyColor); + display: flex; + justify-content: center; + align-items: center; + min-width: 32px; + font-size: 0.9em; + font-weight: 500; + } + } + } + + .cd-mediaitem-square { + .mediaitem-artwork { + animation: replayFadeIn 0.5s var(--appleEase); + } + + transition: transform 0.2s var(--appleEase); + transition-delay: 0.1s; + + &:hover { + transform: scale(1.1); + transition-delay: 0s; + } + } + + @keyframes replayFadeIn { + 0% { + //border-radius: 100%; + transform: translateY(10px) scale(0.9); + opacity: 0; + } + + 100% { + //border-radius: var(--mediaItemRadius); + transform: scale(1); + opacity: 1; + } + } + + .replay-viewport { + background-image: linear-gradient(-45deg, #2e2173, #925042); + animation: gradient-animation 5s ease-in-out infinite; + background-size: 400% 400%; + padding: 16px 40px; + border-radius: 10px; + box-shadow: var(--mediaItemShadow), var(--mediaItemShadow-Shadow); + color: rgb(238 238 238 / 86%); + + .replay-header { + text-align: center; + font-size: 3em; + text-shadow: var(--replayTextShadow); + } + } + + .replay-card { + background: transparent; + border: 0px; + } +} + +.content-inner.oobe { + position: absolute; + overflow: hidden; + top: 0; + left: 0; + bottom: 0; + right: 0; + display: grid; + place-items: center; + width: 100%; + background: #1e1e1e; + + .oobe-view { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 32px; + max-width: 1280px; + max-height: 720px; + align-self: center; + justify-self: center; + height: 100%; + width: 100%; + + .oobe-header { + font-size: 3em; + text-shadow: var(--replayTextShadow); + font-weight: 600; + } + + .oobe-body { + flex: 1; + width: 100%; + background: #ffffff0d; + border-radius: 20px; + padding: 3em; + overflow-y: scroll; + overflow-x: hidden; + + @media screen and (max-width: 1161px) { + font-size: 13px; + } + + &.text { + white-space: pre-wrap; + } + + .blurb { + white-space: pre-wrap; + margin: 16px; + line-height: 1.5em; + } + + &.visual { + padding: 1em; + + .stylePicker { + border-radius: 10px; + overflow: hidden; + cursor: pointer; + transition: 0.25s all; + box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25); + width: 450px; + margin: 0 auto; + + .visualPreview { + pointer-events: none; + transition: 0.25s all; + width: 100%; + } + + .card-body { + padding: 0; + display: flex; + justify-content: center; + align-items: center; + } + + .card-footer { + font-size: 1.25em; + font-weight: 500; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + border: 0px; + text-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25); + font-weight: bold; + } + + &.style-active { + outline: 4px solid var(--keyColor); + } + + &:hover { + transform: scale(1.1) translateZ(-1px) translateY(10px); + z-index: 1; + box-shadow: 0px 12px 16px rgb(0 0 0 / 25%); + } + + @media screen and (max-height: 688px) { + width: 270px; + } + } + } + } + + .oobe-footer { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 16px; + + .md-btn { + font-size: 18px; + min-width: 128px; + text-align: center; + } + } + } + + .oobe-titlebar { + position: absolute; + top: 0; + left: 0; + height: 46px; + width: 100%; + align-items: center; + justify-content: right; + display: flex; + -webkit-app-region: drag; + + .button-group { + -webkit-app-region: no-drag; + display: flex; + flex-direction: row; + width: 100px; + height: 100%; + justify-content: center; + align-items: center; + gap: 16px; + + > button { + height: 32px; + width: 32px; + font-size: 16px; + border-radius: 0px; + border: 0; + appearance: none; + position: relative; + display: flex; + justify-content: center; + align-items: center; + border-radius: 100%; + + &.close { + background-color: #fc3c44aa; + + &:hover { + background-color: #fc3c44; + } + } + + &.min { + background-color: rgb(200 200 200 / 5%); + + &:hover { + background-color: rgb(200 200 200 / 10%); + } + } + + &.close::before { + font-family: "codicon"; + content: "îǏ"; + color: white; + } + + &.min::before { + font-family: "codicon"; + content: "îĒē"; + color: white; + } + } + } + } +} + +.content-inner.cider-multiroom { + padding: 0px; + + .detail { + padding: 32px; + } + + .header-desc { + font-size: 1em; + font-weight: 400; + } + + .artworkContainer { + height: 300px; + width: 100%; + + img { + height: 100%; + width: 100%; + overflow: hidden; + object-fit: cover; + filter: unset; + + &:last-child { + transform: unset; + } + } + } +} + +.settings-panel { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgb(0 0 0 / 0); + display: flex; + justify-content: center; + align-items: center; + z-index: 16; + + .settings-window { + background: var(--baseColorMix); + max-width: 90%; + max-height: 90%; + width: 100%; + height: 100%; + border-radius: 10px; + box-shadow: var(--ciderShadow-Generic); + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + position: relative; + flex: 1; + backdrop-filter: var(--glassFilterHeavy); + transition: + width 0.25s ease-in-out, + height 0.25s ease-in-out, + max-width 0.25s ease-in-out, + max-height 0.25s ease-in-out; + + .header-text { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + opacity: 0.9; + } + + .nav-pills { + gap: 6px; + } + + .nav-pills .nav-link { + display: flex; + gap: 10px; + align-items: center; + height: 35px; + + :nth-child(2) { + white-space: nowrap; + } + } + + .md-option-header { + padding: 0px 26px; + border-bottom: unset; + border-top: unset; + font-weight: 600; + background: rgb(255 255 255 / 0%); + font-size: 2em; + } + + .settings-option-body-webview { + height: 100%; + width: 100%; + } + + .settings-option-body { + margin: 16px; + } + + &.maxed { + width: 100%; + height: 100%; + max-height: 100%; + max-width: 100%; + border-radius: 0px; + box-shadow: unset; + } + + .close-btn { + width: 36px; + height: 36px; + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + appearance: none; + border: 0; + background-color: transparent; + position: absolute; + top: 10px; + right: 10px; + border-radius: 50px; + display: grid; + align-content: center; + z-index: 9; + + &:before { + content: "îŠļ"; + font-family: "codicon"; + color: var(--textColor); + font-size: 20px; + } + + &:hover { + background-color: rgb(196, 43, 28); + } + + &.back-btn { + left: 10px; + right: unset; + } + + &.minmax-btn { + right: 52px; + + &:before { + content: ""; + } + + &.min { + &:before { + content: ""; + } + } + + &:hover { + background-color: var(--selected); + } + } + } + + .tabs { + height: 100%; + width: 100%; + margin: 0; + padding: 0; + + > .col-auto { + width: auto; + overflow-x: hidden; + overflow-y: overlay; + transition: width 0.25s ease-in-out; + } + + .tab-content { + margin: 0 !important; + } + } + + .tab-content { + overflow-y: overlay; + height: 100%; + background-color: var(--panelColor2); + padding: 0px; + padding-top: 48px; + border-left: 1px solid var(--borderColor); + } + + .github-themes-page, + .installed-themes-page { + .header-text { + font-size: 1.25em; + } + } + + .tab-pane { + height: 100%; + } + + .settings-tab-content { + height: 100%; + } + + &.no-sidebar { + .gh-header { + > .row { + &:last-child { + padding-right: 90px; + } + } + } + .tab-content { + padding-top: 0px; + } + + .tabs { + .nav-pills .nav-link { + width: 50px; + :nth-child(2) { + // font-size: 0px; + opacity: 0; + } + } + > .col-auto { + width: 80px; + } + } + } + } +} + +#hid___BV_tab_button__ { + display: none; +} diff --git a/src/renderer/js/bootbox.min.js b/src/renderer/lib/bootbox.min.js similarity index 100% rename from src/renderer/js/bootbox.min.js rename to src/renderer/lib/bootbox.min.js diff --git a/src/renderer/lib/bootstrap-vue.min.js b/src/renderer/lib/bootstrap-vue.min.js new file mode 100644 index 00000000..74575d56 --- /dev/null +++ b/src/renderer/lib/bootstrap-vue.min.js @@ -0,0 +1,11 @@ +/*! + * BootstrapVue 2.21.2 + * + * @link https://bootstrap-vue.org + * @source https://github.com/bootstrap-vue/bootstrap-vue + * @copyright (c) 2016-2021 BootstrapVue + * @license MIT + * https://github.com/bootstrap-vue/bootstrap-vue/blob/master/LICENSE + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("vue")):"function"==typeof define&&define.amd?define(["vue"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrapVue=e(t.Vue)}(this,(function(t){"use strict";function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var i=e(t);function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}function s(t,e,i){return e&&r(t.prototype,e),i&&r(t,i),t}function a(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function l(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,n)}return i}function c(t){for(var e=1;e<arguments.length;e++){var i=null!=arguments[e]?arguments[e]:{};e%2?l(Object(i),!0).forEach((function(e){a(t,e,i[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(i)):l(Object(i)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(i,e))}))}return t}function u(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&h(t,e)}function d(t){return(d=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function h(t,e){return(h=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function f(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}function p(t,e,i){return(p=f()?Reflect.construct:function(t,e,i){var n=[null];n.push.apply(n,e);var o=new(Function.bind.apply(t,n));return i&&h(o,i.prototype),o}).apply(null,arguments)}function m(t){var e="function"==typeof Map?new Map:void 0;return(m=function(t){if(null===t||(i=t,-1===Function.toString.call(i).indexOf("[native code]")))return t;var i;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if("undefined"!=typeof e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return p(t,arguments,d(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),h(n,t)})(t)}function v(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function b(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?v(t):e}function g(t){var e=f();return function(){var i,n=d(t);if(e){var o=d(this).constructor;i=Reflect.construct(n,arguments,o)}else i=n.apply(this,arguments);return b(this,i)}}function y(t,e,i){return(y="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,i){var n=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=d(t)););return t}(t,e);if(n){var o=Object.getOwnPropertyDescriptor(n,e);return o.get?o.get.call(i):o.value}})(t,e,i||t)}function w(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(t)))return;var i=[],n=!0,o=!1,r=void 0;try{for(var s,a=t[Symbol.iterator]();!(n=(s=a.next()).done)&&(i.push(s.value),!e||i.length!==e);n=!0);}catch(t){o=!0,r=t}finally{try{n||null==a.return||a.return()}finally{if(o)throw r}}return i}(t,e)||C(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function T(t){return function(t){if(Array.isArray(t))return x(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||C(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function C(t,e){if(t){if("string"==typeof t)return x(t,e);var i=Object.prototype.toString.call(t).slice(8,-1);return"Object"===i&&t.constructor&&(i=t.constructor.name),"Map"===i||"Set"===i?Array.from(t):"Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?x(t,e):void 0}}function x(t,e){(null==e||e>t.length)&&(e=t.length);for(var i=0,n=new Array(e);i<e;i++)n[i]=t[i];return n}var S=function(){return(S=Object.assign||function(t){for(var e,i=1,n=arguments.length;i<n;i++)for(var o in e=arguments[i])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)},k=/-(\w)/g,$=/:(.*)/,B=/;(?![^(]*\))/g;function _(t,e){return e?e.toUpperCase():""}function D(t){for(var e,i={},n=0,o=t.split(B);n<o.length;n++){var r=o[n].split($),s=r[0],a=r[1];(s=s.trim())&&("string"==typeof a&&(a=a.trim()),i[(e=s,e.replace(k,_))]=a)}return i}function F(){for(var t,e,i={},n=arguments.length;n--;)for(var o=0,r=Object.keys(arguments[n]);o<r.length;o++)switch(t=r[o]){case"class":case"style":case"directives":if(Array.isArray(i[t])||(i[t]=[]),"style"===t){var s=void 0;s=Array.isArray(arguments[n].style)?arguments[n].style:[arguments[n].style];for(var a=0;a<s.length;a++){var l=s[a];"string"==typeof l&&(s[a]=D(l))}arguments[n].style=s}i[t]=i[t].concat(arguments[n][t]);break;case"staticClass":if(!arguments[n][t])break;void 0===i[t]&&(i[t]=""),i[t]&&(i[t]+=" "),i[t]+=arguments[n][t].trim();break;case"on":case"nativeOn":i[t]||(i[t]={});for(var c=0,u=Object.keys(arguments[n][t]||{});c<u.length;c++)e=u[c],i[t][e]?i[t][e]=[].concat(i[t][e],arguments[n][t][e]):i[t][e]=arguments[n][t][e];break;case"attrs":case"props":case"domProps":case"scopedSlots":case"staticStyle":case"hook":case"transition":i[t]||(i[t]={}),i[t]=S({},arguments[n][t],i[t]);break;case"slot":case"key":case"ref":case"tag":case"show":case"keepAlive":default:i[t]||(i[t]=arguments[n][t])}return i}var I,P,O,V="undefined"!=typeof window,E="undefined"!=typeof document,L="undefined"!=typeof navigator,A="undefined"!=typeof Promise,R="undefined"!=typeof MutationObserver||"undefined"!=typeof WebKitMutationObserver||"undefined"!=typeof MozMutationObserver,M=V&&E&&L,H=V?window:{},z=E?document:{},N=L?navigator:{},j=(N.userAgent||"").toLowerCase(),G=j.indexOf("jsdom")>0,W=(/msie|trident/.test(j),function(){var t=!1;if(M)try{var e={get passive(){t=!0}};H.addEventListener("test",e,e),H.removeEventListener("test",e,e)}catch(e){t=!1}return t}()),Y=M&&("ontouchstart"in z.documentElement||N.maxTouchPoints>0),U=M&&Boolean(H.PointerEvent||H.MSPointerEvent),q=M&&"IntersectionObserver"in H&&"IntersectionObserverEntry"in H&&"intersectionRatio"in H.IntersectionObserverEntry.prototype,K="BvConfig",X=["xs","sm","md","lg","xl"],Z=/\[(\d+)]/g,J=/^(BV?)/,Q=/^\d+$/,tt=/^\..+/,et=/^#/,it=/^#[A-Za-z]+[\w\-:.]*$/,nt=/(<([^>]+)>)/gi,ot=/\B([A-Z])/g,rt=/([a-z])([A-Z])/g,st=/^[0-9]*\.?[0-9]+$/,at=/\+/g,lt=/[-/\\^$*+?.()|[\]{}]/g,ct=/[\s\uFEFF\xA0]+/g,ut=/\s+/,dt=/\/\*$/,ht=/(\s|^)(\w)/g,ft=/^\s+/,pt=/_/g,mt=/-(\w)/g,vt=/^\d+-\d\d?-\d\d?(?:\s|T|$)/,bt=/-|\s|T/,gt=/^([0-1]?[0-9]|2[0-3]):[0-5]?[0-9](:[0-5]?[0-9])?$/,yt=/^.*(#[^#]+)$/,wt=/%2C/g,Tt=/[!'()*]/g,Ct=/^(\?|#|&)/,xt=/^\d+(\.\d*)?[/:]\d+(\.\d*)?$/,St=/[/:]/,kt=/^col-/,$t=/^BIcon/,Bt=/-u-.+/,Element=V?H.Element:function(t){u(Element,t);var e=g(Element);function Element(){return o(this,Element),e.apply(this,arguments)}return Element}(m(Object)),HTMLElement=V?H.HTMLElement:function(t){u(HTMLElement,t);var e=g(HTMLElement);function HTMLElement(){return o(this,HTMLElement),e.apply(this,arguments)}return HTMLElement}(Element),SVGElement=V?H.SVGElement:function(t){u(SVGElement,t);var e=g(SVGElement);function SVGElement(){return o(this,SVGElement),e.apply(this,arguments)}return SVGElement}(Element),_t=V?H.File:function(t){u(i,t);var e=g(i);function i(){return o(this,i),e.apply(this,arguments)}return i}(m(Object)),Dt=function(t){return n(t)},Ft=function(t){return void 0===t},It=function(t){return null===t},Pt=function(t){return Ft(t)||It(t)},Ot=function(t){return"function"===Dt(t)},Vt=function(t){return"boolean"===Dt(t)},Et=function(t){return"string"===Dt(t)},Lt=function(t){return"number"===Dt(t)},At=function(t){return st.test(String(t))},Rt=function(t){return Array.isArray(t)},Mt=function(t){return null!==t&&"object"===n(t)},Ht=function(t){return"[object Object]"===Object.prototype.toString.call(t)},zt=function(t){return t instanceof Date},Nt=function(t){return t instanceof Event},jt=function(t){return"RegExp"===function(t){return Object.prototype.toString.call(t).slice(8,-1)}(t)},Gt=function(){return Object.assign.apply(Object,arguments)},Wt=function(t,e){return Object.create(t,e)},Yt=function(t,e){return Object.defineProperties(t,e)},Ut=function(t,e,i){return Object.defineProperty(t,e,i)},qt=function(t){return Object.getOwnPropertyNames(t)},Kt=function(t){return Object.keys(t)},Xt=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},Zt=function(t){return c({},t)},Jt=function(t,e){return Kt(t).filter((function(t){return-1!==e.indexOf(t)})).reduce((function(e,i){return c(c({},e),{},a({},i,t[i]))}),{})},Qt=function(t,e){return Kt(t).filter((function(t){return-1===e.indexOf(t)})).reduce((function(e,i){return c(c({},e),{},a({},i,t[i]))}),{})},te=function t(e,i){return Mt(e)&&Mt(i)&&Kt(i).forEach((function(n){Mt(i[n])?(e[n]&&Mt(e[n])||(e[n]=i[n]),t(e[n],i[n])):Gt(e,a({},n,i[n]))})),e},ee=function(t){return Kt(t).sort().reduce((function(e,i){return c(c({},e),{},a({},i,t[i]))}),{})},ie=function t(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e;return Rt(e)?e.reduce((function(e,i){return[].concat(T(e),[t(i,i)])}),[]):Ht(e)?Kt(e).reduce((function(i,n){return c(c({},i),{},a({},n,t(e[n],e[n])))}),{}):i},ne=function(t){return t},oe=function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;if(!(e=Rt(e)?e.join("."):e)||!Mt(t))return i;if(e in t)return t[e];var n=(e=String(e).replace(Z,".$1")).split(".").filter(ne);return 0===n.length?i:n.every((function(e){return Mt(t)&&e in t&&!Pt(t=t[e])}))?t:It(t)?null:i},re=function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,n=oe(t,e);return Pt(n)?i:n},se=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i="undefined"!=typeof process&&process&&process.env||{};return t?i[t]||e:i},ae=function(){return se("BOOTSTRAP_VUE_NO_WARN")||"production"===se("NODE_ENV")},le=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;ae()||console.warn("[BootstrapVue warn]: ".concat(e?"".concat(e," - "):"").concat(t))},ce=function(t){return!M&&(le("".concat(t,": Can not be called during SSR.")),!0)},ue=function(t){return!A&&(le("".concat(t,": Requires Promise support.")),!0)},de=function(){function t(){o(this,t),this.$_config={}}return s(t,[{key:"setConfig",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(Ht(e)){var i=qt(e);i.forEach((function(i){var n=e[i];"breakpoints"===i?!Rt(n)||n.length<2||n.some((function(t){return!Et(t)||0===t.length}))?le('"breakpoints" must be an array of at least 2 breakpoint names',K):t.$_config[i]=ie(n):Ht(n)&&(t.$_config[i]=qt(n).reduce((function(t,e){return Ft(n[e])||(t[e]=ie(n[e])),t}),t.$_config[i]||{}))}))}}},{key:"resetConfig",value:function(){this.$_config={}}},{key:"getConfig",value:function(){return ie(this.$_config)}},{key:"getConfigValue",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;return ie(oe(this.$_config,t,e))}}]),t}(),he=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:i.default;e.prototype.$bvConfig=i.default.prototype.$bvConfig=e.prototype.$bvConfig||i.default.prototype.$bvConfig||new de,e.prototype.$bvConfig.setConfig(t)},fe=(I=!1,P=["Multiple instances of Vue detected!","You may need to set up an alias for Vue in your bundler config.","See: https://bootstrap-vue.org/docs#using-module-bundlers"].join("\n"),function(t){I||i.default===t||G||le(P),I=!0}),pe=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.components,i=t.directives,n=t.plugins,o=function t(o){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.installed||(t.installed=!0,fe(o),he(r,o),ge(o,e),we(o,i),ve(o,n))};return o.installed=!1,o},me=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return c(c({},e),{},{install:pe(t)})},ve=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};for(var i in e)i&&e[i]&&t.use(e[i])},be=function(t,e,i){t&&e&&i&&t.component(e,i)},ge=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};for(var i in e)be(t,i,e[i])},ye=function(t,e,i){t&&e&&i&&t.directive(e.replace(/^VB/,"B"),i)},we=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};for(var i in e)ye(t,i,e[i])},Te="BAlert",Ce="BAspect",xe="BAvatar",Se="BAvatarGroup",ke="BBadge",$e="BBreadcrumb",Be="BBreadcrumbItem",_e="BBreadcrumbLink",De="BButton",Fe="BButtonClose",Ie="BButtonGroup",Pe="BButtonToolbar",Oe="BCalendar",Ve="BCard",Ee="BCardBody",Le="BCardFooter",Ae="BCardGroup",Re="BCardHeader",Me="BCardImg",He="BCardImgLazy",ze="BCardSubTitle",Ne="BCardText",je="BCardTitle",Ge="BCarousel",We="BCarouselSlide",Ye="BCol",Ue="BCollapse",qe="BContainer",Ke="BDropdown",Xe="BDropdownDivider",Ze="BDropdownForm",Je="BDropdownGroup",Qe="BDropdownHeader",ti="BDropdownItem",ei="BDropdownItemButton",ii="BDropdownText",ni="BEmbed",oi="BForm",ri="BFormCheckbox",si="BFormCheckboxGroup",ai="BFormDatalist",li="BFormDatepicker",ci="BFormFile",ui="BFormGroup",di="BFormInput",hi="BFormInvalidFeedback",fi="BFormRadio",pi="BFormRadioGroup",mi="BFormRating",vi="BFormRow",bi="BFormSelect",gi="BFormSelectOption",yi="BFormSelectOptionGroup",wi="BFormSpinbutton",Ti="BFormTag",Ci="BFormTags",xi="BFormText",Si="BFormTextarea",ki="BFormTimepicker",$i="BFormValidFeedback",Bi="BIcon",_i="BImg",Di="BImgLazy",Fi="BInputGroup",Ii="BInputGroupAddon",Pi="BInputGroupAppend",Oi="BInputGroupPrepend",Vi="BInputGroupText",Ei="BJumbotron",Li="BLink",Ai="BListGroup",Ri="BListGroupItem",Mi="BMedia",Hi="BMediaAside",zi="BMediaBody",Ni="BModal",ji="BNav",Gi="BNavbar",Wi="BNavbarBrand",Yi="BNavbarNav",Ui="BNavbarToggle",qi="BNavForm",Ki="BNavItem",Xi="BNavItemDropdown",Zi="BOverlay",Ji="BPagination",Qi="BPaginationNav",tn="BPopover",en="BProgress",nn="BProgressBar",on="BRow",rn="BSidebar",sn="BSkeleton",an="BSkeletonIcon",ln="BSkeletonImg",cn="BSkeletonTable",un="BSkeletonWrapper",dn="BSpinner",hn="BTab",fn="BTable",pn="BTableCell",mn="BTableLite",vn="BTableSimple",bn="BTabs",gn="BTbody",yn="BTfoot",wn="BThead",Tn="BTime",Cn="BToast",xn="BToaster",Sn="BTooltip",kn="cancel",$n="change",Bn="click",_n="close",Dn="context",Fn="context-changed",In="destroyed",Pn="disable",On="disabled",Vn="enable",En="enabled",Ln="filtered",An="first",Rn="focusin",Mn="focusout",Hn="head-clicked",zn="hidden",Nn="hide",jn="input",Gn="last",Wn="mouseenter",Yn="mouseleave",Un="next",qn="open",Kn="page-click",Xn="prev",Zn="refreshed",Jn="row-clicked",Qn="selected",to="show",eo="shown",io="sliding-end",no="toggle",oo="hook:beforeDestroy",ro="hook:destroyed",so="bv",ao={passive:!0},lo={passive:!0,capture:!1},co=void 0,uo=Array,ho=Boolean,fo=Date,po=Function,mo=Number,vo=Object,bo=RegExp,go=String,yo=[uo,po],wo=[uo,vo],To=[uo,vo,go],Co=[uo,go],xo=[ho,mo],So=[ho,mo,go],ko=[ho,go],$o=[fo,go],Bo=[po,go],_o=[mo,go],Do=[mo,vo,go],Fo=[vo,po],Io=[vo,go],Po="append",Oo="badge",Vo="bottom-row",Eo="button-content",Lo="custom-foot",Ao="default",Ro="empty",Mo="file-name",Ho="first",zo="footer",No="header",jo="label",Go="lead",Wo="modal-cancel",Yo="modal-ok",Uo="modal-title",qo="prepend",Ko="row-details",Xo="table-busy",Zo="table-caption",Jo="table-colgroup",Qo="thead-top",tr="title",er="top-row",ir=function(){return Array.from.apply(Array,arguments)},nr=function(t,e){return-1!==t.indexOf(e)},or=function(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];return Array.prototype.concat.apply([],e)},rr=function(t,e){var i=Ot(e)?e:function(){return e};return Array.apply(null,{length:t}).map(i)},sr=function(t){return t.reduce((function(t,e){return or(t,e)}),[])},ar=function t(e){return e.reduce((function(e,i){return or(e,Array.isArray(i)?t(i):i)}),[])},lr=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:NaN,i=parseInt(t,10);return isNaN(i)?e:i},cr=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:NaN,i=parseFloat(t);return isNaN(i)?e:i},ur=function(t,e){return cr(t).toFixed(lr(e,0))},dr=function(t){return t.replace(ot,"-$1").toLowerCase()},hr=function(t){return(t=dr(t).replace(mt,(function(t,e){return e?e.toUpperCase():""}))).charAt(0).toUpperCase()+t.slice(1)},fr=function(t){return t.replace(pt," ").replace(rt,(function(t,e,i){return e+" "+i})).replace(ht,(function(t,e,i){return e+i.toUpperCase()}))},pr=function(t){return(t=Et(t)?t.trim():String(t)).charAt(0).toUpperCase()+t.slice(1)},mr=function(t){return t.replace(lt,"\\$&")},vr=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2;return Pt(t)?"":Rt(t)||Ht(t)&&t.toString===Object.prototype.toString?JSON.stringify(t,null,e):String(t)},br=function(t){return vr(t).trim()},gr=function(t){return vr(t).toLowerCase()},yr=Element.prototype,wr=["button","[href]:not(.disabled)","input","select","textarea","[tabindex]","[contenteditable]"].map((function(t){return"".concat(t,":not(:disabled):not([disabled])")})).join(", "),Tr=yr.matches||yr.msMatchesSelector||yr.webkitMatchesSelector,Cr=yr.closest||function(t){var e=this;do{if(Vr(e,t))return e;e=e.parentElement||e.parentNode}while(!It(e)&&e.nodeType===Node.ELEMENT_NODE);return null},xr=H.requestAnimationFrame||H.webkitRequestAnimationFrame||H.mozRequestAnimationFrame||H.msRequestAnimationFrame||H.oRequestAnimationFrame||function(t){return setTimeout(t,16)},Sr=H.MutationObserver||H.WebKitMutationObserver||H.MozMutationObserver||null,kr=function(t){return!(!t||t.nodeType!==Node.ELEMENT_NODE)},$r=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=z.activeElement;return e&&!t.some((function(t){return t===e}))?e:null},Br=function(t,e){return vr(t).toLowerCase()===vr(e).toLowerCase()},_r=function(t){return kr(t)&&t===$r()},Dr=function(t){if(!kr(t)||!t.parentNode||!Lr(z.body,t))return!1;if("none"===Ur(t,"display"))return!1;var e=qr(t);return!!(e&&e.height>0&&e.width>0)},Fr=function(t){return!kr(t)||t.disabled||Gr(t,"disabled")||Hr(t,"disabled")},Ir=function(t){return kr(t)&&t.offsetHeight},Pr=function(t,e){return ir((kr(e)?e:z).querySelectorAll(t))},Or=function(t,e){return(kr(e)?e:z).querySelector(t)||null},Vr=function(t,e){return!!kr(t)&&Tr.call(t,e)},Er=function(t,e){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!kr(e))return null;var n=Cr.call(e,t);return i?n:n===e?null:n},Lr=function(t,e){return!(!t||!Ot(t.contains))&&t.contains(e)},Ar=function(t){return z.getElementById(/^#/.test(t)?t.slice(1):t)||null},Rr=function(t,e){e&&kr(t)&&t.classList&&t.classList.add(e)},Mr=function(t,e){e&&kr(t)&&t.classList&&t.classList.remove(e)},Hr=function(t,e){return!!(e&&kr(t)&&t.classList)&&t.classList.contains(e)},zr=function(t,e,i){e&&kr(t)&&t.setAttribute(e,i)},Nr=function(t,e){e&&kr(t)&&t.removeAttribute(e)},jr=function(t,e){return e&&kr(t)?t.getAttribute(e):null},Gr=function(t,e){return e&&kr(t)?t.hasAttribute(e):null},Wr=function(t,e,i){e&&kr(t)&&(t.style[e]=i)},Yr=function(t,e){e&&kr(t)&&(t.style[e]="")},Ur=function(t,e){return e&&kr(t)&&t.style[e]||null},qr=function(t){return kr(t)?t.getBoundingClientRect():null},Kr=function(t){var e=H.getComputedStyle;return e&&kr(t)?e(t):{}},Xr=function(){return H.getSelection?H.getSelection():null},Zr=function(t){var e={top:0,left:0};if(!kr(t)||0===t.getClientRects().length)return e;var i=qr(t);if(i){var n=t.ownerDocument.defaultView;e.top=i.top+n.pageYOffset,e.left=i.left+n.pageXOffset}return e},Jr=function(t){var e={top:0,left:0};if(!kr(t))return e;var i={top:0,left:0},n=Kr(t);if("fixed"===n.position)e=qr(t)||e;else{e=Zr(t);for(var o=t.ownerDocument,r=t.offsetParent||o.documentElement;r&&(r===o.body||r===o.documentElement)&&"static"===Kr(r).position;)r=r.parentNode;if(r&&r!==t&&r.nodeType===Node.ELEMENT_NODE){i=Zr(r);var s=Kr(r);i.top+=cr(s.borderTopWidth,0),i.left+=cr(s.borderLeftWidth,0)}}return{top:e.top-i.top-cr(n.marginTop,0),left:e.left-i.left-cr(n.marginLeft,0)}},Qr=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document;return Pr(wr,t).filter(Dr).filter((function(t){return t.tabIndex>-1&&!t.disabled}))},ts=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};try{t.focus(e)}catch(t){}return _r(t)},es=function(t){try{t.blur()}catch(t){}return!_r(t)},is=function(t){var e=Wt(null);return function(){for(var i=arguments.length,n=new Array(i),o=0;o<i;o++)n[o]=arguments[o];var r=JSON.stringify(n);return e[r]=e[r]||t.apply(null,n)}},ns=i.default.prototype,os=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0,i=ns.$bvConfig;return i?i.getConfigValue(t,e):ie(e)},rs=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;return e?os("".concat(t,".").concat(e),i):os(t,{})},ss=function(){return os("breakpoints",X)},as=is((function(){return ss()})),ls=is((function(){var t=ie(as());return t[0]="",t})),cs=function(t,e){return t+pr(e)},us=function(t,e){return i=e.replace(t,""),(i=Et(i)?i.trim():String(i)).charAt(0).toLowerCase()+i.slice(1);var i},ds=function(t,e){return e+(t?pr(t):"")},hs=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:co,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0,o=!0===i;return n=o?n:i,c(c(c({},t?{type:t}:{}),o?{required:o}:Ft(e)?{}:{default:Mt(e)?function(){return e}:e}),Ft(n)?{}:{validator:n})},fs=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ne;if(Rt(t))return t.map(e);var i={};for(var n in t)Xt(t,n)&&(i[e(n)]=Mt(t[n])?Zt(t[n]):t[n]);return i},ps=function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:ne;return(Rt(t)?t.slice():Kt(t)).reduce((function(t,n){return t[i(n)]=e[n],t}),{})},ms=function(t,e,i){return c(c({},ie(t)),{},{default:function(){var n=rs(i,e,t.default);return Ot(n)?n():n}})},vs=function(t,e){return Kt(t).reduce((function(i,n){return c(c({},i),{},a({},n,ms(t[n],n,e)))}),{})},bs=ms({},"","").default.name,gs=function(t){return Ot(t)&&t.name!==bs},ys=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.type,o=void 0===n?co:n,r=e.defaultValue,s=void 0===r?void 0:r,l=e.validator,c=void 0===l?void 0:l,u=e.event,d=void 0===u?jn:u,h=a({},t,hs(o,s,c)),f=i.default.extend({model:{prop:t,event:d},props:h});return{mixin:f,props:h,prop:t,event:d}},ws=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return(t=or(t).filter(ne)).some((function(t){return e[t]||i[t]}))},Ts=function(t){var e,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};t=or(t).filter(ne);for(var r=0;r<t.length&&!e;r++){var s=t[r];e=n[s]||o[s]}return Ot(e)?e(i):e},Cs=i.default.extend({methods:{hasNormalizedSlot:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Ao,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.$scopedSlots,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.$slots;return ws(t,e,i)},normalizeSlot:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Ao,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.$scopedSlots,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:this.$slots,o=Ts(t,e,i,n);return o?or(o):o}}}),xs=function(t){return W?Mt(t)?t:{capture:!!t||!1}:!!(Mt(t)?t.capture:t)},Ss=function(t,e,i,n){t&&t.addEventListener&&t.addEventListener(e,i,xs(n))},ks=function(t,e,i,n){t&&t.removeEventListener&&t.removeEventListener(e,i,xs(n))},$s=function(t){for(var e=t?Ss:ks,i=arguments.length,n=new Array(i>1?i-1:0),o=1;o<i;o++)n[o-1]=arguments[o];e.apply(void 0,n)},Bs=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=e.preventDefault,n=void 0===i||i,o=e.propagation,r=void 0===o||o,s=e.immediatePropagation,a=void 0!==s&&s;n&&t.preventDefault(),r&&t.stopPropagation(),a&&t.stopImmediatePropagation()},_s=function(t){return dr(t.replace(J,""))},Ds=function(t,e){return[so,_s(t),e].join("::")},Fs=function(t,e){return[so,e,_s(t)].join("::")},Is=vs({ariaLabel:hs(go,"Close"),content:hs(go,"×"),disabled:hs(ho,!1),textVariant:hs(go)},Fe),Ps=i.default.extend({name:Fe,functional:!0,props:Is,render:function(t,e){var i=e.props,n=e.data,o=e.slots,r=e.scopedSlots,s=o(),l=r||{},c={staticClass:"close",class:a({},"text-".concat(i.textVariant),i.textVariant),attrs:{type:"button",disabled:i.disabled,"aria-label":i.ariaLabel?String(i.ariaLabel):null},on:{click:function(t){i.disabled&&Nt(t)&&Bs(t)}}};return ws(Ao,l,s)||(c.domProps={innerHTML:i.content}),t("button",F(n,c),Ts(Ao,{},l,s))}}),Os={name:"",enterClass:"",enterActiveClass:"",enterToClass:"show",leaveClass:"show",leaveActiveClass:"",leaveToClass:""},Vs=c(c({},Os),{},{enterActiveClass:"fade",leaveActiveClass:"fade"}),Es={appear:hs(ho,!1),mode:hs(go),noFade:hs(ho,!1),transProps:hs(vo)},Ls=i.default.extend({name:"BVTransition",functional:!0,props:Es,render:function(t,e){var i=e.children,n=e.data,o=e.props,r=o.transProps;return Ht(r)||(r=o.noFade?Os:Vs,o.appear&&(r=c(c({},r),{},{appear:!0,appearClass:r.enterClass,appearActiveClass:r.enterActiveClass,appearToClass:r.enterToClass}))),t("transition",F(n,{props:r=c(c({mode:o.mode},r),{},{css:!0})}),i)}}),As=ys("show",{type:So,defaultValue:!1}),Rs=As.mixin,Ms=As.props,Hs=As.prop,zs=As.event,Ns=function(t){return""===t||Vt(t)?0:(t=lr(t,0))>0?t:0},js=function(t){return""===t||!0===t||!(lr(t,0)<1)&&!!t},Gs=vs(ee(c(c({},Ms),{},{dismissLabel:hs(go,"Close"),dismissible:hs(ho,!1),fade:hs(ho,!1),variant:hs(go,"info")})),Te),Ws=me({components:{BAlert:i.default.extend({name:Te,mixins:[Rs,Cs],props:Gs,data:function(){return{countDown:0,localShow:js(this[Hs])}},watch:(O={},a(O,Hs,(function(t){this.countDown=Ns(t),this.localShow=js(t)})),a(O,"countDown",(function(t){var e=this;this.clearCountDownInterval();var i=this[Hs];At(i)&&(this.$emit("dismiss-count-down",t),i!==t&&this.$emit(zs,t),t>0?(this.localShow=!0,this.$_countDownTimeout=setTimeout((function(){e.countDown--}),1e3)):this.$nextTick((function(){xr((function(){e.localShow=!1}))})))})),a(O,"localShow",(function(t){var e=this[Hs];t||!this.dismissible&&!At(e)||this.$emit("dismissed"),At(e)||e===t||this.$emit(zs,t)})),O),created:function(){this.$_filterTimer=null;var t=this[Hs];this.countDown=Ns(t),this.localShow=js(t)},beforeDestroy:function(){this.clearCountDownInterval()},methods:{dismiss:function(){this.clearCountDownInterval(),this.countDown=0,this.localShow=!1},clearCountDownInterval:function(){clearTimeout(this.$_countDownTimeout),this.$_countDownTimeout=null}},render:function(t){var e=t();if(this.localShow){var i=this.dismissible,n=this.variant,o=t();i&&(o=t(Ps,{attrs:{"aria-label":this.dismissLabel},on:{click:this.dismiss}},[this.normalizeSlot("dismiss")])),e=t("div",{staticClass:"alert",class:a({"alert-dismissible":i},"alert-".concat(n),n),attrs:{role:"alert","aria-live":"polite","aria-atomic":!0},key:this._uid},[o,this.normalizeSlot()])}return t(Ls,{props:{noFade:!this.fade}},[e])}})}}),Ys=Math.min,Us=Math.max,qs=Math.abs,Ks=Math.ceil,Xs=Math.floor,Zs=Math.pow,Js=Math.round,Qs="b-aspect",ta=vs({aspect:hs(_o,"1:1"),tag:hs(go,"div")},Ce),ea=i.default.extend({name:Ce,mixins:[Cs],props:ta,computed:{padding:function(){var t=this.aspect,e=1;if(xt.test(t)){var i=w(t.split(St).map((function(t){return cr(t)||1})),2);e=i[0]/i[1]}else e=cr(t)||1;return"".concat(100/qs(e),"%")}},render:function(t){var e=t("div",{staticClass:"".concat(Qs,"-sizer flex-grow-1"),style:{paddingBottom:this.padding,height:0}}),i=t("div",{staticClass:"".concat(Qs,"-content flex-grow-1 w-100 mw-100"),style:{marginLeft:"-100%"}},this.normalizeSlot());return t(this.tag,{staticClass:"".concat(Qs," d-flex")},[e,i])}}),ia=me({components:{BAspect:ea}}),na=function(t){return"%"+t.charCodeAt(0).toString(16)},oa=function(t){return encodeURIComponent(vr(t)).replace(Tt,na).replace(wt,",")},ra=decodeURIComponent,sa=function(t){if(!Ht(t))return"";var e=Kt(t).map((function(e){var i=t[e];return Ft(i)?"":It(i)?oa(e):Rt(i)?i.reduce((function(t,i){return It(i)?t.push(oa(e)):Ft(i)||t.push(oa(e)+"="+oa(i)),t}),[]).join("&"):oa(e)+"="+oa(i)})).filter((function(t){return t.length>0})).join("&");return e?"?".concat(e):""},aa=function(t){var e={};return(t=vr(t).trim().replace(Ct,""))?(t.split("&").forEach((function(t){var i=t.replace(at," ").split("="),n=ra(i.shift()),o=i.length>0?ra(i.join("=")):null;Ft(e[n])?e[n]=o:Rt(e[n])?e[n].push(o):e[n]=[e[n],o]})),e):e},la=function(t){return!(!t.href&&!t.to)},ca=function(t){return!(!t||Br(t,"a"))},ua=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.href,i=t.to,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"a",o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"#",r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"/";if(e)return e;if(ca(n))return null;if(Et(i))return i||r;if(Ht(i)&&(i.path||i.query||i.hash)){var s=vr(i.path),a=sa(i.query),l=vr(i.hash);return l=l&&"#"!==l.charAt(0)?"#".concat(l):l,"".concat(s).concat(a).concat(l)||r}return o},da={viewBox:"0 0 16 16",width:"1em",height:"1em",focusable:"false",role:"img","aria-label":"icon"},ha={width:null,height:null,focusable:null,role:null,"aria-label":null},fa={animation:hs(go),content:hs(go),flipH:hs(ho,!1),flipV:hs(ho,!1),fontScale:hs(_o,1),rotate:hs(_o,0),scale:hs(_o,1),shiftH:hs(_o,0),shiftV:hs(_o,0),stacked:hs(ho,!1),title:hs(go),variant:hs(go)},pa=i.default.extend({name:"BIconBase",functional:!0,props:fa,render:function(t,e){var i,n=e.data,o=e.props,r=e.children,s=o.animation,l=o.content,c=o.flipH,u=o.flipV,d=o.stacked,h=o.title,f=o.variant,p=Us(cr(o.fontScale,1),0)||1,m=Us(cr(o.scale,1),0)||1,v=cr(o.rotate,0),b=cr(o.shiftH,0),g=cr(o.shiftV,0),y=c||u||1!==m,w=y||v,T=b||g,C=!Pt(l),x=t("g",{attrs:{transform:[w?"translate(8 8)":null,y?"scale(".concat((c?-1:1)*m," ").concat((u?-1:1)*m,")"):null,v?"rotate(".concat(v,")"):null,w?"translate(-8 -8)":null].filter(ne).join(" ")||null},domProps:C?{innerHTML:l||""}:{}},r);T&&(x=t("g",{attrs:{transform:"translate(".concat(16*b/16," ").concat(-16*g/16,")")}},[x])),d&&(x=t("g",[x]));var S=[h?t("title",h):null,x].filter(ne);return t("svg",F({staticClass:"b-icon bi",class:(i={},a(i,"text-".concat(f),f),a(i,"b-icon-animation-".concat(s),s),i),attrs:da,style:d?{}:{fontSize:1===p?null:"".concat(100*p,"%")}},n,d?{attrs:ha}:{},{attrs:{xmlns:d?null:"http://www.w3.org/2000/svg",fill:"currentColor"}}),S)}}),ma=function(t,e){var n=dr(t),o="BIcon".concat(hr(t)),r="bi-".concat(n),s=n.replace(/-/g," "),a=br(e||"");return i.default.extend({name:o,functional:!0,props:Qt(fa,["content"]),render:function(t,e){var i=e.data,n=e.props;return t(pa,F({props:{title:s},attrs:{"aria-label":s}},i,{staticClass:r,props:c(c({},n),{},{content:a})}))}})},va=ma("Blank",""),ba=ma("Calendar",'<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>'),ga=ma("CalendarFill",'<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V5h16V4H0V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5z"/>'),ya=ma("ChevronBarLeft",'<path fill-rule="evenodd" d="M11.854 3.646a.5.5 0 0 1 0 .708L8.207 8l3.647 3.646a.5.5 0 0 1-.708.708l-4-4a.5.5 0 0 1 0-.708l4-4a.5.5 0 0 1 .708 0zM4.5 1a.5.5 0 0 0-.5.5v13a.5.5 0 0 0 1 0v-13a.5.5 0 0 0-.5-.5z"/>'),wa=ma("ChevronDoubleLeft",'<path fill-rule="evenodd" d="M8.354 1.646a.5.5 0 0 1 0 .708L2.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/><path fill-rule="evenodd" d="M12.354 1.646a.5.5 0 0 1 0 .708L6.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/>'),Ta=ma("ChevronDown",'<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>'),Ca=ma("ChevronLeft",'<path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/>'),xa=ma("ChevronUp",'<path fill-rule="evenodd" d="M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708l6-6z"/>'),Sa=ma("CircleFill",'<circle cx="8" cy="8" r="8"/>'),ka=ma("Clock",'<path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/><path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/>'),$a=ma("ClockFill",'<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/>'),Ba=ma("Dash",'<path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8z"/>'),_a=ma("PersonFill",'<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>'),Da=ma("Plus",'<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>'),Fa=ma("Star",'<path d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.523-3.356c.329-.314.158-.888-.283-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767l-3.686 1.894.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288l1.847-3.658 1.846 3.658a.525.525 0 0 0 .393.288l4.052.575-2.906 2.77a.564.564 0 0 0-.163.506l.694 3.957-3.686-1.894a.503.503 0 0 0-.461 0z"/>'),Ia=ma("StarFill",'<path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>'),Pa=ma("StarHalf",'<path d="M5.354 5.119L7.538.792A.516.516 0 0 1 8 .5c.183 0 .366.097.465.292l2.184 4.327 4.898.696A.537.537 0 0 1 16 6.32a.55.55 0 0 1-.17.445l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256a.519.519 0 0 1-.146.05c-.341.06-.668-.254-.6-.642l.83-4.73L.173 6.765a.55.55 0 0 1-.171-.403.59.59 0 0 1 .084-.302.513.513 0 0 1 .37-.245l4.898-.696zM8 12.027c.08 0 .16.018.232.056l3.686 1.894-.694-3.957a.564.564 0 0 1 .163-.505l2.906-2.77-4.052-.576a.525.525 0 0 1-.393-.288L8.002 2.223 8 2.226v9.8z"/>'),Oa=ma("X",'<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>'),Va=function t(e,i){return e?(e.$options||{}).components[i]||t(e.$parent,i):null},Ea=Qt(fa,["content"]),La=vs(ee(c(c({},Ea),{},{icon:hs(go)})),Bi),Aa=i.default.extend({name:Bi,functional:!0,props:La,render:function(t,e){var i=e.data,n=e.props,o=e.parent,r=hr(br(n.icon||"")).replace($t,"");return t(r&&Va(o,"BIcon".concat(r))||va,F(i,{props:ps(Ea,n)}))}}),Ra=40,Ma=35,Ha=13,za=36,Na=37,ja=39,Ga=32,Wa=38,Ya=function(t,e){if(t.length!==e.length)return!1;for(var i=!0,n=0;i&&n<t.length;n++)i=Ua(t[n],e[n]);return i},Ua=function t(e,i){if(e===i)return!0;var n=zt(e),o=zt(i);if(n||o)return!(!n||!o)&&e.getTime()===i.getTime();if(n=Rt(e),o=Rt(i),n||o)return!(!n||!o)&&Ya(e,i);if(n=Mt(e),o=Mt(i),n||o){if(!n||!o)return!1;if(Kt(e).length!==Kt(i).length)return!1;for(var r in e){var s=Xt(e,r),a=Xt(i,r);if(s&&!a||!s&&a||!t(e[r],i[r]))return!1}}return String(e)===String(i)},qa=function(t){return!t||0===Kt(t).length},Ka=function(t){return{handler:function(e,i){if(!Ua(e,i))if(qa(e)||qa(i))this[t]=ie(e);else{for(var n in i)Xt(e,n)||this.$delete(this.$data[t],n);for(var o in e)this.$set(this.$data[t],o,e[o])}}}},Xa=function(t,e){return i.default.extend({data:function(){return a({},e,ie(this[t]))},watch:a({},t,Ka(e))})},Za=Xa("$attrs","bvAttrs"),Ja=i.default.extend({methods:{listenOnRoot:function(t,e){var i=this;this.$root.$on(t,e),this.$on(oo,(function(){i.$root.$off(t,e)}))},listenOnRootOnce:function(t,e){var i=this;this.$root.$once(t,e),this.$on(oo,(function(){i.$root.$off(t,e)}))},emitOnRoot:function(t){for(var e,i=arguments.length,n=new Array(i>1?i-1:0),o=1;o<i;o++)n[o-1]=arguments[o];(e=this.$root).$emit.apply(e,[t].concat(n))}}}),Qa=Xa("$listeners","bvListeners"),tl=Ds(Li,"clicked"),el={activeClass:hs(go),append:hs(ho,!1),event:hs(Co,Bn),exact:hs(ho,!1),exactActiveClass:hs(go),replace:hs(ho,!1),routerTag:hs(go,"a"),to:hs(Io)},il={noPrefetch:hs(ho,!1),prefetch:hs(ho,null)},nl=vs(ee(c(c(c({},il),el),{},{active:hs(ho,!1),disabled:hs(ho,!1),href:hs(go),rel:hs(go,null),routerComponentName:hs(go),target:hs(go,"_self")})),Li),ol=i.default.extend({name:Li,mixins:[Za,Qa,Ja,Cs],inheritAttrs:!1,props:nl,computed:{computedTag:function(){return function(t,e){var i=t.to,n=t.disabled,o=t.routerComponentName,r=!!e.$router;return!r||r&&(n||!i)?"a":o||(e.$nuxt?"nuxt-link":"router-link")}({to:this.to,disabled:this.disabled,routerComponentName:this.routerComponentName},this)},isRouterLink:function(){return ca(this.computedTag)},computedRel:function(){return function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target,i=t.rel;return"_blank"===e&&It(i)?"noopener":i||null}({target:this.target,rel:this.rel})},computedHref:function(){var t=this.to,e=this.href;return ua({to:t,href:e},this.computedTag)},computedProps:function(){var t=this.prefetch;return this.isRouterLink?c(c({},ps(c(c({},el),il),this)),{},{prefetch:Vt(t)?t:void 0,tag:this.routerTag}):{}},computedAttrs:function(){var t=this.bvAttrs,e=this.computedHref,i=this.computedRel,n=this.disabled,o=this.target,r=this.routerTag,s=this.isRouterLink;return c(c(c(c({},t),e?{href:e}:{}),s&&!Br(r,"a")?{}:{rel:i,target:o}),{},{tabindex:n?"-1":Ft(t.tabindex)?null:t.tabindex,"aria-disabled":n?"true":null})},computedListeners:function(){return c(c({},this.bvListeners),{},{click:this.onClick})}},methods:{onClick:function(t){var e=arguments,i=Nt(t),n=this.isRouterLink,o=this.bvListeners.click;i&&this.disabled?Bs(t,{immediatePropagation:!0}):(n&&t.currentTarget.__vue__&&t.currentTarget.__vue__.$emit(Bn,t),or(o).filter((function(t){return Ot(t)})).forEach((function(t){t.apply(void 0,T(e))})),this.emitOnRoot(tl,t),this.emitOnRoot("clicked::link",t)),i&&!n&&"#"===this.computedHref&&Bs(t,{propagation:!1})},focus:function(){ts(this.$el)},blur:function(){es(this.$el)}},render:function(t){var e=this.active,i=this.disabled;return t(this.computedTag,a({class:{active:e,disabled:i},attrs:this.computedAttrs,props:this.computedProps},this.isRouterLink?"nativeOn":"on",this.computedListeners),this.normalizeSlot())}}),rl=Qt(nl,["event","routerTag"]);delete rl.href.default,delete rl.to.default;var sl=vs(ee(c(c({},rl),{},{block:hs(ho,!1),disabled:hs(ho,!1),pill:hs(ho,!1),pressed:hs(ho,null),size:hs(go),squared:hs(ho,!1),tag:hs(go,"button"),type:hs(go,"button"),variant:hs(go,"secondary")})),De),al=function(t){"focusin"===t.type?Rr(t.target,"focus"):"focusout"===t.type&&Mr(t.target,"focus")},ll=function(t){return la(t)||Br(t.tag,"a")},cl=function(t){return Vt(t.pressed)},ul=function(t){return!(ll(t)||t.tag&&!Br(t.tag,"button"))},dl=function(t){return!ll(t)&&!ul(t)},hl=function(t){var e;return["btn-".concat(t.variant||"secondary"),(e={},a(e,"btn-".concat(t.size),t.size),a(e,"btn-block",t.block),a(e,"rounded-pill",t.pill),a(e,"rounded-0",t.squared&&!t.pill),a(e,"disabled",t.disabled),a(e,"active",t.pressed),e)]},fl=function(t){return ll(t)?ps(rl,t):{}},pl=function(t,e){var i=ul(t),n=ll(t),o=cl(t),r=dl(t),s=n&&"#"===t.href,a=e.attrs&&e.attrs.role?e.attrs.role:null,l=e.attrs?e.attrs.tabindex:null;return(r||s)&&(l="0"),{type:i&&!n?t.type:null,disabled:i?t.disabled:null,role:r||s?"button":a,"aria-disabled":r?String(t.disabled):null,"aria-pressed":o?String(t.pressed):null,autocomplete:o?"off":null,tabindex:t.disabled&&!i?"-1":l}},ml=i.default.extend({name:De,functional:!0,props:sl,render:function(t,e){var i=e.props,n=e.data,o=e.listeners,r=e.children,s=cl(i),a=ll(i),l=dl(i),c=a&&"#"===i.href,u={keydown:function(t){if(!i.disabled&&(l||c)){var e=t.keyCode;if(e===Ga||e===Ha&&l){var n=t.currentTarget||t.target;Bs(t,{propagation:!1}),n.click()}}},click:function(t){i.disabled&&Nt(t)?Bs(t):s&&o&&o["update:pressed"]&&or(o["update:pressed"]).forEach((function(t){Ot(t)&&t(!i.pressed)}))}};s&&(u.focusin=al,u.focusout=al);var d={staticClass:"btn",class:hl(i),props:fl(i),attrs:pl(i,n),on:u};return t(a?ol:i.tag,F(n,d),r)}}),vl="b-avatar",bl=["sm",null,"lg"],gl=function(t){return t=Et(t)&&At(t)?cr(t,0):t,Lt(t)?"".concat(t,"px"):t||null},yl=Qt(nl,["active","event","routerTag"]),wl=vs(ee(c(c({},yl),{},{alt:hs(go,"avatar"),ariaLabel:hs(go),badge:hs(ko,!1),badgeLeft:hs(ho,!1),badgeOffset:hs(go),badgeTop:hs(ho,!1),badgeVariant:hs(go,"primary"),button:hs(ho,!1),buttonType:hs(go,"button"),icon:hs(go),rounded:hs(ko,!1),size:hs(_o),square:hs(ho,!1),src:hs(go),text:hs(go),variant:hs(go,"secondary")})),xe),Tl=i.default.extend({name:xe,mixins:[Cs],inject:{bvAvatarGroup:{default:null}},props:wl,data:function(){return{localSrc:this.src||null}},computed:{computedSize:function(){var t=this.bvAvatarGroup;return gl(t?t.size:this.size)},computedVariant:function(){var t=this.bvAvatarGroup;return t&&t.variant?t.variant:this.variant},computedRounded:function(){var t=this.bvAvatarGroup,e=!(!t||!t.square)||this.square,i=t&&t.rounded?t.rounded:this.rounded;return e?"0":""===i||(i||"circle")},fontStyle:function(){var t=this.computedSize,e=-1===bl.indexOf(t)?"calc(".concat(t," * ").concat(.4,")"):null;return e?{fontSize:e}:{}},marginStyle:function(){var t=this.computedSize,e=this.bvAvatarGroup,i=e?e.overlapScale:0,n=t&&i?"calc(".concat(t," * -").concat(i,")"):null;return n?{marginLeft:n,marginRight:n}:{}},badgeStyle:function(){var t=this.computedSize,e=this.badgeTop,i=this.badgeLeft,n=this.badgeOffset||"0px";return{fontSize:-1===bl.indexOf(t)?"calc(".concat(t," * ").concat(.27999999999999997," )"):null,top:e?n:null,bottom:e?null:n,left:i?n:null,right:i?null:n}}},watch:{src:function(t,e){t!==e&&(this.localSrc=t||null)}},methods:{onImgError:function(t){this.localSrc=null,this.$emit("img-error",t)},onClick:function(t){this.$emit(Bn,t)}},render:function(t){var e,i=this.computedVariant,n=this.disabled,o=this.computedRounded,r=this.icon,s=this.localSrc,l=this.text,u=this.fontStyle,d=this.marginStyle,h=this.computedSize,f=this.button,p=this.buttonType,m=this.badge,v=this.badgeVariant,b=this.badgeStyle,g=!f&&la(this),y=f?ml:g?ol:"span",w=this.alt,T=this.ariaLabel||null,C=null;this.hasNormalizedSlot()?C=t("span",{staticClass:"b-avatar-custom"},[this.normalizeSlot()]):s?(C=t("img",{style:i?{}:{width:"100%",height:"100%"},attrs:{src:s,alt:w},on:{error:this.onImgError}}),C=t("span",{staticClass:"b-avatar-img"},[C])):C=r?t(Aa,{props:{icon:r},attrs:{"aria-hidden":"true",alt:w}}):l?t("span",{staticClass:"b-avatar-text",style:u},[t("span",l)]):t(_a,{attrs:{"aria-hidden":"true",alt:w}});var x=t(),S=this.hasNormalizedSlot(Oo);if(m||""===m||S){var k=!0===m?"":m;x=t("span",{staticClass:"b-avatar-badge",class:a({},"badge-".concat(v),v),style:b},[S?this.normalizeSlot(Oo):k])}return t(y,{staticClass:vl,class:(e={},a(e,"".concat(vl,"-").concat(h),h&&-1!==bl.indexOf(h)),a(e,"badge-".concat(i),!f&&i),a(e,"rounded",!0===o),a(e,"rounded-".concat(o),o&&!0!==o),a(e,"disabled",n),e),style:c(c({},d),{},{width:h,height:h}),attrs:{"aria-label":T||null},props:f?{variant:i,disabled:n,type:p}:g?ps(yl,this):{},on:f||g?{click:this.onClick}:{}},[C,x])}}),Cl=vs({overlap:hs(_o,.3),rounded:hs(ko,!1),size:hs(go),square:hs(ho,!1),tag:hs(go,"div"),variant:hs(go)},Se),xl=me({components:{BAvatar:Tl,BAvatarGroup:i.default.extend({name:Se,mixins:[Cs],provide:function(){return{bvAvatarGroup:this}},props:Cl,computed:{computedSize:function(){return gl(this.size)},overlapScale:function(){return Ys(Us(cr(this.overlap,0),0),1)/2},paddingStyle:function(){var t=this.computedSize;return(t=t?"calc(".concat(t," * ").concat(this.overlapScale,")"):null)?{paddingLeft:t,paddingRight:t}:{}}},render:function(t){var e=t("div",{staticClass:"b-avatar-group-inner",style:this.paddingStyle},this.normalizeSlot());return t(this.tag,{staticClass:"b-avatar-group",attrs:{role:"group"}},[e])}})}}),Sl=Qt(nl,["event","routerTag"]);delete Sl.href.default,delete Sl.to.default;var kl,$l=vs(ee(c(c({},Sl),{},{pill:hs(ho,!1),tag:hs(go,"span"),variant:hs(go,"secondary")})),ke),Bl=i.default.extend({name:ke,functional:!0,props:$l,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.active,s=i.disabled,a=la(i),l=a?ol:i.tag,c=i.variant||"secondary";return t(l,F(n,{staticClass:"badge",class:["badge-".concat(c),{"badge-pill":i.pill,active:r,disabled:s}],props:a?ps(Sl,i):{}}),o)}}),_l=me({components:{BBadge:Bl}}),Dl=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return String(t).replace(nt,"")},Fl=function(t,e){return t?{innerHTML:t}:e?{textContent:e}:{}},Il=vs(ee(c(c({},Qt(nl,["event","routerTag"])),{},{ariaCurrent:hs(go,"location"),html:hs(go),text:hs(go)})),_e),Pl=i.default.extend({name:_e,functional:!0,props:Il,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.active,s=r?"span":ol,a={attrs:{"aria-current":r?i.ariaCurrent:null},props:ps(Il,i)};return o||(a.domProps=Fl(i.html,i.text)),t(s,F(n,a),o)}}),Ol=vs(Il,Be),Vl=i.default.extend({name:Be,functional:!0,props:Ol,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t("li",F(n,{staticClass:"breadcrumb-item",class:{active:i.active}}),[t(Pl,{props:i},o)])}}),El=vs({items:hs(uo)},$e),Ll=me({components:{BBreadcrumb:i.default.extend({name:$e,functional:!0,props:El,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.items,s=o;if(Rt(r)){var a=!1;s=r.map((function(e,i){Mt(e)||(e={text:vr(e)});var n=e.active;return n&&(a=!0),n||a||(n=i+1===r.length),t(Vl,{props:c(c({},e),{},{active:n})})}))}return t("ol",F(n,{staticClass:"breadcrumb"}),s)}}),BBreadcrumbItem:Vl,BBreadcrumbLink:Pl}}),Al=me({components:{BButton:ml,BBtn:ml,BButtonClose:Ps,BBtnClose:Ps}}),Rl=vs(ee(c(c({},Jt(sl,["size"])),{},{ariaRole:hs(go,"group"),size:hs(go),tag:hs(go,"div"),vertical:hs(ho,!1)})),Ie),Ml=i.default.extend({name:Ie,functional:!0,props:Rl,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.tag,F(n,{class:a({"btn-group":!i.vertical,"btn-group-vertical":i.vertical},"btn-group-".concat(i.size),i.size),attrs:{role:i.ariaRole}}),o)}}),Hl=me({components:{BButtonGroup:Ml,BBtnGroup:Ml}}),zl=[".btn:not(.disabled):not([disabled]):not(.dropdown-item)",".form-control:not(.disabled):not([disabled])","select:not(.disabled):not([disabled])",'input[type="checkbox"]:not(.disabled)','input[type="radio"]:not(.disabled)'].join(","),Nl=vs({justify:hs(ho,!1),keyNav:hs(ho,!1)},Pe),jl=i.default.extend({name:Pe,mixins:[Cs],props:Nl,mounted:function(){this.keyNav&&this.getItems()},methods:{getItems:function(){var t=Pr(zl,this.$el);return t.forEach((function(t){t.tabIndex=-1})),t.filter((function(t){return Dr(t)}))},focusFirst:function(){var t=this.getItems();ts(t[0])},focusPrev:function(t){var e=this.getItems(),i=e.indexOf(t.target);i>-1&&(e=e.slice(0,i).reverse(),ts(e[0]))},focusNext:function(t){var e=this.getItems(),i=e.indexOf(t.target);i>-1&&(e=e.slice(i+1),ts(e[0]))},focusLast:function(){var t=this.getItems().reverse();ts(t[0])},onFocusin:function(t){var e=this.$el;t.target!==e||Lr(e,t.relatedTarget)||(Bs(t),this.focusFirst(t))},onKeydown:function(t){var e=t.keyCode,i=t.shiftKey;e===Wa||e===Na?(Bs(t),i?this.focusFirst(t):this.focusPrev(t)):e!==Ra&&e!==ja||(Bs(t),i?this.focusLast(t):this.focusNext(t))}},render:function(t){var e=this.keyNav;return t("div",{staticClass:"btn-toolbar",class:{"justify-content-between":this.justify},attrs:{role:"toolbar",tabindex:e?"0":null},on:e?{focusin:this.onFocusin,keydown:this.onKeydown}:{}},[this.normalizeSlot()])}}),Gl=me({components:{BButtonToolbar:jl,BBtnToolbar:jl}}),Wl="gregory",Yl="long",Ul="short",ql="2-digit",Kl="numeric",Xl=function(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];return p(Date,e)},Zl=function(t){if(Et(t)&&vt.test(t.trim())){var e=w(t.split(bt).map((function(t){return lr(t,1)})),3),i=e[0],n=e[1],o=e[2];return Xl(i,n-1,o)}return zt(t)?Xl(t.getFullYear(),t.getMonth(),t.getDate()):null},Jl=function(t){if(!(t=Zl(t)))return null;var e=t.getFullYear(),i="0".concat(t.getMonth()+1).slice(-2),n="0".concat(t.getDate()).slice(-2);return"".concat(e,"-").concat(i,"-").concat(n)},Ql=function(t,e){return new Intl.DateTimeFormat(t,e).format},tc=function(t,e){return Jl(t)===Jl(e)},ec=function(t){return(t=Xl(t)).setDate(1),t},ic=function(t){return(t=Xl(t)).setMonth(t.getMonth()+1),t.setDate(0),t},nc=function(t,e){var i=(t=Xl(t)).getMonth();return t.setFullYear(t.getFullYear()+e),t.getMonth()!==i&&t.setDate(0),t},oc=function(t){var e=(t=Xl(t)).getMonth();return t.setMonth(e-1),t.getMonth()===e&&t.setDate(0),t},rc=function(t){var e=(t=Xl(t)).getMonth();return t.setMonth(e+1),t.getMonth()===(e+2)%12&&t.setDate(0),t},sc=function(t){return nc(t,-1)},ac=function(t){return nc(t,1)},lc=function(t){return nc(t,-10)},cc=function(t){return nc(t,10)},uc=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return t=Zl(t),e=Zl(e)||t,i=Zl(i)||t,t?t<e?e:t>i?i:t:null},dc=["ar","az","ckb","fa","he","ks","lrc","mzn","ps","sd","te","ug","ur","yi"].map((function(t){return t.toLowerCase()})),hc=function(t){var e=vr(t).toLowerCase().replace(Bt,"").split("-"),i=e.slice(0,2).join("-"),n=e[0];return nr(dc,i)||nr(dc,n)},fc={id:hs(go)},pc=i.default.extend({props:fc,data:function(){return{localId_:null}},computed:{safeId:function(){var t=this.id||this.localId_;return function(e){return t?(e=String(e||"").replace(/\s+/g,"_"))?t+"_"+e:t:null}}},mounted:function(){var t=this;this.$nextTick((function(){t.localId_="__BVID__".concat(t._uid)}))}}),mc=ys("value",{type:$o}),vc=mc.mixin,bc=mc.props,gc=mc.prop,yc=mc.event,wc=vs(ee(c(c(c({},fc),bc),{},{ariaControls:hs(go),block:hs(ho,!1),dateDisabledFn:hs(po),dateFormatOptions:hs(vo,{year:Kl,month:Yl,day:Kl,weekday:Yl}),dateInfoFn:hs(po),direction:hs(go),disabled:hs(ho,!1),hidden:hs(ho,!1),hideHeader:hs(ho,!1),initialDate:hs($o),labelCalendar:hs(go,"Calendar"),labelCurrentMonth:hs(go,"Current month"),labelHelp:hs(go,"Use cursor keys to navigate calendar dates"),labelNav:hs(go,"Calendar navigation"),labelNextDecade:hs(go,"Next decade"),labelNextMonth:hs(go,"Next month"),labelNextYear:hs(go,"Next year"),labelNoDateSelected:hs(go,"No date selected"),labelPrevDecade:hs(go,"Previous decade"),labelPrevMonth:hs(go,"Previous month"),labelPrevYear:hs(go,"Previous year"),labelSelected:hs(go,"Selected date"),labelToday:hs(go,"Today"),locale:hs(Co),max:hs($o),min:hs($o),navButtonVariant:hs(go,"secondary"),noHighlightToday:hs(ho,!1),noKeyNav:hs(ho,!1),readonly:hs(ho,!1),roleDescription:hs(go),selectedVariant:hs(go,"primary"),showDecadeNav:hs(ho,!1),startWeekday:hs(_o,0),todayVariant:hs(go),valueAsDate:hs(ho,!1),weekdayHeaderFormat:hs(go,Ul,(function(t){return nr([Yl,Ul,"narrow"],t)})),width:hs(go,"270px")})),Oe),Tc=i.default.extend({name:Oe,mixins:[Za,pc,vc,Cs],props:wc,data:function(){var t=Jl(this[gc])||"";return{selectedYMD:t,activeYMD:t||Jl(uc(this.initialDate||this.getToday()),this.min,this.max),gridHasFocus:!1,isLive:!1}},computed:{valueId:function(){return this.safeId()},widgetId:function(){return this.safeId("_calendar-wrapper_")},navId:function(){return this.safeId("_calendar-nav_")},gridId:function(){return this.safeId("_calendar-grid_")},gridCaptionId:function(){return this.safeId("_calendar-grid-caption_")},gridHelpId:function(){return this.safeId("_calendar-grid-help_")},activeId:function(){return this.activeYMD?this.safeId("_cell-".concat(this.activeYMD,"_")):null},selectedDate:function(){return Zl(this.selectedYMD)},activeDate:function(){return Zl(this.activeYMD)},computedMin:function(){return Zl(this.min)},computedMax:function(){return Zl(this.max)},computedWeekStarts:function(){return Us(lr(this.startWeekday,0),0)%7},computedLocale:function(){return function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Wl;return t=or(t).filter(ne),new Intl.DateTimeFormat(t,{calendar:e}).resolvedOptions().locale}(or(this.locale).filter(ne),Wl)},computedDateDisabledFn:function(){var t=this.dateDisabledFn;return gs(t)?t:function(){return!1}},computedDateInfoFn:function(){var t=this.dateInfoFn;return gs(t)?t:function(){return{}}},calendarLocale:function(){var t=new Intl.DateTimeFormat(this.computedLocale,{calendar:Wl}),e=t.resolvedOptions().calendar,i=t.resolvedOptions().locale;return e!==Wl&&(i=i.replace(/-u-.+$/i,"").concat("-u-ca-gregory")),i},calendarYear:function(){return this.activeDate.getFullYear()},calendarMonth:function(){return this.activeDate.getMonth()},calendarFirstDay:function(){return Xl(this.calendarYear,this.calendarMonth,1,12)},calendarDaysInMonth:function(){var t=Xl(this.calendarFirstDay);return t.setMonth(t.getMonth()+1,0),t.getDate()},computedVariant:function(){return"btn-".concat(this.selectedVariant||"primary")},computedTodayVariant:function(){return"btn-outline-".concat(this.todayVariant||this.selectedVariant||"primary")},computedNavButtonVariant:function(){return"btn-outline-".concat(this.navButtonVariant||"primary")},isRTL:function(){var t=vr(this.direction).toLowerCase();return"rtl"===t||"ltr"!==t&&hc(this.computedLocale)},context:function(){var t=this.selectedYMD,e=this.activeYMD,i=Zl(t),n=Zl(e);return{selectedYMD:t,selectedDate:i,selectedFormatted:i?this.formatDateString(i):this.labelNoDateSelected,activeYMD:e,activeDate:n,activeFormatted:n?this.formatDateString(n):"",disabled:this.dateDisabled(n),locale:this.computedLocale,calendarLocale:this.calendarLocale,rtl:this.isRTL}},dateOutOfRange:function(){var t=this.computedMin,e=this.computedMax;return function(i){return i=Zl(i),t&&i<t||e&&i>e}},dateDisabled:function(){var t=this,e=this.dateOutOfRange;return function(i){i=Zl(i);var n=Jl(i);return!(!e(i)&&!t.computedDateDisabledFn(n,i))}},formatDateString:function(){return Ql(this.calendarLocale,c(c({year:Kl,month:ql,day:ql},this.dateFormatOptions),{},{hour:void 0,minute:void 0,second:void 0,calendar:Wl}))},formatYearMonth:function(){return Ql(this.calendarLocale,{year:Kl,month:Yl,calendar:Wl})},formatWeekdayName:function(){return Ql(this.calendarLocale,{weekday:Yl,calendar:Wl})},formatWeekdayNameShort:function(){return Ql(this.calendarLocale,{weekday:this.weekdayHeaderFormat||Ul,calendar:Wl})},formatDay:function(){var t=new Intl.NumberFormat([this.computedLocale],{style:"decimal",minimumIntegerDigits:1,minimumFractionDigits:0,maximumFractionDigits:0,notation:"standard"});return function(e){return t.format(e.getDate())}},prevDecadeDisabled:function(){var t=this.computedMin;return this.disabled||t&&ic(lc(this.activeDate))<t},prevYearDisabled:function(){var t=this.computedMin;return this.disabled||t&&ic(sc(this.activeDate))<t},prevMonthDisabled:function(){var t=this.computedMin;return this.disabled||t&&ic(oc(this.activeDate))<t},thisMonthDisabled:function(){return this.disabled},nextMonthDisabled:function(){var t=this.computedMax;return this.disabled||t&&ec(rc(this.activeDate))>t},nextYearDisabled:function(){var t=this.computedMax;return this.disabled||t&&ec(ac(this.activeDate))>t},nextDecadeDisabled:function(){var t=this.computedMax;return this.disabled||t&&ec(cc(this.activeDate))>t},calendar:function(){for(var t=[],e=this.calendarFirstDay,i=e.getFullYear(),n=e.getMonth(),o=this.calendarDaysInMonth,r=e.getDay(),s=0-((this.computedWeekStarts>r?7:0)-this.computedWeekStarts)-r,a=0;a<6&&s<o;a++){t[a]=[];for(var l=0;l<7;l++){s++;var u=Xl(i,n,s),d=u.getMonth(),h=Jl(u),f=this.dateDisabled(u),p=this.computedDateInfoFn(h,Zl(h));p=Et(p)||Rt(p)?{class:p}:Ht(p)?c({class:""},p):{class:""},t[a].push({ymd:h,day:this.formatDay(u),label:this.formatDateString(u),isThisMonth:d===n,isDisabled:f,info:p})}}return t},calendarHeadings:function(){var t=this;return this.calendar[0].map((function(e){return{text:t.formatWeekdayNameShort(Zl(e.ymd)),label:t.formatWeekdayName(Zl(e.ymd))}}))}},watch:(kl={},a(kl,gc,(function(t,e){var i=Jl(t)||"",n=Jl(e)||"";tc(i,n)||(this.activeYMD=i||this.activeYMD,this.selectedYMD=i)})),a(kl,"selectedYMD",(function(t,e){t!==e&&this.$emit(yc,this.valueAsDate?Zl(t)||null:t||"")})),a(kl,"context",(function(t,e){Ua(t,e)||this.$emit(Dn,t)})),a(kl,"hidden",(function(t){this.activeYMD=this.selectedYMD||Jl(this[gc]||this.constrainDate(this.initialDate||this.getToday())),this.setLive(!t)})),kl),created:function(){var t=this;this.$nextTick((function(){t.$emit(Dn,t.context)}))},mounted:function(){this.setLive(!0)},activated:function(){this.setLive(!0)},deactivated:function(){this.setLive(!1)},beforeDestroy:function(){this.setLive(!1)},methods:{focus:function(){this.disabled||ts(this.$refs.grid)},blur:function(){this.disabled||es(this.$refs.grid)},setLive:function(t){var e=this;t?this.$nextTick((function(){xr((function(){e.isLive=!0}))})):this.isLive=!1},getToday:function(){return Zl(Xl())},constrainDate:function(t){return uc(t,this.computedMin,this.computedMax)},emitSelected:function(t){var e=this;this.$nextTick((function(){e.$emit(Qn,Jl(t)||"",Zl(t)||null)}))},setGridFocusFlag:function(t){this.gridHasFocus=!this.disabled&&"focus"===t.type},onKeydownWrapper:function(t){if(!this.noKeyNav){var e=t.altKey,i=t.ctrlKey,n=t.keyCode;if(nr([33,34,Ma,za,Na,Wa,ja,Ra],n)){Bs(t);var o=Xl(this.activeDate),r=Xl(this.activeDate),s=o.getDate(),a=this.constrainDate(this.getToday()),l=this.isRTL;33===n?(o=(e?i?lc:sc:oc)(o),(r=Xl(o)).setDate(1)):34===n?(o=(e?i?cc:ac:rc)(o),(r=Xl(o)).setMonth(r.getMonth()+1),r.setDate(0)):n===Na?(o.setDate(s+(l?1:-1)),r=o=this.constrainDate(o)):n===ja?(o.setDate(s+(l?-1:1)),r=o=this.constrainDate(o)):n===Wa?(o.setDate(s-7),r=o=this.constrainDate(o)):n===Ra?(o.setDate(s+7),r=o=this.constrainDate(o)):n===za?r=o=a:n===Ma&&(r=o=Zl(this.selectedDate)||a),this.dateOutOfRange(r)||tc(o,this.activeDate)||(this.activeYMD=Jl(o)),this.focus()}}},onKeydownGrid:function(t){var e=t.keyCode,i=this.activeDate;e!==Ha&&e!==Ga||(Bs(t),this.disabled||this.readonly||this.dateDisabled(i)||(this.selectedYMD=Jl(i),this.emitSelected(i)),this.focus())},onClickDay:function(t){var e=this.selectedDate,i=this.activeDate,n=Zl(t.ymd);this.disabled||t.isDisabled||this.dateDisabled(n)||(this.readonly||(this.selectedYMD=Jl(tc(n,e)?e:n),this.emitSelected(n)),this.activeYMD=Jl(tc(n,i)?i:Xl(n)),this.focus())},gotoPrevDecade:function(){this.activeYMD=Jl(this.constrainDate(lc(this.activeDate)))},gotoPrevYear:function(){this.activeYMD=Jl(this.constrainDate(sc(this.activeDate)))},gotoPrevMonth:function(){this.activeYMD=Jl(this.constrainDate(oc(this.activeDate)))},gotoCurrentMonth:function(){this.activeYMD=Jl(this.constrainDate(this.getToday()))},gotoNextMonth:function(){this.activeYMD=Jl(this.constrainDate(rc(this.activeDate)))},gotoNextYear:function(){this.activeYMD=Jl(this.constrainDate(ac(this.activeDate)))},gotoNextDecade:function(){this.activeYMD=Jl(this.constrainDate(cc(this.activeDate)))},onHeaderClick:function(){this.disabled||(this.activeYMD=this.selectedYMD||Jl(this.getToday()),this.focus())}},render:function(t){var e=this;if(this.hidden)return t();var i=this.valueId,n=this.widgetId,o=this.navId,r=this.gridId,s=this.gridCaptionId,l=this.gridHelpId,u=this.activeId,d=this.disabled,h=this.noKeyNav,f=this.isLive,p=this.isRTL,m=this.activeYMD,v=this.selectedYMD,b=this.safeId,g=!this.showDecadeNav,y=Jl(this.getToday()),w=!this.noHighlightToday,T=t("output",{staticClass:"form-control form-control-sm text-center",class:{"text-muted":d,readonly:this.readonly||d},attrs:{id:i,for:r,role:"status",tabindex:d?null:"-1","data-selected":vr(v),"aria-live":f?"polite":"off","aria-atomic":f?"true":null},on:{click:this.onHeaderClick,focus:this.onHeaderClick}},this.selectedDate?[t("bdi",{staticClass:"sr-only"}," (".concat(vr(this.labelSelected),") ")),t("bdi",this.formatDateString(this.selectedDate))]:this.labelNoDateSelected||" ");T=t("header",{staticClass:"b-calendar-header",class:{"sr-only":this.hideHeader},attrs:{title:this.selectedDate&&this.labelSelectedDate||null}},[T]);var C={isRTL:p},x={shiftV:.5},S=c(c({},x),{},{flipH:p}),k=c(c({},x),{},{flipH:!p}),$=this.normalizeSlot("nav-prev-decade",C)||t(ya,{props:S}),B=this.normalizeSlot("nav-prev-year",C)||t(wa,{props:S}),_=this.normalizeSlot("nav-prev-month",C)||t(Ca,{props:S}),D=this.normalizeSlot("nav-this-month",C)||t(Sa,{props:x}),F=this.normalizeSlot("nav-next-month",C)||t(Ca,{props:k}),I=this.normalizeSlot("nav-next-year",C)||t(wa,{props:k}),P=this.normalizeSlot("nav-next-decade",C)||t(ya,{props:k}),O=function(i,n,o,r,s){return t("button",{staticClass:"btn btn-sm border-0 flex-fill",class:[e.computedNavButtonVariant,{disabled:r}],attrs:{title:n||null,type:"button",tabindex:h?"-1":null,"aria-label":n||null,"aria-disabled":r?"true":null,"aria-keyshortcuts":s||null},on:r?{}:{click:o}},[t("div",{attrs:{"aria-hidden":"true"}},[i])])},V=t("div",{staticClass:"b-calendar-nav d-flex",attrs:{id:o,role:"group",tabindex:h?"-1":null,"aria-hidden":d?"true":null,"aria-label":this.labelNav||null,"aria-controls":r}},[g?t():O($,this.labelPrevDecade,this.gotoPrevDecade,this.prevDecadeDisabled,"Ctrl+Alt+PageDown"),O(B,this.labelPrevYear,this.gotoPrevYear,this.prevYearDisabled,"Alt+PageDown"),O(_,this.labelPrevMonth,this.gotoPrevMonth,this.prevMonthDisabled,"PageDown"),O(D,this.labelCurrentMonth,this.gotoCurrentMonth,this.thisMonthDisabled,"Home"),O(F,this.labelNextMonth,this.gotoNextMonth,this.nextMonthDisabled,"PageUp"),O(I,this.labelNextYear,this.gotoNextYear,this.nextYearDisabled,"Alt+PageUp"),g?t():O(P,this.labelNextDecade,this.gotoNextDecade,this.nextDecadeDisabled,"Ctrl+Alt+PageUp")]),E=t("header",{staticClass:"b-calendar-grid-caption text-center font-weight-bold",class:{"text-muted":d},attrs:{id:s,"aria-live":f?"polite":null,"aria-atomic":f?"true":null},key:"grid-caption"},this.formatYearMonth(this.calendarFirstDay)),L=t("div",{staticClass:"b-calendar-grid-weekdays row no-gutters border-bottom",attrs:{"aria-hidden":"true"}},this.calendarHeadings.map((function(e,i){return t("small",{staticClass:"col text-truncate",class:{"text-muted":d},attrs:{title:e.label===e.text?null:e.label,"aria-label":e.label},key:i},e.text)}))),A=this.calendar.map((function(i){var n=i.map((function(i,n){var o,r=i.ymd===v,s=i.ymd===m,l=i.ymd===y,c=b("_cell-".concat(i.ymd,"_")),u=t("span",{staticClass:"btn border-0 rounded-circle text-nowrap",class:(o={focus:s&&e.gridHasFocus,disabled:i.isDisabled||d,active:r},a(o,e.computedVariant,r),a(o,e.computedTodayVariant,l&&w&&!r&&i.isThisMonth),a(o,"btn-outline-light",!(l&&w||r||s)),a(o,"btn-light",!(l&&w)&&!r&&s),a(o,"text-muted",!i.isThisMonth&&!r),a(o,"text-dark",!(l&&w)&&!r&&!s&&i.isThisMonth),a(o,"font-weight-bold",(r||i.isThisMonth)&&!i.isDisabled),o),on:{click:function(){return e.onClickDay(i)}}},i.day);return t("div",{staticClass:"col p-0",class:i.isDisabled?"bg-light":i.info.class||"",attrs:{id:c,role:"button","data-date":i.ymd,"aria-hidden":i.isThisMonth?null:"true","aria-disabled":i.isDisabled||d?"true":null,"aria-label":[i.label,r?"(".concat(e.labelSelected,")"):null,l?"(".concat(e.labelToday,")"):null].filter(ne).join(" "),"aria-selected":r?"true":null,"aria-current":r?"date":null},key:n},[u])}));return t("div",{staticClass:"row no-gutters",key:i[0].ymd},n)}));A=t("div",{staticClass:"b-calendar-grid-body",style:d?{pointerEvents:"none"}:{}},A);var R=t("footer",{staticClass:"b-calendar-grid-help border-top small text-muted text-center bg-light",attrs:{id:l}},[t("div",{staticClass:"small"},this.labelHelp)]),M=t("div",{staticClass:"b-calendar-grid form-control h-auto text-center",attrs:{id:r,role:"application",tabindex:h?"-1":d?null:"0","data-month":m.slice(0,-3),"aria-roledescription":this.labelCalendar||null,"aria-labelledby":s,"aria-describedby":l,"aria-disabled":d?"true":null,"aria-activedescendant":u},on:{keydown:this.onKeydownGrid,focus:this.setGridFocusFlag,blur:this.setGridFocusFlag},ref:"grid"},[E,L,A,R]),H=this.normalizeSlot();H=H?t("footer",{staticClass:"b-calendar-footer"},H):t();var z=t("div",{staticClass:"b-calendar-inner",style:this.block?{}:{width:this.width},attrs:{id:n,dir:p?"rtl":"ltr",lang:this.computedLocale||null,role:"group","aria-disabled":d?"true":null,"aria-controls":this.ariaControls||null,"aria-roledescription":this.roleDescription||null,"aria-describedby":[this.bvAttrs["aria-describedby"],i,l].filter(ne).join(" ")},on:{keydown:this.onKeydownWrapper}},[T,V,M,H]);return t("div",{staticClass:"b-calendar",class:{"d-block":this.block}},[z])}}),Cc=me({components:{BCalendar:Tc}}),xc=vs({bgVariant:hs(go),borderVariant:hs(go),tag:hs(go,"div"),textVariant:hs(go)},Ve),Sc=(i.default.extend({props:xc}),vs({title:hs(go),titleTag:hs(go,"h4")},je)),kc=i.default.extend({name:je,functional:!0,props:Sc,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.titleTag,F(n,{staticClass:"card-title"}),o||vr(i.title))}}),$c=vs({subTitle:hs(go),subTitleTag:hs(go,"h6"),subTitleTextVariant:hs(go,"muted")},ze),Bc=i.default.extend({name:ze,functional:!0,props:$c,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.subTitleTag,F(n,{staticClass:"card-subtitle",class:[i.subTitleTextVariant?"text-".concat(i.subTitleTextVariant):null]}),o||vr(i.subTitle))}}),_c=vs(ee(c(c(c(c({},Sc),$c),fs(xc,cs.bind(null,"body"))),{},{bodyClass:hs(To),overlay:hs(ho,!1)})),Ee),Dc=i.default.extend({name:Ee,functional:!0,props:_c,render:function(t,e){var i,n=e.props,o=e.data,r=e.children,s=n.bodyBgVariant,l=n.bodyBorderVariant,c=n.bodyTextVariant,u=t();n.title&&(u=t(kc,{props:ps(Sc,n)}));var d=t();return n.subTitle&&(d=t(Bc,{props:ps($c,n),class:["mb-2"]})),t(n.bodyTag,F(o,{staticClass:"card-body",class:[(i={"card-img-overlay":n.overlay},a(i,"bg-".concat(s),s),a(i,"border-".concat(l),l),a(i,"text-".concat(c),c),i),n.bodyClass]}),[u,d,r])}}),Fc=vs(ee(c(c({},fs(xc,cs.bind(null,"header"))),{},{header:hs(go),headerClass:hs(To),headerHtml:hs(go)})),Re),Ic=i.default.extend({name:Re,functional:!0,props:Fc,render:function(t,e){var i,n=e.props,o=e.data,r=e.children,s=n.headerBgVariant,l=n.headerBorderVariant,c=n.headerTextVariant;return t(n.headerTag,F(o,{staticClass:"card-header",class:[n.headerClass,(i={},a(i,"bg-".concat(s),s),a(i,"border-".concat(l),l),a(i,"text-".concat(c),c),i)],domProps:r?{}:Fl(n.headerHtml,n.header)}),r)}}),Pc=vs(ee(c(c({},fs(xc,cs.bind(null,"footer"))),{},{footer:hs(go),footerClass:hs(To),footerHtml:hs(go)})),Le),Oc=i.default.extend({name:Le,functional:!0,props:Pc,render:function(t,e){var i,n=e.props,o=e.data,r=e.children,s=n.footerBgVariant,l=n.footerBorderVariant,c=n.footerTextVariant;return t(n.footerTag,F(o,{staticClass:"card-footer",class:[n.footerClass,(i={},a(i,"bg-".concat(s),s),a(i,"border-".concat(l),l),a(i,"text-".concat(c),c),i)],domProps:r?{}:Fl(n.footerHtml,n.footer)}),r)}}),Vc='<svg width="%{w}" height="%{h}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %{w} %{h}" preserveAspectRatio="none"><rect width="100%" height="100%" style="fill:%{f};"></rect></svg>',Ec=vs({alt:hs(go),blank:hs(ho,!1),blankColor:hs(go,"transparent"),block:hs(ho,!1),center:hs(ho,!1),fluid:hs(ho,!1),fluidGrow:hs(ho,!1),height:hs(_o),left:hs(ho,!1),right:hs(ho,!1),rounded:hs(ko,!1),sizes:hs(Co),src:hs(go),srcset:hs(Co),thumbnail:hs(ho,!1),width:hs(_o)},_i),Lc=i.default.extend({name:_i,functional:!0,props:Ec,render:function(t,e){var i,n=e.props,o=e.data,r=n.alt,s=n.src,l=n.block,c=n.fluidGrow,u=n.rounded,d=lr(n.width)||null,h=lr(n.height)||null,f=null,p=or(n.srcset).filter(ne).join(","),m=or(n.sizes).filter(ne).join(",");return n.blank&&(!h&&d?h=d:!d&&h&&(d=h),d||h||(d=1,h=1),s=function(t,e,i){var n=encodeURIComponent(Vc.replace("%{w}",vr(t)).replace("%{h}",vr(e)).replace("%{f}",i));return"data:image/svg+xml;charset=UTF-8,".concat(n)}(d,h,n.blankColor||"transparent"),p=null,m=null),n.left?f="float-left":n.right?f="float-right":n.center&&(f="mx-auto",l=!0),t("img",F(o,{attrs:{src:s,alt:r,width:d?vr(d):null,height:h?vr(h):null,srcset:p||null,sizes:m||null},class:(i={"img-thumbnail":n.thumbnail,"img-fluid":n.fluid||c,"w-100":c,rounded:""===u||!0===u},a(i,"rounded-".concat(u),Et(u)&&""!==u),a(i,f,f),a(i,"d-block",l),i)}))}}),Ac=vs(ee(c(c({},Jt(Ec,["src","alt","width","height","left","right"])),{},{bottom:hs(ho,!1),end:hs(ho,!1),start:hs(ho,!1),top:hs(ho,!1)})),Me),Rc=i.default.extend({name:Me,functional:!0,props:Ac,render:function(t,e){var i=e.props,n=e.data,o=i.src,r=i.alt,s=i.width,a=i.height,l="card-img";return i.top?l+="-top":i.right||i.end?l+="-right":i.bottom?l+="-bottom":(i.left||i.start)&&(l+="-left"),t("img",F(n,{class:l,attrs:{src:o,alt:r,width:s,height:a}}))}}),Mc=fs(Ac,cs.bind(null,"img"));Mc.imgSrc.required=!1;var Hc,zc,Nc,jc=vs(ee(c(c(c(c(c(c({},_c),Fc),Pc),Mc),xc),{},{align:hs(go),noBody:hs(ho,!1)})),Ve),Gc=i.default.extend({name:Ve,functional:!0,props:jc,render:function(t,e){var i,n=e.props,o=e.data,r=e.slots,s=e.scopedSlots,l=n.imgSrc,c=n.imgLeft,u=n.imgRight,d=n.imgStart,h=n.imgEnd,f=n.imgBottom,p=n.header,m=n.headerHtml,v=n.footer,b=n.footerHtml,g=n.align,y=n.textVariant,w=n.bgVariant,T=n.borderVariant,C=s||{},x=r(),S={},k=t(),$=t();if(l){var B=t(Rc,{props:ps(Mc,n,us.bind(null,"img"))});f?$=B:k=B}var _=t(),D=ws(No,C,x);(D||p||m)&&(_=t(Ic,{props:ps(Fc,n),domProps:D?{}:Fl(m,p)},Ts(No,S,C,x)));var I=Ts(Ao,S,C,x);n.noBody||(I=t(Dc,{props:ps(_c,n)},I),n.overlay&&l&&(I=t("div",{staticClass:"position-relative"},[k,I,$]),k=t(),$=t()));var P=t();return(ws(zo,C,x)||v||b)&&(P=t(Oc,{props:ps(Pc,n),domProps:D?{}:Fl(b,v)},Ts(zo,S,C,x))),t(n.tag,F(o,{staticClass:"card",class:(i={"flex-row":c||d,"flex-row-reverse":(u||h)&&!(c||d)},a(i,"text-".concat(g),g),a(i,"bg-".concat(w),w),a(i,"border-".concat(T),T),a(i,"text-".concat(y),y),i)}),[k,_,I,P,$])}}),Wc="__bv__visibility_observer",Yc=function(){function t(e,i,n){o(this,t),this.el=e,this.callback=i.callback,this.margin=i.margin||0,this.once=i.once||!1,this.observer=null,this.visible=void 0,this.doneOnce=!1,this.createObserver(n)}return s(t,[{key:"createObserver",value:function(t){var e=this;if(this.observer&&this.stop(),!this.doneOnce&&Ot(this.callback)){try{this.observer=new IntersectionObserver(this.handler.bind(this),{root:null,rootMargin:this.margin,threshold:0})}catch(t){return this.doneOnce=!0,this.observer=void 0,void this.callback(null)}t.context.$nextTick((function(){xr((function(){e.observer&&e.observer.observe(e.el)}))}))}}},{key:"handler",value:function(t){var e=t?t[0]:{},i=Boolean(e.isIntersecting||e.intersectionRatio>0);i!==this.visible&&(this.visible=i,this.callback(i),this.once&&this.visible&&(this.doneOnce=!0,this.stop()))}},{key:"stop",value:function(){this.observer&&this.observer.disconnect(),this.observer=null}}]),t}(),Uc=function(t){var e=t[Wc];e&&e.stop&&e.stop(),delete t[Wc]},qc=function(t,e,i){var n=e.value,o=e.modifiers,r={margin:"0px",once:!1,callback:n};Kt(o).forEach((function(t){Q.test(t)?r.margin="".concat(t,"px"):"once"===t.toLowerCase()&&(r.once=!0)})),Uc(t),t[Wc]=new Yc(t,r,i),t[Wc]._prevModifiers=Zt(o)},Kc={bind:qc,componentUpdated:function(t,e,i){var n=e.value,o=e.oldValue,r=e.modifiers;r=Zt(r),!t||n===o&&t[Wc]&&Ua(r,t[Wc]._prevModifiers)||qc(t,{value:n,modifiers:r},i)},unbind:function(t){Uc(t)}},Xc="show",Zc=Qt(Ec,["blank"]),Jc=vs(c(c({},Zc),{},a({blankColor:hs(go,"transparent"),blankHeight:hs(_o),blankSrc:hs(go,null),blankWidth:hs(_o),offset:hs(_o,360)},Xc,hs(ho,!1))),Di),Qc=i.default.extend({name:Di,directives:{"b-visible":Kc},props:Jc,data:function(){return{isShown:this.show}},computed:{computedSrc:function(){var t=this.blankSrc;return!t||this.isShown?this.src:t},computedBlank:function(){return!(this.isShown||this.blankSrc)},computedWidth:function(){var t=this.width;return this.isShown?t:this.blankWidth||t},computedHeight:function(){var t=this.height;return this.isShown?t:this.blankHeight||t},computedSrcset:function(){var t=or(this.srcset).filter(ne).join(",");return!this.blankSrc||this.isShown?t:null},computedSizes:function(){var t=or(this.sizes).filter(ne).join(",");return!this.blankSrc||this.isShown?t:null}},watch:(Hc={},a(Hc,Xc,(function(t,e){if(t!==e){var i=!q||t;this.isShown=i,i!==t&&this.$nextTick(this.updateShowProp)}})),a(Hc,"isShown",(function(t,e){t!==e&&this.updateShowProp()})),Hc),mounted:function(){this.isShown=!q||this.show},methods:{updateShowProp:function(){this.$emit("update:show",this.isShown)},doShow:function(t){!t&&null!==t||this.isShown||(this.isShown=!0)}},render:function(t){var e,i=[];this.isShown||i.push({name:"b-visible",value:this.doShow,modifiers:(e={},a(e,"".concat(lr(this.offset,0)),!0),a(e,"once",!0),e)});return t(Lc,{directives:i,props:c({src:this.computedSrc,blank:this.computedBlank,width:this.computedWidth,height:this.computedHeight,srcset:this.computedSrcset||null,sizes:this.computedSizes||null},ps(Zc,this.$props))})}}),tu=vs(ee(c(c({},Qt(Jc,Kt(Ec))),Qt(Ac,["src","alt","width","height"]))),He),eu=i.default.extend({name:He,functional:!0,props:tu,render:function(t,e){var i=e.props,n=e.data,o="card-img";return i.top?o+="-top":i.right||i.end?o+="-right":i.bottom?o+="-bottom":(i.left||i.start)&&(o+="-left"),t(Qc,F(n,{class:[o],props:Qt(i,["left","right"])}))}}),iu=vs({textTag:hs(go,"p")},Ne),nu=i.default.extend({name:Ne,functional:!0,props:iu,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.textTag,F(n,{staticClass:"card-text"}),o)}}),ou=vs({columns:hs(ho,!1),deck:hs(ho,!1),tag:hs(go,"div")},Ae),ru=me({components:{BCard:Gc,BCardHeader:Ic,BCardBody:Dc,BCardTitle:kc,BCardSubTitle:Bc,BCardFooter:Oc,BCardImg:Rc,BCardImgLazy:eu,BCardText:nu,BCardGroup:i.default.extend({name:Ae,functional:!0,props:ou,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.tag,F(n,{class:i.deck?"card-deck":i.columns?"card-columns":"card-group"}),o)}})}}),su=function(){},au=function(t,e,i){if(t=t?t.$el||t:null,!kr(t))return null;if(n="observeDom",!R&&(le("".concat(n,": Requires MutationObserver support.")),1))return null;var n,o=new Sr((function(t){for(var i=!1,n=0;n<t.length&&!i;n++){var o=t[n],r=o.type,s=o.target;("characterData"===r&&s.nodeType===Node.TEXT_NODE||"attributes"===r||"childList"===r&&(o.addedNodes.length>0||o.removedNodes.length>0))&&(i=!0)}i&&e()}));return o.observe(t,c({childList:!0,subtree:!0},i)),o},lu=ys("value",{type:mo,defaultValue:0}),cu=lu.mixin,uu=lu.props,du=lu.prop,hu=lu.event,fu={next:{dirClass:"carousel-item-left",overlayClass:"carousel-item-next"},prev:{dirClass:"carousel-item-right",overlayClass:"carousel-item-prev"}},pu={TOUCH:"touch",PEN:"pen"},mu={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend oTransitionEnd",transition:"transitionend"},vu=vs(ee(c(c(c({},fc),uu),{},{background:hs(go),controls:hs(ho,!1),fade:hs(ho,!1),imgHeight:hs(_o),imgWidth:hs(_o),indicators:hs(ho,!1),interval:hs(mo,5e3),labelGotoSlide:hs(go,"Goto slide"),labelIndicators:hs(go,"Select a slide to display"),labelNext:hs(go,"Next slide"),labelPrev:hs(go,"Previous slide"),noAnimation:hs(ho,!1),noHoverPause:hs(ho,!1),noTouch:hs(ho,!1),noWrap:hs(ho,!1)})),Ge),bu=i.default.extend({name:Ge,mixins:[pc,cu,Cs],provide:function(){return{bvCarousel:this}},props:vu,data:function(){return{index:this[du]||0,isSliding:!1,transitionEndEvent:null,slides:[],direction:null,isPaused:!(lr(this.interval,0)>0),touchStartX:0,touchDeltaX:0}},computed:{numSlides:function(){return this.slides.length}},watch:(zc={},a(zc,du,(function(t,e){t!==e&&this.setSlide(lr(t,0))})),a(zc,"interval",(function(t,e){t!==e&&(t?(this.pause(!0),this.start(!1)):this.pause(!1))})),a(zc,"isPaused",(function(t,e){t!==e&&this.$emit(t?"paused":"unpaused")})),a(zc,"index",(function(t,e){t===e||this.isSliding||this.doSlide(t,e)})),zc),created:function(){this.$_interval=null,this.$_animationTimeout=null,this.$_touchTimeout=null,this.$_observer=null,this.isPaused=!(lr(this.interval,0)>0)},mounted:function(){this.transitionEndEvent=function(t){for(var e in mu)if(!Ft(t.style[e]))return mu[e];return null}(this.$el)||null,this.updateSlides(),this.setObserver(!0)},beforeDestroy:function(){this.clearInterval(),this.clearAnimationTimeout(),this.clearTouchTimeout(),this.setObserver(!1)},methods:{clearInterval:function(t){function e(){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}((function(){clearInterval(this.$_interval),this.$_interval=null})),clearAnimationTimeout:function(){clearTimeout(this.$_animationTimeout),this.$_animationTimeout=null},clearTouchTimeout:function(){clearTimeout(this.$_touchTimeout),this.$_touchTimeout=null},setObserver:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.$_observer&&this.$_observer.disconnect(),this.$_observer=null,t&&(this.$_observer=au(this.$refs.inner,this.updateSlides.bind(this),{subtree:!1,childList:!0,attributes:!0,attributeFilter:["id"]}))},setSlide:function(t){var e=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(!(M&&document.visibilityState&&document.hidden)){var n=this.noWrap,o=this.numSlides;t=Xs(t),0!==o&&(this.isSliding?this.$once(io,(function(){xr((function(){return e.setSlide(t,i)}))})):(this.direction=i,this.index=t>=o?n?o-1:0:t<0?n?0:o-1:t,n&&this.index!==t&&this.index!==this[du]&&this.$emit(hu,this.index)))}},prev:function(){this.setSlide(this.index-1,"prev")},next:function(){this.setSlide(this.index+1,"next")},pause:function(t){t||(this.isPaused=!0),this.clearInterval()},start:function(t){t||(this.isPaused=!1),this.clearInterval(),this.interval&&this.numSlides>1&&(this.$_interval=setInterval(this.next,Us(1e3,this.interval)))},restart:function(){this.$el.contains($r())||this.start()},doSlide:function(t,e){var i=this,n=Boolean(this.interval),o=this.calcDirection(this.direction,e,t),r=o.overlayClass,s=o.dirClass,a=this.slides[e],l=this.slides[t];if(a&&l){if(this.isSliding=!0,n&&this.pause(!1),this.$emit("sliding-start",t),this.$emit(hu,this.index),this.noAnimation)Rr(l,"active"),Mr(a,"active"),this.isSliding=!1,this.$nextTick((function(){return i.$emit(io,t)}));else{Rr(l,r),Ir(l),Rr(a,s),Rr(l,s);var c=!1,u=function e(){if(!c){if(c=!0,i.transitionEndEvent)i.transitionEndEvent.split(/\s+/).forEach((function(t){return ks(l,t,e,lo)}));i.clearAnimationTimeout(),Mr(l,s),Mr(l,r),Rr(l,"active"),Mr(a,"active"),Mr(a,s),Mr(a,r),zr(a,"aria-current","false"),zr(l,"aria-current","true"),zr(a,"aria-hidden","true"),zr(l,"aria-hidden","false"),i.isSliding=!1,i.direction=null,i.$nextTick((function(){return i.$emit(io,t)}))}};if(this.transitionEndEvent)this.transitionEndEvent.split(/\s+/).forEach((function(t){return Ss(l,t,u,lo)}));this.$_animationTimeout=setTimeout(u,650)}n&&this.start(!1)}},updateSlides:function(){this.pause(!0),this.slides=Pr(".carousel-item",this.$refs.inner);var t=this.slides.length,e=Us(0,Ys(Xs(this.index),t-1));this.slides.forEach((function(i,n){var o=n+1;n===e?(Rr(i,"active"),zr(i,"aria-current","true")):(Mr(i,"active"),zr(i,"aria-current","false")),zr(i,"aria-posinset",String(o)),zr(i,"aria-setsize",String(t))})),this.setSlide(e),this.start(this.isPaused)},calcDirection:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return t?fu[t]:i>e?fu.next:fu.prev},handleClick:function(t,e){var i=t.keyCode;"click"!==t.type&&i!==Ga&&i!==Ha||(Bs(t),e())},handleSwipe:function(){var t=qs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0?this.prev():e<0&&this.next()}},touchStart:function(t){U&&pu[t.pointerType.toUpperCase()]?this.touchStartX=t.clientX:U||(this.touchStartX=t.touches[0].clientX)},touchMove:function(t){t.touches&&t.touches.length>1?this.touchDeltaX=0:this.touchDeltaX=t.touches[0].clientX-this.touchStartX},touchEnd:function(t){U&&pu[t.pointerType.toUpperCase()]&&(this.touchDeltaX=t.clientX-this.touchStartX),this.handleSwipe(),this.pause(!1),this.clearTouchTimeout(),this.$_touchTimeout=setTimeout(this.start,500+Us(1e3,this.interval))}},render:function(t){var e=this,i=this.indicators,n=this.background,o=this.noAnimation,r=this.noHoverPause,s=this.noTouch,a=this.index,l=this.isSliding,c=this.pause,u=this.restart,d=this.touchStart,h=this.touchEnd,f=this.safeId("__BV_inner_"),p=t("div",{staticClass:"carousel-inner",attrs:{id:f,role:"list"},ref:"inner"},[this.normalizeSlot()]),m=t();if(this.controls){var v=function(i,n,o){var r=function(t){l?Bs(t,{propagation:!1}):e.handleClick(t,o)};return t("a",{staticClass:"carousel-control-".concat(i),attrs:{href:"#",role:"button","aria-controls":f,"aria-disabled":l?"true":null},on:{click:r,keydown:r}},[t("span",{staticClass:"carousel-control-".concat(i,"-icon"),attrs:{"aria-hidden":"true"}}),t("span",{class:"sr-only"},[n])])};m=[v("prev",this.labelPrev,this.prev),v("next",this.labelNext,this.next)]}var b=t("ol",{staticClass:"carousel-indicators",directives:[{name:"show",value:i}],attrs:{id:this.safeId("__BV_indicators_"),"aria-hidden":i?"false":"true","aria-label":this.labelIndicators,"aria-owns":f}},this.slides.map((function(n,o){var r=function(t){e.handleClick(t,(function(){e.setSlide(o)}))};return t("li",{class:{active:o===a},attrs:{role:"button",id:e.safeId("__BV_indicator_".concat(o+1,"_")),tabindex:i?"0":"-1","aria-current":o===a?"true":"false","aria-label":"".concat(e.labelGotoSlide," ").concat(o+1),"aria-describedby":n.id||null,"aria-controls":f},on:{click:r,keydown:r},key:"slide_".concat(o)})}))),g={mouseenter:r?su:c,mouseleave:r?su:u,focusin:c,focusout:u,keydown:function(t){if(!/input|textarea/i.test(t.target.tagName)){var i=t.keyCode;i!==Na&&i!==ja||(Bs(t),e[i===Na?"prev":"next"]())}}};return Y&&!s&&(U?(g["&pointerdown"]=d,g["&pointerup"]=h):(g["&touchstart"]=d,g["&touchmove"]=this.touchMove,g["&touchend"]=h)),t("div",{staticClass:"carousel",class:{slide:!o,"carousel-fade":!o&&this.fade,"pointer-event":Y&&U&&!s},style:{background:n},attrs:{role:"region",id:this.safeId(),"aria-busy":l?"true":"false"},on:g},[p,m,b])}}),gu={imgAlt:hs(go),imgBlank:hs(ho,!1),imgBlankColor:hs(go,"transparent"),imgHeight:hs(_o),imgSrc:hs(go),imgWidth:hs(_o)},yu=vs(ee(c(c(c({},fc),gu),{},{background:hs(go),caption:hs(go),captionHtml:hs(go),captionTag:hs(go,"h3"),contentTag:hs(go,"div"),contentVisibleUp:hs(go),text:hs(go),textHtml:hs(go),textTag:hs(go,"p")})),We),wu=me({components:{BCarousel:bu,BCarouselSlide:i.default.extend({name:We,mixins:[pc,Cs],inject:{bvCarousel:{default:function(){return{noTouch:!0}}}},props:yu,computed:{contentClasses:function(){return[this.contentVisibleUp?"d-none":"",this.contentVisibleUp?"d-".concat(this.contentVisibleUp,"-block"):""]},computedWidth:function(){return this.imgWidth||this.bvCarousel.imgWidth||null},computedHeight:function(){return this.imgHeight||this.bvCarousel.imgHeight||null}},render:function(t){var e=this.normalizeSlot("img");if(!e&&(this.imgSrc||this.imgBlank)){var i={};!this.bvCarousel.noTouch&&Y&&(i.dragstart=function(t){return Bs(t,{propagation:!1})}),e=t(Lc,{props:c(c({},ps(gu,this.$props,us.bind(null,"img"))),{},{width:this.computedWidth,height:this.computedHeight,fluidGrow:!0,block:!0}),on:i})}var n=[!(!this.caption&&!this.captionHtml)&&t(this.captionTag,{domProps:Fl(this.captionHtml,this.caption)}),!(!this.text&&!this.textHtml)&&t(this.textTag,{domProps:Fl(this.textHtml,this.text)}),this.normalizeSlot()||!1],o=t();return n.some(ne)&&(o=t(this.contentTag,{staticClass:"carousel-caption",class:this.contentClasses},n.map((function(e){return e||t()})))),t("div",{staticClass:"carousel-item",style:{background:this.background||this.bvCarousel.background||null},attrs:{id:this.safeId(),role:"listitem"}},[e,o])}})}}),Tu="show",Cu={css:!0,enterClass:"",enterActiveClass:"collapsing",enterToClass:"collapse show",leaveClass:"collapse show",leaveActiveClass:"collapsing",leaveToClass:"collapse"},xu={enter:function(t){Wr(t,"height",0),xr((function(){Ir(t),Wr(t,"height","".concat(t.scrollHeight,"px"))}))},afterEnter:function(t){Yr(t,"height")},leave:function(t){Wr(t,"height","auto"),Wr(t,"display","block"),Wr(t,"height","".concat(qr(t).height,"px")),Ir(t),Wr(t,"height",0)},afterLeave:function(t){Yr(t,"height")}},Su={appear:hs(ho,!1)},ku=i.default.extend({name:"BVCollapse",functional:!0,props:Su,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t("transition",F(n,{props:Cu,on:xu},{props:i}),o)}}),$u=Fs(Ue,"toggle"),Bu=Fs(Ue,"request-state"),_u=Ds(Ue,"accordion"),Du=Ds(Ue,"state"),Fu=Ds(Ue,"sync-state"),Iu=ys("visible",{type:ho,defaultValue:!1}),Pu=Iu.mixin,Ou=Iu.props,Vu=Iu.prop,Eu=Iu.event,Lu=vs(ee(c(c(c({},fc),Ou),{},{accordion:hs(go),appear:hs(ho,!1),isNav:hs(ho,!1),tag:hs(go,"div")})),Ue),Au=i.default.extend({name:Ue,mixins:[pc,Pu,Cs,Ja],props:Lu,data:function(){return{show:this[Vu],transitioning:!1}},computed:{classObject:function(){var t=this.transitioning;return{"navbar-collapse":this.isNav,collapse:!t,show:this.show&&!t}},slotScope:function(){var t=this;return{visible:this.show,close:function(){t.show=!1}}}},watch:(Nc={},a(Nc,Vu,(function(t){t!==this.show&&(this.show=t)})),a(Nc,"show",(function(t,e){t!==e&&this.emitState()})),Nc),created:function(){this.show=this[Vu]},mounted:function(){var t=this;this.show=this[Vu],this.listenOnRoot($u,this.handleToggleEvt),this.listenOnRoot(_u,this.handleAccordionEvt),this.isNav&&(this.setWindowEvents(!0),this.handleResize()),this.$nextTick((function(){t.emitState()})),this.listenOnRoot(Bu,(function(e){e===t.safeId()&&t.$nextTick(t.emitSync)}))},updated:function(){this.emitSync()},deactivated:function(){this.isNav&&this.setWindowEvents(!1)},activated:function(){this.isNav&&this.setWindowEvents(!0),this.emitSync()},beforeDestroy:function(){this.show=!1,this.isNav&&M&&this.setWindowEvents(!1)},methods:{setWindowEvents:function(t){$s(t,window,"resize",this.handleResize,lo),$s(t,window,"orientationchange",this.handleResize,lo)},toggle:function(){this.show=!this.show},onEnter:function(){this.transitioning=!0,this.$emit(to)},onAfterEnter:function(){this.transitioning=!1,this.$emit(eo)},onLeave:function(){this.transitioning=!0,this.$emit(Nn)},onAfterLeave:function(){this.transitioning=!1,this.$emit(zn)},emitState:function(){var t=this.show,e=this.accordion,i=this.safeId();this.$emit(Eu,t),this.emitOnRoot(Du,i,t),e&&t&&this.emitOnRoot(_u,i,e)},emitSync:function(){this.emitOnRoot(Fu,this.safeId(),this.show)},checkDisplayBlock:function(){var t=this.$el,e=Hr(t,Tu);Mr(t,Tu);var i="block"===Kr(t).display;return e&&Rr(t,Tu),i},clickHandler:function(t){var e=t.target;this.isNav&&e&&"block"===Kr(this.$el).display&&(!Vr(e,".nav-link,.dropdown-item")&&!Er(".nav-link,.dropdown-item",e)||this.checkDisplayBlock()||(this.show=!1))},handleToggleEvt:function(t){t===this.safeId()&&this.toggle()},handleAccordionEvt:function(t,e){var i=this.accordion,n=this.show;if(i&&i===e){var o=t===this.safeId();(o&&!n||!o&&n)&&this.toggle()}},handleResize:function(){this.show="block"===Kr(this.$el).display}},render:function(t){var e=this.appear,i=t(this.tag,{class:this.classObject,directives:[{name:"show",value:this.show}],attrs:{id:this.safeId()},on:{click:this.clickHandler}},this.normalizeSlot(Ao,this.slotScope));return t(ku,{props:{appear:e},on:{enter:this.onEnter,afterEnter:this.onAfterEnter,leave:this.onLeave,afterLeave:this.onAfterLeave}},[i])}}),Ru="collapsed",Mu="not-collapsed",Hu="__BV_toggle",zu="".concat(Hu,"_HANDLER__"),Nu="".concat(Hu,"_CLICK__"),ju="".concat(Hu,"_STATE__"),Gu="".concat(Hu,"_TARGETS__"),Wu="aria-controls",Yu="aria-expanded",Uu="role",qu="tabindex",Ku="overflow-anchor",Xu=Fs(Ue,"toggle"),Zu=Ds(Ue,"state"),Ju=Ds(Ue,"sync-state"),Qu=Fs(Ue,"request-state"),td=[Ha,Ga],ed=function(t){return!nr(["button","a"],t.tagName.toLowerCase())},id=function(t){var e=t[Nu];e&&(ks(t,"click",e,ao),ks(t,"keydown",e,ao)),t[Nu]=null},nd=function(t,e){t[zu]&&e.context&&e.context.$root.$off([Zu,Ju],t[zu]),t[zu]=null},od=function(t,e){e?(Mr(t,Ru),Rr(t,Mu),zr(t,Yu,"true")):(Mr(t,Mu),Rr(t,Ru),zr(t,Yu,"false"))},rd=function(t,e){t[e]=null,delete t[e]},sd=function(t,e,i){if(M&&i.context){ed(t)&&(Gr(t,Uu)||zr(t,Uu,"button"),Gr(t,qu)||zr(t,qu,"0")),od(t,t[ju]);var n=function(t,e){var i=t.modifiers,n=t.arg,o=t.value,r=Kt(i||{});if(o=Et(o)?o.split(ut):o,Br(e.tagName,"a")){var s=jr(e,"href")||"";it.test(s)&&r.push(s.replace(et,""))}return or(n,o).forEach((function(t){return Et(t)&&r.push(t)})),r.filter((function(t,e,i){return t&&i.indexOf(t)===e}))}(e,t);n.length>0?(zr(t,Wu,n.join(" ")),Wr(t,Ku,"none")):(Nr(t,Wu),Yr(t,Ku)),xr((function(){!function(t,e){if(id(t),e.context){var i=function(i){"keydown"===i.type&&!nr(td,i.keyCode)||Fr(t)||(t[Gu]||[]).forEach((function(t){e.context.$root.$emit(Xu,t)}))};t[Nu]=i,Ss(t,"click",i,ao),ed(t)&&Ss(t,"keydown",i,ao)}}(t,i)})),Ua(n,t[Gu])||(t[Gu]=n,n.forEach((function(t){i.context.$root.$emit(Qu,t)})))}},ad={bind:function(t,e,i){t[ju]=!1,t[Gu]=[],function(t,e){if(nd(t,e),e.context){var i=function(e,i){nr(t[Gu]||[],e)&&(t[ju]=i,od(t,i))};t[zu]=i,e.context.$root.$on([Zu,Ju],i)}}(t,i),sd(t,e,i)},componentUpdated:sd,updated:sd,unbind:function(t,e,i){id(t),nd(t,i),rd(t,zu),rd(t,Nu),rd(t,ju),rd(t,Gu),Mr(t,Ru),Mr(t,Mu),Nr(t,Yu),Nr(t,Wu),Nr(t,Uu),Yr(t,Ku)}},ld=me({directives:{VBToggle:ad}}),cd=me({components:{BCollapse:Au},plugins:{VBTogglePlugin:ld}}),ud="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,dd=function(){for(var t=["Edge","Trident","Firefox"],e=0;e<t.length;e+=1)if(ud&&navigator.userAgent.indexOf(t[e])>=0)return 1;return 0}();var hd=ud&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),dd))}};function fd(t){return t&&"[object Function]"==={}.toString.call(t)}function pd(t,e){if(1!==t.nodeType)return[];var i=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?i[e]:i}function md(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function vd(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=pd(t),i=e.overflow,n=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(i+o+n)?t:vd(md(t))}function bd(t){return t&&t.referenceNode?t.referenceNode:t}var gd=ud&&!(!window.MSInputMethodContext||!document.documentMode),yd=ud&&/MSIE 10/.test(navigator.userAgent);function wd(t){return 11===t?gd:10===t?yd:gd||yd}function Td(t){if(!t)return document.documentElement;for(var e=wd(10)?document.body:null,i=t.offsetParent||null;i===e&&t.nextElementSibling;)i=(t=t.nextElementSibling).offsetParent;var n=i&&i.nodeName;return n&&"BODY"!==n&&"HTML"!==n?-1!==["TH","TD","TABLE"].indexOf(i.nodeName)&&"static"===pd(i,"position")?Td(i):i:t?t.ownerDocument.documentElement:document.documentElement}function Cd(t){return null!==t.parentNode?Cd(t.parentNode):t}function xd(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var i=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,n=i?t:e,o=i?e:t,r=document.createRange();r.setStart(n,0),r.setEnd(o,0);var s,a,l=r.commonAncestorContainer;if(t!==l&&e!==l||n.contains(o))return"BODY"===(a=(s=l).nodeName)||"HTML"!==a&&Td(s.firstElementChild)!==s?Td(l):l;var c=Cd(t);return c.host?xd(c.host,e):xd(t,Cd(e).host)}function Sd(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",i="top"===e?"scrollTop":"scrollLeft",n=t.nodeName;if("BODY"===n||"HTML"===n){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[i]}return t[i]}function kd(t,e){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=Sd(e,"top"),o=Sd(e,"left"),r=i?-1:1;return t.top+=n*r,t.bottom+=n*r,t.left+=o*r,t.right+=o*r,t}function $d(t,e){var i="x"===e?"Left":"Top",n="Left"===i?"Right":"Bottom";return parseFloat(t["border"+i+"Width"])+parseFloat(t["border"+n+"Width"])}function Bd(t,e,i,n){return Math.max(e["offset"+t],e["scroll"+t],i["client"+t],i["offset"+t],i["scroll"+t],wd(10)?parseInt(i["offset"+t])+parseInt(n["margin"+("Height"===t?"Top":"Left")])+parseInt(n["margin"+("Height"===t?"Bottom":"Right")]):0)}function _d(t){var e=t.body,i=t.documentElement,n=wd(10)&&getComputedStyle(i);return{height:Bd("Height",e,i,n),width:Bd("Width",e,i,n)}}var Dd=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},Fd=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}(),Id=function(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t},Pd=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(t[n]=i[n])}return t};function Od(t){return Pd({},t,{right:t.left+t.width,bottom:t.top+t.height})}function Vd(t){var e={};try{if(wd(10)){e=t.getBoundingClientRect();var i=Sd(t,"top"),n=Sd(t,"left");e.top+=i,e.left+=n,e.bottom+=i,e.right+=n}else e=t.getBoundingClientRect()}catch(t){}var o={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},r="HTML"===t.nodeName?_d(t.ownerDocument):{},s=r.width||t.clientWidth||o.width,a=r.height||t.clientHeight||o.height,l=t.offsetWidth-s,c=t.offsetHeight-a;if(l||c){var u=pd(t);l-=$d(u,"x"),c-=$d(u,"y"),o.width-=l,o.height-=c}return Od(o)}function Ed(t,e){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=wd(10),o="HTML"===e.nodeName,r=Vd(t),s=Vd(e),a=vd(t),l=pd(e),c=parseFloat(l.borderTopWidth),u=parseFloat(l.borderLeftWidth);i&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var d=Od({top:r.top-s.top-c,left:r.left-s.left-u,width:r.width,height:r.height});if(d.marginTop=0,d.marginLeft=0,!n&&o){var h=parseFloat(l.marginTop),f=parseFloat(l.marginLeft);d.top-=c-h,d.bottom-=c-h,d.left-=u-f,d.right-=u-f,d.marginTop=h,d.marginLeft=f}return(n&&!i?e.contains(a):e===a&&"BODY"!==a.nodeName)&&(d=kd(d,e)),d}function Ld(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=t.ownerDocument.documentElement,n=Ed(t,i),o=Math.max(i.clientWidth,window.innerWidth||0),r=Math.max(i.clientHeight,window.innerHeight||0),s=e?0:Sd(i),a=e?0:Sd(i,"left"),l={top:s-n.top+n.marginTop,left:a-n.left+n.marginLeft,width:o,height:r};return Od(l)}function Ad(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===pd(t,"position"))return!0;var i=md(t);return!!i&&Ad(i)}function Rd(t){if(!t||!t.parentElement||wd())return document.documentElement;for(var e=t.parentElement;e&&"none"===pd(e,"transform");)e=e.parentElement;return e||document.documentElement}function Md(t,e,i,n){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},s=o?Rd(t):xd(t,bd(e));if("viewport"===n)r=Ld(s,o);else{var a=void 0;"scrollParent"===n?"BODY"===(a=vd(md(e))).nodeName&&(a=t.ownerDocument.documentElement):a="window"===n?t.ownerDocument.documentElement:n;var l=Ed(a,s,o);if("HTML"!==a.nodeName||Ad(s))r=l;else{var c=_d(t.ownerDocument),u=c.height,d=c.width;r.top+=l.top-l.marginTop,r.bottom=u+l.top,r.left+=l.left-l.marginLeft,r.right=d+l.left}}var h="number"==typeof(i=i||0);return r.left+=h?i:i.left||0,r.top+=h?i:i.top||0,r.right-=h?i:i.right||0,r.bottom-=h?i:i.bottom||0,r}function Hd(t){return t.width*t.height}function zd(t,e,i,n,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var s=Md(i,n,r,o),a={top:{width:s.width,height:e.top-s.top},right:{width:s.right-e.right,height:s.height},bottom:{width:s.width,height:s.bottom-e.bottom},left:{width:e.left-s.left,height:s.height}},l=Object.keys(a).map((function(t){return Pd({key:t},a[t],{area:Hd(a[t])})})).sort((function(t,e){return e.area-t.area})),c=l.filter((function(t){var e=t.width,n=t.height;return e>=i.clientWidth&&n>=i.clientHeight})),u=c.length>0?c[0].key:l[0].key,d=t.split("-")[1];return u+(d?"-"+d:"")}function Nd(t,e,i){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=n?Rd(e):xd(e,bd(i));return Ed(i,o,n)}function jd(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),i=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),n=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+n,height:t.offsetHeight+i}}function Gd(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function Wd(t,e,i){i=i.split("-")[0];var n=jd(t),o={width:n.width,height:n.height},r=-1!==["right","left"].indexOf(i),s=r?"top":"left",a=r?"left":"top",l=r?"height":"width",c=r?"width":"height";return o[s]=e[s]+e[l]/2-n[l]/2,o[a]=i===a?e[a]-n[c]:e[Gd(a)],o}function Yd(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function Ud(t,e,i){return(void 0===i?t:t.slice(0,function(t,e,i){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===i}));var n=Yd(t,(function(t){return t[e]===i}));return t.indexOf(n)}(t,"name",i))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var i=t.function||t.fn;t.enabled&&fd(i)&&(e.offsets.popper=Od(e.offsets.popper),e.offsets.reference=Od(e.offsets.reference),e=i(e,t))})),e}function qd(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=Nd(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=zd(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=Wd(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=Ud(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function Kd(t,e){return t.some((function(t){var i=t.name;return t.enabled&&i===e}))}function Xd(t){for(var e=[!1,"ms","Webkit","Moz","O"],i=t.charAt(0).toUpperCase()+t.slice(1),n=0;n<e.length;n++){var o=e[n],r=o?""+o+i:t;if("undefined"!=typeof document.body.style[r])return r}return null}function Zd(){return this.state.isDestroyed=!0,Kd(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.position="",this.popper.style.top="",this.popper.style.left="",this.popper.style.right="",this.popper.style.bottom="",this.popper.style.willChange="",this.popper.style[Xd("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function Jd(t){var e=t.ownerDocument;return e?e.defaultView:window}function Qd(t,e,i,n){var o="BODY"===t.nodeName,r=o?t.ownerDocument.defaultView:t;r.addEventListener(e,i,{passive:!0}),o||Qd(vd(r.parentNode),e,i,n),n.push(r)}function th(t,e,i,n){i.updateBound=n,Jd(t).addEventListener("resize",i.updateBound,{passive:!0});var o=vd(t);return Qd(o,"scroll",i.updateBound,i.scrollParents),i.scrollElement=o,i.eventsEnabled=!0,i}function eh(){this.state.eventsEnabled||(this.state=th(this.reference,this.options,this.state,this.scheduleUpdate))}function ih(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,Jd(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach((function(t){t.removeEventListener("scroll",e.updateBound)})),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function nh(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function oh(t,e){Object.keys(e).forEach((function(i){var n="";-1!==["width","height","top","right","bottom","left"].indexOf(i)&&nh(e[i])&&(n="px"),t.style[i]=e[i]+n}))}var rh=ud&&/Firefox/i.test(navigator.userAgent);function sh(t,e,i){var n=Yd(t,(function(t){return t.name===e})),o=!!n&&t.some((function(t){return t.name===i&&t.enabled&&t.order<n.order}));if(!o){var r="`"+e+"`",s="`"+i+"`";console.warn(s+" modifier is required by "+r+" modifier in order to work, be sure to include it before "+r+"!")}return o}var ah=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],lh=ah.slice(3);function ch(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=lh.indexOf(t),n=lh.slice(i+1).concat(lh.slice(0,i));return e?n.reverse():n}var uh="flip",dh="clockwise",hh="counterclockwise";function fh(t,e,i,n){var o=[0,0],r=-1!==["right","left"].indexOf(n),s=t.split(/(\+|\-)/).map((function(t){return t.trim()})),a=s.indexOf(Yd(s,(function(t){return-1!==t.search(/,|\s/)})));s[a]&&-1===s[a].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,c=-1!==a?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return(c=c.map((function(t,n){var o=(1===n?!r:r)?"height":"width",s=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,s=!0,t):s?(t[t.length-1]+=e,s=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,i,n){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],s=o[2];if(!r)return t;if(0===s.indexOf("%")){var a=void 0;switch(s){case"%p":a=i;break;case"%":case"%r":default:a=n}return Od(a)[e]/100*r}if("vh"===s||"vw"===s)return("vh"===s?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r;return r}(t,o,e,i)}))}))).forEach((function(t,e){t.forEach((function(i,n){nh(i)&&(o[e]+=i*("-"===t[n-1]?-1:1))}))})),o}var ph={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,i=e.split("-")[0],n=e.split("-")[1];if(n){var o=t.offsets,r=o.reference,s=o.popper,a=-1!==["bottom","top"].indexOf(i),l=a?"left":"top",c=a?"width":"height",u={start:Id({},l,r[l]),end:Id({},l,r[l]+r[c]-s[c])};t.offsets.popper=Pd({},s,u[n])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var i=e.offset,n=t.placement,o=t.offsets,r=o.popper,s=o.reference,a=n.split("-")[0],l=void 0;return l=nh(+i)?[+i,0]:fh(i,r,s,a),"left"===a?(r.top+=l[0],r.left-=l[1]):"right"===a?(r.top+=l[0],r.left+=l[1]):"top"===a?(r.left+=l[0],r.top-=l[1]):"bottom"===a&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var i=e.boundariesElement||Td(t.instance.popper);t.instance.reference===i&&(i=Td(i));var n=Xd("transform"),o=t.instance.popper.style,r=o.top,s=o.left,a=o[n];o.top="",o.left="",o[n]="";var l=Md(t.instance.popper,t.instance.reference,e.padding,i,t.positionFixed);o.top=r,o.left=s,o[n]=a,e.boundaries=l;var c=e.priority,u=t.offsets.popper,d={primary:function(t){var i=u[t];return u[t]<l[t]&&!e.escapeWithReference&&(i=Math.max(u[t],l[t])),Id({},t,i)},secondary:function(t){var i="right"===t?"left":"top",n=u[i];return u[t]>l[t]&&!e.escapeWithReference&&(n=Math.min(u[i],l[t]-("right"===t?u.width:u.height))),Id({},i,n)}};return c.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";u=Pd({},u,d[e](t))})),t.offsets.popper=u,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,i=e.popper,n=e.reference,o=t.placement.split("-")[0],r=Math.floor,s=-1!==["top","bottom"].indexOf(o),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return i[a]<r(n[l])&&(t.offsets.popper[l]=r(n[l])-i[c]),i[l]>r(n[a])&&(t.offsets.popper[l]=r(n[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var i;if(!sh(t.instance.modifiers,"arrow","keepTogether"))return t;var n=e.element;if("string"==typeof n){if(!(n=t.instance.popper.querySelector(n)))return t}else if(!t.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,a=r.reference,l=-1!==["left","right"].indexOf(o),c=l?"height":"width",u=l?"Top":"Left",d=u.toLowerCase(),h=l?"left":"top",f=l?"bottom":"right",p=jd(n)[c];a[f]-p<s[d]&&(t.offsets.popper[d]-=s[d]-(a[f]-p)),a[d]+p>s[f]&&(t.offsets.popper[d]+=a[d]+p-s[f]),t.offsets.popper=Od(t.offsets.popper);var m=a[d]+a[c]/2-p/2,v=pd(t.instance.popper),b=parseFloat(v["margin"+u]),g=parseFloat(v["border"+u+"Width"]),y=m-t.offsets.popper[d]-b-g;return y=Math.max(Math.min(s[c]-p,y),0),t.arrowElement=n,t.offsets.arrow=(Id(i={},d,Math.round(y)),Id(i,h,""),i),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(Kd(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var i=Md(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),n=t.placement.split("-")[0],o=Gd(n),r=t.placement.split("-")[1]||"",s=[];switch(e.behavior){case uh:s=[n,o];break;case dh:s=ch(n);break;case hh:s=ch(n,!0);break;default:s=e.behavior}return s.forEach((function(a,l){if(n!==a||s.length===l+1)return t;n=t.placement.split("-")[0],o=Gd(n);var c=t.offsets.popper,u=t.offsets.reference,d=Math.floor,h="left"===n&&d(c.right)>d(u.left)||"right"===n&&d(c.left)<d(u.right)||"top"===n&&d(c.bottom)>d(u.top)||"bottom"===n&&d(c.top)<d(u.bottom),f=d(c.left)<d(i.left),p=d(c.right)>d(i.right),m=d(c.top)<d(i.top),v=d(c.bottom)>d(i.bottom),b="left"===n&&f||"right"===n&&p||"top"===n&&m||"bottom"===n&&v,g=-1!==["top","bottom"].indexOf(n),y=!!e.flipVariations&&(g&&"start"===r&&f||g&&"end"===r&&p||!g&&"start"===r&&m||!g&&"end"===r&&v),w=!!e.flipVariationsByContent&&(g&&"start"===r&&p||g&&"end"===r&&f||!g&&"start"===r&&v||!g&&"end"===r&&m),T=y||w;(h||b||T)&&(t.flipped=!0,(h||b)&&(n=s[l+1]),T&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=n+(r?"-"+r:""),t.offsets.popper=Pd({},t.offsets.popper,Wd(t.instance.popper,t.offsets.reference,t.placement)),t=Ud(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,i=e.split("-")[0],n=t.offsets,o=n.popper,r=n.reference,s=-1!==["left","right"].indexOf(i),a=-1===["top","left"].indexOf(i);return o[s?"left":"top"]=r[i]-(a?o[s?"width":"height"]:0),t.placement=Gd(e),t.offsets.popper=Od(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!sh(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,i=Yd(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottom<i.top||e.left>i.right||e.top>i.bottom||e.right<i.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var i=e.x,n=e.y,o=t.offsets.popper,r=Yd(t.instance.modifiers,(function(t){return"applyStyle"===t.name})).gpuAcceleration;void 0!==r&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var s=void 0!==r?r:e.gpuAcceleration,a=Td(t.instance.popper),l=Vd(a),c={position:o.position},u=function(t,e){var i=t.offsets,n=i.popper,o=i.reference,r=Math.round,s=Math.floor,a=function(t){return t},l=r(o.width),c=r(n.width),u=-1!==["left","right"].indexOf(t.placement),d=-1!==t.placement.indexOf("-"),h=e?u||d||l%2==c%2?r:s:a,f=e?r:a;return{left:h(l%2==1&&c%2==1&&!d&&e?n.left-1:n.left),top:f(n.top),bottom:f(n.bottom),right:h(n.right)}}(t,window.devicePixelRatio<2||!rh),d="bottom"===i?"top":"bottom",h="right"===n?"left":"right",f=Xd("transform"),p=void 0,m=void 0;if(m="bottom"===d?"HTML"===a.nodeName?-a.clientHeight+u.bottom:-l.height+u.bottom:u.top,p="right"===h?"HTML"===a.nodeName?-a.clientWidth+u.right:-l.width+u.right:u.left,s&&f)c[f]="translate3d("+p+"px, "+m+"px, 0)",c[d]=0,c[h]=0,c.willChange="transform";else{var v="bottom"===d?-1:1,b="right"===h?-1:1;c[d]=m*v,c[h]=p*b,c.willChange=d+", "+h}var g={"x-placement":t.placement};return t.attributes=Pd({},g,t.attributes),t.styles=Pd({},c,t.styles),t.arrowStyles=Pd({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){var e,i;return oh(t.instance.popper,t.styles),e=t.instance.popper,i=t.attributes,Object.keys(i).forEach((function(t){!1!==i[t]?e.setAttribute(t,i[t]):e.removeAttribute(t)})),t.arrowElement&&Object.keys(t.arrowStyles).length&&oh(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,i,n,o){var r=Nd(o,e,t,i.positionFixed),s=zd(i.placement,r,e,t,i.modifiers.flip.boundariesElement,i.modifiers.flip.padding);return e.setAttribute("x-placement",s),oh(e,{position:i.positionFixed?"fixed":"absolute"}),i},gpuAcceleration:void 0}}},mh=function(){function t(e,i){var n=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};Dd(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(n.update)},this.update=hd(this.update.bind(this)),this.options=Pd({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=i&&i.jquery?i[0]:i,this.options.modifiers={},Object.keys(Pd({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){n.options.modifiers[e]=Pd({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return Pd({name:t},n.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&fd(t.onLoad)&&t.onLoad(n.reference,n.popper,n.options,t,n.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return Fd(t,[{key:"update",value:function(){return qd.call(this)}},{key:"destroy",value:function(){return Zd.call(this)}},{key:"enableEventListeners",value:function(){return eh.call(this)}},{key:"disableEventListeners",value:function(){return ih.call(this)}}]),t}();mh.Utils=("undefined"!=typeof window?window:global).PopperUtils,mh.placements=ah,mh.Defaults=ph;var vh,bh,gh,yh,wh,Th,Ch,xh,Sh,kh,$h,Bh,BvEvent=function(){function BvEvent(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(o(this,BvEvent),!t)throw new TypeError("Failed to construct '".concat(this.constructor.name,"'. 1 argument required, ").concat(arguments.length," given."));Gt(this,BvEvent.Defaults,this.constructor.Defaults,e,{type:t}),Yt(this,{type:{enumerable:!0,configurable:!1,writable:!1},cancelable:{enumerable:!0,configurable:!1,writable:!1},nativeEvent:{enumerable:!0,configurable:!1,writable:!1},target:{enumerable:!0,configurable:!1,writable:!1},relatedTarget:{enumerable:!0,configurable:!1,writable:!1},vueTarget:{enumerable:!0,configurable:!1,writable:!1},componentId:{enumerable:!0,configurable:!1,writable:!1}});var i=!1;this.preventDefault=function(){this.cancelable&&(i=!0)},Ut(this,"defaultPrevented",{enumerable:!0,get:function(){return i}})}return s(BvEvent,null,[{key:"Defaults",get:function(){return{type:"",cancelable:!0,nativeEvent:null,target:null,relatedTarget:null,vueTarget:null,componentId:null}}}]),BvEvent}(),_h=i.default.extend({data:function(){return{listenForClickOut:!1}},watch:{listenForClickOut:function(t,e){t!==e&&(ks(this.clickOutElement,this.clickOutEventName,this._clickOutHandler,lo),t&&Ss(this.clickOutElement,this.clickOutEventName,this._clickOutHandler,lo))}},beforeCreate:function(){this.clickOutElement=null,this.clickOutEventName=null},mounted:function(){this.clickOutElement||(this.clickOutElement=document),this.clickOutEventName||(this.clickOutEventName="click"),this.listenForClickOut&&Ss(this.clickOutElement,this.clickOutEventName,this._clickOutHandler,lo)},beforeDestroy:function(){ks(this.clickOutElement,this.clickOutEventName,this._clickOutHandler,lo)},methods:{isClickOut:function(t){return!Lr(this.$el,t.target)},_clickOutHandler:function(t){this.clickOutHandler&&this.isClickOut(t)&&this.clickOutHandler(t)}}}),Dh=i.default.extend({data:function(){return{listenForFocusIn:!1}},watch:{listenForFocusIn:function(t,e){t!==e&&(ks(this.focusInElement,"focusin",this._focusInHandler,lo),t&&Ss(this.focusInElement,"focusin",this._focusInHandler,lo))}},beforeCreate:function(){this.focusInElement=null},mounted:function(){this.focusInElement||(this.focusInElement=document),this.listenForFocusIn&&Ss(this.focusInElement,"focusin",this._focusInHandler,lo)},beforeDestroy:function(){ks(this.focusInElement,"focusin",this._focusInHandler,lo)},methods:{_focusInHandler:function(t){this.focusInHandler&&this.focusInHandler(t)}}}),Fh=Ds(Ke,eo),Ih=Ds(Ke,zn),Ph=[".dropdown-item",".b-dropdown-form"].map((function(t){return"".concat(t,":not(.disabled):not([disabled])")})).join(", "),Oh=vs(ee(c(c({},fc),{},{boundary:hs([HTMLElement,go],"scrollParent"),disabled:hs(ho,!1),dropleft:hs(ho,!1),dropright:hs(ho,!1),dropup:hs(ho,!1),noFlip:hs(ho,!1),offset:hs(_o,0),popperOpts:hs(vo,{}),right:hs(ho,!1)})),Ke),Vh=i.default.extend({mixins:[pc,Ja,_h,Dh],provide:function(){return{bvDropdown:this}},inject:{bvNavbar:{default:null}},props:Oh,data:function(){return{visible:!1,visibleChangePrevented:!1}},computed:{inNavbar:function(){return!It(this.bvNavbar)},toggler:function(){var t=this.$refs.toggle;return t?t.$el||t:null},directionClass:function(){return this.dropup?"dropup":this.dropright?"dropright":this.dropleft?"dropleft":""},boundaryClass:function(){return"scrollParent"===this.boundary||this.inNavbar?"":"position-static"}},watch:{visible:function(t,e){if(this.visibleChangePrevented)this.visibleChangePrevented=!1;else if(t!==e){var i=new BvEvent(t?to:Nn,{cancelable:!0,vueTarget:this,target:this.$refs.menu,relatedTarget:null,componentId:this.safeId?this.safeId():this.id||null});if(this.emitEvent(i),i.defaultPrevented)return this.visibleChangePrevented=!0,this.visible=e,void this.$off(zn,this.focusToggler);t?this.showMenu():this.hideMenu()}},disabled:function(t,e){t!==e&&t&&this.visible&&(this.visible=!1)}},created:function(){this.$_popper=null,this.$_hideTimeout=null},deactivated:function(){this.visible=!1,this.whileOpenListen(!1),this.destroyPopper()},beforeDestroy:function(){this.visible=!1,this.whileOpenListen(!1),this.destroyPopper(),this.clearHideTimeout()},methods:{emitEvent:function(t){var e=t.type;this.emitOnRoot(Ds(Ke,e),t),this.$emit(e,t)},showMenu:function(){var t=this;if(!this.disabled){if(!this.inNavbar)if("undefined"==typeof mh)le("Popper.js not found. Falling back to CSS positioning",Ke);else{var e=this.dropup&&this.right||this.split?this.$el:this.$refs.toggle;e=e.$el||e,this.createPopper(e)}this.emitOnRoot(Fh,this),this.whileOpenListen(!0),this.$nextTick((function(){t.focusMenu(),t.$emit(eo)}))}},hideMenu:function(){this.whileOpenListen(!1),this.emitOnRoot(Ih,this),this.$emit(zn),this.destroyPopper()},createPopper:function(t){this.destroyPopper(),this.$_popper=new mh(t,this.$refs.menu,this.getPopperConfig())},destroyPopper:function(){this.$_popper&&this.$_popper.destroy(),this.$_popper=null},updatePopper:function(){try{this.$_popper.scheduleUpdate()}catch(t){}},clearHideTimeout:function(){clearTimeout(this.$_hideTimeout),this.$_hideTimeout=null},getPopperConfig:function(){var t="bottom-start";this.dropup?t=this.right?"top-end":"top-start":this.dropright?t="right-start":this.dropleft?t="left-start":this.right&&(t="bottom-end");var e={placement:t,modifiers:{offset:{offset:this.offset||0},flip:{enabled:!this.noFlip}}},i=this.boundary;return i&&(e.modifiers.preventOverflow={boundariesElement:i}),te(e,this.popperOpts||{})},whileOpenListen:function(t){this.listenForClickOut=t,this.listenForFocusIn=t;var e=t?"$on":"$off";this.$root[e](Fh,this.rootCloseListener)},rootCloseListener:function(t){t!==this&&(this.visible=!1)},show:function(){var t=this;this.disabled||xr((function(){t.visible=!0}))},hide:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.disabled||(this.visible=!1,t&&this.$once(zn,this.focusToggler))},toggle:function(t){var e=t=t||{},i=e.type,n=e.keyCode;("click"===i||"keydown"===i&&-1!==[Ha,Ga,Ra].indexOf(n))&&(this.disabled?this.visible=!1:(this.$emit(no,t),Bs(t),this.visible?this.hide(!0):this.show()))},onMousedown:function(t){Bs(t,{propagation:!1})},onKeydown:function(t){var e=t.keyCode;27===e?this.onEsc(t):e===Ra?this.focusNext(t,!1):e===Wa&&this.focusNext(t,!0)},onEsc:function(t){this.visible&&(this.visible=!1,Bs(t),this.$once(zn,this.focusToggler))},onSplitClick:function(t){this.disabled?this.visible=!1:this.$emit(Bn,t)},hideHandler:function(t){var e=this,i=t.target;!this.visible||Lr(this.$refs.menu,i)||Lr(this.toggler,i)||(this.clearHideTimeout(),this.$_hideTimeout=setTimeout((function(){return e.hide()}),this.inNavbar?300:0))},clickOutHandler:function(t){this.hideHandler(t)},focusInHandler:function(t){this.hideHandler(t)},focusNext:function(t,e){var i=this,n=t.target;!this.visible||t&&Er(".dropdown form",n)||(Bs(t),this.$nextTick((function(){var t=i.getItems();if(!(t.length<1)){var o=t.indexOf(n);e&&o>0?o--:!e&&o<t.length-1&&o++,o<0&&(o=0),i.focusItem(o,t)}})))},focusItem:function(t,e){var i=e.find((function(e,i){return i===t}));ts(i)},getItems:function(){return(Pr(Ph,this.$refs.menu)||[]).filter(Dr)},focusMenu:function(){ts(this.$refs.menu)},focusToggler:function(){var t=this;this.$nextTick((function(){ts(t.toggler)}))}}}),Eh=vs(ee(c(c(c({},fc),Oh),{},{block:hs(ho,!1),html:hs(go),lazy:hs(ho,!1),menuClass:hs(To),noCaret:hs(ho,!1),role:hs(go,"menu"),size:hs(go),split:hs(ho,!1),splitButtonType:hs(go,"button",(function(t){return nr(["button","submit","reset"],t)})),splitClass:hs(To),splitHref:hs(go),splitTo:hs(Io),splitVariant:hs(go),text:hs(go),toggleClass:hs(To),toggleTag:hs(go,"button"),toggleText:hs(go,"Toggle dropdown"),variant:hs(go,"secondary")})),Ke),Lh=i.default.extend({name:Ke,mixins:[pc,Vh,Cs],props:Eh,computed:{dropdownClasses:function(){var t=this.block,e=this.split;return[this.directionClass,this.boundaryClass,{show:this.visible,"btn-group":e||!t,"d-flex":t&&e}]},menuClasses:function(){return[this.menuClass,{"dropdown-menu-right":this.right,show:this.visible}]},toggleClasses:function(){var t=this.split;return[this.toggleClass,{"dropdown-toggle-split":t,"dropdown-toggle-no-caret":this.noCaret&&!t}]}},render:function(t){var e=this.visible,i=this.variant,n=this.size,o=this.block,r=this.disabled,s=this.split,a=this.role,l=this.hide,u=this.toggle,d={variant:i,size:n,block:o,disabled:r},h=this.normalizeSlot(Eo),f=this.hasNormalizedSlot(Eo)?{}:Fl(this.html,this.text),p=t();if(s){var m=this.splitTo,v=this.splitHref,b=this.splitButtonType,g=c(c({},d),{},{variant:this.splitVariant||i});m?g.to=m:v?g.href=v:b&&(g.type=b),p=t(ml,{class:this.splitClass,attrs:{id:this.safeId("_BV_button_")},props:g,domProps:f,on:{click:this.onSplitClick},ref:"button"},h),h=[t("span",{class:["sr-only"]},[this.toggleText])],f={}}var y=t(ml,{staticClass:"dropdown-toggle",class:this.toggleClasses,attrs:{id:this.safeId("_BV_toggle_"),"aria-haspopup":"true","aria-expanded":vr(e)},props:c(c({},d),{},{tag:this.toggleTag,block:o&&!s}),domProps:f,on:{mousedown:this.onMousedown,click:u,keydown:u},ref:"toggle"},h),w=t("ul",{staticClass:"dropdown-menu",class:this.menuClasses,attrs:{role:a,tabindex:"-1","aria-labelledby":this.safeId(s?"_BV_button_":"_BV_toggle_")},on:{keydown:this.onKeydown},ref:"menu"},[!this.lazy||e?this.normalizeSlot(Ao,{hide:l}):t()]);return t("div",{staticClass:"dropdown b-dropdown",class:this.dropdownClasses,attrs:{id:this.safeId()}},[p,y,w])}}),Ah=Qt(nl,["event","routerTag"]),Rh=vs(ee(c(c({},Ah),{},{linkClass:hs(To),variant:hs(go)})),ti),Mh=i.default.extend({name:ti,mixins:[Za,Cs],inject:{bvDropdown:{default:null}},inheritAttrs:!1,props:Rh,computed:{computedAttrs:function(){return c(c({},this.bvAttrs),{},{role:"menuitem"})}},methods:{closeDropdown:function(){var t=this;xr((function(){t.bvDropdown&&t.bvDropdown.hide(!0)}))},onClick:function(t){this.$emit(Bn,t),this.closeDropdown()}},render:function(t){var e=this.linkClass,i=this.variant,n=this.active,o=this.disabled,r=this.onClick,s=this.bvAttrs;return t("li",{class:s.class,style:s.style,attrs:{role:"presentation"}},[t(ol,{staticClass:"dropdown-item",class:[e,a({},"text-".concat(i),i&&!(n||o))],props:ps(Ah,this.$props),attrs:this.computedAttrs,on:{click:r},ref:"item"},this.normalizeSlot())])}}),Hh=vs({active:hs(ho,!1),activeClass:hs(go,"active"),buttonClass:hs(To),disabled:hs(ho,!1),variant:hs(go)},ei),zh=i.default.extend({name:ei,mixins:[Za,Cs],inject:{bvDropdown:{default:null}},inheritAttrs:!1,props:Hh,computed:{computedAttrs:function(){return c(c({},this.bvAttrs),{},{role:"menuitem",type:"button",disabled:this.disabled})}},methods:{closeDropdown:function(){this.bvDropdown&&this.bvDropdown.hide(!0)},onClick:function(t){this.$emit(Bn,t),this.closeDropdown()}},render:function(t){var e,i=this.active,n=this.variant,o=this.bvAttrs;return t("li",{class:o.class,style:o.style,attrs:{role:"presentation"}},[t("button",{staticClass:"dropdown-item",class:[this.buttonClass,(e={},a(e,this.activeClass,i),a(e,"text-".concat(n),n&&!(i||this.disabled)),e)],attrs:this.computedAttrs,on:{click:this.onClick},ref:"button"},this.normalizeSlot())])}}),Nh=vs({id:hs(go),tag:hs(go,"header"),variant:hs(go)},Qe),jh=i.default.extend({name:Qe,functional:!0,props:Nh,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.tag,s=i.variant;return t("li",F(Qt(n,["attrs"]),{attrs:{role:"presentation"}}),[t(r,{staticClass:"dropdown-header",class:a({},"text-".concat(s),s),attrs:c(c({},n.attrs||{}),{},{id:i.id||null,role:Br(r,"header")?null:"heading"}),ref:"header"},o)])}}),Gh=vs({tag:hs(go,"hr")},Xe),Wh=i.default.extend({name:Xe,functional:!0,props:Gh,render:function(t,e){var i=e.props,n=e.data;return t("li",F(Qt(n,["attrs"]),{attrs:{role:"presentation"}}),[t(i.tag,{staticClass:"dropdown-divider",attrs:c(c({},n.attrs||{}),{},{role:"separator","aria-orientation":"horizontal"}),ref:"divider"})])}}),Yh=vs({id:hs(go),inline:hs(ho,!1),novalidate:hs(ho,!1),validated:hs(ho,!1)},oi),Uh=i.default.extend({name:oi,functional:!0,props:Yh,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t("form",F(n,{class:{"form-inline":i.inline,"was-validated":i.validated},attrs:{id:i.id,novalidate:i.novalidate}}),o)}}),qh=vs(ee(c(c({},Yh),{},{disabled:hs(ho,!1),formClass:hs(To)})),Ze),Kh=i.default.extend({name:Ze,functional:!0,props:qh,render:function(t,e){var i=e.props,n=e.data,o=e.listeners,r=e.children;return t("li",F(Qt(n,["attrs","on"]),{attrs:{role:"presentation"}}),[t(Uh,{staticClass:"b-dropdown-form",class:[i.formClass,{disabled:i.disabled}],props:i,attrs:c(c({},n.attrs||{}),{},{disabled:i.disabled,tabindex:i.disabled?null:"-1"}),on:o,ref:"form"},r)])}}),Xh=vs({tag:hs(go,"p"),textClass:hs(To),variant:hs(go)},ii),Zh=i.default.extend({name:ii,functional:!0,props:Xh,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.tag,s=i.textClass,l=i.variant;return t("li",F(Qt(n,["attrs"]),{attrs:{role:"presentation"}}),[t(r,{staticClass:"b-dropdown-text",class:[s,a({},"text-".concat(l),l)],props:i,attrs:n.attrs||{},ref:"text"},o)])}}),Jh=vs({ariaDescribedby:hs(go),header:hs(go),headerClasses:hs(To),headerTag:hs(go,"header"),headerVariant:hs(go),id:hs(go)},Je),Qh=i.default.extend({name:Je,functional:!0,props:Jh,render:function(t,e){var i=e.props,n=e.data,o=e.slots,r=e.scopedSlots,s=i.id,l=i.variant,u=i.header,d=i.headerTag,h=o(),f=r||{},p={},m=s?"_bv_".concat(s,"_group_dd_header"):null,v=t();return(ws(No,f,h)||u)&&(v=t(d,{staticClass:"dropdown-header",class:[i.headerClasses,a({},"text-".concat(l),l)],attrs:{id:m,role:Br(d,"header")?null:"heading"}},Ts(No,p,f,h)||u)),t("li",F(Qt(n,["attrs"]),{attrs:{role:"presentation"}}),[v,t("ul",{staticClass:"list-unstyled",attrs:c(c({},n.attrs||{}),{},{id:s,role:"group","aria-describedby":[m,i.ariaDescribedBy].filter(ne).join(" ").trim()||null})},Ts(Ao,p,f,h))])}}),tf=me({components:{BDropdown:Lh,BDd:Lh,BDropdownItem:Mh,BDdItem:Mh,BDropdownItemButton:zh,BDropdownItemBtn:zh,BDdItemButton:zh,BDdItemBtn:zh,BDropdownHeader:jh,BDdHeader:jh,BDropdownDivider:Wh,BDdDivider:Wh,BDropdownForm:Kh,BDdForm:Kh,BDropdownText:Zh,BDdText:Zh,BDropdownGroup:Qh,BDdGroup:Qh}}),ef=["iframe","embed","video","object","img","b-img","b-img-lazy"],nf=vs({aspect:hs(go,"16by9"),tag:hs(go,"div"),type:hs(go,"iframe",(function(t){return nr(ef,t)}))},ni),of=i.default.extend({name:ni,functional:!0,props:nf,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.aspect;return t(i.tag,{staticClass:"embed-responsive",class:a({},"embed-responsive-".concat(r),r),ref:n.ref},[t(i.type,F(Qt(n,["ref"]),{staticClass:"embed-responsive-item"}),o)])}}),rf=me({components:{BEmbed:of}}),sf=vs({disabledField:hs(go,"disabled"),htmlField:hs(go,"html"),options:hs(wo,[]),textField:hs(go,"text"),valueField:hs(go,"value")},"formOptionControls"),af=i.default.extend({props:sf,computed:{formOptions:function(){return this.normalizeOptions(this.options)}},methods:{normalizeOption:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(Ht(t)){var i=re(t,this.valueField),n=re(t,this.textField);return{value:Ft(i)?e||n:i,text:Dl(String(Ft(n)?e:n)),html:re(t,this.htmlField),disabled:Boolean(re(t,this.disabledField))}}return{value:e||t,text:Dl(String(t)),disabled:!1}},normalizeOptions:function(t){var e=this;return Rt(t)?t.map((function(t){return e.normalizeOption(t)})):Ht(t)?(le('Setting prop "options" to an object is deprecated. Use the array format instead.',this.$options.name),Kt(t).map((function(i){return e.normalizeOption(t[i]||{},i)}))):[]}}}),lf=vs(ee(c(c({},sf),{},{id:hs(go,void 0,!0)})),ai),cf=i.default.extend({name:ai,mixins:[af,Cs],props:lf,render:function(t){var e=this.id,i=this.formOptions.map((function(e,i){var n=e.value,o=e.text,r=e.html,s=e.disabled;return t("option",{attrs:{value:n,disabled:s},domProps:Fl(r,o),key:"option_".concat(i)})}));return t("datalist",{attrs:{id:e}},[i,this.normalizeSlot()])}}),uf=vs({id:hs(go),inline:hs(ho,!1),tag:hs(go,"small"),textVariant:hs(go,"muted")},xi),df=i.default.extend({name:xi,functional:!0,props:uf,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.tag,F(n,{class:a({"form-text":!i.inline},"text-".concat(i.textVariant),i.textVariant),attrs:{id:i.id}}),o)}}),hf=vs({ariaLive:hs(go),forceShow:hs(ho,!1),id:hs(go),role:hs(go),state:hs(ho,null),tag:hs(go,"div"),tooltip:hs(ho,!1)},hi),ff=i.default.extend({name:hi,functional:!0,props:hf,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.tooltip,s=i.ariaLive,a=!0===i.forceShow||!1===i.state;return t(i.tag,F(n,{class:{"d-block":a,"invalid-feedback":!r,"invalid-tooltip":r},attrs:{id:i.id||null,role:i.role||null,"aria-live":s||null,"aria-atomic":s?"true":null}}),o)}}),pf=vs({ariaLive:hs(go),forceShow:hs(ho,!1),id:hs(go),role:hs(go),state:hs(ho,null),tag:hs(go,"div"),tooltip:hs(ho,!1)},$i),mf=i.default.extend({name:$i,functional:!0,props:pf,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.tooltip,s=i.ariaLive,a=!0===i.forceShow||!0===i.state;return t(i.tag,F(n,{class:{"d-block":a,"valid-feedback":!r,"valid-tooltip":r},attrs:{id:i.id||null,role:i.role||null,"aria-live":s||null,"aria-atomic":s?"true":null}}),o)}}),vf=vs({tag:hs(go,"div")},vi),bf=i.default.extend({name:vi,functional:!0,props:vf,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.tag,F(n,{staticClass:"form-row"}),o)}}),gf=me({components:{BForm:Uh,BFormDatalist:cf,BDatalist:cf,BFormText:df,BFormInvalidFeedback:ff,BFormFeedback:ff,BFormValidFeedback:mf,BFormRow:bf}}),yf=function(t,e){for(var i=0;i<t.length;i++)if(Ua(t[i],e))return i;return-1},wf="input, textarea, select",Tf=vs({autofocus:hs(ho,!1),disabled:hs(ho,!1),form:hs(go),id:hs(go),name:hs(go),required:hs(ho,!1)},"formControls"),Cf=i.default.extend({props:Tf,mounted:function(){this.handleAutofocus()},activated:function(){this.handleAutofocus()},methods:{handleAutofocus:function(){var t=this;this.$nextTick((function(){xr((function(){var e=t.$el;t.autofocus&&Dr(e)&&(Vr(e,wf)||(e=Or(wf,e)),ts(e))}))}))}}}),xf=vs({plain:hs(ho,!1)},"formControls"),Sf=i.default.extend({props:xf,computed:{custom:function(){return!this.plain}}}),kf=vs({size:hs(go)},"formControls"),$f=i.default.extend({props:kf,computed:{sizeFormClass:function(){return[this.size?"form-control-".concat(this.size):null]}}}),Bf=vs({state:hs(ho,null)},"formState"),_f=i.default.extend({props:Bf,computed:{computedState:function(){return Vt(this.state)?this.state:null},stateClass:function(){var t=this.computedState;return!0===t?"is-valid":!1===t?"is-invalid":null},computedAriaInvalid:function(){var t=this.ariaInvalid;return!0===t||"true"===t||""===t||!1===this.computedState?"true":t}}}),Df=ys("checked",{defaultValue:null}),Ff=Df.mixin,If=Df.props,Pf=Df.prop,Of=Df.event,Vf=vs(ee(c(c(c(c(c(c(c({},fc),If),Tf),kf),Bf),xf),{},{ariaLabel:hs(go),ariaLabelledby:hs(go),button:hs(ho,!1),buttonVariant:hs(go),inline:hs(ho,!1),value:hs(co)})),"formRadioCheckControls"),Ef=i.default.extend({mixins:[Za,pc,Ff,Cs,Cf,$f,_f,Sf],inheritAttrs:!1,props:Vf,data:function(){return{localChecked:this.isGroup?this.bvGroup[Pf]:this[Pf],hasFocus:!1}},computed:{computedLocalChecked:{get:function(){return this.isGroup?this.bvGroup.localChecked:this.localChecked},set:function(t){this.isGroup?this.bvGroup.localChecked=t:this.localChecked=t}},isChecked:function(){return Ua(this.value,this.computedLocalChecked)},isRadio:function(){return!0},isGroup:function(){return!!this.bvGroup},isBtnMode:function(){return this.isGroup?this.bvGroup.buttons:this.button},isPlain:function(){return!this.isBtnMode&&(this.isGroup?this.bvGroup.plain:this.plain)},isCustom:function(){return!this.isBtnMode&&!this.isPlain},isSwitch:function(){return!(this.isBtnMode||this.isRadio||this.isPlain)&&(this.isGroup?this.bvGroup.switches:this.switch)},isInline:function(){return this.isGroup?this.bvGroup.inline:this.inline},isDisabled:function(){return this.isGroup&&this.bvGroup.disabled||this.disabled},isRequired:function(){return this.computedName&&(this.isGroup?this.bvGroup.required:this.required)},computedName:function(){return(this.isGroup?this.bvGroup.groupName:this.name)||null},computedForm:function(){return(this.isGroup?this.bvGroup.form:this.form)||null},computedSize:function(){return(this.isGroup?this.bvGroup.size:this.size)||""},computedState:function(){return this.isGroup?this.bvGroup.computedState:Vt(this.state)?this.state:null},computedButtonVariant:function(){var t=this.buttonVariant;return t||(this.isGroup&&this.bvGroup.buttonVariant?this.bvGroup.buttonVariant:"secondary")},buttonClasses:function(){var t,e=this.computedSize;return["btn","btn-".concat(this.computedButtonVariant),(t={},a(t,"btn-".concat(e),e),a(t,"disabled",this.isDisabled),a(t,"active",this.isChecked),a(t,"focus",this.hasFocus),t)]},computedAttrs:function(){var t=this.isDisabled,e=this.isRequired;return c(c({},this.bvAttrs),{},{id:this.safeId(),type:this.isRadio?"radio":"checkbox",name:this.computedName,form:this.computedForm,disabled:t,required:e,"aria-required":e||null,"aria-label":this.ariaLabel||null,"aria-labelledby":this.ariaLabelledby||null})}},watch:(vh={},a(vh,Pf,(function(){this["".concat(Pf,"Watcher")].apply(this,arguments)})),a(vh,"computedLocalChecked",(function(){this.computedLocalCheckedWatcher.apply(this,arguments)})),vh),methods:(bh={},a(bh,"".concat(Pf,"Watcher"),(function(t){Ua(t,this.computedLocalChecked)||(this.computedLocalChecked=t)})),a(bh,"computedLocalCheckedWatcher",(function(t,e){Ua(t,e)||this.$emit(Of,t)})),a(bh,"handleChange",(function(t){var e=this,i=t.target.checked,n=this.value,o=i?n:null;this.computedLocalChecked=n,this.$nextTick((function(){e.$emit($n,o),e.isGroup&&e.bvGroup.$emit($n,o)}))})),a(bh,"handleFocus",(function(t){t.target&&("focus"===t.type?this.hasFocus=!0:"blur"===t.type&&(this.hasFocus=!1))})),a(bh,"focus",(function(){this.isDisabled||ts(this.$refs.input)})),a(bh,"blur",(function(){this.isDisabled||es(this.$refs.input)})),bh),render:function(t){var e=this.isRadio,i=this.isBtnMode,n=this.isPlain,o=this.isCustom,r=this.isInline,s=this.isSwitch,l=this.computedSize,u=this.bvAttrs,d=this.normalizeSlot(),h=t("input",{class:[{"form-check-input":n,"custom-control-input":o,"position-static":n&&!d},i?"":this.stateClass],directives:[{name:"model",value:this.computedLocalChecked}],attrs:this.computedAttrs,domProps:{value:this.value,checked:this.isChecked},on:c({change:this.handleChange},i?{focus:this.handleFocus,blur:this.handleFocus}:{}),key:"input",ref:"input"});if(i){var f=t("label",{class:this.buttonClasses},[h,d]);return this.isGroup||(f=t("div",{class:["btn-group-toggle","d-inline-block"]},[f])),f}var p=t();return n&&!d||(p=t("label",{class:{"form-check-label":n,"custom-control-label":o},attrs:{for:this.safeId()}},d)),t("div",{class:[a({"form-check":n,"form-check-inline":n&&r,"custom-control":o,"custom-control-inline":o&&r,"custom-checkbox":o&&!e&&!s,"custom-switch":s,"custom-radio":o&&e},"b-custom-control-".concat(l),l&&!i),u.class],style:u.style},[h,p])}}),Lf="indeterminate",Af="update:indeterminate",Rf=vs(ee(c(c({},Vf),{},(a(gh={},Lf,hs(ho,!1)),a(gh,"switch",hs(ho,!1)),a(gh,"uncheckedValue",hs(co,!1)),a(gh,"value",hs(co,!0)),gh))),ri),Mf=i.default.extend({name:ri,mixins:[Ef],inject:{bvGroup:{from:"bvCheckGroup",default:null}},props:Rf,computed:{isChecked:function(){var t=this.value,e=this.computedLocalChecked;return Rt(e)?yf(e,t)>-1:Ua(e,t)},isRadio:function(){return!1}},watch:a({},Lf,(function(t,e){Ua(t,e)||this.setIndeterminate(t)})),mounted:function(){this.setIndeterminate(this.indeterminate)},methods:{computedLocalCheckedWatcher:function(t,e){if(!Ua(t,e)){this.$emit(Of,t);var i=this.$refs.input;i&&this.$emit(Af,i.indeterminate)}},handleChange:function(t){var e=this,i=t.target,n=i.checked,o=i.indeterminate,r=this.value,s=this.uncheckedValue,a=this.computedLocalChecked;if(Rt(a)){var l=yf(a,r);n&&l<0?a=a.concat(r):!n&&l>-1&&(a=a.slice(0,l).concat(a.slice(l+1)))}else a=n?r:s;this.computedLocalChecked=a,this.$nextTick((function(){e.$emit($n,a),e.isGroup&&e.bvGroup.$emit($n,a),e.$emit(Af,o)}))},setIndeterminate:function(t){Rt(this.computedLocalChecked)&&(t=!1);var e=this.$refs.input;e&&(e.indeterminate=t,this.$emit(Af,t))}}}),Hf=vs(ee(c(c(c(c(c({},fc),Tf),Vf),kf),Bf)),fi),zf=i.default.extend({name:fi,mixins:[pc,Ef,Cf,$f,_f],inject:{bvGroup:{from:"bvRadioGroup",default:!1}},props:Hf,watch:{computedLocalChecked:function(t,e){Ua(t,e)||this.$emit(Of,t)}}}),Nf=["aria-describedby","aria-labelledby"],jf=ys("checked"),Gf=jf.mixin,Wf=jf.props,Yf=jf.prop,Uf=jf.event,qf=vs(ee(c(c(c(c(c(c(c(c({},fc),Wf),Tf),sf),kf),Bf),xf),{},{ariaInvalid:hs(ko,!1),buttonVariant:hs(go),buttons:hs(ho,!1),stacked:hs(ho,!1),validated:hs(ho,!1)})),"formRadioCheckGroups"),Kf=i.default.extend({mixins:[pc,Gf,Cs,Cf,af,$f,_f,Sf],inheritAttrs:!1,props:qf,data:function(){return{localChecked:this[Yf]}},computed:{inline:function(){return!this.stacked},groupName:function(){return this.name||this.safeId()},groupClasses:function(){var t=this.inline,e=this.size,i={"was-validated":this.validated};return this.buttons&&(i=[i,"btn-group-toggle",a({"btn-group":t,"btn-group-vertical":!t},"btn-group-".concat(e),e)]),i}},watch:(yh={},a(yh,Yf,(function(t){Ua(t,this.localChecked)||(this.localChecked=t)})),a(yh,"localChecked",(function(t,e){Ua(t,e)||this.$emit(Uf,t)})),yh),render:function(t){var e=this,i=this.isRadioGroup,n=Jt(this.$attrs,Nf),o=i?zf:Mf,r=this.formOptions.map((function(i,r){var s="BV_option_".concat(r);return t(o,{props:{disabled:i.disabled||!1,id:e.safeId(s),value:i.value},attrs:n,key:s},[t("span",{domProps:Fl(i.html,i.text)})])}));return t("div",{class:[this.groupClasses,"bv-no-focus-ring"],attrs:c(c({},Qt(this.$attrs,Nf)),{},{"aria-invalid":this.computedAriaInvalid,"aria-required":this.required?"true":null,id:this.safeId(),role:i?"radiogroup":"group",tabindex:"-1"})},[this.normalizeSlot(Ho),r,this.normalizeSlot()])}}),Xf=vs(ee(c(c({},qf),{},(a(wh={},Yf,hs(uo,[])),a(wh,"switches",hs(ho,!1)),wh))),si),Zf=i.default.extend({name:si,mixins:[Kf],provide:function(){return{bvCheckGroup:this}},props:Xf,computed:{isRadioGroup:function(){return!1}}}),Jf=me({components:{BFormCheckbox:Mf,BCheckbox:Mf,BCheck:Mf,BFormCheckboxGroup:Zf,BCheckboxGroup:Zf,BCheckGroup:Zf}}),Qf="__BV_hover_handler__",tp="mouseenter",ep=function(t,e,i){$s(t,e,tp,i,lo),$s(t,e,"mouseleave",i,lo)},ip=function(t,e){var i=e.value,n=void 0===i?null:i;if(M){var o=t[Qf],r=Ot(o),s=!(r&&o.fn===n);r&&s&&(ep(!1,t,o),delete t[Qf]),Ot(n)&&s&&(t[Qf]=function(t){var e=function(e){t(e.type===tp,e)};return e.fn=t,e}(n),ep(!0,t,t[Qf]))}},np={bind:ip,componentUpdated:ip,unbind:function(t){ip(t,{value:null})}},op=ee(c(c(c(c(c(c({},fc),kf),Bf),Qt(Oh,["disabled"])),Qt(Tf,["autofocus"])),{},{buttonOnly:hs(ho,!1),buttonVariant:hs(go,"secondary"),formattedValue:hs(go),labelSelected:hs(go),lang:hs(go),menuClass:hs(To),placeholder:hs(go),readonly:hs(ho,!1),rtl:hs(ho,null),value:hs(go,"")})),rp=i.default.extend({name:"BVFormBtnLabelControl",directives:{"b-hover":np},mixins:[pc,$f,_f,Vh,Cs],props:op,data:function(){return{isHovered:!1,hasFocus:!1}},computed:{idButton:function(){return this.safeId()},idLabel:function(){return this.safeId("_value_")},idMenu:function(){return this.safeId("_dialog_")},idWrapper:function(){return this.safeId("_outer_")},computedDir:function(){return!0===this.rtl?"rtl":!1===this.rtl?"ltr":null}},methods:{focus:function(){this.disabled||ts(this.$refs.toggle)},blur:function(){this.disabled||es(this.$refs.toggle)},setFocus:function(t){this.hasFocus="focus"===t.type},handleHover:function(t){this.isHovered=t}},render:function(t){var e,i=this.idButton,n=this.idLabel,o=this.idMenu,r=this.idWrapper,s=this.disabled,l=this.readonly,c=this.required,u=this.name,d=this.state,h=this.visible,f=this.size,p=this.isHovered,m=this.hasFocus,v=this.labelSelected,b=this.buttonVariant,g=this.buttonOnly,y=vr(this.value)||"",w=!1===d||c&&!y,T={isHovered:p,hasFocus:m,state:d,opened:h},C=t("button",{staticClass:"btn",class:(e={},a(e,"btn-".concat(b),g),a(e,"btn-".concat(f),f),a(e,"h-auto",!g),a(e,"dropdown-toggle",g),a(e,"dropdown-toggle-no-caret",g),e),attrs:{id:i,type:"button",disabled:s,"aria-haspopup":"dialog","aria-expanded":h?"true":"false","aria-invalid":w?"true":null,"aria-required":c?"true":null},directives:[{name:"b-hover",value:this.handleHover}],on:{mousedown:this.onMousedown,click:this.toggle,keydown:this.toggle,"!focus":this.setFocus,"!blur":this.setFocus},ref:"toggle"},[this.hasNormalizedSlot(Eo)?this.normalizeSlot(Eo,T):t(Ta,{props:{scale:1.25}})]),x=t();u&&!s&&(x=t("input",{attrs:{type:"hidden",name:u||null,form:this.form||null,value:y}}));var S=t("div",{staticClass:"dropdown-menu",class:[this.menuClass,{show:h,"dropdown-menu-right":this.right}],attrs:{id:o,role:"dialog",tabindex:"-1","aria-modal":"false","aria-labelledby":n},on:{keydown:this.onKeydown},ref:"menu"},[this.normalizeSlot(Ao,{opened:h})]),k=t("label",{class:g?"sr-only":["form-control",{"text-muted":!y},this.stateClass,this.sizeFormClass],attrs:{id:n,for:i,"aria-invalid":w?"true":null,"aria-required":c?"true":null},directives:[{name:"b-hover",value:this.handleHover}],on:{"!click":function(t){Bs(t,{preventDefault:!1})}}},[y?this.formattedValue||y:this.placeholder||"",y&&v?t("bdi",{staticClass:"sr-only"},v):""]);return t("div",{staticClass:"b-form-btn-label-control dropdown",class:[this.directionClass,this.boundaryClass,[{"btn-group":g,"form-control":!g,focus:m&&!g,show:h,"is-valid":!0===d,"is-invalid":!1===d},g?null:this.sizeFormClass]],attrs:{id:r,role:g?null:"group",lang:this.lang||null,dir:this.computedDir,"aria-disabled":s,"aria-readonly":l&&!s,"aria-labelledby":n,"aria-invalid":!1===d||c&&!y?"true":null,"aria-required":c?"true":null}},[C,x,S,k])}}),sp=ys("value",{type:$o}),ap=sp.mixin,lp=sp.props,cp=sp.prop,up=sp.event,dp=Qt(wc,["block","hidden","id","noKeyNav","roleDescription","value","width"]),hp=Qt(op,["formattedValue","id","lang","rtl","value"]),fp=vs(ee(c(c(c(c(c({},fc),lp),dp),hp),{},{calendarWidth:hs(go,"270px"),closeButton:hs(ho,!1),closeButtonVariant:hs(go,"outline-secondary"),dark:hs(ho,!1),labelCloseButton:hs(go,"Close"),labelResetButton:hs(go,"Reset"),labelTodayButton:hs(go,"Select today"),noCloseOnSelect:hs(ho,!1),resetButton:hs(ho,!1),resetButtonVariant:hs(go,"outline-danger"),resetValue:hs($o),todayButton:hs(ho,!1),todayButtonVariant:hs(go,"outline-primary")})),li),pp=i.default.extend({name:li,mixins:[pc,ap],props:fp,data:function(){return{localYMD:Jl(this[cp])||"",isVisible:!1,localLocale:null,isRTL:!1,formattedValue:"",activeYMD:""}},computed:{calendarYM:function(){return this.activeYMD.slice(0,-3)},computedLang:function(){return(this.localLocale||"").replace(/-u-.*$/i,"")||null},computedResetValue:function(){return Jl(uc(this.resetValue))||""}},watch:(Th={},a(Th,cp,(function(t){this.localYMD=Jl(t)||""})),a(Th,"localYMD",(function(t){this.isVisible&&this.$emit(up,this.valueAsDate?Zl(t)||null:t||"")})),a(Th,"calendarYM",(function(t,e){if(t!==e&&e)try{this.$refs.control.updatePopper()}catch(t){}})),Th),methods:{focus:function(){this.disabled||ts(this.$refs.control)},blur:function(){this.disabled||es(this.$refs.control)},setAndClose:function(t){var e=this;this.localYMD=t,this.noCloseOnSelect||this.$nextTick((function(){e.$refs.control.hide(!0)}))},onSelected:function(t){var e=this;this.$nextTick((function(){e.setAndClose(t)}))},onInput:function(t){this.localYMD!==t&&(this.localYMD=t)},onContext:function(t){var e=t.activeYMD,i=t.isRTL,n=t.locale,o=t.selectedYMD,r=t.selectedFormatted;this.isRTL=i,this.localLocale=n,this.formattedValue=r,this.localYMD=o,this.activeYMD=e,this.$emit(Dn,t)},onTodayButton:function(){this.setAndClose(Jl(uc(Xl(),this.min,this.max)))},onResetButton:function(){this.setAndClose(this.computedResetValue)},onCloseButton:function(){this.$refs.control.hide(!0)},onShow:function(){this.isVisible=!0},onShown:function(){var t=this;this.$nextTick((function(){ts(t.$refs.calendar),t.$emit(eo)}))},onHidden:function(){this.isVisible=!1,this.$emit(zn)},defaultButtonFn:function(t){var e=t.isHovered,i=t.hasFocus;return this.$createElement(e||i?ga:ba,{attrs:{"aria-hidden":"true"}})}},render:function(t){var e=this.localYMD,i=this.disabled,n=this.readonly,o=this.dark,r=this.$props,s=this.$scopedSlots,l=Pt(this.placeholder)?this.labelNoDateSelected:this.placeholder,u=[];if(this.todayButton){var d=this.labelTodayButton;u.push(t(ml,{props:{disabled:i||n,size:"sm",variant:this.todayButtonVariant},attrs:{"aria-label":d||null},on:{click:this.onTodayButton}},d))}if(this.resetButton){var h=this.labelResetButton;u.push(t(ml,{props:{disabled:i||n,size:"sm",variant:this.resetButtonVariant},attrs:{"aria-label":h||null},on:{click:this.onResetButton}},h))}if(this.closeButton){var f=this.labelCloseButton;u.push(t(ml,{props:{disabled:i,size:"sm",variant:this.closeButtonVariant},attrs:{"aria-label":f||null},on:{click:this.onCloseButton}},f))}u.length>0&&(u=[t("div",{staticClass:"b-form-date-controls d-flex flex-wrap",class:{"justify-content-between":u.length>1,"justify-content-end":u.length<2}},u)]);var p=t(Tc,{staticClass:"b-form-date-calendar w-100",props:c(c({},ps(dp,r)),{},{hidden:!this.isVisible,value:e,valueAsDate:!1,width:this.calendarWidth}),on:{selected:this.onSelected,input:this.onInput,context:this.onContext},scopedSlots:Jt(s,["nav-prev-decade","nav-prev-year","nav-prev-month","nav-this-month","nav-next-month","nav-next-year","nav-next-decade"]),key:"calendar",ref:"calendar"},u);return t(rp,{staticClass:"b-form-datepicker",props:c(c({},ps(hp,r)),{},{formattedValue:e?this.formattedValue:"",id:this.safeId(),lang:this.computedLang,menuClass:[{"bg-dark":o,"text-light":o},this.menuClass],placeholder:l,rtl:this.isRTL,value:e}),on:{show:this.onShow,shown:this.onShown,hidden:this.onHidden},scopedSlots:a({},Eo,s["button-content"]||this.defaultButtonFn),ref:"control"},[p])}}),mp=me({components:{BFormDatepicker:pp,BDatepicker:pp}}),vp=ys("value",{type:[uo,_t],defaultValue:null,validator:function(t){return""===t?(le(Tp,ci),!0):Pt(t)||Cp(t)}}),bp=vp.mixin,gp=vp.props,yp=vp.prop,wp=vp.event,Tp='Setting "value"/"v-model" to an empty string for reset is deprecated. Set to "null" instead.',Cp=function t(e){return function(t){return t instanceof _t}(e)||Rt(e)&&e.every((function(e){return t(e)}))},xp=function(t){return Ot(t.getAsEntry)?t.getAsEntry():Ot(t.webkitGetAsEntry)?t.webkitGetAsEntry():null},Sp=function t(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return new Promise((function(n){var o=[];!function r(){e.readEntries((function(e){0===e.length?n(Promise.all(o).then((function(t){return sr(t)}))):(o.push(Promise.all(e.map((function(e){if(e){if(e.isDirectory)return t(e.createReader(),"".concat(i).concat(e.name,"/"));if(e.isFile)return new Promise((function(t){e.file((function(e){e.$path="".concat(i).concat(e.name),t(e)}))}))}return null})).filter(ne))),r())}))}()}))},kp=vs(ee(c(c(c(c(c(c(c({},fc),gp),Tf),xf),Bf),kf),{},{accept:hs(go,""),browseText:hs(go,"Browse"),capture:hs(ho,!1),directory:hs(ho,!1),dropPlaceholder:hs(go,"Drop files here"),fileNameFormatter:hs(po),multiple:hs(ho,!1),noDrop:hs(ho,!1),noDropPlaceholder:hs(go,"Not allowed"),noTraverse:hs(ho,!1),placeholder:hs(go,"No file chosen")})),ci),$p=i.default.extend({name:ci,mixins:[Za,pc,bp,Cs,Cf,_f,Sf,Cs],inheritAttrs:!1,props:kp,data:function(){return{files:[],dragging:!1,dropAllowed:!this.noDrop,hasFocus:!1}},computed:{computedAccept:function(){var t=this.accept;return 0===(t=(t||"").trim().split(/[,\s]+/).filter(ne)).length?null:t.map((function(t){var e="name",i="^",n="$";return tt.test(t)?i="":(e="type",dt.test(t)&&(n=".+$",t=t.slice(0,-1))),t=mr(t),{rx:new RegExp("".concat(i).concat(t).concat(n)),prop:e}}))},computedCapture:function(){var t=this.capture;return!0===t||""===t||(t||null)},computedAttrs:function(){var t=this.name,e=this.disabled,i=this.required,n=this.form,o=this.computedCapture,r=this.accept,s=this.multiple,a=this.directory;return c(c({},this.bvAttrs),{},{type:"file",id:this.safeId(),name:t,disabled:e,required:i,form:n||null,capture:o,accept:r||null,multiple:s,directory:a,webkitdirectory:a,"aria-required":i?"true":null})},computedFileNameFormatter:function(){var t=this.fileNameFormatter;return gs(t)?t:this.defaultFileNameFormatter},clonedFiles:function(){return ie(this.files)},flattenedFiles:function(){return ar(this.files)},fileNames:function(){return this.flattenedFiles.map((function(t){return t.name}))},labelContent:function(){if(this.dragging&&!this.noDrop)return this.normalizeSlot("drop-placeholder",{allowed:this.dropAllowed})||(this.dropAllowed?this.dropPlaceholder:this.$createElement("span",{staticClass:"text-danger"},this.noDropPlaceholder));if(0===this.files.length)return this.normalizeSlot("placeholder")||this.placeholder;var t=this.flattenedFiles,e=this.clonedFiles,i=this.fileNames,n=this.computedFileNameFormatter;return this.hasNormalizedSlot(Mo)?this.normalizeSlot(Mo,{files:t,filesTraversed:e,names:i}):n(t,e,i)}},watch:(Ch={},a(Ch,yp,(function(t){(!t||Rt(t)&&0===t.length)&&this.reset()})),a(Ch,"files",(function(t,e){if(!Ua(t,e)){var i=this.multiple,n=this.noTraverse,o=!i||n?ar(t):t;this.$emit(wp,i?o:o[0]||null)}})),Ch),created:function(){this.$_form=null},mounted:function(){var t=Er("form",this.$el);t&&(Ss(t,"reset",this.reset,ao),this.$_form=t)},beforeDestroy:function(){var t=this.$_form;t&&ks(t,"reset",this.reset,ao)},methods:{isFileValid:function(t){if(!t)return!1;var e=this.computedAccept;return!e||e.some((function(e){return e.rx.test(t[e.prop])}))},isFilesArrayValid:function(t){var e=this;return Rt(t)?t.every((function(t){return e.isFileValid(t)})):this.isFileValid(t)},defaultFileNameFormatter:function(t,e,i){return i.join(", ")},setFiles:function(t){this.dropAllowed=!this.noDrop,this.dragging=!1,this.files=this.multiple?this.directory?t:ar(t):ar(t).slice(0,1)},setInputFiles:function(t){try{var e=new ClipboardEvent("").clipboardData||new DataTransfer;ar(ie(t)).forEach((function(t){delete t.$path,e.items.add(t)})),this.$refs.input.files=e.files}catch(t){}},reset:function(){try{var t=this.$refs.input;t.value="",t.type="",t.type="file"}catch(t){}this.files=[]},handleFiles:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(e){var i=t.filter(this.isFilesArrayValid);i.length>0&&(this.setFiles(i),this.setInputFiles(i))}else this.setFiles(t)},focusHandler:function(t){this.plain||"focusout"===t.type?this.hasFocus=!1:this.hasFocus=!0},onChange:function(t){var e=this,i=t.type,n=t.target,o=t.dataTransfer,r=void 0===o?{}:o,s="drop"===i;this.$emit($n,t);var a=ir(r.items||[]);if(A&&a.length>0&&!It(xp(a[0])))(function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return Promise.all(ir(t).filter((function(t){return"file"===t.kind})).map((function(t){var i=xp(t);if(i){if(i.isDirectory&&e)return Sp(i.createReader(),"".concat(i.name,"/"));if(i.isFile)return new Promise((function(t){i.file((function(e){e.$path="",t(e)}))}))}return null})).filter(ne))})(a,this.directory).then((function(t){return e.handleFiles(t,s)}));else{var l=ir(n.files||r.files||[]).map((function(t){return t.$path=t.webkitRelativePath||"",t}));this.handleFiles(l,s)}},onDragenter:function(t){Bs(t),this.dragging=!0;var e=t.dataTransfer,i=void 0===e?{}:e;if(this.noDrop||this.disabled||!this.dropAllowed)return i.dropEffect="none",void(this.dropAllowed=!1);i.dropEffect="copy"},onDragover:function(t){Bs(t),this.dragging=!0;var e=t.dataTransfer,i=void 0===e?{}:e;if(this.noDrop||this.disabled||!this.dropAllowed)return i.dropEffect="none",void(this.dropAllowed=!1);i.dropEffect="copy"},onDragleave:function(t){var e=this;Bs(t),this.$nextTick((function(){e.dragging=!1,e.dropAllowed=!e.noDrop}))},onDrop:function(t){var e=this;Bs(t),this.dragging=!1,this.noDrop||this.disabled||!this.dropAllowed?this.$nextTick((function(){e.dropAllowed=!e.noDrop})):this.onChange(t)}},render:function(t){var e=this.custom,i=this.plain,n=this.size,o=this.dragging,r=this.stateClass,s=this.bvAttrs,l=t("input",{class:[{"form-control-file":i,"custom-file-input":e,focus:e&&this.hasFocus},r],style:e?{zIndex:-5}:{},attrs:this.computedAttrs,on:{change:this.onChange,focusin:this.focusHandler,focusout:this.focusHandler,reset:this.reset},ref:"input"});if(i)return l;var c=t("label",{staticClass:"custom-file-label",class:{dragging:o},attrs:{for:this.safeId(),"data-browse":this.browseText||null}},[t("span",{staticClass:"d-block form-file-text",style:{pointerEvents:"none"}},[this.labelContent])]);return t("div",{staticClass:"custom-file b-form-file",class:[a({},"b-custom-control-".concat(n),n),r,s.class],style:s.style,attrs:{id:this.safeId("_BV_file_outer_")},on:{dragenter:this.onDragenter,dragover:this.onDragover,dragleave:this.onDragleave,drop:this.onDrop}},[l,c])}}),Bp=me({components:{BFormFile:$p,BFile:$p}}),_p=function(t){return"\\"+t},Dp=function(t){var e=(t=vr(t)).length,i=t.charCodeAt(0);return t.split("").reduce((function(n,o,r){var s=t.charCodeAt(r);return 0===s?n+"īŋŊ":127===s||s>=1&&s<=31||0===r&&s>=48&&s<=57||1===r&&s>=48&&s<=57&&45===i?n+_p("".concat(s.toString(16)," ")):0===r&&45===s&&1===e?n+_p(o):s>=128||45===s||95===s||s>=48&&s<=57||s>=65&&s<=90||s>=97&&s<=122?n+o:n+_p(o)}),"")},Fp=["auto","start","end","center","baseline","stretch"],Ip=is((function(t,e,i){var n=t;if(!Pt(i)&&!1!==i)return e&&(n+="-".concat(e)),"col"!==t||""!==i&&!0!==i?(n+="-".concat(i),gr(n)):gr(n)})),Pp=Wt(null),Op={name:Ye,functional:!0,get props(){return delete this.props,this.props=(t=ls().filter(ne),e=t.reduce((function(t,e){return t[e]=hs(So),t}),Wt(null)),i=t.reduce((function(t,e){return t[ds(e,"offset")]=hs(_o),t}),Wt(null)),n=t.reduce((function(t,e){return t[ds(e,"order")]=hs(_o),t}),Wt(null)),Pp=Gt(Wt(null),{col:Kt(e),offset:Kt(i),order:Kt(n)}),vs(ee(c(c(c(c({},e),i),n),{},{alignSelf:hs(go,null,(function(t){return nr(Fp,t)})),col:hs(ho,!1),cols:hs(_o),offset:hs(_o),order:hs(_o),tag:hs(go,"div")})),Ye));var t,e,i,n},render:function(t,e){var i,n=e.props,o=e.data,r=e.children,s=n.cols,l=n.offset,c=n.order,u=n.alignSelf,d=[];for(var h in Pp)for(var f=Pp[h],p=0;p<f.length;p++){var m=Ip(h,f[p].replace(h,""),n[f[p]]);m&&d.push(m)}var v=d.some((function(t){return kt.test(t)}));return d.push((a(i={col:n.col||!v&&!s},"col-".concat(s),s),a(i,"offset-".concat(l),l),a(i,"order-".concat(c),c),a(i,"align-self-".concat(u),u),i)),t(n.tag,F(o,{class:d}),r)}},Vp=["input","select","textarea"],Ep=Vp.map((function(t){return"".concat(t,":not([disabled])")})).join(),Lp=[].concat(Vp,["a","button","label"]),Ap={name:ui,mixins:[pc,_f,Cs],get props(){return delete this.props,this.props=vs(ee(c(c(c(c({},fc),Bf),ls().reduce((function(t,e){return t[ds(e,"contentCols")]=hs(So),t[ds(e,"labelAlign")]=hs(go),t[ds(e,"labelCols")]=hs(So),t}),Wt(null))),{},{description:hs(go),disabled:hs(ho,!1),feedbackAriaLive:hs(go,"assertive"),invalidFeedback:hs(go),label:hs(go),labelClass:hs(To),labelFor:hs(go),labelSize:hs(go),labelSrOnly:hs(ho,!1),tooltip:hs(ho,!1),validFeedback:hs(go),validated:hs(ho,!1)})),ui)},data:function(){return{ariaDescribedby:null}},computed:{contentColProps:function(){return this.getColProps(this.$props,"content")},labelAlignClasses:function(){return this.getAlignClasses(this.$props,"label")},labelColProps:function(){return this.getColProps(this.$props,"label")},isHorizontal:function(){return Kt(this.contentColProps).length>0||Kt(this.labelColProps).length>0}},watch:{ariaDescribedby:function(t,e){t!==e&&this.updateAriaDescribedby(t,e)}},mounted:function(){var t=this;this.$nextTick((function(){t.updateAriaDescribedby(t.ariaDescribedby)}))},methods:{getAlignClasses:function(t,e){return ls().reduce((function(i,n){var o=t[ds(n,"".concat(e,"Align"))]||null;return o&&i.push(["text",n,o].filter(ne).join("-")),i}),[])},getColProps:function(t,e){return ls().reduce((function(i,n){var o=t[ds(n,"".concat(e,"Cols"))];return Vt(o=""===o||(o||!1))||"auto"===o||(o=(o=lr(o,0))>0&&o),o&&(i[n||(Vt(o)?"col":"cols")]=o),i}),{})},updateAriaDescribedby:function(t,e){var i=this.labelFor;if(M&&i){var n=Or("#".concat(Dp(i)),this.$refs.content);if(n){var o="aria-describedby",r=(t||"").split(ut),s=(e||"").split(ut),a=(jr(n,o)||"").split(ut).filter((function(t){return!nr(s,t)})).concat(r).filter((function(t,e,i){return i.indexOf(t)===e})).filter(ne).join(" ").trim();a?zr(n,o,a):Nr(n,o)}}},onLegendClick:function(t){if(!this.labelFor){var e=t.target,i=e?e.tagName:"";if(-1===Lp.indexOf(i)){var n=Pr(Ep,this.$refs.content).filter(Dr);1===n.length&&ts(n[0])}}}},render:function(t){var e=this.computedState,i=this.feedbackAriaLive,n=this.isHorizontal,o=this.labelFor,r=this.normalizeSlot,s=this.safeId,a=this.tooltip,l=s(),u=!o,d=t(),h=r(jo)||this.label,f=h?s("_BV_label_"):null;if(h||n){var p=this.labelSize,m=this.labelColProps,v=u?"legend":"label";this.labelSrOnly?(h&&(d=t(v,{class:"sr-only",attrs:{id:f,for:o||null}},[h])),d=t(n?Op:"div",{props:n?m:{}},[d])):d=t(n?Op:v,{on:u?{click:this.onLegendClick}:{},props:n?c(c({},m),{},{tag:v}):{},attrs:{id:f,for:o||null,tabindex:u?"-1":null},class:[u?"bv-no-focus-ring":"",n||u?"col-form-label":"",!n&&u?"pt-0":"",n||u?"":"d-block",p?"col-form-label-".concat(p):"",this.labelAlignClasses,this.labelClass]},[h])}var b=t(),g=r("invalid-feedback")||this.invalidFeedback,y=g?s("_BV_feedback_invalid_"):null;g&&(b=t(ff,{props:{ariaLive:i,id:y,role:i?"alert":null,state:e,tooltip:a},attrs:{tabindex:g?"-1":null}},[g]));var w=t(),T=r("valid-feedback")||this.validFeedback,C=T?s("_BV_feedback_valid_"):null;T&&(w=t(mf,{props:{ariaLive:i,id:C,role:i?"alert":null,state:e,tooltip:a},attrs:{tabindex:T?"-1":null}},[T]));var x=t(),S=r("description")||this.description,k=S?s("_BV_description_"):null;S&&(x=t(df,{attrs:{id:k,tabindex:"-1"}},[S]));var $=this.ariaDescribedby=[k,!1===e?y:null,!0===e?C:null].filter(ne).join(" ")||null,B=t(n?Op:"div",{props:n?this.contentColProps:{},ref:"content"},[r(Ao,{ariaDescribedby:$,descriptionId:k,id:l,labelId:f})||t(),b,w,x]);return t(u?"fieldset":n?bf:"div",{staticClass:"form-group",class:[{"was-validated":this.validated},this.stateClass],attrs:{id:l,disabled:u?this.disabled:null,role:u?null:"group","aria-invalid":this.computedAriaInvalid,"aria-labelledby":u&&n?f:null}},n&&u?[t(bf,[d,B])]:[d,B])}},Rp=me({components:{BFormGroup:Ap,BFormFieldset:Ap}}),Mp=i.default.extend({computed:{selectionStart:{cache:!1,get:function(){return this.$refs.input.selectionStart},set:function(t){this.$refs.input.selectionStart=t}},selectionEnd:{cache:!1,get:function(){return this.$refs.input.selectionEnd},set:function(t){this.$refs.input.selectionEnd=t}},selectionDirection:{cache:!1,get:function(){return this.$refs.input.selectionDirection},set:function(t){this.$refs.input.selectionDirection=t}}},methods:{select:function(){var t;(t=this.$refs.input).select.apply(t,arguments)},setSelectionRange:function(){var t;(t=this.$refs.input).setSelectionRange.apply(t,arguments)},setRangeText:function(){var t;(t=this.$refs.input).setRangeText.apply(t,arguments)}}}),Hp=ys("value",{type:_o,defaultValue:"",event:"update"}),zp=Hp.mixin,Np=Hp.props,jp=Hp.prop,Gp=Hp.event,Wp=vs(ee(c(c({},Np),{},{ariaInvalid:hs(ko,!1),autocomplete:hs(go),debounce:hs(_o,0),formatter:hs(po),lazy:hs(ho,!1),lazyFormatter:hs(ho,!1),number:hs(ho,!1),placeholder:hs(go),plaintext:hs(ho,!1),readonly:hs(ho,!1),trim:hs(ho,!1)})),"formTextControls"),Yp=i.default.extend({mixins:[zp],props:Wp,data:function(){var t=this[jp];return{localValue:vr(t),vModelValue:this.modifyValue(t)}},computed:{computedClass:function(){var t=this.plaintext,e=this.type,i="range"===e,n="color"===e;return[{"custom-range":i,"form-control-plaintext":t&&!i&&!n,"form-control":n||!t&&!i},this.sizeFormClass,this.stateClass]},computedDebounce:function(){return Us(lr(this.debounce,0),0)},hasFormatter:function(){return gs(this.formatter)}},watch:a({},jp,(function(t){var e=vr(t),i=this.modifyValue(t);e===this.localValue&&i===this.vModelValue||(this.clearDebounce(),this.localValue=e,this.vModelValue=i)})),created:function(){this.$_inputDebounceTimer=null},mounted:function(){this.$on(oo,this.clearDebounce)},beforeDestroy:function(){this.clearDebounce()},methods:{clearDebounce:function(){clearTimeout(this.$_inputDebounceTimer),this.$_inputDebounceTimer=null},formatValue:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return t=vr(t),!this.hasFormatter||this.lazyFormatter&&!i||(t=this.formatter(t,e)),t},modifyValue:function(t){return t=vr(t),this.trim&&(t=t.trim()),this.number&&(t=cr(t,t)),t},updateValue:function(t){var e=this,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=this.lazy;if(!n||i){this.clearDebounce();var o=function(){if((t=e.modifyValue(t))!==e.vModelValue)e.vModelValue=t,e.$emit(Gp,t);else if(e.hasFormatter){var i=e.$refs.input;i&&t!==i.value&&(i.value=t)}},r=this.computedDebounce;r>0&&!n&&!i?this.$_inputDebounceTimer=setTimeout(o,r):o()}},onInput:function(t){if(!t.target.composing){var e=t.target.value,i=this.formatValue(e,t);!1===i||t.defaultPrevented?Bs(t,{propagation:!1}):(this.localValue=i,this.updateValue(i),this.$emit(jn,i))}},onChange:function(t){var e=t.target.value,i=this.formatValue(e,t);!1===i||t.defaultPrevented?Bs(t,{propagation:!1}):(this.localValue=i,this.updateValue(i,!0),this.$emit($n,i))},onBlur:function(t){var e=t.target.value,i=this.formatValue(e,t,!0);!1!==i&&(this.localValue=vr(this.modifyValue(i)),this.updateValue(i,!0)),this.$emit("blur",t)},focus:function(){this.disabled||ts(this.$el)},blur:function(){this.disabled||es(this.$el)}}}),Up=i.default.extend({computed:{validity:{cache:!1,get:function(){return this.$refs.input.validity}},validationMessage:{cache:!1,get:function(){return this.$refs.input.validationMessage}},willValidate:{cache:!1,get:function(){return this.$refs.input.willValidate}}},methods:{setCustomValidity:function(){var t;return(t=this.$refs.input).setCustomValidity.apply(t,arguments)},checkValidity:function(){var t;return(t=this.$refs.input).checkValidity.apply(t,arguments)},reportValidity:function(){var t;return(t=this.$refs.input).reportValidity.apply(t,arguments)}}}),qp=["text","password","email","number","url","tel","search","range","color","date","time","datetime","datetime-local","month","week"],Kp=vs(ee(c(c(c(c(c(c({},fc),Tf),kf),Bf),Wp),{},{list:hs(go),max:hs(_o),min:hs(_o),noWheel:hs(ho,!1),step:hs(_o),type:hs(go,"text",(function(t){return nr(qp,t)}))})),di),Xp=i.default.extend({name:di,mixins:[Qa,pc,Cf,$f,_f,Yp,Mp,Up],props:Kp,computed:{localType:function(){var t=this.type;return nr(qp,t)?t:"text"},computedAttrs:function(){var t=this.localType,e=this.name,i=this.form,n=this.disabled,o=this.placeholder,r=this.required,s=this.min,a=this.max,l=this.step;return{id:this.safeId(),name:e,form:i,type:t,disabled:n,placeholder:o,required:r,autocomplete:this.autocomplete||null,readonly:this.readonly||this.plaintext,min:s,max:a,step:l,list:"password"!==t?this.list:null,"aria-required":r?"true":null,"aria-invalid":this.computedAriaInvalid}},computedListeners:function(){return c(c({},this.bvListeners),{},{input:this.onInput,change:this.onChange,blur:this.onBlur})}},watch:{noWheel:function(t){this.setWheelStopper(t)}},mounted:function(){this.setWheelStopper(this.noWheel)},deactivated:function(){this.setWheelStopper(!1)},activated:function(){this.setWheelStopper(this.noWheel)},beforeDestroy:function(){this.setWheelStopper(!1)},methods:{setWheelStopper:function(t){var e=this.$el;$s(t,e,"focus",this.onWheelFocus),$s(t,e,"blur",this.onWheelBlur),t||ks(document,"wheel",this.stopWheel)},onWheelFocus:function(){Ss(document,"wheel",this.stopWheel)},onWheelBlur:function(){ks(document,"wheel",this.stopWheel)},stopWheel:function(t){Bs(t,{propagation:!1}),es(this.$el)}},render:function(t){return t("input",{class:this.computedClass,attrs:this.computedAttrs,domProps:{value:this.localValue},on:this.computedListeners,ref:"input"})}}),Zp=me({components:{BFormInput:Xp,BInput:Xp}}),Jp=vs(qf,pi),Qp=i.default.extend({name:pi,mixins:[Kf],provide:function(){return{bvRadioGroup:this}},props:Jp,computed:{isRadioGroup:function(){return!0}}}),tm=me({components:{BFormRadio:zf,BRadio:zf,BFormRadioGroup:Qp,BRadioGroup:Qp}}),em=ys("value",{type:_o,event:$n}),im=em.mixin,nm=em.props,om=em.prop,rm=em.event,sm=function(t){return Us(3,lr(t,5))},am=function(t,e,i){return Us(Ys(t,i),e)},lm=i.default.extend({name:"BVFormRatingStar",mixins:[Cs],props:{disabled:hs(ho,!1),focused:hs(ho,!1),hasClear:hs(ho,!1),rating:hs(mo,0),readonly:hs(ho,!1),star:hs(mo,0),variant:hs(go)},methods:{onClick:function(t){this.disabled||this.readonly||(Bs(t,{propagation:!1}),this.$emit(Qn,this.star))}},render:function(t){var e=this.rating,i=this.star,n=this.focused,o=this.hasClear,r=this.variant,s=this.disabled,a=this.readonly,l=o?0:1,c=e>=i?"full":e>=i-.5?"half":"empty",u={variant:r,disabled:s,readonly:a};return t("span",{staticClass:"b-rating-star",class:{focused:n&&e===i||!lr(e)&&i===l,"b-rating-star-empty":"empty"===c,"b-rating-star-half":"half"===c,"b-rating-star-full":"full"===c},attrs:{tabindex:s||a?null:"-1"},on:{click:this.onClick}},[t("span",{staticClass:"b-rating-icon"},[this.normalizeSlot(c,u)])])}}),cm=vs(ee(c(c(c(c(c({},fc),nm),Qt(Tf,["required","autofocus"])),kf),{},{color:hs(go),iconClear:hs(go,"x"),iconEmpty:hs(go,"star"),iconFull:hs(go,"star-fill"),iconHalf:hs(go,"star-half"),inline:hs(ho,!1),locale:hs(Co),noBorder:hs(ho,!1),precision:hs(_o),readonly:hs(ho,!1),showClear:hs(ho,!1),showValue:hs(ho,!1),showValueMax:hs(ho,!1),stars:hs(_o,5,(function(t){return lr(t)>=3})),variant:hs(go)})),mi),um=i.default.extend({name:mi,components:{BIconStar:Fa,BIconStarHalf:Pa,BIconStarFill:Ia,BIconX:Oa},mixins:[pc,im,$f],props:cm,data:function(){var t=cr(this[om],null),e=sm(this.stars);return{localValue:It(t)?null:am(t,0,e),hasFocus:!1}},computed:{computedStars:function(){return sm(this.stars)},computedRating:function(){var t=cr(this.localValue,0),e=lr(this.precision,3);return am(cr(t.toFixed(e)),0,this.computedStars)},computedLocale:function(){var t=or(this.locale).filter(ne);return new Intl.NumberFormat(t).resolvedOptions().locale},isInteractive:function(){return!this.disabled&&!this.readonly},isRTL:function(){return hc(this.computedLocale)},formattedRating:function(){var t=lr(this.precision),e=this.showValueMax,i=this.computedLocale,n={notation:"standard",minimumFractionDigits:isNaN(t)?0:t,maximumFractionDigits:isNaN(t)?3:t},o=this.computedStars.toLocaleString(i),r=this.localValue;return r=It(r)?e?"-":"":r.toLocaleString(i,n),e?"".concat(r,"/").concat(o):r}},watch:(xh={},a(xh,om,(function(t,e){if(t!==e){var i=cr(t,null);this.localValue=It(i)?null:am(i,0,this.computedStars)}})),a(xh,"localValue",(function(t,e){t!==e&&t!==(this.value||0)&&this.$emit(rm,t||null)})),a(xh,"disabled",(function(t){t&&(this.hasFocus=!1,this.blur())})),xh),methods:{focus:function(){this.disabled||ts(this.$el)},blur:function(){this.disabled||es(this.$el)},onKeydown:function(t){var e=t.keyCode;if(this.isInteractive&&nr([Na,Ra,ja,Wa],e)){Bs(t,{propagation:!1});var i=lr(this.localValue,0),n=this.showClear?0:1,o=this.computedStars,r=this.isRTL?-1:1;e===Na?this.localValue=am(i-r,n,o)||null:e===ja?this.localValue=am(i+r,n,o):e===Ra?this.localValue=am(i-1,n,o)||null:e===Wa&&(this.localValue=am(i+1,n,o))}},onSelected:function(t){this.isInteractive&&(this.localValue=t)},onFocus:function(t){this.hasFocus=!!this.isInteractive&&"focus"===t.type},renderIcon:function(t){return this.$createElement(Aa,{props:{icon:t,variant:this.disabled||this.color?null:this.variant||null}})},iconEmptyFn:function(){return this.renderIcon(this.iconEmpty)},iconHalfFn:function(){return this.renderIcon(this.iconHalf)},iconFullFn:function(){return this.renderIcon(this.iconFull)},iconClearFn:function(){return this.$createElement(Aa,{props:{icon:this.iconClear}})}},render:function(t){var e=this,i=this.disabled,n=this.readonly,o=this.name,r=this.form,s=this.inline,a=this.variant,l=this.color,c=this.noBorder,u=this.hasFocus,d=this.computedRating,h=this.computedStars,f=this.formattedRating,p=this.showClear,m=this.isRTL,v=this.isInteractive,b=this.$scopedSlots,g=[];if(p&&!i&&!n){var y=t("span",{staticClass:"b-rating-icon"},[(b["icon-clear"]||this.iconClearFn)()]);g.push(t("span",{staticClass:"b-rating-star b-rating-star-clear flex-grow-1",class:{focused:u&&0===d},attrs:{tabindex:v?"-1":null},on:{click:function(){return e.onSelected(null)}},key:"clear"},[y]))}for(var w=0;w<h;w++){var T=w+1;g.push(t(lm,{staticClass:"flex-grow-1",style:l&&!i?{color:l}:{},props:{rating:d,star:T,variant:i?null:a||null,disabled:i,readonly:n,focused:u,hasClear:p},on:{selected:this.onSelected},scopedSlots:{empty:b["icon-empty"]||this.iconEmptyFn,half:b["icon-half"]||this.iconHalfFn,full:b["icon-full"]||this.iconFullFn},key:w}))}return o&&g.push(t("input",{attrs:{type:"hidden",value:It(this.localValue)?"":d,name:o,form:r||null},key:"hidden"})),this.showValue&&g.push(t("b",{staticClass:"b-rating-value flex-grow-1",attrs:{"aria-hidden":"true"},key:"value"},vr(f))),t("output",{staticClass:"b-rating form-control align-items-center",class:[{"d-inline-flex":s,"d-flex":!s,"border-0":c,disabled:i,readonly:!i&&n},this.sizeFormClass],attrs:{id:this.safeId(),dir:m?"rtl":"ltr",tabindex:i?null:"0",disabled:i,role:"slider","aria-disabled":i?"true":null,"aria-readonly":!i&&n?"true":null,"aria-live":"off","aria-valuemin":p?"0":"1","aria-valuemax":vr(h),"aria-valuenow":d?vr(d):null},on:{keydown:this.onKeydown,focus:this.onFocus,blur:this.onFocus}},g)}}),dm=me({components:{BFormRating:um,BRating:um}}),hm=ys("value"),fm=hm.mixin,pm=hm.props,mm=hm.prop,vm=hm.event,bm=vs(ee(c(c({},sf),{},{labelField:hs(go,"label"),optionsField:hs(go,"options")})),"formOptions"),gm=i.default.extend({mixins:[af],props:bm,methods:{normalizeOption:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(Ht(t)){var i=re(t,this.valueField),n=re(t,this.textField),o=re(t,this.optionsField,null);return It(o)?{value:Ft(i)?e||n:i,text:String(Ft(n)?e:n),html:re(t,this.htmlField),disabled:Boolean(re(t,this.disabledField))}:{label:String(re(t,this.labelField)||n),options:this.normalizeOptions(o)}}return{value:e||t,text:String(t),disabled:!1}}}}),ym=vs({disabled:hs(ho,!1),value:hs(co,void 0,!0)},gi),wm=i.default.extend({name:gi,functional:!0,props:ym,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.value;return t("option",F(n,{attrs:{disabled:i.disabled},domProps:{value:r}}),o)}}),Tm=vs(ee(c(c({},sf),{},{label:hs(go,void 0,!0)})),yi),Cm=i.default.extend({name:yi,mixins:[Cs,af],props:Tm,render:function(t){var e=this.label,i=this.formOptions.map((function(e,i){var n=e.value,o=e.text,r=e.html,s=e.disabled;return t(wm,{attrs:{value:n,disabled:s},domProps:Fl(r,o),key:"option_".concat(i)})}));return t("optgroup",{attrs:{label:e}},[this.normalizeSlot(Ho),i,this.normalizeSlot()])}}),xm=vs(ee(c(c(c(c(c(c(c({},fc),pm),Tf),xf),kf),Bf),{},{ariaInvalid:hs(ko,!1),multiple:hs(ho,!1),selectSize:hs(mo,0)})),bi),Sm=i.default.extend({name:bi,mixins:[pc,fm,Cf,$f,_f,Sf,gm,Cs],props:xm,data:function(){return{localValue:this[mm]}},computed:{computedSelectSize:function(){return this.plain||0!==this.selectSize?this.selectSize:null},inputClass:function(){return[this.plain?"form-control":"custom-select",this.size&&this.plain?"form-control-".concat(this.size):null,this.size&&!this.plain?"custom-select-".concat(this.size):null,this.stateClass]}},watch:{value:function(t){this.localValue=t},localValue:function(){this.$emit(vm,this.localValue)}},methods:{focus:function(){ts(this.$refs.input)},blur:function(){es(this.$refs.input)},onChange:function(t){var e=this,i=t.target,n=ir(i.options).filter((function(t){return t.selected})).map((function(t){return"_value"in t?t._value:t.value}));this.localValue=i.multiple?n:n[0],this.$nextTick((function(){e.$emit($n,e.localValue)}))}},render:function(t){var e=this.name,i=this.disabled,n=this.required,o=this.computedSelectSize,r=this.localValue,s=this.formOptions.map((function(e,i){var n=e.value,o=e.label,r=e.options,s=e.disabled,a="option_".concat(i);return Rt(r)?t(Cm,{props:{label:o,options:r},key:a}):t(wm,{props:{value:n,disabled:s},domProps:Fl(e.html,e.text),key:a})}));return t("select",{class:this.inputClass,attrs:{id:this.safeId(),name:e,form:this.form||null,multiple:this.multiple||null,size:o,disabled:i,required:n,"aria-required":n?"true":null,"aria-invalid":this.computedAriaInvalid},on:{change:this.onChange},directives:[{name:"model",value:r}],ref:"input"},[this.normalizeSlot(Ho),s,this.normalizeSlot()])}}),km=me({components:{BFormSelect:Sm,BFormSelectOption:wm,BFormSelectOptionGroup:Cm,BSelect:Sm,BSelectOption:wm,BSelectOptionGroup:Cm}}),$m=ys("value",{type:xo}),Bm=$m.mixin,_m=$m.props,Dm=$m.prop,Fm=$m.event,Im=[Wa,Ra,za,Ma,33,34],Pm=vs(ee(c(c(c(c(c(c({},fc),_m),Qt(Tf,["required","autofocus"])),kf),Bf),{},{ariaControls:hs(go),ariaLabel:hs(go),formatterFn:hs(po),inline:hs(ho,!1),labelDecrement:hs(go,"Decrement"),labelIncrement:hs(go,"Increment"),locale:hs(Co),max:hs(_o,100),min:hs(_o,1),placeholder:hs(go),readonly:hs(ho,!1),repeatDelay:hs(_o,500),repeatInterval:hs(_o,100),repeatStepMultiplier:hs(_o,4),repeatThreshold:hs(_o,10),step:hs(_o,1),vertical:hs(ho,!1),wrap:hs(ho,!1)})),wi),Om=i.default.extend({name:wi,mixins:[Za,pc,Bm,$f,_f,Cs],inheritAttrs:!1,props:Pm,data:function(){return{localValue:cr(this[Dm],null),hasFocus:!1}},computed:{spinId:function(){return this.safeId()},computedInline:function(){return this.inline&&!this.vertical},computedReadonly:function(){return this.readonly&&!this.disabled},computedRequired:function(){return this.required&&!this.computedReadonly&&!this.disabled},computedStep:function(){return cr(this.step,1)},computedMin:function(){return cr(this.min,1)},computedMax:function(){var t=cr(this.max,100),e=this.computedStep,i=this.computedMin;return Xs((t-i)/e)*e+i},computedDelay:function(){var t=lr(this.repeatDelay,0);return t>0?t:500},computedInterval:function(){var t=lr(this.repeatInterval,0);return t>0?t:100},computedThreshold:function(){return Us(lr(this.repeatThreshold,10),1)},computedStepMultiplier:function(){return Us(lr(this.repeatStepMultiplier,4),1)},computedPrecision:function(){var t=this.computedStep;return Xs(t)===t?0:(t.toString().split(".")[1]||"").length},computedMultiplier:function(){return Zs(10,this.computedPrecision||0)},valueAsFixed:function(){var t=this.localValue;return It(t)?"":t.toFixed(this.computedPrecision)},computedLocale:function(){var t=or(this.locale).filter(ne);return new Intl.NumberFormat(t).resolvedOptions().locale},computedRTL:function(){return hc(this.computedLocale)},defaultFormatter:function(){var t=this.computedPrecision;return new Intl.NumberFormat(this.computedLocale,{style:"decimal",useGrouping:!1,minimumIntegerDigits:1,minimumFractionDigits:t,maximumFractionDigits:t,notation:"standard"}).format},computedFormatter:function(){var t=this.formatterFn;return gs(t)?t:this.defaultFormatter},computedAttrs:function(){return c(c({},this.bvAttrs),{},{role:"group",lang:this.computedLocale,tabindex:this.disabled?null:"-1",title:this.ariaLabel})},computedSpinAttrs:function(){var t=this.spinId,e=this.localValue,i=this.computedRequired,n=this.disabled,o=this.state,r=this.computedFormatter,s=!It(e);return c(c({dir:this.computedRTL?"rtl":"ltr"},this.bvAttrs),{},{id:t,role:"spinbutton",tabindex:n?null:"0","aria-live":"off","aria-label":this.ariaLabel||null,"aria-controls":this.ariaControls||null,"aria-invalid":!1===o||!s&&i?"true":null,"aria-required":i?"true":null,"aria-valuemin":vr(this.computedMin),"aria-valuemax":vr(this.computedMax),"aria-valuenow":s?e:null,"aria-valuetext":s?r(e):null})}},watch:(Sh={},a(Sh,Dm,(function(t){this.localValue=cr(t,null)})),a(Sh,"localValue",(function(t){this.$emit(Fm,t)})),a(Sh,"disabled",(function(t){t&&this.clearRepeat()})),a(Sh,"readonly",(function(t){t&&this.clearRepeat()})),Sh),created:function(){this.$_autoDelayTimer=null,this.$_autoRepeatTimer=null,this.$_keyIsDown=!1},beforeDestroy:function(){this.clearRepeat()},deactivated:function(){this.clearRepeat()},methods:{focus:function(){this.disabled||ts(this.$refs.spinner)},blur:function(){this.disabled||es(this.$refs.spinner)},emitChange:function(){this.$emit($n,this.localValue)},stepValue:function(t){var e=this.localValue;if(!this.disabled&&!It(e)){var i=this.computedStep*t,n=this.computedMin,o=this.computedMax,r=this.computedMultiplier,s=this.wrap;e=Js((e-n)/i)*i+n+i,e=Js(e*r)/r,this.localValue=e>o?s?n:o:e<n?s?o:n:e}},onFocusBlur:function(t){this.disabled?this.hasFocus=!1:this.hasFocus="focus"===t.type},stepUp:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,e=this.localValue;It(e)?this.localValue=this.computedMin:this.stepValue(1*t)},stepDown:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,e=this.localValue;It(e)?this.localValue=this.wrap?this.computedMax:this.computedMin:this.stepValue(-1*t)},onKeydown:function(t){var e=t.keyCode,i=t.altKey,n=t.ctrlKey,o=t.metaKey;if(!(this.disabled||this.readonly||i||n||o)&&nr(Im,e)){if(Bs(t,{propagation:!1}),this.$_keyIsDown)return;this.resetTimers(),nr([Wa,Ra],e)?(this.$_keyIsDown=!0,e===Wa?this.handleStepRepeat(t,this.stepUp):e===Ra&&this.handleStepRepeat(t,this.stepDown)):33===e?this.stepUp(this.computedStepMultiplier):34===e?this.stepDown(this.computedStepMultiplier):e===za?this.localValue=this.computedMin:e===Ma&&(this.localValue=this.computedMax)}},onKeyup:function(t){var e=t.keyCode,i=t.altKey,n=t.ctrlKey,o=t.metaKey;this.disabled||this.readonly||i||n||o||nr(Im,e)&&(Bs(t,{propagation:!1}),this.resetTimers(),this.$_keyIsDown=!1,this.emitChange())},handleStepRepeat:function(t,e){var i=this,n=t||{},o=n.type,r=n.button;if(!this.disabled&&!this.readonly){if("mousedown"===o&&r)return;this.resetTimers(),e(1);var s=this.computedThreshold,a=this.computedStepMultiplier,l=this.computedDelay,c=this.computedInterval;this.$_autoDelayTimer=setTimeout((function(){var t=0;i.$_autoRepeatTimer=setInterval((function(){e(t<s?1:a),t++}),c)}),l)}},onMouseup:function(t){var e=t||{},i=e.type,n=e.button;"mouseup"===i&&n||(Bs(t,{propagation:!1}),this.resetTimers(),this.setMouseup(!1),this.emitChange())},setMouseup:function(t){try{$s(t,document.body,"mouseup",this.onMouseup,!1),$s(t,document.body,"touchend",this.onMouseup,!1)}catch(t){}},resetTimers:function(){clearTimeout(this.$_autoDelayTimer),clearInterval(this.$_autoRepeatTimer),this.$_autoDelayTimer=null,this.$_autoRepeatTimer=null},clearRepeat:function(){this.resetTimers(),this.setMouseup(!1),this.$_keyIsDown=!1}},render:function(t){var e=this,i=this.spinId,n=this.localValue,o=this.computedInline,r=this.computedReadonly,s=this.vertical,a=this.disabled,l=this.computedFormatter,c=!It(n),u=function(n,o,l,c,u,d,h){var f=t(l,{props:{scale:e.hasFocus?1.5:1.25},attrs:{"aria-hidden":"true"}}),p={hasFocus:e.hasFocus},m=function(t){a||r||(Bs(t,{propagation:!1}),e.setMouseup(!0),ts(t.currentTarget),e.handleStepRepeat(t,n))};return t("button",{staticClass:"btn btn-sm border-0 rounded-0",class:{"py-0":!s},attrs:{tabindex:"-1",type:"button",disabled:a||r||d,"aria-disabled":a||r||d?"true":null,"aria-controls":i,"aria-label":o||null,"aria-keyshortcuts":u||null},on:{mousedown:m,touchstart:m},key:c||null,ref:c},[e.normalizeSlot(h,p)||f])},d=u(this.stepUp,this.labelIncrement,Da,"inc","ArrowUp",!1,"increment"),h=u(this.stepDown,this.labelDecrement,Ba,"dec","ArrowDown",!1,"decrement"),f=t();this.name&&!a&&(f=t("input",{attrs:{type:"hidden",name:this.name,form:this.form||null,value:this.valueAsFixed},key:"hidden"}));var p=t("output",{staticClass:"flex-grow-1",class:{"d-flex":s,"align-self-center":!s,"align-items-center":s,"border-top":s,"border-bottom":s,"border-left":!s,"border-right":!s},attrs:this.computedSpinAttrs,key:"output",ref:"spinner"},[t("bdi",c?l(n):this.placeholder||"")]);return t("div",{staticClass:"b-form-spinbutton form-control",class:[{disabled:a,readonly:r,focus:this.hasFocus,"d-inline-flex":o||s,"d-flex":!o&&!s,"align-items-stretch":!s,"flex-column":s},this.sizeFormClass,this.stateClass],attrs:this.computedAttrs,on:{keydown:this.onKeydown,keyup:this.onKeyup,"!focus":this.onFocusBlur,"!blur":this.onFocusBlur}},s?[d,f,p,h]:[h,f,p,d])}}),Vm=me({components:{BFormSpinbutton:Om,BSpinbutton:Om}}),Em=vs(ee(c(c({},fc),{},{disabled:hs(ho,!1),noRemove:hs(ho,!1),pill:hs(ho,!1),removeLabel:hs(go,"Remove tag"),tag:hs(go,"span"),title:hs(go),variant:hs(go,"secondary")})),Ti),Lm=i.default.extend({name:Ti,mixins:[pc,Cs],props:Em,methods:{onRemove:function(t){var e=t.type,i=t.keyCode;this.disabled||"click"!==e&&("keydown"!==e||46!==i)||this.$emit("remove")}},render:function(t){var e=this.title,i=this.tag,n=this.variant,o=this.pill,r=this.disabled,s=this.safeId(),a=this.safeId("_taglabel_"),l=t();this.noRemove||r||(l=t(Ps,{staticClass:"b-form-tag-remove",props:{ariaLabel:this.removeLabel},attrs:{"aria-controls":s,"aria-describedby":a,"aria-keyshortcuts":"Delete"},on:{click:this.onRemove,keydown:this.onRemove}}));var c=t("span",{staticClass:"b-form-tag-content flex-grow-1 text-truncate",attrs:{id:a}},this.normalizeSlot()||e);return t(Bl,{staticClass:"b-form-tag d-inline-flex align-items-baseline mw-100",class:{disabled:r},props:{tag:i,variant:n,pill:o},attrs:{id:s,title:e||null,"aria-labelledby":a}},[c,l])}}),Am=ys("value",{type:uo,defaultValue:[]}),Rm=Am.mixin,Mm=Am.props,Hm=Am.prop,zm=Am.event,Nm=["text","email","tel","url","number"],jm=[".b-form-tag","button","input","select"].join(" "),Gm=function(t){return or(t).map((function(t){return br(vr(t))})).filter((function(t,e,i){return t.length>0&&i.indexOf(t)===e}))},Wm=function(t){return Et(t)?t:Nt(t)&&t.target.value||""},Ym=vs(ee(c(c(c(c(c(c({},fc),Mm),Tf),kf),Bf),{},{addButtonText:hs(go,"Add"),addButtonVariant:hs(go,"outline-secondary"),addOnChange:hs(ho,!1),duplicateTagText:hs(go,"Duplicate tag(s)"),ignoreInputFocusSelector:hs(Co,jm),inputAttrs:hs(vo,{}),inputClass:hs(To),inputId:hs(go),inputType:hs(go,"text",(function(t){return nr(Nm,t)})),invalidTagText:hs(go,"Invalid tag(s)"),limit:hs(mo),limitTagsText:hs(go,"Tag limit reached"),noAddOnEnter:hs(ho,!1),noOuterFocus:hs(ho,!1),noTagRemove:hs(ho,!1),placeholder:hs(go,"Add tag..."),removeOnDelete:hs(ho,!1),separator:hs(Co),tagClass:hs(To),tagPills:hs(ho,!1),tagRemoveLabel:hs(go,"Remove tag"),tagRemovedLabel:hs(go,"Tag removed"),tagValidator:hs(po),tagVariant:hs(go,"secondary")})),Ci),Um=i.default.extend({name:Ci,mixins:[pc,Rm,Cf,$f,_f,Cs],props:Ym,data:function(){return{hasFocus:!1,newTag:"",tags:[],removedTags:[],tagsState:{all:[],valid:[],invalid:[],duplicate:[]}}},computed:{computedInputId:function(){return this.inputId||this.safeId("__input__")},computedInputType:function(){return nr(Nm,this.inputType)?this.inputType:"text"},computedInputAttrs:function(){var t=this.disabled,e=this.form;return c(c({},this.inputAttrs),{},{id:this.computedInputId,value:this.newTag,disabled:t,form:e})},computedInputHandlers:function(){return{input:this.onInputInput,change:this.onInputChange,keydown:this.onInputKeydown,reset:this.reset}},computedSeparator:function(){return or(this.separator).filter(Et).filter(ne).join("")},computedSeparatorRegExp:function(){var t=this.computedSeparator;return t?new RegExp("[".concat(mr(t).replace(ct,"\\s"),"]+")):null},computedJoiner:function(){var t=this.computedSeparator.charAt(0);return" "!==t?"".concat(t," "):t},computeIgnoreInputFocusSelector:function(){return or(this.ignoreInputFocusSelector).filter(ne).join(",").trim()},disableAddButton:function(){var t=this,e=br(this.newTag);return""===e||!this.splitTags(e).some((function(e){return!nr(t.tags,e)&&t.validateTag(e)}))},duplicateTags:function(){return this.tagsState.duplicate},hasDuplicateTags:function(){return this.duplicateTags.length>0},invalidTags:function(){return this.tagsState.invalid},hasInvalidTags:function(){return this.invalidTags.length>0},isLimitReached:function(){var t=this.limit;return Lt(t)&&t>=0&&this.tags.length>=t}},watch:(kh={},a(kh,Hm,(function(t){this.tags=Gm(t)})),a(kh,"tags",(function(t,e){Ua(t,this[Hm])||this.$emit(zm,t),Ua(t,e)||(t=or(t).filter(ne),e=or(e).filter(ne),this.removedTags=e.filter((function(e){return!nr(t,e)})))})),a(kh,"tagsState",(function(t,e){Ua(t,e)||this.$emit("tag-state",t.valid,t.invalid,t.duplicate)})),kh),created:function(){this.tags=Gm(this[Hm])},mounted:function(){var t=this,e=Er("form",this.$el);e&&(Ss(e,"reset",this.reset,ao),this.$on(oo,(function(){ks(e,"reset",t.reset,ao)})))},methods:{addTag:function(t){if(t=Et(t)?t:this.newTag,!this.disabled&&""!==br(t)&&!this.isLimitReached){var e=this.parseTags(t);if(e.valid.length>0||0===e.all.length)if(Vr(this.getInput(),"select"))this.newTag="";else{var i=[].concat(T(e.invalid),T(e.duplicate));this.newTag=e.all.filter((function(t){return nr(i,t)})).join(this.computedJoiner).concat(i.length>0?this.computedJoiner.charAt(0):"")}e.valid.length>0&&(this.tags=or(this.tags,e.valid)),this.tagsState=e,this.focus()}},removeTag:function(t){var e=this;this.disabled||(this.tags=this.tags.filter((function(e){return e!==t})),this.$nextTick((function(){e.focus()})))},reset:function(){var t=this;this.newTag="",this.tags=[],this.$nextTick((function(){t.removedTags=[],t.tagsState={all:[],valid:[],invalid:[],duplicate:[]}}))},onInputInput:function(t){if(!(this.disabled||Nt(t)&&t.target.composing)){var e=Wm(t),i=this.computedSeparatorRegExp;this.newTag!==e&&(this.newTag=e),e=vr(e).replace(ft,""),i&&i.test(e.slice(-1))?this.addTag():this.tagsState=""===e?{all:[],valid:[],invalid:[],duplicate:[]}:this.parseTags(e)}},onInputChange:function(t){if(!this.disabled&&this.addOnChange){var e=Wm(t);this.newTag!==e&&(this.newTag=e),this.addTag()}},onInputKeydown:function(t){if(!this.disabled&&Nt(t)){var e=t.keyCode,i=t.target.value||"";this.noAddOnEnter||e!==Ha?!this.removeOnDelete||8!==e&&46!==e||""!==i||(Bs(t,{propagation:!1}),this.tags=this.tags.slice(0,-1)):(Bs(t,{propagation:!1}),this.addTag())}},onClick:function(t){var e=this,i=this.computeIgnoreInputFocusSelector,n=t.target;this.disabled||_r(n)||i&&Er(i,n,!0)||this.$nextTick((function(){e.focus()}))},onFocusin:function(){this.hasFocus=!0},onFocusout:function(){this.hasFocus=!1},handleAutofocus:function(){var t=this;this.$nextTick((function(){xr((function(){t.autofocus&&!t.disabled&&t.focus()}))}))},focus:function(){this.disabled||ts(this.getInput())},blur:function(){this.disabled||es(this.getInput())},splitTags:function(t){t=vr(t);var e=this.computedSeparatorRegExp;return(e?t.split(e):[t]).map(br).filter(ne)},parseTags:function(t){var e=this,i=this.splitTags(t),n={all:i,valid:[],invalid:[],duplicate:[]};return i.forEach((function(t){nr(e.tags,t)||nr(n.valid,t)?nr(n.duplicate,t)||n.duplicate.push(t):e.validateTag(t)?n.valid.push(t):nr(n.invalid,t)||n.invalid.push(t)})),n},validateTag:function(t){var e=this.tagValidator;return!gs(e)||e(t)},getInput:function(){return Or("#".concat(Dp(this.computedInputId)),this.$el)},defaultRender:function(t){var e=t.addButtonText,i=t.addButtonVariant,n=t.addTag,o=t.disableAddButton,r=t.disabled,s=t.duplicateTagText,a=t.inputAttrs,l=t.inputClass,u=t.inputHandlers,d=t.inputType,h=t.invalidTagText,f=t.isDuplicate,p=t.isInvalid,m=t.isLimitReached,v=t.limitTagsText,b=t.noTagRemove,g=t.placeholder,y=t.removeTag,w=t.tagClass,T=t.tagPills,C=t.tagRemoveLabel,x=t.tagVariant,S=t.tags,k=this.$createElement,$=S.map((function(t){return t=vr(t),k(Lm,{class:w,props:{disabled:r,noRemove:b,pill:T,removeLabel:C,tag:"li",title:t,variant:x},on:{remove:function(){return y(t)}},key:"tags_".concat(t)},t)})),B=h&&p?this.safeId("__invalid_feedback__"):null,_=s&&f?this.safeId("__duplicate_feedback__"):null,D=v&&m?this.safeId("__limit_feedback__"):null,F=[a["aria-describedby"],B,_,D].filter(ne).join(" "),I=k("input",{staticClass:"b-form-tags-input w-100 flex-grow-1 p-0 m-0 bg-transparent border-0",class:l,style:{outline:0,minWidth:"5rem"},attrs:c(c({},a),{},{"aria-describedby":F||null,type:d,placeholder:g||null}),domProps:{value:a.value},on:u,directives:[{name:"model",value:a.value}],ref:"input"}),P=k(ml,{staticClass:"b-form-tags-button py-0",class:{invisible:o},style:{fontSize:"90%"},props:{disabled:o||m,variant:i},on:{click:function(){return n()}},ref:"button"},[this.normalizeSlot("add-button-text")||e]),O=this.safeId("__tag_list__"),V=k("li",{staticClass:"b-from-tags-field flex-grow-1",attrs:{role:"none","aria-live":"off","aria-controls":O},key:"tags_field"},[k("div",{staticClass:"d-flex",attrs:{role:"group"}},[I,P])]),E=k("ul",{staticClass:"b-form-tags-list list-unstyled mb-0 d-flex flex-wrap align-items-center",attrs:{id:O},key:"tags_list"},[$,V]),L=k();if(h||s||v){var A=this.computedJoiner,R=k();B&&(R=k(ff,{props:{id:B,forceShow:!0},key:"tags_invalid_feedback"},[this.invalidTagText,": ",this.invalidTags.join(A)]));var M=k();_&&(M=k(df,{props:{id:_},key:"tags_duplicate_feedback"},[this.duplicateTagText,": ",this.duplicateTags.join(A)]));var H=k();D&&(H=k(df,{props:{id:D},key:"tags_limit_feedback"},[v])),L=k("div",{attrs:{"aria-live":"polite","aria-atomic":"true"},key:"tags_feedback"},[R,M,H])}return[E,L]}},render:function(t){var e=this.name,i=this.disabled,n=this.required,o=this.form,r=this.tags,s=this.computedInputId,a=this.hasFocus,l=this.noOuterFocus,u=c({tags:r.slice(),inputAttrs:this.computedInputAttrs,inputType:this.computedInputType,inputHandlers:this.computedInputHandlers,removeTag:this.removeTag,addTag:this.addTag,reset:this.reset,inputId:s,isInvalid:this.hasInvalidTags,invalidTags:this.invalidTags.slice(),isDuplicate:this.hasDuplicateTags,duplicateTags:this.duplicateTags.slice(),isLimitReached:this.isLimitReached,disableAddButton:this.disableAddButton},Jt(this.$props,["addButtonText","addButtonVariant","disabled","duplicateTagText","form","inputClass","invalidTagText","limit","limitTagsText","noTagRemove","placeholder","required","separator","size","state","tagClass","tagPills","tagRemoveLabel","tagVariant"])),d=this.normalizeSlot(Ao,u)||this.defaultRender(u),h=t("output",{staticClass:"sr-only",attrs:{id:this.safeId("__selected_tags__"),role:"status",for:s,"aria-live":a?"polite":"off","aria-atomic":"true","aria-relevant":"additions text"}},this.tags.join(", ")),f=t("div",{staticClass:"sr-only",attrs:{id:this.safeId("__removed_tags__"),role:"status","aria-live":a?"assertive":"off","aria-atomic":"true"}},this.removedTags.length>0?"(".concat(this.tagRemovedLabel,") ").concat(this.removedTags.join(", ")):""),p=t();if(e&&!i){var m=r.length>0;p=(m?r:[""]).map((function(i){return t("input",{class:{"sr-only":!m},attrs:{type:m?"hidden":"text",value:i,required:n,name:e,form:o},key:"tag_input_".concat(i)})}))}return t("div",{staticClass:"b-form-tags form-control h-auto",class:[{focus:a&&!l&&!i,disabled:i},this.sizeFormClass,this.stateClass],attrs:{id:this.safeId(),role:"group",tabindex:i||l?null:"-1","aria-describedby":this.safeId("__selected_tags__")},on:{click:this.onClick,focusin:this.onFocusin,focusout:this.onFocusout}},[h,f,d,p])}}),qm=me({components:{BFormTags:Um,BTags:Um,BFormTag:Lm,BTag:Lm}}),Km=vs(ee(c(c(c(c(c(c({},fc),Tf),kf),Bf),Wp),{},{maxRows:hs(_o),noAutoShrink:hs(ho,!1),noResize:hs(ho,!1),rows:hs(_o,2),wrap:hs(go,"soft")})),Si),Xm=i.default.extend({name:Si,directives:{"b-visible":Kc},mixins:[Qa,pc,Ja,Cf,$f,_f,Yp,Mp,Up],props:Km,data:function(){return{heightInPx:null}},computed:{computedStyle:function(){var t={resize:!this.computedRows||this.noResize?"none":null};return this.computedRows||(t.height=this.heightInPx,t.overflowY="scroll"),t},computedMinRows:function(){return Us(lr(this.rows,2),2)},computedMaxRows:function(){return Us(this.computedMinRows,lr(this.maxRows,0))},computedRows:function(){return this.computedMinRows===this.computedMaxRows?this.computedMinRows:null},computedAttrs:function(){var t=this.disabled,e=this.required;return{id:this.safeId(),name:this.name||null,form:this.form||null,disabled:t,placeholder:this.placeholder||null,required:e,autocomplete:this.autocomplete||null,readonly:this.readonly||this.plaintext,rows:this.computedRows,wrap:this.wrap||null,"aria-required":this.required?"true":null,"aria-invalid":this.computedAriaInvalid}},computedListeners:function(){return c(c({},this.bvListeners),{},{input:this.onInput,change:this.onChange,blur:this.onBlur})}},watch:{localValue:function(){this.setHeight()}},mounted:function(){this.setHeight()},methods:{visibleCallback:function(t){t&&this.$nextTick(this.setHeight)},setHeight:function(){var t=this;this.$nextTick((function(){xr((function(){t.heightInPx=t.computeHeight()}))}))},computeHeight:function(){if(this.$isServer||!It(this.computedRows))return null;var t=this.$el;if(!Dr(t))return null;var e=Kr(t),i=cr(e.lineHeight,1),n=cr(e.borderTopWidth,0)+cr(e.borderBottomWidth,0),o=cr(e.paddingTop,0)+cr(e.paddingBottom,0),r=n+o,s=i*this.computedMinRows+r,a=Ur(t,"height")||e.height;Wr(t,"height","auto");var l=t.scrollHeight;Wr(t,"height",a);var c=Us((l-o)/i,2),u=Ys(Us(c,this.computedMinRows),this.computedMaxRows),d=Us(Ks(u*i+r),s);return this.noAutoShrink&&cr(a,0)>d?a:"".concat(d,"px")}},render:function(t){return t("textarea",{class:this.computedClass,style:this.computedStyle,directives:[{name:"b-visible",value:this.visibleCallback,modifiers:{640:!0}}],attrs:this.computedAttrs,domProps:{value:this.localValue},on:this.computedListeners,ref:"input"})}}),Zm=me({components:{BFormTextarea:Xm,BTextarea:Xm}}),Jm=ys("value",{type:go,defaultValue:""}),Qm=Jm.mixin,tv=Jm.props,ev=Jm.prop,iv=Jm.event,nv="numeric",ov=function(t){return"00".concat(t||"").slice(-2)},rv=function(t){t=vr(t);var e=null,i=null,n=null;if(gt.test(t)){var o=w(t.split(":").map((function(t){return lr(t,null)})),3);e=o[0],i=o[1],n=o[2]}return{hours:Pt(e)?null:e,minutes:Pt(i)?null:i,seconds:Pt(n)?null:n,ampm:Pt(e)||e<12?0:1}},sv=vs(ee(c(c(c(c({},fc),tv),Jt(Pm,["labelIncrement","labelDecrement"])),{},{ariaLabelledby:hs(go),disabled:hs(ho,!1),hidden:hs(ho,!1),hideHeader:hs(ho,!1),hour12:hs(ho,null),labelAm:hs(go,"AM"),labelAmpm:hs(go,"AM/PM"),labelHours:hs(go,"Hours"),labelMinutes:hs(go,"Minutes"),labelNoTimeSelected:hs(go,"No time selected"),labelPm:hs(go,"PM"),labelSeconds:hs(go,"Seconds"),labelSelected:hs(go,"Selected time"),locale:hs(Co),minutesStep:hs(_o,1),readonly:hs(ho,!1),secondsStep:hs(_o,1),showSeconds:hs(ho,!1)})),Tn),av=i.default.extend({name:Tn,mixins:[pc,Qm,Cs],props:sv,data:function(){var t=rv(this[ev]||"");return{modelHours:t.hours,modelMinutes:t.minutes,modelSeconds:t.seconds,modelAmpm:t.ampm,isLive:!1}},computed:{computedHMS:function(){return function(t){var e=t.hours,i=t.minutes,n=t.seconds,o=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return It(e)||It(i)||o&&It(n)?"":[e,i,o?n:0].map(ov).join(":")}({hours:this.modelHours,minutes:this.modelMinutes,seconds:this.modelSeconds},this.showSeconds)},resolvedOptions:function(){var t=or(this.locale).filter(ne),e={hour:nv,minute:nv,second:nv};Pt(this.hour12)||(e.hour12=!!this.hour12);var i=new Intl.DateTimeFormat(t,e).resolvedOptions(),n=i.hour12||!1,o=i.hourCycle||(n?"h12":"h23");return{locale:i.locale,hour12:n,hourCycle:o}},computedLocale:function(){return this.resolvedOptions.locale},computedLang:function(){return(this.computedLocale||"").replace(/-u-.*$/,"")},computedRTL:function(){return hc(this.computedLang)},computedHourCycle:function(){return this.resolvedOptions.hourCycle},is12Hour:function(){return!!this.resolvedOptions.hour12},context:function(){return{locale:this.computedLocale,isRTL:this.computedRTL,hourCycle:this.computedHourCycle,hour12:this.is12Hour,hours:this.modelHours,minutes:this.modelMinutes,seconds:this.showSeconds?this.modelSeconds:0,value:this.computedHMS,formatted:this.formattedTimeString}},valueId:function(){return this.safeId()||null},computedAriaLabelledby:function(){return[this.ariaLabelledby,this.valueId].filter(ne).join(" ")||null},timeFormatter:function(){var t={hour12:this.is12Hour,hourCycle:this.computedHourCycle,hour:nv,minute:nv,timeZone:"UTC"};return this.showSeconds&&(t.second=nv),Ql(this.computedLocale,t)},numberFormatter:function(){return new Intl.NumberFormat(this.computedLocale,{style:"decimal",minimumIntegerDigits:2,minimumFractionDigits:0,maximumFractionDigits:0,notation:"standard"}).format},formattedTimeString:function(){var t=this.modelHours,e=this.modelMinutes,i=this.showSeconds&&this.modelSeconds||0;return this.computedHMS?this.timeFormatter(Xl(Date.UTC(0,0,1,t,e,i))):this.labelNoTimeSelected||" "},spinScopedSlots:function(){var t=this.$createElement;return{increment:function(e){var i=e.hasFocus;return t(xa,{props:{scale:i?1.5:1.25},attrs:{"aria-hidden":"true"}})},decrement:function(e){var i=e.hasFocus;return t(xa,{props:{flipV:!0,scale:i?1.5:1.25},attrs:{"aria-hidden":"true"}})}}}},watch:($h={},a($h,ev,(function(t,e){if(t!==e&&!Ua(rv(t),rv(this.computedHMS))){var i=rv(t),n=i.hours,o=i.minutes,r=i.seconds,s=i.ampm;this.modelHours=n,this.modelMinutes=o,this.modelSeconds=r,this.modelAmpm=s}})),a($h,"computedHMS",(function(t,e){t!==e&&this.$emit(iv,t)})),a($h,"context",(function(t,e){Ua(t,e)||this.$emit(Dn,t)})),a($h,"modelAmpm",(function(t,e){var i=this;if(t!==e){var n=It(this.modelHours)?0:this.modelHours;this.$nextTick((function(){0===t&&n>11?i.modelHours=n-12:1===t&&n<12&&(i.modelHours=n+12)}))}})),a($h,"modelHours",(function(t,e){t!==e&&(this.modelAmpm=t>11?1:0)})),$h),created:function(){var t=this;this.$nextTick((function(){t.$emit(Dn,t.context)}))},mounted:function(){this.setLive(!0)},activated:function(){this.setLive(!0)},deactivated:function(){this.setLive(!1)},beforeDestroy:function(){this.setLive(!1)},methods:{focus:function(){this.disabled||ts(this.$refs.spinners[0])},blur:function(){if(!this.disabled){var t=$r();Lr(this.$el,t)&&es(t)}},formatHours:function(t){var e=this.computedHourCycle;return t=0===(t=this.is12Hour&&t>12?t-12:t)&&"h12"===e?12:0===t&&"h24"===e?24:12===t&&"h11"===e?0:t,this.numberFormatter(t)},formatMinutes:function(t){return this.numberFormatter(t)},formatSeconds:function(t){return this.numberFormatter(t)},formatAmpm:function(t){return 0===t?this.labelAm:1===t?this.labelPm:""},setHours:function(t){this.modelHours=t},setMinutes:function(t){this.modelMinutes=t},setSeconds:function(t){this.modelSeconds=t},setAmpm:function(t){this.modelAmpm=t},onSpinLeftRight:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.type,i=t.keyCode;if(!this.disabled&&"keydown"===e&&(i===Na||i===ja)){Bs(t);var n=this.$refs.spinners||[],o=n.map((function(t){return!!t.hasFocus})).indexOf(!0);o=(o+=i===Na?-1:1)>=n.length?0:o<0?n.length-1:o,ts(n[o])}},setLive:function(t){var e=this;t?this.$nextTick((function(){xr((function(){e.isLive=!0}))})):this.isLive=!1}},render:function(t){var e=this;if(this.hidden)return t();var i=this.valueId,n=this.computedAriaLabelledby,o=[],r=function(n,r,s){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},l=e.safeId("_spinbutton_".concat(r,"_"))||null;return o.push(l),t(Om,{class:s,props:c({id:l,placeholder:"--",vertical:!0,required:!0,disabled:e.disabled,readonly:e.readonly,locale:e.computedLocale,labelIncrement:e.labelIncrement,labelDecrement:e.labelDecrement,wrap:!0,ariaControls:i,min:0},a),scopedSlots:e.spinScopedSlots,on:{change:n},key:r,ref:"spinners",refInFor:!0})},s=function(){return t("div",{staticClass:"d-flex flex-column",class:{"text-muted":e.disabled||e.readonly},attrs:{"aria-hidden":"true"}},[t(Sa,{props:{shiftV:4,scale:.5}}),t(Sa,{props:{shiftV:-4,scale:.5}})])},a=[];a.push(r(this.setHours,"hours","b-time-hours",{value:this.modelHours,max:23,step:1,formatterFn:this.formatHours,ariaLabel:this.labelHours})),a.push(s()),a.push(r(this.setMinutes,"minutes","b-time-minutes",{value:this.modelMinutes,max:59,step:this.minutesStep||1,formatterFn:this.formatMinutes,ariaLabel:this.labelMinutes})),this.showSeconds&&(a.push(s()),a.push(r(this.setSeconds,"seconds","b-time-seconds",{value:this.modelSeconds,max:59,step:this.secondsStep||1,formatterFn:this.formatSeconds,ariaLabel:this.labelSeconds}))),this.is12Hour&&a.push(r(this.setAmpm,"ampm","b-time-ampm",{value:this.modelAmpm,max:1,formatterFn:this.formatAmpm,ariaLabel:this.labelAmpm,required:!1})),a=t("div",{staticClass:"d-flex align-items-center justify-content-center mx-auto",attrs:{role:"group",tabindex:this.disabled||this.readonly?null:"-1","aria-labelledby":n},on:{keydown:this.onSpinLeftRight,click:function(t){t.target===t.currentTarget&&e.focus()}}},a);var l=t("output",{staticClass:"form-control form-control-sm text-center",class:{disabled:this.disabled||this.readonly},attrs:{id:i,role:"status",for:o.filter(ne).join(" ")||null,tabindex:this.disabled?null:"-1","aria-live":this.isLive?"polite":"off","aria-atomic":"true"},on:{click:this.focus,focus:this.focus}},[t("bdi",this.formattedTimeString),this.computedHMS?t("span",{staticClass:"sr-only"}," (".concat(this.labelSelected,") ")):""]),u=t("header",{staticClass:"b-time-header",class:{"sr-only":this.hideHeader}},[l]),d=this.normalizeSlot();return d=d?t("footer",{staticClass:"b-time-footer"},d):t(),t("div",{staticClass:"b-time d-inline-flex flex-column text-center",attrs:{role:"group",lang:this.computedLang||null,"aria-labelledby":n||null,"aria-disabled":this.disabled?"true":null,"aria-readonly":this.readonly&&!this.disabled?"true":null}},[u,a,d])}}),lv=ys("value",{type:go,defaultValue:""}),cv=lv.mixin,uv=lv.props,dv=lv.prop,hv=lv.event,fv=Qt(sv,["hidden","id","value"]),pv=Qt(op,["formattedValue","id","lang","rtl","value"]),mv=vs(ee(c(c(c(c(c({},fc),uv),fv),pv),{},{closeButtonVariant:hs(go,"outline-secondary"),labelCloseButton:hs(go,"Close"),labelNowButton:hs(go,"Select now"),labelResetButton:hs(go,"Reset"),noCloseButton:hs(ho,!1),nowButton:hs(ho,!1),nowButtonVariant:hs(go,"outline-primary"),resetButton:hs(ho,!1),resetButtonVariant:hs(go,"outline-danger"),resetValue:hs($o)})),ki),vv=i.default.extend({name:ki,mixins:[pc,cv],props:mv,data:function(){return{localHMS:this[dv]||"",localLocale:null,isRTL:!1,formattedValue:"",isVisible:!1}},computed:{computedLang:function(){return(this.localLocale||"").replace(/-u-.*$/i,"")||null}},watch:(Bh={},a(Bh,dv,(function(t){this.localHMS=t||""})),a(Bh,"localHMS",(function(t){this.isVisible&&this.$emit(hv,t||"")})),Bh),methods:{focus:function(){this.disabled||ts(this.$refs.control)},blur:function(){this.disabled||es(this.$refs.control)},setAndClose:function(t){var e=this;this.localHMS=t,this.$nextTick((function(){e.$refs.control.hide(!0)}))},onInput:function(t){this.localHMS!==t&&(this.localHMS=t)},onContext:function(t){var e=t.isRTL,i=t.locale,n=t.value,o=t.formatted;this.isRTL=e,this.localLocale=i,this.formattedValue=o,this.localHMS=n||"",this.$emit(Dn,t)},onNowButton:function(){var t=new Date,e=[t.getHours(),t.getMinutes(),this.showSeconds?t.getSeconds():0].map((function(t){return"00".concat(t||"").slice(-2)})).join(":");this.setAndClose(e)},onResetButton:function(){this.setAndClose(this.resetValue)},onCloseButton:function(){this.$refs.control.hide(!0)},onShow:function(){this.isVisible=!0},onShown:function(){var t=this;this.$nextTick((function(){ts(t.$refs.time),t.$emit(eo)}))},onHidden:function(){this.isVisible=!1,this.$emit(zn)},defaultButtonFn:function(t){var e=t.isHovered,i=t.hasFocus;return this.$createElement(e||i?$a:ka,{attrs:{"aria-hidden":"true"}})}},render:function(t){var e=this.localHMS,i=this.disabled,n=this.readonly,o=this.$props,r=Pt(this.placeholder)?this.labelNoTimeSelected:this.placeholder,s=[];if(this.nowButton){var l=this.labelNowButton;s.push(t(ml,{props:{size:"sm",disabled:i||n,variant:this.nowButtonVariant},attrs:{"aria-label":l||null},on:{click:this.onNowButton},key:"now-btn"},l))}if(this.resetButton){s.length>0&&s.push(t("span"," "));var u=this.labelResetButton;s.push(t(ml,{props:{size:"sm",disabled:i||n,variant:this.resetButtonVariant},attrs:{"aria-label":u||null},on:{click:this.onResetButton},key:"reset-btn"},u))}if(!this.noCloseButton){s.length>0&&s.push(t("span"," "));var d=this.labelCloseButton;s.push(t(ml,{props:{size:"sm",disabled:i,variant:this.closeButtonVariant},attrs:{"aria-label":d||null},on:{click:this.onCloseButton},key:"close-btn"},d))}s.length>0&&(s=[t("div",{staticClass:"b-form-date-controls d-flex flex-wrap",class:{"justify-content-between":s.length>1,"justify-content-end":s.length<2}},s)]);var h=t(av,{staticClass:"b-form-time-control",props:c(c({},ps(fv,o)),{},{value:e,hidden:!this.isVisible}),on:{input:this.onInput,context:this.onContext},ref:"time"},s);return t(rp,{staticClass:"b-form-timepicker",props:c(c({},ps(pv,o)),{},{id:this.safeId(),value:e,formattedValue:e?this.formattedValue:"",placeholder:r,rtl:this.isRTL,lang:this.computedLang}),on:{show:this.onShow,shown:this.onShown,hidden:this.onHidden},scopedSlots:a({},Eo,this.$scopedSlots["button-content"]||this.defaultButtonFn),ref:"control"},[h])}}),bv=me({components:{BFormTimepicker:vv,BTimepicker:vv}}),gv=me({components:{BImg:Lc,BImgLazy:Qc}}),yv=vs({tag:hs(go,"div")},Vi),wv=i.default.extend({name:Vi,functional:!0,props:yv,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.tag,F(n,{staticClass:"input-group-text"}),o)}}),Tv=vs({append:hs(ho,!1),id:hs(go),isText:hs(ho,!1),tag:hs(go,"div")},Ii),Cv=i.default.extend({name:Ii,functional:!0,props:Tv,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.append;return t(i.tag,F(n,{class:{"input-group-append":r,"input-group-prepend":!r},attrs:{id:i.id}}),i.isText?[t(wv,o)]:o)}}),xv=vs(Qt(Tv,["append"]),Pi),Sv=i.default.extend({name:Pi,functional:!0,props:xv,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(Cv,F(n,{props:c(c({},i),{},{append:!0})}),o)}}),kv=vs(Qt(Tv,["append"]),Oi),$v=i.default.extend({name:Oi,functional:!0,props:kv,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(Cv,F(n,{props:c(c({},i),{},{append:!1})}),o)}}),Bv=vs({append:hs(go),appendHtml:hs(go),id:hs(go),prepend:hs(go),prependHtml:hs(go),size:hs(go),tag:hs(go,"div")},Fi),_v=me({components:{BInputGroup:i.default.extend({name:Fi,functional:!0,props:Bv,render:function(t,e){var i=e.props,n=e.data,o=e.slots,r=e.scopedSlots,s=i.prepend,l=i.prependHtml,c=i.append,u=i.appendHtml,d=i.size,h=r||{},f=o(),p={},m=t(),v=ws(qo,h,f);(v||s||l)&&(m=t($v,[v?Ts(qo,p,h,f):t(wv,{domProps:Fl(l,s)})]));var b=t(),g=ws(Po,h,f);return(g||c||u)&&(b=t(Sv,[g?Ts(Po,p,h,f):t(wv,{domProps:Fl(u,c)})])),t(i.tag,F(n,{staticClass:"input-group",class:a({},"input-group-".concat(d),d),attrs:{id:i.id||null,role:"group"}}),[m,Ts(Ao,p,h,f),b])}}),BInputGroupAddon:Cv,BInputGroupPrepend:$v,BInputGroupAppend:Sv,BInputGroupText:wv}}),Dv=vs({fluid:hs(ko,!1),tag:hs(go,"div")},qe),Fv=i.default.extend({name:qe,functional:!0,props:Dv,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.fluid;return t(i.tag,F(n,{class:a({container:!(r||""===r),"container-fluid":!0===r||""===r},"container-".concat(r),r&&!0!==r)}),o)}}),Iv=vs({bgVariant:hs(go),borderVariant:hs(go),containerFluid:hs(ko,!1),fluid:hs(ho,!1),header:hs(go),headerHtml:hs(go),headerLevel:hs(_o,3),headerTag:hs(go,"h1"),lead:hs(go),leadHtml:hs(go),leadTag:hs(go,"p"),tag:hs(go,"div"),textVariant:hs(go)},Ei),Pv=me({components:{BJumbotron:i.default.extend({name:Ei,functional:!0,props:Iv,render:function(t,e){var i,n=e.props,o=e.data,r=e.slots,s=e.scopedSlots,l=n.header,c=n.headerHtml,u=n.lead,d=n.leadHtml,h=n.textVariant,f=n.bgVariant,p=n.borderVariant,m=s||{},v=r(),b={},g=t(),y=ws(No,m,v);if(y||l||c){var w=n.headerLevel;g=t(n.headerTag,{class:a({},"display-".concat(w),w),domProps:y?{}:Fl(c,l)},Ts(No,b,m,v))}var T=t(),C=ws(Go,m,v);(C||u||d)&&(T=t(n.leadTag,{staticClass:"lead",domProps:C?{}:Fl(d,u)},Ts(Go,b,m,v)));var x=[g,T,Ts(Ao,b,m,v)];return n.fluid&&(x=[t(Fv,{props:{fluid:n.containerFluid}},x)]),t(n.tag,F(o,{staticClass:"jumbotron",class:(i={"jumbotron-fluid":n.fluid},a(i,"text-".concat(h),h),a(i,"bg-".concat(f),f),a(i,"border-".concat(p),p),a(i,"border",p),i)}),x)}})}}),Ov=["start","end","center"],Vv=is((function(t,e){return(e=br(vr(e)))?gr(["row-cols",t,e].filter(ne).join("-")):null})),Ev=is((function(t){return gr(t.replace("cols",""))})),Lv=[],Av=me({components:{BContainer:Fv,BRow:{name:on,functional:!0,get props(){var t;return delete this.props,this.props=(t=ls().reduce((function(t,e){return t[ds(e,"cols")]=hs(_o),t}),Wt(null)),Lv=Kt(t),vs(ee(c(c({},t),{},{alignContent:hs(go,null,(function(t){return nr(or(Ov,"between","around","stretch"),t)})),alignH:hs(go,null,(function(t){return nr(or(Ov,"between","around"),t)})),alignV:hs(go,null,(function(t){return nr(or(Ov,"baseline","stretch"),t)})),noGutters:hs(ho,!1),tag:hs(go,"div")})),on)),this.props},render:function(t,e){var i,n=e.props,o=e.data,r=e.children,s=n.alignV,l=n.alignH,c=n.alignContent,u=[];return Lv.forEach((function(t){var e=Vv(Ev(t),n[t]);e&&u.push(e)})),u.push((a(i={"no-gutters":n.noGutters},"align-items-".concat(s),s),a(i,"justify-content-".concat(l),l),a(i,"align-content-".concat(c),c),i)),t(n.tag,F(o,{staticClass:"row",class:u}),r)}},BCol:Op,BFormRow:bf}}),Rv=me({components:{BLink:ol}}),Mv=vs({flush:hs(ho,!1),horizontal:hs(ko,!1),tag:hs(go,"div")},Ai),Hv=i.default.extend({name:Ai,functional:!0,props:Mv,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=""===i.horizontal||i.horizontal;r=!i.flush&&r;var s={staticClass:"list-group",class:a({"list-group-flush":i.flush,"list-group-horizontal":!0===r},"list-group-horizontal-".concat(r),Et(r))};return t(i.tag,F(n,s),o)}}),zv=["a","router-link","button","b-link"],Nv=Qt(nl,["event","routerTag"]);delete Nv.href.default,delete Nv.to.default;var jv=vs(ee(c(c({},Nv),{},{action:hs(ho,!1),button:hs(ho,!1),tag:hs(go,"div"),variant:hs(go)})),Ri),Gv=me({components:{BListGroup:Hv,BListGroupItem:i.default.extend({name:Ri,functional:!0,props:jv,render:function(t,e){var i,n=e.props,o=e.data,r=e.children,s=n.button,l=n.variant,c=n.active,u=n.disabled,d=la(n),h=s?"button":d?ol:n.tag,f=!!(n.action||d||s||nr(zv,n.tag)),p={},m={};return Br(h,"button")?(o.attrs&&o.attrs.type||(p.type="button"),n.disabled&&(p.disabled=!0)):m=ps(Nv,n),t(h,F(o,{attrs:p,props:m,staticClass:"list-group-item",class:(i={},a(i,"list-group-item-".concat(l),l),a(i,"list-group-item-action",f),a(i,"active",c),a(i,"disabled",u),i)}),r)}})}}),Wv=vs({right:hs(ho,!1),tag:hs(go,"div"),verticalAlign:hs(go,"top")},Hi),Yv=i.default.extend({name:Hi,functional:!0,props:Wv,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.verticalAlign,s="top"===r?"start":"bottom"===r?"end":r;return t(i.tag,F(n,{staticClass:"media-aside",class:a({"media-aside-right":i.right},"align-self-".concat(s),s)}),o)}}),Uv=vs({tag:hs(go,"div")},zi),qv=i.default.extend({name:zi,functional:!0,props:Uv,render:function(t,e){var i=e.props,n=e.data,o=e.children;return t(i.tag,F(n,{staticClass:"media-body"}),o)}}),Kv=vs({noBody:hs(ho,!1),rightAlign:hs(ho,!1),tag:hs(go,"div"),verticalAlign:hs(go,"top")},Mi),Xv=me({components:{BMedia:i.default.extend({name:Mi,functional:!0,props:Kv,render:function(t,e){var i=e.props,n=e.data,o=e.slots,r=e.scopedSlots,s=e.children,a=i.noBody,l=i.rightAlign,c=i.verticalAlign,u=a?s:[];if(!a){var d={},h=o(),f=r||{};u.push(t(qv,Ts(Ao,d,f,h)));var p=Ts("aside",d,f,h);p&&u[l?"push":"unshift"](t(Yv,{props:{right:l,verticalAlign:c}},p))}return t(i.tag,F(n,{staticClass:"media"}),u)}}),BMediaAside:Yv,BMediaBody:qv}}),Zv="$_bv_documentHandlers_",Jv=i.default.extend({created:function(){var t=this;M&&(this[Zv]={},this.$once(oo,(function(){var e=t[Zv]||{};delete t[Zv],Kt(e).forEach((function(t){(e[t]||[]).forEach((function(e){return ks(document,t,e,lo)}))}))})))},methods:{listenDocument:function(t,e,i){t?this.listenOnDocument(e,i):this.listenOffDocument(e,i)},listenOnDocument:function(t,e){this[Zv]&&Et(t)&&Ot(e)&&(this[Zv][t]=this[Zv][t]||[],nr(this[Zv][t],e)||(this[Zv][t].push(e),Ss(document,t,e,lo)))},listenOffDocument:function(t,e){this[Zv]&&Et(t)&&Ot(e)&&(ks(document,t,e,lo),this[Zv][t]=(this[Zv][t]||[]).filter((function(t){return t!==e})))}}}),Qv="$_bv_windowHandlers_",tb=i.default.extend({beforeCreate:function(){this[Qv]={}},beforeDestroy:function(){if(M){var t=this[Qv];delete this[Qv],Kt(t).forEach((function(e){(t[e]||[]).forEach((function(t){return ks(window,e,t,lo)}))}))}},methods:{listenWindow:function(t,e,i){t?this.listenOnWindow(e,i):this.listenOffWindow(e,i)},listenOnWindow:function(t,e){M&&this[Qv]&&Et(t)&&Ot(e)&&(this[Qv][t]=this[Qv][t]||[],nr(this[Qv][t],e)||(this[Qv][t].push(e),Ss(window,t,e,lo)))},listenOffWindow:function(t,e){M&&this[Qv]&&Et(t)&&Ot(e)&&(ks(window,t,e,lo),this[Qv][t]=(this[Qv][t]||[]).filter((function(t){return t!==e})))}}}),eb=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return t&&t.$options._scopeId||e},ib=i.default.extend({computed:{scopedStyleAttrs:function(){var t=eb(this.$parent);return t?a({},t,""):{}}}}),nb=i.default.extend({abstract:!0,name:"BVTransporterTarget",props:{nodes:hs(yo)},data:function(t){return{updatedNodes:t.nodes}},destroyed:function(){var t;(t=this.$el)&&t.parentNode&&t.parentNode.removeChild(t)},render:function(t){var e=this.updatedNodes,i=Ot(e)?e({}):e;return(i=or(i).filter(ne))&&i.length>0&&!i[0].text?i[0]:t()}}),ob={container:hs([HTMLElement,go],"body"),disabled:hs(ho,!1),tag:hs(go,"div")},rb=i.default.extend({name:"BVTransporter",mixins:[Cs],props:ob,watch:{disabled:{immediate:!0,handler:function(t){t?this.unmountTarget():this.$nextTick(this.mountTarget)}}},created:function(){this.$_defaultFn=null,this.$_target=null},beforeMount:function(){this.mountTarget()},updated:function(){this.updateTarget()},beforeDestroy:function(){this.unmountTarget(),this.$_defaultFn=null},methods:{getContainer:function(){if(M){var t=this.container;return Et(t)?Or(t):t}return null},mountTarget:function(){if(!this.$_target){var t=this.getContainer();if(t){var e=document.createElement("div");t.appendChild(e),this.$_target=new nb({el:e,parent:this,propsData:{nodes:or(this.normalizeSlot())}})}}},updateTarget:function(){if(M&&this.$_target){var t=this.$scopedSlots.default;this.disabled||(t&&this.$_defaultFn!==t?this.$_target.updatedNodes=t:t||(this.$_target.updatedNodes=this.$slots.default)),this.$_defaultFn=t}},unmountTarget:function(){this.$_target&&this.$_target.$destroy(),this.$_target=null}},render:function(t){if(this.disabled){var e=or(this.normalizeSlot()).filter(ne);if(e.length>0&&!e[0].text)return e[0]}return t()}}),BvModalEvent=function(t){u(BvModalEvent,t);var e=g(BvModalEvent);function BvModalEvent(t){var i,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return o(this,BvModalEvent),i=e.call(this,t,n),Yt(v(i),{trigger:{enumerable:!0,configurable:!1,writable:!1}}),i}return s(BvModalEvent,null,[{key:"Defaults",get:function(){return c(c({},y(d(BvModalEvent),"Defaults",this)),{},{trigger:null})}}]),BvModalEvent}(BvEvent),sb=new(i.default.extend({data:function(){return{modals:[],baseZIndex:null,scrollbarWidth:null,isBodyOverflowing:!1}},computed:{modalCount:function(){return this.modals.length},modalsAreOpen:function(){return this.modalCount>0}},watch:{modalCount:function(t,e){M&&(this.getScrollbarWidth(),t>0&&0===e?(this.checkScrollbar(),this.setScrollbar(),Rr(document.body,"modal-open")):0===t&&e>0&&(this.resetScrollbar(),Mr(document.body,"modal-open")),zr(document.body,"data-modal-open-count",String(t)))},modals:function(t){var e=this;this.checkScrollbar(),xr((function(){e.updateModals(t||[])}))}},methods:{registerModal:function(t){var e=this;t&&-1===this.modals.indexOf(t)&&(this.modals.push(t),t.$once(oo,(function(){e.unregisterModal(t)})))},unregisterModal:function(t){var e=this.modals.indexOf(t);e>-1&&(this.modals.splice(e,1),t._isBeingDestroyed||t._isDestroyed||this.resetModal(t))},getBaseZIndex:function(){if(It(this.baseZIndex)&&M){var t=document.createElement("div");Rr(t,"modal-backdrop"),Rr(t,"d-none"),Wr(t,"display","none"),document.body.appendChild(t),this.baseZIndex=lr(Kr(t).zIndex,1040),document.body.removeChild(t)}return this.baseZIndex||1040},getScrollbarWidth:function(){if(It(this.scrollbarWidth)&&M){var t=document.createElement("div");Rr(t,"modal-scrollbar-measure"),document.body.appendChild(t),this.scrollbarWidth=qr(t).width-t.clientWidth,document.body.removeChild(t)}return this.scrollbarWidth||0},updateModals:function(t){var e=this,i=this.getBaseZIndex(),n=this.getScrollbarWidth();t.forEach((function(t,o){t.zIndex=i+o,t.scrollbarWidth=n,t.isTop=o===e.modals.length-1,t.isBodyOverflowing=e.isBodyOverflowing}))},resetModal:function(t){t&&(t.zIndex=this.getBaseZIndex(),t.isTop=!0,t.isBodyOverflowing=!1)},checkScrollbar:function(){var t=qr(document.body),e=t.left,i=t.right;this.isBodyOverflowing=e+i<window.innerWidth},setScrollbar:function(){var t=document.body;if(t._paddingChangedForModal=t._paddingChangedForModal||[],t._marginChangedForModal=t._marginChangedForModal||[],this.isBodyOverflowing){var e=this.scrollbarWidth;Pr(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top").forEach((function(i){var n=Ur(i,"paddingRight")||"";zr(i,"data-padding-right",n),Wr(i,"paddingRight","".concat(cr(Kr(i).paddingRight,0)+e,"px")),t._paddingChangedForModal.push(i)})),Pr(".sticky-top").forEach((function(i){var n=Ur(i,"marginRight")||"";zr(i,"data-margin-right",n),Wr(i,"marginRight","".concat(cr(Kr(i).marginRight,0)-e,"px")),t._marginChangedForModal.push(i)})),Pr(".navbar-toggler").forEach((function(i){var n=Ur(i,"marginRight")||"";zr(i,"data-margin-right",n),Wr(i,"marginRight","".concat(cr(Kr(i).marginRight,0)+e,"px")),t._marginChangedForModal.push(i)}));var i=Ur(t,"paddingRight")||"";zr(t,"data-padding-right",i),Wr(t,"paddingRight","".concat(cr(Kr(t).paddingRight,0)+e,"px"))}},resetScrollbar:function(){var t=document.body;t._paddingChangedForModal&&t._paddingChangedForModal.forEach((function(t){Gr(t,"data-padding-right")&&(Wr(t,"paddingRight",jr(t,"data-padding-right")||""),Nr(t,"data-padding-right"))})),t._marginChangedForModal&&t._marginChangedForModal.forEach((function(t){Gr(t,"data-margin-right")&&(Wr(t,"marginRight",jr(t,"data-margin-right")||""),Nr(t,"data-margin-right"))})),t._paddingChangedForModal=null,t._marginChangedForModal=null,Gr(t,"data-padding-right")&&(Wr(t,"paddingRight",jr(t,"data-padding-right")||""),Nr(t,"data-padding-right"))}}})),ab=ys("visible",{type:ho,defaultValue:!1,event:$n}),lb=ab.mixin,cb=ab.props,ub=ab.prop,db=ab.event,hb="FORCE",fb="cancel",pb="headerclose",mb="ok",vb=[fb,pb,mb],bb={subtree:!0,childList:!0,characterData:!0,attributes:!0,attributeFilter:["style","class"]},gb=vs(ee(c(c(c({},fc),cb),{},{ariaLabel:hs(go),autoFocusButton:hs(go,null,(function(t){return Pt(t)||nr(vb,t)})),bodyBgVariant:hs(go),bodyClass:hs(To),bodyTextVariant:hs(go),busy:hs(ho,!1),buttonSize:hs(go),cancelDisabled:hs(ho,!1),cancelTitle:hs(go,"Cancel"),cancelTitleHtml:hs(go),cancelVariant:hs(go,"secondary"),centered:hs(ho,!1),contentClass:hs(To),dialogClass:hs(To),footerBgVariant:hs(go),footerBorderVariant:hs(go),footerClass:hs(To),footerTextVariant:hs(go),headerBgVariant:hs(go),headerBorderVariant:hs(go),headerClass:hs(To),headerCloseContent:hs(go,"×"),headerCloseLabel:hs(go,"Close"),headerCloseVariant:hs(go),headerTextVariant:hs(go),hideBackdrop:hs(ho,!1),hideFooter:hs(ho,!1),hideHeader:hs(ho,!1),hideHeaderClose:hs(ho,!1),ignoreEnforceFocusSelector:hs(Co),lazy:hs(ho,!1),modalClass:hs(To),noCloseOnBackdrop:hs(ho,!1),noCloseOnEsc:hs(ho,!1),noEnforceFocus:hs(ho,!1),noFade:hs(ho,!1),noStacking:hs(ho,!1),okDisabled:hs(ho,!1),okOnly:hs(ho,!1),okTitle:hs(go,"OK"),okTitleHtml:hs(go),okVariant:hs(go,"primary"),returnFocus:hs([HTMLElement,vo,go]),scrollable:hs(ho,!1),size:hs(go,"md"),static:hs(ho,!1),title:hs(go),titleClass:hs(To),titleHtml:hs(go),titleSrOnly:hs(ho,!1),titleTag:hs(go,"h5")})),Ni),yb=i.default.extend({name:Ni,mixins:[Za,pc,lb,Jv,Ja,tb,Cs,ib],inheritAttrs:!1,props:gb,data:function(){return{isHidden:!0,isVisible:!1,isTransitioning:!1,isShow:!1,isBlock:!1,isOpening:!1,isClosing:!1,ignoreBackdropClick:!1,isModalOverflowing:!1,scrollbarWidth:0,zIndex:sb.getBaseZIndex(),isTop:!0,isBodyOverflowing:!1}},computed:{modalId:function(){return this.safeId()},modalOuterId:function(){return this.safeId("__BV_modal_outer_")},modalHeaderId:function(){return this.safeId("__BV_modal_header_")},modalBodyId:function(){return this.safeId("__BV_modal_body_")},modalTitleId:function(){return this.safeId("__BV_modal_title_")},modalContentId:function(){return this.safeId("__BV_modal_content_")},modalFooterId:function(){return this.safeId("__BV_modal_footer_")},modalBackdropId:function(){return this.safeId("__BV_modal_backdrop_")},modalClasses:function(){return[{fade:!this.noFade,show:this.isShow},this.modalClass]},modalStyles:function(){var t="".concat(this.scrollbarWidth,"px");return{paddingLeft:!this.isBodyOverflowing&&this.isModalOverflowing?t:"",paddingRight:this.isBodyOverflowing&&!this.isModalOverflowing?t:"",display:this.isBlock?"block":"none"}},dialogClasses:function(){var t;return[(t={},a(t,"modal-".concat(this.size),this.size),a(t,"modal-dialog-centered",this.centered),a(t,"modal-dialog-scrollable",this.scrollable),t),this.dialogClass]},headerClasses:function(){var t;return[(t={},a(t,"bg-".concat(this.headerBgVariant),this.headerBgVariant),a(t,"text-".concat(this.headerTextVariant),this.headerTextVariant),a(t,"border-".concat(this.headerBorderVariant),this.headerBorderVariant),t),this.headerClass]},titleClasses:function(){return[{"sr-only":this.titleSrOnly},this.titleClass]},bodyClasses:function(){var t;return[(t={},a(t,"bg-".concat(this.bodyBgVariant),this.bodyBgVariant),a(t,"text-".concat(this.bodyTextVariant),this.bodyTextVariant),t),this.bodyClass]},footerClasses:function(){var t;return[(t={},a(t,"bg-".concat(this.footerBgVariant),this.footerBgVariant),a(t,"text-".concat(this.footerTextVariant),this.footerTextVariant),a(t,"border-".concat(this.footerBorderVariant),this.footerBorderVariant),t),this.footerClass]},modalOuterStyle:function(){return{position:"absolute",zIndex:this.zIndex}},slotScope:function(){return{cancel:this.onCancel,close:this.onClose,hide:this.hide,ok:this.onOk,visible:this.isVisible}},computeIgnoreEnforceFocusSelector:function(){return or(this.ignoreEnforceFocusSelector).filter(ne).join(",").trim()},computedAttrs:function(){return c(c(c({},this.static?{}:this.scopedStyleAttrs),this.bvAttrs),{},{id:this.modalOuterId})},computedModalAttrs:function(){var t=this.isVisible,e=this.ariaLabel;return{id:this.modalId,role:"dialog","aria-hidden":t?null:"true","aria-modal":t?"true":null,"aria-label":e,"aria-labelledby":this.hideHeader||e||!(this.hasNormalizedSlot(Uo)||this.titleHtml||this.title)?null:this.modalTitleId,"aria-describedby":this.modalBodyId}}},watch:a({},ub,(function(t,e){t!==e&&this[t?"show":"hide"]()})),created:function(){this.$_observer=null,this.$_returnFocus=this.returnFocus||null},mounted:function(){this.zIndex=sb.getBaseZIndex(),this.listenOnRoot(Fs(Ni,to),this.showHandler),this.listenOnRoot(Fs(Ni,Nn),this.hideHandler),this.listenOnRoot(Fs(Ni,no),this.toggleHandler),this.listenOnRoot(Ds(Ni,to),this.modalListener),!0===this[ub]&&this.$nextTick(this.show)},beforeDestroy:function(){this.setObserver(!1),this.isVisible&&(this.isVisible=!1,this.isShow=!1,this.isTransitioning=!1)},methods:{setObserver:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.$_observer&&this.$_observer.disconnect(),this.$_observer=null,t&&(this.$_observer=au(this.$refs.content,this.checkModalOverflow.bind(this),bb))},updateModel:function(t){t!==this[ub]&&this.$emit(db,t)},buildEvent:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new BvModalEvent(t,c(c({cancelable:!1,target:this.$refs.modal||this.$el||null,relatedTarget:null,trigger:null},e),{},{vueTarget:this,componentId:this.modalId}))},show:function(){if(!this.isVisible&&!this.isOpening)if(this.isClosing)this.$once(zn,this.show);else{this.isOpening=!0,this.$_returnFocus=this.$_returnFocus||this.getActiveElement();var t=this.buildEvent(to,{cancelable:!0});if(this.emitEvent(t),t.defaultPrevented||this.isVisible)return this.isOpening=!1,void this.updateModel(!1);this.doShow()}},hide:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(this.isVisible&&!this.isClosing){this.isClosing=!0;var e=this.buildEvent(Nn,{cancelable:t!==hb,trigger:t||null});if(t===mb?this.$emit("ok",e):t===fb?this.$emit(kn,e):t===pb&&this.$emit(_n,e),this.emitEvent(e),e.defaultPrevented||!this.isVisible)return this.isClosing=!1,void this.updateModel(!0);this.setObserver(!1),this.isVisible=!1,this.updateModel(!1)}},toggle:function(t){t&&(this.$_returnFocus=t),this.isVisible?this.hide("toggle"):this.show()},getActiveElement:function(){var t=$r(M?[document.body]:[]);return t&&t.focus?t:null},doShow:function(){var t=this;sb.modalsAreOpen&&this.noStacking?this.listenOnRootOnce(Ds(Ni,zn),this.doShow):(sb.registerModal(this),this.isHidden=!1,this.$nextTick((function(){t.isVisible=!0,t.isOpening=!1,t.updateModel(!0),t.$nextTick((function(){t.setObserver(!0)}))})))},onBeforeEnter:function(){this.isTransitioning=!0,this.setResizeEvent(!0)},onEnter:function(){var t=this;this.isBlock=!0,xr((function(){xr((function(){t.isShow=!0}))}))},onAfterEnter:function(){var t=this;this.checkModalOverflow(),this.isTransitioning=!1,xr((function(){t.emitEvent(t.buildEvent(eo)),t.setEnforceFocus(!0),t.$nextTick((function(){t.focusFirst()}))}))},onBeforeLeave:function(){this.isTransitioning=!0,this.setResizeEvent(!1),this.setEnforceFocus(!1)},onLeave:function(){this.isShow=!1},onAfterLeave:function(){var t=this;this.isBlock=!1,this.isTransitioning=!1,this.isModalOverflowing=!1,this.isHidden=!0,this.$nextTick((function(){t.isClosing=!1,sb.unregisterModal(t),t.returnFocusTo(),t.emitEvent(t.buildEvent(zn))}))},emitEvent:function(t){var e=t.type;this.emitOnRoot(Ds(Ni,e),t,t.componentId),this.$emit(e,t)},onDialogMousedown:function(){var t=this,e=this.$refs.modal;Ss(e,"mouseup",(function i(n){ks(e,"mouseup",i,lo),n.target===e&&(t.ignoreBackdropClick=!0)}),lo)},onClickOut:function(t){this.ignoreBackdropClick?this.ignoreBackdropClick=!1:this.isVisible&&!this.noCloseOnBackdrop&&Lr(document.body,t.target)&&(Lr(this.$refs.content,t.target)||this.hide("backdrop"))},onOk:function(){this.hide(mb)},onCancel:function(){this.hide(fb)},onClose:function(){this.hide(pb)},onEsc:function(t){27===t.keyCode&&this.isVisible&&!this.noCloseOnEsc&&this.hide("esc")},focusHandler:function(t){var e=this.$refs.content,i=t.target;if(!(this.noEnforceFocus||!this.isTop||!this.isVisible||!e||document===i||Lr(e,i)||this.computeIgnoreEnforceFocusSelector&&Er(this.computeIgnoreEnforceFocusSelector,i,!0))){var n=Qr(this.$refs.content),o=this.$refs["bottom-trap"],r=this.$refs["top-trap"];if(o&&i===o){if(ts(n[0]))return}else if(r&&i===r&&ts(n[n.length-1]))return;ts(e,{preventScroll:!0})}},setEnforceFocus:function(t){this.listenDocument(t,"focusin",this.focusHandler)},setResizeEvent:function(t){this.listenWindow(t,"resize",this.checkModalOverflow),this.listenWindow(t,"orientationchange",this.checkModalOverflow)},showHandler:function(t,e){t===this.modalId&&(this.$_returnFocus=e||this.getActiveElement(),this.show())},hideHandler:function(t){t===this.modalId&&this.hide("event")},toggleHandler:function(t,e){t===this.modalId&&this.toggle(e)},modalListener:function(t){this.noStacking&&t.vueTarget!==this&&this.hide()},focusFirst:function(){var t=this;M&&xr((function(){var e=t.$refs.modal,i=t.$refs.content,n=t.getActiveElement();if(e&&i&&(!n||!Lr(i,n))){var o=t.$refs["ok-button"],r=t.$refs["cancel-button"],s=t.$refs["close-button"],a=t.autoFocusButton,l=a===mb&&o?o.$el||o:a===fb&&r?r.$el||r:a===pb&&s?s.$el||s:i;ts(l),l===i&&t.$nextTick((function(){e.scrollTop=0}))}}))},returnFocusTo:function(){var t=this.returnFocus||this.$_returnFocus||null;this.$_returnFocus=null,this.$nextTick((function(){(t=Et(t)?Or(t):t)&&(t=t.$el||t,ts(t))}))},checkModalOverflow:function(){if(this.isVisible){var t=this.$refs.modal;this.isModalOverflowing=t.scrollHeight>document.documentElement.clientHeight}},makeModal:function(t){var e=t();if(!this.hideHeader){var i=this.normalizeSlot("modal-header",this.slotScope);if(!i){var n=t();this.hideHeaderClose||(n=t(Ps,{props:{content:this.headerCloseContent,disabled:this.isTransitioning,ariaLabel:this.headerCloseLabel,textVariant:this.headerCloseVariant||this.headerTextVariant},on:{click:this.onClose},ref:"close-button"},[this.normalizeSlot("modal-header-close")])),i=[t(this.titleTag,{staticClass:"modal-title",class:this.titleClasses,attrs:{id:this.modalTitleId},domProps:this.hasNormalizedSlot(Uo)?{}:Fl(this.titleHtml,this.title)},this.normalizeSlot(Uo,this.slotScope)),n]}e=t("header",{staticClass:"modal-header",class:this.headerClasses,attrs:{id:this.modalHeaderId},ref:"header"},[i])}var o=t("div",{staticClass:"modal-body",class:this.bodyClasses,attrs:{id:this.modalBodyId},ref:"body"},this.normalizeSlot(Ao,this.slotScope)),r=t();if(!this.hideFooter){var s=this.normalizeSlot("modal-footer",this.slotScope);if(!s){var a=t();this.okOnly||(a=t(ml,{props:{variant:this.cancelVariant,size:this.buttonSize,disabled:this.cancelDisabled||this.busy||this.isTransitioning},domProps:this.hasNormalizedSlot(Wo)?{}:Fl(this.cancelTitleHtml,this.cancelTitle),on:{click:this.onCancel},ref:"cancel-button"},this.normalizeSlot(Wo))),s=[a,t(ml,{props:{variant:this.okVariant,size:this.buttonSize,disabled:this.okDisabled||this.busy||this.isTransitioning},domProps:this.hasNormalizedSlot(Yo)?{}:Fl(this.okTitleHtml,this.okTitle),on:{click:this.onOk},ref:"ok-button"},this.normalizeSlot(Yo))]}r=t("footer",{staticClass:"modal-footer",class:this.footerClasses,attrs:{id:this.modalFooterId},ref:"footer"},[s])}var l=t("div",{staticClass:"modal-content",class:this.contentClass,attrs:{id:this.modalContentId,tabindex:"-1"},ref:"content"},[e,o,r]),c=t(),u=t();this.isVisible&&!this.noEnforceFocus&&(c=t("span",{attrs:{tabindex:"0"},ref:"top-trap"}),u=t("span",{attrs:{tabindex:"0"},ref:"bottom-trap"}));var d=t("div",{staticClass:"modal-dialog",class:this.dialogClasses,on:{mousedown:this.onDialogMousedown},ref:"dialog"},[c,l,u]),h=t("div",{staticClass:"modal",class:this.modalClasses,style:this.modalStyles,attrs:this.computedModalAttrs,on:{keydown:this.onEsc,click:this.onClickOut},directives:[{name:"show",value:this.isVisible}],ref:"modal"},[d]);h=t("transition",{props:{enterClass:"",enterToClass:"",enterActiveClass:"",leaveClass:"",leaveActiveClass:"",leaveToClass:""},on:{beforeEnter:this.onBeforeEnter,enter:this.onEnter,afterEnter:this.onAfterEnter,beforeLeave:this.onBeforeLeave,leave:this.onLeave,afterLeave:this.onAfterLeave}},[h]);var f=t();return!this.hideBackdrop&&this.isVisible&&(f=t("div",{staticClass:"modal-backdrop",attrs:{id:this.modalBackdropId}},this.normalizeSlot("modal-backdrop"))),f=t(Ls,{props:{noFade:this.noFade}},[f]),t("div",{style:this.modalOuterStyle,attrs:this.computedAttrs,key:"modal-outer-".concat(this._uid)},[h,f])}},render:function(t){return this.static?this.lazy&&this.isHidden?t():this.makeModal(t):this.isHidden?t():t(rb,[this.makeModal(t)])}}),wb=Fs(Ni,to),Tb="__bv_modal_directive__",Cb=function(t){var e=t.modifiers,i=void 0===e?{}:e,n=t.arg,o=t.value;return Et(o)?o:Et(n)?n:Kt(i).reverse()[0]},xb=function(t){return t&&Vr(t,".dropdown-menu > li, li.nav-item")&&Or("a, button",t)||t},Sb=function(t){t&&"BUTTON"!==t.tagName&&(Gr(t,"role")||zr(t,"role","button"),"A"===t.tagName||Gr(t,"tabindex")||zr(t,"tabindex","0"))},kb=function(t){var e=t[Tb]||{},i=e.trigger,n=e.handler;i&&n&&(ks(i,"click",n,ao),ks(i,"keydown",n,ao),ks(t,"click",n,ao),ks(t,"keydown",n,ao)),delete t[Tb]},$b=function(t,e,i){var n=t[Tb]||{},o=Cb(e),r=xb(t);o===n.target&&r===n.trigger||(kb(t),function(t,e,i){var n=Cb(e),o=xb(t);if(n&&o){var r=function(t){var e=t.currentTarget;if(!Fr(e)){var o=t.type,r=t.keyCode;"click"!==o&&("keydown"!==o||r!==Ha&&r!==Ga)||i.context.$root.$emit(wb,n,e)}};t[Tb]={handler:r,target:n,trigger:o},Sb(o),Ss(o,"click",r,ao),"BUTTON"!==o.tagName&&"button"===jr(o,"role")&&Ss(o,"keydown",r,ao)}}(t,e,i)),Sb(r)},Bb={inserted:$b,updated:function(){},componentUpdated:$b,unbind:kb},_b="$bvModal",Db=["id"].concat(T(Kt(Qt(gb,["busy","lazy","noStacking","static","visible"])))),Fb=function(){},Ib={msgBoxContent:"default",title:"modal-title",okTitle:"modal-ok",cancelTitle:"modal-cancel"},Pb=function(t){return Db.reduce((function(e,i){return Ft(t[i])||(e[i]=t[i]),e}),{})},Ob=me({components:{BModal:yb},directives:{VBModal:Bb},plugins:{BVModalPlugin:me({plugins:{plugin:function(t){var e=t.extend({name:"BMsgBox",extends:yb,destroyed:function(){this.$el&&this.$el.parentNode&&this.$el.parentNode.removeChild(this.$el)},mounted:function(){var t=this,e=function(){t.$nextTick((function(){xr((function(){t.$destroy()}))}))};this.$parent.$once(ro,e),this.$once(zn,e),this.$router&&this.$route&&this.$once(oo,this.$watch("$router",e)),this.show()}}),i=function(t,i){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Fb;if(!ce(_b)&&!ue(_b)){var o=new e({parent:t,propsData:c(c(c({},Pb(rs(Ni))),{},{hideHeaderClose:!0,hideHeader:!(i.title||i.titleHtml)},Qt(i,Kt(Ib))),{},{lazy:!1,busy:!1,visible:!1,noStacking:!1,noEnforceFocus:!1})});return Kt(Ib).forEach((function(t){Ft(i[t])||(o.$slots[Ib[t]]=or(i[t]))})),new Promise((function(t,e){var i=!1;o.$once(ro,(function(){i||e(new Error("BootstrapVue MsgBox destroyed before resolve"))})),o.$on(Nn,(function(e){if(!e.defaultPrevented){var o=n(e);e.defaultPrevented||(i=!0,t(o))}}));var r=document.createElement("div");document.body.appendChild(r),o.$mount(r)}))}},n=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(e&&!ue(_b)&&!ce(_b)&&Ot(o))return i(t,c(c({},Pb(n)),{},{msgBoxContent:e}),o)},r=function(){function t(e){o(this,t),Gt(this,{_vm:e,_root:e.$root}),Yt(this,{_vm:{enumerable:!0,configurable:!1,writable:!1},_root:{enumerable:!0,configurable:!1,writable:!1}})}return s(t,[{key:"show",value:function(t){if(t&&this._root){for(var e,i=arguments.length,n=new Array(i>1?i-1:0),o=1;o<i;o++)n[o-1]=arguments[o];(e=this._root).$emit.apply(e,[Fs(Ni,"show"),t].concat(n))}}},{key:"hide",value:function(t){if(t&&this._root){for(var e,i=arguments.length,n=new Array(i>1?i-1:0),o=1;o<i;o++)n[o-1]=arguments[o];(e=this._root).$emit.apply(e,[Fs(Ni,"hide"),t].concat(n))}}},{key:"msgBoxOk",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=c(c({},e),{},{okOnly:!0,okDisabled:!1,hideFooter:!1,msgBoxContent:t});return n(this._vm,t,i,(function(){return!0}))}},{key:"msgBoxConfirm",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=c(c({},e),{},{okOnly:!1,okDisabled:!1,cancelDisabled:!1,hideFooter:!1});return n(this._vm,t,i,(function(t){var e=t.trigger;return"ok"===e||"cancel"!==e&&null}))}}]),t}();t.mixin({beforeCreate:function(){this._bv__modal=new r(this)}}),Xt(t.prototype,_b)||Ut(t.prototype,_b,{get:function(){return this&&this._bv__modal||le('"'.concat(_b,'" must be accessed from a Vue instance "this" context.'),Ni),this._bv__modal}})}}})}}),Vb=vs({align:hs(go),cardHeader:hs(ho,!1),fill:hs(ho,!1),justified:hs(ho,!1),pills:hs(ho,!1),small:hs(ho,!1),tabs:hs(ho,!1),tag:hs(go,"ul"),vertical:hs(ho,!1)},ji),Eb=i.default.extend({name:ji,functional:!0,props:Vb,render:function(t,e){var i,n,o=e.props,r=e.data,s=e.children,l=o.tabs,c=o.pills,u=o.vertical,d=o.align,h=o.cardHeader;return t(o.tag,F(r,{staticClass:"nav",class:(i={"nav-tabs":l,"nav-pills":c&&!l,"card-header-tabs":!u&&h&&l,"card-header-pills":!u&&h&&c&&!l,"flex-column":u,"nav-fill":!u&&o.fill,"nav-justified":!u&&o.justified},a(i,(n=d,"justify-content-".concat(n="left"===n?"start":"right"===n?"end":n)),!u&&d),a(i,"small",o.small),i)}),s)}}),Lb=Qt(nl,["event","routerTag"]),Ab=vs(ee(c(c({},Lb),{},{linkAttrs:hs(vo,{}),linkClasses:hs(To)})),Ki),Rb=i.default.extend({name:Ki,functional:!0,props:Ab,render:function(t,e){var i=e.props,n=e.data,o=e.listeners,r=e.children;return t("li",F(Qt(n,["on"]),{staticClass:"nav-item"}),[t(ol,{staticClass:"nav-link",class:i.linkClasses,attrs:i.linkAttrs,props:ps(Lb,i),on:o},r)])}}),Mb=i.default.extend({name:"BNavText",functional:!0,props:{},render:function(t,e){var i=e.data,n=e.children;return t("li",F(i,{staticClass:"navbar-text"}),n)}}),Hb=Qt(Yh,["inline"]),zb=vs(ee(c(c({},Hb),{},{formClass:hs(To)})),qi),Nb=i.default.extend({name:qi,functional:!0,props:zb,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=e.listeners,s=t(Uh,{class:i.formClass,props:c(c({},ps(Hb,i)),{},{inline:!0}),attrs:n.attrs,on:r},o);return t("li",F(Qt(n,["attrs","on"]),{staticClass:"form-inline"}),[s])}}),jb=vs(ee(c(c({},fc),Jt(Eh,[].concat(T(Kt(Oh)),["html","lazy","menuClass","noCaret","role","text","toggleClass"])))),Xi),Gb=i.default.extend({name:Xi,mixins:[pc,Vh,Cs],props:jb,computed:{toggleId:function(){return this.safeId("_BV_toggle_")},dropdownClasses:function(){return[this.directionClass,this.boundaryClass,{show:this.visible}]},menuClasses:function(){return[this.menuClass,{"dropdown-menu-right":this.right,show:this.visible}]},toggleClasses:function(){return[this.toggleClass,{"dropdown-toggle-no-caret":this.noCaret}]}},render:function(t){var e=this.toggleId,i=this.visible,n=this.hide,o=t(ol,{staticClass:"nav-link dropdown-toggle",class:this.toggleClasses,props:{href:"#".concat(this.id||""),disabled:this.disabled},attrs:{id:e,role:"button","aria-haspopup":"true","aria-expanded":i?"true":"false"},on:{mousedown:this.onMousedown,click:this.toggle,keydown:this.toggle},ref:"toggle"},[this.normalizeSlot([Eo,"text"])||t("span",{domProps:Fl(this.html,this.text)})]),r=t("ul",{staticClass:"dropdown-menu",class:this.menuClasses,attrs:{tabindex:"-1","aria-labelledby":e},on:{keydown:this.onKeydown},ref:"menu"},!this.lazy||i?this.normalizeSlot(Ao,{hide:n}):[t()]);return t("li",{staticClass:"nav-item b-nav-dropdown dropdown",class:this.dropdownClasses,attrs:{id:this.safeId()}},[o,r])}}),Wb=me({components:{BNav:Eb,BNavItem:Rb,BNavText:Mb,BNavForm:Nb,BNavItemDropdown:Gb,BNavItemDd:Gb,BNavDropdown:Gb,BNavDd:Gb},plugins:{DropdownPlugin:tf}}),Yb=vs({fixed:hs(go),print:hs(ho,!1),sticky:hs(ho,!1),tag:hs(go,"nav"),toggleable:hs(ko,!1),type:hs(go,"light"),variant:hs(go)},Gi),Ub=i.default.extend({name:Gi,mixins:[Cs],provide:function(){return{bvNavbar:this}},props:Yb,computed:{breakpointClass:function(){var t=this.toggleable,e=ss()[0],i=null;return t&&Et(t)&&t!==e?i="navbar-expand-".concat(t):!1===t&&(i="navbar-expand"),i}},render:function(t){var e,i=this.tag,n=this.type,o=this.variant,r=this.fixed;return t(i,{staticClass:"navbar",class:[(e={"d-print":this.print,"sticky-top":this.sticky},a(e,"navbar-".concat(n),n),a(e,"bg-".concat(o),o),a(e,"fixed-".concat(r),r),e),this.breakpointClass],attrs:{role:Br(i,"nav")?null:"navigation"}},[this.normalizeSlot()])}}),qb=vs(Jt(Vb,["tag","fill","justified","align","small"]),Yi),Kb=i.default.extend({name:Yi,functional:!0,props:qb,render:function(t,e){var i,n,o=e.props,r=e.data,s=e.children,l=o.align;return t(o.tag,F(r,{staticClass:"navbar-nav",class:(i={"nav-fill":o.fill,"nav-justified":o.justified},a(i,(n=l,"justify-content-".concat(n="left"===n?"start":"right"===n?"end":n)),l),a(i,"small",o.small),i)}),s)}}),Xb=Qt(nl,["event","routerTag"]);Xb.href.default=void 0,Xb.to.default=void 0;var Zb,Jb,Qb,tg,eg,ig,ng,og,rg,sg=vs(ee(c(c({},Xb),{},{tag:hs(go,"div")})),Wi),ag=i.default.extend({name:Wi,functional:!0,props:sg,render:function(t,e){var i=e.props,n=e.data,o=e.children,r=i.to||i.href;return t(r?ol:i.tag,F(n,{staticClass:"navbar-brand",props:r?ps(Xb,i):{}}),o)}}),lg="navbar-toggler",cg=Ds(Ue,"state"),ug=Ds(Ue,"sync-state"),dg=vs({disabled:hs(ho,!1),label:hs(go,"Toggle navigation"),target:hs(Co,void 0,!0)},Ui),hg=i.default.extend({name:Ui,directives:{VBToggle:ad},mixins:[Ja,Cs],props:dg,data:function(){return{toggleState:!1}},created:function(){this.listenOnRoot(cg,this.handleStateEvt),this.listenOnRoot(ug,this.handleStateEvt)},methods:{onClick:function(t){this.disabled||this.$emit(Bn,t)},handleStateEvt:function(t,e){t===this.target&&(this.toggleState=e)}},render:function(t){var e=this.disabled;return t("button",{staticClass:lg,class:{disabled:e},directives:[{name:"VBToggle",value:this.target}],attrs:{type:"button",disabled:e,"aria-label":this.label},on:{click:this.onClick}},[this.normalizeSlot(Ao,{expanded:this.toggleState})||t("span",{staticClass:"".concat(lg,"-icon")})])}}),fg=me({components:{BNavbar:Ub,BNavbarNav:Kb,BNavbarBrand:ag,BNavbarToggle:hg,BNavToggle:hg},plugins:{NavPlugin:Wb,CollapsePlugin:cd,DropdownPlugin:tf}}),pg=vs({label:hs(go),role:hs(go,"status"),small:hs(ho,!1),tag:hs(go,"span"),type:hs(go,"border"),variant:hs(go)},dn),mg=i.default.extend({name:dn,functional:!0,props:pg,render:function(t,e){var i,n=e.props,o=e.data,r=e.slots,s=e.scopedSlots,l=r(),c=Ts(jo,{},s||{},l)||n.label;return c&&(c=t("span",{staticClass:"sr-only"},c)),t(n.tag,F(o,{attrs:{role:c?n.role||"status":null,"aria-hidden":c?null:"true"},class:(i={},a(i,"spinner-".concat(n.type),n.type),a(i,"spinner-".concat(n.type,"-sm"),n.small),a(i,"text-".concat(n.variant),n.variant),i)}),[c||t()])}}),vg={top:0,left:0,bottom:0,right:0},bg=vs({bgColor:hs(go),blur:hs(go,"2px"),fixed:hs(ho,!1),noCenter:hs(ho,!1),noFade:hs(ho,!1),noWrap:hs(ho,!1),opacity:hs(_o,.85,(function(t){var e=cr(t,0);return e>=0&&e<=1})),overlayTag:hs(go,"div"),rounded:hs(ko,!1),show:hs(ho,!1),spinnerSmall:hs(ho,!1),spinnerType:hs(go,"border"),spinnerVariant:hs(go),variant:hs(go,"light"),wrapTag:hs(go,"div"),zIndex:hs(_o,10)},Zi),gg=i.default.extend({name:Zi,mixins:[Cs],props:bg,computed:{computedRounded:function(){var t=this.rounded;return!0===t||""===t?"rounded":t?"rounded-".concat(t):""},computedVariant:function(){var t=this.variant;return t&&!this.bgColor?"bg-".concat(t):""},slotScope:function(){return{spinnerType:this.spinnerType||null,spinnerVariant:this.spinnerVariant||null,spinnerSmall:this.spinnerSmall}}},methods:{defaultOverlayFn:function(t){var e=t.spinnerType,i=t.spinnerVariant,n=t.spinnerSmall;return this.$createElement(mg,{props:{type:e,variant:i,small:n}})}},render:function(t){var e=this,i=this.show,n=this.fixed,o=this.noFade,r=this.noWrap,s=this.slotScope,a=t();if(i){var l=t("div",{staticClass:"position-absolute",class:[this.computedVariant,this.computedRounded],style:c(c({},vg),{},{opacity:this.opacity,backgroundColor:this.bgColor||null,backdropFilter:this.blur?"blur(".concat(this.blur,")"):null})}),u=t("div",{staticClass:"position-absolute",style:this.noCenter?c({},vg):{top:"50%",left:"50%",transform:"translateX(-50%) translateY(-50%)"}},[this.normalizeSlot("overlay",s)||this.defaultOverlayFn(s)]);a=t(this.overlayTag,{staticClass:"b-overlay",class:{"position-absolute":!r||r&&!n,"position-fixed":r&&n},style:c(c({},vg),{},{zIndex:this.zIndex||10}),on:{click:function(t){return e.$emit(Bn,t)}},key:"overlay"},[l,u])}return a=t(Ls,{props:{noFade:o,appear:!0},on:{"after-enter":function(){return e.$emit(eo)},"after-leave":function(){return e.$emit(zn)}}},[a]),r?a:t(this.wrapTag,{staticClass:"b-overlay-wrap position-relative",attrs:{"aria-busy":i?"true":null}},r?[a]:[this.normalizeSlot(),a])}}),yg=me({components:{BOverlay:gg}}),wg=ys("value",{type:So,defaultValue:null,validator:function(t){return!(!It(t)&&lr(t,0)<1)||(le('"v-model" value must be a number greater than "0"',Ji),!1)}}),Tg=wg.mixin,Cg=wg.props,xg=wg.prop,Sg=wg.event,kg=function(t){var e=lr(t)||1;return e<1?5:e},$g=function(t,e){var i=lr(t)||1;return i>e?e:i<1?1:i},Bg=function(t){if(t.keyCode===Ga)return Bs(t,{immediatePropagation:!0}),t.currentTarget.click(),!1},_g=vs(ee(c(c({},Cg),{},{align:hs(go,"left"),ariaLabel:hs(go,"Pagination"),disabled:hs(ho,!1),ellipsisClass:hs(To),ellipsisText:hs(go,"â€Ļ"),firstClass:hs(To),firstNumber:hs(ho,!1),firstText:hs(go,"ÂĢ"),hideEllipsis:hs(ho,!1),hideGotoEndButtons:hs(ho,!1),labelFirstPage:hs(go,"Go to first page"),labelLastPage:hs(go,"Go to last page"),labelNextPage:hs(go,"Go to next page"),labelPage:hs(Bo,"Go to page"),labelPrevPage:hs(go,"Go to previous page"),lastClass:hs(To),lastNumber:hs(ho,!1),lastText:hs(go,"Âģ"),limit:hs(_o,5,(function(t){return!(lr(t,0)<1)||(le('Prop "limit" must be a number greater than "0"',Ji),!1)})),nextClass:hs(To),nextText:hs(go,"â€ē"),pageClass:hs(To),pills:hs(ho,!1),prevClass:hs(To),prevText:hs(go,"‹"),size:hs(go)})),"pagination"),Dg=i.default.extend({mixins:[Tg,Cs],props:_g,data:function(){var t=lr(this[xg],0);return{currentPage:t=t>0?t:-1,localNumberOfPages:1,localLimit:5}},computed:{btnSize:function(){var t=this.size;return t?"pagination-".concat(t):""},alignment:function(){var t=this.align;return"center"===t?"justify-content-center":"end"===t||"right"===t?"justify-content-end":"fill"===t?"text-center":""},styleClass:function(){return this.pills?"b-pagination-pills":""},computedCurrentPage:function(){return $g(this.currentPage,this.localNumberOfPages)},paginationParams:function(){var t=this.localLimit,e=this.localNumberOfPages,i=this.computedCurrentPage,n=this.hideEllipsis,o=this.firstNumber,r=this.lastNumber,s=!1,a=!1,l=t,c=1;e<=t?l=e:i<t-1&&t>3?(n&&!r||(a=!0,l=t-(o?0:1)),l=Ys(l,t)):e-i+2<t&&t>3?(n&&!o||(s=!0,l=t-(r?0:1)),c=e-l+1):(t>3&&(l=t-(n?0:2),s=!(n&&!o),a=!(n&&!r)),c=i-Xs(l/2)),c<1?(c=1,s=!1):c>e-l&&(c=e-l+1,a=!1),s&&o&&c<4&&(l+=2,c=1,s=!1);var u=c+l-1;return a&&r&&u>e-3&&(l+=u===e-2?2:3,a=!1),t<=3&&(o&&1===c?l=Ys(l+1,e,t+1):r&&e===c+l-1&&(c=Us(c-1,1),l=Ys(e-c+1,e,t+1))),{showFirstDots:s,showLastDots:a,numberOfLinks:l=Ys(l,e-c+1),startNumber:c}},pageList:function(){var t=this.paginationParams,e=t.numberOfLinks,i=t.startNumber,n=this.computedCurrentPage,o=function(t,e){return rr(e,(function(e,i){return{number:t+i,classes:null}}))}(i,e);if(o.length>3){var r=n-i,s="bv-d-xs-down-none";if(0===r)for(var a=3;a<o.length;a++)o[a].classes=s;else if(r===o.length-1)for(var l=0;l<o.length-3;l++)o[l].classes=s;else{for(var c=0;c<r-1;c++)o[c].classes=s;for(var u=o.length-1;u>r+1;u--)o[u].classes=s}}return o}},watch:(Zb={},a(Zb,xg,(function(t,e){t!==e&&(this.currentPage=$g(t,this.localNumberOfPages))})),a(Zb,"currentPage",(function(t,e){t!==e&&this.$emit(Sg,t>0?t:null)})),a(Zb,"limit",(function(t,e){t!==e&&(this.localLimit=kg(t))})),Zb),created:function(){var t=this;this.localLimit=kg(this.limit),this.$nextTick((function(){t.currentPage=t.currentPage>t.localNumberOfPages?t.localNumberOfPages:t.currentPage}))},methods:{handleKeyNav:function(t){var e=t.keyCode,i=t.shiftKey;this.isNav||(e===Na||e===Wa?(Bs(t,{propagation:!1}),i?this.focusFirst():this.focusPrev()):e!==ja&&e!==Ra||(Bs(t,{propagation:!1}),i?this.focusLast():this.focusNext()))},getButtons:function(){return Pr("button.page-link, a.page-link",this.$el).filter((function(t){return Dr(t)}))},focusCurrent:function(){var t=this;this.$nextTick((function(){var e=t.getButtons().find((function(e){return lr(jr(e,"aria-posinset"),0)===t.computedCurrentPage}));ts(e)||t.focusFirst()}))},focusFirst:function(){var t=this;this.$nextTick((function(){var e=t.getButtons().find((function(t){return!Fr(t)}));ts(e)}))},focusLast:function(){var t=this;this.$nextTick((function(){var e=t.getButtons().reverse().find((function(t){return!Fr(t)}));ts(e)}))},focusPrev:function(){var t=this;this.$nextTick((function(){var e=t.getButtons(),i=e.indexOf($r());i>0&&!Fr(e[i-1])&&ts(e[i-1])}))},focusNext:function(){var t=this;this.$nextTick((function(){var e=t.getButtons(),i=e.indexOf($r());i<e.length-1&&!Fr(e[i+1])&&ts(e[i+1])}))}},render:function(t){var e=this,i=this.disabled,n=this.labelPage,o=this.ariaLabel,r=this.isNav,s=this.localNumberOfPages,a=this.computedCurrentPage,l=this.pageList.map((function(t){return t.number})),c=this.paginationParams,u=c.showFirstDots,d=c.showLastDots,h="fill"===this.align,f=[],p=function(t){return t===a},m=this.currentPage<1,v=function(n,o,a,l,c,u,d){var f=i||p(u)||m||n<1||n>s,v=n<1?1:n>s?s:n,b={disabled:f,page:v,index:v-1},g=e.normalizeSlot(a,b)||vr(l)||t(),y=t(f?"span":r?ol:"button",{staticClass:"page-link",class:{"flex-grow-1":!r&&!f&&h},props:f||!r?{}:e.linkProps(n),attrs:{role:r?null:"menuitem",type:r||f?null:"button",tabindex:f||r?null:"-1","aria-label":o,"aria-controls":e.ariaControls||null,"aria-disabled":f?"true":null},on:f?{}:{"!click":function(t){e.onClick(t,n)},keydown:Bg}},[g]);return t("li",{key:d,staticClass:"page-item",class:[{disabled:f,"flex-fill":h,"d-flex":h&&!r&&!f},c],attrs:{role:r?null:"presentation","aria-hidden":f?"true":null}},[y])},b=function(i){return t("li",{staticClass:"page-item",class:["disabled","bv-d-xs-down-none",h?"flex-fill":"",e.ellipsisClass],attrs:{role:"separator"},key:"ellipsis-".concat(i?"last":"first")},[t("span",{staticClass:"page-link"},[e.normalizeSlot("ellipsis-text")||vr(e.ellipsisText)||t()])])},g=function(o,a){var l=o.number,c=p(l)&&!m,u=i?null:c||m&&0===a?"0":"-1",d={role:r?null:"menuitemradio",type:r||i?null:"button","aria-disabled":i?"true":null,"aria-controls":e.ariaControls||null,"aria-label":gs(n)?n(l):"".concat(Ot(n)?n():n," ").concat(l),"aria-checked":r?null:c?"true":"false","aria-current":r&&c?"page":null,"aria-posinset":r?null:l,"aria-setsize":r?null:s,tabindex:r?null:u},f=vr(e.makePage(l)),v={page:l,index:l-1,content:f,active:c,disabled:i},b=t(i?"span":r?ol:"button",{props:i||!r?{}:e.linkProps(l),staticClass:"page-link",class:{"flex-grow-1":!r&&!i&&h},attrs:d,on:i?{}:{"!click":function(t){e.onClick(t,l)},keydown:Bg}},[e.normalizeSlot("page",v)||f]);return t("li",{staticClass:"page-item",class:[{disabled:i,active:c,"flex-fill":h,"d-flex":h&&!r&&!i},o.classes,e.pageClass],attrs:{role:r?null:"presentation"},key:"page-".concat(l)},[b])},y=t();this.firstNumber||this.hideGotoEndButtons||(y=v(1,this.labelFirstPage,"first-text",this.firstText,this.firstClass,1,"pagination-goto-first")),f.push(y),f.push(v(a-1,this.labelPrevPage,"prev-text",this.prevText,this.prevClass,1,"pagination-goto-prev")),f.push(this.firstNumber&&1!==l[0]?g({number:1},0):t()),f.push(u?b(!1):t()),this.pageList.forEach((function(t,i){var n=u&&e.firstNumber&&1!==l[0]?1:0;f.push(g(t,i+n))})),f.push(d?b(!0):t()),f.push(this.lastNumber&&l[l.length-1]!==s?g({number:s},-1):t()),f.push(v(a+1,this.labelNextPage,"next-text",this.nextText,this.nextClass,s,"pagination-goto-next"));var w=t();this.lastNumber||this.hideGotoEndButtons||(w=v(s,this.labelLastPage,"last-text",this.lastText,this.lastClass,s,"pagination-goto-last")),f.push(w);var T=t("ul",{staticClass:"pagination",class:["b-pagination",this.btnSize,this.alignment,this.styleClass],attrs:{role:r?null:"menubar","aria-disabled":i?"true":"false","aria-label":r?null:o||null},on:r?{}:{keydown:this.handleKeyNav},ref:"ul"},f);return r?t("nav",{attrs:{"aria-disabled":i?"true":null,"aria-hidden":i?"true":"false","aria-label":r&&o||null}},[T]):T}}),Fg=function(t){return Us(lr(t)||20,1)},Ig=function(t){return Us(lr(t)||0,0)},Pg=vs(ee(c(c({},_g),{},{ariaControls:hs(go),perPage:hs(_o,20),totalRows:hs(_o,0)})),Ji),Og=i.default.extend({name:Ji,mixins:[Dg],props:Pg,computed:{numberOfPages:function(){var t=Ks(Ig(this.totalRows)/Fg(this.perPage));return t<1?1:t},pageSizeNumberOfPages:function(){return{perPage:Fg(this.perPage),totalRows:Ig(this.totalRows),numberOfPages:this.numberOfPages}}},watch:{pageSizeNumberOfPages:function(t,e){Pt(e)||(t.perPage!==e.perPage&&t.totalRows===e.totalRows||t.numberOfPages!==e.numberOfPages&&this.currentPage>t.numberOfPages)&&(this.currentPage=1),this.localNumberOfPages=t.numberOfPages}},created:function(){var t=this;this.localNumberOfPages=this.numberOfPages;var e=lr(this[xg],0);e>0?this.currentPage=e:this.$nextTick((function(){t.currentPage=0}))},methods:{onClick:function(t,e){var i=this;if(e!==this.currentPage){var n=t.target,o=new BvEvent(Kn,{cancelable:!0,vueTarget:this,target:n});this.$emit(o.type,o,e),o.defaultPrevented||(this.currentPage=e,this.$emit($n,this.currentPage),this.$nextTick((function(){Dr(n)&&i.$el.contains(n)?ts(n):i.focusCurrent()})))}},makePage:function(t){return t},linkProps:function(){return{}}}}),Vg=me({components:{BPagination:Og}}),Eg=Qt(nl,["event","routerTag"]),Lg=vs(ee(c(c(c({},_g),Eg),{},{baseUrl:hs(go,"/"),linkGen:hs(po),noPageDetect:hs(ho,!1),numberOfPages:hs(_o,1,(function(t){return!(lr(t,0)<1)||(le('Prop "number-of-pages" must be a number greater than "0"',Qi),!1)})),pageGen:hs(po),pages:hs(uo),useRouter:hs(ho,!1)})),Qi),Ag=i.default.extend({name:Qi,mixins:[Dg],props:Lg,computed:{isNav:function(){return!0},computedValue:function(){var t=lr(this.value,0);return t<1?null:t}},watch:{numberOfPages:function(){var t=this;this.$nextTick((function(){t.setNumberOfPages()}))},pages:function(){var t=this;this.$nextTick((function(){t.setNumberOfPages()}))}},created:function(){this.setNumberOfPages()},mounted:function(){var t=this;this.$router&&this.$watch("$route",(function(){t.$nextTick((function(){xr((function(){t.guessCurrentPage()}))}))}))},methods:{setNumberOfPages:function(){var t,e=this;Rt(this.pages)&&this.pages.length>0?this.localNumberOfPages=this.pages.length:this.localNumberOfPages=(t=this.numberOfPages,Us(lr(t,0),1)),this.$nextTick((function(){e.guessCurrentPage()}))},onClick:function(t,e){var i=this;if(e!==this.currentPage){var n=t.currentTarget||t.target,o=new BvEvent(Kn,{cancelable:!0,vueTarget:this,target:n});this.$emit(o.type,o,e),o.defaultPrevented||(xr((function(){i.currentPage=e,i.$emit($n,e)})),this.$nextTick((function(){es(n)})))}},getPageInfo:function(t){if(!Rt(this.pages)||0===this.pages.length||Ft(this.pages[t-1])){var e="".concat(this.baseUrl).concat(t);return{link:this.useRouter?{path:e}:e,text:vr(t)}}var i=this.pages[t-1];if(Mt(i)){var n=i.link;return{link:Mt(n)?n:this.useRouter?{path:n}:n,text:vr(i.text||t)}}return{link:vr(i),text:vr(t)}},makePage:function(t){var e=this.pageGen,i=this.getPageInfo(t);return gs(e)?e(t,i):i.text},makeLink:function(t){var e=this.linkGen,i=this.getPageInfo(t);return gs(e)?e(t,i):i.link},linkProps:function(t){var e=ps(Eg,this),i=this.makeLink(t);return this.useRouter||Mt(i)?e.to=i:e.href=i,e},resolveLink:function(){var t,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";try{(t=document.createElement("a")).href=ua({to:e},"a","/","/"),document.body.appendChild(t);var i=t,n=i.pathname,o=i.hash,r=i.search;return document.body.removeChild(t),{path:n,hash:o,query:aa(r)}}catch(e){try{t&&t.parentNode&&t.parentNode.removeChild(t)}catch(t){}return{}}},resolveRoute:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";try{var e=this.$router.resolve(t,this.$route).route;return{path:e.path,hash:e.hash,query:e.query}}catch(t){return{}}},guessCurrentPage:function(){var t=this.$router,e=this.$route,i=this.computedValue;if(!this.noPageDetect&&!i&&(M||!M&&t))for(var n=t&&e?{path:e.path,hash:e.hash,query:e.query}:{},o=M?window.location||document.location:null,r=o?{path:o.pathname,hash:o.hash,query:aa(o.search)}:{},s=1;!i&&s<=this.localNumberOfPages;s++){var a=this.makeLink(s);i=t&&(Mt(a)||this.useRouter)?Ua(this.resolveRoute(a),n)?s:null:M?Ua(this.resolveLink(a),r)?s:null:-1}this.currentPage=i>0?i:0}}}),Rg=me({components:{BPaginationNav:Ag}}),Mg={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left",TOPLEFT:"top",TOPRIGHT:"top",RIGHTTOP:"right",RIGHTBOTTOM:"right",BOTTOMLEFT:"bottom",BOTTOMRIGHT:"bottom",LEFTTOP:"left",LEFTBOTTOM:"left"},Hg={AUTO:0,TOPLEFT:-1,TOP:0,TOPRIGHT:1,RIGHTTOP:-1,RIGHT:0,RIGHTBOTTOM:1,BOTTOMLEFT:-1,BOTTOM:0,BOTTOMRIGHT:1,LEFTTOP:-1,LEFT:0,LEFTBOTTOM:1},zg={arrowPadding:hs(_o,6),boundary:hs([HTMLElement,go],"scrollParent"),boundaryPadding:hs(_o,5),fallbackPlacement:hs(Co,"flip"),offset:hs(_o,0),placement:hs(go,"top"),target:hs([HTMLElement,SVGElement])},Ng=i.default.extend({name:"BVPopper",props:zg,data:function(){return{noFade:!1,localShow:!0,attachment:this.getAttachment(this.placement)}},computed:{templateType:function(){return"unknown"},popperConfig:function(){var t=this,e=this.placement;return{placement:this.getAttachment(e),modifiers:{offset:{offset:this.getOffset(e)},flip:{behavior:this.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{padding:this.boundaryPadding,boundariesElement:this.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t.popperPlacementChange(e)},onUpdate:function(e){t.popperPlacementChange(e)}}}},created:function(){var t=this;this.$_popper=null,this.localShow=!0,this.$on(to,(function(e){t.popperCreate(e)}));var e=function(){t.$nextTick((function(){xr((function(){t.$destroy()}))}))};this.$parent.$once(ro,e),this.$once(zn,e)},beforeMount:function(){this.attachment=this.getAttachment(this.placement)},updated:function(){this.updatePopper()},beforeDestroy:function(){this.destroyPopper()},destroyed:function(){var t=this.$el;t&&t.parentNode&&t.parentNode.removeChild(t)},methods:{hide:function(){this.localShow=!1},getAttachment:function(t){return Mg[String(t).toUpperCase()]||"auto"},getOffset:function(t){if(!this.offset){var e=this.$refs.arrow||Or(".arrow",this.$el),i=cr(Kr(e).width,0)+cr(this.arrowPadding,0);switch(Hg[String(t).toUpperCase()]||0){case 1:return"+50%p - ".concat(i,"px");case-1:return"-50%p + ".concat(i,"px");default:return 0}}return this.offset},popperCreate:function(t){this.destroyPopper(),this.$_popper=new mh(this.target,t,this.popperConfig)},destroyPopper:function(){this.$_popper&&this.$_popper.destroy(),this.$_popper=null},updatePopper:function(){this.$_popper&&this.$_popper.scheduleUpdate()},popperPlacementChange:function(t){this.attachment=this.getAttachment(t.placement)},renderTemplate:function(t){return t("div")}},render:function(t){var e=this,i=this.noFade;return t(Ls,{props:{appear:!0,noFade:i},on:{beforeEnter:function(t){return e.$emit(to,t)},afterEnter:function(t){return e.$emit(eo,t)},beforeLeave:function(t){return e.$emit(Nn,t)},afterLeave:function(t){return e.$emit(zn,t)}}},[this.localShow?this.renderTemplate(t):t()])}}),jg={html:hs(ho,!1),id:hs(go)},Gg=i.default.extend({name:"BVTooltipTemplate",extends:Ng,mixins:[ib],props:jg,data:function(){return{title:"",content:"",variant:null,customClass:null,interactive:!0}},computed:{templateType:function(){return"tooltip"},templateClasses:function(){var t,e=this.variant,i=this.attachment,n=this.templateType;return[(t={noninteractive:!this.interactive},a(t,"b-".concat(n,"-").concat(e),e),a(t,"bs-".concat(n,"-").concat(i),i),t),this.customClass]},templateAttributes:function(){var t=this.id;return c(c({},this.$parent.$parent.$attrs),{},{id:t,role:"tooltip",tabindex:"-1"},this.scopedStyleAttrs)},templateListeners:function(){var t=this;return{mouseenter:function(e){t.$emit(Wn,e)},mouseleave:function(e){t.$emit(Yn,e)},focusin:function(e){t.$emit(Rn,e)},focusout:function(e){t.$emit(Mn,e)}}}},methods:{renderTemplate:function(t){var e=this.title,i=Ot(e)?e({}):e,n=this.html&&!Ot(e)?{innerHTML:e}:{};return t("div",{staticClass:"tooltip b-tooltip",class:this.templateClasses,attrs:this.templateAttributes,on:this.templateListeners},[t("div",{staticClass:"arrow",ref:"arrow"}),t("div",{staticClass:"tooltip-inner",domProps:n},[i])])}}}),Wg=".modal-content",Yg=Ds(Ni,zn),Ug=[Wg,".b-sidebar"].join(", "),qg="data-original-title",Kg={title:"",content:"",variant:null,customClass:null,triggers:"",placement:"auto",fallbackPlacement:"flip",target:null,container:null,noFade:!1,boundary:"scrollParent",boundaryPadding:5,offset:0,delay:0,arrowPadding:6,interactive:!0,disabled:!1,id:null,html:!1},Xg=i.default.extend({name:"BVTooltip",mixins:[Ja],data:function(){return c(c({},Kg),{},{activeTrigger:{hover:!1,click:!1,focus:!1},localShow:!1})},computed:{templateType:function(){return"tooltip"},computedId:function(){return this.id||"__bv_".concat(this.templateType,"_").concat(this._uid,"__")},computedDelay:function(){var t={show:0,hide:0};return Ht(this.delay)?(t.show=Us(lr(this.delay.show,0),0),t.hide=Us(lr(this.delay.hide,0),0)):(Lt(this.delay)||Et(this.delay))&&(t.show=t.hide=Us(lr(this.delay,0),0)),t},computedTriggers:function(){return or(this.triggers).filter(ne).join(" ").trim().toLowerCase().split(/\s+/).sort()},isWithActiveTrigger:function(){for(var t in this.activeTrigger)if(this.activeTrigger[t])return!0;return!1},computedTemplateData:function(){return{title:this.title,content:this.content,variant:this.variant,customClass:this.customClass,noFade:this.noFade,interactive:this.interactive}}},watch:{computedTriggers:function(t,e){var i=this;Ua(t,e)||this.$nextTick((function(){i.unListen(),e.forEach((function(e){nr(t,e)||i.activeTrigger[e]&&(i.activeTrigger[e]=!1)})),i.listen()}))},computedTemplateData:function(){this.handleTemplateUpdate()},title:function(t,e){t===e||t||this.hide()},disabled:function(t){t?this.disable():this.enable()}},created:function(){var t=this;this.$_tip=null,this.$_hoverTimeout=null,this.$_hoverState="",this.$_visibleInterval=null,this.$_enabled=!this.disabled,this.$_noop=su.bind(this),this.$parent&&this.$parent.$once(oo,(function(){t.$nextTick((function(){xr((function(){t.$destroy()}))}))})),this.$nextTick((function(){var e=t.getTarget();e&&Lr(document.body,e)?(t.scopeId=eb(t.$parent),t.listen()):le(Et(t.target)?'Unable to find target element by ID "#'.concat(t.target,'" in document.'):"The provided target is no valid HTML element.",t.templateType)}))},updated:function(){this.$nextTick(this.handleTemplateUpdate)},deactivated:function(){this.forceHide()},beforeDestroy:function(){this.unListen(),this.setWhileOpenListeners(!1),this.clearHoverTimeout(),this.clearVisibilityInterval(),this.destroyTemplate(),this.$_noop=null},methods:{getTemplate:function(){return Gg},updateData:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=!1;Kt(Kg).forEach((function(n){Ft(e[n])||t[n]===e[n]||(t[n]=e[n],"title"===n&&(i=!0))})),i&&this.localShow&&this.fixTitle()},createTemplateAndShow:function(){var t=this.getContainer(),e=this.getTemplate(),i=this.$_tip=new e({parent:this,propsData:{id:this.computedId,html:this.html,placement:this.placement,fallbackPlacement:this.fallbackPlacement,target:this.getPlacementTarget(),boundary:this.getBoundary(),offset:lr(this.offset,0),arrowPadding:lr(this.arrowPadding,0),boundaryPadding:lr(this.boundaryPadding,0)}});this.handleTemplateUpdate(),i.$once(to,this.onTemplateShow),i.$once(eo,this.onTemplateShown),i.$once(Nn,this.onTemplateHide),i.$once(zn,this.onTemplateHidden),i.$once(ro,this.destroyTemplate),i.$on(Rn,this.handleEvent),i.$on(Mn,this.handleEvent),i.$on(Wn,this.handleEvent),i.$on(Yn,this.handleEvent),i.$mount(t.appendChild(document.createElement("div")))},hideTemplate:function(){this.$_tip&&this.$_tip.hide(),this.clearActiveTriggers(),this.$_hoverState=""},destroyTemplate:function(){this.setWhileOpenListeners(!1),this.clearHoverTimeout(),this.$_hoverState="",this.clearActiveTriggers(),this.localPlacementTarget=null;try{this.$_tip.$destroy()}catch(t){}this.$_tip=null,this.removeAriaDescribedby(),this.restoreTitle(),this.localShow=!1},getTemplateElement:function(){return this.$_tip?this.$_tip.$el:null},handleTemplateUpdate:function(){var t=this,e=this.$_tip;if(e){["title","content","variant","customClass","noFade","interactive"].forEach((function(i){e[i]!==t[i]&&(e[i]=t[i])}))}},show:function(){var t=this.getTarget();if(t&&Lr(document.body,t)&&Dr(t)&&!this.dropdownOpen()&&(!Pt(this.title)&&""!==this.title||!Pt(this.content)&&""!==this.content)&&!this.$_tip&&!this.localShow){this.localShow=!0;var e=this.buildEvent(to,{cancelable:!0});this.emitEvent(e),e.defaultPrevented?this.destroyTemplate():(this.fixTitle(),this.addAriaDescribedby(),this.createTemplateAndShow())}},hide:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=this.getTemplateElement();if(e&&this.localShow){var i=this.buildEvent(Nn,{cancelable:!t});this.emitEvent(i),i.defaultPrevented||this.hideTemplate()}else this.restoreTitle()},forceHide:function(){this.getTemplateElement()&&this.localShow&&(this.setWhileOpenListeners(!1),this.clearHoverTimeout(),this.$_hoverState="",this.clearActiveTriggers(),this.$_tip&&(this.$_tip.noFade=!0),this.hide(!0))},enable:function(){this.$_enabled=!0,this.emitEvent(this.buildEvent(En))},disable:function(){this.$_enabled=!1,this.emitEvent(this.buildEvent(On))},onTemplateShow:function(){this.setWhileOpenListeners(!0)},onTemplateShown:function(){var t=this.$_hoverState;this.$_hoverState="","out"===t&&this.leave(null),this.emitEvent(this.buildEvent(eo))},onTemplateHide:function(){this.setWhileOpenListeners(!1)},onTemplateHidden:function(){this.destroyTemplate(),this.emitEvent(this.buildEvent(zn))},getTarget:function(){var t=this.target;return Et(t)?t=Ar(t.replace(/^#/,"")):Ot(t)?t=t():t&&(t=t.$el||t),kr(t)?t:null},getPlacementTarget:function(){return this.getTarget()},getTargetId:function(){var t=this.getTarget();return t&&t.id?t.id:null},getContainer:function(){var t=!!this.container&&(this.container.$el||this.container),e=document.body,i=this.getTarget();return!1===t?Er(Ug,i)||e:Et(t)&&Ar(t.replace(/^#/,""))||e},getBoundary:function(){return this.boundary?this.boundary.$el||this.boundary:"scrollParent"},isInModal:function(){var t=this.getTarget();return t&&Er(Wg,t)},isDropdown:function(){var t=this.getTarget();return t&&Hr(t,"dropdown")},dropdownOpen:function(){var t=this.getTarget();return this.isDropdown()&&t&&Or(".dropdown-menu.show",t)},clearHoverTimeout:function(){clearTimeout(this.$_hoverTimeout),this.$_hoverTimeout=null},clearVisibilityInterval:function(){clearInterval(this.$_visibleInterval),this.$_visibleInterval=null},clearActiveTriggers:function(){for(var t in this.activeTrigger)this.activeTrigger[t]=!1},addAriaDescribedby:function(){var t=this.getTarget(),e=jr(t,"aria-describedby")||"";e=e.split(/\s+/).concat(this.computedId).join(" ").trim(),zr(t,"aria-describedby",e)},removeAriaDescribedby:function(){var t=this,e=this.getTarget(),i=jr(e,"aria-describedby")||"";(i=i.split(/\s+/).filter((function(e){return e!==t.computedId})).join(" ").trim())?zr(e,"aria-describedby",i):Nr(e,"aria-describedby")},fixTitle:function(){var t=this.getTarget();if(Gr(t,"title")){var e=jr(t,"title");zr(t,"title",""),e&&zr(t,qg,e)}},restoreTitle:function(){var t=this.getTarget();if(Gr(t,qg)){var e=jr(t,qg);Nr(t,qg),e&&zr(t,"title",e)}},buildEvent:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new BvEvent(t,c({cancelable:!1,target:this.getTarget(),relatedTarget:this.getTemplateElement()||null,componentId:this.computedId,vueTarget:this},e))},emitEvent:function(t){var e=t.type;this.emitOnRoot(Ds(this.templateType,e),t),this.$emit(e,t)},listen:function(){var t=this,e=this.getTarget();e&&(this.setRootListener(!0),this.computedTriggers.forEach((function(i){"click"===i?Ss(e,"click",t.handleEvent,lo):"focus"===i?(Ss(e,"focusin",t.handleEvent,lo),Ss(e,"focusout",t.handleEvent,lo)):"blur"===i?Ss(e,"focusout",t.handleEvent,lo):"hover"===i&&(Ss(e,"mouseenter",t.handleEvent,lo),Ss(e,"mouseleave",t.handleEvent,lo))}),this))},unListen:function(){var t=this,e=this.getTarget();this.setRootListener(!1),["click","focusin","focusout","mouseenter","mouseleave"].forEach((function(i){e&&ks(e,i,t.handleEvent,lo)}),this)},setRootListener:function(t){var e=this.$root;if(e){var i=t?"$on":"$off",n=this.templateType;e[i](Fs(n,Nn),this.doHide),e[i](Fs(n,to),this.doShow),e[i](Fs(n,Pn),this.doDisable),e[i](Fs(n,Vn),this.doEnable)}},setWhileOpenListeners:function(t){this.setModalListener(t),this.setDropdownListener(t),this.visibleCheck(t),this.setOnTouchStartListener(t)},visibleCheck:function(t){var e=this;this.clearVisibilityInterval();var i=this.getTarget(),n=this.getTemplateElement();t&&(this.$_visibleInterval=setInterval((function(){!n||!e.localShow||i.parentNode&&Dr(i)||e.forceHide()}),100))},setModalListener:function(t){this.isInModal()&&this.$root[t?"$on":"$off"](Yg,this.forceHide)},setOnTouchStartListener:function(t){var e=this;"ontouchstart"in document.documentElement&&ir(document.body.children).forEach((function(i){$s(t,i,"mouseover",e.$_noop)}))},setDropdownListener:function(t){var e=this.getTarget();e&&this.$root&&this.isDropdown&&e.__vue__&&e.__vue__[t?"$on":"$off"](eo,this.forceHide)},handleEvent:function(t){var e=this.getTarget();if(e&&!Fr(e)&&this.$_enabled&&!this.dropdownOpen()){var i=t.type,n=this.computedTriggers;if("click"===i&&nr(n,"click"))this.click(t);else if("mouseenter"===i&&nr(n,"hover"))this.enter(t);else if("focusin"===i&&nr(n,"focus"))this.enter(t);else if("focusout"===i&&(nr(n,"focus")||nr(n,"blur"))||"mouseleave"===i&&nr(n,"hover")){var o=this.getTemplateElement(),r=t.target,s=t.relatedTarget;if(o&&Lr(o,r)&&Lr(e,s)||o&&Lr(e,r)&&Lr(o,s)||o&&Lr(o,r)&&Lr(o,s)||Lr(e,r)&&Lr(e,s))return;this.leave(t)}}},doHide:function(t){t&&this.getTargetId()!==t&&this.computedId!==t||this.forceHide()},doShow:function(t){t&&this.getTargetId()!==t&&this.computedId!==t||this.show()},doDisable:function(t){t&&this.getTargetId()!==t&&this.computedId!==t||this.disable()},doEnable:function(t){t&&this.getTargetId()!==t&&this.computedId!==t||this.enable()},click:function(t){this.$_enabled&&!this.dropdownOpen()&&(ts(t.currentTarget),this.activeTrigger.click=!this.activeTrigger.click,this.isWithActiveTrigger?this.enter(null):this.leave(null))},toggle:function(){this.$_enabled&&!this.dropdownOpen()&&(this.localShow?this.leave(null):this.enter(null))},enter:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;e&&(this.activeTrigger["focusin"===e.type?"focus":"hover"]=!0),this.localShow||"in"===this.$_hoverState?this.$_hoverState="in":(this.clearHoverTimeout(),this.$_hoverState="in",this.computedDelay.show?(this.fixTitle(),this.$_hoverTimeout=setTimeout((function(){"in"===t.$_hoverState?t.show():t.localShow||t.restoreTitle()}),this.computedDelay.show)):this.show())},leave:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;e&&(this.activeTrigger["focusout"===e.type?"focus":"hover"]=!1,"focusout"===e.type&&nr(this.computedTriggers,"blur")&&(this.activeTrigger.click=!1,this.activeTrigger.hover=!1)),this.isWithActiveTrigger||(this.clearHoverTimeout(),this.$_hoverState="out",this.computedDelay.hide?this.$_hoverTimeout=setTimeout((function(){"out"===t.$_hoverState&&t.hide()}),this.computedDelay.hide):this.hide())}}}),Zg="disabled",Jg="update:disabled",Qg="show",ty=vs((a(Jb={boundary:hs([HTMLElement,vo,go],"scrollParent"),boundaryPadding:hs(_o,50),container:hs([HTMLElement,vo,go]),customClass:hs(go),delay:hs(Do,50)},Zg,hs(ho,!1)),a(Jb,"fallbackPlacement",hs(Co,"flip")),a(Jb,"id",hs(go)),a(Jb,"noFade",hs(ho,!1)),a(Jb,"noninteractive",hs(ho,!1)),a(Jb,"offset",hs(_o,0)),a(Jb,"placement",hs(go,"top")),a(Jb,Qg,hs(ho,!1)),a(Jb,"target",hs([HTMLElement,SVGElement,po,vo,go],void 0,!0)),a(Jb,"title",hs(go)),a(Jb,"triggers",hs(Co,"hover focus")),a(Jb,"variant",hs(go)),Jb),Sn),ey=i.default.extend({name:Sn,mixins:[Cs],inheritAttrs:!1,props:ty,data:function(){return{localShow:this.show,localTitle:"",localContent:""}},computed:{templateData:function(){return c({title:this.localTitle,content:this.localContent,interactive:!this.noninteractive},Jt(this.$props,["boundary","boundaryPadding","container","customClass","delay","fallbackPlacement","id","noFade","offset","placement","target","target","triggers","variant",Zg]))},templateTitleContent:function(){return{title:this.title,content:this.content}}},watch:(Qb={},a(Qb,Qg,(function(t,e){t!==e&&t!==this.localShow&&this.$_toolpop&&(t?this.$_toolpop.show():this.$_toolpop.forceHide())})),a(Qb,Zg,(function(t){t?this.doDisable():this.doEnable()})),a(Qb,"localShow",(function(t){this.$emit("update:show",t)})),a(Qb,"templateData",(function(){var t=this;this.$nextTick((function(){t.$_toolpop&&t.$_toolpop.updateData(t.templateData)}))})),a(Qb,"templateTitleContent",(function(){this.$nextTick(this.updateContent)})),Qb),created:function(){this.$_toolpop=null},updated:function(){this.$nextTick(this.updateContent)},beforeDestroy:function(){this.$off(qn,this.doOpen),this.$off(_n,this.doClose),this.$off(Pn,this.doDisable),this.$off(Vn,this.doEnable),this.$_toolpop&&(this.$_toolpop.$destroy(),this.$_toolpop=null)},mounted:function(){var t=this;this.$nextTick((function(){var e=t.getComponent();t.updateContent();var i=eb(t)||eb(t.$parent),n=t.$_toolpop=new e({parent:t,_scopeId:i||void 0});n.updateData(t.templateData),n.$on(to,t.onShow),n.$on(eo,t.onShown),n.$on(Nn,t.onHide),n.$on(zn,t.onHidden),n.$on(On,t.onDisabled),n.$on(En,t.onEnabled),t.disabled&&t.doDisable(),t.$on(qn,t.doOpen),t.$on(_n,t.doClose),t.$on(Pn,t.doDisable),t.$on(Vn,t.doEnable),t.localShow&&n.show()}))},methods:{getComponent:function(){return Xg},updateContent:function(){this.setTitle(this.normalizeSlot()||this.title)},setTitle:function(t){t=Pt(t)?"":t,this.localTitle!==t&&(this.localTitle=t)},setContent:function(t){t=Pt(t)?"":t,this.localContent!==t&&(this.localContent=t)},onShow:function(t){this.$emit(to,t),t&&(this.localShow=!t.defaultPrevented)},onShown:function(t){this.localShow=!0,this.$emit(eo,t)},onHide:function(t){this.$emit(Nn,t)},onHidden:function(t){this.$emit(zn,t),this.localShow=!1},onDisabled:function(t){t&&t.type===On&&(this.$emit(Jg,!0),this.$emit(On,t))},onEnabled:function(t){t&&t.type===En&&(this.$emit(Jg,!1),this.$emit(En,t))},doOpen:function(){!this.localShow&&this.$_toolpop&&this.$_toolpop.show()},doClose:function(){this.localShow&&this.$_toolpop&&this.$_toolpop.hide()},doDisable:function(){this.$_toolpop&&this.$_toolpop.disable()},doEnable:function(){this.$_toolpop&&this.$_toolpop.enable()}},render:function(t){return t()}}),iy=i.default.extend({name:"BVPopoverTemplate",extends:Gg,computed:{templateType:function(){return"popover"}},methods:{renderTemplate:function(t){var e=this.title,i=this.content,n=Ot(e)?e({}):e,o=Ot(i)?i({}):i,r=this.html&&!Ot(e)?{innerHTML:e}:{},s=this.html&&!Ot(i)?{innerHTML:i}:{};return t("div",{staticClass:"popover b-popover",class:this.templateClasses,attrs:this.templateAttributes,on:this.templateListeners},[t("div",{staticClass:"arrow",ref:"arrow"}),Pt(n)||""===n?t():t("h3",{staticClass:"popover-header",domProps:r},[n]),Pt(o)||""===o?t():t("div",{staticClass:"popover-body",domProps:s},[o])])}}}),ny=i.default.extend({name:"BVPopover",extends:Xg,computed:{templateType:function(){return"popover"}},methods:{getTemplate:function(){return iy}}}),oy=vs(ee(c(c({},ty),{},{content:hs(go),placement:hs(go,"right"),triggers:hs(Co,Bn)})),tn),ry=i.default.extend({name:tn,extends:ey,inheritAttrs:!1,props:oy,methods:{getComponent:function(){return ny},updateContent:function(){this.setContent(this.normalizeSlot()||this.content),this.setTitle(this.normalizeSlot(tr)||this.title)}}}),sy="__BV_Popover__",ay={focus:!0,hover:!0,click:!0,blur:!0,manual:!0},ly=/^html$/i,cy=/^nofade$/i,uy=/^(auto|top(left|right)?|bottom(left|right)?|left(top|bottom)?|right(top|bottom)?)$/i,dy=/^(window|viewport|scrollParent)$/i,hy=/^d\d+$/i,fy=/^ds\d+$/i,py=/^dh\d+$/i,my=/^o-?\d+$/i,vy=/^v-.+$/i,by=/\s+/,gy=function(t,e,i){if(M){var n=function(t,e){var i={title:void 0,content:void 0,trigger:"",placement:"right",fallbackPlacement:"flip",container:!1,animation:!0,offset:0,disabled:!1,id:null,html:!1,delay:rs(tn,"delay",50),boundary:String(rs(tn,"boundary","scrollParent")),boundaryPadding:lr(rs(tn,"boundaryPadding",5),0),variant:rs(tn,"variant"),customClass:rs(tn,"customClass")};if(Et(t.value)||Lt(t.value)||Ot(t.value)?i.content=t.value:Ht(t.value)&&(i=c(c({},i),t.value)),t.arg&&(i.container="#".concat(t.arg)),Ft(i.title)){var n=e.data||{};i.title=n.attrs&&!Pt(n.attrs.title)?n.attrs.title:void 0}Ht(i.delay)||(i.delay={show:lr(i.delay,0),hide:lr(i.delay,0)}),Kt(t.modifiers).forEach((function(t){if(ly.test(t))i.html=!0;else if(cy.test(t))i.animation=!1;else if(uy.test(t))i.placement=t;else if(dy.test(t))t="scrollparent"===t?"scrollParent":t,i.boundary=t;else if(hy.test(t)){var e=lr(t.slice(1),0);i.delay.show=e,i.delay.hide=e}else fy.test(t)?i.delay.show=lr(t.slice(2),0):py.test(t)?i.delay.hide=lr(t.slice(2),0):my.test(t)?i.offset=lr(t.slice(1),0):vy.test(t)&&(i.variant=t.slice(2)||null)}));var o={};return or(i.trigger||"").filter(ne).join(" ").trim().toLowerCase().split(by).forEach((function(t){ay[t]&&(o[t]=!0)})),Kt(t.modifiers).forEach((function(t){t=t.toLowerCase(),ay[t]&&(o[t]=!0)})),i.trigger=Kt(o).join(" "),"blur"===i.trigger&&(i.trigger="focus"),i.trigger||(i.trigger="click"),i}(e,i);if(!t[sy]){var o=i.context;t[sy]=new ny({parent:o,_scopeId:eb(o,void 0)}),t[sy].__bv_prev_data__={},t[sy].$on(to,(function(){var e={};Ot(n.title)&&(e.title=n.title(t)),Ot(n.content)&&(e.content=n.content(t)),Kt(e).length>0&&t[sy].updateData(e)}))}var r={title:n.title,content:n.content,triggers:n.trigger,placement:n.placement,fallbackPlacement:n.fallbackPlacement,variant:n.variant,customClass:n.customClass,container:n.container,boundary:n.boundary,delay:n.delay,offset:n.offset,noFade:!n.animation,id:n.id,disabled:n.disabled,html:n.html},s=t[sy].__bv_prev_data__;if(t[sy].__bv_prev_data__=r,!Ua(r,s)){var a={target:t};Kt(r).forEach((function(e){r[e]!==s[e]&&(a[e]="title"!==e&&"content"!==e||!Ot(r[e])?r[e]:r[e](t))})),t[sy].updateData(a)}}},yy=me({directives:{VBPopover:{bind:function(t,e,i){gy(t,e,i)},componentUpdated:function(t,e,i){i.context.$nextTick((function(){gy(t,e,i)}))},unbind:function(t){!function(t){t[sy]&&(t[sy].$destroy(),t[sy]=null),delete t[sy]}(t)}}}}),wy=me({components:{BPopover:ry},plugins:{VBPopoverPlugin:yy}}),Ty=vs({animated:hs(ho,null),label:hs(go),labelHtml:hs(go),max:hs(_o,null),precision:hs(_o,null),showProgress:hs(ho,null),showValue:hs(ho,null),striped:hs(ho,null),value:hs(_o,0),variant:hs(go)},nn),Cy=i.default.extend({name:nn,mixins:[Cs],inject:{bvProgress:{default:function(){return{}}}},props:Ty,computed:{progressBarClasses:function(){var t=this.computedAnimated,e=this.computedVariant;return[e?"bg-".concat(e):"",this.computedStriped||t?"progress-bar-striped":"",t?"progress-bar-animated":""]},progressBarStyles:function(){return{width:this.computedValue/this.computedMax*100+"%"}},computedValue:function(){return cr(this.value,0)},computedMax:function(){var t=cr(this.max)||cr(this.bvProgress.max,0);return t>0?t:100},computedPrecision:function(){return Us(lr(this.precision,lr(this.bvProgress.precision,0)),0)},computedProgress:function(){var t=this.computedPrecision,e=Zs(10,t);return ur(100*e*this.computedValue/this.computedMax/e,t)},computedVariant:function(){return this.variant||this.bvProgress.variant},computedStriped:function(){return Vt(this.striped)?this.striped:this.bvProgress.striped||!1},computedAnimated:function(){return Vt(this.animated)?this.animated:this.bvProgress.animated||!1},computedShowProgress:function(){return Vt(this.showProgress)?this.showProgress:this.bvProgress.showProgress||!1},computedShowValue:function(){return Vt(this.showValue)?this.showValue:this.bvProgress.showValue||!1}},render:function(t){var e,i=this.label,n=this.labelHtml,o=this.computedValue,r=this.computedPrecision,s={};return this.hasNormalizedSlot()?e=this.normalizeSlot():i||n?s=Fl(n,i):this.computedShowProgress?e=this.computedProgress:this.computedShowValue&&(e=ur(o,r)),t("div",{staticClass:"progress-bar",class:this.progressBarClasses,style:this.progressBarStyles,attrs:{role:"progressbar","aria-valuemin":"0","aria-valuemax":vr(this.computedMax),"aria-valuenow":ur(o,r)},domProps:s},e)}}),xy=Qt(Ty,["label","labelHtml"]),Sy=vs(ee(c(c({},xy),{},{animated:hs(ho,!1),height:hs(go),max:hs(_o,100),precision:hs(_o,0),showProgress:hs(ho,!1),showValue:hs(ho,!1),striped:hs(ho,!1)})),en),ky=me({components:{BProgress:i.default.extend({name:en,mixins:[Cs],provide:function(){return{bvProgress:this}},props:Sy,computed:{progressHeight:function(){return{height:this.height||null}}},render:function(t){var e=this.normalizeSlot();return e||(e=t(Cy,{props:ps(xy,this.$props)})),t("div",{staticClass:"progress",style:this.progressHeight},[e])}}),BProgressBar:Cy}}),$y="b-sidebar",By=Fs(Ue,"request-state"),_y=Fs(Ue,"toggle"),Dy=Ds(Ue,"state"),Fy=Ds(Ue,"sync-state"),Iy=ys("visible",{type:ho,defaultValue:!1,event:$n}),Py=Iy.mixin,Oy=Iy.props,Vy=Iy.prop,Ey=Iy.event,Ly=vs(ee(c(c(c({},fc),Oy),{},{ariaLabel:hs(go),ariaLabelledby:hs(go),backdrop:hs(ho,!1),backdropVariant:hs(go,"dark"),bgVariant:hs(go,"light"),bodyClass:hs(To),closeLabel:hs(go),footerClass:hs(To),headerClass:hs(To),lazy:hs(ho,!1),noCloseOnBackdrop:hs(ho,!1),noCloseOnEsc:hs(ho,!1),noCloseOnRouteChange:hs(ho,!1),noEnforceFocus:hs(ho,!1),noHeader:hs(ho,!1),noHeaderClose:hs(ho,!1),noSlide:hs(ho,!1),right:hs(ho,!1),shadow:hs(ko,!1),sidebarClass:hs(To),tag:hs(go,"div"),textVariant:hs(go,"dark"),title:hs(go),width:hs(go),zIndex:hs(_o)})),rn),Ay=function(t,e){if(e.noHeader)return t();var i=e.normalizeSlot(No,e.slotScope);if(!i){var n=function(t,e){var i=e.normalizeSlot(tr,e.slotScope)||e.title;return i?t("strong",{attrs:{id:e.safeId("__title__")}},[i]):t("span")}(t,e),o=function(t,e){if(e.noHeaderClose)return t();var i=e.closeLabel,n=e.textVariant,o=e.hide;return t(Ps,{props:{ariaLabel:i,textVariant:n},on:{click:o},ref:"close-button"},[e.normalizeSlot("header-close")||t(Oa)])}(t,e);i=e.right?[o,n]:[n,o]}return t("header",{staticClass:"".concat($y,"-header"),class:e.headerClass,key:"header"},i)},Ry=function(t,e){return t("div",{staticClass:"".concat($y,"-body"),class:e.bodyClass,key:"body"},[e.normalizeSlot(Ao,e.slotScope)])},My=function(t,e){var i=e.normalizeSlot(zo,e.slotScope);return i?t("footer",{staticClass:"".concat($y,"-footer"),class:e.footerClass,key:"footer"},[i]):t()},Hy=function(t,e){var i=Ay(t,e);return e.lazy&&!e.isOpen?i:[i,Ry(t,e),My(t,e)]},zy=function(t,e){if(!e.backdrop)return t();var i=e.backdropVariant;return t("div",{directives:[{name:"show",value:e.localShow}],staticClass:"b-sidebar-backdrop",class:a({},"bg-".concat(i),i),on:{click:e.onBackdropClick}})},Ny=me({components:{BSidebar:i.default.extend({name:rn,mixins:[Za,pc,Py,Ja,Cs],inheritAttrs:!1,props:Ly,data:function(){var t=!!this[Vy];return{localShow:t,isOpen:t}},computed:{transitionProps:function(){return this.noSlide?{css:!0}:{css:!0,enterClass:"",enterActiveClass:"slide",enterToClass:"show",leaveClass:"show",leaveActiveClass:"slide",leaveToClass:""}},slotScope:function(){return{hide:this.hide,right:this.right,visible:this.localShow}},hasTitle:function(){var t=this.$scopedSlots,e=this.$slots;return!(this.noHeader||this.hasNormalizedSlot(No)||!this.normalizeSlot(tr,this.slotScope,t,e)&&!this.title)},titleId:function(){return this.hasTitle?this.safeId("__title__"):null},computedAttrs:function(){return c(c({},this.bvAttrs),{},{id:this.safeId(),tabindex:"-1",role:"dialog","aria-modal":this.backdrop?"true":"false","aria-hidden":this.localShow?null:"true","aria-label":this.ariaLabel||null,"aria-labelledby":this.ariaLabelledby||this.titleId||null})}},watch:(tg={},a(tg,Vy,(function(t,e){t!==e&&(this.localShow=t)})),a(tg,"localShow",(function(t,e){t!==e&&(this.emitState(t),this.$emit(Ey,t))})),a(tg,"$route",(function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.noCloseOnRouteChange||t.fullPath===e.fullPath||this.hide()})),tg),created:function(){this.$_returnFocusEl=null},mounted:function(){var t=this;this.listenOnRoot(_y,this.handleToggle),this.listenOnRoot(By,this.handleSync),this.$nextTick((function(){t.emitState(t.localShow)}))},activated:function(){this.emitSync()},beforeDestroy:function(){this.localShow=!1,this.$_returnFocusEl=null},methods:{hide:function(){this.localShow=!1},emitState:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.localShow;this.emitOnRoot(Dy,this.safeId(),t)},emitSync:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.localShow;this.emitOnRoot(Fy,this.safeId(),t)},handleToggle:function(t){t&&t===this.safeId()&&(this.localShow=!this.localShow)},handleSync:function(t){var e=this;t&&t===this.safeId()&&this.$nextTick((function(){e.emitSync(e.localShow)}))},onKeydown:function(t){var e=t.keyCode;!this.noCloseOnEsc&&27===e&&this.localShow&&this.hide()},onBackdropClick:function(){this.localShow&&!this.noCloseOnBackdrop&&this.hide()},onTopTrapFocus:function(){var t=Qr(this.$refs.content);this.enforceFocus(t.reverse()[0])},onBottomTrapFocus:function(){var t=Qr(this.$refs.content);this.enforceFocus(t[0])},onBeforeEnter:function(){this.$_returnFocusEl=$r(M?[document.body]:[]),this.isOpen=!0},onAfterEnter:function(t){Lr(t,$r())||this.enforceFocus(t),this.$emit(eo)},onAfterLeave:function(){this.enforceFocus(this.$_returnFocusEl),this.$_returnFocusEl=null,this.isOpen=!1,this.$emit(zn)},enforceFocus:function(t){this.noEnforceFocus||ts(t)}},render:function(t){var e,i=this.bgVariant,n=this.width,o=this.textVariant,r=this.localShow,s=""===this.shadow||this.shadow,l=t(this.tag,{staticClass:$y,class:[(e={shadow:!0===s},a(e,"shadow-".concat(s),s&&!0!==s),a(e,"".concat($y,"-right"),this.right),a(e,"bg-".concat(i),i),a(e,"text-".concat(o),o),e),this.sidebarClass],style:{width:n},attrs:this.computedAttrs,directives:[{name:"show",value:r}],ref:"content"},[Hy(t,this)]);l=t("transition",{props:this.transitionProps,on:{beforeEnter:this.onBeforeEnter,afterEnter:this.onAfterEnter,afterLeave:this.onAfterLeave}},[l]);var c=t(Ls,{props:{noFade:this.noSlide}},[zy(t,this)]),u=t(),d=t();return this.backdrop&&r&&(u=t("div",{attrs:{tabindex:"0"},on:{focus:this.onTopTrapFocus}}),d=t("div",{attrs:{tabindex:"0"},on:{focus:this.onBottomTrapFocus}})),t("div",{staticClass:"b-sidebar-outer",style:{zIndex:this.zIndex},attrs:{tabindex:"-1"},on:{keydown:this.onKeydown}},[u,l,d,c])}})},plugins:{VBTogglePlugin:ld}}),jy=vs({animation:hs(go,"wave"),height:hs(go),size:hs(go),type:hs(go,"text"),variant:hs(go),width:hs(go)},sn),Gy=i.default.extend({name:sn,functional:!0,props:jy,render:function(t,e){var i,n=e.data,o=e.props,r=o.size,s=o.animation,l=o.variant;return t("div",F(n,{staticClass:"b-skeleton",style:{width:r||o.width,height:r||o.height},class:(i={},a(i,"b-skeleton-".concat(o.type),!0),a(i,"b-skeleton-animate-".concat(s),s),a(i,"bg-".concat(l),l),i)}))}}),Wy=(vs(Qt(fa,["content","stacked"]),"BIconstack"),vs({animation:hs(go,"wave"),icon:hs(go),iconProps:hs(vo,{})},an)),Yy=i.default.extend({name:an,functional:!0,props:Wy,render:function(t,e){var i=e.props,n=i.icon,o=i.animation,r=t(Aa,{staticClass:"b-skeleton-icon",props:c(c({},i.iconProps),{},{icon:n})});return t("div",{staticClass:"b-skeleton-icon-wrapper position-relative d-inline-block overflow-hidden",class:a({},"b-skeleton-animate-".concat(o),o)},[r])}}),Uy=vs({animation:hs(go),aspect:hs(go,"16:9"),cardImg:hs(go),height:hs(go),noAspect:hs(ho,!1),variant:hs(go),width:hs(go)},ln),qy=i.default.extend({name:ln,functional:!0,props:Uy,render:function(t,e){var i=e.props,n=i.aspect,o=i.width,r=i.height,s=i.animation,l=i.variant,c=i.cardImg,u=t(Gy,{props:{type:"img",width:o,height:r,animation:s,variant:l},class:a({},"card-img-".concat(c),c)});return i.noAspect?u:t(ea,{props:{aspect:n}},[u])}}),Ky=i.default.extend({methods:{hasListener:function(t){var e=this.$listeners||{},i=this._events||{};return!Ft(e[t])||Rt(i[t])&&i[t].length>0}}}),Xy="light",Zy="dark",Jy=vs({variant:hs(go)},"BTr"),Qy=i.default.extend({name:"BTr",mixins:[Za,Qa,Cs],provide:function(){return{bvTableTr:this}},inject:{bvTableRowGroup:{default:function(){return{}}}},inheritAttrs:!1,props:Jy,computed:{inTbody:function(){return this.bvTableRowGroup.isTbody},inThead:function(){return this.bvTableRowGroup.isThead},inTfoot:function(){return this.bvTableRowGroup.isTfoot},isDark:function(){return this.bvTableRowGroup.isDark},isStacked:function(){return this.bvTableRowGroup.isStacked},isResponsive:function(){return this.bvTableRowGroup.isResponsive},isStickyHeader:function(){return this.bvTableRowGroup.isStickyHeader},hasStickyHeader:function(){return!this.isStacked&&this.bvTableRowGroup.hasStickyHeader},tableVariant:function(){return this.bvTableRowGroup.tableVariant},headVariant:function(){return this.inThead?this.bvTableRowGroup.headVariant:null},footVariant:function(){return this.inTfoot?this.bvTableRowGroup.footVariant:null},isRowDark:function(){return this.headVariant!==Xy&&this.footVariant!==Xy&&(this.headVariant===Zy||this.footVariant===Zy||this.isDark)},trClasses:function(){var t=this.variant;return[t?"".concat(this.isRowDark?"bg":"table","-").concat(t):null]},trAttrs:function(){return c({role:"row"},this.bvAttrs)}},render:function(t){return t("tr",{class:this.trClasses,attrs:this.trAttrs,on:this.bvListeners},this.normalizeSlot())}}),tw={},ew=i.default.extend({props:tw,methods:{renderBottomRow:function(){var t=this.computedFields,e=this.stacked,i=this.tbodyTrClass,n=this.tbodyTrAttr,o=this.$createElement;return this.hasNormalizedSlot(Vo)&&!0!==e&&""!==e?o(Qy,{staticClass:"b-table-bottom-row",class:[Ot(i)?i(null,"row-bottom"):i],attrs:Ot(n)?n(null,"row-bottom"):n,key:"b-bottom-row"},this.normalizeSlot(Vo,{columns:t.length,fields:t})):o()}}}),iw=function(t){return(t=lr(t,0))>0?t:null},nw=function(t){return Pt(t)||iw(t)>0},ow=vs({colspan:hs(_o,null,nw),rowspan:hs(_o,null,nw),stackedHeading:hs(go),stickyColumn:hs(ho,!1),variant:hs(go)},pn),rw=i.default.extend({name:pn,mixins:[Za,Qa,Cs],inject:{bvTableTr:{default:function(){return{}}}},inheritAttrs:!1,props:ow,computed:{tag:function(){return"td"},inTbody:function(){return this.bvTableTr.inTbody},inThead:function(){return this.bvTableTr.inThead},inTfoot:function(){return this.bvTableTr.inTfoot},isDark:function(){return this.bvTableTr.isDark},isStacked:function(){return this.bvTableTr.isStacked},isStackedCell:function(){return this.inTbody&&this.isStacked},isResponsive:function(){return this.bvTableTr.isResponsive},isStickyHeader:function(){return this.bvTableTr.isStickyHeader},hasStickyHeader:function(){return this.bvTableTr.hasStickyHeader},isStickyColumn:function(){return!this.isStacked&&(this.isResponsive||this.hasStickyHeader)&&this.stickyColumn},rowVariant:function(){return this.bvTableTr.variant},headVariant:function(){return this.bvTableTr.headVariant},footVariant:function(){return this.bvTableTr.footVariant},tableVariant:function(){return this.bvTableTr.tableVariant},computedColspan:function(){return iw(this.colspan)},computedRowspan:function(){return iw(this.rowspan)},cellClasses:function(){var t=this.variant,e=this.headVariant,i=this.isStickyColumn;return(!t&&this.isStickyHeader&&!e||!t&&i&&this.inTfoot&&!this.footVariant||!t&&i&&this.inThead&&!e||!t&&i&&this.inTbody)&&(t=this.rowVariant||this.tableVariant||"b-table-default"),[t?"".concat(this.isDark?"bg":"table","-").concat(t):null,i?"b-table-sticky-column":null]},cellAttrs:function(){var t=this.stackedHeading,e=this.inThead||this.inTfoot,i=this.computedColspan,n=this.computedRowspan,o="cell",r=null;return e?(o="columnheader",r=i>0?"colspan":"col"):Br(this.tag,"th")&&(o="rowheader",r=n>0?"rowgroup":"row"),c(c({colspan:i,rowspan:n,role:o,scope:r},this.bvAttrs),{},{"data-label":this.isStackedCell&&!Pt(t)?vr(t):null})}},render:function(t){var e=[this.normalizeSlot()];return t(this.tag,{class:this.cellClasses,attrs:this.cellAttrs,on:this.bvListeners},[this.isStackedCell?t("div",[e]):e])}}),sw="busy",aw=a({},sw,hs(ho,!1)),lw=i.default.extend({props:aw,data:function(){return{localBusy:!1}},computed:{computedBusy:function(){return this.busy||this.localBusy}},watch:{localBusy:function(t,e){t!==e&&this.$emit("update:busy",t)}},methods:{stopIfBusy:function(t){return!!this.computedBusy&&(Bs(t),!0)},renderBusy:function(){var t=this.tbodyTrClass,e=this.tbodyTrAttr,i=this.$createElement;return this.computedBusy&&this.hasNormalizedSlot(Xo)?i(Qy,{staticClass:"b-table-busy-slot",class:[Ot(t)?t(null,Xo):t],attrs:Ot(e)?e(null,Xo):e,key:"table-busy-slot"},[i(rw,{props:{colspan:this.computedFields.length||null}},[this.normalizeSlot(Xo)])]):null}}}),cw={caption:hs(go),captionHtml:hs(go)},uw=i.default.extend({props:cw,computed:{captionId:function(){return this.isStacked?this.safeId("_caption_"):null}},methods:{renderCaption:function(){var t=this.caption,e=this.captionHtml,i=this.$createElement,n=i(),o=this.hasNormalizedSlot(Zo);return(o||t||e)&&(n=i("caption",{attrs:{id:this.captionId},domProps:o?{}:Fl(e,t),key:"caption",ref:"caption"},this.normalizeSlot(Zo))),n}}}),dw={},hw=i.default.extend({methods:{renderColgroup:function(){var t=this.computedFields,e=this.$createElement,i=e();return this.hasNormalizedSlot(Jo)&&(i=e("colgroup",{key:"colgroup"},[this.normalizeSlot(Jo,{columns:t.length,fields:t})])),i}}}),fw={emptyFilteredHtml:hs(go),emptyFilteredText:hs(go,"There are no records matching your request"),emptyHtml:hs(go),emptyText:hs(go,"There are no records to show"),showEmpty:hs(ho,!1)},pw=i.default.extend({props:fw,methods:{renderEmpty:function(){var t=this.computedItems,e=this.$createElement,i=e();if(this.showEmpty&&(!t||0===t.length)&&(!this.computedBusy||!this.hasNormalizedSlot(Xo))){var n=this.computedFields,o=this.isFiltered,r=this.emptyText,s=this.emptyHtml,a=this.emptyFilteredText,l=this.emptyFilteredHtml,c=this.tbodyTrClass,u=this.tbodyTrAttr;(i=this.normalizeSlot(o?"emptyfiltered":Ro,{emptyFilteredHtml:l,emptyFilteredText:a,emptyHtml:s,emptyText:r,fields:n,items:t}))||(i=e("div",{class:["text-center","my-2"],domProps:o?Fl(l,a):Fl(s,r)})),i=e(rw,{props:{colspan:n.length||null}},[e("div",{attrs:{role:"alert","aria-live":"polite"}},[i])]),i=e(Qy,{staticClass:"b-table-empty-row",class:[Ot(c)?c(null,"row-empty"):c],attrs:Ot(u)?u(null,"row-empty"):u,key:o?"b-empty-filtered-row":"b-empty-row"},[i])}return i}}}),mw=function t(e){return Pt(e)?"":Mt(e)&&!zt(e)?Kt(e).sort().map((function(i){return t(e[i])})).filter((function(t){return!!t})).join(" "):vr(e)},vw="_cellVariants",bw="_rowVariant",gw="_showDetails",yw=[vw,bw,gw].reduce((function(t,e){return c(c({},t),{},a({},e,!0))}),{}),ww=["a","a *","button","button *","input:not(.disabled):not([disabled])","select:not(.disabled):not([disabled])","textarea:not(.disabled):not([disabled])",'[role="link"]','[role="link"] *','[role="button"]','[role="button"] *',"[tabindex]:not(.disabled):not([disabled])"].join(","),Tw=function(t,e,i){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=Kt(n).reduce((function(e,i){var o=n[i],r=o.filterByFormatted,s=Ot(r)?r:r?o.formatter:null;return Ot(s)&&(e[i]=s(t[i],i,t)),e}),Zt(t)),r=Kt(o).filter((function(t){return!(yw[t]||Rt(e)&&e.length>0&&nr(e,t)||Rt(i)&&i.length>0&&!nr(i,t))}));return Jt(o,r)},Cw={filter:hs([].concat(T(To),[bo])),filterDebounce:hs(_o,0,(function(t){return Q.test(String(t))})),filterFunction:hs(po),filterIgnoredFields:hs(uo,[]),filterIncludedFields:hs(uo,[])},xw=i.default.extend({props:Cw,data:function(){return{isFiltered:!1,localFilter:this.filterSanitize(this.filter)}},computed:{computedFilterIgnored:function(){return or(this.filterIgnoredFields||[]).filter(ne)},computedFilterIncluded:function(){return or(this.filterIncludedFields||[]).filter(ne)},computedFilterDebounce:function(){var t=lr(this.filterDebounce,0);return t>0&&le('Prop "filter-debounce" is deprecated. Use the debounce feature of "<b-form-input>" instead.',fn),t},localFiltering:function(){return!this.hasProvider||!!this.noProviderFiltering},filteredCheck:function(){return{filteredItems:this.filteredItems,localItems:this.localItems,localFilter:this.localFilter}},localFilterFn:function(){var t=this.filterFunction;return gs(t)?t:null},filteredItems:function(){var t=this.localItems,e=this.localFilter,i=this.localFiltering?this.filterFnFactory(this.localFilterFn,e)||this.defaultFilterFnFactory(e):null;return i&&t.length>0?t.filter(i):t}},watch:{computedFilterDebounce:function(t){!t&&this.$_filterTimer&&(this.clearFilterTimer(),this.localFilter=this.filterSanitize(this.filter))},filter:{deep:!0,handler:function(t){var e=this,i=this.computedFilterDebounce;this.clearFilterTimer(),i&&i>0?this.$_filterTimer=setTimeout((function(){e.localFilter=e.filterSanitize(t)}),i):this.localFilter=this.filterSanitize(t)}},filteredCheck:function(t){var e=t.filteredItems,i=t.localFilter,n=!1;i?Ua(i,[])||Ua(i,{})?n=!1:i&&(n=!0):n=!1,n&&this.$emit(Ln,e,e.length),this.isFiltered=n},isFiltered:function(t,e){if(!1===t&&!0===e){var i=this.localItems;this.$emit(Ln,i,i.length)}}},created:function(){var t=this;this.$_filterTimer=null,this.$nextTick((function(){t.isFiltered=Boolean(t.localFilter)}))},beforeDestroy:function(){this.clearFilterTimer()},methods:{clearFilterTimer:function(){clearTimeout(this.$_filterTimer),this.$_filterTimer=null},filterSanitize:function(t){return!this.localFiltering||this.localFilterFn||Et(t)||jt(t)?ie(t):""},filterFnFactory:function(t,e){if(!t||!Ot(t)||!e||Ua(e,[])||Ua(e,{}))return null;return function(i){return t(i,e)}},defaultFilterFnFactory:function(t){var e=this;if(!t||!Et(t)&&!jt(t))return null;var i=t;if(Et(i)){var n=mr(t).replace(ct,"\\s+");i=new RegExp(".*".concat(n,".*"),"i")}return function(t){return i.lastIndex=0,i.test((n=t,o=e.computedFilterIgnored,r=e.computedFilterIncluded,s=e.computedFieldsObj,Mt(n)?mw(Tw(n,o,r,s)):""));var n,o,r,s}}}}),Sw=function(t,e){var i=[];if(Rt(t)&&t.filter(ne).forEach((function(t){if(Et(t))i.push({key:t,label:fr(t)});else if(Mt(t)&&t.key&&Et(t.key))i.push(Zt(t));else if(Mt(t)&&1===Kt(t).length){var e=Kt(t)[0],n=function(t,e){var i=null;return Et(e)?i={key:t,label:e}:Ot(e)?i={key:t,formatter:e}:Mt(e)?(i=Zt(e)).key=i.key||t:!1!==e&&(i={key:t}),i}(e,t[e]);n&&i.push(n)}})),0===i.length&&Rt(e)&&e.length>0){var n=e[0];Kt(n).forEach((function(t){yw[t]||i.push({key:t,label:fr(t)})}))}var o={};return i.filter((function(t){return!o[t.key]&&(o[t.key]=!0,t.label=Et(t.label)?t.label:fr(t.key),!0)}))},kw=ys("value",{type:uo,defaultValue:[]}),$w=kw.mixin,Bw=kw.props,_w=kw.prop,Dw=kw.event,Fw=ee(c(c({},Bw),{},a({fields:hs(uo,null),items:hs(uo,[]),primaryKey:hs(go)},_w,hs(uo,[])))),Iw=i.default.extend({mixins:[$w],props:Fw,data:function(){var t=this.items;return{localItems:Rt(t)?t.slice():[]}},computed:{computedFields:function(){return Sw(this.fields,this.localItems)},computedFieldsObj:function(){var t=this.$parent;return this.computedFields.reduce((function(e,i){if(e[i.key]=Zt(i),i.formatter){var n=i.formatter;Et(n)&&Ot(t[n])?n=t[n]:Ot(n)||(n=void 0),e[i.key].formatter=n}return e}),{})},computedItems:function(){return(this.paginatedItems||this.sortedItems||this.filteredItems||this.localItems||[]).slice()},context:function(){return{filter:this.localFilter,sortBy:this.localSortBy,sortDesc:this.localSortDesc,perPage:Us(lr(this.perPage,0),0),currentPage:Us(lr(this.currentPage,0),1),apiUrl:this.apiUrl}}},watch:{items:function(t){this.localItems=Rt(t)?t.slice():[]},computedItems:function(t,e){Ua(t,e)||this.$emit(Dw,t)},context:function(t,e){Ua(t,e)||this.$emit(Fn,t)}},mounted:function(){this.$emit(Dw,this.computedItems)},methods:{getFieldFormatter:function(t){var e=this.computedFieldsObj[t];return e?e.formatter:void 0}}}),Pw={currentPage:hs(_o,1),perPage:hs(_o,0)},Ow=i.default.extend({props:Pw,computed:{localPaging:function(){return!this.hasProvider||!!this.noProviderPaging},paginatedItems:function(){var t=this.sortedItems||this.filteredItems||this.localItems||[],e=Us(lr(this.currentPage,1),1),i=Us(lr(this.perPage,0),0);return this.localPaging&&i&&(t=t.slice((e-1)*i,e*i)),t}}}),Vw=Ds(fn,Zn),Ew=Fs(fn,"refresh"),Lw={apiUrl:hs(go),items:hs(yo,[]),noProviderFiltering:hs(ho,!1),noProviderPaging:hs(ho,!1),noProviderSorting:hs(ho,!1)},Aw=i.default.extend({mixins:[Ja],props:Lw,computed:{hasProvider:function(){return Ot(this.items)},providerTriggerContext:function(){var t={apiUrl:this.apiUrl,filter:null,sortBy:null,sortDesc:null,perPage:null,currentPage:null};return this.noProviderFiltering||(t.filter=this.localFilter),this.noProviderSorting||(t.sortBy=this.localSortBy,t.sortDesc=this.localSortDesc),this.noProviderPaging||(t.perPage=this.perPage,t.currentPage=this.currentPage),Zt(t)}},watch:{items:function(t){(this.hasProvider||Ot(t))&&this.$nextTick(this._providerUpdate)},providerTriggerContext:function(t,e){Ua(t,e)||this.$nextTick(this._providerUpdate)}},mounted:function(){var t=this;!this.hasProvider||this.localItems&&0!==this.localItems.length||this._providerUpdate(),this.listenOnRoot(Ew,(function(e){e!==t.id&&e!==t||t.refresh()}))},methods:{refresh:function(){var t=this.items,e=this.refresh;this.$off(Zn,e),this.computedBusy?this.localBusy&&this.hasProvider&&this.$on(Zn,e):(this.clearSelected(),this.hasProvider?this.$nextTick(this._providerUpdate):this.localItems=Rt(t)?t.slice():[])},_providerSetLocal:function(t){this.localItems=Rt(t)?t.slice():[],this.localBusy=!1,this.$emit(Zn),this.id&&this.emitOnRoot(Vw,this.id)},_providerUpdate:function(){var t=this;this.hasProvider&&(this.computedBusy?this.$nextTick(this.refresh):(this.localBusy=!0,this.$nextTick((function(){try{var e=t.items(t.context,t._providerSetLocal);!Pt(i=e)&&Ot(i.then)&&Ot(i.catch)?e.then((function(e){t._providerSetLocal(e)})):Rt(e)?t._providerSetLocal(e):2!==t.items.length&&(le("Provider function didn't request callback and did not return a promise or data.",fn),t.localBusy=!1)}catch(e){le("Provider function error [".concat(e.name,"] ").concat(e.message,"."),fn),t.localBusy=!1,t.$off(Zn,t.refresh)}var i}))))}}}),Rw=["range","multi","single"],Mw={noSelectOnClick:hs(ho,!1),selectMode:hs(go,"multi",(function(t){return nr(Rw,t)})),selectable:hs(ho,!1),selectedVariant:hs(go,"active")},Hw=i.default.extend({props:Mw,data:function(){return{selectedRows:[],selectedLastRow:-1}},computed:{isSelectable:function(){return this.selectable&&this.selectMode},hasSelectableRowClick:function(){return this.isSelectable&&!this.noSelectOnClick},supportsSelectableRows:function(){return!0},selectableHasSelection:function(){var t=this.selectedRows;return this.isSelectable&&t&&t.length>0&&t.some(ne)},selectableIsMultiSelect:function(){return this.isSelectable&&nr(["range","multi"],this.selectMode)},selectableTableClasses:function(){var t,e=this.isSelectable;return a(t={"b-table-selectable":e},"b-table-select-".concat(this.selectMode),e),a(t,"b-table-selecting",this.selectableHasSelection),a(t,"b-table-selectable-no-click",e&&!this.hasSelectableRowClick),t},selectableTableAttrs:function(){return{"aria-multiselectable":this.isSelectable?this.selectableIsMultiSelect?"true":"false":null}}},watch:{computedItems:function(t,e){var i=!1;if(this.isSelectable&&this.selectedRows.length>0){i=Rt(t)&&Rt(e)&&t.length===e.length;for(var n=0;i&&n<t.length;n++)i=Ua(Tw(t[n]),Tw(e[n]))}i||this.clearSelected()},selectable:function(t){this.clearSelected(),this.setSelectionHandlers(t)},selectMode:function(){this.clearSelected()},hasSelectableRowClick:function(t){this.clearSelected(),this.setSelectionHandlers(!t)},selectedRows:function(t,e){var i=this;if(this.isSelectable&&!Ua(t,e)){var n=[];t.forEach((function(t,e){t&&n.push(i.computedItems[e])})),this.$emit("row-selected",n)}}},beforeMount:function(){this.isSelectable&&this.setSelectionHandlers(!0)},methods:{selectRow:function(t){if(this.isSelectable&&Lt(t)&&t>=0&&t<this.computedItems.length&&!this.isRowSelected(t)){var e=this.selectableIsMultiSelect?this.selectedRows.slice():[];e[t]=!0,this.selectedLastClicked=-1,this.selectedRows=e}},unselectRow:function(t){if(this.isSelectable&&Lt(t)&&this.isRowSelected(t)){var e=this.selectedRows.slice();e[t]=!1,this.selectedLastClicked=-1,this.selectedRows=e}},selectAllRows:function(){var t=this.computedItems.length;this.isSelectable&&t>0&&(this.selectedLastClicked=-1,this.selectedRows=this.selectableIsMultiSelect?rr(t,!0):[!0])},isRowSelected:function(t){return!(!Lt(t)||!this.selectedRows[t])},clearSelected:function(){this.selectedLastClicked=-1,this.selectedRows=[]},selectableRowClasses:function(t){if(this.isSelectable&&this.isRowSelected(t)){var e=this.selectedVariant;return a({"b-table-row-selected":!0},"".concat(this.dark?"bg":"table","-").concat(e),e)}return{}},selectableRowAttrs:function(t){return{"aria-selected":this.isSelectable?this.isRowSelected(t)?"true":"false":null}},setSelectionHandlers:function(t){var e=t&&!this.noSelectOnClick?"$on":"$off";this[e](Jn,this.selectionHandler),this[e](Ln,this.clearSelected),this[e](Fn,this.clearSelected)},selectionHandler:function(t,e,i){if(this.isSelectable&&!this.noSelectOnClick){var n=this.selectMode,o=this.selectedLastRow,r=this.selectedRows.slice(),s=!r[e];if("single"===n)r=[];else if("range"===n)if(o>-1&&i.shiftKey){for(var a=Ys(o,e);a<=Us(o,e);a++)r[a]=!0;s=!0}else i.ctrlKey||i.metaKey||(r=[],s=!0),this.selectedLastRow=s?e:-1;r[e]=s,this.selectedRows=r}else this.clearSelected()}}}),zw=function(t,e){return t.map((function(t,e){return[e,t]})).sort(function(t,e){return this(t[1],e[1])||t[0]-e[0]}.bind(e)).map((function(t){return t[1]}))},Nw=function(t){return Pt(t)?"":At(t)?cr(t,t):t},jw="sortBy",Gw="sortDesc",Ww="asc",Yw="desc",Uw=[Ww,Yw,"last"],qw=(a(eg={labelSortAsc:hs(go,"Click to sort Ascending"),labelSortClear:hs(go,"Click to clear sorting"),labelSortDesc:hs(go,"Click to sort Descending"),noFooterSorting:hs(ho,!1),noLocalSorting:hs(ho,!1),noSortReset:hs(ho,!1)},jw,hs(go)),a(eg,"sortCompare",hs(po)),a(eg,"sortCompareLocale",hs(Co)),a(eg,"sortCompareOptions",hs(vo,{numeric:!0})),a(eg,Gw,hs(ho,!1)),a(eg,"sortDirection",hs(go,Ww,(function(t){return nr(Uw,t)}))),a(eg,"sortIconLeft",hs(ho,!1)),a(eg,"sortNullLast",hs(ho,!1)),eg),Kw=i.default.extend({props:qw,data:function(){return{localSortBy:this.sortBy||"",localSortDesc:this.sortDesc||!1}},computed:{localSorting:function(){return this.hasProvider?!!this.noProviderSorting:!this.noLocalSorting},isSortable:function(){return this.computedFields.some((function(t){return t.sortable}))},sortedItems:function(){var t=this.localSortBy,e=this.localSortDesc,i=this.sortCompareLocale,n=this.sortNullLast,o=this.sortCompare,r=this.localSorting,s=(this.filteredItems||this.localItems||[]).slice(),a=c(c({},this.sortCompareOptions),{},{usage:"sort"});if(t&&r){var l=(this.computedFieldsObj[t]||{}).sortByFormatted,u=Ot(l)?l:l?this.getFieldFormatter(t):void 0;return zw(s,(function(r,s){var l=null;return Ot(o)&&(l=o(r,s,t,e,u,a,i)),(Pt(l)||!1===l)&&(l=function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=i.sortBy,o=void 0===n?null:n,r=i.formatter,s=void 0===r?null:r,a=i.locale,l=void 0===a?void 0:a,c=i.localeOptions,u=void 0===c?{}:c,d=i.nullLast,h=void 0!==d&&d,f=re(t,o,null),p=re(e,o,null);return Ot(s)&&(f=s(f,o,t),p=s(p,o,e)),f=Nw(f),p=Nw(p),zt(f)&&zt(p)||Lt(f)&&Lt(p)?f<p?-1:f>p?1:0:h&&""===f&&""!==p?1:h&&""!==f&&""===p?-1:mw(f).localeCompare(mw(p),l,u)}(r,s,{sortBy:t,formatter:u,locale:i,localeOptions:a,nullLast:n})),(l||0)*(e?-1:1)}))}return s}},watch:(ig={isSortable:function(t){t?this.isSortable&&this.$on(Hn,this.handleSort):this.$off(Hn,this.handleSort)}},a(ig,Gw,(function(t){t!==this.localSortDesc&&(this.localSortDesc=t||!1)})),a(ig,jw,(function(t){t!==this.localSortBy&&(this.localSortBy=t||"")})),a(ig,"localSortDesc",(function(t,e){t!==e&&this.$emit("update:sortDesc",t)})),a(ig,"localSortBy",(function(t,e){t!==e&&this.$emit("update:sortBy",t)})),ig),created:function(){this.isSortable&&this.$on(Hn,this.handleSort)},methods:{handleSort:function(t,e,i,n){var o=this;if(this.isSortable&&(!n||!this.noFooterSorting)){var r=!1,s=function(){var t=e.sortDirection||o.sortDirection;t===Ww?o.localSortDesc=!1:t===Yw&&(o.localSortDesc=!0)};if(e.sortable){var a=!this.localSorting&&e.sortKey?e.sortKey:t;this.localSortBy===a?this.localSortDesc=!this.localSortDesc:(this.localSortBy=a,s()),r=!0}else this.localSortBy&&!this.noSortReset&&(this.localSortBy="",s(),r=!0);r&&this.$emit("sort-changed",this.context)}},sortTheadThClasses:function(t,e,i){return{"b-table-sort-icon-left":e.sortable&&this.sortIconLeft&&!(i&&this.noFooterSorting)}},sortTheadThAttrs:function(t,e,i){if(!this.isSortable||i&&this.noFooterSorting)return{};var n=e.sortable;return{"aria-sort":n&&this.localSortBy===t?this.localSortDesc?"descending":"ascending":n?"none":null}},sortTheadThLabel:function(t,e,i){if(!this.isSortable||i&&this.noFooterSorting)return null;var n="";if(e.sortable)if(this.localSortBy===t)n=this.localSortDesc?this.labelSortAsc:this.labelSortDesc;else{n=this.localSortDesc?this.labelSortDesc:this.labelSortAsc;var o=this.sortDirection||e.sortDirection;o===Ww?n=this.labelSortAsc:o===Yw&&(n=this.labelSortDesc)}else this.noSortReset||(n=this.localSortBy?this.labelSortClear:"");return br(n)||null}}}),Xw={stacked:hs(ko,!1)},Zw=i.default.extend({props:Xw,computed:{isStacked:function(){var t=this.stacked;return""===t||t},isStackedAlways:function(){return!0===this.isStacked},stackedTableClasses:function(){var t=this.isStackedAlways;return a({"b-table-stacked":t},"b-table-stacked-".concat(this.stacked),!t&&this.isStacked)}}}),Jw={bordered:hs(ho,!1),borderless:hs(ho,!1),captionTop:hs(ho,!1),dark:hs(ho,!1),fixed:hs(ho,!1),hover:hs(ho,!1),noBorderCollapse:hs(ho,!1),outlined:hs(ho,!1),responsive:hs(ko,!1),small:hs(ho,!1),stickyHeader:hs(ko,!1),striped:hs(ho,!1),tableClass:hs(To),tableVariant:hs(go)},Qw=i.default.extend({mixins:[Za],provide:function(){return{bvTable:this}},inheritAttrs:!1,props:Jw,computed:{isResponsive:function(){var t=this.responsive;return""===t||t},isStickyHeader:function(){var t=this.stickyHeader;return t=""===t||t,!this.isStacked&&t},wrapperClasses:function(){var t=this.isResponsive;return[this.isStickyHeader?"b-table-sticky-header":"",!0===t?"table-responsive":t?"table-responsive-".concat(this.responsive):""].filter(ne)},wrapperStyles:function(){var t=this.isStickyHeader;return t&&!Vt(t)?{maxHeight:t}:{}},tableClasses:function(){var t=this.hover,e=this.tableVariant;return t=this.isTableSimple?t:t&&this.computedItems.length>0&&!this.computedBusy,[this.tableClass,{"table-striped":this.striped,"table-hover":t,"table-dark":this.dark,"table-bordered":this.bordered,"table-borderless":this.borderless,"table-sm":this.small,border:this.outlined,"b-table-fixed":this.fixed,"b-table-caption-top":this.captionTop,"b-table-no-border-collapse":this.noBorderCollapse},e?"".concat(this.dark?"bg":"table","-").concat(e):"",this.stackedTableClasses,this.selectableTableClasses]},tableAttrs:function(){var t=this.computedItems,e=this.filteredItems,i=this.computedFields,n=this.selectableTableAttrs,o=this.isTableSimple?{}:{"aria-busy":this.computedBusy?"true":"false","aria-colcount":vr(i.length),"aria-describedby":this.bvAttrs["aria-describedby"]||this.$refs.caption?this.captionId:null};return c(c(c({"aria-rowcount":t&&e&&e.length>t.length?vr(e.length):null},this.bvAttrs),{},{id:this.safeId(),role:"table"},o),n)}},render:function(t){var e=this.wrapperClasses,i=this.renderCaption,n=this.renderColgroup,o=this.renderThead,r=this.renderTbody,s=this.renderTfoot,a=[];this.isTableSimple?a.push(this.normalizeSlot()):(a.push(i?i():null),a.push(n?n():null),a.push(o?o():null),a.push(r?r():null),a.push(s?s():null));var l=t("table",{staticClass:"table b-table",class:this.tableClasses,attrs:this.tableAttrs,key:"b-table"},a.filter(ne));return e.length>0?t("div",{class:e,style:this.wrapperStyles,key:"wrap"},[l]):l}}),tT=vs({tbodyTransitionHandlers:hs(vo),tbodyTransitionProps:hs(vo)},gn),eT=i.default.extend({name:gn,mixins:[Za,Qa,Cs],provide:function(){return{bvTableRowGroup:this}},inject:{bvTable:{default:function(){return{}}}},inheritAttrs:!1,props:tT,computed:{isTbody:function(){return!0},isDark:function(){return this.bvTable.dark},isStacked:function(){return this.bvTable.isStacked},isResponsive:function(){return this.bvTable.isResponsive},isStickyHeader:function(){return!1},hasStickyHeader:function(){return!this.isStacked&&this.bvTable.stickyHeader},tableVariant:function(){return this.bvTable.tableVariant},isTransitionGroup:function(){return this.tbodyTransitionProps||this.tbodyTransitionHandlers},tbodyAttrs:function(){return c({role:"rowgroup"},this.bvAttrs)},tbodyProps:function(){var t=this.tbodyTransitionProps;return t?c(c({},t),{},{tag:"tbody"}):{}}},render:function(t){var e={props:this.tbodyProps,attrs:this.tbodyAttrs};return this.isTransitionGroup?(e.on=this.tbodyTransitionHandlers||{},e.nativeOn=this.bvListeners):e.on=this.bvListeners,t(this.isTransitionGroup?"transition-group":"tbody",e,this.normalizeSlot())}}),iT=["TD","TH","TR"],nT=function(t){if(!t||!t.target)return!1;var e=t.target;if(e.disabled||-1!==iT.indexOf(e.tagName))return!1;if(Er(".dropdown-menu",e))return!0;var i="LABEL"===e.tagName?e:Er("label",e);if(i){var n=jr(i,"for"),o=n?Ar(n):Or("input, select, textarea",i);if(o&&!o.disabled)return!0}return Vr(e,ww)},oT=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document,e=Xr();return!!(e&&""!==e.toString().trim()&&e.containsNode&&kr(t))&&e.containsNode(t,!0)},rT=vs(ow,"BTh"),sT=i.default.extend({name:"BTh",extends:rw,props:rT,computed:{tag:function(){return"th"}}}),aT={detailsTdClass:hs(To),tbodyTrAttr:hs(Fo),tbodyTrClass:hs([].concat(T(To),[po]))},lT=i.default.extend({props:aT,methods:{getTdValues:function(t,e,i,n){var o=this.$parent;if(i){var r=re(t,e,"");return Ot(i)?i(r,e,t):Et(i)&&Ot(o[i])?o[i](r,e,t):i}return n},getThValues:function(t,e,i,n,o){var r=this.$parent;if(i){var s=re(t,e,"");return Ot(i)?i(s,e,t,n):Et(i)&&Ot(r[i])?r[i](s,e,t,n):i}return o},getFormattedValue:function(t,e){var i=e.key,n=this.getFieldFormatter(i),o=re(t,i,null);return Ot(n)&&(o=n(o,i,t)),Pt(o)?"":o},toggleDetailsFactory:function(t,e){var i=this;return function(){t&&i.$set(e,gw,!e[gw])}},rowHovered:function(t){this.tbodyRowEvtStopped(t)||this.emitTbodyRowEvent("row-hovered",t)},rowUnhovered:function(t){this.tbodyRowEvtStopped(t)||this.emitTbodyRowEvent("row-unhovered",t)},renderTbodyRowCell:function(t,e,i,n){var o=this,r=this.isStacked,s=t.key,a=t.label,l=t.isRowHeader,u=this.$createElement,d=this.hasNormalizedSlot(Ko),h=this.getFormattedValue(i,t),f=!r&&(this.isResponsive||this.stickyHeader)&&t.stickyColumn,p=f?l?sT:rw:l?"th":"td",m=i[vw]&&i[vw][s]?i[vw][s]:t.variant||null,v={class:[t.class?t.class:"",this.getTdValues(i,s,t.tdClass,"")],props:{},attrs:c({"aria-colindex":String(e+1)},l?this.getThValues(i,s,t.thAttr,"row",{}):this.getTdValues(i,s,t.tdAttr,{})),key:"row-".concat(n,"-cell-").concat(e,"-").concat(s)};f?v.props={stackedHeading:r?a:null,stickyColumn:!0,variant:m}:(v.attrs["data-label"]=r&&!Pt(a)?vr(a):null,v.attrs.role=l?"rowheader":"cell",v.attrs.scope=l?"row":null,m&&v.class.push("".concat(this.dark?"bg":"table","-").concat(m)));var b={item:i,index:n,field:t,unformatted:re(i,s,""),value:h,toggleDetails:this.toggleDetailsFactory(d,i),detailsShowing:Boolean(i[gw])};this.supportsSelectableRows&&(b.rowSelected=this.isRowSelected(n),b.selectRow=function(){return o.selectRow(n)},b.unselectRow=function(){return o.unselectRow(n)});var g=this.$_bodyFieldSlotNameCache[s],y=g?this.normalizeSlot(g,b):vr(h);return this.isStacked&&(y=[u("div",[y])]),u(p,v,[y])},renderTbodyRow:function(t,e){var i=this,n=this.computedFields,o=this.striped,r=this.primaryKey,s=this.currentPage,a=this.perPage,l=this.tbodyTrClass,u=this.tbodyTrAttr,d=this.$createElement,h=this.hasNormalizedSlot(Ko),f=t[gw]&&h,p=this.$listeners["row-clicked"]||this.hasSelectableRowClick,m=[],v=f?this.safeId("_details_".concat(e,"_")):null,b=n.map((function(n,o){return i.renderTbodyRowCell(n,o,t,e)})),g=null;s&&a&&a>0&&(g=String((s-1)*a+e+1));var y=vr(re(t,r))||null,w=y||vr(e),T=y?this.safeId("_row_".concat(y)):null,C=this.selectableRowClasses?this.selectableRowClasses(e):{},x=this.selectableRowAttrs?this.selectableRowAttrs(e):{},S=Ot(l)?l(t,"row"):l,k=Ot(u)?u(t,"row"):u;if(m.push(d(Qy,{class:[S,C,f?"b-table-has-details":""],props:{variant:t[bw]||null},attrs:c(c({id:T},k),{},{tabindex:p?"0":null,"data-pk":y||null,"aria-details":v,"aria-owns":v,"aria-rowindex":g},x),on:{mouseenter:this.rowHovered,mouseleave:this.rowUnhovered},key:"__b-table-row-".concat(w,"__"),ref:"item-rows",refInFor:!0},b)),f){var $={item:t,index:e,fields:n,toggleDetails:this.toggleDetailsFactory(h,t)};this.supportsSelectableRows&&($.rowSelected=this.isRowSelected(e),$.selectRow=function(){return i.selectRow(e)},$.unselectRow=function(){return i.unselectRow(e)});var B=d(rw,{props:{colspan:n.length},class:this.detailsTdClass},[this.normalizeSlot(Ko,$)]);o&&m.push(d("tr",{staticClass:"d-none",attrs:{"aria-hidden":"true",role:"presentation"},key:"__b-table-details-stripe__".concat(w)}));var _=Ot(this.tbodyTrClass)?this.tbodyTrClass(t,Ko):this.tbodyTrClass,D=Ot(this.tbodyTrAttr)?this.tbodyTrAttr(t,Ko):this.tbodyTrAttr;m.push(d(Qy,{staticClass:"b-table-details",class:[_],props:{variant:t[bw]||null},attrs:c(c({},D),{},{id:v,tabindex:"-1"}),key:"__b-table-details__".concat(w)},[B]))}else h&&(m.push(d()),o&&m.push(d()));return m}}}),cT=function(t){return"cell(".concat(t||"",")")},uT=ee(c(c(c({},tT),aT),{},{tbodyClass:hs(To)})),dT=i.default.extend({mixins:[lT],props:uT,beforeDestroy:function(){this.$_bodyFieldSlotNameCache=null},methods:{getTbodyTrs:function(){var t=this.$refs,e=t.tbody?t.tbody.$el||t.tbody:null,i=(t["item-rows"]||[]).map((function(t){return t.$el||t}));return e&&e.children&&e.children.length>0&&i&&i.length>0?ir(e.children).filter((function(t){return nr(i,t)})):[]},getTbodyTrIndex:function(t){if(!kr(t))return-1;var e="TR"===t.tagName?t:Er("tr",t,!0);return e?this.getTbodyTrs().indexOf(e):-1},emitTbodyRowEvent:function(t,e){if(t&&this.hasListener(t)&&e&&e.target){var i=this.getTbodyTrIndex(e.target);if(i>-1){var n=this.computedItems[i];this.$emit(t,n,i,e)}}},tbodyRowEvtStopped:function(t){return this.stopIfBusy&&this.stopIfBusy(t)},onTbodyRowKeydown:function(t){var e=t.target,i=t.keyCode;if(!this.tbodyRowEvtStopped(t)&&"TR"===e.tagName&&_r(e)&&0===e.tabIndex)if(nr([Ha,Ga],i))Bs(t),this.onTBodyRowClicked(t);else if(nr([Wa,Ra,za,Ma],i)){var n=this.getTbodyTrIndex(e);if(n>-1){Bs(t);var o=this.getTbodyTrs(),r=t.shiftKey;i===za||r&&i===Wa?ts(o[0]):i===Ma||r&&i===Ra?ts(o[o.length-1]):i===Wa&&n>0?ts(o[n-1]):i===Ra&&n<o.length-1&&ts(o[n+1])}}},onTBodyRowClicked:function(t){this.tbodyRowEvtStopped(t)||nT(t)||oT(this.$el)||this.emitTbodyRowEvent(Jn,t)},onTbodyRowMiddleMouseRowClicked:function(t){this.tbodyRowEvtStopped(t)||2!==t.which||this.emitTbodyRowEvent("row-middle-clicked",t)},onTbodyRowContextmenu:function(t){this.tbodyRowEvtStopped(t)||this.emitTbodyRowEvent("row-contextmenu",t)},onTbodyRowDblClicked:function(t){this.tbodyRowEvtStopped(t)||nT(t)||this.emitTbodyRowEvent("row-dblclicked",t)},renderTbody:function(){var t=this,e=this.computedItems,i=this.renderBusy,n=this.renderTopRow,o=this.renderEmpty,r=this.renderBottomRow,s=this.$createElement,a=this.hasListener(Jn)||this.hasSelectableRowClick,l=[],c=i?i():null;if(c)l.push(c);else{var u={},d=cT();d=this.hasNormalizedSlot(d)?d:null,this.computedFields.forEach((function(e){var i=e.key,n=cT(i),o=cT(i.toLowerCase());u[i]=t.hasNormalizedSlot(n)?n:t.hasNormalizedSlot(o)?o:d})),this.$_bodyFieldSlotNameCache=u,l.push(n?n():s()),e.forEach((function(e,i){l.push(t.renderTbodyRow(e,i))})),l.push(o?o():s()),l.push(r?r():s())}var h={auxclick:this.onTbodyRowMiddleMouseRowClicked,contextmenu:this.onTbodyRowContextmenu,dblclick:this.onTbodyRowDblClicked};return a&&(h.click=this.onTBodyRowClicked,h.keydown=this.onTbodyRowKeydown),s(eT,{class:this.tbodyClass||null,props:ps(tT,this.$props),on:h,ref:"tbody"},l)}}}),hT=vs({footVariant:hs(go)},yn),fT=i.default.extend({name:yn,mixins:[Za,Qa,Cs],provide:function(){return{bvTableRowGroup:this}},inject:{bvTable:{default:function(){return{}}}},inheritAttrs:!1,props:hT,computed:{isTfoot:function(){return!0},isDark:function(){return this.bvTable.dark},isStacked:function(){return this.bvTable.isStacked},isResponsive:function(){return this.bvTable.isResponsive},isStickyHeader:function(){return!1},hasStickyHeader:function(){return!this.isStacked&&this.bvTable.stickyHeader},tableVariant:function(){return this.bvTable.tableVariant},tfootClasses:function(){return[this.footVariant?"thead-".concat(this.footVariant):null]},tfootAttrs:function(){return c(c({},this.bvAttrs),{},{role:"rowgroup"})}},render:function(t){return t("tfoot",{class:this.tfootClasses,attrs:this.tfootAttrs,on:this.bvListeners},this.normalizeSlot())}}),pT={footClone:hs(ho,!1),footRowVariant:hs(go),footVariant:hs(go),tfootClass:hs(To),tfootTrClass:hs(To)},mT=i.default.extend({props:pT,methods:{renderTFootCustom:function(){var t=this.$createElement;return this.hasNormalizedSlot(Lo)?t(fT,{class:this.tfootClass||null,props:{footVariant:this.footVariant||this.headVariant||null},key:"bv-tfoot-custom"},this.normalizeSlot(Lo,{items:this.computedItems.slice(),fields:this.computedFields.slice(),columns:this.computedFields.length})):t()},renderTfoot:function(){return this.footClone?this.renderThead(!0):this.renderTFootCustom()}}}),vT=vs({headVariant:hs(go)},wn),bT=i.default.extend({name:wn,mixins:[Za,Qa,Cs],provide:function(){return{bvTableRowGroup:this}},inject:{bvTable:{default:function(){return{}}}},inheritAttrs:!1,props:vT,computed:{isThead:function(){return!0},isDark:function(){return this.bvTable.dark},isStacked:function(){return this.bvTable.isStacked},isResponsive:function(){return this.bvTable.isResponsive},isStickyHeader:function(){return!this.isStacked&&this.bvTable.stickyHeader},hasStickyHeader:function(){return!this.isStacked&&this.bvTable.stickyHeader},tableVariant:function(){return this.bvTable.tableVariant},theadClasses:function(){return[this.headVariant?"thead-".concat(this.headVariant):null]},theadAttrs:function(){return c({role:"rowgroup"},this.bvAttrs)}},render:function(t){return t("thead",{class:this.theadClasses,attrs:this.theadAttrs,on:this.bvListeners},this.normalizeSlot())}}),gT=function(t){return"head(".concat(t||"",")")},yT=function(t){return"foot(".concat(t||"",")")},wT={headRowVariant:hs(go),headVariant:hs(go),theadClass:hs(To),theadTrClass:hs(To)},TT=i.default.extend({props:wT,methods:{fieldClasses:function(t){return[t.class?t.class:"",t.thClass?t.thClass:""]},headClicked:function(t,e,i){this.stopIfBusy&&this.stopIfBusy(t)||nT(t)||oT(this.$el)||(Bs(t),this.$emit(Hn,e.key,e,t,i))},renderThead:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.computedFields,n=this.isSortable,o=this.isSelectable,r=this.headVariant,s=this.footVariant,a=this.headRowVariant,l=this.footRowVariant,u=this.$createElement;if(this.isStackedAlways||0===i.length)return u();var d=n||this.hasListener(Hn),h=o?this.selectAllRows:su,f=o?this.clearSelected:su,p=function(i,o){var r=i.label,s=i.labelHtml,a=i.variant,l=i.stickyColumn,p=i.key,m=null;i.label.trim()||i.headerTitle||(m=fr(i.key));var v={};d&&(v.click=function(n){t.headClicked(n,i,e)},v.keydown=function(n){var o=n.keyCode;o!==Ha&&o!==Ga||t.headClicked(n,i,e)});var b=n?t.sortTheadThAttrs(p,i,e):{},g=n?t.sortTheadThClasses(p,i,e):null,y=n?t.sortTheadThLabel(p,i,e):null,w={class:[t.fieldClasses(i),g],props:{variant:a,stickyColumn:l},style:i.thStyle||{},attrs:c(c({tabindex:d&&i.sortable?"0":null,abbr:i.headerAbbr||null,title:i.headerTitle||null,"aria-colindex":o+1,"aria-label":m},t.getThValues(null,p,i.thAttr,e?"foot":"head",{})),b),on:v,key:p},C=[gT(p),gT(p.toLowerCase()),gT()];e&&(C=[yT(p),yT(p.toLowerCase()),yT()].concat(T(C)));var x={label:r,column:p,field:i,isFoot:e,selectAllRows:h,clearSelected:f},S=t.normalizeSlot(C,x)||u("div",{domProps:Fl(s,r)}),k=y?u("span",{staticClass:"sr-only"}," (".concat(y,")")):null;return u(sT,w,[S,k].filter(ne))},m=i.map(p).filter(ne),v=[];if(e)v.push(u(Qy,{class:this.tfootTrClass,props:{variant:Pt(l)?a:l}},m));else{var b={columns:i.length,fields:i,selectAllRows:h,clearSelected:f};v.push(this.normalizeSlot(Qo,b)||u()),v.push(u(Qy,{class:this.theadTrClass,props:{variant:a}},m))}return u(e?fT:bT,{class:(e?this.tfootClass:this.theadClass)||null,props:e?{footVariant:s||r||null}:{headVariant:r||null},key:e?"bv-tfoot":"bv-thead"},v)}}}),CT=i.default.extend({methods:{renderTopRow:function(){var t=this.computedFields,e=this.stacked,i=this.tbodyTrClass,n=this.tbodyTrAttr,o=this.$createElement;return this.hasNormalizedSlot(er)&&!0!==e&&""!==e?o(Qy,{staticClass:"b-table-top-row",class:[Ot(i)?i(null,"row-top"):i],attrs:Ot(n)?n(null,"row-top"):n,key:"b-top-row"},[this.normalizeSlot(er,{columns:t.length,fields:t})]):o()}}}),xT=vs(ee(c(c(c(c(c(c(c(c(c(c(c(c(c(c(c(c(c(c({},fc),tw),aw),cw),dw),fw),Cw),Fw),Pw),Lw),Mw),qw),Xw),Jw),uT),pT),wT),{})),fn),ST=i.default.extend({name:fn,mixins:[Za,Ky,pc,Cs,Iw,Qw,Zw,TT,mT,dT,Zw,xw,Kw,Ow,uw,hw,Hw,pw,CT,ew,lw,Aw],props:xT}),kT=vs(ee(c(c(c(c(c(c(c(c(c({},fc),cw),dw),Fw),Xw),Jw),uT),pT),wT)),mn),$T=i.default.extend({name:mn,mixins:[Za,Ky,pc,Cs,Iw,Qw,Zw,TT,mT,dT,uw,hw],props:kT}),BT=vs(ee(c(c(c({},fc),Xw),Jw)),vn),_T=i.default.extend({name:vn,mixins:[Za,Ky,pc,Cs,Qw,Zw],props:BT,computed:{isTableSimple:function(){return!0}}}),DT=me({components:{BTable:ST},plugins:{TableLitePlugin:me({components:{BTableLite:$T}}),TableSimplePlugin:me({components:{BTableSimple:_T,BTbody:eT,BThead:bT,BTfoot:fT,BTr:Qy,BTd:rw,BTh:sT}})}}),FT=function(t){return t>0},IT=vs({animation:hs(go),columns:hs(mo,5,FT),hideHeader:hs(ho,!1),rows:hs(mo,3,FT),showFooter:hs(ho,!1),tableProps:hs(vo,{})},cn),PT=i.default.extend({name:cn,functional:!0,props:IT,render:function(t,e){var i=e.props,n=i.animation,o=i.columns,r=t("th",[t(Gy,{props:{animation:n}})]),s=t("tr",rr(o,r)),a=t("td",[t(Gy,{props:{width:"75%",animation:n}})]),l=t("tr",rr(o,a)),u=t("tbody",rr(i.rows,l)),d=i.hideHeader?t():t("thead",[s]),h=i.showFooter?t("tfoot",[s]):t();return t(_T,{props:c({},i.tableProps)},[d,u,h])}}),OT=vs({loading:hs(ho,!1)},un),VT=me({components:{BSkeleton:Gy,BSkeletonIcon:Yy,BSkeletonImg:qy,BSkeletonTable:PT,BSkeletonWrapper:i.default.extend({name:un,functional:!0,props:OT,render:function(t,e){var i=e.data,n=e.props,o=e.slots,r=e.scopedSlots,s=o(),a=r||{},l={};return n.loading?t("div",F(i,{attrs:{role:"alert","aria-live":"polite","aria-busy":!0},staticClass:"b-skeleton-wrapper",key:"loading"}),Ts("loading",l,a,s)):Ts(Ao,l,a,s)}})}}),ET=me({components:{BSpinner:mg}}),LT=ys("value",{type:mo}),AT=LT.mixin,RT=LT.props,MT=LT.prop,HT=LT.event,zT=function(t){return!t.disabled},NT=i.default.extend({name:"BVTabButton",inject:{bvTabs:{default:function(){return{}}}},props:{controls:hs(go),id:hs(go),noKeyNav:hs(ho,!1),posInSet:hs(mo),setSize:hs(mo),tab:hs(),tabIndex:hs(mo)},methods:{focus:function(){ts(this.$refs.link)},handleEvt:function(t){if(!this.tab.disabled){var e=t.type,i=t.keyCode,n=t.shiftKey;"click"===e||"keydown"===e&&i===Ga?(Bs(t),this.$emit(Bn,t)):"keydown"!==e||this.noKeyNav||(-1!==[Wa,Na,za].indexOf(i)?(Bs(t),n||i===za?this.$emit(An,t):this.$emit(Xn,t)):-1!==[Ra,ja,Ma].indexOf(i)&&(Bs(t),n||i===Ma?this.$emit(Gn,t):this.$emit(Un,t)))}}},render:function(t){var e=this.id,i=this.tabIndex,n=this.setSize,o=this.posInSet,r=this.controls,s=this.handleEvt,a=this.tab,l=a.title,u=a.localActive,d=a.disabled,h=a.titleItemClass,f=a.titleLinkClass,p=a.titleLinkAttributes,m=t(ol,{staticClass:"nav-link",class:[{active:u&&!d,disabled:d},f,u?this.bvTabs.activeNavItemClass:null],props:{disabled:d},attrs:c(c({},p),{},{id:e,role:"tab",tabindex:i,"aria-selected":u&&!d?"true":"false","aria-setsize":n,"aria-posinset":o,"aria-controls":r}),on:{click:s,keydown:s},ref:"link"},[this.tab.normalizeSlot(tr)||l]);return t("li",{staticClass:"nav-item",class:[h],attrs:{role:"presentation"}},[m])}}),jT=Qt(Vb,["tabs","isNavBar","cardHeader"]),GT=vs(ee(c(c(c(c({},fc),RT),jT),{},{activeNavItemClass:hs(To),activeTabClass:hs(To),card:hs(ho,!1),contentClass:hs(To),end:hs(ho,!1),lazy:hs(ho,!1),navClass:hs(To),navWrapperClass:hs(To),noFade:hs(ho,!1),noKeyNav:hs(ho,!1),noNavStyle:hs(ho,!1),tag:hs(go,"div")})),bn),WT=i.default.extend({name:bn,mixins:[pc,AT,Cs],provide:function(){return{bvTabs:this}},props:GT,data:function(){return{currentTab:lr(this[MT],-1),tabs:[],registeredTabs:[]}},computed:{fade:function(){return!this.noFade},localNavClass:function(){var t=[];return this.card&&this.vertical&&t.push("card-header","h-100","border-bottom-0","rounded-0"),[].concat(t,[this.navClass])}},watch:(ng={},a(ng,MT,(function(t,e){if(t!==e){t=lr(t,-1),e=lr(e,0);var i=this.tabs[t];i&&!i.disabled?this.activateTab(i):t<e?this.previousTab():this.nextTab()}})),a(ng,"currentTab",(function(t){var e=-1;this.tabs.forEach((function(i,n){n!==t||i.disabled?i.localActive=!1:(i.localActive=!0,e=n)})),this.$emit(HT,e)})),a(ng,"tabs",(function(t,e){var i=this;Ua(t.map((function(t){return t._uid})),e.map((function(t){return t._uid})))||this.$nextTick((function(){i.$emit("changed",t.slice(),e.slice())}))})),a(ng,"registeredTabs",(function(){this.updateTabs()})),ng),created:function(){this.$_observer=null},mounted:function(){this.setObserver(!0)},beforeDestroy:function(){this.setObserver(!1),this.tabs=[]},methods:{registerTab:function(t){nr(this.registeredTabs,t)||this.registeredTabs.push(t)},unregisterTab:function(t){this.registeredTabs=this.registeredTabs.slice().filter((function(e){return e!==t}))},setObserver:function(){var t=this,e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];if(this.$_observer&&this.$_observer.disconnect(),this.$_observer=null,e){var i=function(){t.$nextTick((function(){xr((function(){t.updateTabs()}))}))};this.$_observer=au(this.$refs.content,i,{childList:!0,subtree:!1,attributes:!0,attributeFilter:["id"]})}},getTabs:function(){var t=this.registeredTabs.filter((function(t){return 0===t.$children.filter((function(t){return t._isTab})).length})),e=[];if(M&&t.length>0){var i=t.map((function(t){return"#".concat(t.safeId())})).join(", ");e=Pr(i,this.$el).map((function(t){return t.id})).filter(ne)}return zw(t,(function(t,i){return e.indexOf(t.safeId())-e.indexOf(i.safeId())}))},updateTabs:function(){var t=this.getTabs(),e=t.indexOf(t.slice().reverse().find((function(t){return t.localActive&&!t.disabled})));if(e<0){var i=this.currentTab;i>=t.length?e=t.indexOf(t.slice().reverse().find(zT)):t[i]&&!t[i].disabled&&(e=i)}e<0&&(e=t.indexOf(t.find(zT))),t.forEach((function(t,i){t.localActive=i===e})),this.tabs=t,this.currentTab=e},getButtonForTab:function(t){return(this.$refs.buttons||[]).find((function(e){return e.tab===t}))},updateButton:function(t){var e=this.getButtonForTab(t);e&&e.$forceUpdate&&e.$forceUpdate()},activateTab:function(t){var e=this.currentTab,i=this.tabs,n=!1;if(t){var o=i.indexOf(t);if(o!==e&&o>-1&&!t.disabled){var r=new BvEvent("activate-tab",{cancelable:!0,vueTarget:this,componentId:this.safeId()});this.$emit(r.type,o,e,r),r.defaultPrevented||(this.currentTab=o,n=!0)}}return n||this[MT]===e||this.$emit(HT,e),n},deactivateTab:function(t){return!!t&&this.activateTab(this.tabs.filter((function(e){return e!==t})).find(zT))},focusButton:function(t){var e=this;this.$nextTick((function(){ts(e.getButtonForTab(t))}))},emitTabClick:function(t,e){Nt(e)&&t&&t.$emit&&!t.disabled&&t.$emit(Bn,e)},clickTab:function(t,e){this.activateTab(t),this.emitTabClick(t,e)},firstTab:function(t){var e=this.tabs.find(zT);this.activateTab(e)&&t&&(this.focusButton(e),this.emitTabClick(e,t))},previousTab:function(t){var e=Us(this.currentTab,0),i=this.tabs.slice(0,e).reverse().find(zT);this.activateTab(i)&&t&&(this.focusButton(i),this.emitTabClick(i,t))},nextTab:function(t){var e=Us(this.currentTab,-1),i=this.tabs.slice(e+1).find(zT);this.activateTab(i)&&t&&(this.focusButton(i),this.emitTabClick(i,t))},lastTab:function(t){var e=this.tabs.slice().reverse().find(zT);this.activateTab(e)&&t&&(this.focusButton(e),this.emitTabClick(e,t))}},render:function(t){var e=this,i=this.align,n=this.card,o=this.end,r=this.fill,s=this.firstTab,l=this.justified,c=this.lastTab,u=this.nextTab,d=this.noKeyNav,h=this.noNavStyle,f=this.pills,p=this.previousTab,m=this.small,v=this.tabs,b=this.vertical,g=v.find((function(t){return t.localActive&&!t.disabled})),y=v.find((function(t){return!t.disabled})),w=v.map((function(i,n){var o,r=i.safeId,l=null;return d||(l=-1,(i===g||!g&&i===y)&&(l=null)),t(NT,{props:{controls:r?r():null,id:i.controlledBy||(r?r("_BV_tab_button_"):null),noKeyNav:d,posInSet:n+1,setSize:v.length,tab:i,tabIndex:l},on:(o={},a(o,Bn,(function(t){e.clickTab(i,t)})),a(o,An,s),a(o,Xn,p),a(o,Un,u),a(o,Gn,c),o),key:i._uid||n,ref:"buttons",refInFor:!0})})),T=t(Eb,{class:this.localNavClass,attrs:{role:"tablist",id:this.safeId("_BV_tab_controls_")},props:{fill:r,justified:l,align:i,tabs:!h&&!f,pills:!h&&f,vertical:b,small:m,cardHeader:n&&!b},ref:"nav"},[this.normalizeSlot("tabs-start")||t(),w,this.normalizeSlot("tabs-end")||t()]);T=t("div",{class:[{"card-header":n&&!b&&!o,"card-footer":n&&!b&&o,"col-auto":b},this.navWrapperClass],key:"bv-tabs-nav"},[T]);var C=this.normalizeSlot()||[],x=t();0===C.length&&(x=t("div",{class:["tab-pane","active",{"card-body":n}],key:"bv-empty-tab"},this.normalizeSlot(Ro)));var S=t("div",{staticClass:"tab-content",class:[{col:b},this.contentClass],attrs:{id:this.safeId("_BV_tab_container_")},key:"bv-content",ref:"content"},[C,x]);return t(this.tag,{staticClass:"tabs",class:{row:b,"no-gutters":b&&n},attrs:{id:this.safeId()}},[o?S:t(),T,o?t():S])}}),YT="active",UT="update:active",qT=vs(ee(c(c({},fc),{},(a(og={},YT,hs(ho,!1)),a(og,"buttonId",hs(go)),a(og,"disabled",hs(ho,!1)),a(og,"lazy",hs(ho,!1)),a(og,"noBody",hs(ho,!1)),a(og,"tag",hs(go,"div")),a(og,"title",hs(go)),a(og,"titleItemClass",hs(To)),a(og,"titleLinkAttributes",hs(vo)),a(og,"titleLinkClass",hs(To)),og))),hn),KT=me({components:{BTabs:WT,BTab:i.default.extend({name:hn,mixins:[pc,Cs],inject:{bvTabs:{default:function(){return{}}}},props:qT,data:function(){return{localActive:this.active&&!this.disabled}},computed:{_isTab:function(){return!0},tabClasses:function(){var t=this.localActive;return[{active:t,disabled:this.disabled,"card-body":this.bvTabs.card&&!this.noBody},t?this.bvTabs.activeTabClass:null]},controlledBy:function(){return this.buttonId||this.safeId("__BV_tab_button__")},computedNoFade:function(){return!this.bvTabs.fade},computedLazy:function(){return this.bvTabs.lazy||this.lazy}},watch:(rg={},a(rg,YT,(function(t,e){t!==e&&(t?this.activate():this.deactivate()||this.$emit(UT,this.localActive))})),a(rg,"disabled",(function(t,e){if(t!==e){var i=this.bvTabs.firstTab;t&&this.localActive&&i&&(this.localActive=!1,i())}})),a(rg,"localActive",(function(t){this.$emit(UT,t)})),rg),mounted:function(){this.registerTab()},updated:function(){var t=this.bvTabs.updateButton;t&&this.hasNormalizedSlot(tr)&&t(this)},beforeDestroy:function(){this.unregisterTab()},methods:{registerTab:function(){var t=this.bvTabs.registerTab;t&&t(this)},unregisterTab:function(){var t=this.bvTabs.unregisterTab;t&&t(this)},activate:function(){var t=this.bvTabs.activateTab;return!(!t||this.disabled)&&t(this)},deactivate:function(){var t=this.bvTabs.deactivateTab;return!(!t||!this.localActive)&&t(this)}},render:function(t){var e=this.localActive,i=t(this.tag,{staticClass:"tab-pane",class:this.tabClasses,directives:[{name:"show",value:e}],attrs:{role:"tabpanel",id:this.safeId(),"aria-hidden":e?"false":"true","aria-labelledby":this.controlledBy||null},ref:"panel"},[e||!this.computedLazy?this.normalizeSlot():t()]);return t(Ls,{props:{mode:"out-in",noFade:this.computedNoFade}},[i])}})}}),XT=me({components:{BTime:av}});function ZT(t){return(ZT="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function JT(t){return function(t){if(Array.isArray(t)){for(var e=0,i=new Array(t.length);e<t.length;e++)i[e]=t[e];return i}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}var QT="undefined"!=typeof window;function tC(t,e){return e.reduce((function(e,i){return t.hasOwnProperty(i)&&(e[i]=t[i]),e}),{})}var eC,iC,nC={},oC={},rC={},sC=new(i.default.extend({data:function(){return{transports:nC,targets:oC,sources:rC,trackInstances:QT}},methods:{open:function(t){if(QT){var e=t.to,n=t.from,o=t.passengers,r=t.order,s=void 0===r?1/0:r;if(e&&n&&o){var a,l={to:e,from:n,passengers:(a=o,Array.isArray(a)||"object"===ZT(a)?Object.freeze(a):a),order:s};-1===Object.keys(this.transports).indexOf(e)&&i.default.set(this.transports,e,[]);var c,u=this.$_getTransportIndex(l),d=this.transports[e].slice(0);-1===u?d.push(l):d[u]=l,this.transports[e]=(c=function(t,e){return t.order-e.order},d.map((function(t,e){return[e,t]})).sort((function(t,e){return c(t[1],e[1])||t[0]-e[0]})).map((function(t){return t[1]})))}}},close:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=t.to,n=t.from;if(i&&(n||!1!==e)&&this.transports[i])if(e)this.transports[i]=[];else{var o=this.$_getTransportIndex(t);if(o>=0){var r=this.transports[i].slice(0);r.splice(o,1),this.transports[i]=r}}},registerTarget:function(t,e,i){QT&&(this.trackInstances&&!i&&this.targets[t]&&console.warn("[portal-vue]: Target ".concat(t," already exists")),this.$set(this.targets,t,Object.freeze([e])))},unregisterTarget:function(t){this.$delete(this.targets,t)},registerSource:function(t,e,i){QT&&(this.trackInstances&&!i&&this.sources[t]&&console.warn("[portal-vue]: source ".concat(t," already exists")),this.$set(this.sources,t,Object.freeze([e])))},unregisterSource:function(t){this.$delete(this.sources,t)},hasTarget:function(t){return!(!this.targets[t]||!this.targets[t][0])},hasSource:function(t){return!(!this.sources[t]||!this.sources[t][0])},hasContentFor:function(t){return!!this.transports[t]&&!!this.transports[t].length},$_getTransportIndex:function(t){var e=t.to,i=t.from;for(var n in this.transports[e])if(this.transports[e][n].from===i)return+n;return-1}}}))(nC),aC=1,lC=i.default.extend({name:"portal",props:{disabled:{type:Boolean},name:{type:String,default:function(){return String(aC++)}},order:{type:Number,default:0},slim:{type:Boolean},slotProps:{type:Object,default:function(){return{}}},tag:{type:String,default:"DIV"},to:{type:String,default:function(){return String(Math.round(1e7*Math.random()))}}},created:function(){var t=this;this.$nextTick((function(){sC.registerSource(t.name,t)}))},mounted:function(){this.disabled||this.sendUpdate()},updated:function(){this.disabled?this.clear():this.sendUpdate()},beforeDestroy:function(){sC.unregisterSource(this.name),this.clear()},watch:{to:function(t,e){e&&e!==t&&this.clear(e),this.sendUpdate()}},methods:{clear:function(t){var e={from:this.name,to:t||this.to};sC.close(e)},normalizeSlots:function(){return this.$scopedSlots.default?[this.$scopedSlots.default]:this.$slots.default},normalizeOwnChildren:function(t){return"function"==typeof t?t(this.slotProps):t},sendUpdate:function(){var t=this.normalizeSlots();if(t){var e={from:this.name,to:this.to,passengers:JT(t),order:this.order};sC.open(e)}else this.clear()}},render:function(t){var e=this.$slots.default||this.$scopedSlots.default||[],i=this.tag;return e&&this.disabled?e.length<=1&&this.slim?this.normalizeOwnChildren(e)[0]:t(i,[this.normalizeOwnChildren(e)]):this.slim?t():t(i,{class:{"v-portal":!0},style:{display:"none"},key:"v-portal-placeholder"})}}),cC=i.default.extend({name:"portalTarget",props:{multiple:{type:Boolean,default:!1},name:{type:String,required:!0},slim:{type:Boolean,default:!1},slotProps:{type:Object,default:function(){return{}}},tag:{type:String,default:"div"},transition:{type:[String,Object,Function]}},data:function(){return{transports:sC.transports,firstRender:!0}},created:function(){var t=this;this.$nextTick((function(){sC.registerTarget(t.name,t)}))},watch:{ownTransports:function(){this.$emit("change",this.children().length>0)},name:function(t,e){sC.unregisterTarget(e),sC.registerTarget(t,this)}},mounted:function(){var t=this;this.transition&&this.$nextTick((function(){t.firstRender=!1}))},beforeDestroy:function(){sC.unregisterTarget(this.name)},computed:{ownTransports:function(){var t=this.transports[this.name]||[];return this.multiple?t:0===t.length?[]:[t[t.length-1]]},passengers:function(){return function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return t.reduce((function(t,i){var n=i.passengers[0],o="function"==typeof n?n(e):i.passengers;return t.concat(o)}),[])}(this.ownTransports,this.slotProps)}},methods:{children:function(){return 0!==this.passengers.length?this.passengers:this.$scopedSlots.default?this.$scopedSlots.default(this.slotProps):this.$slots.default||[]},noWrapper:function(){var t=this.slim&&!this.transition;return t&&this.children().length>1&&console.warn("[portal-vue]: PortalTarget with `slim` option received more than one child element."),t}},render:function(t){var e=this.noWrapper(),i=this.children(),n=this.transition||this.tag;return e?i[0]:this.slim&&!n?t():t(n,{props:{tag:this.transition&&this.tag?this.tag:void 0},class:{"vue-portal-target":!0}},i)}}),uC=0,dC=["disabled","name","order","slim","slotProps","tag","to"],hC=["multiple","transition"],fC=(i.default.extend({name:"MountingPortal",inheritAttrs:!1,props:{append:{type:[Boolean,String]},bail:{type:Boolean},mountTo:{type:String,required:!0},disabled:{type:Boolean},name:{type:String,default:function(){return"mounted_"+String(uC++)}},order:{type:Number,default:0},slim:{type:Boolean},slotProps:{type:Object,default:function(){return{}}},tag:{type:String,default:"DIV"},to:{type:String,default:function(){return String(Math.round(1e7*Math.random()))}},multiple:{type:Boolean,default:!1},targetSlim:{type:Boolean},targetSlotProps:{type:Object,default:function(){return{}}},targetTag:{type:String,default:"div"},transition:{type:[String,Object,Function]}},created:function(){if("undefined"!=typeof document){var t=document.querySelector(this.mountTo);if(t){var e=this.$props;if(sC.targets[e.name])e.bail?console.warn("[portal-vue]: Target ".concat(e.name," is already mounted.\n Aborting because 'bail: true' is set")):this.portalTarget=sC.targets[e.name];else{var i=e.append;if(i){var n="string"==typeof i?i:"DIV",o=document.createElement(n);t.appendChild(o),t=o}var r=tC(this.$props,hC);r.slim=this.targetSlim,r.tag=this.targetTag,r.slotProps=this.targetSlotProps,r.name=this.to,this.portalTarget=new cC({el:t,parent:this.$parent||this,propsData:r})}}else console.error("[portal-vue]: Mount Point '".concat(this.mountTo,"' not found in document"))}},beforeDestroy:function(){var t=this.portalTarget;if(this.append){var e=t.$el;e.parentNode.removeChild(e)}t.$destroy()},render:function(t){if(!this.portalTarget)return console.warn("[portal-vue] Target wasn't mounted"),t();if(!this.$scopedSlots.manual){var e=tC(this.$props,dC);return t(lC,{props:e,attrs:this.$attrs,on:this.$listeners,scopedSlots:this.$scopedSlots},this.$slots.default)}var i=this.$scopedSlots.manual({to:this.to});return Array.isArray(i)&&(i=i[0]),i||t()}}),i.default.extend({mixins:[Cs],data:function(){return{name:"b-toaster"}},methods:{onAfterEnter:function(t){var e=this;xr((function(){Mr(t,"".concat(e.name,"-enter-to"))}))}},render:function(t){return t("transition-group",{props:{tag:"div",name:this.name},on:{afterEnter:this.onAfterEnter}},this.normalizeSlot())}})),pC=vs({ariaAtomic:hs(go),ariaLive:hs(go),name:hs(go,void 0,!0),role:hs(go)},xn),mC=i.default.extend({name:xn,mixins:[Ja],props:pC,data:function(){return{doRender:!1,dead:!1,staticName:this.name}},beforeMount:function(){var t=this,e=this.name;this.staticName=e,sC.hasTarget(e)?(le('A "<portal-target>" with name "'.concat(e,'" already exists in the document.'),xn),this.dead=!0):(this.doRender=!0,this.$once(oo,(function(){t.emitOnRoot(Ds(xn,In),e)})))},destroyed:function(){var t=this.$el;t&&t.parentNode&&t.parentNode.removeChild(t)},render:function(t){var e=t("div",{class:["d-none",{"b-dead-toaster":this.dead}]});if(this.doRender){var i=t(cC,{staticClass:"b-toaster-slot",props:{name:this.staticName,multiple:!0,tag:"div",slim:!1,transition:fC}});e=t("div",{staticClass:"b-toaster",class:[this.staticName],attrs:{id:this.staticName,role:this.role||null,"aria-live":this.ariaLive,"aria-atomic":this.ariaAtomic}},[i])}return e}}),vC=ys("visible",{type:ho,defaultValue:!1,event:$n}),bC=vC.mixin,gC=vC.props,yC=vC.prop,wC=vC.event,TC=Jt(nl,["href","to"]),CC=vs(ee(c(c(c(c({},fc),gC),TC),{},{appendToast:hs(ho,!1),autoHideDelay:hs(_o,5e3),bodyClass:hs(To),headerClass:hs(To),isStatus:hs(ho,!1),noAutoHide:hs(ho,!1),noCloseButton:hs(ho,!1),noFade:hs(ho,!1),noHoverPause:hs(ho,!1),solid:hs(ho,!1),static:hs(ho,!1),title:hs(go),toastClass:hs(To),toaster:hs(go,"b-toaster-top-right"),variant:hs(go)})),Cn),xC=i.default.extend({name:Cn,mixins:[Za,pc,bC,Ja,Cs,ib],inheritAttrs:!1,props:CC,data:function(){return{isMounted:!1,doRender:!1,localShow:!1,isTransitioning:!1,isHiding:!1,order:0,dismissStarted:0,resumeDismiss:0}},computed:{toastClasses:function(){var t=this.appendToast,e=this.variant;return a({"b-toast-solid":this.solid,"b-toast-append":t,"b-toast-prepend":!t},"b-toast-".concat(e),e)},slotScope:function(){return{hide:this.hide}},computedDuration:function(){return Us(lr(this.autoHideDelay,0),1e3)},computedToaster:function(){return String(this.toaster)},transitionHandlers:function(){return{beforeEnter:this.onBeforeEnter,afterEnter:this.onAfterEnter,beforeLeave:this.onBeforeLeave,afterLeave:this.onAfterLeave}},computedAttrs:function(){return c(c({},this.bvAttrs),{},{id:this.safeId(),tabindex:"0"})}},watch:(eC={},a(eC,yC,(function(t){this[t?"show":"hide"]()})),a(eC,"localShow",(function(t){t!==this[yC]&&this.$emit(wC,t)})),a(eC,"toaster",(function(){this.$nextTick(this.ensureToaster)})),a(eC,"static",(function(t){t&&this.localShow&&this.ensureToaster()})),eC),created:function(){this.$_dismissTimer=null},mounted:function(){var t=this;this.isMounted=!0,this.$nextTick((function(){t[yC]&&xr((function(){t.show()}))})),this.listenOnRoot(Fs(Cn,to),(function(e){e===t.safeId()&&t.show()})),this.listenOnRoot(Fs(Cn,Nn),(function(e){e&&e!==t.safeId()||t.hide()})),this.listenOnRoot(Ds(xn,In),(function(e){e===t.computedToaster&&t.hide()}))},beforeDestroy:function(){this.clearDismissTimer()},methods:{show:function(){var t=this;if(!this.localShow){this.ensureToaster();var e=this.buildEvent(to);this.emitEvent(e),this.dismissStarted=this.resumeDismiss=0,this.order=Date.now()*(this.appendToast?1:-1),this.isHiding=!1,this.doRender=!0,this.$nextTick((function(){xr((function(){t.localShow=!0}))}))}},hide:function(){var t=this;if(this.localShow){var e=this.buildEvent(Nn);this.emitEvent(e),this.setHoverHandler(!1),this.dismissStarted=this.resumeDismiss=0,this.clearDismissTimer(),this.isHiding=!0,xr((function(){t.localShow=!1}))}},buildEvent:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new BvEvent(t,c(c({cancelable:!1,target:this.$el||null,relatedTarget:null},e),{},{vueTarget:this,componentId:this.safeId()}))},emitEvent:function(t){var e=t.type;this.emitOnRoot(Ds(Cn,e),t),this.$emit(e,t)},ensureToaster:function(){if(!this.static){var t=this.computedToaster;if(!sC.hasTarget(t)){var e=document.createElement("div");document.body.appendChild(e),new mC({parent:this.$root,propsData:{name:t}}).$mount(e)}}},startDismissTimer:function(){this.clearDismissTimer(),this.noAutoHide||(this.$_dismissTimer=setTimeout(this.hide,this.resumeDismiss||this.computedDuration),this.dismissStarted=Date.now(),this.resumeDismiss=0)},clearDismissTimer:function(){clearTimeout(this.$_dismissTimer),this.$_dismissTimer=null},setHoverHandler:function(t){var e=this.$refs["b-toast"];$s(t,e,"mouseenter",this.onPause,lo),$s(t,e,"mouseleave",this.onUnPause,lo)},onPause:function(){if(!this.noAutoHide&&!this.noHoverPause&&this.$_dismissTimer&&!this.resumeDismiss){var t=Date.now()-this.dismissStarted;t>0&&(this.clearDismissTimer(),this.resumeDismiss=Us(this.computedDuration-t,1e3))}},onUnPause:function(){this.noAutoHide||this.noHoverPause||!this.resumeDismiss?this.resumeDismiss=this.dismissStarted=0:this.startDismissTimer()},onLinkClick:function(){var t=this;this.$nextTick((function(){xr((function(){t.hide()}))}))},onBeforeEnter:function(){this.isTransitioning=!0},onAfterEnter:function(){this.isTransitioning=!1;var t=this.buildEvent(eo);this.emitEvent(t),this.startDismissTimer(),this.setHoverHandler(!0)},onBeforeLeave:function(){this.isTransitioning=!0},onAfterLeave:function(){this.isTransitioning=!1,this.order=0,this.resumeDismiss=this.dismissStarted=0;var t=this.buildEvent(zn);this.emitEvent(t),this.doRender=!1},makeToast:function(t){var e=this,i=this.title,n=this.slotScope,o=la(this),r=[],s=this.normalizeSlot("toast-title",n);s?r.push(s):i&&r.push(t("strong",{staticClass:"mr-2"},i)),this.noCloseButton||r.push(t(Ps,{staticClass:"ml-auto mb-1",on:{click:function(){e.hide()}}}));var a=t();r.length>0&&(a=t("header",{staticClass:"toast-header",class:this.headerClass},r));var l=t(o?ol:"div",{staticClass:"toast-body",class:this.bodyClass,props:o?ps(TC,this):{},on:o?{click:this.onLinkClick}:{}},this.normalizeSlot(Ao,n));return t("div",{staticClass:"toast",class:this.toastClass,attrs:this.computedAttrs,key:"toast-".concat(this._uid),ref:"toast"},[a,l])}},render:function(t){if(!this.doRender||!this.isMounted)return t();var e=this.order,i=this.static,n=this.isHiding,o=this.isStatus,r="b-toast-".concat(this._uid),s=t("div",{staticClass:"b-toast",class:this.toastClasses,attrs:c(c({},i?{}:this.scopedStyleAttrs),{},{id:this.safeId("_toast_outer"),role:n?null:o?"status":"alert","aria-live":n?null:o?"polite":"assertive","aria-atomic":n?null:"true"}),key:r,ref:"b-toast"},[t(Ls,{props:{noFade:this.noFade},on:this.transitionHandlers},[this.localShow?this.makeToast(t):t()])]);return t(lC,{props:{name:r,to:this.computedToaster,order:e,slim:!0,disabled:i}},[s])}}),SC="$bvToast",kC=["id"].concat(T(Kt(Qt(CC,["static","visible"])))),$C={toastContent:"default",title:"toast-title"},BC=function(t){return kC.reduce((function(e,i){return Ft(t[i])||(e[i]=t[i]),e}),{})},_C=me({components:{BToast:xC,BToaster:mC},plugins:{BVToastPlugin:me({plugins:{plugin:function(t){var e=t.extend({name:"BVToastPop",extends:xC,destroyed:function(){var t=this.$el;t&&t.parentNode&&t.parentNode.removeChild(t)},mounted:function(){var t=this,e=function(){t.localShow=!1,t.doRender=!1,t.$nextTick((function(){t.$nextTick((function(){xr((function(){t.$destroy()}))}))}))};this.$parent.$once(ro,e),this.$once(zn,e),this.listenOnRoot(Ds(xn,In),(function(i){i===t.toaster&&e()}))}}),i=function(t,i){if(!ce(SC)){var n=new e({parent:i,propsData:c(c(c({},BC(rs(Cn))),Qt(t,Kt($C))),{},{static:!1,visible:!0})});Kt($C).forEach((function(e){var o=t[e];Ft(o)||("title"===e&&Et(o)&&(o=[i.$createElement("strong",{class:"mr-2"},o)]),n.$slots[$C[e]]=or(o))}));var o=document.createElement("div");document.body.appendChild(o),n.$mount(o)}},n=function(){function t(e){o(this,t),Gt(this,{_vm:e,_root:e.$root}),Yt(this,{_vm:{enumerable:!0,configurable:!1,writable:!1},_root:{enumerable:!0,configurable:!1,writable:!1}})}return s(t,[{key:"toast",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t&&!ce(SC)&&i(c(c({},BC(e)),{},{toastContent:t}),this._vm)}},{key:"show",value:function(t){t&&this._root.$emit(Fs(Cn,to),t)}},{key:"hide",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;this._root.$emit(Fs(Cn,Nn),t)}}]),t}();t.mixin({beforeCreate:function(){this._bv__toast=new n(this)}}),Xt(t.prototype,SC)||Ut(t.prototype,SC,{get:function(){return this&&this._bv__toast||le('"'.concat(SC,'" must be accessed from a Vue instance "this" context.'),Cn),this._bv__toast}})}}})}}),DC="__BV_Tooltip__",FC={focus:!0,hover:!0,click:!0,blur:!0,manual:!0},IC=/^html$/i,PC=/^noninteractive$/i,OC=/^nofade$/i,VC=/^(auto|top(left|right)?|bottom(left|right)?|left(top|bottom)?|right(top|bottom)?)$/i,EC=/^(window|viewport|scrollParent)$/i,LC=/^d\d+$/i,AC=/^ds\d+$/i,RC=/^dh\d+$/i,MC=/^o-?\d+$/i,HC=/^v-.+$/i,zC=/\s+/,NC=function(t,e,i){if(M){var n=function(t,e){var i={title:void 0,trigger:"",placement:"top",fallbackPlacement:"flip",container:!1,animation:!0,offset:0,id:null,html:!1,interactive:!0,disabled:!1,delay:rs(Sn,"delay",50),boundary:String(rs(Sn,"boundary","scrollParent")),boundaryPadding:lr(rs(Sn,"boundaryPadding",5),0),variant:rs(Sn,"variant"),customClass:rs(Sn,"customClass")};if(Et(t.value)||Lt(t.value)||Ot(t.value)?i.title=t.value:Ht(t.value)&&(i=c(c({},i),t.value)),Ft(i.title)){var n=e.data||{};i.title=n.attrs&&!Pt(n.attrs.title)?n.attrs.title:void 0}Ht(i.delay)||(i.delay={show:lr(i.delay,0),hide:lr(i.delay,0)}),t.arg&&(i.container="#".concat(t.arg)),Kt(t.modifiers).forEach((function(t){if(IC.test(t))i.html=!0;else if(PC.test(t))i.interactive=!1;else if(OC.test(t))i.animation=!1;else if(VC.test(t))i.placement=t;else if(EC.test(t))t="scrollparent"===t?"scrollParent":t,i.boundary=t;else if(LC.test(t)){var e=lr(t.slice(1),0);i.delay.show=e,i.delay.hide=e}else AC.test(t)?i.delay.show=lr(t.slice(2),0):RC.test(t)?i.delay.hide=lr(t.slice(2),0):MC.test(t)?i.offset=lr(t.slice(1),0):HC.test(t)&&(i.variant=t.slice(2)||null)}));var o={};return or(i.trigger||"").filter(ne).join(" ").trim().toLowerCase().split(zC).forEach((function(t){FC[t]&&(o[t]=!0)})),Kt(t.modifiers).forEach((function(t){t=t.toLowerCase(),FC[t]&&(o[t]=!0)})),i.trigger=Kt(o).join(" "),"blur"===i.trigger&&(i.trigger="focus"),i.trigger||(i.trigger="hover focus"),i}(e,i);if(!t[DC]){var o=i.context;t[DC]=new Xg({parent:o,_scopeId:eb(o,void 0)}),t[DC].__bv_prev_data__={},t[DC].$on(to,(function(){Ot(n.title)&&t[DC].updateData({title:n.title(t)})}))}var r={title:n.title,triggers:n.trigger,placement:n.placement,fallbackPlacement:n.fallbackPlacement,variant:n.variant,customClass:n.customClass,container:n.container,boundary:n.boundary,delay:n.delay,offset:n.offset,noFade:!n.animation,id:n.id,interactive:n.interactive,disabled:n.disabled,html:n.html},s=t[DC].__bv_prev_data__;if(t[DC].__bv_prev_data__=r,!Ua(r,s)){var a={target:t};Kt(r).forEach((function(e){r[e]!==s[e]&&(a[e]="title"===e&&Ot(r[e])?r[e](t):r[e])})),t[DC].updateData(a)}}},jC=me({directives:{VBTooltip:{bind:function(t,e,i){NC(t,e,i)},componentUpdated:function(t,e,i){i.context.$nextTick((function(){NC(t,e,i)}))},unbind:function(t){!function(t){t[DC]&&(t[DC].$destroy(),t[DC]=null),delete t[DC]}(t)}}}}),GC=me({plugins:{AlertPlugin:Ws,AspectPlugin:ia,AvatarPlugin:xl,BadgePlugin:_l,BreadcrumbPlugin:Ll,ButtonPlugin:Al,ButtonGroupPlugin:Hl,ButtonToolbarPlugin:Gl,CalendarPlugin:Cc,CardPlugin:ru,CarouselPlugin:wu,CollapsePlugin:cd,DropdownPlugin:tf,EmbedPlugin:rf,FormPlugin:gf,FormCheckboxPlugin:Jf,FormDatepickerPlugin:mp,FormFilePlugin:Bp,FormGroupPlugin:Rp,FormInputPlugin:Zp,FormRadioPlugin:tm,FormRatingPlugin:dm,FormSelectPlugin:km,FormSpinbuttonPlugin:Vm,FormTagsPlugin:qm,FormTextareaPlugin:Zm,FormTimepickerPlugin:bv,ImagePlugin:gv,InputGroupPlugin:_v,JumbotronPlugin:Pv,LayoutPlugin:Av,LinkPlugin:Rv,ListGroupPlugin:Gv,MediaPlugin:Xv,ModalPlugin:Ob,NavPlugin:Wb,NavbarPlugin:fg,OverlayPlugin:yg,PaginationPlugin:Vg,PaginationNavPlugin:Rg,PopoverPlugin:wy,ProgressPlugin:ky,SidebarPlugin:Ny,SkeletonPlugin:VT,SpinnerPlugin:ET,TablePlugin:DT,TabsPlugin:KT,TimePlugin:XT,ToastPlugin:_C,TooltipPlugin:me({components:{BTooltip:ey},plugins:{VBTooltipPlugin:jC}})}}),WC=me({directives:{VBHover:np}}),YC=me({directives:{VBModal:Bb}}),UC="active",qC=".nav-link",KC=".nav-item",XC=".list-group-item",ZC=".dropdown-item",JC=Ds("BVScrollspy","activate"),QC="position",tx={element:"body",offset:10,method:"auto",throttle:75},ex={element:"(string|element|component)",offset:"number",method:"string",throttle:"number"},ix=["webkitTransitionEnd","transitionend","otransitionend","oTransitionEnd"],nx=function(t){return function(t){return Object.prototype.toString.call(t)}(t).match(/\s([a-zA-Z]+)/)[1].toLowerCase()},ox=function(){function t(e,i,n){o(this,t),this.$el=e,this.$scroller=null,this.$selector=[qC,XC,ZC].join(","),this.$offsets=[],this.$targets=[],this.$activeTarget=null,this.$scrollHeight=0,this.$resizeTimeout=null,this.$scrollerObserver=null,this.$targetsObserver=null,this.$root=n||null,this.$config=null,this.updateConfig(i)}return s(t,[{key:"updateConfig",value:function(t,e){this.$scroller&&(this.unlisten(),this.$scroller=null);var i=c(c({},this.constructor.Default),t);if(e&&(this.$root=e),function(t,e,i){for(var n in i)if(Xt(i,n)){var o=i[n],r=e[n],s=r&&kr(r)?"element":nx(r);s=r&&r._isVue?"component":s,new RegExp(o).test(s)||le("".concat(t,': Option "').concat(n,'" provided type "').concat(s,'" but expected type "').concat(o,'"'))}}(this.constructor.Name,i,this.constructor.DefaultType),this.$config=i,this.$root){var n=this;this.$root.$nextTick((function(){n.listen()}))}else this.listen()}},{key:"dispose",value:function(){this.unlisten(),clearTimeout(this.$resizeTimeout),this.$resizeTimeout=null,this.$el=null,this.$config=null,this.$scroller=null,this.$selector=null,this.$offsets=null,this.$targets=null,this.$activeTarget=null,this.$scrollHeight=null}},{key:"listen",value:function(){var t=this,e=this.getScroller();e&&"BODY"!==e.tagName&&Ss(e,"scroll",this,lo),Ss(window,"scroll",this,lo),Ss(window,"resize",this,lo),Ss(window,"orientationchange",this,lo),ix.forEach((function(e){Ss(window,e,t,lo)})),this.setObservers(!0),this.handleEvent("refresh")}},{key:"unlisten",value:function(){var t=this,e=this.getScroller();this.setObservers(!1),e&&"BODY"!==e.tagName&&ks(e,"scroll",this,lo),ks(window,"scroll",this,lo),ks(window,"resize",this,lo),ks(window,"orientationchange",this,lo),ix.forEach((function(e){ks(window,e,t,lo)}))}},{key:"setObservers",value:function(t){var e=this;this.$scrollerObserver&&this.$scrollerObserver.disconnect(),this.$targetsObserver&&this.$targetsObserver.disconnect(),this.$scrollerObserver=null,this.$targetsObserver=null,t&&(this.$targetsObserver=au(this.$el,(function(){e.handleEvent("mutation")}),{subtree:!0,childList:!0,attributes:!0,attributeFilter:["href"]}),this.$scrollerObserver=au(this.getScroller(),(function(){e.handleEvent("mutation")}),{subtree:!0,childList:!0,characterData:!0,attributes:!0,attributeFilter:["id","style","class"]}))}},{key:"handleEvent",value:function(t){var e=Et(t)?t:t.type,i=this;"scroll"===e?(this.$scrollerObserver||this.listen(),this.process()):/(resize|orientationchange|mutation|refresh)/.test(e)&&(i.$resizeTimeout||(i.$resizeTimeout=setTimeout((function(){i.refresh(),i.process(),i.$resizeTimeout=null}),i.$config.throttle)))}},{key:"refresh",value:function(){var t=this,e=this.getScroller();if(e){var i=e!==e.window?QC:"offset",n="auto"===this.$config.method?i:this.$config.method,o=n===QC?Jr:Zr,r=n===QC?this.getScrollTop():0;return this.$offsets=[],this.$targets=[],this.$scrollHeight=this.getScrollHeight(),Pr(this.$selector,this.$el).map((function(t){return jr(t,"href")})).filter((function(t){return t&&yt.test(t||"")})).map((function(t){var i=t.replace(yt,"$1").trim();if(!i)return null;var n=Or(i,e);return n&&Dr(n)?{offset:lr(o(n).top,0)+r,target:i}:null})).filter(ne).sort((function(t,e){return t.offset-e.offset})).reduce((function(e,i){return e[i.target]||(t.$offsets.push(i.offset),t.$targets.push(i.target),e[i.target]=!0),e}),{}),this}}},{key:"process",value:function(){var t=this.getScrollTop()+this.$config.offset,e=this.getScrollHeight(),i=this.$config.offset+e-this.getOffsetHeight();if(this.$scrollHeight!==e&&this.refresh(),t>=i){var n=this.$targets[this.$targets.length-1];this.$activeTarget!==n&&this.activate(n)}else{if(this.$activeTarget&&t<this.$offsets[0]&&this.$offsets[0]>0)return this.$activeTarget=null,void this.clear();for(var o=this.$offsets.length;o--;){this.$activeTarget!==this.$targets[o]&&t>=this.$offsets[o]&&(Ft(this.$offsets[o+1])||t<this.$offsets[o+1])&&this.activate(this.$targets[o])}}}},{key:"getScroller",value:function(){if(this.$scroller)return this.$scroller;var t=this.$config.element;return t?(kr(t.$el)?t=t.$el:Et(t)&&(t=Or(t)),t?(this.$scroller="BODY"===t.tagName?window:t,this.$scroller):null):null}},{key:"getScrollTop",value:function(){var t=this.getScroller();return t===window?t.pageYOffset:t.scrollTop}},{key:"getScrollHeight",value:function(){return this.getScroller().scrollHeight||Us(document.body.scrollHeight,document.documentElement.scrollHeight)}},{key:"getOffsetHeight",value:function(){var t=this.getScroller();return t===window?window.innerHeight:qr(t).height}},{key:"activate",value:function(t){var e=this;this.$activeTarget=t,this.clear();var i=Pr(this.$selector.split(",").map((function(e){return"".concat(e,'[href$="').concat(t,'"]')})).join(","),this.$el);i.forEach((function(t){if(Hr(t,"dropdown-item")){var i=Er(".dropdown, .dropup",t);i&&e.setActiveState(Or(".dropdown-toggle",i),!0),e.setActiveState(t,!0)}else{e.setActiveState(t,!0),Vr(t.parentElement,KC)&&e.setActiveState(t.parentElement,!0);for(var n=t;n;){var o=(n=Er(".nav, .list-group",n))?n.previousElementSibling:null;o&&Vr(o,"".concat(qC,", ").concat(XC))&&e.setActiveState(o,!0),o&&Vr(o,KC)&&(e.setActiveState(Or(qC,o),!0),e.setActiveState(o,!0))}}})),i&&i.length>0&&this.$root&&this.$root.$emit(JC,t,i)}},{key:"clear",value:function(){var t=this;Pr("".concat(this.$selector,", ").concat(KC),this.$el).filter((function(t){return Hr(t,UC)})).forEach((function(e){return t.setActiveState(e,!1)}))}},{key:"setActiveState",value:function(t,e){t&&(e?Rr(t,UC):Mr(t,UC))}}],[{key:"Name",get:function(){return"v-b-scrollspy"}},{key:"Default",get:function(){return tx}},{key:"DefaultType",get:function(){return ex}}]),t}(),rx="__BV_ScrollSpy__",sx=/^\d+$/,ax=/^(auto|position|offset)$/,lx=function(t,e,i){if(M){var n=function(t){var e={};return t.arg&&(e.element="#".concat(t.arg)),Kt(t.modifiers).forEach((function(t){sx.test(t)?e.offset=lr(t,0):ax.test(t)&&(e.method=t)})),Et(t.value)?e.element=t.value:Lt(t.value)?e.offset=Js(t.value):Mt(t.value)&&Kt(t.value).filter((function(t){return!!ox.DefaultType[t]})).forEach((function(i){e[i]=t.value[i]})),e}(e);t[rx]?t[rx].updateConfig(n,i.context.$root):t[rx]=new ox(t,n,i.context.$root)}},cx={install:pe({plugins:{componentsPlugin:GC,directivesPlugin:me({plugins:{VBHoverPlugin:WC,VBModalPlugin:YC,VBPopoverPlugin:yy,VBScrollspyPlugin:me({directives:{VBScrollspy:{bind:function(t,e,i){lx(t,e,i)},inserted:function(t,e,i){lx(t,e,i)},update:function(t,e,i){e.value!==e.oldValue&&lx(t,e,i)},componentUpdated:function(t,e,i){e.value!==e.oldValue&&lx(t,e,i)},unbind:function(t){!function(t){t[rx]&&(t[rx].dispose(),t[rx]=null,delete t[rx])}(t)}}}}),VBTogglePlugin:ld,VBTooltipPlugin:jC,VBVisiblePlugin:me({directives:{VBVisible:Kc}})}})}}),NAME:"BootstrapVue"};return iC=cx,V&&window.Vue&&window.Vue.use(iC),V&&iC.NAME&&(window[iC.NAME]=iC),cx})); +//# sourceMappingURL=bootstrap-vue.min.js.map \ No newline at end of file diff --git a/src/renderer/js/bootstrap.min.js b/src/renderer/lib/bootstrap.min.js similarity index 100% rename from src/renderer/js/bootstrap.min.js rename to src/renderer/lib/bootstrap.min.js diff --git a/src/renderer/lib/fast-plural-rules.js b/src/renderer/lib/fast-plural-rules.js new file mode 100644 index 00000000..b0b5c857 --- /dev/null +++ b/src/renderer/lib/fast-plural-rules.js @@ -0,0 +1 @@ +!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).fastPluralRules={})}(this,(function(n){"use strict";var e=[function(){return 0},function(n){return 1===n?0:1},function(n){return n<=1?0:1},function(n){return n%10==1&&n%100!=11?1:n%10!=0?2:0},function(n){return 1===n||11===n?0:2===n||12===n?1:n>2&&n<20?2:3},function(n){return 1===n?0:0===n||n%100>0&&n%100<20?1:2},function(n){return n%10==1&&n%100!=11?0:n%10>=2&&(n%100<10||n%100>=20)?2:1},function(n){return n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2},function(n){return 1===n?0:n>=2&&n<=4?1:2},function(n){return 1===n?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2},function(n){return n%100==1?0:n%100==2?1:n%100==3||n%100==4?2:3},function(n){return 1===n?0:2===n?1:n>2&&n<7?2:n>6&&n<11?3:4},function(n){return 1===n?0:2===n?1:n%100>=3&&n%100<=10?2:n%100>=11?3:0!==n?4:5},function(n){return 1===n?0:0===n||n%100>0&&n%100<11?1:n%100>10&&n%100<20?2:3},function(n){return n%10==1?0:n%10==2?1:2},function(n){return n%10==1&&n%100!=11?0:1},function(n){return n%10==1&&n%100!=11&&n%100!=71&&n%100!=91?0:n%10==2&&n%100!=12&&n%100!=72&&n%100!=92?1:n%10!=3&&n%10!=4&&n%10!=9||n%100==13||n%100==73||n%100==93||n%100==14||n%100==74||n%100==94||n%100==19||n%100==79||n%100==99?0!==n&&n%1e6==0?3:4:2},function(n){return 0!==n?1:0},function(n){return 1===n?1:2===n?2:3===n?3:6===n?4:0!==n?5:0},function(n){return 1===n?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2},function(n){return 1===n?0:2===n?1:3===n?2:3},function(n){return n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2},function(n){return 0===n?0:1===n?1:2}],r={ach:2,af:1,ak:2,am:2,an:1,anp:1,ar:12,arn:2,as:1,ast:1,ay:0,az:1,be:7,bg:1,bn:1,bo:0,br:2,brx:1,bs:7,ca:1,cgg:0,cs:8,csb:19,cy:18,da:1,de:1,doi:1,dz:0,el:1,en:1,eo:1,es:1,"es-ar":1,et:1,eu:1,fa:2,ff:1,fi:1,fil:2,fo:1,fr:2,fur:1,fy:1,ga:11,gd:4,gl:1,gu:1,gun:2,ha:1,he:1,hi:1,hne:1,hr:7,hu:1,hy:1,ia:1,id:0,is:15,it:1,ja:0,jbo:0,jv:17,ka:0,kk:1,kl:1,km:0,kn:1,ko:0,ku:1,kw:20,ky:1,lb:1,ln:2,lo:0,lt:6,lv:3,mai:1,me:21,mfe:2,mg:2,mi:2,mk:15,ml:1,mn:1,mni:1,mnk:22,mr:1,ms:0,mt:13,my:0,nah:1,nap:1,nb:1,ne:1,nl:1,nn:1,no:1,nso:1,oc:2,or:1,pa:1,pap:1,pl:9,pms:1,ps:1,pt:1,"pt-br":2,rm:1,ro:5,ru:7,rw:1,sah:0,sat:1,sco:1,sd:1,se:1,si:1,sk:8,sl:10,so:1,son:1,sq:1,sr:7,su:0,sv:1,sw:1,ta:1,te:1,tg:2,th:0,ti:2,tk:1,tr:2,tt:0,ug:0,uk:7,ur:1,uz:2,vi:0,wa:2,wo:0,yo:1,"zh-cn":0,"zh-tw":2},o=[["other"],["one","other"],["one","other"],["zero","one","other"],["one","two","few","other"],["one","few","other"],["one","few","other"],["one","few","other"],["one","few","other"],["one","few","other"],["one","two","few","other"],["one","two","few","many","other"],["one","two","few","many","other","zero"],["one","few","many","other"],["one","few","other"],["one","other"],["one","two","few","many","other"],["zero","other"],["zero","one","two","few","many","other"],["one","few","other"],["one","two","few","other"],["one","few","other"],["zero","one","other"]];function t(n){n=function(n){return n.toLowerCase().replace("_","-")}(n);var e=r[n];if(void 0===e){var o=function(n){var e=n.indexOf("-");return e>0?n.substr(0,e):n}(n);e=r[o]}if(void 0===e)throw new Error('Unrecognized locale: "'+n+'".');return e}function u(n,e){var r=o[e];return function(e){return r[n(e)]}}function a(n){var r=t(n);return e[r]}function i(n){var r=e[n];if(void 0===r)throw new Error('Invalid index: "'+n+'".');return r}function f(n){var r=t(n);return u(e[r],r)}function l(n){if(void 0===e[n])throw new Error('Invalid index: "'+n+'".');return u(e[n],n)}n.getPluralFormForCardinalByIndex=function(n,e){return i(n)(e)},n.getPluralFormForCardinalByLocale=function(n,e){return a(n)(e)},n.getPluralFormNameForCardinalByIndex=function(n,e){return l(n)(e)},n.getPluralFormNameForCardinalByLocale=function(n,e){return f(n)(e)},n.getPluralRuleForCardinalsByIndex=i,n.getPluralRuleForCardinalsByLocale=a,n.getPluralRuleForNamedFormsForCardinalsByIndex=l,n.getPluralRuleForNamedFormsForCardinalsByLocale=f,Object.defineProperty(n,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/src/renderer/js/jquery-3.2.1.slim.min.js b/src/renderer/lib/jquery-3.2.1.slim.min.js similarity index 100% rename from src/renderer/js/jquery-3.2.1.slim.min.js rename to src/renderer/lib/jquery-3.2.1.slim.min.js diff --git a/src/renderer/js/less.js b/src/renderer/lib/less.js similarity index 100% rename from src/renderer/js/less.js rename to src/renderer/lib/less.js diff --git a/src/renderer/lib/marked.js b/src/renderer/lib/marked.js new file mode 100644 index 00000000..05e7a449 --- /dev/null +++ b/src/renderer/lib/marked.js @@ -0,0 +1,2914 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2021, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ + +/** + * DO NOT EDIT THIS FILE + * The code in this file is generated from files in ./src/ + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {})); +})(this, (function (exports) { 'use strict'; + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; + } + + function _createForOfIteratorHelperLoose(o, allowArrayLike) { + var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; + if (it) return (it = it.call(o)).next.bind(it); + + if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { + if (it) o = it; + var i = 0; + return function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + function getDefaults() { + return { + baseUrl: null, + breaks: false, + extensions: null, + gfm: true, + headerIds: true, + headerPrefix: '', + highlight: null, + langPrefix: 'language-', + mangle: true, + pedantic: false, + renderer: null, + sanitize: false, + sanitizer: null, + silent: false, + smartLists: false, + smartypants: false, + tokenizer: null, + walkTokens: null, + xhtml: false + }; + } + exports.defaults = getDefaults(); + function changeDefaults(newDefaults) { + exports.defaults = newDefaults; + } + + /** + * Helpers + */ + var escapeTest = /[&<>"']/; + var escapeReplace = /[&<>"']/g; + var escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; + var escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; + var escapeReplacements = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + var getEscapeReplacement = function getEscapeReplacement(ch) { + return escapeReplacements[ch]; + }; + + function escape(html, encode) { + if (encode) { + if (escapeTest.test(html)) { + return html.replace(escapeReplace, getEscapeReplacement); + } + } else { + if (escapeTestNoEncode.test(html)) { + return html.replace(escapeReplaceNoEncode, getEscapeReplacement); + } + } + + return html; + } + var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; + function unescape(html) { + // explicitly match decimal, hex, and named HTML entities + return html.replace(unescapeTest, function (_, n) { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1)); + } + + return ''; + }); + } + var caret = /(^|[^\[])\^/g; + function edit(regex, opt) { + regex = regex.source || regex; + opt = opt || ''; + var obj = { + replace: function replace(name, val) { + val = val.source || val; + val = val.replace(caret, '$1'); + regex = regex.replace(name, val); + return obj; + }, + getRegex: function getRegex() { + return new RegExp(regex, opt); + } + }; + return obj; + } + var nonWordAndColonTest = /[^\w:]/g; + var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; + function cleanUrl(sanitize, base, href) { + if (sanitize) { + var prot; + + try { + prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase(); + } catch (e) { + return null; + } + + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { + return null; + } + } + + if (base && !originIndependentUrl.test(href)) { + href = resolveUrl(base, href); + } + + try { + href = encodeURI(href).replace(/%25/g, '%'); + } catch (e) { + return null; + } + + return href; + } + var baseUrls = {}; + var justDomain = /^[^:]+:\/*[^/]*$/; + var protocol = /^([^:]+:)[\s\S]*$/; + var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; + function resolveUrl(base, href) { + if (!baseUrls[' ' + base]) { + // we can ignore everything in base after the last slash of its path component, + // but we might need to add _that_ + // https://tools.ietf.org/html/rfc3986#section-3 + if (justDomain.test(base)) { + baseUrls[' ' + base] = base + '/'; + } else { + baseUrls[' ' + base] = rtrim(base, '/', true); + } + } + + base = baseUrls[' ' + base]; + var relativeBase = base.indexOf(':') === -1; + + if (href.substring(0, 2) === '//') { + if (relativeBase) { + return href; + } + + return base.replace(protocol, '$1') + href; + } else if (href.charAt(0) === '/') { + if (relativeBase) { + return href; + } + + return base.replace(domain, '$1') + href; + } else { + return base + href; + } + } + var noopTest = { + exec: function noopTest() {} + }; + function merge(obj) { + var i = 1, + target, + key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; + } + function splitCells(tableRow, count) { + // ensure that every cell-delimiting pipe has a space + // before it to distinguish it from an escaped pipe + var row = tableRow.replace(/\|/g, function (match, offset, str) { + var escaped = false, + curr = offset; + + while (--curr >= 0 && str[curr] === '\\') { + escaped = !escaped; + } + + if (escaped) { + // odd number of slashes means | is escaped + // so we leave it alone + return '|'; + } else { + // add space before unescaped | + return ' |'; + } + }), + cells = row.split(/ \|/); + var i = 0; // First/last cell in a row cannot be empty if it has no leading/trailing pipe + + if (!cells[0].trim()) { + cells.shift(); + } + + if (!cells[cells.length - 1].trim()) { + cells.pop(); + } + + if (cells.length > count) { + cells.splice(count); + } else { + while (cells.length < count) { + cells.push(''); + } + } + + for (; i < cells.length; i++) { + // leading or trailing whitespace is ignored per the gfm spec + cells[i] = cells[i].trim().replace(/\\\|/g, '|'); + } + + return cells; + } // Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). + // /c*$/ is vulnerable to REDOS. + // invert: Remove suffix of non-c chars instead. Default falsey. + + function rtrim(str, c, invert) { + var l = str.length; + + if (l === 0) { + return ''; + } // Length of suffix matching the invert condition. + + + var suffLen = 0; // Step left until we fail to match the invert condition. + + while (suffLen < l) { + var currChar = str.charAt(l - suffLen - 1); + + if (currChar === c && !invert) { + suffLen++; + } else if (currChar !== c && invert) { + suffLen++; + } else { + break; + } + } + + return str.substr(0, l - suffLen); + } + function findClosingBracket(str, b) { + if (str.indexOf(b[1]) === -1) { + return -1; + } + + var l = str.length; + var level = 0, + i = 0; + + for (; i < l; i++) { + if (str[i] === '\\') { + i++; + } else if (str[i] === b[0]) { + level++; + } else if (str[i] === b[1]) { + level--; + + if (level < 0) { + return i; + } + } + } + + return -1; + } + function checkSanitizeDeprecation(opt) { + if (opt && opt.sanitize && !opt.silent) { + console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options'); + } + } // copied from https://stackoverflow.com/a/5450113/806777 + + function repeatString(pattern, count) { + if (count < 1) { + return ''; + } + + var result = ''; + + while (count > 1) { + if (count & 1) { + result += pattern; + } + + count >>= 1; + pattern += pattern; + } + + return result + pattern; + } + + function outputLink(cap, link, raw, lexer) { + var href = link.href; + var title = link.title ? escape(link.title) : null; + var text = cap[1].replace(/\\([\[\]])/g, '$1'); + + if (cap[0].charAt(0) !== '!') { + lexer.state.inLink = true; + var token = { + type: 'link', + raw: raw, + href: href, + title: title, + text: text, + tokens: lexer.inlineTokens(text, []) + }; + lexer.state.inLink = false; + return token; + } else { + return { + type: 'image', + raw: raw, + href: href, + title: title, + text: escape(text) + }; + } + } + + function indentCodeCompensation(raw, text) { + var matchIndentToCode = raw.match(/^(\s+)(?:```)/); + + if (matchIndentToCode === null) { + return text; + } + + var indentToCode = matchIndentToCode[1]; + return text.split('\n').map(function (node) { + var matchIndentInNode = node.match(/^\s+/); + + if (matchIndentInNode === null) { + return node; + } + + var indentInNode = matchIndentInNode[0]; + + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length); + } + + return node; + }).join('\n'); + } + /** + * Tokenizer + */ + + + var Tokenizer = /*#__PURE__*/function () { + function Tokenizer(options) { + this.options = options || exports.defaults; + } + + var _proto = Tokenizer.prototype; + + _proto.space = function space(src) { + var cap = this.rules.block.newline.exec(src); + + if (cap) { + if (cap[0].length > 1) { + return { + type: 'space', + raw: cap[0] + }; + } + + return { + raw: '\n' + }; + } + }; + + _proto.code = function code(src) { + var cap = this.rules.block.code.exec(src); + + if (cap) { + var text = cap[0].replace(/^ {1,4}/gm, ''); + return { + type: 'code', + raw: cap[0], + codeBlockStyle: 'indented', + text: !this.options.pedantic ? rtrim(text, '\n') : text + }; + } + }; + + _proto.fences = function fences(src) { + var cap = this.rules.block.fences.exec(src); + + if (cap) { + var raw = cap[0]; + var text = indentCodeCompensation(raw, cap[3] || ''); + return { + type: 'code', + raw: raw, + lang: cap[2] ? cap[2].trim() : cap[2], + text: text + }; + } + }; + + _proto.heading = function heading(src) { + var cap = this.rules.block.heading.exec(src); + + if (cap) { + var text = cap[2].trim(); // remove trailing #s + + if (/#$/.test(text)) { + var trimmed = rtrim(text, '#'); + + if (this.options.pedantic) { + text = trimmed.trim(); + } else if (!trimmed || / $/.test(trimmed)) { + // CommonMark requires space before trailing #s + text = trimmed.trim(); + } + } + + var token = { + type: 'heading', + raw: cap[0], + depth: cap[1].length, + text: text, + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.hr = function hr(src) { + var cap = this.rules.block.hr.exec(src); + + if (cap) { + return { + type: 'hr', + raw: cap[0] + }; + } + }; + + _proto.blockquote = function blockquote(src) { + var cap = this.rules.block.blockquote.exec(src); + + if (cap) { + var text = cap[0].replace(/^ *> ?/gm, ''); + return { + type: 'blockquote', + raw: cap[0], + tokens: this.lexer.blockTokens(text, []), + text: text + }; + } + }; + + _proto.list = function list(src) { + var cap = this.rules.block.list.exec(src); + + if (cap) { + var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, lines, itemContents; + var bull = cap[1].trim(); + var isordered = bull.length > 1; + var list = { + type: 'list', + raw: '', + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : '', + loose: false, + items: [] + }; + bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull; + + if (this.options.pedantic) { + bull = isordered ? bull : '[*+-]'; + } // Get next list item + + + var itemRegex = new RegExp("^( {0,3}" + bull + ")((?: [^\\n]*| *)(?:\\n[^\\n]*)*(?:\\n|$))"); // Get each top-level item + + while (src) { + if (this.rules.block.hr.test(src)) { + // End list if we encounter an HR (possibly move into itemRegex?) + break; + } + + if (!(cap = itemRegex.exec(src))) { + break; + } + + lines = cap[2].split('\n'); + + if (this.options.pedantic) { + indent = 2; + itemContents = lines[0].trimLeft(); + } else { + indent = cap[2].search(/[^ ]/); // Find first non-space char + + indent = cap[1].length + (indent > 4 ? 1 : indent); // intented code blocks after 4 spaces; indent is always 1 + + itemContents = lines[0].slice(indent - cap[1].length); + } + + blankLine = false; + raw = cap[0]; + + if (!lines[0] && /^ *$/.test(lines[1])) { + // items begin with at most one blank line + raw = cap[1] + lines.slice(0, 2).join('\n') + '\n'; + list.loose = true; + lines = []; + } + + var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])"); + + for (i = 1; i < lines.length; i++) { + line = lines[i]; + + if (this.options.pedantic) { + // Re-align to follow commonmark nesting rules + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } // End list item if found start of new bullet + + + if (nextBulletRegex.test(line)) { + raw = cap[1] + lines.slice(0, i).join('\n') + '\n'; + break; + } // Until we encounter a blank line, item contents do not need indentation + + + if (!blankLine) { + if (!line.trim()) { + // Check if current line is empty + blankLine = true; + } // Dedent if possible + + + if (line.search(/[^ ]/) >= indent) { + itemContents += '\n' + line.slice(indent); + } else { + itemContents += '\n' + line; + } + + continue; + } // Dedent this line + + + if (line.search(/[^ ]/) >= indent || !line.trim()) { + itemContents += '\n' + line.slice(indent); + continue; + } else { + // Line was not properly indented; end of this item + raw = cap[1] + lines.slice(0, i).join('\n') + '\n'; + break; + } + } + + if (!list.loose) { + // If the previous item ended with a blank line, the list is loose + if (endsWithBlankLine) { + list.loose = true; + } else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true; + } + } // Check for task list items + + + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents); + + if (istask) { + ischecked = istask[0] !== '[ ] '; + itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); + } + } + + list.items.push({ + type: 'list_item', + raw: raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents + }); + list.raw += raw; + src = src.slice(raw.length); + } // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic + + + list.items[list.items.length - 1].raw = raw.trimRight(); + list.items[list.items.length - 1].text = itemContents.trimRight(); + list.raw = list.raw.trimRight(); + var l = list.items.length; // Item child tokens handled here at end because we needed to have the final item to trim it first + + for (i = 0; i < l; i++) { + this.lexer.state.top = false; + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); + + if (list.items[i].tokens.some(function (t) { + return t.type === 'space'; + })) { + list.loose = true; + list.items[i].loose = true; + } + } + + return list; + } + }; + + _proto.html = function html(src) { + var cap = this.rules.block.html.exec(src); + + if (cap) { + var token = { + type: 'html', + raw: cap[0], + pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), + text: cap[0] + }; + + if (this.options.sanitize) { + token.type = 'paragraph'; + token.text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]); + token.tokens = []; + this.lexer.inline(token.text, token.tokens); + } + + return token; + } + }; + + _proto.def = function def(src) { + var cap = this.rules.block.def.exec(src); + + if (cap) { + if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1); + var tag = cap[1].toLowerCase().replace(/\s+/g, ' '); + return { + type: 'def', + tag: tag, + raw: cap[0], + href: cap[2], + title: cap[3] + }; + } + }; + + _proto.table = function table(src) { + var cap = this.rules.block.table.exec(src); + + if (cap) { + var item = { + type: 'table', + header: splitCells(cap[1]).map(function (c) { + return { + text: c + }; + }), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + rows: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : [] + }; + + if (item.header.length === item.align.length) { + item.raw = cap[0]; + var l = item.align.length; + var i, j, k, row; + + for (i = 0; i < l; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + l = item.rows.length; + + for (i = 0; i < l; i++) { + item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) { + return { + text: c + }; + }); + } // parse child tokens inside headers and cells + // header child tokens + + + l = item.header.length; + + for (j = 0; j < l; j++) { + item.header[j].tokens = []; + this.lexer.inlineTokens(item.header[j].text, item.header[j].tokens); + } // cell child tokens + + + l = item.rows.length; + + for (j = 0; j < l; j++) { + row = item.rows[j]; + + for (k = 0; k < row.length; k++) { + row[k].tokens = []; + this.lexer.inlineTokens(row[k].text, row[k].tokens); + } + } + + return item; + } + } + }; + + _proto.lheading = function lheading(src) { + var cap = this.rules.block.lheading.exec(src); + + if (cap) { + var token = { + type: 'heading', + raw: cap[0], + depth: cap[2].charAt(0) === '=' ? 1 : 2, + text: cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.paragraph = function paragraph(src) { + var cap = this.rules.block.paragraph.exec(src); + + if (cap) { + var token = { + type: 'paragraph', + raw: cap[0], + text: cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.text = function text(src) { + var cap = this.rules.block.text.exec(src); + + if (cap) { + var token = { + type: 'text', + raw: cap[0], + text: cap[0], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.escape = function escape$1(src) { + var cap = this.rules.inline.escape.exec(src); + + if (cap) { + return { + type: 'escape', + raw: cap[0], + text: escape(cap[1]) + }; + } + }; + + _proto.tag = function tag(src) { + var cap = this.rules.inline.tag.exec(src); + + if (cap) { + if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) { + this.lexer.state.inLink = true; + } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) { + this.lexer.state.inLink = false; + } + + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = true; + } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = false; + } + + return { + type: this.options.sanitize ? 'text' : 'html', + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0] + }; + } + }; + + _proto.link = function link(src) { + var cap = this.rules.inline.link.exec(src); + + if (cap) { + var trimmedUrl = cap[2].trim(); + + if (!this.options.pedantic && /^</.test(trimmedUrl)) { + // commonmark requires matching angle brackets + if (!/>$/.test(trimmedUrl)) { + return; + } // ending angle bracket cannot be escaped + + + var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); + + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { + return; + } + } else { + // find closing parenthesis + var lastParenIndex = findClosingBracket(cap[2], '()'); + + if (lastParenIndex > -1) { + var start = cap[0].indexOf('!') === 0 ? 5 : 4; + var linkLen = start + cap[1].length + lastParenIndex; + cap[2] = cap[2].substring(0, lastParenIndex); + cap[0] = cap[0].substring(0, linkLen).trim(); + cap[3] = ''; + } + } + + var href = cap[2]; + var title = ''; + + if (this.options.pedantic) { + // split pedantic href and title + var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); + + if (link) { + href = link[1]; + title = link[3]; + } + } else { + title = cap[3] ? cap[3].slice(1, -1) : ''; + } + + href = href.trim(); + + if (/^</.test(href)) { + if (this.options.pedantic && !/>$/.test(trimmedUrl)) { + // pedantic allows starting angle bracket without ending angle bracket + href = href.slice(1); + } else { + href = href.slice(1, -1); + } + } + + return outputLink(cap, { + href: href ? href.replace(this.rules.inline._escapes, '$1') : href, + title: title ? title.replace(this.rules.inline._escapes, '$1') : title + }, cap[0], this.lexer); + } + }; + + _proto.reflink = function reflink(src, links) { + var cap; + + if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) { + var link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = links[link.toLowerCase()]; + + if (!link || !link.href) { + var text = cap[0].charAt(0); + return { + type: 'text', + raw: text, + text: text + }; + } + + return outputLink(cap, link, cap[0], this.lexer); + } + }; + + _proto.emStrong = function emStrong(src, maskedSrc, prevChar) { + if (prevChar === void 0) { + prevChar = ''; + } + + var match = this.rules.inline.emStrong.lDelim.exec(src); + if (!match) return; // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + + if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/)) return; + var nextChar = match[1] || match[2] || ''; + + if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) { + var lLength = match[0].length - 1; + var rDelim, + rLength, + delimTotal = lLength, + midDelimTotal = 0; + var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; + endReg.lastIndex = 0; // Clip maskedSrc to same section of string as src (move to lexer?) + + maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; + if (!rDelim) continue; // skip single * in __abc*abc__ + + rLength = rDelim.length; + + if (match[3] || match[4]) { + // found another Left Delim + delimTotal += rLength; + continue; + } else if (match[5] || match[6]) { + // either Left or Right Delim + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength; + continue; // CommonMark Emphasis Rules 9-10 + } + } + + delimTotal -= rLength; + if (delimTotal > 0) continue; // Haven't found enough closing delimiters + // Remove extra characters. *a*** -> *a* + + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); // Create `em` if smallest delimiter has odd char count. *a*** + + if (Math.min(lLength, rLength) % 2) { + var _text = src.slice(1, lLength + match.index + rLength); + + return { + type: 'em', + raw: src.slice(0, lLength + match.index + rLength + 1), + text: _text, + tokens: this.lexer.inlineTokens(_text, []) + }; + } // Create 'strong' if smallest delimiter has even char count. **a*** + + + var text = src.slice(2, lLength + match.index + rLength - 1); + return { + type: 'strong', + raw: src.slice(0, lLength + match.index + rLength + 1), + text: text, + tokens: this.lexer.inlineTokens(text, []) + }; + } + } + }; + + _proto.codespan = function codespan(src) { + var cap = this.rules.inline.code.exec(src); + + if (cap) { + var text = cap[2].replace(/\n/g, ' '); + var hasNonSpaceChars = /[^ ]/.test(text); + var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); + + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text = text.substring(1, text.length - 1); + } + + text = escape(text, true); + return { + type: 'codespan', + raw: cap[0], + text: text + }; + } + }; + + _proto.br = function br(src) { + var cap = this.rules.inline.br.exec(src); + + if (cap) { + return { + type: 'br', + raw: cap[0] + }; + } + }; + + _proto.del = function del(src) { + var cap = this.rules.inline.del.exec(src); + + if (cap) { + return { + type: 'del', + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2], []) + }; + } + }; + + _proto.autolink = function autolink(src, mangle) { + var cap = this.rules.inline.autolink.exec(src); + + if (cap) { + var text, href; + + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]); + href = 'mailto:' + text; + } else { + text = escape(cap[1]); + href = text; + } + + return { + type: 'link', + raw: cap[0], + text: text, + href: href, + tokens: [{ + type: 'text', + raw: text, + text: text + }] + }; + } + }; + + _proto.url = function url(src, mangle) { + var cap; + + if (cap = this.rules.inline.url.exec(src)) { + var text, href; + + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]); + href = 'mailto:' + text; + } else { + // do extended autolink path validation + var prevCapZero; + + do { + prevCapZero = cap[0]; + cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; + } while (prevCapZero !== cap[0]); + + text = escape(cap[0]); + + if (cap[1] === 'www.') { + href = 'http://' + text; + } else { + href = text; + } + } + + return { + type: 'link', + raw: cap[0], + text: text, + href: href, + tokens: [{ + type: 'text', + raw: text, + text: text + }] + }; + } + }; + + _proto.inlineText = function inlineText(src, smartypants) { + var cap = this.rules.inline.text.exec(src); + + if (cap) { + var text; + + if (this.lexer.state.inRawBlock) { + text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]; + } else { + text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]); + } + + return { + type: 'text', + raw: cap[0], + text: text + }; + } + }; + + return Tokenizer; + }(); + + /** + * Block-Level Grammar + */ + + var block = { + newline: /^(?: *(?:\n|$))+/, + code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, + fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, + hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/, + heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, + blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, + list: /^( {0,3}bull)( [^\n]+?)?(?:\n|$)/, + html: '^ {0,3}(?:' // optional indentation + + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1) + + '|comment[^\\n]*(\\n+|$)' // (2) + + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) + + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4) + + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5) + + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) + + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag + + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + + ')', + def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/, + table: noopTest, + lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, + // regex template, placeholders will be replaced according to different paragraph + // interruption rules of commonmark and the original markdown spec: + _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/, + text: /^[^\n]+/ + }; + block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/; + block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; + block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex(); + block.bullet = /(?:[*+-]|\d{1,9}[.)])/; + block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex(); + block.list = edit(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex(); + block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul'; + block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/; + block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); + block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs + .replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks + .getRegex(); + block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex(); + /** + * Normal Block Grammar + */ + + block.normal = merge({}, block); + /** + * GFM Block Grammar + */ + + block.gfm = merge({}, block.normal, { + table: '^ *([^\\n ].*\\|.*)\\n' // Header + + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align + + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells + + }); + block.gfm.table = edit(block.gfm.table).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks + .getRegex(); + /** + * Pedantic grammar (original John Gruber's loose markdown specification) + */ + + block.pedantic = merge({}, block.normal, { + html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag + + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', block._comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(), + def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, + // fences not supported + paragraph: edit(block.normal._paragraph).replace('hr', block.hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', block.lheading).replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').getRegex() + }); + /** + * Inline-Level Grammar + */ + + var inline = { + escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, + autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, + url: noopTest, + tag: '^comment' + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag + + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag + + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?> + + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html> + + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', + // CDATA section + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, + reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/, + nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/, + reflinkSearch: 'reflink|nolink(?!\\()', + emStrong: { + lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, + // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. + // () Skip orphan delim inside strong (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a + rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, + rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ + + }, + code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, + br: /^( {2,}|\\)\n(?!\s*$)/, + del: noopTest, + text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/, + punctuation: /^([\spunctuation])/ + }; // list of punctuation marks from CommonMark spec + // without * and _ to handle the different emphasis markers * and _ + + inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~'; + inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); // sequences em should skip over [title](link), `code`, <html> + + inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; + inline.escapedEmSt = /\\\*|\\_/g; + inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex(); + inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex(); + inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex(); + inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex(); + inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; + inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; + inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; + inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex(); + inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; + inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex(); + inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; + inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; + inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; + inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex(); + inline.reflink = edit(inline.reflink).replace('label', inline._label).getRegex(); + inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex(); + /** + * Normal Inline Grammar + */ + + inline.normal = merge({}, inline); + /** + * Pedantic Inline Grammar + */ + + inline.pedantic = merge({}, inline.normal, { + strong: { + start: /^__|\*\*/, + middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + endAst: /\*\*(?!\*)/g, + endUnd: /__(?!_)/g + }, + em: { + start: /^_|\*/, + middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, + endAst: /\*(?!\*)/g, + endUnd: /_(?!_)/g + }, + link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex() + }); + /** + * GFM Inline Grammar + */ + + inline.gfm = merge({}, inline.normal, { + escape: edit(inline.escape).replace('])', '~|])').getRegex(), + _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, + _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/ + }); + inline.gfm.url = edit(inline.gfm.url, 'i').replace('email', inline.gfm._extended_email).getRegex(); + /** + * GFM + Line Breaks Inline Grammar + */ + + inline.breaks = merge({}, inline.gfm, { + br: edit(inline.br).replace('{2,}', '*').getRegex(), + text: edit(inline.gfm.text).replace('\\b_', '\\b_| {2,}\\n').replace(/\{2,\}/g, '*').getRegex() + }); + + /** + * smartypants text replacement + */ + + function smartypants(text) { + return text // em-dashes + .replace(/---/g, "\u2014") // en-dashes + .replace(/--/g, "\u2013") // opening singles + .replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018") // closing singles & apostrophes + .replace(/'/g, "\u2019") // opening doubles + .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C") // closing doubles + .replace(/"/g, "\u201D") // ellipses + .replace(/\.{3}/g, "\u2026"); + } + /** + * mangle email addresses + */ + + + function mangle(text) { + var out = '', + i, + ch; + var l = text.length; + + for (i = 0; i < l; i++) { + ch = text.charCodeAt(i); + + if (Math.random() > 0.5) { + ch = 'x' + ch.toString(16); + } + + out += '&#' + ch + ';'; + } + + return out; + } + /** + * Block Lexer + */ + + + var Lexer = /*#__PURE__*/function () { + function Lexer(options) { + this.tokens = []; + this.tokens.links = Object.create(null); + this.options = options || exports.defaults; + this.options.tokenizer = this.options.tokenizer || new Tokenizer(); + this.tokenizer = this.options.tokenizer; + this.tokenizer.options = this.options; + this.tokenizer.lexer = this; + this.inlineQueue = []; + this.state = { + inLink: false, + inRawBlock: false, + top: true + }; + var rules = { + block: block.normal, + inline: inline.normal + }; + + if (this.options.pedantic) { + rules.block = block.pedantic; + rules.inline = inline.pedantic; + } else if (this.options.gfm) { + rules.block = block.gfm; + + if (this.options.breaks) { + rules.inline = inline.breaks; + } else { + rules.inline = inline.gfm; + } + } + + this.tokenizer.rules = rules; + } + /** + * Expose Rules + */ + + + /** + * Static Lex Method + */ + Lexer.lex = function lex(src, options) { + var lexer = new Lexer(options); + return lexer.lex(src); + } + /** + * Static Lex Inline Method + */ + ; + + Lexer.lexInline = function lexInline(src, options) { + var lexer = new Lexer(options); + return lexer.inlineTokens(src); + } + /** + * Preprocessing + */ + ; + + var _proto = Lexer.prototype; + + _proto.lex = function lex(src) { + src = src.replace(/\r\n|\r/g, '\n').replace(/\t/g, ' '); + this.blockTokens(src, this.tokens); + var next; + + while (next = this.inlineQueue.shift()) { + this.inlineTokens(next.src, next.tokens); + } + + return this.tokens; + } + /** + * Lexing + */ + ; + + _proto.blockTokens = function blockTokens(src, tokens) { + var _this = this; + + if (tokens === void 0) { + tokens = []; + } + + if (this.options.pedantic) { + src = src.replace(/^ +$/gm, ''); + } + + var token, lastToken, cutSrc, lastParagraphClipped; + + while (src) { + if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(function (extTokenizer) { + if (token = extTokenizer.call({ + lexer: _this + }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + + return false; + })) { + continue; + } // newline + + + if (token = this.tokenizer.space(src)) { + src = src.substring(token.raw.length); + + if (token.type) { + tokens.push(token); + } + + continue; + } // code + + + if (token = this.tokenizer.code(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; // An indented code block cannot interrupt a paragraph. + + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + continue; + } // fences + + + if (token = this.tokenizer.fences(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // heading + + + if (token = this.tokenizer.heading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // hr + + + if (token = this.tokenizer.hr(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // blockquote + + + if (token = this.tokenizer.blockquote(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // list + + + if (token = this.tokenizer.list(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // html + + + if (token = this.tokenizer.html(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // def + + + if (token = this.tokenizer.def(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.raw; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title + }; + } + + continue; + } // table (gfm) + + + if (token = this.tokenizer.table(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // lheading + + + if (token = this.tokenizer.lheading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // top-level paragraph + // prevent paragraph consuming extensions by clipping 'src' to extension start + + + cutSrc = src; + + if (this.options.extensions && this.options.extensions.startBlock) { + (function () { + var startIndex = Infinity; + var tempSrc = src.slice(1); + var tempStart = void 0; + + _this.options.extensions.startBlock.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ + lexer: this + }, tempSrc); + + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + })(); + } + + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1]; + + if (lastParagraphClipped && lastToken.type === 'paragraph') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + lastParagraphClipped = cutSrc.length !== src.length; + src = src.substring(token.raw.length); + continue; + } // text + + + if (token = this.tokenizer.text(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && lastToken.type === 'text') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + continue; + } + + if (src) { + var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + this.state.top = true; + return tokens; + }; + + _proto.inline = function inline(src, tokens) { + this.inlineQueue.push({ + src: src, + tokens: tokens + }); + } + /** + * Lexing/Compiling + */ + ; + + _proto.inlineTokens = function inlineTokens(src, tokens) { + var _this2 = this; + + if (tokens === void 0) { + tokens = []; + } + + var token, lastToken, cutSrc; // String with links masked to avoid interference with em and strong + + var maskedSrc = src; + var match; + var keepPrevChar, prevChar; // Mask out reflinks + + if (this.tokens.links) { + var links = Object.keys(this.tokens.links); + + if (links.length > 0) { + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { + if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); + } + } + } + } // Mask out other blocks + + + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + } // Mask out escaped em & strong delimiters + + + while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); + } + + while (src) { + if (!keepPrevChar) { + prevChar = ''; + } + + keepPrevChar = false; // extensions + + if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(function (extTokenizer) { + if (token = extTokenizer.call({ + lexer: _this2 + }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + + return false; + })) { + continue; + } // escape + + + if (token = this.tokenizer.escape(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // tag + + + if (token = this.tokenizer.tag(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } // link + + + if (token = this.tokenizer.link(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // reflink, nolink + + + if (token = this.tokenizer.reflink(src, this.tokens.links)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } // em & strong + + + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // code + + + if (token = this.tokenizer.codespan(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // br + + + if (token = this.tokenizer.br(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // del (gfm) + + + if (token = this.tokenizer.del(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // autolink + + + if (token = this.tokenizer.autolink(src, mangle)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // url (gfm) + + + if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // text + // prevent inlineText consuming extensions by clipping 'src' to extension start + + + cutSrc = src; + + if (this.options.extensions && this.options.extensions.startInline) { + (function () { + var startIndex = Infinity; + var tempSrc = src.slice(1); + var tempStart = void 0; + + _this2.options.extensions.startInline.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ + lexer: this + }, tempSrc); + + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + })(); + } + + if (token = this.tokenizer.inlineText(cutSrc, smartypants)) { + src = src.substring(token.raw.length); + + if (token.raw.slice(-1) !== '_') { + // Track prevChar before string of ____ started + prevChar = token.raw.slice(-1); + } + + keepPrevChar = true; + lastToken = tokens[tokens.length - 1]; + + if (lastToken && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } + + if (src) { + var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + return tokens; + }; + + _createClass(Lexer, null, [{ + key: "rules", + get: function get() { + return { + block: block, + inline: inline + }; + } + }]); + + return Lexer; + }(); + + /** + * Renderer + */ + + var Renderer = /*#__PURE__*/function () { + function Renderer(options) { + this.options = options || exports.defaults; + } + + var _proto = Renderer.prototype; + + _proto.code = function code(_code, infostring, escaped) { + var lang = (infostring || '').match(/\S*/)[0]; + + if (this.options.highlight) { + var out = this.options.highlight(_code, lang); + + if (out != null && out !== _code) { + escaped = true; + _code = out; + } + } + + _code = _code.replace(/\n$/, '') + '\n'; + + if (!lang) { + return '<pre><code>' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n'; + } + + return '<pre><code class="' + this.options.langPrefix + escape(lang, true) + '">' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n'; + }; + + _proto.blockquote = function blockquote(quote) { + return '<blockquote>\n' + quote + '</blockquote>\n'; + }; + + _proto.html = function html(_html) { + return _html; + }; + + _proto.heading = function heading(text, level, raw, slugger) { + if (this.options.headerIds) { + return '<h' + level + ' id="' + this.options.headerPrefix + slugger.slug(raw) + '">' + text + '</h' + level + '>\n'; + } // ignore IDs + + + return '<h' + level + '>' + text + '</h' + level + '>\n'; + }; + + _proto.hr = function hr() { + return this.options.xhtml ? '<hr/>\n' : '<hr>\n'; + }; + + _proto.list = function list(body, ordered, start) { + var type = ordered ? 'ol' : 'ul', + startatt = ordered && start !== 1 ? ' start="' + start + '"' : ''; + return '<' + type + startatt + '>\n' + body + '</' + type + '>\n'; + }; + + _proto.listitem = function listitem(text) { + return '<li>' + text + '</li>\n'; + }; + + _proto.checkbox = function checkbox(checked) { + return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox"' + (this.options.xhtml ? ' /' : '') + '> '; + }; + + _proto.paragraph = function paragraph(text) { + return '<p>' + text + '</p>\n'; + }; + + _proto.table = function table(header, body) { + if (body) body = '<tbody>' + body + '</tbody>'; + return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n'; + }; + + _proto.tablerow = function tablerow(content) { + return '<tr>\n' + content + '</tr>\n'; + }; + + _proto.tablecell = function tablecell(content, flags) { + var type = flags.header ? 'th' : 'td'; + var tag = flags.align ? '<' + type + ' align="' + flags.align + '">' : '<' + type + '>'; + return tag + content + '</' + type + '>\n'; + } // span level renderer + ; + + _proto.strong = function strong(text) { + return '<strong>' + text + '</strong>'; + }; + + _proto.em = function em(text) { + return '<em>' + text + '</em>'; + }; + + _proto.codespan = function codespan(text) { + return '<code>' + text + '</code>'; + }; + + _proto.br = function br() { + return this.options.xhtml ? '<br/>' : '<br>'; + }; + + _proto.del = function del(text) { + return '<del>' + text + '</del>'; + }; + + _proto.link = function link(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + + if (href === null) { + return text; + } + + var out = '<a href="' + escape(href) + '" target="_blank"'; + + if (title) { + out += ' title="' + title + '"'; + } + + out += '>' + text + '</a>'; + return out; + }; + + _proto.image = function image(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + + if (href === null) { + return text; + } + + var out = '<img style="max-width:100%" src="' + href + '" alt="' + text + '"'; + + if (title) { + out += ' title="' + title + '"'; + } + + out += this.options.xhtml ? '/>' : '>'; + return out; + }; + + _proto.text = function text(_text) { + return _text; + }; + + return Renderer; + }(); + + /** + * TextRenderer + * returns only the textual part of the token + */ + var TextRenderer = /*#__PURE__*/function () { + function TextRenderer() {} + + var _proto = TextRenderer.prototype; + + // no need for block level renderers + _proto.strong = function strong(text) { + return text; + }; + + _proto.em = function em(text) { + return text; + }; + + _proto.codespan = function codespan(text) { + return text; + }; + + _proto.del = function del(text) { + return text; + }; + + _proto.html = function html(text) { + return text; + }; + + _proto.text = function text(_text) { + return _text; + }; + + _proto.link = function link(href, title, text) { + return '' + text; + }; + + _proto.image = function image(href, title, text) { + return '' + text; + }; + + _proto.br = function br() { + return ''; + }; + + return TextRenderer; + }(); + + /** + * Slugger generates header id + */ + var Slugger = /*#__PURE__*/function () { + function Slugger() { + this.seen = {}; + } + + var _proto = Slugger.prototype; + + _proto.serialize = function serialize(value) { + return value.toLowerCase().trim() // remove html tags + .replace(/<[!\/a-z].*?>/ig, '') // remove unwanted chars + .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-'); + } + /** + * Finds the next safe (unique) slug to use + */ + ; + + _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) { + var slug = originalSlug; + var occurenceAccumulator = 0; + + if (this.seen.hasOwnProperty(slug)) { + occurenceAccumulator = this.seen[originalSlug]; + + do { + occurenceAccumulator++; + slug = originalSlug + '-' + occurenceAccumulator; + } while (this.seen.hasOwnProperty(slug)); + } + + if (!isDryRun) { + this.seen[originalSlug] = occurenceAccumulator; + this.seen[slug] = 0; + } + + return slug; + } + /** + * Convert string to unique id + * @param {object} options + * @param {boolean} options.dryrun Generates the next unique slug without updating the internal accumulator. + */ + ; + + _proto.slug = function slug(value, options) { + if (options === void 0) { + options = {}; + } + + var slug = this.serialize(value); + return this.getNextSafeSlug(slug, options.dryrun); + }; + + return Slugger; + }(); + + /** + * Parsing & Compiling + */ + + var Parser = /*#__PURE__*/function () { + function Parser(options) { + this.options = options || exports.defaults; + this.options.renderer = this.options.renderer || new Renderer(); + this.renderer = this.options.renderer; + this.renderer.options = this.options; + this.textRenderer = new TextRenderer(); + this.slugger = new Slugger(); + } + /** + * Static Parse Method + */ + + + Parser.parse = function parse(tokens, options) { + var parser = new Parser(options); + return parser.parse(tokens); + } + /** + * Static Parse Inline Method + */ + ; + + Parser.parseInline = function parseInline(tokens, options) { + var parser = new Parser(options); + return parser.parseInline(tokens); + } + /** + * Parse Loop + */ + ; + + var _proto = Parser.prototype; + + _proto.parse = function parse(tokens, top) { + if (top === void 0) { + top = true; + } + + var out = '', + i, + j, + k, + l2, + l3, + row, + cell, + header, + body, + token, + ordered, + start, + loose, + itemBody, + item, + checked, + task, + checkbox, + ret; + var l = tokens.length; + + for (i = 0; i < l; i++) { + token = tokens[i]; // Run any renderer extensions + + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ + parser: this + }, token); + + if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'space': + { + continue; + } + + case 'hr': + { + out += this.renderer.hr(); + continue; + } + + case 'heading': + { + out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger); + continue; + } + + case 'code': + { + out += this.renderer.code(token.text, token.lang, token.escaped); + continue; + } + + case 'table': + { + header = ''; // header + + cell = ''; + l2 = token.header.length; + + for (j = 0; j < l2; j++) { + cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { + header: true, + align: token.align[j] + }); + } + + header += this.renderer.tablerow(cell); + body = ''; + l2 = token.rows.length; + + for (j = 0; j < l2; j++) { + row = token.rows[j]; + cell = ''; + l3 = row.length; + + for (k = 0; k < l3; k++) { + cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { + header: false, + align: token.align[k] + }); + } + + body += this.renderer.tablerow(cell); + } + + out += this.renderer.table(header, body); + continue; + } + + case 'blockquote': + { + body = this.parse(token.tokens); + out += this.renderer.blockquote(body); + continue; + } + + case 'list': + { + ordered = token.ordered; + start = token.start; + loose = token.loose; + l2 = token.items.length; + body = ''; + + for (j = 0; j < l2; j++) { + item = token.items[j]; + checked = item.checked; + task = item.task; + itemBody = ''; + + if (item.task) { + checkbox = this.renderer.checkbox(checked); + + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: 'text', + text: checkbox + }); + } + } else { + itemBody += checkbox; + } + } + + itemBody += this.parse(item.tokens, loose); + body += this.renderer.listitem(itemBody, task, checked); + } + + out += this.renderer.list(body, ordered, start); + continue; + } + + case 'html': + { + // TODO parse inline content if parameter markdown=1 + out += this.renderer.html(token.text); + continue; + } + + case 'paragraph': + { + out += this.renderer.paragraph(this.parseInline(token.tokens)); + continue; + } + + case 'text': + { + body = token.tokens ? this.parseInline(token.tokens) : token.text; + + while (i + 1 < l && tokens[i + 1].type === 'text') { + token = tokens[++i]; + body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text); + } + + out += top ? this.renderer.paragraph(body) : body; + continue; + } + + default: + { + var errMsg = 'Token with "' + token.type + '" type was not found.'; + + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + } + /** + * Parse Inline Tokens + */ + ; + + _proto.parseInline = function parseInline(tokens, renderer) { + renderer = renderer || this.renderer; + var out = '', + i, + token, + ret; + var l = tokens.length; + + for (i = 0; i < l; i++) { + token = tokens[i]; // Run any renderer extensions + + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ + parser: this + }, token); + + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'escape': + { + out += renderer.text(token.text); + break; + } + + case 'html': + { + out += renderer.html(token.text); + break; + } + + case 'link': + { + out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); + break; + } + + case 'image': + { + out += renderer.image(token.href, token.title, token.text); + break; + } + + case 'strong': + { + out += renderer.strong(this.parseInline(token.tokens, renderer)); + break; + } + + case 'em': + { + out += renderer.em(this.parseInline(token.tokens, renderer)); + break; + } + + case 'codespan': + { + out += renderer.codespan(token.text); + break; + } + + case 'br': + { + out += renderer.br(); + break; + } + + case 'del': + { + out += renderer.del(this.parseInline(token.tokens, renderer)); + break; + } + + case 'text': + { + out += renderer.text(token.text); + break; + } + + default: + { + var errMsg = 'Token with "' + token.type + '" type was not found.'; + + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + }; + + return Parser; + }(); + + /** + * Marked + */ + + function marked(src, opt, callback) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked(): input parameter is undefined or null'); + } + + if (typeof src !== 'string') { + throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); + } + + if (typeof opt === 'function') { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + if (callback) { + var highlight = opt.highlight; + var tokens; + + try { + tokens = Lexer.lex(src, opt); + } catch (e) { + return callback(e); + } + + var done = function done(err) { + var out; + + if (!err) { + try { + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + } + + opt.highlight = highlight; + return err ? callback(err) : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + if (!tokens.length) return done(); + var pending = 0; + marked.walkTokens(tokens, function (token) { + if (token.type === 'code') { + pending++; + setTimeout(function () { + highlight(token.text, token.lang, function (err, code) { + if (err) { + return done(err); + } + + if (code != null && code !== token.text) { + token.text = code; + token.escaped = true; + } + + pending--; + + if (pending === 0) { + done(); + } + }); + }, 0); + } + }); + + if (pending === 0) { + done(); + } + + return; + } + + try { + var _tokens = Lexer.lex(src, opt); + + if (opt.walkTokens) { + marked.walkTokens(_tokens, opt.walkTokens); + } + + return Parser.parse(_tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + + if (opt.silent) { + return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>'; + } + + throw e; + } + } + /** + * Options + */ + + + marked.options = marked.setOptions = function (opt) { + merge(marked.defaults, opt); + changeDefaults(marked.defaults); + return marked; + }; + + marked.getDefaults = getDefaults; + marked.defaults = exports.defaults; + /** + * Use Extension + */ + + marked.use = function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var opts = merge.apply(void 0, [{}].concat(args)); + var extensions = marked.defaults.extensions || { + renderers: {}, + childTokens: {} + }; + var hasExtensions; + args.forEach(function (pack) { + // ==-- Parse "addon" extensions --== // + if (pack.extensions) { + hasExtensions = true; + pack.extensions.forEach(function (ext) { + if (!ext.name) { + throw new Error('extension name required'); + } + + if (ext.renderer) { + // Renderer extensions + var prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null; + + if (prevRenderer) { + // Replace extension with func to run new extension but fall back if false + extensions.renderers[ext.name] = function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + var ret = ext.renderer.apply(this, args); + + if (ret === false) { + ret = prevRenderer.apply(this, args); + } + + return ret; + }; + } else { + extensions.renderers[ext.name] = ext.renderer; + } + } + + if (ext.tokenizer) { + // Tokenizer Extensions + if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') { + throw new Error("extension level must be 'block' or 'inline'"); + } + + if (extensions[ext.level]) { + extensions[ext.level].unshift(ext.tokenizer); + } else { + extensions[ext.level] = [ext.tokenizer]; + } + + if (ext.start) { + // Function to check for start of token + if (ext.level === 'block') { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start); + } else { + extensions.startBlock = [ext.start]; + } + } else if (ext.level === 'inline') { + if (extensions.startInline) { + extensions.startInline.push(ext.start); + } else { + extensions.startInline = [ext.start]; + } + } + } + } + + if (ext.childTokens) { + // Child tokens to be visited by walkTokens + extensions.childTokens[ext.name] = ext.childTokens; + } + }); + } // ==-- Parse "overwrite" extensions --== // + + + if (pack.renderer) { + (function () { + var renderer = marked.defaults.renderer || new Renderer(); + + var _loop = function _loop(prop) { + var prevRenderer = renderer[prop]; // Replace renderer with func to run extension, but fall back if false + + renderer[prop] = function () { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + var ret = pack.renderer[prop].apply(renderer, args); + + if (ret === false) { + ret = prevRenderer.apply(renderer, args); + } + + return ret; + }; + }; + + for (var prop in pack.renderer) { + _loop(prop); + } + + opts.renderer = renderer; + })(); + } + + if (pack.tokenizer) { + (function () { + var tokenizer = marked.defaults.tokenizer || new Tokenizer(); + + var _loop2 = function _loop2(prop) { + var prevTokenizer = tokenizer[prop]; // Replace tokenizer with func to run extension, but fall back if false + + tokenizer[prop] = function () { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + var ret = pack.tokenizer[prop].apply(tokenizer, args); + + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args); + } + + return ret; + }; + }; + + for (var prop in pack.tokenizer) { + _loop2(prop); + } + + opts.tokenizer = tokenizer; + })(); + } // ==-- Parse WalkTokens extensions --== // + + + if (pack.walkTokens) { + var _walkTokens = marked.defaults.walkTokens; + + opts.walkTokens = function (token) { + pack.walkTokens.call(this, token); + + if (_walkTokens) { + _walkTokens.call(this, token); + } + }; + } + + if (hasExtensions) { + opts.extensions = extensions; + } + + marked.setOptions(opts); + }); + }; + /** + * Run callback for every token + */ + + + marked.walkTokens = function (tokens, callback) { + var _loop3 = function _loop3() { + var token = _step.value; + callback.call(marked, token); + + switch (token.type) { + case 'table': + { + for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) { + var cell = _step2.value; + marked.walkTokens(cell.tokens, callback); + } + + for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) { + var row = _step3.value; + + for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) { + var _cell = _step4.value; + marked.walkTokens(_cell.tokens, callback); + } + } + + break; + } + + case 'list': + { + marked.walkTokens(token.items, callback); + break; + } + + default: + { + if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { + // Walk any extensions + marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) { + marked.walkTokens(token[childTokens], callback); + }); + } else if (token.tokens) { + marked.walkTokens(token.tokens, callback); + } + } + } + }; + + for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) { + _loop3(); + } + }; + /** + * Parse Inline + */ + + + marked.parseInline = function (src, opt) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked.parseInline(): input parameter is undefined or null'); + } + + if (typeof src !== 'string') { + throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + try { + var tokens = Lexer.lexInline(src, opt); + + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + + return Parser.parseInline(tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + + if (opt.silent) { + return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>'; + } + + throw e; + } + }; + /** + * Expose + */ + + + marked.Parser = Parser; + marked.parser = Parser.parse; + marked.Renderer = Renderer; + marked.TextRenderer = TextRenderer; + marked.Lexer = Lexer; + marked.lexer = Lexer.lex; + marked.Tokenizer = Tokenizer; + marked.Slugger = Slugger; + marked.parse = marked; + var options = marked.options; + var setOptions = marked.setOptions; + var use = marked.use; + var walkTokens = marked.walkTokens; + var parseInline = marked.parseInline; + var parse = marked; + var parser = Parser.parse; + var lexer = Lexer.lex; + + exports.Lexer = Lexer; + exports.Parser = Parser; + exports.Renderer = Renderer; + exports.Slugger = Slugger; + exports.TextRenderer = TextRenderer; + exports.Tokenizer = Tokenizer; + exports["default"] = marked; + exports.getDefaults = getDefaults; + exports.lexer = lexer; + exports.options = options; + exports.parse = parse; + exports.parseInline = parseInline; + exports.parser = parser; + exports.setOptions = setOptions; + exports.use = use; + exports.walkTokens = walkTokens; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); \ No newline at end of file diff --git a/src/renderer/js/notyf.min.js b/src/renderer/lib/notyf.min.js similarity index 100% rename from src/renderer/js/notyf.min.js rename to src/renderer/lib/notyf.min.js diff --git a/src/renderer/js/popper.min.js b/src/renderer/lib/popper.min.js similarity index 100% rename from src/renderer/js/popper.min.js rename to src/renderer/lib/popper.min.js diff --git a/src/renderer/lib/quasar/quasar.min.css b/src/renderer/lib/quasar/quasar.min.css new file mode 100644 index 00000000..60acb04b --- /dev/null +++ b/src/renderer/lib/quasar/quasar.min.css @@ -0,0 +1,14733 @@ +*, +:after, +:before { + box-sizing : inherit; + -webkit-tap-highlight-color: transparent; + -moz-tap-highlight-color : transparent +} + +#q-app, +body, +html { + width : 100%; + direction: ltr +} + +body.platform-ios.within-iframe, +body.platform-ios.within-iframe #q-app { + width : 100px; + min-width: 100% +} + +body, +html { + margin : 0; + box-sizing: border-box +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +main, +menu, +nav, +section, +summary { + display: block +} + +abbr[title] { + border-bottom : none; + text-decoration : underline; + -webkit-text-decoration: underline dotted; + text-decoration : underline dotted +} + +img { + border-style: none +} + +svg:not(:root) { + overflow: hidden +} + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size : 1em +} + +hr { + box-sizing: content-box; + height : 0; + overflow : visible +} + +fieldset { + padding: 0.35em 0.75em 0.625em +} + +legend { + box-sizing : border-box; + color : inherit; + display : table; + max-width : 100%; + padding : 0; + white-space: normal +} + +progress { + vertical-align: baseline +} + +textarea { + overflow: auto +} + +input[type=search]::-webkit-search-cancel-button, +input[type=search]::-webkit-search-decoration { + -webkit-appearance: none +} + +.q-icon { + line-height : 1; + width : 1em; + height : 1em; + flex-shrink : 0; + letter-spacing: normal; + text-transform: none; + white-space : nowrap; + word-wrap : normal; + direction : ltr; + text-align : center; + position : relative; + box-sizing : content-box; + fill : currentColor +} + +.q-icon:after, +.q-icon:before { + width : 100%; + height : 100%; + display : flex !important; + align-items : center; + justify-content: center +} + +.q-icon>img, +.q-icon>svg { + width : 100%; + height: 100% +} + +.material-icons, +.material-icons-outlined, +.material-icons-round, +.material-icons-sharp, +.material-symbols-outlined, +.material-symbols-rounded, +.material-symbols-sharp, +.q-icon { + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + cursor : inherit; + font-size : inherit; + display : inline-flex; + align-items : center; + justify-content : center; + vertical-align : middle +} + +.q-panel, +.q-panel>div { + height: 100%; + width : 100% +} + +.q-panel-parent { + overflow: hidden; + position: relative +} + +.q-loading-bar { + position : fixed; + z-index : 9998; + transition: transform 0.5s cubic-bezier(0, 0, 0.2, 1), opacity 0.5s; + background: #f44336 +} + +.q-loading-bar--top { + left : 0; + right: 0; + top : 0; + width: 100% +} + +.q-loading-bar--bottom { + left : 0; + right : 0; + bottom: 0; + width : 100% +} + +.q-loading-bar--right { + top : 0; + bottom: 0; + right : 0; + height: 100% +} + +.q-loading-bar--left { + top : 0; + bottom: 0; + left : 0; + height: 100% +} + +.q-avatar { + position : relative; + vertical-align: middle; + display : inline-block; + border-radius : 50%; + font-size : 48px; + height : 1em; + width : 1em +} + +.q-avatar__content { + font-size : 0.5em; + line-height: 0.5em +} + +.q-avatar__content, +.q-avatar img:not(.q-icon) { + border-radius: inherit; + height : inherit; + width : inherit +} + +.q-avatar--square { + border-radius: 0 +} + +.q-badge { + background-color: #1976d2; + background-color: var(--q-color-primary); + color : #fff; + padding : 2px 6px; + border-radius : 4px; + font-size : 12px; + min-height : 12px; + line-height : 12px; + font-weight : 400; + vertical-align : baseline +} + +.q-badge--single-line { + white-space: nowrap +} + +.q-badge--multi-line { + word-break: break-all; + word-wrap : break-word +} + +.q-badge--floating { + position: absolute; + top : -4px; + right : -3px; + cursor : inherit +} + +.q-badge--transparent { + opacity: 0.8 +} + +.q-badge--outline { + background-color: transparent; + border : 1px solid currentColor +} + +.q-badge--rounded { + border-radius: 1em +} + +.q-banner { + min-height: 54px; + padding : 8px 16px; + background: #fff +} + +.q-banner--top-padding { + padding-top: 14px +} + +.q-banner__avatar { + min-width: 1px !important +} + +.q-banner__avatar>.q-avatar { + font-size: 46px +} + +.q-banner__avatar>.q-icon { + font-size: 40px +} + +.q-banner__actions.col-auto, +.q-banner__avatar:not(:empty)+.q-banner__content { + padding-left: 16px +} + +.q-banner__actions.col-all .q-btn-item { + margin: 4px 0 0 4px +} + +.q-banner--dense { + min-height: 32px; + padding : 8px +} + +.q-banner--dense.q-banner--top-padding { + padding-top: 12px +} + +.q-banner--dense .q-banner__avatar>.q-avatar, +.q-banner--dense .q-banner__avatar>.q-icon { + font-size: 28px +} + +.q-banner--dense .q-banner__actions.col-auto, +.q-banner--dense .q-banner__avatar:not(:empty)+.q-banner__content { + padding-left: 8px +} + +.q-bar { + background: rgba(0, 0, 0, 0.2) +} + +.q-bar>.q-icon { + margin-left: 2px +} + +.q-bar>div, +.q-bar>div+.q-icon { + margin-left: 8px +} + +.q-bar>.q-btn { + margin-left: 2px +} + +.q-bar>.q-btn:first-child, +.q-bar>.q-icon:first-child, +.q-bar>div:first-child { + margin-left: 0 +} + +.q-bar--standard { + padding : 0 12px; + height : 32px; + font-size: 18px +} + +.q-bar--standard>div { + font-size: 16px +} + +.q-bar--standard .q-btn { + font-size: 11px +} + +.q-bar--dense { + padding : 0 8px; + height : 24px; + font-size: 14px +} + +.q-bar--dense .q-btn { + font-size: 8px +} + +.q-bar--dark { + background: hsla(0, 0%, 100%, 0.15) +} + +.q-breadcrumbs__el { + color: inherit +} + +.q-breadcrumbs__el-icon { + font-size: 125% +} + +.q-breadcrumbs__el-icon--with-label { + margin-right: 8px +} + +[dir=rtl] .q-breadcrumbs__separator .q-icon { + transform: scaleX(-1) +} + +.q-btn { + display : inline-flex; + flex-direction : column; + align-items : stretch; + position : relative; + outline : 0; + border : 0; + vertical-align : middle; + padding : 0; + font-size : 14px; + line-height : 1.715em; + text-decoration: none; + color : inherit; + background : transparent; + font-weight : 500; + text-transform : uppercase; + text-align : center; + width : auto; + height : auto +} + +.q-btn .q-icon, +.q-btn .q-spinner { + font-size: 1.715em +} + +.q-btn.disabled { + opacity: 0.7 !important +} + +.q-btn__wrapper { + padding : 4px 16px; + min-height : 2.572em; + border-radius: inherit; + width : 100%; + height : 100% +} + +.q-btn__wrapper:before { + content : ""; + display : block; + position : absolute; + left : 0; + right : 0; + top : 0; + bottom : 0; + border-radius: inherit; + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12) +} + +.q-btn--actionable { + cursor: pointer +} + +.q-btn--actionable.q-btn--standard .q-btn__wrapper:before { + transition: box-shadow 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) +} + +.q-btn--actionable.q-btn--standard.q-btn--active .q-btn__wrapper:before, +.q-btn--actionable.q-btn--standard:active .q-btn__wrapper:before { + box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 5px 8px rgba(0, 0, 0, 0.14), 0 1px 14px rgba(0, 0, 0, 0.12) +} + +.q-btn--no-uppercase { + text-transform: none +} + +.q-btn--rectangle { + border-radius: 3px +} + +.q-btn--outline { + background: transparent !important +} + +.q-btn--outline .q-btn__wrapper:before { + border: 1px solid currentColor +} + +.q-btn--push { + border-radius: 7px +} + +.q-btn--push .q-btn__wrapper:before { + border-bottom: 3px solid rgba(0, 0, 0, 0.15) +} + +.q-btn--push.q-btn--actionable { + transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) +} + +.q-btn--push.q-btn--actionable .q-btn__wrapper:before { + transition: top 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), bottom 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), border-bottom-width 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) +} + +.q-btn--push.q-btn--actionable.q-btn--active, +.q-btn--push.q-btn--actionable:active { + transform: translateY(2px) +} + +.q-btn--push.q-btn--actionable.q-btn--active .q-btn__wrapper:before, +.q-btn--push.q-btn--actionable:active .q-btn__wrapper:before { + border-bottom-width: 0 +} + +.q-btn--rounded { + border-radius: 28px +} + +.q-btn--round { + border-radius: 50% +} + +.q-btn--round .q-btn__wrapper { + padding : 0; + min-width : 3em; + min-height: 3em +} + +.q-btn--flat .q-btn__wrapper:before, +.q-btn--outline .q-btn__wrapper:before, +.q-btn--unelevated .q-btn__wrapper:before { + box-shadow: none +} + +.q-btn--dense .q-btn__wrapper { + padding : 0.285em; + min-height: 2em +} + +.q-btn--dense.q-btn--round .q-btn__wrapper { + padding : 0; + min-height: 2.4em; + min-width : 2.4em +} + +.q-btn--dense .on-left { + margin-right: 6px +} + +.q-btn--dense .on-right { + margin-left: 6px +} + +.q-btn--fab-mini .q-icon, +.q-btn--fab .q-icon { + font-size: 24px +} + +.q-btn--fab .q-icon { + margin: auto +} + +.q-btn--fab .q-btn__wrapper { + padding : 16px; + min-height: 56px; + min-width : 56px +} + +.q-btn--fab-mini .q-btn__wrapper { + padding : 8px; + min-height: 40px; + min-width : 40px +} + +.q-btn__content { + transition: opacity 0.3s; + z-index : 0 +} + +.q-btn__content--hidden { + opacity : 0; + pointer-events: none +} + +.q-btn__progress { + border-radius: inherit; + z-index : 0 +} + +.q-btn__progress-indicator { + z-index : -1; + transform : translateX(-100%); + background: hsla(0, 0%, 100%, 0.25) +} + +.q-btn__progress--dark .q-btn__progress-indicator { + background: rgba(0, 0, 0, 0.2) +} + +.q-btn--flat .q-btn__progress-indicator, +.q-btn--outline .q-btn__progress-indicator { + opacity : 0.2; + background: currentColor +} + +.q-btn-dropdown--split .q-btn-dropdown__arrow-container.q-btn--outline { + border-left: 1px solid currentColor +} + +.q-btn-dropdown--split .q-btn-dropdown__arrow-container:not(.q-btn--outline) { + border-left: 1px solid hsla(0, 0%, 100%, 0.3) +} + +.q-btn-dropdown--split .q-btn-dropdown__arrow-container .q-btn__wrapper { + padding: 0 4px +} + +.q-btn-dropdown--simple *+.q-btn-dropdown__arrow { + margin-left: 8px +} + +.q-btn-dropdown__arrow { + transition: transform 0.28s +} + +.q-btn-dropdown--current { + flex-grow: 1 +} + +.q-btn-group { + border-radius : 3px; + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + vertical-align: middle +} + +.q-btn-group>.q-btn-item { + border-radius: inherit; + align-self : stretch +} + +.q-btn-group>.q-btn-item .q-btn__wrapper:before { + box-shadow: none +} + +.q-btn-group>.q-btn-item .q-badge--floating { + right: 0 +} + +.q-btn-group>.q-btn-group { + box-shadow: none +} + +.q-btn-group>.q-btn-group:first-child>.q-btn:first-child { + border-top-left-radius : inherit; + border-bottom-left-radius: inherit +} + +.q-btn-group>.q-btn-group:last-child>.q-btn:last-child { + border-top-right-radius : inherit; + border-bottom-right-radius: inherit +} + +.q-btn-group>.q-btn-group:not(:first-child)>.q-btn:first-child .q-btn__wrapper:before { + border-left: 0 +} + +.q-btn-group>.q-btn-group:not(:last-child)>.q-btn:last-child .q-btn__wrapper:before { + border-right: 0 +} + +.q-btn-group>.q-btn-item:not(:last-child) { + border-top-right-radius : 0; + border-bottom-right-radius: 0 +} + +.q-btn-group>.q-btn-item:not(:first-child) { + border-top-left-radius : 0; + border-bottom-left-radius: 0 +} + +.q-btn-group>.q-btn-item.q-btn--standard .q-btn__wrapper:before { + z-index: -1 +} + +.q-btn-group--push { + border-radius: 7px +} + +.q-btn-group--push>.q-btn--push.q-btn--actionable { + transform: none +} + +.q-btn-group--push>.q-btn--push.q-btn--actionable .q-btn__wrapper { + transition: margin-top 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), margin-bottom 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), box-shadow 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) +} + +.q-btn-group--push>.q-btn--push.q-btn--actionable.q-btn--active .q-btn__wrapper, +.q-btn-group--push>.q-btn--push.q-btn--actionable:active .q-btn__wrapper { + margin-top : 2px; + margin-bottom: -2px +} + +.q-btn-group--rounded { + border-radius: 28px +} + +.q-btn-group--flat, +.q-btn-group--outline, +.q-btn-group--unelevated { + box-shadow: none +} + +.q-btn-group--outline>.q-separator { + display: none +} + +.q-btn-group--outline>.q-btn-item+.q-btn-item .q-btn__wrapper:before { + border-left: 0 +} + +.q-btn-group--outline>.q-btn-item:not(:last-child) .q-btn__wrapper:before { + border-right: 0 +} + +.q-btn-group--stretch { + align-self : stretch; + border-radius: 0 +} + +.q-btn-group--glossy>.q-btn-item { + background-image: linear-gradient(180deg, hsla(0, 0%, 100%, 0.3), hsla(0, 0%, 100%, 0) 50%, rgba(0, 0, 0, 0.12) 51%, rgba(0, 0, 0, 0.04)) !important +} + +.q-btn-group--spread>.q-btn-group { + display: flex !important +} + +.q-btn-group--spread>.q-btn-group>.q-btn-item:not(.q-btn-dropdown__arrow-container), +.q-btn-group--spread>.q-btn-item { + width : auto; + min-width: 0; + max-width: 100%; + flex : 10000 1 0% +} + +.q-btn-toggle, +.q-card { + position: relative +} + +.q-card { + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + border-radius : 4px; + vertical-align: top; + background : #fff +} + +.q-card>div:first-child, +.q-card>img:first-child { + border-top : 0; + border-top-left-radius : inherit; + border-top-right-radius: inherit +} + +.q-card>div:last-child, +.q-card>img:last-child { + border-bottom : 0; + border-bottom-left-radius : inherit; + border-bottom-right-radius: inherit +} + +.q-card>div:not(:first-child), +.q-card>img:not(:first-child) { + border-top-left-radius : 0; + border-top-right-radius: 0 +} + +.q-card>div:not(:last-child), +.q-card>img:not(:last-child) { + border-bottom-left-radius : 0; + border-bottom-right-radius: 0 +} + +.q-card>div { + border-left : 0; + border-right: 0; + box-shadow : none +} + +.q-card--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-card--dark { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-card__section { + position: relative +} + +.q-card__section--vert { + padding: 16px +} + +.q-card__section--horiz>div:first-child, +.q-card__section--horiz>img:first-child { + border-top-left-radius : inherit; + border-bottom-left-radius: inherit +} + +.q-card__section--horiz>div:last-child, +.q-card__section--horiz>img:last-child { + border-top-right-radius : inherit; + border-bottom-right-radius: inherit +} + +.q-card__section--horiz>div:not(:first-child), +.q-card__section--horiz>img:not(:first-child) { + border-top-left-radius : 0; + border-bottom-left-radius: 0 +} + +.q-card__section--horiz>div:not(:last-child), +.q-card__section--horiz>img:not(:last-child) { + border-top-right-radius : 0; + border-bottom-right-radius: 0 +} + +.q-card__section--horiz>div { + border-top : 0; + border-bottom: 0; + box-shadow : none +} + +.q-card__actions { + padding : 8px; + align-items: center +} + +.q-card__actions .q-btn__wrapper { + padding: 0 8px +} + +.q-card__actions--horiz>.q-btn-group+.q-btn-item, +.q-card__actions--horiz>.q-btn-item+.q-btn-group, +.q-card__actions--horiz>.q-btn-item+.q-btn-item { + margin-left: 8px +} + +.q-card__actions--vert>.q-btn-item.q-btn--round { + align-self: center +} + +.q-card__actions--vert>.q-btn-group+.q-btn-item, +.q-card__actions--vert>.q-btn-item+.q-btn-group, +.q-card__actions--vert>.q-btn-item+.q-btn-item { + margin-top: 4px +} + +.q-card__actions--vert>.q-btn-group>.q-btn-item { + flex-grow: 1 +} + +.q-card>img { + display : block; + width : 100%; + max-width: 100%; + border : 0 +} + +.q-carousel { + background-color: #fff; + height : 400px +} + +.q-carousel__slide { + min-height : 100%; + background-size : cover; + background-position: 50% +} + +.q-carousel .q-carousel--padding, +.q-carousel__slide { + padding: 16px +} + +.q-carousel__slides-container { + height: 100% +} + +.q-carousel__control { + color: #fff +} + +.q-carousel__arrow { + pointer-events: none +} + +.q-carousel__arrow .q-icon { + font-size: 28px +} + +.q-carousel__arrow .q-btn { + pointer-events: all +} + +.q-carousel__next-arrow--horizontal, +.q-carousel__prev-arrow--horizontal { + top : 16px; + bottom: 16px +} + +.q-carousel__prev-arrow--horizontal { + left: 16px +} + +.q-carousel__next-arrow--horizontal { + right: 16px +} + +.q-carousel__next-arrow--vertical, +.q-carousel__prev-arrow--vertical { + left : 16px; + right: 16px +} + +.q-carousel__prev-arrow--vertical { + top: 16px +} + +.q-carousel__next-arrow--vertical { + bottom: 16px +} + +.q-carousel__navigation--bottom, +.q-carousel__navigation--top { + left : 16px; + right : 16px; + overflow-x: auto; + overflow-y: hidden +} + +.q-carousel__navigation--top { + top: 16px +} + +.q-carousel__navigation--bottom { + bottom: 16px +} + +.q-carousel__navigation--left, +.q-carousel__navigation--right { + top : 16px; + bottom : 16px; + overflow-x: hidden; + overflow-y: auto +} + +.q-carousel__navigation--left>.q-carousel__navigation-inner, +.q-carousel__navigation--right>.q-carousel__navigation-inner { + flex-direction: column +} + +.q-carousel__navigation--left { + left: 16px +} + +.q-carousel__navigation--right { + right: 16px +} + +.q-carousel__navigation-inner { + flex: 1 1 auto +} + +.q-carousel__navigation .q-btn { + margin: 6px 4px +} + +.q-carousel__navigation .q-btn .q-btn__wrapper { + padding: 5px +} + +.q-carousel__navigation-icon--inactive { + opacity: 0.7 +} + +.q-carousel .q-carousel__thumbnail { + margin : 2px; + height : 50px; + width : auto; + display : inline-block; + cursor : pointer; + border : 1px solid transparent; + border-radius : 4px; + vertical-align: middle; + opacity : 0.7; + transition : opacity 0.3s +} + +.q-carousel .q-carousel__thumbnail--active, +.q-carousel .q-carousel__thumbnail:hover { + opacity: 1 +} + +.q-carousel .q-carousel__thumbnail--active { + border-color: currentColor; + cursor : default +} + +.q-carousel--arrows-vertical .q-carousel--padding, +.q-carousel--arrows-vertical.q-carousel--with-padding .q-carousel__slide, +.q-carousel--navigation-top .q-carousel--padding, +.q-carousel--navigation-top.q-carousel--with-padding .q-carousel__slide { + padding-top: 60px +} + +.q-carousel--arrows-vertical .q-carousel--padding, +.q-carousel--arrows-vertical.q-carousel--with-padding .q-carousel__slide, +.q-carousel--navigation-bottom .q-carousel--padding, +.q-carousel--navigation-bottom.q-carousel--with-padding .q-carousel__slide { + padding-bottom: 60px +} + +.q-carousel--arrows-horizontal .q-carousel--padding, +.q-carousel--arrows-horizontal.q-carousel--with-padding .q-carousel__slide, +.q-carousel--navigation-left .q-carousel--padding, +.q-carousel--navigation-left.q-carousel--with-padding .q-carousel__slide { + padding-left: 60px +} + +.q-carousel--arrows-horizontal .q-carousel--padding, +.q-carousel--arrows-horizontal.q-carousel--with-padding .q-carousel__slide, +.q-carousel--navigation-right .q-carousel--padding, +.q-carousel--navigation-right.q-carousel--with-padding .q-carousel__slide { + padding-right: 60px +} + +.q-carousel.fullscreen { + height: 100% +} + +.q-message-label, +.q-message-name, +.q-message-stamp { + font-size: small +} + +.q-message-label { + margin : 24px 0; + text-align: center +} + +.q-message-stamp { + color : inherit; + margin-top: 4px; + opacity : 0.6; + display : none +} + +.q-message-avatar { + border-radius: 50%; + width : 48px; + height : 48px; + min-width : 48px +} + +.q-message { + margin-bottom: 8px +} + +.q-message:first-child .q-message-label { + margin-top: 0 +} + +.q-message-avatar--received { + margin-right: 8px +} + +.q-message-text--received { + color : #81c784; + border-radius: 4px 4px 4px 0 +} + +.q-message-text--received:last-child:before { + right : 100%; + border-right : 0 solid transparent; + border-left : 8px solid transparent; + border-bottom: 8px solid currentColor +} + +.q-message-text-content--received { + color: #000 +} + +.q-message-name--sent { + text-align: right +} + +.q-message-avatar--sent { + margin-left: 8px +} + +.q-message-container--sent { + flex-direction: row-reverse +} + +.q-message-text--sent { + color : #e0e0e0; + border-radius: 4px 4px 0 4px +} + +.q-message-text--sent:last-child:before { + left : 100%; + border-left : 0 solid transparent; + border-right : 8px solid transparent; + border-bottom: 8px solid currentColor +} + +.q-message-text-content--sent { + color: #000 +} + +.q-message-text { + background : currentColor; + padding : 8px; + line-height: 1.2; + word-break : break-word; + position : relative +} + +.q-message-text+.q-message-text { + margin-top: 3px +} + +.q-message-text:last-child { + min-height: 48px +} + +.q-message-text:last-child .q-message-stamp { + display: block +} + +.q-message-text:last-child:before { + content : ""; + position: absolute; + bottom : 0; + width : 0; + height : 0 +} + +.q-checkbox { + vertical-align: middle +} + +.q-checkbox__native { + width : 1px; + height: 1px +} + +.q-checkbox__bg, +.q-checkbox__icon-container { + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none +} + +.q-checkbox__bg { + top : 25%; + left : 25%; + width : 50%; + height : 50%; + border : 2px solid currentColor; + border-radius : 2px; + transition : background 0.22s cubic-bezier(0, 0, 0.2, 1) 0ms; + -webkit-print-color-adjust: exact +} + +.q-checkbox__icon { + color : currentColor; + font-size: 0.5em +} + +.q-checkbox__svg { + color: #fff +} + +.q-checkbox__truthy { + stroke : currentColor; + stroke-width : 3.12px; + stroke-dashoffset: 29.78334; + stroke-dasharray : 29.78334 +} + +.q-checkbox__indet { + fill : currentColor; + transform-origin: 50% 50%; + transform : rotate(-280deg) scale(0) +} + +.q-checkbox__inner { + font-size : 40px; + width : 1em; + min-width : 1em; + height : 1em; + outline : 0; + border-radius: 50%; + color : rgba(0, 0, 0, 0.54) +} + +.q-checkbox__inner--indet, +.q-checkbox__inner--truthy { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-checkbox__inner--indet .q-checkbox__bg, +.q-checkbox__inner--truthy .q-checkbox__bg { + background: currentColor +} + +.q-checkbox__inner--truthy path { + stroke-dashoffset: 0; + transition : stroke-dashoffset 0.18s cubic-bezier(0.4, 0, 0.6, 1) 0ms +} + +.q-checkbox__inner--indet .q-checkbox__indet { + transform : rotate(0) scale(1); + transition: transform 0.22s cubic-bezier(0, 0, 0.2, 1) 0ms +} + +.q-checkbox.disabled { + opacity: 0.75 !important +} + +.q-checkbox--dark .q-checkbox__inner { + color: hsla(0, 0%, 100%, 0.7) +} + +.q-checkbox--dark .q-checkbox__inner:before { + opacity: 0.32 !important +} + +.q-checkbox--dark .q-checkbox__inner--indet, +.q-checkbox--dark .q-checkbox__inner--truthy { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-checkbox--dense .q-checkbox__inner { + width : 0.5em; + min-width: 0.5em; + height : 0.5em +} + +.q-checkbox--dense .q-checkbox__bg { + left : 5%; + top : 5%; + width : 90%; + height: 90% +} + +.q-checkbox--dense .q-checkbox__label { + padding-left: 0.5em +} + +.q-checkbox--dense.reverse .q-checkbox__label { + padding-left : 0; + padding-right: 0.5em +} + +body.desktop .q-checkbox:not(.disabled) .q-checkbox__inner:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + border-radius: 50%; + background : currentColor; + opacity : 0.12; + transform : scale3d(0, 0, 1); + transition : transform 0.22s cubic-bezier(0, 0, 0.2, 1) +} + +body.desktop .q-checkbox:not(.disabled):focus .q-checkbox__inner:before, +body.desktop .q-checkbox:not(.disabled):hover .q-checkbox__inner:before { + transform: scale3d(1, 1, 1) +} + +body.desktop .q-checkbox--dense:not(.disabled):focus .q-checkbox__inner:before, +body.desktop .q-checkbox--dense:not(.disabled):hover .q-checkbox__inner:before { + transform: scale3d(1.4, 1.4, 1) +} + +.q-chip { + vertical-align: middle; + border-radius : 16px; + outline : 0; + position : relative; + height : 2em; + max-width : 100%; + margin : 4px; + background : #e0e0e0; + color : rgba(0, 0, 0, 0.87); + font-size : 14px; + padding : 0.5em 0.9em +} + +.q-chip--colored .q-chip__icon, +.q-chip--dark .q-chip__icon { + color: inherit +} + +.q-chip--outline { + background: transparent !important; + border : 1px solid currentColor +} + +.q-chip .q-avatar { + font-size : 2em; + margin-left : -0.45em; + margin-right : 0.2em; + border-radius: 16px +} + +.q-chip--selected .q-avatar { + display: none +} + +.q-chip__icon { + color : rgba(0, 0, 0, 0.54); + font-size: 1.5em; + margin : -0.2em +} + +.q-chip__icon--left { + margin-right: 0.2em +} + +.q-chip__icon--right { + margin-left: 0.2em +} + +.q-chip__icon--remove { + margin-left : 0.1em; + margin-right: -0.5em; + opacity : 0.6; + outline : 0 +} + +.q-chip__icon--remove:focus, +.q-chip__icon--remove:hover { + opacity: 1 +} + +.q-chip__content { + white-space: nowrap +} + +.q-chip--dense { + border-radius: 12px; + padding : 0 0.4em; + height : 1.5em +} + +.q-chip--dense .q-avatar { + font-size : 1.5em; + margin-left : -0.27em; + margin-right : 0.1em; + border-radius: 12px +} + +.q-chip--dense .q-chip__icon { + font-size: 1.25em +} + +.q-chip--dense .q-chip__icon--left { + margin-right: 0.195em +} + +.q-chip--dense .q-chip__icon--remove { + margin-right: -0.25em +} + +.q-chip--square { + border-radius: 4px +} + +.q-chip--square .q-avatar { + border-radius: 3px 0 0 3px +} + +body.desktop .q-chip--clickable:focus { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12) +} + +.q-circular-progress { + display : inline-block; + position : relative; + vertical-align: middle; + width : 1em; + height : 1em; + line-height : 1 +} + +.q-circular-progress.q-focusable { + border-radius: 50% +} + +.q-circular-progress__svg { + width : 100%; + height: 100% +} + +.q-circular-progress__text { + font-size: 0.25em +} + +.q-circular-progress--indeterminate .q-circular-progress__svg { + transform-origin : 50% 50%; + -webkit-animation: q-spin 2s linear infinite; + animation : q-spin 2s linear infinite +} + +.q-circular-progress--indeterminate .q-circular-progress__circle { + stroke-dasharray : 1 400; + stroke-dashoffset: 0; + -webkit-animation: q-circular-progress-circle 1.5s ease-in-out infinite; + animation : q-circular-progress-circle 1.5s ease-in-out infinite +} + +.q-color-picker { + overflow : hidden; + background : #fff; + max-width : 350px; + vertical-align: top; + min-width : 180px; + border-radius : 4px; + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12) +} + +.q-color-picker .q-tab { + padding: 0 !important +} + +.q-color-picker--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-color-picker__header-tabs { + height: 32px +} + +.q-color-picker__header input { + line-height: 24px; + border : 0 +} + +.q-color-picker__header .q-tab { + min-height: 32px !important; + height : 32px !important +} + +.q-color-picker__header .q-tab--inactive { + background: linear-gradient(0deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.15) 25%, rgba(0, 0, 0, 0.1)) +} + +.q-color-picker__error-icon { + bottom : 2px; + right : 2px; + font-size : 24px; + opacity : 0; + transition: opacity 0.3s ease-in +} + +.q-color-picker__header-content { + position : relative; + background: #fff +} + +.q-color-picker__header-content--light { + color: #000 +} + +.q-color-picker__header-content--dark { + color: #fff +} + +.q-color-picker__header-content--dark .q-tab--inactive:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + background: hsla(0, 0%, 100%, 0.2) +} + +.q-color-picker__header-banner { + height: 36px +} + +.q-color-picker__header-bg { + background : #fff; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAH0lEQVQoU2NkYGAwZkAFZ5G5jPRRgOYEVDeB3EBjBQBOZwTVugIGyAAAAABJRU5ErkJggg==") !important +} + +.q-color-picker__footer { + height: 36px +} + +.q-color-picker__footer .q-tab { + min-height: 36px !important; + height : 36px !important +} + +.q-color-picker__footer .q-tab--inactive { + background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.15) 25%, rgba(0, 0, 0, 0.1)) +} + +.q-color-picker__spectrum { + width : 100%; + height: 100% +} + +.q-color-picker__spectrum-tab { + padding: 0 !important +} + +.q-color-picker__spectrum-white { + background: linear-gradient(90deg, #fff, hsla(0, 0%, 100%, 0)) +} + +.q-color-picker__spectrum-black { + background: linear-gradient(0deg, #000, transparent) +} + +.q-color-picker__spectrum-circle { + width : 10px; + height : 10px; + box-shadow : 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0, 0, 0, 0.3), 0 0 1px 2px rgba(0, 0, 0, 0.4); + border-radius: 50%; + transform : translate(-5px, -5px) +} + +.q-color-picker__hue .q-slider__track { + background: linear-gradient(90deg, red 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, red) !important; + opacity : 1 +} + +.q-color-picker__alpha .q-slider__track-container { + padding-top: 0 +} + +.q-color-picker__alpha .q-slider__track:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + border-radius: inherit; + background : linear-gradient(90deg, hsla(0, 0%, 100%, 0), #757575) +} + +.q-color-picker__sliders { + padding: 0 16px +} + +.q-color-picker__sliders .q-slider__thumb { + color: #424242 +} + +.q-color-picker__sliders .q-slider__thumb path { + stroke-width: 2px; + fill : transparent +} + +.q-color-picker__sliders .q-slider--active path { + stroke-width: 3px +} + +.q-color-picker__tune-tab .q-slider { + margin-left : 18px; + margin-right: 18px +} + +.q-color-picker__tune-tab input { + font-size : 11px; + border : 1px solid #e0e0e0; + border-radius: 4px; + width : 3.5em +} + +.q-color-picker__palette-tab { + padding: 0 !important +} + +.q-color-picker__palette-rows--editable .q-color-picker__cube { + cursor: pointer +} + +.q-color-picker__cube { + padding-bottom: 10%; + width : 10% !important +} + +.q-color-picker input { + color : inherit; + background: transparent; + outline : 0; + text-align: center +} + +.q-color-picker .q-tabs { + overflow: hidden +} + +.q-color-picker .q-tab--active { + box-shadow: 0 0 14px 3px rgba(0, 0, 0, 0.2) +} + +.q-color-picker .q-tab--active .q-focus-helper, +.q-color-picker .q-tab__indicator { + display: none +} + +.q-color-picker .q-tab-panels { + background: inherit +} + +.q-color-picker--dark .q-color-picker__tune-tab input { + border: 1px solid hsla(0, 0%, 100%, 0.3) +} + +.q-color-picker--dark .q-slider { + color: #fafafa +} + +.q-date { + display : inline-flex; + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + border-radius: 4px; + background : #fff; + width : 290px; + min-width : 290px; + max-width : 100% +} + +.q-date--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-date__header { + border-top-left-radius: inherit; + color : #fff; + background-color : #1976d2; + background-color : var(--q-color-primary); + padding : 16px +} + +.q-date__actions { + padding: 0 16px 16px +} + +.q-date__content, +.q-date__main { + outline: 0 +} + +.q-date__content .q-btn { + font-weight: 400 +} + +.q-date__header-link { + opacity : 0.64; + outline : 0; + transition: opacity 0.3s ease-out +} + +.q-date__header-link--active, +.q-date__header-link:focus, +.q-date__header-link:hover { + opacity: 1 +} + +.q-date__header-subtitle { + font-size : 14px; + line-height : 1.75; + letter-spacing: 0.00938em +} + +.q-date__header-title-label { + font-size : 24px; + line-height : 1.2; + letter-spacing: 0.00735em +} + +.q-date__view { + height : 100%; + width : 100%; + min-height: 290px; + padding : 16px +} + +.q-date__navigation { + height: 12.5% +} + +.q-date__navigation>div:first-child { + width : 8%; + min-width : 24px; + justify-content: flex-end +} + +.q-date__navigation>div:last-child { + width : 8%; + min-width : 24px; + justify-content: flex-start +} + +.q-date__calendar-weekdays { + height: 12.5% +} + +.q-date__calendar-weekdays>div { + opacity : 0.38; + font-size: 12px +} + +.q-date__calendar-item { + display : inline-flex; + align-items : center; + justify-content: center; + vertical-align : middle; + width : 14.285% !important; + height : 12.5% !important; + position : relative; + padding : 1px +} + +.q-date__calendar-item:after { + content : ""; + position : absolute; + pointer-events: none; + top : 1px; + right : 0; + bottom : 1px; + left : 0; + border-style : dashed; + border-color : transparent; + border-width : 1px +} + +.q-date__calendar-item>div, +.q-date__calendar-item button { + width : 30px; + height : 30px; + border-radius: 50% +} + +.q-date__calendar-item>div { + line-height: 30px; + text-align : center +} + +.q-date__calendar-item>button { + line-height: 22px +} + +.q-date__calendar-item--out { + opacity: 0.18 +} + +.q-date__calendar-item--fill { + visibility: hidden +} + +.q-date__range-from:before, +.q-date__range-to:before, +.q-date__range:before { + content : ""; + background-color: currentColor; + position : absolute; + top : 1px; + bottom : 1px; + left : 0; + right : 0; + opacity : 0.3 +} + +.q-date__range-from:nth-child(7n-6):before, +.q-date__range-to:nth-child(7n-6):before, +.q-date__range:nth-child(7n-6):before { + border-top-left-radius : 0; + border-bottom-left-radius: 0 +} + +.q-date__range-from:nth-child(7n):before, +.q-date__range-to:nth-child(7n):before, +.q-date__range:nth-child(7n):before { + border-top-right-radius : 0; + border-bottom-right-radius: 0 +} + +.q-date__range-from:before { + left: 50% +} + +.q-date__range-to:before { + right: 50% +} + +.q-date__edit-range:after { + border-color: currentColor transparent +} + +.q-date__edit-range:nth-child(7n-6):after { + border-top-left-radius : 0; + border-bottom-left-radius: 0 +} + +.q-date__edit-range:nth-child(7n):after { + border-top-right-radius : 0; + border-bottom-right-radius: 0 +} + +.q-date__edit-range-from-to:after, +.q-date__edit-range-from:after { + left : 4px; + border-left-color : currentColor; + border-top-color : currentColor; + border-bottom-color : currentColor; + border-top-left-radius : 28px; + border-bottom-left-radius: 28px +} + +.q-date__edit-range-from-to:after, +.q-date__edit-range-to:after { + right : 4px; + border-right-color : currentColor; + border-top-color : currentColor; + border-bottom-color : currentColor; + border-top-right-radius : 28px; + border-bottom-right-radius: 28px +} + +.q-date__calendar-days-container { + height : 75%; + min-height: 192px +} + +.q-date__calendar-days>div { + height: 16.66% !important +} + +.q-date__event { + position : absolute; + bottom : 2px; + left : 50%; + height : 5px; + width : 8px; + border-radius : 5px; + background-color: #26a69a; + background-color: var(--q-color-secondary); + transform : translate3d(-50%, 0, 0) +} + +.q-date__today { + box-shadow: 0 0 1px 0 currentColor +} + +.q-date__years-content { + padding: 0 8px +} + +.q-date__months-item, +.q-date__years-item { + flex: 0 0 33.3333% +} + +.q-date--readonly .q-date__content, +.q-date--readonly .q-date__header, +.q-date.disabled .q-date__content, +.q-date.disabled .q-date__header { + pointer-events: none +} + +.q-date--readonly .q-date__navigation { + display: none +} + +.q-date--portrait { + flex-direction: column +} + +.q-date--portrait-standard .q-date__content { + height: calc(100% - 86px) +} + +.q-date--portrait-standard .q-date__header { + border-top-right-radius: inherit; + height : 86px +} + +.q-date--portrait-standard .q-date__header-title { + align-items: center; + height : 30px +} + +.q-date--portrait-minimal .q-date__content { + height: 100% +} + +.q-date--landscape { + flex-direction: row; + align-items : stretch; + min-width : 420px +} + +.q-date--landscape>div { + display : flex; + flex-direction: column +} + +.q-date--landscape .q-date__content { + height: 100% +} + +.q-date--landscape-standard { + min-width: 420px +} + +.q-date--landscape-standard .q-date__header { + border-bottom-left-radius: inherit; + min-width : 110px; + width : 110px +} + +.q-date--landscape-standard .q-date__header-title { + flex-direction: column +} + +.q-date--landscape-standard .q-date__header-today { + margin-top : 12px; + margin-left: -8px +} + +.q-date--landscape-minimal { + width: 310px +} + +.q-date--dark { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-dialog__title { + font-size : 1.25rem; + font-weight : 500; + line-height : 2rem; + letter-spacing: 0.0125em +} + +.q-dialog__progress { + font-size: 4rem +} + +.q-dialog__inner { + outline: 0 +} + +.q-dialog__inner>div { + pointer-events : all; + overflow : auto; + -webkit-overflow-scrolling: touch; + will-change : scroll-position; + border-radius : 4px; + box-shadow : 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px rgba(0, 0, 0, 0.14), 0 1px 10px rgba(0, 0, 0, 0.12) +} + +.q-dialog__inner--square>div { + border-radius: 0 !important +} + +.q-dialog__inner>.q-card>.q-card__actions .q-btn--rectangle .q-btn__wrapper { + min-width: 64px +} + +.q-dialog__inner--minimized { + padding: 24px +} + +.q-dialog__inner--minimized>div { + max-height: calc(100vh - 48px) +} + +.q-dialog__inner--maximized>div { + height : 100%; + width : 100%; + max-height : 100vh; + max-width : 100vw; + border-radius: 0 !important +} + +.q-dialog__inner--bottom, +.q-dialog__inner--top { + padding-top : 0 !important; + padding-bottom: 0 !important +} + +.q-dialog__inner--left, +.q-dialog__inner--right { + padding-right: 0 !important; + padding-left : 0 !important +} + +.q-dialog__inner--left:not(.q-dialog__inner--animating)>div, +.q-dialog__inner--top:not(.q-dialog__inner--animating)>div { + border-top-left-radius: 0 +} + +.q-dialog__inner--right:not(.q-dialog__inner--animating)>div, +.q-dialog__inner--top:not(.q-dialog__inner--animating)>div { + border-top-right-radius: 0 +} + +.q-dialog__inner--bottom:not(.q-dialog__inner--animating)>div, +.q-dialog__inner--left:not(.q-dialog__inner--animating)>div { + border-bottom-left-radius: 0 +} + +.q-dialog__inner--bottom:not(.q-dialog__inner--animating)>div, +.q-dialog__inner--right:not(.q-dialog__inner--animating)>div { + border-bottom-right-radius: 0 +} + +.q-dialog__inner--fullwidth>div { + width : 100% !important; + max-width: 100% !important +} + +.q-dialog__inner--fullheight>div { + height : 100% !important; + max-height: 100% !important +} + +.q-dialog__backdrop { + z-index : -1; + pointer-events: all; + outline : 0; + background : rgba(0, 0, 0, 0.4) +} + +body.platform-android:not(.native-mobile) .q-dialog__inner--minimized>div, +body.platform-ios .q-dialog__inner--minimized>div { + max-height: calc(100vh - 108px) +} + +body.q-ios-padding .q-dialog__inner { + padding-top : 20px !important; + padding-top : env(safe-area-inset-top) !important; + padding-bottom: env(safe-area-inset-bottom) !important +} + +body.q-ios-padding .q-dialog__inner>div { + max-height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom)) !important +} + +@media (max-width:599.98px) { + + .q-dialog__inner--bottom, + .q-dialog__inner--top { + padding-left : 0; + padding-right: 0 + } + + .q-dialog__inner--bottom>div, + .q-dialog__inner--top>div { + width: 100% !important + } +} + +@media (min-width:600px) { + .q-dialog__inner--minimized>div { + max-width: 560px + } +} + +.q-body--dialog { + overflow: hidden +} + +.q-bottom-sheet { + padding-bottom: 8px +} + +.q-bottom-sheet__avatar { + border-radius: 50% +} + +.q-bottom-sheet--list { + width: 400px +} + +.q-bottom-sheet--list .q-icon, +.q-bottom-sheet--list img { + font-size: 24px; + width : 24px; + height : 24px +} + +.q-bottom-sheet--grid { + width: 700px +} + +.q-bottom-sheet--grid .q-bottom-sheet__item { + padding : 8px; + text-align: center; + min-width : 100px +} + +.q-bottom-sheet--grid .q-bottom-sheet__empty-icon, +.q-bottom-sheet--grid .q-icon, +.q-bottom-sheet--grid img { + font-size : 48px; + width : 48px; + height : 48px; + margin-bottom: 8px +} + +.q-bottom-sheet--grid .q-separator { + margin: 12px 0 +} + +.q-bottom-sheet__item { + flex: 0 0 33.3333% +} + +@media (min-width:600px) { + .q-bottom-sheet__item { + flex: 0 0 25% + } +} + +.q-dialog-plugin { + width: 400px +} + +.q-dialog-plugin__form { + max-height: 50vh +} + +.q-dialog-plugin .q-card__section+.q-card__section { + padding-top: 0 +} + +.q-dialog-plugin--progress { + text-align: center +} + +.q-editor { + border : 1px solid rgba(0, 0, 0, 0.12); + border-radius : 4px; + background-color: #fff +} + +.q-editor.disabled { + border-style: dashed +} + +.q-editor.fullscreen { + max-height: 100% +} + +.q-editor>div:first-child, +.q-editor__toolbars-container, +.q-editor__toolbars-container>div:first-child { + border-top-left-radius : inherit; + border-top-right-radius: inherit +} + +.q-editor__toolbars-container { + max-width: 100% +} + +.q-editor__content { + outline : 0; + padding : 10px; + min-height : 10em; + border-bottom-left-radius : inherit; + border-bottom-right-radius: inherit; + overflow : auto; + max-width : 100% +} + +.q-editor__content pre { + white-space: pre-wrap +} + +.q-editor__content hr { + border : 0; + outline : 0; + margin : 1px; + height : 1px; + background: rgba(0, 0, 0, 0.12) +} + +.q-editor__content:empty:not(:focus):before { + content: attr(placeholder); + opacity: 0.7 +} + +.q-editor__toolbar { + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + min-height : 32px +} + +.q-editor .q-btn { + margin: 4px +} + +.q-editor__toolbar-group { + position: relative; + margin : 0 4px +} + +.q-editor__toolbar-group+.q-editor__toolbar-group:before { + content : ""; + position : absolute; + left : -4px; + top : 4px; + bottom : 4px; + width : 1px; + background: rgba(0, 0, 0, 0.12) +} + +.q-editor__link-input { + color : inherit; + text-decoration: none; + text-transform : none; + border : none; + border-radius : 0; + background : none; + outline : 0 +} + +.q-editor--flat, +.q-editor--flat .q-editor__toolbar { + border: 0 +} + +.q-editor--dense .q-editor__toolbar-group { + display : flex; + align-items: center; + flex-wrap : nowrap +} + +.q-editor--dark { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-editor--dark .q-editor__content hr { + background: hsla(0, 0%, 100%, 0.28) +} + +.q-editor--dark .q-editor__toolbar { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-editor--dark .q-editor__toolbar-group+.q-editor__toolbar-group:before { + background: hsla(0, 0%, 100%, 0.28) +} + +.q-expansion-item__border { + opacity: 0 +} + +.q-expansion-item__toggle-icon { + position : relative; + transition: transform 0.3s +} + +.q-expansion-item__toggle-icon--rotated { + transform: rotate(180deg) +} + +.q-expansion-item__toggle-focus { + width : 1em !important; + height : 1em !important; + position: relative !important +} + +.q-expansion-item__toggle-focus+.q-expansion-item__toggle-icon { + margin-top: -1em +} + +.q-expansion-item--standard.q-expansion-item--expanded>div>.q-expansion-item__border { + opacity: 1 +} + +.q-expansion-item--popup { + transition: padding 0.5s +} + +.q-expansion-item--popup>.q-expansion-item__container { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-expansion-item--popup>.q-expansion-item__container>.q-separator { + display: none +} + +.q-expansion-item--popup.q-expansion-item--collapsed { + padding: 0 15px +} + +.q-expansion-item--popup.q-expansion-item--expanded { + padding: 15px 0 +} + +.q-expansion-item--popup.q-expansion-item--expanded+.q-expansion-item--popup.q-expansion-item--expanded { + padding-top: 0 +} + +.q-expansion-item--popup.q-expansion-item--collapsed:not(:first-child)>.q-expansion-item__container { + border-top-width: 0 +} + +.q-expansion-item--popup.q-expansion-item--expanded+.q-expansion-item--popup.q-expansion-item--collapsed>.q-expansion-item__container { + border-top-width: 1px +} + +.q-expansion-item__content>.q-card { + box-shadow : none; + border-radius: 0 +} + +.q-expansion-item--expanded+.q-expansion-item--expanded>div>.q-expansion-item__border--top, +.q-expansion-item:first-child>div>.q-expansion-item__border--top, +.q-expansion-item:last-child>div>.q-expansion-item__border--bottom { + opacity: 0 +} + +.q-expansion-item--expanded .q-textarea--autogrow textarea { + -webkit-animation: q-expansion-done 0s; + animation : q-expansion-done 0s +} + +.z-fab { + z-index: 990 +} + +.q-fab { + position : relative; + vertical-align: middle +} + +.q-fab>.q-btn { + width: 100% +} + +.q-fab--form-rounded { + border-radius: 28px +} + +.q-fab--form-square { + border-radius: 4px +} + +.q-fab__active-icon, +.q-fab__icon { + transition: opacity 0.4s, transform 0.4s +} + +.q-fab__icon { + opacity : 1; + transform: rotate(0deg) +} + +.q-fab__active-icon { + opacity : 0; + transform: rotate(-180deg) +} + +.q-fab__label--external { + position : absolute; + padding : 0 8px; + transition: opacity 0.18s cubic-bezier(0.65, 0.815, 0.735, 0.395) +} + +.q-fab__label--external-hidden { + opacity : 0; + pointer-events: none +} + +.q-fab__label--external-left { + top : 50%; + left : -12px; + transform: translate(-100%, -50%) +} + +.q-fab__label--external-right { + top : 50%; + right : -12px; + transform: translate(100%, -50%) +} + +.q-fab__label--external-bottom { + bottom : -12px; + left : 50%; + transform: translate(-50%, 100%) +} + +.q-fab__label--external-top { + top : -12px; + left : 50%; + transform: translate(-50%, -100%) +} + +.q-fab__label--internal { + padding : 0; + transition: font-size 0.12s cubic-bezier(0.65, 0.815, 0.735, 0.395), max-height 0.12s cubic-bezier(0.65, 0.815, 0.735, 0.395), opacity 0.07s cubic-bezier(0.65, 0.815, 0.735, 0.395); + max-height: 30px +} + +.q-fab__label--internal-hidden { + font-size: 0; + opacity : 0 +} + +.q-fab__label--internal-top { + padding-bottom: 0.12em +} + +.q-fab__label--internal-bottom { + padding-top: 0.12em +} + +.q-fab__label--internal-bottom.q-fab__label--internal-hidden, +.q-fab__label--internal-top.q-fab__label--internal-hidden { + max-height: 0 +} + +.q-fab__label--internal-left { + padding-left : 0.285em; + padding-right: 0.571em +} + +.q-fab__label--internal-right { + padding-right: 0.285em; + padding-left : 0.571em +} + +.q-fab__icon-holder { + min-width : 24px; + min-height: 24px; + position : relative +} + +.q-fab__icon-holder--opened .q-fab__icon { + transform: rotate(180deg); + opacity : 0 +} + +.q-fab__icon-holder--opened .q-fab__active-icon { + transform: rotate(0deg); + opacity : 1 +} + +.q-fab__actions { + position : absolute; + opacity : 0; + transition : transform 0.18s ease-in, opacity 0.18s ease-in; + pointer-events : none; + align-items : center; + justify-content: center; + align-self : center; + padding : 3px +} + +.q-fab__actions .q-btn { + margin: 5px +} + +.q-fab__actions--right { + transform-origin: 0 50%; + transform : scale(0.4) translateX(-62px); + height : 56px; + left : 100%; + margin-left : 9px +} + +.q-fab__actions--left { + transform-origin: 100% 50%; + transform : scale(0.4) translateX(62px); + height : 56px; + right : 100%; + margin-right : 9px; + flex-direction : row-reverse +} + +.q-fab__actions--up { + transform-origin: 50% 100%; + transform : scale(0.4) translateY(62px); + width : 56px; + bottom : 100%; + margin-bottom : 9px; + flex-direction : column-reverse +} + +.q-fab__actions--down { + transform-origin: 50% 0; + transform : scale(0.4) translateY(-62px); + width : 56px; + top : 100%; + margin-top : 9px; + flex-direction : column +} + +.q-fab__actions--down, +.q-fab__actions--up { + left : 50%; + margin-left: -28px +} + +.q-fab__actions--opened { + opacity : 1; + transform : scale(1) translate(0, 0); + pointer-events: all +} + +.q-fab--align-left>.q-fab__actions--down, +.q-fab--align-left>.q-fab__actions--up { + align-items: flex-start; + left : 28px +} + +.q-fab--align-right>.q-fab__actions--down, +.q-fab--align-right>.q-fab__actions--up { + align-items: flex-end; + left : auto; + right : 0 +} + +.q-field { + font-size: 14px +} + +.q-field ::-ms-clear, +.q-field ::-ms-reveal { + display: none +} + +.q-field--with-bottom { + padding-bottom: 20px +} + +.q-field__marginal { + height : 56px; + color : rgba(0, 0, 0, 0.54); + font-size: 24px +} + +.q-field__marginal>*+* { + margin-left: 2px +} + +.q-field__marginal .q-avatar { + font-size: 32px +} + +.q-field__before, +.q-field__prepend { + padding-right: 12px +} + +.q-field__after, +.q-field__append { + padding-left: 12px +} + +.q-field__after:empty, +.q-field__append:empty { + display: none +} + +.q-field__append+.q-field__append { + padding-left: 2px +} + +.q-field__inner { + text-align: left +} + +.q-field__bottom { + font-size : 12px; + min-height : 20px; + line-height : 1; + color : rgba(0, 0, 0, 0.54); + padding : 8px 12px 0; + -webkit-backface-visibility: hidden; + backface-visibility : hidden +} + +.q-field__bottom--animated { + transform: translateY(100%); + position : absolute; + left : 0; + right : 0; + bottom : 0 +} + +.q-field__messages { + line-height: 1 +} + +.q-field__messages>div { + word-break : break-word; + word-wrap : break-word; + overflow-wrap: break-word +} + +.q-field__messages>div+div { + margin-top: 4px +} + +.q-field__counter { + padding-left: 8px; + line-height : 1 +} + +.q-field--item-aligned { + padding: 8px 16px +} + +.q-field--item-aligned .q-field__before { + min-width: 56px +} + +.q-field__control-container { + height: inherit +} + +.q-field__control { + color : #1976d2; + color : var(--q-color-primary); + height : 56px; + max-width: 100%; + outline : none +} + +.q-field__control:after, +.q-field__control:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + pointer-events: none +} + +.q-field__control:before { + border-radius: inherit +} + +.q-field__shadow { + top : 8px; + opacity : 0; + overflow : hidden; + white-space: pre-wrap; + transition : opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field__shadow+.q-field__native::-moz-placeholder { + -moz-transition: opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1); + transition : opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field__shadow+.q-field__native:-ms-input-placeholder { + -ms-transition: opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1); + transition : opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field__shadow+.q-field__native::placeholder { + transition: opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field__shadow+.q-field__native:focus::-moz-placeholder { + opacity: 0 +} + +.q-field__shadow+.q-field__native:focus:-ms-input-placeholder { + opacity: 0 +} + +.q-field__shadow+.q-field__native:focus::placeholder { + opacity: 0 +} + +.q-field__input, +.q-field__native, +.q-field__prefix, +.q-field__suffix { + font-weight : 400; + line-height : 28px; + letter-spacing : 0.00937em; + text-decoration: inherit; + text-transform : inherit; + border : none; + border-radius : 0; + background : none; + color : rgba(0, 0, 0, 0.87); + outline : 0; + padding : 6px 0 +} + +.q-field__input, +.q-field__native { + width : 100%; + min-width : 0; + outline : 0 !important; + -webkit-user-select: auto; + -moz-user-select : auto; + -ms-user-select : auto; + user-select : auto +} + +.q-field__input:-webkit-autofill, +.q-field__native:-webkit-autofill { + -webkit-animation-name : q-autofill; + -webkit-animation-fill-mode: both +} + +.q-field__input:-webkit-autofill+.q-field__label, +.q-field__native:-webkit-autofill+.q-field__label { + transform: translateY(-40%) scale(0.75) +} + +.q-field__input[type=number]:invalid+.q-field__label, +.q-field__native[type=number]:invalid+.q-field__label { + transform: translateY(-40%) scale(0.75) +} + +.q-field__input:invalid, +.q-field__native:invalid { + box-shadow: none +} + +.q-field__native[type=file] { + line-height: 1em +} + +.q-field__input { + padding : 0; + height : 0; + min-height : 24px; + line-height: 24px +} + +.q-field__prefix, +.q-field__suffix { + transition : opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1); + white-space: nowrap +} + +.q-field__prefix { + padding-right: 4px +} + +.q-field__suffix { + padding-left: 4px +} + +.q-field--disabled .q-placeholder, +.q-field--readonly .q-placeholder { + opacity: 1 !important +} + +.q-field--readonly.q-field--labeled .q-field__input, +.q-field--readonly.q-field--labeled .q-field__native { + cursor: default +} + +.q-field--readonly.q-field--float .q-field__input, +.q-field--readonly.q-field--float .q-field__native { + cursor: text +} + +.q-field--disabled .q-field__inner { + cursor: not-allowed +} + +.q-field--disabled .q-field__control { + pointer-events: none +} + +.q-field--disabled .q-field__control>div { + opacity: 0.6 !important +} + +.q-field--disabled .q-field__control>div, +.q-field--disabled .q-field__control>div * { + outline: 0 !important +} + +.q-field__label { + left : 0; + right : 0; + top : 18px; + color : rgba(0, 0, 0, 0.6); + font-size : 16px; + line-height : 20px; + font-weight : 400; + letter-spacing : 0.00937em; + text-decoration : inherit; + text-transform : inherit; + transform-origin : left top; + transition : transform 0.36s cubic-bezier(0.4, 0, 0.2, 1), right 0.324s cubic-bezier(0.4, 0, 0.2, 1); + -webkit-backface-visibility: hidden; + backface-visibility : hidden +} + +.q-field--float .q-field__label { + transform : translateY(-40%) scale(0.75); + right : -33.33333%; + transition: transform 0.36s cubic-bezier(0.4, 0, 0.2, 1), right 0.396s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--highlighted .q-field__label { + color: currentColor +} + +.q-field--highlighted .q-field__shadow { + opacity: 0.5 +} + +.q-field--filled .q-field__control { + padding : 0 12px; + background : rgba(0, 0, 0, 0.05); + border-radius: 4px 4px 0 0 +} + +.q-field--filled .q-field__control:before { + background : rgba(0, 0, 0, 0.05); + border-bottom: 1px solid rgba(0, 0, 0, 0.42); + opacity : 0; + transition : opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1), background 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--filled .q-field__control:hover:before { + opacity: 1 +} + +.q-field--filled .q-field__control:after { + height : 2px; + top : auto; + transform-origin: center bottom; + transform : scale3d(0, 1, 1); + background : currentColor; + transition : transform 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--filled.q-field--rounded .q-field__control { + border-radius: 28px 28px 0 0 +} + +.q-field--filled.q-field--highlighted .q-field__control:before { + opacity : 1; + background: rgba(0, 0, 0, 0.12) +} + +.q-field--filled.q-field--highlighted .q-field__control:after { + transform: scale3d(1, 1, 1) +} + +.q-field--filled.q-field--dark .q-field__control, +.q-field--filled.q-field--dark .q-field__control:before { + background: hsla(0, 0%, 100%, 0.07) +} + +.q-field--filled.q-field--dark.q-field--highlighted .q-field__control:before { + background: hsla(0, 0%, 100%, 0.1) +} + +.q-field--filled.q-field--readonly .q-field__control:before { + opacity : 1; + background : transparent; + border-bottom-style: dashed +} + +.q-field--outlined .q-field__control { + border-radius: 4px; + padding : 0 12px +} + +.q-field--outlined .q-field__control:before { + border : 1px solid rgba(0, 0, 0, 0.24); + transition: border-color 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--outlined .q-field__control:hover:before { + border-color: #000 +} + +.q-field--outlined .q-field__control:after { + height : inherit; + border-radius: inherit; + border : 2px solid transparent; + transition : border-color 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--outlined .q-field__input:-webkit-autofill, +.q-field--outlined .q-field__native:-webkit-autofill { + margin-top : 1px; + margin-bottom: 1px +} + +.q-field--outlined.q-field--rounded .q-field__control { + border-radius: 28px +} + +.q-field--outlined.q-field--highlighted .q-field__control:hover:before { + border-color: transparent +} + +.q-field--outlined.q-field--highlighted .q-field__control:after { + border-color: currentColor; + border-width: 2px; + transform : scale3d(1, 1, 1) +} + +.q-field--outlined.q-field--readonly .q-field__control:before { + border-style: dashed +} + +.q-field--standard .q-field__control:before { + border-bottom: 1px solid rgba(0, 0, 0, 0.24); + transition : border-color 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--standard .q-field__control:hover:before { + border-color: #000 +} + +.q-field--standard .q-field__control:after { + height : 2px; + top : auto; + border-bottom-left-radius : inherit; + border-bottom-right-radius: inherit; + transform-origin : center bottom; + transform : scale3d(0, 1, 1); + background : currentColor; + transition : transform 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--standard.q-field--highlighted .q-field__control:after { + transform: scale3d(1, 1, 1) +} + +.q-field--standard.q-field--readonly .q-field__control:before { + border-bottom-style: dashed +} + +.q-field--dark .q-field__control:before { + border-color: hsla(0, 0%, 100%, 0.6) +} + +.q-field--dark .q-field__control:hover:before { + border-color: #fff +} + +.q-field--dark .q-field__input, +.q-field--dark .q-field__native, +.q-field--dark .q-field__prefix, +.q-field--dark .q-field__suffix { + color: #fff +} + +.q-field--dark .q-field__bottom, +.q-field--dark .q-field__marginal, +.q-field--dark:not(.q-field--highlighted) .q-field__label { + color: hsla(0, 0%, 100%, 0.7) +} + +.q-field--standout .q-field__control { + padding : 0 12px; + background : rgba(0, 0, 0, 0.05); + border-radius: 4px; + transition : box-shadow 0.36s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--standout .q-field__control:before { + background: rgba(0, 0, 0, 0.07); + opacity : 0; + transition: opacity 0.36s cubic-bezier(0.4, 0, 0.2, 1), background 0.36s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-field--standout .q-field__control:hover:before { + opacity: 1 +} + +.q-field--standout.q-field--rounded .q-field__control { + border-radius: 28px +} + +.q-field--standout.q-field--highlighted .q-field__control { + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + background: #000 +} + +.q-field--standout.q-field--highlighted .q-field__append, +.q-field--standout.q-field--highlighted .q-field__input, +.q-field--standout.q-field--highlighted .q-field__native, +.q-field--standout.q-field--highlighted .q-field__prefix, +.q-field--standout.q-field--highlighted .q-field__prepend, +.q-field--standout.q-field--highlighted .q-field__suffix { + color: #fff +} + +.q-field--standout.q-field--readonly .q-field__control:before { + opacity : 1; + background: transparent; + border : 1px dashed rgba(0, 0, 0, 0.24) +} + +.q-field--standout.q-field--dark .q-field__control, +.q-field--standout.q-field--dark .q-field__control:before { + background: hsla(0, 0%, 100%, 0.07) +} + +.q-field--standout.q-field--dark.q-field--highlighted .q-field__control { + background: #fff +} + +.q-field--standout.q-field--dark.q-field--highlighted .q-field__append, +.q-field--standout.q-field--dark.q-field--highlighted .q-field__input, +.q-field--standout.q-field--dark.q-field--highlighted .q-field__native, +.q-field--standout.q-field--dark.q-field--highlighted .q-field__prefix, +.q-field--standout.q-field--dark.q-field--highlighted .q-field__prepend, +.q-field--standout.q-field--dark.q-field--highlighted .q-field__suffix { + color: #000 +} + +.q-field--standout.q-field--dark.q-field--readonly .q-field__control:before { + border-color: hsla(0, 0%, 100%, 0.24) +} + +.q-field--labeled .q-field__native, +.q-field--labeled .q-field__prefix, +.q-field--labeled .q-field__suffix { + line-height : 24px; + padding-top : 24px; + padding-bottom: 8px +} + +.q-field--labeled .q-field__shadow { + top: 0 +} + +.q-field--labeled:not(.q-field--float) .q-field__prefix, +.q-field--labeled:not(.q-field--float) .q-field__suffix { + opacity: 0 +} + +.q-field--labeled:not(.q-field--float) .q-field__input:-ms-input-placeholder, +.q-field--labeled:not(.q-field--float) .q-field__native:-ms-input-placeholder { + color: transparent !important +} + +.q-field--labeled:not(.q-field--float) .q-field__input::-moz-placeholder, +.q-field--labeled:not(.q-field--float) .q-field__native::-moz-placeholder { + color: transparent +} + +.q-field--labeled:not(.q-field--float) .q-field__input:-ms-input-placeholder, +.q-field--labeled:not(.q-field--float) .q-field__native:-ms-input-placeholder { + color: transparent +} + +.q-field--labeled:not(.q-field--float) .q-field__input::placeholder, +.q-field--labeled:not(.q-field--float) .q-field__native::placeholder { + color: transparent +} + +.q-field--labeled.q-field--dense .q-field__native, +.q-field--labeled.q-field--dense .q-field__prefix, +.q-field--labeled.q-field--dense .q-field__suffix { + padding-top : 14px; + padding-bottom: 2px +} + +.q-field--dense .q-field__shadow { + top: 0 +} + +.q-field--dense .q-field__control, +.q-field--dense .q-field__marginal { + height: 40px +} + +.q-field--dense .q-field__bottom { + font-size: 11px +} + +.q-field--dense .q-field__label { + font-size: 14px; + top : 10px +} + +.q-field--dense .q-field__before, +.q-field--dense .q-field__prepend { + padding-right: 6px +} + +.q-field--dense .q-field__after, +.q-field--dense .q-field__append { + padding-left: 6px +} + +.q-field--dense .q-field__append+.q-field__append { + padding-left: 2px +} + +.q-field--dense .q-field__marginal .q-avatar { + font-size: 24px +} + +.q-field--dense.q-field--float .q-field__label { + transform: translateY(-30%) scale(0.75) +} + +.q-field--dense .q-field__input:-webkit-autofill+.q-field__label, +.q-field--dense .q-field__native:-webkit-autofill+.q-field__label { + transform: translateY(-30%) scale(0.75) +} + +.q-field--dense .q-field__input[type=number]:invalid+.q-field__label, +.q-field--dense .q-field__native[type=number]:invalid+.q-field__label { + transform: translateY(-30%) scale(0.75) +} + +.q-field--borderless.q-field--dense .q-field__control, +.q-field--borderless .q-field__bottom, +.q-field--standard.q-field--dense .q-field__control, +.q-field--standard .q-field__bottom { + padding-left : 0; + padding-right: 0 +} + +.q-field--error .q-field__label { + -webkit-animation: q-field-label 0.36s; + animation : q-field-label 0.36s +} + +.q-field--error .q-field__bottom { + color: #c10015; + color: var(--q-color-negative) +} + +.q-field__focusable-action { + opacity : 0.6; + cursor : pointer; + outline : 0 !important; + border : 0; + color : inherit; + background: transparent; + padding : 0 +} + +.q-field__focusable-action:focus, +.q-field__focusable-action:hover { + opacity: 1 +} + +.q-field--auto-height .q-field__control { + height: auto +} + +.q-field--auto-height .q-field__control, +.q-field--auto-height .q-field__native { + min-height: 56px +} + +.q-field--auto-height .q-field__native { + align-items: center +} + +.q-field--auto-height .q-field__control-container { + padding-top: 0 +} + +.q-field--auto-height .q-field__native, +.q-field--auto-height .q-field__prefix, +.q-field--auto-height .q-field__suffix { + line-height: 18px +} + +.q-field--auto-height.q-field--labeled .q-field__control-container { + padding-top: 24px +} + +.q-field--auto-height.q-field--labeled .q-field__shadow { + top: 24px +} + +.q-field--auto-height.q-field--labeled .q-field__native, +.q-field--auto-height.q-field--labeled .q-field__prefix, +.q-field--auto-height.q-field--labeled .q-field__suffix { + padding-top: 0 +} + +.q-field--auto-height.q-field--labeled .q-field__native { + min-height: 24px +} + +.q-field--auto-height.q-field--dense .q-field__control, +.q-field--auto-height.q-field--dense .q-field__native { + min-height: 40px +} + +.q-field--auto-height.q-field--dense.q-field--labeled .q-field__control-container { + padding-top: 14px +} + +.q-field--auto-height.q-field--dense.q-field--labeled .q-field__shadow { + top: 14px +} + +.q-field--auto-height.q-field--dense.q-field--labeled .q-field__native { + min-height: 24px +} + +.q-field--square .q-field__control { + border-radius: 0 !important +} + +.q-transition--field-message-enter-active, +.q-transition--field-message-leave-active { + transition: transform 0.6s cubic-bezier(0.86, 0, 0.07, 1), opacity 0.6s cubic-bezier(0.86, 0, 0.07, 1) +} + +.q-transition--field-message-enter, +.q-transition--field-message-leave-to { + opacity : 0; + transform: translateY(-10px) +} + +.q-transition--field-message-leave, +.q-transition--field-message-leave-active { + position: absolute +} + +.q-file .q-field__native { + word-break: break-all +} + +.q-file .q-field__input { + opacity: 0 !important +} + +.q-file .q-field__input::-webkit-file-upload-button { + cursor: pointer +} + +.q-file__filler { + visibility: hidden; + width : 100%; + border : none; + padding : 0 +} + +.q-file__dnd { + outline : 1px dashed currentColor; + outline-offset: -4px +} + +.q-form, +.q-img { + position: relative +} + +.q-img { + width : 100%; + display : inline-block; + vertical-align: middle +} + +.q-img__loading .q-spinner { + font-size: 50px +} + +.q-img__image { + border-radius : inherit; + background-repeat: no-repeat +} + +.q-img__content { + overflow : hidden; + border-radius: inherit +} + +.q-img__content>div { + position : absolute; + padding : 16px; + color : #fff; + background: rgba(0, 0, 0, 0.47) +} + +.q-img--menu .q-img__image { + pointer-events: none +} + +.q-img--menu .q-img__image>img { + pointer-events: all; + opacity : 0 +} + +.q-img--menu .q-img__content { + pointer-events: none +} + +.q-img--menu .q-img__content>div { + pointer-events: all +} + +.q-inner-loading { + background: hsla(0, 0%, 100%, 0.6) +} + +.q-inner-loading--dark { + background: rgba(0, 0, 0, 0.4) +} + +.q-inner-loading__label { + margin-top: 8px +} + +.q-textarea .q-field__control { + min-height: 56px; + height : auto +} + +.q-textarea .q-field__control-container { + padding-top : 2px; + padding-bottom: 2px +} + +.q-textarea .q-field__shadow { + top : 2px; + bottom: 2px +} + +.q-textarea .q-field__native, +.q-textarea .q-field__prefix, +.q-textarea .q-field__suffix { + line-height: 18px +} + +.q-textarea .q-field__native { + resize : vertical; + padding-top: 17px; + min-height : 52px +} + +.q-textarea.q-field--labeled .q-field__control-container { + padding-top: 26px +} + +.q-textarea.q-field--labeled .q-field__shadow { + top: 26px +} + +.q-textarea.q-field--labeled .q-field__native, +.q-textarea.q-field--labeled .q-field__prefix, +.q-textarea.q-field--labeled .q-field__suffix { + padding-top: 0 +} + +.q-textarea.q-field--labeled .q-field__native { + min-height : 26px; + padding-top: 1px +} + +.q-textarea--autogrow .q-field__native { + resize: none +} + +.q-textarea.q-field--dense .q-field__control, +.q-textarea.q-field--dense .q-field__native { + min-height: 36px +} + +.q-textarea.q-field--dense .q-field__native { + padding-top: 9px +} + +.q-textarea.q-field--dense.q-field--labeled .q-field__control-container { + padding-top: 14px +} + +.q-textarea.q-field--dense.q-field--labeled .q-field__shadow { + top: 14px +} + +.q-textarea.q-field--dense.q-field--labeled .q-field__native { + min-height : 24px; + padding-top: 3px +} + +.q-textarea.q-field--dense.q-field--labeled .q-field__prefix, +.q-textarea.q-field--dense.q-field--labeled .q-field__suffix { + padding-top: 2px +} + +.q-textarea.disabled .q-field__native, +body.mobile .q-textarea .q-field__native { + resize: none +} + +.q-intersection { + position: relative +} + +.q-item { + min-height: 48px; + padding : 8px 16px; + color : inherit; + transition: color 0.3s, background-color 0.3s +} + +.q-item__section--side { + color : #757575; + align-items : flex-start; + padding-right: 16px; + width : auto; + min-width : 0; + max-width : 100% +} + +.q-item__section--side>.q-icon { + font-size: 24px +} + +.q-item__section--side>.q-avatar { + font-size: 40px +} + +.q-item__section--avatar { + color : inherit; + min-width: 56px +} + +.q-item__section--thumbnail img { + width : 100px; + height: 56px +} + +.q-item__section--nowrap { + white-space: nowrap +} + +.q-item>.q-focus-helper+.q-item__section--thumbnail, +.q-item>.q-item__section--thumbnail:first-child { + margin-left: -16px +} + +.q-item>.q-item__section--thumbnail:last-of-type { + margin-right: -16px +} + +.q-item__label { + line-height: 1.2em !important; + max-width : 100% +} + +.q-item__label--overline { + color: rgba(0, 0, 0, 0.7) +} + +.q-item__label--caption { + color: rgba(0, 0, 0, 0.54) +} + +.q-item__label--header { + color : #757575; + padding : 16px; + font-size : 0.875rem; + line-height : 1.25rem; + letter-spacing: 0.01786em +} + +.q-list--padding .q-item__label--header, +.q-separator--spaced+.q-item__label--header { + padding-top: 8px +} + +.q-item__label+.q-item__label { + margin-top: 4px +} + +.q-item__section--main { + width : auto; + min-width: 0; + max-width: 100%; + flex : 10000 1 0% +} + +.q-item__section--main+.q-item__section--main { + margin-left: 8px +} + +.q-item__section--main~.q-item__section--side { + align-items : flex-end; + padding-right: 0; + padding-left : 16px +} + +.q-item__section--main.q-item__section--thumbnail { + margin-left : 0; + margin-right: -16px +} + +.q-list--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-list--separator>.q-item-type+.q-item-type, +.q-list--separator>.q-virtual-scroll__content>.q-item-type+.q-item-type { + border-top: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-list--padding { + padding: 8px 0 +} + +.q-item--dense, +.q-list--dense>.q-item { + min-height: 32px; + padding : 2px 16px +} + +.q-list--dark.q-list--separator>.q-item-type+.q-item-type, +.q-list--dark.q-list--separator>.q-virtual-scroll__content>.q-item-type+.q-item-type { + border-top-color: hsla(0, 0%, 100%, 0.28) +} + +.q-item--dark, +.q-list--dark { + color : #fff; + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-item--dark .q-item__section--side:not(.q-item__section--avatar), +.q-list--dark .q-item__section--side:not(.q-item__section--avatar) { + color: hsla(0, 0%, 100%, 0.7) +} + +.q-item--dark .q-item__label--header, +.q-list--dark .q-item__label--header { + color: hsla(0, 0%, 100%, 0.64) +} + +.q-item--dark .q-item__label--caption, +.q-item--dark .q-item__label--overline, +.q-list--dark .q-item__label--caption, +.q-list--dark .q-item__label--overline { + color: hsla(0, 0%, 100%, 0.8) +} + +.q-item { + position: relative +} + +.q-item--active, +.q-item.q-router-link--active { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-knob { + font-size: 48px +} + +.q-knob--editable { + cursor : pointer; + outline: 0 +} + +.q-knob--editable:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + border-radius: 50%; + box-shadow : none; + transition : box-shadow 0.24s ease-in-out +} + +.q-knob--editable:focus:before { + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px rgba(0, 0, 0, 0.14), 0 1px 10px rgba(0, 0, 0, 0.12) +} + +.q-layout { + width: 100% +} + +.q-layout-container { + position: relative; + width : 100%; + height : 100% +} + +.q-layout-container .q-layout { + min-height: 100% +} + +.q-layout-container>div { + transform: translate3d(0, 0, 0) +} + +.q-layout-container>div>div { + min-height: 0; + max-height: 100% +} + +.q-layout__shadow { + width: 100% +} + +.q-layout__shadow:after { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0px 10px rgba(0, 0, 0, 0.24) +} + +.q-layout__section--marginal { + background-color: #1976d2; + background-color: var(--q-color-primary); + color : #fff +} + +.q-header--hidden { + transform: translateY(-110%) +} + +.q-header--bordered { + border-bottom: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-header .q-layout__shadow { + bottom: -10px +} + +.q-header .q-layout__shadow:after { + bottom: 10px +} + +.q-footer--hidden { + transform: translateY(110%) +} + +.q-footer--bordered { + border-top: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-footer .q-layout__shadow { + top: -10px +} + +.q-footer .q-layout__shadow:after { + top: 10px +} + +.q-footer, +.q-header { + z-index: 2000 +} + +.q-drawer { + position : absolute; + top : 0; + bottom : 0; + background: #fff; + z-index : 1000 +} + +.q-drawer--on-top { + z-index: 3000 +} + +.q-drawer--left { + left : 0; + transform: translateX(-100%) +} + +.q-drawer--left.q-drawer--bordered { + border-right: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-drawer--left .q-layout__shadow { + left : 10px; + right: -10px +} + +.q-drawer--left .q-layout__shadow:after { + right: 10px +} + +.q-drawer--right { + right : 0; + transform: translateX(100%) +} + +.q-drawer--right.q-drawer--bordered { + border-left: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-drawer--right .q-layout__shadow { + left: -10px +} + +.q-drawer--right .q-layout__shadow:after { + left: 10px +} + +.q-drawer-container:not(.q-drawer--mini-animate) .q-drawer--mini { + padding: 0 !important +} + +.q-drawer-container:not(.q-drawer--mini-animate) .q-drawer--mini .q-item, +.q-drawer-container:not(.q-drawer--mini-animate) .q-drawer--mini .q-item__section { + text-align : center; + justify-content: center; + padding-left : 0; + padding-right : 0; + min-width : 0 +} + +.q-drawer--mini .q-expansion-item__content, +.q-drawer--mini .q-mini-drawer-hide, +.q-drawer-container:not(.q-drawer--mini-animate) .q-drawer--mini .q-item__label, +.q-drawer-container:not(.q-drawer--mini-animate) .q-drawer--mini .q-item__section--main, +.q-drawer-container:not(.q-drawer--mini-animate) .q-drawer--mini .q-item__section--side~.q-item__section--side { + display: none +} + +.q-drawer--mini-animate .q-drawer__content { + overflow-x : hidden; + white-space: nowrap +} + +.q-drawer--mobile .q-mini-drawer-hide, +.q-drawer--mobile .q-mini-drawer-only, +.q-drawer--standard .q-mini-drawer-only { + display: none +} + +.q-drawer__backdrop { + z-index : 2999 !important; + will-change: background-color +} + +.q-drawer__opener { + z-index : 2001; + height : 100%; + width : 15px; + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none +} + +.q-footer, +.q-header, +.q-layout, +.q-page { + position: relative +} + +.q-page-sticky--shrink { + pointer-events: none +} + +.q-page-sticky--shrink>div { + display : inline-block; + pointer-events: auto +} + +body.q-ios-padding .q-layout--standard .q-drawer--top-padding .q-drawer__content, +body.q-ios-padding .q-layout--standard .q-header>.q-tabs:first-child .q-tabs-head, +body.q-ios-padding .q-layout--standard .q-header>.q-toolbar:first-child { + padding-top: 20px; + min-height : 70px; + padding-top: env(safe-area-inset-top); + min-height : calc(env(safe-area-inset-top) + 50px) +} + +body.q-ios-padding .q-layout--standard .q-drawer--top-padding .q-drawer__content, +body.q-ios-padding .q-layout--standard .q-footer>.q-tabs:last-child .q-tabs-head, +body.q-ios-padding .q-layout--standard .q-footer>.q-toolbar:last-child { + padding-bottom: env(safe-area-inset-bottom); + min-height : calc(env(safe-area-inset-bottom) + 50px) +} + +.q-body--layout-animate .q-drawer__backdrop { + transition: background-color 0.12s !important +} + +.q-body--layout-animate .q-drawer { + transition: transform 0.12s, width 0.12s, top 0.12s, bottom 0.12s !important +} + +.q-body--layout-animate .q-layout__section--marginal { + transition: transform 0.12s, left 0.12s, right 0.12s !important +} + +.q-body--layout-animate .q-page-container { + transition: padding-top 0.12s, padding-right 0.12s, padding-bottom 0.12s, padding-left 0.12s !important +} + +.q-body--layout-animate .q-page-sticky { + transition: transform 0.12s, left 0.12s, right 0.12s, top 0.12s, bottom 0.12s !important +} + +body:not(.q-body--layout-animate) .q-layout--prevent-focus { + visibility: hidden +} + +.q-body--drawer-toggle { + overflow-x: hidden !important +} + +@media (max-width:599.98px) { + .q-layout-padding { + padding: 8px + } +} + +@media (min-width:600px) and (max-width:1439.98px) { + .q-layout-padding { + padding: 16px + } +} + +@media (min-width:1440px) { + .q-layout-padding { + padding: 24px + } +} + +body.body--dark .q-drawer, +body.body--dark .q-footer, +body.body--dark .q-header { + border-color: hsla(0, 0%, 100%, 0.28) +} + +body.platform-ios .q-layout--containerized { + position: unset !important +} + +.q-linear-progress { + position : relative; + width : 100%; + overflow : hidden; + font-size: 4px; + height : 1em; + color : #1976d2; + color : var(--q-color-primary); + transform: scale3d(1, 1, 1) +} + +.q-linear-progress__model, +.q-linear-progress__track { + transform-origin: 0 0 +} + +.q-linear-progress__model--with-transition, +.q-linear-progress__track--with-transition { + transition: transform 0.3s +} + +.q-linear-progress--reverse .q-linear-progress__model, +.q-linear-progress--reverse .q-linear-progress__track { + transform-origin: 0 100% +} + +.q-linear-progress__model--determinate { + background: currentColor +} + +.q-linear-progress__model--indeterminate, +.q-linear-progress__model--query { + transition: none +} + +.q-linear-progress__model--indeterminate:after, +.q-linear-progress__model--indeterminate:before, +.q-linear-progress__model--query:after, +.q-linear-progress__model--query:before { + background : currentColor; + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + transform-origin: 0 0 +} + +.q-linear-progress__model--indeterminate:before, +.q-linear-progress__model--query:before { + -webkit-animation: q-linear-progress--indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; + animation : q-linear-progress--indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite +} + +.q-linear-progress__model--indeterminate:after, +.q-linear-progress__model--query:after { + transform : translate3d(-101%, 0, 0) scale3d(1, 1, 1); + -webkit-animation : q-linear-progress--indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; + animation : q-linear-progress--indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; + -webkit-animation-delay: 1.15s; + animation-delay : 1.15s +} + +.q-linear-progress__track { + opacity: 0.4 +} + +.q-linear-progress__track--light { + background: rgba(0, 0, 0, 0.26) +} + +.q-linear-progress__track--dark { + background: hsla(0, 0%, 100%, 0.6) +} + +.q-linear-progress__stripe { + transition : width 0.3s; + background-image: linear-gradient(45deg, hsla(0, 0%, 100%, 0.15) 25%, hsla(0, 0%, 100%, 0) 0, hsla(0, 0%, 100%, 0) 50%, hsla(0, 0%, 100%, 0.15) 0, hsla(0, 0%, 100%, 0.15) 75%, hsla(0, 0%, 100%, 0) 0, hsla(0, 0%, 100%, 0)) !important; + background-size : 40px 40px !important +} + +.q-menu { + position : fixed !important; + display : inline-block; + max-width : 95vw; + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + background : #fff; + border-radius: 4px; + overflow-y : auto; + overflow-x : hidden; + outline : 0; + max-height : 65vh; + z-index : 6000 +} + +.q-menu--square { + border-radius: 0 +} + +.q-option-group--inline>div { + display: inline-block +} + +.q-pagination input { + text-align : center; + -moz-appearance: textfield +} + +.q-pagination input::-webkit-inner-spin-button, +.q-pagination input::-webkit-outer-spin-button { + -webkit-appearance: none; + margin : 0 +} + +.q-parallax { + position : relative; + width : 100%; + overflow : hidden; + border-radius: inherit +} + +.q-parallax__media>img, +.q-parallax__media>video { + position : absolute; + left : 50%; + bottom : 0; + min-width : 100%; + min-height : 100%; + will-change: transform; + display : none +} + +.q-popup-edit { + padding: 8px 16px +} + +.q-popup-edit__buttons { + margin-top: 8px +} + +.q-popup-edit__buttons .q-btn+.q-btn { + margin-left: 8px +} + +.q-pull-to-refresh { + position: relative +} + +.q-pull-to-refresh__puller { + border-radius: 50%; + width : 40px; + height : 40px; + color : #1976d2; + color : var(--q-color-primary); + background : #fff; + box-shadow : 0 0 4px 0 rgba(0, 0, 0, 0.3) +} + +.q-pull-to-refresh__puller--animating { + transition: transform 0.3s, opacity 0.3s +} + +.q-radio { + vertical-align: middle +} + +.q-radio__native { + width : 1px; + height: 1px +} + +.q-radio__bg, +.q-radio__icon-container { + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none +} + +.q-radio__bg { + top : 25%; + left : 25%; + width : 50%; + height : 50%; + -webkit-print-color-adjust: exact +} + +.q-radio__bg path { + fill: currentColor +} + +.q-radio__icon { + color : currentColor; + font-size: 0.5em +} + +.q-radio__check { + transform-origin: 50% 50%; + transform : scale3d(0, 0, 1); + transition : transform 0.22s cubic-bezier(0, 0, 0.2, 1) 0ms +} + +.q-radio__inner { + font-size : 40px; + width : 1em; + min-width : 1em; + height : 1em; + outline : 0; + border-radius: 50%; + color : rgba(0, 0, 0, 0.54) +} + +.q-radio__inner--truthy { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-radio__inner--truthy .q-radio__check { + transform: scale3d(1, 1, 1) +} + +.q-radio.disabled { + opacity: 0.75 !important +} + +.q-radio--dark .q-radio__inner { + color: hsla(0, 0%, 100%, 0.7) +} + +.q-radio--dark .q-radio__inner:before { + opacity: 0.32 !important +} + +.q-radio--dark .q-radio__inner--truthy { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-radio--dense .q-radio__inner { + width : 0.5em; + min-width: 0.5em; + height : 0.5em +} + +.q-radio--dense .q-radio__bg { + left : 0; + top : 0; + width : 100%; + height: 100% +} + +.q-radio--dense .q-radio__label { + padding-left: 0.5em +} + +.q-radio--dense.reverse .q-radio__label { + padding-left : 0; + padding-right: 0.5em +} + +body.desktop .q-radio:not(.disabled) .q-radio__inner:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + border-radius: 50%; + background : currentColor; + opacity : 0.12; + transform : scale3d(0, 0, 1); + transition : transform 0.22s cubic-bezier(0, 0, 0.2, 1) 0ms +} + +body.desktop .q-radio:not(.disabled):focus .q-radio__inner:before, +body.desktop .q-radio:not(.disabled):hover .q-radio__inner:before { + transform: scale3d(1, 1, 1) +} + +body.desktop .q-radio--dense:not(.disabled):focus .q-radio__inner:before, +body.desktop .q-radio--dense:not(.disabled):hover .q-radio__inner:before { + transform: scale3d(1.5, 1.5, 1) +} + +.q-rating { + color : #ffeb3b; + vertical-align: middle +} + +.q-rating__icon-container { + height : 1em; + outline: 0 +} + +.q-rating__icon-container+.q-rating__icon-container { + margin-left: 2px +} + +.q-rating__icon { + color : currentColor; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + position : relative; + opacity : 0.4; + transition : transform 0.2s ease-in, opacity 0.2s ease-in +} + +.q-rating__icon--hovered { + transform: scale(1.3) +} + +.q-rating__icon--active { + opacity: 1 +} + +.q-rating__icon--exselected { + opacity: 0.7 +} + +.q-rating--no-dimming .q-rating__icon { + opacity: 1 +} + +.q-rating--editable .q-rating__icon-container { + cursor: pointer +} + +.q-responsive { + position : relative; + max-width : 100%; + max-height: 100% +} + +.q-responsive__filler { + width : inherit; + max-width : inherit; + height : inherit; + max-height: inherit +} + +.q-responsive__content { + border-radius: inherit +} + +.q-responsive__content>* { + width : 100% !important; + height : 100% !important; + max-height: 100% !important; + max-width : 100% !important +} + +.q-scrollarea { + position: relative; + contain : strict +} + +.q-scrollarea__bar, +.q-scrollarea__thumb { + opacity : 0.2; + transition : opacity 0.3s; + will-change: opacity; + cursor : -webkit-grab; + cursor : grab +} + +.q-scrollarea__bar--v, +.q-scrollarea__thumb--v { + right: 0; + width: 10px +} + +.q-scrollarea__bar--h, +.q-scrollarea__thumb--h { + bottom: 0; + height: 10px +} + +.q-scrollarea__bar--invisible, +.q-scrollarea__thumb--invisible { + opacity : 0 !important; + pointer-events: none +} + +.q-scrollarea__thumb { + background: #000 +} + +.q-scrollarea__thumb:hover { + opacity: 0.3 +} + +.q-scrollarea__thumb:active { + opacity: 0.5 +} + +.q-scrollarea__content { + min-height: 100%; + min-width : 100% +} + +.q-scrollarea--dark .q-scrollarea__thumb { + background: #fff +} + +.q-select--without-input .q-field__control { + cursor: pointer +} + +.q-select--with-input .q-field__control { + cursor: text +} + +.q-select .q-field__input { + min-width: 50px !important; + cursor : text +} + +.q-select .q-field__input--padding { + padding-left: 4px +} + +.q-select__autocomplete-input, +.q-select__focus-target { + position: absolute; + outline : 0 !important; + width : 0; + height : 0; + padding : 0; + border : 0; + opacity : 0 +} + +.q-select__dropdown-icon { + cursor : pointer; + transition: transform 0.28s +} + +.q-select.q-field--readonly .q-field__control, +.q-select.q-field--readonly .q-select__dropdown-icon { + cursor: default +} + +.q-select__dialog { + width : 90vw !important; + max-width : 90vw !important; + max-height : calc(100vh - 70px) !important; + background : #fff; + display : flex; + flex-direction: column +} + +.q-select__dialog>.scroll { + position : relative; + background: inherit +} + +body.mobile:not(.native-mobile) .q-select__dialog { + max-height: calc(100vh - 108px) !important +} + +body.platform-android.native-mobile .q-dialog__inner--top .q-select__dialog { + max-height: calc(100vh - 24px) !important +} + +body.platform-android:not(.native-mobile) .q-dialog__inner--top .q-select__dialog { + max-height: calc(100vh - 80px) !important +} + +body.platform-ios.native-mobile .q-dialog__inner--top>div { + border-radius: 4px +} + +body.platform-ios.native-mobile .q-dialog__inner--top .q-select__dialog--focused { + max-height: 47vh !important +} + +body.platform-ios:not(.native-mobile) .q-dialog__inner--top .q-select__dialog--focused { + max-height: 50vh !important +} + +.q-separator { + border : 0; + background : rgba(0, 0, 0, 0.12); + margin : 0; + transition : background 0.3s, opacity 0.3s; + flex-shrink: 0 +} + +.q-separator--dark { + background: hsla(0, 0%, 100%, 0.28) +} + +.q-separator--horizontal { + display: block; + height : 1px +} + +.q-separator--horizontal-inset { + margin-left : 16px; + margin-right: 16px +} + +.q-separator--horizontal-item-inset { + margin-left : 72px; + margin-right: 0 +} + +.q-separator--horizontal-item-thumbnail-inset { + margin-left : 116px; + margin-right: 0 +} + +.q-separator--vertical { + width : 1px; + height : auto; + align-self: stretch +} + +.q-separator--vertical-inset { + margin-top : 8px; + margin-bottom: 8px +} + +.q-skeleton { + background : rgba(0, 0, 0, 0.12); + border-radius: 4px; + box-sizing : border-box +} + +.q-skeleton--anim { + cursor: wait +} + +.q-skeleton:before { + content: "\00a0" +} + +.q-skeleton--type-text { + transform: scale(1, 0.5) +} + +.q-skeleton--type-circle, +.q-skeleton--type-QAvatar { + height : 48px; + width : 48px; + border-radius: 50% +} + +.q-skeleton--type-QBtn { + width : 90px; + height: 36px +} + +.q-skeleton--type-QBadge { + width : 70px; + height: 16px +} + +.q-skeleton--type-QChip { + width : 90px; + height : 28px; + border-radius: 16px +} + +.q-skeleton--type-QToolbar { + height: 50px +} + +.q-skeleton--type-QCheckbox, +.q-skeleton--type-QRadio { + width : 40px; + height : 40px; + border-radius: 50% +} + +.q-skeleton--type-QToggle { + width : 56px; + height : 40px; + border-radius: 7px +} + +.q-skeleton--type-QRange, +.q-skeleton--type-QSlider { + height: 40px +} + +.q-skeleton--type-QInput { + height: 56px +} + +.q-skeleton--bordered { + border: 1px solid rgba(0, 0, 0, 0.05) +} + +.q-skeleton--square { + border-radius: 0 +} + +.q-skeleton--anim-fade { + -webkit-animation: q-skeleton--fade 1.5s linear 0.5s infinite; + animation : q-skeleton--fade 1.5s linear 0.5s infinite +} + +.q-skeleton--anim-pulse { + -webkit-animation: q-skeleton--pulse 1.5s ease-in-out 0.5s infinite; + animation : q-skeleton--pulse 1.5s ease-in-out 0.5s infinite +} + +.q-skeleton--anim-pulse-x { + -webkit-animation: q-skeleton--pulse-x 1.5s ease-in-out 0.5s infinite; + animation : q-skeleton--pulse-x 1.5s ease-in-out 0.5s infinite +} + +.q-skeleton--anim-pulse-y { + -webkit-animation: q-skeleton--pulse-y 1.5s ease-in-out 0.5s infinite; + animation : q-skeleton--pulse-y 1.5s ease-in-out 0.5s infinite +} + +.q-skeleton--anim-blink, +.q-skeleton--anim-pop, +.q-skeleton--anim-wave { + position: relative; + overflow: hidden; + z-index : 1 +} + +.q-skeleton--anim-blink:after, +.q-skeleton--anim-pop:after, +.q-skeleton--anim-wave:after { + content : ""; + position: absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + z-index : 0 +} + +.q-skeleton--anim-blink:after { + background : hsla(0, 0%, 100%, 0.7); + -webkit-animation: q-skeleton--fade 1.5s linear 0.5s infinite; + animation : q-skeleton--fade 1.5s linear 0.5s infinite +} + +.q-skeleton--anim-wave:after { + background : linear-gradient(90deg, hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, 0.5), hsla(0, 0%, 100%, 0)); + -webkit-animation: q-skeleton--wave 1.5s linear 0.5s infinite; + animation : q-skeleton--wave 1.5s linear 0.5s infinite +} + +.q-skeleton--dark { + background: hsla(0, 0%, 100%, 0.05) +} + +.q-skeleton--dark.q-skeleton--bordered { + border: 1px solid hsla(0, 0%, 100%, 0.25) +} + +.q-skeleton--dark.q-skeleton--anim-wave:after { + background: linear-gradient(90deg, hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, 0.1), hsla(0, 0%, 100%, 0)) +} + +.q-skeleton--dark.q-skeleton--anim-blink:after { + background: hsla(0, 0%, 100%, 0.2) +} + +.q-slide-item { + position : relative; + background: #fff +} + +.q-slide-item__bottom, +.q-slide-item__left, +.q-slide-item__right, +.q-slide-item__top { + visibility: hidden; + font-size : 14px; + color : #fff +} + +.q-slide-item__bottom .q-icon, +.q-slide-item__left .q-icon, +.q-slide-item__right .q-icon, +.q-slide-item__top .q-icon { + font-size: 1.714em +} + +.q-slide-item__left { + background: #4caf50; + padding : 8px 16px +} + +.q-slide-item__left>div { + transform-origin: left center +} + +.q-slide-item__right { + background: #ff9800; + padding : 8px 16px +} + +.q-slide-item__right>div { + transform-origin: right center +} + +.q-slide-item__top { + background: #2196f3; + padding : 16px 8px +} + +.q-slide-item__top>div { + transform-origin: top center +} + +.q-slide-item__bottom { + background: #9c27b0; + padding : 16px 8px +} + +.q-slide-item__bottom>div { + transform-origin: bottom center +} + +.q-slide-item__content { + background : inherit; + transition : transform 0.2s ease-in; + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + cursor : pointer +} + +.q-slider { + position: relative +} + +.q-slider--h { + width: 100% +} + +.q-slider--v { + height: 200px +} + +.q-slider--editable .q-slider__track-container { + cursor: -webkit-grab; + cursor: grab +} + +.q-slider__track-container { + outline: 0 +} + +.q-slider__track-container--h { + width : 100%; + padding: 12px 0 +} + +.q-slider__track-container--h .q-slider__selection { + will-change: width, left +} + +.q-slider__track-container--v { + height : 100%; + padding: 0 12px +} + +.q-slider__track-container--v .q-slider__selection { + will-change: height, top +} + +.q-slider__track { + color : #1976d2; + color : var(--q-color-primary); + background : rgba(0, 0, 0, 0.1); + border-radius: 4px; + width : inherit; + height : inherit +} + +.q-slider__inner { + background: rgba(0, 0, 0, 0.1) +} + +.q-slider__inner, +.q-slider__selection { + border-radius: inherit; + width : 100%; + height : 100% +} + +.q-slider__selection { + background: currentColor +} + +.q-slider__markers { + color : rgba(0, 0, 0, 0.3); + border-radius: inherit; + width : 100%; + height : 100% +} + +.q-slider__markers:after { + content : ""; + position : absolute; + background: currentColor +} + +.q-slider__markers--h { + background-image: repeating-linear-gradient(90deg, currentColor, currentColor 2px, hsla(0, 0%, 100%, 0) 0, hsla(0, 0%, 100%, 0)) +} + +.q-slider__markers--h:after { + height: 100%; + width : 2px; + top : 0; + right : 0 +} + +.q-slider__markers--v { + background-image: repeating-linear-gradient(180deg, currentColor, currentColor 2px, hsla(0, 0%, 100%, 0) 0, hsla(0, 0%, 100%, 0)) +} + +.q-slider__markers--v:after { + width : 100%; + height: 2px; + left : 0; + bottom: 0 +} + +.q-slider__marker-labels-container { + position : relative; + width : 100%; + height : 100%; + min-height: 24px; + min-width : 24px +} + +.q-slider__marker-labels { + position: absolute +} + +.q-slider__marker-labels--h-standard { + top: 0 +} + +.q-slider__marker-labels--h-switched { + bottom: 0 +} + +.q-slider__marker-labels--h-ltr { + transform: translateX(-50%) +} + +.q-slider__marker-labels--h-rtl { + transform: translateX(50%) +} + +.q-slider__marker-labels--v-standard { + left: 4px +} + +.q-slider__marker-labels--v-switched { + right: 4px +} + +.q-slider__marker-labels--v-ltr { + transform: translateY(-50%) +} + +.q-slider__marker-labels--v-rtl { + transform: translateY(50%) +} + +.q-slider__thumb { + z-index : 1; + outline : 0; + color : #1976d2; + color : var(--q-color-primary); + transition: transform 0.18s ease-out, fill 0.18s ease-out, stroke 0.18s ease-out +} + +.q-slider__thumb.q-slider--focus { + opacity: 1 !important +} + +.q-slider__thumb--h { + top : 50%; + will-change: left +} + +.q-slider__thumb--h-ltr { + transform: scale(1) translate(-50%, -50%) +} + +.q-slider__thumb--h-rtl { + transform: scale(1) translate(50%, -50%) +} + +.q-slider__thumb--v { + left : 50%; + will-change: top +} + +.q-slider__thumb--v-ltr { + transform: scale(1) translate(-50%, -50%) +} + +.q-slider__thumb--v-rtl { + transform: scale(1) translate(-50%, 50%) +} + +.q-slider__thumb-shape { + top : 0; + left : 0; + stroke-width: 3.5; + stroke : currentColor; + transition : transform 0.28s +} + +.q-slider__thumb-shape path { + stroke: currentColor; + fill : currentColor +} + +.q-slider__focus-ring { + border-radius : 50%; + opacity : 0; + transition : transform 266.67ms ease-out, opacity 266.67ms ease-out, background-color 266.67ms ease-out; + transition-delay: 0.14s +} + +.q-slider__pin { + opacity : 0; + white-space : nowrap; + transition : opacity 0.28s ease-out; + transition-delay: 0.14s +} + +.q-slider__pin:before { + content : ""; + width : 0; + height : 0; + position: absolute +} + +.q-slider__pin--h:before { + border-left : 6px solid transparent; + border-right: 6px solid transparent; + left : 50%; + transform : translateX(-50%) +} + +.q-slider__pin--h-standard { + bottom: 100% +} + +.q-slider__pin--h-standard:before { + bottom : 2px; + border-top: 6px solid currentColor +} + +.q-slider__pin--h-switched { + top: 100% +} + +.q-slider__pin--h-switched:before { + top : 2px; + border-bottom: 6px solid currentColor +} + +.q-slider__pin--v { + top: 0 +} + +.q-slider__pin--v:before { + top : 50%; + transform : translateY(-50%); + border-top : 6px solid transparent; + border-bottom: 6px solid transparent +} + +.q-slider__pin--v-standard { + left: 100% +} + +.q-slider__pin--v-standard:before { + left : 2px; + border-right: 6px solid currentColor +} + +.q-slider__pin--v-switched { + right: 100% +} + +.q-slider__pin--v-switched:before { + right : 2px; + border-left: 6px solid currentColor +} + +.q-slider__label { + z-index : 1; + white-space: nowrap; + position : absolute +} + +.q-slider__label--h { + left : 50%; + transform: translateX(-50%) +} + +.q-slider__label--h-standard { + bottom: 7px +} + +.q-slider__label--h-switched { + top: 7px +} + +.q-slider__label--v { + top : 50%; + transform: translateY(-50%) +} + +.q-slider__label--v-standard { + left: 7px +} + +.q-slider__label--v-switched { + right: 7px +} + +.q-slider__text-container { + min-height : 25px; + padding : 2px 8px; + border-radius: 4px; + background : currentColor; + position : relative; + text-align : center +} + +.q-slider__text { + color : #fff; + font-size: 12px +} + +.q-slider--no-value .q-slider__inner, +.q-slider--no-value .q-slider__selection, +.q-slider--no-value .q-slider__thumb { + opacity: 0 +} + +.q-slider--focus .q-slider__focus-ring, +body.desktop .q-slider.q-slider--editable .q-slider__track-container:hover .q-slider__focus-ring { + background: currentColor; + transform : scale3d(1.55, 1.55, 1); + opacity : 0.25 +} + +.q-slider--focus .q-slider__inner, +.q-slider--focus .q-slider__selection, +.q-slider--focus .q-slider__thumb, +body.desktop .q-slider.q-slider--editable .q-slider__track-container:hover .q-slider__inner, +body.desktop .q-slider.q-slider--editable .q-slider__track-container:hover .q-slider__selection, +body.desktop .q-slider.q-slider--editable .q-slider__track-container:hover .q-slider__thumb { + opacity: 1 +} + +.q-slider--inactive .q-slider__thumb--h { + transition: left 0.28s, right 0.28s +} + +.q-slider--inactive .q-slider__thumb--v { + transition: top 0.28s, bottom 0.28s +} + +.q-slider--inactive .q-slider__selection { + transition: width 0.28s, left 0.28s, right 0.28s, height 0.28s, top 0.28s, bottom 0.28s +} + +.q-slider--inactive .q-slider__text-container { + transition: transform 0.28s +} + +.q-slider--active { + cursor: -webkit-grabbing; + cursor: grabbing +} + +.q-slider--active .q-slider__thumb-shape { + transform: scale(1.5) +} + +.q-slider--active.q-slider--label .q-slider__thumb-shape, +.q-slider--active .q-slider__focus-ring { + transform: scale(0) !important +} + +.q-slider--label.q-slider--active .q-slider__pin, +.q-slider--label .q-slider--focus .q-slider__pin, +.q-slider--label.q-slider--label-always .q-slider__pin, +body.desktop .q-slider.q-slider--enabled .q-slider__track-container:hover .q-slider__pin { + opacity: 1 +} + +.q-slider--dark .q-slider__inner, +.q-slider--dark .q-slider__track { + background: hsla(0, 0%, 100%, 0.1) +} + +.q-slider--dark .q-slider__markers { + color: hsla(0, 0%, 100%, 0.3) +} + +.q-slider--dense .q-slider__track-container--h { + padding: 6px 0 +} + +.q-slider--dense .q-slider__track-container--v { + padding: 0 6px +} + +.q-space { + flex-grow: 1 !important +} + +.q-spinner { + vertical-align: middle +} + +.q-spinner-mat { + -webkit-animation: q-spin 2s linear infinite; + animation : q-spin 2s linear infinite; + transform-origin : center center +} + +.q-spinner-mat .path { + stroke-dasharray : 1, 200; + stroke-dashoffset: 0; + -webkit-animation: q-mat-dash 1.5s ease-in-out infinite; + animation : q-mat-dash 1.5s ease-in-out infinite +} + +.q-splitter__panel { + position: relative; + z-index : 0 +} + +.q-splitter__panel>.q-splitter { + width : 100%; + height: 100% +} + +.q-splitter__separator { + background-color : rgba(0, 0, 0, 0.12); + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + position : relative; + z-index : 1 +} + +.q-splitter__separator-area>* { + position : absolute; + top : 50%; + left : 50%; + transform: translate(-50%, -50%) +} + +.q-splitter--dark .q-splitter__separator { + background-color: hsla(0, 0%, 100%, 0.28) +} + +.q-splitter--vertical>.q-splitter__panel { + height: 100% +} + +.q-splitter--vertical.q-splitter--active { + cursor: col-resize +} + +.q-splitter--vertical>.q-splitter__separator { + width: 1px +} + +.q-splitter--vertical>.q-splitter__separator>div { + left : -6px; + right: -6px +} + +.q-splitter--vertical.q-splitter--workable>.q-splitter__separator { + cursor: col-resize +} + +.q-splitter--horizontal>.q-splitter__panel { + width: 100% +} + +.q-splitter--horizontal.q-splitter--active { + cursor: row-resize +} + +.q-splitter--horizontal>.q-splitter__separator { + height: 1px +} + +.q-splitter--horizontal>.q-splitter__separator>div { + top : -6px; + bottom: -6px +} + +.q-splitter--horizontal.q-splitter--workable>.q-splitter__separator { + cursor: row-resize +} + +.q-splitter__after, +.q-splitter__before { + overflow: auto +} + +.q-stepper { + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + border-radius: 4px; + background : #fff +} + +.q-stepper__title { + font-size : 14px; + line-height : 18px; + letter-spacing: 0.1px +} + +.q-stepper__caption { + font-size : 12px; + line-height: 14px +} + +.q-stepper__dot { + contain : layout; + margin-right : 8px; + font-size : 14px; + width : 24px; + min-width : 24px; + height : 24px; + border-radius: 50%; + background : currentColor +} + +.q-stepper__dot span { + color: #fff +} + +.q-stepper__tab { + padding : 8px 24px; + font-size : 14px; + color : #9e9e9e; + flex-direction: row +} + +.q-stepper--dark .q-stepper__dot span { + color: #000 +} + +.q-stepper__tab--navigation { + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + cursor : pointer +} + +.q-stepper__tab--active, +.q-stepper__tab--done { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-stepper__tab--active .q-stepper__dot, +.q-stepper__tab--active .q-stepper__label, +.q-stepper__tab--done .q-stepper__dot, +.q-stepper__tab--done .q-stepper__label { + text-shadow: 0 0 0 currentColor +} + +.q-stepper__tab--disabled .q-stepper__dot { + background: rgba(0, 0, 0, 0.22) +} + +.q-stepper__tab--disabled .q-stepper__label { + color: rgba(0, 0, 0, 0.32) +} + +.q-stepper__tab--error { + color: #c10015; + color: var(--q-color-negative) +} + +.q-stepper__tab--error-with-icon .q-stepper__dot { + background: transparent !important +} + +.q-stepper__tab--error-with-icon .q-stepper__dot span { + color: currentColor +} + +.q-stepper__tab--error-with-icon .q-stepper__dot .q-icon { + font-size: 24px +} + +.q-stepper__header { + border-top-left-radius : inherit; + border-top-right-radius: inherit +} + +.q-stepper__header--border { + border-bottom: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-stepper__header--standard-labels .q-stepper__tab { + min-height : 72px; + justify-content: center +} + +.q-stepper__header--standard-labels .q-stepper__tab:first-child { + justify-content: flex-start +} + +.q-stepper__header--standard-labels .q-stepper__tab:last-child { + justify-content: flex-end +} + +.q-stepper__header--standard-labels .q-stepper__tab:only-child { + justify-content: center +} + +.q-stepper__header--standard-labels .q-stepper__dot:after { + display: none +} + +.q-stepper__header--alternative-labels .q-stepper__tab { + min-height : 104px; + padding : 24px 32px; + flex-direction : column; + justify-content: flex-start +} + +.q-stepper__header--alternative-labels .q-stepper__dot { + margin-right: 0 +} + +.q-stepper__header--alternative-labels .q-stepper__label { + margin-top: 8px; + text-align: center +} + +.q-stepper__header--alternative-labels .q-stepper__label:after, +.q-stepper__header--alternative-labels .q-stepper__label:before { + display: none +} + +.q-stepper__header--contracted, +.q-stepper__header--contracted.q-stepper__header--alternative-labels .q-stepper__tab { + min-height: 72px +} + +.q-stepper__header--contracted.q-stepper__header--alternative-labels .q-stepper__tab:first-child { + align-items: flex-start +} + +.q-stepper__header--contracted.q-stepper__header--alternative-labels .q-stepper__tab:last-child { + align-items: flex-end +} + +.q-stepper__header--contracted .q-stepper__tab { + padding: 24px 0 +} + +.q-stepper__header--contracted .q-stepper__tab:first-child .q-stepper__dot { + transform: translateX(24px) +} + +.q-stepper__header--contracted .q-stepper__tab:last-child .q-stepper__dot { + transform: translateX(-24px) +} + +.q-stepper__header--contracted .q-stepper__tab:not(:last-child) .q-stepper__dot:after { + display: block !important +} + +.q-stepper__header--contracted .q-stepper__dot { + margin: 0 +} + +.q-stepper__header--contracted .q-stepper__label { + display: none +} + +.q-stepper__nav { + padding-top: 24px +} + +.q-stepper--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-stepper--horizontal .q-stepper__step-inner { + padding: 24px +} + +.q-stepper--horizontal .q-stepper__tab:first-child { + border-top-left-radius: inherit +} + +.q-stepper--horizontal .q-stepper__tab:last-child { + border-top-right-radius: inherit +} + +.q-stepper--horizontal .q-stepper__tab:first-child .q-stepper__dot:before, +.q-stepper--horizontal .q-stepper__tab:last-child .q-stepper__dot:after, +.q-stepper--horizontal .q-stepper__tab:last-child .q-stepper__label:after { + display: none +} + +.q-stepper--horizontal .q-stepper__tab { + overflow: hidden +} + +.q-stepper--horizontal .q-stepper__line { + contain: layout +} + +.q-stepper--horizontal .q-stepper__line:after, +.q-stepper--horizontal .q-stepper__line:before { + position : absolute; + top : 50%; + height : 1px; + width : 100vw; + background: rgba(0, 0, 0, 0.12) +} + +.q-stepper--horizontal .q-stepper__dot:after, +.q-stepper--horizontal .q-stepper__label:after { + content : ""; + left : 100%; + margin-left: 8px +} + +.q-stepper--horizontal .q-stepper__dot:before { + content : ""; + right : 100%; + margin-right: 8px +} + +.q-stepper--horizontal>.q-stepper__nav { + padding: 0 24px 24px +} + +.q-stepper--vertical { + padding: 16px 0 +} + +.q-stepper--vertical .q-stepper__tab { + padding: 12px 24px +} + +.q-stepper--vertical .q-stepper__title { + line-height: 18px +} + +.q-stepper--vertical .q-stepper__step-inner { + padding: 0 24px 32px 60px +} + +.q-stepper--vertical>.q-stepper__nav { + padding: 24px 24px 0 +} + +.q-stepper--vertical .q-stepper__step { + overflow: hidden +} + +.q-stepper--vertical .q-stepper__dot { + margin-right: 12px +} + +.q-stepper--vertical .q-stepper__dot:after, +.q-stepper--vertical .q-stepper__dot:before { + content : ""; + position : absolute; + left : 50%; + width : 1px; + height : 99999px; + background: rgba(0, 0, 0, 0.12) +} + +.q-stepper--vertical .q-stepper__dot:before { + bottom : 100%; + margin-bottom: 8px +} + +.q-stepper--vertical .q-stepper__dot:after { + top : 100%; + margin-top: 8px +} + +.q-stepper--vertical .q-stepper__step:first-child .q-stepper__dot:before, +.q-stepper--vertical .q-stepper__step:last-child .q-stepper__dot:after { + display: none +} + +.q-stepper--vertical .q-stepper__step:last-child .q-stepper__step-inner { + padding-bottom: 8px +} + +.q-stepper--dark.q-stepper--bordered, +.q-stepper--dark .q-stepper__header--border { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-stepper--dark.q-stepper--horizontal .q-stepper__line:after, +.q-stepper--dark.q-stepper--horizontal .q-stepper__line:before, +.q-stepper--dark.q-stepper--vertical .q-stepper__dot:after, +.q-stepper--dark.q-stepper--vertical .q-stepper__dot:before { + background: hsla(0, 0%, 100%, 0.28) +} + +.q-stepper--dark .q-stepper__tab--disabled { + color: hsla(0, 0%, 100%, 0.28) +} + +.q-stepper--dark .q-stepper__tab--disabled .q-stepper__dot { + background: hsla(0, 0%, 100%, 0.28) +} + +.q-stepper--dark .q-stepper__tab--disabled .q-stepper__label { + color: hsla(0, 0%, 100%, 0.54) +} + +.q-tab-panels { + background: #fff +} + +.q-tab-panel { + padding: 16px +} + +.q-markup-table { + overflow : auto; + background: #fff +} + +.q-table { + width : 100%; + max-width : 100%; + border-collapse: separate; + border-spacing : 0 +} + +.q-table tbody td, +.q-table thead tr { + height: 48px +} + +.q-table th { + font-weight : 500; + font-size : 12px; + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none +} + +.q-table th.sortable { + cursor: pointer +} + +.q-table th.sortable:hover .q-table__sort-icon { + opacity: 0.64 +} + +.q-table th.sorted .q-table__sort-icon { + opacity: 0.86 !important +} + +.q-table th.sort-desc .q-table__sort-icon { + transform: rotate(180deg) +} + +.q-table td, +.q-table th { + padding : 7px 16px; + background-color: inherit +} + +.q-table td, +.q-table th, +.q-table thead { + border-style: solid; + border-width: 0 +} + +.q-table tbody td { + font-size: 13px +} + +.q-table__card { + color : #000; + background-color: #fff; + border-radius : 4px; + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12) +} + +.q-table__card .q-table__middle { + flex: 1 1 auto +} + +.q-table__card .q-table__bottom, +.q-table__card .q-table__top { + flex: 0 0 auto +} + +.q-table__container { + position: relative +} + +.q-table__container.fullscreen { + max-height: 100% +} + +.q-table__container>div:first-child { + border-top-left-radius : inherit; + border-top-right-radius: inherit +} + +.q-table__container>div:last-child { + border-bottom-left-radius : inherit; + border-bottom-right-radius: inherit +} + +.q-table__container>.q-inner-loading { + border-radius: inherit !important +} + +.q-table__top { + padding: 12px 16px +} + +.q-table__top .q-table__control { + flex-wrap: wrap +} + +.q-table__title { + font-size : 20px; + letter-spacing: 0.005em; + font-weight : 400 +} + +.q-table__separator { + min-width: 8px !important +} + +.q-table__progress { + height: 0 !important +} + +.q-table__progress th { + padding: 0 !important; + border : 0 !important +} + +.q-table__progress .q-linear-progress { + position: absolute; + bottom : 0 +} + +.q-table__middle { + max-width: 100% +} + +.q-table__bottom { + min-height: 50px; + padding : 4px 14px 4px 16px; + font-size : 12px +} + +.q-table__bottom .q-table__control { + min-height: 24px +} + +.q-table__bottom-nodata-icon { + font-size : 200%; + margin-right: 8px +} + +.q-table__bottom-item { + margin-right: 16px +} + +.q-table__control { + display : flex; + align-items: center +} + +.q-table__sort-icon { + transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); + opacity : 0; + font-size : 120% +} + +.q-table__sort-icon--center, +.q-table__sort-icon--left { + margin-left: 4px +} + +.q-table__sort-icon--right { + margin-right: 4px +} + +.q-table--col-auto-width { + width: 1px +} + +.q-table--flat { + box-shadow: none +} + +.q-table--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-table--square { + border-radius: 0 +} + +.q-table__linear-progress { + height: 2px +} + +.q-table--no-wrap td, +.q-table--no-wrap th { + white-space: nowrap +} + +.q-table--grid { + box-shadow : none; + border-radius: 4px +} + +.q-table--grid .q-table__top { + padding-bottom: 4px +} + +.q-table--grid .q-table__middle { + min-height : 2px; + margin-bottom: 4px +} + +.q-table--grid .q-table__middle thead, +.q-table--grid .q-table__middle thead th { + border: 0 !important +} + +.q-table--grid .q-table__linear-progress { + bottom: 0 +} + +.q-table--grid .q-table__bottom { + border-top: 0 +} + +.q-table--grid .q-table__grid-content { + flex: 1 1 auto +} + +.q-table--grid.fullscreen { + background: inherit +} + +.q-table__grid-item-card { + vertical-align: top; + padding : 12px +} + +.q-table__grid-item-card .q-separator { + margin: 12px 0 +} + +.q-table__grid-item-row+.q-table__grid-item-row { + margin-top: 8px +} + +.q-table__grid-item-title { + opacity : 0.54; + font-weight: 500; + font-size : 12px +} + +.q-table__grid-item-value { + font-size: 13px +} + +.q-table__grid-item { + padding : 4px; + transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) +} + +.q-table__grid-item--selected { + transform: scale(0.95) +} + +.q-table--cell-separator tbody tr:not(:last-child)>td, +.q-table--cell-separator thead th, +.q-table--horizontal-separator tbody tr:not(:last-child)>td, +.q-table--horizontal-separator thead th { + border-bottom-width: 1px +} + +.q-table--cell-separator td, +.q-table--cell-separator th, +.q-table--vertical-separator td, +.q-table--vertical-separator th { + border-left-width: 1px +} + +.q-table--cell-separator.q-table--loading tr:nth-last-child(2) th, +.q-table--cell-separator thead tr:last-child th, +.q-table--vertical-separator.q-table--loading tr:nth-last-child(2) th, +.q-table--vertical-separator thead tr:last-child th { + border-bottom-width: 1px +} + +.q-table--cell-separator td:first-child, +.q-table--cell-separator th:first-child, +.q-table--vertical-separator td:first-child, +.q-table--vertical-separator th:first-child { + border-left: 0 +} + +.q-table--cell-separator .q-table__top, +.q-table--vertical-separator .q-table__top { + border-bottom: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-table--dense .q-table__top { + padding: 6px 16px +} + +.q-table--dense .q-table__bottom { + min-height: 33px +} + +.q-table--dense .q-table__sort-icon { + font-size: 110% +} + +.q-table--dense .q-table td, +.q-table--dense .q-table th { + padding: 4px 8px +} + +.q-table--dense .q-table tbody td, +.q-table--dense .q-table tbody tr, +.q-table--dense .q-table thead tr { + height: 28px +} + +.q-table--dense .q-table td:first-child, +.q-table--dense .q-table th:first-child { + padding-left: 16px +} + +.q-table--dense .q-table td:last-child, +.q-table--dense .q-table th:last-child { + padding-right: 16px +} + +.q-table--dense .q-table__bottom-item { + margin-right: 8px +} + +.q-table--dense .q-table__select .q-field__control, +.q-table--dense .q-table__select .q-field__native { + min-height: 24px; + padding : 0 +} + +.q-table--dense .q-table__select .q-field__marginal { + height: 24px +} + +.q-table__bottom { + border-top: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-table td, +.q-table th, +.q-table thead, +.q-table tr { + border-color: rgba(0, 0, 0, 0.12) +} + +.q-table tbody td { + position: relative +} + +.q-table tbody td:after, +.q-table tbody td:before { + position : absolute; + top : 0; + left : 0; + right : 0; + bottom : 0; + pointer-events: none +} + +.q-table tbody td:before { + background: rgba(0, 0, 0, 0.03) +} + +.q-table tbody td:after { + background: rgba(0, 0, 0, 0.06) +} + +.q-table tbody tr.selected td:after, +body.desktop .q-table>tbody>tr:not(.q-tr--no-hover):hover>td:not(.q-td--no-hover):before { + content: "" +} + +.q-table--dark, +.q-table--dark .q-table__bottom, +.q-table--dark td, +.q-table--dark th, +.q-table--dark thead, +.q-table--dark tr, +.q-table__card--dark { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-table--dark tbody td:before { + background: hsla(0, 0%, 100%, 0.07) +} + +.q-table--dark tbody td:after { + background: hsla(0, 0%, 100%, 0.1) +} + +.q-table--dark.q-table--cell-separator .q-table__top, +.q-table--dark.q-table--vertical-separator .q-table__top { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-tab { + padding : 0 16px; + min-height : 48px; + transition : color 0.3s, background-color 0.3s; + text-transform : uppercase; + white-space : nowrap; + color : inherit; + text-decoration: none +} + +.q-tab--full { + min-height: 72px +} + +.q-tab--no-caps { + text-transform: none +} + +.q-tab__content { + height : inherit; + padding : 4px 0; + min-width: 40px +} + +.q-tab__content--inline .q-tab__icon+.q-tab__label { + padding-left: 8px +} + +.q-tab__content .q-chip--floating { + top : 0; + right: -16px +} + +.q-tab__icon { + width : 24px; + height : 24px; + font-size: 24px +} + +.q-tab__label { + font-size : 14px; + line-height: 1.715em; + font-weight: 500 +} + +.q-tab .q-badge { + top : 3px; + right: -12px +} + +.q-tab__alert, +.q-tab__alert-icon { + position: absolute +} + +.q-tab__alert { + top : 7px; + right : -9px; + height : 10px; + width : 10px; + border-radius: 50%; + background : currentColor +} + +.q-tab__alert-icon { + top : 2px; + right : -12px; + font-size: 18px +} + +.q-tab__indicator { + opacity : 0; + height : 2px; + background: currentColor +} + +.q-tab--active .q-tab__indicator { + opacity : 1; + transform-origin: left +} + +.q-tab--inactive { + opacity: 0.85 +} + +.q-tabs { + position : relative; + transition: color 0.3s, background-color 0.3s +} + +.q-tabs--scrollable.q-tabs__arrows--outside.q-tabs--horizontal { + padding-left : 36px; + padding-right: 36px +} + +.q-tabs--scrollable.q-tabs__arrows--outside.q-tabs--vertical { + padding-top : 36px; + padding-bottom: 36px +} + +.q-tabs--scrollable.q-tabs__arrows--outside .q-tabs__arrow--faded { + opacity : 0.3; + pointer-events: none +} + +.q-tabs--not-scrollable .q-tabs__arrow, +.q-tabs--scrollable.q-tabs__arrows--inside .q-tabs__arrow--faded { + display: none +} + +.q-tabs--not-scrollable .q-tabs__content { + border-radius: inherit +} + +.q-tabs__arrow { + cursor : pointer; + font-size : 32px; + min-width : 36px; + text-shadow: 0 0 3px #fff, 0 0 1px #fff, 0 0 1px #000; + transition : opacity 0.3s +} + +.q-tabs__content { + overflow: hidden; + flex : 1 1 auto +} + +.q-tabs__content--align-center { + justify-content: center +} + +.q-tabs__content--align-right { + justify-content: flex-end +} + +.q-tabs__content--align-justify .q-tab { + flex: 1 1 auto +} + +.q-tabs__offset { + display: none +} + +.q-tabs--horizontal .q-tabs__arrow { + height: 100% +} + +.q-tabs--horizontal .q-tabs__arrow--start { + top : 0; + left : 0; + bottom: 0 +} + +.q-tabs--horizontal .q-tabs__arrow--end { + top : 0; + right : 0; + bottom: 0 +} + +.q-tabs--vertical, +.q-tabs--vertical .q-tabs__content { + display: block !important; + height : 100% +} + +.q-tabs--vertical .q-tabs__arrow { + width : 100%; + height : 36px; + text-align: center +} + +.q-tabs--vertical .q-tabs__arrow--start { + top : 0; + left : 0; + right: 0 +} + +.q-tabs--vertical .q-tabs__arrow--end { + left : 0; + right : 0; + bottom: 0 +} + +.q-tabs--vertical .q-tab { + padding: 0 8px +} + +.q-tabs--vertical .q-tab__indicator { + height: unset; + width : 2px +} + +.q-tabs--vertical.q-tabs--not-scrollable .q-tabs__content { + height: 100% +} + +.q-tabs--vertical.q-tabs--dense .q-tab__content { + min-width: 24px +} + +.q-tabs--dense .q-tab { + min-height: 36px +} + +.q-tabs--dense .q-tab--full { + min-height: 52px +} + +@media (min-width:1440px) { + + .q-footer .q-tab__content, + .q-header .q-tab__content { + min-width: 128px + } +} + +.q-time { + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + border-radius: 4px; + background : #fff; + outline : 0; + width : 290px; + min-width : 290px; + max-width : 100% +} + +.q-time--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-time__header { + border-top-left-radius: inherit; + color : #fff; + background-color : #1976d2; + background-color : var(--q-color-primary); + padding : 16px; + font-weight : 300 +} + +.q-time__actions { + padding: 0 16px 16px +} + +.q-time__header-label { + font-size : 28px; + line-height : 1; + letter-spacing: -0.00833em +} + +.q-time__header-label>div+div { + margin-left: 4px +} + +.q-time__link { + opacity : 0.56; + outline : 0; + transition: opacity 0.3s ease-out +} + +.q-time__link--active, +.q-time__link:focus, +.q-time__link:hover { + opacity: 1 +} + +.q-time__header-ampm { + font-size : 16px; + letter-spacing: 0.1em +} + +.q-time__content { + padding: 16px +} + +.q-time__content:before { + content : ""; + display : block; + padding-bottom: 100% +} + +.q-time__container-parent { + padding: 16px +} + +.q-time__container-child { + border-radius: 50%; + background : rgba(0, 0, 0, 0.12) +} + +.q-time__clock { + padding : 24px; + width : 100%; + height : 100%; + max-width : 100%; + max-height: 100%; + font-size : 14px +} + +.q-time__clock-circle { + position: relative +} + +.q-time__clock-center { + height : 6px; + width : 6px; + margin : auto; + border-radius: 50%; + min-height : 0; + background : currentColor +} + +.q-time__clock-pointer { + width : 2px; + height : 50%; + transform-origin: 0 0; + min-height : 0; + position : absolute; + left : 50%; + right : 0; + bottom : 0; + color : #1976d2; + color : var(--q-color-primary); + background : currentColor; + transform : translateX(-50%) +} + +.q-time__clock-pointer:after, +.q-time__clock-pointer:before { + content : ""; + position : absolute; + left : 50%; + border-radius: 50%; + background : currentColor; + transform : translateX(-50%) +} + +.q-time__clock-pointer:before { + bottom: -4px; + width : 8px; + height: 8px +} + +.q-time__clock-pointer:after { + top : -3px; + height: 6px; + width : 6px +} + +.q-time__clock-position { + position : absolute; + min-height : 32px; + width : 32px; + height : 32px; + font-size : 12px; + line-height : 32px; + margin : 0; + padding : 0; + transform : translate(-50%, -50%); + border-radius: 50% +} + +.q-time__clock-position--disable { + opacity: 0.4 +} + +.q-time__clock-position--active { + background-color: #1976d2; + background-color: var(--q-color-primary); + color : #fff +} + +.q-time__clock-pos-0 { + top : 0%; + left: 50% +} + +.q-time__clock-pos-1 { + top : 6.7%; + left: 75% +} + +.q-time__clock-pos-2 { + top : 25%; + left: 93.3% +} + +.q-time__clock-pos-3 { + top : 50%; + left: 100% +} + +.q-time__clock-pos-4 { + top : 75%; + left: 93.3% +} + +.q-time__clock-pos-5 { + top : 93.3%; + left: 75% +} + +.q-time__clock-pos-6 { + top : 100%; + left: 50% +} + +.q-time__clock-pos-7 { + top : 93.3%; + left: 25% +} + +.q-time__clock-pos-8 { + top : 75%; + left: 6.7% +} + +.q-time__clock-pos-9 { + top : 50%; + left: 0% +} + +.q-time__clock-pos-10 { + top : 25%; + left: 6.7% +} + +.q-time__clock-pos-11 { + top : 6.7%; + left: 25% +} + +.q-time__clock-pos-12 { + top : 15%; + left: 50% +} + +.q-time__clock-pos-13 { + top : 19.69%; + left: 67.5% +} + +.q-time__clock-pos-14 { + top : 32.5%; + left: 80.31% +} + +.q-time__clock-pos-15 { + top : 50%; + left: 85% +} + +.q-time__clock-pos-16 { + top : 67.5%; + left: 80.31% +} + +.q-time__clock-pos-17 { + top : 80.31%; + left: 67.5% +} + +.q-time__clock-pos-18 { + top : 85%; + left: 50% +} + +.q-time__clock-pos-19 { + top : 80.31%; + left: 32.5% +} + +.q-time__clock-pos-20 { + top : 67.5%; + left: 19.69% +} + +.q-time__clock-pos-21 { + top : 50%; + left: 15% +} + +.q-time__clock-pos-22 { + top : 32.5%; + left: 19.69% +} + +.q-time__clock-pos-23 { + top : 19.69%; + left: 32.5% +} + +.q-time__now-button { + background-color: #1976d2; + background-color: var(--q-color-primary); + color : #fff; + top : 12px; + right : 12px +} + +.q-time--readonly .q-time__content, +.q-time--readonly .q-time__header-ampm, +.q-time.disabled .q-time__content, +.q-time.disabled .q-time__header-ampm { + pointer-events: none +} + +.q-time--portrait { + display : inline-flex; + flex-direction: column +} + +.q-time--portrait .q-time__header { + border-top-right-radius: inherit; + min-height : 86px +} + +.q-time--portrait .q-time__header-ampm { + margin-left: 12px +} + +.q-time--portrait.q-time--bordered .q-time__content { + margin: 1px 0 +} + +.q-time--landscape { + display : inline-flex; + align-items: stretch; + min-width : 420px +} + +.q-time--landscape>div { + display : flex; + flex-direction : column; + justify-content: center +} + +.q-time--landscape .q-time__header { + border-bottom-left-radius: inherit; + min-width : 156px +} + +.q-time--landscape .q-time__header-ampm { + margin-top: 12px +} + +.q-time--dark { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-timeline { + padding : 0; + width : 100%; + list-style: none +} + +.q-timeline h6 { + line-height: inherit +} + +.q-timeline--dark { + color: #fff +} + +.q-timeline--dark .q-timeline__subtitle { + opacity: 0.7 +} + +.q-timeline__content { + padding-bottom: 24px +} + +.q-timeline__title { + margin-top : 0; + margin-bottom: 16px +} + +.q-timeline__subtitle { + font-size : 12px; + margin-bottom : 8px; + opacity : 0.6; + text-transform: uppercase; + letter-spacing: 1px; + font-weight : 700 +} + +.q-timeline__dot { + position: absolute; + top : 0; + bottom : 0; + width : 15px +} + +.q-timeline__dot:after, +.q-timeline__dot:before { + content : ""; + background: currentColor; + display : block; + position : absolute +} + +.q-timeline__dot:before { + border : 3px solid transparent; + border-radius: 100%; + height : 15px; + width : 15px; + top : 4px; + left : 0; + transition : background 0.3s ease-in-out, border 0.3s ease-in-out +} + +.q-timeline__dot:after { + width : 3px; + opacity: 0.4; + top : 24px; + bottom : 0; + left : 6px +} + +.q-timeline__dot .q-icon { + position : absolute; + top : 0; + left : 0; + right : 0; + font-size : 16px; + height : 38px; + line-height: 38px; + width : 100%; + color : #fff +} + +.q-timeline__dot .q-icon>img, +.q-timeline__dot .q-icon>svg { + width : 1em; + height: 1em +} + +.q-timeline__dot-img { + position : absolute; + top : 4px; + left : 0; + right : 0; + height : 31px; + width : 31px; + background : currentColor; + border-radius: 50% +} + +.q-timeline__heading { + position: relative +} + +.q-timeline__heading:first-child .q-timeline__heading-title { + padding-top: 0 +} + +.q-timeline__heading:last-child .q-timeline__heading-title { + padding-bottom: 0 +} + +.q-timeline__heading-title { + padding: 32px 0; + margin : 0 +} + +.q-timeline__entry { + position : relative; + line-height: 22px +} + +.q-timeline__entry:last-child { + padding-bottom: 0 !important +} + +.q-timeline__entry:last-child .q-timeline__dot:after { + content: none +} + +.q-timeline__entry--icon .q-timeline__dot { + width: 31px +} + +.q-timeline__entry--icon .q-timeline__dot:before { + height: 31px; + width : 31px +} + +.q-timeline__entry--icon .q-timeline__dot:after { + top : 41px; + left: 14px +} + +.q-timeline__entry--icon .q-timeline__subtitle { + padding-top: 8px +} + +.q-timeline--dense--right .q-timeline__entry { + padding-left: 40px +} + +.q-timeline--dense--right .q-timeline__entry--icon .q-timeline__dot { + left: -8px +} + +.q-timeline--dense--right .q-timeline__dot { + left: 0 +} + +.q-timeline--dense--left .q-timeline__heading { + text-align: right +} + +.q-timeline--dense--left .q-timeline__entry { + padding-right: 40px +} + +.q-timeline--dense--left .q-timeline__entry--icon .q-timeline__dot { + right: -8px +} + +.q-timeline--dense--left .q-timeline__content, +.q-timeline--dense--left .q-timeline__subtitle, +.q-timeline--dense--left .q-timeline__title { + text-align: right +} + +.q-timeline--dense--left .q-timeline__dot { + right: 0 +} + +.q-timeline--comfortable { + display: table +} + +.q-timeline--comfortable .q-timeline__heading { + display : table-row; + font-size: 200% +} + +.q-timeline--comfortable .q-timeline__heading>div { + display: table-cell +} + +.q-timeline--comfortable .q-timeline__entry { + display: table-row; + padding: 0 +} + +.q-timeline--comfortable .q-timeline__entry--icon .q-timeline__content { + padding-top: 8px +} + +.q-timeline--comfortable .q-timeline__content, +.q-timeline--comfortable .q-timeline__dot, +.q-timeline--comfortable .q-timeline__subtitle { + display : table-cell; + vertical-align: top +} + +.q-timeline--comfortable .q-timeline__subtitle { + width: 35% +} + +.q-timeline--comfortable .q-timeline__dot { + position : relative; + min-width: 31px +} + +.q-timeline--comfortable--right .q-timeline__heading .q-timeline__heading-title { + margin-left: -50px +} + +.q-timeline--comfortable--right .q-timeline__subtitle { + text-align : right; + padding-right: 30px +} + +.q-timeline--comfortable--right .q-timeline__content { + padding-left: 30px +} + +.q-timeline--comfortable--right .q-timeline__entry--icon .q-timeline__dot { + left: -8px +} + +.q-timeline--comfortable--left .q-timeline__heading { + text-align: right +} + +.q-timeline--comfortable--left .q-timeline__heading .q-timeline__heading-title { + margin-right: -50px +} + +.q-timeline--comfortable--left .q-timeline__subtitle { + padding-left: 30px +} + +.q-timeline--comfortable--left .q-timeline__content { + padding-right: 30px +} + +.q-timeline--comfortable--left .q-timeline__content, +.q-timeline--comfortable--left .q-timeline__title { + text-align: right +} + +.q-timeline--comfortable--left .q-timeline__entry--icon .q-timeline__dot { + right: 0 +} + +.q-timeline--comfortable--left .q-timeline__dot { + right: -8px +} + +.q-timeline--loose .q-timeline__heading-title { + text-align : center; + margin-left: 0 +} + +.q-timeline--loose .q-timeline__content, +.q-timeline--loose .q-timeline__dot, +.q-timeline--loose .q-timeline__entry, +.q-timeline--loose .q-timeline__subtitle { + display: block; + margin : 0; + padding: 0 +} + +.q-timeline--loose .q-timeline__dot { + position : absolute; + left : 50%; + margin-left: -7.15px +} + +.q-timeline--loose .q-timeline__entry { + padding-bottom: 24px; + overflow : hidden +} + +.q-timeline--loose .q-timeline__entry--icon .q-timeline__dot { + margin-left: -15px +} + +.q-timeline--loose .q-timeline__entry--icon .q-timeline__subtitle { + line-height: 38px +} + +.q-timeline--loose .q-timeline__entry--icon .q-timeline__content { + padding-top: 8px +} + +.q-timeline--loose .q-timeline__entry--left .q-timeline__content, +.q-timeline--loose .q-timeline__entry--right .q-timeline__subtitle { + float : left; + padding-right: 30px; + text-align : right +} + +.q-timeline--loose .q-timeline__entry--left .q-timeline__subtitle, +.q-timeline--loose .q-timeline__entry--right .q-timeline__content { + float : right; + text-align : left; + padding-left: 30px +} + +.q-timeline--loose .q-timeline__content, +.q-timeline--loose .q-timeline__subtitle { + width: 50% +} + +.q-toggle { + vertical-align: middle +} + +.q-toggle__native { + width : 1px; + height: 1px +} + +.q-toggle__track { + height : 0.35em; + border-radius: 0.175em; + opacity : 0.38; + background : currentColor +} + +.q-toggle__thumb { + top : 0.25em; + left : 0.25em; + width : 0.5em; + height : 0.5em; + transition : left 0.22s cubic-bezier(0.4, 0, 0.2, 1); + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + z-index : 0 +} + +.q-toggle__thumb:after { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + border-radius: 50%; + background : #fff; + box-shadow : 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12) +} + +.q-toggle__thumb .q-icon { + font-size: 0.3em; + min-width: 1em; + color : #000; + opacity : 0.54; + z-index : 1 +} + +.q-toggle__inner { + font-size : 40px; + width : 1.4em; + min-width : 1.4em; + height : 1em; + padding : 0.325em 0.3em; + -webkit-print-color-adjust: exact +} + +.q-toggle__inner--indet .q-toggle__thumb { + left: 0.45em +} + +.q-toggle__inner--truthy { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-toggle__inner--truthy .q-toggle__track { + opacity: 0.54 +} + +.q-toggle__inner--truthy .q-toggle__thumb { + left: 0.65em +} + +.q-toggle__inner--truthy .q-toggle__thumb:after { + background-color: currentColor +} + +.q-toggle__inner--truthy .q-toggle__thumb .q-icon { + color : #fff; + opacity: 1 +} + +.q-toggle.disabled { + opacity: 0.75 !important +} + +.q-toggle--dark .q-toggle__inner { + color: #fff +} + +.q-toggle--dark .q-toggle__inner--truthy { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-toggle--dark .q-toggle__thumb:before { + opacity: 0.32 !important +} + +.q-toggle--dense .q-toggle__inner { + width : 0.8em; + min-width: 0.8em; + height : 0.5em; + padding : 0.07625em 0 +} + +.q-toggle--dense .q-toggle__thumb { + top : 0; + left: 0 +} + +.q-toggle--dense .q-toggle__inner--indet .q-toggle__thumb { + left: 0.15em +} + +.q-toggle--dense .q-toggle__inner--truthy .q-toggle__thumb { + left: 0.3em +} + +.q-toggle--dense .q-toggle__label { + padding-left: 0.5em +} + +.q-toggle--dense.reverse .q-toggle__label { + padding-left : 0; + padding-right: 0.5em +} + +body.desktop .q-toggle:not(.disabled) .q-toggle__thumb:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + border-radius: 50%; + background : currentColor; + opacity : 0.12; + transform : scale3d(0, 0, 1); + transition : transform 0.22s cubic-bezier(0, 0, 0.2, 1) +} + +body.desktop .q-toggle:not(.disabled):focus .q-toggle__thumb:before, +body.desktop .q-toggle:not(.disabled):hover .q-toggle__thumb:before { + transform: scale3d(2, 2, 1) +} + +body.desktop .q-toggle--dense:not(.disabled):focus .q-toggle__thumb:before, +body.desktop .q-toggle--dense:not(.disabled):hover .q-toggle__thumb:before { + transform: scale3d(1.5, 1.5, 1) +} + +.q-toolbar { + position : relative; + padding : 0 12px; + min-height: 50px; + width : 100% +} + +.q-toolbar--inset { + padding-left: 58px +} + +.q-toolbar .q-avatar { + font-size: 38px +} + +.q-toolbar__title { + flex : 1 1 0%; + min-width : 1px; + max-width : 100%; + font-size : 21px; + font-weight : 400; + letter-spacing: 0.01em; + padding : 0 12px +} + +.q-toolbar__title:first-child { + padding-left: 0 +} + +.q-toolbar__title:last-child { + padding-right: 0 +} + +.q-tooltip--style { + font-size : 10px; + color : #fafafa; + background : #757575; + border-radius : 4px; + text-transform: none; + font-weight : 400 +} + +.q-tooltip { + z-index : 9000; + position : fixed !important; + overflow-y: auto; + overflow-x: hidden; + padding : 6px 10px +} + +@media (max-width:599.98px) { + .q-tooltip { + font-size: 14px; + padding : 8px 16px + } +} + +.q-tree { + position: relative; + color : #9e9e9e +} + +.q-tree__node { + padding: 0 0 3px 22px +} + +.q-tree__node:after { + content : ""; + position : absolute; + top : -3px; + bottom : 0; + width : 2px; + right : auto; + left : -13px; + border-left: 1px solid currentColor +} + +.q-tree__node:last-child:after { + display: none +} + +.q-tree__node--disabled { + pointer-events: none +} + +.q-tree__node--disabled .disabled { + opacity: 1 !important +} + +.q-tree__node--disabled>.disabled, +.q-tree__node--disabled>div, +.q-tree__node--disabled>i { + opacity: 0.6 !important +} + +.q-tree__node--disabled>.disabled .q-tree__node--disabled>.disabled, +.q-tree__node--disabled>.disabled .q-tree__node--disabled>div, +.q-tree__node--disabled>.disabled .q-tree__node--disabled>i, +.q-tree__node--disabled>div .q-tree__node--disabled>.disabled, +.q-tree__node--disabled>div .q-tree__node--disabled>div, +.q-tree__node--disabled>div .q-tree__node--disabled>i, +.q-tree__node--disabled>i .q-tree__node--disabled>.disabled, +.q-tree__node--disabled>i .q-tree__node--disabled>div, +.q-tree__node--disabled>i .q-tree__node--disabled>i { + opacity: 1 !important +} + +.q-tree__node-header:before { + content : ""; + position : absolute; + top : -3px; + bottom : 50%; + width : 31px; + left : -35px; + border-left : 1px solid currentColor; + border-bottom: 1px solid currentColor +} + +.q-tree__children { + padding-left: 25px +} + +.q-tree__node-body { + padding: 5px 0 8px 5px +} + +.q-tree__node--parent { + padding-left: 2px +} + +.q-tree__node--parent>.q-tree__node-header:before { + width: 15px; + left : -15px +} + +.q-tree__node--parent>.q-tree__node-collapsible>.q-tree__node-body { + padding: 5px 0 8px 27px +} + +.q-tree__node--parent>.q-tree__node-collapsible>.q-tree__node-body:after { + content : ""; + position : absolute; + top : 0; + width : 2px; + height : 100%; + right : auto; + left : 12px; + border-left: 1px solid currentColor; + bottom : 50px +} + +.q-tree__node--link { + cursor: pointer +} + +.q-tree__node-header { + padding : 4px; + margin-top : 3px; + border-radius: 4px; + outline : 0 +} + +.q-tree__node-header-content { + color : #000; + transition: color 0.3s +} + +.q-tree__node--selected .q-tree__node-header-content { + color: #9e9e9e +} + +.q-tree__icon, +.q-tree__node-header-content .q-icon { + font-size: 21px +} + +.q-tree__img { + height : 42px; + border-radius: 2px +} + +.q-tree__avatar, +.q-tree__node-header-content .q-avatar { + font-size : 28px; + border-radius: 50%; + width : 28px; + height : 28px +} + +.q-tree__arrow, +.q-tree__spinner { + font-size : 16px; + margin-right: 4px +} + +.q-tree__arrow { + transition: transform 0.3s +} + +.q-tree__arrow--rotate { + transform: rotate3d(0, 0, 1, 90deg) +} + +.q-tree__tickbox { + margin-right: 4px +} + +.q-tree>.q-tree__node { + padding: 0 +} + +.q-tree>.q-tree__node:after, +.q-tree>.q-tree__node>.q-tree__node-header:before { + display: none +} + +.q-tree>.q-tree__node--child>.q-tree__node-header { + padding-left: 24px +} + +.q-tree--dark .q-tree__node-header-content { + color: #fff +} + +.q-tree--no-connectors .q-tree__node-body:after, +.q-tree--no-connectors .q-tree__node-header:before, +.q-tree--no-connectors .q-tree__node:after { + display: none !important +} + +.q-tree--dense>.q-tree__node--child>.q-tree__node-header { + padding-left: 1px +} + +.q-tree--dense .q-tree__arrow, +.q-tree--dense .q-tree__spinner { + margin-right: 1px +} + +.q-tree--dense .q-tree__img { + height: 32px +} + +.q-tree--dense .q-tree__tickbox { + margin-right: 3px +} + +.q-tree--dense .q-tree__node { + padding: 0 +} + +.q-tree--dense .q-tree__node:after { + top : 0; + left: -8px +} + +.q-tree--dense .q-tree__node-header { + margin-top: 0; + padding : 1px +} + +.q-tree--dense .q-tree__node-header:before { + top : 0; + left : -8px; + width: 8px +} + +.q-tree--dense .q-tree__node--child { + padding-left: 17px +} + +.q-tree--dense .q-tree__node--child>.q-tree__node-header:before { + left : -25px; + width: 21px +} + +.q-tree--dense .q-tree__node-body { + padding: 0 0 2px +} + +.q-tree--dense .q-tree__node--parent>.q-tree__node-collapsible>.q-tree__node-body { + padding: 0 0 2px 20px +} + +.q-tree--dense .q-tree__node--parent>.q-tree__node-collapsible>.q-tree__node-body:after { + left: 8px +} + +.q-tree--dense .q-tree__children { + padding-left: 16px +} + +[dir=rtl] .q-tree__arrow { + transform: rotate3d(0, 0, 1, 180deg) +} + +[dir=rtl] .q-tree__arrow--rotate { + transform: rotate3d(0, 0, 1, 90deg) +} + +.q-uploader { + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + border-radius : 4px; + vertical-align: top; + background : #fff; + position : relative; + width : 320px; + max-height : 320px +} + +.q-uploader--bordered { + border: 1px solid rgba(0, 0, 0, 0.12) +} + +.q-uploader__input { + opacity: 0; + width : 100%; + height : 100%; + cursor : pointer !important; + z-index: 1 +} + +.q-uploader__input::-webkit-file-upload-button { + cursor: pointer +} + +.q-uploader__file:before { + content : ""; + position : absolute; + top : 0; + right : 0; + bottom : 0; + left : 0; + pointer-events: none; + background : currentColor; + opacity : 0.04 +} + +.q-uploader__file:before, +.q-uploader__header { + border-top-left-radius : inherit; + border-top-right-radius: inherit +} + +.q-uploader__header { + position : relative; + background-color: #1976d2; + background-color: var(--q-color-primary); + color : #fff; + width : 100% +} + +.q-uploader__spinner { + font-size : 24px; + margin-right: 4px +} + +.q-uploader__header-content { + padding: 8px +} + +.q-uploader__dnd { + outline : 1px dashed currentColor; + outline-offset: -4px; + background : hsla(0, 0%, 100%, 0.6) +} + +.q-uploader__overlay { + font-size : 36px; + color : #000; + background-color: hsla(0, 0%, 100%, 0.6) +} + +.q-uploader__list { + position : relative; + border-bottom-left-radius : inherit; + border-bottom-right-radius: inherit; + padding : 8px; + min-height : 60px; + flex : 1 1 auto +} + +.q-uploader__file { + border-radius: 4px 4px 0 0; + border : 1px solid rgba(0, 0, 0, 0.12) +} + +.q-uploader__file .q-circular-progress { + font-size: 24px +} + +.q-uploader__file--img { + color : #fff; + height : 200px; + min-width : 200px; + background-position: 50% 50%; + background-size : cover; + background-repeat : no-repeat +} + +.q-uploader__file--img:before { + content: none +} + +.q-uploader__file--img .q-circular-progress { + color: #fff +} + +.q-uploader__file--img .q-uploader__file-header { + padding-bottom: 24px; + background : linear-gradient(180deg, rgba(0, 0, 0, 0.7) 20%, hsla(0, 0%, 100%, 0)) +} + +.q-uploader__file+.q-uploader__file { + margin-top: 8px +} + +.q-uploader__file-header { + position : relative; + padding : 4px 8px; + border-top-left-radius : inherit; + border-top-right-radius: inherit +} + +.q-uploader__file-header-content { + padding-right: 8px +} + +.q-uploader__file-status { + font-size : 24px; + margin-right: 4px +} + +.q-uploader__title { + font-size : 14px; + font-weight: 700; + line-height: 18px; + word-break : break-word +} + +.q-uploader__subtitle { + font-size : 12px; + line-height: 18px +} + +.q-uploader--disable .q-uploader__header, +.q-uploader--disable .q-uploader__list { + pointer-events: none +} + +.q-uploader--dark, +.q-uploader--dark .q-uploader__file { + border-color: hsla(0, 0%, 100%, 0.28) +} + +.q-uploader--dark .q-uploader__dnd, +.q-uploader--dark .q-uploader__overlay { + background: hsla(0, 0%, 100%, 0.3) +} + +.q-uploader--dark .q-uploader__overlay { + color: #fff +} + +.q-video { + position : relative; + overflow : hidden; + border-radius: inherit +} + +.q-video embed, +.q-video iframe, +.q-video object { + width : 100%; + height: 100% +} + +.q-video--responsive { + height: 0 +} + +.q-video--responsive embed, +.q-video--responsive iframe, +.q-video--responsive object { + position: absolute; + top : 0; + left : 0 +} + +.q-virtual-scroll:focus { + outline: 0 +} + +.q-virtual-scroll__content { + outline: none; + contain: content +} + +.q-virtual-scroll__content>* { + overflow-anchor: none +} + +.q-virtual-scroll__content>[data-q-vs-anchor] { + overflow-anchor: auto +} + +.q-virtual-scroll__padding { + background : linear-gradient(hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, 0) 20%, hsla(0, 0%, 50.2%, 0.03) 0, hsla(0, 0%, 50.2%, 0.08) 50%, hsla(0, 0%, 50.2%, 0.03) 80%, hsla(0, 0%, 100%, 0) 0, hsla(0, 0%, 100%, 0)); + background-size: 100% 50px; + background-size: var(--q-virtual-scroll-item-width, 100%) var(--q-virtual-scroll-item-height, 50px) +} + +.q-table .q-virtual-scroll__padding tr { + height: 0 !important +} + +.q-table .q-virtual-scroll__padding td { + padding: 0 !important +} + +.q-virtual-scroll--horizontal { + align-items: stretch +} + +.q-virtual-scroll--horizontal, +.q-virtual-scroll--horizontal .q-virtual-scroll__content { + display : flex; + flex-direction: row; + flex-wrap : nowrap +} + +.q-virtual-scroll--horizontal .q-virtual-scroll__content, +.q-virtual-scroll--horizontal .q-virtual-scroll__content>*, +.q-virtual-scroll--horizontal .q-virtual-scroll__padding { + flex: 0 0 auto +} + +.q-virtual-scroll--horizontal .q-virtual-scroll__padding { + background : linear-gradient(270deg, hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, 0) 20%, hsla(0, 0%, 50.2%, 0.03) 0, hsla(0, 0%, 50.2%, 0.08) 50%, hsla(0, 0%, 50.2%, 0.03) 80%, hsla(0, 0%, 100%, 0) 0, hsla(0, 0%, 100%, 0)); + background-size: 50px 100%; + background-size: var(--q-virtual-scroll-item-width, 50px) var(--q-virtual-scroll-item-height, 100%) +} + +.q-ripple { + width : 100%; + height : 100%; + border-radius: inherit; + z-index : 0; + overflow : hidden; + contain : strict +} + +.q-ripple, +.q-ripple__inner { + position : absolute; + top : 0; + left : 0; + color : inherit; + pointer-events: none +} + +.q-ripple__inner { + opacity : 0; + border-radius: 50%; + background : currentColor; + will-change : transform, opacity +} + +.q-ripple__inner--enter { + transition: transform 0.225s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.1s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-ripple__inner--leave { + transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1) +} + +.q-morph--internal, +.q-morph--invisible { + opacity : 0 !important; + pointer-events: none !important; + position : fixed !important; + right : 200vw !important; + bottom : 200vh !important +} + +.q-loading { + color : #000; + position: fixed !important +} + +.q-loading:before { + content : ""; + position : fixed; + top : 0; + right : 0; + bottom : 0; + left : 0; + background: currentColor; + opacity : 0.5; + z-index : -1 +} + +.q-loading>div { + margin : 40px 20px 0; + max-width : 450px; + text-align: center +} + +.q-notifications__list { + z-index : 9500; + pointer-events: none; + left : 0; + right : 0; + margin-bottom : 10px; + position : relative +} + +.q-notifications__list--center { + top : 0; + bottom: 0 +} + +.q-notifications__list--top { + top: 0 +} + +.q-notifications__list--bottom { + bottom: 0 +} + +body.q-ios-padding .q-notifications__list--center, +body.q-ios-padding .q-notifications__list--top { + top: 20px; + top: env(safe-area-inset-top) +} + +body.q-ios-padding .q-notifications__list--bottom, +body.q-ios-padding .q-notifications__list--center { + bottom: env(safe-area-inset-bottom) +} + +.q-notification { + box-shadow : 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); + border-radius : 4px; + pointer-events: all; + display : inline-flex; + margin : 10px 10px 0; + transition : transform 1s, opacity 1s; + z-index : 9500; + flex-shrink : 0; + max-width : 95vw; + background : #323232; + color : #fff; + font-size : 14px +} + +.q-notification__icon { + font-size: 24px; + flex : 0 0 1em +} + +.q-notification__icon--additional { + margin-right: 16px +} + +.q-notification__avatar { + font-size: 32px +} + +.q-notification__avatar--additional { + margin-right: 8px +} + +.q-notification__spinner { + font-size: 32px +} + +.q-notification__spinner--additional { + margin-right: 8px +} + +.q-notification__message { + padding: 8px 0 +} + +.q-notification__caption { + font-size: 0.9em; + opacity : 0.7 +} + +.q-notification__actions { + color: #1976d2; + color: var(--q-color-primary) +} + +.q-notification__badge { + -webkit-animation: q-notif-badge 0.42s; + animation : q-notif-badge 0.42s; + padding : 4px 8px; + position : absolute; + background : #c10015; + box-shadow : 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12); + background-color : #c10015; + background-color : var(--q-color-negative); + color : #fff; + border-radius : 4px; + font-size : 12px; + line-height : 12px +} + +.q-notification__badge--top-left, +.q-notification__badge--top-right { + top: -6px +} + +.q-notification__badge--bottom-left, +.q-notification__badge--bottom-right { + bottom: -6px +} + +.q-notification__badge--bottom-left, +.q-notification__badge--top-left { + left: -22px +} + +.q-notification__badge--bottom-right, +.q-notification__badge--top-right { + right: -22px +} + +.q-notification__progress { + z-index : -1; + position : absolute; + height : 3px; + bottom : 0; + left : -10px; + right : -10px; + -webkit-animation: q-notif-progress linear; + animation : q-notif-progress linear; + background : currentColor; + opacity : 0.3; + border-radius : 4px 4px 0 0; + transform-origin : 0 50%; + transform : scaleX(0) +} + +.q-notification--standard { + padding : 0 16px; + min-height: 48px +} + +.q-notification--standard .q-notification__actions { + padding : 6px 0 6px 8px; + margin-right: -8px +} + +.q-notification--multi-line { + min-height: 68px; + padding : 8px 16px +} + +.q-notification--multi-line .q-notification__badge--top-left, +.q-notification--multi-line .q-notification__badge--top-right { + top: -15px +} + +.q-notification--multi-line .q-notification__badge--bottom-left, +.q-notification--multi-line .q-notification__badge--bottom-right { + bottom: -15px +} + +.q-notification--multi-line .q-notification__progress { + bottom: -8px +} + +.q-notification--multi-line .q-notification__actions { + padding: 0 +} + +.q-notification--multi-line .q-notification__actions--with-media { + padding-left: 25px +} + +.q-notification--top-enter, +.q-notification--top-leave-to, +.q-notification--top-left-enter, +.q-notification--top-left-leave-to, +.q-notification--top-right-enter, +.q-notification--top-right-leave-to { + opacity : 0; + transform: translateY(-50px); + z-index : 9499 +} + +.q-notification--center-enter, +.q-notification--center-leave-to, +.q-notification--left-enter, +.q-notification--left-leave-to, +.q-notification--right-enter, +.q-notification--right-leave-to { + opacity : 0; + transform: rotateX(90deg); + z-index : 9499 +} + +.q-notification--bottom-enter, +.q-notification--bottom-leave-to, +.q-notification--bottom-left-enter, +.q-notification--bottom-left-leave-to, +.q-notification--bottom-right-enter, +.q-notification--bottom-right-leave-to { + opacity : 0; + transform: translateY(50px); + z-index : 9499 +} + +.q-notification--bottom-leave-active, +.q-notification--bottom-left-leave-active, +.q-notification--bottom-right-leave-active, +.q-notification--center-leave-active, +.q-notification--left-leave-active, +.q-notification--right-leave-active, +.q-notification--top-leave-active, +.q-notification--top-left-leave-active, +.q-notification--top-right-leave-active { + position : absolute; + z-index : 9499; + margin-left : 0; + margin-right: 0 +} + +.q-notification--center-leave-active, +.q-notification--top-leave-active { + top: 0 +} + +.q-notification--bottom-leave-active, +.q-notification--bottom-left-leave-active, +.q-notification--bottom-right-leave-active { + bottom: 0 +} + +@media (min-width:600px) { + .q-notification { + max-width: 65vw + } +} + +:root { + --animate-duration: 0.3s; + --animate-delay : 0.3s; + --animate-repeat : 1 +} + +.animated { + -webkit-animation-duration : var(--animate-duration); + animation-duration : var(--animate-duration); + -webkit-animation-fill-mode: both; + animation-fill-mode : both +} + +.animated.infinite { + -webkit-animation-iteration-count: infinite; + animation-iteration-count : infinite +} + +.animated.hinge { + -webkit-animation-duration: 2s; + animation-duration : 2s +} + +.animated.repeat-1 { + -webkit-animation-iteration-count: var(--animate-repeat); + animation-iteration-count : var(--animate-repeat) +} + +.animated.repeat-2 { + -webkit-animation-iteration-count: calc(var(--animate-repeat)*2); + animation-iteration-count : calc(var(--animate-repeat)*2) +} + +.animated.repeat-3 { + -webkit-animation-iteration-count: calc(var(--animate-repeat)*3); + animation-iteration-count : calc(var(--animate-repeat)*3) +} + +.animated.delay-1s { + -webkit-animation-delay: var(--animate-delay); + animation-delay : var(--animate-delay) +} + +.animated.delay-2s { + -webkit-animation-delay: calc(var(--animate-delay)*2); + animation-delay : calc(var(--animate-delay)*2) +} + +.animated.delay-3s { + -webkit-animation-delay: calc(var(--animate-delay)*3); + animation-delay : calc(var(--animate-delay)*3) +} + +.animated.delay-4s { + -webkit-animation-delay: calc(var(--animate-delay)*4); + animation-delay : calc(var(--animate-delay)*4) +} + +.animated.delay-5s { + -webkit-animation-delay: calc(var(--animate-delay)*5); + animation-delay : calc(var(--animate-delay)*5) +} + +.animated.faster { + -webkit-animation-duration: calc(var(--animate-duration)/2); + animation-duration : calc(var(--animate-duration)/2) +} + +.animated.fast { + -webkit-animation-duration: calc(var(--animate-duration)*0.8); + animation-duration : calc(var(--animate-duration)*0.8) +} + +.animated.slow { + -webkit-animation-duration: calc(var(--animate-duration)*2); + animation-duration : calc(var(--animate-duration)*2) +} + +.animated.slower { + -webkit-animation-duration: calc(var(--animate-duration)*3); + animation-duration : calc(var(--animate-duration)*3) +} + +@media (prefers-reduced-motion:reduce), +print { + .animated { + -webkit-animation-duration : 1ms !important; + animation-duration : 1ms !important; + transition-duration : 1ms !important; + -webkit-animation-iteration-count: 1 !important; + animation-iteration-count : 1 !important + } + + .animated[class*=Out] { + opacity: 0 + } +} + +.q-animate--scale { + -webkit-animation : q-scale 0.15s; + animation : q-scale 0.15s; + -webkit-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1); + animation-timing-function : cubic-bezier(0.25, 0.8, 0.25, 1) +} + +.q-animate--fade { + -webkit-animation: q-fade 0.2s; + animation : q-fade 0.2s +} + +:root { + --q-color-primary : #1976d2; + --q-color-secondary: #26a69a; + --q-color-accent : #9c27b0; + --q-color-positive : #21ba45; + --q-color-negative : #c10015; + --q-color-info : #31ccec; + --q-color-warning : #f2c037; + --q-color-dark : #1d1d1d; + --q-color-dark-page: #121212 +} + +.text-dark { + color: #1d1d1d !important; + color: var(--q-color-dark) !important +} + +.bg-dark { + background: #1d1d1d !important; + background: var(--q-color-dark) !important +} + +.text-primary { + color: #1976d2 !important; + color: var(--q-color-primary) !important +} + +.bg-primary { + background: #1976d2 !important; + background: var(--q-color-primary) !important +} + +.text-secondary { + color: #26a69a !important; + color: var(--q-color-secondary) !important +} + +.bg-secondary { + background: #26a69a !important; + background: var(--q-color-secondary) !important +} + +.text-accent { + color: #9c27b0 !important; + color: var(--q-color-accent) !important +} + +.bg-accent { + background: #9c27b0 !important; + background: var(--q-color-accent) !important +} + +.text-positive { + color: #21ba45 !important; + color: var(--q-color-positive) !important +} + +.bg-positive { + background: #21ba45 !important; + background: var(--q-color-positive) !important +} + +.text-negative { + color: #c10015 !important; + color: var(--q-color-negative) !important +} + +.bg-negative { + background: #c10015 !important; + background: var(--q-color-negative) !important +} + +.text-info { + color: #31ccec !important; + color: var(--q-color-info) !important +} + +.bg-info { + background: #31ccec !important; + background: var(--q-color-info) !important +} + +.text-warning { + color: #f2c037 !important; + color: var(--q-color-warning) !important +} + +.bg-warning { + background: #f2c037 !important; + background: var(--q-color-warning) !important +} + +.text-white { + color: #fff !important +} + +.bg-white { + background: #fff !important +} + +.text-black { + color: #000 !important +} + +.bg-black { + background: #000 !important +} + +.text-transparent { + color: transparent !important +} + +.bg-transparent { + background: transparent !important +} + +.text-separator { + color: rgba(0, 0, 0, 0.12) !important +} + +.bg-separator { + background: rgba(0, 0, 0, 0.12) !important +} + +.text-dark-separator { + color: hsla(0, 0%, 100%, 0.28) !important +} + +.bg-dark-separator { + background: hsla(0, 0%, 100%, 0.28) !important +} + +.text-red { + color: #f44336 !important +} + +.text-red-1 { + color: #ffebee !important +} + +.text-red-2 { + color: #ffcdd2 !important +} + +.text-red-3 { + color: #ef9a9a !important +} + +.text-red-4 { + color: #e57373 !important +} + +.text-red-5 { + color: #ef5350 !important +} + +.text-red-6 { + color: #f44336 !important +} + +.text-red-7 { + color: #e53935 !important +} + +.text-red-8 { + color: #d32f2f !important +} + +.text-red-9 { + color: #c62828 !important +} + +.text-red-10 { + color: #b71c1c !important +} + +.text-red-11 { + color: #ff8a80 !important +} + +.text-red-12 { + color: #ff5252 !important +} + +.text-red-13 { + color: #ff1744 !important +} + +.text-red-14 { + color: #d50000 !important +} + +.text-pink { + color: #e91e63 !important +} + +.text-pink-1 { + color: #fce4ec !important +} + +.text-pink-2 { + color: #f8bbd0 !important +} + +.text-pink-3 { + color: #f48fb1 !important +} + +.text-pink-4 { + color: #f06292 !important +} + +.text-pink-5 { + color: #ec407a !important +} + +.text-pink-6 { + color: #e91e63 !important +} + +.text-pink-7 { + color: #d81b60 !important +} + +.text-pink-8 { + color: #c2185b !important +} + +.text-pink-9 { + color: #ad1457 !important +} + +.text-pink-10 { + color: #880e4f !important +} + +.text-pink-11 { + color: #ff80ab !important +} + +.text-pink-12 { + color: #ff4081 !important +} + +.text-pink-13 { + color: #f50057 !important +} + +.text-pink-14 { + color: #c51162 !important +} + +.text-purple { + color: #9c27b0 !important +} + +.text-purple-1 { + color: #f3e5f5 !important +} + +.text-purple-2 { + color: #e1bee7 !important +} + +.text-purple-3 { + color: #ce93d8 !important +} + +.text-purple-4 { + color: #ba68c8 !important +} + +.text-purple-5 { + color: #ab47bc !important +} + +.text-purple-6 { + color: #9c27b0 !important +} + +.text-purple-7 { + color: #8e24aa !important +} + +.text-purple-8 { + color: #7b1fa2 !important +} + +.text-purple-9 { + color: #6a1b9a !important +} + +.text-purple-10 { + color: #4a148c !important +} + +.text-purple-11 { + color: #ea80fc !important +} + +.text-purple-12 { + color: #e040fb !important +} + +.text-purple-13 { + color: #d500f9 !important +} + +.text-purple-14 { + color: #a0f !important +} + +.text-deep-purple { + color: #673ab7 !important +} + +.text-deep-purple-1 { + color: #ede7f6 !important +} + +.text-deep-purple-2 { + color: #d1c4e9 !important +} + +.text-deep-purple-3 { + color: #b39ddb !important +} + +.text-deep-purple-4 { + color: #9575cd !important +} + +.text-deep-purple-5 { + color: #7e57c2 !important +} + +.text-deep-purple-6 { + color: #673ab7 !important +} + +.text-deep-purple-7 { + color: #5e35b1 !important +} + +.text-deep-purple-8 { + color: #512da8 !important +} + +.text-deep-purple-9 { + color: #4527a0 !important +} + +.text-deep-purple-10 { + color: #311b92 !important +} + +.text-deep-purple-11 { + color: #b388ff !important +} + +.text-deep-purple-12 { + color: #7c4dff !important +} + +.text-deep-purple-13 { + color: #651fff !important +} + +.text-deep-purple-14 { + color: #6200ea !important +} + +.text-indigo { + color: #3f51b5 !important +} + +.text-indigo-1 { + color: #e8eaf6 !important +} + +.text-indigo-2 { + color: #c5cae9 !important +} + +.text-indigo-3 { + color: #9fa8da !important +} + +.text-indigo-4 { + color: #7986cb !important +} + +.text-indigo-5 { + color: #5c6bc0 !important +} + +.text-indigo-6 { + color: #3f51b5 !important +} + +.text-indigo-7 { + color: #3949ab !important +} + +.text-indigo-8 { + color: #303f9f !important +} + +.text-indigo-9 { + color: #283593 !important +} + +.text-indigo-10 { + color: #1a237e !important +} + +.text-indigo-11 { + color: #8c9eff !important +} + +.text-indigo-12 { + color: #536dfe !important +} + +.text-indigo-13 { + color: #3d5afe !important +} + +.text-indigo-14 { + color: #304ffe !important +} + +.text-blue { + color: #2196f3 !important +} + +.text-blue-1 { + color: #e3f2fd !important +} + +.text-blue-2 { + color: #bbdefb !important +} + +.text-blue-3 { + color: #90caf9 !important +} + +.text-blue-4 { + color: #64b5f6 !important +} + +.text-blue-5 { + color: #42a5f5 !important +} + +.text-blue-6 { + color: #2196f3 !important +} + +.text-blue-7 { + color: #1e88e5 !important +} + +.text-blue-8 { + color: #1976d2 !important +} + +.text-blue-9 { + color: #1565c0 !important +} + +.text-blue-10 { + color: #0d47a1 !important +} + +.text-blue-11 { + color: #82b1ff !important +} + +.text-blue-12 { + color: #448aff !important +} + +.text-blue-13 { + color: #2979ff !important +} + +.text-blue-14 { + color: #2962ff !important +} + +.text-light-blue { + color: #03a9f4 !important +} + +.text-light-blue-1 { + color: #e1f5fe !important +} + +.text-light-blue-2 { + color: #b3e5fc !important +} + +.text-light-blue-3 { + color: #81d4fa !important +} + +.text-light-blue-4 { + color: #4fc3f7 !important +} + +.text-light-blue-5 { + color: #29b6f6 !important +} + +.text-light-blue-6 { + color: #03a9f4 !important +} + +.text-light-blue-7 { + color: #039be5 !important +} + +.text-light-blue-8 { + color: #0288d1 !important +} + +.text-light-blue-9 { + color: #0277bd !important +} + +.text-light-blue-10 { + color: #01579b !important +} + +.text-light-blue-11 { + color: #80d8ff !important +} + +.text-light-blue-12 { + color: #40c4ff !important +} + +.text-light-blue-13 { + color: #00b0ff !important +} + +.text-light-blue-14 { + color: #0091ea !important +} + +.text-cyan { + color: #00bcd4 !important +} + +.text-cyan-1 { + color: #e0f7fa !important +} + +.text-cyan-2 { + color: #b2ebf2 !important +} + +.text-cyan-3 { + color: #80deea !important +} + +.text-cyan-4 { + color: #4dd0e1 !important +} + +.text-cyan-5 { + color: #26c6da !important +} + +.text-cyan-6 { + color: #00bcd4 !important +} + +.text-cyan-7 { + color: #00acc1 !important +} + +.text-cyan-8 { + color: #0097a7 !important +} + +.text-cyan-9 { + color: #00838f !important +} + +.text-cyan-10 { + color: #006064 !important +} + +.text-cyan-11 { + color: #84ffff !important +} + +.text-cyan-12 { + color: #18ffff !important +} + +.text-cyan-13 { + color: #00e5ff !important +} + +.text-cyan-14 { + color: #00b8d4 !important +} + +.text-teal { + color: #009688 !important +} + +.text-teal-1 { + color: #e0f2f1 !important +} + +.text-teal-2 { + color: #b2dfdb !important +} + +.text-teal-3 { + color: #80cbc4 !important +} + +.text-teal-4 { + color: #4db6ac !important +} + +.text-teal-5 { + color: #26a69a !important +} + +.text-teal-6 { + color: #009688 !important +} + +.text-teal-7 { + color: #00897b !important +} + +.text-teal-8 { + color: #00796b !important +} + +.text-teal-9 { + color: #00695c !important +} + +.text-teal-10 { + color: #004d40 !important +} + +.text-teal-11 { + color: #a7ffeb !important +} + +.text-teal-12 { + color: #64ffda !important +} + +.text-teal-13 { + color: #1de9b6 !important +} + +.text-teal-14 { + color: #00bfa5 !important +} + +.text-green { + color: #4caf50 !important +} + +.text-green-1 { + color: #e8f5e9 !important +} + +.text-green-2 { + color: #c8e6c9 !important +} + +.text-green-3 { + color: #a5d6a7 !important +} + +.text-green-4 { + color: #81c784 !important +} + +.text-green-5 { + color: #66bb6a !important +} + +.text-green-6 { + color: #4caf50 !important +} + +.text-green-7 { + color: #43a047 !important +} + +.text-green-8 { + color: #388e3c !important +} + +.text-green-9 { + color: #2e7d32 !important +} + +.text-green-10 { + color: #1b5e20 !important +} + +.text-green-11 { + color: #b9f6ca !important +} + +.text-green-12 { + color: #69f0ae !important +} + +.text-green-13 { + color: #00e676 !important +} + +.text-green-14 { + color: #00c853 !important +} + +.text-light-green { + color: #8bc34a !important +} + +.text-light-green-1 { + color: #f1f8e9 !important +} + +.text-light-green-2 { + color: #dcedc8 !important +} + +.text-light-green-3 { + color: #c5e1a5 !important +} + +.text-light-green-4 { + color: #aed581 !important +} + +.text-light-green-5 { + color: #9ccc65 !important +} + +.text-light-green-6 { + color: #8bc34a !important +} + +.text-light-green-7 { + color: #7cb342 !important +} + +.text-light-green-8 { + color: #689f38 !important +} + +.text-light-green-9 { + color: #558b2f !important +} + +.text-light-green-10 { + color: #33691e !important +} + +.text-light-green-11 { + color: #ccff90 !important +} + +.text-light-green-12 { + color: #b2ff59 !important +} + +.text-light-green-13 { + color: #76ff03 !important +} + +.text-light-green-14 { + color: #64dd17 !important +} + +.text-lime { + color: #cddc39 !important +} + +.text-lime-1 { + color: #f9fbe7 !important +} + +.text-lime-2 { + color: #f0f4c3 !important +} + +.text-lime-3 { + color: #e6ee9c !important +} + +.text-lime-4 { + color: #dce775 !important +} + +.text-lime-5 { + color: #d4e157 !important +} + +.text-lime-6 { + color: #cddc39 !important +} + +.text-lime-7 { + color: #c0ca33 !important +} + +.text-lime-8 { + color: #afb42b !important +} + +.text-lime-9 { + color: #9e9d24 !important +} + +.text-lime-10 { + color: #827717 !important +} + +.text-lime-11 { + color: #f4ff81 !important +} + +.text-lime-12 { + color: #eeff41 !important +} + +.text-lime-13 { + color: #c6ff00 !important +} + +.text-lime-14 { + color: #aeea00 !important +} + +.text-yellow { + color: #ffeb3b !important +} + +.text-yellow-1 { + color: #fffde7 !important +} + +.text-yellow-2 { + color: #fff9c4 !important +} + +.text-yellow-3 { + color: #fff59d !important +} + +.text-yellow-4 { + color: #fff176 !important +} + +.text-yellow-5 { + color: #ffee58 !important +} + +.text-yellow-6 { + color: #ffeb3b !important +} + +.text-yellow-7 { + color: #fdd835 !important +} + +.text-yellow-8 { + color: #fbc02d !important +} + +.text-yellow-9 { + color: #f9a825 !important +} + +.text-yellow-10 { + color: #f57f17 !important +} + +.text-yellow-11 { + color: #ffff8d !important +} + +.text-yellow-12 { + color: #ff0 !important +} + +.text-yellow-13 { + color: #ffea00 !important +} + +.text-yellow-14 { + color: #ffd600 !important +} + +.text-amber { + color: #ffc107 !important +} + +.text-amber-1 { + color: #fff8e1 !important +} + +.text-amber-2 { + color: #ffecb3 !important +} + +.text-amber-3 { + color: #ffe082 !important +} + +.text-amber-4 { + color: #ffd54f !important +} + +.text-amber-5 { + color: #ffca28 !important +} + +.text-amber-6 { + color: #ffc107 !important +} + +.text-amber-7 { + color: #ffb300 !important +} + +.text-amber-8 { + color: #ffa000 !important +} + +.text-amber-9 { + color: #ff8f00 !important +} + +.text-amber-10 { + color: #ff6f00 !important +} + +.text-amber-11 { + color: #ffe57f !important +} + +.text-amber-12 { + color: #ffd740 !important +} + +.text-amber-13 { + color: #ffc400 !important +} + +.text-amber-14 { + color: #ffab00 !important +} + +.text-orange { + color: #ff9800 !important +} + +.text-orange-1 { + color: #fff3e0 !important +} + +.text-orange-2 { + color: #ffe0b2 !important +} + +.text-orange-3 { + color: #ffcc80 !important +} + +.text-orange-4 { + color: #ffb74d !important +} + +.text-orange-5 { + color: #ffa726 !important +} + +.text-orange-6 { + color: #ff9800 !important +} + +.text-orange-7 { + color: #fb8c00 !important +} + +.text-orange-8 { + color: #f57c00 !important +} + +.text-orange-9 { + color: #ef6c00 !important +} + +.text-orange-10 { + color: #e65100 !important +} + +.text-orange-11 { + color: #ffd180 !important +} + +.text-orange-12 { + color: #ffab40 !important +} + +.text-orange-13 { + color: #ff9100 !important +} + +.text-orange-14 { + color: #ff6d00 !important +} + +.text-deep-orange { + color: #ff5722 !important +} + +.text-deep-orange-1 { + color: #fbe9e7 !important +} + +.text-deep-orange-2 { + color: #ffccbc !important +} + +.text-deep-orange-3 { + color: #ffab91 !important +} + +.text-deep-orange-4 { + color: #ff8a65 !important +} + +.text-deep-orange-5 { + color: #ff7043 !important +} + +.text-deep-orange-6 { + color: #ff5722 !important +} + +.text-deep-orange-7 { + color: #f4511e !important +} + +.text-deep-orange-8 { + color: #e64a19 !important +} + +.text-deep-orange-9 { + color: #d84315 !important +} + +.text-deep-orange-10 { + color: #bf360c !important +} + +.text-deep-orange-11 { + color: #ff9e80 !important +} + +.text-deep-orange-12 { + color: #ff6e40 !important +} + +.text-deep-orange-13 { + color: #ff3d00 !important +} + +.text-deep-orange-14 { + color: #dd2c00 !important +} + +.text-brown { + color: #795548 !important +} + +.text-brown-1 { + color: #efebe9 !important +} + +.text-brown-2 { + color: #d7ccc8 !important +} + +.text-brown-3 { + color: #bcaaa4 !important +} + +.text-brown-4 { + color: #a1887f !important +} + +.text-brown-5 { + color: #8d6e63 !important +} + +.text-brown-6 { + color: #795548 !important +} + +.text-brown-7 { + color: #6d4c41 !important +} + +.text-brown-8 { + color: #5d4037 !important +} + +.text-brown-9 { + color: #4e342e !important +} + +.text-brown-10 { + color: #3e2723 !important +} + +.text-brown-11 { + color: #d7ccc8 !important +} + +.text-brown-12 { + color: #bcaaa4 !important +} + +.text-brown-13 { + color: #8d6e63 !important +} + +.text-brown-14 { + color: #5d4037 !important +} + +.text-grey { + color: #9e9e9e !important +} + +.text-grey-1 { + color: #fafafa !important +} + +.text-grey-2 { + color: #f5f5f5 !important +} + +.text-grey-3 { + color: #eee !important +} + +.text-grey-4 { + color: #e0e0e0 !important +} + +.text-grey-5 { + color: #bdbdbd !important +} + +.text-grey-6 { + color: #9e9e9e !important +} + +.text-grey-7 { + color: #757575 !important +} + +.text-grey-8 { + color: #616161 !important +} + +.text-grey-9 { + color: #424242 !important +} + +.text-grey-10 { + color: #212121 !important +} + +.text-grey-11 { + color: #f5f5f5 !important +} + +.text-grey-12 { + color: #eee !important +} + +.text-grey-13 { + color: #bdbdbd !important +} + +.text-grey-14 { + color: #616161 !important +} + +.text-blue-grey { + color: #607d8b !important +} + +.text-blue-grey-1 { + color: #eceff1 !important +} + +.text-blue-grey-2 { + color: #cfd8dc !important +} + +.text-blue-grey-3 { + color: #b0bec5 !important +} + +.text-blue-grey-4 { + color: #90a4ae !important +} + +.text-blue-grey-5 { + color: #78909c !important +} + +.text-blue-grey-6 { + color: #607d8b !important +} + +.text-blue-grey-7 { + color: #546e7a !important +} + +.text-blue-grey-8 { + color: #455a64 !important +} + +.text-blue-grey-9 { + color: #37474f !important +} + +.text-blue-grey-10 { + color: #263238 !important +} + +.text-blue-grey-11 { + color: #cfd8dc !important +} + +.text-blue-grey-12 { + color: #b0bec5 !important +} + +.text-blue-grey-13 { + color: #78909c !important +} + +.text-blue-grey-14 { + color: #455a64 !important +} + +.bg-red { + background: #f44336 !important +} + +.bg-red-1 { + background: #ffebee !important +} + +.bg-red-2 { + background: #ffcdd2 !important +} + +.bg-red-3 { + background: #ef9a9a !important +} + +.bg-red-4 { + background: #e57373 !important +} + +.bg-red-5 { + background: #ef5350 !important +} + +.bg-red-6 { + background: #f44336 !important +} + +.bg-red-7 { + background: #e53935 !important +} + +.bg-red-8 { + background: #d32f2f !important +} + +.bg-red-9 { + background: #c62828 !important +} + +.bg-red-10 { + background: #b71c1c !important +} + +.bg-red-11 { + background: #ff8a80 !important +} + +.bg-red-12 { + background: #ff5252 !important +} + +.bg-red-13 { + background: #ff1744 !important +} + +.bg-red-14 { + background: #d50000 !important +} + +.bg-pink { + background: #e91e63 !important +} + +.bg-pink-1 { + background: #fce4ec !important +} + +.bg-pink-2 { + background: #f8bbd0 !important +} + +.bg-pink-3 { + background: #f48fb1 !important +} + +.bg-pink-4 { + background: #f06292 !important +} + +.bg-pink-5 { + background: #ec407a !important +} + +.bg-pink-6 { + background: #e91e63 !important +} + +.bg-pink-7 { + background: #d81b60 !important +} + +.bg-pink-8 { + background: #c2185b !important +} + +.bg-pink-9 { + background: #ad1457 !important +} + +.bg-pink-10 { + background: #880e4f !important +} + +.bg-pink-11 { + background: #ff80ab !important +} + +.bg-pink-12 { + background: #ff4081 !important +} + +.bg-pink-13 { + background: #f50057 !important +} + +.bg-pink-14 { + background: #c51162 !important +} + +.bg-purple { + background: #9c27b0 !important +} + +.bg-purple-1 { + background: #f3e5f5 !important +} + +.bg-purple-2 { + background: #e1bee7 !important +} + +.bg-purple-3 { + background: #ce93d8 !important +} + +.bg-purple-4 { + background: #ba68c8 !important +} + +.bg-purple-5 { + background: #ab47bc !important +} + +.bg-purple-6 { + background: #9c27b0 !important +} + +.bg-purple-7 { + background: #8e24aa !important +} + +.bg-purple-8 { + background: #7b1fa2 !important +} + +.bg-purple-9 { + background: #6a1b9a !important +} + +.bg-purple-10 { + background: #4a148c !important +} + +.bg-purple-11 { + background: #ea80fc !important +} + +.bg-purple-12 { + background: #e040fb !important +} + +.bg-purple-13 { + background: #d500f9 !important +} + +.bg-purple-14 { + background: #a0f !important +} + +.bg-deep-purple { + background: #673ab7 !important +} + +.bg-deep-purple-1 { + background: #ede7f6 !important +} + +.bg-deep-purple-2 { + background: #d1c4e9 !important +} + +.bg-deep-purple-3 { + background: #b39ddb !important +} + +.bg-deep-purple-4 { + background: #9575cd !important +} + +.bg-deep-purple-5 { + background: #7e57c2 !important +} + +.bg-deep-purple-6 { + background: #673ab7 !important +} + +.bg-deep-purple-7 { + background: #5e35b1 !important +} + +.bg-deep-purple-8 { + background: #512da8 !important +} + +.bg-deep-purple-9 { + background: #4527a0 !important +} + +.bg-deep-purple-10 { + background: #311b92 !important +} + +.bg-deep-purple-11 { + background: #b388ff !important +} + +.bg-deep-purple-12 { + background: #7c4dff !important +} + +.bg-deep-purple-13 { + background: #651fff !important +} + +.bg-deep-purple-14 { + background: #6200ea !important +} + +.bg-indigo { + background: #3f51b5 !important +} + +.bg-indigo-1 { + background: #e8eaf6 !important +} + +.bg-indigo-2 { + background: #c5cae9 !important +} + +.bg-indigo-3 { + background: #9fa8da !important +} + +.bg-indigo-4 { + background: #7986cb !important +} + +.bg-indigo-5 { + background: #5c6bc0 !important +} + +.bg-indigo-6 { + background: #3f51b5 !important +} + +.bg-indigo-7 { + background: #3949ab !important +} + +.bg-indigo-8 { + background: #303f9f !important +} + +.bg-indigo-9 { + background: #283593 !important +} + +.bg-indigo-10 { + background: #1a237e !important +} + +.bg-indigo-11 { + background: #8c9eff !important +} + +.bg-indigo-12 { + background: #536dfe !important +} + +.bg-indigo-13 { + background: #3d5afe !important +} + +.bg-indigo-14 { + background: #304ffe !important +} + +.bg-blue { + background: #2196f3 !important +} + +.bg-blue-1 { + background: #e3f2fd !important +} + +.bg-blue-2 { + background: #bbdefb !important +} + +.bg-blue-3 { + background: #90caf9 !important +} + +.bg-blue-4 { + background: #64b5f6 !important +} + +.bg-blue-5 { + background: #42a5f5 !important +} + +.bg-blue-6 { + background: #2196f3 !important +} + +.bg-blue-7 { + background: #1e88e5 !important +} + +.bg-blue-8 { + background: #1976d2 !important +} + +.bg-blue-9 { + background: #1565c0 !important +} + +.bg-blue-10 { + background: #0d47a1 !important +} + +.bg-blue-11 { + background: #82b1ff !important +} + +.bg-blue-12 { + background: #448aff !important +} + +.bg-blue-13 { + background: #2979ff !important +} + +.bg-blue-14 { + background: #2962ff !important +} + +.bg-light-blue { + background: #03a9f4 !important +} + +.bg-light-blue-1 { + background: #e1f5fe !important +} + +.bg-light-blue-2 { + background: #b3e5fc !important +} + +.bg-light-blue-3 { + background: #81d4fa !important +} + +.bg-light-blue-4 { + background: #4fc3f7 !important +} + +.bg-light-blue-5 { + background: #29b6f6 !important +} + +.bg-light-blue-6 { + background: #03a9f4 !important +} + +.bg-light-blue-7 { + background: #039be5 !important +} + +.bg-light-blue-8 { + background: #0288d1 !important +} + +.bg-light-blue-9 { + background: #0277bd !important +} + +.bg-light-blue-10 { + background: #01579b !important +} + +.bg-light-blue-11 { + background: #80d8ff !important +} + +.bg-light-blue-12 { + background: #40c4ff !important +} + +.bg-light-blue-13 { + background: #00b0ff !important +} + +.bg-light-blue-14 { + background: #0091ea !important +} + +.bg-cyan { + background: #00bcd4 !important +} + +.bg-cyan-1 { + background: #e0f7fa !important +} + +.bg-cyan-2 { + background: #b2ebf2 !important +} + +.bg-cyan-3 { + background: #80deea !important +} + +.bg-cyan-4 { + background: #4dd0e1 !important +} + +.bg-cyan-5 { + background: #26c6da !important +} + +.bg-cyan-6 { + background: #00bcd4 !important +} + +.bg-cyan-7 { + background: #00acc1 !important +} + +.bg-cyan-8 { + background: #0097a7 !important +} + +.bg-cyan-9 { + background: #00838f !important +} + +.bg-cyan-10 { + background: #006064 !important +} + +.bg-cyan-11 { + background: #84ffff !important +} + +.bg-cyan-12 { + background: #18ffff !important +} + +.bg-cyan-13 { + background: #00e5ff !important +} + +.bg-cyan-14 { + background: #00b8d4 !important +} + +.bg-teal { + background: #009688 !important +} + +.bg-teal-1 { + background: #e0f2f1 !important +} + +.bg-teal-2 { + background: #b2dfdb !important +} + +.bg-teal-3 { + background: #80cbc4 !important +} + +.bg-teal-4 { + background: #4db6ac !important +} + +.bg-teal-5 { + background: #26a69a !important +} + +.bg-teal-6 { + background: #009688 !important +} + +.bg-teal-7 { + background: #00897b !important +} + +.bg-teal-8 { + background: #00796b !important +} + +.bg-teal-9 { + background: #00695c !important +} + +.bg-teal-10 { + background: #004d40 !important +} + +.bg-teal-11 { + background: #a7ffeb !important +} + +.bg-teal-12 { + background: #64ffda !important +} + +.bg-teal-13 { + background: #1de9b6 !important +} + +.bg-teal-14 { + background: #00bfa5 !important +} + +.bg-green { + background: #4caf50 !important +} + +.bg-green-1 { + background: #e8f5e9 !important +} + +.bg-green-2 { + background: #c8e6c9 !important +} + +.bg-green-3 { + background: #a5d6a7 !important +} + +.bg-green-4 { + background: #81c784 !important +} + +.bg-green-5 { + background: #66bb6a !important +} + +.bg-green-6 { + background: #4caf50 !important +} + +.bg-green-7 { + background: #43a047 !important +} + +.bg-green-8 { + background: #388e3c !important +} + +.bg-green-9 { + background: #2e7d32 !important +} + +.bg-green-10 { + background: #1b5e20 !important +} + +.bg-green-11 { + background: #b9f6ca !important +} + +.bg-green-12 { + background: #69f0ae !important +} + +.bg-green-13 { + background: #00e676 !important +} + +.bg-green-14 { + background: #00c853 !important +} + +.bg-light-green { + background: #8bc34a !important +} + +.bg-light-green-1 { + background: #f1f8e9 !important +} + +.bg-light-green-2 { + background: #dcedc8 !important +} + +.bg-light-green-3 { + background: #c5e1a5 !important +} + +.bg-light-green-4 { + background: #aed581 !important +} + +.bg-light-green-5 { + background: #9ccc65 !important +} + +.bg-light-green-6 { + background: #8bc34a !important +} + +.bg-light-green-7 { + background: #7cb342 !important +} + +.bg-light-green-8 { + background: #689f38 !important +} + +.bg-light-green-9 { + background: #558b2f !important +} + +.bg-light-green-10 { + background: #33691e !important +} + +.bg-light-green-11 { + background: #ccff90 !important +} + +.bg-light-green-12 { + background: #b2ff59 !important +} + +.bg-light-green-13 { + background: #76ff03 !important +} + +.bg-light-green-14 { + background: #64dd17 !important +} + +.bg-lime { + background: #cddc39 !important +} + +.bg-lime-1 { + background: #f9fbe7 !important +} + +.bg-lime-2 { + background: #f0f4c3 !important +} + +.bg-lime-3 { + background: #e6ee9c !important +} + +.bg-lime-4 { + background: #dce775 !important +} + +.bg-lime-5 { + background: #d4e157 !important +} + +.bg-lime-6 { + background: #cddc39 !important +} + +.bg-lime-7 { + background: #c0ca33 !important +} + +.bg-lime-8 { + background: #afb42b !important +} + +.bg-lime-9 { + background: #9e9d24 !important +} + +.bg-lime-10 { + background: #827717 !important +} + +.bg-lime-11 { + background: #f4ff81 !important +} + +.bg-lime-12 { + background: #eeff41 !important +} + +.bg-lime-13 { + background: #c6ff00 !important +} + +.bg-lime-14 { + background: #aeea00 !important +} + +.bg-yellow { + background: #ffeb3b !important +} + +.bg-yellow-1 { + background: #fffde7 !important +} + +.bg-yellow-2 { + background: #fff9c4 !important +} + +.bg-yellow-3 { + background: #fff59d !important +} + +.bg-yellow-4 { + background: #fff176 !important +} + +.bg-yellow-5 { + background: #ffee58 !important +} + +.bg-yellow-6 { + background: #ffeb3b !important +} + +.bg-yellow-7 { + background: #fdd835 !important +} + +.bg-yellow-8 { + background: #fbc02d !important +} + +.bg-yellow-9 { + background: #f9a825 !important +} + +.bg-yellow-10 { + background: #f57f17 !important +} + +.bg-yellow-11 { + background: #ffff8d !important +} + +.bg-yellow-12 { + background: #ff0 !important +} + +.bg-yellow-13 { + background: #ffea00 !important +} + +.bg-yellow-14 { + background: #ffd600 !important +} + +.bg-amber { + background: #ffc107 !important +} + +.bg-amber-1 { + background: #fff8e1 !important +} + +.bg-amber-2 { + background: #ffecb3 !important +} + +.bg-amber-3 { + background: #ffe082 !important +} + +.bg-amber-4 { + background: #ffd54f !important +} + +.bg-amber-5 { + background: #ffca28 !important +} + +.bg-amber-6 { + background: #ffc107 !important +} + +.bg-amber-7 { + background: #ffb300 !important +} + +.bg-amber-8 { + background: #ffa000 !important +} + +.bg-amber-9 { + background: #ff8f00 !important +} + +.bg-amber-10 { + background: #ff6f00 !important +} + +.bg-amber-11 { + background: #ffe57f !important +} + +.bg-amber-12 { + background: #ffd740 !important +} + +.bg-amber-13 { + background: #ffc400 !important +} + +.bg-amber-14 { + background: #ffab00 !important +} + +.bg-orange { + background: #ff9800 !important +} + +.bg-orange-1 { + background: #fff3e0 !important +} + +.bg-orange-2 { + background: #ffe0b2 !important +} + +.bg-orange-3 { + background: #ffcc80 !important +} + +.bg-orange-4 { + background: #ffb74d !important +} + +.bg-orange-5 { + background: #ffa726 !important +} + +.bg-orange-6 { + background: #ff9800 !important +} + +.bg-orange-7 { + background: #fb8c00 !important +} + +.bg-orange-8 { + background: #f57c00 !important +} + +.bg-orange-9 { + background: #ef6c00 !important +} + +.bg-orange-10 { + background: #e65100 !important +} + +.bg-orange-11 { + background: #ffd180 !important +} + +.bg-orange-12 { + background: #ffab40 !important +} + +.bg-orange-13 { + background: #ff9100 !important +} + +.bg-orange-14 { + background: #ff6d00 !important +} + +.bg-deep-orange { + background: #ff5722 !important +} + +.bg-deep-orange-1 { + background: #fbe9e7 !important +} + +.bg-deep-orange-2 { + background: #ffccbc !important +} + +.bg-deep-orange-3 { + background: #ffab91 !important +} + +.bg-deep-orange-4 { + background: #ff8a65 !important +} + +.bg-deep-orange-5 { + background: #ff7043 !important +} + +.bg-deep-orange-6 { + background: #ff5722 !important +} + +.bg-deep-orange-7 { + background: #f4511e !important +} + +.bg-deep-orange-8 { + background: #e64a19 !important +} + +.bg-deep-orange-9 { + background: #d84315 !important +} + +.bg-deep-orange-10 { + background: #bf360c !important +} + +.bg-deep-orange-11 { + background: #ff9e80 !important +} + +.bg-deep-orange-12 { + background: #ff6e40 !important +} + +.bg-deep-orange-13 { + background: #ff3d00 !important +} + +.bg-deep-orange-14 { + background: #dd2c00 !important +} + +.bg-brown { + background: #795548 !important +} + +.bg-brown-1 { + background: #efebe9 !important +} + +.bg-brown-2 { + background: #d7ccc8 !important +} + +.bg-brown-3 { + background: #bcaaa4 !important +} + +.bg-brown-4 { + background: #a1887f !important +} + +.bg-brown-5 { + background: #8d6e63 !important +} + +.bg-brown-6 { + background: #795548 !important +} + +.bg-brown-7 { + background: #6d4c41 !important +} + +.bg-brown-8 { + background: #5d4037 !important +} + +.bg-brown-9 { + background: #4e342e !important +} + +.bg-brown-10 { + background: #3e2723 !important +} + +.bg-brown-11 { + background: #d7ccc8 !important +} + +.bg-brown-12 { + background: #bcaaa4 !important +} + +.bg-brown-13 { + background: #8d6e63 !important +} + +.bg-brown-14 { + background: #5d4037 !important +} + +.bg-grey { + background: #9e9e9e !important +} + +.bg-grey-1 { + background: #fafafa !important +} + +.bg-grey-2 { + background: #f5f5f5 !important +} + +.bg-grey-3 { + background: #eee !important +} + +.bg-grey-4 { + background: #e0e0e0 !important +} + +.bg-grey-5 { + background: #bdbdbd !important +} + +.bg-grey-6 { + background: #9e9e9e !important +} + +.bg-grey-7 { + background: #757575 !important +} + +.bg-grey-8 { + background: #616161 !important +} + +.bg-grey-9 { + background: #424242 !important +} + +.bg-grey-10 { + background: #212121 !important +} + +.bg-grey-11 { + background: #f5f5f5 !important +} + +.bg-grey-12 { + background: #eee !important +} + +.bg-grey-13 { + background: #bdbdbd !important +} + +.bg-grey-14 { + background: #616161 !important +} + +.bg-blue-grey { + background: #607d8b !important +} + +.bg-blue-grey-1 { + background: #eceff1 !important +} + +.bg-blue-grey-2 { + background: #cfd8dc !important +} + +.bg-blue-grey-3 { + background: #b0bec5 !important +} + +.bg-blue-grey-4 { + background: #90a4ae !important +} + +.bg-blue-grey-5 { + background: #78909c !important +} + +.bg-blue-grey-6 { + background: #607d8b !important +} + +.bg-blue-grey-7 { + background: #546e7a !important +} + +.bg-blue-grey-8 { + background: #455a64 !important +} + +.bg-blue-grey-9 { + background: #37474f !important +} + +.bg-blue-grey-10 { + background: #263238 !important +} + +.bg-blue-grey-11 { + background: #cfd8dc !important +} + +.bg-blue-grey-12 { + background: #b0bec5 !important +} + +.bg-blue-grey-13 { + background: #78909c !important +} + +.bg-blue-grey-14 { + background: #455a64 !important +} + +.shadow-transition { + transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1) !important +} + +.shadow-1 { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12) +} + +.shadow-up-1 { + box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.2), 0 -1px 1px rgba(0, 0, 0, 0.14), 0 -2px 1px -1px rgba(0, 0, 0, 0.12) +} + +.shadow-2 { + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12) +} + +.shadow-up-2 { + box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.2), 0 -2px 2px rgba(0, 0, 0, 0.14), 0 -3px 1px -2px rgba(0, 0, 0, 0.12) +} + +.shadow-3 { + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.2), 0 3px 4px rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.12) +} + +.shadow-up-3 { + box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.2), 0 -3px 4px rgba(0, 0, 0, 0.14), 0 -3px 3px -2px rgba(0, 0, 0, 0.12) +} + +.shadow-4 { + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px rgba(0, 0, 0, 0.14), 0 1px 10px rgba(0, 0, 0, 0.12) +} + +.shadow-up-4 { + box-shadow: 0 -2px 4px -1px rgba(0, 0, 0, 0.2), 0 -4px 5px rgba(0, 0, 0, 0.14), 0 -1px 10px rgba(0, 0, 0, 0.12) +} + +.shadow-5 { + box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 5px 8px rgba(0, 0, 0, 0.14), 0 1px 14px rgba(0, 0, 0, 0.12) +} + +.shadow-up-5 { + box-shadow: 0 -3px 5px -1px rgba(0, 0, 0, 0.2), 0 -5px 8px rgba(0, 0, 0, 0.14), 0 -1px 14px rgba(0, 0, 0, 0.12) +} + +.shadow-6 { + box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px rgba(0, 0, 0, 0.14), 0 1px 18px rgba(0, 0, 0, 0.12) +} + +.shadow-up-6 { + box-shadow: 0 -3px 5px -1px rgba(0, 0, 0, 0.2), 0 -6px 10px rgba(0, 0, 0, 0.14), 0 -1px 18px rgba(0, 0, 0, 0.12) +} + +.shadow-7 { + box-shadow: 0 4px 5px -2px rgba(0, 0, 0, 0.2), 0 7px 10px 1px rgba(0, 0, 0, 0.14), 0 2px 16px 1px rgba(0, 0, 0, 0.12) +} + +.shadow-up-7 { + box-shadow: 0 -4px 5px -2px rgba(0, 0, 0, 0.2), 0 -7px 10px 1px rgba(0, 0, 0, 0.14), 0 -2px 16px 1px rgba(0, 0, 0, 0.12) +} + +.shadow-8 { + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12) +} + +.shadow-up-8 { + box-shadow: 0 -5px 5px -3px rgba(0, 0, 0, 0.2), 0 -8px 10px 1px rgba(0, 0, 0, 0.14), 0 -3px 14px 2px rgba(0, 0, 0, 0.12) +} + +.shadow-9 { + box-shadow: 0 5px 6px -3px rgba(0, 0, 0, 0.2), 0 9px 12px 1px rgba(0, 0, 0, 0.14), 0 3px 16px 2px rgba(0, 0, 0, 0.12) +} + +.shadow-up-9 { + box-shadow: 0 -5px 6px -3px rgba(0, 0, 0, 0.2), 0 -9px 12px 1px rgba(0, 0, 0, 0.14), 0 -3px 16px 2px rgba(0, 0, 0, 0.12) +} + +.shadow-10 { + box-shadow: 0 6px 6px -3px rgba(0, 0, 0, 0.2), 0 10px 14px 1px rgba(0, 0, 0, 0.14), 0 4px 18px 3px rgba(0, 0, 0, 0.12) +} + +.shadow-up-10 { + box-shadow: 0 -6px 6px -3px rgba(0, 0, 0, 0.2), 0 -10px 14px 1px rgba(0, 0, 0, 0.14), 0 -4px 18px 3px rgba(0, 0, 0, 0.12) +} + +.shadow-11 { + box-shadow: 0 6px 7px -4px rgba(0, 0, 0, 0.2), 0 11px 15px 1px rgba(0, 0, 0, 0.14), 0 4px 20px 3px rgba(0, 0, 0, 0.12) +} + +.shadow-up-11 { + box-shadow: 0 -6px 7px -4px rgba(0, 0, 0, 0.2), 0 -11px 15px 1px rgba(0, 0, 0, 0.14), 0 -4px 20px 3px rgba(0, 0, 0, 0.12) +} + +.shadow-12 { + box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2), 0 12px 17px 2px rgba(0, 0, 0, 0.14), 0 5px 22px 4px rgba(0, 0, 0, 0.12) +} + +.shadow-up-12 { + box-shadow: 0 -7px 8px -4px rgba(0, 0, 0, 0.2), 0 -12px 17px 2px rgba(0, 0, 0, 0.14), 0 -5px 22px 4px rgba(0, 0, 0, 0.12) +} + +.shadow-13 { + box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2), 0 13px 19px 2px rgba(0, 0, 0, 0.14), 0 5px 24px 4px rgba(0, 0, 0, 0.12) +} + +.shadow-up-13 { + box-shadow: 0 -7px 8px -4px rgba(0, 0, 0, 0.2), 0 -13px 19px 2px rgba(0, 0, 0, 0.14), 0 -5px 24px 4px rgba(0, 0, 0, 0.12) +} + +.shadow-14 { + box-shadow: 0 7px 9px -4px rgba(0, 0, 0, 0.2), 0 14px 21px 2px rgba(0, 0, 0, 0.14), 0 5px 26px 4px rgba(0, 0, 0, 0.12) +} + +.shadow-up-14 { + box-shadow: 0 -7px 9px -4px rgba(0, 0, 0, 0.2), 0 -14px 21px 2px rgba(0, 0, 0, 0.14), 0 -5px 26px 4px rgba(0, 0, 0, 0.12) +} + +.shadow-15 { + box-shadow: 0 8px 9px -5px rgba(0, 0, 0, 0.2), 0 15px 22px 2px rgba(0, 0, 0, 0.14), 0 6px 28px 5px rgba(0, 0, 0, 0.12) +} + +.shadow-up-15 { + box-shadow: 0 -8px 9px -5px rgba(0, 0, 0, 0.2), 0 -15px 22px 2px rgba(0, 0, 0, 0.14), 0 -6px 28px 5px rgba(0, 0, 0, 0.12) +} + +.shadow-16 { + box-shadow: 0 8px 10px -5px rgba(0, 0, 0, 0.2), 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12) +} + +.shadow-up-16 { + box-shadow: 0 -8px 10px -5px rgba(0, 0, 0, 0.2), 0 -16px 24px 2px rgba(0, 0, 0, 0.14), 0 -6px 30px 5px rgba(0, 0, 0, 0.12) +} + +.shadow-17 { + box-shadow: 0 8px 11px -5px rgba(0, 0, 0, 0.2), 0 17px 26px 2px rgba(0, 0, 0, 0.14), 0 6px 32px 5px rgba(0, 0, 0, 0.12) +} + +.shadow-up-17 { + box-shadow: 0 -8px 11px -5px rgba(0, 0, 0, 0.2), 0 -17px 26px 2px rgba(0, 0, 0, 0.14), 0 -6px 32px 5px rgba(0, 0, 0, 0.12) +} + +.shadow-18 { + box-shadow: 0 9px 11px -5px rgba(0, 0, 0, 0.2), 0 18px 28px 2px rgba(0, 0, 0, 0.14), 0 7px 34px 6px rgba(0, 0, 0, 0.12) +} + +.shadow-up-18 { + box-shadow: 0 -9px 11px -5px rgba(0, 0, 0, 0.2), 0 -18px 28px 2px rgba(0, 0, 0, 0.14), 0 -7px 34px 6px rgba(0, 0, 0, 0.12) +} + +.shadow-19 { + box-shadow: 0 9px 12px -6px rgba(0, 0, 0, 0.2), 0 19px 29px 2px rgba(0, 0, 0, 0.14), 0 7px 36px 6px rgba(0, 0, 0, 0.12) +} + +.shadow-up-19 { + box-shadow: 0 -9px 12px -6px rgba(0, 0, 0, 0.2), 0 -19px 29px 2px rgba(0, 0, 0, 0.14), 0 -7px 36px 6px rgba(0, 0, 0, 0.12) +} + +.shadow-20 { + box-shadow: 0 10px 13px -6px rgba(0, 0, 0, 0.2), 0 20px 31px 3px rgba(0, 0, 0, 0.14), 0 8px 38px 7px rgba(0, 0, 0, 0.12) +} + +.shadow-up-20 { + box-shadow: 0 -10px 13px -6px rgba(0, 0, 0, 0.2), 0 -20px 31px 3px rgba(0, 0, 0, 0.14), 0 -8px 38px 7px rgba(0, 0, 0, 0.12) +} + +.shadow-21 { + box-shadow: 0 10px 13px -6px rgba(0, 0, 0, 0.2), 0 21px 33px 3px rgba(0, 0, 0, 0.14), 0 8px 40px 7px rgba(0, 0, 0, 0.12) +} + +.shadow-up-21 { + box-shadow: 0 -10px 13px -6px rgba(0, 0, 0, 0.2), 0 -21px 33px 3px rgba(0, 0, 0, 0.14), 0 -8px 40px 7px rgba(0, 0, 0, 0.12) +} + +.shadow-22 { + box-shadow: 0 10px 14px -6px rgba(0, 0, 0, 0.2), 0 22px 35px 3px rgba(0, 0, 0, 0.14), 0 8px 42px 7px rgba(0, 0, 0, 0.12) +} + +.shadow-up-22 { + box-shadow: 0 -10px 14px -6px rgba(0, 0, 0, 0.2), 0 -22px 35px 3px rgba(0, 0, 0, 0.14), 0 -8px 42px 7px rgba(0, 0, 0, 0.12) +} + +.shadow-23 { + box-shadow: 0 11px 14px -7px rgba(0, 0, 0, 0.2), 0 23px 36px 3px rgba(0, 0, 0, 0.14), 0 9px 44px 8px rgba(0, 0, 0, 0.12) +} + +.shadow-up-23 { + box-shadow: 0 -11px 14px -7px rgba(0, 0, 0, 0.2), 0 -23px 36px 3px rgba(0, 0, 0, 0.14), 0 -9px 44px 8px rgba(0, 0, 0, 0.12) +} + +.shadow-24 { + box-shadow: 0 11px 15px -7px rgba(0, 0, 0, 0.2), 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12) +} + +.shadow-up-24 { + box-shadow: 0 -11px 15px -7px rgba(0, 0, 0, 0.2), 0 -24px 38px 3px rgba(0, 0, 0, 0.14), 0 -9px 46px 8px rgba(0, 0, 0, 0.12) +} + +.no-shadow, +.shadow-0 { + box-shadow: none !important +} + +.inset-shadow { + box-shadow: inset 0 7px 9px -7px rgba(0, 0, 0, 0.7) !important +} + +.inset-shadow-down { + box-shadow: inset 0 -7px 9px -7px rgba(0, 0, 0, 0.7) !important +} + +.z-marginals { + z-index: 2000 +} + +.z-notify { + z-index: 9500 +} + +.z-fullscreen { + z-index: 6000 +} + +.z-inherit { + z-index: inherit !important +} + +.column, +.flex, +.row { + display : flex; + flex-wrap: wrap +} + +.column.inline, +.flex.inline, +.row.inline { + display: inline-flex +} + +.row.reverse { + flex-direction: row-reverse +} + +.column { + flex-direction: column +} + +.column.reverse { + flex-direction: column-reverse +} + +.wrap { + flex-wrap: wrap +} + +.no-wrap { + flex-wrap: nowrap +} + +.reverse-wrap { + flex-wrap: wrap-reverse +} + +.order-first { + order: -10000 +} + +.order-last { + order: 10000 +} + +.order-none { + order: 0 +} + +.justify-start { + justify-content: flex-start +} + +.justify-end { + justify-content: flex-end +} + +.flex-center, +.justify-center { + justify-content: center +} + +.justify-between { + justify-content: space-between +} + +.justify-around { + justify-content: space-around +} + +.justify-evenly { + justify-content: space-evenly +} + +.items-start { + align-items: flex-start +} + +.items-end { + align-items: flex-end +} + +.flex-center, +.items-center { + align-items: center +} + +.items-baseline { + align-items: baseline +} + +.items-stretch { + align-items: stretch +} + +.content-start { + align-content: flex-start +} + +.content-end { + align-content: flex-end +} + +.content-center { + align-content: center +} + +.content-stretch { + align-content: stretch +} + +.content-between { + align-content: space-between +} + +.content-around { + align-content: space-around +} + +.self-start { + align-self: flex-start +} + +.self-end { + align-self: flex-end +} + +.self-center { + align-self: center +} + +.self-baseline { + align-self: baseline +} + +.self-stretch { + align-self: stretch +} + +.q-gutter-none, +.q-gutter-none>*, +.q-gutter-x-none, +.q-gutter-x-none>* { + margin-left: 0 +} + +.q-gutter-none, +.q-gutter-none>*, +.q-gutter-y-none, +.q-gutter-y-none>* { + margin-top: 0 +} + +.q-col-gutter-none, +.q-col-gutter-x-none { + margin-left: 0 +} + +.q-col-gutter-none>*, +.q-col-gutter-x-none>* { + padding-left: 0 +} + +.q-col-gutter-none, +.q-col-gutter-y-none { + margin-top: 0 +} + +.q-col-gutter-none>*, +.q-col-gutter-y-none>* { + padding-top: 0 +} + +.q-gutter-x-xs, +.q-gutter-xs { + margin-left: -4px +} + +.q-gutter-x-xs>*, +.q-gutter-xs>* { + margin-left: 4px +} + +.q-gutter-xs, +.q-gutter-y-xs { + margin-top: -4px +} + +.q-gutter-xs>*, +.q-gutter-y-xs>* { + margin-top: 4px +} + +.q-col-gutter-x-xs, +.q-col-gutter-xs { + margin-left: -4px +} + +.q-col-gutter-x-xs>*, +.q-col-gutter-xs>* { + padding-left: 4px +} + +.q-col-gutter-xs, +.q-col-gutter-y-xs { + margin-top: -4px +} + +.q-col-gutter-xs>*, +.q-col-gutter-y-xs>* { + padding-top: 4px +} + +.q-gutter-sm, +.q-gutter-x-sm { + margin-left: -8px +} + +.q-gutter-sm>*, +.q-gutter-x-sm>* { + margin-left: 8px +} + +.q-gutter-sm, +.q-gutter-y-sm { + margin-top: -8px +} + +.q-gutter-sm>*, +.q-gutter-y-sm>* { + margin-top: 8px +} + +.q-col-gutter-sm, +.q-col-gutter-x-sm { + margin-left: -8px +} + +.q-col-gutter-sm>*, +.q-col-gutter-x-sm>* { + padding-left: 8px +} + +.q-col-gutter-sm, +.q-col-gutter-y-sm { + margin-top: -8px +} + +.q-col-gutter-sm>*, +.q-col-gutter-y-sm>* { + padding-top: 8px +} + +.q-gutter-md, +.q-gutter-x-md { + margin-left: -16px +} + +.q-gutter-md>*, +.q-gutter-x-md>* { + margin-left: 16px +} + +.q-gutter-md, +.q-gutter-y-md { + margin-top: -16px +} + +.q-gutter-md>*, +.q-gutter-y-md>* { + margin-top: 16px +} + +.q-col-gutter-md, +.q-col-gutter-x-md { + margin-left: -16px +} + +.q-col-gutter-md>*, +.q-col-gutter-x-md>* { + padding-left: 16px +} + +.q-col-gutter-md, +.q-col-gutter-y-md { + margin-top: -16px +} + +.q-col-gutter-md>*, +.q-col-gutter-y-md>* { + padding-top: 16px +} + +.q-gutter-lg, +.q-gutter-x-lg { + margin-left: -24px +} + +.q-gutter-lg>*, +.q-gutter-x-lg>* { + margin-left: 24px +} + +.q-gutter-lg, +.q-gutter-y-lg { + margin-top: -24px +} + +.q-gutter-lg>*, +.q-gutter-y-lg>* { + margin-top: 24px +} + +.q-col-gutter-lg, +.q-col-gutter-x-lg { + margin-left: -24px +} + +.q-col-gutter-lg>*, +.q-col-gutter-x-lg>* { + padding-left: 24px +} + +.q-col-gutter-lg, +.q-col-gutter-y-lg { + margin-top: -24px +} + +.q-col-gutter-lg>*, +.q-col-gutter-y-lg>* { + padding-top: 24px +} + +.q-gutter-x-xl, +.q-gutter-xl { + margin-left: -48px +} + +.q-gutter-x-xl>*, +.q-gutter-xl>* { + margin-left: 48px +} + +.q-gutter-xl, +.q-gutter-y-xl { + margin-top: -48px +} + +.q-gutter-xl>*, +.q-gutter-y-xl>* { + margin-top: 48px +} + +.q-col-gutter-x-xl, +.q-col-gutter-xl { + margin-left: -48px +} + +.q-col-gutter-x-xl>*, +.q-col-gutter-xl>* { + padding-left: 48px +} + +.q-col-gutter-xl, +.q-col-gutter-y-xl { + margin-top: -48px +} + +.q-col-gutter-xl>*, +.q-col-gutter-y-xl>* { + padding-top: 48px +} + +@media (min-width:0) { + + .flex>.col, + .flex>.col-0, + .flex>.col-1, + .flex>.col-2, + .flex>.col-3, + .flex>.col-4, + .flex>.col-5, + .flex>.col-6, + .flex>.col-7, + .flex>.col-8, + .flex>.col-9, + .flex>.col-10, + .flex>.col-11, + .flex>.col-12, + .flex>.col-auto, + .flex>.col-grow, + .flex>.col-shrink, + .flex>.col-xs, + .flex>.col-xs-0, + .flex>.col-xs-1, + .flex>.col-xs-2, + .flex>.col-xs-3, + .flex>.col-xs-4, + .flex>.col-xs-5, + .flex>.col-xs-6, + .flex>.col-xs-7, + .flex>.col-xs-8, + .flex>.col-xs-9, + .flex>.col-xs-10, + .flex>.col-xs-11, + .flex>.col-xs-12, + .flex>.col-xs-auto, + .flex>.col-xs-grow, + .flex>.col-xs-shrink, + .row>.col, + .row>.col-0, + .row>.col-1, + .row>.col-2, + .row>.col-3, + .row>.col-4, + .row>.col-5, + .row>.col-6, + .row>.col-7, + .row>.col-8, + .row>.col-9, + .row>.col-10, + .row>.col-11, + .row>.col-12, + .row>.col-auto, + .row>.col-grow, + .row>.col-shrink, + .row>.col-xs, + .row>.col-xs-0, + .row>.col-xs-1, + .row>.col-xs-2, + .row>.col-xs-3, + .row>.col-xs-4, + .row>.col-xs-5, + .row>.col-xs-6, + .row>.col-xs-7, + .row>.col-xs-8, + .row>.col-xs-9, + .row>.col-xs-10, + .row>.col-xs-11, + .row>.col-xs-12, + .row>.col-xs-auto, + .row>.col-xs-grow, + .row>.col-xs-shrink { + width : auto; + min-width: 0; + max-width: 100% + } + + .column>.col, + .column>.col-0, + .column>.col-1, + .column>.col-2, + .column>.col-3, + .column>.col-4, + .column>.col-5, + .column>.col-6, + .column>.col-7, + .column>.col-8, + .column>.col-9, + .column>.col-10, + .column>.col-11, + .column>.col-12, + .column>.col-auto, + .column>.col-grow, + .column>.col-shrink, + .column>.col-xs, + .column>.col-xs-0, + .column>.col-xs-1, + .column>.col-xs-2, + .column>.col-xs-3, + .column>.col-xs-4, + .column>.col-xs-5, + .column>.col-xs-6, + .column>.col-xs-7, + .column>.col-xs-8, + .column>.col-xs-9, + .column>.col-xs-10, + .column>.col-xs-11, + .column>.col-xs-12, + .column>.col-xs-auto, + .column>.col-xs-grow, + .column>.col-xs-shrink, + .flex>.col, + .flex>.col-0, + .flex>.col-1, + .flex>.col-2, + .flex>.col-3, + .flex>.col-4, + .flex>.col-5, + .flex>.col-6, + .flex>.col-7, + .flex>.col-8, + .flex>.col-9, + .flex>.col-10, + .flex>.col-11, + .flex>.col-12, + .flex>.col-auto, + .flex>.col-grow, + .flex>.col-shrink, + .flex>.col-xs, + .flex>.col-xs-0, + .flex>.col-xs-1, + .flex>.col-xs-2, + .flex>.col-xs-3, + .flex>.col-xs-4, + .flex>.col-xs-5, + .flex>.col-xs-6, + .flex>.col-xs-7, + .flex>.col-xs-8, + .flex>.col-xs-9, + .flex>.col-xs-10, + .flex>.col-xs-11, + .flex>.col-xs-12, + .flex>.col-xs-auto, + .flex>.col-xs-grow, + .flex>.col-xs-shrink { + height : auto; + min-height: 0; + max-height: 100% + } + + .col, + .col-xs { + flex: 10000 1 0% + } + + .col-0, + .col-1, + .col-2, + .col-3, + .col-4, + .col-5, + .col-6, + .col-7, + .col-8, + .col-9, + .col-10, + .col-11, + .col-12, + .col-auto, + .col-xs-0, + .col-xs-1, + .col-xs-2, + .col-xs-3, + .col-xs-4, + .col-xs-5, + .col-xs-6, + .col-xs-7, + .col-xs-8, + .col-xs-9, + .col-xs-10, + .col-xs-11, + .col-xs-12, + .col-xs-auto { + flex: 0 0 auto + } + + .col-grow, + .col-xs-grow { + flex: 1 0 auto + } + + .col-shrink, + .col-xs-shrink { + flex: 0 1 auto + } + + .row>.col-0, + .row>.col-xs-0 { + height: auto; + width : 0% + } + + .row>.offset-0, + .row>.offset-xs-0 { + margin-left: 0% + } + + .column>.col-0, + .column>.col-xs-0 { + height: 0%; + width : auto + } + + .row>.col-1, + .row>.col-xs-1 { + height: auto; + width : 8.3333% + } + + .row>.offset-1, + .row>.offset-xs-1 { + margin-left: 8.3333% + } + + .column>.col-1, + .column>.col-xs-1 { + height: 8.3333%; + width : auto + } + + .row>.col-2, + .row>.col-xs-2 { + height: auto; + width : 16.6667% + } + + .row>.offset-2, + .row>.offset-xs-2 { + margin-left: 16.6667% + } + + .column>.col-2, + .column>.col-xs-2 { + height: 16.6667%; + width : auto + } + + .row>.col-3, + .row>.col-xs-3 { + height: auto; + width : 25% + } + + .row>.offset-3, + .row>.offset-xs-3 { + margin-left: 25% + } + + .column>.col-3, + .column>.col-xs-3 { + height: 25%; + width : auto + } + + .row>.col-4, + .row>.col-xs-4 { + height: auto; + width : 33.3333% + } + + .row>.offset-4, + .row>.offset-xs-4 { + margin-left: 33.3333% + } + + .column>.col-4, + .column>.col-xs-4 { + height: 33.3333%; + width : auto + } + + .row>.col-5, + .row>.col-xs-5 { + height: auto; + width : 41.6667% + } + + .row>.offset-5, + .row>.offset-xs-5 { + margin-left: 41.6667% + } + + .column>.col-5, + .column>.col-xs-5 { + height: 41.6667%; + width : auto + } + + .row>.col-6, + .row>.col-xs-6 { + height: auto; + width : 50% + } + + .row>.offset-6, + .row>.offset-xs-6 { + margin-left: 50% + } + + .column>.col-6, + .column>.col-xs-6 { + height: 50%; + width : auto + } + + .row>.col-7, + .row>.col-xs-7 { + height: auto; + width : 58.3333% + } + + .row>.offset-7, + .row>.offset-xs-7 { + margin-left: 58.3333% + } + + .column>.col-7, + .column>.col-xs-7 { + height: 58.3333%; + width : auto + } + + .row>.col-8, + .row>.col-xs-8 { + height: auto; + width : 66.6667% + } + + .row>.offset-8, + .row>.offset-xs-8 { + margin-left: 66.6667% + } + + .column>.col-8, + .column>.col-xs-8 { + height: 66.6667%; + width : auto + } + + .row>.col-9, + .row>.col-xs-9 { + height: auto; + width : 75% + } + + .row>.offset-9, + .row>.offset-xs-9 { + margin-left: 75% + } + + .column>.col-9, + .column>.col-xs-9 { + height: 75%; + width : auto + } + + .row>.col-10, + .row>.col-xs-10 { + height: auto; + width : 83.3333% + } + + .row>.offset-10, + .row>.offset-xs-10 { + margin-left: 83.3333% + } + + .column>.col-10, + .column>.col-xs-10 { + height: 83.3333%; + width : auto + } + + .row>.col-11, + .row>.col-xs-11 { + height: auto; + width : 91.6667% + } + + .row>.offset-11, + .row>.offset-xs-11 { + margin-left: 91.6667% + } + + .column>.col-11, + .column>.col-xs-11 { + height: 91.6667%; + width : auto + } + + .row>.col-12, + .row>.col-xs-12 { + height: auto; + width : 100% + } + + .row>.offset-12, + .row>.offset-xs-12 { + margin-left: 100% + } + + .column>.col-12, + .column>.col-xs-12 { + height: 100%; + width : auto + } + + .row>.col-all { + height: auto; + flex : 0 0 100% + } +} + +@media (min-width:600px) { + + .flex>.col-sm, + .flex>.col-sm-0, + .flex>.col-sm-1, + .flex>.col-sm-2, + .flex>.col-sm-3, + .flex>.col-sm-4, + .flex>.col-sm-5, + .flex>.col-sm-6, + .flex>.col-sm-7, + .flex>.col-sm-8, + .flex>.col-sm-9, + .flex>.col-sm-10, + .flex>.col-sm-11, + .flex>.col-sm-12, + .flex>.col-sm-auto, + .flex>.col-sm-grow, + .flex>.col-sm-shrink, + .row>.col-sm, + .row>.col-sm-0, + .row>.col-sm-1, + .row>.col-sm-2, + .row>.col-sm-3, + .row>.col-sm-4, + .row>.col-sm-5, + .row>.col-sm-6, + .row>.col-sm-7, + .row>.col-sm-8, + .row>.col-sm-9, + .row>.col-sm-10, + .row>.col-sm-11, + .row>.col-sm-12, + .row>.col-sm-auto, + .row>.col-sm-grow, + .row>.col-sm-shrink { + width : auto; + min-width: 0; + max-width: 100% + } + + .column>.col-sm, + .column>.col-sm-0, + .column>.col-sm-1, + .column>.col-sm-2, + .column>.col-sm-3, + .column>.col-sm-4, + .column>.col-sm-5, + .column>.col-sm-6, + .column>.col-sm-7, + .column>.col-sm-8, + .column>.col-sm-9, + .column>.col-sm-10, + .column>.col-sm-11, + .column>.col-sm-12, + .column>.col-sm-auto, + .column>.col-sm-grow, + .column>.col-sm-shrink, + .flex>.col-sm, + .flex>.col-sm-0, + .flex>.col-sm-1, + .flex>.col-sm-2, + .flex>.col-sm-3, + .flex>.col-sm-4, + .flex>.col-sm-5, + .flex>.col-sm-6, + .flex>.col-sm-7, + .flex>.col-sm-8, + .flex>.col-sm-9, + .flex>.col-sm-10, + .flex>.col-sm-11, + .flex>.col-sm-12, + .flex>.col-sm-auto, + .flex>.col-sm-grow, + .flex>.col-sm-shrink { + height : auto; + min-height: 0; + max-height: 100% + } + + .col-sm { + flex: 10000 1 0% + } + + .col-sm-0, + .col-sm-1, + .col-sm-2, + .col-sm-3, + .col-sm-4, + .col-sm-5, + .col-sm-6, + .col-sm-7, + .col-sm-8, + .col-sm-9, + .col-sm-10, + .col-sm-11, + .col-sm-12, + .col-sm-auto { + flex: 0 0 auto + } + + .col-sm-grow { + flex: 1 0 auto + } + + .col-sm-shrink { + flex: 0 1 auto + } + + .row>.col-sm-0 { + height: auto; + width : 0% + } + + .row>.offset-sm-0 { + margin-left: 0% + } + + .column>.col-sm-0 { + height: 0%; + width : auto + } + + .row>.col-sm-1 { + height: auto; + width : 8.3333% + } + + .row>.offset-sm-1 { + margin-left: 8.3333% + } + + .column>.col-sm-1 { + height: 8.3333%; + width : auto + } + + .row>.col-sm-2 { + height: auto; + width : 16.6667% + } + + .row>.offset-sm-2 { + margin-left: 16.6667% + } + + .column>.col-sm-2 { + height: 16.6667%; + width : auto + } + + .row>.col-sm-3 { + height: auto; + width : 25% + } + + .row>.offset-sm-3 { + margin-left: 25% + } + + .column>.col-sm-3 { + height: 25%; + width : auto + } + + .row>.col-sm-4 { + height: auto; + width : 33.3333% + } + + .row>.offset-sm-4 { + margin-left: 33.3333% + } + + .column>.col-sm-4 { + height: 33.3333%; + width : auto + } + + .row>.col-sm-5 { + height: auto; + width : 41.6667% + } + + .row>.offset-sm-5 { + margin-left: 41.6667% + } + + .column>.col-sm-5 { + height: 41.6667%; + width : auto + } + + .row>.col-sm-6 { + height: auto; + width : 50% + } + + .row>.offset-sm-6 { + margin-left: 50% + } + + .column>.col-sm-6 { + height: 50%; + width : auto + } + + .row>.col-sm-7 { + height: auto; + width : 58.3333% + } + + .row>.offset-sm-7 { + margin-left: 58.3333% + } + + .column>.col-sm-7 { + height: 58.3333%; + width : auto + } + + .row>.col-sm-8 { + height: auto; + width : 66.6667% + } + + .row>.offset-sm-8 { + margin-left: 66.6667% + } + + .column>.col-sm-8 { + height: 66.6667%; + width : auto + } + + .row>.col-sm-9 { + height: auto; + width : 75% + } + + .row>.offset-sm-9 { + margin-left: 75% + } + + .column>.col-sm-9 { + height: 75%; + width : auto + } + + .row>.col-sm-10 { + height: auto; + width : 83.3333% + } + + .row>.offset-sm-10 { + margin-left: 83.3333% + } + + .column>.col-sm-10 { + height: 83.3333%; + width : auto + } + + .row>.col-sm-11 { + height: auto; + width : 91.6667% + } + + .row>.offset-sm-11 { + margin-left: 91.6667% + } + + .column>.col-sm-11 { + height: 91.6667%; + width : auto + } + + .row>.col-sm-12 { + height: auto; + width : 100% + } + + .row>.offset-sm-12 { + margin-left: 100% + } + + .column>.col-sm-12 { + height: 100%; + width : auto + } +} + +@media (min-width:1024px) { + + .flex>.col-md, + .flex>.col-md-0, + .flex>.col-md-1, + .flex>.col-md-2, + .flex>.col-md-3, + .flex>.col-md-4, + .flex>.col-md-5, + .flex>.col-md-6, + .flex>.col-md-7, + .flex>.col-md-8, + .flex>.col-md-9, + .flex>.col-md-10, + .flex>.col-md-11, + .flex>.col-md-12, + .flex>.col-md-auto, + .flex>.col-md-grow, + .flex>.col-md-shrink, + .row>.col-md, + .row>.col-md-0, + .row>.col-md-1, + .row>.col-md-2, + .row>.col-md-3, + .row>.col-md-4, + .row>.col-md-5, + .row>.col-md-6, + .row>.col-md-7, + .row>.col-md-8, + .row>.col-md-9, + .row>.col-md-10, + .row>.col-md-11, + .row>.col-md-12, + .row>.col-md-auto, + .row>.col-md-grow, + .row>.col-md-shrink { + width : auto; + min-width: 0; + max-width: 100% + } + + .column>.col-md, + .column>.col-md-0, + .column>.col-md-1, + .column>.col-md-2, + .column>.col-md-3, + .column>.col-md-4, + .column>.col-md-5, + .column>.col-md-6, + .column>.col-md-7, + .column>.col-md-8, + .column>.col-md-9, + .column>.col-md-10, + .column>.col-md-11, + .column>.col-md-12, + .column>.col-md-auto, + .column>.col-md-grow, + .column>.col-md-shrink, + .flex>.col-md, + .flex>.col-md-0, + .flex>.col-md-1, + .flex>.col-md-2, + .flex>.col-md-3, + .flex>.col-md-4, + .flex>.col-md-5, + .flex>.col-md-6, + .flex>.col-md-7, + .flex>.col-md-8, + .flex>.col-md-9, + .flex>.col-md-10, + .flex>.col-md-11, + .flex>.col-md-12, + .flex>.col-md-auto, + .flex>.col-md-grow, + .flex>.col-md-shrink { + height : auto; + min-height: 0; + max-height: 100% + } + + .col-md { + flex: 10000 1 0% + } + + .col-md-0, + .col-md-1, + .col-md-2, + .col-md-3, + .col-md-4, + .col-md-5, + .col-md-6, + .col-md-7, + .col-md-8, + .col-md-9, + .col-md-10, + .col-md-11, + .col-md-12, + .col-md-auto { + flex: 0 0 auto + } + + .col-md-grow { + flex: 1 0 auto + } + + .col-md-shrink { + flex: 0 1 auto + } + + .row>.col-md-0 { + height: auto; + width : 0% + } + + .row>.offset-md-0 { + margin-left: 0% + } + + .column>.col-md-0 { + height: 0%; + width : auto + } + + .row>.col-md-1 { + height: auto; + width : 8.3333% + } + + .row>.offset-md-1 { + margin-left: 8.3333% + } + + .column>.col-md-1 { + height: 8.3333%; + width : auto + } + + .row>.col-md-2 { + height: auto; + width : 16.6667% + } + + .row>.offset-md-2 { + margin-left: 16.6667% + } + + .column>.col-md-2 { + height: 16.6667%; + width : auto + } + + .row>.col-md-3 { + height: auto; + width : 25% + } + + .row>.offset-md-3 { + margin-left: 25% + } + + .column>.col-md-3 { + height: 25%; + width : auto + } + + .row>.col-md-4 { + height: auto; + width : 33.3333% + } + + .row>.offset-md-4 { + margin-left: 33.3333% + } + + .column>.col-md-4 { + height: 33.3333%; + width : auto + } + + .row>.col-md-5 { + height: auto; + width : 41.6667% + } + + .row>.offset-md-5 { + margin-left: 41.6667% + } + + .column>.col-md-5 { + height: 41.6667%; + width : auto + } + + .row>.col-md-6 { + height: auto; + width : 50% + } + + .row>.offset-md-6 { + margin-left: 50% + } + + .column>.col-md-6 { + height: 50%; + width : auto + } + + .row>.col-md-7 { + height: auto; + width : 58.3333% + } + + .row>.offset-md-7 { + margin-left: 58.3333% + } + + .column>.col-md-7 { + height: 58.3333%; + width : auto + } + + .row>.col-md-8 { + height: auto; + width : 66.6667% + } + + .row>.offset-md-8 { + margin-left: 66.6667% + } + + .column>.col-md-8 { + height: 66.6667%; + width : auto + } + + .row>.col-md-9 { + height: auto; + width : 75% + } + + .row>.offset-md-9 { + margin-left: 75% + } + + .column>.col-md-9 { + height: 75%; + width : auto + } + + .row>.col-md-10 { + height: auto; + width : 83.3333% + } + + .row>.offset-md-10 { + margin-left: 83.3333% + } + + .column>.col-md-10 { + height: 83.3333%; + width : auto + } + + .row>.col-md-11 { + height: auto; + width : 91.6667% + } + + .row>.offset-md-11 { + margin-left: 91.6667% + } + + .column>.col-md-11 { + height: 91.6667%; + width : auto + } + + .row>.col-md-12 { + height: auto; + width : 100% + } + + .row>.offset-md-12 { + margin-left: 100% + } + + .column>.col-md-12 { + height: 100%; + width : auto + } +} + +@media (min-width:1440px) { + + .flex>.col-lg, + .flex>.col-lg-0, + .flex>.col-lg-1, + .flex>.col-lg-2, + .flex>.col-lg-3, + .flex>.col-lg-4, + .flex>.col-lg-5, + .flex>.col-lg-6, + .flex>.col-lg-7, + .flex>.col-lg-8, + .flex>.col-lg-9, + .flex>.col-lg-10, + .flex>.col-lg-11, + .flex>.col-lg-12, + .flex>.col-lg-auto, + .flex>.col-lg-grow, + .flex>.col-lg-shrink, + .row>.col-lg, + .row>.col-lg-0, + .row>.col-lg-1, + .row>.col-lg-2, + .row>.col-lg-3, + .row>.col-lg-4, + .row>.col-lg-5, + .row>.col-lg-6, + .row>.col-lg-7, + .row>.col-lg-8, + .row>.col-lg-9, + .row>.col-lg-10, + .row>.col-lg-11, + .row>.col-lg-12, + .row>.col-lg-auto, + .row>.col-lg-grow, + .row>.col-lg-shrink { + width : auto; + min-width: 0; + max-width: 100% + } + + .column>.col-lg, + .column>.col-lg-0, + .column>.col-lg-1, + .column>.col-lg-2, + .column>.col-lg-3, + .column>.col-lg-4, + .column>.col-lg-5, + .column>.col-lg-6, + .column>.col-lg-7, + .column>.col-lg-8, + .column>.col-lg-9, + .column>.col-lg-10, + .column>.col-lg-11, + .column>.col-lg-12, + .column>.col-lg-auto, + .column>.col-lg-grow, + .column>.col-lg-shrink, + .flex>.col-lg, + .flex>.col-lg-0, + .flex>.col-lg-1, + .flex>.col-lg-2, + .flex>.col-lg-3, + .flex>.col-lg-4, + .flex>.col-lg-5, + .flex>.col-lg-6, + .flex>.col-lg-7, + .flex>.col-lg-8, + .flex>.col-lg-9, + .flex>.col-lg-10, + .flex>.col-lg-11, + .flex>.col-lg-12, + .flex>.col-lg-auto, + .flex>.col-lg-grow, + .flex>.col-lg-shrink { + height : auto; + min-height: 0; + max-height: 100% + } + + .col-lg { + flex: 10000 1 0% + } + + .col-lg-0, + .col-lg-1, + .col-lg-2, + .col-lg-3, + .col-lg-4, + .col-lg-5, + .col-lg-6, + .col-lg-7, + .col-lg-8, + .col-lg-9, + .col-lg-10, + .col-lg-11, + .col-lg-12, + .col-lg-auto { + flex: 0 0 auto + } + + .col-lg-grow { + flex: 1 0 auto + } + + .col-lg-shrink { + flex: 0 1 auto + } + + .row>.col-lg-0 { + height: auto; + width : 0% + } + + .row>.offset-lg-0 { + margin-left: 0% + } + + .column>.col-lg-0 { + height: 0%; + width : auto + } + + .row>.col-lg-1 { + height: auto; + width : 8.3333% + } + + .row>.offset-lg-1 { + margin-left: 8.3333% + } + + .column>.col-lg-1 { + height: 8.3333%; + width : auto + } + + .row>.col-lg-2 { + height: auto; + width : 16.6667% + } + + .row>.offset-lg-2 { + margin-left: 16.6667% + } + + .column>.col-lg-2 { + height: 16.6667%; + width : auto + } + + .row>.col-lg-3 { + height: auto; + width : 25% + } + + .row>.offset-lg-3 { + margin-left: 25% + } + + .column>.col-lg-3 { + height: 25%; + width : auto + } + + .row>.col-lg-4 { + height: auto; + width : 33.3333% + } + + .row>.offset-lg-4 { + margin-left: 33.3333% + } + + .column>.col-lg-4 { + height: 33.3333%; + width : auto + } + + .row>.col-lg-5 { + height: auto; + width : 41.6667% + } + + .row>.offset-lg-5 { + margin-left: 41.6667% + } + + .column>.col-lg-5 { + height: 41.6667%; + width : auto + } + + .row>.col-lg-6 { + height: auto; + width : 50% + } + + .row>.offset-lg-6 { + margin-left: 50% + } + + .column>.col-lg-6 { + height: 50%; + width : auto + } + + .row>.col-lg-7 { + height: auto; + width : 58.3333% + } + + .row>.offset-lg-7 { + margin-left: 58.3333% + } + + .column>.col-lg-7 { + height: 58.3333%; + width : auto + } + + .row>.col-lg-8 { + height: auto; + width : 66.6667% + } + + .row>.offset-lg-8 { + margin-left: 66.6667% + } + + .column>.col-lg-8 { + height: 66.6667%; + width : auto + } + + .row>.col-lg-9 { + height: auto; + width : 75% + } + + .row>.offset-lg-9 { + margin-left: 75% + } + + .column>.col-lg-9 { + height: 75%; + width : auto + } + + .row>.col-lg-10 { + height: auto; + width : 83.3333% + } + + .row>.offset-lg-10 { + margin-left: 83.3333% + } + + .column>.col-lg-10 { + height: 83.3333%; + width : auto + } + + .row>.col-lg-11 { + height: auto; + width : 91.6667% + } + + .row>.offset-lg-11 { + margin-left: 91.6667% + } + + .column>.col-lg-11 { + height: 91.6667%; + width : auto + } + + .row>.col-lg-12 { + height: auto; + width : 100% + } + + .row>.offset-lg-12 { + margin-left: 100% + } + + .column>.col-lg-12 { + height: 100%; + width : auto + } +} + +@media (min-width:1920px) { + + .flex>.col-xl, + .flex>.col-xl-0, + .flex>.col-xl-1, + .flex>.col-xl-2, + .flex>.col-xl-3, + .flex>.col-xl-4, + .flex>.col-xl-5, + .flex>.col-xl-6, + .flex>.col-xl-7, + .flex>.col-xl-8, + .flex>.col-xl-9, + .flex>.col-xl-10, + .flex>.col-xl-11, + .flex>.col-xl-12, + .flex>.col-xl-auto, + .flex>.col-xl-grow, + .flex>.col-xl-shrink, + .row>.col-xl, + .row>.col-xl-0, + .row>.col-xl-1, + .row>.col-xl-2, + .row>.col-xl-3, + .row>.col-xl-4, + .row>.col-xl-5, + .row>.col-xl-6, + .row>.col-xl-7, + .row>.col-xl-8, + .row>.col-xl-9, + .row>.col-xl-10, + .row>.col-xl-11, + .row>.col-xl-12, + .row>.col-xl-auto, + .row>.col-xl-grow, + .row>.col-xl-shrink { + width : auto; + min-width: 0; + max-width: 100% + } + + .column>.col-xl, + .column>.col-xl-0, + .column>.col-xl-1, + .column>.col-xl-2, + .column>.col-xl-3, + .column>.col-xl-4, + .column>.col-xl-5, + .column>.col-xl-6, + .column>.col-xl-7, + .column>.col-xl-8, + .column>.col-xl-9, + .column>.col-xl-10, + .column>.col-xl-11, + .column>.col-xl-12, + .column>.col-xl-auto, + .column>.col-xl-grow, + .column>.col-xl-shrink, + .flex>.col-xl, + .flex>.col-xl-0, + .flex>.col-xl-1, + .flex>.col-xl-2, + .flex>.col-xl-3, + .flex>.col-xl-4, + .flex>.col-xl-5, + .flex>.col-xl-6, + .flex>.col-xl-7, + .flex>.col-xl-8, + .flex>.col-xl-9, + .flex>.col-xl-10, + .flex>.col-xl-11, + .flex>.col-xl-12, + .flex>.col-xl-auto, + .flex>.col-xl-grow, + .flex>.col-xl-shrink { + height : auto; + min-height: 0; + max-height: 100% + } + + .col-xl { + flex: 10000 1 0% + } + + .col-xl-0, + .col-xl-1, + .col-xl-2, + .col-xl-3, + .col-xl-4, + .col-xl-5, + .col-xl-6, + .col-xl-7, + .col-xl-8, + .col-xl-9, + .col-xl-10, + .col-xl-11, + .col-xl-12, + .col-xl-auto { + flex: 0 0 auto + } + + .col-xl-grow { + flex: 1 0 auto + } + + .col-xl-shrink { + flex: 0 1 auto + } + + .row>.col-xl-0 { + height: auto; + width : 0% + } + + .row>.offset-xl-0 { + margin-left: 0% + } + + .column>.col-xl-0 { + height: 0%; + width : auto + } + + .row>.col-xl-1 { + height: auto; + width : 8.3333% + } + + .row>.offset-xl-1 { + margin-left: 8.3333% + } + + .column>.col-xl-1 { + height: 8.3333%; + width : auto + } + + .row>.col-xl-2 { + height: auto; + width : 16.6667% + } + + .row>.offset-xl-2 { + margin-left: 16.6667% + } + + .column>.col-xl-2 { + height: 16.6667%; + width : auto + } + + .row>.col-xl-3 { + height: auto; + width : 25% + } + + .row>.offset-xl-3 { + margin-left: 25% + } + + .column>.col-xl-3 { + height: 25%; + width : auto + } + + .row>.col-xl-4 { + height: auto; + width : 33.3333% + } + + .row>.offset-xl-4 { + margin-left: 33.3333% + } + + .column>.col-xl-4 { + height: 33.3333%; + width : auto + } + + .row>.col-xl-5 { + height: auto; + width : 41.6667% + } + + .row>.offset-xl-5 { + margin-left: 41.6667% + } + + .column>.col-xl-5 { + height: 41.6667%; + width : auto + } + + .row>.col-xl-6 { + height: auto; + width : 50% + } + + .row>.offset-xl-6 { + margin-left: 50% + } + + .column>.col-xl-6 { + height: 50%; + width : auto + } + + .row>.col-xl-7 { + height: auto; + width : 58.3333% + } + + .row>.offset-xl-7 { + margin-left: 58.3333% + } + + .column>.col-xl-7 { + height: 58.3333%; + width : auto + } + + .row>.col-xl-8 { + height: auto; + width : 66.6667% + } + + .row>.offset-xl-8 { + margin-left: 66.6667% + } + + .column>.col-xl-8 { + height: 66.6667%; + width : auto + } + + .row>.col-xl-9 { + height: auto; + width : 75% + } + + .row>.offset-xl-9 { + margin-left: 75% + } + + .column>.col-xl-9 { + height: 75%; + width : auto + } + + .row>.col-xl-10 { + height: auto; + width : 83.3333% + } + + .row>.offset-xl-10 { + margin-left: 83.3333% + } + + .column>.col-xl-10 { + height: 83.3333%; + width : auto + } + + .row>.col-xl-11 { + height: auto; + width : 91.6667% + } + + .row>.offset-xl-11 { + margin-left: 91.6667% + } + + .column>.col-xl-11 { + height: 91.6667%; + width : auto + } + + .row>.col-xl-12 { + height: auto; + width : 100% + } + + .row>.offset-xl-12 { + margin-left: 100% + } + + .column>.col-xl-12 { + height: 100%; + width : auto + } +} + +.rounded-borders { + border-radius: 4px +} + +.border-radius-inherit { + border-radius: inherit +} + +.no-transition { + transition: none !important +} + +.transition-0 { + transition: 0s !important +} + +.glossy { + background-image: linear-gradient(180deg, hsla(0, 0%, 100%, 0.3), hsla(0, 0%, 100%, 0) 50%, rgba(0, 0, 0, 0.12) 51%, rgba(0, 0, 0, 0.04)) !important +} + +.q-placeholder::-moz-placeholder { + color : inherit; + opacity: 0.7 +} + +.q-placeholder:-ms-input-placeholder { + color : inherit !important; + opacity: 0.7 !important +} + +.q-placeholder::placeholder { + color : inherit; + opacity: 0.7 +} + +.q-body--fullscreen-mixin, +.q-body--prevent-scroll { + position: fixed !important +} + +.q-body--force-scrollbar { + overflow-y: scroll +} + +.q-no-input-spinner { + -moz-appearance: textfield !important +} + +.q-no-input-spinner::-webkit-inner-spin-button, +.q-no-input-spinner::-webkit-outer-spin-button { + -webkit-appearance: none; + margin : 0 +} + +.q-link { + outline : 0; + text-decoration: none +} + +.q-link--focusable:focus-visible { + -webkit-text-decoration: underline dashed currentColor 1px; + text-decoration : underline dashed currentColor 1px +} + +body.electron .q-electron-drag { + -webkit-user-select: none; + -webkit-app-region : drag +} + +body.electron .q-electron-drag--exception, +body.electron .q-electron-drag .q-btn-item { + -webkit-app-region: no-drag +} + +img.responsive { + max-width: 100%; + height : auto +} + +.non-selectable { + -webkit-user-select: none !important; + -moz-user-select : none !important; + -ms-user-select : none !important; + user-select : none !important +} + +.scroll { + overflow: auto +} + +.scroll, +.scroll-x, +.scroll-y { + -webkit-overflow-scrolling: touch; + will-change : scroll-position +} + +.scroll-x { + overflow-x: auto +} + +.scroll-y { + overflow-y: auto +} + +.no-scroll { + overflow: hidden !important +} + +.no-pointer-events, +.no-pointer-events--children, +.no-pointer-events--children * { + pointer-events: none !important +} + +.all-pointer-events { + pointer-events: all !important +} + +.cursor-pointer { + cursor: pointer !important +} + +.cursor-not-allowed { + cursor: not-allowed !important +} + +.cursor-inherit { + cursor: inherit !important +} + +.cursor-none { + cursor: none !important +} + +[aria-busy=true] { + cursor: progress +} + +[aria-controls], +[role=button] { + cursor: pointer +} + +[aria-disabled] { + cursor: default +} + +.rotate-45 { + transform: rotate(45deg) +} + +.rotate-90 { + transform: rotate(90deg) +} + +.rotate-135 { + transform: rotate(135deg) +} + +.rotate-180 { + transform: rotate(180deg) +} + +.rotate-205 { + transform: rotate(205deg) +} + +.rotate-225 { + transform: rotate(225deg) +} + +.rotate-270 { + transform: rotate(270deg) +} + +.rotate-315 { + transform: rotate(315deg) +} + +.flip-horizontal { + transform: scaleX(-1) +} + +.flip-vertical { + transform: scaleY(-1) +} + +.float-left { + float: left +} + +.float-right { + float: right +} + +.relative-position { + position: relative +} + +.fixed, +.fixed-bottom, +.fixed-bottom-left, +.fixed-bottom-right, +.fixed-center, +.fixed-full, +.fixed-left, +.fixed-right, +.fixed-top, +.fixed-top-left, +.fixed-top-right, +.fullscreen { + position: fixed +} + +.absolute, +.absolute-bottom, +.absolute-bottom-left, +.absolute-bottom-right, +.absolute-center, +.absolute-full, +.absolute-left, +.absolute-right, +.absolute-top, +.absolute-top-left, +.absolute-top-right { + position: absolute +} + +.absolute-top, +.fixed-top { + top : 0; + left : 0; + right: 0 +} + +.absolute-right, +.fixed-right { + top : 0; + right : 0; + bottom: 0 +} + +.absolute-bottom, +.fixed-bottom { + right : 0; + bottom: 0; + left : 0 +} + +.absolute-left, +.fixed-left { + top : 0; + bottom: 0; + left : 0 +} + +.absolute-top-left, +.fixed-top-left { + top : 0; + left: 0 +} + +.absolute-top-right, +.fixed-top-right { + top : 0; + right: 0 +} + +.absolute-bottom-left, +.fixed-bottom-left { + bottom: 0; + left : 0 +} + +.absolute-bottom-right, +.fixed-bottom-right { + bottom: 0; + right : 0 +} + +.fullscreen { + z-index : 6000; + border-radius: 0 !important; + max-width : 100vw; + max-height : 100vh +} + +body.q-ios-padding .fullscreen { + padding-top : 20px !important; + padding-top : env(safe-area-inset-top) !important; + padding-bottom: env(safe-area-inset-bottom) !important +} + +.absolute-full, +.fixed-full, +.fullscreen { + top : 0; + right : 0; + bottom: 0; + left : 0 +} + +.absolute-center, +.fixed-center { + top : 50%; + left : 50%; + transform: translate(-50%, -50%) +} + +.vertical-top { + vertical-align: top !important +} + +.vertical-middle { + vertical-align: middle !important +} + +.vertical-bottom { + vertical-align: bottom !important +} + +.on-left { + margin-right: 12px +} + +.on-right { + margin-left: 12px +} + +.q-position-engine { + margin-top : var(--q-pe-top, 0) !important; + margin-left: var(--q-pe-left, 0) !important; + will-change: auto; + visibility : collapse +} + +:root { + --q-size-xs: 0; + --q-size-sm: 600px; + --q-size-md: 1024px; + --q-size-lg: 1440px; + --q-size-xl: 1920px +} + +.fit { + width: 100% !important +} + +.fit, +.full-height { + height: 100% !important +} + +.full-width { + width : 100% !important; + margin-left : 0 !important; + margin-right: 0 !important +} + +.window-height { + margin-top : 0 !important; + margin-bottom: 0 !important; + height : 100vh !important +} + +.window-width { + margin-left : 0 !important; + margin-right: 0 !important; + width : 100vw !important +} + +.block { + display: block !important +} + +.inline-block { + display: inline-block !important +} + +.q-pa-none { + padding: 0 0 +} + +.q-pl-none { + padding-left: 0 +} + +.q-pr-none { + padding-right: 0 +} + +.q-pt-none, +.q-py-none { + padding-top: 0 +} + +.q-pb-none, +.q-py-none { + padding-bottom: 0 +} + +.q-px-none { + padding-left : 0; + padding-right: 0 +} + +.q-ma-none { + margin: 0 0 +} + +.q-ml-none { + margin-left: 0 +} + +.q-mr-none { + margin-right: 0 +} + +.q-mt-none, +.q-my-none { + margin-top: 0 +} + +.q-mb-none, +.q-my-none { + margin-bottom: 0 +} + +.q-mx-none { + margin-left : 0; + margin-right: 0 +} + +.q-pa-xs { + padding: 4px 4px +} + +.q-pl-xs { + padding-left: 4px +} + +.q-pr-xs { + padding-right: 4px +} + +.q-pt-xs, +.q-py-xs { + padding-top: 4px +} + +.q-pb-xs, +.q-py-xs { + padding-bottom: 4px +} + +.q-px-xs { + padding-left : 4px; + padding-right: 4px +} + +.q-ma-xs { + margin: 4px 4px +} + +.q-ml-xs { + margin-left: 4px +} + +.q-mr-xs { + margin-right: 4px +} + +.q-mt-xs, +.q-my-xs { + margin-top: 4px +} + +.q-mb-xs, +.q-my-xs { + margin-bottom: 4px +} + +.q-mx-xs { + margin-left : 4px; + margin-right: 4px +} + +.q-pa-sm { + padding: 8px 8px +} + +.q-pl-sm { + padding-left: 8px +} + +.q-pr-sm { + padding-right: 8px +} + +.q-pt-sm, +.q-py-sm { + padding-top: 8px +} + +.q-pb-sm, +.q-py-sm { + padding-bottom: 8px +} + +.q-px-sm { + padding-left : 8px; + padding-right: 8px +} + +.q-ma-sm { + margin: 8px 8px +} + +.q-ml-sm { + margin-left: 8px +} + +.q-mr-sm { + margin-right: 8px +} + +.q-mt-sm, +.q-my-sm { + margin-top: 8px +} + +.q-mb-sm, +.q-my-sm { + margin-bottom: 8px +} + +.q-mx-sm { + margin-left : 8px; + margin-right: 8px +} + +.q-pa-md { + padding: 16px 16px +} + +.q-pl-md { + padding-left: 16px +} + +.q-pr-md { + padding-right: 16px +} + +.q-pt-md, +.q-py-md { + padding-top: 16px +} + +.q-pb-md, +.q-py-md { + padding-bottom: 16px +} + +.q-px-md { + padding-left : 16px; + padding-right: 16px +} + +.q-ma-md { + margin: 16px 16px +} + +.q-ml-md { + margin-left: 16px +} + +.q-mr-md { + margin-right: 16px +} + +.q-mt-md, +.q-my-md { + margin-top: 16px +} + +.q-mb-md, +.q-my-md { + margin-bottom: 16px +} + +.q-mx-md { + margin-left : 16px; + margin-right: 16px +} + +.q-pa-lg { + padding: 24px 24px +} + +.q-pl-lg { + padding-left: 24px +} + +.q-pr-lg { + padding-right: 24px +} + +.q-pt-lg, +.q-py-lg { + padding-top: 24px +} + +.q-pb-lg, +.q-py-lg { + padding-bottom: 24px +} + +.q-px-lg { + padding-left : 24px; + padding-right: 24px +} + +.q-ma-lg { + margin: 24px 24px +} + +.q-ml-lg { + margin-left: 24px +} + +.q-mr-lg { + margin-right: 24px +} + +.q-mt-lg, +.q-my-lg { + margin-top: 24px +} + +.q-mb-lg, +.q-my-lg { + margin-bottom: 24px +} + +.q-mx-lg { + margin-left : 24px; + margin-right: 24px +} + +.q-pa-xl { + padding: 48px 48px +} + +.q-pl-xl { + padding-left: 48px +} + +.q-pr-xl { + padding-right: 48px +} + +.q-pt-xl, +.q-py-xl { + padding-top: 48px +} + +.q-pb-xl, +.q-py-xl { + padding-bottom: 48px +} + +.q-px-xl { + padding-left : 48px; + padding-right: 48px +} + +.q-ma-xl { + margin: 48px 48px +} + +.q-ml-xl { + margin-left: 48px +} + +.q-mr-xl { + margin-right: 48px +} + +.q-mt-xl, +.q-my-xl { + margin-top: 48px +} + +.q-mb-xl, +.q-my-xl { + margin-bottom: 48px +} + +.q-mx-xl { + margin-left : 48px; + margin-right: 48px +} + +.q-mt-auto, +.q-my-auto { + margin-top: auto +} + +.q-ml-auto { + margin-left: auto +} + +.q-mb-auto, +.q-my-auto { + margin-bottom: auto +} + +.q-mr-auto, +.q-mx-auto { + margin-right: auto +} + +.q-mx-auto { + margin-left: auto +} + +.q-touch { + -webkit-user-select: none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + user-drag : none; + -khtml-user-drag : none; + -webkit-user-drag : none +} + +.q-touch-x { + touch-action: pan-x +} + +.q-touch-y { + touch-action: pan-y +} + +.q-transition--fade-leave-active, +.q-transition--flip-leave-active, +.q-transition--jump-down-leave-active, +.q-transition--jump-left-leave-active, +.q-transition--jump-right-leave-active, +.q-transition--jump-up-leave-active, +.q-transition--rotate-leave-active, +.q-transition--scale-leave-active, +.q-transition--slide-down-leave-active, +.q-transition--slide-left-leave-active, +.q-transition--slide-right-leave-active, +.q-transition--slide-up-leave-active { + position: absolute +} + +.q-transition--slide-down-enter-active, +.q-transition--slide-down-leave-active, +.q-transition--slide-left-enter-active, +.q-transition--slide-left-leave-active, +.q-transition--slide-right-enter-active, +.q-transition--slide-right-leave-active, +.q-transition--slide-up-enter-active, +.q-transition--slide-up-leave-active { + transition: transform 0.3s cubic-bezier(0.215, 0.61, 0.355, 1) +} + +.q-transition--slide-right-enter { + transform: translate3d(-100%, 0, 0) +} + +.q-transition--slide-left-enter, +.q-transition--slide-right-leave-to { + transform: translate3d(100%, 0, 0) +} + +.q-transition--slide-left-leave-to { + transform: translate3d(-100%, 0, 0) +} + +.q-transition--slide-up-enter { + transform: translate3d(0, 100%, 0) +} + +.q-transition--slide-down-enter, +.q-transition--slide-up-leave-to { + transform: translate3d(0, -100%, 0) +} + +.q-transition--slide-down-leave-to { + transform: translate3d(0, 100%, 0) +} + +.q-transition--jump-down-enter-active, +.q-transition--jump-down-leave-active, +.q-transition--jump-left-enter-active, +.q-transition--jump-left-leave-active, +.q-transition--jump-right-enter-active, +.q-transition--jump-right-leave-active, +.q-transition--jump-up-enter-active, +.q-transition--jump-up-leave-active { + transition: opacity 0.3s, transform 0.3s +} + +.q-transition--jump-down-enter, +.q-transition--jump-down-leave-to, +.q-transition--jump-left-enter, +.q-transition--jump-left-leave-to, +.q-transition--jump-right-enter, +.q-transition--jump-right-leave-to, +.q-transition--jump-up-enter, +.q-transition--jump-up-leave-to { + opacity: 0 +} + +.q-transition--jump-right-enter { + transform: translate3d(-15px, 0, 0) +} + +.q-transition--jump-left-enter, +.q-transition--jump-right-leave-to { + transform: translate3d(15px, 0, 0) +} + +.q-transition--jump-left-leave-to { + transform: translateX(-15px) +} + +.q-transition--jump-up-enter { + transform: translate3d(0, 15px, 0) +} + +.q-transition--jump-down-enter, +.q-transition--jump-up-leave-to { + transform: translate3d(0, -15px, 0) +} + +.q-transition--jump-down-leave-to { + transform: translate3d(0, 15px, 0) +} + +.q-transition--fade-enter-active, +.q-transition--fade-leave-active { + transition: opacity 0.3s ease-out +} + +.q-transition--fade-enter, +.q-transition--fade-leave, +.q-transition--fade-leave-to { + opacity: 0 +} + +.q-transition--scale-enter-active, +.q-transition--scale-leave-active { + transition: opacity 0.3s, transform 0.3s cubic-bezier(0.215, 0.61, 0.355, 1) +} + +.q-transition--scale-enter, +.q-transition--scale-leave, +.q-transition--scale-leave-to { + opacity : 0; + transform: scale3d(0, 0, 1) +} + +.q-transition--rotate-enter-active, +.q-transition--rotate-leave-active { + transition : opacity 0.3s, transform 0.3s cubic-bezier(0.215, 0.61, 0.355, 1); + transform-style: preserve-3d +} + +.q-transition--rotate-enter, +.q-transition--rotate-leave, +.q-transition--rotate-leave-to { + opacity : 0; + transform: scale3d(0, 0, 1) rotate3d(0, 0, 1, 90deg) +} + +.q-transition--flip-down-enter-active, +.q-transition--flip-down-leave-active, +.q-transition--flip-left-enter-active, +.q-transition--flip-left-leave-active, +.q-transition--flip-right-enter-active, +.q-transition--flip-right-leave-active, +.q-transition--flip-up-enter-active, +.q-transition--flip-up-leave-active { + transition : transform 0.3s; + -webkit-backface-visibility: hidden; + backface-visibility : hidden +} + +.q-transition--flip-down-enter-to, +.q-transition--flip-down-leave, +.q-transition--flip-left-enter-to, +.q-transition--flip-left-leave, +.q-transition--flip-right-enter-to, +.q-transition--flip-right-leave, +.q-transition--flip-up-enter-to, +.q-transition--flip-up-leave { + transform: perspective(400px) rotate3d(1, 1, 0, 0deg) +} + +.q-transition--flip-right-enter { + transform: perspective(400px) rotate3d(0, 1, 0, -180deg) +} + +.q-transition--flip-left-enter, +.q-transition--flip-right-leave-to { + transform: perspective(400px) rotate3d(0, 1, 0, 180deg) +} + +.q-transition--flip-left-leave-to { + transform: perspective(400px) rotate3d(0, 1, 0, -180deg) +} + +.q-transition--flip-up-enter { + transform: perspective(400px) rotate3d(1, 0, 0, -180deg) +} + +.q-transition--flip-down-enter, +.q-transition--flip-up-leave-to { + transform: perspective(400px) rotate3d(1, 0, 0, 180deg) +} + +.q-transition--flip-down-leave-to { + transform: perspective(400px) rotate3d(1, 0, 0, -180deg) +} +.text-h1 { + font-size : 6rem; + font-weight : 300; + line-height : 6rem; + letter-spacing: -0.01562em +} + +.text-h2 { + font-size : 3.75rem; + font-weight : 300; + line-height : 3.75rem; + letter-spacing: -0.00833em +} + +.text-h3 { + font-size : 3rem; + font-weight : 400; + line-height : 3.125rem; + letter-spacing: normal +} + +.text-h4 { + font-size : 2.125rem; + font-weight : 400; + line-height : 2.5rem; + letter-spacing: 0.00735em +} + +.text-h5 { + font-size : 1.5rem; + font-weight : 400; + line-height : 2rem; + letter-spacing: normal +} + +.text-h6 { + font-size : 1.25rem; + font-weight : 500; + line-height : 2rem; + letter-spacing: 0.0125em +} + +.text-subtitle1 { + font-size : 1rem; + font-weight : 400; + line-height : 1.75rem; + letter-spacing: 0.00937em +} + +.text-subtitle2 { + font-size : 0.875rem; + font-weight : 500; + line-height : 1.375rem; + letter-spacing: 0.00714em +} + +.text-body1 { + font-size : 1rem; + font-weight : 400; + line-height : 1.5rem; + letter-spacing: 0.03125em +} + +.text-body2 { + font-size : 0.875rem; + font-weight : 400; + line-height : 1.25rem; + letter-spacing: 0.01786em +} + +.text-overline { + font-size : 0.75rem; + font-weight : 500; + line-height : 2rem; + letter-spacing: 0.16667em +} + +.text-caption { + font-size : 0.75rem; + font-weight : 400; + line-height : 1.25rem; + letter-spacing: 0.03333em +} + +.text-uppercase { + text-transform: uppercase +} + +.text-lowercase { + text-transform: lowercase +} + +.text-capitalize { + text-transform: capitalize +} + +.text-center { + text-align: center +} + +.text-left { + text-align: left +} + +.text-right { + text-align: right +} + +.text-justify { + text-align : justify; + -webkit-hyphens: auto; + -ms-hyphens : auto; + hyphens : auto +} + +.text-italic { + font-style: italic +} + +.text-bold { + font-weight: 700 +} + +.text-no-wrap { + white-space: nowrap +} + +.text-strike { + text-decoration: line-through +} + +.text-weight-thin { + font-weight: 100 +} + +.text-weight-light { + font-weight: 300 +} + +.text-weight-regular { + font-weight: 400 +} + +.text-weight-medium { + font-weight: 500 +} + +.text-weight-bold { + font-weight: 700 +} + +.text-weight-bolder { + font-weight: 900 +} + +small { + font-size: 80% +} + +big { + font-size: 170% +} + +sub { + bottom: -0.25em +} + +sup { + top: -0.5em +} + +.no-margin { + margin: 0 !important +} + +.no-padding { + padding: 0 !important +} + +.no-border { + border: 0 !important +} + +.no-border-radius { + border-radius: 0 !important +} + +.no-box-shadow { + box-shadow: none !important +} + +.no-outline { + outline: 0 !important +} + +.ellipsis { + text-overflow: ellipsis; + white-space : nowrap; + overflow : hidden +} + +.ellipsis-2-lines, +.ellipsis-3-lines { + overflow : hidden; + display : -webkit-box; + -webkit-box-orient: vertical +} + +.ellipsis-2-lines { + -webkit-line-clamp: 2 +} + +.ellipsis-3-lines { + -webkit-line-clamp: 3 +} + +.readonly { + cursor: default !important +} + +.disabled, +.disabled *, +[disabled], +[disabled] * { + outline: 0 !important; + cursor : not-allowed !important +} + +.disabled, +[disabled] { + opacity: 0.6 !important +} + +.hidden { + display: none !important +} + +.invisible { + visibility: hidden !important +} + +.transparent { + background: transparent !important +} + +.overflow-auto { + overflow: auto !important +} + +.overflow-hidden { + overflow: hidden !important +} + +.overflow-hidden-y { + overflow-y: hidden !important +} + +.hide-scrollbar { + scrollbar-width : none; + -ms-overflow-style: none +} + +.hide-scrollbar::-webkit-scrollbar { + width : 0; + height : 0; + display: none +} + +.dimmed:after, +.light-dimmed:after { + content : ""; + position: absolute; + top : 0; + right : 0; + bottom : 0; + left : 0 +} + +.dimmed:after { + background: rgba(0, 0, 0, 0.4) !important +} + +.light-dimmed:after { + background: hsla(0, 0%, 100%, 0.6) !important +} + +.z-top { + z-index: 7000 !important +} + +.z-max { + z-index: 9998 !important +} + +body.capacitor .capacitor-hide, +body.cordova .cordova-hide, +body.desktop .desktop-hide, +body.electron .electron-hide, +body.mobile .mobile-hide, +body.native-mobile .native-mobile-hide, +body.platform-android .platform-android-hide, +body.platform-ios .platform-ios-hide, +body.touch .touch-hide, +body.within-iframe .within-iframe-hide, +body:not(.capacitor) .capacitor-only, +body:not(.cordova) .cordova-only, +body:not(.desktop) .desktop-only, +body:not(.electron) .electron-only, +body:not(.mobile) .mobile-only, +body:not(.native-mobile) .native-mobile-only, +body:not(.platform-android) .platform-android-only, +body:not(.platform-ios) .platform-ios-only, +body:not(.touch) .touch-only, +body:not(.within-iframe) .within-iframe-only { + display: none !important +} + +@media (orientation:portrait) { + .orientation-landscape { + display: none !important + } +} + +@media (orientation:landscape) { + .orientation-portrait { + display: none !important + } +} + +@media screen { + .print-only { + display: none !important + } +} + +@media print { + .print-hide { + display: none !important + } +} + +@media (max-width:599.98px) { + + .gt-lg, + .gt-md, + .gt-sm, + .gt-xs, + .lg, + .md, + .sm, + .xl, + .xs-hide { + display: none !important + } +} + +@media (min-width:600px) and (max-width:1023.98px) { + + .gt-lg, + .gt-md, + .gt-sm, + .lg, + .lt-sm, + .md, + .sm-hide, + .xl, + .xs { + display: none !important + } +} + +@media (min-width:1024px) and (max-width:1439.98px) { + + .gt-lg, + .gt-md, + .lg, + .lt-md, + .lt-sm, + .md-hide, + .sm, + .xl, + .xs { + display: none !important + } +} + +@media (min-width:1440px) and (max-width:1919.98px) { + + .gt-lg, + .lg-hide, + .lt-lg, + .lt-md, + .lt-sm, + .md, + .sm, + .xl, + .xs { + display: none !important + } +} + +@media (min-width:1920px) { + + .lg, + .lt-lg, + .lt-md, + .lt-sm, + .lt-xl, + .md, + .sm, + .xl-hide, + .xs { + display: none !important + } +} + +.q-focus-helper, +.q-focusable, +.q-hoverable, +.q-manual-focusable { + outline: 0 +} + +body.desktop .q-focus-helper { + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; + pointer-events: none; + border-radius : inherit; + opacity : 0; + transition : background-color 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), opacity 0.4s cubic-bezier(0.25, 0.8, 0.5, 1) +} + +body.desktop .q-focus-helper:after, +body.desktop .q-focus-helper:before { + content : ""; + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; + opacity : 0; + border-radius: inherit; + transition : background-color 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), opacity 0.6s cubic-bezier(0.25, 0.8, 0.5, 1) +} + +body.desktop .q-focus-helper:before { + background: #000 +} + +body.desktop .q-focus-helper:after { + background: #fff +} + +body.desktop .q-focus-helper--rounded { + border-radius: 4px +} + +body.desktop .q-focus-helper--round { + border-radius: 50% +} + +body.desktop .q-focusable:focus>.q-focus-helper, +body.desktop .q-hoverable:hover>.q-focus-helper, +body.desktop .q-manual-focusable--focused>.q-focus-helper { + background: currentColor; + opacity : 0.15 +} + +body.desktop .q-focusable:focus>.q-focus-helper:before, +body.desktop .q-hoverable:hover>.q-focus-helper:before, +body.desktop .q-manual-focusable--focused>.q-focus-helper:before { + opacity: 0.1 +} + +body.desktop .q-focusable:focus>.q-focus-helper:after, +body.desktop .q-hoverable:hover>.q-focus-helper:after, +body.desktop .q-manual-focusable--focused>.q-focus-helper:after { + opacity: 0.4 +} + +body.desktop .q-focusable:focus>.q-focus-helper, +body.desktop .q-manual-focusable--focused>.q-focus-helper { + opacity: 0.22 +} + +body.body--dark { + color : #fff; + background: #121212; + background: var(--q-color-dark-page) +} + +.q-dark { + color : #fff; + background: #424242; + background: var(--q-color-dark) +} + +@media (-ms-high-contrast:none), +screen and (-ms-high-contrast:active) { + + .q-item:after, + .q-notification:after, + .q-toolbar:after { + content : ""; + font-size : 0; + visibility: collapse; + display : inline; + width : 0 + } + + .q-banner>.q-banner__avatar { + min-height: 38px + } + + .q-banner--dense>.q-banner__avatar { + min-height: 20px + } + + .q-item:after { + min-height: 32px + } + + .q-item--denseafter, + .q-list--dense>.q-itemafter { + min-height: 24px + } + + .q-toolbar:after { + min-height: 50px + } + + .q-notification--standard:after { + min-height: 48px + } + + .q-notification--multi-line { + min-height: 68px + } + + .q-btn__wrapper, + .q-menu .q-item__section--main, + .q-table__middle, + .q-time__content, + .q-toolbar__title { + flex-basis: auto + } + + .q-banner__content { + flex-basis: 0 !important + } + + .q-dialog__inner>.q-banner>.q-banner__content, + .q-menu>.q-banner>.q-banner__content { + flex-basis: auto !important + } + + .q-tab__content { + flex-basis: auto; + min-width : 100% + } + + .q-card__actions--vert { + flex: 0 0 auto + } + + .column { + min-width: 0% + } + + .q-item__section--avatar { + min-width: 56px + } + + button.q-btn--actionable:active:hover .q-btn__wrapper { + margin: -1px 1px 1px -1px + } + + .q-btn-group--push>button.q-btn--push.q-btn--actionable:active:hover .q-btn__wrapper { + margin: 1px 1px -1px -1px + } + + .q-btn { + overflow: visible + } + + .q-btn--wrap { + flex-direction: row + } + + .q-carousel__slide>* { + max-width: 100% + } + + .q-tabs--vertical .q-tab__indicator { + height: auto + } + + .q-spinner { + -webkit-animation: q-ie-spinner 2s linear infinite; + animation : q-ie-spinner 2s linear infinite; + transform-origin : center center; + opacity : 0.5 + } + + .q-spinner.q-spinner-mat .path { + stroke-dasharray: 89, 200 + } + + .q-checkbox__indet { + opacity: 0 + } + + .q-checkbox__inner--indet .q-checkbox__indet { + opacity: 1 + } + + .q-radio__check { + opacity: 0 + } + + .q-radio__inner--truthy .q-radio__check { + opacity: 1 + } + + .q-date__main { + min-height: 290px !important + } + + .q-date__months { + align-items: stretch + } + + .q-time--portrait .q-time__main { + display : flex; + flex-direction: column; + flex-wrap : nowrap; + flex : 1 0 auto + } + + .q-field__prefix, + .q-field__suffix { + flex: 1 0 auto + } + + .q-field__bottom--stale .q-field__messages { + left: 12px + } + + .q-field--borderless .q-field__bottom--stale .q-field__messages, + .q-field--standard .q-field__bottom--stale .q-field__messages { + left: 0 + } + + .q-field--float .q-field__label { + max-width: 100% + } + + .q-focus-helper { + z-index: 1 + } +} + +@media (-ms-high-contrast:none) and (min-width:0), +screen and (-ms-high-contrast:active) and (min-width:0) { + + .flex>.col, + .flex>.col-xs, + .row>.col, + .row>.col-xs { + flex-basis: auto; + min-width : 0% + } +} + +@media (-ms-high-contrast:none) and (min-width:600px), +screen and (-ms-high-contrast:active) and (min-width:600px) { + + .flex>.col-sm, + .row>.col-sm { + flex-basis: auto; + min-width : 0% + } +} + +@media (-ms-high-contrast:none) and (min-width:1024px), +screen and (-ms-high-contrast:active) and (min-width:1024px) { + + .flex>.col-md, + .row>.col-md { + flex-basis: auto; + min-width : 0% + } +} + +@media (-ms-high-contrast:none) and (min-width:1440px), +screen and (-ms-high-contrast:active) and (min-width:1440px) { + + .flex>.col-lg, + .row>.col-lg { + flex-basis: auto; + min-width : 0% + } +} + +@media (-ms-high-contrast:none) and (min-width:1920px), +screen and (-ms-high-contrast:active) and (min-width:1920px) { + + .flex>.col-xl, + .row>.col-xl { + flex-basis: auto; + min-width : 0% + } +} + +@supports (-ms-ime-align:auto) { + + .q-item:after, + .q-notification:after, + .q-toolbar:after { + content : ""; + font-size : 0; + visibility: collapse; + display : inline; + width : 0 + } + + .q-banner>.q-banner__avatar { + min-height: 38px + } + + .q-banner--dense>.q-banner__avatar { + min-height: 20px + } + + .q-item:after { + min-height: 32px + } + + .q-item--denseafter, + .q-list--dense>.q-itemafter { + min-height: 24px + } + + .q-toolbar:after { + min-height: 50px + } + + .q-notification--standard:after { + min-height: 48px + } + + .q-notification--multi-line { + min-height: 68px + } + + .q-btn__wrapper, + .q-menu .q-item__section--main, + .q-table__middle, + .q-time__content, + .q-toolbar__title { + flex-basis: auto + } + + .q-banner__content { + flex-basis: 0 !important + } + + .q-dialog__inner>.q-banner>.q-banner__content, + .q-menu>.q-banner>.q-banner__content { + flex-basis: auto !important + } + + .q-tab__content { + flex-basis: auto; + min-width : 100% + } + + .q-card__actions--vert { + flex: 0 0 auto + } + + .column { + min-width: 0% + } + + @media (-ms-high-contrast:none) and (min-width:0), + screen and (-ms-high-contrast:active) and (min-width:0) { + + .flex>.col, + .flex>.col-xs, + .row>.col, + .row>.col-xs { + flex-basis: auto; + min-width : 0% + } + } + + @media (-ms-high-contrast:none) and (min-width:600px), + screen and (-ms-high-contrast:active) and (min-width:600px) { + + .flex>.col-sm, + .row>.col-sm { + flex-basis: auto; + min-width : 0% + } + } + + @media (-ms-high-contrast:none) and (min-width:1024px), + screen and (-ms-high-contrast:active) and (min-width:1024px) { + + .flex>.col-md, + .row>.col-md { + flex-basis: auto; + min-width : 0% + } + } + + @media (-ms-high-contrast:none) and (min-width:1440px), + screen and (-ms-high-contrast:active) and (min-width:1440px) { + + .flex>.col-lg, + .row>.col-lg { + flex-basis: auto; + min-width : 0% + } + } + + @media (-ms-high-contrast:none) and (min-width:1920px), + screen and (-ms-high-contrast:active) and (min-width:1920px) { + + .flex>.col-xl, + .row>.col-xl { + flex-basis: auto; + min-width : 0% + } + } + + .q-item__section--avatar { + min-width: 56px + } + + button.q-btn--actionable:active:hover .q-btn__wrapper { + margin: -1px 1px 1px -1px + } + + .q-btn-group--push>button.q-btn--push.q-btn--actionable:active:hover .q-btn__wrapper { + margin: 1px 1px -1px -1px + } + + .q-btn { + overflow: visible + } + + .q-btn--wrap { + flex-direction: row + } + + .q-carousel__slide>* { + max-width: 100% + } + + .q-tabs--vertical .q-tab__indicator { + height: auto + } + + .q-spinner { + -webkit-animation: q-ie-spinner 2s linear infinite; + animation : q-ie-spinner 2s linear infinite; + transform-origin : center center; + opacity : 0.5 + } + + .q-spinner.q-spinner-mat .path { + stroke-dasharray: 89, 200 + } + + .q-checkbox__indet { + opacity: 0 + } + + .q-checkbox__inner--indet .q-checkbox__indet { + opacity: 1 + } + + .q-radio__check { + opacity: 0 + } + + .q-radio__inner--truthy .q-radio__check { + opacity: 1 + } + + .q-date__main { + min-height: 290px !important + } + + .q-date__months { + align-items: stretch + } + + .q-time--portrait .q-time__main { + display : flex; + flex-direction: column; + flex-wrap : nowrap; + flex : 1 0 auto + } + + .q-field__prefix, + .q-field__suffix { + flex: 1 0 auto + } + + .q-field__bottom--stale .q-field__messages { + left: 12px + } + + .q-field--borderless .q-field__bottom--stale .q-field__messages, + .q-field--standard .q-field__bottom--stale .q-field__messages { + left: 0 + } + + .q-field--float .q-field__label { + max-width: 100% + } + + .q-focus-helper { + z-index: 1 + } +} + +@-webkit-keyframes q-circular-progress-circle { + 0% { + stroke-dasharray : 1, 400; + stroke-dashoffset: 0 + } + + 50% { + stroke-dasharray : 400, 400; + stroke-dashoffset: -100 + } + + to { + stroke-dasharray : 400, 400; + stroke-dashoffset: -300 + } +} + +@keyframes q-circular-progress-circle { + 0% { + stroke-dasharray : 1, 400; + stroke-dashoffset: 0 + } + + 50% { + stroke-dasharray : 400, 400; + stroke-dashoffset: -100 + } + + to { + stroke-dasharray : 400, 400; + stroke-dashoffset: -300 + } +} + +@-webkit-keyframes q-expansion-done { + 0% { + --q-exp-done: 1 + } +} + +@keyframes q-expansion-done { + 0% { + --q-exp-done: 1 + } +} + +@-webkit-keyframes q-field-label { + 40% { + margin-left: 2px + } + + 60%, + 80% { + margin-left: -2px + } + + 70%, + 90% { + margin-left: 2px + } +} + +@keyframes q-field-label { + 40% { + margin-left: 2px + } + + 60%, + 80% { + margin-left: -2px + } + + 70%, + 90% { + margin-left: 2px + } +} + +@-webkit-keyframes q-autofill { + to { + background: transparent; + color : inherit + } +} + +@keyframes q-autofill { + to { + background: transparent; + color : inherit + } +} + +@-webkit-keyframes q-linear-progress--indeterminate { + 0% { + transform: translate3d(-35%, 0, 0) scale3d(0.35, 1, 1) + } + + 60% { + transform: translate3d(100%, 0, 0) scale3d(0.9, 1, 1) + } + + to { + transform: translate3d(100%, 0, 0) scale3d(0.9, 1, 1) + } +} + +@keyframes q-linear-progress--indeterminate { + 0% { + transform: translate3d(-35%, 0, 0) scale3d(0.35, 1, 1) + } + + 60% { + transform: translate3d(100%, 0, 0) scale3d(0.9, 1, 1) + } + + to { + transform: translate3d(100%, 0, 0) scale3d(0.9, 1, 1) + } +} + +@-webkit-keyframes q-linear-progress--indeterminate-short { + 0% { + transform: translate3d(-101%, 0, 0) scale3d(1, 1, 1) + } + + 60% { + transform: translate3d(107%, 0, 0) scale3d(0.01, 1, 1) + } + + to { + transform: translate3d(107%, 0, 0) scale3d(0.01, 1, 1) + } +} + +@keyframes q-linear-progress--indeterminate-short { + 0% { + transform: translate3d(-101%, 0, 0) scale3d(1, 1, 1) + } + + 60% { + transform: translate3d(107%, 0, 0) scale3d(0.01, 1, 1) + } + + to { + transform: translate3d(107%, 0, 0) scale3d(0.01, 1, 1) + } +} + +@-webkit-keyframes q-skeleton--fade { + 0% { + opacity: 1 + } + + 50% { + opacity: 0.4 + } + + to { + opacity: 1 + } +} + +@keyframes q-skeleton--fade { + 0% { + opacity: 1 + } + + 50% { + opacity: 0.4 + } + + to { + opacity: 1 + } +} + +@-webkit-keyframes q-skeleton--pulse { + 0% { + transform: scale(1) + } + + 50% { + transform: scale(0.85) + } + + to { + transform: scale(1) + } +} + +@keyframes q-skeleton--pulse { + 0% { + transform: scale(1) + } + + 50% { + transform: scale(0.85) + } + + to { + transform: scale(1) + } +} + +@-webkit-keyframes q-skeleton--pulse-x { + 0% { + transform: scaleX(1) + } + + 50% { + transform: scaleX(0.75) + } + + to { + transform: scaleX(1) + } +} + +@keyframes q-skeleton--pulse-x { + 0% { + transform: scaleX(1) + } + + 50% { + transform: scaleX(0.75) + } + + to { + transform: scaleX(1) + } +} + +@-webkit-keyframes q-skeleton--pulse-y { + 0% { + transform: scaleY(1) + } + + 50% { + transform: scaleY(0.75) + } + + to { + transform: scaleY(1) + } +} + +@keyframes q-skeleton--pulse-y { + 0% { + transform: scaleY(1) + } + + 50% { + transform: scaleY(0.75) + } + + to { + transform: scaleY(1) + } +} + +@-webkit-keyframes q-skeleton--wave { + 0% { + transform: translateX(-100%) + } + + to { + transform: translateX(100%) + } +} + +@keyframes q-skeleton--wave { + 0% { + transform: translateX(-100%) + } + + to { + transform: translateX(100%) + } +} + +@-webkit-keyframes q-spin { + 0% { + transform: rotate3d(0, 0, 1, 0deg) + } + + 25% { + transform: rotate3d(0, 0, 1, 90deg) + } + + 50% { + transform: rotate3d(0, 0, 1, 180deg) + } + + 75% { + transform: rotate3d(0, 0, 1, 270deg) + } + + to { + transform: rotate3d(0, 0, 1, 359deg) + } +} + +@keyframes q-spin { + 0% { + transform: rotate3d(0, 0, 1, 0deg) + } + + 25% { + transform: rotate3d(0, 0, 1, 90deg) + } + + 50% { + transform: rotate3d(0, 0, 1, 180deg) + } + + 75% { + transform: rotate3d(0, 0, 1, 270deg) + } + + to { + transform: rotate3d(0, 0, 1, 359deg) + } +} + +@-webkit-keyframes q-mat-dash { + 0% { + stroke-dasharray : 1, 200; + stroke-dashoffset: 0 + } + + 50% { + stroke-dasharray : 89, 200; + stroke-dashoffset: -35px + } + + to { + stroke-dasharray : 89, 200; + stroke-dashoffset: -124px + } +} + +@keyframes q-mat-dash { + 0% { + stroke-dasharray : 1, 200; + stroke-dashoffset: 0 + } + + 50% { + stroke-dasharray : 89, 200; + stroke-dashoffset: -35px + } + + to { + stroke-dasharray : 89, 200; + stroke-dashoffset: -124px + } +} + +@-webkit-keyframes q-notif-badge { + 15% { + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg) + } + + 30% { + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg) + } + + 45% { + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg) + } + + 60% { + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg) + } + + 75% { + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg) + } +} + +@keyframes q-notif-badge { + 15% { + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg) + } + + 30% { + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg) + } + + 45% { + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg) + } + + 60% { + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg) + } + + 75% { + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg) + } +} + +@-webkit-keyframes q-notif-progress { + 0% { + transform: scaleX(1) + } + + to { + transform: scaleX(0) + } +} + +@keyframes q-notif-progress { + 0% { + transform: scaleX(1) + } + + to { + transform: scaleX(0) + } +} + +@-webkit-keyframes q-scale { + 0% { + transform: scale(1) + } + + 50% { + transform: scale(1.04) + } + + to { + transform: scale(1) + } +} + +@keyframes q-scale { + 0% { + transform: scale(1) + } + + 50% { + transform: scale(1.04) + } + + to { + transform: scale(1) + } +} + +@-webkit-keyframes q-fade { + 0% { + opacity: 0 + } + + to { + opacity: 1 + } +} + +@keyframes q-fade { + 0% { + opacity: 0 + } + + to { + opacity: 1 + } +} + +@-webkit-keyframes q-ie-spinner { + 0% { + opacity: 0.5 + } + + 50% { + opacity: 1 + } + + to { + opacity: 0.5 + } +} + +@keyframes q-ie-spinner { + 0% { + opacity: 0.5 + } + + 50% { + opacity: 1 + } + + to { + opacity: 0.5 + } +} \ No newline at end of file diff --git a/src/renderer/lib/quasar/quasar.umd.min.js b/src/renderer/lib/quasar/quasar.umd.min.js new file mode 100644 index 00000000..339a125b --- /dev/null +++ b/src/renderer/lib/quasar/quasar.umd.min.js @@ -0,0 +1,6 @@ +/*! + * Quasar Framework v1.19.4 + * (c) 2015-present Razvan Stoenescu + * Released under the MIT License. + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("vue")):"function"==typeof define&&define.amd?define(["vue"],e):(t=t||self).Quasar=e(t.Vue)}(this,function(t){"use strict";t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;var e,i="undefined"==typeof window,n=!1,s=i;var o=!1===i&&("ontouchstart"in window||window.navigator.maxTouchPoints>0);function r(t){var r=t.toLowerCase(),a=function(t,e){var i=/(edge|edga|edgios)\/([\w.]+)/.exec(t)||/(opr)[\/]([\w.]+)/.exec(t)||/(vivaldi)[\/]([\w.]+)/.exec(t)||/(chrome|crios)[\/]([\w.]+)/.exec(t)||/(iemobile)[\/]([\w.]+)/.exec(t)||/(version)(applewebkit)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(t)||/(webkit)[\/]([\w.]+).*(version)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(t)||/(firefox|fxios)[\/]([\w.]+)/.exec(t)||/(webkit)[\/]([\w.]+)/.exec(t)||/(opera)(?:.*version|)[\/]([\w.]+)/.exec(t)||/(msie) ([\w.]+)/.exec(t)||t.indexOf("trident")>=0&&/(rv)(?::| )([\w.]+)/.exec(t)||t.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(t)||[];return{browser:i[5]||i[3]||i[1]||"",version:i[2]||i[4]||"0",versionNumber:i[4]||i[2]||"0",platform:e[0]||""}}(r,function(t){return/(ipad)/.exec(t)||/(ipod)/.exec(t)||/(windows phone)/.exec(t)||/(iphone)/.exec(t)||/(kindle)/.exec(t)||/(silk)/.exec(t)||/(android)/.exec(t)||/(win)/.exec(t)||/(mac)/.exec(t)||/(linux)/.exec(t)||/(cros)/.exec(t)||/(playbook)/.exec(t)||/(bb)/.exec(t)||/(blackberry)/.exec(t)||[]}(r)),l={};a.browser&&(l[a.browser]=!0,l.version=a.version,l.versionNumber=parseInt(a.versionNumber,10)),a.platform&&(l[a.platform]=!0);var c=l.android||l.ios||l.bb||l.blackberry||l.ipad||l.iphone||l.ipod||l.kindle||l.playbook||l.silk||l["windows phone"];return!0===c||r.indexOf("mobile")>-1?(l.mobile=!0,l.edga||l.edgios?(l.edge=!0,a.browser="edge"):l.crios?(l.chrome=!0,a.browser="chrome"):l.fxios&&(l.firefox=!0,a.browser="firefox")):l.desktop=!0,(l.ipod||l.ipad||l.iphone)&&(l.ios=!0),l["windows phone"]&&(l.winphone=!0,delete l["windows phone"]),(l.chrome||l.opr||l.safari||l.vivaldi||!0===l.mobile&&!0!==l.ios&&!0!==c)&&(l.webkit=!0),(l.rv||l.iemobile)&&(a.browser="ie",l.ie=!0),(l.safari&&l.blackberry||l.bb)&&(a.browser="blackberry",l.blackberry=!0),l.safari&&l.playbook&&(a.browser="playbook",l.playbook=!0),l.opr&&(a.browser="opera",l.opera=!0),l.safari&&l.android&&(a.browser="android",l.android=!0),l.safari&&l.kindle&&(a.browser="kindle",l.kindle=!0),l.safari&&l.silk&&(a.browser="silk",l.silk=!0),l.vivaldi&&(a.browser="vivaldi",l.vivaldi=!0),l.name=a.browser,l.platform=a.platform,!1===i&&(r.indexOf("electron")>-1?l.electron=!0:document.location.href.indexOf("-extension://")>-1?l.bex=!0:(void 0!==window.Capacitor?(l.capacitor=!0,l.nativeMobile=!0,l.nativeMobileWrapper="capacitor"):void 0===window._cordovaNative&&void 0===window.cordova||(l.cordova=!0,l.nativeMobile=!0,l.nativeMobileWrapper="cordova"),!0===o&&!0===l.mac&&(!0===l.desktop&&!0===l.safari||!0===l.nativeMobile&&!0!==l.android&&!0!==l.ios&&!0!==l.ipad)&&function(t){var i;e={is:Object.assign({},t)},delete t.mac,delete t.desktop;var n=Math.min(window.innerHeight,window.innerWidth)>414?"ipad":"iphone";Object.assign(t,((i={mobile:!0,ios:!0,platform:n})[n]=!0,i))}(l)),!0===(n=void 0===l.nativeMobile&&void 0===l.electron&&null!==document.querySelector("[data-server-rendered]"))&&(s=!0)),l}var a=!0!==i?navigator.userAgent||navigator.vendor||window.opera:"",l={has:{touch:!1,webStorage:!1},within:{iframe:!1}},c=!1===i?{userAgent:a,is:r(a),has:{touch:o,webStorage:function(){try{if(window.localStorage)return!0}catch(t){}return!1}()},within:{iframe:window.self!==window.top}}:l,u={install:function(o,r){var a=this;!0===i?r.server.push(function(t,e){t.platform=a.parseSSR(e.ssr)}):!0===n?(Object.assign(this,c,e,l),r.takeover.push(function(t){s=n=!1,Object.assign(t.platform,c),e=void 0}),t.util.defineReactive(o,"platform",this)):(Object.assign(this,c),o.platform=this)}};!0===i?u.parseSSR=function(t){var e=t.req.headers["user-agent"]||t.req.headers["User-Agent"]||"";return Object.assign({},c,{userAgent:e,is:r(e)})}:!0===c.is.ios&&window.navigator.vendor.toLowerCase().indexOf("apple");var h={hasPassive:!1,passiveCapture:!0,notPassiveCapture:!0};try{var d=Object.defineProperty({},"passive",{get:function(){Object.assign(h,{hasPassive:!0,passive:{passive:!0},notPassive:{passive:!1},passiveCapture:{passive:!0,capture:!0},notPassiveCapture:{passive:!1,capture:!0}})}});window.addEventListener("qtest",null,d),window.removeEventListener("qtest",null,d)}catch(t){}function p(){}function f(t){return 0===t.button}function m(t){return t.touches&&t.touches[0]?t=t.touches[0]:t.changedTouches&&t.changedTouches[0]?t=t.changedTouches[0]:t.targetTouches&&t.targetTouches[0]&&(t=t.targetTouches[0]),{top:t.clientY,left:t.clientX}}function v(t){if(t.path)return t.path;if(t.composedPath)return t.composedPath();for(var e=[],i=t.target;i;){if(e.push(i),"HTML"===i.tagName)return e.push(document),e.push(window),e;i=i.parentElement}}var g=40,_=800;function b(t){t.stopPropagation()}function y(t){!1!==t.cancelable&&t.preventDefault()}function S(t){!1!==t.cancelable&&t.preventDefault(),t.stopPropagation()}function w(t,e){if(void 0!==t&&(!0!==e||!0!==t.__dragPrevented)){var i=!0===e?function(t){t.__dragPrevented=!0,t.addEventListener("dragstart",y,h.notPassiveCapture)}:function(t){delete t.__dragPrevented,t.removeEventListener("dragstart",y,h.notPassiveCapture)};t.querySelectorAll("a, img").forEach(i)}}function C(t,e){void 0===e&&(e={});var i=e.bubbles;void 0===i&&(i=!1);var n=e.cancelable;void 0===n&&(n=!1);try{return new CustomEvent(t,{bubbles:i,cancelable:n})}catch(e){var s=document.createEvent("Event");return s.initEvent(t,i,n),s}}function x(t,e,i){var n="__q_"+e+"_evt";t[n]=void 0!==t[n]?t[n].concat(i):i,i.forEach(function(e){e[0].addEventListener(e[1],t[e[2]],h[e[3]])})}function k(t,e){var i="__q_"+e+"_evt";void 0!==t[i]&&(t[i].forEach(function(e){e[0].removeEventListener(e[1],t[e[2]],h[e[3]])}),t[i]=void 0)}var q={listenOpts:h,leftClick:f,middleClick:function(t){return 1===t.button},rightClick:function(t){return 2===t.button},position:m,getEventPath:v,getMouseWheelDistance:function(t){var e,i=t.deltaX,n=t.deltaY;if((i||n)&&t.deltaMode){var s=1===t.deltaMode?g:_;i*=s,n*=s}return t.shiftKey&&!i&&(n=(e=[i,n])[0],i=e[1]),{x:i,y:n}},stop:b,prevent:y,stopAndPrevent:S,preventDraggable:w,create:C};function T(t,e,i){var n;function s(){var s=this,o=arguments;clearTimeout(n),!0===i&&void 0===n&&t.apply(this,o),n=setTimeout(function(){n=void 0,!0!==i&&t.apply(s,o)},e)}return void 0===e&&(e=250),s.cancel=function(){clearTimeout(n)},s}var M=["sm","md","lg","xl"],$=h.passive,L={width:0,height:0,name:"xs",sizes:{sm:600,md:1024,lg:1440,xl:1920},lt:{sm:!0,md:!0,lg:!0,xl:!0},gt:{xs:!1,sm:!1,md:!1,lg:!1},xs:!0,sm:!1,md:!1,lg:!1,xl:!1,setSizes:p,setDebounce:p,install:function(e,s,o){var r=this;if(!0!==i){var a,l=window.visualViewport,u=l||window,h=document.scrollingElement||document.documentElement,d=void 0===l||!0===c.is.mobile?function(){return[Math.max(window.innerWidth,h.clientWidth),Math.max(window.innerHeight,h.clientHeight)]}:function(){return[l.width*l.scale+window.innerWidth-h.clientWidth,l.height*l.scale+window.innerHeight-h.clientHeight]},p=void 0!==o.screen&&!0===o.screen.bodyClasses,f=function(t){var e=d(),i=e[0],n=e[1];if(n!==r.height&&(r.height=n),i!==r.width)r.width=i;else if(!0!==t)return;var s=r.sizes;r.gt.xs=i>=s.sm,r.gt.sm=i>=s.md,r.gt.md=i>=s.lg,r.gt.lg=i>=s.xl,r.lt.sm=i<s.sm,r.lt.md=i<s.md,r.lt.lg=i<s.lg,r.lt.xl=i<s.xl,r.xs=r.lt.sm,r.sm=!0===r.gt.xs&&!0===r.lt.md,r.md=!0===r.gt.sm&&!0===r.lt.lg,r.lg=!0===r.gt.md&&!0===r.lt.xl,r.xl=r.gt.lg,(s=(!0===r.xs?"xs":!0===r.sm&&"sm")||!0===r.md&&"md"||!0===r.lg&&"lg"||"xl")!==r.name&&(!0===p&&(document.body.classList.remove("screen--"+r.name),document.body.classList.add("screen--"+s)),r.name=s)},m={},v=16;this.setSizes=function(t){M.forEach(function(e){void 0!==t[e]&&(m[e]=t[e])})},this.setDebounce=function(t){v=t};var g=function(){var t=getComputedStyle(document.body);t.getPropertyValue("--q-size-sm")&&M.forEach(function(e){r.sizes[e]=parseInt(t.getPropertyValue("--q-size-"+e),10)}),r.setSizes=function(t){M.forEach(function(e){t[e]&&(r.sizes[e]=t[e])}),f(!0)},r.setDebounce=function(t){void 0!==a&&u.removeEventListener("resize",a,$),a=t>0?T(f,t):f,u.addEventListener("resize",a,$)},r.setDebounce(v),Object.keys(m).length>0?(r.setSizes(m),m=void 0):f(),!0===p&&"xs"===r.name&&document.body.classList.add("screen--xs")};!0===n?s.takeover.push(g):g(),t.util.defineReactive(e,"screen",this)}else e.screen=this}},O={isActive:!1,mode:!1,install:function(e,s,o){var r=this,a=o.dark;if(this.isActive=!0===a,!0===i)return s.server.push(function(t,e){t.dark={isActive:!1,mode:!1,set:function(i){e.ssr.Q_BODY_CLASSES=e.ssr.Q_BODY_CLASSES.replace(" body--light","").replace(" body--dark","")+" body--"+(!0===i?"dark":"light"),t.dark.isActive=!0===i,t.dark.mode=i},toggle:function(){t.dark.set(!1===t.dark.isActive)}},t.dark.set(a)}),void(this.set=p);var l=void 0!==a&&a;if(!0===n){var c=function(t){r.__fromSSR=t},u=this.set;this.set=c,c(l),s.takeover.push(function(){r.set=u,r.set(r.__fromSSR)})}else this.set(l);t.util.defineReactive(this,"isActive",this.isActive),t.util.defineReactive(e,"dark",this)},set:function(t){var e=this;this.mode=t,"auto"===t?(void 0===this.__media&&(this.__media=window.matchMedia("(prefers-color-scheme: dark)"),this.__updateMedia=function(){e.set("auto")},this.__media.addListener(this.__updateMedia)),t=this.__media.matches):void 0!==this.__media&&(this.__media.removeListener(this.__updateMedia),this.__media=void 0),this.isActive=!0===t,document.body.classList.remove("body--"+(!0===t?"light":"dark")),document.body.classList.add("body--"+(!0===t?"dark":"light"))},toggle:function(){O.set(!1===O.isActive)},__media:void 0},B=function(){return!0};function E(t){return"string"==typeof t&&""!==t&&"/"!==t&&"#/"!==t}function z(t){return!0===t.startsWith("#")&&(t=t.substr(1)),!1===t.startsWith("/")&&(t="/"+t),!0===t.endsWith("/")&&(t=t.substr(0,t.length-1)),"#"+t}var P={__history:[],add:p,remove:p,install:function(t){var e=this;if(!0!==i){var n=c.is,s=n.cordova,o=n.capacitor;if(!0===s||!0===o){var r=t[!0===s?"cordova":"capacitor"];if((void 0===r||!1!==r.backButton)&&(!0!==o||void 0!==window.Capacitor&&void 0!==window.Capacitor.Plugins.App)){this.add=function(t){void 0===t.condition&&(t.condition=B),e.__history.push(t)},this.remove=function(t){var i=e.__history.indexOf(t);i>=0&&e.__history.splice(i,1)};var a=function(t){if(!1===t.backButtonExit)return function(){return!1};if("*"===t.backButtonExit)return B;var e=["#/"];return!0===Array.isArray(t.backButtonExit)&&e.push.apply(e,t.backButtonExit.filter(E).map(z)),function(){return e.includes(window.location.hash)}}(Object.assign({backButtonExit:!0},r)),l=function(){if(e.__history.length){var t=e.__history[e.__history.length-1];!0===t.condition()&&(e.__history.pop(),t.handler())}else!0===a()?navigator.app.exitApp():window.history.back()};!0===s?document.addEventListener("deviceready",function(){document.addEventListener("backbutton",l,!1)}):window.Capacitor.Plugins.App.addListener("backButton",l)}}}}},A={isoName:"en-us",nativeName:"English (US)",label:{clear:"Clear",ok:"OK",cancel:"Cancel",close:"Close",set:"Set",select:"Select",reset:"Reset",remove:"Remove",update:"Update",create:"Create",search:"Search",filter:"Filter",refresh:"Refresh"},date:{days:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),daysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),firstDayOfWeek:0,format24h:!1,pluralDay:"days"},table:{noData:"No data available",noResults:"No matching records found",loading:"Loading...",selectedRecords:function(t){return 1===t?"1 record selected.":(0===t?"No":t)+" records selected."},recordsPerPage:"Records per page:",allRows:"All",pagination:function(t,e,i){return t+"-"+e+" of "+i},columns:"Columns"},editor:{url:"URL",bold:"Bold",italic:"Italic",strikethrough:"Strikethrough",underline:"Underline",unorderedList:"Unordered List",orderedList:"Ordered List",subscript:"Subscript",superscript:"Superscript",hyperlink:"Hyperlink",toggleFullscreen:"Toggle Fullscreen",quote:"Quote",left:"Left align",center:"Center align",right:"Right align",justify:"Justify align",print:"Print",outdent:"Decrease indentation",indent:"Increase indentation",removeFormat:"Remove formatting",formatting:"Formatting",fontSize:"Font Size",align:"Align",hr:"Insert Horizontal Rule",undo:"Undo",redo:"Redo",heading1:"Heading 1",heading2:"Heading 2",heading3:"Heading 3",heading4:"Heading 4",heading5:"Heading 5",heading6:"Heading 6",paragraph:"Paragraph",code:"Code",size1:"Very small",size2:"A bit small",size3:"Normal",size4:"Medium-large",size5:"Big",size6:"Very big",size7:"Maximum",defaultFont:"Default Font",viewSource:"View Source"},tree:{noNodes:"No nodes available",noResults:"No matching nodes found"}};function I(){if(!0!==i){var t=navigator.language||navigator.languages[0]||navigator.browserLanguage||navigator.userLanguage||navigator.systemLanguage;return t?t.toLowerCase():void 0}}var D={getLocale:I,install:function(e,s,o){var r=this,a=o||A;this.set=function(t,s){void 0===t&&(t=A);var o=Object.assign({},t,{rtl:!0===t.rtl,getLocale:I});if(!0===i){if(void 0===s)return void console.error("SSR ERROR: second param required: Quasar.lang.set(lang, ssrContext)");var a=!0===o.rtl?"rtl":"ltr",l="lang="+o.isoName+" dir="+a;o.set=s.$q.lang.set,s.Q_HTML_ATTRS=void 0!==s.Q_PREV_LANG?s.Q_HTML_ATTRS.replace(s.Q_PREV_LANG,l):l,s.Q_PREV_LANG=l,s.$q.lang=o}else{if(!1===n){var c=document.documentElement;c.setAttribute("dir",!0===o.rtl?"rtl":"ltr"),c.setAttribute("lang",o.isoName)}o.set=r.set,e.lang=r.props=o,r.isoName=o.isoName,r.nativeName=o.nativeName}},!0===i?(s.server.push(function(t,e){t.lang={},t.lang.set=function(t){r.set(t,e.ssr)},t.lang.set(a)}),this.isoName=a.isoName,this.nativeName=a.nativeName,this.props=a):(t.util.defineReactive(e,"lang",{}),this.set(a))}},R=/^rgb(a)?\((\d{1,3}),(\d{1,3}),(\d{1,3}),?([01]?\.?\d*?)?\)$/;function F(t){var e=t.r,i=t.g,n=t.b,s=t.a,o=void 0!==s;if(e=Math.round(e),i=Math.round(i),n=Math.round(n),e>255||i>255||n>255||o&&s>100)throw new TypeError("Expected 3 numbers below 256 (and optionally one below 100)");return s=o?(256|Math.round(255*s/100)).toString(16).slice(1):"","#"+(n|i<<8|e<<16|1<<24).toString(16).slice(1)+s}function j(t){var e=t.r,i=t.g,n=t.b,s=t.a;return"rgb"+(void 0!==s?"a":"")+"("+e+","+i+","+n+(void 0!==s?","+s/100:"")+")"}function V(t){if("string"!=typeof t)throw new TypeError("Expected a string");3===(t=t.replace(/^#/,"")).length?t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]:4===t.length&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]+t[3]+t[3]);var e=parseInt(t,16);return t.length>6?{r:e>>24&255,g:e>>16&255,b:e>>8&255,a:Math.round((255&e)/2.55)}:{r:e>>16,g:e>>8&255,b:255&e}}function N(t){var e,i,n,s=t.h,o=t.s,r=t.v,a=t.a;o/=100,r/=100,s/=360;var l=Math.floor(6*s),c=6*s-l,u=r*(1-o),h=r*(1-c*o),d=r*(1-(1-c)*o);switch(l%6){case 0:e=r,i=d,n=u;break;case 1:e=h,i=r,n=u;break;case 2:e=u,i=r,n=d;break;case 3:e=u,i=h,n=r;break;case 4:e=d,i=u,n=r;break;case 5:e=r,i=u,n=h}return{r:Math.round(255*e),g:Math.round(255*i),b:Math.round(255*n),a:a}}function H(t){var e,i=t.r,n=t.g,s=t.b,o=t.a,r=Math.max(i,n,s),a=Math.min(i,n,s),l=r-a,c=0===r?0:l/r,u=r/255;switch(r){case a:e=0;break;case i:e=n-s+l*(n<s?6:0),e/=6*l;break;case n:e=s-i+2*l,e/=6*l;break;case s:e=i-n+4*l,e/=6*l}return{h:Math.round(360*e),s:Math.round(100*c),v:Math.round(100*u),a:o}}function Q(t){if("string"!=typeof t)throw new TypeError("Expected a string");var e=t.replace(/ /g,""),i=R.exec(e);if(null===i)return V(e);var n={r:Math.min(255,parseInt(i[2],10)),g:Math.min(255,parseInt(i[3],10)),b:Math.min(255,parseInt(i[4],10))};if(i[1]){var s=parseFloat(i[5]);n.a=100*Math.min(1,!0===isNaN(s)?1:s)}return n}function W(t){if("string"!=typeof t&&(!t||void 0===t.r))throw new TypeError("Expected a string or a {r, g, b} object as color");var e="string"==typeof t?Q(t):t,i=e.r/255,n=e.g/255,s=e.b/255;return.2126*(i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4))+.7152*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))+.0722*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))}function Y(t,e,i){if(void 0===i&&(i=document.body),"string"!=typeof t)throw new TypeError("Expected a string as color");if("string"!=typeof e)throw new TypeError("Expected a string as value");if(!(i instanceof Element))throw new TypeError("Expected a DOM element");i.style.setProperty("--q-color-"+t,e)}function U(t,e){if(void 0===e&&(e=document.body),"string"!=typeof t)throw new TypeError("Expected a string as color");if(!(e instanceof Element))throw new TypeError("Expected a DOM element");return getComputedStyle(e).getPropertyValue("--q-color-"+t).trim()||null}var K={rgbToHex:F,hexToRgb:V,hsvToRgb:N,rgbToHsv:H,textToRgb:Q,lighten:function(t,e){if("string"!=typeof t)throw new TypeError("Expected a string as color");if("number"!=typeof e)throw new TypeError("Expected a numeric percent");var i=Q(t),n=e<0?0:255,s=Math.abs(e)/100,o=i.r,r=i.g,a=i.b;return"#"+(16777216+65536*(Math.round((n-o)*s)+o)+256*(Math.round((n-r)*s)+r)+(Math.round((n-a)*s)+a)).toString(16).slice(1)},luminosity:W,brightness:function(t){if("string"!=typeof t&&(!t||void 0===t.r))throw new TypeError("Expected a string or a {r, g, b} object as color");var e="string"==typeof t?Q(t):t;return(299*e.r+587*e.g+114*e.b)/1e3},blend:function(t,e){if("string"!=typeof t&&(!t||void 0===t.r))throw new TypeError("Expected a string or a {r, g, b[, a]} object as fgColor");if("string"!=typeof e&&(!e||void 0===e.r))throw new TypeError("Expected a string or a {r, g, b[, a]} object as bgColor");var i="string"==typeof t?Q(t):t,n=i.r/255,s=i.g/255,o=i.b/255,r=void 0!==i.a?i.a/100:1,a="string"==typeof e?Q(e):e,l=a.r/255,c=a.g/255,u=a.b/255,h=void 0!==a.a?a.a/100:1,d=r+h*(1-r),p={r:Math.round((n*r+l*h*(1-r))/d*255),g:Math.round((s*r+c*h*(1-r))/d*255),b:Math.round((o*r+u*h*(1-r))/d*255),a:Math.round(100*d)};return"string"==typeof t?F(p):p},changeAlpha:function(t,e){if("string"!=typeof t)throw new TypeError("Expected a string as color");if(void 0===e||e<-1||e>1)throw new TypeError("Expected offset to be between -1 and 1");var i=Q(t),n=i.r,s=i.g,o=i.b,r=i.a,a=void 0!==r?r/100:0;return F({r:n,g:s,b:o,a:Math.round(100*Math.min(1,Math.max(0,a+e)))})},setBrand:Y,getBrand:U,getPaletteColor:function(t){if("string"!=typeof t)throw new TypeError("Expected a string as color");var e=document.createElement("div");e.className="text-"+t+" invisible fixed no-pointer-events",document.body.appendChild(e);var i=getComputedStyle(e).getPropertyValue("color");return e.remove(),F(Q(i))}},X=!1;function G(t){X=!0===t.isComposing}function Z(t){return!0===X||t!==Object(t)||!0===t.isComposing||!0===t.qKeyEvent}function J(t,e){return!0!==Z(t)&&[].concat(e).includes(t.keyCode)}function tt(t,e){var i=t.is,n=t.has,s=t.within,o=[!0===i.desktop?"desktop":"mobile",(!1===n.touch?"no-":"")+"touch"];if(!0===i.mobile){var r=function(t){return!0===t.ios?"ios":!0===t.android?"android":void 0}(i);void 0!==r&&o.push("platform-"+r)}if(!0===i.nativeMobile){var a=i.nativeMobileWrapper;o.push(a),o.push("native-mobile"),!0!==i.ios||void 0!==e[a]&&!1===e[a].iosStatusBarPadding||o.push("q-ios-padding")}else!0===i.electron?o.push("electron"):!0===i.bex&&o.push("bex");return!0===s.iframe&&o.push("within-iframe"),o}var et={install:function(t,s){if(!0!==i){if(!0===n)r=document.body.className,a=r,void 0!==e&&(a=a.replace("desktop","platform-ios mobile")),!0===c.has.touch&&(a=a.replace("no-touch","touch")),!0===c.within.iframe&&(a+=" within-iframe"),r!==a&&(document.body.className=a);else{var o=tt(c,s);!0===c.is.ie&&11===c.is.versionNumber?o.forEach(function(t){return document.body.classList.add(t)}):document.body.classList.add.apply(document.body.classList,o)}var r,a;void 0!==s.brand&&function(t){for(var e in t)Y(e,t[e])}(s.brand),!0===c.is.ios&&document.body.addEventListener("touchstart",p),window.addEventListener("keydown",G,!0)}else t.server.push(function(t,e){var i=tt(t.platform,s),n=e.ssr.setBodyClasses;void 0!==s.screen&&!0===s.screen.bodyClass&&i.push("screen--xs"),"function"==typeof n?n(i):e.ssr.Q_BODY_CLASSES=i.join(" ")})}},it={name:"material-icons",type:{positive:"check_circle",negative:"warning",info:"info",warning:"priority_high"},arrow:{up:"arrow_upward",right:"arrow_forward",down:"arrow_downward",left:"arrow_back",dropdown:"arrow_drop_down"},chevron:{left:"chevron_left",right:"chevron_right"},colorPicker:{spectrum:"gradient",tune:"tune",palette:"style"},pullToRefresh:{icon:"refresh"},carousel:{left:"chevron_left",right:"chevron_right",up:"keyboard_arrow_up",down:"keyboard_arrow_down",navigationIcon:"lens"},chip:{remove:"cancel",selected:"check"},datetime:{arrowLeft:"chevron_left",arrowRight:"chevron_right",now:"access_time",today:"today"},editor:{bold:"format_bold",italic:"format_italic",strikethrough:"strikethrough_s",underline:"format_underlined",unorderedList:"format_list_bulleted",orderedList:"format_list_numbered",subscript:"vertical_align_bottom",superscript:"vertical_align_top",hyperlink:"link",toggleFullscreen:"fullscreen",quote:"format_quote",left:"format_align_left",center:"format_align_center",right:"format_align_right",justify:"format_align_justify",print:"print",outdent:"format_indent_decrease",indent:"format_indent_increase",removeFormat:"format_clear",formatting:"text_format",fontSize:"format_size",align:"format_align_left",hr:"remove",undo:"undo",redo:"redo",heading:"format_size",code:"code",size:"format_size",font:"font_download",viewSource:"code"},expansionItem:{icon:"keyboard_arrow_down",denseIcon:"arrow_drop_down"},fab:{icon:"add",activeIcon:"close"},field:{clear:"cancel",error:"error"},pagination:{first:"first_page",prev:"keyboard_arrow_left",next:"keyboard_arrow_right",last:"last_page"},rating:{icon:"grade"},stepper:{done:"check",active:"edit",error:"warning"},tabs:{left:"chevron_left",right:"chevron_right",up:"keyboard_arrow_up",down:"keyboard_arrow_down"},table:{arrowUp:"arrow_upward",warning:"warning",firstPage:"first_page",prevPage:"chevron_left",nextPage:"chevron_right",lastPage:"last_page"},tree:{icon:"play_arrow"},uploader:{done:"done",clear:"clear",add:"add_box",upload:"cloud_upload",removeQueue:"clear_all",removeUploaded:"done_all"}},nt={install:function(e,n,s){var o=this,r=s||it;this.set=function(t,n){var s=Object.assign({},t);if(!0===i){if(void 0===n)return void console.error("SSR ERROR: second param required: Quasar.iconSet.set(iconSet, ssrContext)");s.set=n.$q.iconSet.set,n.$q.iconSet=s}else s.set=o.set,e.iconSet=s},!0===i?n.server.push(function(t,e){t.iconSet={},t.iconSet.set=function(t){o.set(t,e.ssr)},t.iconSet.set(r)}):(t.util.defineReactive(e,"iconMapFn",void 0),t.util.defineReactive(e,"iconSet",{}),this.set(r))}},st=[u,L,O],ot={server:[],takeover:[]},rt={version:"1.19.4",config:{}};var at=["B","KB","MB","GB","TB","PB"];function lt(t){for(var e=0;parseInt(t,10)>=1024&&e<at.length-1;)t/=1024,++e;return""+t.toFixed(1)+at[e]}function ct(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t,e,i){return i<=e?e:Math.min(i,Math.max(e,t))}function ht(t,e,i){if(i<=e)return e;var n=i-e+1,s=e+(t-e)%n;return s<e&&(s=n+s),0===s?0:s}function dt(t,e,i){if(void 0===e&&(e=2),void 0===i&&(i="0"),void 0===t||null===t)return t;var n=""+t;return n.length>=e?n:new Array(e-n.length+1).join(i)+n}var pt={humanStorageSize:lt,capitalize:ct,between:ut,normalizeToInterval:ht,pad:dt};function ft(t,e,n){if(!0===i)return n;var s="__qcache_"+e;return void 0===t[s]?t[s]=n:t[s]}function mt(t,e,n){if(!0===i)return n();var s="__qcache_"+e;return void 0===t[s]?t[s]=n():t[s]}function vt(t,e){var i;return{data:function(){var i,n={},s=this[t];for(var o in s)n[o]=s[o];return(i={})[e]=n,i},watch:(i={},i[t]=function(t,i){var n=this[e];if(void 0!==i)for(var s in i)void 0===t[s]&&this.$delete(n,s);for(var o in t)n[o]!==t[o]&&this.$set(n,o,t[o])},i)}}var gt={"aria-hidden":"true"},_t={tabindex:0,type:"button","aria-hidden":!1,role:null},bt=vt("$attrs","qAttrs"),yt=i?null:XMLHttpRequest,St=i?null:yt.prototype.open,wt=["top","right","bottom","left"],Ct=[],xt=0;var kt=t.extend({name:"QAjaxBar",props:{position:{type:String,default:"top",validator:function(t){return wt.includes(t)}},size:{type:String,default:"2px"},color:String,reverse:Boolean,skipHijack:Boolean,hijackFilter:Function},data:function(){return{calls:0,progress:0,onScreen:!1,animate:!0}},computed:{classes:function(){return"q-loading-bar q-loading-bar--"+this.position+(void 0!==this.color?" bg-"+this.color:"")+(!0===this.animate?"":" no-transition")},style:function(){var t=this.onScreen,e=function(t){var e=t.p,i=t.pos,n=t.active,s=t.horiz,o=t.reverse,r=t.dir,a=1,l=1;return!0===s?(!0===o&&(a=-1),"bottom"===i&&(l=-1),{transform:"translate3d("+a*(e-100)+"%,"+(n?0:-200*l)+"%,0)"}):(!0===o&&(l=-1),"right"===i&&(a=-1),{transform:"translate3d("+(n?0:r*a*-200)+"%,"+l*(e-100)+"%,0)"})}({p:this.progress,pos:this.position,active:t,horiz:this.horizontal,reverse:!0===this.$q.lang.rtl&&["top","bottom"].includes(this.position)?!1===this.reverse:this.reverse,dir:!0===this.$q.lang.rtl?-1:1});return e[this.sizeProp]=this.size,e.opacity=t?1:0,e},horizontal:function(){return"top"===this.position||"bottom"===this.position},sizeProp:function(){return this.horizontal?"height":"width"},attrs:function(){return!0===this.onScreen?{role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":this.progress}:gt}},methods:{start:function(t){var e=this;void 0===t&&(t=300);var i=this.speed,n=this.speed=Math.max(0,t)||0;return this.calls++,this.calls>1?(0===i&&n>0?this.__work():i>0&&n<=0&&clearTimeout(this.timer),this.calls):(clearTimeout(this.timer),this.$emit("start"),this.progress=0,this.timer=setTimeout(function(){e.animate=!0,n>0&&e.__work()},!0===this.onScreen?500:1),!0!==this.onScreen&&(this.onScreen=!0,this.animate=!1),this.calls)},increment:function(t){return this.calls>0&&(this.progress=function(t,e){return"number"!=typeof e&&(e=t<25?3*Math.random()+3:t<65?3*Math.random():t<85?2*Math.random():t<99?.6:0),ut(t+e,0,100)}(this.progress,t)),this.calls},stop:function(){var t=this;if(this.calls=Math.max(0,this.calls-1),this.calls>0)return this.calls;clearTimeout(this.timer),this.$emit("stop");var e=function(){t.animate=!0,t.progress=100,t.timer=setTimeout(function(){t.onScreen=!1},1e3)};return 0===this.progress?this.timer=setTimeout(e,1):e(),this.calls},__work:function(){var t=this;this.progress<100&&(this.timer=setTimeout(function(){t.increment(),t.__work()},this.speed))}},mounted:function(){var t,e=this;!0!==this.skipHijack&&(this.hijacked=!0,t={start:this.start,stop:this.stop,getHijackFilter:function(){return e.hijackFilter||null}},xt++,Ct.push(t),xt>1||(yt.prototype.open=function(t,e){var i=[];this.addEventListener("loadstart",function(){Ct.forEach(function(t){var n=t.getHijackFilter();null!==n&&!0!==n(e)||(t.start(),i.push(t.stop))})},{once:!0}),this.addEventListener("loadend",function(){i.forEach(function(t){t()})},{once:!0}),St.apply(this,arguments)}))},beforeDestroy:function(){var t;clearTimeout(this.timer),!0===this.hijacked&&(t=this.start,Ct=Ct.filter(function(e){return e.start!==t}),(xt=Math.max(0,xt-1))||(yt.prototype.open=St))},render:function(t){return t("div",{class:this.classes,style:this.style,attrs:this.attrs})}}),qt={xs:18,sm:24,md:32,lg:38,xl:46};function Tt(t){return{props:{size:String},computed:{sizeStyle:function(){if(void 0!==this.size)return{fontSize:this.size in t?t[this.size]+"px":this.size}}}}}var Mt=Tt(qt),$t={props:{tag:{type:String,default:"div"}}},Lt=vt("$listeners","qListeners");function Ot(t,e,i){return void 0!==t.$scopedSlots[e]?t.$scopedSlots[e]():i}function Bt(t,e,i){return void 0!==t.$scopedSlots[e]?[].concat(t.$scopedSlots[e]()):i}function Et(t,e,i){return void 0!==e.$scopedSlots[i]?t.concat(e.$scopedSlots[i]()):t}function zt(t,e,i){if(void 0===e.$scopedSlots[i])return t;var n=e.$scopedSlots[i]();return void 0!==t?t.concat(n):n}var Pt=function(t){return t},At=function(t){return"ionicons "+t},It={"mdi-":function(t){return"mdi "+t},"icon-":Pt,"bt-":function(t){return"bt "+t},"eva-":function(t){return"eva "+t},"ion-md":At,"ion-ios":At,"ion-logo":At,"iconfont ":Pt,"ti-":function(t){return"themify-icon "+t},"bi-":function(t){return"bootstrap-icons "+t}},Dt={o_:"-outlined",r_:"-round",s_:"-sharp"},Rt={sym_o_:"-outlined",sym_r_:"-rounded",sym_s_:"-sharp"},Ft=new RegExp("^("+Object.keys(It).join("|")+")"),jt=new RegExp("^("+Object.keys(Dt).join("|")+")"),Vt=new RegExp("^("+Object.keys(Rt).join("|")+")"),Nt=/^[Mm]\s?[-+]?\.?\d/,Ht=/^img:/,Qt=/^svguse:/,Wt=/^ion-/,Yt=/^(fa-(solid|regular|light|brands|duotone|thin)|[lf]a[srlbdk]?) /,Ut=t.extend({name:"QIcon",mixins:[Lt,Mt,$t],props:{tag:{type:String,default:"i"},name:String,color:String,left:Boolean,right:Boolean},computed:{classes:function(){return"q-icon"+(!0===this.left?" on-left":"")+(!0===this.right?" on-right":"")+(void 0!==this.color?" text-"+this.color:"")},type:function(){var t,e=this,i=this.name;if("none"===i||!i)return{none:!0};if(void 0!==this.$q.iconMapFn){var n=this.$q.iconMapFn(i);if(void 0!==n){if(void 0===n.icon)return{cls:n.cls,content:void 0!==n.content?n.content:" "};if("none"===(i=n.icon)||!i)return{none:!0}}}if(!0===Nt.test(i)){var s=i.split("|"),o=s[0],r=s[1];return void 0===r&&(r="0 0 24 24"),{svg:!0,viewBox:r,nodes:o.split("&&").map(function(t){var i=t.split("@@"),n=i[0],s=i[1],o=i[2];return e.$createElement("path",{attrs:{d:n,transform:o},style:s})})}}if(!0===Ht.test(i))return{img:!0,src:i.substring(4)};if(!0===Qt.test(i)){var a=i.split("|"),l=a[0],c=a[1];return void 0===c&&(c="0 0 24 24"),{svguse:!0,src:l.substring(7),viewBox:c}}var u=" ",h=i.match(Ft);if(null!==h)t=It[h[1]](i);else if(!0===Yt.test(i))t=i;else if(!0===Wt.test(i))t="ionicons ion-"+(!0===this.$q.platform.is.ios?"ios":"md")+i.substr(3);else if(!0===Vt.test(i)){t="notranslate material-symbols";var d=i.match(Vt);null!==d&&(i=i.substring(6),t+=Rt[d[1]]),u=i}else{t="notranslate material-icons";var p=i.match(jt);null!==p&&(i=i.substring(2),t+=Dt[p[1]]),u=i}return{cls:t,content:u}}},render:function(t){var e={class:this.classes,style:this.sizeStyle,on:Object.assign({},this.qListeners),attrs:{"aria-hidden":"true",role:"presentation"}};return!0===this.type.none?t(this.tag,e,Ot(this,"default")):!0===this.type.img?t("span",e,Et([t("img",{attrs:{src:this.type.src}})],this,"default")):!0===this.type.svg?t("span",e,Et([t("svg",{attrs:{viewBox:this.type.viewBox||"0 0 24 24",focusable:"false"}},this.type.nodes)],this,"default")):!0===this.type.svguse?t("span",e,Et([t("svg",{attrs:{viewBox:this.type.viewBox,focusable:"false"}},[t("use",{attrs:{"xlink:href":this.type.src}})])],this,"default")):(void 0!==this.type.cls&&(e.class+=" "+this.type.cls),t(this.tag,e,Et([this.type.content],this,"default")))}}),Kt=t.extend({name:"QAvatar",mixins:[Lt,Mt],props:{fontSize:String,color:String,textColor:String,icon:String,square:Boolean,rounded:Boolean},computed:{classes:function(){var t;return(t={})["bg-"+this.color]=this.color,t["text-"+this.textColor+" q-chip--colored"]=this.textColor,t["q-avatar--square"]=this.square,t["rounded-borders"]=this.rounded,t},contentStyle:function(){if(this.fontSize)return{fontSize:this.fontSize}}},render:function(t){var e=void 0!==this.icon?[t(Ut,{props:{name:this.icon}})]:void 0;return t("div",{staticClass:"q-avatar",style:this.sizeStyle,class:this.classes,on:Object.assign({},this.qListeners)},[t("div",{staticClass:"q-avatar__content row flex-center overflow-hidden",style:this.contentStyle},zt(e,this,"default"))])}}),Xt=t.extend({name:"QBadge",mixins:[Lt],props:{color:String,textColor:String,floating:Boolean,transparent:Boolean,multiLine:Boolean,outline:Boolean,rounded:Boolean,label:[Number,String],align:{type:String,validator:function(t){return["top","middle","bottom"].includes(t)}}},computed:{style:function(){if(void 0!==this.align)return{verticalAlign:this.align}},classes:function(){var t=!0===this.outline&&this.color||this.textColor;return"q-badge flex inline items-center no-wrap q-badge--"+(!0===this.multiLine?"multi":"single")+"-line"+(!0===this.outline?" q-badge--outline":void 0!==this.color?" bg-"+this.color:"")+(void 0!==t?" text-"+t:"")+(!0===this.floating?" q-badge--floating":"")+(!0===this.rounded?" q-badge--rounded":"")+(!0===this.transparent?" q-badge--transparent":"")},attrs:function(){return{role:"alert","aria-label":this.label}}},render:function(t){return t("div",{style:this.style,class:this.classes,attrs:this.attrs,on:Object.assign({},this.qListeners)},void 0!==this.label?[this.label]:Ot(this,"default"))}}),Gt={props:{dark:{type:Boolean,default:null}},computed:{isDark:function(){return null===this.dark?this.$q.dark.isActive:this.dark}}},Zt={role:"alert"},Jt=t.extend({name:"QBanner",mixins:[Lt,Gt],props:{inlineActions:Boolean,dense:Boolean,rounded:Boolean},render:function(t){var e=Ot(this,"action"),i=[t("div",{staticClass:"q-banner__avatar col-auto row items-center self-start"},Ot(this,"avatar")),t("div",{staticClass:"q-banner__content col text-body2"},Ot(this,"default"))];return void 0!==e&&i.push(t("div",{staticClass:"q-banner__actions row items-center justify-end",class:"col-"+(!0===this.inlineActions?"auto":"all")},e)),t("div",{staticClass:"q-banner row items-center",class:{"q-banner--top-padding":void 0!==e&&!this.inlineActions,"q-banner--dense":this.dense,"q-banner--dark q-dark":this.isDark,"rounded-borders":this.rounded},attrs:Zt,on:Object.assign({},this.qListeners)},i)}}),te={role:"toolbar"},ee=t.extend({name:"QBar",mixins:[Lt,Gt],props:{dense:Boolean},computed:{classes:function(){return"q-bar--"+(!0===this.dense?"dense":"standard")+" q-bar--"+(!0===this.isDark?"dark":"light")}},render:function(t){return t("div",{staticClass:"q-bar row no-wrap items-center",class:this.classes,attrs:te,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),ie={left:"start",center:"center",right:"end",between:"between",around:"around",evenly:"evenly",stretch:"stretch"},ne=Object.keys(ie),se={props:{align:{type:String,validator:function(t){return ne.includes(t)}}},computed:{alignClass:function(){var t=void 0===this.align?!0===this.vertical?"stretch":"left":this.align;return(!0===this.vertical?"items":"justify")+"-"+ie[t]}}},oe=[!0,""],re=t.extend({name:"QBreadcrumbs",mixins:[Lt,se],props:{separator:{type:String,default:"/"},separatorColor:String,activeColor:{type:String,default:"primary"},gutter:{type:String,validator:function(t){return["none","xs","sm","md","lg","xl"].includes(t)},default:"sm"}},computed:{classes:function(){return this.alignClass+("none"===this.gutter?"":" q-gutter-"+this.gutter)},sepClass:function(){return this.separatorColor?" text-"+this.separatorColor:""},activeClass:function(){return" text-"+this.activeColor}},render:function(t){var e=this,i=Ot(this,"default");if(void 0!==i){var n=1,s=[],o=i.filter(function(t){return void 0!==t.tag&&t.tag.endsWith("-QBreadcrumbsEl")}).length,r=void 0!==this.$scopedSlots.separator?this.$scopedSlots.separator:function(){return e.separator};return i.forEach(function(i){if(void 0!==i.tag&&i.tag.endsWith("-QBreadcrumbsEl")){var a=n<o,l=oe.includes(i.componentOptions.propsData.disable),c=!0===a?!0!==l?e.activeClass:"":" q-breadcrumbs--last";n++,s.push(t("div",{staticClass:"flex items-center"+c},[i])),!0===a&&s.push(t("div",{staticClass:"q-breadcrumbs__separator"+e.sepClass},r()))}else s.push(i)}),t("div",{staticClass:"q-breadcrumbs",on:Object.assign({},this.qListeners)},[t("div",{staticClass:"flex items-center",class:this.classes},s)])}}}),ae={props:{to:[String,Object],exact:Boolean,append:Boolean,replace:Boolean,activeClass:{type:String,default:"q-router-link--active"},exactActiveClass:{type:String,default:"q-router-link--exact-active"},href:String,target:String,disable:Boolean},computed:{hasHrefLink:function(){return!0!==this.disable&&void 0!==this.href},hasRouterLinkProps:function(){return void 0!==this.$router&&!0!==this.disable&&!0!==this.hasHrefLink&&void 0!==this.to&&null!==this.to&&""!==this.to},linkRoute:function(){if(!0===this.hasRouterLinkProps)try{return!0===this.append?this.$router.resolve(this.to,this.$route,!0):this.$router.resolve(this.to)}catch(t){}return null},hasRouterLink:function(){return null!==this.linkRoute},hasLink:function(){return!0===this.hasHrefLink||!0===this.hasRouterLink},linkTag:function(){return!0===this.hasRouterLink?"router-link":"a"===this.type||!0===this.hasLink?"a":this.tag||this.fallbackTag||"div"},linkProps:function(){return!0===this.hasHrefLink?{attrs:{href:this.href,target:this.target}}:!0===this.hasRouterLink?{props:{to:this.to,exact:this.exact,append:this.append,replace:this.replace,activeClass:this.activeClass,exactActiveClass:this.exactActiveClass},attrs:{href:this.linkRoute.href,target:this.target}}:{}}}},le=t.extend({name:"QBreadcrumbsEl",mixins:[Lt,ae],props:{label:String,icon:String},computed:{iconClass:function(){return"q-breadcrumbs__el-icon"+(void 0!==this.label?" q-breadcrumbs__el-icon--with-label":"")},renderData:function(){var t;return Object.assign({staticClass:"q-breadcrumbs__el q-link flex inline items-center relative-position "+(!0!==this.disable?"q-link--focusable":"q-breadcrumbs__el--disabled")},this.linkProps,((t={})[!0===this.hasRouterLink?"nativeOn":"on"]=Object.assign({},this.qListeners),t))}},beforeCreate:function(){this.fallbackTag="span"},render:function(t){var e=[];return void 0!==this.icon&&e.push(t(Ut,{class:this.iconClass,props:{name:this.icon}})),void 0!==this.label&&e.push(this.label),t(this.linkTag,this.renderData,Et(e,this,"default"))}}),ce={mixins:[Lt],props:{color:String,size:{type:[Number,String],default:"1em"}},computed:{cSize:function(){return this.size in qt?qt[this.size]+"px":this.size},classes:function(){if(this.color)return"text-"+this.color}}},ue=t.extend({name:"QSpinner",mixins:[ce],props:{thickness:{type:Number,default:5}},render:function(t){return t("svg",{staticClass:"q-spinner q-spinner-mat",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"25 25 50 50"}},[t("circle",{staticClass:"path",attrs:{cx:"50",cy:"50",r:"20",fill:"none",stroke:"currentColor","stroke-width":this.thickness,"stroke-miterlimit":"10"}})])}});function he(t){if(t===window)return{top:0,left:0};var e=t.getBoundingClientRect();return{top:e.top,left:e.left}}function de(t){return t===window?window.innerHeight:t.getBoundingClientRect().height}function pe(t,e){var i=t.style;Object.keys(e).forEach(function(t){i[t]=e[t]})}function fe(t){var e=typeof t;if("function"===e&&(t=t()),"string"===e)try{t=document.querySelector(t)}catch(t){}return t!==Object(t)?null:!0===t._isVue&&void 0!==t.$el?t.$el:t}function me(t){return t===document.documentElement||null===t?document.body:t}var ve={offset:he,style:function(t,e){return window.getComputedStyle(t).getPropertyValue(e)},height:de,width:function(t){return t===window?window.innerWidth:t.getBoundingClientRect().width},css:pe,cssBatch:function(t,e){t.forEach(function(t){return pe(t,e)})},ready:function(t){if("function"==typeof t)return"loading"!==document.readyState?t():void document.addEventListener("DOMContentLoaded",t,!1)}};function ge(t,e){void 0===e&&(e=250);var i,n=!1;return function(){return!1===n&&(n=!0,setTimeout(function(){n=!1},e),i=t.apply(this,arguments)),i}}function _e(t,e,i,n){!0===i.modifiers.stop&&b(t);var s=i.modifiers.color,o=i.modifiers.center;o=!0===o||!0===n;var r=document.createElement("span"),a=document.createElement("span"),l=m(t),c=e.getBoundingClientRect(),u=c.left,h=c.top,d=c.width,p=c.height,f=Math.sqrt(d*d+p*p),v=f/2,g=(d-f)/2+"px",_=o?g:l.left-u-v+"px",y=(p-f)/2+"px",S=o?y:l.top-h-v+"px";a.className="q-ripple__inner",pe(a,{height:f+"px",width:f+"px",transform:"translate3d("+_+","+S+",0) scale3d(.2,.2,1)",opacity:0}),r.className="q-ripple"+(s?" text-"+s:""),r.setAttribute("dir","ltr"),r.appendChild(a),e.appendChild(r);var w=function(){r.remove(),clearTimeout(C)};i.abort.push(w);var C=setTimeout(function(){a.classList.add("q-ripple__inner--enter"),a.style.transform="translate3d("+g+","+y+",0) scale3d(1,1,1)",a.style.opacity=.2,C=setTimeout(function(){a.classList.remove("q-ripple__inner--enter"),a.classList.add("q-ripple__inner--leave"),a.style.opacity=0,C=setTimeout(function(){r.remove(),i.abort.splice(i.abort.indexOf(w),1)},275)},250)},50)}function be(t,e){var i=e.modifiers,n=e.value,s=e.arg,o=Object.assign({},rt.config.ripple,i,n);t.modifiers={early:!0===o.early,stop:!0===o.stop,center:!0===o.center,color:o.color||s,keyCodes:[].concat(o.keyCodes||13)}}function ye(t){var e=t.__qripple;void 0!==e&&(e.abort.forEach(function(t){t()}),k(e,"main"),delete t._qripple)}var Se={name:"ripple",inserted:function(t,e){void 0!==t.__qripple&&(ye(t),t.__qripple_destroyed=!0);var i={enabled:!1!==e.value,modifiers:{},abort:[],start:function(e){!0===i.enabled&&!0!==e.qSkipRipple&&(!0!==c.is.ie||e.clientX>=0)&&e.type===(!0===i.modifiers.early?"pointerdown":"click")&&_e(e,t,i,!0===e.qKeyEvent)},keystart:ge(function(e){!0===i.enabled&&!0!==e.qSkipRipple&&!0===J(e,i.modifiers.keyCodes)&&e.type==="key"+(!0===i.modifiers.early?"down":"up")&&_e(e,t,i,!0)},300)};be(i,e),t.__qripple=i,x(i,"main",[[t,"pointerdown","start","passive"],[t,"click","start","passive"],[t,"keydown","keystart","passive"],[t,"keyup","keystart","passive"]])},update:function(t,e){var i=t.__qripple;void 0!==i&&e.oldValue!==e.value&&(i.enabled=!1!==e.value,!0===i.enabled&&Object(e.value)===e.value&&be(i,e))},unbind:function(t){void 0===t.__qripple_destroyed?ye(t):delete t.__qripple_destroyed}},we={directives:{Ripple:Se},props:{ripple:{type:[Boolean,Object],default:!0}}},Ce={none:0,xs:4,sm:8,md:16,lg:24,xl:32},xe=["button","submit","reset"],ke=/[^\s]\/[^\s]/,qe={mixins:[Lt,we,ae,se,Tt({xs:8,sm:10,md:14,lg:20,xl:24})],props:{type:{type:String,default:"button"},to:[Object,String],replace:Boolean,append:Boolean,label:[Number,String],icon:String,iconRight:String,round:Boolean,outline:Boolean,flat:Boolean,unelevated:Boolean,rounded:Boolean,push:Boolean,glossy:Boolean,size:String,fab:Boolean,fabMini:Boolean,padding:String,color:String,textColor:String,noCaps:Boolean,noWrap:Boolean,dense:Boolean,tabindex:[Number,String],align:{default:"center"},stack:Boolean,stretch:Boolean,loading:{type:Boolean,default:null},disable:Boolean},computed:{style:function(){if(!1===this.fab&&!1===this.fabMini)return this.sizeStyle},isRounded:function(){return!0===this.rounded||!0===this.fab||!0===this.fabMini},isActionable:function(){return!0!==this.disable&&!0!==this.loading},computedTabIndex:function(){return!0===this.isActionable?this.tabindex||0:-1},design:function(){return!0===this.flat?"flat":!0===this.outline?"outline":!0===this.push?"push":!0===this.unelevated?"unelevated":"standard"},attrs:function(){var t={tabindex:this.computedTabIndex};return!0===this.hasLink?Object.assign(t,this.linkProps.attrs):!0===xe.includes(this.type)&&(t.type=this.type),!0===this.hasLink||"a"===this.type?(!0===this.disable?t["aria-disabled"]="true":void 0===t.href&&(t.role="button"),!0===ke.test(this.type)&&(t.type=this.type)):!0===this.disable&&(t.disabled="",t["aria-disabled"]="true"),!0===this.loading&&void 0!==this.percentage&&(t.role="progressbar",t["aria-valuemin"]=0,t["aria-valuemax"]=100,t["aria-valuenow"]=this.percentage),t},classes:function(){var t;return void 0!==this.color?t=!0===this.flat||!0===this.outline?"text-"+(this.textColor||this.color):"bg-"+this.color+" text-"+(this.textColor||"white"):this.textColor&&(t="text-"+this.textColor),"q-btn--"+this.design+" q-btn--"+(!0===this.round?"round":"rectangle"+(!0===this.isRounded?" q-btn--rounded":""))+(void 0!==t?" "+t:"")+(!0===this.isActionable?" q-btn--actionable q-focusable q-hoverable":!0===this.disable?" disabled":"")+(!0===this.fab?" q-btn--fab":!0===this.fabMini?" q-btn--fab-mini":"")+(!0===this.noCaps?" q-btn--no-uppercase":"")+(!0===this.noWrap?"":" q-btn--wrap")+(!0===this.dense?" q-btn--dense":"")+(!0===this.stretch?" no-border-radius self-stretch":"")+(!0===this.glossy?" glossy":"")},innerClasses:function(){return this.alignClass+(!0===this.stack?" column":" row")+(!0===this.noWrap?" no-wrap text-no-wrap":"")+(!0===this.loading?" q-btn__content--hidden":"")},wrapperStyle:function(){if(void 0!==this.padding)return{padding:this.padding.split(/\s+/).map(function(t){return t in Ce?Ce[t]+"px":t}).join(" "),minWidth:"0",minHeight:"0"}}}},Te=h.passiveCapture,Me=void 0,$e=void 0,Le=void 0,Oe={role:"img","aria-hidden":"true"},Be=t.extend({name:"QBtn",mixins:[qe],props:{percentage:Number,darkPercentage:Boolean},computed:{hasLabel:function(){return void 0!==this.label&&null!==this.label&&""!==this.label},computedRipple:function(){return!1!==this.ripple&&Object.assign({},{keyCodes:!0===this.hasLink?[13,32]:[13]},!0===this.ripple?{}:this.ripple)},percentageStyle:function(){var t=Math.max(0,Math.min(100,this.percentage));if(t>0)return{transition:"transform 0.6s",transform:"translateX("+(t-100)+"%)"}},onEvents:function(){if(!0===this.loading)return{mousedown:this.__onLoadingEvt,touchstart:this.__onLoadingEvt,click:this.__onLoadingEvt,keydown:this.__onLoadingEvt,keyup:this.__onLoadingEvt};if(!0===this.isActionable){var t=Object.assign({},this.qListeners,{click:this.click,keydown:this.__onKeydown,mousedown:this.__onMousedown});return!0===this.$q.platform.has.touch&&(t.touchstart=this.__onTouchstart),t}return{click:S}},directives:function(){if(!0!==this.disable&&!1!==this.ripple)return[{name:"ripple",value:this.computedRipple,modifiers:{center:this.round}}]}},methods:{click:function(t){var e=this;if(void 0!==t){if(!0===t.defaultPrevented)return;var i=document.activeElement;if("submit"===this.type&&(!0===this.$q.platform.is.ie&&(t.clientX<0||t.clientY<0)||i!==document.body&&!1===this.$el.contains(i)&&!1===i.contains(this.$el))){this.$el.focus();var n=function(){document.removeEventListener("keydown",S,!0),document.removeEventListener("keyup",n,Te),void 0!==e.$el&&e.$el.removeEventListener("blur",n,Te)};document.addEventListener("keydown",S,!0),document.addEventListener("keyup",n,Te),this.$el.addEventListener("blur",n,Te)}if(!0===this.hasRouterLink){if(!0===t.ctrlKey||!0===t.shiftKey||!0===t.altKey||!0===t.metaKey)return;S(t)}}var s=function(){e.$router[!0===e.replace?"replace":"push"](e.linkRoute.route,void 0,p)};this.$emit("click",t,s),!0===this.hasRouterLink&&!1!==t.navigate&&s()},__onKeydown:function(t){this.$emit("keydown",t),!0===J(t,[13,32])&&($e!==this.$el&&(void 0!==$e&&this.__cleanup(),!0!==t.defaultPrevented&&(this.$el.focus(),$e=this.$el,this.$el.classList.add("q-btn--active"),document.addEventListener("keyup",this.__onPressEnd,!0),this.$el.addEventListener("blur",this.__onPressEnd,Te))),S(t))},__onTouchstart:function(t){var e=this;if(this.$emit("touchstart",t),Me!==this.$el&&(void 0!==Me&&this.__cleanup(),!0!==t.defaultPrevented)){Me=this.$el;var i=this.touchTargetEl=t.target;i.addEventListener("touchcancel",this.__onPressEnd,Te),i.addEventListener("touchend",this.__onPressEnd,Te)}this.avoidMouseRipple=!0,clearTimeout(this.mouseTimer),this.mouseTimer=setTimeout(function(){e.avoidMouseRipple=!1},200)},__onMousedown:function(t){t.qSkipRipple=!0===this.avoidMouseRipple,this.$emit("mousedown",t),Le!==this.$el&&(void 0!==Le&&this.__cleanup(),!0!==t.defaultPrevented&&(Le=this.$el,this.$el.classList.add("q-btn--active"),document.addEventListener("mouseup",this.__onPressEnd,Te)))},__onPressEnd:function(t){if(void 0===t||"blur"!==t.type||document.activeElement!==this.$el){if(void 0!==t&&"keyup"===t.type){if($e===this.$el&&!0===J(t,[13,32])){var e=new MouseEvent("click",t);e.qKeyEvent=!0,!0===t.defaultPrevented&&y(e),!0===t.cancelBubble&&b(e),this.$el.dispatchEvent(e),S(t),t.qKeyEvent=!0}this.$emit("keyup",t)}this.__cleanup()}},__cleanup:function(t){var e=this.$refs.blurTarget;if(!0===t||Me!==this.$el&&Le!==this.$el||void 0===e||e===document.activeElement||(e.setAttribute("tabindex",-1),e.focus()),Me===this.$el){var i=this.touchTargetEl;i.removeEventListener("touchcancel",this.__onPressEnd,Te),i.removeEventListener("touchend",this.__onPressEnd,Te),Me=this.touchTargetEl=void 0}Le===this.$el&&(document.removeEventListener("mouseup",this.__onPressEnd,Te),Le=void 0),$e===this.$el&&(document.removeEventListener("keyup",this.__onPressEnd,!0),void 0!==this.$el&&this.$el.removeEventListener("blur",this.__onPressEnd,Te),$e=void 0),void 0!==this.$el&&this.$el.classList.remove("q-btn--active")},__onLoadingEvt:function(t){S(t),t.qSkipRipple=!0}},beforeDestroy:function(){this.__cleanup(!0)},render:function(t){var e=[];void 0!==this.icon&&e.push(t(Ut,{attrs:Oe,props:{name:this.icon,left:!1===this.stack&&!0===this.hasLabel}})),!0===this.hasLabel&&e.push(t("span",{staticClass:"block"},[this.label])),e=Et(e,this,"default"),void 0!==this.iconRight&&!1===this.round&&e.push(t(Ut,{attrs:Oe,props:{name:this.iconRight,right:!1===this.stack&&!0===this.hasLabel}}));var i=[t("span",{staticClass:"q-focus-helper",ref:"blurTarget"})];return!0===this.loading&&void 0!==this.percentage&&i.push(t("span",{staticClass:"q-btn__progress absolute-full overflow-hidden",class:!0===this.darkPercentage?"q-btn__progress--dark":""},[t("span",{staticClass:"q-btn__progress-indicator fit block",style:this.percentageStyle})])),i.push(t("span",{staticClass:"q-btn__wrapper col row q-anchor--skip",style:this.wrapperStyle},[t("span",{staticClass:"q-btn__content text-center col items-center q-anchor--skip",class:this.innerClasses},e)])),null!==this.loading&&i.push(t("transition",{props:{name:"q-transition--fade"}},!0===this.loading?[t("span",{key:"loading",staticClass:"absolute-full flex flex-center"},void 0!==this.$scopedSlots.loading?this.$scopedSlots.loading():[t(ue)])]:void 0)),t(!0===this.hasLink||"a"===this.type?"a":"button",{staticClass:"q-btn q-btn-item non-selectable no-outline",class:this.classes,style:this.style,attrs:this.attrs,on:this.onEvents,directives:this.directives},i)}}),Ee=t.extend({name:"QBtnGroup",mixin:[Lt],props:{unelevated:Boolean,outline:Boolean,flat:Boolean,rounded:Boolean,push:Boolean,stretch:Boolean,glossy:Boolean,spread:Boolean},computed:{classes:function(){var t=this;return["unelevated","outline","flat","rounded","push","stretch","glossy"].filter(function(e){return!0===t[e]}).map(function(t){return"q-btn-group--"+t}).join(" ")}},render:function(t){return t("div",{staticClass:"q-btn-group row no-wrap "+(!0===this.spread?"q-btn-group--spread":"inline"),class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}});function ze(){if(void 0!==window.getSelection){var t=window.getSelection();void 0!==t.empty?t.empty():void 0!==t.removeAllRanges&&(t.removeAllRanges(),!0!==u.is.mobile&&t.addRange(document.createRange()))}else void 0!==document.selection&&document.selection.empty()}var Pe={props:{target:{default:!0},noParentEvent:Boolean,contextMenu:Boolean},watch:{contextMenu:function(t){void 0!==this.anchorEl&&(this.__unconfigureAnchorEl(),this.__configureAnchorEl(t))},target:function(){void 0!==this.anchorEl&&this.__unconfigureAnchorEl(),this.__pickAnchorEl()},noParentEvent:function(t){void 0!==this.anchorEl&&(!0===t?this.__unconfigureAnchorEl():this.__configureAnchorEl())}},methods:{__showCondition:function(t){return void 0!==this.anchorEl&&(void 0===t||(void 0===t.touches||t.touches.length<=1))},__contextClick:function(t){var e=this;this.hide(t),this.$nextTick(function(){e.show(t)}),y(t)},__toggleKey:function(t){!0===J(t,13)&&this.toggle(t)},__mobileCleanup:function(t){this.anchorEl.classList.remove("non-selectable"),clearTimeout(this.touchTimer),!0===this.showing&&void 0!==t&&ze()},__mobilePrevent:y,__mobileTouch:function(t){var e=this;if(this.__mobileCleanup(t),!0===this.__showCondition(t)){this.hide(t),this.anchorEl.classList.add("non-selectable");var i=t.target;x(this,"anchor",[[i,"touchmove","__mobileCleanup","passive"],[i,"touchend","__mobileCleanup","passive"],[i,"touchcancel","__mobileCleanup","passive"],[this.anchorEl,"contextmenu","__mobilePrevent","notPassive"]]),this.touchTimer=setTimeout(function(){e.show(t)},300)}},__unconfigureAnchorEl:function(){k(this,"anchor")},__configureAnchorEl:function(t){(void 0===t&&(t=this.contextMenu),!0!==this.noParentEvent&&void 0!==this.anchorEl)&&x(this,"anchor",!0===t?!0===this.$q.platform.is.mobile?[[this.anchorEl,"touchstart","__mobileTouch","passive"]]:[[this.anchorEl,"click","hide","passive"],[this.anchorEl,"contextmenu","__contextClick","notPassive"]]:[[this.anchorEl,"click","toggle","passive"],[this.anchorEl,"keyup","__toggleKey","passive"]])},__setAnchorEl:function(t){for(this.anchorEl=t;this.anchorEl.classList.contains("q-anchor--skip");)this.anchorEl=this.anchorEl.parentNode;this.__configureAnchorEl()},__pickAnchorEl:function(){!1===this.target||""===this.target||null===this.parentEl?this.anchorEl=void 0:!0===this.target?this.__setAnchorEl(this.parentEl):(this.anchorEl=fe(this.target)||void 0,void 0!==this.anchorEl?this.__configureAnchorEl():console.error('Anchor: target "'+this.target+'" not found',this))},__changeScrollEvent:function(t,e){var i=(void 0!==e?"add":"remove")+"EventListener",n=void 0!==e?e:this.__scrollFn;t!==window&&t[i]("scroll",n,h.passive),window[i]("scroll",n,h.passive),this.__scrollFn=e}},created:function(){var t=this;"function"==typeof this.__configureScrollTarget&&"function"==typeof this.__unconfigureScrollTarget&&(this.noParentEventWatcher=this.$watch("noParentEvent",function(){void 0!==t.__scrollTarget&&(t.__unconfigureScrollTarget(),t.__configureScrollTarget())}))},mounted:function(){this.parentEl=this.$el.parentNode,this.__pickAnchorEl(),!0===this.value&&void 0===this.anchorEl&&this.$emit("input",!1)},beforeDestroy:function(){clearTimeout(this.touchTimer),void 0!==this.noParentEventWatcher&&this.noParentEventWatcher(),void 0!==this.__anchorCleanup&&this.__anchorCleanup(),this.__unconfigureAnchorEl()}},Ae={methods:{__nextTick:function(t){this.__tickFn=t},__prepareTick:function(){var t=this;if(void 0!==this.__tickFn){var e=this.__tickFn;this.$nextTick(function(){t.__tickFn===e&&(t.__tickFn(),t.__tickFn=void 0)})}},__clearTick:function(){this.__tickFn=void 0},__setTimeout:function(t,e){clearTimeout(this.__timer),this.__timer=setTimeout(t,e)},__clearTimeout:function(){clearTimeout(this.__timer)}},beforeDestroy:function(){this.__tickFn=void 0,clearTimeout(this.__timer)}},Ie={mixins:[Ae,Lt],props:{value:{type:Boolean,default:void 0}},data:function(){return{showing:!1}},watch:{value:function(t){this.__processModelChange(t)},$route:function(){!0===this.hideOnRouteChange&&!0===this.showing&&this.hide()}},methods:{toggle:function(t){this[!0===this.showing?"hide":"show"](t)},show:function(t){var e=this;!0===this.disable||void 0!==this.__showCondition&&!0!==this.__showCondition(t)||(void 0!==this.qListeners.input&&!1===i&&(this.$emit("input",!0),this.payload=t,this.$nextTick(function(){e.payload===t&&(e.payload=void 0)})),void 0!==this.value&&void 0!==this.qListeners.input&&!0!==i||this.__processShow(t))},__processShow:function(t){!0!==this.showing&&(void 0!==this.__preparePortal&&this.__preparePortal(),this.showing=!0,this.$emit("before-show",t),void 0!==this.__show?(this.__clearTick(),this.__show(t),this.__prepareTick()):this.$emit("show",t))},hide:function(t){var e=this;!0!==this.disable&&(void 0!==this.qListeners.input&&!1===i&&(this.$emit("input",!1),this.payload=t,this.$nextTick(function(){e.payload===t&&(e.payload=void 0)})),void 0!==this.value&&void 0!==this.qListeners.input&&!0!==i||this.__processHide(t))},__processHide:function(t){!1!==this.showing&&(this.showing=!1,this.$emit("before-hide",t),void 0!==this.__hide?(this.__clearTick(),this.__hide(t),this.__prepareTick()):this.$emit("hide",t))},__processModelChange:function(t){!0===this.disable&&!0===t?void 0!==this.qListeners.input&&this.$emit("input",!1):!0===t!==this.showing&&this["__process"+(!0===t?"Show":"Hide")](this.payload)}}},De=[],Re=[];function Fe(t){Re=Re.filter(function(e){return e!==t})}function je(t){Fe(t),0===Re.length&&De.length>0&&(De[De.length-1](),De=[])}function Ve(t){0===Re.length?t():De.push(t)}function Ne(t,e){do{if("QMenu"===t.$options.name){if(t.hide(e),!0===t.separateClosePopup)return t.$parent}else if(void 0!==t.__renderPortal)return void 0!==t.$parent&&"QPopupProxy"===t.$parent.$options.name?(t.hide(e),t.$parent):t;t=t.$parent}while(void 0!==t&&(void 0===t.$el.contains||!0!==t.$el.contains(e.target)))}var He={inheritAttrs:!1,props:{contentClass:[Array,String,Object],contentStyle:[Array,String,Object]},methods:{__showPortal:function(t){var e,i=this;if(!0===t)return je(this.focusObj),void(this.__portalIsAccessible=!0);if(this.__portalIsAccessible=!1,!0!==this.__portalIsActive)if(this.__portalIsActive=!0,void 0===this.focusObj&&(this.focusObj={}),Fe(e=this.focusObj),Re.push(e),void 0!==this.$q.fullscreen&&!0===this.$q.fullscreen.isCapable){var n=function(){if(void 0!==i.__portal){var t=me(i.$q.fullscreen.activeEl);i.__portal.$el.parentElement!==t&&t.contains(i.$el)===(!1===i.__onGlobalDialog)&&t.appendChild(i.__portal.$el)}};this.unwatchFullscreen=this.$watch("$q.fullscreen.activeEl",T(n,50)),!1!==this.__onGlobalDialog&&!0!==this.$q.fullscreen.isActive||n()}else void 0!==this.__portal&&!1===this.__onGlobalDialog&&document.body.appendChild(this.__portal.$el)},__hidePortal:function(t){this.__portalIsAccessible=!1,!0===t&&(this.__portalIsActive=!1,je(this.focusObj),void 0!==this.__portal&&(void 0!==this.unwatchFullscreen&&(this.unwatchFullscreen(),this.unwatchFullscreen=void 0),!1===this.__onGlobalDialog&&(this.__portal.$destroy(),this.__portal.$el.remove()),this.__portal=void 0))},__preparePortal:function(){var e=this;void 0===this.__portal&&(this.__portal=!0===this.__onGlobalDialog?{$el:this.$el,$refs:this.$refs}:new t({name:"QPortal",parent:this,inheritAttrs:!1,render:function(t){return e.__renderPortal(t)},components:this.$options.components,directives:this.$options.directives}).$mount())}},render:function(t){if(!0===this.__onGlobalDialog)return this.__renderPortal(t);void 0!==this.__portal&&this.__portal.$forceUpdate()},beforeDestroy:function(){this.__hidePortal(!0)}};!1===i&&(He.created=function(){this.__onGlobalDialog=function(t){for(;void 0!==t;){if("QGlobalDialog"===t.$options.name)return!0;if("QDialog"===t.$options.name)return!1;t=t.$parent}return!1}(this.$parent)});var Qe,We={props:{transitionShow:{type:String,default:"fade"},transitionHide:{type:String,default:"fade"}},data:function(){return{transitionState:this.showing}},watch:{showing:function(t){var e=this;this.transitionShow!==this.transitionHide&&this.$nextTick(function(){e.transitionState=t})}},computed:{transition:function(){return"q-transition--"+(!0===this.transitionState?this.transitionHide:this.transitionShow)}}};var Ye=h.notPassiveCapture,Ue=h.passiveCapture,Ke={click:[],focus:[]};function Xe(t,e){for(var i=t.length-1;i>=0;i--)if(void 0===t[i](e))return}function Ge(t){clearTimeout(Qe),"focusin"===t.type&&(!0===c.is.ie&&t.target===document.body||!0===t.target.hasAttribute("tabindex"))?Qe=setTimeout(function(){Xe(Ke.focus,t)},!0===c.is.ie?500:200):Xe(Ke.click,t)}var Ze,Je={name:"click-outside",bind:function(t,e,i){var n=e.value,s=e.arg,o=i.componentInstance||i.context,r={trigger:n,toggleEl:s,handler:function(e){var i=e.target;if(!(!0===e.qClickOutside||!0!==document.body.contains(i)||8===i.nodeType||i===document.documentElement||!1!==i.classList.contains("no-pointer-events")||!0===function(t){for(;null!==(t=t.nextElementSibling);)if(t.classList.contains("q-dialog--modal"))return!0;return!1}(t)||void 0!==r.toggleEl&&!1!==r.toggleEl.contains(i)||i!==document.body&&!1!==function(t,e){if(null===t||null===e)return null;for(var i=t;void 0!==i;i=i.$parent)if(i===e)return!0;return!1}(function(t){for(var e=t;null!==e;e=e.parentNode)if(void 0!==e.__vue__)return e.__vue__}(i),o)))return e.qClickOutside=!0,r.trigger(e)}};t.__qclickoutside&&(t.__qclickoutside_old=t.__qclickoutside),t.__qclickoutside=r,0===Ke.click.length&&(document.addEventListener("mousedown",Ge,Ye),document.addEventListener("touchstart",Ge,Ye),document.addEventListener("focusin",Ge,Ue)),Ke.click.push(r.handler),r.timerFocusin=setTimeout(function(){Ke.focus.push(r.handler)},500)},update:function(t,e){var i=e.value,n=e.oldValue,s=e.arg,o=t.__qclickoutside;i!==n&&(o.trigger=i),s!==o.arg&&(o.toggleEl=s)},unbind:function(t){var e=t.__qclickoutside_old||t.__qclickoutside;if(void 0!==e){clearTimeout(e.timerFocusin);var i=Ke.click.findIndex(function(t){return t===e.handler}),n=Ke.focus.findIndex(function(t){return t===e.handler});i>-1&&Ke.click.splice(i,1),n>-1&&Ke.focus.splice(n,1),0===Ke.click.length&&(clearTimeout(Qe),document.removeEventListener("mousedown",Ge,Ye),document.removeEventListener("touchstart",Ge,Ye),document.removeEventListener("focusin",Ge,Ue)),delete t[t.__qclickoutside_old?"__qclickoutside_old":"__qclickoutside"]}}},ti=!0===i?[]:[null,document,document.body,document.scrollingElement,document.documentElement];function ei(){if(!0===i)return!1;if(void 0===Ze){var t=document.createElement("div"),e=document.createElement("div");Object.assign(t.style,{direction:"rtl",width:"1px",height:"1px",overflow:"auto"}),Object.assign(e.style,{width:"1000px",height:"1px"}),t.appendChild(e),document.body.appendChild(t),t.scrollLeft=-1e3,Ze=t.scrollLeft>=0,t.remove()}return Ze}function ii(t,e){var i=fe(e);if(null===i){if(t!==Object(t)||"function"!=typeof t.closest)return window;i=t.closest(".scroll,.scroll-y,.overflow-auto")}return ti.includes(i)?window:i}function ni(t){return(t===window?document.body:t).scrollHeight}function si(t){return t===window?window.pageYOffset||window.scrollY||document.body.scrollTop||0:t.scrollTop}var oi=si;function ri(t){return t===window?window.pageXOffset||window.scrollX||document.body.scrollLeft||0:t.scrollLeft}function ai(t,e,i){void 0===i&&(i=0);var n=void 0===arguments[3]?performance.now():arguments[3],s=si(t);i<=0?s!==e&&ci(t,e):requestAnimationFrame(function(o){var r=o-n,a=s+(e-s)/Math.max(r,i)*r;ci(t,a),a!==e&&ai(t,e,i-r,o)})}function li(t,e,i){void 0===i&&(i=0);var n=void 0===arguments[3]?performance.now():arguments[3],s=ri(t);i<=0?s!==e&&ui(t,e):requestAnimationFrame(function(o){var r=o-n,a=s+(e-s)/Math.max(r,i)*r;ui(t,a),a!==e&&li(t,e,i-r,o)})}function ci(t,e){t!==window?t.scrollTop=e:window.scrollTo(window.pageXOffset||window.scrollX||document.body.scrollLeft||0,e)}function ui(t,e){t!==window?t.scrollLeft=e:window.scrollTo(e,window.pageYOffset||window.scrollY||document.body.scrollTop||0)}function hi(t,e,i){i?ai(t,e,i):ci(t,e)}var di,pi=hi;function fi(t,e,i){i?li(t,e,i):ui(t,e)}function mi(){if(void 0!==di)return di;var t=document.createElement("p"),e=document.createElement("div");pe(t,{width:"100%",height:"200px"}),pe(e,{position:"absolute",top:"0px",left:"0px",visibility:"hidden",width:"200px",height:"150px",overflow:"hidden"}),e.appendChild(t),document.body.appendChild(e);var i=t.offsetWidth;e.style.overflow="scroll";var n=t.offsetWidth;return i===n&&(n=e.clientWidth),e.remove(),di=i-n}function vi(t,e){return void 0===e&&(e=!0),!(!t||t.nodeType!==Node.ELEMENT_NODE)&&(e?t.scrollHeight>t.clientHeight&&(t.classList.contains("scroll")||t.classList.contains("overflow-auto")||["auto","scroll"].includes(window.getComputedStyle(t)["overflow-y"])):t.scrollWidth>t.clientWidth&&(t.classList.contains("scroll")||t.classList.contains("overflow-auto")||["auto","scroll"].includes(window.getComputedStyle(t)["overflow-x"])))}var gi,_i,bi={getScrollTarget:ii,getScrollHeight:ni,getScrollWidth:function(t){return(t===window?document.body:t).scrollWidth},getScrollPosition:oi,getVerticalScrollPosition:si,getHorizontalScrollPosition:ri,rtlHasScrollBug:ei,animScrollTo:ai,animVerticalScrollTo:ai,animHorizontalScrollTo:li,setScrollPosition:pi,setVerticalScrollPosition:hi,setHorizontalScrollPosition:fi,getScrollbarWidth:mi,hasScrollbar:vi},yi=[],Si=!1,wi={__install:function(){this.__installed=!0,window.addEventListener("keydown",function(t){Si=27===t.keyCode}),window.addEventListener("blur",function(){!0===Si&&(Si=!1)}),window.addEventListener("keyup",function(t){!0===Si&&(Si=!1,0!==yi.length&&!0===J(t,27)&&yi[yi.length-1].fn(t))})},register:function(t,e){!0===t.$q.platform.is.desktop&&(!0!==this.__installed&&this.__install(),yi.push({comp:t,fn:e}))},pop:function(t){if(!0===t.$q.platform.is.desktop){var e=yi.findIndex(function(e){return e.comp===t});e>-1&&yi.splice(e,1)}}};function Ci(t){var e=t.split(" ");return 2===e.length&&(!0!==["top","center","bottom"].includes(e[0])?(console.error("Anchor/Self position must start with one of top/center/bottom"),!1):!0===["left","middle","right","start","end"].includes(e[1])||(console.error("Anchor/Self position must end with one of left/middle/right/start/end"),!1))}function xi(t){return!t||2===t.length&&("number"==typeof t[0]&&"number"==typeof t[1])}var ki={"start#ltr":"left","start#rtl":"right","end#ltr":"right","end#rtl":"left"};function qi(t,e){var i=t.split(" ");return{vertical:i[0],horizontal:ki[i[1]+"#"+(!0===e?"rtl":"ltr")]}}function Ti(t){if(!0===c.is.ios&&void 0!==window.visualViewport){var e=document.body.style,i=window.visualViewport,n=i.offsetLeft,s=i.offsetTop;n!==gi&&(e.setProperty("--q-pe-left",n+"px"),gi=n),s!==_i&&(e.setProperty("--q-pe-top",s+"px"),_i=s)}var o,r=t.el,a=r.scrollLeft,l=r.scrollTop;if(void 0===t.absoluteOffset)o=function(t,e){var i=t.getBoundingClientRect(),n=i.top,s=i.left,o=i.right,r=i.bottom,a=i.width,l=i.height;return void 0!==e&&(n-=e[1],s-=e[0],r+=e[1],o+=e[0],a+=e[0],l+=e[1]),{top:n,left:s,right:o,bottom:r,width:a,height:l,middle:s+(o-s)/2,center:n+(r-n)/2}}(t.anchorEl,!0===t.cover?[0,0]:t.offset);else{var u=t.anchorEl.getBoundingClientRect(),h=u.top,d=u.left,p=h+t.absoluteOffset.top,f=d+t.absoluteOffset.left;o={top:p,left:f,width:1,height:1,right:f+1,center:p,middle:f,bottom:p+1}}var m={maxHeight:t.maxHeight,maxWidth:t.maxWidth,visibility:"visible"};!0!==t.fit&&!0!==t.cover||(m.minWidth=o.width+"px",!0===t.cover&&(m.minHeight=o.height+"px")),Object.assign(t.el.style,m);var v=function(t){return{top:0,center:t.offsetHeight/2,bottom:t.offsetHeight,left:0,middle:t.offsetWidth/2,right:t.offsetWidth}}(t.el),g={top:o[t.anchorOrigin.vertical]-v[t.selfOrigin.vertical],left:o[t.anchorOrigin.horizontal]-v[t.selfOrigin.horizontal]};!function(t,e,i,n,s){var o=i.bottom,r=i.right,a=mi(),l=window.innerHeight-a,c=document.body.clientWidth;if(t.top<0||t.top+o>l)if("center"===s.vertical)t.top=e[n.vertical]>l/2?Math.max(0,l-o):0,t.maxHeight=Math.min(o,l);else if(e[n.vertical]>l/2){var u=Math.min(l,"center"===n.vertical?e.center:n.vertical===s.vertical?e.bottom:e.top);t.maxHeight=Math.min(o,u),t.top=Math.max(0,u-o)}else t.top=Math.max(0,"center"===n.vertical?e.center:n.vertical===s.vertical?e.top:e.bottom),t.maxHeight=Math.min(o,l-t.top);if(t.left<0||t.left+r>c)if(t.maxWidth=Math.min(r,c),"middle"===s.horizontal)t.left=e[n.horizontal]>c/2?Math.max(0,c-r):0;else if(e[n.horizontal]>c/2){var h=Math.min(c,"middle"===n.horizontal?e.middle:n.horizontal===s.horizontal?e.right:e.left);t.maxWidth=Math.min(r,h),t.left=Math.max(0,h-t.maxWidth)}else t.left=Math.max(0,"middle"===n.horizontal?e.middle:n.horizontal===s.horizontal?e.left:e.right),t.maxWidth=Math.min(r,c-t.left)}(g,o,v,t.anchorOrigin,t.selfOrigin),m={top:g.top+"px",left:g.left+"px"},void 0!==g.maxHeight&&(m.maxHeight=g.maxHeight+"px",o.height>g.maxHeight&&(m.minHeight=m.maxHeight)),void 0!==g.maxWidth&&(m.maxWidth=g.maxWidth+"px",o.width>g.maxWidth&&(m.minWidth=m.maxWidth)),Object.assign(t.el.style,m),t.el.scrollTop!==l&&(t.el.scrollTop=l),t.el.scrollLeft!==a&&(t.el.scrollLeft=a)}["left","middle","right"].forEach(function(t){ki[t+"#ltr"]=t,ki[t+"#rtl"]=t});var Mi=t.extend({name:"QMenu",mixins:[bt,Gt,Pe,Ie,He,We],directives:{ClickOutside:Je},props:{persistent:Boolean,autoClose:Boolean,separateClosePopup:Boolean,noRouteDismiss:Boolean,noRefocus:Boolean,noFocus:Boolean,fit:Boolean,cover:Boolean,square:Boolean,anchor:{type:String,validator:Ci},self:{type:String,validator:Ci},offset:{type:Array,validator:xi},scrollTarget:{default:void 0},touchPosition:Boolean,maxHeight:{type:String,default:null},maxWidth:{type:String,default:null}},computed:{anchorOrigin:function(){return qi(this.anchor||(!0===this.cover?"center middle":"bottom start"),this.$q.lang.rtl)},selfOrigin:function(){return!0===this.cover?this.anchorOrigin:qi(this.self||"top start",this.$q.lang.rtl)},menuClass:function(){return(!0===this.square?" q-menu--square":"")+(!0===this.isDark?" q-menu--dark q-dark":"")},hideOnRouteChange:function(){return!0!==this.persistent&&!0!==this.noRouteDismiss},onEvents:function(){var t=Object.assign({},this.qListeners,{input:b,"popup-show":b,"popup-hide":b});return!0===this.autoClose&&(t.click=this.__onAutoClose),t},attrs:function(){return Object.assign({},{tabindex:-1},this.qAttrs)}},methods:{focus:function(){var t=this;Ve(function(){var e=void 0!==t.__portal&&void 0!==t.__portal.$refs?t.__portal.$refs.inner:void 0;void 0!==e&&!0!==e.contains(document.activeElement)&&(e=e.querySelector("[autofocus], [data-autofocus]")||e).focus({preventScroll:!0})})},__show:function(t){var e=this;if(this.__refocusTarget=!0!==c.is.mobile&&!1===this.noRefocus&&null!==document.activeElement?document.activeElement:void 0,wi.register(this,function(){!0!==e.persistent&&(e.$emit("escape-key"),e.hide())}),this.__showPortal(),this.__configureScrollTarget(),this.absoluteOffset=void 0,void 0!==t&&(this.touchPosition||this.contextMenu)){var i=m(t);if(void 0!==i.left){var n=this.anchorEl.getBoundingClientRect(),s=n.top,o=n.left;this.absoluteOffset={left:i.left-o,top:i.top-s}}}void 0===this.unwatch&&(this.unwatch=this.$watch(function(){return e.$q.screen.width+"|"+e.$q.screen.height+"|"+e.self+"|"+e.anchor+"|"+e.$q.lang.rtl},this.updatePosition)),this.$el.dispatchEvent(C("popup-show",{bubbles:!0})),!0!==this.noFocus&&null!==document.activeElement&&document.activeElement.blur(),this.__nextTick(function(){e.updatePosition(),!0!==e.noFocus&&e.focus()}),this.__setTimeout(function(){!0===e.$q.platform.is.ios&&(e.__avoidAutoClose=e.autoClose,e.__portal.$el.click()),e.updatePosition(),e.__showPortal(!0),e.$emit("show",t)},300)},__hide:function(t){var e=this;this.__anchorCleanup(!0),this.__hidePortal(),void 0===this.__refocusTarget||null===this.__refocusTarget||void 0!==t&&!0===t.qClickOutside||(this.__refocusTarget.focus(),this.__refocusTarget=void 0),this.$el.dispatchEvent(C("popup-hide",{bubbles:!0})),this.__setTimeout(function(){e.__hidePortal(!0),e.$emit("hide",t)},300)},__anchorCleanup:function(t){this.absoluteOffset=void 0,void 0!==this.unwatch&&(this.unwatch(),this.unwatch=void 0),!0!==t&&!0!==this.showing||(wi.pop(this),this.__unconfigureScrollTarget())},__unconfigureScrollTarget:function(){void 0!==this.__scrollTarget&&(this.__changeScrollEvent(this.__scrollTarget),this.__scrollTarget=void 0)},__configureScrollTarget:function(){void 0===this.anchorEl&&void 0===this.scrollTarget||(this.__scrollTarget=ii(this.anchorEl,this.scrollTarget),this.__changeScrollEvent(this.__scrollTarget,this.updatePosition))},__onAutoClose:function(t){!0!==this.__avoidAutoClose?(Ne(this,t),void 0!==this.qListeners.click&&this.$emit("click",t)):this.__avoidAutoClose=!1},updatePosition:function(){if(void 0!==this.anchorEl&&void 0!==this.__portal){var t=this.__portal.$el;8!==t.nodeType?Ti({el:t,offset:this.offset,anchorEl:this.anchorEl,anchorOrigin:this.anchorOrigin,selfOrigin:this.selfOrigin,absoluteOffset:this.absoluteOffset,fit:this.fit,cover:this.cover,maxHeight:this.maxHeight,maxWidth:this.maxWidth}):setTimeout(this.updatePosition,25)}},__onClickOutside:function(t){if(!0!==this.persistent&&!0===this.showing){var e=t.target.classList;return Ne(this,t),("touchstart"===t.type||e.contains("q-dialog__backdrop"))&&function(t){if(S(t),"mousedown"===t.type){var e=function(i){i.target===t.target&&S(i),document.removeEventListener("click",e,h.notPassiveCapture)};document.addEventListener("click",e,h.notPassiveCapture)}}(t),!0}},__renderPortal:function(t){return t("transition",{props:{name:this.transition}},[!0===this.showing?t("div",{ref:"inner",staticClass:"q-menu q-position-engine scroll"+this.menuClass,class:this.contentClass,style:this.contentStyle,attrs:this.attrs,on:this.onEvents,directives:[{name:"click-outside",value:this.__onClickOutside,arg:this.anchorEl}]},Ot(this,"default")):null])}},mounted:function(){this.__processModelChange(this.value)},beforeDestroy:function(){this.__refocusTarget=void 0,!0===this.showing&&void 0!==this.anchorEl&&this.anchorEl.dispatchEvent(C("popup-hide",{bubbles:!0}))}}),$i=t.extend({name:"QBtnDropdown",mixins:[qe,bt],inheritAttrs:!1,props:{value:Boolean,split:Boolean,dropdownIcon:String,contentClass:[Array,String,Object],contentStyle:[Array,String,Object],cover:Boolean,persistent:Boolean,noRouteDismiss:Boolean,autoClose:Boolean,menuAnchor:{type:String,default:"bottom end"},menuSelf:{type:String,default:"top end"},menuOffset:Array,disableMainBtn:Boolean,disableDropdown:Boolean,noIconAnimation:Boolean},data:function(){return{showing:this.value}},watch:{value:function(t){void 0!==this.$refs.menu&&this.$refs.menu[t?"show":"hide"]()},split:function(){this.hide()}},render:function(t){var e=this,i=Ot(this,"label",[]),n={"aria-expanded":!0===this.showing?"true":"false","aria-haspopup":"true"};(!0===this.disable||!1===this.split&&!0===this.disableMainBtn||!0===this.disableDropdown)&&(n["aria-disabled"]="true");var s=[t(Ut,{props:{name:this.dropdownIcon||this.$q.iconSet.arrow.dropdown},class:"q-btn-dropdown__arrow"+(!0===this.showing&&!1===this.noIconAnimation?" rotate-180":"")+(!1===this.split?" q-btn-dropdown__arrow-container":"")})];if(!0!==this.disableDropdown&&s.push(t(Mi,{ref:"menu",props:{cover:this.cover,fit:!0,persistent:this.persistent,noRouteDismiss:this.noRouteDismiss,autoClose:this.autoClose,anchor:this.menuAnchor,self:this.menuSelf,offset:this.menuOffset,contentClass:this.contentClass,contentStyle:this.contentStyle,separateClosePopup:!0},on:ft(this,"menu",{"before-show":function(t){e.showing=!0,e.$emit("before-show",t)},show:function(t){e.$emit("show",t),e.$emit("input",!0)},"before-hide":function(t){e.showing=!1,e.$emit("before-hide",t)},hide:function(t){e.$emit("hide",t),e.$emit("input",!1)}})},Ot(this,"default"))),!1===this.split)return t(Be,{class:"q-btn-dropdown q-btn-dropdown--simple",props:Object.assign({},this.$props,{disable:!0===this.disable||!0===this.disableMainBtn,noWrap:!0,round:!1}),attrs:Object.assign({},this.qAttrs,n),on:ft(this,"nonSpl",{click:function(t){e.$emit("click",t)}})},i.concat(s));var o=t(Be,{class:"q-btn-dropdown--current",props:Object.assign({},this.$props,{disable:!0===this.disable||!0===this.disableMainBtn,noWrap:!0,iconRight:this.iconRight,round:!1}),attrs:this.qAttrs,on:ft(this,"spl",{click:function(t){b(t),e.hide(),e.$emit("click",t)}})},i);return t(Ee,{props:{outline:this.outline,flat:this.flat,rounded:this.rounded,push:this.push,unelevated:this.unelevated,glossy:this.glossy,stretch:this.stretch},staticClass:"q-btn-dropdown q-btn-dropdown--split no-wrap q-btn-item"},[o,t(Be,{staticClass:"q-btn-dropdown__arrow-container q-anchor--skip",attrs:n,props:{disable:!0===this.disable||!0===this.disableDropdown,outline:this.outline,flat:this.flat,rounded:this.rounded,push:this.push,size:this.size,color:this.color,textColor:this.textColor,dense:this.dense,ripple:this.ripple}},s)])},methods:{toggle:function(t){this.$refs.menu&&this.$refs.menu.toggle(t)},show:function(t){this.$refs.menu&&this.$refs.menu.show(t)},hide:function(t){this.$refs.menu&&this.$refs.menu.hide(t)}},mounted:function(){!0===this.value&&this.show()}}),Li={props:{name:String},computed:{formAttrs:function(){return{type:"hidden",name:this.name,value:this.value}}},methods:{__injectFormInput:function(t,e,i){t[e](this.$createElement("input",{staticClass:"hidden",class:i,attrs:this.formAttrs,domProps:this.formDomProps}))}}},Oi={props:{name:String},computed:{nameProp:function(){return this.name||this.for}}},Bi=t.extend({name:"QBtnToggle",mixins:[Lt,we,Li],props:{value:{required:!0},options:{type:Array,required:!0,validator:function(t){return t.every(function(t){return("label"in t||"icon"in t||"slot"in t)&&"value"in t})}},color:String,textColor:String,toggleColor:{type:String,default:"primary"},toggleTextColor:String,outline:Boolean,flat:Boolean,unelevated:Boolean,rounded:Boolean,push:Boolean,glossy:Boolean,size:String,padding:String,noCaps:Boolean,noWrap:Boolean,dense:Boolean,readonly:Boolean,disable:Boolean,stack:Boolean,stretch:Boolean,spread:Boolean,clearable:Boolean},computed:{hasActiveValue:function(){var t=this;return void 0!==this.options.find(function(e){return e.value===t.value})},formAttrs:function(){return{type:"hidden",name:this.name,value:this.value}},btnOptions:function(){var t=this,e=function(e,i){return void 0===e[i]?t[i]:e[i]};return this.options.map(function(i,n){return{slot:i.slot,options:{key:n,class:i.class,style:i.style,on:Object.assign({},t.qListeners,{click:function(e){return t.__set(i.value,i,e)}}),attrs:Object.assign({},{"aria-pressed":i.value===t.value?"true":"false"},i.attrs),props:Object.assign({},i,{slot:void 0,class:void 0,style:void 0,value:void 0,attrs:void 0,outline:t.outline,flat:t.flat,rounded:t.rounded,push:t.push,unelevated:t.unelevated,dense:t.dense,disable:!0===t.disable||!0===i.disable,color:i.value===t.value?e(i,"toggleColor"):e(i,"color"),textColor:i.value===t.value?e(i,"toggleTextColor"):e(i,"textColor"),noCaps:!0===e(i,"noCaps"),noWrap:!0===e(i,"noWrap"),size:e(i,"size"),padding:e(i,"padding"),ripple:e(i,"ripple"),stack:!0===e(i,"stack"),stretch:!0===e(i,"stretch")})}}})}},methods:{__set:function(t,e,i){!0!==this.readonly&&(this.value===t?!0===this.clearable&&(this.$emit("input",null,null),this.$emit("clear")):this.$emit("input",t,e),this.$emit("click",i))}},render:function(t){var e=this,i=this.btnOptions.map(function(i){return t(Be,Object.assign({},i.options),void 0!==i.slot?Ot(e,i.slot):void 0)});return void 0!==this.name&&!0!==this.disable&&!0===this.hasActiveValue&&this.__injectFormInput(i,"push"),t(Ee,{staticClass:"q-btn-toggle",props:{outline:this.outline,flat:this.flat,rounded:this.rounded,push:this.push,stretch:this.stretch,unelevated:this.unelevated,glossy:this.glossy,spread:this.spread}},Et(i,this,"default"))}}),Ei=t.extend({name:"QCard",mixins:[Lt,Gt,$t],props:{square:Boolean,flat:Boolean,bordered:Boolean},computed:{classes:function(){return"q-card"+(!0===this.isDark?" q-card--dark q-dark":"")+(!0===this.bordered?" q-card--bordered":"")+(!0===this.square?" q-card--square no-border-radius":"")+(!0===this.flat?" q-card--flat no-shadow":"")}},render:function(t){return t(this.tag,{class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),zi=t.extend({name:"QCardSection",mixins:[Lt,$t],props:{horizontal:Boolean},computed:{classes:function(){return"q-card__section q-card__section--"+(!0===this.horizontal?"horiz row no-wrap":"vert")}},render:function(t){return t(this.tag,{class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),Pi=t.extend({name:"QCardActions",mixins:[Lt,se],props:{vertical:Boolean},computed:{classes:function(){return"q-card__actions--"+(!0===this.vertical?"vert column":"horiz row")+" "+this.alignClass}},render:function(t){return t("div",{staticClass:"q-card__actions",class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),Ai=["left","right","up","down","horizontal","vertical"],Ii={left:!0,right:!0,up:!0,down:!0,horizontal:!0,vertical:!0,all:!0};function Di(t){var e={};return Ai.forEach(function(i){t[i]&&(e[i]=!0)}),0===Object.keys(e).length?Ii:(!0===e.horizontal&&(e.left=e.right=!0),!0===e.vertical&&(e.up=e.down=!0),!0===e.left&&!0===e.right&&(e.horizontal=!0),!0===e.up&&!0===e.down&&(e.vertical=!0),!0===e.horizontal&&!0===e.vertical&&(e.all=!0),e)}function Ri(t,e){return void 0===e.event&&void 0!==t.target&&!0!==t.target.draggable&&"function"==typeof e.handler&&"INPUT"!==t.target.nodeName.toUpperCase()&&(void 0===t.qClonedBy||-1===t.qClonedBy.indexOf(e.uid))}function Fi(t){var e=t.__qtouchswipe;void 0!==e&&(k(e,"main"),k(e,"temp"),!0===c.is.firefox&&w(t,!1),void 0!==e.styleCleanup&&e.styleCleanup(),delete t.__qtouchswipe)}var ji={name:"touch-swipe",bind:function(t,e){var i=e.value,n=e.arg,s=e.modifiers;if(void 0!==t.__qtouchswipe&&(Fi(t),t.__qtouchswipe_destroyed=!0),!0===s.mouse||!0===c.has.touch){var o=!0===s.mouseCapture?"Capture":"",r={handler:i,sensitivity:function(t){var e=[.06,6,50];return"string"==typeof t&&t.length&&t.split(":").forEach(function(t,i){var n=parseFloat(t);n&&(e[i]=n)}),e}(n),modifiers:s,direction:Di(s),noop:p,mouseStart:function(t){Ri(t,r)&&f(t)&&(x(r,"temp",[[document,"mousemove","move","notPassive"+o],[document,"mouseup","end","notPassiveCapture"]]),r.start(t,!0))},touchStart:function(t){if(Ri(t,r)){var e=t.target;x(r,"temp",[[e,"touchmove","move","notPassiveCapture"],[e,"touchcancel","end","notPassiveCapture"],[e,"touchend","end","notPassiveCapture"]]),r.start(t)}},start:function(e,i){!0===c.is.firefox&&w(t,!0);var n=m(e);r.event={x:n.left,y:n.top,time:Date.now(),mouse:!0===i,dir:!1}},move:function(t){if(void 0!==r.event)if(!1===r.event.dir){var e=Date.now()-r.event.time;if(0!==e){var i=m(t),n=i.left-r.event.x,s=Math.abs(n),o=i.top-r.event.y,a=Math.abs(o);if(!0!==r.event.mouse){if(s<r.sensitivity[1]&&a<r.sensitivity[1])return void r.end(t)}else if(s<r.sensitivity[2]&&a<r.sensitivity[2])return;var l=s/e,c=a/e;!0===r.direction.vertical&&s<a&&s<100&&c>r.sensitivity[0]&&(r.event.dir=o<0?"up":"down"),!0===r.direction.horizontal&&s>a&&a<100&&l>r.sensitivity[0]&&(r.event.dir=n<0?"left":"right"),!0===r.direction.up&&s<a&&o<0&&s<100&&c>r.sensitivity[0]&&(r.event.dir="up"),!0===r.direction.down&&s<a&&o>0&&s<100&&c>r.sensitivity[0]&&(r.event.dir="down"),!0===r.direction.left&&s>a&&n<0&&a<100&&l>r.sensitivity[0]&&(r.event.dir="left"),!0===r.direction.right&&s>a&&n>0&&a<100&&l>r.sensitivity[0]&&(r.event.dir="right"),!1!==r.event.dir?(S(t),!0===r.event.mouse&&(document.body.classList.add("no-pointer-events--children"),document.body.classList.add("non-selectable"),ze(),r.styleCleanup=function(t){r.styleCleanup=void 0,document.body.classList.remove("non-selectable");var e=function(){document.body.classList.remove("no-pointer-events--children")};!0===t?setTimeout(e,50):e()}),r.handler({evt:t,touch:!0!==r.event.mouse,mouse:r.event.mouse,direction:r.event.dir,duration:e,distance:{x:s,y:a}})):r.end(t)}}else S(t)},end:function(e){void 0!==r.event&&(k(r,"temp"),!0===c.is.firefox&&w(t,!1),void 0!==r.styleCleanup&&r.styleCleanup(!0),void 0!==e&&!1!==r.event.dir&&S(e),r.event=void 0)}};t.__qtouchswipe=r,!0===s.mouse&&x(r,"main",[[t,"mousedown","mouseStart","passive"+o]]),!0===c.has.touch&&x(r,"main",[[t,"touchstart","touchStart","passive"+(!0===s.capture?"Capture":"")],[t,"touchmove","noop","notPassiveCapture"]])}},update:function(t,e){var i=e.oldValue,n=e.value,s=t.__qtouchswipe;void 0!==s&&i!==n&&("function"!=typeof n&&s.end(),s.handler=n)},unbind:function(t){void 0===t.__qtouchswipe_destroyed?Fi(t):delete t.__qtouchswipe_destroyed}};function Vi(t){return t("div",{staticClass:"q-panel scroll",attrs:{role:"tabpanel"},on:ft(this,"stop",{input:b})},Ot(this,"default"))}var Ni=t.extend({render:Vi}),Hi={mixins:[Lt],directives:{TouchSwipe:ji},props:{value:{required:!0},animated:Boolean,infinite:Boolean,swipeable:Boolean,vertical:Boolean,transitionPrev:String,transitionNext:String,keepAlive:Boolean,keepAliveInclude:[String,Array,RegExp],keepAliveExclude:[String,Array,RegExp],keepAliveMax:Number},data:function(){return{panelIndex:null,panelTransition:null}},computed:{panelDirectives:function(){if(!0===this.swipeable)return[{name:"touch-swipe",value:this.__swipe,modifiers:{horizontal:!0!==this.vertical,vertical:this.vertical,mouse:!0}}]},contentKey:function(){return"string"==typeof this.value||"number"==typeof this.value?this.value:String(this.value)},transitionPrevComputed:function(){return this.transitionPrev||"slide-"+(!0===this.vertical?"down":"right")},transitionNextComputed:function(){return this.transitionNext||"slide-"+(!0===this.vertical?"up":"left")},keepAliveProps:function(){return{include:this.keepAliveInclude,exclude:this.keepAliveExclude,max:this.keepAliveMax}},needsUniqueWrapper:function(){return void 0!==this.keepAliveInclude||void 0!==this.keepAliveExclude}},watch:{value:function(t,e){var i=this,n=!0===this.__isValidPanelName(t)?this.__getPanelIndex(t):-1;!0!==this.__forcedPanelTransition&&this.__updatePanelTransition(-1===n?0:n<this.__getPanelIndex(e)?-1:1),this.panelIndex!==n&&(this.panelIndex=n,this.$emit("before-transition",t,e),this.$nextTick(function(){i.$emit("transition",t,e)}))}},methods:{next:function(){this.__go(1)},previous:function(){this.__go(-1)},goTo:function(t){this.$emit("input",t)},__isValidPanelName:function(t){return void 0!==t&&null!==t&&""!==t},__getPanelIndex:function(t){return this.panels.findIndex(function(e){var i=e.componentOptions.propsData;return i.name===t&&""!==i.disable&&!0!==i.disable})},__getEnabledPanels:function(){return this.panels.filter(function(t){var e=t.componentOptions.propsData;return""!==e.disable&&!0!==e.disable})},__updatePanelTransition:function(t){var e=0!==t&&!0===this.animated&&-1!==this.panelIndex?"q-transition--"+(-1===t?this.transitionPrevComputed:this.transitionNextComputed):null;this.panelTransition!==e&&(this.panelTransition=e)},__go:function(t,e){var i=this;void 0===e&&(e=this.panelIndex);for(var n=e+t,s=this.panels;n>-1&&n<s.length;){var o=s[n].componentOptions;if(void 0!==o&&""!==o.propsData.disable&&!0!==o.propsData.disable)return this.__updatePanelTransition(t),this.__forcedPanelTransition=!0,this.$emit("input",s[n].componentOptions.propsData.name),void setTimeout(function(){i.__forcedPanelTransition=!1});n+=t}!0===this.infinite&&s.length>0&&-1!==e&&e!==s.length&&this.__go(t,-1===t?s.length:-1)},__swipe:function(t){var e=!0===this.vertical?"up":"left";this.__go((!0===this.$q.lang.rtl?-1:1)*(t.direction===e?1:-1))},__updatePanelIndex:function(){var t=this.__getPanelIndex(this.value);return this.panelIndex!==t&&(this.panelIndex=t),!0},__getPanelContent:function(e){var i=this;if(0!==this.panels.length){var n=this.__isValidPanelName(this.value)&&this.__updatePanelIndex()&&this.panels[this.panelIndex],s=!0===this.keepAlive?[e("keep-alive",{props:this.keepAliveProps},[e(!0===this.needsUniqueWrapper?mt(this,this.contentKey,function(){return t.extend({name:i.contentKey,render:Vi})}):Ni,{key:this.contentKey},[n])])]:[e("div",{staticClass:"q-panel scroll",key:this.contentKey,attrs:{role:"tabpanel"},on:ft(this,"stop",{input:b})},[n])];return!0===this.animated?[e("transition",{props:{name:this.panelTransition}},s)]:s}}},render:function(t){var e=this;return this.panels=Ot(this,"default",[]).filter(function(t){return void 0!==t&&void 0!==t.componentOptions&&void 0!==t.componentOptions.propsData&&e.__isValidPanelName(t.componentOptions.propsData.name)}),this.__renderPanels(t)}},Qi={mixins:[Lt],props:{name:{required:!0},disable:Boolean}},Wi=0,Yi={props:{fullscreen:Boolean,noRouteFullscreenExit:Boolean},data:function(){return{inFullscreen:!1}},watch:{$route:function(){!0!==this.noRouteFullscreenExit&&this.exitFullscreen()},fullscreen:function(t){this.inFullscreen!==t&&this.toggleFullscreen()},inFullscreen:function(t){this.$emit("update:fullscreen",t),this.$emit("fullscreen",t)}},methods:{toggleFullscreen:function(){!0===this.inFullscreen?this.exitFullscreen():this.setFullscreen()},setFullscreen:function(){!0!==this.inFullscreen&&(this.inFullscreen=!0,this.container=this.$el.parentNode,this.container.replaceChild(this.fullscreenFillerNode,this.$el),document.body.appendChild(this.$el),1===++Wi&&document.body.classList.add("q-body--fullscreen-mixin"),this.__historyFullscreen={handler:this.exitFullscreen},P.add(this.__historyFullscreen))},exitFullscreen:function(){var t=this;!0===this.inFullscreen&&(void 0!==this.__historyFullscreen&&(P.remove(this.__historyFullscreen),this.__historyFullscreen=void 0),this.container.replaceChild(this.$el,this.fullscreenFillerNode),this.inFullscreen=!1,0===(Wi=Math.max(0,Wi-1))&&(document.body.classList.remove("q-body--fullscreen-mixin"),void 0!==this.$el.scrollIntoView&&setTimeout(function(){t.$el.scrollIntoView()})))}},beforeMount:function(){this.fullscreenFillerNode=document.createElement("span")},mounted:function(){!0===this.fullscreen&&this.setFullscreen()},beforeDestroy:function(){this.exitFullscreen()}},Ui="function"==typeof Map,Ki="function"==typeof Set,Xi="function"==typeof ArrayBuffer;function Gi(t,e){if(t===e)return!0;if(null!==t&&null!==e&&"object"==typeof t&&"object"==typeof e){if(t.constructor!==e.constructor)return!1;var i,n;if(t.constructor===Array){if((i=t.length)!==e.length)return!1;for(n=i;0!=n--;)if(!0!==Gi(t[n],e[n]))return!1;return!0}if(!0===Ui&&t.constructor===Map){if(t.size!==e.size)return!1;for(n=t.entries().next();!0!==n.done;){if(!0!==e.has(n.value[0]))return!1;n=n.next()}for(n=t.entries().next();!0!==n.done;){if(!0!==Gi(n.value[1],e.get(n.value[0])))return!1;n=n.next()}return!0}if(!0===Ki&&t.constructor===Set){if(t.size!==e.size)return!1;for(n=t.entries().next();!0!==n.done;){if(!0!==e.has(n.value[0]))return!1;n=n.next()}return!0}if(!0===Xi&&null!=t.buffer&&t.buffer.constructor===ArrayBuffer){if((i=t.length)!==e.length)return!1;for(n=i;0!=n--;)if(t[n]!==e[n])return!1;return!0}if(t.constructor===RegExp)return t.source===e.source&&t.flags===e.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===e.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===e.toString();var s=Object.keys(t).filter(function(e){return void 0!==t[e]});if((i=s.length)!==Object.keys(e).filter(function(t){return void 0!==e[t]}).length)return!1;for(n=i;0!=n--;){var o=s[n];if(!0!==Gi(t[o],e[o]))return!1}return!0}return t!=t&&e!=e}function Zi(t){return null!==t&&"object"==typeof t&&!0!==Array.isArray(t)}function Ji(t){return"[object Date]"===Object.prototype.toString.call(t)}function tn(t){return"number"==typeof t&&isFinite(t)}var en=t.extend({name:"QCarousel",mixins:[Gt,Hi,Yi],props:{height:String,padding:Boolean,controlType:{type:String,validator:function(t){return["regular","flat","outline","push","unelevated"].includes(t)},default:"flat"},controlColor:String,controlTextColor:String,autoplay:[Number,Boolean],arrows:Boolean,prevIcon:String,nextIcon:String,navigation:Boolean,navigationPosition:{type:String,validator:function(t){return["top","right","bottom","left"].includes(t)}},navigationIcon:String,navigationActiveIcon:String,thumbnails:Boolean},computed:{style:function(){if(!0!==this.inFullscreen&&void 0!==this.height)return{height:this.height}},direction:function(){return!0===this.vertical?"vertical":"horizontal"},classes:function(){return"q-carousel q-panel-parent q-carousel--with"+(!0===this.padding?"":"out")+"-padding"+(!0===this.inFullscreen?" fullscreen":"")+(!0===this.isDark?" q-carousel--dark q-dark":"")+(!0===this.arrows?" q-carousel--arrows-"+this.direction:"")+(!0===this.navigation?" q-carousel--navigation-"+this.navigationPositionComputed:"")},arrowIcons:function(){var t=[this.prevIcon||this.$q.iconSet.carousel[!0===this.vertical?"up":"left"],this.nextIcon||this.$q.iconSet.carousel[!0===this.vertical?"down":"right"]];return!1===this.vertical&&!0===this.$q.lang.rtl?t.reverse():t},navIcon:function(){return this.navigationIcon||this.$q.iconSet.carousel.navigationIcon},navActiveIcon:function(){return this.navigationActiveIcon||this.navIcon},navigationPositionComputed:function(){return this.navigationPosition||(!0===this.vertical?"right":"bottom")},controlProps:function(){var t;return(t={color:this.controlColor,textColor:this.controlTextColor,round:!0})[this.controlType]=!0,t.dense=!0,t},transitionPrevComputed:function(){return this.transitionPrev||"fade"},transitionNextComputed:function(){return this.transitionNext||"fade"}},watch:{value:function(){this.autoplay&&(clearInterval(this.timer),this.__startTimer())},autoplay:function(t){t?this.__startTimer():clearInterval(this.timer)}},methods:{__startTimer:function(){var t=!0===tn(this.autoplay)?this.autoplay:5e3;this.timer=setTimeout(t>=0?this.next:this.previous,Math.abs(t))},__getNavigationContainer:function(t,e,i){return t("div",{class:"q-carousel__control q-carousel__navigation no-wrap absolute flex q-carousel__navigation--"+e+" q-carousel__navigation--"+this.navigationPositionComputed+(void 0!==this.controlColor?" text-"+this.controlColor:"")},[t("div",{staticClass:"q-carousel__navigation-inner flex flex-center no-wrap"},this.__getEnabledPanels().map(i))])},__getContent:function(t){var e=this,i=[];if(!0===this.navigation){var n=void 0!==this.$scopedSlots["navigation-icon"]?this.$scopedSlots["navigation-icon"]:function(i){return t(Be,{key:"nav"+i.name,class:"q-carousel__navigation-icon q-carousel__navigation-icon--"+(!0===i.active?"":"in")+"active",props:i.btnProps,on:ft(e,"nav#"+i.name,{click:i.onClick})})},s=this.panels.length-1;i.push(this.__getNavigationContainer(t,"buttons",function(t,i){var o=t.componentOptions.propsData.name,r=e.panelIndex===i;return n({index:i,maxIndex:s,name:o,active:r,btnProps:Object.assign({},{icon:!0===r?e.navActiveIcon:e.navIcon,size:"sm"},e.controlProps),onClick:function(){e.goTo(o)}})}))}else if(!0===this.thumbnails){var o=void 0!==this.controlColor?" text-"+this.controlColor:"";i.push(this.__getNavigationContainer(t,"thumbnails",function(i){var n=i.componentOptions.propsData;return t("img",{class:"q-carousel__thumbnail q-carousel__thumbnail--"+(n.name===e.value?"":"in")+"active"+o,attrs:{src:n.imgSrc},key:"tmb#"+n.name,on:ft(e,"tmb#"+n.name,{click:function(){e.goTo(n.name)}})})}))}return!0===this.arrows&&this.panelIndex>=0&&((!0===this.infinite||this.panelIndex>0)&&i.push(t("div",{key:"prev",staticClass:"q-carousel__control q-carousel__arrow q-carousel__prev-arrow q-carousel__prev-arrow--"+this.direction+" absolute flex flex-center"},[t(Be,{props:Object.assign({},{icon:this.arrowIcons[0]},this.controlProps),on:ft(this,"prev",{click:this.previous})})])),(!0===this.infinite||this.panelIndex<this.panels.length-1)&&i.push(t("div",{key:"next",staticClass:"q-carousel__control q-carousel__arrow q-carousel__next-arrow q-carousel__next-arrow--"+this.direction+" absolute flex flex-center"},[t(Be,{props:Object.assign({},{icon:this.arrowIcons[1]},this.controlProps),on:ft(this,"next",{click:this.next})})]))),Et(i,this,"control")},__renderPanels:function(t){return t("div",{style:this.style,class:this.classes,on:Object.assign({},this.qListeners)},[t("div",{staticClass:"q-carousel__slides-container",directives:this.panelDirectives},this.__getPanelContent(t))].concat(this.__getContent(t)))}},mounted:function(){this.autoplay&&this.__startTimer()},beforeDestroy:function(){clearInterval(this.timer)}}),nn=t.extend({name:"QCarouselSlide",mixins:[Qi],props:{imgSrc:String},computed:{style:function(){if(this.imgSrc)return{backgroundImage:'url("'+this.imgSrc+'")'}}},render:function(t){return t("div",{staticClass:"q-carousel__slide",style:this.style,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),sn=t.extend({name:"QCarouselControl",mixins:[Lt],props:{position:{type:String,default:"bottom-right",validator:function(t){return["top-right","top-left","bottom-right","bottom-left","top","right","bottom","left"].includes(t)}},offset:{type:Array,default:function(){return[18,18]},validator:function(t){return 2===t.length}}},computed:{classes:function(){return"absolute-"+this.position},style:function(){return{margin:this.offset[1]+"px "+this.offset[0]+"px"}}},render:function(t){return t("div",{staticClass:"q-carousel__control absolute",style:this.style,class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),on=t.extend({name:"QChatMessage",mixins:[Lt],props:{sent:Boolean,label:String,bgColor:String,textColor:String,name:String,avatar:String,text:Array,stamp:String,size:String,labelSanitize:Boolean,nameSanitize:Boolean,textSanitize:Boolean,stampSanitize:Boolean},computed:{textClass:function(){return"q-message-text-content q-message-text-content--"+this.op+(void 0!==this.textColor?" text-"+this.textColor:"")},messageClass:function(){return"q-message-text q-message-text--"+this.op+(void 0!==this.bgColor?" text-"+this.bgColor:"")},containerClass:function(){return"q-message-container row items-end no-wrap"+(!0===this.sent?" reverse":"")},sizeClass:function(){if(void 0!==this.size)return"col-"+this.size},op:function(){return!0===this.sent?"sent":"received"}},methods:{__wrapStamp:function(t,e){var i;return void 0!==this.$scopedSlots.stamp?[e,t("div",{staticClass:"q-message-stamp"},this.$scopedSlots.stamp())]:this.stamp?[e,t("div",{staticClass:"q-message-stamp",domProps:(i={},i[!0===this.stampSanitize?"textContent":"innerHTML"]=this.stamp,i)})]:[e]},__getText:function(t,e,i){var n=this,s=!0===this.textSanitize?"textContent":"innerHTML";if(!0===i&&!0===e.some(function(t){return void 0===t.tag&&void 0!==t.text}))return[t("div",{class:this.messageClass},[t("div",{class:this.textClass},this.__wrapStamp(t,t("div",e)))])];var o=!0!==i?function(e){var i;return t("div",{domProps:(i={},i[s]=e,i)})}:e.length>1?function(t){return t}:function(e){return t("div",[e])};return e.map(function(e,i){return t("div",{key:i,class:n.messageClass},[t("div",{class:n.textClass},n.__wrapStamp(t,o(e)))])})}},render:function(t){var e,i,n=[];void 0!==this.$scopedSlots.avatar?n.push(this.$scopedSlots.avatar()):void 0!==this.avatar&&n.push(t("img",{class:"q-message-avatar q-message-avatar--"+this.op,attrs:{src:this.avatar,"aria-hidden":"true"}}));var s=[];void 0!==this.$scopedSlots.name?s.push(t("div",{class:"q-message-name q-message-name--"+this.op},this.$scopedSlots.name())):void 0!==this.name&&s.push(t("div",{class:"q-message-name q-message-name--"+this.op,domProps:(e={},e[!0===this.nameSanitize?"textContent":"innerHTML"]=this.name,e)})),void 0!==this.text&&s.push(this.__getText(t,this.text)),void 0!==this.$scopedSlots.default&&s.push(this.__getText(t,this.$scopedSlots.default(),!0)),n.push(t("div",{class:this.sizeClass},s));var o=[];return void 0!==this.$scopedSlots.label?o.push(t("div",{staticClass:"q-message-label"},this.$scopedSlots.label())):void 0!==this.label&&o.push(t("div",{staticClass:"q-message-label",domProps:(i={},i[!0===this.labelSanitize?"textContent":"innerHTML"]=this.label,i)})),o.push(t("div",{class:this.containerClass},n)),t("div",{class:"q-message q-message-"+this.op,on:Object.assign({},this.qListeners)},o)}}),rn=Tt({xs:30,sm:35,md:40,lg:50,xl:60}),an={computed:{__refocusTargetEl:function(){if(!0!==this.disable)return this.$createElement("span",{ref:"refocusTarget",staticClass:"no-outline",attrs:{tabindex:-1}})}},methods:{__refocusTarget:function(t){void 0!==t&&0===t.type.indexOf("key")?document.activeElement!==this.$el&&!0===this.$el.contains(document.activeElement)&&this.$el.focus():void 0!==t&&!0!==this.$el.contains(t.target)||void 0===this.$refs.refocusTarget||this.$refs.refocusTarget.focus()}}},ln={mixins:[Gt,rn,Li,an],props:{value:{required:!0,default:null},val:{},trueValue:{default:!0},falseValue:{default:!1},indeterminateValue:{default:null},checkedIcon:String,uncheckedIcon:String,indeterminateIcon:String,toggleOrder:{type:String,validator:function(t){return"tf"===t||"ft"===t}},toggleIndeterminate:Boolean,label:String,leftLabel:Boolean,color:String,keepColor:Boolean,dense:Boolean,disable:Boolean,tabindex:[String,Number]},computed:{isTrue:function(){return!0===this.modelIsArray?this.index>-1:this.value===this.trueValue},isFalse:function(){return!0===this.modelIsArray?-1===this.index:this.value===this.falseValue},isIndeterminate:function(){return!1===this.isTrue&&!1===this.isFalse},index:function(){if(!0===this.modelIsArray)return this.value.indexOf(this.val)},modelIsArray:function(){return void 0!==this.val&&Array.isArray(this.value)},computedTabindex:function(){return!0===this.disable?-1:this.tabindex||0},classes:function(){return"q-"+this.type+" cursor-pointer no-outline row inline no-wrap items-center"+(!0===this.disable?" disabled":"")+(!0===this.isDark?" q-"+this.type+"--dark":"")+(!0===this.dense?" q-"+this.type+"--dense":"")+(!0===this.leftLabel?" reverse":"")},innerClass:function(){var t=!0===this.isTrue?"truthy":!0===this.isFalse?"falsy":"indet",e=void 0===this.color||!0!==this.keepColor&&("toggle"===this.type?!0!==this.isTrue:!0===this.isFalse)?"":" text-"+this.color;return"q-"+this.type+"__inner--"+t+e},formAttrs:function(){var t={type:"checkbox"};return void 0!==this.name&&Object.assign(t,{checked:this.isTrue,name:this.name,value:!0===this.modelIsArray?this.val:this.trueValue}),t},attrs:function(){var t={tabindex:this.computedTabindex,role:"checkbox","aria-label":this.label,"aria-checked":!0===this.isIndeterminate?"mixed":!0===this.isTrue?"true":"false"};return!0===this.disable&&(t["aria-disabled"]="true"),t}},methods:{toggle:function(t){void 0!==t&&(S(t),this.__refocusTarget(t)),!0!==this.disable&&this.$emit("input",this.__getNextValue(),t)},__getNextValue:function(){if(!0===this.modelIsArray){if(!0===this.isTrue){var t=this.value.slice();return t.splice(this.index,1),t}return this.value.concat([this.val])}if(!0===this.isTrue){if("ft"!==this.toggleOrder||!1===this.toggleIndeterminate)return this.falseValue}else{if(!0!==this.isFalse)return"ft"!==this.toggleOrder?this.trueValue:this.falseValue;if("ft"===this.toggleOrder||!1===this.toggleIndeterminate)return this.trueValue}return this.indeterminateValue},__onKeydown:function(t){13!==t.keyCode&&32!==t.keyCode||S(t)},__onKeyup:function(t){13!==t.keyCode&&32!==t.keyCode||this.toggle(t)}},render:function(t){var e=this.__getInner(t);!0!==this.disable&&this.__injectFormInput(e,"unshift","q-"+this.type+"__native absolute q-ma-none q-pa-none");var i=[t("div",{staticClass:"q-"+this.type+"__inner relative-position non-selectable",class:this.innerClass,style:this.sizeStyle},e)];void 0!==this.__refocusTargetEl&&i.push(this.__refocusTargetEl);var n=void 0!==this.label?Et([this.label],this,"default"):Ot(this,"default");return void 0!==n&&i.push(t("div",{staticClass:"q-"+this.type+"__label q-anchor--skip"},n)),t("div",{class:this.classes,attrs:this.attrs,on:ft(this,"inpExt",{click:this.toggle,keydown:this.__onKeydown,keyup:this.__onKeyup})},i)}},cn=t.extend({name:"QCheckbox",mixins:[ln],computed:{computedIcon:function(){return!0===this.isTrue?this.checkedIcon:!0===this.isIndeterminate?this.indeterminateIcon:this.uncheckedIcon}},methods:{__getInner:function(t){return void 0!==this.computedIcon?[t("div",{key:"icon",staticClass:"q-checkbox__icon-container absolute-full flex flex-center no-wrap"},[t(Ut,{staticClass:"q-checkbox__icon",props:{name:this.computedIcon}})])]:[t("div",{key:"svg",staticClass:"q-checkbox__bg absolute"},[t("svg",{staticClass:"q-checkbox__svg fit absolute-full",attrs:{focusable:"false",viewBox:"0 0 24 24","aria-hidden":"true"}},[t("path",{staticClass:"q-checkbox__truthy",attrs:{fill:"none",d:"M1.73,12.91 8.1,19.28 22.79,4.59"}}),t("path",{staticClass:"q-checkbox__indet",attrs:{d:"M4,14H20V10H4"}})])])]}},created:function(){this.type="checkbox"}}),un=t.extend({name:"QChip",mixins:[we,Gt,Tt({xs:8,sm:10,md:14,lg:20,xl:24})],model:{event:"remove"},props:{dense:Boolean,icon:String,iconRight:String,iconRemove:String,iconSelected:String,label:[String,Number],color:String,textColor:String,value:{type:Boolean,default:!0},selected:{type:Boolean,default:null},square:Boolean,outline:Boolean,clickable:Boolean,removable:Boolean,tabindex:[String,Number],disable:Boolean},computed:{classes:function(){var t,e=!0===this.outline&&this.color||this.textColor;return(t={})["bg-"+this.color]=!1===this.outline&&void 0!==this.color,t["text-"+e+" q-chip--colored"]=e,t.disabled=this.disable,t["q-chip--dense"]=this.dense,t["q-chip--outline"]=this.outline,t["q-chip--selected"]=this.selected,t["q-chip--clickable cursor-pointer non-selectable q-hoverable"]=this.isClickable,t["q-chip--square"]=this.square,t["q-chip--dark q-dark"]=this.isDark,t},hasLeftIcon:function(){return!0===this.selected||void 0!==this.icon},leftIcon:function(){return!0===this.selected?this.iconSelected||this.$q.iconSet.chip.selected:this.icon},removeIcon:function(){return this.iconRemove||this.$q.iconSet.chip.remove},isClickable:function(){return!1===this.disable&&(!0===this.clickable||null!==this.selected)},attrs:function(){return!0===this.disable?{tabindex:-1,"aria-disabled":"true"}:{tabindex:this.tabindex||0}}},methods:{__onKeyup:function(t){13===t.keyCode&&this.__onClick(t)},__onClick:function(t){this.disable||(this.$emit("update:selected",!this.selected),this.$emit("click",t))},__onRemove:function(t){void 0!==t.keyCode&&13!==t.keyCode||(S(t),!this.disable&&this.$emit("remove",!1))},__getContent:function(t){var e=[];!0===this.isClickable&&e.push(t("div",{staticClass:"q-focus-helper"})),!0===this.hasLeftIcon&&e.push(t(Ut,{staticClass:"q-chip__icon q-chip__icon--left",props:{name:this.leftIcon}}));var i=void 0!==this.label?[t("div",{staticClass:"ellipsis"},[this.label])]:void 0;return e.push(t("div",{staticClass:"q-chip__content col row no-wrap items-center q-anchor--skip"},zt(i,this,"default"))),this.iconRight&&e.push(t(Ut,{staticClass:"q-chip__icon q-chip__icon--right",props:{name:this.iconRight}})),!0===this.removable&&e.push(t(Ut,{staticClass:"q-chip__icon q-chip__icon--remove cursor-pointer",props:{name:this.removeIcon},attrs:this.attrs,on:ft(this,"non",{click:this.__onRemove,keyup:this.__onRemove})})),e}},render:function(t){if(!1!==this.value){var e={staticClass:"q-chip row inline no-wrap items-center",class:this.classes,style:this.sizeStyle};return!0===this.isClickable&&Object.assign(e,{attrs:this.attrs,on:ft(this,"click",{click:this.__onClick,keyup:this.__onKeyup}),directives:ft(this,"dir#"+this.ripple,[{name:"ripple",value:this.ripple}])}),t("div",e,this.__getContent(t))}}}),hn=100*Math.PI,dn=Math.round(1e3*hn)/1e3,pn=t.extend({name:"QCircularProgress",mixins:[Lt,Mt],props:{value:{type:Number,default:0},min:{type:Number,default:0},max:{type:Number,default:100},color:String,centerColor:String,trackColor:String,fontSize:String,thickness:{type:Number,default:.2,validator:function(t){return t>=0&&t<=1}},angle:{type:Number,default:0},indeterminate:Boolean,showValue:Boolean,reverse:Boolean,instantFeedback:Boolean},computed:{normalizedValue:function(){return ut(this.value,this.min,this.max)},svgStyle:function(){var t=!0===this.$q.lang.rtl?-this.angle:this.angle;return{transform:this.reverse!==(!0===this.$q.lang.rtl)?"scale3d(-1, 1, 1) rotate3d(0, 0, 1, "+(-90-t)+"deg)":"rotate3d(0, 0, 1, "+(t-90)+"deg)"}},circleStyle:function(){if(!0!==this.instantFeedback&&!0!==this.indeterminate)return{transition:"stroke-dashoffset 0.6s ease 0s, stroke 0.6s ease"}},viewBox:function(){return 100/(1-this.thickness/2)},viewBoxAttr:function(){return this.viewBox/2+" "+this.viewBox/2+" "+this.viewBox+" "+this.viewBox},strokeDashOffset:function(){return(1-(this.normalizedValue-this.min)/(this.max-this.min))*hn},strokeWidth:function(){return this.thickness/2*this.viewBox},attrs:function(){return{role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.max,"aria-valuenow":!0===this.indeterminate?void 0:this.normalizedValue}}},methods:{__getCircle:function(t,e){var i=e.thickness,n=e.offset,s=e.color;return t("circle",{staticClass:"q-circular-progress__"+e.cls,class:void 0!==s?"text-"+s:null,style:this.circleStyle,attrs:{fill:"transparent",stroke:"currentColor","stroke-width":i,"stroke-dasharray":dn,"stroke-dashoffset":n,cx:this.viewBox,cy:this.viewBox,r:50}})}},render:function(t){var e=[];void 0!==this.centerColor&&"transparent"!==this.centerColor&&e.push(t("circle",{staticClass:"q-circular-progress__center",class:"text-"+this.centerColor,attrs:{fill:"currentColor",r:50-this.strokeWidth/2,cx:this.viewBox,cy:this.viewBox}})),void 0!==this.trackColor&&"transparent"!==this.trackColor&&e.push(this.__getCircle(t,{cls:"track",thickness:this.strokeWidth,offset:0,color:this.trackColor})),e.push(this.__getCircle(t,{cls:"circle",thickness:this.strokeWidth,offset:this.strokeDashOffset,color:this.color}));var i=[t("svg",{staticClass:"q-circular-progress__svg",style:this.svgStyle,attrs:{focusable:"false",viewBox:this.viewBoxAttr,"aria-hidden":"true"}},e)];return!0===this.showValue&&i.push(t("div",{staticClass:"q-circular-progress__text absolute-full row flex-center content-center",style:{fontSize:this.fontSize}},void 0!==this.$scopedSlots.default?this.$scopedSlots.default():[t("div",[this.normalizedValue])])),t("div",{staticClass:"q-circular-progress",class:"q-circular-progress--"+(!0===this.indeterminate?"in":"")+"determinate",style:this.sizeStyle,on:Object.assign({},this.qListeners),attrs:this.attrs},zt(i,this,"internal"))}}),fn=/^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/,mn=/^#[0-9a-fA-F]{4}([0-9a-fA-F]{4})?$/,vn=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,gn=/^rgb\(((0|[1-9][\d]?|1[\d]{0,2}|2[\d]?|2[0-4][\d]|25[0-5]),){2}(0|[1-9][\d]?|1[\d]{0,2}|2[\d]?|2[0-4][\d]|25[0-5])\)$/,_n=/^rgba\(((0|[1-9][\d]?|1[\d]{0,2}|2[\d]?|2[0-4][\d]|25[0-5]),){2}(0|[1-9][\d]?|1[\d]{0,2}|2[\d]?|2[0-4][\d]|25[0-5]),(0|0\.[0-9]+[1-9]|0\.[1-9]+|1)\)$/,bn={date:function(t){return/^-?[\d]+\/[0-1]\d\/[0-3]\d$/.test(t)},time:function(t){return/^([0-1]?\d|2[0-3]):[0-5]\d$/.test(t)},fulltime:function(t){return/^([0-1]?\d|2[0-3]):[0-5]\d:[0-5]\d$/.test(t)},timeOrFulltime:function(t){return/^([0-1]?\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/.test(t)},email:function(t){return/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(t)},hexColor:function(t){return fn.test(t)},hexaColor:function(t){return mn.test(t)},hexOrHexaColor:function(t){return vn.test(t)},rgbColor:function(t){return gn.test(t)},rgbaColor:function(t){return _n.test(t)},rgbOrRgbaColor:function(t){return gn.test(t)||_n.test(t)},hexOrRgbColor:function(t){return fn.test(t)||gn.test(t)},hexaOrRgbaColor:function(t){return mn.test(t)||_n.test(t)},anyColor:function(t){return vn.test(t)||gn.test(t)||_n.test(t)}},yn={testPattern:bn};function Sn(t,e,i){var n,s=m(t),o=s.left-e.event.x,r=s.top-e.event.y,a=Math.abs(o),l=Math.abs(r),c=e.direction;!0===c.horizontal&&!0!==c.vertical?n=o<0?"left":"right":!0!==c.horizontal&&!0===c.vertical?n=r<0?"up":"down":!0===c.up&&r<0?(n="up",a>l&&(!0===c.left&&o<0?n="left":!0===c.right&&o>0&&(n="right"))):!0===c.down&&r>0?(n="down",a>l&&(!0===c.left&&o<0?n="left":!0===c.right&&o>0&&(n="right"))):!0===c.left&&o<0?(n="left",a<l&&(!0===c.up&&r<0?n="up":!0===c.down&&r>0&&(n="down"))):!0===c.right&&o>0&&(n="right",a<l&&(!0===c.up&&r<0?n="up":!0===c.down&&r>0&&(n="down")));var u=!1;if(void 0===n&&!1===i){if(!0===e.event.isFirst||void 0===e.event.lastDir)return{};u=!0,"left"===(n=e.event.lastDir)||"right"===n?(s.left-=o,a=0,o=0):(s.top-=r,l=0,r=0)}return{synthetic:u,payload:{evt:t,touch:!0!==e.event.mouse,mouse:!0===e.event.mouse,position:s,direction:n,isFirst:e.event.isFirst,isFinal:!0===i,duration:Date.now()-e.event.time,distance:{x:a,y:l},offset:{x:o,y:r},delta:{x:s.left-e.event.lastX,y:s.top-e.event.lastY}}}}function wn(t){var e=t.__qtouchpan;void 0!==e&&(void 0!==e.event&&e.end(),k(e,"main"),k(e,"temp"),!0===c.is.firefox&&w(t,!1),void 0!==e.styleCleanup&&e.styleCleanup(),delete t.__qtouchpan)}var Cn=0,xn={name:"touch-pan",bind:function(t,e){var i=e.value,n=e.modifiers;if(void 0!==t.__qtouchpan&&(wn(t),t.__qtouchpan_destroyed=!0),!0===n.mouse||!0===c.has.touch){var s={uid:"qvtp_"+Cn++,handler:i,modifiers:n,direction:Di(n),noop:p,mouseStart:function(t){Ri(t,s)&&f(t)&&(x(s,"temp",[[document,"mousemove","move","notPassiveCapture"],[document,"mouseup","end","passiveCapture"]]),s.start(t,!0))},touchStart:function(t){if(Ri(t,s)){var e=t.target;x(s,"temp",[[e,"touchmove","move","notPassiveCapture"],[e,"touchcancel","end","passiveCapture"],[e,"touchend","end","passiveCapture"]]),s.start(t)}},start:function(e,i){!0===c.is.firefox&&w(t,!0),s.lastEvt=e;var o=m(e);if(!0===i||!0===n.stop){if(!0!==s.direction.all&&(!0!==i||!0!==s.direction.mouseAllDir)){var r=e.type.indexOf("mouse")>-1?new MouseEvent(e.type,e):new TouchEvent(e.type,e);!0===e.defaultPrevented&&y(r),!0===e.cancelBubble&&b(r),r.qClonedBy=void 0===e.qClonedBy?[s.uid]:e.qClonedBy.concat(s.uid),r.qKeyEvent=e.qKeyEvent,r.qClickOutside=e.qClickOutside,s.initialEvent={target:e.target,event:r}}b(e)}s.event={x:o.left,y:o.top,time:Date.now(),mouse:!0===i,detected:!1,isFirst:!0,isFinal:!1,lastX:o.left,lastY:o.top}},move:function(t){if(void 0!==s.event){s.lastEvt=t;var e=!0===s.event.mouse,i=function(){o(t,e),!0!==n.preserveCursor&&(document.documentElement.style.cursor="grabbing"),!0===e&&document.body.classList.add("no-pointer-events--children"),document.body.classList.add("non-selectable"),ze(),s.styleCleanup=function(t){if(s.styleCleanup=void 0,!0!==n.preserveCursor&&(document.documentElement.style.cursor=""),document.body.classList.remove("non-selectable"),!0===e){var i=function(){document.body.classList.remove("no-pointer-events--children")};void 0!==t?setTimeout(function(){i(),t()},50):i()}else void 0!==t&&t()}};if(!0!==s.event.detected){if(!0===s.direction.all||!0===e&&!0===s.modifiers.mouseAllDir)return i(),s.event.detected=!0,void s.move(t);var r=m(t),a=r.left-s.event.x,l=r.top-s.event.y,c=Math.abs(a),u=Math.abs(l);c!==u&&(!0===s.direction.horizontal&&c>u||!0===s.direction.vertical&&c<u||!0===s.direction.up&&c<u&&l<0||!0===s.direction.down&&c<u&&l>0||!0===s.direction.left&&c>u&&a<0||!0===s.direction.right&&c>u&&a>0?(s.event.detected=!0,s.move(t)):s.end(t,!0))}else{!0!==s.event.isFirst&&o(t,s.event.mouse);var h=Sn(t,s,!1),d=h.payload,p=h.synthetic;void 0!==d&&(!1===s.handler(d)?s.end(t):(void 0===s.styleCleanup&&!0===s.event.isFirst&&i(),s.event.lastX=d.position.left,s.event.lastY=d.position.top,s.event.lastDir=!0===p?void 0:d.direction,s.event.isFirst=!1))}}},end:function(e,i){if(void 0!==s.event){if(k(s,"temp"),!0===c.is.firefox&&w(t,!1),!0===i)void 0!==s.styleCleanup&&s.styleCleanup(),!0!==s.event.detected&&void 0!==s.initialEvent&&s.initialEvent.target.dispatchEvent(s.initialEvent.event);else if(!0===s.event.detected){!0===s.event.isFirst&&s.handler(Sn(void 0===e?s.lastEvt:e,s).payload);var n=Sn(void 0===e?s.lastEvt:e,s,!0).payload,o=function(){s.handler(n)};void 0!==s.styleCleanup?s.styleCleanup(o):o()}s.event=void 0,s.initialEvent=void 0,s.lastEvt=void 0}}};t.__qtouchpan=s,!0===n.mouse&&x(s,"main",[[t,"mousedown","mouseStart","passive"+(!0===n.mouseCapture?"Capture":"")]]),!0===c.has.touch&&x(s,"main",[[t,"touchstart","touchStart","passive"+(!0===n.capture?"Capture":"")],[t,"touchmove","noop","notPassiveCapture"]])}function o(t,e){!0===n.mouse&&!0===e?S(t):(!0===n.stop&&b(t),!0===n.prevent&&y(t))}},update:function(t,e){var i=e.oldValue,n=e.value,s=t.__qtouchpan;void 0!==s&&i!==n&&("function"!=typeof n&&s.end(),s.handler=n)},unbind:function(t){void 0===t.__qtouchpan_destroyed?wn(t):delete t.__qtouchpan_destroyed}},kn=function(t){return{value:t}},qn=[34,37,40,33,39,38],Tn={mixins:[Gt,Li],directives:{TouchPan:xn},props:{min:{type:Number,default:0},max:{type:Number,default:100},innerMin:Number,innerMax:Number,step:{type:Number,default:1,validator:function(t){return t>=0}},snap:Boolean,vertical:Boolean,reverse:Boolean,hideSelection:Boolean,color:String,markerLabelsClass:String,label:Boolean,labelColor:String,labelTextColor:String,labelAlways:Boolean,switchLabelSide:Boolean,markers:[Boolean,Number],markerLabels:[Boolean,Array,Object,Function],switchMarkerLabelsSide:Boolean,trackImg:String,trackColor:String,innerTrackImg:String,innerTrackColor:String,selectionColor:String,selectionImg:String,thumbSize:{type:String,default:"20px"},trackSize:{type:String,default:"4px"},disable:Boolean,readonly:Boolean,dense:Boolean,tabindex:[String,Number],thumbColor:String,thumbPath:{type:String,default:"M 4, 10 a 6,6 0 1,0 12,0 a 6,6 0 1,0 -12,0"}},data:function(){return{active:!1,preventFocus:!1,focus:!1,dragging:!1}},computed:{axis:function(){return!0===this.vertical?"--v":"--h"},labelSide:function(){return"-"+(!0===this.switchLabelSide?"switched":"standard")},isReversed:function(){return!0===this.vertical?!0===this.reverse:this.reverse!==(!0===this.$q.lang.rtl)},computedInnerMin:function(){return this.__getInnerMin(this.innerMin)},computedInnerMax:function(){return this.__getInnerMax(this.innerMax)},editable:function(){return!0!==this.disable&&!0!==this.readonly&&this.computedInnerMin<this.computedInnerMax},computedDecimals:function(){return(String(this.step).trim("0").split(".")[1]||"").length},computedStep:function(){return 0===this.step?1:this.step},computedTabindex:function(){return!0===this.editable?this.tabindex||0:-1},trackLen:function(){return this.max-this.min},innerBarLen:function(){return this.computedInnerMax-this.computedInnerMin},innerMinRatio:function(){return this.__convertModelToRatio(this.computedInnerMin)},innerMaxRatio:function(){return this.__convertModelToRatio(this.computedInnerMax)},positionProp:function(){return!0===this.vertical?!0===this.isReversed?"bottom":"top":!0===this.isReversed?"right":"left"},sizeProp:function(){return!0===this.vertical?"height":"width"},thicknessProp:function(){return!0===this.vertical?"width":"height"},orientation:function(){return!0===this.vertical?"vertical":"horizontal"},attributes:function(){var t={role:"slider","aria-valuemin":this.computedInnerMin,"aria-valuemax":this.computedInnerMax,"aria-orientation":this.orientation,"data-step":this.step};return!0===this.disable?t["aria-disabled"]="true":!0===this.readonly&&(t["aria-readonly"]="true"),t},classes:function(){return"q-slider q-slider"+this.axis+" q-slider--"+(!0===this.active?"":"in")+"active inline no-wrap "+(!0===this.vertical?"row":"column")+(!0===this.disable?" disabled":" q-slider--enabled"+(!0===this.editable?" q-slider--editable":""))+("both"===this.focus?" q-slider--focus":"")+(this.label||!0===this.labelAlways?" q-slider--label":"")+(!0===this.labelAlways?" q-slider--label-always":"")+(!0===this.isDark?" q-slider--dark":"")+(!0===this.dense?" q-slider--dense q-slider--dense"+this.axis:"")},selectionBarClass:function(){var t=this.selectionColor||this.color;return"q-slider__selection absolute"+(void 0!==t?" text-"+t:"")},markerClass:function(){return this.__getAxisClass("markers")+" absolute overflow-hidden"},trackContainerClass:function(){return this.__getAxisClass("track-container")},pinClass:function(){return this.__getPositionClass("pin")},labelClass:function(){return this.__getPositionClass("label")},textContainerClass:function(){return this.__getPositionClass("text-container")},markerLabelsContainerClass:function(){return this.__getPositionClass("marker-labels-container")+(void 0!==this.markerLabelsClass?" "+this.markerLabelsClass:"")},trackClass:function(){return"q-slider__track relative-position no-outline"+(void 0!==this.trackColor?" bg-"+this.trackColor:"")},trackStyle:function(){var t={};return t[this.thicknessProp]=this.trackSize,void 0!==this.trackImg&&(t.backgroundImage="url("+this.trackImg+") !important"),t},innerBarClass:function(){return"q-slider__inner absolute"+(void 0!==this.innerTrackColor?" bg-"+this.innerTrackColor:"")},innerBarStyle:function(){var t={};return t[this.positionProp]=100*this.innerMinRatio+"%",t[this.sizeProp]=100*(this.innerMaxRatio-this.innerMinRatio)+"%",void 0!==this.innerTrackImg&&(t.backgroundImage="url("+this.innerTrackImg+") !important"),t},markerStep:function(){return!0===tn(this.markers)?this.markers:this.computedStep},markerTicks:function(){var t=[],e=this.markerStep,i=this.min;do{t.push(i),i+=e}while(i<this.max);return t.push(this.max),t},markerLabelClass:function(){var t=" q-slider__marker-labels"+this.axis+"-";return"q-slider__marker-labels"+t+(!0===this.switchMarkerLabelsSide?"switched":"standard")+t+(!0===this.isReversed?"rtl":"ltr")},markerLabelsList:function(){var t=this;return!1===this.markerLabels?null:this.__getMarkerList(this.markerLabels).map(function(e,i){return{index:i,value:e.value,label:e.label||e.value,classes:t.markerLabelClass+(void 0!==e.classes?" "+e.classes:""),style:Object.assign({},t.__getMarkerLabelStyle(e.value),e.style||{})}})},markerScope:function(){return{markerList:this.markerLabelsList,markerMap:this.markerLabelsMap,classes:this.markerLabelClass,getStyle:this.__getMarkerLabelStyle}},markerStyle:function(){if(0!==this.innerBarLen){var t=100*this.markerStep/this.innerBarLen;return Object.assign({},this.innerBarStyle,{backgroundSize:!0===this.vertical?"2px "+t+"%":t+"% 2px"})}return null},markerLabelsMap:function(){if(!1===this.markerLabels)return null;var t={};return this.markerLabelsList.forEach(function(e){t[e.value]=e}),t},panDirectives:function(){var t;return!0===this.editable?[{name:"touch-pan",value:this.__onPan,modifiers:(t={},t[this.orientation]=!0,t.prevent=!0,t.stop=!0,t.mouse=!0,t.mouseAllDir=!0,t)}]:null}},methods:{__getInnerMin:function(t){return!0===isNaN(t)||this.innerMin<this.min?this.min:this.innerMin},__getInnerMax:function(t){return!0===isNaN(t)||t>this.max?this.max:this.innerMax},__getPositionClass:function(t){var e="q-slider__"+t;return e+" "+e+this.axis+" "+e+this.axis+this.labelSide},__getAxisClass:function(t){var e="q-slider__"+t;return e+" "+e+this.axis},__convertRatioToModel:function(t){var e=this.min+t*(this.max-this.min);if(this.step>0){var i=(e-this.min)%this.step;e+=(Math.abs(i)>=this.step/2?(i<0?-1:1)*this.step:0)-i}return this.computedDecimals>0&&(e=parseFloat(e.toFixed(this.computedDecimals))),ut(e,this.computedInnerMin,this.computedInnerMax)},__convertModelToRatio:function(t){return 0===this.trackLen?0:(t-this.min)/this.trackLen},__getDraggingRatio:function(t,e){var i=m(t),n=!0===this.vertical?ut((i.top-e.top)/e.height,0,1):ut((i.left-e.left)/e.width,0,1);return ut(!0===this.isReversed?1-n:n,this.innerMinRatio,this.innerMaxRatio)},__getMarkerList:function(t){var e=this;if(!1===t)return null;if(!0===t)return this.markerTicks.map(kn);if("function"==typeof t)return this.markerTicks.map(function(e){var i=t(e);return!0===Zi(i)?Object.assign({},i,{value:e}):{value:e,label:i}});var i=function(t){var i=t.value;return i>=e.min&&i<=e.max};return!0===Array.isArray(t)?t.map(function(t){return!0===Zi(t)?t:{value:t}}).filter(i):Object.keys(t).map(function(e){var i=t[e],n=Number(e);return!0===Zi(i)?Object.assign({},i,{value:n}):{value:n,label:i}}).filter(i)},__getMarkerLabelStyle:function(t){var e;return(e={})[this.positionProp]=100*(t-this.min)/this.trackLen+"%",e},__getMarkerLabelsContent:function(t){var e=this;if(void 0!==this.$scopedSlots["marker-label-group"])return this.$scopedSlots["marker-label-group"](this.markerScope);var i=this.$scopedSlots["marker-label"];return void 0!==i?this.markerLabelsList.map(function(t){return i(Object.assign({},{marker:t},e.markerScope))}):this.markerLabelsList.map(function(e){return t("div",{key:e.value,style:e.style,class:e.classes},e.label)})},__onPan:function(t){!0===t.isFinal?(void 0!==this.dragging&&(this.__updatePosition(t.evt),!0===t.touch&&this.__updateValue(!0),this.dragging=void 0,this.$emit("pan","end")),this.active=!1,this.focus=!1):!0===t.isFirst?(this.dragging=this.__getDragging(t.evt),this.__updatePosition(t.evt),this.__updateValue(),this.active=!0,this.$emit("pan","start")):(this.__updatePosition(t.evt),this.__updateValue())},__onBlur:function(){this.focus=!1},__onActivate:function(t){this.__updatePosition(t,this.__getDragging(t)),this.__updateValue(),this.preventFocus=!0,this.active=!0,document.addEventListener("mouseup",this.__onDeactivate,!0)},__onDeactivate:function(){this.preventFocus=!1,this.active=!1,this.__updateValue(!0),this.__onBlur(),document.removeEventListener("mouseup",this.__onDeactivate,!0)},__onMobileClick:function(t){this.__updatePosition(t,this.__getDragging(t)),this.__updateValue(!0)},__onKeyup:function(t){qn.includes(t.keyCode)&&this.__updateValue(!0)},__getTextContainerStyle:function(t){if(!0===this.vertical)return null;var e=this.$q.lang.rtl!==this.reverse?1-t:t;return{transform:"translateX(calc("+(2*e-1)+" * "+this.thumbSize+" / 2 + "+(50-100*e)+"%))"}},__getThumb:function(t,e){var i=[t("svg",{class:"q-slider__thumb-shape absolute-full",attrs:{viewBox:"0 0 20 20","aria-hidden":"true"}},[t("path",{attrs:{d:this.thumbPath}})]),t("div",{class:"q-slider__focus-ring fit"})];return!0!==this.label&&!0!==this.labelAlways||(i.push(t("div",{class:this.pinClass+" absolute fit no-pointer-events"+e.pinColor},[t("div",{class:this.labelClass,style:{minWidth:this.thumbSize}},[t("div",{class:this.textContainerClass,style:e.textContainerStyle},[t("span",{class:e.textClass},e.label)])])])),void 0!==this.name&&!0!==this.disable&&this.__injectFormInput(i,"push")),t("div",Object.assign({},{class:e.classes,style:e.style},e.nodeData),i)},__getContent:function(t,e){var i=[];"transparent"!==this.innerTrackColor&&i.push(t("div",{key:"inner",class:this.innerBarClass,style:this.innerBarStyle})),"transparent"!==this.selectionColor&&i.push(t("div",{key:"selection",class:this.selectionBarClass,style:this.selectionBarStyle})),!1!==this.markers&&i.push(t("div",{key:"marker",class:this.markerClass,style:this.markerStyle})),e(i);var n=[t("div",{key:"trackC",class:this.trackContainerClass,attrs:this.trackContainerAttrs,on:this.trackContainerEvents,directives:this.panDirectives},[t("div",{class:this.trackClass,style:this.trackStyle},i)])];!1!==this.markerLabels&&n[!0===this.switchMarkerLabelsSide?"unshift":"push"](t("div",{key:"markerL",class:this.markerLabelsContainerClass},this.__getMarkerLabelsContent(t)));return n}},beforeDestroy:function(){document.removeEventListener("mouseup",this.__onDeactivate,!0)}},Mn=t.extend({name:"QSlider",mixins:[Tn],props:{value:{required:!0,default:null,validator:function(t){return"number"==typeof t||null===t}},labelValue:[String,Number]},data:function(){var t=this.__getInnerMin(this.innerMin),e=this.__getInnerMax(this.innerMax);return{model:null===this.value?t:ut(this.value,t,e),curRatio:0}},computed:{modelRatio:function(){return this.__convertModelToRatio(this.model)},ratio:function(){return!0===this.active?this.curRatio:this.modelRatio},selectionBarStyle:function(){var t={};return t[this.positionProp]=100*this.innerMinRatio+"%",t[this.sizeProp]=100*(this.ratio-this.innerMinRatio)+"%",void 0!==this.selectionImg&&(t.backgroundImage="url("+this.selectionImg+") !important"),t},thumbLabel:function(){return void 0!==this.labelValue?this.labelValue:this.model},thumbClasses:function(){var t=this.thumbColor||this.color;return"q-slider__thumb q-slider__thumb"+this.axis+" q-slider__thumb"+this.axis+"-"+(!0===this.isReversed?"rtl":"ltr")+" absolute non-selectable"+(!1===this.preventFocus&&!0===this.focus?" q-slider--focus":"")+(void 0!==t?" text-"+t:"")},thumbStyle:function(){var t;return(t={width:this.thumbSize,height:this.thumbSize})[this.positionProp]=100*this.ratio+"%",t},thumbPinColor:function(){return void 0!==this.labelColor?" text-"+this.labelColor:""},thumbTextContainerStyle:function(){return this.__getTextContainerStyle(this.ratio)},thumbTextClass:function(){return"q-slider__text"+(void 0!==this.labelTextColor?" text-"+this.labelTextColor:"")},trackContainerEvents:function(){return!0!==this.editable?{}:!0===this.$q.platform.is.mobile?{click:this.__onMobileClick}:{mousedown:this.__onActivate,focus:this.__onFocus,blur:this.__onBlur,keydown:this.__onKeydown,keyup:this.__onKeyup}},trackContainerAttrs:function(){return{tabindex:!0!==this.$q.platform.is.mobile?this.computedTabindex:null}},modelUpdate:function(){return this.value+"|"+this.computedInnerMin+"|"+this.computedInnerMax}},watch:{modelUpdate:function(){this.model=null===this.value?this.computedInnerMin:ut(this.value,this.computedInnerMin,this.computedInnerMax)}},methods:{__updateValue:function(t){this.model!==this.value&&this.$emit("input",this.model),!0===t&&this.$emit("change",this.model)},__getDragging:function(){return this.$el.getBoundingClientRect()},__updatePosition:function(t,e){void 0===e&&(e=this.dragging);var i=this.__getDraggingRatio(t,e);this.model=this.__convertRatioToModel(i),this.curRatio=!0!==this.snap||0===this.computedStep?i:this.__convertModelToRatio(this.model)},__onFocus:function(){this.focus=!0},__onKeydown:function(t){if(qn.includes(t.keyCode)){S(t);var e=([34,33].includes(t.keyCode)?10:1)*this.computedStep,i=([34,37,40].includes(t.keyCode)?-1:1)*(!0===this.isReversed?-1:1)*e;this.model=ut(parseFloat((this.model+i).toFixed(this.computedDecimals)),this.computedInnerMin,this.computedInnerMax),this.__updateValue()}}},render:function(t){var e=this,i=this.__getContent(t,function(i){i.push(e.__getThumb(t,{pinColor:e.thumbPinColor,textContainerStyle:e.thumbTextContainerStyle,textClass:e.thumbTextClass,label:e.thumbLabel,classes:e.thumbClasses,style:e.thumbStyle,nodeData:{}}))});return t("div",{class:this.classes+(null===this.value?" q-slider--no-value":""),attrs:Object.assign({},this.attributes,{"aria-valuenow":this.value})},i)}}),$n={data:function(){return{canRender:!s}},mounted:function(){!1===this.canRender&&(this.canRender=!0)}},Ln=t.extend({name:"QResizeObserver",mixins:[$n],props:{debounce:{type:[String,Number],default:100}},data:function(){return!0===this.hasObserver?{}:{url:!0===this.$q.platform.is.ie?null:"about:blank"}},methods:{trigger:function(t){!0===t||0===this.debounce||"0"===this.debounce?this.__emit():null===this.timer&&(this.timer=setTimeout(this.__emit,this.debounce))},__emit:function(){if(null!==this.timer&&(clearTimeout(this.timer),this.timer=null),this.$el&&this.$el.parentNode){var t=this.$el.parentNode,e={width:t.offsetWidth,height:t.offsetHeight};e.width===this.size.width&&e.height===this.size.height||(this.size=e,this.$emit("resize",this.size))}},__cleanup:function(){void 0!==this.curDocView&&(void 0!==this.curDocView.removeEventListener&&this.curDocView.removeEventListener("resize",this.trigger,h.passive),this.curDocView=void 0)},__onObjLoad:function(){this.__cleanup(),this.$el.contentDocument&&(this.curDocView=this.$el.contentDocument.defaultView,this.curDocView.addEventListener("resize",this.trigger,h.passive)),this.__emit()}},render:function(t){if(!1!==this.canRender&&!0!==this.hasObserver)return t("object",{style:this.style,attrs:{tabindex:-1,type:"text/html",data:this.url,"aria-hidden":"true"},on:ft(this,"load",{load:this.__onObjLoad})})},beforeCreate:function(){this.size={width:-1,height:-1},!0!==i&&(this.hasObserver="undefined"!=typeof ResizeObserver,!0!==this.hasObserver&&(this.style=(this.$q.platform.is.ie?"visibility:hidden;":"")+"display:block;position:absolute;top:0;left:0;right:0;bottom:0;height:100%;width:100%;overflow:hidden;pointer-events:none;z-index:-1;"))},mounted:function(){if(this.timer=null,!0===this.hasObserver)return this.observer=new ResizeObserver(this.trigger),this.observer.observe(this.$el.parentNode),void this.__emit();!0===this.$q.platform.is.ie?(this.url="about:blank",this.__emit()):this.__onObjLoad()},beforeDestroy:function(){clearTimeout(this.timer),!0!==this.hasObserver?this.__cleanup():void 0!==this.observer&&this.$el.parentNode&&this.observer.unobserve(this.$el.parentNode)}});function On(t,e,i){var n=!0===i?["left","right"]:["top","bottom"];return"absolute-"+(!0===e?n[0]:n[1])+(t?" text-"+t:"")}function Bn(t,e){return t.priorityMatched===e.priorityMatched?e.priorityHref-t.priorityHref:e.priorityMatched-t.priorityMatched}function En(t){return t.selected=!1,t}var zn=[function(t){return!0===t.selected&&!0===t.exact&&!0!==t.redirected},function(t){return!0===t.selected&&!0===t.exact},function(t){return!0===t.selected&&!0!==t.redirected},function(t){return!0===t.selected},function(t){return!0===t.exact&&!0!==t.redirected},function(t){return!0!==t.redirected},function(t){return!0===t.exact},function(t){return!0}],Pn=zn.length,An=t.extend({name:"QTabs",mixins:[Ae,Lt],provide:function(){return{tabs:this.tabs,__recalculateScroll:this.__recalculateScroll,__activateTab:this.__activateTab,__activateRoute:this.__activateRoute,__onKbdNavigate:this.__onKbdNavigate}},props:{value:[Number,String],align:{type:String,default:"center",validator:function(t){return["left","center","right","justify"].includes(t)}},breakpoint:{type:[String,Number],default:600},vertical:Boolean,shrink:Boolean,stretch:Boolean,activeClass:String,activeColor:String,activeBgColor:String,indicatorColor:String,leftIcon:String,rightIcon:String,outsideArrows:Boolean,mobileArrows:Boolean,switchIndicator:Boolean,narrowIndicator:Boolean,inlineLabel:Boolean,noCaps:Boolean,dense:Boolean,contentClass:String},data:function(){return{tabs:{current:this.value,hasFocus:!1,activeClass:this.activeClass,activeColor:this.activeColor,activeBgColor:this.activeBgColor,indicatorClass:On(this.indicatorColor,this.switchIndicator,this.vertical),narrowIndicator:this.narrowIndicator,inlineLabel:this.inlineLabel,noCaps:this.noCaps},scrollable:!1,startArrow:!0,endArrow:!1,justify:!1}},watch:{value:function(t){this.__activateTab(t,!0,!0)},activeClass:function(t){this.tabs.activeClass=t},activeColor:function(t){this.tabs.activeColor=t},activeBgColor:function(t){this.tabs.activeBgColor=t},vertical:function(t){this.tabs.indicatorClass=On(this.indicatorColor,this.switchIndicator,t)},indicatorColor:function(t){this.tabs.indicatorClass=On(t,this.switchIndicator,this.vertical)},switchIndicator:function(t){this.tabs.indicatorClass=On(this.indicatorColor,t,this.vertical)},narrowIndicator:function(t){this.tabs.narrowIndicator=t},inlineLabel:function(t){this.tabs.inlineLabel=t},noCaps:function(t){this.tabs.noCaps=t},outsideArrows:function(){this.__recalculateScroll()},arrowsEnabled:function(t){this.__updateArrows=!0===t?this.__updateArrowsFn:p,this.__recalculateScroll()},isRTL:function(){this.__updateArrows()}},computed:{arrowsEnabled:function(){return!0===this.$q.platform.is.desktop||!0===this.mobileArrows},arrowIcons:function(){var t,e=!0===this.isRTL?["end","start"]:["start","end"];return(t={})[e[0]]=this.leftIcon||(!0===this.vertical?this.$q.iconSet.tabs.up:this.$q.iconSet.tabs.left),t[e[1]]=this.rightIcon||(!0===this.vertical?this.$q.iconSet.tabs.down:this.$q.iconSet.tabs.right),t},alignClass:function(){return"q-tabs__content--align-"+(!0===this.scrollable?"left":!0===this.justify?"justify":this.align)},classes:function(){return"q-tabs--"+(!0===this.scrollable?"":"not-")+"scrollable q-tabs--"+(!0===this.vertical?"vertical":"horizontal")+" q-tabs__arrows--"+(!0===this.arrowsEnabled&&!0===this.outsideArrows?"outside":"inside")+(!0===this.dense?" q-tabs--dense":"")+(!0===this.shrink?" col-shrink":"")+(!0===this.stretch?" self-stretch":"")},innerClass:function(){return this.alignClass+(void 0!==this.contentClass?" "+this.contentClass:"")+(!0===this.$q.platform.is.mobile?" scroll":"")},domProps:function(){return!0===this.vertical?{container:"height",content:"offsetHeight",scroll:"scrollHeight"}:{container:"width",content:"offsetWidth",scroll:"scrollWidth"}},isRTL:function(){return!0!==this.vertical&&!0===this.$q.lang.rtl},__getScrollPosition:function(){return!0===this.vertical?function(t){return t.scrollTop}:!0!==this.$q.lang.rtl?function(t){return t.scrollLeft}:!0===this.rtlHasScrollBug?function(t){return t.scrollWidth-t.clientWidth-t.scrollLeft}:function(t){return 1-t.scrollLeft}},__setScrollPosition:function(){return!0===this.vertical?function(t,e){t.scrollTop=e}:!0!==this.$q.lang.rtl?function(t,e){t.scrollLeft=e}:!0===this.rtlHasScrollBug?function(t,e){t.scrollLeft=t.scrollWidth-t.clientWidth-e}:function(t,e){t.scrollLeft=1-e}},__getScrollOffset:function(){return!0===this.vertical?function(t){return t.offsetTop}:!0!==this.$q.lang.rtl||!0===this.rtlHasScrollBug?function(t){return t.offsetLeft}:function(t){return t.offsetParent.offsetWidth-t.offsetLeft-t.clientWidth}},onEvents:function(){return Object.assign({},{input:b},this.qListeners,{focusin:this.__onFocusin,focusout:this.__onFocusout})}},methods:{__onFocusin:function(t){this.tabs.hasFocus=!0,void 0!==this.qListeners.focusin&&this.$emit("focusin",t)},__onFocusout:function(t){this.tabs.hasFocus=!1,void 0!==this.qListeners.focusout&&this.$emit("focusout",t)},__activateTab:function(t,e,i){this.tabs.current!==t&&(!0!==i&&this.$emit("input",t),!0!==e&&void 0!==this.qListeners.input||(this.__animate(this.tabs.current,t),this.tabs.current=t))},__activateRoute:function(t){var e=this;this.bufferRoute!==this.$route&&this.buffer.length>0&&(clearTimeout(this.bufferTimer),this.bufferTimer=void 0,this.buffer.length=0),this.bufferRoute=this.$route,void 0!==t&&(!0===t.remove?this.buffer=this.buffer.filter(function(e){return e.name!==t.name}):this.buffer.push(t)),void 0===this.bufferTimer&&(this.bufferTimer=setTimeout(function(){for(var t=[],i=0;i<Pn&&0===t.length;i++)t=e.buffer.filter(zn[i]);t.sort(Bn),e.__activateTab(0===t.length?null:t[0].name,!0),e.buffer=e.buffer.map(En),e.bufferTimer=void 0},1))},__recalculateScroll:function(){var t=this;this.__nextTick(function(){!0!==t._isDestroyed&&t.__updateContainer({width:t.$el.offsetWidth,height:t.$el.offsetHeight})}),this.__prepareTick()},__updateContainer:function(t){var e=this,i=t[this.domProps.container],n=Math.min(this.$refs.content[this.domProps.scroll],Array.prototype.reduce.call(this.$refs.content.children,function(t,i){return t+(i[e.domProps.content]||0)},0)),s=i>0&&n>i;this.scrollable!==s&&(this.scrollable=s),!0===s&&this.$nextTick(function(){return e.__updateArrows()});var o=i<parseInt(this.breakpoint,10);this.justify!==o&&(this.justify=o)},__animate:function(t,e){var i=this,n=void 0!==t&&null!==t&&""!==t?this.$children.find(function(e){return e.name===t}):null,s=void 0!==e&&null!==e&&""!==e?this.$children.find(function(t){return t.name===e}):null;if(n&&s){var o=n.$el.getElementsByClassName("q-tab__indicator")[0],r=s.$el.getElementsByClassName("q-tab__indicator")[0];clearTimeout(this.animateTimer),o.style.transition="none",o.style.transform="none",r.style.transition="none",r.style.transform="none";var a=o.getBoundingClientRect(),l=r.getBoundingClientRect();r.style.transform=!0===this.vertical?"translate3d(0,"+(a.top-l.top)+"px,0) scale3d(1,"+(l.height?a.height/l.height:1)+",1)":"translate3d("+(a.left-l.left)+"px,0,0) scale3d("+(l.width?a.width/l.width:1)+",1,1)",this.$nextTick(function(){i.animateTimer=setTimeout(function(){r.style.transition="transform .25s cubic-bezier(.4, 0, .2, 1)",r.style.transform="none"},70)})}s&&!0===this.scrollable?this.__scrollToTab(s.$el,void 0,!0):this.__updateArrows()},__updateArrowsFn:function(){var t=this.$refs.content;if(void 0!==t){var e=t.getBoundingClientRect(),i=this.__getScrollPosition(t);this.startArrow=i>(!0===this.isRTL?1:0),this.endArrow=!0===this.vertical?Math.ceil(i+e.height)<t.scrollHeight:Math.ceil(i+e.width)<t.scrollWidth}},__animScrollTo:function(t,e){var i=this;this.__stopAnimScroll(),this.__onAnimScrollEnd=e,this.__scrollTowards(t),this.scrollTimer=setInterval(function(){i.__scrollTowards(t)&&i.__stopAnimScroll()},5)},__scrollToStart:function(){this.__animScrollTo(0)},__scrollToEnd:function(){this.__animScrollTo(Number.MAX_SAFE_INTEGER)},__stopAnimScroll:function(){clearInterval(this.scrollTimer),void 0!==this.__onAnimScrollEnd&&(this.__onAnimScrollEnd(),this.__onAnimScrollEnd=void 0)},__scrollTowards:function(t){var e=this.$refs.content,i=!0===this.vertical?e.scrollHeight-e.offsetHeight:e.scrollWidth-e.offsetWidth,n=this.__getScrollPosition(e),s=!1,o=(t=Math.max(0,Math.min(i,t)))<n?-1:1;return n+=5*o,(-1===o&&n<=t||1===o&&n>=t)&&(s=!0,n=t),this.__setScrollPosition(e,n),this.__updateArrows(),s},__scrollToTab:function(t,e,i){if(void 0!==this.$refs.content){var n=this.$refs.content,s=this.__getScrollPosition(n),o=!0===this.vertical?n.offsetHeight:n.offsetWidth,r=!0===this.vertical?n.scrollHeight:n.scrollWidth,a=this.__getScrollOffset(t),l=a+(!0===this.vertical?t.offsetHeight:t.offsetWidth),c=a<s,u=l>s+o;!0!==c&&!0!==u?e=void 0:void 0===e&&(l>=r-1?e=!0:!0===c||!0===u&&a<l-o?e=!1:c!==u&&(e=u)),void 0!==e?this.__animScrollTo(!0===e?l>=r-1?r:l-o:a<=1?0:a,!0!==i?function(){setTimeout(function(){t&&t.focus()})}:void 0):!0!==i&&t.focus()}},__onKbdNavigate:function(t,e){var i=Array.prototype.filter.call(this.$refs.content.children,function(t){return t===e||t.matches&&!0===t.matches(".q-tab.q-focusable")}),n=i.length;if(0!==n){if(36===t)return!0!==i[0].contains(document.activeElement)&&(this.__scrollToTab(i[0],!1),this.__recalculateScroll(),!0);if(35===t)return!0!==i[n-1].contains(document.activeElement)&&(this.__scrollToTab(i[n-1],!0),this.__recalculateScroll(),!0);var s=!0===this.vertical&&38===t||!0!==this.vertical&&37===t,o=!0===this.vertical&&40===t||!0!==this.vertical&&39===t,r=!0===s?-1:!0===o?1:void 0;if(void 0!==r){var a=!0===this.isRTL?-1:1,l=i.indexOf(e)+r*a;return!(l<0||l>=n||!0===i[l].contains(document.activeElement))&&(this.__scrollToTab(i[l],r===a),this.__recalculateScroll(),!0)}}}},created:function(){this.buffer=[],this.__updateArrows=!0===this.arrowsEnabled?this.__updateArrowsFn:p},mounted:function(){this.rtlHasScrollBug=ei()},activated:function(){!0===this.shouldActivate&&this.__recalculateScroll()},deactivated:function(){this.shouldActivate=!0},beforeDestroy:function(){clearTimeout(this.bufferTimer),clearTimeout(this.animateTimer)},render:function(t){var e=[t(Ln,{on:ft(this,"resize",{resize:this.__updateContainer})}),t("div",{ref:"content",staticClass:"q-tabs__content row no-wrap items-center self-stretch hide-scrollbar relative-position",class:this.innerClass,on:!0===this.arrowsEnabled?ft(this,"scroll",{scroll:this.__updateArrowsFn}):void 0},Ot(this,"default"))];return!0===this.arrowsEnabled&&e.push(t(Ut,{staticClass:"q-tabs__arrow q-tabs__arrow--start absolute q-tab__icon",class:!0===this.startArrow?"":"q-tabs__arrow--faded",props:{name:this.arrowIcons.start},on:ft(this,"onS",{mousedown:this.__scrollToStart,touchstart:this.__scrollToStart,mouseup:this.__stopAnimScroll,mouseleave:this.__stopAnimScroll,touchend:this.__stopAnimScroll})}),t(Ut,{staticClass:"q-tabs__arrow q-tabs__arrow--end absolute q-tab__icon",class:!0===this.endArrow?"":"q-tabs__arrow--faded",props:{name:this.arrowIcons.end},on:ft(this,"onE",{mousedown:this.__scrollToEnd,touchstart:this.__scrollToEnd,mouseup:this.__stopAnimScroll,mouseleave:this.__stopAnimScroll,touchend:this.__stopAnimScroll})})),t("div",{staticClass:"q-tabs row no-wrap items-center",class:this.classes,on:this.onEvents,attrs:{role:"tablist"}},e)}}),In=0,Dn=t.extend({name:"QTab",mixins:[we,Lt],inject:{tabs:{default:function(){console.error("QTab/QRouteTab components need to be child of QTabs")}},__activateTab:{},__recalculateScroll:{},__onKbdNavigate:{}},props:{icon:String,label:[Number,String],alert:[Boolean,String],alertIcon:String,name:{type:[Number,String],default:function(){return"t_"+In++}},noCaps:Boolean,tabindex:[String,Number],disable:Boolean,contentClass:String},computed:{isActive:function(){return this.tabs.current===this.name},classes:function(){var t;return Object.assign({},!0===this.isActive?((t={"q-tab--active":!0})[this.tabs.activeClass]=this.tabs.activeClass,t["text-"+this.tabs.activeColor]=this.tabs.activeColor,t["bg-"+this.tabs.activeBgColor]=this.tabs.activeBgColor,t):{"q-tab--inactive":!0},{"q-tab--full":this.icon&&this.label&&!this.tabs.inlineLabel,"q-tab--no-caps":!0===this.noCaps||!0===this.tabs.noCaps,"q-focusable q-hoverable cursor-pointer":!this.disable,disabled:this.disable})},innerClass:function(){return(!0===this.tabs.inlineLabel?"row no-wrap q-tab__content--inline":"column")+(void 0!==this.contentClass?" "+this.contentClass:"")},computedTabIndex:function(){return!0===this.disable||!0===this.tabs.hasFocus?-1:this.tabindex||0},computedRipple:function(){return!1!==this.ripple&&Object.assign({keyCodes:[13,32],early:!0},!0===this.ripple?{}:this.ripple)},onEvents:function(){return Object.assign({},{input:b},this.qListeners,{click:this.__activate,keydown:this.__onKeydown})},attrs:function(){var t={tabindex:this.computedTabIndex,role:"tab","aria-selected":!0===this.isActive?"true":"false"};return!0===this.disable&&(t["aria-disabled"]="true"),t}},methods:{__activate:function(t,e){!0!==e&&void 0!==this.$refs.blurTarget&&this.$refs.blurTarget.focus({preventScroll:!0}),!0!==this.disable&&(void 0!==this.qListeners.click&&this.$emit("click",t),this.__activateTab(this.name))},__onKeydown:function(t){Z(t)||(-1!==[13,32].indexOf(t.keyCode)?(this.__activate(t,!0),y(t)):t.keyCode>=35&&t.keyCode<=40&&!0===this.__onKbdNavigate(t.keyCode,this.$el)&&S(t))},__getContent:function(t){var e=this.tabs.narrowIndicator,i=[],n=t("div",{staticClass:"q-tab__indicator",class:this.tabs.indicatorClass});void 0!==this.icon&&i.push(t(Ut,{staticClass:"q-tab__icon",props:{name:this.icon}})),void 0!==this.label&&i.push(t("div",{staticClass:"q-tab__label"},[this.label])),!1!==this.alert&&i.push(void 0!==this.alertIcon?t(Ut,{staticClass:"q-tab__alert-icon",props:{color:!0!==this.alert?this.alert:void 0,name:this.alertIcon}}):t("div",{staticClass:"q-tab__alert",class:!0!==this.alert?"text-"+this.alert:null})),!0===e&&i.push(n);var s=[t("div",{staticClass:"q-focus-helper",attrs:{tabindex:-1},ref:"blurTarget"}),t("div",{staticClass:"q-tab__content self-stretch flex-center relative-position q-anchor--skip non-selectable",class:this.innerClass},Et(i,this,"default"))];return!1===e&&s.push(n),s},__renderTab:function(t,e){var i=this,n={staticClass:"q-tab relative-position self-stretch flex flex-center text-center no-outline",class:this.classes,attrs:this.attrs,directives:!1===this.ripple||!0===this.disable?null:[{name:"ripple",value:this.computedRipple}]};return!0===this.hasRouterLink?t(e,Object.assign({},n,{nativeOn:this.onEvents,props:this.routerTabLinkProps,scopedSlots:{default:function(e){var n,s=e.href,o=e.isActive,r=e.isExactActive;return t("a",{class:(n={},n[i.activeClass]=o,n[i.exactActiveClass]=r,n),attrs:Object.assign({},i.linkProps.attrs,{href:s})},i.__getContent(t))}}})):(!0===this.hasLink&&(Object.assign(n.attrs,this.linkProps.attrs),n.props=this.linkProps.props),n.on=this.onEvents,t(e,n,this.__getContent(t)))}},mounted:function(){this.__recalculateScroll()},beforeDestroy:function(){this.__recalculateScroll()},render:function(t){return this.__renderTab(t,"div")}}),Rn=t.extend({name:"QTabPanels",mixins:[Gt,Hi],computed:{classes:function(){return"q-tab-panels q-panel-parent"+(!0===this.isDark?" q-tab-panels--dark q-dark":"")}},methods:{__renderPanels:function(t){return t("div",{class:this.classes,directives:this.panelDirectives,on:Object.assign({},this.qListeners)},this.__getPanelContent(t))}}}),Fn=t.extend({name:"QTabPanel",mixins:[Qi],render:function(t){return t("div",{staticClass:"q-tab-panel",on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),jn=["rgb(255,204,204)","rgb(255,230,204)","rgb(255,255,204)","rgb(204,255,204)","rgb(204,255,230)","rgb(204,255,255)","rgb(204,230,255)","rgb(204,204,255)","rgb(230,204,255)","rgb(255,204,255)","rgb(255,153,153)","rgb(255,204,153)","rgb(255,255,153)","rgb(153,255,153)","rgb(153,255,204)","rgb(153,255,255)","rgb(153,204,255)","rgb(153,153,255)","rgb(204,153,255)","rgb(255,153,255)","rgb(255,102,102)","rgb(255,179,102)","rgb(255,255,102)","rgb(102,255,102)","rgb(102,255,179)","rgb(102,255,255)","rgb(102,179,255)","rgb(102,102,255)","rgb(179,102,255)","rgb(255,102,255)","rgb(255,51,51)","rgb(255,153,51)","rgb(255,255,51)","rgb(51,255,51)","rgb(51,255,153)","rgb(51,255,255)","rgb(51,153,255)","rgb(51,51,255)","rgb(153,51,255)","rgb(255,51,255)","rgb(255,0,0)","rgb(255,128,0)","rgb(255,255,0)","rgb(0,255,0)","rgb(0,255,128)","rgb(0,255,255)","rgb(0,128,255)","rgb(0,0,255)","rgb(128,0,255)","rgb(255,0,255)","rgb(245,0,0)","rgb(245,123,0)","rgb(245,245,0)","rgb(0,245,0)","rgb(0,245,123)","rgb(0,245,245)","rgb(0,123,245)","rgb(0,0,245)","rgb(123,0,245)","rgb(245,0,245)","rgb(214,0,0)","rgb(214,108,0)","rgb(214,214,0)","rgb(0,214,0)","rgb(0,214,108)","rgb(0,214,214)","rgb(0,108,214)","rgb(0,0,214)","rgb(108,0,214)","rgb(214,0,214)","rgb(163,0,0)","rgb(163,82,0)","rgb(163,163,0)","rgb(0,163,0)","rgb(0,163,82)","rgb(0,163,163)","rgb(0,82,163)","rgb(0,0,163)","rgb(82,0,163)","rgb(163,0,163)","rgb(92,0,0)","rgb(92,46,0)","rgb(92,92,0)","rgb(0,92,0)","rgb(0,92,46)","rgb(0,92,92)","rgb(0,46,92)","rgb(0,0,92)","rgb(46,0,92)","rgb(92,0,92)","rgb(255,255,255)","rgb(205,205,205)","rgb(178,178,178)","rgb(153,153,153)","rgb(127,127,127)","rgb(102,102,102)","rgb(76,76,76)","rgb(51,51,51)","rgb(25,25,25)","rgb(0,0,0)"],Vn=t.extend({name:"QColor",mixins:[Lt,Gt,Li],directives:{TouchPan:xn},props:{value:String,defaultValue:String,defaultView:{type:String,default:"spectrum",validator:function(t){return["spectrum","tune","palette"].includes(t)}},formatModel:{type:String,default:"auto",validator:function(t){return["auto","hex","rgb","hexa","rgba"].includes(t)}},palette:Array,noHeader:Boolean,noHeaderTabs:Boolean,noFooter:Boolean,square:Boolean,flat:Boolean,bordered:Boolean,disable:Boolean,readonly:Boolean},data:function(){return{topView:"auto"===this.formatModel?void 0===this.value||null===this.value||""===this.value||this.value.startsWith("#")?"hex":"rgb":this.formatModel.startsWith("hex")?"hex":"rgb",view:this.defaultView,model:this.__parseModel(this.value||this.defaultValue)}},watch:{value:function(t){var e=this.__parseModel(t||this.defaultValue);e.hex!==this.model.hex&&(this.model=e)},defaultValue:function(t){if(!this.value&&t){var e=this.__parseModel(t);e.hex!==this.model.hex&&(this.model=e)}}},computed:{editable:function(){return!0!==this.disable&&!0!==this.readonly},forceHex:function(){return"auto"===this.formatModel?null:this.formatModel.indexOf("hex")>-1},forceAlpha:function(){return"auto"===this.formatModel?null:this.formatModel.indexOf("a")>-1},isHex:function(){return void 0===this.value||null===this.value||""===this.value||this.value.startsWith("#")},isOutputHex:function(){return null!==this.forceHex?this.forceHex:this.isHex},formAttrs:function(){return{type:"hidden",name:this.name,value:this.model[!0===this.isOutputHex?"hex":"rgb"]}},hasAlpha:function(){return null!==this.forceAlpha?this.forceAlpha:void 0!==this.model.a},currentBgColor:function(){return{backgroundColor:this.model.rgb||"#000"}},headerClass:function(){return"q-color-picker__header-content--"+(void 0!==this.model.a&&this.model.a<65||W(this.model)>.4?"light":"dark")},spectrumStyle:function(){return{background:"hsl("+this.model.h+",100%,50%)"}},spectrumPointerStyle:function(){var t;return(t={top:100-this.model.v+"%"})[!0===this.$q.lang.rtl?"right":"left"]=this.model.s+"%",t},computedPalette:function(){return void 0!==this.palette&&this.palette.length>0?this.palette:jn},classes:function(){return"q-color-picker"+(!0===this.bordered?" q-color-picker--bordered":"")+(!0===this.square?" q-color-picker--square no-border-radius":"")+(!0===this.flat?" q-color-picker--flat no-shadow":"")+(!0===this.disable?" disabled":"")+(!0===this.isDark?" q-color-picker--dark q-dark":"")},attrs:function(){return!0===this.disable?{"aria-disabled":"true"}:!0===this.readonly?{"aria-readonly":"true"}:void 0}},created:function(){this.__spectrumChange=ge(this.__spectrumChange,20)},render:function(t){var e=[this.__getContent(t)];return void 0!==this.name&&!0!==this.disable&&this.__injectFormInput(e,"push"),!0!==this.noHeader&&e.unshift(this.__getHeader(t)),!0!==this.noFooter&&e.push(this.__getFooter(t)),t("div",{class:this.classes,attrs:this.attrs,on:Object.assign({},this.qListeners)},e)},methods:{__getHeader:function(t){var e=this,i=[];return!0!==this.noHeaderTabs&&i.push(t(An,{class:"q-color-picker__header-tabs",props:{value:this.topView,dense:!0,align:"justify"},on:ft(this,"topVTab",{input:function(t){e.topView=t}})},[t(Dn,{props:{label:"HEX"+(!0===this.hasAlpha?"A":""),name:"hex",ripple:!1}}),t(Dn,{props:{label:"RGB"+(!0===this.hasAlpha?"A":""),name:"rgb",ripple:!1}})])),i.push(t("div",{staticClass:"q-color-picker__header-banner row flex-center no-wrap"},[t("input",{staticClass:"fit",domProps:{value:this.model[this.topView]},attrs:!0!==this.editable?{readonly:!0}:null,on:ft(this,"topIn",{input:function(t){e.__updateErrorIcon(!0===e.__onEditorChange(t))},change:b,blur:function(t){!0===e.__onEditorChange(t,!0)&&e.$forceUpdate(),e.__updateErrorIcon(!1)}})}),t(Ut,{ref:"errorIcon",staticClass:"q-color-picker__error-icon absolute no-pointer-events",props:{name:this.$q.iconSet.type.negative}})])),t("div",{staticClass:"q-color-picker__header relative-position overflow-hidden"},[t("div",{staticClass:"q-color-picker__header-bg absolute-full"}),t("div",{staticClass:"q-color-picker__header-content",class:this.headerClass,style:this.currentBgColor},i)])},__getContent:function(t){return t(Rn,{props:{value:this.view,animated:!0}},[t(Fn,{staticClass:"q-color-picker__spectrum-tab overflow-hidden",props:{name:"spectrum"}},this.__getSpectrumTab(t)),t(Fn,{staticClass:"q-pa-md q-color-picker__tune-tab",props:{name:"tune"}},this.__getTuneTab(t)),t(Fn,{staticClass:"q-color-picker__palette-tab",props:{name:"palette"}},this.__getPaletteTab(t))])},__getFooter:function(t){var e=this;return t("div",{staticClass:"q-color-picker__footer relative-position overflow-hidden"},[t(An,{staticClass:"absolute-full",props:{value:this.view,dense:!0,align:"justify"},on:ft(this,"ftIn",{input:function(t){e.view=t}})},[t(Dn,{props:{icon:this.$q.iconSet.colorPicker.spectrum,name:"spectrum",ripple:!1}}),t(Dn,{props:{icon:this.$q.iconSet.colorPicker.tune,name:"tune",ripple:!1}}),t(Dn,{props:{icon:this.$q.iconSet.colorPicker.palette,name:"palette",ripple:!1}})])])},__getSpectrumTab:function(t){var e=this;return[t("div",{ref:"spectrum",staticClass:"q-color-picker__spectrum non-selectable relative-position cursor-pointer",style:this.spectrumStyle,class:{readonly:!0!==this.editable},on:!0===this.editable?ft(this,"spectrT",{click:this.__spectrumClick,mousedown:this.__activate}):null,directives:!0===this.editable?ft(this,"spectrDir",[{name:"touch-pan",modifiers:{prevent:!0,stop:!0,mouse:!0},value:this.__spectrumPan}]):null},[t("div",{style:{paddingBottom:"100%"}}),t("div",{staticClass:"q-color-picker__spectrum-white absolute-full"}),t("div",{staticClass:"q-color-picker__spectrum-black absolute-full"}),t("div",{staticClass:"absolute",style:this.spectrumPointerStyle},[void 0!==this.model.hex?t("div",{staticClass:"q-color-picker__spectrum-circle"}):null])]),t("div",{staticClass:"q-color-picker__sliders"},[t(Mn,{staticClass:"q-color-picker__hue non-selectable",props:{value:this.model.h,min:0,max:360,trackSize:"8px",innerTrackColor:"transparent",selectionColor:"transparent",readonly:!0!==this.editable,thumbPath:"M5 5 h10 v10 h-10 v-10 z"},on:ft(this,"hueSlide",{input:this.__onHueChange,change:function(t){return e.__onHueChange(t,!0)}})}),!0===this.hasAlpha?t(Mn,{staticClass:"q-color-picker__alpha non-selectable",props:{value:this.model.a,min:0,max:100,trackSize:"8px",trackColor:"white",innerTrackColor:"transparent",selectionColor:"transparent",trackImg:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAH0lEQVQoU2NkYGAwZkAFZ5G5jPRRgOYEVDeB3EBjBQBOZwTVugIGyAAAAABJRU5ErkJggg==",readonly:!0!==this.editable,hideSelection:!0,thumbPath:"M5 5 h10 v10 h-10 v-10 z"},on:ft(this,"alphaSlide",{input:function(t){return e.__onNumericChange(t,"a",100)},change:function(t){return e.__onNumericChange(t,"a",100,void 0,!0)}})}):null])]},__getTuneTab:function(t){var e=this,i={inputmode:"numeric",maxlength:3,readonly:!0!==this.editable};return[t("div",{staticClass:"row items-center no-wrap"},[t("div",["R"]),t(Mn,{props:{value:this.model.r,min:0,max:255,color:"red",dark:this.isDark,readonly:!0!==this.editable},on:ft(this,"rSlide",{input:function(t){return e.__onNumericChange(t,"r",255)},change:function(t){return e.__onNumericChange(t,"r",255,void 0,!0)}})}),t("input",{domProps:{value:this.model.r},attrs:i,on:ft(this,"rIn",{input:function(t){return e.__onNumericChange(t.target.value,"r",255,t)},change:b,blur:function(t){return e.__onNumericChange(t.target.value,"r",255,t,!0)}})})]),t("div",{staticClass:"row items-center no-wrap"},[t("div",["G"]),t(Mn,{props:{value:this.model.g,min:0,max:255,color:"green",dark:this.isDark,readonly:!0!==this.editable},on:ft(this,"gSlide",{input:function(t){return e.__onNumericChange(t,"g",255)},change:function(t){return e.__onNumericChange(t,"g",255,void 0,!0)}})}),t("input",{domProps:{value:this.model.g},attrs:i,on:ft(this,"gIn",{input:function(t){return e.__onNumericChange(t.target.value,"g",255,t)},change:b,blur:function(t){return e.__onNumericChange(t.target.value,"g",255,t,!0)}})})]),t("div",{staticClass:"row items-center no-wrap"},[t("div",["B"]),t(Mn,{props:{value:this.model.b,min:0,max:255,color:"blue",readonly:!0!==this.editable,dark:this.isDark},on:ft(this,"bSlide",{input:function(t){return e.__onNumericChange(t,"b",255)},change:function(t){return e.__onNumericChange(t,"b",255,void 0,!0)}})}),t("input",{domProps:{value:this.model.b},attrs:i,on:ft(this,"bIn",{input:function(t){return e.__onNumericChange(t.target.value,"b",255,t)},change:b,blur:function(t){return e.__onNumericChange(t.target.value,"b",255,t,!0)}})})]),!0===this.hasAlpha?t("div",{staticClass:"row items-center no-wrap"},[t("div",["A"]),t(Mn,{props:{value:this.model.a,color:"grey",readonly:!0!==this.editable,dark:this.isDark},on:ft(this,"aSlide",{input:function(t){return e.__onNumericChange(t,"a",100)},change:function(t){return e.__onNumericChange(t,"a",100,void 0,!0)}})}),t("input",{domProps:{value:this.model.a},attrs:i,on:ft(this,"aIn",{input:function(t){return e.__onNumericChange(t.target.value,"a",100,t)},change:b,blur:function(t){return e.__onNumericChange(t.target.value,"a",100,t,!0)}})})]):null]},__getPaletteTab:function(t){var e=this;return[t("div",{staticClass:"row items-center q-color-picker__palette-rows",class:!0===this.editable?"q-color-picker__palette-rows--editable":""},this.computedPalette.map(function(i){return t("div",{staticClass:"q-color-picker__cube col-auto",style:{backgroundColor:i},on:!0===e.editable?ft(e,"palette#"+i,{click:function(){e.__onPalettePick(i)}}):null})}))]},__onSpectrumChange:function(t,e,i){var n=this.$refs.spectrum;if(void 0!==n){var s=n.clientWidth,o=n.clientHeight,r=n.getBoundingClientRect(),a=Math.min(s,Math.max(0,t-r.left));!0===this.$q.lang.rtl&&(a=s-a);var l=Math.min(o,Math.max(0,e-r.top)),c=Math.round(100*a/s),u=Math.round(100*Math.max(0,Math.min(1,-l/o+1))),h=N({h:this.model.h,s:c,v:u,a:!0===this.hasAlpha?this.model.a:void 0});this.model.s=c,this.model.v=u,this.__update(h,i)}},__onHueChange:function(t,e){var i=N({h:t=Math.round(t),s:this.model.s,v:this.model.v,a:!0===this.hasAlpha?this.model.a:void 0});this.model.h=t,this.__update(i,e)},__onNumericChange:function(t,e,i,n,s){if(void 0!==n&&b(n),/^[0-9]+$/.test(t)){var o=Math.floor(Number(t));if(o<0||o>i)!0===s&&this.$forceUpdate();else{var r={r:"r"===e?o:this.model.r,g:"g"===e?o:this.model.g,b:"b"===e?o:this.model.b,a:!0===this.hasAlpha?"a"===e?o:this.model.a:void 0};if("a"!==e){var a=H(r);this.model.h=a.h,this.model.s=a.s,this.model.v=a.v}if(this.__update(r,s),void 0!==n&&!0!==s&&void 0!==n.target.selectionEnd){var l=n.target.selectionEnd;this.$nextTick(function(){n.target.setSelectionRange(l,l)})}}}else!0===s&&this.$forceUpdate()},__onEditorChange:function(t,e){var i,n=t.target.value;if(b(t),"hex"===this.topView){if(n.length!==(!0===this.hasAlpha?9:7)||!/^#[0-9A-Fa-f]+$/.test(n))return!0;i=V(n)}else{var s;if(!n.endsWith(")"))return!0;if(!0!==this.hasAlpha&&n.startsWith("rgb(")){if(3!==(s=n.substring(4,n.length-1).split(",").map(function(t){return parseInt(t,10)})).length||!/^rgb\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)$/.test(n))return!0}else{if(!0!==this.hasAlpha||!n.startsWith("rgba("))return!0;if(4!==(s=n.substring(5,n.length-1).split(",")).length||!/^rgba\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},(0|0\.[0-9]+[1-9]|0\.[1-9]+|1)\)$/.test(n))return!0;for(var o=0;o<3;o++){var r=parseInt(s[o],10);if(r<0||r>255)return!0;s[o]=r}var a=parseFloat(s[3]);if(a<0||a>1)return!0;s[3]=a}if(s[0]<0||s[0]>255||s[1]<0||s[1]>255||s[2]<0||s[2]>255||!0===this.hasAlpha&&(s[3]<0||s[3]>1))return!0;i={r:s[0],g:s[1],b:s[2],a:!0===this.hasAlpha?100*s[3]:void 0}}var l=H(i);if(this.model.h=l.h,this.model.s=l.s,this.model.v=l.v,this.__update(i,e),!0!==e){var c=t.target.selectionEnd;this.$nextTick(function(){t.target.setSelectionRange(c,c)})}},__onPalettePick:function(t){var e=this.__parseModel(t),i={r:e.r,g:e.g,b:e.b,a:e.a};void 0===i.a&&(i.a=this.model.a),this.model.h=e.h,this.model.s=e.s,this.model.v=e.v,this.__update(i,!0)},__update:function(t,e){this.model.hex=F(t),this.model.rgb=j(t),this.model.r=t.r,this.model.g=t.g,this.model.b=t.b,this.model.a=t.a;var i=this.model[!0===this.isOutputHex?"hex":"rgb"];this.$emit("input",i),!0===e&&this.$emit("change",i)},__updateErrorIcon:function(t){void 0!==this.$refs.errorIcon&&(this.$refs.errorIcon.$el.style.opacity=t?1:0)},__parseModel:function(t){var e=void 0!==this.forceAlpha?this.forceAlpha:"auto"===this.formatModel?null:this.formatModel.indexOf("a")>-1;if("string"!=typeof t||0===t.length||!0!==bn.anyColor(t.replace(/ /g,"")))return{h:0,s:0,v:0,r:0,g:0,b:0,a:!0===e?100:void 0,hex:void 0,rgb:void 0};var i=Q(t);return!0===e&&void 0===i.a&&(i.a=100),i.hex=F(i),i.rgb=j(i),Object.assign(i,H(i))},__spectrumPan:function(t){t.isFinal?this.__onSpectrumChange(t.position.left,t.position.top,!0):this.__spectrumChange(t)},__spectrumChange:function(t){this.__onSpectrumChange(t.position.left,t.position.top)},__spectrumClick:function(t){this.__onSpectrumChange(t.pageX-window.pageXOffset,t.pageY-window.pageYOffset,!0)},__activate:function(t){this.__onSpectrumChange(t.pageX-window.pageXOffset,t.pageY-window.pageYOffset)}}}),Nn=[-61,9,38,199,426,686,756,818,1111,1181,1210,1635,2060,2097,2192,2262,2324,2394,2456,3178];function Hn(t,e,i){return"[object Date]"===Object.prototype.toString.call(t)&&(i=t.getDate(),e=t.getMonth()+1,t=t.getFullYear()),function(t){var e,i,n,s=Xn(t).gy,o=s-621,r=Un(o,!1),a=Kn(s,3,r.march);if((n=t-a)>=0){if(n<=185)return i=1+Gn(n,31),e=Zn(n,31)+1,{jy:o,jm:i,jd:e};n-=186}else o-=1,n+=179,1===r.leap&&(n+=1);return i=7+Gn(n,30),e=Zn(n,30)+1,{jy:o,jm:i,jd:e}}(Kn(t,e,i))}function Qn(t,e,i){return Xn(function(t,e,i){var n=Un(t,!0);return Kn(n.gy,3,n.march)+31*(e-1)-Gn(e,7)*(e-7)+i-1}(t,e,i))}function Wn(t){return 0===function(t){var e,i,n,s,o,r=Nn.length,a=Nn[0];if(t<a||t>=Nn[r-1])throw new Error("Invalid Jalaali year "+t);for(o=1;o<r&&(e=Nn[o],i=e-a,!(t<e));o+=1)a=e;i-(s=t-a)<6&&(s=s-i+33*Gn(i+4,33));-1===(n=Zn(Zn(s+1,33)-1,4))&&(n=4);return n}(t)}function Yn(t,e){return e<=6?31:e<=11?30:Wn(t)?30:29}function Un(t,e){var i,n,s,o,r,a=Nn.length,l=t+621,c=-14,u=Nn[0];if(t<u||t>=Nn[a-1])throw new Error("Invalid Jalaali year "+t);for(r=1;r<a&&(n=(i=Nn[r])-u,!(t<i));r+=1)c=c+8*Gn(n,33)+Gn(Zn(n,33),4),u=i;c=c+8*Gn(o=t-u,33)+Gn(Zn(o,33)+3,4),4===Zn(n,33)&&n-o==4&&(c+=1);var h=20+c-(Gn(l,4)-Gn(3*(Gn(l,100)+1),4)-150);return e||(n-o<6&&(o=o-n+33*Gn(n+4,33)),-1===(s=Zn(Zn(o+1,33)-1,4))&&(s=4)),{leap:s,gy:l,march:h}}function Kn(t,e,i){var n=Gn(1461*(t+Gn(e-8,6)+100100),4)+Gn(153*Zn(e+9,12)+2,5)+i-34840408;return n=n-Gn(3*Gn(t+100100+Gn(e-8,6),100),4)+752}function Xn(t){var e=4*t+139361631,i=5*Gn(Zn(e=e+4*Gn(3*Gn(4*t+183187720,146097),4)-3908,1461),4)+308,n=Gn(Zn(i,153),5)+1,s=Zn(Gn(i,153),12)+1;return{gy:Gn(e,1461)-100100+Gn(8-s,6),gm:s,gd:n}}function Gn(t,e){return~~(t/e)}function Zn(t,e){return t-~~(t/e)*e}var Jn=["gregorian","persian"],ts={mixins:[Gt,Li,Lt],props:{value:{required:!0},mask:{type:String},locale:Object,calendar:{type:String,validator:function(t){return Jn.includes(t)},default:"gregorian"},landscape:Boolean,color:String,textColor:String,square:Boolean,flat:Boolean,bordered:Boolean,readonly:Boolean,disable:Boolean},computed:{computedMask:function(){return this.__getMask()},computedLocale:function(){return this.__getLocale()},editable:function(){return!0!==this.disable&&!0!==this.readonly},computedColor:function(){return this.color||"primary"},computedTextColor:function(){return this.textColor||"white"},computedTabindex:function(){return!0===this.editable?0:-1},headerClass:function(){var t=[];return void 0!==this.color&&t.push("bg-"+this.color),void 0!==this.textColor&&t.push("text-"+this.textColor),t.join(" ")}},methods:{__getLocale:function(){return void 0!==this.locale?Object.assign({},this.$q.lang.date,this.locale):this.$q.lang.date},__getCurrentDate:function(t){var e=new Date,i=!0===t?null:0;if("persian"===this.calendar){var n=Hn(e);return{year:n.jy,month:n.jm,day:n.jd}}return{year:e.getFullYear(),month:e.getMonth()+1,day:e.getDate(),hour:i,minute:i,second:i,millisecond:i}},__getCurrentTime:function(){var t=new Date;return{hour:t.getHours(),minute:t.getMinutes(),second:t.getSeconds(),millisecond:t.getMilliseconds()}},__getDayHash:function(t){return t.year+"/"+dt(t.month)+"/"+dt(t.day)}}},es=864e5,is=36e5,ns=6e4,ss="YYYY-MM-DDTHH:mm:ss.SSSZ",os=/\[((?:[^\]\\]|\\]|\\)*)\]|d{1,4}|M{1,4}|m{1,2}|w{1,2}|Qo|Do|D{1,4}|YY(?:YY)?|H{1,2}|h{1,2}|s{1,2}|S{1,3}|Z{1,2}|a{1,2}|[AQExX]/g,rs=/(\[[^\]]*\])|d{1,4}|M{1,4}|m{1,2}|w{1,2}|Qo|Do|D{1,4}|YY(?:YY)?|H{1,2}|h{1,2}|s{1,2}|S{1,3}|Z{1,2}|a{1,2}|[AQExX]|([.*+:?^,\s${}()|\\]+)/g,as={};function ls(t,e){return void 0!==t?t:void 0!==e?e.date:A.date}function cs(t,e){void 0===e&&(e="");var i=t>0?"-":"+",n=Math.abs(t),s=n%60;return i+dt(Math.floor(n/60))+e+dt(s)}function us(t,e,i){var n=hs(e),s=new Date(t),o=void 0!==n.year||void 0!==n.month||void 0!==n.date?function(t,e,i){var n=t.getFullYear(),s=t.getMonth(),o=t.getDate();return void 0!==e.year&&(n+=i*e.year,delete e.year),void 0!==e.month&&(s+=i*e.month,delete e.month),t.setDate(1),t.setMonth(2),t.setFullYear(n),t.setMonth(s),t.setDate(Math.min(o,ys(t))),void 0!==e.date&&(t.setDate(t.getDate()+i*e.date),delete e.date),t}(s,n,i):s;for(var r in n){var a=ct(r);o["set"+a](o["get"+a]()+i*n[r])}return o}function hs(t){var e=Object.assign({},t);return void 0!==t.years&&(e.year=t.years,delete e.years),void 0!==t.months&&(e.month=t.months,delete e.months),void 0!==t.days&&(e.date=t.days,delete e.days),void 0!==t.day&&(e.date=t.day,delete e.day),void 0!==t.hour&&(e.hours=t.hour,delete e.hour),void 0!==t.minute&&(e.minutes=t.minute,delete e.minute),void 0!==t.second&&(e.seconds=t.second,delete e.second),void 0!==t.millisecond&&(e.milliseconds=t.millisecond,delete e.millisecond),e}function ds(t,e,i){var n=hs(e),s=!0===i?"UTC":"",o=new Date(t),r=void 0!==n.year||void 0!==n.month||void 0!==n.date?function(t,e,i){var n=void 0!==e.year?e.year:t["get"+i+"FullYear"](),s=void 0!==e.month?e.month-1:t["get"+i+"Month"](),o=new Date(n,s+1,0).getDate(),r=Math.min(o,void 0!==e.date?e.date:t["get"+i+"Date"]());return t["set"+i+"Date"](1),t["set"+i+"Month"](2),t["set"+i+"FullYear"](n),t["set"+i+"Month"](s),t["set"+i+"Date"](r),delete e.year,delete e.month,delete e.date,t}(o,n,s):o;for(var a in n){r["set"+s+(a.charAt(0).toUpperCase()+a.slice(1))](n[a])}return r}function ps(t,e,i,n,s){var o={year:null,month:null,day:null,hour:null,minute:null,second:null,millisecond:null,timezoneOffset:null,dateHash:null,timeHash:null};if(void 0!==s&&Object.assign(o,s),void 0===t||null===t||""===t||"string"!=typeof t)return o;void 0===e&&(e=ss);var r=ls(i,D.props),a=r.months,l=r.monthsShort,c=function(t,e){var i="("+e.days.join("|")+")",n=t+i;if(void 0!==as[n])return as[n];var s="("+e.daysShort.join("|")+")",o="("+e.months.join("|")+")",r="("+e.monthsShort.join("|")+")",a={},l=0,c=t.replace(rs,function(t){switch(l++,t){case"YY":return a.YY=l,"(-?\\d{1,2})";case"YYYY":return a.YYYY=l,"(-?\\d{1,4})";case"M":return a.M=l,"(\\d{1,2})";case"MM":return a.M=l,"(\\d{2})";case"MMM":return a.MMM=l,r;case"MMMM":return a.MMMM=l,o;case"D":return a.D=l,"(\\d{1,2})";case"Do":return a.D=l++,"(\\d{1,2}(st|nd|rd|th))";case"DD":return a.D=l,"(\\d{2})";case"H":return a.H=l,"(\\d{1,2})";case"HH":return a.H=l,"(\\d{2})";case"h":return a.h=l,"(\\d{1,2})";case"hh":return a.h=l,"(\\d{2})";case"m":return a.m=l,"(\\d{1,2})";case"mm":return a.m=l,"(\\d{2})";case"s":return a.s=l,"(\\d{1,2})";case"ss":return a.s=l,"(\\d{2})";case"S":return a.S=l,"(\\d{1})";case"SS":return a.S=l,"(\\d{2})";case"SSS":return a.S=l,"(\\d{3})";case"A":return a.A=l,"(AM|PM)";case"a":return a.a=l,"(am|pm)";case"aa":return a.aa=l,"(a\\.m\\.|p\\.m\\.)";case"ddd":return s;case"dddd":return i;case"Q":case"d":case"E":return"(\\d{1})";case"Qo":return"(1st|2nd|3rd|4th)";case"DDD":case"DDDD":return"(\\d{1,3})";case"w":return"(\\d{1,2})";case"ww":return"(\\d{2})";case"Z":return a.Z=l,"(Z|[+-]\\d{2}:\\d{2})";case"ZZ":return a.ZZ=l,"(Z|[+-]\\d{2}\\d{2})";case"X":return a.X=l,"(-?\\d+)";case"x":return a.x=l,"(-?\\d{4,})";default:return l--,"["===t[0]&&(t=t.substring(1,t.length-1)),t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}}),u={map:a,regex:new RegExp("^"+c)};return as[n]=u,u}(e,r),u=c.regex,h=c.map,d=t.match(u);if(null===d)return o;var p="";if(void 0!==h.X||void 0!==h.x){var f=parseInt(d[void 0!==h.X?h.X:h.x],10);if(!0===isNaN(f)||f<0)return o;var m=new Date(f*(void 0!==h.X?1e3:1));o.year=m.getFullYear(),o.month=m.getMonth()+1,o.day=m.getDate(),o.hour=m.getHours(),o.minute=m.getMinutes(),o.second=m.getSeconds(),o.millisecond=m.getMilliseconds()}else{if(void 0!==h.YYYY)o.year=parseInt(d[h.YYYY],10);else if(void 0!==h.YY){var v=parseInt(d[h.YY],10);o.year=v<0?v:2e3+v}if(void 0!==h.M){if(o.month=parseInt(d[h.M],10),o.month<1||o.month>12)return o}else void 0!==h.MMM?o.month=l.indexOf(d[h.MMM])+1:void 0!==h.MMMM&&(o.month=a.indexOf(d[h.MMMM])+1);if(void 0!==h.D){if(o.day=parseInt(d[h.D],10),null===o.year||null===o.month||o.day<1)return o;var g="persian"!==n?new Date(o.year,o.month,0).getDate():Yn(o.year,o.month);if(o.day>g)return o}void 0!==h.H?o.hour=parseInt(d[h.H],10)%24:void 0!==h.h&&(o.hour=parseInt(d[h.h],10)%12,(h.A&&"PM"===d[h.A]||h.a&&"pm"===d[h.a]||h.aa&&"p.m."===d[h.aa])&&(o.hour+=12),o.hour=o.hour%24),void 0!==h.m&&(o.minute=parseInt(d[h.m],10)%60),void 0!==h.s&&(o.second=parseInt(d[h.s],10)%60),void 0!==h.S&&(o.millisecond=parseInt(d[h.S],10)*Math.pow(10,3-d[h.S].length)),void 0===h.Z&&void 0===h.ZZ||(p=void 0!==h.Z?d[h.Z].replace(":",""):d[h.ZZ],o.timezoneOffset=("+"===p[0]?-1:1)*(60*p.slice(1,3)+1*p.slice(3,5)))}return o.dateHash=dt(o.year,6)+"/"+dt(o.month)+"/"+dt(o.day),o.timeHash=dt(o.hour)+":"+dt(o.minute)+":"+dt(o.second)+p,o}function fs(t){var e=new Date(t.getFullYear(),t.getMonth(),t.getDate());e.setDate(e.getDate()-(e.getDay()+6)%7+3);var i=new Date(e.getFullYear(),0,4);i.setDate(i.getDate()-(i.getDay()+6)%7+3);var n=e.getTimezoneOffset()-i.getTimezoneOffset();e.setHours(e.getHours()-n);var s=(e-i)/(7*es);return 1+Math.floor(s)}function ms(t,e){var i=new Date(t);return!0===e?function(t){return 1e4*t.getFullYear()+100*t.getMonth()+t.getDate()}(i):i.getTime()}function vs(t,e,i){var n=new Date(t),s="set"+(!0===i?"UTC":"");switch(e){case"year":case"years":n[s+"Month"](0);case"month":case"months":n[s+"Date"](1);case"day":case"days":case"date":n[s+"Hours"](0);case"hour":case"hours":n[s+"Minutes"](0);case"minute":case"minutes":n[s+"Seconds"](0);case"second":case"seconds":n[s+"Milliseconds"](0)}return n}function gs(t,e,i){return(t.getTime()-t.getTimezoneOffset()*ns-(e.getTime()-e.getTimezoneOffset()*ns))/i}function _s(t,e,i){void 0===i&&(i="days");var n=new Date(t),s=new Date(e);switch(i){case"years":case"year":return n.getFullYear()-s.getFullYear();case"months":case"month":return 12*(n.getFullYear()-s.getFullYear())+n.getMonth()-s.getMonth();case"days":case"day":case"date":return gs(vs(n,"day"),vs(s,"day"),es);case"hours":case"hour":return gs(vs(n,"hour"),vs(s,"hour"),is);case"minutes":case"minute":return gs(vs(n,"minute"),vs(s,"minute"),ns);case"seconds":case"second":return gs(vs(n,"second"),vs(s,"second"),1e3)}}function bs(t){return _s(t,vs(t,"year"),"days")+1}function ys(t){return new Date(t.getFullYear(),t.getMonth()+1,0).getDate()}function Ss(t){if(t>=11&&t<=13)return t+"th";switch(t%10){case 1:return t+"st";case 2:return t+"nd";case 3:return t+"rd"}return t+"th"}var ws={YY:function(t,e,i){var n=this.YYYY(t,e,i)%100;return n>=0?dt(n):"-"+dt(Math.abs(n))},YYYY:function(t,e,i){return void 0!==i&&null!==i?i:t.getFullYear()},M:function(t){return t.getMonth()+1},MM:function(t){return dt(t.getMonth()+1)},MMM:function(t,e){return e.monthsShort[t.getMonth()]},MMMM:function(t,e){return e.months[t.getMonth()]},Q:function(t){return Math.ceil((t.getMonth()+1)/3)},Qo:function(t){return Ss(this.Q(t))},D:function(t){return t.getDate()},Do:function(t){return Ss(t.getDate())},DD:function(t){return dt(t.getDate())},DDD:function(t){return bs(t)},DDDD:function(t){return dt(bs(t),3)},d:function(t){return t.getDay()},dd:function(t,e){return this.dddd(t,e).slice(0,2)},ddd:function(t,e){return e.daysShort[t.getDay()]},dddd:function(t,e){return e.days[t.getDay()]},E:function(t){return t.getDay()||7},w:function(t){return fs(t)},ww:function(t){return dt(fs(t))},H:function(t){return t.getHours()},HH:function(t){return dt(t.getHours())},h:function(t){var e=t.getHours();return 0===e?12:e>12?e%12:e},hh:function(t){return dt(this.h(t))},m:function(t){return t.getMinutes()},mm:function(t){return dt(t.getMinutes())},s:function(t){return t.getSeconds()},ss:function(t){return dt(t.getSeconds())},S:function(t){return Math.floor(t.getMilliseconds()/100)},SS:function(t){return dt(Math.floor(t.getMilliseconds()/10))},SSS:function(t){return dt(t.getMilliseconds(),3)},A:function(t){return this.H(t)<12?"AM":"PM"},a:function(t){return this.H(t)<12?"am":"pm"},aa:function(t){return this.H(t)<12?"a.m.":"p.m."},Z:function(t,e,i,n){return cs(void 0===n||null===n?t.getTimezoneOffset():n,":")},ZZ:function(t,e,i,n){return cs(void 0===n||null===n?t.getTimezoneOffset():n)},X:function(t){return Math.floor(t.getTime()/1e3)},x:function(t){return t.getTime()}};function Cs(t,e,i,n,s){if((0===t||t)&&t!==1/0&&t!==-1/0){var o=new Date(t);if(!isNaN(o)){void 0===e&&(e=ss);var r=ls(i,D.props);return e.replace(os,function(t,e){return t in ws?ws[t](o,r,n,s):void 0===e?t:e.split("\\]").join("]")})}}}var xs,ks,qs,Ts,Ms,$s,Ls={isValid:function(t){return"number"==typeof t||!1===isNaN(Date.parse(t))},extractDate:function(t,e,i){var n=ps(t,e,i),s=new Date(n.year,null===n.month?null:n.month-1,null===n.day?1:n.day,n.hour,n.minute,n.second,n.millisecond),o=s.getTimezoneOffset();return null===n.timezoneOffset||n.timezoneOffset===o?s:us(s,{minutes:n.timezoneOffset-o},1)},buildDate:function(t,e){return ds(new Date,t,e)},getDayOfWeek:function(t){var e=new Date(t).getDay();return 0===e?7:e},getWeekOfYear:fs,isBetweenDates:function(t,e,i,n){void 0===n&&(n={});var s=ms(e,n.onlyDate),o=ms(i,n.onlyDate),r=ms(t,n.onlyDate);return(r>s||!0===n.inclusiveFrom&&r===s)&&(r<o||!0===n.inclusiveTo&&r===o)},addToDate:function(t,e){return us(t,e,1)},subtractFromDate:function(t,e){return us(t,e,-1)},adjustDate:ds,startOfDate:vs,endOfDate:function(t,e,i){var n=new Date(t),s="set"+(!0===i?"UTC":"");switch(e){case"year":case"years":n[s+"Month"](11);case"month":case"months":n[s+"Date"](ys(n));case"day":case"days":case"date":n[s+"Hours"](23);case"hour":case"hours":n[s+"Minutes"](59);case"minute":case"minutes":n[s+"Seconds"](59);case"second":case"seconds":n[s+"Milliseconds"](999)}return n},getMaxDate:function(t){var e=new Date(t);return Array.prototype.slice.call(arguments,1).forEach(function(t){e=Math.max(e,new Date(t))}),e},getMinDate:function(t){var e=new Date(t);return Array.prototype.slice.call(arguments,1).forEach(function(t){e=Math.min(e,new Date(t))}),e},getDateDiff:_s,getDayOfYear:bs,inferDateFormat:function(t){return!0===Ji(t)?"date":"number"==typeof t?"number":"string"},getDateBetween:function(t,e,i){var n=new Date(t);if(e){var s=new Date(e);if(n<s)return s}if(i){var o=new Date(i);if(n>o)return o}return n},isSameDate:function(t,e,i){var n=new Date(t),s=new Date(e);if(void 0===i)return n.getTime()===s.getTime();switch(i){case"second":case"seconds":if(n.getSeconds()!==s.getSeconds())return!1;case"minute":case"minutes":if(n.getMinutes()!==s.getMinutes())return!1;case"hour":case"hours":if(n.getHours()!==s.getHours())return!1;case"day":case"days":case"date":if(n.getDate()!==s.getDate())return!1;case"month":case"months":if(n.getMonth()!==s.getMonth())return!1;case"year":case"years":if(n.getFullYear()!==s.getFullYear())return!1;break;default:throw new Error("date isSameDate unknown unit "+i)}return!0},daysInMonth:ys,formatDate:Cs,clone:function(t){return!0===Ji(t)?new Date(t.getTime()):t}},Os=["Calendar","Years","Months"],Bs=function(t){return Os.includes(t)},Es=function(t){return/^-?[\d]+\/[0-1]\d$/.test(t)},zs=t.extend({name:"QDate",mixins:[ts],props:{multiple:Boolean,range:Boolean,title:String,subtitle:String,mask:{default:"YYYY/MM/DD"},defaultYearMonth:{type:String,validator:Es},yearsInMonthView:Boolean,events:[Array,Function],eventColor:[String,Function],emitImmediately:Boolean,options:[Array,Function],navigationMinYearMonth:{type:String,validator:Es},navigationMaxYearMonth:{type:String,validator:Es},noUnset:Boolean,firstDayOfWeek:[String,Number],todayBtn:Boolean,minimal:Boolean,defaultView:{type:String,default:"Calendar",validator:Bs}},data:function(){var t=this.__getMask(),e=this.__getLocale(),i=this.__getViewModel(t,e),n=i.year,s=!0===this.$q.lang.rtl?"right":"left";return{view:this.defaultView,monthDirection:s,yearDirection:s,startYear:n-n%20-(n<0?20:0),editRange:void 0,innerMask:t,innerLocale:e,viewModel:i}},watch:{value:function(t){if(this.lastEmitValue===t)this.lastEmitValue=0;else{var e=this.__getViewModel(this.innerMask,this.innerLocale),i=e.year,n=e.month;this.__updateViewModel(i,n)}},view:function(){void 0!==this.$refs.blurTarget&&this.$refs.blurTarget.focus()},"viewModel.year":function(t){this.$emit("navigation",{year:t,month:this.viewModel.month})},"viewModel.month":function(t){this.$emit("navigation",{year:this.viewModel.year,month:t})},computedMask:function(t){this.__updateValue(t,this.innerLocale,"mask"),this.innerMask=t},computedLocale:function(t){this.__updateValue(this.innerMask,t,"locale"),this.innerLocale=t}},computed:{classes:function(){var t=!0===this.landscape?"landscape":"portrait";return"q-date q-date--"+t+" q-date--"+t+"-"+(!0===this.minimal?"minimal":"standard")+(!0===this.isDark?" q-date--dark q-dark":"")+(!0===this.bordered?" q-date--bordered":"")+(!0===this.square?" q-date--square no-border-radius":"")+(!0===this.flat?" q-date--flat no-shadow":"")+(!0===this.disable?" disabled":!0===this.readonly?" q-date--readonly":"")},isImmediate:function(){return!0===this.emitImmediately&&!0!==this.multiple&&!0!==this.range},normalizedModel:function(){return!0===Array.isArray(this.value)?this.value:null!==this.value&&void 0!==this.value?[this.value]:[]},daysModel:function(){var t=this;return this.normalizedModel.filter(function(t){return"string"==typeof t}).map(function(e){return t.__decodeString(e,t.innerMask,t.innerLocale)}).filter(function(t){return null!==t.dateHash&&null!==t.day&&null!==t.month&&null!==t.year})},rangeModel:function(){var t=this,e=function(e){return t.__decodeString(e,t.innerMask,t.innerLocale)};return this.normalizedModel.filter(function(t){return!0===Zi(t)&&void 0!==t.from&&void 0!==t.to}).map(function(t){return{from:e(t.from),to:e(t.to)}}).filter(function(t){return null!==t.from.dateHash&&null!==t.to.dateHash&&t.from.dateHash<t.to.dateHash})},getNativeDateFn:function(){return"persian"!==this.calendar?function(t){return new Date(t.year,t.month-1,t.day)}:function(t){var e=Qn(t.year,t.month,t.day);return new Date(e.gy,e.gm-1,e.gd)}},encodeObjectFn:function(){var t=this;return"persian"===this.calendar?this.__getDayHash:function(e,i,n){return Cs(new Date(e.year,e.month-1,e.day,e.hour,e.minute,e.second,e.millisecond),void 0===i?t.innerMask:i,void 0===n?t.innerLocale:n,e.year,e.timezoneOffset)}},daysInModel:function(){var t=this;return this.daysModel.length+this.rangeModel.reduce(function(e,i){return e+1+_s(t.getNativeDateFn(i.to),t.getNativeDateFn(i.from))},0)},headerTitle:function(){if(void 0!==this.title&&null!==this.title&&this.title.length>0)return this.title;if(void 0!==this.editRange){var t=this.editRange.init,e=this.getNativeDateFn(t);return this.innerLocale.daysShort[e.getDay()]+", "+this.innerLocale.monthsShort[t.month-1]+" "+t.day+" — ?"}if(0===this.daysInModel)return" — ";if(this.daysInModel>1)return this.daysInModel+" "+this.innerLocale.pluralDay;var i=this.daysModel[0],n=this.getNativeDateFn(i);return!0===isNaN(n.valueOf())?" — ":void 0!==this.innerLocale.headerTitle?this.innerLocale.headerTitle(n,i):this.innerLocale.daysShort[n.getDay()]+", "+this.innerLocale.monthsShort[i.month-1]+" "+i.day},headerSubtitle:function(){if(void 0!==this.subtitle&&null!==this.subtitle&&this.subtitle.length>0)return this.subtitle;if(0===this.daysInModel)return" — ";if(this.daysInModel>1){var t=this.minSelectedModel,e=this.maxSelectedModel,i=this.innerLocale.monthsShort;return i[t.month-1]+(t.year!==e.year?" "+t.year+" — "+i[e.month-1]+" ":t.month!==e.month?" — "+i[e.month-1]:"")+" "+e.year}return this.daysModel[0].year},minSelectedModel:function(){return this.daysModel.concat(this.rangeModel.map(function(t){return t.from})).sort(function(t,e){return t.year-e.year||t.month-e.month})[0]},maxSelectedModel:function(){return this.daysModel.concat(this.rangeModel.map(function(t){return t.to})).sort(function(t,e){return e.year-t.year||e.month-t.month})[0]},dateArrow:function(){var t=[this.$q.iconSet.datetime.arrowLeft,this.$q.iconSet.datetime.arrowRight];return!0===this.$q.lang.rtl?t.reverse():t},computedFirstDayOfWeek:function(){return void 0!==this.firstDayOfWeek?Number(this.firstDayOfWeek):this.innerLocale.firstDayOfWeek},daysOfWeek:function(){var t=this.innerLocale.daysShort,e=this.computedFirstDayOfWeek;return e>0?t.slice(e,7).concat(t.slice(0,e)):t},daysInMonth:function(){var t=this.viewModel;return"persian"!==this.calendar?new Date(t.year,t.month,0).getDate():Yn(t.year,t.month)},today:function(){return this.__getCurrentDate()},evtColor:function(){var t=this;return"function"==typeof this.eventColor?this.eventColor:function(){return t.eventColor}},minNav:function(){if(void 0!==this.navigationMinYearMonth){var t=this.navigationMinYearMonth.split("/");return{year:parseInt(t[0],10),month:parseInt(t[1],10)}}},maxNav:function(){if(void 0!==this.navigationMaxYearMonth){var t=this.navigationMaxYearMonth.split("/");return{year:parseInt(t[0],10),month:parseInt(t[1],10)}}},navBoundaries:function(){var t={month:{prev:!0,next:!0},year:{prev:!0,next:!0}};return void 0!==this.minNav&&this.minNav.year>=this.viewModel.year&&(t.year.prev=!1,this.minNav.year===this.viewModel.year&&this.minNav.month>=this.viewModel.month&&(t.month.prev=!1)),void 0!==this.maxNav&&this.maxNav.year<=this.viewModel.year&&(t.year.next=!1,this.maxNav.year===this.viewModel.year&&this.maxNav.month<=this.viewModel.month&&(t.month.next=!1)),t},daysMap:function(){var t=this,e={};return this.daysModel.forEach(function(i){var n=t.__getMonthHash(i);void 0===e[n]&&(e[n]=[]),e[n].push(i.day)}),e},rangeMap:function(){var t=this,e={};return this.rangeModel.forEach(function(i){var n=t.__getMonthHash(i.from),s=t.__getMonthHash(i.to);if(void 0===e[n]&&(e[n]=[]),e[n].push({from:i.from.day,to:n===s?i.to.day:void 0,range:i}),n<s)for(var o,r=i.from,a=r.year,l=r.month,c=l<12?{year:a,month:l+1}:{year:a+1,month:1};(o=t.__getMonthHash(c))<=s;)void 0===e[o]&&(e[o]=[]),e[o].push({from:void 0,to:o===s?i.to.day:void 0,range:i}),c.month++,c.month>12&&(c.year++,c.month=1)}),e},rangeView:function(){if(void 0!==this.editRange){var t=this.editRange,e=t.init,i=t.initHash,n=t.final,s=i<=t.finalHash?[e,n]:[n,e],o=s[0],r=s[1],a=this.__getMonthHash(o),l=this.__getMonthHash(r);if(a===this.viewMonthHash||l===this.viewMonthHash){var c={};return a===this.viewMonthHash?(c.from=o.day,c.includeFrom=!0):c.from=1,l===this.viewMonthHash?(c.to=r.day,c.includeTo=!0):c.to=this.daysInMonth,c}}},viewMonthHash:function(){return this.__getMonthHash(this.viewModel)},selectionDaysMap:function(){var t=this,e={};if(void 0===this.options){for(var i=1;i<=this.daysInMonth;i++)e[i]=!0;return e}for(var n="function"==typeof this.options?this.options:function(e){return t.options.includes(e)},s=1;s<=this.daysInMonth;s++){var o=this.viewMonthHash+"/"+dt(s);e[s]=n(o)}return e},eventDaysMap:function(){var t=this,e={};if(void 0===this.events)for(var i=1;i<=this.daysInMonth;i++)e[i]=!1;else for(var n="function"==typeof this.events?this.events:function(e){return t.events.includes(e)},s=1;s<=this.daysInMonth;s++){var o=this.viewMonthHash+"/"+dt(s);e[s]=!0===n(o)&&this.evtColor(o)}return e},viewDays:function(){var t,e,i=this.viewModel,n=i.year,s=i.month;if("persian"!==this.calendar)t=new Date(n,s-1,1),e=new Date(n,s-1,0).getDate();else{var o=Qn(n,s,1);t=new Date(o.gy,o.gm-1,o.gd);var r=s-1,a=n;0===r&&(r=12,a--),e=Yn(a,r)}return{days:t.getDay()-this.computedFirstDayOfWeek-1,endDay:e}},days:function(){var t=this,e=[],i=this.viewDays,n=i.days,s=i.endDay,o=n<0?n+7:n;if(o<6)for(var r=s-o;r<=s;r++)e.push({i:r,fill:!0});for(var a=e.length,l=1;l<=this.daysInMonth;l++){var c={i:l,event:this.eventDaysMap[l],classes:[]};!0===this.selectionDaysMap[l]&&(c.in=!0,c.flat=!0),e.push(c)}if(void 0!==this.daysMap[this.viewMonthHash]&&this.daysMap[this.viewMonthHash].forEach(function(i){var n=a+i-1;Object.assign(e[n],{selected:!0,unelevated:!0,flat:!1,color:t.computedColor,textColor:t.computedTextColor})}),void 0!==this.rangeMap[this.viewMonthHash]&&this.rangeMap[this.viewMonthHash].forEach(function(i){if(void 0!==i.from){for(var n=a+i.from-1,s=a+(i.to||t.daysInMonth)-1,o=n;o<=s;o++)Object.assign(e[o],{range:i.range,unelevated:!0,color:t.computedColor,textColor:t.computedTextColor});Object.assign(e[n],{rangeFrom:!0,flat:!1}),void 0!==i.to&&Object.assign(e[s],{rangeTo:!0,flat:!1})}else if(void 0!==i.to){for(var r=a+i.to-1,l=a;l<=r;l++)Object.assign(e[l],{range:i.range,unelevated:!0,color:t.computedColor,textColor:t.computedTextColor});Object.assign(e[r],{flat:!1,rangeTo:!0})}else for(var c=a+t.daysInMonth-1,u=a;u<=c;u++)Object.assign(e[u],{range:i.range,unelevated:!0,color:t.computedColor,textColor:t.computedTextColor})}),void 0!==this.rangeView){for(var u=a+this.rangeView.from-1,h=a+this.rangeView.to-1,d=u;d<=h;d++)e[d].color=this.computedColor,e[d].editRange=!0;!0===this.rangeView.includeFrom&&(e[u].editRangeFrom=!0),!0===this.rangeView.includeTo&&(e[h].editRangeTo=!0)}this.viewModel.year===this.today.year&&this.viewModel.month===this.today.month&&(e[a+this.today.day-1].today=!0);var p=e.length%7;if(p>0)for(var f=7-p,m=1;m<=f;m++)e.push({i:m,fill:!0});return e.forEach(function(t){var e="q-date__calendar-item ";!0===t.fill?e+="q-date__calendar-item--fill":(e+="q-date__calendar-item--"+(!0===t.in?"in":"out"),void 0!==t.range&&(e+=" q-date__range"+(!0===t.rangeTo?"-to":!0===t.rangeFrom?"-from":"")),!0===t.editRange&&(e+=" q-date__edit-range"+(!0===t.editRangeFrom?"-from":"")+(!0===t.editRangeTo?"-to":"")),void 0===t.range&&!0!==t.editRange||(e+=" text-"+t.color)),t.classes=e}),e},attrs:function(){return!0===this.disable?{"aria-disabled":"true"}:!0===this.readonly?{"aria-readonly":"true"}:void 0}},methods:{setToday:function(){var t=this.today,e=this.daysMap[this.__getMonthHash(t)];void 0!==e&&!1!==e.includes(t.day)||this.__addToModel(t),this.setCalendarTo(this.today.year,this.today.month)},setView:function(t){!0===Bs(t)&&(this.view=t)},offsetCalendar:function(t,e){["month","year"].includes(t)&&this["__goTo"+("month"===t?"Month":"Year")](!0===e?-1:1)},setCalendarTo:function(t,e){this.view="Calendar",this.__updateViewModel(t,e)},setEditingRange:function(t,e){if(!1!==this.range&&t){var i=Object.assign(Object.assign({},this.viewModel),t),n=void 0!==e?Object.assign(Object.assign({},this.viewModel),e):i;this.editRange={init:i,initHash:this.__getDayHash(i),final:n,finalHash:this.__getDayHash(n)},this.setCalendarTo(i.year,i.month)}else this.editRange=void 0},__getMask:function(){return"persian"===this.calendar?"YYYY/MM/DD":this.mask},__decodeString:function(t,e,i){return ps(t,e,i,this.calendar,{hour:0,minute:0,second:0,millisecond:0})},__getViewModel:function(t,e){var i=!0===Array.isArray(this.value)?this.value:this.value?[this.value]:[];if(0===i.length)return this.__getDefaultViewModel();var n=this.__decodeString(void 0!==i[0].from?i[0].from:i[0],t,e);return null===n.dateHash?this.__getDefaultViewModel():n},__getDefaultViewModel:function(){var t,e;if(void 0!==this.defaultYearMonth){var i=this.defaultYearMonth.split("/");t=parseInt(i[0],10),e=parseInt(i[1],10)}else{var n=void 0!==this.today?this.today:this.__getCurrentDate();t=n.year,e=n.month}return{year:t,month:e,day:1,hour:0,minute:0,second:0,millisecond:0,dateHash:t+"/"+dt(e)+"/01"}},__getHeader:function(t){var e=this;if(!0!==this.minimal)return t("div",{staticClass:"q-date__header",class:this.headerClass},[t("div",{staticClass:"relative-position"},[t("transition",{props:{name:"q-transition--fade"}},[t("div",{key:"h-yr-"+this.headerSubtitle,staticClass:"q-date__header-subtitle q-date__header-link",class:"Years"===this.view?"q-date__header-link--active":"cursor-pointer",attrs:{tabindex:this.computedTabindex},on:ft(this,"vY",{click:function(){e.view="Years"},keyup:function(t){13===t.keyCode&&(e.view="Years")}})},[this.headerSubtitle])])]),t("div",{staticClass:"q-date__header-title relative-position flex no-wrap"},[t("div",{staticClass:"relative-position col"},[t("transition",{props:{name:"q-transition--fade"}},[t("div",{key:"h-sub"+this.headerTitle,staticClass:"q-date__header-title-label q-date__header-link",class:"Calendar"===this.view?"q-date__header-link--active":"cursor-pointer",attrs:{tabindex:this.computedTabindex},on:ft(this,"vC",{click:function(){e.view="Calendar"},keyup:function(t){13===t.keyCode&&(e.view="Calendar")}})},[this.headerTitle])])]),!0===this.todayBtn?t(Be,{staticClass:"q-date__header-today self-start",props:{icon:this.$q.iconSet.datetime.today,flat:!0,size:"sm",round:!0,tabindex:this.computedTabindex},on:ft(this,"today",{click:this.setToday})}):null])])},__getNavigation:function(t,e){var i=this,n=e.label,s=e.view,o=e.key,r=e.dir,a=e.goTo,l=e.boundaries,c=e.cls;return[t("div",{staticClass:"row items-center q-date__arrow"},[t(Be,{props:{round:!0,dense:!0,size:"sm",flat:!0,icon:this.dateArrow[0],tabindex:this.computedTabindex,disable:!1===l.prev},on:ft(this,"go-#"+s,{click:function(){a(-1)}})})]),t("div",{staticClass:"relative-position overflow-hidden flex flex-center"+c},[t("transition",{props:{name:"q-transition--jump-"+r}},[t("div",{key:o},[t(Be,{props:{flat:!0,dense:!0,noCaps:!0,label:n,tabindex:this.computedTabindex},on:ft(this,"view#"+s,{click:function(){i.view=s}})})])])]),t("div",{staticClass:"row items-center q-date__arrow"},[t(Be,{props:{round:!0,dense:!0,size:"sm",flat:!0,icon:this.dateArrow[1],tabindex:this.computedTabindex,disable:!1===l.next},on:ft(this,"go+#"+s,{click:function(){a(1)}})})])]},__getCalendarView:function(t){var e=this;return[t("div",{key:"calendar-view",staticClass:"q-date__view q-date__calendar"},[t("div",{staticClass:"q-date__navigation row items-center no-wrap"},this.__getNavigation(t,{label:this.innerLocale.months[this.viewModel.month-1],view:"Months",key:this.viewModel.month,dir:this.monthDirection,goTo:this.__goToMonth,boundaries:this.navBoundaries.month,cls:" col"}).concat(this.__getNavigation(t,{label:this.viewModel.year,view:"Years",key:this.viewModel.year,dir:this.yearDirection,goTo:this.__goToYear,boundaries:this.navBoundaries.year,cls:""}))),t("div",{staticClass:"q-date__calendar-weekdays row items-center no-wrap"},this.daysOfWeek.map(function(e){return t("div",{staticClass:"q-date__calendar-item"},[t("div",[e])])})),t("div",{staticClass:"q-date__calendar-days-container relative-position overflow-hidden"},[t("transition",{props:{name:"q-transition--slide-"+this.monthDirection}},[t("div",{key:this.viewMonthHash,staticClass:"q-date__calendar-days fit"},this.days.map(function(i){return t("div",{staticClass:i.classes},[!0===i.in?t(Be,{staticClass:!0===i.today?"q-date__today":null,props:{dense:!0,flat:i.flat,unelevated:i.unelevated,color:i.color,textColor:i.textColor,label:i.i,tabindex:e.computedTabindex},on:ft(e,"day#"+i.i,{click:function(){e.__onDayClick(i.i)},mouseover:function(){e.__onDayMouseover(i.i)}})},!1!==i.event?[t("div",{staticClass:"q-date__event bg-"+i.event})]:null):t("div",[i.i])])}))])])])]},__getMonthsView:function(t){var e=this,i=this.viewModel.year===this.today.year,n=this.innerLocale.monthsShort.map(function(n,s){var o=e.viewModel.month===s+1;return t("div",{staticClass:"q-date__months-item flex flex-center"},[t(Be,{staticClass:!0===i&&e.today.month===s+1?"q-date__today":null,props:{flat:!0!==o,label:n,unelevated:o,color:!0===o?e.computedColor:null,textColor:!0===o?e.computedTextColor:null,tabindex:e.computedTabindex,disable:function(t){return void 0!==e.minNav&&e.viewModel.year===e.minNav.year&&e.minNav.month>t||void 0!==e.maxNav&&e.viewModel.year===e.maxNav.year&&e.maxNav.month<t}(s+1)},on:ft(e,"month#"+s,{click:function(){e.__setMonth(s+1)}})})])});return!0===this.yearsInMonthView&&n.unshift(t("div",{staticClass:"row no-wrap full-width"},[this.__getNavigation(t,{label:this.viewModel.year,view:"Years",key:this.viewModel.year,dir:this.yearDirection,goTo:this.__goToYear,boundaries:this.navBoundaries.year,cls:" col"})])),t("div",{key:"months-view",staticClass:"q-date__view q-date__months flex flex-center"},n)},__getYearsView:function(t){for(var e=this,i=this.startYear,n=i+20,s=[],o=function(t){return void 0!==e.minNav&&e.minNav.year>t||void 0!==e.maxNav&&e.maxNav.year<t},r=function(i){var n=e.viewModel.year===i;s.push(t("div",{staticClass:"q-date__years-item flex flex-center"},[t(Be,{key:"yr"+i,staticClass:e.today.year===i?"q-date__today":null,props:{flat:!n,label:i,dense:!0,unelevated:n,color:!0===n?e.computedColor:null,textColor:!0===n?e.computedTextColor:null,tabindex:e.computedTabindex,disable:o(i)},on:ft(e,"yr#"+i,{click:function(){e.__setYear(i)}})})]))},a=i;a<=n;a++)r(a);return t("div",{staticClass:"q-date__view q-date__years flex flex-center"},[t("div",{staticClass:"col-auto"},[t(Be,{props:{round:!0,dense:!0,flat:!0,icon:this.dateArrow[0],tabindex:this.computedTabindex,disable:o(i)},on:ft(this,"y-",{click:function(){e.startYear-=20}})})]),t("div",{staticClass:"q-date__years-content col self-stretch row items-center"},s),t("div",{staticClass:"col-auto"},[t(Be,{props:{round:!0,dense:!0,flat:!0,icon:this.dateArrow[1],tabindex:this.computedTabindex,disable:o(n)},on:ft(this,"y+",{click:function(){e.startYear+=20}})})])])},__goToMonth:function(t){var e=this.viewModel.year,i=Number(this.viewModel.month)+t;13===i?(i=1,e++):0===i&&(i=12,e--),this.__updateViewModel(e,i),!0===this.isImmediate&&this.__emitImmediately("month")},__goToYear:function(t){var e=Number(this.viewModel.year)+t;this.__updateViewModel(e,this.viewModel.month),!0===this.isImmediate&&this.__emitImmediately("year")},__setYear:function(t){this.__updateViewModel(t,this.viewModel.month),this.view="Years"===this.defaultView?"Months":"Calendar",!0===this.isImmediate&&this.__emitImmediately("year")},__setMonth:function(t){this.__updateViewModel(this.viewModel.year,t),this.view="Calendar",!0===this.isImmediate&&this.__emitImmediately("month")},__getMonthHash:function(t){return t.year+"/"+dt(t.month)},__toggleDate:function(t,e){var i=this.daysMap[e];(void 0!==i&&!0===i.includes(t.day)?this.__removeFromModel:this.__addToModel)(t)},__getShortDate:function(t){return{year:t.year,month:t.month,day:t.day}},__onDayClick:function(t){var e=Object.assign({},this.viewModel,{day:t});if(!1!==this.range)if(void 0===this.editRange){var i=this.days.find(function(e){return!0!==e.fill&&e.i===t});if(void 0!==i.range)return void this.__removeFromModel({target:e,from:i.range.from,to:i.range.to});if(!0===i.selected)return void this.__removeFromModel(e);var n=this.__getDayHash(e);this.editRange={init:e,initHash:n,final:e,finalHash:n},this.$emit("range-start",this.__getShortDate(e))}else{var s=this.editRange.initHash,o=this.__getDayHash(e),r=s<=o?{from:this.editRange.init,to:e}:{from:e,to:this.editRange.init};this.editRange=void 0,this.__addToModel(s===o?e:Object.assign({},{target:e},r)),this.$emit("range-end",{from:this.__getShortDate(r.from),to:this.__getShortDate(r.to)})}else this.__toggleDate(e,this.viewMonthHash)},__onDayMouseover:function(t){if(void 0!==this.editRange){var e=Object.assign({},this.viewModel,{day:t});Object.assign(this.editRange,{final:e,finalHash:this.__getDayHash(e)})}},__updateViewModel:function(t,e){var i=this;void 0!==this.minNav&&t<=this.minNav.year&&(t=this.minNav.year,e<this.minNav.month&&(e=this.minNav.month)),void 0!==this.maxNav&&t>=this.maxNav.year&&(t=this.maxNav.year,e>this.maxNav.month&&(e=this.maxNav.month));var n=t+"/"+dt(e)+"/01";n!==this.viewModel.dateHash&&(this.monthDirection=this.viewModel.dateHash<n==(!0!==this.$q.lang.rtl)?"left":"right",t!==this.viewModel.year&&(this.yearDirection=this.monthDirection),this.$nextTick(function(){i.startYear=t-t%20-(t<0?20:0),Object.assign(i.viewModel,{year:t,month:e,day:1,dateHash:n})}))},__emitValue:function(t,e,i){var n=null!==t&&1===t.length&&!1===this.multiple?t[0]:t;this.lastEmitValue=n;var s=this.__getEmitParams(e,i),o=s.reason,r=s.details;this.$emit("input",n,o,r)},__emitImmediately:function(t){var e=this,i=void 0!==this.daysModel[0]&&null!==this.daysModel[0].dateHash?Object.assign({},this.daysModel[0]):Object.assign({},this.viewModel);this.$nextTick(function(){i.year=e.viewModel.year,i.month=e.viewModel.month;var n="persian"!==e.calendar?new Date(i.year,i.month,0).getDate():Yn(i.year,i.month);i.day=Math.min(Math.max(1,i.day),n);var s=e.__encodeEntry(i);e.lastEmitValue=s;var o=e.__getEmitParams("",i).details;e.$emit("input",s,t,o)})},__getEmitParams:function(t,e){return void 0!==e.from?{reason:t+"-range",details:Object.assign({},this.__getShortDate(e.target),{from:this.__getShortDate(e.from),to:this.__getShortDate(e.to),changed:!0})}:{reason:t+"-day",details:Object.assign({},this.__getShortDate(e),{changed:!0})}},__encodeEntry:function(t,e,i){return void 0!==t.from?{from:this.encodeObjectFn(t.from,e,i),to:this.encodeObjectFn(t.to,e,i)}:this.encodeObjectFn(t,e,i)},__addToModel:function(t){var e,i=this;if(!0===this.multiple)if(void 0!==t.from){var n=this.__getDayHash(t.from),s=this.__getDayHash(t.to),o=this.daysModel.filter(function(t){return t.dateHash<n||t.dateHash>s}),r=this.rangeModel.filter(function(t){var e=t.from;return t.to.dateHash<n||e.dateHash>s});e=o.concat(r).concat(t).map(function(t){return i.__encodeEntry(t)})}else{var a=this.normalizedModel.slice();a.push(this.__encodeEntry(t)),e=a}else e=this.__encodeEntry(t);this.__emitValue(e,"add",t)},__removeFromModel:function(t){if(!0!==this.noUnset){var e=null;if(!0===this.multiple&&!0===Array.isArray(this.value)){var i=this.__encodeEntry(t);0===(e=void 0!==t.from?this.value.filter(function(t){return void 0===t.from||t.from!==i.from&&t.to!==i.to}):this.value.filter(function(t){return t!==i})).length&&(e=null)}this.__emitValue(e,"remove",t)}},__updateValue:function(t,e,i){var n=this,s=this.daysModel.concat(this.rangeModel).map(function(i){return n.__encodeEntry(i,t,e)}).filter(function(t){return void 0!==t.from?null!==t.from.dateHash&&null!==t.to.dateHash:null!==t.dateHash});this.$emit("input",(!0===this.multiple?s:s[0])||null,i)}},render:function(t){var e=[t("div",{staticClass:"q-date__content col relative-position"},[t("transition",{props:{name:"q-transition--fade"}},[this["__get"+this.view+"View"](t)])])],i=Ot(this,"default");return void 0!==i&&e.push(t("div",{staticClass:"q-date__actions"},i)),void 0!==this.name&&!0!==this.disable&&this.__injectFormInput(e,"push"),t("div",{class:this.classes,attrs:this.attrs,on:Object.assign({},this.qListeners)},[this.__getHeader(t),t("div",{staticClass:"q-date__main col column",attrs:{tabindex:-1},ref:"blurTarget"},e)])}}),Ps={methods:{__addHistory:function(){var t=this;this.__historyEntry={condition:function(){return!0===t.hideOnRouteChange},handler:this.hide},P.add(this.__historyEntry)},__removeHistory:function(){void 0!==this.__historyEntry&&(P.remove(this.__historyEntry),this.__historyEntry=void 0)}},beforeDestroy:function(){!0===this.showing&&this.__removeHistory()}},As=0,Is=!1;function Ds(t){(function(t){if(t.target===document.body||t.target.classList.contains("q-layout__backdrop"))return!0;for(var e=v(t),i=t.shiftKey&&!t.deltaX,n=!i&&Math.abs(t.deltaX)<=Math.abs(t.deltaY),s=i||n?t.deltaY:t.deltaX,o=0;o<e.length;o++){var r=e[o];if(vi(r,n))return n?s<0&&0===r.scrollTop||s>0&&r.scrollTop+r.clientHeight===r.scrollHeight:s<0&&0===r.scrollLeft||s>0&&r.scrollLeft+r.clientWidth===r.scrollWidth}return!0})(t)&&S(t)}function Rs(t){t.target===document&&(document.scrollingElement.scrollTop=document.scrollingElement.scrollTop)}function Fs(t){!0!==Is&&(Is=!0,requestAnimationFrame(function(){Is=!1;var e=t.target.height,i=document.scrollingElement,n=i.clientHeight,s=i.scrollTop;void 0!==qs&&e===window.innerHeight||(qs=n-e,document.scrollingElement.scrollTop=s),s>qs&&(document.scrollingElement.scrollTop-=Math.ceil((s-qs)/8))}))}function js(t){var e=document.body,i=void 0!==window.visualViewport;if("add"===t){var n=window.getComputedStyle(e).overflowY;xs=ri(window),ks=oi(window),Ts=e.style.left,Ms=e.style.top,e.style.left="-"+xs+"px",e.style.top="-"+ks+"px","hidden"!==n&&("scroll"===n||e.scrollHeight>window.innerHeight)&&e.classList.add("q-body--force-scrollbar"),e.classList.add("q-body--prevent-scroll"),document.qScrollPrevented=!0,!0===c.is.ios&&(!0===i?(window.scrollTo(0,0),window.visualViewport.addEventListener("resize",Fs,h.passiveCapture),window.visualViewport.addEventListener("scroll",Fs,h.passiveCapture),window.scrollTo(0,0)):window.addEventListener("scroll",Rs,h.passiveCapture))}!0===c.is.desktop&&!0===c.is.mac&&window[t+"EventListener"]("wheel",Ds,h.notPassive),"remove"===t&&(!0===c.is.ios&&(!0===i?(window.visualViewport.removeEventListener("resize",Fs,h.passiveCapture),window.visualViewport.removeEventListener("scroll",Fs,h.passiveCapture)):window.removeEventListener("scroll",Rs,h.passiveCapture)),e.classList.remove("q-body--prevent-scroll"),e.classList.remove("q-body--force-scrollbar"),document.qScrollPrevented=!1,e.style.left=Ts,e.style.top=Ms,window.scrollTo(xs,ks),qs=void 0)}function Vs(t){var e="add";if(!0===t){if(As++,void 0!==$s)return clearTimeout($s),void($s=void 0);if(As>1)return}else{if(0===As)return;if(--As>0)return;if(e="remove",!0===c.is.ios&&!0===c.is.nativeMobile)return clearTimeout($s),void($s=setTimeout(function(){js(e),$s=void 0},100))}js(e)}var Ns={methods:{__preventScroll:function(t){t===this.preventedScroll||void 0===this.preventedScroll&&!0!==t||(this.preventedScroll=t,Vs(t))}}},Hs=0,Qs={standard:"fixed-full flex-center",top:"fixed-top justify-center",bottom:"fixed-bottom justify-center",right:"fixed-right items-center",left:"fixed-left items-center"},Ws={standard:["scale","scale"],top:["slide-down","slide-up"],bottom:["slide-up","slide-down"],right:["slide-left","slide-right"],left:["slide-right","slide-left"]},Ys=t.extend({name:"QDialog",mixins:[bt,Ps,Ie,He,Ns],props:{persistent:Boolean,autoClose:Boolean,noEscDismiss:Boolean,noBackdropDismiss:Boolean,noRouteDismiss:Boolean,noRefocus:Boolean,noFocus:Boolean,noShake:Boolean,seamless:Boolean,maximized:Boolean,fullWidth:Boolean,fullHeight:Boolean,square:Boolean,position:{type:String,default:"standard",validator:function(t){return"standard"===t||["top","bottom","left","right"].includes(t)}},transitionShow:String,transitionHide:String},data:function(){return{transitionState:this.showing,animating:!1}},watch:{showing:function(t){var e=this;this.transitionShowComputed!==this.transitionHideComputed&&this.$nextTick(function(){e.transitionState=t})},maximized:function(t){!0===this.showing&&this.__updateMaximized(t)},useBackdrop:function(t){this.__preventScroll(t),this.__preventFocusout(t)}},computed:{classes:function(){return"q-dialog__inner--"+(!0===this.maximized?"maximized":"minimized")+" q-dialog__inner--"+this.position+" "+Qs[this.position]+(!0===this.animating?" q-dialog__inner--animating":"")+(!0===this.fullWidth?" q-dialog__inner--fullwidth":"")+(!0===this.fullHeight?" q-dialog__inner--fullheight":"")+(!0===this.square?" q-dialog__inner--square":"")},transitionShowComputed:function(){return"q-transition--"+(void 0===this.transitionShow?Ws[this.position][0]:this.transitionShow)},transitionHideComputed:function(){return"q-transition--"+(void 0===this.transitionHide?Ws[this.position][1]:this.transitionHide)},transition:function(){return!0===this.transitionState?this.transitionHideComputed:this.transitionShowComputed},useBackdrop:function(){return!0===this.showing&&!0!==this.seamless},hideOnRouteChange:function(){return!0!==this.persistent&&!0!==this.noRouteDismiss&&!0!==this.seamless},onEvents:function(){var t=Object.assign({},this.qListeners,{input:b,"popup-show":b,"popup-hide":b});return!0===this.autoClose&&(t.click=this.__onAutoClose),t}},methods:{focus:function(t){var e=this;Ve(function(){var i=e.__getInnerNode();void 0!==i&&!0!==i.contains(document.activeElement)&&(i=i.querySelector(t||"[autofocus], [data-autofocus]")||i).focus({preventScroll:!0})})},shake:function(){this.focus(),this.$emit("shake");var t=this.__getInnerNode();void 0!==t&&(t.classList.remove("q-animate--scale"),t.classList.add("q-animate--scale"),clearTimeout(this.shakeTimeout),this.shakeTimeout=setTimeout(function(){t.classList.remove("q-animate--scale")},170))},__getInnerNode:function(){return void 0!==this.__portal&&void 0!==this.__portal.$refs?this.__portal.$refs.inner:void 0},__show:function(t){var e=this;this.__addHistory(),this.__refocusTarget=!0!==c.is.mobile&&!1===this.noRefocus&&null!==document.activeElement?document.activeElement:void 0,this.$el.dispatchEvent(C("popup-show",{bubbles:!0})),this.__updateMaximized(this.maximized),wi.register(this,function(){!0!==e.seamless&&(!0===e.persistent||!0===e.noEscDismiss?!0!==e.maximized&&!0!==e.noShake&&e.shake():(e.$emit("escape-key"),e.hide()))}),this.__showPortal(),this.animating=!0,!0!==this.noFocus&&(null!==document.activeElement&&document.activeElement.blur(),this.__nextTick(this.focus)),this.__setTimeout(function(){if(!0===e.$q.platform.is.ios){if(!0!==e.seamless&&document.activeElement){var i=document.activeElement.getBoundingClientRect(),n=i.top,s=i.bottom,o=window.innerHeight,r=void 0!==window.visualViewport?window.visualViewport.height:o;n>0&&s>r/2&&(document.scrollingElement.scrollTop=Math.min(document.scrollingElement.scrollHeight-r,s>=o?1/0:Math.ceil(document.scrollingElement.scrollTop+s-r/2))),document.activeElement.scrollIntoView()}e.__portal.$el.click()}e.animating=!1,e.__showPortal(!0),e.$emit("show",t)},300)},__hide:function(t){var e=this;this.__removeHistory(),this.__cleanup(!0),this.__hidePortal(),this.animating=!0,void 0!==this.__refocusTarget&&null!==this.__refocusTarget&&(this.__refocusTarget.focus(t),this.__refocusTarget=void 0),this.$el.dispatchEvent(C("popup-hide",{bubbles:!0})),this.__setTimeout(function(){e.__hidePortal(!0),e.animating=!1,e.$emit("hide",t)},300)},__cleanup:function(t){clearTimeout(this.shakeTimeout),!0!==t&&!0!==this.showing||(wi.pop(this),this.__updateMaximized(!1),!0!==this.seamless&&(this.__preventScroll(!1),this.__preventFocusout(!1)))},__updateMaximized:function(t){!0===t?!0!==this.isMaximized&&(Hs<1&&document.body.classList.add("q-body--dialog"),Hs++,this.isMaximized=!0):!0===this.isMaximized&&(Hs<2&&document.body.classList.remove("q-body--dialog"),Hs--,this.isMaximized=!1)},__preventFocusout:function(t){if(!0===this.$q.platform.is.desktop){var e=(!0===t?"add":"remove")+"EventListener";document.body[e]("focusin",this.__onFocusChange)}},__onAutoClose:function(t){this.hide(t),void 0!==this.qListeners.click&&this.$emit("click",t)},__onBackdropClick:function(t){!0!==this.persistent&&!0!==this.noBackdropDismiss?this.hide(t):!0!==this.noShake&&this.shake()},__onFocusChange:function(t){!0===this.__portalIsAccessible&&!0!==function(t,e){if(void 0===t||!0===t.contains(e))return!0;for(var i=t.nextElementSibling;null!==i;i=i.nextElementSibling)if(i.contains(e))return!0;return!1}(this.__portal.$el,t.target)&&this.focus('[tabindex]:not([tabindex="-1"])')},__renderPortal:function(t){return t("div",{staticClass:"q-dialog fullscreen no-pointer-events q-dialog--"+(!0===this.useBackdrop?"modal":"seamless"),class:this.contentClass,style:this.contentStyle,attrs:this.qAttrs},[t("transition",{props:{name:"q-transition--fade"}},!0===this.useBackdrop?[t("div",{staticClass:"q-dialog__backdrop fixed-full",attrs:gt,on:ft(this,"bkdrop",{click:this.__onBackdropClick})})]:null),t("transition",{props:{name:this.transition}},[!0===this.showing?t("div",{ref:"inner",staticClass:"q-dialog__inner flex no-pointer-events",class:this.classes,attrs:{tabindex:-1},on:this.onEvents},Ot(this,"default")):null])])}},mounted:function(){this.__processModelChange(this.value)},beforeDestroy:function(){this.__cleanup(),this.__refocusTarget=void 0}}),Us=["mouseover","mouseout","mouseenter","mouseleave"],Ks=t.extend({name:"QDrawer",inject:{layout:{default:function(){console.error("QDrawer needs to be child of QLayout")}}},mixins:[Gt,Ps,Ie,Ns],directives:{TouchPan:xn},props:{side:{type:String,default:"left",validator:function(t){return["left","right"].includes(t)}},width:{type:Number,default:300},mini:Boolean,miniToOverlay:Boolean,miniWidth:{type:Number,default:57},breakpoint:{type:Number,default:1023},showIfAbove:Boolean,behavior:{type:String,validator:function(t){return["default","desktop","mobile"].includes(t)},default:"default"},bordered:Boolean,elevated:Boolean,contentStyle:[String,Object,Array],contentClass:[String,Object,Array],overlay:Boolean,persistent:Boolean,noSwipeOpen:Boolean,noSwipeClose:Boolean,noSwipeBackdrop:Boolean},data:function(){var t="mobile"===this.behavior||"desktop"!==this.behavior&&this.layout.totalWidth<=this.breakpoint;return{belowBreakpoint:t,showing:!0===this.showIfAbove&&!1===t||!0===this.value}},watch:{belowBreakpoint:function(t){!0===t?(this.lastDesktopState=this.showing,!0===this.showing&&this.hide(!1)):!1===this.overlay&&"mobile"!==this.behavior&&!1!==this.lastDesktopState&&(!0===this.showing?(this.__applyPosition(0),this.__applyBackdrop(0),this.__cleanup()):this.show(!1))},"layout.totalWidth":function(){!0!==this.layout.container&&!0===document.qScrollPrevented||this.__updateBelowBreakpoint()},side:function(t,e){this.layout.instances[e]===this&&(this.layout.instances[e]=void 0,this.layout[e].space=!1,this.layout[e].offset=0),this.layout.instances[t]=this,this.layout[t].size=this.size,this.layout[t].space=this.onLayout,this.layout[t].offset=this.offset},behavior:function(){this.__updateBelowBreakpoint()},breakpoint:function(){this.__updateBelowBreakpoint()},"layout.container":function(t){!0===this.showing&&this.__preventScroll(!0!==t),!0===t&&this.__updateBelowBreakpoint()},"layout.scrollbarWidth":function(){this.__applyPosition(!0===this.showing?0:void 0)},offset:function(t){this.__update("offset",t)},onLayout:function(t){this.$emit("on-layout",t),this.__update("space",t)},rightSide:function(){this.__applyPosition()},size:function(t){this.__applyPosition(),this.__updateSizeOnLayout(this.miniToOverlay,t)},miniToOverlay:function(t){this.__updateSizeOnLayout(t,this.size)},"$q.lang.rtl":function(){this.__applyPosition()},mini:function(){!0===this.value&&(this.__animateMini(),this.layout.__animate())},isMini:function(t){this.$emit("mini-state",t)}},computed:{rightSide:function(){return"right"===this.side},otherSide:function(){return!0===this.rightSide?"left":"right"},offset:function(){return!0===this.showing&&!1===this.belowBreakpoint&&!1===this.overlay?!0===this.miniToOverlay?this.miniWidth:this.size:0},size:function(){return!0===this.isMini?this.miniWidth:this.width},fixed:function(){return!0===this.overlay||!0===this.miniToOverlay||this.layout.view.indexOf(this.rightSide?"R":"L")>-1||this.$q.platform.is.ios&&!0===this.layout.container},onLayout:function(){return!0===this.showing&&!1===this.belowBreakpoint&&!1===this.overlay},onScreenOverlay:function(){return!0===this.showing&&!1===this.belowBreakpoint&&!0===this.overlay},backdropClass:function(){return!1===this.showing?"hidden":null},headerSlot:function(){return!0===this.rightSide?"r"===this.layout.rows.top[2]:"l"===this.layout.rows.top[0]},footerSlot:function(){return!0===this.rightSide?"r"===this.layout.rows.bottom[2]:"l"===this.layout.rows.bottom[0]},aboveStyle:function(){var t={};return!0===this.layout.header.space&&!1===this.headerSlot&&(!0===this.fixed?t.top=this.layout.header.offset+"px":!0===this.layout.header.space&&(t.top=this.layout.header.size+"px")),!0===this.layout.footer.space&&!1===this.footerSlot&&(!0===this.fixed?t.bottom=this.layout.footer.offset+"px":!0===this.layout.footer.space&&(t.bottom=this.layout.footer.size+"px")),t},style:function(){var t={width:this.size+"px"};return!0===this.belowBreakpoint?t:Object.assign(t,this.aboveStyle)},classes:function(){return"q-drawer--"+this.side+(!0===this.bordered?" q-drawer--bordered":"")+(!0===this.isDark?" q-drawer--dark q-dark":"")+(!0!==this.showing?" q-layout--prevent-focus":"")+(!0===this.belowBreakpoint?" fixed q-drawer--on-top q-drawer--mobile q-drawer--top-padding":" q-drawer--"+(!0===this.isMini?"mini":"standard")+(!0===this.fixed||!0!==this.onLayout?" fixed":"")+(!0===this.overlay||!0===this.miniToOverlay?" q-drawer--on-top":"")+(!0===this.headerSlot?" q-drawer--top-padding":""))},stateDirection:function(){return(!0===this.$q.lang.rtl?-1:1)*(!0===this.rightSide?1:-1)},isMini:function(){return!0===this.mini&&!0!==this.belowBreakpoint},onNativeEvents:function(){var t=this;if(!0!==this.belowBreakpoint){var e={"!click":function(e){t.$emit("click",e)}};return Us.forEach(function(i){e[i]=function(e){void 0!==t.qListeners[i]&&t.$emit(i,e)}}),e}},hideOnRouteChange:function(){return!0!==this.persistent&&(!0===this.belowBreakpoint||!0===this.onScreenOverlay)},openDirective:function(){var t,e=!0===this.$q.lang.rtl?this.side:this.otherSide;return[{name:"touch-pan",value:this.__openByTouch,modifiers:(t={},t[e]=!0,t.mouse=!0,t)}]},contentCloseDirective:function(){var t;if(!0!==this.noSwipeClose){var e=!0===this.$q.lang.rtl?this.otherSide:this.side;return[{name:"touch-pan",value:this.__closeByTouch,modifiers:(t={},t[e]=!0,t.mouse=!0,t)}]}},backdropCloseDirective:function(){var t;if(!0!==this.noSwipeBackdrop){var e=!0===this.$q.lang.rtl?this.otherSide:this.side;return[{name:"touch-pan",value:this.__closeByTouch,modifiers:(t={},t[e]=!0,t.mouse=!0,t.mouseAllDir=!0,t)}]}}},methods:{__applyPosition:function(t){var e=this;void 0===t?this.$nextTick(function(){t=!0===e.showing?0:e.size,e.__applyPosition(e.stateDirection*t)}):void 0!==this.$refs.content&&(!0!==this.layout.container||!0!==this.rightSide||!0!==this.belowBreakpoint&&Math.abs(t)!==this.size||(t+=this.stateDirection*this.layout.scrollbarWidth),this.__lastPosition!==t&&(this.$refs.content.style.transform="translateX("+t+"px)",this.__lastPosition=t))},__applyBackdrop:function(t,e){var i=this;void 0!==this.$refs.backdrop?this.$refs.backdrop.style.backgroundColor=this.lastBackdropBg="rgba(0,0,0,"+.4*t+")":!0!==e&&this.$nextTick(function(){i.__applyBackdrop(t,!0)})},__setBackdropVisible:function(t){void 0!==this.$refs.backdrop&&this.$refs.backdrop.classList[!0===t?"remove":"add"]("hidden")},__setScrollable:function(t){var e=!0===t?"remove":!0!==this.layout.container?"add":"";""!==e&&document.body.classList[e]("q-body--drawer-toggle")},__animateMini:function(){var t=this;void 0!==this.timerMini?clearTimeout(this.timerMini):void 0!==this.$el&&this.$el.classList.add("q-drawer--mini-animate"),this.timerMini=setTimeout(function(){void 0!==t.$el&&t.$el.classList.remove("q-drawer--mini-animate"),t.timerMini=void 0},150)},__openByTouch:function(t){if(!1===this.showing){var e=this.size,i=ut(t.distance.x,0,e);if(!0===t.isFinal){var n=this.$refs.content,s=i>=Math.min(75,e);return n.classList.remove("no-transition"),void(!0===s?this.show():(this.layout.__animate(),this.__applyBackdrop(0),this.__applyPosition(this.stateDirection*e),n.classList.remove("q-drawer--delimiter"),n.classList.add("q-layout--prevent-focus"),this.__setBackdropVisible(!1)))}if(this.__applyPosition((!0===this.$q.lang.rtl?!0!==this.rightSide:this.rightSide)?Math.max(e-i,0):Math.min(0,i-e)),this.__applyBackdrop(ut(i/e,0,1)),!0===t.isFirst){var o=this.$refs.content;o.classList.add("no-transition"),o.classList.add("q-drawer--delimiter"),o.classList.remove("q-layout--prevent-focus"),this.__setBackdropVisible(!0)}}},__closeByTouch:function(t){if(!0===this.showing){var e=this.size,i=t.direction===this.side,n=(!0===this.$q.lang.rtl?!0!==i:i)?ut(t.distance.x,0,e):0;if(!0===t.isFinal){var s=Math.abs(n)<Math.min(75,e);return this.$refs.content.classList.remove("no-transition"),void(!0===s?(this.layout.__animate(),this.__applyBackdrop(1),this.__applyPosition(0)):this.hide())}this.__applyPosition(this.stateDirection*n),this.__applyBackdrop(ut(1-n/e,0,1)),!0===t.isFirst&&this.$refs.content.classList.add("no-transition")}},__show:function(t,e){var i=this;if(this.__addHistory(),this.__setBackdropVisible(!0),!1!==t&&this.layout.__animate(),this.__applyPosition(0),!0===this.belowBreakpoint){var n=this.layout.instances[this.otherSide];void 0!==n&&!0===n.belowBreakpoint&&n.hide(!1),this.__applyBackdrop(1),!0!==this.layout.container&&this.__preventScroll(!0)}else this.__applyBackdrop(0),!1!==t&&this.__setScrollable(!1);this.__setTimeout(function(){!1!==t&&i.__setScrollable(!0),!0!==e&&i.$emit("show",t)},150)},__hide:function(t,e){var i=this;this.__removeHistory(),!1!==t&&this.layout.__animate(),this.__applyBackdrop(0),this.__applyPosition(this.stateDirection*this.size),this.__setBackdropVisible(!1),this.__cleanup(),!0!==e&&this.__setTimeout(function(){i.$emit("hide",t)},150)},__cleanup:function(){this.__preventScroll(!1),this.__setScrollable(!0)},__update:function(t,e){this.layout[this.side][t]!==e&&(this.layout[this.side][t]=e)},__updateLocal:function(t,e){this[t]!==e&&(this[t]=e)},__updateSizeOnLayout:function(t,e){this.__update("size",!0===t?this.miniWidth:e)},__updateBelowBreakpoint:function(){this.__updateLocal("belowBreakpoint","mobile"===this.behavior||"desktop"!==this.behavior&&this.layout.totalWidth<=this.breakpoint)}},created:function(){this.layout.instances[this.side]=this,this.__updateSizeOnLayout(this.miniToOverlay,this.size),this.__update("space",this.onLayout),this.__update("offset",this.offset),!0===this.showIfAbove&&!0!==this.value&&!0===this.showing&&void 0!==this.qListeners.input&&this.$emit("input",!0)},mounted:function(){var t=this;this.$emit("on-layout",this.onLayout),this.$emit("mini-state",this.isMini),this.lastDesktopState=!0===this.showIfAbove;var e=function(){var e=!0===t.showing?"show":"hide";t["__"+e](!1,!0)};0===this.layout.totalWidth?this.watcher=this.$watch("layout.totalWidth",function(){t.watcher(),t.watcher=void 0,!1===t.showing&&!0===t.showIfAbove&&!1===t.belowBreakpoint?t.show(!1):e()}):this.$nextTick(e)},beforeDestroy:function(){void 0!==this.watcher&&this.watcher(),clearTimeout(this.timerMini),!0===this.showing&&this.__cleanup(),this.layout.instances[this.side]===this&&(this.layout.instances[this.side]=void 0,this.__update("size",0),this.__update("offset",0),this.__update("space",!1))},render:function(t){var e=[];!0===this.belowBreakpoint&&(!0!==this.noSwipeOpen&&e.push(t("div",{staticClass:"q-drawer__opener fixed-"+this.side,attrs:gt,directives:this.openDirective})),e.push(t("div",{ref:"backdrop",staticClass:"fullscreen q-drawer__backdrop",class:this.backdropClass,attrs:gt,style:void 0!==this.lastBackdropBg?{backgroundColor:this.lastBackdropBg}:null,on:ft(this,"bkdrop",{click:this.hide}),directives:!1===this.showing?void 0:this.backdropCloseDirective})));var i=[t("div",{staticClass:"q-drawer__content fit "+(!0===this.layout.container?"overflow-auto":"scroll"),class:this.contentClass,style:this.contentStyle},!0===this.isMini&&void 0!==this.$scopedSlots.mini?this.$scopedSlots.mini():Ot(this,"default"))];return!0===this.elevated&&!0===this.showing&&i.push(t("div",{staticClass:"q-layout__shadow absolute-full overflow-hidden no-pointer-events"})),e.push(t("aside",{ref:"content",staticClass:"q-drawer",class:this.classes,style:this.style,on:this.onNativeEvents,directives:!0===this.belowBreakpoint?this.contentCloseDirective:void 0},i)),t("div",{staticClass:"q-drawer-container"},e)}}),Xs=t.extend({name:"QTooltip",mixins:[Pe,Ie,He,We],props:{maxHeight:{type:String,default:null},maxWidth:{type:String,default:null},transitionShow:{default:"jump-down"},transitionHide:{default:"jump-up"},anchor:{type:String,default:"bottom middle",validator:Ci},self:{type:String,default:"top middle",validator:Ci},offset:{type:Array,default:function(){return[14,14]},validator:xi},scrollTarget:{default:void 0},delay:{type:Number,default:0},hideDelay:{type:Number,default:0}},computed:{anchorOrigin:function(){return qi(this.anchor,this.$q.lang.rtl)},selfOrigin:function(){return qi(this.self,this.$q.lang.rtl)},hideOnRouteChange:function(){return!0!==this.persistent}},methods:{__show:function(t){var e=this;this.__showPortal(),this.__nextTick(function(){e.observer=new MutationObserver(function(){return e.updatePosition()}),e.observer.observe(e.__portal.$el,{attributes:!1,childList:!0,characterData:!0,subtree:!0}),e.updatePosition(),e.__configureScrollTarget()}),void 0===this.unwatch&&(this.unwatch=this.$watch(function(){return e.$q.screen.width+"|"+e.$q.screen.height+"|"+e.self+"|"+e.anchor+"|"+e.$q.lang.rtl},this.updatePosition)),this.__setTimeout(function(){e.__showPortal(!0),e.$emit("show",t)},300)},__hide:function(t){var e=this;this.__anchorCleanup(),this.__hidePortal(),this.__setTimeout(function(){e.__hidePortal(!0),e.$emit("hide",t)},300)},__anchorCleanup:function(){void 0!==this.observer&&(this.observer.disconnect(),this.observer=void 0),void 0!==this.unwatch&&(this.unwatch(),this.unwatch=void 0),this.__unconfigureScrollTarget(),k(this,"tooltipTemp")},updatePosition:function(){if(void 0!==this.anchorEl&&void 0!==this.__portal){var t=this.__portal.$el;8!==t.nodeType?Ti({el:t,offset:this.offset,anchorEl:this.anchorEl,anchorOrigin:this.anchorOrigin,selfOrigin:this.selfOrigin,maxHeight:this.maxHeight,maxWidth:this.maxWidth}):setTimeout(this.updatePosition,25)}},__delayShow:function(t){var e=this;if(!0===this.$q.platform.is.mobile){ze(),document.body.classList.add("non-selectable");var i=this.anchorEl;x(this,"tooltipTemp",["touchmove","touchcancel","touchend","click"].map(function(t){return[i,t,"__delayHide","passiveCapture"]}))}this.__setTimeout(function(){e.show(t)},this.delay)},__delayHide:function(t){var e=this;this.__clearTimeout(),!0===this.$q.platform.is.mobile&&(k(this,"tooltipTemp"),ze(),setTimeout(function(){document.body.classList.remove("non-selectable")},10)),this.__setTimeout(function(){e.hide(t)},this.hideDelay)},__configureAnchorEl:function(){!0!==this.noParentEvent&&void 0!==this.anchorEl&&x(this,"anchor",!0===this.$q.platform.is.mobile?[[this.anchorEl,"touchstart","__delayShow","passive"]]:[[this.anchorEl,"mouseenter","__delayShow","passive"],[this.anchorEl,"mouseleave","__delayHide","passive"]])},__unconfigureScrollTarget:function(){void 0!==this.__scrollTarget&&(this.__changeScrollEvent(this.__scrollTarget),this.__scrollTarget=void 0)},__configureScrollTarget:function(){if(void 0!==this.anchorEl||void 0!==this.scrollTarget){this.__scrollTarget=ii(this.anchorEl,this.scrollTarget);var t=!0===this.noParentEvent?this.updatePosition:this.hide;this.__changeScrollEvent(this.__scrollTarget,t)}},__renderPortal:function(t){return t("transition",{props:{name:this.transition}},[!0===this.showing?t("div",{staticClass:"q-tooltip q-tooltip--style q-position-engine no-pointer-events",class:this.contentClass,style:this.contentStyle,attrs:{role:"complementary"}},Ot(this,"default")):null])}},mounted:function(){this.__processModelChange(this.value)}}),Gs=t.extend({name:"QList",mixins:[Lt,Gt],props:{bordered:Boolean,dense:Boolean,separator:Boolean,padding:Boolean},computed:{classes:function(){return"q-list"+(!0===this.bordered?" q-list--bordered":"")+(!0===this.dense?" q-list--dense":"")+(!0===this.separator?" q-list--separator":"")+(!0===this.isDark?" q-list--dark":"")+(!0===this.padding?" q-list--padding":"")}},render:function(t){return t("div",{class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),Zs=t.extend({name:"QItem",mixins:[Gt,ae,$t,Lt],props:{active:Boolean,clickable:Boolean,dense:Boolean,insetLevel:Number,tabindex:[String,Number],focused:Boolean,manualFocus:Boolean},computed:{isActionable:function(){return!0===this.clickable||!0===this.hasLink||"label"===this.tag},isClickable:function(){return!0!==this.disable&&!0===this.isActionable},classes:function(){var t;return(t={"q-item--clickable q-link cursor-pointer":this.isClickable,"q-focusable q-hoverable":!0===this.isClickable&&!1===this.manualFocus,"q-manual-focusable":!0===this.isClickable&&!0===this.manualFocus,"q-manual-focusable--focused":!0===this.isClickable&&!0===this.focused,"q-item--dense":this.dense,"q-item--dark":this.isDark,"q-item--active":this.active})[this.activeClass]=!0===this.active&&!0!==this.hasRouterLink&&void 0!==this.activeClass,t.disabled=this.disable,t},style:function(){var t;if(void 0!==this.insetLevel)return(t={})["padding"+(!0===this.$q.lang.rtl?"Right":"Left")]=16+56*this.insetLevel+"px",t},onEvents:function(){return Object.assign({},this.qListeners,{click:this.__onClick,keyup:this.__onKeyup})}},methods:{__getContent:function(t){var e=Bt(this,"default",[]);return!0===this.isClickable&&e.unshift(t("div",{staticClass:"q-focus-helper",attrs:{tabindex:-1},ref:"blurTarget"})),e},__onClick:function(t){!0===this.isClickable&&(void 0!==this.$refs.blurTarget&&(!0!==t.qKeyEvent&&document.activeElement===this.$el?this.$refs.blurTarget.focus():document.activeElement===this.$refs.blurTarget&&this.$el.focus()),this.$emit("click",t))},__onKeyup:function(t){if(!0===this.isClickable&&!0===J(t,13)){S(t),t.qKeyEvent=!0;var e=new MouseEvent("click",t);e.qKeyEvent=!0,this.$el.dispatchEvent(e)}this.$emit("keyup",t)}},render:function(t){var e={staticClass:"q-item q-item-type row no-wrap",class:this.classes,style:this.style,attrs:{}};return e[!0===this.hasRouterLink?"nativeOn":"on"]=this.onEvents,!0===this.isClickable?e.attrs.tabindex=this.tabindex||"0":!0===this.isActionable&&(e.attrs["aria-disabled"]="true"),!0===this.hasLink&&(e.props=this.linkProps.props,Object.assign(e.attrs,this.linkProps.attrs)),t(this.linkTag,e,this.__getContent(t))}}),Js=t.extend({name:"QItemSection",mixins:[Lt],props:{avatar:Boolean,thumbnail:Boolean,side:Boolean,top:Boolean,noWrap:Boolean},computed:{classes:function(){var t,e=this.avatar||this.side||this.thumbnail;return(t={"q-item__section--top":this.top,"q-item__section--avatar":this.avatar,"q-item__section--thumbnail":this.thumbnail,"q-item__section--side":e,"q-item__section--nowrap":this.noWrap,"q-item__section--main":!e})["justify-"+(this.top?"start":"center")]=!0,t}},render:function(t){return t("div",{staticClass:"q-item__section column",class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}});function to(t,e,i){e.handler?e.handler(t,i,i.caret):i.runCmd(e.cmd,e.param)}function eo(t,e){return t("div",{staticClass:"q-editor__toolbar-group"},e)}function io(t,e,i,n,s){void 0===s&&(s=!1);var o=s||"toggle"===i.type&&(i.toggled?i.toggled(e):i.cmd&&e.caret.is(i.cmd,i.param)),r=[],a={click:function(t){n&&n(),to(t,i,e)}};if(i.tip&&e.$q.platform.is.desktop){var l=i.key?t("div",[t("small","(CTRL + "+String.fromCharCode(i.key)+")")]):null;r.push(t(Xs,{props:{delay:1e3}},[t("div",{domProps:{innerHTML:i.tip}}),l]))}return t(Be,{props:Object.assign({},e.buttonProps,{icon:null!==i.icon?i.icon:void 0,color:o?i.toggleColor||e.toolbarToggleColor:i.color||e.toolbarColor,textColor:o&&!e.toolbarPush?null:i.textColor||e.toolbarTextColor,label:i.label,disable:!!i.disable&&("function"!=typeof i.disable||i.disable(e)),size:"sm"}),on:a},r)}function no(t,e){if(e.caret)return e.buttons.filter(function(t){return!e.isViewingSource||t.find(function(t){return"viewsource"===t.cmd})}).map(function(i){return eo(t,i.map(function(i){return(!e.isViewingSource||"viewsource"===i.cmd)&&("slot"===i.type?Ot(e,i.slot):"dropdown"===i.type?function(t,e,i){var n,s,o="only-icons"===i.list,r=i.label,a=null!==i.icon?i.icon:void 0;function l(){p.componentInstance.hide()}if(o)s=i.options.map(function(i){var n=void 0===i.type&&e.caret.is(i.cmd,i.param);return n&&(r=i.tip,a=null!==i.icon?i.icon:void 0),io(t,e,i,l,n)}),n=e.toolbarBackgroundClass,s=[eo(t,s)];else{var c=void 0!==e.toolbarToggleColor?"text-"+e.toolbarToggleColor:null,u=void 0!==e.toolbarTextColor?"text-"+e.toolbarTextColor:null,h="no-icons"===i.list;s=i.options.map(function(i){var n=!!i.disable&&i.disable(e),s=void 0===i.type&&e.caret.is(i.cmd,i.param);s&&(r=i.tip,a=null!==i.icon?i.icon:void 0);var o=i.htmlTip;return t(Zs,{props:{active:s,activeClass:c,clickable:!0,disable:n,dense:!0},on:{click:function(t){l(),e.$refs.content&&e.$refs.content.focus(),e.caret.restore(),to(t,i,e)}}},[!0===h?null:t(Js,{class:s?c:u,props:{side:!0}},[t(Ut,{props:{name:null!==i.icon?i.icon:void 0}})]),t(Js,[o?t("div",{staticClass:"text-no-wrap",domProps:{innerHTML:i.htmlTip}}):i.tip?t("div",{staticClass:"text-no-wrap"},[i.tip]):null])])}),n=[e.toolbarBackgroundClass,u],s=[t(Gs,[s])]}var d=i.highlight&&r!==i.label,p=t($i,{props:Object.assign({},e.buttonProps,{noCaps:!0,noWrap:!0,color:d?e.toolbarToggleColor:e.toolbarColor,textColor:d&&!e.toolbarPush?null:e.toolbarTextColor,label:i.fixedLabel?i.label:r,icon:i.fixedIcon?null!==i.icon?i.icon:void 0:a,contentClass:n})},s);return p}(t,e,i):io(t,e,i))}))})}function so(t,e,i){return!(!t||t===document.body)&&(!0===i&&t===e||(e===document?document.body:e).contains(t.parentNode))}var oo=/^https?:\/\//,ro=function(t,e){this.el=t,this.vm=e,this._range=null},ao={selection:{configurable:!0},hasSelection:{configurable:!0},range:{configurable:!0},parent:{configurable:!0},blockParent:{configurable:!0}};ao.selection.get=function(){if(this.el){var t=document.getSelection();if(so(t.anchorNode,this.el,!0)&&so(t.focusNode,this.el,!0))return t}return null},ao.hasSelection.get=function(){return null!==this.selection&&this.selection.toString().length>0},ao.range.get=function(){var t=this.selection;return null!==t&&t.rangeCount?t.getRangeAt(0):this._range},ao.parent.get=function(){var t=this.range;if(null!==t){var e=t.startContainer;return e.nodeType===document.ELEMENT_NODE?e:e.parentNode}return null},ao.blockParent.get=function(){var t=this.parent;return null!==t?function t(e,i){if(i&&e===i)return null;var n=e.nodeName.toLowerCase();if(!0===["div","li","ul","ol","blockquote"].includes(n))return e;var s=(window.getComputedStyle?window.getComputedStyle(e):e.currentStyle).display;return"block"===s||"table"===s?e:t(e.parentNode)}(t,this.el):null},ro.prototype.save=function(t){void 0===t&&(t=this.range),null!==t&&(this._range=t)},ro.prototype.restore=function(t){void 0===t&&(t=this._range);var e=document.createRange(),i=document.getSelection();null!==t?(e.setStart(t.startContainer,t.startOffset),e.setEnd(t.endContainer,t.endOffset),i.removeAllRanges(),i.addRange(e)):(i.selectAllChildren(this.el),i.collapseToEnd())},ro.prototype.savePosition=function(){var t,e=-1,i=document.getSelection(),n=this.el.parentNode;if(i.focusNode&&so(i.focusNode,n))for(t=i.focusNode,e=i.focusOffset;t&&t!==n;)t!==this.el&&t.previousSibling?e+=(t=t.previousSibling).textContent.length:t=t.parentNode;this.savedPos=e},ro.prototype.restorePosition=function(t){if(void 0===t&&(t=0),this.savedPos>0&&this.savedPos<t){var e=window.getSelection(),i=function t(e,i,n){if(n||((n=document.createRange()).selectNode(e),n.setStart(e,0)),0===i.count)n.setEnd(e,i.count);else if(i.count>0)if(e.nodeType===Node.TEXT_NODE)e.textContent.length<i.count?i.count-=e.textContent.length:(n.setEnd(e,i.count),i.count=0);else for(var s=0;0!==i.count&&s<e.childNodes.length;s++)n=t(e.childNodes[s],i,n);return n}(this.el,{count:this.savedPos});i&&(i.collapse(!1),e.removeAllRanges(),e.addRange(i))}},ro.prototype.hasParent=function(t,e){var i=e?this.parent:this.blockParent;return null!==i&&i.nodeName.toLowerCase()===t.toLowerCase()},ro.prototype.hasParents=function(t,e,i){return void 0===i&&(i=this.parent),null!==i&&(!0===t.includes(i.nodeName.toLowerCase())||!0===e&&this.hasParents(t,e,i.parentNode))},ro.prototype.is=function(t,e){if(null===this.selection)return!1;switch(t){case"formatBlock":return"DIV"===e&&this.parent===this.el||this.hasParent(e,"PRE"===e);case"link":return this.hasParent("A",!0);case"fontSize":return document.queryCommandValue(t)===e;case"fontName":var i=document.queryCommandValue(t);return i==='"'+e+'"'||i===e;case"fullscreen":return this.vm.inFullscreen;case"viewsource":return this.vm.isViewingSource;case void 0:return!1;default:var n=document.queryCommandState(t);return void 0!==e?n===e:n}},ro.prototype.getParentAttribute=function(t){return null!==this.parent?this.parent.getAttribute(t):null},ro.prototype.can=function(t){return"outdent"===t?this.hasParents(["blockquote","li"],!0):"indent"===t?this.hasParents(["li"],!0):"link"===t?null!==this.selection||this.is("link"):void 0},ro.prototype.apply=function(t,e,i){if(void 0===i&&(i=p),"formatBlock"===t)["BLOCKQUOTE","H1","H2","H3","H4","H5","H6"].includes(e)&&this.is(t,e)&&(t="outdent",e=null),"PRE"===e&&this.is(t,"PRE")&&(e="P");else{if("print"===t){i();var n=window.open();return n.document.write("\n <!doctype html>\n <html>\n <head>\n <title>Print - "+document.title+"\n \n \n
"+this.el.innerHTML+"
\n \n \n "),n.print(),void n.close()}if("link"===t){var s=this.getParentAttribute("href");if(null===s){var o=this.selectWord(this.selection),r=o?o.toString():"";if(!(r.length||this.range&&this.range.cloneContents().querySelector("img")))return;this.vm.editLinkUrl=oo.test(r)?r:"https://",document.execCommand("createLink",!1,this.vm.editLinkUrl),this.save(o.getRangeAt(0))}else this.vm.editLinkUrl=s,this.range.selectNodeContents(this.parent),this.save();return}if("fullscreen"===t)return this.vm.toggleFullscreen(),void i();if("viewsource"===t)return this.vm.isViewingSource=!1===this.vm.isViewingSource,this.vm.__setContent(this.vm.value),void i()}document.execCommand(t,!1,e),i()},ro.prototype.selectWord=function(t){if(null===t||!0!==t.isCollapsed||void 0===t.modify)return t;var e=document.createRange();e.setStart(t.anchorNode,t.anchorOffset),e.setEnd(t.focusNode,t.focusOffset);var i=e.collapsed?["backward","forward"]:["forward","backward"];e.detach();var n=t.focusNode,s=t.focusOffset;return t.collapse(t.anchorNode,t.anchorOffset),t.modify("move",i[0],"character"),t.modify("move",i[1],"word"),t.extend(n,s),t.modify("extend",i[1],"character"),t.modify("extend",i[0],"word"),t},Object.defineProperties(ro.prototype,ao);var lo=Object.prototype.toString,co=Object.prototype.hasOwnProperty,uo={};function ho(t){return null===t?String(t):uo[lo.call(t)]||"object"}function po(t){if(!t||"object"!==ho(t))return!1;if(t.constructor&&!co.call(t,"constructor")&&!co.call(t.constructor.prototype,"isPrototypeOf"))return!1;var e;for(e in t);return void 0===e||co.call(t,e)}function fo(){var t,e,i,n,s,o,r=arguments,a=arguments[0]||{},l=1,c=!1,u=arguments.length;for("boolean"==typeof a&&(c=a,a=arguments[1]||{},l=2),Object(a)!==a&&"function"!==ho(a)&&(a={}),u===l&&(a=this,l--);l0},toolbarBackgroundClass:function(){if(this.toolbarBg)return"bg-"+this.toolbarBg},buttonProps:function(){return{type:"a",flat:!0!==this.toolbarOutline&&!0!==this.toolbarPush,noWrap:!0,outline:this.toolbarOutline,push:this.toolbarPush,rounded:this.toolbarRounded,dense:!0,color:this.toolbarColor,disable:!this.editable,size:"sm"}},buttonDef:function(){var t=this.$q.lang.editor,e=this.$q.iconSet.editor;return{bold:{cmd:"bold",icon:e.bold,tip:t.bold,key:66},italic:{cmd:"italic",icon:e.italic,tip:t.italic,key:73},strike:{cmd:"strikeThrough",icon:e.strikethrough,tip:t.strikethrough,key:83},underline:{cmd:"underline",icon:e.underline,tip:t.underline,key:85},unordered:{cmd:"insertUnorderedList",icon:e.unorderedList,tip:t.unorderedList},ordered:{cmd:"insertOrderedList",icon:e.orderedList,tip:t.orderedList},subscript:{cmd:"subscript",icon:e.subscript,tip:t.subscript,htmlTip:"x2"},superscript:{cmd:"superscript",icon:e.superscript,tip:t.superscript,htmlTip:"x2"},link:{cmd:"link",disable:function(t){return t.caret&&!t.caret.can("link")},icon:e.hyperlink,tip:t.hyperlink,key:76},fullscreen:{cmd:"fullscreen",icon:e.toggleFullscreen,tip:t.toggleFullscreen,key:70},viewsource:{cmd:"viewsource",icon:e.viewSource,tip:t.viewSource},quote:{cmd:"formatBlock",param:"BLOCKQUOTE",icon:e.quote,tip:t.quote,key:81},left:{cmd:"justifyLeft",icon:e.left,tip:t.left},center:{cmd:"justifyCenter",icon:e.center,tip:t.center},right:{cmd:"justifyRight",icon:e.right,tip:t.right},justify:{cmd:"justifyFull",icon:e.justify,tip:t.justify},print:{type:"no-state",cmd:"print",icon:e.print,tip:t.print,key:80},outdent:{type:"no-state",disable:function(t){return t.caret&&!t.caret.can("outdent")},cmd:"outdent",icon:e.outdent,tip:t.outdent},indent:{type:"no-state",disable:function(t){return t.caret&&!t.caret.can("indent")},cmd:"indent",icon:e.indent,tip:t.indent},removeFormat:{type:"no-state",cmd:"removeFormat",icon:e.removeFormat,tip:t.removeFormat},hr:{type:"no-state",cmd:"insertHorizontalRule",icon:e.hr,tip:t.hr},undo:{type:"no-state",cmd:"undo",icon:e.undo,tip:t.undo,key:90},redo:{type:"no-state",cmd:"redo",icon:e.redo,tip:t.redo,key:89},h1:{cmd:"formatBlock",param:"H1",icon:e.heading1||e.heading,tip:t.heading1,htmlTip:'

'+t.heading1+"

"},h2:{cmd:"formatBlock",param:"H2",icon:e.heading2||e.heading,tip:t.heading2,htmlTip:'

'+t.heading2+"

"},h3:{cmd:"formatBlock",param:"H3",icon:e.heading3||e.heading,tip:t.heading3,htmlTip:'

'+t.heading3+"

"},h4:{cmd:"formatBlock",param:"H4",icon:e.heading4||e.heading,tip:t.heading4,htmlTip:'

'+t.heading4+"

"},h5:{cmd:"formatBlock",param:"H5",icon:e.heading5||e.heading,tip:t.heading5,htmlTip:'
'+t.heading5+"
"},h6:{cmd:"formatBlock",param:"H6",icon:e.heading6||e.heading,tip:t.heading6,htmlTip:'
'+t.heading6+"
"},p:{cmd:"formatBlock",param:this.paragraphTag.toUpperCase(),icon:e.heading,tip:t.paragraph},code:{cmd:"formatBlock",param:"PRE",icon:e.code,htmlTip:""+t.code+""},"size-1":{cmd:"fontSize",param:"1",icon:e.size1||e.size,tip:t.size1,htmlTip:''+t.size1+""},"size-2":{cmd:"fontSize",param:"2",icon:e.size2||e.size,tip:t.size2,htmlTip:''+t.size2+""},"size-3":{cmd:"fontSize",param:"3",icon:e.size3||e.size,tip:t.size3,htmlTip:''+t.size3+""},"size-4":{cmd:"fontSize",param:"4",icon:e.size4||e.size,tip:t.size4,htmlTip:''+t.size4+""},"size-5":{cmd:"fontSize",param:"5",icon:e.size5||e.size,tip:t.size5,htmlTip:''+t.size5+""},"size-6":{cmd:"fontSize",param:"6",icon:e.size6||e.size,tip:t.size6,htmlTip:''+t.size6+""},"size-7":{cmd:"fontSize",param:"7",icon:e.size7||e.size,tip:t.size7,htmlTip:''+t.size7+""}}},buttons:function(){var t=this,e=this.definitions||{},i=this.definitions||this.fonts?fo(!0,{},this.buttonDef,e,function(t,e,i,n){void 0===n&&(n={});var s=Object.keys(n);if(0===s.length)return{};var o={default_font:{cmd:"fontName",param:t,icon:i,tip:e}};return s.forEach(function(t){var e=n[t];o[t]={cmd:"fontName",param:e,icon:i,tip:e,htmlTip:''+e+""}}),o}(this.defaultFont,this.$q.lang.editor.defaultFont,this.$q.iconSet.editor.font,this.fonts)):this.buttonDef;return this.toolbar.map(function(n){return n.map(function(n){if(n.options)return{type:"dropdown",icon:n.icon,label:n.label,size:"sm",dense:!0,fixedLabel:n.fixedLabel,fixedIcon:n.fixedIcon,highlight:n.highlight,list:n.list,options:n.options.map(function(t){return i[t]})};var s=i[n];return s?"no-state"===s.type||e[n]&&(void 0===s.cmd||t.buttonDef[s.cmd]&&"no-state"===t.buttonDef[s.cmd].type)?s:Object.assign({type:"toggle"},s):{type:"slot",slot:n}})})},keys:function(){var t={},e=function(e){e.key&&(t[e.key]={cmd:e.cmd,param:e.param})};return this.buttons.forEach(function(t){t.forEach(function(t){t.options?t.options.forEach(e):e(t)})}),t},innerStyle:function(){return this.inFullscreen?this.contentStyle:[{minHeight:this.minHeight,height:this.height,maxHeight:this.maxHeight},this.contentStyle]},classes:function(){return"q-editor q-editor--"+(!0===this.isViewingSource?"source":"default")+(!0===this.disable?" disabled":"")+(!0===this.inFullscreen?" fullscreen column":"")+(!0===this.square?" q-editor--square no-border-radius":"")+(!0===this.flat?" q-editor--flat":"")+(!0===this.dense?" q-editor--dense":"")+(!0===this.isDark?" q-editor--dark q-dark":"")},innerClass:function(){return[this.contentClass,{col:this.inFullscreen,"overflow-auto":this.inFullscreen||this.maxHeight}]},attrs:function(){return!0===this.disable?{"aria-disabled":"true"}:!0===this.readonly?{"aria-readonly":"true"}:void 0},onEditor:function(){return{focusin:this.__onFocusin,focusout:this.__onFocusout}}},data:function(){return{lastEmit:this.value,editLinkUrl:null,isViewingSource:!1}},watch:{value:function(t){this.lastEmit!==t&&(this.lastEmit=t,this.__setContent(t,!0))}},methods:{__onInput:function(){if(void 0!==this.$refs.content){var t=!0===this.isViewingSource?this.$refs.content.innerText:this.$refs.content.innerHTML;t!==this.value&&(this.lastEmit=t,this.$emit("input",t))}},__onKeydown:function(t){if(this.$emit("keydown",t),!0!==t.ctrlKey||!0===Z(t))return this.refreshToolbar(),void(this.$q.platform.is.ie&&this.$nextTick(this.__onInput));var e=t.keyCode,i=this.keys[e];if(void 0!==i){var n=i.cmd,s=i.param;S(t),this.runCmd(n,s,!1)}},__onClick:function(t){this.refreshToolbar(),this.$emit("click",t)},__onBlur:function(t){if(void 0!==this.$refs.content){var e=this.$refs.content,i=e.scrollTop,n=e.scrollHeight;this.__offsetBottom=n-i}!0!==this.$q.platform.is.ie&&this.caret.save(),this.$emit("blur",t)},__onFocus:function(t){var e=this;this.$nextTick(function(){void 0!==e.$refs.content&&void 0!==e.__offsetBottom&&(e.$refs.content.scrollTop=e.$refs.content.scrollHeight-e.__offsetBottom)}),this.$emit("focus",t)},__onFocusin:function(t){if(!0===this.$el.contains(t.target)&&(null===t.relatedTarget||!0!==this.$el.contains(t.relatedTarget))){var e="inner"+(!0===this.isViewingSource?"Text":"HTML");this.caret.restorePosition(this.$refs.content[e].length),this.refreshToolbar()}},__onFocusout:function(t){!0!==this.$el.contains(t.target)||null!==t.relatedTarget&&!0===this.$el.contains(t.relatedTarget)||(this.caret.savePosition(),this.refreshToolbar())},__onPointerStart:function(t){this.__offsetBottom=void 0,void 0!==this.qListeners[t.type]&&this.$emit(t.type,t)},__onSelectionchange:function(){this.caret.save()},runCmd:function(t,e,i){var n=this;void 0===i&&(i=!0),this.focus(),this.caret.restore(),this.caret.apply(t,e,function(){n.focus(),n.caret.save(),!0!==n.$q.platform.is.ie&&!0!==n.$q.platform.is.edge||n.$nextTick(n.__onInput),i&&n.refreshToolbar()})},refreshToolbar:function(){var t=this;setTimeout(function(){t.editLinkUrl=null,t.$forceUpdate()},1)},focus:function(){var t=this;Ve(function(){void 0!==t.$refs.content&&t.$refs.content.focus({preventScroll:!0})})},getContentEl:function(){return this.$refs.content},__setContent:function(t,e){if(void 0!==this.$refs.content){!0===e&&this.caret.savePosition();var i="inner"+(!0===this.isViewingSource?"Text":"HTML");this.$refs.content[i]=t,!0===e&&(this.caret.restorePosition(this.$refs.content[i].length),this.refreshToolbar())}}},created:function(){!1===i&&(document.execCommand("defaultParagraphSeparator",!1,this.paragraphTag),this.defaultFont=window.getComputedStyle(document.body).fontFamily)},mounted:function(){this.caret=new ro(this.$refs.content,this),this.__setContent(this.value),this.refreshToolbar(),document.addEventListener("selectionchange",this.__onSelectionchange)},beforeDestroy:function(){document.removeEventListener("selectionchange",this.__onSelectionchange)},render:function(t){var e;if(this.hasToolbar){var n=[t("div",{key:"qedt_top",staticClass:"q-editor__toolbar row no-wrap scroll-x",class:this.toolbarBackgroundClass},no(t,this))];null!==this.editLinkUrl&&n.push(t("div",{key:"qedt_btm",staticClass:"q-editor__toolbar row no-wrap items-center scroll-x",class:this.toolbarBackgroundClass},function(t,e,i){if(e.caret){var n=e.toolbarColor||e.toolbarTextColor,s=e.editLinkUrl,o=function(){e.caret.restore(),s!==e.editLinkUrl&&document.execCommand("createLink",!1,""===s?" ":s),e.editLinkUrl=null,!0===i&&e.$nextTick(e.__onInput)};return[t("div",{staticClass:"q-mx-xs",class:"text-"+n},[e.$q.lang.editor.url+": "]),t("input",{key:"qedt_btm_input",staticClass:"col q-editor__link-input",domProps:{value:s},on:{input:function(t){b(t),s=t.target.value},keydown:function(t){if(!0!==Z(t))switch(t.keyCode){case 13:return y(t),o();case 27:y(t),e.caret.restore(),e.editLinkUrl&&"https://"!==e.editLinkUrl||document.execCommand("unlink"),e.editLinkUrl=null}}}}),eo(t,[t(Be,{key:"qedt_btm_rem",attrs:{tabindex:-1},props:Object.assign({},e.buttonProps,{label:e.$q.lang.label.remove,noCaps:!0}),on:{click:function(){e.caret.restore(),document.execCommand("unlink"),e.editLinkUrl=null,!0===i&&e.$nextTick(e.__onInput)}}}),t(Be,{key:"qedt_btm_upd",props:Object.assign({},e.buttonProps,{label:e.$q.lang.label.update,noCaps:!0}),on:{click:o}})])]}}(t,this,this.$q.platform.is.ie))),e=t("div",{key:"toolbar_ctainer",staticClass:"q-editor__toolbars-container"},n)}var s=Object.assign({},this.qListeners,{input:this.__onInput,keydown:this.__onKeydown,click:this.__onClick,blur:this.__onBlur,focus:this.__onFocus,mousedown:this.__onPointerStart,touchstart:this.__onPointerStart});return t("div",{style:{height:!0===this.inFullscreen?"100%":null},class:this.classes,attrs:this.attrs,on:this.onEditor},[e,t("div",{ref:"content",staticClass:"q-editor__content",style:this.innerStyle,class:this.innerClass,attrs:{contenteditable:this.editable,placeholder:this.placeholder},domProps:i?{innerHTML:this.value}:void 0,on:s})])}}),go=t.extend({name:"QItemLabel",mixins:[Lt],props:{overline:Boolean,caption:Boolean,header:Boolean,lines:[Number,String]},computed:{classes:function(){return{"q-item__label--overline text-overline":this.overline,"q-item__label--caption text-caption":this.caption,"q-item__label--header":this.header,ellipsis:1===parseInt(this.lines,10)}},style:function(){if(void 0!==this.lines&&parseInt(this.lines,10)>1)return{overflow:"hidden",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":this.lines}}},render:function(t){return t("div",{staticClass:"q-item__label",style:this.style,class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),_o=t.extend({name:"QSlideTransition",props:{appear:Boolean,duration:{type:Number,default:300}},methods:{__begin:function(t,e,i){t.style.overflowY="hidden",void 0!==e&&(t.style.height=e+"px"),t.style.transition="height "+this.duration+"ms cubic-bezier(.25, .8, .50, 1)",this.animating=!0,this.done=i},__end:function(t,e){t.style.overflowY=null,t.style.height=null,t.style.transition=null,this.__cleanup(),e!==this.lastEvent&&this.$emit(e)},__cleanup:function(){this.done&&this.done(),this.done=null,this.animating=!1,clearTimeout(this.timer),clearTimeout(this.timerFallback),void 0!==this.el&&this.el.removeEventListener("transitionend",this.animListener),this.animListener=null}},beforeDestroy:function(){this.animating&&this.__cleanup()},render:function(t){var e=this;return t("transition",{props:{css:!1,appear:this.appear},on:ft(this,"tr",{enter:function(t,i){var n=0;e.el=t,!0===e.animating?(e.__cleanup(),n=t.offsetHeight===t.scrollHeight?0:void 0):e.lastEvent="hide",e.__begin(t,n,i),e.timer=setTimeout(function(){t.style.height=t.scrollHeight+"px",e.animListener=function(i){Object(i)===i&&i.target!==t||e.__end(t,"show")},t.addEventListener("transitionend",e.animListener),e.timerFallback=setTimeout(e.animListener,1.1*e.duration)},100)},leave:function(t,i){var n;e.el=t,!0===e.animating?e.__cleanup():(e.lastEvent="show",n=t.scrollHeight),e.__begin(t,n,i),e.timer=setTimeout(function(){t.style.height=0,e.animListener=function(i){Object(i)===i&&i.target!==t||e.__end(t,"hide")},t.addEventListener("transitionend",e.animListener),e.timerFallback=setTimeout(e.animListener,1.1*e.duration)},100)}})},Ot(this,"default"))}}),bo={true:"inset",item:"item-inset","item-thumbnail":"item-thumbnail-inset"},yo={xs:2,sm:4,md:8,lg:16,xl:24},So=t.extend({name:"QSeparator",mixins:[Gt,Lt],props:{spaced:[Boolean,String],inset:[Boolean,String],vertical:Boolean,color:String,size:String},computed:{orientation:function(){return!0===this.vertical?"vertical":"horizontal"},classPrefix:function(){return" q-separator--"+this.orientation},insetClass:function(){return!1!==this.inset?this.classPrefix+"-"+bo[this.inset]:""},classes:function(){return"q-separator"+this.classPrefix+this.insetClass+(void 0!==this.color?" bg-"+this.color:"")+(!0===this.isDark?" q-separator--dark":"")},style:function(){var t={};if(void 0!==this.size&&(t[!0===this.vertical?"width":"height"]=this.size),!1!==this.spaced){var e=!0===this.spaced?yo.md+"px":this.spaced in yo?yo[this.spaced]+"px":this.spaced,i=!0===this.vertical?["Left","Right"]:["Top","Bottom"];t["margin"+i[0]]=t["margin"+i[1]]=e}return t},attrs:function(){return{"aria-orientation":this.orientation}}},render:function(t){return t("hr",{staticClass:"q-separator",class:this.classes,style:this.style,attrs:this.attrs,on:Object.assign({},this.qListeners)})}}),wo="q:expansion-item:close",Co=t.extend({name:"QExpansionItem",mixins:[Gt,ae,Ie],props:{icon:String,label:String,labelLines:[Number,String],caption:String,captionLines:[Number,String],dense:Boolean,expandIcon:String,expandedIcon:String,expandIconClass:[Array,String,Object],duration:Number,headerInsetLevel:Number,contentInsetLevel:Number,expandSeparator:Boolean,defaultOpened:Boolean,expandIconToggle:Boolean,switchToggleSide:Boolean,denseToggle:Boolean,group:String,popup:Boolean,headerStyle:[Array,String,Object],headerClass:[Array,String,Object]},data:function(){return{showing:void 0!==this.value?this.value:this.defaultOpened}},watch:{showing:function(t){!0===t&&void 0!==this.group&&this.$root.$emit(wo,this)},group:function(t,e){void 0!==t&&void 0===e?this.$root.$on(wo,this.__eventHandler):void 0===t&&void 0!==e&&this.$root.$off(wo,this.__eventHandler)}},computed:{classes:function(){return"q-expansion-item--"+(!0===this.showing?"expanded":"collapsed")+" q-expansion-item--"+(!0===this.popup?"popup":"standard")},contentStyle:function(){var t;if(void 0!==this.contentInsetLevel)return(t={})["padding"+(!0===this.$q.lang.rtl?"Right":"Left")]=56*this.contentInsetLevel+"px",t},isClickable:function(){return!0===this.hasLink||!0!==this.expandIconToggle},expansionIcon:function(){return void 0!==this.expandedIcon&&!0===this.showing?this.expandedIcon:this.expandIcon||this.$q.iconSet.expansionItem[!0===this.denseToggle?"denseIcon":"icon"]},activeToggleIcon:function(){return!0!==this.disable&&(!0===this.hasLink||!0===this.expandIconToggle)}},methods:{__onHeaderClick:function(t){!0!==this.hasLink&&this.toggle(t),this.$emit("click",t)},__toggleIconKeyboard:function(t){13===t.keyCode&&this.__toggleIcon(t,!0)},__toggleIcon:function(t,e){!0!==e&&void 0!==this.$refs.blurTarget&&this.$refs.blurTarget.focus(),this.toggle(t),S(t)},__eventHandler:function(t){this!==t&&this.group===t.group&&this.hide()},__getToggleIcon:function(t){var e={staticClass:"q-focusable relative-position cursor-pointer"+(!0===this.denseToggle&&!0===this.switchToggleSide?" items-end":""),class:this.expandIconClass,props:{side:!0!==this.switchToggleSide,avatar:this.switchToggleSide}},i=[t(Ut,{staticClass:"q-expansion-item__toggle-icon",class:void 0===this.expandedIcon&&!0===this.showing?"q-expansion-item__toggle-icon--rotated":void 0,props:{name:this.expansionIcon}})];return!0===this.activeToggleIcon&&(Object.assign(e,{attrs:{tabindex:0},on:ft(this,"inpExt",{click:this.__toggleIcon,keyup:this.__toggleIconKeyboard})}),i.unshift(t("div",{ref:"blurTarget",staticClass:"q-expansion-item__toggle-focus q-icon q-focus-helper q-focus-helper--rounded",attrs:{tabindex:-1}}))),t(Js,e,i)},__getHeader:function(t){var e;void 0!==this.$scopedSlots.header?e=[].concat(this.$scopedSlots.header()):(e=[t(Js,[t(go,{props:{lines:this.labelLines}},[this.label||""]),this.caption?t(go,{props:{lines:this.captionLines,caption:!0}},[this.caption]):null])],this.icon&&e[!0===this.switchToggleSide?"push":"unshift"](t(Js,{props:{side:!0===this.switchToggleSide,avatar:!0!==this.switchToggleSide}},[t(Ut,{props:{name:this.icon}})]))),!0!==this.disable&&e[!0===this.switchToggleSide?"unshift":"push"](this.__getToggleIcon(t));var i={ref:"item",style:this.headerStyle,class:this.headerClass,props:{dark:this.isDark,disable:this.disable,dense:this.dense,insetLevel:this.headerInsetLevel}};return!0===this.isClickable&&(i.props.clickable=!0,i[!0===this.hasRouterLink?"nativeOn":"on"]=Object.assign({},this.qListeners,{click:this.__onHeaderClick}),!0===this.hasLink&&(Object.assign(i.props,this.linkProps.props),i.attrs=this.linkProps.attrs)),t(Zs,i,e)},__getContent:function(t){var e=this,i=[this.__getHeader(t),t(_o,{props:{duration:this.duration},on:ft(this,"slide",{show:function(){e.$emit("after-show")},hide:function(){e.$emit("after-hide")}})},[t("div",{staticClass:"q-expansion-item__content relative-position",style:this.contentStyle,directives:[{name:"show",value:this.showing}]},Ot(this,"default"))])];return this.expandSeparator&&i.push(t(So,{staticClass:"q-expansion-item__border q-expansion-item__border--top absolute-top",props:{dark:this.isDark}}),t(So,{staticClass:"q-expansion-item__border q-expansion-item__border--bottom absolute-bottom",props:{dark:this.isDark}})),i}},render:function(t){return t("div",{staticClass:"q-expansion-item q-item-type",class:this.classes},[t("div",{staticClass:"q-expansion-item__container relative-position"},this.__getContent(t))])},created:function(){void 0!==this.group&&this.$root.$on(wo,this.__eventHandler)},beforeDestroy:function(){void 0!==this.group&&this.$root.$off(wo,this.__eventHandler)}}),xo=["top","right","bottom","left"],ko={mixins:[Lt],props:{type:{type:String,default:"a"},outline:Boolean,push:Boolean,flat:Boolean,unelevated:Boolean,color:String,textColor:String,glossy:Boolean,square:Boolean,padding:String,label:{type:[String,Number],default:""},labelPosition:{type:String,default:"right",validator:function(t){return xo.includes(t)}},externalLabel:Boolean,hideLabel:{type:Boolean},labelClass:[Array,String,Object],labelStyle:[Array,String,Object],disable:Boolean,tabindex:[Number,String]},computed:{formClass:function(){return"q-fab--form-"+(!0===this.square?"square":"rounded")},stacked:function(){return!1===this.externalLabel&&["top","bottom"].includes(this.labelPosition)},labelProps:function(){if(!0===this.externalLabel){var t=null===this.hideLabel?!1===this.showing:this.hideLabel;return{action:"push",data:{staticClass:"q-fab__label q-tooltip--style q-fab__label--external q-fab__label--external-"+this.labelPosition+(!0===t?" q-fab__label--external-hidden":""),style:this.labelStyle,class:this.labelClass}}}return{action:["left","top"].includes(this.labelPosition)?"unshift":"push",data:{staticClass:"q-fab__label q-fab__label--internal q-fab__label--internal-"+this.labelPosition+(!0===this.hideLabel?" q-fab__label--internal-hidden":""),style:this.labelStyle,class:this.labelClass}}}}},qo=["up","right","down","left"],To=["left","center","right"],Mo=t.extend({name:"QFab",inheritAttrs:!1,mixins:[ko,bt,Ie],provide:function(){return{__qFab:this}},props:{icon:String,activeIcon:String,hideIcon:Boolean,hideLabel:{default:null},direction:{type:String,default:"right",validator:function(t){return qo.includes(t)}},persistent:Boolean,verticalActionsAlign:{type:String,default:"center",validator:function(t){return To.includes(t)}}},data:function(){return{showing:!0===this.value}},computed:{hideOnRouteChange:function(){return!0!==this.persistent},classes:function(){return"q-fab--align-"+this.verticalActionsAlign+" "+this.formClass+(!0===this.showing?" q-fab--opened":"")},actionsClasses:function(){return"q-fab__actions--"+this.direction+(!0===this.showing?" q-fab__actions--opened":"")},iconHolderClasses:function(){return!0===this.showing?"q-fab__icon-holder--opened":""},attrs:function(){return Object.assign({},{"aria-expanded":!0===this.showing?"true":"false","aria-haspopup":"true"},this.qAttrs)},slotScope:function(){return{opened:this.showing}}},methods:{__onChildClick:function(t){this.hide(t),this.$refs.trigger&&this.$refs.trigger.$el&&this.$refs.trigger.$el.focus()},__getIcon:function(t,e,i){var n=this.$scopedSlots[e],s="q-fab__"+e+" absolute-full";return void 0===n?t(Ut,{staticClass:s,props:{name:this[i]||this.$q.iconSet.fab[i]}}):t("div",{staticClass:s},n(this.slotScope))}},render:function(t){var e=[];return!0!==this.hideIcon&&e.push(t("div",{staticClass:"q-fab__icon-holder",class:this.iconHolderClasses},[this.__getIcon(t,"icon","icon"),this.__getIcon(t,"active-icon","activeIcon")])),""===this.label&&void 0===this.$scopedSlots.label||e[this.labelProps.action](t("div",this.labelProps.data,void 0!==this.$scopedSlots.label?this.$scopedSlots.label(this.slotScope):[this.label])),t("div",{staticClass:"q-fab z-fab row inline justify-center",class:this.classes,on:Object.assign({},this.qListeners)},[t(Be,{ref:"trigger",class:this.formClass,props:Object.assign({},this.$props,{noWrap:!0,stack:this.stacked,align:void 0,icon:void 0,label:void 0,noCaps:!0,fab:!0}),attrs:this.attrs,on:ft(this,"tog",{click:this.toggle})},Et(e,this,"tooltip")),t("div",{staticClass:"q-fab__actions flex no-wrap inline",class:this.actionsClasses},Ot(this,"default"))])}}),$o={start:"self-end",center:"self-center",end:"self-start"},Lo=Object.keys($o),Oo=t.extend({name:"QFabAction",mixins:[ko],props:{icon:{type:String,default:""},anchor:{type:String,validator:function(t){return Lo.includes(t)}},to:[String,Object],replace:Boolean},inject:{__qFab:{default:function(){return{showing:!0,__onChildClick:p}}}},computed:{classes:function(){var t=$o[this.anchor];return this.formClass+(void 0!==t?" "+t:"")},onEvents:function(){return Object.assign({},this.qListeners,{click:this.click})},isDisabled:function(){return!0!==this.__qFab.showing||!0===this.disable}},methods:{click:function(t){this.__qFab.__onChildClick(t),this.$emit("click",t)}},render:function(t){var e=[];return void 0!==this.$scopedSlots.icon?e.push(this.$scopedSlots.icon()):""!==this.icon&&e.push(t(Ut,{props:{name:this.icon}})),""===this.label&&void 0===this.$scopedSlots.label||e[this.labelProps.action](t("div",this.labelProps.data,void 0!==this.$scopedSlots.label?this.$scopedSlots.label():[this.label])),t(Be,{class:this.classes,props:Object.assign({},this.$props,{noWrap:!0,stack:this.stacked,icon:void 0,label:void 0,noCaps:!0,fabMini:!0,disable:this.isDisabled}),on:this.onEvents},Et(e,this,"default"))}}),Bo=[!0,!1,"ondemand"],Eo={props:{value:{},error:{type:Boolean,default:null},errorMessage:String,noErrorIcon:Boolean,rules:Array,reactiveRules:Boolean,lazyRules:{type:[Boolean,String],validator:function(t){return Bo.includes(t)}}},data:function(){return{isDirty:null,innerError:!1,innerErrorMessage:void 0}},watch:{value:function(){this.__validateIfNeeded()},disable:function(t){!0===t?this.__resetValidation():this.__validateIfNeeded(!0)},reactiveRules:{handler:function(t){var e=this;!0===t?void 0===this.unwatchRules&&(this.unwatchRules=this.$watch("rules",function(){e.__validateIfNeeded(!0)})):void 0!==this.unwatchRules&&(this.unwatchRules(),this.unwatchRules=void 0)},immediate:!0},focused:function(t){!0===t?null===this.isDirty&&(this.isDirty=!1):!1===this.isDirty&&(this.isDirty=!0,!0===this.hasActiveRules&&"ondemand"!==this.lazyRules&&!1===this.innerLoading&&this.debouncedValidate())},hasError:function(t){var e=document.getElementById(this.targetUid);null!==e&&e.setAttribute("aria-invalid",!0===t)}},computed:{hasRules:function(){return void 0!==this.rules&&null!==this.rules&&this.rules.length>0},hasActiveRules:function(){return!0!==this.disable&&!0===this.hasRules},hasError:function(){return!0===this.error||!0===this.innerError},computedErrorMessage:function(){return"string"==typeof this.errorMessage&&this.errorMessage.length>0?this.errorMessage:this.innerErrorMessage}},created:function(){this.debouncedValidate=T(this.validate,0)},mounted:function(){this.validateIndex=0},beforeDestroy:function(){void 0!==this.unwatchRules&&this.unwatchRules(),this.debouncedValidate.cancel()},methods:{resetValidation:function(){this.isDirty=null,this.__resetValidation()},validate:function(t){var e=this;if(void 0===t&&(t=this.value),!0!==this.hasActiveRules)return!0;var i=++this.validateIndex;!0!==this.innerLoading&&!0!==this.lazyRules&&(this.isDirty=!0);for(var n=function(t,i){e.innerError!==t&&(e.innerError=t);var n=i||void 0;e.innerErrorMessage!==n&&(e.innerErrorMessage=n),!1!==e.innerLoading&&(e.innerLoading=!1)},s=[],o=0;o0;i--)e.push(Math.floor(256*Math.random()));return e}}(),Do=4096;function Ro(){(void 0===mo||zo+16>Do)&&(zo=0,mo=Io(Do));var t=Array.prototype.slice.call(mo,zo,zo+=16);return t[6]=15&t[6]|64,t[8]=63&t[8]|128,Po[t[0]]+Po[t[1]]+Po[t[2]]+Po[t[3]]+"-"+Po[t[4]]+Po[t[5]]+"-"+Po[t[6]]+Po[t[7]]+"-"+Po[t[8]]+Po[t[9]]+"-"+Po[t[10]]+Po[t[11]]+Po[t[12]]+Po[t[13]]+Po[t[14]]+Po[t[15]]}function Fo(t){return void 0===t?"f_"+Ro():t}var jo=t.extend({name:"QField",mixins:[Gt,Eo,bt],inheritAttrs:!1,props:{label:String,stackLabel:Boolean,hint:String,hideHint:Boolean,prefix:String,suffix:String,labelColor:String,color:String,bgColor:String,filled:Boolean,outlined:Boolean,borderless:Boolean,standout:[Boolean,String],square:Boolean,loading:Boolean,labelSlot:Boolean,bottomSlots:Boolean,hideBottomSpace:Boolean,rounded:Boolean,dense:Boolean,itemAligned:Boolean,counter:Boolean,clearable:Boolean,clearIcon:String,disable:Boolean,readonly:Boolean,autofocus:Boolean,for:String,maxlength:[Number,String],maxValues:[Number,String]},data:function(){return{focused:!1,targetUid:Fo(this.for),innerLoading:!1}},watch:{for:function(t){this.targetUid=Fo(t)}},computed:{editable:function(){return!0!==this.disable&&!0!==this.readonly},hasValue:function(){var t=void 0===this.__getControl?this.value:this.innerValue;return void 0!==t&&null!==t&&(""+t).length>0},computedCounter:function(){if(!1!==this.counter){var t="string"==typeof this.value||"number"==typeof this.value?(""+this.value).length:!0===Array.isArray(this.value)?this.value.length:0,e=void 0!==this.maxlength?this.maxlength:this.maxValues;return t+(void 0!==e?" / "+e:"")}},floatingLabel:function(){return!0===this.stackLabel||!0===this.focused||"string"==typeof this.inputValue&&this.inputValue.length>0||!0!==this.hideSelected&&!0===this.hasValue||void 0!==this.displayValue&&null!==this.displayValue&&(""+this.displayValue).length>0},shouldRenderBottom:function(){return!0===this.bottomSlots||void 0!==this.hint||!0===this.hasRules||!0===this.counter||null!==this.error},classes:function(){var t;return(t={})[this.fieldClass]=void 0!==this.fieldClass,t["q-field--"+this.styleType]=!0,t["q-field--rounded"]=this.rounded,t["q-field--square"]=this.square,t["q-field--focused"]=!0===this.focused,t["q-field--highlighted"]=!0===this.focused||!0===this.hasError,t["q-field--float"]=this.floatingLabel,t["q-field--labeled"]=this.hasLabel,t["q-field--dense"]=this.dense,t["q-field--item-aligned q-item-type"]=this.itemAligned,t["q-field--dark"]=this.isDark,t["q-field--auto-height"]=void 0===this.__getControl,t["q-field--with-bottom"]=!0!==this.hideBottomSpace&&!0===this.shouldRenderBottom,t["q-field--error"]=this.hasError,t["q-field--readonly"]=!0===this.readonly&&!0!==this.disable,t["q-field--disabled"]=!0===this.disable,t},styleType:function(){return!0===this.filled?"filled":!0===this.outlined?"outlined":!0===this.borderless?"borderless":this.standout?"standout":"standard"},contentClass:function(){var t=[];if(!0===this.hasError)t.push("text-negative");else{if("string"==typeof this.standout&&this.standout.length>0&&!0===this.focused)return this.standout;void 0!==this.color&&t.push("text-"+this.color)}return void 0!==this.bgColor&&t.push("bg-"+this.bgColor),t},hasLabel:function(){return!0===this.labelSlot||void 0!==this.label},labelClass:function(){if(void 0!==this.labelColor&&!0!==this.hasError)return"text-"+this.labelColor},controlSlotScope:function(){return{id:this.targetUid,field:this.$el,editable:this.editable,focused:this.focused,floatingLabel:this.floatingLabel,value:this.value,emitValue:this.__emitValue}},bottomSlotScope:function(){return{id:this.targetUid,field:this.$el,editable:this.editable,focused:this.focused,value:this.value,errorMessage:this.computedErrorMessage}},attrs:function(){var t={for:this.targetUid};return!0===this.disable?t["aria-disabled"]="true":!0===this.readonly&&(t["aria-readonly"]="true"),t}},methods:{focus:function(){Ve(this.__focus)},blur:function(){var t;t=this.__focus,De=De.filter(function(e){return e!==t});var e=document.activeElement;null!==e&&this.$el.contains(e)&&e.blur()},__focus:function(){var t=document.activeElement,e=this.$refs.target;void 0===e||null!==t&&t.id===this.targetUid||(!0===e.hasAttribute("tabindex")||(e=e.querySelector("[tabindex]")),null!==e&&e!==t&&e.focus({preventScroll:!0}))},__getContent:function(t){var e=[];return void 0!==this.$scopedSlots.prepend&&e.push(t("div",{staticClass:"q-field__prepend q-field__marginal row no-wrap items-center",key:"prepend",on:this.slotsEvents},this.$scopedSlots.prepend())),e.push(t("div",{staticClass:"q-field__control-container col relative-position row no-wrap q-anchor--skip"},this.__getControlContainer(t))),!0===this.hasError&&!1===this.noErrorIcon&&e.push(this.__getInnerAppendNode(t,"error",[t(Ut,{props:{name:this.$q.iconSet.field.error,color:"negative"}})])),!0===this.loading||!0===this.innerLoading?e.push(this.__getInnerAppendNode(t,"inner-loading-append",void 0!==this.$scopedSlots.loading?this.$scopedSlots.loading():[t(ue,{props:{color:this.color}})])):!0===this.clearable&&!0===this.hasValue&&!0===this.editable&&e.push(this.__getInnerAppendNode(t,"inner-clearable-append",[t(Ut,{staticClass:"q-field__focusable-action",props:{tag:"button",name:this.clearIcon||this.$q.iconSet.field.clear},attrs:_t,on:this.clearableEvents})])),void 0!==this.$scopedSlots.append&&e.push(t("div",{staticClass:"q-field__append q-field__marginal row no-wrap items-center",key:"append",on:this.slotsEvents},this.$scopedSlots.append())),void 0!==this.__getInnerAppend&&e.push(this.__getInnerAppendNode(t,"inner-append",this.__getInnerAppend(t))),void 0!==this.__getControlChild&&e.push(this.__getControlChild(t)),e},__getControlContainer:function(t){var e=[];return void 0!==this.prefix&&null!==this.prefix&&e.push(t("div",{staticClass:"q-field__prefix no-pointer-events row items-center"},[this.prefix])),!0===this.hasShadow&&void 0!==this.__getShadowControl&&e.push(this.__getShadowControl(t)),void 0!==this.__getControl?e.push(this.__getControl(t)):void 0!==this.$scopedSlots.rawControl?e.push(this.$scopedSlots.rawControl()):void 0!==this.$scopedSlots.control&&e.push(t("div",{ref:"target",staticClass:"q-field__native row",attrs:Object.assign({},{tabindex:-1},this.qAttrs,{"data-autofocus":this.autofocus||void 0})},this.$scopedSlots.control(this.controlSlotScope))),!0===this.hasLabel&&e.push(t("div",{staticClass:"q-field__label no-pointer-events absolute ellipsis",class:this.labelClass},[Ot(this,"label",this.label)])),void 0!==this.suffix&&null!==this.suffix&&e.push(t("div",{staticClass:"q-field__suffix no-pointer-events row items-center"},[this.suffix])),e.concat(void 0!==this.__getDefaultSlot?this.__getDefaultSlot(t):Ot(this,"default"))},__getBottom:function(t){var e,i;!0===this.hasError?(i="q--slot-error",void 0!==this.$scopedSlots.error?e=this.$scopedSlots.error(this.bottomSlotScope):void 0!==this.computedErrorMessage&&(e=[t("div",{attrs:{role:"alert"}},[this.computedErrorMessage])],i=this.computedErrorMessage)):!0===this.hideHint&&!0!==this.focused||(i="q--slot-hint",void 0!==this.$scopedSlots.hint?e=this.$scopedSlots.hint(this.bottomSlotScope):void 0!==this.hint&&(e=[t("div",[this.hint])],i=this.hint));var n=!0===this.counter||void 0!==this.$scopedSlots.counter;if(!0!==this.hideBottomSpace||!1!==n||void 0!==e){var s=t("div",{key:i,staticClass:"q-field__messages col"},e);return t("div",{staticClass:"q-field__bottom row items-start q-field__bottom--"+(!0!==this.hideBottomSpace?"animated":"stale")},[!0===this.hideBottomSpace?s:t("transition",{props:{name:"q-transition--field-message"}},[s]),!0===n?t("div",{staticClass:"q-field__counter"},void 0!==this.$scopedSlots.counter?this.$scopedSlots.counter():[this.computedCounter]):null])}},__getInnerAppendNode:function(t,e,i){return null===i?null:t("div",{staticClass:"q-field__append q-field__marginal row no-wrap items-center q-anchor--skip",key:e},i)},__onControlPopupShow:function(t){void 0!==t&&b(t),this.$emit("popup-show",t),this.hasPopupOpen=!0,this.__onControlFocusin(t)},__onControlPopupHide:function(t){void 0!==t&&b(t),this.$emit("popup-hide",t),this.hasPopupOpen=!1,this.__onControlFocusout(t)},__onControlFocusin:function(t){clearTimeout(this.focusoutTimer),!0===this.editable&&!1===this.focused&&(this.focused=!0,this.$emit("focus",t))},__onControlFocusout:function(t,e){var i=this;clearTimeout(this.focusoutTimer),this.focusoutTimer=setTimeout(function(){(!0!==document.hasFocus()||!0!==i.hasPopupOpen&&void 0!==i.$refs&&void 0!==i.$refs.control&&!1===i.$refs.control.contains(document.activeElement))&&(!0===i.focused&&(i.focused=!1,i.$emit("blur",t)),void 0!==e&&e())})},__clearValue:function(t){var e=this;(S(t),!0!==this.$q.platform.is.mobile)?(this.$refs.target||this.$el).focus():!0===this.$el.contains(document.activeElement)&&document.activeElement.blur();"file"===this.type&&(this.$refs.input.value=null),this.$emit("input",null),this.$emit("clear",this.value),this.$nextTick(function(){e.resetValidation(),!0!==e.$q.platform.is.mobile&&(e.isDirty=!1)})},__emitValue:function(t){this.$emit("input",t)}},render:function(t){void 0!==this.__onPreRender&&this.__onPreRender(),void 0!==this.__onPostRender&&this.$nextTick(this.__onPostRender);var e=void 0===this.__getControl&&void 0===this.$scopedSlots.control?Object.assign({},this.qAttrs,{"data-autofocus":this.autofocus||void 0},this.attrs):this.attrs;return t("label",{staticClass:"q-field q-validation-component row no-wrap items-start",class:this.classes,attrs:e},[void 0!==this.$scopedSlots.before?t("div",{staticClass:"q-field__before q-field__marginal row no-wrap items-center",on:this.slotsEvents},this.$scopedSlots.before()):null,t("div",{staticClass:"q-field__inner relative-position col self-stretch"},[t("div",{ref:"control",staticClass:"q-field__control relative-position row no-wrap",class:this.contentClass,attrs:{tabindex:-1},on:this.controlEvents},this.__getContent(t)),!0===this.shouldRenderBottom?this.__getBottom(t):null]),void 0!==this.$scopedSlots.after?t("div",{staticClass:"q-field__after q-field__marginal row no-wrap items-center",on:this.slotsEvents},this.$scopedSlots.after()):null])},created:function(){void 0!==this.__onPreRender&&this.__onPreRender(),this.slotsEvents={click:y},this.clearableEvents={click:this.__clearValue},this.controlEvents=void 0!==this.__getControlEvents?this.__getControlEvents():{focusin:this.__onControlFocusin,focusout:this.__onControlFocusout,"popup-show":this.__onControlPopupShow,"popup-hide":this.__onControlPopupHide}},mounted:function(){!0===n&&void 0===this.for&&(this.targetUid=Fo()),!0===this.autofocus&&this.focus()},activated:function(){!0===this.shouldActivate&&!0===this.autofocus&&this.focus()},deactivated:function(){this.shouldActivate=!0},beforeDestroy:function(){clearTimeout(this.focusoutTimer)}});function Vo(t,e,i,n){var s=[];return t.forEach(function(t){!0===n(t)?s.push(t):e.push({failedPropValidation:i,file:t})}),s}function No(t){t&&t.dataTransfer&&(t.dataTransfer.dropEffect="copy"),S(t)}var Ho={props:{multiple:Boolean,accept:String,capture:String,maxFileSize:[Number,String],maxTotalSize:[Number,String],maxFiles:[Number,String],filter:Function},computed:{extensions:function(){if(void 0!==this.accept)return this.accept.split(",").map(function(t){return"*"===(t=t.trim())?"*/":(t.endsWith("/*")&&(t=t.slice(0,t.length-1)),t.toUpperCase())})},maxFilesNumber:function(){return parseInt(this.maxFiles,10)},maxTotalSizeNumber:function(){return parseInt(this.maxTotalSize,10)}},methods:{pickFiles:function(t){if(!0===this.editable)if(t!==Object(t)&&(t={target:null}),null!==t.target&&!0===t.target.matches('input[type="file"]'))0===t.clientX&&0===t.clientY&&b(t);else{var e=this.__getFileInput();e&&e!==t.target&&e.click(t)}},addFiles:function(t){this.editable&&t&&this.__addFiles(null,t)},__processFiles:function(t,e,i,n){var s=this,o=Array.from(e||t.target.files),r=[],a=function(){r.length>0&&s.$emit("rejected",r)};if(void 0!==this.accept&&-1===this.extensions.indexOf("*/")&&0===(o=Vo(o,r,"accept",function(t){return s.extensions.some(function(e){return t.type.toUpperCase().startsWith(e)||t.name.toUpperCase().endsWith(e)})})).length)return a();if(void 0!==this.maxFileSize){var l=parseInt(this.maxFileSize,10);if(0===(o=Vo(o,r,"max-file-size",function(t){return t.size<=l})).length)return a()}!0!==this.multiple&&o.length>0&&(o=[o[0]]),o.forEach(function(t){t.__key=t.webkitRelativePath+t.lastModified+t.name+t.size});var c=i.map(function(t){return t.__key});if(0===(o=Vo(o,r,"duplicate",function(t){return!1===c.includes(t.__key)})).length)return a();if(void 0!==this.maxTotalSize){var u=!0===n?i.reduce(function(t,e){return t+e.size},0):0;if(0===(o=Vo(o,r,"max-total-size",function(t){return(u+=t.size)<=s.maxTotalSizeNumber})).length)return a()}if("function"==typeof this.filter){var h=this.filter(o);o=Vo(o,r,"filter",function(t){return h.includes(t)})}if(void 0!==this.maxFiles){var d=!0===n?i.length:0;if(0===(o=Vo(o,r,"max-files",function(){return++d<=s.maxFilesNumber})).length)return a()}return a(),o.length>0?o:void 0},__onDragOver:function(t){No(t),!0!==this.dnd&&(this.dnd=!0)},__onDragLeave:function(t){S(t),t.relatedTarget!==this.$refs.dnd&&(this.dnd=!1)},__onDrop:function(t){No(t);var e=t.dataTransfer.files;e.length>0&&this.__addFiles(null,e),this.dnd=!1},__getDnd:function(t,e){if(!0===this.dnd)return t("div",{staticClass:"q-"+e+"__dnd absolute-full",ref:"dnd",on:ft(this,"dnd",{dragenter:No,dragover:No,dragleave:this.__onDragLeave,drop:this.__onDrop})})}}},Qo={computed:{formDomProps:function(){if("file"===this.type)try{var t="DataTransfer"in window?new DataTransfer:"ClipboardEvent"in window?new ClipboardEvent("").clipboardData:void 0;return Object(this.value)===this.value&&("length"in this.value?Array.from(this.value):[this.value]).forEach(function(e){t.items.add(e)}),{files:t.files}}catch(t){return{files:void 0}}}}},Wo=t.extend({name:"QFile",mixins:[jo,Ho,Oi,Qo],props:{value:!0===i?{}:[File,FileList,Array],append:Boolean,useChips:Boolean,displayValue:[String,Number],tabindex:{type:[String,Number],default:0},counterLabel:Function,inputClass:[Array,String,Object],inputStyle:[Array,String,Object]},data:function(){return{dnd:!1}},computed:{innerValue:function(){return Object(this.value)===this.value?"length"in this.value?Array.from(this.value):[this.value]:[]},selectedString:function(){return this.innerValue.map(function(t){return t.name}).join(", ")},totalSize:function(){return lt(this.innerValue.reduce(function(t,e){return t+e.size},0))},counterProps:function(){return{totalSize:this.totalSize,filesNumber:this.innerValue.length,maxFiles:this.maxFiles}},computedCounter:function(){if(void 0!==this.counterLabel)return this.counterLabel(this.counterProps);var t=this.maxFiles;return this.innerValue.length+(void 0!==t?" / "+t:"")+" ("+this.totalSize+")"},inputAttrs:function(){return Object.assign({},{tabindex:-1,type:"file",title:"",accept:this.accept,capture:this.capture,name:this.nameProp},this.qAttrs,{id:this.targetUid,disabled:!0!==this.editable})},isAppending:function(){return!0===this.multiple&&!0===this.append},fieldClass:function(){return"q-file q-field--auto-height"+(!0===this.dnd?" q-file--dnd":"")}},methods:{removeAtIndex:function(t){var e=this.innerValue.slice();e.splice(t,1),this.__emitValue(e)},removeFile:function(t){var e=this.innerValue.findIndex(t);e>-1&&this.removeAtIndex(e)},__emitValue:function(t){this.$emit("input",!0===this.multiple?t:t[0])},__onKeydown:function(t){13===t.keyCode&&y(t)},__onKeyup:function(t){13!==t.keyCode&&32!==t.keyCode||this.pickFiles(t)},__getFileInput:function(){return this.$refs.input},__addFiles:function(t,e){var i=this,n=this.__processFiles(t,e,this.innerValue,this.isAppending);void 0!==n&&((!0===this.multiple?this.value&&n.every(function(t){return i.innerValue.includes(t)}):this.value===n[0])||this.__emitValue(!0===this.isAppending?this.innerValue.concat(n):n))},__getControl:function(t){var e={ref:"target",staticClass:"q-field__native row items-center cursor-pointer",attrs:{tabindex:this.tabindex}};return!0===this.editable&&(e.on=ft(this,"native",{dragover:this.__onDragOver,dragleave:this.__onDragLeave,keydown:this.__onKeydown,keyup:this.__onKeyup})),t("div",e,[this.__getInput(t)].concat(this.__getSelection(t)))},__getControlChild:function(t){return this.__getDnd(t,"file")},__getFiller:function(t){return[t("input",{class:[this.inputClass,"q-file__filler"],style:this.inputStyle})]},__getSelection:function(t){var e=this;if(void 0!==this.$scopedSlots.file)return 0===this.innerValue.length?this.__getFiller(t):this.innerValue.map(function(t,i){return e.$scopedSlots.file({index:i,file:t,ref:e})});if(void 0!==this.$scopedSlots.selected)return 0===this.innerValue.length?this.__getFiller(t):this.$scopedSlots.selected({files:this.innerValue,ref:this});if(!0===this.useChips)return 0===this.innerValue.length?this.__getFiller(t):this.innerValue.map(function(i,n){return t(un,{key:"file-"+n,props:{removable:e.editable,dense:!0,textColor:e.color,tabindex:e.tabindex},on:ft(e,"rem#"+n,{remove:function(){e.removeAtIndex(n)}})},[t("span",{staticClass:"ellipsis",domProps:{textContent:i.name}})])});var i=void 0!==this.displayValue?this.displayValue:this.selectedString;return i.length>0?[t("div",{style:this.inputStyle,class:this.inputClass,domProps:{textContent:i}})]:this.__getFiller(t)},__getInput:function(t){var e={ref:"input",staticClass:"q-field__input fit absolute-full cursor-pointer",attrs:this.inputAttrs,domProps:this.formDomProps,on:ft(this,"input",{change:this.__addFiles})};return!0===this.multiple&&(e.attrs.multiple=!0),t("input",e)}},created:function(){this.type="file"}}),Yo=t.extend({name:"QFooter",mixins:[Lt],inject:{layout:{default:function(){console.error("QFooter needs to be child of QLayout")}}},props:{value:{type:Boolean,default:!0},reveal:Boolean,bordered:Boolean,elevated:Boolean,heightHint:{type:[String,Number],default:50}},data:function(){return{size:parseInt(this.heightHint,10),revealed:!0,windowHeight:s||this.layout.container?0:window.innerHeight}},watch:{value:function(t){this.__update("space",t),this.__updateLocal("revealed",!0),this.layout.__animate()},offset:function(t){this.__update("offset",t)},reveal:function(t){!1===t&&this.__updateLocal("revealed",this.value)},revealed:function(t){this.layout.__animate(),this.$emit("reveal",t)},"layout.scroll":function(){this.__updateRevealed()},"layout.height":function(){this.__updateRevealed()},size:function(){this.__updateRevealed()},"$q.screen.height":function(t){!0!==this.layout.container&&this.__updateLocal("windowHeight",t)}},computed:{fixed:function(){return!0===this.reveal||this.layout.view.indexOf("F")>-1||this.$q.platform.is.ios&&!0===this.layout.container},containerHeight:function(){return!0===this.layout.container?this.layout.containerHeight:this.windowHeight},offset:function(){if(!0!==this.value)return 0;if(!0===this.fixed)return!0===this.revealed?this.size:0;var t=this.layout.scroll.position+this.containerHeight+this.size-this.layout.height;return t>0?t:0},hidden:function(){return!0!==this.value||!0===this.fixed&&!0!==this.revealed},revealOnFocus:function(){return!0===this.value&&!0===this.hidden&&!0===this.reveal},classes:function(){return(!0===this.fixed?"fixed":"absolute")+"-bottom"+(!0===this.bordered?" q-footer--bordered":"")+(!0===this.hidden?" q-footer--hidden":"")+(!0!==this.value?" q-layout--prevent-focus":"")+(!0!==this.value&&!0!==this.fixed?" hidden":"")},style:function(){var t=this.layout.rows.bottom,e={};return"l"===t[0]&&!0===this.layout.left.space&&(e[!0===this.$q.lang.rtl?"right":"left"]=this.layout.left.size+"px"),"r"===t[2]&&!0===this.layout.right.space&&(e[!0===this.$q.lang.rtl?"left":"right"]=this.layout.right.size+"px"),e},onEvents:function(){return Object.assign({},this.qListeners,{focusin:this.__onFocusin,input:b})}},render:function(t){var e=Et([t(Ln,{props:{debounce:0},on:ft(this,"resize",{resize:this.__onResize})})],this,"default");return!0===this.elevated&&e.push(t("div",{staticClass:"q-layout__shadow absolute-full overflow-hidden no-pointer-events"})),t("footer",{staticClass:"q-footer q-layout__section--marginal",class:this.classes,style:this.style,on:this.onEvents},e)},created:function(){this.layout.instances.footer=this,!0===this.value&&this.__update("size",this.size),this.__update("space",this.value),this.__update("offset",this.offset)},beforeDestroy:function(){this.layout.instances.footer===this&&(this.layout.instances.footer=void 0,this.__update("size",0),this.__update("offset",0),this.__update("space",!1))},methods:{__onResize:function(t){var e=t.height;this.__updateLocal("size",e),this.__update("size",e)},__update:function(t,e){this.layout.footer[t]!==e&&(this.layout.footer[t]=e)},__updateLocal:function(t,e){this[t]!==e&&(this[t]=e)},__updateRevealed:function(){if(!0===this.reveal){var t=this.layout.scroll,e=t.direction,i=t.position,n=t.inflexionPosition;this.__updateLocal("revealed","up"===e||i-n<100||this.layout.height-this.containerHeight-i-this.size<300)}},__onFocusin:function(t){!0===this.revealOnFocus&&this.__updateLocal("revealed",!0),this.$emit("focusin",t)}}}),Uo=t.extend({name:"QForm",mixins:[Lt],props:{autofocus:Boolean,noErrorFocus:Boolean,noResetFocus:Boolean,greedy:Boolean},computed:{onEvents:function(){return Object.assign({},this.qListeners,{submit:this.submit,reset:this.reset})}},mounted:function(){this.validateIndex=0,!0===this.autofocus&&this.focus()},activated:function(){!0===this.shouldActivate&&!0===this.autofocus&&this.focus()},deactivated:function(){this.shouldActivate=!0},methods:{validate:function(t){for(var e=this,i=[],n="boolean"==typeof t?t:!0!==this.noErrorFocus,s=++this.validateIndex,o=this.getValidationComponents().filter(function(t){return!0!==t.disable}),r=function(t,i){e.$emit("validation-"+(!0===t?"success":"error"),i)},a=function(t){var s=o[t],a=s.validate();if("function"==typeof a.then)i.push(a.then(function(t){return{valid:t,comp:s}},function(t){return{valid:!1,comp:s,err:t}}));else if(!0!==a){if(!1===e.greedy)return r(!1,s),!0===n&&"function"==typeof s.focus&&s.focus(),{v:Promise.resolve(!1)};i.push({valid:!1,comp:s})}},l=0;l-1});null!==e&&void 0!==e&&e.focus({preventScroll:!0})}})},getValidationComponents:function(){return Array.prototype.map.call(this.$el.getElementsByClassName("q-validation-component"),function(t){return t.__vue__}).filter(function(t){return void 0!==t&&"function"==typeof t.validate})}},render:function(t){return t("form",{staticClass:"q-form",on:this.onEvents},Ot(this,"default"))}}),Ko=t.extend({name:"QHeader",mixins:[Lt],inject:{layout:{default:function(){console.error("QHeader needs to be child of QLayout")}}},props:{value:{type:Boolean,default:!0},reveal:Boolean,revealOffset:{type:Number,default:250},bordered:Boolean,elevated:Boolean,heightHint:{type:[String,Number],default:50}},data:function(){return{size:parseInt(this.heightHint,10),revealed:!0}},watch:{value:function(t){this.__update("space",t),this.__updateLocal("revealed",!0),this.layout.__animate()},offset:function(t){this.__update("offset",t)},reveal:function(t){!1===t&&this.__updateLocal("revealed",this.value)},revealed:function(t){this.layout.__animate(),this.$emit("reveal",t)},"layout.scroll":function(t){!0===this.reveal&&this.__updateLocal("revealed","up"===t.direction||t.position<=this.revealOffset||t.position-t.inflexionPosition<100)}},computed:{fixed:function(){return!0===this.reveal||this.layout.view.indexOf("H")>-1||this.$q.platform.is.ios&&!0===this.layout.container},offset:function(){if(!0!==this.value)return 0;if(!0===this.fixed)return!0===this.revealed?this.size:0;var t=this.size-this.layout.scroll.position;return t>0?t:0},hidden:function(){return!0!==this.value||!0===this.fixed&&!0!==this.revealed},revealOnFocus:function(){return!0===this.value&&!0===this.hidden&&!0===this.reveal},classes:function(){return(!0===this.fixed?"fixed":"absolute")+"-top"+(!0===this.bordered?" q-header--bordered":"")+(!0===this.hidden?" q-header--hidden":"")+(!0!==this.value?" q-layout--prevent-focus":"")},style:function(){var t=this.layout.rows.top,e={};return"l"===t[0]&&!0===this.layout.left.space&&(e[!0===this.$q.lang.rtl?"right":"left"]=this.layout.left.size+"px"),"r"===t[2]&&!0===this.layout.right.space&&(e[!0===this.$q.lang.rtl?"left":"right"]=this.layout.right.size+"px"),e},onEvents:function(){return Object.assign({},this.qListeners,{focusin:this.__onFocusin,input:b})}},render:function(t){var e=Bt(this,"default",[]);return!0===this.elevated&&e.push(t("div",{staticClass:"q-layout__shadow absolute-full overflow-hidden no-pointer-events"})),e.push(t(Ln,{props:{debounce:0},on:ft(this,"resize",{resize:this.__onResize})})),t("header",{staticClass:"q-header q-layout__section--marginal",class:this.classes,style:this.style,on:this.onEvents},e)},created:function(){this.layout.instances.header=this,!0===this.value&&this.__update("size",this.size),this.__update("space",this.value),this.__update("offset",this.offset)},beforeDestroy:function(){this.layout.instances.header===this&&(this.layout.instances.header=void 0,this.__update("size",0),this.__update("offset",0),this.__update("space",!1))},methods:{__onResize:function(t){var e=t.height;this.__updateLocal("size",e),this.__update("size",e)},__update:function(t,e){this.layout.header[t]!==e&&(this.layout.header[t]=e)},__updateLocal:function(t,e){this[t]!==e&&(this[t]=e)},__onFocusin:function(t){!0===this.revealOnFocus&&this.__updateLocal("revealed",!0),this.$emit("focusin",t)}}}),Xo={props:{ratio:[String,Number]},computed:{ratioStyle:function(){var t=this.ratio||this.naturalRatio;if(void 0!==t)return{paddingBottom:100/t+"%"}}}},Go=t.extend({name:"QImg",mixins:[Lt,Xo],props:{src:String,srcset:String,sizes:String,alt:String,width:String,height:String,placeholderSrc:String,basic:Boolean,contain:Boolean,position:{type:String,default:"50% 50%"},transition:{type:String,default:"fade"},imgClass:[Array,String,Object],imgStyle:Object,nativeContextMenu:Boolean,noDefaultSpinner:Boolean,spinnerColor:String,spinnerSize:String},data:function(){return{currentSrc:"",image:null,isLoading:!!this.src,hasError:!1,naturalRatio:void 0}},watch:{src:function(){this.__load()},srcset:function(t){this.__updateWatcher(t)}},computed:{url:function(){return this.currentSrc||this.placeholderSrc||void 0},attrs:function(){var t={role:"img"};return void 0!==this.alt&&(t["aria-label"]=this.alt),t},imgContainerStyle:function(){return Object.assign({backgroundSize:!0===this.contain?"contain":"cover",backgroundPosition:this.position},this.imgStyle,{backgroundImage:'url("'+this.url+'")'})},style:function(){return{width:this.width,height:this.height}},classes:function(){return"q-img overflow-hidden"+(!0===this.nativeContextMenu?" q-img--menu":"")}},methods:{__onLoad:function(t){this.isLoading=!1,this.hasError=!1,this.__computeRatio(t),this.__updateSrc(),this.__updateWatcher(this.srcset),this.$emit("load",this.currentSrc)},__onError:function(t){clearTimeout(this.ratioTimer),this.isLoading=!1,this.hasError=!0,this.currentSrc="",this.$emit("error",t)},__updateSrc:function(){if(void 0!==this.image&&!1===this.isLoading){var t=this.image.currentSrc||this.image.src;this.currentSrc!==t&&(this.currentSrc=t)}},__updateWatcher:function(t){t?void 0===this.unwatch&&(this.unwatch=this.$watch("$q.screen.width",this.__updateSrc)):void 0!==this.unwatch&&(this.unwatch(),this.unwatch=void 0)},__load:function(){var t=this;if(clearTimeout(this.ratioTimer),this.hasError=!1,!this.src)return this.isLoading=!1,this.image=void 0,void(this.currentSrc="");this.isLoading=!0;var e=new Image;this.image=e,e.onerror=function(i){t.image===e&&!0!==t.destroyed&&t.__onError(i)},e.onload=function(){!0!==t.destroyed&&t.image===e&&(void 0!==e.decode?e.decode().catch(function(i){t.image===e&&!0!==t.destroyed&&t.__onError(i)}).then(function(){t.image===e&&!0!==t.destroyed&&t.__onLoad(e)}):t.__onLoad(e))},e.src=this.src,this.srcset&&(e.srcset=this.srcset),void 0!==this.sizes?e.sizes=this.sizes:Object.assign(e,{height:this.height,width:this.width})},__computeRatio:function(t){var e=this,i=t.naturalHeight,n=t.naturalWidth;i||n?this.naturalRatio=0===i?1:n/i:this.ratioTimer=setTimeout(function(){e.image===t&&!0!==e.destroyed&&e.__computeRatio(t)},100)},__getImage:function(t){var e=!0===this.nativeContextMenu?[t("img",{staticClass:"absolute-full fit",attrs:{src:this.url,"aria-hidden":"true"}})]:void 0,i=void 0!==this.url?t("div",{key:this.url,staticClass:"q-img__image absolute-full",class:this.imgClass,style:this.imgContainerStyle},e):null;return!0===this.basic?i:t("transition",{props:{name:"q-transition--"+this.transition}},[i])},__getContent:function(t){var e=Ot(this,!0===this.hasError?"error":"default");return!0===this.basic?t("div",{key:"content",staticClass:"q-img__content absolute-full"},e):t("transition",{props:{name:"q-transition--fade"}},[!0===this.isLoading?t("div",{key:"placeholder",staticClass:"q-img__loading absolute-full flex flex-center"},void 0!==this.$scopedSlots.loading?this.$scopedSlots.loading():!1===this.noDefaultSpinner?[t(ue,{props:{color:this.spinnerColor,size:this.spinnerSize}})]:void 0):t("div",{key:"content",staticClass:"q-img__content absolute-full"},e)])}},render:function(t){return t("div",{class:this.classes,style:this.style,attrs:this.attrs,on:Object.assign({},this.qListeners)},[t("div",{style:this.ratioStyle}),this.__getImage(t),this.__getContent(t)])},beforeMount:function(){if(void 0!==this.placeholderSrc&&void 0===this.ratio){var t=new Image;t.src=this.placeholderSrc,this.__computeRatio(t)}!0===this.isLoading&&this.__load()},beforeDestroy:function(){this.destroyed=!0,clearTimeout(this.ratioTimer),void 0!==this.unwatch&&this.unwatch()}}),Zo=h.passive,Jo=t.extend({name:"QInfiniteScroll",mixins:[Lt],props:{offset:{type:Number,default:500},debounce:{type:[String,Number],default:100},scrollTarget:{default:void 0},initialIndex:Number,disable:Boolean,reverse:Boolean},data:function(){return{index:this.initialIndex||0,isFetching:!1,isWorking:!0}},watch:{disable:function(t){!0===t?this.stop():this.resume()},reverse:function(){!1===this.isFetching&&!0===this.isWorking&&this.immediatePoll()},scrollTarget:function(){this.updateScrollTarget()},debounce:function(t){this.__setDebounce(t)}},methods:{poll:function(){if(!0!==this.disable&&!0!==this.isFetching&&!1!==this.isWorking){var t=ni(this.__scrollTarget),e=oi(this.__scrollTarget),i=de(this.__scrollTarget);!1===this.reverse?Math.round(e+i+this.offset)>=Math.round(t)&&this.trigger():Math.round(e)-1){for(var s=t-e.length;s>0;s--)i+=rr;e=e.slice(0,n)+i+e.slice(n)}return e},__updateMaskInternals:function(){var t=this;if(this.hasMask=void 0!==this.mask&&this.mask.length>0&&(!0===this.autogrow||["textarea","text","search","url","tel","password"].includes(this.type)),!1===this.hasMask)return this.computedUnmask=void 0,this.maskMarked="",void(this.maskReplaced="");var e=void 0===er[this.mask]?this.mask:er[this.mask],i="string"==typeof this.fillMask&&this.fillMask.length>0?this.fillMask.slice(0,1):"_",n=i.replace(or,"\\$&"),s=[],o=[],r=[],a=!0===this.reverseFillMask,l="",c="";e.replace(sr,function(t,e,i,n,u){if(void 0!==n){var h=ir[n];r.push(h),c=h.negate,!0===a&&(o.push("(?:"+c+"+)?("+h.pattern+"+)?(?:"+c+"+)?("+h.pattern+"+)?"),a=!1),o.push("(?:"+c+"+)?("+h.pattern+")?")}else if(void 0!==i)l="\\"+("\\"===i?"":i),r.push(i),s.push("([^"+l+"]+)?"+l+"?");else{var d=void 0!==e?e:u;l="\\"===d?"\\\\\\\\":d.replace(or,"\\\\$&"),r.push(d),s.push("([^"+l+"]+)?"+l+"?")}});var u=new RegExp("^"+s.join("")+"("+(""===l?".":"[^"+l+"]")+"+)?$"),h=o.length-1,d=o.map(function(e,i){return 0===i&&!0===t.reverseFillMask?new RegExp("^"+n+"*"+e):i===h?new RegExp("^"+e+"("+(""===c?".":c)+"+)?"+(!0===t.reverseFillMask?"$":n+"*")):new RegExp("^"+e)});this.computedMask=r,this.computedUnmask=function(t){var e=u.exec(t);null!==e&&(t=e.slice(1).join(""));for(var i=[],n=d.length,s=0,o=t;s0?i.join(""):t},this.maskMarked=r.map(function(t){return"string"==typeof t?t:rr}).join(""),this.maskReplaced=this.maskMarked.split(rr).join(i)},__updateMaskValue:function(t,e,i){var n=this,s=this.$refs.input,o=s.selectionEnd,r=s.value.length-o,a=this.__unmask(t);!0===e&&this.__updateMaskInternals();var l=this.__mask(a),c=!1!==this.fillMask?this.__fillWithMask(l):l,u=this.innerValue!==c;s.value!==c&&(s.value=c),!0===u&&(this.innerValue=c),document.activeElement===s&&this.$nextTick(function(){if(c!==n.maskReplaced)if("insertFromPaste"!==i||!0===n.reverseFillMask)if(["deleteContentBackward","deleteContentForward"].indexOf(i)>-1){var t=!0===n.reverseFillMask?0===o?c.length>l.length?1:0:Math.max(0,c.length-(c===n.maskReplaced?0:Math.min(l.length,r)+1))+1:o;s.setSelectionRange(t,t,"forward")}else if(!0===n.reverseFillMask)if(!0===u){var e=Math.max(0,c.length-(c===n.maskReplaced?0:Math.min(l.length,r+1)));1===e&&1===o?s.setSelectionRange(e,e,"forward"):n.__moveCursorRightReverse(s,e,e)}else{var a=c.length-r;s.setSelectionRange(a,a,"backward")}else if(!0===u){var h=Math.max(0,n.maskMarked.indexOf(rr),Math.min(l.length,o)-1);n.__moveCursorRight(s,h,h)}else{var d=o-1;n.__moveCursorRight(s,d,d)}else{var p=o-1;n.__moveCursorRight(s,p,p)}else{var f=!0===n.reverseFillMask?n.maskReplaced.length:0;s.setSelectionRange(f,f,"forward")}});var h=!0===this.unmaskedValue?this.__unmask(c):c;String(this.value)!==h&&this.__emitValue(h,!0)},__moveCursorForPaste:function(t,e,i){var n=this.__mask(this.__unmask(t.value));e=Math.max(0,this.maskMarked.indexOf(rr),Math.min(n.length,e)),t.setSelectionRange(e,i,"forward")},__moveCursorLeft:function(t,e,i,n){for(var s=-1===this.maskMarked.slice(e-1).indexOf(rr),o=Math.max(0,e-1);o>=0;o--)if(this.maskMarked[o]===rr){e=o,!0===s&&e++;break}if(o<0&&void 0!==this.maskMarked[e]&&this.maskMarked[e]!==rr)return this.__moveCursorRight(t,0,0);e>=0&&t.setSelectionRange(e,!0===n?i:e,"backward")},__moveCursorRight:function(t,e,i,n){for(var s=t.value.length,o=Math.min(s,i+1);o<=s;o++){if(this.maskMarked[o]===rr){i=o;break}this.maskMarked[o-1]===rr&&(i=o)}if(o>s&&void 0!==this.maskMarked[i-1]&&this.maskMarked[i-1]!==rr)return this.__moveCursorLeft(t,s,s);t.setSelectionRange(n?e:i,i,"forward")},__moveCursorLeftReverse:function(t,e,i,n){for(var s=this.__getPaddedMaskMarked(t.value.length),o=Math.max(0,e-1);o>=0;o--){if(s[o-1]===rr){e=o;break}if(s[o]===rr&&(e=o,0===o))break}if(o<0&&void 0!==s[e]&&s[e]!==rr)return this.__moveCursorRightReverse(t,0,0);e>=0&&t.setSelectionRange(e,!0===n?i:e,"backward")},__moveCursorRightReverse:function(t,e,i,n){for(var s=t.value.length,o=this.__getPaddedMaskMarked(s),r=-1===o.slice(0,i+1).indexOf(rr),a=Math.min(s,i+1);a<=s;a++)if(o[a-1]===rr){(i=a)>0&&!0===r&&i--;break}if(a>s&&void 0!==o[i-1]&&o[i-1]!==rr)return this.__moveCursorLeftReverse(t,s,s);t.setSelectionRange(!0===n?e:i,i,"forward")},__onMaskedKeydown:function(t){if(!0!==Z(t)){var e=this.$refs.input,i=e.selectionStart,n=e.selectionEnd;if(37===t.keyCode||39===t.keyCode){var s=this["__moveCursor"+(39===t.keyCode?"Right":"Left")+(!0===this.reverseFillMask?"Reverse":"")];t.preventDefault(),s(e,i,n,t.shiftKey)}else 8===t.keyCode&&!0!==this.reverseFillMask&&i===n?this.__moveCursorLeft(e,i,n,!0):46===t.keyCode&&!0===this.reverseFillMask&&i===n&&this.__moveCursorRightReverse(e,i,n,!0);this.$emit("keydown",t)}},__mask:function(t){if(void 0===t||null===t||""===t)return"";if(!0===this.reverseFillMask)return this.__maskReverse(t);for(var e=this.computedMask,i=0,n="",s=0;s=0&&n>-1;o--){var r=e[o],a=t[n];if("string"==typeof r)s=r+s,a===r&&n--;else{if(void 0===a||!r.regex.test(a))return s;do{s=(void 0!==r.transform?r.transform(a):a)+s,a=t[--n]}while(i===o&&void 0!==a&&r.regex.test(a))}}return s},__unmask:function(t){return"string"!=typeof t||void 0===this.computedUnmask?"number"==typeof t?this.computedUnmask(""+t):t:this.computedUnmask(t)},__fillWithMask:function(t){return this.maskReplaced.length-t.length<=0?t:!0===this.reverseFillMask&&t.length>0?this.maskReplaced.slice(0,-t.length)+t:t+this.maskReplaced.slice(t.length)}}},lr=/[\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uff00-\uff9f\u4e00-\u9faf\u3400-\u4dbf]/,cr=/(?:[\u3300-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\uFE30-\uFE4F]|[\uD840-\uD868\uD86A-\uD872][\uDC00-\uDFFF]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD873[\uDC00-\uDEAF]|\uD87E[\uDC00-\uDE1F])/,ur=/[\u3131-\u314e\u314f-\u3163\uac00-\ud7a3]/,hr=/[a-z0-9_ -]$/i,dr={methods:{__onComposition:function(t){if("compositionend"===t.type||"change"===t.type){if(!0!==t.target.qComposing)return;t.target.qComposing=!1,this.__onInput(t)}else if("compositionupdate"===t.type&&!0!==t.target.qComposing&&"string"==typeof t.data){!0===(!0===c.is.firefox?!1===hr.test(t.data):!0===lr.test(t.data)||!0===cr.test(t.data)||!0===ur.test(t.data))&&(t.target.qComposing=!0)}}}},pr=t.extend({name:"QInput",mixins:[jo,ar,dr,Oi,Qo,Lt],props:{value:{required:!1},shadowText:String,type:{type:String,default:"text"},debounce:[String,Number],autogrow:Boolean,inputClass:[Array,String,Object],inputStyle:[Array,String,Object]},watch:{value:function(t){if(!0===this.hasMask){if(!0===this.stopValueWatcher&&(this.stopValueWatcher=!1,String(t)===this.emitCachedValue))return;this.__updateMaskValue(t)}else this.innerValue!==t&&(this.innerValue=t,"number"===this.type&&!0===this.hasOwnProperty("tempValue")&&(!0===this.typedNumber?this.typedNumber=!1:delete this.tempValue));!0===this.autogrow&&this.$nextTick(this.__adjustHeight)},type:function(){this.$refs.input&&(this.$refs.input.value=this.value)},autogrow:function(t){if(!0===t)this.$nextTick(this.__adjustHeight);else if(this.qAttrs.rows>0&&void 0!==this.$refs.input){this.$refs.input.style.height="auto"}},dense:function(){!0===this.autogrow&&this.$nextTick(this.__adjustHeight)}},data:function(){return{innerValue:this.__getInitialMaskedValue()}},computed:{isTextarea:function(){return"textarea"===this.type||!0===this.autogrow},isTypeText:function(){return!0===this.isTextarea||["text","search","url","tel","password"].includes(this.type)},fieldClass:function(){return"q-"+(!0===this.isTextarea?"textarea":"input")+(!0===this.autogrow?" q-textarea--autogrow":"")},hasShadow:function(){return"file"!==this.type&&"string"==typeof this.shadowText&&this.shadowText.length>0},onEvents:function(){var t=Object.assign({},this.qListeners,{input:this.__onInput,paste:this.__onPaste,change:this.__onChange,blur:this.__onFinishEditing,focus:b});return t.compositionstart=t.compositionupdate=t.compositionend=this.__onComposition,!0===this.hasMask&&(t.keydown=this.__onMaskedKeydown),!0===this.autogrow&&(t.animationend=this.__adjustHeight),t},inputAttrs:function(){var t=Object.assign({},{tabindex:0,"data-autofocus":this.autofocus||void 0,rows:"textarea"===this.type?6:void 0,"aria-label":this.label,name:this.nameProp},this.qAttrs,{id:this.targetUid,type:this.type,maxlength:this.maxlength,disabled:!0===this.disable,readonly:!0===this.readonly});return!0===this.autogrow&&(t.rows=1),t}},methods:{focus:function(){var t=this;Ve(function(){var e=document.activeElement;void 0===t.$refs.input||t.$refs.input===e||null!==e&&e.id===t.targetUid||t.$refs.input.focus({preventScroll:!0})})},select:function(){void 0!==this.$refs.input&&this.$refs.input.select()},getNativeElement:function(){return this.$refs.input},__onPaste:function(t){if(!0===this.hasMask&&!0!==this.reverseFillMask){var e=t.target;this.__moveCursorForPaste(e,e.selectionStart,e.selectionEnd)}this.$emit("paste",t)},__onInput:function(t){if(t&&t.target&&!0!==t.target.qComposing)if("file"!==this.type){var e=t.target.value;if(!0===this.hasMask)this.__updateMaskValue(e,!1,t.inputType);else if(this.__emitValue(e),!0===this.isTypeText&&t.target===document.activeElement){var i=t.target,n=i.selectionStart,s=i.selectionEnd;void 0!==n&&void 0!==s&&this.$nextTick(function(){t.target===document.activeElement&&0===e.indexOf(t.target.value)&&t.target.setSelectionRange(n,s)})}!0===this.autogrow&&this.__adjustHeight()}else this.$emit("input",t.target.files)},__emitValue:function(t,e){var i=this;this.emitValueFn=function(){"number"!==i.type&&!0===i.hasOwnProperty("tempValue")&&delete i.tempValue,i.value!==t&&i.emitCachedValue!==t&&(i.emitCachedValue=t,!0===e&&(i.stopValueWatcher=!0),i.$emit("input",t),i.$nextTick(function(){i.emitCachedValue===t&&(i.emitCachedValue=NaN)})),i.emitValueFn=void 0},"number"===this.type&&(this.typedNumber=!0,this.tempValue=t),void 0!==this.debounce?(clearTimeout(this.emitTimer),this.tempValue=t,this.emitTimer=setTimeout(this.emitValueFn,this.debounce)):this.emitValueFn()},__adjustHeight:function(){var t=this.$refs.input;if(void 0!==t){var e=t.parentNode.style,i=t.style.overflow;e.marginBottom=t.scrollHeight-1+"px",t.style.height="1px",t.style.overflow="hidden",t.style.height=t.scrollHeight+"px",t.style.overflow=i,e.marginBottom=""}},__onChange:function(t){this.__onComposition(t),clearTimeout(this.emitTimer),void 0!==this.emitValueFn&&this.emitValueFn(),this.$emit("change",t)},__onFinishEditing:function(t){var e=this;void 0!==t&&b(t),clearTimeout(this.emitTimer),void 0!==this.emitValueFn&&this.emitValueFn(),this.typedNumber=!1,this.stopValueWatcher=!1,delete this.tempValue,"file"!==this.type&&setTimeout(function(){void 0!==e.$refs.input&&(e.$refs.input.value=void 0!==e.innerValue?e.innerValue:"")})},__getCurValue:function(){return!0===this.hasOwnProperty("tempValue")?this.tempValue:void 0!==this.innerValue?this.innerValue:""},__getShadowControl:function(t){return t("div",{staticClass:"q-field__native q-field__shadow absolute-bottom no-pointer-events"+(!0===this.isTextarea?"":" text-no-wrap")},[t("span",{staticClass:"invisible"},this.__getCurValue()),t("span",this.shadowText)])},__getControl:function(t){return t(!0===this.isTextarea?"textarea":"input",{ref:"input",staticClass:"q-field__native q-placeholder",style:this.inputStyle,class:this.inputClass,attrs:this.inputAttrs,on:this.onEvents,domProps:"file"!==this.type?{value:this.__getCurValue()}:this.formDomProps})}},created:function(){this.emitCachedValue=NaN},mounted:function(){!0===this.autogrow&&this.__adjustHeight()},beforeDestroy:function(){this.__onFinishEditing()}}),fr={threshold:0,root:null,rootMargin:"0px"};function mr(t,e,i){var n,s,o;"function"==typeof i?(n=i,s=fr,o=void 0===e.cfg):(n=i.handler,s=Object.assign({},fr,i.cfg),o=void 0===e.cfg||!1===Gi(e.cfg,s)),e.handler!==n&&(e.handler=n),!0===o&&(e.cfg=s,void 0!==e.observer&&e.observer.unobserve(t),e.observer=new IntersectionObserver(function(i){var n=i[0];if("function"==typeof e.handler){if(null===n.rootBounds&&(void 0!==t.__vue__?!0!==t.__vue__._inactive:!0===document.body.contains(t)))return e.observer.unobserve(t),void e.observer.observe(t);(!1===e.handler(n,e.observer)||!0===e.once&&!0===n.isIntersecting)&&vr(t)}},s),e.observer.observe(t))}function vr(t){var e=t.__qvisible;void 0!==e&&(void 0!==e.observer&&e.observer.unobserve(t),delete t.__qvisible)}var gr={name:"intersection",inserted:function(t,e){var i=e.modifiers,n=e.value;void 0!==t.__qvisible&&(vr(t),t.__qvisible_destroyed=!0);var s={once:!0===i.once};mr(t,s,n),t.__qvisible=s},update:function(t,e){var i=t.__qvisible;void 0!==i&&mr(t,i,e.value)},unbind:function(t){void 0===t.__qvisible_destroyed?vr(t):delete t.__qvisible_destroyed}},_r=t.extend({name:"QIntersection",mixins:[$t,Lt],directives:{Intersection:gr},props:{once:Boolean,transition:String,ssrPrerender:Boolean,margin:String,threshold:[Number,Array],root:{default:null},disable:Boolean},data:function(){return{showing:!0===s&&this.ssrPrerender}},computed:{value:function(){return void 0!==this.root||void 0!==this.margin||void 0!==this.threshold?{handler:this.__trigger,cfg:{root:this.root,rootMargin:this.margin,threshold:this.threshold}}:this.__trigger},directives:function(){if(!0!==this.disable&&(!0!==s||!0!==this.once||!0!==this.ssrPrerender))return[{name:"intersection",value:this.value,modifiers:{once:this.once}}]}},methods:{__trigger:function(t){this.showing!==t.isIntersecting&&(this.showing=t.isIntersecting,void 0!==this.qListeners.visibility&&this.$emit("visibility",this.showing))}},render:function(t){var e=!0===this.showing?[t("div",{key:"content"},Ot(this,"default"))]:void 0;return t(this.tag,{staticClass:"q-intersection",on:Object.assign({},this.qListeners),directives:this.directives},this.transition?[t("transition",{props:{name:"q-transition--"+this.transition}},e)]:e)}}),br=[34,37,40,33,39,38],yr=t.extend({name:"QKnob",mixins:[{props:pn.options.props},Li],directives:{TouchPan:xn},props:{innerMin:Number,innerMax:Number,step:{type:Number,default:1,validator:function(t){return t>=0}},tabindex:{type:[Number,String],default:0},disable:Boolean,readonly:Boolean},data:function(){var t=this.__getInnerMin(this.innerMin),e=this.__getInnerMax(this.innerMax);return{model:null===this.value?t:ut(this.value,t,e),dragging:!1}},watch:{modelUpdate:function(){this.model=null===this.value?this.computedInnerMin:ut(this.value,this.computedInnerMin,this.computedInnerMax),this.__updateValue(!0)}},computed:{classes:function(){return"q-knob non-selectable"+(!0===this.editable?" q-knob--editable":!0===this.disable?" disabled":"")},computedInnerMin:function(){return this.__getInnerMin(this.innerMin)},computedInnerMax:function(){return this.__getInnerMax(this.innerMax)},modelUpdate:function(){return this.value+"|"+this.computedInnerMin+"|"+this.computedInnerMax},editable:function(){return!1===this.disable&&!1===this.readonly},decimals:function(){return(String(this.step).trim("0").split(".")[1]||"").length},computedStep:function(){return 0===this.step?1:this.step},computedInstantFeedback:function(){return!0===this.instantFeedback||!0===this.dragging},onEvents:function(){return!0===this.$q.platform.is.mobile?{click:this.__click}:{mousedown:this.__activate,click:this.__click,keydown:this.__keydown,keyup:this.__keyup}},attrs:function(){var t={role:"slider","aria-valuemin":this.computedInnerMin,"aria-valuemax":this.computedInnerMax,"aria-valuenow":this.value};return!0===this.editable?t.tabindex=this.tabindex:t["aria-"+(!0===this.disable?"disabled":"readonly")]="",t}},methods:{__getInnerMin:function(t){return!0===isNaN(t)||this.innerMinthis.max?this.max:this.innerMax},__updateCenterPosition:function(){var t=this.$el.getBoundingClientRect(),e=t.top,i=t.left,n=t.width,s=t.height;this.centerPosition={top:e+s/2,left:i+n/2}},__pan:function(t){t.isFinal?(this.__updatePosition(t.evt,!0),this.dragging=!1):t.isFirst?(this.__updateCenterPosition(),this.dragging=!0,this.__updatePosition(t.evt)):this.__updatePosition(t.evt)},__click:function(t){this.__updateCenterPosition(),this.__updatePosition(t,!0)},__keydown:function(t){if(br.includes(t.keyCode)){S(t);var e=([34,33].includes(t.keyCode)?10:1)*this.computedStep,i=[34,37,40].includes(t.keyCode)?-e:e;this.model=ut(parseFloat((this.model+i).toFixed(this.decimals)),this.computedInnerMin,this.computedInnerMax),this.__updateValue()}},__keyup:function(t){br.includes(t.keyCode)&&this.__updateValue(!0)},__activate:function(t){this.__updateCenterPosition(),this.__updatePosition(t)},__updatePosition:function(t,e){var i=this.centerPosition,n=m(t),s=Math.abs(n.top-i.top),o=Math.sqrt(Math.pow(s,2)+Math.pow(Math.abs(n.left-i.left),2)),r=Math.asin(s/o)*(180/Math.PI);r=n.top=l/2?(c<0?-1:1)*l:0),a=parseFloat(a.toFixed(this.decimals))}a=ut(a,this.computedInnerMin,this.computedInnerMax),this.$emit("drag-value",a),this.model!==a&&(this.model=a),this.__updateValue(e)},__updateValue:function(t){this.value!==this.model&&this.$emit("input",this.model),!0===t&&this.$emit("change",this.model)},__getNameInput:function(){return this.$createElement("input",{attrs:this.formAttrs})}},render:function(t){var e={class:this.classes,attrs:this.attrs,props:Object.assign({},this.$props,{value:this.model,instantFeedback:this.computedInstantFeedback})};return!0===this.editable&&(e.on=this.onEvents,e.directives=ft(this,"dir",[{name:"touch-pan",value:this.__pan,modifiers:{prevent:!0,stop:!0,mouse:!0}}]),void 0!==this.name&&(e.scopedSlots={internal:this.__getNameInput})),t(pn,e,Ot(this,"default"))}}),Sr=h.passive,wr=t.extend({name:"QScrollObserver",props:{debounce:[String,Number],horizontal:Boolean,scrollTarget:{default:void 0}},render:p,data:function(){return{pos:0,dir:!0===this.horizontal?"right":"down",dirChanged:!1,dirChangePos:0}},watch:{scrollTarget:function(){this.__unconfigureScrollTarget(),this.__configureScrollTarget()}},methods:{getPosition:function(){return{position:this.pos,direction:this.dir,directionChanged:this.dirChanged,inflexionPosition:this.dirChangePos}},trigger:function(t){var e=this;if(!0===t||0===this.debounce||"0"===this.debounce)this.__emit();else if(void 0===this.clearTimer){var i=this.debounce?[setTimeout(this.__emit,this.debounce),clearTimeout]:[requestAnimationFrame(this.__emit),cancelAnimationFrame],n=i[0],s=i[1];this.clearTimer=function(){s(n),e.clearTimer=void 0}}},__emit:function(){void 0!==this.clearTimer&&this.clearTimer();var t=!0===this.horizontal?ri:oi,e=Math.max(0,t(this.__scrollTarget)),i=e-this.pos,n=!0===this.horizontal?i<0?"left":"right":i<0?"up":"down";this.dirChanged=this.dir!==n,this.dirChanged&&(this.dir=n,this.dirChangePos=this.pos),this.pos=e,this.$emit("scroll",this.getPosition())},__configureScrollTarget:function(){this.__scrollTarget=ii(this.$el.parentNode,this.scrollTarget),this.__scrollTarget.addEventListener("scroll",this.trigger,Sr),this.trigger(!0)},__unconfigureScrollTarget:function(){void 0!==this.__scrollTarget&&(this.__scrollTarget.removeEventListener("scroll",this.trigger,Sr),this.__scrollTarget=void 0)}},mounted:function(){this.__configureScrollTarget()},beforeDestroy:function(){void 0!==this.clearTimer&&this.clearTimer(),this.__unconfigureScrollTarget()}}),Cr=t.extend({name:"QLayout",mixins:[Lt],provide:function(){return{layout:this}},props:{container:Boolean,view:{type:String,default:"hhh lpr fff",validator:function(t){return/^(h|l)h(h|r) lpr (f|l)f(f|r)$/.test(t.toLowerCase())}}},data:function(){return{height:this.$q.screen.height,width:!0===this.container?0:this.$q.screen.width,containerHeight:0,scrollbarWidth:!0===s?0:mi(),header:{size:0,offset:0,space:!1},right:{size:300,offset:0,space:!1},footer:{size:0,offset:0,space:!1},left:{size:300,offset:0,space:!1},scroll:{position:0,direction:"down"}}},computed:{rows:function(){var t=this.view.toLowerCase().split(" ");return{top:t[0].split(""),middle:t[1].split(""),bottom:t[2].split("")}},style:function(){return!0===this.container?null:{minHeight:this.$q.screen.height+"px"}},targetStyle:function(){var t;if(0!==this.scrollbarWidth)return(t={})[!0===this.$q.lang.rtl?"left":"right"]=this.scrollbarWidth+"px",t},targetChildStyle:function(){var t;if(0!==this.scrollbarWidth)return(t={})[!0===this.$q.lang.rtl?"right":"left"]=0,t[!0===this.$q.lang.rtl?"left":"right"]="-"+this.scrollbarWidth+"px",t.width="calc(100% + "+this.scrollbarWidth+"px)",t},totalWidth:function(){return this.width+this.scrollbarWidth},classes:function(){return"q-layout q-layout--"+(!0===this.container?"containerized":"standard")},scrollbarEvtAction:function(){return!0!==this.container&&this.scrollbarWidth>0?"add":"remove"}},watch:{scrollbarEvtAction:"__updateScrollEvent"},created:function(){this.instances={}},mounted:function(){"add"===this.scrollbarEvtAction&&this.__updateScrollEvent("add")},beforeDestroy:function(){"add"===this.scrollbarEvtAction&&this.__updateScrollEvent("remove")},render:function(t){var e=t("div",{class:this.classes,style:this.style,attrs:{tabindex:-1},on:Object.assign({},this.qListeners)},Et([t(wr,{on:ft(this,"scroll",{scroll:this.__onPageScroll})}),t(Ln,{on:ft(this,"resizeOut",{resize:this.__onPageResize})})],this,"default"));return!0===this.container?t("div",{staticClass:"q-layout-container overflow-hidden"},[t(Ln,{on:ft(this,"resizeIn",{resize:this.__onContainerResize})}),t("div",{staticClass:"absolute-full",style:this.targetStyle},[t("div",{staticClass:"scroll",style:this.targetChildStyle},[e])])]):e},methods:{__animate:function(){var t=this;void 0!==this.timer?clearTimeout(this.timer):document.body.classList.add("q-body--layout-animate"),this.timer=setTimeout(function(){document.body.classList.remove("q-body--layout-animate"),t.timer=void 0},150)},__onPageScroll:function(t){!0!==this.container&&!0===document.qScrollPrevented||(this.scroll=t),void 0!==this.qListeners.scroll&&this.$emit("scroll",t)},__onPageResize:function(t){var e=t.height,i=t.width,n=!1;this.height!==e&&(n=!0,this.height=e,void 0!==this.qListeners["scroll-height"]&&this.$emit("scroll-height",e),this.__updateScrollbarWidth()),this.width!==i&&(n=!0,this.width=i),!0===n&&void 0!==this.qListeners.resize&&this.$emit("resize",{height:e,width:i})},__onContainerResize:function(t){var e=t.height;this.containerHeight!==e&&(this.containerHeight=e,this.__updateScrollbarWidth())},__updateScrollbarWidth:function(){if(!0===this.container){var t=this.height>this.containerHeight?mi():0;this.scrollbarWidth!==t&&(this.scrollbarWidth=t)}},__updateScrollEvent:function(t){void 0!==this.timerScrollbar&&"remove"===t&&(clearTimeout(this.timerScrollbar),this.__restoreScrollbar()),window[t+"EventListener"]("resize",this.__hideScrollbar)},__hideScrollbar:function(){if(void 0===this.timerScrollbar){var t=document.body;if(t.scrollHeight>this.$q.screen.height)return;t.classList.add("hide-scrollbar")}else clearTimeout(this.timerScrollbar);this.timerScrollbar=setTimeout(this.__restoreScrollbar,200)},__restoreScrollbar:function(){this.timerScrollbar=void 0,document.body.classList.remove("hide-scrollbar")}}}),xr=t.extend({name:"QMarkupTable",mixins:[Gt,Lt],props:{dense:Boolean,flat:Boolean,bordered:Boolean,square:Boolean,separator:{type:String,default:"horizontal",validator:function(t){return["horizontal","vertical","cell","none"].includes(t)}},wrapCells:Boolean},computed:{classes:function(){return"q-table--"+this.separator+"-separator"+(!0===this.isDark?" q-table--dark q-table__card--dark q-dark":"")+(!0===this.dense?" q-table--dense":"")+(!0===this.flat?" q-table--flat":"")+(!0===this.bordered?" q-table--bordered":"")+(!0===this.square?" q-table--square":"")+(!1===this.wrapCells?" q-table--no-wrap":"")}},render:function(t){return t("div",{staticClass:"q-markup-table q-table__container q-table__card",class:this.classes,on:Object.assign({},this.qListeners)},[t("table",{staticClass:"q-table"},Ot(this,"default"))])}}),kr=t.extend({name:"QNoSsr",mixins:[$n,$t,Lt],props:{placeholder:String},render:function(t){var e={on:Object.assign({},this.qListeners)};if(!0===this.canRender){var i=Ot(this,"default");return void 0===i?i:i.length>1?t(this.tag,e,i):i[0]}e.staticClass="q-no-ssr-placeholder";var n=Ot(this,"placeholder");return void 0!==n?n.length>1?t(this.tag,e,n):n[0]:void 0!==this.placeholder?t(this.tag,e,[this.placeholder]):void 0}}),qr=t.extend({name:"QRadio",mixins:[Gt,rn,Li,an],props:{value:{required:!0},val:{required:!0},label:String,leftLabel:Boolean,checkedIcon:String,uncheckedIcon:String,color:String,keepColor:Boolean,dense:Boolean,disable:Boolean,tabindex:[String,Number]},computed:{isTrue:function(){return this.value===this.val},classes:function(){return"q-radio cursor-pointer no-outline row inline no-wrap items-center"+(!0===this.disable?" disabled":"")+(!0===this.isDark?" q-radio--dark":"")+(!0===this.dense?" q-radio--dense":"")+(!0===this.leftLabel?" reverse":"")},innerClass:function(){var t=void 0===this.color||!0!==this.keepColor&&!0!==this.isTrue?"":" text-"+this.color;return"q-radio__inner--"+(!0===this.isTrue?"truthy":"falsy")+t},computedIcon:function(){return!0===this.isTrue?this.checkedIcon:this.uncheckedIcon},computedTabindex:function(){return!0===this.disable?-1:this.tabindex||0},formAttrs:function(){var t={type:"radio"};return void 0!==this.name&&Object.assign(t,{name:this.name,value:this.val}),t},formDomProps:function(){if(void 0!==this.name&&!0===this.isTrue)return{checked:!0}},attrs:function(){var t={tabindex:this.computedTabindex,role:"radio","aria-label":this.label,"aria-checked":!0===this.isTrue?"true":"false"};return!0===this.disable&&(t["aria-disabled"]="true"),t}},methods:{set:function(t){void 0!==t&&(S(t),this.__refocusTarget(t)),!0!==this.disable&&!0!==this.isTrue&&this.$emit("input",this.val,t)}},render:function(t){var e=this,i=void 0!==this.computedIcon?[t("div",{key:"icon",staticClass:"q-radio__icon-container absolute-full flex flex-center no-wrap"},[t(Ut,{staticClass:"q-radio__icon",props:{name:this.computedIcon}})])]:[t("svg",{key:"svg",staticClass:"q-radio__bg absolute non-selectable",attrs:{focusable:"false",viewBox:"0 0 24 24","aria-hidden":"true"}},[t("path",{attrs:{d:"M12,22a10,10 0 0 1 -10,-10a10,10 0 0 1 10,-10a10,10 0 0 1 10,10a10,10 0 0 1 -10,10m0,-22a12,12 0 0 0 -12,12a12,12 0 0 0 12,12a12,12 0 0 0 12,-12a12,12 0 0 0 -12,-12"}}),t("path",{staticClass:"q-radio__check",attrs:{d:"M12,6a6,6 0 0 0 -6,6a6,6 0 0 0 6,6a6,6 0 0 0 6,-6a6,6 0 0 0 -6,-6"}})])];!0!==this.disable&&this.__injectFormInput(i,"unshift","q-radio__native q-ma-none q-pa-none");var n=[t("div",{staticClass:"q-radio__inner relative-position",class:this.innerClass,style:this.sizeStyle},i)];void 0!==this.__refocusTargetEl&&n.push(this.__refocusTargetEl);var s=void 0!==this.label?Et([this.label],this,"default"):Ot(this,"default");return void 0!==s&&n.push(t("div",{staticClass:"q-radio__label q-anchor--skip"},s)),t("div",{class:this.classes,attrs:this.attrs,on:ft(this,"inpExt",{click:this.set,keydown:function(t){13!==t.keyCode&&32!==t.keyCode||S(t)},keyup:function(t){13!==t.keyCode&&32!==t.keyCode||e.set(t)}})},n)}}),Tr=t.extend({name:"QToggle",mixins:[ln],props:{icon:String,iconColor:String},computed:{computedIcon:function(){return(!0===this.isTrue?this.checkedIcon:!0===this.isIndeterminate?this.indeterminateIcon:this.uncheckedIcon)||this.icon},computedIconColor:function(){if(!0===this.isTrue)return this.iconColor}},methods:{__getInner:function(t){return[t("div",{staticClass:"q-toggle__track"}),t("div",{staticClass:"q-toggle__thumb absolute flex flex-center no-wrap"},void 0!==this.computedIcon?[t(Ut,{props:{name:this.computedIcon,color:this.computedIconColor}})]:void 0)]}},created:function(){this.type="toggle"}}),Mr={radio:qr,checkbox:cn,toggle:Tr},$r=Object.keys(Mr),Lr=t.extend({name:"QOptionGroup",mixins:[Gt,Lt],props:{value:{required:!0},options:{type:Array,validator:function(t){return t.every(function(t){return"value"in t&&"label"in t})}},name:String,type:{default:"radio",validator:function(t){return $r.includes(t)}},color:String,keepColor:Boolean,dense:Boolean,size:String,leftLabel:Boolean,inline:Boolean,disable:Boolean},computed:{component:function(){return Mr[this.type]},model:function(){return Array.isArray(this.value)?this.value.slice():this.value},classes:function(){return"q-option-group q-gutter-x-sm"+(!0===this.inline?" q-option-group--inline":"")},attrs:function(){if("radio"===this.type){var t={role:"radiogroup"};return!0===this.disable&&(t["aria-disabled"]="true"),t}}},methods:{__update:function(t){this.$emit("input",t)}},created:function(){var t=Array.isArray(this.value);"radio"===this.type?t&&console.error("q-option-group: model should not be array"):!1===t&&console.error("q-option-group: model should be array in your case")},render:function(t){var e=this;return t("div",{class:this.classes,attrs:this.attrs,on:Object.assign({},this.qListeners)},this.options.map(function(i,n){var s=void 0!==e.$scopedSlots["label-"+n]?e.$scopedSlots["label-"+n](i):void 0!==e.$scopedSlots.label?e.$scopedSlots.label(i):void 0;return t("div",[t(e.component,{props:{value:e.value,val:i.value,name:void 0===i.name?e.name:i.name,disable:e.disable||i.disable,label:void 0===s?i.label:void 0,leftLabel:void 0===i.leftLabel?e.leftLabel:i.leftLabel,color:void 0===i.color?e.color:i.color,checkedIcon:i.checkedIcon,uncheckedIcon:i.uncheckedIcon,dark:i.dark||e.isDark,size:void 0===i.size?e.size:i.size,dense:e.dense,keepColor:void 0===i.keepColor?e.keepColor:i.keepColor},on:ft(e,"inp",{input:e.__update})},s)])}))}}),Or=t.extend({name:"QPage",mixins:[Lt],inject:{pageContainer:{default:function(){console.error("QPage needs to be child of QPageContainer")}},layout:{}},props:{padding:Boolean,styleFn:Function},computed:{style:function(){var t=(!0===this.layout.header.space?this.layout.header.size:0)+(!0===this.layout.footer.space?this.layout.footer.size:0);if("function"==typeof this.styleFn){var e=!0===this.layout.container?this.layout.containerHeight:this.$q.screen.height;return this.styleFn(t,e)}return{minHeight:!0===this.layout.container?this.layout.containerHeight-t+"px":0===this.$q.screen.height?"calc(100vh - "+t+"px)":this.$q.screen.height-t+"px"}},classes:function(){if(!0===this.padding)return"q-layout-padding"}},render:function(t){return t("main",{staticClass:"q-page",style:this.style,class:this.classes,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),Br=t.extend({name:"QPageContainer",mixins:[Lt],inject:{layout:{default:function(){console.error("QPageContainer needs to be child of QLayout")}}},provide:{pageContainer:!0},computed:{style:function(){var t={};return!0===this.layout.header.space&&(t.paddingTop=this.layout.header.size+"px"),!0===this.layout.right.space&&(t["padding"+(!0===this.$q.lang.rtl?"Left":"Right")]=this.layout.right.size+"px"),!0===this.layout.footer.space&&(t.paddingBottom=this.layout.footer.size+"px"),!0===this.layout.left.space&&(t["padding"+(!0===this.$q.lang.rtl?"Right":"Left")]=this.layout.left.size+"px"),t}},render:function(t){return t("div",{staticClass:"q-page-container",style:this.style,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),Er=t.extend({name:"QPageSticky",mixins:[Lt],inject:{layout:{default:function(){console.error("QPageSticky needs to be child of QLayout")}}},props:{position:{type:String,default:"bottom-right",validator:function(t){return["top-right","top-left","bottom-right","bottom-left","top","right","bottom","left"].includes(t)}},offset:{type:Array,validator:function(t){return 2===t.length}},expand:Boolean},computed:{attach:function(){var t=this.position;return{top:t.indexOf("top")>-1,right:t.indexOf("right")>-1,bottom:t.indexOf("bottom")>-1,left:t.indexOf("left")>-1,vertical:"top"===t||"bottom"===t,horizontal:"left"===t||"right"===t}},top:function(){return this.layout.header.offset},right:function(){return this.layout.right.offset},bottom:function(){return this.layout.footer.offset},left:function(){return this.layout.left.offset},style:function(){var t=0,e=0,i=this.attach,n=!0===this.$q.lang.rtl?-1:1;!0===i.top&&0!==this.top?e=this.top+"px":!0===i.bottom&&0!==this.bottom&&(e=-this.bottom+"px"),!0===i.left&&0!==this.left?t=n*this.left+"px":!0===i.right&&0!==this.right&&(t=-n*this.right+"px");var s={transform:"translate("+t+", "+e+")"};return this.offset&&(s.margin=this.offset[1]+"px "+this.offset[0]+"px"),!0===i.vertical?(0!==this.left&&(s[!0===this.$q.lang.rtl?"right":"left"]=this.left+"px"),0!==this.right&&(s[!0===this.$q.lang.rtl?"left":"right"]=this.right+"px")):!0===i.horizontal&&(0!==this.top&&(s.top=this.top+"px"),0!==this.bottom&&(s.bottom=this.bottom+"px")),s},classes:function(){return"fixed-"+this.position+" q-page-sticky--"+(!0===this.expand?"expand":"shrink")}},render:function(t){var e=Ot(this,"default");return t("div",{staticClass:"q-page-sticky row flex-center",class:this.classes,style:this.style,on:Object.assign({},this.qListeners)},!0===this.expand?e:[t("div",e)])}}),zr=t.extend({name:"QPageScroller",mixins:[Er],props:{scrollOffset:{type:Number,default:1e3},reverse:Boolean,duration:{type:Number,default:300},offset:{default:function(){return[18,18]}}},inject:{layout:{default:function(){console.error("QPageScroller needs to be used within a QLayout")}}},data:function(){return{showing:this.__isVisible()}},computed:{scrollHeight:function(){return this.layout.height-(!0===this.layout.container?this.layout.containerHeight:this.$q.screen.height)},onEvents:function(){return Object.assign({},this.qListeners,{click:this.__onClick})}},watch:{"layout.scroll.position":function(){this.__updateVisibility()},reverse:{handler:function(t){!0===t?void 0===this.heightWatcher&&(this.heightWatcher=this.$watch("scrollHeight",this.__updateVisibility)):void 0!==this.heightWatcher&&this.__cleanup()},immediate:!0}},methods:{__isVisible:function(){return!0===this.reverse?this.scrollHeight-this.layout.scroll.position>this.scrollOffset:this.layout.scroll.position>this.scrollOffset},__onClick:function(t){var e=ii(!0===this.layout.container?this.$el:this.layout.$el);pi(e,!0===this.reverse?this.layout.height:0,this.duration),this.$emit("click",t)},__updateVisibility:function(){var t=this.__isVisible();this.showing!==t&&(this.showing=t)},__cleanup:function(){this.heightWatcher(),this.heightWatcher=void 0}},render:function(t){return t("transition",{props:{name:"q-transition--fade"}},!0===this.showing?[t("div",{staticClass:"q-page-scroller",on:this.onEvents},[Er.options.render.call(this,t)])]:null)},beforeDestroy:function(){void 0!==this.heightWatcher&&this.__cleanup()}}),Pr=t.extend({name:"QPagination",mixins:[Gt,Lt],props:{value:{type:Number,required:!0},min:{type:Number,default:1},max:{type:Number,required:!0},color:{type:String,default:"primary"},textColor:String,activeColor:String,activeTextColor:String,inputStyle:[Array,String,Object],inputClass:[Array,String,Object],size:String,disable:Boolean,input:Boolean,iconPrev:String,iconNext:String,iconFirst:String,iconLast:String,toFn:Function,boundaryLinks:{type:Boolean,default:null},boundaryNumbers:{type:Boolean,default:null},directionLinks:{type:Boolean,default:null},ellipses:{type:Boolean,default:null},maxPages:{type:Number,default:0,validator:function(t){return t>=0}},ripple:{type:[Boolean,Object],default:null},round:Boolean,rounded:Boolean,flat:Boolean,outline:Boolean,unelevated:Boolean,push:Boolean,glossy:Boolean,dense:Boolean,padding:{type:String,default:"3px 2px"}},data:function(){return{newPage:null}},watch:{min:function(){this.model=this.value},max:function(){this.model=this.value}},computed:{model:{get:function(){return this.value},set:function(t){if(t=parseInt(t,10),!this.disable&&!isNaN(t)){var e=ut(t,this.min,this.max);this.$emit("input",e)}}},inputPlaceholder:function(){return this.model+" / "+this.max},__boundaryLinks:function(){return this.__getBool(this.boundaryLinks,this.input)},__boundaryNumbers:function(){return this.__getBool(this.boundaryNumbers,!this.input)},__directionLinks:function(){return this.__getBool(this.directionLinks,this.input)},__ellipses:function(){return this.__getBool(this.ellipses,!this.input)},icons:function(){var t=[this.iconFirst||this.$q.iconSet.pagination.first,this.iconPrev||this.$q.iconSet.pagination.prev,this.iconNext||this.$q.iconSet.pagination.next,this.iconLast||this.$q.iconSet.pagination.last];return!0===this.$q.lang.rtl?t.reverse():t},attrs:function(){if(!0===this.disable)return{"aria-disabled":"true"}},btnProps:function(){return{round:this.round,rounded:this.rounded,outline:this.outline,unelevated:this.unelevated,push:this.push,glossy:this.glossy,dense:this.dense,padding:this.padding,color:this.color,flat:!0,size:this.size,ripple:null===this.ripple||this.ripple}},activeBtnProps:function(){return{flat:this.flat,color:this.activeColor||this.color,textColor:this.activeTextColor||this.textColor}}},methods:{set:function(t){this.model=t},setByOffset:function(t){this.model=this.model+t},__update:function(){this.model=this.newPage,this.newPage=null},__getBool:function(t,e){return[!0,!1].includes(t)?t:e},__getBtn:function(t,e,i,n){var s=this;return e.props=Object.assign({},this.btnProps,i),void 0!==n&&(void 0!==this.toFn?e.props.to=this.toFn(n):e.on={click:function(){return s.set(n)}}),t(Be,e)}},render:function(t){var e=this,i=[],n=[],s=[];if(this.__boundaryLinks&&(i.push(this.__getBtn(t,{key:"bls"},{disable:this.disable||this.value<=this.min,icon:this.icons[0]},this.min)),n.unshift(this.__getBtn(t,{key:"ble"},{disable:this.disable||this.value>=this.max,icon:this.icons[3]},this.max))),this.__directionLinks&&(i.push(this.__getBtn(t,{key:"bdp"},{disable:this.disable||this.value<=this.min,icon:this.icons[1]},this.value-1)),n.unshift(this.__getBtn(t,{key:"bdn"},{disable:this.disable||this.value>=this.max,icon:this.icons[2]},this.value+1))),!0===this.input)s.push(t(pr,{staticClass:"inline",style:{width:this.inputPlaceholder.length/1.5+"em"},props:{type:"number",dense:!0,value:this.newPage,disable:this.disable,dark:this.isDark,borderless:!0,inputClass:this.inputClass,inputStyle:this.inputStyle},attrs:{placeholder:this.inputPlaceholder,min:this.min,max:this.max},on:ft(this,"inp",{input:function(t){e.newPage=t},keyup:function(t){!0===J(t,13)&&e.__update()},blur:this.__update})}));else{var o=Math.max(this.maxPages,1+(this.__ellipses?2:0)+(this.__boundaryNumbers?2:0)),r=this.min,a=this.max,l=!1,c=!1,u=!1,h=!1;this.maxPages&&othis.min+(this.__boundaryNumbers?1:0)&&(l=!0,r+=1),this.__boundaryNumbers&&(h=!0,a-=1),this.__ellipses&&a=0&&t<=1}},scrollTarget:{default:void 0}},data:function(){return{scrolling:!1,percentScrolled:0}},watch:{height:function(){!0===this.working&&this.__updatePos()},scrollTarget:function(){!0===this.working&&(this.__stop(),this.__start())}},methods:{__update:function(t){this.percentScrolled=t,void 0!==this.qListeners.scroll&&this.$emit("scroll",t)},__updatePos:function(){var t,e,i;this.__scrollTarget===window?(t=0,i=e=window.innerHeight):i=(t=he(this.__scrollTarget).top)+(e=de(this.__scrollTarget));var n=he(this.$el).top,s=n+this.height;if(void 0!==this.observer||s>t&&n20?"pulled":"pull";this.state!==o&&(this.state=o)}else!0===this.pulling&&(this.pulling=!1,"pulled"===this.state?(this.state="refreshing",this.__animateTo({pos:20}),this.trigger()):"pull"===this.state&&this.__animateTo({pos:-40,ratio:0}))},__animateTo:function(t,e){var i=this,n=t.pos,s=t.ratio;this.animating=!0,this.pullPosition=n,void 0!==s&&(this.pullRatio=s),clearTimeout(this.timer),this.timer=setTimeout(function(){i.animating=!1,e&&e()},300)}},mounted:function(){this.updateScrollTarget()},beforeDestroy:function(){clearTimeout(this.timer)},render:function(t){return t("div",{staticClass:"q-pull-to-refresh",on:Object.assign({},this.qListeners),directives:this.directives},[t("div",{class:this.contentClass},Ot(this,"default")),t("div",{staticClass:"q-pull-to-refresh__puller-container fixed row flex-center no-pointer-events z-top",style:this.positionCSS},[t("div",{style:this.style,class:this.classes},["refreshing"!==this.state?t(Ut,{props:{name:this.icon||this.$q.iconSet.pullToRefresh.icon,color:this.color,size:"32px"}}):t(ue,{props:{size:"24px",color:this.color}})])])])}}),Qr=0,Wr=1,Yr=2,Ur=t.extend({name:"QRange",mixins:[Tn],props:{value:{type:Object,default:function(){return{min:null,max:null}},validator:function(t){return"min"in t&&"max"in t}},dragRange:Boolean,dragOnlyRange:Boolean,leftLabelColor:String,leftLabelTextColor:String,rightLabelColor:String,rightLabelTextColor:String,leftLabelValue:[String,Number],rightLabelValue:[String,Number],leftThumbColor:String,rightThumbColor:String},data:function(){var t=this.__getInnerMin(this.innerMin),e=this.__getInnerMax(this.innerMax);return{model:{min:null===this.value.min?t:ut(this.value.min,t,e),max:null===this.value.max?e:ut(this.value.max,t,e)},curMinRatio:0,curMaxRatio:0}},computed:{modelMinRatio:function(){return this.__convertModelToRatio(this.model.min)},modelMaxRatio:function(){return this.__convertModelToRatio(this.model.max)},ratioMin:function(){return!0===this.active?this.curMinRatio:this.modelMinRatio},ratioMax:function(){return!0===this.active?this.curMaxRatio:this.modelMaxRatio},selectionBarStyle:function(){var t={};return t[this.positionProp]=100*this.ratioMin+"%",t[this.sizeProp]=100*(this.ratioMax-this.ratioMin)+"%",void 0!==this.selectionImg&&(t.backgroundImage="url("+this.selectionImg+") !important"),t},trackContainerEvents:function(){var t=this;if(!0!==this.editable)return{};if(!0===this.$q.platform.is.mobile)return{click:this.__onMobileClick};var e={mousedown:this.__onActivate};return!0!==this.dragRange&&!0!==this.dragOnlyRange||Object.assign(e,{focus:function(){t.focus="both"},blur:this.__onBlur,keydown:this.__onKeydown,keyup:this.__onKeyup}),e},trackContainerAttrs:function(){return{tabindex:!0===this.$q.platform.is.mobile||!this.dragRange&&!0!==this.dragOnlyRange?null:this.computedTabindex}},thumbAttrs:function(){return{tabindex:!0!==this.dragOnlyRange?this.computedTabindex:null}},thumbMinEvents:function(){return this.__getEvents("min")},thumbMaxEvents:function(){return this.__getEvents("max")},thumbMinLabel:function(){return void 0!==this.leftLabelValue?this.leftLabelValue:this.model.min},thumbMaxLabel:function(){return void 0!==this.rightLabelValue?this.rightLabelValue:this.model.max},thumbMinClasses:function(){var t=this.leftThumbColor||this.thumbColor||this.color;return"q-slider__thumb q-slider__thumb"+this.axis+" q-slider__thumb"+this.axis+"-"+(!0===this.isReversed?"rtl":"ltr")+" absolute non-selectable"+(!1!==this.preventFocus||"min"!==this.focus&&"both"!==this.focus?"":" q-slider--focus")+(void 0!==t?" text-"+t:"")},thumbMaxClasses:function(){var t=this.rightThumbColor||this.thumbColor||this.color;return"q-slider__thumb q-slider__thumb"+this.axis+" q-slider__thumb"+this.axis+"-"+(!0===this.isReversed?"rtl":"ltr")+" absolute non-selectable"+(!1!==this.preventFocus||"max"!==this.focus&&"both"!==this.focus?"":" q-slider--focus")+(void 0!==t?" text-"+t:"")},thumbMinStyle:function(){var t;return(t={width:this.thumbSize,height:this.thumbSize})[this.positionProp]=100*this.ratioMin+"%",t.zIndex="min"===this.focus?2:void 0,t},thumbMaxStyle:function(){var t;return(t={width:this.thumbSize,height:this.thumbSize})[this.positionProp]=100*this.ratioMax+"%",t.zIndex="max"===this.focus?2:void 0,t},thumbMinPinColor:function(){var t=this.leftLabelColor||this.labelColor;return void 0!==t?" text-"+t:""},thumbMaxPinColor:function(){var t=this.rightLabelColor||this.labelColor;return void 0!==t?" text-"+t:""},thumbMinTextContainerStyle:function(){return this.__getTextContainerStyle(this.ratioMin)},thumbMaxTextContainerStyle:function(){return this.__getTextContainerStyle(this.ratioMax)},thumbMinTextClass:function(){var t=this.leftLabelTextColor||this.labelTextColor;return"q-slider__text"+(void 0!==t?" text-"+t:"")},thumbMaxTextClass:function(){var t=this.rightLabelTextColor||this.labelTextColor;return"q-slider__text"+(void 0!==t?" text-"+t:"")},formAttrs:function(){return{type:"hidden",name:this.name,value:this.value.min+"|"+this.value.max}},modelUpdate:function(){return this.value.min+"|"+this.value.max+"|"+this.computedInnerMin+"|"+this.computedInnerMax}},watch:{modelUpdate:function(){this.model.min=null===this.value.min?this.computedInnerMin:ut(this.value.min,this.computedInnerMin,this.computedInnerMax),this.model.max=null===this.value.max?this.computedInnerMax:ut(this.value.max,this.computedInnerMin,this.computedInnerMax)}},methods:{__updateValue:function(t){this.model.min===this.value.min&&this.model.max===this.value.max||this.$emit("input",Object.assign({},this.model)),!0===t&&this.$emit("change",Object.assign({},this.model))},__getDragging:function(t){var e=this.$el.getBoundingClientRect(),i=e.left,n=e.top,s=e.width,o=e.height,r=!0===this.dragOnlyRange?0:!0===this.vertical?this.$refs.minThumb.offsetHeight/(2*o):this.$refs.minThumb.offsetWidth/(2*s),a={left:i,top:n,width:s,height:o,valueMin:this.model.min,valueMax:this.model.max,ratioMin:this.modelMinRatio,ratioMax:this.modelMaxRatio},l=this.__getDraggingRatio(t,a);return!0!==this.dragOnlyRange&&l=e.ratioMin?(i={minR:e.ratioMin,maxR:n,min:e.valueMin,max:s},this.focus="max"):(i={minR:n,maxR:e.ratioMin,min:s,max:e.valueMin},this.focus="min");break;case Wr:var o=n-e.offsetRatio,r=ut(e.ratioMin+o,0,1-e.rangeRatio),a=s-e.offsetModel,l=ut(e.valueMin+a,this.min,this.max-e.rangeValue);i={minR:r,maxR:r+e.rangeRatio,min:parseFloat(l.toFixed(this.computedDecimals)),max:parseFloat((l+e.rangeValue).toFixed(this.computedDecimals))},this.focus="both"}this.model=null===this.model.min||null===this.model.max?{min:i.min||this.min,max:i.max||this.max}:{min:i.min,max:i.max},!0!==this.snap||0===this.step?(this.curMinRatio=i.minR,this.curMaxRatio=i.maxR):(this.curMinRatio=this.__convertModelToRatio(this.model.min),this.curMaxRatio=this.__convertModelToRatio(this.model.max))},__getEvents:function(t){var e=this;return!0!==this.$q.platform.is.mobile&&!0===this.editable&&!0!==this.dragOnlyRange?{focus:function(){e.focus=t},blur:this.__onBlur,keydown:this.__onKeydown,keyup:this.__onKeyup}:{}},__onKeydown:function(t){var e;if(qn.includes(t.keyCode)){S(t);var i=([34,33].includes(t.keyCode)?10:1)*this.computedStep,n=([34,37,40].includes(t.keyCode)?-1:1)*(!0===this.isReversed?-1:1)*i;if("both"===this.focus){var s=this.model.max-this.model.min,o=ut(parseFloat((this.model.min+n).toFixed(this.computedDecimals)),this.computedInnerMin,this.computedInnerMax-s);this.model={min:o,max:parseFloat((o+s).toFixed(this.computedDecimals))}}else{if(!1===this.focus)return;var r=this.focus;this.model=Object.assign({},this.model,((e={})[r]=ut(parseFloat((this.model[r]+n).toFixed(this.computedDecimals)),"min"===r?this.computedInnerMin:this.model.min,"max"===r?this.computedInnerMax:this.model.max),e))}this.__updateValue()}}},render:function(t){var e=this,i=this.__getContent(t,function(i){i.push(e.__getThumb(t,{pinColor:e.thumbMinPinColor,textContainerStyle:e.thumbMinTextContainerStyle,textClass:e.thumbMinTextClass,label:e.thumbMinLabel,classes:e.thumbMinClasses,style:e.thumbMinStyle,nodeData:{ref:"minThumb",key:"tmin",on:e.thumbMinEvents,attrs:e.thumbAttrs}}),e.__getThumb(t,{pinColor:e.thumbMaxPinColor,textContainerStyle:e.thumbMaxTextContainerStyle,textClass:e.thumbMaxTextClass,label:e.thumbMaxLabel,classes:e.thumbMaxClasses,style:e.thumbMaxStyle,nodeData:{key:"tmax",on:e.thumbMaxEvents,attrs:e.thumbAttrs}}))});return t("div",{class:"q-range "+this.classes+(null===this.value.min||null===this.value.max?" q-slider--no-value":""),attrs:Object.assign({},this.attributes,{"aria-valuenow":this.value.min+"|"+this.value.max})},i)}}),Kr=t.extend({name:"QRating",mixins:[Mt,Li,Lt],props:{value:{type:Number,required:!0},max:{type:[String,Number],default:5},icon:[String,Array],iconHalf:[String,Array],iconSelected:[String,Array],color:[String,Array],colorHalf:[String,Array],colorSelected:[String,Array],noReset:Boolean,noDimming:Boolean,readonly:Boolean,disable:Boolean},data:function(){return{mouseModel:0}},computed:{editable:function(){return!0!==this.readonly&&!0!==this.disable},classes:function(){return"q-rating--"+(!0===this.editable?"":"non-")+"editable"+(!0===this.noDimming?" q-rating--no-dimming":"")+(!0===this.disable?" disabled":"")+(void 0!==this.color&&!1===Array.isArray(this.color)?" text-"+this.color:"")},iconData:function(){var t=!0===Array.isArray(this.icon)?this.icon.length:0,e=!0===Array.isArray(this.iconSelected)?this.iconSelected.length:0,i=!0===Array.isArray(this.iconHalf)?this.iconHalf.length:0,n=!0===Array.isArray(this.color)?this.color.length:0,s=!0===Array.isArray(this.colorSelected)?this.colorSelected.length:0,o=!0===Array.isArray(this.colorHalf)?this.colorHalf.length:0;return{iconLen:t,icon:t>0?this.icon[t-1]:this.icon,selIconLen:e,selIcon:e>0?this.iconSelected[e-1]:this.iconSelected,halfIconLen:i,halfIcon:i>0?this.iconHalf[e-1]:this.iconHalf,colorLen:n,color:n>0?this.color[n-1]:this.color,selColorLen:s,selColor:s>0?this.colorSelected[s-1]:this.colorSelected,halfColorLen:o,halfColor:o>0?this.colorHalf[o-1]:this.colorHalf}},stars:function(){for(var t=[],e=this.iconData,i=Math.ceil(this.value),n=void 0===this.iconHalf||i===this.value?-1:i,s=1;s<=this.max;s++){var o=0===this.mouseModel&&this.value>=s||this.mouseModel>0&&this.mouseModel>=s,r=n===s&&this.mouseModel0&&(!0===r?i:this.value)>=s&&this.mouseModel=250?50:Math.ceil(t/5)},Zr=["vertical","horizontal"],Jr={vertical:{offset:"offsetY",scroll:"scrollTop",dir:"down",dist:"y"},horizontal:{offset:"offsetX",scroll:"scrollLeft",dir:"right",dist:"x"}},ta=t.extend({name:"QScrollArea",mixins:[Gt],directives:{TouchPan:xn},props:{thumbStyle:Object,verticalThumbStyle:Object,horizontalThumbStyle:Object,barStyle:[Array,String,Object],verticalBarStyle:[Array,String,Object],horizontalBarStyle:[Array,String,Object],contentStyle:[Array,String,Object],contentActiveStyle:[Array,String,Object],delay:{type:[String,Number],default:1e3},visible:{type:Boolean,default:null},horizontal:Boolean,tabindex:[String,Number]},data:function(){return{tempShowing:!1,panning:!1,hover:!1,container:{vertical:0,horizontal:0},scroll:{vertical:{position:0,size:0},horizontal:{position:0,size:0}}}},computed:{classes:function(){return"q-scrollarea"+(!0===this.isDark?" q-scrollarea--dark":"")},verticalScrollPercentage:function(){var t=this.scroll.vertical.size-this.container.vertical;if(t<=0)return 0;var e=ut(this.scroll.vertical.position/t,0,1);return Math.round(1e4*e)/1e4},horizontalScrollPercentage:function(){var t=this.scroll.horizontal.size-this.container.horizontal;if(t<=0)return 0;var e=ut(this.scroll.horizontal.position/t,0,1);return Math.round(1e4*e)/1e4},verticalThumbHidden:function(){return!0!==(null===this.visible?this.hover:this.visible)&&!1===this.tempShowing&&!1===this.panning||this.scroll.vertical.size<=this.container.vertical+1},horizontalThumbHidden:function(){return!0!==(null===this.visible?this.hover:this.visible)&&!1===this.tempShowing&&!1===this.panning||this.scroll.horizontal.size<=this.container.horizontal+1},verticalThumbStart:function(){return this.verticalScrollPercentage*(this.container.vertical-this.verticalThumbSize)},horizontalThumbStart:function(){return this.horizontalScrollPercentage*(this.container.horizontal-this.horizontalThumbSize)},verticalThumbSize:function(){return Math.round(ut(this.container.vertical*this.container.vertical/this.scroll.vertical.size,Gr(this.container.vertical),this.container.vertical))},horizontalThumbSize:function(){return Math.round(ut(this.container.horizontal*this.container.horizontal/this.scroll.horizontal.size,Gr(this.container.horizontal),this.container.horizontal))},verticalStyle:function(){return Object.assign({},this.thumbStyle,this.verticalThumbStyle,{top:this.verticalThumbStart+"px",height:this.verticalThumbSize+"px"})},horizontalStyle:function(){return Object.assign({},this.thumbStyle,this.horizontalThumbStyle,{left:this.horizontalThumbStart+"px",width:this.horizontalThumbSize+"px"})},verticalThumbClass:function(){return"q-scrollarea__thumb q-scrollarea__thumb--v absolute-right"+(!0===this.verticalThumbHidden?" q-scrollarea__thumb--invisible":"")},horizontalThumbClass:function(){return"q-scrollarea__thumb q-scrollarea__thumb--h absolute-bottom"+(!0===this.horizontalThumbHidden?" q-scrollarea__thumb--invisible":"")},verticalBarClass:function(){return"q-scrollarea__bar q-scrollarea__bar--v absolute-right"+(!0===this.verticalThumbHidden?" q-scrollarea__bar--invisible":"")},horizontalBarClass:function(){return"q-scrollarea__bar q-scrollarea__bar--h absolute-bottom"+(!0===this.horizontalThumbHidden?" q-scrollarea__bar--invisible":"")},scrollComputed:function(){return{vertical:Object.assign({},this.scroll.vertical,{percentage:this.verticalScrollPercentage,thumbHidden:this.verticalThumbHidden,thumbStart:this.verticalThumbStart,thumbSize:this.verticalThumbSize,style:this.verticalStyle,thumbClass:this.verticalThumbClass,barClass:this.verticalBarClass}),horizontal:Object.assign({},this.scroll.horizontal,{percentage:this.horizontalScrollPercentage,thumbHidden:this.horizontalThumbHidden,thumbStart:this.horizontalThumbStart,thumbSize:this.horizontalThumbSize,style:this.horizontalStyle,thumbClass:this.horizontalThumbClass,barClass:this.horizontalBarClass})}},mainStyle:function(){return!0===this.verticalThumbHidden&&!0===this.horizontalThumbHidden?this.contentStyle:this.contentActiveStyle},verticalThumbDirectives:function(){var t=this;return[{name:"touch-pan",modifiers:{vertical:!0,prevent:!0,mouse:!0,mouseAllDir:!0},value:function(e){t.__panThumb(e,"vertical")}}]},horizontalThumbDirectives:function(){var t=this;return[{name:"touch-pan",modifiers:{horizontal:!0,prevent:!0,mouse:!0,mouseAllDir:!0},value:function(e){t.__panThumb(e,"horizontal")}}]},scrollAttrs:function(){if(void 0!==this.tabindex)return{tabindex:this.tabindex}}},methods:{getScrollTarget:function(){return this.$refs.target},getScroll:function(){var t=this,e={};return Zr.forEach(function(i){var n=t.scrollComputed[i];e[i+"Position"]=n.position,e[i+"Percentage"]=n.percentage,e[i+"Size"]=n.size,e[i+"ContainerSize"]=t.container[i]}),e},getScrollPosition:function(t){return"both"===t?{top:this.scroll.vertical.position,left:this.scroll.horizontal.position}:(!0!==Zr.includes(t)&&(t=!0===this.horizontal?"horizontal":"vertical"),this.scroll[t].position)},getScrollPercentage:function(t){return"both"===t?{top:this.verticalScrollPercentage,left:this.horizontalScrollPercentage}:(!0!==Zr.includes(t)&&(t=!0===this.horizontal?"horizontal":"vertical"),this[t+"ScrollPercentage"])},setScrollPosition:function(t,e,i){var n;if(!1===Zr.includes(t)){if(!0===isNaN(t))return void console.error("[QScrollArea]: wrong first param of setScrollPosition (vertical/horizontal)");t=(n=[!0===this.horizontal?"horizontal":"vertical",t,e])[0],e=n[1],i=n[2]}("vertical"===t?hi:fi)(this.$refs.target,e,i)},setScrollPercentage:function(t,e,i){var n;if(!1===Zr.includes(t)){if(!0===isNaN(t))return void console.error("[QScrollArea]: wrong first param of setScrollPercentage (vertical/horizontal)");t=(n=[!0===this.horizontal?"horizontal":"vertical",t,e])[0],e=n[1],i=n[2]}this.setScrollPosition(t,e*(this.scroll[t].size-this.container[t]),i)},__updateContainer:function(t){var e=t.height,i=t.width,n=!1;this.container.vertical!==e&&(this.container.vertical=e,n=!0),this.container.horizontal!==i&&(this.container.horizontal=i,n=!0),!0===n&&this.__startTimer()},__updateVerticalScroll:function(t){var e=t.position;this.scroll.vertical.position!==e&&(this.scroll.vertical.position=e,this.__startTimer())},__updateHorizontalScroll:function(t){var e=t.position;this.scroll.horizontal.position!==e&&(this.scroll.horizontal.position=e,this.__startTimer())},__updateScrollSize:function(t){var e=t.height,i=t.width,n=!1;this.scroll.horizontal.size!==i&&(this.scroll.horizontal.size=i,n=!0),this.scroll.vertical.size!==e&&(this.scroll.vertical.size=e,n=!0),!0===n&&this.__startTimer()},__panThumb:function(t,e){var i=this.scrollComputed[e];if(!0===t.isFinal){if(!0!==this.panning)return;this.panning=!1}else if(!0===t.isFirst){if(!0===i.thumbHidden)return;this.refPos=i.position,this.panning=!0}else if(!0!==this.panning)return;var n=Jr[e],s=this.container[e],o=(i.size-s)/(s-i.thumbSize),r=t.distance[n.dist],a=this.refPos+(t.direction===n.dir?1:-1)*r*o;this.__setScroll(a,e)},__mouseDown:function(t,e){var i=this.scrollComputed[e];if(!0!==i.thumbHidden){var n=t[Jr[e].offset];if(ni.thumbStart+i.thumbSize){var s=n-i.thumbSize/2;this.__setScroll(s/this.container[e]*i.size,e)}var o="vertical"===e?this.$refs.verticalThumb:this.$refs.horizontalThumb;void 0!==o&&o.dispatchEvent(new MouseEvent(t.type,t))}},__verticalMouseDown:function(t){this.__mouseDown(t,"vertical")},__horizontalMouseDown:function(t){this.__mouseDown(t,"horizontal")},__startTimer:function(){var t=this;!0===this.tempShowing?clearTimeout(this.timer):this.tempShowing=!0,this.timer=setTimeout(function(){t.tempShowing=!1},this.delay),void 0!==this.$listeners.scroll&&this.__emitScroll()},__setScroll:function(t,e){this.$refs.target[Jr[e].scroll]=t},__mouseEnter:function(){this.hover=!0},__mouseLeave:function(){this.hover=!1}},render:function(t){return t("div",{class:this.classes,on:ft(this,"desk",{mouseenter:this.__mouseEnter,mouseleave:this.__mouseLeave})},[t("div",{ref:"target",staticClass:"q-scrollarea__container scroll relative-position fit hide-scrollbar",attrs:this.scrollAttrs},[t("div",{staticClass:"q-scrollarea__content absolute",style:this.mainStyle},Et([t(Ln,{props:{debounce:0},on:ft(this,"resizeIn",{resize:this.__updateScrollSize})})],this,"default")),t(wr,{on:ft(this,"scrollV",{scroll:this.__updateVerticalScroll})}),t(wr,{props:{horizontal:!0},on:ft(this,"scrollH",{scroll:this.__updateHorizontalScroll})})]),t(Ln,{props:{debounce:0},on:ft(this,"resizeOut",{resize:this.__updateContainer})}),t("div",{class:this.verticalBarClass,style:[this.barStyle,this.verticalBarStyle],attrs:gt,on:ft(this,"barV",{mousedown:this.__verticalMouseDown})}),t("div",{class:this.horizontalBarClass,style:[this.barStyle,this.horizontalBarStyle],attrs:gt,on:ft(this,"barH",{mousedown:this.__horizontalMouseDown})}),t("div",{ref:"verticalThumb",class:this.verticalThumbClass,style:this.verticalStyle,attrs:gt,directives:this.verticalThumbDirectives}),t("div",{ref:"horizontalThumb",class:this.horizontalThumbClass,style:this.horizontalStyle,attrs:gt,directives:this.horizontalThumbDirectives})])},created:function(){var t=this;this.__emitScroll=T(function(){var e=t.getScroll();e.ref=t,t.$emit("scroll",e)},0)},activated:function(){if(void 0!==this.__scrollPosition){var t=this.getScrollTarget();void 0!==t&&(fi(t,this.__scrollPosition.left),hi(t,this.__scrollPosition.top))}},deactivated:function(){this.__scrollPosition=this.getScrollPosition("both")},beforeDestroy:function(){this.__emitScroll.cancel(),clearTimeout(this.timer)}}),ea=1e3,ia=["start","center","end","start-force","center-force","end-force"],na=Array.prototype.filter;function sa(t,e){return t+e}function oa(t,e,i,n,s,o,r,a){var l=t===window?document.scrollingElement||document.documentElement:t,c=!0===s?"offsetWidth":"offsetHeight",u={scrollStart:0,scrollViewSize:-r-a,scrollMaxSize:0,offsetStart:-r,offsetEnd:-a};if(!0===s?(t===window?(u.scrollStart=window.pageXOffset||window.scrollX||document.body.scrollLeft||0,u.scrollViewSize+=document.documentElement.clientWidth):(u.scrollStart=l.scrollLeft,u.scrollViewSize+=l.clientWidth),u.scrollMaxSize=l.scrollWidth,!0===o&&(u.scrollStart=(!0===ei()?u.scrollMaxSize-u.scrollViewSize:0)-u.scrollStart)):(t===window?(u.scrollStart=window.pageYOffset||window.scrollY||document.body.scrollTop||0,u.scrollViewSize+=document.documentElement.clientHeight):(u.scrollStart=l.scrollTop,u.scrollViewSize+=l.clientHeight),u.scrollMaxSize=l.scrollHeight),void 0!==i)for(var h=i.previousElementSibling;null!==h;h=h.previousElementSibling)!1===h.classList.contains("q-virtual-scroll--skip")&&(u.offsetStart+=h[c]);if(void 0!==n)for(var d=n.nextElementSibling;null!==d;d=d.nextElementSibling)!1===d.classList.contains("q-virtual-scroll--skip")&&(u.offsetEnd+=d[c]);if(e!==t){var p=l.getBoundingClientRect(),f=e.getBoundingClientRect();!0===s?(u.offsetStart+=f.left-p.left,u.offsetEnd-=f.width):(u.offsetStart+=f.top-p.top,u.offsetEnd-=f.height),t!==window&&(u.offsetStart+=u.scrollStart),u.offsetEnd+=u.scrollMaxSize-u.offsetStart}return u}function ra(t,e,i,n){"end"===e&&(e=(t===window?document.body:t)[!0===i?"scrollWidth":"scrollHeight"]),t===window?!0===i?(!0===n&&(e=(!0===ei()?document.body.scrollWidth-document.documentElement.clientWidth:0)-e),window.scrollTo(e,window.pageYOffset||window.scrollY||document.body.scrollTop||0)):window.scrollTo(window.pageXOffset||window.scrollX||document.body.scrollLeft||0,e):!0===i?(!0===n&&(e=(!0===ei()?t.scrollWidth-t.offsetWidth:0)-e),t.scrollLeft=e):t.scrollTop=e}function aa(t,e,i,n){if(i>=n)return 0;var s=e.length,o=Math.floor(i/ea),r=Math.floor((n-1)/ea)+1,a=t.slice(o,r).reduce(sa,0);return i%ea!=0&&(a-=e.slice(o*ea,i).reduce(sa,0)),n%ea!=0&&n!==s&&(a-=e.slice(n,r*ea).reduce(sa,0)),a}var la={virtualScrollSliceSize:{type:[Number,String],default:null},virtualScrollSliceRatioBefore:{type:[Number,String],default:1},virtualScrollSliceRatioAfter:{type:[Number,String],default:1},virtualScrollItemSize:{type:[Number,String],default:24},virtualScrollStickySizeStart:{type:[Number,String],default:0},virtualScrollStickySizeEnd:{type:[Number,String],default:0},tableColspan:[Number,String]};var ca=Object.keys(la),ua={props:Object.assign({},{virtualScrollHorizontal:Boolean},la),data:function(){return{virtualScrollSliceRange:{from:0,to:0}}},watch:{needsSliceRecalc:function(){this.__setVirtualScrollSize()},needsReset:function(){this.reset()}},computed:{needsReset:function(){var t=this;return["virtualScrollItemSizeComputed","virtualScrollHorizontal"].map(function(e){return t[e]}).join(";")},needsSliceRecalc:function(){var t=this;return this.needsReset+";"+["virtualScrollSliceRatioBefore","virtualScrollSliceRatioAfter"].map(function(e){return t[e]}).join(";")},colspanAttr:function(){return void 0!==this.tableColspan?{colspan:this.tableColspan}:{colspan:100}},virtualScrollItemSizeComputed:function(){return this.virtualScrollItemSize}},methods:{reset:function(){this.__resetVirtualScroll(this.prevToIndex,!0)},refresh:function(t){this.__resetVirtualScroll(void 0===t?this.prevToIndex:t)},scrollTo:function(t,e){var i=this.__getVirtualScrollTarget();if(void 0!==i&&null!==i&&8!==i.nodeType){var n=oa(i,this.__getVirtualScrollEl(),this.$refs.before,this.$refs.after,this.virtualScrollHorizontal,this.$q.lang.rtl,this.virtualScrollStickySizeStart,this.virtualScrollStickySizeEnd);this.__scrollViewSize!==n.scrollViewSize&&this.__setVirtualScrollSize(n.scrollViewSize),this.__setVirtualScrollSliceRange(i,n,Math.min(this.virtualScrollLength-1,Math.max(0,parseInt(t,10)||0)),0,ia.indexOf(e)>-1?e:this.prevToIndex>-1&&t>this.prevToIndex?"end":"start")}},__onVirtualScrollEvt:function(){var t=this.__getVirtualScrollTarget();if(void 0!==t&&null!==t&&8!==t.nodeType){var e=oa(t,this.__getVirtualScrollEl(),this.$refs.before,this.$refs.after,this.virtualScrollHorizontal,this.$q.lang.rtl,this.virtualScrollStickySizeStart,this.virtualScrollStickySizeEnd),i=this.virtualScrollLength-1,n=e.scrollMaxSize-e.offsetStart-e.offsetEnd-this.virtualScrollPaddingAfter;if(this.prevScrollStart!==e.scrollStart)if(e.scrollMaxSize<=0)this.__setVirtualScrollSliceRange(t,e,0,0);else{this.__scrollViewSize!==e.scrollViewSize&&this.__setVirtualScrollSize(e.scrollViewSize),this.__updateVirtualScrollSizes(this.virtualScrollSliceRange.from);var s=Math.floor(e.scrollMaxSize-Math.max(e.scrollViewSize,e.offsetEnd)-Math.min(this.virtualScrollSizes[i],e.scrollViewSize/2));if(s>0&&Math.ceil(e.scrollStart)>=s)this.__setVirtualScrollSliceRange(t,e,i,e.scrollMaxSize-e.offsetEnd-this.virtualScrollSizesAgg.reduce(sa,0));else{var o=0,r=e.scrollStart-e.offsetStart,a=r;if(r<=n&&r+e.scrollViewSize>=this.virtualScrollPaddingBefore)r-=this.virtualScrollPaddingBefore,o=this.virtualScrollSliceRange.from,a=r;else for(var l=0;r>=this.virtualScrollSizesAgg[l]&&o0&&o-e.scrollViewSize?(o++,a=r):a=this.virtualScrollSizes[o]+r;this.__setVirtualScrollSliceRange(t,e,o,a)}}}},__setVirtualScrollSliceRange:function(t,e,i,n,s){var o=this,r="string"==typeof s&&s.indexOf("-force")>-1,a=!0===r?s.replace("-force",""):s,l=void 0!==a?a:"start",c=Math.max(0,i-this.virtualScrollSliceSizeComputed[l]),u=c+this.virtualScrollSliceSizeComputed.total;u>this.virtualScrollLength&&(u=this.virtualScrollLength,c=Math.max(0,u-this.virtualScrollSliceSizeComputed.total)),this.prevScrollStart=e.scrollStart;var h=c!==this.virtualScrollSliceRange.from||u!==this.virtualScrollSliceRange.to;if(!1!==h||void 0!==a){var d=document.activeElement,p=this.$refs.content;!0===h&&void 0!==p&&p!==d&&!0===p.contains(d)&&(p.addEventListener("focusout",this.__onBlurRefocusFn),setTimeout(function(){void 0!==p&&p.removeEventListener("focusout",o.__onBlurRefocusFn)})),function t(e,i){void 0===t.isSupported&&(t.isSupported=void 0!==window.getComputedStyle(document.body).overflowAnchor),!1!==t.isSupported&&void 0!==e&&(cancelAnimationFrame(e._qOverflowAnimationFrame),e._qOverflowAnimationFrame=requestAnimationFrame(function(){if(void 0!==e){var t=e.children||[];na.call(t,function(t){return t.dataset&&void 0!==t.dataset.qVsAnchor}).forEach(function(t){delete t.dataset.qVsAnchor});var n=t[i];n&&n.dataset&&(n.dataset.qVsAnchor="")}}))}(p,i-c);var f=void 0!==a?this.virtualScrollSizes.slice(c,i).reduce(sa,0):0;if(!0===h){var m=u>=this.virtualScrollSliceRange.from&&c<=this.virtualScrollSliceRange.to?this.virtualScrollSliceRange.to:u;this.virtualScrollSliceRange={from:c,to:m},this.virtualScrollPaddingBefore=aa(this.virtualScrollSizesAgg,this.virtualScrollSizes,0,c),this.virtualScrollPaddingAfter=aa(this.virtualScrollSizesAgg,this.virtualScrollSizes,this.virtualScrollSliceRange.to,this.virtualScrollLength),requestAnimationFrame(function(){o.virtualScrollSliceRange.to!==u&&o.prevScrollStart===e.scrollStart&&(o.virtualScrollSliceRange={from:o.virtualScrollSliceRange.from,to:u},o.virtualScrollPaddingAfter=aa(o.virtualScrollSizesAgg,o.virtualScrollSizes,u,o.virtualScrollLength))})}requestAnimationFrame(function(){if(o.prevScrollStart===e.scrollStart){!0===h&&o.__updateVirtualScrollSizes(c);var s=o.virtualScrollSizes.slice(c,i).reduce(sa,0),l=s+e.offsetStart+o.virtualScrollPaddingBefore,u=l+o.virtualScrollSizes[i],d=l+n;if(void 0!==a){var p=s-f,m=e.scrollStart+p;d=!0!==r&&m=s;o--)this.virtualScrollSizes[o]=n;var r=Math.floor((this.virtualScrollLength-1)/ea);this.virtualScrollSizesAgg=[];for(var a=0;a<=r;a++){for(var l=0,c=Math.min((a+1)*ea,this.virtualScrollLength),u=a*ea;u=0?(this.__updateVirtualScrollSizes(this.virtualScrollSliceRange.from),this.$nextTick(function(){i.scrollTo(t)})):this.__onVirtualScrollEvt()},__setVirtualScrollSize:function(t){if(void 0===t&&"undefined"!=typeof window){var e=this.__getVirtualScrollTarget();void 0!==e&&null!==e&&8!==e.nodeType&&(t=oa(e,this.__getVirtualScrollEl(),this.$refs.before,this.$refs.after,this.virtualScrollHorizontal,this.$q.lang.rtl,this.virtualScrollStickySizeStart,this.virtualScrollStickySizeEnd).scrollViewSize)}this.__scrollViewSize=t;var i=parseFloat(this.virtualScrollSliceRatioBefore)||0,n=1+i+(parseFloat(this.virtualScrollSliceRatioAfter)||0),s=void 0===t||t<=0?1:Math.ceil(t/this.virtualScrollItemSizeComputed),o=Math.max(1,s,Math.ceil((this.virtualScrollSliceSize>0?this.virtualScrollSliceSize:10)/n));this.virtualScrollSliceSizeComputed={total:Math.ceil(o*n),start:Math.ceil(o*i),center:Math.ceil(o*(.5+i)),end:Math.ceil(o*(1+i)),view:s}},__padVirtualScroll:function(t,e,i){var n,s,o,r,a=!0===this.virtualScrollHorizontal?"width":"height",l={};return l["--q-virtual-scroll-item-"+a]=this.virtualScrollItemSizeComputed+"px",["tbody"===e?t(e,{staticClass:"q-virtual-scroll__padding",key:"before",ref:"before"},[t("tr",[t("td",{style:Object.assign((n={},n[a]=this.virtualScrollPaddingBefore+"px",n),l),attrs:this.colspanAttr})])]):t(e,{staticClass:"q-virtual-scroll__padding",key:"before",ref:"before",style:Object.assign((s={},s[a]=this.virtualScrollPaddingBefore+"px",s),l)}),t(e,{staticClass:"q-virtual-scroll__content",key:"content",ref:"content",attrs:{tabindex:-1}},i),"tbody"===e?t(e,{staticClass:"q-virtual-scroll__padding",key:"after",ref:"after"},[t("tr",[t("td",{style:Object.assign((o={},o[a]=this.virtualScrollPaddingAfter+"px",o),l),attrs:this.colspanAttr})])]):t(e,{staticClass:"q-virtual-scroll__padding",key:"after",ref:"after",style:Object.assign((r={},r[a]=this.virtualScrollPaddingAfter+"px",r),l)})]},__emitScroll:function(t){this.prevToIndex!==t&&(void 0!==this.qListeners["virtual-scroll"]&&this.$emit("virtual-scroll",{index:t,from:this.virtualScrollSliceRange.from,to:this.virtualScrollSliceRange.to-1,direction:te?i.__resetVirtualScroll():i.__updateMenu(!0))}))}},computed:{isOptionsDark:function(){return null===this.optionsDark?this.isDark:this.optionsDark},virtualScrollLength:function(){return Array.isArray(this.options)?this.options.length:0},fieldClass:function(){return"q-select q-field--auto-height q-select--with"+(!0!==this.useInput?"out":"")+"-input q-select--with"+(!0!==this.useChips?"out":"")+"-chips q-select--"+(!0===this.multiple?"multiple":"single")},computedInputClass:function(){return!0===this.hideSelected||0===this.innerValue.length?this.inputClass:void 0===this.inputClass?"q-field__input--padding":[this.inputClass,"q-field__input--padding"]},menuContentClass:function(){return(!0===this.virtualScrollHorizontal?"q-virtual-scroll--horizontal":"")+(this.popupContentClass?" "+this.popupContentClass:"")},innerValue:function(){var t=this,e=!0===this.mapOptions&&!0!==this.multiple,i=void 0===this.value||null===this.value&&!0!==e?[]:!0===this.multiple&&Array.isArray(this.value)?this.value:[this.value];if(!0===this.mapOptions&&!0===Array.isArray(this.options)){var n=!0===this.mapOptions&&void 0!==this.innerValueCache?this.innerValueCache:[],s=i.map(function(e){return t.__getOption(e,n)});return null===this.value&&!0===e?s.filter(function(t){return null!==t}):s}return i},noOptions:function(){return 0===this.virtualScrollLength},selectedString:function(){var t=this;return this.innerValue.map(function(e){return t.getOptionLabel(e)}).join(", ")},sanitizeFn:function(){return!0===this.optionsSanitize?function(){return!0}:function(t){return void 0!==t&&null!==t&&!0===t.sanitize}},displayAsText:function(){return!0===this.displayValueSanitize||void 0===this.displayValue&&(!0===this.optionsSanitize||this.innerValue.some(this.sanitizeFn))},computedTabindex:function(){return!0===this.focused?this.tabindex:-1},selectedScope:function(){var t=this;return this.innerValue.map(function(e,i){return{index:i,opt:e,sanitize:t.sanitizeFn(e),selected:!0,removeAtIndex:t.__removeAtIndexAndFocus,toggleOption:t.toggleOption,tabindex:t.computedTabindex}})},optionScope:function(){var t=this;if(0===this.virtualScrollLength)return[];var e=this.virtualScrollSliceRange,i=e.from,n=e.to,s=this.__optionScopeCache,o=s.options,r=s.optionEls;return this.options.slice(i,n).map(function(e,n){var s=t.isOptionDisabled(e),a=i+n,l={clickable:!0,active:!1,activeClass:t.computedOptionsSelectedClass,manualFocus:!0,focused:!1,disable:s,tabindex:-1,dense:t.optionsDense,dark:t.isOptionsDark},c={role:"option",id:t.targetUid+"_"+a};!0!==s&&(!0===t.isOptionSelected(e)&&(l.active=!0),c["aria-selected"]=!0===l.active?"true":"false",t.optionIndex===a&&(l.focused=!0));var u={click:function(){t.toggleOption(e)}};!0===t.$q.platform.is.desktop&&(u.mousemove=function(){!0===t.menu&&t.setOptionIndex(a)});var h={index:a,opt:e,sanitize:t.sanitizeFn(e),selected:l.active,focused:l.focused,toggleOption:t.toggleOption,setOptionIndex:t.setOptionIndex,itemProps:l,itemAttrs:c};return void 0!==o[n]&&!0===Gi(h,o[n])||(o[n]=h,r[n]=void 0),Object.assign({},h,{itemEvents:u})})},dropdownArrowIcon:function(){return void 0!==this.dropdownIcon?this.dropdownIcon:this.$q.iconSet.arrow.dropdown},squaredMenu:function(){return!1===this.optionsCover&&!0!==this.outlined&&!0!==this.standout&&!0!==this.borderless&&!0!==this.rounded},computedOptionsSelectedClass:function(){return void 0!==this.optionsSelectedClass?this.optionsSelectedClass:void 0!==this.color?"text-"+this.color:""},innerOptionsValue:function(){var t=this;return this.innerValue.map(function(e){return t.getOptionValue(e)})},getOptionValue:function(){return this.__getPropValueFn("optionValue","value")},getOptionLabel:function(){return this.__getPropValueFn("optionLabel","label")},isOptionDisabled:function(){var t=this.__getPropValueFn("optionDisable","disable");return function(){for(var e=[],i=arguments.length;i--;)e[i]=arguments[i];return!0===t.apply(null,e)}},inputControlEvents:function(){var t=this,e={input:this.__onInput,change:this.__onChange,keydown:this.__onTargetKeydown,keyup:this.__onTargetAutocomplete,keypress:this.__onTargetKeypress,focus:this.__selectInputText,click:function(e){!0===t.hasDialog&&b(e)}};return e.compositionstart=e.compositionupdate=e.compositionend=this.__onComposition,e},virtualScrollItemSizeComputed:function(){return void 0===this.virtualScrollItemSize?!0===this.optionsDense?24:48:this.virtualScrollItemSize},comboboxAttrs:function(){return{role:"combobox","aria-multiselectable":!0===this.multiple?"true":"false","aria-expanded":!0===this.menu?"true":"false","aria-owns":this.targetUid+"_lb","aria-activedescendant":this.targetUid+"_"+this.optionIndex}},listboxAttrs:function(){return{role:"listbox",id:this.targetUid+"_lb"}}},methods:{getEmittingOptionValue:function(t){return!0===this.emitValue?this.getOptionValue(t):t},removeAtIndex:function(t){if(t>-1&&t=this.maxValues)){var n=this.value.slice();this.$emit("add",{index:n.length,value:i}),n.push(i),this.$emit("input",n)}},toggleOption:function(t,e){if(!0===this.editable&&void 0!==t&&!0!==this.isOptionDisabled(t)){var i=this.getOptionValue(t);if(!0!==this.multiple)return!0!==e&&(this.updateInputValue(!0===this.fillInput?this.getOptionLabel(t):"",!0,!0),this.hidePopup()),void 0!==this.$refs.target&&this.$refs.target.focus(),void(0!==this.innerValue.length&&!0===Gi(this.getOptionValue(this.innerValue[0]),i)||this.$emit("input",!0===this.emitValue?i:t));if((!0!==this.hasDialog||!0===this.dialogFieldFocused)&&this.__focus(),this.__selectInputText(),0===this.innerValue.length){var n=!0===this.emitValue?i:t;return this.$emit("add",{index:0,value:n}),void this.$emit("input",!0===this.multiple?[n]:n)}var s=this.value.slice(),o=this.innerOptionsValue.findIndex(function(t){return Gi(t,i)});if(o>-1)this.$emit("remove",{index:o,value:s.splice(o,1)[0]});else{if(void 0!==this.maxValues&&s.length>=this.maxValues)return;var r=!0===this.emitValue?i:t;this.$emit("add",{index:s.length,value:r}),s.push(r)}this.$emit("input",s)}},setOptionIndex:function(t){if(!0===this.$q.platform.is.desktop){var e=t>-1&&t=0?this.getOptionLabel(this.options[i]):this.defaultInputValue))}},__getOption:function(t,e){var i=this,n=function(e){return Gi(i.getOptionValue(e),t)};return this.options.find(n)||e.find(n)||t},__getPropValueFn:function(t,e){var i=void 0!==this[t]?this[t]:e;return"function"==typeof i?i:function(t){return null!==t&&"object"==typeof t&&i in t?t[i]:t}},isOptionSelected:function(t){var e=this.getOptionValue(t);return void 0!==this.innerOptionsValue.find(function(t){return Gi(t,e)})},__selectInputText:function(t){!0===this.useInput&&void 0!==this.$refs.target&&(void 0===t||this.$refs.target===t.target&&t.target.value===this.selectedString)&&this.$refs.target.select()},__onTargetKeyup:function(t){!0===J(t,27)&&!0===this.menu&&(b(t),this.hidePopup(),this.__resetInputValue()),this.$emit("keyup",t)},__onTargetAutocomplete:function(t){var e=this,i=t.target.value;if(void 0===t.keyCode)if(t.target.value="",clearTimeout(this.inputTimer),this.__resetInputValue(),"string"==typeof i&&i.length>0){var n=i.toLocaleLowerCase(),s=function(t){var i=e.options.find(function(e){return t(e).toLocaleLowerCase()===n});return void 0!==i&&(-1===e.innerValue.indexOf(i)?e.toggleOption(i):e.hidePopup(),!0)},o=function(t){!0!==s(e.getOptionValue)&&!0!==s(e.getOptionLabel)&&!0!==t&&e.filter(i,!0,function(){return o(!0)})};o()}else this.__clearValue(t);else this.__onTargetKeyup(t)},__onTargetKeypress:function(t){this.$emit("keypress",t)},__onTargetKeydown:function(t){var e=this;if(this.$emit("keydown",t),!0!==Z(t)){var i=this.inputValue.length>0&&(void 0!==this.newValueMode||void 0!==this.qListeners["new-value"]),n=!0!==t.shiftKey&&!0!==this.multiple&&(this.optionIndex>-1||!0===i);if(27!==t.keyCode)if(9!==t.keyCode||!1!==n){if(void 0!==t.target&&t.target.id===this.targetUid){if(40===t.keyCode&&!0!==this.innerLoading&&!1===this.menu)return S(t),void this.showPopup();if(8!==t.keyCode||!0===this.hideSelected||0!==this.inputValue.length){35!==t.keyCode&&36!==t.keyCode||"string"==typeof this.inputValue&&0!==this.inputValue.length||(S(t),this.optionIndex=-1,this.moveOptionSelection(36===t.keyCode?1:-1,this.multiple)),33!==t.keyCode&&34!==t.keyCode||void 0===this.virtualScrollSliceSizeComputed||(S(t),this.optionIndex=Math.max(-1,Math.min(this.virtualScrollLength,this.optionIndex+(33===t.keyCode?-1:1)*this.virtualScrollSliceSizeComputed.view)),this.moveOptionSelection(33===t.keyCode?1:-1,this.multiple)),38!==t.keyCode&&40!==t.keyCode||(S(t),this.moveOptionSelection(38===t.keyCode?-1:1,this.multiple));var s=this.virtualScrollLength;if((void 0===this.searchBuffer||this.searchBufferExp0&&!0!==this.useInput&&void 0!==t.key&&1===t.key.length&&t.altKey===t.ctrlKey&&(32!==t.keyCode||this.searchBuffer.length>0)){!0!==this.menu&&this.showPopup(t);var o=t.key.toLocaleLowerCase(),r=1===this.searchBuffer.length&&this.searchBuffer[0]===o;this.searchBufferExp=Date.now()+1500,!1===r&&(S(t),this.searchBuffer+=o);var a=new RegExp("^"+this.searchBuffer.split("").map(function(t){return".*+?^${}()|[]\\".indexOf(t)>-1?"\\"+t:t}).join(".*"),"i"),l=this.optionIndex;if(!0===r||l<0||!0!==a.test(this.getOptionLabel(this.options[l])))do{l=ht(l+1,-1,s-1)}while(l!==this.optionIndex&&(!0===this.isOptionDisabled(this.options[l])||!0!==a.test(this.getOptionLabel(this.options[l]))));this.optionIndex!==l&&this.$nextTick(function(){e.setOptionIndex(l),e.scrollTo(l),l>=0&&!0===e.useInput&&!0===e.fillInput&&e.__setInputValue(e.getOptionLabel(e.options[l]))})}else if(13===t.keyCode||32===t.keyCode&&!0!==this.useInput&&""===this.searchBuffer||9===t.keyCode&&!1!==n)if(9!==t.keyCode&&S(t),this.optionIndex>-1&&this.optionIndex0&&i.push(t("input",{staticClass:"q-select__autocomplete-input",attrs:{autocomplete:this.autocomplete},on:ft(this,"autoinp",{keyup:this.__onTargetAutocomplete})}))}if(void 0!==this.nameProp&&!0!==this.disable&&this.innerOptionsValue.length>0){var o=this.innerOptionsValue.map(function(e){return t("option",{attrs:{value:e,selected:!0}})});i.push(t("select",{staticClass:"hidden",attrs:{name:this.nameProp,multiple:this.multiple}},o))}var r=!0===this.useInput||!0!==n?void 0:this.qAttrs;return t("div",{staticClass:"q-field__native row items-center",attrs:r},i)},__getOptions:function(t){var e=this;if(!0===this.menu){void 0!==this.$scopedSlots.option&&this.__optionScopeCache.optionSlot!==this.$scopedSlots.option&&(this.__optionScopeCache.optionSlot=this.$scopedSlots.option,this.__optionScopeCache.optionEls=[]);var i=void 0!==this.$scopedSlots.option?this.$scopedSlots.option:function(i){var n;return t(Zs,{key:i.index,props:i.itemProps,attrs:i.itemAttrs,on:i.itemEvents},[t(Js,[t(go,{domProps:(n={},n[!0===i.sanitize?"textContent":"innerHTML"]=e.getOptionLabel(i.opt),n)})])])},n=this.__optionScopeCache.optionEls,s=this.__padVirtualScroll(t,"div",this.optionScope.map(function(t,e){return void 0===n[e]&&(n[e]=i(t)),n[e]}));return void 0!==this.$scopedSlots["before-options"]&&(s=this.$scopedSlots["before-options"]().concat(s)),Et(s,this,"after-options")}},__getInnerAppend:function(t){return!0!==this.loading&&!0!==this.innerLoadingIndicator&&!0!==this.hideDropdownIcon?[t(Ut,{staticClass:"q-select__dropdown-icon"+(!0===this.menu?" rotate-180":""),props:{name:this.dropdownArrowIcon}})]:null},__getInput:function(t,e,i){var n=!0===i?Object.assign({},this.comboboxAttrs,this.qAttrs):void 0,s={ref:!0===i?"target":void 0,key:"i_t",staticClass:"q-field__input q-placeholder col",style:this.inputStyle,class:this.computedInputClass,domProps:{value:void 0!==this.inputValue?this.inputValue:""},attrs:Object.assign({},{type:"search"},n,{id:!0===i?this.targetUid:void 0,maxlength:this.maxlength,tabindex:this.tabindex,autocomplete:this.autocomplete,"data-autofocus":!0!==e&&this.autofocus||void 0,disabled:!0===this.disable,readonly:!0===this.readonly}),on:this.inputControlEvents};return!0!==e&&!0===this.hasDialog&&(s.staticClass+=" no-pointer-events"),t("input",s)},__onChange:function(t){this.__onComposition(t)},__onInput:function(t){var e=this;clearTimeout(this.inputTimer),t&&t.target&&!0===t.target.qComposing||(this.__setInputValue(t.target.value||""),this.userInputValue=!0,this.defaultInputValue=this.inputValue,!0===this.focused||!0===this.hasDialog&&!0!==this.dialogFieldFocused||this.__focus(),void 0!==this.qListeners.filter&&(this.inputTimer=setTimeout(function(){e.filter(e.inputValue)},this.inputDebounce)))},__setInputValue:function(t){this.inputValue!==t&&(this.inputValue=t,this.$emit("input-value",t))},updateInputValue:function(t,e,i){this.userInputValue=!0!==i,!0===this.useInput&&(this.__setInputValue(t),!0!==e&&!0===i||(this.defaultInputValue=t),!0!==e&&this.filter(t))},filter:function(t,e,i){var n=this;if(void 0!==this.qListeners.filter&&(!0===e||!0===this.focused)){!0===this.innerLoading?this.$emit("filter-abort"):(this.innerLoading=!0,this.innerLoadingIndicator=!0),""!==t&&!0!==this.multiple&&this.innerValue.length>0&&!0!==this.userInputValue&&t===this.getOptionLabel(this.innerValue[0])&&(t="");var s=setTimeout(function(){!0===n.menu&&(n.menu=!1)},10);clearTimeout(this.filterId),this.filterId=s,this.$emit("filter",t,function(t,o){!0!==e&&!0!==n.focused||n.filterId!==s||(clearTimeout(n.filterId),"function"==typeof t&&t(),n.innerLoadingIndicator=!1,n.$nextTick(function(){n.innerLoading=!1,!0===n.editable&&(!0===e?!0===n.menu&&n.hidePopup():!0===n.menu?n.__updateMenu(!0):n.menu=!0),"function"==typeof o&&n.$nextTick(function(){o(n)}),"function"==typeof i&&n.$nextTick(function(){i(n)})}))},function(){!0===n.focused&&n.filterId===s&&(clearTimeout(n.filterId),n.innerLoading=!1,n.innerLoadingIndicator=!1),!0===n.menu&&(n.menu=!1)})}},__getControlEvents:function(){var t=this,e=function(e){t.__onControlFocusout(e,function(){t.__resetInputValue(),t.__closeMenu()})};return{focusin:this.__onControlFocusin,focusout:e,"popup-show":this.__onControlPopupShow,"popup-hide":function(i){void 0!==i&&b(i),t.$emit("popup-hide",i),t.hasPopupOpen=!1,e(i)},click:function(e){if(!0!==t.hasDialog&&(y(e),!0===t.menu))return t.__closeMenu(),void(void 0!==t.$refs.target&&t.$refs.target.focus());t.showPopup(e)}}},__getControlChild:function(t){if(!1!==this.editable&&(!0===this.dialog||!0!==this.noOptions||void 0!==this.$scopedSlots["no-option"]))return this["__get"+(!0===this.hasDialog?"Dialog":"Menu")](t)},__getMenu:function(t){var e=!0===this.noOptions?void 0!==this.$scopedSlots["no-option"]?this.$scopedSlots["no-option"]({inputValue:this.inputValue}):null:this.__getOptions(t);return t(Mi,{ref:"menu",props:{value:this.menu,fit:!0!==this.menuShrink,cover:!0===this.optionsCover&&!0!==this.noOptions&&!0!==this.useInput,anchor:this.menuAnchor,self:this.menuSelf,offset:this.menuOffset,contentClass:this.menuContentClass,contentStyle:this.popupContentStyle,dark:this.isOptionsDark,noParentEvent:!0,noRefocus:!0,noFocus:!0,square:this.squaredMenu,transitionShow:this.transitionShow,transitionHide:this.transitionHide,separateClosePopup:!0},attrs:this.listboxAttrs,on:ft(this,"menu",{"&scroll":this.__onVirtualScrollEvt,"before-hide":this.__closeMenu,show:this.__onMenuShow})},e)},__onMenuShow:function(){this.__setVirtualScrollSize()},__onDialogFieldFocus:function(t){b(t),void 0!==this.$refs.target&&this.$refs.target.focus(),this.dialogFieldFocused=!0,window.scrollTo(window.pageXOffset||window.scrollX||document.body.scrollLeft||0,0)},__onDialogFieldBlur:function(t){var e=this;b(t),this.$nextTick(function(){e.dialogFieldFocused=!1})},__getDialog:function(t){var e=this,i=[t(jo,{staticClass:"col-auto "+this.fieldClass,props:Object.assign({},this.$props,{for:this.targetUid,dark:this.isOptionsDark,square:!0,filled:!0,itemAligned:!1,loading:this.innerLoadingIndicator,stackLabel:this.inputValue.length>0}),on:Object.assign({},this.qListeners,{focus:this.__onDialogFieldFocus,blur:this.__onDialogFieldBlur}),scopedSlots:Object.assign({},this.$scopedSlots,{rawControl:function(){return e.__getControl(t,!0)},before:void 0,after:void 0})})];return!0===this.menu&&i.push(t("div",{ref:"menuContent",staticClass:"scroll",class:this.menuContentClass,style:this.popupContentStyle,attrs:this.listboxAttrs,on:ft(this,"virtMenu",{click:y,"&scroll":this.__onVirtualScrollEvt})},!0===this.noOptions?void 0!==this.$scopedSlots["no-option"]?this.$scopedSlots["no-option"]({inputValue:this.inputValue}):null:this.__getOptions(t))),t(Ys,{ref:"dialog",props:{value:this.dialog,dark:this.isOptionsDark,position:!0===this.useInput?"top":void 0,transitionShow:this.transitionShowComputed,transitionHide:this.transitionHide},on:ft(this,"dialog",{"before-hide":this.__onDialogBeforeHide,hide:this.__onDialogHide,show:this.__onDialogShow})},[t("div",{staticClass:"q-select__dialog"+(!0===this.isOptionsDark?" q-select__dialog--dark q-dark":"")+(!0===this.dialogFieldFocused?" q-select__dialog--focused":"")},i)])},__onDialogBeforeHide:function(){!0!==c.is.mobile&&(this.$refs.dialog.__refocusTarget=this.$el.querySelector(".q-field__native > [tabindex]:last-child")),this.focused=!1},__onDialogHide:function(t){this.hidePopup(),!1===this.focused&&this.$emit("blur",t),this.__resetInputValue()},__onDialogShow:function(){var t=document.activeElement;null!==t&&t.id===this.targetUid||this.$refs.target===t||void 0===this.$refs.target||this.$refs.target.focus(),this.__setVirtualScrollSize()},__closeMenu:function(){void 0!==this.__optionScopeCache&&(this.__optionScopeCache.optionEls=[]),!0!==this.dialog&&(this.optionIndex=-1,!0===this.menu&&(this.menu=!1),!1===this.focused&&(clearTimeout(this.filterId),this.filterId=void 0,!0===this.innerLoading&&(this.$emit("filter-abort"),this.innerLoading=!1,this.innerLoadingIndicator=!1)))},showPopup:function(t){var e=this;!0===this.editable&&(!0===this.hasDialog?(this.__onControlFocusin(t),this.dialog=!0,this.$nextTick(function(){e.__focus()})):this.__focus(),void 0!==this.qListeners.filter?this.filter(this.inputValue):!0===this.noOptions&&void 0===this.$scopedSlots["no-option"]||(this.menu=!0))},hidePopup:function(){this.dialog=!1,this.__closeMenu()},__resetInputValue:function(){!0===this.useInput&&this.updateInputValue(!0!==this.multiple&&!0===this.fillInput&&this.innerValue.length>0&&this.getOptionLabel(this.innerValue[0])||"",!0,!0)},__updateMenu:function(t){var e=this,i=-1;if(!0===t){if(this.innerValue.length>0){var n=this.getOptionValue(this.innerValue[0]);i=this.options.findIndex(function(t){return Gi(e.getOptionValue(t),n)})}this.__resetVirtualScroll(i)}this.setOptionIndex(i)},__onPreRender:function(){this.hasDialog=(!0===this.$q.platform.is.mobile||"dialog"===this.behavior)&&("menu"!==this.behavior&&(!0!==this.useInput||(void 0!==this.$scopedSlots["no-option"]||void 0!==this.qListeners.filter||!1===this.noOptions))),this.transitionShowComputed=!0===this.hasDialog&&!0===this.useInput&&!0===this.$q.platform.is.ios?"fade":this.transitionShow},__onPostRender:function(){!1===this.dialog&&void 0!==this.$refs.menu&&this.$refs.menu.updatePosition()},updateMenuPosition:function(){this.__onPostRender()}},beforeMount:function(){this.__optionScopeCache={optionSlot:this.$scopedSlots.option,options:[],optionEls:[]}},beforeDestroy:function(){this.__optionScopeCache=void 0,clearTimeout(this.inputTimer)}}),pa=["text","rect","circle","QBtn","QBadge","QChip","QToolbar","QCheckbox","QRadio","QToggle","QSlider","QRange","QInput","QAvatar"],fa=["wave","pulse","pulse-x","pulse-y","fade","blink","none"],ma=t.extend({name:"QSkeleton",mixins:[Gt,$t,Lt],props:{type:{type:String,validator:function(t){return pa.includes(t)},default:"rect"},animation:{type:String,validator:function(t){return fa.includes(t)},default:"wave"},square:Boolean,bordered:Boolean,size:String,width:String,height:String},computed:{style:function(){return void 0!==this.size?{width:this.size,height:this.size}:{width:this.width,height:this.height}},classes:function(){return"q-skeleton--"+(!0===this.isDark?"dark":"light")+" q-skeleton--type-"+this.type+("none"!==this.animation?" q-skeleton--anim q-skeleton--anim-"+this.animation:"")+(!0===this.square?" q-skeleton--square":"")+(!0===this.bordered?" q-skeleton--bordered":"")}},render:function(t){return t(this.tag,{staticClass:"q-skeleton",class:this.classes,style:this.style,on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),va=[["left","center","start","width"],["right","center","end","width"],["top","start","center","height"],["bottom","end","center","height"]],ga=t.extend({name:"QSlideItem",mixins:[Gt,Lt],props:{leftColor:String,rightColor:String,topColor:String,bottomColor:String},directives:{TouchPan:xn},computed:{langDir:function(){return!0===this.$q.lang.rtl?{left:"right",right:"left"}:{left:"left",right:"right"}}},methods:{reset:function(){this.$refs.content.style.transform="translate(0,0)",this.__emitSlide(this.__showing,0,!0)},__emitSlide:function(t,e,i){void 0!==this.qListeners.slide&&this.$emit("slide",{side:t,ratio:e,isReset:i})},__pan:function(t){var e,i,n,s=this,o=this.$refs.content;if(t.isFirst)this.__dir=null,this.__size={left:0,right:0,top:0,bottom:0},this.__scale=0,o.classList.add("no-transition"),va.forEach(function(t){if(void 0!==s.$scopedSlots[t[0]]){var e=s.$refs[t[0]+"Content"];e.style.transform="scale(1)",s.__size[t[0]]=e.getBoundingClientRect()[t[3]]}}),this.__axis="up"===t.direction||"down"===t.direction?"Y":"X";else{if(t.isFinal)return o.classList.remove("no-transition"),void(1===this.__scale?(o.style.transform="translate"+this.__axis+"("+100*this.__dir+"%)",this.timer=setTimeout(function(){s.$emit(s.__showing,{reset:s.reset}),s.$emit("action",{side:s.__showing,reset:s.reset})},230)):(o.style.transform="translate(0,0)",this.__emitSlide(this.__showing,0,!0)));t.direction="X"===this.__axis?t.offset.x<0?"left":"right":t.offset.y<0?"up":"down"}void 0===this.$scopedSlots.left&&t.direction===this.langDir.right||void 0===this.$scopedSlots.right&&t.direction===this.langDir.left||void 0===this.$scopedSlots.top&&"down"===t.direction||void 0===this.$scopedSlots.bottom&&"up"===t.direction?o.style.transform="translate(0,0)":("X"===this.__axis?(i="left"===t.direction?-1:1,e=1===i?this.langDir.left:this.langDir.right,n=t.distance.x):(i="up"===t.direction?-2:2,e=2===i?"top":"bottom",n=t.distance.y),null!==this.__dir&&Math.abs(i)!==Math.abs(this.__dir)||(this.__dir!==i&&(["left","right","top","bottom"].forEach(function(t){void 0!==s.$refs[t]&&(s.$refs[t].style.visibility=e===t?"visible":"hidden")}),this.__showing=e,this.__dir=i),this.__scale=Math.max(0,Math.min(1,(n-40)/this.__size[e])),o.style.transform="translate"+this.__axis+"("+n*i/Math.abs(i)+"px)",this.$refs[e+"Content"].style.transform="scale("+this.__scale+")",this.__emitSlide(e,this.__scale,!1)))}},render:function(t){var e=this,i=[],n={left:void 0!==this.$scopedSlots[this.langDir.right],right:void 0!==this.$scopedSlots[this.langDir.left],up:void 0!==this.$scopedSlots.bottom,down:void 0!==this.$scopedSlots.top},s=Object.keys(n).filter(function(t){return!0===n[t]});return va.forEach(function(n){var s=n[0];void 0!==e.$scopedSlots[s]&&i.push(t("div",{ref:s,class:"q-slide-item__"+s+" absolute-full row no-wrap items-"+n[1]+" justify-"+n[2]+(void 0!==e[s+"Color"]?" bg-"+e[s+"Color"]:"")},[t("div",{ref:s+"Content"},e.$scopedSlots[s]())]))}),i.push(t("div",{ref:"content",key:"content",staticClass:"q-slide-item__content",directives:s.length>0?mt(this,"dir#"+s.join(""),function(){var t={prevent:!0,stop:!0,mouse:!0};return s.forEach(function(e){t[e]=!0}),[{name:"touch-pan",value:e.__pan,modifiers:t}]}):null},Ot(this,"default"))),t("div",{staticClass:"q-slide-item q-item-type overflow-hidden",class:!0===this.isDark?"q-slide-item--dark q-dark":"",on:Object.assign({},this.qListeners)},i)},beforeDestroy:function(){clearTimeout(this.timer)}}),_a=t.extend({name:"QSpace",mixins:[Lt],render:function(t){return t("div",{staticClass:"q-space",on:Object.assign({},this.qListeners)})}}),ba=t.extend({name:"QSpinnerAudio",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",fill:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 55 80",xmlns:"http://www.w3.org/2000/svg"}},[t("g",{attrs:{transform:"matrix(1 0 0 -1 0 80)"}},[t("rect",{attrs:{width:"10",height:"20",rx:"3"}},[t("animate",{attrs:{attributeName:"height",begin:"0s",dur:"4.3s",values:"20;45;57;80;64;32;66;45;64;23;66;13;64;56;34;34;2;23;76;79;20",calcMode:"linear",repeatCount:"indefinite"}})]),t("rect",{attrs:{x:"15",width:"10",height:"80",rx:"3"}},[t("animate",{attrs:{attributeName:"height",begin:"0s",dur:"2s",values:"80;55;33;5;75;23;73;33;12;14;60;80",calcMode:"linear",repeatCount:"indefinite"}})]),t("rect",{attrs:{x:"30",width:"10",height:"50",rx:"3"}},[t("animate",{attrs:{attributeName:"height",begin:"0s",dur:"1.4s",values:"50;34;78;23;56;23;34;76;80;54;21;50",calcMode:"linear",repeatCount:"indefinite"}})]),t("rect",{attrs:{x:"45",width:"10",height:"30",rx:"3"}},[t("animate",{attrs:{attributeName:"height",begin:"0s",dur:"2s",values:"30;45;13;80;56;72;45;76;34;23;67;30",calcMode:"linear",repeatCount:"indefinite"}})])])])}}),ya=t.extend({name:"QSpinnerBall",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",stroke:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 57 57",xmlns:"http://www.w3.org/2000/svg"}},[t("g",{attrs:{transform:"translate(1 1)","stroke-width":"2",fill:"none","fill-rule":"evenodd"}},[t("circle",{attrs:{cx:"5",cy:"50",r:"5"}},[t("animate",{attrs:{attributeName:"cy",begin:"0s",dur:"2.2s",values:"50;5;50;50",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"cx",begin:"0s",dur:"2.2s",values:"5;27;49;5",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"27",cy:"5",r:"5"}},[t("animate",{attrs:{attributeName:"cy",begin:"0s",dur:"2.2s",from:"5",to:"5",values:"5;50;50;5",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"cx",begin:"0s",dur:"2.2s",from:"27",to:"27",values:"27;49;5;27",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"49",cy:"50",r:"5"}},[t("animate",{attrs:{attributeName:"cy",begin:"0s",dur:"2.2s",values:"50;50;5;50",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"cx",from:"49",to:"49",begin:"0s",dur:"2.2s",values:"49;5;27;49",calcMode:"linear",repeatCount:"indefinite"}})])])])}}),Sa=t.extend({name:"QSpinnerBars",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",fill:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 135 140",xmlns:"http://www.w3.org/2000/svg"}},[t("rect",{attrs:{y:"10",width:"15",height:"120",rx:"6"}},[t("animate",{attrs:{attributeName:"height",begin:"0.5s",dur:"1s",values:"120;110;100;90;80;70;60;50;40;140;120",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"y",begin:"0.5s",dur:"1s",values:"10;15;20;25;30;35;40;45;50;0;10",calcMode:"linear",repeatCount:"indefinite"}})]),t("rect",{attrs:{x:"30",y:"10",width:"15",height:"120",rx:"6"}},[t("animate",{attrs:{attributeName:"height",begin:"0.25s",dur:"1s",values:"120;110;100;90;80;70;60;50;40;140;120",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"y",begin:"0.25s",dur:"1s",values:"10;15;20;25;30;35;40;45;50;0;10",calcMode:"linear",repeatCount:"indefinite"}})]),t("rect",{attrs:{x:"60",width:"15",height:"140",rx:"6"}},[t("animate",{attrs:{attributeName:"height",begin:"0s",dur:"1s",values:"120;110;100;90;80;70;60;50;40;140;120",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"y",begin:"0s",dur:"1s",values:"10;15;20;25;30;35;40;45;50;0;10",calcMode:"linear",repeatCount:"indefinite"}})]),t("rect",{attrs:{x:"90",y:"10",width:"15",height:"120",rx:"6"}},[t("animate",{attrs:{attributeName:"height",begin:"0.25s",dur:"1s",values:"120;110;100;90;80;70;60;50;40;140;120",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"y",begin:"0.25s",dur:"1s",values:"10;15;20;25;30;35;40;45;50;0;10",calcMode:"linear",repeatCount:"indefinite"}})]),t("rect",{attrs:{x:"120",y:"10",width:"15",height:"120",rx:"6"}},[t("animate",{attrs:{attributeName:"height",begin:"0.5s",dur:"1s",values:"120;110;100;90;80;70;60;50;40;140;120",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"y",begin:"0.5s",dur:"1s",values:"10;15;20;25;30;35;40;45;50;0;10",calcMode:"linear",repeatCount:"indefinite"}})])])}}),wa=t.extend({name:"QSpinnerBox",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("rect",{attrs:{x:"25",y:"25",width:"50",height:"50",fill:"none","stroke-width":"4",stroke:"currentColor"}},[t("animateTransform",{attrs:{id:"spinnerBox",attributeName:"transform",type:"rotate",from:"0 50 50",to:"180 50 50",dur:"0.5s",begin:"rectBox.end"}})]),t("rect",{attrs:{x:"27",y:"27",width:"46",height:"50",fill:"currentColor"}},[t("animate",{attrs:{id:"rectBox",attributeName:"height",begin:"0s;spinnerBox.end",dur:"1.3s",from:"50",to:"0",fill:"freeze"}})])])}}),Ca=t.extend({name:"QSpinnerClock",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("circle",{attrs:{cx:"50",cy:"50",r:"48",fill:"none","stroke-width":"4","stroke-miterlimit":"10",stroke:"currentColor"}}),t("line",{attrs:{"stroke-linecap":"round","stroke-width":"4","stroke-miterlimit":"10",stroke:"currentColor",x1:"50",y1:"50",x2:"85",y2:"50.5"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"360 50 50",dur:"2s",repeatCount:"indefinite"}})]),t("line",{attrs:{"stroke-linecap":"round","stroke-width":"4","stroke-miterlimit":"10",stroke:"currentColor",x1:"50",y1:"50",x2:"49.5",y2:"74"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"360 50 50",dur:"15s",repeatCount:"indefinite"}})])])}}),xa=t.extend({name:"QSpinnerComment",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("rect",{attrs:{x:"0",y:"0",width:"100",height:"100",fill:"none"}}),t("path",{attrs:{d:"M78,19H22c-6.6,0-12,5.4-12,12v31c0,6.6,5.4,12,12,12h37.2c0.4,3,1.8,5.6,3.7,7.6c2.4,2.5,5.1,4.1,9.1,4 c-1.4-2.1-2-7.2-2-10.3c0-0.4,0-0.8,0-1.3h8c6.6,0,12-5.4,12-12V31C90,24.4,84.6,19,78,19z",fill:"currentColor"}}),t("circle",{attrs:{cx:"30",cy:"47",r:"5",fill:"#fff"}},[t("animate",{attrs:{attributeName:"opacity",from:"0",to:"1",values:"0;1;1",keyTimes:"0;0.2;1",dur:"1s",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"50",cy:"47",r:"5",fill:"#fff"}},[t("animate",{attrs:{attributeName:"opacity",from:"0",to:"1",values:"0;0;1;1",keyTimes:"0;0.2;0.4;1",dur:"1s",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"70",cy:"47",r:"5",fill:"#fff"}},[t("animate",{attrs:{attributeName:"opacity",from:"0",to:"1",values:"0;0;1;1",keyTimes:"0;0.4;0.6;1",dur:"1s",repeatCount:"indefinite"}})])])}}),ka=t.extend({name:"QSpinnerCube",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("rect",{attrs:{x:"0",y:"0",width:"100",height:"100",fill:"none"}}),t("g",{attrs:{transform:"translate(25 25)"}},[t("rect",{attrs:{x:"-20",y:"-20",width:"40",height:"40",fill:"currentColor",opacity:"0.9"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"scale",from:"1.5",to:"1",repeatCount:"indefinite",begin:"0s",dur:"1s",calcMode:"spline",keySplines:"0.2 0.8 0.2 0.8",keyTimes:"0;1"}})])]),t("g",{attrs:{transform:"translate(75 25)"}},[t("rect",{attrs:{x:"-20",y:"-20",width:"40",height:"40",fill:"currentColor",opacity:"0.8"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"scale",from:"1.5",to:"1",repeatCount:"indefinite",begin:"0.1s",dur:"1s",calcMode:"spline",keySplines:"0.2 0.8 0.2 0.8",keyTimes:"0;1"}})])]),t("g",{attrs:{transform:"translate(25 75)"}},[t("rect",{staticClass:"cube",attrs:{x:"-20",y:"-20",width:"40",height:"40",fill:"currentColor",opacity:"0.7"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"scale",from:"1.5",to:"1",repeatCount:"indefinite",begin:"0.3s",dur:"1s",calcMode:"spline",keySplines:"0.2 0.8 0.2 0.8",keyTimes:"0;1"}})])]),t("g",{attrs:{transform:"translate(75 75)"}},[t("rect",{staticClass:"cube",attrs:{x:"-20",y:"-20",width:"40",height:"40",fill:"currentColor",opacity:"0.6"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"scale",from:"1.5",to:"1",repeatCount:"indefinite",begin:"0.2s",dur:"1s",calcMode:"spline",keySplines:"0.2 0.8 0.2 0.8",keyTimes:"0;1"}})])])])}}),qa=t.extend({name:"QSpinnerDots",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",fill:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 120 30",xmlns:"http://www.w3.org/2000/svg"}},[t("circle",{attrs:{cx:"15",cy:"15",r:"15"}},[t("animate",{attrs:{attributeName:"r",from:"15",to:"15",begin:"0s",dur:"0.8s",values:"15;9;15",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"fill-opacity",from:"1",to:"1",begin:"0s",dur:"0.8s",values:"1;.5;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"60",cy:"15",r:"9","fill-opacity":".3"}},[t("animate",{attrs:{attributeName:"r",from:"9",to:"9",begin:"0s",dur:"0.8s",values:"9;15;9",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"fill-opacity",from:".5",to:".5",begin:"0s",dur:"0.8s",values:".5;1;.5",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"105",cy:"15",r:"15"}},[t("animate",{attrs:{attributeName:"r",from:"15",to:"15",begin:"0s",dur:"0.8s",values:"15;9;15",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"fill-opacity",from:"1",to:"1",begin:"0s",dur:"0.8s",values:"1;.5;1",calcMode:"linear",repeatCount:"indefinite"}})])])}}),Ta=t.extend({name:"QSpinnerFacebook",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"0 0 100 100",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid"}},[t("g",{attrs:{transform:"translate(20 50)"}},[t("rect",{attrs:{x:"-10",y:"-30",width:"20",height:"60",fill:"currentColor",opacity:"0.6"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"scale",from:"2",to:"1",begin:"0s",repeatCount:"indefinite",dur:"1s",calcMode:"spline",keySplines:"0.1 0.9 0.4 1",keyTimes:"0;1",values:"2;1"}})])]),t("g",{attrs:{transform:"translate(50 50)"}},[t("rect",{attrs:{x:"-10",y:"-30",width:"20",height:"60",fill:"currentColor",opacity:"0.8"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"scale",from:"2",to:"1",begin:"0.1s",repeatCount:"indefinite",dur:"1s",calcMode:"spline",keySplines:"0.1 0.9 0.4 1",keyTimes:"0;1",values:"2;1"}})])]),t("g",{attrs:{transform:"translate(80 50)"}},[t("rect",{attrs:{x:"-10",y:"-30",width:"20",height:"60",fill:"currentColor",opacity:"0.9"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"scale",from:"2",to:"1",begin:"0.2s",repeatCount:"indefinite",dur:"1s",calcMode:"spline",keySplines:"0.1 0.9 0.4 1",keyTimes:"0;1",values:"2;1"}})])])])}}),Ma=t.extend({name:"QSpinnerGears",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid",xmlns:"http://www.w3.org/2000/svg"}},[t("g",{attrs:{transform:"translate(-20,-20)"}},[t("path",{attrs:{d:"M79.9,52.6C80,51.8,80,50.9,80,50s0-1.8-0.1-2.6l-5.1-0.4c-0.3-2.4-0.9-4.6-1.8-6.7l4.2-2.9c-0.7-1.6-1.6-3.1-2.6-4.5 L70,35c-1.4-1.9-3.1-3.5-4.9-4.9l2.2-4.6c-1.4-1-2.9-1.9-4.5-2.6L59.8,27c-2.1-0.9-4.4-1.5-6.7-1.8l-0.4-5.1C51.8,20,50.9,20,50,20 s-1.8,0-2.6,0.1l-0.4,5.1c-2.4,0.3-4.6,0.9-6.7,1.8l-2.9-4.1c-1.6,0.7-3.1,1.6-4.5,2.6l2.1,4.6c-1.9,1.4-3.5,3.1-5,4.9l-4.5-2.1 c-1,1.4-1.9,2.9-2.6,4.5l4.1,2.9c-0.9,2.1-1.5,4.4-1.8,6.8l-5,0.4C20,48.2,20,49.1,20,50s0,1.8,0.1,2.6l5,0.4 c0.3,2.4,0.9,4.7,1.8,6.8l-4.1,2.9c0.7,1.6,1.6,3.1,2.6,4.5l4.5-2.1c1.4,1.9,3.1,3.5,5,4.9l-2.1,4.6c1.4,1,2.9,1.9,4.5,2.6l2.9-4.1 c2.1,0.9,4.4,1.5,6.7,1.8l0.4,5.1C48.2,80,49.1,80,50,80s1.8,0,2.6-0.1l0.4-5.1c2.3-0.3,4.6-0.9,6.7-1.8l2.9,4.2 c1.6-0.7,3.1-1.6,4.5-2.6L65,69.9c1.9-1.4,3.5-3,4.9-4.9l4.6,2.2c1-1.4,1.9-2.9,2.6-4.5L73,59.8c0.9-2.1,1.5-4.4,1.8-6.7L79.9,52.6 z M50,65c-8.3,0-15-6.7-15-15c0-8.3,6.7-15,15-15s15,6.7,15,15C65,58.3,58.3,65,50,65z",fill:"currentColor"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"90 50 50",to:"0 50 50",dur:"1s",repeatCount:"indefinite"}})])]),t("g",{attrs:{transform:"translate(20,20) rotate(15 50 50)"}},[t("path",{attrs:{d:"M79.9,52.6C80,51.8,80,50.9,80,50s0-1.8-0.1-2.6l-5.1-0.4c-0.3-2.4-0.9-4.6-1.8-6.7l4.2-2.9c-0.7-1.6-1.6-3.1-2.6-4.5 L70,35c-1.4-1.9-3.1-3.5-4.9-4.9l2.2-4.6c-1.4-1-2.9-1.9-4.5-2.6L59.8,27c-2.1-0.9-4.4-1.5-6.7-1.8l-0.4-5.1C51.8,20,50.9,20,50,20 s-1.8,0-2.6,0.1l-0.4,5.1c-2.4,0.3-4.6,0.9-6.7,1.8l-2.9-4.1c-1.6,0.7-3.1,1.6-4.5,2.6l2.1,4.6c-1.9,1.4-3.5,3.1-5,4.9l-4.5-2.1 c-1,1.4-1.9,2.9-2.6,4.5l4.1,2.9c-0.9,2.1-1.5,4.4-1.8,6.8l-5,0.4C20,48.2,20,49.1,20,50s0,1.8,0.1,2.6l5,0.4 c0.3,2.4,0.9,4.7,1.8,6.8l-4.1,2.9c0.7,1.6,1.6,3.1,2.6,4.5l4.5-2.1c1.4,1.9,3.1,3.5,5,4.9l-2.1,4.6c1.4,1,2.9,1.9,4.5,2.6l2.9-4.1 c2.1,0.9,4.4,1.5,6.7,1.8l0.4,5.1C48.2,80,49.1,80,50,80s1.8,0,2.6-0.1l0.4-5.1c2.3-0.3,4.6-0.9,6.7-1.8l2.9,4.2 c1.6-0.7,3.1-1.6,4.5-2.6L65,69.9c1.9-1.4,3.5-3,4.9-4.9l4.6,2.2c1-1.4,1.9-2.9,2.6-4.5L73,59.8c0.9-2.1,1.5-4.4,1.8-6.7L79.9,52.6 z M50,65c-8.3,0-15-6.7-15-15c0-8.3,6.7-15,15-15s15,6.7,15,15C65,58.3,58.3,65,50,65z",fill:"currentColor"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"90 50 50",dur:"1s",repeatCount:"indefinite"}})])])])}}),$a=t.extend({name:"QSpinnerGrid",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",fill:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 105 105",xmlns:"http://www.w3.org/2000/svg"}},[t("circle",{attrs:{cx:"12.5",cy:"12.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"0s",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"12.5",cy:"52.5",r:"12.5","fill-opacity":".5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"100ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"52.5",cy:"12.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"300ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"52.5",cy:"52.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"600ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"92.5",cy:"12.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"800ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"92.5",cy:"52.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"400ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"12.5",cy:"92.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"700ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"52.5",cy:"92.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"500ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"92.5",cy:"92.5",r:"12.5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"200ms",dur:"1s",values:"1;.2;1",calcMode:"linear",repeatCount:"indefinite"}})])])}}),La=t.extend({name:"QSpinnerHearts",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",fill:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 140 64",xmlns:"http://www.w3.org/2000/svg"}},[t("path",{attrs:{d:"M30.262 57.02L7.195 40.723c-5.84-3.976-7.56-12.06-3.842-18.063 3.715-6 11.467-7.65 17.306-3.68l4.52 3.76 2.6-5.274c3.716-6.002 11.47-7.65 17.304-3.68 5.84 3.97 7.56 12.054 3.842 18.062L34.49 56.118c-.897 1.512-2.793 1.915-4.228.9z","fill-opacity":".5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"0s",dur:"1.4s",values:"0.5;1;0.5",calcMode:"linear",repeatCount:"indefinite"}})]),t("path",{attrs:{d:"M105.512 56.12l-14.44-24.272c-3.716-6.008-1.996-14.093 3.843-18.062 5.835-3.97 13.588-2.322 17.306 3.68l2.6 5.274 4.52-3.76c5.84-3.97 13.593-2.32 17.308 3.68 3.718 6.003 1.998 14.088-3.842 18.064L109.74 57.02c-1.434 1.014-3.33.61-4.228-.9z","fill-opacity":".5"}},[t("animate",{attrs:{attributeName:"fill-opacity",begin:"0.7s",dur:"1.4s",values:"0.5;1;0.5",calcMode:"linear",repeatCount:"indefinite"}})]),t("path",{attrs:{d:"M67.408 57.834l-23.01-24.98c-5.864-6.15-5.864-16.108 0-22.248 5.86-6.14 15.37-6.14 21.234 0L70 16.168l4.368-5.562c5.863-6.14 15.375-6.14 21.235 0 5.863 6.14 5.863 16.098 0 22.247l-23.007 24.98c-1.43 1.556-3.757 1.556-5.188 0z"}})])}}),Oa=t.extend({name:"QSpinnerHourglass",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid",xmlns:"http://www.w3.org/2000/svg"}},[t("g",[t("path",{staticClass:"glass",attrs:{fill:"none",stroke:"currentColor","stroke-width":"5","stroke-miterlimit":"10",d:"M58.4,51.7c-0.9-0.9-1.4-2-1.4-2.3s0.5-0.4,1.4-1.4 C70.8,43.8,79.8,30.5,80,15.5H70H30H20c0.2,15,9.2,28.1,21.6,32.3c0.9,0.9,1.4,1.2,1.4,1.5s-0.5,1.6-1.4,2.5 C29.2,56.1,20.2,69.5,20,85.5h10h40h10C79.8,69.5,70.8,55.9,58.4,51.7z"}}),t("clipPath",{attrs:{id:"uil-hourglass-clip1"}},[t("rect",{staticClass:"clip",attrs:{x:"15",y:"20",width:"70",height:"25"}},[t("animate",{attrs:{attributeName:"height",from:"25",to:"0",dur:"1s",repeatCount:"indefinite",values:"25;0;0",keyTimes:"0;0.5;1"}}),t("animate",{attrs:{attributeName:"y",from:"20",to:"45",dur:"1s",repeatCount:"indefinite",values:"20;45;45",keyTimes:"0;0.5;1"}})])]),t("clipPath",{attrs:{id:"uil-hourglass-clip2"}},[t("rect",{staticClass:"clip",attrs:{x:"15",y:"55",width:"70",height:"25"}},[t("animate",{attrs:{attributeName:"height",from:"0",to:"25",dur:"1s",repeatCount:"indefinite",values:"0;25;25",keyTimes:"0;0.5;1"}}),t("animate",{attrs:{attributeName:"y",from:"80",to:"55",dur:"1s",repeatCount:"indefinite",values:"80;55;55",keyTimes:"0;0.5;1"}})])]),t("path",{staticClass:"sand",attrs:{d:"M29,23c3.1,11.4,11.3,19.5,21,19.5S67.9,34.4,71,23H29z","clip-path":"url(#uil-hourglass-clip1)",fill:"currentColor"}}),t("path",{staticClass:"sand",attrs:{d:"M71.6,78c-3-11.6-11.5-20-21.5-20s-18.5,8.4-21.5,20H71.6z","clip-path":"url(#uil-hourglass-clip2)",fill:"currentColor"}}),t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"180 50 50",repeatCount:"indefinite",dur:"1s",values:"0 50 50;0 50 50;180 50 50",keyTimes:"0;0.7;1"}})])])}}),Ba=t.extend({name:"QSpinnerInfinity",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("path",{attrs:{d:"M24.3,30C11.4,30,5,43.3,5,50s6.4,20,19.3,20c19.3,0,32.1-40,51.4-40C88.6,30,95,43.3,95,50s-6.4,20-19.3,20C56.4,70,43.6,30,24.3,30z",fill:"none",stroke:"currentColor","stroke-width":"8","stroke-dasharray":"10.691205342610678 10.691205342610678","stroke-dashoffset":"0"}},[t("animate",{attrs:{attributeName:"stroke-dashoffset",from:"0",to:"21.382410685221355",begin:"0",dur:"2s",repeatCount:"indefinite",fill:"freeze"}})])])}}),Ea=t.extend({name:"QSpinnerIos",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,stroke:"currentColor",fill:"currentColor",viewBox:"0 0 64 64"}},[t("g",{attrs:{"stroke-width":"4","stroke-linecap":"round"}},[t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(180)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(210)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:"0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(240)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".1;0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(270)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".15;.1;0;1;.85;.7;.65;.55;.45;.35;.25;.15",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(300)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".25;.15;.1;0;1;.85;.7;.65;.55;.45;.35;.25",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(330)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".35;.25;.15;.1;0;1;.85;.7;.65;.55;.45;.35",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(0)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".45;.35;.25;.15;.1;0;1;.85;.7;.65;.55;.45",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(30)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".55;.45;.35;.25;.15;.1;0;1;.85;.7;.65;.55",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(60)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".65;.55;.45;.35;.25;.15;.1;0;1;.85;.7;.65",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(90)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".7;.65;.55;.45;.35;.25;.15;.1;0;1;.85;.7",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(120)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:".85;.7;.65;.55;.45;.35;.25;.15;.1;0;1;.85",repeatCount:"indefinite"}})]),t("line",{attrs:{y1:"17",y2:"29",transform:"translate(32,32) rotate(150)"}},[t("animate",{attrs:{attributeName:"stroke-opacity",dur:"750ms",values:"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1",repeatCount:"indefinite"}})])])])}}),za=t.extend({name:"QSpinnerOrbit",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("circle",{attrs:{cx:"50",cy:"50",r:"44",fill:"none","stroke-width":"4","stroke-opacity":".5",stroke:"currentColor"}}),t("circle",{attrs:{cx:"8",cy:"54",r:"6",fill:"currentColor","stroke-width":"3",stroke:"currentColor"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 48",to:"360 50 52",dur:"2s",repeatCount:"indefinite"}})])])}}),Pa=t.extend({name:"QSpinnerOval",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",stroke:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 38 38",xmlns:"http://www.w3.org/2000/svg"}},[t("g",{attrs:{transform:"translate(1 1)","stroke-width":"2",fill:"none","fill-rule":"evenodd"}},[t("circle",{attrs:{"stroke-opacity":".5",cx:"18",cy:"18",r:"18"}}),t("path",{attrs:{d:"M36 18c0-9.94-8.06-18-18-18"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 18 18",to:"360 18 18",dur:"1s",repeatCount:"indefinite"}})])])])}}),Aa=t.extend({name:"QSpinnerPie",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid",xmlns:"http://www.w3.org/2000/svg"}},[t("path",{attrs:{d:"M0 50A50 50 0 0 1 50 0L50 50L0 50",fill:"currentColor",opacity:"0.5"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"360 50 50",dur:"0.8s",repeatCount:"indefinite"}})]),t("path",{attrs:{d:"M50 0A50 50 0 0 1 100 50L50 50L50 0",fill:"currentColor",opacity:"0.5"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"360 50 50",dur:"1.6s",repeatCount:"indefinite"}})]),t("path",{attrs:{d:"M100 50A50 50 0 0 1 50 100L50 50L100 50",fill:"currentColor",opacity:"0.5"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"360 50 50",dur:"2.4s",repeatCount:"indefinite"}})]),t("path",{attrs:{d:"M50 100A50 50 0 0 1 0 50L50 50L50 100",fill:"currentColor",opacity:"0.5"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 50 50",to:"360 50 50",dur:"3.2s",repeatCount:"indefinite"}})])])}}),Ia=t.extend({name:"QSpinnerPuff",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",stroke:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 44 44",xmlns:"http://www.w3.org/2000/svg"}},[t("g",{attrs:{fill:"none","fill-rule":"evenodd","stroke-width":"2"}},[t("circle",{attrs:{cx:"22",cy:"22",r:"1"}},[t("animate",{attrs:{attributeName:"r",begin:"0s",dur:"1.8s",values:"1; 20",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.165, 0.84, 0.44, 1",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"stroke-opacity",begin:"0s",dur:"1.8s",values:"1; 0",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.3, 0.61, 0.355, 1",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"22",cy:"22",r:"1"}},[t("animate",{attrs:{attributeName:"r",begin:"-0.9s",dur:"1.8s",values:"1; 20",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.165, 0.84, 0.44, 1",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"stroke-opacity",begin:"-0.9s",dur:"1.8s",values:"1; 0",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.3, 0.61, 0.355, 1",repeatCount:"indefinite"}})])])])}}),Da=t.extend({name:"QSpinnerRadio",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid",xmlns:"http://www.w3.org/2000/svg"}},[t("g",{attrs:{transform:"scale(0.55)"}},[t("circle",{attrs:{cx:"30",cy:"150",r:"30",fill:"currentColor"}},[t("animate",{attrs:{attributeName:"opacity",from:"0",to:"1",dur:"1s",begin:"0",repeatCount:"indefinite",keyTimes:"0;0.5;1",values:"0;1;1"}})]),t("path",{attrs:{d:"M90,150h30c0-49.7-40.3-90-90-90v30C63.1,90,90,116.9,90,150z",fill:"currentColor"}},[t("animate",{attrs:{attributeName:"opacity",from:"0",to:"1",dur:"1s",begin:"0.1",repeatCount:"indefinite",keyTimes:"0;0.5;1",values:"0;1;1"}})]),t("path",{attrs:{d:"M150,150h30C180,67.2,112.8,0,30,0v30C96.3,30,150,83.7,150,150z",fill:"currentColor"}},[t("animate",{attrs:{attributeName:"opacity",from:"0",to:"1",dur:"1s",begin:"0.2",repeatCount:"indefinite",keyTimes:"0;0.5;1",values:"0;1;1"}})])])])}}),Ra=t.extend({name:"QSpinnerRings",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",stroke:"currentColor",width:this.cSize,height:this.cSize,viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg"}},[t("g",{attrs:{fill:"none","fill-rule":"evenodd",transform:"translate(1 1)","stroke-width":"2"}},[t("circle",{attrs:{cx:"22",cy:"22",r:"6"}},[t("animate",{attrs:{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"22",cy:"22",r:"6"}},[t("animate",{attrs:{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}}),t("animate",{attrs:{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"}})]),t("circle",{attrs:{cx:"22",cy:"22",r:"8"}},[t("animate",{attrs:{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}})])])])}}),Fa=t.extend({name:"QSpinnerTail",mixins:[ce],render:function(t){return t("svg",{staticClass:"q-spinner",class:this.classes,on:Object.assign({},this.qListeners),attrs:{focusable:"false",width:this.cSize,height:this.cSize,viewBox:"0 0 38 38",xmlns:"http://www.w3.org/2000/svg"}},[t("defs",[t("linearGradient",{attrs:{x1:"8.042%",y1:"0%",x2:"65.682%",y2:"23.865%",id:"a"}},[t("stop",{attrs:{"stop-color":"currentColor","stop-opacity":"0",offset:"0%"}}),t("stop",{attrs:{"stop-color":"currentColor","stop-opacity":".631",offset:"63.146%"}}),t("stop",{attrs:{"stop-color":"currentColor",offset:"100%"}})])]),t("g",{attrs:{transform:"translate(1 1)",fill:"none","fill-rule":"evenodd"}},[t("path",{attrs:{d:"M36 18c0-9.94-8.06-18-18-18",stroke:"url(#a)","stroke-width":"2"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 18 18",to:"360 18 18",dur:"0.9s",repeatCount:"indefinite"}})]),t("circle",{attrs:{fill:"currentColor",cx:"36",cy:"18",r:"1"}},[t("animateTransform",{attrs:{attributeName:"transform",type:"rotate",from:"0 18 18",to:"360 18 18",dur:"0.9s",repeatCount:"indefinite"}})])])])}}),ja=t.extend({name:"QSplitter",mixins:[Gt,Lt],directives:{TouchPan:xn},props:{value:{type:Number,required:!0},reverse:Boolean,unit:{type:String,default:"%",validator:function(t){return["%","px"].includes(t)}},limits:{type:Array,validator:function(t){return 2===t.length&&("number"==typeof t[0]&&"number"==typeof t[1]&&(t[0]>=0&&t[0]<=t[1]))}},emitImmediately:Boolean,horizontal:Boolean,disable:Boolean,beforeClass:[Array,String,Object],afterClass:[Array,String,Object],separatorClass:[Array,String,Object],separatorStyle:[Array,String,Object]},watch:{value:{immediate:!0,handler:function(t){this.__normalize(t,this.computedLimits)}},limits:{deep:!0,handler:function(){var t=this;this.$nextTick(function(){t.__normalize(t.value,t.computedLimits)})}}},computed:{classes:function(){return(!0===this.horizontal?"column":"row")+" q-splitter--"+(!0===this.horizontal?"horizontal":"vertical")+" q-splitter--"+(!0===this.disable?"disabled":"workable")+(!0===this.isDark?" q-splitter--dark":"")},prop:function(){return!0===this.horizontal?"height":"width"},side:function(){return!0!==this.reverse?"before":"after"},computedLimits:function(){return void 0!==this.limits?this.limits:"%"===this.unit?[10,90]:[50,1/0]},styles:function(){var t,e;return(e={})[this.side]=((t={})[this.prop]=this.__getCSSValue(this.value),t),e},separatorDirectives:function(){var t;if(!0!==this.disable)return[{name:"touch-pan",value:this.__pan,modifiers:(t={},t[!0===this.horizontal?"vertical":"horizontal"]=!0,t.prevent=!0,t.stop=!0,t.mouse=!0,t.mouseAllDir=!0,t)}]}},methods:{__pan:function(t){if(!0===t.isFirst){var e=this.$el.getBoundingClientRect()[this.prop];return this.__dir=!0===this.horizontal?"up":"left",this.__maxValue="%"===this.unit?100:e,this.__value=Math.min(this.__maxValue,this.computedLimits[1],Math.max(this.computedLimits[0],this.value)),this.__multiplier=(!0!==this.reverse?1:-1)*(!0===this.horizontal?1:!0===this.$q.lang.rtl?-1:1)*("%"===this.unit?0===e?0:100/e:1),void this.$el.classList.add("q-splitter--active")}if(!0===t.isFinal)return this.__normalized!==this.value&&this.$emit("input",this.__normalized),void this.$el.classList.remove("q-splitter--active");var i=this.__value+this.__multiplier*(t.direction===this.__dir?-1:1)*t.distance[!0===this.horizontal?"y":"x"];this.__normalized=Math.min(this.__maxValue,this.computedLimits[1],Math.max(this.computedLimits[0],i)),this.$refs[this.side].style[this.prop]=this.__getCSSValue(this.__normalized),!0===this.emitImmediately&&this.value!==this.__normalized&&this.$emit("input",this.__normalized)},__normalize:function(t,e){te[1]&&this.$emit("input",e[1])},__getCSSValue:function(t){return("%"===this.unit?t:Math.round(t))+this.unit}},render:function(t){var e=!0===this.disable?{"aria-disabled":"true"}:void 0,i=[t("div",{ref:"before",staticClass:"q-splitter__panel q-splitter__before"+(!0===this.reverse?" col":""),style:this.styles.before,class:this.beforeClass,on:ft(this,"stop",{input:b})},Ot(this,"before")),t("div",{staticClass:"q-splitter__separator",style:this.separatorStyle,class:this.separatorClass,attrs:e},[t("div",{staticClass:"absolute-full q-splitter__separator-area",directives:this.separatorDirectives},Ot(this,"separator"))]),t("div",{ref:"after",staticClass:"q-splitter__panel q-splitter__after"+(!0===this.reverse?"":" col"),style:this.styles.after,class:this.afterClass,on:ft(this,"stop",{input:b})},Ot(this,"after"))];return t("div",{staticClass:"q-splitter no-wrap",class:this.classes,on:Object.assign({},this.qListeners)},Et(i,this,"default"))}}),Va=t.extend({name:"StepHeader",mixins:[bt],directives:{Ripple:Se},props:{stepper:{},step:{}},computed:{isActive:function(){return this.stepper.value===this.step.name},isDisable:function(){var t=this.step.disable;return!0===t||""===t},isError:function(){var t=this.step.error;return!0===t||""===t},isDone:function(){var t=this.step.done;return!1===this.isDisable&&(!0===t||""===t)},headerNav:function(){var t=this.step.headerNav,e=!0===t||""===t||void 0===t;return!1===this.isDisable&&this.stepper.headerNav&&e},hasPrefix:function(){return this.step.prefix&&(!1===this.isActive||"none"===this.stepper.activeIcon)&&(!1===this.isError||"none"===this.stepper.errorIcon)&&(!1===this.isDone||"none"===this.stepper.doneIcon)},icon:function(){var t=this.step.icon||this.stepper.inactiveIcon;if(!0===this.isActive){var e=this.step.activeIcon||this.stepper.activeIcon;return"none"===e?t:e||this.$q.iconSet.stepper.active}if(!0===this.isError){var i=this.step.errorIcon||this.stepper.errorIcon;return"none"===i?t:i||this.$q.iconSet.stepper.error}if(!1===this.isDisable&&!0===this.isDone){var n=this.step.doneIcon||this.stepper.doneIcon;return"none"===n?t:n||this.$q.iconSet.stepper.done}return t},color:function(){var t=!0===this.isError?this.step.errorColor||this.stepper.errorColor:void 0;if(!0===this.isActive){var e=this.step.activeColor||this.stepper.activeColor||this.step.color;return void 0!==e?e:t}return void 0!==t?t:!1===this.isDisable&&!0===this.isDone?this.step.doneColor||this.stepper.doneColor||this.step.color||this.stepper.inactiveColor:this.step.color||this.stepper.inactiveColor},classes:function(){return"q-stepper__tab col-grow flex items-center no-wrap relative-position"+(void 0!==this.color?" text-"+this.color:"")+(!0===this.isError?" q-stepper__tab--error q-stepper__tab--error-with-"+(!0===this.hasPrefix?"prefix":"icon"):"")+(!0===this.isActive?" q-stepper__tab--active":"")+(!0===this.isDone?" q-stepper__tab--done":"")+(!0===this.headerNav?" q-stepper__tab--navigation q-focusable q-hoverable":"")+(!0===this.isDisable?" q-stepper__tab--disabled":"")}},methods:{activate:function(){void 0!==this.$refs.blurTarget&&this.$refs.blurTarget.focus(),!1===this.isActive&&this.stepper.goTo(this.step.name)},keyup:function(t){13===t.keyCode&&!1===this.isActive&&this.stepper.goTo(this.step.name)}},render:function(t){var e={class:this.classes};!0===this.stepper.headerNav&&(e.directives=[{name:"ripple",value:this.headerNav}]),!0===this.headerNav&&Object.assign(e,{on:ft(this,"headnavon",{click:this.activate,keyup:this.keyup}),attrs:!0===this.isDisable?{tabindex:-1,"aria-disabled":"true"}:{tabindex:this.qAttrs.tabindex||0}});var i=[t("div",{staticClass:"q-focus-helper",attrs:{tabindex:-1},ref:"blurTarget"}),t("div",{staticClass:"q-stepper__dot row flex-center q-stepper__line relative-position"},[t("span",{staticClass:"row flex-center"},[!0===this.hasPrefix?this.step.prefix:t(Ut,{props:{name:this.icon}})])])];if(void 0!==this.step.title&&null!==this.step.title){var n=[t("div",{staticClass:"q-stepper__title"},[this.step.title])];void 0!==this.step.caption&&null!==this.step.caption&&n.push(t("div",{staticClass:"q-stepper__caption"},[this.step.caption])),i.push(t("div",{staticClass:"q-stepper__label q-stepper__line relative-position"},n))}return t("div",e,i)}}),Na=t.extend({name:"QStepWrapper",render:function(t){return t("div",{staticClass:"q-stepper__step-content"},[t("div",{staticClass:"q-stepper__step-inner"},Ot(this,"default"))])}}),Ha=t.extend({name:"QStep",inject:{stepper:{default:function(){console.error("QStep needs to be child of QStepper")}}},mixins:[Qi],props:{icon:String,color:String,title:{type:String,required:!0},caption:String,prefix:[String,Number],doneIcon:String,doneColor:String,activeIcon:String,activeColor:String,errorIcon:String,errorColor:String,headerNav:{type:Boolean,default:!0},done:Boolean,error:Boolean},computed:{isActive:function(){return this.stepper.value===this.name},onEvents:function(){return!0!==this.isActive||!0!==this.stepper.vertical||!0!==this.$q.platform.is.ios&&!0===this.$q.platform.is.chrome?Object.assign({},this.qListeners):Object.assign({},this.qListeners,{scroll:this.__keepScroll})}},methods:{__keepScroll:function(t){var e=t.target;e.scrollTop>0&&(e.scrollTop=0),void 0!==this.qListeners.scroll&&this.qListeners.scroll(t)}},render:function(t){var e=this.stepper.vertical,i=!0===e&&!0===this.stepper.keepAlive?t("keep-alive",!0===this.isActive?[t(Na,{key:this.name},Ot(this,"default"))]:void 0):!0!==e||!0===this.isActive?Na.options.render.call(this,t):void 0;return t("div",{staticClass:"q-stepper__step",on:this.onEvents},!0===e?[t(Va,{props:{stepper:this.stepper,step:this}}),!0===this.stepper.animated?t(_o,[i]):i]:[i])}}),Qa=t.extend({name:"QStepper",provide:function(){return{stepper:this}},mixins:[Gt,Hi],props:{flat:Boolean,bordered:Boolean,alternativeLabels:Boolean,headerNav:Boolean,contracted:Boolean,headerClass:String,inactiveColor:String,inactiveIcon:String,doneIcon:String,doneColor:String,activeIcon:String,activeColor:String,errorIcon:String,errorColor:String},computed:{classes:function(){return"q-stepper q-stepper--"+(!0===this.vertical?"vertical":"horizontal")+(!0===this.flat||!0===this.isDark?" q-stepper--flat no-shadow":"")+(!0===this.bordered||!0===this.isDark&&!1===this.flat?" q-stepper--bordered":"")+(!0===this.isDark?" q-stepper--dark q-dark":"")},headerClasses:function(){return"q-stepper__header row items-stretch justify-between q-stepper__header--"+(!0===this.alternativeLabels?"alternative":"standard")+"-labels"+(!1===this.flat||!0===this.bordered?" q-stepper__header--border":"")+(!0===this.contracted?" q-stepper__header--contracted":"")+(void 0!==this.headerClass?" "+this.headerClass:"")}},methods:{__getContent:function(t){var e=this,i=Ot(this,"message",[]);if(!0===this.vertical){this.__isValidPanelName(this.value)&&this.__updatePanelIndex();var n=t("div",{staticClass:"q-stepper__content",on:ft(this,"stop",{input:b})},Ot(this,"default"));return void 0===i?[n]:i.concat(n)}return[t("div",{class:this.headerClasses},this.panels.map(function(i){var n=i.componentOptions.propsData;return t(Va,{key:n.name,props:{stepper:e,step:n}})}))].concat(i,t("div",{staticClass:"q-stepper__content q-panel-parent",directives:this.panelDirectives},this.__getPanelContent(t)))},__renderPanels:function(t){return t("div",{class:this.classes,on:Object.assign({},this.qListeners)},Et(this.__getContent(t),this,"navigation"))}}}),Wa=t.extend({name:"QStepperNavigation",mixins:[Lt],render:function(t){return t("div",{staticClass:"q-stepper__nav",on:Object.assign({},this.qListeners)},Ot(this,"default"))}}),Ya=t.extend({name:"QTh",mixins:[Lt],props:{props:Object,autoWidth:Boolean},render:function(t){var e,i,n=this,s=Object.assign({},this.qListeners);if(void 0===this.props)return t("th",{on:s,class:!0===this.autoWidth?"q-table--col-auto-width":null},Ot(this,"default"));var o=this.$vnode.key;if(o){if(void 0===(e=this.props.colsMap[o]))return}else e=this.props.col;if(!0===e.sortable){var r="right"===e.align?"unshift":"push";(i=Bt(this,"default",[]))[r](t(Ut,{props:{name:this.$q.iconSet.table.arrowUp},staticClass:e.__iconClass}))}else i=Ot(this,"default");var a=!0===e.sortable?{click:function(t){n.props.sort(e),n.$emit("click",t)}}:{};return t("th",{on:Object.assign({},s,a),style:e.headerStyle,class:e.__thClass+(!0===this.autoWidth?" q-table--col-auto-width":"")},i)}}),Ua={computed:{headerSelectedValue:function(){return!0===this.someRowsSelected?null:this.allRowsSelected}},methods:{__getTHead:function(t){var e=this.__getTHeadTR(t);return!0===this.loading&&void 0===this.$scopedSlots.loading&&e.push(t("tr",{staticClass:"q-table__progress"},[t("th",{staticClass:"relative-position",attrs:{colspan:this.computedColspan}},this.__getProgress(t))])),t("thead",e)},__getTHeadTR:function(t){var e=this,i=this.$scopedSlots.header,n=this.$scopedSlots["header-cell"];if(void 0!==i)return i(this.__getHeaderScope({header:!0})).slice();var s=this.computedCols.map(function(i){var s=e.$scopedSlots["header-cell-"+i.name],o=void 0!==s?s:n,r=e.__getHeaderScope({col:i});return void 0!==o?o(r):t(Ya,{key:i.name,props:{props:r}},i.label)});if(!0===this.singleSelection&&!0!==this.grid)s.unshift(t("th",{staticClass:"q-table--col-auto-width"},[" "]));else if(!0===this.multipleSelection){var o=this.$scopedSlots["header-selection"],r=void 0!==o?o(this.__getHeaderScope({})):[t(cn,{props:{color:this.color,value:this.headerSelectedValue,dark:this.isDark,dense:this.dense},on:ft(this,"inp",{input:this.__onMultipleSelectionSet})})];s.unshift(t("th",{staticClass:"q-table--col-auto-width"},r))}return[t("tr",{style:this.tableHeaderStyle,class:this.tableHeaderClass},s)]},__getHeaderScope:function(t){var e=this;return Object.assign(t,{cols:this.computedCols,sort:this.sort,colsMap:this.computedColsMap,color:this.color,dark:this.isDark,dense:this.dense}),!0===this.multipleSelection&&(Object.defineProperty(t,"selected",{get:function(){return e.headerSelectedValue},set:this.__onMultipleSelectionSet,configurable:!0,enumerable:!0}),t.partialSelected=this.someRowsSelected,t.multipleSelect=!0),t},__onMultipleSelectionSet:function(t){!0===this.someRowsSelected&&(t=!1),this.__updateSelection(this.computedRows.map(this.getRowKey),this.computedRows,t)}}},Ka={methods:{__getTBodyTR:function(t,e,i,n){var s=this,o=this.getRowKey(e),r=this.isRowSelected(o);if(void 0!==i)return i(this.__getBodyScope({key:o,row:e,pageIndex:n,__trClass:r?"selected":""}));var a=this.$scopedSlots["body-cell"],l=this.computedCols.map(function(i){var r=s.$scopedSlots["body-cell-"+i.name],l=void 0!==r?r:a;return void 0!==l?l(s.__getBodyCellScope({key:o,row:e,pageIndex:n,col:i})):t("td",{class:i.__tdClass(e),style:i.__tdStyle(e)},s.getCellValue(i,e))});if(!0===this.hasSelectionMode){var c=this.$scopedSlots["body-selection"],u=void 0!==c?c(this.__getBodySelectionScope({key:o,row:e,pageIndex:n})):[t(cn,{props:{value:r,color:this.color,dark:this.isDark,dense:this.dense},on:{input:function(t,i){s.__updateSelection([o],[e],t,i)}}})];l.unshift(t("td",{staticClass:"q-table--col-auto-width"},u))}var h={key:o,class:{selected:r},on:{}};return void 0!==this.qListeners["row-click"]&&(h.class["cursor-pointer"]=!0,h.on.click=function(t){s.$emit("row-click",t,e,n)}),void 0!==this.qListeners["row-dblclick"]&&(h.class["cursor-pointer"]=!0,h.on.dblclick=function(t){s.$emit("row-dblclick",t,e,n)}),void 0!==this.qListeners["row-contextmenu"]&&(h.class["cursor-pointer"]=!0,h.on.contextmenu=function(t){s.$emit("row-contextmenu",t,e,n)}),t("tr",h,l)},__getTBody:function(t){var e=this,i=this.$scopedSlots.body,n=this.$scopedSlots["top-row"],s=this.$scopedSlots["bottom-row"],o=this.computedRows.map(function(n,s){return e.__getTBodyTR(t,n,i,s)});return void 0!==n&&(o=n({cols:this.computedCols}).concat(o)),void 0!==s&&(o=o.concat(s({cols:this.computedCols}))),t("tbody",o)},__getVirtualTBodyTR:function(t){var e=this,i=this.$scopedSlots.body;return function(n){return e.__getTBodyTR(t,n.item,i,n.index)}},__getBodyScope:function(t){var e=this;return this.__injectBodyCommonScope(t),t.cols=t.cols.map(function(i){var n=Object.assign({},i);return Object.defineProperty(n,"value",{get:function(){return e.getCellValue(i,t.row)},configurable:!0,enumerable:!0}),n}),t},__getBodyCellScope:function(t){var e=this;return this.__injectBodyCommonScope(t),Object.defineProperty(t,"value",{get:function(){return e.getCellValue(t.col,t.row)},configurable:!0,enumerable:!0}),t},__getBodySelectionScope:function(t){return this.__injectBodyCommonScope(t),t},__injectBodyCommonScope:function(t){var e=this;Object.assign(t,{cols:this.computedCols,colsMap:this.computedColsMap,sort:this.sort,rowIndex:this.firstRowIndex+t.pageIndex,color:this.color,dark:this.isDark,dense:this.dense}),!0===this.hasSelectionMode&&Object.defineProperty(t,"selected",{get:function(){return e.isRowSelected(t.key)},set:function(i,n){e.__updateSelection([t.key],[t.row],i,n)},configurable:!0,enumerable:!0}),Object.defineProperty(t,"expand",{get:function(){return e.isRowExpanded(t.key)},set:function(i){e.__updateExpanded(t.key,i)},configurable:!0,enumerable:!0})},getCellValue:function(t,e){var i="function"==typeof t.field?t.field(e):e[t.field];return void 0!==t.format?t.format(i,e):i}}},Xa="q-table__bottom row items-center",Ga={props:{hideBottom:Boolean,hideSelectedBanner:Boolean,hideNoData:Boolean,hidePagination:Boolean},computed:{navIcon:function(){var t=[this.iconFirstPage||this.$q.iconSet.table.firstPage,this.iconPrevPage||this.$q.iconSet.table.prevPage,this.iconNextPage||this.$q.iconSet.table.nextPage,this.iconLastPage||this.$q.iconSet.table.lastPage];return!0===this.$q.lang.rtl?t.reverse():t}},methods:{__getBottomDiv:function(t){if(!0!==this.hideBottom){if(!0===this.nothingToDisplay){if(!0===this.hideNoData)return;var e=!0===this.loading?this.loadingLabel||this.$q.lang.table.loading:this.filter?this.noResultsLabel||this.$q.lang.table.noResults:this.noDataLabel||this.$q.lang.table.noData,i=this.$scopedSlots["no-data"],n=void 0!==i?[i({message:e,icon:this.$q.iconSet.table.warning,filter:this.filter})]:[t(Ut,{staticClass:"q-table__bottom-nodata-icon",props:{name:this.$q.iconSet.table.warning}}),e];return t("div",{staticClass:Xa+" q-table__bottom--nodata"},n)}var s=this.$scopedSlots.bottom;if(void 0!==s)return t("div",{staticClass:Xa},[s(this.marginalsScope)]);var o=!0!==this.hideSelectedBanner&&!0===this.hasSelectionMode&&this.rowsSelectedNumber>0?[t("div",{staticClass:"q-table__control"},[t("div",[(this.selectedRowsLabel||this.$q.lang.table.selectedRecords)(this.rowsSelectedNumber)])])]:[];return!0!==this.hidePagination?t("div",{staticClass:Xa+" justify-end"},this.__getPaginationDiv(t,o)):o.length>0?t("div",{staticClass:Xa},o):void 0}},__getPaginationDiv:function(t,e){var i,n=this,s=this.computedPagination.rowsPerPage,o=this.paginationLabel||this.$q.lang.table.pagination,r=this.$scopedSlots.pagination,a=this.rowsPerPageOptions.length>1;if(e.push(t("div",{staticClass:"q-table__separator col"})),!0===a&&e.push(t("div",{staticClass:"q-table__control"},[t("span",{staticClass:"q-table__bottom-item"},[this.rowsPerPageLabel||this.$q.lang.table.recordsPerPage]),t(da,{staticClass:"q-table__select inline q-table__bottom-item",props:{color:this.color,value:s,options:this.computedRowsPerPageOptions,displayValue:0===s?this.$q.lang.table.allRows:s,dark:this.isDark,borderless:!0,dense:!0,optionsDense:!0,optionsCover:!0},on:ft(this,"pgSize",{input:function(t){n.setPagination({page:1,rowsPerPage:t.value})}})})])),void 0!==r)i=r(this.marginalsScope);else if(i=[t("span",0!==s?{staticClass:"q-table__bottom-item"}:{},[s?o(this.firstRowIndex+1,Math.min(this.lastRowIndex,this.computedRowsNumber),this.computedRowsNumber):o(1,this.filteredSortedRowsNumber,this.computedRowsNumber)])],0!==s&&this.pagesNumber>1){var l={color:this.color,round:!0,dense:!0,flat:!0};!0===this.dense&&(l.size="sm"),this.pagesNumber>2&&i.push(t(Be,{key:"pgFirst",props:Object.assign({},l,{icon:this.navIcon[0],disable:this.isFirstPage}),on:ft(this,"pgFirst",{click:this.firstPage})})),i.push(t(Be,{key:"pgPrev",props:Object.assign({},l,{icon:this.navIcon[1],disable:this.isFirstPage}),on:ft(this,"pgPrev",{click:this.prevPage})}),t(Be,{key:"pgNext",props:Object.assign({},l,{icon:this.navIcon[2],disable:this.isLastPage}),on:ft(this,"pgNext",{click:this.nextPage})})),this.pagesNumber>2&&i.push(t(Be,{key:"pgLast",props:Object.assign({},l,{icon:this.navIcon[3],disable:this.isLastPage}),on:ft(this,"pgLast",{click:this.lastPage})}))}return e.push(t("div",{staticClass:"q-table__control"},i)),e}}},Za={methods:{__getGridHeader:function(t){return t("div",{staticClass:"q-table__middle"},!0===this.gridHeader?[t("table",{staticClass:"q-table"},[this.__getTHead(t)])]:!0===this.loading&&void 0===this.$scopedSlots.loading?this.__getProgress(t):void 0)},__getGridBody:function(t){var e=this,i=void 0!==this.$scopedSlots.item?this.$scopedSlots.item:function(i){var n=i.cols.map(function(e){return t("div",{staticClass:"q-table__grid-item-row"},[t("div",{staticClass:"q-table__grid-item-title"},[e.label]),t("div",{staticClass:"q-table__grid-item-value"},[e.value])])});if(!0===e.hasSelectionMode){var s=e.$scopedSlots["body-selection"],o=void 0!==s?s(i):[t(cn,{props:{value:i.selected,color:e.color,dark:e.isDark,dense:e.dense},on:{input:function(t,n){e.__updateSelection([i.key],[i.row],t,n)}}})];n.unshift(t("div",{staticClass:"q-table__grid-item-row"},o),t(So,{props:{dark:e.isDark}}))}var r={staticClass:"q-table__grid-item-card"+e.cardDefaultClass,class:e.cardClass,style:e.cardStyle,on:{}};return void 0===e.qListeners["row-click"]&&void 0===e.qListeners["row-dblclick"]||(r.staticClass+=" cursor-pointer"),void 0!==e.qListeners["row-click"]&&(r.on.click=function(t){e.$emit("row-click",t,i.row,i.pageIndex)}),void 0!==e.qListeners["row-dblclick"]&&(r.on.dblclick=function(t){e.$emit("row-dblclick",t,i.row,i.pageIndex)}),t("div",{staticClass:"q-table__grid-item col-xs-12 col-sm-6 col-md-4 col-lg-3",class:!0===i.selected?"q-table__grid-item--selected":""},[t("div",r,n)])};return t("div",{staticClass:"q-table__grid-content row",class:this.cardContainerClass,style:this.cardContainerStyle},this.computedRows.map(function(t,n){return i(e.__getBodyScope({key:e.getRowKey(t),row:t,pageIndex:n}))}))}}};function Ja(t,e,i){return t("div",Object.assign({},e,{staticClass:"q-table__middle"+(void 0!==e.staticClass?" "+e.staticClass:"")}),[t("table",{staticClass:"q-table"},i)])}var tl={list:Gs,table:xr},el=t.extend({name:"QVirtualScroll",mixins:[bt,Lt,ua],props:{type:{type:String,default:"list",validator:function(t){return["list","table","__qtable"].includes(t)}},items:{type:Array,default:function(){return[]}},itemsFn:Function,itemsSize:Number,scrollTarget:{default:void 0}},computed:{virtualScrollLength:function(){return this.itemsSize>=0&&void 0!==this.itemsFn?parseInt(this.itemsSize,10):Array.isArray(this.items)?this.items.length:0},virtualScrollScope:function(){var t=this;if(0===this.virtualScrollLength)return[];var e=function(e,i){return{index:t.virtualScrollSliceRange.from+i,item:e}};return void 0===this.itemsFn?this.items.slice(this.virtualScrollSliceRange.from,this.virtualScrollSliceRange.to).map(e):this.itemsFn(this.virtualScrollSliceRange.from,this.virtualScrollSliceRange.to-this.virtualScrollSliceRange.from).map(e)},classes:function(){return"q-virtual-scroll q-virtual-scroll"+(!0===this.virtualScrollHorizontal?"--horizontal":"--vertical")+(void 0!==this.scrollTarget?"":" scroll")},attrs:function(){return void 0!==this.scrollTarget?void 0:{tabindex:0}}},watch:{virtualScrollLength:function(){this.__resetVirtualScroll()},scrollTarget:function(){this.__unconfigureScrollTarget(),this.__configureScrollTarget()}},methods:{__getVirtualScrollEl:function(){return this.$el},__getVirtualScrollTarget:function(){return this.__scrollTarget},__configureScrollTarget:function(){this.__scrollTarget=ii(this.$el,this.scrollTarget),this.__scrollTarget.addEventListener("scroll",this.__onVirtualScrollEvt,h.passive)},__unconfigureScrollTarget:function(){void 0!==this.__scrollTarget&&(this.__scrollTarget.removeEventListener("scroll",this.__onVirtualScrollEvt,h.passive),this.__scrollTarget=void 0)}},beforeMount:function(){this.__resetVirtualScroll()},mounted:function(){this.__configureScrollTarget()},activated:function(){this.__configureScrollTarget()},deactivated:function(){this.__unconfigureScrollTarget()},beforeDestroy:function(){this.__unconfigureScrollTarget()},render:function(t){if(void 0!==this.$scopedSlots.default){var e=this.__padVirtualScroll(t,"list"===this.type?"div":"tbody",this.virtualScrollScope.map(this.$scopedSlots.default));return void 0!==this.$scopedSlots.before&&(e=this.$scopedSlots.before().concat(e)),e=Et(e,this,"after"),"__qtable"===this.type?Ja(t,{staticClass:this.classes},e):t(tl[this.type],{class:this.classes,attrs:this.attrs,props:this.qAttrs,on:Object.assign({},this.qListeners)},e)}console.error("QVirtualScroll: default scoped slot is required for rendering",this)}});var il={props:{sortMethod:{type:Function,default:function(t,e,i){var n=this.colList.find(function(t){return t.name===e});if(void 0===n||void 0===n.field)return t;var s=!0===i?-1:1,o="function"==typeof n.field?function(t){return n.field(t)}:function(t){return t[n.field]};return t.sort(function(t,e){var i,r=o(t),a=o(e);return null===r||void 0===r?-1*s:null===a||void 0===a?1*s:void 0!==n.sort?n.sort(r,a,t,e)*s:!0===tn(r)&&!0===tn(a)?(r-a)*s:!0===Ji(r)&&!0===Ji(a)?function(t,e){return new Date(t)-new Date(e)}(r,a)*s:"boolean"==typeof r&&"boolean"==typeof a?(r-a)*s:(r=(i=[r,a].map(function(t){return(t+"").toLocaleString().toLowerCase()}))[0])<(a=i[1])?-1*s:r===a?0:s})}},columnSortOrder:{type:String,validator:function(t){return"ad"===t||"da"===t},default:"ad"}},computed:{columnToSort:function(){var t=this.computedPagination.sortBy;if(t)return this.colList.find(function(e){return e.name===t})||null}},methods:{sort:function(t){var e=this.columnSortOrder;if(!0===Zi(t))t.sortOrder&&(e=t.sortOrder),t=t.name;else{var i=this.colList.find(function(e){return e.name===t});void 0!==i&&i.sortOrder&&(e=i.sortOrder)}var n=this.computedPagination,s=n.sortBy,o=n.descending;s!==t?(s=t,o="da"===e):!0===this.binaryStateSort?o=!o:!0===o?"ad"===e?s=null:o=!1:"ad"===e?o=!0:s=null,this.setPagination({sortBy:s,descending:o,page:1})}}},nl={props:{filter:[String,Object],filterMethod:{type:Function,default:function(t,e,i,n){void 0===i&&(i=this.computedCols),void 0===n&&(n=this.getCellValue);var s=e?e.toLowerCase():"";return t.filter(function(t){return i.some(function(e){var i=n(e,t)+"";return-1!==("undefined"===i||"null"===i?"":i.toLowerCase()).indexOf(s)})})}}},watch:{filter:{handler:function(){var t=this;this.$nextTick(function(){t.setPagination({page:1},!0)})},deep:!0}}};function sl(t){return t.page<1&&(t.page=1),void 0!==t.rowsPerPage&&t.rowsPerPage<1&&(t.rowsPerPage=0),t}var ol={props:{pagination:Object,rowsPerPageOptions:{type:Array,default:function(){return[5,7,10,15,20,25,50,0]}}},computed:{computedPagination:function(){return sl(void 0!==this.qListeners["update:pagination"]?Object.assign({},this.innerPagination,this.pagination):this.innerPagination)},firstRowIndex:function(){var t=this.computedPagination;return(t.page-1)*t.rowsPerPage},lastRowIndex:function(){var t=this.computedPagination;return t.page*t.rowsPerPage},isFirstPage:function(){return 1===this.computedPagination.page},pagesNumber:function(){return 0===this.computedPagination.rowsPerPage?1:Math.max(1,Math.ceil(this.computedRowsNumber/this.computedPagination.rowsPerPage))},isLastPage:function(){return 0===this.lastRowIndex||this.computedPagination.page>=this.pagesNumber},computedRowsPerPageOptions:function(){var t=this;return(this.rowsPerPageOptions.includes(this.innerPagination.rowsPerPage)?this.rowsPerPageOptions:[this.innerPagination.rowsPerPage].concat(this.rowsPerPageOptions)).map(function(e){return{label:0===e?t.$q.lang.table.allRows:""+e,value:e}})}},watch:{pagesNumber:function(t,e){if(t!==e){var i=this.computedPagination.page;t&&!i?this.setPagination({page:1}):t1&&this.setPagination({page:t-1})},nextPage:function(){var t=this.computedPagination,e=t.page,i=t.rowsPerPage;this.lastRowIndex>0&&e*i0&&this.computedRows.every(function(e){return!0===t.selectedKeys[t.getRowKey(e)]})},someRowsSelected:function(){var t=this;return!0!==this.allRowsSelected&&this.computedRows.some(function(e){return!0===t.selectedKeys[t.getRowKey(e)]})},rowsSelectedNumber:function(){return this.selected.length}},methods:{isRowSelected:function(t){return!0===this.selectedKeys[t]},clearSelection:function(){this.$emit("update:selected",[])},__updateSelection:function(t,e,i,n){var s=this;this.$emit("selection",{rows:e,added:i,keys:t,evt:n});var o=!0===this.singleSelection?!0===i?e:[]:!0===i?this.selected.concat(e):this.selected.filter(function(e){return!1===t.includes(s.getRowKey(e))});this.$emit("update:selected",o)}}};function al(t){return Array.isArray(t)?t.slice():[]}var ll={props:{expanded:Array},data:function(){return{innerExpanded:al(this.expanded)}},watch:{expanded:function(t){this.innerExpanded=al(t)}},methods:{isRowExpanded:function(t){return this.innerExpanded.includes(t)},setExpanded:function(t){void 0!==this.expanded?this.$emit("update:expanded",t):this.innerExpanded=t},__updateExpanded:function(t,e){var i=this.innerExpanded.slice(),n=i.indexOf(t);!0===e?-1===n&&(i.push(t),this.setExpanded(i)):-1!==n&&(i.splice(n,1),this.setExpanded(i))}}},cl={props:{visibleColumns:Array},computed:{colList:function(){if(void 0!==this.columns)return this.columns;var t=this.data[0];return void 0!==t?Object.keys(t).map(function(e){return{name:e,label:e.toUpperCase(),field:e,align:tn(t[e])?"right":"left",sortable:!0}}):[]},computedCols:function(){var t=this,e=this.computedPagination,i=e.sortBy,n=e.descending;return(void 0!==this.visibleColumns?this.colList.filter(function(e){return!0===e.required||!0===t.visibleColumns.includes(e.name)}):this.colList).map(function(t){var e=t.align||"right",s="text-"+e;return Object.assign({},t,{align:e,__iconClass:"q-table__sort-icon q-table__sort-icon--"+e,__thClass:s+(void 0!==t.headerClasses?" "+t.headerClasses:"")+(!0===t.sortable?" sortable":"")+(t.name===i?" sorted "+(!0===n?"sort-desc":""):""),__tdStyle:void 0!==t.style?"function"!=typeof t.style?function(){return t.style}:t.style:function(){return null},__tdClass:void 0!==t.classes?"function"!=typeof t.classes?function(){return s+" "+t.classes}:function(e){return s+" "+t.classes(e)}:function(){return s}})})},computedColsMap:function(){var t={};return this.computedCols.forEach(function(e){t[e.name]=e}),t},computedColspan:function(){return void 0!==this.tableColspan?this.tableColspan:this.computedCols.length+(!0===this.hasSelectionMode?1:0)}}},ul={};ca.forEach(function(t){ul[t]={}});var hl=t.extend({name:"QTable",mixins:[Gt,Lt,Yi,{computed:{marginalsScope:function(){return{pagination:this.computedPagination,pagesNumber:this.pagesNumber,isFirstPage:this.isFirstPage,isLastPage:this.isLastPage,firstPage:this.firstPage,prevPage:this.prevPage,nextPage:this.nextPage,lastPage:this.lastPage,inFullscreen:this.inFullscreen,toggleFullscreen:this.toggleFullscreen}}},methods:{__getTopDiv:function(t){var e,i=this.$scopedSlots.top,n=this.$scopedSlots["top-left"],s=this.$scopedSlots["top-right"],o=this.$scopedSlots["top-selection"],r=!0===this.hasSelectionMode&&void 0!==o&&this.rowsSelectedNumber>0,a="q-table__top relative-position row items-center";return void 0!==i?t("div",{staticClass:a},[i(this.marginalsScope)]):(!0===r?e=o(this.marginalsScope).slice():(e=[],void 0!==n?e.push(t("div",{staticClass:"q-table-control"},[n(this.marginalsScope)])):this.title&&e.push(t("div",{staticClass:"q-table__control"},[t("div",{staticClass:"q-table__title",class:this.titleClass},this.title)]))),void 0!==s&&(e.push(t("div",{staticClass:"q-table__separator col"})),e.push(t("div",{staticClass:"q-table__control"},[s(this.marginalsScope)]))),0!==e.length?t("div",{staticClass:a},e):void 0)}}},Ua,Ka,Ga,Za,il,nl,ol,rl,ll,cl],props:Object.assign({},{data:{type:Array,default:function(){return[]}},rowKey:{type:[String,Function],default:"id"},columns:Array,loading:Boolean,binaryStateSort:Boolean,iconFirstPage:String,iconPrevPage:String,iconNextPage:String,iconLastPage:String,title:String,hideHeader:Boolean,grid:Boolean,gridHeader:Boolean,dense:Boolean,flat:Boolean,bordered:Boolean,square:Boolean,separator:{type:String,default:"horizontal",validator:function(t){return["horizontal","vertical","cell","none"].includes(t)}},wrapCells:Boolean,virtualScroll:Boolean},ul,{noDataLabel:String,noResultsLabel:String,loadingLabel:String,selectedRowsLabel:Function,rowsPerPageLabel:String,paginationLabel:Function,color:{type:String,default:"grey-8"},titleClass:[String,Array,Object],tableStyle:[String,Array,Object],tableClass:[String,Array,Object],tableHeaderStyle:[String,Array,Object],tableHeaderClass:[String,Array,Object],cardContainerClass:[String,Array,Object],cardContainerStyle:[String,Array,Object],cardStyle:[String,Array,Object],cardClass:[String,Array,Object]}),data:function(){return{innerPagination:Object.assign({sortBy:null,descending:!1,page:1,rowsPerPage:this.rowsPerPageOptions.length>0?this.rowsPerPageOptions[0]:5},this.pagination)}},watch:{needsReset:function(){!0===this.hasVirtScroll&&void 0!==this.$refs.virtScroll&&this.$refs.virtScroll.reset()}},computed:{getRowKey:function(){var t=this;return"function"==typeof this.rowKey?this.rowKey:function(e){return e[t.rowKey]}},hasVirtScroll:function(){return!0!==this.grid&&!0===this.virtualScroll},needsReset:function(){var t=this;return["tableStyle","tableClass","tableHeaderStyle","tableHeaderClass","__containerClass"].map(function(e){return t[e]}).join(";")},filteredSortedRows:function(){var t=this.data;if(!0===this.isServerSide||0===t.length)return t;var e=this.computedPagination,i=e.sortBy,n=e.descending;return this.filter&&(t=this.filterMethod(t,this.filter,this.computedCols,this.getCellValue)),void 0!==this.columnToSort&&(t=this.sortMethod(this.data===t?t.slice():t,i,n)),t},filteredSortedRowsNumber:function(){return this.filteredSortedRows.length},computedRows:function(){var t=this.filteredSortedRows;return!0===this.isServerSide?t:(0!==this.computedPagination.rowsPerPage&&(0===this.firstRowIndex&&this.data!==t?t.length>this.lastRowIndex&&(t=t.slice(0,this.lastRowIndex)):t=t.slice(this.firstRowIndex,this.lastRowIndex)),t)},computedRowsNumber:function(){return!0===this.isServerSide?this.computedPagination.rowsNumber||0:this.filteredSortedRowsNumber},nothingToDisplay:function(){return 0===this.computedRows.length},isServerSide:function(){return void 0!==this.computedPagination.rowsNumber},cardDefaultClass:function(){return" q-table__card"+(!0===this.isDark?" q-table__card--dark q-dark":"")+(!0===this.square?" q-table--square":"")+(!0===this.flat?" q-table--flat":"")+(!0===this.bordered?" q-table--bordered":"")},__containerClass:function(){return"q-table__container q-table--"+this.separator+"-separator column no-wrap"+(!0===this.grid?" q-table--grid":this.cardDefaultClass)+(!0===this.isDark?" q-table--dark":"")+(!0===this.dense?" q-table--dense":"")+(!1===this.wrapCells?" q-table--no-wrap":"")+(!0===this.inFullscreen?" fullscreen scroll":"")},containerClass:function(){return this.__containerClass+(!0===this.loading?" q-table--loading":"")},virtProps:function(){var t=this,e={};return ca.forEach(function(i){e[i]=t[i]}),void 0===e.virtualScrollItemSize&&(e.virtualScrollItemSize=!0===this.dense?28:48),e}},render:function(t){var e=[this.__getTopDiv(t)],i={staticClass:this.containerClass};return!0===this.grid?e.push(this.__getGridHeader(t)):Object.assign(i,{class:this.cardClass,style:this.cardStyle}),e.push(this.__getBody(t),this.__getBottomDiv(t)),!0===this.loading&&void 0!==this.$scopedSlots.loading&&e.push(this.$scopedSlots.loading()),t("div",i,e)},methods:{requestServerInteraction:function(t){var e=this;void 0===t&&(t={}),this.$nextTick(function(){e.$emit("request",{pagination:t.pagination||e.computedPagination,filter:t.filter||e.filter,getCellValue:e.getCellValue})})},resetVirtualScroll:function(){!0===this.hasVirtScroll&&this.$refs.virtScroll.reset()},__getBody:function(t){var e=this;if(!0===this.grid)return this.__getGridBody(t);var i=!0!==this.hideHeader?this.__getTHead(t):null;if(!0===this.hasVirtScroll){var n=this.$scopedSlots["top-row"],s=this.$scopedSlots["bottom-row"],o={default:this.__getVirtualTBodyTR(t)};if(void 0!==n){var r=t("tbody",n({cols:this.computedCols}));o.before=null===i?function(){return[r]}:function(){return[i].concat(r)}}else null!==i&&(o.before=function(){return i});return void 0!==s&&(o.after=function(){return t("tbody",s({cols:e.computedCols}))}),t(el,{ref:"virtScroll",props:Object.assign({},this.virtProps,{items:this.computedRows,type:"__qtable",tableColspan:this.computedColspan}),on:ft(this,"vs",{"virtual-scroll":this.__onVScroll}),class:this.tableClass,style:this.tableStyle,scopedSlots:o})}return Ja(t,{staticClass:"scroll",class:this.tableClass,style:this.tableStyle},[i,this.__getTBody(t)])},scrollTo:function(t,e){if(void 0===this.$refs.virtScroll){t=parseInt(t,10);var i=this.$el.querySelector("tbody tr:nth-of-type("+(t+1)+")");if(null!==i){var n=this.$el.querySelector(".q-table__middle.scroll"),s=i.offsetTop,o=s12?t.hour-12:t.hour),minute:null===t.minute?"--":dt(t.minute),second:null===t.second?"--":dt(t.second)}},defaultDateModel:function(){return this.__getDefaultDateModel()},computedFormat24h:function(){return null!==this.format24h?this.format24h:this.$q.lang.date.format24h},pointerStyle:function(){var t="Hour"===this.view,e=!0===t?12:60,i=this.innerModel[this.view.toLowerCase()],n="rotate("+(Math.round(i*(360/e))-180)+"deg) translateX(-50%)";return!0===t&&!0===this.computedFormat24h&&this.innerModel.hour>=12&&(n+=" scale(.7)"),{transform:n}},minLink:function(){return null!==this.innerModel.hour},secLink:function(){return!0===this.minLink&&null!==this.innerModel.minute},hourInSelection:function(){var t=this;return void 0!==this.hourOptions?function(e){return t.hourOptions.includes(e)}:void 0!==this.options?function(e){return t.options(e,null,null)}:void 0},minuteInSelection:function(){var t=this;return void 0!==this.minuteOptions?function(e){return t.minuteOptions.includes(e)}:void 0!==this.options?function(e){return t.options(t.innerModel.hour,e,null)}:void 0},secondInSelection:function(){var t=this;return void 0!==this.secondOptions?function(e){return t.secondOptions.includes(e)}:void 0!==this.options?function(e){return t.options(t.innerModel.hour,t.innerModel.minute,e)}:void 0},validHours:function(){if(void 0!==this.hourInSelection){var t=this.__getValidValues(0,11,this.hourInSelection),e=this.__getValidValues(12,11,this.hourInSelection);return{am:t,pm:e,values:t.values.concat(e.values)}}},validMinutes:function(){if(void 0!==this.minuteInSelection)return this.__getValidValues(0,59,this.minuteInSelection)},validSeconds:function(){if(void 0!==this.secondInSelection)return this.__getValidValues(0,59,this.secondInSelection)},viewValidOptions:function(){switch(this.view){case"Hour":return this.validHours;case"Minute":return this.validMinutes;case"Second":return this.validSeconds}},positions:function(){var t,e,i=0,n=1,s=void 0!==this.viewValidOptions?this.viewValidOptions.values:void 0;"Hour"===this.view?!0===this.computedFormat24h?(t=0,e=23):(t=0,e=11,!1===this.isAM&&(i=12)):(t=0,e=55,n=5);for(var o=[],r=t,a=t;r<=e;r+=n,a++){var l=r+i,c=void 0!==s&&!1===s.includes(l),u="Hour"===this.view&&0===r?!0===this.computedFormat24h?"00":"12":r;o.push({val:l,index:a,disable:c,label:u})}return o}},methods:{setNow:function(){var t=Object.assign({},this.__getCurrentDate(),this.__getCurrentTime());this.__updateValue(t),Object.assign(this.innerModel,t),this.view="Hour"},__getValidValues:function(t,e,i){var n=Array.apply(null,{length:e+1}).map(function(e,n){var s=n+t;return{index:s,val:!0===i(s)}}).filter(function(t){return!0===t.val}).map(function(t){return t.index});return{min:n[0],max:n[n.length-1],values:n,threshold:e+1}},__getWheelDist:function(t,e,i){var n=Math.abs(t-e);return Math.min(n,i-n)},__getNormalizedClockValue:function(t,e){var i=e.min,n=e.max,s=e.values,o=e.threshold;if(t===i)return i;if(tn)return this.__getWheelDist(t,i,o)<=this.__getWheelDist(t,n,o)?i:n;var r=s.findIndex(function(e){return t<=e}),a=s[r-1],l=s[r];return t-a<=l-t?a:l},__getMask:function(){return"persian"!==this.calendar&&null!==this.mask?this.mask:"HH:mm"+(!0===this.withSeconds?":ss":"")},__getDefaultDateModel:function(){if("string"!=typeof this.defaultDate){var t=this.__getCurrentDate(!0);return t.dateHash=this.__getDayHash(t),t}return ps(this.defaultDate,"YYYY/MM/DD",void 0,this.calendar)},__click:function(t){!0!==this.__shouldAbortInteraction()&&(!0!==this.$q.platform.is.desktop&&this.__updateClock(t,this.__getClockRect()),this.__goToNextView())},__activate:function(t){!0!==this.__shouldAbortInteraction()&&this.__updateClock(t,this.__getClockRect())},__shouldAbortInteraction:function(){return!0===this._isBeingDestroyed||!0===this._isDestroyed||void 0!==this.viewValidOptions&&(0===this.viewValidOptions.values.length||"Hour"===this.view&&!0!==this.computedFormat24h&&0===this.validHours[!0===this.isAM?"am":"pm"].values.length)},__getClockRect:function(){var t=this.$refs.clock.getBoundingClientRect(),e=t.top,i=t.left,n=t.width/2;return{top:e+n,left:i+n,dist:.7*n}},__goToNextView:function(){"Hour"===this.view?this.view="Minute":this.withSeconds&&"Minute"===this.view&&(this.view="Second")},__drag:function(t){if(!0!==this.__shouldAbortInteraction()){if(!0===t.isFirst)return this.draggingClockRect=this.__getClockRect(),void(this.dragCache=this.__updateClock(t.evt,this.draggingClockRect));this.dragCache=this.__updateClock(t.evt,this.draggingClockRect,this.dragCache),!0===t.isFinal&&(this.draggingClockRect=!1,this.dragCache=null,this.__goToNextView())}},__updateClock:function(t,e,i){var n,s=m(t),o=Math.abs(s.top-e.top),r=Math.sqrt(Math.pow(Math.abs(s.top-e.top),2)+Math.pow(Math.abs(s.left-e.left),2)),a=Math.asin(o/r)*(180/Math.PI);if(a=s.top0&&this.validHours.pm.values.length>0?r>=e.dist:this.validHours.am.values.length>0;n=this.__getNormalizedClockValue(n+(!0===l?0:12),this.validHours[!0===l?"am":"pm"])}else n=Math.round(n),!0===this.computedFormat24h?r-1}},duration:Number,noConnectors:Boolean,noNodesLabel:String,noResultsLabel:String},computed:{classes:function(){return"q-tree q-tree--"+(!0===this.dense?"dense":"standard")+(!0===this.noConnectors?" q-tree--no-connectors":"")+(!0===this.isDark?" q-tree--dark":"")+(void 0!==this.color?" text-"+this.color:"")},hasSelection:function(){return void 0!==this.selected},computedIcon:function(){return this.icon||this.$q.iconSet.tree.icon},computedControlColor:function(){return this.controlColor||this.color},textColorClass:function(){if(void 0!==this.textColor)return"text-"+this.textColor},selectedColorClass:function(){var t=this.selectedColor||this.color;if(t)return"text-"+t},meta:function(){var t=this,e={},i=function(n,s){var o=n.tickStrategy||(s?s.tickStrategy:t.tickStrategy),r=n[t.nodeKey],a=n[t.childrenKey]&&n[t.childrenKey].length>0,l=!0!==a,c=!0!==n.disabled&&!0===t.hasSelection&&!1!==n.selectable,u=!0!==n.disabled&&!1!==n.expandable,h="none"!==o,d="strict"===o,p="leaf-filtered"===o,f="leaf"===o||"leaf-filtered"===o,m=!0!==n.disabled&&!1!==n.tickable;!0===f&&!0===m&&s&&!0!==s.tickable&&(m=!1);var v=n.lazy;!0===v&&void 0!==t.lazy[r]&&!0===Array.isArray(n[t.childrenKey])&&(v=t.lazy[r]);var g={key:r,parent:s,isParent:a,isLeaf:l,lazy:v,disabled:n.disabled,link:!0!==n.disabled&&(!0===c||!0===u&&(!0===a||!0===v)),children:[],matchesFilter:!t.filter||t.filterMethod(n,t.filter),selected:r===t.selected&&!0===c,selectable:c,expanded:!0===a&&t.innerExpanded.includes(r),expandable:u,noTick:!0===n.noTick||!0!==d&&v&&"loaded"!==v,tickable:m,tickStrategy:o,hasTicking:h,strictTicking:d,leafFilteredTicking:p,leafTicking:f,ticked:!0===d?t.innerTicked.includes(r):!0===l&&t.innerTicked.includes(r)};if(e[r]=g,!0===a&&(g.children=n[t.childrenKey].map(function(t){return i(t,g)}),t.filter&&(!0!==g.matchesFilter?g.matchesFilter=g.children.some(function(t){return t.matchesFilter}):!0!==g.noTick&&!0!==g.disabled&&!0===g.tickable&&!0===p&&!0===g.children.every(function(t){return!0!==t.matchesFilter||!0===t.noTick||!0!==t.tickable})&&(g.tickable=!1)),!0===g.matchesFilter&&(!0!==g.noTick&&!0!==d&&!0===g.children.every(function(t){return t.noTick})&&(g.noTick=!0),f))){if(g.ticked=!1,g.indeterminate=g.children.some(function(t){return!0===t.indeterminate}),g.tickable=!0===g.tickable&&g.children.some(function(t){return t.tickable}),!0!==g.indeterminate){var _=g.children.reduce(function(t,e){return!0===e.ticked?t+1:t},0);_===g.children.length?g.ticked=!0:_>0&&(g.indeterminate=!0)}!0===g.indeterminate&&(g.indeterminateNextState=g.children.every(function(t){return!0!==t.tickable||!0!==t.ticked}))}return g};return this.nodes.forEach(function(t){return i(t,null)}),e}},data:function(){return{lazy:{},innerTicked:this.ticked||[],innerExpanded:this.expanded||[]}},watch:{ticked:function(t){this.innerTicked=t},expanded:function(t){this.innerExpanded=t}},methods:{getNodeByKey:function(t){var e=this,i=[].reduce,n=function(s,o){return s||!o?s:!0===Array.isArray(o)?i.call(Object(o),n,s):o[e.nodeKey]===t?o:o[e.childrenKey]?n(null,o[e.childrenKey]):void 0};return n(null,this.nodes)},getTickedNodes:function(){var t=this;return this.innerTicked.map(function(e){return t.getNodeByKey(e)})},getExpandedNodes:function(){var t=this;return this.innerExpanded.map(function(e){return t.getNodeByKey(e)})},isExpanded:function(t){return!(!t||!this.meta[t])&&this.meta[t].expanded},collapseAll:function(){void 0!==this.expanded?this.$emit("update:expanded",[]):this.innerExpanded=[]},expandAll:function(){var t=this,e=this.innerExpanded,i=function(n){n[t.childrenKey]&&n[t.childrenKey].length>0&&!1!==n.expandable&&!0!==n.disabled&&(e.push(n[t.nodeKey]),n[t.childrenKey].forEach(i))};this.nodes.forEach(i),void 0!==this.expanded?this.$emit("update:expanded",e):this.innerExpanded=e},setExpanded:function(t,e,i,n){var s=this;if(void 0===i&&(i=this.getNodeByKey(t)),void 0===n&&(n=this.meta[t]),n.lazy&&"loaded"!==n.lazy){if("loading"===n.lazy)return;this.$set(this.lazy,t,"loading"),!0!==Array.isArray(i[this.childrenKey])&&this.$set(i,this.childrenKey,[]),this.$emit("lazy-load",{node:i,key:t,done:function(e){s.lazy[t]="loaded",s.$set(i,s.childrenKey,!0===Array.isArray(e)?e:[]),s.$nextTick(function(){var e=s.meta[t];e&&!0===e.isParent&&s.__setExpanded(t,!0)})},fail:function(){s.$delete(s.lazy,t),0===i[s.childrenKey].length&&s.$delete(i,s.childrenKey)}})}else!0===n.isParent&&!0===n.expandable&&this.__setExpanded(t,e)},__setExpanded:function(t,e){var i=this,n=this.innerExpanded,s=void 0!==this.expanded;if(!0===s&&(n=n.slice()),e){if(this.accordion&&this.meta[t]){var o=[];this.meta[t].parent?this.meta[t].parent.children.forEach(function(e){e.key!==t&&!0===e.expandable&&o.push(e.key)}):this.nodes.forEach(function(e){var n=e[i.nodeKey];n!==t&&o.push(n)}),o.length>0&&(n=n.filter(function(t){return!1===o.includes(t)}))}n=n.concat([t]).filter(function(t,e,i){return i.indexOf(t)===e})}else n=n.filter(function(e){return e!==t});!0===s?this.$emit("update:expanded",n):this.innerExpanded=n},isTicked:function(t){return!(!t||!this.meta[t])&&this.meta[t].ticked},setTicked:function(t,e){var i=this.innerTicked,n=void 0!==this.ticked;!0===n&&(i=i.slice()),i=e?i.concat(t).filter(function(t,e,i){return i.indexOf(t)===e}):i.filter(function(e){return!1===t.includes(e)}),!0===n&&this.$emit("update:ticked",i)},__getSlotScope:function(t,e,i){var n=this,s={tree:this,node:t,key:i,color:this.color,dark:this.isDark};return Object.defineProperty(s,"expanded",{get:function(){return e.expanded},set:function(t){t!==e.expanded&&n.setExpanded(i,t)},configurable:!0,enumerable:!0}),Object.defineProperty(s,"ticked",{get:function(){return e.ticked},set:function(t){t!==e.ticked&&n.setTicked([i],t)},configurable:!0,enumerable:!0}),s},__getChildren:function(t,e){var i=this;return(this.filter?e.filter(function(t){return i.meta[t[i.nodeKey]].matchesFilter}):e).map(function(e){return i.__getNode(t,e)})},__getNodeMedia:function(t,e){if(void 0!==e.icon)return t(Ut,{staticClass:"q-tree__icon q-mr-sm",props:{name:e.icon,color:e.iconColor}});var i=e.img||e.avatar;return i?t("img",{staticClass:"q-tree__"+(e.img?"img":"avatar")+" q-mr-sm",attrs:{src:i}}):void 0},__getNode:function(t,e){var i=this,n=e[this.nodeKey],s=this.meta[n],o=e.header&&this.$scopedSlots["header-"+e.header]||this.$scopedSlots["default-header"],r=!0===s.isParent?this.__getChildren(t,e[this.childrenKey]):[],a=r.length>0||s.lazy&&"loaded"!==s.lazy,l=e.body&&this.$scopedSlots["body-"+e.body]||this.$scopedSlots["default-body"],c=void 0!==o||void 0!==l?this.__getSlotScope(e,s,n):null;return void 0!==l&&(l=t("div",{staticClass:"q-tree__node-body relative-position"},[t("div",{class:this.textColorClass},[l(c)])])),t("div",{key:n,staticClass:"q-tree__node relative-position",class:{"q-tree__node--parent":a,"q-tree__node--child":!a}},[t("div",{staticClass:"q-tree__node-header relative-position row no-wrap items-center",class:{"q-tree__node--link q-hoverable q-focusable":s.link,"q-tree__node--selected":s.selected,"q-tree__node--disabled":s.disabled},attrs:{tabindex:s.link?0:-1},on:{click:function(t){i.__onClick(e,s,t)},keypress:function(t){!0!==Z(t)&&(13===t.keyCode?i.__onClick(e,s,t,!0):32===t.keyCode&&i.__onExpandClick(e,s,t,!0))}}},[t("div",{staticClass:"q-focus-helper",attrs:{tabindex:-1},ref:"blurTarget_"+s.key}),"loading"===s.lazy?t(ue,{staticClass:"q-tree__spinner",props:{color:this.computedControlColor}}):!0===a?t(Ut,{staticClass:"q-tree__arrow",class:{"q-tree__arrow--rotate":s.expanded},props:{name:this.computedIcon},on:{click:function(t){i.__onExpandClick(e,s,t)}}}):null,!0===s.hasTicking&&!0!==s.noTick?t(cn,{staticClass:"q-tree__tickbox",props:{value:!0===s.indeterminate?null:s.ticked,color:this.computedControlColor,dark:this.isDark,dense:!0,keepColor:!0,disable:!0!==s.tickable},on:{keydown:S,input:function(t){i.__onTickedClick(s,t)}}}):null,t("div",{staticClass:"q-tree__node-header-content col row no-wrap items-center",class:s.selected?this.selectedColorClass:this.textColorClass},[o?o(c):[this.__getNodeMedia(t,e),t("div",e[this.labelKey])]])]),!0===a?t(_o,{props:{duration:this.duration},on:ft(this,"slide",{show:function(){i.$emit("after-show")},hide:function(){i.$emit("after-hide")}})},[t("div",{staticClass:"q-tree__node-collapsible",class:this.textColorClass,directives:[{name:"show",value:s.expanded}]},[l,t("div",{staticClass:"q-tree__children",class:{"q-tree__node--disabled":s.disabled}},r)])]):l])},__blur:function(t){var e=this.$refs["blurTarget_"+t];void 0!==e&&e.focus()},__onClick:function(t,e,i,n){!0!==n&&this.__blur(e.key),this.hasSelection&&e.selectable?!1===this.noSelectionUnset?this.$emit("update:selected",e.key!==this.selected?e.key:null):e.key!==this.selected&&this.$emit("update:selected",e.key||null):this.__onExpandClick(t,e,i,n),"function"==typeof t.handler&&t.handler(t)},__onExpandClick:function(t,e,i,n){void 0!==i&&S(i),!0!==n&&this.__blur(e.key),this.setExpanded(e.key,!e.expanded,t,e)},__onTickedClick:function(t,e){if(!0===t.indeterminate&&(e=t.indeterminateNextState),t.strictTicking)this.setTicked([t.key],e);else if(t.leafTicking){var i=[],n=function(t){t.isParent?(!0!==e&&!0!==t.noTick&&!0===t.tickable&&i.push(t.key),!0===t.leafTicking&&t.children.forEach(n)):!0===t.noTick||!0!==t.tickable||!0===t.leafFilteredTicking&&!0!==t.matchesFilter||i.push(t.key)};n(t),this.setTicked(i,e)}}},render:function(t){var e=this.__getChildren(t,this.nodes);return t("div",{class:this.classes},0===e.length?this.filter?this.noResultsLabel||this.$q.lang.tree.noResults:this.noNodesLabel||this.$q.lang.tree.noNodes:e)},created:function(){!0===this.defaultExpandAll&&this.expandAll()}}),ql=t.extend({name:"QUploaderBase",mixins:[Gt,Ho],props:{label:String,color:String,textColor:String,square:Boolean,flat:Boolean,bordered:Boolean,noThumbnails:Boolean,autoUpload:Boolean,hideUploadBtn:Boolean,disable:Boolean,readonly:Boolean},provide:function(){return{__qUploaderGetInput:this.__getInputControl}},data:function(){return{files:[],queuedFiles:[],uploadedFiles:[],dnd:!1,expanded:!1,uploadSize:0,uploadedSize:0}},watch:{isUploading:function(t,e){!1===e&&!0===t?this.$emit("start"):!0===e&&!1===t&&this.$emit("finish")}},computed:{canUpload:function(){return!0===this.editable&&!0!==this.isBusy&&!0!==this.isUploading&&this.queuedFiles.length>0},canAddFiles:function(){return!0===this.editable&&!0!==this.isUploading&&(!0===this.multiple||0===this.queuedFiles.length)&&(void 0===this.maxFiles||this.files.length0&&(this.files=n,void 0!==e&&e(i),this.$emit("removed",i.files))}},removeFile:function(t){this.disable||("uploaded"===t.__status?this.uploadedFiles=this.uploadedFiles.filter(function(e){return e.__key!==t.__key}):"uploading"===t.__status?t.__abort():this.uploadSize-=t.size,this.files=this.files.filter(function(e){return e.__key!==t.__key||(void 0!==e.__img&&window.URL.revokeObjectURL(e.__img.src),!1)}),this.queuedFiles=this.queuedFiles.filter(function(e){return e.__key!==t.__key}),this.$emit("removed",[t]))},__revokeImgURLs:function(){this.files.forEach(function(t){void 0!==t.__img&&window.URL.revokeObjectURL(t.__img.src)})},__getFileInput:function(){return this.$refs.input||this.$el.getElementsByClassName("q-uploader__input")[0]},__getProgressLabel:function(t){return(100*t).toFixed(2)+"%"},__updateFile:function(t,e,i){if(t.__status=e,"idle"===e)return t.__uploaded=0,t.__progress=0,t.__sizeLabel=lt(t.size),void(t.__progressLabel="0.00%");"failed"!==e?(t.__uploaded="uploaded"===e?t.size:i,t.__progress="uploaded"===e?1:Math.min(.9999,t.__uploaded/t.size),t.__progressLabel=this.__getProgressLabel(t.__progress),this.$forceUpdate()):this.$forceUpdate()},__addFiles:function(t,e){var i=this,n=this.__processFiles(t,e,this.files,!0);if(void 0!==n){var s=this.__getFileInput();void 0!==s&&(s.value=""),n.forEach(function(t){if(i.__updateFile(t,"idle"),i.uploadSize+=t.size,!0!==i.noThumbnails&&t.type.toUpperCase().startsWith("IMAGE")){var e=new Image;e.src=window.URL.createObjectURL(t),t.__img=e}}),this.files=this.files.concat(n),this.queuedFiles=this.queuedFiles.concat(n),this.$emit("added",n),!0===this.autoUpload&&this.upload()}},__getBtn:function(t,e,i,n){if(!0===e)return t(Be,{props:{type:"a",icon:this.$q.iconSet.uploader[i],flat:!0,dense:!0},on:{click:"add"===i?this.pickFiles:n}},"add"===i?this.__getInputControl(t):null)},__getInputControl:function(t){return[t("input",{ref:"input",staticClass:"q-uploader__input overflow-hidden absolute-full",attrs:Object.assign({},{tabindex:-1,type:"file",title:"",accept:this.accept,capture:this.capture},!0===this.multiple?{multiple:!0}:{}),on:ft(this,"input",{mousedown:b,click:this.pickFiles,change:this.__addFiles})})]},__getHeader:function(t){return void 0!==this.$scopedSlots.header?this.$scopedSlots.header(this):[t("div",{staticClass:"q-uploader__header-content column"},[t("div",{staticClass:"flex flex-center no-wrap q-gutter-xs"},[this.__getBtn(t,this.queuedFiles.length>0,"removeQueue",this.removeQueuedFiles),this.__getBtn(t,this.uploadedFiles.length>0,"removeUploaded",this.removeUploadedFiles),!0===this.isUploading?t(ue,{staticClass:"q-uploader__spinner"}):null,t("div",{staticClass:"col column justify-center"},[void 0!==this.label?t("div",{staticClass:"q-uploader__title"},[this.label]):null,t("div",{staticClass:"q-uploader__subtitle"},[this.uploadSizeLabel+" / "+this.uploadProgressLabel])]),this.__getBtn(t,this.canAddFiles,"add",this.pickFiles),this.__getBtn(t,!1===this.hideUploadBtn&&!0===this.canUpload,"upload",this.upload),this.__getBtn(t,this.isUploading,"clear",this.abort)])])]},__getList:function(t){var e=this;return void 0!==this.$scopedSlots.list?this.$scopedSlots.list(this):this.files.map(function(i){return t("div",{key:i.__key,staticClass:"q-uploader__file relative-position",class:{"q-uploader__file--img":!0!==e.noThumbnails&&void 0!==i.__img,"q-uploader__file--failed":"failed"===i.__status,"q-uploader__file--uploaded":"uploaded"===i.__status},style:!0!==e.noThumbnails&&void 0!==i.__img?{backgroundImage:'url("'+i.__img.src+'")'}:null},[t("div",{staticClass:"q-uploader__file-header row flex-center no-wrap"},["failed"===i.__status?t(Ut,{staticClass:"q-uploader__file-status",props:{name:e.$q.iconSet.type.negative,color:"negative"}}):null,t("div",{staticClass:"q-uploader__file-header-content col"},[t("div",{staticClass:"q-uploader__title"},[i.name]),t("div",{staticClass:"q-uploader__subtitle row items-center no-wrap"},[i.__sizeLabel+" / "+i.__progressLabel])]),"uploading"===i.__status?t(pn,{props:{value:i.__progress,min:0,max:1,indeterminate:0===i.__progress}}):t(Be,{props:{round:!0,dense:!0,flat:!0,icon:e.$q.iconSet.uploader["uploaded"===i.__status?"done":"clear"]},on:{click:function(){e.removeFile(i)}}})])])})}},beforeDestroy:function(){!0===this.isUploading&&this.abort(),this.files.length>0&&this.__revokeImgURLs()},render:function(t){var e=[t("div",{staticClass:"q-uploader__header",class:this.colorClass},this.__getHeader(t)),t("div",{staticClass:"q-uploader__list scroll"},this.__getList(t)),this.__getDnd(t,"uploader")];return!0===this.isBusy&&e.push(t("div",{staticClass:"q-uploader__overlay absolute-full flex flex-center"},[t(ue)])),t("div",{staticClass:"q-uploader column no-wrap",class:{"q-uploader--dark q-dark":this.isDark,"q-uploader--bordered":this.bordered,"q-uploader--square no-border-radius":this.square,"q-uploader--flat no-shadow":this.flat,"disabled q-uploader--disable":this.disable,"q-uploader--dnd":this.dnd},on:!0===this.canAddFiles?ft(this,"drag",{dragover:this.__onDragOver,dragleave:this.__onDragLeave}):null},e)}});function Tl(t){return"function"==typeof t?t:function(){return t}}var Ml={props:{url:[Function,String],method:{type:[Function,String],default:"POST"},fieldName:{type:[Function,String],default:function(t){return t.name}},headers:[Function,Array],formFields:[Function,Array],withCredentials:[Function,Boolean],sendRaw:[Function,Boolean],batch:[Function,Boolean],factory:Function},data:function(){return{xhrs:[],promises:[],workingThreads:0}},computed:{xhrProps:function(){return{url:Tl(this.url),method:Tl(this.method),headers:Tl(this.headers),formFields:Tl(this.formFields),fieldName:Tl(this.fieldName),withCredentials:Tl(this.withCredentials),sendRaw:Tl(this.sendRaw),batch:Tl(this.batch)}},isUploading:function(){return this.workingThreads>0},isBusy:function(){return this.promises.length>0}},methods:{abort:function(){this.xhrs.forEach(function(t){t.abort()}),this.promises.length>0&&(this.abortPromises=!0)},upload:function(){var t=this;if(!1!==this.canUpload){var e=this.queuedFiles.slice(0);this.queuedFiles=[],this.xhrProps.batch(e)?this.__runFactory(e):e.forEach(function(e){t.__runFactory([e])})}},__runFactory:function(t){var e=this;if(this.workingThreads++,"function"==typeof this.factory){var i=this.factory(t);if(i)if("function"==typeof i.catch&&"function"==typeof i.then){this.promises.push(i);var n=function(n){!0!==e._isBeingDestroyed&&!0!==e._isDestroyed&&(e.promises=e.promises.filter(function(t){return t!==i}),0===e.promises.length&&(e.abortPromises=!1),e.queuedFiles=e.queuedFiles.concat(t),t.forEach(function(t){e.__updateFile(t,"failed")}),e.$emit("factory-failed",n,t),e.workingThreads--)};i.then(function(s){!0===e.abortPromises?n(new Error("Aborted")):!0!==e._isBeingDestroyed&&!0!==e._isDestroyed&&(e.promises=e.promises.filter(function(t){return t!==i}),e.__uploadFiles(t,s))}).catch(n)}else this.__uploadFiles(t,i||{});else this.$emit("factory-failed",new Error("QUploader: factory() does not return properly"),t),this.workingThreads--}else this.__uploadFiles(t,{})},__uploadFiles:function(t,e){var i=this,n=new FormData,s=new XMLHttpRequest,o=function(t,n){return void 0!==e[t]?Tl(e[t])(n):i.xhrProps[t](n)},r=o("url",t);if(!r)return console.error("q-uploader: invalid or no URL specified"),void this.workingThreads--;var a=o("formFields",t);void 0!==a&&a.forEach(function(t){n.append(t.name,t.value)});var l,c=0,u=0,h=0,d=0;s.upload.addEventListener("progress",function(e){if(!0!==l){var n=Math.min(d,e.loaded);i.uploadedSize+=n-h;for(var s=(h=n)-u,o=c;s>0&&or.size))return void i.__updateFile(r,"uploading",s);s-=r.size,c++,u+=r.size,i.__updateFile(r,"uploading",r.size)}}},!1),s.onreadystatechange=function(){s.readyState<4||(s.status&&s.status<400?(i.uploadedFiles=i.uploadedFiles.concat(t),t.forEach(function(t){i.__updateFile(t,"uploaded")}),i.$emit("uploaded",{files:t,xhr:s})):(l=!0,i.uploadedSize-=h,i.queuedFiles=i.queuedFiles.concat(t),t.forEach(function(t){i.__updateFile(t,"failed")}),i.$emit("failed",{files:t,xhr:s})),i.workingThreads--,i.xhrs=i.xhrs.filter(function(t){return t!==s}))},s.open(o("method",t),r),!0===o("withCredentials",t)&&(s.withCredentials=!0);var p=o("headers",t);void 0!==p&&p.forEach(function(t){s.setRequestHeader(t.name,t.value)});var f=o("sendRaw",t);t.forEach(function(t){i.__updateFile(t,"uploading",0),!0!==f&&n.append(o("fieldName",t),t,t.name),t.xhr=s,t.__abort=function(){s.abort()},d+=t.size}),this.$emit("uploading",{files:t,xhr:s}),this.xhrs.push(s),!0===f?s.send(new Blob(t)):s.send(n)}}},$l=t.extend({name:"QUploader",mixins:[ql,Ml]}),Ll=t.extend({name:"QUploaderAddTrigger",inject:{__qUploaderGetInput:{default:function(){console.error("QUploaderAddTrigger needs to be child of QUploader")}}},render:function(t){return this.__qUploaderGetInput(t)}}),Ol=t.extend({name:"QVideo",mixins:[Xo,Lt],props:{src:{type:String,required:!0},title:String,fetchpriority:{type:String,default:"auto"},loading:{type:String,default:"eager"},referrerpolicy:{type:String,default:"strict-origin-when-cross-origin"}},computed:{iframeData:function(){return{attrs:{src:this.src,frameborder:"0",title:this.title,allowfullscreen:!0,fetchpriority:this.fetchpriority,loading:this.loading,referrerpolicy:this.referrerpolicy}}},classes:function(){return"q-video"+(void 0!==this.ratio?" q-video--responsive":"")}},render:function(t){return t("div",{class:this.classes,style:this.ratioStyle,on:Object.assign({},this.qListeners)},[t("iframe",this.iframeData)])}}),Bl=Object.freeze({__proto__:null,QAjaxBar:kt,QAvatar:Kt,QBadge:Xt,QBanner:Jt,QBar:ee,QBreadcrumbs:re,QBreadcrumbsEl:le,QBtn:Be,QBtnDropdown:$i,QBtnGroup:Ee,QBtnToggle:Bi,QCard:Ei,QCardSection:zi,QCardActions:Pi,QCarousel:en,QCarouselSlide:nn,QCarouselControl:sn,QChatMessage:on,QCheckbox:cn,QChip:un,QCircularProgress:pn,QColor:Vn,QDate:zs,QDialog:Ys,QDrawer:Ks,QEditor:vo,QExpansionItem:Co,QFab:Mo,QFabAction:Oo,QField:jo,QFile:Wo,QFooter:Yo,QForm:Uo,QHeader:Ko,QIcon:Ut,QImg:Go,QInfiniteScroll:Jo,QInnerLoading:tr,QInput:pr,QIntersection:_r,QList:Gs,QItem:Zs,QItemSection:Js,QItemLabel:go,QKnob:yr,QLayout:Cr,QMarkupTable:xr,QMenu:Mi,QNoSsr:kr,QOptionGroup:Lr,QPage:Or,QPageContainer:Br,QPageScroller:zr,QPageSticky:Er,QPagination:Pr,QParallax:Dr,QPopupEdit:Fr,QPopupProxy:jr,QLinearProgress:Nr,QPullToRefresh:Hr,QRadio:qr,QRange:Ur,QRating:Kr,QResizeObserver:Ln,QResponsive:Xr,QScrollArea:ta,QScrollObserver:wr,QSelect:da,QSeparator:So,QSkeleton:ma,QSlideItem:ga,QSlideTransition:_o,QSlider:Mn,QSpace:_a,QSpinner:ue,QSpinnerAudio:ba,QSpinnerBall:ya,QSpinnerBars:Sa,QSpinnerBox:wa,QSpinnerClock:Ca,QSpinnerComment:xa,QSpinnerCube:ka,QSpinnerDots:qa,QSpinnerFacebook:Ta,QSpinnerGears:Ma,QSpinnerGrid:$a,QSpinnerHearts:La,QSpinnerHourglass:Oa,QSpinnerInfinity:Ba,QSpinnerIos:Ea,QSpinnerOrbit:za,QSpinnerOval:Pa,QSpinnerPie:Aa,QSpinnerPuff:Ia,QSpinnerRadio:Da,QSpinnerRings:Ra,QSpinnerTail:Fa,QSplitter:ja,QStep:Ha,QStepper:Qa,QStepperNavigation:Wa,QTabPanels:Rn,QTabPanel:Fn,QTable:hl,QTh:Ya,QTr:dl,QTd:pl,QTabs:An,QTab:Dn,QRouteTab:_l,QTime:bl,QTimeline:yl,QTimelineEntry:Sl,QToggle:Tr,QToolbar:wl,QToolbarTitle:Cl,QTooltip:Xs,QTree:kl,QUploader:$l,QUploaderBase:ql,QUploaderAddTrigger:Ll,QVideo:Ol,QVirtualScroll:el});function El(t){if(!1===t)return 0;if(!0===t||void 0===t)return 1;var e=parseInt(t,10);return isNaN(e)?0:e}function zl(t){var e=t.__qclosepopup;void 0!==e&&(t.removeEventListener("click",e.handler),t.removeEventListener("keyup",e.handlerKey),delete t.__qclosepopup)}var Pl={name:"close-popup",bind:function(t,e,i){var n=e.value;void 0!==t.__qclosepopup&&(zl(t),t.__qclosepopup_destroyed=!0);var s={depth:El(n),handler:function(t){0!==s.depth&&setTimeout(function(){!function(t,e,i){for(;0!==i&&void 0!==t;){if(void 0!==t.__renderPortal){if(i--,"QMenu"===t.$options.name){t=Ne(t,e);continue}t.hide(e)}t=t.$parent}}(i.componentInstance||i.context,t,s.depth)})},handlerKey:function(t){!0===J(t,13)&&s.handler(t)}};t.__qclosepopup=s,t.addEventListener("click",s.handler),t.addEventListener("keyup",s.handlerKey)},update:function(t,e){var i=e.value,n=e.oldValue;void 0!==t.__qclosepopup&&i!==n&&(t.__qclosepopup.depth=El(i))},unbind:function(t){void 0===t.__qclosepopup_destroyed?zl(t):delete t.__qclosepopup_destroyed}};function Al(t){var e=t.__qgoback;void 0!==e&&(t.removeEventListener("click",e.goBack),t.removeEventListener("keyup",e.goBackKey),delete t.__qgoback)}var Il={name:"go-back",bind:function(t,e,i){var n=e.value,s=e.modifiers;void 0!==t.__qgoback&&(Al(t),t.__qgoback_destroyed=!0);var o={value:n,position:window.history.length-1,single:s.single,goBack:function(){var t=i.context.$router;!0===o.single?t.go(-1):!0===c.is.nativeMobile?t.go(o.position-window.history.length):t.replace(o.value)},goBackKey:function(t){!0===J(t,13)&&o.goBack()}};t.__qgoback=o,t.addEventListener("click",o.goBack),t.addEventListener("keyup",o.goBackKey)},update:function(t,e){var i=e.value,n=e.oldValue,s=t.__qgoback;void 0!==s&&i!==n&&(s.value=i)},unbind:function(t){void 0===t.__qgoback_destroyed?Al(t):delete t.__qgoback_destroyed}},Dl=0,Rl=void 0;function Fl(t,e){void 0===Rl&&((Rl=document.createElement("div")).style.cssText="position: absolute; left: 0; top: 0",document.body.appendChild(Rl));var i=t.getBoundingClientRect(),n=Rl.getBoundingClientRect(),s=window.getComputedStyle(t),o=s.marginLeft,r=s.marginRight,a=s.marginTop,l=s.marginBottom,c=parseInt(o,10)+parseInt(r,10),u=parseInt(a,10)+parseInt(l,10);return{left:i.left-n.left,top:i.top-n.top,width:i.right-i.left,height:i.bottom-i.top,widthM:i.right-i.left+(!0===e?0:c),heightM:i.bottom-i.top+(!0===e?0:u),marginH:!0===e?c:0,marginV:!0===e?u:0}}function jl(t){return{width:t.scrollWidth,height:t.scrollHeight}}var Vl=["Top","Right","Bottom","Left"],Nl=["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],Hl=/-block|-inline|block-|inline-/,Ql=/(-block|-inline|block-|inline-).*:/;function Wl(t,e){for(var i=window.getComputedStyle(t),n={},s=0;s-1){for(var c=o.replace("border",""),u="",h=0;hi&&(e===t||!0===Yl.includes(s))&&(i=r),e=e.parentNode}return i}function Kl(t){return t&&t.ownerDocument===document&&null!==t.parentNode}function Xl(t){var e,i=function(){return!1},n=!1,s=!0,o={from:(e=t).from,to:void 0!==e.to?e.to:e.from},r=function(t){return"number"==typeof t?t={duration:t}:"function"==typeof t&&(t={onEnd:t}),Object.assign({},t,{waitFor:void 0===t.waitFor?0:t.waitFor,duration:!0===isNaN(t.duration)?300:parseInt(t.duration,10),easing:"string"==typeof t.easing&&t.easing.length>0?t.easing:"ease-in-out",delay:!0===isNaN(t.delay)?0:parseInt(t.delay,10),fill:"string"==typeof t.fill&&t.fill.length>0?t.fill:"none",resize:!0===t.resize,useCSS:!0===t.useCSS,hideFromClone:!0===t.hideFromClone,keepToClone:!0===t.keepToClone,tween:!0===t.tween,tweenFromOpacity:!0===isNaN(t.tweenFromOpacity)?.6:parseFloat(t.tweenFromOpacity),tweenToOpacity:!0===isNaN(t.tweenToOpacity)?.5:parseFloat(t.tweenToOpacity)})}(t),a=fe(o.from);if(!0!==Kl(a))return i;"function"==typeof a.qMorphCancel&&a.qMorphCancel();var l=void 0,c=void 0,u=void 0,h=void 0,d=a.parentNode,p=a.nextElementSibling,f=Fl(a,r.resize),m=jl(d),v=m.width,g=m.height,_=Wl(a,["borderWidth","borderStyle","borderColor","borderRadius","backgroundColor","transform","position","cssText"]),b=_.borderWidth,y=_.borderStyle,S=_.borderColor,w=_.borderRadius,C=_.backgroundColor,x=_.transform,k=_.position,q=_.cssText,T=a.classList.toString(),M=a.style.cssText,$=a.cloneNode(!0),L=!0===r.tween?a.cloneNode(!0):void 0;void 0!==L&&(L.className=L.classList.toString().split(" ").filter(function(t){return!1===/^bg-/.test(t)}).join(" ")),!0===r.hideFromClone&&$.classList.add("q-morph--internal"),$.setAttribute("aria-hidden","true"),$.style.transition="none",$.style.animation="none",$.style.pointerEvents="none",d.insertBefore($,p),a.qMorphCancel=function(){n=!0,$.remove(),void 0!==L&&L.remove(),!0===r.hideFromClone&&$.classList.remove("q-morph--internal"),a.qMorphCancel=void 0};return"function"==typeof t.onToggle&&t.onToggle(),requestAnimationFrame(function(){var t=fe(o.to);if(!0!==n&&!0===Kl(t)){a!==t&&"function"==typeof t.qMorphCancel&&t.qMorphCancel(),!0!==r.keepToClone&&t.classList.add("q-morph--internal"),$.classList.add("q-morph--internal");var e=jl(d),p=e.width,m=e.height,_=jl(t.parentNode),O=_.width,B=_.height;!0!==r.hideFromClone&&$.classList.remove("q-morph--internal"),t.qMorphCancel=function(){n=!0,$.remove(),void 0!==L&&L.remove(),!0===r.hideFromClone&&$.classList.remove("q-morph--internal"),!0!==r.keepToClone&&t.classList.remove("q-morph--internal"),a.qMorphCancel=void 0,t.qMorphCancel=void 0};var E=function(){if(!0!==n){!0!==r.hideFromClone&&($.classList.add("q-morph--internal"),$.innerHTML="",$.style.left=0,$.style.right="unset",$.style.top=0,$.style.bottom="unset",$.style.transform="none"),!0!==r.keepToClone&&t.classList.remove("q-morph--internal");var e=t.parentNode,o=jl(e),_=o.width,E=o.height,z=t.cloneNode(r.keepToClone);z.setAttribute("aria-hidden","true"),!0!==r.keepToClone&&(z.style.left=0,z.style.right="unset",z.style.top=0,z.style.bottom="unset",z.style.transform="none",z.style.pointerEvents="none"),z.classList.add("q-morph--internal");var P=t===a&&d===e?$:t.nextElementSibling;e.insertBefore(z,P);var A=Wl(t,["borderWidth","borderStyle","borderColor","borderRadius","backgroundColor","transform","position","cssText"]),I=A.borderWidth,D=A.borderStyle,R=A.borderColor,F=A.borderRadius,j=A.backgroundColor,V=A.transform,N=A.position,H=A.cssText,Q=t.classList.toString(),W=t.style.cssText;t.style.cssText=H,t.style.transform="none",t.style.animation="none",t.style.transition="none",t.className=Q.split(" ").filter(function(t){return!1===/^bg-/.test(t)}).join(" ");for(var Y=Fl(t,r.resize),U=f.left-Y.left,K=f.top-Y.top,X=f.width/(Y.width>0?Y.width:10),G=f.height/(Y.height>0?Y.height:100),Z=v-p,J=g-m,tt=_-O,et=E-B,it=Math.max(f.widthM,Z),nt=Math.max(f.heightM,J),st=Math.max(Y.widthM,tt),ot=Math.max(Y.heightM,et),rt=a===t&&!1===["absolute","fixed"].includes(N)&&!1===["absolute","fixed"].includes(k),at="fixed"===N,lt=e;!0!==at&<!==document;)at="fixed"===window.getComputedStyle(lt).position,lt=lt.parentNode;if(!0!==r.hideFromClone&&($.style.display="block",$.style.flex="0 0 auto",$.style.opacity=0,$.style.minWidth="unset",$.style.maxWidth="unset",$.style.minHeight="unset",$.style.maxHeight="unset",$.classList.remove("q-morph--internal")),!0!==r.keepToClone&&(z.style.display="block",z.style.flex="0 0 auto",z.style.opacity=0,z.style.minWidth="unset",z.style.maxWidth="unset",z.style.minHeight="unset",z.style.maxHeight="unset"),z.classList.remove("q-morph--internal"),"string"==typeof r.classes&&(t.className+=" "+r.classes),"string"==typeof r.style)t.style.cssText+=" "+r.style;else if(!0===Zi(r.style))for(var ct in r.style)t.style[ct]=r.style[ct];var ut=Ul($),ht=Ul(t),dt=!0===at?document.documentElement:{scrollLeft:0,scrollTop:0};t.style.position=!0===at?"fixed":"absolute",t.style.left=Y.left-dt.scrollLeft+"px",t.style.right="unset",t.style.top=Y.top-dt.scrollTop+"px",t.style.margin=0,!0===r.resize&&(t.style.minWidth="unset",t.style.maxWidth="unset",t.style.minHeight="unset",t.style.maxHeight="unset",t.style.overflow="hidden",t.style.overflowX="hidden",t.style.overflowY="hidden"),document.body.appendChild(t),void 0!==L&&(L.style.cssText=q,L.style.transform="none",L.style.animation="none",L.style.transition="none",L.style.position=t.style.position,L.style.left=f.left-dt.scrollLeft+"px",L.style.right="unset",L.style.top=f.top-dt.scrollTop+"px",L.style.margin=0,L.style.pointerEvents="none",!0===r.resize&&(L.style.minWidth="unset",L.style.maxWidth="unset",L.style.minHeight="unset",L.style.maxHeight="unset",L.style.overflow="hidden",L.style.overflowX="hidden",L.style.overflowY="hidden"),document.body.appendChild(L));var pt=function(n){a===t&&!0!==s?(t.style.cssText=M,t.className=T):(t.style.cssText=W,t.className=Q),z.parentNode===e&&e.insertBefore(t,z),$.remove(),z.remove(),void 0!==L&&L.remove(),i=function(){return!1},a.qMorphCancel=void 0,t.qMorphCancel=void 0,"function"==typeof r.onEnd&&r.onEnd(!0===s?"to":"from",!0===n)};if(!0!==r.useCSS&&"function"==typeof t.animate){var ft=!0===r.resize?{transform:"translate("+U+"px, "+K+"px)",width:it+"px",height:nt+"px"}:{transform:"translate("+U+"px, "+K+"px) scale("+X+", "+G+")"},mt=!0===r.resize?{width:st+"px",height:ot+"px"}:{},vt=!0===r.resize?{width:it+"px",height:nt+"px"}:{},gt=!0===r.resize?{transform:"translate("+-1*U+"px, "+-1*K+"px)",width:st+"px",height:ot+"px"}:{transform:"translate("+-1*U+"px, "+-1*K+"px) scale("+1/X+", "+1/G+")"},_t=void 0!==L?{opacity:r.tweenToOpacity}:{backgroundColor:C},bt=void 0!==L?{opacity:1}:{backgroundColor:j};h=t.animate([Object.assign({},{margin:0,borderWidth:b,borderStyle:y,borderColor:S,borderRadius:w,zIndex:ut,transformOrigin:"0 0"},ft,_t),Object.assign({},{margin:0,borderWidth:I,borderStyle:D,borderColor:R,borderRadius:F,zIndex:ht,transformOrigin:"0 0",transform:V},mt,bt)],{duration:r.duration,easing:r.easing,fill:r.fill,delay:r.delay}),c=void 0===L?void 0:L.animate([Object.assign({},{opacity:r.tweenFromOpacity,margin:0,borderWidth:b,borderStyle:y,borderColor:S,borderRadius:w,zIndex:ut,transformOrigin:"0 0",transform:x},vt),Object.assign({},{opacity:0,margin:0,borderWidth:I,borderStyle:D,borderColor:R,borderRadius:F,zIndex:ht,transformOrigin:"0 0"},gt)],{duration:r.duration,easing:r.easing,fill:r.fill,delay:r.delay}),l=!0===r.hideFromClone||!0===rt?void 0:$.animate([{margin:(J<0?J/2:0)+"px "+(Z<0?Z/2:0)+"px",width:it+f.marginH+"px",height:nt+f.marginV+"px"},{margin:0,width:0,height:0}],{duration:r.duration,easing:r.easing,fill:r.fill,delay:r.delay}),u=!0===r.keepToClone?void 0:z.animate([!0===rt?{margin:(J<0?J/2:0)+"px "+(Z<0?Z/2:0)+"px",width:it+f.marginH+"px",height:nt+f.marginV+"px"}:{margin:0,width:0,height:0},{margin:(et<0?et/2:0)+"px "+(tt<0?tt/2:0)+"px",width:st+Y.marginH+"px",height:ot+Y.marginV+"px"}],{duration:r.duration,easing:r.easing,fill:r.fill,delay:r.delay});var yt=function(t){void 0!==l&&l.cancel(),void 0!==c&&c.cancel(),void 0!==u&&u.cancel(),h.cancel(),h.removeEventListener("finish",yt),h.removeEventListener("cancel",yt),pt(t),l=void 0,c=void 0,u=void 0,h=void 0};a.qMorphCancel=function(){a.qMorphCancel=void 0,n=!0,yt()},t.qMorphCancel=function(){t.qMorphCancel=void 0,n=!0,yt()},h.addEventListener("finish",yt),h.addEventListener("cancel",yt),i=function(t){return!0!==n&&void 0!==h&&(!0===t?(yt(!0),!0):(s=!0!==s,void 0!==l&&l.reverse(),void 0!==c&&c.reverse(),void 0!==u&&u.reverse(),h.reverse(),!0))}}else{var St="q-morph-anim-"+ ++Dl,wt=document.createElement("style"),Ct=!0===r.resize?"\n transform: translate("+U+"px, "+K+"px);\n width: "+it+"px;\n height: "+nt+"px;\n ":"transform: translate("+U+"px, "+K+"px) scale("+X+", "+G+");",xt=!0===r.resize?"\n width: "+st+"px;\n height: "+ot+"px;\n ":"",kt=!0===r.resize?"\n width: "+it+"px;\n height: "+nt+"px;\n ":"",qt=!0===r.resize?"\n transform: translate("+-1*U+"px, "+-1*K+"px);\n width: "+st+"px;\n height: "+ot+"px;\n ":"transform: translate("+-1*U+"px, "+-1*K+"px) scale("+1/X+", "+1/G+");",Tt=void 0!==L?"opacity: "+r.tweenToOpacity+";":"background-color: "+C+";",Mt=void 0!==L?"opacity: 1;":"background-color: "+j+";",$t=void 0===L?"":"\n @keyframes "+St+"-from-tween {\n 0% {\n opacity: "+r.tweenFromOpacity+";\n margin: 0;\n border-width: "+b+";\n border-style: "+y+";\n border-color: "+S+";\n border-radius: "+w+";\n z-index: "+ut+";\n transform-origin: 0 0;\n transform: "+x+";\n "+kt+"\n }\n\n 100% {\n opacity: 0;\n margin: 0;\n border-width: "+I+";\n border-style: "+D+";\n border-color: "+R+";\n border-radius: "+F+";\n z-index: "+ht+";\n transform-origin: 0 0;\n "+qt+"\n }\n }\n ",Lt=!0===r.hideFromClone||!0===rt?"":"\n @keyframes "+St+"-from {\n 0% {\n margin: "+(J<0?J/2:0)+"px "+(Z<0?Z/2:0)+"px;\n width: "+(it+f.marginH)+"px;\n height: "+(nt+f.marginV)+"px;\n }\n\n 100% {\n margin: 0;\n width: 0;\n height: 0;\n }\n }\n ",Ot=!0===rt?"\n margin: "+(J<0?J/2:0)+"px "+(Z<0?Z/2:0)+"px;\n width: "+(it+f.marginH)+"px;\n height: "+(nt+f.marginV)+"px;\n ":"\n margin: 0;\n width: 0;\n height: 0;\n ",Bt=!0===r.keepToClone?"":"\n @keyframes "+St+"-to {\n 0% {\n "+Ot+"\n }\n\n 100% {\n margin: "+(et<0?et/2:0)+"px "+(tt<0?tt/2:0)+"px;\n width: "+(st+Y.marginH)+"px;\n height: "+(ot+Y.marginV)+"px;\n }\n }\n ";wt.innerHTML="\n @keyframes "+St+" {\n 0% {\n margin: 0;\n border-width: "+b+";\n border-style: "+y+";\n border-color: "+S+";\n border-radius: "+w+";\n background-color: "+C+";\n z-index: "+ut+";\n transform-origin: 0 0;\n "+Ct+"\n "+Tt+"\n }\n\n 100% {\n margin: 0;\n border-width: "+I+";\n border-style: "+D+";\n border-color: "+R+";\n border-radius: "+F+";\n background-color: "+j+";\n z-index: "+ht+";\n transform-origin: 0 0;\n transform: "+V+";\n "+xt+"\n "+Mt+"\n }\n }\n\n "+Lt+"\n\n "+$t+"\n\n "+Bt+"\n ",document.head.appendChild(wt);var Et="normal";$.style.animation=r.duration+"ms "+r.easing+" "+r.delay+"ms "+Et+" "+r.fill+" "+St+"-from",void 0!==L&&(L.style.animation=r.duration+"ms "+r.easing+" "+r.delay+"ms "+Et+" "+r.fill+" "+St+"-from-tween"),z.style.animation=r.duration+"ms "+r.easing+" "+r.delay+"ms "+Et+" "+r.fill+" "+St+"-to",t.style.animation=r.duration+"ms "+r.easing+" "+r.delay+"ms "+Et+" "+r.fill+" "+St;var zt=function(e){e===Object(e)&&e.animationName!==St||(t.removeEventListener("animationend",zt),t.removeEventListener("animationcancel",zt),pt(),wt.remove())};a.qMorphCancel=function(){a.qMorphCancel=void 0,n=!0,zt()},t.qMorphCancel=function(){t.qMorphCancel=void 0,n=!0,zt()},t.addEventListener("animationend",zt),t.addEventListener("animationcancel",zt),i=function(e){return!!(!0!==n&&t&&$&&z)&&(!0===e?(zt(),!0):(s=!0!==s,Et="normal"===Et?"reverse":"normal",$.style.animationDirection=Et,L.style.animationDirection=Et,z.style.animationDirection=Et,t.style.animationDirection=Et,!0))}}}else"function"==typeof t.qMorphCancel&&t.qMorphCancel()};r.waitFor>0||"transitionend"===r.waitFor||r.waitFor===Object(r.waitFor)&&"function"==typeof r.waitFor.then?(r.waitFor>0?new Promise(function(t){return setTimeout(t,r.waitFor)}):"transitionend"===r.waitFor?new Promise(function(e){var i=setTimeout(function(){n()},400),n=function(s){clearTimeout(i),t&&(t.removeEventListener("transitionend",n),t.removeEventListener("transitioncancel",n)),e()};t.addEventListener("transitionend",n),t.addEventListener("transitioncancel",n)}):r.waitFor).then(E).catch(function(){"function"==typeof t.qMorphCancel&&t.qMorphCancel()}):E()}else"function"==typeof a.qMorphCancel&&a.qMorphCancel()}),function(t){return i(t)}}var Gl={},Zl=["duration","delay","easing","fill","classes","style","duration","resize","useCSS","hideFromClone","keepToClone","tween","tweenFromOpacity","tweenToOpacity","waitFor","onEnd"],Jl=["resize","useCSS","hideFromClone","keepToClone","tween"];function tc(t,e){t.clsAction!==e&&(t.clsAction=e,t.el.classList[e]("q-morph--invisible"))}function ec(t,e){var i=e.opts;Jl.forEach(function(e){i[e]=!0===t[e]})}function ic(t,e){if(e.name!==t)!1===e.animating&&tc(e,"add");else{var i=Gl[e.group];void 0===i?(Gl[e.group]={name:e.group,model:t,queue:[e],animating:!1},tc(e,"remove")):i.model!==t&&(i.model=t,i.queue.push(e),!1===i.animating&&2===i.queue.length&&function t(e){if(!(!0===e.animating||e.queue.length<2)){var i=e.queue,n=i[0],s=i[1];e.animating=!0,n.animating=!0,s.animating=!0,tc(n,"remove"),tc(s,"remove");var o=Xl(Object.assign({},{from:n.el,to:s.el,onToggle:function(){tc(n,"add"),tc(s,"remove")}},s.opts,{onEnd:function(i,o){void 0!==s.opts.onEnd&&s.opts.onEnd(i,o),!0!==o&&(n.animating=!1,s.animating=!1,e.animating=!1,e.cancel=void 0,e.queue.shift(),t(e))}}));e.cancel=function(){o(!0),e.cancel=void 0}}}(i))}}function nc(t,e){var i;Object(e)===e?(i=""+e.model,function(t,e){void 0!==t.group&&(e.group=t.group),void 0!==t.name&&(e.name=t.name);var i=e.opts;Zl.forEach(function(e){void 0!==t[e]&&(i[e]=t[e])})}(e,t),ec(e,t)):i=""+e,i!==t.model?(t.model=i,ic(i,t)):!1===t.animating&&void 0!==t.clsAction&&t.el.classList[t.clsAction]("q-morph--invisible")}function sc(t){var e=t.__qmorph;if(void 0!==e){var i=Gl[e.group];if(void 0!==i)-1!==i.queue.indexOf(e)&&(i.queue=i.queue.filter(function(t){return t!==e}),0===i.queue.length&&(void 0!==i.cancel&&i.cancel(),delete Gl[e.group]));"add"===e.clsAction&&t.classList.remove("q-morph--invisible"),delete t.__qmorph}}var oc={name:"morph",inserted:function(t,e){void 0!==t.__qmorph&&(sc(t),t.__qmorph_destroyed=!0);var i={el:t,animating:!1,opts:{}};ec(e.modifiers,i),function(t,e){var i="string"==typeof t&&t.length>0?t.split(":"):[];e.name=i[0],e.group=i[1],Object.assign(e.opts,{duration:!0===isNaN(i[2])?300:parseFloat(i[2]),waitFor:i[3]})}(e.arg,i),nc(i,e.value),t.__qmorph=i},update:function(t,e){var i=t.__qmorph;void 0!==i&&nc(i,e.value)},unbind:function(t){void 0===t.__qmorph_destroyed?sc(t):delete t.__qmorph_destroyed}};var rc={childList:!0,subtree:!0,attributes:!0,characterData:!0,attributeOldValue:!0,characterDataOldValue:!0};function ac(t,e,i){e.handler=i,void 0!==e.observer&&e.observer.disconnect(),e.observer=new MutationObserver(function(i){"function"==typeof e.handler&&(!1!==e.handler(i)&&!0!==e.once||lc(t))}),e.observer.observe(t,e.opts)}function lc(t){var e=t.__qmutation;void 0!==e&&(void 0!==e.observer&&e.observer.disconnect(),delete t.__qmutation)}var cc={name:"mutation",inserted:function(t,e){var i=e.modifiers,n=i.once,s=function(t,e){var i={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&-1===e.indexOf(n)&&(i[n]=t[n]);return i}(i,["once"]),o=e.value;void 0!==t.__qmutation&&(lc(t),t.__qmutation_destroyed=!0);var r={once:n,opts:0===Object.keys(s).length?rc:s};ac(t,r,o),t.__qmutation=r},update:function(t,e){var i=e.oldValue,n=e.value,s=t.__qmutation;void 0!==s&&i!==n&&ac(t,s,n)},unbind:function(t){void 0===t.__qmutation_destroyed?lc(t):delete t.__qmutation_destroyed}};function uc(t,e){var i=e.value,n=e.oldValue;"function"==typeof i?(t.handler=i,"function"!=typeof n&&(t.scrollTarget.addEventListener("scroll",t.scroll,h.passive),t.scroll())):t.scrollTarget.removeEventListener("scroll",t.scroll,h.passive)}function hc(t){var e=t.__qscrollfire;void 0!==e&&(e.scrollTarget.removeEventListener("scroll",e.scroll,h.passive),e.scroll.cancel(),delete t.__qscrollfire)}var dc={name:"scroll-fire",inserted:function(t,e){void 0!==t.__qscrollfire&&(hc(t),t.__qscrollfire_destroyed=!0);var i={scrollTarget:ii(t),scroll:T(function(){var e,n;i.scrollTarget===window?(n=t.getBoundingClientRect().bottom,e=window.innerHeight):(n=he(t).top+de(t),e=he(i.scrollTarget).top+de(i.scrollTarget)),n>0&&n=s.sensitivity||Math.abs(i-s.origin.top)>=s.sensitivity)&&clearTimeout(s.timer)},end:function(t){k(s,"temp"),void 0!==s.styleCleanup&&s.styleCleanup(s.triggered),!0===s.triggered?void 0!==t&&S(t):clearTimeout(s.timer)}},o=[600,5,7];"string"==typeof e.arg&&e.arg.length>0&&e.arg.split(":").forEach(function(t,e){var i=parseInt(t,10);i&&(o[e]=i)}),i=o,s.duration=i[0],s.touchSensitivity=i[1],s.mouseSensitivity=i[2],t.__qtouchhold=s,!0===n.mouse&&x(s,"main",[[t,"mousedown","mouseStart","passive"+(!0===n.mouseCapture?"Capture":"")]]),!0===c.has.touch&&x(s,"main",[[t,"touchstart","touchStart","passive"+(!0===n.capture?"Capture":"")],[t,"touchend","noop","notPassiveCapture"]])}},update:function(t,e){var i=t.__qtouchhold;void 0!==i&&e.oldValue!==e.value&&("function"!=typeof e.value&&i.end(),i.handler=e.value)},unbind:function(t){void 0===t.__qtouchhold_destroyed?vc(t):delete t.__qtouchhold_destroyed}},_c={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},bc=new RegExp("^([\\d+]+|"+Object.keys(_c).join("|")+")$","i");function yc(t){var e=t.__qtouchrepeat;void 0!==e&&(clearTimeout(e.timer),k(e,"main"),k(e,"temp"),void 0!==e.styleCleanup&&e.styleCleanup(),delete t.__qtouchrepeat)}var Sc,wc={name:"touch-repeat",bind:function(t,e){var i=e.modifiers,n=e.value,s=e.arg;void 0!==t.__qtouchrepeat&&(yc(t),t.__qtouchrepeat_destroyed=!0);var o=Object.keys(i).reduce(function(t,e){if(!0===bc.test(e)){var i=isNaN(parseInt(e,10))?_c[e.toLowerCase()]:parseInt(e,10);i>=0&&t.push(i)}return t},[]);if(!0===i.mouse||!0===c.has.touch||0!==o.length){var r="string"==typeof s&&s.length>0?s.split(":").map(function(t){return parseInt(t,10)}):[0,600,300],a=r.length-1,l={keyboard:o,handler:n,noop:p,mouseStart:function(t){void 0===l.event&&"function"==typeof l.handler&&!0===f(t)&&(x(l,"temp",[[document,"mousemove","move","passiveCapture"],[document,"click","end","notPassiveCapture"]]),l.start(t,!0))},keyboardStart:function(e){if("function"==typeof l.handler&&!0===J(e,o)){if((0===r[0]||void 0!==l.event)&&(S(e),t.focus(),void 0!==l.event))return;x(l,"temp",[[document,"keyup","end","notPassiveCapture"],[document,"click","end","notPassiveCapture"]]),l.start(e,!1,!0)}},touchStart:function(t){if(void 0!==t.target&&"function"==typeof l.handler){var e=t.target;x(l,"temp",[[e,"touchmove","move","passiveCapture"],[e,"touchcancel","end","notPassiveCapture"],[e,"touchend","end","notPassiveCapture"]]),l.start(t)}},start:function(t,e,i){function n(t){l.styleCleanup=void 0,document.documentElement.style.cursor="";var e=function(){document.body.classList.remove("non-selectable")};!0===t?(ze(),setTimeout(e,10)):e()}!0!==i&&(l.origin=m(t)),!0===c.is.mobile&&(document.body.classList.add("non-selectable"),ze(),l.styleCleanup=n),l.event={touch:!0!==e&&!0!==i,mouse:!0===e,keyboard:!0===i,startTime:Date.now(),repeatCount:0};var s=function(){if(void 0!==l.event){0===l.event.repeatCount&&(l.event.evt=t,!0===i?l.event.keyCode=t.keyCode:l.event.position=m(t),!0!==c.is.mobile&&(document.documentElement.style.cursor="pointer",document.body.classList.add("non-selectable"),ze(),l.styleCleanup=n)),l.event.duration=Date.now()-l.event.startTime,l.event.repeatCount+=1,l.handler(l.event);var e=a=7||Math.abs(n-e.top)>=7}(t,l.origin)&&clearTimeout(l.timer)},end:function(t){void 0!==l.event&&(void 0!==l.styleCleanup&&l.styleCleanup(!0),void 0!==t&&l.event.repeatCount>0&&S(t),k(l,"temp"),clearTimeout(l.timer),l.event=void 0)}};t.__qtouchrepeat=l,!0===i.mouse&&x(l,"main",[[t,"mousedown","mouseStart","passive"+(!0===i.mouseCapture?"Capture":"")]]),!0===c.has.touch&&x(l,"main",[[t,"touchstart","touchStart","passive"+(!0===i.capture?"Capture":"")],[t,"touchend","noop","notPassiveCapture"]]),o.length>0&&x(l,"main",[[t,"keydown","keyboardStart","notPassive"+(!0===i.keyCapture?"Capture":"")]])}},update:function(t,e){var i=e.oldValue,n=e.value,s=t.__qtouchrepeat;void 0!==s&&i!==n&&("function"!=typeof n&&s.end(),s.handler=n)},unbind:function(t){void 0===t.__qtouchrepeat_destroyed?yc(t):delete t.__qtouchrepeat_destroyed}},Cc=Object.freeze({__proto__:null,ClosePopup:Pl,GoBack:Il,Intersection:gr,Morph:oc,Mutation:cc,Ripple:Se,ScrollFire:dc,Scroll:mc,TouchHold:gc,TouchPan:xn,TouchRepeat:wc,TouchSwipe:ji});function xc(t){void 0===Sc&&(Sc=u.is.winphone?"msapplication-navbutton-color":u.is.safari?"apple-mobile-web-app-status-bar-style":"theme-color");var e=function(t){var e=document.getElementsByTagName("META");for(var i in e)if(e[i].name===t)return e[i]}(Sc),i=void 0===e;i&&(e=document.createElement("meta")).setAttribute("name",Sc),e.setAttribute("content",t),i&&document.head.appendChild(e)}var kc={install:function(t){var e=t.$q,n=t.cfg;this.set=!1!==i||!0!==u.is.mobile||!0!==u.is.nativeMobile&&!0!==u.is.winphone&&!0!==u.is.safari&&!0!==u.is.webkit&&!0!==u.is.vivaldi?p:function(t){var e=t||U("primary");!0===u.is.nativeMobile&&window.StatusBar?window.StatusBar.backgroundColorByHexString(e):xc(e)},e.addressbarColor=this,n.addressbarColor&&this.set(n.addressbarColor)}},qc={};function Tc(t,e){try{var i=t[e]();return void 0===i?Promise.resolve():i}catch(t){return Promise.reject(t)}}function Mc(t){t.activeEl=document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement||null,t.isActive=null!==t.activeEl}var $c={isCapable:!1,isActive:!1,activeEl:null,request:function(t){var e=this;if(!0===this.isCapable){var i=t||document.documentElement;if(i!==this.activeEl)return(!0===c.is.ie&&null!==this.activeEl&&i.contains(this.activeEl)?this.exit():Promise.resolve()).then(function(){return Tc(i,qc.request)}).catch(function(t){return null!==e.activeEl?e.exit().then(function(){return Tc(i,qc.request)}):Promise.reject(t)}).then(function(t){return Mc(e),t})}return this.__getErr()},exit:function(){var t=this;return!0===this.isCapable&&!0===this.isActive?Tc(document,qc.exit).then(function(e){return Mc(t),t.isActive?t.exit():e}):this.__getErr()},toggle:function(t){var e=t||document.documentElement;return this.activeEl===e?this.exit():this.request(e)},install:function(e){var n=this;e.$q.fullscreen=this,this.__getErr=function(){return Promise.resolve()},!0!==i&&(qc.request=["requestFullscreen","msRequestFullscreen","mozRequestFullScreen","webkitRequestFullscreen"].find(function(t){return void 0!==document.documentElement[t]}),this.isCapable=void 0!==qc.request,!1!==this.isCapable?(qc.exit=["exitFullscreen","msExitFullscreen","mozCancelFullScreen","webkitExitFullscreen"].find(function(t){return document[t]}),Mc(this),["onfullscreenchange","onmsfullscreenchange","onwebkitfullscreenchange"].forEach(function(t){document[t]=function(){Mc(n)}}),t.util.defineReactive(this,"isActive",this.isActive),t.util.defineReactive(this,"activeEl",this.activeEl)):this.__getErr=function(){return Promise.reject("Not capable")})}},Lc={appVisible:!1,install:function(e){var n=this,s=e.$q;if(!0!==i){var o,r;void 0!==document.hidden?(o="hidden",r="visibilitychange"):void 0!==document.msHidden?(o="msHidden",r="msvisibilitychange"):void 0!==document.webkitHidden&&(o="webkitHidden",r="webkitvisibilitychange");var a=function(){n.appVisible=s.appVisible=!document[o]};a(),r&&void 0!==document[o]&&(t.util.defineReactive(s,"appVisible",this.appVisible),document.addEventListener(r,a,!1))}else this.appVisible=s.appVisible=!0}},Oc=t.extend({name:"BottomSheetPlugin",mixins:[Gt,bt],inheritAttrs:!1,props:{title:String,message:String,actions:Array,grid:Boolean,cardClass:[String,Array,Object],cardStyle:[String,Array,Object]},computed:{dialogProps:function(){return Object.assign({},this.qAttrs,{position:"bottom"})}},methods:{show:function(){this.$refs.dialog.show()},hide:function(){this.$refs.dialog.hide()},onOk:function(t){this.$emit("ok",t),this.hide()},__getGrid:function(t){var e=this;return this.actions.map(function(i){var n=i.avatar||i.img;return void 0===i.label?t(So,{staticClass:"col-all",props:{dark:e.isDark}}):t("div",{staticClass:"q-bottom-sheet__item q-hoverable q-focusable cursor-pointer relative-position",class:i.classes,attrs:{tabindex:0},on:{click:function(){return e.onOk(i)},keyup:function(t){13===t.keyCode&&e.onOk(i)}}},[t("div",{staticClass:"q-focus-helper"}),i.icon?t(Ut,{props:{name:i.icon,color:i.color}}):n?t("img",{attrs:{src:n},staticClass:i.avatar?"q-bottom-sheet__avatar":null}):t("div",{staticClass:"q-bottom-sheet__empty-icon"}),t("div",[i.label])])})},__getList:function(t){var e=this;return this.actions.map(function(i){var n=i.avatar||i.img;return void 0===i.label?t(So,{props:{spaced:!0,dark:e.isDark}}):t(Zs,{staticClass:"q-bottom-sheet__item",class:i.classes,props:{tabindex:0,clickable:!0,dark:e.isDark},on:{click:function(){return e.onOk(i)},keyup:function(t){13===t.keyCode&&e.onOk(i)}}},[t(Js,{props:{avatar:!0}},[i.icon?t(Ut,{props:{name:i.icon,color:i.color}}):n?t("img",{attrs:{src:n},staticClass:i.avatar?"q-bottom-sheet__avatar":null}):null]),t(Js,[i.label])])})}},render:function(t){var e=this,i=[];return this.title&&i.push(t(zi,{staticClass:"q-dialog__title"},[this.title])),this.message&&i.push(t(zi,{staticClass:"q-dialog__message"},[this.message])),i.push(!0===this.grid?t("div",{staticClass:"row items-stretch justify-start"},this.__getGrid(t)):t("div",this.__getList(t))),t(Ys,{ref:"dialog",props:this.dialogProps,on:ft(this,"hide",{hide:function(){e.$emit("hide")}})},[t(Ei,{staticClass:"q-bottom-sheet q-bottom-sheet--"+(!0===this.grid?"grid":"list")+(!0===this.isDark?" q-bottom-sheet--dark q-dark":""),style:this.cardStyle,class:this.cardClass},i)])}});function Bc(t,e){var i={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&-1===e.indexOf(n)&&(i[n]=t[n]);return i}var Ec,zc={onOk:function(){return zc},okCancel:function(){return zc},hide:function(){return zc},update:function(){return zc}};function Pc(e){return function(n){n.className;var s=n.class,o=n.style,r=n.component,a=n.root,l=n.parent,c=Bc(n,["className","class","style","component","root","parent"]);if(!0===i)return zc;void 0!==s&&(c.cardClass=s),void 0!==o&&(c.cardStyle=o);var u,h,d=void 0!==r;!0===d?u=r:(u=e,h=c);var p=[],f=[],m={onOk:function(t){return p.push(t),m},onCancel:function(t){return f.push(t),m},onDismiss:function(t){return p.push(t),f.push(t),m},hide:function(){return b.$refs.dialog.hide(),m},update:function(t){t.className;var e=t.class,i=t.style,n=(t.component,t.root,t.parent,Bc(t,["className","class","style","component","root","parent"]));return null!==b&&(void 0!==e&&(n.cardClass=e),void 0!==i&&(n.cardStyle=i),!0===d?Object.assign(c,n):(!function t(e,i){for(var n in i)"spinner"!==n&&Object(i[n])===i[n]?(e[n]=Object(e[n])!==e[n]?{}:Object.assign({},e[n]),t(e[n],i[n])):e[n]=i[n]}(c,n),h=Object.assign({},c)),b.$forceUpdate()),m}},v=document.createElement("div");document.body.appendChild(v);var g=!1,_={ok:function(t){g=!0,p.forEach(function(e){e(t)})},hide:function(){b.$destroy(),b.$el.remove(),b=null,!0!==g&&f.forEach(function(t){t()})}},b=new t({name:"QGlobalDialog",el:v,parent:function(t,e){if(void 0!==t)return t;if(void 0!==e)return e;if(void 0===Ec){var i=document.getElementById("q-app");i&&i.__vue__&&(Ec=i.__vue__.$root)}return Ec}(l,a),render:function(t){return t(u,{ref:"dialog",props:c,attrs:h,on:_})},mounted:function(){var t=this;void 0!==this.$refs.dialog?this.$refs.dialog.show():_["hook:mounted"]=function(){void 0!==t.$refs.dialog&&t.$refs.dialog.show()}}});return m}}var Ac={install:function(t){var e=t.$q;this.create=e.bottomSheet=Pc(Oc)}};function Ic(t){return encodeURIComponent(t)}function Dc(t){return decodeURIComponent(t)}function Rc(t){if(""===t)return t;0===t.indexOf('"')&&(t=t.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\")),t=Dc(t.replace(/\+/g," "));try{t=JSON.parse(t)}catch(t){}return t}function Fc(t){var e=new Date;return e.setMilliseconds(e.getMilliseconds()+t),e.toUTCString()}function jc(t,e,i,n){var s,o,r,a,l,c,u,h;void 0===i&&(i={}),void 0!==i.expires&&("[object Date]"===Object.prototype.toString.call(i.expires)?s=i.expires.toUTCString():"string"==typeof i.expires?(r=i.expires,a=0,l=r.match(/(\d+)d/),c=r.match(/(\d+)h/),u=r.match(/(\d+)m/),h=r.match(/(\d+)s/),l&&(a+=864e5*l[1]),c&&(a+=36e5*c[1]),u&&(a+=6e4*u[1]),h&&(a+=1e3*h[1]),s=0===a?r:Fc(a)):(o=parseFloat(i.expires),s=!1===isNaN(o)?Fc(864e5*o):i.expires));var d,p=Ic(t)+"="+Ic((d=e)===Object(d)?JSON.stringify(d):""+d),f=[p,void 0!==s?"; Expires="+s:"",i.path?"; Path="+i.path:"",i.domain?"; Domain="+i.domain:"",i.sameSite?"; SameSite="+i.sameSite:"",i.httpOnly?"; HttpOnly":"",i.secure?"; Secure":"",i.other?"; "+i.other:""].join("");if(n){n.req.qCookies?n.req.qCookies.push(f):n.req.qCookies=[f],n.res.setHeader("Set-Cookie",n.req.qCookies);var m=n.req.headers.cookie||"";if(void 0!==s&&o<0){var v=Vc(t,n);void 0!==v&&(m=m.replace(t+"="+v+"; ","").replace("; "+t+"="+v,"").replace(t+"="+v,""))}else m=m?p+"; "+m:f;n.req.headers.cookie=m}else document.cookie=f}function Vc(t,e){for(var i,n,s,o=e?e.req.headers:document,r=o.cookie?o.cookie.split("; "):[],a=r.length,l=t?null:{},c=0;c0)return t(Pi,{staticClass:!0===this.stackButtons?"items-end":null,props:{vertical:this.stackButtons,align:"right"}},e)},onOk:function(){this.$emit("ok",Rr(this.getData())),this.hide()},onCancel:function(){this.hide()},getData:function(){return void 0!==this.prompt?this.prompt.model:void 0!==this.options?this.options.model:void 0},getSection:function(t,e,i){return!0===this.html?t(zi,{staticClass:e,domProps:{innerHTML:i}}):t(zi,{staticClass:e},[i])}},render:function(t){var e=this,i=[];return this.title&&i.push(this.getSection(t,"q-dialog__title",this.title)),!1!==this.progress&&i.push(t(zi,{staticClass:"q-dialog__progress"},[t(this.spinner.component,{props:this.spinner.props})])),this.message&&i.push(this.getSection(t,"q-dialog__message",this.message)),void 0!==this.prompt?i.push(t(zi,{staticClass:"scroll q-dialog-plugin__form"},this.getPrompt(t))):void 0!==this.options&&i.push(t(So,{props:{dark:this.isDark}}),t(zi,{staticClass:"scroll q-dialog-plugin__form"},this.getOptions(t)),t(So,{props:{dark:this.isDark}})),(this.ok||this.cancel)&&i.push(this.getButtons(t)),t(Ys,{ref:"dialog",props:Object.assign({},this.qAttrs,{value:this.value}),on:ft(this,"hide",{hide:function(){e.$emit("hide")}})},[t(Ei,{staticClass:this.classes,style:this.cardStyle,class:this.cardClass,props:{dark:this.isDark}},i)])}}),Xc={install:function(t){var e=t.$q;this.create=e.dialog=Pc(Kc)}},Gc={isActive:!1,start:p,stop:p,increment:p,setDefaults:p,install:function(e){var n=this,s=e.$q,o=e.cfg;if(s.loadingBar=this,!0!==i){var r=void 0!==o.loadingBar?Object.assign({},o.loadingBar):{},a={start:function(){n.isActive=!0},stop:function(){n.isActive=!1}},l=new t({name:"LoadingBar",devtools:{hide:!0},beforeCreate:function(){void 0===this._routerRoot&&(this._routerRoot={})},render:function(t){return t(kt,{ref:"bar",props:r,on:a})}}).$mount().$refs.bar;Object.assign(this,{start:l.start,stop:l.stop,increment:l.increment,setDefaults:function(t){!0===Zi(t)&&Object.assign(r,t),l.$parent.$forceUpdate()}}),t.util.defineReactive(this,"isActive",this.isActive),t.util.defineReactive(l,"isActive",this.isActive),l.setDefaults=this.setDefaults,document.body.appendChild(l.$parent.$el)}}},Zc=0,Jc={},tu={delay:0,message:!1,spinnerSize:80,spinnerColor:"white",messageColor:"white",backgroundColor:"black",spinner:ue,customClass:""},eu=Object.assign({},tu),iu={isActive:!1,show:function(e){var n=this;if(!0!==i){if((Jc=!0===Zi(e)&&!0===e.ignoreDefaults?Object.assign({},tu,e):Object.assign({},eu,e)).customClass+=" text-"+Jc.backgroundColor,this.isActive=!0,void 0!==Hc)return Jc.uid=Zc,void Hc.$forceUpdate();Jc.uid=++Zc,clearTimeout(Qc),Qc=setTimeout(function(){Qc=void 0;var e=document.createElement("div");document.body.appendChild(e),Hc=new t({name:"QLoading",devtools:{hide:!0},beforeCreate:function(){void 0===this._routerRoot&&(this._routerRoot={})},el:e,mounted:function(){Vs(!0)},render:function(t){var e;return t("transition",{props:{name:"q-transition--fade",appear:!0},on:ft(n,"tr",{"after-leave":function(){!0!==n.isActive&&void 0!==Hc&&(Vs(!1),Hc.$destroy(),Hc.$el.remove(),Hc=void 0)}})},[!0===n.isActive?t("div",{staticClass:"q-loading fullscreen column flex-center z-max",key:Jc.uid,class:Jc.customClass.trim()},[t(Jc.spinner,{props:{color:Jc.spinnerColor,size:Jc.spinnerSize}}),Jc.message&&t("div",{class:"text-"+Jc.messageColor,domProps:(e={},e[!0===Jc.sanitize?"textContent":"innerHTML"]=Jc.message,e)})||void 0]):null])}})},Jc.delay)}},hide:function(){!0===this.isActive&&(void 0!==Qc&&(clearTimeout(Qc),Qc=void 0),this.isActive=!1)},setDefaults:function(t){!0===Zi(t)&&Object.assign(eu,t)},install:function(t){var e=t.$q,i=t.cfg.loading;this.setDefaults(i),e.loading=this}};function nu(t){t.title&&(t.title=t.titleTemplate?t.titleTemplate(t.title):t.title,delete t.titleTemplate),[["meta","content"],["link","href"]].forEach(function(e){var i=t[e[0]],n=e[1];for(var s in i){var o=i[s];o.template&&(1===Object.keys(o).length?delete i[s]:(o[n]=o.template(o[n]||""),delete o.template))}})}function su(t,e){if(Object.keys(t).length!==Object.keys(e).length)return!0;for(var i in t)if(t[i]!==e[i])return!0}function ou(t){return!1===["class","style"].includes(t)}function ru(t){return!1===["lang","dir"].includes(t)}function au(t,e){!0!==t._inactive&&(!0===du(t)&&(fo(!0,e,t.__qMeta),!0===t.$options.meta.stopPropagation)||t.$children.forEach(function(t){au(t,e)}))}function lu(){!0===Yc&&(Yc=!1,this.$root.__currentMeta=window.__Q_META__);var t,e,i,n={title:"",titleTemplate:null,meta:{},link:{},script:{},htmlAttr:{},bodyAttr:{}};au(this.$root,n),nu(n),t=function(t,e){var i={},n={};return void 0===t?{add:e,remove:n}:(t.title!==e.title&&(i.title=e.title),["meta","link","script","htmlAttr","bodyAttr"].forEach(function(s){var o=t[s],r=e[s];if(n[s]=[],void 0!==o&&null!==o){for(var a in i[s]={},o)!1===r.hasOwnProperty(a)&&n[s].push(a);for(var l in r)!1===o.hasOwnProperty(l)?i[s][l]=r[l]:!0===su(o[l],r[l])&&(n[s].push(l),i[s][l]=r[l])}else i[s]=r}),{add:i,remove:n})}(this.$root.__currentMeta,n),e=t.add,i=t.remove,e.title&&(document.title=e.title),Object.keys(i).length>0&&(["meta","link","script"].forEach(function(t){i[t].forEach(function(e){document.head.querySelector(t+'[data-qmeta="'+e+'"]').remove()})}),i.htmlAttr.filter(ru).forEach(function(t){document.documentElement.removeAttribute(t)}),i.bodyAttr.filter(ou).forEach(function(t){document.body.removeAttribute(t)})),["meta","link","script"].forEach(function(t){var i=e[t];for(var n in i){var s=document.createElement(t);for(var o in i[n])"innerHTML"!==o&&s.setAttribute(o,i[n][o]);s.setAttribute("data-qmeta",n),"script"===t&&(s.innerHTML=i[n].innerHTML||""),document.head.appendChild(s)}}),Object.keys(e.htmlAttr).filter(ru).forEach(function(t){document.documentElement.setAttribute(t,e.htmlAttr[t]||"")}),Object.keys(e.bodyAttr).filter(ou).forEach(function(t){document.body.setAttribute(t,e.bodyAttr[t]||"")}),this.$root.__currentMeta=n}function cu(t){return function(e){var i=t[e];return e+(!0!==i&&void 0!==i?'="'+i+'"':"")}}function uu(t,e,i){var n={title:"",titleTemplate:null,meta:{},link:{},htmlAttr:{},bodyAttr:{},noscript:{}};au(t,n),nu(n);var s=void 0!==i&&void 0!==i.nonce?' nonce="'+i.nonce+'"':"",o={"%%Q_HTML_ATTRS%%":Object.keys(n.htmlAttr).filter(ru).map(cu(n.htmlAttr)).join(" "),"%%Q_HEAD_TAGS%%":function(t){var e="";return t.title&&(e+=""+t.title+""),["meta","link","script"].forEach(function(i){var n=t[i];for(var s in n){var o=Object.keys(n[s]).filter(function(t){return"innerHTML"!==t}).map(cu(n[s]));e+="<"+i+" "+o.join(" ")+' data-qmeta="'+s+'">',"script"===i&&(e+=(n[s].innerHTML||"")+"<\/script>")}}),e}(n),"%%Q_BODY_ATTRS%%":Object.keys(n.bodyAttr).filter(ou).map(cu(n.bodyAttr)).join(" "),"%%Q_BODY_TAGS%%":Object.keys(n.noscript).map(function(t){return'"}).join("")+"window.__Q_META__="+(delete n.noscript&&JSON.stringify(n))+"<\/script>"};return Object.keys(o).forEach(function(t){e=e.replace(t,o[t])}),e}function hu(){"function"==typeof this.$options.meta?(void 0===this.$options.computed&&(this.$options.computed={}),this.$options.computed.__qMeta=this.$options.meta):!0===du(this)&&(this.__qMeta=this.$options.meta)}function du(t){return void 0!==t.$options.meta&&null!==t.$options.meta}function pu(){!0===du(this)&&this.__qMetaUpdate()}!1===i&&t.util.defineReactive(iu,"isActive",iu.isActive);var fu={install:function(e){var s=e.queues;!0===i?(t.prototype.$getMetaHTML=function(t){return function(e,i){return uu(t,e,i)}},t.mixin({beforeCreate:hu}),s.server.push(function(t,e){e.ssr.Q_HTML_ATTRS+=" %%Q_HTML_ATTRS%%",Object.assign(e.ssr,{Q_HEAD_TAGS:"%%Q_HEAD_TAGS%%",Q_BODY_ATTRS:"%%Q_BODY_ATTRS%%",Q_BODY_TAGS:"%%Q_BODY_TAGS%%"})})):(Yc=n,t.mixin({beforeCreate:hu,created:function(){!0===du(this)&&(this.__qMetaUnwatch=this.$watch("__qMeta",this.__qMetaUpdate))},activated:pu,deactivated:pu,beforeMount:pu,destroyed:function(){!0===du(this)&&(this.__qMetaUnwatch(),this.__qMetaUpdate())},methods:{__qMetaUpdate:function(){clearTimeout(Wc),Wc=setTimeout(lu.bind(this),50)}}}))}};var mu,vu=0,gu={},_u={},bu={},yu={},Su=/^\s*$/,wu=["top-left","top-right","bottom-left","bottom-right","top","bottom","left","right","center"],Cu=["top-left","top-right","bottom-left","bottom-right"],xu={positive:{icon:function(t){return t.iconSet.type.positive},color:"positive"},negative:{icon:function(t){return t.iconSet.type.negative},color:"negative"},warning:{icon:function(t){return t.iconSet.type.warning},color:"warning",textColor:"dark"},info:{icon:function(t){return t.iconSet.type.info},color:"info"},ongoing:{group:!1,timeout:0,spinner:!0,color:"grey-8"}};function ku(t,e,i){if(!t)return Tu("parameter required");var n,s={textColor:"white"};if(!0!==t.ignoreDefaults&&Object.assign(s,gu),!1===Zi(t)&&(s.type&&Object.assign(s,xu[s.type]),t={message:t}),Object.assign(s,xu[t.type||s.type],t),"function"==typeof s.icon&&(s.icon=s.icon(e.$q)),s.spinner?!0===s.spinner&&(s.spinner=ue):s.spinner=!1,s.meta={hasMedia:Boolean(!1!==s.spinner||s.icon||s.avatar),hasText:qu(s.message)||qu(s.caption)},s.position){if(!1===wu.includes(s.position))return Tu("wrong position",t)}else s.position="bottom";if(void 0===s.timeout)s.timeout=5e3;else{var o=parseInt(s.timeout,10);if(isNaN(o)||o<0)return Tu("wrong timeout",t);s.timeout=o}0===s.timeout?s.progress=!1:!0===s.progress&&(s.meta.progressClass="q-notification__progress"+(s.progressClass?" "+s.progressClass:""),s.meta.progressStyle={animationDuration:s.timeout+1e3+"ms"});var r=(!0===Array.isArray(t.actions)?t.actions:[]).concat(!0!==t.ignoreDefaults&&!0===Array.isArray(gu.actions)?gu.actions:[]).concat(void 0!==xu[t.type]&&!0===Array.isArray(xu[t.type].actions)?xu[t.type].actions:[]),a=s.closeBtn;if(a&&r.push({label:"string"==typeof a?a:e.$q.lang.label.close}),s.actions=r.map(function(t){var e=t.handler,i=t.noDismiss,n=t.style,s=t.class,o=t.attrs,r=function(t,e){var i={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&-1===e.indexOf(n)&&(i[n]=t[n]);return i}(t,["handler","noDismiss","style","class","attrs"]);return{staticClass:s,style:n,props:Object.assign({},{flat:!0},r),attrs:o,on:{click:"function"==typeof e?function(){e(),!0!==i&&d()}:function(){d()}}}}),void 0===s.multiLine&&(s.multiLine=s.actions.length>1),Object.assign(s.meta,{staticClass:"q-notification row items-stretch q-notification--"+(!0===s.multiLine?"multi-line":"standard")+(void 0!==s.color?" bg-"+s.color:"")+(void 0!==s.textColor?" text-"+s.textColor:"")+(void 0!==s.classes?" "+s.classes:""),wrapperClass:"q-notification__wrapper col relative-position border-radius-inherit "+(!0===s.multiLine?"column no-wrap justify-center":"row items-center"),contentClass:"q-notification__content row items-center"+(!0===s.multiLine?"":" col"),leftClass:!0===s.meta.hasText?"additional":"single",attrs:Object.assign({},{role:"alert"},s.attrs)}),!1===s.group?(s.group=void 0,s.meta.group=void 0):(void 0!==s.group&&!0!==s.group||(s.group=[s.message,s.caption,s.multiline].concat(s.actions.map(function(t){var e=t.props;return e.label+"*"+e.icon})).join("|")),s.meta.group=s.group+"|"+s.position),0===s.actions.length?s.actions=void 0:s.meta.actionsClass="q-notification__actions row items-center "+(!0===s.multiLine?"justify-end":"col-auto")+(!0===s.meta.hasMedia?" q-notification__actions--with-media":""),void 0!==i){clearTimeout(i.notif.meta.timer),s.meta.uid=i.notif.meta.uid;var l=bu[s.position].indexOf(i.notif);bu[s.position][l]=s}else{var c=_u[s.meta.group];if(void 0===c){if(s.meta.uid=vu++,s.meta.badge=1,-1!==["left","right","center"].indexOf(s.position))bu[s.position].splice(Math.floor(bu[s.position].length/2),0,s);else{var u=s.position.indexOf("top")>-1?"unshift":"push";bu[s.position][u](s)}void 0!==s.group&&(_u[s.meta.group]=s)}else{if(clearTimeout(c.meta.timer),void 0!==s.badgePosition){if(!1===Cu.includes(s.badgePosition))return Tu("wrong badgePosition",t)}else s.badgePosition="top-"+(s.position.indexOf("left")>-1?"right":"left");s.meta.uid=c.meta.uid,s.meta.badge=c.meta.badge+1,s.meta.badgeClass="q-notification__badge q-notification__badge--"+s.badgePosition+(void 0!==s.badgeColor?" bg-"+s.badgeColor:"")+(void 0!==s.badgeTextColor?" text-"+s.badgeTextColor:"")+(s.badgeClass?" "+s.badgeClass:"");var h=bu[s.position].indexOf(c);bu[s.position][h]=_u[s.meta.group]=s}}var d=function(){!function(t,e){clearTimeout(t.meta.timer);var i=bu[t.position].indexOf(t);if(-1!==i){void 0!==t.group&&delete _u[t.meta.group];var n=e.$refs[""+t.meta.uid];if(n){var s=getComputedStyle(n),o=s.width,r=s.height;n.style.left=n.offsetLeft+"px",n.style.width=o,n.style.height=r}bu[t.position].splice(i,1),e.$forceUpdate(),"function"==typeof t.onDismiss&&t.onDismiss()}}(s,e),n=void 0};return e.$forceUpdate(),s.timeout>0&&(s.meta.timer=setTimeout(function(){d()},s.timeout+1e3)),void 0!==s.group?function(e){void 0!==e?Tu("trying to update a grouped one which is forbidden",t):d()}:(n={dismiss:d,config:t,notif:s},void 0===i?function(t){void 0!==n&&(void 0===t?n.dismiss():ku(Object.assign({},n.config,t,{group:!1,position:s.position}),e,n))}:void Object.assign(i,n))}function qu(t){return void 0!==t&&null!==t&&!0!==Su.test(t)}function Tu(t,e){return console.error("Notify: "+t,e),!1}var Mu={name:"QNotifications",devtools:{hide:!0},beforeCreate:function(){void 0===this._routerRoot&&(this._routerRoot={})},render:function(t){return t("div",{staticClass:"q-notifications"},wu.map(function(e){return t("transition-group",{key:e,staticClass:yu[e],tag:"div",props:{name:"q-notification--"+e,mode:"out-in"}},bu[e].map(function(e){var i=e.meta,n=[];if(!0===i.hasMedia&&(!1!==e.spinner?n.push(t(e.spinner,{staticClass:"q-notification__spinner q-notification__spinner--"+i.leftClass,props:{color:e.spinnerColor,size:e.spinnerSize}})):e.icon?n.push(t(Ut,{staticClass:"q-notification__icon q-notification__icon--"+i.leftClass,attrs:{role:"img"},props:{name:e.icon,color:e.iconColor,size:e.iconSize}})):e.avatar&&n.push(t(Kt,{staticClass:"q-notification__avatar q-notification__avatar--"+i.leftClass},[t("img",{attrs:{src:e.avatar,"aria-hidden":"true"}})]))),!0===i.hasText){var s,o={staticClass:"q-notification__message col"};if(!0===e.html)o.domProps={innerHTML:e.caption?"
"+e.message+'
'+e.caption+"
":e.message};else{var r=[e.message];s=e.caption?[t("div",r),t("div",{staticClass:"q-notification__caption"},[e.caption])]:r}n.push(t("div",o,s))}var a=[t("div",{staticClass:i.contentClass},n)];return!0===e.progress&&a.push(t("div",{key:i.uid+"|p|"+i.badge,staticClass:i.progressClass,style:i.progressStyle})),void 0!==e.actions&&a.push(t("div",{staticClass:i.actionsClass},e.actions.map(function(e){return t(Be,Object.assign({},e))}))),i.badge>1&&a.push(t("div",{key:i.uid+"|"+i.badge,staticClass:i.badgeClass,style:e.badgeStyle},[i.badge])),t("div",{ref:""+i.uid,key:i.uid,staticClass:i.staticClass,attrs:i.attrs},[t("div",{staticClass:i.wrapperClass},a)])}))}))},mounted:function(){var t=this;if(void 0!==this.$q.fullscreen&&!0===this.$q.fullscreen.isCapable){var e=function(){var e=me(t.$q.fullscreen.activeEl);t.$el.parentElement!==e&&e.appendChild(t.$el)};this.unwatchFullscreen=this.$watch("$q.fullscreen.activeEl",T(e,50)),!0===this.$q.fullscreen.isActive&&e()}},beforeDestroy:function(){void 0!==this.unwatchFullscreen&&this.unwatchFullscreen()}},$u={setDefaults:function(t){!0!==i&&!0===Zi(t)&&Object.assign(gu,t)},registerType:function(t,e){!0!==i&&!0===Zi(e)&&(xu[t]=e)},install:function(e){var n=e.$q;if(n.notify=this.create=!0===i?p:function(t){return ku(t,mu)},n.notify.setDefaults=this.setDefaults,n.notify.registerType=this.registerType,void 0!==n.config.notify&&this.setDefaults(n.config.notify),!0!==i){wu.forEach(function(t){bu[t]=[];var e=!0===["left","center","right"].includes(t)?"center":t.indexOf("top")>-1?"top":"bottom",i=t.indexOf("left")>-1?"start":t.indexOf("right")>-1?"end":"center",n=["left","right"].includes(t)?"items-"+("left"===t?"start":"end")+" justify-center":"center"===t?"flex-center":"items-"+i;yu[t]="q-notifications__list q-notifications__list--"+e+" fixed column no-wrap "+n});var s=document.createElement("div");document.body.appendChild(s),(mu=new t(Mu)).$mount(s)}}};function Lu(t){return!0===Ji(t)?"__q_date|"+t.toUTCString():!0==(e=t,"[object RegExp]"===Object.prototype.toString.call(e))?"__q_expr|"+t.source:"number"==typeof t?"__q_numb|"+t:"boolean"==typeof t?"__q_bool|"+(t?"1":"0"):"string"==typeof t?"__q_strn|"+t:"function"==typeof t?"__q_strn|"+t.toString():t===Object(t)?"__q_objt|"+JSON.stringify(t):t;var e}function Ou(){var t=function(){return null};return{has:function(){return!1},getLength:function(){return 0},getItem:t,getIndex:t,getKey:t,getAll:function(){},getAllKeys:function(){return[]},set:p,remove:p,clear:p,isEmpty:function(){return!0}}}function Bu(t){var e=window[t+"Storage"],i=function(t){var i=e.getItem(t);return i?function(t){if(t.length<9)return t;var e=t.substr(0,8),i=t.substring(9);switch(e){case"__q_date":return new Date(i);case"__q_expr":return new RegExp(i);case"__q_numb":return Number(i);case"__q_bool":return Boolean("1"===i);case"__q_strn":return""+i;case"__q_objt":return JSON.parse(i);default:return t}}(i):null};return{has:function(t){return null!==e.getItem(t)},getLength:function(){return e.length},getItem:i,getIndex:function(t){return tt.EPSILON_FLOAT&&(e=1/e,A[0]*=e,A[1]*=e,A[2]*=e),A},i.crossProduct=function(A,t){return[A[1]*t[2]-A[2]*t[1],A[2]*t[0]-A[0]*t[2],A[0]*t[1]-A[1]*t[0]]},A.exports=i},function(A,t,e){"use strict";function i(A,t){void 0==t&&(t={}),void 0==t.ambisonicOrder&&(t.ambisonicOrder=s.DEFAULT_AMBISONIC_ORDER),void 0==t.azimuth&&(t.azimuth=s.DEFAULT_AZIMUTH),void 0==t.elevation&&(t.elevation=s.DEFAULT_ELEVATION),void 0==t.sourceWidth&&(t.sourceWidth=s.DEFAULT_SOURCE_WIDTH),this._context=A,this.input=A.createGain(),this._channelGain=[],this._merger=void 0,this.output=A.createGain(),this.setAmbisonicOrder(t.ambisonicOrder),this._azimuth=t.azimuth,this._elevation=t.elevation,this.setSourceWidth(t.sourceWidth)}/** + * @license + * Copyright 2017 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const n=e(3),s=e(0);i.prototype.setAmbisonicOrder=function(A){this._ambisonicOrder=i.validateAmbisonicOrder(A),this.input.disconnect();for(let e=0;en.SPHERICAL_HARMONICS_MAX_ORDER&&(s.log("Error: Unable to render ambisonic order",options.ambisonicOrder,"(Max order is",n.SPHERICAL_HARMONICS_MAX_ORDER,")\nUsing max order instead."),options.ambisonicOrder=n.SPHERICAL_HARMONICS_MAX_ORDER),A},A.exports=i},function(A,t,e){"use strict";function i(A,t){void 0==t&&(t={}),void 0==t.ambisonicOrder&&(t.ambisonicOrder=o.DEFAULT_AMBISONIC_ORDER),void 0==t.position&&(t.position=o.DEFAULT_POSITION.slice()),void 0==t.forward&&(t.forward=o.DEFAULT_FORWARD.slice()),void 0==t.up&&(t.up=o.DEFAULT_UP.slice()),this.position=new Float32Array(3),this._tempMatrix3=new Float32Array(9),this._ambisonicOrder=s.validateAmbisonicOrder(t.ambisonicOrder),this._context=A,1==this._ambisonicOrder?this._renderer=n.Omnitone.createFOARenderer(A,{}):this._ambisonicOrder>1&&(this._renderer=n.Omnitone.createHOARenderer(A,{ambisonicOrder:this._ambisonicOrder})),this.input=A.createGain(),this.output=A.createGain(),this.ambisonicOutput=A.createGain();let e=this;this._renderer.initialize().then(function(){e.input.connect(e._renderer.input),e._ambisonicOrder>1?e._renderer._hoaRotator.output.connect(e.ambisonicOutput):e._renderer._foaRotator.output.connect(e.ambisonicOutput),e._renderer.output.connect(e.output)}),this.setOrientation(t.forward[0],t.forward[1],t.forward[2],t.up[0],t.up[1],t.up[2])}/** + * @license + * Copyright 2017 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const n=e(12),s=e(1),o=e(0);i.prototype.setOrientation=function(A,t,e,i,n,s){let r=o.crossProduct([A,t,e],[i,n,s]);this._tempMatrix3[0]=r[0],this._tempMatrix3[1]=r[1],this._tempMatrix3[2]=r[2],this._tempMatrix3[3]=i,this._tempMatrix3[4]=n,this._tempMatrix3[5]=s,this._tempMatrix3[6]=A,this._tempMatrix3[7]=t,this._tempMatrix3[8]=e,this._renderer.setRotationMatrix3(this._tempMatrix3)},i.prototype.setFromMatrix=function(A){this._renderer.setRotationMatrix4(A.elements),this.position[0]=A.elements[12],this.position[1]=A.elements[13],this.position[2]=A.elements[14]},A.exports=i},function(A,t,e){"use strict";t.SPHERICAL_HARMONICS=[[[0,0,0,1,1,1],[.052336,.034899,.017452,.999848,.999391,.99863],[.104528,.069756,.034899,.999391,.997564,.994522],[.156434,.104528,.052336,.99863,.994522,.987688],[.207912,.139173,.069756,.997564,.990268,.978148],[.258819,.173648,.087156,.996195,.984808,.965926],[.309017,.207912,.104528,.994522,.978148,.951057],[.358368,.241922,.121869,.992546,.970296,.93358],[.406737,.275637,.139173,.990268,.961262,.913545],[.45399,.309017,.156434,.987688,.951057,.891007],[.5,.34202,.173648,.984808,.939693,.866025],[.544639,.374607,.190809,.981627,.927184,.838671],[.587785,.406737,.207912,.978148,.913545,.809017],[.62932,.438371,.224951,.97437,.898794,.777146],[.669131,.469472,.241922,.970296,.882948,.743145],[.707107,.5,.258819,.965926,.866025,.707107],[.743145,.529919,.275637,.961262,.848048,.669131],[.777146,.559193,.292372,.956305,.829038,.62932],[.809017,.587785,.309017,.951057,.809017,.587785],[.838671,.615661,.325568,.945519,.788011,.544639],[.866025,.642788,.34202,.939693,.766044,.5],[.891007,.669131,.358368,.93358,.743145,.45399],[.913545,.694658,.374607,.927184,.71934,.406737],[.93358,.71934,.390731,.920505,.694658,.358368],[.951057,.743145,.406737,.913545,.669131,.309017],[.965926,.766044,.422618,.906308,.642788,.258819],[.978148,.788011,.438371,.898794,.615661,.207912],[.987688,.809017,.45399,.891007,.587785,.156434],[.994522,.829038,.469472,.882948,.559193,.104528],[.99863,.848048,.48481,.87462,.529919,.052336],[1,.866025,.5,.866025,.5,0],[.99863,.882948,.515038,.857167,.469472,-.052336],[.994522,.898794,.529919,.848048,.438371,-.104528],[.987688,.913545,.544639,.838671,.406737,-.156434],[.978148,.927184,.559193,.829038,.374607,-.207912],[.965926,.939693,.573576,.819152,.34202,-.258819],[.951057,.951057,.587785,.809017,.309017,-.309017],[.93358,.961262,.601815,.798636,.275637,-.358368],[.913545,.970296,.615661,.788011,.241922,-.406737],[.891007,.978148,.62932,.777146,.207912,-.45399],[.866025,.984808,.642788,.766044,.173648,-.5],[.838671,.990268,.656059,.75471,.139173,-.544639],[.809017,.994522,.669131,.743145,.104528,-.587785],[.777146,.997564,.681998,.731354,.069756,-.62932],[.743145,.999391,.694658,.71934,.034899,-.669131],[.707107,1,.707107,.707107,0,-.707107],[.669131,.999391,.71934,.694658,-.034899,-.743145],[.62932,.997564,.731354,.681998,-.069756,-.777146],[.587785,.994522,.743145,.669131,-.104528,-.809017],[.544639,.990268,.75471,.656059,-.139173,-.838671],[.5,.984808,.766044,.642788,-.173648,-.866025],[.45399,.978148,.777146,.62932,-.207912,-.891007],[.406737,.970296,.788011,.615661,-.241922,-.913545],[.358368,.961262,.798636,.601815,-.275637,-.93358],[.309017,.951057,.809017,.587785,-.309017,-.951057],[.258819,.939693,.819152,.573576,-.34202,-.965926],[.207912,.927184,.829038,.559193,-.374607,-.978148],[.156434,.913545,.838671,.544639,-.406737,-.987688],[.104528,.898794,.848048,.529919,-.438371,-.994522],[.052336,.882948,.857167,.515038,-.469472,-.99863],[0,.866025,.866025,.5,-.5,-1],[-.052336,.848048,.87462,.48481,-.529919,-.99863],[-.104528,.829038,.882948,.469472,-.559193,-.994522],[-.156434,.809017,.891007,.45399,-.587785,-.987688],[-.207912,.788011,.898794,.438371,-.615661,-.978148],[-.258819,.766044,.906308,.422618,-.642788,-.965926],[-.309017,.743145,.913545,.406737,-.669131,-.951057],[-.358368,.71934,.920505,.390731,-.694658,-.93358],[-.406737,.694658,.927184,.374607,-.71934,-.913545],[-.45399,.669131,.93358,.358368,-.743145,-.891007],[-.5,.642788,.939693,.34202,-.766044,-.866025],[-.544639,.615661,.945519,.325568,-.788011,-.838671],[-.587785,.587785,.951057,.309017,-.809017,-.809017],[-.62932,.559193,.956305,.292372,-.829038,-.777146],[-.669131,.529919,.961262,.275637,-.848048,-.743145],[-.707107,.5,.965926,.258819,-.866025,-.707107],[-.743145,.469472,.970296,.241922,-.882948,-.669131],[-.777146,.438371,.97437,.224951,-.898794,-.62932],[-.809017,.406737,.978148,.207912,-.913545,-.587785],[-.838671,.374607,.981627,.190809,-.927184,-.544639],[-.866025,.34202,.984808,.173648,-.939693,-.5],[-.891007,.309017,.987688,.156434,-.951057,-.45399],[-.913545,.275637,.990268,.139173,-.961262,-.406737],[-.93358,.241922,.992546,.121869,-.970296,-.358368],[-.951057,.207912,.994522,.104528,-.978148,-.309017],[-.965926,.173648,.996195,.087156,-.984808,-.258819],[-.978148,.139173,.997564,.069756,-.990268,-.207912],[-.987688,.104528,.99863,.052336,-.994522,-.156434],[-.994522,.069756,.999391,.034899,-.997564,-.104528],[-.99863,.034899,.999848,.017452,-.999391,-.052336],[-1,0,1,0,-1,-0],[-.99863,-.034899,.999848,-.017452,-.999391,.052336],[-.994522,-.069756,.999391,-.034899,-.997564,.104528],[-.987688,-.104528,.99863,-.052336,-.994522,.156434],[-.978148,-.139173,.997564,-.069756,-.990268,.207912],[-.965926,-.173648,.996195,-.087156,-.984808,.258819],[-.951057,-.207912,.994522,-.104528,-.978148,.309017],[-.93358,-.241922,.992546,-.121869,-.970296,.358368],[-.913545,-.275637,.990268,-.139173,-.961262,.406737],[-.891007,-.309017,.987688,-.156434,-.951057,.45399],[-.866025,-.34202,.984808,-.173648,-.939693,.5],[-.838671,-.374607,.981627,-.190809,-.927184,.544639],[-.809017,-.406737,.978148,-.207912,-.913545,.587785],[-.777146,-.438371,.97437,-.224951,-.898794,.62932],[-.743145,-.469472,.970296,-.241922,-.882948,.669131],[-.707107,-.5,.965926,-.258819,-.866025,.707107],[-.669131,-.529919,.961262,-.275637,-.848048,.743145],[-.62932,-.559193,.956305,-.292372,-.829038,.777146],[-.587785,-.587785,.951057,-.309017,-.809017,.809017],[-.544639,-.615661,.945519,-.325568,-.788011,.838671],[-.5,-.642788,.939693,-.34202,-.766044,.866025],[-.45399,-.669131,.93358,-.358368,-.743145,.891007],[-.406737,-.694658,.927184,-.374607,-.71934,.913545],[-.358368,-.71934,.920505,-.390731,-.694658,.93358],[-.309017,-.743145,.913545,-.406737,-.669131,.951057],[-.258819,-.766044,.906308,-.422618,-.642788,.965926],[-.207912,-.788011,.898794,-.438371,-.615661,.978148],[-.156434,-.809017,.891007,-.45399,-.587785,.987688],[-.104528,-.829038,.882948,-.469472,-.559193,.994522],[-.052336,-.848048,.87462,-.48481,-.529919,.99863],[-0,-.866025,.866025,-.5,-.5,1],[.052336,-.882948,.857167,-.515038,-.469472,.99863],[.104528,-.898794,.848048,-.529919,-.438371,.994522],[.156434,-.913545,.838671,-.544639,-.406737,.987688],[.207912,-.927184,.829038,-.559193,-.374607,.978148],[.258819,-.939693,.819152,-.573576,-.34202,.965926],[.309017,-.951057,.809017,-.587785,-.309017,.951057],[.358368,-.961262,.798636,-.601815,-.275637,.93358],[.406737,-.970296,.788011,-.615661,-.241922,.913545],[.45399,-.978148,.777146,-.62932,-.207912,.891007],[.5,-.984808,.766044,-.642788,-.173648,.866025],[.544639,-.990268,.75471,-.656059,-.139173,.838671],[.587785,-.994522,.743145,-.669131,-.104528,.809017],[.62932,-.997564,.731354,-.681998,-.069756,.777146],[.669131,-.999391,.71934,-.694658,-.034899,.743145],[.707107,-1,.707107,-.707107,-0,.707107],[.743145,-.999391,.694658,-.71934,.034899,.669131],[.777146,-.997564,.681998,-.731354,.069756,.62932],[.809017,-.994522,.669131,-.743145,.104528,.587785],[.838671,-.990268,.656059,-.75471,.139173,.544639],[.866025,-.984808,.642788,-.766044,.173648,.5],[.891007,-.978148,.62932,-.777146,.207912,.45399],[.913545,-.970296,.615661,-.788011,.241922,.406737],[.93358,-.961262,.601815,-.798636,.275637,.358368],[.951057,-.951057,.587785,-.809017,.309017,.309017],[.965926,-.939693,.573576,-.819152,.34202,.258819],[.978148,-.927184,.559193,-.829038,.374607,.207912],[.987688,-.913545,.544639,-.838671,.406737,.156434],[.994522,-.898794,.529919,-.848048,.438371,.104528],[.99863,-.882948,.515038,-.857167,.469472,.052336],[1,-.866025,.5,-.866025,.5,0],[.99863,-.848048,.48481,-.87462,.529919,-.052336],[.994522,-.829038,.469472,-.882948,.559193,-.104528],[.987688,-.809017,.45399,-.891007,.587785,-.156434],[.978148,-.788011,.438371,-.898794,.615661,-.207912],[.965926,-.766044,.422618,-.906308,.642788,-.258819],[.951057,-.743145,.406737,-.913545,.669131,-.309017],[.93358,-.71934,.390731,-.920505,.694658,-.358368],[.913545,-.694658,.374607,-.927184,.71934,-.406737],[.891007,-.669131,.358368,-.93358,.743145,-.45399],[.866025,-.642788,.34202,-.939693,.766044,-.5],[.838671,-.615661,.325568,-.945519,.788011,-.544639],[.809017,-.587785,.309017,-.951057,.809017,-.587785],[.777146,-.559193,.292372,-.956305,.829038,-.62932],[.743145,-.529919,.275637,-.961262,.848048,-.669131],[.707107,-.5,.258819,-.965926,.866025,-.707107],[.669131,-.469472,.241922,-.970296,.882948,-.743145],[.62932,-.438371,.224951,-.97437,.898794,-.777146],[.587785,-.406737,.207912,-.978148,.913545,-.809017],[.544639,-.374607,.190809,-.981627,.927184,-.838671],[.5,-.34202,.173648,-.984808,.939693,-.866025],[.45399,-.309017,.156434,-.987688,.951057,-.891007],[.406737,-.275637,.139173,-.990268,.961262,-.913545],[.358368,-.241922,.121869,-.992546,.970296,-.93358],[.309017,-.207912,.104528,-.994522,.978148,-.951057],[.258819,-.173648,.087156,-.996195,.984808,-.965926],[.207912,-.139173,.069756,-.997564,.990268,-.978148],[.156434,-.104528,.052336,-.99863,.994522,-.987688],[.104528,-.069756,.034899,-.999391,.997564,-.994522],[.052336,-.034899,.017452,-.999848,.999391,-.99863],[0,-0,0,-1,1,-1],[-.052336,.034899,-.017452,-.999848,.999391,-.99863],[-.104528,.069756,-.034899,-.999391,.997564,-.994522],[-.156434,.104528,-.052336,-.99863,.994522,-.987688],[-.207912,.139173,-.069756,-.997564,.990268,-.978148],[-.258819,.173648,-.087156,-.996195,.984808,-.965926],[-.309017,.207912,-.104528,-.994522,.978148,-.951057],[-.358368,.241922,-.121869,-.992546,.970296,-.93358],[-.406737,.275637,-.139173,-.990268,.961262,-.913545],[-.45399,.309017,-.156434,-.987688,.951057,-.891007],[-.5,.34202,-.173648,-.984808,.939693,-.866025],[-.544639,.374607,-.190809,-.981627,.927184,-.838671],[-.587785,.406737,-.207912,-.978148,.913545,-.809017],[-.62932,.438371,-.224951,-.97437,.898794,-.777146],[-.669131,.469472,-.241922,-.970296,.882948,-.743145],[-.707107,.5,-.258819,-.965926,.866025,-.707107],[-.743145,.529919,-.275637,-.961262,.848048,-.669131],[-.777146,.559193,-.292372,-.956305,.829038,-.62932],[-.809017,.587785,-.309017,-.951057,.809017,-.587785],[-.838671,.615661,-.325568,-.945519,.788011,-.544639],[-.866025,.642788,-.34202,-.939693,.766044,-.5],[-.891007,.669131,-.358368,-.93358,.743145,-.45399],[-.913545,.694658,-.374607,-.927184,.71934,-.406737],[-.93358,.71934,-.390731,-.920505,.694658,-.358368],[-.951057,.743145,-.406737,-.913545,.669131,-.309017],[-.965926,.766044,-.422618,-.906308,.642788,-.258819],[-.978148,.788011,-.438371,-.898794,.615661,-.207912],[-.987688,.809017,-.45399,-.891007,.587785,-.156434],[-.994522,.829038,-.469472,-.882948,.559193,-.104528],[-.99863,.848048,-.48481,-.87462,.529919,-.052336],[-1,.866025,-.5,-.866025,.5,0],[-.99863,.882948,-.515038,-.857167,.469472,.052336],[-.994522,.898794,-.529919,-.848048,.438371,.104528],[-.987688,.913545,-.544639,-.838671,.406737,.156434],[-.978148,.927184,-.559193,-.829038,.374607,.207912],[-.965926,.939693,-.573576,-.819152,.34202,.258819],[-.951057,.951057,-.587785,-.809017,.309017,.309017],[-.93358,.961262,-.601815,-.798636,.275637,.358368],[-.913545,.970296,-.615661,-.788011,.241922,.406737],[-.891007,.978148,-.62932,-.777146,.207912,.45399],[-.866025,.984808,-.642788,-.766044,.173648,.5],[-.838671,.990268,-.656059,-.75471,.139173,.544639],[-.809017,.994522,-.669131,-.743145,.104528,.587785],[-.777146,.997564,-.681998,-.731354,.069756,.62932],[-.743145,.999391,-.694658,-.71934,.034899,.669131],[-.707107,1,-.707107,-.707107,0,.707107],[-.669131,.999391,-.71934,-.694658,-.034899,.743145],[-.62932,.997564,-.731354,-.681998,-.069756,.777146],[-.587785,.994522,-.743145,-.669131,-.104528,.809017],[-.544639,.990268,-.75471,-.656059,-.139173,.838671],[-.5,.984808,-.766044,-.642788,-.173648,.866025],[-.45399,.978148,-.777146,-.62932,-.207912,.891007],[-.406737,.970296,-.788011,-.615661,-.241922,.913545],[-.358368,.961262,-.798636,-.601815,-.275637,.93358],[-.309017,.951057,-.809017,-.587785,-.309017,.951057],[-.258819,.939693,-.819152,-.573576,-.34202,.965926],[-.207912,.927184,-.829038,-.559193,-.374607,.978148],[-.156434,.913545,-.838671,-.544639,-.406737,.987688],[-.104528,.898794,-.848048,-.529919,-.438371,.994522],[-.052336,.882948,-.857167,-.515038,-.469472,.99863],[-0,.866025,-.866025,-.5,-.5,1],[.052336,.848048,-.87462,-.48481,-.529919,.99863],[.104528,.829038,-.882948,-.469472,-.559193,.994522],[.156434,.809017,-.891007,-.45399,-.587785,.987688],[.207912,.788011,-.898794,-.438371,-.615661,.978148],[.258819,.766044,-.906308,-.422618,-.642788,.965926],[.309017,.743145,-.913545,-.406737,-.669131,.951057],[.358368,.71934,-.920505,-.390731,-.694658,.93358],[.406737,.694658,-.927184,-.374607,-.71934,.913545],[.45399,.669131,-.93358,-.358368,-.743145,.891007],[.5,.642788,-.939693,-.34202,-.766044,.866025],[.544639,.615661,-.945519,-.325568,-.788011,.838671],[.587785,.587785,-.951057,-.309017,-.809017,.809017],[.62932,.559193,-.956305,-.292372,-.829038,.777146],[.669131,.529919,-.961262,-.275637,-.848048,.743145],[.707107,.5,-.965926,-.258819,-.866025,.707107],[.743145,.469472,-.970296,-.241922,-.882948,.669131],[.777146,.438371,-.97437,-.224951,-.898794,.62932],[.809017,.406737,-.978148,-.207912,-.913545,.587785],[.838671,.374607,-.981627,-.190809,-.927184,.544639],[.866025,.34202,-.984808,-.173648,-.939693,.5],[.891007,.309017,-.987688,-.156434,-.951057,.45399],[.913545,.275637,-.990268,-.139173,-.961262,.406737],[.93358,.241922,-.992546,-.121869,-.970296,.358368],[.951057,.207912,-.994522,-.104528,-.978148,.309017],[.965926,.173648,-.996195,-.087156,-.984808,.258819],[.978148,.139173,-.997564,-.069756,-.990268,.207912],[.987688,.104528,-.99863,-.052336,-.994522,.156434],[.994522,.069756,-.999391,-.034899,-.997564,.104528],[.99863,.034899,-.999848,-.017452,-.999391,.052336],[1,0,-1,-0,-1,0],[.99863,-.034899,-.999848,.017452,-.999391,-.052336],[.994522,-.069756,-.999391,.034899,-.997564,-.104528],[.987688,-.104528,-.99863,.052336,-.994522,-.156434],[.978148,-.139173,-.997564,.069756,-.990268,-.207912],[.965926,-.173648,-.996195,.087156,-.984808,-.258819],[.951057,-.207912,-.994522,.104528,-.978148,-.309017],[.93358,-.241922,-.992546,.121869,-.970296,-.358368],[.913545,-.275637,-.990268,.139173,-.961262,-.406737],[.891007,-.309017,-.987688,.156434,-.951057,-.45399],[.866025,-.34202,-.984808,.173648,-.939693,-.5],[.838671,-.374607,-.981627,.190809,-.927184,-.544639],[.809017,-.406737,-.978148,.207912,-.913545,-.587785],[.777146,-.438371,-.97437,.224951,-.898794,-.62932],[.743145,-.469472,-.970296,.241922,-.882948,-.669131],[.707107,-.5,-.965926,.258819,-.866025,-.707107],[.669131,-.529919,-.961262,.275637,-.848048,-.743145],[.62932,-.559193,-.956305,.292372,-.829038,-.777146],[.587785,-.587785,-.951057,.309017,-.809017,-.809017],[.544639,-.615661,-.945519,.325568,-.788011,-.838671],[.5,-.642788,-.939693,.34202,-.766044,-.866025],[.45399,-.669131,-.93358,.358368,-.743145,-.891007],[.406737,-.694658,-.927184,.374607,-.71934,-.913545],[.358368,-.71934,-.920505,.390731,-.694658,-.93358],[.309017,-.743145,-.913545,.406737,-.669131,-.951057],[.258819,-.766044,-.906308,.422618,-.642788,-.965926],[.207912,-.788011,-.898794,.438371,-.615661,-.978148],[.156434,-.809017,-.891007,.45399,-.587785,-.987688],[.104528,-.829038,-.882948,.469472,-.559193,-.994522],[.052336,-.848048,-.87462,.48481,-.529919,-.99863],[0,-.866025,-.866025,.5,-.5,-1],[-.052336,-.882948,-.857167,.515038,-.469472,-.99863],[-.104528,-.898794,-.848048,.529919,-.438371,-.994522],[-.156434,-.913545,-.838671,.544639,-.406737,-.987688],[-.207912,-.927184,-.829038,.559193,-.374607,-.978148],[-.258819,-.939693,-.819152,.573576,-.34202,-.965926],[-.309017,-.951057,-.809017,.587785,-.309017,-.951057],[-.358368,-.961262,-.798636,.601815,-.275637,-.93358],[-.406737,-.970296,-.788011,.615661,-.241922,-.913545],[-.45399,-.978148,-.777146,.62932,-.207912,-.891007],[-.5,-.984808,-.766044,.642788,-.173648,-.866025],[-.544639,-.990268,-.75471,.656059,-.139173,-.838671],[-.587785,-.994522,-.743145,.669131,-.104528,-.809017],[-.62932,-.997564,-.731354,.681998,-.069756,-.777146],[-.669131,-.999391,-.71934,.694658,-.034899,-.743145],[-.707107,-1,-.707107,.707107,-0,-.707107],[-.743145,-.999391,-.694658,.71934,.034899,-.669131],[-.777146,-.997564,-.681998,.731354,.069756,-.62932],[-.809017,-.994522,-.669131,.743145,.104528,-.587785],[-.838671,-.990268,-.656059,.75471,.139173,-.544639],[-.866025,-.984808,-.642788,.766044,.173648,-.5],[-.891007,-.978148,-.62932,.777146,.207912,-.45399],[-.913545,-.970296,-.615661,.788011,.241922,-.406737],[-.93358,-.961262,-.601815,.798636,.275637,-.358368],[-.951057,-.951057,-.587785,.809017,.309017,-.309017],[-.965926,-.939693,-.573576,.819152,.34202,-.258819],[-.978148,-.927184,-.559193,.829038,.374607,-.207912],[-.987688,-.913545,-.544639,.838671,.406737,-.156434],[-.994522,-.898794,-.529919,.848048,.438371,-.104528],[-.99863,-.882948,-.515038,.857167,.469472,-.052336],[-1,-.866025,-.5,.866025,.5,-0],[-.99863,-.848048,-.48481,.87462,.529919,.052336],[-.994522,-.829038,-.469472,.882948,.559193,.104528],[-.987688,-.809017,-.45399,.891007,.587785,.156434],[-.978148,-.788011,-.438371,.898794,.615661,.207912],[-.965926,-.766044,-.422618,.906308,.642788,.258819],[-.951057,-.743145,-.406737,.913545,.669131,.309017],[-.93358,-.71934,-.390731,.920505,.694658,.358368],[-.913545,-.694658,-.374607,.927184,.71934,.406737],[-.891007,-.669131,-.358368,.93358,.743145,.45399],[-.866025,-.642788,-.34202,.939693,.766044,.5],[-.838671,-.615661,-.325568,.945519,.788011,.544639],[-.809017,-.587785,-.309017,.951057,.809017,.587785],[-.777146,-.559193,-.292372,.956305,.829038,.62932],[-.743145,-.529919,-.275637,.961262,.848048,.669131],[-.707107,-.5,-.258819,.965926,.866025,.707107],[-.669131,-.469472,-.241922,.970296,.882948,.743145],[-.62932,-.438371,-.224951,.97437,.898794,.777146],[-.587785,-.406737,-.207912,.978148,.913545,.809017],[-.544639,-.374607,-.190809,.981627,.927184,.838671],[-.5,-.34202,-.173648,.984808,.939693,.866025],[-.45399,-.309017,-.156434,.987688,.951057,.891007],[-.406737,-.275637,-.139173,.990268,.961262,.913545],[-.358368,-.241922,-.121869,.992546,.970296,.93358],[-.309017,-.207912,-.104528,.994522,.978148,.951057],[-.258819,-.173648,-.087156,.996195,.984808,.965926],[-.207912,-.139173,-.069756,.997564,.990268,.978148],[-.156434,-.104528,-.052336,.99863,.994522,.987688],[-.104528,-.069756,-.034899,.999391,.997564,.994522],[-.052336,-.034899,-.017452,.999848,.999391,.99863]],[[-1,-0,1,-0,0,-1,-0,0,-0],[-.999848,.017452,.999543,-.030224,264e-6,-.999086,.042733,-59e-5,4e-6],[-.999391,.034899,.998173,-.060411,.001055,-.996348,.085356,-.002357,34e-6],[-.99863,.052336,.995891,-.090524,.002372,-.991791,.127757,-.005297,113e-6],[-.997564,.069756,.992701,-.120527,.004214,-.985429,.169828,-.0094,268e-6],[-.996195,.087156,.988606,-.150384,.006578,-.977277,.21146,-.014654,523e-6],[-.994522,.104528,.983611,-.180057,.009462,-.967356,.252544,-.021043,903e-6],[-.992546,.121869,.977722,-.209511,.012862,-.955693,.292976,-.028547,.001431],[-.990268,.139173,.970946,-.238709,.016774,-.942316,.332649,-.037143,.002131],[-.987688,.156434,.963292,-.267617,.021193,-.927262,.371463,-.046806,.003026],[-.984808,.173648,.954769,-.296198,.026114,-.910569,.409317,-.057505,.00414],[-.981627,.190809,.945388,-.324419,.03153,-.892279,.446114,-.069209,.005492],[-.978148,.207912,.935159,-.352244,.037436,-.872441,.481759,-.08188,.007105],[-.97437,.224951,.924096,-.379641,.043823,-.851105,.516162,-.095481,.008999],[-.970296,.241922,.912211,-.406574,.050685,-.828326,.549233,-.109969,.011193],[-.965926,.258819,.899519,-.433013,.058013,-.804164,.580889,-.1253,.013707],[-.961262,.275637,.886036,-.458924,.065797,-.77868,.61105,-.141427,.016556],[-.956305,.292372,.871778,-.484275,.074029,-.75194,.639639,-.158301,.019758],[-.951057,.309017,.856763,-.509037,.082698,-.724012,.666583,-.175868,.023329],[-.945519,.325568,.841008,-.533178,.091794,-.694969,.691816,-.194075,.027281],[-.939693,.34202,.824533,-.55667,.101306,-.664885,.715274,-.212865,.03163],[-.93358,.358368,.807359,-.579484,.111222,-.633837,.736898,-.23218,.036385],[-.927184,.374607,.789505,-.601592,.121529,-.601904,.756637,-.25196,.041559],[-.920505,.390731,.770994,-.622967,.132217,-.569169,.774442,-.272143,.04716],[-.913545,.406737,.751848,-.643582,.143271,-.535715,.79027,-.292666,.053196],[-.906308,.422618,.732091,-.663414,.154678,-.501627,.804083,-.313464,.059674],[-.898794,.438371,.711746,-.682437,.166423,-.466993,.81585,-.334472,.066599],[-.891007,.45399,.690839,-.700629,.178494,-.431899,.825544,-.355623,.073974],[-.882948,.469472,.669395,-.717968,.190875,-.396436,.833145,-.376851,.081803],[-.87462,.48481,.647439,-.734431,.203551,-.360692,.838638,-.398086,.090085],[-.866025,.5,.625,-.75,.216506,-.32476,.842012,-.419263,.098821],[-.857167,.515038,.602104,-.764655,.229726,-.288728,.843265,-.440311,.108009],[-.848048,.529919,.578778,-.778378,.243192,-.252688,.842399,-.461164,.117644],[-.838671,.544639,.555052,-.791154,.256891,-.21673,.839422,-.481753,.127722],[-.829038,.559193,.530955,-.802965,.270803,-.180944,.834347,-.502011,.138237],[-.819152,.573576,.506515,-.813798,.284914,-.14542,.827194,-.521871,.149181],[-.809017,.587785,.481763,-.823639,.299204,-.110246,.817987,-.541266,.160545],[-.798636,.601815,.456728,-.832477,.313658,-.075508,.806757,-.560132,.172317],[-.788011,.615661,.431441,-.840301,.328257,-.041294,.793541,-.578405,.184487],[-.777146,.62932,.405934,-.847101,.342984,-.007686,.778379,-.596021,.19704],[-.766044,.642788,.380236,-.852869,.357821,.025233,.761319,-.612921,.209963],[-.75471,.656059,.35438,-.857597,.372749,.057383,.742412,-.629044,.223238],[-.743145,.669131,.328396,-.861281,.387751,.088686,.721714,-.644334,.23685],[-.731354,.681998,.302317,-.863916,.402807,.119068,.699288,-.658734,.250778],[-.71934,.694658,.276175,-.865498,.417901,.148454,.675199,-.67219,.265005],[-.707107,.707107,.25,-.866025,.433013,.176777,.649519,-.684653,.279508],[-.694658,.71934,.223825,-.865498,.448125,.203969,.622322,-.696073,.294267],[-.681998,.731354,.197683,-.863916,.463218,.229967,.593688,-.706405,.309259],[-.669131,.743145,.171604,-.861281,.478275,.254712,.5637,-.715605,.324459],[-.656059,.75471,.14562,-.857597,.493276,.278147,.532443,-.723633,.339844],[-.642788,.766044,.119764,-.852869,.508205,.300221,.500009,-.730451,.355387],[-.62932,.777146,.094066,-.847101,.523041,.320884,.46649,-.736025,.371063],[-.615661,.788011,.068559,-.840301,.537768,.340093,.431982,-.740324,.386845],[-.601815,.798636,.043272,-.832477,.552367,.357807,.396584,-.74332,.402704],[-.587785,.809017,.018237,-.823639,.566821,.373991,.360397,-.744989,.418613],[-.573576,.819152,-.006515,-.813798,.581112,.388612,.323524,-.745308,.434544],[-.559193,.829038,-.030955,-.802965,.595222,.401645,.286069,-.744262,.450467],[-.544639,.838671,-.055052,-.791154,.609135,.413066,.24814,-.741835,.466352],[-.529919,.848048,-.078778,-.778378,.622833,.422856,.209843,-.738017,.482171],[-.515038,.857167,-.102104,-.764655,.6363,.431004,.171288,-.732801,.497894],[-.5,.866025,-.125,-.75,.649519,.4375,.132583,-.726184,.51349],[-.48481,.87462,-.147439,-.734431,.662474,.44234,.093837,-.718167,.528929],[-.469472,.882948,-.169395,-.717968,.67515,.445524,.05516,-.708753,.544183],[-.45399,.891007,-.190839,-.700629,.687531,.447059,.016662,-.69795,.55922],[-.438371,.898794,-.211746,-.682437,.699602,.446953,-.02155,-.685769,.574011],[-.422618,.906308,-.232091,-.663414,.711348,.445222,-.059368,-.672226,.588528],[-.406737,.913545,-.251848,-.643582,.722755,.441884,-.096684,-.657339,.602741],[-.390731,.920505,-.270994,-.622967,.733809,.436964,-.133395,-.64113,.616621],[-.374607,.927184,-.289505,-.601592,.744496,.430488,-.169397,-.623624,.630141],[-.358368,.93358,-.307359,-.579484,.754804,.422491,-.204589,-.604851,.643273],[-.34202,.939693,-.324533,-.55667,.76472,.413008,-.238872,-.584843,.65599],[-.325568,.945519,-.341008,-.533178,.774231,.402081,-.27215,-.563635,.668267],[-.309017,.951057,-.356763,-.509037,.783327,.389754,-.304329,-.541266,.680078],[-.292372,.956305,-.371778,-.484275,.791997,.376077,-.335319,-.517778,.691399],[-.275637,.961262,-.386036,-.458924,.800228,.361102,-.365034,-.493216,.702207],[-.258819,.965926,-.399519,-.433013,.808013,.344885,-.393389,-.467627,.712478],[-.241922,.970296,-.412211,-.406574,.81534,.327486,-.420306,-.441061,.722191],[-.224951,.97437,-.424096,-.379641,.822202,.308969,-.445709,-.413572,.731327],[-.207912,.978148,-.435159,-.352244,.828589,.289399,-.469527,-.385215,.739866],[-.190809,.981627,-.445388,-.324419,.834495,.268846,-.491693,-.356047,.74779],[-.173648,.984808,-.454769,-.296198,.839912,.247382,-.512145,-.326129,.755082],[-.156434,.987688,-.463292,-.267617,.844832,.225081,-.530827,-.295521,.761728],[-.139173,.990268,-.470946,-.238709,.849251,.20202,-.547684,-.264287,.767712],[-.121869,.992546,-.477722,-.209511,.853163,.178279,-.562672,-.232494,.773023],[-.104528,.994522,-.483611,-.180057,.856563,.153937,-.575747,-.200207,.777648],[-.087156,.996195,-.488606,-.150384,.859447,.129078,-.586872,-.167494,.781579],[-.069756,.997564,-.492701,-.120527,.861811,.103786,-.596018,-.134426,.784806],[-.052336,.99863,-.495891,-.090524,.863653,.078146,-.603158,-.101071,.787324],[-.034899,.999391,-.498173,-.060411,.864971,.052243,-.608272,-.0675,.789126],[-.017452,.999848,-.499543,-.030224,.865762,.026165,-.611347,-.033786,.790208],[0,1,-.5,0,.866025,-0,-.612372,0,.790569],[.017452,.999848,-.499543,.030224,.865762,-.026165,-.611347,.033786,.790208],[.034899,.999391,-.498173,.060411,.864971,-.052243,-.608272,.0675,.789126],[.052336,.99863,-.495891,.090524,.863653,-.078146,-.603158,.101071,.787324],[.069756,.997564,-.492701,.120527,.861811,-.103786,-.596018,.134426,.784806],[.087156,.996195,-.488606,.150384,.859447,-.129078,-.586872,.167494,.781579],[.104528,.994522,-.483611,.180057,.856563,-.153937,-.575747,.200207,.777648],[.121869,.992546,-.477722,.209511,.853163,-.178279,-.562672,.232494,.773023],[.139173,.990268,-.470946,.238709,.849251,-.20202,-.547684,.264287,.767712],[.156434,.987688,-.463292,.267617,.844832,-.225081,-.530827,.295521,.761728],[.173648,.984808,-.454769,.296198,.839912,-.247382,-.512145,.326129,.755082],[.190809,.981627,-.445388,.324419,.834495,-.268846,-.491693,.356047,.74779],[.207912,.978148,-.435159,.352244,.828589,-.289399,-.469527,.385215,.739866],[.224951,.97437,-.424096,.379641,.822202,-.308969,-.445709,.413572,.731327],[.241922,.970296,-.412211,.406574,.81534,-.327486,-.420306,.441061,.722191],[.258819,.965926,-.399519,.433013,.808013,-.344885,-.393389,.467627,.712478],[.275637,.961262,-.386036,.458924,.800228,-.361102,-.365034,.493216,.702207],[.292372,.956305,-.371778,.484275,.791997,-.376077,-.335319,.517778,.691399],[.309017,.951057,-.356763,.509037,.783327,-.389754,-.304329,.541266,.680078],[.325568,.945519,-.341008,.533178,.774231,-.402081,-.27215,.563635,.668267],[.34202,.939693,-.324533,.55667,.76472,-.413008,-.238872,.584843,.65599],[.358368,.93358,-.307359,.579484,.754804,-.422491,-.204589,.604851,.643273],[.374607,.927184,-.289505,.601592,.744496,-.430488,-.169397,.623624,.630141],[.390731,.920505,-.270994,.622967,.733809,-.436964,-.133395,.64113,.616621],[.406737,.913545,-.251848,.643582,.722755,-.441884,-.096684,.657339,.602741],[.422618,.906308,-.232091,.663414,.711348,-.445222,-.059368,.672226,.588528],[.438371,.898794,-.211746,.682437,.699602,-.446953,-.02155,.685769,.574011],[.45399,.891007,-.190839,.700629,.687531,-.447059,.016662,.69795,.55922],[.469472,.882948,-.169395,.717968,.67515,-.445524,.05516,.708753,.544183],[.48481,.87462,-.147439,.734431,.662474,-.44234,.093837,.718167,.528929],[.5,.866025,-.125,.75,.649519,-.4375,.132583,.726184,.51349],[.515038,.857167,-.102104,.764655,.6363,-.431004,.171288,.732801,.497894],[.529919,.848048,-.078778,.778378,.622833,-.422856,.209843,.738017,.482171],[.544639,.838671,-.055052,.791154,.609135,-.413066,.24814,.741835,.466352],[.559193,.829038,-.030955,.802965,.595222,-.401645,.286069,.744262,.450467],[.573576,.819152,-.006515,.813798,.581112,-.388612,.323524,.745308,.434544],[.587785,.809017,.018237,.823639,.566821,-.373991,.360397,.744989,.418613],[.601815,.798636,.043272,.832477,.552367,-.357807,.396584,.74332,.402704],[.615661,.788011,.068559,.840301,.537768,-.340093,.431982,.740324,.386845],[.62932,.777146,.094066,.847101,.523041,-.320884,.46649,.736025,.371063],[.642788,.766044,.119764,.852869,.508205,-.300221,.500009,.730451,.355387],[.656059,.75471,.14562,.857597,.493276,-.278147,.532443,.723633,.339844],[.669131,.743145,.171604,.861281,.478275,-.254712,.5637,.715605,.324459],[.681998,.731354,.197683,.863916,.463218,-.229967,.593688,.706405,.309259],[.694658,.71934,.223825,.865498,.448125,-.203969,.622322,.696073,.294267],[.707107,.707107,.25,.866025,.433013,-.176777,.649519,.684653,.279508],[.71934,.694658,.276175,.865498,.417901,-.148454,.675199,.67219,.265005],[.731354,.681998,.302317,.863916,.402807,-.119068,.699288,.658734,.250778],[.743145,.669131,.328396,.861281,.387751,-.088686,.721714,.644334,.23685],[.75471,.656059,.35438,.857597,.372749,-.057383,.742412,.629044,.223238],[.766044,.642788,.380236,.852869,.357821,-.025233,.761319,.612921,.209963],[.777146,.62932,.405934,.847101,.342984,.007686,.778379,.596021,.19704],[.788011,.615661,.431441,.840301,.328257,.041294,.793541,.578405,.184487],[.798636,.601815,.456728,.832477,.313658,.075508,.806757,.560132,.172317],[.809017,.587785,.481763,.823639,.299204,.110246,.817987,.541266,.160545],[.819152,.573576,.506515,.813798,.284914,.14542,.827194,.521871,.149181],[.829038,.559193,.530955,.802965,.270803,.180944,.834347,.502011,.138237],[.838671,.544639,.555052,.791154,.256891,.21673,.839422,.481753,.127722],[.848048,.529919,.578778,.778378,.243192,.252688,.842399,.461164,.117644],[.857167,.515038,.602104,.764655,.229726,.288728,.843265,.440311,.108009],[.866025,.5,.625,.75,.216506,.32476,.842012,.419263,.098821],[.87462,.48481,.647439,.734431,.203551,.360692,.838638,.398086,.090085],[.882948,.469472,.669395,.717968,.190875,.396436,.833145,.376851,.081803],[.891007,.45399,.690839,.700629,.178494,.431899,.825544,.355623,.073974],[.898794,.438371,.711746,.682437,.166423,.466993,.81585,.334472,.066599],[.906308,.422618,.732091,.663414,.154678,.501627,.804083,.313464,.059674],[.913545,.406737,.751848,.643582,.143271,.535715,.79027,.292666,.053196],[.920505,.390731,.770994,.622967,.132217,.569169,.774442,.272143,.04716],[.927184,.374607,.789505,.601592,.121529,.601904,.756637,.25196,.041559],[.93358,.358368,.807359,.579484,.111222,.633837,.736898,.23218,.036385],[.939693,.34202,.824533,.55667,.101306,.664885,.715274,.212865,.03163],[.945519,.325568,.841008,.533178,.091794,.694969,.691816,.194075,.027281],[.951057,.309017,.856763,.509037,.082698,.724012,.666583,.175868,.023329],[.956305,.292372,.871778,.484275,.074029,.75194,.639639,.158301,.019758],[.961262,.275637,.886036,.458924,.065797,.77868,.61105,.141427,.016556],[.965926,.258819,.899519,.433013,.058013,.804164,.580889,.1253,.013707],[.970296,.241922,.912211,.406574,.050685,.828326,.549233,.109969,.011193],[.97437,.224951,.924096,.379641,.043823,.851105,.516162,.095481,.008999],[.978148,.207912,.935159,.352244,.037436,.872441,.481759,.08188,.007105],[.981627,.190809,.945388,.324419,.03153,.892279,.446114,.069209,.005492],[.984808,.173648,.954769,.296198,.026114,.910569,.409317,.057505,.00414],[.987688,.156434,.963292,.267617,.021193,.927262,.371463,.046806,.003026],[.990268,.139173,.970946,.238709,.016774,.942316,.332649,.037143,.002131],[.992546,.121869,.977722,.209511,.012862,.955693,.292976,.028547,.001431],[.994522,.104528,.983611,.180057,.009462,.967356,.252544,.021043,903e-6],[.996195,.087156,.988606,.150384,.006578,.977277,.21146,.014654,523e-6],[.997564,.069756,.992701,.120527,.004214,.985429,.169828,.0094,268e-6],[.99863,.052336,.995891,.090524,.002372,.991791,.127757,.005297,113e-6],[.999391,.034899,.998173,.060411,.001055,.996348,.085356,.002357,34e-6],[.999848,.017452,.999543,.030224,264e-6,.999086,.042733,59e-5,4e-6],[1,-0,1,-0,0,1,-0,0,-0]]],t.SPHERICAL_HARMONICS_AZIMUTH_RESOLUTION=t.SPHERICAL_HARMONICS[0].length,t.SPHERICAL_HARMONICS_ELEVATION_RESOLUTION=t.SPHERICAL_HARMONICS[1].length,t.SPHERICAL_HARMONICS_MAX_ORDER=t.SPHERICAL_HARMONICS[0][0].length/2,t.MAX_RE_WEIGHTS=[[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1],[1.003236,1.002156,.999152,.990038],[1.03237,1.021194,.990433,.898572],[1.062694,1.040231,.979161,.799806],[1.093999,1.058954,.964976,.693603],[1.126003,1.077006,.947526,.57989],[1.158345,1.093982,.926474,.45869],[1.19059,1.109437,.901512,.330158],[1.222228,1.12289,.87237,.194621],[1.252684,1.133837,.838839,.052614],[1.281987,1.142358,.801199,0],[1.312073,1.150207,.760839,0],[1.343011,1.157424,.717799,0],[1.374649,1.163859,.671999,0],[1.406809,1.169354,.623371,0],[1.439286,1.173739,.571868,0],[1.471846,1.176837,.517465,0],[1.504226,1.178465,.460174,0],[1.536133,1.178438,.400043,0],[1.567253,1.176573,.337165,0],[1.597247,1.172695,.271688,0],[1.625766,1.166645,.203815,0],[1.652455,1.158285,.133806,0],[1.676966,1.147506,.061983,0],[1.699006,1.134261,0,0],[1.720224,1.119789,0,0],[1.741631,1.10481,0,0],[1.763183,1.08933,0,0],[1.784837,1.073356,0,0],[1.806548,1.056898,0,0],[1.828269,1.039968,0,0],[1.849952,1.02258,0,0],[1.871552,1.004752,0,0],[1.893018,.986504,0,0],[1.914305,.967857,0,0],[1.935366,.948837,0,0],[1.956154,.929471,0,0],[1.976625,.90979,0,0],[1.996736,.889823,0,0],[2.016448,.869607,0,0],[2.035721,.849175,0,0],[2.054522,.828565,0,0],[2.072818,.807816,0,0],[2.090581,.786964,0,0],[2.107785,.766051,0,0],[2.124411,.745115,0,0],[2.140439,.724196,0,0],[2.155856,.703332,0,0],[2.170653,.682561,0,0],[2.184823,.661921,0,0],[2.198364,.641445,0,0],[2.211275,.621169,0,0],[2.223562,.601125,0,0],[2.23523,.581341,0,0],[2.246289,.561847,0,0],[2.256751,.542667,0,0],[2.266631,.523826,0,0],[2.275943,.505344,0,0],[2.284707,.487239,0,0],[2.292939,.469528,0,0],[2.300661,.452225,0,0],[2.307892,.435342,0,0],[2.314654,.418888,0,0],[2.320969,.40287,0,0],[2.326858,.387294,0,0],[2.332343,.372164,0,0],[2.337445,.357481,0,0],[2.342186,.343246,0,0],[2.346585,.329458,0,0],[2.350664,.316113,0,0],[2.354442,.303208,0,0],[2.357937,.290738,0,0],[2.361168,.278698,0,0],[2.364152,.26708,0,0],[2.366906,.255878,0,0],[2.369446,.245082,0,0],[2.371786,.234685,0,0],[2.37394,.224677,0,0],[2.375923,.215048,0,0],[2.377745,.20579,0,0],[2.379421,.196891,0,0],[2.380959,.188342,0,0],[2.382372,.180132,0,0],[2.383667,.172251,0,0],[2.384856,.164689,0,0],[2.385945,.157435,0,0],[2.386943,.150479,0,0],[2.387857,.143811,0,0],[2.388694,.137421,0,0],[2.38946,.131299,0,0],[2.39016,.125435,0,0],[2.390801,.11982,0,0],[2.391386,.114445,0,0],[2.391921,.1093,0,0],[2.39241,.104376,0,0],[2.392857,.099666,0,0],[2.393265,.09516,0,0],[2.393637,.090851,0,0],[2.393977,.086731,0,0],[2.394288,.082791,0,0],[2.394571,.079025,0,0],[2.394829,.075426,0,0],[2.395064,.071986,0,0],[2.395279,.068699,0,0],[2.395475,.065558,0,0],[2.395653,.062558,0,0],[2.395816,.059693,0,0],[2.395964,.056955,0,0],[2.396099,.054341,0,0],[2.396222,.051845,0,0],[2.396334,.049462,0,0],[2.396436,.047186,0,0],[2.396529,.045013,0,0],[2.396613,.042939,0,0],[2.396691,.040959,0,0],[2.396761,.039069,0,0],[2.396825,.037266,0,0],[2.396883,.035544,0,0],[2.396936,.033901,0,0],[2.396984,.032334,0,0],[2.397028,.030838,0,0],[2.397068,.02941,0,0],[2.397104,.028048,0,0],[2.397137,.026749,0,0],[2.397167,.025509,0,0],[2.397194,.024326,0,0],[2.397219,.023198,0,0],[2.397242,.022122,0,0],[2.397262,.021095,0,0],[2.397281,.020116,0,0],[2.397298,.019181,0,0],[2.397314,.01829,0,0],[2.397328,.017441,0,0],[2.397341,.01663,0,0],[2.397352,.015857,0,0],[2.397363,.015119,0,0],[2.397372,.014416,0,0],[2.397381,.013745,0,0],[2.397389,.013106,0,0],[2.397396,.012496,0,0],[2.397403,.011914,0,0],[2.397409,.01136,0,0],[2.397414,.010831,0,0],[2.397419,.010326,0,0],[2.397424,.009845,0,0],[2.397428,.009387,0,0],[2.397432,.008949,0,0],[2.397435,.008532,0,0],[2.397438,.008135,0,0],[2.397441,.007755,0,0],[2.397443,.007394,0,0],[2.397446,.007049,0,0],[2.397448,.006721,0,0],[2.39745,.006407,0,0],[2.397451,.006108,0,0],[2.397453,.005824,0,0],[2.397454,.005552,0,0],[2.397456,.005293,0,0],[2.397457,.005046,0,0],[2.397458,.004811,0,0],[2.397459,.004586,0,0],[2.39746,.004372,0,0],[2.397461,.004168,0,0],[2.397461,.003974,0,0],[2.397462,.003788,0,0],[2.397463,.003611,0,0],[2.397463,.003443,0,0],[2.397464,.003282,0,0],[2.397464,.003129,0,0],[2.397465,.002983,0,0],[2.397465,.002844,0,0],[2.397465,.002711,0,0],[2.397466,.002584,0,0],[2.397466,.002464,0,0],[2.397466,.002349,0,0],[2.397466,.002239,0,0],[2.397467,.002135,0,0],[2.397467,.002035,0,0],[2.397467,.00194,0,0],[2.397467,.001849,0,0],[2.397467,.001763,0,0],[2.397467,.001681,0,0],[2.397468,.001602,0,0],[2.397468,.001527,0,0],[2.397468,.001456,0,0],[2.397468,.001388,0,0],[2.397468,.001323,0,0],[2.397468,.001261,0,0],[2.397468,.001202,0,0],[2.397468,.001146,0,0],[2.397468,.001093,0,0],[2.397468,.001042,0,0],[2.397468,993e-6,0,0],[2.397468,947e-6,0,0],[2.397468,902e-6,0,0],[2.397468,86e-5,0,0],[2.397468,82e-5,0,0],[2.397469,782e-6,0,0],[2.397469,745e-6,0,0],[2.397469,71e-5,0,0],[2.397469,677e-6,0,0],[2.397469,646e-6,0,0],[2.397469,616e-6,0,0],[2.397469,587e-6,0,0],[2.397469,559e-6,0,0],[2.397469,533e-6,0,0],[2.397469,508e-6,0,0],[2.397469,485e-6,0,0],[2.397469,462e-6,0,0],[2.397469,44e-5,0,0],[2.397469,42e-5,0,0],[2.397469,4e-4,0,0],[2.397469,381e-6,0,0],[2.397469,364e-6,0,0],[2.397469,347e-6,0,0],[2.397469,33e-5,0,0],[2.397469,315e-6,0,0],[2.397469,3e-4,0,0],[2.397469,286e-6,0,0],[2.397469,273e-6,0,0],[2.397469,26e-5,0,0],[2.397469,248e-6,0,0],[2.397469,236e-6,0,0],[2.397469,225e-6,0,0],[2.397469,215e-6,0,0],[2.397469,205e-6,0,0],[2.397469,195e-6,0,0],[2.397469,186e-6,0,0],[2.397469,177e-6,0,0],[2.397469,169e-6,0,0],[2.397469,161e-6,0,0],[2.397469,154e-6,0,0],[2.397469,147e-6,0,0],[2.397469,14e-5,0,0],[2.397469,133e-6,0,0],[2.397469,127e-6,0,0],[2.397469,121e-6,0,0],[2.397469,115e-6,0,0],[2.397469,11e-5,0,0],[2.397469,105e-6,0,0],[2.397469,1e-4,0,0],[2.397469,95e-6,0,0],[2.397469,91e-6,0,0],[2.397469,87e-6,0,0],[2.397469,83e-6,0,0],[2.397469,79e-6,0,0],[2.397469,75e-6,0,0],[2.397469,71e-6,0,0],[2.397469,68e-6,0,0],[2.397469,65e-6,0,0],[2.397469,62e-6,0,0],[2.397469,59e-6,0,0],[2.397469,56e-6,0,0],[2.397469,54e-6,0,0],[2.397469,51e-6,0,0],[2.397469,49e-6,0,0],[2.397469,46e-6,0,0],[2.397469,44e-6,0,0],[2.397469,42e-6,0,0],[2.397469,4e-5,0,0],[2.397469,38e-6,0,0],[2.397469,37e-6,0,0],[2.397469,35e-6,0,0],[2.397469,33e-6,0,0],[2.397469,32e-6,0,0],[2.397469,3e-5,0,0],[2.397469,29e-6,0,0],[2.397469,27e-6,0,0],[2.397469,26e-6,0,0],[2.397469,25e-6,0,0],[2.397469,24e-6,0,0],[2.397469,23e-6,0,0],[2.397469,22e-6,0,0],[2.397469,21e-6,0,0],[2.397469,2e-5,0,0],[2.397469,19e-6,0,0],[2.397469,18e-6,0,0],[2.397469,17e-6,0,0],[2.397469,16e-6,0,0],[2.397469,15e-6,0,0],[2.397469,15e-6,0,0],[2.397469,14e-6,0,0],[2.397469,13e-6,0,0],[2.397469,13e-6,0,0],[2.397469,12e-6,0,0],[2.397469,12e-6,0,0],[2.397469,11e-6,0,0],[2.397469,11e-6,0,0],[2.397469,1e-5,0,0],[2.397469,1e-5,0,0],[2.397469,9e-6,0,0],[2.397469,9e-6,0,0],[2.397469,8e-6,0,0],[2.397469,8e-6,0,0],[2.397469,8e-6,0,0],[2.397469,7e-6,0,0],[2.397469,7e-6,0,0],[2.397469,7e-6,0,0],[2.397469,6e-6,0,0],[2.397469,6e-6,0,0],[2.397469,6e-6,0,0],[2.397469,5e-6,0,0],[2.397469,5e-6,0,0],[2.397469,5e-6,0,0],[2.397469,5e-6,0,0],[2.397469,4e-6,0,0],[2.397469,4e-6,0,0],[2.397469,4e-6,0,0],[2.397469,4e-6,0,0],[2.397469,4e-6,0,0],[2.397469,4e-6,0,0],[2.397469,3e-6,0,0],[2.397469,3e-6,0,0],[2.397469,3e-6,0,0],[2.397469,3e-6,0,0],[2.397469,3e-6,0,0],[2.397469,3e-6,0,0],[2.397469,3e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,2e-6,0,0],[2.397469,1e-6,0,0],[2.397469,1e-6,0,0],[2.397469,1e-6,0,0]],t.MAX_RE_WEIGHTS_RESOLUTION=t.MAX_RE_WEIGHTS.length},function(A,t,e){"use strict";function i(A,t){void 0==t&&(t={}),void 0==t.position&&(t.position=a.DEFAULT_POSITION.slice()),void 0==t.forward&&(t.forward=a.DEFAULT_FORWARD.slice()),void 0==t.up&&(t.up=a.DEFAULT_UP.slice()),void 0==t.minDistance&&(t.minDistance=a.DEFAULT_MIN_DISTANCE),void 0==t.maxDistance&&(t.maxDistance=a.DEFAULT_MAX_DISTANCE),void 0==t.rolloff&&(t.rolloff=a.DEFAULT_ROLLOFF),void 0==t.gain&&(t.gain=a.DEFAULT_SOURCE_GAIN),void 0==t.alpha&&(t.alpha=a.DEFAULT_DIRECTIVITY_ALPHA),void 0==t.sharpness&&(t.sharpness=a.DEFAULT_DIRECTIVITY_SHARPNESS),void 0==t.sourceWidth&&(t.sourceWidth=a.DEFAULT_SOURCE_WIDTH),this._scene=A,this._position=t.position,this._forward=t.forward,this._up=t.up,this._dx=new Float32Array(3),this._right=a.crossProduct(this._forward,this._up);let e=A._context;this.input=e.createGain(),this._directivity=new s(e,{alpha:t.alpha,sharpness:t.sharpness}),this._toEarly=e.createGain(),this._toLate=e.createGain(),this._attenuation=new o(e,{minDistance:t.minDistance,maxDistance:t.maxDistance,rolloff:t.rolloff}),this._encoder=new r(e,{ambisonicOrder:A._ambisonicOrder,sourceWidth:t.sourceWidth}),this.input.connect(this._toLate),this._toLate.connect(A._room.late.input),this.input.connect(this._attenuation.input),this._attenuation.output.connect(this._toEarly),this._toEarly.connect(A._room.early.input),this._attenuation.output.connect(this._directivity.input),this._directivity.output.connect(this._encoder.input),this._encoder.output.connect(A._listener.input),this.setPosition(t.position[0],t.position[1],t.position[2]),this.input.gain.value=t.gain}function n(A){let t=1;return A>a.EPSILON_FLOAT&&(t=1-A/a.SOURCE_MAX_OUTSIDE_ROOM_DISTANCE,t=Math.max(0,Math.min(1,t))),t}/** + * @license + * Copyright 2017 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const s=e(5),o=e(6),r=e(1),a=e(0);i.prototype.setPosition=function(A,t,e){this._position[0]=A,this._position[1]=t,this._position[2]=e;let i=n(this._scene._room.getDistanceOutsideRoom(this._position[0],this._position[1],this._position[2]));this._toLate.gain.value=i,this._toEarly.gain.value=i,this._update()},i.prototype._update=function(){for(let i=0;i<3;i++)this._dx[i]=this._position[i]-this._scene._listener.position[i];let A=Math.sqrt(this._dx[0]*this._dx[0]+this._dx[1]*this._dx[1]+this._dx[2]*this._dx[2]);A>0&&(this._dx[0]/=A,this._dx[1]/=A,this._dx[2]/=A);let t=Math.atan2(-this._dx[0],this._dx[2])*a.RADIANS_TO_DEGREES,e=Math.atan2(this._dx[1],Math.sqrt(this._dx[0]*this._dx[0]+this._dx[2]*this._dx[2]))*a.RADIANS_TO_DEGREES;this._attenuation.setDistance(A),this._directivity.computeAngle(this._forward,this._dx),this._encoder.setDirection(t,e)},i.prototype.setRolloff=function(A){this._attenuation.setRolloff(A)},i.prototype.setMinDistance=function(A){this._attenuation.minDistance=A},i.prototype.setMaxDistance=function(A){this._attenuation.maxDistance=A},i.prototype.setGain=function(A){this.input.gain.value=A},i.prototype.setOrientation=function(A,t,e,i,n,s){this._forward[0]=A,this._forward[1]=t,this._forward[2]=e,this._up[0]=i,this._up[1]=n,this._up[2]=s,this._right=a.crossProduct(this._forward,this._up)},i.prototype.setFromMatrix=function(A){this._right[0]=A.elements[0],this._right[1]=A.elements[1],this._right[2]=A.elements[2],this._up[0]=A.elements[4],this._up[1]=A.elements[5],this._up[2]=A.elements[6],this._forward[0]=A.elements[8],this._forward[1]=A.elements[9],this._forward[2]=A.elements[10],this._right=a.normalizeVector(this._right),this._up=a.normalizeVector(this._up),this._forward=a.normalizeVector(this._forward),this.setPosition(A.elements[12],A.elements[13],A.elements[14])},i.prototype.setSourceWidth=function(A){this._encoder.setSourceWidth(A),this.setPosition(this._position[0],this._position[1],this._position[2])},i.prototype.setDirectivityPattern=function(A,t){this._directivity.setPattern(A,t),this.setPosition(this._position[0],this._position[1],this._position[2])},A.exports=i},function(A,t,e){"use strict";function i(A,t){void 0==t&&(t={}),void 0==t.alpha&&(t.alpha=n.DEFAULT_DIRECTIVITY_ALPHA),void 0==t.sharpness&&(t.sharpness=n.DEFAULT_DIRECTIVITY_SHARPNESS),this._context=A,this._lowpass=A.createBiquadFilter(),this._lowpass.type="lowpass",this._lowpass.Q.value=0,this._lowpass.frequency.value=.5*A.sampleRate,this._cosTheta=0,this.setPattern(t.alpha,t.sharpness),this.input=this._lowpass,this.output=this._lowpass}/** + * @license + * Copyright 2017 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const n=e(0);i.prototype.computeAngle=function(A,t){let e=n.normalizeVector(A),i=n.normalizeVector(t),s=1;if(this._alpha>n.EPSILON_FLOAT){let A=e[0]*i[0]+e[1]*i[1]+e[2]*i[2];s=1-this._alpha+this._alpha*A,s=Math.pow(Math.abs(s),this._sharpness)}this._lowpass.frequency.value=.5*this._context.sampleRate*s},i.prototype.setPattern=function(A,t){this._alpha=Math.min(1,Math.max(0,A)),this._sharpness=Math.max(1,t),this.computeAngle([this._cosTheta*this._cosTheta,0,0],[1,0,0])},A.exports=i},function(A,t,e){"use strict";function i(A,t){void 0==t&&(t={}),void 0==t.minDistance&&(t.minDistance=n.DEFAULT_MIN_DISTANCE),void 0==t.maxDistance&&(t.maxDistance=n.DEFAULT_MAX_DISTANCE),void 0==t.rolloff&&(t.rolloff=n.DEFAULT_ATTENUATION_ROLLOFF),this.minDistance=t.minDistance,this.maxDistance=t.maxDistance,this.setRolloff(t.rolloff),this._gainNode=A.createGain(),this.setDistance(t.maxDistance),this.input=this._gainNode,this.output=this._gainNode}/** + * @license + * Copyright 2017 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const n=e(0);i.prototype.setDistance=function(A){let t=1;if("logarithmic"==this._rolloff){if(A>this.maxDistance)t=0;else if(A>this.minDistance){let e=this.maxDistance-this.minDistance;if(e>n.EPSILON_FLOAT){let i=1/(e+1);t=(1/(A-this.minDistance+1)-i)/(1-i)}}}else if("linear"==this._rolloff)if(A>this.maxDistance)t=0;else if(A>this.minDistance){let e=this.maxDistance-this.minDistance;e>n.EPSILON_FLOAT&&(t=(this.maxDistance-A)/e)}this._gainNode.gain.value=t},i.prototype.setRolloff=function(A){let t=~n.ATTENUATION_ROLLOFFS.indexOf(A);void 0!=A&&t?A=A.toString().toLowerCase():(t||n.log('Invalid rolloff model ("'+A+'"). Using default: "'+n.DEFAULT_ATTENUATION_ROLLOFF+'".'),A=n.DEFAULT_ATTENUATION_ROLLOFF),this._rolloff=A},A.exports=i},function(A,t,e){"use strict";function i(A){let t={};for(let e in _.DEFAULT_ROOM_MATERIALS)_.DEFAULT_ROOM_MATERIALS.hasOwnProperty(e)&&(t[e]=_.ROOM_MATERIAL_COEFFICIENTS[_.DEFAULT_ROOM_MATERIALS[e]]);void 0==A&&(A={},Object.assign(A,_.DEFAULT_ROOM_MATERIALS));for(let e in _.DEFAULT_ROOM_MATERIALS)_.DEFAULT_ROOM_MATERIALS.hasOwnProperty(e)&&A.hasOwnProperty(e)?A[e]in _.ROOM_MATERIAL_COEFFICIENTS?t[e]=_.ROOM_MATERIAL_COEFFICIENTS[A[e]]:_.log('Material "'+A[e]+'" on wall "'+e+'" not found. Using "'+_.DEFAULT_ROOM_MATERIALS[e]+'".'):_.log('Wall "'+e+'" is not defined. Default used.');return t}function n(A){void 0==A&&(A={});for(let t in _.DEFAULT_ROOM_MATERIALS)A.hasOwnProperty(t)||(A[t]=_.ROOM_MATERIAL_COEFFICIENTS[_.DEFAULT_ROOM_MATERIALS[t]]);return A}function s(A){void 0==A&&(A={});for(let t in _.DEFAULT_ROOM_DIMENSIONS)A.hasOwnProperty(t)||(A[t]=_.DEFAULT_ROOM_DIMENSIONS[t]);return A}function o(A,t,e){let i=new Float32Array(_.NUMBER_REVERB_FREQUENCY_BANDS);A=s(A),t=n(t),void 0==e&&(e=_.DEFAULT_SPEED_OF_SOUND);let o=_.TWENTY_FOUR_LOG10/e,r=A.width*A.height*A.depth;if(r<_.ROOM_MIN_VOLUME)return i;let a=A.width*A.height,h=A.width*A.depth,c=A.depth*A.height,f=2*(a+h+c);for(let n=0;n<_.NUMBER_REVERB_FREQUENCY_BANDS;n++){let A=((t.left[n]+t.right[n])*a+(t.down[n]+t.up[n])*h+(t.front[n]+t.back[n])*c)/f;i[n]=_.ROOM_EYRING_CORRECTION_COEFFICIENT*o*r/(-f*Math.log(1-A)+4*_.ROOM_AIR_ABSORPTION_COEFFICIENTS[n]*r)}return i}function r(A){let t=[];for(let e in _.DEFAULT_REFLECTION_COEFFICIENTS)if(_.DEFAULT_REFLECTION_COEFFICIENTS.hasOwnProperty(e)){t[e]=0;for(let i=0;i<_.NUMBER_REFLECTION_AVERAGING_BANDS;i++){let n=i+_.ROOM_STARTING_AVERAGING_BAND;t[e]+=A[e][n]}t[e]/=_.NUMBER_REFLECTION_AVERAGING_BANDS,t[e]=Math.sqrt(1-t[e])}return t}function a(A,t){void 0==t&&(t={}),void 0==t.listenerPosition&&(t.listenerPosition=_.DEFAULT_POSITION.slice()),void 0==t.dimensions&&(t.dimensions={},Object.assign(t.dimensions,_.DEFAULT_ROOM_DIMENSIONS)),void 0==t.materials&&(t.materials={},Object.assign(t.materials,_.DEFAULT_ROOM_MATERIALS)),void 0==t.speedOfSound&&(t.speedOfSound=_.DEFAULT_SPEED_OF_SOUND),t.dimensions=s(t.dimensions);let e=i(t.materials),n=r(e),a=o(t.dimensions,e,t.speedOfSound);this.early=new c(A,{dimensions:t.dimensions,coefficients:n,speedOfSound:t.speedOfSound,listenerPosition:t.listenerPosition}),this.late=new h(A,{durations:a}),this.speedOfSound=t.speedOfSound,this.output=A.createGain(),this.early.output.connect(this.output),this._merger=A.createChannelMerger(4),this.late.output.connect(this._merger,0,0),this._merger.connect(this.output)}/** + * @license + * Copyright 2017 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const h=e(8),c=e(9),_=e(0);a.prototype.setProperties=function(A,t){let e=i(t),n=o(A,e,this.speedOfSound);this.late.setDurations(n),this.early.speedOfSound=this.speedOfSound;let s=r(e);this.early.setRoomProperties(A,s)},a.prototype.setListenerPosition=function(A,t,e){this.early.speedOfSound=this.speedOfSound,this.early.setListenerPosition(A,t,e);let i=this.getDistanceOutsideRoom(A,t,e),n=1;i>_.EPSILON_FLOAT&&(n=1-i/_.LISTENER_MAX_OUTSIDE_ROOM_DISTANCE,n=Math.max(0,Math.min(1,n))),this.output.gain.value=n},a.prototype.getDistanceOutsideRoom=function(A,t,e){let i=Math.max(0,-this.early._halfDimensions.width-A,A-this.early._halfDimensions.width),n=Math.max(0,-this.early._halfDimensions.height-t,t-this.early._halfDimensions.height),s=Math.max(0,-this.early._halfDimensions.depth-e,e-this.early._halfDimensions.depth);return Math.sqrt(i*i+n*n+s*s)},A.exports=a},function(A,t,e){"use strict";function i(A,t){void 0==t&&(t={}),void 0==t.durations&&(t.durations=n.DEFAULT_REVERB_DURATIONS.slice()),void 0==t.predelay&&(t.predelay=n.DEFAULT_REVERB_PREDELAY),void 0==t.gain&&(t.gain=n.DEFAULT_REVERB_GAIN),void 0==t.bandwidth&&(t.bandwidth=n.DEFAULT_REVERB_BANDWIDTH),void 0==t.tailonset&&(t.tailonset=n.DEFAULT_REVERB_TAIL_ONSET);let e=t.predelay/1e3;this._bandwidthCoeff=t.bandwidth*n.LOG2_DIV2,this._tailonsetSamples=t.tailonset/1e3,this._context=A,this.input=A.createGain(),this._predelay=A.createDelay(e),this._convolver=A.createConvolver(),this.output=A.createGain(),this.output.gain.value=t.gain,this._convolver.normalize=!1,this.input.connect(this._predelay),this._predelay.connect(this._convolver),this._convolver.connect(this.output),this.setDurations(t.durations)}/** + * @license + * Copyright 2017 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const n=e(0);i.prototype.setDurations=function(A){if(A.length!==n.NUMBER_REVERB_FREQUENCY_BANDS)return void n.log("Warning: invalid number of RT60 values provided to reverb.");let t=new Float32Array(n.NUMBER_REVERB_FREQUENCY_BANDS),e=this._context.sampleRate;for(let h=0;hi&&(i=t[n]);i<1&&(i=1);let s=this._context.createBuffer(1,i,e),o=s.getChannelData(0),r=new Float32Array(i);for(let n=0;n32&&t.throw("Utils.mergeBuffer: Number of channels cannot exceed 32.(got "+s+")"),i!==e[a].length&&t.throw("Utils.mergeBuffer: AudioBuffer lengths are inconsistent. (expected "+i+" but got "+e[a].length+")"),n!==e[a].sampleRate&&t.throw("Utils.mergeBuffer: AudioBuffer sample rates are inconsistent. (expected "+n+" but got "+e[a].sampleRate+")"),s+=e[a].numberOfChannels;const o=A.createBuffer(s,i,n);let r=0;for(let t=0;te[i]=t.charCodeAt(i)),e.buffer}},function(A,t,e){"use strict";function i(A,t,e){this._context=n.isAudioContext(A)?A:n.throw("BufferList: Invalid BaseAudioContext."),this._options={dataType:s.BASE64,verbose:!1},e&&(e.dataType&&n.isDefinedENUMEntry(s,e.dataType)&&(this._options.dataType=e.dataType),e.verbose&&(this._options.verbose=Boolean(e.verbose))),this._bufferList=[],this._bufferData=this._options.dataType===s.BASE64?t:t.slice(0),this._numberOfTasks=this._bufferData.length,this._resolveHandler=null,this._rejectHandler=new Function}const n=e(0),s={BASE64:"base64",URL:"url"};i.prototype.load=function(){return new Promise(this._promiseGenerator.bind(this))},i.prototype._promiseGenerator=function(A,t){"function"!=typeof A?n.throw("BufferList: Invalid Promise resolver."):this._resolveHandler=A,"function"==typeof t&&(this._rejectHandler=t);for(let e=0;e=0?this._stereoSplitters[i].connect(this._positiveIndexSphericalHarmonics,e%2):this._stereoSplitters[i].connect(this._negativeIndexSphericalHarmonics,e%2)}this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,1),this._negativeIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._negativeIndexSphericalHarmonics.connect(this._inverter),this._inverter.connect(this._binauralMerger,0,1),this._inverter.gain.value=-1,this.input=this._inputSplitter,this.output=this._outputGain},i.prototype.setHRIRBufferList=function(A){if(!this._isBufferLoaded){for(let t=0;t0){const s=i(t,1);return o(A,1,t-1,e,n)*Math.sqrt(1+s)-o(A,-1,1-t,e,n)*(1-s)}{const s=i(t,-1);return o(A,1,t+1,e,n)*(1-s)+o(A,-1,-t-1,e,n)*Math.sqrt(1+s)}}function h(A,t,e,i){return 0===t?0:t>0?o(A,1,t+1,e,i)+o(A,-1,-t-1,e,i):o(A,1,t-1,e,i)-o(A,-1,1-t,e,i)}function c(A,t,e){const n=i(A,0),s=Math.abs(t)===e?1/(2*e*(2*e-1)):1/((e+t)*(e-t));return[Math.sqrt((e+A)*(e-A)*s),.5*(1-2*n)*Math.sqrt((1+n)*(e+Math.abs(A)-1)*(e+Math.abs(A))*s),-.5*(1-n)*Math.sqrt((e-Math.abs(A)-1)*(e-Math.abs(A)))*s]}function _(A,t){for(let e=-t;e<=t;e++)for(let i=-t;i<=t;i++){const s=c(e,i,t);Math.abs(s[0])>0&&(s[0]*=r(A,e,i,t)),Math.abs(s[1])>0&&(s[1]*=a(A,e,i,t)),Math.abs(s[2])>0&&(s[2]*=h(A,e,i,t)),n(A,t,e,i,s[0]+s[1]+s[2])}}function f(A){for(let t=2;t<=A.length;t++)_(A,t)}function l(A,t){this._context=A,this._ambisonicOrder=t;const e=(t+1)*(t+1);this._splitter=this._context.createChannelSplitter(e),this._merger=this._context.createChannelMerger(e),this._gainNodeMatrix=[];let i,n,s,o,r;for(let a=1;a<=t;a++){i=a*a,n=2*a+1,this._gainNodeMatrix[a-1]=[];for(let A=0;A ["+A+"])"),this._audioElementSource=this._context.createMediaElementSource(this._videoElement),this._foaRouter=new s(this._context,this._channelMap),this._foaRotator=new o(this._context),this._foaPhaseMatchedFilter=new r(this._context),this._audioElementSource.connect(this._foaRouter.input),this._foaRouter.output.connect(this._foaRotator.input),this._foaRotator.output.connect(this._foaPhaseMatchedFilter.input),this._foaVirtualSpeakers=[],this._bypass=this._context.createGain(),this._audioElementSource.connect(this._bypass);const e=Math.pow(10,this._postGainDB/20);c.log("Gain compensation: "+e+" ("+this._postGainDB+"dB)");const i=this;return new Promise(function(A,t){new n(i._context,i._speakerData,function(t){for(let A=0;A ["+A.toString()+"])."),this._config.channelMap=A.slice(),this._foaRouter.setChannelMap(this._config.channelMap))},i.prototype.setRotationMatrix3=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix3(A)},i.prototype.setRotationMatrix4=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix4(A)},i.prototype.setRotationMatrixFromCamera=function(A){this._isRendererReady&&(h.invertMatrix4(this._tempMatrix4,A.elements),this._foaRotator.setRotationMatrix4(this._tempMatrix4))},i.prototype.setRenderingMode=function(A){if(A!==this._config.renderingMode){switch(A){case c.AMBISONIC:this._foaConvolver.enable(),this._bypass.disconnect();break;case c.BYPASS:this._foaConvolver.disable(),this._bypass.connect(this.output);break;case c.OFF:this._foaConvolver.disable(),this._bypass.disconnect();break;default:return void h.log('FOARenderer: Rendering mode "'+A+'" is not supported.')}this._config.renderingMode=A,h.log("FOARenderer: Rendering mode changed. ("+A+")")}},A.exports=i},function(A,t){A.exports=["UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+/wIA9v8QAPv/CwD+/wcA/v8MAP//AQD7/wEACAAEAPj/+v8YABAA7v/n//v/9P/M/8D//f34/R38EvzxAfEBtA2lDTcBJQFJ9T71FP0D/cD1tfVo/Wv9uPTO9PPmOufc/U/+agL3Aisc/RxuGKEZBv3j/iYMzQ2gAzsEQQUABiQFrASzA5cB2QmyCy0AtgR4AeYGtfgAA2j5OQHP+scArPsMBJgEggIEBtz6+QVq/pj/aPg8BPP3gQEi+jEAof0fA1v9+/7S+8IBjvwd/xD4IADL/Pf9zvs+/l3+wgB7/+L+7fzFADH9kf6A+n3+DP6+/TP9xP68/pn+w/26/i39YgA0/u790Pt9/kD+7v1s/Wb+8f4C/1P+pf/x/cT+6/3p/Xz9ff5F/0f9G/4r/6v/4P5L/sL+ff7c/pj+Ov7X/UT+9P5G/oz+6v6A/2D+9/6P/8r/bP7m/ij+C//e/tj/Gf4e/9v+FwDP/lz/sP7F/2H+rv/G/s7/Hf7y/4P+NAD9/k0AK/6w/zP/hACh/sX/gf44AOP+dgCm/iUAk/5qAOD+PwC+/jEAWP4CAAr/bQBw/vv/zf5iACD/OgCS/uD/Cv9oAAb/CgDK/kwA//5tACH/TgCg/h4AHP9aABP/JADP/hEAYv9gAAj/3f8m/ysAYv8gACX/8/8k/ysAXv8bABH//v8j/ygAa/8qAAD/9f9g/1YAWf8JACH/AgB2/z4AXP/w/z3/FgB2/ykAX//9/z//EwCV/zUAS//n/1T/GACK/x4ATv/0/4P/QQB4//v/WP/2/3X/HAB8//P/V//3/2f/AQBh/9v/Tf/x/5P/IwCI/wMAf/8hAKP/JACZ/xUAiv8nAK//HgCr/yMAm/8uAMz/OACi/yQAqf87AMT/MwCY/yUAtP9FAMH/KgCu/ycAyP85AMv/IwCz/xoA1f8qAMn/FgC8/xQA4/8nAMX/CwDJ/xQA4f8ZAMH/BgDO/xQA4f8WAMP/BwDU/xQA4P8QAMH/AQDb/xQA3P8JAMP/AgDh/xIA2v8EAMj/AgDk/w0A1f/+/8v/AwDm/wwA0v/+/9H/BgDl/wkAzv/8/9T/BwDk/wcAzv/8/9r/CQDi/wQAzf/8/9//CADf////0P/9/+L/BwDd//7/0////+T/BgDb//z/1f8AAOf/BQDZ//v/2v8CAOb/AwDY//v/3v8EAOb/AgDY//3/4f8FAOX/AQDZ//7/5P8GAOP/AADb/wAA5/8GAOH////d/wIA5/8FAOD////f/wMA6P8FAOD////h/wQA6P8EAN7////h/wUA4v8DANv/AQDd/wQA3P8CANn/AgDb/wMA2/8CANv/AgDd/wIA3v8CAOH/AQDj/wEA","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAAAAAAA/f8CAP//AQD//wEA//8BAP3/AAACAP7/+f8AAAIA/P8FAAQA8/8AABoA+f/V/wQAHQDO/xoAQQBO/ocA0Px1/ucHW/4UCm8HLO6kAjv8/fCRDdAAYfPiBIgFXveUCM0GBvh6/nz7rf0J/QcQSRVdBgoBSgFR62r9NP8m+LoEAvriBVAAiAPmABEGMf2l+SwBjva6/G4A//8P/CYDMgXm/R0CKAE6/fcBBwAtAND+kQA0A5UDhwFs/8IB8fydAEP/A/8v/e7/mP8j/2YBIwE3Av0AYv+uAOD8lgAg/wwAIf/L/n0Ae//OAJMB3P/XAF//XwCM/08AB/8NAEf/rf4jAT3/lgAJAP4AHgDpAO8AUf9L/07/Qf8KAOD/x/+D/3sATQCDAMoA0f79/+L/EQDt/7EAqv+S/7IAuv/o/wgAc//X//H/SwCm/+3/Yf/B/yoAAADI/7X/AwBg/5EATgCX/xYA/P+q/00AVACY/6v/BADD/zwALQCN/8z/KQDu/ygAEgCZ/6f/VQDC//T/KQCs/7P/UgAfAO7/NgC8/57/awAZAPP/+P/V/8z/bQBBAL//DgD0/+T/TABBAMz/CwAxAPz/SQBqALn/BgALAPz/EAA7AIz/3/8iAAUA//8kALf/y/9VABQA+v81AOj/0P9cAB4A+f8WAOr/vv83ABgAw/8JAOj/4f8nACIAsf/y/w4A3v8gACQAxP/n/ycA7P8WAC0Ayf/U/ycA9v/7/yUA0P/P/zUABADc/xUA5P/J/zcACwDS/xUA9P/m/zAACQDX/+3/9v/2/yQACgDZ/+P/AwAKABYA///b/9j/EQALABkADgD6/+7/GwD4/w4A8P/w//j/EgAEAAUA9f/1/wQAGgD4/wAA5////wAAGQD1////7f8FAAUAFQDv/wAA6v8LAAcAFQDs/wEA9P8SAAYACwDr//7/AQASAAYABQDv/wIAAwAWAAIAAgDv/wAABgATAAEA/f/u/wQABgAQAPr/+P/z/wUACQALAPj/9//4/wgABwAKAPT/+f/5/w4ABwAIAPT/+//9/w4AAwADAPH//f///w8A//8BAPP///8BAA0A/f/+//X/AgACAA0A+//8//b/BAADAAoA+f/7//n/BgADAAcA+P/7//v/BwABAAQA+P/8//3/CQABAAIA9//9////CQD/////+P///wAACAD9//7/+f8AAAAABwD8//3/+v8CAAAABgD7//z//P8EAAAABAD6//3//P8FAP//AgD6//7//v8FAP7/AQD7//////8GAP7/AAD7/wEA//8EAP3/AAD9/wEA/v8DAP3/AAD9/wIA/v8CAP3/AQD9/wIA/v8CAP7/AQD+/wEA"]},function(A,t,e){"use strict";function i(A,t){this._context=h.isAudioContext(A)?A:h.throw("HOARenderer: Invalid BaseAudioContext."),this._config={ambisonicOrder:3,renderingMode:c.AMBISONIC},t&&t.ambisonicOrder&&(_.includes(t.ambisonicOrder)?this._config.ambisonicOrder=t.ambisonicOrder:h.log("HOARenderer: Invalid ambisonic order. (got "+t.ambisonicOrder+") Fallbacks to 3rd-order ambisonic.")),this._config.numberOfChannels=(this._config.ambisonicOrder+1)*(this._config.ambisonicOrder+1),this._config.numberOfStereoChannels=Math.ceil(this._config.numberOfChannels/2),t&&t.hrirPathList&&(Array.isArray(t.hrirPathList)&&t.hrirPathList.length===this._config.numberOfStereoChannels?this._config.pathList=t.hrirPathList:h.throw("HOARenderer: Invalid HRIR URLs. It must be an array with "+this._config.numberOfStereoChannels+" URLs to HRIR files. (got "+t.hrirPathList+")")),t&&t.renderingMode&&(Object.values(c).includes(t.renderingMode)?this._config.renderingMode=t.renderingMode:h.log("HOARenderer: Invalid rendering mode. (got "+t.renderingMode+') Fallbacks to "ambisonic".')),this._buildAudioGraph(),this._isRendererReady=!1}const n=e(1),s=e(8),o=e(9),r=e(17),a=e(18),h=e(0),c={AMBISONIC:"ambisonic",BYPASS:"bypass",OFF:"off"},_=[2,3];i.prototype._buildAudioGraph=function(){this.input=this._context.createGain(),this.output=this._context.createGain(),this._bypass=this._context.createGain(),this._hoaRotator=new o(this._context,this._config.ambisonicOrder),this._hoaConvolver=new s(this._context,this._config.ambisonicOrder),this.input.connect(this._hoaRotator.input),this.input.connect(this._bypass),this._hoaRotator.output.connect(this._hoaConvolver.input),this._hoaConvolver.output.connect(this.output),this.input.channelCount=this._config.numberOfChannels,this.input.channelCountMode="explicit",this.input.channelInterpretation="discrete"},i.prototype._initializeCallback=function(A,t){let e;(e=this._config.pathList?new n(this._context,this._config.pathList,{dataType:"url"}):2===this._config.ambisonicOrder?new n(this._context,a):new n(this._context,r)).load().then(function(t){this._hoaConvolver.setHRIRBufferList(t),this.setRenderingMode(this._config.renderingMode),this._isRendererReady=!0,h.log("HOARenderer: HRIRs loaded successfully. Ready."),A()}.bind(this),function(){const A="HOARenderer: HRIR loading/decoding failed.";h.throw(A),t(A)})},i.prototype.initialize=function(){return h.log("HOARenderer: Initializing... (mode: "+this._config.renderingMode+", ambisonic order: "+this._config.ambisonicOrder+")"),new Promise(this._initializeCallback.bind(this),function(A){h.throw("HOARenderer: Initialization failed. ("+A+")")})},i.prototype.setRotationMatrix3=function(A){this._isRendererReady&&this._hoaRotator.setRotationMatrix3(A)},i.prototype.setRotationMatrix4=function(A){this._isRendererReady&&this._hoaRotator.setRotationMatrix4(A)},i.prototype.setRenderingMode=function(A){if(A!==this._config.renderingMode){switch(A){case c.AMBISONIC:this._hoaConvolver.enable(),this._bypass.disconnect();break;case c.BYPASS:this._hoaConvolver.disable(),this._bypass.connect(this.output);break;case c.OFF:this._hoaConvolver.disable(),this._bypass.disconnect();break;default:return void h.log('HOARenderer: Rendering mode "'+A+'" is not supported.')}this._config.renderingMode=A,h.log("HOARenderer: Rendering mode changed. ("+A+")")}},A.exports=i},function(A,t){A.exports=["UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+/wQA8/8YAP3/CgACAAAA//8CAAYA8/8AAPH/CgDv/97/e/+y/9P+UQDwAHUBEwV7/pP8P/y09bsDwAfNBGYIFf/Y+736+fP890Hv8AGcC3T/vwYy+S70AAICA3AD4AagBw0R4w3ZEAcN8RVYAV8Q8P2z+kECHwdK/jIG0QNKAYUElf8IClj7BgjX+/f8j/l3/5f/6fkK+xz8FP0v/nj/Mf/n/FcBPfvH/1H3+gBP/Hf8cfiCAR/54QBh+UQAcvkzAWL8TP13+iD/V/73+wv9Kv+Y/hv+xPz7/UL83//a/z/9AP6R/5L+jf26/P3+rP26/tD8nP7B/Pv+WP1V/sP9gv91/3P9xP3J/nv/GP5S/sb+IP8v/9j/dv7U/pr+6v+u/Z3/sv5cAOr9Q/83/+n/zP5x/57+2//k/nwA/v01//L+SACB/sD/Ff81AJT+TgDp/ocAm/5dAFT+MgD+/pMAW/7o/yH/xQDA/kkA9P6LAL3+pAC0/iQAz/5UALD+UwAt/3UAhf4UAA//pwC+/joAz/5aAAv/fwDY/iMAIf+uAPP+ZAAc/0QAy/4xAB7/TgDs/goADP8wAEL/NwDo/ub/Uf9BAC3/+v9F/y4ARP9HAFP/EQA3/xMATP81AG3/HQAu/wgAaP9FACb/9f9B/y0AUP8rAED/CwBV/z4AW/8TAGH/BQBK/xsAfv8eAFn/AgB3/zwAff8RAGj//v+E/yAAb//0/3n/FwBz/xcAiv8PAHn/FQCJ/xgAg//x/3j/EQCa/ycAff/w/47/HwCI//X/iv/7/43/JQCM/+n/kP8AAJb/JACj//7/oP8ZAML/SwCo/w4Atv8tAMb/PACr/xcAwP9HAMP/OADF/y4A0f9IANL/NwC//zEA0f9LAMb/MAC8/y4A3f9GAMH/FQDQ/yYA2/8sAMT/AwDX/xkA3v8SAM3/9v/c/w8A4f8LAMj/8f/h/xQA2P8CAMn/8//j/xQA0v/7/9H//P/i/xEA0v/1/9L//f/j/w0A0f/x/9f//v/k/wgAz//u/9z/AwDg/wMA0P/v/9//BQDf////0v/y/+D/CADc//3/0v/2/+L/CgDa//r/1v/5/+T/CgDY//j/2f/9/+T/CADY//f/3P8AAOT/BwDY//f/4P8EAOP/BADZ//j/4v8GAOL/AwDa//r/5f8IAOH/AQDc//3/5v8JAOD//v/f////5v8IAOD//v/h/wIA5/8HAOD//f/j/wMA5/8GAOD//f/l/wYA5v8EAOD//v/m/wYA5f8CAOL////n/wYA5P8BAOH/AADl/wUA4f///+H/AQDk/wMA4f///+T/AQDm/wEA5////+r/AADt/wAA7/////P/AAD1////","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD//////v///wAAAAAAAAAAAQAAAAAA///9/wAABAD+//n/AgAJAAAA+v/+//f/DAAdAPv/+v+l/8L+jf/4/vgAdwVPAQACLQBo+Qj/Ev7o/N3/VgCbA08Bxf+L+yn9J/2HCU8FmgBvDe30Rv5h/LT09gi5CxkA5gOi8/30kwEM+4YJMf2nBmkJJAQQBLoFtvvv+m4A7PF6/R0Bif3qAuf8WARAAf4GyABG/BIAwvr4Acv8U//c/yIC8AEn/B8Daf2CAgMBAf3MAN38vgLK/UT/QwCyAPYClPyvAW/+pQAoASD+zP+R/IYC1f7C/nEBQP96AZb+1QAIAM//yQE7/tkAZ/7TAXL/w/8+AIsAtwB7/24A4v9a/z4A7v4iADb/dwCj/23/kgBOANUAIv8lAKEAxP9gAK7/BwCP/5kA7/9v/0wAzv9DAGT/3/9vAHv/6P+q/xUA7P8XAO//uv/g/2UAEgCV/wEATADM/+7/+//j/+D/9v/i//j/IgD+/xoAxf/6/z4A5/+8/9D/QwDq/+3/OQDT/zUAIgA/APP/PgAjAPD/BwAGACAADAC3//b/HAA3AN//RgDN/w8AIAACAN//GQBDACEAIwA+ACoAJQAeAPz/KgAYAPr/DgAEABYAIgAcAMT/7f8OAOL/5P/2//L/9P8GAPT/7v/8/+7/6v/t//z/AgAUAOL//P8VAAMA4/8IAPb/+P8MAAoA5v8NAAsA9v///wEAAAD9//n/9/8JAAYA7v/6/wMA+f8GAAEA7f/7/xgACAD4/w8A///3/w0A+f8BAAIA/P/5/xIA///9//r/7v/+/xYACQD///H/CwDz/wEADgAHAPP/FADn/+3/AQD5//f/AgD7/wEABwAMAAEADQD8//n/8f8OAPX/BAD+//X/+v8WAAQA+f8CAAEA7/8QAAEA/P8DAAUA9f8KAAwA9v8DAAUA+f8OAAoA9f/7/w0A+v8EAAgA8P/6/woA+//8/wkA+P/3/woA+//8/wcA9//1/woAAwD5/wcA/P/3/w0AAwD3/wEABAD2/wkABgD3/wEABQD3/wUABQD3//v/BwD3/wMABQD3//r/CQD7////BQD6//n/CQD9//3/BAD9//j/BwAAAPv/AwD///j/BwABAPn/AQABAPn/BQACAPn///8DAPr/AwADAPr//v8EAPv/AQADAPv//P8FAP3///8DAPz/+/8FAP7//f8CAP7/+/8EAP///P8BAP//+/8DAAEA+/8AAAEA+/8CAAIA+////wIA/f8AAAIA/P/+/wIA/f8AAAIA/f/9/wMA/////wEA///+/wIA/////wAAAAD+/wAAAAD/////AAD//wAA//8AAP//AAD//wAA","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD////////+//////8AAP////8AAP//AAAAAPz//f8IAAMA9////w4AAQD6/wwA8//+/y8Afv/0/2H/UP5gAbH+2QG1B2cAVAIh/l32FPyM/nACPQDV/+UEo/Q6AQwCu/oLD9kF8QJA/Uz+Wf2KCOcC+wUKBsL5aQBQ97rwOPiPAvn5CAl8AHEDkQPcAA8Bn/lIAdz7HQF1+xz9cAM4/94E4gDKAun+cgPYAYr9JgJr/bf+ivxz/MoBgv5UA8EBSgAQAJ7/UgEk/cQB7f63/sD/vf4XAhT/BQFCADYAnQGI/9EBtv3hALD/vP+c/3H/TgIN/1sBpf8yAP3/4f8qABr+1f8OAJ3/dwAGADEBnv9JAPz/IQBwAIH/jgAS/4wAsACTAOn/DQDCALn/ZQCSAAIAAwD1/9//jv9aADQA/v9EAB0AfgA8AAQACgB9APr/IAARAPT/5v9xACAABAAHAGUAt/89AC4ACgAjAMP/+v/9/xYA7f/1/+D/7P87AC0Auv8RAAcA9/8FAC8A2//y/xIAEwAaADQAJADp/zoAAgAfABIA2f/e/zUA+P/6/w4A9//A/zcA4//P//T/5f/R////EwDb/w4A8/8BABkANADh/xEA+f/0/wIAHADc//j/GwD1//f/GADs/+v/EAAAAPz/EgD3/+r/FgAMAAkAGAD9/+z/IQAQAPH/GQD3//z/CgAfAOX/AgD8//H/BAATAOv/+v///wIABAAdAOj/BQAPAAcAAQATAOz/8/8JAAkA6f8VAOv/+f8QABUA/v8OAO3/+P8KABUA9f8FAPv/5/8TAA0A7f8XAAkAAQAJABYA4/8WAAcACgANABEA7v8EAP7/AAD+/wMA9//7/xAAAQD8/wQA+f/7/wMABgDq/wAA+v/3/wYACQD1//3/BAD9/wgADgDw//r/AgD6/wEACADv//j/BQD///X/BwDu//j/AgACAPP/BAD2//n/BAAGAPb/BAD8//3/BQAJAPL/AwD+//3/BAAIAPP//f8DAPz/AAAGAPP/+/8CAP7//f8FAPX/+f8DAAAA/P8EAPf/+v8GAAMA+/8EAPv/+/8GAAQA+v8CAP///P8EAAUA+f8AAP///f8CAAUA+P///wEA/v8BAAUA+f/+/wIAAAD//wUA+v/9/wMAAQD9/wQA+//9/wMAAgD8/wMA/P/9/wMAAwD7/wEA/v/+/wIAAwD6/wEA///+/wAABAD6/wAAAQD//wAAAwD7////AQAAAP//AwD8//7/AgABAP3/AgD9//7/AQABAP3/AQD+//7/AAACAPz/AAD+//////8BAP3/AAD//wAA//8BAP7/AAD//wAA/v8AAP7/AAD//wAA//8AAP//","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD//////P/9//3//////wAAAAAAAAIAAgACAP//CAAEAEEA//+cAAUAb/8HAAH9+P9eARkAogQUAJn8BwCd/gX/+QQNAKoC9gFdAtb/b/vd/936TP/6AsD/nfqn/un1W/0dA8IEsQLvAJv2bP72+WMAkP8dAcX+nQO2AIr6bP/EABX+NgK/Bdj2IQv2AE4EUAiD/xQAnwIm/B0B/wGNAoH7sQaP/b8CiQakAqD+R/9xA477KQL//6r75v/O/pcCgQCtAiMCBQAkANAARwHf//39hgBl/kUAJgEtAUEATgA/AgoASADK/zUAJv29/vL+l/9c/0cAUwBBAE8A6QE5/87/Wv9NAOf+5v7P/5P/4/9BAKYAQwDD/zYB5v+r/zYATwAp/1v/WQAEAB0AhwA0AA0AIAA3AAEAzv/u/+//5v9m/zwAIADQ/8T/SABiANb/SwAbAFf/MQDX/7L/hP8TAPr/AgAMAAsAHwAZAI3/VgDC/9v/5//x/6P/AwBlAMv/yf82AB4A+P9WAPj/NwDi/1EA0v9JANj/JwAcAAEADABYANj/4f8MAEwAmP82AN//3P8UADYA7//6/wIACADU/ygAyv82AN7/9v/2/ygAxv/9/+3/5//n/zUA6//g/y4ADgD5/wsABwDv/xIADwAGACoAJQD3/zIA+/8FABsAFgDO/zAAHAAIABQALADp/xcACAAAAPH/GADs/wkACQAFAAgAFQDp/wIAHAD1//P/EQDw/+3/GAD9/+f/HAD8//T/DAAQAPH/HwD4//r/DwAPAOj/EQACAOn/DAAXAOX/BAAOANH/9/8MAO//9f8LANT/9f8EAO//6f8NANb/+P8KAOz/5v8MAOD/7f8UAO//7//+//7/9v8YAPj/9f/z/wsA+v8SAPD/+v/x/xYA+f8SAPb/9//3/xEABQACAPn/9//y/xQACQD///b//v/7/xIACQD9//H/AAD7/xEAAgD5//P/AwD9/w8AAgD3//D/BAD//wUA/v/0//D/BgADAAMA/P/2//f/BwAGAP7/+//2//j/CAAFAPv/+f/5//v/BwAHAPn/9//7//7/BQAFAPf/9//+/wEABAACAPf/+P8BAAIAAgAAAPj/9/8CAAMAAAD+//n/+f8EAAQA/v/8//r/+/8EAAMA/P/7//z//P8EAAIA/P/5//7//v8DAAEA+//5//////8CAAAA+//5/wEAAAABAP//+//6/wIAAQD///3//P/7/wMAAQD///3//f/9/wIAAQD9//3//v/9/wMAAQD9//z/AAD//wEAAAD9//z/AAAAAAAA///9//3/AAD//wAA/v////7/AAD//wAA////////AAD//wAA//8AAP//","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+////+f////v//v///wAA/////wUAAQAIAAIABwACAHkATAAOAaMAAf9C/9X6QvwhArAAtghABW37nv/y+0wAWQNcAE8JRwSOC6AEJe8P8S/zrPWaBI/+LQA/+0L+P/4K8AgAb/8uCh78BQtC614GaQWfAin5UfzN8Tf+GQizAZ4MCQMbGJ4BoRS7AvcHyQARA6n9ZwHZ/z4DvwAZAlAB6gbNAS4GFADFATL7E/2K+j37C/xp/SD9Uv0VAOsDs//WAd3+bv7F/f79mP2X/KH+FwC0/1n+VgFcATABHQGaAET+nf8Y/hoAovpqAXj9CQKW/lsCl/4RApj+bAHk/RcAlv4BAG/+DgDi//3/GwAOAEIAq/+y/3z/8v8+/7T/Tv8//27/mgDZ/1sA+P+cAAAA/P/i/yMAi/85AMP/KgDM/9MA9P+QABoA4QAiACwACwBdAP7/TQDb/y0Ayf+SAA0AZwDg/4wA+/8/AAMAgQDp/w0ADAAQAAoANgAgAA4AKABIAB4A4v/3/+f/+v/c/+n/EADn/wgAFAAqAOz/IwDc/9//3f8XAND/2v/a/w0A5v8BANb/9P/m/wAA8P8ZAN3/RwAGAEsABgB/AP7/NAASAEgABAA3AP3/KgD9/1sA8P8lAOr/FgD1/xAA4/8kAOv/AwD4/xEA5f8NAPT/+v/3/x8A7f8PAPj/IwD5/yAA9/8ZAAEAGgD4/xoA9f8HAAMACAD0/xgA+P8AAPr/IQDp/w4A8v8HAPX/IgD1/wYA+P8GAPX/GgD3/woABQASAAcAGQDw/+v/9P8bAP3/HADs/+f/7/8LAPr//v/0//T/AgD2/wsA6P///+P/CADY//7/5v/3/wQA/v8LAPD/GgD1/yMA/P8QAOv/LADw/yQA+P8XAO7/MQD9/yEAAQAcAPD/IgD9/xMA+/8OAO//FQABAAoA+/8PAPP/FQABAAQA9/8PAPX/CAADAAEA+P8NAPv/CAAGAAUA9/8JAP//AAAFAPz/+f8HAAQA/f8FAP3//P8FAAYA+P8DAP7/+/8AAAcA9/8BAP///f///wgA9//+/wAA/v/8/wUA9//8/wIA///7/wUA+v/7/wIAAAD6/wMA/P/6/wEAAQD6/wEA/v/7/wIAAgD6////AAD7/wEAAgD7//7/AQD8/wAAAwD8//3/AwD9/wAAAgD9//z/AwD/////AgD+//z/AwAAAP7/AQD///3/AgABAP3/AAAAAP3/AgACAPz///8BAP3/AQACAP3//v8BAP7/AAABAP3//v8CAP7///8BAP7//f8CAP////8AAAAA/v8CAAAAAAAAAAAA/v8BAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAAAAP//AAD//wAA//8AAAAA/////wAAAQD+////AAAGAP3/OAABAIIAAwBv//f/E/0QAK0ADQCzA/7/8P4u/0cBDQCJA6ABbQDg/w7/z/9o+Vn/SPnL/1//Ef+2+jr9RfZgA5QFZwILDFj+PAb2/nEFKgKk/R0Dlv6b/FUDsP6YAoj9SgAT/iL/tAPwAv8A0P6zAr7/dwAnAf39uP22/skA2v///2YCoP4UAUsAZgF2AJH+4P70/rz9+f+U/Xv/8v7CAcb+TACS/kwAv/+x/tX9oP71/oL/1f8nAEUAZwGtAAgAIgC/AD4BaP8GAGH/dQDF/64Arf8nAakAhAH9/+kAQQD3AFb/q/8p/yIAR/8FAPD/ZAA/AIYA3v8tADQADQBp/3f/CwABAP3/Wf8OANj/WwDH/xoAe/8DAKz/zv96/z8A3f/J/5X/IAD5//j/q//c/+//RADq//D/vv8pADUAFQDI/y8ACAAbANb/OwD3/+3/9f/e/wcAIAAeAMH/8/8xAC0AEADW/+3/HAADAPv/8P8DAOL/OwD3/xcACQAHAM//5f8XAAcAz//T/9D/HgD9////yf/e//v/AgD//9H/6/////H/+/8hAAIA9//7/w0AFgAQAPL/2v/8/xsAGQABANz/9P8YAAQA/v/y/wMA5v8YAAkAAAAAAAMA7/8KABgADwDs//j/BwATABsA8P/1//z/BAAMAAAA9P/s/xAA/v8GAAkA/v/p/wMACwALAP7/9P/p/wcADQAFAPb/7//4/w0ACAD8//b//v/1/wMACwD1//T/8P/8/wAACQDz/+f/5P8GAAkABQD5//D/+v8FAA0AAwD///T/AgACABAA/v8CAPD/+/8FAAoA9f/3//f//v8GAP7/9v/t//z/+f8AAPj/+v/3/wEA+v8HAPr//P/5/wQA//8DAPr/+P/3/wYA///+//X/+//5/wQA/f/7//X/+//4/wMA/f/8//j//v/9/wYA///8//f/AgAAAAUA/f/6//n/AwACAAIA/f/7//z/AwACAAAA/f/6//3/AgADAP7//f/7/wAAAwAFAPz////8/wMAAgAEAPv//v/+/wMAAgADAPv//v///wMAAQABAPv//f8AAAIAAAD///v//f8BAAIA///+//z//v8CAAIA/v/9//3///8CAAEA/v/9//7/AAACAAAA/v/9////AAABAAAA/f/9/wAAAQABAP///f/+/wEAAQAAAP///v/+/wEAAQD///7//v///wEAAQD///7//v///wEAAAD+//7///8AAAAAAAD+//7///8AAAAA///+//7///8AAAAA////////AAAAAP////////////8AAP//////////","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAAAAAAAAAABAAAAAAD//////////////v////3/////////+//8////AQD9//z/9f8BAAIA+f8dACgAWQBxAJX/qv+Y/uz9aP9k/7UDUQQBAiQA4Pgi/AkB0gKaBsD/+fxp/vz9CQSp/I/+ywDO+vMD0fzK/PABcgBeBfoBv/+uAuH9Sf5gAy39awMmBWUBuP9fA9/9fgDj/2/+EACaACcCSv9Z/2j/rv7hAA0AWf55/7L84P7E/SIAT/67AMv/tf+FAA7/1v+7/gv/IP+E/sQA+P5aAXz/tP9XAFX/tP8o/4r/j//e/yQAMv9mAJT/rgCr/9X/EwCb//H/9f7F/6D/EAAoAK3//v+e/zsAh/+B/7r/if/C/2r/4P/z/6//HwCy/0IA7/9ZALT/y/80ACgA9v/J/9//DgA5ADUALQARADIACwAfAOf/NgArACMACQBBAEcAGAAjAC4AWQBUAHcAAAAfACEAIAAcAPj/CADk/yQA7v89AEEAFwD5/xYA6f8aAOX/AADF/zQADwAUAOT/BQDr/yUA6P8XAOf/HADR/0AA8P8nAAgACQDt/ycAKAAHAPH/IQDz/xsACADn//n/DgADAA4A8P///8z/GgDN/yMA/f8QANj/MwACAC0ACwAOAO3/JgAZAAUACgAAAA4AIgAaAAkADwACAAAAHQATAAUABQACAAgACwAjAO////8AAA8ABQAPAPL//f8GAAsABgAGAPD/8v8GAPz/CAD6//H/6v8PAAgABgD4//3/9v8aAAgABwD1//7//v8QAAoACAD//wUA9v8QAAoABAAFAAgAAgAJAAoAAwD//w0AAgD//wcA/v8DAAoABQAFABUABAAKAAYABwAHAA8ACgAGAAwADwAMAAkAEAAJAAgADwAMAAgADgAJAAUACQAPAAUACwAHAAEABgAIAAEABAAGAP//AgAJAAAAAgAEAP7///8IAAIA//8GAAEAAQAJAAIA/v8EAAMA//8JAAEA/v8DAAMA/v8HAAMA/f8BAAUA/v8FAAMA/v8BAAcA//8DAAMA/v8BAAYA//8CAAMA/////wcAAAAAAAMAAAD//wYAAQD+/wMAAQD//wUAAQD+/wIAAgD//wQAAgD+/wEAAwD//wMAAwD+/wEAAwD//wIAAwD//wEABAAAAAEABAD//wAABAABAAAAAwAAAAAABAABAP//AwABAAAAAwACAP//AgACAAAAAwACAP//AgACAAAAAgACAAAAAQADAAAAAQACAAAAAQADAAAAAQACAAAAAAACAAEAAAACAAEAAAACAAEAAAABAAEAAAABAAEAAAABAAEAAAABAAEAAAABAAEAAAABAAEAAAAAAAAAAAAAAAAA","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAAAAP//AAD//wAA//8AAAAA//8AAP//AAACAAAA+f8BAAYA///4/wIA//8AAA8A/v/V/wEAEwA9AAEBRwA2AF7/kfog/3gBwv99CDYBU/qtAUX/AP7OAfkAX/o9B38FSfwaAuT14/60BAr8CQAI/tfyIQTzAXP+egdUBBwBof7TBMT8bAWi/5EEWwBRAAAKyfxE/8b88vp6ACP+PAF4/qD8MQNM/ygCJ/2XAPD9kP5gAVT/iP9I/lEB4P8qAD0BFAGa/+7/DgB2AOP98gFm/u/+Vv5/AG8ASP9gAM//qv9w//oAcv+2/jIBHgA7/6D/oAAGAKH/lADT/wAAggC8AAYAkP9yAEcAkf8BAOD/RAAr/zUANwDt/xQAJQAkAMT/zwA/AOH/xv9zAGsANQBTAIcALAAvACIATACy/xMADADg/xcAWABvAJL/7f9VAPb/EgDt/wcA4f8kAPP/5P+h/wgACQDy//r/LgAQAMn/8/9CAOX/5v/S/9//3P8pABYAuP/s/w8AFgDt/+3/7v/w/9j/5/8GAOf/2P/2//P//v8kABMAuf/m/xoADADZ/+r/3P8KAAUAKwDe/wsA3P8VAAAADgAfAB0ACAAMAF4AGgAhAPL/MwDz/0kABAAKAPX/LwAbAAkA9v/s/+3/8/8CABAAAADm//n/BQALAAUAAQDj//n/JQAVAPX/9v/+/wIAEQABAPP/8P/1/wAABgD6/+3/7//o//j/DAD8/+b/8P8IAAkABgD4//D/8P8UAAoAAwD4/wAA+f8OAAcAAAAFAPX/9v8TAAkA8v8EAPb/9/8dAA0A7/8CAPn/+f8SAAQA8/8CAOf/+v8DAAgA9P////H//P8IAAUA8//0/wIAAQAGAAgA9//7/wAA+/8EAP//+P/+////AgACAAsA8v/+/wIABQD7/wgA9v/7/wMABAD5/wAA/P/3/wEAAQD7//7//P/1/wQA///3//r////3/wMAAwD1//r/AwD6////AgD4//n/AwD8//7/AgD4//n/AwD+//3/AQD4//n/BQD///n/AAD6//j/BAABAPj/AAD9//v/AwADAPj//v/+//z/AwAEAPj//v8BAP7/AQADAPj//f8CAP////8EAPr//P8DAAAA/v8CAPv//P8DAAEA/f8BAP3//f8DAAIA/P8AAP7//f8DAAIA/P///wAA/f8BAAIA+//+/wEA//8AAAEA+//+/wEA/////wEA/P/+/wEA///+/wAA/f/9/wEAAAD9/wAA/f/+/wEAAQD8/////v/+/wAAAQD8////////////AQD9////AAD/////AAD+////AAAAAP//AAD///////8AAP//AAD//wAA//8AAP//"]},function(A,t){A.exports=["UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+/wQA8/8ZAPr/DAD+/wMA/v8KAAQA/f8DAAMABADs//z/8v/z/8f/R/90/ob+//zAAWsDAwY3DKn9//tu93DvkwI6An4CuwJ0/BH7VPux92X0Gu7N/EX9mgfqCkkIiRMgBd4NQQGL/c0G/xBxAKELZATUA/sIHRSx+fkCyAUmBNEJIARlAdHz2AjNACcIsAW4AlECsvtJ/P/7K/tf++n8aP4W+g0FXAElAMn8nQHn/sT+Zv7N+9X2xvzM/O3+EvpqBBD7SQLd+vb/sPlw/JD72/3n+Rr+L/wS/vz6UQGg/Nf+Av5L/5X9Gv2//SP+mf3j/lf+v/2B/ZH/5P05/iL9MP9F/uf9UP4v/qv9mv7o/Xn+wP2k/8L+uP5J/tD+Dv/Y/bL+mP72/n3+pP+7/hAA+/5zAGH+Z/+u/g8Azv2y/6L+//9o/iIADP8VACz/CwCN/pb/1v4yAFP+wf+4/jsAcf5VAP3+bADa/nMA6f4sAOT+IQBd/v7/7v6aAIL+QADe/nEA0P4yAKz+CQCo/moAuf5xAN7+mAC8/jcANf9eAPX+IAA1/1kAAP9hAMz+PQD5/m0A2/4gAPr+UQDh/jQAEv9BAPH+FABN/zkASv9DADP/BABe/1IAGf8oAE3/RQAw/zIAQf8mADn/GgBE/xIAR/8hAD7/BABy/zEAKP/0/07/GwBX/z4ARf8mAFr/QQBV/zUAVP8eAFz/JABt/0EAUP8MAHz/KgBr/ycAYv8EAH3/MABl/x8Agv8bAIj/GgBv//z/ff8AAJX/IABu/+T/jv/r/4z/9/9n/77/pP8JAJD/EQCJ//r/q/8WAJ//GQCU/xYAtv8qAKr/PQCW/ysAwf8+ALb/OgC3/ygAz/8uAM7/OgDH/ygAz/8kAMz/OgC//xsA1f8qAMn/LwDN/xcA1f8oAMv/JQDR/xMAzf8bAM//HgDU/wUA2v8ZANL/EwDW/wEA1f8ZAMz/BwDX/wIA0v8SANT/BQDW/wMA0/8PANT/AADY/wIA1f8MANX/+f/a/wUA0v8IANf/+//Y/wUA0/8DANr/+f/Y/wQA1v8BANr/+f/Z/wUA1//8/9z/+v/Y/wYA2f/8/93//v/Y/wUA2v/9/93////Z/wUA3P/8/97/AgDa/wMA3v/8/97/AwDb/wIA3//9/97/BADd/wEA4f///9//BQDf/wAA4v8AAN//BQDf/wAA4/8CAN//BADh/wAA4/8DAOD/BADi////4/8DAOH/AwDk/wAA5P8FAOL/AgDl/wEA5P8FAOL/AQDl/wEA4/8EAOL/AQDj/wIA4P8DAN//AADg/wIA3v8CAOD/AADh/wEA4v8AAOP/AADm/wAA6P8AAOz/AADu/wAA","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD//////f/+//7///8AAP////8BAAEA/f8AAAEAAQAFAAUA9//6/x0A2f/9/xMA3P+jAE//of9HAKP//gCj/77/Z/vi/28D9/ywDJAJIvr6AsX0Xec4BhcGzf23DZP7yfZ6C1//nwBDBIHyYgob/Tf3sQ41ANoKRA/A+E7yffAa9gD5EQUBDMwMygiqAHMAqPqhAGUB2/gE+a78H/+4APT6DwIUAA0HNwMhBfL8E/90A5n7dP9cALIC+v5C/q0AOv9kAogBHv01/+3/qAQD/ub8T/4vAOUA5P6KATv+ywEYAeT+KP6i/3gCFP6h/hr/+P83ACL/VADn/8UARQJI/4MAu/8qAlj+wf4iAPb/LgFJ/8QAUABAAI4ABf+k/3X/YgFK/ij/j/9HADoAi/+WAA0BVwC/ACL/LACe//cARv9i/xgAUgA0ACj/FgBgAIj/5P9M/7z/zv8/AKz/gv8sAEQA6/+I/yYAawDL/7T/xf8qAOv/FQCu/5n/EgAyAO3/i/9LAE4A+//R//P/FgDe/8z/u/8DADIALAAZALL/TAA8ABwAo//1/xwA/P/L/z0A6P8jAN7/7v+a/zAAwf/7/3//KQAuACwA9v8RAGYAIwBNADgAKgASAF0ADgANACEAMQDH//H/LQACAB0Ay////x0APAABAAQA2v8iAAcAEgDE/+v/FQD+/+P/DAD1/97/6v/4//X/EwD4/+7/5P8cAA0ACQDH//7/CQAXAAEA/P/5//j/CwAWAAEABQD9//n/AQAWAB0A7v/k/wAACQAmAP//9/8AAPn/8/8aAO//6/8fAOv/5v8hAP//5/8PAOf/AAAGAPn/6v8JAAYABgABAOv/1//1//L/+P8DABcA6f/8/wMACgD7/xAA3v/2//z/DADu//z/5v/5/wEA/P/6//7/7v/x/wQABgD5/wAA8v/w/wkAEQD2//j/+v8EAAcAEAD3//v/+v8CAAAACQD3//v//v/9/wUADAD2//X/AgAHAAAABwD2//T/BgAKAP7/AQD4//r/BAAIAPn/AAD3//f/BQAHAPv//v/7//n/BQAJAPj/+v/9//7/AgAGAPj/+f8BAAEAAgAFAPn/+v8BAAIAAAAEAPn/+f8CAAQA/v8BAPr/+v8CAAQA/P////v//P8CAAQA+//+//3//f8CAAUA+v/9//////8AAAQA+v/8////AAD//wIA+//8/wAAAQD+/wEA+//8/wAAAgD9/////P/9/wEAAgD8//7//f/9/wAAAgD8//3//v/+////AQD8//z/////////AAD8//3///8AAP7/AAD9//7///8AAP7////+//////8AAP7////+////////////////////","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD//////v8AAP///////wAAAAAAAP7/AQABAAAABwD///X/BQAjAPL/CQDb/9D/GAAb/7sAYwCW/z0BcP/X/7T/2QDW+wH8yANCCCUJ5QT++UXmhPwhA78FuAxH+p78ifudBlAG9vmu/lAK2fdlB///cfjoCa0E7Akn9Yb/zvba+AkAHPywBGEBFwUNAL8AXAAGA20DFvmR/kz+F/06Ag/+GwHl/5EEKgJd/q0AP/ym/9n6EfxY/2H+/QFtAC4C6QBDAaMCo/20/+3/3f/p/fL9rv9V/6cBhQHuAX4AcwJYAaH/IP/P/gsApP0LAe7/sQBuAI0AAgGDAE4BzACe/5X//v+v/+f+Zf+gAOv/5QBhAOIApAANASYAuP+h/8b/HQBr/9//bACWAGEAFAB5AD0AWQDU/+D/Yf/p//D/s/+R/4QAMQBvABEAkQBfABQAJgDW/wwA8/8XALz/vf8zAFAAKwD1/zEAPwDJ/x0A7/8LAOX/FwDR//H/EQAdAO//6P8QAFEA2f8WABEAMgDy/xIA+f/s/xAALgDv////HQAvAPT/+f8iAAYAEgAFABoAGgD//w0A+f/0/xsAHgDx/9f/GAACAPH/8f8JAPf/GwALABEA7/8cAPT/CgD2//j/BQD8/+3/OgAgAAYA9f8PAN7/DgD9/9r/1//3/+3/9//1//b/8//5//f/AgAJAOf/+v8OAAMACwD9/+7/5f8eAAEA9//q//7/8P8WAP7/+//4/wIA+f8TAAIA9f/5/wcA+P8iAAgA9v/n/xoA//8gAAUABwDj/wAA9v8BAAUAFQDn/wMA7v8QABAAEQDm/wwA8f8aAAAABwDu/wcACgASAAEA7//w//f/BgARAAkA6P/3/wcADgAKAAYA4f/4/wYADgAAAPr/8P/9/xQACgAHAPn/7//9/xEAAgD+//L/8v/8/xUAAwDw//H/9f8CAAsA/v/q//L/+f8FAAYA/P/r//j///8GAAkA+//o//j/AQAIAP//+v/o//v/CAAIAPv/+P/w/wEACQAHAPj/+f/0/wIACwAFAPb/+f/4/wQACwACAPP/+f/+/wYACAD///L/+/8BAAYABQD9//P//P8FAAUAAgD7//T//f8HAAQA///7//f///8IAAMA/P/6//r/AQAIAAEA+v/6//3/AgAHAAAA+f/7/wAAAwAFAP7/+P/8/wIAAgACAP3/+f/9/wMAAwAAAPz/+v/+/wQAAgD+//z/+/8AAAQAAQD8//z//f8BAAQAAAD7//3///8BAAMA///7//3/AAACAAEA/v/7//7/AQABAAAA/v/9////AQAAAP///v/+////AAD/////////////////////////////","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD////////+//////8AAAAA/v/+/wAAAQD8//3/CQAJAP3/+v8PAAcApABlABkBkwCO/i//lfqa/HQAcf/3BdkCzwJcBCMC0wMN/9/9wgI7AaECYfxV/Tf83vhn/xrt8Owx/8n7cgHABYb43QcZDh4WugNrA7P74gHu/9z/zv0t/acCiQHY/iv4qQOl/ysCE/0//XT9Sf4O//j9xfupAn394gHO+rsCXAFIAxQC9wIXBgcD2AQuAnb/9gJh/6wAVfxEAI4Bvf7oAFv/bALsAMQBe/88/joAT/4dAH39/v9LAXn/gwDI//QBdABcAA0A7f4lAMn///+9/tv/iABp/13/pP/dALv/w/8MAHv//f+y/6////7U/5AAZP+Z/8r/nQDR/5r/DwDr/xAA4v+s/3z/+P9uAOv/t/82AGcAHgCb/yQAFQBGAM7/CgD3/xoAegAaAOz/CgBHAA8Adv8/AAAABQC2/xIAAAA7ABQAKgCj/z4AAQAXAJz/JAADAAcA8f/1/2AAAQAlAPD/NgDx/1wA7v/4/wMAZADv//3/HQAkAFoA8P9FAPv/FgBIAPf/WQAHAEUACQD0/xIAQwDu/wMAwP9VALn/XwCw/yEA5f8sAPj/FgDD/1YAyv8rAOX/HQDo//j/IQAQACAAHwD9/yQAHQBAABgABQAiAAUAKAD3/wkACwAKAAMABwAJAPb/+f8GAOr/JQAHABMA6P8TAA4AGgD//woA8/8ZAP//GADu/w0A9v8SAAMABwD4/wQA5P8XAAQACgDq/wUA+/8VAAcACADs/xIAAAATAPH/+v/1//T/7f///+z/+v/y/+//9/8KAAcACgAJAPT/BAAKAAAABgAIAPL/9v8KAAMABAACAPr/9v8OAAIA+P/x//v/+f8MAPb/+P/w/wQA9f8MAPn////7/woA/v8PAAEAAgD1/xAAAQAPAP//AwD//xQABwALAAAABgADABAAAgAHAAAACAABAA8ABQAFAAMABwAEAA4ABwADAAEACQAFAAoAAwD//wAACQADAAUAAQD/////CAABAAMAAAD/////BwACAAEAAAD/////BwACAP7///8BAAAABgABAP7///8CAAAABAAAAP7///8DAAAAAwAAAP3///8DAAAAAQAAAP3//v8EAAAAAAD+//////8EAP/////+/wAA/v8EAP/////+/wEA/v8EAP///v/+/wIA//8DAP///v/+/wIA//8BAP///v/+/wMA//8BAP/////+/wMA//8AAP//AAD+/wQA//8AAP7/AQD//wIA////////AQD//wIA////////AQAAAAEAAAAAAP//AQD//wEAAAAAAP//AQAAAAEAAAAAAAAA","UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+/wAA+v8AAPz/AAD//wAA/f8AAAEAAAD+/wAACQAAAAQAAAAZAAAAtgAAAFsBAABW/gAAH/oAAGcBAABoBwAAlAAAAO3/AAARAQAA+wIAAEoEAACe/gAAiv4AALD0AADJ8wAAkQQAAF34AABi8QAAPQAAAAH2AAD19AAADAMAAJwGAACTEAAA0AwAAJkHAACOBwAAuQEAANcDAAC6AgAAHwUAAHEFAAB0AwAAbgEAADz+AADYAQAAGAAAAJwCAADgAAAA//0AAMn+AAAT/AAAwP8AAOn9AAAJAAAAewEAAOn+AACN/wAAOv0AAO3+AADN/gAAcP8AACj/AACq/gAA+f4AAML9AACa/wAA/f4AAN7/AABo/wAA6/4AAE//AAAC/wAAEQAAAHX/AAB0AAAA5f8AAEwAAAB3AAAA5/8AAMIAAABCAAAAzgAAAE8AAAB3AAAAKAAAADMAAACqAAAALwAAAK4AAAASAAAAVgAAACgAAAAtAAAATAAAAP3/AAA7AAAA2/8AACQAAADw/wAALQAAADEAAAAlAAAAbAAAADMAAABUAAAAEAAAACgAAAD1/wAA9v8AAPr/AADu/wAALgAAABIAAABUAAAARAAAAGUAAABGAAAAOAAAAGAAAAAuAAAARQAAACEAAAAfAAAAAAAAAAkAAAAQAAAAAwAAABIAAADs/wAAEAAAAAYAAAASAAAAIgAAABEAAAADAAAABAAAAA8AAAD4/wAAHQAAAAsAAAAIAAAADgAAAP//AAAcAAAADwAAAAYAAAASAAAAFwAAAAMAAAAYAAAAEgAAAPr/AAAQAAAADQAAAAoAAAD3/wAABgAAAPb/AADf/wAA/v8AAPL/AAD6/wAAFAAAAAQAAAAEAAAAGwAAAAEAAAAMAAAAIAAAAAIAAAAdAAAAGAAAAAIAAAAcAAAAEgAAAAcAAAAeAAAADwAAAAQAAAAeAAAABAAAAAYAAAAZAAAAAQAAAA4AAAATAAAA/v8AAAoAAAAOAAAA+/8AAAsAAAAJAAAA+f8AAAsAAAABAAAA+f8AAAoAAAD9/wAA+v8AAAcAAAD5/wAA+v8AAAUAAAD3/wAA/f8AAAQAAAD2/wAAAAAAAAEAAAD3/wAAAgAAAAAAAAD4/wAAAwAAAP7/AAD6/wAABAAAAP3/AAD8/wAABAAAAPv/AAD+/wAAAwAAAPv/AAD//wAAAQAAAPv/AAAAAAAAAAAAAPv/AAACAAAA//8AAPz/AAACAAAA/v8AAP3/AAACAAAA/f8AAP7/AAABAAAA/f8AAP//AAABAAAA/f8AAAAAAAAAAAAA/v8AAAEAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"]},function(A,t,e){"use strict";t.getBrowserInfo=function(){const A=navigator.userAgent;let t,e=A.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([\d\.]+)/i)||[];if(/trident/i.test(e[1]))return t=/\brv[ :]+(\d+)/g.exec(A)||[],{name:"IE",version:t[1]||""};if("Chrome"===e[1]&&null!=(t=A.match(/\bOPR|Edge\/(\d+)/)))return{name:"Opera",version:t[1]};e=e[2]?[e[1],e[2]]:[navigator.appName,navigator.appVersion,"-?"],null!=(t=A.match(/version\/([\d.]+)/i))&&e.splice(1,1,t[1]);let i=A.match(/android|ipad|iphone/i);return i||(i=A.match(/cros|linux|mac os x|windows/i)),{name:e[0],version:e[1],platform:i?i[0]:"unknown"}},t.patchSafari=function(){window.webkitAudioContext&&window.webkitOfflineAudioContext&&(window.AudioContext=window.webkitAudioContext,window.OfflineAudioContext=window.webkitOfflineAudioContext)}},function(A,t,e){"use strict";A.exports="1.0.6"}])})},function(A,t,e){"use strict";A.exports="0.0.4"}])}); \ No newline at end of file diff --git a/src/renderer/lib/smoothscroll.js b/src/renderer/lib/smoothscroll.js new file mode 100644 index 00000000..8c694ad6 --- /dev/null +++ b/src/renderer/lib/smoothscroll.js @@ -0,0 +1,434 @@ +/* smoothscroll v0.4.4 - 2019 - Dustan Kasten, Jeremias Menichelli - MIT License */ +(function () { + 'use strict'; + + // polyfill + function polyfill() { + // aliases + var w = window; + var d = document; + + // return if scroll behavior is supported and polyfill is not forced + if ( + 'scrollBehavior' in d.documentElement.style && + w.__forceSmoothScrollPolyfill__ !== true + ) { + return; + } + + // globals + var Element = w.HTMLElement || w.Element; + var SCROLL_TIME = 468; + + // object gathering original scroll methods + var original = { + scroll: w.scroll || w.scrollTo, + scrollBy: w.scrollBy, + elementScroll: Element.prototype.scroll || scrollElement, + scrollIntoView: Element.prototype.scrollIntoView + }; + + // define timing method + var now = + w.performance && w.performance.now + ? w.performance.now.bind(w.performance) + : Date.now; + + /** + * indicates if a the current browser is made by Microsoft + * @method isMicrosoftBrowser + * @param {String} userAgent + * @returns {Boolean} + */ + function isMicrosoftBrowser(userAgent) { + var userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/']; + + return new RegExp(userAgentPatterns.join('|')).test(userAgent); + } + + /* + * IE has rounding bug rounding down clientHeight and clientWidth and + * rounding up scrollHeight and scrollWidth causing false positives + * on hasScrollableSpace + */ + var ROUNDING_TOLERANCE = isMicrosoftBrowser(w.navigator.userAgent) ? 1 : 0; + + /** + * changes scroll position inside an element + * @method scrollElement + * @param {Number} x + * @param {Number} y + * @returns {undefined} + */ + function scrollElement(x, y) { + this.scrollLeft = x; + this.scrollTop = y; + } + + /** + * returns result of applying ease math function to a number + * @method ease + * @param {Number} k + * @returns {Number} + */ + function ease(k) { + return 0.5 * (1 - Math.cos(Math.PI * k)); + } + + /** + * indicates if a smooth behavior should be applied + * @method shouldBailOut + * @param {Number|Object} firstArg + * @returns {Boolean} + */ + function shouldBailOut(firstArg) { + if ( + firstArg === null || + typeof firstArg !== 'object' || + firstArg.behavior === undefined || + firstArg.behavior === 'auto' || + firstArg.behavior === 'instant' + ) { + // first argument is not an object/null + // or behavior is auto, instant or undefined + return true; + } + + if (typeof firstArg === 'object' && firstArg.behavior === 'smooth') { + // first argument is an object and behavior is smooth + return false; + } + + // throw error when behavior is not supported + throw new TypeError( + 'behavior member of ScrollOptions ' + + firstArg.behavior + + ' is not a valid value for enumeration ScrollBehavior.' + ); + } + + /** + * indicates if an element has scrollable space in the provided axis + * @method hasScrollableSpace + * @param {Node} el + * @param {String} axis + * @returns {Boolean} + */ + function hasScrollableSpace(el, axis) { + if (axis === 'Y') { + return el.clientHeight + ROUNDING_TOLERANCE < el.scrollHeight; + } + + if (axis === 'X') { + return el.clientWidth + ROUNDING_TOLERANCE < el.scrollWidth; + } + } + + /** + * indicates if an element has a scrollable overflow property in the axis + * @method canOverflow + * @param {Node} el + * @param {String} axis + * @returns {Boolean} + */ + function canOverflow(el, axis) { + var overflowValue = w.getComputedStyle(el, null)['overflow' + axis]; + + return overflowValue === 'auto' || overflowValue === 'scroll'; + } + + /** + * indicates if an element can be scrolled in either axis + * @method isScrollable + * @param {Node} el + * @param {String} axis + * @returns {Boolean} + */ + function isScrollable(el) { + var isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y'); + var isScrollableX = hasScrollableSpace(el, 'X') && canOverflow(el, 'X'); + + return isScrollableY || isScrollableX; + } + + /** + * finds scrollable parent of an element + * @method findScrollableParent + * @param {Node} el + * @returns {Node} el + */ + function findScrollableParent(el) { + while (el !== d.body && isScrollable(el) === false) { + el = el.parentNode || el.host; + } + + return el; + } + + /** + * self invoked function that, given a context, steps through scrolling + * @method step + * @param {Object} context + * @returns {undefined} + */ + function step(context) { + var time = now(); + var value; + var currentX; + var currentY; + var elapsed = (time - context.startTime) / SCROLL_TIME; + + // avoid elapsed times higher than one + elapsed = elapsed > 1 ? 1 : elapsed; + + // apply easing to elapsed time + value = ease(elapsed); + + currentX = context.startX + (context.x - context.startX) * value; + currentY = context.startY + (context.y - context.startY) * value; + + context.method.call(context.scrollable, currentX, currentY); + + // scroll more if we have not reached our destination + if (currentX !== context.x || currentY !== context.y) { + w.requestAnimationFrame(step.bind(w, context)); + } + } + + /** + * scrolls window or element with a smooth behavior + * @method smoothScroll + * @param {Object|Node} el + * @param {Number} x + * @param {Number} y + * @returns {undefined} + */ + function smoothScroll(el, x, y) { + var scrollable; + var startX; + var startY; + var method; + var startTime = now(); + + // define scroll context + if (el === d.body) { + scrollable = w; + startX = w.scrollX || w.pageXOffset; + startY = w.scrollY || w.pageYOffset; + method = original.scroll; + } else { + scrollable = el; + startX = el.scrollLeft; + startY = el.scrollTop; + method = scrollElement; + } + + // scroll looping over a frame + step({ + scrollable: scrollable, + method: method, + startTime: startTime, + startX: startX, + startY: startY, + x: x, + y: y + }); + } + + // ORIGINAL METHODS OVERRIDES + // w.scroll and w.scrollTo + w.scroll = w.scrollTo = function() { + // avoid action when no arguments are passed + if (arguments[0] === undefined) { + return; + } + + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0]) === true) { + original.scroll.call( + w, + arguments[0].left !== undefined + ? arguments[0].left + : typeof arguments[0] !== 'object' + ? arguments[0] + : w.scrollX || w.pageXOffset, + // use top prop, second argument if present or fallback to scrollY + arguments[0].top !== undefined + ? arguments[0].top + : arguments[1] !== undefined + ? arguments[1] + : w.scrollY || w.pageYOffset + ); + + return; + } + + // LET THE SMOOTHNESS BEGIN! + smoothScroll.call( + w, + d.body, + arguments[0].left !== undefined + ? ~~arguments[0].left + : w.scrollX || w.pageXOffset, + arguments[0].top !== undefined + ? ~~arguments[0].top + : w.scrollY || w.pageYOffset + ); + }; + + // w.scrollBy + w.scrollBy = function() { + // avoid action when no arguments are passed + if (arguments[0] === undefined) { + return; + } + + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0])) { + original.scrollBy.call( + w, + arguments[0].left !== undefined + ? arguments[0].left + : typeof arguments[0] !== 'object' ? arguments[0] : 0, + arguments[0].top !== undefined + ? arguments[0].top + : arguments[1] !== undefined ? arguments[1] : 0 + ); + + return; + } + + // LET THE SMOOTHNESS BEGIN! + smoothScroll.call( + w, + d.body, + ~~arguments[0].left + (w.scrollX || w.pageXOffset), + ~~arguments[0].top + (w.scrollY || w.pageYOffset) + ); + }; + + // Element.prototype.scroll and Element.prototype.scrollTo + Element.prototype.scroll = Element.prototype.scrollTo = function() { + // avoid action when no arguments are passed + if (arguments[0] === undefined) { + return; + } + + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0]) === true) { + // if one number is passed, throw error to match Firefox implementation + if (typeof arguments[0] === 'number' && arguments[1] === undefined) { + throw new SyntaxError('Value could not be converted'); + } + + original.elementScroll.call( + this, + // use left prop, first number argument or fallback to scrollLeft + arguments[0].left !== undefined + ? ~~arguments[0].left + : typeof arguments[0] !== 'object' ? ~~arguments[0] : this.scrollLeft, + // use top prop, second argument or fallback to scrollTop + arguments[0].top !== undefined + ? ~~arguments[0].top + : arguments[1] !== undefined ? ~~arguments[1] : this.scrollTop + ); + + return; + } + + var left = arguments[0].left; + var top = arguments[0].top; + + // LET THE SMOOTHNESS BEGIN! + smoothScroll.call( + this, + this, + typeof left === 'undefined' ? this.scrollLeft : ~~left, + typeof top === 'undefined' ? this.scrollTop : ~~top + ); + }; + + // Element.prototype.scrollBy + Element.prototype.scrollBy = function() { + // avoid action when no arguments are passed + if (arguments[0] === undefined) { + return; + } + + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0]) === true) { + original.elementScroll.call( + this, + arguments[0].left !== undefined + ? ~~arguments[0].left + this.scrollLeft + : ~~arguments[0] + this.scrollLeft, + arguments[0].top !== undefined + ? ~~arguments[0].top + this.scrollTop + : ~~arguments[1] + this.scrollTop + ); + + return; + } + + this.scroll({ + left: ~~arguments[0].left + this.scrollLeft, + top: ~~arguments[0].top + this.scrollTop, + behavior: arguments[0].behavior + }); + }; + + // Element.prototype.scrollIntoView + Element.prototype.scrollIntoView = function() { + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0]) === true) { + original.scrollIntoView.call( + this, + arguments[0] === undefined ? true : arguments[0] + ); + + return; + } + + // LET THE SMOOTHNESS BEGIN! + var scrollableParent = findScrollableParent(this); + var parentRects = scrollableParent.getBoundingClientRect(); + var clientRects = this.getBoundingClientRect(); + + if (scrollableParent !== d.body) { + // reveal element inside parent + smoothScroll.call( + this, + scrollableParent, + scrollableParent.scrollLeft + clientRects.left - parentRects.left, + scrollableParent.scrollTop + clientRects.top - parentRects.top + ); + + // reveal parent in viewport unless is fixed + if (w.getComputedStyle(scrollableParent).position !== 'fixed') { + w.scrollBy({ + left: parentRects.left, + top: parentRects.top, + behavior: 'smooth' + }); + } + } else { + // reveal element in viewport + w.scrollBy({ + left: clientRects.left, + top: clientRects.top, + behavior: 'smooth' + }); + } + }; + } + + if (typeof exports === 'object' && typeof module !== 'undefined') { + // commonjs + module.exports = { polyfill: polyfill }; + } else { + // global + polyfill(); + } + + }()); + \ No newline at end of file diff --git a/src/renderer/js/sortable.min.js b/src/renderer/lib/sortable.min.js similarity index 100% rename from src/renderer/js/sortable.min.js rename to src/renderer/lib/sortable.min.js diff --git a/src/renderer/lib/stackblur.min.js b/src/renderer/lib/stackblur.min.js new file mode 100644 index 00000000..79cff7a8 --- /dev/null +++ b/src/renderer/lib/stackblur.min.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).StackBlur={})}(this,(function(t){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var r=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259],n=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];function a(t,r,n,a,o){if("string"==typeof t&&(t=document.getElementById(t)),!t||"object"!==e(t)||!("getContext"in t))throw new TypeError("Expecting canvas with `getContext` method in processCanvasRGB(A) calls!");var i=t.getContext("2d");try{return i.getImageData(r,n,a,o)}catch(t){throw new Error("unable to access image data: "+t)}}function o(t,e,r,n,o,f){if(!(isNaN(f)||f<1)){f|=0;var g=a(t,e,r,n,o);g=i(g,e,r,n,o,f),t.getContext("2d").putImageData(g,e,r)}}function i(t,e,a,o,i,f){for(var g,l=t.data,c=2*f+1,s=o-1,v=i-1,b=f+1,x=b*(b+1)/2,d=new u,y=d,h=1;h>E;if(l[B+3]=Y,0!==Y){var Z=255/Y;l[B]=(O*C>>E)*Z,l[B+1]=(P*C>>E)*Z,l[B+2]=(q*C>>E)*Z}else l[B]=l[B+1]=l[B+2]=0;O-=k,P-=H,q-=_,z-=M,k-=p.r,H-=p.g,_-=p.b,M-=p.a;var $=X+f+1;$=w+($>E,ut>0?(ut=255/ut,l[Nt]=(bt*C>>E)*ut,l[Nt+1]=(xt*C>>E)*ut,l[Nt+2]=(dt*C>>E)*ut):l[Nt]=l[Nt+1]=l[Nt+2]=0,bt-=lt,xt-=ct,dt-=st,yt-=vt,lt-=p.r,ct-=p.g,st-=p.b,vt-=p.a,Nt=ot+((Nt=St+b)>E,l[S+1]=k*C>>E,l[S+2]=H*C>>E,W-=T,k-=j,H-=A,T-=w.r,j-=w.g,A-=w.b,p=I+((p=z+f+1)>E,l[p+1]=Y*C>>E,l[p+2]=Z*C>>E,X-=Q,Y-=U,Z-=V,Q-=w.r,U-=w.g,V-=w.b,p=F+((p=ot+b)=t?function(t,n){for(var r=0;r0?i=a:t=a}while(Math.abs(o)>n&&++l=0)return n;null==e||t||console.error("VelocityJS: Trying to set 'duration' to an invalid value:",e)}function W(e,t,n){if(u(e))return S[e];if(o(e))return e;if(Array.isArray(e)){if(1===e.length)return r=e[0],C[r]||(C[r]=function(e,t,n){return 0===e?t:1===e?n:t+Math.round(e*r)*(1/r)*(n-t)});if(2===e.length)return function e(t,n,r){var i={x:-1,v:0,tension:parseFloat(t)||500,friction:parseFloat(n)||20},o=[0],a=null!=r,l=0,s=void 0,u=void 0;for(s=a?(l=e(i.tension,i.friction))/r*.016:.016;u=j(u||i,s),o.push(1+u.x),l+=16,Math.abs(u.x)>1e-4&&Math.abs(u.v)>1e-4;);return a?function(e,t,n){return 0===e?t:1===e?n:t+o[Math.floor(e*(o.length-1))]*(n-t)}:l}(e[0],e[1],t);if(4===e.length)return q.apply(null,e)||!1}var r;null==e||n||console.error("VelocityJS: Trying to set 'easing' to an invalid value:",e)}function $(e){if(!1===e)return 0;var t=parseInt(e,10);if(!isNaN(t)&&t>=0)return Math.min(t,60);null!=e&&console.warn("VelocityJS: Trying to set 'fpsLimit' to an invalid value:",e)}function G(e){switch(e){case!1:return 0;case!0:return!0;default:var t=parseInt(e,10);if(!isNaN(t)&&t>=0)return t}null!=e&&console.warn("VelocityJS: Trying to set 'loop' to an invalid value:",e)}function Q(e,t){if(!1===e||u(e))return e;null==e||t||console.warn("VelocityJS: Trying to set 'queue' to an invalid value:",e)}function D(e){switch(e){case!1:return 0;case!0:return!0;default:var t=parseInt(e,10);if(!isNaN(t)&&t>=0)return t}null!=e&&console.warn("VelocityJS: Trying to set 'repeat' to an invalid value:",e)}function U(e){if(l(e))return e;null!=e&&console.error("VelocityJS: Trying to set 'speed' to an invalid value:",e)}function Z(e){if(i(e))return e;null!=e&&console.error("VelocityJS: Trying to set 'sync' to an invalid value:",e)}var Y=void 0,X=void 0,K=void 0,ee=void 0,te=void 0,ne=void 0,re=void 0,ie=void 0,oe=void 0,ae=void 0,le=void 0,se=void 0,ue=void 0,ce=void 0,fe=void 0,de=void 0,ve=function(){function e(){t(this,e)}return n(e,null,[{key:"reset",value:function(){Y=!0,X=void 0,K=void 0,ee=0,te=w,ne=W("swing",w),re=60,ie=0,ae=980/60,le=!0,se=!0,ue="",ce=0,fe=1,de=!0}},{key:"cache",get:function(){return Y},set:function(e){void 0!==(e=z(e))&&(Y=e)}},{key:"begin",get:function(){return X},set:function(e){void 0!==(e=F(e))&&(X=e)}},{key:"complete",get:function(){return K},set:function(e){void 0!==(e=H(e))&&(K=e)}},{key:"delay",get:function(){return ee},set:function(e){void 0!==(e=R(e))&&(ee=e)}},{key:"duration",get:function(){return te},set:function(e){void 0!==(e=B(e))&&(te=e)}},{key:"easing",get:function(){return ne},set:function(e){void 0!==(e=W(e,te))&&(ne=e)}},{key:"fpsLimit",get:function(){return re},set:function(e){void 0!==(e=$(e))&&(re=e,ae=980/e)}},{key:"loop",get:function(){return ie},set:function(e){void 0!==(e=G(e))&&(ie=e)}},{key:"mobileHA",get:function(){return oe},set:function(e){i(e)&&(oe=e)}},{key:"minFrameTime",get:function(){return ae}},{key:"promise",get:function(){return le},set:function(e){void 0!==(e=function(e){if(i(e))return e;null!=e&&console.warn("VelocityJS: Trying to set 'promise' to an invalid value:",e)}(e))&&(le=e)}},{key:"promiseRejectEmpty",get:function(){return se},set:function(e){void 0!==(e=function(e){if(i(e))return e;null!=e&&console.warn("VelocityJS: Trying to set 'promiseRejectEmpty' to an invalid value:",e)}(e))&&(se=e)}},{key:"queue",get:function(){return ue},set:function(e){void 0!==(e=Q(e))&&(ue=e)}},{key:"repeat",get:function(){return ce},set:function(e){void 0!==(e=D(e))&&(ce=e)}},{key:"repeatAgain",get:function(){return ce}},{key:"speed",get:function(){return fe},set:function(e){void 0!==(e=U(e))&&(fe=e)}},{key:"sync",get:function(){return de},set:function(e){void 0!==(e=Z(e))&&(de=e)}}]),e}();Object.freeze(ve),ve.reset();var pe=[],ye={},ge=new Set,he=[],me=new Map,we="velocityData";function be(e){var t=e[we];if(t)return t;for(var n=e.ownerDocument.defaultView,r=0,i=0;i=0&&pe[r].hasOwnProperty(n)}function Ne(e,t){for(var n=be(e),r=void 0,i=he.length-1,o=n.types;!r&&i>=0;i--)o&1<=2&&console.info('Set "'+t+'": "'+n+'"',e))}function Le(e){if(e.indexOf("calc(")>=0){for(var t=e.split(/([\(\)])/),n=0,r=0;r=2&&console.info('Get "'+t+'": "'+o+'"',e),o}var De=/^#([A-f\d]{3}){1,2}$/i,Ue={function:function(e,t,n,r,i,o){return e.call(t,r,n.length,i)},number:function(e,t,n,r,i,o){return String(e)+function(e){for(var t in ye)if(ye[t].includes(e))return t;return""}(o.fn)},string:function(e,t,n,r,i,o){return Be(e)},undefined:function(e,t,n,r,i,o){return Be(Qe(t,i,o.fn)||"")}};function Ze(t,n){var r=t.tweens=Object.create(null),i=t.elements,a=t.element,s=i.indexOf(a),c=be(a),f=p(t.queue,t.options.queue),d=p(t.options.duration,ve.duration);for(var v in n)if(n.hasOwnProperty(v)){var y=Ie(v),g=Ne(a,y),h=n[v];if(!g&&"tween"!==y){Ut.debug&&console.log('Skipping "'+v+'" due to a lack of browser support.');continue}if(null==h){Ut.debug&&console.log('Skipping "'+v+'" due to no value supplied.');continue}var m=r[y]={},w=void 0,b=void 0;if(m.fn=g,o(h)&&(h=h.call(a,s,i.length,i)),Array.isArray(h)){var x=h[1],k=h[2];w=h[0],u(x)&&(/^[\d-]/.test(x)||De.test(x))||o(x)||l(x)?b=x:u(x)&&S[x]||Array.isArray(x)?(m.easing=W(x,d),b=k):b=x||k}else w=h;m.end=Ue[void 0===w?"undefined":e(w)](w,a,i,s,y,m),null==b&&!1!==f&&void 0!==c.queueList[f]||(m.start=Ue[void 0===b?"undefined":e(b)](b,a,i,s,y,m),et(y,m,d))}}var Ye=/((?:[+\-*/]=)?(?:[+-]?\d*\.\d+|[+-]?\d+)[a-z%]*|(?:.(?!$|[+-]?\d|[+\-*/]=[+-]?\d))+.|.)/g,Xe=/^([+\-*/]=)?([+-]?\d*\.\d+|[+-]?\d+)(.*)$/;function Ke(e,t){for(var n=e.length,r=[],i=[],o=void 0,a=0;a1}for(var l=[],s=l.pattern=[],c=function(e){if(u(s[s.length-1]))s[s.length-1]+=e;else if(e){s.push(e);for(var t=0;t1)){for(var r="display"===t,i="visibility"===t,a=0;a=0?H++:R.indexOf("rgb")>=0&&(H=1):H&&(H<4?s[F]=!0:H=0)}return l}function et(e,t,n,r){var i=t.start,o=t.end;if(u(o)&&u(i)){var a=Ke([i,o],e);if(!a&&r){var l=i.match(/\d\.?\d*/g)||["0"],s=l.length,c=0;a=Ke([o.replace(/\d+\.?\d*/g,function(){return l[c++%s]}),o],e)}if(a)switch(Ut.debug&&console.log("Velocity: Sequence found:",a),a[0].percent=0,a[1].percent=1,t.sequence=a,t.easing){case S["at-start"]:case S.during:case S["at-end"]:a[0].easing=a[1].easing=t.easing}}}function tt(e){if(ke.firstNew===e&&(ke.firstNew=e._next),!(1&e._flags)){var t=e.element,n=e.tweens;p(e.options.duration,ve.duration);for(var r in n){var i=n[r];if(null==i.start){var o=Qe(e.element,r);u(o)?(i.start=Be(o),et(r,i,0,!0)):Array.isArray(o)||console.warn("bad type",i,r,o)}Ut.debug&&console.log('tweensContainer "'+r+'": '+JSON.stringify(i),t)}e._flags|=1}}function nt(e){var t=e.begin||e.options.begin;if(t)try{var n=e.elements;t.call(n,n,e)}catch(e){setTimeout(function(){throw e},1)}}function rt(e){var t=e.progress||e.options.progress;if(t)try{var n=e.elements,r=e.percentComplete,i=e.options,o=e.tween;t.call(n,n,r,Math.max(0,e.timeStart+(null!=e.duration?e.duration:null!=i.duration?i.duration:ve.duration)-vt),void 0!==o?o:String(100*r),e)}catch(e){setTimeout(function(){throw e},1)}}function it(){var e=!0,t=!1,n=void 0;try{for(var r,i=lt[Symbol.iterator]();!(e=(r=i.next()).done);e=!0){rt(r.value)}}catch(e){t=!0,n=e}finally{try{!e&&i.return&&i.return()}finally{if(t)throw n}}lt.clear();var o=!0,a=!1,l=void 0;try{for(var s,u=at[Symbol.iterator]();!(o=(s=u.next()).done);o=!0){Me(s.value)}}catch(e){a=!0,l=e}finally{try{!o&&u.return&&u.return()}finally{if(a)throw l}}at.clear()}var ot=1e3/60,at=new Set,lt=new Set,st=function(){var e=window.performance||{};if("function"!=typeof e.now){var t=e.timing&&e.timing.navigationStart?e.timing.navigationStart:y();e.now=function(){return y()-t}}return e}(),ut=function(e){return setTimeout(e,Math.max(0,ot-(st.now()-vt)))},ct=window.requestAnimationFrame||ut,ft=void 0,dt=void 0,vt=0;try{(dt=new Worker(URL.createObjectURL(new Blob(["("+function(){var e=this,t=void 0;this.onmessage=function(n){switch(n.data){case!0:t||(t=setInterval(function(){e.postMessage(!0)},1e3/30));break;case!1:t&&(clearInterval(t),t=0);break;default:e.postMessage(n.data)}}}+")()"])))).onmessage=function(e){!0===e.data?pt():it()},ke.isMobile||void 0===document.hidden||document.addEventListener("visibilitychange",function(){dt.postMessage(ke.isTicking&&document.hidden)})}catch(e){}function pt(e){if(!ft){if(ft=!0,!1!==e){var t=st.now(),n=vt?t-vt:ot,r=ve.speed,i=ve.easing,o=ve.duration,a=void 0,l=void 0;if(n>=ve.minFrameTime||!vt){for(vt=t;ke.firstNew;)tt(ke.firstNew);for(a=ke.first;a&&a!==ke.firstNew;a=a._next){var s=a.element,u=be(s);if(s.parentNode&&u){var c=a.options,f=a._flags,d=a.timeStart;if(!d){var v=null!=a.queue?a.queue:c.queue;d=t-n,!1!==v&&(d=Math.max(d,u.lastFinishList[v]||0)),a.timeStart=d}16&f?a.timeStart+=n:2&f||(a._flags|=2,c._ready++)}else _e(a)}for(a=ke.first;a&&a!==ke.firstNew;a=l){var p=a._flags;if(l=a._next,2&p&&!(16&p)){var y=a.options;if(32&p&&y._readyt)continue;a.timeStart=h+=m/(m>0?g:1)}a._flags|=4,0==y._started++&&(y._first=a,y.begin&&(nt(a),y.begin=void 0))}1!==g&&(a.timeStart=h+=Math.min(n,t-h)*(1-g));var w=null!=a.easing?a.easing:null!=y.easing?y.easing:i,b=a.ellapsedTime=t-h,S=null!=a.duration?a.duration:null!=y.duration?y.duration:o,x=a.percentComplete=Ut.mock?1:Math.min(b/S,1),O=a.tweens,E=64&p;for(var _ in(a.progress||y._first===a&&y.progress)&<.add(a),1===x&&at.add(a),O){var T=O[_],M=T.sequence,V=M.pattern,q="",N=0;if(V){for(var A=(T.easing||w)(x,0,1,_),L=0,J=0;J=0?r.replace(/^.*\./,""):void 0)&&Q(e[0]),a=ve.queue;if(c(t)&&t.velocity.animations){var l=!0,s=!1,u=void 0;try{for(var f,d=t.velocity.animations[Symbol.iterator]();!(l=(f=d.next()).done);l=!0){ht(f.value,o,a,i)}}catch(e){s=!0,u=e}finally{try{!l&&d.return&&d.return()}finally{if(s)throw u}}}else for(var v=ke.first;v;)t&&!t.includes(v.element)||ht(v,o,a,i),v=v._next;n&&(c(t)&&t.velocity.animations&&t.then?t.then(n._resolver):n._resolver(t))}function wt(t,n,r,i){var o=t[0],a=t[1];if(!o)return console.warn("VelocityJS: Cannot access a non-existant property!"),null;if(void 0===a&&!s(o)){if(Array.isArray(o)){if(1===n.length){var f={},d=!0,v=!1,p=void 0;try{for(var y,g=o[Symbol.iterator]();!(d=(y=g.next()).done);d=!0){var h=y.value;f[h]=Be(Qe(n[0],h))}}catch(e){v=!0,p=e}finally{try{!d&&g.return&&g.return()}finally{if(v)throw p}}return f}var m=[],w=!0,b=!1,S=void 0;try{for(var x,k=n[Symbol.iterator]();!(w=(x=k.next()).done);w=!0){var O=x.value,E={},_=!0,T=!1,M=void 0;try{for(var V,q=o[Symbol.iterator]();!(_=(V=q.next()).done);_=!0){var N=V.value;E[N]=Be(Qe(O,N))}}catch(e){T=!0,M=e}finally{try{!_&&q.return&&q.return()}finally{if(T)throw M}}m.push(E)}}catch(e){b=!0,S=e}finally{try{!w&&k.return&&k.return()}finally{if(b)throw S}}return m}if(1===n.length)return Be(Qe(n[0],o));var A=[],L=!0,J=!1,I=void 0;try{for(var j,C=n[Symbol.iterator]();!(L=(j=C.next()).done);L=!0){var P=j.value;A.push(Be(Qe(P,o)))}}catch(e){J=!0,I=e}finally{try{!L&&C.return&&C.return()}finally{if(J)throw I}}return A}var z=[];if(s(o)){for(var F in o)if(o.hasOwnProperty(F)){var H=!0,R=!1,B=void 0;try{for(var W,$=n[Symbol.iterator]();!(H=(W=$.next()).done);H=!0){var G=W.value,Q=o[F];u(Q)||l(Q)?Ae(G,F,o[F]):(z.push('Cannot set a property "'+F+'" to an unknown type: '+(void 0===Q?"undefined":e(Q))),console.warn('VelocityJS: Cannot set a property "'+F+'" to an unknown type:',Q))}}catch(e){R=!0,B=e}finally{try{!H&&$.return&&$.return()}finally{if(R)throw B}}}}else if(u(a)||l(a)){var D=!0,U=!1,Z=void 0;try{for(var Y,X=n[Symbol.iterator]();!(D=(Y=X.next()).done);D=!0){Ae(Y.value,o,String(a))}}catch(e){U=!0,Z=e}finally{try{!D&&X.return&&X.return()}finally{if(U)throw Z}}}else z.push('Cannot set a property "'+o+'" to an unknown type: '+(void 0===a?"undefined":e(a))),console.warn('VelocityJS: Cannot set a property "'+o+'" to an unknown type:',a);r&&(z.length?r._rejecter(z.join(", ")):c(n)&&n.velocity.animations&&n.then?n.then(r._resolver):r._resolver(n))}function bt(e,t,n){tt(e),void 0!==t&&t!==p(e.queue,e.options.queue,n)||(e._flags|=8,Me(e))}m(["option",function(e,t,n,r){var i=e[0],o=r.indexOf(".")>=0?r.replace(/^.*\./,""):void 0,a="false"!==o&&Q(o,!0),l=void 0,s=e[1];if(!i)return console.warn("VelocityJS: Cannot access a non-existant key!"),null;if(c(t)&&t.velocity.animations)l=t.velocity.animations;else{l=[];for(var u=ke.first;u;u=u._next)t.indexOf(u.element)>=0&&p(u.queue,u.options.queue)===a&&l.push(u);if(t.length>1&&l.length>1){for(var f=1,d=l[0].options;f, "tween", percentComplete, property, end | [end, , ], ) => value\nVelocity(, "tween", percentComplete, {property: end | [end, , ], ...}, ) => {property: value, ...}'),null;t=[document.body],o=!0}var a=e[0],c={elements:t,element:t[0],queue:!1,options:{duration:1e3},tweens:null},f={},d=e[1],v=void 0,y=void 0,g=e[2],h=0;if(u(e[1])?Te&&Te[e[1]]?(y=Te[e[1]],d={},g=e[2]):(v=!0,d=r({},e[1],e[2]),g=e[3]):Array.isArray(e[1])&&(v=!0,d={tween:e[1]},g=e[2]),!l(a)||a<0||a>1)throw new Error("VelocityJS: Must tween a percentage from 0 to 1!");if(!s(d))throw new Error("VelocityJS: Cannot tween an invalid property!");if(o)for(var m in d)if(d.hasOwnProperty(m)&&(!Array.isArray(d[m])||d[m].length<2))throw new Error("VelocityJS: When not supplying an element you must force-feed values: "+m);var b=W(p(g,ve.easing),w);for(var S in y?tn(c,y):Ze(c,d),c.tweens){var x=c.tweens[S],O=x.sequence,E=O.pattern,_="",T=0;if(h++,E){for(var M=(x.easing||b)(a,0,1,S),V=0,q=0;q4;e--){var t=document.createElement("div");if(t.innerHTML="\x3c!--[if IE "+e+"]>100)console.warn("VelocityJS: Trying to use an invalid value as a percentage (0 <= n <= 100):",r,x);else if(isNaN(x))console.warn("VelocityJS: Trying to use an invalid number as a percentage:",r,v,S);else for(var k in o[String(x)]||(o[String(x)]=[]),o[String(x)].push(v),i[v])c.includes(k)||c.push(k)}}catch(e){g=!0,h=e}finally{try{!y&&b.return&&b.return()}finally{if(g)throw h}}}}var O=Object.keys(o).sort(function(e,t){var n=parseFloat(e),r=parseFloat(t);return n>r?1:n1&&(u(ae[1])||Array.isArray(ae[1]))&&(Q[D].easing=W(ae[1],f.duration||w)),Q[D++].percent=parseFloat(ee)/100)}}catch(e){ne=!0,re=e}finally{try{!te&&oe.return&&oe.return()}finally{if(ne)throw re}}}}catch(e){Z=!0,Y=e}finally{try{!U&&K.return&&K.return()}finally{if(Z)throw Y}}f.tweens[A]=Q}}}}catch(e){_=!0,T=e}finally{try{!E&&V.return&&V.return()}finally{if(_)throw T}}}else console.warn("VelocityJS: Trying to set 'registerSequence' sequence to an invalid value:",r,i);else console.warn("VelocityJS: Trying to set 'registerSequence' name to an invalid value:",r)}}],!0);var nn=void 0;try{nn=Promise}catch(e){}var rn=", if that is deliberate then pass `promiseRejectEmpty:false` as an option";function on(e,t){v(t,"promise",e),v(t,"then",e.then.bind(e)),v(t,"catch",e.catch.bind(e)),e.finally&&v(t,"finally",e.finally.bind(e))}function an(){var e,t=ve,n=arguments.length<=0?void 0:arguments[0],r=s(n)&&(n.p||s(n.properties)&&!n.properties.names||u(n.properties)),y=0,g=void 0,m=void 0,w=void 0,b=void 0,S=void 0,x=void 0,k=void 0;(a(this)?g=[this]:f(this)?(g=d(this),c(this)&&(b=this.velocity.animations)):r?(g=d(n.elements||n.e),y++):a(n)?(g=d([n]),y++):f(n)&&(g=d(n),y++),g&&(v(g,"velocity",an.bind(g)),b&&v(g.velocity,"animations",b)),r)?m=p(n.properties,n.p):(e=y++,m=arguments.length<=e?void 0:arguments[e]);var O="reverse"===m,E=!O&&u(m),_=E&&Te[m],T=r?p(n.options,n.o):arguments.length<=y?void 0:arguments[y];if(s(T)&&(w=T),nn&&p(w&&w.promise,t.promise)&&(S=new nn(function(e,t){k=t,x=function(t){c(t)&&t.promise?(delete t.then,delete t.catch,delete t.finally,e(t),on(t.promise,t)):e(t)}}),g&&on(S,g)),S){var M=w&&w.promiseRejectEmpty,V=p(M,t.promiseRejectEmpty);g||E?m||(V?k("Velocity: No properties supplied"+(i(M)?"":rn)+". Aborting."):x()):V?k("Velocity: No elements supplied"+(i(M)?"":rn)+". Aborting."):x()}if(!g&&!E||!m)return S;if(E){for(var q=[],N=S&&{_promise:S,_resolver:x,_rejecter:k};y4;e--){var t=document.createElement("div");if(t.innerHTML="\x3c!--[if IE "+e+"]>2.5)return void this.scrollToLeft(t.scrollLeft+o)}var l=t.clientWidth*this.displacement;this.scrollToLeft(t.scrollLeft+l)},scrollToIndex:function(t){var e=this.children();if(e[t]){var n=this.$refs.container,i=e[t].getBoundingClientRect().left-n.getBoundingClientRect().left;this.scrollToLeft(n.scrollLeft+i)}},scrollToLeft:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"smooth",n=this.$refs.container;n.scrollTo({left:t,behavior:e})},onScroll:function(){var t=this.$refs.container;t&&(this.$emit("scroll",{left:t.scrollLeft}),clearTimeout(this.debounceId),this.debounceId=setTimeout(this.onScrollDebounce,100))},onScrollDebounce:function(){var t=this;this.refresh((function(e){t.$emit("scroll-debounce",e)}))},refresh:function(t){var e=this;this.$nextTick((function(){var n=e.calculate();e.left=n.left,e.width=n.width,e.scrollWidth=n.scrollWidth,e.hasNext=n.hasNext,e.hasPrev=n.hasPrev,null==t||t(n)}))},calculate:function(){var t=this.$refs.container,e=this.children()[0];return{left:t.scrollLeft,width:t.clientWidth,scrollWidth:t.scrollWidth,hasNext:t.scrollWidth>t.scrollLeft+t.clientWidth+2.5,hasPrev:function(){var n,i;if(0===t.scrollLeft)return!1;var o=t.getBoundingClientRect().left,l=null!==(n=null==e||null===(i=e.getBoundingClientRect())||void 0===i?void 0:i.left)&&void 0!==n?n:0;return Math.abs(o-l)>=2.5}()}}}});function o(t,e,n,i,o,l,r,a,s,c){"boolean"!=typeof r&&(s=a,a=r,r=!1);const d="function"==typeof n?n.options:n;let h;if(t&&t.render&&(d.render=t.render,d.staticRenderFns=t.staticRenderFns,d._compiled=!0,o&&(d.functional=!0)),i&&(d._scopeId=i),l?(h=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),e&&e.call(this,s(t)),t&&t._registeredComponents&&t._registeredComponents.add(l)},d._ssrRegister=h):e&&(h=r?function(t){e.call(this,c(t,this.$root.$options.shadowRoot))}:function(t){e.call(this,a(t))}),h)if(d.functional){const t=d.render;d.render=function(e,n){return h.call(n),t(e,n)}}else{const t=d.beforeCreate;d.beforeCreate=t?[].concat(t,h):[h]}return n}const l="undefined"!=typeof navigator&&/msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());function r(t){return(t,e)=>function(t,e){const n=l?e.media||"default":t,i=s[n]||(s[n]={ids:new Set,styles:[]});if(!i.ids.has(t)){i.ids.add(t);let n=e.source;if(e.map&&(n+="\n/*# sourceURL="+e.map.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e.map))))+" */"),i.element||(i.element=document.createElement("style"),i.element.type="text/css",e.media&&i.element.setAttribute("media",e.media),void 0===a&&(a=document.head||document.getElementsByTagName("head")[0]),a.appendChild(i.element)),"styleSheet"in i.element)i.styles.push(n),i.element.styleSheet.cssText=i.styles.filter(Boolean).join("\n");else{const t=i.ids.size-1,e=document.createTextNode(n),o=i.element.childNodes;o[t]&&i.element.removeChild(o[t]),o.length?i.element.insertBefore(e,o[t]):i.element.appendChild(e)}}}(t,e)}let a;const s={};var c=o({render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"vue-horizontal",staticStyle:{position:"relative",display:"flex"}},[t.button&&t.hasPrev?n("div",{staticClass:"v-hl-btn v-hl-btn-prev",class:{"v-hl-btn-between":t.buttonBetween},attrs:{role:"button"},on:{click:function(e){return e.stopPropagation(),t.prev(e)}}},[t._t("btn-prev",[n("svg",{staticClass:"v-hl-svg",attrs:{viewBox:"0 0 24 24","aria-label":"horizontal scroll area navigate to previous button"}},[n("path",{attrs:{d:"m9.8 12 5 5a1 1 0 1 1-1.4 1.4l-5.7-5.7a1 1 0 0 1 0-1.4l5.7-5.7a1 1 0 0 1 1.4 1.4l-5 5z"}})])])],2):t._e(),t._v(" "),t.button&&t.hasNext?n("div",{staticClass:"v-hl-btn v-hl-btn-next",class:{"v-hl-btn-between":t.buttonBetween},attrs:{role:"button"},on:{click:function(e){return e.stopPropagation(),t.next(e)}}},[t._t("btn-next",[n("svg",{staticClass:"v-hl-svg",attrs:{viewBox:"0 0 24 24","aria-label":"horizontal scroll area navigate to next button"}},[n("path",{attrs:{d:"m14.3 12.1-5-5a1 1 0 0 1 1.4-1.4l5.7 5.7a1 1 0 0 1 0 1.4l-5.7 5.7a1 1 0 0 1-1.4-1.4l5-5z"}})])])],2):t._e(),t._v(" "),n("div",{ref:"container",staticClass:"v-hl-container",class:{"v-hl-responsive":t.responsive,"v-hl-scroll":t.scroll,"v-hl-snap-start":"start"===t.snap,"v-hl-snap-center":"center"===t.snap,"v-hl-snap-end":"end"===t.snap},on:{"&scroll":function(e){return t.onScroll(e)}}},[t._t("default")],2)])},staticRenderFns:[]},(function(t){t&&t("data-v-45080727_0",{source:".v-hl-btn[data-v-45080727]{position:absolute;align-self:center;z-index:1;top:0;bottom:0;display:flex;align-items:center;cursor:pointer}.v-hl-btn-prev[data-v-45080727]{left:0}.v-hl-btn-prev.v-hl-btn-between[data-v-45080727]{transform:translateX(-50%)}.v-hl-btn-next[data-v-45080727]{right:0}.v-hl-btn-next.v-hl-btn-between[data-v-45080727]{transform:translateX(50%)}.v-hl-svg[data-v-45080727]{width:40px;height:40px;margin:6px;padding:6px;border-radius:20px;box-sizing:border-box;background:#fff;color:#000;fill:currentColor;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.v-hl-container[data-v-45080727]{display:flex;width:100%;margin:0;padding:0;border:none;box-sizing:content-box;overflow-x:scroll;overflow-y:hidden;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch}.v-hl-container>*[data-v-45080727]{flex-shrink:0;box-sizing:border-box;min-height:1px}.v-hl-snap-start>*[data-v-45080727]{scroll-snap-align:start}.v-hl-snap-center>*[data-v-45080727]{scroll-snap-align:center}.v-hl-snap-end>*[data-v-45080727]{scroll-snap-align:end}.v-hl-container[data-v-45080727]:not(.v-hl-scroll){scrollbar-width:none;-ms-overflow-style:none;padding-bottom:30px;margin-bottom:-30px;clip-path:inset(0 0 30px 0)}.v-hl-container[data-v-45080727]:not(.v-hl-scroll)::-webkit-scrollbar{width:0!important;height:0!important}.v-hl-responsive>*[data-v-45080727]{width:100%;margin-right:24px}.v-hl-responsive[data-v-45080727]>:last-child{margin-right:0}@media (min-width:640px){.v-hl-responsive>*[data-v-45080727]{width:calc((100% - 24px)/ 2)}}@media (min-width:768px){.v-hl-responsive>*[data-v-45080727]{width:calc((100% - 48px)/ 3)}}@media (min-width:1024px){.v-hl-responsive>*[data-v-45080727]{width:calc((100% - 72px)/ 4)}}@media (min-width:1280px){.v-hl-responsive>*[data-v-45080727]{width:calc((100% - 96px)/ 5)}}",map:void 0,media:void 0})}),i,"data-v-45080727",!1,void 0,!1,r,void 0,void 0),d=function(t){d.installed||(d.installed=!0,t.component("VueHorizontal",c))},h={install:d},u=null;return"undefined"!=typeof window?u=window.Vue:"undefined"!=typeof global&&(u=global.Vue),u&&u.use(h),c.install=d,t.default=c,Object.defineProperty(t,"__esModule",{value:!0}),t}({},Vue); \ No newline at end of file diff --git a/src/renderer/js/vue-observe-visibility.min.js b/src/renderer/lib/vue-observe-visibility.min.js similarity index 100% rename from src/renderer/js/vue-observe-visibility.min.js rename to src/renderer/lib/vue-observe-visibility.min.js diff --git a/src/renderer/js/vue.dev.js b/src/renderer/lib/vue.dev.js similarity index 100% rename from src/renderer/js/vue.dev.js rename to src/renderer/lib/vue.dev.js diff --git a/src/renderer/js/vue.js b/src/renderer/lib/vue.js similarity index 100% rename from src/renderer/js/vue.js rename to src/renderer/lib/vue.js diff --git a/src/renderer/js/vuedraggable.umd.min.js b/src/renderer/lib/vuedraggable.umd.min.js similarity index 100% rename from src/renderer/js/vuedraggable.umd.min.js rename to src/renderer/lib/vuedraggable.umd.min.js diff --git a/src/renderer/js/vuex.min.js b/src/renderer/lib/vuex.min.js similarity index 100% rename from src/renderer/js/vuex.min.js rename to src/renderer/lib/vuex.min.js diff --git a/src/renderer/logo-simple.svg b/src/renderer/logo-simple.svg deleted file mode 100644 index 9f78bf50..00000000 --- a/src/renderer/logo-simple.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/renderer/logotmp2.svg b/src/renderer/logotmp2.svg deleted file mode 100644 index 61317b00..00000000 --- a/src/renderer/logotmp2.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/renderer/main/app.js b/src/renderer/main/app.js new file mode 100644 index 00000000..5b4b2e08 --- /dev/null +++ b/src/renderer/main/app.js @@ -0,0 +1,47 @@ +import { app } from "./vueapp.js"; +import { CiderCache } from "./cidercache.js"; +import { CiderFrontAPI } from "./ciderfrontapi.js"; +import { simulateGamepad } from "./gamepad.js"; +import { CiderAudio } from "../audio/cideraudio.js"; +import { Events } from "./events.js"; +import { wsapi } from "./wsapi_interop.js"; +import { MusicKitTools } from "./musickittools.js"; +import { spawnMica } from "./mica.js"; +import { svgIcon } from "./components/svg-icon.js"; +import { sidebarLibraryItem } from "./components/sidebar-library-item.js"; +import { i18nEditor } from "./components/i18n-editor.js"; + +// Define window objects +window.app = app; +window.MusicKitTools = MusicKitTools; +window.CiderAudio = CiderAudio; +window.CiderCache = CiderCache; +window.CiderFrontAPI = CiderFrontAPI; +window.wsapi = wsapi; + +if (app.cfg.advanced.disableLogging === true) { + window.console = { + log: function () {}, + error: function () {}, + warn: function () {}, + assert: function () {}, + debug: function () {}, + }; +} + +// Mount Vue to #app +app.$mount("#app"); + +// Init CiderAudio and force audiocontext +if (app.cfg.advanced.AudioContext != true) { + app.cfg.advanced.AudioContext = true; + window.location.reload(); +} + +CiderAudio.init(); + +// Import gamepad support +app.simulateGamepad = simulateGamepad; +app.spawnMica = spawnMica; + +Events.InitEvents(); diff --git a/src/renderer/main/cidercache.js b/src/renderer/main/cidercache.js new file mode 100644 index 00000000..c7888d88 --- /dev/null +++ b/src/renderer/main/cidercache.js @@ -0,0 +1,24 @@ +const CiderCache = { + async getCache(file) { + let cache = await ipcRenderer.sendSync("get-cache", file); + if (isJson(cache)) { + cache = JSON.parse(cache); + if (Object.keys(cache).length === 0) { + cache = false; + } + } else { + cache = false; + } + return cache; + }, + async putCache(file, data) { + console.log(`Caching ${file}`); + ipcRenderer.invoke("put-cache", { + file: file, + data: JSON.stringify(data), + }); + return true; + }, +}; + +export { CiderCache }; diff --git a/src/renderer/main/ciderfrontapi.js b/src/renderer/main/ciderfrontapi.js new file mode 100644 index 00000000..6b87ad3f --- /dev/null +++ b/src/renderer/main/ciderfrontapi.js @@ -0,0 +1,36 @@ +const CiderFrontAPI = { + Objects: { + MenuEntry: function () { + this.id = ""; + this.name = ""; + this.onClick = () => {}; + this.top = false; + }, + }, + AddMenuEntry(entry) { + if (entry?.top) { + app.pluginMenuTopEntries.push(entry); + } else { + app.pluginMenuEntries.push(entry); + } + app.pluginInstalled = true; + }, + StyleSheets: { + Add(href) { + console.log("Adding stylesheet: " + href); + let id = uuidv4(); + let link = document.createElement("link"); + link.rel = "stylesheet/less"; + link.type = "text/css"; + link.href = href; + link.setAttribute("css-id", id); + // insert the link before document.querySelector("#userTheme") in head + document.querySelector("head").insertBefore(link, document.querySelector("#userTheme")); + less.registerStylesheetsImmediately(); + less.refresh(true, true, true); + return link; + }, + }, +}; + +export { CiderFrontAPI }; diff --git a/src/renderer/main/components/i18n-editor.js b/src/renderer/main/components/i18n-editor.js new file mode 100644 index 00000000..0482fac6 --- /dev/null +++ b/src/renderer/main/components/i18n-editor.js @@ -0,0 +1,78 @@ +import { html } from "../html.js"; + +export const i18nEditor = Vue.component("i18n-editor", { + // language=HTML + template: html` +
+
+
+

i18n Editor

+
+
+ + +
+
+
+
+ +
+
+ `, + data() { + return { + listing: ipcRenderer.sendSync("get-i18n-listing"), + baseLz: ipcRenderer.sendSync("get-i18n", "en_US"), + }; + }, + methods: { + exportLz() { + bootbox.alert(``); + notyf.success("Copied to clipboard"); + navigator.clipboard.writeText(JSON.stringify(app.lz, true, " ")).then((r) => console.debug("Copied to clipboard.")); + }, + getLanguages: function () { + let langs = this.$root.lzListing; + let categories = { + main: [], + fun: [], + unsorted: [], + }; + // sort by category if category is undefined or empty put it in "unsorted" + for (let i = 0; i < langs.length; i++) { + if (langs[i].category === undefined || langs[i].category === "") { + categories.unsorted.push(langs[i]); + } else { + categories[langs[i].category].push(langs[i]); + } + } + // return + return categories; + }, + }, +}); diff --git a/src/renderer/main/components/sidebar-library-item.js b/src/renderer/main/components/sidebar-library-item.js new file mode 100644 index 00000000..e02ba490 --- /dev/null +++ b/src/renderer/main/components/sidebar-library-item.js @@ -0,0 +1,45 @@ +import { html } from "../html.js"; + +export const sidebarLibraryItem = Vue.component("sidebar-library-item", { + template: html` + + `, + props: { + name: { + type: String, + required: true, + }, + page: { + type: String, + required: true, + }, + svgIcon: { + type: String, + required: false, + default: "", + }, + svgIconName: { + type: String, + required: false, + }, + cdClick: { + type: Function, + required: false, + }, + }, + data: function () { + return { + app: app, + svgIconData: "", + }; + }, + async mounted() { + if (this.svgIcon) { + this.svgIconData = this.svgIcon; + } + }, + methods: {}, +}); diff --git a/src/renderer/main/components/svg-icon.js b/src/renderer/main/components/svg-icon.js new file mode 100644 index 00000000..b2c197dc --- /dev/null +++ b/src/renderer/main/components/svg-icon.js @@ -0,0 +1,20 @@ +import { html } from "../html.js"; + +export const svgIcon = Vue.component("svg-icon", { + template: html`
`, + props: { + name: { + type: String, + required: false, + }, + classes: { + type: String, + required: false, + }, + url: { + type: String, + required: true, + default: "./assets/repeat.svg", + }, + }, +}); diff --git a/src/renderer/main/events.js b/src/renderer/main/events.js new file mode 100644 index 00000000..d90b54c2 --- /dev/null +++ b/src/renderer/main/events.js @@ -0,0 +1,111 @@ +const Events = { + InitEvents() { + const app = window.app; + + // add event listener for when window.location.hash changes + window.addEventListener("hashchange", function () { + app.page = "blank"; + setTimeout(() => { + app.appRoute(window.location.hash); + }, 100); + }); + + window.addEventListener("mouseup", (e) => { + if (e.button === 3) { + e.preventDefault(); + app.navigateBack(); + } else if (e.button === 4) { + e.preventDefault(); + app.navigateForward(); + } + }); + + document.addEventListener("keydown", async function (event) { + // CTRL + R + if (event.keyCode === 82 && event.ctrlKey) { + event.preventDefault(); + app.confirm(app.getLz("term.reload"), (res) => { + if (res) { + window.location.reload(); + } + }); + } + // CTRL + SHIFT + R + if (event.keyCode === 82 && event.ctrlKey && event.shiftKey) { + event.preventDefault(); + window.location.reload(); + } + // CTRL + E + if (event.keyCode === 69 && event.ctrlKey) { + app.invokeDrawer("queue"); + } + // CTRL+H + if (event.keyCode === 72 && event.ctrlKey) { + app.appRoute("home"); + } + // CTRL+SHIFT+H + if (event.ctrlKey && event.shiftKey && event.keyCode == 72) { + let hist = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`, { + l: app.mklang, + }); + app.showCollection(hist.data, app.getLz("term.history")); + } + // CTRL+F10 + if (event.ctrlKey && event.keyCode == 121) { + try { + app.mk._services.mediaItemPlayback._currentPlayer.stop(); + } catch (e) {} + try { + app.mk._services.mediaItemPlayback._currentPlayer.destroy(); + } catch (e) {} + try { + this.radiohls.destroy(); + this.radiohls = null; + } catch (_) {} + try { + let searchInt = setInterval(function () { + if (document.getElementById("apple-music-player")) { + //AudioOutputs.eqReady = true; + document.getElementById("apple-music-player").crossOrigin = "anonymous"; + CiderAudio.source = CiderAudio.context.createMediaElementSource(document.getElementById("apple-music-player")); + CiderAudio.source.connect(CiderAudio.audioNodes.intelliGainComp); + clearInterval(searchInt); + } + }, 1000); + } catch (e) {} + } + // CTRL+F11 + if (event.ctrlKey && event.keyCode == 122) { + try { + ipcRenderer.send("detachDT", ""); + } catch (e) {} + } + // Prevent Scrolling on spacebar + if (event.keyCode === 32 && event.target === document.body) { + event.preventDefault(); + app.SpacePause(); + } + }); + + // Hang Timer + app.hangtimer = setTimeout(() => { + if (confirm("Cider is not responding. Reload the app?")) { + window.location.reload(); + } + }, 10000); + + // Refresh Focus + function refreshFocus() { + if (document.hasFocus() == false) { + app.windowFocus(false); + } else { + app.windowFocus(true); + } + setTimeout(refreshFocus, 200); + } + + refreshFocus(); + }, +}; + +export { Events }; diff --git a/src/renderer/main/gamepad.js b/src/renderer/main/gamepad.js new file mode 100644 index 00000000..d27700da --- /dev/null +++ b/src/renderer/main/gamepad.js @@ -0,0 +1,313 @@ +function simulateGamepad() { + const app = window.app; + app.chrome.showCursor = true; + let cursorPos = [0, 0]; + let intTabIndex = 0; + const cursorSpeedPvt = 8; + const cursorSize = 16; + let scrollSpeed = 8; + let buttonPressDelay = 500; + let stickDeadZone = 0.2; + let scrollGroup = null; + let scrollGroupY = null; + let elementFocusEnabled = true; + let start; + + let cursorSpeed = cursorSpeedPvt; + + let lastButtonPress = {}; + + var sounds = { + Confirm: new Audio("./sounds/confirm.ogg"), + Menu: new Audio("./sounds/btn1.ogg"), + Hover: new Audio("./sounds/hover.ogg"), + }; + + let element = document.elementFromPoint(0, 0); + let elementType = 0; + + function appLoop() { + var gamepads = navigator.getGamepads ? navigator.getGamepads() : navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []; + if (!gamepads) { + return; + } + + var gp = gamepads[0]; + + // LEFT STICK + if (gp.axes[0] > stickDeadZone) { + cursorPos[0] += gp.axes[0] * cursorSpeed; + } else if (gp.axes[0] < -stickDeadZone) { + cursorPos[0] += gp.axes[0] * cursorSpeed; + } + + if (gp.axes[1] > stickDeadZone) { + cursorPos[1] += gp.axes[1] * cursorSpeed; + } else if (gp.axes[1] < -stickDeadZone) { + cursorPos[1] += gp.axes[1] * cursorSpeed; + } + + if (cursorPos[0] < cursorSize) { + cursorPos[0] = cursorSize; + } + if (cursorPos[1] < cursorSize) { + cursorPos[1] = cursorSize; + } + if (cursorPos[0] > window.innerWidth - cursorSize) { + cursorPos[0] = window.innerWidth - cursorSize; + } + if (cursorPos[1] > window.innerHeight - cursorSize) { + cursorPos[1] = window.innerHeight - cursorSize; + } + + // RIGHT STICK. + if (scrollGroupY) { + if (gp.axes[3] > stickDeadZone) { + $(scrollGroupY).scrollTop($(scrollGroupY).scrollTop() + gp.axes[3] * scrollSpeed); + elementFocusEnabled = false; + } else if (gp.axes[3] < -stickDeadZone) { + $(scrollGroupY).scrollTop($(scrollGroupY).scrollTop() + gp.axes[3] * scrollSpeed); + elementFocusEnabled = false; + } else { + elementFocusEnabled = true; + } + } + + if (scrollGroup) { + if (gp.axes[2] > stickDeadZone) { + $(scrollGroup).scrollLeft($(scrollGroup).scrollLeft() + gp.axes[2] * scrollSpeed); + elementFocusEnabled = false; + } else if (gp.axes[2] < -stickDeadZone) { + $(scrollGroup).scrollLeft($(scrollGroup).scrollLeft() + gp.axes[2] * scrollSpeed); + elementFocusEnabled = false; + } else { + elementFocusEnabled = true; + } + } + + $(".cursor").css({ + top: cursorPos[1] + "px", + left: cursorPos[0] + "px", + display: "block", + }); + + // A BUTTON + if (gp.buttons[0].pressed) { + if (!lastButtonPress["A"]) { + lastButtonPress["A"] = 0; + } + if (Date.now() - lastButtonPress["A"] > buttonPressDelay) { + lastButtonPress["A"] = Date.now(); + sounds.Confirm.play(); + if (elementType == 0) { + document.activeElement.dispatchEvent(new Event("click")); + document.activeElement.dispatchEvent(new Event("controller-click")); + } else { + element.dispatchEvent(new Event("click")); + element.dispatchEvent(new Event("controller-click")); + } + } + } + + // B BUTTON + if (gp.buttons[1].pressed) { + if (!lastButtonPress["B"]) { + lastButtonPress["B"] = 0; + } + if (Date.now() - lastButtonPress["B"] > buttonPressDelay) { + lastButtonPress["B"] = Date.now(); + if (elementType == 0) { + document.activeElement.dispatchEvent(new Event("contextmenu")); + setTimeout(() => { + if ($(".menu-option").length > 0) { + let bounds = $(".menu-option")[0].getBoundingClientRect(); + cursorPos[0] = bounds.left + bounds.width / 2; + cursorPos[1] = bounds.top + bounds.height / 2; + } + }, 100); + } else { + element.dispatchEvent(new Event("contextmenu")); + } + } + } + + // right bumper + if (gp.buttons[5].pressed) { + if (!lastButtonPress["RB"]) { + lastButtonPress["RB"] = 0; + } + if (Date.now() - lastButtonPress["RB"] > buttonPressDelay) { + lastButtonPress["RB"] = Date.now(); + app.navigateForward(); + } + } + + // left bumper + if (gp.buttons[4].pressed) { + if (!lastButtonPress["LB"]) { + lastButtonPress["LB"] = 0; + } + if (Date.now() - lastButtonPress["LB"] > buttonPressDelay) { + lastButtonPress["LB"] = Date.now(); + app.navigateBack(); + } + } + + // cursor hover + if (elementFocusEnabled) { + element = document.elementFromPoint(cursorPos[0], cursorPos[1]); + } + + if (element) { + let closest = element.closest("[tabindex], input, button, a"); + + // VERT SCROLL + let scrollGroupCloY = element.closest(`[scrollaxis="y"]`); + if (scrollGroupCloY) { + scrollGroupY = scrollGroupCloY; + } + + // HOZ SCROLL + let scrollGroupClo = element.closest(".v-hl-container"); + + if (scrollGroupClo) { + if (scrollGroupClo.classList.contains("v-hl-container")) { + scrollGroup = scrollGroupClo; + scrollGroup.style["scroll-snap-type"] = "unset"; + } else { + scrollGroup.style["scroll-snap-type"] = ""; + scrollGroup = null; + } + } + + if (closest) { + elementType = 0; + closest.focus(); + } else { + if (closest) { + closest.blur(); + } + elementType = 1; + element.focus(); + } + cursorSpeed = cursorSpeedPvt; + if (!element.classList.contains("app-chrome") && !element.classList.contains("app-content")) { + cursorSpeed = cursorSpeedPvt; + } + // console.log($._data($(element), "events")) + } else { + cursorSpeed = 12; + } + // console.log(gp.axes[0], gp.axes[1]) + start = requestAnimationFrame(appLoop); + } + + // controller pairing + notyf.error("Press the button on your controller to pair it to Cider."); + window.addEventListener( + "gamepadconnected", + function (e) { + console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.", e.gamepad.index, e.gamepad.id, e.gamepad.buttons.length, e.gamepad.axes.length); + notyf.success("Pairing successful!"); + appLoop(); + }, + { once: true }, + ); + + document.addEventListener("keydown", (e) => { + sounds.Confirm.currentTime = 0; + sounds.Menu.currentTime = 0; + sounds.Hover.currentTime = 0; + let tabbable = $("[tabindex]"); + console.log(e.key); + switch (e.key) { + default: + break; + case "ArrowLeft": + e.preventDefault(); + + cursorPos[0] -= cursorSpeed; + break; + case "ArrowRight": + e.preventDefault(); + + cursorPos[0] += cursorSpeed; + break; + case "ArrowUp": + e.preventDefault(); + + cursorPos[1] -= cursorSpeed; + // sounds.Hover.play() + // if (intTabIndex <= 0) { + // intTabIndex = 0 + // } else { + // intTabIndex-- + // } + // $(tabbable[intTabIndex]).focus() + // $("#app-content").scrollTop($(document.activeElement).offset().top) + break; + case "ArrowDown": + e.preventDefault(); + + cursorPos[1] += cursorSpeed; + // if (intTabIndex < tabbable.length) { + // intTabIndex++ + // } else { + // intTabIndex = tabbable.length + // } + // $(tabbable[intTabIndex]).focus() + // $("#app-content").scrollTop($(document.activeElement).offset().top) + break; + case "c": + app.resetState(); + break; + case "x": + // set cursorPos to the top right of the screen + // sounds.Menu.play() + if (elementType == 0) { + document.activeElement.dispatchEvent(new Event("contextmenu")); + } else { + element.dispatchEvent(new Event("contextmenu")); + } + + e.preventDefault(); + break; + case "z": + sounds.Confirm.play(); + if (elementType == 0) { + document.activeElement.dispatchEvent(new Event("click")); + document.activeElement.dispatchEvent(new Event("controller-click")); + } else { + element.dispatchEvent(new Event("click")); + element.dispatchEvent(new Event("controller-click")); + } + + e.preventDefault(); + break; + } + + $(".cursor").css({ + top: cursorPos[1] + "px", + left: cursorPos[0] + "px", + }); + function lerp(a, b, n) { + return (1 - n) * a + n * b; + } + + element = document.elementFromPoint(cursorPos[0], cursorPos[1]); + + if (element) { + let closest = element.closest("[tabindex], input, button, a"); + if (closest) { + elementType = 0; + closest.focus(); + } else { + elementType = 1; + element.focus(); + } + } + console.log(element); + }); +} + +export { simulateGamepad }; diff --git a/src/renderer/main/html.js b/src/renderer/main/html.js new file mode 100644 index 00000000..f705b412 --- /dev/null +++ b/src/renderer/main/html.js @@ -0,0 +1,3 @@ +export function html(str) { + return str[0]; +} diff --git a/src/renderer/main/mica.js b/src/renderer/main/mica.js new file mode 100644 index 00000000..dcd55fae --- /dev/null +++ b/src/renderer/main/mica.js @@ -0,0 +1,88 @@ +import { CiderCache } from "./cidercache.js"; + +async function spawnMica() { + if (typeof window.micaSpawned !== "undefined") { + return; + } else { + window.micaSpawned = true; + } + const micaDiv = document.createElement("div"); + const blurIterations = 6; + micaDiv.id = "micaEffect"; + micaDiv.style.position = "fixed"; + micaDiv.style.top = "0"; + micaDiv.style.left = "0"; + micaDiv.style.right = "0"; + micaDiv.style.bottom = "0"; + micaDiv.style.zIndex = -1; + + let lastScreenX; + let lastScreenY; + let lastScreenWidth; + let lastScreenHeight; + + let imgSrc = ""; + let micaCache = await CiderCache.getCache("mica-cache"); + if (!micaCache) { + micaCache = { + path: "", + data: "", + }; + } + if (micaCache.path == imgSrc.path) { + imgSrc = micaCache; + } else { + imgSrc = await ipcRenderer.sendSync("get-wallpaper", { + blurAmount: 256, + }); + CiderCache.putCache("mica-cache", imgSrc); + } + let canvas = document.createElement("canvas"); + let ctx = canvas.getContext("2d"); + let img = new Image(); + micaDiv.style.backgroundImage = `url(${imgSrc.data})`; + document.body.appendChild(micaDiv); + + function onScreenMove(cb) { + function detectScreenMove() { + if (lastScreenY !== window.screenY || lastScreenX !== window.screenX) { + lastScreenY = window.screenY; + lastScreenX = window.screenX; + cb(); + } + // window size change + if (lastScreenWidth !== window.innerWidth || lastScreenHeight !== window.innerHeight) { + lastScreenWidth = window.innerWidth; + lastScreenHeight = window.innerHeight; + cb(); + } + if (true) { + requestAnimationFrame(detectScreenMove); + } + } + + if (true) { + requestAnimationFrame(detectScreenMove); + } + } + + onScreenMove(function () { + const screenHeight = window.screen.height; + const screenWidth = window.screen.width; + const windowHeight = window.innerHeight; + const windowWidth = window.innerWidth; + const ratio = windowWidth / windowHeight; + const x = window.screenX; + const y = window.screenY; + micaDiv.style.backgroundSize = `${screenWidth}px ${screenHeight}px`; + // micaDiv.style.backgroundPosition = `-${x}px -${y}px`; + if (x < 0) { + micaDiv.style.backgroundPosition = `${screenWidth + x}px -${y}px`; + } else { + micaDiv.style.backgroundPosition = `-${x}px -${y}px`; + } + }); + return true; +} + +export { spawnMica }; diff --git a/src/renderer/main/musickittools.js b/src/renderer/main/musickittools.js new file mode 100644 index 00000000..2392fe58 --- /dev/null +++ b/src/renderer/main/musickittools.js @@ -0,0 +1,44 @@ +const MusicKitTools = { + async v3Backend({ route = "", getBody = {}, options = {} }) { + return await await ipcRenderer.invoke("mkv3", { + token: MusicKit.getInstance().developerToken, + route: route, + mediaToken: MusicKit.getInstance().musicUserToken, + GETBody: getBody, + }); + }, + async v3Continuous({ href, options = {}, reqOptions = {}, onProgress = () => {}, onError = () => {}, onSuccess = () => {} } = {}) { + let returnData = []; + + async function sendReq(href, options) { + const response = await app.mk.api.v3.music(href, options).catch((error) => onError); + + returnData = returnData.concat(response.data.data); + if (response.data.next) { + onProgress({ + response: response, + total: returnData.length, + }); + try { + await sendReq(response.data.next, options); + } catch (e) { + await sendReq(response.data.next, options); + } + } + } + + await sendReq(href, options); + onSuccess(returnData); + return returnData; + }, + getHeader() { + return new Headers({ + Authorization: "Bearer " + MusicKit.getInstance().developerToken, + Accept: "application/json", + "Content-Type": "application/json", + "Music-User-Token": "" + MusicKit.getInstance().musicUserToken, + }); + }, +}; + +export { MusicKitTools }; diff --git a/src/renderer/main/vueapp.js b/src/renderer/main/vueapp.js new file mode 100644 index 00000000..3af24c4e --- /dev/null +++ b/src/renderer/main/vueapp.js @@ -0,0 +1,5363 @@ +import { store } from "./vuex-store.js"; + +Vue.use(VueHorizontal); +Vue.use(VueObserveVisibility); +Vue.use(BootstrapVue); +/* @namespace */ +const app = new Vue({ + store: store, + data: { + version: ipcRenderer.sendSync("get-version"), + appMode: "player", + ipcRenderer: ipcRenderer, + cfg: ipcRenderer.sendSync("getStore"), + isDev: ipcRenderer.sendSync("is-dev"), + clientPort: ipcRenderer.sendSync("get-port"), + drawertest: false, + platform: "", + mk: {}, + pluginInstalled: false, + pluginMenuEntries: [], + pluginMenuTopEntries: [], + lz: ipcRenderer.sendSync("get-i18n", "en"), + lzListing: ipcRenderer.sendSync("get-i18n-listing"), + radiohls: null, + search: { + term: "", + cursor: -1, + hints: [], + showHints: false, + showSearchView: false, + results: {}, + resultsSocial: {}, + resultsLibrary: {}, + limit: 10, + }, + fullscreenLyrics: false, + fullscreenState: ipcRenderer.sendSync("getFullScreen"), + playerLCD: { + playbackDuration: 0, + desiredDuration: 0, + userInteraction: false, + }, + drawer: { + open: false, + panel: "", + }, + browsepage: [], + listennow: [], + madeforyou: [], + radio: [], + mklang: "en", + webview: { + url: "", + title: "", + loading: false, + }, + showingPlaylist: [], + appleCurator: [], + multiroom: [], + artistPage: { + data: {}, + }, + library: { + backgroundNotification: { + show: false, + message: "", + total: 0, + progress: 0, + }, + songs: { + sortingOptions: { + albumName: "0", + artistName: "0", + name: "0", + genre: "0", + releaseDate: "0", + durationInMillis: "0", + dateAdded: "0", + }, + sorting: "name", + sortOrder: "asc", + listing: [], + meta: { total: 0, progress: 0 }, + search: "", + displayListing: [], + downloadState: 0, // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library + }, + albums: { + sortingOptions: { + artistName: "0", + name: "0", + genre: "0", + releaseDate: "0", + }, + viewAs: "covers", + sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page + sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page + listing: [], + meta: { total: 0, progress: 0 }, + search: "", + displayListing: [], + downloadState: 0, // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library + }, + artists: { + sortingOptions: { + artistName: "0", + name: "0", + genre: "0", + releaseDate: "0", + }, + viewAs: "covers", + sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page + sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page + listing: [], + meta: { total: 0, progress: 0 }, + search: "", + displayListing: [], + downloadState: 0, // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library + }, + localsongs: [], + }, + playlists: { + listing: [], + details: {}, + loadingState: 0, // 0 loading, 1 loaded, 2 error + id: "", + trackMapping: {}, + }, + webremoteurl: "", + webremoteqr: "", + mxmtoken: "", + mkIsReady: false, + animateBackground: false, + currentArtUrl: "", + currentArtUrlRaw: "", + mvViewMode: "full", + lyricon: false, + currentTrackID: "", + lyrics: [], + currentLyricsLine: 0, + richlyrics: [], + lyricsMediaItem: {}, + lyricsDebug: { + current: 0, + start: 0, + end: 0, + }, + lyricOffset: 0, + v3: { + requestBody: { + platform: "web", + }, + }, + tmpHeight: "", + tmpWidth: "", + tmpX: "", + tmpY: "", + miniTmpX: "", + miniTmpY: "", + tmpVar: [], + notification: false, + hintscontext: false, + chrome: { + sidebarCollapsed: false, + nativeControls: false, + contentScrollPosY: 0, + appliedTheme: { + location: "", + info: {}, + }, + windowState: "normal", + desiredPageTransition: "wpfade_transform", + hideUserInfo: ipcRenderer.sendSync("is-dev") || false, + artworkReady: false, + userinfo: { + id: "", + attributes: { + name: "Cider User", + handle: "CiderUser", + artwork: { url: "./assets/logocut.png" }, + }, + }, + forceDirectives: {}, + menuOpened: false, + maximized: false, + drawerOpened: false, + drawerState: "queue", + topChromeVisible: true, + progresshover: false, + windowControlPosition: "right", + contentAreaScrolling: true, + showCursor: false, + noC2Upgrade: localStorage.getItem("noC2Upgrade") == "true" ? true : false, + }, + collectionList: { + response: {}, + title: "", + type: "", + }, + MVsource: null, + currentSongInfo: {}, + page: "", + pageHistory: [], + songstest: false, + hangtimer: null, + selectedMediaItems: [], + routes: ["browse", "listen_now", "radio"], + musicBaseUrl: "https://api.music.apple.com/", + modals: { + addToPlaylist: false, + spatialProperties: false, + qrcode: false, + equalizer: false, + audioSettings: false, + pluginMenu: false, + audioControls: false, + audioPlaybackRate: false, + showPlaylist: false, + castMenu: false, + pathMenu: false, + moreInfo: false, + airplayPW: false, + settings: false, + c2Upgrade: false, + }, + socialBadges: { + badgeMap: {}, + version: "", + mediaItems: [], + mediaItemDLState: 0, // 0 = not started, 1 = in progress, 2 = complete + }, + menuPanel: { + visible: false, + event: null, + content: { + name: "", + items: {}, + headerItems: {}, + }, + }, + pauseButtonTimer: null, + activeCasts: [], + pluginPages: { + page: "hello-world", + pages: [], + }, + moreinfodata: [], + notyf: notyf, + idleTimer: null, + idleState: false, + appVisible: true, + currentAirPlayCodeID: "", + airplayTrys: [], + }, + watch: { + cfg: { + handler: function (val, oldVal) { + console.debug(`Config changed: ${JSON.stringify(val)}`); + ipcRenderer.send("setStore", val); + }, + deep: true, + }, + "cfg.connectivity.discord_rpc.enabled"(newValue) { + ipcRenderer.send("discordrpc:reload", newValue); + }, + "mk.privateEnabled"(newValue) { + ipcRenderer.send("onPrivacyModeChange", newValue); + }, + page: () => { + // document.getElementById("app-content").scrollTo(0, 0); + app.resetState(); + }, + showingPlaylist: () => { + if (!app.modals.showPlaylist) { + // document.getElementById("app-content").scrollTo(0, 0); + app.resetState(); + } + }, + artistPage: () => { + // document.getElementById("app-content").scrollTo(0, 0); + app.resetState(); + }, + }, + mounted() { + window.addEventListener( + "hashchange", + function (event) { + let currentPath = window.location.hash.slice(1); + console.debug("hashchange", currentPath); + }, + false, + ); + }, + methods: { + _fetch(url, opts = {}) { + if (app.cfg.advanced.experiments.includes("cider_mirror") === true) { + if (url.includes("api.github.com/")) { + return fetch(url.replace("api.github.com/", "mirror.api.cider.sh/v2/api/"), opts); + } else if (url.includes("raw.githubusercontent.com/")) { + return fetch(url.replace("raw.githubusercontent.com/", "mirror.api.cider.sh/v2/raw/"), opts); + } else { + return fetch(url, opts); + } + } else { + return fetch(url, opts); + } + }, + setWindowHash(route = "") { + this.setPagePos(); + window.location.hash = `#${route}`; + }, + monitorMusickit() { + if (!app.cfg.musickit) return; + + for (const [attr, value] of Object.entries(app.cfg.musickit["stored-attributes"])) { + console.log(`Musickit value: ` + app.mk[attr]); + console.log(`Config value: ` + value); + if (value !== "" && app.mk[attr] !== value) { + app.mk[attr] = value; + } + this.$watch(`mk.${attr}`, (val) => { + console.log(`MK ${attr} changed to ${val}`); + app.cfg.musickit["stored-attributes"][attr] = val; + }); + } + const ERROR_CODES = ["drmUnsupported", "mediaPlaybackError"]; + /* MusicKit.Events */ + ERROR_CODES.forEach((code) => { + MusicKit.getInstance().addEventListener(MusicKit.Events[code], (e) => { + console.error(`[MusicKit] MusicKit Error ${code}`); + console.error({ e: e }); + app.notyf.open({ + duration: 20000, + type: "error", + className: "notyf-info", + message: `${app.getLz("error.musickitError")} \n${code.toUpperCase()}`, + }); + }); + }); + }, + async oobeInit() { + this.appMode = "oobe"; + for (const [k, v] of Object.entries(ipcRenderer.sendSync("get-i18n-listing"))) { + if (v.code === navigator.language.replace("-", "_")) { + this.cfg.general.language = v.code; + break; + } + } + this.setLz(this.cfg.general.language); + this.setLzManual(); + clearTimeout(this.hangtimer); + document.body.removeAttribute("loading"); + ipcRenderer.invoke("renderer-ready", true); + document.querySelector("#LOADER").remove(); + + ipcRenderer.on("recv-cookies", function (_event, cookies) { + console.log("[appIPC] recv-cookies"); + Object.keys(cookies).forEach((key) => { + localStorage.setItem(key, cookies[key]); + }); + localStorage.setItem("seenOOBE", 1); + window.location.reload(); + }); + }, + getAppStyle() { + let finalStyle = {}; + if (this.cfg.visual.window_background_style === "color") { + finalStyle["background-color"] = this.cfg.visual.windowColor; + } + if (this.cfg.visual.customAccentColor) { + finalStyle["--keyColor"] = this.cfg.visual.accentColor; + finalStyle["--songProgressColor"] = this.cfg.visual.accentColor; + } else if (this.cfg.visual.purplePodcastPlaybackBar && MusicKit.getInstance().nowPlayingItem?.type == "podcast-episodes") { + finalStyle["--songProgressColor"] = "#6929D0"; + } + return finalStyle; + }, + setTimeout(func, time) { + return setTimeout(func, time); + }, + songLinkShare(amUrl) { + notyf.open({ + type: "info", + className: "notyf-info", + message: app.getLz("term.song.link.generate"), + }); + let self = this; + let httpRequest = new XMLHttpRequest(); + httpRequest.open("GET", `https://api.song.link/v1-alpha.1/links?url=${amUrl}&userCountry=US`, true); + httpRequest.send(); + httpRequest.onreadystatechange = function () { + if (httpRequest.readyState === 4) { + if (httpRequest.status === 200) { + let response = JSON.parse(httpRequest.responseText); + console.debug(response); + self.copyToClipboard(response.pageUrl); + } else { + console.warn("There was a problem with the request."); + notyf.error(app.getLz("term.requestError")); + } + } + }; + }, + formatVolumeTooltip() { + let advancedTooltip = this.cfg.audio.dBSPL ? (Number(this.cfg.audio.dBSPLcalibration) + Math.log10(this.mk.volume) * 20).toFixed(2) + " dB SPL" : (Math.log10(this.mk.volume) * 20).toFixed(2) + " dBFS"; + return this.cfg.audio.advanced ? advancedTooltip : (this.mk.volume * 100).toFixed(0) + "%"; + }, + mainMenuVisibility(val) { + if (val) { + this.mk.isAuthorized ? (this.chrome.menuOpened = !this.chrome.menuOpened) : false; + if (!this.mk.isAuthorized) { + ipcRenderer.send("auth-window"); + } + } else { + setTimeout(() => { + this.chrome.menuOpened = false; + }, 100); + } + }, + stringTemplateParser(expression, valueObj) { + const templateMatcher = /{{\s?([^{}\s]*)\s?}}/g; + let text = expression.replace(templateMatcher, (substring, value, index) => { + value = valueObj[value]; + return value; + }); + return text; + // stringTemplateParser('my name is {{name}} and age is {{age}}', {name: 'Tom', age:100}) + }, + async setLz(lang) { + if (lang == "") { + lang = this.cfg.general.language; + } + this.lz = ipcRenderer.sendSync("get-i18n", lang); + this.mklang = await this.MKJSLang(); + try { + this.listennow.timestamp = 0; + this.browsepage.timestamp = 0; + this.radio.timestamp = 0; + } catch (e) {} + }, + /** + * Grabs translation for localization. + * @param {string} message - The key to grab the translated term + * @param {object} options - Optional options + * @author booploops#7139 + * @memberOf app + */ + getLz(message, options = {}) { + if (this.lz[message]) { + if (options["count"]) { + if (typeof this.lz[message] === "object") { + let type = window.fastPluralRules.getPluralFormNameForCardinalByLocale(this.cfg.general.language.replace("_", "-"), options["count"]); + return this.lz[message][type] ?? this.lz[message][Object.keys(this.lz[message])[0]] ?? this.lz[message]; + } else { + // fallback English plural forms ( old i18n ) + if (options["count"] > 1) { + return this.lz[message + "s"] ?? this.lz[message]; + } else { + return this.lz[message] ?? this.lz[message + "s"]; + } + } + } else if (typeof this.lz[message] === "object") { + return this.lz[message][Object.keys(this.lz[message])[0]]; + } + return this.lz[message]; + } else { + return message; + } + }, + getProfileLz(type, name) { + // For Spatial and CAR. + let result = ""; + + // Hard-coded shiz + switch (name) { + case "Maikiwi": + return "Maikiwi"; + break; + + case "Maikiwi+": + return "Maikiwi+"; + break; + + case "Minimal+": + return this.getLz("settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal") + "+"; + break; + + case "live": + return "LIVE"; + break; + } + switch (type) { + case "CAR": + result = this.getLz("settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode." + name); + if (result === "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode." + name) { + return name; + } else { + return result; + } + break; + case "CTS": + result = this.getLz("settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile." + name.toLowerCase()); + if (result === "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile." + name.toLowerCase()) { + return name; + } else { + return result; + } + break; + default: + return name; + } + }, + setLzManual() { + app.$data.library.songs.sortingOptions = { + albumName: app.getLz("term.sortBy.album"), + artistName: app.getLz("term.sortBy.artist"), + name: app.getLz("term.sortBy.name"), + genre: app.getLz("term.sortBy.genre"), + releaseDate: app.getLz("term.sortBy.releaseDate"), + durationInMillis: app.getLz("term.sortBy.duration"), + dateAdded: app.getLz("term.sortBy.dateAdded"), + }; + + app.$data.library.albums.sortingOptions = { + artistName: app.getLz("term.sortBy.artist"), + name: app.getLz("term.sortBy.name"), + genre: app.getLz("term.sortBy.genre"), + releaseDate: app.getLz("term.sortBy.releaseDate"), + dateAdded: app.getLz("term.sortBy.dateAdded"), + }; + + app.$data.library.artists.sortingOptions = { + artistName: app.getLz("term.sortBy.artist"), + name: app.getLz("term.sortBy.name"), + genre: app.getLz("term.sortBy.genre"), + releaseDate: app.getLz("term.sortBy.releaseDate"), + }; + + this.lz.repeat = { + 0: this.lz["term.repeat.all"] ?? this.lz["term.repeat"], + 1: this.lz["term.repeat.none"] ?? this.lz["term.disableRepeat"], + 2: this.lz["term.repeat.one"] ?? this.lz["term.enableRepeatOne"], + }; + }, + async showSocialListeningTo() { + let contentIds = Object.keys(app.socialBadges.badgeMap); + app.showCollection({ data: this.socialBadges.mediaItems }, "Friends Listening To", "albums"); + if (this.socialBadges.mediaItemDLState == 1 || this.socialBadges.mediaItemDLState == 2) { + return; + } + this.socialBadges.mediaItemDLState = 2; + await asyncForEach(contentIds, async (item) => { + try { + let type = "albums"; + if (item.includes("pl.")) { + type = "playlists"; + } + if (item.includes("ra.")) { + type = "stations"; + } + let found = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${type}/${item}`); + this.socialBadges.mediaItems.push(found.data.data[0]); + } catch (e) {} + }); + }, + quit() { + ipcRenderer.invoke("quit-app"); + }, + async openAppleMusicURL(url) { + let properties = MusicKit.formattedMediaURL(url); + let item = { + id: properties.contentId, + attributes: { + playParams: { + id: properties.contentId, + kind: properties.kind, + }, + }, + type: properties.kind, + kind: properties.kind, + }; + app.routeView(item); + }, + saveFile(fileName, urlFile) { + let a = document.createElement("a"); + a.style = "display: none"; + document.body.appendChild(a); + a.href = urlFile; + a.download = fileName; + a.click(); + window.URL.revokeObjectURL(url); + a.remove(); + }, + async showMenuPanel(data, event) { + app.menuPanel.visible = true; + app.menuPanel.content.name = data.name ?? ""; + app.menuPanel.content.items = data.items ?? {}; + app.menuPanel.content.headerItems = data.headerItems ?? {}; + if (event) { + app.menuPanel.event = event; + } + }, + async getSvgIcon(url) { + let response = await fetch(url); + let data = await response.text(); + return data; + }, + getSocialBadges(cb = () => {}) { + let self = this; + try { + app.mk.api.v3.music("/v1/social/badging-map").then((data) => { + self.socialBadges.badgeMap = data.data.results.badgingMap; + cb(data.data.results.badgingMap); + }); + } catch (ex) { + this.socialBadges.badgeMap = {}; + } + }, + addFavorite(id, type) { + this.cfg.home.favoriteItems.push({ + id: id, + type: type, + }); + }, + modularUITest(val = false) { + this.fullscreenLyrics = val; + if (val) { + document.querySelector("#app-main").classList.add("modular-fs"); + } else { + document.querySelector("#app-main").classList.remove("modular-fs"); + } + }, + navigateBack() { + this.setPagePos(); + this.resumePagePos(); + this.chrome.desiredPageTransition = "wpfade_transform_backwards"; + return new Promise((resolve, reject) => { + history.back(); + setTimeout(() => { + resolve((this.chrome.desiredPageTransition = "wpfade_transform")); + }, 100); + }); + }, + goToGrouping(url = "https://music.apple.com/WebObjects/MZStore.woa/wa/viewGrouping?cc=us&id=34") { + this.setPagePos(); + this.resumePagePos(); + if (url.includes("viewTop")) { + window.location.hash = `#charts/top`; + } else { + const id = url.split("id=")[1]; + if (id != null) { + window.location.hash = `#groupings/${id}`; + } else { + const params = new Proxy(new URLSearchParams(new URL(url).search), { + get: (searchParams, prop) => searchParams.get(prop), + }); + let id = params.fcId; + app + .getTypeFromID("room", id, false, { + platform: "web", + extend: "editorialArtwork,uber,lockupStyle", + }) + .then(() => { + let kind = "multiroom"; + window.location.hash = `${kind}/${id}`; + document.querySelector("#app-content").scrollTop = 0; + }); + } + } + }, + navigateForward() { + this.setPagePos(); + this.resumePagePos(); + history.forward(); + }, + resetState() { + this.menuPanel.visible = false; + app.selectedMediaItems = []; + this.chrome.contentAreaScrolling = true; + for (let key in app.modals) { + app.modals[key] = false; + } + }, + resumeTabs() { + if (app.cfg.general.resumeTabs.tab == "dynamic") { + this.appRoute(app.cfg.general.resumeTabs.dynamicData); + } else { + this.appRoute(app.cfg.general.resumeTabs.tab); + } + }, + promptAddToPlaylist() { + app.modals.addToPlaylist = true; + }, + async addSelectedToNewPlaylist() { + let self = this; + let pl_items = []; + for (let i = 0; i < self.selectedMediaItems.length; i++) { + if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") { + self.selectedMediaItems[i].kind = "songs"; + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind, + }); + } else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) { + self.selectedMediaItems[i].kind = "albums"; + let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`); + let ids = res.data.data.map(function (i) { + return { id: i.id, type: i.type }; + }); + pl_items = pl_items.concat(ids); + } else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") { + self.selectedMediaItems[i].kind = "library-songs"; + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind, + }); + } else if (self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums" || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) { + self.selectedMediaItems[i].kind = "library-albums"; + let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`); + let ids = res.data.data.map(function (i) { + return { id: i.id, type: i.type }; + }); + pl_items = pl_items.concat(ids); + } else { + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind, + }); + } + } + this.modals.addToPlaylist = false; + app.newPlaylist(app.getLz("term.newPlaylist"), pl_items); + }, + async isSongInPlaylist(song_ids, playlist_id) { + let isInPlaylist = false; + const playlistTracks = ( + await app.mk.api.v3.music(`/v1/me/library/playlists/${playlist_id}/tracks`, { + platform: "web", + l: app.mklang, + }) + ).data?.data; + + playlistTracks.forEach((track) => { + if (song_ids.includes(track.id)) { + isInPlaylist = true; + } + }); + return isInPlaylist; + }, + addToPlaylist(pid, pitems) { + app.mk.api.v3 + .music( + `/v1/me/library/playlists/${pid}/tracks`, + {}, + { + fetchOptions: { + method: "POST", + body: JSON.stringify({ + data: pitems, + }), + }, + }, + ) + .then(() => { + if (app.page === "playlist_" + pid) { + app.getPlaylistFromID(app.showingPlaylist.id, true); + } + }); + }, + async addSelectedToPlaylist(playlist_id) { + let self = this; + let pl_items = []; + const song_ids = []; + for (let i = 0; i < self.selectedMediaItems.length; i++) { + if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") { + self.selectedMediaItems[i].kind = "songs"; + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind, + }); + song_ids.push(self.selectedMediaItems[i].id); + } else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) { + self.selectedMediaItems[i].kind = "albums"; + let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`); + let ids = res.data.data.map(function (i) { + return { id: i.id, type: i.type }; + }); + pl_items = pl_items.concat(ids); + song_ids.push(...ids.map((id) => id.id)); + } else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") { + self.selectedMediaItems[i].kind = "library-songs"; + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind, + }); + song_ids.push(self.selectedMediaItems[i].id); + } else if (self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums" || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) { + self.selectedMediaItems[i].kind = "library-albums"; + let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`); + let ids = res.data.data.map(function (i) { + return { id: i.id, type: i.type }; + }); + pl_items = pl_items.concat(ids); + song_ids.push(...ids.map((id) => id.id)); + } else { + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind, + }); + song_ids.push(self.selectedMediaItems[i].id); + } + } + this.modals.addToPlaylist = false; + + if (await this.isSongInPlaylist(song_ids, playlist_id)) { + app.confirm(app.getLz("action.addToPlaylist.duplicate"), (result) => { + if (result === true) { + app.addToPlaylist(playlist_id, pl_items); + } + }); + } else { + app.addToPlaylist(playlist_id, pl_items); + } + }, + async init() { + let self = this; + if (!localStorage.getItem("seenOOBE")) { + localStorage.setItem("seenOOBE", 1); + } + if (this.cfg.visual.styles.length != 0) { + await this.reloadStyles(); + } + + if (this.platform == "darwin") { + this.chrome.windowControlPosition = "left"; + } + + if (this.cfg.visual.nativeTitleBar) { + this.chrome.nativeControls = true; + } + + this.setLz(this.cfg.general.language); + this.setLzManual(); + clearTimeout(this.hangtimer); + this.mk = MusicKit.getInstance(); + let needsReload = typeof localStorage["music.ampwebplay.media-user-token"] == "undefined"; + if (needsReload) { + ipcRenderer.send("auth-window"); + this.mkIsReady = true; + } + // this.mk.authorize().then(() => { + // self.mkIsReady = true; + // if (needsReload) { + // document.location.reload(); + // } + // }); + this.$forceUpdate(); + if (this.isDev) { + this.mk.privateEnabled = true; + // Hide UserInfo if Dev mode + } else { + // Get Hide User from Settings + this.chrome.hideUserInfo = !this.cfg.visual.showuserinfo; + this.mk.privateEnabled = this.cfg.general.privateEnabled; + } + if (this.cfg.visual.hw_acceleration == "disabled") { + document.body.classList.add("no-gpu"); + } + this.mk._services.timing.mode = 0; + this.platform = this.cfg.main.PLATFORM; + + this.mklang = await this.MKJSLang(); + this.mk._playbackController._storekit.overrideRestrictEnabled(false); + try { + // Set profile name + this.chrome.userinfo = (await app.mk.api.v3.music(`/v1/me/social-profile`)).data.data[0]; + // check if this.chrome.userinfo.attributes.artwork exists + if (this.chrome.userinfo.attributes.artwork && !this.chrome.hideUserInfo) { + document.documentElement.style.setProperty("--cvar-userprofileimg", `url("${this.getMediaItemArtwork(this.chrome.userinfo.attributes.artwork.url)}")`); + } + } catch (err) {} + + // Used to get a scale factor for the window for CSS scaling + window.addEventListener("resize", (e) => this.setWindowScaleFactor()); + this.setWindowScaleFactor(); + this.mk._bag.features["seamless-audio-transitions"] = this.cfg.audio.seamless_audio; + this.mk._bag.features["broadcast-radio"] = true; + this.mk._services.apiManager.store.storekit._restrictedEnabled = false; + // API Fallback + if (!this.chrome.userinfo) { + this.chrome.userinfo = { + id: "", + attributes: { + name: "Cider User", + handle: "CiderUser", + artwork: { url: "./assets/logocut.png" }, + }, + }; + } + MusicKitInterop.init(); + this.monitorMusickit(); + // Set the volume + + // Check the value of this.cfg.audio.muted + if (!this.cfg.audio.muted) { + // Set the mk.volume to the last stored volume data + this.mk.volume = this.cfg.audio.volume; + } else if (this.cfg.audio.muted) { + // Set mk.volume to -1 (setting to 0 wont work, so temp solution setting to -1) + this.mk.volume = -1; + } + + // Restore mk + + // load cached library + let librarySongs = await CiderCache.getCache("library-songs"); + let libraryAlbums = await CiderCache.getCache("library-albums"); + if (librarySongs) { + this.library.songs.listing = librarySongs; + this.library.songs.displayListing = this.library.songs.listing; + } + if (libraryAlbums) { + this.library.albums.listing = libraryAlbums; + this.library.albums.displayListing = this.library.albums.listing; + } + + if (typeof MusicKit.PlaybackBitrate[app.cfg.audio.quality] !== "string") { + app.mk.bitrate = MusicKit.PlaybackBitrate[app.cfg.audio.quality]; + } else { + app.mk.bitrate = 256; + app.cfg.audio.quality = "HIGH"; + } + + switch (this.cfg.general.resumeOnStartupBehavior) { + default: + case "local": + // load last played track + try { + let lastItem = window.localStorage.getItem("currentTrack"); + let time = window.localStorage.getItem("currentTime"); + let queue = window.localStorage.getItem("currentQueue"); + app.mk.queue.position = 0; // Reset queue position. + if (lastItem != null) { + lastItem = JSON.parse(lastItem); + let kind = lastItem.attributes.playParams.kind; + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + app.mk.setQueue({ + [truekind]: [lastItem.attributes.playParams.id], + parameters: { l: app.mklang }, + }); + app.mk.mute(); + setTimeout(() => { + app.mk.play().then(() => { + app.mk.pause().then(() => { + if (time != null) { + app.mk.seekToTime(time); + } + app.mk.unmute(); + if (queue != null) { + queue = JSON.parse(queue); + if (queue && queue.length > 0) { + let ids = queue.map((e) => (e.playParams ? e.playParams.id : e.item.attributes.playParams ? e.item.attributes.playParams.id : "")); + let i = 0; + if (ids.length > 0) { + for (let id of ids) { + if (!(i == 0 && ids[0] == lastItem.attributes.playParams.id)) { + try { + app.mk.playLater({ songs: [id] }); + } catch (err) {} + } + i++; + } + } + } + } + }); + }); + }, 1500); + } + } catch (e) { + console.log(e); + } + break; + case "history": + let history = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`, { l: app.mklang }); + if (history.data.data.length > 0) { + let lastItem = history.data.data[0]; + let kind = lastItem.attributes.playParams.kind; + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + app.mk.setQueue({ + [truekind]: [lastItem.attributes.playParams.id], + parameters: { l: app.mklang }, + }); + app.mk.mute(); + setTimeout(() => { + app.mk.play().then(() => { + app.mk.pause().then(() => { + app.mk.unmute(); + }); + }); + }, 1500); + } + + break; + case "disabled": + break; + } + + MusicKit.getInstance().videoContainerElement = document.getElementById("apple-music-video-player"); + + ipcRenderer.on("setStoreValue", (e, key, value) => { + app.cfg[key] = value; + }); + + ipcRenderer.on("theme-update", async (event, arg) => { + await less.refresh(true, true, true); + self.setTheme(self.cfg.visual.theme, true); + if (app.cfg.visual.styles.length != 0) { + app.reloadStyles(); + } + }); + + /** + * DiscordRPC Reload Return Event + * @author @coredev-uk + */ + ipcRenderer.on("rpcReloaded", (e, user) => { + if (user.username) { + app.notyf.success( + app.stringTemplateParser(app.getLz("settings.option.connectivity.discordRPC.reconnectedToUser"), { + user: `${user.username}#${user.discriminator}`, + userid: user.id, + }), + ); + } + }); + + ipcRenderer.on("getUpdatedLocalList", (event, data) => { + // console.log("cider-local", data); + this.library.localsongs = data; + }); + + ipcRenderer.on("window-state-changed", (event, data) => { + this.chrome.windowState = data; + }); + + ipcRenderer.on("SoundCheckTag", (event, tag) => { + // let replaygain = self.parseSCTagToRG(tag) + try { + if (app.mk.nowPlayingItem.type !== "song") { + CiderAudio.audioNodes.gainNode.gain.value = 0.70794578438; + } else { + let soundcheck = tag.split(" "); + let numbers = []; + for (let item of soundcheck) { + numbers.push(parseInt(item, 16)); + } + numbers.shift(); + let peak = Math.max(numbers[6], numbers[7]) / 32768.0; + let gain = Math.pow(10, (-1.7 - Math.log10(peak) * 20) / 20); // EBU R 128 Compliant + console.debug(`[Cider][MaikiwiSoundCheck] Peak Gain: '${(Math.log10(peak) * 20).toFixed(2)}' dB | Adjusting '${(Math.log10(gain) * 20).toFixed(2)}' dB`); + try { + //CiderAudio.audioNodes.gainNode.gain.value = (Math.min(Math.pow(10, (replaygain.gain / 20)), (1 / replaygain.peak))) + CiderAudio.audioNodes.gainNode.gain.value = gain; + CiderAudio.hierarchical_loading(); + } catch (e) {} + } + } catch (e) { + try { + ipcRenderer.send("SoundCheckTag", event, tag); + } catch (e) { + try { + ipcRenderer.send("SoundCheckTag", event, tag); + } catch (e) { + console.log("[Cider][MaikiwiSoundCheck] Error [Gave up after 3 consecutive attempts]: " + e); + } + } + } // brute force until it works + }); + + ipcRenderer.on("play", function (_event, mode, id) { + if (mode !== "url") { + self.mk.setQueue({ [mode]: id, parameters: { l: self.mklang } }).then(() => { + app.mk.play(); + }); + } else { + app.openAppleMusicURL(id); + } + }); + + this.mk.addEventListener(MusicKit.Events.playbackStateDidChange, (event) => { + ipcRenderer.send("wsapi-updatePlaybackState", wsapi.getAttributes()); + document.body.setAttribute("playback-state", event.state == 2 ? "playing" : "paused"); + }); + + this.mk.addEventListener(MusicKit.Events.playbackTimeDidChange, (a) => { + // self.lyriccurrenttime = self.mk.currentPlaybackTime - app.lyricOffset + this.currentSongInfo = a; + self.playerLCD.playbackDuration = self.mk.currentPlaybackTime; + // wsapi + ipcRenderer.send("wsapi-updatePlaybackState", wsapi.getAttributes()); + }); + + this.mk.addEventListener(MusicKit.Events.queueItemsDidChange, () => { + if (self.$refs.queue || self.$refs.fsView?.$refs?.queue) { + setTimeout(() => { + if (self.$refs.fsView?.$refs?.queue) { + self.$refs.fsView?.$refs?.queue.updateQueue(); + } + if (self.$refs?.queue) { + self.$refs.queue.updateQueue(); + } + }, 100); + } + }); + + // Used for Live Radio stations to set Metadata + this.mk.addEventListener(MusicKit.Events.timedMetadataDidChange, (e) => { + app.mk.nowPlayingItem.attributes.name = e.title; + app.mk.nowPlayingItem.attributes.artistName = e.performer; + app.mk.nowPlayingItem.attributes.albumName = e.album; + if (e.links[1]) { + app.currentArtUrl = e.links[1].url; + app.currentArtUrlRaw = e.links[1].url; + } else { + app.currentArtUrl = e.links[0].url; + app.currentArtUrlRaw = e.links[0].url; + } + app.mk.nowPlayingItem._songId = e._adamId ? e._adamId : -1; + app.mk.nowPlayingItem.id = e._adamId ? e._adamId : -1; + }); + + this.mk.addEventListener(MusicKit.Events.nowPlayingItemDidChange, (a) => { + if (self.$refs.fsView?.$refs?.queue) { + self.$refs.fsView?.$refs?.queue.updateQueue(); + } + if (self.$refs?.queue) { + self.$refs.queue.updateQueue(); + } + this.currentSongInfo = a; + if (this.currentSongInfo === null || this.currentSongInfo === undefined) { + return; + } // EVIL EMPTY OBJECTS BE GONE + + try { + this.radiohls.destroy(); + this.radiohls = null; + } catch (_) {} + + try { + if ((MusicKit.getInstance().nowPlayingItem["type"] ?? "").includes("ideo")) { + setTimeout(() => { + this.MVsource = CiderAudio.context.createMediaElementSource(document.querySelector("div#apple-music-video-player > video")); + this.MVsource.connect(CiderAudio.audioNodes.intelliGainComp); + }, 300); + } else { + this.MVsource.disconnect(); + this.MVsource = null; + } + } catch (e) { + // console.log(e); + } + + let localFiles = false; + try { + if (app.mk.nowPlayingItem.flavor.includes("64") && app.mk.nowPlayingItem.flavor.includes(":")) { + localStorage.setItem("playingBitrate", "64"); + } else if (app.mk.nowPlayingItem.flavor.includes("256") && app.mk.nowPlayingItem.flavor.includes(":")) { + localStorage.setItem("playingBitrate", "256"); + } else { + localFiles = true; + localStorage.setItem("playingBitrate", app.mk.nowPlayingItem.flavor); + } + } catch (e) { + localFiles = true; + try { + localStorage.setItem("playingBitrate", app.mk.nowPlayingItem.flavor); + } catch (e) {} + } + + if (app.cfg.audio.normalization === false) { + CiderAudio.hierarchical_loading(); + } // Just Reload for Adaptive CAP if norm is off + else { + // get unencrypted audio previews to get SoundCheck's normalization tag + try { + let previewURL = null; + try { + previewURL = app.mk.nowPlayingItem.previewURL; + } catch (e) { + if (e instanceof TypeError === false) { + console.debug("[Cider][MaikiwiSoundCheck] normalizer function err: " + e); + } else { + if (localFiles === true) { + CiderAudio.audioNodes.gainNode.gain.value = 0.822242649947; + } + } + } + if (previewURL == null && (app.mk.nowPlayingItem?._songId ?? app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id) != -1) { + app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem?._songId ?? app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id}`).then((response) => { + try { + previewURL = response.data.data[0].attributes.previews[0].url; + } catch (e) { + if (e instanceof TypeError === false) { + console.debug("[Cider][MaikiwiSoundCheck] normalizer function err: " + e); + } else { + if (localFiles === true) { + CiderAudio.audioNodes.gainNode.gain.value = 0.822242649947; + } + } + } + if (previewURL) { + console.debug("[Cider][MaikiwiSoundCheck] previewURL response.data.data[0].attributes.previews[0].url: " + previewURL); + ipcRenderer.send("getPreviewURL", previewURL); + } else { + if (localFiles === true) { + CiderAudio.audioNodes.gainNode.gain.value = 0.822242649947; + } + } + }); + } else { + if (previewURL) { + console.debug("[Cider][MaikiwiSoundCheck] previewURL in app.mk.nowPlayingItem.previewURL: " + previewURL); + ipcRenderer.send("getPreviewURL", previewURL); + } + } + } catch (e) { + if (e instanceof TypeError === false) { + console.debug("[Cider][MaikiwiSoundCheck] normalizer function err: " + e); + } else { + if (localFiles === true) { + CiderAudio.audioNodes.gainNode.gain.value = 0.822242649947; + } + } + } + } + + try { + a = a.item.attributes; + } catch (_) {} + let type = self.mk.nowPlayingItem != null ? self.mk.nowPlayingItem["type"] ?? "" : ""; + + if (type.includes("musicVideo") || type.includes("uploadedVideo") || type.includes("music-movie") || (self.mk.nowPlayingItem?.type == "radioStation") & (self.mk.nowPlayingItem?.attributes?.mediaKind == "video")) { + document.getElementById("apple-music-video-container").style.display = "block"; + document.body.setAttribute("video-playing", "true"); + // app.chrome.topChromeVisible = false + } else { + document.body.removeAttribute("video-playing"); + document.getElementById("apple-music-video-container").style.display = "none"; + // app.chrome.topChromeVisible = true + } + self.chrome.artworkReady = false; + self.lyrics = []; + self.richlyrics = []; + app.getCurrentArtURL().then((urls) => { + app.currentArtUrl = urls?.currentArtUrl ?? ""; + app.currentArtUrlRaw = urls?.currentArtUrlRaw ?? ""; + ipcRenderer.send("discordrpc:updateImage", app.currentArtUrl); + }); + // app.getNowPlayingArtwork(42); + app.getNowPlayingArtworkBG(32); + app.loadLyrics(); + + setTimeout(() => { + let i = document.querySelector("#apple-music-player")?.src ?? ""; + if (i.endsWith(".m3u8") || i.endsWith(".m3u")) { + this._playRadioStream(i); + } + }, 1500); + }); + + this.mk.addEventListener(MusicKit.Events.playbackVolumeDidChange, (_a) => { + this.cfg.audio.volume = this.mk.volume; + ipcRenderer.send("mpris:volumeChange", this.mk.volume); + }); + + this.refreshPlaylists(this.isDev); + document.body.removeAttribute("loading"); + if (window.location.hash != "") { + this.appRoute(window.location.hash); + } + + if (this.page != "home") { + this.resumeTabs(); + } + this.mediaKeyFixes(); + + setTimeout(() => { + this.getSocialBadges(); + this.getBrowsePage(); + this.$forceUpdate(); + }, 500); + document.querySelector("#apple-music-video-player-controls").addEventListener("mousemove", () => { + this.showFoo(".music-player-info", 2000); + }); + ipcRenderer.invoke("renderer-ready", true); + document.querySelector("#LOADER").remove(); + if (this.cfg.general.themeUpdateNotification && !this.isDev) { + this.checkForThemeUpdates(); + } + + if (!localStorage.getItem("noC2Startup")) { + const c2UpgradeDate = 1688172351000; + if (Date.now() <= c2UpgradeDate) { + setTimeout(() => { + app.modals.c2Upgrade = true; + }, 2000); + } + } + }, + setWindowScaleFactor() { + let scale = (((window.devicePixelRatio * window.innerWidth) / 1280) * window.innerHeight) / 720; + let desiredScale = clamp(parseFloat(app.cfg.visual.maxElementScale == -1 ? 1.5 : app.cfg.visual.maxElementScale), 1, 1.5); + app.$store.state.windowRelativeScale = scale; + if (scale <= 1) { + scale = 1; + } else if (scale >= desiredScale) { + scale = desiredScale; + } + document.documentElement.style.setProperty("--windowRelativeScale", scale); + }, + c2offer() { + app.modals.c2Upgrade = true; + }, + showFoo(querySelector, time) { + clearTimeout(this.idleTimer); + if (this.idleState == true) { + document.querySelector(querySelector).classList.remove("inactive"); + } + this.idleState = false; + this.idleTimer = setTimeout(() => { + document.querySelector(querySelector).classList.add("inactive"); + this.idleState = true; + }, time); + }, + setContentScrollPos(scroll) { + this.chrome.contentScrollPosY = scroll.target.scrollTop; + }, + async checkForThemeUpdates() { + let self = this; + const themes = ipcRenderer.sendSync("get-themes"); + await asyncForEach(themes, async (theme) => { + if (theme.commit != "") { + if (theme.commit != "") { + app._fetch(`https://api.github.com/repos/${theme.github_repo}/commits`).then((res) => res.json()); + if (res[0].sha != theme.commit) { + const notify = notyf.open({ + className: "notyf-info", + type: "info", + message: app.stringTemplateParser(app.getLz("settings.notyf.visual.theme.updateAvailable"), { theme: theme.name }), + }); + notify.on("click", () => { + app.openSettingsPage("github-themes"); + notyf.dismiss(notify); + }); + } + } + } + }); + }, + async setTheme(theme = "", onlyPrefs = false) { + console.debug(theme); + if (this.cfg.visual.theme == "") { + this.cfg.visual.theme = "default.less"; + } + if (theme == "") { + theme = this.cfg.visual.theme; + } else { + this.cfg.visual.theme = ""; + this.cfg.visual.theme = theme; + } + const info = {}; + try { + const infoResponse = await fetch("themes/" + app.cfg.visual.theme.replace("index.less", "theme.json")); + this.chrome.appliedTheme.info = await infoResponse.json(); + } catch (e) { + e = null; + console.warn("failed to get theme.json"); + this.chrome.appliedTheme.info = {}; + } + + if (!onlyPrefs) { + document.querySelector("#userTheme").href = `themes/${this.cfg.visual.theme}`; + document.querySelectorAll(`[id*='less']`).forEach((el) => { + el.remove(); + }); + await less.refresh(); + } + }, + async reloadStyles() { + const styles = this.cfg.visual.styles; + document.querySelectorAll(`[id*='less']`).forEach((el) => { + if (el.id != "less:style") { + el.remove(); + } + }); + + this.chrome.appliedTheme.info = {}; + await asyncForEach(styles, async (style) => { + let styleEl = document.createElement("link"); + styleEl.id = `less-${style.replace(".less", "")}`; + styleEl.rel = "stylesheet/less"; + styleEl.href = `themes/${style}`; + styleEl.type = "text/css"; + document.head.appendChild(styleEl); + try { + let infoResponse = await fetch("themes/" + style.replace("index.less", "theme.json")); + this.chrome.appliedTheme.info = Object.assign(this.chrome.appliedTheme.info, await infoResponse.json()); + } catch (e) { + e = null; + console.warn("failed to get theme.json"); + } + }); + less.registerStylesheetsImmediately(); + await less.refresh(true, true, true); + this.$forceUpdate(); + return; + }, + macOSEmu() { + this.chrome.forceDirectives["macosemu"] = { + value: true, + }; + this.chrome.windowControlPosition = "left"; + }, + getThemeDirective(directive = "") { + let directives = {}; + if (typeof this.chrome.appliedTheme.info.directives == "object") { + directives = this.chrome.appliedTheme.info.directives; + } + directives = Object.assign(directives, this.chrome.forceDirectives); + if (directives[directive]) { + return directives[directive].value; + } else if (this.cfg.visual.directives[directive]) { + return this.cfg.visual.directives[directive]; + } else { + return false; + } + }, + unauthorize() { + this.confirm(app.getLz("term.confirmLogout"), function (result) { + if (result) { + app.mk.unauthorize(); + document.location.reload(); + } + }); + }, + getAppClasses() { + let classes = {}; + switch (this.getThemeDirective("forceUI") ?? "none") { + case "compact": + classes.compact = true; + break; + case "standard": + classes.compact = false; + break; + default: + if (this.cfg.advanced.experiments.includes("compactui")) { + classes.compact = true; + } + break; + } + + if (this.cfg.visual.window_background_style == "none") { + classes.simplebg = true; + } + + if (this.platform !== "darwin") { + switch (parseInt(this.cfg.visual.windowControlPosition)) { + default: + case 0: + this.chrome.windowControlPosition = "right"; + this.chrome.forceDirectives["macosemu"] = { + value: false, + }; + break; + case 1: + this.chrome.windowControlPosition = "left"; + this.chrome.forceDirectives["macosemu"] = { + value: true, + }; + break; + } + } + + if (this.getThemeDirective("windowLayout") == "twopanel") { + classes.twopanel = true; + } + if (this.getThemeDirective("appNavigation") == "seperate") { + classes.navbar = true; + } + if (this.getThemeDirective("macosemu") == true) { + classes.macosemu = true; + } + return classes; + }, + invokeDrawer(panel) { + if (this.drawer.panel == panel && this.drawer.open) { + if (panel == "lyrics") { + this.lyricon = false; + } + this.drawer.panel = ""; + this.drawer.open = false; + } else { + if (panel == "lyrics") { + this.lyricon = true; + } else { + this.lyricon = false; + } + this.drawer.open = true; + this.drawer.panel = panel; + } + }, + select_removeMediaItem(id) { + this.selectedMediaItems + .filter((item) => item.guid == id) + .forEach((item) => { + this.selectedMediaItems.splice(this.selectedMediaItems.indexOf(item), 1); + }); + }, + select_hasMediaItem(id) { + let found = this.selectedMediaItems.find((item) => item.guid == id); + if (found) { + return true; + } else { + return false; + } + }, + select_selectMediaItem(id, kind, index, guid, library) { + if (!this.select_hasMediaItem(guid)) { + this.selectedMediaItems.push({ + id: id, + kind: kind, + index: index, + guid: guid, + isLibrary: library, + }); + } + }, + getPlaylistFolderChildren(id) { + return this.playlists.listing.filter((playlist) => { + if (playlist.parent == id) { + return playlist; + } + }); + }, + async syncFavorites() { + const notify = notyf.open({ + className: "notyf-info", + type: "info", + message: `[${app.getLz("home.syncFavorites")}] ${app.getLz("home.syncFavorites.gettingArtists")}`, + }); + const results = await MusicKitTools.v3Continuous({ + href: "/v1/me/library/artists", + options: { + include: ["catalog"], + "fields[artists]": ["inFavorites"], + }, + }); + let favs = []; + // for each result + results.forEach((result) => { + try { + if (result.relationships?.catalog?.data[0]?.attributes?.inFavorites) { + if (!favs.includes(result.relationships?.catalog?.data[0].id)) { + favs.push(result.relationships?.catalog?.data[0].id); + } + } + } catch (e) { + e = null; + } + }); + notyf.success(`[${app.getLz("home.syncFavorites")}] ${app.getLz("action.done")}`); + app.cfg.home.followedArtists = favs; + return favs; + }, + async setArtistFavorite(id, val = true) { + if (val) { + if (!app.cfg.home.followedArtists.includes(id)) { + app.cfg.home.followedArtists.push(id); + } + await app.mk.api.v3.music( + `/v1/me/favorites`, + { + "art[url]": "f", + "ids[artists]": app.artistPage.data.id, + l: app.mklang, + platform: "web", + }, + { + fetchOptions: { + method: "POST", + }, + }, + ); + } else { + if (app.cfg.home.followedArtists.includes(id)) { + app.cfg.home.followedArtists.splice(app.cfg.home.followedArtists.indexOf(id), 1); + } + await app.mk.api.v3.music( + `/v1/me/favorites`, + { + "art[url]": "f", + "ids[artists]": app.artistPage.data.id, + l: app.mklang, + platform: "web", + }, + { + fetchOptions: { + method: "DELETE", + }, + }, + ); + } + }, + async refreshPlaylists(localOnly = false, useCachedPlaylists = true) { + let self = this; + let trackMap = this.cfg.advanced.playlistTrackMapping; + let newListing = []; + let trackMapping = {}; + + if (useCachedPlaylists) { + const cachedPlaylist = await CiderCache.getCache("library-playlists"); + const cachedTrackMapping = await CiderCache.getCache("library-playlists-tracks"); + + if (cachedPlaylist) { + console.debug("[CiderCache] Using cached playlist"); + this.playlists.listing = cachedPlaylist; + self.sortPlaylists(); + } else { + console.debug("[CiderCache] Playlist has no cache"); + } + + if (cachedTrackMapping) { + console.debug("[CiderCache] Using cached track mapping"); + this.playlists.trackMapping = cachedTrackMapping; + } + if (localOnly) { + return; + } + } + + this.library.backgroundNotification.message = app.getLz("notification.buildingPlaylistCache"); + this.library.backgroundNotification.show = true; + + async function deepScan(parent = "p.playlistsroot") { + console.debug(`scanning ${parent}`); + // const playlistData = await app.mk.api.v3.music(`/v1/me/library/playlist-folders/${parent}/children/`) + const playlistData = await MusicKitTools.v3Continuous({ + href: `/v1/me/library/playlist-folders/${parent}/children/`, + }); + console.log(playlistData); + await asyncForEach(playlistData, async (playlist) => { + playlist.parent = parent; + if (playlist.type != "library-playlist-folders" && typeof playlist.attributes.playParams["versionHash"] != "undefined") { + playlist.parent = "p.applemusic"; + } + playlist.children = []; + playlist.tracks = []; + try { + if (trackMap) { + let tracks = await app.mk.api.v3.music(playlist.href + "/tracks").catch((e) => { + // no tracks + e = null; + }); + tracks.data.data.forEach((track) => { + if (!trackMapping[track.id]) { + trackMapping[track.id] = []; + } + trackMapping[track.id].push(playlist.id); + + if (typeof track.attributes.playParams.catalogId == "string") { + if (!trackMapping[track.attributes.playParams.catalogId]) { + trackMapping[track.attributes.playParams.catalogId] = []; + } + trackMapping[track.attributes.playParams.catalogId].push(playlist.id); + } + }); + } + } catch (e) {} + if (playlist.type == "library-playlist-folders") { + try { + await deepScan(playlist.id).catch((e) => {}); + } catch (e) {} + } + newListing.push(playlist); + }); + } + + await deepScan(); + + this.library.backgroundNotification.show = false; + this.playlists.listing = newListing; + self.sortPlaylists(); + if (trackMap) { + CiderCache.putCache("library-playlists-tracks", trackMapping); + this.playlists.trackMapping = trackMapping; + } + CiderCache.putCache("library-playlists", newListing); + }, + sortPlaylists() { + this.playlists.listing.sort((a, b) => { + if (a.type === "library-playlist-folders" && b.type !== "library-playlist-folders") { + return -1; + } else if (a.type !== "library-playlist-folders" && b.type === "library-playlist-folders") { + return 1; + } else { + return 0; + } + }); + }, + playlistHeaderContextMenu(event) { + let menu = { + items: [ + { + name: app.getLz("term.createNewPlaylist"), + action: () => { + this.newPlaylist(); + }, + }, + { + name: app.getLz("term.createNewPlaylistFolder"), + action: () => { + this.newPlaylistFolder(); + }, + }, + { + name: app.getLz("action.refresh"), + action: () => { + this.refreshPlaylists(); + }, + }, + ], + }; + this.showMenuPanel(menu, event); + }, + async editPlaylistFolder(id, name = app.getLz("term.newPlaylist")) { + let self = this; + this.mk.api.v3 + .music( + `/v1/me/library/playlist-folders/${id}`, + {}, + { + fetchOptions: { + method: "PATCH", + body: JSON.stringify({ + attributes: { name: name }, + }), + }, + }, + ) + .then((res) => { + self.refreshPlaylists(false, false); + }); + }, + async editPlaylist(id, name = app.getLz("term.newPlaylist")) { + let self = this; + this.mk.api.v3 + .music( + `/v1/me/library/playlists/${id}`, + {}, + { + fetchOptions: { + method: "PATCH", + body: JSON.stringify({ + attributes: { name: name }, + }), + }, + }, + ) + .then((res) => { + self.refreshPlaylists(false, false); + }); + }, + async editPlaylistDescription(id, name = app.getLz("term.newPlaylist")) { + let self = this; + this.mk.api.v3 + .music( + `/v1/me/library/playlists/${id}`, + {}, + { + fetchOptions: { + method: "PATCH", + body: JSON.stringify({ + attributes: { description: name }, + }), + }, + }, + ) + .then((res) => { + self.refreshPlaylists(false, false); + }); + }, + copyToClipboard(str) { + // if (navigator.userAgent.includes('Darwin') || navigator.appVersion.indexOf("Mac") != -1) { + // this.darwinShare(str) + // } else { + notyf.success(app.getLz("term.share.success")); + navigator.clipboard.writeText(str).then((r) => console.debug("Copied to clipboard.")); + // } + }, + newPlaylist(name = app.getLz("term.newPlaylist"), tracks = []) { + let self = this; + let request = { + name: name, + }; + if (tracks.length > 0) { + request.tracks = tracks; + } + app.mk.api.v3 + .music( + `/v1/me/library/playlists`, + {}, + { + fetchOptions: { + method: "POST", + body: JSON.stringify({ + attributes: { name: name }, + relationships: { + tracks: { data: tracks }, + }, + }), + }, + }, + ) + .then((res) => { + res = res.data.data[0]; + console.debug(res); + self.appRoute(`playlist_` + res.id); + self.showingPlaylist = []; + self.getPlaylistFromID(app.page.substring(9), true); + self.playlists.listing.push({ + id: res.id, + attributes: { + name: name, + }, + parent: "p.playlistsroot", + }); + self.sortPlaylists(); + setTimeout(() => { + app.refreshPlaylists(false, false); + }, 8000); + }); + }, + deletePlaylist(id) { + let self = this; + this.confirm(app.getLz("term.deletePlaylist"), (ok) => { + if (ok) { + app.mk.api.v3 + .music( + `/v1/me/library/playlists/${id}`, + {}, + { + fetchOptions: { + method: "DELETE", + }, + }, + ) + .then((res) => { + // remove this playlist from playlists.listing if it exists + let found = self.playlists.listing.find((item) => item.id == id); + if (found) { + self.playlists.listing.splice(self.playlists.listing.indexOf(found), 1); + } + setTimeout(() => { + app.refreshPlaylists(false, false); + }, 8000); + }); + } + }); + }, + /** + * @param {string} url, href for the initial request + * @memberof app + */ + async showRoom(url) { + let self = this; + const response = await this.mk.api.v3.music(url); + let room = response.data.data[0]; + this.showCollection(room.relationships.contents, room.attributes.title); + }, + async showCollection(response, title, type, requestBody = {}) { + let self = this; + console.debug(response); + this.collectionList.requestBody = {}; + this.collectionList.response = response; + this.collectionList.title = title; + this.collectionList.type = type; + this.collectionList.requestBody = requestBody; + app.appRoute("collection-list"); + }, + async showArtistView(artist, title, view) { + let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artist}/view/${view}?l=${this.mklang}`, {}, { includeResponseMeta: !0 })).data; + console.debug(response); + await this.showCollection(response, title, "artists"); + }, + async showRecordLabelView(label, title, view) { + let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/record-labels/${label}/view/${view}?l=${this.mklang}`)).data; + await this.showCollection(response, title, "record-labels"); + }, + async showSearchView(term, group, title) { + let requestBody = { + platform: "web", + groups: group, + types: "activities,albums,apple-curators,artists,curators,editorial-items,music-movies,music-videos,playlists,songs,stations,tv-episodes,uploaded-videos,record-labels", + limit: 25, + relate: { + editorialItems: ["contents"], + }, + include: { + albums: ["artists"], + songs: ["artists"], + "music-videos": ["artists"], + }, + extend: "artistUrl", + fields: { + artists: "url,name,artwork,hero", + albums: "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", + }, + with: "serverBubbles,lyricHighlights", + art: { + url: "cf", + }, + omit: { + resource: ["autos"], + }, + l: this.mklang, + }; + let response = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${term}`, requestBody, { + includeResponseMeta: !0, + }); + + console.debug("searchres", response); + let responseFormat = { + data: response.data.results[group].data, + next: response.data.results[group].next, + groups: group, + }; + await this.showCollection(responseFormat, title, "search", requestBody); + }, + async getPlaylistContinuous(response, transient = false) { + response = response.data.data[0]; + let self = this; + let playlistId = response.id; + this.playlists.loadingState = !transient ? 0 : 1; + this.showingPlaylist = response; + if (!response.relationships?.tracks?.next) { + this.playlists.loadingState = 1; + return; + } + + function getPlaylistTracks(next) { + app.apiCall(app.musicBaseUrl + next, (res) => { + if (self.showingPlaylist.id != playlistId) { + return; + } + self.showingPlaylist.relationships.tracks.data = self.showingPlaylist.relationships.tracks.data.concat(res.data); + if (res.next) { + getPlaylistTracks(res.next); + } else { + self.playlists.loadingState = 1; + } + }); + } + + getPlaylistTracks(response.relationships.tracks.next); + }, + async getPlaylistFromID(id, transient = false) { + let self = this; + const params = { + include: "tracks", + platform: "web", + "include[library-playlists]": "catalog,tracks", + "fields[playlists]": "curatorName,playlistType,name,artwork,url,playParams", + "include[library-songs]": "catalog,artists,albums,playParams,name,artwork,url", + "fields[catalog]": "artistUrl,albumUrl,url", + "fields[songs]": "artistUrl,albumUrl,playParams,name,artwork,url,artistName,albumName,durationInMillis", + l: this.mklang, + }; + if (!transient) { + this.playlists.loadingState = 0; + } + app.mk.api.v3 + .music(`/v1/me/library/playlists/${id}`, params) + .then((res) => { + self.getPlaylistContinuous(res, transient); + }) + .catch((e) => { + console.debug(e); + try { + app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`, params).then((res) => { + self.getPlaylistContinuous(res, transient); + }); + } catch (err) { + console.debug(err); + } + }); + }, + async getArtistFromID(id) { + this.page = ""; + const artistData = await this.mkapi( + "artists", + false, + id, + { + views: "featured-release,full-albums,appears-on-albums,featured-albums,featured-on-albums,singles,compilation-albums,live-albums,latest-release,top-music-videos,similar-artists,top-songs,playlists,more-to-hear,more-to-see", + extend: "centeredFullscreenBackground,artistBio,bornOrFormed,editorialArtwork,editorialVideo,isGroup,origin,hero", + "extend[playlists]": "trackCount", + "include[songs]": "albums", + "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount", + "limit[artists:top-songs]": 20, + "art[url]": "f", + l: this.mklang, + }, + { includeResponseMeta: !0 }, + ); + console.debug(artistData.data.data[0]); + this.artistPage.data = artistData.data.data[0]; + this.page = "artist-page"; + }, + progressBarStyle() { + let val = this.playerLCD.playbackDuration; + if (this.playerLCD.desiredDuration > 0) { + val = this.playerLCD.desiredDuration; + } + let min = 0; + let max = this.mk.currentPlaybackDuration; + let value = ((val - min) / (max - min)) * 100; + return { + background: "linear-gradient(to right, var(--songProgressColor) 0%, var(--songProgressColor) " + value + "%, var(--songProgressBackground) " + value + "%, var(--songProgressBackground) 100%)", + }; + }, + async getRecursive(response) { + // if response has a .next() property run it and keep running until .next is null or undefined + // and then return the response concatenated with the results of the next() call + function executeRequest() { + if (response.next) { + return response.next().then(executeRequest); + } else { + return response; + } + } + + return executeRequest(); + }, + async getRecursive2(response, sendTo) { + let returnData = { + data: [], + meta: {}, + }; + if (response.next) { + console.debug("has next"); + returnData.data.concat(response.data); + returnData.meta = response.meta; + return await this.getRecursive(await response.next()); + } else { + console.debug("no next"); + returnData.data.concat(response.data); + return returnData; + } + }, + async getSearchHints() { + if (this.search.term == "") { + this.search.hints = []; + this.search.showHints = true; + this.search.showSearchView = false; + return; + } + let hints = await ( + await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search/suggestions?term=${encodeURIComponent(this.search.term)}`, { + "fields[albums]": "artwork,name,playParams,url,artistName,id", + "fields[artists]": "url,name,artwork,id", + "fields[songs]": "artwork,name,playParams,url,artistName,id", + kinds: "terms,topResults", + l: this.mklang, + "limit[results:terms]": 5, + "limit[results:topResults]": 5, + "omit[resource]": "autos", + platform: "web", + types: "activities,albums,artists,editorial-items,music-movies,playlists,record-labels,songs,stations", + }) + ).data.results; + let shints = hints ? hints.suggestions : []; + for (let item in shints) { + if ((shints[item]?.displayTerm ?? "").includes("?fields[")) { + shints[item].displayTerm = shints[item].searchTerm = shints[item].displayTerm.split("?fields[")[0]; + } + } + this.search.hints = shints; + }, + getSongProgress() { + if (this.playerLCD.userInteraction) { + return this.playerLCD.desiredDuration; + } else { + return this.playerLCD.playbackDuration; + } + }, + /** + * Converts seconds to dd:hh:mm:ss / Days:Hours:Minutes:Seconds + * @param {number} seconds + * @param {string} format (short, long) + * @returns {string} + * @author Core#1034 + * @memberOf app + */ + convertTime(seconds, format = "short") { + if (app.mk?.nowPlayingItem?.type === "radioStation") return; + if (isNaN(seconds) || seconds === Infinity) { + seconds = 0; + } + + const datetime = new Date(seconds * 1000); + + if (format === "long") { + const d = Math.floor(seconds / (3600 * 24)); + const h = Math.floor((seconds % (3600 * 24)) / 3600); + const m = Math.floor((seconds % 3600) / 60); + const s = Math.floor(seconds % 60); + + const dDisplay = d > 0 ? `${d} ${app.getLz("term.time.day", { count: d })}` : ""; + const hDisplay = h > 0 ? `${h} ${app.getLz("term.time.hour", { count: h })}` : ""; + const mDisplay = m > 0 ? `${m} ${app.getLz("term.time.minute", { count: m })}` : ""; + + return dDisplay + (dDisplay && hDisplay ? ", " : "") + hDisplay + (hDisplay && mDisplay ? ", " : "") + mDisplay; + } else { + return MusicKit.formatMediaTime(seconds); + } + }, + hashCode(str) { + let hash = 0, + i, + chr; + if (str.length === 0) return hash; + for (i = 0; i < str.length; i++) { + chr = str.charCodeAt(i); + hash = (hash << 5) - hash + chr; + hash |= 0; // Convert to 32bit integer + } + return hash; + }, + getPagePos(href = "") { + let state = this.$store.state.pageState.scrollPos.pos.find((page) => { + return page.href === href; + }); + return ( + state ?? { + page: href, + position: 0, + } + ); + }, + appRoute(route) { + if (route == "" || route == "#" || route == "/") { + return; + } + route = route.replace(/#/g, ""); + if (app.cfg.general.resumeTabs.tab == "dynamic") { + if (route == "home" || route == "listen_now" || route == "browse" || route == "radio" || route == "library-songs" || route == "library-albums" || route == "library-artists" || route == "library-videos" || route == "podcasts") { + app.cfg.general.resumeTabs.dynamicData = route; + } else { + app.cfg.general.resumeTabs.dynamicData = "home"; + } + } + + // if the route contains does not include a / then route to the page directly + if (route.indexOf("/") == -1) { + this.page = route; + window.location.hash = this.page; + this.resumePagePos(); + // if (this.page == "settings") { + // this.version + // } + return; + } + let hash = route.split("/"); + let page = hash[0]; + let id = hash[1]; + let isLibrary = hash[2] ?? false; + if (page == "plugin") { + this.pluginPages.page = "plugin." + id; + this.page = "plugin-renderer"; + return; + } + this.routeView({ + kind: page, + id: id, + attributes: { + playParams: { kind: page, id: id, isLibrary: isLibrary }, + }, + }); + }, + resumePagePos() { + setTimeout(() => { + $("#app-content").scrollTop(app.getPagePos(window.location.hash).position); + }, 100); + }, + setPagePos() { + try { + console.debug({ + href: window.location.hash, + position: $("#app-content").scrollTop(), + }); + this.$store.commit("setPagePos", { + href: window.location.hash, + position: $("#app-content").scrollTop(), + }); + } catch (e) {} + }, + routeView(item) { + this.setPagePos(); + let kind = item.attributes?.playParams ? item.attributes?.playParams?.kind ?? item.type ?? "" : item.type ?? ""; + let id = item.attributes?.playParams ? item.attributes?.playParams?.id ?? item.id ?? "" : item.id ?? ""; + let isLibrary = item.attributes?.playParams ? item.attributes?.playParams?.isLibrary ?? false : false; + if (kind.includes("playlist") || kind.includes("album")) { + app.showingPlaylist = []; + } + if (kind.toString().includes("apple-curator")) { + kind = "appleCurator"; + app + .getTypeFromID("appleCurator", id, false, { + platform: "web", + include: "grouping,playlists", + extend: "editorialArtwork", + "art[url]": "f", + }) + .then(() => { + kind = "appleCurator"; + window.location.hash = `${kind}/${id}`; + }); + } else if (kind == "editorial-elements" || kind == "editorial-items") { + console.debug(item); + if (item.relationships?.contents?.data != null && item.relationships?.contents?.data.length > 0) { + this.routeView(item.relationships.contents.data[0]); + } else if (item.attributes?.link?.url != null) { + if (item.attributes.link.url.includes("viewMultiRoom") || item.attributes.link.url.includes("/collection/")) { + const params = new Proxy(new URLSearchParams(new URL(item.attributes.link.url).search), { + get: (searchParams, prop) => searchParams.get(prop), + }); + id = params.fcId; + kind = "multiroom"; + if (item.attributes.link.url.includes("viewMultiRoom")) { + kind = "multiroom"; + } else { + kind = "room"; + } + app + .getTypeFromID(kind, id, false, { + platform: "web", + extend: "editorialArtwork,uber,lockupStyle", + }) + .then(() => { + kind = "multiroom"; + window.location.hash = `${kind}/${id}`; + }); + + return; + } else if (item.attributes.link.url.includes("viewFeature")) { + const params = new Proxy(new URLSearchParams(new URL(item.attributes.link.url).search), { + get: (searchParams, prop) => searchParams.get(prop), + }); + id = params.id; + app.mk.api.v3.music(`/v1/editorial/${app.mk.storefrontId}/multiplex/${id}?art%5Burl%5D=f&format%5Bresources%5D=map&platform=web`).then((data) => { + let item = data.data.results?.target ?? []; + app.routeView(item); + }); + } else { + window.open(item.attributes.link.url); + } + } + } else if (kind == "multiplex") { + app.mk.api.v3.music(`/v1/editorial/${app.mk.storefrontId}/multiplex/${id}?art%5Burl%5D=f&format%5Bresources%5D=map&platform=web`).then((data) => { + let item = data.data.results?.target ?? []; + app.routeView(item); + }); + } + if (kind == "multirooms") { + app + .getTypeFromID("multiroom", id, false, { + platform: "web", + extend: "editorialArtwork,uber,lockupStyle", + }) + .then(() => { + kind = "multiroom"; + window.location.hash = `${kind}/${id}`; + // document.querySelector("#app-content").scrollTop = 0; + }); + this.resumePagePos(); + } else if (kind.toString().includes("artist")) { + app.getArtistInfo(id, isLibrary); + window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ""}`; + // document.querySelector("#app-content").scrollTop = 0; + } else if (kind.toString().includes("record-label") || kind.toString().includes("curator")) { + if (kind.toString().includes("record-label")) { + kind = "recordLabel"; + } else { + kind = "curator"; + } + app.page = kind + "_" + id; + app.getTypeFromID(kind, id, isLibrary, { + extend: "editorialVideo", + include: "grouping,playlists", + views: "top-releases,latest-releases,top-artists", + }); + window.location.hash = `${kind}/${id}`; + document.querySelector("#app-content").scrollTop = 0; + this.resumePagePos(); + } else if (kind.toString().includes("social-profiles")) { + app.page = kind + "_" + id; + app.mk.api.v3 + .music(`/v1/social/${app.mk.storefrontId}/social-profiles/${id}`, { + include: "shared-playlists", + }) + .then((data) => { + console.log(data); + app.showingPlaylist = data.data?.data[0]; + window.location.hash = `${kind}/${id}`; + document.querySelector("#app-content").scrollTop = 0; + }); + // app.getTypeFromID((kind), (id), (isLibrary), { + // extend: "editorialVideo", + // include: 'grouping,playlists', + // views: 'top-releases,latest-releases,top-artists' + // }); + } else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) { + let params = { + extend: "offers,editorialVideo", + views: "appears-on,more-by-artist,related-videos,other-versions,you-might-also-like,video-extras,audio-extras", + }; + if (kind.includes("playlist")) { + params["include"] = "tracks"; + } + if (kind.includes("album")) { + params["include[albums]"] = "artists"; + params["fields[artists]"] = "name,url"; + params["omit[resource]"] = "autos"; + params["meta[albums:tracks]"] = "popularity"; + params["fields[albums]"] = "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialNotes,editorialVideo,name,playParams,releaseDate,url,copyright,genreNames"; + } + if (kind.includes("playlist") || kind.includes("album")) { + app.page = kind + "_" + id; + window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ""}`; + app.getTypeFromID(kind, id, isLibrary, params); + } else { + app.page = kind; + window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ""}`; + } + this.resumePagePos(); + // app.getTypeFromID((kind), (id), (isLibrary), params); + } else if (kind.toString().includes("song")) { + const albumUrl = new Promise(async (resolve, reject) => { + resolve(await MusicKitInterop.fetchSongRelationships({ id: id, relationship: "album" })); + }); + albumUrl.then((data) => { + if (data && data.type === "albums" && data.id) { + window.location.hash = `album/${data.id}${isLibrary ? "/" + isLibrary : ""}`; + } else { + app.playMediaItemById(id, kind, isLibrary, item.attributes.url ?? ""); + } + }); + } else { + app.playMediaItemById(id, kind, isLibrary, item.attributes.url ?? ""); + } + }, + prevButton() { + if (app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) { + app.mk.seekToTime(0); + } else { + app.skipToPreviousItem(); + } + }, + isDisabled() { + return !app.mk.nowPlayingItem || app.mk.nowPlayingItem.attributes.playParams.kind === "radioStation"; + }, + isPrevDisabled() { + return this.isDisabled() || (app.mk.queue._position === 0 && app.mk.currentPlaybackTime <= 2); + }, + isNextDisabled() { + return this.isDisabled() || app.mk.queue._position + 1 === app.mk.queue.length; + }, + + switchArtworkDisplayLayout() { + switch (app.cfg.visual.artworkDisplayLayout) { + case "default": + app.cfg.visual.artworkDisplayLayout = "sidebar"; + break; + case "sidebar": + app.cfg.visual.artworkDisplayLayout = "default"; + break; + default: + app.cfg.visual.artworkDisplayLayout = "default"; + break; + } + }, + + async getNowPlayingItemDetailed(target) { + let nowPlayingItem = JSON.parse(JSON.stringify(this.mk.nowPlayingItem)); + if (nowPlayingItem.type === "radioStation" && app.mk.nowPlayingItem.id !== -1) { + nowPlayingItem.playParams = { kind: "songs" }; + nowPlayingItem.attributes.playParams.catalogId = app.mk.nowPlayingItem.id; + nowPlayingItem.attributes.playParams.id = app.mk.nowPlayingItem.id; + nowPlayingItem.id = app.mk.nowPlayingItem.id; + } + try { + let u = await app.mkapi(nowPlayingItem.playParams.kind, nowPlayingItem.songId == -1, nowPlayingItem.songId != -1 ? nowPlayingItem.songId : nowPlayingItem["id"], { "include[songs]": "albums,artists", l: app.mklang }); + app.searchAndNavigate(u.data.data[0], target); + } catch (e) { + app.searchAndNavigate(nowPlayingItem, target); + } + }, + async searchAndNavigate(item, target) { + let self = this; + app.tmpVar = item; + switch (target) { + case "artist": + let artistId = ""; + try { + if (item.relationships.artists && item.relationships.artists.data.length > 0 && !item.relationships.artists.data[0].type.includes("library")) { + if (item.relationships.artists.data[0].type === "artist" || item.relationships.artists.data[0].type === "artists") { + artistId = item.relationships.artists.data[0].id; + } + } + if (item.relationships.albums && item.relationships.albums.data.length > 0) { + if (item.relationships.albums.data[0].attributes.artistUrl) { + artistId = item.relationships.albums.data[0].attributes.artistUrl.split("/").pop(); + } + } + if (artistId == "") { + const url = item.relationships.catalog.data[0].attributes.artistUrl; + artistId = url.substring(url.lastIndexOf("/") + 1); + if (artistId.includes("viewCollaboration")) { + artistId = artistId.substring(artistId.lastIndexOf("ids=") + 4, artistId.lastIndexOf("-")); + } + } + } catch (_) {} + + if (artistId == "") { + let artistQuery = ( + await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.artistName}`, { + limit: 1, + types: "artists", + }) + ).data.results; + try { + if (artistQuery.artists.data.length > 0) { + artistId = artistQuery.artists.data[0].id; + console.debug(artistId); + } + } catch (e) {} + } + console.debug(artistId); + if (artistId != "") self.appRoute(`artist/${artistId}`); + break; + case "album": + let albumId = ""; + try { + if ((item.type ?? item.playParams?.kind ?? "") == "albums") { + albumId = item.id ?? ""; + } else if (item.relationships.albums && item.relationships.albums.data.length > 0 && !item.relationships.albums.data[0].type.includes("library")) { + if (item.relationships.albums.data[0].type === "album" || item.relationships.albums.data[0].type === "albums") { + albumId = item.relationships.albums.data[0].id; + } + } + if (albumId == "") { + const url = item.relationships.catalog.data[0].attributes.url; + albumId = url.substring(url.lastIndexOf("/") + 1); + if (albumId.includes("?i=")) { + albumId = albumId.substring(0, albumId.indexOf("?i=")); + } + } + } catch (_) {} + + if (albumId == "") { + try { + let albumQuery = ( + await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${(item.attributes.albumName ?? item.attributes.name ?? "") + " " + (item.attributes.artistName ?? "")}`, { + limit: 1, + types: "albums", + }) + ).data.results; + if (albumQuery.albums.data.length > 0) { + albumId = albumQuery.albums.data[0].id; + console.debug(albumId); + } + } catch (e) {} + } + if (albumId != "") { + self.appRoute(`album/${albumId}`); + } + break; + case "recordLabel": + let labelId = ""; + try { + labelId = item.relationships["record-labels"].data[0].id; + } catch (_) {} + + if (labelId == "") { + try { + let labelQuery = ( + await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.recordLabel}`, { + limit: 1, + types: "record-labels", + }) + ).data.results; + if (labelQuery["record-labels"].data.length > 0) { + labelId = labelQuery["record-labels"].data[0].id; + console.debug(labelId); + } + } catch (e) {} + } + if (labelId != "") { + app.showingPlaylist = []; + await app.getTypeFromID("recordLabel", labelId, false, { + views: "top-releases,latest-releases,top-artists", + }); + app.page = "recordLabel_" + labelId; + } + + break; + } + }, + exitMV() { + MusicKit.getInstance().stop(); + document.getElementById("apple-music-video-container").style.display = "none"; + }, + getArtistInfo(id, isLibrary) { + this.getArtistFromID(id); + //this.getTypeFromID("artist",id,isLibrary,query) + }, + followingArtist(id) { + console.debug(`check for ${id}`); + return this.cfg.home.followedArtists.includes(id); + }, + playMediaItem(item) { + let kind = item.attributes.playParams ? item.attributes.playParams.kind ?? item.type ?? "" : item.type ?? ""; + let id = item.attributes.playParams ? item.attributes.playParams.id ?? item.id ?? "" : item.id ?? ""; + let isLibrary = item.attributes.playParams ? item.attributes.playParams.isLibrary ?? false : false; + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + // console.log(kind, id, isLibrary) + app.mk.stop().then(() => { + if (kind.includes("artist")) { + app.mk.setStationQueue({ artist: "a-" + id }).then(() => { + app.mk.play(); + }); + } else { + app.playMediaItemById(id, kind, isLibrary, item.attributes.url ?? ""); + } + }); + }, + async getTypeFromID(kind, id, isLibrary = false, params = {}, params2 = {}) { + let a; + if ((kind == "album") | (kind == "albums")) { + params["include"] = "tracks,artists,record-labels,catalog"; + } + params["l"] = this.mklang; + try { + a = await this.mkapi(kind.toString(), isLibrary, id.toString(), params, params2); + } catch (e) { + console.debug(e); + try { + a = await this.mkapi(kind.toString(), !isLibrary, id.toString(), params, params2); + } catch (err) { + console.log(err); + a = []; + } finally { + if (kind == "appleCurator") { + app.appleCurator = a.data.data[0]; + } else if (kind == "multiroom" || kind == "room") { + app.multiroom = a.data.data[0]; + } else { + this.getPlaylistContinuous(a, true); + } + } + } finally { + if (kind == "appleCurator") { + app.appleCurator = a.data.data[0]; + } else if (kind == "multiroom" || kind == "room") { + app.multiroom = a.data.data[0]; + } else { + this.getPlaylistContinuous(a, true); + } + } + }, + searchLibrarySongs() { + let self = this; + let prefs = this.cfg.libraryPrefs.songs; + + function sortSongs() { + // sort this.library.songs.displayListing by song.attributes[self.library.songs.sorting] in descending or ascending order based on alphabetical order and numeric order + // check if song.attributes[self.library.songs.sorting] is a number and if so, sort by number if not, sort by alphabetical order ignoring case + self.library.songs.displayListing.sort((a, b) => { + let aa = a.attributes[prefs.sort]; + let bb = b.attributes[prefs.sort]; + if (prefs.sort === "genre") { + aa = a.attributes.genreNames[0]; + bb = b.attributes.genreNames[0]; + } else if (prefs.sort === "dateAdded") { + aa = a.relationships?.albums?.data[0]?.attributes?.dateAdded; + bb = b.relationships?.albums?.data[0]?.attributes?.dateAdded; + // if dateAdded is equal, an entire album was added at once, so sorting by track number (in reverse order because lower track number should be above in descending mode) + if (aa === bb) { + aa = b.attributes.trackNumber; + bb = a.attributes.trackNumber; + } + } else if (prefs.sort === "artistName") { + if (a.relationships?.artists?.data[0]?.id === b.relationships?.artists?.data[0]?.id) { + aa = a.attributes.albumName; + bb = b.attributes.albumName; + } + if (a.relationships?.albums?.data[0]?.id === b.relationships?.albums?.data[0]?.id) { + aa = a.attributes.trackNumber; + bb = b.attributes.trackNumber; + } + } else if (prefs.sort === "albumName") { + if (a.relationships?.albums?.data[0]?.id === b.relationships?.albums?.data[0]?.id) { + aa = a.attributes.trackNumber; + bb = b.attributes.trackNumber; + } + } + if (aa == null) { + aa = ""; + } + if (bb == null) { + bb = ""; + } + if (prefs.sortOrder === "asc") { + if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { + return aa - bb; + } else { + return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()); + } + } else if (prefs.sortOrder === "desc") { + if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { + return bb - aa; + } else { + return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()); + } + } + }); + } + + if (this.library.songs.search == "") { + this.library.songs.displayListing = this.library.songs.listing; + sortSongs(); + } else { + this.library.songs.displayListing = this.library.songs.listing.filter((item) => { + let itemName = item.attributes.name.toLowerCase(); + let searchTerm = this.library.songs.search.toLowerCase(); + let artistName = ""; + let albumName = ""; + if (item.attributes.artistName != null) { + artistName = item.attributes.artistName.toLowerCase(); + } + if (item.attributes.albumName != null) { + albumName = item.attributes.albumName.toLowerCase(); + } + + // remove any non-alphanumeric characters and spaces from search term and item name + searchTerm = searchTerm.replace(/[^\p{L}\p{N} ]/gu, ""); + itemName = itemName.replace(/[^\p{L}\p{N} ]/gu, ""); + artistName = artistName.replace(/[^\p{L}\p{N} ]/gu, ""); + albumName = albumName.replace(/[^\p{L}\p{N} ]/gu, ""); + + if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { + return item; + } + }); + sortSongs(); + } + }, + getAlbumSort() { + this.library.albums.sortOrder[1] = this.cfg.libraryPrefs.albums.sortOrder; + this.library.albums.sorting[1] = this.cfg.libraryPrefs.albums.sort; + }, + // make a copy of searchLibrarySongs except use Albums instead of Songs + searchLibraryAlbums(index) { + let self = this; + + function sortAlbums() { + // sort this.library.albums.displayListing by album.attributes[self.library.albums.sorting[index]] in descending or ascending order based on alphabetical order and numeric order + // check if album.attributes[self.library.albums.sorting[index]] is a number and if so, sort by number if not, sort by alphabetical order ignoring case + self.library.albums.displayListing.sort((a, b) => { + let aa = a.attributes[self.library.albums.sorting[index]]; + let bb = b.attributes[self.library.albums.sorting[index]]; + if (self.library.albums.sorting[index] == "genre") { + aa = a.attributes.genreNames[0]; + bb = b.attributes.genreNames[0]; + } else if (self.library.albums.sorting[index] === "dateAdded") { + aa = a.attributes?.dateAdded; + bb = b.attributes?.dateAdded; + } + if (aa == null) { + aa = ""; + } + if (bb == null) { + bb = ""; + } + if (self.library.albums.sortOrder[index] == "asc") { + if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { + return aa - bb; + } else { + return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()); + } + } else if (self.library.albums.sortOrder[index] == "desc") { + if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { + return bb - aa; + } else { + return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()); + } + } + }); + } + + if (this.library.albums.search == "") { + this.library.albums.displayListing = this.library.albums.listing; + sortAlbums(); + } else { + this.library.albums.displayListing = this.library.albums.listing.filter((item) => { + let itemName = item.attributes.name.toLowerCase(); + let searchTerm = this.library.albums.search.toLowerCase(); + let artistName = ""; + let albumName = ""; + if (item.attributes.artistName != null) { + artistName = item.attributes.artistName.toLowerCase(); + } + if (item.attributes.albumName != null) { + albumName = item.attributes.albumName.toLowerCase(); + } + + // remove any non-alphanumeric characters and spaces from search term and item name + searchTerm = searchTerm.replace(/[^\p{L}\p{N} ]/gu, ""); + itemName = itemName.replace(/[^\p{L}\p{N} ]/gu, ""); + artistName = artistName.replace(/[^\p{L}\p{N} ]/gu, ""); + albumName = albumName.replace(/[^\p{L}\p{N} ]/gu, ""); + + if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { + return item; + } + }); + sortAlbums(); + } + }, + // make a copy of searchLibrarySongs except use Albums instead of Songs + searchLibraryArtists(index) { + let self = this; + + function sortArtists() { + // sort this.library.albums.displayListing by album.attributes[self.library.albums.sorting[index]] in descending or ascending order based on alphabetical order and numeric order + // check if album.attributes[self.library.albums.sorting[index]] is a number and if so, sort by number if not, sort by alphabetical order ignoring case + self.library.artists.displayListing.sort((a, b) => { + let aa = a.attributes[self.library.artists.sorting[index]]; + let bb = b.attributes[self.library.artists.sorting[index]]; + if (self.library.artists.sorting[index] == "genre") { + aa = a.attributes.genreNames[0]; + bb = b.attributes.genreNames[0]; + } + if (aa == null) { + aa = ""; + } + if (bb == null) { + bb = ""; + } + if (self.library.artists.sortOrder[index] == "asc") { + if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { + return aa - bb; + } else { + return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()); + } + } else if (self.library.artists.sortOrder[index] == "desc") { + if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { + return bb - aa; + } else { + return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()); + } + } + }); + } + + if (this.library.artists.search == "") { + this.library.artists.displayListing = this.library.artists.listing; + sortArtists(); + } else { + this.library.artists.displayListing = this.library.artists.listing.filter((item) => { + let itemName = item.attributes.name.toLowerCase(); + let searchTerm = this.library.artists.search.toLowerCase(); + let artistName = ""; + let albumName = ""; + // if (item.attributes.artistName != null) { + // artistName = item.attributes.artistName.toLowerCase() + // } + // if (item.attributes.albumName != null) { + // albumName = item.attributes.albumName.toLowerCase() + // } + + // remove any non-alphanumeric characters and spaces from search term and item name + searchTerm = searchTerm.replace(/[^\p{L}\p{N} ]/gu, ""); + itemName = itemName.replace(/[^\p{L}\p{N} ]/gu, ""); + + if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { + return item; + } + }); + sortArtists(); + } + }, + focusSearch() { + app.appRoute("search"); + const search = document.getElementsByClassName("search-input"); + if (search.length > 0) { + search[0].focus(); + } + }, + getSidebarItemClass(page) { + if (this.page == page) { + return ["active"]; + } else { + return []; + } + }, + async mkapi(method, library = false, term, params = {}, params2 = {}, attempts = 0) { + if (method.includes(`recordLabel`)) { + method = `record-labels`; + } + if (method.includes(`appleCurator`)) { + method = `apple-curators`; + } + if (attempts > 3) { + return; + } + let truemethod = !method.endsWith("s") ? method + "s" : method; + try { + if (method.includes(`room`)) { + return await this.mk.api.v3.music(`v1/editorial/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2); + } else if (library) { + return await this.mk.api.v3.music(`v1/me/library/${truemethod}/${term.toString()}`, params, params2); + } else { + return await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2); + } + } catch (e) { + console.debug(e); + return await this.mkapi(method, library, term, params, params2, attempts + 1); + } + }, + getLibraryGenres() { + let genres = []; + genres = []; + this.library.songs.listing.forEach((item) => { + item.attributes.genreNames.forEach((genre) => { + if (!genres.includes(genre)) { + genres.push(genre); + } + }); + }); + return genres; + }, + async getLibrarySongsFull(force = false) { + let self = this; + let library = []; + let cacheId = "library-songs"; + let downloaded = null; + this.$store.commit("resetRecentlyAdded"); + if (this.library.songs.downloadState == 2 && !force) { + return; + } + if (this.library.songs.downloadState == 1) { + return; + } + let librarySongs = await CiderCache.getCache(cacheId); + if (librarySongs) { + this.library.songs.listing.data = librarySongs; + this.searchLibrarySongs(); + } + if (this.songstest) { + return; + } + this.library.songs.downloadState = 1; + this.library.backgroundNotification.show = true; + this.library.backgroundNotification.message = app.getLz("notification.updatingLibrarySongs"); + + library = await MusicKitTools.v3Continuous({ + href: `/v1/me/library/songs/`, + options: { + "include[library-songs]": "catalog,artists,albums", + "fields[artists]": "name,url,id", + "fields[albums]": "name,url,id", + platform: "web", + "fields[catalog]": "artistUrl,albumUrl", + "fields[songs]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", + limit: 100, + l: app.mklang, + }, + onProgress: (data) => { + console.debug(`${data.total}/${data.response.data.meta.total}`); + self.library.backgroundNotification.show = true; + self.library.backgroundNotification.message = app.getLz("notification.updatingLibrarySongs"); + self.library.backgroundNotification.total = data.response.data.meta.total; + self.library.backgroundNotification.progress = data.total; + }, + onSuccess: () => {}, + }); + + self.library.songs.listing = library; + self.library.songs.downloadState = 2; + self.library.backgroundNotification.show = false; + self.searchLibrarySongs(); + CiderCache.putCache(cacheId, library); + console.debug("Done!"); + + return; + }, + // copy the getLibrarySongsFull function except change Songs to Albums + async getLibraryAlbumsFull(force = false, index) { + let self = this; + let library = []; + let cacheId = "library-albums"; + let downloaded = null; + if ((this.library.albums.downloadState == 2 || this.library.albums.downloadState == 1) && !force) { + return; + } + let libraryAlbums = await CiderCache.getCache(cacheId); + if (libraryAlbums) { + this.library.albums.listing = libraryAlbums; + this.searchLibraryAlbums(index); + } + if (this.songstest) { + return; + } + this.library.albums.downloadState = 1; + this.library.backgroundNotification.show = true; + this.library.backgroundNotification.message = app.getLz("notification.updatingLibraryAlbums"); + + function downloadChunk() { + self.library.albums.downloadState = 1; + const params = { + "include[library-albums]": "catalog,artists,albums", + "fields[artists]": "name,url,id", + // "fields[albums]": "name,url,id", + platform: "web", + "fields[catalog]": "artistUrl,albumUrl", + "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", + limit: 100, + l: self.mklang, + }; + const safeparams = { + platform: "web", + limit: "60", + "include[library-albums]": "artists", + "include[library-artists]": "catalog", + "include[albums]": "artists", + "fields[artists]": "name,url", + "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", + includeOnly: "catalog,artists", + }; + if (downloaded == null) { + app.mk.api.v3 + .music(`/v1/me/library/albums/`, params) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.debug("safe loading"); + app.mk.api.v3 + .music(`/v1/me/library/albums/`, safeparams) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.log("safe loading failed", error); + app.library.albums.downloadState = 2; + app.library.backgroundNotification.show = false; + }); + }); + } else { + if (downloaded.next != null) { + app.mk.api.v3 + .music(downloaded.next, params) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.debug("safe loading"); + app.mk.api.v3 + .music(downloaded.next, safeparams) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.log("safe loading failed", error); + app.library.albums.downloadState = 2; + app.library.backgroundNotification.show = false; + }); + }); + } else { + console.debug("Download next", downloaded.next); + } + } + } + + function processChunk(response) { + downloaded = response; + library = library.concat(downloaded.data); + self.library.backgroundNotification.show = true; + self.library.backgroundNotification.message = app.getLz("notification.updatingLibraryAlbums"); + self.library.backgroundNotification.total = downloaded.meta.total; + self.library.backgroundNotification.progress = library.length; + if (downloaded.meta.total == 0) { + self.library.albums.downloadState = 3; + return; + } + if (typeof downloaded.next == "undefined") { + console.debug("downloaded.next is undefined"); + self.library.albums.listing = library; + self.library.albums.downloadState = 2; + self.library.backgroundNotification.show = false; + CiderCache.putCache(cacheId, library); + self.searchLibraryAlbums(index); + } + if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { + console.debug(`downloading next chunk - ${library.length} albums so far`); + downloadChunk(); + } else { + self.library.albums.listing = library; + self.library.albums.downloadState = 2; + self.library.backgroundNotification.show = false; + CiderCache.putCache(cacheId, library); + self.searchLibraryAlbums(index); + // console.log(library) + } + } + + downloadChunk(); + }, + // copy the getLibrarySongsFull function except change Songs to Albums + async getLibraryArtistsFull(force = false, index) { + let self = this; + let library = []; + let cacheId = "library-artists"; + let downloaded = null; + if ((this.library.artists.downloadState == 2 || this.library.artists.downloadState == 1) && !force) { + return; + } + let libraryArtists = await CiderCache.getCache(cacheId); + if (libraryArtists) { + this.library.artists.listing = libraryArtists; + this.searchLibraryArtists(index); + } + if (this.songstest) { + return; + } + this.library.artists.downloadState = 1; + this.library.backgroundNotification.show = true; + this.library.backgroundNotification.message = app.getLz("notification.updatingLibraryArtists"); + + function downloadChunk() { + self.library.artists.downloadState = 1; + const params = { + include: "catalog", + // "include[library-artists]": "catalog,artists,albums", + // "fields[artists]": "name,url,id", + // "fields[albums]": "name,url,id", + platform: "web", + // "fields[catalog]": "artistUrl,albumUrl", + // "fields[artists]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", + limit: 100, + l: self.mklang, + }; + const safeparams = { + include: "catalog", + platform: "web", + limit: 50, + }; + if (downloaded == null) { + app.mk.api.v3 + .music(`/v1/me/library/artists/`, params) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.debug("safe loading"); + app.mk.api.v3 + .music(`/v1/me/library/artists/`, safeparams) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.log("safe loading failed", error); + app.library.artists.downloadState = 2; + app.library.backgroundNotification.show = false; + }); + }); + } else { + if (downloaded.next != null) { + app.mk.api.v3 + .music(downloaded.next, params) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.log("safe loading"); + app.mk.api.v3 + .music(downloaded.next, safeparams) + .then((response) => { + processChunk(response.data); + }) + .catch((error) => { + console.log("safe loading failed", error); + app.library.artists.downloadState = 2; + app.library.backgroundNotification.show = false; + }); + }); + } else { + console.log("Download next", downloaded.next); + } + } + } + + function processChunk(response) { + downloaded = response; + library = library.concat(downloaded.data); + self.library.backgroundNotification.show = true; + self.library.backgroundNotification.message = app.getLz("notification.updatingLibraryArtists"); + self.library.backgroundNotification.total = downloaded.meta.total; + self.library.backgroundNotification.progress = library.length; + if (downloaded.meta.total == 0) { + self.library.albums.downloadState = 3; + return; + } + if (typeof downloaded.next == "undefined") { + console.log("downloaded.next is undefined"); + self.library.artists.listing = library; + self.library.artists.downloadState = 2; + self.library.artists.show = false; + CiderCache.putCache(cacheId, library); + self.searchLibraryArtists(index); + } + if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { + console.log(`downloading next chunk - ${library.length} artists so far`); + downloadChunk(); + } else { + self.library.artists.listing = library; + self.library.artists.downloadState = 2; + self.library.backgroundNotification.show = false; + CiderCache.putCache(cacheId, library); + self.searchLibraryArtists(index); + // console.log(library) + } + } + + downloadChunk(); + }, + /** + * Gets the total duration in seconds of a playlist + * @returns {string} Total tracks, and duration + * @author Core#1034 + * @memberOf app + */ + getTotalTime() { + try { + if (app.showingPlaylist.relationships.tracks.data.length === 0) return ""; + const timeInSeconds = Math.round([].concat(...app.showingPlaylist.relationships.tracks.data).reduce((a, { attributes: { durationInMillis } }) => a + durationInMillis, 0) / 1000); + return `${app.showingPlaylist.relationships.tracks.data.length} ${app.getLz("term.track", { + count: app.showingPlaylist.relationships.tracks.data.length, + })}, ${app.convertTime(timeInSeconds, "long")}`; + } catch (err) { + return ""; + } + }, + async getLibrarySongs() { + let response = await this.mkapi("songs", true, "", { limit: 100, l: this.mklang }, { includeResponseMeta: !0 }); + this.library.songs.listing = response.data.data; + this.library.songs.meta = response.data.meta; + }, + async getLibraryAlbums() { + let response = await this.mkapi("albums", true, "", { limit: 100, l: this.mklang }, { includeResponseMeta: !0 }); + this.library.albums.listing = response.data.data; + this.library.albums.meta = response.data.meta; + }, + async getListenNow(attempt = 0) { + if (this.listennow.timestamp > Date.now() - 120000) { + return; + } + + if (attempt > 3) { + return; + } + try { + this.listennow = ( + await this.mk.api.v3.music( + `v1/me/recommendations?timezone=${encodeURIComponent(this.formatTimezoneOffset())}`, + { + name: "listen-now", + with: "friendsMix,library,social", + "art[social-profiles:url]": "c", + "art[url]": "c,f", + "omit[resource]": "autos", + "relate[editorial-items]": "contents", + extend: ["editorialCard", "editorialVideo"], + "extend[albums]": ["artistUrl"], + "extend[library-albums]": ["artistUrl", "editorialVideo"], + "extend[playlists]": ["artistNames", "editorialArtwork", "editorialVideo"], + "extend[library-playlists]": ["artistNames", "editorialArtwork", "editorialVideo"], + "extend[social-profiles]": "topGenreNames", + "include[albums]": "artists", + "include[songs]": "artists", + "include[music-videos]": "artists", + "include[personal-recommendation]": "primary-content", + "fields[albums]": ["artistName", "artistUrl", "artwork", "contentRating", "editorialArtwork", "editorialVideo", "name", "playParams", "releaseDate", "url"], + "fields[artists]": ["name", "url", "artwork"], + "extend[stations]": ["airDate", "supportsAirTimeUpdates"], + "meta[stations]": "inflectionPoints", + types: "artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-upsells", + platform: "web", + l: this.mklang, + }, + { + includeResponseMeta: !0, + reload: !0, + }, + ) + ).data; + this.listennow.timestamp = Date.now(); + console.debug(this.listennow); + } catch (e) { + console.log(e); + this.getListenNow(attempt + 1); + } + }, + async getRadioPage(attempt = 0) { + if (this.radio.timestamp > Date.now() - 120000) { + return; + } + if (attempt > 3) { + return; + } + try { + app.mk.api.v3 + .music(`/v1/editorial/${app.mk.storefrontId}/groupings`, { + platform: "web", + name: "radio", + "omit[resource:artists]": "relationships", + "include[albums]": "artists", + "include[songs]": "artists", + "include[music-videos]": "artists", + extend: "editorialArtwork,artistUrl", + "fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes", + "art[url]": "f", + l: app.mklang, + }) + .then((radio) => { + app.radio = radio.data.data[0]; + console.debug(app.radio); + }); + + this.radio.timestamp = Date.now(); + } catch (e) { + console.log(e); + this.getRadioPage(attempt + 1); + } + }, + async getBrowsePage(attempt = 0) { + if (this.browsepage.timestamp > Date.now() - 120000) { + return; + } + if (attempt > 3) { + return; + } + try { + let browse = await app.mk.api.v3.music(`/v1/editorial/${app.mk.storefrontId}/groupings`, { + platform: "web", + name: "music", + "omit[resource:artists]": "relationships", + "include[albums]": "artists", + "include[songs]": "artists", + "include[music-videos]": "artists", + extend: "editorialArtwork,artistUrl", + "fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes", + "art[url]": "f", + l: app.mklang, + }); + this.browsepage = browse.data.data[0]; + this.browsepage.timestamp = Date.now(); + console.debug(this.browsepage); + } catch (e) { + console.log(e); + this.getBrowsePage(attempt + 1); + } + }, + async getMadeForYou(attempt = 0) { + if (attempt > 3) { + return; + } + try { + let mfu = await app.mk.api.v3.music("/v1/me/library/playlists?platform=web&extend=editorialVideo&fields%5Bplaylists%5D=lastModifiedDate&filter%5Bfeatured%5D=made-for-you&include%5Blibrary-playlists%5D=catalog&fields%5Blibrary-playlists%5D=artwork%2Cname%2CplayParams%2CdateAdded"); + this.madeforyou = mfu.data; + } catch (e) { + console.log(e); + this.getMadeForYou(attempt + 1); + } + }, + newPlaylistFolder(name = app.getLz("term.newPlaylistFolder")) { + let self = this; + this.mk.api.v3 + .music( + "/v1/me/library/playlist-folders/", + {}, + { + fetchOptions: { + method: "POST", + body: JSON.stringify({ + attributes: { name: name }, + }), + }, + }, + ) + .then((res) => { + let playlist = res.data.data[0]; + self.playlists.listing.push({ + id: playlist.id, + attributes: { + name: playlist.attributes.name, + }, + type: "library-playlist-folders", + parent: "p.playlistsroot", + }); + self.sortPlaylists(); + setTimeout(() => { + app.refreshPlaylists(false, false); + }, 13000); + }); + }, + showSearch() { + this.page = "search"; + }, + loadLyrics() { + const musicType = MusicKit.getInstance().nowPlayingItem != null ? MusicKit.getInstance().nowPlayingItem["type"] ?? "" : ""; + // console.log("mt", musicType) + if (musicType === "musicVideo") { + this.loadYTLyrics(); + } else { + // only load MXM lyrics if AM lyrics failed to load + if (app.cfg.lyrics.enable_mxm) { + this.loadMXM(); + } else { + this.loadAMLyrics(); + } + } + }, + async loadAMLyrics() { + const songID = this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem["_songId"] ?? this.mk.nowPlayingItem["songId"] ?? -1 : -1; + // this.getMXM( trackName, artistName, 'en', duration); + if (songID != -1) { + try { + let response = await this.mk.api.v3.music(`v1/catalog/${this.mk.storefrontId}/songs/${songID}/lyrics`); + this.lyricsMediaItem = response.data?.data[0]?.attributes["ttml"]; + this.parseTTML(); + } catch (_) { + if (app.cfg.lyrics.enable_mxm) { + this.loadQQLyrics(); + } else { + this.loadMXM(); + } + } + } else { + if (app.cfg.lyrics.enable_mxm) { + this.loadQQLyrics(); // since mxm is already prioritized, we can just load qq lyrics if am fails + } else { + this.loadMXM(); + } + } + }, + addToLibrary(id) { + let self = this; + this.mk.addToLibrary(id).then((data) => { + self.getLibrarySongsFull(true); + }); + notyf.success(app.getLz("action.addToLibrary.success")); + }, + removeFromLibrary(kind, id) { + let self = this; + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + app.mk.api.v3 + .music( + `v1/me/library/${truekind}/${id.toString()}`, + {}, + { + fetchOptions: { + method: "DELETE", + }, + }, + ) + .then((data) => { + self.getLibrarySongsFull(true); + }); + notyf.success(app.getLz("action.removeFromLibrary.success")); + }, + async loadYTLyrics() { + const track = this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.title ?? "" : ""; + const artist = this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.artistName ?? "" : ""; + const time = this.mk.nowPlayingItem != null ? Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1 : -1; + ipcRenderer.invoke("getYTLyrics", track, artist).then((result) => { + if (result.length > 0) { + let ytid = result[0]["id"]["videoId"]; + if (app.cfg.lyrics.enable_yt) { + loadYT(ytid, app.cfg.lyrics.mxm_language ?? "en"); + } else { + app.loadMXM(); + } + } else { + app.loadMXM(); + } + + function loadYT(id, lang) { + let req = new XMLHttpRequest(); + let url = `https://www.youtube.com/watch?&v=${id}`; + req.open("GET", url, true); + req.onerror = function (e) { + this.loadMXM(); + }; + req.onload = function () { + // console.log(this.responseText); + let res = this.responseText; + let captionurl1 = res.substring(res.indexOf(`{"playerCaptionsRenderer":{"baseUrl":"`) + `{"playerCaptionsRenderer":{"baseUrl":"`.length); + let captionurl = captionurl1.substring(0, captionurl1.indexOf(`"`)); + if (captionurl.includes("timedtext")) { + let json = JSON.parse(`{"url": "${captionurl}"}`); + let newurl = json.url + `&lang=${lang}&format=ttml`; + + let req2 = new XMLHttpRequest(); + + req2.open("GET", newurl, true); + req2.onerror = function (e) { + app.loadMXM(); + }; + req2.onload = function () { + try { + const ttmlLyrics = this.responseText; + if (ttmlLyrics) { + this.lyricsMediaItem = ttmlLyrics; + this.parseTTML(); + } + } catch (e) { + app.loadMXM(); + } + }; + req2.send(); + } else { + app.loadMXM(); + } + }; + req.send(); + } + }); + }, + loadMXM() { + let attempt = 0; + const track = encodeURIComponent(this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.title ?? "" : ""); + const artist = encodeURIComponent(this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.artistName ?? "" : ""); + const time = encodeURIComponent(this.mk.nowPlayingItem != null ? Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1 : -1); + const id = encodeURIComponent(this.mk.nowPlayingItem != null ? app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem["songId"] ?? "" : ""); + let lrcfile = ""; + let richsync = []; + const lang = app.cfg.lyrics.mxm_language; // translation language + function revisedRandId() { + return Math.random() + .toString(36) + .replace(/[^a-z]+/g, "") + .slice(2, 10); + } + + /* get token */ + function getToken(mode, track, artist, songid, lang, time, id) { + if (attempt > 2) { + app.loadNeteaseLyrics(); + // app.loadAMLyrics(); + } else { + attempt = attempt + 1; + let url = "https://apic-desktop.musixmatch.com/ws/1.1/token.get?app_id=web-desktop-app-v1.0&t=" + revisedRandId(); + let req = new XMLHttpRequest(); + req.overrideMimeType("application/json"); + req.open("GET", url, true); + req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); + req.onload = function () { + try { + let jsonResponse = JSON.parse(this.responseText); + let status2 = jsonResponse["message"]["header"]["status_code"]; + if (status2 == 200) { + let token = jsonResponse["message"]["body"]["user_token"] ?? ""; + if (token != "" && token != "UpgradeOnlyUpgradeOnlyUpgradeOnlyUpgradeOnly") { + console.debug("200 token", mode); + // token good + app.mxmtoken = token; + + if (mode == 1) { + getMXMSubs(track, artist, app.mxmtoken, lang, time, id); + } else { + getMXMTrans(songid, lang, app.mxmtoken); + } + } else { + console.debug("fake 200 token"); + getToken(mode, track, artist, songid, lang, time); + } + } else { + // console.log('token 4xx'); + getToken(mode, track, artist, songid, lang, time); + } + } catch (e) { + console.log("error"); + app.loadQQLyrics(); + //app.loadAMLyrics(); + } + }; + req.onerror = function () { + console.log("error"); + app.loadQQLyrics(); + // app.loadAMLyrics(); + }; + req.send(); + } + } + + function getMXMSubs(track, artist, token, lang, time, id) { + let usertoken = encodeURIComponent(token); + let richsyncQuery = app.cfg.lyrics.mxm_karaoke ? "&optional_calls=track.richsync" : ""; + let timecustom = !time || (time && time < 0) ? "" : `&f_subtitle_length=${time}&q_duration=${time}&f_subtitle_length_max_deviation=40`; + let itunesid = id && id != "" ? `&track_itunes_id=${id}` : ""; + let url = "https://apic-desktop.musixmatch.com/ws/1.1/macro.subtitles.get?format=json&namespace=lyrics_richsynched" + richsyncQuery + "&subtitle_format=lrc&q_artist=" + artist + "&q_track=" + track + itunesid + "&usertoken=" + usertoken + timecustom + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId(); + let req = new XMLHttpRequest(); + req.overrideMimeType("application/json"); + req.open("GET", url, true); + req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); + req.onload = function () { + try { + let jsonResponse = JSON.parse(this.responseText); + console.debug(jsonResponse); + let status1 = jsonResponse["message"]["header"]["status_code"]; + + if (status1 == 200) { + let id = ""; + try { + if (jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["header"]["status_code"] == 200 && jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["header"]["status_code"] == 200) { + id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["track_id"] ?? ""; + lrcfile = jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["body"]["subtitle_list"][0]["subtitle"]["subtitle_body"]; + + try { + let lrcrich = jsonResponse["message"]["body"]["macro_calls"]["track.richsync.get"]["message"]["body"]["richsync"]["richsync_body"]; + richsync = JSON.parse(lrcrich); + app.richlyrics = richsync; + } catch (_) {} + } + + if (lrcfile == "") { + app.loadQQLyrics(); + // app.loadAMLyrics() + } else { + if (richsync == [] || richsync.length == 0) { + console.log("ok"); + // process lrcfile to json here + app.lyricsMediaItem = lrcfile; + let u = app.lyricsMediaItem.split(/[\r\n]/); + let preLrc = []; + for (var i = u.length - 1; i >= 0; i--) { + let xline = /(\[[0-9.:\[\]]*\])+(.*)/.exec(u[i]); + let end = preLrc.length > 0 ? preLrc[preLrc.length - 1].startTime ?? 99999 : 99999; + preLrc.push({ + startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, + endTime: end, + line: xline[2], + translation: "", + }); + } + if (preLrc.length > 0) + preLrc.push({ + startTime: 0, + endTime: preLrc[preLrc.length - 1].startTime, + line: "lrcInstrumental", + translation: "", + }); + app.lyrics = preLrc.reverse(); + } else { + let preLrc = richsync.map(function (item) { + return { + startTime: item.ts, + endTime: item.te, + line: item.x, + translation: "", + }; + }); + if (preLrc.length > 0) + preLrc.unshift({ + startTime: 0, + endTime: preLrc[0].startTime, + line: "lrcInstrumental", + translation: "", + }); + app.lyrics = preLrc; + } + if (lrcfile != null && lrcfile != "") { + // load translation + getMXMTrans(id, lang, token); + } else { + // app.loadAMLyrics() + app.loadQQLyrics(); + } + } + } catch (e) { + console.log(e); + app.loadQQLyrics(); + // app.loadAMLyrics() + } + } else { + //4xx rejected + getToken(1, track, artist, "", lang, time); + } + } catch (e) { + console.log(e); + app.loadQQLyrics(); + //app.loadAMLyrics() + } + }; + req.onerror = function () { + app.loadQQLyrics(); + console.log("error"); + // app.loadAMLyrics(); + }; + req.send(); + } + + function getMXMTrans(id, lang, token) { + if (lang != "disabled" && id != "") { + let usertoken = encodeURIComponent(token); + let url2 = "https://apic-desktop.musixmatch.com/ws/1.1/crowd.track.translations.get?translation_fields_set=minimal&selected_language=" + lang + "&track_id=" + id + "&comment_format=text&part=user&format=json&usertoken=" + usertoken + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId(); + let req2 = new XMLHttpRequest(); + req2.overrideMimeType("application/json"); + req2.open("GET", url2, true); + req2.setRequestHeader("authority", "apic-desktop.musixmatch.com"); + req2.onload = function () { + try { + let jsonResponse2 = JSON.parse(this.responseText); + console.log(jsonResponse2); + let status2 = jsonResponse2["message"]["header"]["status_code"]; + if (status2 == 200) { + try { + let preTrans = []; + let u = app.lyrics; + let translation_list = jsonResponse2["message"]["body"]["translations_list"]; + if (translation_list.length > 0) { + for (var i = 0; i < u.length - 1; i++) { + preTrans[i] = ""; + for (var trans_line of translation_list) { + if (u[i].line == " " + trans_line["translation"]["matched_line"] || u[i].line == trans_line["translation"]["matched_line"]) { + u[i].translation = trans_line["translation"]["description"]; + break; + } + } + } + app.lyrics = u; + } + } catch (e) { + /// not found trans -> ignore + } + } else { + //4xx rejected + getToken(2, "", "", id, lang, ""); + } + } catch (e) {} + }; + req2.send(); + } + } + + if ((track != "") & (track != "No Title Found")) { + if (app.mxmtoken != null && app.mxmtoken != "") { + getMXMSubs(track, artist, app.mxmtoken, lang, time, id); + } else { + getToken(1, track, artist, "", lang, time); + } + } + }, + loadNeteaseLyrics() { + const track = encodeURIComponent(this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.title ?? "" : ""); + const artist = encodeURIComponent(this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.artistName ?? "" : ""); + const time = encodeURIComponent(this.mk.nowPlayingItem != null ? Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1 : -1); + var url = `http://music.163.com/api/search/get/?csrf_token=hlpretag=&hlposttag=&s=${track + " " + artist}&type=1&offset=0&total=true&limit=6`; + var req = new XMLHttpRequest(); + req.overrideMimeType("application/json"); + req.open("GET", url, true); + req.onload = function () { + try { + var jsonResponse = JSON.parse(req.responseText); + var id = jsonResponse["result"]["songs"][0]["id"]; + var url2 = "https://music.163.com/api/song/lyric?os=pc&id=" + id + "&lv=-1&kv=-1&tv=-1"; + var req2 = new XMLHttpRequest(); + req2.overrideMimeType("application/json"); + req2.open("GET", url2, true); + req2.onload = function () { + try { + var jsonResponse2 = JSON.parse(req2.responseText); + var lrcfile = jsonResponse2["lrc"]["lyric"]; + app.lyricsMediaItem = lrcfile; + let u = app.lyricsMediaItem.split(/[\n]/); + let preLrc = []; + for (var i = u.length - 1; i >= 0; i--) { + let xline = /(\[[0-9.:\[\]]*\])+(.*)/.exec(u[i]); + if (xline != null) { + let end = preLrc.length > 0 ? preLrc[preLrc.length - 1].startTime ?? 99999 : 99999; + preLrc.push({ + startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, + endTime: end, + line: xline[2], + translation: "", + }); + } + } + if (preLrc.length > 0) + preLrc.push({ + startTime: 0, + endTime: preLrc[preLrc.length - 1].startTime, + line: "lrcInstrumental", + translation: "", + }); + app.lyrics = preLrc.reverse(); + } catch (e) { + app.lyrics = ""; + } + }; + req2.onerror = function () {}; + req2.send(); + } catch (e) { + app.lyrics = ""; + } + }; + req.send(); + req.onerror = function () {}; + }, + loadQQLyrics() { + if (!app.cfg.lyrics.enable_qq) return; + const track = encodeURIComponent(this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.title ?? "" : ""); + const artist = encodeURIComponent(this.mk.nowPlayingItem != null ? this.mk.nowPlayingItem.artistName ?? "" : ""); + const time = encodeURIComponent(this.mk.nowPlayingItem != null ? Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1 : -1); + var url = `https://c.y.qq.com/soso/fcgi-bin/client_search_cp?w=${track + " " + artist}&t=0&n=1&page=1&cr=1&new_json=1&format=json&platform=yqq.json`; + + var req = new XMLHttpRequest(); + req.overrideMimeType("application/json"); + req.open("GET", url, true); + req.onload = function () { + try { + var jsonResponse = JSON.parse(req.responseText); + let id = jsonResponse?.data?.song?.list[0]?.mid; + console.log(jsonResponse); + let usz = new Date().getTime(); + var url2 = `https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?-=MusicJsonCallback_lrc&songmid=${id}&pcachetime=${usz}&g_tk=5381&loginUin=3003436226&hostUin=0&inCharset=utf-8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0`; + var req2 = new XMLHttpRequest(); + req2.overrideMimeType("application/json"); + req2.open("GET", url2, true); + req2.onload = function () { + try { + function b64_to_utf8(str) { + return decodeURIComponent(escape(window.atob(str))); + } + + const htmlDecode = (input) => { + const doc = new DOMParser().parseFromString(input, "text/html"); + return doc.documentElement.textContent; + }; + var jsonResponse2 = JSON.parse(req2.responseText.replace("MusicJsonCallback(", "").replace("})", "}")); + var lrcfile = htmlDecode(b64_to_utf8(jsonResponse2["lyric"])); + app.lyricsMediaItem = lrcfile; + let u = app.lyricsMediaItem.split(/[\n]/); + + let preLrc = []; + for (var i = u.length - 1; i >= 0; i--) { + let xline = /(\[[0-9.:\[\]]*\])+(.*)/.exec(u[i]); + if (xline != null) { + let end = preLrc.length > 0 ? preLrc[preLrc.length - 1].startTime ?? 99999 : 99999; + preLrc.push({ + startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, + endTime: end, + line: xline[2], + translation: "", + }); + } + } + if (preLrc.length > 0) + preLrc.push({ + startTime: 0, + endTime: preLrc[preLrc.length - 1].startTime, + line: "lrcInstrumental", + translation: "", + }); + app.lyrics = preLrc.reverse(); + if (app.lyrics[5].line == "") { + app.loadNeteaseLyrics(); + } // Detect incomplete QQ lyrics. + } catch (e) { + console.log(e); + app.loadNeteaseLyrics(); + app.lyrics = ""; + } + }; + req2.onerror = function () { + app.loadNeteaseLyrics(); + }; + req2.send(); + } catch (e) { + console.log(e); + app.loadNeteaseLyrics(); + app.lyrics = ""; + } + }; + req.onerror = function () { + app.loadNeteaseLyrics(); + }; + req.send(); + }, + toMS(str) { + let rawTime = str.match(/(\d+:)?(\d+:)?(\d+)(\.\d+)?/); + let hours = rawTime[2] != null ? rawTime[1].replace(":", "") : 0; + let minutes = rawTime[2] != null ? hours * 60 + rawTime[2].replace(":", "") * 1 : rawTime[1] != null ? rawTime[1].replace(":", "") : 0; + let seconds = rawTime[3] != null ? rawTime[3] : 0; + let milliseconds = rawTime[4] != null ? rawTime[4].replace(".", "") : 0; + return parseFloat(`${minutes * 60 + seconds * 1}.${milliseconds * 1}`); + }, + parseTTML() { + this.lyrics = []; + let preLrc = []; + let xml = this.stringToXml(this.lyricsMediaItem); + let lyricsLines = xml.getElementsByTagName("p"); + let synced = true; + let endTimes = []; + if (xml.getElementsByTagName("tt")[0].getAttribute("itunes:timing") === "None") { + synced = false; + } + endTimes.push(0); + if (synced) { + for (let element of lyricsLines) { + let start = this.toMS(element.getAttribute("begin")); + let end = this.toMS(element.getAttribute("end")); + if (start - endTimes[endTimes.length - 1] > 5 && endTimes[endTimes.length - 1] != 0) { + preLrc.push({ + startTime: endTimes[endTimes.length - 1], + endTime: start, + line: "lrcInstrumental", + }); + } + preLrc.push({ + startTime: start, + endTime: end, + line: element.textContent, + }); + endTimes.push(end); + } + // first line dot + if (preLrc.length > 0) + preLrc.unshift({ + startTime: 0, + endTime: preLrc[0].startTime, + line: "lrcInstrumental", + }); + } else { + for (let element of lyricsLines) { + preLrc.push({ + startTime: 9999999, + endTime: 9999999, + line: element.textContent, + }); + } + } + this.lyrics = preLrc; + }, + parseLyrics() { + let xml = this.stringToXml(this.lyricsMediaItem); + let json = xmlToJson(xml); + this.lyrics = json; + }, + stringToXml(st) { + // string to xml + let xml = new DOMParser().parseFromString(st, "text/xml"); + return xml; + }, + getCurrentTime() { + return parseFloat(this.hmsToSecondsOnly(this.parseTime(this.mk.nowPlayingItem.attributes.durationInMillis - app.mk.currentPlaybackTimeRemaining * 1000))); + }, + seekTo(time) { + this.mk.seekToTime(time); + }, + parseTime(value) { + let minutes = Math.floor(value / 60000); + let seconds = ((value % 60000) / 1000).toFixed(0); + return minutes + ":" + (seconds < 10 ? "0" : "") + seconds; + }, + parseTimeDecimal(value) { + let minutes = Math.floor(value / 60000); + let seconds = ((value % 60000) / 1000).toFixed(0); + return minutes + "." + (seconds < 10 ? "0" : "") + seconds; + }, + hmsToSecondsOnly(str) { + let p = str.split(":"), + s = 0, + m = 1; + + while (p.length > 0) { + s += m * parseInt(p.pop(), 10); + m *= 60; + } + + return s; + }, + getLyricBGStyle(start, end) { + let currentTime = this.getCurrentTime(); + // let duration = this.mk.nowPlayingItem.attributes.durationInMillis + let start2 = this.hmsToSecondsOnly(start); + let end2 = this.hmsToSecondsOnly(end); + // let currentProgress = ((100 * (currentTime)) / (end2)) + // check if currenttime is between start and end + this.player.lyricsDebug.start = start2; + this.player.lyricsDebug.end = end2; + this.player.lyricsDebug.current = currentTime; + if (currentTime >= start2 && currentTime <= end2) { + return { + "--bgSpeed": `${end2 - start2}s`, + }; + } else { + return {}; + } + }, + playMediaItemById(id, kind, isLibrary, raurl = "") { + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + console.debug(id, truekind, isLibrary); + try { + if (truekind.includes("artist")) { + app.mk.setStationQueue({ artist: "a-" + id }).then(() => { + app.mk.play(); + }); + } else if (truekind == "radioStations") { + this.mk.setStationQueue({ url: raurl }).then(function (queue) { + MusicKit.getInstance().play(); + }); + } else { + this.mk + .setQueue({ + [truekind]: [id], + parameters: { l: this.mklang }, + }) + .then(function (queue) { + MusicKit.getInstance().play(); + }); + } + } catch (err) { + console.log(err); + this.playMediaItemById(id, kind, isLibrary, raurl); + } + }, + queueParentandplayChild(parent, childIndex, item) { + /* Randomize array in-place using Durstenfeld shuffle algorithm */ + function shuffleArray(array) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + } + + let kind = parent.substring(0, parent.indexOf(":")); + let id = parent.substring(parent.indexOf(":") + 1, parent.length); + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + console.log(truekind, id); + + try { + if (parent == "playlist:ciderlocal") { + let u = app.library.localsongs.map((i) => { + return i.id; + }); + app.mk.setQueue({ episodes: u }).then(() => { + let id = app.mk.queue._itemIDs.findIndex((element) => element == item.id); + app.mk.changeToMediaAtIndex(id); + }); + } else if (app.library.songs.displayListing.length > childIndex && parent == "librarysongs") { + console.log(item); + if (item && app.library.songs.displayListing[childIndex].id != item.id) { + childIndex = app.library.songs.displayListing.indexOf(item); + } + + let query = app.library.songs.displayListing.map((item) => new MusicKit.MediaItem(item)); + + app.mk.stop().then(() => { + if (item) { + app.mk + .setQueue({ + [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id, + parameters: { l: app.mklang }, + }) + .then(function () { + app.mk.play().then(() => { + if (app.mk.shuffleMode == 1) { + shuffleArray(query); + } else { + for (let i = 0; i < query.length; i++) { + if (query[i].id == item.id) { + query.splice(0, i + 1); + break; + } + } + } + app.mk.queue.append(query); + }); + }); + } else { + app.mk.queue.splice(0, app.mk.queue._itemIDs.length); + if (app.mk.shuffleMode == 1) { + shuffleArray(query); + } + app.mk.queue.append(query); + if (childIndex != -1) { + app.mk.changeToMediaAtIndex(childIndex); + } else { + app.mk.play(); + } + } + }); + } else if (parent.startsWith("listitem-hr")) { + app.mk.stop().then(() => { + if (app.mk.shuffleMode == 1) { + app.mk + .setQueue({ + [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id, + }) + .then(function () { + app.mk.play().then(() => { + let data = JSON.parse(parent.split("listitem-hr")[1] ?? "[]"); + let itemsToPlay = {}; + let u = data.map((x) => x.id); + try { + data.splice(u.indexOf(item.attributes.playParams.id ?? item.id), 1); + } catch (e) {} + if (app.mk.shuffleMode == 1) { + shuffleArray(data); + } + data.forEach((item) => { + if (!itemsToPlay[item.kind]) { + itemsToPlay[item.kind] = []; + } + itemsToPlay[item.kind].push(item.id); + }); + // loop through itemsToPlay + for (let kind in itemsToPlay) { + let ids = itemsToPlay[kind]; + if (ids.length > 0) { + app.mk.playLater({ [kind + "s"]: itemsToPlay[kind] }); + } + } + }); + }); + } else { + let data = JSON.parse(parent.split("listitem-hr")[1] ?? "[]"); + let itemsToPlay = {}; + data.forEach((item) => { + if (!itemsToPlay[item.kind]) { + itemsToPlay[item.kind] = []; + } + itemsToPlay[item.kind].push(item.id); + }); + // loop through itemsToPlay + app.mk.queue.splice(0, app.mk.queue._itemIDs.length); + let ind = 0; + for (let kind in itemsToPlay) { + let ids = itemsToPlay[kind]; + if (ids.length > 0) { + if (app.mk.queue._itemIDs.length > 0) { + app.mk.playLater({ [kind + "s"]: itemsToPlay[kind] }).then(function () { + ind += 1; + console.log(ind, Object.keys(itemsToPlay).length); + if (ind >= Object.keys(itemsToPlay).length) { + app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.attributes.playParams.id ?? item.id)); + } + }); + } else { + app.mk.setQueue({ [kind + "s"]: itemsToPlay[kind] }).then(function () { + ind += 1; + console.log(ind, Object.keys(itemsToPlay).length); + if (ind >= Object.keys(itemsToPlay).length) { + app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.attributes.playParams.id ?? item.id)); + } + }); + } + } + } + } + }); + } else { + app.mk.stop().then(() => { + if (truekind == "playlists" && (id.startsWith("p.") || id.startsWith("pl.u"))) { + app.mk + .setQueue({ + [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id, + parameters: { l: app.mklang }, + }) + .then(function () { + app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1).then(function () { + if (app.showingPlaylist && app.showingPlaylist.id == id) { + let query = app.showingPlaylist.relationships.tracks.data.map((item) => new MusicKit.MediaItem(item)); + let u = query; + if (app.mk.shuffleMode == 1) { + shuffleArray(u); + } else { + for (let i = 0; i < app.showingPlaylist.relationships.tracks.data.length; i++) { + if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) { + u.splice(0, i + 1); + break; + } + } + } + app.mk.queue.append(u); + } else { + app.getPlaylistFromID(id, true).then(function () { + let query = app.showingPlaylist.relationships.tracks.data.map((item) => new MusicKit.MediaItem(item)); + let u = query; + if (app.mk.shuffleMode == 1) { + shuffleArray(u); + } else { + for (let i = 0; i < app.showingPlaylist.relationships.tracks.data.length; i++) { + if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) { + u.splice(0, i + 1); + break; + } + } + } + app.mk.queue.append(u); + }); + } + }); + }); + } else { + this.mk + .setQueue({ + [truekind]: [id], + parameters: { l: this.mklang }, + }) + .then(function (queue) { + if (item && queue._itemIDs[childIndex] != item.id) { + childIndex = queue._itemIDs.indexOf(item.id); + } + if (childIndex != -1) { + app.mk.changeToMediaAtIndex(childIndex); + } else if (item) { + app.mk + .playNext({ + [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id, + }) + .then(function () { + app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1); + app.mk.play(); + }); + } else { + app.mk.play(); + } + }); + } + }); + } + } catch (err) { + console.log(err); + try { + app.mk.stop(); + } catch (e) {} + this.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url); + } + }, + friendlyTypes(type) { + // use switch statement to return friendly name for media types "songs,artists,albums,playlists,music-videos,stations,apple-curators,curators" + switch (type) { + case "library-songs": + return app.getLz("term.songs"); + break; + case "library-artists": + return app.getLz("term.artists"); + break; + case "library-albums": + return app.getLz("term.albums"); + break; + case "library-playlists": + return app.getLz("term.playlists"); + break; + case "song": + return app.getLz("term.songs"); + break; + case "artist": + return app.getLz("term.artists"); + break; + case "album": + return app.getLz("term.albums"); + break; + case "playlist": + return app.getLz("term.playlists"); + break; + case "music_video": + return app.getLz("term.musicVideos"); + break; + case "station": + return app.getLz("term.stations"); + break; + case "apple-curator": + return app.getLz("term.appleCurators"); + break; + case "radio_show": + return app.getLz("term.radioShows"); + break; + case "record_label": + return app.getLz("term.recordLabels"); + break; + case "radio_episode": + return app.getLz("podcast.episodes"); + break; + case "video_extra": + return app.getLz("term.videoExtras"); + break; + case "curator": + return app.getLz("term.curators"); + break; + case "top": + return app.getLz("term.top"); + break; + default: + return type; + break; + } + }, + searchCursor(e) { + if (e.keyCode == "40") { + if (this.search.hints.length - 1 < this.search.cursor + 1) return; + this.search.cursor++; + let item = this.search.hints[this.search.cursor]; + this.search.term = item.content ? item.content?.attributes?.name ?? "" : item.displayTerm; + } else if (e.keyCode == "38") { + if (this.search.cursor == 0) return; + this.search.cursor--; + let item = this.search.hints[this.search.cursor]; + this.search.term = item.content ? item.content?.attributes?.name ?? "" : item.displayTerm; + } + }, + async searchQuery(term = this.search.term) { + let self = this; + if (typeof term === "object") { + this.routeView(term); + this.search.term = ""; + return; + } + if (term == "") { + return; + } + //this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${this.search.term}` + this.mk.api.v3 + .music(`/v1/catalog/${app.mk.storefrontId}/search?term=${encodeURIComponent(this.search.term)}`, { + types: "activities,albums,apple-curators,artists,curators,editorial-items,music-movies,music-videos,playlists,songs,stations,tv-episodes,uploaded-videos,record-labels", + "relate[editorial-items]": "contents", + "include[editorial-items]": "contents", + "include[albums]": "artists", + "include[artists]": "artists", + "include[songs]": "artists,albums", + "include[music-videos]": "artists", + extend: "artistUrl", + "fields[artists]": "url,name,artwork,hero", + "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url", + with: "serverBubbles,lyricHighlights", + "art[url]": "c,f", + "omit[resource]": "autos", + platform: "web", + limit: 25, + l: this.mklang, + }) + .then(function (results) { + results.data.results["meta"] = results.data.meta; + self.search.results = results.data.results; + }); + + await app.mk.api.v3 + .music( + `v1/social/${app.mk.storefrontId}/search?term=${app.search.term}`, + { + types: ["playlists", "social-profiles"], + limit: 25, + with: ["serverBubbles", "lyricSnippet"], + "art[url]": "f", + "art[social-profiles:url]": "c", + }, + { includeResponseMeta: !0 }, + ) + .then(function (results) { + results.data.results["meta"] = results.data.meta; + self.search.resultsSocial = results.data.results; + }); + + this.search.resultsLibrary = await app.mk.api.library.search(app.search.term, { + types: "library-songs,library-albums,library-playlists,library-artists", + limit: 25, + offset: 0, + }); + }, + async inLibrary(items = []) { + let types = []; + + for (let item of items) { + let type = item.type; + if (type.slice(-1) != "s") { + type += "s"; + } + type = type.replace("library-", ""); + let id = item.attributes.playParams?.catalogId ?? item.attributes.playParams.id ?? item.id; + + let index = types.findIndex(function (type) { + return type.type == this; + }, type); + if (index == -1) { + types.push({ type: type, id: [id] }); + } else { + types[index].id.push(id); + } + } + let types2 = types.map(function (item) { + return { + [`ids[${item.type}]`]: [item.id], + }; + }); + types2 = types2.reduce(function (result, item) { + var key = Object.keys(item)[0]; //first property: a, b, c + result[key] = item[key]; + return result; + }, {}); + return ( + await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}`, { + ...{ + "omit[resource]": "autos", + relate: "library", + fields: "inLibrary", + }, + ...types2, + }) + ).data.data; + }, + isInLibrary(playParams) { + let self = this; + let id = ""; + // ugly code to check if current playback item is in library + if (typeof playParams == "undefined") { + return true; + } + if (playParams["isLibrary"]) { + return true; + } else if (playParams["catalogId"]) { + id = playParams["catalogId"]; + } else if (playParams["id"]) { + id = playParams["id"]; + } + let found = this.library.songs.listing.filter((item) => { + if (item["attributes"]) { + if (item["attributes"]["playParams"] && item["attributes"]["playParams"]["catalogId"] == id) { + return item; + } + } + }); + if (found.length != 0) { + return true; + } else { + return false; + } + }, + mkReady() { + if (this.mk["nowPlayingItem"]) { + return true; + } else { + return false; + } + }, + getMediaItemArtwork(url, height = 64, width) { + try { + if (typeof url == "undefined" || url == "") { + return "./assets/MissingArtwork.svg"; + } + height = parseInt(height * window.devicePixelRatio); + if (width) { + width = parseInt(width * window.devicePixelRatio); + } + let newurl = `${(url ?? "") + .replace("{w}", width ?? height) + .replace("{h}", height) + .replace("{f}", "webp") + .replace("{c}", width === 900 || width === 380 || width === 600 ? "sr" : "cc")}`; + + if (newurl.includes("900x516")) { + newurl = newurl.replace("900x516cc", "900x516sr").replace("900x516bb", "900x516sr"); + } + return newurl; + } catch (e) { + console.log(url); + return "./assets/MissingArtwork.svg"; + } + }, + _rgbToRgb(rgb = [0, 0, 0]) { + // if rgb + return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`; + }, + getNowPlayingArtworkBG(size = 32, force = false) { + let self = this; + if (typeof this.mk.nowPlayingItem === "undefined") return; + let bginterval = setInterval(() => { + if (!this.mkReady()) { + return ""; + } + + try { + if ((this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] != this.currentTrackID && document.querySelector(".bg-artwork")) || force) { + if (document.querySelector(".bg-artwork")) { + clearInterval(bginterval); + } + this.currentTrackID = this.mk.nowPlayingItem["id"]; + document.querySelector(".bg-artwork").src = ""; + if (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"]) { + getBase64FromUrl(this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"].replace("{w}", size).replace("{h}", size)).then((img) => { + document.querySelectorAll(".bg-artwork").forEach((artwork) => { + artwork.src = img; + }); + self.$store.commit("setLCDArtwork", img); + }); + try { + clearInterval(bginterval); + } catch (err) {} + } else { + this.setLibraryArtBG(); + } + } else if (this.mk.nowPlayingItem["id"] == this.currentTrackID) { + try { + clearInterval(bginterval); + } catch (err) {} + } + } catch (e) { + if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] && document.querySelector(".bg-artwork")) { + this.setLibraryArtBG(); + try { + clearInterval(bginterval); + } catch (err) {} + } + } + }, 200); + }, + async getCurrentArtURL() { + let artworkSize = 50; + if (app.getThemeDirective("lcdArtworkSize") !== "") { + artworkSize = app.getThemeDirective("lcdArtworkSize"); + } else if (this.cfg.visual.directives.windowLayout === "twopanel") { + artworkSize = 110; + } + const mediaItem = (app?.mk?.nowPlayingItem?.attributes?.artwork?.url ? app?.mk?.nowPlayingItem : null) ?? (await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk?.nowPlayingItem?.id}`)?.data?.data?.data[0]) ?? {}; + return { currentArtUrlRaw: mediaItem?.attributes?.artwork?.url ?? "", currentArtUrl: mediaItem?._assets[0]?.artworkURL ?? mediaItem?.attributes?.artwork?.url?.replace("{w}", artworkSize).replace("{h}", artworkSize) }; + }, + async setLibraryArt() { + if (typeof this.mk.nowPlayingItem === "undefined") return; + try { + let data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); + data = data.data.data[0]; + + if (data != null && data !== "") { + document.querySelector(".app-playback-controls .artwork").style.setProperty("--artwork", 'url("' + data["attributes"]["artwork"]["url"].toString() + '")'); + } else { + document.querySelector(".app-playback-controls .artwork").style.setProperty("--artwork", `url("")`); + } + } catch (e) {} + }, + async setLibraryArtBG() { + if (typeof this.mk.nowPlayingItem === "undefined") return; + try { + let data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); + data = data.data.data[0]; + + if (data != null && data !== "") { + getBase64FromUrl(data["attributes"]["artwork"]["url"].toString()).then((img) => { + document.querySelector(".bg-artwork").forEach((artwork) => { + artwork.src = img; + }); + self.$store.commit("setLCDArtwork", img); + }); + } + } catch (e) {} + }, + quickPlay(query) { + let self = this; + MusicKit.getInstance() + .api.search(query, { limit: 2, types: "songs" }) + .then(function (data) { + MusicKit.getInstance() + .setQueue({ + song: data["songs"]["data"][0]["id"], + parameters: { l: app.mklang }, + }) + .then(function (queue) { + MusicKit.getInstance().play(); + setTimeout(() => { + self.$forceUpdate(); + }, 1000); + }); + }); + }, + async getRating(item) { + let type = item.type.slice(-1) === "s" ? item.type : item.type + "s"; + let id = item.attributes?.playParams?.catalogId ? item.attributes.playParams.catalogId : item.attributes?.playParams?.id ?? item.id; + if (item.id != null && item.id.toString().startsWith("i.")) { + if (!type.startsWith("library-")) { + type = "library-" + type; + } + id = item.id; + } + let response = await this.mk.api.v3.music(`/v1/me/ratings/${type}?platform=web&ids=${type.includes("library") ? item.id : id}`); + if (response.data.data.length != 0) { + let value = response.data.data[0].attributes.value; + return value; + } else { + return 0; + } + }, + love(item) { + let type = item.type.slice(-1) === "s" ? item.type : item.type + "s"; + let id = item.attributes?.playParams?.catalogId ? item.attributes.playParams.catalogId : item.attributes?.playParams?.id ?? item.id; + if (item.id != null && item.id.toString().startsWith("i.")) { + if (!type.startsWith("library-")) { + type = "library-" + type; + } + id = item.id; + } + this.mk.api.v3.music( + `/v1/me/ratings/${type}/${id}`, + {}, + { + fetchOptions: { + method: "PUT", + body: JSON.stringify({ + type: "rating", + attributes: { + value: 1, + }, + }), + }, + }, + ); + }, + dislike(item) { + let type = item.type.slice(-1) === "s" ? item.type : item.type + "s"; + let id = item.attributes?.playParams?.catalogId ? item.attributes.playParams.catalogId : item.attributes?.playParams?.id ?? item.id; + if (item.id != null && item.id.toString().startsWith("i.")) { + if (!type.startsWith("library-")) { + type = "library-" + type; + } + id = item.id; + } + this.mk.api.v3.music( + `/v1/me/ratings/${type}/${id}`, + {}, + { + fetchOptions: { + method: "PUT", + body: JSON.stringify({ + type: "rating", + attributes: { + value: -1, + }, + }), + }, + }, + ); + }, + unlove(item) { + let type = item.type.slice(-1) === "s" ? item.type : item.type + "s"; + let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id; + if (item.id.startsWith("i.")) { + if (!type.startsWith("library-")) { + type = "library-" + type; + } + id = item.id; + } + this.mk.api.v3.music( + `/v1/me/ratings/${type}/${id}`, + {}, + { + fetchOptions: { + method: "DELETE", + }, + }, + ); + }, + checkScrollDirectionIsUp(event) { + if (event.wheelDelta) { + return event.wheelDelta > 0; + } + return event.deltaY < 0; + }, + volumeUp() { + if (app.mk.volume + app.cfg.audio.volumeStep > app.cfg.audio.maxVolume) { + app.mk.volume = app.cfg.audio.maxVolume; + } else { + app.mk.volume = (Math.floor(app.mk.volume * 100) + app.cfg.audio.volumeStep * 100) / 100; + } + }, + volumeDown() { + if (app.mk.volume - app.cfg.audio.volumeStep < 0) { + app.mk.volume = 0; + } else { + app.mk.volume = (Math.floor(app.mk.volume * 100) - app.cfg.audio.volumeStep * 100) / 100; + } + }, + volumeWheel(event) { + app.checkScrollDirectionIsUp(event) ? this.volumeUp() : this.volumeDown(); + }, + muteButtonPressed() { + if (this.cfg.audio.muted) { + this.mk.volume = this.cfg.audio.lastVolume; + this.cfg.audio.muted = false; + } else { + this.cfg.audio.lastVolume = this.cfg.audio.volume; + this.mk.volume = 0; + this.cfg.audio.muted = true; + } + }, + checkMuteChange() { + if (this.cfg.audio.muted) { + this.cfg.audio.muted = false; + } + }, + repeatIncrement() { + switch (app.mk.repeatMode) { + default: + case MusicKit.PlayerRepeatMode.none: + app.mk.repeatMode = MusicKit.PlayerRepeatMode.all; + break; + + case MusicKit.PlayerRepeatMode.all: + app.mk.repeatMode = MusicKit.PlayerRepeatMode.one; + break; + + case MusicKit.PlayerRepeatMode.one: + app.mk.repeatMode = MusicKit.PlayerRepeatMode.none; + break; + } + }, + async apiCall(url, callback) { + const xmlHttp = new XMLHttpRequest(); + + xmlHttp.onreadystatechange = (e) => { + if (xmlHttp.readyState !== 4) { + return; + } + + if (xmlHttp.status === 200) { + // console.log('SUCCESS', xmlHttp.responseText); + callback(JSON.parse(xmlHttp.responseText)); + } else { + console.warn("request_error"); + } + }; + + xmlHttp.open("GET", url); + xmlHttp.setRequestHeader("Authorization", "Bearer " + MusicKit.getInstance().developerToken); + xmlHttp.setRequestHeader("Music-User-Token", "" + MusicKit.getInstance().musicUserToken); + xmlHttp.setRequestHeader("Accept", "application/json"); + xmlHttp.setRequestHeader("Content-Type", "application/json"); + xmlHttp.responseType = "text"; + xmlHttp.send(); + }, + fetchPlaylist(id, callback) { + // id can be found in playlist.attributes.playParams.globalId + // this.mk.api. + this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`).then((res) => { + callback(res.data.data[0]); + }); + + // tracks are found in relationship.data + }, + setAirPlayCodeUI(identifier) { + this.modals.airplayPW = true; + this.currentAirPlayCodeID = identifier; + }, + sendAirPlaySuccess(silent = false, identifier = "") { + if (!silent) { + notyf.success("Device paired successfully!"); + } + console.log("delete idx-pre", identifier); + let idx = this.airplayTrys.findIndex((a) => { + return a.id == identifier; + }); + console.log("delete idx", idx); + if (idx != -1) delete this.airplayTrys[idx]; + this.airplayTrys = this.airplayTrys.filter((n) => n); + }, + sendAirPlayFailed() { + notyf.success("Device paring failed!"); + }, + airplayDisconnect(dropped, array = [], identifier = "") { + console.log("airplay dropped", dropped, array, identifier); + if (dropped) { + let [ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv] = array; + console.log(ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv); + let idx = this.airplayTrys.findIndex((a) => { + return a.id == ipv4 + ":" + ipport + "ap"; + }); + if (idx == -1) { + this.airplayTrys.push({ + id: ipv4 + ":" + ipport + "ap", + attempts: 1, + }); + } + idx = this.airplayTrys.findIndex((a) => { + return a.id == ipv4 + ":" + ipport + "ap"; + }); + if (this.airplayTrys[idx].attempts > 3) { + delete this.airplayTrys[idx]; + this.airplayTrys = this.airplayTrys.filter((n) => n); + console.log("delete idx", idx); + return; + } else { + this.airplayTrys[idx].attempts = this.airplayTrys[idx].attempts + 1; + setTimeout(() => { + ipcRenderer.send("performAirplayPCM", ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv, true); + }, 1000); + } + } else { + if (identifier == "") { + app.activeCasts = []; + notyf.error("Devices disconnected!"); + } else { + app.activeCasts; + notyf.error("Device disconnected!"); + } + } + }, + windowFocus(val) { + if (val) { + document.querySelectorAll(".animated-artwork-video").forEach((el) => { + el.play(); + }); + document.querySelector("body").classList.remove("stopanimation"); + document.body.setAttribute("focus-state", "focused"); + this.animateBackground = true; + } else { + document.querySelectorAll(".animated-artwork-video").forEach((el) => { + el.pause(); + }); + document.querySelector("body").classList.add("stopanimation"); + document.body.setAttribute("focus-state", "blurred"); + this.animateBackground = false; + } + }, + async nowPlayingContextMenu(event) { + let self = this; + let data_type = this.mk.nowPlayingItem.playParams.kind; + let item_id = this.mk.nowPlayingItem.attributes.playParams.id ?? this.mk.nowPlayingItem.id; + let isLibrary = this.mk.nowPlayingItem.attributes.playParams.isLibrary ?? false; + let params = { + "fields[songs]": "inLibrary", + "fields[albums]": "inLibrary", + relate: "library", + t: "1", + }; + app.selectedMediaItems = []; + app.select_selectMediaItem(item_id, data_type, 0, "12344", isLibrary); + let useMenu = "normal"; + let menus = { + multiple: { + items: [], + }, + normal: { + headerItems: [ + { + icon: "./assets/feather/heart.svg", + id: "love", + name: app.getLz("action.love"), + hidden: false, + disabled: true, + action: function () { + app.love(app.mk.nowPlayingItem); + }, + }, + { + icon: "./assets/feather/heart.svg", + id: "unlove", + active: true, + name: app.getLz("action.unlove"), + hidden: true, + action: function () { + app.unlove(app.mk.nowPlayingItem); + }, + }, + { + icon: "./assets/feather/thumbs-down.svg", + id: "dislike", + name: app.getLz("action.dislike"), + hidden: false, + disabled: true, + action: function () { + app.dislike(app.mk.nowPlayingItem); + }, + }, + { + icon: "./assets/feather/thumbs-down.svg", + id: "undo_dislike", + name: app.getLz("action.undoDislike"), + active: true, + hidden: true, + action: function () { + app.unlove(app.mk.nowPlayingItem); + }, + }, + ], + items: [ + { + icon: "./assets/feather/plus.svg", + id: "addToLibrary", + name: app.getLz("action.addToLibrary") + " ...", + disabled: true, + action: function () { + app.addToLibrary(app.mk.nowPlayingItem.id); + }, + }, + { + id: "removeFromLibrary", + icon: "./assets/feather/x-circle.svg", + name: app.getLz("action.removeFromLibrary"), + hidden: true, + action: function () { + self.removeFromLibrary(app.mk.nowPlayingItem.type, MusicKitInterop.getAttributes().songId); + }, + }, + { + icon: "./assets/feather/list.svg", + name: app.getLz("action.addToPlaylist") + " ...", + action: function () { + app.promptAddToPlaylist(); + }, + }, + { + icon: "./assets/feather/radio.svg", + name: app.getLz("action.startRadio"), + action: function () { + app.mk.setStationQueue({ song: app.mk.nowPlayingItem.id }).then(() => { + app.mk.play(); + app.selectedMediaItems = []; + }); + }, + }, + { + icon: "./assets/feather/user.svg", + name: app.getLz("action.goToArtist"), + action: async function () { + if (app.mk.nowPlayingItem.relationships.artists.data[0].id) { + app.appRoute(`artist/${app.mk.nowPlayingItem.relationships.artists.data[0].id}`); + } else { + const primaryArtist = await MusicKitInterop.fetchSongRelationships({ relationship: "primaryArtist" }); + app.appRoute(`artist/${primaryArtist.id}`); + } + }, + }, + { + icon: "./assets/feather/disc.svg", + name: app.getLz("action.goToAlbum"), + action: function () { + app.appRoute(`album/${app.mk.nowPlayingItem.relationships.albums.data[0].id}`); + }, + }, + { + id: "showInMusic", + icon: "./assets/music.svg", + hidden: true, + name: app.getLz("action.showInAppleMusic"), + action: function () { + app.routeView(app.mk.nowPlayingItem._container); + }, + }, + { + icon: "./assets/feather/share.svg", + name: app.getLz("action.share"), + action: function () { + app.mkapi(app.mk.nowPlayingItem.attributes?.playParams?.kind ?? app.mk.nowPlayingItem.type ?? "songs", false, app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.songId ?? app.mk.nowPlayingItem.id ?? "").then((u) => { + app.copyToClipboard(u.data.data.length && u.data.data.length > 0 ? u.data.data[0].attributes.url : u.data.data.attributes.url); + }); + }, + }, + { + icon: "./assets/feather/share.svg", + name: `${app.getLz("action.share")} (song.link)`, + action: function () { + app.mkapi(app.mk.nowPlayingItem.attributes?.playParams?.kind ?? app.mk.nowPlayingItem.type ?? "songs", false, app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.songId ?? app.mk.nowPlayingItem.id ?? "").then((u) => { + app.songLinkShare(u.data.data.length && u.data.data.length > 0 ? u.data.data[0].attributes.url : u.data.data.attributes.url); + }); + }, + }, + { + id: "equalizer", + icon: "../views/svg/speaker.svg", + name: app.getLz("term.equalizer"), + hidden: false, + action: function () { + app.modals.equalizer = true; + app.modals.audioSettings = false; + }, + }, + { + id: "audioLab", + icon: "../views/svg/speaker.svg", + name: app.getLz("settings.option.audio.audioLab"), + hidden: false, + action: function () { + app.openSettingsPage("audiolabs"); + }, + }, + ], + }, + }; + /* + if (this.cfg.advanced.AudioContext) { + menus.normal.items.find(i => i.id === 'audioLab').hidden = false + menus.normal.items.find(i => i.id === 'equalizer').hidden = false + } + */ + if (this.contextExt) { + if (this.contextExt.normal) { + menus.normal.items = menus.normal.items.concat(this.contextExt.normal); + } + } + + const nowPlayingContainer = app.mk.nowPlayingItem._container; + if (nowPlayingContainer && nowPlayingContainer["attributes"] && nowPlayingContainer.name != "station") { + menus.normal.items.find((x) => x.id == "showInMusic").hidden = false; + } + + this.showMenuPanel(menus[useMenu], event); + + try { + // if its a radio station, then change the attributes to match a song + const nowPlayingItem = JSON.parse(JSON.stringify(this.mk.nowPlayingItem)); + if (nowPlayingItem.type == "radioStation" && app.mk.nowPlayingItem.id != -1) { + nowPlayingItem.type = "song"; + nowPlayingItem.attributes.playParams.catalogId = app.mk.nowPlayingItem.id; + nowPlayingItem.attributes.playParams.id = app.mk.nowPlayingItem.id; + nowPlayingItem.id = app.mk.nowPlayingItem.id; + } + let result = await this.inLibrary([nowPlayingItem]); + if (result[0].attributes.inLibrary) { + menus.normal.items.find((x) => x.id == "addToLibrary").hidden = true; + menus.normal.items.find((x) => x.id == "removeFromLibrary").hidden = false; + } else { + menus.normal.items.find((x) => x.id == "addToLibrary").disabled = false; + } + } catch (e) { + e = null; + } + + try { + let rating = await app.getRating(app.mk.nowPlayingItem); + if (rating == 0) { + menus.normal.headerItems.find((x) => x.id == "love").disabled = false; + menus.normal.headerItems.find((x) => x.id == "dislike").disabled = false; + } else if (rating == 1) { + menus.normal.headerItems.find((x) => x.id == "unlove").hidden = false; + menus.normal.headerItems.find((x) => x.id == "love").hidden = true; + } else if (rating == -1) { + menus.normal.headerItems.find((x) => x.id == "undo_dislike").hidden = false; + menus.normal.headerItems.find((x) => x.id == "dislike").hidden = true; + } + } catch (err) {} + }, + openSettingsPage(page) { + switch (page) { + case "general": + this.$store.state.pageState.settings.currentTabIndex = 0; + break; + case "audio": + this.$store.state.pageState.settings.currentTabIndex = 1; + break; + case "audiolabs": + this.$store.state.pageState.settings.currentTabIndex = 2; + break; + case "styles": + this.$store.state.pageState.settings.currentTabIndex = 3; + break; + case "visual": + this.$store.state.pageState.settings.currentTabIndex = 4; + break; + case "github-plugins": + this.$store.state.pageState.settings.currentTabIndex = 5; + break; + case "lyrics": + this.$store.state.pageState.settings.currentTabIndex = 6; + break; + case "connectivity": + this.$store.state.pageState.settings.currentTabIndex = 7; + break; + case "advanced": + this.$store.state.pageState.settings.currentTabIndex = 8; + break; + case "keybindings": + this.$store.state.pageState.settings.currentTabIndex = 9; + break; + case "github-themes": + this.$store.state.pageState.settings.currentTabIndex = 10; + break; + } + app.modals.settings = true; + }, + fullscreen(flag, mv = false) { + this.fullscreenState = flag; + if (flag) { + ipcRenderer.send("setFullScreen", true); + if (!mv) { + app.appMode = "fullscreen"; + } else { + app.mvViewMode = "full"; + } + + document.addEventListener("keydown", (event) => { + if (event.key === "Escape" && app.appMode === "fullscreen") { + this.fullscreen(false); + } + }); + } else { + ipcRenderer.send("setFullScreen", false); + app.appMode = "player"; + } + }, + pip() { + // document.querySelector("video#apple-music-video-player").requestPictureInPicture(); + // // .then(pictureInPictureWindow => { + // // pictureInPictureWindow.addEventListener("resize", () => { + // // console.log("[PIP] Resized") + // // }, false); + // // }) + this.mvViewMode = this.mvViewMode == "mini" ? "full" : "mini"; + }, + miniPlayer(flag) { + if (flag) { + this.tmpWidth = window.innerWidth; + this.tmpHeight = window.innerHeight; + this.tmpX = window.screenX; + this.tmpY = window.screenY; + ipcRenderer.send("unmaximize"); + ipcRenderer.send("windowmin", 250, 250); + if (this.miniTmpX !== "" && this.miniTmpY !== "") ipcRenderer.send("windowmove", this.miniTmpX, this.miniTmpY); + ipcRenderer.send("windowresize", 300, 300, false); + app.appMode = "mini"; + } else { + this.miniTmpX = window.screenX; + this.miniTmpY = window.screenY; + ipcRenderer.send("windowmin", 844, 410); + ipcRenderer.send("windowresize", this.tmpWidth, this.tmpHeight, false); + ipcRenderer.send("windowmove", this.tmpX, this.tmpY); + ipcRenderer.send("windowontop", false); + //this.cfg.visual.miniplayer_top_toggle = true; + app.appMode = "player"; + } + }, + pinMiniPlayer(status = false) { + if (!status) { + if (!this.cfg.visual.miniplayer_top_toggle) { + ipcRenderer.send("windowontop", true); + this.cfg.visual.miniplayer_top_toggle = true; + } else { + ipcRenderer.send("windowontop", false); + this.cfg.visual.miniplayer_top_toggle = false; + } + } else { + ipcRenderer.send("windowontop", this.cfg.visual.miniplayer_top_toggle ?? false); + } + }, + formatTimezoneOffset: (e = new Date()) => { + let leadingZeros = (e, s = 2) => { + let n = "" + e; + for (; n.length < s; ) n = "0" + n; + return n; + }; + + const s = e.getTimezoneOffset(), + n = Math.floor(Math.abs(s) / 60), + d = Math.round(Math.abs(s) % 60); + let h = "+"; + return 0 !== s && (h = s > 0 ? "-" : "+"), `${h}${leadingZeros(n, 2)}:${leadingZeros(d, 2)}`; + }, + toggleHideUserInfo() { + if (this.chrome.hideUserInfo) { + this.cfg.visual.showuserinfo = true; + this.chrome.hideUserInfo = false; + } else { + this.cfg.visual.showuserinfo = false; + this.chrome.hideUserInfo = true; + } + }, + isElementOverflowing(selector) { + try { + let element = document.querySelector(selector); + var overflowX = element.offsetWidth < element.scrollWidth, + overflowY = element.offsetHeight < element.scrollHeight; + element.setAttribute("data-value", "\xa0\xa0\xa0\xa0" + element.textContent); + + return overflowX || overflowY; + } catch (e) { + return false; + } + }, + async showWebRemoteQR() { + //this.webremoteqr = await ipcRenderer.invoke('setRemoteQR','') + this.webremoteurl = await ipcRenderer.invoke("showQR", ""); + //this.modals.qrcode = true; + }, + checkMarquee() { + if (isElementOverflowing("#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-artist") == true) { + document.getElementsByClassName("song-artist")[0].classList.add("marquee"); + document.getElementsByClassName("song-artist")[1].classList.add("marquee-after"); + } + if (isElementOverflowing("#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name") == true) { + document.getElementsByClassName("song-name")[0].classList.add("marquee"); + document.getElementsByClassName("song-name")[1].classList.add("marquee-after"); + } + }, + closeWindow() { + ipcRenderer.send("close"); + }, + darwinShare(url) { + ipcRenderer.send("share-menu", url); + }, + arrayToChunk(arr, chunkSize) { + let R = []; + for (let i = 0, len = arr.length; i < len; i += chunkSize) { + R.push(arr.slice(i, i + chunkSize)); + } + return R; + }, + SpacePause() { + const elems = document.querySelectorAll("input"); + for (let elem of elems) { + if (elem === document.activeElement) { + return; + } + } + if (!this.isDev) { + // disable in dev mode to keep my sanity + MusicKitInterop.playPause(); + } + }, + async MKJSLang() { + let u = this.cfg.general.language; + // use MusicKit.getInstance or crash + try { + let item = await MusicKit.getInstance().api.v3.music(`v1/storefronts/${app.mk.storefrontId}`); + let langcodes = item.data.data[0].attributes.supportedLanguageTags; + if (langcodes) + langcodes = langcodes.map(function (u) { + return u.replace(/-Han[s|t]/i, "").toLowerCase(); + }); + console.log(langcodes); + let sellang = ""; + if (u && langcodes.includes(u.toLowerCase().replace("_", "-"))) { + sellang = u.toLowerCase().replace("_", "-"); + } else if (u && u.includes("_") && langcodes.includes(u.toLowerCase().replace("_", "-").split("-")[0])) { + sellang = u.toLowerCase().replace("_", "-").split("-")[0]; + } + if (sellang == "") sellang = item.data.data[0].attributes.defaultLanguageTag.toLowerCase(); + + // Fix weird locales: + if (sellang == "iw") sellang = "iw-il"; + sellang = sellang.replace(/-Han[s|t]/i, "").toLowerCase(); + + console.log(sellang); + return await sellang; + } catch (err) { + console.log("locale err", err); + let langcodes = [ + "af", + "sq", + "ar", + "eu", + "bg", + "be", + "ca", + "zh", + "zh-tw", + "zh-cn", + "zh-hk", + "zh-sg", + "hr", + "cs", + "da", + "nl", + "nl-be", + "en", + "en-us", + "en-eg", + "en-au", + "en-gb", + "en-ca", + "en-nz", + "en-ie", + "en-za", + "en-jm", + "en-bz", + "en-tt", + "en-001", + "et", + "fo", + "fa", + "fi", + "fr", + "fr-ca", + "gd", + "de", + "de-ch", + "el", + "he", + "hi", + "hu", + "is", + "id", + "it", + "ja", + "ko", + "lv", + "lt", + "mk", + "mt", + "no", + "nb", + "nn", + "pl", + "pt-br", + "pt", + "rm", + "ro", + "ru", + "sr", + "sk", + "sl", + "es", + "es-mx", + "es-419", + "sv", + "th", + "ts", + "tn", + "tr", + "uk", + "ur", + "ve", + "vi", + "xh", + "yi", + "zu", + "ms", + "iw", + "lo", + "tl", + "kk", + "ta", + "te", + "bn", + "ga", + "ht", + "la", + "pa", + "sa", + ]; + let sellang = "en"; + if (u && langcodes.includes(u.toLowerCase().replace("_", "-"))) { + sellang = u.toLowerCase().replace("_", "-"); + } else if (u && u.includes("_") && langcodes.includes(u.toLowerCase().replace("_", "-").split("-")[0])) { + sellang = u.toLowerCase().replace("_", "-").split("-")[0]; + } + if (sellang.startsWith("en") && this.mk.storefrontId != "us") sellang = "en-gb"; + return await sellang; + } + }, + skipToNextItem() { + if (this.mk.queue.nextPlayableItemIndex !== -1 && this.mk.queue.nextPlayableItemIndex != null) this.mk.changeToMediaAtIndex(this.mk.queue.nextPlayableItemIndex); + }, + skipToPreviousItem() { + if (this.mk.queue.previousPlayableItemIndex !== -1 && this.mk.queue.previousPlayableItemIndex != null) this.mk.changeToMediaAtIndex(this.mk.queue.previousPlayableItemIndex); + }, + mediaKeyFixes() { + MusicKitInterop.initMediaSession(); + // navigator.mediaSession.setActionHandler("previoustrack", function () { + // app.skipToPreviousItem(); + // }); + // navigator.mediaSession.setActionHandler("nexttrack", function () { + // app.skipToNextItem(); + // }); + }, + authCC() { + ipcRenderer.send("cc-auth"); + }, + _playRadioStream(e) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = process; + xhr.open("GET", e, true); + xhr.send(); + let self = this; + + function process() { + if (xhr.readyState == 4) { + let sources = xhr.responseText.match(/^(?!#)(?!\s).*$/gm).filter(function (element) { + return element; + }); + // Load first source + let src = sources[0]; + if (src.includes("http")) { + app.mk._services.mediaItemPlayback._currentPlayer._playAssetURL(src, false); + } else { + if (Hls.isSupported()) { + let d = "WIDEVINE_SOFTWARE"; + let h = { + initDataTypes: ["cenc", "keyids"], + distinctiveIdentifier: "optional", + persistentState: "required", + }; + let p = { + platformInfo: { requiresCDMAttachOnStart: !0, maxSecurityLevel: d, keySystemConfig: h }, + appData: { serviceName: "Apple Music" }, + }; + if (app.radiohls != null && app.radiohls.destroy != null) { + app.radiohls.destroy(); + app.radiohls = null; + app.radiohls = new CiderHls(); + app.radiohls.loadSource(e); + app.radiohls.attachMedia(app.mk._services.mediaItemPlayback._currentPlayer._targetElement); + app.mk._services.mediaItemPlayback._currentPlayer._targetElement.play(); + } else { + app.radiohls = null; + app.radiohls = new CiderHls(); + app.radiohls.loadSource(e); + app.radiohls.attachMedia(app.mk._services.mediaItemPlayback._currentPlayer._targetElement); + app.mk._services.mediaItemPlayback._currentPlayer._targetElement.play(); + } + } + } + } + } + }, + confirm(message, callback) { + bootbox.confirm(this.getBootboxParams(null, message, callback)); + }, + prompt(title, callback) { + bootbox.prompt(this.getBootboxParams(title, null, callback)); + }, + getBootboxParams(title, message, callback) { + return { + title: title, + message: message, + buttons: { + confirm: { + label: app.getLz("dialog.ok"), + }, + cancel: { + label: app.getLz("dialog.cancel"), + }, + }, + callback: function (result) { + if (callback) callback(result); + }, + }; + }, + }, +}); + +export { app }; diff --git a/src/renderer/main/vuex-store.js b/src/renderer/main/vuex-store.js new file mode 100644 index 00000000..716c427d --- /dev/null +++ b/src/renderer/main/vuex-store.js @@ -0,0 +1,63 @@ +const store = new Vuex.Store({ + state: { + windowRelativeScale: 1, + library: { + // songs: ipcRenderer.sendSync("get-library-songs"), + // albums: ipcRenderer.sendSync("get-library-albums"), + // recentlyAdded: ipcRenderer.sendSync("get-library-recentlyAdded"), + // playlists: ipcRenderer.sendSync("get-library-playlists") + }, + pageState: { + recentlyAdded: { + loaded: false, + nextUrl: null, + items: [], + size: "normal", + }, + settings: { + currentTabIndex: 0, + fullscreen: false, + }, + scrollPos: { + limit: 10, + pos: [], + }, + }, + artwork: { + playerLCD: "", + }, + }, + mutations: { + resetRecentlyAdded(state) { + state.pageState.recentlyAdded.loaded = false; + state.pageState.recentlyAdded.nextUrl = null; + state.pageState.recentlyAdded.items = []; + }, + setLCDArtwork(state, artwork) { + state.artwork.playerLCD = artwork; + }, + setPagePos(state, pageState = {}) { + let cached = state.pageState.scrollPos.pos.find((page) => { + return page.href === pageState.href; + }); + if (cached) { + state.pageState.scrollPos.pos.find((page) => { + if (page.href === pageState.href) { + page.position = pageState.position; + } + }); + return; + } + state.pageState.scrollPos.pos.push({ + href: pageState.href, + position: pageState.position, + }); + if (state.pageState.scrollPos.pos.length > state.pageState.scrollPos.limit) { + pages.value.shift(); + } + return; + }, + }, +}); + +export { store }; diff --git a/src/renderer/main/wsapi_interop.js b/src/renderer/main/wsapi_interop.js new file mode 100644 index 00000000..e9f8d766 --- /dev/null +++ b/src/renderer/main/wsapi_interop.js @@ -0,0 +1,228 @@ +const wsapi = { + cache: { playParams: { id: 0 }, status: null, remainingTime: 0 }, + playbackCache: { status: null, time: Date.now() }, + async v3(encoded = "") { + let decoded = atob(encoded); + let json = JSON.parse(decoded); + console.log(json); + let response = await await MusicKit.getInstance().api.v3.music(json.route, json.body, json.options); + let ret = response.data; + return JSON.stringify(ret); + }, + search(term, limit) { + MusicKit.getInstance() + .api.search(term, { + limit: limit, + types: "songs,artists,albums,playlists", + }) + .then((results) => { + ipcRenderer.send("wsapi-returnSearch", JSON.stringify(results)); + }); + }, + searchLibrary(term, limit) { + MusicKit.getInstance() + .api.library.search(term, { + limit: limit, + types: "library-songs,library-artists,library-albums,library-playlists", + }) + .then((results) => { + ipcRenderer.send("wsapi-returnSearchLibrary", JSON.stringify(results)); + }); + }, + getAttributes: function () { + const mk = MusicKit.getInstance(); + const nowPlayingItem = mk.nowPlayingItem; + const isPlayingExport = mk.isPlaying; + const remainingTimeExport = mk.currentPlaybackTimeRemaining; + const attributes = nowPlayingItem != null ? nowPlayingItem.attributes : {}; + + attributes.status = isPlayingExport ? isPlayingExport : false; + attributes.name = attributes.name ? attributes.name : "No Title Found"; + attributes.artwork = attributes.artwork ? attributes.artwork : { url: "" }; + attributes.artwork.url = attributes.artwork.url ? attributes.artwork.url : ""; + attributes.playParams = attributes.playParams ? attributes.playParams : { id: "no-id-found" }; + attributes.playParams.id = attributes.playParams.id ? attributes.playParams.id : "no-id-found"; + attributes.albumName = attributes.albumName ? attributes.albumName : ""; + attributes.artistName = attributes.artistName ? attributes.artistName : ""; + attributes.genreNames = attributes.genreNames ? attributes.genreNames : []; + attributes.remainingTime = remainingTimeExport ? remainingTimeExport * 1000 : 0; + attributes.durationInMillis = attributes.durationInMillis ? attributes.durationInMillis : 0; + attributes.startTime = Date.now(); + attributes.endTime = attributes.endTime ? attributes.endTime : Date.now(); + attributes.volume = mk.volume; + attributes.shuffleMode = mk.shuffleMode; + attributes.repeatMode = mk.repeatMode; + attributes.autoplayEnabled = mk.autoplayEnabled; + return attributes; + }, + moveQueueItem(oldPosition, newPosition) { + MusicKit.getInstance().queue._queueItems.splice(newPosition, 0, MusicKit.getInstance().queue._queueItems.splice(oldPosition, 1)[0]); + MusicKit.getInstance().queue._reindex(); + }, + setAutoplay(value) { + MusicKit.getInstance().autoplayEnabled = value; + }, + returnDynamic(data, type) { + ipcRenderer.send("wsapi-returnDynamic", JSON.stringify(data), type); + }, + musickitApi(method, id, params, library = false) { + if (library) { + MusicKit.getInstance() + .api.library[method](id, params) + .then((results) => { + ipcRenderer.send("wsapi-returnMusicKitApi", JSON.stringify(results), method); + }); + } else { + MusicKit.getInstance() + .api[method](id, params) + .then((results) => { + ipcRenderer.send("wsapi-returnMusicKitApi", JSON.stringify(results), method); + }); + } + }, + getPlaybackState() { + ipcRenderer.send("wsapi-updatePlaybackState", MusicKitInterop.getAttributes()); + }, + getLyrics() { + ipcRenderer.send("wsapi-returnLyrics", JSON.stringify(app.lyrics)); + }, + getQueue() { + ipcRenderer.send("wsapi-returnQueue", JSON.stringify(MusicKit.getInstance().queue)); + }, + playNext(type, id) { + var request = {}; + request[type] = id; + MusicKit.getInstance().playNext(request); + }, + playLater(type, id) { + var request = {}; + request[type] = id; + MusicKit.getInstance().playLater(request); + }, + love() {}, + playTrackById(id, kind = "song") { + MusicKit.getInstance() + .setQueue({ [kind]: id, parameters: { l: app.mklang } }) + .then(function (queue) { + MusicKit.getInstance().play(); + }); + }, + quickPlay(term) { + // Quick play by song name + MusicKit.getInstance() + .api.search(term, { limit: 2, types: "songs" }) + .then(function (data) { + MusicKit.getInstance() + .setQueue({ + song: data["songs"][0]["id"], + parameters: { l: app.mklang }, + }) + .then(function (queue) { + MusicKit.getInstance().play(); + }); + }); + }, + toggleShuffle() { + MusicKit.getInstance().shuffleMode = MusicKit.getInstance().shuffleMode === 0 ? 1 : 0; + }, + togglePlayPause() { + app.mk.isPlaying ? app.mk.pause() : app.mk.play(); + }, + toggleRepeat() { + app.repeatIncrement(); + }, + getmaxVolume() { + ipcRenderer.send("wsapi-returnvolumeMax", JSON.stringify(app.cfg.audio.maxVolume)); + }, + getLibraryStatus(kind, id) { + if (kind === undefined || id === "no-id-found") return; + + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + app.mk.api.v3 + .music(`/v1/catalog/${app.mk.storefrontId}/?ids[${truekind}]=${id}`, { + relate: "library", + fields: "inLibrary", + }) + .then((data) => { + const res = data.data.data[0]; + const inLibrary = res && res.attributes && res.attributes.inLibrary; + + app.getRating({ type: truekind, id: id }).then((rating) => { + ipcRenderer.send("wsapi-libraryStatus", inLibrary, rating); + }); + }); + }, + rate(kind, id, rating) { + if (kind === undefined || id === "no-id-found") return; + + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + + if (rating === 0) { + app.mk.api.v3 + .music( + `/v1/me/ratings/${truekind}/${id}`, + {}, + { + fetchOptions: { + method: "DELETE", + }, + }, + ) + .then(function () { + ipcRenderer.send("wsapi-rate", kind, id, rating); + }); + } else if (rating === undefined) { + app.getRating({ type: truekind, id: id }).then((rating) => { + ipcRenderer.send("wsapi-rate", kind, id, rating); + }); + } else { + app.mk.api.v3 + .music( + `/v1/me/ratings/${truekind}/${id}`, + {}, + { + fetchOptions: { + method: "PUT", + body: JSON.stringify({ + type: "rating", + attributes: { + value: rating, + }, + }), + }, + }, + ) + .then(function () { + ipcRenderer.send("wsapi-rate", kind, id, rating); + }); + } + }, + changeLibrary(kind, id, shouldAdd) { + if (shouldAdd) { + app.addToLibrary(id); + ipcRenderer.send("wsapi-change-library", kind, id, shouldAdd); + } else { + let truekind = !kind.endsWith("s") ? kind + "s" : kind; + + app.mk.api.v3 + .music(`/v1/catalog/${app.mk.storefrontId}/?ids[${truekind}]=${id}`, { + relate: "library", + fields: "inLibrary", + }) + .then((res) => { + res = res.data.data[0]; + if (res && res.relationships && res.relationships.library && res.relationships.library.data) { + const item = res.relationships.library.data[0]; + + if (item) { + app.removeFromLibrary(kind, item.id); + } + + ipcRenderer.send("wsapi-change-library", kind, id, shouldAdd); + } + }); + } + }, +}; + +export { wsapi }; diff --git a/src/renderer/sounds/btn1.ogg b/src/renderer/sounds/btn1.ogg new file mode 100644 index 00000000..f6f75efa Binary files /dev/null and b/src/renderer/sounds/btn1.ogg differ diff --git a/src/renderer/sounds/confirm.ogg b/src/renderer/sounds/confirm.ogg new file mode 100644 index 00000000..c4e3857b Binary files /dev/null and b/src/renderer/sounds/confirm.ogg differ diff --git a/src/renderer/sounds/hover.ogg b/src/renderer/sounds/hover.ogg new file mode 100644 index 00000000..9da1b148 Binary files /dev/null and b/src/renderer/sounds/hover.ogg differ diff --git a/src/renderer/style-old.css b/src/renderer/style-old.css deleted file mode 100644 index 7662fb15..00000000 --- a/src/renderer/style-old.css +++ /dev/null @@ -1,2165 +0,0 @@ -@import url("ameframework.css"); - -:root { - --appleEase: cubic-bezier(0.42, 0, 0.58, 1); - --mediaItemShadow-Shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55); - --mediaItemShadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%); - --mediaItemRadius: 4px; - --mediaItemRadiusRound: 100%; - --contentInnerPadding: 16px; - --navbarHeight: 48px; - --keyColor: #fa586a; - --keyColor-rgb: 250, 88, 106; - --keyColor-rollover: #ff8a9c; - --keyColor-rollover-rgb: 255, 138, 156; - --keyColor-pressed: #ff7183; - --keyColor-pressed-rgb: 255, 113, 131; - --keyColor-deepPressed: #ff8a9c; - --keyColor-deepPressed-rgb: 255, 138, 156; - --keyColor-disabled: rgba(250, 88, 106, 0.35); -} - -html, -body { - margin: 0; - padding: 0; - overflow: hidden; - width: 100%; - height: 100%; - box-sizing: border-box; - background-size: cover; - background-position: center; - background: #0000; - font-family: "Segoe UI Variable Display", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - transition: opacity .10s var(--appleEase); -} - -body[loading] { - opacity: 0.5; - pointer-events: none; -} - -body[platform='linux'] { - background:#222; -} - -*, -*:before, -*:after { - box-sizing: inherit; -} - - -/* Modern style overlay scrollbars */ -::-webkit-scrollbar { - width: 16px; - height: 24px; -} - -::-webkit-scrollbar-button { - display: none; -} - -::-webkit-scrollbar-track-piece { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: transparent; - border: 6px solid transparent; - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); - border-radius: 16px; - min-height: 64px; - transition: border 1s; -} - -::-webkit-scrollbar-thumb:hover { - border: 5px solid transparent; - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 80%); -} - -#app { - --color1: rgb(30, 30, 30, 30%); - --color2: rgba(15, 15, 15, 70%); - /* --color1: rgb(30, 30, 31, 20%); - --color2: rgba(17, 17, 17, 24%); */ - --chromeHeight: 55px; - width: 100%; - height: 100%; - background: var(--color1); - color: white; - user-select: none; - margin: 0 auto; - position: relative; - overflow: hidden; -} -[hidden] { - display: none !important; -} - - -.bg-artwork--placeholder { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: #222; - z-index: -1; - background-size: cover; - background-position: center; - opacity: 0.70; -} - - -.bg-artwork { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: var(--artwork); - z-index: -1; - object-fit: cover; - object-position: center; - /* filter: blur(60px) saturate(180%); - opacity: 0.70; */ - filter: blur(180px) saturate(280%); - opacity: 0.60; - transition: opacity .25s var(--appleEase); - pointer-events: none; - transform: translateZ(0px); -} - - -[artwork-hidden] { - transition: opacity .25s var(--appleEase); - opacity:0; -} - -input[type="range"].web-slider { - -webkit-appearance: none; - height: 4px; - background: rgba(255, 255, 255, 0.6); - border-radius: 5px; - background-size: 70% 100%; - background-repeat: no-repeat; -} - -input[type="range"].web-slider::-webkit-slider-thumb { - -webkit-appearance: none; - height: 20px; - width: 20px; - border-radius: 50%; - background: rgb(255 255 255); - cursor: ew-resize; - box-shadow: 0 0 2px 0 #555; -} - -input[type=range].web-slider::-webkit-slider-runnable-track { - -webkit-appearance: none; - box-shadow: none; - border: none; - background: transparent; -} - -.nopadding { - padding: 0px; -} - -.md-btn { - font-family: inherit; - color: white; - font-size: 14px; -} - -#app-main { - display: flex; - width: 100%; - height: 100%; - flex-direction: column; -} - -#app-sidebar { - /* background-color: var(--color1); */ - height: 100%; - width: 260px; - display: flex; - flex-direction: column; - flex: 0 0 auto; -} - -#app-navbar { - height: 40px; - width: 100%; - background: rgb(30 30 30 / 85%); - position: sticky; - top: 0px; - left: 0; - z-index: 2; - backdrop-filter: blur(16px) saturate(180%); -} - -#app-content { - background-color: var(--color2); - height: 100%; - width: 100%; - overflow-y: scroll; - overflow-y: overlay; - overflow-x: hidden; - border-radius: 10px 0px; - border-left: 1px solid rgb(0 0 0 / 25%); - border-top: 1px solid rgb(0 0 0 / 25%); - position:relative; -} - -.content-inner { - position: absolute; - top: 0; - left: 0; - padding: 32px; - width: 100%; -} - -.content-inner.centered { - height: 100%; - display: flex; - flex-flow: column; - justify-content: center; - align-items: center; -} - -.app-drawer { - width: 300px; - border-left: 1px solid rgb(0 0 0 / 25%); - flex: 0 0 auto; - border-top: 1px solid rgb(0 0 0 / 25%); -} - -.search-input-container { - position: relative; -} - -.search-input { - width: 100%; - padding: 6px; - border-radius: 6px; - border: 1px solid rgb(200 200 200 / 10%); - font-family: inherit; - font-size: 14px; - background: rgb(100 100 100 / 25%); - color: rgb(200 200 200); - font-weight: 500; - padding-left: 32px; - position: relative; -} - -.search-input:focus { - outline: none; - border-bottom: 1px solid var(--keyColor); -} - -.search-input--icon { - content: ''; - width: 100%; - height: 100%; - display: block; - position: absolute; - top: 0px; - left: 0px; - background-image: url('assets/search.svg'); - background-position: 10px; - background-repeat: no-repeat; - background-size: 12px; - pointer-events: none; - opacity: 0.55; -} - -.app-sidebar-header { - font-size: 14px; - padding: 11px; - font-weight: 600; -} - -.app-sidebar-header-text { - font-size: 11px; - margin: 6px 3px; - font-weight: 600; - opacity: 0.50; -} - -.app-sidebar-footer { - padding: 11px; -} - -.app-sidebar-button { - width: 100%; - padding: 0px; - font-family: inherit; - display: flex; - border-radius: 6px; - border: 1px solid rgb(200 200 200 / 5%); - background: rgb(100 100 100 / 25%); - color: #eee; - font-weight: 500; - align-items: center; -} - -.app-sidebar-button > .sidebar-user-icon { - width: 32px; - height: 32px; - border-radius: 100%; - background-image: var(--artwork); - margin: 10px; - flex: 0 0 auto; - box-shadow: var(--mediaItemShadow); - background-size: contain; -} - -.app-sidebar-button > .sidebar-user-text { - width: 100%; - display: flex; - font-size: 14px; - flex-direction: column; -} - -.app-sidebar-button > .sidebar-user-text .fullname { - text-align: left; -} - -.app-sidebar-button > .sidebar-user-text .handle-text { - font-size: 12px; - opacity: 0.7; - text-align: left; -} - -.app-sidebar-notification { - text-align: center; - font-size: 12px; - min-height: 60px; - display: flex; - justify-content: center; - align-items: center; - border-top: 1px solid rgb(200 200 200 / 15%); - background: rgb(0 0 0 / 15%); - flex-direction: column; - padding: 20px 0px; -} - -.app-sidebar-content { - padding: 8px; - overflow-y: scroll; - overflow-y: overlay; - height: 100%; -} - -.app-sidebar-content::-webkit-scrollbar { - display: none; -} - -.app-sidebar-content:hover::-webkit-scrollbar { - display: initial; -} - -.app-sidebar-item { - display: flex; - width: 100%; - padding: 8px 12px; - font-weight: 400; - font-family: inherit; - font-size: 14px; - margin: 6px 0px; - border: 1px solid transparent; - border-radius: 6px; - background: transparent; - color: white; - transition: transform .1s; - text-align: left; -} - -.app-sidebar-item:hover { - border: 1px solid rgb(200 200 200 / 5%); - background: rgb(200 200 200 / 15%); -} - -.app-sidebar-item:active { - border: 1px solid rgb(200 200 200 / 5%); - background: rgb(200 200 200 / 15%); - transform: scale(0.98); - transition: transform 0s; -} - -.app-sidebar-item.active { - border: 1px solid rgb(200 200 200 / 5%); - background: rgb(200 200 200 / 15%); - transform: scale(1); - transition: transform 0s; -} - -.app-sidebar-item.active::after { - content: ''; - width: 4px; - height: 16px; - display: block; - position: absolute; - top: calc(100% - 72%); - border-radius: 10px; - left: 0px; - background: var(--keyColor); -} - -.app-chrome { - background: var(--color1); - width: 100%; - height: var(--chromeHeight); - display: flex; - flex-direction: row; - -webkit-app-region: drag; -} - -.mv-chrome { - position: absolute; - top: 0; - right: 0; - width: 90%; - height: 55px; - -webkit-app-region: drag; -} - -.app-chrome .app-chrome--left, -.app-chrome .app-chrome--center, -.app-chrome .app-chrome--right { - height: 100%; - width: 100%; - display: flex; - justify-content: center; - align-items: center; -} - -.app-chrome .app-chrome--left { - width: 30%; - justify-content: left; -} - -.app-chrome .app-chrome--center { - width: 100%; -} - -.app-chrome .app-chrome--right { - width: 30%; - justify-content: right; -} - -.app-chrome .app-chrome-item { - height: 100%; - width: auto; - display: flex; - justify-content: center; - align-items: center; - -webkit-app-region: no-drag; - height: auto; -} - -.app-chrome .app-chrome-item.generic { - width: 50px; - opacity: 0.70; -} - -.app-chrome .app-chrome-item.volume { - width: 80px; - margin-right: 6px; -} - -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb { - transition: all var(--appleTransition); -} - -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb:hover { - background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); - transform: scale(1.2); -} - -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb:active { - background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); - transform: scale(1); -} - -.app-chrome .app-chrome-item.volume > input[type=range] { - width: 100%; -} - -.app-chrome .app-chrome-item.volume > input[type=range] { - -webkit-appearance: none; - height: 4px; - background: rgba(255, 255, 255, 0.4); - border-radius: 5px; - background-size: 70% 100%; - background-repeat: no-repeat; -} - -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb { - -webkit-appearance: none; - height: 14px; - width: 14px; - border-radius: 50%; - background: rgb(50 50 50); - cursor: default; - box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); -} - -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-runnable-track { - -webkit-appearance: none; - box-shadow: none; - border: none; - background: transparent; -} - -.app-chrome .back-button { - height: 100%; - width: 60px; -} - -.app-chrome .app-chrome-item.full-height { - height: 100%; -} - -.app-chrome .app-chrome-item > .app-title { - width: 100px; - font-size: 13px; - background: url("./logotmp.png"); - background-size: 90px; - background-repeat: no-repeat; - background-position: center; - height: 100%; - margin-right: 16px; - margin-left: 16px; - image-rendering: -webkit-optimize-contrast; - -webkit-app-region: drag; -} - -.app-chrome .app-chrome-item > .window-controls { - width: 138px; - font-size: 13px; - height: 100%; - display: flex; -} - -.app-chrome .app-chrome-item > .window-controls > div { - height: 100%; - width: 32px; -} - -.app-chrome .app-chrome-item > .window-controls > div:hover { - background: rgb(200 200 200 / 10%); -} - -.app-chrome .app-chrome-item > .window-controls > div.close { - width: 100%; - height: 100%; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; -} - -.app-chrome .app-chrome-item > .window-controls > div.minmax { - background-image: var(--gfx-maxBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - width: 100%; - height: 100%; -} - -.app-chrome .app-chrome-item > .window-controls > div.minmax.restore { - background-image: var(--gfx-restoreBtn); -} - -.app-chrome .app-chrome-item > .window-controls > div.minimize { - background-image: var(--gfx-minBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - width: 100%; - height: 100%; -} - -.app-chrome .app-chrome-item.playback-controls { - width: 80%; - height: 90%; - display: flex; - max-width: 500px; - border-left: 1px solid rgb(200 200 200 / 8%); - border-right: 1px solid rgb(200 200 200 / 8%); -} - -.app-chrome .app-chrome-item > .app-playback-controls { - display: flex; - justify-content: center; - align-content: center; - width: 100%; -} - -.app-chrome .app-chrome-item > .app-playback-controls .song-name { - font-weight: 600; - text-align: center; - font-size: 13px; - height: 1em; - line-height: 1em; - overflow: hidden; -} - -.app-chrome .app-chrome-item > .app-playback-controls .song-artist { - font-weight: 400; - font-size: 13px; - text-align: center; - height: 1em; - line-height: 1em; - overflow: hidden; - /* animation: marquee 10s linear infinite; */ -} - -.app-chrome .app-chrome-item > .app-playback-controls .song-progress { - height: 16px; - position: absolute; - bottom: 0px; - left: 0px; - overflow: hidden; - -} - -@keyframes marquee { - from { - transform: translateX(100%); - } - to { - transform: translateX(-100%); - } -} - -.app-chrome .app-chrome-item > .app-playback-controls .song-progress > input[type=range] { - appearance: none; - width: 100%; - height: 4px; - background-color: rgb(200 200 200 / 10%); -} - -.app-chrome .app-chrome-item > .app-playback-controls .song-progress > input[type=range]::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 4px; - height: 12px; - border-radius: 2px; - background: var(--keyColor); - cursor: ew-resize; -} - -.app-chrome .app-chrome-item > .app-playback-controls .song-progress > input[type=range]::-moz-range-thumb { - width: 8px; - height: 8px; - border-radius: 100%; - background: var(--keyColor); - cursor: pointer; -} - -.app-chrome .app-chrome-item > .app-playback-controls .artwork { - width: 42px; - height: 42px; - background-image: var(--artwork); - background-position: center; - background-size: contain; - background-repeat: no-repeat; - border-radius: 4px; - flex: 0 0 auto; - margin: 6px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 25%); - image-rendering: -webkit-optimize-contrast; -} - -.app-chrome .app-chrome-item > .app-playback-controls .actions { - width: 42px; - height: 42px; - border-radius: 2px; - flex: 0 0 auto; - margin: 6px; - display: flex; - justify-content: center; - align-items: center; -} - -.app-chrome .app-chrome-item > .app-playback-controls .playback-info { - width: 100%; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - position: relative; -} - -.app-chrome .app-chrome-item > .app-playback-controls .playback-info > div { - width: 100%; -} - -.app-navigation { - background: var(--color1); - height: calc(100% - var(--chromeHeight)); - width: 100%; - display: flex; -} - -.display--small { - display: none !important; -} - -.web-slider.display--small{ - margin: 10px; -} - -input[type="range"].web-slider.display--small::-webkit-slider-thumb { - -webkit-appearance: none; - height: 14px; - width: 14px; - border-radius: 50%; - background: rgb(50 50 50); - cursor: default; - box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); -} - -/* Window is smaller <= 1023px width */ -@media only screen and (max-width: 1023px) { - .display--small { - display: inherit !important; - } - - .display--large { - display: none !important; - } -} - -.header-text { - margin: 0px; -} - -.media-item--small { - background: rgb(0 0 0 / 25%); - height: 162px; - width: 132px; - display: inline-flex; - flex-direction: column; - justify-content: center; - align-items: center; - border-radius: 10px; -} - -.media-item--small .artwork { - background: red; - margin: 6px; - border-radius: 100%; - width: 90px; - height: 90px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 30%); -} - -.playlist-artwork { - height: 190px; - width: 190px; - background: blue; - border-radius: 6px; - background: var(--artwork); - background-size: cover; - box-shadow: var(--mediaItemShadow); - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; -} - -.media-item--small .text { - font-weight: 600; - font-size: 0.90em; -} - -.media-item--small .subtext { - font-size: 0.75em; -} - -.player-duration-time { - opacity: 0.5; -} - -.player-artwork-container { - display: flex; - align-items: center; - justify-content: center; -} - -.player-duration-container { - font-size: 0.85em; - font-weight: 500; -} - -.media-artwork { - --artwork: url(""); - width: 80vw; - height: 80vw; - max-height: 500px; - max-width: 500px; - background: black; - background-image: var(--artwork); - background-size: cover; - background-position: center; - background-repeat: no-repeat; - border-radius: 8px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55); - transition: transform .10s var(--appleEase); -} - -.media-artwork.paused { - transition: transform .35s var(--appleEase); - transform: scale(0.85); -} - -.playback-slider { - width: 90%; -} - -.volume-slider { - width: 100%; -} - -.volume-slider-container { - width: 90%; - margin: 0 auto; - padding: 0px; -} - -.volume-slider-container .col-auto, -.volume-slider-container .col { - display: flex; - align-items: center; - justify-self: center; - padding: 0px; - margin: 0px; -} - -.playback-button { - font-size: 2em; - width: 40px; - height: 36px; - padding: 0px; - background: transparent; - border: 0px; - border-radius: 0px; - box-shadow: unset; - background-size: 12px; - background-position: center; - background-repeat: no-repeat; - opacity: 0.70; - border-radius: 6px; -} - -.playback-button:active { - transform: scale(0.95); -} - -.playback-button--small { - border-radius: 6px; - font-size: 1em; - color: inherit; - background-size: 14px; - background-repeat: no-repeat; - background-position: center; - background-color: transparent; - width: 40px; - height: 32px; - border: 0px; - box-shadow: unset; -} - -.playback-button:hover, .playback-button--small:hover { - background-color: rgb(200 200 200 / 10%); -} - -.playback-button:active, .playback-button--small:active { - transform: scale(0.9); -} - -.playback-button--small.active { - background-color: rgb(200 200 200 / 10%); -} - -.playback-button--small.search { - background-image: url("./assets/search.svg"); -} - -.playback-button--small.cast { - background-image: url("./assets/cast_white.svg"); -} - -.playback-button--small.queue { - background-image: url("./assets/list.svg"); -} - -.playback-button--small.lyrics { - background-image: url("./assets/quote-right.svg"); -} - -.playback-button--small.shuffle { - background-image: url("./assets/shuffle.svg"); -} - -.playback-button--small.repeat { - background-image: url("./assets/repeat.svg"); -} - -.playback-button--small.repeat.repeatOne { - background-color: var(--keyColor); -} - -.playback-button.pause { - background-image: url('./assets/pause.svg'); -} - -.playback-button.play { - background-image: url('./assets/play.svg'); -} - -.playback-button.next { - background-image: url('./assets/forward.svg'); -} - -.playback-button.previous { - background-image: url('./assets/backward.svg'); -} - -.playback-buttons { - display: flex; - align-items: center; - justify-content: center; -} - -.player-volume-glyph { - width: 32px; - height: 16px; - background-repeat: no-repeat; - background-size: contain; - background-position: center; -} - -.player-volume-glyph.decrease { - background-image: url("./assets/volume-down.svg"); - opacity: 0.5; -} - -.player-volume-glyph.increase { - background-image: url("./assets/volume-up.svg"); - opacity: 0.5; -} - -.player-track-info { - width: 90%; - margin: 0 auto; -} - -.player-song-title { - font-size: 1.25em; - text-align: left; - margin: 0 auto; - font-weight: 500; -} - -.player-song-artist { - font-size: 1.0em; - text-align: left; - margin: 0 auto; - color: var(--keyColor); - font-weight: 400; -} - -.player-song-artist:hover { - cursor: pointer; - text-decoration: underline; -} - -.player-more-container { - display: flex; - align-items: center; - justify-content: center; -} - -.player-more-button { - appearance: none; - width: 32px; - height: 32px; - border-radius: 50%; - border: 0px; - background: var(--keyColor); - cursor: pointer; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%); - color: white; - font-weight: bold; - padding: 0px; - font-size: 16px; -} - -.back-button { - width: 40px; - height: 40px; - background-color: transparent; - background-size: 16px; - background-position: center; - background-repeat: no-repeat; - background-image: url("./assets/arrow-left.svg"); - border: 0px; - border-radius: 0px; -} - -.header-text { - height: 40px; - display: flex; - align-items: center; - -} - - -.flex-center { - display: flex; - align-items: center; - flex-wrap: wrap; -} - -.list-entry-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px; - font-size: 1em; - font-family: inherit; -} - -.list-entry { - display: flex; - align-items: center; - /* justify-content: space-between; */ - padding: 12px; - font-size: 1em; - font-family: inherit; - border-bottom: 1px solid rgba(255 255 255 / 0.1); - cursor: pointer; -} - -.list-entry-image { - --artwork: url(""); - width: 64px; - height: 64px; - background: var(--artwork); - background-size: cover; - background-position: center; - background-repeat: no-repeat; - border-radius: 8px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55); -} - -.list-entry-image.artist { - border-radius: 50%; -} - -.list-entry-body { - display: flex; - flex-direction: column; - justify-content: center; - align-items: flex-start; - margin-left: 12px; -} - -.list-entry-name { - font-size: 14px; - font-weight: 500; - overflow: hidden; - width: 100%; -} - -.list-entry-artist { - font-size: 12px; - overflow: hidden; - width: 100%; -} - -.list-entry .handle { - height: 100%; - width: 28px; - background: var(--keyColor); - display: flex; - justify-content: center; - align-items: center; -} - -.md-container { - width: 100%; - position: relative; -} - -.search-panel { - background: rgb(0 0 0 / 50%); -} - -.search-header { - position: absolute; - width: 100%; - z-index: 1; - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border-bottom: 1px solid rgb(200 200 200 / 8%); -} - -.connection-error-panel { - background: rgb(0 0 0 / 50%); -} - -.search-type-container { - display: flex; -} - -.search-type-button { - background: rgb(20 20 20 / 0.85); - border-radius: 50px; - color: white; - border: 0px; - box-shadow: unset; - font-family: inherit; - padding: 8px 16px; - font-size: 14px; - font-weight: 500; - margin: 8px; - margin-top: 0px; - margin-bottom: 0px; -} - -.search-type-button.active { - background: var(--keyColor); -} - -.search-tab-container { - overflow: auto; - white-space: nowrap; - overflow-y: hidden; -} - -.search-body-container { - position: relative; - width: 100%; - height: 100%; -} - -.queue-body { - width: 100%; - height: 100%; -} - -.search-body { - position: absolute; - width: 100%; - height: 100%; - padding-top: 220px; -} - -.search-tab { - background: rgb(20 20 20 / 0.85); - border-radius: 50px; - color: white; - border: 0px; - box-shadow: unset; - font-family: inherit; - padding: 8px 16px; - font-size: 14px; - font-weight: 500; -} - -.search-tab.active { - background: var(--keyColor); -} - -.context-menu { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.5); - z-index: 100; -} - -.context-menu .context-menu-item { - --borderRadius: 10px; - appearance: none; - width: 100%; - display: block; - font-size: 1.10em; - padding: 18px 20px; - font-family: inherit; - border: 0px; - font-weight: 600; - border-radius: 0px; - border-bottom: 1px solid rgb(200 200 200 / 15%); - margin: 0px; - background: rgb(60 60 60 / 80%); - backdrop-filter: blur(16px) saturate(180%); - -webkit-backdrop-filter: blur(16px) saturate(180%); - color: #ccc; -} - -.context-menu .context-menu-item:hover { - cursor: pointer; -} - -.context-menu .context-menu-item:active { - filter: brightness(75%); -} - -.context-menu .context-menu-item:first-child { - border-radius: 0px; - border-top-left-radius: var(--borderRadius); - border-top-right-radius: var(--borderRadius); -} - -.context-menu .context-menu-item:last-child { - border-radius: 0px; - border-bottom-left-radius: var(--borderRadius); - border-bottom-right-radius: var(--borderRadius); - border-bottom: 0px; -} - -.context-menu .context-menu-item:only-child { - border-radius: var(--borderRadius); -} - -.context-menu .context-menu-item.context-menu-item--left { - text-align: left; -} - -.context-menu .context-menu-body { - display: flex; - align-items: flex-end; - justify-content: flex-end; - flex-direction: column; -} - -.lyric-body { - -webkit-mask-image: -webkit-gradient(linear, left 95%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0))); - overflow-y: scroll; - overflow-x: hidden; - display: flex; - flex-flow: column; -} - -.lyric-line { - --bgSpeed: 1s; - appearance: none; - color: white; - font-size: 26px; - transform: scale(0.8); - transform-origin: left center; - transition: transform 0.2s var(--appleEase); - opacity: 0.75; - width: auto; - display: inline-block; - margin: 10px; - margin-left: 5%; - margin-right: 0px; -} - -.lyric-line:hover { - cursor: pointer; -} - -.lyric-line:hover::after { - content: ' '; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - transform: scale(1.06); - background: rgba(200, 200, 200, 0.1); - pointer-events: none; - border-radius: 10px; - -webkit-backface-visibility: hidden; -} - -.lyric-line.active { - --bgSpeed: 1s; - opacity: 1; - transform: scale(1); - /*background: var(--keyColor);*/ - transition: transform 0.2s var(--appleEase); -} - -.lyric-line:not(.active) { - filter: blur(1px) -} - -.lyricWaiting { - margin-top: 8px; - display: none; -} - -.lyric-line.active .lyricWaiting { - display: inline-flex; - animation: lyricWaitingLine 6s cubic-bezier(0.42, 0, 0.58, 1) infinite; -} - - -.lyric-line.active .lyricWaiting > div { - width: 10px; - height: 10px; - background: white; - border-radius: 50%; - margin: 3px; -} - -.lyrics-translation { - font-size: 1.6rem; - font-weight: 400; -} - -@keyframes lyricWaitingLine { - 0% { - opacity: 0.25; - transform: scale(0.85); - } - 50% { - opacity: 1; - transform: scale(1); - } - 100% { - opacity: 0.25; - transform: scale(0.85); - } -} - -@keyframes dotOpacity { - 0% { - opacity: 0.25; - } - 100% { - opacity: 1; - } -} - - -.lyric-line2:before { - background: var(--keyColor); - content: ''; - width: 0%; - height: 6px; - position: absolute; - bottom: -8px; - left: 0; - border-radius: 10px; - z-index: -1; - transition: width var(--bgSpeed); -} - -.lyric-line2.active:before { - width: 100%; - transition: width var(--bgSpeed); -} - -.player_top { - height: 100%; -} - -/* Cider */ - -.reload-btn { - background: rgb(86 86 86 / 52%); - border-radius: 100%; - width: 32px; - height: 32px; - border: 0px; - appearance: none; - display: flex; - justify-content: center; - align-items: center; -} - -.reload-btn:hover { - background: rgb(86 86 86 / 80%); - cursor: pointer; -} - -.reload-btn>svg { - height: 50%; - color: #eee; -} - -.wr-btn { - font-family: inherit; - appearance: none; - border:0px; - border-radius: 6px; - padding: 8px; - font-weight: 600; - background: rgb(80 80 80 / 70%); - color: white; -} - -/* Album / Playlist Page */ -.playlist-page { - padding: 0px; -} - -.playlist-page .well { - background: rgba(200, 200, 200, 0.05); - border-radius: 10px; - padding: var(--contentInnerPadding); - box-shadow: rgb(0 0 0 / 8%) 0px 0px 0px 1px; - margin-top: 16px; -} - -.playlist-page .playlist-body { - padding: var(--contentInnerPadding); -} - -.playlist-display { - padding: var(--contentInnerPadding); - min-height: 300px; -} - -.playlist-display .playlist-info{ - flex-shrink: unset; - display: flex; - flex-flow: column; - justify-content: flex-end; -} - -.playlist-display .playlist-info .playlist-name { - font-weight: 700; - font-size: 1.6rem; - margin-bottom: 6px; - margin-right: 6px; - flex-shrink: unset; - -} -.playlist-display .playlist-info .playlist-artist { - font-weight: 500; - font-size: 1.6rem; - margin-bottom: 6px; - margin-right: 6px; - flex-shrink: unset; -} -.playlist-display .playlist-info .playlist-desc { - box-sizing: border-box; - font-size: 14px; - flex-shrink: unset; - margin-right: 5px; - max-height: 100px; - position: relative; -} -.playlist-display .playlist-info .playlist-desc .content { - height: 100px; - -webkit-mask-image: -webkit-gradient(linear, left 50%, left 90%, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0))); -} - -.playlist-display .playlist-info .playlist-desc .more-btn { - appearance: none; - position: absolute; - right: 0; - bottom: 0; - padding: 0 5px; - font-size: 14px; - color: var(--keyColor); - background-color: transparent; - border: 0px; - cursor: pointer; - width: 100%; - height: 100%; - overflow: hidden; - display: flex; - justify-content: flex-end; - align-items: flex-end; - font-weight: 600; - font-family: inherit; - text-transform: uppercase; -} - -.playlist-display .playlist-info .playlist-desc-expanded { - box-sizing: border-box; - font-size: 14px; - position: relative; -} - -.playlist-display .playlist-info .playlist-desc-expanded .more-btn { - appearance: none; - position: absolute; - right: 0; - bottom: 0; - padding: 0 5px; - font-size: 14px; - color: var(--keyColor); - background-color: transparent; - border: 0px; - cursor: pointer; - width: 100%; - height: 100%; - overflow: hidden; - display: flex; - justify-content: flex-end; - align-items: flex-end; - font-weight: 600; - font-family: inherit; - text-transform: uppercase; -} - -.playlist-time { - font-size: 0.9em; - margin: 6px; - opacity: 0.7; -} - -/* Artist Page */ - -.artist-page { - padding: 0px; -} - -.artist-page .artist-header { - background: var(--keyColor); - color: white; - display: flex; - align-items: center; - justify-content: space-between; - min-height: 300px; - position: relative; -} - -.artist-page .artist-image { - width: 200px; - height: 200px; - margin: 32px; -} - -.artist-page .artist-body { - padding: var(--contentInnerPadding); -} - -.artist-page .well { - background: rgba(200, 200, 200, 0.05); - border-radius: 10px; - padding: var(--contentInnerPadding); - box-shadow: rgb(0 0 0 / 8%) 0px 0px 0px 1px; - margin-top: 16px; -} - -.artist-page .showmoreless { - font-family: inherit; - font-size: 16px; - font-weight: 500; - background: transparent; - border: 0px; - border-radius: 6px; - appearance: none; - color: var(--keyColor); - padding: 8px 12px; - cursor: pointer; - margin-top: 12px; - float: right; -} - -.artist-page .showmoreless:hover { - background: rgb(200 200 200 / 10%); -} - - -/* Artist Page End */ - -.text-overflow-elipsis { - display: -webkit-box; - min-width: 0px; - overflow: hidden; - text-overflow: ellipsis; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; -} - - -.mediaitem-artwork { - border-radius: var(--mediaItemRadius); - overflow: hidden; - flex: 0 0 auto; - position:relative; - width: 100%; - height: 100%; -} -.mediaitem-artwork .animatedartwork-view-box .animated{ - position: absolute; - top: 0px; - width: 100%; - height: 100%; -} - -.mediaitem-artwork .animatedartwork-view-box .animated > video { - width: 100%; - height: 100%; -} - -.mediaitem-artwork .animatedartwork-view-box{ - position: absolute; - top: 0px; - width: 100%; - height: 100%; -} - -.artist-header .animated{ - width: 100%; - height: 100%; - align-self: center; - position: absolute; - overflow: hidden; - box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; -} - -.artist-header .row .col.flex-center{ - z-index: 4; -} - -.artist-header .animated > video { - overflow: hidden; - height: 100%; - width: 100%; - min-height: 56.25vw; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%,-50%); - -} - -.mediaitem-artwork.rounded { - border-radius: 100%; -} - -.mediaitem-artwork::after { - content: ""; - box-shadow: var(--mediaItemShadow); - z-index: 1; - width:100%; - height:100%; - position: absolute; - top:0; - left:0; - border-radius: inherit; -} - -.mediaitem-artwork.rounded::after { - border-radius: 100%; -} - -.mediaitem-artwork>img { - width: 100%; - height: 100%; - object-fit: cover; - image-rendering: -webkit-optimize-contrast; -} - -/* horizontal media scroller */ -.cd-hmedia-scroller { - margin: 0 auto; - display: flex; - flex-flow: row; - overflow-x: scroll; -} - -.cd-hmedia-scroller::-webkit-scrollbar-thumb{ - box-shadow: none; -} - -.cd-hmedia-scroller:hover::-webkit-scrollbar-thumb{ - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); -} - -/* mediaitem-list-item */ -.cd-mediaitem-list-item { - width: 100%; - height: 60px; - display: flex; - flex: 0 0 auto; - flex-direction: row; - font-size: 14px; - justify-content: center; - align-items: center; - cursor: pointer; - border-bottom: 1px solid rgb(200 200 200 / 10%); -} - -.cd-mediaitem-list-item:hover { - background: rgb(200 200 200 / 10%); -} - -.cd-mediaitem-list-item .artwork { - height: 34px; - width: 34px; - border-radius: var(--mediaItemRadius); - object-fit: cover; - object-position: center; - flex: 0 0 auto; - background-repeat: no-repeat; - margin: 12px; - border: 0px; - outline: none; -} - -.cd-mediaitem-list-item .artwork.round { - border-radius: var(--mediaItemRadiusRound); -} - -.cd-mediaitem-list-item .info-rect { - width: 100%; -} - -.cd-mediaitem-list-item .title { - width: 100%; -} - -.cd-mediaitem-list-item .subtitle { - width: 90%; - font-size: 12px; - opacity: 0.7; -} - -.cd-mediaitem-list-item .duration { - min-width: 60px; - text-align: center; -} - -.cd-mediaitem-list-item .metainfo { - min-width: 145px; - text-align: center; -} - -.cd-mediaitem-list-item .content-rating { - text-transform: uppercase; - font-size: 10px; - border-radius: 3px; - background: rgb(200 200 200 / 15%); - width: 60px; - text-align: center; - padding: 5px; - margin-right: 12px; - flex: 0 0 auto; - font-weight: 500; - color: #ccc; -} - -.cd-mediaitem-list-item .isLibrary>button { - appearance: none; - border:0px; - background:transparent; - cursor:pointer; -} - -/* mediaitem-hrect */ -.cd-mediaitem-hrect { - background: rgb(255 255 255 / 18%); - width: 264px; - height: 100px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: row; - font-size: 14px; - justify-content: center; - align-items: center; - border-radius: 6px; - cursor: pointer; -} - -.cd-mediaitem-hrect .artwork { - height: 70px; - width: 70px; - background: blue; - border-radius: var(--mediaItemRadius); - background: var(--artwork); - background-size: contain; - flex: 0 0 auto; - background-repeat: no-repeat; - margin: 18px; -} - -.cd-mediaitem-hrect .artwork.round { - border-radius: var(--mediaItemRadiusRound); -} - -.cd-mediaitem-hrect .info-rect { - width: 100%; -} - -.cd-mediaitem-hrect .title { - width: 100%; - text-align: center; -} - -.cd-mediaitem-hrect .subtitle { - width: 100%; - text-align: center; - font-size: 12px; -} - -/* mediaitem-square-sp */ -.cd-mediaitem-square-sp { - --spcolor: var(""); - width: 190px; - height: 250px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; - justify-content: flex-start; - align-items: center; - border-radius: 6px; - margin-left: 10px; - cursor: pointer; - background-color: var(--spcolor); -} - -.cd-mediaitem-square-sp:hover { - box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; -} - -.cd-mediaitem-square-sp .artwork { - height: 190px; - width: 190px; - background: blue; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; -} - -.artwork -{height: 190px; - width: 190px; - background: blue; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; -} - -.cd-mediaitem-square-sp .artwork:hover { - box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; -} - -.cd-mediaitem-square-sp .artwork.round { - border-radius: var(--mediaItemRadiusRound); -} - -.cd-mediaitem-square-sp .title { - width: 90%; - text-align: center; -} - -.cd-mediaitem-square-sp .subtitle { - width: 100%; - text-align: center; - font-size: 12px; -} - - -.cd-mediaitem-square-sp > .cd-mediaitem-square-large-overlay { - z-index: 3; -} -.cd-mediaitem-square-sp > .cd-mediaitem-square-large-overlay:hover { - opacity: 1; -} - -.cd-mediaitem-square-sp + .cd-mediaitem-square-large-overlay { - pointer-events: none; - -} - -.cd-mediaitem-square-sp:hover + .cd-mediaitem-square-large-overlay { - opacity: 1; - -} - -/* mediaitem-square-large */ -.cd-mediaitem-square-large { - width: 190px; - height: 250px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; - justify-content: flex-start; - align-items: center; - border-radius: 6px; - margin-left: 10px; - cursor: pointer; -} -.cd-mediaitem-square-large > * { - z-index: inherit; - -} - -/* .cd-mediaitem-square-large .artwork:hover { - box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; -} */ - -.cd-mediaitem-square-large .artwork { - height: 190px; - width: 190px; - background: blue; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; -} - -.cd-mediaitem-square-large-overlay{ - position: absolute; - width: 190px; - float: right; - height: 250px; - top: 0px; - margin: 10px; - margin-top: 0px; - opacity: 0; - -} - -.cd-mediaitem-square-large-overlay > * { - pointer-events: auto; - -} -.cd-mediaitem-square-large > .cd-mediaitem-square-large-overlay { - z-index: 3; -} -.cd-mediaitem-square-large > .cd-mediaitem-square-large-overlay:hover { - opacity: 1; -} - -.cd-mediaitem-square-large + .cd-mediaitem-square-large-overlay { - pointer-events: none; - -} - -.cd-mediaitem-square-large:hover + .cd-mediaitem-square-large-overlay { - opacity: 1; - -} - - -.cd-mediaitem-square-large .artwork.round { - border-radius: var(--mediaItemRadiusRound); -} - -.cd-mediaitem-square-large .title { - width: 90%; - text-align: center; -} - -.cd-mediaitem-square-large .subtitle { - width: 100%; - text-align: center; - font-size: 12px; -} - -/* mediaitem-square */ -.cd-mediaitem-square { - width: 200px; - height: 190px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; - justify-content: center; - align-items: center; - border-radius: 6px; - cursor: pointer; -} - -.cd-mediaitem-square:hover { - background: rgb(200 200 200 / 10%); -} - -.cd-mediaitem-square .artwork { - height: 128px; - width: 128px; - background: blue; - border-radius: var(--mediaItemRadius); - background: var(--artwork); - background-size: cover; - box-shadow: var(--mediaItemShadow); - flex: 0 0 auto; - margin: 6px; -} - -.cd-mediaitem-square .artwork.round { - border-radius: var(--mediaItemRadiusRound); -} - -.cd-mediaitem-square .title { - width: 90%; - text-align: center; -} - -.cd-mediaitem-square .subtitle { - width: 100%; - text-align: center; - font-size: 12px; -} - - -.cd-btn-seeall { - background: transparent; - border: 0px; - color: var(--keyColor); - font-family: inherit; - font-size: 16px; - border-radius: 4px; - padding: 6px; -} - -.cd-btn-seeall:hover { - cursor: pointer; - background: rgb(200 200 200 / 10%) -} - -/* Cider */ - -/* Transitions */ -.wpfade-enter-active, -.wpfade-leave-active { - transition: opacity .1s var(--appleEase); -} - -.wpfade-enter, -.wpfade-leave-to { - opacity: 0; -} -/* Transitions End */ - -@media (prefers-color-scheme: light) { - :root { - /* */ - --gfx-closeBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6MjY6MjgtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI2OjI4LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6MjY6MjgtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PtPY89oAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEpJREFUGJWNkMENwDAIA1Gh3F7sP0Ty7xD5JgpU+OuTLVvMmQohhRTCnCEK8TpfBl9eBpcBu/HXcsAZ9FQjSrWqW2Pa95gzGofPBQZRG2fS0899AAAAAElFTkSuQmCC'); - --gfx-maxBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6MjU6NTItMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI1OjUyLTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6MjU6NTItMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PntJ23wAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEhJREFUGJVjYGBgmMzAwPCXgYHhPw78l4GBYTIjlKHHwMDwlAE7EGFgYLjJANUlgEMRDPxnIqAADoaKwn8MkCDABaShaogLcACWZRl4ajKVtAAAAABJRU5ErkJggg=='); - --gfx-restoreBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6MjY6NTMtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI2OjUzLTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6MjY6NTMtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PluKsJ0AAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAGlJREFUGJWt0LEOgkAQhOFPShspSWyvMPFxKaDh0XgOq8tZuCqBIzRMMsXmn51slr9GlJVfmHC9LII3LGfoomCGHrnSloM9olnGE+3KKVgbi0oMNX1ZaXYCG50aLBj4HJwqgXuwn47eA95vgSGy6zr7OwAAAABJRU5ErkJggg=='); - --gfx-minBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxMAAAsTAQCanBgAAAaxaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pg0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPg0KICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPg0KICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDItMTdUMTM6MDA6MzJaIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wOk1vZGlmeURhdGU9IjIwMjAtMDItMTdUMTM6MDA6MzJaIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1ZDBlZGIwLWZkMDAtYjY0Zi05ZWZiLWEyYjQ1ODcwNWE4YSIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmEzMDAxZTFhLTI5MTktZTQ0OS1iOTRjLWMyMTIyNDhhOWY4YSIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjc4N2Y3OTljLTRiMTEtZTU0YS1iMjBkLTY4NjE3ZWQ5YzVlMiIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciPg0KICAgICAgPHhtcE1NOkhpc3Rvcnk+DQogICAgICAgIDxyZGY6U2VxPg0KICAgICAgICAgIDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc4N2Y3OTljLTRiMTEtZTU0YS1iMjBkLTY4NjE3ZWQ5YzVlMiIgc3RFdnQ6d2hlbj0iMjAyMC0wMi0xN1QxMzowMDozMloiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgLz4NCiAgICAgICAgICA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ODVkMGVkYjAtZmQwMC1iNjRmLTllZmItYTJiNDU4NzA1YThhIiBzdEV2dDp3aGVuPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIiAvPg0KICAgICAgICA8L3JkZjpTZXE+DQogICAgICA8L3htcE1NOkhpc3Rvcnk+DQogICAgICA8cGhvdG9zaG9wOlRleHRMYXllcnM+DQogICAgICAgIDxyZGY6QmFnPg0KICAgICAgICAgIDxyZGY6bGkgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qShIiBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKEiIC8+DQogICAgICAgIDwvcmRmOkJhZz4NCiAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+DQogICAgPC9yZGY6RGVzY3JpcHRpb24+DQogIDwvcmRmOlJERj4NCjwveDp4bXBtZXRhPg0KPD94cGFja2V0IGVuZD0iciI/PmeGdrgAAAAVSURBVChTYxhOgBGI/0OYQx0wMAAAyp4BAZ26NiYAAAAASUVORK5CYII='); - } -} - -@media (prefers-color-scheme: dark) { - :root { - --gfx-closeBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjM2LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PmN2D9EAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEtJREFUGJWNkMENwDAIA1FGY/8hkn8HOAqPfBsFKvz1yZYtbqwAlUIB6saUAH2NJ4MvL4PLgK/x13LAGTSqEaVa1a0x7XvcmI3D1wbntaRbB2haYwAAAABJRU5ErkJggg=='); - --gfx-maxBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjU4LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PlwQMBUAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAFBJREFUGJXV0LERgCAUBNHVsQADM3uwWWbojQIs47MEGhgAuS/eSw41qeFYqGlRA7iAm74DKLyrfRABoLrOgq+/hJXngi71BOoGZKBMHqhAbtMvQzel9pREAAAAAElFTkSuQmCC'); - --gfx-restoreBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjI0LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PqiFCFwAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAHNJREFUGJWtkKEOwlAMRc+QM5AwQYJFoPjZCWb2YRPIaeRTLwfTLQs0UxzX3tumtxCog78UdVTbZmM8AmsdXIABeKH2ak221dDuamnUCjyA+WtbB0zAGXgT0ycSFk31kBky/moUeBLpbsl91wi6Nnbfs/g+7XOQq6ifjfkAAAAASUVORK5CYII='); - --gfx-minBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAGOmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wMi0xN1QxMzowMDozMloiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4NWQwZWRiMC1mZDAwLWI2NGYtOWVmYi1hMmI0NTg3MDVhOGEiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDphMzAwMWUxYS0yOTE5LWU0NDktYjk0Yy1jMjEyMjQ4YTlmOGEiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHN0RXZ0OndoZW49IjIwMjAtMDItMTdUMTM6MDA6MzJaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1ZDBlZGIwLWZkMDAtYjY0Zi05ZWZiLWEyYjQ1ODcwNWE4YSIgc3RFdnQ6d2hlbj0iMjAyMC0wMi0xN1QxMzowMDozMloiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPiA8cmRmOkJhZz4gPHJkZjpsaSBwaG90b3Nob3A6TGF5ZXJOYW1lPSLupKEiIHBob3Rvc2hvcDpMYXllclRleHQ9Iu6koSIvPiA8L3JkZjpCYWc+IDwvcGhvdG9zaG9wOlRleHRMYXllcnM+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+FwvRXAAAABdJREFUGNNj/P//PwMxgHGIKPw/XDwDAOr1HuzlELLnAAAAAElFTkSuQmCC'); - } -} - - -#apple-music-video-container { - background: black; - position: absolute; - float: left; - display: none; - width: 100%; - height: calc(100% - var(--chromeHeight)); - bottom: 0; - z-index: 100000; -} - -#apple-music-video-player{ - position: absolute; - top: 50%; - width: 100%; - transform: translate(0, -50%); - height: 100%; -} - -#apple-music-video-player-controls{ - position: absolute; - z-index: 100001; - float: left; - width: 100%; - height: 100%; -} - -#apple-music-video-player-controls #player-exit{ - position: absolute; - z-index: 100001; - float: left; - width: 100%; - margin: 10px; - cursor: pointer; -} - -#apple-music-video-player-controls #player-pip{ - position: absolute; - z-index: 100001; - width: 32px; - height: 32px; - margin: 10px; - right: 50px; - border-radius: 100%; - background: rgb(255 255 255 / 50%); - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; -} - -#apple-music-video-player-controls #player-pip>svg { - width: 50%; -} - -#apple-music-video-player-controls #player-fullscreen{ - position: absolute; - z-index: 100001; - width: 32px; - height: 32px; - margin: 10px; - right: 0px; - border-radius: 100%; - background: rgb(255 255 255 / 50%); - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; -} - -#apple-music-video-player-controls #player-fullscreen>svg { - width: 50%; -} - -#apple-music-video-player-controls:hover{ - opacity: 1; -} - -img[src=""] { - text-indent: -10000px; -} - -div#captions { - font-size: 1.2rem; - position: absolute; - top: 85%; - text-align: center; - width: auto; - align-self: center; - left: 50%; - transform: translate(-50%, -50%); - background: rgba(0,0,0,0.6); - color: yellow; -} - -[v-cloak] {display: none!important} diff --git a/src/renderer/style.less b/src/renderer/style.less index 8ed97e9d..a008f5bc 100644 --- a/src/renderer/style.less +++ b/src/renderer/style.less @@ -1,27 +1,42 @@ -@import url("ameframework.css"); -@import url("assets/fonts/Inter/inter.css"); -@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;300;400;500;700;900&display=swap'); -@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100;300;400;500;700;900&display=swap"); -@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@100;300;400;500;700;900&display=swap"); -@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap"); +@import url("assets/fonts/Pretendard/pretendardvariable.css"); +@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;300;400;500;700;900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100;300;400;500;700;900&display=swap"); +// @import url("lib/quasar/quasar.min.css"); +@import url("less/appvars.less"); +@import url("less/bootstrap-vue.min.less"); +@import url("less/ameframework.less"); +@import url("less/codicon.css"); @import url("less/bootstrap.less"); @import url("less/notyf.less"); +@import url("less/elements.less"); +@import url("less/helpers.less"); +@import url("less/pages.less"); :root { + --windowRelativeScale: 1; --appleEase: cubic-bezier(0.42, 0, 0.58, 1); + --borderColor: rgb(200 200 200 / 16%); --mediaItemShadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%); --mediaItemShadow-Shadow: 0 8px 40px rgb(0 0 0 / 0.55); --mediaItemShadow-ShadowSubtle: 0 4px 14px rgb(0 0 0 / 10%); --ciderShadow-Generic: var(--mediaItemShadow), 0 8px 40px rgb(0 0 0 / 0.55); - --mediaItemRadius: 6px; + --mediaItemRadius: 8px; + --mediaItemRadiusSmall: 6px; + --mediaItemRadiusMedium: 8px; --mediaItemRadiusRound: 100%; + --panelRadius: 10px; --contentInnerPadding: 16px; - --navbarHeight: 48px; + --navbarHeight1: 48px; + --navbarHeight2: 0px; + --navbarHeight: calc(var(--navbarHeight1) + var(--navbarHeight2)); --selected: rgb(130 130 130 / 30%); --selected-click: rgb(80 80 80 / 30%); --hover: rgb(200 200 200 / 10%); - --keyColor: #fa586a; + // --keyColor: #fa586a; + --keyColorDefault: @keyColor; + --keyColor: @keyColor; --keyColor-rgb: 250, 88, 106; --keyColor-rollover: #ff8a9c; --keyColor-rollover-rgb: 255, 138, 156; @@ -30,9 +45,20 @@ --keyColor-deepPressed: #ff8a9c; --keyColor-deepPressed-rgb: 255, 138, 156; --keyColor-disabled: rgba(250, 88, 106, 0.35); - --navigationBarHeight: 38px; + --keyColor-primary: #ff2b52a6; + --navigationBarHeight: 0px; --modalBackground: #262626; + --songProgressColor: var(--keyColor); + --songProgressBackground: #333; --textColor: #eee; + --replayGradient: linear-gradient(45deg, hsl(248deg 58% 29%), hsl(13deg 41% 42%)); + --glassFilter: blur(16px) saturate(180%); + --glassFilterHeavy: blur(64px) saturate(280%); + --sidebarWidth: 260px; +} + +*:focus-visible { + outline: 2px solid var(--keyColor); } html, @@ -46,11 +72,25 @@ body { background-size: cover; background-position: center; background: #0000; - font-family: "Inter var experimental", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - transition: opacity .10s var(--appleEase); + font-family: + "Pretendard Variable", + "Noto Sans JP", + "Noto Sans KR", + "Noto Sans TC", + "Noto Sans SC", + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; + transition: opacity 0.1s var(--appleEase); } - a:-webkit-any-link { color: var(--keyColor); } @@ -68,8 +108,12 @@ body[loading] { } } -body[platform='linux'] { - background: #222; +body.stopanimation * { + animation: unset !important; + + .loadbar-sound { + display: none; + } } body.notransparency::before { @@ -80,6 +124,7 @@ body.notransparency::before { right: 0; bottom: 0; opacity: 0.5; + display: none; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==); } @@ -89,7 +134,6 @@ body.notransparency::before { box-sizing: inherit; } - /* Modern style overlay scrollbars */ ::-webkit-scrollbar { width: 16px; @@ -124,16 +168,26 @@ body.notransparency::before { } #app { - --color1: rgba(30, 30, 30, 30%); - --color2: rgba(15, 15, 15, 30%); + @panelBrightness: 0%; + @panelTransparency: 50%; + @msColor1: #202020; + @msColor2: #272727; + @msColor3: #2b2b2b; + --panelColor1: darken(mix(@msColor1, transparent, @panelTransparency), @panelBrightness); + --panelColor2: darken(mix(@msColor2, transparent, @panelTransparency), @panelBrightness); + --color1: var(--panelColor2); + --color2: var(--panelColor1); + --color3: rgb(0 0 0 / 20%); --bgColor: transparent; --bgWidth: 0px; --bgHeight: 0px; - --chromeHeight: 55px; + --chromeHeight1: 55px; + --chromeHeight2: 0px; + --chromeHeight: calc(var(--chromeHeight1) + var(--chromeHeight2)); width: 100%; height: 100%; - background: var(--color1); - color: white; + background: transparent; + color: var(--textColor); user-select: none; margin: 0 auto; position: relative; @@ -142,37 +196,7 @@ body.notransparency::before { &.simplebg { background: #0e0e0e; - - &::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - opacity: 0.5; - z-index:0; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==); - } - - .app-chrome { - z-index: 1; - } } - //&::before { - // position: absolute; - // top: -50%; - // left: -50%; - // width: var(--bgWidth); - // height: var(--bgHeight); - // background-image: var(--bgColor); - // content: ""; - // z-index: -1; - // transform: rotateZ(0deg); - // transform-origin: center; - // animation: bgRotate 10s linear infinite; - // filter: brightness(100%) saturate(200%) contrast(1.5); - //} } .bgGradientMaterial-base { @@ -198,6 +222,7 @@ body.notransparency::before { 0% { transform: rotateZ(0deg); } + 100% { transform: rotateZ(360deg); } @@ -207,7 +232,8 @@ body.notransparency::before { display: none !important; } -input[type="text"], input[type="number"] { +input[type="text"], +input[type="number"] { background: #1c1c1c; border-radius: 3px; border: 1px solid rgb(200 200 200 / 25%); @@ -217,7 +243,6 @@ input[type="text"], input[type="number"] { font-family: inherit; } - .bg-artwork--placeholder { position: absolute; top: 0; @@ -228,9 +253,21 @@ input[type="text"], input[type="number"] { z-index: -1; background-size: cover; background-position: center; - opacity: 0.70; + opacity: 0.7; } +a.dropdown-item { + color: var(--textColor); + + &:hover { + background-color: var(--selected); + color: var(--textColor); + } + + &:active { + background-color: var(--selected-click); + } +} .bg-artwork { position: absolute; @@ -249,12 +286,12 @@ input[type="text"], input[type="number"] { 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } } - .bg-artwork-container { position: absolute; top: 0; @@ -287,33 +324,32 @@ input[type="text"], input[type="number"] { .artworkMaterial { position: relative; - height:100%; - width:100%; + height: 100%; + width: 100%; overflow: hidden; pointer-events: none; - >img { + img { position: absolute; width: 200%; opacity: 0.5; filter: brightness(200%) blur(180px) saturate(280%) contrast(2); } - >img:first-child { - top:0; - left:0; + img:first-child { + top: 0; + left: 0; } - >img:last-child { - bottom:0; + img:last-child { + bottom: 0; right: 0; transform: rotate(180deg); } } - [artwork-hidden] { - transition: opacity .25s var(--appleEase); + transition: opacity 0.25s var(--appleEase); opacity: 0; } @@ -336,7 +372,7 @@ input[type="range"].web-slider::-webkit-slider-thumb { box-shadow: 0 0 2px 0 #555; } -input[type=range].web-slider::-webkit-slider-runnable-track { +input[type="range"].web-slider::-webkit-slider-runnable-track { -webkit-appearance: none; box-shadow: none; border: none; @@ -347,11 +383,6 @@ input[type=range].web-slider::-webkit-slider-runnable-track { padding: 0px; } -.md-btn { - font-family: inherit; - font-size: 14px; -} - #app-main { display: flex; width: 100%; @@ -359,16 +390,19 @@ input[type=range].web-slider::-webkit-slider-runnable-track { flex-direction: column; opacity: 1; overflow: hidden; + background-color: rgba(20 20 20 / 0.7); } #app-sidebar { - /* background-color: var(--color1); */ height: 100%; - width: 260px; + width: var(--sidebarWidth); display: flex; flex-direction: column; flex: 0 0 auto; position: relative; + background: linear-gradient(180deg, var(--baseColorMix) calc(var(--chromeHeight1) + 1px), var(--sidebarColorMix) calc(var(--chromeHeight1) + 1px)); + max-width: var(--sidebarWidth); + padding-top: var(--chromeHeight1); } #app-navbar { @@ -383,34 +417,21 @@ input[type=range].web-slider::-webkit-slider-runnable-track { } #app-content { - background-color: var(--color2); + --navigationBarHeight: var(--chromeHeight1); + background-color: var(--baseColorMix); height: 100%; width: 100%; overflow-y: scroll; overflow-y: overlay; overflow-x: hidden; - border-radius: 10px 0px 0px 0px; - border-left: 1px solid rgb(0 0 0 / 25%); - border-top: 1px solid rgb(0 0 0 / 25%); + border-radius: 0; + border-left: 1px solid var(--baseColorMix); + // border-top: 1px solid rgb(0 0 0 / 25%); position: relative; -} -.content-inner { - position: absolute; - top: var(--navigationBarHeight); - left: 0; - padding: 32px; - width: 100%; - transition: zoom 1s; - zoom: 1; -} - -.content-inner.centered { - height: 100%; - display: flex; - flex-flow: column; - justify-content: center; - align-items: center; + &::-webkit-scrollbar-track-piece { + margin-top: var(--chromeHeight1); + } } .app-drawer { @@ -418,14 +439,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track { flex: 0 0 auto; position: absolute; right: 16px; - top: 3%; - background: #1c1c1c8f; + background: var(--color2); border-radius: 12px; - z-index: 9; - height: 94%; + z-index: 10; backdrop-filter: blur(40px) saturate(180%); box-shadow: var(--ciderShadow-Generic); overflow: hidden; + height: calc(calc(100% - 6%) - var(--chromeHeight1)); + top: calc(var(--chromeHeight1) + 3%); .bgArtworkMaterial { display: none; @@ -437,6 +458,8 @@ input[type=range].web-slider::-webkit-slider-runnable-track { filter: brightness(80%) blur(180px) saturate(180%) contrast(1); } } + + transition: 0.3s var(--appleEase); } .search-input-container { @@ -447,15 +470,16 @@ input[type=range].web-slider::-webkit-slider-runnable-track { width: 100%; padding: 6px; border-radius: 6px; - border: 1px solid rgb(200 200 200 / 10%); + border: 1px solid rgba(100, 100, 100, 0.35); + border-top: 1px solid rgba(100, 100, 100, 0.5); + border-bottom: 1px solid rgb(60 60 60 / 62%); font-family: inherit; font-size: 14px; - background: rgb(100 100 100 / 25%); - color: rgb(200 200 200); + background: #1e1e1e99; + color: #c8c8c8; font-weight: 500; padding-left: 32px; position: relative; - filter: contrast(0.1); } .search-input:focus { @@ -464,14 +488,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track { } .search-input--icon { - content: ''; + content: ""; width: 100%; height: 100%; display: block; position: absolute; top: 0px; left: 0px; - background-image: url('assets/search.svg'); + background-image: url("assets/search.svg"); background-position: 10px; background-repeat: no-repeat; background-size: 12px; @@ -487,15 +511,35 @@ input[type=range].web-slider::-webkit-slider-runnable-track { .app-sidebar-header-text { font-size: 11px; - margin: 6px 3px; + padding: 6px 6px; font-weight: 600; - opacity: 0.50; + opacity: 0.5; + background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iNDYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBkPSJtNiA5IDYgNiA2LTYiPjwvcGF0aD4KPC9zdmc+"); + background-size: 16px; + background-repeat: no-repeat; + background-position: 98%; + border-radius: 3px; + + &.collapsed { + background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iNDYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBkPSJtOSAxOCA2LTYtNi02Ij48L3BhdGg+Cjwvc3ZnPg=="); + } + + &:hover { + background-color: var(--selected); + } + + &:active { + background-color: var(--selected-click); + } } .app-sidebar-footer { + border-top: 1px solid rgba(200, 200, 200, 0.15); padding: 11px; .app-playback-controls { + margin: 0 auto; + .control-buttons { display: flex; justify-content: center; @@ -506,6 +550,44 @@ input[type=range].web-slider::-webkit-slider-runnable-track { display: flex; } } + + &.collapseTab { + display: flex; + padding: 6px; + border: 0; + + > button { + appearance: none; + width: 100%; + position: relative; + padding-left: 40px; + text-align: left; + font-family: inherit; + + &:hover { + background-color: var(--selected); + } + + &:active { + background-color: var(--selected-click); + } + + &:after { + content: ""; + display: flex; + justify-content: center; + align-items: center; + width: 46px; + height: 100%; + position: absolute; + top: 0; + left: 0; + font-weight: bold; + font-size: 1em; + font-family: "codicon"; + } + } + } } .app-sidebar-button { @@ -522,7 +604,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { &.active { background: rgb(200 200 200 / 15%); - animation: usermenuBtnClick .30s cubic-bezier(0.36, 0, 0.66, -0.56); + animation: usermenuBtnClick 0.3s cubic-bezier(0.36, 0, 0.66, -0.56); } } @@ -557,7 +639,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { font-size: 14px; flex-direction: column; text-align: center; - margin-right: 35px ; + margin-right: 35px; } .app-sidebar-button > .sidebar-user-text .fullname { @@ -573,14 +655,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track { .app-sidebar-notification { text-align: center; font-size: 12px; - min-height: 60px; + min-height: 36px; display: flex; justify-content: center; align-items: center; border-top: 1px solid rgb(200 200 200 / 15%); background: rgb(0 0 0 / 15%); flex-direction: column; - padding: 20px 0px; + padding: 10px 0px; &.libraryNotification { flex-direction: row; @@ -608,17 +690,31 @@ input[type=range].web-slider::-webkit-slider-runnable-track { #cmenu() { .container { position: absolute; - width: 100%; + left: 0px; + width: var(--sidebarWidth); + max-width: var(--sidebarWidth); padding: 10px; z-index: 1; } .body { - background: #242424; + background: rgb(30 30 30 / 45%); padding: 6px; - border-radius: 6px; + border-radius: var(--panelRadius); width: 100%; box-shadow: var(--ciderShadow-Generic); + backdrop-filter: var(--glassFilter); + animation: cmenuBodyIn 0.5s var(--appleEase); + + @keyframes cmenuBodyIn { + 0% { + background: rgb(30 30 30); + } + + 100% { + background: rgb(30 30 30 / 45%); + } + } } .item { @@ -636,7 +732,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { margin: 2px 0px; &:hover { - background: var(--keyColor); + background: var(--selected); } } } @@ -646,16 +742,22 @@ input[type=range].web-slider::-webkit-slider-runnable-track { #cmenu.container(); .search-hints { + background: rgb(30 30 30) !important; #cmenu.body(); .search-hint { #cmenu.item(); + + &.active { + background: var(--keyColor); + } } } } .usermenu-container { - bottom: 66px; + top: var(--chromeHeight1); + z-index: 200001 !important; #cmenu.container(); .usermenu-body { @@ -663,19 +765,19 @@ input[type=range].web-slider::-webkit-slider-runnable-track { .usermenu-item { #cmenu.item(); - + .usermenu-item-icon { - position:relative; - top:1.5px; - right:3px; - display:table-cell; + position: relative; + top: 1.5px; + right: 3px; + display: table-cell; } .usermenu-item-name { - position:relative; - bottom:2px; + position: relative; + bottom: 2px; padding-left: 5px; - display:table-cell; + display: table-cell; } } } @@ -687,7 +789,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { left: 0; width: 100%; height: 100%; - background: rgba(0, 0, 0, 0.0); + background: rgba(0, 0, 0, 0); z-index: 100; .context-menu-item { @@ -721,14 +823,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track { box-shadow: var(--ciderShadow-Generic); &.context-menu-open { - animation-duration: .10s; + animation-duration: 0.1s; animation-name: contextMenuIn; animation-iteration-count: 1; animation-easings: var(--appleEase); } &.context-menu-close { - animation-duration: .10s; + animation-duration: 0.1s; animation-name: contextMenuOut; animation-iteration-count: 1; animation-easings: var(--appleEase); @@ -786,65 +888,129 @@ input[type=range].web-slider::-webkit-slider-runnable-track { } .app-sidebar-item { + --iconSize: 18px; display: flex; width: 100%; padding: 8px 12px; font-weight: 400; font-family: inherit; font-size: 14px; - margin: 6px 0px; + margin: 3px 0px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: #eee; - transition: transform .1s; + transition: transform 0.1s; text-align: left; + align-items: center; + gap: 12px; + position: relative; &.app-sidebar-item-playlist { -webkit-user-drag: element; overflow: hidden; text-overflow: ellipsis; + + .presentNotice { + align-self: center; + margin-left: 8px; + text-transform: uppercase; + font-size: 0.7em; + opacity: 0.6; + } + } + + > ._svg-icon { + --size: var(--iconSize); + flex-shrink: 0; } } .app-sidebar-item:hover { - border: 1px solid rgb(200 200 200 / 5%); - background: rgb(200 200 200 / 15%); + border: 1px solid rgb(200 200 200 / 0%); + background: rgb(180 180 180 / 15%); + // cursor: pointer; } .app-sidebar-item:active { - border: 1px solid rgb(200 200 200 / 5%); - background: rgb(200 200 200 / 15%); - transform: scale(0.98); + border: 1px solid rgb(200 200 200 / 0%); + background: rgb(150 150 150 / 15%); + // transform: scale(0.98); transition: transform 0s; } .app-sidebar-item.active { - border: 1px solid rgb(200 200 200 / 5%); + border: 1px solid rgb(200 200 200 / 0%); background: rgb(200 200 200 / 15%); transform: scale(1); transition: transform 0s; -} - -.app-sidebar-item.active::after { - content: ''; - width: 4px; - height: 16px; - display: block; - position: absolute; - top: calc(100% - 72%); - border-radius: 10px; - left: 0px; - background: var(--keyColor); + cursor: default; } .app-chrome { - background: var(--color1); + background-color: var(--baseColorMix); + box-shadow: + 0px 3px 6px rgb(20 20 20 / 12%), + 0px 1px 0px 0px rgb(200 200 200 / 12%); width: 100%; - height: var(--chromeHeight); + height: var(--chromeHeight1); display: flex; flex-direction: row; -webkit-app-region: drag; + z-index: 4; + + &:not(.chrome-bottom) { + // box-shadow: 0px 0px + z-index: 16; + position: fixed; + backdrop-filter: var(--glassFilter); + + .app-chrome--center { + flex: 1; + } + } + + .top-nav-group { + background: var(--baseColor); + border: 1px solid lighten(@baseColor, 8); + border-radius: 10px; + display: flex; + height: 32px; + + .app-sidebar-item { + background-color: var(--baseColor); + border-radius: 10px !important; + border: 0px; + min-width: 120px; + padding: 6px; + justify-content: center; + align-items: center; + margin: 0px; + height: 100%; + + &:hover { + background-color: lighten(@baseColor, @colorMixRate * 5); + } + + &.active { + background-color: lighten(@baseColor, @colorMixRate * 5); + } + + &.md-btn-primary { + box-shadow: 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8); + background-color: lighten(@baseColor, @colorMixRate * 5); + z-index: 1; + } + } + } + + .vdiv { + width: 1px; + background: white; + opacity: 0.25; + height: 50%; + margin: 6px; + } } .mv-chrome { @@ -869,10 +1035,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track { .app-chrome .app-chrome--left { width: 30%; justify-content: left; + -webkit-app-region: drag; } .app-chrome .app-chrome--center { - width: 100%; + //width: 40%; + .app-title-text { + font-size: 0.8em; + } } .app-chrome .app-chrome--right { @@ -888,16 +1058,20 @@ input[type=range].web-slider::-webkit-slider-runnable-track { align-items: center; -webkit-app-region: no-drag; height: auto; -} -.app-chrome .app-chrome-item.generic { - width: 50px; - opacity: 0.70; -} + &.generic { + width: 50px; + opacity: 0.7; + } -.app-chrome .app-chrome-item.volume { - width: 100px; - margin-right: 6px; + &.volume { + width: 100px; + margin-right: 6px; + } + + &.search { + margin-right: 6px; + } } .volume-button { @@ -912,15 +1086,17 @@ input[type=range].web-slider::-webkit-slider-runnable-track { background-size: 12px; background-position: center; background-repeat: no-repeat; - opacity: 0.70; + opacity: 0.7; border-radius: 6px; } -.volume-button:active, .volume-button--small:active { +.volume-button:active, +.volume-button--small:active { transform: scale(0.9); } -.volume-button.active, .volume-button--small.active { +.volume-button.active, +.volume-button--small.active { background-image: url("./assets/feather/volume.svg"); } @@ -935,42 +1111,32 @@ input[type=range].web-slider::-webkit-slider-runnable-track { width: 30px; border: 0px; box-shadow: unset; - opacity: 0.70; + opacity: 0.7; background-image: url("./assets/feather/volume-2.svg"); } -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb { +.app-chrome .app-chrome-item.volume > input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; height: 14px; width: 14px; border-radius: 50%; - background: rgb(50 50 50); + background: #a5a8ba; + box-shadow: 0px 0px 0px 1px rgba(0 0 0 / 10%); cursor: default; - box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); transition: all var(--appleTransition); } -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb:hover { - background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); - transform: scale(1.2); -} - -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb:active { - background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); - transform: scale(1); -} - -.app-chrome .app-chrome-item.volume > input[type=range] { +.app-chrome .app-chrome-item.volume > input[type="range"] { -webkit-appearance: none; height: 4px; background: rgba(255, 255, 255, 0.4); border-radius: 5px; background-size: 70% 100%; background-repeat: no-repeat; - width: 100%, + width: 100%; } -.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-runnable-track { +.app-chrome .app-chrome-item.volume > input[type="range"]::-webkit-slider-runnable-track { -webkit-appearance: none; box-shadow: none; border: none; @@ -986,18 +1152,47 @@ input[type=range].web-slider::-webkit-slider-runnable-track { height: 100%; } -.app-chrome .app-chrome-item > .app-title { - width: 100px; +.app-chrome .app-chrome-item > .app-mainmenu { + width: 34px; font-size: 13px; - background: url("./AppHeader.svg"); - background-size: 95px; + background: url("./assets/CiderMenu.svg"); + background-size: auto; background-repeat: no-repeat; background-position: center; - height: 100%; + height: 34px; margin-right: 16px; margin-left: 16px; - image-rendering: -webkit-optimize-contrast; - -webkit-app-region: drag; + margin-top: 1.5px; + border: 0px; + border-radius: 6px; + transition: transform 0.1s var(--appleEase); + position: relative; + + // &:after { + // content: ""; + // background-image: var(--cvar-userprofileimg); + // height:100%; + // width:100%; + // top:0; + // left: 0; + // display:block; + // position: absolute; + // background-size: cover; + // border-radius: 100%; + // border: 0px solid rgb(50 50 50); + // box-shadow: 0px 0px 0px 1px rgb(80 80 80); + // } + + &:hover { + transform: scale(1.1); + } + + &:active, + &.active { + border-radius: 100%; + transform: scale(1.1); + outline: 2px solid var(--keyColor); + } } .app-chrome .app-chrome-item > .window-controls { @@ -1005,50 +1200,70 @@ input[type=range].web-slider::-webkit-slider-runnable-track { font-size: 13px; height: 100%; display: flex; -} -.app-chrome .app-chrome-item > .window-controls > div { - height: 100%; - width: 32px; -} + &-macos { + width: 100px; + } -.app-chrome .app-chrome-item > .window-controls > div:hover { - background: rgb(200 200 200 / 10%); -} + > div { + height: 100%; + width: 32px; -.app-chrome .app-chrome-item > .window-controls > div.close { - width: 100%; - height: 100%; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; + &:hover { + background: rgb(200 200 200 / 10%); + } - &:hover { - background-color: rgb(196, 43, 28) + &.close { + width: 100%; + height: 100%; + background-image: var(--gfx-closeBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + + &:hover { + background-color: rgb(196, 43, 28); + } + } + + &.minmax { + background-image: var(--gfx-maxBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + width: 100%; + height: 100%; + } + + &.minmax.restore { + background-image: var(--gfx-restoreBtn); + } + + &.minimize { + background-image: var(--gfx-minBtn); + background-position: center; + background-repeat: no-repeat; + -webkit-app-region: no-drag; + width: 100%; + height: 100%; + } } } -.app-chrome .app-chrome-item > .window-controls > div.minmax { - background-image: var(--gfx-maxBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - width: 100%; - height: 100%; +body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minimize { + display: none; } -.app-chrome .app-chrome-item > .window-controls > div.minmax.restore { - background-image: var(--gfx-restoreBtn); +//body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls { +// display: none; +//} + +body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minmax { + display: none; } -.app-chrome .app-chrome-item > .window-controls > div.minimize { - background-image: var(--gfx-minBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - width: 100%; - height: 100%; +body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.close { + display: none; } .app-chrome .app-chrome-item.playback-controls { @@ -1058,6 +1273,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { max-width: 500px; border-left: 1px solid rgb(200 200 200 / 8%); border-right: 1px solid rgb(200 200 200 / 8%); + -webkit-app-region: drag; } .app-chrome .app-chrome-item > .app-playback-controls { @@ -1065,37 +1281,117 @@ input[type=range].web-slider::-webkit-slider-runnable-track { justify-content: center; align-content: center; width: 100%; + -webkit-app-region: no-drag; } -.app-chrome .app-chrome-item > .app-playback-controls .song-name { - font-weight: 600; - text-align: center; - font-size: 13px; - height: 1.3em; - line-height: 1.3em; - white-space: nowrap; - max-width: 360px; - - .song-name-normal { - height: inherit; +.app-chrome .app-chrome-item > .app-playback-controls { + .info-rect { + mask-image: linear-gradient(-90deg, transparent 0%, black 10%, black 90%, transparent 100%); + -webkit-mask-image: linear-gradient(-90deg, transparent 3%, black 10%, black 90%, transparent 100%); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; } - &.song-artist-marquee { - > marquee { - //margin-bottom: -3px; + .song-name { + font-weight: 600; + text-align: center; + font-size: 13px; + height: 1.3em; + line-height: 1.3em; + white-space: nowrap; + max-width: 360px; + + .song-name-normal { + height: inherit; + } + + &.song-artist-marquee { + > marquee { + //margin-bottom: -3px; + } + } + + .explicit-icon { + background-image: url("./assets/explicit.svg"); + height: 9px; + width: 13px; + filter: contrast(0); + background-repeat: no-repeat; + margin-left: 3px; + } + + .heart-icon { + height: 9px; + width: 13px; + filter: contrast(0); + background-repeat: no-repeat; + margin-left: 3px; } } - .explicit-icon { - background-image: url("./assets/explicit.svg"); - height: 9px; - width: 36px; + .lossless-icon { + background-image: url("./assets/lossless.svg") !important; + margin-left: 0.5em !important; + flex: 1; + } + + .ppe-icon { + background-image: url("./assets/ppe.svg") !important; + margin-left: 0.5em !important; + flex: 1; + } + + .spatial-icon { + background-image: url("./assets/spatialization.svg") !important; + margin-left: 0.5em !important; + flex: 1; + } + + .private-icon { + background-image: url("./assets/private.svg") !important; + margin-left: 0.5em !important; + flex: 1; + } + + .live-icon { + filter: none !important; + margin-left: 0.5em !important; + flex: 1; + } + + .chrome-icon-container { + display: flex; + position: absolute; + right: 0px; + } + + .audio-type { filter: contrast(0); background-repeat: no-repeat; - margin-left: 3px; + background-size: contain; + height: 15px; + width: 15px; + margin-bottom: 15px; + z-index: 1; } } +// Add Music Video Icons to Songs that are Music Videos +div[data-type="library-music-videos"] .info-rect .title::before, +div[data-type="musicVideo"] .info-rect .title::before { + content: ""; + background-image: url(./assets/feather/video.svg); + background-size: contain; + filter: invert(0.6); + display: inline-block; + width: 20px; + height: 20px; + margin-bottom: -4px; +} + .app-chrome .app-chrome-item > .app-playback-controls .song-duration p { font-weight: 400; font-size: 10px; @@ -1105,43 +1401,47 @@ input[type=range].web-slider::-webkit-slider-runnable-track { margin: 0 0 0 0.25em; } -.app-playback-controls:hover .marquee{ - animation: unset; - &.song-artist{ +.app-playback-controls:hover .marquee { + animation: unset; + + &.song-artist { overflow: hidden; } - .song-artist{ + + .song-artist { overflow: hidden; } - &.song-name{ + + &.song-name { overflow: hidden; } - &::after{ + + &::after { content: none !important; display: none; } } +.marquee { + animation: marquee 15s linear 2s infinite; -.marquee{ - animation: marquee 15s linear infinite; - &.song-artist{ - overflow: unset ; + &.song-artist { + overflow: unset; } - .song-artist{ - overflow: unset ; + + .song-artist { + overflow: unset; } - &.song-name{ - overflow: unset ; + + &.song-name { + overflow: unset; } - &::after{ + + &::after { content: attr(data-value); } } - - - .app-chrome .app-chrome-item > .app-playback-controls .song-progress { @bgColor: transparent; //height: 16px; @@ -1151,7 +1451,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { background: @bgColor; &:hover { - > input[type=range] { + > input[type="range"] { &::-webkit-slider-thumb { opacity: 1; transform: scale(1); @@ -1160,12 +1460,13 @@ input[type=range].web-slider::-webkit-slider-runnable-track { } } - > input[type=range] { + > input[type="range"] { appearance: none; width: 100%; height: 4px; background-color: rgb(200 200 200 / 10%); border-radius: 2px; + margin: 0; &::-webkit-slider-thumb { opacity: 0; @@ -1175,16 +1476,18 @@ input[type=range].web-slider::-webkit-slider-runnable-track { width: 12px; height: 12px; border-radius: 100%; - background: var(--keyColor); + background: var(--songProgressColor); cursor: default; - transition: opacity .10s var(--appleEase), transform .10s var(--appleEase); + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); } &::-moz-range-thumb { width: 8px; height: 8px; border-radius: 100%; - background: var(--keyColor); + background: var(--songProgressColor); cursor: default; } } @@ -1207,11 +1510,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track { background-position: center; background-size: contain; background-repeat: no-repeat; - border-radius: 4px; + border-radius: var(--mediaItemRadiusSmall); flex: 0 0 auto; margin: 6px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 25%); image-rendering: -webkit-optimize-contrast; + + .mediaitem-artwork { + border-radius: var(--mediaItemRadiusSmall); + } } .app-chrome .app-chrome-item > .app-playback-controls .actions { @@ -1241,15 +1547,18 @@ input[type=range].web-slider::-webkit-slider-runnable-track { &:focus { outline: none; } + &:hover { background: var(--hover); } + &:active { background: var(--selected-click); transform: scale(0.95); } + .svg-icon { - --url: url('views/svg/more.svg')!important; + --url: url("views/svg/more.svg") !important; } } } @@ -1264,23 +1573,27 @@ input[type=range].web-slider::-webkit-slider-runnable-track { overflow: hidden; } -.app-chrome .app-chrome-item > .app-playback-controls .playback-info > .song-progress{ +.app-chrome .app-chrome-item > .app-playback-controls .playback-info > .song-progress { width: 100%; } .app-navigation { + background: transparent; + align-items: center; + justify-content: center; background: var(--color1); - height: calc(100% - var(--chromeHeight)); + height: calc(100% - var(--chromeHeight2)); width: 100%; display: flex; position: relative; } -.app-chrome .app-chrome-item > .app-playback-controls > div >.song-artist-album { + +.app-chrome .app-chrome-item > .app-playback-controls .song-artist-album { font-weight: 400; font-size: 12px; text-align: center; - /*height: 1.2em; - line-height: 1.2em;*/ + /*height : 1.2em; + line-height : 1.2em;*/ z-index: 1; align-items: center; justify-content: center; @@ -1288,17 +1601,16 @@ input[type=range].web-slider::-webkit-slider-runnable-track { max-width: 340px; overflow: hidden; - .song-artist-album-content{ + .song-artist-album-content { font-weight: 400; font-size: 12px; text-align: center; - width:100%; + width: 100%; &.song-artist-normal { height: inherit; } } - &.song-artist-marquee { > marquee { @@ -1326,9 +1638,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } /* Window is smaller <= 1023px width */ -@media only screen and (max-width: 1023px) { +@media only screen and (max-width: 1120px) { .display--small { - display: inherit !important;; + display: inherit !important; .slider { width: 100%; @@ -1343,7 +1655,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { padding-bottom: 10px; } - input[type=range] { + input[type="range"] { -webkit-appearance: none; height: 4px; background: rgba(255, 255, 255, 0.4); @@ -1361,14 +1673,14 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); transition: all var(--appleTransition); } - + &::-webkit-slider-thumb:hover { - background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); + background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px); transform: scale(1.2); } - + &::-webkit-slider-thumb:active { - background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); + background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px); transform: scale(1); } @@ -1381,465 +1693,44 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } - - .display--large { display: none !important; } } -.header-text { - margin: 0px; -} - -.media-item--small { - background: rgb(0 0 0 / 25%); - height: 162px; - width: 132px; - display: inline-flex; - flex-direction: column; - justify-content: center; - align-items: center; - border-radius: 10px; -} - -.media-item--small .artwork { - background: red; - margin: 6px; - border-radius: 100%; - width: 90px; - height: 90px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 30%); -} - -.playlist-artwork { - height: 190px; - width: 190px; - background: blue; - border-radius: 6px; - background: var(--artwork); - background-size: cover; - box-shadow: var(--mediaItemShadow); - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; -} - -.media-item--small .text { - font-weight: 600; - font-size: 0.90em; -} - -.media-item--small .subtext { - font-size: 0.75em; -} - -.player-duration-time { - opacity: 0.5; -} - -.player-artwork-container { - display: flex; - align-items: center; - justify-content: center; -} - -.player-duration-container { - font-size: 0.85em; - font-weight: 500; -} - -.media-artwork { - --artwork: url(""); - width: 80vw; - height: 80vw; - max-height: 500px; - max-width: 500px; - background: black; - background-image: var(--artwork); - background-size: cover; - background-position: center; - background-repeat: no-repeat; - border-radius: 8px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55); - transition: transform .10s var(--appleEase); -} - -.media-artwork.paused { - transition: transform .35s var(--appleEase); - transform: scale(0.85); -} - -.playback-slider { - width: 90%; -} - -.volume-slider { - width: 100%; -} - -.volume-slider-container { - width: 90%; - margin: 0 auto; - padding: 0px; -} - -.volume-slider-container .col-auto, -.volume-slider-container .col { - display: flex; - align-items: center; - justify-self: center; - padding: 0px; - margin: 0px; -} - -.playback-button { - font-size: 2em; - width: 40px; - height: 36px; - padding: 0px; - background: transparent; - border: 0px; - border-radius: 0px; - box-shadow: unset; - background-size: 12px; - background-position: center; - background-repeat: no-repeat; - opacity: 0.70; - border-radius: 6px; -} - -.playback-button:active { - transform: scale(0.95); -} - -.playback-button--small { - border-radius: 6px; - font-size: 1em; - color: inherit; - background-size: 14px; - background-repeat: no-repeat; - background-position: center; - background-color: transparent; - width: 40px; - height: 32px; - border: 0px; - box-shadow: unset; - opacity: 0.70; -} - -.playback-button:hover, -.playback-button--small:hover { - background-color: rgb(200 200 200 / 10%); -} - -.playback-button:active, -.playback-button--small:active { - transform: scale(0.9); -} - -.playback-button--small.active { - background-color: rgb(200 200 200 / 25%); -} - -.playback-button--small.search { - background-image: url("./assets/search.svg"); -} - -.playback-button--small.cast { - background-image: url("./assets/cast_white.svg"); -} - -.playback-button--small.miniplayer { - background-image: url("./assets/pip.svg"); -} - -.playback-button--small.queue { - background-image: url("./assets/list.svg"); -} - -.playback-button--small.lyrics { - background-image: url("./assets/quote-right.svg"); -} - -.playback-button--small.shuffle { - background-image: url("./assets/shuffle.svg"); -} - -.playback-button--small.repeat { - background-image: url("./assets/repeat.svg"); -} - -.playback-button--small.repeat.repeatOne { - background-color: rgb(200 200 200 / 25%); - background-image: url("./assets/repeatOne.svg"); -} - -.playback-button.pause { - background-image: url('./assets/pause.svg'); -} - -.playback-button.play { - background-image: url('./assets/play.svg'); -} - -.playback-button.next { - background-image: url('./assets/forward.svg'); -} - -.playback-button.previous { - background-image: url('./assets/backward.svg'); -} - -.playback-buttons { - display: flex; - align-items: center; - justify-content: center; -} - -.player-volume-glyph { - width: 32px; - height: 16px; - background-repeat: no-repeat; - background-size: contain; - background-position: center; -} - -.player-volume-glyph.decrease { - background-image: url("./assets/volume.svg"); - opacity: 0.5; -} - -.player-volume-glyph.increase { - background-image: url("./assets/volume-2.svg"); - opacity: 0.5; -} - -.player-track-info { - width: 90%; - margin: 0 auto; -} - -.player-song-title { - font-size: 1.25em; - text-align: left; - margin: 0 auto; - font-weight: 500; -} - -.player-song-artist { - font-size: 1.0em; - text-align: left; - margin: 0 auto; - color: var(--keyColor); - font-weight: 400; -} - -.player-song-artist:hover { - cursor: pointer; - text-decoration: underline; -} - -.player-more-container { - display: flex; - align-items: center; - justify-content: center; -} - -.player-more-button { - appearance: none; - width: 32px; - height: 32px; - border-radius: 50%; - border: 0px; - background: var(--keyColor); - cursor: pointer; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%); - color: white; - font-weight: bold; - padding: 0px; - font-size: 16px; -} - -.back-button { - width: 40px; - height: 40px; - background-color: transparent; - background-size: 16px; - background-position: center; - background-repeat: no-repeat; - background-image: url("./assets/arrow-left.svg"); - border: 0px; - border-radius: 0px; -} - -.header-text { - height: 40px; - display: flex; - align-items: center; - -} - - -.flex-center { +.cider-flex-center { display: flex; align-items: center; flex-wrap: wrap; } -.list-entry-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px; - font-size: 1em; - font-family: inherit; -} - -.list-entry { - display: flex; - align-items: center; - /* justify-content: space-between; */ - padding: 12px; - font-size: 1em; - font-family: inherit; - border-bottom: 1px solid rgba(255 255 255 / 0.1); - cursor: pointer; -} - -.list-entry-image { - --artwork: url(""); - width: 64px; - height: 64px; - background: var(--artwork); - background-size: cover; - background-position: center; - background-repeat: no-repeat; - border-radius: 8px; - box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55); -} - -.list-entry-image.artist { - border-radius: 50%; -} - -.list-entry-body { - display: flex; - flex-direction: column; - justify-content: center; - align-items: flex-start; - margin-left: 12px; -} - -.list-entry-name { - font-size: 14px; - font-weight: 500; - overflow: hidden; - width: 100%; -} - -.list-entry-artist { - font-size: 12px; - overflow: hidden; - width: 100%; -} - -.list-entry .handle { - height: 100%; - width: 28px; - background: var(--keyColor); - display: flex; - justify-content: center; - align-items: center; -} - .md-container { width: 100%; position: relative; } -.search-panel { - background: rgb(0 0 0 / 50%); -} - -.search-header { - position: absolute; - width: 100%; - z-index: 1; - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border-bottom: 1px solid rgb(200 200 200 / 8%); -} - -.connection-error-panel { - background: rgb(0 0 0 / 50%); -} - -.search-type-container { - display: flex; -} - -.search-type-button { - background: rgb(20 20 20 / 0.85); - border-radius: 50px; - color: white; - border: 0px; - box-shadow: unset; - font-family: inherit; - padding: 8px 16px; - font-size: 14px; - font-weight: 500; - margin: 8px; - margin-top: 0px; - margin-bottom: 0px; -} - -.search-type-button.active { - background: var(--keyColor); -} - -.search-tab-container { - overflow: auto; - white-space: nowrap; - overflow-y: hidden; -} - -.search-body-container { - position: relative; - width: 100%; - height: 100%; -} - -.search-body { - position: absolute; - width: 100%; - height: 100%; - padding-top: 220px; -} - -.search-tab { - background: rgb(20 20 20 / 0.85); - border-radius: 50px; - color: white; - border: 0px; - box-shadow: unset; - font-family: inherit; - padding: 8px 16px; - font-size: 14px; - font-weight: 500; -} - -.search-tab.active { - background: var(--keyColor); -} - .lyric-body { -webkit-mask-image: -webkit-gradient(linear, left 95%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0))); overflow-y: scroll; overflow-x: hidden; display: flex; flex-flow: column; - font-family: 'Inter', 'Noto Sans JP', 'Source Han Sans SC', 'Source Han Sans HK', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans HK', 'Noto Sans KR', sans-serif; + font-family: + "Pretendard Variable", + "Noto Sans JP", + "Noto Sans KR", + "Noto Sans TC", + "Noto Sans SC", + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; } .lyric-body .no-lyrics { @@ -1857,13 +1748,14 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { font-size: 26px; transform: scale(0.8); transform-origin: left center; - transition: transform 0.2s var(--appleEase); + transition: transform 0.5s var(--appleEase); opacity: 0.75; width: auto; display: inline-block; margin: 10px; margin-left: 5%; margin-right: 0px; + overflow-wrap: break-word; } .lyric-line.active .verse { @@ -1872,6 +1764,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .lyric-line.active .verse.verse-active { opacity: 1; + transition: opacity 0.35s var(--appleEase); } .lyric-line:hover { @@ -1879,7 +1772,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } .lyric-line:hover::after { - content: ' '; + content: " "; width: 100%; height: 100%; position: absolute; @@ -1897,11 +1790,13 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { opacity: 1; transform: scale(1); /*background: var(--keyColor);*/ - transition: transform 0.2s var(--appleEase); + transition: + transform 0.2s var(--appleEase), + opacity 0.35s var(--appleEase); } .lyric-line:not(.active) { - filter: blur(1px) + filter: blur(1px); } .lyric-line:not(.active).unsynced { @@ -1912,8 +1807,16 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { filter: none !important; } +.lyric-body:hover > .lyric-line:not(.active) { + filter: none !important; +} + +.lyric-body > .lyric-line:not(.active) { + // transition: filter var(--appleEase) 0.5s ease; +} + .lyricWaiting { - margin-top: 8px; + margin-bottom: 10px; display: none; } @@ -1922,7 +1825,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { animation: lyricWaitingLine 6s cubic-bezier(0.42, 0, 0.58, 1) infinite; } - .lyric-line.active .lyricWaiting > div { width: 10px; height: 10px; @@ -1934,7 +1836,22 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .lyrics-translation { font-size: 1.6rem; font-weight: 450; - font-family: 'Inter', 'Noto Sans JP', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans HK', 'Noto Sans KR', sans-serif; + font-family: + "Pretendard Variable", + "Noto Sans JP", + "Noto Sans KR", + "Noto Sans TC", + "Noto Sans SC", + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; filter: contrast(0.5); } @@ -1945,14 +1862,15 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { position: absolute; z-index: 1000; opacity: 1; - background: rgba(30, 30, 30, 0.8); + background-image: linear-gradient(180deg, transparent, rgba(30, 30, 30, 0.8)); justify-content: center; align-items: center; display: none; transition: opacity 0.1s var(--appleEase); } -.lyric-body:hover + .lyric-footer, .lyric-footer:hover { +.lyric-body:hover + .lyric-footer, +.lyric-footer:hover { display: flex; } @@ -1998,10 +1916,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } - .lyric-line2:before { background: var(--keyColor); - content: ''; + content: ""; width: 0%; height: 6px; position: absolute; @@ -2021,66 +1938,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 100%; } -.home-page { - top: 0; - padding-top: var(--navbarHeight); - - .artist-feed-card { - position: absolute; - bottom: 0; - left: 10%; - z-index: 1; - background: black; - width: 80%; - height: 96%; - overflow: scroll; - border-radius: 10px; - } - - .col.madeforyou-col { - width: 420px; - min-width: 0px; - max-width: 420px; - } - - .well.artistfeed-well { - margin-top: 0px; - height: 392px; - align-content: flex-start; - } - - .hint-text { - font-size: 0.9rem; - color: rgb(200 200 200 / 70%); - } - - .user-icon { - border-radius: 100%; - width: 128px; - height: 128px; - overflow: hidden; - box-shadow: var(--mediaItemShadow-Shadow); - margin: 16px; - } - - .well.profile-well { - flex-direction: column; - justify-content: center; - align-items: center; - - .name { - margin: 4px; - font-weight: 500; - } - - .handle { - margin: 4px; - opacity: 0.7; - font-weight: 500; - } - } -} - /* Cider */ .more-btn-round { @@ -2103,7 +1960,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { &:active { filter: brightness(75%); transform: scale(0.98); - transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase); + transition: + transform 0s var(--appleEase), + box-shadow 0.2s var(--appleEase); } .svg-icon { @@ -2113,6 +1972,27 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } +.social-btn { + border-radius: 100%; + background: transparent; + height: 17px; + border: 0px; + cursor: pointer; + z-index: 69; + display: flex; + justify-content: center; + align-items: center; + float: right; +} + +@media only screen and (min-width: 1133px) and (max-width: 1277px) { + .about-page { + .social-btn { + display: none !important; + } + } +} + .about-page { .teamBtn { display: flex; @@ -2142,133 +2022,30 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { margin: 0px 16px 0px 0px; pointer-events: none; } - } -} -.md-close-btn { - -webkit-mask-image: url("ameres://icons/webui/close.svg"); - -webkit-mask-repeat: no-repeat; - -webkit-mask-position: center; - background-color: white; - opacity: 0.75; - -webkit-mask-size: contain; - height: 18px; - width: 18px; -} - -.md-btn { - background: rgb(100 100 100 / 25%); - padding: 8px 14px; - border-radius: 6px; - font-size: 14px; - border: 1px solid rgba(100, 100, 100, 0.35); - border-top: 1px solid rgba(100, 100, 100, 0.5); - color: #eee; - transition: transform 0.2s var(--appleEase), box-shadow 0.2s var(--appleEase); - - &.md-btn-block { - display: block; - width:100%; - } - - &.md-btn-glyph { - display:flex; - align-items: center; - justify-content: center; - width: 100%; - } - - &.md-btn-primary { - background: #ff2b52a6; - color: white; - border: 1px solid rgb(220 53 69 / 25%); - border-top: 1px solid rgb(220 53 69 / 50%); - } - - &:hover { - filter: brightness(125%); - } - - &:active { - filter: brightness(75%); - transform: scale(0.98); - transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase); - } - - &.md-btn-icon { - display: inline-flex; - vertical-align: middle; - justify-content: center; - - > img { - margin: 0px 16px 0px 0px; - pointer-events: none; + &.githubBtn { + background-color: #211f1f; } - > .md-btn-text { - margin: 0px; + &.kofiBtn { + background-color: #fbaa19; } - } -} -.md-ico-play { - content:url("./assets/play.svg"); - width: 10px; - height: 12px; - margin-right: 1px; - align-self: center; -} + &.opencollectiveBtn { + background-color: #7fadf2; + } -.md-ico-shuffle { - content:url("./assets/shuffle.svg"); - width: 1em; - height: 1em; - margin-right: 1px; - margin-bottom: -2px; - align-self: center; -} + &.discordBtn { + background-color: #5865f2; + } -.md-ico-remove { - content:url("./assets/feather/x-circle-white.svg"); - width: 16px; - height: 16px; - margin-right: 1px; - margin-bottom: -1.5px; - align-self: center; -} + &.twitterBtn { + background-color: #1d9bf0; + } -.md-ico-add { - content:url("./assets/feather/plus-circle-white.svg"); - width: 1em; - height: 1em; - margin-right: 1px; - margin-bottom: -1.5px; - align-self: center; -} - -.md-select { - padding: 6px; - border-radius: 6px; - border: 1px solid rgba(200, 200, 200, 0.1); - border-top: 1px solid rgba(100, 100, 100, 0.5); - font-family: inherit; - font-size: 14px; - background: rgba(100, 100, 100, 0.25); - color: #eee; - - option { - font-size: 1em; - font-family: inherit; - padding: 8px 16px; - background: #404040; - } - - optgroup { - background: #2c2c2c; - } - - &:focus { - outline: solid 1px var(--selected); + &.qqBtn { + background-color: #d32f2f; + } } } @@ -2291,254 +2068,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } -.modal-fullscreen { - display: flex; - justify-content: center; - align-items: center; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.3); - z-index: 1000; - - .modal-window { - background: #333; - border-radius: 10px; - box-shadow: var(--mediaItemShadow-Shadow); - display: flex; - flex-flow: column; - max-height: 500px; - max-width: 360px; - background: #121212; - width: 100%; - position: relative; - - &:after { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - box-shadow: var(--mediaItemShadow); - z-index: 1; - border-radius: inherit; - } - - .modal-header { - width: 100%; - padding: 6px; - } - - .modal-content { - width: 100%; - height: 100%; - overflow: hidden; - overflow-y: overlay; - } - - .modal-footer { - } - } -} - -.spatialproperties-panel { - .modal-window { - height: 700px; - max-height: 700px; - width: 800px; - max-width: 800px; - overflow: hidden; - - .info-header { - padding-left: 12px; - } - - .visual-container { - display: flex; - justify-content: center; - align-items: center; - overflow: hidden; - } - - .visual { - position: relative; - height: 250px; - width: 300px; - display: inline-flex; - align-items: flex-end; - justify-content: center; - filter: drop-shadow(2px 12px 6px rgb(0 0 0 / 25%)); - margin: 0 auto; - - .face { - position: absolute; - width: calc(12px * 6); - height: calc(12px * 6); - border-radius: 6px; - transform: rotateX(60deg) rotateZ(-45deg); - transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; - } - - .listener { - position: absolute; - width: 32px; - height: 32px; - border-radius: 6px; - transform: rotateX(60deg) rotateZ(-45deg); - transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; - background: white; - color: black; - z-index: 2; - } - - .audiosource { - position: absolute; - width: 32px; - height: 32px; - border-radius: 6px; - transform: rotateX(60deg) rotateZ(-45deg); - transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; - background: yellow; - z-index: 2; - } - - .face:nth-of-type(1) { - background: linear-gradient(45deg, #28223a, #1f2038); - z-index: 1; - } - - .face:nth-of-type(2) { - background: linear-gradient(45deg, #7d53ad, #5763ff); - transform: rotateX(60deg) rotateZ(-45deg) translateZ(30px); - opacity: 0.7; - z-index: 3; - } - } - - .modal-header { - padding: 16px; - position: relative; - overflow: hidden; - - .modal-title { - text-align: center; - } - - .close-btn { - width: 50px; - height: 100%; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; - - &:hover { - background-color: rgb(196, 43, 28) - } - } - } - } -} - -.addtoplaylist-panel { - .modal-window { - max-height: 600px; - max-width: 400px; - background: rgb(18 18 18 / 90%); - overflow: hidden; - backdrop-filter: blur(16px) saturate(180%); - - .modal-header { - padding: 16px; - position: relative; - - .modal-title { - text-align: center; - } - - .close-btn { - width: 50px; - height: 100%; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; - - &:hover { - background-color: rgb(196, 43, 28) - } - } - } - - .modal-search { - width: 100%; - padding: 0px 16px; - position: relative; - } - - .playlist-item { - appearance: none; - border: 0px; - text-align: left; - width: 100%; - margin: 0; - display: flex; - background: rgba(32, 32, 32, 0.46); - color: #eee; - font-family: inherit; - font-size: 0.98em; - padding: 6px 12px; - align-items: center; - flex-flow: row; - - .icon { - pointer-events: none; - width: 32px; - height: 32px; - display: flex; - justify-content: center; - align-items: center; - margin-right: 6px; - } - - .name { - } - - &:hover { - background: var(--selected); - } - - &:active { - background: var(--selected-click); - } - - &.focused { - background: var(--keyColor); - } - } - - .playlist-item:last-child { - border-bottom: 0px; - } - } -} - #navigation-bar { width: 100%; background: rgba(0, 0, 0, 0.25); @@ -2567,7 +2096,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { color: rgba(200, 200, 200, 0.8); margin: 2px; border-radius: 6px; - transition: transform .10s var(--appleEase); + transition: transform 0.1s var(--appleEase); &:active { background: var(--selected-click); @@ -2584,739 +2113,71 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { background: var(--selected); > svg { - color: rgba(200, 200, 200, 1.0); + color: rgba(200, 200, 200, 1); } } } } -.reload-btn { - background: rgb(86 86 86 / 52%); - border-radius: 100%; - width: 32px; - height: 32px; - border: 0px; - appearance: none; - display: flex; - justify-content: center; - align-items: center; -} - -.reload-btn:hover { - background: rgb(86 86 86 / 80%); - cursor: pointer; -} - -.reload-btn > svg { - height: 50%; - color: #eee; -} - -.wr-btn { - font-family: inherit; - appearance: none; - border: 0px; - border-radius: 6px; - padding: 8px; - font-weight: 600; - background: rgb(80 80 80 / 70%); - color: white; -} - .well { background: rgba(200, 200, 200, 0.05); border-radius: 10px; padding: var(--contentInnerPadding); - box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 0px 1px; margin-top: 16px; - display: flex; - flex-flow: wrap; - justify-content: center; - > .cd-mediaitem-square { - width: 220px; - height: 260px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; + &.itemContainer { + display: flex; + flex-flow: wrap; justify-content: center; - align-items: center; - border-radius: 6px; - max-width: 240px; - flex-grow: 1; - } -} -// Library - Songs page -.library-page { - padding: 0px; - - .library-header { - position: sticky; - top: 0; - left: 0; - border-bottom: 1px solid rgba(200, 200, 200, 0.05); - z-index: 6; - background: black; - padding: 0px 2em; - backdrop-filter: blur(32px); - background: rgba(0, 0, 0, 0.25); - top: var(--navigationBarHeight); - } - - .well { - margin: 2em; - } -} - -// Podcast Page -.content-inner.podcasts-page { - display: flex; - height: calc(100% - var(--navigationBarHeight)); - padding: 0px; - - .list-flat { - border-radius: 0px; - } - - .podcast-artwork { - width: 200px; - margin: 16px auto; - height: 200px; - } - - .podcasts-list { - height: 100%; - width: 280px; - background: rgb(200 200 200 / 10%); - overflow-y: overlay; - border-right: 1px solid var(--color2); - flex: none; - overflow-x: hidden; - - .podcast-list-header { - border-bottom: 1px solid var(--color2); - font-size: 0.7em; - padding: 6px; - background: #ffffff17; - text-transform: uppercase; - font-weight: 600; - opacity: 0.5; - } - - .podcasts-search { - padding: 10px; - position: sticky; - top: 0; - left: 0; - width: 100%; - border-bottom: 1px solid var(--color2); - z-index: 2; - background: #303030; - } - } - - .episodes-list { - height: 100%; - width: 100%; - background: rgb(200 200 200 / 6%); - overflow-y: overlay; - overflow-x: hidden; - - .episodes-inline-info { - padding: 14px 14px 0px 14px; - - .podcast-show-info { - display: flex; - justify-content: center; - flex-direction: column; - } - - .podcast-show-description { - margin: 32px 6px; - font-size: 0.8rem; - white-space: pre-wrap; - display:block; - } - - .podcast-artwork { - width: 120px; - margin: 0px auto; - height: 120px; - } - } - - .podcast-no-search-results { - text-align: center; - margin-top: 40px; - } - } - - .podcasts-details { - width: 300px; - flex: none; - background: rgb(255 255 255 / 5%); - overflow-y: overlay; - overflow-x: hidden; - top: 2%; - z-index: 2; - border-left: 1px solid var(--color2); - padding-bottom: 1em; - - .meta-btn { - font-size: 0.75em; - } - - .podcasts-details-header { - display: flex; - justify-content: end; + .cd-mediaitem-square-container { align-items: center; - position: sticky; - top: 0; - z-index: 2; - } - .close-btn { - width: 50px; - height: 42px; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; - - &:hover { - background-color: rgb(196, 43, 28) - } } - .podcast-genre { - text-align: center; - margin: 6px; - font-size: 0.8em; - font-weight: 500; - opacity: 0.8; - } - - .podcast-metainfo { - text-align: center; - font-size: 0.7em; - opacity: 0.8; - } - - .podcast-header { - text-align:center; - } - - .podcast-play-btn { - width: 50%; - display: block; - margin: 0 auto; - } - - .podcast-description { - margin: 12px; - font-size: 0.75em; - white-space: pre-wrap; - display:block; - line-break: anywhere; - } - - - } - -} - -@media only screen and (max-width: 1230px) { - .content-inner.podcasts-page { - .podcasts-details { - height: 96%; - width: 300px; - flex: none; - background: rgb(20 20 20 / 97%); - overflow-y: overlay; - overflow-x: hidden; - position: absolute; - right: 2%; - top: 2%; - border-radius: 10px; - box-shadow: var(--ciderShadow-Generic); - z-index: 2; - } - } -} - - - -/* Album / Playlist Page */ -.playlist-page { - --bgColor: transparent; - padding: 0px; - //background: linear-gradient(180deg, var(--bgColor) 32px, var(--bgColor) 18px, transparent 60px, transparent 100%); - top: 0; - padding-top: var(--navigationBarHeight); - - .playlist-body { - padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); - margin-top: -75px; - } - - .floating-header { - position: sticky; - top: 0; - left: 0; - border-bottom: 1px solid rgba(200, 200, 200, 0.05); - z-index: 6; - padding: 0px 1em; - backdrop-filter: blur(32px); - background: rgba(0, 0, 0, 0.25); - top: var(--navigationBarHeight); - transition: opacity 0.1s var(--appleEase); - } - - .playlist-display { - padding: var(--contentInnerPadding); - min-height: 300px; - position: relative; - - .artworkContainer { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - margin: 0; - margin-top: calc(var(--navigationBarHeight) * -1); - margin-bottom: -10px; - padding: 0; - -webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%); - opacity: .7; - animation: playlistArtworkFadeIn 1s var(--appleEase); - - .artworkMaterial>img { - filter: brightness(100%) blur(80px) saturate(100%) contrast(1); - object-position: center; - object-fit: cover; - width: 100%; - height: 100%; - transform: unset; - } - } - - .playlistInfo { - z-index: 1; - position: absolute; - bottom: 0; - left: 0; - right: 0; - top: 0; - display: flex; + .cd-mediaitem-square { + width: 220px; + height: 260px; + display: inline-flex; + flex: 0 0 auto; + flex-direction: column; + font-size: 14px; justify-content: center; align-items: center; - width: 100%; - height: 100%; - - >.row { - width: calc(100% - 32px); - } - - .playlist-info { - flex-shrink: unset; - display: flex; - flex-flow: column; - justify-content: flex-end; - - .playlist-name { - font-weight: 700; - font-size: 1.6rem; - margin-bottom: 6px; - margin-right: 6px; - flex-shrink: unset; - } - - .nameEdit { - font-weight: 700; - font-size: 1.6rem; - margin-bottom: 6px; - margin-right: 6px; - flex-shrink: unset; - background: transparent; - border: 0px; - color: inherit; - font-family: inherit; - } - - .playlist-artist { - font-size: 20px; - margin-bottom: 6px; - margin-right: 6px; - flex-shrink: unset; - } - - .playlist-desc { - box-sizing: border-box; - font-size: 14px; - flex-shrink: unset; - margin-right: 5px; - max-height: 100px; - position: relative; - - .content { - height: 100px; - -webkit-mask-image: -webkit-gradient(linear, left 50%, left 90%, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0))); - } - - .more-btn { - appearance: none; - position: absolute; - right: 0; - bottom: 0; - padding: 0 5px; - font-size: 14px; - color: var(--keyColor); - background-color: transparent; - border: 0px; - cursor: pointer; - width: 100%; - height: 100%; - overflow: hidden; - display: flex; - justify-content: flex-end; - align-items: flex-end; - font-weight: 600; - font-family: inherit; - text-transform: uppercase; - } - } - - .playlist-desc-expanded { - box-sizing: border-box; - font-size: 14px; - position: relative; - - .more-btn { - appearance: none; - position: absolute; - right: 0; - bottom: 0; - padding: 0 5px; - font-size: 14px; - color: var(--keyColor); - background-color: transparent; - border: 0px; - cursor: pointer; - width: 100%; - height: 100%; - overflow: hidden; - display: flex; - justify-content: flex-end; - align-items: flex-end; - font-weight: 600; - font-family: inherit; - text-transform: uppercase; - } - } - } + border-radius: 6px; + max-width: 240px; + flex-grow: 1; } + &.collection-list-square { + display: grid; + grid-template-columns: repeat(4, minmax(200px, 1fr)); - } + // screen size > 1200px + @media screen and (min-width: 1500px) { + grid-template-columns: repeat(5, minmax(200px, 1fr)); + } - .friends-info { - display: flex; - flex-flow: column; - - .badge-container { - display: flex; - flex-flow: wrap; - - .socialBadge { - width: 40px; - height: 40px; - border-radius: 100%; - overflow: hidden; - box-shadow: var(--mediaItemShadow-ShadowSubtle); - transition: transform .2s var(--appleEase); - margin: 6px; - - &:hover { - transform: scale(1.2); - } + // less than 1100px + @media screen and (max-width: 1150px) { + grid-template-columns: repeat(3, minmax(200px, 1fr)); } } - - .friends-name { - text-align: center; - font-size: 0.9em; - margin: 8px; - } - } - - .playlist-time { - font-size: 0.9em; - margin: 6px; - opacity: 0.7; } } -@keyframes playlistArtworkFadeIn { - 0%{ - opacity: 0; - } - 100%{ - opacity: 0.7; - } -} -// Collection Page -.collection-page { - padding-bottom: 128px; - - .top-fab { - height: 52px; - width: 52px; - position: fixed; - bottom: 32px; - right: 32px; - border-radius: 100%; - background: rgb(60 60 60); - border: 0px; - appearance: none; - box-shadow: var(--ciderShadow-Generic); - - > svg { - height: 50%; - color: #eee; - pointer-events: none; - } - - &:hover { - background: rgb(100 100 100); - } - - &:active { - background: var(--keyColor); - } - } - - .header-text { - margin-bottom: 32px; - } +.cd-mediaitem-square-container { + display: inline-flex; + flex-direction: column; + justify-content: center; } -/* Artist Page */ - -.artist-page { - padding: 0px; - top: 0; - - .floating-header { - position: sticky; - top: 0; - left: 0; - border-bottom: 1px solid rgba(200, 200, 200, 0.05); - z-index: 6; - padding: 0px 1em; - backdrop-filter: blur(32px); - background: rgba(0, 0, 0, 0.25); - top: var(--navigationBarHeight); - transition: opacity 0.1s var(--appleEase); - } - - &.animated .artist-header .more-btn-round { - position: absolute; - bottom: 22px !important; - right: 28px; - } - - .artist-header { - //background: linear-gradient(45deg, var(--keyColor), #0e0e0e); - color: white; - display: flex; - align-items: center; - justify-content: space-between; - min-height: 400px; - position: relative; - pointer-events: none; - - .header-content { - z-index: 1; - } - - - .artworkContainer { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - margin: 0; - padding: 0; - -webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%); - opacity: .7; - animation: playlistArtworkFadeIn 1s var(--appleEase); - - .artworkMaterial>img { - filter: brightness(100%) blur(80px) saturate(100%) contrast(1); - object-position: center; - object-fit: cover; - width: 100%; - height: 100%; - transform: unset; - } - } - - .more-btn-round { - position: absolute; - bottom: 82px; - right: 28px; - } - - .animated { - width: 100%; - height: 100%; - align-self: center; - position: absolute; - overflow: hidden; - box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; - - video { - overflow: hidden; - height: 100%; - width: 100%; - min-height: 56.25vw; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } - } - - .row .col.flex-center { - z-index: 4; - } - } - - .artist-image { - width: 200px; - height: 200px; - margin: 32px; - margin-top: -5px; - position: relative; - - .overlay-play { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - opacity: 0; - background: rgb(0 0 0 / 50%); - transition: opacity 0.1s var(--appleEase); - border-radius: 100%; - z-index: 1; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - appearance: none; - border: 0px; - padding: 0px; - - &:hover { - opacity: 1; - } - - &:active { - background: var(--selected-click); - } - - > svg { - width: 70%; - } - } - } - - .artist-play { - width: 32px; - height: 32px; - background: rgba(100, 100, 100, 0.5); - box-shadow: var(--ciderShadow-Generic); - border-radius: 100%; - box-shadow: var(--mediaItemShadow); - display: none; - cursor: pointer; - appearance: none; - border: 0px; - padding: 0px; - - &:hover { - filter: brightness(125%); - } - - &:active { - filter: brightness(75%); - transform: scale(0.98); - transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase); - } - } - .artist-title { - - .artist-play { - transform: translateY(3px); - margin: 14px; - } - - &.artist-animation-on { - width: 100%; - flex: unset; - margin-left: 0.5em; - color: whitesmoke; - position: absolute; - bottom: 0; - - .artist-play { - display: block; - } - } - } - - .artist-body { - padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); - margin-top: -140px; - } - - &.animated > .artist-body { - padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); - margin-top: -57px; - } - - .showmoreless { - font-family: inherit; - font-size: 16px; - font-weight: 500; - background: transparent; - border: 0px; - border-radius: 6px; - appearance: none; - color: var(--keyColor); - padding: 8px 12px; - cursor: pointer; - margin-top: 12px; - float: right; - } - - .showmoreless:hover { - background: rgb(200 200 200 / 10%); - } +.reasonSP { + // margin-left: 15px; + color: rgb(167 163 163); + font-weight: 500; + margin-left: 15px; } -/* Artist Page End */ - .text-overflow-elipsis { display: -webkit-box; min-width: 0px; @@ -3326,1997 +2187,30 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { -webkit-box-orient: vertical; } - -.mediaitem-artwork { - border-radius: var(--mediaItemRadius); - overflow: hidden; - flex: 0 0 auto; - position: relative; - width: 100%; - height: 100%; - background-image: url("https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg"); - background-size: cover; - background-position: center; - - .animatedartwork-view-box { - position: absolute; - top: 0px; - width: 100%; - height: 100%; - - .animated { - position: absolute; - top: 0px; - width: 100%; - height: 100%; - - video { - width: 100%; - height: 100%; - } - } - } - - &.rounded { - border-radius: 100%; - - &::after { - border-radius: 100%; - } - } - - &::after { - content: ""; - box-shadow: var(--mediaItemShadow); - z-index: 1; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - border-radius: inherit; - } - - img { - width: 100%; - height: 100%; - object-fit: cover; - image-rendering: -webkit-optimize-contrast; - pointer-events: none; - } - - &.no-shadow { - box-shadow: none; - - &::after { - display: none; - } - } - - &.subtle-shadow { - box-shadow: var(--mediaItemShadow-ShadowSubtle); - } - - &.shadow { - box-shadow: var(--mediaItemShadow-Shadow); - } +.no-animation { + animation: unset !important; } -.menu-panel { - width: 100%; - height: 100%; - position: fixed; - top: 0; - left: 0; - z-index: 1001; - display: flex; - justify-content: center; - align-items: center; - - .menu-header-body { - padding: 6px; - display: flex; - background: rgb(200 200 200 / 10%); - .menu-option-header { - width: 40px; - height: 40px; - display: flex; - justify-content: center; - align-items: center; - border-radius: var(--mediaItemRadius); - appearance: none; - border: 0; - background: transparent; - - &.active { - .sidebar-icon>.svg-icon { - --color: var(--keyColor); - } - } - - &:hover { - background: var(--selected); - } - - &:active { - background: var(--selected-click); - } - } - } - .menu-panel-body { - display: flex; - flex-flow: column; - background: rgb(38 38 38); - position: relative; - min-width: 200px; - box-shadow: var(--ciderShadow-Generic); - border-radius: var(--mediaItemRadius); - overflow: hidden; - font-size: 14px; - - .menu-option { - text-align: left; - display: flex; - width: 100%; - padding: 12px 16px; - appearance: none; - border: 0px; - font: inherit; - background: transparent; - color: inherit; - - &:hover { - background: var(--selected); - } - - &:active { - background: var(--selected-click); - } - } - } - - - .menu-header-text { - margin: 18px 6px; - - .close-btn { - width: 50px; - height: 42px; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; - - &:hover { - background-color: rgb(196, 43, 28) - } - } - } - - .menu-body { - overflow: overlay; - height: 100%; - } - - .menu-footer { - width: 100%; - padding: 12px; - } -} - -.queue-panel { - height: 100%; - width: 100%; - display: flex; - flex-flow: column; - - .queue-header-text { - margin: 18px 6px; - } - - .queue-body { - overflow: overlay; - height: 100%; - } - - .queue-footer { - width: 100%; - padding: 12px; - } - - .autoplay { - background: rgb(200 200 200 / 15%); - display: flex; - justify-content: center; - appearance: none; - border: 0; - border-radius: 6px; - height: 32px; - width: 32px; - } - .infinity{ - content: url("./assets/infinity.svg"); - margin: auto; - } -} - -/* queue item */ -.cd-queue-item { - border-bottom: 1px solid rgb(200 200 200 / 10%); - padding: 8px; - - .row, - .col { - padding: 0px; - margin: 0px; - } - - .artwork { - width: 32px; - height: 32px; - flex: 0 0 auto; - } - - &.selected { - background: var(--selected); - } - - &:active { - background: var(--selected-click); - color: #eee; - } - - .queue-info { - display: flex; - flex-direction: column; - - .queue-title { - font-size: 14px; - } - - .queue-subtitle { - font-size: 13px; - opacity: 0.85; - } - } -} - -/* horizontal media scroller */ -.cd-hmedia-scroller { - margin: 0 auto; - display: flex; - flex-flow: row; - overflow-x: scroll; - overflow-y: hidden; - height: 284px; - align-items: center; - - &::-webkit-scrollbar-thumb { - box-shadow: none; - } - - &:hover::-webkit-scrollbar-thumb { - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); - } - - &.small { - overflow-x: overlay; - height: 210px; - } - - &.hmedia-scroller-card { - height: 370px; - - .mediaitem-card { - margin: 12px; - } - } -} - -/* mediaitem-list-item */ -.cd-mediaitem-list-item { - width: 100%; - height: 60px; - display: flex; - flex: 0 0 auto; - flex-direction: row; - font-size: 14px; - justify-content: center-between; - align-items: center; - border-radius: var(--mediaItemRadius); - - .artwork { - height: 42px; - width: 42px; - border-radius: var(--mediaItemRadius); - object-fit: cover; - object-position: center; - flex: 0 0 auto; - background-repeat: no-repeat; - margin: 12px; - border: 0px; - outline: none; - position: relative; - overflow: hidden; - - .overlay-play { - background: rgba(0, 0, 0, 0.5); - opacity: 0; - appearance: none; - border: 0; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - padding: 0px; - z-index: 5; - cursor: pointer; - - &:hover { - opacity: 1; - } - - &:active { - background: var(--selected-click); - } - } - } - - .artwork.round { - border-radius: var(--mediaItemRadiusRound); - } - - .info-rect { - height: 100%; - display: flex; - flex-flow: column; - justify-content: center; - flex-grow: 1; - } - - .title { - width: 100%; - } - - .subtitle { - width: 90%; - font-size: .8em; - opacity: 0.7; - } - - .duration { - min-width: 60px; - text-align: center; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - } - - .metainfo { - min-width: 145px; - text-align: center; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - } - - .explicit-icon { - background-image: url("./assets/explicit.svg"); - height: 12px; - width: 36px; - filter: contrast(0); - background-repeat: no-repeat; - } - - /* CSS.gg - */ - @keyframes load-bar { - 10% {box-shadow: inset 0 -4px 0} - 20% {box-shadow: inset 0 -10px 0} - 30% {box-shadow: inset 0 -12px 0} - 40% {box-shadow: inset 0 -8px 0} - 50% {box-shadow: inset 0 -4px 0} - 60% {box-shadow: inset 0 -6px 0} - 80% {box-shadow: inset 0 -12px 0} - 90% {box-shadow: inset 0 -6px 0} - to {box-shadow: inset 0 -2px 0} - } - - .loadbar-sound, - .loadbar-sound::after, - .loadbar-sound::before { - animation: load-bar 1.3s ease infinite alternate; - box-sizing: border-box; - width: 3px; - height: 28px; - box-shadow: inset 0 -12px 0; - } - .loadbar-sound { - margin-left: 22px; - margin-top: -16px; - position: relative; - transform: scale(var(--load-bar,1)); - color: var(--keyColor); - display: block; - } - .loadbar-sound::after, - .loadbar-sound::before { - content: ""; - position: absolute; - bottom: 0 - } - .loadbar-sound::before { - left: -4.5px; - animation-delay: -2.4s - } - .loadbar-sound::after { - right: -4.2px; - animation-delay: -3.7s - } - - .isLibrary { - flex: 0 0 auto; - width: 40px; - text-align: center; - - button { - appearance: none; - border: 0px; - background: transparent; - cursor: pointer; - filter: contrast(0.8); - } - } - - &:hover { - background: rgb(200 200 200 / 10%); - box-shadow: var(--mediaItemShadow); - - .overlay-play { - opacity: 1; - } - } - - &.mediaitem-selected { - background: var(--selected); - box-shadow: var(--mediaItemShadow); - } - - - &:active { - background: var(--selected-click); - box-shadow: var(--mediaItemShadow); - color: #eee; - } - - // list item compact - &.compact { - height: 40px; - font-size: 13px; - - .artwork { - display: none; - } - - .info-rect { - padding-left: 1em; - } - } -} - -/* mediaitem-hrect */ -.cd-mediaitem-hrect { - background: rgb(255 255 255 / 18%); - width: 264px; - height: 100px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: row; - font-size: 14px; - justify-content: center; - align-items: center; - border-radius: 6px; - cursor: pointer; - - .artwork { - height: 70px; - width: 70px; - background: blue; - border-radius: var(--mediaItemRadius); - background: var(--artwork); - background-size: contain; - flex: 0 0 auto; - background-repeat: no-repeat; - margin: 18px; - } - - .artwork.round { - border-radius: var(--mediaItemRadiusRound); - } - - .info-rect { - width: 100%; - } - - .title { - width: 100%; - text-align: center; - } - - .subtitle { - width: 100%; - text-align: center; - font-size: 12px; - } -} - -/* mediaitem-square-sp */ -.cd-mediaitem-square-sp { - --spcolor: var(""); - width: 190px; - height: 250px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; - justify-content: flex-start; - align-items: center; - border-radius: 6px; - margin-left: 10px; - cursor: pointer; - background-color: var(--spcolor); - - .artwork { - height: 190px; - width: 190px; - background: blue; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; - - &.round { - border-radius: var(--mediaItemRadiusRound); - } - - &:hover { - box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; - } - } - - .title { - width: 90%; - text-align: center; - } - - .subtitle { - width: 100%; - text-align: center; - font-size: 12px; - } - - > .cd-mediaitem-square-large-overlay { - z-index: 3; - - &:hover { - opacity: 1; - } - } - - + .cd-mediaitem-square-large-overlay { - pointer-events: none; - } - - &:hover + .cd-mediaitem-square-large-overlay { - opacity: 1; - - } - - &:hover { - box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset; - } -} - - -/* mediaitem-square-large */ -.cd-mediaitem-square-large { - width: 190px; - height: 250px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; - justify-content: flex-start; - align-items: center; - border-radius: 6px; - margin-left: 10px; - cursor: pointer; - - > * { - z-index: inherit; - } -} - -.cd-mediaitem-square-large .artwork { - height: 190px; - width: 190px; - background: blue; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; -} - -.cd-mediaitem-square-large-overlay { - position: absolute; - width: 190px; - float: right; - height: 250px; - top: 0px; - margin: 10px; - margin-top: 0px; - opacity: 0; - -} - -.cd-mediaitem-square-large-overlay > * { - pointer-events: auto; - -} - -.cd-mediaitem-square-large > .cd-mediaitem-square-large-overlay { - z-index: 3; -} - -.cd-mediaitem-square-large > .cd-mediaitem-square-large-overlay:hover { - opacity: 1; -} - -.cd-mediaitem-square-large + .cd-mediaitem-square-large-overlay { - pointer-events: none; - -} - -.cd-mediaitem-square-large:hover + .cd-mediaitem-square-large-overlay { - opacity: 1; - -} - - -.cd-mediaitem-square-large .artwork.round { - border-radius: var(--mediaItemRadiusRound); -} - -.cd-mediaitem-square-large .title { - width: 90%; - text-align: center; -} - -.cd-mediaitem-square-large .subtitle { - width: 100%; - text-align: center; - font-size: 12px; -} - -/* mediaitem-mvview */ - -/* mediaitem-mvview */ -.cd-mediaitem-mvview { - width: 300px; - height: 250px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; - justify-content: flex-start; - align-items: center; - border-radius: 6px; - margin-left: 10px; - cursor: pointer; - - > * { - z-index: inherit; - } -} - -.cd-mediaitem-mvview .artwork { - height: 172px; - width: 300px; - background: blue; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: 6px; - margin-top: 0px; -} - -.cd-mediaitem-mvview-overlay { - position: absolute; - width: 300px; - float: right; - height: 250px; - top: 0px; - margin: 10px; - margin-top: 0px; - opacity: 0; - -} - -.cd-mediaitem-mvview-overlay > * { - pointer-events: auto; - -} - -.cd-mediaitem-mvview > .cd-mediaitem-mvview-overlay { - z-index: 3; -} - -.cd-mediaitem-mvview > .cd-mediaitem-mvview-overlay:hover { - opacity: 1; -} - -.cd-mediaitem-mvview + .cd-mediaitem-mvview-overlay { - pointer-events: none; - -} - -.cd-mediaitem-mvview:hover + .cd-mediaitem-mvview-overlay { - opacity: 1; - -} - - -.cd-mediaitem-mvview .artwork.round { - border-radius: var(--mediaItemRadiusRound); -} - -.cd-mediaitem-mvview .title { - width: 90%; - text-align: center; -} - -.cd-mediaitem-mvview .subtitle { - width: 100%; - text-align: center; - font-size: 12px; -} - - -/* mediaitem-square */ -.cd-mediaitem-square { - width: 220px; - height: 260px; - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: 14px; - justify-content: center; - align-items: center; - border-radius: 6px; - - .artwork-container { - position: relative; - - .artwork { - height: 190px; - width: 190px; - background: blue; - border-radius: var(--mediaItemRadius); - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: 6px; - cursor: pointer; - - &.round { - border-radius: var(--mediaItemRadiusRound); - } - } - - .badge-container { - transition: opacity 0.1s var(--appleEase); - opacity: 1; - - .socialBadge { - width: 32px; - height: 32px; - position: absolute; - right: 14px; - bottom: 14px; - border-radius: 100%; - overflow: hidden; - z-index: 2; - pointer-events: none; - } - } - - > .play-btn, - > .menu-btn { - opacity: 0; - appearance: none; - padding: 0px; - border: 0px; - width: 30px; - height: 30px; - border-radius: 50%; - background: rgba(50, 50, 50, 0.7); - cursor: pointer; - transition: opacity 0.1s var(--appleEase); - - :hover { - border-radius: 50%; - background: rgba(250, 0, 0, 0.7); - } - } - - > .play-btn { - position: absolute; - bottom: 14px; - left: 14px; - z-index: 2; - - } - - > .menu-btn { - position: absolute; - bottom: 14px; - right: 14px; - z-index: 2; - } - - &:hover { - > .badge-container { - opacity: 0; - } - - > .play-btn, - > .menu-btn { - opacity: 1; - } - } - } - - .info-rect { - width: 90%; - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - } - - - .title { - width: 100%; - text-align: center; - display: flex; - align-content: center; - justify-content: center; - } - - .subtitle { - width: 100%; - text-align: center; - font-size: 12px; - } - - &.mediaitem-video { - height: 200px; - width: 240px; - - .artwork { - height: 120px; - width: 212px; - } - } - - &.mediaitem-brick { - height: 200px; - width: 240px; - - .artwork { - height: 123px; - width: 220px; - } - } - - &.mediaitem-small { - width: 140px; - height: 180px; - - .artwork { - height: 128px; - width: 128px; - } - } - - &.mediaitem-card { - background: #ccc; - background: var(--spcolor); - height: 298px; - width: 230px; - max-width: 250px; - max-height: 500px; - overflow: hidden; - position: relative; - border-radius: calc(var(--mediaItemRadius) * 2); - box-shadow: var(--mediaItemShadow-ShadowSubtle); - - .artwork { - width: 230px; - height: 230px; - overflow: hidden; - border-radius: 0px; - margin: 0; - - .mediaitem-artwork { - border-radius: 0px; - - &::after { - box-shadow: unset; - } - } - } - - .info-rect-card { - padding: 10px 10px 14px; - position: relative; - width: 100%; - - &::before { - background: var(--bgartwork); - content: ""; - top: 0; - left: 0; - bottom: 0; - right: 0; - position: absolute; - background-size: cover; - background-position: bottom; - z-index: 0; - opacity: 1; - filter: brightness(0.5) blur(50px) saturate(180%); - } - } - - .title { - height: 100%; - display: flex; - justify-content: center; - align-items: center; - font-size: 0.9em; - font-weight: 500; - z-index: 1; - } - - .subtitle { - height: 100%; - justify-content: center; - align-items: center; - font-size: 0.75em; - width: 100%; - display: flex; - z-index: 1; - } - - &::after { - box-shadow: var(--mediaItemShadow); - content: ""; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - pointer-events: none; - border-radius: inherit; - } - } -} - -/* mediaitem-square */ -.albums-square-containeru > * > .cd-mediaitem-square { - --frame: max(220px, 15vw); - width: var(--frame); - height: calc(var(--frame) * 13 / 11); - display: inline-flex; - flex: 0 0 auto; - flex-direction: column; - font-size: calc(var(--frame) / 220 * 14); - justify-content: center; - align-items: center; - border-radius: calc(var(--frame) / 220 * 6); - - .artwork-container { - position: relative; - - .artwork { - height: calc(var(--frame) * 19 / 22); - width: calc(var(--frame) * 19 / 22); - background: blue; - border-radius: var(--mediaItemRadius); - background: var(--artwork); - background-size: cover; - flex: 0 0 auto; - margin: calc(var(--frame) / 220 * 6); - cursor: pointer; - - &.round { - border-radius: var(--mediaItemRadiusRound); - } - } - - > .play-btn, - > .menu-btn { - opacity: 0; - appearance: none; - padding: 0px; - border: 0px; - width: calc(var(--frame) / 220 * 30); - height: calc(var(--frame) / 220 * 30); - border-radius: 50%; - background: rgba(50, 50, 50, 0.7); - cursor: pointer; - backdrop-filter: blur(32px) saturate(180%); - transition: opacity 0.1s var(--appleEase); - } - - > .play-btn { - position: absolute; - bottom: calc(var(--frame) / 220 * 14); - left: calc(var(--frame) / 220 * 14); - z-index: 2; - } - - > .menu-btn { - position: absolute; - bottom: calc(var(--frame) / 220 * 14); - right: calc(var(--frame) / 220 * 14); - z-index: 2; - } - - &:hover { - - > .play-btn, - > .menu-btn { - opacity: 1; - } - } - } - - - .title { - width: 90%; - text-align: center; - } - - .subtitle { - width: 100%; - text-align: center; - font-size: calc(var(--frame) / 220 * 12); - } - - &.mediaitem-video { - height: calc(var(--frame) / 220 * 200); - width: calc(var(--frame) / 220 * 240); - - .artwork { - height: calc(var(--frame) / 220 * 120); - width: calc(var(--frame) / 220 * 212); - } - } - - &.mediaitem-brick { - height: calc(var(--frame) / 220 * 200); - width: calc(var(--frame) / 220 * 240); - - .artwork { - height: calc(var(--frame) / 220 * 123); - width: calc(var(--frame)); - } - } -} - -.cd-btn-seeall { - background: transparent; - border: 0px; - color: var(--keyColor); - font-family: inherit; - font-weight: 500; - font-size: 16px; - border-radius: 4px; - padding: 6px; - - &:hover { - cursor: pointer; - background: rgb(200 200 200 / 10%) - } -} - -.fullscreen-view-container { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: black; - z-index: 99; - display: flex; - justify-content: center; - align-items: center; - opacity: 1; -} - -.fullscreen-view { - width: 100%; - height: 100%; - background: black; - display: flex; - justify-content: center; - align-items: center; - - .fs-row { - flex-grow: 1; - } - - .playback-button--small.active { - background-color: rgb(200 200 200 / 25%); - } - - .playback-button--small { - opacity: 0.7; - } - - .right-col { - height: 50vh; - } - - @media only screen and (max-width: 1023px) { - .display--large { - display: flex !important; - } - } - - .display--large { - display: flex; - - .slider { - width: 100%; - z-index: 1; - } - - .input-container { - display: flex; - justify-content: center; - align-items: center; - width: 100% - } - - .volume-button--small { - border-radius: 6px; - color: inherit; - background-size: 16px; - background-repeat: no-repeat; - background-position: center; - background-color: transparent; - height: 15px; - width: 30px; - border: 0px; - box-shadow: unset; - opacity: 0.70; - background-image: url("./assets/feather/volume-2.svg"); - } - - .volume-button--small:active { - transform: scale(0.9); - } - - .volume-button--small.active { - background-image: url("./assets/feather/volume.svg"); - } - - input[type=range] { - -webkit-appearance: none; - height: 4px; - background: rgba(255, 255, 255, 0.4); - border-radius: 5px; - background-size: 70% 100%; - background-repeat: no-repeat; - - &::-webkit-slider-thumb { - -webkit-appearance: none; - height: 14px; - width: 14px; - border-radius: 50%; - background: rgb(50 50 50); - cursor: default; - box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); - transition: all var(--appleTransition); - } - - &::-webkit-slider-thumb:hover { - background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); - transform: scale(1.2); - } - - &::-webkit-slider-thumb:active { - background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); - transform: scale(1); - } - - &::-webkit-slider-runnable-track { - -webkit-appearance: none; - box-shadow: none; - border: none; - background: transparent; - } - } - } - - - .background { - position: absolute; - background-size: cover; - width: 100%; - height: 100%; - - .bgArtworkMaterial { - position: absolute; - width: 100%; - height: 100%; - - .bg-artwork-container { - z-index: unset; - } - - .bg-artwork-container .bg-artwork { - filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9); - } - - .no-animation { - animation: unset; - } - } - } - - - .lyrics-col { - - height: 62vh; - display: flex; - justify-content: center; - align-content: center; - width: 80%; - - ::-webkit-scrollbar-thumb { - box-shadow: unset; - } - - &:hover ::-webkit-scrollbar-thumb { - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); - } - - .no-lyrics { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - } - - .lyric-line { - font-size: 35px; - } - - } - - .queue-col { - - width: 60vh; - height: 62vh; - - .queue-title { - opacity: 0.6; - } - - .queue-panel > * { - z-index: 3; - } - - ::-webkit-scrollbar-thumb { - box-shadow: unset; - } - - &:hover ::-webkit-scrollbar-thumb { - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); - } - } - - .tab-toggles { - display: flex; - position: absolute; - bottom: 0; - right: 0; - width: 15vh; - height: 5vh; - justify-content: space-evenly; - - .volume { - background-image: url("./assets/feathers/volume.svg"); - padding: 0.5vh; - width: 2vh; - height: 2vh; - background-origin: content-box; - background-repeat: no-repeat; - } - - .queue { - background-image: url("./assets/list.svg"); - padding: 0.5vh; - width: 2.5vh; - height: 2.5vh; - background-origin: content-box; - background-repeat: no-repeat; - } - - .lyrics { - background-image: url("./assets/quote-right.svg"); - padding: 0.5vh; - width: 2.5vh; - height: 2.5vh; - background-origin: content-box; - background-repeat: no-repeat; - } - - .active { - background-color: rgba(200, 200, 200, 0.7); - border-radius: 3px; - } - } - - .artwork-col { - justify-content: center; - align-items: center; - display: flex; - flex-direction: column; - - .artwork { - width: 50vh; - height: 50vh; - } - - .controls-parents { - width: 50vh; - } - - .app-playback-controls { - .song-artist, .song-name { - font-weight: 600; - text-align: center; - font-size: 0.9em; - height: 1.2em; - line-height: 0.9em; - overflow: hidden; - text-overflow: ellipsis; - max-width: 360px; - - .song-name-normal { - height: inherit; - } - - &.song-artist-marquee { - > marquee { - //margin-bottom: -3px; - } - } - } - - .song-artist { - font-size: 0.875em; - font-weight: 400; - } - - .song-name { - width: unset !important; - margin-top: 0.15vh; - display: -webkit-box; - line-height: 1.2; - text-overflow: ellipsis; - text-align: center; - } - } - - .app-playback-controls .playback-info { - margin-top: 0.5vh; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - position: relative; - - input[type="range"] { - width: 100%; - } - - > div { - width: 100%; - text-align: center; - } - - - } - - .app-playback-controls .song-progress { - @bgColor: transparent; - //height: 16px; - position: absolute; - bottom: -1.5vh; - left: 0px; - background: @bgColor; - - .song-duration p { - font-weight: 400; - font-size: 10px; - height: 1.2em; - line-height: 1.3em; - overflow: hidden; - margin: 0 0 0 0.25em; - } - - &:hover { - > input[type=range] { - &::-webkit-slider-thumb { - opacity: 1; - transform: scale(1); - z-index: 1; - } - } - } - - input[type=range] { - appearance: none; - width: 100%; - height: 4px; - background-color: rgb(200 200 200 / 10%); - border-radius: 2px; - - &::-webkit-slider-thumb { - opacity: 0; - transform: scale(0.5); - -webkit-appearance: none; - appearance: none; - width: 12px; - height: 12px; - border-radius: 100%; - background: var(--keyColor); - cursor: default; - transition: opacity .10s var(--appleEase), transform .10s var(--appleEase); - } - - &::-moz-range-thumb { - width: 8px; - height: 8px; - border-radius: 100%; - background: var(--keyColor); - cursor: default; - } - } - } - - .control-buttons { - margin-top: 2vh; - display: inline-flex; - width: 100%; - justify-content: center; - } - - } -} - -.mini-view { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - - .fs-row { - flex-grow: 1; - } - - .playback-button--small.active { - background-color: rgb(200 200 200 / 25%); - } - - .player-exit { - z-index: 3; - position: absolute; - top: 5px; - right: 5px; - -webkit-app-region: no-drag; - } - - .player-pin { - z-index: 3; - position: absolute; - min-width: 20px; - min-height: 20px; - top: 5px; - right: 30px; - -webkit-app-region: no-drag; - } - - #mini-pin{ - display: none; - } - - .player-pin:hover #mini-pin { - display: block; - } - - .playback-button--small { - opacity: 0.7; - } - - .right-col { - height: 50vh; - } - - @media only screen and (max-width: 1023px) { - .display--large { - display: flex !important; - } - } - - .display--large { - display: flex; - - .slider { - width: 100%; - z-index: 1; - } - - .input-container { - display: flex; - justify-content: center; - align-items: center; - width: 100% - } - - .volume-button--small { - border-radius: 6px; - color: inherit; - background-size: 16px; - background-repeat: no-repeat; - background-position: center; - background-color: transparent; - height: 15px; - width: 30px; - border: 0px; - box-shadow: unset; - opacity: 0.70; - background-image: url("./assets/feather/volume-2.svg"); - } - - .volume-button--small:active { - transform: scale(0.9); - } - - .volume-button--small.active { - background-image: url("./assets/feather/volume.svg"); - } - - input[type=range] { - -webkit-appearance: none; - height: 4px; - background: rgba(255, 255, 255, 0.4); - border-radius: 5px; - background-size: 70% 100%; - background-repeat: no-repeat; - - &::-webkit-slider-thumb { - -webkit-appearance: none; - height: 14px; - width: 14px; - border-radius: 50%; - background: rgb(50 50 50); - cursor: default; - box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); - transition: all var(--appleTransition); - } - - &::-webkit-slider-thumb:hover { - background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); - transform: scale(1.2); - } - - &::-webkit-slider-thumb:active { - background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); - transform: scale(1); - } - - &::-webkit-slider-runnable-track { - -webkit-appearance: none; - box-shadow: none; - border: none; - background: transparent; - } - } - } - - - .background { - position: absolute; - background-size: cover; - width: 100%; - height: 100%; - -webkit-user-select: none; - -webkit-app-region: drag; - - .bgArtworkMaterial { - position: absolute; - width: 100%; - height: 100%; - - .bg-artwork-container { - z-index: unset; - } - - .bg-artwork-container .bg-artwork { - filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9); - } - - .no-animation { - animation: unset; - } - } - } - - - .lyrics-col { - - height: 62vh; - display: flex; - justify-content: center; - align-content: center; - width: 80%; - - ::-webkit-scrollbar-thumb { - box-shadow: unset; - } - - &:hover ::-webkit-scrollbar-thumb { - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); - } - - .no-lyrics { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - } - - .lyric-line { - font-size: 35px; - } - - } - - .queue-col { - - width: 60vh; - height: 50vh; - - .queue-title { - opacity: 0.6; - } - - .queue-panel > * { - z-index: 3; - } - - ::-webkit-scrollbar-thumb { - box-shadow: unset; - } - - &:hover ::-webkit-scrollbar-thumb { - box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%); - } - } - - .tab-toggles { - display: flex; - position: absolute; - bottom: 0; - right: 0; - width: 15vh; - height: 5vh; - justify-content: space-evenly; - - .volume { - background-image: url("./assets/feathers/volume.svg"); - padding: 0.5vh; - width: 2vh; - height: 2vh; - background-origin: content-box; - background-repeat: no-repeat; - } - - .queue { - background-image: url("./assets/list.svg"); - padding: 0.5vh; - width: 2.5vh; - height: 2.5vh; - background-origin: content-box; - background-repeat: no-repeat; - } - - .lyrics { - background-image: url("./assets/quote-right.svg"); - padding: 0.5vh; - width: 2.5vh; - height: 2.5vh; - background-origin: content-box; - background-repeat: no-repeat; - } - - .active { - background-color: rgba(200, 200, 200, 0.7); - border-radius: 3px; - } - } - - .artwork-col { - justify-content: center; - align-items: center; - display: flex; - flex-direction: column; - - .artwork { - width: 100%; - height: 100%; - - .mediaitem-artwork{ - border-radius: unset; - } - } - - .controls-parents { - width: 100%; - position: absolute; - background: #0000009e; - backdrop-filter: blur(10px); - bottom: 0px; - z-index: 3; - opacity: 0; - padding: 3%; - &:hover { - opacity : 1; - } - } - - - .app-playback-controls { - -webkit-app-region: no-drag; - - .song-artist, .song-name { - font-weight: 600; - text-align: center; - font-size: 0.9em; - height: 1.2em; - line-height: 0.9em; - overflow: hidden; - text-overflow: ellipsis; - max-width: 360px; - - .song-name-normal { - height: inherit; - } - - &.song-artist-marquee { - > marquee { - //margin-bottom: -3px; - } - } - } - - .song-artist { - font-size: 0.875em; - font-weight: 400; - } - - .song-name { - width: unset !important; - margin-top: 0.15vh; - display: -webkit-box; - line-height: 1.2; - text-overflow: ellipsis; - text-align: center; - } - } - - .app-playback-controls .playback-info { - margin-top: 0.5vh; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - position: relative; - - input[type="range"] { - width: 100%; - } - - > div { - width: 100%; - text-align: center; - } - - - } - - .app-playback-controls .song-progress { - @bgColor: transparent; - //height: 16px; - position: absolute; - bottom: -3.5vh; - left: 0px; - background: @bgColor; - - .song-duration p { - font-weight: 400; - font-size: 10px; - height: 1.2em; - line-height: 1.3em; - overflow: hidden; - margin: 0 0 0 0.25em; - } - - &:hover { - > input[type=range] { - &::-webkit-slider-thumb { - opacity: 1; - transform: scale(1); - z-index: 1; - } - } - } - - input[type=range] { - appearance: none; - width: 100%; - height: 4px; - background-color: rgb(200 200 200 / 10%); - border-radius: 2px; - - &::-webkit-slider-thumb { - opacity: 0; - transform: scale(0.5); - -webkit-appearance: none; - appearance: none; - width: 12px; - height: 12px; - border-radius: 100%; - background: var(--keyColor); - cursor: default; - transition: opacity .10s var(--appleEase), transform .10s var(--appleEase); - } - - &::-moz-range-thumb { - width: 8px; - height: 8px; - border-radius: 100%; - background: var(--keyColor); - cursor: default; - } - } - } - - .control-buttons { - margin-top: 3.5vh; - display: inline-flex; - width: 100%; - justify-content: center; - } - - } -} +@import url("less/fullscreen.less"); +@import url("less/miniplayer.less"); // Cider App -.mediaitem-list-item__grid { - overflow-x: overlay; - overflow-y: hidden; - background: rgba(200, 200, 200, 0.05); - border-radius: 10px; - padding: var(--contentInnerPadding); - box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 0px 1px; - height: 300px; - display: flex; - align-items: center; - .grid-body { - display: grid; - grid-auto-flow: column dense; - grid-template-rows: auto auto auto auto; - grid-gap: 0 6px; - padding: 2px 0; - justify-content: left; - width: 0; - } +#micaEffect { + opacity: 1; + // animation: micaEnter 1s ease-in-out forwards; + filter: brightness(1) saturate(320%); - .cd-mediaitem-list-item { - width: 350px; - height: 60px; - } - - &::-webkit-scrollbar { - display: none; - } - - &:hover::-webkit-scrollbar { - display: initial; - - } -} + @keyframes micaEnter { + 0% { + opacity: 0; + transform: translateY(10px); + } -.settings-page { - padding:0px; - - .md-option-header { - padding: 1.25em 1.25em; - border-bottom: unset; - border-top: unset; - font-weight: 600; - font-size: 1.0em; - background: rgb(255 255 255 / 3%); - } - .settings-option-body { - margin: 16px; - } -} - -// sidebar icon -.svg-icon { - --color: #aaa; - --url: url("./assets/feather/share.svg"); - -webkit-mask-image: var(--url); - -webkit-mask-size: cover; - height: 18px; - width: 18px; - background: var(--color); -} - -.sidebar-icon { - width: 18px; - height: 18px; - margin-right: 8px; - - > .svg-icon { - width: 100%; - height: 100%; - --color: #aaa; - } - - > svg { - width: 100%; - height: 100%; - color: #aaa; + 100% { + opacity: 1; + transform: translateY(0px); + } } } @@ -5332,6 +2226,18 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { // Modular .modular-fs { + .app-chrome.chrome-bottom { + position: fixed; + bottom: 0; + left: 0; + z-index: 14 !important; + backdrop-filter: var(--glassFilter); + } + + .app-navigation { + height: 100%; + } + .app-drawer { width: 100%; right: 0px; @@ -5347,8 +2253,12 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { &::before { top: -50%; left: -20%; - width: 200VH; - height: 200VH; + width: 200vh; + height: 200vh; + } + + .bg-artwork-container { + display: block !important; } } @@ -5358,22 +2268,15 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { padding: 0px; margin: 0px; overflow: hidden; + filter: drop-shadow(0px 4px 6px rgb(0 0 0 / 70%)); .lyric-line { pointer-events: none; - font-weight: 500; + font-weight: 600; font-size: 2em; transform-origin: center; - animation: fsLyricIn var(--appleEase) .2s; + animation: fsLyricIn var(--appleEase) 0.2s; opacity: 0.9; - text-shadow: -1px -1px 0 #000, - 0 -1px 0 #000, - 1px -1px 0 #000, - 1px 0 0 #000, - 1px 1px 0 #000, - 0 1px 0 #000, - -1px 1px 0 #000, - -1px 0 0 #000; &:not(.active) { display: none; @@ -5393,8 +2296,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { @keyframes fsLyricIn { 0% { opacity: 0; - transform: scale(0.98) + transform: scale(0.98); } + 100% { opacity: 1; transform: scale(1); @@ -5405,20 +2309,45 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { /* Transitions */ +.replaycard-enter-active, +.replaycard-leave-active { + transition: + opacity 0.5s var(--appleEase), + transform 0.5s var(--appleEase); +} + +.replaycard-enter, +.replaycard-leave-to { + opacity: 0; + transform: translateY(20px); +} + +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.15s var(--appleEase); +} + +.fade-enter, +.fade-leave-to { + opacity: 0; +} + .modal-enter-active, .modal-leave-active { - transition: opacity .1s var(--appleEase), transform .1s var(--appleEase); + transition: + opacity 0.1s var(--appleEase), + transform 0.1s var(--appleEase); } .modal-enter, .modal-leave-to { opacity: 0; - transform: scale(1.10); + transform: scale(1.1); } .wpfade-enter-active, .wpfade-leave-active { - transition: opacity .1s var(--appleEase); + transition: opacity 0.1s var(--appleEase); } .wpfade-enter, @@ -5428,18 +2357,46 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .wpfade_transform-enter-active, .wpfade_transform-leave-active { - transition: opacity .1s var(--appleEase), transform .1s var(--appleEase); + --transitionTime: 0.2s; + transition: opacity var(--transitionTime) var(--appleEase); + will-change: opacity, transform; } -.wpfade_transform-enter, -.wpfade_transform-leave-to { - transform: scale(0.90); +.wpfade_transform-enter { opacity: 0; + transform: unset; + will-change: opacity; +} + +.wpfade_transform-leave-to { + opacity: 0; + transform: unset; + will-change: opacity; +} + +.wpfade_transform_backwards-enter-active, +.wpfade_transform_backwards-leave-active { + --transitionTime: 0.2s; + transition: opacity var(--transitionTime) var(--appleEase); +} + +.wpfade_transform_backwards-enter { + opacity: 0; + transform: unset; + will-change: opacity; +} + +.wpfade_transform_backwards-leave-to { + opacity: 0; + transform: unset; + will-change: opacity; } .fabfade-enter-active, .fabfade-leave-active { - transition: transform .1s var(--appleEase), opacity .1s var(--appleEase); + transition: + transform 0.1s var(--appleEase), + opacity 0.1s var(--appleEase); } .fabfade-enter, @@ -5450,59 +2407,141 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .fsModeSwitch-enter-active, .fsModeSwitch-leave-active { - transition: transform 1s var(--appleEase), opacity 1s var(--appleEase); + transition: + transform 1s var(--appleEase), + opacity 1s var(--appleEase); } .fsModeSwitch-enter, .fsModeSwitch-leave-to { - transform: scale(1.10); + transform: scale(1.1); opacity: 0; } +.sidebartransition-enter-active, +.sidebartransition-leave-active { + transition: margin-left 0.35s var(--appleEase); +} + +.sidebartransition-enter, +.sidebartransition-leave-to { + margin-left: calc(var(--sidebarWidth) * -1); +} .drawertransition-enter-active, .drawertransition-leave-active { - transition: right .25s var(--appleEase); + transition: transform 0.25s var(--appleEase); } .drawertransition-enter, .drawertransition-leave-to { - right: -300px; + transform: translateX(400px); } -/* Transitions End */ - -// @media (prefers-color-scheme: light) { -// :root { -// /* */ -// --gfx-closeBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6MjY6MjgtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI2OjI4LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6MjY6MjgtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PtPY89oAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEpJREFUGJWNkMENwDAIA1Gh3F7sP0Ty7xD5JgpU+OuTLVvMmQohhRTCnCEK8TpfBl9eBpcBu/HXcsAZ9FQjSrWqW2Pa95gzGofPBQZRG2fS0899AAAAAElFTkSuQmCC'); -// --gfx-maxBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6MjU6NTItMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI1OjUyLTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6MjU6NTItMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PntJ23wAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEhJREFUGJVjYGBgmMzAwPCXgYHhPw78l4GBYTIjlKHHwMDwlAE7EGFgYLjJANUlgEMRDPxnIqAADoaKwn8MkCDABaShaogLcACWZRl4ajKVtAAAAABJRU5ErkJggg=='); -// --gfx-restoreBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6MjY6NTMtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI2OjUzLTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6MjY6NTMtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PluKsJ0AAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAGlJREFUGJWt0LEOgkAQhOFPShspSWyvMPFxKaDh0XgOq8tZuCqBIzRMMsXmn51slr9GlJVfmHC9LII3LGfoomCGHrnSloM9olnGE+3KKVgbi0oMNX1ZaXYCG50aLBj4HJwqgXuwn47eA95vgSGy6zr7OwAAAABJRU5ErkJggg=='); -// --gfx-minBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxMAAAsTAQCanBgAAAaxaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pg0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPg0KICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPg0KICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDItMTdUMTM6MDA6MzJaIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wOk1vZGlmeURhdGU9IjIwMjAtMDItMTdUMTM6MDA6MzJaIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1ZDBlZGIwLWZkMDAtYjY0Zi05ZWZiLWEyYjQ1ODcwNWE4YSIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmEzMDAxZTFhLTI5MTktZTQ0OS1iOTRjLWMyMTIyNDhhOWY4YSIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjc4N2Y3OTljLTRiMTEtZTU0YS1iMjBkLTY4NjE3ZWQ5YzVlMiIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciPg0KICAgICAgPHhtcE1NOkhpc3Rvcnk+DQogICAgICAgIDxyZGY6U2VxPg0KICAgICAgICAgIDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc4N2Y3OTljLTRiMTEtZTU0YS1iMjBkLTY4NjE3ZWQ5YzVlMiIgc3RFdnQ6d2hlbj0iMjAyMC0wMi0xN1QxMzowMDozMloiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgLz4NCiAgICAgICAgICA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ODVkMGVkYjAtZmQwMC1iNjRmLTllZmItYTJiNDU4NzA1YThhIiBzdEV2dDp3aGVuPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIiAvPg0KICAgICAgICA8L3JkZjpTZXE+DQogICAgICA8L3htcE1NOkhpc3Rvcnk+DQogICAgICA8cGhvdG9zaG9wOlRleHRMYXllcnM+DQogICAgICAgIDxyZGY6QmFnPg0KICAgICAgICAgIDxyZGY6bGkgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qShIiBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKEiIC8+DQogICAgICAgIDwvcmRmOkJhZz4NCiAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+DQogICAgPC9yZGY6RGVzY3JpcHRpb24+DQogIDwvcmRmOlJERj4NCjwveDp4bXBtZXRhPg0KPD94cGFja2V0IGVuZD0iciI/PmeGdrgAAAAVSURBVChTYxhOgBGI/0OYQx0wMAAAyp4BAZ26NiYAAAAASUVORK5CYII='); -// } -// } - @media (prefers-color-scheme: dark) { - } :root { - --gfx-closeBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjM2LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PmN2D9EAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEtJREFUGJWNkMENwDAIA1FGY/8hkn8HOAqPfBsFKvz1yZYtbqwAlUIB6saUAH2NJ4MvL4PLgK/x13LAGTSqEaVa1a0x7XvcmI3D1wbntaRbB2haYwAAAABJRU5ErkJggg=='); - --gfx-maxBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjU4LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PlwQMBUAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAFBJREFUGJXV0LERgCAUBNHVsQADM3uwWWbojQIs47MEGhgAuS/eSw41qeFYqGlRA7iAm74DKLyrfRABoLrOgq+/hJXngi71BOoGZKBMHqhAbtMvQzel9pREAAAAAElFTkSuQmCC'); - --gfx-restoreBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjI0LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PqiFCFwAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAHNJREFUGJWtkKEOwlAMRc+QM5AwQYJFoPjZCWb2YRPIaeRTLwfTLQs0UxzX3tumtxCog78UdVTbZmM8AmsdXIABeKH2ak221dDuamnUCjyA+WtbB0zAGXgT0ycSFk31kBky/moUeBLpbsl91wi6Nnbfs/g+7XOQq6ifjfkAAAAASUVORK5CYII='); - --gfx-minBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAGOmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wMi0xN1QxMzowMDozMloiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4NWQwZWRiMC1mZDAwLWI2NGYtOWVmYi1hMmI0NTg3MDVhOGEiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDphMzAwMWUxYS0yOTE5LWU0NDktYjk0Yy1jMjEyMjQ4YTlmOGEiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHN0RXZ0OndoZW49IjIwMjAtMDItMTdUMTM6MDA6MzJaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1ZDBlZGIwLWZkMDAtYjY0Zi05ZWZiLWEyYjQ1ODcwNWE4YSIgc3RFdnQ6d2hlbj0iMjAyMC0wMi0xN1QxMzowMDozMloiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPiA8cmRmOkJhZz4gPHJkZjpsaSBwaG90b3Nob3A6TGF5ZXJOYW1lPSLupKEiIHBob3Rvc2hvcDpMYXllclRleHQ9Iu6koSIvPiA8L3JkZjpCYWc+IDwvcGhvdG9zaG9wOlRleHRMYXllcnM+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+FwvRXAAAABdJREFUGNNj/P//PwMxgHGIKPw/XDwDAOr1HuzlELLnAAAAAElFTkSuQmCC'); + --gfx-closeBtn: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjM2LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PmN2D9EAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEtJREFUGJWNkMENwDAIA1FGY/8hkn8HOAqPfBsFKvz1yZYtbqwAlUIB6saUAH2NJ4MvL4PLgK/x13LAGTSqEaVa1a0x7XvcmI3D1wbntaRbB2haYwAAAABJRU5ErkJggg=="); + --gfx-maxBtn: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjU4LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PlwQMBUAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAFBJREFUGJXV0LERgCAUBNHVsQADM3uwWWbojQIs47MEGhgAuS/eSw41qeFYqGlRA7iAm74DKLyrfRABoLrOgq+/hJXngi71BOoGZKBMHqhAbtMvQzel9pREAAAAAElFTkSuQmCC"); + --gfx-restoreBtn: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjI0LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PqiFCFwAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAHNJREFUGJWtkKEOwlAMRc+QM5AwQYJFoPjZCWb2YRPIaeRTLwfTLQs0UxzX3tumtxCog78UdVTbZmM8AmsdXIABeKH2ak221dDuamnUCjyA+WtbB0zAGXgT0ycSFk31kBky/moUeBLpbsl91wi6Nnbfs/g+7XOQq6ifjfkAAAAASUVORK5CYII="); + --gfx-minBtn: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAGOmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wMi0xN1QxMzowMDozMloiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4NWQwZWRiMC1mZDAwLWI2NGYtOWVmYi1hMmI0NTg3MDVhOGEiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDphMzAwMWUxYS0yOTE5LWU0NDktYjk0Yy1jMjEyMjQ4YTlmOGEiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHN0RXZ0OndoZW49IjIwMjAtMDItMTdUMTM6MDA6MzJaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1ZDBlZGIwLWZkMDAtYjY0Zi05ZWZiLWEyYjQ1ODcwNWE4YSIgc3RFdnQ6d2hlbj0iMjAyMC0wMi0xN1QxMzowMDozMloiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPiA8cmRmOkJhZz4gPHJkZjpsaSBwaG90b3Nob3A6TGF5ZXJOYW1lPSLupKEiIHBob3Rvc2hvcDpMYXllclRleHQ9Iu6koSIvPiA8L3JkZjpCYWc+IDwvcGhvdG9zaG9wOlRleHRMYXllcnM+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+FwvRXAAAABdJREFUGNNj/P//PwMxgHGIKPw/XDwDAOr1HuzlELLnAAAAAElFTkSuQmCC"); } - #apple-music-video-container { background: black; position: absolute; float: left; display: none; width: 100%; - height: calc(100% - var(--chromeHeight)); + height: 100%; bottom: 0; z-index: 100000; + &.mini { + width: 20%; + height: 20%; + right: 2vw; + bottom: 5vh; + } +} + +#apple-music-video-container { + // AM Web Style Fullscreen Button + #player-fullscreen { + background-size: 50%; + background-position: center; + background-repeat: no-repeat; + filter: opacity(0.6); + // filter: drop-shadow(0px 0px 4px rgb(0 0 0 / 80%)); + background-color: transparent; + border-radius: 10px; + transition: 0.2s ease-in-out filter; + bottom: 0; + + &:hover { + filter: opacity(1); + transition: 0.2s ease-in-out filter; + } + } + + // AM Web Style PiP Button + #player-pip { + background-color: transparent; + border-radius: 10px; + bottom: 0; + filter: opacity(0.6); + transition: 0.2s ease-in-out filter; + + &.mini { + right: 0px; + } + + &:hover { + filter: opacity(1); + transition: 0.2s ease-in-out filter; + } + } + + .playback-info { + position: absolute; + width: 100%; + bottom: 0; + padding: 20px 40px; + background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 50%); + + .song-artist { + font-size: 1.7rem; + font-weight: bold; + } + + .song-name { + font-size: 1.2rem; + font-weight: bold; + color: rgb(255, 255, 255, 0.8); + } + } + + input[type="range"] { + align-self: center; + height: 4px; + border-radius: 0.5rem; + margin-inline: 10px; + } + + .song-progress input[type="range"] { + appearance: initial; + + &::-webkit-slider-thumb { + box-shadow: 0px 0px 0px #000000; + border: 1px solid #39404d; + background: #fff; + height: 0.7rem; + width: 0.7rem; + border-radius: 50%; + cursor: pointer; + -webkit-appearance: none; + } + } } #apple-music-video-player { @@ -5513,12 +2552,74 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 100%; } +#app.twopanel #apple-music-video-container { + top: 0; + bottom: unset; +} + +.inactive { + opacity: 0; +} + #apple-music-video-player-controls { position: absolute; z-index: 100001; float: left; width: 100%; height: 100%; + + .playback-info { + .song-progress { + display: flex; + } + + .app-chrome-item.display--large { + position: relative; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + + .playback-button { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 3px; + } + } + + .song-artist-album { + font-weight: 400; + font-size: 12px; + text-align: center; + /*height : 1.2em; + line-height : 1.2em;*/ + z-index: 1; + align-items: center; + justify-content: center; + width: 80%; + max-width: 340px; + overflow: hidden; + + .song-artist-album-content { + font-weight: 400; + font-size: 12px; + text-align: center; + width: 100%; + + &.song-artist-normal { + height: inherit; + } + } + + &.song-artist-marquee { + > marquee { + margin-bottom: -3px; + } + } + } + } } #apple-music-video-player-controls #player-exit { @@ -5526,7 +2627,10 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { z-index: 100001; float: left; width: 100%; - margin: 10px; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; + margin-bottom: 10px; cursor: pointer; } @@ -5538,7 +2642,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { margin: 10px; right: 50px; border-radius: 100%; - background: rgb(255 255 255 / 50%); display: flex; justify-content: center; align-items: center; @@ -5557,7 +2660,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { margin: 10px; right: 0px; border-radius: 100%; - background: rgb(255 255 255 / 50%); display: flex; justify-content: center; align-items: center; @@ -5588,11 +2690,11 @@ div#captions { background: rgba(0, 0, 0, 0.6); color: yellow; white-space: pre-line; - font-family: 'Inter', 'Noto Sans JP', 'Source Han Sans SC', 'Source Han Sans HK', 'Source Han Sans SC', 'Source Han Sans HK', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans HK', 'Noto Sans KR', sans-serif; + font-family: "Inter", "Noto Sans JP", "Source Han Sans SC", "Source Han Sans HK", "Source Han Sans SC", "Source Han Sans HK", "Noto Sans SC", "Noto Sans TC", "Noto Sans HK", "Noto Sans KR", sans-serif; } [v-cloak] { - display: none !important + display: none !important; } .item-navigate:hover { @@ -5614,78 +2716,6 @@ div#captions { font-weight: 500; } -/* Switch Checkbox */ -input[type=checkbox][switch] { - width: 38px; - appearance: none; - border-radius: 32px; - height: 24px; - zoom: 1; - top: 0; - cursor: pointer; - left: 0; - position: relative; - transform: scale(1); - background: rgb(142 142 147 / 100%); - padding: 0; - margin: 0; -} - -input[type=checkbox][switch]:focus, -input[type=checkbox][switch]:active { - outline: none; -} - -input[type=checkbox][switch]:checked { - background: var(--keyColor); - border: 0 solid var(--keyColor); - mix-blend-mode: unset; - - &:hover { - background: var(--keyColor-rollover); - } - - &:active { - background: var(--keyColor-pressed); - } -} - -input[type=checkbox][switch]::before { - background: white; - width: 26px; - height: 26px; - top: -1px; - left: -1px; - position: absolute; - content: ' '; - border-radius: 32px; - transition: .10s left var(--appleEase); - transform: scale(.75); -} - - -input[type=checkbox][switch]:checked::before { - background: white; - top: -1px; - left: 13px; - transition: .10s left var(--appleEase); - transform: scale(.75); -} - -input[type=checkbox][switch]:disabled::before { - opacity: .5; -} - -input[type=checkbox][switch]:active::before { - left: 13px; -} - -input[type=checkbox][switch]:checked:active::before { - left: -1px; -} - -/* End Switch Checkbox */ - .madeforyou-body { margin-top: 15px; } @@ -5701,6 +2731,32 @@ body.no-gpu { .bg-artwork-container { display: none; + animation: none !important; + + .bg-artwork { + animation: none !important; + } + } + + .floating-header { + background: black; + backdrop-filter: unset; + } + + .artworkContainer { + animation: unset !important; + opacity: 0.7; + } + + .info-rect-card { + &:before { + display: none; + } + } + + .menu-panel .menu-panel-body { + background: rgb(30 30 30); + backdrop-filter: unset; } #navigation-bar { @@ -5720,6 +2776,7 @@ body.no-gpu { backdrop-filter: unset; mix-blend-mode: unset; background: #1c1c1c; + transition: unset; } .wpfade-enter-active, @@ -5741,6 +2798,10 @@ body.no-gpu { .drawertransition-leave-to { right: -300px; } + + .lyric-line:hover::after { + display: none; + } } .qrimg { @@ -5751,11 +2812,22 @@ body.no-gpu { overflow-y: hidden; } +.moreinfo-modal { + .modal-window { + height: max-content !important; + + .modal-content { + height: max-content !important; + padding-block: 25px; + } + } +} + .equalizer-panel { .modal-window { height: 330px; max-height: 330px; - width: 800px; + width: 740px; max-width: 800px; overflow: hidden; @@ -5770,7 +2842,6 @@ body.no-gpu { overflow: hidden; } - .modal-header { padding: 16px; position: relative; @@ -5781,61 +2852,52 @@ body.no-gpu { } .close-btn { - width: 50px; - height: 100%; - background-image: var(--gfx-closeBtn); - background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; - - &:hover { - background-color: rgb(196, 43, 28) - } + .menu-panel.menu-header-text.close-btn; } } - .modal-content{ + + .modal-content { display: block; - - .inputs-container{ + + .inputs-container { margin-left: 8px; } - .input-container{ + .input-container { display: inline-grid; width: 54px; justify-items: center; font-size: 0.7em; } - .input-container.mini{ + + .input-container.mini { display: inline-grid; width: 43px; justify-items: center; font-size: 0.7em; } - .freq-header{ + + .freq-header { margin-bottom: 2px; } - - .reset-button{ + + .reset-button { width: 50%; margin-left: 25%; text-align: center; } + input.eq-slider { -webkit-appearance: slider-vertical; width: 5%; } - input[type="number"]{ + + input[type="number"] { padding: unset; width: 55px; } - .header input.eq-slider { + + .header input.eq-slider { -webkit-appearance: slider-vertical; width: 5%; opacity: 0; @@ -5849,5 +2911,98 @@ body.no-gpu { } } +body[platform="darwin"] { + #window-controls-container { + display: none; + } + .app-chrome .app-chrome-item > .app-mainmenu { + opacity: 0; + width: 52px; + pointer-events: none; + -webkit-app-region: drag; + } +} + +.percent { + display: inline-block; + position: relative; +} + +.percent::after { + position: relative; + right: 2em; + transition: all 0.05s ease-in-out; +} + +.percent:hover::after, +.percent:focus-within::after { + right: 3.5em; +} + +.percent::after { + content: "%"; +} + +.playbackrate-text { + align-items: end; + margin-right: 5px; +} + +.modal .close { + color: transparent; +} + +.spatialproperties-panel.modal-fullscreen { + flex-direction: column; +} + +.cursor { + background: rgb(255 255 255 / 50%); + width: 16px; + height: 16px; + position: fixed; + z-index: 9999999999; + pointer-events: none; + border-radius: 100%; + box-shadow: 0px 0px 0px 2px rgb(200 200 200 / 100%); + top: 0; + left: 0; + display: none; +} + +.keybinds-page { + .md-option-header { + padding: 10px 0px; + border-bottom: unset; + border-top: unset; + font-weight: 600; + background: rgba(255, 255, 255, 0); + font-size: 2em; + } + + .md-option-header-sub { + padding: 15px 10px; + border-bottom: unset; + border-top: unset; + background: rgba(255, 255, 255, 0); + font-weight: 600; + font-size: 1.7em; + } + + .md-option-line { + padding: 15px 20px; + font-size: 0.9em; + } +} + +.content-inner.keybinds-page { + top: var(--navigationBarHeight); + padding: 15px; +} + +@import url("less/macos.less"); +@import url("less/linux.less"); @import url("less/compact.less"); +@import url("less/directives.less"); +@import url("less/macosemu.less"); diff --git a/src/renderer/sw.js b/src/renderer/sw.js index d1b70d5d..23b46fde 100644 --- a/src/renderer/sw.js +++ b/src/renderer/sw.js @@ -1,2 +1,68 @@ -if(!self.define){let e,i={};const s=(s,r)=>(s=new URL(s+".js",r).href,i[s]||new Promise((i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()})).then((()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e})));self.define=(r,c)=>{const n=e||("document"in self?document.currentScript.src:"")||location.href;if(i[n])return;let o={};const t=e=>s(e,n),a={module:{uri:n},exports:o,require:t};i[n]=Promise.all(r.map((e=>a[e]||t(e)))).then((e=>(c(...e),o)))}}define(["./workbox-962786f2"],(function(e){"use strict";self.addEventListener("message",(e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()})),e.precacheAndRoute([{url:"ameframework.css",revision:"4bcc8646bb5742638fad52b94e231601"},{url:"apple-hls.js",revision:"2b74055662676b0fcc2d4a4bf994a9dc"},{url:"hlscider.js",revision:"cf7f512e83e32694f2c94f904714fe4c"},{url:"index_old.html",revision:"c21f3e9c5b015599d3ab07639f64a7a8"},{url:"index.js",revision:"8591a69fc9c975a063eb264b7447f173"},{url:"less.js",revision:"b6e574e4d680686786a28e7e71a17bbc"},{url:"musickit.js",revision:"211d80891c3336c1795cb83df58d4b63"},{url:"sortable.min.js",revision:"5cbc31ebec32adf60e27b76418e79d93"},{url:"style-old.css",revision:"aea9ea49df13f2deee42b68654aeea06"},{url:"todo.js",revision:"18d49fabcb96de8bd11455877d8eacb6"},{url:"vue-observe-visibility.min.js",revision:"5a52e761f6aa71b4f65a7b458f698b95"},{url:"vue.js",revision:"0a9a4681294d8c5f476687eea6e74842"},{url:"vuedraggable.umd.min.js",revision:"9a84fec5263bb510cee88e1c3b9583cc"}],{ignoreURLParametersMatching:[/^utm_/,/^fbclid$/,/^X-Amz-Algorithm/,/^X-Amz-Date/,/^X-Amz-SignedHeaders/,/^X-Amz-Expires/,/^X-Amz-Credential/,/^X-Amz-Signature/]}),e.registerRoute(/\.(?:png|jpg|jpeg|svg|webp)$/,new e.CacheFirst({cacheName:"imageinternet",plugins:[]}),"GET"),e.registerRoute(/https:\/\/is[0-9]-ssl\.mzstatic\.com\/image+/,new e.CacheFirst,"GET"),e.registerRoute(/^https:\/\/store-\d{3}\.blobstore\.apple\.com\/.{65}\/image+/,new e.CacheFirst,"GET")})); +if (!self.define) { + let e, + i = {}; + const s = (s, r) => ( + (s = new URL(s + ".js", r).href), + i[s] || + new Promise((i) => { + if ("document" in self) { + const e = document.createElement("script"); + (e.src = s), (e.onload = i), document.head.appendChild(e); + } else (e = s), importScripts(s), i(); + }).then(() => { + let e = i[s]; + if (!e) throw new Error(`Module ${s} didn’t register its module`); + return e; + }) + ); + self.define = (r, c) => { + const n = e || ("document" in self ? document.currentScript.src : "") || location.href; + if (i[n]) return; + let o = {}; + const t = (e) => s(e, n), + a = { module: { uri: n }, exports: o, require: t }; + i[n] = Promise.all(r.map((e) => a[e] || t(e))).then((e) => (c(...e), o)); + }; +} +define(["./workbox-962786f2"], function (e) { + "use strict"; + self.addEventListener("message", (e) => { + e.data && "SKIP_WAITING" === e.data.type && self.skipWaiting(); + }), + e.precacheAndRoute( + [ + { + url: "ameframework.css", + revision: "4bcc8646bb5742638fad52b94e231601", + }, + { url: "apple-hls.js", revision: "2b74055662676b0fcc2d4a4bf994a9dc" }, + { url: "hlscider.js", revision: "cf7f512e83e32694f2c94f904714fe4c" }, + { url: "index_old.html", revision: "c21f3e9c5b015599d3ab07639f64a7a8" }, + { url: "index.js", revision: "8591a69fc9c975a063eb264b7447f173" }, + { url: "less.js", revision: "b6e574e4d680686786a28e7e71a17bbc" }, + { url: "musickit.js", revision: "211d80891c3336c1795cb83df58d4b63" }, + { + url: "sortable.min.js", + revision: "5cbc31ebec32adf60e27b76418e79d93", + }, + { url: "style-old.css", revision: "aea9ea49df13f2deee42b68654aeea06" }, + { url: "todo.js", revision: "18d49fabcb96de8bd11455877d8eacb6" }, + { + url: "vue-observe-visibility.min.js", + revision: "5a52e761f6aa71b4f65a7b458f698b95", + }, + { url: "vue.js", revision: "0a9a4681294d8c5f476687eea6e74842" }, + { + url: "vuedraggable.umd.min.js", + revision: "9a84fec5263bb510cee88e1c3b9583cc", + }, + ], + { + ignoreURLParametersMatching: [/^utm_/, /^fbclid$/, /^X-Amz-Algorithm/, /^X-Amz-Date/, /^X-Amz-SignedHeaders/, /^X-Amz-Expires/, /^X-Amz-Credential/, /^X-Amz-Signature/], + }, + ), + e.registerRoute(/\.(?:png|jpg|jpeg|svg|webp)$/, new e.CacheFirst({ cacheName: "imageinternet", plugins: [] }), "GET"), + e.registerRoute(/https:\/\/is[0-9]-ssl\.mzstatic\.com\/image+/, new e.CacheFirst(), "GET"), + e.registerRoute(/^https:\/\/store-\d{3}\.blobstore\.apple\.com\/.{65}\/image+/, new e.CacheFirst(), "GET"); +}); //# sourceMappingURL=sw.js.map diff --git a/src/renderer/themes/WIP.md b/src/renderer/themes/WIP.md new file mode 100644 index 00000000..9bac366d --- /dev/null +++ b/src/renderer/themes/WIP.md @@ -0,0 +1,14 @@ +# Themes (WIP) + +## Making a theme +* If one does not already exist, create a new theme directory in the user data folder. + * **Windows:** `%appdata%/Cider/themes` + * **Mac:** `~/Library/Application Support/Cider/themes` + * **Linux:** `~/.config/Cider/themes` +* Create a `theme.less` file with the name of the theme. +* In Cider, select the theme in the settings. +* To enable hot reloading for the theme, open the DevTools and enter `less.watch()` in the console. + +## Resources +* The default styles.less can be found in: [src/renderer/style.less](https://github.com/ciderapp/Cider/tree/main/src/renderer/style.less) +* [Less.js documentation](https://lesscss.org/) \ No newline at end of file diff --git a/src/renderer/themes/compactui.less b/src/renderer/themes/compactui.less new file mode 100644 index 00000000..e69de29b diff --git a/src/renderer/themes/dark.less b/src/renderer/themes/dark.less new file mode 100644 index 00000000..2b06488f --- /dev/null +++ b/src/renderer/themes/dark.less @@ -0,0 +1,3 @@ +#app { + --color1: #111; +} diff --git a/src/renderer/themes/default.less b/src/renderer/themes/default.less new file mode 100644 index 00000000..6eb16e8e --- /dev/null +++ b/src/renderer/themes/default.less @@ -0,0 +1 @@ +// Default theme diff --git a/src/renderer/themes/grain.less b/src/renderer/themes/grain.less new file mode 100644 index 00000000..8a46724f --- /dev/null +++ b/src/renderer/themes/grain.less @@ -0,0 +1,3 @@ +body.notransparency::before { + display: block; +} diff --git a/src/renderer/themes/inline_drawer.less b/src/renderer/themes/inline_drawer.less new file mode 100644 index 00000000..31124d04 --- /dev/null +++ b/src/renderer/themes/inline_drawer.less @@ -0,0 +1,44 @@ +&:not(.modular-fs) { + .app-drawer { + border-radius: 0px; + top: 0; + right: 0; + height: 100%; + box-shadow: unset; + border-left: 1px solid var(--color2); + background: var(--color1); + margin-right: 0px; + position: relative; + } + + .drawertransition-enter-active, + .drawertransition-leave-active { + transition: + margin 0.25s var(--appleEase), + opacity 0.25s var(--appleEase); + } + + .drawertransition-enter, + .drawertransition-leave-to { + margin-right: -300px; + } + + @media screen and (max-width: 1120px) { + .app-drawer { + margin-right: 0px; + position: absolute; + } + + .drawertransition-enter-active, + .drawertransition-leave-active { + transition: + right 0.25s var(--appleEase), + opacity 0.25s var(--appleEase); + } + + .drawertransition-enter, + .drawertransition-leave-to { + right: -300px; + } + } +} diff --git a/src/renderer/themes/reduce_visuals.less b/src/renderer/themes/reduce_visuals.less new file mode 100644 index 00000000..1f44a544 --- /dev/null +++ b/src/renderer/themes/reduce_visuals.less @@ -0,0 +1,139 @@ +body { + --ciderShadow-Generic: var(--mediaItemShadow); + --mediaItemShadow-Shadow: var(--mediaItemShadow); + --mediaItemShadow-ShadowSubtle: var(--mediaItemShadow); +} + +.bg-artwork-container { + display: none; + animation: none !important; + + .bg-artwork { + animation: none !important; + } +} + +.app-chrome:not(.chrome-bottom) { + backdrop-filter: unset; + background-color: var(--baseColor); +} + +.menu-panel .menu-panel-body { + background: rgb(30 30 30); +} +.menu-panel .menu-panel-body .menu-option::before { + transition: unset !important; +} + +#app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center .top-nav-group .app-sidebar-item:before { + transition: unset !important; +} + +.playback-button:before, +.playback-button--small:before { + transition: unset !important; +} + +.floating-header { + backdrop-filter: unset !important; + background: rgb(0 0 0 / 80%) !important; +} + +.replaycard-enter-active, +.replaycard-leave-active { + transition: unset; +} + +.replaycard-enter, +.replaycard-leave-to { + opacity: 0; + transform: translateY(20px); +} + +.modal-enter-active, +.modal-leave-active { + transition: unset; +} + +.modal-enter, +.modal-leave-to { + opacity: 0; + transform: scale(1.1); +} + +.wpfade-enter-active, +.wpfade-leave-active { + transition: opacity 0.1s var(--appleEase); +} + +.wpfade-enter, +.wpfade-leave-to { + opacity: 0; +} + +.wpfade_transform-enter-active, +.wpfade_transform-leave-active { + transition: unset; + will-change: unset; +} + +.wpfade_transform-enter { + opacity: 0; + transform: unset; + will-change: unset; +} + +.wpfade_transform-leave-to { + opacity: 0; + transform: unset; + will-change: unset; +} + +.wpfade_transform_backwards-enter-active, +.wpfade_transform_backwards-leave-active { + transition: unset; +} + +.wpfade_transform_backwards-enter { + opacity: 0; + transform: unset; + will-change: unset; +} + +.wpfade_transform_backwards-leave-to { + opacity: 0; + transform: unset; + will-change: unset; +} + +.fabfade-enter-active, +.fabfade-leave-active { + transition: unset; +} + +.fabfade-enter, +.fabfade-leave-to { + opacity: 0; + transform: scale(0.5); +} + +.fsModeSwitch-enter-active, +.fsModeSwitch-leave-active { + transition: unset; +} + +.fsModeSwitch-enter, +.fsModeSwitch-leave-to { + transform: scale(1.1); + opacity: 0; +} + +.drawertransition-enter-active, +.drawertransition-leave-active { + transition: unset; +} + +.drawertransition-enter, +.drawertransition-leave-to { + right: -300px; +} diff --git a/src/renderer/themes/sweetener.less b/src/renderer/themes/sweetener.less new file mode 100644 index 00000000..f939bd38 --- /dev/null +++ b/src/renderer/themes/sweetener.less @@ -0,0 +1,135 @@ +@panelColorsFallback: rgb(30 30 30); +@panelColors: rgb(30 30 30 / 45%); + +.menu-panel { + .menu-panel-body { + background-color: @panelColors; + backdrop-filter: blur(32px) saturate(180%); + + &.menu-panel-body-down { + animation: menuInDown 0.1s var(--appleEase); + } + + &.menu-panel-body-up { + animation: menuInUp 0.1s var(--appleEase); + } + } + + @keyframes menuInUp { + 0% { + opacity: 0; + transform: translateY(-10px) translate3d(0, 0, 0); + background: @panelColorsFallback; + } + + 100% { + opacity: 1; + transform: translateY(0); + background: @panelColors; + } + } + + @keyframes menuInDown { + 0% { + opacity: 0; + transform: translateY(10px) translate3d(0, 0, 0); + background: @panelColorsFallback; + } + + 100% { + opacity: 1; + transform: translateY(0); + background: @panelColors; + } + } +} + +.cd-mediaitem-square { + --transition: width 1s, height 1s; + transition: var(--transition); + .artwork { + transition: var(--transition); + } +} + +.cd-mediaitem-square:not(.mediaitem-card) { + transition: transform 0.2s var(--appleEase); + transition-delay: 0.1s; + + .artwork-container { + } + + .info-rect { + } + + .artwork-container, + .info-rect { + transition: transform 0.22s var(--appleEase); + transition-delay: 0.05s; + } + + .artwork-container { + transform: scale(0.962) translateZ(0); + transition: transform 0.1s var(--appleEase); + transition-delay: 0s; + transform-origin: center; + } + + &:hover { + .artwork-container { + transform: scale(1); + transition: transform 0.1s var(--appleEase); + transition-delay: 0s; + transform-origin: center; + } + + .info-rect { + z-index: 1; + transition: transform 0.1s var(--appleEase); + transition-delay: 0s; + transform: translateY(8px) translate3d(0, 0, 0); + } + } + + &:active { + } +} + +.wpfade_transform-enter-active, +.wpfade_transform-leave-active { + --transitionTime: 0.2s; + transition: + opacity var(--transitionTime) var(--appleEase), + transform var(--transitionTime) var(--appleEase); + will-change: opacity, transform; +} + +.wpfade_transform-enter { + opacity: 0; + transform: translateX(50%) translate3d(0, 0, 0); + will-change: opacity, transform; +} +.wpfade_transform-leave-to { + opacity: 0; + transform: translateX(-50%) translate3d(0, 0, 0); + will-change: opacity, transform; +} + +.wpfade_transform_backwards-enter-active, +.wpfade_transform_backwards-leave-active { + --transitionTime: 0.2s; + transition: + opacity var(--transitionTime) var(--appleEase), + transform var(--transitionTime) var(--appleEase); +} + +.wpfade_transform_backwards-enter { + opacity: 0; + transform: translateX(-50%) translate3d(0, 0, 0); + will-change: opacity, transform; +} +.wpfade_transform_backwards-leave-to { + opacity: 0; + transform: translateX(50%) translate3d(0, 0, 0); + will-change: opacity, transform; +} diff --git a/src/renderer/todo.js b/src/renderer/todo.js index 3e8deaf9..ffdff935 100644 --- a/src/renderer/todo.js +++ b/src/renderer/todo.js @@ -1,180 +1,193 @@ // Apple Music Listen Now Page // URL : https://amp-api.music.apple.com/v1/me/recommendations?timezone=+00:00 - // &with=friendsMix,library,social&art[social-profiles:url]=c - // &name=listen-now&art[url]=c,f&omit[resource]=autos - // &relate[editorial-items]=contents - // &extend=editorialCard,editorialVideo - // &extend[albums]=artistUrl - // &extend[library-albums]=artistUrl - // &extend[playlists]=artistNames,editorialArtwork - // &extend[library-playlists]=artistNames,editorialArtwork - // &extend[social-profiles]=topGenreNames&include[albums]=artists - // &include[songs]=artists&include[music-videos]=artists - // &fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url - // &fields[artists]=name,url&extend[stations]=airDate,supportsAirTimeUpdates&meta[stations]=inflectionPoints - // &types=artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-profiles,social-upsells - // &l=en-gb&platform=web +// &with=friendsMix,library,social&art[social-profiles:url]=c +// &name=listen-now&art[url]=c,f&omit[resource]=autos +// &relate[editorial-items]=contents +// &extend=editorialCard,editorialVideo +// &extend[albums]=artistUrl +// &extend[library-albums]=artistUrl +// &extend[playlists]=artistNames,editorialArtwork +// &extend[library-playlists]=artistNames,editorialArtwork +// &extend[social-profiles]=topGenreNames&include[albums]=artists +// &include[songs]=artists&include[music-videos]=artists +// &fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url +// &fields[artists]=name,url&extend[stations]=airDate,supportsAirTimeUpdates&meta[stations]=inflectionPoints +// &types=artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-profiles,social-upsells +// &l=en-gb&platform=web -await app.mk.api.personalRecommendations("", - { - name: "listen-now", - with: "friendsMix,library,social", - "art[social-profiles:url]":"c", - "art[url]": "c,f", - "omit[resource]": "autos", - "relate[editorial-items]": "contents", - extend: ["editorialCard", "editorialVideo"], - "extend[albums]": ["artistUrl"], - "extend[library-albums]": ["artistUrl"], - "extend[playlists]": ["artistNames", "editorialArtwork"], - "extend[library-playlists]": ["artistNames", "editorialArtwork"], - "extend[social-profiles]": "topGenreNames", - "include[albums]": "artists", - "include[songs]": "artists", - "include[music-videos]": "artists", - "fields[albums]": ["artistName", "artistUrl", "artwork", "contentRating", "editorialArtwork", "editorialVideo", "name", "playParams", "releaseDate", "url"], - "fields[artists]": ["name", "url"], - "extend[stations]": ["airDate", "supportsAirTimeUpdates"], - "meta[stations]": "inflectionPoints", - types: "artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-profiles,social-upsells", - l:"en-gb", - platform:"web" - }, - { - includeResponseMeta: !0, - reload: !0 - }); +await app.mk.api.personalRecommendations( + "", + { + name: "listen-now", + with: "friendsMix,library,social", + "art[social-profiles:url]": "c", + "art[url]": "c,f", + "omit[resource]": "autos", + "relate[editorial-items]": "contents", + extend: ["editorialCard", "editorialVideo"], + "extend[albums]": ["artistUrl"], + "extend[library-albums]": ["artistUrl"], + "extend[playlists]": ["artistNames", "editorialArtwork"], + "extend[library-playlists]": ["artistNames", "editorialArtwork"], + "extend[social-profiles]": "topGenreNames", + "include[albums]": "artists", + "include[songs]": "artists", + "include[music-videos]": "artists", + "fields[albums]": ["artistName", "artistUrl", "artwork", "contentRating", "editorialArtwork", "editorialVideo", "name", "playParams", "releaseDate", "url"], + "fields[artists]": ["name", "url"], + "extend[stations]": ["airDate", "supportsAirTimeUpdates"], + "meta[stations]": "inflectionPoints", + types: "artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-profiles,social-upsells", + l: "en-gb", + platform: "web", + }, + { + includeResponseMeta: !0, + reload: !0, + }, +); // Browse page -await app.mk.api.groupings("", - { - platform: "web", - name: "music", - l: "en-gb", - "omit[resource:artists]": "relationships", - "include[albums]": "artists", - "include[songs]": "artists", - "include[music-videos]": "artists", - extend: "editorialArtwork,artistUrl", - "fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes", - "art[url]": "f" - }); +await app.mk.api.groupings("", { + platform: "web", + name: "music", + l: "en-gb", + "omit[resource:artists]": "relationships", + "include[albums]": "artists", + "include[songs]": "artists", + "include[music-videos]": "artists", + extend: "editorialArtwork,artistUrl", + "fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes", + "art[url]": "f", +}); // Radio page -await app.mk.api.recentRadioStations("", - {l: "en-gb", - "platform": "web", - "art[url]": "f"}); +await app.mk.api.recentRadioStations("", { + l: "en-gb", + platform: "web", + "art[url]": "f", +}); // Recently Added -await app.mk.api.library.recentlyAdded({ - "platform": "web", +await app.mk.api.library.recentlyAdded( + { + platform: "web", include: { - "library-albums": ["artists"], - "library-artists": ["catalog"] + "library-albums": ["artists"], + "library-artists": ["catalog"], }, fields: { - artists: ["url"], - albums: "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url" + artists: ["url"], + albums: "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", }, includeOnly: ["catalog", "artists"], - limit: 25 -}, { + limit: 25, + }, + { reload: !0, - includePagination: !0 -}) + includePagination: !0, + }, +); -// Songs -await app.mk.api.library.songs({limit: 100}).then((data)=>{ - console.log(data) -}) +// Songs +await app.mk.api.library.songs({ limit: 100 }).then((data) => { + console.log(data); +}); -// Artists -await app.mk.api.library.artists({limit: 100}).then((data)=>{ - console.log(data) -}) +// Artists +await app.mk.api.library.artists({ limit: 100 }).then((data) => { + console.log(data); +}); -// Artists -await app.mk.api.library.albums({limit: 100}).then((data)=>{ - console.log(data) -}) +// Artists +await app.mk.api.library.albums({ limit: 100 }).then((data) => { + console.log(data); +}); // Albums // does not like limit = 100 for some reason -await app.mk.api.library.albums({limit: 50}).then((data)=>{ - console.log(data) -}) +await app.mk.api.library.albums({ limit: 50 }).then((data) => { + console.log(data); +}); // Made For You -app.mk.api.recommendations("",{extend: "editorialArtwork,artistUrl"}) +app.mk.api.recommendations("", { extend: "editorialArtwork,artistUrl" }); // Library with library length -await app.mk.api.library.songs("", {limit: 100}, {includeResponseMeta: !0}).then((data)=>{ - console.log(data) -}) +await app.mk.api.library.songs("", { limit: 100 }, { includeResponseMeta: !0 }).then((data) => { + console.log(data); +}); // Artist View Top Songs -app.mk.api.artistView("325096253", "top-songs", {}, {view: "top-songs", includeResponseMeta: !0}) +app.mk.api.artistView("325096253", "top-songs", {}, { view: "top-songs", includeResponseMeta: !0 }); // Artist Page Data -app.mkapi("artists", false, "412778295", { - "views": "featured-release,full-albums,appears-on-albums,featured-albums,featured-on-albums,singles,compilation-albums,live-albums,latest-release,top-music-videos,similar-artists,top-songs,playlists,more-to-hear,more-to-see", - "extend": "artistBio,bornOrFormed,editorialArtwork,editorialVideo,isGroup,origin,hero", - "extend[playlists]": "trackCount", - "omit[resource:songs]": "relationships", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url,trackCount", - "limit[artists:top-songs]": 20, - "art[url]": "f" -}, {includeResponseMeta: !0}).then((data)=>{ - console.log(data) -}) +app + .mkapi( + "artists", + false, + "412778295", + { + views: "featured-release,full-albums,appears-on-albums,featured-albums,featured-on-albums,singles,compilation-albums,live-albums,latest-release,top-music-videos,similar-artists,top-songs,playlists,more-to-hear,more-to-see", + extend: "artistBio,bornOrFormed,editorialArtwork,editorialVideo,isGroup,origin,hero", + "extend[playlists]": "trackCount", + "omit[resource:songs]": "relationships", + "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url,trackCount", + "limit[artists:top-songs]": 20, + "art[url]": "f", + }, + { includeResponseMeta: !0 }, + ) + .then((data) => { + console.log(data); + }); // download entire library -var library = [] +var library = []; var downloaded = null; -function downloadChunk () { - if(downloaded == null) { - app.mk.api.library.songs("", {limit: 100}, {includeResponseMeta: !0}).then((response)=>{ - processChunk(response) - }) - }else{ - downloaded.next("", {limit: 100}, {includeResponseMeta: !0}).then((response)=>{ - processChunk(response) - }) - } +function downloadChunk() { + if (downloaded == null) { + app.mk.api.library.songs("", { limit: 100 }, { includeResponseMeta: !0 }).then((response) => { + processChunk(response); + }); + } else { + downloaded.next("", { limit: 100 }, { includeResponseMeta: !0 }).then((response) => { + processChunk(response); + }); + } } -function processChunk (response) { - downloaded = response - library = library.concat(downloaded.data) - if (downloaded.meta.total > library.length) { - console.log(`downloading next chunk - ${library.length} songs so far`) - downloadChunk() - } else { - console.log(library) - } +function processChunk(response) { + downloaded = response; + library = library.concat(downloaded.data); + if (downloaded.meta.total > library.length) { + console.log(`downloading next chunk - ${library.length} songs so far`); + downloadChunk(); + } else { + console.log(library); + } } //Some Available Functions from MusicKit // recentPlayed() -> recently played songs ? // create Artist / Song/ Album stations: -app.mk.setStationQueue({artist:"1258279972"}) -app.mk.setStationQueue({song:"1437308307"}) // yes the song id here can be the albumId, but just keep using the song: +app.mk.setStationQueue({ artist: "1258279972" }); +app.mk.setStationQueue({ song: "1437308307" }); // yes the song id here can be the albumId, but just keep using the song: // Sorting Playlists, send an array of tracks in the format below // playlist must be fully recursively downloaded first before sorting app.mk.api.library.putPlaylistTracklisting(app.showingPlaylist.attributes.playParams.id, [ - { - "id": relationships.tracks.data[X].id, - "type": relationships.tracks.data[X].type - }, - { - "id": relationships.tracks.data[X].id, - "type": relationships.tracks.data[X].type - }, - { - "id": relationships.tracks.data[X].id, - "type": relationships.tracks.data[X].type - }, -]) \ No newline at end of file + { + id: relationships.tracks.data[X].id, + type: relationships.tracks.data[X].type, + }, + { + id: relationships.tracks.data[X].id, + type: relationships.tracks.data[X].type, + }, + { + id: relationships.tracks.data[X].id, + type: relationships.tracks.data[X].type, + }, +]); diff --git a/src/renderer/views/app/app-navigation.ejs b/src/renderer/views/app/app-navigation.ejs new file mode 100644 index 00000000..098ee2bd --- /dev/null +++ b/src/renderer/views/app/app-navigation.ejs @@ -0,0 +1,184 @@ +
+ +
+
+ + + + + + + + + + + + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + +
+
+ +
+ +
+
+
diff --git a/src/renderer/views/app/chrome-bottom.ejs b/src/renderer/views/app/chrome-bottom.ejs new file mode 100644 index 00000000..bb2a0cd5 --- /dev/null +++ b/src/renderer/views/app/chrome-bottom.ejs @@ -0,0 +1,192 @@ +
+
+
+ + + +
+ +
+
+
+ + {{ convertTime(getSongProgress()) }} + + + + {{ + convertTime(mk.currentPlaybackDuration) }} + + {{ getLz("term.live") }} + +
+
+
+ + +
+
+ +
+
+ + + +
+
+ +
+
+ +
+
+
+
+
+ + +
+
+ +
+
+ +
+
+ + + +
+
+
diff --git a/src/renderer/views/app/chrome-top.ejs b/src/renderer/views/app/chrome-top.ejs new file mode 100644 index 00000000..ace325dc --- /dev/null +++ b/src/renderer/views/app/chrome-top.ejs @@ -0,0 +1,311 @@ +
+
+
+
+
+
+
+
+
+
+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + + + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ +
+
+
diff --git a/src/renderer/views/app/panels.ejs b/src/renderer/views/app/panels.ejs new file mode 100644 index 00000000..5da27c0c --- /dev/null +++ b/src/renderer/views/app/panels.ejs @@ -0,0 +1,201 @@ + + +
+ + +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+
+ {{ (lyricon ? (lyrics.length > 0 && lyrics[currentLyricsLine] && lyrics[currentLyricsLine].line ? lyrics[currentLyricsLine].line.replace("lrcInstrumental", "") : "") : "") + (lyricon ? (lyrics.length > 0 && lyrics[currentLyricsLine] && lyrics[currentLyricsLine].line ? (lyrics[currentLyricsLine].translation ? "\n\r" + lyrics[currentLyricsLine].translation : "") : "") : "") }} +
+
+
+
+ {{ mk.nowPlayingItem?.attributes?.artistName ?? "" }} +
+
+
+ {{ mk.nowPlayingItem?.attributes?.name ?? "" }} +
+
+
+

{{ convertTime(getSongProgress()) }}

+ +

{{ convertTime(mk.currentPlaybackDuration) }}

+
+ +
+
+ + +
+ +
+ + +
+
+ <%- include("../svg/pip.svg") %> +
+
+ <%- include("../svg/fullscreen.svg") %> +
+
+
+
+
+
diff --git a/src/renderer/views/components/add-to-playlist.ejs b/src/renderer/views/components/add-to-playlist.ejs index ee093413..d3f778d6 100644 --- a/src/renderer/views/components/add-to-playlist.ejs +++ b/src/renderer/views/components/add-to-playlist.ejs @@ -1,88 +1,90 @@ \ No newline at end of file + }) + }, + methods: { + playlistSelect(playlist) { + if (playlist.type != "library-playlist-folders") { + this.addToPlaylist(playlist.id) + } + }, + addToPlaylist(id) { + app.addSelectedToPlaylist(id) + }, + search() { + this.focused = "" + if (this.searchQuery == "") { + this.playlistSorted = this.playlists + } else { + this.playlistSorted = this.playlists.filter(playlist => { + return playlist.attributes.name.toLowerCase().indexOf(this.searchQuery.toLowerCase()) > -1 + }) + if (this.playlistSorted.length == 1) { + this.focused = this.playlistSorted[0].id + } + } + }, + } + }); + diff --git a/src/renderer/views/components/airplay-modal.ejs b/src/renderer/views/components/airplay-modal.ejs new file mode 100644 index 00000000..1d14ea76 --- /dev/null +++ b/src/renderer/views/components/airplay-modal.ejs @@ -0,0 +1,45 @@ + + diff --git a/src/renderer/views/components/animatedartwork-view.ejs b/src/renderer/views/components/animatedartwork-view.ejs index b6cae3cd..bbc73c51 100644 --- a/src/renderer/views/components/animatedartwork-view.ejs +++ b/src/renderer/views/components/animatedartwork-view.ejs @@ -5,70 +5,98 @@ \ No newline at end of file + + this.hls.attachMedia(this.$refs.video); + this.hls.loadSource(this.video, p); + let u = this.hls; + var quality = app.cfg.visual.animated_artwork_qualityLevel; + setTimeout(() => { + let levelsnum = u.levels.map((level) => { + return level.width + }) + if (levelsnum.length > 0) { + let qualities = [] + let qualities2 = [] + for (let i = 0; i < levelsnum.length; i++) { + if (qualities2.indexOf(levelsnum[i]) == -1) { + qualities.push({ level: i, quality: levelsnum[i] }) + qualities2.push(levelsnum[i]) + } + } + let actualnum = Math.floor(qualities[qualities.length - 1].level * (quality / 4)) + if (quality != 0) { + quality = qualities[Math.min(actualnum, qualities.length - 1)].level + } + if (quality == 4) { + quality = qualities[qualities.length - 1].level + } + } + try { + this.hls.loadLevel = parseInt(quality || 1); + } catch (e) { + } + }, 200) + } + }) + } + }, + async beforeDestroy() { + if (this.hls) { + await this.hls.destroy(); + this.hls = null + } + } + }); + diff --git a/src/renderer/views/components/app-content.ejs b/src/renderer/views/components/app-content.ejs new file mode 100644 index 00000000..3600042e --- /dev/null +++ b/src/renderer/views/components/app-content.ejs @@ -0,0 +1,50 @@ + + + diff --git a/src/renderer/views/components/artist-chip.ejs b/src/renderer/views/components/artist-chip.ejs new file mode 100644 index 00000000..b588615d --- /dev/null +++ b/src/renderer/views/components/artist-chip.ejs @@ -0,0 +1,53 @@ + + + diff --git a/src/renderer/views/components/artwork-material.ejs b/src/renderer/views/components/artwork-material.ejs index 3cfe9891..6adef2c0 100644 --- a/src/renderer/views/components/artwork-material.ejs +++ b/src/renderer/views/components/artwork-material.ejs @@ -1,37 +1,36 @@ \ No newline at end of file + Vue.component('artwork-material', { + template: '#artwork-material', + data: function() { + return { + src: "" + } + }, + mounted() { + this.src = app.getMediaItemArtwork(this.url, this.size) + }, + props: { + url: { + type: String, + required: true + }, + size: { + type: [String, Number], + required: false, + default: '32' + }, + images: { + type: [String, Number], + required: false, + default: '2' + } + }, + methods: {} + }); + diff --git a/src/renderer/views/components/audio-controls.ejs b/src/renderer/views/components/audio-controls.ejs new file mode 100644 index 00000000..3dbb3f91 --- /dev/null +++ b/src/renderer/views/components/audio-controls.ejs @@ -0,0 +1,98 @@ + + + diff --git a/src/renderer/views/components/audio-playbackrate.ejs b/src/renderer/views/components/audio-playbackrate.ejs new file mode 100644 index 00000000..0e54b385 --- /dev/null +++ b/src/renderer/views/components/audio-playbackrate.ejs @@ -0,0 +1,61 @@ + + + diff --git a/src/renderer/views/components/audio-settings.ejs b/src/renderer/views/components/audio-settings.ejs index 379cf9ae..699c7599 100644 --- a/src/renderer/views/components/audio-settings.ejs +++ b/src/renderer/views/components/audio-settings.ejs @@ -1,10 +1,12 @@ \ No newline at end of file + }, + props: {}, + mounted() { + }, + methods: { + openEqualizer() { + app.modals.equalizer = true + app.modals.audioSettings = false + }, + openAudioControls() { + app.modals.audioControls = true + app.modals.audioSettings = false + }, + openAudioPlaybackRate() { + app.modals.audioPlaybackRate = true + app.modals.audioSettings = false + }, + }, + } + ); + diff --git a/src/renderer/views/components/c2-upgrade.ejs b/src/renderer/views/components/c2-upgrade.ejs new file mode 100644 index 00000000..980fd811 --- /dev/null +++ b/src/renderer/views/components/c2-upgrade.ejs @@ -0,0 +1,106 @@ + + + diff --git a/src/renderer/views/components/castmenu.ejs b/src/renderer/views/components/castmenu.ejs new file mode 100644 index 00000000..d6d5d7ce --- /dev/null +++ b/src/renderer/views/components/castmenu.ejs @@ -0,0 +1,173 @@ + + diff --git a/src/renderer/views/components/cider-modal.ejs b/src/renderer/views/components/cider-modal.ejs index e7bebd90..84128f7b 100644 --- a/src/renderer/views/components/cider-modal.ejs +++ b/src/renderer/views/components/cider-modal.ejs @@ -4,15 +4,17 @@ @@ -33,50 +35,50 @@ \ No newline at end of file + }) + }, + methods: { + addToPlaylist(id) { + app.addSelectedToPlaylist(id) + }, + search() { + this.focused = "" + if (this.searchQuery == "") { + this.playlistSorted = this.playlists + } else { + this.playlistSorted = this.playlists.filter(playlist => { + return playlist.attributes.name.toLowerCase().indexOf(this.searchQuery.toLowerCase()) > -1 + }) + if (this.playlistSorted.length == 1) { + this.focused = this.playlistSorted[0].id + } + } + }, + } + }); + diff --git a/src/renderer/views/components/equalizer.ejs b/src/renderer/views/components/equalizer.ejs index f5086eca..422374ca 100644 --- a/src/renderer/views/components/equalizer.ejs +++ b/src/renderer/views/components/equalizer.ejs @@ -1,15 +1,15 @@ \ No newline at end of file + diff --git a/src/renderer/views/components/fullscreen.ejs b/src/renderer/views/components/fullscreen.ejs index e35c760b..a0e919ef 100644 --- a/src/renderer/views/components/fullscreen.ejs +++ b/src/renderer/views/components/fullscreen.ejs @@ -3,156 +3,245 @@
- - - + + +
-
+
+
+ + + + + + + + + + + + + +
+
+
-
+
-
-
-
- +
+ :richlyrics="richlyrics">
-
- +
+
+
+ +
-
-
-
+
+
+
+
- - - \ No newline at end of file + } else if (app.mk.nowPlayingItem._container.type == "library-albums") { + try { + const result = (await app.mk.api.v3.music(`/v1/me/library/albums/${app.mk.nowPlayingItem._container.id}/catalog` + , { "fields": "editorialArtwork,editorialVideo" })).data.data[0].attributes?.editorialVideo?.motionDetailSquare?.video + if (result) { + this.video = result + } else { + this.video = null + } + } catch (e) { + e = null + this.video = null + } + } + }, + beforeMount() { + window.addEventListener('keyup', this.onEscapeKeyUp); + }, + beforeDestroy() { + window.removeEventListener('keyup', this.onEscapeKeyUp) + }, + methods: { + onEscapeKeyUp(event) { + if (event.which === 27) { + app.fullscreen(false); + console.log('js') + } + }, + } + }); + diff --git a/src/renderer/views/components/hello-world.ejs b/src/renderer/views/components/hello-world.ejs index 6fa4e1f7..1386bf63 100644 --- a/src/renderer/views/components/hello-world.ejs +++ b/src/renderer/views/components/hello-world.ejs @@ -3,12 +3,12 @@ \ No newline at end of file + var hw = Vue.component('hello-world', { + template: '#hello-world', + methods: { + sayHello: function() { + alert('Hello world!'); + } + } + }); + diff --git a/src/renderer/views/components/inline-collection-list.ejs b/src/renderer/views/components/inline-collection-list.ejs new file mode 100644 index 00000000..3bb3173e --- /dev/null +++ b/src/renderer/views/components/inline-collection-list.ejs @@ -0,0 +1,133 @@ + + diff --git a/src/renderer/views/components/karaoke-in.ejs b/src/renderer/views/components/karaoke-in.ejs index 23427996..b916a829 100644 --- a/src/renderer/views/components/karaoke-in.ejs +++ b/src/renderer/views/components/karaoke-in.ejs @@ -4,7 +4,7 @@